metaforce/Runtime/GuiSys/CGuiTableGroup.cpp

232 lines
6.1 KiB
C++
Raw Normal View History

#include "Runtime/GuiSys/CGuiTableGroup.hpp"
#include "Runtime/Input/CFinalInput.hpp"
2016-03-10 16:23:16 -08:00
2021-04-10 01:42:06 -07:00
namespace metaforce {
2016-03-10 16:23:16 -08:00
2018-12-07 21:30:43 -08:00
bool CGuiTableGroup::CRepeatState::Update(float dt, bool state) {
if (x0_timer == 0.f) {
if (state) {
x0_timer = 0.6f;
return true;
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
} else {
if (state) {
x0_timer -= dt;
if (x0_timer <= 0.f) {
x0_timer = 0.05f;
return true;
}
} else {
x0_timer = 0.f;
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
}
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) {
2022-07-29 13:16:55 -07:00
if (input.PA() || input.PSpecialKey(ESpecialKey::Enter)) {
2018-12-07 21:30:43 -08:00
DoAdvance();
2022-07-29 13:16:55 -07:00
} else if (input.PB() || input.PSpecialKey(ESpecialKey::Esc)) {
2018-12-07 21:30:43 -08:00
DoCancel();
} else {
bool decrement;
if (xd1_vertical)
decrement = (input.DLAUp() || input.DDPUp());
2017-01-08 19:44:00 -08:00
else
2018-12-07 21:30:43 -08:00
decrement = (input.DLALeft() || input.DDPLeft());
2017-01-08 19:44:00 -08:00
2018-12-07 21:30:43 -08:00
bool increment;
if (xd1_vertical)
increment = (input.DLADown() || input.DDPDown());
else
increment = (input.DLARight() || input.DDPRight());
2017-01-08 19:44:00 -08:00
2018-12-07 21:30:43 -08:00
if (xb8_decRepeat.Update(input.DeltaTime(), decrement) && decrement) {
DoDecrement();
return;
}
2017-01-08 19:44:00 -08:00
2018-12-07 21:30:43 -08:00
if (xbc_incRepeat.Update(input.DeltaTime(), increment) && increment) {
DoIncrement();
return;
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
}
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
bool CGuiTableGroup::IsWorkerSelectable(int idx) const {
if (CGuiWidget* widget = GetWorkerWidget(idx))
return widget->GetIsSelectable();
return false;
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
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();
}
2017-01-08 19:44:00 -08:00
}
2019-01-21 20:23:51 -08:00
void CGuiTableGroup::DoSelectWorker(int worker) {
if (worker == xc4_userSelection)
return;
if (IsWorkerSelectable(worker)) {
int oldSel = xc4_userSelection;
SelectWorker(worker);
if (x104_doMenuSelChange)
x104_doMenuSelChange(this, oldSel);
}
}
void CGuiTableGroup::SetWorkersMouseActive(bool active) {
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
while (child) {
if (child->GetWorkerId() != -1)
child->SetMouseActive(active);
child = static_cast<CGuiWidget*>(child->GetNextSibling());
}
}
2018-12-07 21:30:43 -08:00
void CGuiTableGroup::DeactivateWorker(CGuiWidget* widget) { widget->SetIsActive(false); }
2017-01-08 19:44:00 -08:00
2018-12-07 21:30:43 -08:00
void CGuiTableGroup::ActivateWorker(CGuiWidget* widget) { widget->SetIsActive(true); }
2017-01-08 19:44:00 -08:00
2018-12-07 21:30:43 -08:00
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;
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
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;
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
void CGuiTableGroup::DoSelectPrevRow() {
DecrementSelectedRow();
DeactivateWorker(GetWorkerWidget(xc8_prevUserSelection));
ActivateWorker(GetWorkerWidget(xc4_userSelection));
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
void CGuiTableGroup::DoSelectNextRow() {
IncrementSelectedRow();
DeactivateWorker(GetWorkerWidget(xc8_prevUserSelection));
ActivateWorker(GetWorkerWidget(xc4_userSelection));
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
void CGuiTableGroup::DoCancel() {
if (xec_doMenuCancel)
xec_doMenuCancel(this);
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
void CGuiTableGroup::DoAdvance() {
if (xd4_doMenuAdvance)
xd4_doMenuAdvance(this);
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
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;
}
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
} else {
for (int sel = std::max(-1, xc4_userSelection - 1); sel >= 0; --sel) {
if (IsWorkerSelectable(sel)) {
SelectWorker(sel);
return true;
}
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
}
2017-01-08 19:44:00 -08:00
2018-12-07 21:30:43 -08:00
return false;
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
void CGuiTableGroup::DoDecrement() {
int oldSel = xc4_userSelection;
if (!PreDecrement())
return;
if (x104_doMenuSelChange)
x104_doMenuSelChange(this, oldSel);
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
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;
}
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
} else {
for (int sel = std::min(xc0_elementCount, xc4_userSelection + 1); sel < xc0_elementCount; ++sel) {
if (IsWorkerSelectable(sel)) {
SelectWorker(sel);
return true;
}
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
}
2017-01-08 19:44:00 -08:00
2018-12-07 21:30:43 -08:00
return false;
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
void CGuiTableGroup::DoIncrement() {
int oldSel = xc4_userSelection;
if (!PreIncrement())
return;
if (x104_doMenuSelChange)
x104_doMenuSelChange(this, oldSel);
2017-01-08 19:44:00 -08:00
}
2018-12-07 21:30:43 -08:00
std::shared_ptr<CGuiWidget> CGuiTableGroup::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) {
CGuiWidgetParms parms = ReadWidgetHeader(frame, in);
2016-03-17 19:45:45 -07:00
int elementCount = in.ReadInt16();
in.ReadInt16();
in.ReadLong();
int defaultSel = in.ReadInt16();
in.ReadInt16();
bool selectWraparound = in.ReadBool();
in.ReadBool();
in.ReadFloat();
in.ReadFloat();
in.ReadBool();
in.ReadFloat();
in.ReadInt16();
in.ReadInt16();
in.ReadInt16();
in.ReadInt16();
2018-12-07 21:30:43 -08:00
std::shared_ptr<CGuiWidget> ret = std::make_shared<CGuiTableGroup>(parms, elementCount, defaultSel, selectWraparound);
ret->ParseBaseInfo(frame, in, parms);
return ret;
2016-03-17 19:45:45 -07:00
}
2021-04-10 01:42:06 -07:00
} // namespace metaforce