diff --git a/src/Sketch.js b/src/Sketch.js index d5670a9..89b0d70 100644 --- a/src/Sketch.js +++ b/src/Sketch.js @@ -153,6 +153,7 @@ class Sketch { activate() { + console.log('activatee') window.addEventListener('keydown', this.onKeyPress) this.canvas.addEventListener('pointerdown', this.onPick) this.canvas.addEventListener('pointermove', this.onHover) diff --git a/src/react/app.css b/src/react/app.css index 0569650..9b68c36 100644 --- a/src/react/app.css +++ b/src/react/app.css @@ -10,8 +10,8 @@ body { height: 100%; font-family: sans-serif; overflow: hidden; - --topNavH: 48px; - --sideNavW: 240px; + --topNavH: 3rem; + --sideNavW: 15rem; } #c { @@ -38,8 +38,10 @@ body { .dialog { position: absolute; - top: var(--topNavH); - left: var(--sideNavW); + height: var(--topNavH); + left:0; + right:0; + top:0; } diff --git a/src/react/app.jsx b/src/react/app.jsx index 95afbdd..96dd500 100644 --- a/src/react/app.jsx +++ b/src/react/app.jsx @@ -2,15 +2,15 @@ import ReactDOM from 'react-dom' import React, { useState } from 'react' -import { createStore, applyMiddleware} from 'redux' +import { createStore, applyMiddleware } from 'redux' import { Provider } from 'react-redux' import { reducer } from './reducer' import logger from 'redux-logger' import { Tree } from './tree' import { NavBar } from './navBar' -import { ToolTip} from './toolTip' -import { Dialog } from './dialog' +import { ToolTip } from './toolTip' + import './app.css' @@ -31,14 +31,15 @@ const preloadedState = { const store = createStore(reducer, {}, applyMiddleware(logger)) // const store = createStore(reducer, sc.loadState(), applyMiddleware(logger)) + const App = ({ store }) => { - const [dialog, setDialog] = useState() + return - + + - - + }; diff --git a/src/react/dialog.jsx b/src/react/dialog.jsx index 4967b90..7d33999 100644 --- a/src/react/dialog.jsx +++ b/src/react/dialog.jsx @@ -3,64 +3,71 @@ import React, { useEffect, useReducer, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux' - import { MdDone, MdClose } from 'react-icons/md' -import { GiVerticalFlip } from 'react-icons/gi' import * as Icon from "./icons"; -export const Dialog = ({ dialog, setDialog }) => { - if (!dialog) return null + +export const Dialog = () => { + + const dialog = useSelector(state => state.ui.dialog) const dispatch = useDispatch() - const treeEntriesById = useSelector(state => state.treeEntries.byId) - const activeSketchId = useSelector(state => state.treeEntries.activeSketchId) const ref = useRef() + useEffect(() => { + if (!ref.current) return ref.current.focus() - }, []) + }, [dialog]) const extrude = () => { - let sketch - if (sc.activeSketch) { - sketch = sc.activeSketch - } else if (sc.selected.length === 1 && sc.selected[0].userData.type == 'sketch') { - sketch = treeEntriesById[sc.selected[0].name] - } else { - console.log('invalid selection') - return - } - - setDialog(null) - sc.extrude(sketch, ref.current.value) - + sc.extrude(dialog.target, ref.current.value) sc.render() - forceUpdate() - } + dispatch({ type: "clear-dialog" }) + forceUpdate() + + } const [_, forceUpdate] = useReducer(x => x + 1, 0); - return
- {/* return
*/} - - ref.current.value *= -1} - /> - - setDialog(null)} - /> -
+ switch (dialog.action) { + case 'extrude': + return <> + + ref.current.value *= -1} + /> + + dispatch({ type: "clear-dialog" })} + /> + + case 'sketch': + return <> + { + // dispatch({ type: 'update-descendents', sketch}) + sc.activeSketch.deactivate() + sc.render() + forceUpdate() + }} + /> + dispatch({ type: "clear-dialog" })} + /> + + default: + return null + } } -export const useNumField = (initValue = 0) => { - const [value, setValue] = useState(initValue); - const onChange = e => setValue(e.target.value); - return { value, onChange }; -} \ No newline at end of file + + + diff --git a/src/react/navBar.jsx b/src/react/navBar.jsx index 5e0a29d..1625d83 100644 --- a/src/react/navBar.jsx +++ b/src/react/navBar.jsx @@ -7,12 +7,12 @@ import { useDispatch, useSelector } from 'react-redux' import { FaEdit } from 'react-icons/fa' import { MdDone, MdSave, MdFolder } from 'react-icons/md' import * as Icon from "./icons"; +import { Dialog } from './dialog' - -export const NavBar = ({ setDialog }) => { +export const NavBar = () => { const dispatch = useDispatch() const activeSketchId = useSelector(state => state.treeEntries.activeSketchId) - + const treeEntriesById = useSelector(state => state.treeEntries.byId) const boolOp = (code) => { if (sc.selected.length != 2 || !sc.selected.every(e => e.userData.type == 'mesh')) return @@ -21,11 +21,11 @@ export const NavBar = ({ setDialog }) => { sc.render() forceUpdate() } - const extrude = () => { setDialog(true) } const addSketch = () => { sc.addSketch() - console.log(!!sc.activeSketch, 'state') + dispatch({ type: 'set-dialog', action: 'sketch' }) + forceUpdate() } @@ -45,14 +45,18 @@ export const NavBar = ({ setDialog }) => { // }, [treeEntriesById]) - const btnz = [ - [MdDone, () => { + const sketchModeButtons = [ + // [MdDone, () => { + // // dispatch({ type: 'update-descendents', sketch}) + + // sc.activeSketch.deactivate() + // sc.render() + // forceUpdate() + // }, 'Finish'], + [Icon.Extrude, () => { sc.activeSketch.deactivate() - // dispatch({ type: 'update-descendents', sketch}) - sc.render() - forceUpdate() - }, 'Finish'], - [Icon.Extrude, extrude, 'Extrude [e]'], + dispatch({ type: 'set-dialog', action: 'extrude', target: sc.activeSketch }) + }, 'Extrude [e]'], [Icon.Dimension, () => sc.activeSketch.command('d'), 'Dimension [d]'], [Icon.Line, () => sc.activeSketch.command('l'), 'Line [l]'], [Icon.Arc, () => sc.activeSketch.command('a'), 'Arc [a]'], @@ -63,9 +67,12 @@ export const NavBar = ({ setDialog }) => { ] - const btnz2 = [ + const partModeButtons = [ [FaEdit, addSketch, 'Sketch [s]'], - [Icon.Extrude, extrude, 'Extrude [e]'], + [Icon.Extrude, () => { + dispatch({ type: 'set-dialog', action: 'extrude', target: treeEntriesById[sc.selected[0].name] }) + }, 'Extrude [e]'], + [Icon.Union, () => boolOp('u'), 'Union'], [Icon.Subtract, () => boolOp('s'), 'Subtract'], [Icon.Intersect, () => boolOp('i'), 'Intersect'], @@ -77,19 +84,26 @@ export const NavBar = ({ setDialog }) => { const [_, forceUpdate] = useReducer(x => x + 1, 0); return
+ +
+ +
{ activeSketchId ? - btnz.map(([Icon, fcn, txt, shortcut], idx) => ( + sketchModeButtons.map(([Icon, fcn, txt, shortcut], idx) => ( )) : - btnz2.map(([Icon, fcn, txt, shortcut], idx) => ( + partModeButtons.map(([Icon, fcn, txt, shortcut], idx) => ( )) } +
+
+
-} +} \ No newline at end of file diff --git a/src/react/reducer.js b/src/react/reducer.js index 36fd3af..cc95fb8 100644 --- a/src/react/reducer.js +++ b/src/react/reducer.js @@ -82,9 +82,25 @@ export function treeEntries(state = defaultState, action) { } } +export function ui(state = {dialog:{}}, action) { + switch (action.type) { + + case 'set-dialog': + return update(state, { + dialog: { $set: { target: action.target, action: action.action } }, + }) + case 'clear-dialog': + return update(state, { + dialog: { $set: {} }, + }) + default: + return state + } +} export const reducer = combineReducers({ + ui, treeEntries }) \ No newline at end of file diff --git a/src/react/tree.jsx b/src/react/tree.jsx index d186cda..cea99fa 100644 --- a/src/react/tree.jsx +++ b/src/react/tree.jsx @@ -13,7 +13,7 @@ export const Tree = () => { return
{treeEntries.allIds.map((entId, idx) => ( - + ))}
@@ -28,6 +28,8 @@ const treeIcons = { const TreeEntry = ({ entId }) => { + + const state = useSelector(state => state.treeEntries) const treeEntries = useSelector(state => state.treeEntries.byId) const dispatch = useDispatch() @@ -54,6 +56,7 @@ const TreeEntry = ({ entId }) => { sketch.activate() sc.clearSelection() sc.activeSketch = sketch; + dispatch({ type: 'set-dialog', action: 'sketch' }) sc.render() }