mock: スタビ位置は、どのサイズも何も選ばない状態から始める(T-30 単位8)
候補が1つのサイズも既定で選ばない。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017yoUu9Xd8dhwyQdCfKfaXG
This commit is contained in:
@@ -44,11 +44,6 @@ export function stabilizerCandidates(size: Size): StabilizerCandidate[] {
|
||||
const length = Math.max(size.w, size.h);
|
||||
return TABLE.find((row) => row.lengths.some((l) => Math.abs(l - length) < EPS))?.candidates ?? [];
|
||||
}
|
||||
/** A size with a single candidate shows it until chosen otherwise; several start unselected. */
|
||||
export function defaultStabilizerSelection(size: Size): string[] {
|
||||
const candidates = stabilizerCandidates(size);
|
||||
return candidates.length === 1 ? [candidates[0]!.id] : [];
|
||||
}
|
||||
/** Mount points in key-local coordinates, around the (w, h) rectangle's center, not the switch. */
|
||||
export function stabilizerPoints(size: Size, ids: string[]): Point[] {
|
||||
const cx = size.w / 2,
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import type { KeyNode, Node, PhyFile, Transform } from "../../domain/phy";
|
||||
import type { ProjectFile } from "../../domain/project";
|
||||
import {
|
||||
defaultStabilizerSelection,
|
||||
stabilizerCandidates,
|
||||
stabilizerPoints,
|
||||
switchPoint,
|
||||
} from "../../domain/stabilizers";
|
||||
import { stabilizerCandidates, stabilizerPoints, switchPoint } from "../../domain/stabilizers";
|
||||
import { apply, compose, inverse, matrix, type Affine } from "../../domain/geometry";
|
||||
|
||||
export function normalizeSelection(file: PhyFile, ids: string[]): string[] {
|
||||
@@ -337,10 +332,9 @@ export function stabilizerSelections(project: ProjectFile): StabilizerSelections
|
||||
const ui = project.ui as { phy?: { stabilizers?: StabilizerSelections } } | undefined;
|
||||
return ui?.phy?.stabilizers ?? {};
|
||||
}
|
||||
/** 記録がなければサイズの既定。サイズが変わって候補にない記録は捨てて読む。 */
|
||||
/** 記録がなければ何も選ばない。サイズが変わって候補にない記録は捨てて読む。 */
|
||||
export function selectedStabilizers(selections: StabilizerSelections, key: KeyNode): string[] {
|
||||
const ids = selections[key.id];
|
||||
if (!ids) return defaultStabilizerSelection(key.size);
|
||||
const ids = selections[key.id] ?? [];
|
||||
const known = new Set(stabilizerCandidates(key.size).map((c) => c.id));
|
||||
return ids.filter((id) => known.has(id));
|
||||
}
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
defaultStabilizerSelection,
|
||||
stabilizerCandidates,
|
||||
stabilizerPoints,
|
||||
switchPoint,
|
||||
} from "../src/domain/stabilizers";
|
||||
import { stabilizerCandidates, stabilizerPoints, switchPoint } from "../src/domain/stabilizers";
|
||||
import { mountMarks, selectedStabilizers, stabilizerSelections, withStabilizers } from "../src/ui/phy/logic";
|
||||
import type { KeyNode } from "../src/domain/phy";
|
||||
import type { ProjectFile } from "../src/domain/project";
|
||||
@@ -34,10 +29,6 @@ describe("stabilizer candidates", () => {
|
||||
expect(stabilizerCandidates({ w: 1.25, h: 2, w2: 1.5, h2: 1, x2: -0.25 })).toEqual([]);
|
||||
expect(stabilizerCandidates({ w: 2, h: 1, w2: 2.25 })).toEqual([]);
|
||||
});
|
||||
it("selects a lone candidate by default and nothing when there are several", () => {
|
||||
expect(defaultStabilizerSelection({ w: 2, h: 1 })).toEqual(["11.938mm"]);
|
||||
expect(defaultStabilizerSelection({ w: 6.25, h: 1 })).toEqual([]);
|
||||
});
|
||||
it("places mounts around the rectangle center along the long axis", () => {
|
||||
expect(stabilizerPoints({ w: 7, h: 1 }, ["3u"])).toEqual([
|
||||
{ x: 0.5, y: 0.5 },
|
||||
@@ -57,9 +48,9 @@ describe("stabilizer candidates", () => {
|
||||
|
||||
describe("stabilizer selections in ProjectFile.ui", () => {
|
||||
const project = { ui: { other: 1 } } as unknown as ProjectFile;
|
||||
it("falls back to the size default and drops ids the size no longer offers", () => {
|
||||
expect(selectedStabilizers({}, key("a", 2))).toEqual(["11.938mm"]);
|
||||
expect(selectedStabilizers({ a: [] }, key("a", 2))).toEqual([]);
|
||||
it("selects nothing by default and drops ids the size no longer offers", () => {
|
||||
expect(selectedStabilizers({}, key("a", 2))).toEqual([]);
|
||||
expect(selectedStabilizers({ a: ["11.938mm"] }, key("a", 2))).toEqual(["11.938mm"]);
|
||||
expect(selectedStabilizers({ a: ["2.5u", "3u"] }, key("a", 6))).toEqual(["2.5u"]);
|
||||
});
|
||||
it("writes per key without touching other ui state", () => {
|
||||
@@ -86,7 +77,7 @@ describe("stabilizer selections in ProjectFile.ui", () => {
|
||||
},
|
||||
],
|
||||
{ g: "v2" },
|
||||
{},
|
||||
{ a: ["11.938mm"] },
|
||||
);
|
||||
expect(marks.map((m) => m.id)).toEqual(["a", "c"]);
|
||||
expect(marks[1]!.transform.f).toBe(1);
|
||||
|
||||
@@ -96,7 +96,7 @@ T-29 のコードを作り直さず、[phy-editor-feedback.md](phy-editor-feedba
|
||||
|
||||
スタビ位置はキーのサイズで候補を引き、キーごとに候補を複数選べる。何も選ばなくてもよい。
|
||||
選んだ候補はプロジェクトファイルの `ui` にキーIDごとに持ち、PHYには入れない(いずれPHYへ移す)。
|
||||
候補が1つのサイズは、その候補を選んだ状態で表示する。候補が複数のサイズは、何も選ばない状態から始める。
|
||||
どのサイズも、何も選ばない状態から始める。
|
||||
候補を選んでも `switchOffset` は変えない。`switchOffset` は手で入れる。
|
||||
|
||||
候補は、キーの (w,h) 矩形の中心から±の位置に置く2点で表す(1U = 19.05mm)。縦長のキーは長辺の向きに置く。
|
||||
|
||||
Reference in New Issue
Block a user