1 /* ---------- window.c ------------- */
5 DFWINDOW DfInFocus
= NULL
;
7 int DfForeground
, DfBackground
; /* current video colors */
9 static void TopLine(DFWINDOW
, int, DFRECT
);
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 */
22 DFWINDOW wnd
= DfCalloc(1, sizeof(struct DfWindow
));
25 /* ----- height, width = -1: fill the screen ------- */
27 height
= DfScreenHeight
;
29 width
= DfScreenWidth
;
30 /* ----- coordinates -1, -1 = center the window ---- */
32 wnd
->rc
.lf
= (DfScreenWidth
-width
)/2;
36 wnd
->rc
.tp
= (DfScreenHeight
-height
)/2;
41 DfAddAttribute(wnd
, DF_HASTITLEBAR
);
43 wnd
->wndproc
= DfClassDefs
[class].wndproc
;
45 wnd
->wndproc
= wndproc
;
46 /* ---- derive attributes of base classes ---- */
49 DfAddAttribute(wnd
, DfClassDefs
[base
].attrib
);
50 base
= DfClassDefs
[base
].base
;
54 if (!DfTestAttribute(wnd
, DF_NOCLIP
))
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
));
62 parent
= DfApplicationWindow
;
65 wnd
->extension
= extension
;
66 wnd
->rc
.rt
= DfGetLeft(wnd
)+width
-1;
67 wnd
->rc
.bt
= DfGetTop(wnd
)+height
-1;
71 DfInsertTitle(wnd
, ttl
);
73 wnd
->oldcondition
= wnd
->condition
= DF_SRESTORED
;
74 wnd
->RestoredRC
= wnd
->rc
;
75 DfInitWindowColors(wnd
);
76 DfSendMessage(wnd
, DFM_CREATE_WINDOW
, 0, 0);
78 DfSendMessage(wnd
, DFM_SHOW_WINDOW
, 0, 0);
83 /* -------- add a title to a window --------- */
84 void DfAddTitle(DFWINDOW wnd
, char *ttl
)
86 DfInsertTitle(wnd
, ttl
);
87 DfSendMessage(wnd
, DFM_BORDER
, 0, 0);
90 /* ----- insert a title into a window ---------- */
91 void DfInsertTitle(DFWINDOW wnd
, char *ttl
)
93 wnd
->title
=DfRealloc(wnd
->title
,strlen(ttl
)+1);
94 strcpy(wnd
->title
, ttl
);
97 static char line
[300];
99 /* ------ write a line to video window client area ------ */
100 void DfWriteLine(DFWINDOW wnd
, char *str
, int x
, int y
, BOOL pad
)
107 memset(wline
, 0, 200);
108 len
= DfLineLength(str
);
109 dif
= strlen(str
) - len
;
110 strncpy(wline
, str
, DfClientWidth(wnd
) + dif
);
112 cp
= wline
+strlen(wline
);
113 while (len
++ < DfClientWidth(wnd
)-x
)
116 DfWPuts(wnd
, wline
, x
, y
);
119 DFRECT
DfAdjustRectangle(DFWINDOW wnd
, DFRECT rc
)
121 /* -------- adjust the rectangle ------- */
122 if (DfTestAttribute(wnd
, DF_HASBORDER
)) {
123 if (DfRectLeft(rc
) == 0)
125 else if (DfRectLeft(rc
) < DfRectRight(rc
) &&
126 DfRectLeft(rc
) < DfWindowWidth(wnd
)+1)
129 if (DfTestAttribute(wnd
, DF_HASBORDER
| DF_HASTITLEBAR
)) {
130 if (DfRectTop(rc
) == 0)
132 else if (DfRectTop(rc
) < DfRectBottom(rc
) &&
133 DfRectTop(rc
) < DfWindowHeight(wnd
)+1)
136 DfRectRight(rc
) = max(DfRectLeft(rc
),
137 min(DfRectRight(rc
),DfWindowWidth(wnd
)));
138 DfRectBottom(rc
) = max(DfRectTop(rc
),
139 min(DfRectBottom(rc
),DfWindowHeight(wnd
)));
143 /* -------- display a window's title --------- */
144 void DfDisplayTitle(DFWINDOW wnd
, DFRECT
*rcc
)
146 if (DfGetTitle(wnd
) != NULL
)
148 int tlen
= min((int)strlen(DfGetTitle(wnd
)), (int)DfWindowWidth(wnd
)-2);
149 int tend
= DfWindowWidth(wnd
)-3-DfBorderAdj(wnd
);
153 rc
= DfRelativeWindowRect(wnd
, DfWindowRect(wnd
));
156 rc
= DfAdjustRectangle(wnd
, rc
);
158 if (DfSendMessage(wnd
, DFM_TITLE
, (DF_PARAM
) rcc
, 0))
160 if (wnd
== DfInFocus
)
162 DfForeground
= DfCfg
.clr
[DF_TITLEBAR
] [DF_HILITE_COLOR
] [DF_FG
];
163 DfBackground
= DfCfg
.clr
[DF_TITLEBAR
] [DF_HILITE_COLOR
] [DF_BG
];
167 DfForeground
= DfCfg
.clr
[DF_TITLEBAR
] [DF_STD_COLOR
] [DF_FG
];
168 DfBackground
= DfCfg
.clr
[DF_TITLEBAR
] [DF_STD_COLOR
] [DF_BG
];
170 memset(line
,' ',DfWindowWidth(wnd
));
171 #ifdef INCLUDE_MINIMIZE
172 if (wnd
->condition
!= DF_ISMINIMIZED
)
174 strncpy (line
+ ((DfWindowWidth(wnd
)-2 - tlen
) / 2),
176 if (DfTestAttribute(wnd
, DF_CONTROLBOX
))
177 line
[2-DfBorderAdj(wnd
)] = DF_CONTROLBOXCHAR
;
178 if (DfTestAttribute(wnd
, DF_MINMAXBOX
))
180 switch (wnd
->condition
)
183 #ifdef INCLUDE_MAXIMIZE
184 line
[tend
+1] = DF_MAXPOINTER
;
186 #ifdef INCLUDE_MINIMIZE
187 line
[tend
] = DF_MINPOINTER
;
190 #ifdef INCLUDE_MINIMIZE
192 line
[tend
+1] = DF_MAXPOINTER
;
195 #ifdef INCLUDE_MAXIMIZE
197 #ifdef INCLUDE_MINIMIZE
198 line
[tend
] = DF_MINPOINTER
;
200 #ifdef INCLUDE_RESTORE
201 line
[tend
+1] = DF_RESTOREPOINTER
;
209 line
[DfRectRight(rc
)+1] = line
[tend
+3] = '\0';
210 if (wnd
!= DfInFocus
)
212 DfWriteLine(wnd
, line
+DfRectLeft(rc
),
213 DfRectLeft(rc
)+DfBorderAdj(wnd
),
221 /* --- display right border shadow character of a window --- */
222 static void shadow_char(DFWINDOW wnd
, int y
)
224 int fg
= DfForeground
;
225 int bg
= DfBackground
;
226 int x
= DfWindowWidth(wnd
);
227 char c
= DfVideoChar(DfGetLeft(wnd
)+x
, DfGetTop(wnd
)+y
);
229 if (DfTestAttribute(wnd
, DF_SHADOW
) == 0)
231 DfForeground
= DARKGRAY
;
232 DfBackground
= BLACK
;
233 DfWPutch(wnd
, c
, x
, y
);
238 /* --- display the bottom border shadow line for a window -- */
239 static void shadowline(DFWINDOW wnd
, DFRECT rc
)
242 int y
= DfGetBottom(wnd
)+1;
243 int fg
= DfForeground
;
244 int bg
= DfBackground
;
246 if ((DfTestAttribute(wnd
, DF_SHADOW
)) == 0)
248 for (i
= 0; i
< DfWindowWidth(wnd
)+1; i
++)
249 line
[i
] = DfVideoChar(DfGetLeft(wnd
)+i
, y
);
251 DfForeground
= DARKGRAY
;
252 DfBackground
= BLACK
;
253 line
[DfRectRight(rc
)+1] = '\0';
254 if (DfRectLeft(rc
) == 0)
257 DfWPuts(wnd
, line
+DfRectLeft(rc
), DfRectLeft(rc
),
258 DfWindowHeight(wnd
));
264 static DFRECT
ParamRect(DFWINDOW wnd
, DFRECT
*rcc
)
268 rc
= DfRelativeWindowRect(wnd
, DfWindowRect(wnd
));
269 if (DfTestAttribute(wnd
, DF_SHADOW
)) {
279 void DfPaintShadow(DFWINDOW wnd
)
282 DFRECT rc
= ParamRect(wnd
, NULL
);
283 for (y
= 1; y
< DfWindowHeight(wnd
); y
++)
288 /* ------- display a window's border ----- */
289 void DfRepaintBorder(DFWINDOW wnd
, DFRECT
*rcc
)
292 char lin
, side
, ne
, nw
, se
, sw
;
295 if (!DfTestAttribute(wnd
, DF_HASBORDER
))
297 rc
= ParamRect(wnd
, rcc
);
298 clrc
= DfAdjustRectangle(wnd
, rc
);
300 if (wnd
== DfInFocus
) {
302 side
= DF_FOCUS_SIDE
;
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
);
335 /* ----------- window body ------------ */
336 for (y
= DfRectTop(rc
); y
<= DfRectBottom(rc
); y
++) {
338 if (y
== 0 || y
>= DfWindowHeight(wnd
)-1)
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 ?
348 y
-1 == wnd
->VScrollBox
?
353 DfWPutch(wnd
, ch
, DfWindowWidth(wnd
)-1, y
);
355 if (DfRectRight(rc
) == DfWindowWidth(wnd
))
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);
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
;
379 line
[DfWindowWidth(wnd
)-2] = line
[DfRectRight(rc
)] = '\0';
380 if (DfRectLeft(rc
) != DfRectRight(rc
) ||
381 (DfRectLeft(rc
) && DfRectLeft(rc
) < DfWindowWidth(wnd
)-1))
383 if (wnd
!= DfInFocus
)
386 line
+(DfRectLeft(clrc
)),
388 DfWindowHeight(wnd
)-1,
393 if (DfRectRight(rc
) == DfWindowWidth(wnd
))
394 shadow_char(wnd
, DfWindowHeight(wnd
)-1);
396 if (DfRectBottom(rc
) == DfWindowHeight(wnd
))
397 /* ---------- bottom shadow ------------- */
401 static void TopLine(DFWINDOW wnd
, int lin
, DFRECT rc
)
403 if (DfTestAttribute(wnd
, DF_HASMENUBAR
))
405 if (DfTestAttribute(wnd
, DF_HASTITLEBAR
) && DfGetTitle(wnd
))
407 if (DfRectLeft(rc
) == 0) {
408 DfRectLeft(rc
) += DfBorderAdj(wnd
);
409 DfRectRight(rc
) += DfBorderAdj(wnd
);
411 if (DfRectRight(rc
) < DfWindowWidth(wnd
)-1)
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
;
421 line
[DfRectRight(rc
)] = '\0';
422 DfWriteLine(wnd
, line
+DfRectLeft(rc
),
423 DfRectLeft(rc
), 0, FALSE
);
427 /* ------ clear the data space of a window -------- */
428 void DfClearWindow(DFWINDOW wnd
, DFRECT
*rcc
, int clrchar
)
430 if (DfIsVisible(wnd
)) {
435 rc
= DfRelativeWindowRect(wnd
, DfWindowRect(wnd
));
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
++)
448 if (y
< DfTopBorderAdj(wnd
) ||
449 y
> DfClientHeight(wnd
)+
450 (DfTestAttribute(wnd
, DF_HASMENUBAR
) ? 1 : 0))
453 line
+(DfRectLeft(rc
)),
461 /* ------ compute the logical line length of a window ------ */
462 int DfLineLength(char *ln
)
464 int len
= strlen(ln
);
466 while ((cp
= strchr(cp
, DF_CHANGECOLOR
)) != NULL
)
472 while ((cp
= strchr(cp
, DF_RESETCOLOR
)) != NULL
)
480 void DfInitWindowColors(DFWINDOW wnd
)
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
];
493 void DfPutWindowChar(DFWINDOW wnd
, char c
, int x
, int y
)
495 if (x
< DfClientWidth(wnd
) && y
< DfClientHeight(wnd
))
496 DfWPutch(wnd
, c
, x
+DfBorderAdj(wnd
), y
+DfTopBorderAdj(wnd
));
499 void DfPutWindowLine(DFWINDOW wnd
, void *s
, int x
, int y
)
504 if (x
< DfClientWidth(wnd
) && y
< DfClientHeight(wnd
))
506 char *en
= (char *)s
+DfClientWidth(wnd
)-x
;
507 if ((int)(strlen(s
)+x
) > (int)DfClientWidth(wnd
))
514 DfWPuts(wnd
, s
, x
+DfBorderAdj(wnd
), y
+DfTopBorderAdj(wnd
));