update experimental gcc 6 patch to gcc 6.1.0 release
[AROS.git] / workbench / c / Decoration / windowdecorclass.c
blobc84c96fe72773b6d1bea549d46b21ffcd3758f47
1 /*
2 Copyright © 2011-2012, The AROS Development Team.
3 $Id$
4 */
6 #define DEBUG 0
7 #include <aros/debug.h>
9 #include <clib/alib_protos.h>
11 #include <intuition/windecorclass.h>
12 #include <intuition/extensions.h>
13 #include <intuition/gadgetclass.h>
14 #include <graphics/rpattr.h>
15 #include <proto/arossupport.h>
16 #include <proto/intuition.h>
17 #include <proto/utility.h>
18 #include <proto/graphics.h>
19 #include <proto/cybergraphics.h>
20 #include <proto/exec.h>
21 #include <string.h>
23 #include "windowdecorclass.h"
24 #include "screendecorclass.h"
25 #include "drawfuncs.h"
26 #include "config.h"
28 #define SETIMAGE_WIN(id) wd->img_##id=sd->di->img_##id
30 struct windecor_data
32 struct DecorConfig * dc;
34 /* Pointers to images used for sys images */
35 struct NewImage *img_close;
36 struct NewImage *img_depth;
37 struct NewImage *img_zoom;
38 struct NewImage *img_up;
39 struct NewImage *img_down;
40 struct NewImage *img_left;
41 struct NewImage *img_right;
42 struct NewImage *img_mui;
43 struct NewImage *img_popup;
44 struct NewImage *img_snapshot;
45 struct NewImage *img_iconify;
46 struct NewImage *img_lock;
48 UWORD TextAlign;
51 #define CHANGE_NO_CHANGE 0
52 #define CHANGE_SIZE_CHANGE 1 /* Whole gadget area has changed */
53 #define CHANGE_NO_SIZE_CHANGE 2 /* Size remained the same, contents has changed */
55 static ULONG HasPropGadgetChanged(struct CachedPropGadget *cached, struct wdpDrawBorderPropKnob *msg)
57 /* More restrictive tests */
59 /* If the size has changed */
60 if (cached->width != (msg->wdp_PropRect->MaxX - msg->wdp_PropRect->MinX + 1))
61 return CHANGE_SIZE_CHANGE;
62 if (cached->height != (msg->wdp_PropRect->MaxY - msg->wdp_PropRect->MinY + 1))
63 return CHANGE_SIZE_CHANGE;
65 /* If there is no cached bitmap at all (this can happen NOT only at first call) */
66 if (cached->bm == NULL)
67 return CHANGE_SIZE_CHANGE;
69 /* Less restrictive tests */
71 /* If knob position has changed */
72 if (cached->knobx != (msg->wdp_RenderRect->MinX - msg->wdp_PropRect->MinX))
73 return CHANGE_NO_SIZE_CHANGE;
74 if (cached->knoby != (msg->wdp_RenderRect->MinY - msg->wdp_PropRect->MinY))
75 return CHANGE_NO_SIZE_CHANGE;
77 /* If knob is release state has changed */
78 if (cached->gadgetflags ^ (msg->wdp_Flags & WDF_DBPK_HIT))
79 return CHANGE_NO_SIZE_CHANGE;
81 /* If the window activity status has changed */
82 if (cached->windowflags ^ (msg->wdp_Window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)))
83 return CHANGE_NO_SIZE_CHANGE;
85 /* If knob size has changed */
86 if (cached->knobwidth != (msg->wdp_RenderRect->MaxX - msg->wdp_RenderRect->MinX + 1))
87 return CHANGE_NO_SIZE_CHANGE;
88 if (cached->knobheight != (msg->wdp_RenderRect->MaxY - msg->wdp_RenderRect->MinY + 1))
89 return CHANGE_NO_SIZE_CHANGE;
91 return CHANGE_NO_CHANGE;
94 static VOID CachePropGadget(struct CachedPropGadget *cached, struct wdpDrawBorderPropKnob *msg,
95 struct BitMap *bitmap)
97 cached->bm = bitmap;
98 cached->width = msg->wdp_PropRect->MaxX - msg->wdp_PropRect->MinX + 1;
99 cached->height = msg->wdp_PropRect->MaxY - msg->wdp_PropRect->MinY + 1;
100 cached->windowflags= (msg->wdp_Window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX));
101 cached->gadgetflags= (msg->wdp_Flags & WDF_DBPK_HIT);
102 cached->knobwidth = msg->wdp_RenderRect->MaxX - msg->wdp_RenderRect->MinX + 1;
103 cached->knobheight = msg->wdp_RenderRect->MaxY - msg->wdp_RenderRect->MinY + 1;
104 cached->knobx = msg->wdp_RenderRect->MinX - msg->wdp_PropRect->MinX;
105 cached->knoby = msg->wdp_RenderRect->MinY - msg->wdp_PropRect->MinY;
108 static ULONG HasTitleBarChanged(struct CachedTitleBar *cached, struct Window *window)
110 ULONG len = 0;
112 /* More restrictive tests */
114 /* If the window size has changed */
115 if (cached->width != window->Width)
116 return CHANGE_SIZE_CHANGE;
117 if (cached->height != window->Height)
118 return CHANGE_SIZE_CHANGE;
120 /* If there is no cached bitmap at all (this can happen NOT only at first call) */
121 if (cached->bm == NULL)
122 return CHANGE_SIZE_CHANGE;
124 /* Less restrictive tests */
126 /* If the window activity status has changed */
127 if (cached->windowflags ^ (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)))
128 return CHANGE_NO_SIZE_CHANGE;
130 /* If the window title/title contents has changed */
131 if (window->Title)
132 len = strlen(window->Title);
134 if (cached->titlelen != len)
135 return CHANGE_NO_SIZE_CHANGE;
137 if (cached->title)
139 /* At this point:
140 - length of both buffer is guarateed to be the same, see previous test
141 - both buffers are allocated
143 ULONG i;
144 for (i = 0; i < len; i++)
145 if (cached->title[i] != window->Title[i])
146 return CHANGE_NO_SIZE_CHANGE;
149 return CHANGE_NO_CHANGE;
152 static VOID CacheTitleBar(struct CachedTitleBar *cached, struct Window *window, struct BitMap *bitmap)
154 ULONG len = 0;
156 cached->bm = bitmap;
157 cached->width = window->Width;
158 cached->height = window->Height;
159 cached->windowflags = (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX));
161 /* Cache the title */
162 if (window->Title)
163 len = strlen(window->Title);
165 if (cached->titlelen != len)
167 if (cached->title)
168 FreeVec(cached->title);
169 cached->title = AllocVec(len + 1, MEMF_ANY | MEMF_CLEAR);
171 cached->titlelen = len;
172 strncpy(cached->title, window->Title, len);
175 static ULONG HasTitleBarShapeChanged(struct CachedTitleBarShape *cached, struct Window *window)
177 /* More restrictive tests */
179 /* If the window size has changed */
180 if (cached->width != window->Width)
181 return CHANGE_SIZE_CHANGE;
182 if (cached->height != window->Height)
183 return CHANGE_SIZE_CHANGE;
185 /* If there is no cached shape at all (this can happen NOT only at first call) */
186 if (cached->shape == NULL)
187 return CHANGE_SIZE_CHANGE;
189 /* Less restrictive tests */
191 /* If the window activity status has changed */
192 if (cached->windowflags ^ (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)))
193 return CHANGE_NO_SIZE_CHANGE;
195 return CHANGE_NO_CHANGE;
198 static VOID CacheTitleBarShape(struct CachedTitleBarShape *cached, struct Window *window, struct Region *shape)
200 cached->shape = shape;
201 cached->width = window->Width;
202 cached->height = window->Height;
203 cached->windowflags = (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX));
206 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)
208 int w = dw;
209 int x = xp;
210 int ddw;
212 if (!ni->ok) return xp;
214 if ((sw == 0) || (dw == 0)) return xp;
216 if (win)
218 if (x > win->Width) return xp;
219 if ((x + w) > win->Width) w = win->Width - x;
222 while (w > 0)
224 ddw = sw;
225 if (w < ddw) ddw = w;
226 WriteAlphaPixelArray(ni, lut8, sx, sy, x, yp, ddw, dh);
227 w -= ddw;
228 x += ddw;
230 return x;
233 static void getrightgadgetsdimensions(struct windecor_data *data, struct Window *win, LONG *xs, LONG *xe)
235 struct Gadget *g;
237 LONG x0 = 1000000;
238 LONG x1 = 0;
239 UWORD type;
241 for (g = win->FirstGadget; g; g = g->NextGadget)
243 if ((g->Flags & GFLG_RELRIGHT) == GFLG_RELRIGHT)
245 type = g->GadgetType & GTYP_SYSTYPEMASK;
246 if (data->dc->CloseGadgetOnRight)
248 if (((type & (GTYP_CLOSE | GTYP_WDEPTH | GTYP_WZOOM)) != 0) || (g->Activation & GACT_TOPBORDER))
250 if (g->Width > 0)
252 if ((win->Width + g->LeftEdge) < x0) x0 = win->Width + g->LeftEdge;
253 if ((win->Width + g->LeftEdge + g->Width) > x1) x1 = win->Width + g->LeftEdge + g->Width;
257 else
259 if (((type & (GTYP_WDEPTH | GTYP_WZOOM)) != 0) || (g->Activation & GACT_TOPBORDER))
261 if (g->Width > 0)
263 if ((win->Width + g->LeftEdge) < x0) x0 = win->Width + g->LeftEdge;
264 if ((win->Width + g->LeftEdge + g->Width) > x1) x1 = win->Width + g->LeftEdge + g->Width;
270 if (x0 == 1000000) x0 = 0;
271 *xs = x0;
272 *xe = x1;
275 static void getleftgadgetsdimensions(struct windecor_data *data, struct Window *win, LONG *xs, LONG *xe)
277 struct Gadget *g;
279 LONG w = 0;
280 LONG x0 = 1000000;
281 LONG x1 = 0;
282 for (g = win->FirstGadget; g; g = g->NextGadget)
284 w++;
285 if (((g->Flags & GFLG_RELRIGHT) == 0) && (g->Activation & GACT_TOPBORDER))
287 if ((g->GadgetType & GTYP_WDRAGGING) == 0)
289 if (g->Width > 0)
291 if (g->LeftEdge < x0) x0 = g->LeftEdge;
292 if ((g->LeftEdge + g->Width) > x1) x1 = g->LeftEdge + g->Width;
297 if (x0 == 1000000) x0 = 0;
298 *xs = x0;
299 *xe = x1;
302 static void DrawShapePartialTitleBar(struct WindowData *wd, struct NewLUT8Image *shape, struct windecor_data *data, struct Window *window)
304 LONG xl0, xl1, xr0, xr1, defwidth;
305 ULONG textlen = 0, titlelen = 0, textpixellen = 0;
306 struct TextExtent te;
308 BOOL hastitle;
309 BOOL hastitlebar;
310 LONG dy;
312 struct RastPort *rp = &window->WScreen->RastPort;
313 hastitle = window->Title != NULL ? TRUE : FALSE;
314 hastitlebar = (window->BorderTop > 0) ? TRUE : FALSE;
316 getleftgadgetsdimensions(data, window, &xl0, &xl1);
317 getrightgadgetsdimensions(data, window, &xr0, &xr1);
319 defwidth = (xl0 != xl1) ? data->dc->BarPreGadget_s : data->dc->BarPre_s;
320 if(xr1 == 0)
322 xr1 = window->Width - data->dc->BarPre_s;
323 xr0 = window->Width - data->dc->BarPre_s;
326 defwidth += (xl1 - xl0);
328 defwidth += data->dc->BarJoinGB_s;
329 defwidth += data->dc->BarJoinBT_s;
330 defwidth += data->dc->BarJoinTB_s;
331 defwidth += data->dc->BarJoinBG_s;
332 defwidth += (xr1 - xr0);
333 defwidth += (xr0 != xr1) ? data->dc->BarPostGadget_s : data->dc->BarPost_s;
335 if (defwidth >= window->Width) hastitle = FALSE;
337 if (hastitle)
339 titlelen = strlen(window->Title);
340 textlen = TextFit(rp, window->Title, titlelen, &te, NULL, 1, window->Width-defwidth, window->BorderTop - 2);
341 if (textlen)
343 textpixellen = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
348 if (wd->img_winbar_normal->ok && hastitlebar)
350 UWORD x = 0;
351 UWORD barh = window->BorderTop;
352 struct NewImage * img_winbar_normal = wd->img_winbar_normal;
354 if (data->dc->BarHeight != barh)
355 img_winbar_normal = ScaleNewImage(wd->img_winbar_normal, wd->img_winbar_normal->w, 2 * barh);
357 if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX))
358 dy = 0;
359 else
360 dy = barh; /* Offset into source image */
362 if (xl0 != xl1)
364 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);
365 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);
367 else
369 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);
371 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);
372 if (hastitle && (textlen > 0))
374 switch(data->TextAlign)
376 case WD_DWTA_CENTER:
377 //BarLFill
378 x = WriteTiledImageShape(data->dc->FillTitleBar, window, shape, img_winbar_normal, data->dc->BarLFill_o, dy, data->dc->BarLFill_s, barh, x, 0, 60, barh);
379 break;
380 case WD_DWTA_RIGHT:
381 //BarLFill
382 break;
383 default:
384 case WD_DWTA_LEFT:
385 break;
387 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);
388 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);
389 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);
391 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);
392 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);
393 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);
394 if (xr0 != xr1)
396 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);
398 else
400 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);
403 if (data->dc->BarHeight != barh)
404 DisposeImageContainer(img_winbar_normal);
408 static VOID DrawPartialTitleBar(struct WindowData *wd, struct windecor_data *data, struct Window *window, struct RastPort *dst_rp, struct DrawInfo *dri, UWORD *pens)
410 LONG xl0, xl1, xr0, xr1, defwidth;
411 ULONG textlen = 0, titlelen = 0, textpixellen = 0;
412 struct TextExtent te;
413 struct RastPort *rp;
414 struct NewImage *ni = NULL;
416 BOOL hastitle;
417 BOOL hastitlebar;
418 UWORD textstart = 0;
419 ULONG color, s_col, e_col, arc;
420 LONG dy;
421 LONG pen = -1;
422 ULONG changetype = CHANGE_NO_CHANGE;
423 struct BitMap *cachedtitlebarbitmap = NULL;
425 changetype = HasTitleBarChanged(&wd->tbar, window);
426 if (changetype == CHANGE_SIZE_CHANGE)
428 if (wd->tbar.bm)
429 FreeBitMap(wd->tbar.bm);
430 wd->tbar.bm = NULL;
432 cachedtitlebarbitmap = wd->tbar.bm;
434 if (changetype == CHANGE_NO_CHANGE)
436 BltBitMapRastPort(cachedtitlebarbitmap, 0, 0, dst_rp, 0, 0, window->Width, window->BorderTop, 0xc0);
437 return;
440 /* Regenerate the bitmap */
441 rp = CreateRastPort();
442 if (rp)
444 /* Reuse the bitmap if there was no size change (ie. only change of state) */
445 if (changetype == CHANGE_NO_SIZE_CHANGE)
446 rp->BitMap = cachedtitlebarbitmap;
447 else
448 rp->BitMap = AllocBitMap(window->Width, window->BorderTop, 1, 0, window->WScreen->RastPort.BitMap);
450 if (rp->BitMap == NULL)
452 FreeRastPort(rp);
453 return;
456 SetFont(rp, dri->dri_Font);
458 else
459 return;
461 hastitle = window->Title != NULL ? TRUE : FALSE;
462 hastitlebar = (window->BorderTop > 0) ? TRUE : FALSE;
464 if (wd->img_border_normal->ok) ni = wd->img_border_normal;
466 if (ni == NULL) data->dc->UseGradients = TRUE;
468 color = 0x00cccccc;
470 if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX))
472 s_col = data->dc->ActivatedGradientColor_s;
473 e_col = data->dc->ActivatedGradientColor_e;
474 arc = data->dc->ActivatedGradientColor_a;
475 dy = 0;
476 pen = wd->ActivePen;
477 } else {
478 s_col = data->dc->DeactivatedGradientColor_s;
479 e_col = data->dc->DeactivatedGradientColor_e;
480 arc = data->dc->DeactivatedGradientColor_a;
481 dy = data->dc->BarHeight;
482 if (!data->dc->UseGradients)
484 if (wd->img_border_deactivated->ok) ni = wd->img_border_deactivated;
486 pen = wd->DeactivePen;
490 if (data->dc->FillTitleBar)
492 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);
493 else HorizVertRepeatNewImage(ni, color, 0, 0, rp, 0, 0, window->Width, window->BorderTop);
496 getleftgadgetsdimensions(data, window, &xl0, &xl1);
497 getrightgadgetsdimensions(data, window, &xr0, &xr1);
498 defwidth = (xl0 != xl1) ? data->dc->BarPreGadget_s : data->dc->BarPre_s;
499 if(xr1 == 0)
501 xr1 = window->Width - data->dc->BarPre_s;
502 xr0 = window->Width - data->dc->BarPre_s;
505 defwidth += (xl1 - xl0);
507 defwidth += data->dc->BarJoinGB_s;
508 defwidth += data->dc->BarJoinBT_s;
509 defwidth += data->dc->BarJoinTB_s;
510 defwidth += data->dc->BarJoinBG_s;
511 defwidth += (xr1 - xr0);
512 defwidth += (xr0 != xr1) ? data->dc->BarPostGadget_s : data->dc->BarPost_s;
514 if (defwidth >= window->Width) hastitle = FALSE;
516 if (hastitle)
518 titlelen = strlen(window->Title);
519 textlen = TextFit(rp, window->Title, titlelen, &te, NULL, 1, window->Width-defwidth, window->BorderTop - 2);
520 if (textlen)
522 textpixellen = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
526 if (wd->img_winbar_normal->ok && hastitlebar)
528 UWORD x = 0;
529 UWORD barh = window->BorderTop;
530 struct NewImage * img_winbar_normal = wd->img_winbar_normal;
532 if (data->dc->BarHeight != barh)
533 img_winbar_normal = ScaleNewImage(wd->img_winbar_normal, wd->img_winbar_normal->w, 2 * barh);
535 if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX))
536 dy = 0;
537 else
538 dy = barh; /* Offset into source image */
540 if (xl0 != xl1)
542 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);
543 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);
545 else
547 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);
549 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);
550 if (hastitle && (textlen > 0))
552 switch(data->TextAlign)
554 case WD_DWTA_CENTER:
555 //BarLFill
556 x = WriteTiledImageTitle(data->dc->FillTitleBar, window, rp, img_winbar_normal, data->dc->BarLFill_o, dy, data->dc->BarLFill_s, barh, x, 0, 60, barh);
557 break;
558 case WD_DWTA_RIGHT:
559 //BarLFill
560 break;
561 default:
562 case WD_DWTA_LEFT:
563 break;
565 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);
566 textstart = x;
567 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);
568 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);
570 /* Part right to window title */
571 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);
572 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);
573 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);
574 if (xr0 != xr1)
576 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);
578 else
580 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);
583 if (data->dc->BarHeight != barh)
584 DisposeImageContainer(img_winbar_normal);
587 if ((textlen > 0) && hastitle)
589 SetAPen(rp, pens[(window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)) ? FILLTEXTPEN : TEXTPEN]);
590 SetDrMd(rp, JAM1);
591 UWORD tx = textstart;
592 UWORD tymax = window->BorderTop - (dri->dri_Font->tf_YSize - dri->dri_Font->tf_Baseline) - 1;
593 UWORD ty = (window->BorderTop + dri->dri_Font->tf_Baseline - 1) >> 1;
594 if (ty > tymax) ty = tymax;
596 if (!wd->truecolor || ((data->dc->TitleOutline == FALSE) && (data->dc->TitleShadow == FALSE)))
598 Move(rp, tx, ty);
599 Text(rp, window->Title, textlen);
601 else if (data->dc->TitleOutline)
604 SetSoftStyle(rp, FSF_BOLD, AskSoftStyle(rp));
605 SetRPAttrs(rp, RPTAG_PenMode, FALSE, RPTAG_FgColor, data->dc->TitleColorShadow, TAG_DONE);
607 Move(rp, tx + 1, ty ); Text(rp, window->Title, textlen);
608 Move(rp, tx + 2, ty ); Text(rp, window->Title, textlen);
609 Move(rp, tx , ty ); Text(rp, window->Title, textlen);
610 Move(rp, tx, ty + 1); Text(rp, window->Title, textlen);
611 Move(rp, tx, ty + 2); Text(rp, window->Title, textlen);
612 Move(rp, tx + 1, ty + 2); Text(rp, window->Title, textlen);
613 Move(rp, tx + 2, ty + 1); Text(rp, window->Title, textlen);
614 Move(rp, tx + 2, ty + 2); Text(rp, window->Title, textlen);
616 SetRPAttrs(rp, RPTAG_PenMode, FALSE, RPTAG_FgColor, data->dc->TitleColorText, TAG_DONE);
617 Move(rp, tx + 1, ty + 1);
618 Text(rp, window->Title, textlen);
619 SetSoftStyle(rp, FS_NORMAL, AskSoftStyle(rp));
621 else
623 SetRPAttrs(rp, RPTAG_PenMode, FALSE, RPTAG_FgColor, data->dc->TitleColorShadow, TAG_DONE);
624 Move(rp, tx + 1, ty + 1 );
625 Text(rp, window->Title, textlen);
627 SetRPAttrs(rp, RPTAG_PenMode, FALSE, RPTAG_FgColor, data->dc->TitleColorText, TAG_DONE);
628 Move(rp, tx, ty);
629 Text(rp, window->Title, textlen);
634 BltBitMapRastPort(rp->BitMap, 0, 0, dst_rp, 0, 0, window->Width, window->BorderTop, 0xc0);
636 /* Cache the actual bitmap */
637 CacheTitleBar(&wd->tbar, window, rp->BitMap);
639 FreeRastPort(rp);
642 static VOID DisposeWindowSkinning(struct windecor_data *data)
647 static BOOL InitWindowSkinning(struct windecor_data *data, struct DecorImages * di, struct DecorConfig * dc)
649 if ((!di) || (!dc))
650 return FALSE;
652 data->dc = dc;
654 data->TextAlign = WD_DWTA_LEFT;
656 /* Set pointers to gadget images, used only to get gadget sizes as they
657 are requested prior to creation of menu object */
658 data->img_close = di->img_close;
659 data->img_depth = di->img_depth;
660 data->img_zoom = di->img_zoom;
661 data->img_up = di->img_up;
662 data->img_down = di->img_down;
663 data->img_left = di->img_left;
664 data->img_right = di->img_right;
665 data->img_mui = di->img_mui;
666 data->img_popup = di->img_popup;
667 data->img_snapshot = di->img_snapshot;
668 data->img_iconify = di->img_iconify;
669 data->img_lock = di->img_lock;
671 if (data->img_close && data->img_depth && data->img_zoom && data->img_up &&
672 data->img_down && data->img_left && data->img_right)
673 return TRUE;
675 DisposeWindowSkinning(data);
676 return FALSE;
679 /**************************************************************************************************/
680 static IPTR windecor_new(Class *cl, Object *obj, struct opSet *msg)
682 struct windecor_data *data;
684 D(bug("windecor_new(tags @ 0x%p)\n", msg->ops_AttrList));
686 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
687 if (obj)
689 data = INST_DATA(cl, obj);
691 struct DecorImages * di = (struct DecorImages *) GetTagData(WDA_DecorImages, (IPTR)NULL, msg->ops_AttrList);
692 struct DecorConfig * dc = (struct DecorConfig *) GetTagData(WDA_DecorConfig, (IPTR)NULL, msg->ops_AttrList);
694 D(bug("windecor_new: DecorImages @ 0x%p\n", di));
695 D(bug("windecor_new: DecorConfig @ 0x%p\n", dc));
697 if (!InitWindowSkinning(data, di, dc))
699 CoerceMethod(cl, obj, OM_DISPOSE);
700 obj = NULL;
704 return (IPTR)obj;
707 /**************************************************************************************************/
708 static IPTR windecor_dispose(Class *cl, Object *obj, struct opSet *msg)
710 struct windecor_data *data = INST_DATA(cl, obj);
712 DisposeWindowSkinning(data);
714 return 1;
717 /**************************************************************************************************/
718 static IPTR windecor_get(Class *cl, Object *obj, struct opGet *msg)
720 switch(msg->opg_AttrID)
722 case WDA_TrueColorOnly:
723 *msg->opg_Storage = TRUE;
724 break;
725 default:
726 return DoSuperMethodA(cl, obj, (Msg)msg);
728 return 1;
731 /**************************************************************************************************/
732 static IPTR windecor_draw_sysimage(Class *cl, Object *obj, struct wdpDrawSysImage *msg)
734 struct windecor_data *data = INST_DATA(cl, obj);
735 struct RastPort *rp = msg->wdp_RPort;
736 struct NewImage *ni = NULL;
737 struct WindowData *wd = (struct WindowData *) msg->wdp_UserBuffer;
738 LONG state = msg->wdp_State;
739 LONG left = msg->wdp_X;
740 LONG top = msg->wdp_Y;
741 LONG width = msg->wdp_Width;
742 LONG height = msg->wdp_Height;
743 WORD addx = 0;
744 WORD addy = 0;
745 BOOL isset = FALSE;
746 BOOL titlegadget = FALSE;
748 switch(msg->wdp_Which)
750 case SIZEIMAGE:
751 if (wd->img_size->ok)
753 ni = wd->img_size;
754 isset = TRUE;
755 if (data->dc->GadgetsThreeState)
756 addx = (data->dc->RightBorderGadgets - (wd->img_size->w / 3)) /2;
757 else
758 addx = (data->dc->RightBorderGadgets - (wd->img_size->w >> 2)) /2;
759 addy = (data->dc->BottomBorderGadgets - wd->img_size->h) / 2;
761 break;
763 case CLOSEIMAGE:
764 if (wd->img_close->ok)
766 ni = wd->img_close;
767 isset = TRUE;
768 titlegadget = TRUE;
770 break;
772 case MUIIMAGE:
773 if (wd->img_mui->ok)
775 ni = wd->img_mui;
776 isset = TRUE;
777 titlegadget = TRUE;
779 break;
781 case POPUPIMAGE:
782 if (wd->img_popup->ok)
784 ni = wd->img_popup;
785 isset = TRUE;
786 titlegadget = TRUE;
788 break;
790 case SNAPSHOTIMAGE:
791 if (wd->img_snapshot->ok)
793 ni = wd->img_snapshot;
794 isset = TRUE;
795 titlegadget = TRUE;
797 break;
799 case LOCKIMAGE:
800 if (wd->img_lock->ok)
802 ni = wd->img_lock;
803 isset = TRUE;
804 titlegadget = TRUE;
806 break;
808 case ICONIFYIMAGE:
809 if (wd->img_iconify->ok)
811 ni = wd->img_iconify;
812 isset = TRUE;
813 titlegadget = TRUE;
815 break;
817 case DEPTHIMAGE:
818 if (wd->img_depth->ok)
820 ni = wd->img_depth;
821 isset = TRUE;
822 titlegadget = TRUE;
824 break;
826 case ZOOMIMAGE:
827 if (wd->img_zoom->ok)
829 ni = wd->img_zoom;
830 isset = TRUE;
831 titlegadget = TRUE;
833 break;
835 case UPIMAGE:
836 ni = wd->img_up;
837 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;
838 addy = data->dc->UpDownAddY / 2;
839 isset = TRUE;
840 break;
842 case DOWNIMAGE:
843 ni = wd->img_down;
844 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;
845 addy = data->dc->UpDownAddY / 2;
846 isset = TRUE;
847 break;
849 case LEFTIMAGE:
850 ni = wd->img_left;
851 addx = data->dc->LeftRightAddX / 2;
852 addy = (data->dc->BottomBorderGadgets - wd->img_left->h) / 2;
853 isset = TRUE;
854 break;
856 case RIGHTIMAGE:
857 ni = wd->img_right;
858 addx = data->dc->LeftRightAddX / 2;
859 addy = (data->dc->BottomBorderGadgets - wd->img_right->h) /2;
860 isset = TRUE;
861 break;
863 default:
864 return DoSuperMethodA(cl, obj, (Msg)msg);
867 if (!isset) return DoSuperMethodA(cl, obj, (Msg)msg);
869 /* Reblit title bar */
870 if (wd && titlegadget && wd->tbar.bm)
871 BltBitMapRastPort(wd->tbar.bm, left + addx, top + addy, rp, left + addx, top + addy, width, height, 0xc0);
873 if (ni)
875 if (titlegadget)
876 DrawScaledStatefulGadgetImageToRP(rp, ni, state, left + addx, top + addy, -1, height);
877 else
878 DrawStatefulGadgetImageToRP(rp, ni, state, left + addx, top + addy);
881 return TRUE;
884 /**************************************************************************************************/
885 static IPTR windecor_draw_winborder(Class *cl, Object *obj, struct wdpDrawWinBorder *msg)
887 struct windecor_data *data = INST_DATA(cl, obj);
888 struct RastPort *rp = msg->wdp_RPort;
889 struct Window *window = msg->wdp_Window;
890 struct WindowData *wd = (struct WindowData *) msg->wdp_UserBuffer;
891 struct NewImage *ni = NULL;
892 UWORD *pens = msg->wdp_Dri->dri_Pens;
893 ULONG bc, color, s_col, e_col, arc;
894 UWORD bl, bt, br, bb, ww, wh;
895 LONG pen = -1;
897 if (wd->img_border_normal->ok) ni = wd->img_border_normal;
899 if (ni == NULL) data->dc->UseGradients = TRUE;
901 BOOL tc = wd->truecolor;
903 LONG dpen = pens[SHADOWPEN];
904 LONG lpen = pens[SHINEPEN];
905 LONG mpen = pens[SHINEPEN];
907 bl = window->BorderLeft;
908 bt = window->BorderTop;
909 bb = window->BorderBottom;
910 br = window->BorderRight;
911 ww = window->Width;
912 wh = window->Height;
914 color = 0x00cccccc;
916 if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX))
918 pen = wd->ActivePen;
919 s_col = data->dc->ActivatedGradientColor_s;
920 e_col = data->dc->ActivatedGradientColor_e;
921 arc = data->dc->ActivatedGradientColor_a;
922 bc = data->dc->BaseColors_a;
923 } else {
924 pen = wd->DeactivePen;
925 s_col = data->dc->DeactivatedGradientColor_s;
926 e_col = data->dc->DeactivatedGradientColor_e;
927 arc = data->dc->DeactivatedGradientColor_a;
928 bc = data->dc->BaseColors_d;
929 if (!data->dc->UseGradients)
931 if (wd->img_border_deactivated->ok) ni = wd->img_border_deactivated;
935 /* Draw title bar */
936 DrawPartialTitleBar(wd, data, window, rp, msg->wdp_Dri, pens);
938 /* Draw left, right and bottom frames */
939 if (!(msg->wdp_Flags & WDF_DWB_TOP_ONLY))
941 UBYTE * buf = NULL;
942 int overlap = 0;
944 if (data->dc->WinFrameStyle > 0)
945 overlap = 2;
947 if (data->dc->UseGradients)
949 /* Create one pixel wide buffer */
950 buf = AllocVec(1 * window->Height * 3, MEMF_ANY | MEMF_CLEAR);
952 /* Fill the buffer with gradient */
953 FillMemoryBufferRGBGradient(buf, pen, 0, 0, window->Width - 1, window->Height - 1, 0, 0,
954 1, window->Height , s_col, e_col, arc);
957 if (data->dc->UseGradients)
959 /* Reuse the buffer for blitting frames */
960 if (window->BorderLeft > overlap) HorizRepeatBuffer(buf, window->BorderTop, pen, wd->truecolor, rp,
961 0, window->BorderTop,
962 window->BorderLeft, window->Height - window->BorderTop);
963 if (window->BorderRight > overlap) HorizRepeatBuffer(buf, window->BorderTop, pen, wd->truecolor, rp,
964 window->Width - window->BorderRight, window->BorderTop,
965 window->BorderRight, window->Height - window->BorderTop);
966 if (window->BorderBottom > overlap) HorizRepeatBuffer(buf, window->Height - window->BorderBottom, pen, wd->truecolor, rp,
967 0, window->Height - window->BorderBottom,
968 window->Width, window->BorderBottom);
970 else
972 if (window->BorderLeft > overlap) HorizVertRepeatNewImage(ni, color, 0, window->BorderTop, rp,
973 0, window->BorderTop,
974 window->BorderLeft - 1, window->Height - window->BorderTop);
975 if (window->BorderRight > overlap) HorizVertRepeatNewImage(ni, color, window->Width - window->BorderRight , window->BorderTop, rp,
976 window->Width - window->BorderRight , window->BorderTop,
977 window->BorderRight, window->Height - window->BorderTop);
978 if (window->BorderBottom > overlap) HorizVertRepeatNewImage(ni, color, 0, window->Height - window->BorderBottom, rp,
979 0, window->Height - window->BorderBottom,
980 window->Width, window->BorderBottom);
983 /* Shading borders */
984 int bbt = bt;
986 if (data->dc->WinFrameStyle > 0)
988 if (bl > 0) ShadeLine(dpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_d, bbt, 0, bbt, 0, wh - 1);
989 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);
990 if (br > 0) ShadeLine(dpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_d, bbt , ww - 1, bbt , ww - 1, wh - 1);
991 if (bl > 1) ShadeLine(dpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_d, bbt, bl - 1, bbt, bl - 1, wh - bb);
992 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);
993 if (br > 1) ShadeLine(dpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_d, bbt , ww - br, bbt , ww - br, wh - bb);
994 if (bl > 2) ShadeLine(lpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_l, bbt, 1, bbt, 1, wh - 2);
995 if (bl > 3) {
996 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);
997 else ShadeLine(mpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_m, bbt, bl - 2, bbt, bl - 2, wh - bb);
999 if (br > 2) ShadeLine(mpen, tc, data->dc->UseGradients, rp, ni, bc, data->dc->ShadeValues_m, bbt, ww - 2, bbt, ww - 2, wh - 2);
1000 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);
1001 if (bb > 3) {
1002 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);
1004 if (br > 3) {
1005 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);
1008 FreeVec(buf);
1010 return TRUE;
1013 /**************************************************************************************************/
1014 static IPTR windecor_layout_bordergadgets(Class *cl, Object *obj, struct wdpLayoutBorderGadgets *msg)
1016 struct windecor_data *data = INST_DATA(cl, obj);
1017 struct Window *window = msg->wdp_Window;
1018 struct Gadget *gadget = msg->wdp_Gadgets;
1019 struct Gadget *draggadget = NULL;
1020 struct WindowData *wd = (struct WindowData *) msg->wdp_UserBuffer;
1021 ULONG eb = msg->wdp_ExtraButtons;
1023 BOOL hasdepth;
1024 BOOL haszoom;
1025 BOOL hasclose;
1026 LONG width;
1027 LONG refheight = window->BorderTop;
1029 DoSuperMethodA(cl, obj, (Msg)msg);
1031 hasclose = (window->Flags & WFLG_CLOSEGADGET) ? TRUE : FALSE;
1032 hasdepth = (window->Flags & WFLG_DEPTHGADGET) ? TRUE : FALSE;
1033 haszoom = ((window->Flags & WFLG_HASZOOM) || ((window->Flags & WFLG_SIZEGADGET) && hasdepth)) ? TRUE : FALSE;
1036 if ((msg->wdp_Flags & WDF_LBG_SYSTEMGADGET) != 0)
1038 if (gadget->GadgetType == GTYP_CUSTOMGADGET)
1040 switch(gadget->GadgetID)
1042 case ETI_MUI:
1043 if (wd->img_mui->ok)
1045 if (data->dc->GadgetsThreeState) width = (wd->img_mui->w / 3); else width = (wd->img_mui->w >> 2);
1047 gadget->Width = width;
1048 gadget->TopEdge = (refheight - gadget->Height) / 2;
1050 if (haszoom)
1052 if (data->dc->GadgetsThreeState) width += (wd->img_zoom->w / 3); else width += (wd->img_zoom->w >> 2);
1054 if (hasclose && data->dc->CloseGadgetOnRight)
1056 if (data->dc->GadgetsThreeState) width += (wd->img_close->w / 3); else width += (wd->img_close->w >> 2);
1058 if (hasdepth)
1060 if (data->dc->GadgetsThreeState) width += (wd->img_depth->w / 3); else width += (wd->img_depth->w >> 2);
1061 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1063 else
1065 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1067 gadget->Flags &= ~GFLG_RELWIDTH;
1068 gadget->Flags |= GFLG_RELRIGHT;
1071 break;
1073 case ETI_PopUp:
1074 if (wd->img_popup->ok)
1076 if (data->dc->GadgetsThreeState) width = (wd->img_popup->w / 3); else width = (wd->img_popup->w >> 2);
1078 gadget->Width = width;
1079 gadget->TopEdge = (refheight - gadget->Height) / 2;
1081 if ((eb & ETG_MUI) != 0)
1083 if (wd->img_mui->ok)
1085 if (data->dc->GadgetsThreeState) width += (wd->img_mui->w / 3); else width += (wd->img_mui->w >> 2);
1089 if (haszoom)
1091 if (data->dc->GadgetsThreeState) width += (wd->img_zoom->w / 3); else width += (wd->img_zoom->w >> 2);
1094 if (hasclose && data->dc->CloseGadgetOnRight)
1096 if (data->dc->GadgetsThreeState) width += (wd->img_close->w / 3); else width += (wd->img_close->w >> 2);
1098 if (hasdepth)
1100 if (data->dc->GadgetsThreeState) width += (wd->img_depth->w / 3); else width += (wd->img_depth->w >> 2);
1101 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1103 else
1105 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1107 gadget->Flags &= ~GFLG_RELWIDTH;
1108 gadget->Flags |= GFLG_RELRIGHT;
1111 break;
1113 case ETI_Snapshot:
1114 if (wd->img_snapshot->ok)
1116 if (data->dc->GadgetsThreeState) width = (wd->img_snapshot->w / 3); else width = (wd->img_snapshot->w >> 2);
1118 gadget->Width = width;
1119 gadget->TopEdge = (refheight - gadget->Height) / 2;
1121 if ((eb & ETG_MUI) != 0)
1124 if (wd->img_mui->ok)
1126 if (data->dc->GadgetsThreeState) width += (wd->img_mui->w / 3); else width += (wd->img_mui->w >> 2);
1130 if ((eb & ETG_POPUP) != 0)
1132 if (wd->img_popup->ok)
1134 if (data->dc->GadgetsThreeState) width += (wd->img_popup->w / 3); else width += (wd->img_popup->w >> 2);
1138 if (haszoom)
1140 if (data->dc->GadgetsThreeState) width += (wd->img_zoom->w / 3); else width += (wd->img_zoom->w >> 2);
1143 if (hasclose && data->dc->CloseGadgetOnRight)
1145 if (data->dc->GadgetsThreeState) width += (wd->img_close->w / 3); else width += (wd->img_close->w >> 2);
1148 if (hasdepth)
1150 if (data->dc->GadgetsThreeState) width += (wd->img_depth->w / 3); else width += (wd->img_depth->w >> 2);
1151 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1153 else
1155 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1158 gadget->Flags &= ~GFLG_RELWIDTH;
1159 gadget->Flags |= GFLG_RELRIGHT;
1162 break;
1164 case ETI_Iconify:
1165 if (wd->img_iconify->ok)
1167 if (data->dc->GadgetsThreeState) width = (wd->img_iconify->w / 3); else width = (wd->img_iconify->w >> 2);
1169 gadget->Width = width;
1170 gadget->TopEdge = (refheight - gadget->Height) / 2;
1172 if ((eb & ETG_MUI) != 0)
1174 if (wd->img_mui->ok)
1176 if (data->dc->GadgetsThreeState) width += (wd->img_mui->w / 3); else width += (wd->img_mui->w >> 2);
1180 if ((eb & ETG_POPUP) != 0)
1182 if (wd->img_popup->ok)
1184 if (data->dc->GadgetsThreeState) width += (wd->img_popup->w / 3); else width += (wd->img_popup->w >> 2);
1188 if ((eb & ETG_SNAPSHOT) != 0)
1190 if (wd->img_snapshot->ok)
1192 if (data->dc->GadgetsThreeState) width += (wd->img_snapshot->w / 3); else width += (wd->img_snapshot->w >> 2);
1196 if (haszoom)
1198 if (data->dc->GadgetsThreeState) width += (wd->img_zoom->w / 3); else width += (wd->img_zoom->w >> 2);
1201 if (hasclose && data->dc->CloseGadgetOnRight)
1203 if (data->dc->GadgetsThreeState) width += (wd->img_close->w / 3); else width += (wd->img_close->w >> 2);
1205 if (hasdepth)
1207 if (data->dc->GadgetsThreeState) width += (wd->img_depth->w / 3); else width += (wd->img_depth->w >> 2);
1208 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1210 else
1212 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1214 gadget->Flags &= ~GFLG_RELWIDTH;
1215 gadget->Flags |= GFLG_RELRIGHT;
1218 break;
1220 case ETI_Lock:
1221 if (wd->img_lock->ok)
1223 if (data->dc->GadgetsThreeState) width = (wd->img_lock->w / 3); else width = (wd->img_lock->w >> 2);
1225 gadget->Width = width;
1226 gadget->TopEdge = (refheight - gadget->Height) / 2;
1228 if ((eb & ETG_MUI) != 0)
1230 if (wd->img_mui->ok)
1232 if (data->dc->GadgetsThreeState) width += (wd->img_mui->w / 3); else width += (wd->img_mui->w >> 2);
1236 if ((eb & ETG_POPUP) != 0)
1238 if (wd->img_popup->ok)
1240 if (data->dc->GadgetsThreeState) width += (wd->img_popup->w / 3); else width += (wd->img_popup->w >> 2);
1244 if ((eb & ETG_SNAPSHOT) != 0)
1246 if (wd->img_snapshot->ok)
1248 if (data->dc->GadgetsThreeState) width += (wd->img_snapshot->w / 3); else width += (wd->img_snapshot->w >> 2);
1252 if ((eb & ETG_ICONIFY) != 0)
1254 if (wd->img_iconify->ok)
1256 if (data->dc->GadgetsThreeState) width += (wd->img_iconify->w / 3); else width += (wd->img_iconify->w >> 2);
1260 if (haszoom)
1262 if (data->dc->GadgetsThreeState) width += (wd->img_zoom->w / 3); else width += (wd->img_zoom->w >> 2);
1265 if (hasclose && data->dc->CloseGadgetOnRight)
1267 if (data->dc->GadgetsThreeState) width += (wd->img_close->w / 3); else width += (wd->img_close->w >> 2);
1269 if (hasdepth)
1271 if (data->dc->GadgetsThreeState) width += (wd->img_depth->w / 3); else width += (wd->img_depth->w >> 2);
1272 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1274 else
1276 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1278 gadget->Flags &= ~GFLG_RELWIDTH;
1279 gadget->Flags |= GFLG_RELRIGHT;
1282 break;
1286 else
1288 switch(gadget->GadgetType & GTYP_SYSTYPEMASK)
1290 case GTYP_CLOSE:
1291 if (data->dc->GadgetsThreeState) width = (wd->img_close->w / 3); else width = (wd->img_close->w >> 2);
1292 gadget->Width = width;
1293 wd->closewidth = width;
1294 if (data->dc->CloseGadgetOnRight)
1296 gadget->Flags &= ~GFLG_RELWIDTH;
1297 gadget->Flags |= GFLG_RELRIGHT;
1298 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1300 else
1302 gadget->LeftEdge = data->dc->BarPreGadget_s;
1304 gadget->TopEdge = (refheight - gadget->Height) / 2;
1305 break;
1307 case GTYP_WDEPTH:
1308 if (data->dc->GadgetsThreeState) width = (wd->img_depth->w / 3); else width = (wd->img_depth->w >> 2);
1309 gadget->Width = width;
1310 wd->depthwidth = width;
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 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1316 gadget->TopEdge = (refheight - gadget->Height) / 2;
1317 gadget->Flags &= ~GFLG_RELWIDTH;
1318 gadget->Flags |= GFLG_RELRIGHT;
1319 break;
1321 case GTYP_WZOOM:
1322 if (data->dc->GadgetsThreeState) width = (wd->img_zoom->w / 3); else width = (wd->img_zoom->w >> 2);
1323 gadget->Width = width;
1324 wd->zoomwidth = width;
1325 gadget->TopEdge = (refheight - gadget->Height) / 2;
1326 if (hasclose && data->dc->CloseGadgetOnRight)
1328 if (data->dc->GadgetsThreeState) width += (wd->img_close->w / 3); else width += (wd->img_close->w >> 2);
1330 if (hasdepth)
1332 if (data->dc->GadgetsThreeState) width += (wd->img_depth->w / 3); else width += (wd->img_depth->w >> 2);
1333 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1335 else
1337 gadget->LeftEdge = -data->dc->BarPostGadget_s - width;
1339 gadget->Flags &= ~GFLG_RELWIDTH;
1340 gadget->Flags |= GFLG_RELRIGHT;
1342 break;
1344 case GTYP_WDRAGGING:
1345 break;
1349 return TRUE;
1352 int sysrgad = -data->dc->BarPostGadget_s - 1;
1354 if (data->dc->CloseGadgetOnRight && hasclose) sysrgad -= wd->closewidth;
1355 if (hasdepth) sysrgad -= wd->depthwidth;
1356 if (haszoom) sysrgad -= wd->zoomwidth;
1357 while(gadget)
1359 if ((gadget->GadgetType & GTYP_SYSTYPEMASK) == 0)
1361 switch(gadget->GadgetType & GTYP_SYSTYPEMASK)
1363 case GTYP_WDRAGGING:
1364 break;
1366 default:
1367 if ((gadget->Flags & GFLG_EXTENDED) != 0)
1369 if ((((struct ExtGadget *) gadget)->MoreFlags & GMORE_BOOPSIGADGET) != 0)
1371 IPTR rtsm = 0;
1372 GetAttr(GA_RightBorder, (Object *) gadget, &rtsm);
1373 if (rtsm)
1375 if (GetAttr(PGA_Top, (Object *) gadget, &rtsm))
1377 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);
1379 else
1381 GetAttr(GA_Width, (Object *) gadget, &rtsm);
1382 SetAttrs((Object *) gadget, GA_RelRight, - data->dc->RightBorderGadgets + ((data->dc->RightBorderGadgets - rtsm + 1) >> 1) + 1, TAG_DONE);
1385 else
1387 GetAttr(GA_BottomBorder, (Object *) gadget, &rtsm);
1388 if (rtsm)
1390 if (GetAttr(PGA_Top, (Object *) gadget, &rtsm))
1392 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);
1394 else
1396 GetAttr(GA_Height, (Object *) gadget, &rtsm);
1397 SetAttrs((Object *) gadget, GA_RelBottom, - data->dc->BottomBorderGadgets + ((data->dc->BottomBorderGadgets - rtsm + 1) >> 1) + 1, TAG_DONE);
1403 break;
1406 if (msg->wdp_Flags & WDF_LBG_MULTIPLE)
1408 gadget = gadget->NextGadget;
1410 else
1412 gadget = NULL;
1415 gadget = msg->wdp_Gadgets;
1417 while(gadget)
1419 if ((gadget->GadgetType & GTYP_SYSTYPEMASK) == 0)
1421 if ((gadget->Activation & GACT_TOPBORDER) != 0)
1423 if ((gadget->Flags & GFLG_RELRIGHT) != 0)
1425 gadget->TopEdge = (refheight - gadget->Height) / 2;
1426 sysrgad -= gadget->Width;
1427 gadget->LeftEdge = sysrgad;
1431 gadget = gadget->NextGadget;
1434 gadget = msg->wdp_Gadgets;
1436 if ((msg->wdp_Flags & WDF_LBG_SYSTEMGADGET) != 0) while(gadget)
1438 switch(gadget->GadgetType & GTYP_SYSTYPEMASK)
1440 case GTYP_WDRAGGING:
1441 gadget->Width = sysrgad;
1442 if (hasclose && !data->dc->CloseGadgetOnRight)
1444 gadget->Width -= data->dc->BarPreGadget_s;
1445 if (data->dc->GadgetsThreeState) gadget->Width -= (wd->img_close->w / 3); else gadget->Width -= (wd->img_close->w >> 2);
1447 break;
1449 gadget = gadget->NextGadget;
1452 if (draggadget)
1456 return TRUE;
1459 /**************************************************************************************************/
1460 static IPTR windecor_draw_borderpropback(Class *cl, Object *obj, struct wdpDrawBorderPropBack *msg)
1462 /* Simply return, we need to render the back in the knob method */
1463 /* because we want to use irregular (alpha images) for the sliders */
1464 return TRUE;
1467 /**************************************************************************************************/
1468 static IPTR windecor_draw_borderpropknob(Class *cl, Object *obj, struct wdpDrawBorderPropKnob *msg)
1470 struct windecor_data *data = INST_DATA(cl, obj);
1471 struct Window *window = msg->wdp_Window;
1472 struct RastPort *winrp = msg->wdp_RPort;
1473 struct WindowData *wd = (struct WindowData *) msg->wdp_UserBuffer;
1475 struct RastPort *rp;
1476 struct Gadget *gadget = msg->wdp_Gadget;
1477 struct Rectangle *r;
1478 struct PropInfo *pi = ((struct PropInfo *)gadget->SpecialInfo);
1479 struct NewImage *ni = NULL;
1480 BOOL hit = (msg->wdp_Flags & WDF_DBPK_HIT) ? TRUE : FALSE;
1481 ULONG y, x, bx0, bx1, by0, by1;
1482 LONG size;
1483 ULONG s_col, e_col, arc;
1484 LONG pen = -1;
1485 struct BitMap *cachedgadgetbitmap = NULL;
1486 ULONG changetype = CHANGE_NO_CHANGE;
1487 ULONG subimage = 0;
1489 if (!(pi->Flags & PROPNEWLOOK) || (gadget->Activation && (GACT_RIGHTBORDER | GACT_BOTTOMBORDER) == 0))
1491 return DoSuperMethodA(cl, obj, (Msg)msg);
1494 /* Detect change in gadget dimensions (which needs to trigger redraw) */
1495 if ((pi->Flags & FREEVERT) != 0)
1497 changetype = HasPropGadgetChanged(&wd->vert, msg);
1499 if (changetype == CHANGE_SIZE_CHANGE)
1501 /* Free is there was size change */
1502 if (wd->vert.bm != NULL)
1503 FreeBitMap(wd->vert.bm);
1504 wd->vert.bm = NULL;
1506 cachedgadgetbitmap = wd->vert.bm;
1508 else if ((pi->Flags & FREEHORIZ) != 0)
1510 changetype = HasPropGadgetChanged(&wd->horiz, msg);
1512 if (changetype == CHANGE_SIZE_CHANGE)
1514 /* Free is there was size change */
1515 if (wd->horiz.bm != NULL)
1516 FreeBitMap(wd->horiz.bm);
1517 wd->horiz.bm = NULL;
1519 cachedgadgetbitmap = wd->horiz.bm;
1522 else
1523 return TRUE; /* Return TRUE - after all this is not an error */
1525 /* Reuse the bitmap if that is possible */
1526 if (changetype == CHANGE_NO_CHANGE)
1528 /* Final blitting of gadget bitmap to window rast port */
1529 BltBitMapRastPort(cachedgadgetbitmap, 0, 0, winrp, msg->wdp_PropRect->MinX,
1530 msg->wdp_PropRect->MinY,
1531 msg->wdp_PropRect->MaxX - msg->wdp_PropRect->MinX + 1,
1532 msg->wdp_PropRect->MaxY - msg->wdp_PropRect->MinY + 1, 0xc0);
1533 return TRUE;
1536 /* Regenerate the bitmap */
1537 r = msg->wdp_PropRect;
1539 bx0 = r->MinX;
1540 by0 = r->MinY;
1541 bx1 = r->MaxX;
1542 by1 = r->MaxY;
1544 rp = CreateRastPort();
1545 if (rp)
1547 /* Reuse the bitmap if there was no size change (ie. only move of knob) */
1548 if (changetype == CHANGE_NO_SIZE_CHANGE)
1549 rp->BitMap = cachedgadgetbitmap;
1550 else
1551 rp->BitMap = AllocBitMap(bx1 - bx0 + 1, by1 - by0 + 1, 1, 0, window->WScreen->RastPort.BitMap);
1553 if (rp->BitMap == NULL)
1555 FreeRastPort(rp);
1556 return FALSE;
1559 else
1560 return FALSE;
1562 if (wd->img_border_normal->ok) ni = wd->img_border_normal;
1564 if (ni == NULL) data->dc->UseGradients = TRUE;
1566 if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX))
1568 s_col = data->dc->ActivatedGradientColor_s;
1569 e_col = data->dc->ActivatedGradientColor_e;
1570 arc = data->dc->ActivatedGradientColor_a;
1571 pen = wd->ActivePen;
1573 else
1575 s_col = data->dc->DeactivatedGradientColor_s;
1576 e_col = data->dc->DeactivatedGradientColor_e;
1577 arc = data->dc->DeactivatedGradientColor_a;
1578 if (!data->dc->UseGradients)
1580 if (wd->img_border_deactivated->ok) ni = wd->img_border_deactivated;
1582 pen = wd->DeactivePen;
1585 /* Drawing background - this solves WDM_DRAW_BORDERPROPBACK without need of
1586 reading from window when drawing container and knob */
1587 if (data->dc->UseGradients)
1589 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);
1591 else
1593 if (ni->ok)
1595 ULONG color = 0x00cccccc;
1596 HorizVertRepeatNewImage(ni, color, bx0, by0, rp, 0, 0, bx1 - bx0 + 1, by1 - by0 + 1);
1600 /* Drawing knob container */
1601 r = msg->wdp_PropRect;
1603 bx0 = 0;
1604 by0 = 0;
1605 bx1 = r->MaxX - r->MinX;
1606 by1 = r->MaxY - r->MinY;
1608 if ((pi->Flags & FREEVERT) != 0)
1610 if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)) subimage = 0; else subimage = 1;
1611 y = by0;
1612 size = by1 - by0 - data->dc->ContainerTop_s - data->dc->ContainerBottom_s + 1;
1613 y = WriteTiledImageVertical(rp, wd->img_verticalcontainer, subimage, data->dc->ContainerTop_o, data->dc->ContainerTop_s, bx0, y, data->dc->ContainerTop_s);
1614 if (size > 0) y = WriteTiledImageVertical(rp, wd->img_verticalcontainer, subimage, data->dc->ContainerVertTile_o, data->dc->ContainerVertTile_s, bx0, y, size);
1616 y = WriteTiledImageVertical(rp, wd->img_verticalcontainer, subimage, data->dc->ContainerBottom_o, data->dc->ContainerBottom_s, bx0, y, data->dc->ContainerBottom_s);
1619 else if ((pi->Flags & FREEHORIZ) != 0)
1621 if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)) subimage = 0; else subimage = 1;
1622 x = bx0;
1623 size = bx1 - bx0 - data->dc->ContainerLeft_s - data->dc->ContainerRight_s + 1;
1624 x = WriteTiledImageHorizontal(rp, wd->img_horizontalcontainer, subimage, data->dc->ContainerLeft_o, data->dc->ContainerLeft_s, x, by0, data->dc->ContainerLeft_s);
1625 if (size > 0) x = WriteTiledImageHorizontal(rp, wd->img_horizontalcontainer, subimage, data->dc->ContainerHorTile_o, data->dc->ContainerHorTile_s, x, by0, size);
1626 x = WriteTiledImageHorizontal(rp, wd->img_horizontalcontainer, subimage, data->dc->ContainerRight_o, data->dc->ContainerRight_s, x, by0, data->dc->ContainerRight_s);
1630 /* Drawing knob */
1631 bx0 = msg->wdp_PropRect->MinX;
1632 by0 = msg->wdp_PropRect->MinY;
1633 bx1 = msg->wdp_PropRect->MaxX;
1634 by1 = msg->wdp_PropRect->MaxY;
1636 r = msg->wdp_RenderRect;
1637 if ((pi->Flags & FREEVERT) != 0)
1639 if (hit) subimage = 1; else if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)) subimage = 0; else subimage = 2;
1640 y = r->MinY - by0;
1641 size = r->MaxY - r->MinY - data->dc->KnobTop_s - data->dc->KnobBottom_s + 1;
1643 y = WriteTiledImageVertical(rp, wd->img_verticalknob, subimage, data->dc->KnobTop_o, data->dc->KnobTop_s, r->MinX - bx0, y, data->dc->KnobTop_s);
1644 if (size > 0)
1646 if (size > data->dc->KnobVertGripper_s)
1648 size = size - data->dc->KnobVertGripper_s;
1649 int size_bak = size;
1650 size = size / 2;
1651 if (size > 0) y = WriteTiledImageVertical(rp, wd->img_verticalknob, subimage, data->dc->KnobTileTop_o, data->dc->KnobTileTop_s, r->MinX - bx0, y, size);
1652 y = WriteTiledImageVertical(rp, wd->img_verticalknob, subimage, data->dc->KnobVertGripper_o, data->dc->KnobVertGripper_s, r->MinX - bx0, y, data->dc->KnobVertGripper_s);
1653 size = size_bak - size;
1654 if (size > 0) y = WriteTiledImageVertical(rp, wd->img_verticalknob, subimage, data->dc->KnobTileBottom_o, data->dc->KnobTileBottom_s, r->MinX - bx0, y, size);
1656 else
1658 y = WriteTiledImageVertical(rp, wd->img_verticalknob, subimage, data->dc->KnobTileTop_o, data->dc->KnobTileTop_s, r->MinX - bx0, y, size);
1661 y = WriteTiledImageVertical(rp, wd->img_verticalknob, subimage, data->dc->KnobBottom_o, data->dc->KnobBottom_s, r->MinX - bx0, y, data->dc->KnobBottom_s);
1663 else if ((pi->Flags & FREEHORIZ) != 0)
1665 if (hit) subimage = 1; else if (window->Flags & (WFLG_WINDOWACTIVE | WFLG_TOOLBOX)) subimage = 0; else subimage = 2;
1666 x = r->MinX - bx0;
1667 size = r->MaxX - r->MinX - data->dc->KnobLeft_s - data->dc->KnobRight_s + 1;
1668 x = WriteTiledImageHorizontal(rp, wd->img_horizontalknob, subimage, data->dc->KnobLeft_o, data->dc->KnobLeft_s, x, r->MinY - by0, data->dc->KnobLeft_s);
1670 if (size > 0)
1672 if (size > data->dc->KnobHorGripper_s)
1674 size = size - data->dc->KnobHorGripper_s;
1675 int size_bak = size;
1676 size = size / 2;
1677 if (size > 0) x = WriteTiledImageHorizontal(rp, wd->img_horizontalknob, subimage, data->dc->KnobTileLeft_o, data->dc->KnobTileLeft_s, x, r->MinY - by0, size);
1678 x = WriteTiledImageHorizontal(rp, wd->img_horizontalknob, subimage, data->dc->KnobHorGripper_o, data->dc->KnobHorGripper_s, x, r->MinY - by0, data->dc->KnobHorGripper_s);
1679 size = size_bak - size;
1680 if (size > 0) x = WriteTiledImageHorizontal(rp, wd->img_horizontalknob, subimage, data->dc->KnobTileRight_o, data->dc->KnobTileRight_s, x, r->MinY - by0, size);
1682 else
1684 x = WriteTiledImageHorizontal(rp, wd->img_horizontalknob, subimage, data->dc->KnobTileRight_o, data->dc->KnobTileRight_s, x, r->MinY - by0, size);
1687 x = WriteTiledImageHorizontal(rp, wd->img_horizontalknob, subimage, data->dc->KnobRight_o, data->dc->KnobRight_s, x, r->MinY - by0, data->dc->KnobRight_s);
1690 /* Final blitting of gadget bitmap to window rast port */
1691 BltBitMapRastPort(rp->BitMap, 0, 0, winrp, msg->wdp_PropRect->MinX,
1692 msg->wdp_PropRect->MinY,
1693 msg->wdp_PropRect->MaxX - msg->wdp_PropRect->MinX + 1,
1694 msg->wdp_PropRect->MaxY - msg->wdp_PropRect->MinY + 1, 0xc0);
1696 /* Cache the actual bitmap */
1697 if ((pi->Flags & FREEVERT) != 0)
1698 CachePropGadget(&wd->vert, msg, rp->BitMap);
1699 else if ((pi->Flags & FREEHORIZ) != 0)
1700 CachePropGadget(&wd->horiz, msg, rp->BitMap);
1702 FreeRastPort(rp);
1704 return TRUE;
1707 /**************************************************************************************************/
1708 static IPTR windecor_getdefsizes(Class *cl, Object *obj, struct wdpGetDefSizeSysImage *msg)
1710 struct windecor_data *data = INST_DATA(cl, obj);
1711 struct NewImage *n = NULL;
1712 WORD w = 0, h = 0;
1713 BOOL isset = FALSE;
1714 BOOL titlegadget = FALSE;
1716 switch(msg->wdp_Which)
1718 case SIZEIMAGE:
1719 n = NULL;
1720 w = data->dc->RightBorderGadgets;
1721 h = data->dc->BottomBorderGadgets;
1722 isset = TRUE;
1723 break;
1725 case CLOSEIMAGE:
1726 n = data->img_close;
1727 if(n) isset = TRUE;
1728 titlegadget = TRUE;
1729 break;
1731 case MUIIMAGE:
1732 n = data->img_mui;
1733 if(n) isset = TRUE;
1734 titlegadget = TRUE;
1735 break;
1737 case POPUPIMAGE:
1738 n = data->img_popup;
1739 if(n) isset = TRUE;
1740 titlegadget = TRUE;
1741 break;
1743 case SNAPSHOTIMAGE:
1744 n = data->img_snapshot;
1745 if(n) isset = TRUE;
1746 titlegadget = TRUE;
1747 break;
1749 case ICONIFYIMAGE:
1750 n = data->img_iconify;
1751 if(n) isset = TRUE;
1752 titlegadget = TRUE;
1753 break;
1755 case LOCKIMAGE:
1756 n = data->img_lock;
1757 if(n) isset = TRUE;
1758 titlegadget = TRUE;
1759 break;
1761 case UPIMAGE:
1762 n = NULL;
1763 w = data->dc->RightBorderGadgets;
1764 h = data->img_up->h + data->dc->UpDownAddY;
1765 isset = TRUE;
1766 break;
1768 case DOWNIMAGE:
1769 n = NULL;
1770 w = data->dc->RightBorderGadgets;
1771 h = data->img_down->h + data->dc->UpDownAddY;
1772 isset = TRUE;
1773 break;
1775 case LEFTIMAGE:
1776 n = NULL;
1777 if (data->dc->GadgetsThreeState) w = (data->img_left->w / 3); else w = (data->img_left->w >> 2);
1778 w += data->dc->LeftRightAddX;
1779 h = data->dc->BottomBorderGadgets;
1780 isset = TRUE;
1781 break;
1783 case RIGHTIMAGE:
1784 n = NULL;
1785 if (data->dc->GadgetsThreeState) w = (data->img_right->w / 3); else w = (data->img_right->w >> 2);
1786 w += data->dc->LeftRightAddX;
1787 h = data->dc->BottomBorderGadgets;
1788 isset = TRUE;
1789 break;
1791 case DEPTHIMAGE:
1792 n = data->img_depth;
1793 if(n) isset = TRUE;
1794 titlegadget = TRUE;
1795 break;
1797 case ZOOMIMAGE:
1798 n = data->img_zoom;
1799 if(n) isset = TRUE;
1800 titlegadget = TRUE;
1801 break;
1803 default:
1804 return FALSE;
1807 if (!isset) return DoSuperMethodA(cl, obj, (Msg) msg);
1809 if (n == NULL)
1811 *msg->wdp_Width = w;
1812 *msg->wdp_Height = h;
1814 else
1816 if (n->ok)
1818 if (data->dc->GadgetsThreeState)
1820 *msg->wdp_Width = (n->w / 3);
1821 *msg->wdp_Height = n->h;
1823 else
1825 *msg->wdp_Width = (n->w >> 2);
1826 *msg->wdp_Height = n->h;
1829 if(titlegadget && (msg->wdp_ReferenceFont->tf_YSize + 2 > data->dc->BarHeight))
1831 /* Scale height so that the gadget is not proportionally resized (so that width does not change) */
1832 *msg->wdp_Height *= msg->wdp_ReferenceFont->tf_YSize + 2;
1833 *msg->wdp_Height /= data->dc->BarHeight;
1835 } else return DoSuperMethodA(cl, obj, (Msg) msg);
1838 return TRUE;
1841 /**************************************************************************************************/
1842 static IPTR windecor_windowshape(Class *cl, Object *obj, struct wdpWindowShape *msg)
1844 struct windecor_data *data = INST_DATA(cl, obj);
1845 struct WindowData *wd = (struct WindowData *) msg->wdp_UserBuffer;
1846 struct Window *window = msg->wdp_Window;
1848 if (data->dc->BarMasking)
1850 if (HasTitleBarShapeChanged(&wd->tbarshape, window) != CHANGE_NO_CHANGE)
1852 struct NewLUT8ImageContainer *shape;
1853 struct Region * newreg = NULL;
1855 if (wd->tbarshape.shape != NULL)
1857 DisposeRegion(wd->tbarshape.shape);
1858 wd->tbarshape.shape = NULL;
1861 shape = (struct NewLUT8ImageContainer *)NewLUT8ImageContainer(window->Width, window->BorderTop);
1862 if (shape)
1864 if (window->BorderTop > 0) DrawShapePartialTitleBar(wd, (struct NewLUT8Image *)shape, data, window);
1866 newreg = RegionFromLUT8Image(msg->wdp_Width, msg->wdp_Height, (struct NewLUT8Image *)shape);
1867 DisposeLUT8ImageContainer((struct NewLUT8Image *)shape);
1869 CacheTitleBarShape(&wd->tbarshape, window, newreg);
1873 /* Make a copy of region and return it */
1874 return (IPTR)CopyRegion(wd->tbarshape.shape);
1878 if (!data->dc->BarRounded) return (IPTR) NULL;
1880 struct Region *newshape;
1882 int x2 = msg->wdp_Width-1;
1883 int y2 = msg->wdp_Height-1;
1885 if ((newshape = NewRegion()))
1887 struct Rectangle rect;
1888 BOOL success = TRUE;
1890 rect.MinX = 9;
1891 rect.MinY = 0;
1892 rect.MaxX = x2 - 9;
1893 rect.MaxY = y2;
1894 success &= OrRectRegion(newshape, &rect);
1896 rect.MinX = 6;
1897 rect.MinY = 1;
1898 rect.MaxX = x2 - 6;
1899 rect.MaxY = y2;
1900 success &= OrRectRegion(newshape, &rect);
1902 rect.MinX = 4;
1903 rect.MinY = 2;
1904 rect.MaxX = x2 - 4;
1905 rect.MaxY = y2;
1906 success &= OrRectRegion(newshape, &rect);
1908 rect.MinX = 3;
1909 rect.MinY = 3;
1910 rect.MaxX = x2 - 3;
1911 rect.MaxY = y2;
1912 success &= OrRectRegion(newshape, &rect);
1914 rect.MinX = 2;
1915 rect.MinY = 4;
1916 rect.MaxX = x2 - 2;
1917 rect.MaxY = y2;
1918 success &= OrRectRegion(newshape, &rect);
1920 rect.MinX = 1;
1921 rect.MinY = 6;
1922 rect.MaxX = x2 - 1;
1923 rect.MaxY = y2;
1924 success &= OrRectRegion(newshape, &rect);
1926 rect.MinX = 0;
1927 rect.MinY = 9;
1928 rect.MaxX = x2;
1929 rect.MaxY = y2;
1930 success &= OrRectRegion(newshape, &rect);
1932 return (IPTR) newshape;
1935 /**************************************************************************************************/
1936 static IPTR windecor_initwindow(Class *cl, Object *obj, struct wdpInitWindow *msg)
1938 struct WindowData *wd = (struct WindowData *)msg->wdp_UserBuffer;
1939 struct ScreenData *sd = (struct ScreenData *)msg->wdp_ScreenUserBuffer;
1941 wd->truecolor = msg->wdp_TrueColor;
1943 wd->ActivePen = sd->ActivePen;
1944 wd->DeactivePen = sd->DeactivePen;
1946 wd->vert.bm = NULL;
1947 wd->horiz.bm = NULL;
1949 SETIMAGE_WIN(size);
1950 SETIMAGE_WIN(close);
1951 SETIMAGE_WIN(depth);
1952 SETIMAGE_WIN(zoom);
1953 SETIMAGE_WIN(up);
1954 SETIMAGE_WIN(down);
1955 SETIMAGE_WIN(left);
1956 SETIMAGE_WIN(right);
1957 SETIMAGE_WIN(mui);
1958 SETIMAGE_WIN(popup);
1959 SETIMAGE_WIN(snapshot);
1960 SETIMAGE_WIN(iconify);
1961 SETIMAGE_WIN(lock);
1962 SETIMAGE_WIN(winbar_normal);
1963 SETIMAGE_WIN(border_normal);
1964 SETIMAGE_WIN(border_deactivated);
1965 SETIMAGE_WIN(verticalcontainer);
1966 SETIMAGE_WIN(verticalknob);
1967 SETIMAGE_WIN(horizontalcontainer);
1968 SETIMAGE_WIN(horizontalknob);
1970 return TRUE;
1973 /**************************************************************************************************/
1974 static IPTR windecor_exitwindow(Class *cl, Object *obj, struct wdpExitWindow *msg)
1976 struct WindowData *wd = (struct WindowData *) msg->wdp_UserBuffer;
1978 if (wd->vert.bm) FreeBitMap(wd->vert.bm);
1979 if (wd->horiz.bm) FreeBitMap(wd->horiz.bm);
1980 if (wd->tbar.bm) FreeBitMap(wd->tbar.bm);
1981 if (wd->tbarshape.shape) DisposeRegion(wd->tbarshape.shape);
1982 if (wd->tbar.title) FreeVec(wd->tbar.title);
1984 return TRUE;
1987 /**************************************************************************************************/
1988 static IPTR windecor_dispatcher(struct IClass *cl, Object *obj, Msg msg)
1990 IPTR retval;
1992 switch(msg->MethodID)
1994 case OM_NEW:
1995 retval = windecor_new(cl, obj, (struct opSet *)msg);
1996 break;
1998 case OM_DISPOSE:
1999 retval = windecor_dispose(cl, obj, (struct opSet *)msg);
2000 break;
2002 case OM_GET:
2003 retval = windecor_get(cl, obj, (struct opGet *)msg);
2004 break;
2006 case WDM_DRAW_SYSIMAGE:
2007 retval = windecor_draw_sysimage(cl, obj, (struct wdpDrawSysImage *)msg);
2008 break;
2010 case WDM_DRAW_WINBORDER:
2011 retval = windecor_draw_winborder(cl, obj, (struct wdpDrawWinBorder *)msg);
2012 break;
2014 case WDM_LAYOUT_BORDERGADGETS:
2015 retval = windecor_layout_bordergadgets(cl, obj, (struct wdpLayoutBorderGadgets *)msg);
2016 break;
2018 case WDM_DRAW_BORDERPROPBACK:
2019 retval = windecor_draw_borderpropback(cl, obj, (struct wdpDrawBorderPropBack *)msg);
2020 break;
2022 case WDM_DRAW_BORDERPROPKNOB:
2023 retval = windecor_draw_borderpropknob(cl, obj, (struct wdpDrawBorderPropKnob *)msg);
2024 break;
2026 case WDM_GETDEFSIZE_SYSIMAGE:
2027 retval = windecor_getdefsizes(cl, obj, (struct wdpGetDefSizeSysImage *) msg);
2028 break;
2030 case WDM_WINDOWSHAPE:
2031 retval = windecor_windowshape(cl, obj, (struct wdpWindowShape *) msg);
2032 break;
2034 case WDM_INITWINDOW:
2035 retval = windecor_initwindow(cl, obj, (struct wdpInitWindow *) msg);
2036 break;
2038 case WDM_EXITWINDOW:
2039 retval = windecor_exitwindow(cl, obj, (struct wdpExitWindow *) msg);
2040 break;
2042 default:
2043 retval = DoSuperMethodA(cl, obj, msg);
2044 break;
2047 return retval;
2050 struct IClass * MakeWindowDecorClass()
2052 struct IClass * cl = MakeClass(NULL, WINDECORCLASS, NULL, sizeof(struct windecor_data), 0);
2053 if (cl)
2055 cl->cl_Dispatcher.h_Entry = HookEntry;
2056 cl->cl_Dispatcher.h_SubEntry = (HOOKFUNC)windecor_dispatcher;
2059 return cl;