efb98e7652babc990da115232a9e60e44d9a7b3d
[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 OBButtonWidget::OBButtonWidget(otk::OtkWidget *parent,
13                                OBWidget::WidgetType type)
14   : otk::OtkWidget(parent),
15     OBWidget(type),
16     _pressed(false),
17     _button(0)
18 {
19 }
20
21
22 OBButtonWidget::~OBButtonWidget()
23 {
24 }
25
26
27 void OBButtonWidget::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 OBButtonWidget::setStyle(otk::Style *style)
60 {
61   otk::OtkWidget::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 OBButtonWidget::update()
81 {
82   otk::PixmapMask *pm;
83   int width;
84
85   otk::OtkWidget::update();
86
87   switch (type()) {
88   case Type_StickyButton:
89     pm = _style->getStickyButtonMask();
90     break;
91   case Type_CloseButton:
92     pm = _style->getCloseButtonMask();
93     break;
94   case Type_MaximizeButton:
95     pm = _style->getMaximizeButtonMask();
96     break;
97   case Type_IconifyButton:
98     pm = _style->getIconifyButtonMask();
99     break;
100   case Type_LeftGrip:
101   case Type_RightGrip:
102     return; // no drawing
103   default:
104     assert(false); // there's no other button widgets!
105   }
106
107   if (pm->mask == None) return; // no mask for the button, leave it empty
108
109   width = _rect.width();
110   
111   otk::BPen pen(_focused ? *_style->getButtonPicFocus() :
112                            *_style->getButtonPicUnfocus());
113
114   // set the clip region
115   XSetClipMask(otk::OBDisplay::display, pen.gc(), pm->mask);
116   XSetClipOrigin(otk::OBDisplay::display, pen.gc(),
117                  (width - pm->w)/2, (width - pm->h)/2);
118
119   // fill in the clipped region
120   XFillRectangle(otk::OBDisplay::display, _window, pen.gc(),
121                  (width - pm->w)/2, (width - pm->h)/2,
122                  (width + pm->w)/2, (width + pm->h)/2);
123
124   // unset the clip region
125   XSetClipMask(otk::OBDisplay::display, pen.gc(), None);
126   XSetClipOrigin(otk::OBDisplay::display, pen.gc(), 0, 0);
127 }
128
129
130 void OBButtonWidget::adjust()
131 {
132   // XXX: adjust shit
133 }
134
135
136 void OBButtonWidget::focus()
137 {
138   otk::OtkWidget::focus();
139   setTextures();
140 }
141
142
143 void OBButtonWidget::unfocus()
144 {
145   otk::OtkWidget::unfocus();
146   setTextures();
147 }
148
149
150 void OBButtonWidget::buttonPressHandler(const XButtonEvent &e)
151 {
152   OtkWidget::buttonPressHandler(e);
153   if (_button) return;
154   _button = e.button;
155   _pressed = true;
156   setTextures();
157   update();
158 }
159
160
161 void OBButtonWidget::buttonReleaseHandler(const XButtonEvent &e)
162 {
163   OtkWidget::buttonPressHandler(e);
164   if (e.button != _button) return;
165   _button = 0;
166   _pressed = false;
167   setTextures();
168   update();
169 }
170
171 }