/* * wikipedia.h * Shared header for the MontaukOS Wikipedia GUI client * Copyright (c) 2026 Daniel Hammer */ #pragma once #include #include #include #include #include #include #include #include #include extern "C" { #include #include #include } using namespace gui; using namespace gui::colors; // ============================================================================ // Constants // ============================================================================ static constexpr int INIT_W = 820; static constexpr int INIT_H = 580; static constexpr int SCROLLBAR_W = mtk::SCROLLBAR_W; static constexpr int TEXT_PAD = 16; static constexpr int RESP_MAX = 131072; static constexpr int MAX_LINES = 2000; inline const char WIKI_HOST[] = "en.wikipedia.org"; inline const char DISPLAY_ICON_PATH[] = "0:/os/icons/cog.svg"; // ============================================================================ // Types // ============================================================================ struct WikiLine { char text[256]; Color color; int font_size; TrueTypeFont* font; int indent; }; enum class AppPhase { WELCOME, IDLE, LOADING, DONE, ERR }; enum class ReaderTextSize : uint8_t { SMALL = 0, MEDIUM, LARGE, COUNT }; enum class ReaderFontFace : uint8_t { SANS = 0, SERIF, BOOK, COUNT }; struct ReaderPalette { Color page_bg; Color control_bg; Color toolbar_bg; Color border; Color text; Color heading; Color muted; Color accent; Color accent_hover; Color accent_soft; Color danger; Color danger_hover; Color disabled_bg; Color disabled_fg; }; struct ReaderToolbarLayout { Rect search_field; Rect display_button; Rect search_button; Rect text_size_buttons[(int)ReaderTextSize::COUNT]; Rect font_buttons[(int)ReaderFontFace::COUNT]; Rect text_size_label; Rect font_face_label; int sep_x; bool show_labels; }; static constexpr int READER_TEXT_SIZE_COUNT = (int)ReaderTextSize::COUNT; static constexpr int READER_FONT_FACE_COUNT = (int)ReaderFontFace::COUNT; // ============================================================================ // Global state (extern -- defined in state.cpp) // ============================================================================ extern int TOOLBAR_H; extern int FONT_SIZE; extern int TITLE_SIZE; extern int SECTION_SIZE; extern AppPhase g_phase; extern char g_query[256]; extern mtk::TextInputState g_query_input; extern char g_status[256]; extern int g_scroll_y; extern int g_line_count; extern int g_line_h; extern int g_win_w; extern int g_win_h; extern int g_mouse_x; extern int g_mouse_y; extern bool g_search_focused; extern bool g_scroll_dragging; extern int g_scroll_drag_offset; extern bool g_display_controls_open; extern ReaderTextSize g_reader_text_size; extern ReaderFontFace g_reader_font_face; extern char g_title[512]; extern int g_extract_len; extern int g_base_font_size; extern int g_base_title_size; extern int g_base_section_size; extern Color g_accent; extern bool g_welcome_feature_loaded; extern char g_welcome_feature_title[256]; extern char g_welcome_feature_extract[1024]; extern char g_welcome_status[192]; extern char g_welcome_date[16]; extern WikiLine* g_lines; extern char* g_resp_buf; extern char* g_extract_buf; extern TrueTypeFont* g_font; extern TrueTypeFont* g_font_serif; extern TrueTypeFont* g_body_fonts[READER_FONT_FACE_COUNT]; extern TrueTypeFont* g_heading_fonts[READER_FONT_FACE_COUNT]; extern SvgIcon g_display_icon; extern SvgIcon g_display_icon_active; extern bool g_tls_ready; extern uint32_t g_server_ip; extern tls::TrustAnchors g_tas; extern const char* g_text_size_labels[READER_TEXT_SIZE_COUNT]; extern const char* g_font_face_labels[READER_FONT_FACE_COUNT]; // ============================================================================ // theme.cpp -- palette, theme, layout, scaling // ============================================================================ ReaderPalette reader_palette(); mtk::Theme wiki_theme(); TrueTypeFont* current_body_font(); TrueTypeFont* current_heading_font(); void apply_reader_preferences(); void apply_scale(int scale); void update_toolbar_height(); void reload_display_icons(); int search_control_h(); int reader_button_h(); int display_toggle_icon_size(); int display_toggle_button_w(); int search_row_y(); int reader_row_y(); ReaderToolbarLayout toolbar_layout(); Rect content_rect(); Rect article_column_rect(); Rect document_column_rect(); Rect search_button_rect(); Rect search_field_rect(); Rect scrollbar_track_rect(); Rect scrollbar_thumb_rect(); int visible_line_count(); int max_scroll_lines(); bool document_scrollable(); void clamp_scroll(); bool mouse_in_rect(const Rect& rect); void set_scroll_from_thumb_top(int thumb_top); int document_top_pad(); // ============================================================================ // text.cpp -- encoding, HTTP/URL/JSON parsing // ============================================================================ int encode_single_byte_codepoint(unsigned codepoint); void append_codepoint(char* out, int* j, int maxOut, unsigned codepoint); void underscores_to_spaces(char* text); bool is_main_page_query(const char* query); unsigned decode_utf8_codepoint(const char* buf, int len, int* consumed); int find_substr(const char* buf, int len, const char* needle); int url_encode_title(const char* in, char* out, int maxLen); int extract_json_string(const char* buf, int len, const char* key, char* out, int maxOut); // ============================================================================ // document.cpp -- display line building // ============================================================================ void add_line(const char* text, int len, Color color, int size, TrueTypeFont* font, int indent = 0); void add_spacer(int size); void wrap_text(TrueTypeFont* font, int size, const char* text, int textLen, int max_px, Color color, int indent = 0); void build_display_lines(const char* title, const char* extract, int extractLen, bool preserve_scroll = false); void build_welcome_lines(bool preserve_scroll = false); void rebuild_current_document(bool preserve_scroll = true); void apply_reader_setting_change(); bool handle_reader_option_click(int mx, int my); // ============================================================================ // network.cpp -- TLS fetch, welcome fetch, search // ============================================================================ http::Response wiki_fetch(const char* path, char* respBuf, int respMax); bool ensure_wiki_tls_ready(char* err, int err_len); bool welcome_feed_path(char* path, int path_len); void do_welcome_fetch(); void do_search(const char* query); // ============================================================================ // render.cpp -- drawing // ============================================================================ void draw_display_toggle_button(Canvas& canvas, const Rect& bounds, const mtk::WidgetState& state, const mtk::Theme& theme); void render_message(Canvas& canvas, const Rect& content, const char* text, Color color); void render(Canvas& canvas);