mirror of https://github.com/AxioDL/metaforce.git
212 lines
5.6 KiB
C++
212 lines
5.6 KiB
C++
#include "CGuiTableGroup.hpp"
|
|
#include "Input/CFinalInput.hpp"
|
|
|
|
namespace urde {
|
|
|
|
bool CGuiTableGroup::CRepeatState::Update(float dt, bool state) {
|
|
if (x0_timer == 0.f) {
|
|
if (state) {
|
|
x0_timer = 0.6f;
|
|
return true;
|
|
}
|
|
} else {
|
|
if (state) {
|
|
x0_timer -= dt;
|
|
if (x0_timer <= 0.f) {
|
|
x0_timer = 0.05f;
|
|
return true;
|
|
}
|
|
} else {
|
|
x0_timer = 0.f;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
CGuiTableGroup::CGuiTableGroup(const CGuiWidgetParms& parms, int elementCount, int defaultSel, bool selectWraparound)
|
|
: CGuiCompoundWidget(parms)
|
|
, xc0_elementCount(elementCount)
|
|
, xc4_userSelection(defaultSel)
|
|
, xc8_prevUserSelection(defaultSel)
|
|
, xcc_defaultUserSelection(defaultSel)
|
|
, xd0_selectWraparound(selectWraparound) {}
|
|
|
|
void CGuiTableGroup::ProcessUserInput(const CFinalInput& input) {
|
|
if (input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter)) {
|
|
DoAdvance();
|
|
} else if (input.PB() || input.PSpecialKey(boo::ESpecialKey::Esc)) {
|
|
DoCancel();
|
|
} else {
|
|
bool decrement;
|
|
if (xd1_vertical)
|
|
decrement = (input.DLAUp() || input.DDPUp());
|
|
else
|
|
decrement = (input.DLALeft() || input.DDPLeft());
|
|
|
|
bool increment;
|
|
if (xd1_vertical)
|
|
increment = (input.DLADown() || input.DDPDown());
|
|
else
|
|
increment = (input.DLARight() || input.DDPRight());
|
|
|
|
if (xb8_decRepeat.Update(input.DeltaTime(), decrement) && decrement) {
|
|
DoDecrement();
|
|
return;
|
|
}
|
|
|
|
if (xbc_incRepeat.Update(input.DeltaTime(), increment) && increment) {
|
|
DoIncrement();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CGuiTableGroup::IsWorkerSelectable(int idx) const {
|
|
if (CGuiWidget* widget = GetWorkerWidget(idx))
|
|
return widget->GetIsSelectable();
|
|
return false;
|
|
}
|
|
|
|
void CGuiTableGroup::SelectWorker(int idx) {
|
|
idx = zeus::clamp(0, idx, xc0_elementCount - 1);
|
|
if (idx < xc4_userSelection) {
|
|
while (idx != xc4_userSelection)
|
|
DoSelectPrevRow();
|
|
} else {
|
|
while (idx != xc4_userSelection)
|
|
DoSelectNextRow();
|
|
}
|
|
}
|
|
|
|
void CGuiTableGroup::DeactivateWorker(CGuiWidget* widget) { widget->SetIsActive(false); }
|
|
|
|
void CGuiTableGroup::ActivateWorker(CGuiWidget* widget) { widget->SetIsActive(true); }
|
|
|
|
CGuiTableGroup::TableSelectReturn CGuiTableGroup::DecrementSelectedRow() {
|
|
xc8_prevUserSelection = xc4_userSelection;
|
|
--xc4_userSelection;
|
|
if (xc4_userSelection < 0) {
|
|
xc4_userSelection = xd0_selectWraparound ? xc0_elementCount - 1 : 0;
|
|
return xd0_selectWraparound ? TableSelectReturn::WrappedAround : TableSelectReturn::Unchanged;
|
|
}
|
|
return TableSelectReturn::Changed;
|
|
}
|
|
|
|
CGuiTableGroup::TableSelectReturn CGuiTableGroup::IncrementSelectedRow() {
|
|
xc8_prevUserSelection = xc4_userSelection;
|
|
++xc4_userSelection;
|
|
if (xc4_userSelection >= xc0_elementCount) {
|
|
xc4_userSelection = xd0_selectWraparound ? 0 : xc0_elementCount - 1;
|
|
return xd0_selectWraparound ? TableSelectReturn::WrappedAround : TableSelectReturn::Unchanged;
|
|
}
|
|
return TableSelectReturn::Changed;
|
|
}
|
|
|
|
void CGuiTableGroup::DoSelectPrevRow() {
|
|
DecrementSelectedRow();
|
|
DeactivateWorker(GetWorkerWidget(xc8_prevUserSelection));
|
|
ActivateWorker(GetWorkerWidget(xc4_userSelection));
|
|
}
|
|
|
|
void CGuiTableGroup::DoSelectNextRow() {
|
|
IncrementSelectedRow();
|
|
DeactivateWorker(GetWorkerWidget(xc8_prevUserSelection));
|
|
ActivateWorker(GetWorkerWidget(xc4_userSelection));
|
|
}
|
|
|
|
void CGuiTableGroup::DoCancel() {
|
|
if (xec_doMenuCancel)
|
|
xec_doMenuCancel(this);
|
|
}
|
|
|
|
void CGuiTableGroup::DoAdvance() {
|
|
if (xd4_doMenuAdvance)
|
|
xd4_doMenuAdvance(this);
|
|
}
|
|
|
|
bool CGuiTableGroup::PreDecrement() {
|
|
if (xd0_selectWraparound) {
|
|
for (int sel = (xc4_userSelection + xc0_elementCount - 1) % xc0_elementCount; sel != xc4_userSelection;
|
|
sel = (sel + xc0_elementCount - 1) % xc0_elementCount) {
|
|
if (IsWorkerSelectable(sel)) {
|
|
SelectWorker(sel);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
for (int sel = std::max(-1, xc4_userSelection - 1); sel >= 0; --sel) {
|
|
if (IsWorkerSelectable(sel)) {
|
|
SelectWorker(sel);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CGuiTableGroup::DoDecrement() {
|
|
int oldSel = xc4_userSelection;
|
|
if (!PreDecrement())
|
|
return;
|
|
if (x104_doMenuSelChange)
|
|
x104_doMenuSelChange(this, oldSel);
|
|
}
|
|
|
|
bool CGuiTableGroup::PreIncrement() {
|
|
if (xd0_selectWraparound) {
|
|
for (int sel = (xc4_userSelection + 1) % xc0_elementCount; sel != xc4_userSelection;
|
|
sel = (sel + 1) % xc0_elementCount) {
|
|
if (IsWorkerSelectable(sel)) {
|
|
SelectWorker(sel);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
for (int sel = std::min(xc0_elementCount, xc4_userSelection + 1); sel < xc0_elementCount; ++sel) {
|
|
if (IsWorkerSelectable(sel)) {
|
|
SelectWorker(sel);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CGuiTableGroup::DoIncrement() {
|
|
int oldSel = xc4_userSelection;
|
|
if (!PreIncrement())
|
|
return;
|
|
if (x104_doMenuSelChange)
|
|
x104_doMenuSelChange(this, oldSel);
|
|
}
|
|
|
|
std::shared_ptr<CGuiWidget> CGuiTableGroup::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) {
|
|
CGuiWidgetParms parms = ReadWidgetHeader(frame, in);
|
|
|
|
int elementCount = in.readInt16Big();
|
|
in.readInt16Big();
|
|
in.readUint32Big();
|
|
int defaultSel = in.readInt16Big();
|
|
in.readInt16Big();
|
|
bool selectWraparound = in.readBool();
|
|
in.readBool();
|
|
in.readFloatBig();
|
|
in.readFloatBig();
|
|
in.readBool();
|
|
in.readFloatBig();
|
|
in.readInt16Big();
|
|
in.readInt16Big();
|
|
in.readInt16Big();
|
|
in.readInt16Big();
|
|
|
|
std::shared_ptr<CGuiWidget> ret = std::make_shared<CGuiTableGroup>(parms, elementCount, defaultSel, selectWraparound);
|
|
ret->ParseBaseInfo(frame, in, parms);
|
|
return ret;
|
|
}
|
|
|
|
} // namespace urde
|