mirror of
https://github.com/JannisHeydemann/BoredOS.git
synced 2026-05-30 02:16:58 +00:00
DOCS: Refine and add documentation for libwidget.c
This commit is contained in:
@@ -10,7 +10,7 @@ This guide explains how to write a new "Hello World" application locally, compil
|
||||
> [!TIP]
|
||||
> **Looking for working code?** Check out the [Examples Directory](examples/README.md) for full source code demonstrating basic CLI, Windows, Animations, and TCP Networking.
|
||||
|
||||
## 📝 Step 1: Write the C Source
|
||||
## Step 1: Write the C Source
|
||||
|
||||
Applications reside entirely in the `src/userland/` directory. Create a new file, for example, `src/userland/gui/hello.c`.
|
||||
|
||||
@@ -52,7 +52,7 @@ int main(void) {
|
||||
}
|
||||
```
|
||||
|
||||
## ⚙️ Step 2: Edit the Makefile
|
||||
## Step 2: Edit the Makefile
|
||||
|
||||
Now you need to tell the build system to compile `hello.c`. Fortunately, the `src/userland/Makefile` is designed to detect new C files largely automatically!
|
||||
|
||||
@@ -64,7 +64,7 @@ Now you need to tell the build system to compile `hello.c`. Fortunately, the `sr
|
||||
Since you placed the file in `gui/hello.c`, the wildcard logic will pick it up automatically.
|
||||
3. The Makefile will generate `bin/hello.elf` during the build phase.
|
||||
|
||||
## 📦 Step 3: Bundle it into the OS
|
||||
## Step 3: Bundle it into the OS
|
||||
|
||||
The main overarching `Makefile` (in the project root) takes binaries from `src/userland/bin/*.elf` and places them into the `iso_root/bin/` directory, while also adding them to `limine.conf` as loadable boot modules.
|
||||
|
||||
@@ -77,7 +77,7 @@ The main overarching `Makefile` (in the project root) takes binaries from `src/u
|
||||
make clean && make run
|
||||
```
|
||||
|
||||
## 🚀 Step 4: Run it inside BoredOS
|
||||
## Step 4: Run it inside BoredOS
|
||||
|
||||
1. When BoredOS boots, launch the **Terminal** application.
|
||||
2. The OS automatically maps built applications to standard shell commands. Simply type your application's filename (without the `.elf` extension).
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
|
||||
BoredOS provides a custom `libc` implementation necessary for writing userland applications (`.elf` binaries). By avoiding a full-blown standard library like `glibc`, the OS ensures a minimal executable footprint tailored strictly to the existing kernel features.
|
||||
|
||||
All headers are located in `src/userland/libc/`.
|
||||
All headers are located in `src/userland/libc/` (standard functions) and `src/wm/` (UI and widgets).
|
||||
- `libui.h`: Core window and drawing API.
|
||||
- `libwidget.h`: High-level UI components.
|
||||
|
||||
## 📚 Standard Library (`stdlib.h` & `string.h`)
|
||||
## Standard Library (`stdlib.h` & `string.h`)
|
||||
|
||||
The standard library wrappers provide memory management, string manipulation, and basic IO formatting without needing direct syscalls.
|
||||
|
||||
@@ -45,7 +47,7 @@ The standard library wrappers provide memory management, string manipulation, an
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ System Calls (`syscall.h`)
|
||||
## System Calls (`syscall.h`)
|
||||
|
||||
For advanced operations, `syscall.h` provides direct wrappers into the kernel.
|
||||
|
||||
@@ -108,7 +110,7 @@ BoredOS includes lwIP for hardware TCP/UDP networking.
|
||||
|
||||
---
|
||||
|
||||
## 📑 Core Data Structures
|
||||
## Core Data Structures
|
||||
|
||||
### `os_info_t`
|
||||
Contains detailed build and version information about the OS.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
The UI library (`libui.h`) is the sole mechanism for Graphical Userland Applications to draw to the screen and receive input events in BoredOS. It wraps `SYS_GUI` kernel calls.
|
||||
|
||||
## 🪟 Window Management
|
||||
## Window Management
|
||||
|
||||
A "Window" is a reserved drawing canvas managed by the compositor.
|
||||
|
||||
@@ -21,7 +21,7 @@ A "Window" is a reserved drawing canvas managed by the compositor.
|
||||
* `void ui_get_screen_size(uint64_t *out_w, uint64_t *out_h);`
|
||||
Query the global screen resolution of the display.
|
||||
|
||||
## 🎨 Drawing Primitives
|
||||
## Drawing Primitives
|
||||
|
||||
All drawing functions write to an off-screen buffer associated with the window. **You must call `ui_mark_dirty()` to instruct the compositor to push your changes to the physical screen.**
|
||||
|
||||
@@ -38,7 +38,7 @@ All drawing functions write to an off-screen buffer associated with the window.
|
||||
> Colors are defined as 32-bit unsigned integers in **ARGB** format: `0xAARRGGBB`.
|
||||
> E.g., `0xFF000000` is opaque black, `0xFFFF0000` is opaque red.
|
||||
|
||||
## 🔤 Text Rendering
|
||||
## Text Rendering
|
||||
|
||||
BoredOS provides multiple text rendering methodologies, including a default system font and scaled/bitmap alternatives.
|
||||
|
||||
@@ -60,7 +60,7 @@ Used for calculating layout bounds before drawing:
|
||||
* `uint32_t ui_get_string_width_scaled(const char *str, float scale);`
|
||||
* `uint32_t ui_get_font_height_scaled(float scale);`
|
||||
|
||||
## 🔄 Event Handling
|
||||
## Event Handling
|
||||
|
||||
Applications must continuously poll for events inside an infinite `$while(1)` loop.
|
||||
|
||||
@@ -103,3 +103,9 @@ typedef struct {
|
||||
*(Note: Coordinate arguments (`arg1`, `arg2`) for mouse events are typically relative to the top-left corner of the window's client area).*
|
||||
|
||||
---
|
||||
|
||||
> [!TIP]
|
||||
> **Looking for Buttons, TextBoxes, or Scrollbars?**
|
||||
> While `libui.h` provides the foundation for drawing, most applications should use the higher-level [**Widget API**](widget_api.md) (`libwidget.h`) for standard interactive components.
|
||||
|
||||
---
|
||||
|
||||
108
docs/appdev/widget_api.md
Normal file
108
docs/appdev/widget_api.md
Normal file
@@ -0,0 +1,108 @@
|
||||
<div align="center">
|
||||
<h1>Widget API (<code>libwidget.h</code>)</h1>
|
||||
<p><em>High-level UI components for BoredOS applications.</em></p>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
The Widget library (`libwidget.h`) provides a set of reusable UI components built on top of `libui.h`. It uses an abstract `widget_context_t` to decouple component logic from specific drawing implementations, making it easier to build complex graphical interfaces.
|
||||
|
||||
## Widget Context
|
||||
|
||||
To use any widget, you must first define a `widget_context_t`. This structure contains function pointers for basic drawing operations (rects, strings) and theme preferences.
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
void *user_data;
|
||||
void (*draw_rect)(void *user_data, int x, int y, int w, int h, uint32_t color);
|
||||
void (*draw_rounded_rect_filled)(void *user_data, int x, int y, int w, int h, int r, uint32_t color);
|
||||
void (*draw_string)(void *user_data, int x, int y, const char *str, uint32_t color);
|
||||
int (*measure_string_width)(void *user_data, const char *str);
|
||||
void (*mark_dirty)(void *user_data, int x, int y, int w, int h);
|
||||
bool use_light_theme;
|
||||
} widget_context_t;
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> Usually, `user_data` is set to your `ui_window_t` handle, and the functions are simple wrappers around `ui_draw_rect`, `ui_draw_string`, etc.
|
||||
|
||||
---
|
||||
|
||||
## Button (`widget_button_t`)
|
||||
|
||||
Standard interactive button with hover and click states.
|
||||
|
||||
* `void widget_button_init(widget_button_t *btn, int x, int y, int w, int h, const char *text);`
|
||||
* `void widget_button_draw(widget_context_t *ctx, widget_button_t *btn);`
|
||||
* `bool widget_button_handle_mouse(widget_button_t *btn, int mx, int my, bool mouse_down, bool mouse_clicked, void *user_data);`
|
||||
|
||||
### Usage Example:
|
||||
```c
|
||||
widget_button_t my_btn;
|
||||
widget_button_init(&my_btn, 10, 10, 80, 25, "Click Me");
|
||||
my_btn.on_click = my_callback_func;
|
||||
|
||||
// In your event loop:
|
||||
widget_button_handle_mouse(&my_btn, ev.arg1, ev.arg2, is_down, is_clicked, my_data);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Scrollbar (`widget_scrollbar_t`)
|
||||
|
||||
Vertical scrollbar supporting dragging and track-paging.
|
||||
|
||||
* `void widget_scrollbar_init(widget_scrollbar_t *sb, int x, int y, int w, int h);`
|
||||
* `void widget_scrollbar_update(widget_scrollbar_t *sb, int content_height, int scroll_y);`
|
||||
* `void widget_scrollbar_draw(widget_context_t *ctx, widget_scrollbar_t *sb);`
|
||||
* `bool widget_scrollbar_handle_mouse(widget_scrollbar_t *sb, int mx, int my, bool mouse_down, void *user_data);`
|
||||
|
||||
> [!NOTE]
|
||||
> The scrollbar automatically calculates the "thumb" size based on the ratio of `h` to `content_height`.
|
||||
|
||||
---
|
||||
|
||||
## TextBox (`widget_textbox_t`)
|
||||
|
||||
Editable text field with focus support and keyboard handling.
|
||||
|
||||
* `void widget_textbox_init(widget_textbox_t *tb, int x, int y, int w, int h, char *buffer, int max_len);`
|
||||
* `void widget_textbox_draw(widget_context_t *ctx, widget_textbox_t *tb);`
|
||||
* `bool widget_textbox_handle_mouse(widget_textbox_t *tb, int mx, int my, bool mouse_clicked, void *user_data);`
|
||||
* `bool widget_textbox_handle_key(widget_textbox_t *tb, char c, void *user_data);`
|
||||
|
||||
---
|
||||
|
||||
## Dropdown (`widget_dropdown_t`)
|
||||
|
||||
Selection menu for picking one item from a list.
|
||||
|
||||
* `void widget_dropdown_init(widget_dropdown_t *dd, int x, int y, int w, int h, const char **items, int count);`
|
||||
* `void widget_dropdown_draw(widget_context_t *ctx, widget_dropdown_t *dd);`
|
||||
* `bool widget_dropdown_handle_mouse(widget_dropdown_t *dd, int mx, int my, bool mouse_clicked, void *user_data);`
|
||||
|
||||
---
|
||||
|
||||
## Checkbox / Radio (`widget_checkbox_t`)
|
||||
|
||||
Toggleable options with support for circular "Radio" style or square "Checkbox" style.
|
||||
|
||||
* `void widget_checkbox_init(widget_checkbox_t *cb, int x, int y, int w, int h, const char *text, bool is_radio);`
|
||||
* `void widget_checkbox_draw(widget_context_t *ctx, widget_checkbox_t *cb);`
|
||||
* `bool widget_checkbox_handle_mouse(widget_checkbox_t *cb, int mx, int my, bool mouse_clicked, void *user_data);`
|
||||
|
||||
---
|
||||
|
||||
## Event Integration
|
||||
|
||||
Widgets are designed to be polled within your `libui` event loop. Most handle-mouse functions return `true` if the event was "consumed" by the widget, allowing you to stop further processing for that event.
|
||||
|
||||
```c
|
||||
if (ui_get_event(win, &ev)) {
|
||||
bool handled = false;
|
||||
handled |= widget_button_handle_mouse(&btn, ev.arg1, ev.arg2, is_down, is_clicked, NULL);
|
||||
if (!handled) {
|
||||
// Handle global window events...
|
||||
}
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user