int GUISliderValue::measureText(const std::string& str) { void* fontResource = NULL; if (mFont) fontResource = mFont->GetResource(); return gr_measureEx(str.c_str(), fontResource); }
int GUIText::GetCurrentBounds(int& w, int& h) { void* fontResource = NULL; if (mFont) fontResource = mFont->GetResource(); h = mFontHeight; w = gr_measureEx(mLastValue.c_str(), fontResource); return 0; }
int GUIText::Render(void) { if (!isConditionTrue()) return 0; void* fontResource = NULL; string displayValue; if (mFont) fontResource = mFont->GetResource(); mLastValue = parseText(); displayValue = mLastValue; if (charSkip) displayValue.erase(0, charSkip); mVarChanged = 0; int x = mRenderX, y = mRenderY; int width = gr_measureEx(displayValue.c_str(), fontResource); if (mPlacement != TOP_LEFT && mPlacement != BOTTOM_LEFT) { if (mPlacement == CENTER || mPlacement == CENTER_X_ONLY) x -= (width / 2); else x -= width; } if (mPlacement != TOP_LEFT && mPlacement != TOP_RIGHT) { if (mPlacement == CENTER) y -= (mFontHeight / 2); else if (mPlacement == BOTTOM_LEFT || mPlacement == BOTTOM_RIGHT) y -= mFontHeight; } if (hasHighlightColor && isHighlighted) gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha); else gr_color(mColor.red, mColor.green, mColor.blue, mColor.alpha); if (maxWidth) gr_textExW(x, y, displayValue.c_str(), fontResource, maxWidth + x); else gr_textEx(x, y, displayValue.c_str(), fontResource); return 0; }
int GUIInput::NotifyTouch(TOUCH_STATE state, int x, int y) { static int startSelection = -1; int textWidth; string displayValue, originalValue; void* fontResource = NULL; if (mFont) fontResource = mFont->GetResource(); if (!isConditionTrue()) return -1; if (!HasInputFocus) { if (state != TOUCH_RELEASE) return 0; // Only change focus if touch releases within the input box if (GetSelection(x, y) >= 0) { // When changing focus, we don't scroll or change the cursor location PageManager::SetKeyBoardFocus(0); PageManager::NotifyKeyboard(0); SetInputFocus(1); DrawCursor = true; mRendered = false; } } else { switch (state) { case TOUCH_HOLD: case TOUCH_REPEAT: break; case TOUCH_START: startSelection = GetSelection(x,y); lastX = x; DrawCursor = false; mRendered = false; break; case TOUCH_DRAG: // Check if we dragged out of the selection window if (GetSelection(x, y) == -1) { lastX = 0; break; } DrawCursor = false; // Provide some debounce on initial touches if (startSelection != -1 && abs(x - lastX) < 6) { break; } startSelection = -1; if (lastX != x) HandleTextLocation(x); break; case TOUCH_RELEASE: // We've moved the cursor location int relativeX = x - mRenderX; mRendered = false; DrawCursor = true; DataManager::GetValue(mVariable, displayValue); if (HasMask) { int index, string_size = displayValue.size(); string maskedValue; for (index=0; index<string_size; index++) maskedValue += mMask; displayValue = maskedValue; } if (displayValue.size() == 0) { skipChars = 0; mCursorLocation = -1; return 0; } else if (skipChars && skipChars < displayValue.size()) { displayValue.erase(0, skipChars); } string cursorString; int cursorX = 0; unsigned index = 0; for(index=0; index<displayValue.size(); index++) { cursorString = displayValue.substr(0, index); cursorX = gr_measureEx(cursorString.c_str(), fontResource) + mRenderX; if (cursorX > x) { if (index > 0) mCursorLocation = index - 1; else mCursorLocation = index; return 0; } } mCursorLocation = -1; break; } } return 0; }
int GUIInput::Render(void) { if (!isConditionTrue()) { mRendered = false; return 0; } void* fontResource = NULL; if (mFont) fontResource = mFont->GetResource(); // First step, fill background gr_color(mBackgroundColor.red, mBackgroundColor.green, mBackgroundColor.blue, 255); gr_fill(mRenderX, mRenderY, mRenderW, mRenderH); // Next, render the background resource (if it exists) if (mBackground && mBackground->GetResource()) { mBackgroundX = mRenderX + ((mRenderW - mBackgroundW) / 2); mBackgroundY = mRenderY + ((mRenderH - mBackgroundH) / 2); gr_blit(mBackground->GetResource(), 0, 0, mBackgroundW, mBackgroundH, mBackgroundX, mBackgroundY); } int ret = 0; // Render the text mInputText->SetRenderPos(mRenderX + scrollingX, mFontY); mInputText->SetMaxWidth(mRenderW - scrollingX); if (mInputText) ret = mInputText->Render(); if (ret < 0) return ret; if (HasInputFocus && DrawCursor) { // Render the cursor string displayValue; int cursorX; DataManager::GetValue(mVariable, displayValue); if (HasMask) { int index, string_size = displayValue.size(); string maskedValue; for (index=0; index<string_size; index++) maskedValue += mMask; displayValue = maskedValue; } if (displayValue.size() == 0) { skipChars = 0; mCursorLocation = -1; cursorX = mRenderX; } else { if (skipChars && skipChars < displayValue.size()) { displayValue.erase(0, skipChars); } if (mCursorLocation == 0) { // Cursor is at the beginning cursorX = mRenderX; } else if (mCursorLocation > 0) { // Cursor is in the middle if (displayValue.size() > (unsigned)mCursorLocation) { string cursorDisplay; cursorDisplay = displayValue; cursorDisplay.resize(mCursorLocation); cursorX = gr_measureEx(cursorDisplay.c_str(), fontResource) + mRenderX; } else { // Cursor location is after the end of the text - reset to -1 mCursorLocation = -1; cursorX = gr_measureEx(displayValue.c_str(), fontResource) + mRenderX; } } else { // Cursor is at the end (-1) cursorX = gr_measureEx(displayValue.c_str(), fontResource) + mRenderX; } } cursorX += scrollingX; // Make sure that the cursor doesn't go past the boundaries of the box if (cursorX + (int)CursorWidth > mRenderX + mRenderW) cursorX = mRenderX + mRenderW - CursorWidth; // Set the color for the cursor gr_color(mCursorColor.red, mCursorColor.green, mCursorColor.blue, 255); gr_fill(cursorX, mFontY, CursorWidth, mFontHeight); } mRendered = true; return ret; }
int GUIInput::HandleTextLocation(int x) { int textWidth; string displayValue, originalValue, insertChar; void* fontResource = NULL; if (mFont) fontResource = mFont->GetResource(); DataManager::GetValue(mVariable, originalValue); displayValue = originalValue; if (HasMask) { int index, string_size = displayValue.size(); string maskedValue; for (index=0; index<string_size; index++) maskedValue += mMask; displayValue = maskedValue; } textWidth = gr_measureEx(displayValue.c_str(), fontResource); if (textWidth <= mRenderW) { lastX = x; scrollingX = 0; skipChars = 0; mInputText->SkipCharCount(skipChars); mRendered = false; return 0; } if (skipChars && skipChars < displayValue.size()) displayValue.erase(0, skipChars); textWidth = gr_measureEx(displayValue.c_str(), fontResource); mRendered = false; int deltaX, deltaText, newWidth; if (x < -1000) { // No change in scrolling if (x == -1003) mCursorLocation = -1; if (mCursorLocation == -1) { displayValue = originalValue; skipChars = 0; textWidth = gr_measureEx(displayValue.c_str(), fontResource); while (textWidth > mRenderW) { displayValue.erase(0, 1); skipChars++; textWidth = gr_measureEx(displayValue.c_str(), fontResource); } scrollingX = mRenderW - textWidth; mInputText->SkipCharCount(skipChars); } else if (x == -1001) { // Added a new character int adjust_scrollingX = 0; string cursorLocate; cursorLocate = displayValue; cursorLocate.resize(mCursorLocation); textWidth = gr_measureEx(cursorLocate.c_str(), fontResource); while (textWidth > mRenderW) { skipChars++; mCursorLocation--; cursorLocate.erase(0, 1); textWidth = gr_measureEx(cursorLocate.c_str(), fontResource); adjust_scrollingX = -1; } if (adjust_scrollingX) { scrollingX = mRenderW - textWidth; if (scrollingX < 0) scrollingX = 0; } mInputText->SkipCharCount(skipChars); } else if (x == -1002) { // Deleted a character while (-1) { if (skipChars == 0) { scrollingX = 0; mInputText->SkipCharCount(skipChars); return 0; } insertChar = originalValue.substr(skipChars - 1, 1); displayValue.insert(0, insertChar); newWidth = gr_measureEx(displayValue.c_str(), fontResource); deltaText = newWidth - textWidth; if (newWidth > mRenderW) { scrollingX = mRenderW - textWidth; if (scrollingX < 0) scrollingX = 0; mInputText->SkipCharCount(skipChars); return 0; } else { textWidth = newWidth; skipChars--; mCursorLocation++; } } } else LOGINFO("GUIInput::HandleTextLocation -> We really shouldn't ever get here...\n"); } else if (x > lastX) { // Dragging to right, scrolling left while (-1) { deltaX = x - lastX + scrollingX; if (skipChars == 0 || deltaX == 0) { scrollingX = 0; lastX = x; mInputText->SkipCharCount(skipChars); return 0; } insertChar = originalValue.substr(skipChars - 1, 1); displayValue.insert(0, insertChar); newWidth = gr_measureEx(displayValue.c_str(), fontResource); deltaText = newWidth - textWidth; if (deltaText < deltaX) { lastX += deltaText; textWidth = newWidth; skipChars--; } else { scrollingX = deltaX; lastX = x; mInputText->SkipCharCount(skipChars); return 0; } } } else if (x < lastX) { // Dragging to left, scrolling right if (textWidth <= mRenderW) { lastX = x; scrollingX = mRenderW - textWidth; return 0; } if (scrollingX) { deltaX = lastX - x; if (scrollingX > deltaX) { scrollingX -= deltaX; lastX = x; return 0; } else { lastX -= deltaX; scrollingX = 0; } } while (-1) { deltaX = lastX - x; displayValue.erase(0, 1); skipChars++; newWidth = gr_measureEx(displayValue.c_str(), fontResource); deltaText = textWidth - newWidth; if (newWidth <= mRenderW) { scrollingX = mRenderW - newWidth; lastX = x; mInputText->SkipCharCount(skipChars); return 0; } if (deltaText < deltaX) { lastX -= deltaText; textWidth = newWidth; } else { scrollingX = deltaText - deltaX; lastX = x; mInputText->SkipCharCount(skipChars); return 0; } } } return 0; }
void GUIKeyboard::DrawKey(Key& key, int keyX, int keyY, int keyW, int keyH) { unsigned char keychar = key.key; if (!keychar) return; // key background COLOR& c = (keychar >= 32 && keychar < 127) ? mKeyColorAlphanumeric : mKeyColorOther; gr_color(c.red, c.green, c.blue, c.alpha); keyX += mKeyMarginX; keyY += mKeyMarginY; keyW -= mKeyMarginX * 2; keyH -= mKeyMarginY * 2; gr_fill(keyX, keyY, keyW, keyH); // key label FontResource* labelFont = mFont; string labelText; ImageResource* labelImage = NULL; if (keychar > 32 && keychar < 127) { labelText = (char) keychar; gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, mFontColor.alpha); } else { // search for a special key label for (std::vector<KeyLabel>::iterator it = mKeyLabels.begin(); it != mKeyLabels.end(); ++it) { if (it->layout_from > 0 && it->layout_from != currentLayout) continue; // this label is for another layout if (it->key == key.key && it->layout_to == key.layout) { // found a label labelText = it->text; labelImage = it->image; break; } } labelFont = mSmallFont; gr_color(mFontColorSmall.red, mFontColorSmall.green, mFontColorSmall.blue, mFontColorSmall.alpha); } if (labelImage) { int w = labelImage->GetWidth(); int h = labelImage->GetHeight(); int x = keyX + (keyW - w) / 2; int y = keyY + (keyH - h) / 2; gr_blit(labelImage->GetResource(), 0, 0, w, h, x, y); } else if (!labelText.empty()) { void* fontResource = labelFont->GetResource(); int textW = gr_measureEx(labelText.c_str(), fontResource); int textH = labelFont->GetHeight(); int textX = keyX + (keyW - textW) / 2; int textY = keyY + (keyH - textH) / 2; gr_textEx(textX, textY, labelText.c_str(), fontResource); } // longpress key label (only if font is defined) keychar = key.longpresskey; if (keychar > 32 && keychar < 127 && mLongpressFont->GetResource()) { void* fontResource = mLongpressFont->GetResource(); gr_color(mLongpressFontColor.red, mLongpressFontColor.green, mLongpressFontColor.blue, mLongpressFontColor.alpha); string text(1, keychar); int textH = mLongpressFont->GetHeight(); int textW = gr_measureEx(text.c_str(), fontResource); int textX = keyX + keyW - longpressOffsetX - textW; int textY = keyY + longpressOffsetY; gr_textEx(textX, textY, text.c_str(), fontResource); } }