diff --git a/src/openrct2-ui/input/MouseInput.cpp b/src/openrct2-ui/input/MouseInput.cpp index dc139be5b1..83c13be951 100644 --- a/src/openrct2-ui/input/MouseInput.cpp +++ b/src/openrct2-ui/input/MouseInput.cpp @@ -1067,6 +1067,7 @@ static void InputWidgetLeft(const ScreenCoordsXY& screenCoords, WindowBase* w, W case WindowWidgetType::LabelCentred: case WindowWidgetType::Label: case WindowWidgetType::Groupbox: + case WindowWidgetType::ProgressBar: case WindowWidgetType::Placeholder: case WindowWidgetType::Last: // Non-interactive widget type diff --git a/src/openrct2-ui/interface/Widget.cpp b/src/openrct2-ui/interface/Widget.cpp index ab24c843ac..f66b2e629a 100644 --- a/src/openrct2-ui/interface/Widget.cpp +++ b/src/openrct2-ui/interface/Widget.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,7 @@ static void WidgetTextCentred(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid static void WidgetText(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex); static void WidgetTextInset(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex); static void WidgetTextBoxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex); +static void WidgetProgressBarDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex); static void WidgetGroupboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex); static void WidgetCaptionDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex); static void WidgetCheckboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex); @@ -108,6 +110,9 @@ void WidgetDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex) case WindowWidgetType::TextBox: WidgetTextBoxDraw(dpi, w, widgetIndex); break; + case WindowWidgetType::ProgressBar: + WidgetProgressBarDraw(dpi, w, widgetIndex); + break; default: break; } @@ -1189,6 +1194,37 @@ static void WidgetTextBoxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid } } +static void WidgetProgressBarDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex) +{ + const auto& widget = w.widgets[widgetIndex]; + + ScreenCoordsXY topLeft{ w.windowPos + ScreenCoordsXY{ widget.left, widget.top } }; + ScreenCoordsXY bottomRight{ w.windowPos + ScreenCoordsXY{ widget.right, widget.bottom } }; + + auto percentage = widget.content & 0xFF; + auto lowerBlinkBounds = (widget.content >> 8) & 0xFF; + auto upperBlinkBounds = (widget.content >> 16) & 0xFF; + + auto isBlinking = (lowerBlinkBounds != upperBlinkBounds) && (percentage >= lowerBlinkBounds) + && (percentage <= upperBlinkBounds); + + GfxFillRectInset(dpi, { topLeft, bottomRight }, w.colours[1], INSET_RECT_F_30); + if (isBlinking) + { + if (GameIsNotPaused() && (gCurrentRealTimeTicks & 8)) + return; + } + + const auto barWidth = widget.width() - 2; + const int32_t fillSize = (barWidth * percentage) / 100; + if (fillSize > 0) + { + GfxFillRectInset( + dpi, { topLeft + ScreenCoordsXY{ 1, 1 }, topLeft + ScreenCoordsXY{ fillSize + 1, widget.height() - 1 } }, + widget.colour, 0); + } +} + ImageId GetColourButtonImage(colour_t colour) { if (colour == COLOUR_INVISIBLE) @@ -1200,3 +1236,9 @@ ImageId GetColourButtonImage(colour_t colour) return ImageId(SPR_PALETTE_BTN, colour).WithBlended(true); } } + +void WidgetProgressBarSetNewPercentage(Widget& widget, uint8_t newPercentage) +{ + widget.content &= ~0xFF; + widget.content |= newPercentage; +} diff --git a/src/openrct2-ui/interface/Widget.h b/src/openrct2-ui/interface/Widget.h index 5b8a3fe2ac..dafa430e49 100644 --- a/src/openrct2-ui/interface/Widget.h +++ b/src/openrct2-ui/interface/Widget.h @@ -85,6 +85,23 @@ constexpr Widget MakeTab(const ScreenCoordsXY& origin, StringId tooltip = STR_NO return MakeWidget(origin, size, type, colour, content, tooltip); } +constexpr Widget MakeProgressBar( + const ScreenCoordsXY& origin, const ScreenSize& size, colour_t colour, uint8_t lowerBlinkBound = 0, + uint8_t upperBlinkBound = 0) +{ + Widget out = {}; + out.left = origin.x; + out.right = origin.x + size.width - 1; + out.top = origin.y; + out.bottom = origin.y + size.height - 1; + out.type = WindowWidgetType::ProgressBar; + out.colour = colour; + out.content = 0 | (lowerBlinkBound << 8) | (upperBlinkBound << 16); + out.tooltip = STR_NONE; + + return out; +} + // NOLINTBEGIN #define MakeSpinnerWidgets(...) \ MakeWidget(__VA_ARGS__), MakeSpinnerIncreaseWidget(__VA_ARGS__), MakeSpinnerDecreaseWidget(__VA_ARGS__) @@ -154,3 +171,5 @@ void WidgetSetHoldable(WindowBase& w, WidgetIndex widgetIndex, bool value); void WidgetSetVisible(WindowBase& w, WidgetIndex widgetIndex, bool value); void WidgetSetPressed(WindowBase& w, WidgetIndex widgetIndex, bool value); void WidgetSetCheckboxValue(WindowBase& w, WidgetIndex widgetIndex, bool value); + +void WidgetProgressBarSetNewPercentage(Widget& widget, uint8_t newPercentage); diff --git a/src/openrct2-ui/scripting/ScWidget.hpp b/src/openrct2-ui/scripting/ScWidget.hpp index 5ffa194999..a7082df10e 100644 --- a/src/openrct2-ui/scripting/ScWidget.hpp +++ b/src/openrct2-ui/scripting/ScWidget.hpp @@ -112,6 +112,8 @@ namespace OpenRCT2::Scripting return "empty"; case WindowWidgetType::Placeholder: return "placeholder"; + case WindowWidgetType::ProgressBar: + return "progress_bar"; case WindowWidgetType::Custom: return "custom"; case WindowWidgetType::Last: diff --git a/src/openrct2/interface/Widget.h b/src/openrct2/interface/Widget.h index 2f395de441..11d15c87c0 100644 --- a/src/openrct2/interface/Widget.h +++ b/src/openrct2/interface/Widget.h @@ -38,6 +38,7 @@ enum class WindowWidgetType : uint8_t Scroll = 22, Checkbox = 23, Placeholder = 25, + ProgressBar = 29, Custom = 28, TextBox = 27, Last = 26,