]> Dogcows Code - chaz/openbox/blob - otk/widget.cc
1da7dd9025f15a32e75e6c9b9eeb09c87abc2905
[chaz/openbox] / otk / widget.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2
3 #ifdef HAVE_CONFIG_H
4 # include "../config.h"
5 #endif // HAVE_CONFIG_H
6
7 #include "widget.hh"
8
9 #include <algorithm>
10
11 namespace otk {
12
13 OtkWidget::OtkWidget(OtkWidget *parent, Direction direction)
14 : OtkBaseWidget(parent),
15 _direction(direction), _stretchable_vert(false), _stretchable_horz(false),
16 _event_dispatcher(parent->getEventDispatcher())
17 {
18 assert(parent);
19 _event_dispatcher->registerHandler(getWindow(), this);
20 }
21
22 OtkWidget::OtkWidget(OtkEventDispatcher *event_dispatcher, Style *style,
23 Direction direction, Cursor cursor, int bevel_width)
24 : OtkBaseWidget(style, cursor, bevel_width),
25 _direction(direction), _stretchable_vert(false), _stretchable_horz(false),
26 _event_dispatcher(event_dispatcher)
27 {
28 assert(event_dispatcher);
29 _event_dispatcher->registerHandler(getWindow(), this);
30 }
31
32 OtkWidget::~OtkWidget()
33 {
34 _event_dispatcher->clearHandler(_window);
35 }
36
37 void OtkWidget::adjust(void)
38 {
39 if (_direction == Horizontal)
40 adjustHorz();
41 else
42 adjustVert();
43 }
44
45 void OtkWidget::adjustHorz(void)
46 {
47 if (_children.size() == 0)
48 return;
49
50 OtkWidget *tmp;
51 OtkBaseWidgetList::iterator it, end = _children.end();
52
53 int tallest = 0;
54 int width = _bevel_width;
55 OtkBaseWidgetList stretchable;
56
57 for (it = _children.begin(); it != end; ++it) {
58 if (!(tmp = dynamic_cast<OtkWidget*>(*it))) continue;
59 if (tmp->isStretchableVert())
60 tmp->setHeight(_rect.height() > _bevel_width * 2 ?
61 _rect.height() - _bevel_width * 2 : _bevel_width);
62 if (tmp->isStretchableHorz())
63 stretchable.push_back(tmp);
64 else
65 width += tmp->_rect.width() + _bevel_width;
66
67 if (tmp->_rect.height() > tallest)
68 tallest = tmp->_rect.height();
69 }
70
71 if (stretchable.size() > 0) {
72 OtkBaseWidgetList::iterator str_it = stretchable.begin(),
73 str_end = stretchable.end();
74
75 int str_width = _rect.width() - width / stretchable.size();
76
77 for (; str_it != str_end; ++str_it)
78 (*str_it)->setWidth(str_width > _bevel_width ? str_width - _bevel_width
79 : _bevel_width);
80 }
81
82 OtkWidget *prev_widget = 0;
83
84 for (it = _children.begin(); it != end; ++it) {
85 if (!(tmp = dynamic_cast<OtkWidget*>(*it))) continue;
86 int x, y;
87
88 if (prev_widget)
89 x = prev_widget->_rect.x() + prev_widget->_rect.width() + _bevel_width;
90 else
91 x = _rect.x() + _bevel_width;
92 y = (tallest - tmp->_rect.height()) / 2 + _bevel_width;
93
94 tmp->move(x, y);
95
96 prev_widget = tmp;
97 }
98
99 internalResize(width, tallest + _bevel_width * 2);
100 }
101
102 void OtkWidget::adjustVert(void)
103 {
104 if (_children.size() == 0)
105 return;
106
107 OtkWidget *tmp;
108 OtkBaseWidgetList::iterator it, end = _children.end();
109
110 int widest = 0;
111 int height = _bevel_width;
112 OtkBaseWidgetList stretchable;
113
114 for (it = _children.begin(); it != end; ++it) {
115 if (!(tmp = dynamic_cast<OtkWidget*>(*it))) continue;
116 if (tmp->isStretchableHorz())
117 tmp->setWidth(_rect.width() > _bevel_width * 2 ?
118 _rect.width() - _bevel_width * 2 : _bevel_width);
119 if (tmp->isStretchableVert())
120 stretchable.push_back(tmp);
121 else
122 height += tmp->_rect.height() + _bevel_width;
123
124 if (tmp->_rect.width() > widest)
125 widest = tmp->_rect.width();
126 }
127
128 if (stretchable.size() > 0) {
129 OtkBaseWidgetList::iterator str_it = stretchable.begin(),
130 str_end = stretchable.end();
131
132 int str_height = _rect.height() - height / stretchable.size();
133
134 for (; str_it != str_end; ++str_it)
135 (*str_it)->setHeight(str_height > _bevel_width ?
136 str_height - _bevel_width : _bevel_width);
137 }
138
139 OtkWidget *prev_widget = 0;
140
141 for (it = _children.begin(); it != end; ++it) {
142 if (!(tmp = dynamic_cast<OtkWidget*>(*it))) continue;
143 int x, y;
144
145 if (prev_widget)
146 y = prev_widget->_rect.y() + prev_widget->_rect.height() + _bevel_width;
147 else
148 y = _rect.y() + _bevel_width;
149 x = (widest - tmp->_rect.width()) / 2 + _bevel_width;
150
151 tmp->move(x, y);
152
153 prev_widget = tmp;
154 }
155
156 internalResize(widest + _bevel_width * 2, height);
157 }
158
159 void OtkWidget::update(void)
160 {
161 if (_dirty)
162 adjust();
163
164 OtkBaseWidget::update();
165 }
166
167 void OtkWidget::internalResize(int w, int h)
168 {
169 assert(w > 0 && h > 0);
170
171 // if (! _fixed_width && ! _fixed_height)
172 resize(w, h);
173 // else if (! _fixed_width)
174 // resize(w, _rect.height());
175 // else if (! _fixed_height)
176 // resize(_rect.width(), h);
177 }
178
179 void OtkWidget::setEventDispatcher(OtkEventDispatcher *disp)
180 {
181 if (_event_dispatcher)
182 _event_dispatcher->clearHandler(_window);
183 _event_dispatcher = disp;
184 _event_dispatcher->registerHandler(_window, this);
185 }
186
187
188 }
This page took 0.043347 seconds and 4 git commands to generate.