4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
11 #include <libtu/objp.h>
12 #include <libextl/extl.h>
14 #include <ioncore/common.h>
15 #include <ioncore/rootwin.h>
16 #include <ioncore/extlconv.h>
17 #include <ioncore/ioncore.h>
26 /*{{{ Brush creation and releasing */
29 #define MATCHES(S, A) (gr_stylespec_score(&(S), A)>0)
31 #define ENSURE_INITSPEC(S, NM) \
32 if((S).attrs==NULL) gr_stylespec_load(&(S), NM);
35 static GrStyleSpec tabframe_spec
=GR_STYLESPEC_INIT
;
36 static GrStyleSpec tabinfo_spec
=GR_STYLESPEC_INIT
;
37 static GrStyleSpec tabmenuentry_spec
=GR_STYLESPEC_INIT
;
40 bool debrush_init(DEBrush
*brush
, Window win
,
41 const GrStyleSpec
*spec
, DEStyle
*style
)
44 brush
->extras_fn
=NULL
;
47 brush
->clip_set
=FALSE
;
49 gr_stylespec_init(&brush
->current_attr
);
53 if(!grbrush_init(&(brush
->grbrush
))){
58 ENSURE_INITSPEC(tabframe_spec
, "tab-frame");
59 ENSURE_INITSPEC(tabinfo_spec
, "tab-info");
60 ENSURE_INITSPEC(tabmenuentry_spec
, "tab-menuentry");
62 if(MATCHES(tabframe_spec
, spec
) || MATCHES(tabinfo_spec
, spec
)){
63 brush
->extras_fn
=debrush_tab_extras
;
64 if(!style
->tabbrush_data_ok
)
65 destyle_create_tab_gcs(style
);
66 }else if(MATCHES(tabmenuentry_spec
, spec
)){
67 brush
->extras_fn
=debrush_menuentry_extras
;
68 brush
->indicator_w
=grbrush_get_text_width((GrBrush
*)brush
,
77 DEBrush
*create_debrush(Window win
, const GrStyleSpec
*spec
, DEStyle
*style
)
79 CREATEOBJ_IMPL(DEBrush
, debrush
, (p
, win
, spec
, style
));
83 static DEBrush
*do_get_brush(Window win
, WRootWin
*rootwin
,
84 const char *stylename
, bool slave
)
90 if(!gr_stylespec_load(&spec
, stylename
))
93 style
=de_get_style(rootwin
, &spec
);
96 gr_stylespec_unalloc(&spec
);
100 brush
=create_debrush(win
, &spec
, style
);
102 gr_stylespec_unalloc(&spec
);
104 /* Set background colour */
105 if(brush
!=NULL
&& !slave
){
106 grbrush_enable_transparency(&(brush
->grbrush
),
107 GR_TRANSPARENCY_DEFAULT
);
114 DEBrush
*de_get_brush(Window win
, WRootWin
*rootwin
, const char *stylename
)
116 return do_get_brush(win
, rootwin
, stylename
, FALSE
);
120 DEBrush
*debrush_get_slave(DEBrush
*master
, WRootWin
*rootwin
,
121 const char *stylename
)
123 return do_get_brush(master
->win
, rootwin
, stylename
, TRUE
);
127 void debrush_deinit(DEBrush
*brush
)
129 destyle_unref(brush
->d
);
131 gr_stylespec_unalloc(&brush
->current_attr
);
132 grbrush_deinit(&(brush
->grbrush
));
136 void debrush_release(DEBrush
*brush
)
138 destroy_obj((Obj
*)brush
);
148 void debrush_init_attr(DEBrush
*brush
, const GrStyleSpec
*spec
)
150 gr_stylespec_unalloc(&brush
->current_attr
);
153 gr_stylespec_append(&brush
->current_attr
, spec
);
157 void debrush_set_attr(DEBrush
*brush
, GrAttr attr
)
159 gr_stylespec_set(&brush
->current_attr
, attr
);
163 void debrush_unset_attr(DEBrush
*brush
, GrAttr attr
)
165 gr_stylespec_unset(&brush
->current_attr
, attr
);
169 GrStyleSpec
*debrush_get_current_attr(DEBrush
*brush
)
171 return &brush
->current_attr
;
179 /*{{{ Border widths and extra information */
182 void debrush_get_border_widths(DEBrush
*brush
, GrBorderWidths
*bdw
)
184 DEStyle
*style
=brush
->d
;
185 DEBorder
*bd
=&(style
->border
);
189 uint spc
=style
->spacing
;
200 /* Ridge/groove styles use 'padding' for the spacing between the
201 * 'highlight' and 'shadow' portions of the border, and 'spacing'
202 * between the border and contents. Inlaid style also uses 'spacing'
203 * between the contents and the border, and padding as its outer
204 * component. Elevated style does not use spacing.
208 case DEBORDER_GROOVE
:
209 tmp
=bd
->sh
+bd
->hl
+pad
;
210 bdw
->top
=tbf
*tmp
+spc
; bdw
->bottom
=tbf
*tmp
+spc
;
211 bdw
->left
=lrf
*tmp
+spc
; bdw
->right
=lrf
*tmp
+spc
;
213 case DEBORDER_INLAID
:
214 tmp
=bd
->sh
+pad
; bdw
->top
=tbf
*tmp
+spc
; bdw
->left
=lrf
*tmp
+spc
;
215 tmp
=bd
->hl
+pad
; bdw
->bottom
=tbf
*tmp
+spc
; bdw
->right
=lrf
*tmp
+spc
;
217 case DEBORDER_ELEVATED
:
219 tmp
=bd
->hl
; bdw
->top
=tbf
*tmp
+pad
; bdw
->left
=lrf
*tmp
+pad
;
220 tmp
=bd
->sh
; bdw
->bottom
=tbf
*tmp
+pad
; bdw
->right
=lrf
*tmp
+pad
;
224 bdw
->right
+=brush
->indicator_w
;
226 bdw
->tb_ileft
=bdw
->left
;
227 bdw
->tb_iright
=bdw
->right
;
228 bdw
->spacing
=style
->spacing
;
232 bool debrush_get_extra(DEBrush
*brush
, const char *key
, char type
, void *data
)
234 DEStyle
*style
=brush
->d
;
236 if(extl_table_get(style
->extras_table
, 's', type
, key
, data
))
238 style
=style
->based_on
;
248 /*{{{ Class implementation */
251 static DynFunTab debrush_dynfuntab
[]={
252 {grbrush_release
, debrush_release
},
253 {grbrush_draw_border
, debrush_draw_border
},
254 {grbrush_draw_borderline
, debrush_draw_borderline
},
255 {grbrush_get_border_widths
, debrush_get_border_widths
},
256 {grbrush_draw_string
, debrush_draw_string
},
257 {debrush_do_draw_string
, debrush_do_draw_string_default
},
258 {grbrush_get_font_extents
, debrush_get_font_extents
},
259 {(DynFun
*)grbrush_get_text_width
, (DynFun
*)debrush_get_text_width
},
260 {grbrush_draw_textbox
, debrush_draw_textbox
},
261 {grbrush_draw_textboxes
, debrush_draw_textboxes
},
262 {grbrush_set_window_shape
, debrush_set_window_shape
},
263 {grbrush_enable_transparency
, debrush_enable_transparency
},
264 {grbrush_clear_area
, debrush_clear_area
},
265 {grbrush_fill_area
, debrush_fill_area
},
266 {(DynFun
*)grbrush_get_extra
, (DynFun
*)debrush_get_extra
},
267 {(DynFun
*)grbrush_get_slave
, (DynFun
*)debrush_get_slave
},
268 {grbrush_begin
, debrush_begin
},
269 {grbrush_end
, debrush_end
},
270 {grbrush_init_attr
, debrush_init_attr
},
271 {grbrush_set_attr
, debrush_set_attr
},
272 {grbrush_unset_attr
, debrush_unset_attr
},
277 IMPLCLASS(DEBrush
, GrBrush
, debrush_deinit
, debrush_dynfuntab
);