]> icculus.org git repositories - mikachu/openbox.git/blob - src/buttonwidget.cc
import config
[mikachu/openbox.git] / src / buttonwidget.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2
3 #ifdef HAVE_CONFIG_H
4 # include "../config.h"
5 #endif
6
7 #include "buttonwidget.hh"
8 #include "client.hh"
9
10 namespace ob {
11
12 ButtonWidget::ButtonWidget(otk::Widget *parent,
13                            WidgetBase::WidgetType type,
14                            Client *client)
15   : otk::Widget(parent),
16     WidgetBase(type),
17     _client(client),
18     _pressed(false),
19     _button(0),
20     _state(false)
21 {
22 }
23
24
25 ButtonWidget::~ButtonWidget()
26 {
27 }
28
29
30 void ButtonWidget::setTextures()
31 {
32   bool p = _pressed;
33
34   switch (type()) {
35   case Type_AllDesktopsButton:
36     if (_client->desktop() == (signed)0xffffffff)
37       p = true;
38     break;
39   case Type_MaximizeButton:
40     if (_client->maxHorz() || _client->maxVert())
41       p = true;
42     break;
43   default:
44     break;
45   }
46   
47   switch (type()) {
48   case Type_LeftGrip:
49   case Type_RightGrip:
50     if (_focused)
51       setTexture(_style->gripFocusBackground());
52     else
53       setTexture(_style->gripUnfocusBackground());
54     break;
55   case Type_AllDesktopsButton:
56   case Type_MaximizeButton:
57   case Type_CloseButton:
58   case Type_IconifyButton:
59     if (p) {
60       if (_focused)
61         setTexture(_style->buttonPressFocusBackground());
62       else
63         setTexture(_style->buttonPressUnfocusBackground());
64     } else {
65       if (_focused)
66         setTexture(_style->buttonUnpressFocusBackground());
67       else
68         setTexture(_style->buttonUnpressUnfocusBackground());
69     }
70     break;
71   default:
72     assert(false); // there's no other button widgets!
73   }
74 }
75
76
77 void ButtonWidget::setStyle(otk::RenderStyle *style)
78 {
79   otk::Widget::setStyle(style);
80   setTextures();
81
82   switch (type()) {
83   case Type_LeftGrip:
84   case Type_RightGrip:
85     setBorderColor(_style->frameBorderColor());
86     break;
87   case Type_AllDesktopsButton:
88   case Type_CloseButton:
89   case Type_MaximizeButton:
90   case Type_IconifyButton:
91     break;
92   default:
93     assert(false); // there's no other button widgets!
94   }
95 }
96
97
98 void ButtonWidget::update()
99 {
100   switch (type()) {
101   case Type_AllDesktopsButton:
102     if ((_client->desktop() == (signed)0xffffffff) != _state) {
103       _state = !_state;
104       setTextures();
105     }
106     break;
107   case Type_MaximizeButton:
108     if ((_client->maxHorz() || _client->maxVert()) != _state) {
109       _state = !_state;
110       setTextures();
111     }
112     break;
113   default:
114     break;
115   }
116   
117   otk::Widget::update();
118 }
119
120
121 void ButtonWidget::renderForeground()
122 {
123   otk::PixmapMask *pm;
124   int width;
125   bool draw = _dirty;
126
127   otk::Widget::renderForeground();
128
129   if (draw) {
130     switch (type()) {
131     case Type_AllDesktopsButton:
132       pm = _style->alldesktopsMask();
133       break;
134     case Type_CloseButton:
135       pm = _style->closeMask();
136       break;
137     case Type_MaximizeButton:
138       pm = _style->maximizeMask();
139       break;
140     case Type_IconifyButton:
141       pm = _style->iconifyMask();
142       break;
143     case Type_LeftGrip:
144     case Type_RightGrip:
145       return; // no drawing
146     default:
147       assert(false); // there's no other button widgets!
148     }
149
150     assert(pm->mask);
151     if (pm->mask == None) return; // no mask for the button, leave it empty
152
153     width = _rect.width();
154
155     otk::RenderColor *color = (_focused ? _style->buttonFocusColor() :
156                                _style->buttonUnfocusColor());
157
158     // set the clip region
159     int x = (width - pm->w) / 2, y = (width - pm->h) / 2;
160     XSetClipMask(**otk::display, color->gc(), pm->mask);
161     XSetClipOrigin(**otk::display, color->gc(), x, y);
162
163     // fill in the clipped region
164     XFillRectangle(**otk::display, _surface->pixmap(), color->gc(), x, y,
165                    x + pm->w, y + pm->h);
166
167     // unset the clip region
168     XSetClipMask(**otk::display, color->gc(), None);
169     XSetClipOrigin(**otk::display, color->gc(), 0, 0);
170   }
171 }
172
173
174 void ButtonWidget::adjust()
175 {
176   // nothing to adjust. no children.
177 }
178
179
180 void ButtonWidget::focus()
181 {
182   otk::Widget::focus();
183   setTextures();
184 }
185
186
187 void ButtonWidget::unfocus()
188 {
189   otk::Widget::unfocus();
190   setTextures();
191 }
192
193
194 void ButtonWidget::buttonPressHandler(const XButtonEvent &e)
195 {
196   otk::Widget::buttonPressHandler(e);
197   if (_button) return;
198   _button = e.button;
199   _pressed = true;
200   setTextures();
201   update();
202 }
203
204
205 void ButtonWidget::buttonReleaseHandler(const XButtonEvent &e)
206 {
207   otk::Widget::buttonPressHandler(e);
208   if (e.button != _button) return;
209   _button = 0;
210   _pressed = false;
211   setTextures();
212   update();
213 }
214
215 }