Files
MontaukOS/programs/src/wikipedia/wikipedia.h
T

236 lines
7.8 KiB
C++

/*
* wikipedia.h
* Shared header for the MontaukOS Wikipedia GUI client
* Copyright (c) 2026 Daniel Hammer
*/
#pragma once
#include <montauk/syscall.h>
#include <montauk/string.h>
#include <montauk/heap.h>
#include <gui/mtk.hpp>
#include <gui/mtk/settings.hpp>
#include <gui/standalone.hpp>
#include <gui/svg.hpp>
#include <gui/truetype.hpp>
#include <http/http.hpp>
extern "C" {
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
}
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);