1 #include "ExpandFrame.h"
2 
Paint(Draw & w)3 void ExpandFrame::ExpandButton::Paint(Draw &w)
4 {
5 	Size sz = GetSize();
6 	int state = GetVisualState();
7 	bool lr = (align == ExpandFrame::LEFT || align == ExpandFrame::RIGHT);
8 	int margin = style->handle_margin[state];
9 	int x = margin;
10 	// BG
11 	ChPaint(w, sz, style->handle_look[state]);
12 
13 	if (lr)
14 		Swap(sz.cx, sz.cy);
15 
16 	// Image
17 	Image img = style->image[expand ? 1 : 0];
18 	if (!IsNull(img)) {
19 		Size isz = img.GetSize();
20 		if (lr)
21 			Swap(isz.cx, isz.cy);
22 		Point p(x, (sz.cy - isz.cy)/2);
23 
24 		if (style->imagealign == ExpandFrame::RIGHT) {
25 			sz.cx -= isz.cx + margin;
26 			p.x = sz.cx;
27 		}
28 		else
29 			x += isz.cx+margin;
30 		if (lr)
31 			w.DrawImage(p.y, p.x, img);
32 		else
33 			w.DrawImage(p.x, p.y, img);
34 	}
35 	// Text
36 	if (label.GetLength()) {
37 		Size tsz = GetTextSize(label, style->font[state]);
38 		if (lr)
39 			Swap(tsz.cx, tsz.cy);
40 		Point p(x, (sz.cy - tsz.cy)/2);
41 
42 		if (style->textalign == ExpandFrame::RIGHT)
43 			p.x = sz.cx - margin - tsz.cx;
44 
45 		if (lr)
46 			w.DrawText(sz.cy + p.y, p.x, 2700, label, style->font[state], style->textcolor[state]);
47 		else
48 			w.DrawText(p.x, p.y, label, style->font[state], style->textcolor[state]);
49 	}
50 }
51 
GetVisualState() const52 int ExpandFrame::ExpandButton::GetVisualState() const
53 {
54 	int i = FlatButton::GetVisualState();
55 	return (i == CTRL_NORMAL && expand) ? CTRL_PRESSED : i;
56 }
57 
FrameAdd(Ctrl & parent)58 void ExpandFrame::FrameAdd(Ctrl& parent)
59 {
60 	parent.Add(*this);
61 }
62 
FrameRemove()63 void ExpandFrame::FrameRemove()
64 {
65 	this->Ctrl::Remove();
66 }
67 
FrameAddSize(Size & sz)68 void ExpandFrame::FrameAddSize(Size& sz)
69 {
70 	if (!IsSet() || !IsShown()) return;
71 	bool lr = (handle.align == LEFT || handle.align == RIGHT);
72 	sz.cx += lr ? ExpandSz() : 0;
73 	sz.cy += lr ? 0 : ExpandSz();
74 }
75 
FrameLayout(Rect & r)76 void ExpandFrame::FrameLayout(Rect& r)
77 {
78 	if (!IsSet()) return;
79 	switch (handle.align) {
80 	case LEFT:
81 		LayoutFrameLeft(r, this, ExpandSz());
82 		break;
83 	case RIGHT:
84 		LayoutFrameRight(r, this, ExpandSz());
85 		break;
86 	case TOP:
87 		LayoutFrameTop(r, this, ExpandSz());
88 		break;
89 	case BOTTOM:
90 		LayoutFrameBottom(r, this, ExpandSz());
91 		break;
92 	}
93 }
94 
Paint(Draw & w)95 void ExpandFrame::Paint(Draw& w)
96 {
97 	if (!IsSet() || !IsShown()) return;
98 
99 	if (!IsTransparent())
100 		w.DrawRect(GetSize(), SColorFace());
101 
102 	// Paint Border
103 	int state = handle.GetVisualState();
104 	if (handle.style->border[state]) {
105 		Rect r = GetSize();
106 		r.Deflate(handle.style->border_inset);
107 		DrawBorder(w, r, handle.style->border[state]);
108 	}
109 }
110 
UpdateButton()111 void ExpandFrame::UpdateButton()
112 {
113 	Rect r = handle.style->handle_border[0];
114 	switch (handle.align) {
115 	case TOP:
116 		handle.HSizePosZ(r.left, r.right).TopPosZ(r.top, handle.style->handle_size);
117 		break;
118 	case LEFT:
119 		handle.VSizePosZ(r.right, r.left).LeftPosZ(r.top, handle.style->handle_size);
120 		break;
121 	case BOTTOM:
122 		handle.HSizePosZ(r.right, r.left).BottomPosZ(r.top, handle.style->handle_size);
123 		break;
124 	case RIGHT:
125 		handle.VSizePosZ(r.left, r.right).RightPosZ(r.top, handle.style->handle_size);
126 		break;
127 	}
128 }
129 
ExpandSz() const130 int ExpandFrame::ExpandSz() const
131 {
132 	if (IsExpanded()) {
133 		Rect r = BorderSz();
134 		return max(r.top, HandleSz()) + r.bottom + child_size;
135 	}
136 	else
137 		return HandleSz();
138 }
139 
BorderSz() const140 Rect ExpandFrame::BorderSz() const
141 {
142 	int sz = (int)(uintptr_t)(handle.style->border[0][0]);
143 	const Rect &in = handle.style->border_inset;
144 	const Rect &out = handle.style->border_outset;
145 	return Rect(in.left + out.left + sz, in.top + out.top + sz,
146 		in.right + out.right + sz, in.bottom + out.bottom + sz);
147 }
148 
SetChildPos()149 void ExpandFrame::SetChildPos()
150 {
151 	if (!IsSet()) return;
152 	Ctrl *c = GetLastChild();
153 
154 	Rect r = BorderSz();
155 	r.top = max(r.top, HandleSz());
156 
157 	switch (handle.align) {
158 	case TOP:
159 		c->VSizePos(r.top, r.bottom).HSizePos(r.left, r.right);
160 		break;
161 	case LEFT:
162 		c->HSizePos(r.top, r.bottom).VSizePos(r.right, r.left);
163 		break;
164 	case BOTTOM:
165 		c->VSizePos(r.bottom, r.top).HSizePos(r.left, r.right);
166 		break;
167 	case RIGHT:
168 		c->HSizePos(r.top, r.bottom).VSizePos(r.left, r.right);
169 		break;
170 	}
171 }
172 
Set(Ctrl & c,int size,int _type)173 ExpandFrame& ExpandFrame::Set(Ctrl& c, int size, int _type)
174 {
175 	ASSERT(handle.align >= LEFT && handle.align <= BOTTOM);
176 	ASSERT(size > 0);
177 	handle.align = _type;
178 	bool lr = (handle.align == LEFT || handle.align == RIGHT);
179 	if (IsSet())
180 		GetLastChild()->Remove();
181 	child_size = size;
182 	UpdateButton();
183 	Add(c);
184 	SetChildPos();
185 	c.Show(IsExpanded());
186 	RefreshParentLayout();
187 	return *this;
188 }
189 
Expand(bool _expand)190 ExpandFrame& ExpandFrame::Expand(bool _expand)
191 {
192 	handle.expand = _expand;
193 	UpdateButton();
194 	if (!IsSet()) return *this;
195 	bool hasfocus = HasFocusDeep();
196 	GetLastChild()->Show(_expand);
197 /*	if (!expand && childfocus)
198 		Ctrl::IterateFocusForward(GetFocusCtrl(), GetParent());
199 	else*/
200 	if (_expand && childfocus)
201 		GetLastChild()->SetFocus();
202 	childfocus = _expand;
203 	RefreshParentLayout();
204 	return *this;
205 }
206 
GetMinSize() const207 Size ExpandFrame::GetMinSize() const
208 {
209 	return IsSet() ? Size(handle.style->handle_size, handle.style->handle_size) : Ctrl::GetMinSize();
210 }
211 
GetStdSize() const212 Size ExpandFrame::GetStdSize() const
213 {
214 	int t = ExpandSz();
215 	return IsSet() ? Size(t, t) : Ctrl::GetStdSize();
216 }
217 
ExpandFrame()218 ExpandFrame::ExpandFrame()
219 {
220 	handle.style = &StyleDefault();
221 	child_size = 0;
222 	childfocus = false;
223 	ignorefocus = false;
224 	handle.expand = false;
225 	handle.align = 0;
226 	handle <<= THISBACK(Toggle);
227 	hasarrow = true;
228 	Add(handle);
229 }
230 
LabelBoxBorder()231 const ColorF *LabelBoxBorder()
232 {
233 	static ColorF data[] = {
234 		(ColorF)2,
235 		&LabelBoxColor, &LabelBoxColor, &LabelBoxColor, &LabelBoxColor,
236 		&LabelBoxColor, &LabelBoxColor, &LabelBoxColor, &LabelBoxColor,
237 	};
238 	return data;
239 }
240 
CH_STYLE(ExpandFrame,Style,StyleDefault)241 CH_STYLE(ExpandFrame, Style, StyleDefault)
242 {
243 	handle_size = 20;
244 	for (int i =0; i < 4; i++) {
245 		handle_look[i] = Button::StyleNormal().look[i];
246 		handle_margin[i] = 5;
247 		handle_border[i] = Rect(10, 0, 10, 0);
248 		font[i] = StdFont();
249 		textcolor[i] = Button::StyleNormal().textcolor[i];
250 	}
251 	textalign = ExpandFrame::LEFT;
252 	image[0] = CtrlsImg::kDA(); // DOWN
253 	image[1] = CtrlsImg::kUA(); // UP
254 	imagealign = ExpandFrame::RIGHT;
255 	for (int i =0; i < 4; i++)
256 		border[i] = LabelBoxBorder();
257 	border_inset = Rect(1, handle_size/3, 1, handle_size/3);
258 	border_outset = Rect(1, 2, 2, 1);
259 }
260 
CH_STYLE(ExpandFrame,Style,StyleFlat)261 CH_STYLE(ExpandFrame, Style, StyleFlat)
262 {
263 	handle_size = 20;
264 	for (int i =0; i < 4; i++) {
265 		handle_look[i] = ButtonOption::StyleFlat().look[i];
266 		handle_margin[i] = 3;
267 		handle_border[i] = Rect(10, 0, 10, 0);
268 		font[i] = StdFont();
269 		textcolor[i] = ButtonOption::StyleFlat().textcolor[i];
270 	}
271 	textalign = ExpandFrame::LEFT;
272 	image[0] = CtrlsImg::DA(); // DOWN
273 	image[1] = CtrlsImg::UA(); // UP
274 	imagealign = ExpandFrame::RIGHT;
275 	for (int i =0; i < 4; i++)
276 		border[i] = NULL;
277 	border_inset = Rect(1, handle_size/2, 1, 1);
278 	border_outset = Rect(2, 2, 2, 2);
279 }
280