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));
|
drawArea = drawArea.findIntersectingRect(Common::Rect(0, 0, _activeSurface->w, _activeSurface->h));
|
||||||
|
|
||||||
if (!drawArea.isEmpty()) {
|
if (!drawArea.isEmpty()) {
|
||||||
|
Common::Rect textArea(area);
|
||||||
|
textArea.right -= deltax;
|
||||||
|
|
||||||
Surface textAreaSurface = _activeSurface->getSubArea(drawArea);
|
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
|
// 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
|
// that we do allow an empty width to be specified here. This allows us
|
||||||
// to obtain the complete bounding box of a string.
|
// 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);
|
int width = font.getStringWidth(str);
|
||||||
|
|
||||||
if (align == kTextAlignCenter)
|
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.
|
// ever change something here we will need to change it there too.
|
||||||
assert(dst != 0);
|
assert(dst != 0);
|
||||||
|
|
||||||
const int leftX = x, rightX = x + w;
|
const int leftX = x, rightX = x + w + 1;
|
||||||
int width = font.getStringWidth(str);
|
int width = font.getStringWidth(str);
|
||||||
|
|
||||||
if (align == kTextAlignCenter)
|
if (align == kTextAlignCenter)
|
||||||
|
|
|
@ -47,6 +47,9 @@ void EditableWidget::init() {
|
||||||
|
|
||||||
_editScrollOffset = 0;
|
_editScrollOffset = 0;
|
||||||
|
|
||||||
|
_align = g_gui.useRTL() ? Graphics::kTextAlignRight : Graphics::kTextAlignLeft;
|
||||||
|
_drawAlign = _align;
|
||||||
|
|
||||||
_font = ThemeEngine::kFontStyleBold;
|
_font = ThemeEngine::kFontStyleBold;
|
||||||
_inversion = ThemeEngine::kTextInversionNone;
|
_inversion = ThemeEngine::kTextInversionNone;
|
||||||
}
|
}
|
||||||
|
@ -58,8 +61,12 @@ void EditableWidget::reflowLayout() {
|
||||||
Widget::reflowLayout();
|
Widget::reflowLayout();
|
||||||
|
|
||||||
_editScrollOffset = g_gui.getStringWidth(_editString, _font) - getEditRect().width();
|
_editScrollOffset = g_gui.getStringWidth(_editString, _font) - getEditRect().width();
|
||||||
if (_editScrollOffset < 0)
|
if (_editScrollOffset < 0) {
|
||||||
_editScrollOffset = 0;
|
_editScrollOffset = 0;
|
||||||
|
_drawAlign = _align;
|
||||||
|
} else {
|
||||||
|
_drawAlign = Graphics::kTextAlignLeft;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditableWidget::setEditString(const String &str) {
|
void EditableWidget::setEditString(const String &str) {
|
||||||
|
@ -265,18 +272,8 @@ void EditableWidget::defaultKeyDownHandler(Common::KeyState &state, bool &dirty,
|
||||||
}
|
}
|
||||||
|
|
||||||
int EditableWidget::getCaretOffset() const {
|
int EditableWidget::getCaretOffset() const {
|
||||||
int caretpos = 0;
|
Common::String substr(_editString.c_str(), _caretPos);
|
||||||
|
return g_gui.getStringWidth(substr, _font) - _editScrollOffset;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditableWidget::drawCaret(bool erase) {
|
void EditableWidget::drawCaret(bool erase) {
|
||||||
|
@ -289,7 +286,16 @@ void EditableWidget::drawCaret(bool erase) {
|
||||||
int x = editRect.left;
|
int x = editRect.left;
|
||||||
int y = editRect.top;
|
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();
|
const int caretOffset = getCaretOffset();
|
||||||
x += caretOffset;
|
x += caretOffset;
|
||||||
|
@ -297,14 +303,12 @@ void EditableWidget::drawCaret(bool erase) {
|
||||||
if (y < 0 || y + editRect.height() > _h)
|
if (y < 0 || y + editRect.height() > _h)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
x += getAbsX();
|
if (g_gui.useRTL())
|
||||||
|
x += g_system->getOverlayWidth() - _w - getAbsX() + g_gui.getOverlayOffset();
|
||||||
|
else
|
||||||
|
x += getAbsX();
|
||||||
y += getAbsY();
|
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);
|
g_gui.theme()->drawCaret(Common::Rect(x, y, x + 1, y + editRect.height()), erase);
|
||||||
|
|
||||||
if (erase) {
|
if (erase) {
|
||||||
|
@ -335,7 +339,7 @@ void EditableWidget::drawCaret(bool erase) {
|
||||||
width = MIN(editRect.width() - caretOffset, width);
|
width = MIN(editRect.width() - caretOffset, width);
|
||||||
if (width > 0) {
|
if (width > 0) {
|
||||||
g_gui.theme()->drawText(Common::Rect(x, y, x + width, y + editRect.height()), character,
|
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);
|
ThemeEngine::kFontColorNormal, true, _textDrawableArea);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,9 @@ protected:
|
||||||
|
|
||||||
int _editScrollOffset;
|
int _editScrollOffset;
|
||||||
|
|
||||||
|
Graphics::TextAlign _align;
|
||||||
|
Graphics::TextAlign _drawAlign;
|
||||||
|
|
||||||
ThemeEngine::FontStyle _font;
|
ThemeEngine::FontStyle _font;
|
||||||
|
|
||||||
ThemeEngine::TextInversionState _inversion;
|
ThemeEngine::TextInversionState _inversion;
|
||||||
|
|
|
@ -72,21 +72,28 @@ void EditTextWidget::handleMouseDown(int x, int y, int button, int clickCount) {
|
||||||
if (_caretVisible)
|
if (_caretVisible)
|
||||||
drawCaret(true);
|
drawCaret(true);
|
||||||
|
|
||||||
x += _editScrollOffset;
|
if (g_gui.useRTL()) {
|
||||||
|
x = _w - x;
|
||||||
|
}
|
||||||
|
|
||||||
|
x += _editScrollOffset;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
|
if (_drawAlign == Graphics::kTextAlignRight)
|
||||||
|
width = _editScrollOffset + getEditRect().width() - g_gui.getStringWidth(_editString, _font);
|
||||||
|
|
||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
uint last = 0;
|
uint last = 0;
|
||||||
for (i = 0; i < _editString.size(); ++i) {
|
for (i = 0; i < _editString.size(); ++i) {
|
||||||
const uint cur = _editString[i];
|
const uint cur = _editString[i];
|
||||||
width += g_gui.getCharWidth(cur, _font) + g_gui.getKerningOffset(last, cur, _font);
|
width += g_gui.getCharWidth(cur, _font) + g_gui.getKerningOffset(last, cur, _font);
|
||||||
if (width >= x)
|
if (width >= x && width > _editScrollOffset + _leftPadding)
|
||||||
break;
|
break;
|
||||||
last = cur;
|
last = cur;
|
||||||
}
|
}
|
||||||
if (setCaretPos(i))
|
|
||||||
markAsDirty();
|
setCaretPos(i);
|
||||||
|
markAsDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditTextWidget::drawWidget() {
|
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);
|
const Common::Rect &r = Common::Rect(_x + 2 + _leftPadding, _y + 2, _x + _leftPadding + getEditRect().width() + 8, _y + _h);
|
||||||
setTextDrawableArea(r);
|
setTextDrawableArea(r);
|
||||||
|
|
||||||
Graphics::TextAlign alignment = g_gui.useRTL() ? Graphics::kTextAlignRight : Graphics::kTextAlignLeft;
|
|
||||||
|
|
||||||
g_gui.theme()->drawText(
|
g_gui.theme()->drawText(
|
||||||
Common::Rect(_x + 2 + _leftPadding, _y + 1, _x + _leftPadding + getEditRect().width() + 2, _y + _h),
|
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);
|
-_editScrollOffset, false, _font, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -536,7 +536,6 @@ void ListWidget::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
|
||||||
void ListWidget::drawWidget() {
|
void ListWidget::drawWidget() {
|
||||||
int i, pos, len = _list.size();
|
int i, pos, len = _list.size();
|
||||||
Common::String buffer;
|
Common::String buffer;
|
||||||
Graphics::TextAlign alignment = g_gui.useRTL() ? Graphics::kTextAlignRight : Graphics::kTextAlignLeft;
|
|
||||||
|
|
||||||
// Draw a thin frame around the list.
|
// Draw a thin frame around the list.
|
||||||
g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x + _w, _y + _h),
|
g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x + _w, _y + _h),
|
||||||
|
@ -553,14 +552,14 @@ void ListWidget::drawWidget() {
|
||||||
inverted = _inversion;
|
inverted = _inversion;
|
||||||
|
|
||||||
Common::Rect r(getEditRect());
|
Common::Rect r(getEditRect());
|
||||||
int pad = g_gui.useRTL() ? _rightPadding : _leftPadding;
|
int pad = _leftPadding;
|
||||||
int rtlPad = (_x + r.left + _leftPadding) - (_x + _hlLeftPadding);
|
int rtlPad = (_x + r.left + _leftPadding) - (_x + _hlLeftPadding);
|
||||||
|
|
||||||
// If in numbering mode & not in RTL based GUI, we first print a number prefix
|
// If in numbering mode & not in RTL based GUI, we first print a number prefix
|
||||||
if (_numberingMode != kListNumberingOff && g_gui.useRTL() == false) {
|
if (_numberingMode != kListNumberingOff && g_gui.useRTL() == false) {
|
||||||
buffer = Common::String::format("%2d. ", (pos + _numberingMode));
|
buffer = Common::String::format("%2d. ", (pos + _numberingMode));
|
||||||
g_gui.theme()->drawText(Common::Rect(_x + _hlLeftPadding, y, _x + r.left + _leftPadding, y + fontHeight - 2),
|
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;
|
pad = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,18 +592,18 @@ void ListWidget::drawWidget() {
|
||||||
buffer = _list[pos];
|
buffer = _list[pos];
|
||||||
}
|
}
|
||||||
g_gui.theme()->drawText(r1, buffer, _state,
|
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 in numbering mode & using RTL layout in GUI, we print a number suffix after drawing the text
|
||||||
if (_numberingMode != kListNumberingOff && g_gui.useRTL()) {
|
if (_numberingMode != kListNumberingOff && g_gui.useRTL()) {
|
||||||
buffer = Common::String::format("%2d. ", (pos + _numberingMode));
|
buffer = Common::String::format(" .%2d", (pos + _numberingMode));
|
||||||
|
|
||||||
Common::Rect r2 = r1;
|
Common::Rect r2 = r1;
|
||||||
|
|
||||||
r2.left = r1.right;
|
r2.left = r1.right;
|
||||||
r2.right = r1.right + rtlPad;
|
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 r1(x, y, x + w, y + _lineHeight);
|
||||||
Common::Rect r2(x + 1, y + 2, x + w, y + 2 + _lineHeight);
|
Common::Rect r2(x + 1, y + 2, x + w, y + 2 + _lineHeight);
|
||||||
Graphics::TextAlign alignment = Graphics::kTextAlignLeft;
|
Graphics::TextAlign alignment = Graphics::kTextAlignLeft;
|
||||||
|
int pad = _leftPadding;
|
||||||
|
|
||||||
if (g_gui.useRTL()) {
|
if (g_gui.useRTL()) {
|
||||||
if (_twoColumns) {
|
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();
|
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;
|
alignment = Graphics::kTextAlignRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
_leftPadding = 0;
|
pad = _rightPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name.size() == 0) {
|
if (name.size() == 0) {
|
||||||
|
@ -420,7 +421,7 @@ void PopUpDialog::drawMenuEntry(int entry, bool hilite) {
|
||||||
g_gui.theme()->drawText(
|
g_gui.theme()->drawText(
|
||||||
r2,
|
r2,
|
||||||
name, hilite ? ThemeEngine::kStateHighlight : ThemeEngine::kStateEnabled,
|
name, hilite ? ThemeEngine::kStateHighlight : ThemeEngine::kStateEnabled,
|
||||||
alignment, ThemeEngine::kTextInversionNone, _leftPadding
|
alignment, ThemeEngine::kTextInversionNone, pad
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -537,10 +538,12 @@ void PopUpWidget::drawWidget() {
|
||||||
if (_selectedItem >= 0)
|
if (_selectedItem >= 0)
|
||||||
sel = _entries[_selectedItem].name;
|
sel = _entries[_selectedItem].name;
|
||||||
|
|
||||||
if (g_gui.useRTL() && _useRTL)
|
int pad = _leftPadding;
|
||||||
_leftPadding = 0;
|
|
||||||
|
|
||||||
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
|
} // End of namespace GUI
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue