diff options
-rw-r--r-- | src/widget.cpp | 152 | ||||
-rw-r--r-- | src/widget_type.h | 16 | ||||
-rw-r--r-- | src/window.cpp | 16 |
3 files changed, 130 insertions, 54 deletions
diff --git a/src/widget.cpp b/src/widget.cpp index f188e3365..88878e0c8 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -1636,6 +1636,109 @@ void NWidgetViewport::UpdateViewportCoordinates(Window *w) } } +/** + * Scrollbar widget. + * @param tp Scrollbar type. (horizontal/vertical) + * @param colour Colour of the scrollbar. + * @param index Index in the widget array used by the window system. + */ +NWidgetScrollbar::NWidgetScrollbar(WidgetType tp, Colours colour, int index) : NWidgetCore(tp, colour, 1, 1, 0x0, STR_NULL) +{ + assert(tp == WWT_HSCROLLBAR || tp == WWT_SCROLLBAR || tp == WWT_SCROLL2BAR); + this->SetIndex(index); + + switch (this->type) { + case WWT_HSCROLLBAR: + this->SetMinimalSize(30, WD_HSCROLLBAR_HEIGHT); + this->SetResize(1, 0); + this->SetFill(1, 0); + this->SetDataTip(0x0, STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST); + break; + + case WWT_SCROLLBAR: + case WWT_SCROLL2BAR: + this->SetMinimalSize(WD_VSCROLLBAR_WIDTH, 30); + this->SetResize(0, 1); + this->SetFill(0, 1); + this->SetDataTip(0x0, STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST); + break; + + default: NOT_REACHED(); + } +} + +void NWidgetScrollbar::SetupSmallestSize(Window *w, bool init_array) +{ + if (init_array && this->index >= 0) { + assert(w->nested_array_size > (uint)this->index); + w->nested_array[this->index] = this; + } + this->smallest_x = this->min_x; + this->smallest_y = this->min_y; +} + +void NWidgetScrollbar::Draw(const Window *w) +{ + if (this->current_x == 0 || this->current_y == 0) return; + + Rect r; + r.left = this->pos_x; + r.right = this->pos_x + this->current_x - 1; + r.top = this->pos_y; + r.bottom = this->pos_y + this->current_y - 1; + + const DrawPixelInfo *dpi = _cur_dpi; + if (dpi->left > r.right || dpi->left + dpi->width <= r.left || dpi->top > r.bottom || dpi->top + dpi->height <= r.top) return; + + switch (this->type) { + case WWT_HSCROLLBAR: + DrawHorizontalScrollbar(r, this->colour, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL)) == (WF_SCROLL_UP | WF_HSCROLL), + (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL)) == (WF_SCROLL_MIDDLE | WF_HSCROLL), + (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL)) == (WF_SCROLL_DOWN | WF_HSCROLL), this->GetScrollbar(w)); + break; + + case WWT_SCROLLBAR: + assert(this->widget_data == 0); + DrawVerticalScrollbar(r, this->colour, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_UP, + (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_MIDDLE, + (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_DOWN, this->GetScrollbar(w)); + break; + + case WWT_SCROLL2BAR: + assert(this->widget_data == 0); + DrawVerticalScrollbar(r, this->colour, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_UP | WF_SCROLL2), + (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_MIDDLE | WF_SCROLL2), + (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_DOWN | WF_SCROLL2), this->GetScrollbar(w)); + break; + + default: NOT_REACHED(); + } + + if (this->IsDisabled()) { + GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, _colour_gradient[this->colour & 0xF][2], FILLRECT_CHECKER); + } +} + +const Scrollbar *NWidgetScrollbar::GetScrollbar(const Window *w) const +{ + switch (this->type) { + case WWT_HSCROLLBAR: return &w->old_hscroll; + case WWT_SCROLLBAR: return &w->old_vscroll; + case WWT_SCROLL2BAR: return &w->old_vscroll2; + default: NOT_REACHED(); + } +} + +Scrollbar *NWidgetScrollbar::GetScrollbar(Window *w) const +{ + switch (this->type) { + case WWT_HSCROLLBAR: return &w->old_hscroll; + case WWT_SCROLLBAR: return &w->old_vscroll; + case WWT_SCROLL2BAR: return &w->old_vscroll2; + default: NOT_REACHED(); + } +} + /** Reset the cached dimensions. */ /* static */ void NWidgetLeaf::InvalidateDimensionCache() { @@ -1691,14 +1794,6 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, this->SetFill(0, 0); break; - case WWT_SCROLLBAR: - case WWT_SCROLL2BAR: - this->SetFill(0, 1); - this->SetResize(0, 1); - this->min_x = WD_VSCROLLBAR_WIDTH; - this->SetDataTip(0x0, STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST); - break; - case WWT_CAPTION: this->SetFill(1, 0); this->SetResize(1, 0); @@ -1706,13 +1801,6 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, this->SetDataTip(data, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS); break; - case WWT_HSCROLLBAR: - this->SetFill(1, 0); - this->SetResize(1, 0); - this->min_y = WD_HSCROLLBAR_HEIGHT; - this->SetDataTip(0x0, STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST); - break; - case WWT_STICKYBOX: this->SetFill(0, 0); this->SetMinimalSize(WD_STICKYBOX_WIDTH, 14); @@ -1766,10 +1854,7 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) /* Get padding, and update size with the real content size if appropriate. */ const Dimension *padding = NULL; switch (this->type) { - case WWT_EMPTY: - case WWT_SCROLLBAR: - case WWT_SCROLL2BAR: - case WWT_HSCROLLBAR: { + case WWT_EMPTY: { static const Dimension extra = {0, 0}; padding = &extra; break; @@ -1993,32 +2078,11 @@ void NWidgetLeaf::Draw(const Window *w) DrawFrameRect(r.left, r.top, r.right, r.bottom, this->colour, FR_LOWERED | FR_DARKENED); break; - case WWT_SCROLLBAR: - assert(this->widget_data == 0); - DrawVerticalScrollbar(r, this->colour, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_UP, - (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_MIDDLE, - (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_DOWN, &w->old_vscroll); - break; - - case WWT_SCROLL2BAR: - assert(this->widget_data == 0); - DrawVerticalScrollbar(r, this->colour, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_UP | WF_SCROLL2), - (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_MIDDLE | WF_SCROLL2), - (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_DOWN | WF_SCROLL2), &w->old_vscroll2); - break; - case WWT_CAPTION: if (this->index >= 0) w->SetStringParameters(this->index); DrawCaption(r, this->colour, w->owner, this->widget_data); break; - case WWT_HSCROLLBAR: - assert(this->widget_data == 0); - DrawHorizontalScrollbar(r, this->colour, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL)) == (WF_SCROLL_UP | WF_HSCROLL), - (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL)) == (WF_SCROLL_MIDDLE | WF_HSCROLL), - (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL)) == (WF_SCROLL_DOWN | WF_HSCROLL), &w->old_hscroll); - break; - case WWT_SHADEBOX: assert(this->widget_data == 0); DrawShadeBox(r, this->colour, w->IsShaded()); @@ -2220,6 +2284,14 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, *biggest_index = max(*biggest_index, (int)parts->u.widget.index); break; + case WWT_HSCROLLBAR: + case WWT_SCROLLBAR: + case WWT_SCROLL2BAR: + if (*dest != NULL) return num_used; + *dest = new NWidgetScrollbar(parts->type, parts->u.widget.colour, parts->u.widget.index); + *biggest_index = max(*biggest_index, (int)parts->u.widget.index); + break; + case NWID_SELECTION: { if (*dest != NULL) return num_used; NWidgetStacked *nws = new NWidgetStacked(); diff --git a/src/widget_type.h b/src/widget_type.h index da871df55..f61937aa8 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -502,6 +502,22 @@ public: }; /** + * Nested widget to display and control a scrollbar in a window. + * Also assign the scrollbar to other widgets using #SetScrollbar() to make the mousewheel work. + * @ingroup NestedWidgets + */ +class NWidgetScrollbar : public NWidgetCore { +public: + NWidgetScrollbar(WidgetType tp, Colours colour, int index); + + /* virtual */ void SetupSmallestSize(Window *w, bool init_array); + /* virtual */ void Draw(const Window *w); + + const Scrollbar *GetScrollbar(const Window *w) const; + Scrollbar *GetScrollbar(Window *w) const; +}; + +/** * Leaf widget. * @ingroup NestedWidgets */ diff --git a/src/window.cpp b/src/window.cpp index 1261a66d0..cba0f799e 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -137,13 +137,7 @@ void Scrollbar::SetCapacityFromWidget(Window *w, int widget, int padding) */ const Scrollbar *Window::GetScrollbar(uint widnum) const { - const NWidgetLeaf *wid = this->GetWidget<NWidgetLeaf>(widnum); - switch (wid->type) { - case WWT_HSCROLLBAR: return &this->old_hscroll; - case WWT_SCROLLBAR: return &this->old_vscroll; - case WWT_SCROLL2BAR: return &this->old_vscroll2; - default: NOT_REACHED(); - } + return this->GetWidget<NWidgetScrollbar>(widnum)->GetScrollbar(this); } /** @@ -153,13 +147,7 @@ const Scrollbar *Window::GetScrollbar(uint widnum) const */ Scrollbar *Window::GetScrollbar(uint widnum) { - NWidgetLeaf *wid = this->GetWidget<NWidgetLeaf>(widnum); - switch (wid->type) { - case WWT_HSCROLLBAR: return &this->old_hscroll; - case WWT_SCROLLBAR: return &this->old_vscroll; - case WWT_SCROLL2BAR: return &this->old_vscroll2; - default: NOT_REACHED(); - } + return this->GetWidget<NWidgetScrollbar>(widnum)->GetScrollbar(this); } |