feat(spreadsheet): 상태 표시줄 확대 비율 — sub6 zoom() 이음
sub6 격자 확대 커밋(origin/sub_laptop_6 7b294adc) 받아 GridHandle.zoom() 으로 처음 값 · 격자 root 「aislo-grid-zoom」 사건으로 바뀔 때마다 「확대 N%」 다시 씀.
가짜 SpreadsheetContext(test_stage2_helpers.ts) 격자에 zoom() 스텁 더함(0 계약 필수 자리라 안 채우면 모양 안 맞음).
ORCA(포트 5179) — 실제 createSpreadsheet 를 띄워 Ctrl+휠(WheelEvent ctrlKey) 로 확인: 「확대 100%」→「확대 332%」로 실시간 바뀜.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EUypcnp5d1gU2aeKh9F2H7
This commit is contained in:
@@ -2,13 +2,9 @@
|
||||
* spreadsheet_statusbar.ts (3단계 · 주인 sub_laptop_4)
|
||||
* 아래 상태 표시줄 — 고른 범위의 합계 · 평균 · 개수(COUNTA) · 숫자 개수(COUNT) · 최소 · 최대.
|
||||
* 엑셀처럼 우클릭으로 보일 줄 고름(이 표시줄만의 취향 — 문서에는 안 남음 · 계약 손 안 댐).
|
||||
* 확대 비율 자리는 칸만 둠 — 실제 격자 확대와는 아직 안 이어짐(아래 「잇는 법」 2).
|
||||
*
|
||||
* 잇는 법(D · C · sub7 — 지금은 하나도 안 이어짐):
|
||||
* 1) `spreadsheet.ts` 가 `createStatusBar(ctx)` 를 한 번 부르고 `root` 를 화면 맨 아래 붙임.
|
||||
* `ctx.select()` 뒤(그리고 `dispatch` 로 값이 바뀐 뒤) `refresh()` 를 부름 — 스스로 구독 안 함.
|
||||
* 2) 확대 비율을 실제로 쓰려면 `GridHandle` 에 `zoom()` · `setZoom()` 을 계약(0)에 더하고(격자 C 몫),
|
||||
* 이 파일의 확대 자리를 그 값으로 채우고 바꾸면 `setZoom` 을 부르게 이음.
|
||||
* 확대 비율 — `ctx.grid.zoom()` 으로 처음 값 · 격자 root 의 `aislo-grid-zoom` 사건(sub6, 2026-09-27)을
|
||||
* 들어 Ctrl+휠로 바뀔 때마다 다시 씀. `setZoom` 은 아직 계약에 없음(격자만 바꿈 · 상태줄은 읽기만).
|
||||
* 화면 붙이기는 `spreadsheet.ts`(D)가 `createStatusBar(ctx)` 로 이미 함(root 를 격자 아래).
|
||||
* ========================================================================== */
|
||||
|
||||
import { el } from "@ui/ui_template_elements";
|
||||
@@ -76,14 +72,27 @@ function formatNumber(n: number): string {
|
||||
: n.toLocaleString(undefined, { maximumFractionDigits: 4 });
|
||||
}
|
||||
|
||||
function zoomText(ratio: number): string {
|
||||
return `확대 ${Math.round(ratio * 100)}%`;
|
||||
}
|
||||
|
||||
/** 아래 상태 표시줄 — 우클릭 메뉴로 보일 줄 고름. */
|
||||
export function createStatusBar(ctx: SpreadsheetContext): PartHandle {
|
||||
const root = el("div", { className: "ss-statusbar" });
|
||||
const stats = el("div", { className: "ss-statusbar__stats" });
|
||||
const zoom = el("span", { className: "ss-statusbar__zoom", text: "확대 100%" });
|
||||
const zoom = el("span", {
|
||||
className: "ss-statusbar__zoom",
|
||||
text: zoomText(ctx.grid.zoom()),
|
||||
});
|
||||
const menu = createMapContextMenu("ss-statusbar");
|
||||
root.append(stats, zoom, menu.element);
|
||||
|
||||
const onZoom = (ev: Event): void => {
|
||||
const ratio = (ev as CustomEvent<{ zoom: number }>).detail?.zoom;
|
||||
if (typeof ratio === "number") zoom.textContent = zoomText(ratio);
|
||||
};
|
||||
ctx.grid.root.addEventListener("aislo-grid-zoom", onZoom);
|
||||
|
||||
let visible = new Set<StatKey>(STAT_KEYS);
|
||||
|
||||
function render(): void {
|
||||
@@ -115,6 +124,7 @@ export function createStatusBar(ctx: SpreadsheetContext): PartHandle {
|
||||
root,
|
||||
refresh: render,
|
||||
destroy(): void {
|
||||
ctx.grid.root.removeEventListener("aislo-grid-zoom", onZoom);
|
||||
menu.close();
|
||||
root.remove();
|
||||
},
|
||||
|
||||
@@ -142,6 +142,7 @@ export function makeCtx(
|
||||
hitTest: () => null,
|
||||
reveal: () => {},
|
||||
visibleRange: () => ({ r0: 0, c0: 0, r1: 0, c1: 0 }),
|
||||
zoom: () => 1,
|
||||
editorSlot: () => ({ layer: {} as HTMLElement, box: { x: 0, y: 0, w: 0, h: 0 } }),
|
||||
destroy: () => {},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user