void VVirtualThumbStick::Reset() { m_fXValue = 0.0f; m_fYValue = 0.0f; m_iLastTouchPointIndex = -1; // (Re)position thumb stick const VRectanglef finalValidArea = m_spTouchArea->GetArea(); // Outer ring mask const float fInitialX = finalValidArea.m_vMin.x + finalValidArea.GetSizeX() * m_fRelativeInitialX; const float fInitialY = finalValidArea.m_vMin.y + finalValidArea.GetSizeY() * m_fRelativeInitialY; m_spRingMask->GetTextureSize(m_iRingWidth, m_iRingHeight); m_spRingMask->SetPos( fInitialX - static_cast<float>(m_iRingWidth / 2), fInitialY - static_cast<float>(m_iRingHeight / 2)); // Inner circle mask m_iCircleCenterX = static_cast<int>(fInitialX); m_iCircleCenterY = static_cast<int>(fInitialY); m_spCircleMask->GetTextureSize(m_iCircleWidth, m_iCircleHeight); m_spCircleMask->SetPos( fInitialX - static_cast<float>(m_iCircleWidth / 2), fInitialY - static_cast<float>(m_iCircleHeight / 2)); }
void VTextState::Paint(VGraphicsInfo *pGraphics, VWindowBase *pParentWnd, VColorRef iColor) { const char *szText = GetText(); if (!m_spFont || !szText || !szText[0]) return; VRectanglef vParentRect = pParentWnd->GetClientRect(); // clipping box of parent control if(!m_bCachedLinesValid) { m_lines.Reset(); m_lineOffsets.Reset(); float fLineHeight = m_spFont->GetFontHeight() * m_fRelativeFontHeight * m_fFontScaling; if(!m_bTextWrap) { const char* szCurrentLine = szText; for (const char* szPtr = szCurrentLine; *szPtr != '\0'; ++szPtr) { if (*szPtr == '\n') { VStaticString<512> line; line.Set(szCurrentLine, static_cast<int>(szPtr - szCurrentLine)); m_lines.Add(line.AsChar()); szCurrentLine = szPtr + 1; } } // Add the last line if(*szCurrentLine) { m_lines.Add(szCurrentLine); } } else { float fMaxLineWidth = vParentRect.GetSizeX() / m_fFontScaling; // Wrap text into individual lines { const char *szCurrentLine = szText; while (*szCurrentLine) { // byte offsets int iByteOffsetAtWrapPosition; int iByteOffsetAfterWrapPosition; // search for next newline const char *pNextNewLine = strchr(szCurrentLine, '\n'); // compute automatic wrap character index int iCharCount = m_spFont->GetCharacterIndexAtPos(szCurrentLine, fMaxLineWidth, -1, false); int iWrapOffset = VString::GetUTF8CharacterOffset(szCurrentLine, iCharCount); if (pNextNewLine != NULL && (pNextNewLine - szCurrentLine) <= iWrapOffset) { // newline occurs before automatic text wrap iByteOffsetAtWrapPosition = static_cast<int>(pNextNewLine - szCurrentLine); iByteOffsetAfterWrapPosition = iByteOffsetAtWrapPosition + 1; } else if(strlen(szCurrentLine) <= iWrapOffset) { // End of text occurs before automatic text wrap iByteOffsetAtWrapPosition = static_cast<int>(strlen(szCurrentLine)); iByteOffsetAfterWrapPosition = iByteOffsetAtWrapPosition; } else { // automatic text wrap iByteOffsetAtWrapPosition = iWrapOffset; if (iByteOffsetAtWrapPosition > 0) { // Go backwards and try to find white space while (iByteOffsetAtWrapPosition > 0 && !IsWhiteSpace(szCurrentLine[iByteOffsetAtWrapPosition])) { iByteOffsetAtWrapPosition--; } // no whitespace found? then wrap inside word if (iByteOffsetAtWrapPosition == 0) { iByteOffsetAtWrapPosition = iWrapOffset; } else { // Find end of next word int iEndOfWord = iByteOffsetAtWrapPosition + 1; while(szCurrentLine[iEndOfWord] && !IsWhiteSpace(szCurrentLine[iEndOfWord])) { iEndOfWord++; } // If the word does not fit into a line by itself, it will be wrapped anyway, so wrap it early to avoid ragged looking line endings VRectanglef nextWordSize; m_spFont->GetTextDimension(szCurrentLine + iByteOffsetAtWrapPosition, nextWordSize, iEndOfWord - iByteOffsetAtWrapPosition); if(nextWordSize.GetSizeX() > fMaxLineWidth) { iByteOffsetAtWrapPosition = iWrapOffset; } } } else { // First character is already wider than the line iByteOffsetAtWrapPosition = VString::GetUTF8CharacterOffset(szCurrentLine, 1); } iByteOffsetAfterWrapPosition = iByteOffsetAtWrapPosition; } // put together line VStaticString<512> line; line.Set(szCurrentLine, iByteOffsetAtWrapPosition); m_lines.Add(line.AsChar()); szCurrentLine = &szCurrentLine[iByteOffsetAfterWrapPosition]; while(*szCurrentLine == ' ') szCurrentLine++; } } } // Compute offset for each line for(int iLineIdx = 0; iLineIdx < m_lines.GetLength(); iLineIdx++) { hkvVec2 offset = m_vOffset; offset.x += m_spFont->GetTextPositionOfs(m_lines[iLineIdx], vParentRect.GetSize(), m_hAlign, m_vAlign, m_fFontScaling).x; offset.y += iLineIdx * fLineHeight; if (m_vAlign == VisFont_cl::ALIGN_CENTER) { offset.y += (vParentRect.GetSizeY() - fLineHeight * m_lines.GetSize()) * 0.5f; } else if (m_vAlign == VisFont_cl::ALIGN_BOTTOM) { offset.y += (vParentRect.GetSizeY() - fLineHeight * m_lines.GetSize()); } m_lineOffsets.Add(offset); } m_bCachedLinesValid = true; } // Render lines if (pGraphics) { VSimpleRenderState_t state = VGUIManager::DefaultGUIRenderState(); if (m_fFontScaling!=1.0f) state.SetFlag(RENDERSTATEFLAG_FILTERING); for(int iLineIdx = 0; iLineIdx < m_lines.GetLength(); iLineIdx++) { m_spFont->PrintText(&pGraphics->Renderer, vParentRect.m_vMin + m_lineOffsets[iLineIdx], m_lines[iLineIdx], iColor, state, m_fFontScaling, m_pCustomBBox ? m_pCustomBBox : &vParentRect); } } }