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