diff --git a/src/components/MenuView.scss b/src/components/MenuView.scss
index 1533bcd..02a9327 100644
--- a/src/components/MenuView.scss
+++ b/src/components/MenuView.scss
@@ -1,6 +1,6 @@
.menu {
user-select: none;
- font-size: 13px;
+ font-size: 16px;
& details {
&>summary {
@@ -12,6 +12,7 @@
display: flex;
padding: 8px 8px;
+ gap: 8px;
cursor: pointer;
border-radius: 4px;
white-space: nowrap;
@@ -28,15 +29,22 @@
background: rgba(255, 255, 255, 0.15);
color: #fff;
}
-
+
&>.title {
flex: 1;
+ overflow-x: hidden;
+ text-overflow: ellipsis;
+ }
+
+ &>.actions {
+ display: flex;
+ gap: 8px;
}
& svg {
vertical-align: middle;
margin: 2px;
-
+
box-sizing: border-box;
}
}
diff --git a/src/components/ObjectEditorView.tsx b/src/components/ObjectEditorView.tsx
index 9905033..dcd50d4 100644
--- a/src/components/ObjectEditorView.tsx
+++ b/src/components/ObjectEditorView.tsx
@@ -4,7 +4,6 @@ import { useMemo, useRef, type RefObject } from "react";
import type { Group } from "three";
import { TransformControls, useHelper } from "@react-three/drei";
import { BoxHelper } from "three";
-import type { ThreeEvent } from "@react-three/fiber";
import { state } from "../state";
import { nextObjectEditMode } from "../state/worldEditorState";
import { ObjectViewInternal, type ObjectViewInternalHandle } from "./ObjectViewInternal";
diff --git a/src/state/menuState.tsx b/src/state/menuState.tsx
index 7606f85..44bcda7 100644
--- a/src/state/menuState.tsx
+++ b/src/state/menuState.tsx
@@ -1,7 +1,7 @@
import { makeAutoObservable } from "mobx";
import { state } from "./rootState";
import type { ReactNode } from "react";
-import { IconRun } from '@tabler/icons-react';
+import { IconRun, IconTrash, IconCubePlus, IconPlus } from '@tabler/icons-react';
export type MenuNodeAction = {
id: string;
@@ -26,27 +26,43 @@ export class MenuState {
}
private get editorObjectTypesMenu(): MenuNode[] {
- const scene = state.worldEditor.scene;
+ const editor = state.worldEditor;
+ const scene = editor.scene;
return Object.values(state.world.data.objectTypes)
.map((ot) => ({
id: `ot-${ot.id}`,
title: ot.name,
- onClick: () => { state.worldEditor.setSelectedObjectType({ id: ot.id, editMode: 'scripts' }) },
- selected: () => state.worldEditor.selection?.type === 'objectType' && state.worldEditor.selection?.id === ot.id,
+ actions: [
+ {
+ id: 'create-instance',
+ content: ,
+ tooltip: 'Create new object instance',
+ onClick: () => { editor.addObjectInstanceAtRandomPosition(ot.id); },
+ },
+ ],
+ onClick: () => { editor.setSelectedObjectType({ id: ot.id, editMode: 'scripts' }) },
+ selected: () => editor.selection?.type === 'objectType' && editor.selection?.id === ot.id,
children: Object.values(scene.objects)
.filter((o) => o.typeId === ot.id)
.map((o) => {
const isPlayer = scene.playerObjectId === o.id;
const actions: MenuNodeAction[] = [];
- if (!isPlayer)
+ if (!isPlayer) {
+ actions.push({
+ id: 'delete',
+ content: ,
+ tooltip: 'Delete the object',
+ onClick: () => { editor.deleteObject(o.id); },
+ });
actions.push({
id: 'control-by-player',
content: ,
tooltip: 'Mark as player',
- onClick: () => { state.markObjectAsPlayer(o); },
+ onClick: () => { scene.playerObjectId = o.id; },
});
+ }
return {
id: `o-${o.id}`,
diff --git a/src/state/worldEditorState.ts b/src/state/worldEditorState.ts
index a67f621..e4d0ba0 100644
--- a/src/state/worldEditorState.ts
+++ b/src/state/worldEditorState.ts
@@ -116,14 +116,14 @@ export class WorldEditorState {
});
}
- public addObjectCloneAtRandomPosition(typeId: string): ObjectInstance {
- return this.addObjectClone(
+ public addObjectInstanceAtRandomPosition(typeId: string): ObjectInstance {
+ return this.addObjectInstance(
typeId,
{ x: Math.random() * 3, y: Math.random() * 3, z: Math.random() * 1 },
);
}
- public addObjectClone(
+ public addObjectInstance(
typeId: string,
pos: { x: number; y: number; z: number; },
): ObjectInstance {
@@ -133,7 +133,15 @@ export class WorldEditorState {
this.scene.objects[obj.id] = obj;
+ this.setSelectedObject({ id: obj.id, editMode: 'translate' });
+
return obj;
}
+
+ public deleteObject(objectId: string) {
+ if (this.selection?.type ==='object' && this.selection.id === objectId)
+ this.resetSelection();
+ delete (this.scene.objects[objectId]);
+ }
}