mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
feat(gui): Add SUB-WT widget toolkit, icon set, modal dialogs, six apps and a reworked window manager
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
This commit is contained in:
1 parent
ed8922c498
commit
1aee7c7a0d
16 files changed
+3248
-335
No files matched your search
+59
-12
@@ -7,8 +7,11 @@
|
||||
#include <gui/gui_gfx.h>
|
||||
#include <gui/gui_theme.h>
|
||||
|
||||
#define GUI_MAX_WINDOWS 16
|
||||
#define GUI_TITLEBAR_HEIGHT 24
|
||||
#define GUI_MAX_WINDOWS 16
|
||||
#define GUI_TITLEBAR_HEIGHT 24
|
||||
#define GUI_RESIZE_GRIP 12
|
||||
#define GUI_MIN_WINDOW_W 160
|
||||
#define GUI_MIN_WINDOW_H 100
|
||||
|
||||
typedef enum {
|
||||
GUI_EVENT_MOUSE_MOVE,
|
||||
@@ -16,6 +19,7 @@ typedef enum {
|
||||
GUI_EVENT_MOUSE_UP,
|
||||
GUI_EVENT_KEY_DOWN,
|
||||
GUI_EVENT_FOCUS,
|
||||
GUI_EVENT_RESIZE,
|
||||
GUI_EVENT_CLOSE
|
||||
} gui_event_type_t;
|
||||
|
||||
@@ -30,19 +34,40 @@ typedef struct {
|
||||
uint16_t key;
|
||||
} gui_event_t;
|
||||
|
||||
// Where a window sits relative to the screen edges.
|
||||
typedef enum {
|
||||
GUI_SNAP_NONE = 0,
|
||||
GUI_SNAP_LEFT,
|
||||
GUI_SNAP_RIGHT,
|
||||
GUI_SNAP_MAXIMIZED
|
||||
} gui_snap_t;
|
||||
|
||||
typedef struct gui_window {
|
||||
int id;
|
||||
int id;
|
||||
char title[64];
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
bool active;
|
||||
bool minimized;
|
||||
bool visible;
|
||||
bool resizable;
|
||||
|
||||
// Drag / resize interaction state
|
||||
bool is_dragging;
|
||||
int drag_off_x;
|
||||
int drag_off_y;
|
||||
bool is_resizing;
|
||||
int drag_off_x;
|
||||
int drag_off_y;
|
||||
|
||||
// Geometry remembered across maximize / snap so restore is exact
|
||||
gui_snap_t snap;
|
||||
int saved_x;
|
||||
int saved_y;
|
||||
int saved_width;
|
||||
int saved_height;
|
||||
|
||||
void* user_data;
|
||||
|
||||
void (*paint)(struct gui_window* win);
|
||||
@@ -50,12 +75,34 @@ typedef struct gui_window {
|
||||
} gui_window_t;
|
||||
|
||||
void gui_wm_init(void);
|
||||
|
||||
// The work area excludes the taskbar; windows maximize and snap inside it.
|
||||
void gui_wm_set_workarea(int width, int height);
|
||||
|
||||
gui_window_t* gui_wm_create_window(const char* title, int x, int y, int w, int h);
|
||||
void gui_wm_destroy_window(int win_id);
|
||||
void gui_wm_focus_window(int win_id);
|
||||
void gui_wm_destroy_window(int win_id);
|
||||
void gui_wm_focus_window(int win_id);
|
||||
gui_window_t* gui_wm_get_window(int win_id);
|
||||
gui_window_t* gui_wm_get_active_window(void);
|
||||
int gui_wm_get_window_count(void);
|
||||
int gui_wm_get_window_count(void);
|
||||
|
||||
// Enumerate in z-order, bottom-most first. Returns NULL past the end.
|
||||
gui_window_t* gui_wm_get_window_at_index(int index);
|
||||
|
||||
void gui_wm_minimize_window(int win_id);
|
||||
void gui_wm_restore_window(int win_id);
|
||||
void gui_wm_toggle_maximize(int win_id);
|
||||
void gui_wm_snap_window(int win_id, gui_snap_t snap);
|
||||
void gui_wm_close_active(void);
|
||||
void gui_wm_cycle_focus(void);
|
||||
void gui_wm_cascade_windows(void);
|
||||
void gui_wm_tile_windows(void);
|
||||
|
||||
// Keep the WM's press-edge detector in step when another layer (a menu, a
|
||||
// modal dialog) consumed the click instead. Without this the WM still holds
|
||||
// the pre-press state and reads the still-held button as a fresh press on the
|
||||
// following frame, stealing focus from whatever the click just opened.
|
||||
void gui_wm_sync_button_state(bool btn_left);
|
||||
|
||||
void gui_wm_handle_mouse(int x, int y, bool btn_left, bool btn_right);
|
||||
void gui_wm_handle_key(uint16_t key);
|
||||
|
||||
Reference in new issue
Block a user