#include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/GuiSys/CGuiWidget.hpp" #include "Runtime/GuiSys/CGuiFrame.hpp" #include namespace metaforce { static logvisor::Module Log("metaforce::CGuiWidget"); CGuiWidget::CGuiWidget(const CGuiWidgetParms& parms) : x70_selfId(parms.x6_selfId) , x72_parentId(parms.x8_parentId) , m_initColor(parms.x10_color) , xa4_color(parms.x10_color) , xa8_color2(parms.x10_color) , xac_drawFlags(parms.x14_drawFlags) , xb0_frame(parms.x0_frame) , m_name(parms.m_name) { xb6_24_pg = parms.xd_g; xb6_25_isVisible = parms.xa_defaultVisible; xb6_26_isActive = parms.xb_defaultActive; xb6_29_cullFaces = parms.xc_cullFaces; RecalcWidgetColor(ETraversalMode::Single); } CGuiWidget::CGuiWidgetParms CGuiWidget::ReadWidgetHeader(CGuiFrame* frame, CInputStream& in) { std::string name = in.Get(); s16 selfId = frame->GetWidgetIdDB().AddWidget(name); std::string parent = in.Get(); s16 parentId = frame->GetWidgetIdDB().AddWidget(parent); bool useAnimController = in.ReadBool(); bool defaultVis = in.ReadBool(); bool defaultActive = in.ReadBool(); bool cullFaces = in.ReadBool(); zeus::CColor color = in.Get(); EGuiModelDrawFlags df = EGuiModelDrawFlags(in.ReadLong()); return CGuiWidget::CGuiWidgetParms(frame, useAnimController, selfId, parentId, defaultVis, defaultActive, cullFaces, color, df, true, false, std::move(name)); } std::shared_ptr CGuiWidget::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) { CGuiWidgetParms parms = ReadWidgetHeader(frame, in); std::shared_ptr ret = std::make_shared(parms); ret->ParseBaseInfo(frame, in, parms); return ret; } void CGuiWidget::Initialize() {} void CGuiWidget::ParseBaseInfo(CGuiFrame* frame, CInputStream& in, const CGuiWidgetParms& parms) { CGuiWidget* parent = frame->FindWidget(parms.x8_parentId); bool isWorker = in.ReadBool(); if (isWorker) xb4_workerId = in.ReadInt16(); zeus::CVector3f trans = in.Get(); zeus::CMatrix3f orient = in.Get(); x74_transform = zeus::CTransform(orient, trans); m_initTransform = x74_transform; ReapplyXform(); in.Get(); // Unused in.ReadLong(); in.ReadShort(); if (isWorker) { if (!parent->AddWorkerWidget(this)) { Log.report(logvisor::Warning, FMT_STRING("Warning: Discarding useless worker id. Parent is not a compound widget.")); xb4_workerId = -1; } } parent->AddChildWidget(this, false, true); m_initLocalXF = x4_localXF; } void CGuiWidget::Reset(ETraversalMode mode) { xa4_color = m_initColor; xa8_color2 = m_initColor; x74_transform = m_initTransform; ReapplyXform(); x4_localXF = m_initLocalXF; RecalculateTransforms(); switch (mode) { case ETraversalMode::Children: { CGuiWidget* child = static_cast(GetChildObject()); if (child) child->Reset(ETraversalMode::ChildrenAndSiblings); break; } case ETraversalMode::ChildrenAndSiblings: { CGuiWidget* child = static_cast(GetChildObject()); if (child) child->Reset(ETraversalMode::ChildrenAndSiblings); CGuiWidget* nextSib = static_cast(GetNextSibling()); if (nextSib) nextSib->Reset(ETraversalMode::ChildrenAndSiblings); break; } default: break; } } void CGuiWidget::Update(float dt) { CGuiWidget* ch = static_cast(GetChildObject()); if (ch) ch->Update(dt); CGuiWidget* sib = static_cast(GetNextSibling()); if (sib) sib->Update(dt); } void CGuiWidget::Draw(const CGuiWidgetDrawParms& parms) {} void CGuiWidget::ProcessUserInput(const CFinalInput& input) {} void CGuiWidget::Touch() {} bool CGuiWidget::GetIsVisible() const { return xb6_25_isVisible; } bool CGuiWidget::GetIsActive() const { return xb6_26_isActive; } bool CGuiWidget::GetMouseActive() const { return m_mouseActive; } void CGuiWidget::InitializeRGBAFactor() { CGuiWidget* child = static_cast(GetChildObject()); if (child) child->InitializeRGBAFactor(); CGuiWidget* nextSib = static_cast(GetNextSibling()); if (nextSib) nextSib->InitializeRGBAFactor(); } bool CGuiWidget::GetIsFinishedLoadingWidgetSpecific() { return true; } void CGuiWidget::SetTransform(const zeus::CTransform& xf) { x74_transform = xf; ReapplyXform(); } void CGuiWidget::SetIdlePosition(const zeus::CVector3f& pos, bool reapply) { x74_transform.origin = pos; if (reapply) ReapplyXform(); } void CGuiWidget::ReapplyXform() { RotateReset(); SetLocalPosition(zeus::skZero3f); MultiplyO2P(x74_transform); } void CGuiWidget::AddChildWidget(CGuiWidget* widget, bool makeWorldLocal, bool atEnd) { AddChildObject(widget, makeWorldLocal, atEnd); } bool CGuiWidget::AddWorkerWidget(CGuiWidget* worker) { return false; } void CGuiWidget::SetVisibility(bool visible, ETraversalMode mode) { switch (mode) { case ETraversalMode::Children: { auto* child = static_cast(GetChildObject()); if (child) { child->SetVisibility(visible, ETraversalMode::ChildrenAndSiblings); } break; } case ETraversalMode::ChildrenAndSiblings: { auto* child = static_cast(GetChildObject()); if (child) { child->SetVisibility(visible, ETraversalMode::ChildrenAndSiblings); } auto* nextSib = static_cast(GetNextSibling()); if (nextSib) { nextSib->SetVisibility(visible, ETraversalMode::ChildrenAndSiblings); } break; } default: break; } SetIsVisible(visible); } void CGuiWidget::RecalcWidgetColor(ETraversalMode mode) { CGuiWidget* parent = static_cast(GetParent()); if (parent) xa8_color2 = xa4_color * parent->xa8_color2; else xa8_color2 = xa4_color; switch (mode) { case ETraversalMode::ChildrenAndSiblings: { CGuiWidget* nextSib = static_cast(GetNextSibling()); if (nextSib) nextSib->RecalcWidgetColor(ETraversalMode::ChildrenAndSiblings); [[fallthrough]]; } case ETraversalMode::Children: { CGuiWidget* child = static_cast(GetChildObject()); if (child) child->RecalcWidgetColor(ETraversalMode::ChildrenAndSiblings); break; } default: break; } } CGuiWidget* CGuiWidget::FindWidget(s16 id) { if (x70_selfId == id) return this; CGuiWidget* child = static_cast(GetChildObject()); if (child) { CGuiWidget* found = child->FindWidget(id); if (found) return found; } CGuiWidget* nextSib = static_cast(GetNextSibling()); if (nextSib) { CGuiWidget* found = nextSib->FindWidget(id); if (found) return found; } return nullptr; } bool CGuiWidget::GetIsFinishedLoading() { return GetIsFinishedLoadingWidgetSpecific(); } void CGuiWidget::DispatchInitialize() { Initialize(); CGuiWidget* ch = static_cast(GetChildObject()); if (ch) ch->DispatchInitialize(); CGuiWidget* sib = static_cast(GetNextSibling()); if (sib) sib->DispatchInitialize(); } void CGuiWidget::SetColor(const zeus::CColor& color) { xa4_color = color; RecalcWidgetColor(ETraversalMode::Children); } void CGuiWidget::OnActiveChange() {} void CGuiWidget::OnVisibleChange() {} void CGuiWidget::SetIsVisible(bool visible) { xb6_25_isVisible = visible; OnVisibleChange(); } void CGuiWidget::SetIsActive(bool active) { if (active == xb6_26_isActive) { return; } xb6_26_isActive = active; OnActiveChange(); } } // namespace metaforce