refactor: move selection util script into selection context
This commit is contained in:
parent
4687330f02
commit
a80119c011
6 changed files with 22 additions and 38 deletions
|
|
@ -25,8 +25,6 @@ import { usePaintBucketTool } from "@/hooks/tools/paint-bucket";
|
||||||
import { useEyedropperTool } from "@/hooks/tools/eyedropper";
|
import { useEyedropperTool } from "@/hooks/tools/eyedropper";
|
||||||
import { useZoomTool } from "@/hooks/tools/zoom";
|
import { useZoomTool } from "@/hooks/tools/zoom";
|
||||||
|
|
||||||
import * as selection from "@/utils/selection";
|
|
||||||
|
|
||||||
import Blocks from "./Blocks";
|
import Blocks from "./Blocks";
|
||||||
import Cursor from "./Cursor";
|
import Cursor from "./Cursor";
|
||||||
import Selection from "./Selection";
|
import Selection from "./Selection";
|
||||||
|
|
@ -43,7 +41,7 @@ PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
|
||||||
function Canvas() {
|
function Canvas() {
|
||||||
const { stageSize, canvasSize, blocks, coords, scale, version, setStageSize, setBlocks, setCoords, setScale } = useContext(CanvasContext);
|
const { stageSize, canvasSize, blocks, coords, scale, version, setStageSize, setBlocks, setCoords, setScale } = useContext(CanvasContext);
|
||||||
const { addHistory, undo, redo } = useContext(HistoryContext);
|
const { addHistory, undo, redo } = useContext(HistoryContext);
|
||||||
const { selectionCoords, selectionLayerBlocks, setSelectionCoords, setSelectionLayerBlocks } = useContext(SelectionContext);
|
const { selectionCoords, selectionLayerBlocks, setSelectionCoords, setSelectionLayerBlocks, confirmSelection } = useContext(SelectionContext);
|
||||||
const { settings } = useContext(SettingsContext);
|
const { settings } = useContext(SettingsContext);
|
||||||
const { missingTexture } = useContext(TexturesContext);
|
const { missingTexture } = useContext(TexturesContext);
|
||||||
const { isDark } = useContext(ThemeContext);
|
const { isDark } = useContext(ThemeContext);
|
||||||
|
|
@ -250,7 +248,7 @@ function Canvas() {
|
||||||
setSelectionLayerBlocks([]);
|
setSelectionLayerBlocks([]);
|
||||||
break;
|
break;
|
||||||
case "Enter":
|
case "Enter":
|
||||||
selection.confirm(blocks, selectionLayerBlocks, setBlocks, setSelectionLayerBlocks);
|
confirmSelection();
|
||||||
break;
|
break;
|
||||||
case " ": // Space
|
case " ": // Space
|
||||||
setDragging(true);
|
setDragging(true);
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,12 @@
|
||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { CheckIcon, XIcon } from "lucide-react";
|
import { CheckIcon, XIcon } from "lucide-react";
|
||||||
|
|
||||||
import { CanvasContext } from "@/context/Canvas";
|
|
||||||
import { SelectionContext } from "@/context/Selection";
|
import { SelectionContext } from "@/context/Selection";
|
||||||
|
|
||||||
import * as selection from "@/utils/selection";
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
||||||
function SelectionBar() {
|
function SelectionBar() {
|
||||||
const { blocks, setBlocks } = useContext(CanvasContext);
|
const { selectionLayerBlocks, setSelectionLayerBlocks, confirmSelection } = useContext(SelectionContext);
|
||||||
const { selectionLayerBlocks, setSelectionLayerBlocks } = useContext(SelectionContext);
|
|
||||||
|
|
||||||
const [isVisible, setIsVisible] = useState(false);
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
|
|
||||||
|
|
@ -29,7 +25,7 @@ function SelectionBar() {
|
||||||
<XIcon />
|
<XIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<span className="mx-2 text-[0.85rem]">Confirm selection?</span>
|
<span className="mx-2 text-[0.85rem]">Confirm selection?</span>
|
||||||
<Button variant="ghost" className="w-8 h-8" onClick={() => selection.confirm(blocks, selectionLayerBlocks, setBlocks, setSelectionLayerBlocks)}>
|
<Button variant="ghost" className="w-8 h-8" onClick={confirmSelection}>
|
||||||
<CheckIcon />
|
<CheckIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,9 @@ import { SelectionContext } from "@/context/Selection";
|
||||||
import { MenubarContent, MenubarItem, MenubarMenu, MenubarShortcut, MenubarTrigger } from "@/components/ui/menubar";
|
import { MenubarContent, MenubarItem, MenubarMenu, MenubarShortcut, MenubarTrigger } from "@/components/ui/menubar";
|
||||||
import { CanvasContext } from "@/context/Canvas";
|
import { CanvasContext } from "@/context/Canvas";
|
||||||
|
|
||||||
import * as selection from "@/utils/selection";
|
|
||||||
|
|
||||||
function SelectMenu() {
|
function SelectMenu() {
|
||||||
const { canvasSize } = useContext(CanvasContext);
|
const { canvasSize } = useContext(CanvasContext);
|
||||||
const { selectionCoords, setSelectionCoords } = useContext(SelectionContext);
|
const { setSelectionCoords, isInSelection } = useContext(SelectionContext);
|
||||||
|
|
||||||
// Add every block within the canvas size to the temporary array
|
// Add every block within the canvas size to the temporary array
|
||||||
const selectAll = () => {
|
const selectAll = () => {
|
||||||
|
|
@ -30,7 +28,7 @@ function SelectMenu() {
|
||||||
|
|
||||||
for (let x = canvasSize.minX; x < canvasSize.maxX; x++) {
|
for (let x = canvasSize.minX; x < canvasSize.maxX; x++) {
|
||||||
for (let y = canvasSize.minY; y < canvasSize.maxY; y++) {
|
for (let y = canvasSize.minY; y < canvasSize.maxY; y++) {
|
||||||
if (!selection.isIn(selectionCoords, x, y)) newSelection.push([x, y]);
|
if (!isInSelection(x, y)) newSelection.push([x, y]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,10 @@ import { Label } from "@/components/ui/label";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
||||||
import { useTextures } from "@/hooks/useTextures";
|
import { useTextures } from "@/hooks/useTextures";
|
||||||
import * as selection from "@/utils/selection";
|
|
||||||
|
|
||||||
function Replace() {
|
function Replace() {
|
||||||
const { version, setBlocks } = useContext(CanvasContext);
|
const { version, setBlocks } = useContext(CanvasContext);
|
||||||
const { selectionCoords } = useContext(SelectionContext);
|
const { isInSelection } = useContext(SelectionContext);
|
||||||
const { selectedBlock, tool, setTool } = useContext(ToolContext);
|
const { selectedBlock, tool, setTool } = useContext(ToolContext);
|
||||||
const { missingTexture } = useContext(TexturesContext);
|
const { missingTexture } = useContext(TexturesContext);
|
||||||
|
|
||||||
|
|
@ -36,7 +35,7 @@ function Replace() {
|
||||||
setBlocks((prev) =>
|
setBlocks((prev) =>
|
||||||
prev
|
prev
|
||||||
.map((block) => {
|
.map((block) => {
|
||||||
if (selection.isIn(selectionCoords, block.x, block.y)) {
|
if (isInSelection(block.x, block.y)) {
|
||||||
if (block.name === block1) {
|
if (block.name === block1) {
|
||||||
// If block2 is air, return null
|
// If block2 is air, return null
|
||||||
// If not, change the block name
|
// If not, change the block name
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { createContext, ReactNode, useState } from "react";
|
import { createContext, ReactNode, useContext, useState } from "react";
|
||||||
|
import { CanvasContext } from "./Canvas";
|
||||||
|
|
||||||
interface Context {
|
interface Context {
|
||||||
selectionCoords: CoordinateArray;
|
selectionCoords: CoordinateArray;
|
||||||
|
|
@ -6,6 +7,7 @@ interface Context {
|
||||||
setSelectionCoords: React.Dispatch<React.SetStateAction<CoordinateArray>>;
|
setSelectionCoords: React.Dispatch<React.SetStateAction<CoordinateArray>>;
|
||||||
setSelectionLayerBlocks: React.Dispatch<React.SetStateAction<Block[]>>;
|
setSelectionLayerBlocks: React.Dispatch<React.SetStateAction<Block[]>>;
|
||||||
isInSelection: (x: number, y: number) => boolean;
|
isInSelection: (x: number, y: number) => boolean;
|
||||||
|
confirmSelection: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|
@ -15,6 +17,8 @@ interface Props {
|
||||||
export const SelectionContext = createContext<Context>({} as Context);
|
export const SelectionContext = createContext<Context>({} as Context);
|
||||||
|
|
||||||
export const SelectionProvider = ({ children }: Props) => {
|
export const SelectionProvider = ({ children }: Props) => {
|
||||||
|
const { blocks, setBlocks } = useContext(CanvasContext);
|
||||||
|
|
||||||
const [selectionCoords, setSelectionCoords] = useState<CoordinateArray>([]);
|
const [selectionCoords, setSelectionCoords] = useState<CoordinateArray>([]);
|
||||||
const [selectionLayerBlocks, setSelectionLayerBlocks] = useState<Block[]>([]);
|
const [selectionLayerBlocks, setSelectionLayerBlocks] = useState<Block[]>([]);
|
||||||
|
|
||||||
|
|
@ -25,6 +29,14 @@ export const SelectionProvider = ({ children }: Props) => {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const confirmSelection = () => {
|
||||||
|
const combinedBlocks = [...blocks, ...selectionLayerBlocks];
|
||||||
|
const uniqueBlocks = Array.from(new Map(combinedBlocks.map((block) => [`${block.x},${block.y}`, block])).values());
|
||||||
|
|
||||||
|
setBlocks(uniqueBlocks);
|
||||||
|
setSelectionLayerBlocks([]);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SelectionContext.Provider
|
<SelectionContext.Provider
|
||||||
value={{
|
value={{
|
||||||
|
|
@ -33,6 +45,7 @@ export const SelectionProvider = ({ children }: Props) => {
|
||||||
setSelectionCoords,
|
setSelectionCoords,
|
||||||
setSelectionLayerBlocks,
|
setSelectionLayerBlocks,
|
||||||
isInSelection,
|
isInSelection,
|
||||||
|
confirmSelection,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
// Check if a block is within the selection
|
|
||||||
export function isIn(selection: CoordinateArray, x: number, y: number): boolean {
|
|
||||||
if (selection.length !== 0) {
|
|
||||||
return selection.some(([x2, y2]) => x2 === x && y2 === y);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function confirm(
|
|
||||||
blocks: Block[],
|
|
||||||
layerBlocks: Block[],
|
|
||||||
setBlocks: React.Dispatch<React.SetStateAction<Block[]>>,
|
|
||||||
setLayerBlocks: React.Dispatch<React.SetStateAction<Block[]>>
|
|
||||||
) {
|
|
||||||
const combinedBlocks = [...blocks, ...layerBlocks];
|
|
||||||
const uniqueBlocks = Array.from(new Map(combinedBlocks.map((block) => [`${block.x},${block.y}`, block])).values());
|
|
||||||
|
|
||||||
setBlocks(uniqueBlocks);
|
|
||||||
setLayerBlocks([]);
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue