UI:
[blender-staging.git] / source / blender / editors / interface / interface_style.c
1 /**
2 * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  *
18  * The Original Code is Copyright (C) 2009 Blender Foundation.
19  * All rights reserved.
20  * 
21  * Contributor(s): Blender Foundation
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 #include <limits.h>
27 #include <math.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include "MEM_guardedalloc.h"
32
33 #include "DNA_ID.h"
34 #include "DNA_screen_types.h"
35 #include "DNA_userdef_types.h"
36 #include "DNA_windowmanager_types.h"
37
38 #include "BLI_arithb.h"
39 #include "BLI_listbase.h"
40 #include "BLI_rect.h"
41 #include "BLI_string.h"
42
43 #include "BKE_context.h"
44 #include "BKE_global.h"
45 #include "BKE_utildefines.h"
46
47 #include "BIF_gl.h"
48 #include "BIF_glutil.h"
49
50 #include "BLF_api.h"
51
52 #include "UI_interface.h"
53 #include "UI_interface_icons.h"
54 #include "UI_resources.h"
55 #include "UI_view2d.h"
56
57 #include "ED_datafiles.h"
58 #include "ED_util.h"
59 #include "ED_types.h"
60
61 #include "interface_intern.h"
62
63
64 /* style + theme + layout-engine = UI */
65
66 /* 
67  This is a complete set of layout rules, the 'state' of the Layout 
68  Engine. Multiple styles are possible, defined via C or Python. Styles 
69  get a name, and will typically get activated per region type, like 
70  "Header", or "Listview" or "Toolbar". Properties of Style definitions 
71  are:
72  
73  - default collumn properties, internal spacing, aligning, min/max width
74  - button alignment rules (for groups)
75  - label placement rules
76  - internal labeling or external labeling default
77  - default minimum widths for buttons/labels (in amount of characters)
78  - font types, styles and relative sizes for Panel titles, labels, etc.
79
80 */
81
82
83 /* ********************************************** */
84
85 static uiStyle *ui_style_new(ListBase *styles, const char *name)
86 {
87         uiStyle *style= MEM_callocN(sizeof(uiStyle), "new style");
88         
89         BLI_addtail(styles, style);
90         BLI_strncpy(style->name, name, MAX_STYLE_NAME);
91         
92         style->paneltitle.uifont_id= UIFONT_DEFAULT;
93         style->paneltitle.points= 14;
94         style->paneltitle.shadow= 5;
95         style->paneltitle.shadx= 2;
96         style->paneltitle.shady= -2;
97         style->paneltitle.shadowalpha= 0.25f;
98         style->paneltitle.shadowcolor= 0.0f;
99         
100         style->grouplabel.uifont_id= UIFONT_DEFAULT;
101         style->grouplabel.points= 12;
102         style->grouplabel.shadow= 3;
103         style->grouplabel.shadx= 1;
104         style->grouplabel.shady= -1;
105         style->grouplabel.shadowalpha= 0.25f;
106         
107         style->widgetlabel.uifont_id= UIFONT_DEFAULT;
108         style->widgetlabel.points= 11;
109         style->widgetlabel.shadow= 3;
110         style->widgetlabel.shadx= 1;
111         style->widgetlabel.shady= -1;
112         style->widgetlabel.shadowalpha= 0.3f;
113         style->widgetlabel.shadowcolor= 1.0f;
114         
115         style->widget.uifont_id= UIFONT_DEFAULT;
116         style->widget.points= 11;
117         style->widget.shadowalpha= 0.25f;
118
119         style->columnspace= 5;
120         style->templatespace= 5;
121         style->boxspace= 5;
122         style->buttonspacex= 5;
123         style->buttonspacey= 2;
124         
125         return style;
126 }
127
128 static uiFont *uifont_to_blfont(int id)
129 {
130         uiFont *font= U.uifonts.first;
131         
132         for(; font; font= font->next) {
133                 if(font->uifont_id==id) {
134                         return font;
135                 }
136         }
137         return U.uifonts.first;
138 }
139
140 /* *************** draw ************************ */
141
142 static void ui_font_shadow_draw(uiFontStyle *fs, int x, int y, char *str)
143 {
144         float color[4];
145         
146         glGetFloatv(GL_CURRENT_COLOR, color);
147         
148         glColor4f(fs->shadowcolor, fs->shadowcolor, fs->shadowcolor, fs->shadowalpha);
149         
150         BLF_blur(fs->shadow);
151         BLF_position(x+fs->shadx, y+fs->shady, 0.0f);
152         BLF_draw(str);
153         BLF_blur(0);
154         
155         glColor4fv(color);
156 }
157
158 void uiStyleFontDraw(uiFontStyle *fs, rcti *rect, char *str)
159 {
160         float height;
161         int xofs=0, yofs;
162         
163         uiStyleFontSet(fs);
164         
165         height= BLF_height("A");
166         yofs= floor( 0.5f*(rect->ymax - rect->ymin - height));
167
168         if(fs->align==UI_STYLE_TEXT_CENTER)
169                 xofs= floor( 0.5f*(rect->xmax - rect->xmin - BLF_width(str)));
170         else if(fs->align==UI_STYLE_TEXT_RIGHT)
171                 xofs= rect->xmax - rect->xmin - BLF_width(str);
172         
173         /* clip is very strict, so we give it some space */
174         if (BLF_type_get() == BLF_FONT_INTERNAL)
175                 BLF_clipping(rect->xmin-4, rect->ymin-4, rect->xmax+8, rect->ymax+4);
176         else
177                 BLF_clipping(rect->xmin-4, rect->ymin-4, rect->xmax+4, rect->ymax+4);
178
179         BLF_enable(BLF_CLIPPING);
180         
181         if(fs->shadow) 
182                 ui_font_shadow_draw(fs, rect->xmin+xofs, rect->ymin+yofs, str);
183         
184         BLF_position(rect->xmin+xofs, rect->ymin+yofs, 0.0f);
185         BLF_draw(str);
186
187         BLF_disable(BLF_CLIPPING);
188 }
189
190 /* ************** helpers ************************ */
191
192 /* temporarily, does widget font */
193 int UI_GetStringWidth(char *str)
194 {
195         uiStyle *style= U.uistyles.first;
196         
197         uiStyleFontSet(&style->widget);
198         return BLF_width(str);  
199 }
200
201 /* temporarily, does widget font */
202 void UI_DrawString(float x, float y, char *str)
203 {
204         uiStyle *style= U.uistyles.first;
205         
206         uiStyleFontSet(&style->widget);
207         BLF_position(x, y, 0.0f);
208         BLF_draw(str);
209 }
210
211 /* ************** init exit ************************ */
212
213 /* called on each .B.blend read */
214 /* reading without uifont will create one */
215 void uiStyleInit(void)
216 {
217         uiFont *font= U.uifonts.first;
218         uiStyle *style= U.uistyles.first;
219         
220         /* recover from uninitialized dpi */
221         CLAMP(U.dpi, 72, 240);
222         
223         /* default builtin */
224         if(font==NULL) {
225                 font= MEM_callocN(sizeof(uiFont), "ui font");
226                 BLI_addtail(&U.uifonts, font);
227                 
228                 strcpy(font->filename, "default");
229                 font->uifont_id= UIFONT_DEFAULT;
230         }
231         
232         for(font= U.uifonts.first; font; font= font->next) {
233                 
234                 if(font->uifont_id==UIFONT_DEFAULT) {
235                         font->blf_id= BLF_load_mem("default", (unsigned char*)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
236                 }               
237                 else {
238                         font->blf_id= BLF_load(font->filename);
239                         if(font->blf_id == -1)
240                                 font->blf_id= BLF_load_mem("default", (unsigned char*)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
241                 }
242
243                 if (font->blf_id == -1) {
244                         /* when all fail, we go back to the internal font. */
245                         font->blf_id= BLF_load_mem("helv", NULL, 0);
246                 }
247
248                 if (font->blf_id == -1)
249                         printf("uiStyleInit error, no fonts available\n");
250                 else {
251                         BLF_set(font->blf_id);
252                         /* ? just for speed to initialize?
253                          * Yes but only if we used the freetype2 library,
254                          * this build the glyph cache and create the texture.
255                          */
256                         BLF_size(11, U.dpi);
257                         BLF_size(12, U.dpi);
258                         BLF_size(14, U.dpi);
259                 }
260         }
261         
262         if(style==NULL) {
263                 ui_style_new(&U.uistyles, "Default Style");
264         }
265 }
266
267
268 void uiStyleExit(void)
269 {
270         BLI_freelistN(&U.uifonts);
271         BLI_freelistN(&U.uistyles);
272         
273 }
274
275 void uiStyleFontSet(uiFontStyle *fs)
276 {
277         uiFont *font= uifont_to_blfont(fs->uifont_id);
278         
279         BLF_set(font->blf_id);
280         BLF_size(fs->points, U.dpi);
281 }
282