feat(ui): update CSimpleStatusBar to support texture

This commit is contained in:
VDm 2025-08-12 22:23:22 +04:00
parent ff2a0da254
commit fa55a29a93
3 changed files with 169 additions and 4 deletions

View File

@ -1,5 +1,7 @@
#include "ui/CSimpleStatusBar.hpp"
#include "ui/CSimpleStatusBarScript.hpp"
#include "ui/CSimpleTexture.hpp"
#include "util/Lua.hpp"
int32_t CSimpleStatusBar::s_metatable = 0;
int32_t CSimpleStatusBar::s_objectType = 0;
@ -32,6 +34,90 @@ void CSimpleStatusBar::SetOrientation(uint32_t orientation) {
this->m_orientation = orientation;
}
void CSimpleStatusBar::SetMinMaxValues(float minValue, float maxValue) {
if ((this->m_flags & 2) != 0 && this->m_minValue == minValue && this->m_maxValue == maxValue) {
return;
}
this->m_flags |= 3;
this->m_minValue = minValue;
this->m_maxValue = maxValue;
this->RunOnMinMaxChanged();
if (this->m_flags & 4) {
this->SetValue(this->m_value);
}
}
void CSimpleStatusBar::SetBarTexture(const char* texFile, int32_t layer) {
if (this->m_barTexture) {
this->m_barTexture->SetTexture(texFile, false, false, GxTex_Linear, ImageMode_UI);
return;
}
// TODO: CDataAllocator__GetData(CSimpleTexture::s_allocator, 0, ".?AVCSimpleTexture@@", -2);
auto texture = NEW(CSimpleTexture, nullptr, DRAWLAYER_ARTWORK, 0);
if (texture->SetTexture(texFile, false, false, GxTex_Linear, ImageMode_UI)) {
texture->SetAllPoints(this, 1);
texture->SetBlendMode(GxBlend_Add);
this->SetBarTexture(texture, layer);
} else if (texture) {
// TODO: FrameScript_Object::LookupScriptMethod(texture, 1);
}
}
void CSimpleStatusBar::SetBarTexture(CSimpleTexture* texture, int32_t layer) {
if (texture == this->m_barTexture) {
return;
}
if (this->m_barTexture) {
// TODO: FrameScript_Object::LookupScriptMethod(this->m_checkedTexture, 1);
}
if (texture) {
texture->SetFrame(this, layer, 1);
texture->SetPoint(FRAMEPOINT_BOTTOMLEFT, this, FRAMEPOINT_BOTTOMLEFT, 0.0f, 0.0f, 1);
texture->SetPoint(FRAMEPOINT_BOTTOMRIGHT, this, FRAMEPOINT_BOTTOMRIGHT, 0.0f, 0.0f, 1);
texture->SetPoint(FRAMEPOINT_TOPLEFT, this, FRAMEPOINT_TOPLEFT, 0.0f, 0.0f, 1);
texture->SetPoint(FRAMEPOINT_TOPRIGHT, this, FRAMEPOINT_TOPRIGHT, 0.0f, 0.0f, 1);
}
this->m_flags |= 1;
this->m_barTexture = texture;
}
void CSimpleStatusBar::RunOnMinMaxChanged() {
if (this->m_onMinMaxChanged.luaRef) {
auto L = FrameScript_GetContext();
lua_pushnumber(L, this->m_minValue);
lua_pushnumber(L, this->m_maxValue);
this->RunScript(this->m_onMinMaxChanged, 2, 0);
}
}
void CSimpleStatusBar::RunOnValueChanged() {
if (this->m_onValueChanged.luaRef) {
auto L = FrameScript_GetContext();
lua_pushnumber(L, this->m_value);
this->RunScript(this->m_onMinMaxChanged, 1, 0);
}
}
void CSimpleStatusBar::SetValue(float value) {
if ((this->m_flags & 2) == 0) {
return;
}
value = std::min(value, this->m_maxValue);
value = std::max(value, this->m_minValue);
if ((this->m_flags & 4) == 0 || this->m_value != value) {
this->m_value = value;
this->RunOnValueChanged();
}
}
bool CSimpleStatusBar::IsA(int32_t type) {
return type == CSimpleStatusBar::s_objectType
|| type == CSimpleFrame::s_objectType

View File

@ -17,8 +17,14 @@ class CSimpleStatusBar : public CSimpleFrame {
// Member functions
CSimpleStatusBar(CSimpleFrame* parent);
void SetOrientation(uint32_t orientation);
void SetMinMaxValues(float minValue, float maxValue);
void SetBarTexture(const char* texFile, int32_t layer);
void SetBarTexture(CSimpleTexture* texture, int32_t layer);
void RunOnMinMaxChanged();
void RunOnValueChanged();
// Virtual member functions
virtual void SetValue(float value);
virtual bool IsA(int32_t type);
virtual int32_t GetScriptMetaTable();
virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data);

View File

@ -1,5 +1,6 @@
#include "ui/CSimpleStatusBarScript.hpp"
#include "ui/CSimpleStatusBar.hpp"
#include "ui/CSimpleTexture.hpp"
#include "ui/Util.hpp"
#include "util/Lua.hpp"
#include "util/Unimplemented.hpp"
@ -38,7 +39,22 @@ static int32_t Script_GetMinMaxValues(lua_State* L) {
}
static int32_t Script_SetMinMaxValues(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
auto type = CSimpleStatusBar::GetObjectType();
auto statusBar = static_cast<CSimpleStatusBar*>(FrameScript_GetObjectThis(L, type));
if (!lua_isnumber(L, 2) || !lua_isnumber(L, 3)) {
return luaL_error(L, "Usage: %s:SetMinMaxValues(min, max)", statusBar->GetDisplayName());
}
auto minval = lua_tonumber(L, 2);
auto maxval = lua_tonumber(L, 3);
if (minval < -1.0e12 || minval > 1.0e12 || maxval < -1.0e12 || maxval > 1.0e12) {
return luaL_error(L, "Min or Max out of range");
}
if (maxval - minval > 1.0e12) {
return luaL_error(L, "Min and Max too far apart");
}
statusBar->SetMinMaxValues(minval, maxval);
return 0;
}
static int32_t Script_GetValue(lua_State* L) {
@ -49,15 +65,72 @@ static int32_t Script_GetValue(lua_State* L) {
}
static int32_t Script_SetValue(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
auto type = CSimpleStatusBar::GetObjectType();
auto statusBar = static_cast<CSimpleStatusBar*>(FrameScript_GetObjectThis(L, type));
if (!lua_isnumber(L, 2)) {
return luaL_error(L, "Usage: %s:SetValue(value)", statusBar->GetDisplayName());
}
auto value = lua_tonumber(L, 2);
statusBar->SetValue(value);
return 0;
}
static int32_t Script_GetStatusBarTexture(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
auto type = CSimpleStatusBar::GetObjectType();
auto statusBar = static_cast<CSimpleStatusBar*>(FrameScript_GetObjectThis(L, type));
auto texture = statusBar->m_barTexture;
if (texture) {
if (!texture->lua_registered) {
texture->RegisterScriptObject(nullptr);
}
lua_rawgeti(L, LUA_REGISTRYINDEX, texture->lua_objectRef);
} else {
lua_pushnil(L);
}
return 1;
}
static int32_t Script_SetStatusBarTexture(lua_State* L) {
WHOA_UNIMPLEMENTED(0);
auto type = CSimpleStatusBar::GetObjectType();
auto statusBar = static_cast<CSimpleStatusBar*>(FrameScript_GetObjectThis(L, type));
int32_t layer = 2;
if (lua_isstring(L, 3)) {
StringToDrawLayer(lua_tolstring(L, 3, nullptr), layer);
}
if (lua_type(L, 2) == LUA_TTABLE) {
lua_rawgeti(L, 2, 0);
auto texture = static_cast<CSimpleTexture*>(lua_touserdata(L, -1));
lua_settop(L, -2);
if (!texture) {
return luaL_error(L, "%s:SetStatusBarTexture(): Couldn't find 'this' in texture", statusBar->GetDisplayName());
} else {
auto textureType = CSimpleTexture::GetObjectType();
if (!texture->IsA(textureType)) {
return luaL_error(L, "%s:SetStatusBarTexture(): Wrong object type, expected texture", statusBar->GetDisplayName());
}
}
statusBar->SetBarTexture(texture, layer);
return 0;
}
if (lua_isstring(L, 2)) {
auto texFile = lua_tostring(L, 2);
statusBar->SetBarTexture(texFile, layer);
return 0;
}
if (lua_type(L, 2) != LUA_TNIL) {
luaL_error(L, "Usage: %s:SetStatusBarTexture(texture or \"texture\" or nil [, \"layer\"])", statusBar->GetDisplayName());
}
statusBar->SetBarTexture(static_cast<CSimpleTexture*>(nullptr), 2);
return 0;
}
static int32_t Script_GetStatusBarColor(lua_State* L) {