]> icculus.org git repositories - mikachu/openbox.git/blob - otk/widget.cc
can now map windows and render textures
[mikachu/openbox.git] / otk / widget.cc
1 #include "widget.hh"
2 #include "display.hh"
3 #include "assassin.hh"
4 #include "screeninfo.hh"
5
6 namespace otk {
7
8 OtkWidget::OtkWidget(OtkWidget *parent, Direction direction)
9   : _parent(parent), _style(parent->getStyle()), _direction(direction),
10     _cursor(parent->getCursor()), _bevel_width(parent->getBevelWidth()),
11     _visible(false), _focused(false), _grabbed_mouse(false),
12     _grabbed_keyboard(false), _stretchable_vert(false),
13     _stretchable_horz(false), _texture(0), _bg_pixmap(0),
14     _screen(parent->getScreen())
15 {
16   parent->addChild(this);
17   create();
18 }
19
20 OtkWidget::OtkWidget(Style *style, Direction direction,
21                      Cursor cursor, int bevel_width)
22   : _parent(0), _style(style), _direction(direction), _cursor(cursor),
23     _bevel_width(bevel_width), _visible(false),
24     _focused(false), _grabbed_mouse(false), _grabbed_keyboard(false),
25     _stretchable_vert(false), _stretchable_horz(false), _texture(0),
26     _bg_pixmap(0), _screen(style->getScreen())
27 {
28   assert(style);
29   create();
30 }
31
32 OtkWidget::~OtkWidget()
33 {
34   if (_visible)
35     hide();
36
37   std::for_each(_children.begin(), _children.end(), PointerAssassin());
38
39   if (_parent)
40     _parent->removeChild(this);
41
42   XDestroyWindow(otk::OBDisplay::display, _window);
43 }
44
45 void OtkWidget::create(void)
46 {
47   const ScreenInfo *scr_info = otk::OBDisplay::screenInfo(_screen);
48   Window p_window = _parent ? _parent->getWindow() : scr_info->getRootWindow();
49
50   _rect.setRect(0, 0, 1, 1); // just some initial values
51
52   XSetWindowAttributes attrib_create;
53   unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWEventMask;
54
55   attrib_create.background_pixmap = None;
56   attrib_create.colormap = scr_info->getColormap();
57   attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask |
58     ButtonMotionMask | ExposureMask | StructureNotifyMask;
59
60   if (_cursor) {
61     create_mask |= CWCursor;
62     attrib_create.cursor = _cursor;
63   }
64
65   _window = XCreateWindow(otk::OBDisplay::display, p_window, _rect.x(),
66                           _rect.y(), _rect.width(), _rect.height(), 0,
67                           scr_info->getDepth(), InputOutput,
68                           scr_info->getVisual(), create_mask, &attrib_create);
69 }
70
71 void OtkWidget::move(const Point &to)
72 {
73   move(to.x(), to.y());
74 }
75
76 void OtkWidget::move(int x, int y)
77 {
78   _rect.setPos(x, y);
79   XMoveWindow(otk::OBDisplay::display, _window, x, y);
80 }
81
82 void OtkWidget::resize(const Point &to)
83 {
84   resize(to.x(), to.y());
85 }
86
87 void OtkWidget::resize(int x, int y)
88 {
89   assert(x >= _rect.x() && y >= _rect.y());
90
91   setGeometry(_rect.x(), _rect.y(), x - _rect.x(), y - _rect.y());
92 }
93
94 void OtkWidget::setGeometry(const Rect &new_geom)
95 {
96   setGeometry(new_geom.x(), new_geom.y(), new_geom.width(), new_geom.height());
97 }
98  
99 void OtkWidget::setGeometry(const Point &topleft, int width, int height)
100 {
101   setGeometry(topleft.x(), topleft.y(), width, height);
102 }
103
104 void OtkWidget::setGeometry(int x, int y, int width, int height)
105 {
106   _rect = Rect(x, y, width, height);
107
108   fprintf(stderr, "Resizing to x: %d, y: %d, width: %d, height: %d\n",
109           x, y, width, height);
110
111   XMoveResizeWindow(otk::OBDisplay::display, _window, x, y, width, height);
112   setTexture();
113 }
114
115 void OtkWidget::show(void)
116 {
117   if (_visible)
118     return;
119
120   OtkWidgetList::iterator it = _children.begin(), end = _children.end();
121   for (; it != end; ++it) {
122     fprintf(stderr, "showing child\n");
123     (*it)->show();
124   }
125
126   fprintf(stderr, "x: %d, y: %d, width: %d, height: %d\n",
127           _rect.x(), _rect.y(), _rect.width(), _rect.height());
128
129   XMapWindow(otk::OBDisplay::display, _window);
130   _visible = true;
131 }
132
133 void OtkWidget::hide(void)
134 {
135   if (! _visible)
136     return;
137
138   OtkWidgetList::iterator it = _children.begin(), end = _children.end();
139   for (; it != end; ++it)
140     (*it)->hide();
141
142   XUnmapWindow(otk::OBDisplay::display, _window);
143   _visible = false;
144 }
145
146 void OtkWidget::focus(void)
147 {
148   if (! _visible)
149     return;
150
151   XSetInputFocus(otk::OBDisplay::display, _window, RevertToPointerRoot,
152                  CurrentTime);
153 }
154
155 bool OtkWidget::grabMouse(void)
156 {
157   Status ret = XGrabPointer(otk::OBDisplay::display, _window, True,
158                             (ButtonPressMask | ButtonReleaseMask |
159                              ButtonMotionMask | EnterWindowMask |
160                              LeaveWindowMask | PointerMotionMask),
161                             GrabModeSync, GrabModeAsync, None, None,
162                             CurrentTime);
163   _grabbed_mouse = (ret == GrabSuccess);
164   return _grabbed_mouse;
165 }
166
167 void OtkWidget::ungrabMouse(void)
168 {
169   if (! _grabbed_mouse)
170     return;
171
172   XUngrabPointer(otk::OBDisplay::display, CurrentTime);
173   _grabbed_mouse = false;
174 }
175
176 bool OtkWidget::grabKeyboard(void)
177 {
178   Status ret = XGrabKeyboard(otk::OBDisplay::display, _window, True,
179                              GrabModeSync, GrabModeAsync, CurrentTime);
180   _grabbed_keyboard = (ret == GrabSuccess);
181   return _grabbed_keyboard;
182
183 }
184
185 void OtkWidget::ungrabKeyboard(void)
186 {
187   if (! _grabbed_keyboard)
188     return;
189
190   XUngrabKeyboard(otk::OBDisplay::display, CurrentTime);
191   _grabbed_keyboard = false;
192 }
193
194 void OtkWidget::setTexture(BTexture *texture)
195 {
196   if (!texture && !_texture)
197     return;
198
199   Pixmap old = _bg_pixmap;
200
201   if (texture)
202     _texture = texture;
203
204   _bg_pixmap = _texture->render(_rect.width(), _rect.height(), _bg_pixmap);
205
206   if (_bg_pixmap != old)
207     XSetWindowBackgroundPixmap(otk::OBDisplay::display, _window, _bg_pixmap);
208   
209   //XSetWindowBackground(otk::OBDisplay::display, win, pix);
210 }
211
212 void OtkWidget::addChild(OtkWidget *child, bool front)
213 {
214   assert(child);
215   if (front)
216     _children.push_front(child);
217   else
218     _children.push_back(child);
219 }
220
221 void OtkWidget::removeChild(OtkWidget *child)
222 {
223   OtkWidgetList::iterator it, end = _children.end();
224   for (; it != end; ++it) {
225     if ((*it) == child)
226       break;
227   }
228
229   if (it != _children.end())
230     _children.erase(it);
231 }
232
233 }