void TextEditComponent::render(const Transform4x4f& parentTrans) { Transform4x4f trans = getTransform() * parentTrans; renderChildren(trans); // text + cursor rendering // offset into our "text area" (padding) trans.translation() += Vector3f(getTextAreaPos().x(), getTextAreaPos().y(), 0); Vector2i clipPos((int)trans.translation().x(), (int)trans.translation().y()); Vector3f dimScaled = trans * Vector3f(getTextAreaSize().x(), getTextAreaSize().y(), 0); // use "text area" size for clipping Vector2i clipDim((int)(dimScaled.x() - trans.translation().x()), (int)(dimScaled.y() - trans.translation().y())); Renderer::pushClipRect(clipPos, clipDim); trans.translate(Vector3f(-mScrollOffset.x(), -mScrollOffset.y(), 0)); trans.round(); Renderer::setMatrix(trans); if(mTextCache) { mFont->renderTextCache(mTextCache.get()); } // pop the clip early to allow the cursor to be drawn outside of the "text area" Renderer::popClipRect(); // draw cursor if(mEditing) { Vector2f cursorPos; if(isMultiline()) { cursorPos = mFont->getWrappedTextCursorOffset(mText, getTextAreaSize().x(), mCursor); }else{ cursorPos = mFont->sizeText(mText.substr(0, mCursor)); cursorPos[1] = 0; } float cursorHeight = mFont->getHeight() * 0.8f; Renderer::drawRect(cursorPos.x(), cursorPos.y() + (mFont->getHeight() - cursorHeight) / 2, 2.0f, cursorHeight, 0x000000FF); } }
// Draw background extras void SystemView::renderExtras(const Transform4x4f& trans, float lower, float upper) { int extrasCenter = (int)mExtrasCamOffset; // Adding texture loading buffers depending on scrolling speed and status int bufferIndex = getScrollingVelocity() + 1; Renderer::pushClipRect(Vector2i::Zero(), Vector2i((int)mSize.x(), (int)mSize.y())); for (int i = extrasCenter + logoBuffersLeft[bufferIndex]; i <= extrasCenter + logoBuffersRight[bufferIndex]; i++) { int index = i; while (index < 0) index += (int)mEntries.size(); while (index >= (int)mEntries.size()) index -= (int)mEntries.size(); //Only render selected system when not showing if (mShowing || index == mCursor) { Transform4x4f extrasTrans = trans; if (mCarousel.type == HORIZONTAL || mCarousel.type == HORIZONTAL_WHEEL) extrasTrans.translate(Vector3f((i - mExtrasCamOffset) * mSize.x(), 0, 0)); else extrasTrans.translate(Vector3f(0, (i - mExtrasCamOffset) * mSize.y(), 0)); Renderer::pushClipRect(Vector2i((int)extrasTrans.translation()[0], (int)extrasTrans.translation()[1]), Vector2i((int)mSize.x(), (int)mSize.y())); SystemViewData data = mEntries.at(index).data; for (unsigned int j = 0; j < data.backgroundExtras.size(); j++) { GuiComponent *extra = data.backgroundExtras[j]; if (extra->getZIndex() >= lower && extra->getZIndex() < upper) { extra->render(extrasTrans); } } Renderer::popClipRect(); } } Renderer::popClipRect(); }
// Render system carousel void SystemView::renderCarousel(const Transform4x4f& trans) { // background box behind logos Transform4x4f carouselTrans = trans; carouselTrans.translate(Vector3f(mCarousel.pos.x(), mCarousel.pos.y(), 0.0)); carouselTrans.translate(Vector3f(mCarousel.origin.x() * mCarousel.size.x() * -1, mCarousel.origin.y() * mCarousel.size.y() * -1, 0.0f)); Vector2f clipPos(carouselTrans.translation().x(), carouselTrans.translation().y()); Renderer::pushClipRect(Vector2i((int)clipPos.x(), (int)clipPos.y()), Vector2i((int)mCarousel.size.x(), (int)mCarousel.size.y())); Renderer::setMatrix(carouselTrans); Renderer::drawRect(0.0, 0.0, mCarousel.size.x(), mCarousel.size.y(), mCarousel.color); // draw logos Vector2f logoSpacing(0.0, 0.0); // NB: logoSpacing will include the size of the logo itself as well! float xOff = 0.0; float yOff = 0.0; switch (mCarousel.type) { case VERTICAL_WHEEL: yOff = (mCarousel.size.y() - mCarousel.logoSize.y()) / 2.f - (mCamOffset * logoSpacing[1]); if (mCarousel.logoAlignment == ALIGN_LEFT) xOff = mCarousel.logoSize.x() / 10.f; else if (mCarousel.logoAlignment == ALIGN_RIGHT) xOff = mCarousel.size.x() - (mCarousel.logoSize.x() * 1.1f); else xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2.f; break; case VERTICAL: logoSpacing[1] = ((mCarousel.size.y() - (mCarousel.logoSize.y() * mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.y(); yOff = (mCarousel.size.y() - mCarousel.logoSize.y()) / 2.f - (mCamOffset * logoSpacing[1]); if (mCarousel.logoAlignment == ALIGN_LEFT) xOff = mCarousel.logoSize.x() / 10.f; else if (mCarousel.logoAlignment == ALIGN_RIGHT) xOff = mCarousel.size.x() - (mCarousel.logoSize.x() * 1.1f); else xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2; break; case HORIZONTAL_WHEEL: xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2 - (mCamOffset * logoSpacing[1]); if (mCarousel.logoAlignment == ALIGN_TOP) yOff = mCarousel.logoSize.y() / 10; else if (mCarousel.logoAlignment == ALIGN_BOTTOM) yOff = mCarousel.size.y() - (mCarousel.logoSize.y() * 1.1f); else yOff = (mCarousel.size.y() - mCarousel.logoSize.y()) / 2; break; case HORIZONTAL: default: logoSpacing[0] = ((mCarousel.size.x() - (mCarousel.logoSize.x() * mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.x(); xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2.f - (mCamOffset * logoSpacing[0]); if (mCarousel.logoAlignment == ALIGN_TOP) yOff = mCarousel.logoSize.y() / 10.f; else if (mCarousel.logoAlignment == ALIGN_BOTTOM) yOff = mCarousel.size.y() - (mCarousel.logoSize.y() * 1.1f); else yOff = (mCarousel.size.y() - mCarousel.logoSize.y()) / 2.f; break; } int center = (int)(mCamOffset); int logoCount = Math::min(mCarousel.maxLogoCount, (int)mEntries.size()); // Adding texture loading buffers depending on scrolling speed and status int bufferIndex = getScrollingVelocity() + 1; int bufferLeft = logoBuffersLeft[bufferIndex]; int bufferRight = logoBuffersRight[bufferIndex]; if (logoCount == 1) { bufferLeft = 0; bufferRight = 0; } for (int i = center - logoCount / 2 + bufferLeft; i <= center + logoCount / 2 + bufferRight; i++) { int index = i; while (index < 0) index += (int)mEntries.size(); while (index >= (int)mEntries.size()) index -= (int)mEntries.size(); Transform4x4f logoTrans = carouselTrans; logoTrans.translate(Vector3f(i * logoSpacing[0] + xOff, i * logoSpacing[1] + yOff, 0)); float distance = i - mCamOffset; float scale = 1.0f + ((mCarousel.logoScale - 1.0f) * (1.0f - fabs(distance))); scale = Math::min(mCarousel.logoScale, Math::max(1.0f, scale)); scale /= mCarousel.logoScale; int opacity = (int)Math::round(0x80 + ((0xFF - 0x80) * (1.0f - fabs(distance)))); opacity = Math::max((int) 0x80, opacity); const std::shared_ptr<GuiComponent> &comp = mEntries.at(index).data.logo; if (mCarousel.type == VERTICAL_WHEEL || mCarousel.type == HORIZONTAL_WHEEL) { comp->setRotationDegrees(mCarousel.logoRotation * distance); comp->setRotationOrigin(mCarousel.logoRotationOrigin); } comp->setScale(scale); comp->setOpacity((unsigned char)opacity); comp->render(logoTrans); } Renderer::popClipRect(); }