]> git.decadent.org.uk Git - ion3.git/blob - de/brush.c
3101324f378849dbf4c524c2674f686844522349
[ion3.git] / de / brush.c
1 /*
2  * ion/de/brush.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2007. 
5  *
6  * Ion is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <string.h>
13
14 #include <libtu/objp.h>
15 #include <libextl/extl.h>
16
17 #include <ioncore/common.h>
18 #include <ioncore/rootwin.h>
19 #include <ioncore/extlconv.h>
20 #include <ioncore/ioncore.h>
21
22 #include "brush.h"
23 #include "style.h"
24 #include "font.h"
25 #include "colour.h"
26 #include "private.h"
27
28
29 /*{{{ Brush creation and releasing */
30
31
32 static GrStyleSpec tabframe_spec=GR_STYLESPEC_INIT;
33 static GrStyleSpec tabinfo_spec=GR_STYLESPEC_INIT;
34 static GrStyleSpec tabmenuentry_spec=GR_STYLESPEC_INIT;
35
36
37 bool debrush_init(DEBrush *brush, Window win,
38                   const GrStyleSpec *spec, DEStyle *style)
39 {
40     GrStyleSpec tmp;
41     
42     brush->d=style;
43     brush->extras_fn=NULL;
44     brush->indicator_w=0;
45     brush->win=win;
46     brush->clip_set=FALSE;
47     
48     gr_stylespec_init(&brush->current_attr);
49     
50     style->usecount++;
51
52     if(!grbrush_init(&(brush->grbrush))){
53         style->usecount--;
54         return FALSE;
55     }
56     
57     ENSURE_INITSPEC(tabframe_spec, "tab-frame");
58     ENSURE_INITSPEC(tabinfo_spec, "tab-info");
59     ENSURE_INITSPEC(tabmenuentry_spec, "tab-menuentry");
60     
61     if(MATCHES(tabframe_spec, spec) || MATCHES(tabinfo_spec, spec)){
62         brush->extras_fn=debrush_tab_extras;
63         if(!style->tabbrush_data_ok)
64             destyle_create_tab_gcs(style);
65     }else if(MATCHES(tabmenuentry_spec, spec)){
66         brush->extras_fn=debrush_menuentry_extras;
67         brush->indicator_w=grbrush_get_text_width((GrBrush*)brush, 
68                                                   DE_SUB_IND, 
69                                                   DE_SUB_IND_LEN);
70     }
71     
72     return TRUE;
73 }
74
75
76 DEBrush *create_debrush(Window win, const GrStyleSpec *spec, DEStyle *style)
77 {
78     CREATEOBJ_IMPL(DEBrush, debrush, (p, win, spec, style));
79 }
80
81
82 static DEBrush *do_get_brush(Window win, WRootWin *rootwin, 
83                              const char *stylename, bool slave)
84 {
85     DEStyle *style;
86     DEBrush *brush;
87     GrStyleSpec spec;
88     
89     if(!gr_stylespec_load(&spec, stylename))
90         return NULL;
91     
92     style=de_get_style(rootwin, &spec);
93     
94     if(style==NULL){
95         gr_stylespec_unalloc(&spec);
96         return NULL;
97     }
98     
99     brush=create_debrush(win, &spec, style);
100
101     gr_stylespec_unalloc(&spec);
102     
103     /* Set background colour */
104     if(brush!=NULL && !slave){
105         grbrush_enable_transparency(&(brush->grbrush), 
106                                     GR_TRANSPARENCY_DEFAULT);
107     }
108     
109     return brush;
110 }
111
112
113 DEBrush *de_get_brush(Window win, WRootWin *rootwin, const char *stylename)
114 {
115     return do_get_brush(win, rootwin, stylename, FALSE);
116 }
117
118
119 DEBrush *debrush_get_slave(DEBrush *master, WRootWin *rootwin, 
120                            const char *stylename)
121 {
122     return do_get_brush(master->win, rootwin, stylename, TRUE);
123 }
124
125
126 void debrush_deinit(DEBrush *brush)
127 {
128     destyle_unref(brush->d);
129     brush->d=NULL;
130     gr_stylespec_unalloc(&brush->current_attr);
131     grbrush_deinit(&(brush->grbrush));
132 }
133
134
135 void debrush_release(DEBrush *brush)
136 {
137     destroy_obj((Obj*)brush);
138 }
139
140
141 /*}}}*/
142
143
144 /*{{{ Attributes */
145
146
147 void debrush_init_attr(DEBrush *brush, const GrStyleSpec *spec)
148 {
149     gr_stylespec_unalloc(&brush->current_attr);
150
151     if(spec!=NULL)
152         gr_stylespec_append(&brush->current_attr, spec);
153 }
154
155     
156 void debrush_set_attr(DEBrush *brush, GrAttr attr)
157 {
158     gr_stylespec_set(&brush->current_attr, attr);
159 }
160
161
162 void debrush_unset_attr(DEBrush *brush, GrAttr attr)
163 {
164     gr_stylespec_unset(&brush->current_attr, attr);
165 }
166
167
168 GrStyleSpec *debrush_get_current_attr(DEBrush *brush)
169 {
170     return &brush->current_attr;
171 }
172
173
174 /*}}}*/
175
176
177
178 /*{{{ Border widths and extra information */
179
180
181 void debrush_get_border_widths(DEBrush *brush, GrBorderWidths *bdw)
182 {
183     DEStyle *style=brush->d;
184     DEBorder *bd=&(style->border);
185     uint tmp=0;
186     uint tbf=1, lrf=1;
187     uint pad=bd->pad;
188     
189     switch(bd->sides){
190     case DEBORDER_TB:
191         lrf=0;
192         break;
193     case DEBORDER_LR:
194         tbf=0;
195         break;
196     }
197     
198     switch(bd->style){
199     case DEBORDER_RIDGE:
200     case DEBORDER_GROOVE:
201         tmp=bd->sh+bd->hl;
202         bdw->top=tbf*tmp+pad; bdw->bottom=tbf*tmp+pad; 
203         bdw->left=lrf*tmp+pad; bdw->right=lrf*tmp+pad;
204         break;
205     case DEBORDER_INLAID:
206         tmp=bd->sh; bdw->top=tbf*tmp+pad; bdw->left=lrf*tmp+pad;
207         tmp=bd->hl; bdw->bottom=tbf*tmp+pad; bdw->right=lrf*tmp+pad;
208         break;
209     case DEBORDER_ELEVATED:
210     default:
211         tmp=bd->hl; bdw->top=tbf*tmp+pad; bdw->left=lrf*tmp+pad;
212         tmp=bd->sh; bdw->bottom=tbf*tmp+pad; bdw->right=lrf*tmp+pad;
213         break;
214     }
215     
216     bdw->right+=brush->indicator_w;
217
218     bdw->tb_ileft=bdw->left;
219     bdw->tb_iright=bdw->right;
220     bdw->spacing=style->spacing;
221 }
222
223
224 bool debrush_get_extra(DEBrush *brush, const char *key, char type, void *data)
225 {
226     DEStyle *style=brush->d;
227     while(style!=NULL){
228         if(extl_table_get(style->data_table, 's', type, key, data))
229             return TRUE;
230         style=style->based_on;
231     }
232     return FALSE;
233 }
234
235
236
237 /*}}}*/
238
239
240 /*{{{ Class implementation */
241
242
243 static DynFunTab debrush_dynfuntab[]={
244     {grbrush_release, debrush_release},
245     {grbrush_draw_border, debrush_draw_border},
246     {grbrush_draw_borderline, debrush_draw_borderline},
247     {grbrush_get_border_widths, debrush_get_border_widths},
248     {grbrush_draw_string, debrush_draw_string},
249     {debrush_do_draw_string, debrush_do_draw_string_default},
250     {grbrush_get_font_extents, debrush_get_font_extents},
251     {(DynFun*)grbrush_get_text_width, (DynFun*)debrush_get_text_width},
252     {grbrush_draw_textbox, debrush_draw_textbox},
253     {grbrush_draw_textboxes, debrush_draw_textboxes},
254     {grbrush_set_window_shape, debrush_set_window_shape},
255     {grbrush_enable_transparency, debrush_enable_transparency},
256     {grbrush_clear_area, debrush_clear_area},
257     {grbrush_fill_area, debrush_fill_area},
258     {(DynFun*)grbrush_get_extra, (DynFun*)debrush_get_extra},
259     {(DynFun*)grbrush_get_slave, (DynFun*)debrush_get_slave},
260     {grbrush_begin, debrush_begin},
261     {grbrush_end, debrush_end},
262     {grbrush_init_attr, debrush_init_attr},
263     {grbrush_set_attr, debrush_set_attr},
264     {grbrush_unset_attr, debrush_unset_attr},
265     END_DYNFUNTAB
266 };
267
268
269 IMPLCLASS(DEBrush, GrBrush, debrush_deinit, debrush_dynfuntab);
270
271
272 /*}}}*/
273
274
275