Skip to content

Commit bdadf84

Browse files
committedJan 6, 2025
more compact display of check, search, ... results
1 parent 9e19f85 commit bdadf84

File tree

9 files changed

+143
-55
lines changed

9 files changed

+143
-55
lines changed
 

‎npm-module/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"author": "Envox <eez@envox.hr>",
44
"description": "EEZ Studio for building standalone dashboard applications",
55
"repository": "https://github.com/eez-open/studio",
6-
"version": "0.0.57",
6+
"version": "0.0.58",
77
"revision": "1",
88
"license": "GPL-3.0-only",
99
"files": ["packages", "libs", "resources"]

‎packages/eez-studio-ui/tree.tsx

+55-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export const TreeRow = observer(
2929
toggleExpanded: (level: number, node: ITreeNode) => void;
3030
collapsable: boolean;
3131
rowPadding?: number;
32+
collapseSingleChild: boolean;
3233
}> {
3334
constructor(props: any) {
3435
super(props);
@@ -56,6 +57,22 @@ export const TreeRow = observer(
5657
render() {
5758
let childrenRows: JSX.Element[] = [];
5859

60+
const collapsedChildren = [];
61+
let children = this.props.node.children;
62+
if (
63+
!this.props.showOnlyChildren &&
64+
this.props.collapseSingleChild
65+
) {
66+
while (children.length == 1) {
67+
const singleChild = children[0];
68+
if (singleChild.children.length == 0) {
69+
break;
70+
}
71+
collapsedChildren.push(singleChild);
72+
children = singleChild.children;
73+
}
74+
}
75+
5976
if (
6077
this.props.showOnlyChildren ||
6178
this.props.getExpanded(this.props.level, this.props.node)
@@ -64,7 +81,7 @@ export const TreeRow = observer(
6481
? this.props.level
6582
: this.props.level + 1;
6683

67-
this.props.node.children.forEach(child => {
84+
children.forEach(child => {
6885
childrenRows.push(
6986
<TreeRow
7087
key={child.id}
@@ -77,6 +94,7 @@ export const TreeRow = observer(
7794
toggleExpanded={this.props.toggleExpanded}
7895
collapsable={this.props.collapsable}
7996
rowPadding={this.props.rowPadding}
97+
collapseSingleChild={this.props.collapseSingleChild}
8098
/>
8199
);
82100
});
@@ -101,6 +119,38 @@ export const TreeRow = observer(
101119

102120
let labelText = this.props.node.label;
103121

122+
if (collapsedChildren.length > 0) {
123+
labelText = (
124+
<span
125+
style={{
126+
display: "inline-flex",
127+
alignItems: "start"
128+
}}
129+
>
130+
{labelText}
131+
{collapsedChildren.map(child => (
132+
<span
133+
key={child.id}
134+
style={{
135+
display: "inline-flex",
136+
alignItems: "start"
137+
}}
138+
>
139+
<span
140+
style={{
141+
padding: "0 5px",
142+
fontWeight: "bold"
143+
}}
144+
>
145+
/
146+
</span>
147+
{child.label}
148+
</span>
149+
))}
150+
</span>
151+
);
152+
}
153+
104154
let label: JSX.Element | undefined;
105155
let triangle: JSX.Element | undefined;
106156

@@ -190,6 +240,7 @@ export const Tree = observer(
190240
style?: React.CSSProperties;
191241
collapsable?: boolean;
192242
rowPadding?: number;
243+
collapseSingleChild?: boolean;
193244
},
194245
{}
195246
> {
@@ -345,6 +396,9 @@ export const Tree = observer(
345396
toggleExpanded={this.toggleExpanded}
346397
collapsable={this.props.collapsable ?? true}
347398
rowPadding={this.props.rowPadding}
399+
collapseSingleChild={
400+
this.props.collapseSingleChild ?? false
401+
}
348402
/>
349403
</div>
350404
);

‎packages/project-editor/build/build.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ var checkTransformer: (object: IEezObject) => IMessage[] = createTransformer(
661661
new Message(
662662
MessageType.GROUP,
663663
getLabel(object),
664-
undefined,
664+
object,
665665
messages as Message[]
666666
)
667667
];

‎packages/project-editor/flow/component.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -2020,7 +2020,9 @@ export class Component extends EezObject {
20202020
componentInput.displayName ||
20212021
componentInput.name
20222022
}"`,
2023-
component
2023+
component,
2024+
undefined,
2025+
true
20242026
)
20252027
);
20262028
}
@@ -2096,7 +2098,9 @@ export class Component extends EezObject {
20962098
)
20972099
: componentOutput.name
20982100
}" is not connected`,
2099-
component
2101+
component,
2102+
undefined,
2103+
true
21002104
)
21012105
);
21022106
}

‎packages/project-editor/flow/components/actions/serial.tsx

+19-9
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,9 @@ registerActionComponents("Serial Port", [
208208
}
209209
],
210210
execute: (context: IDashboardComponentContext) => {
211-
const serialConnection = context.evalProperty("connection");
212-
if (!serialConnection) {
211+
const serialConnection =
212+
context.evalProperty<SerialConnection>("connection");
213+
if (!serialConnection || serialConnection.destroyed) {
213214
context.throwError(`invalid connection`);
214215
return;
215216
}
@@ -219,16 +220,21 @@ registerActionComponents("Serial Port", [
219220
(async (serialConnectionId: number) => {
220221
let serialConnection =
221222
serialConnections.get(serialConnectionId);
222-
if (serialConnection) {
223+
if (serialConnection && !serialConnection.destroyed) {
223224
try {
224225
await serialConnection.connect();
225226

226-
context.setPropertyField(
227-
"connection",
228-
"id",
229-
serialConnection.id
230-
);
231-
context.propagateValueThroughSeqout();
227+
if (serialConnection.destroyed) {
228+
serialConnection.disconnect();
229+
context.throwError(`invalid connection`);
230+
} else {
231+
context.setPropertyField(
232+
"connection",
233+
"id",
234+
serialConnection.id
235+
);
236+
context.propagateValueThroughSeqout();
237+
}
232238
} catch (err) {
233239
context.throwError(err.toString());
234240
}
@@ -271,6 +277,7 @@ registerActionComponents("Serial Port", [
271277

272278
if (serialConnection) {
273279
serialConnection.disconnect();
280+
274281
context.propagateValueThroughSeqout();
275282
} else {
276283
context.throwError("serial connection not found");
@@ -451,6 +458,7 @@ registerObjectVariableType("SerialConnection", {
451458
if (serialConnection) {
452459
serialConnection.disconnect();
453460
serialConnections.delete(serialConnection.id);
461+
serialConnection.destroyed = true;
454462
}
455463
},
456464
getValue: (variableValue: any): IObjectVariableValue | null => {
@@ -641,6 +649,8 @@ export class SerialConnection implements SerialConnectionCallbacks {
641649

642650
isConnected: boolean = false;
643651

652+
destroyed: boolean = false;
653+
644654
get port() {
645655
return this.constructorParams.port;
646656
}

‎packages/project-editor/flow/components/widgets/dashboard/index.tsx

+29-30
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
makeObservable,
55
computed,
66
runInAction,
7-
IReactionDisposer,
87
action
98
} from "mobx";
109
import classNames from "classnames";
@@ -309,30 +308,18 @@ const TextInputWidgetInput = observer(
309308
password: boolean;
310309
iterators: number[];
311310
}> {
312-
ref = React.createRef<HTMLInputElement>();
313-
cursor: number | null = null;
311+
inputElement = React.createRef<HTMLInputElement>();
312+
latestFlowValue: any;
313+
inputValue: any;
314314

315315
constructor(props: any) {
316316
super(props);
317317

318318
makeObservable(this, {
319-
cursor: observable
319+
inputValue: observable
320320
});
321321
}
322322

323-
setSelectionRange() {
324-
const input = this.ref.current;
325-
if (input) input.setSelectionRange(this.cursor, this.cursor);
326-
}
327-
328-
componentDidMount() {
329-
this.setSelectionRange();
330-
}
331-
332-
componentDidUpdate() {
333-
this.setSelectionRange();
334-
}
335-
336323
handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
337324
if (event.key === "Enter") {
338325
const flowState = this.props.flowContext.flowState as FlowState;
@@ -354,13 +341,13 @@ const TextInputWidgetInput = observer(
354341
onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
355342
const { flowContext, textInputWidget, iterators } = this.props;
356343

344+
runInAction(() => {
345+
this.inputValue = event.target.value;
346+
});
347+
357348
const flowState = flowContext.flowState as FlowState;
358349
if (flowState) {
359-
runInAction(() => {
360-
this.cursor = event.target.selectionStart;
361-
});
362-
363-
const value = event.target.value;
350+
const value = this.inputValue;
364351

365352
if (this.props.textInputWidget.data) {
366353
assignProperty(
@@ -402,12 +389,26 @@ const TextInputWidgetInput = observer(
402389
render() {
403390
const { value, readOnly, placeholder, password } = this.props;
404391

392+
if (value != this.latestFlowValue) {
393+
this.latestFlowValue = value;
394+
395+
setTimeout(
396+
action(() => {
397+
this.inputValue = undefined;
398+
})
399+
);
400+
}
401+
405402
return (
406403
<>
407404
<input
408-
ref={this.ref}
405+
ref={this.inputElement}
409406
type={password ? "password" : "text"}
410-
value={value}
407+
value={
408+
this.inputValue != undefined
409+
? this.inputValue
410+
: value
411+
}
411412
placeholder={placeholder}
412413
onChange={this.onChange}
413414
onBlur={this.onBlur}
@@ -626,6 +627,10 @@ const NumberInputDashboardWidgetElement = observer(
626627
disableDefaultTabHandling: boolean;
627628
iterators: number[];
628629
}> {
630+
inputElement = React.createRef<HTMLInputElement>();
631+
latestFlowValue: any;
632+
inputValue: any;
633+
629634
constructor(props: any) {
630635
super(props);
631636

@@ -634,8 +639,6 @@ const NumberInputDashboardWidgetElement = observer(
634639
});
635640
}
636641

637-
inputElement = React.createRef<HTMLInputElement>();
638-
639642
componentDidMount() {
640643
if (this.props.flowContext.flowState && this.inputElement.current) {
641644
this.inputElement.current.focus();
@@ -652,10 +655,6 @@ const NumberInputDashboardWidgetElement = observer(
652655
}
653656
}
654657

655-
dispose: IReactionDisposer;
656-
latestFlowValue: any;
657-
inputValue: any;
658-
659658
render() {
660659
const { flowContext, component } = this.props;
661660

‎packages/project-editor/flow/runtime/wasm-runtime.tsx

+7-4
Original file line numberDiff line numberDiff line change
@@ -1186,10 +1186,11 @@ export class WasmRuntime extends RemoteRuntime {
11861186
//key = e.key;
11871187
}
11881188

1189-
const isFunctionKey =
1190-
key != undefined && key.startsWith("F") && key.length > 1;
1189+
const passKey =
1190+
(key != undefined && key.startsWith("F") && key.length > 1) ||
1191+
key == "Escape";
11911192

1192-
if (!isFunctionKey) {
1193+
if (!passKey) {
11931194
if (e.target instanceof HTMLInputElement) {
11941195
if (
11951196
(key != "Tab" && key != "ShiftTab") ||
@@ -1198,6 +1199,7 @@ export class WasmRuntime extends RemoteRuntime {
11981199
"eez-studio-disable-default-tab-handling"
11991200
)
12001201
) {
1202+
// do not pass key
12011203
return;
12021204
}
12031205
}
@@ -1206,15 +1208,16 @@ export class WasmRuntime extends RemoteRuntime {
12061208
e.target instanceof HTMLSelectElement ||
12071209
e.target instanceof HTMLTextAreaElement
12081210
) {
1211+
// do not pass key
12091212
return;
12101213
}
12111214
}
12121215

1213-
/*
12141216
if (key == undefined) {
12151217
return;
12161218
}
12171219

1220+
/*
12181221
e.preventDefault();
12191222
e.stopPropagation();
12201223
*/

‎packages/project-editor/store/output-sections.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ export class Message implements IMessage {
5252
public type: MessageType,
5353
public text: string,
5454
public object?: IEezObject,
55-
public messages?: Message[]
55+
public messages?: Message[],
56+
public useGeneratedId?: boolean
5657
) {
5758
makeObservable(this, {
5859
selected: observable,
@@ -61,6 +62,9 @@ export class Message implements IMessage {
6162
}
6263

6364
get id() {
65+
if (this.useGeneratedId) {
66+
return this._id;
67+
}
6468
return this.object ? getObjectPathAsString(this.object) : this._id;
6569
}
6670
}

0 commit comments

Comments
 (0)