void StGLRootWidget::stglResize(const StGLBoxPx& theRectPx) { const bool isChanged = getRectPx().right() != theRectPx.width() || getRectPx().bottom() != theRectPx.height(); myProjCamera.resize(*myGlCtx, theRectPx.width(), theRectPx.height()); changeRectPx().right() = theRectPx.width(); // (left, top) forced to zero point (0, 0) changeRectPx().bottom() = theRectPx.height(); myProjCamera.getZParams(myRectGl); myScaleGlX = (myRectGl.right() - myRectGl.left()) / GLdouble(getRectPx().width()); myScaleGlY = (myRectGl.top() - myRectGl.bottom()) / GLdouble(getRectPx().height()); myScrProjMat = myProjCamera.getProjMatrix(); myScrProjMat.translate(StGLVec3(0.0f, 0.0f, -myProjCamera.getZScreen())); if(myMenuProgram->isValid()) { myMenuProgram->use(*myGlCtx); myMenuProgram->setProjMat(*myGlCtx, getScreenProjection()); myMenuProgram->unuse(*myGlCtx); } // update all child widgets if(isChanged) { StGLWidget::stglResize(); } }
bool StGLSwitchTextured::stglInit() { bool isOK = StGLWidget::stglInit(); StGLWidget* aChild = getChildren()->getStart(); if(aChild != NULL) { // just upsacle to fit children changeRectPx().right() = getRectPx().left() + aChild->getRectPx().width(); changeRectPx().bottom() = getRectPx().top() + aChild->getRectPx().height(); } return isOK; }
void StGLScrollArea::stglResize() { StGLWidget* aContent = myChildren.getStart(); StGLContext& aCtx = getContext(); if(!isScrollable() && aContent != NULL && aContent->getRectPx().top() < 0 && aContent->getCorner().v == ST_VCORNER_TOP) { const int aDelta = -aContent->getRectPx().top(); aContent->changeRectPx().top() += aDelta; aContent->changeRectPx().bottom() += aDelta; } if(isScrollable() && aContent != NULL) { const int aSizeY = stMax(getRectPx().height(), 1); const int aContSizeY = aContent->getRectPx().height(); const double aScaleY = double(aSizeY) / double(aContSizeY); const int aScrollSizeY = stMax(int(aScaleY * (double )aSizeY), myRoot->scale(4)); const double aPosY = double(-aContent->getRectPx().top()) / double(aContSizeY - aSizeY); StArray<StGLVec2> aVertices(4); StRectI_t aRectPx = getRectPxAbsolute(); aRectPx.left() = aRectPx.right() - myRoot->scale(2); aRectPx.top() += int(aPosY * double(aSizeY - aScrollSizeY)); aRectPx.bottom() = aRectPx.top() + aScrollSizeY; myRoot->getRectGl(aRectPx, aVertices); myBarVertBuf.init(aCtx, aVertices); } else { myBarVertBuf.release(aCtx); } StGLWidget::stglResize(); }
bool StGLButton::stglInit() { const int aWidth = myWidth; if(!StGLMenu::stglInit()) { return false; } myWidth = aWidth; StGLMenuItem* anItem = (StGLMenuItem* )getChildren()->getStart(); if(anItem == NULL) { return true; } anItem->changeRectPx().left() = 0; anItem->changeRectPx().right() = myWidth; anItem->changeRectPx().bottom() = anItem->changeRectPx().top() + myItemHeight; anItem->setTextWidth(myWidth); changeRectPx().right() = getRectPx().left() + myWidth; changeRectPx().bottom() = getRectPx().top() + myItemHeight; return true; }
bool StGLRangeFieldFloat32::stglInit() { if(myValueText != NULL) { return true; } myValueText = new StGLTextArea(this, 0, 0, StGLCorner(ST_VCORNER_CENTER, ST_HCORNER_LEFT), -myRoot->scale(1), myRoot->scale(10)); onValueChange(0.0f); myValueText->setTextColor(StGLVec3(1.0f, 1.0f, 1.0f)); myValueText->setVisibility(true, true); if(!myValueText->stglInitAutoHeightWidth()) { delete myValueText; myValueText = NULL; return false; } myValueText->changeRectPx().right() += myRoot->scale(10); myValueText->setTextWidth(myValueText->getRectPx().width()); myValueText->setupAlignment(StGLTextFormatter::ST_ALIGN_X_RIGHT, StGLTextFormatter::ST_ALIGN_Y_TOP); onValueChange(myTrackValue->getValue()); const GLint aHeight = myValueText->getRectPx().height(); StGLButton* aButDec = new StGLButton(this, 0, 0, "-"); aButDec->setCorner(StGLCorner(ST_VCORNER_CENTER, ST_HCORNER_LEFT)); aButDec->setHeight(aHeight); aButDec->setWidth(myRoot->scale(15)); aButDec->setVisibility(true, true); aButDec->signals.onBtnClick += stSlot(this, &StGLRangeFieldFloat32::doDecrement); myValueText->changeRectPx().moveLeftTo(aButDec->getRectPx().right() - myRoot->scale(5)); StGLButton* aButInc = new StGLButton(this, myValueText->getRectPx().right() + myRoot->scale(5), 0, "+"); aButInc->setCorner(StGLCorner(ST_VCORNER_CENTER, ST_HCORNER_LEFT)); aButInc->setHeight(aHeight); aButInc->setWidth(myRoot->scale(15)); aButInc->setVisibility(true, true); aButInc->signals.onBtnClick += stSlot(this, &StGLRangeFieldFloat32::doIncrement); changeRectPx().right() = getRectPx().left() + aButInc->getRectPx().right(); changeRectPx().bottom() = getRectPx().top() + aHeight; return StGLWidget::stglInit(); }
void StGLRootWidget::stglScissorRect(const StRectI_t& theRect, StGLBoxPx& theScissorRect) const { const GLint aVPortWidth = myViewport[2]; const GLint aVPortHeight = myViewport[3]; const GLint aRootWidth = getRectPx().width(); const GLint aRootHeight = getRectPx().height(); if(aRootWidth <= 0 || aRootHeight <= 0) { // just prevent division by zero - should never happen stMemZero(&theScissorRect, sizeof(StGLBoxPx)); return; } // viewport could have different size in case of rendering to FBO const GLdouble aWidthFactor = GLdouble(aVPortWidth) / GLdouble(aRootWidth); const GLdouble aHeightFactor = GLdouble(aVPortHeight) / GLdouble(aRootHeight); theScissorRect.x() = myViewport[0] + GLint(aWidthFactor * GLdouble(theRect.left())) + myScrDispXPx; theScissorRect.y() = myViewport[1] + GLint(aHeightFactor * GLdouble(aRootHeight - theRect.bottom())); theScissorRect.width() = GLint(aWidthFactor * GLdouble(theRect.width())); theScissorRect.height() = GLint(aHeightFactor * GLdouble(theRect.height())); }
bool StGLScrollArea::stglInit() { if(!StGLWidget::stglInit()) { return false; } stglResize(); // extend text area to fit whole text StGLTextArea* aText = dynamic_cast<StGLTextArea*> (myChildren.getStart()); if(aText != NULL) { aText->changeRectPx().bottom() = aText->getRectPx().top() + aText->getTextHeight(); if(aText->getRectPx().height() < getRectPx().height()) { aText->setCorner(StGLCorner(ST_VCORNER_CENTER, ST_HCORNER_LEFT)); } } return true; }
bool StGLScrollArea::doScroll(const int theDelta, const bool theIsFling) { if(!theIsFling) { myDragYDelta = 0.0; myFlingTimer.stop(); } if(!isScrollable()) { return false; } StGLWidget* aContent = myChildren.getStart(); const int aMinLim = 0; const int aMaxLim = getRectPx().height() - aContent->getRectPx().height(); const int aTopOld = aContent->getRectPx().top(); const int aTopNew = stMax(stMin(aMinLim, aTopOld + theDelta), aMaxLim); const int aDelta = aTopNew - aTopOld; if(aDelta == 0) { if(theIsFling) { myFlingTimer.stop(); } return false; } aContent->changeRectPx().top() += aDelta; aContent->changeRectPx().bottom() += aDelta; if(myIsLeftClick) { if(!theIsFling) { myDragYCumul += aDelta; if(std::abs(myDragYCumul) > myRoot->getClickThreshold() && !myHasDragged) { setClickedWithChildren(myChildren, ST_MOUSE_LEFT, false); myHasDragged = true; } } else { myDragYCumul = 0; } } myIsResized = true; return true; }
bool StGLMenu::stglInit() { myWidth = 0; myIsInitialized = StGLWidget::stglInit(); if(!myIsInitialized) { return false; } int aMarginLeft = 0; for(StGLWidget* aChild = getChildren()->getStart(); aChild != NULL; aChild = aChild->getNext()) { StGLMenuItem* anItem = (StGLMenuItem* )aChild; aMarginLeft = stMax(aMarginLeft, anItem->getMargins().left); int anItemW = anItem->getMargins().left + anItem->computeTextWidth() + anItem->getMargins().right; if(myOrient == MENU_HORIZONTAL) { anItem->changeRectPx().moveLeftTo(myWidth); anItem->changeRectPx().right() = anItem->getRectPx().left() + anItemW; anItem->setTextWidth(anItemW - anItem->getMargins().left); myWidth += anItemW; } else { myWidth = stMax(myWidth, anItemW); } if(anItem->getSubMenu() != NULL) { if(myOrient == MENU_HORIZONTAL) { anItem->getSubMenu()->changeRectPx().moveTopLeftTo(anItem->getRectPxAbsolute().left(), anItem->getRectPxAbsolute().bottom()); } else if(myOrient == MENU_VERTICAL || myOrient == MENU_VERTICAL_COMPACT) { anItem->getSubMenu()->changeRectPx().moveTopLeftTo(anItem->getRectPxAbsolute().right() - myRoot->scale(10), anItem->getRectPxAbsolute().top()); } } } StGLWidget* aChildLast = getChildren()->getLast(); if(aChildLast != NULL) { changeRectPx().right() = getRectPx().left() + aChildLast->getRectPx().right(); changeRectPx().bottom() = getRectPx().top() + aChildLast->getRectPx().bottom(); } int aWidth = stMax(myWidthMin, myWidth); if(myOrient == MENU_VERTICAL || myOrient == MENU_VERTICAL_COMPACT) { changeRectPx().right() = getRectPx().left() + aWidth; int anItemCount = 0; for(StGLWidget* aChild = getChildren()->getStart(); aChild != NULL; aChild = aChild->getNext(), ++anItemCount) { StGLMenuItem* anItem = (StGLMenuItem* )aChild; anItem->changeRectPx().moveTopTo(anItemCount * myItemHeight); anItem->changeRectPx().right() = anItem->getRectPx().left() + aWidth; anItem->setTextWidth(aWidth); if(anItem->getSubMenu() != NULL) { anItem->getSubMenu()->changeRectPx().moveTopLeftTo(getRectPxAbsolute().right() - myRoot->scale(10), anItem->getRectPxAbsolute().top()); } } changeRectPx().bottom() = getRectPx().top() + anItemCount * myItemHeight; } // already initialized? if(myVertexBuf.isValid()) { // synchronize menu items visibility setOpacity(myOpacity, true); return true; } stglResize(); return myIsInitialized; }