summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/widget.cpp152
-rw-r--r--src/widget_type.h16
-rw-r--r--src/window.cpp16
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);
}