1#include "Layout/WindowConfirmData.h"
2
3#include <time/seadDateTime.h>
4
5#include "Library/Base/StringUtil.h"
6#include "Library/Layout/LayoutActionFunction.h"
7#include "Library/Layout/LayoutActor.h"
8#include "Library/Layout/LayoutActorUtil.h"
9#include "Library/Layout/LayoutInitInfo.h"
10#include "Library/Math/MathUtil.h"
11#include "Library/Message/MessageHolder.h"
12#include "Library/Nerve/NerveSetupUtil.h"
13#include "Library/Nerve/NerveUtil.h"
14#include "Library/Play/Layout/SimpleLayoutAppearWaitEnd.h"
15
16#include "Util/StageInputFunction.h"
17
18namespace {
19NERVE_IMPL(WindowConfirmData, Disable);
20NERVE_IMPL(WindowConfirmData, Appear);
21NERVE_IMPL(WindowConfirmData, Vanish);
22NERVE_IMPL(WindowConfirmData, Select);
23NERVE_IMPL(WindowConfirmData, Wait);
24
25NERVES_MAKE_NOSTRUCT(WindowConfirmData, Disable, Appear, Vanish, Select, Wait);
26} // namespace
27
28WindowConfirmData::WindowConfirmData(const al::LayoutInitInfo& info, const char* layoutName,
29 const char* name, bool createDataParts)
30 : al::NerveExecutor(name) {
31 mWindowConfirmLayout = new al::SimpleLayoutAppearWaitEnd("セーブデータ確認ウィンドウ",
32 layoutName, info, nullptr, 0);
33 mParCursor = new al::LayoutActor("カーソル");
34 al::initLayoutPartsActor(mParCursor, mWindowConfirmLayout, info, "ParCursor", nullptr);
35
36 mParOptions[PaneType_Confirm] = new al::LayoutActor("決定");
37 al::initLayoutPartsActor(mParOptions[PaneType_Confirm], mWindowConfirmLayout, info, "ParList00",
38 nullptr);
39
40 mParOptions[PaneType_Cancel] = new al::LayoutActor("キャンセル");
41 al::initLayoutPartsActor(mParOptions[PaneType_Cancel], mWindowConfirmLayout, info, "ParList01",
42 nullptr);
43
44 if (createDataParts) {
45 mParData = new al::LayoutActor("対象データ");
46 al::initLayoutPartsActor(mParData, mWindowConfirmLayout, info, "ParData", nullptr);
47 }
48
49 initNerve(nerve: &Disable, stateCount: 0);
50}
51
52void WindowConfirmData::setConfirmMessage(const char16* message, const char16* confirmMessage,
53 const char16* cancelMessage) {
54 al::setPaneString(mWindowConfirmLayout, "TxtMessage", message, 0);
55 al::setPaneString(mParOptions[PaneType_Confirm], "TxtContent", confirmMessage, 0);
56 al::setPaneString(mParOptions[PaneType_Cancel], "TxtContent", cancelMessage, 0);
57}
58
59void WindowConfirmData::setConfirmData(al::LayoutActor* actor, nn::ui2d::TextureInfo* texture) {
60 al::setPaneString(mParData, "TxtNumber", al::getPaneStringBuffer(actor, "TxtNumber"), 0);
61 al::setPaneString(mParData, "TxtWorld", al::getPaneStringBuffer(actor, "TxtWorld"), 0);
62 al::setPaneString(mParData, "TxtShine", al::getPaneStringBuffer(actor, "TxtShine"), 0);
63 al::setPaneString(mParData, "TxtDay", al::getPaneStringBuffer(actor, "TxtDay"), 0);
64 al::setPaneString(mParData, "TxtPlay", al::getPaneStringBuffer(actor, "TxtPlay"), 0);
65 al::setPaneTexture(mParData, "PicDummy", texture);
66
67 al::startAction(layout: mParData, actionName: al::getActionName(layout: actor, paneName: "State"), paneName: "State");
68 al::startAction(layout: mParData, actionName: al::getActionName(layout: actor, paneName: "OnOff"), paneName: "OnOff");
69}
70
71void WindowConfirmData::updateConfirmDataDate() {
72 sead::DateTime dateTime(0);
73 dateTime.setNow();
74
75 al::ReplaceTimeInfo replaceTimeInfo;
76 al::createReplaceTimeInfoForDateTime(&replaceTimeInfo, dateTime.getUnixTime());
77
78 al::WStringTmp<128> dateStr(u"---");
79 al::replaceMessageTagTimeDirectDateDetail(&dateStr, mWindowConfirmLayout, replaceTimeInfo);
80 al::setPaneString(mParData, "TxtDay", dateStr.cstr(), 0);
81}
82
83void WindowConfirmData::appear() {
84 al::setNerve(user: this, nerve: &Appear);
85 mSelectionIndex = PaneType_Confirm;
86}
87
88void WindowConfirmData::appearWithChoicingCancel() {
89 al::setNerve(user: this, nerve: &Appear);
90 mSelectionIndex = PaneType_Cancel;
91}
92
93void WindowConfirmData::end() {
94 al::setNerve(user: this, nerve: &Vanish);
95}
96
97void WindowConfirmData::kill() {
98 mWindowConfirmLayout->kill();
99 al::setNerve(user: this, nerve: &Disable);
100}
101
102bool WindowConfirmData::isEndSelect() {
103 if (!al::isNerve(user: this, nerve: &Select))
104 return false;
105
106 if (!al::isActionPlaying(layout: mParCursor, actionName: "End", paneName: nullptr))
107 return false;
108
109 if (!al::isActionEnd(layout: mParCursor, paneName: nullptr))
110 return false;
111
112 if (!al::isActionPlaying(layout: mParOptions[mSelectionIndex], actionName: "Decide", paneName: nullptr))
113 return false;
114
115 if (!al::isActionEnd(layout: mParOptions[mSelectionIndex], paneName: nullptr))
116 return false;
117
118 return true;
119}
120
121bool WindowConfirmData::isDecided() {
122 return isEndSelect() && mSelectionIndex == PaneType_Confirm;
123}
124
125bool WindowConfirmData::isCanceled() {
126 return !isEndSelect() || mSelectionIndex == PaneType_Cancel;
127}
128
129bool WindowConfirmData::isDisable() {
130 return al::isNerve(user: this, nerve: &Disable);
131}
132
133void WindowConfirmData::exeAppear() {
134 if (al::isFirstStep(user: this)) {
135 mWindowConfirmLayout->appear();
136 al::startAction(layout: mParCursor, actionName: "Hide", paneName: nullptr);
137 changeSelectingIdx(index: mSelectionIndex);
138 }
139 if (mWindowConfirmLayout->isWait())
140 al::setNerve(user: this, nerve: &Wait);
141}
142
143void WindowConfirmData::changeSelectingIdx(s32 index) {
144 al::startAction(layout: mParOptions[PaneType_Confirm], actionName: index == PaneType_Confirm ? "Wait" : "Select",
145 paneName: nullptr);
146 al::startAction(layout: mParOptions[PaneType_Cancel], actionName: index == PaneType_Cancel ? "Wait" : "Select",
147 paneName: nullptr);
148 mSelectionIndex = (PaneType)index;
149}
150
151void WindowConfirmData::exeWait() {
152 if (al::isFirstStep(user: this)) {
153 updateCursorPos();
154 al::startAction(layout: mParCursor, actionName: "Appear", paneName: nullptr);
155 }
156
157 if (al::isActionPlaying(layout: mParCursor, actionName: "Appear", paneName: nullptr) && al::isActionEnd(layout: mParCursor, paneName: nullptr))
158 al::startAction(layout: mParCursor, actionName: "Wait", paneName: nullptr);
159
160 updateCursorPos();
161
162 if (rs::isRepeatUiDown(mWindowConfirmLayout)) {
163 if (mSelectionCooldown == 0)
164 changeSelectingIdx(index: al::modi(a: (mSelectionIndex + 1) + 2, b: 2));
165 mSelectionCooldown = al::modi(a: (mSelectionCooldown + 1) + 10, b: 10);
166 return;
167 }
168
169 if (rs::isRepeatUiUp(mWindowConfirmLayout)) {
170 if (mSelectionCooldown == 0)
171 changeSelectingIdx(index: al::modi(a: (mSelectionIndex - 1) + 2, b: 2));
172 mSelectionCooldown = al::modi(a: (mSelectionCooldown + 1) + 10, b: 10);
173 return;
174 }
175
176 if (rs::isTriggerUiDecide(mWindowConfirmLayout)) {
177 al::startHitReaction(mWindowConfirmLayout, "決定", nullptr);
178 al::setNerve(user: this, nerve: &Select);
179 return;
180 }
181
182 if (rs::isTriggerUiCancel(mWindowConfirmLayout)) {
183 al::startHitReaction(mWindowConfirmLayout, "キャンセル", nullptr);
184
185 if (mSelectionIndex != PaneType_Cancel) {
186 al::startAction(layout: mParOptions[PaneType_Confirm], actionName: "Wait", paneName: nullptr);
187 al::startAction(layout: mParOptions[PaneType_Cancel], actionName: "Select", paneName: nullptr);
188 mSelectionIndex = PaneType_Cancel;
189 updateCursorPos();
190 }
191
192 al::setNerve(user: this, nerve: &Select);
193 return;
194 }
195
196 mSelectionCooldown = 0;
197}
198
199void WindowConfirmData::updateCursorPos() {
200 sead::Vector2f paneTrans = sead::Vector2f::zero;
201 al::calcPaneTrans(&paneTrans, mParOptions[mSelectionIndex], "Cursor");
202 al::setLocalTrans(mParCursor, paneTrans);
203}
204
205void WindowConfirmData::exeSelect() {
206 if (al::isFirstStep(user: this)) {
207 al::startAction(layout: mParCursor, actionName: "End", paneName: nullptr);
208 al::startAction(layout: mParOptions[mSelectionIndex], actionName: "Decide", paneName: nullptr);
209 }
210}
211
212void WindowConfirmData::exeVanish() {
213 if (al::isFirstStep(user: this))
214 mWindowConfirmLayout->end();
215
216 if (al::isDead(mWindowConfirmLayout))
217 kill();
218}
219
220void WindowConfirmData::exeDisable() {}
221