1 // Written by Christopher E. Miller
2 // See the included license.txt for copyright and license details.
3 
4 module dfl.progressbar;
5 import core.sys.windows.windows;
6 import core.sys.windows.commctrl;
7 
8 import dfl.application;
9 import dfl.base;
10 import dfl.control;
11 import dfl.drawing;
12 import dfl.event;
13 import dfl.exception;
14 static import dfl.internal.utf;
15 
16 private extern (Windows) void _initProgressbar();
17 
18 class ProgressBar : ControlSuperClass {
19    this() {
20       _initProgressbar();
21 
22       wexstyle |= WS_EX_CLIENTEDGE;
23       wclassStyle = progressbarClassStyle;
24    }
25 
26    final @property void maximum(int max) {
27       if (max <= 0 /+ || max < _min +/ ) {
28          //bad_max:
29          //throw new DflException("Unable to set progress bar maximum value");
30          if (max) {
31             return;
32          }
33       }
34 
35       if (created) {
36          prevwproc(PBM_SETRANGE, 0, MAKELPARAM(_min, max));
37       }
38 
39       _max = max;
40 
41       if (_val > max) {
42          _val = max; // ?
43       }
44    }
45 
46    final @property int maximum() {
47       return _max;
48    }
49 
50    final @property void minimum(int min) {
51       if (min < 0 /+ || min > _max +/ ) {
52          //bad_min:
53          //throw new DflException("Unable to set progress bar minimum value");
54          return;
55       }
56 
57       if (created) {
58          prevwproc(PBM_SETRANGE, 0, MAKELPARAM(min, _max));
59       }
60 
61       _min = min;
62 
63       if (_val < min) {
64          _val = min; // ?
65       }
66    }
67 
68    final @property int minimum() {
69       return _min;
70    }
71 
72    final @property void step(int stepby) {
73       if (stepby <= 0 /+ || stepby > _max +/ ) {
74          //bad_max:
75          //throw new DflException("Unable to set progress bar step value");
76          if (stepby) {
77             return;
78          }
79       }
80 
81       if (created) {
82          prevwproc(PBM_SETSTEP, stepby, 0);
83       }
84 
85       _step = stepby;
86    }
87 
88    final @property int step() {
89       return _step;
90    }
91 
92    final @property void value(int setval) {
93       if (setval < _min || setval > _max) {
94          //throw new DflException("Progress bar value out of minimum/maximum range");
95          //return;
96          if (setval > _max) {
97             setval = _max;
98          } else {
99             setval = _min;
100          }
101       }
102 
103       if (created) {
104          prevwproc(PBM_SETPOS, setval, 0);
105       }
106 
107       _val = setval;
108    }
109 
110    final @property int value() {
111       return _val;
112    }
113 
114    final void increment(int incby) {
115       int newpos = _val + incby;
116       if (newpos < _min) {
117          newpos = _min;
118       }
119       if (newpos > _max) {
120          newpos = _max;
121       }
122 
123       if (created) {
124          prevwproc(PBM_SETPOS, newpos, 0);
125       }
126 
127       _val = newpos;
128    }
129 
130    final void performStep() {
131       increment(_step);
132    }
133 
134    protected override void onHandleCreated(EventArgs ea) {
135       super.onHandleCreated(ea);
136 
137       if (_min != MIN_INIT || _max != MAX_INIT) {
138          prevwproc(PBM_SETRANGE, 0, MAKELPARAM(_min, _max));
139       }
140 
141       if (_step != STEP_INIT) {
142          prevwproc(PBM_SETSTEP, _step, 0);
143       }
144 
145       if (_val != VAL_INIT) {
146          prevwproc(PBM_SETPOS, _val, 0);
147       }
148    }
149 
150    protected override @property Size defaultSize() {
151       return Size(100, 23);
152    }
153 
154    static @property Color defaultForeColor() {
155       return SystemColors.highlight;
156    }
157 
158    protected override void createParams(ref CreateParams cp) {
159       super.createParams(cp);
160 
161       cp.className = PROGRESSBAR_CLASSNAME;
162    }
163 
164    protected override void prevWndProc(ref Message msg) {
165       //msg.result = CallWindowProcA(progressbarPrevWndProc, msg.hWnd, msg.msg, msg.wParam, msg.lParam);
166       msg.result = dfl.internal.utf.callWindowProc(progressbarPrevWndProc,
167          msg.hWnd, msg.msg, msg.wParam, msg.lParam);
168    }
169 
170 private:
171 
172    enum MIN_INIT = 0;
173    enum MAX_INIT = 100;
174    enum STEP_INIT = 10;
175    enum VAL_INIT = 0;
176 
177    int _min = MIN_INIT, _max = MAX_INIT, _step = STEP_INIT, _val = VAL_INIT;
178 
179 package:
180 final:
181    LRESULT prevwproc(UINT msg, WPARAM wparam, LPARAM lparam) {
182       //return CallWindowProcA(progressbarPrevWndProc, hwnd, msg, wparam, lparam);
183       return dfl.internal.utf.callWindowProc(progressbarPrevWndProc, hwnd, msg, wparam,
184          lparam);
185    }
186 }