three.cad/src/react/navBar.jsx

137 lines
4.1 KiB
React
Raw Normal View History

2021-04-07 12:21:09 +08:00
2021-04-08 06:50:53 +08:00
import React, { useEffect, useReducer } from 'react';
2021-04-07 12:21:09 +08:00
import { useDispatch, useSelector } from 'react-redux'
2021-04-19 03:14:01 +08:00
import { FaEdit, FaFileDownload } from 'react-icons/fa'
import { MdSave, MdFolder, MdFileUpload, MdInsertDriveFile } from 'react-icons/md'
import { FaRegFolderOpen, FaFile } from 'react-icons/fa'
2021-04-17 13:58:54 +08:00
2021-04-07 12:21:09 +08:00
import * as Icon from "./icons";
2021-04-17 11:54:01 +08:00
import { Dialog } from './dialog'
2021-04-19 03:14:01 +08:00
import { STLExport, savePart, saveFile, openFile } from './fileExporter'
2021-04-17 21:32:14 +08:00
2021-04-07 12:21:09 +08:00
2021-04-17 11:54:01 +08:00
export const NavBar = () => {
2021-04-07 12:21:09 +08:00
const dispatch = useDispatch()
2021-04-11 15:57:39 +08:00
const activeSketchId = useSelector(state => state.treeEntries.activeSketchId)
2021-04-17 11:54:01 +08:00
const treeEntriesById = useSelector(state => state.treeEntries.byId)
2021-04-19 03:14:01 +08:00
const fileHandle = useSelector(state => state.ui.fileHandle)
2021-04-13 09:37:16 +08:00
const boolOp = (code) => {
if (sc.selected.length != 2 || !sc.selected.every(e => e.userData.type == 'mesh')) return
const [m1, m2] = sc.selected
2021-04-17 07:03:30 +08:00
sc.boolOp(m1, m2, code)
2021-04-13 09:37:16 +08:00
sc.render()
forceUpdate()
}
2021-04-15 06:46:30 +08:00
const addSketch = () => {
sc.addSketch()
2021-04-17 11:54:01 +08:00
dispatch({ type: 'set-dialog', action: 'sketch' })
2021-04-15 06:46:30 +08:00
forceUpdate()
2021-04-13 09:37:16 +08:00
}
2021-04-19 03:14:01 +08:00
2021-04-17 18:25:43 +08:00
useEffect(() => { // hacky way to handle mounting and unmounting mouse listeners for feature mode
if (!activeSketchId) {
sc.canvas.addEventListener('pointermove', sc.onHover)
sc.canvas.addEventListener('pointerdown', sc.onPick)
return () => {
sc.canvas.removeEventListener('pointermove', sc.onHover)
sc.canvas.removeEventListener('pointerdown', sc.onPick)
}
}
}, [activeSketchId])
2021-04-07 12:21:09 +08:00
2021-04-17 11:54:01 +08:00
const sketchModeButtons = [
[Icon.Extrude, () => {
2021-04-17 21:32:14 +08:00
dispatch({ type: 'finish-sketch' })
2021-04-17 11:54:01 +08:00
dispatch({ type: 'set-dialog', action: 'extrude', target: sc.activeSketch })
2021-04-17 21:32:14 +08:00
2021-04-17 11:54:01 +08:00
}, 'Extrude [e]'],
2021-04-15 06:46:30 +08:00
[Icon.Dimension, () => sc.activeSketch.command('d'), 'Dimension [d]'],
[Icon.Line, () => sc.activeSketch.command('l'), 'Line [l]'],
[Icon.Arc, () => sc.activeSketch.command('a'), 'Arc [a]'],
[Icon.Coincident, () => sc.activeSketch.command('c'), 'Coincident [c]'],
[Icon.Vertical, () => sc.activeSketch.command('v'), 'Vertical [v]'],
[Icon.Horizontal, () => sc.activeSketch.command('h'), 'Horizontal [h]'],
[Icon.Tangent, () => sc.activeSketch.command('t'), 'Tangent [t]'],
2021-04-19 03:14:01 +08:00
[Icon.Tangent, () => sc.activeSketch.command('t'), 'Tangent [t]'],
2021-04-14 04:39:33 +08:00
]
2021-04-17 11:54:01 +08:00
const partModeButtons = [
2021-04-17 07:03:30 +08:00
[FaEdit, addSketch, 'Sketch [s]'],
2021-04-17 11:54:01 +08:00
[Icon.Extrude, () => {
dispatch({ type: 'set-dialog', action: 'extrude', target: treeEntriesById[sc.selected[0].name] })
}, 'Extrude [e]'],
2021-04-14 04:39:33 +08:00
[Icon.Union, () => boolOp('u'), 'Union'],
[Icon.Subtract, () => boolOp('s'), 'Subtract'],
[Icon.Intersect, () => boolOp('i'), 'Intersect'],
2021-04-19 03:14:01 +08:00
[MdInsertDriveFile, savePart, 'New [ctrl+n]'],
[MdSave, () => {
saveFile(fileHandle, sc.saveScene(), dispatch)
}, 'Save [ctrl+s]'],
[MdFolder, () => openFile(dispatch), 'Open'],
2021-04-17 21:32:14 +08:00
[Icon.Stl, STLExport, 'Export STL'],
2021-04-07 12:21:09 +08:00
]
const [_, forceUpdate] = useReducer(x => x + 1, 0);
2021-04-11 07:16:08 +08:00
return <div className='topNav flex justify-center items-center bg-gray-700'>
2021-04-17 11:54:01 +08:00
2021-04-17 13:58:54 +08:00
<div className='w-auto h-full flex-1 flex items-center justify-end'>
2021-04-17 11:54:01 +08:00
<Dialog />
</div>
2021-04-17 13:58:54 +08:00
<div className='w-auto h-full flex-none'>
{
activeSketchId ?
sketchModeButtons.map(([Icon, fcn, txt, shortcut], idx) => (
<Icon className="btn w-auto h-full p-3.5" tooltip={txt}
onClick={fcn} key={idx}
/>
))
:
partModeButtons.map(([Icon, fcn, txt, shortcut], idx) => (
<Icon className="btn w-auto h-full p-3.5" tooltip={txt}
onClick={fcn} key={idx}
/>
))
}
</div>
<div className='w-auto h-full flex-1 items-center'>
2021-04-17 11:54:01 +08:00
</div>
2021-04-07 12:21:09 +08:00
</div>
2021-04-19 03:14:01 +08:00
}
// app.saveFile = async () => {
// try {
// if (!app.file.handle) {
// return await app.saveFileAs();
// }
// gaEvent('FileAction', 'Save');
// await writeFile(app.file.handle, app.getText());
// app.setModified(false);
// } catch (ex) {
// gaEvent('Error', 'FileSave', ex.name);
// const msg = 'Unable to save file';
// console.error(msg, ex);
// alert(msg);
// }
// app.setFocus();
// };