mirror of https://github.com/OpenTTD/OpenTTD
Codechange: Add the universal selector widget.
parent
6006e832f2
commit
2af1065c4e
|
@ -378,6 +378,8 @@ add_files(
|
||||||
screenshot_gui.h
|
screenshot_gui.h
|
||||||
screenshot.cpp
|
screenshot.cpp
|
||||||
screenshot.h
|
screenshot.h
|
||||||
|
selector_gui.cpp
|
||||||
|
selector_gui.h
|
||||||
settings.cpp
|
settings.cpp
|
||||||
settings_cmd.h
|
settings_cmd.h
|
||||||
settings_func.h
|
settings_func.h
|
||||||
|
|
|
@ -619,18 +619,18 @@ STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}Cargo Pa
|
||||||
STR_GRAPH_CARGO_PAYMENT_RATES_DAYS :{TINY_FONT}{BLACK}Days in transit
|
STR_GRAPH_CARGO_PAYMENT_RATES_DAYS :{TINY_FONT}{BLACK}Days in transit
|
||||||
STR_GRAPH_CARGO_PAYMENT_RATES_SECONDS :{TINY_FONT}{BLACK}Seconds in transit
|
STR_GRAPH_CARGO_PAYMENT_RATES_SECONDS :{TINY_FONT}{BLACK}Seconds in transit
|
||||||
STR_GRAPH_CARGO_PAYMENT_RATES_TITLE :{TINY_FONT}{BLACK}Payment for delivering 10 units (or 10,000 litres) of cargo a distance of 20 squares
|
STR_GRAPH_CARGO_PAYMENT_RATES_TITLE :{TINY_FONT}{BLACK}Payment for delivering 10 units (or 10,000 litres) of cargo a distance of 20 squares
|
||||||
STR_GRAPH_CARGO_ENABLE_ALL :{TINY_FONT}{BLACK}Enable all
|
|
||||||
STR_GRAPH_CARGO_DISABLE_ALL :{TINY_FONT}{BLACK}Disable all
|
# Selector widget
|
||||||
STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL :{BLACK}Display all cargoes on the cargo payment rates graph
|
STR_SELECTOR_WIDGET_ALL :{BLACK}All
|
||||||
STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}Display no cargoes on the cargo payment rates graph
|
STR_SELECTOR_WIDGET_NONE :{BLACK}None
|
||||||
STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}Toggle graph of this cargo type
|
STR_SELECTOR_WIDGET_TOOLTIP_ALL :{BLACK}Display all of the items in the list
|
||||||
STR_GRAPH_CARGO_PAYMENT_CARGO :{TINY_FONT}{BLACK}{STRING}
|
STR_SELECTOR_WIDGET_TOOLTIP_NONE :{BLACK}Display none of the items in the list
|
||||||
|
|
||||||
STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP :{BLACK}Show detailed performance ratings
|
STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP :{BLACK}Show detailed performance ratings
|
||||||
|
|
||||||
# Graph key window
|
# Graph key window
|
||||||
STR_GRAPH_KEY_CAPTION :{WHITE}Key to company graphs
|
STR_GRAPH_KEY_CAPTION :{WHITE}Key to company graphs
|
||||||
STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP :{BLACK}Toggle graph of this company
|
STR_GRAPH_CARGO_KEY_CAPTION :{WHITE}Key to cargo graphs
|
||||||
|
|
||||||
# Company league window
|
# Company league window
|
||||||
STR_COMPANY_LEAGUE_TABLE_CAPTION :{WHITE}Company League Table
|
STR_COMPANY_LEAGUE_TABLE_CAPTION :{WHITE}Company League Table
|
||||||
|
|
|
@ -0,0 +1,375 @@
|
||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file selector_gui.cpp A composable selector widget. */
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "company_base.h"
|
||||||
|
#include "company_gui.h"
|
||||||
|
#include "strings_func.h"
|
||||||
|
#include "table/sprites.h"
|
||||||
|
#include "selector_gui.h"
|
||||||
|
#include "widget_type.h"
|
||||||
|
#include "widgets/selector_widget.h"
|
||||||
|
#include "zoom_func.h"
|
||||||
|
|
||||||
|
#include "safeguards.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new NWidgetBase with all the widgets needed by the SelectorWidget widget
|
||||||
|
* This function is made to be passed in NWidgetFunction, when creating UI for a parent window
|
||||||
|
* @see NWidgetFunction
|
||||||
|
*/
|
||||||
|
std::unique_ptr<NWidgetBase> SelectorWidget::MakeSelectorWidgetUI()
|
||||||
|
{
|
||||||
|
static constexpr NWidgetPart widget_ui[] = {
|
||||||
|
NWidget(WWT_PANEL, COLOUR_BROWN),
|
||||||
|
NWidget(WWT_EDITBOX, COLOUR_BROWN, WID_SELECTOR_EDITBOX), SetFill(1, 0), SetResize(1, 0), SetPadding(2),
|
||||||
|
SetDataTip(STR_LIST_FILTER_TOOLTIP, STR_LIST_FILTER_TOOLTIP),
|
||||||
|
EndContainer(),
|
||||||
|
NWidget(NWID_VERTICAL),
|
||||||
|
NWidget(NWID_HORIZONTAL),
|
||||||
|
NWidget(WWT_MATRIX, COLOUR_BROWN, WID_SELECTOR_MATRIX),
|
||||||
|
SetScrollbar(WID_SELECTOR_SCROLLBAR), SetResize(1, 1), SetMatrixDataTip(1, 0, STR_NULL), SetFill(1, 1),
|
||||||
|
NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_SELECTOR_SCROLLBAR),
|
||||||
|
EndContainer(),
|
||||||
|
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
||||||
|
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_SELECTOR_SHOWALL),
|
||||||
|
SetDataTip(STR_SELECTOR_WIDGET_ALL, STR_SELECTOR_WIDGET_TOOLTIP_ALL), SetResize(1, 0), SetFill(1, 0),
|
||||||
|
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_SELECTOR_HIDEALL),
|
||||||
|
SetDataTip(STR_SELECTOR_WIDGET_NONE, STR_SELECTOR_WIDGET_TOOLTIP_NONE), SetResize(1, 0), SetFill(1, 0),
|
||||||
|
NWidget(WWT_RESIZEBOX, COLOUR_BROWN, WID_SELECTOR_RESIZE), SetDataTip(RWV_SHOW_BEVEL, STR_TOOLTIP_RESIZE), SetResize(0, 0),
|
||||||
|
EndContainer(),
|
||||||
|
EndContainer(),
|
||||||
|
};
|
||||||
|
return MakeNWidgets(widget_ui, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector widget initialization function
|
||||||
|
* This function is meant to be called after CreateNestedTree() of the parent window
|
||||||
|
*
|
||||||
|
* @param w The parent window of this widget.
|
||||||
|
*/
|
||||||
|
void SelectorWidget::Init(Window *w)
|
||||||
|
{
|
||||||
|
this->parent_window = w;
|
||||||
|
this->vscroll = w->GetScrollbar(WID_SELECTOR_SCROLLBAR);
|
||||||
|
assert(this->vscroll != nullptr);
|
||||||
|
RebuildList();
|
||||||
|
w->querystrings[WID_SELECTOR_EDITBOX] = &this->editbox;
|
||||||
|
this->vscroll->SetCount(this->filtered_list.size());
|
||||||
|
this->vscroll->SetCapacityFromWidget(w, WID_SELECTOR_MATRIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector widget's OnClick event handler
|
||||||
|
* This function is meant to be called from the parent's window's OnClick
|
||||||
|
* Event handler
|
||||||
|
*
|
||||||
|
* @param pt The click coordinate.
|
||||||
|
* @param widget The id of the targeted widget.
|
||||||
|
* @param click_count The number of clicks.
|
||||||
|
*
|
||||||
|
* All of these parameters should be passed straight from the parent's window's OnClick
|
||||||
|
* Event handler, without any changes, or conditional checks
|
||||||
|
*
|
||||||
|
* @see Window::OnClick()
|
||||||
|
*/
|
||||||
|
void SelectorWidget::OnClick(Point pt, WidgetID widget, [[maybe_unused]]int click_count)
|
||||||
|
{
|
||||||
|
switch (widget) {
|
||||||
|
case WID_SELECTOR_HIDEALL:
|
||||||
|
for (uint i = 0; i < this->shown.size(); i++) {
|
||||||
|
this->shown[i] = false;
|
||||||
|
}
|
||||||
|
this->OnChanged();
|
||||||
|
this->parent_window->InvalidateData(0, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WID_SELECTOR_SHOWALL:
|
||||||
|
for (uint i = 0; i < this->shown.size(); i++) {
|
||||||
|
this->shown[i] = true;
|
||||||
|
}
|
||||||
|
this->OnChanged();
|
||||||
|
this->parent_window->InvalidateData(0, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WID_SELECTOR_MATRIX: {
|
||||||
|
size_t pos = vscroll->GetScrolledRowFromWidget(pt.y, this->parent_window, widget);
|
||||||
|
|
||||||
|
/* Check if the click was out of range. */
|
||||||
|
if (pos >= filtered_list.size()) return;
|
||||||
|
int id = this->filtered_list[pos];
|
||||||
|
|
||||||
|
this->shown[id].flip();
|
||||||
|
this->OnChanged();
|
||||||
|
this->parent_window->InvalidateData(0, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectorWidget::OnMouseOver(Point pt, WidgetID widget)
|
||||||
|
{
|
||||||
|
if (widget != WID_SELECTOR_MATRIX) return;
|
||||||
|
|
||||||
|
auto it = vscroll->GetScrolledItemFromWidget(this->filtered_list, pt.y, this->parent_window, widget);
|
||||||
|
/* Check if the hover was out of range. */
|
||||||
|
if (it == this->filtered_list.end()) return;
|
||||||
|
|
||||||
|
/* Check if the selection actually changed. */
|
||||||
|
if (*it == this->selected_id) return;
|
||||||
|
|
||||||
|
this->selected_id = *it;
|
||||||
|
|
||||||
|
this->OnChanged();
|
||||||
|
this->parent_window->InvalidateData(0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector widget's OnInvalidateData event handler
|
||||||
|
* This function is meant to be called from the parent's window's OnInvalidateData
|
||||||
|
* Event handler. This function will do nothing when runnning ouside of the gui scope.
|
||||||
|
*
|
||||||
|
* @param data Information about the changed data.
|
||||||
|
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
||||||
|
*
|
||||||
|
* All of these parameters should be passed straight from the parent's window's OnInvalidateData
|
||||||
|
* Event handler, without any changes, or conditional checks
|
||||||
|
*
|
||||||
|
* @see Window::OnInvalidateData()
|
||||||
|
*/
|
||||||
|
void SelectorWidget::OnInvalidateData([[maybe_unused]] int data, bool gui_scope)
|
||||||
|
{
|
||||||
|
if (!gui_scope) return;
|
||||||
|
RebuildList();
|
||||||
|
this->vscroll->SetCount(this->filtered_list.size());
|
||||||
|
this->vscroll->SetCapacityFromWidget(parent_window, WID_SELECTOR_MATRIX);
|
||||||
|
|
||||||
|
/* This does not assume that the IDs must be contiguous. */
|
||||||
|
auto it = std::find(std::begin(this->filtered_list), std::end(this->filtered_list), this->selected_id);
|
||||||
|
|
||||||
|
if (it != std::end(this->filtered_list)) {
|
||||||
|
int selected_pos = std::distance(std::begin(this->filtered_list), it);
|
||||||
|
this->vscroll->ScrollTowards(selected_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector widget's UpdateWidgetSize method
|
||||||
|
* This function is meant to be called from the parent's window's UpdateWidgetSize method
|
||||||
|
*
|
||||||
|
* @param widget Widget number.
|
||||||
|
* @param[In,out] size Size of the widget.
|
||||||
|
* @param padding Recommended amount of space between the widget content and the widget edge.
|
||||||
|
* @param[In,out] fill Fill step of the widget.
|
||||||
|
* @param[In,out] resize Resize step of the widget.
|
||||||
|
*
|
||||||
|
* All of these parameters should be passed straight from the parent's window's UpdateWidgetSize
|
||||||
|
* method, without any changes, or conditional checks.
|
||||||
|
*
|
||||||
|
* @see Window::UpdateWidgetSize()
|
||||||
|
*/
|
||||||
|
void SelectorWidget::UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize)
|
||||||
|
{
|
||||||
|
if (widget != WID_SELECTOR_MATRIX) return;
|
||||||
|
|
||||||
|
const int min_rows = 11; ///< The minimal number of rows shown
|
||||||
|
const int min_width = ScaleGUITrad(100); ///< The minimal width of the widget
|
||||||
|
|
||||||
|
|
||||||
|
this->row_height = GetCharacterHeight(FS_NORMAL) + padding.height;
|
||||||
|
|
||||||
|
size.height = this->row_height * min_rows;
|
||||||
|
size.width = min_width;
|
||||||
|
resize.width = 1;
|
||||||
|
resize.height = this->row_height;
|
||||||
|
fill.width = 1;
|
||||||
|
fill.height = this->row_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector widget's OnResize event handler
|
||||||
|
* This function is meant to be called from the parent's window's OnResize
|
||||||
|
* Event handler
|
||||||
|
*
|
||||||
|
* All of these parameters should be passed straight from the parent's window's OnResize
|
||||||
|
* Event handler, without any changes, or conditional checks
|
||||||
|
*
|
||||||
|
* @see Window::OnResize()
|
||||||
|
*/
|
||||||
|
void SelectorWidget::OnResize()
|
||||||
|
{
|
||||||
|
this->vscroll->SetCapacityFromWidget(parent_window, WID_SELECTOR_MATRIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector widget's OnEditboxChanged event handler
|
||||||
|
* This function is meant to be called from the parent's window's OnEditboxChanged
|
||||||
|
* Event handler
|
||||||
|
*
|
||||||
|
* @param wid The widget id of the editbox.
|
||||||
|
*
|
||||||
|
* All of these parameters should be passed straight from the parent's window's OnEditboxChanged
|
||||||
|
* Event handler, without any changes, or conditional checks
|
||||||
|
*
|
||||||
|
* @see Window::OnEditboxChanged()
|
||||||
|
*/
|
||||||
|
void SelectorWidget::OnEditboxChanged(WidgetID wid)
|
||||||
|
{
|
||||||
|
if (wid != WID_SELECTOR_EDITBOX) return;
|
||||||
|
|
||||||
|
this->string_filter.SetFilterTerm(this->editbox.text.buf);
|
||||||
|
this->parent_window->InvalidateData(0);
|
||||||
|
this->vscroll->SetCount(this->filtered_list.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector widget's DrawWidget method
|
||||||
|
* This function is meant to be called from the parent's window's DrawWidget
|
||||||
|
* method
|
||||||
|
*
|
||||||
|
* @param widget Widget number.
|
||||||
|
* @param[In,out] size Size of the widget.
|
||||||
|
* @param padding Recommended amount of space between the widget content and the widget edge.
|
||||||
|
* @param[In,out] fill Fill step of the widget.
|
||||||
|
* @param[In,out] resize Resize step of the widget.
|
||||||
|
*
|
||||||
|
* All of these parameters should be passed straight from the parent's window's DrawWidget
|
||||||
|
* Event handler, without any changes, or conditional checks
|
||||||
|
*
|
||||||
|
* This function calls a profile defined function this->profile.DrawSection(),
|
||||||
|
* that actually draws the fields
|
||||||
|
*
|
||||||
|
* @see Window::DrawWidget()
|
||||||
|
* @see SelectorWidget::Profile
|
||||||
|
*/
|
||||||
|
void SelectorWidget::DrawWidget(const Rect &r, WidgetID widget)
|
||||||
|
{
|
||||||
|
if (widget != WID_SELECTOR_MATRIX) return;
|
||||||
|
|
||||||
|
Rect line = r.WithHeight(row_height);
|
||||||
|
|
||||||
|
auto [first, last] = this->vscroll->GetVisibleRangeIterators(filtered_list);
|
||||||
|
|
||||||
|
for (auto it = first; it != last; ++it) {
|
||||||
|
const Rect ir = line.Shrink(WidgetDimensions::scaled.framerect);
|
||||||
|
|
||||||
|
if (this->shown[*it]) {
|
||||||
|
DrawFrameRect(line, COLOUR_BROWN, FR_LOWERED);
|
||||||
|
}
|
||||||
|
this->DrawSection(*it, ir.Shrink(WidgetDimensions::scaled.matrix));
|
||||||
|
|
||||||
|
line = line.Translate(0, row_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function that updates and rebuilds the list of selectable items
|
||||||
|
* This function calls a profile defined function this->profile.RebuildList(),
|
||||||
|
* that actually rebuilds the list of items.
|
||||||
|
*
|
||||||
|
* It is also manages the shown items and the filtered_list lists
|
||||||
|
*
|
||||||
|
* @see SelectorWidget::Profile
|
||||||
|
*/
|
||||||
|
void SelectorWidget::RebuildList()
|
||||||
|
{
|
||||||
|
this->list.clear();
|
||||||
|
this->filtered_list.clear();
|
||||||
|
this->PopulateList();
|
||||||
|
uint32_t max = *std::max_element(std::begin(this->list), std::end(this->list));
|
||||||
|
|
||||||
|
this->shown.reserve(max);
|
||||||
|
for (size_t i = this->shown.size(); i <= max ; i++) {
|
||||||
|
this->shown.push_back(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* virtual */ void CargoSelectorWidget::PopulateList()
|
||||||
|
{
|
||||||
|
for (const CargoSpec *cargo : _sorted_standard_cargo_specs){
|
||||||
|
this->list.push_back(cargo->Index());
|
||||||
|
if (this->string_filter.IsEmpty()) {
|
||||||
|
this->filtered_list.push_back(cargo->Index());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this->string_filter.ResetState();
|
||||||
|
|
||||||
|
SetDParam(0, cargo->name);
|
||||||
|
this->string_filter.AddLine(GetString(STR_JUST_STRING));
|
||||||
|
|
||||||
|
if (this->string_filter.GetState()) {
|
||||||
|
this->filtered_list.push_back(cargo->Index());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* virtual */ void CargoSelectorWidget::DrawSection(uint id, const Rect &r)
|
||||||
|
{
|
||||||
|
const CargoID cargo_id = static_cast<CargoID>(id); ///< CargoID of the current row's cargo
|
||||||
|
const CargoSpec *cargo = CargoSpec::Get(id); ///< CargoSpec of the current row's cargo
|
||||||
|
|
||||||
|
const bool rtl = _current_text_dir == TD_RTL;
|
||||||
|
|
||||||
|
int legend_height = GetCharacterHeight(FS_SMALL);
|
||||||
|
int legend_width = legend_height * 9 / 6;
|
||||||
|
|
||||||
|
Rect cargo_swatch = r.WithWidth(legend_width, rtl);
|
||||||
|
cargo_swatch.top = CenterBounds(r.top, r.bottom, legend_height) - 1;
|
||||||
|
cargo_swatch.bottom = cargo_swatch.top + legend_height;
|
||||||
|
|
||||||
|
/* Cargo-colour box with outline. */
|
||||||
|
GfxFillRect(cargo_swatch, PC_BLACK);
|
||||||
|
GfxFillRect(cargo_swatch.Shrink(WidgetDimensions::scaled.bevel), cargo->legend_colour);
|
||||||
|
|
||||||
|
/* Cargo name. */
|
||||||
|
SetDParam(0, cargo->name);
|
||||||
|
const Rect text = r.Indent(legend_width + WidgetDimensions::scaled.hsep_wide, rtl);
|
||||||
|
|
||||||
|
const TextColour colour = (this->selected_id.value_or(INVALID_OWNER) == cargo_id) ? TC_WHITE : TC_BLACK;
|
||||||
|
DrawString(text.left, text.right, CenterBounds(text.top, text.bottom, GetCharacterHeight(FS_NORMAL)), STR_JUST_STRING, colour);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* virtual */ void CompanySelectorWidget::PopulateList()
|
||||||
|
{
|
||||||
|
for (const Company *c: Company::Iterate()) {
|
||||||
|
this->list.push_back(c->index);
|
||||||
|
if (this->string_filter.IsEmpty()) {
|
||||||
|
this->filtered_list.push_back(c->index);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this->string_filter.ResetState();
|
||||||
|
|
||||||
|
SetDParam(0, c->index);
|
||||||
|
this->string_filter.AddLine(GetString(STR_COMPANY_NAME));
|
||||||
|
|
||||||
|
if (this->string_filter.GetState()) {
|
||||||
|
this->filtered_list.push_back(c->index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* virtual */ void CompanySelectorWidget::DrawSection(uint id, const Rect &r)
|
||||||
|
{
|
||||||
|
const CompanyID cid = static_cast<CompanyID>(id);
|
||||||
|
assert(Company::IsValidID(cid));
|
||||||
|
|
||||||
|
const bool rtl = _current_text_dir == TD_RTL;
|
||||||
|
const Dimension icon_size = GetSpriteSize(SPR_COMPANY_ICON);
|
||||||
|
|
||||||
|
DrawCompanyIcon(cid, rtl ? r.right - icon_size.width : r.left, CenterBounds(r.top, r.bottom, icon_size.height));
|
||||||
|
|
||||||
|
const Rect text = r.Indent(icon_size.width + WidgetDimensions::scaled.hsep_wide, rtl);
|
||||||
|
|
||||||
|
SetDParam(0, cid);
|
||||||
|
|
||||||
|
const TextColour colour = (this->selected_id.value_or(INVALID_OWNER) == cid) ? TC_WHITE : TC_BLACK;
|
||||||
|
DrawString(text.left, text.right, CenterBounds(text.top, text.bottom, GetCharacterHeight(FS_NORMAL)), STR_COMPANY_NAME, colour);
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file selector_gui.h Functions/types etc. related to the selector widget. */
|
||||||
|
|
||||||
|
#ifndef SELECTOR_GUI_H
|
||||||
|
#define SELECTOR_GUI_H
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "querystring_gui.h"
|
||||||
|
#include "stringfilter_type.h"
|
||||||
|
#include "strings_type.h"
|
||||||
|
#include "widget_type.h"
|
||||||
|
#include "window_gui.h"
|
||||||
|
#include "window_type.h"
|
||||||
|
#include "safeguards.h"
|
||||||
|
|
||||||
|
struct SelectorWidget {
|
||||||
|
|
||||||
|
std::optional<int> selected_id; ///< ID of the currently selected item
|
||||||
|
std::vector<bool> shown; ///< A vector that determines which items are shown e.g on the graph. Not to be confused with filtered_list
|
||||||
|
std::vector<uint32_t> list; ///< A list of all the items
|
||||||
|
StringFilter string_filter; ///< The filter that checks wether an item should be displayed based on the editbox
|
||||||
|
|
||||||
|
/** A list of items displayed in WID_SELECTION_MATRIX after the editbox filtering
|
||||||
|
* It is a strict subset of SelectorWidget::list */
|
||||||
|
std::vector<uint32_t> filtered_list;
|
||||||
|
|
||||||
|
static std::unique_ptr<NWidgetBase> MakeSelectorWidgetUI();
|
||||||
|
|
||||||
|
void Init(Window *w);
|
||||||
|
void OnClick(Point pt, WidgetID widget, int click_count);
|
||||||
|
void OnMouseOver(Point pt, WidgetID widget);
|
||||||
|
void OnInvalidateData(int data, bool gui_scope);
|
||||||
|
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize);
|
||||||
|
void OnResize();
|
||||||
|
void OnEditboxChanged(WidgetID wid);
|
||||||
|
void DrawWidget(const Rect &r, WidgetID widget);
|
||||||
|
void RebuildList();
|
||||||
|
|
||||||
|
virtual ~SelectorWidget() {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
Window *parent_window; ///< The parent window pointer
|
||||||
|
|
||||||
|
int row_height; ///< The height of 1 row in the WID_SELECTOR_MATRIX widget
|
||||||
|
|
||||||
|
Scrollbar *vscroll; ///< The vertical scrollbar
|
||||||
|
|
||||||
|
/** A QueryString modifiable by the WID_SELECTOR_EDITBOX widget */
|
||||||
|
QueryString editbox{MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH, MAX_LENGTH_COMPANY_NAME_CHARS};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws "section" (line) of the scrollable list.
|
||||||
|
* Called by #DrawWidget
|
||||||
|
* @param id The "id" of the item to be drawn, can mean different things depending on what the selector widget is displaying.
|
||||||
|
* e.g when this widget displays companies, the id is a unique and valid CompanyID
|
||||||
|
* @param r The rectangle where the item is to be drawn.
|
||||||
|
*
|
||||||
|
* @see CargoSelectorWidget::DrawSection()
|
||||||
|
* @see CompanySelectorWidget::DrawSection()
|
||||||
|
* @see SelectorWidget::PopulateList()
|
||||||
|
* @see SelectorWidget::DrawWidget()
|
||||||
|
*/
|
||||||
|
virtual void DrawSection(uint id, const Rect &r) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repopulates the list that the widget uses to keep track of different selectable items
|
||||||
|
* @see CargoSelectorWidget::PopulateList()
|
||||||
|
* @see CompanySelectorWidget::PopulateList()
|
||||||
|
*/
|
||||||
|
virtual void PopulateList() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the widget selection or visibility of some item is changed.
|
||||||
|
* Used to update things that depend on the selector widget's data.
|
||||||
|
*/
|
||||||
|
virtual void OnChanged() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CargoSelectorWidget : SelectorWidget {
|
||||||
|
virtual void DrawSection(uint id, const Rect &r) override;
|
||||||
|
virtual void PopulateList() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CompanySelectorWidget : SelectorWidget {
|
||||||
|
virtual void DrawSection(uint id, const Rect &r) override;
|
||||||
|
virtual void PopulateList() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* SELECTOR_GUI_H */
|
|
@ -45,6 +45,7 @@ add_files(
|
||||||
screenshot_widget.h
|
screenshot_widget.h
|
||||||
script_widget.h
|
script_widget.h
|
||||||
settings_widget.h
|
settings_widget.h
|
||||||
|
selector_widget.h
|
||||||
sign_widget.h
|
sign_widget.h
|
||||||
smallmap_widget.h
|
smallmap_widget.h
|
||||||
station_widget.h
|
station_widget.h
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file selector_widget.h Types related to the selector widget widgets. */
|
||||||
|
|
||||||
|
#ifndef WIDGETS_SELECTOR_WIDGET_H
|
||||||
|
#define WIDGETS_SELECTOR_WIDGET_H
|
||||||
|
|
||||||
|
/** Widgets of the #SelectorWidget class. */
|
||||||
|
enum SelectorClassWindowWidgets : WidgetID {
|
||||||
|
WID_SELECTOR_START = (1 << 16) + 1000, ///< Dummy to ensure widgets don't overlap.
|
||||||
|
|
||||||
|
WID_SELECTOR_MATRIX, ///< Item list.
|
||||||
|
WID_SELECTOR_SCROLLBAR, ///< Vertical scrollbar.
|
||||||
|
WID_SELECTOR_EDITBOX, ///< Editbox filter.
|
||||||
|
WID_SELECTOR_HIDEALL, ///< Hide all button.
|
||||||
|
WID_SELECTOR_SHOWALL, ///< Show all button.
|
||||||
|
WID_SELECTOR_RESIZE, ///< Resize handle
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* WIDGETS_SELECTOR_WIDGET_H */
|
Loading…
Reference in New Issue