add setup_fallback_focus() to handle focus when nothing is left focused
[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   bool draw = _dirty;
85
86   otk::OtkWidget::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::BPen pen(_focused ? *_style->getButtonPicFocus() :
114                   *_style->getButtonPicUnfocus());
115
116     // set the clip region
117     XSetClipMask(otk::OBDisplay::display, pen.gc(), pm->mask);
118     XSetClipOrigin(otk::OBDisplay::display, pen.gc(),
119                    (width - pm->w)/2, (width - pm->h)/2);
120
121     // fill in the clipped region
122     XFillRectangle(otk::OBDisplay::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::OBDisplay::display, pen.gc(), None);
128     XSetClipOrigin(otk::OBDisplay::display, pen.gc(), 0, 0);
129   }
130 }
131
132
133 void OBButtonWidget::adjust()
134 {
135   // nothing to adjust. no children.
136 }
137
138
139 void OBButtonWidget::focus()
140 {
141   otk::OtkWidget::focus();
142   setTextures();
143 }
144
145
146 void OBButtonWidget::unfocus()
147 {
148   otk::OtkWidget::unfocus();
149   setTextures();
150 }
151
152
153 void OBButtonWidget::buttonPressHandler(const XButtonEvent &e)
154 {
155   OtkWidget::buttonPressHandler(e);
156   if (_button) return;
157   _button = e.button;
158   _pressed = true;
159   setTextures();
160   update();
161 }
162
163
164 void OBButtonWidget::buttonReleaseHandler(const XButtonEvent &e)
165 {
166   OtkWidget::buttonPressHandler(e);
167   if (e.button != _button) return;
168   _button = 0;
169   _pressed = false;
170   setTextures();
171   update();
172 }
173
174 }