1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-20 21:43:06 +01:00

Implement horizontal scrollbars and fix resizing

This commit is contained in:
Ted John
2020-05-09 17:09:47 +01:00
parent 41950d75f0
commit f492827c8a
3 changed files with 64 additions and 30 deletions

View File

@@ -14,6 +14,7 @@
# include "../interface/Widget.h"
# include "../interface/Window.h"
# include <numeric>
# include <openrct2/Context.h>
# include <openrct2/localisation/Localisation.h>
# include <openrct2/util/Util.h>
@@ -205,28 +206,32 @@ ScrollbarType CustomListView::GetScrollbars() const
return Scrollbars;
}
void CustomListView::SetScrollbars(ScrollbarType value)
void CustomListView::SetScrollbars(ScrollbarType value, bool initialising)
{
Scrollbars = value;
size_t scrollIndex = 0;
for (auto widget = ParentWindow->widgets; widget->type != WWT_LAST; widget++)
if (!initialising)
{
if (widget->type == WWT_SCROLL)
size_t scrollIndex = 0;
for (auto widget = ParentWindow->widgets; widget->type != WWT_LAST; widget++)
{
if (scrollIndex == ScrollIndex)
if (widget->type == WWT_SCROLL)
{
if (value == ScrollbarType::Horizontal)
widget->content = SCROLL_HORIZONTAL;
else if (value == ScrollbarType::Vertical)
widget->content = SCROLL_VERTICAL;
else if (value == ScrollbarType::Both)
widget->content = SCROLL_BOTH;
else
widget->content = 0;
if (scrollIndex == ScrollIndex)
{
if (value == ScrollbarType::Horizontal)
widget->content = SCROLL_HORIZONTAL;
else if (value == ScrollbarType::Vertical)
widget->content = SCROLL_VERTICAL;
else if (value == ScrollbarType::Both)
widget->content = SCROLL_BOTH;
else
widget->content = 0;
}
scrollIndex++;
}
scrollIndex++;
}
window_init_scroll_widgets(ParentWindow);
}
}
@@ -235,12 +240,14 @@ const std::vector<ListViewColumn>& CustomListView::GetColumns() const
return Columns;
}
void CustomListView::SetColumns(const std::vector<ListViewColumn>& columns)
void CustomListView::SetColumns(const std::vector<ListViewColumn>& columns, bool initialising)
{
SelectedCell = std::nullopt;
Columns = columns;
LastKnownSize = {};
SortItems(0, ColumnSortOrder::None);
if (!initialising)
window_init_scroll_widgets(ParentWindow);
}
const std::vector<ListViewItem>& CustomListView::CustomListView::GetItems() const
@@ -248,17 +255,21 @@ const std::vector<ListViewItem>& CustomListView::CustomListView::GetItems() cons
return Items;
}
void CustomListView::SetItems(const std::vector<ListViewItem>& items)
void CustomListView::SetItems(const std::vector<ListViewItem>& items, bool initialising)
{
SelectedCell = std::nullopt;
Items = items;
SortItems(0, ColumnSortOrder::None);
if (!initialising)
window_update_scroll_widgets(ParentWindow);
}
void CustomListView::SetItems(std::vector<ListViewItem>&& items)
void CustomListView::SetItems(std::vector<ListViewItem>&& items, bool initialising)
{
Items = items;
SortItems(0, ColumnSortOrder::None);
if (!initialising)
window_init_scroll_widgets(ParentWindow);
}
bool CustomListView::SortItem(size_t indexA, size_t indexB, int32_t column)
@@ -328,11 +339,13 @@ void CustomListView::Resize(const ScreenSize& size)
}
// Calculate column widths
bool hasHorizontalScroll = Scrollbars == ScrollbarType::Horizontal || Scrollbars == ScrollbarType::Both;
int32_t widthRemaining = size.width;
for (size_t c = 0; c < Columns.size(); c++)
{
auto& column = Columns[c];
if (c == Columns.size() - 1)
auto isLastColumn = c == Columns.size() - 1;
if (!hasHorizontalScroll && isLastColumn)
{
column.Width = widthRemaining;
}
@@ -341,7 +354,14 @@ void CustomListView::Resize(const ScreenSize& size)
column.Width = 0;
if (column.RatioWidth && *column.RatioWidth > 0)
{
column.Width = (size.width * *column.RatioWidth) / totalRatio;
if (isLastColumn)
{
column.Width = widthRemaining;
}
else
{
column.Width = (size.width * *column.RatioWidth) / totalRatio;
}
}
if (column.MinWidth)
{
@@ -352,8 +372,10 @@ void CustomListView::Resize(const ScreenSize& size)
column.Width = std::min(column.Width, *column.MaxWidth);
}
}
widthRemaining -= column.Width;
widthRemaining = std::max(0, widthRemaining - column.Width);
}
window_init_scroll_widgets(ParentWindow);
}
ScreenSize CustomListView::GetSize()
@@ -365,8 +387,18 @@ ScreenSize CustomListView::GetSize()
IsMouseDown = false;
ScreenSize result;
result.width = 0;
result.height = static_cast<int32_t>(Items.size() * LIST_ROW_HEIGHT);
if (Scrollbars == ScrollbarType::Horizontal || Scrollbars == ScrollbarType::Both)
{
result.width = std::accumulate(
Columns.begin(), Columns.end(), 0, [](int32_t acc, const ListViewColumn& column) { return acc + column.Width; });
// Fixes an off-by-one error that causes the scrollbar thumb to not fill when the widget is wide enough
result.width--;
}
if (Scrollbars == ScrollbarType::Vertical || Scrollbars == ScrollbarType::Both)
{
result.height = static_cast<int32_t>(Items.size() * LIST_ROW_HEIGHT);
}
return result;
}

View File

@@ -121,12 +121,12 @@ namespace OpenRCT2::Ui::Windows
CustomListView(rct_window* parent, size_t scrollIndex);
ScrollbarType GetScrollbars() const;
void SetScrollbars(ScrollbarType value);
void SetScrollbars(ScrollbarType value, bool initialising = false);
const std::vector<ListViewColumn>& GetColumns() const;
void SetColumns(const std::vector<ListViewColumn>& columns);
void SetColumns(const std::vector<ListViewColumn>& columns, bool initialising = false);
const std::vector<ListViewItem>& GetItems() const;
void SetItems(const std::vector<ListViewItem>& items);
void SetItems(std::vector<ListViewItem>&& items);
void SetItems(const std::vector<ListViewItem>& items, bool initialising = false);
void SetItems(std::vector<ListViewItem>&& items, bool initialising = false);
bool SortItem(size_t indexA, size_t indexB, int32_t column);
void SortItems(int32_t column);
void SortItems(int32_t column, ColumnSortOrder order);

View File

@@ -417,8 +417,6 @@ namespace OpenRCT2::Ui::Windows
window->max_height = desc.MaxHeight.value_or(std::numeric_limits<uint16_t>::max());
}
RefreshWidgets(window);
window_init_scroll_widgets(window);
window_custom_update_viewport(window);
return window;
}
@@ -983,8 +981,9 @@ namespace OpenRCT2::Ui::Windows
if (widgetDesc.Type == "listview")
{
CustomListView listView(w, info.ListViews.size());
listView.SetColumns(widgetDesc.ListViewColumns);
listView.SetItems(widgetDesc.ListViewItems);
listView.SetScrollbars(widgetDesc.Scrollbars, true);
listView.SetColumns(widgetDesc.ListViewColumns, true);
listView.SetItems(widgetDesc.ListViewItems, true);
listView.ShowColumnHeaders = widgetDesc.ShowColumnHeaders;
listView.IsStriped = widgetDesc.IsStriped;
listView.OnClick = widgetDesc.OnClick;
@@ -1014,6 +1013,9 @@ namespace OpenRCT2::Ui::Windows
widgets.push_back({ WIDGETS_END });
w->widgets = widgets.data();
window_init_scroll_widgets(w);
window_custom_update_viewport(w);
}
static void InvokeEventHandler(const std::shared_ptr<Plugin>& owner, const DukValue& dukHandler)