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