diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/widget.cpp | 47 | ||||
-rw-r--r-- | src/window.cpp | 3 |
2 files changed, 30 insertions, 20 deletions
diff --git a/src/widget.cpp b/src/widget.cpp index 1d4f84059..85715df7f 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -30,30 +30,35 @@ static const char *DOWNARROW = "\xEE\x8A\xAA"; ///< String containing a downward * @param sb Scrollbar list data * @param top Top position of the scrollbar (top position of the up-button) * @param bottom Bottom position of the scrollbar (bottom position of the down-button) + * @param horizontal Whether the scrollbar is horizontal or not * @return A Point, with x containing the top coordinate of the draggable part, and * y containing the bottom coordinate of the draggable part */ -static Point HandleScrollbarHittest(const Scrollbar *sb, int top, int bottom) +static Point HandleScrollbarHittest(const Scrollbar *sb, int top, int bottom, bool horizontal) { - Point pt; - int height, count, pos, cap; - + /* Base for reversion */ + int rev_base = top + bottom; top += 10; // top points to just below the up-button bottom -= 9; // bottom points to top of the down-button - height = (bottom - top); - - pos = sb->GetPosition(); - count = sb->GetCount(); - cap = sb->GetCapacity(); + int height = (bottom - top); + int pos = sb->GetPosition(); + int count = sb->GetCount(); + int cap = sb->GetCapacity(); if (count != 0) top += height * pos / count; if (cap > count) cap = count; if (count != 0) bottom -= (count - pos - cap) * height / count; - pt.x = top; - pt.y = bottom - 1; + Point pt; + if (horizontal && _dynlang.text_dir == TD_RTL) { + pt.x = rev_base - (bottom - 1); + pt.y = rev_base - top; + } else { + pt.x = top; + pt.y = bottom - 1; + } return pt; } @@ -70,6 +75,7 @@ static void ScrollbarClickPositioning(Window *w, WidgetType wtp, int x, int y, i { int pos; Scrollbar *sb; + bool rtl = false; switch (wtp) { case WWT_SCROLLBAR: @@ -88,12 +94,13 @@ static void ScrollbarClickPositioning(Window *w, WidgetType wtp, int x, int y, i sb = &w->vscroll2; break; - case WWT_HSCROLLBAR: + case WWT_HSCROLLBAR: /* horizontal scroller */ w->flags4 &= ~WF_SCROLL2; w->flags4 |= WF_HSCROLL; pos = x; sb = &w->hscroll; + rtl = _dynlang.text_dir == TD_RTL; break; default: NOT_REACHED(); @@ -103,7 +110,7 @@ static void ScrollbarClickPositioning(Window *w, WidgetType wtp, int x, int y, i w->flags4 |= WF_SCROLL_UP; if (_scroller_click_timeout == 0) { _scroller_click_timeout = 6; - sb->UpdatePosition(-1); + sb->UpdatePosition(rtl ? 1 : -1); } _left_button_clicked = false; } else if (pos >= ma - 10) { @@ -112,16 +119,16 @@ static void ScrollbarClickPositioning(Window *w, WidgetType wtp, int x, int y, i if (_scroller_click_timeout == 0) { _scroller_click_timeout = 6; - sb->UpdatePosition(1); + sb->UpdatePosition(rtl ? -1 : 1); } _left_button_clicked = false; } else { - Point pt = HandleScrollbarHittest(sb, mi, ma); + Point pt = HandleScrollbarHittest(sb, mi, ma, wtp == WWT_HSCROLLBAR); if (pos < pt.x) { - sb->UpdatePosition(-sb->GetCapacity()); + sb->UpdatePosition(rtl ? sb->GetCapacity() : -sb->GetCapacity()); } else if (pos > pt.y) { - sb->UpdatePosition(sb->GetCapacity()); + sb->UpdatePosition(rtl ? -sb->GetCapacity() : sb->GetCapacity()); } else { _scrollbar_start_pos = pt.x - mi - 9; _scrollbar_size = ma - mi - 23; @@ -158,7 +165,7 @@ void ScrollbarClickHandler(Window *w, const NWidgetCore *nw, int x, int y) ma = nw->pos_y + nw->current_y; break; - case WWT_HSCROLLBAR: + case WWT_HSCROLLBAR: /* horizontal scroller */ mi = nw->pos_x; ma = nw->pos_x + nw->current_x; @@ -357,7 +364,7 @@ static inline void DrawVerticalScrollbar(const Rect &r, Colours colour, bool up_ GfxFillRect(r.left + 7, r.top + 10, r.left + 7, r.bottom - 10, c1); GfxFillRect(r.left + 8, r.top + 10, r.left + 8, r.bottom - 10, c2); - Point pt = HandleScrollbarHittest(scrollbar, r.top, r.bottom); + Point pt = HandleScrollbarHittest(scrollbar, r.top, r.bottom, false); DrawFrameRect(r.left, pt.x, r.right, pt.y, colour, bar_dragged ? FR_LOWERED : FR_NONE); } @@ -392,7 +399,7 @@ static inline void DrawHorizontalScrollbar(const Rect &r, Colours colour, bool l GfxFillRect(r.left + 10, r.top + 8, r.right - 10, r.top + 8, c2); /* draw actual scrollbar */ - Point pt = HandleScrollbarHittest(scrollbar, r.left, r.right); + Point pt = HandleScrollbarHittest(scrollbar, r.left, r.right, true); DrawFrameRect(pt.x, r.top, pt.y, r.bottom, colour, bar_dragged ? FR_LOWERED : FR_NONE); } diff --git a/src/window.cpp b/src/window.cpp index 5cfae5d49..bca74130b 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1676,10 +1676,12 @@ static bool HandleScrollbarScrolling() int i; Scrollbar *sb; + bool rtl = false; if (w->flags4 & WF_HSCROLL) { sb = &w->hscroll; i = _cursor.pos.x - _cursorpos_drag_start.x; + rtl = _dynlang.text_dir == TD_RTL; } else if (w->flags4 & WF_SCROLL2) { sb = &w->vscroll2; i = _cursor.pos.y - _cursorpos_drag_start.y; @@ -1690,6 +1692,7 @@ static bool HandleScrollbarScrolling() /* Find the item we want to move to and make sure it's inside bounds. */ int pos = min(max(0, i + _scrollbar_start_pos) * sb->GetCount() / _scrollbar_size, max(0, sb->GetCount() - sb->GetCapacity())); + if (rtl) pos = sb->GetCount() - sb->GetCapacity() - pos; if (pos != sb->GetPosition()) { sb->SetPosition(pos); w->SetDirty(); |