236 lines
7.8 KiB
C++
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);
|