]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/gfx/mw/v2_0/src/mwin/winlib/progbar.c
Initial revision
[karo-tx-redboot.git] / packages / services / gfx / mw / v2_0 / src / mwin / winlib / progbar.c
1 /*
2  * Copyright (C) 1999, 2000, Wei Yongming.
3  * Portions Copyright (c) 2000 Greg Haerr <greg@censoft.com>
4  *
5  * Progress bar for Microwindows win32 api.
6  */
7
8 /*
9 **  This library is free software; you can redistribute it and/or
10 **  modify it under the terms of the GNU Library General Public
11 **  License as published by the Free Software Foundation; either
12 **  version 2 of the License, or (at your option) any later version.
13 **
14 **  This library is distributed in the hope that it will be useful,
15 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 **  Library General Public License for more details.
18 **
19 **  You should have received a copy of the GNU Library General Public
20 **  License along with this library; if not, write to the Free
21 **  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22 **  MA 02111-1307, USA
23 */
24
25 /*
26 **  Alternatively, the contents of this file may be used under the terms 
27 **  of the Mozilla Public License (the "MPL License") in which case the
28 **  provisions of the MPL License are applicable instead of those above.
29 */
30
31 /* Copyright (C) 1999, 2000, Wei Yongming.
32 **
33 ** Note:
34 **   Originally by Zhao Jianghua. 
35 **
36 ** Create date: 1999/8/29
37 **
38 ** Modify records:
39 **
40 **  Who             When        Where       For What                Status
41 **-----------------------------------------------------------------------------
42 **  WEI Yongming    1999/10/27  Tsinghua    unsigned int            Finished
43 **  WEI Yongming    1999/10/27  Tsinghua    FPException fixing      Finished
44 **  WEI Yongming    2000/02/24  Tsinghua    Add MPL License         Finished
45 **  Kevin Tseng     2000/05/24  gv          port to microwin        ported
46 **  Greg Haerr      2000/06/15  Utah        removed floats          Finished
47 */
48
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #define MWINCLUDECOLORS
53 #include "windows.h"    /* windef.h, winuser.h */
54 #include "wintools.h"   /* Draw3dBox */
55 #include "device.h"     /* GdGetTextSize */
56
57 #define TEST    1       /* =1 for testing*/
58
59 #define  WIDTH_PBAR_BORDER  2 
60
61 typedef  struct _PROGRESSDATA {
62     unsigned int nMin;
63     unsigned int nMax;
64     unsigned int nPos;
65     unsigned int nStepInc;
66 } PROGRESSDATA, *PPROGRESSDATA;
67
68 static LRESULT CALLBACK
69 ProgressBarCtrlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
70
71 int WINAPI MwRegisterProgressBarControl(HINSTANCE hInstance)
72 {
73         WNDCLASS        wc;
74
75         wc.style        = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS;
76         wc.lpfnWndProc  = (WNDPROC)ProgressBarCtrlProc;
77         wc.cbClsExtra   = 0;
78         wc.cbWndExtra   = 0;
79         wc.hInstance    = hInstance;
80         wc.hIcon        = NULL;
81         wc.hCursor      = 0; /*LoadCursor(NULL, IDC_ARROW);*/
82         wc.hbrBackground= GetStockObject(LTGRAY_BRUSH);
83         wc.lpszMenuName = NULL;
84         wc.lpszClassName= "PROGBAR";
85
86         return RegisterClass(&wc);
87 }
88
89 static void
90 FillBox(HDC hdc, int x, int y, int w, int h, COLORREF cr)
91 {
92         RECT    rc;
93
94         if (w <= 0)
95                 return;
96         SetRect(&rc, x, y, x+w, y+h);
97         FastFillRect(hdc, &rc, cr);
98 }
99
100 static int
101 GetSysCharWidth(HDC hdc)
102 {
103         int     cw, ch, cb;
104
105         GdGetTextSize(hdc->font->pfont,"X",1, &cw,&ch,&cb,MWTF_ASCII);
106         return cw;
107 }
108
109 static int
110 GetSysCharHeight(HDC hdc)
111 {
112         int     cw, ch, cb;
113
114         GdGetTextSize(hdc->font->pfont,"X",1, &cw,&ch,&cb,MWTF_ASCII);
115         return ch;
116 }
117
118 void pbarOnDraw (HWND hwnd, HDC hdc, PROGRESSDATA* pData, BOOL fVertical,
119         BOOL fErase)
120 {
121     int     x, y, w, h;
122     unsigned int     nAllPart;
123     unsigned int     nNowPart;
124     int     whOne, nRem;
125     int     ix, iy;
126     int     i;
127     int     step;
128     COLORREF cr;
129     RECT    rcClient;
130     char    szText[8];
131     
132     if (!hdc || (pData->nMax == pData->nMin))
133         return;
134     
135     if ((pData->nMax - pData->nMin) > 5)
136         step = 5;
137     else
138         step = 1;
139
140     GetClientRect (hwnd, &rcClient);
141     SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
142
143     x = rcClient.left + WIDTH_PBAR_BORDER;
144     y = rcClient.top + WIDTH_PBAR_BORDER;
145     w = (rcClient.right - rcClient.left) - (WIDTH_PBAR_BORDER << 1);
146     h = (rcClient.bottom - rcClient.top) - (WIDTH_PBAR_BORDER << 1);
147
148     nAllPart = (pData->nMax - pData->nMin) / step;
149     nNowPart = (pData->nPos - pData->nMin) / step;
150     if (fVertical) {
151         whOne = h / nAllPart;
152         nRem = h % nAllPart;
153     } else {
154         whOne = w / nAllPart;
155         nRem = w % nAllPart;
156     }
157         
158     if (fErase)
159         FillBox (hdc, x, y, w, h, GetSysColor(COLOR_BTNSHADOW));
160
161     if(whOne >= 4) {
162         if (fVertical) {
163             for (i = 0, iy = y + h - 1; i < nNowPart; ++i) {
164 #if 0
165                 if ((iy - whOne) < y) 
166                     whOne = iy - y;
167 #endif
168
169                 FillBox (hdc, x, iy - whOne, w, whOne - 1, BLUE);
170
171                 iy -= whOne + 1;
172 #if 0
173                 if(nRem > 0) {
174                     iy --;
175                     nRem --;
176                 }
177 #endif
178             }
179         }
180         else {
181             for (i = 0, ix = x + 1; i < nNowPart; ++i) {
182 #if 0
183                 if ((ix + whOne) > (x + w)) 
184                     whOne = x + w - ix;
185 #endif
186                 FillBox (hdc, ix, y, whOne - 1, h, BLUE);
187                 ix += whOne + 1;
188 #if 0
189                 if(nRem > 0) {
190                     ix ++;
191                     nRem --;
192                 }
193 #endif
194             }
195         }
196     }
197     else {
198         /* no vertical support */
199         int d = nNowPart*100/nAllPart;
200         int maxw = GetSysCharWidth (hdc) << 2;
201         int charh = GetSysCharHeight (hdc);
202
203         if (d > 50)
204             cr = BLUE;
205         else
206             cr = GetSysColor(COLOR_BTNSHADOW);
207         FillBox (hdc, x + ((w - maxw)>>1), y + ((h - charh) > 1), maxw,
208                 charh - 1, cr);
209         FillBox (hdc, x, y, (int)((long)w*d/100L), h, BLUE);
210         SetTextColor (hdc, WHITE);
211         SetBkMode (hdc, TRANSPARENT);
212         sprintf (szText, "%d%%", d);
213         TextOut (hdc, x + ((w - GetSysCharWidth (hdc) * strlen (szText) )>>1), 
214                       y + ((h - GetSysCharHeight(hdc) )>>1), 
215                       szText, strlen(szText));
216     }
217 }
218
219 static void pbarNormalizeParams (const HWND pCtrl, 
220                 PROGRESSDATA* pData, BOOL fNotify)
221 {
222     if (pData->nPos > pData->nMax) {
223         if (fNotify)
224             SendMessage (GetParent ((HWND)pCtrl), WM_COMMAND, 
225                 (WPARAM)MAKELONG (pCtrl->id, PBN_REACHMAX), (LPARAM)pCtrl);
226         pData->nPos = pData->nMax;
227     }
228
229     if (pData->nPos < pData->nMin) {
230         if (fNotify)
231             SendMessage (GetParent ((HWND)pCtrl), WM_COMMAND, 
232                 (WPARAM)MAKELONG (pCtrl->id, PBN_REACHMIN), (LPARAM)pCtrl);
233         pData->nPos = pData->nMin;
234     }
235 }
236
237 static LRESULT CALLBACK
238 ProgressBarCtrlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
239 {
240     HDC           hdc;
241     HWND          pCtrl;
242     PROGRESSDATA* pData;
243     BOOL          fErase;
244     RECT        rc;
245     PAINTSTRUCT ps;
246     int         pos;
247     
248     pCtrl = hwnd;
249     
250     switch (message)
251     {
252         case WM_CREATE:
253             if (!(pData = malloc (sizeof (PROGRESSDATA)))) {
254                 fprintf(stderr, "Create progress bar control failure!\n");
255                 return -1;
256             }
257             
258 #if TEST
259             pData->nMax     = 1000;
260             pData->nMin     = 0;
261             pData->nPos     = 500;
262             pData->nStepInc = 100;
263 #else
264             pData->nMax     = 100;
265             pData->nMin     = 0;
266             pData->nPos     = 0;
267             pData->nStepInc = 10;
268 #endif
269
270             pCtrl->userdata = (DWORD)pData;
271         break;
272     
273         case WM_DESTROY:
274             free ((void *)(pCtrl->userdata));
275         break;
276
277         case WM_GETDLGCODE:
278             return DLGC_STATIC;
279
280         case WM_NCPAINT:
281                 if(GetWindowLong(hwnd, GWL_STYLE) & WS_BORDER) {
282                         GetWindowRect(hwnd, &rc);
283                         hdc = GetWindowDC(hwnd);
284                         Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left,
285                                 rc.bottom-rc.top, GetSysColor(COLOR_BTNSHADOW),
286                                 GetSysColor(COLOR_BTNHIGHLIGHT));
287                 }
288             break;
289
290         case WM_PAINT:
291             hdc = BeginPaint (hwnd,&ps);
292             pbarOnDraw (hwnd, hdc, (PROGRESSDATA *)pCtrl->userdata, 
293                             hwnd->style & PBS_VERTICAL, TRUE);
294             EndPaint (hwnd, &ps);
295             break;
296
297         case PBM_SETRANGE:
298             pData = (PROGRESSDATA *)pCtrl->userdata;
299             pData->nMin = min (wParam, lParam);
300             pData->nMax = max (wParam, lParam);
301             if (pData->nPos > pData->nMax)
302                 pData->nPos = pData->nMax;
303             if (pData->nPos < pData->nMin)
304                 pData->nPos = pData->nMin;
305         break;
306         
307         case PBM_SETSTEP:
308             pData = (PROGRESSDATA *)pCtrl->userdata;
309             pData->nStepInc = wParam;
310         break;
311         
312         case PBM_SETPOS:
313             pData = (PROGRESSDATA *)pCtrl->userdata;
314             
315             if (pData->nPos == wParam)
316                 break;
317
318             fErase = (wParam < pData->nPos);
319             pData->nPos = wParam;
320             pbarNormalizeParams (pCtrl, pData, hwnd->style & PBS_NOTIFY);
321             InvalidateRect(hwnd, NULL, fErase);
322         break;
323         
324         case PBM_DELTAPOS:
325             pData = (PROGRESSDATA *)pCtrl->userdata;
326
327             if (wParam == 0)
328                 break;
329             
330             fErase = (wParam < 0);
331             pData->nPos += wParam;
332             pbarNormalizeParams (pCtrl, pData, hwnd->style & PBS_NOTIFY);
333             InvalidateRect(hwnd, NULL, fErase);
334         break;
335         
336         case PBM_STEPIT:
337             pData = (PROGRESSDATA *)pCtrl->userdata;
338             
339             if (pData->nStepInc == 0)
340                 break;
341
342             fErase = (pData->nStepInc < 0);
343             pData->nPos += pData->nStepInc;
344             pbarNormalizeParams (pCtrl, pData, hwnd->style & PBS_NOTIFY);
345             InvalidateRect(hwnd, NULL, fErase);
346         break;
347             
348 #if TEST
349         case WM_LBUTTONDOWN:
350         case WM_LBUTTONDBLCLK:
351                 pData = (PROGRESSDATA *)pCtrl->userdata;
352                 pos = pData->nPos;
353                 pos += pData->nStepInc;
354                 if (pos > pData->nMax)
355                         pos = pData->nMin;
356                 SendMessage(hwnd, PBM_SETPOS, pos, 0L);
357                 break;
358 #endif
359         default:
360                 return DefWindowProc (hwnd, message, wParam, lParam);
361     }
362     return 0;
363 }