Skip to content

Commit c98e4dc

Browse files
committed
Bug fixing / UI improvements
1 parent e9d65db commit c98e4dc

13 files changed

Lines changed: 419 additions & 222 deletions

File tree

frontend/src/components/blockly/component.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {definition as lego_get_mode_dataset} from './lego_get_mode_dataset.js'
3030
import {definition as lego_select_mode} from './lego_select_mode.js'
3131
import {definition as gamepad_gamepad} from './mh_gamepad_gamepad.js'
3232
import {definition as gamepad_buttonpressed} from './mh_gamepad_buttonpressed.js'
33+
import {definition as gamepad_buttonsraw} from './mh_gamepad_buttonsraw.js'
3334
import {definition as gamepad_value} from './mh_gamepad_value.js'
3435
import {definition as gamepad_connected} from './mh_gamepad_connected.js'
3536
import {definition as mh_debug_millis} from './mh_debug_millis.js'
@@ -257,6 +258,8 @@ const customBlocks = {
257258

258259
"mh_gamepad_buttonpressed": gamepad_buttonpressed,
259260

261+
"mh_gamepad_buttonsraw": gamepad_buttonsraw,
262+
260263
"mh_gamepad_value": gamepad_value,
261264

262265
"mh_gamepad_connected": gamepad_connected,

frontend/src/components/blockly/mh_gamepad_buttonpressed.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,21 @@ export const definition = {
2727
"name" : "BUTTON",
2828
"options" : [
2929
[ "GAMEPAD_BUTTON_1", "GAMEPAD_BUTTON_1" ],
30+
[ "GAMEPAD_BUTTON_1", "GAMEPAD_BUTTON_2" ],
31+
[ "GAMEPAD_BUTTON_2", "GAMEPAD_BUTTON_3" ],
32+
[ "GAMEPAD_BUTTON_4", "GAMEPAD_BUTTON_4" ],
33+
[ "GAMEPAD_BUTTON_5", "GAMEPAD_BUTTON_5" ],
34+
[ "GAMEPAD_BUTTON_6", "GAMEPAD_BUTTON_6" ],
35+
[ "GAMEPAD_BUTTON_7", "GAMEPAD_BUTTON_7" ],
36+
[ "GAMEPAD_BUTTON_8", "GAMEPAD_BUTTON_8" ],
37+
[ "GAMEPAD_BUTTON_9", "GAMEPAD_BUTTON_9" ],
38+
[ "GAMEPAD_BUTTON_10", "GAMEPAD_BUTTON_10" ],
39+
[ "GAMEPAD_BUTTON_11", "GAMEPAD_BUTTON_11" ],
40+
[ "GAMEPAD_BUTTON_12", "GAMEPAD_BUTTON_12" ],
41+
[ "GAMEPAD_BUTTON_13", "GAMEPAD_BUTTON_13" ],
42+
[ "GAMEPAD_BUTTON_14", "GAMEPAD_BUTTON_14" ],
43+
[ "GAMEPAD_BUTTON_15", "GAMEPAD_BUTTON_15" ],
44+
[ "GAMEPAD_BUTTON_16", "GAMEPAD_BUTTON_16" ],
3045
]
3146
}
3247
],
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {colorGamepad} from './colors.js'
2+
3+
// clang-format off
4+
export const definition = {
5+
category : 'Gamepad',
6+
colour : colorGamepad,
7+
inputsForToolbox: {
8+
"GAMEPAD": {
9+
"shadow": {
10+
"type": "mh_gamepad_gamepad",
11+
"fields": {
12+
"GAMEPAD": "GAMEPAD1"
13+
}
14+
}
15+
}
16+
},
17+
blockdefinition : {
18+
"type" : "mh_gamepad_buttonsraw",
19+
"message0" : "Gets the raw button values of %1",
20+
"args0" : [
21+
{
22+
"type" : "input_value",
23+
"name" : "GAMEPAD",
24+
},
25+
],
26+
"output": null,
27+
"colour" : colorGamepad,
28+
"tooltip" : "Gets the raw button values of a Gamepad in as a 32bit integer",
29+
"helpUrl" : ""
30+
},
31+
generator : (block, generator) => {
32+
const gamepad = generator.valueToCode(block, 'GAMEPAD', 0);
33+
34+
const command = "gamepad.buttonsraw(" + gamepad + ")";
35+
36+
return [ command, 0 ];
37+
}
38+
};
39+
// clang-format on

frontend/src/components/blockly/mh_gamepad_value.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export const definition = {
3030
["GAMEPAD_LEFT_Y", "GAMEPAD_LEFT_Y"],
3131
["GAMEPAD_RIGHT_X", "GAMEPAD_RIGHT_X"],
3232
["GAMEPAD_RIGHT_Y", "GAMEPAD_RIGHT_Y"],
33+
["GAMEPAD_DPAD", "GAMEPAD_DPAD"],
3334
]
3435
}
3536
],

frontend/src/components/files/component.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323
<div class="section-title">Create New Project</div>
2424
<div class="input-group">
2525
<input type="text" id="newProjectName" placeholder="Enter project name...">
26-
<button class="btn btn-primary" id="createbutton">Create</button>
26+
<button class="btn btn-primary" id="createbutton" disabled>Create</button>
2727
</div>
28+
<div class="validation-hint" id="validationHint"></div>
2829
</div>
2930

3031
<div class="section">

frontend/src/components/files/component.js

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,50 @@ class FilesHTMLElement extends HTMLElement {
77
selectedProject = undefined;
88
autostartProject = undefined;
99

10+
/**
11+
* Validates project name and returns error message or empty string if valid.
12+
* Rules: not empty, no leading/trailing spaces, only alphanumeric and spaces allowed.
13+
*/
14+
validateProjectName(name) {
15+
if (!name || name.length === 0) {
16+
return 'Project name cannot be empty';
17+
}
18+
if (name.startsWith(' ')) {
19+
return 'Project name cannot start with a space';
20+
}
21+
if (name.endsWith(' ')) {
22+
return 'Project name cannot end with a space';
23+
}
24+
if (!/^[a-zA-Z0-9 ]+$/.test(name)) {
25+
return 'Only letters, numbers, and spaces are allowed';
26+
}
27+
return '';
28+
}
29+
30+
/**
31+
* Updates the validation UI based on input value.
32+
*/
33+
updateValidationUI() {
34+
const input = this.shadowRoot.getElementById('newProjectName');
35+
const hint = this.shadowRoot.getElementById('validationHint');
36+
const createBtn = this.shadowRoot.getElementById('createbutton');
37+
const value = input.value;
38+
39+
const error = this.validateProjectName(value);
40+
41+
if (error) {
42+
input.classList.add('invalid');
43+
hint.textContent = error;
44+
hint.classList.add('visible');
45+
createBtn.setAttribute('disabled', '');
46+
} else {
47+
input.classList.remove('invalid');
48+
hint.textContent = '';
49+
hint.classList.remove('visible');
50+
createBtn.removeAttribute('disabled');
51+
}
52+
}
53+
1054
connectedCallback() {
1155
const shadow = this.attachShadow({mode : 'open'})
1256

@@ -77,9 +121,16 @@ class FilesHTMLElement extends HTMLElement {
77121
this.openProject(this.selectedProject.name);
78122
});
79123

124+
const newProjectInput = this.shadowRoot.getElementById("newProjectName");
125+
newProjectInput.addEventListener("input", () => {
126+
this.updateValidationUI();
127+
});
128+
80129
this.shadowRoot.getElementById("createbutton").addEventListener("click", (event) => {
81-
var project = this.shadowRoot.getElementById("newProjectName").value;
82-
this.createProject(project);
130+
var project = newProjectInput.value;
131+
if (!this.validateProjectName(project)) {
132+
this.createProject(project);
133+
}
83134
});
84135

85136
this.setAutoStartProject(this.autostartProject);

frontend/src/components/files/style.css

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,29 @@ input[type="text"]:focus {
177177
border-color: var(--vscode-accent-blue);
178178
}
179179

180+
input[type="text"].invalid {
181+
border-color: var(--color-error);
182+
}
183+
184+
input[type="text"].invalid:focus {
185+
border-color: var(--color-error);
186+
}
187+
188+
/* Validation Hint */
189+
.validation-hint {
190+
font-size: var(--font-fixed-11);
191+
color: var(--color-error);
192+
min-height: 1.2em;
193+
margin-top: calc(-1 * var(--spacing-sm));
194+
padding-left: var(--spacing-xs);
195+
opacity: 0;
196+
transition: opacity var(--transition-fast);
197+
}
198+
199+
.validation-hint.visible {
200+
opacity: 1;
201+
}
202+
180203
input[type="text"]::placeholder {
181204
color: var(--vscode-text-tertiary);
182205
}

frontend/src/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -602,8 +602,8 @@ async function initBLEConnection() {
602602
btdevicelist.initialize();
603603

604604
bleClient.addEventListener(APP_EVENT_TYPE_LOG, (data) => {
605-
const logEvent = JSON.parse(new TextDecoder().decode(data));
606-
logger.addToLog(logEvent.message);
605+
const message = new TextDecoder().decode(data);
606+
logger.addToLog(message);
607607
});
608608

609609
bleClient.addEventListener(APP_EVENT_TYPE_PORTSTATUS, (data) => {

lib/btremote/src/btremote.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,11 +1079,7 @@ void BTRemote::publishLogMessages() {
10791079
String logMessage = loggingOutput_->waitForLogMessage(0);
10801080
while (logMessage.length() > 0) {
10811081
if (deviceConnected_ && readyForEvents_) {
1082-
std::vector<uint8_t> response;
1083-
createJsonResponse(response, [logMessage](JsonDocument &responseDoc) {
1084-
responseDoc["message"] = logMessage;
1085-
});
1086-
1082+
std::vector<uint8_t> response(logMessage.begin(), logMessage.end());
10871083
sendEvent(APP_EVENT_TYPE_LOG, response);
10881084
}
10891085

lib/megahub/include/megahub.h

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,28 @@
3434
#define PINMODE_INPUT_PULLDOWN 3002
3535
#define PINMODE_OUTPUT 3003
3636

37-
#define GAMEPAD1 4000
38-
#define GAMEPAD_BUTTON_1 5000
39-
#define GAMEPAD_LEFT_X 6000
40-
#define GAMEPAD_LEFT_Y 6001
41-
#define GAMEPAD_RIGHT_X 6002
42-
#define GAMEPAD_RIGHT_Y 6003
37+
#define GAMEPAD1 4000
38+
#define GAMEPAD_BUTTON_1 5000
39+
#define GAMEPAD_BUTTON_2 5001
40+
#define GAMEPAD_BUTTON_3 5002
41+
#define GAMEPAD_BUTTON_4 5003
42+
#define GAMEPAD_BUTTON_5 5004
43+
#define GAMEPAD_BUTTON_6 5005
44+
#define GAMEPAD_BUTTON_7 5006
45+
#define GAMEPAD_BUTTON_8 5007
46+
#define GAMEPAD_BUTTON_9 5008
47+
#define GAMEPAD_BUTTON_10 5009
48+
#define GAMEPAD_BUTTON_11 5010
49+
#define GAMEPAD_BUTTON_12 5011
50+
#define GAMEPAD_BUTTON_13 5012
51+
#define GAMEPAD_BUTTON_14 5013
52+
#define GAMEPAD_BUTTON_15 5014
53+
#define GAMEPAD_BUTTON_16 5015
54+
#define GAMEPAD_LEFT_X 6000
55+
#define GAMEPAD_LEFT_Y 6001
56+
#define GAMEPAD_RIGHT_X 6002
57+
#define GAMEPAD_RIGHT_Y 6003
58+
#define GAMEPAD_DPAD 6004
4359

4460
#define YAW 7000
4561
#define PITCH 7001
@@ -82,7 +98,7 @@ class Megahub {
8298
void registerThread(TaskHandle_t handle);
8399
void stopRunningThreads();
84100
void stopThread(TaskHandle_t handle);
85-
101+
86102
private:
87103
std::unique_ptr<InputDevices> inputdevices_;
88104
std::unique_ptr<LegoDevice> device1_;

0 commit comments

Comments
 (0)