void updateVertical() { // Both edges must be defined, otherwise the rectangle's position is ambiguous. bool topDefined = false; bool bottomDefined = false; Rectanglef r; if(inputRules[Rule::AnchorY] && inputRules[Rule::Height]) { r.topLeft.y = inputRules[Rule::AnchorY]->value() - normalizedAnchorPoint.y * inputRules[Rule::Height]->value(); r.setHeight(inputRules[Rule::Height]->value()); topDefined = bottomDefined = true; } if(inputRules[Rule::Top]) { r.topLeft.y = inputRules[Rule::Top]->value(); topDefined = true; } if(inputRules[Rule::Bottom]) { r.bottomRight.y = inputRules[Rule::Bottom]->value(); bottomDefined = true; } if(inputRules[Rule::Height] && topDefined && !bottomDefined) { r.setHeight(inputRules[Rule::Height]->value()); bottomDefined = true; } if(inputRules[Rule::Height] && !topDefined && bottomDefined) { r.topLeft.y = r.bottomRight.y - inputRules[Rule::Height]->value(); topDefined = true; } #ifdef _DEBUG if(!topDefined || !bottomDefined) { qDebug() << self.description().toLatin1(); } #endif DENG2_ASSERT(topDefined); DENG2_ASSERT(bottomDefined); // Update the derived output rules. outputRules[OutTop]->set(r.topLeft.y); outputRules[OutBottom]->set(r.bottomRight.y); outputRules[OutHeight]->set(r.height()); }
void updateHorizontal() { // Both edges must be defined, otherwise the rectangle's position is ambiguous. bool leftDefined = false; bool rightDefined = false; Rectanglef r; if(inputRules[Rule::AnchorX] && inputRules[Rule::Width]) { r.topLeft.x = inputRules[Rule::AnchorX]->value() - normalizedAnchorPoint.x * inputRules[Rule::Width]->value(); r.setWidth(inputRules[Rule::Width]->value()); leftDefined = rightDefined = true; } if(inputRules[Rule::Left]) { r.topLeft.x = inputRules[Rule::Left]->value(); leftDefined = true; } if(inputRules[Rule::Right]) { r.bottomRight.x = inputRules[Rule::Right]->value(); rightDefined = true; } if(inputRules[Rule::Width] && leftDefined && !rightDefined) { r.setWidth(inputRules[Rule::Width]->value()); rightDefined = true; } if(inputRules[Rule::Width] && !leftDefined && rightDefined) { r.topLeft.x = r.bottomRight.x - inputRules[Rule::Width]->value(); leftDefined = true; } #ifdef _DEBUG if(!leftDefined || !rightDefined) { qDebug() << self.description().toLatin1(); } #endif DENG2_ASSERT(leftDefined); DENG2_ASSERT(rightDefined); outputRules[OutLeft]->set(r.topLeft.x); outputRules[OutRight]->set(r.bottomRight.x); outputRules[OutWidth]->set(r.width()); }
Matrix4f modelMatrix() const { DENG2_ASSERT(vbuf); if (mapBounds.isNull()) return Matrix4f(); Rectanglef const rect = self().contentRect(); float const scale = de::min(rect.width() / mapBounds.width(), rect.height() / mapBounds.height()); return Matrix4f::translate(rect.middle()) * Matrix4f::scale (Vector3f(scale, -scale, 1)) * Matrix4f::translate(Vector2f(-mapBounds.middle())); }
void ListBox::Draw( SpriteBatch& spriteBatch, SpriteBatch& spriteBatchFont ) { if (!mVisible) return; int2 screenPos = GetScreenPosition(); float zOrder = GetDepthLayer(); // Draw background first Rectanglef backRC((float)screenPos.X(), (float)screenPos.Y(), (float)mSize.X(), (float)mSize.Y()); mLisBoxStyle->DrawNinePatch(spriteBatch, UI_State_Normal, backRC, zOrder); if (mItems.size()) { int mimItem, maxItem; mVertScrollBar->GetScrollRange(&mimItem, &maxItem); Rectanglef rc((float)mTextRegion.X, (float)mTextRegion.Y, (float)mTextRegion.Width, (float)mTextRegion.Height); rc.SetBottom( rc.Y + mTextRowHeight); for (int i = mVertScrollBar->GetScrollValue(); i < maxItem + mNumVisibleItems; ++i) { if (rc.Bottom() > (float)mTextRegion.Bottom()) break; if( i == mSelectedIndex ) { // Draw selected highlight Rectanglef rcSel; rcSel.SetLeft(mSelectionRegion.Left()+1); rcSel.SetRight(mSelectionRegion.Right()); rcSel.SetTop((float)rc.Top()); rcSel.SetBottom((float)rc.Bottom()); spriteBatch.Draw(mLisBoxStyle->StyleTex, rcSel, &mLisBoxStyle->StyleStates[UI_State_Hover].TexRegion, mLisBoxStyle->StyleStates[UI_State_Hover].TexColor, zOrder); } // draw text //Rectanglef region((float)rc.X, (float)rc.Y, (float)rc.Width, (float)rc.Height); mLisBoxStyle->Font->DrawString(spriteBatchFont, mItems[i], mLisBoxStyle->FontSize, AlignVCenter, rc, mLisBoxStyle->ForeColor, zOrder); rc.Offset(0, mTextRowHeight); } } }
void TextField::render(Graphics::ptr graphics) { Rectanglef tempRect = PosRect; float letterWidth = PosRect.getSize().y * 0.5f; tempRect.setSize(glm::vec2(letterWidth,PosRect.getSize().y)); FontandKeyMapping::image_map& tempkeymap = FaKM.getKeyMap(); for(unsigned int i = 0; i < Text.length(); i++) { graphics->drawTexture(tempkeymap[Text[i]],tempRect,depth, glm::vec3(0.f)); tempRect.setPosition(glm::vec2((tempRect.getPosition().x + letterWidth),tempRect.getPosition().y)); } if(!active) { graphics->drawTexture(deactiveBackground,PosRect,depth + 0.01f, glm::vec3(1.f)); } else { graphics->drawTexture(activeBackground,PosRect,depth + 0.01f, glm::vec3(1.f)); } }
void makeFlare(VBuf::Vertices & verts, VBuf::Indices & idx, FlareData::FlareId id, float axisPos, float radius, Vector4f color, PVLight const * pvl) { Rectanglef const uvRect = res->uvRect(id); int const firstIdx = verts.size(); VBuf::Type vtx; vtx.pos = pvl->light->lightSourceOrigin().xzy(); vtx.rgba = Vector4f(pvl->light->lightSourceColorf(), 1.f) * color; vtx.texCoord[2] = Vector2f(axisPos, 0); vtx.texCoord[0] = uvRect.topLeft; vtx.texCoord[1] = res->flareCorner(id, FlareData::TopLeft) * radius; verts << vtx; vtx.texCoord[0] = uvRect.topRight(); vtx.texCoord[1] = res->flareCorner(id, FlareData::TopRight) * radius; verts << vtx; vtx.texCoord[0] = uvRect.bottomRight; vtx.texCoord[1] = res->flareCorner(id, FlareData::BottomRight) * radius; verts << vtx; vtx.texCoord[0] = uvRect.bottomLeft(); vtx.texCoord[1] = res->flareCorner(id, FlareData::BottomLeft) * radius; verts << vtx; // Make two triangles. idx << firstIdx << firstIdx + 1 << firstIdx + 2 << firstIdx << firstIdx + 2 << firstIdx + 3; }
float scoreForWidget(GuiWidget const &widget, ui::Direction dir) const { if (!widget.canBeFocused() || &widget == thisPublic) { return -1; } Rectanglef const viewRect = self().root().viewRule().rect(); Rectanglef const selfRect = self().hitRule().rect(); Rectanglef const otherRect = widget.hitRule().rect(); Vector2f const otherMiddle = (dir == ui::Up? otherRect.midBottom() : dir == ui::Down? otherRect.midTop() : dir == ui::Left? otherRect.midRight() : otherRect.midLeft() ); //otherRect.middle(); if (!viewRect.contains(otherMiddle)) { return -1; } bool const axisOverlap = (isHorizontal(dir) && !selfRect.vertical() .intersection(otherRect.vertical()) .isEmpty()) || (isVertical(dir) && !selfRect.horizontal().intersection(otherRect.horizontal()).isEmpty()); // Check for contacting edges. float edgeDistance = 0; // valid only if axisOverlap if (axisOverlap) { switch (dir) { case ui::Left: edgeDistance = selfRect.left() - otherRect.right(); break; case ui::Up: edgeDistance = selfRect.top() - otherRect.bottom(); break; case ui::Right: edgeDistance = otherRect.left() - selfRect.right(); break; default: edgeDistance = otherRect.top() - selfRect.bottom(); break; } // Very close edges are considered contacting. if (edgeDistance >= 0 && edgeDistance < toDevicePixels(5)) { return edgeDistance; } } Vector2f const middle = (dir == ui::Up? selfRect.midTop() : dir == ui::Down? selfRect.midBottom() : dir == ui::Left? selfRect.midLeft() : selfRect.midRight() ); Vector2f const delta = otherMiddle - middle; Vector2f const dirVector = directionVector(dir); auto dotProd = delta.normalize().dot(dirVector); if (dotProd <= 0) { // On the wrong side. return -1; } float distance = delta.length(); if (axisOverlap) { dotProd = 1.0; if (edgeDistance > 0) { distance = de::min(distance, edgeDistance); } } float favorability = 1; if (widget.parentWidget() == self().parentWidget()) { favorability = .1f; // Siblings are much preferred. } else if (self().hasAncestor(widget) || widget.hasAncestor(self())) { favorability = .2f; // Ancestry is also good. } // Prefer widgets that are nearby, particularly in the specified direction. return distance * (.5f + acos(dotProd)) * favorability; }