00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "element.h"
00036
00037 #include "dialog.h"
00038
00039 #include "datahash/datahash_util.h"
00040
00041
00042
00043 namespace dialog {
00044
00045 static const int s_border = 2;
00046
00047
00048 struct element_record_t {
00049 rect_t bounds;
00050 smart_ptr<Element> element;
00051 };
00052
00053
00054 typedef std::vector<element_record_t> vec_element_t;
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 class Container : public Element {
00065 public:
00066 Container(void) throw();
00067 ~Container(void) throw() { }
00068
00069
00070 void initialize(IN vec_element_t& children,
00071 IN int width, IN int height);
00072
00073
00074 int getWidth(void);
00075 int getHeight(void);
00076 void draw(IN const point_t& offset);
00077 void cursor(IN const point_t& pos);
00078 Element * getFocus(IN const point_t& pos);
00079 const char * button(IN int button, IN int state, IN const point_t& pos);
00080 void addData(IN crypto::DESKey * desKey, IN Datahash * data);
00081
00082 private:
00083
00084 Element * getChild(IN const point_t& pos, OUT point_t& rel);
00085 rect_t getRect(IN const element_record_t& er);
00086
00087
00088 int m_width;
00089 int m_height;
00090 vec_element_t m_children;
00091 smart_ptr<Drawer> m_drawer;
00092 };
00093
00094
00095
00096 Container::Container(void)
00097 throw()
00098 {
00099 m_width = -1;
00100 m_height = -1;
00101 }
00102
00103
00104
00105 void
00106 Container::initialize
00107 (
00108 IN vec_element_t& children,
00109 IN int width,
00110 IN int height
00111 )
00112 {
00113 ASSERT(width > 0, "empty?");
00114 ASSERT(height > 0, "empty?");
00115
00116 m_children = children;
00117 m_width = width;
00118 m_height = height;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 int
00130 Container::getWidth
00131 (
00132 void
00133 )
00134 {
00135 return m_width;
00136 }
00137
00138
00139 int
00140 Container::getHeight
00141 (
00142 void
00143 )
00144 {
00145 return m_height;
00146 }
00147
00148
00149
00150 void
00151 Container::draw
00152 (
00153 IN const point_t& offset
00154 )
00155 {
00156 for (vec_element_t::iterator i = m_children.begin();
00157 i != m_children.end(); ++i) {
00158 element_record_t& er = *i;
00159 ASSERT(er.element, "null element in vector");
00160
00161
00162 point_t border(s_border, s_border);
00163 er.element->draw(offset + er.bounds.getTopLeft() + border);
00164 }
00165 }
00166
00167
00168
00169 void
00170 Container::cursor
00171 (
00172 IN const point_t& pos
00173 )
00174 {
00175 point_t rel;
00176 Element * e = this->getChild(pos, rel);
00177 if (e) {
00178 e->cursor(rel);
00179 }
00180 }
00181
00182
00183
00184 const char *
00185 Container::button
00186 (
00187 IN int button,
00188 IN int state,
00189 IN const point_t& pos
00190 )
00191 {
00192 point_t rel;
00193 Element * e = this->getChild(pos, rel);
00194 return e ? e->button(button, state, rel) : NULL;
00195 }
00196
00197
00198
00199 Element *
00200 Container::getFocus
00201 (
00202 IN const point_t& pos
00203 )
00204 {
00205
00206 point_t rel;
00207 Element * e = this->getChild(pos, rel);
00208
00209 return e ? e->getFocus(rel) : NULL;
00210 }
00211
00212
00213
00214 void
00215 Container::addData
00216 (
00217 IN crypto::DESKey * key,
00218 IN Datahash * data
00219 )
00220 {
00221
00222 ASSERT(data, "null");
00223
00224 for (vec_element_t::iterator i = m_children.begin();
00225 i != m_children.end(); ++i) {
00226 element_record_t& er = *i;
00227 ASSERT(er.element, "null element in vector");
00228
00229
00230 er.element->addData(key, data);
00231 }
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 Element *
00243 Container::getChild
00244 (
00245 IN const point_t& pos,
00246 OUT point_t& rel
00247 )
00248 {
00249 rel.clear();
00250
00251 for (vec_element_t::iterator i = m_children.begin();
00252 i != m_children.end(); ++i) {
00253 element_record_t& er = *i;
00254 ASSERT(er.element, "null element in vector");
00255
00256 if (!er.bounds.contains(pos))
00257 continue;
00258
00259
00260 point_t border(s_border, s_border);
00261 rel = pos - er.bounds.getTopLeft() - border;
00262 return er.element;
00263 }
00264
00265
00266 return NULL;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 smart_ptr<Element>
00278 createContainerElement
00279 (
00280 IN Manager * mgr,
00281 IN const Datahash * hash
00282 )
00283 {
00284 ASSERT(mgr, "null");
00285 ASSERT(hash, "null");
00286
00287 vec_element_t children;
00288
00289
00290 int maxW = 0;
00291 int maxH = 0;
00292 Datahash::iterator_t i;
00293 hash->getIterator("element", i);
00294 while (const hash_value_t * phv = hash->getNextElementUnsafe(i)) {
00295 ASSERT_THROW(eHashDataType_Hash == phv->type,
00296 "Bad datahash datatype (expected hash)");
00297 smart_ptr<Datahash> subhash = phv->hash;
00298 ASSERT(subhash, "null subhash");
00299
00300
00301 element_record_t er;
00302 er.element = constructElementTree(mgr, subhash);
00303 ASSERT(er.element, "failed to create element subtree");
00304
00305
00306 int w = er.element->getWidth();
00307 int h = er.element->getHeight();
00308
00309 if (w > maxW) {
00310 maxW = w;
00311 }
00312 if (h > maxH) {
00313 maxH = h;
00314 }
00315 er.bounds.set(0, 0, w, h);
00316
00317 children.push_back(er);
00318 }
00319
00320
00321 std::string s_align = getOptionalString(hash, "axis", "v");
00322 char align = 'v';
00323 if ("h" == s_align) {
00324 align = 'h';
00325 }
00326
00327
00328 int borderX = getOptionalLong(hash, "borderX", s_border);
00329 int borderY = getOptionalLong(hash, "borderY", s_border);
00330
00331
00332 const char * widthString =
00333 getOptionalString(hash, "widthString", NULL);
00334 if (widthString) {
00335
00336 smart_ptr<Drawer> drawer = mgr->getDrawer();
00337 ASSERT(drawer, "null drawer?");
00338
00339 font_size_t fs =
00340 drawer->getFontSizing(eElement_Label, widthString);
00341 int width = fs.lead + fs.trail;
00342 if (width > maxW) {
00343 maxW = width;
00344 }
00345 }
00346
00347
00348 int oldX = 0;
00349 int oldY = 0;
00350 for (vec_element_t::iterator i = children.begin(); i != children.end();
00351 ++i) {
00352 element_record_t& er = *i;
00353
00354 if ('v' == align) {
00355 int dx = (int) (0.5 * (maxW - er.bounds.right) + 0.5);
00356 er.bounds.set(dx, oldY, er.bounds.right + dx,
00357 er.bounds.bottom + oldY);
00358 oldY = er.bounds.bottom;
00359 oldY += borderY;
00360 } else {
00361 int dy = (int) (0.5 * (maxH - er.bounds.bottom) + 0.5);
00362 er.bounds.set(oldX, dy, er.bounds.right + oldX,
00363 er.bounds.bottom + dy);
00364 oldX = er.bounds.right;
00365 oldX += borderX;
00366 }
00367
00368
00369 }
00370
00371
00372 if ('v' == align) {
00373 maxH = oldY;
00374 maxW += borderX;
00375 } else {
00376 maxW = oldX;
00377 maxH += borderY;
00378 }
00379 maxW += borderX;
00380 maxH += borderY;
00381
00382
00383 smart_ptr<Container> local = new Container;
00384 ASSERT(local, "out of memory");
00385
00386 local->initialize(children, maxW, maxH);
00387
00388 return local;
00389 }
00390
00391
00392
00393 };
00394