Skip to content

Commit 6d9bec2

Browse files
committed
Added a new movement control method with a switch toggle to use a button interface.
1 parent 885d63f commit 6d9bec2

3 files changed

Lines changed: 184 additions & 35 deletions

File tree

index.html

Lines changed: 77 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,33 +27,87 @@ <h2>Demo Presets</h2>
2727
</div>
2828

2929
<div class="controls">
30-
<h2>Single Command</h2>
31-
<div class="row">
32-
<input
33-
id="command-input"
34-
type="text"
35-
placeholder="PLACE 0,0,NORTH"
36-
aria-label="Single command input"
37-
/>
38-
<button id="run-command" type="button">Run</button>
30+
<h2>Control Mode</h2>
31+
<label class="mode-toggle" for="button-mode-toggle">
32+
<input id="button-mode-toggle" type="checkbox" />
33+
Use button interface
34+
</label>
35+
</div>
36+
37+
<div id="text-controls">
38+
<div class="controls">
39+
<h2>Single Command</h2>
40+
<div class="row">
41+
<input
42+
id="command-input"
43+
type="text"
44+
placeholder="PLACE 0,0,NORTH"
45+
aria-label="Single command input"
46+
/>
47+
<button id="run-command" type="button">Run</button>
48+
</div>
49+
</div>
50+
51+
<div class="controls">
52+
<h2>Script Mode</h2>
53+
<textarea
54+
id="script-input"
55+
rows="8"
56+
placeholder="PLACE 0,0,NORTH&#10;MOVE&#10;RIGHT&#10;REPORT"
57+
aria-label="Script input"
58+
></textarea>
59+
<div class="row">
60+
<button id="step-script" type="button">Step</button>
61+
<button id="run-script" type="button">Run All</button>
62+
<button id="reset-script" type="button">Reset Script Cursor</button>
63+
<button id="reset-state" type="button">Reset Robot</button>
64+
</div>
65+
<ol id="script-preview" class="script-preview"></ol>
3966
</div>
4067
</div>
4168

42-
<div class="controls">
43-
<h2>Script Mode</h2>
44-
<textarea
45-
id="script-input"
46-
rows="8"
47-
placeholder="PLACE 0,0,NORTH&#10;MOVE&#10;RIGHT&#10;REPORT"
48-
aria-label="Script input"
49-
></textarea>
50-
<div class="row">
51-
<button id="step-script" type="button">Step</button>
52-
<button id="run-script" type="button">Run All</button>
53-
<button id="reset-script" type="button">Reset Script Cursor</button>
54-
<button id="reset-state" type="button">Reset Robot</button>
69+
<div id="button-controls" class="hidden-controls">
70+
<div class="controls">
71+
<h2>Button Commands</h2>
72+
<div class="place-controls">
73+
<label for="place-x">X</label>
74+
<select id="place-x" aria-label="Place X coordinate">
75+
<option>0</option>
76+
<option>1</option>
77+
<option>2</option>
78+
<option>3</option>
79+
<option>4</option>
80+
<option>5</option>
81+
</select>
82+
83+
<label for="place-y">Y</label>
84+
<select id="place-y" aria-label="Place Y coordinate">
85+
<option>0</option>
86+
<option>1</option>
87+
<option>2</option>
88+
<option>3</option>
89+
<option>4</option>
90+
<option>5</option>
91+
</select>
92+
93+
<label for="place-f">Facing</label>
94+
<select id="place-f" aria-label="Place facing direction">
95+
<option>NORTH</option>
96+
<option>EAST</option>
97+
<option>SOUTH</option>
98+
<option>WEST</option>
99+
</select>
100+
<button id="place-button" type="button">PLACE</button>
101+
</div>
102+
103+
<div class="action-pad">
104+
<button data-command="LEFT" type="button">LEFT</button>
105+
<button data-command="MOVE" type="button">MOVE</button>
106+
<button data-command="RIGHT" type="button">RIGHT</button>
107+
<button data-command="REPORT" type="button">REPORT</button>
108+
<button id="button-reset-state" type="button">RESET</button>
109+
</div>
55110
</div>
56-
<ol id="script-preview" class="script-preview"></ol>
57111
</div>
58112

59113
<div class="status">

web/app.js

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ const stateLine = document.getElementById("state-line");
1818
const latestStatus = document.getElementById("latest-status");
1919
const scriptPreview = document.getElementById("script-preview");
2020
const presetButtons = document.querySelectorAll(".preset");
21+
const buttonModeToggle = document.getElementById("button-mode-toggle");
22+
const textControls = document.getElementById("text-controls");
23+
const buttonControls = document.getElementById("button-controls");
24+
const placeX = document.getElementById("place-x");
25+
const placeY = document.getElementById("place-y");
26+
const placeF = document.getElementById("place-f");
27+
const placeButton = document.getElementById("place-button");
28+
const actionPadButtons = document.querySelectorAll("[data-command]");
29+
const buttonResetState = document.getElementById("button-reset-state");
2130

2231
let state = { ...initialState };
2332
let scriptCommands = [];
@@ -117,6 +126,30 @@ function reloadScriptCommands() {
117126
renderScriptPreview();
118127
}
119128

129+
function resetRobotState() {
130+
state = { ...initialState };
131+
renderState();
132+
renderBoard();
133+
setStatusBanner("success", "Command success: Robot state reset");
134+
appendLog({
135+
commandText: "RESET",
136+
status: "success",
137+
message: "Command success: Robot state reset",
138+
reportOutput: null,
139+
});
140+
}
141+
142+
function toggleControlMode(useButtonControls) {
143+
textControls.classList.toggle("hidden-controls", useButtonControls);
144+
buttonControls.classList.toggle("hidden-controls", !useButtonControls);
145+
setStatusBanner(
146+
"neutral",
147+
useButtonControls
148+
? "Button mode enabled: use PLACE/LEFT/MOVE/RIGHT/REPORT controls"
149+
: "Text mode enabled: use command or script input",
150+
);
151+
}
152+
120153
runCommandButton.addEventListener("click", () => {
121154
const commandText = commandInput.value;
122155
executeCommand(commandText);
@@ -172,16 +205,7 @@ resetScriptButton.addEventListener("click", () => {
172205
});
173206

174207
resetStateButton.addEventListener("click", () => {
175-
state = { ...initialState };
176-
renderState();
177-
renderBoard();
178-
setStatusBanner("success", "Command success: Robot state reset");
179-
appendLog({
180-
commandText: "RESET",
181-
status: "success",
182-
message: "Command success: Robot state reset",
183-
reportOutput: null,
184-
});
208+
resetRobotState();
185209
});
186210

187211
scriptInput.addEventListener("input", () => {
@@ -197,6 +221,26 @@ presetButtons.forEach((button) => {
197221
});
198222
});
199223

224+
buttonModeToggle.addEventListener("change", (event) => {
225+
toggleControlMode(event.target.checked);
226+
});
227+
228+
placeButton.addEventListener("click", () => {
229+
const command = `PLACE ${placeX.value},${placeY.value},${placeF.value}`;
230+
executeCommand(command);
231+
});
232+
233+
actionPadButtons.forEach((button) => {
234+
button.addEventListener("click", () => {
235+
executeCommand(button.dataset.command);
236+
});
237+
});
238+
239+
buttonResetState.addEventListener("click", () => {
240+
resetRobotState();
241+
});
242+
200243
renderState();
201244
renderBoard();
202245
reloadScriptCommands();
246+
toggleControlMode(false);

web/styles.css

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,8 @@ button {
185185
}
186186

187187
input,
188-
textarea {
188+
textarea,
189+
select {
189190
width: 100%;
190191
border: 2px solid #c8d7f8;
191192
border-radius: 12px;
@@ -196,7 +197,8 @@ textarea {
196197
}
197198

198199
input:focus,
199-
textarea:focus {
200+
textarea:focus,
201+
select:focus {
200202
outline: none;
201203
border-color: #4f8dff;
202204
box-shadow: 0 0 0 4px rgba(79, 141, 255, 0.22);
@@ -233,6 +235,47 @@ button:active {
233235
box-shadow: 0 1px 0 rgba(24, 56, 120, 0.72);
234236
}
235237

238+
.mode-toggle {
239+
display: inline-flex;
240+
align-items: center;
241+
gap: 0.45rem;
242+
font-weight: 700;
243+
color: #23407f;
244+
}
245+
246+
.mode-toggle input {
247+
width: 18px;
248+
height: 18px;
249+
}
250+
251+
.hidden-controls {
252+
display: none;
253+
}
254+
255+
.place-controls {
256+
display: grid;
257+
grid-template-columns: repeat(4, minmax(70px, 1fr));
258+
gap: 0.5rem;
259+
align-items: center;
260+
margin-bottom: 0.75rem;
261+
}
262+
263+
.place-controls label {
264+
font-weight: 700;
265+
color: #244285;
266+
}
267+
268+
.action-pad {
269+
display: grid;
270+
grid-template-columns: repeat(3, minmax(90px, 1fr));
271+
gap: 0.55rem;
272+
}
273+
274+
.action-pad button[data-command="MOVE"] {
275+
grid-column: 2 / span 1;
276+
background: linear-gradient(145deg, #d7fff3, #8af0cf);
277+
}
278+
236279
.board {
237280
display: grid;
238281
grid-template-columns: repeat(6, minmax(44px, 1fr));
@@ -358,4 +401,12 @@ button:active {
358401
h1 {
359402
box-shadow: 0 10px 0 rgba(17, 34, 72, 0.6);
360403
}
404+
405+
.place-controls {
406+
grid-template-columns: repeat(2, minmax(70px, 1fr));
407+
}
408+
409+
.action-pad {
410+
grid-template-columns: repeat(2, minmax(90px, 1fr));
411+
}
361412
}

0 commit comments

Comments
 (0)