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)
30 #define MATCHES2(S, A1, A2) (gr_stylespec_score2(&(S), A1, A2)>0)
32 #define ENSURE_INITSPEC(S, NM) \
33 if((S).attrs==NULL) gr_stylespec_load(&(S), NM);
36 static GrStyleSpec tabframe_spec
=GR_STYLESPEC_INIT
;
37 static GrStyleSpec tabinfo_spec
=GR_STYLESPEC_INIT
;
38 static GrStyleSpec tabmenuentry_spec
=GR_STYLESPEC_INIT
;
41 bool debrush_init(DEBrush
*brush
, Window win
,
42 const GrStyleSpec
*spec
, DEStyle
*style
)
47 brush
->extras_fn
=NULL
;
50 brush
->clip_set
=FALSE
;
52 gr_stylespec_init(&brush
->current_attr
);
56 if(!grbrush_init(&(brush
->grbrush
))){
61 ENSURE_INITSPEC(tabframe_spec
, "tab-frame");
62 ENSURE_INITSPEC(tabinfo_spec
, "tab-info");
63 ENSURE_INITSPEC(tabmenuentry_spec
, "tab-menuentry");
65 if(MATCHES(tabframe_spec
, spec
) || MATCHES(tabinfo_spec
, spec
)){
66 brush
->extras_fn
=debrush_tab_extras
;
67 if(!style
->tabbrush_data_ok
)
68 destyle_create_tab_gcs(style
);
69 }else if(MATCHES(tabmenuentry_spec
, spec
)){
70 brush
->extras_fn
=debrush_menuentry_extras
;
71 brush
->indicator_w
=grbrush_get_text_width((GrBrush
*)brush
,
80 DEBrush
*create_debrush(Window win
, const GrStyleSpec
*spec
, DEStyle
*style
)
82 CREATEOBJ_IMPL(DEBrush
, debrush
, (p
, win
, spec
, style
));
86 static DEBrush
*do_get_brush(Window win
, WRootWin
*rootwin
,
87 const char *stylename
, bool slave
)
93 if(!gr_stylespec_load(&spec
, stylename
))
96 style
=de_get_style(rootwin
, &spec
);
99 gr_stylespec_unalloc(&spec
);
103 brush
=create_debrush(win
, &spec
, style
);
105 gr_stylespec_unalloc(&spec
);
107 /* Set background colour */
108 if(brush
!=NULL
&& !slave
){
109 grbrush_enable_transparency(&(brush
->grbrush
),
110 GR_TRANSPARENCY_DEFAULT
);
117 DEBrush
*de_get_brush(Window win
, WRootWin
*rootwin
, const char *stylename
)
119 return do_get_brush(win
, rootwin
, stylename
, FALSE
);
123 DEBrush
*debrush_get_slave(DEBrush
*master
, WRootWin
*rootwin
,
124 const char *stylename
)
126 return do_get_brush(master
->win
, rootwin
, stylename
, TRUE
);
130 void debrush_deinit(DEBrush
*brush
)
132 destyle_unref(brush
->d
);
134 gr_stylespec_unalloc(&brush
->current_attr
);
135 grbrush_deinit(&(brush
->grbrush
));
139 void debrush_release(DEBrush
*brush
)
141 destroy_obj((Obj
*)brush
);
151 void debrush_init_attr(DEBrush
*brush
, const GrStyleSpec
*spec
)
153 gr_stylespec_unalloc(&brush
->current_attr
);
156 gr_stylespec_append(&brush
->current_attr
, spec
);
160 void debrush_set_attr(DEBrush
*brush
, GrAttr attr
)
162 gr_stylespec_set(&brush
->current_attr
, attr
);
166 void debrush_unset_attr(DEBrush
*brush
, GrAttr attr
)
168 gr_stylespec_unset(&brush
->current_attr
, attr
);
172 GrStyleSpec
*debrush_get_current_attr(DEBrush
*brush
)
174 return &brush
->current_attr
;
182 /*{{{ Border widths and extra information */
185 void debrush_get_border_widths(DEBrush
*brush
, GrBorderWidths
*bdw
)
187 DEStyle
*style
=brush
->d
;
188 DEBorder
*bd
=&(style
->border
);
192 uint spc
=style
->spacing
;
203 /* Ridge/groove styles use 'padding' for the spacing between the
204 * 'highlight' and 'shadow' portions of the border, and 'spacing'
205 * between the border and contents. Inlaid style also uses 'spacing'
206 * between the contents and the border, and padding as its outer
207 * component. Elevated style does not use spacing.
211 case DEBORDER_GROOVE
:
212 tmp
=bd
->sh
+bd
->hl
+pad
;
213 bdw
->top
=tbf
*tmp
+spc
; bdw
->bottom
=tbf
*tmp
+spc
;
214 bdw
->left
=lrf
*tmp
+spc
; bdw
->right
=lrf
*tmp
+spc
;
216 case DEBORDER_INLAID
:
217 tmp
=bd
->sh
+pad
; bdw
->top
=tbf
*tmp
+spc
; bdw
->left
=lrf
*tmp
+spc
;
218 tmp
=bd
->hl
+pad
; bdw
->bottom
=tbf
*tmp
+spc
; bdw
->right
=lrf
*tmp
+spc
;
220 case DEBORDER_ELEVATED
:
222 tmp
=bd
->hl
; bdw
->top
=tbf
*tmp
+pad
; bdw
->left
=lrf
*tmp
+pad
;
223 tmp
=bd
->sh
; bdw
->bottom
=tbf
*tmp
+pad
; bdw
->right
=lrf
*tmp
+pad
;
227 bdw
->right
+=brush
->indicator_w
;
229 bdw
->tb_ileft
=bdw
->left
;
230 bdw
->tb_iright
=bdw
->right
;
231 bdw
->spacing
=style
->spacing
;
235 bool debrush_get_extra(DEBrush
*brush
, const char *key
, char type
, void *data
)
237 DEStyle
*style
=brush
->d
;
239 if(extl_table_get(style
->extras_table
, 's', type
, key
, data
))
241 style
=style
->based_on
;
251 /*{{{ Class implementation */
254 static DynFunTab debrush_dynfuntab
[]={
255 {grbrush_release
, debrush_release
},
256 {grbrush_draw_border
, debrush_draw_border
},
257 {grbrush_draw_borderline
, debrush_draw_borderline
},
258 {grbrush_get_border_widths
, debrush_get_border_widths
},
259 {grbrush_draw_string
, debrush_draw_string
},
260 {debrush_do_draw_string
, debrush_do_draw_string_default
},
261 {grbrush_get_font_extents
, debrush_get_font_extents
},
262 {(DynFun
*)grbrush_get_text_width
, (DynFun
*)debrush_get_text_width
},
263 {grbrush_draw_textbox
, debrush_draw_textbox
},
264 {grbrush_draw_textboxes
, debrush_draw_textboxes
},
265 {grbrush_set_window_shape
, debrush_set_window_shape
},
266 {grbrush_enable_transparency
, debrush_enable_transparency
},
267 {grbrush_clear_area
, debrush_clear_area
},
268 {grbrush_fill_area
, debrush_fill_area
},
269 {(DynFun
*)grbrush_get_extra
, (DynFun
*)debrush_get_extra
},
270 {(DynFun
*)grbrush_get_slave
, (DynFun
*)debrush_get_slave
},
271 {grbrush_begin
, debrush_begin
},
272 {grbrush_end
, debrush_end
},
273 {grbrush_init_attr
, debrush_init_attr
},
274 {grbrush_set_attr
, debrush_set_attr
},
275 {grbrush_unset_attr
, debrush_unset_attr
},
280 IMPLCLASS(DEBrush
, GrBrush
, debrush_deinit
, debrush_dynfuntab
);