tidy(ui): selectedLayer -> selectedLayerId

This commit is contained in:
psychedelicious 2024-04-19 21:06:48 +10:00 committed by Kent Keirsey
parent 9528287d56
commit e93e0612af
6 changed files with 44 additions and 46 deletions

View File

@ -17,11 +17,11 @@ type Props = {
export const RPLayerListItem = memo(({ layerId }: Props) => {
const dispatch = useAppDispatch();
const selectedLayer = useAppSelector((s) => s.regionalPrompts.present.selectedLayer);
const selectedLayerId = useAppSelector((s) => s.regionalPrompts.present.selectedLayerId);
const color = useAppSelector((s) => {
const layer = s.regionalPrompts.present.layers.find((l) => l.id === layerId);
assert(isRPLayer(layer), `Layer ${layerId} not found or not an RP layer`);
return rgbaColorToString({ ...layer.color, a: selectedLayer === layerId ? 1 : 0.35 });
return rgbaColorToString({ ...layer.color, a: selectedLayerId === layerId ? 1 : 0.35 });
});
const onClickCapture = useCallback(() => {
// Must be capture so that the layer is selected before deleting/resetting/etc

View File

@ -22,11 +22,11 @@ import { assert } from 'tsafe';
const log = logger('regionalPrompts');
const $stage = atom<Konva.Stage | null>(null);
const selectSelectedLayerColor = createMemoizedSelector(selectRegionalPromptsSlice, (regionalPrompts) => {
const layer = regionalPrompts.present.layers.find((l) => l.id === regionalPrompts.present.selectedLayer);
const layer = regionalPrompts.present.layers.find((l) => l.id === regionalPrompts.present.selectedLayerId);
if (!layer) {
return null;
}
assert(isRPLayer(layer), `Layer ${regionalPrompts.present.selectedLayer} is not an RP layer`);
assert(isRPLayer(layer), `Layer ${regionalPrompts.present.selectedLayerId} is not an RP layer`);
return layer.color;
});
@ -39,7 +39,7 @@ const useStageRenderer = (container: HTMLDivElement | null, wrapper: HTMLDivElem
const tool = useStore($tool);
const { onMouseDown, onMouseUp, onMouseMove, onMouseEnter, onMouseLeave } = useMouseEvents();
const cursorPosition = useStore($cursorPosition);
const selectedLayerColor = useAppSelector(selectSelectedLayerColor);
const selectedLayerIdColor = useAppSelector(selectSelectedLayerColor);
const onLayerPosChanged = useCallback(
(layerId: string, x: number, y: number) => {
@ -122,24 +122,24 @@ const useStageRenderer = (container: HTMLDivElement | null, wrapper: HTMLDivElem
if (!stage) {
return;
}
renderBrushPreview(stage, tool, selectedLayerColor, cursorPosition, state.brushSize);
}, [stage, tool, cursorPosition, state.brushSize, selectedLayerColor]);
renderBrushPreview(stage, tool, selectedLayerIdColor, cursorPosition, state.brushSize);
}, [stage, tool, cursorPosition, state.brushSize, selectedLayerIdColor]);
useLayoutEffect(() => {
log.trace('Rendering layers');
if (!stage) {
return;
}
renderLayers(stage, state.layers, state.selectedLayer, state.promptLayerOpacity, tool, onLayerPosChanged);
}, [onLayerPosChanged, stage, state.layers, state.promptLayerOpacity, tool, state.selectedLayer]);
renderLayers(stage, state.layers, state.selectedLayerId, state.promptLayerOpacity, tool, onLayerPosChanged);
}, [onLayerPosChanged, stage, state.layers, state.promptLayerOpacity, tool, state.selectedLayerId]);
useLayoutEffect(() => {
log.trace('Rendering bbox');
if (!stage) {
return;
}
renderBbox(stage, tool, state.selectedLayer, onBboxChanged);
}, [dispatch, stage, tool, state.selectedLayer, onBboxChanged]);
renderBbox(stage, tool, state.selectedLayerId, onBboxChanged);
}, [dispatch, stage, tool, state.selectedLayerId, onBboxChanged]);
};
const $container = atom<HTMLDivElement | null>(null);

View File

@ -28,7 +28,7 @@ const syncCursorPos = (stage: Konva.Stage) => {
export const useMouseEvents = () => {
const dispatch = useAppDispatch();
const selectedLayer = useAppSelector((s) => s.regionalPrompts.present.selectedLayer);
const selectedLayerId = useAppSelector((s) => s.regionalPrompts.present.selectedLayerId);
const tool = useStore($tool);
const onMouseDown = useCallback(
@ -42,15 +42,15 @@ export const useMouseEvents = () => {
return;
}
$isMouseDown.set(true);
if (!selectedLayer) {
if (!selectedLayerId) {
return;
}
// const tool = getTool();
if (tool === 'brush' || tool === 'eraser') {
dispatch(rpLayerLineAdded({ layerId: selectedLayer, points: [pos.x, pos.y, pos.x, pos.y], tool }));
dispatch(rpLayerLineAdded({ layerId: selectedLayerId, points: [pos.x, pos.y, pos.x, pos.y], tool }));
}
},
[dispatch, selectedLayer, tool]
[dispatch, selectedLayerId, tool]
);
const onMouseUp = useCallback(
@ -74,15 +74,15 @@ export const useMouseEvents = () => {
return;
}
const pos = syncCursorPos(stage);
if (!pos || !selectedLayer) {
if (!pos || !selectedLayerId) {
return;
}
// const tool = getTool();
if (getIsFocused(stage) && $isMouseOver.get() && $isMouseDown.get() && (tool === 'brush' || tool === 'eraser')) {
dispatch(rpLayerPointsAdded({ layerId: selectedLayer, point: [pos.x, pos.y] }));
dispatch(rpLayerPointsAdded({ layerId: selectedLayerId, point: [pos.x, pos.y] }));
}
},
[dispatch, selectedLayer, tool]
[dispatch, selectedLayerId, tool]
);
const onMouseLeave = useCallback((e: KonvaEventObject<MouseEvent | TouchEvent>) => {
@ -113,15 +113,15 @@ export const useMouseEvents = () => {
$isMouseDown.set(false);
} else {
$isMouseDown.set(true);
if (!selectedLayer) {
if (!selectedLayerId) {
return;
}
if (tool === 'brush' || tool === 'eraser') {
dispatch(rpLayerLineAdded({ layerId: selectedLayer, points: [pos.x, pos.y, pos.x, pos.y], tool }));
dispatch(rpLayerLineAdded({ layerId: selectedLayerId, points: [pos.x, pos.y, pos.x, pos.y], tool }));
}
}
},
[dispatch, selectedLayer, tool]
[dispatch, selectedLayerId, tool]
);
return { onMouseDown, onMouseUp, onMouseMove, onMouseEnter, onMouseLeave };

View File

@ -10,7 +10,7 @@ import type { UndoableOptions } from 'redux-undo';
import { assert } from 'tsafe';
import { v4 as uuidv4 } from 'uuid';
export type DrawingTool = 'brush' | 'eraser';
type DrawingTool = 'brush' | 'eraser';
export type RPTool = DrawingTool | 'move';
@ -65,7 +65,7 @@ export type Layer = RegionalPromptLayer;
type RegionalPromptsState = {
_version: 1;
selectedLayer: string | null;
selectedLayerId: string | null;
layers: Layer[];
brushSize: number;
promptLayerOpacity: number;
@ -74,7 +74,7 @@ type RegionalPromptsState = {
export const initialRegionalPromptsState: RegionalPromptsState = {
_version: 1,
selectedLayer: null,
selectedLayerId: null,
brushSize: 40,
layers: [],
promptLayerOpacity: 0.5, // This currently doesn't work
@ -106,7 +106,7 @@ export const regionalPromptsSlice = createSlice({
autoNegative: 'off',
};
state.layers.push(layer);
state.selectedLayer = layer.id;
state.selectedLayerId = layer.id;
return;
}
},
@ -114,7 +114,7 @@ export const regionalPromptsSlice = createSlice({
},
layerDeleted: (state, action: PayloadAction<string>) => {
state.layers = state.layers.filter((l) => l.id !== action.payload);
state.selectedLayer = state.layers[0]?.id ?? null;
state.selectedLayerId = state.layers[0]?.id ?? null;
},
layerMovedForward: (state, action: PayloadAction<string>) => {
const cb = (l: Layer) => l.id === action.payload;
@ -139,7 +139,7 @@ export const regionalPromptsSlice = createSlice({
rpLayerSelected: (state, action: PayloadAction<string>) => {
const layer = state.layers.find((l) => l.id === action.payload);
if (isRPLayer(layer)) {
state.selectedLayer = layer.id;
state.selectedLayerId = layer.id;
}
},
rpLayerIsVisibleToggled: (state, action: PayloadAction<string>) => {
@ -173,7 +173,7 @@ export const regionalPromptsSlice = createSlice({
},
allLayersDeleted: (state) => {
state.layers = [];
state.selectedLayer = null;
state.selectedLayerId = null;
},
rpLayerPositivePromptChanged: (state, action: PayloadAction<{ layerId: string; prompt: string }>) => {
const { layerId, prompt } = action.payload;
@ -349,13 +349,12 @@ export const regionalPromptsPersistConfig: PersistConfig<RegionalPromptsState> =
name: regionalPromptsSlice.name,
initialState: initialRegionalPromptsState,
migrate: migrateRegionalPromptsState,
persistDenylist: ['tool'],
persistDenylist: [],
};
// Payload-less actions for `redux-undo`
export const undoRegionalPrompts = createAction(`${regionalPromptsSlice.name}/undo`);
export const redoRegionalPrompts = createAction(`${regionalPromptsSlice.name}/redo`);
export const clearHistoryRegionalPrompts = createAction(`${regionalPromptsSlice.name}/clearHistory`);
// These actions are _individually_ grouped together as single undoable actions
const undoableGroupByMatcher = isAnyOf(
@ -374,7 +373,6 @@ export const regionalPromptsUndoableConfig: UndoableOptions<RegionalPromptsState
limit: 64,
undoType: undoRegionalPrompts.type,
redoType: redoRegionalPrompts.type,
clearHistoryType: clearHistoryRegionalPrompts.type,
groupBy: (action, state, history) => {
// Lines are started with `rpLayerLineAdded` and may have any number of subsequent `rpLayerPointsAdded` events.
// We can use a double-buffer-esque trick to group each "logical" line as a single undoable action, without grouping

View File

@ -18,10 +18,10 @@ export const getRegionalPromptLayerBlobs = async (
): Promise<Record<string, Blob>> => {
const state = getStore().getState();
const reduxLayers = state.regionalPrompts.present.layers;
const selectedLayerId = state.regionalPrompts.present.selectedLayer;
const selectedLayerIdId = state.regionalPrompts.present.selectedLayerId;
const container = document.createElement('div');
const stage = new Konva.Stage({ container, width: state.generation.width, height: state.generation.height });
renderLayers(stage, reduxLayers, selectedLayerId, 1, 'brush');
renderLayers(stage, reduxLayers, selectedLayerIdId, 1, 'brush');
const konvaLayers = stage.find<Konva.Layer>(`.${REGIONAL_PROMPT_LAYER_NAME}`);
const blobs: Record<string, Blob> = {};

View File

@ -129,7 +129,7 @@ const renderRPLayer = (
stage: Konva.Stage,
rpLayer: RegionalPromptLayer,
rpLayerIndex: number,
selectedLayerId: string | null,
selectedLayerIdId: string | null,
tool: RPTool,
layerOpacity: number,
onLayerPosChanged?: (layerId: string, x: number, y: number) => void
@ -195,7 +195,7 @@ const renderRPLayer = (
// Update the layer's position and listening state (only the selected layer is listening)
konvaLayer.setAttrs({
listening: rpLayer.id === selectedLayerId && tool === 'move',
listening: rpLayer.id === selectedLayerIdId && tool === 'move',
x: rpLayer.x,
y: rpLayer.y,
// There are rpLayers.length layers, plus a brush preview layer rendered on top of them, so the zIndex works
@ -268,7 +268,7 @@ const renderRPLayer = (
* Renders the layers on the stage.
* @param stage The konva stage to render on.
* @param reduxLayers Array of the layers from the redux store.
* @param selectedLayerId The selected layer id.
* @param selectedLayerIdId The selected layer id.
* @param layerOpacity The opacity of the layer.
* @param onLayerPosChanged Callback for when the layer's position changes. This is optional to allow for offscreen rendering.
* @returns
@ -276,7 +276,7 @@ const renderRPLayer = (
export const renderLayers = (
stage: Konva.Stage,
reduxLayers: Layer[],
selectedLayerId: string | null,
selectedLayerIdId: string | null,
layerOpacity: number,
tool: RPTool,
onLayerPosChanged?: (layerId: string, x: number, y: number) => void
@ -294,7 +294,7 @@ export const renderLayers = (
const reduxLayer = reduxLayers[layerIndex];
assert(reduxLayer, `Layer at index ${layerIndex} is undefined`);
if (reduxLayer.kind === 'regionalPromptLayer') {
renderRPLayer(stage, reduxLayer, layerIndex, selectedLayerId, tool, layerOpacity, onLayerPosChanged);
renderRPLayer(stage, reduxLayer, layerIndex, selectedLayerIdId, tool, layerOpacity, onLayerPosChanged);
}
}
};
@ -306,14 +306,14 @@ const selectPromptLayerObjectGroup = (item: Node<NodeConfig>) =>
*
* @param stage The konva stage to render on.
* @param tool The current tool.
* @param selectedLayerId The currently selected layer id.
* @param selectedLayerIdId The currently selected layer id.
* @param onBboxChanged A callback to be called when the bounding box changes.
* @returns
*/
export const renderBbox = (
stage: Konva.Stage,
tool: RPTool,
selectedLayerId: string | null,
selectedLayerIdId: string | null,
onBboxChanged: (layerId: string, bbox: IRect) => void
) => {
// Hide all bounding boxes
@ -323,20 +323,20 @@ export const renderBbox = (
}
// No selected layer or not using the move tool - nothing more to do here
if (!selectedLayerId || tool !== 'move') {
if (!selectedLayerIdId || tool !== 'move') {
return;
}
const konvaLayer = stage.findOne<Konva.Layer>(`#${selectedLayerId}`);
assert(konvaLayer, `Selected layer ${selectedLayerId} not found in stage`);
const konvaLayer = stage.findOne<Konva.Layer>(`#${selectedLayerIdId}`);
assert(konvaLayer, `Selected layer ${selectedLayerIdId} not found in stage`);
const bbox = getKonvaLayerBbox(konvaLayer, selectPromptLayerObjectGroup);
onBboxChanged(selectedLayerId, bbox);
onBboxChanged(selectedLayerIdId, bbox);
let rect = konvaLayer.findOne<Konva.Rect>(`.${REGIONAL_PROMPT_LAYER_BBOX_NAME}`);
if (!rect) {
rect = new Konva.Rect({
id: getPRLayerBboxId(selectedLayerId),
id: getPRLayerBboxId(selectedLayerIdId),
name: REGIONAL_PROMPT_LAYER_BBOX_NAME,
strokeWidth: 1,
});
@ -349,6 +349,6 @@ export const renderBbox = (
width: bbox.width,
height: bbox.height,
listening: true,
stroke: selectedLayerId === selectedLayerId ? 'rgba(153, 187, 189, 1)' : 'rgba(255, 255, 255, 0.149)',
stroke: selectedLayerIdId === selectedLayerIdId ? 'rgba(153, 187, 189, 1)' : 'rgba(255, 255, 255, 0.149)',
});
};