mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
Turns the desktop from a fixed set of hand-drawn panels into a real
environment applications can be written against.
SUB-WT immediate-mode toolkit (gui/gui_widgets.c):
Buttons, labels, checkboxes, radios, sliders, list boxes, text fields, tab
bars, scrollbars, progress bars, sparklines and badges. An app feeds the WM
event into the toolkit and then calls widgets from its paint routine, so
each call both draws the control and reports what the user did with it --
no retained widget tree to keep in sync with window state.
Icons and dialogs:
gui_icons.c holds 14 16x16 palette-indexed glyphs stored as hex text, so the
art stays hand-editable and picks up theme changes for free; they scale by
integer factors and can be drawn as tint stencils. gui_dialog.c adds modal
info/warning/error/confirm dialogs that dim the desktop, take exclusive
input, word-wrap on spaces and report results through a callback.
Applications (gui/gui_apps_ext.c):
Settings (tabbed appearance/input/power), Task Manager (live process table
over task_find_by_pid with memory and heap gauges), Kernel Log viewer (reads
the dmesg ring, strips ANSI, colours by severity, scrolls), KTest Runner
(drives the in-kernel suites and reports 21/21 with timing), Clock & Calendar
(Zeller's congruence month grid) and a Text Editor.
Window manager (gui/gui_wm.c):
Minimize/maximize/restore buttons, a corner resize grip, edge snapping, tile
and cascade layouts, F5-F9 shortcuts, title truncation, and index-based
enumeration so the taskbar no longer assumes window ids stay dense.
Desktop shell (gui/gui_desktop.c):
Launcher icon grid, richer start menu, right-click context menu, taskbar
buttons that minimize and restore, and a live CPU trace in the tray.
Two interaction bugs fixed along the way:
- keyboard_get_key() blocks until a key arrives, so calling it every frame
froze the compositor; it is now gated on keyboard_has_key(), and stale
console input is drained before the first frame.
- When the desktop consumed a click, the WM's press-edge detector kept the
pre-press state and read the still-held button as a fresh press on the
next frame, stealing focus from whatever the click had just opened.
gui_wm_sync_button_state() keeps the two layers in step.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP
87 lines
3.7 KiB
C
87 lines
3.7 KiB
C
#ifndef _GUI_WIDGETS_H
|
|
#define _GUI_WIDGETS_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <gui/gui_wm.h>
|
|
#include <gui/gui_gfx.h>
|
|
#include <gui/gui_theme.h>
|
|
|
|
// SUB-WT: immediate-mode widget toolkit for SUB-OS desktop applications.
|
|
//
|
|
// An app feeds the toolkit whatever event the window manager delivered
|
|
// (gui_widget_feed_event) and then simply calls widget functions from inside
|
|
// its paint routine. Each call both draws the control and reports what the
|
|
// user did with it, so no retained widget tree has to be kept in sync with
|
|
// the window's state.
|
|
//
|
|
// static void my_paint(gui_window_t* win) {
|
|
// gui_widget_begin(win);
|
|
// if (gui_button(1, 10, 10, 90, 24, "Refresh")) do_refresh();
|
|
// gui_checkbox(2, 10, 44, "Verbose", &verbose);
|
|
// gui_widget_end();
|
|
// }
|
|
|
|
#define GUI_FONT_W 8
|
|
#define GUI_FONT_H 8
|
|
#define GUI_FONT16_H 16
|
|
#define GUI_WIDGET_ROW_H 22
|
|
|
|
typedef enum {
|
|
GUI_ALIGN_LEFT,
|
|
GUI_ALIGN_CENTER,
|
|
GUI_ALIGN_RIGHT
|
|
} gui_align_t;
|
|
|
|
// Per-frame input snapshot the widgets consult.
|
|
typedef struct {
|
|
int mouse_x; // Window-relative, client area origin
|
|
int mouse_y;
|
|
bool mouse_down; // Button currently held
|
|
bool mouse_clicked; // Press edge, consumed by the first widget hit
|
|
bool mouse_released;
|
|
uint16_t key; // Pending keystroke, consumed by the focused field
|
|
int hot_id; // Widget under the cursor this frame
|
|
int active_id; // Widget holding the press
|
|
int focus_id; // Widget receiving keystrokes
|
|
} gui_widget_input_t;
|
|
|
|
// Called from an app's handle_event to record what the WM delivered.
|
|
void gui_widget_feed_event(gui_window_t* win, const gui_event_t* ev);
|
|
|
|
// Frame scope. Everything between these two is drawn in client-area
|
|
// coordinates: (0,0) is the top-left pixel below the title bar.
|
|
void gui_widget_begin(gui_window_t* win);
|
|
void gui_widget_end(void);
|
|
|
|
const gui_widget_input_t* gui_widget_get_input(void);
|
|
void gui_widget_set_focus(int id);
|
|
int gui_widget_client_width(void);
|
|
int gui_widget_client_height(void);
|
|
|
|
// --- Static content ---------------------------------------------------------
|
|
void gui_label(int x, int y, const char* text, uint32_t color);
|
|
void gui_label_bold(int x, int y, const char* text, uint32_t color);
|
|
void gui_label_aligned(int x, int y, int w, const char* text, uint32_t color, gui_align_t align);
|
|
void gui_panel(int x, int y, int w, int h, const char* title);
|
|
void gui_separator(int x, int y, int w);
|
|
void gui_progress_bar(int x, int y, int w, int h, int percent, uint32_t fill);
|
|
void gui_sparkline(int x, int y, int w, int h, const uint8_t* samples, int count, uint32_t color);
|
|
void gui_badge(int x, int y, const char* text, uint32_t bg, uint32_t fg);
|
|
|
|
// --- Interactive controls ---------------------------------------------------
|
|
// Every control takes a caller-assigned id that must be unique and stable
|
|
// within one window.
|
|
bool gui_button(int id, int x, int y, int w, int h, const char* label);
|
|
bool gui_button_colored(int id, int x, int y, int w, int h, const char* label, uint32_t accent);
|
|
bool gui_checkbox(int id, int x, int y, const char* label, bool* value);
|
|
bool gui_radio(int id, int x, int y, const char* label, int* selected, int this_value);
|
|
bool gui_slider(int id, int x, int y, int w, int* value, int min_val, int max_val);
|
|
bool gui_listbox(int id, int x, int y, int w, int h, const char* const* items, int count, int* selected);
|
|
bool gui_textfield(int id, int x, int y, int w, char* buffer, size_t capacity);
|
|
int gui_tabbar(int id, int x, int y, int w, const char* const* labels, int count, int* active);
|
|
bool gui_scrollbar(int id, int x, int y, int h, int* offset, int total, int visible);
|
|
|
|
#endif // _GUI_WIDGETS_H
|