libroken: Build on windows
[openafs.git] / src / WINNT / afssvrcfg / graphics.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /*
11  * INCLUDES ___________________________________________________________________
12  *
13  */
14 #include <winsock2.h>
15 #include <ws2tcpip.h>
16
17 extern "C" {
18 #include <afsconfig.h>
19 #include <afs/param.h>
20 #include <afs/stds.h>
21 #include <roken.h>
22 }
23
24 #include "afscfg.h"
25 #include "config.h"
26 #include "graphics.h"
27 #include "resource.h"
28
29
30 /*
31  * DEFINITIONS _________________________________________________________________
32  *
33  */
34 static const COLORREF STEP_IN_PROGRESS_COLOR = 0x00FF00;                // Green
35 static const COLORREF STEP_TO_BE_DONE_COLOR = 0xFF0000;                 // Blue
36
37
38 /*
39  * STATIC FUNCTIONS _________________________________________________________________
40  *
41  */
42 static void EraseRect(HDC hdc, RECT rect)
43 {
44     HBRUSH hbr = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
45     HGDIOBJ hbrOld = SelectObject(hdc, hbr);
46
47     HPEN hPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNFACE));
48     HGDIOBJ hOldPen = SelectObject(hdc, hPen);
49
50     Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
51
52     SelectObject(hdc, hOldPen);
53     SelectObject(hdc, hbrOld);
54
55     DeleteObject(hPen);
56     DeleteObject(hbr);
57 }       
58
59 static void DrawCircle(HDC hdc, RECT rect, COLORREF crCircleColor)
60 {
61     HBRUSH hBrush = CreateSolidBrush(crCircleColor);
62     HGDIOBJ hOldBrush = SelectObject(hdc, hBrush);
63
64     HPEN hPen = CreatePen(PS_SOLID, 1, crCircleColor);
65     HGDIOBJ hOldPen = SelectObject(hdc, hPen);
66
67     OffsetRect(&rect, 1, -1);
68
69     int midX = rect.left + ((rect.right - rect.left) / 2);
70     int midY = rect.top + ((rect.bottom - rect.top) / 2);
71         
72     MoveToEx(hdc, midX - 1, midY - 2, 0);
73     LineTo(hdc, midX + 2, midY - 2);
74
75     MoveToEx(hdc, midX - 2, midY - 1, 0);
76     LineTo(hdc, midX + 3, midY - 1);
77
78     MoveToEx(hdc, midX - 2, midY, 0);
79     LineTo(hdc, midX + 3, midY);
80
81     MoveToEx(hdc, midX - 2, midY + 1, 0);
82     LineTo(hdc, midX + 3, midY + 1);
83
84     MoveToEx(hdc, midX - 1, midY + 2, 0);
85     LineTo(hdc, midX + 2, midY + 2);
86
87     SelectObject(hdc, hOldPen);
88     SelectObject(hdc, hOldBrush);
89
90     DeleteObject(hPen);
91     DeleteObject(hBrush);
92 }       
93
94 static void DrawCheckmark(HDC hdc, RECT rect)
95 {
96 #define cxCHECKBOX        (2+9+2)
97 #define cyCHECKBOX        (2+9+2)
98         
99     // Checkmark
100     HPEN hpNew = CreatePen(PS_SOLID, 1, RGB(0,0,0));
101     HGDIOBJ hpOld = (HPEN)SelectObject(hdc, hpNew);
102
103     POINT ptCheckbox;
104     ptCheckbox.x = rect.left;
105     ptCheckbox.y = rect.top + ((rect.bottom - rect.top) - cyCHECKBOX) / 2;
106         
107     MoveToEx(hdc, ptCheckbox.x +3, ptCheckbox.y+5, NULL);
108     LineTo(hdc, ptCheckbox.x +5, ptCheckbox.y+7);
109     LineTo(hdc, ptCheckbox.x+10, ptCheckbox.y+2);
110
111     MoveToEx(hdc, ptCheckbox.x +3, ptCheckbox.y+6, NULL);
112     LineTo(hdc, ptCheckbox.x +5, ptCheckbox.y+8);
113     LineTo(hdc, ptCheckbox.x+10, ptCheckbox.y+3);
114
115     MoveToEx(hdc, ptCheckbox.x +3, ptCheckbox.y+7, NULL);
116     LineTo(hdc, ptCheckbox.x +5, ptCheckbox.y+9);
117     LineTo(hdc, ptCheckbox.x+10, ptCheckbox.y+4);
118
119     SelectObject(hdc, hpOld);
120     DeleteObject(hpNew);
121 }
122
123 static void DrawX(HDC hdc, RECT rect)
124 {
125     // Red X
126     static COLORREF crXColor = 0X0000FF;
127
128     HBRUSH hbrRed = CreateSolidBrush(crXColor);
129     HGDIOBJ hbrOld = SelectObject(hdc, hbrRed);
130
131     HPEN hPen = CreatePen(PS_SOLID, 1, crXColor);
132     HGDIOBJ hOldPen = SelectObject(hdc, hPen);
133
134     OffsetRect(&rect, 3, 0);
135
136     rect.top++;
137     rect.bottom++;
138
139     int nLen = 7;
140
141     MoveToEx(hdc, rect.left, rect.top, 0);
142     LineTo(hdc, rect.left + nLen, rect.top + nLen);
143
144     MoveToEx(hdc, rect.left, rect.top + 1, 0);
145     LineTo(hdc, rect.left + nLen, rect.top + nLen + 1);
146
147     MoveToEx(hdc, rect.left, rect.top - 1, 0);
148     LineTo(hdc, rect.left + nLen, rect.top + nLen - 1);
149
150     MoveToEx(hdc, rect.left + nLen - 1, rect.top, 0);
151     LineTo(hdc, rect.left - 1, rect.top + nLen);
152
153     MoveToEx(hdc, rect.left + nLen - 1, rect.top + 1, 0);
154     LineTo(hdc, rect.left - 1, rect.top + nLen + 1);
155
156     MoveToEx(hdc, rect.left + nLen - 1, rect.top - 1, 0);
157     LineTo(hdc, rect.left - 1, rect.top + nLen - 1);
158
159     SelectObject(hdc, hOldPen);
160     SelectObject(hdc, hbrOld);
161
162     DeleteObject(hPen);
163     DeleteObject(hbrRed);
164 }
165
166
167 /*
168  * EXPORTED FUNCTIONS _________________________________________________________
169  *
170  */
171 void PaintStepGraphic(HWND hwnd, STEP_STATE state)
172 {
173     PAINTSTRUCT ps;
174
175     HDC hdc = BeginPaint(hwnd, &ps);
176     _ASSERTE(hdc);
177
178     RECT rect;
179     GetClientRect(hwnd, &rect);
180
181     InflateRect(&rect, -2, -2);
182
183     // First erase the background
184     EraseRect(hdc, rect);
185
186     // Draw an image that corresponds to the state
187     switch (state) {
188     case SS_STEP_IN_PROGRESS:   
189         DrawCircle(hdc, rect, STEP_IN_PROGRESS_COLOR);
190         break;
191
192     case SS_STEP_TO_BE_DONE:    
193         DrawCircle(hdc, rect, STEP_TO_BE_DONE_COLOR);
194         break;
195
196     case SS_STEP_FINISHED:              
197         DrawCheckmark(hdc, rect);
198         break;
199
200         
201     case SS_STEP_FAILED: 
202         DrawX(hdc, rect);
203         break;
204     }
205         
206     EndPaint(hwnd, &ps);
207 }
208
209
210 #define clrWHITE           RGB(255,255,255)
211 #define clrHIGHLIGHT       RGB(192,192,192)
212 #define clrSHADOW          RGB(128,128,128)
213 #define clrBLACK           RGB(100,100,100)
214 #define clrBAR_INT_LEFT    RGB(0,255,0)
215 #define clrBAR_INT_RIGHT   RGB(128,0,0)
216 #define clrARROW_INTERIOR  RGB(128,128,0)
217 #define clrTEXT_CURRENT    RGB(255,255,255)
218 #define clrTEXT_STEP       RGB(0,255,0)
219
220 #define cxLEFT_MARGIN      10
221 #define cxRIGHT_MARGIN     10
222 #define cyBOTTOM_MARGIN     5
223 #define cyAREA             100
224 #define cyBELOW_CURRENT    15
225 #define cyBELOW_ARROW      10
226
227 void CALLBACK PaintPageGraphic(LPWIZARD pWiz, HDC hdc, LPRECT prTarget, HPALETTE hpal)
228 {
229     static HFONT hFont = AfsAppLib_CreateFont(IDS_GRAPHIC_FONT);
230     static HPEN hPenWhite = CreatePen(PS_SOLID, 1, clrWHITE);
231     static HPEN hPenHighlight = CreatePen(PS_SOLID, 1, clrHIGHLIGHT);
232     static HPEN hPenShadow = CreatePen(PS_SOLID, 1, clrSHADOW);
233     static HPEN hPenBlack = CreatePen(PS_SOLID, 1, clrBLACK);
234     static HPEN hPenBarIntLeft = CreatePen(PS_SOLID, 1, clrBAR_INT_LEFT);
235     static HPEN hPenBarIntRight = CreatePen(PS_SOLID, 1, clrBAR_INT_RIGHT);
236     static HPEN hPenArrowInterior = CreatePen(PS_SOLID, 1, clrARROW_INTERIOR);
237
238     // First find out where we'll be drawing things.
239     RECT rArea;
240     rArea.top = prTarget->bottom - cyAREA - cyBOTTOM_MARGIN;
241     rArea.bottom = prTarget->bottom - cyBOTTOM_MARGIN;
242     rArea.left = prTarget->left + cxLEFT_MARGIN;
243     rArea.right = prTarget->right - cxRIGHT_MARGIN;
244
245     // Draw the "Current Step:" text
246     HGDIOBJ hFontOld = SelectObject(hdc, hFont);
247     COLORREF clrTextOld = SetTextColor (hdc, clrTEXT_CURRENT);
248     SetBkMode (hdc, TRANSPARENT);
249
250     TCHAR szText[cchRESOURCE];
251     GetResString(IDS_CURRENT_STEP, szText);
252
253     RECT rText = rArea;
254     DWORD dwFlags = DT_CENTER | DT_TOP | DT_SINGLELINE;
255     DrawTextEx (hdc, szText, lstrlen(szText), &rText, dwFlags | DT_CALCRECT, NULL);
256
257     rText.right = rArea.right;
258     DrawTextEx (hdc, szText, lstrlen(szText), &rText, dwFlags, NULL);
259
260     // Draw the progress bar; it should look like this:
261     // wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww   // (w=white, b=black...
262     // whhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhb   //  h=highlight, s=shadow...
263     // whllllllllllllllllrrrrrrrrrrrrrrrsb   //  l=left/int, r=right/int)
264     // whllllllllllllllllrrrrrrrrrrrrrrrsb   //  l=left/int, r=right/int)
265     // whssssssssssssssssssssssssssssssssb   //  h=highlight, s=shadow...
266     // wbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb   //  h=highlight, s=shadow...
267
268     // Oh--we'll need to know where the pointer's point should go. We'll
269     // make that be where the leftmost dot of the pointer's tip, and the
270     // rightmost dot that's colored "l". One state 0, we want the pointer
271     // to be all the way to the left--and on state {g_nNumStates-1}, we want
272     // it all the way to the right
273
274     RECT rBar = rArea;
275     rBar.top = rText.bottom + cyBELOW_CURRENT;
276     rBar.bottom = rBar.top + 6;
277
278     RECT rBarInterior = rBar;
279     InflateRect (&rBarInterior, -2, -2);
280
281     int nStepSize = (rBarInterior.right - rBarInterior.left) / (g_nNumStates-1);
282     int xCurPos = rBarInterior.left + (g_pWiz->GetState() * nStepSize);
283     if (!g_pWiz->GetState())
284         xCurPos = rBarInterior.left-1;  // don't draw *any* green
285     else if (g_pWiz->GetState() == (int)(g_nNumStates-1))
286         xCurPos = rBarInterior.right-1;  // don't draw *any* red
287
288     // Draw that bar!
289     HGDIOBJ hPenOld = SelectObject (hdc, hPenWhite);
290     MoveToEx (hdc, rBar.left, rBar.bottom-1, 0);
291     LineTo (hdc, rBar.left, rBar.top);
292     LineTo (hdc, rBar.right, rBar.top);
293     MoveToEx (hdc, rBar.left, rBar.bottom, 0);
294
295     SelectObject (hdc, hPenHighlight);
296     MoveToEx (hdc, rBar.left+1, rBar.bottom-2, 0);
297     LineTo (hdc, rBar.left+1, rBar.top+1);
298     LineTo (hdc, rBar.right-1, rBar.top+1);
299
300     SelectObject (hdc, hPenShadow);
301     MoveToEx (hdc, rBar.left+2, rBar.bottom-2, 0);
302     LineTo (hdc, rBar.right-2, rBar.bottom-2);
303     LineTo (hdc, rBar.right-2, rBar.top+1);
304
305     SelectObject (hdc, hPenBlack);
306     MoveToEx (hdc, rBar.left+1, rBar.bottom-1, 0);
307     LineTo (hdc, rBar.right-1, rBar.bottom-1);
308     LineTo (hdc, rBar.right-1, rBar.top);
309
310     if (xCurPos >= rBarInterior.left) {
311         SelectObject (hdc, hPenBarIntLeft);
312         MoveToEx (hdc, rBarInterior.left, rBarInterior.top, 0);
313         LineTo (hdc, xCurPos+1, rBarInterior.top);
314         MoveToEx (hdc, rBarInterior.left, rBarInterior.top+1, 0);
315         LineTo (hdc, xCurPos+1, rBarInterior.top+1);
316     }
317
318     if (xCurPos < rBarInterior.right-1) {
319         SelectObject (hdc, hPenBarIntRight);
320         MoveToEx (hdc, xCurPos+1, rBarInterior.top, 0);
321         LineTo (hdc, rBarInterior.right, rBarInterior.top);
322         MoveToEx (hdc, xCurPos+1, rBarInterior.top+1, 0);
323         LineTo (hdc, rBarInterior.right, rBarInterior.top+1);
324     }
325     SelectObject (hdc, hPenOld);
326
327     // Draw the arrow underneath it; it should look like this:
328     //             wb
329     //            whsb
330     //           whassb
331     //          whaaassb
332     //         whaaaaassb
333     //        wssssssssssb
334     // Remember that the topmost "w" is where xCurPos is.
335
336     RECT rArrow;
337     rArrow.top = rBar.bottom +1;
338     rArrow.bottom = rArrow.top +6;
339     rArrow.left = xCurPos -5;
340     rArrow.right = xCurPos +7;
341
342     hPenOld = SelectObject (hdc, hPenWhite);
343     MoveToEx (hdc, rArrow.left, rArrow.bottom-1, 0);
344     LineTo (hdc, xCurPos+1, rArrow.top-1);
345
346     SelectObject (hdc, hPenHighlight);
347     MoveToEx (hdc, rArrow.left+2, rArrow.bottom-2, 0);
348     LineTo (hdc, xCurPos+1, rArrow.top);
349
350     SelectObject (hdc, hPenShadow);
351     MoveToEx (hdc, rArrow.left+1, rArrow.bottom-1, 0);
352     LineTo (hdc, rArrow.right-1, rArrow.bottom-1);
353     MoveToEx (hdc, xCurPos+1, rArrow.top+1, 0);
354     LineTo (hdc, rArrow.right, rArrow.bottom);
355     MoveToEx (hdc, xCurPos+1, rArrow.top+2, 0);
356     LineTo (hdc, rArrow.right-1, rArrow.bottom);
357
358     SelectObject (hdc, hPenBlack);
359     MoveToEx (hdc, xCurPos+1, rArrow.top, 0);
360     LineTo (hdc, rArrow.right, rArrow.bottom);
361
362     //             wb
363     //            whsb
364     //           whassb
365     //          whaaassb
366     //         whaaaaassb
367     //        wssssssssssb
368
369     SelectObject (hdc, hPenArrowInterior);
370     MoveToEx (hdc, xCurPos, rArrow.top+2, 0);
371     LineTo (hdc, xCurPos+1, rArrow.top+2);
372     MoveToEx (hdc, xCurPos-1, rArrow.top+3, 0);
373     LineTo (hdc, xCurPos+2, rArrow.top+3);
374     MoveToEx (hdc, xCurPos-2, rArrow.top+4, 0);
375     LineTo (hdc, xCurPos+3, rArrow.top+4);
376
377     SelectObject (hdc, hPenOld);
378
379     // Draw the description text
380     SetTextColor (hdc, clrTEXT_STEP);
381     GetResString(g_StateDesc[g_pWiz->GetState()], szText);
382
383     rText = rArea;
384     rText.top = rArrow.bottom + cyBELOW_ARROW;
385     dwFlags = DT_CENTER | DT_TOP | DT_WORDBREAK;
386     DrawTextEx (hdc, szText, lstrlen(szText), &rText, dwFlags, NULL);
387
388     SetTextColor (hdc, clrTextOld);
389     SelectObject (hdc, hFontOld);
390 }       
391