c0dd1621e6
Вынос подсистем из mdview2.c в отдельные C-модули для читаемости и навигации. mdview2.c: 2740 → 1062 строк (-61%); ядро теперь чистая инфраструктура (cache-пул, EMM/fb, загрузка файла, doc-slot, loading-loop, build_doc, main). Модули (через EXTRA_SRCS, общий интерфейс в mdview2.h): - mdview2_help.c — диалог справки F1 - mdview2_table.c — выровненная отрисовка таблиц - mdview2_enc.c — кодировки CP866/CP1251/KOI8R + UTF-8 конвертер - mdview2_view.c — отрисовка области/статус-бара/меню + прокрутка - mdview2_index.c — парсер/индексатор markdown (сердце приложения) (mdview2_raw.c был выделен ранее) Чистый перенос static→extern; приватное состояние подсистем осталось приватным. Размер: exe 28090 → 28112 (+22 Б / +0.08% — codegen-шум на двух сильно связанных модулях enc/index). Сборка чистая, smoke-тест ОК. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
103 lines
5.9 KiB
C
103 lines
5.9 KiB
C
/*
|
|
* mdview2_help.c — диалог справки (F1).
|
|
*
|
|
* Модальное окно поверх документа: рамка с заголовком, список горячих
|
|
* клавиш и поддерживаемых markdown-элементов. Блокирует до нажатия любой
|
|
* клавиши, после чего восстанавливает статус-бар, область документа и меню.
|
|
*
|
|
* Зависимости от ядра (mdview2.c): render_full_status / draw_viewport_from_cache
|
|
* / render_menu для восстановления экрана. Текст справки — в CP866.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <conio.h>
|
|
#include <bios/text.h>
|
|
#include "mdview2.h"
|
|
|
|
/* Геометрия диалога справки (в символьных координатах 80×32). */
|
|
#define HELP_X 8u /* левая граница рамки */
|
|
#define HELP_Y 4u /* верхняя граница рамки */
|
|
#define HELP_W 64u /* ширина рамки (включая │) */
|
|
#define HELP_H 26u /* высота рамки (включая ─) */
|
|
|
|
/* Заполняет одну внутреннюю строку диалога (r=0 — первая строка за рамкой).
|
|
* Строка s в кодировке CP866; остаток до края дополняется пробелами. */
|
|
static void help_line(uint8_t r, const char *s, uint8_t attr)
|
|
{
|
|
uint8_t x = HELP_X + 1u;
|
|
uint8_t y = HELP_Y + 1u + r;
|
|
uint8_t len = (uint8_t)strlen(s);
|
|
if (len > HELP_W - 2u) len = HELP_W - 2u;
|
|
|
|
bios_set_place(y, x);
|
|
if (len > 0) bios_writeattr(s, len, attr);
|
|
/* place уже продвинут bios_writeattr на len колонок (verified). */
|
|
if (len < HELP_W - 2u) {
|
|
bios_fillcharattr(' ', ATTR_HELP_BG, (uint8_t)(HELP_W - 2u - len));
|
|
}
|
|
}
|
|
|
|
void show_help(void)
|
|
{
|
|
/* " Помощь " в CP866 (8 байт) */
|
|
static const char title[] = " \x8F\xAE\xAC\xAE\xE9\xEC ";
|
|
uint8_t tlen = 8u;
|
|
uint8_t lft = (uint8_t)((HELP_W - 2u - tlen) / 2u); /* = 27 */
|
|
uint8_t rgt = (uint8_t)(HELP_W - 2u - tlen - lft);
|
|
/* Верхняя граница рамки с заголовком по центру.
|
|
* place продвигается каждым BIOS-вызовом (verified), поэтому
|
|
* достаточно одной установки места на всю строку рамки. */
|
|
wrchar(HELP_X, HELP_Y, 0xDA, ATTR_HELP_BDR); /* ┌ */
|
|
bios_set_place(HELP_Y, (uint8_t)(HELP_X + 1u));
|
|
if (lft > 0) bios_fillcharattr(0xC4, ATTR_HELP_BDR, lft);
|
|
if (tlen > 0) bios_writeattr(title, tlen, ATTR_HELP_TIT);
|
|
if (rgt > 0) bios_fillcharattr(0xC4, ATTR_HELP_BDR, rgt);
|
|
wrchar(HELP_X + HELP_W - 1u, HELP_Y, 0xBF, ATTR_HELP_BDR); /* ┐ */
|
|
|
|
/* Боковые границы (левый и правый │ для каждой строки тела) */
|
|
for (uint8_t r = 1u; r < HELP_H - 1u; r++) {
|
|
wrchar(HELP_X, HELP_Y + r, 0xB3, ATTR_HELP_BDR); /* │ */
|
|
wrchar(HELP_X + HELP_W - 1u, HELP_Y + r, 0xB3, ATTR_HELP_BDR); /* │ */
|
|
}
|
|
|
|
/* Нижняя граница рамки */
|
|
wrchar(HELP_X, HELP_Y + HELP_H - 1u, 0xC0, ATTR_HELP_BDR); /* └ */
|
|
bios_set_place((uint8_t)(HELP_Y + HELP_H - 1u), (uint8_t)(HELP_X + 1u));
|
|
bios_fillcharattr(0xC4, ATTR_HELP_BDR, (uint8_t)(HELP_W - 2u));
|
|
wrchar(HELP_X + HELP_W - 1u, HELP_Y + HELP_H - 1u, 0xD9, ATTR_HELP_BDR); /* ┘ */
|
|
|
|
/* Содержимое (20 внутренних строк) */
|
|
uint8_t r = 0;
|
|
help_line(r++, "", ATTR_HELP_BG);
|
|
help_line(r++, " MDView v0.2 -- Markdown Viewer for Sprinter", ATTR_HELP_HDR);
|
|
help_line(r++, " (c) 2026 Petrov A.G.", ATTR_HELP_BG);
|
|
help_line(r++, "", ATTR_HELP_BG);
|
|
help_line(r++, " Navigation:", ATTR_HELP_HDR);
|
|
help_line(r++, " \x18 \x19 Scroll one line up / down", ATTR_HELP_BG);
|
|
help_line(r++, " PgUp PgDn Scroll one page up / down", ATTR_HELP_BG);
|
|
help_line(r++, " Home End Jump to beginning / end of document", ATTR_HELP_BG);
|
|
help_line(r++, " \x1B \x1A Horizontal pan (code blocks/tables)", ATTR_HELP_BG);
|
|
help_line(r++, " Esc F10 Exit", ATTR_HELP_BG);
|
|
help_line(r++, "", ATTR_HELP_BG);
|
|
help_line(r++, " Markdown elements:", ATTR_HELP_HDR);
|
|
help_line(r++, " # ## ### Headings H1-H6", ATTR_HELP_BG);
|
|
help_line(r++, " **bold** *italic* `code` ~~strike~~", ATTR_HELP_BG);
|
|
help_line(r++, " > quote ``` ... ``` Fenced code block", ATTR_HELP_BG);
|
|
help_line(r++, " - * + item 1. 2. Ordered list", ATTR_HELP_BG);
|
|
help_line(r++, " |----|----| Tables", ATTR_HELP_BG);
|
|
help_line(r++, "", ATTR_HELP_BG);
|
|
help_line(r++, " Encoding:", ATTR_HELP_HDR);
|
|
help_line(r++, " F8 Cycle CP866 / CP1251 / KOI8-R / UTF-8", ATTR_HELP_BG);
|
|
help_line(r++, " Auto-detected on open; F8 to override", ATTR_HELP_BG);
|
|
help_line(r++, "", ATTR_HELP_BG);
|
|
help_line(r++, " File size: up to 128 KB (EMM). Lines: up to 16384.", ATTR_HELP_BG);
|
|
help_line(r++, "", ATTR_HELP_BG);
|
|
|
|
(void)getkey();
|
|
|
|
render_full_status();
|
|
draw_viewport_from_cache();
|
|
render_menu();
|
|
}
|