GUI: RTL: Improve right align text drawing
- Fix last chars being eaten - Add support for input in right-align mode editables - Fix issue with dirtyness of editables after clicking - Improve spacing for lists and popup - Make numbers reversed in lists
This commit is contained in:
parent
9cd2ef1271
commit
5a093e4e95
7 changed files with 66 additions and 43 deletions
|
@ -1061,8 +1061,17 @@ drawString(const Graphics::Font *font, const Common::String &text, const Common:
|
|||
drawArea = drawArea.findIntersectingRect(Common::Rect(0, 0, _activeSurface->w, _activeSurface->h));
|
||||
|
||||
if (!drawArea.isEmpty()) {
|
||||
Common::Rect textArea(area);
|
||||
textArea.right -= deltax;
|
||||
|
||||
Surface textAreaSurface = _activeSurface->getSubArea(drawArea);
|
||||
font->drawString(&textAreaSurface, text, area.left - drawArea.left, offset - drawArea.top, area.width() - deltax, _fgColor, alignH, deltax, ellipsis);
|
||||
|
||||
if (deltax >= 0) {
|
||||
textArea.left += deltax;
|
||||
deltax = 0;
|
||||
}
|
||||
|
||||
font->drawString(&textAreaSurface, text, textArea.left - drawArea.left, offset - drawArea.top, textArea.width(), _fgColor, alignH, deltax, ellipsis);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ Common::Rect getBoundingBoxImpl(const Font &font, const StringType &str, int x,
|
|||
// We follow the logic of drawStringImpl here. The only exception is
|
||||
// that we do allow an empty width to be specified here. This allows us
|
||||
// to obtain the complete bounding box of a string.
|
||||
const int leftX = x, rightX = w ? (x + w) : 0x7FFFFFFF;
|
||||
const int leftX = x, rightX = w ? (x + w + 1) : 0x7FFFFFFF;
|
||||
int width = font.getStringWidth(str);
|
||||
|
||||
if (align == kTextAlignCenter)
|
||||
|
@ -100,7 +100,7 @@ void drawStringImpl(const Font &font, Surface *dst, const StringType &str, int x
|
|||
// ever change something here we will need to change it there too.
|
||||
assert(dst != 0);
|
||||
|
||||
const int leftX = x, rightX = x + w;
|
||||
const int leftX = x, rightX = x + w + 1;
|
||||
int width = font.getStringWidth(str);
|
||||
|
||||
if (align == kTextAlignCenter)
|
||||
|
|
|
@ -47,6 +47,9 @@ void EditableWidget::init() {
|
|||
|
||||
_editScrollOffset = 0;
|
||||
|
||||
_align = g_gui.useRTL() ? Graphics::kTextAlignRight : Graphics::kTextAlignLeft;
|
||||
_drawAlign = _align;
|
||||
|
||||
_font = ThemeEngine::kFontStyleBold;
|
||||
_inversion = ThemeEngine::kTextInversionNone;
|
||||
}
|
||||
|
@ -58,8 +61,12 @@ void EditableWidget::reflowLayout() {
|
|||
Widget::reflowLayout();
|
||||
|
||||
_editScrollOffset = g_gui.getStringWidth(_editString, _font) - getEditRect().width();
|
||||
if (_editScrollOffset < 0)
|
||||
if (_editScrollOffset < 0) {
|
||||
_editScrollOffset = 0;
|
||||
_drawAlign = _align;
|
||||
} else {
|
||||
_drawAlign = Graphics::kTextAlignLeft;
|
||||
}
|
||||
}
|
||||
|
||||
void EditableWidget::setEditString(const String &str) {
|
||||
|
@ -265,18 +272,8 @@ void EditableWidget::defaultKeyDownHandler(Common::KeyState &state, bool &dirty,
|
|||
}
|
||||
|
||||
int EditableWidget::getCaretOffset() const {
|
||||
int caretpos = 0;
|
||||
|
||||
uint last = 0;
|
||||
for (int i = 0; i < _caretPos; ++i) {
|
||||
const uint cur = _editString[i];
|
||||
caretpos += g_gui.getCharWidth(cur, _font) + g_gui.getKerningOffset(last, cur, _font);
|
||||
last = cur;
|
||||
}
|
||||
|
||||
caretpos -= _editScrollOffset;
|
||||
|
||||
return caretpos;
|
||||
Common::String substr(_editString.c_str(), _caretPos);
|
||||
return g_gui.getStringWidth(substr, _font) - _editScrollOffset;
|
||||
}
|
||||
|
||||
void EditableWidget::drawCaret(bool erase) {
|
||||
|
@ -289,7 +286,16 @@ void EditableWidget::drawCaret(bool erase) {
|
|||
int x = editRect.left;
|
||||
int y = editRect.top;
|
||||
|
||||
Graphics::TextAlign alignment = Graphics::kTextAlignLeft;
|
||||
if (_align == Graphics::kTextAlignRight) {
|
||||
int strVisibleWidth = g_gui.getStringWidth(_editString, _font) - _editScrollOffset;
|
||||
if (strVisibleWidth > editRect.width()) {
|
||||
_drawAlign = Graphics::kTextAlignLeft;
|
||||
strVisibleWidth = editRect.width();
|
||||
} else {
|
||||
_drawAlign = _align;
|
||||
}
|
||||
x = editRect.right - strVisibleWidth;
|
||||
}
|
||||
|
||||
const int caretOffset = getCaretOffset();
|
||||
x += caretOffset;
|
||||
|
@ -297,14 +303,12 @@ void EditableWidget::drawCaret(bool erase) {
|
|||
if (y < 0 || y + editRect.height() > _h)
|
||||
return;
|
||||
|
||||
x += getAbsX();
|
||||
if (g_gui.useRTL())
|
||||
x += g_system->getOverlayWidth() - _w - getAbsX() + g_gui.getOverlayOffset();
|
||||
else
|
||||
x += getAbsX();
|
||||
y += getAbsY();
|
||||
|
||||
if (g_gui.useRTL()) {
|
||||
x += (g_system->getOverlayWidth() - _x - _x - _w);
|
||||
alignment = Graphics::kTextAlignRight;
|
||||
}
|
||||
|
||||
g_gui.theme()->drawCaret(Common::Rect(x, y, x + 1, y + editRect.height()), erase);
|
||||
|
||||
if (erase) {
|
||||
|
@ -335,7 +339,7 @@ void EditableWidget::drawCaret(bool erase) {
|
|||
width = MIN(editRect.width() - caretOffset, width);
|
||||
if (width > 0) {
|
||||
g_gui.theme()->drawText(Common::Rect(x, y, x + width, y + editRect.height()), character,
|
||||
_state, alignment, _inversion, 0, false, _font,
|
||||
_state, _drawAlign, _inversion, 0, false, _font,
|
||||
ThemeEngine::kFontColorNormal, true, _textDrawableArea);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,9 @@ protected:
|
|||
|
||||
int _editScrollOffset;
|
||||
|
||||
Graphics::TextAlign _align;
|
||||
Graphics::TextAlign _drawAlign;
|
||||
|
||||
ThemeEngine::FontStyle _font;
|
||||
|
||||
ThemeEngine::TextInversionState _inversion;
|
||||
|
|
|
@ -72,21 +72,28 @@ void EditTextWidget::handleMouseDown(int x, int y, int button, int clickCount) {
|
|||
if (_caretVisible)
|
||||
drawCaret(true);
|
||||
|
||||
x += _editScrollOffset;
|
||||
if (g_gui.useRTL()) {
|
||||
x = _w - x;
|
||||
}
|
||||
|
||||
x += _editScrollOffset;
|
||||
int width = 0;
|
||||
if (_drawAlign == Graphics::kTextAlignRight)
|
||||
width = _editScrollOffset + getEditRect().width() - g_gui.getStringWidth(_editString, _font);
|
||||
|
||||
uint i;
|
||||
|
||||
uint last = 0;
|
||||
for (i = 0; i < _editString.size(); ++i) {
|
||||
const uint cur = _editString[i];
|
||||
width += g_gui.getCharWidth(cur, _font) + g_gui.getKerningOffset(last, cur, _font);
|
||||
if (width >= x)
|
||||
if (width >= x && width > _editScrollOffset + _leftPadding)
|
||||
break;
|
||||
last = cur;
|
||||
}
|
||||
if (setCaretPos(i))
|
||||
markAsDirty();
|
||||
|
||||
setCaretPos(i);
|
||||
markAsDirty();
|
||||
}
|
||||
|
||||
void EditTextWidget::drawWidget() {
|
||||
|
@ -99,11 +106,9 @@ void EditTextWidget::drawWidget() {
|
|||
const Common::Rect &r = Common::Rect(_x + 2 + _leftPadding, _y + 2, _x + _leftPadding + getEditRect().width() + 8, _y + _h);
|
||||
setTextDrawableArea(r);
|
||||
|
||||
Graphics::TextAlign alignment = g_gui.useRTL() ? Graphics::kTextAlignRight : Graphics::kTextAlignLeft;
|
||||
|
||||
g_gui.theme()->drawText(
|
||||
Common::Rect(_x + 2 + _leftPadding, _y + 1, _x + _leftPadding + getEditRect().width() + 2, _y + _h),
|
||||
_editString, _state, alignment, ThemeEngine::kTextInversionNone,
|
||||
_editString, _state, _drawAlign, ThemeEngine::kTextInversionNone,
|
||||
-_editScrollOffset, false, _font, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
|
||||
}
|
||||
|
||||
|
|
|
@ -536,7 +536,6 @@ void ListWidget::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
|
|||
void ListWidget::drawWidget() {
|
||||
int i, pos, len = _list.size();
|
||||
Common::String buffer;
|
||||
Graphics::TextAlign alignment = g_gui.useRTL() ? Graphics::kTextAlignRight : Graphics::kTextAlignLeft;
|
||||
|
||||
// Draw a thin frame around the list.
|
||||
g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x + _w, _y + _h),
|
||||
|
@ -553,14 +552,14 @@ void ListWidget::drawWidget() {
|
|||
inverted = _inversion;
|
||||
|
||||
Common::Rect r(getEditRect());
|
||||
int pad = g_gui.useRTL() ? _rightPadding : _leftPadding;
|
||||
int pad = _leftPadding;
|
||||
int rtlPad = (_x + r.left + _leftPadding) - (_x + _hlLeftPadding);
|
||||
|
||||
// If in numbering mode & not in RTL based GUI, we first print a number prefix
|
||||
if (_numberingMode != kListNumberingOff && g_gui.useRTL() == false) {
|
||||
buffer = Common::String::format("%2d. ", (pos + _numberingMode));
|
||||
g_gui.theme()->drawText(Common::Rect(_x + _hlLeftPadding, y, _x + r.left + _leftPadding, y + fontHeight - 2),
|
||||
buffer, _state, alignment, inverted, _leftPadding, true);
|
||||
buffer, _state, _drawAlign, inverted, _leftPadding, true);
|
||||
pad = 0;
|
||||
}
|
||||
|
||||
|
@ -593,18 +592,18 @@ void ListWidget::drawWidget() {
|
|||
buffer = _list[pos];
|
||||
}
|
||||
g_gui.theme()->drawText(r1, buffer, _state,
|
||||
alignment, inverted, pad, true, ThemeEngine::kFontStyleBold, color);
|
||||
_drawAlign, inverted, pad, true, ThemeEngine::kFontStyleBold, color);
|
||||
|
||||
// If in numbering mode & using RTL layout in GUI, we print a number suffix after drawing the text
|
||||
if (_numberingMode != kListNumberingOff && g_gui.useRTL()) {
|
||||
buffer = Common::String::format("%2d. ", (pos + _numberingMode));
|
||||
buffer = Common::String::format(" .%2d", (pos + _numberingMode));
|
||||
|
||||
Common::Rect r2 = r1;
|
||||
|
||||
r2.left = r1.right;
|
||||
r2.right = r1.right + rtlPad;
|
||||
|
||||
g_gui.theme()->drawText(r2, buffer, _state, alignment, inverted, _leftPadding, true);
|
||||
g_gui.theme()->drawText(r2, buffer, _state, _drawAlign, inverted, _leftPadding, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -395,10 +395,11 @@ void PopUpDialog::drawMenuEntry(int entry, bool hilite) {
|
|||
Common::Rect r1(x, y, x + w, y + _lineHeight);
|
||||
Common::Rect r2(x + 1, y + 2, x + w, y + 2 + _lineHeight);
|
||||
Graphics::TextAlign alignment = Graphics::kTextAlignLeft;
|
||||
int pad = _leftPadding;
|
||||
|
||||
if (g_gui.useRTL()) {
|
||||
if (_twoColumns) {
|
||||
r1.translate(this->getWidth() - w, 0);
|
||||
r1.translate(this->getWidth() - w, 0); // Shift the line-separator to the "first" col of RTL popup
|
||||
}
|
||||
|
||||
r2.left = g_system->getOverlayWidth() - r2.left - w + g_gui.getOverlayOffset();
|
||||
|
@ -410,7 +411,7 @@ void PopUpDialog::drawMenuEntry(int entry, bool hilite) {
|
|||
alignment = Graphics::kTextAlignRight;
|
||||
}
|
||||
|
||||
_leftPadding = 0;
|
||||
pad = _rightPadding;
|
||||
}
|
||||
|
||||
if (name.size() == 0) {
|
||||
|
@ -420,7 +421,7 @@ void PopUpDialog::drawMenuEntry(int entry, bool hilite) {
|
|||
g_gui.theme()->drawText(
|
||||
r2,
|
||||
name, hilite ? ThemeEngine::kStateHighlight : ThemeEngine::kStateEnabled,
|
||||
alignment, ThemeEngine::kTextInversionNone, _leftPadding
|
||||
alignment, ThemeEngine::kTextInversionNone, pad
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -537,10 +538,12 @@ void PopUpWidget::drawWidget() {
|
|||
if (_selectedItem >= 0)
|
||||
sel = _entries[_selectedItem].name;
|
||||
|
||||
if (g_gui.useRTL() && _useRTL)
|
||||
_leftPadding = 0;
|
||||
int pad = _leftPadding;
|
||||
|
||||
g_gui.theme()->drawPopUpWidget(Common::Rect(_x, _y, _x + _w, _y + _h), sel, _leftPadding, _state, (g_gui.useRTL() && _useRTL));
|
||||
if (g_gui.useRTL() && _useRTL)
|
||||
pad = _rightPadding;
|
||||
|
||||
g_gui.theme()->drawPopUpWidget(Common::Rect(_x, _y, _x + _w, _y + _h), sel, pad, _state, (g_gui.useRTL() && _useRTL));
|
||||
}
|
||||
|
||||
} // End of namespace GUI
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue