use the new non-static display
[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 "otk/gccache.hh" // otk::BPen
9
10 namespace ob {
11
12 ButtonWidget::ButtonWidget(otk::Widget *parent,
13                            WidgetBase::WidgetType type)
14   : otk::Widget(parent),
15     WidgetBase(type),
16     _pressed(false),
17     _button(0)
18 {
19 }
20
21
22 ButtonWidget::~ButtonWidget()
23 {
24 }
25
26
27 void ButtonWidget::setTextures()
28 {
29   switch (type()) {
30   case Type_LeftGrip:
31   case Type_RightGrip:
32     if (_focused)
33       setTexture(_style->getGripFocus());
34     else
35       setTexture(_style->getGripUnfocus());
36     break;
37   case Type_StickyButton:
38   case Type_CloseButton:
39   case Type_MaximizeButton:
40   case Type_IconifyButton:
41     if (_pressed) {
42       if (_focused)
43         setTexture(_style->getButtonPressedFocus());
44       else
45         setTexture(_style->getButtonPressedUnfocus());
46     } else {
47       if (_focused)
48         setTexture(_style->getButtonFocus());
49       else
50         setTexture(_style->getButtonUnfocus());
51     }
52     break;
53   default:
54     assert(false); // there's no other button widgets!
55   }
56 }
57
58
59 void ButtonWidget::setStyle(otk::Style *style)
60 {
61   otk::Widget::setStyle(style);
62   setTextures();
63
64   switch (type()) {
65   case Type_LeftGrip:
66   case Type_RightGrip:
67     setBorderColor(_style->getBorderColor());
68     break;
69   case Type_StickyButton:
70   case Type_CloseButton:
71   case Type_MaximizeButton:
72   case Type_IconifyButton:
73     break;
74   default:
75     assert(false); // there's no other button widgets!
76   }
77 }
78
79
80 void ButtonWidget::update()
81 {
82   otk::PixmapMask *pm;
83   int width;
84   bool draw = _dirty;
85
86   otk::Widget::update();
87
88   if (draw) {
89     switch (type()) {
90     case Type_StickyButton:
91       pm = _style->getStickyButtonMask();
92       break;
93     case Type_CloseButton:
94       pm = _style->getCloseButtonMask();
95       break;
96     case Type_MaximizeButton:
97       pm = _style->getMaximizeButtonMask();
98       break;
99     case Type_IconifyButton:
100       pm = _style->getIconifyButtonMask();
101       break;
102     case Type_LeftGrip:
103     case Type_RightGrip:
104       return; // no drawing
105     default:
106       assert(false); // there's no other button widgets!
107     }
108
109     if (pm->mask == None) return; // no mask for the button, leave it empty
110
111     width = _rect.width();
112   
113     otk::Pen pen(_focused ? *_style->getButtonPicFocus() :
114                  *_style->getButtonPicUnfocus());
115
116     // set the clip region
117     XSetClipMask(**otk::display, pen.gc(), pm->mask);
118     XSetClipOrigin(**otk::display, pen.gc(),
119                    (width - pm->w)/2, (width - pm->h)/2);
120
121     // fill in the clipped region
122     XFillRectangle(**otk::display, _window, pen.gc(),
123                    (width - pm->w)/2, (width - pm->h)/2,
124                    (width + pm->w)/2, (width + pm->h)/2);
125
126     // unset the clip region
127     XSetClipMask(**otk::display, pen.gc(), None);
128     XSetClipOrigin(**otk::display, pen.gc(), 0, 0);
129   }
130 }
131
132
133 void ButtonWidget::adjust()
134 {
135   // nothing to adjust. no children.
136 }
137
138
139 void ButtonWidget::focus()
140 {
141   otk::Widget::focus();
142   setTextures();
143 }
144
145
146 void ButtonWidget::unfocus()
147 {
148   otk::Widget::unfocus();
149   setTextures();
150 }
151
152
153 void ButtonWidget::buttonPressHandler(const XButtonEvent &e)
154 {
155   otk::Widget::buttonPressHandler(e);
156   if (_button) return;
157   _button = e.button;
158   _pressed = true;
159   setTextures();
160   update();
161 }
162
163
164 void ButtonWidget::buttonReleaseHandler(const XButtonEvent &e)
165 {
166   otk::Widget::buttonPressHandler(e);
167   if (e.button != _button) return;
168   _button = 0;
169   _pressed = false;
170   setTextures();
171   update();
172 }
173
174 }