/*! SLButton::closeAll closes all menus except the root menu */ void SLButton::closeAll() { SLScene* s = SLScene::current; SLButton* mnu2D = s->menu2D(); if (!mnu2D) return; mnu2D->hideAndReleaseRec(); mnu2D->drawBits()->off(SL_DB_HIDDEN); // update world matrices & AABBs _stateGL->pushModelViewMatrix(); _stateGL->modelViewMatrix.identity(); mnu2D->translation(0, 0, 0); mnu2D->updateAABBRec(); _stateGL->popModelViewMatrix(); newMenuPos.set(0,0); oldMenuPos.set(0,0); buttonDown = 0; buttonParent = 0; }
/*! SLButton::onMouseUp handles events and returns true if refresh is needed. This method holds the main functionality for the buttons command execution as well as the hiding and showing of the sub menus. */ SLbool SLButton::onMouseUp(const SLMouseButton button, const SLint x, const SLint y, const SLKey mod) { SLScene* s = SLScene::current; SLButton* mnu2D = s->menu2D(); SLButton* btn = 0; // button pointer for various loops if (!mnu2D) return false; // GUI space is bottom left! SLint h = _sv->scrH()-y; if (x > _aabb.minWS().x && x < _aabb.maxWS().x && h > _aabb.minWS().y && h < _aabb.maxWS().y && !_drawBits.get(SL_DB_HIDDEN)) { if (buttonDown==this) { // For a command execute it if (_command != C_menu) { _isDown = false; // Toggle checkable buttons if (_isCheckable && !_radioParent) _isChecked = !_isChecked; // For radio buttons uncheck others if (_radioParent) _radioParent->checkRadioRec(); // Hide all menus again if (_closeOnClick) closeAll(); ///////////////////////// _sv->onCommand(_command); ///////////////////////// if (_closeOnClick) return true; } else if (_children.size()>0) { // if another menu on the same or higher level is open hide it first if (buttonParent && buttonParent!=this && buttonParent->depth()>=_depth) { while (buttonParent && buttonParent->depth() >= depth()) { for (auto child : buttonParent->children()) child->drawBits()->set(SL_DB_HIDDEN, true); buttonParent->isDown(false); buttonParent = (SLButton*)buttonParent->parent(); } } // show my submenu buttons btn = (SLButton*)_children[0]; if (btn && btn->drawBits()->get(SL_DB_HIDDEN)) { for (auto child : _children) child->drawBits()->set(SL_DB_HIDDEN, false); buttonParent = this; } else // submenu is already open so close everything { if (buttonDown==mnu2D) { mnu2D->hideAndReleaseRec(); mnu2D->drawBits()->off(SL_DB_HIDDEN); buttonParent = 0; } else { if (buttonParent) { for (auto child : buttonParent->children()) child->drawBits()->set(SL_DB_HIDDEN, true); buttonParent->isDown(false); buttonParent = (SLButton*)(buttonParent->parent()); } } } } // Move menu left or right if (buttonParent) { newMenuPos.set(-buttonParent->minX()+minMenuPos.x, 0); if (newMenuPos != oldMenuPos) { mnu2D->translate(newMenuPos.x - oldMenuPos.x, 0, 0, TS_object); // update AABB's _stateGL->pushModelViewMatrix(); _stateGL->modelViewMatrix.identity(); oldMenuPos.set(newMenuPos); mnu2D->updateAABBRec(); _stateGL->popModelViewMatrix(); } } buttonDown = 0; return true; } else // mouse up on a different button, so release it { if (buttonDown) { buttonDown->_isDown = false; buttonDown = 0; return true; } } } // check sub menus for (auto child : _children) { if (child->onMouseUp(button, x, y, mod)) return true; } // check if mouse down was on this button and the up was on the scene if (_isDown && buttonDown==this) { closeAll(); return true; } return false; }