From 95c3a7f5ddde30f16d1591067e166353a8cae996 Mon Sep 17 00:00:00 2001 From: Ted John Date: Fri, 4 Dec 2020 18:46:34 +0000 Subject: [PATCH] Fix #13512: [Plugin] Add item separators to list view --- distribution/changelog.txt | 1 + distribution/openrct2.d.ts | 7 +- src/openrct2-ui/scripting/CustomListView.cpp | 160 ++++++++++++++----- src/openrct2-ui/scripting/CustomListView.h | 2 + 4 files changed, 128 insertions(+), 42 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index ff20550a57..a85f1b54eb 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -6,6 +6,7 @@ - Feature: [#13398] Add pause button to the Track Designer. - Feature: [#13495] [Plugin] Add properties for park value, guests and company value. - Feature: [#13509] [Plugin] Add ability to format strings using OpenRCT2 string framework. +- Feature: [#13512] [Plugin] Add item separators to list view. - Change: [#13346] Change FootpathScenery to FootpathAddition in all occurrences. - Fix: [#12895] Mechanics are called to repair rides that have already been fixed. - Fix: [#13257] Rides that are exactly the minimum objective length are not counted. diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index 63e770429c..c66346578c 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -1853,7 +1853,12 @@ declare global { maxWidth?: number; } - type ListViewItem = string[]; + interface ListViewItemSeperator { + type: 'seperator'; + text?: string; + } + + type ListViewItem = ListViewItemSeperator | string[]; interface RowColumn { row: number; diff --git a/src/openrct2-ui/scripting/CustomListView.cpp b/src/openrct2-ui/scripting/CustomListView.cpp index 48e1cf0083..7d7304553b 100644 --- a/src/openrct2-ui/scripting/CustomListView.cpp +++ b/src/openrct2-ui/scripting/CustomListView.cpp @@ -114,6 +114,16 @@ namespace OpenRCT2::Scripting } result = ListViewItem(std::move(cells)); } + else if (d.type() == DukValue::Type::OBJECT) + { + auto type = ProcessString(d["type"]); + if (type == "seperator") + { + auto text = ProcessString(d["text"]); + result = ListViewItem(text); + result.IsSeparator = true; + } + } return result; } @@ -553,55 +563,64 @@ void CustomListView::Paint(rct_window* w, rct_drawpixelinfo* dpi, const rct_scro const auto& itemIndex = static_cast(SortedItems[i]); const auto& item = Items[itemIndex]; - // Background colour - auto isStriped = IsStriped && (i & 1); - auto isHighlighted = (HighlightedCell && itemIndex == HighlightedCell->Row); - auto isSelected = (SelectedCell && itemIndex == SelectedCell->Row); - if (isSelected) - { - gfx_filter_rect( - dpi, { { dpi->x, y }, { dpi->x + dpi->width, y + (LIST_ROW_HEIGHT - 1) } }, - FilterPaletteID::PaletteDarken2); - } - else if (isHighlighted) - { - gfx_filter_rect( - dpi, { { dpi->x, y }, { dpi->x + dpi->width, y + (LIST_ROW_HEIGHT - 1) } }, - FilterPaletteID::PaletteDarken1); - } - else if (isStriped) - { - gfx_fill_rect( - dpi, { { dpi->x, y }, { dpi->x + dpi->width, y + (LIST_ROW_HEIGHT - 1) } }, - ColourMapA[w->colours[1]].lighter | 0x1000000); - } - - // Columns - if (Columns.size() == 0) + if (item.IsSeparator) { const auto& text = item.Cells[0]; - if (!text.empty()) - { - ScreenSize cellSize = { std::numeric_limits::max(), LIST_ROW_HEIGHT }; - PaintCell(dpi, { 0, y }, cellSize, text.c_str(), isHighlighted); - } + ScreenSize cellSize = { LastKnownSize.width, LIST_ROW_HEIGHT }; + PaintSeperator(dpi, { 0, y }, cellSize, text.c_str()); } else { - int32_t x = 0; - for (size_t j = 0; j < Columns.size(); j++) + // Background colour + auto isStriped = IsStriped && (i & 1); + auto isHighlighted = (HighlightedCell && itemIndex == HighlightedCell->Row); + auto isSelected = (SelectedCell && itemIndex == SelectedCell->Row); + if (isSelected) { - const auto& column = Columns[j]; - if (item.Cells.size() > j) + gfx_filter_rect( + dpi, { { dpi->x, y }, { dpi->x + dpi->width, y + (LIST_ROW_HEIGHT - 1) } }, + FilterPaletteID::PaletteDarken2); + } + else if (isHighlighted) + { + gfx_filter_rect( + dpi, { { dpi->x, y }, { dpi->x + dpi->width, y + (LIST_ROW_HEIGHT - 1) } }, + FilterPaletteID::PaletteDarken2); + } + else if (isStriped) + { + gfx_fill_rect( + dpi, { { dpi->x, y }, { dpi->x + dpi->width, y + (LIST_ROW_HEIGHT - 1) } }, + ColourMapA[w->colours[1]].lighter | 0x1000000); + } + + // Columns + if (Columns.size() == 0) + { + const auto& text = item.Cells[0]; + if (!text.empty()) { - const auto& text = item.Cells[j]; - if (!text.empty()) - { - ScreenSize cellSize = { column.Width, LIST_ROW_HEIGHT }; - PaintCell(dpi, { x, y }, cellSize, text.c_str(), isHighlighted); - } + ScreenSize cellSize = { std::numeric_limits::max(), LIST_ROW_HEIGHT }; + PaintCell(dpi, { 0, y }, cellSize, text.c_str(), isHighlighted); + } + } + else + { + int32_t x = 0; + for (size_t j = 0; j < Columns.size(); j++) + { + const auto& column = Columns[j]; + if (item.Cells.size() > j) + { + const auto& text = item.Cells[j]; + if (!text.empty()) + { + ScreenSize cellSize = { column.Width, LIST_ROW_HEIGHT }; + PaintCell(dpi, { x, y }, cellSize, text.c_str(), isHighlighted); + } + } + x += column.Width; } - x += column.Width; } } } @@ -666,6 +685,65 @@ void CustomListView::PaintHeading( } } +void CustomListView::PaintSeperator( + rct_drawpixelinfo* dpi, const ScreenCoordsXY& pos, const ScreenSize& size, const char* text) const +{ + auto hasText = text != nullptr && text[0] != '\0'; + auto left = pos.x + 4; + auto right = pos.x + size.width - 4; + auto centreX = size.width / 2; + auto lineY0 = pos.y + 5; + auto lineY1 = lineY0 + 1; + + auto baseColour = ParentWindow->colours[1]; + auto lightColour = ColourMapA[baseColour].lighter; + auto darkColour = ColourMapA[baseColour].mid_dark; + + if (hasText) + { + // Draw string + Formatter ft; + ft.Add(text); + gfx_draw_string_centred(dpi, STR_STRING, { centreX, pos.y }, baseColour, ft.Data()); + + // Get string dimensions + format_string(gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), STR_STRING, ft.Data()); + int32_t categoryStringHalfWidth = (gfx_get_string_width(gCommonStringFormatBuffer) / 2) + 4; + int32_t strLeft = centreX - categoryStringHalfWidth; + int32_t strRight = centreX + categoryStringHalfWidth; + + // Draw light horizontal rule + auto lightLineLeftTop1 = ScreenCoordsXY{ left, lineY0 }; + auto lightLineRightBottom1 = ScreenCoordsXY{ strLeft, lineY0 }; + gfx_draw_line(dpi, { lightLineLeftTop1, lightLineRightBottom1 }, lightColour); + + auto lightLineLeftTop2 = ScreenCoordsXY{ strRight, lineY0 }; + auto lightLineRightBottom2 = ScreenCoordsXY{ right, lineY0 }; + gfx_draw_line(dpi, { lightLineLeftTop2, lightLineRightBottom2 }, lightColour); + + // Draw dark horizontal rule + auto darkLineLeftTop1 = ScreenCoordsXY{ left, lineY1 }; + auto darkLineRightBottom1 = ScreenCoordsXY{ strLeft, lineY1 }; + gfx_draw_line(dpi, { darkLineLeftTop1, darkLineRightBottom1 }, darkColour); + + auto darkLineLeftTop2 = ScreenCoordsXY{ strRight, lineY1 }; + auto darkLineRightBottom2 = ScreenCoordsXY{ right, lineY1 }; + gfx_draw_line(dpi, { darkLineLeftTop2, darkLineRightBottom2 }, darkColour); + } + else + { + // Draw light horizontal rule + auto lightLineLeftTop1 = ScreenCoordsXY{ left, lineY0 }; + auto lightLineRightBottom1 = ScreenCoordsXY{ right, lineY0 }; + gfx_draw_line(dpi, { lightLineLeftTop1, lightLineRightBottom1 }, lightColour); + + // Draw dark horizontal rule + auto darkLineLeftTop1 = ScreenCoordsXY{ left, lineY1 }; + auto darkLineRightBottom1 = ScreenCoordsXY{ right, lineY1 }; + gfx_draw_line(dpi, { darkLineLeftTop1, darkLineRightBottom1 }, darkColour); + } +} + void CustomListView::PaintCell( rct_drawpixelinfo* dpi, const ScreenCoordsXY& pos, const ScreenSize& size, const char* text, bool isHighlighted) const { diff --git a/src/openrct2-ui/scripting/CustomListView.h b/src/openrct2-ui/scripting/CustomListView.h index 0266d2b436..183f1f1e1a 100644 --- a/src/openrct2-ui/scripting/CustomListView.h +++ b/src/openrct2-ui/scripting/CustomListView.h @@ -52,6 +52,7 @@ namespace OpenRCT2::Ui::Windows struct ListViewItem { + bool IsSeparator{}; std::vector Cells; ListViewItem() = default; @@ -141,6 +142,7 @@ namespace OpenRCT2::Ui::Windows void PaintHeading( rct_window* w, rct_drawpixelinfo* dpi, const ScreenCoordsXY& pos, const ScreenSize& size, const std::string& text, ColumnSortOrder sortOrder, bool isPressed) const; + void PaintSeperator(rct_drawpixelinfo* dpi, const ScreenCoordsXY& pos, const ScreenSize& size, const char* text) const; void PaintCell( rct_drawpixelinfo* dpi, const ScreenCoordsXY& pos, const ScreenSize& size, const char* text, bool isHighlighted) const;