fix(B07-CAD): 커서 입력창 글이 칸 안 — 줄 세로 가운데 · 칸 폭 = 가장 긴 줄 · 후보 목록도 바탕 안(97-2)

- 글 중심 = 줄 세로 가운데(옛 칸 아래 변 2px 밑)
- 칸 폭 = max(150, 가장 긴 줄 글 폭 + 여백 8) · measureTextScreen(measureText 감쌈)
- 안내 · 좌표 · 명령 후보(최대 6줄)도 바탕 한 장 안 · 입력 줄 아래 가는 줄
- 그리기 시험: 글 중심 · 12px 글 전체가 칸 안 · 폭 · 최소 폭

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015KYZ2HWWdUwZWYnn3tQz7X
This commit is contained in:
2026-10-08 13:53:24 +09:00
co-authored by Claude Opus 5.5
parent 9f0ab53c53
commit e020cf71aa
3 changed files with 92 additions and 26 deletions
@@ -27,7 +27,13 @@ export function inputFieldColors(read: (name: string, fallback: string) => strin
};
}
/** 입력 글 칸 + 그 아래 안내 · 좌표 · 명령 후보 줄 */
/** 글 좌우 여백(px) */
const INPUT_FIELD_PADDING = 4;
/**
* 입력 글 칸 + 그 아래 안내 · 좌표 · 명령 후보 줄 — 바탕 한 장(명령줄 후보 상자 꼴).
* 줄마다 높이 CANVAS_INPUT_FIELD_HEIGHT · 글 중심 = 줄 세로 가운데 · 폭 = max(최소 폭, 가장 긴 줄 + 여백).
*/
export function drawInputField(
drawController: ScreenCanvasDrawController,
input: string,
@@ -35,33 +41,34 @@ export function drawInputField(
): void {
const mouse = drawController.getScreenMouseLocation();
const colors = inputFieldColors();
const rowHeight = CANVAS_INPUT_FIELD_HEIGHT;
const fontSize = CANVAS_INPUT_FIELD_FONT_SIZE;
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;
// 화면 좌표는 위가 + — 칸 위 변이 커서 아래 OFFSET · fillRectScreen 의 y 는 아래 변
const top = mouse.y - CANVAS_INPUT_FIELD_MOUSE_OFFSET;
const height = rowHeight * (1 + lines.length);
const textWidth = Math.max(
0,
...[input, ...lines].map((text) => drawController.measureTextScreen(text, fontSize))
);
const width = Math.max(CANVAS_INPUT_FIELD_WIDTH, Math.ceil(textWidth) + INPUT_FIELD_PADDING * 2);
drawController.fillRectScreen(
left - 1,
bottom - 1,
top - height - 1,
width + 2,
CANVAS_INPUT_FIELD_HEIGHT + 2,
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,
};
drawController.fillRectScreen(left, top - height, width, height, colors.background, true);
if (lines.length) {
// 입력 줄과 목록 사이 가는 줄
drawController.fillRectScreen(left, top - rowHeight, width, 1, colors.border, true);
}
const textOptions = { textAlign: 'left' as const, fontSize, rawColor: true };
const rowCenter = (row: number) => top - rowHeight * row - rowHeight / 2;
if (input) {
drawController.drawTextScreen(input, new Point(left + 2, bottom - 2), {
drawController.drawTextScreen(input, new Point(left + INPUT_FIELD_PADDING, rowCenter(0)), {
...textOptions,
textColor: colors.text,
});
@@ -69,11 +76,11 @@ export function drawInputField(
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 }
new Point(left + INPUT_FIELD_PADDING, rowCenter(index + 1)),
{
...textOptions,
textColor: colors.dimText,
}
);
});
}