aboutsummaryrefslogtreecommitdiff
path: root/src/Container.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/Container.cc')
-rw-r--r--src/Container.cc212
1 files changed, 212 insertions, 0 deletions
diff --git a/src/Container.cc b/src/Container.cc
new file mode 100644
index 0000000..242a7f1
--- /dev/null
+++ b/src/Container.cc
@@ -0,0 +1,212 @@
1// Container.cc
2// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
3// and Simon Bowden (rathnor at users.sourceforge.net)
4//
5// Permission is hereby granted, free of charge, to any person obtaining a
6// copy of this software and associated documentation files (the "Software"),
7// to deal in the Software without restriction, including without limitation
8// the rights to use, copy, modify, merge, publish, distribute, sublicense,
9// and/or sell copies of the Software, and to permit persons to whom the
10// Software is furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21// DEALINGS IN THE SOFTWARE.
22
23// $Id: Container.cc,v 1.7 2003/10/31 10:37:09 rathnor Exp $
24
25#include "Container.hh"
26
27#include "FbTk/Button.hh"
28#include "FbTk/EventManager.hh"
29
30Container::Container(const FbTk::FbWindow &parent):
31 FbTk::FbWindow(parent, 0, 0, 1, 1, ExposureMask), m_selected(0),
32 m_update_lock(false) {
33 FbTk::EventManager::instance()->add(*this, *this);
34}
35
36Container::~Container() {
37
38}
39
40void Container::resize(unsigned int width, unsigned int height) {
41 // do we need to resize?
42 if (FbTk::FbWindow::width() == width &&
43 FbTk::FbWindow::height() == height)
44 return;
45
46 FbTk::FbWindow::resize(width, height);
47 repositionItems();
48}
49
50void Container::moveResize(int x, int y,
51 unsigned int width, unsigned int height) {
52 FbTk::FbWindow::moveResize(x, y, width, height);
53 repositionItems();
54}
55
56void Container::insertItems(ItemList &item_list, int pos) {
57
58 // make sure all items have parent == this
59 ItemList::iterator it = m_item_list.begin();
60 ItemList::iterator it_end = m_item_list.end();
61 for (; it != it_end; ++it) {
62 if ((*it)->parent() != this)
63 return;
64 }
65
66 if (pos > size() || pos < 0) {
67 // insert last
68 m_item_list.splice(m_item_list.end(), item_list);
69 } else if (pos == 0) {
70 // insert first
71 m_item_list.splice(m_item_list.begin(), item_list);
72 } else {
73 // find insert point
74 for (it = m_item_list.begin(); pos != 0; ++it, --pos)
75 continue;
76 m_item_list.splice(it, item_list);
77 }
78
79 m_item_list.unique();
80
81 // update position
82 repositionItems();
83}
84
85void Container::insertItem(Item item, int pos) {
86 if (find(item) != -1)
87 return;
88
89 // it must be a child of this window
90 if (item->parent() != this)
91 return;
92
93 if (pos >= size() || pos < 0) {
94 m_item_list.push_back(item);
95 } else if (pos == 0) {
96 m_item_list.push_front(item);
97 } else {
98 ItemList::iterator it = m_item_list.begin();
99 for (; pos != 0; ++it, --pos)
100 continue;
101
102 m_item_list.insert(it, item);
103 }
104
105 // make sure we dont have duplicate items
106 m_item_list.unique();
107
108 repositionItems();
109}
110
111void Container::removeItem(int index) {
112 if (index < 0 || index > size())
113 return;
114
115 ItemList::iterator it = m_item_list.begin();
116 for (; index != 0; ++it, --index)
117 continue;
118
119 if (*it == selected())
120 m_selected = 0;
121
122 m_item_list.erase(it);
123
124 repositionItems();
125}
126
127void Container::removeAll() {
128 m_selected = 0;
129 m_item_list.clear();
130 if (!m_update_lock)
131 clear();
132
133}
134
135int Container::find(Item item) {
136 ItemList::iterator it = m_item_list.begin();
137 ItemList::iterator it_end = m_item_list.end();
138 int index = 0;
139 for (; it != it_end; ++it, ++index) {
140 if ((*it) == item)
141 break;
142 }
143
144 if (it == it_end)
145 return -1;
146
147 return index;
148}
149
150void Container::setSelected(int pos) {
151 if (pos < 0 || pos >= size())
152 m_selected = 0;
153 else {
154 ItemList::iterator it = m_item_list.begin();
155 for (; pos != 0; --pos, ++it)
156 continue;
157 m_selected = *it;
158 if (m_selected)
159 m_selected->clear();
160 }
161
162}
163
164void Container::exposeEvent(XExposeEvent &event) {
165 if (!m_update_lock)
166 clearArea(event.x, event.y, event.width, event.height);
167}
168
169void Container::repositionItems() {
170 if (size() == 0 || m_update_lock)
171 return;
172
173 //!! TODO vertical position
174
175 const int max_width_per_client = maxWidthPerClient();
176
177 ItemList::iterator it = m_item_list.begin();
178 const ItemList::iterator it_end = m_item_list.end();
179 int borderW = m_item_list.front()->borderWidth();
180
181 int rounding_error = width() - ((maxWidthPerClient() + borderW)* m_item_list.size() - borderW);
182
183 int next_x = -borderW; // zero so the border of the first shows
184 int extra = 0;
185 for (; it != it_end; ++it, next_x += max_width_per_client + borderW + extra) {
186 if (rounding_error != 0) {
187 --rounding_error;
188 extra = 1;
189 } else {
190 extra = 0;
191 }
192 // resize each clients including border in size
193 (*it)->moveResize(next_x,
194 -borderW,
195 max_width_per_client + extra,
196 height());
197 (*it)->clear();
198 }
199}
200
201
202unsigned int Container::maxWidthPerClient() const {
203 int count = size();
204 if (count == 0)
205 return width();
206 else {
207 int borderW = m_item_list.front()->borderWidth();
208 // there're count-1 borders to fit in with the windows
209 // -> 1 per window plus end
210 return (width() - (count - 1) * borderW) / count;
211 }
212}