2 * ion/ioncore/frame-draw.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
11 #include <libtu/objp.h>
12 #include <libtu/minmax.h>
13 #include <libtu/map.h>
18 #include "frame-draw.h"
26 #define BAR_INSIDE_BORDER(FRAME) \
27 ((FRAME)->barmode==FRAME_BAR_INSIDE || (FRAME)->barmode==FRAME_BAR_NONE)
28 #define BAR_EXISTS(FRAME) ((FRAME)->barmode!=FRAME_BAR_NONE)
29 #define BAR_H(FRAME) (FRAME)->bar_h
38 GR_DEFATTR(unselected
);
40 GR_DEFATTR(not_tagged
);
42 GR_DEFATTR(not_dragged
);
44 GR_DEFATTR(no_activity
);
47 static void ensure_create_attrs()
51 GR_ALLOCATTR(inactive
);
52 GR_ALLOCATTR(selected
);
53 GR_ALLOCATTR(unselected
);
55 GR_ALLOCATTR(not_tagged
);
56 GR_ALLOCATTR(dragged
);
57 GR_ALLOCATTR(not_dragged
);
58 GR_ALLOCATTR(no_activity
);
59 GR_ALLOCATTR(activity
);
64 void frame_update_attr(WFrame
*frame
, int i
, WRegion
*reg
)
67 bool selected
, tagged
, dragged
, activity
;
69 if(i
>=frame
->titles_n
){
70 /* Might happen when deinitialising */
74 ensure_create_attrs();
76 spec
=&frame
->titles
[i
].attr
;
78 selected
=(reg
==FRAME_CURRENT(frame
));
79 tagged
=(reg
!=NULL
&& reg
->flags
®ION_TAGGED
);
80 dragged
=(i
==frame
->tab_dragged_idx
);
81 activity
=(reg
!=NULL
&& region_is_activity_r(reg
));
83 gr_stylespec_unalloc(spec
);
84 gr_stylespec_set(spec
, selected
? GR_ATTR(selected
) : GR_ATTR(unselected
));
85 gr_stylespec_set(spec
, tagged
? GR_ATTR(tagged
) : GR_ATTR(not_tagged
));
86 gr_stylespec_set(spec
, dragged
? GR_ATTR(dragged
) : GR_ATTR(not_dragged
));
87 gr_stylespec_set(spec
, activity
? GR_ATTR(activity
) : GR_ATTR(no_activity
));
94 /*{{{ (WFrame) dynfun default implementations */
97 static uint
get_spacing(const WFrame
*frame
)
101 if(frame
->brush
==NULL
)
104 grbrush_get_border_widths(frame
->brush
, &bdw
);
110 void frame_border_geom(const WFrame
*frame
, WRectangle
*geom
)
114 geom
->w
=REGION_GEOM(frame
).w
;
115 geom
->h
=REGION_GEOM(frame
).h
;
117 if(!BAR_INSIDE_BORDER(frame
) && frame
->brush
!=NULL
){
118 geom
->y
+=frame
->bar_h
;
119 geom
->h
=MAXOF(0, geom
->h
-frame
->bar_h
);
124 void frame_border_inner_geom(const WFrame
*frame
, WRectangle
*geom
)
128 frame_border_geom(frame
, geom
);
130 if(frame
->brush
!=NULL
){
131 grbrush_get_border_widths(frame
->brush
, &bdw
);
135 geom
->w
=MAXOF(0, geom
->w
-(bdw
.left
+bdw
.right
));
136 geom
->h
=MAXOF(0, geom
->h
-(bdw
.top
+bdw
.bottom
));
141 void frame_bar_geom(const WFrame
*frame
, WRectangle
*geom
)
145 if(BAR_INSIDE_BORDER(frame
)){
146 off
=0; /*get_spacing(frame);*/
147 frame_border_inner_geom(frame
, geom
);
152 geom
->w
=(frame
->barmode
==FRAME_BAR_SHAPED
154 : REGION_GEOM(frame
).w
);
158 geom
->w
=MAXOF(0, geom
->w
-2*off
);
159 geom
->h
=BAR_H(frame
);
163 void frame_managed_geom(const WFrame
*frame
, WRectangle
*geom
)
165 uint spacing
=get_spacing(frame
);
167 frame_border_inner_geom(frame
, geom
);
176 if(BAR_INSIDE_BORDER(frame
) && BAR_EXISTS(frame
)){
177 geom
->y
+=frame
->bar_h
+spacing
;
178 geom
->h
-=frame
->bar_h
+spacing
;
181 geom
->w
=MAXOF(geom
->w
, 0);
182 geom
->h
=MAXOF(geom
->h
, 0);
186 int frame_shaded_height(const WFrame
*frame
)
188 if(frame
->barmode
==FRAME_BAR_NONE
){
190 }else if(!BAR_INSIDE_BORDER(frame
)){
195 grbrush_get_border_widths(frame
->brush
, &bdw
);
197 return frame
->bar_h
+bdw
.top
+bdw
.bottom
;
202 void frame_set_shape(WFrame
*frame
)
207 if(frame
->brush
!=NULL
){
208 if(BAR_EXISTS(frame
)){
209 frame_bar_geom(frame
, gs
+n
);
212 frame_border_geom(frame
, gs
+n
);
215 grbrush_set_window_shape(frame
->brush
, TRUE
, n
, gs
);
220 void frame_clear_shape(WFrame
*frame
)
222 if(frame
->brush
!=NULL
)
223 grbrush_set_window_shape(frame
->brush
, TRUE
, 0, NULL
);
227 static void free_title(WFrame
*frame
, int i
)
229 if(frame
->titles
[i
].text
!=NULL
){
230 free(frame
->titles
[i
].text
);
231 frame
->titles
[i
].text
=NULL
;
236 void frame_recalc_bar(WFrame
*frame
, bool complete
)
244 if(frame
->bar_brush
==NULL
|| frame
->titles
==NULL
)
247 set_shape
=frame
->tabs_params
.alg(frame
,complete
);
250 if(frame
->barmode
==FRAME_BAR_SHAPED
)
251 frame_set_shape(frame
);
253 frame_clear_shape(frame
);
258 if(FRAME_MCOUNT(frame
)==0){
259 free_title(frame
, i
);
260 textw
=frame
->titles
[i
].iw
;
262 title
=grbrush_make_label(frame
->bar_brush
, TR("<empty frame>"),
264 frame
->titles
[i
].text
=title
;
269 FRAME_MX_FOR_ALL(sub
, frame
, tmp
){
270 free_title(frame
, i
);
271 textw
=frame
->titles
[i
].iw
;
273 title
=region_make_label(sub
, textw
, frame
->bar_brush
);
274 frame
->titles
[i
].text
=title
;
281 void frame_draw_bar(const WFrame
*frame
, bool complete
)
285 if(frame
->bar_brush
==NULL
286 || !BAR_EXISTS(frame
)
287 || frame
->titles
==NULL
){
291 frame_bar_geom(frame
, &geom
);
293 grbrush_begin(frame
->bar_brush
, &geom
, GRBRUSH_AMEND
);
295 grbrush_init_attr(frame
->bar_brush
, &frame
->baseattr
);
297 grbrush_draw_textboxes(frame
->bar_brush
, &geom
, frame
->titles_n
,
298 frame
->titles
, complete
);
300 grbrush_end(frame
->bar_brush
);
303 void frame_draw(const WFrame
*frame
, bool complete
)
307 if(frame
->brush
==NULL
)
310 frame_border_geom(frame
, &geom
);
312 grbrush_begin(frame
->brush
, &geom
, (complete
? 0 : GRBRUSH_NO_CLEAR_OK
));
314 grbrush_init_attr(frame
->brush
, &frame
->baseattr
);
316 grbrush_draw_border(frame
->brush
, &geom
);
318 frame_draw_bar(frame
, TRUE
);
320 grbrush_end(frame
->brush
);
324 void frame_brushes_updated(WFrame
*frame
)
326 WFrameBarMode barmode
;
329 if(frame
->brush
==NULL
)
332 if(frame
->mode
==FRAME_MODE_FLOATING
){
333 barmode
=FRAME_BAR_SHAPED
;
334 }else if(frame
->mode
==FRAME_MODE_TILED
|| frame
->mode
==FRAME_MODE_UNKNOWN
||
335 frame
->mode
==FRAME_MODE_TRANSIENT_ALT
){
336 barmode
=FRAME_BAR_INSIDE
;
338 barmode
=FRAME_BAR_NONE
;
341 if(grbrush_get_extra(frame
->brush
, "bar", 's', &s
)){
342 if(strcmp(s
, "inside")==0)
343 barmode
=FRAME_BAR_INSIDE
;
344 else if(strcmp(s
, "outside")==0)
345 barmode
=FRAME_BAR_OUTSIDE
;
346 else if(strcmp(s
, "shaped")==0)
347 barmode
=FRAME_BAR_SHAPED
;
348 else if(strcmp(s
, "none")==0)
349 barmode
=FRAME_BAR_NONE
;
353 frame
->barmode
=barmode
;
355 if(barmode
==FRAME_BAR_NONE
|| frame
->bar_brush
==NULL
){
361 grbrush_get_border_widths(frame
->bar_brush
, &bdw
);
362 grbrush_get_font_extents(frame
->bar_brush
, &fnte
);
364 frame
->bar_h
=bdw
.top
+bdw
.bottom
+fnte
.max_height
;
367 /* tabs and bar width calculation stuff */
368 frame_tabs_calc_brushes_updated(frame
);
378 void frame_updategr(WFrame
*frame
)
380 frame_release_brushes(frame
);
382 frame_initialise_gr(frame
);
384 /* Update children */
385 region_updategr_default((WRegion
*)frame
);
387 mplex_fit_managed(&frame
->mplex
);
388 frame_recalc_bar(frame
, TRUE
);
389 frame_set_background(frame
, TRUE
);
393 static StringIntMap frame_tab_styles
[]={
394 {"tab-frame-unknown", FRAME_MODE_UNKNOWN
},
395 {"tab-frame-unknown-alt", FRAME_MODE_UNKNOWN_ALT
},
396 {"tab-frame-tiled", FRAME_MODE_TILED
},
397 {"tab-frame-tiled-alt", FRAME_MODE_TILED_ALT
},
398 {"tab-frame-floating", FRAME_MODE_FLOATING
},
399 {"tab-frame-floating-alt", FRAME_MODE_FLOATING_ALT
},
400 {"tab-frame-transient", FRAME_MODE_TRANSIENT
},
401 {"tab-frame-transient-alt", FRAME_MODE_TRANSIENT_ALT
},
406 const char *framemode_get_tab_style(WFrameMode mode
)
408 return stringintmap_key(frame_tab_styles
, mode
, "tab-frame");
412 const char *framemode_get_style(WFrameMode mode
)
414 const char *p
=framemode_get_tab_style(mode
);
420 void frame_initialise_gr(WFrame
*frame
)
422 Window win
=frame
->mplex
.win
.win
;
423 WRootWin
*rw
=region_rootwin_of((WRegion
*)frame
);
424 const char *style
=framemode_get_style(frame
->mode
);
425 const char *tab_style
=framemode_get_tab_style(frame
->mode
);
427 frame
->brush
=gr_get_brush(win
, rw
, style
);
429 if(frame
->brush
==NULL
)
432 frame
->bar_brush
=grbrush_get_slave(frame
->brush
, rw
, tab_style
);
434 if(frame
->bar_brush
==NULL
)
437 frame_brushes_updated(frame
);
441 void frame_release_brushes(WFrame
*frame
)
443 if(frame
->bar_brush
!=NULL
){
444 grbrush_release(frame
->bar_brush
);
445 frame
->bar_brush
=NULL
;
448 if(frame
->brush
!=NULL
){
449 grbrush_release(frame
->brush
);
455 bool frame_set_background(WFrame
*frame
, bool set_always
)
457 GrTransparency mode
=GR_TRANSPARENCY_DEFAULT
;
459 if(FRAME_CURRENT(frame
)!=NULL
){
460 if(OBJ_IS(FRAME_CURRENT(frame
), WClientWin
)){
461 WClientWin
*cwin
=(WClientWin
*)FRAME_CURRENT(frame
);
462 mode
=(cwin
->flags
&CLIENTWIN_PROP_TRANSPARENT
463 ? GR_TRANSPARENCY_YES
: GR_TRANSPARENCY_NO
);
464 }else if(!OBJ_IS(FRAME_CURRENT(frame
), WGroup
)){
465 mode
=GR_TRANSPARENCY_NO
;
469 if(mode
!=frame
->tr_mode
|| set_always
){
471 if(frame
->brush
!=NULL
){
472 grbrush_enable_transparency(frame
->brush
, mode
);
473 window_draw((WWindow
*)frame
, TRUE
);
482 void frame_setup_dragwin_style(WFrame
*frame
, GrStyleSpec
*spec
, int tab
)
484 gr_stylespec_append(spec
, &frame
->baseattr
);
485 gr_stylespec_append(spec
, &frame
->titles
[tab
].attr
);
492 /*{{{ Activated/inactivated */
495 void frame_inactivated(WFrame
*frame
)
497 ensure_create_attrs();
499 gr_stylespec_set(&frame
->baseattr
, GR_ATTR(inactive
));
500 gr_stylespec_unset(&frame
->baseattr
, GR_ATTR(active
));
502 window_draw((WWindow
*)frame
, FALSE
);
506 void frame_activated(WFrame
*frame
)
508 ensure_create_attrs();
510 gr_stylespec_set(&frame
->baseattr
, GR_ATTR(active
));
511 gr_stylespec_unset(&frame
->baseattr
, GR_ATTR(inactive
));
513 window_draw((WWindow
*)frame
, FALSE
);