ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/dclient/include/ndk/packer.hh
Revision: 1.1
Committed: Sun Oct 24 20:31:43 2010 UTC (13 years, 9 months ago) by sf-pippijn
Branch: MAIN
CVS Tags: HEAD
Log Message:
use EV and plain sockets instead of asio

File Contents

# Content
1 /* packer.hh
2 * This file is part of ndk library
3 * Copyright (c) 2003,2004 by Stanislav Ievlev
4 *
5 * This file is covered by the GNU Library General Public License,
6 * which should be included with libndk as the file COPYING.
7 */
8 #ifndef NDK_PACKER_HH__
9 #define NDK_PACKER_HH__
10
11 #include <algorithm>
12 #include <functional>
13 #include <vector>
14
15 #include <ndk/align.hh>
16 #include <ndk/panel.hh>
17 #include <ndk/support.hh>
18
19 namespace ndk
20 {
21 namespace pack /**< packer strategies */
22 {
23 struct vertical /**< vertical packing strategy */
24 {
25 static int align_coord (panel *p)
26 {
27 return p->x ();
28 }
29
30 static int align_size (panel *p)
31 {
32 return p->width ();
33 }
34
35 static void align_move (panel *p, int pos)
36 {
37 p->move (pos, p->y (), absolute);
38 }
39
40 static void align_resize (panel *p, int size)
41 {
42 const bool need_update = (p->width () != size);
43
44 p->resize (size, p->height ());
45 if (need_update)
46 p->draw ();
47 }
48
49 static int line_coord (panel *p)
50 {
51 return p->y ();
52 }
53
54 static int line_size (panel *p)
55 {
56 return p->height ();
57 }
58
59 static void line_move (panel *p, int pos)
60 {
61 p->move (p->x (), pos, absolute);
62 }
63
64 static void resize (panel *p, int align_size, int line_size)
65 {
66 p->resize (align_size, line_size);
67 }
68 };
69
70 struct horizontal /**< horizontal packing strategy */
71 {
72 static int align_coord (panel *p)
73 {
74 return p->y ();
75 }
76
77 static int align_size (panel *p)
78 {
79 return p->height ();
80 }
81
82 static void align_move (panel *p, int pos)
83 {
84 p->move (p->x (), pos, absolute);
85 }
86
87 static void align_resize (panel *p, int size)
88 {
89 const bool need_update = (p->height () != size);
90
91 p->resize (p->width (), size);
92 if (need_update)
93 p->draw ();
94 }
95
96 static int line_coord (panel *p)
97 {
98 return p->x ();
99 }
100
101 static int line_size (panel *p)
102 {
103 return p->width ();
104 }
105
106 static void line_move (panel *p, int pos)
107 {
108 p->move (pos, p->y (), absolute);
109 }
110
111 static void resize (panel *p, int align_size, int line_size)
112 {
113 p->resize (line_size, align_size);
114 }
115 };
116
117 template<class T>
118 struct def_resizer /**< default resize policy for the packer object */
119 {
120 static void fix_item (panel *p, int, int pos)
121 {
122 T::align_move (p, pos);
123 }
124
125 static void fix_panel (panel *p, int align_size, int line_size)
126 {
127 T::resize (p, align_size, line_size);
128 }
129
130 static void draw (panel *p)
131 {
132 p->draw ();
133 }
134 };
135
136 template<class T>
137 struct no_resizer /**< * this policy don't made resize of the object */
138 {
139 static void fix_item (panel *p, int size, int pos)
140 {
141 T::align_move (p, pos);
142 T::align_resize (p, size);
143 }
144
145 static void fix_panel (panel *, int, int)
146 {
147 }
148
149 static void draw (panel *)
150 {
151 }
152 };
153 }
154
155 template<class T>
156 bool
157 wider_panel (panel *p1, panel *p2)
158 {
159 /**< compare panels, who is wider */
160 return T::align_size (p1) < T::align_size (p2);
161 }
162
163 /**
164 * general template to the auto packer/aligner of widgets
165 * packer algorithm:
166 * with resizer:
167 * 1. find widget with maximum size (max)
168 * 2. main widget size is max + 2*padding
169 * 3. align all widgets and place it with begining from padding
170 * 4. resize main to size max + 2*padding, and total widgets length+2*padding
171 * without resizer:
172 * 1. find widget with maximum size
173 * 2. align all widgets, according max widget size and with begining from padding
174 * 3. resize all widgets to the "main - 2*padding" if we need it
175 */
176 template<class T, template<class> class resizer = pack::def_resizer>
177 class packer
178 {
179 typedef std::vector<panel *> widget_vector;
180 typedef resizer<T> resizer_type;
181
182 public:
183 packer (panel *main, align::type alignment, int padding = 0)
184 : main_ (main)
185 , padding_ (padding)
186 , align_ (alignment)
187 {
188 }
189
190 void add (panel *item)
191 {
192 widgets_.push_back (item);
193 resizer_type::draw (item); /* in auto resize method we need to draw widgets to know it's real sizes */
194 }
195
196 void pack () /**< move and align widgets */
197 {
198 if (widgets_.empty ())
199 return;
200
201 /* first made alignment */
202 widget_vector::const_iterator max_item =
203 std::max_element (widgets_.begin (), widgets_.end (), wider_panel<T> );
204 const int align_size = T::align_size (*max_item) + main_->padding () * 2;
205 foreach (panel *widget, widgets_)
206 do_align (widget, T::align_size (*max_item));
207
208 int pos = main_->padding ();
209 foreach (panel *widget, widgets_)
210 do_move (widget, pos);
211 const int line_size = pos - padding_ + main_->padding ();
212
213 resizer_type::fix_panel (main_, align_size, line_size); /* try to fix size of the panel */
214 }
215
216 private:
217 void do_align (panel *p, int max) /**< align panel's possition according current aligment */
218 {
219 resizer_type::fix_item (p, T::align_size (main_) - 2 * main_->padding (),
220 T::align_coord (main_) +
221 main_->padding () +
222 align::pos (T::align_size (p), max, align_));
223 }
224
225 void do_move (panel *p, int &pos) /**< move next item according current packing */
226 {
227 T::line_move (p, T::line_coord (main_) + pos);
228 pos += T::line_size (p) + padding_;
229 }
230
231 widget_vector widgets_; /**< widgets to pack */
232 panel *main_; /**< main widget, we will try to place all widgets under it*/
233 int padding_; /**< size of empty area between widgets on the line */
234 align::type align_; /**< aligment of the widgets */
235 };
236
237 typedef packer<pack::horizontal> horizontal_packer;
238 typedef packer<pack::vertical> vertical_packer;
239 }
240
241 #endif