From a1b2632749db4875416a2cefc91989e4b1210a03 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Sat, 29 Nov 2025 14:52:58 +0100 Subject: [PATCH] CtrlLib, Draw: Support for chameleon animations --- reference/Animation/Animation.upp | 13 ++++ reference/Animation/Chameleon.iml | 13 ++++ reference/Animation/Chameleon.lay | 9 +++ reference/Animation/main.cpp | 123 ++++++++++++++++++++++++++++++ uppsrc/Core/Index.hpp | 2 + uppsrc/CtrlLib/Button.cpp | 8 +- uppsrc/CtrlLib/MenuItem.cpp | 6 +- uppsrc/CtrlLib/MultiButton.cpp | 26 +++---- uppsrc/CtrlLib/Progress.cpp | 8 +- uppsrc/CtrlLib/PushCtrl.h | 2 +- uppsrc/CtrlLib/ScrollBar.cpp | 8 +- uppsrc/CtrlLib/VirtualButtons.cpp | 2 +- uppsrc/Draw/Cham.cpp | 123 +++++++++++++++++++++--------- uppsrc/Draw/Cham.h | 16 +++- 14 files changed, 290 insertions(+), 69 deletions(-) create mode 100644 reference/Animation/Animation.upp create mode 100644 reference/Animation/Chameleon.iml create mode 100644 reference/Animation/Chameleon.lay create mode 100644 reference/Animation/main.cpp diff --git a/reference/Animation/Animation.upp b/reference/Animation/Animation.upp new file mode 100644 index 000000000..60d48a084 --- /dev/null +++ b/reference/Animation/Animation.upp @@ -0,0 +1,13 @@ +description "Skinning Button using Chameleon\377"; + +uses + CtrlLib; + +file + main.cpp, + Chameleon.lay, + Chameleon.iml; + +mainconfig + "" = "GUI"; + diff --git a/reference/Animation/Chameleon.iml b/reference/Animation/Chameleon.iml new file mode 100644 index 000000000..ff61daef7 --- /dev/null +++ b/reference/Animation/Chameleon.iml @@ -0,0 +1,13 @@ +PREMULTIPLIED +IMAGE_ID(B) +IMAGE_ID(Bh) +IMAGE_ID(Bp) +IMAGE_ID(Bd) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,99,224,96,224,96,96,2,66,16,56,112,224,192,127,32,133,21,195,228,254,255,199,142,97,234,32,236,134,255,174) +IMAGE_DATA(174,241,255,115,115,189,255,55,52,56,98,200,131,228,146,147,3,254,55,54,58,254,159,50,197,28,67,30,164,15,36,55) +IMAGE_DATA(111,158,209,255,221,187,149,49,228,65,102,130,244,193,228,208,229,113,185,143,160,255,72,13,12,134,134,6,236,24,166,22) +IMAGE_DATA(204,70,13,12,116,121,244,192,64,151,71,15,12,116,121,244,192,192,176,31,135,251,168,30,24,255,113,96,120,204,128,49) +IMAGE_DATA(122,196,208,91,30,187,251,168,30,24,13,224,152,193,196,48,117,131,89,158,144,255,0,179,40,241,48,0,0,0,0,0) +IMAGE_END_DATA(160, 4) diff --git a/reference/Animation/Chameleon.lay b/reference/Animation/Chameleon.lay new file mode 100644 index 000000000..17c64361b --- /dev/null +++ b/reference/Animation/Chameleon.lay @@ -0,0 +1,9 @@ +LAYOUT(ChameleonLayout, 228, 68) + ITEM(Upp::Button, host, SetLabel(t_("Button")).LeftPosZ(8, 68).TopPosZ(8, 24)) + ITEM(Upp::Button, std, SetLabel(t_("Button")).LeftPosZ(80, 68).TopPosZ(8, 24)) + ITEM(Upp::Button, classic, SetLabel(t_("Button")).LeftPosZ(152, 68).TopPosZ(8, 24)) + ITEM(Upp::Button, color, SetLabel(t_("Button")).LeftPosZ(8, 68).TopPosZ(36, 24)) + ITEM(Upp::Button, img, SetLabel(t_("Button")).LeftPosZ(80, 68).TopPosZ(36, 24)) + ITEM(Upp::Button, fn, SetLabel(t_("Button")).LeftPosZ(152, 68).TopPosZ(36, 24)) +END_LAYOUT + diff --git a/reference/Animation/main.cpp b/reference/Animation/main.cpp new file mode 100644 index 000000000..41f860d8e --- /dev/null +++ b/reference/Animation/main.cpp @@ -0,0 +1,123 @@ +#include + +using namespace Upp; + +#define LAYOUTFILE +#include + +#define IMAGECLASS MyButtonImg +#define IMAGEFILE +#include + +struct ChAnimatedButtonLook { + int status; + int width; + Color pen; + Color color; + + ChAnimatedButtonLook() {} +}; + +Value AnimatedEllipse(Ctrl *ctrl, Draw& draw, const Rect& rect, const Value& v, int op, Color) +{ + struct Rec { + Ptr ctrl; + int start = 0; + }; + + static ArrayMap rec; + + rec.RemoveIf([](int i) { return !rec[i].ctrl; }); + + if(IsTypeRaw(v)) { + const auto& e = ValueTo(v); + + switch(op) { + case LOOK_MARGINS: + return Rect(e.width, e.width, e.width, e.width); + case LOOK_PAINT: + draw.Clipoff(rect); + { + Size sz = rect.GetSize(); + DrawPainter w(draw, rect.GetSize()); + w.Clear(); + w.RoundedRectangle(Rect(sz).Deflated(DPI(2)), DPI(3)).Fill(e.color); + w.Stroke(DPI(e.width), e.pen); + + if(ctrl) { + if(e.status == CTRL_PRESSED) { + Rec& r = rec.GetAdd(ctrl); + int tm = msecs(); + if(!r.ctrl) { + r.ctrl = ctrl; + r.start = tm; + } + + double ani = (msecs() - r.start) / 3; + + if(ani < 300) { + w.Circle(Rect(sz).CenterPoint(), ani).Fill((int)max(255 - ani, 0.0) * SLtGray()); + Ptr h = ctrl; + SetTimeCallback(20, [=] { if(h) h->Refresh(); }); + } + } + else { + int q = rec.Find(ctrl); + if(q >= 0 && rec[q].ctrl) + rec[q].ctrl = nullptr; + } + } + } + draw.End(); + return 1; + } + } + return Null; +} + +INITBLOCK { + ChLookFn(AnimatedEllipse); +} + +Button::Style AnimationStyle() +{ + Button::Style s = Button::StyleNormal(); + + auto Look = [](int status, int width, Color pen, Color color) { + ChAnimatedButtonLook e; + e.status = status; + e.width = width; + e.pen = pen; + e.color = color; + return RawToValue(e); + }; + + s.look[0] = Look(0, 1, Black, LtGray); + s.look[1] = Look(1, 2, Blue, WhiteGray); + s.look[2] = Look(2, 2, Blue, White); + s.look[3] = Look(3, 1, Black, Gray); + s.focus_use_ok = false; // otherwise Button would use OK style for focused button + return s; +} + +void AnimationSkin() +{ + Button::StyleNormal().Write() = AnimationStyle(); +} + +struct MyApp : WithChameleonLayout { + Button::Style scolor, simage, sfn; + + MyApp(); +}; + +MyApp::MyApp() +{ + CtrlLayout(*this, "Animation example"); + SetSkin(AnimationSkin); +} + +GUI_APP_MAIN +{ + MyApp().Run(); +} diff --git a/uppsrc/Core/Index.hpp b/uppsrc/Core/Index.hpp index 6bdff2418..6ceaffe8d 100644 --- a/uppsrc/Core/Index.hpp +++ b/uppsrc/Core/Index.hpp @@ -313,6 +313,8 @@ void Index::Shrink() template void Index::Remove(const int *sorted_list, int count) { + if(count == 0) + return; if(HasUnlinked()) { Vector u; u.SetCount(GetCount()); diff --git a/uppsrc/CtrlLib/Button.cpp b/uppsrc/CtrlLib/Button.cpp index de4787f9c..ffb936241 100644 --- a/uppsrc/CtrlLib/Button.cpp +++ b/uppsrc/CtrlLib/Button.cpp @@ -339,7 +339,7 @@ const Button::Style *Button::St() const return st; } -void Button::PaintButton(Draw& w, const Rect& r, const Button::Style& st, int visualstate, bool focus, +void Button::PaintButton(Ctrl *ctrl, Draw& w, const Rect& r, const Button::Style& st, int visualstate, bool focus, const String& label, Font font, const Image& img, bool monoimg, int accesskey, bool visibleaccesskeys, bool disabled) { @@ -355,7 +355,7 @@ void Button::PaintButton(Draw& w, const Rect& r, const Button::Style& st, int vi dl.accesskey = accesskey; if(monoimg) dl.lcolor = SColorText; - ChPaint(w, r, st.look[visualstate]); + ChPaint(ctrl, w, r, st.look[visualstate]); dl.ink = st.textcolor[visualstate]; if(monoimg) dl.lcolor = st.monocolor[visualstate]; @@ -368,7 +368,7 @@ void Button::PaintButton(Draw& w, const Rect& r, const Button::Style& st, int vi void Button::Paint(Draw& w) { - PaintButton(w, GetSize(), *St(), GetVisualState(), HasFocus(), + PaintButton(this, w, GetSize(), *St(), GetVisualState(), HasFocus(), label, font, img, monoimg, accesskey, VisibleAccessKeys(), !IsShowEnabled()); } @@ -752,7 +752,7 @@ void ButtonOption::Paint(Draw& w) { HasMouseIn() || HasFocus() ? CTRL_HOT : CTRL_NORMAL; if(option) i = CTRL_PRESSED; - ChPaint(w, sz, style->look[i]); + ChPaint(this, w, sz, style->look[i]); dl.ink = style->textcolor[i]; dl.Paint(w, 3, 3, sz.cx - 6, sz.cy - 6, true); if(HasFocus() && style->drawfocus) diff --git a/uppsrc/CtrlLib/MenuItem.cpp b/uppsrc/CtrlLib/MenuItem.cpp index 13531d2a3..4d4284672 100644 --- a/uppsrc/CtrlLib/MenuItem.cpp +++ b/uppsrc/CtrlLib/MenuItem.cpp @@ -213,7 +213,7 @@ void MenuItemBase::PaintTopItem(Draw& w, int state) { hltxt = IsDark(bg) ? White() : Black(); } else - ChPaint(w, 0, 0, sz.cx, sz.cy, style->topitem[state]); + ChPaint(this, w, 0, 0, sz.cx, sz.cy, style->topitem[state]); } else if(opaque) @@ -326,7 +326,7 @@ void MenuItem::Paint(Draw& w) if(hl) { if(GUI_GlobalStyle() >= GUISTYLE_XP) - ChPaint(w, 0, 0, sz.cx, sz.cy, style->item); + ChPaint(this, w, 0, 0, sz.cx, sz.cy, style->item); else w.DrawRect(sz, SColorHighlight); } @@ -352,7 +352,7 @@ void MenuItem::Paint(Draw& w) if(IsNull(style->icheck)) DrawXPButton(w, rr, BUTTON_EDGE|BUTTON_CHECKED); else - ChPaint(w, rr, style->icheck); + ChPaint(this, w, rr, style->icheck); } } else { diff --git a/uppsrc/CtrlLib/MultiButton.cpp b/uppsrc/CtrlLib/MultiButton.cpp index f239e474b..4407b0817 100644 --- a/uppsrc/CtrlLib/MultiButton.cpp +++ b/uppsrc/CtrlLib/MultiButton.cpp @@ -450,7 +450,7 @@ Rect MultiButton::Paint0(Draw& w, bool getcr) GetLR(l, r); w.Clip(l, 0, r - l, sz.cy); } - ChPaint(w, sz, style->edge[style->activeedge ? mst : 0]); + ChPaint(this, w, sz, style->edge[style->activeedge ? mst : 0]); Color p = paper; if(frm && style->activeedge && HasFocus()) p = SColorHighlight(); @@ -459,7 +459,7 @@ Rect MultiButton::Paint0(Draw& w, bool getcr) if(IsEnabled() && IsEditable()) p = Nvl(p, style->paper); if(!IsNull(p) && !IsNull(style->coloredge)) - ChPaint(w, sz, style->coloredge, p); + ChPaint(this, w, sz, style->coloredge, p); if(style->clipedge) w.End(); } @@ -477,33 +477,33 @@ Rect MultiButton::Paint0(Draw& w, bool getcr) : right ? style->rmiddle[st] : style->right[st]; if(!nobg) { if(ComplexFrame()) - ChPaint(w, x, border, cx, sz.cy - 2 * border, style->simple[st]); + ChPaint(this, w, x, border, cx, sz.cy - 2 * border, style->simple[st]); else if(frm) { if(IsTrivial() && style->usetrivial) dopaint = false; - ChPaint(w, x, border, cx, sz.cy - 2 * border, + ChPaint(this, w, x, border, cx, sz.cy - 2 * border, dopaint ? v : style->trivial[st]); } else { w.Clip(x, 0, cx, sz.cy); - ChPaint(w, sz, style->look[Frame() ? mst : st]); + ChPaint(this, w, sz, style->look[Frame() ? mst : st]); if(IsNull(v) || !Frame()) { if((!IsTrivial() || style->trivialsep) && IsEnabled() && IsEditable()) { if(b.left) { if(left) - ChPaint(w, x, style->sepm, 1, sz.cy - 2 * style->sepm, style->sep1); - ChPaint(w, x + cx - 1, style->sepm, 1, sz.cy - 2 * style->sepm, style->sep2); + ChPaint(this, w, x, style->sepm, 1, sz.cy - 2 * style->sepm, style->sep1); + ChPaint(this, w, x + cx - 1, style->sepm, 1, sz.cy - 2 * style->sepm, style->sep2); } else { - ChPaint(w, x, style->sepm, 1, sz.cy - 2 * style->sepm, style->sep1); + ChPaint(this, w, x, style->sepm, 1, sz.cy - 2 * style->sepm, style->sep1); if(right) - ChPaint(w, x + cx - 1, style->sepm, 1, sz.cy - 2 * style->sepm, style->sep2); + ChPaint(this, w, x + cx - 1, style->sepm, 1, sz.cy - 2 * style->sepm, style->sep2); } } } else - ChPaint(w, x, 0, cx, sz.cy, v); + ChPaint(this, w, x, 0, cx, sz.cy, v); w.End(); } } @@ -556,18 +556,18 @@ Rect MultiButton::Paint0(Draw& w, bool getcr) } else { w.Clip(lx, 0, rx - lx, sz.cy); - ChPaint(w, sz, style->look[mst]); + ChPaint(this, w, sz, style->look[mst]); Rect m = style->margin; r = Rect(max(lx, m.left), m.top, min(rx, sz.cx - m.right), sz.cy - m.bottom); if(!IsTrivial() || style->trivialsep) { if(left) { r.left++; if(IsEnabled() && IsEditable()) - ChPaint(w, lx, style->sepm, 1, sz.cy - 2 * style->sepm, style->sep1); + ChPaint(this, w, lx, style->sepm, 1, sz.cy - 2 * style->sepm, style->sep1); } if(right) { if(IsEnabled() && IsEditable()) - ChPaint(w, rx - 1, style->sepm, 1, sz.cy - 2 * style->sepm, style->sep2); + ChPaint(this, w, rx - 1, style->sepm, 1, sz.cy - 2 * style->sepm, style->sep2); r.right--; } } diff --git a/uppsrc/CtrlLib/Progress.cpp b/uppsrc/CtrlLib/Progress.cpp index 4ae888215..00b700862 100644 --- a/uppsrc/CtrlLib/Progress.cpp +++ b/uppsrc/CtrlLib/Progress.cpp @@ -82,14 +82,14 @@ void ProgressIndicator::Paint(Draw& w) { else { Rect r = GetMargins(); if(sz.cx > sz.cy) { - ChPaint(w, sz, style->hlook); + ChPaint(this, w, sz, style->hlook); w.Clip(r.left, r.top, sz.cx - r.left - r.right, sz.cy - r.top - r.bottom); - ChPaintNoCache(w, r.left + p0, r.top, p, sz.cy - r.top - r.bottom, style->hchunk); + ChPaintNoCache(this, w, r.left + p0, r.top, p, sz.cy - r.top - r.bottom, style->hchunk); } else { - ChPaint(w, sz, style->vlook); + ChPaint(this, w, sz, style->vlook); w.Clip(r.left, r.top, sz.cx - r.left - r.right, sz.cy - r.top - r.bottom); - ChPaintNoCache(w, r.left, sz.cy - r.bottom - p - p0, sz.cx - r.left - r.right, p, style->vchunk); + ChPaintNoCache(this, w, r.left, sz.cy - r.bottom - p - p0, sz.cx - r.left - r.right, p, style->vchunk); } w.End(); } diff --git a/uppsrc/CtrlLib/PushCtrl.h b/uppsrc/CtrlLib/PushCtrl.h index 1392eec3a..a9d0ba73b 100644 --- a/uppsrc/CtrlLib/PushCtrl.h +++ b/uppsrc/CtrlLib/PushCtrl.h @@ -106,7 +106,7 @@ public: static const Style& StyleScroll(); static const Style& StyleNaked(); - static void PaintButton(Draw& w, const Rect& r, const Button::Style& st, int visualstate, bool focus, + static void PaintButton(Ctrl *ctrl, Draw& w, const Rect& r, const Button::Style& st, int visualstate, bool focus, const String& label, Font font, const Image& img, bool monoimg, int accesskey, bool visibaleaccesskeys, bool disabled); diff --git a/uppsrc/CtrlLib/ScrollBar.cpp b/uppsrc/CtrlLib/ScrollBar.cpp index 786bb1964..b63e8023a 100644 --- a/uppsrc/CtrlLib/ScrollBar.cpp +++ b/uppsrc/CtrlLib/ScrollBar.cpp @@ -228,19 +228,19 @@ void ScrollBar::Paint(Draw& w) pr = style->through ? GetSize() : Slider(); } if(i != 2 || thumbsize >= style->thumbmin) - ChPaint(w, pr, l[i][p == i ? CTRL_PRESSED : light == i && !buttons_capture ? CTRL_HOT : CTRL_NORMAL]); + ChPaint(this, w, pr, l[i][p == i ? CTRL_PRESSED : light == i && !buttons_capture ? CTRL_HOT : CTRL_NORMAL]); if(i != 2) w.End(); } } else { if(style->through) - ChPaint(w, sz, l[0][CTRL_DISABLED]); + ChPaint(this, w, sz, l[0][CTRL_DISABLED]); else if(IsHorz()) - ChPaint(w, cc, 0, sz.cx, sz.cy, l[0][CTRL_DISABLED]); + ChPaint(this, w, cc, 0, sz.cx, sz.cy, l[0][CTRL_DISABLED]); else - ChPaint(w, 0, cc, sz.cx, sz.cy, l[0][CTRL_DISABLED]); + ChPaint(this, w, 0, cc, sz.cx, sz.cy, l[0][CTRL_DISABLED]); } PaintButtons(w, this); } diff --git a/uppsrc/CtrlLib/VirtualButtons.cpp b/uppsrc/CtrlLib/VirtualButtons.cpp index 2bbd1e94e..087d26104 100644 --- a/uppsrc/CtrlLib/VirtualButtons.cpp +++ b/uppsrc/CtrlLib/VirtualButtons.cpp @@ -40,7 +40,7 @@ void VirtualButtons::PaintButtons(Draw& w, Ctrl *ctrl) for(int i = 0; i < ButtonCount(); i++) { Rect r = ButtonRect(i); if(r.GetWidth() > 0 && r.GetHeight() > 0) - Button::PaintButton(w, ButtonRect(i), ButtonStyle(i), ButtonVisualState(ctrl, i), false, + Button::PaintButton(nullptr, w, ButtonRect(i), ButtonStyle(i), ButtonVisualState(ctrl, i), false, String(), StdFont(), ButtonImage(i), ButtonMono(i), 0, false, !ButtonEnabled(i)); } diff --git a/uppsrc/Draw/Cham.cpp b/uppsrc/Draw/Cham.cpp index 465cb8e4a..135feb2af 100644 --- a/uppsrc/Draw/Cham.cpp +++ b/uppsrc/Draw/Cham.cpp @@ -70,8 +70,6 @@ void ChLookWith(Value *look, const Image& image, const Color *color, int n) look[i] = ChLookWith(look[i], image, color[i]); } -Value sChOp(Draw& w, const Rect& r, const Value& v, int op, Color ink = Null); - struct sChBorder { const ColorF *border; Value face; @@ -300,13 +298,47 @@ Value ChLookFnImage(Draw& w, const Rect& r, const Image& img, int op, Color ink) return ChLookFnImage(w, r, img, op, ink, img.GetHotSpot(), img.Get2ndSpot()); } -Value StdChLookFn(Draw& w, const Rect& r, const Value& v, int op, Color ink) +struct ChPainterFn__ { + Value (*op)(Draw& w, const Rect& r, const Value& v, int op, Color ink) = nullptr; + Value (*op2)(Ctrl *ctrl, Draw& w, const Rect& r, const Value& v, int op, Color ink) = nullptr; +}; + +static Vector sChPainterFns; + +static Value sChOp(Ctrl *ctrl, Draw& w, const Rect& r, const Value& v, int op, Color ink = Null) +{ + if(r.right < r.left || r.bottom < r.top) + return Rect(0, 0, 0, 0); + Value q; + if(!IsNull(v)) + for(auto& a : ReverseRange(sChPainterFns)) { + q = a.op ? (*a.op)(w, r, v, op, ink) : (*a.op2)(ctrl, w, r, v, op, ink); + if(!IsNull(q)) + break; + } + return q; +} + +void ChLookFn(Value (*fn)(Draw& w, const Rect& r, const Value& v, int op, Color ink)) +{ + if(FindMatch(sChPainterFns, [&](const ChPainterFn__& m) { return m.op == fn; }) < 0) + sChPainterFns.Add().op = fn; +} + +void ChLookFn(Value (*fn)(Ctrl *ctrl, Draw& w, const Rect& r, const Value& v, int op, Color ink)) +{ + if(FindMatch(sChPainterFns, [&](const ChPainterFn__& m) { return m.op2 == fn; }) < 0) + sChPainterFns.Add().op2 = fn; +} + + +Value StdChLookFn(Ctrl *ctrl, Draw& w, const Rect& r, const Value& v, int op, Color ink) { if(IsType(v)) { const sChLookWith& x = ValueTo(v); if(op == LOOK_PAINT) { LOGPNG(AsString(x.img.GetSerialId()), x.img); - ChPaint(w, r, x.look); + ChPaint(ctrl, w, r, x.look); Point p = r.CenterPos(x.img.GetSize()) + x.offset; if(x.colorfn) w.DrawImage(p.x, p.y, x.img, (*x.colorfn)(x.ii)); @@ -317,7 +349,7 @@ Value StdChLookFn(Draw& w, const Rect& r, const Value& v, int op, Color ink) w.DrawImage(p.x, p.y, x.img); return 1; } - return sChOp(w, r, x.look, op); + return sChOp(ctrl, w, r, x.look, op); } if(IsType(v)) { @@ -325,7 +357,7 @@ Value StdChLookFn(Draw& w, const Rect& r, const Value& v, int op, Color ink) int n = (int)(intptr_t)*b.border; switch(op) { case LOOK_PAINT: - ChPaint(w, r.Deflated(n), b.face); + ChPaint(ctrl, w, r.Deflated(n), b.face); // fall through - need to paint border now case LOOK_PAINTEDGE: DrawBorder(w, r, b.border); @@ -355,20 +387,6 @@ Value StdChLookFn(Draw& w, const Rect& r, const Value& v, int op, Color ink) return Null; } -typedef Value (*ChPainterFn)(Draw& w, const Rect& r, const Value& v, int op, Color ink); - -Vector& sChps() -{ - static Vector x; - return x; -} - -void ChLookFn(Value (*fn)(Draw& w, const Rect& r, const Value& v, int op, Color ink)) -{ - if(FindIndex(sChps(), fn) < 0) - sChps().Add(fn); -} - struct sStyleCh : Moveable { byte *status; void (*init)(); @@ -437,43 +455,74 @@ void ChFinish() SColor::Refresh(); } -Value sChOp(Draw& w, const Rect& r, const Value& v, int op, Color ink) +void ChPaint(Ctrl *ctrl, Draw& w,const Rect& r, const Value& look, Color ink) { - if(r.right < r.left || r.bottom < r.top) - return Rect(0, 0, 0, 0); - Value q; - if(!IsNull(v)) - for(int i = sChps().GetCount() - 1; i >= 0; i--) { - q = (*sChps()[i])(w, r, v, op, ink); - if(!IsNull(q)) - break; - } - return q; + sChOp(ctrl, w, r, look, LOOK_PAINT, ink); +} + +void ChPaint(Ctrl *ctrl, Draw& w,int x, int y, int cx, int cy, const Value& look, Color ink) +{ + sChOp(ctrl, w, RectC(x, y, cx, cy), look, LOOK_PAINT, ink); +} + +void ChPaintNoCache(Ctrl *ctrl, Draw& w,int x, int y, int cx, int cy, const Value& look, Color ink) +{ + sChOp(ctrl, w, RectC(x, y, cx, cy), look, LOOK_PAINT|LOOK_NOCACHE, ink); +} + +void ChPaintEdge(Ctrl *ctrl, Draw& w,const Rect& r, const Value& look, Color ink) +{ + sChOp(ctrl, w, r, look, LOOK_PAINTEDGE, ink); +} + +void ChPaintEdge(Ctrl *ctrl, Draw& w,int x, int y, int cx, int cy, const Value& look, Color ink) +{ + sChOp(ctrl, w, RectC(x, y, cx, cy), look, LOOK_PAINTEDGE, ink); +} + +void ChPaintBody(Ctrl *ctrl, Draw& w, const Rect& r, const Value& look, Color ink) +{ + Rect m = ChMargins(ctrl, look); + w.Clip(r); + ChPaint(ctrl, w, Rect(r.left - m.left, r.top - m.top, r.right + m.right, r.bottom + m.bottom), + look, ink); + w.End(); +} + +void ChPaintBody(Ctrl *ctrl, Draw& w, int x, int y, int cx, int cy, const Value& look, Color ink) +{ + ChPaintBody(ctrl, w, RectC(x, y, cx, cy), look, ink); +} + +Rect ChMargins(Ctrl *ctrl, const Value& look) +{ + NilDraw w; + return sChOp(ctrl, w, Null, look, LOOK_MARGINS); } void ChPaint(Draw& w, const Rect& r, const Value& look, Color ink) { - sChOp(w, r, look, LOOK_PAINT, ink); + sChOp(nullptr, w, r, look, LOOK_PAINT, ink); } void ChPaint(Draw& w, int x, int y, int cx, int cy, const Value& look, Color ink) { - sChOp(w, RectC(x, y, cx, cy), look, LOOK_PAINT, ink); + sChOp(nullptr, w, RectC(x, y, cx, cy), look, LOOK_PAINT, ink); } void ChPaintNoCache(Draw& w, int x, int y, int cx, int cy, const Value& look, Color ink) { - sChOp(w, RectC(x, y, cx, cy), look, LOOK_PAINT|LOOK_NOCACHE, ink); + sChOp(nullptr, w, RectC(x, y, cx, cy), look, LOOK_PAINT|LOOK_NOCACHE, ink); } void ChPaintEdge(Draw& w, const Rect& r, const Value& look, Color ink) { - sChOp(w, r, look, LOOK_PAINTEDGE, ink); + sChOp(nullptr, w, r, look, LOOK_PAINTEDGE, ink); } void ChPaintEdge(Draw& w, int x, int y, int cx, int cy, const Value& look, Color ink) { - sChOp(w, RectC(x, y, cx, cy), look, LOOK_PAINTEDGE, ink); + sChOp(nullptr, w, RectC(x, y, cx, cy), look, LOOK_PAINTEDGE, ink); } void ChPaintBody(Draw& w, const Rect& r, const Value& look, Color ink) @@ -493,7 +542,7 @@ void ChPaintBody(Draw& w, int x, int y, int cx, int cy, const Value& look, Color Rect ChMargins(const Value& look) { NilDraw w; - return sChOp(w, Null, look, LOOK_MARGINS); + return sChOp(nullptr, w, Null, look, LOOK_MARGINS); } void DeflateMargins(Rect& r, const Rect& m) diff --git a/uppsrc/Draw/Cham.h b/uppsrc/Draw/Cham.h index 0a62eddaf..a25594a01 100644 --- a/uppsrc/Draw/Cham.h +++ b/uppsrc/Draw/Cham.h @@ -2,7 +2,7 @@ enum LookOp { LOOK_PAINT, LOOK_MARGINS, LOOK_PAINTEDGE, - + LOOK_NOCACHE = 0x8000, }; @@ -11,6 +11,9 @@ enum { CH_EDITFIELD_IMAGE = -1001, // special Image hotspot x2 value, y2 is then x and y for the purposes of painting }; +class Ctrl; + +void ChLookFn(Value (*fn)(Ctrl *ctrl, Draw& w, const Rect& r, const Value& look, int lookop, Color ink)); void ChLookFn(Value (*fn)(Draw& w, const Rect& r, const Value& look, int lookop, Color ink)); Image AdjustColors(const Image& img); @@ -21,6 +24,15 @@ void ColoredOverride(Iml& target, Iml& source); void ChReset(); void ChFinish(); +void ChPaint(Ctrl *ctrl, Draw& w,const Rect& r, const Value& look, Color ink = Null); +void ChPaint(Ctrl *ctrl, Draw& w,int x, int y, int cx, int cy, const Value& look, Color ink = Null); +void ChPaintNoCache(Ctrl *ctrl, Draw& w,int x, int y, int cx, int cy, const Value& look, Color ink = Null); +void ChPaintEdge(Ctrl *ctrl, Draw& w,const Rect& r, const Value& look, Color ink = Null); +void ChPaintEdge(Ctrl *ctrl, Draw& w,int x, int y, int cx, int cy, const Value& look, Color ink = Null); +void ChPaintBody(Ctrl *ctrl, Draw& w, const Rect& r, const Value& look, Color ink = Null); +void ChPaintBody(Ctrl *ctrl, Draw& w, int x, int y, int cx, int cy, const Value& look, Color ink = Null); +Rect ChMargins(Ctrl *ctrl, const Value& look); + void ChPaint(Draw& w, const Rect& r, const Value& look, Color ink = Null); void ChPaint(Draw& w, int x, int y, int cx, int cy, const Value& look, Color ink = Null); void ChPaintNoCache(Draw& w, int x, int y, int cx, int cy, const Value& look, Color ink = Null); @@ -119,4 +131,4 @@ void ChLookWith(Value *look, const Image& image, const Color *color, int n = 4) //private: void ChRegisterStyle__(byte& state, byte& registered, void (*init)()); -Value ChBorder(const ColorF *colors, const Value& face = SColorFace()); +Value ChBorder(const ColorF *colors, const Value& face = SColorFace()); \ No newline at end of file