rodecomp/Source/UI/UITextButton.cpp
2026-10-24 00:35:19 +00:00

180 lines
4.8 KiB
C++

#include "Render/DeviceContext.h"
#include "Render/TextContext.h"
#include "UI/FrameFocus.h"
#include "UI/UITextButton.h"
#include <bit>
#include <cstring>
namespace {
int Add(int left, int right) {
return std::bit_cast<std::int32_t>(static_cast<std::uint32_t>(left) + static_cast<std::uint32_t>(right));
}
}
// OFFSET: 0x0086EEB0
UITextButton::UITextButton(UIWindowContext& windows, UIButtonContext& buttons)
: UIButton(windows, buttons), m_outlineColor(0xFFFFFF), m_value(0) {
}
// OFFSET: 0x00874690
// FUNCTION: fn_11187
UITextButton::~UITextButton() = default;
// OFFSET: 0x0087C590
// FUNCTION: fn_11254
void UITextButton::Configure(
const char* text,
std::uint32_t color,
int family,
int height,
unsigned char outline,
unsigned char underline
) {
this->label = text;
this->m_text = this->label;
this->m_normalColor = this->m_hoverColor = this->m_color = color;
this->m_family = family;
this->m_height = height;
this->m_outline = outline;
this->m_underline = underline;
const auto extent = static_cast<std::uint32_t>(height) * static_cast<std::uint32_t>(std::strlen(text));
const int width = std::bit_cast<std::int32_t>((extent >> 1) + 4u * outline + 12u);
this->Resize(width, Add(height, 2));
this->Slot15(width, Add(height, 2));
this->Slot22(width, Add(height, 2));
}
// OFFSET: 0x0088F820
// FUNCTION: fn_11392
void UITextButton::Paint() {
if (this->geometry.surface) {
this->geometry.surface->Fill(nullptr, 0xFFFF00FFu);
}
if (this->parent) {
static_cast<UIWindow*>(this->parent)->Invalidate();
}
TextContext context(*this->geometry.surface, this->m_buttonContext->fonts, this->m_buttonContext->locale);
context.SetFont(this->m_family, this->m_height, this->m_outline != 0, 0);
const int bytes = static_cast<int>(std::strlen(this->m_text.c_str()));
if (this->m_outline != 0) {
if (this->HasTextBackground()) {
context.SetBackground(this->TextBackground(), OPAQUE);
}
context.SetColor(this->m_outlineColor);
context.Draw(0, 1, this->m_text.c_str(), bytes);
context.Draw(2, 1, this->m_text.c_str(), bytes);
context.Draw(1, 0, this->m_text.c_str(), bytes);
context.Draw(1, 2, this->m_text.c_str(), bytes);
}
context.SetColor(this->m_color);
context.Draw(1, 1, this->m_text.c_str(), bytes);
if (this->m_outline != 0 && this->HasTextBackground()) {
context.SetBackground(this->TextBackground(), TRANSPARENT);
}
if (this->m_underline != 0) {
this->FillRegion(0, Add(this->geometry.height, -1), this->geometry.width, 1, this->m_color);
}
}
// OFFSET: 0x00892450
// FUNCTION: fn_11471
void UITextButton::Slot27(int x, int y) {
if (this->m_disabled != 0) {
return;
}
const bool inside = x >= 0 && x < this->geometry.width && y >= 0 && y < this->geometry.height;
const unsigned state = inside ? (this->m_buttonContext->focus.Get() == this ? 2 : 1) : 0;
this->m_color = inside ? this->m_hoverColor : this->m_normalColor;
if (this->geometry.unknown_0030 != state) {
this->geometry.unknown_0030 = state;
this->Invalidate();
}
}
// OFFSET: 0x00892000
// FUNCTION: fn_11461
void UITextButton::Slot28(int x, int y) {
if (this->parent) {
static_cast<UIWindow*>(this->parent)->Slot28(Add(x, this->geometry.x), Add(y, this->geometry.y));
}
UIButton::Slot28(x, y);
}
// OFFSET: 0x00891140
// FUNCTION: fn_11445
void UITextButton::Slot31(int x, int y) {
FrameFocus& focus = this->m_buttonContext->focus;
if (this->m_disabled != 0 || focus.Get() != this) {
return;
}
if (x < 0 || x >= this->geometry.width || y < 0 || y >= this->geometry.height) {
this->geometry.unknown_0030 = 0;
} else {
this->geometry.unknown_0030 = 1;
if (this->parent) {
static_cast<UIWindow*>(this->parent)->SendMsg(this, 98, this->geometry.id, this->m_value, 0, 0);
focus.Clear();
return;
}
}
this->Invalidate();
focus.Clear();
}
// OFFSET: 0x00892B60
// FUNCTION: fn_11487
void UITextButton::Slot32(int, int) {
if (this->m_disabled == 0) {
if (this->parent) {
static_cast<UIWindow*>(this->parent)->SendMsg(this, 99, this->geometry.id, this->m_value, 0, 0);
}
this->Invalidate();
}
}
// OFFSET: 0x00892D60
// FUNCTION: fn_11494
void UITextButton::Slot33(int x, int y) {
FrameFocus& focus = this->m_buttonContext->focus;
if (this->m_disabled != 0 || focus.Get() != this) {
return;
}
if (x < 0 || x >= this->geometry.width || y < 0 || y >= this->geometry.height) {
this->geometry.unknown_0030 = 0;
} else {
this->geometry.unknown_0030 = 1;
if (this->parent) {
static_cast<UIWindow*>(this->parent)->SendMsg(this, 99, this->geometry.id, this->m_value, 0, 0);
}
}
this->Invalidate();
focus.Clear();
}
// OFFSET: 0x00892F30
// FUNCTION: fn_11500
void UITextButton::Slot35(int value) {
if (this->parent) {
static_cast<UIWindow*>(this->parent)->Slot35(value);
}
}