diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -52,15 +52,18 @@ struct AIListWindow : public Window { int selected; CompanyID slot; int line_height; // Height of a row in the matrix widget. + Scrollbar *vscroll; AIListWindow(const WindowDesc *desc, CompanyID slot) : Window(), slot(slot) { this->ai_info_list = AI::GetUniqueInfoList(); - this->InitNested(desc); // Initializes 'this->line_height' as side effect. + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(AIL_WIDGET_SCROLLBAR); + this->FinishInitNested(desc); // Initializes 'this->line_height' as side effect. - this->vscroll.SetCount((int)this->ai_info_list->size() + 1); + this->vscroll->SetCount((int)this->ai_info_list->size() + 1); /* Try if we can find the currently selected AI */ this->selected = -1; @@ -99,13 +102,13 @@ struct AIListWindow : public Window { /* Draw a list of all available AIs. */ int y = this->GetWidget(AIL_WIDGET_LIST)->pos_y; /* First AI in the list is hardcoded to random */ - if (this->vscroll.IsVisible(0)) { + if (this->vscroll->IsVisible(0)) { DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_LEFT, y + WD_MATRIX_TOP, STR_AI_CONFIG_RANDOM_AI, this->selected == -1 ? TC_WHITE : TC_BLACK); y += this->line_height; } AIInfoList::const_iterator it = this->ai_info_list->begin(); for (int i = 1; it != this->ai_info_list->end(); i++, it++) { - if (this->vscroll.IsVisible(i)) { + if (this->vscroll->IsVisible(i)) { DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, (*it).second->GetName(), (this->selected == i - 1) ? TC_WHITE : TC_BLACK); y += this->line_height; } @@ -156,7 +159,7 @@ struct AIListWindow : public Window { { switch (widget) { case AIL_WIDGET_LIST: { // Select one of the AIs - int sel = this->vscroll.GetScrolledRowFromWidget(pt.y, this, AIL_WIDGET_LIST, 0, this->line_height) - 1; + int sel = this->vscroll->GetScrolledRowFromWidget(pt.y, this, AIL_WIDGET_LIST, 0, this->line_height) - 1; if (sel < (int)this->ai_info_list->size()) { this->selected = sel; this->SetDirty(); @@ -183,8 +186,8 @@ struct AIListWindow : public Window { virtual void OnResize() { NWidgetCore *nwi = this->GetWidget(AIL_WIDGET_LIST); - this->vscroll.SetCapacity(nwi->current_y / this->line_height); - nwi->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacity(nwi->current_y / this->line_height); + nwi->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } }; @@ -246,6 +249,7 @@ struct AISettingsWindow : public Window int timeout; int clicked_row; int line_height; // Height of a row in the matrix widget. + Scrollbar *vscroll; AISettingsWindow(const WindowDesc *desc, CompanyID slot) : Window(), slot(slot), @@ -254,11 +258,13 @@ struct AISettingsWindow : public Window { this->ai_config = AIConfig::GetConfig(slot); - this->InitNested(desc, slot); // Initializes 'this->line_height' as side effect. + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(AIS_WIDGET_SCROLLBAR); + this->FinishInitNested(desc, slot); // Initializes 'this->line_height' as side effect. this->SetWidgetDisabledState(AIS_WIDGET_RESET, _game_mode != GM_MENU); - this->vscroll.SetCount((int)this->ai_config->GetConfigList()->size()); + this->vscroll->SetCount((int)this->ai_config->GetConfigList()->size()); } virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) @@ -284,7 +290,7 @@ struct AISettingsWindow : public Window AIConfig *config = this->ai_config; AIConfigItemList::const_iterator it = config->GetConfigList()->begin(); int i = 0; - for (; !this->vscroll.IsVisible(i); i++) it++; + for (; !this->vscroll->IsVisible(i); i++) it++; bool rtl = _dynlang.text_dir == TD_RTL; uint buttons_left = rtl ? r.right - 23 : r.left + 4; @@ -295,7 +301,7 @@ struct AISettingsWindow : public Window int y = r.top; - for (; this->vscroll.IsVisible(i) && it != config->GetConfigList()->end(); i++, it++) { + for (; this->vscroll->IsVisible(i) && it != config->GetConfigList()->end(); i++, it++) { int current_value = config->GetSetting((*it).name); bool editable = (_game_mode == GM_MENU) || ((it->flags & AICONFIG_INGAME) != 0); @@ -334,7 +340,7 @@ struct AISettingsWindow : public Window switch (widget) { case AIS_WIDGET_BACKGROUND: { const NWidgetBase *wid = this->GetWidget(AIS_WIDGET_BACKGROUND); - int num = (pt.y - wid->pos_y) / this->line_height + this->vscroll.GetPosition(); + int num = (pt.y - wid->pos_y) / this->line_height + this->vscroll->GetPosition(); if (num >= (int)this->ai_config->GetConfigList()->size()) break; AIConfigItemList::const_iterator it = this->ai_config->GetConfigList()->begin(); @@ -405,8 +411,8 @@ struct AISettingsWindow : public Window virtual void OnResize() { NWidgetCore *nwi = this->GetWidget(AIS_WIDGET_BACKGROUND); - this->vscroll.SetCapacity(nwi->current_y / this->line_height); - nwi->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacity(nwi->current_y / this->line_height); + nwi->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } virtual void OnTick() @@ -519,15 +525,17 @@ static const WindowDesc _ai_config_desc( struct AIConfigWindow : public Window { CompanyID selected_slot; ///< The currently selected AI slot or \c INVALID_COMPANY. int line_height; ///< Height of a single AI-name line. + Scrollbar *vscroll; AIConfigWindow() : Window() { this->InitNested(&_ai_config_desc); // Initializes 'this->line_height' as a side effect. + this->vscroll = this->GetScrollbar(AIC_WIDGET_SCROLLBAR); this->selected_slot = INVALID_COMPANY; NWidgetCore *nwi = this->GetWidget(AIC_WIDGET_LIST); - this->vscroll.SetCapacity(nwi->current_y / this->line_height); - this->vscroll.SetCount(MAX_COMPANIES); - nwi->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacity(nwi->current_y / this->line_height); + this->vscroll->SetCount(MAX_COMPANIES); + nwi->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); this->OnInvalidateData(0); } @@ -566,7 +574,7 @@ struct AIConfigWindow : public Window { switch (widget) { case AIC_WIDGET_LIST: { int y = r.top; - for (int i = this->vscroll.GetPosition(); this->vscroll.IsVisible(i) && i < MAX_COMPANIES; i++) { + for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < MAX_COMPANIES; i++) { StringID text; if (AIConfig::GetConfig((CompanyID)i)->GetInfo() != NULL) { @@ -603,7 +611,7 @@ struct AIConfigWindow : public Window { } case AIC_WIDGET_LIST: { // Select a slot - this->selected_slot = (CompanyID)this->vscroll.GetScrolledRowFromWidget(pt.y, this, widget, 0, this->line_height); + this->selected_slot = (CompanyID)this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget, 0, this->line_height); this->InvalidateData(); if (click_count > 1 && this->selected_slot != INVALID_COMPANY) ShowAIListWindow((CompanyID)this->selected_slot); break; @@ -613,7 +621,7 @@ struct AIConfigWindow : public Window { if (this->selected_slot > 1) { Swap(_settings_newgame.ai_config[this->selected_slot], _settings_newgame.ai_config[this->selected_slot - 1]); this->selected_slot--; - this->vscroll.ScrollTowards(this->selected_slot); + this->vscroll->ScrollTowards(this->selected_slot); this->InvalidateData(); } break; @@ -622,7 +630,7 @@ struct AIConfigWindow : public Window { if (this->selected_slot < _settings_newgame.difficulty.max_no_competitors) { Swap(_settings_newgame.ai_config[this->selected_slot], _settings_newgame.ai_config[this->selected_slot + 1]); this->selected_slot++; - this->vscroll.ScrollTowards(this->selected_slot); + this->vscroll->ScrollTowards(this->selected_slot); this->InvalidateData(); } break; @@ -708,10 +716,12 @@ struct AIDebugWindow : public QueryStrin static char break_string[MAX_BREAK_STR_STRING_LENGTH]; ///< The string to match to the AI output static bool case_sensitive_break_check; ///< Is the matching done case-sensitive int highlight_row; ///< The output row that matches the given string, or -1 + Scrollbar *vscroll; AIDebugWindow(const WindowDesc *desc, WindowNumber number) : QueryStringBaseWindow(MAX_BREAK_STR_STRING_LENGTH) { this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(AID_WIDGET_SCROLLBAR); this->show_break_box = _settings_client.gui.ai_developer_tools; this->GetWidget(AID_BREAK_STRING_WIDGETS)->SetDisplayedPlane(this->show_break_box ? 0 : SZSP_HORIZONTAL); this->FinishInitNested(desc, number); @@ -824,8 +834,8 @@ struct AIDebugWindow : public QueryStrin cur_company.Restore(); int scroll_count = (log == NULL) ? 0 : log->used; - if (this->vscroll.GetCount() != scroll_count) { - this->vscroll.SetCount(scroll_count); + if (this->vscroll->GetCount() != scroll_count) { + this->vscroll->SetCount(scroll_count); /* We need a repaint */ this->SetWidgetDirty(AID_WIDGET_SCROLLBAR); @@ -835,20 +845,20 @@ struct AIDebugWindow : public QueryStrin /* Detect when the user scrolls the window. Enable autoscroll when the * bottom-most line becomes visible. */ - if (this->last_vscroll_pos != this->vscroll.GetPosition()) { - this->autoscroll = this->vscroll.GetPosition() >= log->used - this->vscroll.GetCapacity(); + if (this->last_vscroll_pos != this->vscroll->GetPosition()) { + this->autoscroll = this->vscroll->GetPosition() >= log->used - this->vscroll->GetCapacity(); } if (this->autoscroll) { - int scroll_pos = max(0, log->used - this->vscroll.GetCapacity()); - if (scroll_pos != this->vscroll.GetPosition()) { - this->vscroll.SetPosition(scroll_pos); + int scroll_pos = max(0, log->used - this->vscroll->GetCapacity()); + if (scroll_pos != this->vscroll->GetPosition()) { + this->vscroll->SetPosition(scroll_pos); /* We need a repaint */ this->SetWidgetDirty(AID_WIDGET_SCROLLBAR); this->SetWidgetDirty(AID_WIDGET_LOG_PANEL); } } - this->last_vscroll_pos = this->vscroll.GetPosition(); + this->last_vscroll_pos = this->vscroll->GetPosition(); } virtual void SetStringParameters(int widget) const @@ -880,7 +890,7 @@ struct AIDebugWindow : public QueryStrin if (log == NULL) return; int y = this->top_offset; - for (int i = this->vscroll.GetPosition(); this->vscroll.IsVisible(i) && i < log->used; i++) { + for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < log->used; i++) { int pos = (i + log->pos + 1 - log->used + log->count) % log->count; if (log->lines[pos] == NULL) break; @@ -916,11 +926,11 @@ struct AIDebugWindow : public QueryStrin Backup cur_company(_current_company, ai_debug_company, FILE_LINE); AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer(); cur_company.Restore(); - this->vscroll.SetCount((log == NULL) ? 0 : log->used); + this->vscroll->SetCount((log == NULL) ? 0 : log->used); this->LowerWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START); this->autoscroll = true; - this->last_vscroll_pos = this->vscroll.GetPosition(); + this->last_vscroll_pos = this->vscroll->GetPosition(); this->SetDirty(); /* Close AI settings window to prevent confusion */ DeleteWindowByClass(WC_AI_SETTINGS); @@ -1034,7 +1044,7 @@ struct AIDebugWindow : public QueryStrin virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, AID_WIDGET_LOG_PANEL); + this->vscroll->SetCapacityFromWidget(this, AID_WIDGET_LOG_PANEL); } }; diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -216,6 +216,7 @@ enum AirportPickerWidgets { class BuildAirportWindow : public PickerWindowBase { SpriteID preview_sprite; ///< Cached airport preview sprite. int line_height; + Scrollbar *vscroll; /** Build a dropdown list of available airport classes */ static DropDownList *BuildAirportClassDropDown() @@ -232,15 +233,19 @@ class BuildAirportWindow : public Picker public: BuildAirportWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(parent) { - this->vscroll.SetCapacity(5); - this->vscroll.SetPosition(0); - this->InitNested(desc, TRANSPORT_AIR); + this->CreateNestedTree(desc); + + this->vscroll = this->GetScrollbar(BAIRW_SCROLLBAR); + this->vscroll->SetCapacity(5); + this->vscroll->SetPosition(0); + + this->FinishInitNested(desc, TRANSPORT_AIR); this->SetWidgetLoweredState(BAIRW_BTN_DONTHILIGHT, !_settings_client.gui.station_show_coverage); this->SetWidgetLoweredState(BAIRW_BTN_DOHILIGHT, _settings_client.gui.station_show_coverage); this->OnInvalidateData(); - this->vscroll.SetCount(AirportClass::GetCount(_selected_airport_class)); + this->vscroll->SetCount(AirportClass::GetCount(_selected_airport_class)); this->SelectFirstAvailableAirport(true); } @@ -298,7 +303,7 @@ public: } this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; - size->height = this->vscroll.GetCapacity() * this->line_height; + size->height = this->vscroll->GetCapacity() * this->line_height; break; } @@ -343,7 +348,7 @@ public: switch (widget) { case BAIRW_AIRPORT_LIST: { int y = r.top; - for (uint i = this->vscroll.GetPosition(); this->vscroll.IsVisible(i) && i < AirportClass::GetCount(_selected_airport_class); i++) { + for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < AirportClass::GetCount(_selected_airport_class); i++) { const AirportSpec *as = AirportClass::Get(_selected_airport_class, i); if (!as->IsAvailable()) { GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->line_height - 2, 0, FILLRECT_CHECKER); @@ -451,8 +456,8 @@ public: break; case BAIRW_AIRPORT_LIST: { - int num_clicked = this->vscroll.GetPosition() + (pt.y - this->nested_array[widget]->pos_y) / this->line_height; - if (num_clicked >= this->vscroll.GetCount()) break; + int num_clicked = this->vscroll->GetPosition() + (pt.y - this->nested_array[widget]->pos_y) / this->line_height; + if (num_clicked >= this->vscroll->GetCount()) break; const AirportSpec *as = AirportClass::Get(_selected_airport_class, num_clicked); if (as->IsAvailable()) this->SelectOtherAirport(num_clicked); break; @@ -518,7 +523,7 @@ public: { assert(widget == BAIRW_CLASS_DROPDOWN); _selected_airport_class = (AirportClassID)index; - this->vscroll.SetCount(AirportClass::GetCount(_selected_airport_class)); + this->vscroll->SetCount(AirportClass::GetCount(_selected_airport_class)); this->SelectFirstAvailableAirport(false); } diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -106,6 +106,8 @@ class ReplaceVehicleWindow : public Wind GroupID sel_group; ///< Group selected to replace. int details_height; ///< Minimal needed height of the details panels (found so far). RailType sel_railtype; ///< Type of rail tracks selected. + Scrollbar *vscroll; + Scrollbar *vscroll2; /** * Figure out if an engine should be added to a list. @@ -171,7 +173,7 @@ class ReplaceVehicleWindow : public Wind if (this->engines[0].NeedRebuild()) { /* We need to rebuild the left engines list */ this->GenerateReplaceVehList(true); - this->vscroll.SetCount(this->engines[0].Length()); + this->vscroll->SetCount(this->engines[0].Length()); if (this->reset_sel_engine && this->sel_engine[0] == INVALID_ENGINE && this->engines[0].Length() != 0) { this->sel_engine[0] = this->engines[0][0]; } @@ -185,7 +187,7 @@ class ReplaceVehicleWindow : public Wind this->sel_engine[1] = INVALID_ENGINE; } else { this->GenerateReplaceVehList(false); - this->vscroll2.SetCount(this->engines[1].Length()); + this->vscroll2->SetCount(this->engines[1].Length()); if (this->reset_sel_engine && this->sel_engine[1] == INVALID_ENGINE && this->engines[1].Length() != 0) { this->sel_engine[1] = this->engines[1][0]; } @@ -226,7 +228,10 @@ public: this->sel_engine[0] = INVALID_ENGINE; this->sel_engine[1] = INVALID_ENGINE; - this->InitNested(desc, vehicletype); + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(RVW_WIDGET_LEFT_SCROLLBAR); + this->vscroll2 = this->GetScrollbar(RVW_WIDGET_RIGHT_SCROLLBAR); + this->FinishInitNested(desc, vehicletype); this->owner = _local_company; this->sel_group = id_g; @@ -339,8 +344,8 @@ public: case RVW_WIDGET_LEFT_MATRIX: case RVW_WIDGET_RIGHT_MATRIX: { int side = (widget == RVW_WIDGET_LEFT_MATRIX) ? 0 : 1; - EngineID start = side == 0 ? this->vscroll.GetPosition() : this->vscroll2.GetPosition(); // what is the offset for the start (scrolling) - EngineID end = min((side == 0 ? this->vscroll.GetCapacity() : this->vscroll2.GetCapacity()) + start, this->engines[side].Length()); + EngineID start = side == 0 ? this->vscroll->GetPosition() : this->vscroll2->GetPosition(); // what is the offset for the start (scrolling) + EngineID end = min((side == 0 ? this->vscroll->GetCapacity() : this->vscroll2->GetCapacity()) + start, this->engines[side].Length()); /* Do the actual drawing */ DrawEngineList((VehicleType)this->window_number, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, @@ -453,10 +458,10 @@ public: uint i; byte click_side; if (widget == RVW_WIDGET_LEFT_MATRIX) { - i = this->vscroll.GetScrolledRowFromWidget(pt.y, this, RVW_WIDGET_LEFT_MATRIX); + i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, RVW_WIDGET_LEFT_MATRIX); click_side = 0; } else { - i = this->vscroll2.GetScrolledRowFromWidget(pt.y, this, RVW_WIDGET_RIGHT_MATRIX); + i = this->vscroll2->GetScrolledRowFromWidget(pt.y, this, RVW_WIDGET_RIGHT_MATRIX); click_side = 1; } size_t engine_count = this->engines[click_side].Length(); @@ -480,8 +485,8 @@ public: if (temp == sel_railtype) return; // we didn't select a new one. No need to change anything sel_railtype = temp; /* Reset scrollbar positions */ - this->vscroll.SetPosition(0); - this->vscroll2.SetPosition(0); + this->vscroll->SetPosition(0); + this->vscroll2->SetPosition(0); /* Rebuild the lists */ this->engines[0].ForceRebuild(); this->engines[1].ForceRebuild(); @@ -491,11 +496,11 @@ public: virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, RVW_WIDGET_LEFT_MATRIX); - this->vscroll2.SetCapacityFromWidget(this, RVW_WIDGET_RIGHT_MATRIX); + this->vscroll->SetCapacityFromWidget(this, RVW_WIDGET_LEFT_MATRIX); + this->vscroll2->SetCapacityFromWidget(this, RVW_WIDGET_RIGHT_MATRIX); this->GetWidget(RVW_WIDGET_LEFT_MATRIX)->widget_data = - this->GetWidget(RVW_WIDGET_RIGHT_MATRIX)->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->GetWidget(RVW_WIDGET_RIGHT_MATRIX)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } virtual void OnInvalidateData(int data) diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -80,6 +80,7 @@ private: uint32 type; GUIBridgeList *bridges; int bridgetext_offset; ///< Horizontal offset of the text describing the bridge properties in #BBSW_BRIDGE_LIST relative to the left edge. + Scrollbar *vscroll; /** Sort the bridges by their index */ static int CDECL BridgeIndexSorter(const BuildBridgeData *a, const BuildBridgeData *b) @@ -131,6 +132,7 @@ public: bridges(bl) { this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(BBSW_SCROLLBAR); /* Change the data, or the caption of the gui. Set it to road or rail, accordingly. */ this->GetWidget(BBSW_CAPTION)->widget_data = (GB(this->type, 15, 2) == TRANSPORT_ROAD) ? STR_SELECT_ROAD_BRIDGE_CAPTION : STR_SELECT_RAIL_BRIDGE_CAPTION; this->FinishInitNested(desc, GB(br_type, 15, 2)); // Initializes 'this->bridgetext_offset'. @@ -141,14 +143,14 @@ public: this->bridges->NeedResort(); this->SortBridgeList(); - this->vscroll.SetCount(bl->Length()); - if (this->last_size < this->vscroll.GetCapacity()) this->last_size = this->vscroll.GetCapacity(); - if (this->last_size > this->vscroll.GetCount()) this->last_size = this->vscroll.GetCount(); + this->vscroll->SetCount(bl->Length()); + if (this->last_size < this->vscroll->GetCapacity()) this->last_size = this->vscroll->GetCapacity(); + if (this->last_size > this->vscroll->GetCount()) this->last_size = this->vscroll->GetCount(); /* Resize the bridge selection window if we used a bigger one the last time. */ - if (this->last_size > this->vscroll.GetCapacity()) { - ResizeWindow(this, 0, (this->last_size - this->vscroll.GetCapacity()) * this->resize.step_height); + if (this->last_size > this->vscroll->GetCapacity()) { + ResizeWindow(this, 0, (this->last_size - this->vscroll->GetCapacity()) * this->resize.step_height); } - this->GetWidget(BBSW_BRIDGE_LIST)->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->GetWidget(BBSW_BRIDGE_LIST)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } ~BuildBridgeWindow() @@ -216,7 +218,7 @@ public: case BBSW_BRIDGE_LIST: { uint y = r.top; - for (int i = this->vscroll.GetPosition(); this->vscroll.IsVisible(i) && i < (int)this->bridges->Length(); i++) { + for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < (int)this->bridges->Length(); i++) { const BridgeSpec *b = this->bridges->Get(i)->spec; SetDParam(2, this->bridges->Get(i)->cost); @@ -249,7 +251,7 @@ public: switch (widget) { default: break; case BBSW_BRIDGE_LIST: { - uint i = this->vscroll.GetScrolledRowFromWidget(pt.y, this, BBSW_BRIDGE_LIST); + uint i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, BBSW_BRIDGE_LIST); if (i < this->bridges->Length()) { this->BuildBridge(i); delete this; @@ -279,10 +281,10 @@ public: virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, BBSW_BRIDGE_LIST); - this->GetWidget(BBSW_BRIDGE_LIST)->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacityFromWidget(this, BBSW_BRIDGE_LIST); + this->GetWidget(BBSW_BRIDGE_LIST)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); - this->last_size = max(this->vscroll.GetCapacity(), this->last_size); + this->last_size = max(this->vscroll->GetCapacity(), this->last_size); } }; diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -779,6 +779,7 @@ struct BuildVehicleWindow : Window { StringID cargo_filter_texts[NUM_CARGO + 3]; ///< Texts for filter_cargo, terminated by INVALID_STRING_ID byte cargo_filter_criteria; ///< Selected cargo filter int details_height; ///< Minimal needed height of the details panels (found so far). + Scrollbar *vscroll; BuildVehicleWindow(const WindowDesc *desc, TileIndex tile, VehicleType type) : Window() { @@ -806,6 +807,8 @@ struct BuildVehicleWindow : Window { this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(BUILD_VEHICLE_WIDGET_SCROLLBAR); + /* If we are just viewing the list of vehicles, we do not need the Build button. * So we just hide it, and enlarge the Rename buton by the now vacant place. */ if (this->listview_mode) this->GetWidget(BUILD_VEHICLE_WIDGET_BUILD_SEL)->SetDisplayedPlane(SZSP_NONE); @@ -1056,7 +1059,7 @@ struct BuildVehicleWindow : Window { break; case BUILD_VEHICLE_WIDGET_LIST: { - uint i = this->vscroll.GetScrolledRowFromWidget(pt.y, this, BUILD_VEHICLE_WIDGET_LIST); + uint i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, BUILD_VEHICLE_WIDGET_LIST); size_t num_items = this->eng_list.Length(); this->sel_engine = (i < num_items) ? this->eng_list[i] : INVALID_ENGINE; this->SetDirty(); @@ -1152,7 +1155,7 @@ struct BuildVehicleWindow : Window { { switch (widget) { case BUILD_VEHICLE_WIDGET_LIST: - DrawEngineList(this->vehicle_type, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, &this->eng_list, this->vscroll.GetPosition(), min(this->vscroll.GetPosition() + this->vscroll.GetCapacity(), this->eng_list.Length()), this->sel_engine, false, DEFAULT_GROUP); + DrawEngineList(this->vehicle_type, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, &this->eng_list, this->vscroll->GetPosition(), min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->eng_list.Length()), this->sel_engine, false, DEFAULT_GROUP); break; case BUILD_VEHICLE_WIDGET_SORT_ASSENDING_DESCENDING: @@ -1164,7 +1167,7 @@ struct BuildVehicleWindow : Window { virtual void OnPaint() { this->GenerateBuildList(); - this->vscroll.SetCount(this->eng_list.Length()); + this->vscroll->SetCount(this->eng_list.Length()); this->DrawWidgets(); @@ -1219,8 +1222,8 @@ struct BuildVehicleWindow : Window { virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, BUILD_VEHICLE_WIDGET_LIST); - this->GetWidget(BUILD_VEHICLE_WIDGET_LIST)->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacityFromWidget(this, BUILD_VEHICLE_WIDGET_LIST); + this->GetWidget(BUILD_VEHICLE_WIDGET_LIST)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } }; diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -222,6 +222,8 @@ struct DepotWindow : Window { bool generate_list; VehicleList vehicle_list; VehicleList wagon_list; + Scrollbar *hscroll; ///< Only for trains. + Scrollbar *vscroll; DepotWindow(const WindowDesc *desc, TileIndex tile, VehicleType type) : Window() { @@ -233,6 +235,8 @@ struct DepotWindow : Window { this->type = type; this->CreateNestedTree(desc); + this->hscroll = (this->type == VEH_TRAIN ? this->GetScrollbar(DEPOT_WIDGET_H_SCROLL) : NULL); + this->vscroll = this->GetScrollbar(DEPOT_WIDGET_V_SCROLL); /* Don't show 'rename button' of aircraft hangar */ this->GetWidget(DEPOT_WIDGET_SHOW_RENAME)->SetDisplayedPlane(type == VEH_AIRCRAFT ? SZSP_NONE : 0); this->SetupWidgetData(type); @@ -271,7 +275,7 @@ struct DepotWindow : Window { uint x_space = free_wagon ? TRAININFO_DEFAULT_VEHICLE_WIDTH : 0; DrawTrainImage(u, image_left + (rtl ? 0 : x_space), image_right - (rtl ? x_space : 0), sprite_y - 1, - this->sel, free_wagon ? 0 : this->hscroll.GetPosition(), this->vehicle_over); + this->sel, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over); /* Number of wagons relative to a standard length wagon (rounded up) */ SetDParam(0, CeilDiv(u->tcache.cached_total_length, 8)); @@ -325,7 +329,7 @@ struct DepotWindow : Window { uint16 rows_in_display = GB(mat_data, MAT_ROW_START, MAT_ROW_BITS); uint16 boxes_in_each_row = GB(mat_data, MAT_COL_START, MAT_COL_BITS); - uint16 num = this->vscroll.GetPosition() * boxes_in_each_row; + uint16 num = this->vscroll->GetPosition() * boxes_in_each_row; int maxval = min(this->vehicle_list.Length(), num + (rows_in_display * boxes_in_each_row)); int y; for (y = r.top + 1; num < maxval; y += this->resize.step_height) { // Draw the rows @@ -341,7 +345,7 @@ struct DepotWindow : Window { } } - maxval = min(this->vehicle_list.Length() + this->wagon_list.Length(), (this->vscroll.GetPosition() * boxes_in_each_row) + (rows_in_display * boxes_in_each_row)); + maxval = min(this->vehicle_list.Length() + this->wagon_list.Length(), (this->vscroll->GetPosition() * boxes_in_each_row) + (rows_in_display * boxes_in_each_row)); /* draw the train wagons, that do not have an engine in front */ for (; num < maxval; num++, y += this->resize.step_height) { @@ -384,15 +388,15 @@ struct DepotWindow : Window { } else { xt = x / this->resize.step_width; xm = x % this->resize.step_width; - if (xt >= this->hscroll.GetCapacity()) return MODE_ERROR; + if (xt >= this->hscroll->GetCapacity()) return MODE_ERROR; } ym = y % this->resize.step_height; uint row = y / this->resize.step_height; - if (row >= this->vscroll.GetCapacity()) return MODE_ERROR; + if (row >= this->vscroll->GetCapacity()) return MODE_ERROR; uint boxes_in_each_row = GB(matrix_widget->widget_data, MAT_COL_START, MAT_COL_BITS); - uint pos = ((row + this->vscroll.GetPosition()) * boxes_in_each_row) + xt; + uint pos = ((row + this->vscroll->GetPosition()) * boxes_in_each_row) + xt; if (this->vehicle_list.Length() + this->wagon_list.Length() <= pos) { /* Clicking on 'line' / 'block' without a vehicle */ @@ -410,7 +414,7 @@ struct DepotWindow : Window { if (this->vehicle_list.Length() > pos) { *veh = this->vehicle_list[pos]; /* Skip vehicles that are scrolled off the list */ - x += this->hscroll.GetPosition(); + x += this->hscroll->GetPosition(); } else { pos -= this->vehicle_list.Length(); *veh = this->wagon_list[pos]; @@ -693,10 +697,10 @@ struct DepotWindow : Window { max_width = max(max_width, width); } /* Always have 1 empty row, so people can change the setting of the train */ - this->vscroll.SetCount(this->vehicle_list.Length() + this->wagon_list.Length() + 1); - this->hscroll.SetCount(max_width); + this->vscroll->SetCount(this->vehicle_list.Length() + this->wagon_list.Length() + 1); + this->hscroll->SetCount(max_width); } else { - this->vscroll.SetCount(CeilDiv(this->vehicle_list.Length(), this->hscroll.GetCapacity())); + this->vscroll->SetCount(CeilDiv(this->vehicle_list.Length(), this->hscroll->GetCapacity())); } /* Setup disabled buttons. */ @@ -1005,13 +1009,13 @@ struct DepotWindow : Window { virtual void OnResize() { NWidgetCore *nwi = this->GetWidget(DEPOT_WIDGET_MATRIX); - this->vscroll.SetCapacityFromWidget(this, DEPOT_WIDGET_MATRIX); + this->vscroll->SetCapacityFromWidget(this, DEPOT_WIDGET_MATRIX); if (this->type == VEH_TRAIN) { - this->hscroll.SetCapacity(nwi->current_x - this->header_width - this->count_width); - nwi->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->hscroll->SetCapacity(nwi->current_x - this->header_width - this->count_width); + nwi->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } else { - this->hscroll.SetCapacityFromWidget(this, DEPOT_WIDGET_MATRIX); - nwi->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (this->hscroll.GetCapacity() << MAT_COL_START); + this->hscroll->SetCapacityFromWidget(this, DEPOT_WIDGET_MATRIX); + nwi->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (this->hscroll->GetCapacity() << MAT_COL_START); } } diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -240,6 +240,7 @@ struct SaveLoadWindow : public QueryStri private: FiosItem o_dir; const FiosItem *selected; + Scrollbar *vscroll; public: void GenerateFileName() @@ -269,9 +270,10 @@ public: this->afilter = CS_ALPHANUMERAL; InitializeTextBuffer(&this->text, this->edit_str_buf, this->edit_str_size, 240); - this->CreateNestedTree(desc); + this->CreateNestedTree(desc, true); if (mode == SLD_LOAD_GAME) this->GetWidget(SLWW_CONTENT_DOWNLOAD_SEL)->SetDisplayedPlane(SZSP_HORIZONTAL); this->GetWidget(SLWW_WINDOWTITLE)->widget_data = saveload_captions[mode]; + this->vscroll = this->GetScrollbar(SLWW_SCROLLBAR); this->FinishInitNested(desc, 0); @@ -353,7 +355,7 @@ public: GfxFillRect(r.left + 1, r.top + 1, r.right, r.bottom, 0xD7); uint y = r.top + WD_FRAMERECT_TOP; - for (uint pos = this->vscroll.GetPosition(); pos < _fios_items.Length(); pos++) { + for (uint pos = this->vscroll->GetPosition(); pos < _fios_items.Length(); pos++) { const FiosItem *item = _fios_items.Get(pos); if (item == this->selected) { @@ -361,7 +363,7 @@ public: } DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, item->title, _fios_colours[item->type]); y += this->resize.step_height; - if (y >= this->vscroll.GetCapacity() * this->resize.step_height + r.top + WD_FRAMERECT_TOP) break; + if (y >= this->vscroll->GetCapacity() * this->resize.step_height + r.top + WD_FRAMERECT_TOP) break; } break; } @@ -483,7 +485,7 @@ public: MakeSortedSaveGameList(); } - this->vscroll.SetCount(_fios_items.Length()); + this->vscroll->SetCount(_fios_items.Length()); this->DrawWidgets(); if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) { @@ -534,7 +536,7 @@ public: break; case SLWW_DRIVES_DIRECTORIES_LIST: { // Click the listbox - int y = this->vscroll.GetScrolledRowFromWidget(pt.y, this, SLWW_DRIVES_DIRECTORIES_LIST, WD_FRAMERECT_TOP); + int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, SLWW_DRIVES_DIRECTORIES_LIST, WD_FRAMERECT_TOP); if (y == INT_MAX) return; const FiosItem *file = _fios_items.Get(y); @@ -647,7 +649,7 @@ public: virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, SLWW_DRIVES_DIRECTORIES_LIST); + this->vscroll->SetCapacityFromWidget(this, SLWW_DRIVES_DIRECTORIES_LIST); } virtual void OnInvalidateData(int data) diff --git a/src/group_gui.cpp b/src/group_gui.cpp --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -119,6 +119,7 @@ private: GroupID group_rename; ///< Group being renamed, INVALID_GROUP if none GUIGroupList groups; ///< List of groups uint tiny_step_height; ///< Step height for the group list + Scrollbar *vscroll2; /** * (Re)Build the group list. @@ -170,6 +171,9 @@ public: { this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(GRP_WIDGET_LIST_VEHICLE_SCROLLBAR); + this->vscroll2 = this->GetScrollbar(GRP_WIDGET_LIST_GROUP_SCROLLBAR); + this->vehicle_type = (VehicleType)GB(window_number, 11, 5); switch (this->vehicle_type) { default: NOT_REACHED(); @@ -305,8 +309,8 @@ public: this->BuildGroupList(owner); this->groups.Sort(&GroupNameSorter); - this->vscroll2.SetCount(this->groups.Length()); - this->vscroll.SetCount(this->vehicles.Length()); + this->vscroll2->SetCount(this->groups.Length()); + this->vscroll->SetCount(this->vehicles.Length()); /* The drop down menu is out, *but* it may not be used, retract it. */ if (this->vehicles.Length() == 0 && this->IsWidgetLowered(GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN)) { @@ -365,8 +369,8 @@ public: case GRP_WIDGET_LIST_GROUP: { int y1 = r.top + WD_FRAMERECT_TOP + 1; - int max = min(this->vscroll2.GetPosition() + this->vscroll2.GetCapacity(), this->groups.Length()); - for (int i = this->vscroll2.GetPosition(); i < max; ++i) { + int max = min(this->vscroll2->GetPosition() + this->vscroll2->GetCapacity(), this->groups.Length()); + for (int i = this->vscroll2->GetPosition(); i < max; ++i) { const Group *g = this->groups[i]; assert(g->owner == this->owner); @@ -423,7 +427,7 @@ public: break; case GRP_WIDGET_LIST_GROUP: { // Matrix Group - uint id_g = this->vscroll2.GetScrolledRowFromWidget(pt.y, this, GRP_WIDGET_LIST_GROUP, 0, this->tiny_step_height); + uint id_g = this->vscroll2->GetScrolledRowFromWidget(pt.y, this, GRP_WIDGET_LIST_GROUP, 0, this->tiny_step_height); if (id_g >= this->groups.Length()) return; this->group_sel = this->groups[id_g]->index; @@ -434,7 +438,7 @@ public: } case GRP_WIDGET_LIST_VEHICLE: { // Matrix Vehicle - uint id_v = this->vscroll.GetScrolledRowFromWidget(pt.y, this, GRP_WIDGET_LIST_VEHICLE); + uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, GRP_WIDGET_LIST_VEHICLE); if (id_v >= this->vehicles.Length()) return; // click out of list bound const Vehicle *v = this->vehicles[id_v]; @@ -512,7 +516,7 @@ public: this->vehicle_sel = INVALID_VEHICLE; this->SetDirty(); - uint id_g = this->vscroll2.GetScrolledRowFromWidget(pt.y, this, GRP_WIDGET_LIST_GROUP, 0, this->tiny_step_height); + uint id_g = this->vscroll2->GetScrolledRowFromWidget(pt.y, this, GRP_WIDGET_LIST_GROUP, 0, this->tiny_step_height); if (id_g >= this->groups.Length()) return; DoCommandP(0, this->groups[id_g]->index, vindex, CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE)); @@ -524,7 +528,7 @@ public: this->vehicle_sel = INVALID_VEHICLE; this->SetDirty(); - uint id_v = this->vscroll.GetScrolledRowFromWidget(pt.y, this, GRP_WIDGET_LIST_VEHICLE); + uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, GRP_WIDGET_LIST_VEHICLE); if (id_v >= this->vehicles.Length()) return; // click out of list bound const Vehicle *v = this->vehicles[id_v]; @@ -546,12 +550,12 @@ public: virtual void OnResize() { NWidgetCore *nwi = this->GetWidget(GRP_WIDGET_LIST_GROUP); - this->vscroll2.SetCapacity(nwi->current_y / this->tiny_step_height); - nwi->widget_data = (this->vscroll2.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll2->SetCapacity(nwi->current_y / this->tiny_step_height); + nwi->widget_data = (this->vscroll2->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); nwi = this->GetWidget(GRP_WIDGET_LIST_VEHICLE); - this->vscroll.SetCapacityFromWidget(this, GRP_WIDGET_LIST_VEHICLE); - nwi->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacityFromWidget(this, GRP_WIDGET_LIST_VEHICLE); + nwi->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } virtual void OnDropdownSelect(int widget, int index) diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -209,6 +209,7 @@ class BuildIndustryWindow : public Windo uint16 count; ///< How many industries are loaded IndustryType index[NUM_INDUSTRYTYPES + 1]; ///< Type of industry, in the order it was loaded bool enabled[NUM_INDUSTRYTYPES + 1]; ///< availability state, coming from CBID_INDUSTRY_AVAILABLE (if ever) + Scrollbar *vscroll; /** The offset for the text in the matrix. */ static const int MATRIX_TEXT_OFFSET = 17; @@ -259,7 +260,7 @@ class BuildIndustryWindow : public Windo this->selected_type = this->index[0]; } - this->vscroll.SetCount(this->count); + this->vscroll->SetCount(this->count); } /** Update status of the fund and display-chain widgets. */ @@ -279,7 +280,10 @@ public: this->callback_timer = DAY_TICKS; - this->InitNested(&_build_industry_desc, 0); + this->CreateNestedTree(&_build_industry_desc); + this->vscroll = this->GetScrollbar(DPIW_SCROLLBAR); + this->FinishInitNested(&_build_industry_desc, 0); + this->SetButtons(); } @@ -381,16 +385,16 @@ public: { switch (widget) { case DPIW_MATRIX_WIDGET: - for (byte i = 0; i < this->vscroll.GetCapacity() && i + this->vscroll.GetPosition() < this->count; i++) { + for (byte i = 0; i < this->vscroll->GetCapacity() && i + this->vscroll->GetPosition() < this->count; i++) { int x = r.left + WD_MATRIX_LEFT; int y = r.top + WD_MATRIX_TOP + i * this->resize.step_height; - bool selected = this->selected_index == i + this->vscroll.GetPosition(); + bool selected = this->selected_index == i + this->vscroll->GetPosition(); - if (this->index[i + this->vscroll.GetPosition()] == INVALID_INDUSTRYTYPE) { + if (this->index[i + this->vscroll->GetPosition()] == INVALID_INDUSTRYTYPE) { DrawString(x + MATRIX_TEXT_OFFSET, r.right - WD_MATRIX_RIGHT, y, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES, selected ? TC_WHITE : TC_ORANGE); continue; } - const IndustrySpec *indsp = GetIndustrySpec(this->index[i + this->vscroll.GetPosition()]); + const IndustrySpec *indsp = GetIndustrySpec(this->index[i + this->vscroll->GetPosition()]); /* Draw the name of the industry in white is selected, otherwise, in orange */ DrawString(x + MATRIX_TEXT_OFFSET, r.right - WD_MATRIX_RIGHT, y, indsp->name, selected ? TC_WHITE : TC_ORANGE); @@ -476,7 +480,7 @@ public: { switch (widget) { case DPIW_MATRIX_WIDGET: { - int y = this->vscroll.GetScrolledRowFromWidget(pt.y, this, DPIW_MATRIX_WIDGET); + int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, DPIW_MATRIX_WIDGET); if (y < this->count) { // Is it within the boundaries of available data? this->selected_index = y; this->selected_type = this->index[y]; @@ -529,8 +533,8 @@ public: virtual void OnResize() { /* Adjust the number of items in the matrix depending of the resize */ - this->vscroll.SetCapacityFromWidget(this, DPIW_MATRIX_WIDGET); - this->GetWidget(DPIW_MATRIX_WIDGET)->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacityFromWidget(this, DPIW_MATRIX_WIDGET); + this->GetWidget(DPIW_MATRIX_WIDGET)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } virtual void OnPlaceObject(Point pt, TileIndex tile) @@ -977,6 +981,7 @@ protected: static GUIIndustryList::SortFunction * const sorter_funcs[]; GUIIndustryList industries; + Scrollbar *vscroll; /** (Re)Build industries list */ void BuildSortIndustriesList() @@ -991,7 +996,7 @@ protected: this->industries.Compact(); this->industries.RebuildDone(); - this->vscroll.SetCount(this->industries.Length()); // Update scrollbar as well. + this->vscroll->SetCount(this->industries.Length()); // Update scrollbar as well. } if (!this->industries.Sort()) return; @@ -1117,12 +1122,15 @@ protected: public: IndustryDirectoryWindow(const WindowDesc *desc, WindowNumber number) : Window() { + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(IDW_SCROLLBAR); + this->industries.SetListing(this->last_sorting); this->industries.SetSortFuncs(IndustryDirectoryWindow::sorter_funcs); this->industries.ForceRebuild(); this->BuildSortIndustriesList(); - this->InitNested(desc, 0); + this->FinishInitNested(desc, 0); } ~IndustryDirectoryWindow() @@ -1154,11 +1162,11 @@ public: DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_DIRECTORY_NONE); break; } - for (uint i = this->vscroll.GetPosition(); i < this->industries.Length(); i++) { + for (uint i = this->vscroll->GetPosition(); i < this->industries.Length(); i++) { DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, this->GetIndustryString(this->industries[i])); y += this->resize.step_height; - if (++n == this->vscroll.GetCapacity()) break; // max number of industries in 1 window + if (++n == this->vscroll->GetCapacity()) break; // max number of industries in 1 window } break; } @@ -1215,7 +1223,7 @@ public: break; case IDW_INDUSTRY_LIST: { - uint p = this->vscroll.GetScrolledRowFromWidget(pt.y, this, IDW_INDUSTRY_LIST, WD_FRAMERECT_TOP); + uint p = this->vscroll->GetScrolledRowFromWidget(pt.y, this, IDW_INDUSTRY_LIST, WD_FRAMERECT_TOP); if (p < this->industries.Length()) { if (_ctrl_pressed) { ShowExtraViewPortWindow(this->industries[p]->location.tile); @@ -1238,7 +1246,7 @@ public: virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, IDW_INDUSTRY_LIST); + this->vscroll->SetCapacityFromWidget(this, IDW_INDUSTRY_LIST); } virtual void OnHundredthTick() @@ -1929,10 +1937,14 @@ struct IndustryCargoesWindow : public Wi Fields fields; ///< Fields to display in the #ICW_PANEL. uint ind_cargo; ///< If less than #NUM_INDUSTRYTYPES, an industry type, else a cargo id + NUM_INDUSTRYTYPES. + Scrollbar *vscroll; + IndustryCargoesWindow(int id) : Window() { this->OnInit(); - this->InitNested(&_industry_cargoes_desc, 0); + this->CreateNestedTree(&_industry_cargoes_desc); + this->vscroll = this->GetScrollbar(ICW_SCROLLBAR); + this->FinishInitNested(&_industry_cargoes_desc, 0); this->OnInvalidateData(id); } @@ -2207,7 +2219,7 @@ struct IndustryCargoesWindow : public Wi this->ShortenCargoColumn(1, 1, num_indrows); this->ShortenCargoColumn(3, 1, num_indrows); const NWidgetBase *nwp = this->GetWidget(ICW_PANEL); - this->vscroll.SetCount(CeilDiv(WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM + CargoesField::small_height + num_indrows * CargoesField::normal_height, nwp->resize_y)); + this->vscroll->SetCount(CeilDiv(WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM + CargoesField::small_height + num_indrows * CargoesField::normal_height, nwp->resize_y)); this->SetDirty(); this->NotifySmallmap(); } @@ -2275,7 +2287,7 @@ struct IndustryCargoesWindow : public Wi this->ShortenCargoColumn(1, 1, num_indrows); const NWidgetBase *nwp = this->GetWidget(ICW_PANEL); - this->vscroll.SetCount(CeilDiv(WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM + CargoesField::small_height + num_indrows * CargoesField::normal_height, nwp->resize_y)); + this->vscroll->SetCount(CeilDiv(WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM + CargoesField::small_height + num_indrows * CargoesField::normal_height, nwp->resize_y)); this->SetDirty(); this->NotifySmallmap(); } @@ -2316,7 +2328,7 @@ struct IndustryCargoesWindow : public Wi int last_column = (this->ind_cargo < NUM_INDUSTRYTYPES) ? 4 : 2; const NWidgetBase *nwp = this->GetWidget(ICW_PANEL); - int vpos = -this->vscroll.GetPosition() * nwp->resize_y; + int vpos = -this->vscroll->GetPosition() * nwp->resize_y; for (uint i = 0; i < this->fields.Length(); i++) { int row_height = (i == 0) ? CargoesField::small_height : CargoesField::normal_height; if (vpos + row_height >= 0) { @@ -2355,7 +2367,7 @@ struct IndustryCargoesWindow : public Wi pt.x -= nw->pos_x; pt.y -= nw->pos_y; - int vpos = WD_FRAMERECT_TOP + CargoesField::small_height - this->vscroll.GetPosition() * nw->resize_y; + int vpos = WD_FRAMERECT_TOP + CargoesField::small_height - this->vscroll->GetPosition() * nw->resize_y; if (pt.y < vpos) return false; int row = (pt.y - vpos) / CargoesField::normal_height; // row is relative to row 1. @@ -2480,7 +2492,7 @@ struct IndustryCargoesWindow : public Wi virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, ICW_PANEL); + this->vscroll->SetCapacityFromWidget(this, ICW_PANEL); } }; diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -239,6 +239,7 @@ class NetworkContentListWindow : public const ContentInfo *selected; ///< The selected content info int list_pos; ///< Our position in the list uint filesize_sum; ///< The sum of all selected file sizes + Scrollbar *vscroll; /** * (Re)build the network game list as its amount has changed because @@ -260,7 +261,7 @@ class NetworkContentListWindow : public this->content.RebuildDone(); this->SortContentList(); - this->vscroll.SetCount(this->content.Length()); // Update the scrollbar + this->vscroll->SetCount(this->content.Length()); // Update the scrollbar this->ScrollToSelected(); } @@ -338,7 +339,7 @@ class NetworkContentListWindow : public { if (this->selected == NULL) return; - this->vscroll.ScrollTowards(this->list_pos); + this->vscroll->ScrollTowards(this->list_pos); } public: @@ -351,7 +352,9 @@ public: selected(NULL), list_pos(0) { - this->InitNested(desc, 1); + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(NCLWW_SCROLLBAR); + this->FinishInitNested(desc, 1); this->GetWidget(NCLWW_SEL_ALL_UPDATE)->SetDisplayedPlane(select_all); @@ -448,7 +451,7 @@ public: int sprite_y_offset = WD_MATRIX_TOP + (FONT_HEIGHT_NORMAL - 10) / 2; uint y = r.top; int cnt = 0; - for (ConstContentIterator iter = this->content.Get(this->vscroll.GetPosition()); iter != this->content.End() && cnt < this->vscroll.GetCapacity(); iter++, cnt++) { + for (ConstContentIterator iter = this->content.Get(this->vscroll->GetPosition()); iter != this->content.End() && cnt < this->vscroll->GetCapacity(); iter++, cnt++) { const ContentInfo *ci = *iter; if (ci == this->selected) GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->resize.step_height - 1, 10); @@ -590,7 +593,7 @@ public: { switch (widget) { case NCLWW_MATRIX: { - uint id_v = this->vscroll.GetScrolledRowFromWidget(pt.y, this, NCLWW_MATRIX); + uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, NCLWW_MATRIX); if (id_v >= this->content.Length()) return; // click out of bounds this->selected = *this->content.Get(id_v); @@ -664,11 +667,11 @@ public: break; case WKC_PAGEUP: /* scroll up a page */ - this->list_pos = (this->list_pos < this->vscroll.GetCapacity()) ? 0 : this->list_pos - this->vscroll.GetCapacity(); + this->list_pos = (this->list_pos < this->vscroll->GetCapacity()) ? 0 : this->list_pos - this->vscroll->GetCapacity(); break; case WKC_PAGEDOWN: /* scroll down a page */ - this->list_pos = min(this->list_pos + this->vscroll.GetCapacity(), (int)this->content.Length() - 1); + this->list_pos = min(this->list_pos + this->vscroll->GetCapacity(), (int)this->content.Length() - 1); break; case WKC_HOME: /* jump to beginning */ @@ -723,8 +726,8 @@ public: virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, NCLWW_MATRIX); - this->GetWidget(NCLWW_MATRIX)->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacityFromWidget(this, NCLWW_MATRIX); + this->GetWidget(NCLWW_MATRIX)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } virtual void OnReceiveContentInfo(const ContentInfo *rci) diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -254,6 +254,7 @@ protected: NetworkGameList *last_joined; ///< the last joined server GUIGameServerList servers; ///< list with game servers. ServerListPosition list_pos; ///< position of the selected server + Scrollbar *vscroll; /** * (Re)build the network game list as its amount has changed because @@ -272,7 +273,7 @@ protected: this->servers.Compact(); this->servers.RebuildDone(); - this->vscroll.SetCount(this->servers.Length()); + this->vscroll->SetCount(this->servers.Length()); } /** Sort servers by name. */ @@ -443,13 +444,15 @@ protected: void ScrollToSelectedServer() { if (this->list_pos == SLP_INVALID) return; // no server selected - this->vscroll.ScrollTowards(this->list_pos); + this->vscroll->ScrollTowards(this->list_pos); } public: NetworkGameWindow(const WindowDesc *desc) : QueryStringBaseWindow(NETWORK_CLIENT_NAME_LENGTH) { - this->InitNested(desc, 0); + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(NGWW_SCROLLBAR); + this->FinishInitNested(desc, 0); ttd_strlcpy(this->edit_str_buf, _settings_client.network.client_name, this->edit_str_size); this->afilter = CS_ALPHANUMERAL; @@ -539,9 +542,9 @@ public: case NGWW_MATRIX: { uint16 y = r.top + WD_MATRIX_TOP; - const int max = min(this->vscroll.GetPosition() + this->vscroll.GetCapacity(), (int)this->servers.Length()); + const int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (int)this->servers.Length()); - for (int i = this->vscroll.GetPosition(); i < max; ++i) { + for (int i = this->vscroll->GetPosition(); i < max; ++i) { const NetworkGameList *ngl = this->servers[i]; this->DrawServerLine(ngl, y, ngl == this->server); y += this->resize.step_height; @@ -696,7 +699,7 @@ public: break; case NGWW_MATRIX: { // Matrix to show networkgames - uint id_v = this->vscroll.GetScrolledRowFromWidget(pt.y, this, NGWW_MATRIX); + uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, NGWW_MATRIX); this->server = (id_v < this->servers.Length()) ? this->servers[id_v] : NULL; this->list_pos = (server == NULL) ? SLP_INVALID : id_v; this->SetDirty(); @@ -843,12 +846,12 @@ public: case WKC_PAGEUP: /* scroll up a page */ if (this->server == NULL) return ES_HANDLED; - this->list_pos = (this->list_pos < this->vscroll.GetCapacity()) ? 0 : this->list_pos - this->vscroll.GetCapacity(); + this->list_pos = (this->list_pos < this->vscroll->GetCapacity()) ? 0 : this->list_pos - this->vscroll->GetCapacity(); break; case WKC_PAGEDOWN: /* scroll down a page */ if (this->server == NULL) return ES_HANDLED; - this->list_pos = min(this->list_pos + this->vscroll.GetCapacity(), (int)this->servers.Length() - 1); + this->list_pos = min(this->list_pos + this->vscroll->GetCapacity(), (int)this->servers.Length() - 1); break; case WKC_HOME: /* jump to beginning */ @@ -900,8 +903,8 @@ public: virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, NGWW_MATRIX); - this->GetWidget(NGWW_MATRIX)->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacityFromWidget(this, NGWW_MATRIX); + this->GetWidget(NGWW_MATRIX)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } }; @@ -1055,17 +1058,20 @@ struct NetworkStartServerWindow : public byte field; ///< Selected text-field FiosItem *map; ///< Selected map byte widget_id; ///< The widget that has the pop-up input menu + Scrollbar *vscroll; NetworkStartServerWindow(const WindowDesc *desc) : QueryStringBaseWindow(NETWORK_NAME_LENGTH) { this->InitNested(desc, 0); + this->vscroll = this->GetScrollbar(NSSW_SCROLLBAR); + ttd_strlcpy(this->edit_str_buf, _settings_client.network.server_name, this->edit_str_size); _saveload_mode = SLD_NEW_GAME; BuildFileList(); - this->vscroll.SetCapacity(14); - this->vscroll.SetCount(_fios_items.Length() + 1); + this->vscroll->SetCapacity(14); + this->vscroll->SetCount(_fios_items.Length() + 1); this->afilter = CS_ALPHANUMERAL; InitializeTextBuffer(&this->text, this->edit_str_buf, this->edit_str_size, 160); @@ -1143,7 +1149,7 @@ struct NetworkStartServerWindow : public /* draw list of maps */ GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, 0xD7); // black background of maps list - for (uint pos = this->vscroll.GetPosition(); pos < _fios_items.Length() + 1; pos++) { + for (uint pos = this->vscroll->GetPosition(); pos < _fios_items.Length() + 1; pos++) { const FiosItem *item = (pos == 0) ? NULL : _fios_items.Get(pos - 1); if (item == this->map) { // this->map == NULL for first item GfxFillRect(r.left + 1, y, r.right - 1, y + FONT_HEIGHT_NORMAL - 1, 155); // show highlighted item with a different colour @@ -1156,7 +1162,7 @@ struct NetworkStartServerWindow : public } y += FONT_HEIGHT_NORMAL; - if (y >= this->vscroll.GetCapacity() * FONT_HEIGHT_NORMAL + r.top) break; + if (y >= this->vscroll->GetCapacity() * FONT_HEIGHT_NORMAL + r.top) break; } } @@ -1175,8 +1181,8 @@ struct NetworkStartServerWindow : public break; case NSSW_SELMAP: { // Select map - int y = this->vscroll.GetScrolledRowFromWidget(pt.y, this, NSSW_SELMAP, WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL); - if (y >= this->vscroll.GetCount()) return; + int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, NSSW_SELMAP, WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL); + if (y >= this->vscroll->GetCount()) return; this->map = (y == 0) ? NULL : _fios_items.Get(y - 1); this->SetDirty(); @@ -1454,11 +1460,14 @@ struct NetworkLobbyWindow : public Windo CompanyID company; ///< Select company NetworkGameList *server; ///< Selected server NetworkCompanyInfo company_info[MAX_COMPANIES]; + Scrollbar *vscroll; NetworkLobbyWindow(const WindowDesc *desc, NetworkGameList *ngl) : Window(), company(INVALID_COMPANY), server(ngl) { - this->InitNested(desc, 0); + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(NLWW_SCROLLBAR); + this->FinishInitNested(desc, 0); this->OnResize(); } @@ -1525,7 +1534,7 @@ struct NetworkLobbyWindow : public Windo /* Cannot spectate if there are too many spectators */ this->SetWidgetDisabledState(NLWW_SPECTATE, gi->spectators_on >= gi->spectators_max); - this->vscroll.SetCount(gi->companies_on); + this->vscroll->SetCount(gi->companies_on); /* Draw window widgets */ this->DrawWidgets(); @@ -1544,7 +1553,7 @@ struct NetworkLobbyWindow : public Windo int y = r.top + WD_MATRIX_TOP; /* Draw company list */ - int pos = this->vscroll.GetPosition(); + int pos = this->vscroll->GetPosition(); while (pos < this->server->info.companies_on) { byte company = NetworkLobbyFindCompanyIndex(pos); bool income = false; @@ -1561,7 +1570,7 @@ struct NetworkLobbyWindow : public Windo pos++; y += this->resize.step_height; - if (pos >= this->vscroll.GetPosition() + this->vscroll.GetCapacity()) break; + if (pos >= this->vscroll->GetPosition() + this->vscroll->GetCapacity()) break; } } @@ -1636,7 +1645,7 @@ struct NetworkLobbyWindow : public Windo break; case NLWW_MATRIX: { // Company list - uint id_v = this->vscroll.GetScrolledRowFromWidget(pt.y, this, NLWW_MATRIX); + uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, NLWW_MATRIX); this->company = (id_v >= this->server->info.companies_on) ? INVALID_COMPANY : NetworkLobbyFindCompanyIndex(id_v); this->SetDirty(); @@ -1669,8 +1678,8 @@ struct NetworkLobbyWindow : public Windo virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, NLWW_MATRIX); - this->GetWidget(NLWW_MATRIX)->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacityFromWidget(this, NLWW_MATRIX); + this->GetWidget(NLWW_MATRIX)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } }; diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -251,6 +251,8 @@ struct NewGRFInspectWindow : Window { /** The currently editted parameter, to update the right one. */ byte current_edit_param; + Scrollbar *vscroll; + /** * Check whether the given variable has a parameter. * @param variable the variable to check. @@ -263,9 +265,11 @@ struct NewGRFInspectWindow : Window { NewGRFInspectWindow(const WindowDesc *desc, WindowNumber wno) : Window() { - this->InitNested(desc, wno); + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(NIW_SCROLLBAR); + this->FinishInitNested(desc, wno); - this->vscroll.SetCount(0); + this->vscroll->SetCount(0); this->SetWidgetDisabledState(NIW_PARENT, GetFeatureHelper(this->window_number)->GetParent(GetFeatureIndex(this->window_number)) == UINT32_MAX); } @@ -301,8 +305,8 @@ struct NewGRFInspectWindow : Window { vsnprintf(buf, lengthof(buf), format, va); va_end(va); - offset -= this->vscroll.GetPosition(); - if (offset < 0 || offset >= this->vscroll.GetCapacity()) return; + offset -= this->vscroll->GetPosition(); + if (offset < 0 || offset >= this->vscroll->GetCapacity()) return; ::DrawString(r.left + LEFT_OFFSET, r.right + RIGHT_OFFSET, r.top + TOP_OFFSET + (offset * this->resize.step_height), buf, TC_BLACK); } @@ -401,7 +405,7 @@ struct NewGRFInspectWindow : Window { /* Not nice and certainly a hack, but it beats duplicating * this whole function just to count the actual number of * elements. Especially because they need to be redrawn. */ - const_cast(this)->vscroll.SetCount(i); + const_cast(this)->vscroll->SetCount(i); } virtual void OnPaint() @@ -424,7 +428,7 @@ struct NewGRFInspectWindow : Window { if (nif->variables == NULL) return; /* Get the line, make sure it's within the boundaries. */ - int line = this->vscroll.GetScrolledRowFromWidget(pt.y, this, NIW_MAINPANEL, TOP_OFFSET); + int line = this->vscroll->GetScrolledRowFromWidget(pt.y, this, NIW_MAINPANEL, TOP_OFFSET); if (line == INT_MAX) return; /* Find the variable related to the line */ @@ -450,7 +454,7 @@ struct NewGRFInspectWindow : Window { virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, NIW_MAINPANEL, TOP_OFFSET + BOTTOM_OFFSET); + this->vscroll->SetCapacityFromWidget(this, NIW_MAINPANEL, TOP_OFFSET + BOTTOM_OFFSET); } }; @@ -560,10 +564,13 @@ enum SpriteAlignerWidgets { /** Window used for aligning sprites. */ struct SpriteAlignerWindow : Window { SpriteID current_sprite; ///< The currently shown sprite + Scrollbar *vscroll; SpriteAlignerWindow(const WindowDesc *desc, WindowNumber wno) : Window() { - this->InitNested(desc, wno); + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(SAW_SCROLLBAR); + this->FinishInitNested(desc, wno); /* Oh yes, we assume there is at least one normal sprite! */ while (GetSpriteType(this->current_sprite) != ST_NORMAL) this->current_sprite++; @@ -628,10 +635,10 @@ struct SpriteAlignerWindow : Window { int step_size = nwid->resize_y; SmallVector &list = _newgrf_debug_sprite_picker.sprites; - int max = min(this->vscroll.GetPosition() + this->vscroll.GetCapacity(), list.Length()); + int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), list.Length()); int y = r.top + WD_FRAMERECT_TOP; - for (int i = this->vscroll.GetPosition(); i < max; i++) { + for (int i = this->vscroll->GetPosition(); i < max; i++) { SetDParam(0, list[i]); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE); y += step_size; @@ -677,7 +684,7 @@ struct SpriteAlignerWindow : Window { const NWidgetBase *nwid = this->GetWidget(widget); int step_size = nwid->resize_y; - uint i = this->vscroll.GetPosition() + (pt.y - nwid->pos_y) / step_size; + uint i = this->vscroll->GetPosition() + (pt.y - nwid->pos_y) / step_size; if (i < _newgrf_debug_sprite_picker.sprites.Length()) { SpriteID spr = _newgrf_debug_sprite_picker.sprites[i]; if (GetSpriteType(spr) == ST_NORMAL) this->current_sprite = spr; @@ -735,14 +742,14 @@ struct SpriteAlignerWindow : Window { if (data == 1) { /* Sprite picker finished */ this->RaiseWidget(SAW_PICKER); - this->vscroll.SetCount(_newgrf_debug_sprite_picker.sprites.Length()); + this->vscroll->SetCount(_newgrf_debug_sprite_picker.sprites.Length()); } } virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, SAW_LIST); - this->GetWidget(SAW_LIST)->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacityFromWidget(this, SAW_LIST); + this->GetWidget(SAW_LIST)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } }; diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -142,6 +142,7 @@ struct NewGRFParametersWindow : public W int timeout; ///< How long before we unpress the last-pressed button? uint clicked_row; ///< The selected parameter int line_height; ///< Height of a row in the matrix widget. + Scrollbar *vscroll; NewGRFParametersWindow(const WindowDesc *desc, GRFConfig *c) : Window(), grf_config(c), @@ -149,9 +150,10 @@ struct NewGRFParametersWindow : public W timeout(0), clicked_row(UINT_MAX) { - this->InitNested(desc); // Initializes 'this->line_height' as side effect. - - this->vscroll.SetCount(c->num_valid_params); + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(GRFPAR_WIDGET_SCROLLBAR); + this->FinishInitNested(desc); // Initializes 'this->line_height' as side effect. + this->vscroll->SetCount(c->num_valid_params); } /** @@ -208,7 +210,7 @@ struct NewGRFParametersWindow : public W uint text_right = r.right - (rtl ? 54 : WD_FRAMERECT_RIGHT); int y = r.top; - for (uint i = this->vscroll.GetPosition(); this->vscroll.IsVisible(i) && i < this->grf_config->num_valid_params; i++) { + for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->grf_config->num_valid_params; i++) { GRFParameterInfo *par_info = (i < this->grf_config->param_info.Length()) ? this->grf_config->param_info[i] : NULL; if (par_info == NULL) par_info = GetDummyParameterInfo(i); uint32 current_value = par_info->GetValue(this->grf_config); @@ -256,7 +258,7 @@ struct NewGRFParametersWindow : public W { switch (widget) { case GRFPAR_WIDGET_BACKGROUND: { - uint num = this->vscroll.GetScrolledRowFromWidget(pt.y, this, GRFPAR_WIDGET_BACKGROUND); + uint num = this->vscroll->GetScrolledRowFromWidget(pt.y, this, GRFPAR_WIDGET_BACKGROUND); if (num >= this->grf_config->num_valid_params) break; if (this->clicked_row != num) { DeleteChildWindows(WC_QUERY_STRING); @@ -321,8 +323,8 @@ struct NewGRFParametersWindow : public W virtual void OnResize() { NWidgetCore *nwi = this->GetWidget(GRFPAR_WIDGET_BACKGROUND); - this->vscroll.SetCapacity(nwi->current_y / this->line_height); - nwi->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacity(nwi->current_y / this->line_height); + nwi->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } virtual void OnTick() @@ -438,6 +440,9 @@ struct NewGRFWindow : public QueryString bool execute; ///< On pressing 'apply changes' are grf changes applied immediately, or only list is updated. int preset; ///< Selected preset. + Scrollbar *vscroll; + Scrollbar *vscroll2; + NewGRFWindow(const WindowDesc *desc, bool editable, bool show_params, bool execute, GRFConfig **orig_list) : QueryStringBaseWindow(EDITBOX_MAX_SIZE) { this->avail_sel = NULL; @@ -453,7 +458,11 @@ struct NewGRFWindow : public QueryString CopyGRFConfigList(&this->actives, *orig_list, false); GetGRFPresetList(&_grf_preset_list); - this->InitNested(desc); + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(SNGRFS_SCROLLBAR); + this->vscroll2 = this->GetScrollbar(SNGRFS_SCROLL2BAR); + this->FinishInitNested(desc); + InitializeTextBuffer(&this->text, this->edit_str_buf, this->edit_str_size, EDITBOX_MAX_LENGTH); this->SetFocusedWidget(SNGRFS_FILTER); @@ -530,8 +539,8 @@ struct NewGRFWindow : public QueryString virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, SNGRFS_FILE_LIST); - this->vscroll2.SetCapacityFromWidget(this, SNGRFS_AVAIL_LIST); + this->vscroll->SetCapacityFromWidget(this, SNGRFS_FILE_LIST); + this->vscroll2->SetCapacityFromWidget(this, SNGRFS_AVAIL_LIST); } virtual void SetStringParameters(int widget) const @@ -608,7 +617,7 @@ struct NewGRFWindow : public QueryString int i = 0; for (const GRFConfig *c = this->actives; c != NULL; c = c->next, i++) { - if (this->vscroll.IsVisible(i)) { + if (this->vscroll->IsVisible(i)) { const char *text = c->GetName(); bool h = (this->active_sel == c); PaletteID pal = this->GetPalette(c); @@ -630,8 +639,8 @@ struct NewGRFWindow : public QueryString uint step_height = this->GetWidget(SNGRFS_AVAIL_LIST)->resize_y; int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2; uint y = r.top + WD_FRAMERECT_TOP; - uint min_index = this->vscroll2.GetPosition(); - uint max_index = min(min_index + this->vscroll2.GetCapacity(), this->avails.Length()); + uint min_index = this->vscroll2->GetPosition(); + uint max_index = min(min_index + this->vscroll2->GetCapacity(), this->avails.Length()); for (uint i = min_index; i < max_index; i++) { const GRFConfig *c = this->avails[i]; @@ -709,7 +718,7 @@ struct NewGRFWindow : public QueryString break; } } - this->vscroll.ScrollTowards(pos); + this->vscroll->ScrollTowards(pos); this->preset = -1; this->InvalidateData(); break; @@ -728,14 +737,14 @@ struct NewGRFWindow : public QueryString break; } } - this->vscroll.ScrollTowards(pos); + this->vscroll->ScrollTowards(pos); this->preset = -1; this->InvalidateData(); break; } case SNGRFS_FILE_LIST: { // Select an active GRF. - uint i = this->vscroll.GetScrolledRowFromWidget(pt.y, this, SNGRFS_FILE_LIST); + uint i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, SNGRFS_FILE_LIST); GRFConfig *c; for (c = this->actives; c != NULL && i > 0; c = c->next, i--) {} @@ -779,7 +788,7 @@ struct NewGRFWindow : public QueryString } case SNGRFS_AVAIL_LIST: { // Select a non-active GRF. - uint i = this->vscroll2.GetScrolledRowFromWidget(pt.y, this, SNGRFS_AVAIL_LIST); + uint i = this->vscroll2->GetScrolledRowFromWidget(pt.y, this, SNGRFS_AVAIL_LIST); this->active_sel = NULL; DeleteWindowByClass(WC_GRF_PARAMETERS); if (i < this->avails.Length()) { @@ -970,11 +979,11 @@ struct NewGRFWindow : public QueryString int i = 0; for (const GRFConfig *c = this->actives; c != NULL; c = c->next, i++) {} - this->vscroll.SetCapacityFromWidget(this, SNGRFS_FILE_LIST); - this->vscroll.SetCount(i); + this->vscroll->SetCapacityFromWidget(this, SNGRFS_FILE_LIST); + this->vscroll->SetCount(i); - this->vscroll2.SetCapacityFromWidget(this, SNGRFS_AVAIL_LIST); - if (this->avail_pos >= 0) this->vscroll2.ScrollTowards(this->avail_pos); + this->vscroll2->SetCapacityFromWidget(this, SNGRFS_AVAIL_LIST); + if (this->avail_pos >= 0) this->vscroll2->ScrollTowards(this->avail_pos); break; } } @@ -1044,12 +1053,12 @@ struct NewGRFWindow : public QueryString case WKC_PAGEUP: /* scroll up a page */ - this->avail_pos = (this->avail_pos < this->vscroll2.GetCapacity()) ? 0 : this->avail_pos - this->vscroll2.GetCapacity(); + this->avail_pos = (this->avail_pos < this->vscroll2->GetCapacity()) ? 0 : this->avail_pos - this->vscroll2->GetCapacity(); break; case WKC_PAGEDOWN: /* scroll down a page */ - this->avail_pos = min(this->avail_pos + this->vscroll2.GetCapacity(), (int)this->avails.Length() - 1); + this->avail_pos = min(this->avail_pos + this->vscroll2->GetCapacity(), (int)this->avails.Length() - 1); break; case WKC_HOME: @@ -1075,7 +1084,7 @@ struct NewGRFWindow : public QueryString if (this->avails.Length() == 0) this->avail_pos = -1; if (this->avail_pos >= 0) { this->avail_sel = this->avails[this->avail_pos]; - this->vscroll2.ScrollTowards(this->avail_pos); + this->vscroll2->ScrollTowards(this->avail_pos); this->InvalidateData(0); } @@ -1149,7 +1158,7 @@ private: if (this->avail_pos < 0) this->avail_sel = NULL; } - this->vscroll2.SetCount(this->avails.Length()); // Update the scrollbar + this->vscroll2->SetCount(this->avails.Length()); // Update the scrollbar } }; diff --git a/src/news_gui.cpp b/src/news_gui.cpp --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -951,9 +951,13 @@ struct MessageHistoryWindow : Window { int line_height; /// < Height of a single line in the news histoy window including spacing. int date_width; /// < Width needed for the date part. + Scrollbar *vscroll; + MessageHistoryWindow(const WindowDesc *desc) : Window() { - this->InitNested(desc); // Initializes 'this->line_height' and 'this->date_width'. + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(MHW_SCROLLBAR); + this->FinishInitNested(desc); // Initializes 'this->line_height' and 'this->date_width'. this->OnInvalidateData(0); } @@ -983,7 +987,7 @@ struct MessageHistoryWindow : Window { /* Find the first news item to display. */ NewsItem *ni = _latest_news; - for (int n = this->vscroll.GetPosition(); n > 0; n--) { + for (int n = this->vscroll->GetPosition(); n > 0; n--) { ni = ni->prev; if (ni == NULL) return; } @@ -995,7 +999,7 @@ struct MessageHistoryWindow : Window { uint date_right = rtl ? r.right - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT + this->date_width; uint news_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.left + WD_FRAMERECT_LEFT + this->date_width + WD_FRAMERECT_RIGHT; uint news_right = rtl ? r.right - WD_FRAMERECT_RIGHT - this->date_width - WD_FRAMERECT_RIGHT : r.right - WD_FRAMERECT_RIGHT; - for (int n = this->vscroll.GetCapacity(); n > 0; n--) { + for (int n = this->vscroll->GetCapacity(); n > 0; n--) { SetDParam(0, ni->date); DrawString(date_left, date_right, y, STR_SHORT_DATE); @@ -1009,7 +1013,7 @@ struct MessageHistoryWindow : Window { virtual void OnInvalidateData(int data) { - this->vscroll.SetCount(_total_news); + this->vscroll->SetCount(_total_news); } virtual void OnClick(Point pt, int widget, int click_count) @@ -1018,7 +1022,7 @@ struct MessageHistoryWindow : Window { NewsItem *ni = _latest_news; if (ni == NULL) return; - for (int n = this->vscroll.GetScrolledRowFromWidget(pt.y, this, MHW_BACKGROUND, WD_FRAMERECT_TOP, this->line_height); n > 0; n--) { + for (int n = this->vscroll->GetScrolledRowFromWidget(pt.y, this, MHW_BACKGROUND, WD_FRAMERECT_TOP, this->line_height); n > 0; n--) { ni = ni->prev; if (ni == NULL) return; } @@ -1029,7 +1033,7 @@ struct MessageHistoryWindow : Window { virtual void OnResize() { - this->vscroll.SetCapacity(this->GetWidget(MHW_BACKGROUND)->current_y / this->line_height); + this->vscroll->SetCapacity(this->GetWidget(MHW_BACKGROUND)->current_y / this->line_height); } }; diff --git a/src/order_gui.cpp b/src/order_gui.cpp --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -466,6 +466,7 @@ private: OrderID order_over; ///< Order over which another order is dragged, \c INVALID_ORDER if none. OrderPlaceObjectState goto_type; const Vehicle *vehicle; ///< Vehicle owning the orders being displayed and manipulated. + Scrollbar *vscroll; /** * Return the memorised selected order. @@ -491,9 +492,9 @@ private: NWidgetBase *nwid = this->GetWidget(ORDER_WIDGET_ORDER_LIST); int sel = (y - nwid->pos_y - WD_FRAMERECT_TOP) / nwid->resize_y; // Selected line in the ORDER_WIDGET_ORDER_LIST panel. - if ((uint)sel >= this->vscroll.GetCapacity()) return INVALID_ORDER; + if ((uint)sel >= this->vscroll->GetCapacity()) return INVALID_ORDER; - sel += this->vscroll.GetPosition(); + sel += this->vscroll->GetPosition(); return (sel <= vehicle->GetNumOrders() && sel >= 0) ? sel : INVALID_ORDER; } @@ -710,7 +711,9 @@ public: { this->vehicle = v; - this->InitNested(desc, v->index); + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(ORDER_WIDGET_SCROLLBAR); + this->FinishInitNested(desc, v->index); this->selected_order = -1; this->order_over = INVALID_ORDER; @@ -819,7 +822,7 @@ public: } } - this->vscroll.SetCount(this->vehicle->GetNumOrders() + 1); + this->vscroll->SetCount(this->vehicle->GetNumOrders() + 1); this->UpdateButtonState(); } @@ -968,13 +971,13 @@ public: int y = r.top + WD_FRAMERECT_TOP; int line_height = this->GetWidget(ORDER_WIDGET_ORDER_LIST)->resize_y; - int i = this->vscroll.GetPosition(); + int i = this->vscroll->GetPosition(); const Order *order = this->vehicle->GetOrder(i); /* First draw the highlighting underground if it exists. */ if (this->order_over != INVALID_ORDER) { while (order != NULL) { /* Don't draw anything if it extends past the end of the window. */ - if (!this->vscroll.IsVisible(i)) break; + if (!this->vscroll->IsVisible(i)) break; if (i != this->selected_order && i == this->order_over) { /* Highlight dragged order destination. */ @@ -992,14 +995,14 @@ public: /* Reset counters for drawing the orders. */ y = r.top + WD_FRAMERECT_TOP; - i = this->vscroll.GetPosition(); + i = this->vscroll->GetPosition(); order = this->vehicle->GetOrder(i); } /* Draw the orders. */ while (order != NULL) { /* Don't draw anything if it extends past the end of the window. */ - if (!this->vscroll.IsVisible(i)) break; + if (!this->vscroll->IsVisible(i)) break; DrawOrderString(this->vehicle, order, i, y, i == this->selected_order, false, r.left + WD_FRAMETEXT_LEFT, middle, r.right - WD_FRAMETEXT_RIGHT); y += line_height; @@ -1008,7 +1011,7 @@ public: order = order->next; } - if (this->vscroll.IsVisible(i)) { + if (this->vscroll->IsVisible(i)) { StringID str = this->vehicle->IsOrderListShared() ? STR_ORDERS_END_OF_SHARED_ORDERS : STR_ORDERS_END_OF_ORDERS; DrawString(rtl ? r.left + WD_FRAMETEXT_LEFT : middle, rtl ? middle : r.right - WD_FRAMETEXT_RIGHT, y, str, (i == this->selected_order) ? TC_WHITE : TC_BLACK); } @@ -1340,7 +1343,7 @@ public: virtual void OnResize() { /* Update the scroll bar */ - this->vscroll.SetCapacityFromWidget(this, ORDER_WIDGET_ORDER_LIST); + this->vscroll->SetCapacityFromWidget(this, ORDER_WIDGET_ORDER_LIST); } virtual void OnTimeout() diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -994,6 +994,7 @@ enum BuildRailStationWidgets { struct BuildRailStationWindow : public PickerWindowBase { private: uint line_height; ///< Height of a single line in the newstation selection matrix (#BRSW_NEWST_LIST widget). + Scrollbar *vscroll; /** * Verify whether the currently selected station size is allowed after selecting a new station class/type. @@ -1041,6 +1042,7 @@ public: BuildRailStationWindow(const WindowDesc *desc, Window *parent, bool newstation) : PickerWindowBase(parent) { this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(BRSW_NEWST_SCROLL); NWidgetStacked *newst_additions = this->GetWidget(BRSW_SHOW_NEWST_ADDITIONS); newst_additions->SetDisplayedPlane(newstation ? 0 : SZSP_NONE); this->FinishInitNested(desc, TRANSPORT_RAIL); @@ -1060,9 +1062,9 @@ public: if (newstation) { _railstation.station_count = StationClass::GetCount(_railstation.station_class); - this->vscroll.SetCount(_railstation.station_count); - this->vscroll.SetCapacity(GB(this->GetWidget(BRSW_NEWST_LIST)->widget_data, MAT_ROW_START, MAT_ROW_BITS)); - this->vscroll.SetPosition(Clamp(_railstation.station_type - 2, 0, max(this->vscroll.GetCount() - this->vscroll.GetCapacity(), 0))); + this->vscroll->SetCount(_railstation.station_count); + this->vscroll->SetCapacity(GB(this->GetWidget(BRSW_NEWST_LIST)->widget_data, MAT_ROW_START, MAT_ROW_BITS)); + this->vscroll->SetPosition(Clamp(_railstation.station_type - 2, 0, max(this->vscroll->GetCount() - this->vscroll->GetCapacity(), 0))); } else { /* New stations are not available, so ensure the default station * type is 'selected'. */ @@ -1186,7 +1188,7 @@ public: case BRSW_NEWST_LIST: { uint y = r.top; - for (uint16 i = this->vscroll.GetPosition(); i < _railstation.station_count && this->vscroll.IsVisible(i); i++) { + for (uint16 i = this->vscroll->GetPosition(); i < _railstation.station_count && this->vscroll->IsVisible(i); i++) { const StationSpec *statspec = StationClass::Get(_railstation.station_class, i); StringID str = STR_STATION_CLASS_DFLT; @@ -1342,7 +1344,7 @@ public: break; case BRSW_NEWST_LIST: { - int y = this->vscroll.GetScrolledRowFromWidget(pt.y, this, BRSW_NEWST_LIST, 0, this->line_height); + int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, BRSW_NEWST_LIST, 0, this->line_height); if (y >= _railstation.station_count) return; /* Check station availability callback */ @@ -1371,8 +1373,8 @@ public: this->CheckSelectedSize(StationClass::Get(_railstation.station_class, _railstation.station_type)); - this->vscroll.SetCount(_railstation.station_count); - this->vscroll.SetPosition(_railstation.station_type); + this->vscroll->SetCount(_railstation.station_count); + this->vscroll->SetPosition(_railstation.station_type); } SndPlayFx(SND_15_BEEP); @@ -1771,28 +1773,31 @@ enum BuildRailWaypointWidgets { }; struct BuildRailWaypointWindow : PickerWindowBase { + Scrollbar *hscroll; + BuildRailWaypointWindow(const WindowDesc *desc, Window *parent) : PickerWindowBase(parent) { this->InitNested(desc, TRANSPORT_RAIL); - this->hscroll.SetCapacity(5); - this->hscroll.SetCount(_waypoint_count); + this->hscroll = this->GetScrollbar(BRWW_SCROLL); + this->hscroll->SetCapacity(5); + this->hscroll->SetCount(_waypoint_count); }; virtual void OnPaint() { - for (uint i = 0; i < this->hscroll.GetCapacity(); i++) { - this->SetWidgetLoweredState(i + BRWW_WAYPOINT_1, (this->hscroll.GetPosition() + i) == _cur_waypoint_type); + for (uint i = 0; i < this->hscroll->GetCapacity(); i++) { + this->SetWidgetLoweredState(i + BRWW_WAYPOINT_1, (this->hscroll->GetPosition() + i) == _cur_waypoint_type); } this->DrawWidgets(); - for (uint i = 0; i < this->hscroll.GetCapacity(); i++) { - if (this->hscroll.GetPosition() + i < this->hscroll.GetCount()) { - const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP, this->hscroll.GetPosition() + i); + for (uint i = 0; i < this->hscroll->GetCapacity(); i++) { + if (this->hscroll->GetPosition() + i < this->hscroll->GetCount()) { + const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP, this->hscroll->GetPosition() + i); NWidgetBase *nw = this->GetWidget(BRWW_WAYPOINT_1 + i); int bottom = nw->pos_y + nw->current_y; - DrawWaypointSprite(nw->pos_x + TILE_PIXELS, bottom - TILE_PIXELS, this->hscroll.GetPosition() + i, _cur_railtype); + DrawWaypointSprite(nw->pos_x + TILE_PIXELS, bottom - TILE_PIXELS, this->hscroll->GetPosition() + i, _cur_railtype); if (statspec != NULL && HasBit(statspec->callback_mask, CBM_STATION_AVAIL) && @@ -1811,7 +1816,7 @@ struct BuildRailWaypointWindow : PickerW case BRWW_WAYPOINT_3: case BRWW_WAYPOINT_4: case BRWW_WAYPOINT_5: { - byte type = widget - BRWW_WAYPOINT_1 + this->hscroll.GetPosition(); + byte type = widget - BRWW_WAYPOINT_1 + this->hscroll->GetPosition(); /* Check station availability callback */ const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP, type); diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1504,6 +1504,8 @@ struct GameSettingsWindow : Window { SettingEntry *valuewindow_entry; ///< If non-NULL, pointer to setting for which a value-entering window has been opened SettingEntry *clicked_entry; ///< If non-NULL, pointer to a clicked numeric setting (with a depressed left or right button) + Scrollbar *vscroll; + GameSettingsWindow(const WindowDesc *desc) : Window() { static bool first_time = true; @@ -1521,9 +1523,11 @@ struct GameSettingsWindow : Window { this->valuewindow_entry = NULL; // No setting entry for which a entry window is opened this->clicked_entry = NULL; // No numeric setting buttons are depressed - this->InitNested(desc, 0); + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(SETTINGSEL_SCROLLBAR); + this->FinishInitNested(desc, 0); - this->vscroll.SetCount(_settings_main_page.Length()); + this->vscroll->SetCount(_settings_main_page.Length()); } virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) @@ -1541,7 +1545,7 @@ struct GameSettingsWindow : Window { if (widget != SETTINGSEL_OPTIONSPANEL) return; _settings_main_page.Draw(settings_ptr, r.left + SETTINGTREE_LEFT_OFFSET, r.right - SETTINGTREE_RIGHT_OFFSET, r.top + SETTINGTREE_TOP_OFFSET, - this->vscroll.GetPosition(), this->vscroll.GetPosition() + this->vscroll.GetCapacity()); + this->vscroll->GetPosition(), this->vscroll->GetPosition() + this->vscroll->GetCapacity()); } virtual void OnPaint() @@ -1553,7 +1557,7 @@ struct GameSettingsWindow : Window { { if (widget != SETTINGSEL_OPTIONSPANEL) return; - uint btn = this->vscroll.GetScrolledRowFromWidget(pt.y, this, SETTINGSEL_OPTIONSPANEL, SETTINGTREE_TOP_OFFSET - 1); + uint btn = this->vscroll->GetScrolledRowFromWidget(pt.y, this, SETTINGSEL_OPTIONSPANEL, SETTINGTREE_TOP_OFFSET - 1); if (btn == INT_MAX) return; uint cur_row = 0; @@ -1567,7 +1571,7 @@ struct GameSettingsWindow : Window { if ((pe->flags & SEF_KIND_MASK) == SEF_SUBTREE_KIND) { pe->d.sub.folded = !pe->d.sub.folded; // Flip 'folded'-ness of the sub-page - this->vscroll.SetCount(_settings_main_page.Length()); + this->vscroll->SetCount(_settings_main_page.Length()); this->SetDirty(); return; } @@ -1695,7 +1699,7 @@ struct GameSettingsWindow : Window { virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, SETTINGSEL_OPTIONSPANEL, SETTINGTREE_TOP_OFFSET + SETTINGTREE_BOTTOM_OFFSET); + this->vscroll->SetCapacityFromWidget(this, SETTINGSEL_OPTIONSPANEL, SETTINGTREE_TOP_OFFSET + SETTINGTREE_BOTTOM_OFFSET); } }; diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -90,17 +90,20 @@ enum SignListWidgets { struct SignListWindow : Window, SignList { int text_offset; // Offset of the sign text relative to the left edge of the SLW_LIST widget. + Scrollbar *vscroll; SignListWindow(const WindowDesc *desc, WindowNumber window_number) : Window() { - this->InitNested(desc, window_number); + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(SLW_SCROLLBAR); + this->FinishInitNested(desc, window_number); /* Create initial list. */ this->signs.ForceRebuild(); this->signs.ForceResort(); this->BuildSignsList(); this->SortSignsList(); - this->vscroll.SetCount(this->signs.Length()); + this->vscroll->SetCount(this->signs.Length()); } virtual void OnPaint() @@ -114,7 +117,7 @@ struct SignListWindow : Window, SignList case SLW_LIST: { uint y = r.top + WD_FRAMERECT_TOP; // Offset from top of widget. /* No signs? */ - if (this->vscroll.GetCount() == 0) { + if (this->vscroll->GetCount() == 0) { DrawString(r.left + WD_FRAMETEXT_LEFT, r.right, y, STR_STATION_LIST_NONE); return; } @@ -126,7 +129,7 @@ struct SignListWindow : Window, SignList uint text_right = r.right - (rtl ? this->text_offset : WD_FRAMERECT_RIGHT); /* At least one sign available. */ - for (uint16 i = this->vscroll.GetPosition(); this->vscroll.IsVisible(i) && i < this->vscroll.GetCount(); i++) { + for (uint16 i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) { const Sign *si = this->signs[i]; if (si->owner != OWNER_NONE) DrawCompanyIcon(si->owner, icon_left, y + sprite_offset_y); @@ -142,13 +145,13 @@ struct SignListWindow : Window, SignList virtual void SetStringParameters(int widget) const { - if (widget == SLW_CAPTION) SetDParam(0, this->vscroll.GetCount()); + if (widget == SLW_CAPTION) SetDParam(0, this->vscroll->GetCount()); } virtual void OnClick(Point pt, int widget, int click_count) { if (widget == SLW_LIST) { - uint id_v = this->vscroll.GetScrolledRowFromWidget(pt.y, this, SLW_LIST, WD_FRAMERECT_TOP); + uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, SLW_LIST, WD_FRAMERECT_TOP); if (id_v == INT_MAX) return; const Sign *si = this->signs[id_v]; @@ -158,7 +161,7 @@ struct SignListWindow : Window, SignList virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, SLW_LIST, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); + this->vscroll->SetCapacityFromWidget(this, SLW_LIST, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); } virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) @@ -188,7 +191,7 @@ struct SignListWindow : Window, SignList this->signs.ForceRebuild(); this->BuildSignsList(); this->SetWidgetDirty(SLW_CAPTION); - this->vscroll.SetCount(this->signs.Length()); + this->vscroll->SetCount(this->signs.Length()); } else { // Change of sign contents. this->signs.ForceResort(); } diff --git a/src/station_gui.cpp b/src/station_gui.cpp --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -217,7 +217,7 @@ protected: static GUIStationList::SortFunction * const sorter_funcs[]; GUIStationList stations; - + Scrollbar *vscroll; /** * (Re)Build station list @@ -257,7 +257,7 @@ protected: this->stations.Compact(); this->stations.RebuildDone(); - this->vscroll.SetCount(this->stations.Length()); // Update the scrollbar + this->vscroll->SetCount(this->stations.Length()); // Update the scrollbar } /** Sort stations by their name */ @@ -349,7 +349,9 @@ public: this->stations.NeedResort(); this->SortStationsList(); - this->InitNested(desc, window_number); + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(SLW_SCROLLBAR); + this->FinishInitNested(desc, window_number); this->owner = (Owner)this->window_number; CargoID cid; @@ -449,9 +451,9 @@ public: case SLW_LIST: { bool rtl = _dynlang.text_dir == TD_RTL; - int max = min(this->vscroll.GetPosition() + this->vscroll.GetCapacity(), this->stations.Length()); + int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->stations.Length()); int y = r.top + WD_FRAMERECT_TOP; - for (int i = this->vscroll.GetPosition(); i < max; ++i) { // do until max number of stations of owner + for (int i = this->vscroll->GetPosition(); i < max; ++i) { // do until max number of stations of owner const Station *st = this->stations[i]; assert(st->xy != INVALID_TILE); @@ -485,7 +487,7 @@ public: y += FONT_HEIGHT_NORMAL; } - if (this->vscroll.GetCount() == 0) { // company has no stations + if (this->vscroll->GetCount() == 0) { // company has no stations DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_STATION_LIST_NONE); return; } @@ -527,7 +529,7 @@ public: { if (widget == SLW_CAPTION) { SetDParam(0, this->window_number); - SetDParam(1, this->vscroll.GetCount()); + SetDParam(1, this->vscroll->GetCount()); } } @@ -535,7 +537,7 @@ public: { switch (widget) { case SLW_LIST: { - uint id_v = this->vscroll.GetScrolledRowFromWidget(pt.y, this, SLW_LIST, 0, FONT_HEIGHT_NORMAL); + uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, SLW_LIST, 0, FONT_HEIGHT_NORMAL); if (id_v >= this->stations.Length()) return; // click out of list bound const Station *st = this->stations[id_v]; @@ -682,7 +684,7 @@ public: virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, SLW_LIST, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); + this->vscroll->SetCapacityFromWidget(this, SLW_LIST, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); } virtual void OnInvalidateData(int data) @@ -878,6 +880,7 @@ struct StationViewWindow : public Window uint expand_shrink_width; ///< The width allocated to the expand/shrink 'button' int rating_lines; ///< Number of lines in the cargo ratings view. int accepts_lines; ///< Number of lines in the accepted cargo view. + Scrollbar *vscroll; /** Height of the #SVW_ACCEPTLIST widget for different views. */ enum AcceptListHeight { @@ -891,6 +894,7 @@ struct StationViewWindow : public Window this->accepts_lines = ALH_ACCEPTS; this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(SVW_SCROLLBAR); /* Nested widget tree creation is done in two steps to ensure that this->GetWidget(SVW_ACCEPTS) exists in UpdateWidgetSize(). */ this->FinishInitNested(desc, window_number); @@ -929,7 +933,7 @@ struct StationViewWindow : public Window uint32 transfers = 0; this->OrderWaitingCargo(&cargolist, &transfers); - this->vscroll.SetCount((int)cargolist.size() + 1); // update scrollbar + this->vscroll->SetCount((int)cargolist.size() + 1); // update scrollbar /* disable some buttons */ const Station *st = Station::Get(this->window_number); @@ -1041,7 +1045,7 @@ struct StationViewWindow : public Window void DrawWaitingCargo(const Rect &r, const CargoDataList &cargolist, uint32 transfers) const { int y = r.top + WD_FRAMERECT_TOP; - int pos = this->vscroll.GetPosition(); + int pos = this->vscroll->GetPosition(); const Station *st = Station::Get(this->window_number); if (--pos < 0) { @@ -1061,7 +1065,7 @@ struct StationViewWindow : public Window int shrink_right = rtl ? r.left + this->expand_shrink_width - WD_FRAMERECT_RIGHT : r.right - WD_FRAMERECT_RIGHT; - int maxrows = this->vscroll.GetCapacity(); + int maxrows = this->vscroll->GetCapacity(); for (CargoDataList::const_iterator it = cargolist.begin(); it != cargolist.end() && pos > -maxrows; ++it) { if (--pos < 0) { const CargoData *cd = &(*it); @@ -1152,7 +1156,7 @@ struct StationViewWindow : public Window { switch (widget) { case SVW_WAITING: - this->HandleCargoWaitingClick(this->vscroll.GetScrolledRowFromWidget(pt.y, this, SVW_WAITING, WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL)); + this->HandleCargoWaitingClick(this->vscroll->GetScrolledRowFromWidget(pt.y, this, SVW_WAITING, WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL)); break; case SVW_LOCATION: @@ -1202,7 +1206,7 @@ struct StationViewWindow : public Window virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, SVW_WAITING, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); + this->vscroll->SetCapacityFromWidget(this, SVW_WAITING, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); } }; @@ -1354,6 +1358,7 @@ template struct SelectStationWindow : Window { CommandContainer select_station_cmd; ///< Command to build new station TileArea area; ///< Location of new station + Scrollbar *vscroll; SelectStationWindow(const WindowDesc *desc, CommandContainer cmd, TileArea ta) : Window(), @@ -1361,6 +1366,7 @@ struct SelectStationWindow : Window { area(ta) { this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(JSW_SCROLLBAR); this->GetWidget(JSW_WIDGET_CAPTION)->widget_data = T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_JOIN_WAYPOINT_CAPTION : STR_JOIN_STATION_CAPTION; this->FinishInitNested(desc, 0); this->OnInvalidateData(0); @@ -1396,14 +1402,14 @@ struct SelectStationWindow : Window { if (widget != JSW_PANEL) return; uint y = r.top + WD_FRAMERECT_TOP; - if (this->vscroll.GetPosition() == 0) { + if (this->vscroll->GetPosition() == 0) { DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT : STR_JOIN_STATION_CREATE_SPLITTED_STATION); y += this->resize.step_height; } - for (uint i = max(1, this->vscroll.GetPosition()); i <= _stations_nearby_list.Length(); ++i, y += this->resize.step_height) { + for (uint i = max(1, this->vscroll->GetPosition()); i <= _stations_nearby_list.Length(); ++i, y += this->resize.step_height) { /* Don't draw anything if it extends past the end of the window. */ - if (i - this->vscroll.GetPosition() >= this->vscroll.GetCapacity()) break; + if (i - this->vscroll->GetPosition() >= this->vscroll->GetCapacity()) break; const T *st = T::Get(_stations_nearby_list[i - 1]); SetDParam(0, st->index); @@ -1416,7 +1422,7 @@ struct SelectStationWindow : Window { { if (widget != JSW_PANEL) return; - uint st_index = this->vscroll.GetScrolledRowFromWidget(pt.y, this, JSW_PANEL, WD_FRAMERECT_TOP); + uint st_index = this->vscroll->GetScrolledRowFromWidget(pt.y, this, JSW_PANEL, WD_FRAMERECT_TOP); bool distant_join = (st_index > 0); if (distant_join) st_index--; @@ -1443,13 +1449,13 @@ struct SelectStationWindow : Window { virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, JSW_PANEL, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); + this->vscroll->SetCapacityFromWidget(this, JSW_PANEL, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); } virtual void OnInvalidateData(int data) { FindStationsNearby(this->area, true); - this->vscroll.SetCount(_stations_nearby_list.Length() + 1); + this->vscroll->SetCount(_stations_nearby_list.Length() + 1); this->SetDirty(); } }; diff --git a/src/subsidy_gui.cpp b/src/subsidy_gui.cpp --- a/src/subsidy_gui.cpp +++ b/src/subsidy_gui.cpp @@ -31,9 +31,13 @@ enum SubsidyListWidgets { }; struct SubsidyListWindow : Window { + Scrollbar *vscroll; + SubsidyListWindow(const WindowDesc *desc, WindowNumber window_number) : Window() { - this->InitNested(desc, window_number); + this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(SLW_SCROLLBAR); + this->FinishInitNested(desc, window_number); this->OnInvalidateData(0); } @@ -41,7 +45,7 @@ struct SubsidyListWindow : Window { { if (widget != SLW_PANEL) return; - int y = this->vscroll.GetScrolledRowFromWidget(pt.y, this, SLW_PANEL, WD_FRAMERECT_TOP); + int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, SLW_PANEL, WD_FRAMERECT_TOP); int num = 0; const Subsidy *s; FOR_ALL_SUBSIDIES(s) { @@ -157,8 +161,8 @@ struct SubsidyListWindow : Window { int y = r.top + WD_FRAMERECT_TOP; int x = r.left + WD_FRAMERECT_LEFT; - int pos = -this->vscroll.GetPosition(); - const int cap = this->vscroll.GetCapacity(); + int pos = -this->vscroll->GetPosition(); + const int cap = this->vscroll->GetCapacity(); /* Section for drawing the offered subisidies */ if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_OFFERED_TITLE); @@ -213,12 +217,12 @@ struct SubsidyListWindow : Window { virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, SLW_PANEL); + this->vscroll->SetCapacityFromWidget(this, SLW_PANEL); } virtual void OnInvalidateData(int data) { - this->vscroll.SetCount(this->CountLines()); + this->vscroll->SetCount(this->CountLines()); } }; diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -172,6 +172,7 @@ struct TimetableWindow : Window { bool show_expected; ///< Whether we show expected arrival or scheduled uint deparr_time_width; ///< The width of the departure/arrival time uint deparr_abbr_width; ///< The width of the departure/arrival abbreviation + Scrollbar *vscroll; TimetableWindow(const WindowDesc *desc, WindowNumber window_number) : Window(), @@ -180,6 +181,8 @@ struct TimetableWindow : Window { show_expected(true) { this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(TTV_SCROLLBAR); + // TODO TTV_FAKE_SCROLLBAR this->UpdateSelectionStates(); this->FinishInitNested(desc, window_number); @@ -229,9 +232,9 @@ struct TimetableWindow : Window { { int sel = (y - this->GetWidget(TTV_TIMETABLE_PANEL)->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL; - if ((uint)sel >= this->vscroll.GetCapacity()) return INVALID_ORDER; + if ((uint)sel >= this->vscroll->GetCapacity()) return INVALID_ORDER; - sel += this->vscroll.GetPosition(); + sel += this->vscroll->GetPosition(); return (sel < v->GetNumOrders() * 2 && sel >= 0) ? sel : INVALID_ORDER; } @@ -308,7 +311,7 @@ struct TimetableWindow : Window { const Vehicle *v = this->vehicle; int selected = this->sel_index; - this->vscroll.SetCount(v->GetNumOrders() * 2); + this->vscroll->SetCount(v->GetNumOrders() * 2); if (v->owner == _local_company) { bool disable = true; @@ -358,7 +361,7 @@ struct TimetableWindow : Window { switch (widget) { case TTV_TIMETABLE_PANEL: { int y = r.top + WD_FRAMERECT_TOP; - int i = this->vscroll.GetPosition(); + int i = this->vscroll->GetPosition(); VehicleOrderID order_id = (i + 1) / 2; bool final_order = false; @@ -370,7 +373,7 @@ struct TimetableWindow : Window { const Order *order = v->GetOrder(order_id); while (order != NULL) { /* Don't draw anything if it extends past the end of the window. */ - if (!this->vscroll.IsVisible(i)) break; + if (!this->vscroll->IsVisible(i)) break; if (i % 2 == 0) { DrawOrderString(v, order, order_id, y, i == selected, true, r.left + WD_FRAMERECT_LEFT, middle, r.right - WD_FRAMERECT_RIGHT); @@ -430,9 +433,9 @@ struct TimetableWindow : Window { int time_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.right - WD_FRAMERECT_RIGHT - this->deparr_time_width; int time_right = rtl ? r.left + WD_FRAMERECT_LEFT + this->deparr_time_width : r.right - WD_FRAMERECT_RIGHT; - for (int i = this->vscroll.GetPosition(); i / 2 < v->GetNumOrders(); ++i) { // note: i is also incremented in the loop + for (int i = this->vscroll->GetPosition(); i / 2 < v->GetNumOrders(); ++i) { // note: i is also incremented in the loop /* Don't draw anything if it extends past the end of the window. */ - if (!this->vscroll.IsVisible(i)) break; + if (!this->vscroll->IsVisible(i)) break; if (i % 2 == 0) { if (arr_dep[i / 2].arrival != INVALID_TICKS) { @@ -591,7 +594,7 @@ struct TimetableWindow : Window { virtual void OnResize() { /* Update the scroll bar */ - this->vscroll.SetCapacityFromWidget(this, TTV_TIMETABLE_PANEL, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); + this->vscroll->SetCapacityFromWidget(this, TTV_TIMETABLE_PANEL, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); } /** diff --git a/src/town_gui.cpp b/src/town_gui.cpp --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -74,6 +74,7 @@ struct TownAuthorityWindow : Window { private: Town *town; ///< Town being displayed. int sel_index; ///< Currently selected town action, \c 0 to \c TACT_COUNT-1, \c -1 means no action selected. + Scrollbar *vscroll; /** * Get the position of the Nth set bit. @@ -101,7 +102,8 @@ public: { this->town = Town::Get(window_number); this->InitNested(desc, window_number); - this->vscroll.SetCapacity((this->GetWidget(TWA_COMMAND_LIST)->current_y - WD_FRAMERECT_TOP - WD_FRAMERECT_BOTTOM) / FONT_HEIGHT_NORMAL); + this->vscroll = this->GetScrollbar(TWA_SCROLLBAR); + this->vscroll->SetCapacity((this->GetWidget(TWA_COMMAND_LIST)->current_y - WD_FRAMERECT_TOP - WD_FRAMERECT_BOTTOM) / FONT_HEIGHT_NORMAL); } virtual void OnPaint() @@ -109,7 +111,7 @@ public: int numact; uint buttons = GetMaskOfTownActions(&numact, _local_company, this->town); - this->vscroll.SetCount(numact + 1); + this->vscroll->SetCount(numact + 1); if (this->sel_index != -1 && !HasBit(buttons, this->sel_index)) { this->sel_index = -1; @@ -198,7 +200,7 @@ public: int numact; uint buttons = GetMaskOfTownActions(&numact, _local_company, this->town); int y = r.top + WD_FRAMERECT_TOP; - int pos = this->vscroll.GetPosition(); + int pos = this->vscroll->GetPosition(); if (--pos < 0) { DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_LOCAL_AUTHORITY_ACTIONS_TITLE); @@ -260,7 +262,7 @@ public: int y = this->GetRowFromWidget(pt.y, TWA_COMMAND_LIST, 1, FONT_HEIGHT_NORMAL); if (!IsInsideMM(y, 0, 5)) return; - y = GetNthSetBit(GetMaskOfTownActions(NULL, _local_company, this->town), y + this->vscroll.GetPosition() - 1); + y = GetNthSetBit(GetMaskOfTownActions(NULL, _local_company, this->town), y + this->vscroll->GetPosition() - 1); if (y >= 0) { this->sel_index = y; this->SetDirty(); @@ -654,6 +656,8 @@ private: GUITownList towns; + Scrollbar *vscroll; + void BuildSortTownList() { if (this->towns.NeedRebuild()) { @@ -666,7 +670,7 @@ private: this->towns.Compact(); this->towns.RebuildDone(); - this->vscroll.SetCount(this->towns.Length()); // Update scrollbar as well. + this->vscroll->SetCount(this->towns.Length()); // Update scrollbar as well. } /* Always sort the towns. */ this->last_town = NULL; @@ -705,12 +709,16 @@ private: public: TownDirectoryWindow(const WindowDesc *desc) : Window() { + this->CreateNestedTree(desc); + + this->vscroll = this->GetScrollbar(TDW_SCROLLBAR); + this->towns.SetListing(this->last_sorting); this->towns.SetSortFuncs(TownDirectoryWindow::sorter_funcs); this->towns.ForceRebuild(); this->BuildSortTownList(); - this->InitNested(desc, 0); + this->FinishInitNested(desc, 0); } ~TownDirectoryWindow() @@ -747,7 +755,7 @@ public: break; } /* At least one town available. */ - for (uint i = this->vscroll.GetPosition(); i < this->towns.Length(); i++) { + for (uint i = this->vscroll->GetPosition(); i < this->towns.Length(); i++) { const Town *t = this->towns[i]; assert(t->xy != INVALID_TILE); @@ -757,7 +765,7 @@ public: DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_TOWN_DIRECTORY_TOWN); y += this->resize.step_height; - if (++n == this->vscroll.GetCapacity()) break; // max number of towns in 1 window + if (++n == this->vscroll->GetCapacity()) break; // max number of towns in 1 window } break; } @@ -827,7 +835,7 @@ public: break; case TDW_CENTERTOWN: { // Click on Town Matrix - uint id_v = this->vscroll.GetScrolledRowFromWidget(pt.y, this, TDW_CENTERTOWN, WD_FRAMERECT_TOP); + uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, TDW_CENTERTOWN, WD_FRAMERECT_TOP); if (id_v >= this->towns.Length()) return; // click out of town bounds const Town *t = this->towns[id_v]; @@ -850,7 +858,7 @@ public: virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, TDW_CENTERTOWN); + this->vscroll->SetCapacityFromWidget(this, TDW_CENTERTOWN); } virtual void OnInvalidateData(int data) diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -129,7 +129,7 @@ void BaseVehicleListWindow::BuildVehicle } this->vehicles.RebuildDone(); - this->vscroll.SetCount(this->vehicles.Length()); + this->vscroll->SetCount(this->vehicles.Length()); } /** @@ -418,11 +418,13 @@ struct RefitWindow : public Window { RefitOption *cargo; ///< Refit option selected by \v sel. RefitList list; ///< List of cargo types available for refitting. VehicleOrderID order; ///< If not #INVALID_VEH_ORDER_ID, selection is part of a refit order (rather than execute directly). + Scrollbar *vscroll; RefitWindow(const WindowDesc *desc, const Vehicle *v, VehicleOrderID order) : Window() { this->CreateNestedTree(desc); + this->vscroll = this->GetScrollbar(VRW_SCROLLBAR); this->GetWidget(VRW_SELECTHEADER)->tool_tip = STR_REFIT_TRAIN_LIST_TOOLTIP + v->type; this->GetWidget(VRW_MATRIX)->tool_tip = STR_REFIT_TRAIN_LIST_TOOLTIP + v->type; NWidgetCore *nwi = this->GetWidget(VRW_REFITBUTTON); @@ -435,7 +437,7 @@ struct RefitWindow : public Window { this->order = order; this->sel = -1; BuildRefitList(v, &this->list); - this->vscroll.SetCount(this->list.Length()); + this->vscroll->SetCount(this->list.Length()); } virtual void OnInit() @@ -446,20 +448,20 @@ struct RefitWindow : public Window { /* Rebuild the refit list */ BuildRefitList(Vehicle::Get(this->window_number), &this->list); - this->vscroll.SetCount(this->list.Length()); + this->vscroll->SetCount(this->list.Length()); this->sel = -1; this->cargo = NULL; for (uint i = 0; i < this->list.Length(); i++) { if (this->list[i] == current_refit_option) { this->sel = i; this->cargo = &this->list[i]; - this->vscroll.ScrollTowards(i); + this->vscroll->ScrollTowards(i); break; } } /* If the selected refit option was not found, scroll the window to the initial position. */ - if (this->sel == -1) this->vscroll.ScrollTowards(0); + if (this->sel == -1) this->vscroll->ScrollTowards(0); } else { /* Rebuild the refit list */ this->OnInvalidateData(0); @@ -490,7 +492,7 @@ struct RefitWindow : public Window { { switch (widget) { case VRW_MATRIX: - DrawVehicleRefitWindow(this->list, this->sel, this->vscroll.GetPosition(), this->vscroll.GetCapacity(), this->resize.step_height, r); + DrawVehicleRefitWindow(this->list, this->sel, this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->resize.step_height, r); break; case VRW_INFOPANEL: @@ -515,7 +517,7 @@ struct RefitWindow : public Window { case 0: { // The consist lenght of the vehicle has changed; rebuild the entire list. Vehicle *v = Vehicle::Get(this->window_number); BuildRefitList(v, &this->list); - this->vscroll.SetCount(this->list.Length()); + this->vscroll->SetCount(this->list.Length()); /* FALL THROUGH */ } @@ -529,7 +531,7 @@ struct RefitWindow : public Window { { switch (widget) { case VRW_MATRIX: { // listbox - this->sel = this->vscroll.GetScrolledRowFromWidget(pt.y, this, VRW_MATRIX); + this->sel = this->vscroll->GetScrolledRowFromWidget(pt.y, this, VRW_MATRIX); this->InvalidateData(1); if (click_count == 1) break; @@ -552,8 +554,8 @@ struct RefitWindow : public Window { virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, VRW_MATRIX); - this->GetWidget(VRW_MATRIX)->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacityFromWidget(this, VRW_MATRIX); + this->GetWidget(VRW_MATRIX)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } }; @@ -983,8 +985,8 @@ void BaseVehicleListWindow::DrawVehicleL int vehicle_button_x = rtl ? right - 8 : left; int y = r.top; - uint max = min(this->vscroll.GetPosition() + this->vscroll.GetCapacity(), this->vehicles.Length()); - for (uint i = this->vscroll.GetPosition(); i < max; ++i) { + uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehicles.Length()); + for (uint i = this->vscroll->GetPosition(); i < max; ++i) { const Vehicle *v = this->vehicles[i]; StringID str; @@ -1057,14 +1059,16 @@ public: default: NOT_REACHED(); } + this->CreateNestedTree(desc); + + this->vscroll = this->GetScrollbar(VLW_WIDGET_SCROLLBAR); + this->vehicles.SetListing(*this->sorting); this->vehicles.ForceRebuild(); this->vehicles.NeedResort(); this->BuildVehicleList(company, GB(window_number, 16, 16), window_type); this->SortVehicleList(); - this->CreateNestedTree(desc); - /* Set up the window widgets */ this->GetWidget(VLW_WIDGET_LIST)->tool_tip = STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP + this->vehicle_type; @@ -1130,26 +1134,26 @@ public: * and we should close the window when deleting the order */ NOT_REACHED(); } - SetDParam(0, this->vscroll.GetCount()); + SetDParam(0, this->vscroll->GetCount()); break; case VLW_STANDARD: // Company Name SetDParam(0, STR_COMPANY_NAME); SetDParam(1, index); - SetDParam(3, this->vscroll.GetCount()); + SetDParam(3, this->vscroll->GetCount()); break; case VLW_STATION_LIST: // Station/Waypoint Name SetDParam(0, Station::IsExpected(BaseStation::Get(index)) ? STR_STATION_NAME : STR_WAYPOINT_NAME); SetDParam(1, index); - SetDParam(3, this->vscroll.GetCount()); + SetDParam(3, this->vscroll->GetCount()); break; case VLW_DEPOT_LIST: SetDParam(0, STR_DEPOT_CAPTION); SetDParam(1, this->vehicle_type); SetDParam(2, index); - SetDParam(3, this->vscroll.GetCount()); + SetDParam(3, this->vscroll->GetCount()); break; default: NOT_REACHED(); } @@ -1220,7 +1224,7 @@ public: return; case VLW_WIDGET_LIST: { // Matrix to show vehicles - uint id_v = this->vscroll.GetScrolledRowFromWidget(pt.y, this, VLW_WIDGET_LIST); + uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, VLW_WIDGET_LIST); if (id_v >= this->vehicles.Length()) return; // click out of list bound const Vehicle *v = this->vehicles[id_v]; @@ -1289,8 +1293,8 @@ public: virtual void OnResize() { - this->vscroll.SetCapacityFromWidget(this, VLW_WIDGET_LIST); - this->GetWidget(VLW_WIDGET_LIST)->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacityFromWidget(this, VLW_WIDGET_LIST); + this->GetWidget(VLW_WIDGET_LIST)->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } virtual void OnInvalidateData(int data) @@ -1460,13 +1464,16 @@ extern void DrawAircraftDetails(const Ai /** Class for managing the vehicle details window. */ struct VehicleDetailsWindow : Window { TrainDetailsWindowTabs tab; ///< For train vehicles: which tab is displayed. + Scrollbar *vscroll; /** Initialize a newly created vehicle details window */ VehicleDetailsWindow(const WindowDesc *desc, WindowNumber window_number) : Window() { - this->InitNested(desc, window_number); + const Vehicle *v = Vehicle::Get(window_number); - const Vehicle *v = Vehicle::Get(this->window_number); + this->CreateNestedTree(desc); + this->vscroll = (v->type == VEH_TRAIN ? this->GetScrollbar(VLD_WIDGET_SCROLLBAR) : NULL); + this->FinishInitNested(desc, window_number); this->GetWidget(VLD_WIDGET_RENAME_VEHICLE)->tool_tip = STR_VEHICLE_DETAILS_TRAIN_RENAME + v->type; @@ -1669,7 +1676,7 @@ struct VehicleDetailsWindow : Window { case VLD_WIDGET_MATRIX: /* For trains only. */ - DrawVehicleDetails(v, r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, r.top + WD_MATRIX_TOP, this->vscroll.GetPosition(), this->vscroll.GetCapacity(), this->tab); + DrawVehicleDetails(v, r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, r.top + WD_MATRIX_TOP, this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->tab); break; case VLD_WIDGET_MIDDLE_DETAILS: { @@ -1689,7 +1696,7 @@ struct VehicleDetailsWindow : Window { DrawVehicleImage(v, sprite_left + WD_FRAMERECT_LEFT, sprite_right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, INVALID_VEHICLE, 0); } - DrawVehicleDetails(v, text_left + WD_FRAMERECT_LEFT, text_right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, this->vscroll.GetPosition(), this->vscroll.GetCapacity(), this->tab); + DrawVehicleDetails(v, text_left + WD_FRAMERECT_LEFT, text_right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->tab); break; } @@ -1712,7 +1719,7 @@ struct VehicleDetailsWindow : Window { if (v->type == VEH_TRAIN) { this->DisableWidget(this->tab + VLD_WIDGET_DETAILS_CARGO_CARRIED); - this->vscroll.SetCount(GetTrainDetailsWndVScroll(v->index, this->tab)); + this->vscroll->SetCount(GetTrainDetailsWndVScroll(v->index, this->tab)); } /* Disable service-scroller when interval is set to disabled */ @@ -1777,8 +1784,8 @@ struct VehicleDetailsWindow : Window { { NWidgetCore *nwi = this->GetWidget(VLD_WIDGET_MATRIX); if (nwi != NULL) { - this->vscroll.SetCapacityFromWidget(this, VLD_WIDGET_MATRIX); - nwi->widget_data = (this->vscroll.GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); + this->vscroll->SetCapacityFromWidget(this, VLD_WIDGET_MATRIX); + nwi->widget_data = (this->vscroll->GetCapacity() << MAT_ROW_START) + (1 << MAT_COL_START); } } }; diff --git a/src/vehicle_gui_base.h b/src/vehicle_gui_base.h --- a/src/vehicle_gui_base.h +++ b/src/vehicle_gui_base.h @@ -23,6 +23,7 @@ struct BaseVehicleListWindow : public Wi Listing *sorting; ///< Pointer to the vehicle type related sorting. VehicleType vehicle_type; ///< The vehicle type that is sorted byte unitnumber_digits; ///< The number of digits of the highest unit number + Scrollbar *vscroll; enum ActionDropdownItem { ADI_REPLACE, diff --git a/src/widget.cpp b/src/widget.cpp --- a/src/widget.cpp +++ b/src/widget.cpp @@ -83,7 +83,7 @@ static void ScrollbarClickPositioning(Wi w->flags4 &= ~WF_HSCROLL; w->flags4 &= ~WF_SCROLL2; pos = y; - sb = &w->vscroll; + sb = &w->old_vscroll; break; case WWT_SCROLL2BAR: @@ -91,7 +91,7 @@ static void ScrollbarClickPositioning(Wi w->flags4 &= ~WF_HSCROLL; w->flags4 |= WF_SCROLL2; pos = y; - sb = &w->vscroll2; + sb = &w->old_vscroll2; break; case WWT_HSCROLLBAR: @@ -99,7 +99,7 @@ static void ScrollbarClickPositioning(Wi w->flags4 &= ~WF_SCROLL2; w->flags4 |= WF_HSCROLL; pos = x; - sb = &w->hscroll; + sb = &w->old_hscroll; rtl = _dynlang.text_dir == TD_RTL; break; @@ -1997,14 +1997,14 @@ void NWidgetLeaf::Draw(const Window *w) 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->vscroll); + (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->vscroll2); + (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_DOWN | WF_SCROLL2), &w->old_vscroll2); break; case WWT_CAPTION: @@ -2016,7 +2016,7 @@ void NWidgetLeaf::Draw(const Window *w) 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->hscroll); + (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL)) == (WF_SCROLL_DOWN | WF_HSCROLL), &w->old_hscroll); break; case WWT_SHADEBOX: diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -99,6 +99,7 @@ struct DropdownWindow : Window { bool instant_close; ///< Close the window when the mouse button is raised. int scrolling; ///< If non-zero, auto-scroll the item list (one time). Point position; ///< Position of the topleft corner of the window. + Scrollbar *vscroll; /** * Create a dropdown menu. @@ -119,6 +120,8 @@ struct DropdownWindow : Window { this->CreateNestedTree(&_dropdown_desc); + this->vscroll = this->GetScrollbar(DDM_SCROLL); + uint items_width = size.width - (scroll ? WD_VSCROLLBAR_WIDTH : 0); NWidgetCore *nwi = this->GetWidget(DDM_ITEMS); nwi->SetMinimalSize(items_width, size.height + 4); @@ -142,8 +145,8 @@ struct DropdownWindow : Window { } /* Capacity is the average number of items visible */ - this->vscroll.SetCapacity(size.height * (uint16)list->size() / list_height); - this->vscroll.SetCount((uint16)list->size()); + this->vscroll->SetCapacity(size.height * (uint16)list->size() / list_height); + this->vscroll->SetCount((uint16)list->size()); this->parent_wnd_class = parent->window_class; this->parent_wnd_num = parent->window_number; @@ -192,7 +195,7 @@ struct DropdownWindow : Window { NWidgetBase *nwi = this->GetWidget(DDM_ITEMS); int y = _cursor.pos.y - this->top - nwi->pos_y - 2; int width = nwi->current_x - 4; - int pos = this->vscroll.GetPosition(); + int pos = this->vscroll->GetPosition(); const DropDownList *list = this->list; @@ -227,7 +230,7 @@ struct DropdownWindow : Window { TextColour colour = (TextColour)this->GetWidget(widget)->colour; int y = r.top + 2; - int pos = this->vscroll.GetPosition(); + int pos = this->vscroll->GetPosition(); for (DropDownList::const_iterator it = this->list->begin(); it != this->list->end(); ++it) { const DropDownListItem *item = *it; int item_height = item->Height(r.right - r.left + 1); @@ -263,12 +266,12 @@ struct DropdownWindow : Window { virtual void OnTick() { if (this->scrolling != 0) { - int pos = this->vscroll.GetPosition(); + int pos = this->vscroll->GetPosition(); - this->vscroll.UpdatePosition(this->scrolling); + this->vscroll->UpdatePosition(this->scrolling); this->scrolling = 0; - if (pos != this->vscroll.GetPosition()) { + if (pos != this->vscroll->GetPosition()) { this->SetDirty(); } } diff --git a/src/window.cpp b/src/window.cpp --- a/src/window.cpp +++ b/src/window.cpp @@ -139,9 +139,9 @@ const Scrollbar *Window::GetScrollbar(ui { const NWidgetLeaf *wid = this->GetWidget(widnum); switch (wid->type) { - case WWT_HSCROLLBAR: return &this->hscroll; - case WWT_SCROLLBAR: return &this->vscroll; - case WWT_SCROLL2BAR: return &this->vscroll2; + case WWT_HSCROLLBAR: return &this->old_hscroll; + case WWT_SCROLLBAR: return &this->old_vscroll; + case WWT_SCROLL2BAR: return &this->old_vscroll2; default: NOT_REACHED(); } } @@ -155,9 +155,9 @@ Scrollbar *Window::GetScrollbar(uint wid { NWidgetLeaf *wid = this->GetWidget(widnum); switch (wid->type) { - case WWT_HSCROLLBAR: return &this->hscroll; - case WWT_SCROLLBAR: return &this->vscroll; - case WWT_SCROLL2BAR: return &this->vscroll2; + case WWT_HSCROLLBAR: return &this->old_hscroll; + case WWT_SCROLLBAR: return &this->old_vscroll; + case WWT_SCROLL2BAR: return &this->old_vscroll2; default: NOT_REACHED(); } } @@ -1349,7 +1349,7 @@ void Window::InitNested(const WindowDesc } /** Empty constructor, initialization has been moved to #InitNested() called from the constructor of the derived class. */ -Window::Window() : hscroll(false), vscroll(true), vscroll2(true) +Window::Window() : old_hscroll(false), old_vscroll(true), old_vscroll2(true) { } @@ -1885,14 +1885,14 @@ static EventState HandleScrollbarScrolli bool rtl = false; if (w->flags4 & WF_HSCROLL) { - sb = &w->hscroll; + sb = &w->old_hscroll; i = _cursor.pos.x - _cursorpos_drag_start.x; rtl = _dynlang.text_dir == TD_RTL; } else if (w->flags4 & WF_SCROLL2) { - sb = &w->vscroll2; + sb = &w->old_vscroll2; i = _cursor.pos.y - _cursorpos_drag_start.y; } else { - sb = &w->vscroll; + sb = &w->old_vscroll; i = _cursor.pos.y - _cursorpos_drag_start.y; } diff --git a/src/window_gui.h b/src/window_gui.h --- a/src/window_gui.h +++ b/src/window_gui.h @@ -382,9 +382,9 @@ public: int width; ///< width of the window (number of pixels to the right in x direction) int height; ///< Height of the window (number of pixels down in y direction) - Scrollbar hscroll; ///< Horizontal scroll bar - Scrollbar vscroll; ///< First vertical scroll bar - Scrollbar vscroll2; ///< Second vertical scroll bar + Scrollbar old_hscroll; ///< Horizontal scroll bar + Scrollbar old_vscroll; ///< First vertical scroll bar + Scrollbar old_vscroll2; ///< Second vertical scroll bar ResizeInfo resize; ///< Resize information Owner owner; ///< The owner of the content shown in this window. Company colour is acquired from this variable. @@ -412,7 +412,7 @@ public: void InitNested(const WindowDesc *desc, WindowNumber number = 0); void CreateNestedTree(const WindowDesc *desc, bool fill_nested = true); - void FinishInitNested(const WindowDesc *desc, WindowNumber window_number); + void FinishInitNested(const WindowDesc *desc, WindowNumber window_number = 0); /** * Sets the enabled/disabled status of a widget.