]> icculus.org git repositories - mikachu/openbox.git/blob - otk/style.cc
change how the widgets' _dirty flag works so that all inheritence levels of the widge...
[mikachu/openbox.git] / otk / style.cc
1 #ifdef    HAVE_CONFIG_H
2 #include "../config.h"
3 #endif // HAVE_CONFIG_H
4
5 #include <assert.h>
6 #include <iostream>
7
8 #include "display.hh"
9 #include "util.hh"
10 #include "style.hh"
11
12 namespace otk {
13
14 Style::Style() : font(NULL)
15 {
16 }
17
18 Style::Style(BImageControl *ctrl)
19   : image_control(ctrl), font(0),
20     screen_number(ctrl->getScreenInfo()->getScreenNumber())
21 {
22 }
23
24 Style::~Style() {
25   if (font)
26     delete font;
27
28   if (close_button.mask != None)
29     XFreePixmap(OBDisplay::display, close_button.mask);
30   if (max_button.mask != None)
31     XFreePixmap(OBDisplay::display, max_button.mask);
32   if (icon_button.mask != None)
33     XFreePixmap(OBDisplay::display, icon_button.mask);
34   if (stick_button.mask != None)
35     XFreePixmap(OBDisplay::display, stick_button.mask);
36
37   max_button.mask = None;
38   close_button.mask = None;
39   icon_button.mask = None;
40   stick_button.mask = None;
41 }
42
43 void Style::load(const Configuration &style) {
44   std::string s;
45
46   // load fonts/fontsets
47   if (font)
48     delete font;
49
50   font = readDatabaseFont("window.", style);
51
52   // load window config
53   t_focus = readDatabaseTexture("window.title.focus", "white", style);
54   t_unfocus = readDatabaseTexture("window.title.unfocus", "black", style);
55
56   l_focus = readDatabaseTexture("window.label.focus", "white", style);
57   l_unfocus = readDatabaseTexture("window.label.unfocus", "black", style);
58
59   h_focus = readDatabaseTexture("window.handle.focus", "white", style);
60   h_unfocus = readDatabaseTexture("window.handle.unfocus", "black", style);
61
62   g_focus = readDatabaseTexture("window.grip.focus", "white", style);
63   g_unfocus = readDatabaseTexture("window.grip.unfocus", "black", style);
64
65   b_focus = readDatabaseTexture("window.button.focus", "white", style);
66   b_unfocus = readDatabaseTexture("window.button.unfocus", "black", style);
67   b_pressed = readDatabaseTexture("window.button.pressed", "black", style);
68
69   //if neither of these can be found, we will use the previous resource
70   b_pressed_focus = readDatabaseTexture("window.button.pressed.focus",
71                                         "black", style, true);
72   b_pressed_unfocus = readDatabaseTexture("window.button.pressed.unfocus",
73                                           "black", style, true);
74
75   if (close_button.mask != None)
76     XFreePixmap(OBDisplay::display, close_button.mask);
77   if (max_button.mask != None)
78     XFreePixmap(OBDisplay::display, max_button.mask);
79   if (icon_button.mask != None)
80     XFreePixmap(OBDisplay::display, icon_button.mask);
81   if (stick_button.mask != None)
82     XFreePixmap(OBDisplay::display, stick_button.mask);
83
84   close_button.mask = max_button.mask = icon_button.mask
85                     = icon_button.mask = None;
86   
87   readDatabaseMask("window.button.close.mask", close_button, style);
88   readDatabaseMask("window.button.max.mask", max_button, style);
89   readDatabaseMask("window.button.icon.mask", icon_button, style);
90   readDatabaseMask("window.button.stick.mask", stick_button, style);
91
92   // we create the window.frame texture by hand because it exists only to
93   // make the code cleaner and is not actually used for display
94   BColor color = readDatabaseColor("window.frame.focusColor", "white",
95                                         style);
96   f_focus = BTexture("solid flat", screen_number, image_control);
97   f_focus.setColor(color);
98
99   color = readDatabaseColor("window.frame.unfocusColor", "white", style);
100   f_unfocus = BTexture("solid flat", screen_number, image_control);
101   f_unfocus.setColor(color);
102
103   l_text_focus = readDatabaseColor("window.label.focus.textColor",
104                                    "black", style);
105   l_text_unfocus = readDatabaseColor("window.label.unfocus.textColor",
106                                      "white", style);
107
108   b_pic_focus = readDatabaseColor("window.button.focus.picColor",
109                                   "black", style);
110   b_pic_unfocus = readDatabaseColor("window.button.unfocus.picColor",
111                                     "white", style);
112
113   justify = LeftJustify;
114
115   if (style.getValue("window.justify", s)) {
116     if (s == "right" || s == "Right")
117       justify = RightJustify;
118     else if (s == "center" || s == "Center")
119       justify = CenterJustify;
120   }
121
122   // sanity checks
123   if (t_focus.texture() == BTexture::Parent_Relative)
124     t_focus = f_focus;
125   if (t_unfocus.texture() == BTexture::Parent_Relative)
126     t_unfocus = f_unfocus;
127   if (h_focus.texture() == BTexture::Parent_Relative)
128     h_focus = f_focus;
129   if (h_unfocus.texture() == BTexture::Parent_Relative)
130     h_unfocus = f_unfocus;
131
132   border_color = readDatabaseColor("borderColor", "black", style);
133
134   // load bevel, border and handle widths
135
136   const ScreenInfo *s_info = OBDisplay::screenInfo(screen_number);
137   unsigned int width = s_info->getRect().width();
138
139   if (! style.getValue("handleWidth", handle_width) ||
140       handle_width > width/2 || handle_width == 0)
141     handle_width = 6;
142
143   if (! style.getValue("borderWidth", border_width))
144     border_width = 1;
145
146   if (! style.getValue("bevelWidth", bevel_width)
147       || bevel_width > width/2 || bevel_width == 0)
148     bevel_width = 3;
149
150   if (! style.getValue("frameWidth", frame_width)
151       || frame_width > width/2)
152     frame_width = bevel_width;
153
154   if (style.getValue("rootCommand", s))
155     bexec(s, s_info->displayString());
156 }
157
158
159 void Style::readDatabaseMask(const std::string &rname, PixmapMask &pixmapMask,
160                              const Configuration &style) {
161   Window root_window = OBDisplay::screenInfo(screen_number)->getRootWindow();
162   std::string s;
163   int hx, hy; //ignored
164   int ret = BitmapOpenFailed; //default to failure.
165   
166   if (style.getValue(rname, s))
167   {
168     if (s[0] != '/' && s[0] != '~')
169     {
170       std::string xbmFile = std::string("~/.openbox/buttons/") + s;
171       ret = XReadBitmapFile(OBDisplay::display, root_window,
172                             expandTilde(xbmFile).c_str(), &pixmapMask.w,
173                             &pixmapMask.h, &pixmapMask.mask, &hx, &hy);
174     } else
175       ret = XReadBitmapFile(OBDisplay::display, root_window,
176                             expandTilde(s).c_str(), &pixmapMask.w,
177                             &pixmapMask.h, &pixmapMask.mask, &hx, &hy);
178     
179     if (ret == BitmapSuccess)
180       return;
181   }
182
183   pixmapMask.mask = None;
184   pixmapMask.w = pixmapMask.h = 0;
185 }
186
187
188 BTexture Style::readDatabaseTexture(const std::string &rname,
189                                          const std::string &default_color,
190                                          const Configuration &style, 
191                                          bool allowNoTexture)
192 {
193   BTexture texture;
194   std::string s;
195
196   if (style.getValue(rname, s))
197     texture = BTexture(s);
198   else if (allowNoTexture) //no default
199     texture.setTexture(BTexture::NoTexture);
200   else
201     texture.setTexture(BTexture::Solid | BTexture::Flat);
202
203   // associate this texture with this screen
204   texture.setScreen(screen_number);
205   texture.setImageControl(image_control);
206
207   if (texture.texture() != BTexture::NoTexture) {
208     texture.setColor(readDatabaseColor(rname + ".color", default_color,
209                                        style));
210     texture.setColorTo(readDatabaseColor(rname + ".colorTo", default_color,
211                                          style));
212     texture.setBorderColor(readDatabaseColor(rname + ".borderColor",
213                                              default_color, style));
214   }
215
216   return texture;
217 }
218
219
220 BColor Style::readDatabaseColor(const std::string &rname,
221                                      const std::string &default_color,
222                                      const Configuration &style) {
223   BColor color;
224   std::string s;
225   if (style.getValue(rname, s))
226     color = BColor(s, screen_number);
227   else
228     color = BColor(default_color, screen_number);
229   return color;
230 }
231
232
233 BFont *Style::readDatabaseFont(const std::string &rbasename,
234                                const Configuration &style) {
235   std::string fontname;
236
237   std::string s;
238
239   int i;
240   if (style.getValue(rbasename + "xft.font", s) &&
241       style.getValue(rbasename + "xft.size", i)) {
242     std::string family = s;
243     bool bold = False;
244     bool italic = False;
245     bool dropShadow = False;
246
247     if (style.getValue(rbasename + "xft.flags", s)) {
248       if (s.find("bold") != std::string::npos)
249         bold = True;
250       if (s.find("italic") != std::string::npos)
251         italic = True;
252       if (s.find("shadow") != std::string::npos)
253         dropShadow = True;
254     }
255     
256     unsigned char offset = 1;
257     if (style.getValue(rbasename + "xft.shadow.offset", s)) {
258       offset = atoi(s.c_str()); //doesn't detect errors
259       if (offset > CHAR_MAX)
260         offset = 1;
261     }
262
263     unsigned char tint = 0x40;
264     if (style.getValue(rbasename + "xft.shadow.tint", s)) {
265       tint = atoi(s.c_str());
266     }
267
268     
269     BFont *b = new BFont(screen_number, family, i, bold, italic,
270                          dropShadow && shadow_fonts,
271                          offset, tint, aa_fonts);
272     if (b->valid())
273       return b;
274     delete b;
275   }
276
277   if (style.getValue(rbasename + "xft.font", s))
278     printf("Unable to load font \"%s\". Exiting\n", s.c_str());
279   else
280     printf("Font not defined by style. Exiting\n");
281   exit(2);  // can't continue without a font
282 }
283
284 }