- Allow menu highlight colour to be configured through an ARGB hex value in
[AROS.git] / workbench / c / Decoration / windowdecorclass.c
bloba5cbc010799f12e7c840e0e17ab23e9664d41efc
1 /*
2 Copyright © 2011-2012, The AROS Development Team.
3 $Id$
4 */
6 #include <clib/alib_protos.h>
8 #include <intuition/windecorclass.h>
9 #include <intuition/extensions.h>
10 #include <intuition/gadgetclass.h>
11 #include <graphics/rpattr.h>
12 #include <proto/arossupport.h>
13 #include <proto/intuition.h>
14 #include <proto/utility.h>
15 #include <proto/graphics.h>
16 #include <proto/cybergraphics.h>
17 #include <proto/exec.h>
18 #include <string.h>
20 #include "windowdecorclass.h"
21 #include "screendecorclass.h"
22 #include "drawfuncs.h"
23 #include "config.h"
25 #define SETIMAGE_WIN(id) wd->img_##id=sd->di->img_##id
27 struct windecor_data
29 struct DecorConfig * dc;
31 /* Pointers to images used for sys images */
32 struct NewImage *img_close;
33 struct NewImage *img_depth;
34 struct NewImage *img_zoom;
35 struct NewImage *img_up;
36 struct NewImage *img_down;
37 struct NewImage *img_left;
38 struct NewImage *img_right;
39 struct NewImage *img_mui;
40 struct NewImage *img_popup;
41 struct NewImage *img_snapshot;
42 struct NewImage *img_iconify;
43 struct NewImage *img_lock;
45 UWORD TextAlign;
48 #define CHANGE_NO_CHANGE 0
49 #define CHANGE_SIZE_CHANGE 1 /* Whole gadget area has changed */
50 #define CHANGE_NO_SIZE_CHANGE 2 /* Size remained the same, contents has changed */
52 static ULONG HasPropGadgetChanged(struct CachedPropGadget *cached, struct wdpDrawBorderPropKnob *msg)
54 /* More restrictive tests */
56 /* If the size has changed */
57 if (cached->width != (msg->wdp_PropRect->MaxX - msg->wdp_PropRect->MinX + 1))
58 return CHANGE_SIZE_CHANGE;
59 if (cached->height != (msg->wdp_PropRect->MaxY - msg->wdp_PropRect->MinY + 1))
60 return CHANGE_SIZE_CHANGE;
62 /* If there is no cached bitmap at all (this can happen NOT only at first call) */
63 if (cached->bm == NULL)
64 return CHANGE_SIZE_CHANGE;
66 /* Less restrictive tests */
68 /* If knob position has changed */
69 if (cached->knobx != (msg->wdp_RenderRect->MinX - msg->wdp_PropRect->MinX))
70 return CHANGE_NO_SIZE_CHANGE;
71 if (cached->knoby != (msg->wdp_RenderRect->MinY - msg->wdp_PropRect->MinY))
72 return CHANGE_NO_SIZE_CHANGE;
74 /* If knob is release state has changed */
75 if (cached->gadgetflags ^ (msg->wdp_Flags & WDF_DBPK_HIT))
76 return CHANGE_NO_SIZE_CHANGE;
78 /* If the window activity status has changed */
79 if (cached->windowflags ^ (msg->wdp_Window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)))
80 return CHANGE_NO_SIZE_CHANGE;
82 /* If knob size has changed */
83 if (cached->knobwidth != (msg->wdp_RenderRect->MaxX - msg->wdp_RenderRect->MinX + 1))
84 return CHANGE_NO_SIZE_CHANGE;
85 if (cached->knobheight != (msg->wdp_RenderRect->MaxY - msg->wdp_RenderRect->MinY + 1))
86 return CHANGE_NO_SIZE_CHANGE;
88 return CHANGE_NO_CHANGE;
91 static VOID CachePropGadget(struct CachedPropGadget *cached, struct wdpDrawBorderPropKnob *msg,
92 struct BitMap *bitmap)
94 cached->bm = bitmap;
95 cached->width = msg->wdp_PropRect->MaxX - msg->wdp_PropRect->MinX + 1;
96 cached->height = msg->wdp_PropRect->MaxY - msg->wdp_PropRect->MinY + 1;
97 cached->windowflags= (msg->wdp_Window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX));
98 cached->gadgetflags= (msg->wdp_Flags & WDF_DBPK_HIT);
99 cached->knobwidth = msg->wdp_RenderRect->MaxX - msg->wdp_RenderRect->MinX + 1;
100 cached->knobheight = msg->wdp_RenderRect->MaxY - msg->wdp_RenderRect->MinY + 1;
101 cached->knobx = msg->wdp_RenderRect->MinX - msg->wdp_PropRect->MinX;
102 cached->knoby = msg->wdp_RenderRect->MinY - msg->wdp_PropRect->MinY;
105 static ULONG HasTitleBarChanged(struct CachedTitleBar *cached, struct Window *window)
107 ULONG len = 0;
109 /* More restrictive tests */
111 /* If the window size has changed */
112 if (cached->width != window->Width)
113 return CHANGE_SIZE_CHANGE;
114 if (cached->height != window->Height)
115 return CHANGE_SIZE_CHANGE;
117 /* If there is no cached bitmap at all (this can happen NOT only at first call) */
118 if (cached->bm == NULL)
119 return CHANGE_SIZE_CHANGE;
121 /* Less restrictive tests */
123 /* If the window activity status has changed */
124 if (cached->windowflags ^ (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)))
125 return CHANGE_NO_SIZE_CHANGE;
127 /* If the window title/title contents has changed */
128 if (window->Title)
129 len = strlen(window->Title);
131 if (cached->titlelen != len)
132 return CHANGE_NO_SIZE_CHANGE;
134 if (cached->title)
136 /* At this point:
137 - length of both buffer is guarateed to be the same, see previous test
138 - both buffers are allocated
140 ULONG i;
141 for (i = 0; i < len; i++)
142 if (cached->title[i] != window->Title[i])
143 return CHANGE_NO_SIZE_CHANGE;
146 return CHANGE_NO_CHANGE;
149 static VOID CacheTitleBar(struct CachedTitleBar *cached, struct Window *window, struct BitMap *bitmap)
151 ULONG len = 0;
153 cached->bm = bitmap;
154 cached->width = window->Width;
155 cached->height = window->Height;
156 cached->windowflags = (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX));
158 /* Cache the title */
159 if (window->Title)
160 len = strlen(window->Title);
162 if (cached->titlelen != len)
164 if (cached->title)
165 FreeVec(cached->title);
166 cached->title = AllocVec(len + 1, MEMF_ANY | MEMF_CLEAR);
168 cached->titlelen = len;
169 strncpy(cached->title, window->Title, len);
172 static ULONG HasTitleBarShapeChanged(struct CachedTitleBarShape *cached, struct Window *window)
174 /* More restrictive tests */
176 /* If the window size has changed */
177 if (cached->width != window->Width)
178 return CHANGE_SIZE_CHANGE;
179 if (cached->height != window->Height)
180 return CHANGE_SIZE_CHANGE;
182 /* If there is no cached shape at all (this can happen NOT only at first call) */
183 if (cached->shape == NULL)
184 return CHANGE_SIZE_CHANGE;
186 /* Less restrictive tests */
188 /* If the window activity status has changed */
189 if (cached->windowflags ^ (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)))
190 return CHANGE_NO_SIZE_CHANGE;
192 return CHANGE_NO_CHANGE;
195 static VOID CacheTitleBarShape(struct CachedTitleBarShape *cached, struct Window *window, struct Region *shape)
197 cached->shape = shape;
198 cached->width = window->Width;
199 cached->height = window->Height;
200 cached->windowflags = (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX));
203 static int WriteTiledImageShape(BOOL fill, struct Window *win, struct NewLUT8Image *lut8, struct NewImage *ni, int sx, int sy, int sw, int sh, int xp, int yp, int dw, int dh)
205 int w = dw;
206 int x = xp;
207 int ddw;
209 if (!ni->ok) return xp;
211 if ((sw == 0) || (dw == 0)) return xp;
213 if (win)
215 if (x > win->Width) return xp;
216 if ((x + w) > win->Width) w = win->Width - x;
219 while (w > 0)
221 ddw = sw;
222 if (w < ddw) ddw = w;
223 WriteAlphaPixelArray(ni, lut8, sx, sy, x, yp, ddw, dh);
224 w -= ddw;
225 x += ddw;
227 return x;
230 static void getrightgadgetsdimensions(struct windecor_data *data, struct Window *win, LONG *xs, LONG *xe)
232 struct Gadget *g;
234 LONG x0 = 1000000;
235 LONG x1 = 0;
236 UWORD type;
238 for (g = win->FirstGadget; g; g = g->NextGadget)
240 if ((g->Flags & GFLG_RELRIGHT) == GFLG_RELRIGHT)
242 type = g->GadgetType & GTYP_SYSTYPEMASK;
243 if (data->dc->CloseGadgetOnRight)
245 if (((type & (GTYP_CLOSE | GTYP_WDEPTH | GTYP_WZOOM)) != 0) || (g->Activation & GACT_TOPBORDER))
247 if (g->Width > 0)
249 if ((win->Width + g->LeftEdge) < x0) x0 = win->Width + g->LeftEdge;
250 if ((win->Width + g->LeftEdge + g->Width) > x1) x1 = win->Width + g->LeftEdge + g->Width;
254 else
256 if (((type & (GTYP_WDEPTH | GTYP_WZOOM)) != 0) || (g->Activation & GACT_TOPBORDER))
258 if (g->Width > 0)
260 if ((win->Width + g->LeftEdge) < x0) x0 = win->Width + g->LeftEdge;
261 if ((win->Width + g->LeftEdge + g->Width) > x1) x1 = win->Width + g->LeftEdge + g->Width;
267 if (x0 == 1000000) x0 = 0;
268 *xs = x0;
269 *xe = x1;
272 static void getleftgadgetsdimensions(struct windecor_data *data, struct Window *win, LONG *xs, LONG *xe)
274 struct Gadget *g;
276 LONG w = 0;
277 LONG x0 = 1000000;
278 LONG x1 = 0;
279 for (g = win->FirstGadget; g; g = g->NextGadget)
281 w++;
282 if (((g->Flags & GFLG_RELRIGHT) == 0) && (g->Activation & GACT_TOPBORDER))
284 if ((g->GadgetType & GTYP_WDRAGGING) == 0)
286 if (g->Width > 0)
288 if (g->LeftEdge < x0) x0 = g->LeftEdge;
289 if ((g->LeftEdge + g->Width) > x1) x1 = g->LeftEdge + g->Width;
294 if (x0 == 1000000) x0 = 0;
295 *xs = x0;
296 *xe = x1;
299 static void DrawShapePartialTitleBar(struct WindowData *wd, struct NewLUT8Image *shape, struct windecor_data *data, struct Window *window)
301 LONG xl0, xl1, xr0, xr1, defwidth;
302 ULONG textlen = 0, titlelen = 0, textpixellen = 0;
303 struct TextExtent te;
305 BOOL hastitle;
306 BOOL hastitlebar;
307 LONG dy;
309 struct RastPort *rp = &window->WScreen->RastPort;
310 hastitle = window->Title != NULL ? TRUE : FALSE;
311 hastitlebar = (window->BorderTop > 0) ? TRUE : FALSE;
313 getleftgadgetsdimensions(data, window, &xl0, &xl1);
314 getrightgadgetsdimensions(data, window, &xr0, &xr1);
316 defwidth = (xl0 != xl1) ? data->dc->BarPreGadget_s : data->dc->BarPre_s;
317 if(xr1 == 0)
319 xr1 = window->Width - data->dc->BarPre_s;
320 xr0 = window->Width - data->dc->BarPre_s;
323 defwidth += (xl1 - xl0);
325 defwidth += data->dc->BarJoinGB_s;
326 defwidth += data->dc->BarJoinBT_s;
327 defwidth += data->dc->BarJoinTB_s;
328 defwidth += data->dc->BarJoinBG_s;
329 defwidth += (xr1 - xr0);
330 defwidth += (xr0 != xr1) ? data->dc->BarPostGadget_s : data->dc->BarPost_s;
332 if (defwidth >= window->Width) hastitle = FALSE;
334 if (hastitle)
336 titlelen = strlen(window->Title);
337 textlen = TextFit(rp, window->Title, titlelen, &te, NULL, 1, window->Width-defwidth, window->BorderTop - 2);
338 if (textlen)
340 textpixellen = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
345 if (wd->img_winbar_normal->ok && hastitlebar)
347 UWORD x = 0;
348 UWORD barh = window->BorderTop;
349 struct NewImage * img_winbar_normal = wd->img_winbar_normal;
351 if (data->dc->BarHeight != barh)
352 img_winbar_normal = ScaleNewImage(wd->img_winbar_normal, wd->img_winbar_normal->w, 2 * barh);
354 if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX))
355 dy = 0;
356 else
357 dy = barh; /* Offset into source image */
359 if (xl0 != xl1)
361 x = WriteTiledImageShape(data->dc->FillTitleBar, window, shape,img_winbar_normal, data->dc->BarPreGadget_o, dy, data->dc->BarPreGadget_s, barh, x, 0, data->dc->BarPreGadget_s, barh);
362 if ((xl1-xl0) > 0) x = WriteTiledImageShape(data->dc->FillTitleBar, window, shape, img_winbar_normal, data->dc->BarLGadgetFill_o, dy, data->dc->BarLGadgetFill_s, barh, x, 0, xl1-xl0, barh);
364 else
366 x = WriteTiledImageShape(data->dc->FillTitleBar, window, shape, img_winbar_normal, data->dc->BarPre_o, dy, data->dc->BarPre_s, barh, x, 0, data->dc->BarPreGadget_s, barh);
368 x = WriteTiledImageShape(data->dc->FillTitleBar, window, shape, img_winbar_normal, data->dc->BarJoinGB_o, dy, data->dc->BarJoinGB_s, barh, x, 0, data->dc->BarJoinGB_s, barh);
369 if (hastitle && (textlen > 0))
371 switch(data->TextAlign)
373 case WD_DWTA_CENTER:
374 //BarLFill
375 x = WriteTiledImageShape(data->dc->FillTitleBar, window, shape, img_winbar_normal, data->dc->BarLFill_o, dy, data->dc->BarLFill_s, barh, x, 0, 60, barh);
376 break;
377 case WD_DWTA_RIGHT:
378 //BarLFill
379 break;
380 default:
381 case WD_DWTA_LEFT:
382 break;
384 x = WriteTiledImageShape(data->dc->FillTitleBar, window, shape, img_winbar_normal, data->dc->BarJoinBT_o, dy, data->dc->BarJoinBT_s, barh, x, 0, data->dc->BarJoinBT_s, barh);
385 if (textpixellen > 0) x = WriteTiledImageShape(data->dc->FillTitleBar, window, shape, img_winbar_normal, data->dc->BarTitleFill_o, dy, data->dc->BarTitleFill_s, barh, x, 0, textpixellen, barh);
386 x = WriteTiledImageShape(data->dc->FillTitleBar, window, shape, img_winbar_normal, data->dc->BarJoinTB_o, dy, data->dc->BarJoinTB_s, barh, x, 0, data->dc->BarJoinTB_s, barh);
388 x = WriteTiledImageShape(data->dc->FillTitleBar, window, shape, img_winbar_normal, data->dc->BarRFill_o, dy, data->dc->BarRFill_s, barh, x, 0, xr0 - x - data->dc->BarJoinBG_s, barh);
389 x = WriteTiledImageShape(data->dc->FillTitleBar, window, shape, img_winbar_normal, data->dc->BarJoinBG_o, dy, data->dc->BarJoinBG_s, barh, x, 0, data->dc->BarJoinBG_s, barh);
390 if ((xr1-xr0) > 0) x = WriteTiledImageShape(data->dc->FillTitleBar, window, shape, img_winbar_normal, data->dc->BarRGadgetFill_o, dy, data->dc->BarRGadgetFill_s, barh, x, 0, xr1-xr0, barh);
391 if (xr0 != xr1)
393 x = WriteTiledImageShape(data->dc->FillTitleBar, window, shape, img_winbar_normal, data->dc->BarPostGadget_o, dy, data->dc->BarPostGadget_s, barh, x, 0, data->dc->BarPostGadget_s, barh);
395 else
397 x = WriteTiledImageShape(data->dc->FillTitleBar, window, shape, img_winbar_normal, data->dc->BarPost_o, dy, data->dc->BarPost_s, barh, x, 0, data->dc->BarPost_s, barh);
400 if (data->dc->BarHeight != barh)
401 DisposeImageContainer(img_winbar_normal);
405 static VOID DrawPartialTitleBar(struct WindowData *wd, struct windecor_data *data, struct Window *window, struct RastPort *dst_rp, struct DrawInfo *dri, UWORD *pens)
407 LONG xl0, xl1, xr0, xr1, defwidth;
408 ULONG textlen = 0, titlelen = 0, textpixellen = 0;
409 struct TextExtent te;
410 struct RastPort *rp;
411 struct NewImage *ni = NULL;
413 BOOL hastitle;
414 BOOL hastitlebar;
415 UWORD textstart = 0;
416 ULONG color, s_col, e_col, arc;
417 LONG dy;
418 LONG pen = -1;
419 ULONG changetype = CHANGE_NO_CHANGE;
420 struct BitMap *cachedtitlebarbitmap = NULL;
422 changetype = HasTitleBarChanged(&wd->tbar, window);
423 if (changetype == CHANGE_SIZE_CHANGE)
425 if (wd->tbar.bm)
426 FreeBitMap(wd->tbar.bm);
427 wd->tbar.bm = NULL;
429 cachedtitlebarbitmap = wd->tbar.bm;
431 if (changetype == CHANGE_NO_CHANGE)
433 BltBitMapRastPort(cachedtitlebarbitmap, 0, 0, dst_rp, 0, 0, window->Width, window->BorderTop, 0xc0);
434 return;
437 /* Regenerate the bitmap */
438 rp = CreateRastPort();
439 if (rp)
441 /* Reuse the bitmap if there was no size change (ie. only change of state) */
442 if (changetype == CHANGE_NO_SIZE_CHANGE)
443 rp->BitMap = cachedtitlebarbitmap;
444 else
445 rp->BitMap = AllocBitMap(window->Width, window->BorderTop, 1, 0, window->WScreen->RastPort.BitMap);
447 if (rp->BitMap == NULL)
449 FreeRastPort(rp);
450 return;
453 SetFont(rp, dri->dri_Font);
455 else
456 return;
458 hastitle = window->Title != NULL ? TRUE : FALSE;
459 hastitlebar = (window->BorderTop > 0) ? TRUE : FALSE;
461 if (wd->img_border_normal->ok) ni = wd->img_border_normal;
463 if (ni == NULL) data->dc->UseGradients = TRUE;
465 color = 0x00cccccc;
467 if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX))
469 s_col = data->dc->ActivatedGradientColor_s;
470 e_col = data->dc->ActivatedGradientColor_e;
471 arc = data->dc->ActivatedGradientColor_a;
472 dy = 0;
473 pen = wd->ActivePen;
474 } else {
475 s_col = data->dc->DeactivatedGradientColor_s;
476 e_col = data->dc->DeactivatedGradientColor_e;
477 arc = data->dc->DeactivatedGradientColor_a;
478 dy = data->dc->BarHeight;
479 if (!data->dc->UseGradients)
481 if (wd->img_border_deactivated->ok) ni = wd->img_border_deactivated;
483 pen = wd->DeactivePen;
487 if (data->dc->FillTitleBar)
489 if (data->dc->UseGradients) FillPixelArrayGradient(pen, wd->truecolor, rp, 0, 0, window->Width - 1, window->Height - 1, 0, 0, window->Width, window->BorderTop, s_col, e_col, arc, 0, 0);
490 else HorizVertRepeatNewImage(ni, color, 0, 0, rp, 0, 0, window->Width, window->BorderTop);
493 getleftgadgetsdimensions(data, window, &xl0, &xl1);
494 getrightgadgetsdimensions(data, window, &xr0, &xr1);
495 defwidth = (xl0 != xl1) ? data->dc->BarPreGadget_s : data->dc->BarPre_s;
496 if(xr1 == 0)
498 xr1 = window->Width - data->dc->BarPre_s;
499 xr0 = window->Width - data->dc->BarPre_s;
502 defwidth += (xl1 - xl0);
504 defwidth += data->dc->BarJoinGB_s;
505 defwidth += data->dc->BarJoinBT_s;
506 defwidth += data->dc->BarJoinTB_s;
507 defwidth += data->dc->BarJoinBG_s;
508 defwidth += (xr1 - xr0);
509 defwidth += (xr0 != xr1) ? data->dc->BarPostGadget_s : data->dc->BarPost_s;
511 if (defwidth >= window->Width) hastitle = FALSE;
513 if (hastitle)
515 titlelen = strlen(window->Title);
516 textlen = TextFit(rp, window->Title, titlelen, &te, NULL, 1, window->Width-defwidth, window->BorderTop - 2);
517 if (textlen)
519 textpixellen = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
523 if (wd->img_winbar_normal->ok && hastitlebar)
525 UWORD x = 0;
526 UWORD barh = window->BorderTop;
527 struct NewImage * img_winbar_normal = wd->img_winbar_normal;
529 if (data->dc->BarHeight != barh)
530 img_winbar_normal = ScaleNewImage(wd->img_winbar_normal, wd->img_winbar_normal->w, 2 * barh);
532 if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX))
533 dy = 0;
534 else
535 dy = barh; /* Offset into source image */
537 if (xl0 != xl1)
539 x = WriteTiledImageTitle(data->dc->FillTitleBar, window, rp, img_winbar_normal, data->dc->BarPreGadget_o, dy, data->dc->BarPreGadget_s, barh, x, 0, data->dc->BarPreGadget_s, barh);
540 if ((xl1-xl0) > 0) x = WriteTiledImageTitle(data->dc->FillTitleBar, window, rp,img_winbar_normal, data->dc->BarLGadgetFill_o, dy, data->dc->BarLGadgetFill_s, barh, x, 0, xl1-xl0, barh);
542 else
544 x = WriteTiledImageTitle(data->dc->FillTitleBar, window, rp, img_winbar_normal, data->dc->BarPre_o, dy, data->dc->BarPre_s, barh, x, 0, data->dc->BarPreGadget_s, barh);
546 x = WriteTiledImageTitle(data->dc->FillTitleBar, window, rp,img_winbar_normal, data->dc->BarJoinGB_o, dy, data->dc->BarJoinGB_s, barh, x, 0, data->dc->BarJoinGB_s, barh);
547 if (hastitle && (textlen > 0))
549 switch(data->TextAlign)
551 case WD_DWTA_CENTER:
552 //BarLFill
553 x = WriteTiledImageTitle(data->dc->FillTitleBar, window, rp, img_winbar_normal, data->dc->BarLFill_o, dy, data->dc->BarLFill_s, barh, x, 0, 60, barh);
554 break;
555 case WD_DWTA_RIGHT:
556 //BarLFill
557 break;
558 default:
559 case WD_DWTA_LEFT:
560 break;
562 x = WriteTiledImageTitle(data->dc->FillTitleBar, window, rp, img_winbar_normal, data->dc->BarJoinBT_o, dy, data->dc->BarJoinBT_s, barh, x, 0, data->dc->BarJoinBT_s, barh);
563 textstart = x;
564 if (textpixellen > 0) x = WriteTiledImageTitle(data->dc->FillTitleBar, window, rp, img_winbar_normal, data->dc->BarTitleFill_o, dy, data->dc->BarTitleFill_s, barh, x, 0, textpixellen, barh);
565 x = WriteTiledImageTitle(data->dc->FillTitleBar, window, rp, img_winbar_normal, data->dc->BarJoinTB_o, dy, data->dc->BarJoinTB_s, barh, x, 0, data->dc->BarJoinTB_s, barh);
567 /* Part right to window title */
568 x = WriteTiledImageTitle(data->dc->FillTitleBar, window, rp, img_winbar_normal, data->dc->BarRFill_o, dy, data->dc->BarRFill_s, barh, x, 0, xr0 - x - data->dc->BarJoinBG_s, barh);
569 x = WriteTiledImageTitle(data->dc->FillTitleBar, window, rp, img_winbar_normal, data->dc->BarJoinBG_o, dy, data->dc->BarJoinBG_s, barh, x, 0, data->dc->BarJoinBG_s, barh);
570 if ((xr1-xr0) > 0) x = WriteTiledImageTitle(data->dc->FillTitleBar, window, rp, img_winbar_normal, data->dc->BarRGadgetFill_o, dy, data->dc->BarRGadgetFill_s, barh, x, 0, xr1-xr0, barh);
571 if (xr0 != xr1)
573 x = WriteTiledImageTitle(data->dc->FillTitleBar, window, rp, img_winbar_normal, data->dc->BarPostGadget_o, dy, data->dc->BarPostGadget_s, barh, x, 0, data->dc->BarPostGadget_s, barh);
575 else
577 x = WriteTiledImageTitle(data->dc->FillTitleBar, window, rp, img_winbar_normal, data->dc->BarPost_o, dy, data->dc->BarPost_s, barh, x, 0, data->dc->BarPost_s, barh);
580 if (data->dc->BarHeight != barh)
581 DisposeImageContainer(img_winbar_normal);
584 if ((textlen > 0) && hastitle)
586 SetAPen(rp, pens[(window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)) ? FILLTEXTPEN : TEXTPEN]);
587 SetDrMd(rp, JAM1);
588 UWORD tx = textstart;
589 UWORD tymax = window->BorderTop - (dri->dri_Font->tf_YSize - dri->dri_Font->tf_Baseline) - 1;
590 UWORD ty = (window->BorderTop + dri->dri_Font->tf_Baseline - 1) >> 1;
591 if (ty > tymax) ty = tymax;
593 if (!wd->truecolor || ((data->dc->TitleOutline == FALSE) && (data->dc->TitleShadow == FALSE)))
595 Move(rp, tx, ty);
596 Text(rp, window->Title, textlen);
598 else if (data->dc->TitleOutline)
601 SetSoftStyle(rp, FSF_BOLD, AskSoftStyle(rp));
602 SetRPAttrs(rp, RPTAG_PenMode, FALSE, RPTAG_FgColor, data->dc->TitleColorShadow, TAG_DONE);
604 Move(rp, tx + 1, ty ); Text(rp, window->Title, textlen);
605 Move(rp, tx + 2, ty ); Text(rp, window->Title, textlen);
606 Move(rp, tx , ty ); Text(rp, window->Title, textlen);
607 Move(rp, tx, ty + 1); Text(rp, window->Title, textlen);
608 Move(rp, tx, ty + 2); Text(rp, window->Title, textlen);
609 Move(rp, tx + 1, ty + 2); Text(rp, window->Title, textlen);
610 Move(rp, tx + 2, ty + 1); Text(rp, window->Title, textlen);
611 Move(rp, tx + 2, ty + 2); Text(rp, window->Title, textlen);
613 SetRPAttrs(rp, RPTAG_PenMode, FALSE, RPTAG_FgColor, data->dc->TitleColorText, TAG_DONE);
614 Move(rp, tx + 1, ty + 1);
615 Text(rp, window->Title, textlen);
616 SetSoftStyle(rp, FS_NORMAL, AskSoftStyle(rp));
618 else
620 SetRPAttrs(rp, RPTAG_PenMode, FALSE, RPTAG_FgColor, data->dc->TitleColorShadow, TAG_DONE);
621 Move(rp, tx + 1, ty + 1 );
622 Text(rp, window->Title, textlen);
624 SetRPAttrs(rp, RPTAG_PenMode, FALSE, RPTAG_FgColor, data->dc->TitleColorText, TAG_DONE);
625 Move(rp, tx, ty);
626 Text(rp, window->Title, textlen);
631 BltBitMapRastPort(rp->BitMap, 0, 0, dst_rp, 0, 0, window->Width, window->BorderTop, 0xc0);
633 /* Cache the actual bitmap */
634 CacheTitleBar(&wd->tbar, window, rp->BitMap);
636 FreeRastPort(rp);
639 static VOID DisposeWindowSkinning(struct windecor_data *data)
644 static BOOL InitWindowSkinning(struct windecor_data *data, struct DecorImages * di, struct DecorConfig * dc)
646 if ((!di) || (!dc))
647 return FALSE;
649 data->dc = dc;
651 data->TextAlign = WD_DWTA_LEFT;
653 /* Set pointers to gadget images, used only to get gadget sizes as they
654 are requested prior to creation of menu object */
655 data->img_close = di->img_close;
656 data->img_depth = di->img_depth;
657 data->img_zoom = di->img_zoom;
658 data->img_up = di->img_up;
659 data->img_down = di->img_down;
660 data->img_left = di->img_left;
661 data->img_right = di->img_right;
662 data->img_mui = di->img_mui;
663 data->img_popup = di->img_popup;
664 data->img_snapshot = di->img_snapshot;
665 data->img_iconify = di->img_iconify;
666 data->img_lock = di->img_lock;
668 if (data->img_close && data->img_depth && data->img_zoom && data->img_up &&
669 data->img_down && data->img_left && data->img_right)
670 return TRUE;
672 DisposeWindowSkinning(data);
673 return FALSE;
676 /**************************************************************************************************/
677 static IPTR windecor_new(Class *cl, Object *obj, struct opSet *msg)
679 struct windecor_data *data;
681 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
682 if (obj)
684 data = INST_DATA(cl, obj);
686 struct DecorImages * di = (struct DecorImages *) GetTagData(WDA_DecorImages, (IPTR)NULL, msg->ops_AttrList);
687 struct DecorConfig * dc = (struct DecorConfig *) GetTagData(WDA_DecorConfig, (IPTR)NULL, msg->ops_AttrList);
689 if (!InitWindowSkinning(data, di, dc))
691 CoerceMethod(cl, obj, OM_DISPOSE);
692 obj = NULL;
696 return (IPTR)obj;
699 /**************************************************************************************************/
700 static IPTR windecor_dispose(Class *cl, Object *obj, struct opSet *msg)
702 struct windecor_data *data = INST_DATA(cl, obj);
704 DisposeWindowSkinning(data);
706 return 1;
709 /**************************************************************************************************/
710 static IPTR windecor_get(Class *cl, Object *obj, struct opGet *msg)
712 switch(msg->opg_AttrID)
714 case WDA_TrueColorOnly:
715 *msg->opg_Storage = TRUE;
716 break;
717 default:
718 return DoSuperMethodA(cl, obj, (Msg)msg);
720 return 1;
723 /**************************************************************************************************/
724 static IPTR windecor_draw_sysimage(Class *cl, Object *obj, struct wdpDrawSysImage *msg)
726 struct windecor_data *data = INST_DATA(cl, obj);
727 struct RastPort *rp = msg->wdp_RPort;
728 struct NewImage *ni = NULL;
729 struct WindowData *wd = (struct WindowData *) msg->wdp_UserBuffer;
730 LONG state = msg->wdp_State;
731 LONG left = msg->wdp_X;
732 LONG top = msg->wdp_Y;
733 LONG width = msg->wdp_Width;
734 LONG height = msg->wdp_Height;
735 WORD addx = 0;
736 WORD addy = 0;
737 BOOL isset = FALSE;
738 BOOL titlegadget = FALSE;
740 switch(msg->wdp_Which)
742 case SIZEIMAGE:
743 if (wd->img_size->ok)
745 ni = wd->img_size;
746 isset = TRUE;
747 if (data->dc->GadgetsThreeState)
748 addx = (data->dc->RightBorderGadgets - (wd->img_size->w / 3)) /2;
749 else
750 addx = (data->dc->RightBorderGadgets - (wd->img_size->w >> 2)) /2;
751 addy = (data->dc->BottomBorderGadgets - wd->img_size->h) / 2;
753 break;
755 case CLOSEIMAGE:
756 if (wd->img_close->ok)
758 ni = wd->img_close;
759 isset = TRUE;
760 titlegadget = TRUE;
762 break;
764 case MUIIMAGE:
765 if (wd->img_mui->ok)
767 ni = wd->img_mui;
768 isset = TRUE;
769 titlegadget = TRUE;
771 break;
773 case POPUPIMAGE:
774 if (wd->img_popup->ok)
776 ni = wd->img_popup;
777 isset = TRUE;
778 titlegadget = TRUE;
780 break;
782 case SNAPSHOTIMAGE:
783 if (wd->img_snapshot->ok)
785 ni = wd->img_snapshot;
786 isset = TRUE;
787 titlegadget = TRUE;
789 break;
791 case LOCKIMAGE:
792 if (wd->img_lock->ok)
794 ni = wd->img_lock;
795 isset = TRUE;
796 titlegadget = TRUE;
798 break;
800 case ICONIFYIMAGE:
801 if (wd->img_iconify->ok)
803 ni = wd->img_iconify;
804 isset = TRUE;
805 titlegadget = TRUE;
807 break;
809 case DEPTHIMAGE:
810 if (wd->img_depth->ok)
812 ni = wd->img_depth;
813 isset = TRUE;
814 titlegadget = TRUE;
816 break;
818 case ZOOMIMAGE:
819 if (wd->img_zoom->ok)
821 ni = wd->img_zoom;
822 isset = TRUE;
823 titlegadget = TRUE;
825 break;
827 case UPIMAGE:
828 ni = wd->img_up;
829 if (data->dc->GadgetsThreeState) addx = (data->dc->RightBorderGadgets - (wd->img_up->w / 3)) /2; else addx = (data->dc->RightBorderGadgets - (wd->img_up->w >> 2)) /2;
830 addy = data->dc->UpDownAddY / 2;
831 isset = TRUE;
832 break;
834 case DOWNIMAGE:
835 ni = wd->img_down;
836 if (data->dc->GadgetsThreeState) addx = (data->dc->RightBorderGadgets - (wd->img_down->w / 3)) /2; else addx = (data->dc->RightBorderGadgets - (wd->img_down->w >> 2)) /2;
837 addy = data->dc->UpDownAddY / 2;
838 isset = TRUE;
839 break;
841 case LEFTIMAGE:
842 ni = wd->img_left;
843 addx = data->dc->LeftRightAddX / 2;
844 addy = (data->dc->BottomBorderGadgets - wd->img_left->h) / 2;
845 isset = TRUE;
846 break;
848 case RIGHTIMAGE:
849 ni = wd->img_right;
850 addx = data->dc->LeftRightAddX / 2;
851 addy = (data->dc->BottomBorderGadgets - wd->img_right->h) /2;
852 isset = TRUE;
853 break;
855 default:
856 return DoSuperMethodA(cl, obj, (Msg)msg);
859 if (!isset) return DoSuperMethodA(cl, obj, (Msg)msg);
861 /* Reblit title bar */
862 if (wd && titlegadget && wd->tbar.bm)
863 BltBitMapRastPort(wd->tbar.bm, left + addx, top + addy, rp, left + addx, top + addy, width, height, 0xc0);
865 if (ni)
867 if (titlegadget)
868 DrawScaledStatefulGadgetImageToRP(rp, ni, state, left + addx, top + addy, -1, height);
869 else
870 DrawStatefulGadgetImageToRP(rp, ni, state, left + addx, top + addy);
873 return TRUE;
876 /**************************************************************************************************/
877 static IPTR windecor_draw_winborder(Class *cl, Object *obj, struct wdpDrawWinBorder *msg)
879 struct windecor_data *data = INST_DATA(cl, obj);
880 struct RastPort *rp = msg->wdp_RPort;
881 struct Window *window = msg->wdp_Window;
882 struct WindowData *wd = (struct WindowData *) msg->wdp_UserBuffer;
883 struct NewImage *ni = NULL;
884 UWORD *pens = msg->wdp_Dri->dri_Pens;
885 ULONG bc = 0, color, s_col, e_col, arc;
886 UWORD bl, bt, br, bb, ww, wh;
887 LONG pen = -1;
889 if (wd->img_border_normal->ok) ni = wd->img_border_normal;
891 if (ni == NULL) data->dc->UseGradients = TRUE;
893 BOOL tc = wd->truecolor;
895 LONG dpen = pens[SHADOWPEN];
896 LONG lpen = pens[SHINEPEN];
897 LONG mpen = pens[SHINEPEN];
899 bl = window->BorderLeft;
900 bt = window->BorderTop;
901 bb = window->BorderBottom;
902 br = window->BorderRight;
903 ww = window->Width;
904 wh = window->Height;
906 color = 0x00cccccc;
908 if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX))
910 pen = wd->ActivePen;
911 s_col = data->dc->ActivatedGradientColor_s;
912 e_col = data->dc->ActivatedGradientColor_e;
913 arc = data->dc->ActivatedGradientColor_a;
914 bc = data->dc->BaseColors_a;
915 } else {
916 pen = wd->DeactivePen;
917 s_col = data->dc->DeactivatedGradientColor_s;
918 e_col = data->dc->DeactivatedGradientColor_e;
919 arc = data->dc->DeactivatedGradientColor_a;
920 if (!data->dc->UseGradients)
922 if (wd->img_border_deactivated->ok) ni = wd->img_border_deactivated;
926 /* Draw title bar */
927 DrawPartialTitleBar(wd, data, window, rp, msg->wdp_Dri, pens);
929 /* Draw left, right and bottom frames */
930 if (!(msg->wdp_Flags & WDF_DWB_TOP_ONLY))
932 UBYTE * buf = NULL;
934 if (data->dc->UseGradients)
936 /* Create one pixel wide buffer */
937 buf = AllocVec(1 * window->Height * 3, MEMF_ANY | MEMF_CLEAR);
939 /* Fill the buffer with gradient */
940 FillMemoryBufferRGBGradient(buf, pen, 0, 0, window->Width - 1, window->Height - 1, 0, 0,
941 1, window->Height , s_col, e_col, arc);
944 if (data->dc->UseGradients)
946 /* Reuse the buffer for blitting frames */
947 if (window->BorderLeft > 2) HorizRepeatBuffer(buf, window->BorderTop, pen, wd->truecolor, rp,
948 0, window->BorderTop,
949 window->BorderLeft, window->Height - window->BorderTop);
950 if (window->BorderRight > 2) HorizRepeatBuffer(buf, window->BorderTop, pen, wd->truecolor, rp,
951 window->Width - window->BorderRight, window->BorderTop,
952 window->BorderRight, window->Height - window->BorderTop);
953 if (window->BorderBottom > 2) HorizRepeatBuffer(buf, window->Height - window->BorderBottom, pen, wd->truecolor, rp,
954 0, window->Height - window->BorderBottom,
955 window->Width, window->BorderBottom);
957 else
959 if (window->BorderLeft > 2) HorizVertRepeatNewImage(ni, color, 0, window->BorderTop, rp,
960 0, window->BorderTop,
961 window->BorderLeft - 1, window->Height - window->BorderTop);
962 if (window->BorderRight > 2) HorizVertRepeatNewImage(ni, color, window->Width - window->BorderRight , window->BorderTop, rp,
963 window->Width - window->BorderRight , window->BorderTop,
964 window->BorderRight, window->Height - window->BorderTop);
965 if (window->BorderBottom > 2) HorizVertRepeatNewImage(ni, color, 0, window->Height - window->BorderBottom, rp,
966 0, window->Height - window->BorderBottom,
967 window->Width, window->BorderBottom);
970 /* Shading borders */
971 int bbt = bt;
973 if (bl > 0) ShadeLine(dpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_d, bbt, 0, bbt, 0, wh - 1);
974 if (bb > 0) ShadeLine(dpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_d, wh - 1, 0, wh - 1, ww - 1, wh - 1);
975 if (br > 0) ShadeLine(dpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_d, bbt , ww - 1, bbt , ww - 1, wh - 1);
976 if (bl > 1) ShadeLine(dpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_d, bbt, bl - 1, bbt, bl - 1, wh - bb);
977 if (bb > 1) ShadeLine(dpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_d, wh - bb, bl - 1, wh - bb, ww - br, wh - bb);
978 if (br > 1) ShadeLine(dpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_d, bbt , ww - br, bbt , ww - br, wh - bb);
979 if (bl > 2) ShadeLine(lpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_l, bbt, 1, bbt, 1, wh - 2);
980 if (bl > 3) {
981 if (bb > 1) ShadeLine(mpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_m, bbt, bl - 2, bbt, bl - 2, wh - bb + 1);
982 else ShadeLine(mpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_m, bbt, bl - 2, bbt, bl - 2, wh - bb);
984 if (br > 2) ShadeLine(mpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_m, bbt, ww - 2, bbt, ww - 2, wh - 2);
985 if (bb > 2) ShadeLine(mpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_m, wh - 2, 1, wh - 2, ww - 2, wh - 2);
986 if (bb > 3) {
987 if ((bl > 0) && (br > 0)) ShadeLine(lpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_l, wh - bb + 1, bl, wh - bb + 1, ww - br, wh - bb + 1);
989 if (br > 3) {
990 if (bb > 1) ShadeLine(lpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_l, bbt, ww - br + 1, bbt, ww - br + 1, wh - bb + 1);
993 FreeVec(buf);
995 return TRUE;
998 /**************************************************************************************************/
999 static IPTR windecor_layout_bordergadgets(Class *cl, Object *obj, struct wdpLayoutBorderGadgets *msg)
1001 struct windecor_data *data = INST_DATA(cl, obj);
1002 struct Window *window = msg->wdp_Window;
1003 struct Gadget *gadget = msg->wdp_Gadgets;
1004 struct Gadget *draggadget = NULL;
1005 struct WindowData *wd = (struct WindowData *) msg->wdp_UserBuffer;
1006 ULONG eb = msg->wdp_ExtraButtons;
1008 BOOL hasdepth;
1009 BOOL haszoom;
1010 BOOL hasclose;
1011 LONG width;
1012 LONG refheight = window->BorderTop;
1014 DoSuperMethodA(cl, obj, (Msg)msg);
1016 hasclose = (window->Flags & WFLG_CLOSEGADGET) ? TRUE : FALSE;
1017 hasdepth = (window->Flags & WFLG_DEPTHGADGET) ? TRUE : FALSE;
1018 haszoom = ((window->Flags & WFLG_HASZOOM) || ((window->Flags & WFLG_SIZEGADGET) && hasdepth)) ? TRUE : FALSE;
1021 if ((msg->wdp_Flags & WDF_LBG_SYSTEMGADGET) != 0)
1023 if (gadget->GadgetType == GTYP_CUSTOMGADGET)
1025 switch(gadget->GadgetID)
1027 case ETI_MUI:
1028 if (wd->img_mui->ok)
1030 if (data->dc->GadgetsThreeState) width = (wd->img_mui->w / 3); else width = (wd->img_mui->w >> 2);
1032 gadget->Width = width;
1033 gadget->TopEdge = (refheight - gadget->Height) / 2;
1035 if (haszoom)
1037 if (data->dc->GadgetsThreeState) width += (wd->img_zoom->w / 3); else width += (wd->img_zoom->w >> 2);
1039 if (hasclose && data->dc->CloseGadgetOnRight)
1041 if (data->dc->GadgetsThreeState) width += (wd->img_close->w / 3); else width += (wd->img_close->w >> 2);
1043 if (hasdepth)
1045 if (data->dc->GadgetsThreeState) width += (wd->img_depth->w / 3); else width += (wd->img_depth->w >> 2);
1046 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1048 else
1050 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1052 gadget->Flags &= ~GFLG_RELWIDTH;
1053 gadget->Flags |= GFLG_RELRIGHT;
1056 break;
1058 case ETI_PopUp:
1059 if (wd->img_popup->ok)
1061 if (data->dc->GadgetsThreeState) width = (wd->img_popup->w / 3); else width = (wd->img_popup->w >> 2);
1063 gadget->Width = width;
1064 gadget->TopEdge = (refheight - gadget->Height) / 2;
1066 if ((eb & ETG_MUI) != 0)
1068 if (wd->img_mui->ok)
1070 if (data->dc->GadgetsThreeState) width += (wd->img_mui->w / 3); else width += (wd->img_mui->w >> 2);
1074 if (haszoom)
1076 if (data->dc->GadgetsThreeState) width += (wd->img_zoom->w / 3); else width += (wd->img_zoom->w >> 2);
1079 if (hasclose && data->dc->CloseGadgetOnRight)
1081 if (data->dc->GadgetsThreeState) width += (wd->img_close->w / 3); else width += (wd->img_close->w >> 2);
1083 if (hasdepth)
1085 if (data->dc->GadgetsThreeState) width += (wd->img_depth->w / 3); else width += (wd->img_depth->w >> 2);
1086 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1088 else
1090 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1092 gadget->Flags &= ~GFLG_RELWIDTH;
1093 gadget->Flags |= GFLG_RELRIGHT;
1096 break;
1098 case ETI_Snapshot:
1099 if (wd->img_snapshot->ok)
1101 if (data->dc->GadgetsThreeState) width = (wd->img_snapshot->w / 3); else width = (wd->img_snapshot->w >> 2);
1103 gadget->Width = width;
1104 gadget->TopEdge = (refheight - gadget->Height) / 2;
1106 if ((eb & ETG_MUI) != 0)
1109 if (wd->img_mui->ok)
1111 if (data->dc->GadgetsThreeState) width += (wd->img_mui->w / 3); else width += (wd->img_mui->w >> 2);
1115 if ((eb & ETG_POPUP) != 0)
1117 if (wd->img_popup->ok)
1119 if (data->dc->GadgetsThreeState) width += (wd->img_popup->w / 3); else width += (wd->img_popup->w >> 2);
1123 if (haszoom)
1125 if (data->dc->GadgetsThreeState) width += (wd->img_zoom->w / 3); else width += (wd->img_zoom->w >> 2);
1128 if (hasclose && data->dc->CloseGadgetOnRight)
1130 if (data->dc->GadgetsThreeState) width += (wd->img_close->w / 3); else width += (wd->img_close->w >> 2);
1133 if (hasdepth)
1135 if (data->dc->GadgetsThreeState) width += (wd->img_depth->w / 3); else width += (wd->img_depth->w >> 2);
1136 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1138 else
1140 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1143 gadget->Flags &= ~GFLG_RELWIDTH;
1144 gadget->Flags |= GFLG_RELRIGHT;
1147 break;
1149 case ETI_Iconify:
1150 if (wd->img_iconify->ok)
1152 if (data->dc->GadgetsThreeState) width = (wd->img_iconify->w / 3); else width = (wd->img_iconify->w >> 2);
1154 gadget->Width = width;
1155 gadget->TopEdge = (refheight - gadget->Height) / 2;
1157 if ((eb & ETG_MUI) != 0)
1159 if (wd->img_mui->ok)
1161 if (data->dc->GadgetsThreeState) width += (wd->img_mui->w / 3); else width += (wd->img_mui->w >> 2);
1165 if ((eb & ETG_POPUP) != 0)
1167 if (wd->img_popup->ok)
1169 if (data->dc->GadgetsThreeState) width += (wd->img_popup->w / 3); else width += (wd->img_popup->w >> 2);
1173 if ((eb & ETG_SNAPSHOT) != 0)
1175 if (wd->img_snapshot->ok)
1177 if (data->dc->GadgetsThreeState) width += (wd->img_snapshot->w / 3); else width += (wd->img_snapshot->w >> 2);
1181 if (haszoom)
1183 if (data->dc->GadgetsThreeState) width += (wd->img_zoom->w / 3); else width += (wd->img_zoom->w >> 2);
1186 if (hasclose && data->dc->CloseGadgetOnRight)
1188 if (data->dc->GadgetsThreeState) width += (wd->img_close->w / 3); else width += (wd->img_close->w >> 2);
1190 if (hasdepth)
1192 if (data->dc->GadgetsThreeState) width += (wd->img_depth->w / 3); else width += (wd->img_depth->w >> 2);
1193 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1195 else
1197 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1199 gadget->Flags &= ~GFLG_RELWIDTH;
1200 gadget->Flags |= GFLG_RELRIGHT;
1203 break;
1205 case ETI_Lock:
1206 if (wd->img_lock->ok)
1208 if (data->dc->GadgetsThreeState) width = (wd->img_lock->w / 3); else width = (wd->img_lock->w >> 2);
1210 gadget->Width = width;
1211 gadget->TopEdge = (refheight - gadget->Height) / 2;
1213 if ((eb & ETG_MUI) != 0)
1215 if (wd->img_mui->ok)
1217 if (data->dc->GadgetsThreeState) width += (wd->img_mui->w / 3); else width += (wd->img_mui->w >> 2);
1221 if ((eb & ETG_POPUP) != 0)
1223 if (wd->img_popup->ok)
1225 if (data->dc->GadgetsThreeState) width += (wd->img_popup->w / 3); else width += (wd->img_popup->w >> 2);
1229 if ((eb & ETG_SNAPSHOT) != 0)
1231 if (wd->img_snapshot->ok)
1233 if (data->dc->GadgetsThreeState) width += (wd->img_snapshot->w / 3); else width += (wd->img_snapshot->w >> 2);
1237 if ((eb & ETG_ICONIFY) != 0)
1239 if (wd->img_iconify->ok)
1241 if (data->dc->GadgetsThreeState) width += (wd->img_iconify->w / 3); else width += (wd->img_iconify->w >> 2);
1245 if (haszoom)
1247 if (data->dc->GadgetsThreeState) width += (wd->img_zoom->w / 3); else width += (wd->img_zoom->w >> 2);
1250 if (hasclose && data->dc->CloseGadgetOnRight)
1252 if (data->dc->GadgetsThreeState) width += (wd->img_close->w / 3); else width += (wd->img_close->w >> 2);
1254 if (hasdepth)
1256 if (data->dc->GadgetsThreeState) width += (wd->img_depth->w / 3); else width += (wd->img_depth->w >> 2);
1257 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1259 else
1261 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1263 gadget->Flags &= ~GFLG_RELWIDTH;
1264 gadget->Flags |= GFLG_RELRIGHT;
1267 break;
1271 else
1273 switch(gadget->GadgetType & GTYP_SYSTYPEMASK)
1275 case GTYP_CLOSE:
1276 if (data->dc->GadgetsThreeState) width = (wd->img_close->w / 3); else width = (wd->img_close->w >> 2);
1277 gadget->Width = width;
1278 wd->closewidth = width;
1279 if (data->dc->CloseGadgetOnRight)
1281 gadget->Flags &= ~GFLG_RELWIDTH;
1282 gadget->Flags |= GFLG_RELRIGHT;
1283 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1285 else
1287 gadget->LeftEdge = data->dc->BarPreGadget_s;
1289 gadget->TopEdge = (refheight - gadget->Height) / 2;
1290 break;
1292 case GTYP_WDEPTH:
1293 if (data->dc->GadgetsThreeState) width = (wd->img_depth->w / 3); else width = (wd->img_depth->w >> 2);
1294 gadget->Width = width;
1295 wd->depthwidth = width;
1296 if (hasclose && data->dc->CloseGadgetOnRight)
1298 if (data->dc->GadgetsThreeState) width += (wd->img_close->w / 3); else width += (wd->img_close->w >> 2);
1300 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1301 gadget->TopEdge = (refheight - gadget->Height) / 2;
1302 gadget->Flags &= ~GFLG_RELWIDTH;
1303 gadget->Flags |= GFLG_RELRIGHT;
1304 break;
1306 case GTYP_WZOOM:
1307 if (data->dc->GadgetsThreeState) width = (wd->img_zoom->w / 3); else width = (wd->img_zoom->w >> 2);
1308 gadget->Width = width;
1309 wd->zoomwidth = width;
1310 gadget->TopEdge = (refheight - gadget->Height) / 2;
1311 if (hasclose && data->dc->CloseGadgetOnRight)
1313 if (data->dc->GadgetsThreeState) width += (wd->img_close->w / 3); else width += (wd->img_close->w >> 2);
1315 if (hasdepth)
1317 if (data->dc->GadgetsThreeState) width += (wd->img_depth->w / 3); else width += (wd->img_depth->w >> 2);
1318 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1320 else
1322 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1324 gadget->Flags &= ~GFLG_RELWIDTH;
1325 gadget->Flags |= GFLG_RELRIGHT;
1327 break;
1329 case GTYP_WDRAGGING:
1330 break;
1334 return TRUE;
1337 int sysrgad = -data->dc->BarPostGadget_s - 1;
1339 if (data->dc->CloseGadgetOnRight && hasclose) sysrgad -= wd->closewidth;
1340 if (hasdepth) sysrgad -= wd->depthwidth;
1341 if (haszoom) sysrgad -= wd->zoomwidth;
1342 while(gadget)
1344 if ((gadget->GadgetType & GTYP_SYSTYPEMASK) == 0)
1346 switch(gadget->GadgetType & GTYP_SYSTYPEMASK)
1348 case GTYP_WDRAGGING:
1349 break;
1351 default:
1352 if ((gadget->Flags & GFLG_EXTENDED) != 0)
1354 if ((((struct ExtGadget *) gadget)->MoreFlags & GMORE_BOOPSIGADGET) != 0)
1356 IPTR rtsm = 0;
1357 GetAttr(GA_RightBorder, (Object *) gadget, &rtsm);
1358 if (rtsm)
1360 if (GetAttr(PGA_Top, (Object *) gadget, &rtsm))
1362 SetAttrs((Object *) gadget, GA_RelRight, - data->dc->RightBorderGadgets + ((data->dc->RightBorderGadgets - (wd->img_verticalcontainer->w >> 1) + 1) >> 1) + 1, GA_Width, wd->img_verticalcontainer->w >> 1, TAG_DONE);
1364 else
1366 GetAttr(GA_Width, (Object *) gadget, &rtsm);
1367 SetAttrs((Object *) gadget, GA_RelRight, - data->dc->RightBorderGadgets + ((data->dc->RightBorderGadgets - rtsm + 1) >> 1) + 1, TAG_DONE);
1370 else
1372 GetAttr(GA_BottomBorder, (Object *) gadget, &rtsm);
1373 if (rtsm)
1375 if (GetAttr(PGA_Top, (Object *) gadget, &rtsm))
1377 SetAttrs((Object *) gadget, GA_RelBottom, - data->dc->BottomBorderGadgets + ((data->dc->BottomBorderGadgets - (wd->img_horizontalcontainer->h >> 1) + 1) >> 1) +1, GA_Height, (wd->img_horizontalcontainer->h >> 1), TAG_DONE);
1379 else
1381 GetAttr(GA_Height, (Object *) gadget, &rtsm);
1382 SetAttrs((Object *) gadget, GA_RelBottom, - data->dc->BottomBorderGadgets + ((data->dc->BottomBorderGadgets - rtsm + 1) >> 1) + 1, TAG_DONE);
1388 break;
1391 if (msg->wdp_Flags & WDF_LBG_MULTIPLE)
1393 gadget = gadget->NextGadget;
1395 else
1397 gadget = NULL;
1400 gadget = msg->wdp_Gadgets;
1402 while(gadget)
1404 if ((gadget->GadgetType & GTYP_SYSTYPEMASK) == 0)
1406 if ((gadget->Activation & GACT_TOPBORDER) != 0)
1408 if ((gadget->Flags & GFLG_RELRIGHT) != 0)
1410 gadget->TopEdge = (refheight - gadget->Height) / 2;
1411 sysrgad -= gadget->Width;
1412 gadget->LeftEdge = sysrgad;
1416 gadget = gadget->NextGadget;
1419 gadget = msg->wdp_Gadgets;
1421 if ((msg->wdp_Flags & WDF_LBG_SYSTEMGADGET) != 0) while(gadget)
1423 switch(gadget->GadgetType & GTYP_SYSTYPEMASK)
1425 case GTYP_WDRAGGING:
1426 gadget->Width = sysrgad;
1427 if (hasclose && !data->dc->CloseGadgetOnRight)
1429 gadget->Width -= data->dc->BarPreGadget_s;
1430 if (data->dc->GadgetsThreeState) gadget->Width -= (wd->img_close->w / 3); else gadget->Width -= (wd->img_close->w >> 2);
1432 break;
1434 gadget = gadget->NextGadget;
1437 if (draggadget)
1441 return TRUE;
1444 /**************************************************************************************************/
1445 static IPTR windecor_draw_borderpropback(Class *cl, Object *obj, struct wdpDrawBorderPropBack *msg)
1447 /* Simply return, we need to render the back in the knob method */
1448 /* because we want to use irregular (alpha images) for the sliders */
1449 return TRUE;
1452 /**************************************************************************************************/
1453 static IPTR windecor_draw_borderpropknob(Class *cl, Object *obj, struct wdpDrawBorderPropKnob *msg)
1455 struct windecor_data *data = INST_DATA(cl, obj);
1456 struct Window *window = msg->wdp_Window;
1457 struct RastPort *winrp = msg->wdp_RPort;
1458 struct WindowData *wd = (struct WindowData *) msg->wdp_UserBuffer;
1460 struct RastPort *rp;
1461 struct Gadget *gadget = msg->wdp_Gadget;
1462 struct Rectangle *r;
1463 struct PropInfo *pi = ((struct PropInfo *)gadget->SpecialInfo);
1464 struct NewImage *ni = NULL;
1465 BOOL hit = (msg->wdp_Flags & WDF_DBPK_HIT) ? TRUE : FALSE;
1466 ULONG y, x, bx0, bx1, by0, by1;
1467 LONG size;
1468 ULONG s_col, e_col, arc;
1469 LONG pen = -1;
1470 struct BitMap *cachedgadgetbitmap = NULL;
1471 ULONG changetype = CHANGE_NO_CHANGE;
1472 ULONG subimage = 0;
1474 if (!(pi->Flags & PROPNEWLOOK) || (gadget->Activation && (GACT_RIGHTBORDER | GACT_BOTTOMBORDER) == 0))
1476 return DoSuperMethodA(cl, obj, (Msg)msg);
1479 /* Detect change in gadget dimensions (which needs to trigger redraw) */
1480 if ((pi->Flags & FREEVERT) != 0)
1482 changetype = HasPropGadgetChanged(&wd->vert, msg);
1484 if (changetype == CHANGE_SIZE_CHANGE)
1486 /* Free is there was size change */
1487 if (wd->vert.bm != NULL)
1488 FreeBitMap(wd->vert.bm);
1489 wd->vert.bm = NULL;
1491 cachedgadgetbitmap = wd->vert.bm;
1493 else if ((pi->Flags & FREEHORIZ) != 0)
1495 changetype = HasPropGadgetChanged(&wd->horiz, msg);
1497 if (changetype == CHANGE_SIZE_CHANGE)
1499 /* Free is there was size change */
1500 if (wd->horiz.bm != NULL)
1501 FreeBitMap(wd->horiz.bm);
1502 wd->horiz.bm = NULL;
1504 cachedgadgetbitmap = wd->horiz.bm;
1507 else
1508 return TRUE; /* Return TRUE - after all this is not an error */
1510 /* Reuse the bitmap if that is possible */
1511 if (changetype == CHANGE_NO_CHANGE)
1513 /* Final blitting of gadget bitmap to window rast port */
1514 BltBitMapRastPort(cachedgadgetbitmap, 0, 0, winrp, msg->wdp_PropRect->MinX,
1515 msg->wdp_PropRect->MinY,
1516 msg->wdp_PropRect->MaxX - msg->wdp_PropRect->MinX + 1,
1517 msg->wdp_PropRect->MaxY - msg->wdp_PropRect->MinY + 1, 0xc0);
1518 return TRUE;
1521 /* Regenerate the bitmap */
1522 r = msg->wdp_PropRect;
1524 bx0 = r->MinX;
1525 by0 = r->MinY;
1526 bx1 = r->MaxX;
1527 by1 = r->MaxY;
1529 rp = CreateRastPort();
1530 if (rp)
1532 /* Reuse the bitmap if there was no size change (ie. only move of knob) */
1533 if (changetype == CHANGE_NO_SIZE_CHANGE)
1534 rp->BitMap = cachedgadgetbitmap;
1535 else
1536 rp->BitMap = AllocBitMap(bx1 - bx0 + 1, by1 - by0 + 1, 1, 0, window->WScreen->RastPort.BitMap);
1538 if (rp->BitMap == NULL)
1540 FreeRastPort(rp);
1541 return FALSE;
1544 else
1545 return FALSE;
1547 if (wd->img_border_normal->ok) ni = wd->img_border_normal;
1549 if (ni == NULL) data->dc->UseGradients = TRUE;
1551 if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX))
1553 s_col = data->dc->ActivatedGradientColor_s;
1554 e_col = data->dc->ActivatedGradientColor_e;
1555 arc = data->dc->ActivatedGradientColor_a;
1556 pen = wd->ActivePen;
1558 else
1560 s_col = data->dc->DeactivatedGradientColor_s;
1561 e_col = data->dc->DeactivatedGradientColor_e;
1562 arc = data->dc->DeactivatedGradientColor_a;
1563 if (!data->dc->UseGradients)
1565 if (wd->img_border_deactivated->ok) ni = wd->img_border_deactivated;
1567 pen = wd->DeactivePen;
1570 /* Drawing background - this solves WDM_DRAW_BORDERPROPBACK without need of
1571 reading from window when drawing container and knob */
1572 if (data->dc->UseGradients)
1574 FillPixelArrayGradient(pen, wd->truecolor, rp, 0, 0, window->Width-1, window->Height-1, 0, 0, bx1 - bx0 + 1, by1 - by0 + 1, s_col, e_col, arc, bx0, by0);
1576 else
1578 if (ni->ok)
1580 ULONG color = 0x00cccccc;
1581 HorizVertRepeatNewImage(ni, color, bx0, by0, rp, 0, 0, bx1 - bx0 + 1, by1 - by0 + 1);
1585 /* Drawing knob container */
1586 r = msg->wdp_PropRect;
1588 bx0 = 0;
1589 by0 = 0;
1590 bx1 = r->MaxX - r->MinX;
1591 by1 = r->MaxY - r->MinY;
1593 if ((pi->Flags & FREEVERT) != 0)
1595 if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)) subimage = 0; else subimage = 1;
1596 y = by0;
1597 size = by1 - by0 - data->dc->ContainerTop_s - data->dc->ContainerBottom_s + 1;
1598 y = WriteTiledImageVertical(rp, wd->img_verticalcontainer, subimage, data->dc->ContainerTop_o, data->dc->ContainerTop_s, bx0, y, data->dc->ContainerTop_s);
1599 if (size > 0) y = WriteTiledImageVertical(rp, wd->img_verticalcontainer, subimage, data->dc->ContainerVertTile_o, data->dc->ContainerVertTile_s, bx0, y, size);
1601 y = WriteTiledImageVertical(rp, wd->img_verticalcontainer, subimage, data->dc->ContainerBottom_o, data->dc->ContainerBottom_s, bx0, y, data->dc->ContainerBottom_s);
1604 else if ((pi->Flags & FREEHORIZ) != 0)
1606 if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)) subimage = 0; else subimage = 1;
1607 x = bx0;
1608 size = bx1 - bx0 - data->dc->ContainerLeft_s - data->dc->ContainerRight_s + 1;
1609 x = WriteTiledImageHorizontal(rp, wd->img_horizontalcontainer, subimage, data->dc->ContainerLeft_o, data->dc->ContainerLeft_s, x, by0, data->dc->ContainerLeft_s);
1610 if (size > 0) x = WriteTiledImageHorizontal(rp, wd->img_horizontalcontainer, subimage, data->dc->ContainerHorTile_o, data->dc->ContainerHorTile_s, x, by0, size);
1611 x = WriteTiledImageHorizontal(rp, wd->img_horizontalcontainer, subimage, data->dc->ContainerRight_o, data->dc->ContainerRight_s, x, by0, data->dc->ContainerRight_s);
1615 /* Drawing knob */
1616 bx0 = msg->wdp_PropRect->MinX;
1617 by0 = msg->wdp_PropRect->MinY;
1618 bx1 = msg->wdp_PropRect->MaxX;
1619 by1 = msg->wdp_PropRect->MaxY;
1621 r = msg->wdp_RenderRect;
1622 if ((pi->Flags & FREEVERT) != 0)
1624 if (hit) subimage = 1; else if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)) subimage = 0; else subimage = 2;
1625 y = r->MinY - by0;
1626 size = r->MaxY - r->MinY - data->dc->KnobTop_s - data->dc->KnobBottom_s + 1;
1628 y = WriteTiledImageVertical(rp, wd->img_verticalknob, subimage, data->dc->KnobTop_o, data->dc->KnobTop_s, r->MinX - bx0, y, data->dc->KnobTop_s);
1629 if (size > 0)
1631 if (size > data->dc->KnobVertGripper_s)
1633 size = size - data->dc->KnobVertGripper_s;
1634 int size_bak = size;
1635 size = size / 2;
1636 if (size > 0) y = WriteTiledImageVertical(rp, wd->img_verticalknob, subimage, data->dc->KnobTileTop_o, data->dc->KnobTileTop_s, r->MinX - bx0, y, size);
1637 y = WriteTiledImageVertical(rp, wd->img_verticalknob, subimage, data->dc->KnobVertGripper_o, data->dc->KnobVertGripper_s, r->MinX - bx0, y, data->dc->KnobVertGripper_s);
1638 size = size_bak - size;
1639 if (size > 0) y = WriteTiledImageVertical(rp, wd->img_verticalknob, subimage, data->dc->KnobTileBottom_o, data->dc->KnobTileBottom_s, r->MinX - bx0, y, size);
1641 else
1643 y = WriteTiledImageVertical(rp, wd->img_verticalknob, subimage, data->dc->KnobTileTop_o, data->dc->KnobTileTop_s, r->MinX - bx0, y, size);
1646 y = WriteTiledImageVertical(rp, wd->img_verticalknob, subimage, data->dc->KnobBottom_o, data->dc->KnobBottom_s, r->MinX - bx0, y, data->dc->KnobBottom_s);
1648 else if ((pi->Flags & FREEHORIZ) != 0)
1650 if (hit) subimage = 1; else if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)) subimage = 0; else subimage = 2;
1651 x = r->MinX - bx0;
1652 size = r->MaxX - r->MinX - data->dc->KnobLeft_s - data->dc->KnobRight_s + 1;
1653 x = WriteTiledImageHorizontal(rp, wd->img_horizontalknob, subimage, data->dc->KnobLeft_o, data->dc->KnobLeft_s, x, r->MinY - by0, data->dc->KnobLeft_s);
1655 if (size > 0)
1657 if (size > data->dc->KnobHorGripper_s)
1659 size = size - data->dc->KnobHorGripper_s;
1660 int size_bak = size;
1661 size = size / 2;
1662 if (size > 0) x = WriteTiledImageHorizontal(rp, wd->img_horizontalknob, subimage, data->dc->KnobTileLeft_o, data->dc->KnobTileLeft_s, x, r->MinY - by0, size);
1663 x = WriteTiledImageHorizontal(rp, wd->img_horizontalknob, subimage, data->dc->KnobHorGripper_o, data->dc->KnobHorGripper_s, x, r->MinY - by0, data->dc->KnobHorGripper_s);
1664 size = size_bak - size;
1665 if (size > 0) x = WriteTiledImageHorizontal(rp, wd->img_horizontalknob, subimage, data->dc->KnobTileRight_o, data->dc->KnobTileRight_s, x, r->MinY - by0, size);
1667 else
1669 x = WriteTiledImageHorizontal(rp, wd->img_horizontalknob, subimage, data->dc->KnobTileRight_o, data->dc->KnobTileRight_s, x, r->MinY - by0, size);
1672 x = WriteTiledImageHorizontal(rp, wd->img_horizontalknob, subimage, data->dc->KnobRight_o, data->dc->KnobRight_s, x, r->MinY - by0, data->dc->KnobRight_s);
1675 /* Final blitting of gadget bitmap to window rast port */
1676 BltBitMapRastPort(rp->BitMap, 0, 0, winrp, msg->wdp_PropRect->MinX,
1677 msg->wdp_PropRect->MinY,
1678 msg->wdp_PropRect->MaxX - msg->wdp_PropRect->MinX + 1,
1679 msg->wdp_PropRect->MaxY - msg->wdp_PropRect->MinY + 1, 0xc0);
1681 /* Cache the actual bitmap */
1682 if ((pi->Flags & FREEVERT) != 0)
1683 CachePropGadget(&wd->vert, msg, rp->BitMap);
1684 else if ((pi->Flags & FREEHORIZ) != 0)
1685 CachePropGadget(&wd->horiz, msg, rp->BitMap);
1687 FreeRastPort(rp);
1689 return TRUE;
1692 /**************************************************************************************************/
1693 static IPTR windecor_getdefsizes(Class *cl, Object *obj, struct wdpGetDefSizeSysImage *msg)
1695 struct windecor_data *data = INST_DATA(cl, obj);
1696 struct NewImage *n = NULL;
1697 WORD w = 0, h = 0;
1698 BOOL isset = FALSE;
1699 BOOL titlegadget = FALSE;
1701 switch(msg->wdp_Which)
1703 case SIZEIMAGE:
1704 n = NULL;
1705 w = data->dc->RightBorderGadgets;
1706 h = data->dc->BottomBorderGadgets;
1707 isset = TRUE;
1708 break;
1710 case CLOSEIMAGE:
1711 n = data->img_close;
1712 if(n) isset = TRUE;
1713 titlegadget = TRUE;
1714 break;
1716 case MUIIMAGE:
1717 n = data->img_mui;
1718 if(n) isset = TRUE;
1719 titlegadget = TRUE;
1720 break;
1722 case POPUPIMAGE:
1723 n = data->img_popup;
1724 if(n) isset = TRUE;
1725 titlegadget = TRUE;
1726 break;
1728 case SNAPSHOTIMAGE:
1729 n = data->img_snapshot;
1730 if(n) isset = TRUE;
1731 titlegadget = TRUE;
1732 break;
1734 case ICONIFYIMAGE:
1735 n = data->img_iconify;
1736 if(n) isset = TRUE;
1737 titlegadget = TRUE;
1738 break;
1740 case LOCKIMAGE:
1741 n = data->img_lock;
1742 if(n) isset = TRUE;
1743 titlegadget = TRUE;
1744 break;
1746 case UPIMAGE:
1747 n = NULL;
1748 w = data->dc->RightBorderGadgets;
1749 h = data->img_up->h + data->dc->UpDownAddY;
1750 isset = TRUE;
1751 break;
1753 case DOWNIMAGE:
1754 n = NULL;
1755 w = data->dc->RightBorderGadgets;
1756 h = data->img_down->h + data->dc->UpDownAddY;
1757 isset = TRUE;
1758 break;
1760 case LEFTIMAGE:
1761 n = NULL;
1762 if (data->dc->GadgetsThreeState) w = (data->img_left->w / 3); else w = (data->img_left->w >> 2);
1763 w += data->dc->LeftRightAddX;
1764 h = data->dc->BottomBorderGadgets;
1765 isset = TRUE;
1766 break;
1768 case RIGHTIMAGE:
1769 n = NULL;
1770 if (data->dc->GadgetsThreeState) w = (data->img_right->w / 3); else w = (data->img_right->w >> 2);
1771 w += data->dc->LeftRightAddX;
1772 h = data->dc->BottomBorderGadgets;
1773 isset = TRUE;
1774 break;
1776 case DEPTHIMAGE:
1777 n = data->img_depth;
1778 if(n) isset = TRUE;
1779 titlegadget = TRUE;
1780 break;
1782 case ZOOMIMAGE:
1783 n = data->img_zoom;
1784 if(n) isset = TRUE;
1785 titlegadget = TRUE;
1786 break;
1788 default:
1789 return FALSE;
1792 if (!isset) return DoSuperMethodA(cl, obj, (Msg) msg);
1794 if (n == NULL)
1796 *msg->wdp_Width = w;
1797 *msg->wdp_Height = h;
1799 else
1801 if (n->ok)
1803 if (data->dc->GadgetsThreeState)
1805 *msg->wdp_Width = (n->w / 3);
1806 *msg->wdp_Height = n->h;
1808 else
1810 *msg->wdp_Width = (n->w >> 2);
1811 *msg->wdp_Height = n->h;
1814 if(titlegadget && (msg->wdp_ReferenceFont->tf_YSize + 2 > data->dc->BarHeight))
1816 /* Scale height so that the gadget is not proportionally resized (so that width does not change) */
1817 *msg->wdp_Height *= msg->wdp_ReferenceFont->tf_YSize + 2;
1818 *msg->wdp_Height /= data->dc->BarHeight;
1820 } else return DoSuperMethodA(cl, obj, (Msg) msg);
1823 return TRUE;
1826 /**************************************************************************************************/
1827 static IPTR windecor_windowshape(Class *cl, Object *obj, struct wdpWindowShape *msg)
1829 struct windecor_data *data = INST_DATA(cl, obj);
1830 struct WindowData *wd = (struct WindowData *) msg->wdp_UserBuffer;
1831 struct Window *window = msg->wdp_Window;
1833 if (data->dc->BarMasking)
1835 if (HasTitleBarShapeChanged(&wd->tbarshape, window) != CHANGE_NO_CHANGE)
1837 struct NewLUT8ImageContainer *shape;
1838 struct Region * newreg = NULL;
1840 if (wd->tbarshape.shape != NULL)
1842 DisposeRegion(wd->tbarshape.shape);
1843 wd->tbarshape.shape = NULL;
1846 shape = (struct NewLUT8ImageContainer *)NewLUT8ImageContainer(window->Width, window->BorderTop);
1847 if (shape)
1849 if (window->BorderTop > 0) DrawShapePartialTitleBar(wd, (struct NewLUT8Image *)shape, data, window);
1851 newreg = RegionFromLUT8Image(msg->wdp_Width, msg->wdp_Height, (struct NewLUT8Image *)shape);
1852 DisposeLUT8ImageContainer((struct NewLUT8Image *)shape);
1854 CacheTitleBarShape(&wd->tbarshape, window, newreg);
1858 /* Make a copy of region and return it */
1859 return (IPTR)CopyRegion(wd->tbarshape.shape);
1863 if (!data->dc->BarRounded) return (IPTR) NULL;
1865 struct Region *newshape;
1867 int x2 = msg->wdp_Width-1;
1868 int y2 = msg->wdp_Height-1;
1870 if ((newshape = NewRegion()))
1872 struct Rectangle rect;
1873 BOOL success = TRUE;
1875 rect.MinX = 9;
1876 rect.MinY = 0;
1877 rect.MaxX = x2 - 9;
1878 rect.MaxY = y2;
1879 success &= OrRectRegion(newshape, &rect);
1881 rect.MinX = 6;
1882 rect.MinY = 1;
1883 rect.MaxX = x2 - 6;
1884 rect.MaxY = y2;
1885 success &= OrRectRegion(newshape, &rect);
1887 rect.MinX = 4;
1888 rect.MinY = 2;
1889 rect.MaxX = x2 - 4;
1890 rect.MaxY = y2;
1891 success &= OrRectRegion(newshape, &rect);
1893 rect.MinX = 3;
1894 rect.MinY = 3;
1895 rect.MaxX = x2 - 3;
1896 rect.MaxY = y2;
1897 success &= OrRectRegion(newshape, &rect);
1899 rect.MinX = 2;
1900 rect.MinY = 4;
1901 rect.MaxX = x2 - 2;
1902 rect.MaxY = y2;
1903 success &= OrRectRegion(newshape, &rect);
1905 rect.MinX = 1;
1906 rect.MinY = 6;
1907 rect.MaxX = x2 - 1;
1908 rect.MaxY = y2;
1909 success &= OrRectRegion(newshape, &rect);
1911 rect.MinX = 0;
1912 rect.MinY = 9;
1913 rect.MaxX = x2;
1914 rect.MaxY = y2;
1915 success &= OrRectRegion(newshape, &rect);
1917 return (IPTR) newshape;
1920 /**************************************************************************************************/
1921 static IPTR windecor_initwindow(Class *cl, Object *obj, struct wdpInitWindow *msg)
1923 struct WindowData *wd = (struct WindowData *)msg->wdp_UserBuffer;
1924 struct ScreenData *sd = (struct ScreenData *)msg->wdp_ScreenUserBuffer;
1926 wd->truecolor = msg->wdp_TrueColor;
1928 wd->ActivePen = sd->ActivePen;
1929 wd->DeactivePen = sd->DeactivePen;
1931 wd->vert.bm = NULL;
1932 wd->horiz.bm = NULL;
1934 SETIMAGE_WIN(size);
1935 SETIMAGE_WIN(close);
1936 SETIMAGE_WIN(depth);
1937 SETIMAGE_WIN(zoom);
1938 SETIMAGE_WIN(up);
1939 SETIMAGE_WIN(down);
1940 SETIMAGE_WIN(left);
1941 SETIMAGE_WIN(right);
1942 SETIMAGE_WIN(mui);
1943 SETIMAGE_WIN(popup);
1944 SETIMAGE_WIN(snapshot);
1945 SETIMAGE_WIN(iconify);
1946 SETIMAGE_WIN(lock);
1947 SETIMAGE_WIN(winbar_normal);
1948 SETIMAGE_WIN(border_normal);
1949 SETIMAGE_WIN(border_deactivated);
1950 SETIMAGE_WIN(verticalcontainer);
1951 SETIMAGE_WIN(verticalknob);
1952 SETIMAGE_WIN(horizontalcontainer);
1953 SETIMAGE_WIN(horizontalknob);
1955 return TRUE;
1958 /**************************************************************************************************/
1959 static IPTR windecor_exitwindow(Class *cl, Object *obj, struct wdpExitWindow *msg)
1961 struct WindowData *wd = (struct WindowData *) msg->wdp_UserBuffer;
1963 if (wd->vert.bm) FreeBitMap(wd->vert.bm);
1964 if (wd->horiz.bm) FreeBitMap(wd->horiz.bm);
1965 if (wd->tbar.bm) FreeBitMap(wd->tbar.bm);
1966 if (wd->tbarshape.shape) DisposeRegion(wd->tbarshape.shape);
1967 if (wd->tbar.title) FreeVec(wd->tbar.title);
1969 return TRUE;
1972 /**************************************************************************************************/
1973 static IPTR windecor_dispatcher(struct IClass *cl, Object *obj, Msg msg)
1975 IPTR retval;
1977 switch(msg->MethodID)
1979 case OM_NEW:
1980 retval = windecor_new(cl, obj, (struct opSet *)msg);
1981 break;
1983 case OM_DISPOSE:
1984 retval = windecor_dispose(cl, obj, (struct opSet *)msg);
1985 break;
1987 case OM_GET:
1988 retval = windecor_get(cl, obj, (struct opGet *)msg);
1989 break;
1991 case WDM_DRAW_SYSIMAGE:
1992 retval = windecor_draw_sysimage(cl, obj, (struct wdpDrawSysImage *)msg);
1993 break;
1995 case WDM_DRAW_WINBORDER:
1996 retval = windecor_draw_winborder(cl, obj, (struct wdpDrawWinBorder *)msg);
1997 break;
1999 case WDM_LAYOUT_BORDERGADGETS:
2000 retval = windecor_layout_bordergadgets(cl, obj, (struct wdpLayoutBorderGadgets *)msg);
2001 break;
2003 case WDM_DRAW_BORDERPROPBACK:
2004 retval = windecor_draw_borderpropback(cl, obj, (struct wdpDrawBorderPropBack *)msg);
2005 break;
2007 case WDM_DRAW_BORDERPROPKNOB:
2008 retval = windecor_draw_borderpropknob(cl, obj, (struct wdpDrawBorderPropKnob *)msg);
2009 break;
2011 case WDM_GETDEFSIZE_SYSIMAGE:
2012 retval = windecor_getdefsizes(cl, obj, (struct wdpGetDefSizeSysImage *) msg);
2013 break;
2015 case WDM_WINDOWSHAPE:
2016 retval = windecor_windowshape(cl, obj, (struct wdpWindowShape *) msg);
2017 break;
2019 case WDM_INITWINDOW:
2020 retval = windecor_initwindow(cl, obj, (struct wdpInitWindow *) msg);
2021 break;
2023 case WDM_EXITWINDOW:
2024 retval = windecor_exitwindow(cl, obj, (struct wdpExitWindow *) msg);
2025 break;
2027 default:
2028 retval = DoSuperMethodA(cl, obj, msg);
2029 break;
2032 return retval;
2035 struct IClass * MakeWindowDecorClass()
2037 struct IClass * cl = MakeClass(NULL, WINDECORCLASS, NULL, sizeof(struct windecor_data), 0);
2038 if (cl)
2040 cl->cl_Dispatcher.h_Entry = HookEntry;
2041 cl->cl_Dispatcher.h_SubEntry = (HOOKFUNC)windecor_dispatcher;
2044 return cl;