fix(B07-CAD): 커서 입력창 칸 · 글 색이 테마를 따름 — 자동색 뒤집기 건너뜀(97-1)
- 칸 = --cad-chrome-raised(밝음 흰 칸 + --cad-line 테두리 · 어두움 #251f38) · 글 = --cad-text · 안내 = --cad-text-dim - fillRectScreen · drawTextScreen 에 paintColor 건너뛰는 rawColor 선택 인자 - 입력창 그리기를 inputController/input-field-draw.ts 로 · 전체 맞춤 계산을 drawControllers/fit-view.ts 로(700줄) - App.consts 입력창 색 상수 = 토큰 폴백 · 틀린 주석 고침 - 시험 theme-auto-color: 칸 · 글 색이 두 테마 모두 다름 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KYZ2HWWdUwZWYnn3tQz7X
This commit is contained in:
@@ -2,13 +2,6 @@ import { Point } from '@flatten-js/core';
|
||||
import { compact, round } from 'es-toolkit';
|
||||
import { Actor } from 'xstate';
|
||||
import {
|
||||
CANVAS_INPUT_FIELD_BACKGROUND_COLOR,
|
||||
CANVAS_INPUT_FIELD_FONT_SIZE,
|
||||
CANVAS_INPUT_FIELD_HEIGHT,
|
||||
CANVAS_INPUT_FIELD_INSTRUCTION_TEXT_COLOR,
|
||||
CANVAS_INPUT_FIELD_MOUSE_OFFSET,
|
||||
CANVAS_INPUT_FIELD_TEXT_COLOR,
|
||||
CANVAS_INPUT_FIELD_WIDTH,
|
||||
PINCH_ZOOM_EXPONENT,
|
||||
SNAP_POINT_DISTANCE,
|
||||
WHEEL_LINE_PX,
|
||||
@@ -66,6 +59,7 @@ import {
|
||||
type TextInputEvent,
|
||||
} from '../tools/tool.types.ts';
|
||||
import { activeToolAcceptsText, ImeSink, isImeKey } from './ime-sink.ts';
|
||||
import { drawInputField } from './input-field-draw.ts';
|
||||
import {
|
||||
ABSOLUTE_POINT_REGEXP,
|
||||
ABSOLUTE_POLAR_REGEXP,
|
||||
@@ -127,36 +121,7 @@ export class InputController {
|
||||
}
|
||||
|
||||
public draw(drawController: ScreenCanvasDrawController) {
|
||||
const screenMouseLocation = drawController.getScreenMouseLocation();
|
||||
|
||||
// draw input field
|
||||
drawController.fillRectScreen(
|
||||
screenMouseLocation.x + CANVAS_INPUT_FIELD_MOUSE_OFFSET,
|
||||
// fillRectScreen이 아래 변 기준으로 바로잡혔으므로, 칸이 있던 자리를 지키려고
|
||||
// 높이만큼 내려 잡는다.
|
||||
screenMouseLocation.y - CANVAS_INPUT_FIELD_MOUSE_OFFSET - CANVAS_INPUT_FIELD_HEIGHT,
|
||||
CANVAS_INPUT_FIELD_WIDTH,
|
||||
CANVAS_INPUT_FIELD_HEIGHT,
|
||||
CANVAS_INPUT_FIELD_BACKGROUND_COLOR
|
||||
);
|
||||
this.ime.sync(activeToolAcceptsText());
|
||||
// Draw text in input field (조합 중인 한글도 함께)
|
||||
if (this.text || this.ime.composing) {
|
||||
drawController.drawTextScreen(
|
||||
this.text + this.ime.composing,
|
||||
new Point(
|
||||
screenMouseLocation.x + CANVAS_INPUT_FIELD_MOUSE_OFFSET + 2,
|
||||
screenMouseLocation.y - CANVAS_INPUT_FIELD_MOUSE_OFFSET - CANVAS_INPUT_FIELD_HEIGHT - 2
|
||||
),
|
||||
{
|
||||
textAlign: 'left',
|
||||
textColor: CANVAS_INPUT_FIELD_TEXT_COLOR,
|
||||
fontSize: CANVAS_INPUT_FIELD_FONT_SIZE,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const matchingCommands = this.getCommandSuggestions();
|
||||
const toolInstruction = getLastStateInstructions();
|
||||
const texts: string[] = [];
|
||||
if (toolInstruction) {
|
||||
@@ -166,11 +131,10 @@ export class InputController {
|
||||
const roundedY = round(drawController.getWorldMouseLocation().y, 2);
|
||||
texts.push(`${roundedX},${roundedY}`);
|
||||
}
|
||||
if (matchingCommands.length) {
|
||||
// 입력 중인 문자로 시작하는 명령 후보. 예: C => CIRCLE (C), COPY (CO)
|
||||
texts.push(...matchingCommands);
|
||||
}
|
||||
this.drawListBelowInputField(drawController, texts);
|
||||
// 입력 중인 문자로 시작하는 명령 후보. 예: C => CIRCLE (C), COPY (CO)
|
||||
texts.push(...this.getCommandSuggestions());
|
||||
// 입력 글(조합 중인 한글도 함께)
|
||||
drawInputField(drawController, this.text + this.ime.composing, texts);
|
||||
}
|
||||
|
||||
public submitText(value: string) {
|
||||
@@ -661,32 +625,6 @@ export class InputController {
|
||||
type: ActorEvent.ESC,
|
||||
});
|
||||
}
|
||||
|
||||
private drawListBelowInputField(
|
||||
drawController: ScreenCanvasDrawController,
|
||||
texts: string[]
|
||||
): void {
|
||||
const screenMouseLocation = drawController.worldToTarget(
|
||||
drawController.getWorldMouseLocation()
|
||||
);
|
||||
const startY =
|
||||
screenMouseLocation.y - CANVAS_INPUT_FIELD_MOUSE_OFFSET - CANVAS_INPUT_FIELD_HEIGHT * 2 - 2;
|
||||
const offsetY = CANVAS_INPUT_FIELD_HEIGHT;
|
||||
texts.forEach((text, index) => {
|
||||
drawController.drawTextScreen(
|
||||
text,
|
||||
new Point(
|
||||
screenMouseLocation.x + CANVAS_INPUT_FIELD_MOUSE_OFFSET + 2,
|
||||
startY - index * offsetY
|
||||
),
|
||||
{
|
||||
textAlign: 'left',
|
||||
textColor: CANVAS_INPUT_FIELD_INSTRUCTION_TEXT_COLOR,
|
||||
fontSize: CANVAS_INPUT_FIELD_FONT_SIZE,
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* 커서 따라다니는 입력창 — 캔버스에 직접 그림(`input-controller.ts` draw 가 부름).
|
||||
* 칸 · 글은 테마 토큰 색을 그대로 칠함(자동색 뒤집기 건너뜀) — 명령줄 후보 상자(`App.css`
|
||||
* `.cad-command-suggestions`)와 같은 색.
|
||||
*/
|
||||
import { Point } from '@flatten-js/core';
|
||||
import {
|
||||
CANVAS_INPUT_FIELD_BACKGROUND_COLOR,
|
||||
CANVAS_INPUT_FIELD_BORDER_COLOR,
|
||||
CANVAS_INPUT_FIELD_FONT_SIZE,
|
||||
CANVAS_INPUT_FIELD_HEIGHT,
|
||||
CANVAS_INPUT_FIELD_INSTRUCTION_TEXT_COLOR,
|
||||
CANVAS_INPUT_FIELD_MOUSE_OFFSET,
|
||||
CANVAS_INPUT_FIELD_TEXT_COLOR,
|
||||
CANVAS_INPUT_FIELD_WIDTH,
|
||||
} from '../App.consts.ts';
|
||||
import type { ScreenCanvasDrawController } from '../drawControllers/screenCanvas.drawController.ts';
|
||||
import { themeColor } from '../theme.ts';
|
||||
|
||||
/** 입력창 색 — 밝음 = 흰 칸 + 테두리 · 어두움 = 짙은 보라 칸 · 글 = CAD 글 색 */
|
||||
export function inputFieldColors(read: (name: string, fallback: string) => string = themeColor) {
|
||||
return {
|
||||
background: read('--cad-chrome-raised', CANVAS_INPUT_FIELD_BACKGROUND_COLOR),
|
||||
border: read('--cad-line', CANVAS_INPUT_FIELD_BORDER_COLOR),
|
||||
text: read('--cad-text', CANVAS_INPUT_FIELD_TEXT_COLOR),
|
||||
dimText: read('--cad-text-dim', CANVAS_INPUT_FIELD_INSTRUCTION_TEXT_COLOR),
|
||||
};
|
||||
}
|
||||
|
||||
/** 입력 글 칸 + 그 아래 안내 · 좌표 · 명령 후보 줄 */
|
||||
export function drawInputField(
|
||||
drawController: ScreenCanvasDrawController,
|
||||
input: string,
|
||||
lines: string[]
|
||||
): void {
|
||||
const mouse = drawController.getScreenMouseLocation();
|
||||
const colors = inputFieldColors();
|
||||
const left = mouse.x + CANVAS_INPUT_FIELD_MOUSE_OFFSET;
|
||||
// 화면 좌표는 위가 + — fillRectScreen 의 y 는 칸 아래 변
|
||||
const bottom = mouse.y - CANVAS_INPUT_FIELD_MOUSE_OFFSET - CANVAS_INPUT_FIELD_HEIGHT;
|
||||
const width = CANVAS_INPUT_FIELD_WIDTH;
|
||||
drawController.fillRectScreen(
|
||||
left - 1,
|
||||
bottom - 1,
|
||||
width + 2,
|
||||
CANVAS_INPUT_FIELD_HEIGHT + 2,
|
||||
colors.border,
|
||||
true
|
||||
);
|
||||
drawController.fillRectScreen(
|
||||
left,
|
||||
bottom,
|
||||
width,
|
||||
CANVAS_INPUT_FIELD_HEIGHT,
|
||||
colors.background,
|
||||
true
|
||||
);
|
||||
const textOptions = {
|
||||
textAlign: 'left' as const,
|
||||
fontSize: CANVAS_INPUT_FIELD_FONT_SIZE,
|
||||
rawColor: true,
|
||||
};
|
||||
if (input) {
|
||||
drawController.drawTextScreen(input, new Point(left + 2, bottom - 2), {
|
||||
...textOptions,
|
||||
textColor: colors.text,
|
||||
});
|
||||
}
|
||||
lines.forEach((line, index) => {
|
||||
drawController.drawTextScreen(
|
||||
line,
|
||||
new Point(
|
||||
left + 2,
|
||||
bottom - CANVAS_INPUT_FIELD_HEIGHT - 2 - index * CANVAS_INPUT_FIELD_HEIGHT
|
||||
),
|
||||
{ ...textOptions, textColor: colors.dimText }
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user