diff --git a/components/editor/editor-layout.tsx b/components/editor/editor-layout.tsx index 22b203b..87e00a8 100644 --- a/components/editor/editor-layout.tsx +++ b/components/editor/editor-layout.tsx @@ -4,15 +4,10 @@ import { useEffect } from 'react'; import { useCanvasStore, useLayerStore } from '@/store'; import { useHistoryStore } from '@/store/history-store'; import { CanvasWithTools } from '@/components/canvas/canvas-with-tools'; -import { LayersPanel } from '@/components/layers/layers-panel'; -import { HistoryPanel } from './history-panel'; import { FileMenu } from './file-menu'; -import { ToolPalette, ToolSettings } from '@/components/tools'; -import { ColorPanel } from '@/components/colors'; -import { FilterPanel } from '@/components/filters'; -import { SelectionPanel } from '@/components/selection'; -import { TransformPanel } from '@/components/transform'; -import { ShapePanel } from '@/components/shapes'; +import { ToolOptions } from './tool-options'; +import { PanelDock } from './panel-dock'; +import { ToolPalette } from '@/components/tools'; import { useKeyboardShortcuts } from '@/hooks/use-keyboard-shortcuts'; import { useFileOperations } from '@/hooks/use-file-operations'; import { useDragDrop } from '@/hooks/use-drag-drop'; @@ -59,8 +54,8 @@ export function EditorLayout() { const handleZoomToFit = () => { // Approximate viewport size (accounting for panels) - const viewportWidth = window.innerWidth - 320; // Subtract sidebar width - const viewportHeight = window.innerHeight - 60; // Subtract toolbar height + const viewportWidth = window.innerWidth - 344; // Subtract sidebar width (64px tools + 280px panels) + const viewportHeight = window.innerHeight - 48; // Subtract toolbar height zoomToFit(viewportWidth, viewportHeight); }; @@ -86,17 +81,24 @@ export function EditorLayout() { )} - {/* Toolbar */} -
-
+ {/* Top Bar */} +
+ {/* Left: Title and File Menu */} +

Paint UI

- {/* History controls */} -
+ {/* Center: Tool Options (context-sensitive) */} +
+ +
+ + {/* Right: Controls */} +
+ {/* History controls */} -
- {/* Zoom controls */} -
+
+ + {/* Zoom controls */} -
-
+
+ + {/* New Layer */}
); diff --git a/components/editor/panel-dock.tsx b/components/editor/panel-dock.tsx new file mode 100644 index 0000000..cb2aa0c --- /dev/null +++ b/components/editor/panel-dock.tsx @@ -0,0 +1,123 @@ +'use client'; + +import { useState } from 'react'; +import { ChevronDown, ChevronRight } from 'lucide-react'; +import { LayersPanel } from '@/components/layers/layers-panel'; +import { ColorPanel } from '@/components/colors'; +import { FilterPanel } from '@/components/filters'; +import { SelectionPanel } from '@/components/selection'; +import { TransformPanel } from '@/components/transform'; +import { ShapePanel } from '@/components/shapes'; +import { HistoryPanel } from './history-panel'; + +interface CollapsibleSectionProps { + title: string; + children: React.ReactNode; + defaultOpen?: boolean; +} + +function CollapsibleSection({ title, children, defaultOpen = true }: CollapsibleSectionProps) { + const [isOpen, setIsOpen] = useState(defaultOpen); + + return ( +
+ + {isOpen &&
{children}
} +
+ ); +} + +export function PanelDock() { + const [activeTab, setActiveTab] = useState<'adjustments' | 'tools' | 'history'>('adjustments'); + + return ( +
+ {/* Always visible panels */} +
+ +
+ +
+ +
+ + {/* Tabbed section */} +
+ {/* Tab buttons */} +
+ + + +
+ + {/* Tab content */} +
+ {activeTab === 'adjustments' && ( +
+ + + + + + + + + +
+ )} + + {activeTab === 'tools' && ( +
+ + + +
+ )} + + {activeTab === 'history' && ( +
+ +
+ )} +
+
+
+ ); +} diff --git a/components/editor/tool-options.tsx b/components/editor/tool-options.tsx new file mode 100644 index 0000000..3c3a868 --- /dev/null +++ b/components/editor/tool-options.tsx @@ -0,0 +1,170 @@ +'use client'; + +import { useToolStore } from '@/store'; +import { useShapeStore } from '@/store/shape-store'; +import { useSelectionStore } from '@/store/selection-store'; + +export function ToolOptions() { + const { activeTool, settings, setSize, setOpacity, setHardness, setColor, setFlow } = useToolStore(); + const { settings: shapeSettings, setShapeType } = useShapeStore(); + const { selectionType, setSelectionType } = useSelectionStore(); + + // Drawing tools: brush, pencil, eraser + const isDrawingTool = ['brush', 'eraser', 'pencil'].includes(activeTool); + const showHardness = ['brush'].includes(activeTool); + const showColor = ['brush', 'pencil', 'fill'].includes(activeTool); + const showFlow = ['brush'].includes(activeTool); + + // Shape tool + const isShapeTool = activeTool === 'shape'; + + // Selection tool + const isSelectionTool = activeTool === 'select'; + + // Don't show options bar if no options available + if (!isDrawingTool && !isShapeTool && !isSelectionTool) { + return null; + } + + return ( +
+ {/* Drawing Tools Options */} + {isDrawingTool && ( + <> + {showColor && ( +
+ + setColor(e.target.value)} + className="h-8 w-16 rounded border border-border cursor-pointer" + /> + setColor(e.target.value)} + className="w-24 px-2 py-1 text-xs rounded border border-border bg-background text-foreground" + /> +
+ )} + +
+ + setSize(Number(e.target.value))} + className="w-32" + /> + + {settings.size}px + +
+ +
+ + setOpacity(Number(e.target.value) / 100)} + className="w-32" + /> + + {Math.round(settings.opacity * 100)}% + +
+ + {showHardness && ( +
+ + setHardness(Number(e.target.value) / 100)} + className="w-32" + /> + + {Math.round(settings.hardness * 100)}% + +
+ )} + + {showFlow && ( +
+ + setFlow(Number(e.target.value) / 100)} + className="w-32" + /> + + {Math.round(settings.flow * 100)}% + +
+ )} + + )} + + {/* Shape Tool Options */} + {isShapeTool && ( +
+ + +
+ )} + + {/* Selection Tool Options */} + {isSelectionTool && ( +
+ + +
+ )} +
+ ); +}