egra: splitted widgets to package with separate submodules
[iv.d.git] / egra / gui / widgets / progbar.d
blobe37eb8cd19304714d09a8af0b0b9c9971cae1ed4
1 /*
2 * Simple Framebuffer Gfx/GUI lib
4 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
5 * Understanding is not required. Only obedience.
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 3 of the License ONLY.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 module iv.egra.gui.widgets.progbar /*is aliced*/;
20 private:
22 import arsd.simpledisplay;
24 import iv.egra.gfx;
26 import iv.alice;
27 import iv.cmdcon;
28 import iv.dynstring;
29 import iv.strex;
30 import iv.utfutil;
32 import iv.egra.gui.subwindows;
33 import iv.egra.gui.widgets.base;
34 import iv.egra.gui.widgets.labels;
37 // ////////////////////////////////////////////////////////////////////////// //
38 public class ProgressBarWidget : LabelWidget {
39 protected:
40 int mMin = 0;
41 int mMax = 100;
42 int mCurrent = 0;
43 int lastWidth = int.min;
44 int lastPxFull = int.min;
46 private:
47 final bool updateLast () {
48 bool res = false;
49 if (width != lastWidth) {
50 lastWidth = width;
51 res = true;
53 if (lastWidth < 1) {
54 if (lastPxFull != 0) {
55 res = true;
56 lastPxFull = 0;
58 } else {
59 int pxFull;
60 if (mMin == mMax) {
61 pxFull = lastWidth;
62 } else {
63 pxFull = cast(int)(cast(long)lastWidth*cast(long)(mCurrent-mMin)/cast(long)(mMax-mMin));
65 if (pxFull != lastPxFull) {
66 res = true;
67 lastPxFull = pxFull;
70 if (res) widgetChanged();
71 return res;
74 public:
75 this(T:const(char)[]) (Widget aparent, T atext, HAlign horiz=HAlign.Center, VAlign vert=VAlign.Center) {
76 super(aparent, atext, horiz, vert);
77 height = height+4;
80 this(T:const(char)[]) (T atext, HAlign horiz=HAlign.Center, VAlign vert=VAlign.Center) {
81 assert(creatorCurrentParent !is null);
82 this(creatorCurrentParent, atext, horiz, vert);
85 final void setMinMax (int amin, int amax) {
86 if (amin > amax) { immutable int tmp = amin; amin = amax; amax = tmp; }
87 mMin = amin;
88 mMax = amax;
89 if (mCurrent < mMin) mCurrent = mMin;
90 if (mCurrent > mMax) mCurrent = mMax;
91 updateLast();
94 final @property int current () const nothrow @safe @nogc {
95 pragma(inline, true);
96 return mCurrent;
99 final @property void current (int val) {
100 pragma(inline, true);
101 if (val < mMin) val = mMin;
102 if (val > mMax) val = mMax;
103 mCurrent = val;
104 updateLast();
107 // returns `true` if need to repaint
108 final bool setCurrentTotal (int val, int total) {
109 if (total < 0) total = 0;
110 setMinMax(0, total);
111 if (val < 0) val = 0;
112 if (val > total) val = total;
113 mCurrent = val;
114 return updateLast();
117 protected void drawStripes (GxRect rect, in bool asfull) {
118 if (rect.empty) return;
120 immutable int sty = rect.pos.y;
121 immutable int sth = rect.size.h;
123 GxRect uprc = rect;
124 if (rect.height > 4) uprc.size.h = 2;
125 else if (rect.height > 2) uprc.size.h = 1;
126 else uprc.size.h = 0;
127 if (uprc.size.h > 0) {
128 rect.pos.y += uprc.size.h;
129 rect.size.h -= uprc.size.h;
132 if (!uprc.empty) gxFillRect(uprc, getColor(asfull ? "back-full-hishade" : "back-hishade"));
133 gxFillRect(rect, getColor(asfull ? "back-full" : "back"));
135 immutable uint clrHi = getColor(asfull ? "stripe-full-hishade" : "stripe-hishade");
136 immutable uint clrOk = getColor(asfull ? "stripe-full" : "stripe");
138 foreach (int y0; 0..sth) {
139 gxHStripedLine(rect.pos.x-y0, sty+y0, rect.size.w+y0, 16, (y0 < uprc.size.h ? clrHi : clrOk));
143 protected override void doPaint (GxRect grect) {
144 immutable uint clrRect = getColor("rect");
146 gxDrawRect(grect, clrRect);
147 gxClipRect.shrinkBy(1, 1);
148 grect.shrinkBy(1, 1);
149 if (grect.empty) return;
151 if (lastWidth != width) updateLast();
152 immutable int pxFull = lastPxFull;
154 if (pxFull > 0) {
155 gxWithSavedClip{
156 GxRect rc = GxRect(grect.pos, pxFull, grect.height);
157 if (gxClipRect.intersect(rc)) drawStripes(rc, asfull:true);
161 if (pxFull < grect.width) {
162 gxWithSavedClip{
163 GxRect rc = grect;
164 rc.pos.x += pxFull;
165 if (gxClipRect.intersect(rc)) drawStripes(grect, asfull:false);
169 if (grect.height > 2) grect.moveLeftTopBy(0, 1);
170 drawLabel(grect);