Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
mvladic committed Nov 2, 2024
1 parent 65f0f27 commit 6152d6f
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 29 deletions.
4 changes: 4 additions & 0 deletions packages/eez-studio-ui/_stylesheets/app.less
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
user-select: auto;
}

.modal > .modal-dialog > .modal-content {
box-shadow: @modalDialogDropdownShadow;
}

body {
overflow: hidden;
font-size: 0.8rem;
Expand Down
2 changes: 2 additions & 0 deletions packages/eez-studio-ui/_stylesheets/vars-dark.less
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,5 @@
@tipBoxColor: @textColor;
@tipBoxBackgroundColor: #003100;
@tipBoxBorderColor: #009400;

@modalDialogDropdownShadow: 4px 4px 24px rgba(0, 0, 0, 0.8);
2 changes: 2 additions & 0 deletions packages/eez-studio-ui/_stylesheets/vars.less
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,5 @@
@tipBoxColor: @textColor;
@tipBoxBackgroundColor: #e6f6e6;
@tipBoxBorderColor: #c3e6c3;

@modalDialogDropdownShadow: 4px 4px 16px rgba(64, 64, 64, 0.5);
54 changes: 46 additions & 8 deletions packages/eez-studio-ui/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export function showDialog(dialog: JSX.Element, opts?: IDialogOptions) {
const root = createRoot(element);
root.render(dialog);

let jsPanelDialog;

if (opts && opts.jsPanel) {
element.style.position = "absolute";
element.style.width = "100%";
Expand Down Expand Up @@ -129,15 +131,28 @@ export function showDialog(dialog: JSX.Element, opts?: IDialogOptions) {
}
}

const dialog = (opts.jsPanel.modeless ? jsPanel : jsPanel.modal).create(
config
);

return [dialog, element, root];
jsPanelDialog = (
opts.jsPanel.modeless ? jsPanel : jsPanel.modal
).create(config);
} else {
document.body.appendChild(element);
return [undefined, element, root];
}

// Unmount dialog if the element is removed from the DOM
const intervalID = setInterval(() => {
let parentElement = element.parentElement;
while (parentElement) {
if (parentElement instanceof HTMLBodyElement) {
return;
}
parentElement = parentElement.parentElement;
}

clearInterval(intervalID);
root.unmount();
}, 100);

return [jsPanelDialog, element, root];
}

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -302,6 +317,7 @@ export const BootstrapDialog = observer(
additionalFooterControl?: React.ReactNode;
backdrop?: "static" | boolean;
className?: string;
modalContentStyle?: React.CSSProperties;
}> {
div: HTMLDivElement | null = null;
form: HTMLFormElement | null = null;
Expand All @@ -325,21 +341,36 @@ export const BootstrapDialog = observer(
}
};

static openBootstrapDialogs: React.Component[] = [];

get numOpenBootstrapDialogs() {
return BootstrapDialog.openBootstrapDialogs.filter(
genericDialog => genericDialog !== this
).length;
}

componentDidMount() {
const div = this.div;
if (div) {
$(div).on("shown.bs.modal", () => {
BootstrapDialog.openBootstrapDialogs.push(this);

setTimeout(this.setFocus);
});

$(div).on("hidden.bs.modal", () => {
BootstrapDialog.openBootstrapDialogs.pop();

const parent = div.parentElement as HTMLElement;
parent.remove();
this.props.onCancel();
});

this.modal = new bootstrap.Modal(div, {
backdrop: this.props.backdrop ?? true
backdrop:
this.numOpenBootstrapDialogs == 0
? this.props.backdrop ?? true
: false
});
this.modal.show();
}
Expand Down Expand Up @@ -464,7 +495,14 @@ export const BootstrapDialog = observer(
}}
onKeyPress={this.onKeyPress}
>
<div className="modal-content">
<div
className="modal-content"
style={{
transform: `translate(${
this.numOpenBootstrapDialogs * 70
}px, ${this.numOpenBootstrapDialogs * 70}px)`
}}
>
{props.title && (
<div className="modal-header">
<h5
Expand Down
11 changes: 11 additions & 0 deletions packages/eez-studio-ui/generic-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ interface GenericDialogProps {
onOk?: (result: GenericDialogResult) => Promise<boolean> | boolean | void;
onCancel?: () => void;
onValueChange?: (name: string, value: string) => void;
setOnChangeCallback?: (
onChange: (fieldProperties: any, value: any) => void
) => void;
}

export const GenericDialog = observer(
Expand Down Expand Up @@ -234,6 +237,10 @@ export const GenericDialog = observer(

this.fieldValues = fieldValues;
this.errorMessages = undefined;

if (this.props.setOnChangeCallback) {
this.props.setOnChangeCallback(this.onChange.bind(this));
}
}

get values() {
Expand Down Expand Up @@ -736,6 +743,9 @@ export function showGenericDialog(conf: {
onOk?: (result: GenericDialogResult) => Promise<boolean>;
opts?: IDialogOptions;
dialogContext?: any;
setOnChangeCallback?: (
onChange: (fieldProperties: any, value: any) => void
) => void;
}) {
return new Promise<GenericDialogResult>((resolve, reject) => {
const [modalDialog] = showDialog(
Expand Down Expand Up @@ -774,6 +784,7 @@ export function showGenericDialog(conf: {
}
reject();
}}
setOnChangeCallback={conf.setOnChangeCallback}
/>,
conf.opts
);
Expand Down
36 changes: 29 additions & 7 deletions packages/project-editor/features/action/action.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -214,16 +214,19 @@ export class Action extends Flow {
type: PropertyType.Enum,
enumItems: [
{
id: "native"
id: "flow"
},
{
id: "flow"
id: "native"
}
],
enumDisallowUndefined: true,
propertyGridGroup: specificGroup,
disabled: (action: Action) => {
return isNotV1Project(action) && !hasFlowSupport(action);
return (
(isNotV1Project(action) && !hasFlowSupport(action)) ||
isDashboardProject(action)
);
}
},
{
Expand Down Expand Up @@ -288,6 +291,8 @@ export class Action extends Flow {
}
},
newItem: async (parent: IEezObject) => {
const projectStore = getProjectStore(parent);

const result = await showGenericDialog({
dialogDefinition: {
title: "New Action",
Expand All @@ -300,21 +305,38 @@ export class Action extends Flow {
validators.invalidCharacters("."),
validators.unique({}, parent)
]
},
{
name: "implementationType",
type: "enum",
enumItems: [
{
id: "flow",
label: "Flow"
},
{
id: "native",
label: "Native"
}
],
visible: () =>
!projectStore.projectTypeTraits.isDashboard &&
projectStore.projectTypeTraits.hasFlowSupport
}
]
},
values: {}
values: {
implementationType: "flow"
}
});

const projectStore = getProjectStore(parent);

const actionProperties: Partial<Action> = Object.assign(
{
name: result.values.name
},
projectStore.projectTypeTraits.hasFlowSupport
? ({
implementationType: "flow",
implementationType: result.values.implementationType,
components: [],
connectionLine: []
} as Partial<Action>)
Expand Down
79 changes: 65 additions & 14 deletions packages/project-editor/flow/component.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { MenuItem } from "@electron/remote";
import React from "react";
import { observable, computed, makeObservable } from "mobx";
import { observable, computed, makeObservable, runInAction } from "mobx";
import classNames from "classnames";
import { each } from "lodash";

import { validators } from "eez-studio-shared/validation";
import { BoundingRectBuilder, Point, Rect } from "eez-studio-shared/geometry";

import { showGenericDialog } from "eez-studio-ui/generic-dialog";
import {
IFieldProperties,
showGenericDialog
} from "eez-studio-ui/generic-dialog";

import * as notification from "eez-studio-ui/notification";

Expand Down Expand Up @@ -110,6 +113,7 @@ import { getComponentName } from "project-editor/flow/components/components-regi
import { ProjectEditor } from "project-editor/project-editor-interface";
import { FLOW_ITERATOR_INDEX_VARIABLE } from "project-editor/features/variable/defs";
import type {
EnumItems,
IActionComponentDefinition,
IComponentProperty,
IDashboardComponentContext
Expand Down Expand Up @@ -164,6 +168,7 @@ import {
} from "project-editor/store/serialization";
import { StylePropertyUI } from "project-editor/features/style/StylePropertyUI";
import { findVariable } from "project-editor/project/project";
import type { Action } from "project-editor/features/action/action";

////////////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -2598,6 +2603,59 @@ export class EventHandler extends EezObject {
return;
}

function getActions() {
return project.actions.map(action => ({
id: action.name,
label: action.name
}));
}
const actionEnumItems = observable.box<EnumItems>([]);
actionEnumItems.set(getActions());

let onChangeCallback: (fieldProperties: any, value: any) => void;

const actionProperty: IFieldProperties = {
name: "action",
type: "enum",
enumItems: actionEnumItems,
inputGroupButton: (
<button
className="btn btn-primary"
onClick={async event => {
event.preventDefault();

try {
const action = (await ProjectEditor.ActionClass
.classInfo.newItem!(
project.actions
)) as Action;

if (action) {
project._store.addObject(
project.actions,
action
);

runInAction(() => {
onChangeCallback(
actionProperty,
action.name
);

actionEnumItems.set(getActions());
});
}
} catch (err) {}
}}
>
New Action
</button>
),
visible: (values: any) => {
return values.handlerType == "action";
}
};

const result = await showGenericDialog({
dialogDefinition: {
title: "New Event Handler",
Expand All @@ -2619,17 +2677,7 @@ export class EventHandler extends EezObject {
visible: () =>
project.projectTypeTraits.hasFlowSupport
},
{
name: "action",
type: "enum",
enumItems: project.actions.map(action => ({
id: action.name,
label: action.name
})),
visible: (values: any) => {
return values.handlerType == "action";
}
},
actionProperty,
{
name: "userData",
type: "number",
Expand All @@ -2645,7 +2693,10 @@ export class EventHandler extends EezObject {
: "action",
userData: 0
},
dialogContext: project
dialogContext: project,
setOnChangeCallback: callback => {
onChangeCallback = callback;
}
});

const properties: Partial<EventHandler> = {
Expand Down

0 comments on commit 6152d6f

Please sign in to comment.