Skip to content

Commit

Permalink
feat: Add shortcuts to select a parent or a child
Browse files Browse the repository at this point in the history
- Those keys feel a bit skeptical though, no better choise so far
  • Loading branch information
miyanokomiya committed Oct 25, 2023
1 parent 2213580 commit 221f027
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function newAlignBoxSelectedState(): AppCanvasState {
targetId = ctx.getLastSelectedShapeId()!;

ctx.showFloatMenu();
ctx.setCommandExams(getCommonCommandExams());
ctx.setCommandExams(getCommonCommandExams(ctx));
initHandler(ctx);
},
onEnd: (ctx) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export function newBoardEntitySelectedState(): AppCanvasState {
});

ctx.showFloatMenu();
ctx.setCommandExams(getCommonCommandExams());
ctx.setCommandExams(getCommonCommandExams(ctx));
initHandler(ctx);
},
onEnd: (ctx) => {
Expand Down
3 changes: 3 additions & 0 deletions src/composables/states/appCanvas/commandExams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ export const COMMAND_EXAM_SRC = {

GROUP: { command: `${getCtrlOrMetaStr()} + g`, title: "Group" },
UNGROUP: { command: `${getCtrlOrMetaStr()} + G`, title: "Ungroup" },

SELECT_PARENT: { command: "p", title: "Select parent" },
SELECT_CHILD: { command: "c", title: "Select child" },
} satisfies { [key: string]: CommandExam };
45 changes: 43 additions & 2 deletions src/composables/states/appCanvas/commons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { newSingleSelectedByPointerOnState } from "./singleSelectedByPointerOnSt
import { newMovingHubState } from "./movingHubState";
import { getPatchByLayouts } from "../../shapeLayoutHandler";
import { ShapeSelectionScope } from "../../../shapes/core";
import { CommandExam } from "../types";

type AcceptableEvent = "Break" | "DroppingNewShape" | "LineReady" | "TextReady";

Expand Down Expand Up @@ -90,6 +91,24 @@ export function handleCommonShortcut(
}
return newSelectionHubState;
}
case "p": {
const shapeComposite = ctx.getShapeComposite();
const current = shapeComposite.shapeMap[ctx.getLastSelectedShapeId() ?? ""];
if (current?.parentId && shapeComposite.shapeMap[current.parentId]) {
ctx.selectShape(current.parentId);
return newSelectionHubState;
}
return;
}
case "c": {
const shapeComposite = ctx.getShapeComposite();
const currentNode = shapeComposite.mergedShapeTreeMap[ctx.getLastSelectedShapeId() ?? ""];
if (currentNode && currentNode.children.length > 0 && shapeComposite.shapeMap[currentNode.children[0].id]) {
ctx.selectShape(currentNode.children[0].id);
return newSelectionHubState;
}
return;
}
case "g":
if (event.data.ctrl) {
event.data.prevent?.();
Expand Down Expand Up @@ -168,8 +187,30 @@ const COMMON_COMMAND_EXAMS = [
COMMAND_EXAM_SRC.PAN_CANVAS,
COMMAND_EXAM_SRC.RESET_VIEWPORT,
];
export function getCommonCommandExams() {
return COMMON_COMMAND_EXAMS;
export function getCommonCommandExams(ctx: AppCanvasStateContext): CommandExam[] {
const shapeComposite = ctx.getShapeComposite();
const shapeMap = shapeComposite.shapeMap;
const current = shapeMap[ctx.getLastSelectedShapeId() ?? ""];
if (!current) return COMMON_COMMAND_EXAMS;

const extra: CommandExam[] = [];
if (shapeComposite.shapeMap[current.parentId ?? ""]) {
extra.push(COMMAND_EXAM_SRC.SELECT_PARENT);
}
const currentNode = shapeComposite.mergedShapeTreeMap[current.id];
if (currentNode.children.length > 0 && shapeMap[currentNode.children[0].id]) {
extra.push(COMMAND_EXAM_SRC.SELECT_CHILD);
}

const selectedIds = Object.keys(ctx.getSelectedShapeIdMap());
if (canGroupShapes(shapeComposite, selectedIds)) {
extra.push(COMMAND_EXAM_SRC.GROUP);
}
if (selectedIds.some((id) => shapeMap[id] && isGroupShape(shapeMap[id]))) {
extra.push(COMMAND_EXAM_SRC.UNGROUP);
}

return extra.length > 0 ? [...extra, ...COMMON_COMMAND_EXAMS] : COMMON_COMMAND_EXAMS;
}

export function handleCommonTextStyle(
Expand Down
2 changes: 1 addition & 1 deletion src/composables/states/appCanvas/defaultState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function newDefaultState(): AppCanvasState {
const state: AppCanvasState = {
getLabel: () => "Default",
onStart(ctx) {
ctx.setCommandExams(getCommonCommandExams());
ctx.setCommandExams(getCommonCommandExams(ctx));
},
onEnd(ctx) {
ctx.setCommandExams();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function newLineLabelSelectedState(option?: Option): AppCanvasState {
return {
getLabel: () => "LineLabelSelected",
onStart: (ctx) => {
ctx.setCommandExams(getCommonCommandExams());
ctx.setCommandExams(getCommonCommandExams(ctx));

const shapeComposite = ctx.getShapeComposite();
const shapeMap = shapeComposite.shapeMap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function newLineSelectedState(): AppCanvasState {
ctx.showFloatMenu();
lineShape = ctx.getShapeComposite().shapeMap[ctx.getLastSelectedShapeId() ?? ""] as LineShape;
lineBounding = newLineBounding({ lineShape, scale: ctx.getScale(), styleScheme: ctx.getStyleScheme() });
ctx.setCommandExams([COMMAND_EXAM_SRC.DELETE_INER_VERTX, ...getCommonCommandExams()]);
ctx.setCommandExams([COMMAND_EXAM_SRC.DELETE_INER_VERTX, ...getCommonCommandExams(ctx)]);
},
onEnd: (ctx) => {
ctx.hideFloatMenu();
Expand Down
12 changes: 2 additions & 10 deletions src/composables/states/appCanvas/multipleSelectedState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ import { newRectangleSelectingState } from "./ractangleSelectingState";
import { newDuplicatingShapesState } from "./duplicatingShapesState";
import { newSelectionHubState } from "./selectionHubState";
import { CONTEXT_MENU_ITEM_SRC, handleContextItemEvent } from "./contextMenuItems";
import { COMMAND_EXAM_SRC } from "./commandExams";
import { canGroupShapes, findBetterShapeAt, getRotatedTargetBounds } from "../../shapeComposite";
import { isGroupShape } from "../../../shapes/group";
import { findBetterShapeAt, getRotatedTargetBounds } from "../../shapeComposite";
import { newMovingHubState } from "./movingHubState";
import { ShapeSelectionScope, isSameShapeSelectionScope } from "../../../shapes/core";

Expand Down Expand Up @@ -73,13 +71,7 @@ export function newMultipleSelectedState(option?: Option): AppCanvasState {
}

ctx.showFloatMenu();
if (selectedIds.some((id) => isGroupShape(shapeMap[id]))) {
ctx.setCommandExams([COMMAND_EXAM_SRC.GROUP, COMMAND_EXAM_SRC.UNGROUP, ...getCommonCommandExams()]);
} else if (canGroupShapes(shapeComposite, selectedIds)) {
ctx.setCommandExams([COMMAND_EXAM_SRC.GROUP, ...getCommonCommandExams()]);
} else {
ctx.setCommandExams(getCommonCommandExams());
}
ctx.setCommandExams(getCommonCommandExams(ctx));

if (option?.boundingBox) {
// Recalculate the bounding because shapes aren't always transformed along with the bounding box.
Expand Down
7 changes: 1 addition & 6 deletions src/composables/states/appCanvas/singleSelectedState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { getOuterRectangle } from "okageo";
import { newSelectionHubState } from "./selectionHubState";
import { CONTEXT_MENU_ITEM_SRC, handleContextItemEvent } from "./contextMenuItems";
import { isGroupShape } from "../../../shapes/group";
import { COMMAND_EXAM_SRC } from "./commandExams";
import { findBetterShapeAt } from "../../shapeComposite";
import { ShapeSelectionScope } from "../../../shapes/core";

Expand All @@ -45,11 +44,7 @@ export function newSingleSelectedState(): AppCanvasState {
selectionScope = shapeComposite.getSelectionScope(shape);
isGroupShapeSelected = isGroupShape(shape);

if (isGroupShapeSelected) {
ctx.setCommandExams([COMMAND_EXAM_SRC.UNGROUP, ...getCommonCommandExams()]);
} else {
ctx.setCommandExams(getCommonCommandExams());
}
ctx.setCommandExams(getCommonCommandExams(ctx));

boundingBox = newBoundingBox({
path: shapeComposite.getLocalRectPolygon(shape),
Expand Down
10 changes: 5 additions & 5 deletions src/utils/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ function getChildNodes<T extends TreeFlatNode>(parentMap: { [id: string]: T[] },
/**
* Depth first ordered
*/
export function walkTree(treeNodes: TreeNode[], fn: (node: TreeNode) => void) {
treeNodes.forEach((n) => walkTreeStep(n, fn));
export function walkTree(treeNodes: TreeNode[], fn: (node: TreeNode, i: number) => void) {
treeNodes.forEach((n, i) => walkTreeStep(n, fn, i));
}

function walkTreeStep(node: TreeNode, fn: (node: TreeNode) => void) {
fn(node);
node.children.forEach((c) => walkTreeStep(c, fn));
function walkTreeStep(node: TreeNode, fn: (node: TreeNode, i: number) => void, i: number) {
fn(node, i);
node.children.forEach((c, j) => walkTreeStep(c, fn, j));
}

/**
Expand Down

0 comments on commit 221f027

Please sign in to comment.