//------------------------------------------------------------------------------------------------- // Author: Márcio Martins // // Purpose: // - A Static Control // // History: // - [3/6/2003] created the file // //------------------------------------------------------------------------------------------------- #include "StdAfx.h" #include "UIStatic.h" #include "UIScrollBar.h" #include "UISystem.h" #include _DECLARE_SCRIPTABLEEX(CUIStatic) //------------------------------------------------------------------------------------------------- CUIStatic::CUIStatic() : m_fVerticalOffset(0), m_fHorizontalOffset(0), m_bVerticalScrollBar(0), m_bHorizontalScrollBar(0), m_pHScroll(0), m_pVScroll(0), m_iHAlignment(UIALIGN_LEFT), m_iVAlignment(UIALIGN_MIDDLE), m_fTotalWidth(0.0f), m_fTotalHeight(0.0f), m_fLineHeight(0), m_fLineSpacing(0.0f), m_pModel(0), m_fAngle(0), m_fCameraDistance(4.0f), m_fCameraFov(35.0f * gf_PI / 180.0f), m_fModelRotation(0.1f), m_fLightDistance(50.0f), m_fModelRotationAcc(1.0f), m_fMouseMultiplier(1.0f), m_iMaxLines(100), m_fLeftSpacing(0.0f), m_fRightSpacing(0.0f) { } //------------------------------------------------------------------------------------------------- CUIStatic::~CUIStatic() { ReleaseModel(); } //------------------------------------------------------------------------------------------------- string CUIStatic::GetClassName() { return UICLASSNAME_STATIC; } //------------------------------------------------------------------------------------------------- int CUIStatic::SetStyle(int iStyle) { return CUIWidget::SetStyle(iStyle); } //------------------------------------------------------------------------------------------------- LRESULT CUIStatic::Update(unsigned int iMessage, WPARAM wParam, LPARAM lParam) //AMD Port { switch(iMessage) { case UIM_DRAW: { if (m_iStyle & UISTYLE_MULTILINE) { m_pVScroll = (CUIScrollBar *)GetChild("vscrollbar"); m_pHScroll = (CUIScrollBar *)GetChild("hscrollbar"); IFFont *pFont = m_pUISystem->GetIFont(m_pFont); // get the rect where we are allowed to draw UIRect pTextRect = GetTextRect(1); UIRect pRect = GetTextRect(0); bool bVScroll = 0, bHScroll = 0; // get the total height m_fTotalHeight = GetTextHeight(); m_fTotalWidth = GetTextWidth(); // check if we need scrollbars bVScroll = (m_fTotalHeight > pTextRect.fHeight); bHScroll = (m_fTotalWidth > pTextRect.fWidth); if (bHScroll && !m_pHScroll) { m_pUISystem->CreateScrollBar(&m_pHScroll, this, "hscrollbar", UIRect(0, 0, 0, 16.0f), UIFLAG_ENABLED, 0, UISCROLLBARTYPE_HORIZONTAL); } if (bVScroll && !m_pVScroll) { m_pUISystem->CreateScrollBar(&m_pVScroll, this, "vscrollbar", UIRect(0, 0, 16.0f, 0.0f), UIFLAG_ENABLED, 0, UISCROLLBARTYPE_VERTICAL); } // set the bar rects and values if (bVScroll && !m_bVerticalScrollBar) { m_bVerticalScrollBar = 1; m_pVScroll->SetFlags(m_pVScroll->GetFlags() | UIFLAG_VISIBLE); if (m_iVAlignment == UIALIGN_BOTTOM) { m_pVScroll->SetValue(1.0f); } else if (m_iVAlignment == UIALIGN_MIDDLE) { m_pVScroll->SetValue(0.5f); } else { m_pVScroll->SetValue(0.0f); } GetLineListMetrics(); } else if (!bVScroll && m_bVerticalScrollBar) { m_bVerticalScrollBar = 0; } // check if we need an horizontal scrollbar if (bHScroll && !m_bHorizontalScrollBar) { m_bHorizontalScrollBar = 1; m_pHScroll->SetFlags(m_pHScroll->GetFlags() | UIFLAG_VISIBLE); if (m_iHAlignment == UIALIGN_RIGHT) { m_pHScroll->SetValue(1.0f); } else if (m_iHAlignment == UIALIGN_CENTER) { m_pHScroll->SetValue(0.5f); } else { m_pHScroll->SetValue(0.0f); } } else if (!bHScroll && m_bHorizontalScrollBar) { m_bHorizontalScrollBar = 0; } // convert pRect to relative coordinates m_pUISystem->GetRelativeXY(&pRect.fLeft, &pRect.fTop, pRect.fLeft, pRect.fTop, this); // set step sizes and rects if (m_bVerticalScrollBar) { UIRect pVScrollRect; pVScrollRect.fLeft = pRect.fLeft + pRect.fWidth - m_pUISystem->GetWidgetRect(m_pVScroll).fWidth; pVScrollRect.fTop = pRect.fTop; pVScrollRect.fWidth = m_pUISystem->GetWidgetRect(m_pVScroll).fWidth; pVScrollRect.fHeight = pRect.fHeight - (m_bHorizontalScrollBar ? m_pUISystem->GetWidgetRect(m_pHScroll).fHeight : 0); m_pVScroll->SetRect(pVScrollRect, 1); m_pVScroll->SetStep(m_fLineHeight / (m_fTotalHeight - pTextRect.fHeight)); } else { m_fVerticalOffset = 0; if (m_pVScroll) { m_pVScroll->SetFlags(m_pVScroll->GetFlags() & ~UIFLAG_VISIBLE); } } if (m_bHorizontalScrollBar) { UIRect pHScrollRect; pHScrollRect.fLeft = pRect.fLeft; pHScrollRect.fTop = pRect.fTop + pRect.fHeight - m_pUISystem->GetWidgetRect(m_pHScroll).fHeight; pHScrollRect.fWidth = pRect.fWidth - (m_bVerticalScrollBar ? m_pUISystem->GetWidgetRect(m_pVScroll).fWidth : 0); pHScrollRect.fHeight = m_pUISystem->GetWidgetRect(m_pHScroll).fHeight; m_pHScroll->SetRect(pHScrollRect, 1); m_pHScroll->SetStep((m_fTotalWidth - pTextRect.fWidth) / m_fTotalWidth); } else { m_fHorizontalOffset = 0; if (m_pHScroll) { m_pHScroll->SetFlags(m_pHScroll->GetFlags() & ~UIFLAG_VISIBLE); } } } } break; case UIM_LBUTTONDBLCLICK: { OnCommand(); } break; case UIM_LBUTTONDOWN: { m_fModelRotationAcc = 0.0f; } break; case UIM_MOUSEUP: { m_fModelRotationAcc = 1.0f; } case UIM_MOUSEMOVE: { if (m_fModelRotationAcc == 0.0f) { m_fAngle += (UIM_GET_X_FLOAT(lParam) - UIM_GET_X_FLOAT(wParam)) * m_fMouseMultiplier; } } break; default: break; } return CUISystem::DefaultUpdate(this, iMessage, wParam, lParam); } //------------------------------------------------------------------------------------------------- int CUIStatic::Draw(int iPass) { if (iPass != 0) { return 1; } m_pUISystem->BeginDraw(this); // get the absolute widget rect UIRect pAbsoluteRect(m_pRect); m_pUISystem->GetAbsoluteXY(&pAbsoluteRect.fLeft, &pAbsoluteRect.fTop, m_pRect.fLeft, m_pRect.fTop, m_pParent); // if transparent, draw only the clipped text if ((GetStyle() & UISTYLE_TRANSPARENT) == 0) { // if shadowed, draw the shadow if (GetStyle() & UISTYLE_SHADOWED) { m_pUISystem->DrawShadow(pAbsoluteRect, UI_DEFAULT_SHADOW_COLOR, UI_DEFAULT_SHADOW_BORDER_SIZE, this); } } // if border is large enough to be visible, draw it if (m_pBorder.fSize > 0.125f) { m_pUISystem->DrawBorder(pAbsoluteRect, m_pBorder); m_pUISystem->AdjustRect(&pAbsoluteRect, pAbsoluteRect, m_pBorder.fSize); } // save the client area without the border, // to draw a greyed quad later, if disabled UIRect pGreyedRect = pAbsoluteRect; if ((GetStyle() & UISTYLE_TRANSPARENT) == 0) { // if we are a textured static, draw the correct texture if (m_pTexture.iTextureID > -1) { m_pUISystem->DrawImage(pAbsoluteRect, m_pTexture, m_cColor); } // if not textured, just draw the back quad else { m_pUISystem->DrawQuad(pAbsoluteRect, m_cColor); } } // draw the model if there is one if (m_pModel) { IRenderer *pRenderer = m_pUISystem->GetIRenderer(); // because we clear the z-buffer here we cannot have more than one // hack was done because z-buffer read for flares was not working with transparent menu pRenderer->ClearDepthBuffer(); pRenderer->SetState(GS_NODEPTHTEST); int iX = (int)(pRenderer->ScaleCoordX(pAbsoluteRect.fLeft) + 0.5f); int iY = (int)(pRenderer->ScaleCoordY(pAbsoluteRect.fTop) + 0.5f); int iW = (int)(pRenderer->ScaleCoordX(pAbsoluteRect.fWidth) + 0.5f); int iH = (int)(pRenderer->ScaleCoordY(pAbsoluteRect.fHeight) + 0.5f); // save old viewport int iViewportX, iViewportY, iViewportW, iViewportH; pRenderer->GetViewport(&iViewportX, &iViewportY, &iViewportW, &iViewportH); // set new viewport pRenderer->SetViewport(iX, iY, iW, iH); // update angle m_fAngle += m_fModelRotationAcc * m_pUISystem->GetISystem()->GetITimer()->GetFrameTime() * m_fModelRotation * 360.0f; // setup the camera CCamera pCamera; pCamera.Init(iW, iH, m_fCameraFov); pCamera.SetPos(Vec3d(0.0f, m_fCameraDistance, 0.0f)); pCamera.SetAngle(Vec3d(0.0f, 0.0f, 0.0f)); pCamera.Update(); pRenderer->SetCamera(pCamera); // set model rendering params SRendParams pRenderParams; pRenderParams.vPos = Vec3d(0.0f, 0.0f, -0.9f); pRenderParams.vAngles = Vec3d(0.0f, 0.0f, m_fAngle); pRenderParams.nDLightMask = 0; pRenderParams.vAmbientColor = Vec3d(0.25f, 0.25f, 0.25f); // setup a dynamic light CDLight pLight; memset(&pLight, 0, sizeof(CDLight)); pLight.m_Color = CFColor(1.0f, 1.0f, 1.0f) * 0.8f; pLight.m_SpecColor = CFColor(0.0f, 0.0f, 0.0f); pLight.m_Flags = DLF_POINT; pLight.m_fRadius = m_fLightDistance * 10.0f; pLight.m_fStartRadius = 0.0f; pLight.m_fEndRadius = m_fLightDistance * 10.0f; pLight.m_fRadius = m_fLightDistance * 10.0f; pLight.m_Origin = Vec3d(10.0f, m_fLightDistance, 0.0f); // enable the light pRenderParams.nDLightMask |= 1 << pLight.m_Id; // pRenderParams.nDLightMaskFull |= 1 << pLight.m_Id; pRenderer->EF_StartEf(); pRenderer->EF_ClearLightsList(); pRenderer->EF_ADDDlight(&pLight); pRenderer->EF_UpdateDLight(&pLight); m_pModel->Update(); m_pModel->Draw(pRenderParams,Vec3(zero)); pRenderer->EF_EndEf3D(SHDF_SORT); // restore old settings pRenderer->SetViewport(iViewportX, iViewportY, iViewportW, iViewportH); } // adjust the rect with the scrollbar sizes if (m_bHorizontalScrollBar) { pAbsoluteRect.fHeight -= m_pUISystem->GetWidgetRect(m_pHScroll).fHeight; } if (m_bVerticalScrollBar) { pAbsoluteRect.fWidth -= m_pUISystem->GetWidgetRect(m_pVScroll).fWidth; } // update the offsets // vertical if (m_bVerticalScrollBar) { if ((m_iVAlignment == UIALIGN_BOTTOM) && (m_pVScroll->GetFlags() & UIFLAG_VISIBLE)) { m_fVerticalOffset = -(pAbsoluteRect.fHeight - m_fTotalHeight) * (1.0f - m_pVScroll->GetValue()); } else if ((m_iVAlignment == UIALIGN_MIDDLE) && (m_pVScroll->GetFlags() & UIFLAG_VISIBLE)) { m_fVerticalOffset = -(pAbsoluteRect.fHeight - m_fTotalHeight) * 0.5f + (m_fTotalHeight - pAbsoluteRect.fHeight) * -m_pVScroll->GetValue(); } else if (m_pVScroll->GetFlags() & UIFLAG_VISIBLE) { m_fVerticalOffset = (m_fTotalHeight - pAbsoluteRect.fHeight) * -m_pVScroll->GetValue(); } else { m_fVerticalOffset = 0.0f; } } else { m_fVerticalOffset = 0.0f; } // horizontal if (m_bHorizontalScrollBar) { if ((m_iHAlignment == UIALIGN_RIGHT) && (m_pHScroll->GetFlags() & UIFLAG_VISIBLE)) { m_fHorizontalOffset = -(pAbsoluteRect.fWidth - m_fTotalWidth) * (1.0f - m_pHScroll->GetValue()); } else if ((m_iHAlignment == UIALIGN_MIDDLE) && (m_pHScroll->GetFlags() & UIFLAG_VISIBLE)) { m_fHorizontalOffset = -(pAbsoluteRect.fWidth - m_fTotalWidth) * 0.5f + (m_fTotalWidth - pAbsoluteRect.fWidth) * -m_pHScroll->GetValue(); } else if (m_pHScroll->GetFlags() & UIFLAG_VISIBLE) { m_fHorizontalOffset = (m_fTotalWidth - pAbsoluteRect.fWidth) * -m_pHScroll->GetValue(); } else { m_fHorizontalOffset = 0.0f; } } else { m_fHorizontalOffset = 0.0f; } // get the font IFFont *pFont = pFont = m_pUISystem->GetIFont(m_pFont); if (!m_vLines.empty()) { IFFont *pFont = m_pUISystem->GetIFont(m_pFont); m_pUISystem->SetScissor(&pAbsoluteRect); if (m_iStyle & UISTYLE_MULTILINE) { UIRect pLineRect(pAbsoluteRect.fLeft + m_fLeftSpacing, 0, pAbsoluteRect.fWidth - m_fLeftSpacing - m_fRightSpacing, 0); // get the correct start switch (m_iVAlignment) { case UIALIGN_BOTTOM: pLineRect.fTop = pAbsoluteRect.fTop + pAbsoluteRect.fHeight - m_fTotalHeight; break; case UIALIGN_TOP: pLineRect.fTop = pAbsoluteRect.fTop; break; case UIALIGN_MIDDLE: pLineRect.fTop = pAbsoluteRect.fTop + (pAbsoluteRect.fHeight - m_fTotalHeight) * 0.5f; break; } m_pUISystem->SetScissor(&pAbsoluteRect); pLineRect.fTop += m_fVerticalOffset; pLineRect.fLeft += m_fHorizontalOffset; for (std::vector::iterator pItor = m_vLines.begin(); pItor != m_vLines.end(); ++pItor) { UIStaticLine &pLine = *pItor; pLineRect.fHeight = m_fLineHeight; // check if the line is below the rect // if so, we stop drawing, because there is no way the following will be visible if (pLineRect.fTop > pAbsoluteRect.fTop + pAbsoluteRect.fHeight) { break; } // check if the line is above the rect else if (pLineRect.fTop + GetLineHeight(&pLine) < pAbsoluteRect.fTop) { pLineRect.fTop += GetLineHeight(&pLine); continue; } if (m_iStyle & UISTYLE_WORDWRAP) { wchar_t *szBaseString = (wchar_t *)pLine.szText.c_str(); wchar_t *szString = szBaseString; wchar_t cSave; int iIndex; for (int i = 0; i < pLine.iWrapCount; i++) { iIndex = pLine.iWrapIndex[i]; cSave = szBaseString[iIndex]; szBaseString[iIndex] = 0; // draw the text m_pUISystem->DrawText(pLineRect, m_iHAlignment, UIALIGN_MIDDLE, pFont, szString); szBaseString[iIndex] = cSave; szString = szBaseString + iIndex; pLineRect.fTop += m_fLineHeight; } m_pUISystem->DrawText(pLineRect, m_iHAlignment, UIALIGN_MIDDLE, pFont, szString); pLineRect.fTop += m_fLineHeight; } else { m_pUISystem->DrawText(pLineRect, m_iHAlignment, UIALIGN_MIDDLE, pFont, pLine.szText.c_str()); pLineRect.fTop += GetLineHeight(&pLine); } } } else { pAbsoluteRect.fLeft += m_fLeftSpacing; pAbsoluteRect.fWidth -= m_fLeftSpacing + m_fRightSpacing; m_pUISystem->DrawText(pAbsoluteRect, m_iHAlignment, m_iVAlignment, pFont, m_vLines[0].szText.c_str()); } } // draw a greyed quad ontop, if disabled if ((m_iFlags & UIFLAG_ENABLED) == 0) { m_pUISystem->ResetDraw(); m_pUISystem->DrawGreyedQuad(pGreyedRect, m_cGreyedColor, m_iGreyedBlend); } m_pUISystem->EndDraw(); // draw the children if (m_pUISystem->ShouldSortByZ()) { SortChildrenByZ(); } DrawChildren(); return 1; } //------------------------------------------------------------------------------------------------- int CUIStatic::SetText(const wstring &szText) { if (m_vLines.empty()) { UIStaticLine pLine; pLine.szText = szText; m_vLines.push_back(pLine); } else { m_vLines[0].szText = szText; } IFFont *pFont = m_pUISystem->GetIFont(m_pFont); GetLineMetrics(&m_vLines[0], pFont); return 1; } //------------------------------------------------------------------------------------------------- int CUIStatic::SetVAlign(int iAlign) { m_iVAlignment = iAlign; return 1; } //------------------------------------------------------------------------------------------------- int CUIStatic::GetVAlign() { return m_iVAlignment; } //------------------------------------------------------------------------------------------------- int CUIStatic::SetHAlign(int iAlign) { m_iHAlignment = iAlign; return 1; } //------------------------------------------------------------------------------------------------- int CUIStatic::GetHAlign() { return m_iHAlignment; } //------------------------------------------------------------------------------------------------- int CUIStatic::LoadModel(const string &szModelName) { if (m_pModel) { ReleaseModel(); } m_pModel = m_pUISystem->GetISystem()->GetIAnimationSystem()->MakeCharacter(szModelName.c_str()); m_szModelName = szModelName; return (m_pModel ? 1 : 0); } //------------------------------------------------------------------------------------------------- int CUIStatic::ReleaseModel() { if (m_pModel) { m_pUISystem->GetISystem()->GetIAnimationSystem()->RemoveCharacter(m_pModel); m_pModel = 0; } m_szModelName.clear(); return 1; } //------------------------------------------------------------------------------------------------- int CUIStatic::StartAnimation(const string &szAnimationName) { if (m_pModel) { // [PETAR] StartAnimation2 is obsolete - old call provided here as reference //if (m_pModel->StartAnimation2(szAnimationName.c_str(), 0.0f, 0.0f, 1, 1, 1)) CryCharAnimationParams ccap; ccap.fBlendInTime = ccap.fBlendOutTime = 0.f; ccap.nLayerID = 1; ccap.nFlags = ccap.FLAGS_SYNCHRONIZE_WITH_LAYER_0; if (m_pModel->StartAnimation(szAnimationName.c_str(),ccap)) { m_pModel->Update(); return 1; } else { m_pModel->ResetAnimations(); return 0; } } return 0; } //------------------------------------------------------------------------------------------------- void CUIStatic::InitializeTemplate(IScriptSystem *pScriptSystem) { _ScriptableEx::InitializeTemplate(pScriptSystem); REGISTER_COMMON_MEMBERS(pScriptSystem, CUIStatic); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, SetText); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, GetText); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, Clear); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, SetLine); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, AddLine); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, GetLine); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, GetLineCount); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, SetVAlign); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, GetVAlign); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, SetHAlign); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, GetHAlign); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, SetTexture); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, GetTexture); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, LoadModel); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, ReleaseModel); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, SetView); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, SetAnimation); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, SetShaderFloat); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, SetShader); REGISTER_SCRIPTOBJECT_MEMBER(pScriptSystem, CUIStatic, SetSecondShader); } //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- int CUIStatic::GetLineMetrics(UIStaticLine *pLine, IFFont *pFont) { // get string metrics vector2f vStringSize = pFont->GetTextSizeW(pLine->szText.c_str()); vStringSize.x /= m_pUISystem->GetIRenderer()->ScaleCoordX(1); vStringSize.y /= m_pUISystem->GetIRenderer()->ScaleCoordY(1); m_fLineHeight = m_fLineSpacing + vStringSize.y; float fAllowedWidth = GetTextRect(1).fWidth - UI_DEFAULT_LINE_WIDTH_ADDITION; float fStringWidth = vStringSize.x; // if the string is short or wordwrap not enabled, don't do anything if ((fStringWidth < fAllowedWidth) || ((m_iStyle & UISTYLE_WORDWRAP) == 0)) { pLine->fWidth = fStringWidth + UI_DEFAULT_LINE_WIDTH_ADDITION; pLine->fHeight = m_fLineHeight; pLine->fWrapWidth = fStringWidth; pLine->iWrapCount = 0; return 1; } // otherwise... // clear the wrap points memset(pLine->iWrapIndex, 0, sizeof(int) * UI_DEFAULT_MAX_WRAP_INDICES); pLine->iWrapCount = 0; pLine->fWrapWidth = 0.0f; // start with one line height pLine->fHeight = m_fLineHeight; int iLastSpace = -1; float fLastSpaceWidth = 0.0f; float fCurrentCharWidth = 0.0f; float fCurrentLineWidth = 0.0f; float fBiggestLineWidth = 0.0f; float fWidthSum = 0.0f; int iCurrentChar = 0; wchar_t *pChar = (wchar_t *)pLine->szText.c_str(); wchar_t szChar[2] = {0, 0}; while(szChar[0] = *pChar++) { // ignore color codes if (szChar[0] == L'$') { if (*pChar) { ++pChar; ++iCurrentChar; if ((*pChar) != L'$') { ++iCurrentChar; continue; } szChar[0] = *pChar; } } // get char width and sum it to the line width fCurrentCharWidth = pFont->GetTextSizeW(szChar).x / m_pUISystem->GetIRenderer()->ScaleCoordX(1);; // keep track of spaces // they are good for spliting the string :D if (szChar[0] == L' ') { iLastSpace = iCurrentChar; fLastSpaceWidth = fCurrentLineWidth + fCurrentCharWidth; } // if line exceed allowed width, split it if ((fCurrentLineWidth + fCurrentCharWidth >= fAllowedWidth) && (*pChar)) { if ((iLastSpace > 0) && ((iCurrentChar - iLastSpace) < UI_DEFAULT_WORDWRAP_TRESHOLD) && (iCurrentChar - iLastSpace > 0)) { pLine->iWrapIndex[pLine->iWrapCount++] = iLastSpace + 1; if (fLastSpaceWidth > fBiggestLineWidth) { fBiggestLineWidth = fLastSpaceWidth; } fCurrentLineWidth = fCurrentLineWidth - fLastSpaceWidth + fCurrentCharWidth; assert(fCurrentLineWidth >= 0); fWidthSum += fCurrentLineWidth; } else { pLine->iWrapIndex[pLine->iWrapCount++] = iCurrentChar; if (fCurrentLineWidth > fBiggestLineWidth) { fBiggestLineWidth = fCurrentLineWidth; } fWidthSum += fCurrentLineWidth; fCurrentLineWidth = fCurrentCharWidth; } pLine->fHeight += m_fLineHeight; // if we don't need any more line breaks, then just stop if (fStringWidth - fWidthSum <= fAllowedWidth) { break; } fLastSpaceWidth = 0; iLastSpace = 0; } else { fCurrentLineWidth += fCurrentCharWidth; } iCurrentChar++; } pLine->fWrapWidth = fBiggestLineWidth; return 1; } //------------------------------------------------------------------------------------------------- int CUIStatic::GetLineListMetrics() { IFFont *pFont = m_pUISystem->GetIFont(m_pFont); m_fLineHeight = m_fLineSpacing + pFont->GetTextSizeW(L"I_").y / m_pUISystem->GetIRenderer()->ScaleCoordY(1);; for (std::vector::iterator pItor = m_vLines.begin(); pItor != m_vLines.end(); ++pItor) { GetLineMetrics(&(*pItor), pFont); } return 1; } //------------------------------------------------------------------------------------------------- float CUIStatic::GetLineWidth(UIStaticLine *pLine) { if (m_iStyle & UISTYLE_WORDWRAP) { return pLine->fWrapWidth; } return pLine->fWidth; } //------------------------------------------------------------------------------------------------- float CUIStatic::GetLineHeight(UIStaticLine *pLine) { if (m_iStyle & UISTYLE_WORDWRAP) { return pLine->fHeight; } return m_fLineHeight; } //------------------------------------------------------------------------------------------------- float CUIStatic::GetTextWidth() { float fTextWidth = 0.0f; if (m_iStyle & UISTYLE_WORDWRAP) { for (std::vector::iterator pItor = m_vLines.begin(); pItor != m_vLines.end(); ++pItor) { if ((*pItor).fWrapWidth > fTextWidth) { fTextWidth = (*pItor).fWrapWidth; } } } else { for (std::vector::iterator pItor = m_vLines.begin(); pItor != m_vLines.end(); ++pItor) { if ((*pItor).fWidth > fTextWidth) { fTextWidth = (*pItor).fWidth; } } } return fTextWidth; } //------------------------------------------------------------------------------------------------- float CUIStatic::GetTextHeight() { float fTextHeight = 0.0f; for (std::vector::iterator pItor = m_vLines.begin(); pItor != m_vLines.end(); ++pItor) { fTextHeight += GetLineHeight(&(*pItor)); } return fTextHeight; } //------------------------------------------------------------------------------------------------- UIRect CUIStatic::GetTextRect(bool bScrollBars) { UIRect pTextRect(m_pRect); // if border is large enough to be visible, remove it from the rect if (m_pBorder.fSize > 0.125f) { m_pUISystem->AdjustRect(&pTextRect, pTextRect, m_pBorder.fSize); } if ((bScrollBars) && (m_iStyle & UISTYLE_MULTILINE)) { // we have the toolbars, remove them from the rect if (m_bHorizontalScrollBar) { pTextRect.fHeight -= m_pUISystem->GetWidgetRect(m_pHScroll).fHeight; } else if (m_bVerticalScrollBar) { pTextRect.fWidth -= m_pUISystem->GetWidgetRect(m_pVScroll).fWidth; } } pTextRect.fLeft += m_fLeftSpacing; pTextRect.fWidth -= m_fRightSpacing + m_fLeftSpacing; return pTextRect; } //------------------------------------------------------------------------------------------------- // Script Functions //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- int CUIStatic::SetFontName(IFunctionHandler *pH) { int iResult = CUIWidget::SetFontName(pH); GetLineListMetrics(); return iResult; } //------------------------------------------------------------------------------------------------- int CUIStatic::SetFontSize(IFunctionHandler *pH) { int iResult = CUIWidget::SetFontSize(pH); GetLineListMetrics(); return iResult; } //------------------------------------------------------------------------------------------------- int CUIStatic::SetText(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), SetText, 1); CHECK_SCRIPT_FUNCTION_PARAMTYPE2(m_pScriptSystem, GetName().c_str(), SetText, 1, svtString, svtNumber); IFFont *pFont = m_pUISystem->GetIFont(m_pFont); if (m_vLines.empty()) { UIStaticLine pLine; m_pUISystem->ConvertToWString(pLine.szText, pH, 1); GetLineMetrics(&pLine, pFont); m_vLines.push_back(pLine); } else { m_vLines[0].szText.clear(); m_pUISystem->ConvertToWString(m_vLines[0].szText, pH, 1); GetLineMetrics(&m_vLines[0], pFont); } return pH->EndFunction(); } //------------------------------------------------------------------------------------------------- int CUIStatic::GetText(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), GetText, 0); if (m_vLines.empty()) { return pH->EndFunctionNull(); } char szString[1024] = {0,0}; int iStringSize = min(m_vLines[0].szText.size(), 1023); wchar_t *pChar = (wchar_t *)m_vLines[0].szText.c_str(); int i = 0; while (*pChar) { szString[i++] = (char)*pChar++; } szString[i] = 0; return pH->EndFunction(szString); } //------------------------------------------------------------------------------------------------- int CUIStatic::Clear(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), Clear, 0); m_vLines.clear(); return pH->EndFunctionNull(); } //------------------------------------------------------------------------------------------------- int CUIStatic::SetLine(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), SetLine, 2); CHECK_SCRIPT_FUNCTION_PARAMTYPE(m_pScriptSystem, GetName().c_str(), SetLine, 1, svtNumber); CHECK_SCRIPT_FUNCTION_PARAMTYPE(m_pScriptSystem, GetName().c_str(), SetLine, 2, svtString); char *szLine; int iLine; pH->GetParam(1, iLine); pH->GetParam(2, szLine); if (iLine < (int)m_vLines.size()) { m_vLines[iLine].szText.clear(); m_pUISystem->ConvertToWString(m_vLines[iLine].szText, szLine); } else if (iLine == (int)m_vLines.size()) { UIStaticLine pLine; m_pUISystem->ConvertToWString(pLine.szText, szLine); m_vLines.push_back(pLine); } IFFont *pFont = m_pUISystem->GetIFont(m_pFont); GetLineMetrics(&m_vLines[iLine], pFont); // don't grow the buffer past our maxlines while ((int)m_vLines.size() >= m_iMaxLines) { m_vLines.erase(m_vLines.begin()); } return pH->EndFunctionNull(); } //------------------------------------------------------------------------------------------------- int CUIStatic::AddLine(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), AddLine, 1); CHECK_SCRIPT_FUNCTION_PARAMTYPE(m_pScriptSystem, GetName().c_str(), AddLine, 1, svtString); char *szLine; wstring szWLine; pH->GetParam(1, szLine); UIStaticLine pLine; m_pUISystem->ConvertToWString(pLine.szText, szLine); m_vLines.push_back(pLine); IFFont *pFont = m_pUISystem->GetIFont(m_pFont); GetLineMetrics(&(*(m_vLines.end()-1)), pFont); // don't grow the buffer past our maxlines while ((int)m_vLines.size() >= m_iMaxLines) { m_vLines.erase(m_vLines.begin()); } return pH->EndFunctionNull(); } //------------------------------------------------------------------------------------------------- int CUIStatic::GetLine(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), GetLine, 1); CHECK_SCRIPT_FUNCTION_PARAMTYPE(m_pScriptSystem, GetName().c_str(), GetLine, 1, svtNumber); int iLine = 0; pH->GetParam(1, iLine); char szString[1024] = {0,0}; if (iLine < (int)m_vLines.size()) { int iStringSize = min(m_vLines[iLine].szText.size(), 1023); wchar_t *pChar = (wchar_t *)m_vLines[iLine].szText.c_str(); int i = 0; while (*pChar) { szString[i++] = (char)*pChar++; } szString[i] = 0; } return pH->EndFunction(szString); } //------------------------------------------------------------------------------------------------- int CUIStatic::GetLineCount(IFunctionHandler *pH) { if (m_iStyle & UISTYLE_MULTILINE) { return pH->EndFunction((int)m_vLines.size()); } else { return pH->EndFunction((int)1); } } //------------------------------------------------------------------------------------------------- int CUIStatic::SetVAlign(IFunctionHandler *pH) { RETURN_INT_FROM_SCRIPT(m_pScriptSystem, GetName().c_str(), SetVAlign, m_iVAlignment); } //------------------------------------------------------------------------------------------------- int CUIStatic::GetVAlign(IFunctionHandler *pH) { RETURN_INT_TO_SCRIPT(m_pScriptSystem, GetName().c_str(), GetVAlign, m_iVAlignment); } //------------------------------------------------------------------------------------------------- int CUIStatic::SetHAlign(IFunctionHandler *pH) { RETURN_INT_FROM_SCRIPT(m_pScriptSystem, GetName().c_str(), SetHAlign, m_iHAlignment); } //------------------------------------------------------------------------------------------------- int CUIStatic::GetHAlign(IFunctionHandler *pH) { RETURN_INT_TO_SCRIPT(m_pScriptSystem, GetName().c_str(), GetHAlign, m_iHAlignment); } //------------------------------------------------------------------------------------------------- int CUIStatic::SetTexture(IFunctionHandler *pH) { RETURN_TEXTURE_FROM_SCRIPT(m_pScriptSystem, GetName().c_str(), SetTexture, m_pTexture.iTextureID); } //------------------------------------------------------------------------------------------------- int CUIStatic::GetTexture(IFunctionHandler *pH) { RETURN_TEXTURE_TO_SCRIPT(m_pScriptSystem, GetName().c_str(), GetTexture, m_pTexture.iTextureID); } //------------------------------------------------------------------------------------------------- int CUIStatic::GetHScrollBar(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), GetHScrollBar, 0); if (m_pHScroll) { return pH->EndFunction(m_pHScroll->GetScriptObject()); } return pH->EndFunctionNull(); } //------------------------------------------------------------------------------------------------- int CUIStatic::GetVScrollBar(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), GetVScrollBar, 0); if (m_pVScroll) { return pH->EndFunction(m_pVScroll->GetScriptObject()); } return pH->EndFunctionNull(); } //------------------------------------------------------------------------------------------------- int CUIStatic::LoadModel(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), LoadModel, 1); CHECK_SCRIPT_FUNCTION_PARAMTYPE(m_pScriptSystem, GetName().c_str(), LoadModel, 1, svtString); char *szModelName; pH->GetParam(1, szModelName); if (m_pModel) { m_pModel = 0; } if (LoadModel(szModelName)) { return pH->EndFunction(true); } else { return pH->EndFunction(false); } } //------------------------------------------------------------------------------------------------- int CUIStatic::ReleaseModel(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), ReleaseModel, 0); ReleaseModel(); return pH->EndFunction(); } //------------------------------------------------------------------------------------------------- int CUIStatic::SetView(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), SetView, 1); CHECK_SCRIPT_FUNCTION_PARAMTYPE(m_pScriptSystem, GetName().c_str(), SetView, 1, svtNumber); if (pH->GetParamCount() > 3) { pH->GetParam(4, m_fModelRotation); } if (pH->GetParamCount() > 2) { pH->GetParam(3, m_fLightDistance); } if (pH->GetParamCount() > 1) { pH->GetParam(2, m_fCameraFov); m_fCameraFov = m_fCameraFov * gf_PI / 180.0f; } if (pH->GetParamCount() > 0) { pH->GetParam(1, m_fCameraDistance); } return pH->EndFunction(); } //------------------------------------------------------------------------------------------------- int CUIStatic::SetAnimation(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), SetAnimation, 1); CHECK_SCRIPT_FUNCTION_PARAMTYPE(m_pScriptSystem, GetName().c_str(), SetAnimation, 1, svtString); if (m_pModel) { char *szAnimName; if (pH->GetParam(1, szAnimName)) { StartAnimation(szAnimName); } } return pH->EndFunction(); } //------------------------------------------------------------------------------------------------- int CUIStatic::SetShaderFloat(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), SetShaderFloat, 2); CHECK_SCRIPT_FUNCTION_PARAMTYPE(m_pScriptSystem, GetName().c_str(), SetShaderFloat, 1, svtString); CHECK_SCRIPT_FUNCTION_PARAMTYPE(m_pScriptSystem, GetName().c_str(), SetShaderFloat, 2, svtNumber); char *szShaderName = 0; float fValue = 0.0f; pH->GetParam(1, szShaderName); pH->GetParam(2, fValue); if (m_pModel) { m_pModel->SetShaderFloat(szShaderName, fValue); } return pH->EndFunction(); } //------------------------------------------------------------------------------------------------- int CUIStatic::SetShader(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), SetShader, 1); CHECK_SCRIPT_FUNCTION_PARAMTYPE(m_pScriptSystem, GetName().c_str(), SetShader, 1, svtString); char *szShaderName = 0; pH->GetParam(1, szShaderName); if (m_pModel) { m_pModel->SetShaderTemplateName(szShaderName, 0, 0, 0); } return pH->EndFunction(); } //------------------------------------------------------------------------------------------------- int CUIStatic::SetSecondShader(IFunctionHandler *pH) { CHECK_SCRIPT_FUNCTION_PARAMCOUNT(m_pScriptSystem, GetName().c_str(), SetSecondShader, 1); CHECK_SCRIPT_FUNCTION_PARAMTYPE(m_pScriptSystem, GetName().c_str(), SetSecondShader, 1, svtString); char *szShaderName = 0; pH->GetParam(1, szShaderName); if (m_pModel) { m_pModel->SetShaderTemplateName(szShaderName, 1, 0, 0); } return pH->EndFunction(); }