From 41950d75f08acd467dbebee5fdb3bd00ccb59684 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 9 May 2020 16:06:21 +0100 Subject: [PATCH] Implement scrollbars field on list view --- distribution/openrct2.d.ts | 4 +- src/openrct2-ui/scripting/CustomListView.cpp | 66 ++++++++++++++++++++ src/openrct2-ui/scripting/CustomListView.h | 10 ++- src/openrct2-ui/scripting/CustomWindow.cpp | 19 ++++-- src/openrct2-ui/scripting/ScWidget.hpp | 22 +++++++ 5 files changed, 114 insertions(+), 7 deletions(-) diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index ce6310469f..b2f6fc644a 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -1074,7 +1074,7 @@ declare global { type SortOrder = "none" | "ascending" | "descending"; - type ScrollType = "none" | "horizontal" | "vertical" | "both"; + type ScrollbarType = "none" | "horizontal" | "vertical" | "both"; interface ListViewColumn { canSort?: boolean; @@ -1095,7 +1095,7 @@ declare global { } interface ListView extends Widget { - scroll?: ScrollType; + scrollbars?: ScrollbarType; isStriped?: boolean; showColumnHeaders?: boolean; columns?: ListViewColumn[]; diff --git a/src/openrct2-ui/scripting/CustomListView.cpp b/src/openrct2-ui/scripting/CustomListView.cpp index bda9302dea..b66e10cc15 100644 --- a/src/openrct2-ui/scripting/CustomListView.cpp +++ b/src/openrct2-ui/scripting/CustomListView.cpp @@ -11,6 +11,7 @@ # include "CustomListView.h" +# include "../interface/Widget.h" # include "../interface/Window.h" # include @@ -162,8 +163,73 @@ namespace OpenRCT2::Scripting obj.Set("column", value.Column); return obj.Take(); } + + template<> ScrollbarType FromDuk(const DukValue& d) + { + auto value = AsOrDefault(d, ""); + if (value == "horizontal") + return ScrollbarType::Horizontal; + if (value == "vertical") + return ScrollbarType::Vertical; + if (value == "both") + return ScrollbarType::Both; + return ScrollbarType::None; + } + + template<> DukValue ToDuk(duk_context* ctx, const ScrollbarType& value) + { + switch (value) + { + default: + case ScrollbarType::None: + return ToDuk(ctx, "none"); + case ScrollbarType::Horizontal: + return ToDuk(ctx, "horizontal"); + case ScrollbarType::Vertical: + return ToDuk(ctx, "vertical"); + case ScrollbarType::Both: + return ToDuk(ctx, "both"); + } + } + } // namespace OpenRCT2::Scripting +CustomListView::CustomListView(rct_window* parent, size_t scrollIndex) + : ParentWindow(parent) + , ScrollIndex(scrollIndex) +{ +} + +ScrollbarType CustomListView::GetScrollbars() const +{ + return Scrollbars; +} + +void CustomListView::SetScrollbars(ScrollbarType value) +{ + Scrollbars = value; + + size_t scrollIndex = 0; + for (auto widget = ParentWindow->widgets; widget->type != WWT_LAST; widget++) + { + if (widget->type == WWT_SCROLL) + { + 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++; + } + } +} + const std::vector& CustomListView::GetColumns() const { return Columns; diff --git a/src/openrct2-ui/scripting/CustomListView.h b/src/openrct2-ui/scripting/CustomListView.h index c4e9f69395..068690a551 100644 --- a/src/openrct2-ui/scripting/CustomListView.h +++ b/src/openrct2-ui/scripting/CustomListView.h @@ -92,8 +92,12 @@ namespace OpenRCT2::Ui::Windows { private: static constexpr int32_t HEADER_ROW = -1; + + rct_window* ParentWindow{}; + size_t ScrollIndex{}; std::vector Columns; std::vector Items; + ScrollbarType Scrollbars = ScrollbarType::Vertical; public: std::shared_ptr Owner; @@ -106,7 +110,6 @@ namespace OpenRCT2::Ui::Windows bool ShowColumnHeaders{}; bool IsStriped{}; ScreenSize LastKnownSize; - ScrollbarType Scrollbars = ScrollbarType::Vertical; ColumnSortOrder CurrentSortOrder{}; int32_t CurrentSortColumn{}; bool LastIsMouseDown{}; @@ -116,6 +119,9 @@ namespace OpenRCT2::Ui::Windows DukValue OnClick; DukValue OnHighlight; + CustomListView(rct_window* parent, size_t scrollIndex); + ScrollbarType GetScrollbars() const; + void SetScrollbars(ScrollbarType value); const std::vector& GetColumns() const; void SetColumns(const std::vector& columns); const std::vector& GetItems() const; @@ -157,6 +163,8 @@ namespace OpenRCT2::Scripting template<> std::optional FromDuk(const DukValue& d); template<> DukValue ToDuk(duk_context* ctx, const RowColumn& value); template<> DukValue ToDuk(duk_context* ctx, const ListViewColumn& value); + template<> ScrollbarType FromDuk(const DukValue& d); + template<> DukValue ToDuk(duk_context* ctx, const ScrollbarType& value); } // namespace OpenRCT2::Scripting #endif diff --git a/src/openrct2-ui/scripting/CustomWindow.cpp b/src/openrct2-ui/scripting/CustomWindow.cpp index a94e51bf1c..d18491a118 100644 --- a/src/openrct2-ui/scripting/CustomWindow.cpp +++ b/src/openrct2-ui/scripting/CustomWindow.cpp @@ -108,6 +108,7 @@ namespace OpenRCT2::Ui::Windows std::vector Items; std::vector ListViewItems; std::vector ListViewColumns; + ScrollbarType Scrollbars{}; int32_t SelectedIndex{}; bool IsChecked{}; bool IsDisabled{}; @@ -178,6 +179,10 @@ namespace OpenRCT2::Ui::Windows result.OnClick = desc["onClick"]; result.OnHighlight = desc["onHighlight"]; result.CanSelect = AsOrDefault(desc["canSelect"], false); + if (desc["scrollbars"].type() == DukValue::UNDEFINED) + result.Scrollbars = ScrollbarType::Vertical; + else + result.Scrollbars = FromDuk(desc["scrollbars"]); } else if (result.Type == "spinner") { @@ -663,11 +668,11 @@ namespace OpenRCT2::Ui::Windows auto& listView = info.ListViews[scrollIndex]; auto width = widget->right - widget->left + 1 - 2; auto height = widget->bottom - widget->top + 1 - 2; - if (listView.Scrollbars == ScrollbarType::Horizontal || listView.Scrollbars == ScrollbarType::Both) + if (listView.GetScrollbars() == ScrollbarType::Horizontal || listView.GetScrollbars() == ScrollbarType::Both) { height -= SCROLLBAR_WIDTH + 1; } - if (listView.Scrollbars == ScrollbarType::Vertical || listView.Scrollbars == ScrollbarType::Both) + if (listView.GetScrollbars() == ScrollbarType::Vertical || listView.GetScrollbars() == ScrollbarType::Both) { width -= SCROLLBAR_WIDTH + 1; } @@ -869,7 +874,13 @@ namespace OpenRCT2::Ui::Windows else if (desc.Type == "listview") { widget.type = WWT_SCROLL; - widget.text = SCROLL_VERTICAL; + widget.content = 0; + if (desc.Scrollbars == ScrollbarType::Horizontal) + widget.content = SCROLL_HORIZONTAL; + else if (desc.Scrollbars == ScrollbarType::Vertical) + widget.content = SCROLL_VERTICAL; + else if (desc.Scrollbars == ScrollbarType::Both) + widget.content = SCROLL_BOTH; widgetList.push_back(widget); } else if (desc.Type == "spinner") @@ -971,7 +982,7 @@ namespace OpenRCT2::Ui::Windows if (widgetDesc.Type == "listview") { - CustomListView listView; + CustomListView listView(w, info.ListViews.size()); listView.SetColumns(widgetDesc.ListViewColumns); listView.SetItems(widgetDesc.ListViewItems); listView.ShowColumnHeaders = widgetDesc.ShowColumnHeaders; diff --git a/src/openrct2-ui/scripting/ScWidget.hpp b/src/openrct2-ui/scripting/ScWidget.hpp index 6677bc1796..e9162117b3 100644 --- a/src/openrct2-ui/scripting/ScWidget.hpp +++ b/src/openrct2-ui/scripting/ScWidget.hpp @@ -368,6 +368,7 @@ namespace OpenRCT2::Scripting dukglue_set_base_class(ctx); dukglue_register_property(ctx, &ScListViewWidget::canSelect_get, &ScListViewWidget::canSelect_set, "canSelect"); dukglue_register_property(ctx, &ScListViewWidget::isStriped_get, &ScListViewWidget::isStriped_set, "isStriped"); + dukglue_register_property(ctx, &ScListViewWidget::scrollbars_get, &ScListViewWidget::scrollbars_set, "scrollbars"); dukglue_register_property( ctx, &ScListViewWidget::showColumnHeaders_get, &ScListViewWidget::showColumnHeaders_set, "showColumnHeaders"); dukglue_register_property(ctx, &ScListViewWidget::highlightedCell_get, nullptr, "highlightedCell"); @@ -416,6 +417,27 @@ namespace OpenRCT2::Scripting } } + DukValue scrollbars_get() const + { + auto ctx = GetContext()->GetScriptEngine().GetContext(); + auto scrollType = ScrollbarType::None; + auto listView = GetListView(); + if (listView != nullptr) + { + scrollType = listView->GetScrollbars(); + } + return ToDuk(ctx, scrollType); + } + + void scrollbars_set(const DukValue& value) + { + auto listView = GetListView(); + if (listView != nullptr) + { + listView->SetScrollbars(FromDuk(value)); + } + } + bool showColumnHeaders_get() const { auto listView = GetListView();