1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-24 15:24:30 +01:00

Add checkboxes to asset pack window

This commit is contained in:
Ted John
2022-10-01 13:06:20 +01:00
parent b2d5e356ab
commit 717e265c19
3 changed files with 147 additions and 35 deletions

View File

@@ -3625,6 +3625,8 @@ STR_6517 :One or more objects in this park require RCT1 linked for proper dis
STR_6518 :{BLACK}Hover over a scenario to view its description and objective. Click it to start playing.
STR_6519 :Extras
STR_6520 :Asset Packs
STR_6521 :Low Priority
STR_6522 :High Priority
#############
# Scenarios #

View File

@@ -13,6 +13,8 @@
#include <openrct2/AssetPackManager.h>
#include <openrct2/Context.h>
#include <openrct2/drawing/Drawing.h>
#include <openrct2/drawing/Text.h>
#include <openrct2/localisation/Localisation.h>
#include <openrct2/object/ObjectManager.h>
#include <openrct2/sprites.h>
@@ -48,6 +50,8 @@ static rct_widget WindowAssetPacksWidgets[] = {
class AssetPacksWindow final : public Window
{
private:
static constexpr int32_t ItemHeight = SCROLLABLE_ROW_HEIGHT + 1;
static constexpr int32_t ItemCheckBoxSize = ItemHeight - 3;
std::optional<size_t> _highlightedIndex;
std::optional<size_t> _selectedIndex;
@@ -91,8 +95,8 @@ public:
auto assetPackManager = GetContext()->GetAssetPackManager();
if (assetPackManager != nullptr)
{
auto numAssetPacks = assetPackManager->GetCount();
result.height = static_cast<int32_t>(numAssetPacks * SCROLLABLE_ROW_HEIGHT);
auto numAssetPacks = assetPackManager->GetCount() + 2; // Add 2 for separators
result.height = static_cast<int32_t>(numAssetPacks * ItemHeight);
}
if (_highlightedIndex)
@@ -106,26 +110,39 @@ public:
void OnScrollMouseDown(int32_t scrollIndex, const ScreenCoordsXY& screenCoords) override
{
const auto index = screenCoords.y / SCROLLABLE_ROW_HEIGHT;
if (index < 0 || static_cast<size_t>(index) >= GetNumAssetPacks())
return;
auto isCheckBox = false;
auto index = GetAssetPackIndexFromPosition(screenCoords, isCheckBox);
if (_selectedIndex != static_cast<size_t>(index))
// Click on checkbox
if (index && isCheckBox)
{
_selectedIndex = static_cast<size_t>(index);
auto assetPackManager = GetContext()->GetAssetPackManager();
if (assetPackManager != nullptr)
{
auto assetPack = assetPackManager->GetAssetPack(*index);
if (assetPack != nullptr)
{
assetPack->SetEnabled(!assetPack->IsEnabled());
Invalidate();
}
}
}
// Select item
if (_selectedIndex != index)
{
_selectedIndex = index;
Invalidate();
}
}
void OnScrollMouseOver(int32_t scrollIndex, const ScreenCoordsXY& screenCoords) override
{
const auto index = screenCoords.y / SCROLLABLE_ROW_HEIGHT;
if (index < 0 || static_cast<size_t>(index) >= GetNumAssetPacks())
return;
if (_highlightedIndex != static_cast<size_t>(index))
auto isCheckBox = false;
auto index = GetAssetPackIndexFromPosition(screenCoords, isCheckBox);
if (_highlightedIndex != index)
{
_highlightedIndex = static_cast<size_t>(index);
_highlightedIndex = index;
Invalidate();
}
}
@@ -185,40 +202,131 @@ public:
return;
auto numAssetPacks = assetPackManager->GetCount();
for (size_t i = 0; i < numAssetPacks; i++)
for (size_t i = 0; i <= numAssetPacks + 1; i++)
{
if (y > dpi.y + dpi.height)
break;
if (y + 11 < dpi.y)
continue;
auto assetPack = assetPackManager->GetAssetPack(i);
if (assetPack != nullptr)
if (i == 0 || i == numAssetPacks + 1)
{
auto stringId = STR_BLACK_STRING;
auto fillRectangle = ScreenRect{ { 0, y }, { listWidth, y + SCROLLABLE_ROW_HEIGHT - 1 } };
if (i == _selectedIndex)
{
gfx_fill_rect(&dpi, fillRectangle, ColourMapA[colours[1]].mid_dark);
stringId = STR_WINDOW_COLOUR_2_STRINGID;
}
else if (i == _highlightedIndex)
{
gfx_fill_rect(&dpi, fillRectangle, ColourMapA[colours[1]].mid_dark);
}
auto ft = Formatter();
ft.Add<StringId>(assetPack->IsEnabled() ? STR_TOGGLE_OPTION_CHECKED : STR_TOGGLE_OPTION);
ft.Add<StringId>(STR_STRING);
ft.Add<const char*>(assetPack->Name.c_str());
DrawTextEllipsised(&dpi, { 0, y }, listWidth, stringId, ft);
auto text = i == 0 ? STR_LOW_PRIORITY : STR_HIGH_PRIORITY;
PaintSeperator(dpi, { 0, y }, { listWidth, y + ItemHeight - 1 }, text);
}
else
{
auto assetPackIndex = i - 1;
auto assetPack = assetPackManager->GetAssetPack(assetPackIndex);
if (assetPack != nullptr)
{
auto stringId = STR_BLACK_STRING;
auto fillRectangle = ScreenRect{ { 0, y }, { listWidth, y + ItemHeight - 1 } };
if (assetPackIndex == _selectedIndex)
{
gfx_fill_rect(&dpi, fillRectangle, ColourMapA[colours[1]].mid_dark);
stringId = STR_WINDOW_COLOUR_2_STRINGID;
}
else if (assetPackIndex == _highlightedIndex)
{
gfx_fill_rect(&dpi, fillRectangle, ColourMapA[colours[1]].mid_dark);
}
y += SCROLLABLE_ROW_HEIGHT;
auto ft = Formatter();
ft.Add<StringId>(STR_STRING);
ft.Add<const char*>(assetPack->Name.c_str());
DrawTextEllipsised(&dpi, { 16, y + 1 }, listWidth, stringId, ft);
auto checkboxSize = ItemHeight - 3;
PaintCheckbox(
dpi, { { 2, y + 1 }, { 2 + checkboxSize + 1, y + 1 + checkboxSize } }, assetPack->IsEnabled());
}
}
y += ItemHeight;
}
}
private:
void PaintSeperator(rct_drawpixelinfo& dpi, const ScreenCoordsXY& pos, const ScreenSize& size, StringId text) const
{
auto hasText = text != STR_NONE;
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 = colours[1];
auto lightColour = ColourMapA[baseColour].lighter;
auto darkColour = ColourMapA[baseColour].mid_dark;
if (hasText)
{
// Draw string
Formatter ft;
ft.Add<StringId>(text);
DrawTextBasic(&dpi, { centreX, pos.y }, STR_STRINGID, ft, { baseColour, TextAlignment::CENTRE });
// Get string dimensions
format_string(gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), STR_STRING, ft.Data());
int32_t categoryStringHalfWidth = (gfx_get_string_width(gCommonStringFormatBuffer, FontSpriteBase::MEDIUM) / 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 PaintCheckbox(rct_drawpixelinfo& dpi, const ScreenRect& rect, bool checked)
{
gfx_fill_rect_inset(&dpi, rect, colours[1], INSET_RECT_F_E0);
if (checked)
{
auto checkmark = Formatter();
checkmark.Add<StringId>(STR_STRING);
checkmark.Add<char*>(CheckBoxMarkString);
DrawTextBasic(&dpi, ScreenCoordsXY{ rect.GetLeft() + 1, rect.GetTop() }, STR_WINDOW_COLOUR_2_STRINGID, checkmark);
}
}
std::optional<size_t> GetAssetPackIndexFromPosition(const ScreenCoordsXY& pos, bool& isCheckBox)
{
const auto index = (pos.y / ItemHeight) - 1;
if (index < 0 || static_cast<size_t>(index) >= GetNumAssetPacks())
return {};
isCheckBox = pos.x >= 2 && pos.x <= 2 + ItemCheckBoxSize + 1;
return static_cast<size_t>(index);
}
size_t GetNumAssetPacks() const
{
auto assetPackManager = GetContext()->GetAssetPackManager();
@@ -276,7 +384,7 @@ private:
(*_selectedIndex)--;
Invalidate();
}
else if (*_selectedIndex < assetPackManager->GetCount() - 1)
else if (direction > 0 && *_selectedIndex < assetPackManager->GetCount() - 1)
{
assetPackManager->Swap(*_selectedIndex, *_selectedIndex + 1);
(*_selectedIndex)++;

View File

@@ -3908,6 +3908,8 @@ enum : uint16_t
STR_SCENARIO_CATEGORY_EXTRAS_PARKS = 6519,
STR_ASSET_PACKS = 6520,
STR_LOW_PRIORITY = 6521,
STR_HIGH_PRIORITY = 6522,
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
/* MAX_STR_COUNT = 32768 */ // MAX_STR_COUNT - upper limit for number of strings, not the current count strings