@ -1,5 +1,6 @@
|
|||||||
import { useRef, useEffect, useMemo } from 'react'
|
import { useRef, useEffect, useMemo } from 'react'
|
||||||
import { Allotment } from 'allotment'
|
import { Allotment } from 'allotment'
|
||||||
|
import { DebugPanel } from './components/DebugPanel'
|
||||||
import { asyncLexer } from './lang/tokeniser'
|
import { asyncLexer } from './lang/tokeniser'
|
||||||
import { abstractSyntaxTree } from './lang/abstractSyntaxTree'
|
import { abstractSyntaxTree } from './lang/abstractSyntaxTree'
|
||||||
import { _executor, ExtrudeGroup, SketchGroup } from './lang/executor'
|
import { _executor, ExtrudeGroup, SketchGroup } from './lang/executor'
|
||||||
@ -50,6 +51,7 @@ export function App() {
|
|||||||
isStreamReady,
|
isStreamReady,
|
||||||
token,
|
token,
|
||||||
formatCode,
|
formatCode,
|
||||||
|
debugPanel,
|
||||||
} = useStore((s) => ({
|
} = useStore((s) => ({
|
||||||
editorView: s.editorView,
|
editorView: s.editorView,
|
||||||
setEditorView: s.setEditorView,
|
setEditorView: s.setEditorView,
|
||||||
@ -77,6 +79,7 @@ export function App() {
|
|||||||
setIsStreamReady: s.setIsStreamReady,
|
setIsStreamReady: s.setIsStreamReady,
|
||||||
token: s.token,
|
token: s.token,
|
||||||
formatCode: s.formatCode,
|
formatCode: s.formatCode,
|
||||||
|
debugPanel: s.debugPanel,
|
||||||
}))
|
}))
|
||||||
// const onChange = React.useCallback((value: string, viewUpdate: ViewUpdate) => {
|
// const onChange = React.useCallback((value: string, viewUpdate: ViewUpdate) => {
|
||||||
const onChange = (value: string, viewUpdate: ViewUpdate) => {
|
const onChange = (value: string, viewUpdate: ViewUpdate) => {
|
||||||
@ -291,6 +294,7 @@ export function App() {
|
|||||||
<Allotment vertical defaultSizes={[40, 400]} minSize={20}>
|
<Allotment vertical defaultSizes={[40, 400]} minSize={20}>
|
||||||
<Stream />
|
<Stream />
|
||||||
</Allotment>
|
</Allotment>
|
||||||
|
{debugPanel && <DebugPanel />}
|
||||||
</Allotment>
|
</Allotment>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
118
src/components/DebugPanel.tsx
Normal file
118
src/components/DebugPanel.tsx
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import { PanelHeader } from '../components/PanelHeader'
|
||||||
|
import { useStore } from '../useStore'
|
||||||
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
import { EngineCommand } from '../lang/std/engineConnection'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { ActionButton } from '../components/ActionButton'
|
||||||
|
import { faCheck } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
|
type SketchModeCmd = EngineCommand['cmd']['DefaultCameraEnableSketchMode']
|
||||||
|
|
||||||
|
export const DebugPanel = () => {
|
||||||
|
const { engineCommandManager } = useStore((s) => ({
|
||||||
|
engineCommandManager: s.engineCommandManager,
|
||||||
|
}))
|
||||||
|
const [sketchModeCmd, setSketchModeCmd] = useState<SketchModeCmd>({
|
||||||
|
origin: { x: 0, y: 0, z: 0 },
|
||||||
|
x_axis: { x: 1, y: 0, z: 0 },
|
||||||
|
y_axis: { x: 0, y: 1, z: 0 },
|
||||||
|
distance_to_plane: 100,
|
||||||
|
ortho: true,
|
||||||
|
})
|
||||||
|
if (!sketchModeCmd) return null
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<PanelHeader title="Debug" />
|
||||||
|
<Xyz onChange={setSketchModeCmd} pointKey="origin" data={sketchModeCmd} />
|
||||||
|
<Xyz onChange={setSketchModeCmd} pointKey="x_axis" data={sketchModeCmd} />
|
||||||
|
<Xyz onChange={setSketchModeCmd} pointKey="y_axis" data={sketchModeCmd} />
|
||||||
|
<div className="flex">
|
||||||
|
<div className="pr-4">distance_to_plane</div>
|
||||||
|
<input
|
||||||
|
className="w-16"
|
||||||
|
type="number"
|
||||||
|
value={sketchModeCmd.distance_to_plane}
|
||||||
|
onChange={({ target }) => {
|
||||||
|
setSketchModeCmd({
|
||||||
|
...sketchModeCmd,
|
||||||
|
distance_to_plane: Number(target.value),
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="pr-4">ortho</div>
|
||||||
|
<input
|
||||||
|
className="w-16"
|
||||||
|
type="checkbox"
|
||||||
|
checked={sketchModeCmd.ortho}
|
||||||
|
onChange={(a) => {
|
||||||
|
console.log(a, (a as any).checked)
|
||||||
|
setSketchModeCmd({
|
||||||
|
...sketchModeCmd,
|
||||||
|
ortho: a.target.checked,
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<ActionButton
|
||||||
|
onClick={() => {
|
||||||
|
engineCommandManager?.sendSceneCommand({
|
||||||
|
type: 'ModelingCmdReq',
|
||||||
|
cmd: {
|
||||||
|
DefaultCameraEnableSketchMode: sketchModeCmd,
|
||||||
|
},
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
file_id: uuidv4(),
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
className="hover:border-succeed-50"
|
||||||
|
icon={{
|
||||||
|
icon: faCheck,
|
||||||
|
bgClassName:
|
||||||
|
'bg-succeed-80 group-hover:bg-succeed-70 hover:bg-succeed-70',
|
||||||
|
iconClassName:
|
||||||
|
'text-succeed-20 group-hover:text-succeed-10 hover:text-succeed-10',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Send sketch mode command
|
||||||
|
</ActionButton>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const Xyz = ({
|
||||||
|
pointKey,
|
||||||
|
data,
|
||||||
|
onChange,
|
||||||
|
}: {
|
||||||
|
pointKey: 'origin' | 'y_axis' | 'x_axis'
|
||||||
|
data: SketchModeCmd
|
||||||
|
onChange: (a: SketchModeCmd) => void
|
||||||
|
}) => {
|
||||||
|
if (!data) return null
|
||||||
|
return (
|
||||||
|
<div className="flex">
|
||||||
|
<div className="pr-4">{pointKey}</div>
|
||||||
|
{Object.entries(data[pointKey]).map(([axis, val]) => {
|
||||||
|
return (
|
||||||
|
<div key={axis} className="flex">
|
||||||
|
<div className="w-4">{axis}</div>
|
||||||
|
<input
|
||||||
|
className="w-16"
|
||||||
|
type="number"
|
||||||
|
value={val}
|
||||||
|
onChange={({ target }) => {
|
||||||
|
onChange({
|
||||||
|
...data,
|
||||||
|
[pointKey]: {
|
||||||
|
...data[pointKey],
|
||||||
|
[axis]: Number(target.value),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -47,7 +47,7 @@ interface XYZ {
|
|||||||
y: number
|
y: number
|
||||||
z: number
|
z: number
|
||||||
}
|
}
|
||||||
interface EngineCommand {
|
export interface EngineCommand {
|
||||||
type: 'ModelingCmdReq'
|
type: 'ModelingCmdReq'
|
||||||
cmd: {
|
cmd: {
|
||||||
StartPath?: {}
|
StartPath?: {}
|
||||||
@ -74,6 +74,13 @@ interface EngineCommand {
|
|||||||
CameraDragMove?: MouseDrag
|
CameraDragMove?: MouseDrag
|
||||||
CameraDragStart?: MouseStuff
|
CameraDragStart?: MouseStuff
|
||||||
CameraDragEnd?: MouseStuff
|
CameraDragEnd?: MouseStuff
|
||||||
|
DefaultCameraEnableSketchMode?: {
|
||||||
|
origin: XYZ
|
||||||
|
x_axis: XYZ
|
||||||
|
y_axis: XYZ
|
||||||
|
distance_to_plane: number
|
||||||
|
ortho: boolean
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cmd_id: uuid
|
cmd_id: uuid
|
||||||
file_id: uuid
|
file_id: uuid
|
||||||
|
@ -12,16 +12,21 @@ export const Settings = () => {
|
|||||||
setDefaultDir: saveDefaultDir,
|
setDefaultDir: saveDefaultDir,
|
||||||
defaultProjectName: originalDefaultProjectName,
|
defaultProjectName: originalDefaultProjectName,
|
||||||
setDefaultProjectName: saveDefaultProjectName,
|
setDefaultProjectName: saveDefaultProjectName,
|
||||||
|
saveDebugPanel,
|
||||||
|
originalDebugPanel,
|
||||||
} = useStore((s) => ({
|
} = useStore((s) => ({
|
||||||
defaultDir: s.defaultDir,
|
defaultDir: s.defaultDir,
|
||||||
setDefaultDir: s.setDefaultDir,
|
setDefaultDir: s.setDefaultDir,
|
||||||
defaultProjectName: s.defaultProjectName,
|
defaultProjectName: s.defaultProjectName,
|
||||||
setDefaultProjectName: s.setDefaultProjectName,
|
setDefaultProjectName: s.setDefaultProjectName,
|
||||||
|
saveDebugPanel: s.setDebugPanel,
|
||||||
|
originalDebugPanel: s.debugPanel,
|
||||||
}))
|
}))
|
||||||
const [defaultDir, setDefaultDir] = useState(originalDefaultDir)
|
const [defaultDir, setDefaultDir] = useState(originalDefaultDir)
|
||||||
const [defaultProjectName, setDefaultProjectName] = useState(
|
const [defaultProjectName, setDefaultProjectName] = useState(
|
||||||
originalDefaultProjectName
|
originalDefaultProjectName
|
||||||
)
|
)
|
||||||
|
const [debugPanel, setDebugPanel] = useState(originalDebugPanel)
|
||||||
|
|
||||||
async function handleDirectorySelection() {
|
async function handleDirectorySelection() {
|
||||||
const newDirectory = await open({
|
const newDirectory = await open({
|
||||||
@ -38,6 +43,7 @@ export const Settings = () => {
|
|||||||
const handleSaveClick = () => {
|
const handleSaveClick = () => {
|
||||||
saveDefaultDir(defaultDir)
|
saveDefaultDir(defaultDir)
|
||||||
saveDefaultProjectName(defaultProjectName)
|
saveDefaultProjectName(defaultProjectName)
|
||||||
|
saveDebugPanel(debugPanel)
|
||||||
toast.success('Settings saved!')
|
toast.success('Settings saved!')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,6 +109,16 @@ export const Settings = () => {
|
|||||||
onChange={(e) => setDefaultProjectName(e.target.value)}
|
onChange={(e) => setDefaultProjectName(e.target.value)}
|
||||||
/>
|
/>
|
||||||
</SettingsSection>
|
</SettingsSection>
|
||||||
|
<SettingsSection
|
||||||
|
title="Debug Panel"
|
||||||
|
description="Show the debug panel in the editor"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={debugPanel}
|
||||||
|
onChange={(e) => setDebugPanel(e.target.checked)}
|
||||||
|
/>
|
||||||
|
</SettingsSection>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
className="hover:border-succeed-50"
|
className="hover:border-succeed-50"
|
||||||
onClick={handleSaveClick}
|
onClick={handleSaveClick}
|
||||||
|
@ -16,11 +16,6 @@ import { asyncLexer } from './lang/tokeniser'
|
|||||||
import { EditorSelection } from '@codemirror/state'
|
import { EditorSelection } from '@codemirror/state'
|
||||||
import { BaseDirectory } from '@tauri-apps/api/fs'
|
import { BaseDirectory } from '@tauri-apps/api/fs'
|
||||||
import { ArtifactMap, SourceRangeMap, EngineCommandManager } from './lang/std/engineConnection'
|
import { ArtifactMap, SourceRangeMap, EngineCommandManager } from './lang/std/engineConnection'
|
||||||
// import {
|
|
||||||
// ArtifactMap,
|
|
||||||
// SourceRangeMap,
|
|
||||||
// EngineCommandManager,
|
|
||||||
// } from './lang/std/engineConnection'
|
|
||||||
|
|
||||||
export type Selection = {
|
export type Selection = {
|
||||||
type: 'default' | 'line-end' | 'line-mid'
|
type: 'default' | 'line-end' | 'line-mid'
|
||||||
@ -166,6 +161,8 @@ export interface StoreState {
|
|||||||
setHomeMenuItems: (items: { name: string; path: string }[]) => void
|
setHomeMenuItems: (items: { name: string; path: string }[]) => void
|
||||||
token: string
|
token: string
|
||||||
setToken: (token: string) => void
|
setToken: (token: string) => void
|
||||||
|
debugPanel: boolean
|
||||||
|
setDebugPanel: (debugPanel: boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
let pendingAstUpdates: number[] = []
|
let pendingAstUpdates: number[] = []
|
||||||
@ -323,6 +320,8 @@ export const useStore = create<StoreState>()(
|
|||||||
setHomeMenuItems: (homeMenuItems) => set({ homeMenuItems }),
|
setHomeMenuItems: (homeMenuItems) => set({ homeMenuItems }),
|
||||||
token: '',
|
token: '',
|
||||||
setToken: (token) => set({ token }),
|
setToken: (token) => set({ token }),
|
||||||
|
debugPanel: false,
|
||||||
|
setDebugPanel: (debugPanel) => set({ debugPanel }),
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
name: 'store',
|
name: 'store',
|
||||||
@ -333,6 +332,7 @@ export const useStore = create<StoreState>()(
|
|||||||
'defaultDir',
|
'defaultDir',
|
||||||
'defaultProjectName',
|
'defaultProjectName',
|
||||||
'token',
|
'token',
|
||||||
|
'debugPanel'
|
||||||
].includes(key))
|
].includes(key))
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -5,5 +5,7 @@
|
|||||||
"moduleResolution": "Node",
|
"moduleResolution": "Node",
|
||||||
"allowSyntheticDefaultImports": true
|
"allowSyntheticDefaultImports": true
|
||||||
},
|
},
|
||||||
"include": ["vite.config.ts"]
|
"include": [
|
||||||
|
"vite.config.ts"
|
||||||
|
]
|
||||||
}
|
}
|
Reference in New Issue
Block a user