mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-23 14:54:30 +01:00
Show hovered values on finance charts (#10925)
This commit is contained in:
committed by
GitHub
parent
a33fbfa234
commit
fa1ddbd9e3
@@ -8,6 +8,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include <openrct2-ui/interface/Graph.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/localisation/Date.h>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
|
||||
@@ -182,10 +183,128 @@ static void graph_draw_line_b_money32(
|
||||
}
|
||||
}
|
||||
|
||||
struct FinancialTooltipInfo
|
||||
{
|
||||
const ScreenCoordsXY coords;
|
||||
const money32 money{};
|
||||
};
|
||||
|
||||
struct ScreenRect
|
||||
{
|
||||
const ScreenCoordsXY LeftTop;
|
||||
const ScreenCoordsXY RightBottom;
|
||||
|
||||
int32_t GetLeft() const
|
||||
{
|
||||
return LeftTop.x;
|
||||
}
|
||||
int32_t GetTop() const
|
||||
{
|
||||
return LeftTop.y;
|
||||
}
|
||||
int32_t GetRight() const
|
||||
{
|
||||
return RightBottom.x;
|
||||
}
|
||||
int32_t GetBottom() const
|
||||
{
|
||||
return RightBottom.y;
|
||||
}
|
||||
int32_t GetWidth() const
|
||||
{
|
||||
return RightBottom.x - LeftTop.x;
|
||||
}
|
||||
int32_t GetHeight() const
|
||||
{
|
||||
return RightBottom.y - LeftTop.y;
|
||||
}
|
||||
bool Contains(const ScreenCoordsXY& coords) const
|
||||
{
|
||||
return coords.x >= GetLeft() && coords.x <= GetRight() && coords.y >= GetTop() && coords.y <= GetBottom();
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr auto CHART_MAX_DATA_COUNT = 64;
|
||||
static constexpr auto CHART_MAX_INDEX = CHART_MAX_DATA_COUNT - 1;
|
||||
static constexpr auto CHART_DATA_WIDTH = 6;
|
||||
static constexpr auto CHART_MAX_WIDTH = CHART_MAX_INDEX * CHART_DATA_WIDTH;
|
||||
static constexpr auto CHART_MAX_HEIGHT = 164;
|
||||
static constexpr auto CURSOR_X_OFFSET = 3;
|
||||
static constexpr auto DEFAULT_DASHED_LENGTH = 2;
|
||||
|
||||
static int32_t IndexForCursorAndHistory(const int32_t historyCount, const int32_t cursorX, const int32_t chartX)
|
||||
{
|
||||
const auto offsettedCursorX = cursorX + CURSOR_X_OFFSET;
|
||||
return (historyCount - 1) - (offsettedCursorX - chartX) / CHART_DATA_WIDTH;
|
||||
}
|
||||
|
||||
static const ScreenCoordsXY ScreenCoordsForHistoryIndex(
|
||||
const int32_t index, const money32* history, const int32_t chartX, const int32_t chartY, const int32_t modifier,
|
||||
const int32_t offset)
|
||||
{
|
||||
ScreenCoordsXY coords;
|
||||
coords.x = chartX + CHART_DATA_WIDTH * (CHART_MAX_INDEX - index);
|
||||
coords.y = chartY + CHART_MAX_HEIGHT - ((((history[index] >> modifier) + offset) * 170) / 256);
|
||||
return coords;
|
||||
}
|
||||
|
||||
static const FinancialTooltipInfo finance_tooltip_info_from_money(
|
||||
const money32* history, const int32_t historyCount, const int32_t modifier, const int32_t offset,
|
||||
const ScreenRect& chartFrame, const ScreenCoordsXY& cursorPosition)
|
||||
{
|
||||
if (!chartFrame.Contains(cursorPosition))
|
||||
{
|
||||
return { {}, MONEY32_UNDEFINED };
|
||||
}
|
||||
|
||||
const auto historyIndex = IndexForCursorAndHistory(historyCount, cursorPosition.x, chartFrame.GetLeft());
|
||||
const auto coords = ScreenCoordsForHistoryIndex(
|
||||
historyIndex, history, chartFrame.GetLeft(), chartFrame.GetTop(), modifier, offset);
|
||||
|
||||
return { { coords.x, coords.y }, history[historyIndex] };
|
||||
}
|
||||
|
||||
static void graph_draw_hovered_value(
|
||||
rct_drawpixelinfo* dpi, const money32* history, const int32_t historyCount, const int32_t baseX, const int32_t baseY,
|
||||
const int32_t modifier, const int32_t offset)
|
||||
{
|
||||
const auto cursorPosition = context_get_cursor_position_scaled();
|
||||
const ScreenRect chartFrame{ { baseX, baseY }, { baseX + CHART_MAX_WIDTH, baseY + CHART_MAX_HEIGHT } };
|
||||
|
||||
if (!chartFrame.Contains(cursorPosition))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto info = finance_tooltip_info_from_money(
|
||||
history, CHART_MAX_DATA_COUNT, modifier, offset, chartFrame, cursorPosition);
|
||||
|
||||
if (info.money == MONEY32_UNDEFINED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gfx_draw_dashed_line(dpi, info.coords.x, chartFrame.GetTop(), info.coords.x, info.coords.y, DEFAULT_DASHED_LENGTH, 0);
|
||||
gfx_draw_dashed_line(dpi, chartFrame.GetLeft() - 10, info.coords.y, info.coords.x, info.coords.y, DEFAULT_DASHED_LENGTH, 0);
|
||||
|
||||
if (cursorPosition.y > info.coords.y)
|
||||
{
|
||||
gfx_draw_dashed_line(dpi, info.coords.x, info.coords.y, info.coords.x, cursorPosition.y, DEFAULT_DASHED_LENGTH, 0);
|
||||
}
|
||||
|
||||
gfx_draw_string_centred(
|
||||
dpi, STR_FINANCES_SUMMARY_EXPENDITURE_VALUE, info.coords.x, info.coords.y - 16, COLOUR_BLACK, &info.money);
|
||||
|
||||
gfx_fill_rect(dpi, info.coords.x - 2, info.coords.y - 2, info.coords.x + 2, info.coords.y + 2, PALETTE_INDEX_10);
|
||||
gfx_fill_rect(dpi, info.coords.x - 1, info.coords.y - 1, info.coords.x + 1, info.coords.y + 1, PALETTE_INDEX_21);
|
||||
}
|
||||
|
||||
void graph_draw_money32(
|
||||
rct_drawpixelinfo* dpi, money32* history, int32_t count, int32_t baseX, int32_t baseY, int32_t modifier, int32_t offset)
|
||||
rct_drawpixelinfo* dpi, const money32* history, const int32_t count, const int32_t baseX, const int32_t baseY,
|
||||
const int32_t modifier, const int32_t offset)
|
||||
{
|
||||
graph_draw_months_money32(dpi, history, count, baseX, baseY);
|
||||
graph_draw_line_a_money32(dpi, history, count, baseX, baseY, modifier, offset);
|
||||
graph_draw_line_b_money32(dpi, history, count, baseX, baseY, modifier, offset);
|
||||
graph_draw_hovered_value(dpi, history, count, baseX, baseY, modifier, offset);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
void graph_draw_uint8_t(rct_drawpixelinfo* dpi, uint8_t* history, int32_t count, int32_t baseX, int32_t baseY);
|
||||
void graph_draw_money32(
|
||||
rct_drawpixelinfo* dpi, money32* history, int32_t count, int32_t baseX, int32_t baseY, int32_t modifier, int32_t offset);
|
||||
rct_drawpixelinfo* dpi, const money32* history, const int32_t count, const int32_t baseX, const int32_t baseY,
|
||||
const int32_t modifier, const int32_t offset);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -465,6 +465,8 @@ void gfx_draw_pickedup_peep(rct_drawpixelinfo* dpi);
|
||||
// line
|
||||
void gfx_draw_line(rct_drawpixelinfo* dpi, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t colour);
|
||||
void gfx_draw_line_software(rct_drawpixelinfo* dpi, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t colour);
|
||||
void gfx_draw_dashed_line(
|
||||
rct_drawpixelinfo* dpi, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t dashedLineSegmentLength, int32_t colour);
|
||||
|
||||
// rect
|
||||
void gfx_fill_rect(rct_drawpixelinfo* dpi, int32_t left, int32_t top, int32_t right, int32_t bottom, int32_t colour);
|
||||
@@ -512,7 +514,8 @@ void FASTCALL
|
||||
void gfx_draw_string(rct_drawpixelinfo* dpi, const_utf8string buffer, uint8_t colour, int32_t x, int32_t y);
|
||||
|
||||
void gfx_draw_string_left(rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y);
|
||||
void gfx_draw_string_centred(rct_drawpixelinfo* dpi, rct_string_id format, int32_t x, int32_t y, uint8_t colour, void* args);
|
||||
void gfx_draw_string_centred(
|
||||
rct_drawpixelinfo* dpi, rct_string_id format, int32_t x, int32_t y, uint8_t colour, const void* args);
|
||||
void gfx_draw_string_right(rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y);
|
||||
|
||||
void draw_string_left_underline(rct_drawpixelinfo* dpi, rct_string_id format, void* args, uint8_t colour, int32_t x, int32_t y);
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include "IDrawingContext.h"
|
||||
#include "IDrawingEngine.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
using namespace OpenRCT2::Drawing;
|
||||
using namespace OpenRCT2::Paint;
|
||||
@@ -209,6 +211,39 @@ void gfx_draw_line(rct_drawpixelinfo* dpi, int32_t x1, int32_t y1, int32_t x2, i
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_draw_dashed_line(
|
||||
rct_drawpixelinfo* dpi, const int32_t x1, const int32_t y1, const int32_t x2, const int32_t y2,
|
||||
const int32_t dashedLineSegmentLength, const int32_t colour)
|
||||
{
|
||||
assert(dashedLineSegmentLength > 0);
|
||||
|
||||
const auto drawingEngine = dpi->DrawingEngine;
|
||||
if (drawingEngine != nullptr)
|
||||
{
|
||||
constexpr int32_t precisionFactor = 1000;
|
||||
|
||||
const int32_t dashedLineLength = std::hypot(x2 - x1, y2 - y1);
|
||||
const int32_t lineSegmentCount = dashedLineLength / dashedLineSegmentLength / 2;
|
||||
if (lineSegmentCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const int32_t lineXDist = std::abs(x2 - x1);
|
||||
const int32_t lineYDist = std::abs(y2 - y1);
|
||||
const int32_t dxPrecise = precisionFactor * lineXDist / lineSegmentCount / 2;
|
||||
const int32_t dyPrecise = precisionFactor * lineYDist / lineSegmentCount / 2;
|
||||
IDrawingContext* dc = drawingEngine->GetDrawingContext(dpi);
|
||||
|
||||
for (int32_t i = 0, x, y; i < lineSegmentCount; ++i)
|
||||
{
|
||||
x = x1 + dxPrecise * i * 2 / precisionFactor;
|
||||
y = y1 + dyPrecise * i * 2 / precisionFactor;
|
||||
dc->DrawLine(colour, x, y, x + dxPrecise / precisionFactor, y + dyPrecise / precisionFactor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FASTCALL gfx_draw_sprite(rct_drawpixelinfo* dpi, int32_t image, int32_t x, int32_t y, uint32_t tertiary_colour)
|
||||
{
|
||||
auto drawingEngine = dpi->DrawingEngine;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
static TextPaint _legacyPaint;
|
||||
|
||||
static void DrawText(rct_drawpixelinfo* dpi, int32_t x, int32_t y, TextPaint* paint, const_utf8string text);
|
||||
static void DrawText(rct_drawpixelinfo* dpi, int32_t x, int32_t y, TextPaint* paint, rct_string_id format, void* args);
|
||||
static void DrawText(rct_drawpixelinfo* dpi, int32_t x, int32_t y, TextPaint* paint, rct_string_id format, const void* args);
|
||||
|
||||
StaticLayout::StaticLayout(utf8string source, TextPaint paint, int32_t width)
|
||||
{
|
||||
@@ -105,7 +105,7 @@ static void DrawText(rct_drawpixelinfo* dpi, int32_t x, int32_t y, TextPaint* pa
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawText(rct_drawpixelinfo* dpi, int32_t x, int32_t y, TextPaint* paint, rct_string_id format, void* args)
|
||||
static void DrawText(rct_drawpixelinfo* dpi, int32_t x, int32_t y, TextPaint* paint, rct_string_id format, const void* args)
|
||||
{
|
||||
utf8 buffer[512];
|
||||
format_string(buffer, sizeof(buffer), format, args);
|
||||
@@ -113,8 +113,8 @@ static void DrawText(rct_drawpixelinfo* dpi, int32_t x, int32_t y, TextPaint* pa
|
||||
}
|
||||
|
||||
static void DrawTextCompat(
|
||||
rct_drawpixelinfo* dpi, int32_t x, int32_t y, rct_string_id format, void* args, uint8_t colour, TextAlignment alignment,
|
||||
bool underline = false)
|
||||
rct_drawpixelinfo* dpi, int32_t x, int32_t y, rct_string_id format, const void* args, uint8_t colour,
|
||||
TextAlignment alignment, bool underline = false)
|
||||
{
|
||||
_legacyPaint.UnderlineText = underline;
|
||||
_legacyPaint.Colour = colour;
|
||||
@@ -156,7 +156,8 @@ void gfx_draw_string_left(rct_drawpixelinfo* dpi, rct_string_id format, void* ar
|
||||
DrawTextCompat(dpi, x, y, format, args, colour, TextAlignment::LEFT);
|
||||
}
|
||||
|
||||
void gfx_draw_string_centred(rct_drawpixelinfo* dpi, rct_string_id format, int32_t x, int32_t y, uint8_t colour, void* args)
|
||||
void gfx_draw_string_centred(
|
||||
rct_drawpixelinfo* dpi, rct_string_id format, int32_t x, int32_t y, uint8_t colour, const void* args)
|
||||
{
|
||||
DrawTextCompat(dpi, x, y, format, args, colour, TextAlignment::CENTRE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user