diff --git a/public/images/tools/arc.png b/public/images/tools/arc.png new file mode 100644 index 0000000..59aedf7 Binary files /dev/null and b/public/images/tools/arc.png differ diff --git a/public/images/tools/loc.png b/public/images/tools/loc.png new file mode 100644 index 0000000..07a801d Binary files /dev/null and b/public/images/tools/loc.png differ diff --git a/public/images/tools/pck.png b/public/images/tools/pck.png new file mode 100644 index 0000000..11148ec Binary files /dev/null and b/public/images/tools/pck.png differ diff --git a/src/components/views/ArcEditorView.tsx b/src/components/views/ArcEditorView.tsx new file mode 100644 index 0000000..e016f38 --- /dev/null +++ b/src/components/views/ArcEditorView.tsx @@ -0,0 +1,89 @@ +import { useState, useEffect, useRef } from "react"; +import { motion } from "framer-motion"; +import { useUI, useAudio, useConfig } from "../../context/LauncherContext"; + +export default function ArcEditorView() { + const { setActiveView } = useUI(); + const { playBackSound } = useAudio(); + const { animationsEnabled } = useConfig(); + const [focusIndex, setFocusIndex] = useState(0); + const containerRef = useRef(null); + + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === "Escape" || e.key === "Backspace") { + playBackSound(); + setActiveView("devtools"); + return; + } + if (e.key === "Enter") { + if (focusIndex === 0) { + playBackSound(); + setActiveView("devtools"); + } + } + }; + window.addEventListener("keydown", handleKeyDown); + return () => window.removeEventListener("keydown", handleKeyDown); + }, [playBackSound, setActiveView, focusIndex]); + + useEffect(() => { + const el = containerRef.current?.querySelector(`[data-index="${focusIndex}"]`) as HTMLElement; + if (el) el.focus(); + }, [focusIndex]); + + return ( + +

+ ARC Editor +

+ +
+ +

ARC Editor Coming Soon

+

+ This tool will allow you to edit ARC files. +

+
+ + +
+ ); +} diff --git a/src/components/views/DevtoolsView.tsx b/src/components/views/DevtoolsView.tsx index 6e2f1c0..ce73030 100644 --- a/src/components/views/DevtoolsView.tsx +++ b/src/components/views/DevtoolsView.tsx @@ -1,70 +1,146 @@ import { useState, useEffect, useRef } from "react"; import { motion } from "framer-motion"; import { useUI, useAudio, useConfig } from "../../context/LauncherContext"; + +interface DevTool { + id: string; + name: string; + view: string; + comingSoon: boolean; +} + +const DEV_TOOLS: DevTool[] = [ + { id: "pck", name: "PCK Editor", view: "pck-editor", comingSoon: false }, + { id: "arc", name: "ARC Editor", view: "arc-editor", comingSoon: false }, + { id: "loc", name: "LOC Editor", view: "devtools", comingSoon: false } +]; + export default function DevtoolsView() { const { setActiveView } = useUI(); - const [backHover, setBackHover] = useState(false); - const { playPressSound } = useAudio(); - const [focusIndex] = useState(null); + const { playPressSound, playBackSound } = useAudio(); + const { animationsEnabled } = useConfig(); + const [focusIndex, setFocusIndex] = useState(0); const containerRef = useRef(null); + const BACK_BUTTON_INDEX = DEV_TOOLS.length; useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === "Escape" || e.key === "Backspace") { - playPressSound(); + playBackSound(); setActiveView("main"); + return; + } + + if (e.key === "ArrowRight") { + setFocusIndex((prev) => (prev >= BACK_BUTTON_INDEX ? 0 : prev + 1)); + } else if (e.key === "ArrowLeft") { + setFocusIndex((prev) => (prev <= 0 ? BACK_BUTTON_INDEX : prev - 1)); + } else if (e.key === "ArrowDown") { + if (focusIndex < BACK_BUTTON_INDEX) { + setFocusIndex(BACK_BUTTON_INDEX); + } + } else if (e.key === "ArrowUp") { + if (focusIndex === BACK_BUTTON_INDEX) { + setFocusIndex(0); + } + } else if (e.key === "Enter") { + if (focusIndex === BACK_BUTTON_INDEX) { + playBackSound(); + setActiveView("main"); + } else { + playPressSound(); + const tool = DEV_TOOLS[focusIndex]; + setActiveView(tool.view); + } } }; + window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); - }, [playPressSound, setActiveView]); + }, [focusIndex, playPressSound, playBackSound, setActiveView, BACK_BUTTON_INDEX]); useEffect(() => { if (focusIndex !== null) { - const el = containerRef.current?.querySelector( - `[data-index="${focusIndex}"]`, - ) as HTMLElement; + const el = containerRef.current?.querySelector(`[data-index="${focusIndex}"]`) as HTMLElement; if (el) el.focus(); } }, [focusIndex]); return ( -

+

Developer Tools

- - Developer Tools coming soon... - +
+ {DEV_TOOLS.map((tool, i) => ( +
setFocusIndex(i)} + onClick={() => { + playPressSound(); + setActiveView(tool.view); + }} + className={`group flex flex-col items-center gap-3 w-40 p-4 relative transition-all cursor-pointer outline-none border-2 ${focusIndex === i ? "border-[#FFFF55] bg-white/5" : "border-transparent" + }`} + > +
+ {tool.name} + {tool.comingSoon && ( +
+ + Coming Soon + +
+ )} +
+ + {tool.name} + +
+ ))} +
+
+ ); +} diff --git a/src/pages/App.tsx b/src/pages/App.tsx index 96e86ca..c5bad86 100644 --- a/src/pages/App.tsx +++ b/src/pages/App.tsx @@ -7,6 +7,8 @@ import DevtoolsView from "../components/views/DevtoolsView"; import SkinsView from "../components/views/SkinsView"; import WorkshopView from "../components/views/WorkshopView"; import SetupView from "../components/views/SetupView"; +import PckEditorView from "../components/views/PckEditorView"; +import ArcEditorView from "../components/views/ArcEditorView"; import SkinViewer from "../components/common/SkinViewer"; import TeamModal from "../components/modals/TeamModal"; import PanoramaBackground from "../components/common/PanoramaBackground"; @@ -339,6 +341,12 @@ export default function App() { {activeView === "devtools" && ( )} + {activeView === "pck-editor" && ( + + )} + {activeView === "arc-editor" && ( + + )} {activeView === "skins" && }