delete .cvsignore
[reactos.git] / rosapps / dflat32 / window.c
1 /* ---------- window.c ------------- */
2
3 #include "dflat.h"
4
5 DFWINDOW DfInFocus = NULL;
6
7 int DfForeground, DfBackground; /* current video colors */
8
9 static void TopLine(DFWINDOW, int, DFRECT);
10
11 /* --------- create a window ------------ */
12 DFWINDOW DfDfCreateWindow(
13 DFCLASS class, /* class of this window */
14 char *ttl, /* title or NULL */
15 int left, int top, /* upper left coordinates */
16 int height, int width, /* dimensions */
17 void *extension, /* pointer to additional data */
18 DFWINDOW parent, /* parent of this window */
19 int (*wndproc)(struct DfWindow *,enum DfMessages,DF_PARAM,DF_PARAM),
20 int attrib) /* window attribute */
21 {
22 DFWINDOW wnd = DfCalloc(1, sizeof(struct DfWindow));
23 if (wnd != NULL) {
24 int base;
25 /* ----- height, width = -1: fill the screen ------- */
26 if (height == -1)
27 height = DfScreenHeight;
28 if (width == -1)
29 width = DfScreenWidth;
30 /* ----- coordinates -1, -1 = center the window ---- */
31 if (left == -1)
32 wnd->rc.lf = (DfScreenWidth-width)/2;
33 else
34 wnd->rc.lf = left;
35 if (top == -1)
36 wnd->rc.tp = (DfScreenHeight-height)/2;
37 else
38 wnd->rc.tp = top;
39 wnd->attrib = attrib;
40 if (ttl != NULL)
41 DfAddAttribute(wnd, DF_HASTITLEBAR);
42 if (wndproc == NULL)
43 wnd->wndproc = DfClassDefs[class].wndproc;
44 else
45 wnd->wndproc = wndproc;
46 /* ---- derive attributes of base classes ---- */
47 base = class;
48 while (base != -1) {
49 DfAddAttribute(wnd, DfClassDefs[base].attrib);
50 base = DfClassDefs[base].base;
51 }
52 if (parent)
53 {
54 if (!DfTestAttribute(wnd, DF_NOCLIP))
55 {
56 /* -- keep upper left DfWithin borders of parent - */
57 wnd->rc.lf = max(wnd->rc.lf,DfGetClientLeft(parent));
58 wnd->rc.tp = max(wnd->rc.tp,DfGetClientTop(parent));
59 }
60 }
61 else
62 parent = DfApplicationWindow;
63
64 wnd->class = class;
65 wnd->extension = extension;
66 wnd->rc.rt = DfGetLeft(wnd)+width-1;
67 wnd->rc.bt = DfGetTop(wnd)+height-1;
68 wnd->ht = height;
69 wnd->wd = width;
70 if (ttl != NULL)
71 DfInsertTitle(wnd, ttl);
72 wnd->parent = parent;
73 wnd->oldcondition = wnd->condition = DF_SRESTORED;
74 wnd->RestoredRC = wnd->rc;
75 DfInitWindowColors(wnd);
76 DfSendMessage(wnd, DFM_CREATE_WINDOW, 0, 0);
77 if (DfIsVisible(wnd))
78 DfSendMessage(wnd, DFM_SHOW_WINDOW, 0, 0);
79 }
80 return wnd;
81 }
82
83 /* -------- add a title to a window --------- */
84 void DfAddTitle(DFWINDOW wnd, char *ttl)
85 {
86 DfInsertTitle(wnd, ttl);
87 DfSendMessage(wnd, DFM_BORDER, 0, 0);
88 }
89
90 /* ----- insert a title into a window ---------- */
91 void DfInsertTitle(DFWINDOW wnd, char *ttl)
92 {
93 wnd->title=DfRealloc(wnd->title,strlen(ttl)+1);
94 strcpy(wnd->title, ttl);
95 }
96
97 static char line[300];
98
99 /* ------ write a line to video window client area ------ */
100 void DfWriteLine(DFWINDOW wnd, char *str, int x, int y, BOOL pad)
101 {
102 char *cp;
103 int len;
104 int dif;
105 char wline[200];
106
107 memset(wline, 0, 200);
108 len = DfLineLength(str);
109 dif = strlen(str) - len;
110 strncpy(wline, str, DfClientWidth(wnd) + dif);
111 if (pad) {
112 cp = wline+strlen(wline);
113 while (len++ < DfClientWidth(wnd)-x)
114 *cp++ = ' ';
115 }
116 DfWPuts(wnd, wline, x, y);
117 }
118
119 DFRECT DfAdjustRectangle(DFWINDOW wnd, DFRECT rc)
120 {
121 /* -------- adjust the rectangle ------- */
122 if (DfTestAttribute(wnd, DF_HASBORDER)) {
123 if (DfRectLeft(rc) == 0)
124 --rc.rt;
125 else if (DfRectLeft(rc) < DfRectRight(rc) &&
126 DfRectLeft(rc) < DfWindowWidth(wnd)+1)
127 --rc.lf;
128 }
129 if (DfTestAttribute(wnd, DF_HASBORDER | DF_HASTITLEBAR)) {
130 if (DfRectTop(rc) == 0)
131 --rc.bt;
132 else if (DfRectTop(rc) < DfRectBottom(rc) &&
133 DfRectTop(rc) < DfWindowHeight(wnd)+1)
134 --rc.tp;
135 }
136 DfRectRight(rc) = max(DfRectLeft(rc),
137 min(DfRectRight(rc),DfWindowWidth(wnd)));
138 DfRectBottom(rc) = max(DfRectTop(rc),
139 min(DfRectBottom(rc),DfWindowHeight(wnd)));
140 return rc;
141 }
142
143 /* -------- display a window's title --------- */
144 void DfDisplayTitle(DFWINDOW wnd, DFRECT *rcc)
145 {
146 if (DfGetTitle(wnd) != NULL)
147 {
148 int tlen = min((int)strlen(DfGetTitle(wnd)), (int)DfWindowWidth(wnd)-2);
149 int tend = DfWindowWidth(wnd)-3-DfBorderAdj(wnd);
150 DFRECT rc;
151
152 if (rcc == NULL)
153 rc = DfRelativeWindowRect(wnd, DfWindowRect(wnd));
154 else
155 rc = *rcc;
156 rc = DfAdjustRectangle(wnd, rc);
157
158 if (DfSendMessage(wnd, DFM_TITLE, (DF_PARAM) rcc, 0))
159 {
160 if (wnd == DfInFocus)
161 {
162 DfForeground = DfCfg.clr[DF_TITLEBAR] [DF_HILITE_COLOR] [DF_FG];
163 DfBackground = DfCfg.clr[DF_TITLEBAR] [DF_HILITE_COLOR] [DF_BG];
164 }
165 else
166 {
167 DfForeground = DfCfg.clr[DF_TITLEBAR] [DF_STD_COLOR] [DF_FG];
168 DfBackground = DfCfg.clr[DF_TITLEBAR] [DF_STD_COLOR] [DF_BG];
169 }
170 memset(line,' ',DfWindowWidth(wnd));
171 #ifdef INCLUDE_MINIMIZE
172 if (wnd->condition != DF_ISMINIMIZED)
173 #endif
174 strncpy (line + ((DfWindowWidth(wnd)-2 - tlen) / 2),
175 wnd->title, tlen);
176 if (DfTestAttribute(wnd, DF_CONTROLBOX))
177 line[2-DfBorderAdj(wnd)] = DF_CONTROLBOXCHAR;
178 if (DfTestAttribute(wnd, DF_MINMAXBOX))
179 {
180 switch (wnd->condition)
181 {
182 case DF_SRESTORED:
183 #ifdef INCLUDE_MAXIMIZE
184 line[tend+1] = DF_MAXPOINTER;
185 #endif
186 #ifdef INCLUDE_MINIMIZE
187 line[tend] = DF_MINPOINTER;
188 #endif
189 break;
190 #ifdef INCLUDE_MINIMIZE
191 case DF_ISMINIMIZED:
192 line[tend+1] = DF_MAXPOINTER;
193 break;
194 #endif
195 #ifdef INCLUDE_MAXIMIZE
196 case DF_ISMAXIMIZED:
197 #ifdef INCLUDE_MINIMIZE
198 line[tend] = DF_MINPOINTER;
199 #endif
200 #ifdef INCLUDE_RESTORE
201 line[tend+1] = DF_RESTOREPOINTER;
202 #endif
203 break;
204 #endif
205 default:
206 break;
207 }
208 }
209 line[DfRectRight(rc)+1] = line[tend+3] = '\0';
210 if (wnd != DfInFocus)
211 DfClipString++;
212 DfWriteLine(wnd, line+DfRectLeft(rc),
213 DfRectLeft(rc)+DfBorderAdj(wnd),
214 0,
215 FALSE);
216 DfClipString = 0;
217 }
218 }
219 }
220
221 /* --- display right border shadow character of a window --- */
222 static void shadow_char(DFWINDOW wnd, int y)
223 {
224 int fg = DfForeground;
225 int bg = DfBackground;
226 int x = DfWindowWidth(wnd);
227 char c = DfVideoChar(DfGetLeft(wnd)+x, DfGetTop(wnd)+y);
228
229 if (DfTestAttribute(wnd, DF_SHADOW) == 0)
230 return;
231 DfForeground = DARKGRAY;
232 DfBackground = BLACK;
233 DfWPutch(wnd, c, x, y);
234 DfForeground = fg;
235 DfBackground = bg;
236 }
237
238 /* --- display the bottom border shadow line for a window -- */
239 static void shadowline(DFWINDOW wnd, DFRECT rc)
240 {
241 int i;
242 int y = DfGetBottom(wnd)+1;
243 int fg = DfForeground;
244 int bg = DfBackground;
245
246 if ((DfTestAttribute(wnd, DF_SHADOW)) == 0)
247 return;
248 for (i = 0; i < DfWindowWidth(wnd)+1; i++)
249 line[i] = DfVideoChar(DfGetLeft(wnd)+i, y);
250 line[i] = '\0';
251 DfForeground = DARKGRAY;
252 DfBackground = BLACK;
253 line[DfRectRight(rc)+1] = '\0';
254 if (DfRectLeft(rc) == 0)
255 rc.lf++;
256 DfClipString++;
257 DfWPuts(wnd, line+DfRectLeft(rc), DfRectLeft(rc),
258 DfWindowHeight(wnd));
259 --DfClipString;
260 DfForeground = fg;
261 DfBackground = bg;
262 }
263
264 static DFRECT ParamRect(DFWINDOW wnd, DFRECT *rcc)
265 {
266 DFRECT rc;
267 if (rcc == NULL) {
268 rc = DfRelativeWindowRect(wnd, DfWindowRect(wnd));
269 if (DfTestAttribute(wnd, DF_SHADOW)) {
270 rc.rt++;
271 rc.bt++;
272 }
273 }
274 else
275 rc = *rcc;
276 return rc;
277 }
278
279 void DfPaintShadow(DFWINDOW wnd)
280 {
281 int y;
282 DFRECT rc = ParamRect(wnd, NULL);
283 for (y = 1; y < DfWindowHeight(wnd); y++)
284 shadow_char(wnd, y);
285 shadowline(wnd, rc);
286 }
287
288 /* ------- display a window's border ----- */
289 void DfRepaintBorder(DFWINDOW wnd, DFRECT *rcc)
290 {
291 int y;
292 char lin, side, ne, nw, se, sw;
293 DFRECT rc, clrc;
294
295 if (!DfTestAttribute(wnd, DF_HASBORDER))
296 return;
297 rc = ParamRect(wnd, rcc);
298 clrc = DfAdjustRectangle(wnd, rc);
299
300 if (wnd == DfInFocus) {
301 lin = DF_FOCUS_LINE;
302 side = DF_FOCUS_SIDE;
303 ne = DF_FOCUS_NE;
304 nw = DF_FOCUS_NW;
305 se = DF_FOCUS_SE;
306 sw = DF_FOCUS_SW;
307 }
308 else {
309 lin = DF_LINE;
310 side = DF_SIDE;
311 ne = DF_NE;
312 nw = DF_NW;
313 se = DF_SE;
314 sw = DF_SW;
315 }
316 line[DfWindowWidth(wnd)] = '\0';
317 /* ---------- window title ------------ */
318 if (DfTestAttribute(wnd, DF_HASTITLEBAR))
319 if (DfRectTop(rc) == 0)
320 if (DfRectLeft(rc) < DfWindowWidth(wnd)-DfBorderAdj(wnd))
321 DfDisplayTitle(wnd, &rc);
322 DfForeground = DfFrameForeground(wnd);
323 DfBackground = DfFrameBackground(wnd);
324 /* -------- top frame corners --------- */
325 if (DfRectTop(rc) == 0) {
326 if (DfRectLeft(rc) == 0)
327 DfWPutch(wnd, nw, 0, 0);
328 if (DfRectLeft(rc) < DfWindowWidth(wnd)) {
329 if (DfRectRight(rc) >= DfWindowWidth(wnd)-1)
330 DfWPutch(wnd, ne, DfWindowWidth(wnd)-1, 0);
331 TopLine(wnd, lin, clrc);
332 }
333 }
334
335 /* ----------- window body ------------ */
336 for (y = DfRectTop(rc); y <= DfRectBottom(rc); y++) {
337 char ch;
338 if (y == 0 || y >= DfWindowHeight(wnd)-1)
339 continue;
340 if (DfRectLeft(rc) == 0)
341 DfWPutch(wnd, side, 0, y);
342 if (DfRectLeft(rc) < DfWindowWidth(wnd) &&
343 DfRectRight(rc) >= DfWindowWidth(wnd)-1) {
344 if (DfTestAttribute(wnd, DF_VSCROLLBAR))
345 ch = ( y == 1 ? DF_UPSCROLLBOX :
346 y == DfWindowHeight(wnd)-2 ?
347 DF_DOWNSCROLLBOX :
348 y-1 == wnd->VScrollBox ?
349 DF_SCROLLBOXCHAR :
350 DF_SCROLLBARCHAR );
351 else
352 ch = side;
353 DfWPutch(wnd, ch, DfWindowWidth(wnd)-1, y);
354 }
355 if (DfRectRight(rc) == DfWindowWidth(wnd))
356 shadow_char(wnd, y);
357 }
358
359 if (DfRectTop(rc) <= DfWindowHeight(wnd)-1 &&
360 DfRectBottom(rc) >= DfWindowHeight(wnd)-1) {
361 /* -------- bottom frame corners ---------- */
362 if (DfRectLeft(rc) == 0)
363 DfWPutch(wnd, sw, 0, DfWindowHeight(wnd)-1);
364 if (DfRectLeft(rc) < DfWindowWidth(wnd) &&
365 DfRectRight(rc) >= DfWindowWidth(wnd)-1)
366 DfWPutch(wnd, se, DfWindowWidth(wnd)-1,
367 DfWindowHeight(wnd)-1);
368
369
370 if (wnd->StatusBar == NULL) {
371 /* ----------- bottom line ------------- */
372 memset(line,lin,DfWindowWidth(wnd)-1);
373 if (DfTestAttribute(wnd, DF_HSCROLLBAR)) {
374 line[0] = DF_LEFTSCROLLBOX;
375 line[DfWindowWidth(wnd)-3] = DF_RIGHTSCROLLBOX;
376 memset(line+1, DF_SCROLLBARCHAR, DfWindowWidth(wnd)-4);
377 line[wnd->HScrollBox] = DF_SCROLLBOXCHAR;
378 }
379 line[DfWindowWidth(wnd)-2] = line[DfRectRight(rc)] = '\0';
380 if (DfRectLeft(rc) != DfRectRight(rc) ||
381 (DfRectLeft(rc) && DfRectLeft(rc) < DfWindowWidth(wnd)-1))
382 {
383 if (wnd != DfInFocus)
384 DfClipString++;
385 DfWriteLine(wnd,
386 line+(DfRectLeft(clrc)),
387 DfRectLeft(clrc)+1,
388 DfWindowHeight(wnd)-1,
389 FALSE);
390 DfClipString = 0;
391 }
392 }
393 if (DfRectRight(rc) == DfWindowWidth(wnd))
394 shadow_char(wnd, DfWindowHeight(wnd)-1);
395 }
396 if (DfRectBottom(rc) == DfWindowHeight(wnd))
397 /* ---------- bottom shadow ------------- */
398 shadowline(wnd, rc);
399 }
400
401 static void TopLine(DFWINDOW wnd, int lin, DFRECT rc)
402 {
403 if (DfTestAttribute(wnd, DF_HASMENUBAR))
404 return;
405 if (DfTestAttribute(wnd, DF_HASTITLEBAR) && DfGetTitle(wnd))
406 return;
407 if (DfRectLeft(rc) == 0) {
408 DfRectLeft(rc) += DfBorderAdj(wnd);
409 DfRectRight(rc) += DfBorderAdj(wnd);
410 }
411 if (DfRectRight(rc) < DfWindowWidth(wnd)-1)
412 DfRectRight(rc)++;
413
414 if (DfRectLeft(rc) < DfRectRight(rc)) {
415 /* ----------- top line ------------- */
416 memset(line,lin,DfWindowWidth(wnd)-1);
417 if (DfTestAttribute(wnd, DF_CONTROLBOX)) {
418 strncpy(line+1, " ", 3);
419 *(line+2) = DF_CONTROLBOXCHAR;
420 }
421 line[DfRectRight(rc)] = '\0';
422 DfWriteLine(wnd, line+DfRectLeft(rc),
423 DfRectLeft(rc), 0, FALSE);
424 }
425 }
426
427 /* ------ clear the data space of a window -------- */
428 void DfClearWindow(DFWINDOW wnd, DFRECT *rcc, int clrchar)
429 {
430 if (DfIsVisible(wnd)) {
431 int y;
432 DFRECT rc;
433
434 if (rcc == NULL)
435 rc = DfRelativeWindowRect(wnd, DfWindowRect(wnd));
436 else
437 rc = *rcc;
438
439 if (DfRectLeft(rc) == 0)
440 DfRectLeft(rc) = DfBorderAdj(wnd);
441 if (DfRectRight(rc) > DfWindowWidth(wnd)-1)
442 DfRectRight(rc) = DfWindowWidth(wnd)-1;
443 DfSetStandardColor(wnd);
444 memset(line, clrchar, sizeof line);
445 line[DfRectRight(rc)+1] = '\0';
446 for (y = DfRectTop(rc); y <= DfRectBottom(rc); y++)
447 {
448 if (y < DfTopBorderAdj(wnd) ||
449 y > DfClientHeight(wnd)+
450 (DfTestAttribute(wnd, DF_HASMENUBAR) ? 1 : 0))
451 continue;
452 DfWriteLine(wnd,
453 line+(DfRectLeft(rc)),
454 DfRectLeft(rc),
455 y,
456 FALSE);
457 }
458 }
459 }
460
461 /* ------ compute the logical line length of a window ------ */
462 int DfLineLength(char *ln)
463 {
464 int len = strlen(ln);
465 char *cp = ln;
466 while ((cp = strchr(cp, DF_CHANGECOLOR)) != NULL)
467 {
468 cp++;
469 len -= 3;
470 }
471 cp = ln;
472 while ((cp = strchr(cp, DF_RESETCOLOR)) != NULL)
473 {
474 cp++;
475 --len;
476 }
477 return len;
478 }
479
480 void DfInitWindowColors(DFWINDOW wnd)
481 {
482 int fbg,col;
483 int cls = DfGetClass(wnd);
484 /* window classes without assigned colors inherit parent's colors */
485 if (DfCfg.clr[cls][0][0] == 0xff && DfGetParent(wnd) != NULL)
486 cls = DfGetClass(DfGetParent(wnd));
487 /* ---------- set the colors ---------- */
488 for (fbg = 0; fbg < 2; fbg++)
489 for (col = 0; col < 4; col++)
490 wnd->WindowColors[col][fbg] = DfCfg.clr[cls][col][fbg];
491 }
492
493 void DfPutWindowChar(DFWINDOW wnd, char c, int x, int y)
494 {
495 if (x < DfClientWidth(wnd) && y < DfClientHeight(wnd))
496 DfWPutch(wnd, c, x+DfBorderAdj(wnd), y+DfTopBorderAdj(wnd));
497 }
498
499 void DfPutWindowLine(DFWINDOW wnd, void *s, int x, int y)
500 {
501 int saved = FALSE;
502 int sv = 0;
503
504 if (x < DfClientWidth(wnd) && y < DfClientHeight(wnd))
505 {
506 char *en = (char *)s+DfClientWidth(wnd)-x;
507 if ((int)(strlen(s)+x) > (int)DfClientWidth(wnd))
508 {
509 sv = *en;
510 *en = '\0';
511 saved = TRUE;
512 }
513 DfClipString++;
514 DfWPuts(wnd, s, x+DfBorderAdj(wnd), y+DfTopBorderAdj(wnd));
515 --DfClipString;
516 if (saved)
517 *en = sv;
518 }
519 }
520
521 /* EOF */