1 /* ---------- window.c ------------- */
5 DFWINDOW inFocus
= NULL
;
7 int foreground
, background
; /* current video colors */
9 static void TopLine(DFWINDOW
, int, DFRECT
);
11 /* --------- create a window ------------ */
12 DFWINDOW
DfCreateWindow(
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 window
*,enum messages
,PARAM
,PARAM
),
20 int attrib
) /* window attribute */
22 DFWINDOW wnd
= DFcalloc(1, sizeof(struct window
));
25 /* ----- height, width = -1: fill the screen ------- */
27 height
= sScreenHeight
;
30 /* ----- coordinates -1, -1 = center the window ---- */
32 wnd
->rc
.lf
= (sScreenWidth
-width
)/2;
36 wnd
->rc
.tp
= (sScreenHeight
-height
)/2;
41 AddAttribute(wnd
, HASTITLEBAR
);
43 wnd
->wndproc
= classdefs
[class].wndproc
;
45 wnd
->wndproc
= wndproc
;
46 /* ---- derive attributes of base classes ---- */
49 AddAttribute(wnd
, classdefs
[base
].attrib
);
50 base
= classdefs
[base
].base
;
54 if (!TestAttribute(wnd
, NOCLIP
))
56 /* -- keep upper left within borders of parent - */
57 wnd
->rc
.lf
= max(wnd
->rc
.lf
,GetClientLeft(parent
));
58 wnd
->rc
.tp
= max(wnd
->rc
.tp
,GetClientTop(parent
));
62 parent
= ApplicationWindow
;
65 wnd
->extension
= extension
;
66 wnd
->rc
.rt
= GetLeft(wnd
)+width
-1;
67 wnd
->rc
.bt
= GetTop(wnd
)+height
-1;
71 InsertTitle(wnd
, ttl
);
73 wnd
->oldcondition
= wnd
->condition
= ISRESTORED
;
74 wnd
->RestoredRC
= wnd
->rc
;
75 InitWindowColors(wnd
);
76 DfSendMessage(wnd
, CREATE_WINDOW
, 0, 0);
78 DfSendMessage(wnd
, SHOW_WINDOW
, 0, 0);
83 /* -------- add a title to a window --------- */
84 void AddTitle(DFWINDOW wnd
, char *ttl
)
86 InsertTitle(wnd
, ttl
);
87 DfSendMessage(wnd
, BORDER
, 0, 0);
90 /* ----- insert a title into a window ---------- */
91 void InsertTitle(DFWINDOW wnd
, char *ttl
)
93 wnd
->title
=DFrealloc(wnd
->title
,strlen(ttl
)+1);
94 strcpy(wnd
->title
, ttl
);
97 static unsigned char line
[300];
99 /* ------ write a line to video window client area ------ */
100 void writeline(DFWINDOW wnd
, char *str
, int x
, int y
, BOOL pad
)
107 memset(wline
, 0, 200);
108 len
= LineLength(str
);
109 dif
= strlen(str
) - len
;
110 strncpy(wline
, str
, ClientWidth(wnd
) + dif
);
112 cp
= wline
+strlen(wline
);
113 while (len
++ < ClientWidth(wnd
)-x
)
116 wputs(wnd
, wline
, x
, y
);
119 DFRECT
AdjustRectangle(DFWINDOW wnd
, DFRECT rc
)
121 /* -------- adjust the rectangle ------- */
122 if (TestAttribute(wnd
, HASBORDER
)) {
123 if (RectLeft(rc
) == 0)
125 else if (RectLeft(rc
) < RectRight(rc
) &&
126 RectLeft(rc
) < WindowWidth(wnd
)+1)
129 if (TestAttribute(wnd
, HASBORDER
| HASTITLEBAR
)) {
130 if (RectTop(rc
) == 0)
132 else if (RectTop(rc
) < RectBottom(rc
) &&
133 RectTop(rc
) < WindowHeight(wnd
)+1)
136 RectRight(rc
) = max(RectLeft(rc
),
137 min(RectRight(rc
),WindowWidth(wnd
)));
138 RectBottom(rc
) = max(RectTop(rc
),
139 min(RectBottom(rc
),WindowHeight(wnd
)));
143 /* -------- display a window's title --------- */
144 void DisplayTitle(DFWINDOW wnd
, DFRECT
*rcc
)
146 if (GetTitle(wnd
) != NULL
)
148 int tlen
= min((int)strlen(GetTitle(wnd
)), (int)WindowWidth(wnd
)-2);
149 int tend
= WindowWidth(wnd
)-3-BorderAdj(wnd
);
153 rc
= RelativeWindowRect(wnd
, WindowRect(wnd
));
156 rc
= AdjustRectangle(wnd
, rc
);
158 if (DfSendMessage(wnd
, TITLE
, (PARAM
) rcc
, 0))
162 foreground
= cfg
.clr
[TITLEBAR
] [HILITE_COLOR
] [FG
];
163 background
= cfg
.clr
[TITLEBAR
] [HILITE_COLOR
] [BG
];
167 foreground
= cfg
.clr
[TITLEBAR
] [STD_COLOR
] [FG
];
168 background
= cfg
.clr
[TITLEBAR
] [STD_COLOR
] [BG
];
170 memset(line
,' ',WindowWidth(wnd
));
171 #ifdef INCLUDE_MINIMIZE
172 if (wnd
->condition
!= ISMINIMIZED
)
174 strncpy (line
+ ((WindowWidth(wnd
)-2 - tlen
) / 2),
176 if (TestAttribute(wnd
, CONTROLBOX
))
177 line
[2-BorderAdj(wnd
)] = CONTROLBOXCHAR
;
178 if (TestAttribute(wnd
, MINMAXBOX
))
180 switch (wnd
->condition
)
183 #ifdef INCLUDE_MAXIMIZE
184 line
[tend
+1] = MAXPOINTER
;
186 #ifdef INCLUDE_MINIMIZE
187 line
[tend
] = MINPOINTER
;
190 #ifdef INCLUDE_MINIMIZE
192 line
[tend
+1] = MAXPOINTER
;
195 #ifdef INCLUDE_MAXIMIZE
197 #ifdef INCLUDE_MINIMIZE
198 line
[tend
] = MINPOINTER
;
200 #ifdef INCLUDE_RESTORE
201 line
[tend
+1] = RESTOREPOINTER
;
209 line
[RectRight(rc
)+1] = line
[tend
+3] = '\0';
212 writeline(wnd
, line
+RectLeft(rc
),
213 RectLeft(rc
)+BorderAdj(wnd
),
221 /* --- display right border shadow character of a window --- */
222 static void shadow_char(DFWINDOW wnd
, int y
)
226 int x
= WindowWidth(wnd
);
227 char c
= videochar(GetLeft(wnd
)+x
, GetTop(wnd
)+y
);
229 if (TestAttribute(wnd
, SHADOW
) == 0)
231 foreground
= DARKGRAY
;
233 wputch(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
= GetBottom(wnd
)+1;
246 if ((TestAttribute(wnd
, SHADOW
)) == 0)
248 for (i
= 0; i
< WindowWidth(wnd
)+1; i
++)
249 line
[i
] = videochar(GetLeft(wnd
)+i
, y
);
251 foreground
= DARKGRAY
;
253 line
[RectRight(rc
)+1] = '\0';
254 if (RectLeft(rc
) == 0)
257 wputs(wnd
, line
+RectLeft(rc
), RectLeft(rc
),
264 static DFRECT
ParamRect(DFWINDOW wnd
, DFRECT
*rcc
)
268 rc
= RelativeWindowRect(wnd
, WindowRect(wnd
));
269 if (TestAttribute(wnd
, SHADOW
)) {
279 void PaintShadow(DFWINDOW wnd
)
282 DFRECT rc
= ParamRect(wnd
, NULL
);
283 for (y
= 1; y
< WindowHeight(wnd
); y
++)
288 /* ------- display a window's border ----- */
289 void RepaintBorder(DFWINDOW wnd
, DFRECT
*rcc
)
292 char lin
, side
, ne
, nw
, se
, sw
;
295 if (!TestAttribute(wnd
, HASBORDER
))
297 rc
= ParamRect(wnd
, rcc
);
298 clrc
= AdjustRectangle(wnd
, rc
);
300 if (wnd
== inFocus
) {
316 line
[WindowWidth(wnd
)] = '\0';
317 /* ---------- window title ------------ */
318 if (TestAttribute(wnd
, HASTITLEBAR
))
319 if (RectTop(rc
) == 0)
320 if (RectLeft(rc
) < WindowWidth(wnd
)-BorderAdj(wnd
))
321 DisplayTitle(wnd
, &rc
);
322 foreground
= FrameForeground(wnd
);
323 background
= FrameBackground(wnd
);
324 /* -------- top frame corners --------- */
325 if (RectTop(rc
) == 0) {
326 if (RectLeft(rc
) == 0)
327 wputch(wnd
, nw
, 0, 0);
328 if (RectLeft(rc
) < WindowWidth(wnd
)) {
329 if (RectRight(rc
) >= WindowWidth(wnd
)-1)
330 wputch(wnd
, ne
, WindowWidth(wnd
)-1, 0);
331 TopLine(wnd
, lin
, clrc
);
335 /* ----------- window body ------------ */
336 for (y
= RectTop(rc
); y
<= RectBottom(rc
); y
++) {
338 if (y
== 0 || y
>= WindowHeight(wnd
)-1)
340 if (RectLeft(rc
) == 0)
341 wputch(wnd
, side
, 0, y
);
342 if (RectLeft(rc
) < WindowWidth(wnd
) &&
343 RectRight(rc
) >= WindowWidth(wnd
)-1) {
344 if (TestAttribute(wnd
, VSCROLLBAR
))
345 ch
= ( y
== 1 ? UPSCROLLBOX
:
346 y
== WindowHeight(wnd
)-2 ?
348 y
-1 == wnd
->VScrollBox
?
353 wputch(wnd
, ch
, WindowWidth(wnd
)-1, y
);
355 if (RectRight(rc
) == WindowWidth(wnd
))
359 if (RectTop(rc
) <= WindowHeight(wnd
)-1 &&
360 RectBottom(rc
) >= WindowHeight(wnd
)-1) {
361 /* -------- bottom frame corners ---------- */
362 if (RectLeft(rc
) == 0)
363 wputch(wnd
, sw
, 0, WindowHeight(wnd
)-1);
364 if (RectLeft(rc
) < WindowWidth(wnd
) &&
365 RectRight(rc
) >= WindowWidth(wnd
)-1)
366 wputch(wnd
, se
, WindowWidth(wnd
)-1,
367 WindowHeight(wnd
)-1);
370 if (wnd
->StatusBar
== NULL
) {
371 /* ----------- bottom line ------------- */
372 memset(line
,lin
,WindowWidth(wnd
)-1);
373 if (TestAttribute(wnd
, HSCROLLBAR
)) {
374 line
[0] = LEFTSCROLLBOX
;
375 line
[WindowWidth(wnd
)-3] = RIGHTSCROLLBOX
;
376 memset(line
+1, SCROLLBARCHAR
, WindowWidth(wnd
)-4);
377 line
[wnd
->HScrollBox
] = SCROLLBOXCHAR
;
379 line
[WindowWidth(wnd
)-2] = line
[RectRight(rc
)] = '\0';
380 if (RectLeft(rc
) != RectRight(rc
) ||
381 (RectLeft(rc
) && RectLeft(rc
) < WindowWidth(wnd
)-1))
386 line
+(RectLeft(clrc
)),
393 if (RectRight(rc
) == WindowWidth(wnd
))
394 shadow_char(wnd
, WindowHeight(wnd
)-1);
396 if (RectBottom(rc
) == WindowHeight(wnd
))
397 /* ---------- bottom shadow ------------- */
401 static void TopLine(DFWINDOW wnd
, int lin
, DFRECT rc
)
403 if (TestAttribute(wnd
, HASMENUBAR
))
405 if (TestAttribute(wnd
, HASTITLEBAR
) && GetTitle(wnd
))
407 if (RectLeft(rc
) == 0) {
408 RectLeft(rc
) += BorderAdj(wnd
);
409 RectRight(rc
) += BorderAdj(wnd
);
411 if (RectRight(rc
) < WindowWidth(wnd
)-1)
414 if (RectLeft(rc
) < RectRight(rc
)) {
415 /* ----------- top line ------------- */
416 memset(line
,lin
,WindowWidth(wnd
)-1);
417 if (TestAttribute(wnd
, CONTROLBOX
)) {
418 strncpy(line
+1, " ", 3);
419 *(line
+2) = CONTROLBOXCHAR
;
421 line
[RectRight(rc
)] = '\0';
422 writeline(wnd
, line
+RectLeft(rc
),
423 RectLeft(rc
), 0, FALSE
);
427 /* ------ clear the data space of a window -------- */
428 void ClearWindow(DFWINDOW wnd
, DFRECT
*rcc
, int clrchar
)
430 if (isVisible(wnd
)) {
435 rc
= RelativeWindowRect(wnd
, WindowRect(wnd
));
439 if (RectLeft(rc
) == 0)
440 RectLeft(rc
) = BorderAdj(wnd
);
441 if (RectRight(rc
) > WindowWidth(wnd
)-1)
442 RectRight(rc
) = WindowWidth(wnd
)-1;
443 SetStandardColor(wnd
);
444 memset(line
, clrchar
, sizeof line
);
445 line
[RectRight(rc
)+1] = '\0';
446 for (y
= RectTop(rc
); y
<= RectBottom(rc
); y
++)
448 if (y
< TopBorderAdj(wnd
) ||
449 y
> ClientHeight(wnd
)+
450 (TestAttribute(wnd
, HASMENUBAR
) ? 1 : 0))
461 /* ------ compute the logical line length of a window ------ */
462 int LineLength(char *ln
)
464 int len
= strlen(ln
);
466 while ((cp
= strchr(cp
, CHANGECOLOR
)) != NULL
)
472 while ((cp
= strchr(cp
, RESETCOLOR
)) != NULL
)
480 void InitWindowColors(DFWINDOW wnd
)
483 int cls
= GetClass(wnd
);
484 /* window classes without assigned colors inherit parent's colors */
485 if (cfg
.clr
[cls
][0][0] == 0xff && GetParent(wnd
) != NULL
)
486 cls
= GetClass(GetParent(wnd
));
487 /* ---------- set the colors ---------- */
488 for (fbg
= 0; fbg
< 2; fbg
++)
489 for (col
= 0; col
< 4; col
++)
490 wnd
->WindowColors
[col
][fbg
] = cfg
.clr
[cls
][col
][fbg
];
493 void PutWindowChar(DFWINDOW wnd
, char c
, int x
, int y
)
495 if (x
< ClientWidth(wnd
) && y
< ClientHeight(wnd
))
496 wputch(wnd
, c
, x
+BorderAdj(wnd
), y
+TopBorderAdj(wnd
));
499 void PutWindowLine(DFWINDOW wnd
, void *s
, int x
, int y
)
504 if (x
< ClientWidth(wnd
) && y
< ClientHeight(wnd
))
506 char *en
= (char *)s
+ClientWidth(wnd
)-x
;
507 if ((int)(strlen(s
)+x
) > (int)ClientWidth(wnd
))
514 wputs(wnd
, s
, x
+BorderAdj(wnd
), y
+TopBorderAdj(wnd
));