#include "ExpandFrame.h" void ExpandFrame::ExpandButton::Paint(Draw &w) { Size sz = GetSize(); int state = GetVisualState(); bool lr = (align == ExpandFrame::LEFT || align == ExpandFrame::RIGHT); int margin = style->handle_margin[state]; int x = margin; // BG ChPaint(w, sz, style->handle_look[state]); if (lr) Swap(sz.cx, sz.cy); // Image Image img = style->image[expand ? 1 : 0]; if (!IsNull(img)) { Size isz = img.GetSize(); if (lr) Swap(isz.cx, isz.cy); Point p(x, (sz.cy - isz.cy)/2); if (style->imagealign == ExpandFrame::RIGHT) { sz.cx -= isz.cx + margin; p.x = sz.cx; } else x += isz.cx+margin; if (lr) w.DrawImage(p.y, p.x, img); else w.DrawImage(p.x, p.y, img); } // Text if (label.GetLength()) { Size tsz = GetTextSize(label, style->font[state]); if (lr) Swap(tsz.cx, tsz.cy); Point p(x, (sz.cy - tsz.cy)/2); if (style->textalign == ExpandFrame::RIGHT) p.x = sz.cx - margin - tsz.cx; if (lr) w.DrawText(sz.cy + p.y, p.x, 2700, label, style->font[state], style->textcolor[state]); else w.DrawText(p.x, p.y, label, style->font[state], style->textcolor[state]); } } int ExpandFrame::ExpandButton::GetVisualState() const { int i = FlatButton::GetVisualState(); return (i == CTRL_NORMAL && expand) ? CTRL_PRESSED : i; } void ExpandFrame::FrameAdd(Ctrl& parent) { parent.Add(*this); } void ExpandFrame::FrameRemove() { this->Ctrl::Remove(); } void ExpandFrame::FrameAddSize(Size& sz) { if (!IsSet() || !IsShown()) return; bool lr = (handle.align == LEFT || handle.align == RIGHT); sz.cx += lr ? ExpandSz() : 0; sz.cy += lr ? 0 : ExpandSz(); } void ExpandFrame::FrameLayout(Rect& r) { if (!IsSet()) return; switch (handle.align) { case LEFT: LayoutFrameLeft(r, this, ExpandSz()); break; case RIGHT: LayoutFrameRight(r, this, ExpandSz()); break; case TOP: LayoutFrameTop(r, this, ExpandSz()); break; case BOTTOM: LayoutFrameBottom(r, this, ExpandSz()); break; } } void ExpandFrame::Paint(Draw& w) { if (!IsSet() || !IsShown()) return; if (!IsTransparent()) w.DrawRect(GetSize(), SColorFace()); // Paint Border int state = handle.GetVisualState(); if (handle.style->border[state]) { Rect r = GetSize(); r.Deflate(handle.style->border_inset); DrawBorder(w, r, handle.style->border[state]); } } void ExpandFrame::UpdateButton() { Rect r = handle.style->handle_border[0]; switch (handle.align) { case TOP: handle.HSizePosZ(r.left, r.right).TopPosZ(r.top, handle.style->handle_size); break; case LEFT: handle.VSizePosZ(r.right, r.left).LeftPosZ(r.top, handle.style->handle_size); break; case BOTTOM: handle.HSizePosZ(r.right, r.left).BottomPosZ(r.top, handle.style->handle_size); break; case RIGHT: handle.VSizePosZ(r.left, r.right).RightPosZ(r.top, handle.style->handle_size); break; } } int ExpandFrame::ExpandSz() const { if (IsExpanded()) { Rect r = BorderSz(); return max(r.top, HandleSz()) + r.bottom + child_size; } else return HandleSz(); } Rect ExpandFrame::BorderSz() const { int sz = (int)(uintptr_t)(handle.style->border[0][0]); const Rect &in = handle.style->border_inset; const Rect &out = handle.style->border_outset; return Rect(in.left + out.left + sz, in.top + out.top + sz, in.right + out.right + sz, in.bottom + out.bottom + sz); } void ExpandFrame::SetChildPos() { if (!IsSet()) return; Ctrl *c = GetLastChild(); Rect r = BorderSz(); r.top = max(r.top, HandleSz()); switch (handle.align) { case TOP: c->VSizePos(r.top, r.bottom).HSizePos(r.left, r.right); break; case LEFT: c->HSizePos(r.top, r.bottom).VSizePos(r.right, r.left); break; case BOTTOM: c->VSizePos(r.bottom, r.top).HSizePos(r.left, r.right); break; case RIGHT: c->HSizePos(r.top, r.bottom).VSizePos(r.left, r.right); break; } } ExpandFrame& ExpandFrame::Set(Ctrl& c, int size, int _type) { ASSERT(handle.align >= LEFT && handle.align <= BOTTOM); ASSERT(size > 0); handle.align = _type; bool lr = (handle.align == LEFT || handle.align == RIGHT); if (IsSet()) GetLastChild()->Remove(); child_size = size; UpdateButton(); Add(c); SetChildPos(); c.Show(IsExpanded()); RefreshParentLayout(); return *this; } ExpandFrame& ExpandFrame::Expand(bool _expand) { handle.expand = _expand; UpdateButton(); if (!IsSet()) return *this; bool hasfocus = HasFocusDeep(); GetLastChild()->Show(_expand); /* if (!expand && childfocus) Ctrl::IterateFocusForward(GetFocusCtrl(), GetParent()); else*/ if (_expand && childfocus) GetLastChild()->SetFocus(); childfocus = _expand; RefreshParentLayout(); return *this; } Size ExpandFrame::GetMinSize() const { return IsSet() ? Size(handle.style->handle_size, handle.style->handle_size) : Ctrl::GetMinSize(); } Size ExpandFrame::GetStdSize() const { int t = ExpandSz(); return IsSet() ? Size(t, t) : Ctrl::GetStdSize(); } ExpandFrame::ExpandFrame() { handle.style = &StyleDefault(); child_size = 0; childfocus = false; ignorefocus = false; handle.expand = false; handle.align = 0; handle <<= THISBACK(Toggle); hasarrow = true; Add(handle); } const ColorF *LabelBoxBorder() { static ColorF data[] = { (ColorF)2, &LabelBoxColor, &LabelBoxColor, &LabelBoxColor, &LabelBoxColor, &LabelBoxColor, &LabelBoxColor, &LabelBoxColor, &LabelBoxColor, }; return data; } CH_STYLE(ExpandFrame, Style, StyleDefault) { handle_size = 20; for (int i =0; i < 4; i++) { handle_look[i] = Button::StyleNormal().look[i]; handle_margin[i] = 5; handle_border[i] = Rect(10, 0, 10, 0); font[i] = StdFont(); textcolor[i] = Button::StyleNormal().textcolor[i]; } textalign = ExpandFrame::LEFT; image[0] = CtrlsImg::kDA(); // DOWN image[1] = CtrlsImg::kUA(); // UP imagealign = ExpandFrame::RIGHT; for (int i =0; i < 4; i++) border[i] = LabelBoxBorder(); border_inset = Rect(1, handle_size/3, 1, handle_size/3); border_outset = Rect(1, 2, 2, 1); } CH_STYLE(ExpandFrame, Style, StyleFlat) { handle_size = 20; for (int i =0; i < 4; i++) { handle_look[i] = ButtonOption::StyleFlat().look[i]; handle_margin[i] = 3; handle_border[i] = Rect(10, 0, 10, 0); font[i] = StdFont(); textcolor[i] = ButtonOption::StyleFlat().textcolor[i]; } textalign = ExpandFrame::LEFT; image[0] = CtrlsImg::DA(); // DOWN image[1] = CtrlsImg::UA(); // UP imagealign = ExpandFrame::RIGHT; for (int i =0; i < 4; i++) border[i] = NULL; border_inset = Rect(1, handle_size/2, 1, 1); border_outset = Rect(2, 2, 2, 2); }