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