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
;
330 if(frame
->brush
==NULL
)
333 if(frame
->mode
==FRAME_MODE_FLOATING
){
334 barmode
=FRAME_BAR_SHAPED
;
335 }else if(frame
->mode
==FRAME_MODE_TILED
|| frame
->mode
==FRAME_MODE_UNKNOWN
||
336 frame
->mode
==FRAME_MODE_TRANSIENT_ALT
){
337 barmode
=FRAME_BAR_INSIDE
;
339 barmode
=FRAME_BAR_NONE
;
342 if(grbrush_get_extra(frame
->brush
, "bar", 's', &s
)){
343 if(strcmp(s
, "inside")==0)
344 barmode
=FRAME_BAR_INSIDE
;
345 else if(strcmp(s
, "outside")==0)
346 barmode
=FRAME_BAR_OUTSIDE
;
347 else if(strcmp(s
, "shaped")==0)
348 barmode
=FRAME_BAR_SHAPED
;
349 else if(strcmp(s
, "none")==0)
350 barmode
=FRAME_BAR_NONE
;
354 frame
->barmode
=barmode
;
356 if(barmode
==FRAME_BAR_NONE
|| frame
->bar_brush
==NULL
){
362 grbrush_get_border_widths(frame
->bar_brush
, &bdw
);
363 grbrush_get_font_extents(frame
->bar_brush
, &fnte
);
365 frame
->bar_h
=bdw
.top
+bdw
.bottom
+fnte
.max_height
;
368 /* tabs and bar width calculation stuff */
369 frame_tabs_calc_brushes_updated(frame
);
379 void frame_updategr(WFrame
*frame
)
381 frame_release_brushes(frame
);
383 frame_initialise_gr(frame
);
385 /* Update children */
386 region_updategr_default((WRegion
*)frame
);
388 mplex_fit_managed(&frame
->mplex
);
389 frame_recalc_bar(frame
, TRUE
);
390 frame_set_background(frame
, TRUE
);
394 static StringIntMap frame_tab_styles
[]={
395 {"tab-frame-unknown", FRAME_MODE_UNKNOWN
},
396 {"tab-frame-unknown-alt", FRAME_MODE_UNKNOWN_ALT
},
397 {"tab-frame-tiled", FRAME_MODE_TILED
},
398 {"tab-frame-tiled-alt", FRAME_MODE_TILED_ALT
},
399 {"tab-frame-floating", FRAME_MODE_FLOATING
},
400 {"tab-frame-floating-alt", FRAME_MODE_FLOATING_ALT
},
401 {"tab-frame-transient", FRAME_MODE_TRANSIENT
},
402 {"tab-frame-transient-alt", FRAME_MODE_TRANSIENT_ALT
},
407 const char *framemode_get_tab_style(WFrameMode mode
)
409 return stringintmap_key(frame_tab_styles
, mode
, "tab-frame");
413 const char *framemode_get_style(WFrameMode mode
)
415 const char *p
=framemode_get_tab_style(mode
);
421 void frame_initialise_gr(WFrame
*frame
)
423 Window win
=frame
->mplex
.win
.win
;
424 WRootWin
*rw
=region_rootwin_of((WRegion
*)frame
);
425 const char *style
=framemode_get_style(frame
->mode
);
426 const char *tab_style
=framemode_get_tab_style(frame
->mode
);
428 frame
->brush
=gr_get_brush(win
, rw
, style
);
430 if(frame
->brush
==NULL
)
433 frame
->bar_brush
=grbrush_get_slave(frame
->brush
, rw
, tab_style
);
435 if(frame
->bar_brush
==NULL
)
438 frame_brushes_updated(frame
);
442 void frame_release_brushes(WFrame
*frame
)
444 if(frame
->bar_brush
!=NULL
){
445 grbrush_release(frame
->bar_brush
);
446 frame
->bar_brush
=NULL
;
449 if(frame
->brush
!=NULL
){
450 grbrush_release(frame
->brush
);
456 bool frame_set_background(WFrame
*frame
, bool set_always
)
458 GrTransparency mode
=GR_TRANSPARENCY_DEFAULT
;
460 if(FRAME_CURRENT(frame
)!=NULL
){
461 if(OBJ_IS(FRAME_CURRENT(frame
), WClientWin
)){
462 WClientWin
*cwin
=(WClientWin
*)FRAME_CURRENT(frame
);
463 mode
=(cwin
->flags
&CLIENTWIN_PROP_TRANSPARENT
464 ? GR_TRANSPARENCY_YES
: GR_TRANSPARENCY_NO
);
465 }else if(!OBJ_IS(FRAME_CURRENT(frame
), WGroup
)){
466 mode
=GR_TRANSPARENCY_NO
;
470 if(mode
!=frame
->tr_mode
|| set_always
){
472 if(frame
->brush
!=NULL
){
473 grbrush_enable_transparency(frame
->brush
, mode
);
474 window_draw((WWindow
*)frame
, TRUE
);
483 void frame_setup_dragwin_style(WFrame
*frame
, GrStyleSpec
*spec
, int tab
)
485 gr_stylespec_append(spec
, &frame
->baseattr
);
486 gr_stylespec_append(spec
, &frame
->titles
[tab
].attr
);
493 /*{{{ Activated/inactivated */
496 void frame_inactivated(WFrame
*frame
)
498 ensure_create_attrs();
500 gr_stylespec_set(&frame
->baseattr
, GR_ATTR(inactive
));
501 gr_stylespec_unset(&frame
->baseattr
, GR_ATTR(active
));
503 window_draw((WWindow
*)frame
, FALSE
);
507 void frame_activated(WFrame
*frame
)
509 ensure_create_attrs();
511 gr_stylespec_set(&frame
->baseattr
, GR_ATTR(active
));
512 gr_stylespec_unset(&frame
->baseattr
, GR_ATTR(inactive
));
514 window_draw((WWindow
*)frame
, FALSE
);