IDE redesign, initial implementation #362
@@ -1,6 +1,6 @@
|
|||||||
import { Menu } from '@headlessui/react'
|
import { Menu } from '@headlessui/react'
|
||||||
|
|
||||||
import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
|
import { useIdeContext, ideTypeNameMap } from 'src/helpers/hooks/useIdeContext'
|
||||||
import Svg from 'src/components/Svg/Svg'
|
import Svg from 'src/components/Svg/Svg'
|
||||||
import { useRender } from 'src/components/IdeWrapper/useRender'
|
import { useRender } from 'src/components/IdeWrapper/useRender'
|
||||||
import { makeStlDownloadHandler, PullTitleFromFirstLine } from './helpers'
|
import { makeStlDownloadHandler, PullTitleFromFirstLine } from './helpers'
|
||||||
@@ -14,30 +14,42 @@ const EditorMenu = () => {
|
|||||||
fileName: PullTitleFromFirstLine(state.code || ''),
|
fileName: PullTitleFromFirstLine(state.code || ''),
|
||||||
thunkDispatch,
|
thunkDispatch,
|
||||||
})
|
})
|
||||||
|
const cadName = ideTypeNameMap[state.ideType] || ''
|
||||||
|
const isOpenScad = state.ideType === 'openScad'
|
||||||
|
const isCadQuery = state.ideType === 'cadQuery'
|
||||||
return (
|
return (
|
||||||
<div className="bg-gray-500 flex items-center h-9 w-full cursor-grab">
|
<div className="flex justify-between bg-gray-500 text-gray-100">
|
||||||
<div className=" text-gray-500 bg-gray-300 cursor-grab px-2 h-full flex items-center">
|
<div className="flex items-center h-9 w-full cursor-grab">
|
||||||
<Svg name="drag-grid" className="w-4 p-px" />
|
<div className=" text-gray-500 bg-gray-300 cursor-grab px-2 h-full flex items-center">
|
||||||
|
<Svg name="drag-grid" className="w-4 p-px" />
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-6 px-5">
|
||||||
|
<FileDropdown
|
||||||
|
handleRender={handleRender}
|
||||||
|
handleStlDownload={handleStlDownload}
|
||||||
|
/>
|
||||||
|
<button className="cursor-not-allowed" disabled>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
<button className="cursor-not-allowed" disabled>
|
||||||
|
View
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className="text-gray-300 h-full cursor-not-allowed"
|
||||||
|
aria-label="editor settings"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
<Svg name="gear" className="w-6 p-px" />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<div className="flex items-center cursor-default">
|
||||||
|
|
|||||||
className="text-gray-300 px-3 h-full cursor-not-allowed"
|
<div
|
||||||
aria-label="editor settings"
|
className={`${isOpenScad && 'bg-yellow-200'} ${
|
||||||
disabled
|
isCadQuery && 'bg-blue-800'
|
||||||
>
|
} w-5 h-5 rounded-full`}
|
||||||
<Svg name="gear" className="w-7 p-px" />
|
|
||||||
</button>
|
|
||||||
<div className="w-px h-full bg-gray-300" />
|
|
||||||
<div className="flex gap-6 px-6">
|
|
||||||
<FileDropdown
|
|
||||||
handleRender={handleRender}
|
|
||||||
handleStlDownload={handleStlDownload}
|
|
||||||
/>
|
/>
|
||||||
<button className="text-gray-100 cursor-not-allowed" disabled>
|
<div className="px-2">{cadName}</div>
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
<button className="text-gray-100 cursor-not-allowed" disabled>
|
|
||||||
View
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
|
import { useIdeContext, ideTypeNameMap } from 'src/helpers/hooks/useIdeContext'
|
||||||
import OutBound from 'src/components/OutBound/OutBound'
|
import OutBound from 'src/components/OutBound/OutBound'
|
||||||
import { prepareEncodedUrl, makeExternalUrl } from './helpers'
|
import { prepareEncodedUrl, makeExternalUrl } from './helpers'
|
||||||
import { copyTextToClipboard } from 'src/helpers/clipboard'
|
import { copyTextToClipboard } from 'src/helpers/clipboard'
|
||||||
import { useRender } from 'src/components/IdeWrapper/useRender'
|
import { useRender } from 'src/components/IdeWrapper/useRender'
|
||||||
import { toast } from '@redwoodjs/web/toast'
|
import { toast } from '@redwoodjs/web/toast'
|
||||||
|
|
||||||
const ideTypeNameMap = {
|
|
||||||
openScad: 'OpenSCAD',
|
|
||||||
cadQuery: 'CadQuery',
|
|
||||||
}
|
|
||||||
|
|
||||||
const ExternalScript = () => {
|
const ExternalScript = () => {
|
||||||
|
|
|||||||
const { state, thunkDispatch } = useIdeContext()
|
const { state, thunkDispatch } = useIdeContext()
|
||||||
const handleRender = useRender()
|
const handleRender = useRender()
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
|
import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
|
||||||
import { matchEditorVsDarkTheme } from 'src/components/IdeEditor'
|
import { matchEditorVsDarkTheme } from 'src/components/IdeEditor'
|
||||||
import PanelToolbar from 'src/components/PanelToolbar'
|
|
||||||
|
|
||||||
const IdeConsole = () => {
|
const IdeConsole = () => {
|
||||||
const { state } = useIdeContext()
|
const { state } = useIdeContext()
|
||||||
@@ -14,10 +13,9 @@ const IdeConsole = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="p-2 px-8 pt-14 min-h-full relative"
|
className="p-2 px-8 pt-14 min-h-full"
|
||||||
style={matchEditorVsDarkTheme.Bg}
|
style={matchEditorVsDarkTheme.Bg}
|
||||||
>
|
>
|
||||||
<PanelToolbar panelName="console" />
|
|
||||||
<div>
|
<div>
|
||||||
{state.consoleMessages?.map(({ type, message, time }, index) => (
|
{state.consoleMessages?.map(({ type, message, time }, index) => (
|
||||||
<pre
|
<pre
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import IdeViewer from 'src/components/IdeViewer'
|
|||||||
import IdeConsole from 'src/components/IdeConsole'
|
import IdeConsole from 'src/components/IdeConsole'
|
||||||
import 'react-mosaic-component/react-mosaic-component.css'
|
import 'react-mosaic-component/react-mosaic-component.css'
|
||||||
import EditorMenu from 'src/components/EditorMenu/EditorMenu'
|
import EditorMenu from 'src/components/EditorMenu/EditorMenu'
|
||||||
|
import PanelToolbar from 'src/components/PanelToolbar'
|
||||||
|
|
||||||
const ELEMENT_MAP = {
|
const ELEMENT_MAP = {
|
||||||
Editor: <IdeEditor />,
|
Editor: <IdeEditor />,
|
||||||
@@ -14,6 +15,24 @@ const ELEMENT_MAP = {
|
|||||||
Console: <IdeConsole />,
|
Console: <IdeConsole />,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TOOLBAR_MAP = {
|
||||||
|
Editor: (
|
||||||
|
<div className="w-full">
|
||||||
|
<EditorMenu />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
Viewer: (
|
||||||
|
<div>
|
||||||
|
<PanelToolbar panelName="Viewer" />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
Console: (
|
||||||
|
<div>
|
||||||
|
<PanelToolbar panelName="Console" />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
const IdeContainer = () => {
|
const IdeContainer = () => {
|
||||||
const { state, thunkDispatch } = useIdeContext()
|
const { state, thunkDispatch } = useIdeContext()
|
||||||
const viewerDOM = useRef(null)
|
const viewerDOM = useRef(null)
|
||||||
@@ -65,15 +84,7 @@ const IdeContainer = () => {
|
|||||||
return (
|
return (
|
||||||
<MosaicWindow
|
<MosaicWindow
|
||||||
path={path}
|
path={path}
|
||||||
renderToolbar={() =>
|
renderToolbar={() => TOOLBAR_MAP[id]}
|
||||||
id === 'Editor' ? (
|
|
||||||
<div className="w-full">
|
|
||||||
<EditorMenu />
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div /> // needs an empty element, otherwise it adds it's own toolbar
|
|
||||||
)
|
|
||||||
}
|
|
||||||
className={`${id.toLowerCase()} ${id.toLowerCase()}-tile`}
|
className={`${id.toLowerCase()} ${id.toLowerCase()}-tile`}
|
||||||
>
|
>
|
||||||
{id === 'Viewer' ? (
|
{id === 'Viewer' ? (
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import {
|
|||||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
||||||
import { Vector3 } from 'three'
|
import { Vector3 } from 'three'
|
||||||
import { requestRender } from 'src/helpers/hooks/useIdeState'
|
import { requestRender } from 'src/helpers/hooks/useIdeState'
|
||||||
import PanelToolbar from 'src/components/PanelToolbar'
|
|
||||||
|
|
||||||
extend({ OrbitControls })
|
extend({ OrbitControls })
|
||||||
|
|
||||||
@@ -228,7 +227,6 @@ const IdeViewer = () => {
|
|||||||
<div className="h-16 w-16 bg-pink-600 rounded-full animate-ping"></div>
|
<div className="h-16 w-16 bg-pink-600 rounded-full animate-ping"></div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<PanelToolbar panelName="3d-view" />
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,13 +35,10 @@ const IdeToolbarNew = ({ cadPackage }) => {
|
|||||||
.
|
.
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
className="flex"
|
className="flex mr-3"
|
||||||
onClick={() => setShouldShowConstructionMessage(false)}
|
onClick={() => setShouldShowConstructionMessage(false)}
|
||||||
>
|
>
|
||||||
<Svg
|
<Svg className="h-4 w-6 text-gray-500 items-center" name="x" />
|
||||||
className="h-4 w-6 text-gray-500 mr-3 items-center"
|
|
||||||
name="x"
|
|
||||||
/>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -5,19 +5,19 @@ import Svg from 'src/components/Svg/Svg'
|
|||||||
const PanelToolbar = ({ panelName }: { panelName: string }) => {
|
const PanelToolbar = ({ panelName }: { panelName: string }) => {
|
||||||
const { mosaicWindowActions } = useContext(MosaicWindowContext)
|
const { mosaicWindowActions } = useContext(MosaicWindowContext)
|
||||||
return (
|
return (
|
||||||
<div className="absolute top-0 left-0 flex items-center h-9">
|
<div className="absolute top-0 right-0 flex items-center h-9">
|
||||||
{mosaicWindowActions.connectDragSource(
|
|
||||||
<div className=" text-gray-500 bg-gray-300 cursor-grab px-2 h-full flex items-center">
|
|
||||||
<Svg name="drag-grid" className="w-4 p-px" />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<button
|
<button
|
||||||
className="bg-gray-500 text-gray-300 px-3 rounded-br-lg h-full cursor-not-allowed"
|
className="bg-gray-500 text-gray-300 px-3 rounded-bl-lg h-full cursor-not-allowed"
|
||||||
aria-label={`${panelName} settings`}
|
aria-label={`${panelName} settings`}
|
||||||
disabled
|
disabled
|
||||||
>
|
>
|
||||||
<Svg name="gear" className="w-7 p-px" />
|
<Svg name="gear" className="w-7 p-px" />
|
||||||
</button>
|
</button>
|
||||||
|
{mosaicWindowActions.connectDragSource(
|
||||||
|
Also rad! Also rad!
|
|||||||
|
<div className=" text-gray-500 bg-gray-300 cursor-grab px-2 h-full flex items-center">
|
||||||
|
<Svg name="drag-grid" className="w-4 p-px" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,3 +4,8 @@ import { useContext } from 'react'
|
|||||||
export function useIdeContext() {
|
export function useIdeContext() {
|
||||||
return useContext(IdeContext)
|
return useContext(IdeContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const ideTypeNameMap = {
|
||||||
|
openScad: 'OpenSCAD',
|
||||||
|
cadQuery: 'CadQuery',
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user


With the additional background I added in the latest Figma designs we may want to start aliasing the CAD packages to class names in the next round so several elements can inherit styles.
Oh right, yeah that's a good idea.