00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <GLEXT/GLState.h>
00022 #include <XML/XMLParser.h>
00023 #include <common/Defines.h>
00024 #include <GLW/GLWTranslate.h>
00025 #include <GLW/GLWPanel.h>
00026 #include <GLW/GLWTab.h>
00027
00028 GLWPanel::GLWPanelEntry::GLWPanelEntry(GLWidget *w, GLWCondition *c,
00029 unsigned int f, float wi) :
00030 widget(w), condition(c), flags(f),
00031 leftSpace(0.0f), rightSpace(0.0f),
00032 topSpace(0.0f), bottomSpace(0.0f)
00033 {
00034 if (! (f & GLWPanel::AlignLeft) &&
00035 ! (f & GLWPanel::AlignRight) &&
00036 ! (f & GLWPanel::AlignCenterLeftRight)) flags |= GLWPanel::AlignLeft;
00037
00038 if (! (f & GLWPanel::AlignTop) &&
00039 ! (f & GLWPanel::AlignCenterTopBottom) &&
00040 ! (f & GLWPanel::AlignBottom)) flags |= GLWPanel::AlignBottom;
00041
00042 if ((f & GLWPanel::SpaceRight) || (f & GLWPanel::SpaceAll)) rightSpace = wi;
00043 if ((f & GLWPanel::SpaceLeft) || (f & GLWPanel::SpaceAll)) leftSpace = wi;
00044 if ((f & GLWPanel::SpaceTop) || (f & GLWPanel::SpaceAll)) topSpace = wi;
00045 if ((f & GLWPanel::SpaceBottom) || (f & GLWPanel::SpaceAll)) bottomSpace = wi;
00046 }
00047
00048 REGISTER_CLASS_SOURCE(GLWPanel);
00049
00050 GLWPanel::GLWPanel(float x, float y, float w, float h,
00051 bool depressed, bool visible, bool ridge) :
00052 GLWidget(x, y, w, h), depressed_(depressed),
00053 drawPanel_(visible), layout_(LayoutNone),
00054 gridWidth_(0), ridge_(ridge)
00055 {
00056
00057 }
00058
00059 GLWPanel::~GLWPanel()
00060 {
00061 clear();
00062 }
00063
00064 GLWidget *GLWPanel::addWidget(GLWidget *widget, GLWCondition *condition,
00065 unsigned int flags, float width)
00066 {
00067 std::list<GLWPanelEntry>::iterator itor;
00068 for (itor = widgets_.begin();
00069 itor != widgets_.end();
00070 itor++)
00071 {
00072 GLWPanelEntry &entry = *itor;
00073 DIALOG_ASSERT(entry.widget != widget);
00074 }
00075
00076 GLWPanelEntry entry(widget, condition, flags, width);
00077 widgets_.push_back(entry);
00078 widget->setParent(this);
00079 return widget;
00080 }
00081
00082 GLWidget *GLWPanel::getWidgetByName(const char *name)
00083 {
00084 std::list<GLWPanelEntry>::iterator itor;
00085 for (itor = widgets_.begin();
00086 itor != widgets_.end();
00087 itor++)
00088 {
00089 GLWPanelEntry &entry = *itor;
00090 if ((*itor).widget->getVisible() &&
00091 (!entry.condition ||
00092 entry.condition->getResult(entry.widget)))
00093 {
00094 if (0 == strcmp(name, entry.widget->getName()))
00095 {
00096 return entry.widget;
00097 }
00098 if (0 == strcmp(entry.widget->getClassName(), "GLWPanel"))
00099 {
00100 GLWPanel *panel = (GLWPanel *) entry.widget;
00101 GLWidget *widget = panel->getWidgetByName(name);
00102 if (widget) return widget;
00103 }
00104 }
00105 }
00106 return 0;
00107 }
00108
00109 void GLWPanel::clear()
00110 {
00111 std::list<GLWPanelEntry>::iterator itor;
00112 for (itor = widgets_.begin();
00113 itor != widgets_.end();
00114 itor++)
00115 {
00116 delete (*itor).widget;
00117 delete (*itor).condition;
00118 }
00119 widgets_.clear();
00120 }
00121
00122 void GLWPanel::simulate(float frameTime)
00123 {
00124 std::list<GLWPanelEntry>::iterator itor;
00125 for (itor = widgets_.begin();
00126 itor != widgets_.end();
00127 itor++)
00128 {
00129 GLWPanelEntry &entry = *itor;
00130 if ((*itor).widget->getVisible() &&
00131 (!entry.condition ||
00132 entry.condition->getResult(entry.widget)))
00133 {
00134 entry.widget->simulate(frameTime);
00135 }
00136 }
00137 }
00138
00139 void GLWPanel::draw()
00140 {
00141 GLState currentState(GLState::DEPTH_OFF | GLState::TEXTURE_OFF);
00142
00143 GLWidget::draw();
00144
00145 glPushMatrix();
00146 if (drawPanel_)
00147 {
00148 glColor3f(0.8f, 0.8f, 1.0f);
00149 glBegin(GL_QUADS);
00150 glVertex2f(x_, y_);
00151 glVertex2f(x_ + w_, y_);
00152 glVertex2f(x_ + w_, y_ + h_);
00153 glVertex2f(x_, y_ + h_);
00154 glEnd();
00155
00156 glBegin(GL_LINE_LOOP);
00157 drawShadedRoundBox(x_, y_, w_, h_, 10.0f, !depressed_);
00158 glEnd();
00159
00160 if (ridge_)
00161 {
00162 glBegin(GL_LINE_LOOP);
00163 drawShadedRoundBox(x_-2.0f, y_-2.0f, w_+4.0f, h_+4.0f, 10.0f, depressed_);
00164 glEnd();
00165 }
00166 }
00167
00168 {
00169 GLWTranslate trans(x_, y_);
00170 glTranslatef(x_, y_, 0.0f);
00171
00172 std::list<GLWPanelEntry>::iterator itor;
00173 for (itor = widgets_.begin();
00174 itor != widgets_.end();
00175 itor++)
00176 {
00177 GLWPanelEntry &entry = *itor;
00178 if ((*itor).widget->getVisible() &&
00179 (!entry.condition ||
00180 entry.condition->getResult(entry.widget)))
00181 {
00182 glPushMatrix();
00183 (*itor).widget->draw();
00184 glPopMatrix();
00185 }
00186 }
00187 }
00188 glPopMatrix();
00189 }
00190
00191 void GLWPanel::mouseWheel(float x, float y, float z, bool &skipRest)
00192 {
00193 if (!inBox(x, y, x_, y_, w_, h_)) return;
00194
00195 x -= x_;
00196 y -= y_;
00197
00198 GLWTranslate trans(x_, y_);
00199
00200 std::list<GLWPanelEntry>::reverse_iterator itor;
00201 for (itor = widgets_.rbegin();
00202 itor != widgets_.rend();
00203 itor++)
00204 {
00205 GLWPanelEntry &entry = *itor;
00206 if ((*itor).widget->getVisible() &&
00207 (!entry.condition ||
00208 entry.condition->getResult(entry.widget)))
00209 {
00210 (*itor).widget->mouseWheel(x, y, z, skipRest);
00211 if (skipRest) break;
00212 }
00213 }
00214 }
00215
00216 void GLWPanel::mouseDown(int button, float x, float y, bool &skipRest)
00217 {
00218 x -= x_;
00219 y -= y_;
00220
00221 GLWTranslate trans(x_, y_);
00222
00223 std::list<GLWPanelEntry>::reverse_iterator itor;
00224 for (itor = widgets_.rbegin();
00225 itor != widgets_.rend();
00226 itor++)
00227 {
00228 GLWPanelEntry &entry = *itor;
00229 if ((*itor).widget->getVisible() &&
00230 (!entry.condition ||
00231 entry.condition->getResult(entry.widget)))
00232 {
00233 (*itor).widget->mouseDown(button, x, y, skipRest);
00234 if (skipRest) break;
00235 }
00236 }
00237 }
00238
00239 void GLWPanel::mouseUp(int button, float x, float y, bool &skipRest)
00240 {
00241 x -= x_;
00242 y -= y_;
00243
00244 GLWTranslate trans(x_, y_);
00245
00246 std::list<GLWPanelEntry>::reverse_iterator itor;
00247 for (itor = widgets_.rbegin();
00248 itor != widgets_.rend();
00249 itor++)
00250 {
00251 GLWPanelEntry &entry = *itor;
00252 if ((*itor).widget->getVisible() &&
00253 (!entry.condition ||
00254 entry.condition->getResult(entry.widget)))
00255 (*itor).widget->mouseUp(button, x, y, skipRest);
00256 if (skipRest) break;
00257 }
00258 }
00259
00260 void GLWPanel::mouseDrag(int button, float mx, float my, float x, float y, bool &skipRest)
00261 {
00262 mx -= x_;
00263 my -= y_;
00264
00265 if (mx < 0.0f || mx > w_ ||
00266 my < 0.0f || my > h_)
00267 {
00268 return;
00269 }
00270
00271 std::list<GLWPanelEntry>::reverse_iterator itor;
00272 for (itor = widgets_.rbegin();
00273 itor != widgets_.rend();
00274 itor++)
00275 {
00276 GLWPanelEntry &entry = *itor;
00277 if ((*itor).widget->getVisible() &&
00278 (!entry.condition ||
00279 entry.condition->getResult(entry.widget)))
00280 {
00281 (*itor).widget->mouseDrag(button, mx, my, x, y, skipRest);
00282 if (skipRest) break;
00283 }
00284 }
00285 skipRest = true;
00286 }
00287
00288 void GLWPanel::keyDown(char *buffer, unsigned int keyState,
00289 KeyboardHistory::HistoryElement *history, int hisCount,
00290 bool &skipRest)
00291 {
00292 std::list<GLWPanelEntry>::reverse_iterator itor;
00293 for (itor = widgets_.rbegin();
00294 itor != widgets_.rend();
00295 itor++)
00296 {
00297 GLWPanelEntry &entry = *itor;
00298 if ((*itor).widget->getVisible() &&
00299 (!entry.condition ||
00300 entry.condition->getResult(entry.widget)))
00301 {
00302 (*itor).widget->keyDown(buffer, keyState, history, hisCount, skipRest);
00303 if (skipRest) break;
00304 }
00305 }
00306 }
00307
00308 void GLWPanel::display()
00309 {
00310 std::list<GLWPanelEntry>::reverse_iterator itor;
00311 for (itor = widgets_.rbegin();
00312 itor != widgets_.rend();
00313 itor++)
00314 {
00315 GLWPanelEntry &entry = *itor;
00316 if ((*itor).widget->getVisible() &&
00317 (!entry.condition ||
00318 entry.condition->getResult(entry.widget)))
00319 {
00320 (*itor).widget->display();
00321 }
00322 }
00323 }
00324
00325 void GLWPanel::hide()
00326 {
00327 std::list<GLWPanelEntry>::reverse_iterator itor;
00328 for (itor = widgets_.rbegin();
00329 itor != widgets_.rend();
00330 itor++)
00331 {
00332 GLWPanelEntry &entry = *itor;
00333 if ((*itor).widget->getVisible() &&
00334 (!entry.condition ||
00335 entry.condition->getResult(entry.widget)))
00336 {
00337 (*itor).widget->hide();
00338 }
00339 }
00340 }
00341
00342 bool GLWPanel::initFromXML(XMLNode *node)
00343 {
00344 if (!GLWidget::initFromXML(node)) return false;
00345 drawPanel_ = false;
00346
00347
00348 XMLNode *itemsNode;
00349 if (!node->getNamedChild("items", itemsNode)) return false;
00350
00351
00352 std::list<XMLNode *>::iterator childrenItor;
00353 std::list<XMLNode *> &children = itemsNode->getChildren();
00354 for (childrenItor = children.begin();
00355 childrenItor != children.end();
00356 childrenItor++)
00357 {
00358
00359 XMLNode *currentNode = (*childrenItor);
00360
00361
00362 XMLNode *widgetNode, *widgetTypeNode;
00363 if (!currentNode->getNamedChild("widget", widgetNode)) return false;
00364 if (!widgetNode->getNamedParameter("type", widgetTypeNode)) return false;
00365
00366
00367 GLWidget *widget = (GLWidget *)
00368 MetaClassRegistration::getNewClass(widgetTypeNode->getContent());
00369 if (!widget)
00370 {
00371 S3D::dialogMessage("GLWPanel", S3D::formatStringBuffer(
00372 "Unknown widget type \"%s\"",
00373 widgetTypeNode->getContent()));
00374 return false;
00375 }
00376 if (!widget->initFromXML(widgetNode))
00377 {
00378 S3D::dialogMessage("GLWPanel", S3D::formatStringBuffer(
00379 "Failed to parse \"%s\" widget type",
00380 widgetTypeNode->getContent()));
00381 return false;
00382 }
00383 if (!widgetNode->failChildren()) return false;
00384
00385
00386 GLWCondition *condition = 0;
00387 XMLNode *conditionNode = 0;
00388 if (currentNode->getNamedChild("condition", conditionNode, false))
00389 {
00390
00391 XMLNode *conditionTypeNode;
00392 if (!conditionNode->getNamedParameter("type", conditionTypeNode)) return false;
00393
00394
00395 condition = (GLWCondition *)
00396 MetaClassRegistration::getNewClass(conditionTypeNode->getContent());
00397 if (!condition)
00398 {
00399 S3D::dialogMessage("GLWPanel", S3D::formatStringBuffer(
00400 "Unknown condition type \"%s\"",
00401 conditionTypeNode->getContent()));
00402 return false;
00403 }
00404 if (!condition->initFromXML(conditionNode))
00405 {
00406 S3D::dialogMessage("GLWPanel", S3D::formatStringBuffer(
00407 "Failed to parse \"%s\" condition type",
00408 conditionTypeNode->getContent()));
00409 return false;
00410 }
00411 }
00412
00413 addWidget(widget, condition);
00414 }
00415 return true;
00416 }
00417
00418 void GLWPanel::layout()
00419 {
00420 if (layout_ == LayoutNone) return;
00421
00422 float w = 0.0f;
00423 float h = 0.0f;
00424 float *gridW = 0;
00425 if (gridWidth_ > 0) gridW = new float[gridWidth_];
00426 for (unsigned int i=0; i<gridWidth_; i++) gridW[i] = 0.0f;
00427
00428
00429 int wid = 0;
00430 std::list<GLWPanelEntry>::iterator itor;
00431 for (itor = widgets_.begin();
00432 itor != widgets_.end();
00433 itor++, wid++)
00434 {
00435 GLWPanelEntry &entry = *itor;
00436
00437
00438 entry.widget->layout();
00439
00440
00441 float width = entry.widget->getW() +
00442 entry.leftSpace + entry.rightSpace;
00443 float height = entry.widget->getH() +
00444 entry.topSpace + entry.bottomSpace;
00445 if (layout_ == LayoutHorizontal)
00446 {
00447 w += width;
00448 h = MAX(h, height);
00449 }
00450 else if (layout_ == LayoutVerticle)
00451 {
00452 w = MAX(w, width);
00453 h += height;
00454 }
00455 else if (layout_ == LayoutGrid)
00456 {
00457 gridW[wid % gridWidth_] = MAX(gridW[wid % gridWidth_], width);
00458 h = MAX(h, height);
00459 }
00460 else DIALOG_ASSERT(0);
00461 }
00462
00463 float prevh = h;
00464 float prevw = w;
00465 if (layout_ == LayoutGrid)
00466 {
00467 DIALOG_ASSERT(gridWidth_ != 0);
00468
00469 w = 0.0f;
00470 for (unsigned int i=0; i<gridWidth_; i++) w += gridW[i];
00471 int rows = widgets_.size() / gridWidth_;
00472 if (widgets_.size() % gridWidth_ > 0) rows ++;
00473 h *= rows;
00474 }
00475
00476
00477 setW(w);
00478 setH(h);
00479
00480
00481 if (layout_ == LayoutHorizontal)
00482 {
00483 float width = 0.0f;
00484 for (itor = widgets_.begin();
00485 itor != widgets_.end();
00486 itor++)
00487 {
00488 GLWPanelEntry &entry = *itor;
00489 width += entry.leftSpace;
00490 entry.widget->setX(width);
00491
00492 if (entry.flags & AlignBottom)
00493 {
00494 entry.widget->setY(entry.bottomSpace);
00495 }
00496 else if (entry.flags & AlignCenterTopBottom)
00497 {
00498 entry.widget->setY(prevh / 2 -
00499 entry.widget->getH() / 2);
00500 }
00501 else if (entry.flags & AlignTop)
00502 {
00503 entry.widget->setY(prevh - entry.topSpace -
00504 entry.widget->getH());
00505 }
00506 else DIALOG_ASSERT(0);
00507
00508 width += entry.widget->getW();
00509 width += entry.rightSpace;
00510 }
00511 }
00512 else if (layout_ == LayoutVerticle)
00513 {
00514 float height = getH();
00515 for (itor = widgets_.begin();
00516 itor != widgets_.end();
00517 itor++)
00518 {
00519 GLWPanelEntry &entry = *itor;
00520 height -= entry.topSpace;
00521 entry.widget->setY(height - entry.widget->getH());
00522
00523 if (entry.flags & AlignLeft)
00524 {
00525 entry.widget->setX(entry.leftSpace);
00526 }
00527 else if (entry.flags & AlignCenterLeftRight)
00528 {
00529 entry.widget->setX(prevw / 2 -
00530 entry.widget->getW() / 2);
00531 }
00532 else if (entry.flags & AlignRight)
00533 {
00534 entry.widget->setX(prevw - entry.rightSpace -
00535 entry.widget->getW());
00536 }
00537 else DIALOG_ASSERT(0);
00538
00539 height -= entry.widget->getH();
00540 height -= entry.bottomSpace;
00541 }
00542 }
00543 else if (layout_ == LayoutGrid)
00544 {
00545 unsigned int cell = 0;
00546 float width = 0.0f;
00547 float height = getH();
00548 for (itor = widgets_.begin();
00549 itor != widgets_.end();
00550 itor++)
00551 {
00552 GLWPanelEntry &entry = *itor;
00553
00554 float prevw = gridW[cell];
00555
00556 if (entry.flags & AlignLeft)
00557 {
00558 entry.widget->setX(width + entry.leftSpace);
00559 }
00560 else if (entry.flags & AlignCenterLeftRight)
00561 {
00562 entry.widget->setX(width + prevw / 2 -
00563 entry.widget->getW() / 2);
00564 }
00565 else if (entry.flags & AlignRight)
00566 {
00567 entry.widget->setX(width + prevw - entry.rightSpace -
00568 entry.widget->getW());
00569 }
00570 else DIALOG_ASSERT(0);
00571
00572 if (entry.flags & AlignBottom)
00573 {
00574 entry.widget->setY(height - prevh + entry.bottomSpace);
00575 }
00576 else if (entry.flags & AlignCenterTopBottom)
00577 {
00578 entry.widget->setY(height - prevh / 2 -
00579 entry.widget->getH() / 2);
00580 }
00581 else if (entry.flags & AlignTop)
00582 {
00583 entry.widget->setY(height - entry.topSpace -
00584 entry.widget->getH());
00585 }
00586 else DIALOG_ASSERT(0);
00587
00588 if (++cell >= gridWidth_)
00589 {
00590 cell = 0;
00591 width = 0.0f;
00592 height -= prevh;
00593 }
00594 else
00595 {
00596 width += prevw;
00597 }
00598 }
00599 }
00600 else DIALOG_ASSERT(0);
00601
00602 delete [] gridW;
00603 }
00604
00605 void GLWPanel::setLayout(unsigned int layout)
00606 {
00607 layout_ = layout;
00608 }
00609
00610 unsigned int GLWPanel::getLayout()
00611 {
00612 return layout_;
00613 }
00614
00615 void GLWPanel::setGridWidth(unsigned int width)
00616 {
00617 gridWidth_ = width;
00618 }
00619
00620 unsigned int GLWPanel::getGridWidth()
00621 {
00622 return gridWidth_;
00623 }
00624