--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+use ui_rs::{UiModel, UiActions};
+use ui_rs::ui::*;
+
+#[derive(UiModel, UiActions, Default)]
+struct NewNotebookDialog {
+ name: UiString
+}
+
+pub fn new_notebook_dialog<T>(parent: &UiObject<T>) {
+ let data = NewNotebookDialog::default();
+
+ parent.dialogwindow_builder()
+ .title("Add Notebook")
+ .modal(true)
+ .show_closebutton(false)
+ .lbutton1("Add")
+ .rbutton4("Cancel")
+ .default_button(1)
+ .onclick(|e|{
+ e.obj.close();
+ })
+ .create(data, |obj, data|
+ {
+ obj.grid(|a| {
+ a.margin(10);
+ a.columnspacing(10);
+ a.rowspacing(10);
+ }, |obj| {
+
+ });
+ }).show();
+}
\ No newline at end of file
--- /dev/null
+use std::ffi::{c_char, c_int, c_void, CString};
+use crate::ui::{ffi, toolkit, Button, ButtonBuilder};
+use crate::ui::ffi::{UiButtonArgs, UiLabelArgs, UiObject, UiString, UiToggleArgs};
+use crate::ui::widget::{widget_fn, Widget};
+
+pub struct Label {
+ ptr: *mut c_void
+}
+
+impl Widget for Label {
+ fn get_widget(&self) -> *mut c_void {
+ self.ptr
+ }
+}
+
+pub type LabelCreate = fn(*const UiObject, *const UiLabelArgs) -> *mut c_void;
+
+pub struct LabelBuilder<'a, T> {
+ args: *mut UiLabelArgs,
+ obj: &'a mut toolkit::UiObject<T>,
+ create: LabelCreate
+}
+
+pub enum LabelStyle {
+ Default = 0,
+ Title = 1,
+ SubTitle = 2,
+ Dim = 3
+}
+
+impl<T> toolkit::UiObject<T> {
+ widget_fn!(label, label_builder, LabelBuilder, Label);
+ widget_fn!(llabel, llabel_builder, LabelBuilder, Label);
+ widget_fn!(rlabel, rlabel_builder, LabelBuilder, Label);
+
+ pub fn label_builder<'a>(&'a mut self) -> LabelBuilder<'a, T> {
+ unsafe {
+ let args = ui_label_args_new();
+ LabelBuilder { args: args, obj: self, create: label_create }
+ }
+ }
+
+ pub fn llabel_builder<'a>(&'a mut self) -> LabelBuilder<'a, T> {
+ unsafe {
+ let args = ui_label_args_new();
+ LabelBuilder { args: args, obj: self, create: llabel_create }
+ }
+ }
+
+ pub fn rlabel_builder<'a>(&'a mut self) -> LabelBuilder<'a, T> {
+ unsafe {
+ let args = ui_label_args_new();
+ LabelBuilder { args: args, obj: self, create: rlabel_create }
+ }
+ }
+}
+
+fn label_create<'a>(obj: *const UiObject, args: *const UiLabelArgs) -> *mut c_void {
+ unsafe {
+ ui_label_create(obj, args)
+ }
+}
+
+fn llabel_create<'a>(obj: *const UiObject, args: *const UiLabelArgs) -> *mut c_void {
+ unsafe {
+ ui_llabel_create(obj, args)
+ }
+}
+
+fn rlabel_create<'a>(obj: *const UiObject, args: *const UiLabelArgs) -> *mut c_void {
+ unsafe {
+ ui_rlabel_create(obj, args)
+ }
+}
+
+impl<'a, T> Drop for LabelBuilder<'a, T> {
+ fn drop(&mut self) {
+ unsafe {
+ ui_label_args_free(self.args);
+ }
+ }
+}
+
+impl<'a, T> LabelBuilder<'a, T> {
+ pub fn create(&mut self) -> Label {
+ unsafe {
+ Label { ptr: (self.create)(self.obj.ptr, self.args) }
+ }
+ }
+
+ pub fn fill(&mut self, fill: bool) -> &mut Self {
+ unsafe {
+ ui_label_args_set_fill(self.args, fill as c_int);
+ }
+ self
+ }
+
+ pub fn hexpand(&mut self, value: bool) -> &mut Self {
+ unsafe {
+ ui_label_args_set_hexpand(self.args, value as c_int);
+ }
+ self
+ }
+
+ pub fn vexpand(&mut self, value: bool) -> &mut Self {
+ unsafe {
+ ui_label_args_set_vexpand(self.args, value as c_int);
+ }
+ self
+ }
+
+ pub fn hfill(&mut self, value: bool) -> &mut Self {
+ unsafe {
+ ui_label_args_set_hfill(self.args, value as c_int);
+ }
+ self
+ }
+
+ pub fn vfill(&mut self, value: bool) -> &mut Self {
+ unsafe {
+ ui_label_args_set_vfill(self.args, value as c_int);
+ }
+ self
+ }
+
+ pub fn override_defaults(&mut self, value: bool) -> &mut Self {
+ unsafe {
+ ui_label_args_set_override_defaults(self.args, value as c_int);
+ }
+ self
+ }
+
+ pub fn margin(&mut self, value: i32) -> &mut Self {
+ unsafe {
+ ui_label_args_set_margin(self.args, value);
+ }
+ self
+ }
+
+ pub fn margin_left(&mut self, value: i32) -> &mut Self {
+ unsafe {
+ ui_label_args_set_margin_left(self.args, value);
+ }
+ self
+ }
+
+ pub fn margin_right(&mut self, value: i32) -> &mut Self {
+ unsafe {
+ ui_label_args_set_margin_right(self.args, value);
+ }
+ self
+ }
+
+ pub fn margin_top(&mut self, value: i32) -> &mut Self {
+ unsafe {
+ ui_label_args_set_margin_top(self.args, value);
+ }
+ self
+ }
+
+ pub fn margin_bottom(&mut self, value: i32) -> &mut Self {
+ unsafe {
+ ui_label_args_set_margin_bottom(self.args, value);
+ }
+ self
+ }
+
+ pub fn colspan(&mut self, value: i32) -> &mut Self {
+ unsafe {
+ ui_label_args_set_colspan(self.args, value);
+ }
+ self
+ }
+
+ pub fn rowspan(&mut self, value: i32) -> &mut Self {
+ unsafe {
+ ui_label_args_set_rowspan(self.args, value);
+ }
+ self
+ }
+
+ pub fn name(&mut self, value: &str) -> &mut Self {
+ let cstr = CString::new(value).unwrap();
+ unsafe {
+ ui_label_args_set_name(self.args, cstr.as_ptr());
+ }
+ self
+ }
+
+ pub fn style_class(&mut self, value: &str) -> &mut Self {
+ let cstr = CString::new(value).unwrap();
+ unsafe {
+ ui_label_args_set_style_class(self.args, cstr.as_ptr());
+ }
+ self
+ }
+
+ pub fn label(&mut self, label: &str) -> &mut Self {
+ let cstr = CString::new(label).unwrap();
+ unsafe {
+ ui_label_args_set_label(self.args, cstr.as_ptr());
+ }
+ self
+ }
+
+ // TODO: align
+
+ pub fn style(&mut self, value: LabelStyle) -> &mut Self {
+ unsafe {
+ ui_label_args_set_style(self.args, value as c_int);
+ }
+ self
+ }
+
+ pub fn value(&mut self, value: &toolkit::UiString) {
+ unsafe {
+ ui_label_args_set_value(self.args, value.ptr);
+ }
+ }
+
+ pub fn varname(&mut self, varname: &str) -> &mut Self {
+ let cstr = CString::new(varname).unwrap();
+ unsafe {
+ ui_label_args_set_varname(self.args, cstr.as_ptr());
+ }
+ self
+ }
+
+ pub fn visibility_states(&mut self, states: &[i32]) -> &mut Self {
+ unsafe {
+ ui_label_args_set_visibility_states(self.args, states.as_ptr(), states.len() as c_int);
+ }
+ self
+ }
+
+ pub fn states(&mut self, states: &[i32]) -> &mut Self {
+ unsafe {
+ ui_label_args_set_states(self.args, states.as_ptr(), states.len() as c_int);
+ }
+ self
+ }
+}
+
+extern "C" {
+ fn ui_label_create(obj: *const ffi::UiObject, args: *const UiLabelArgs) -> *mut c_void;
+ fn ui_llabel_create(obj: *const ffi::UiObject, args: *const UiLabelArgs) -> *mut c_void;
+ fn ui_rlabel_create(obj: *const ffi::UiObject, args: *const UiLabelArgs) -> *mut c_void;
+
+ fn ui_label_args_new() -> *mut UiLabelArgs;
+ fn ui_label_args_set_fill(args: *mut UiLabelArgs, fill: c_int);
+ fn ui_label_args_set_hexpand(args: *mut UiLabelArgs, value: c_int);
+ fn ui_label_args_set_vexpand(args: *mut UiLabelArgs, value: c_int);
+ fn ui_label_args_set_hfill(args: *mut UiLabelArgs, value: c_int);
+ fn ui_label_args_set_vfill(args: *mut UiLabelArgs, value: c_int);
+ fn ui_label_args_set_override_defaults(args: *mut UiLabelArgs, value: c_int);
+ fn ui_label_args_set_margin(args: *mut UiLabelArgs, value: c_int);
+ fn ui_label_args_set_margin_left(args: *mut UiLabelArgs, value: c_int);
+ fn ui_label_args_set_margin_right(args: *mut UiLabelArgs, value: c_int);
+ fn ui_label_args_set_margin_top(args: *mut UiLabelArgs, value: c_int);
+ fn ui_label_args_set_margin_bottom(args: *mut UiLabelArgs, value: c_int);
+ fn ui_label_args_set_colspan(args: *mut UiLabelArgs, value: c_int);
+ fn ui_label_args_set_rowspan(args: *mut UiLabelArgs, value: c_int);
+ fn ui_label_args_set_name(args: *mut UiLabelArgs, name: *const c_char);
+ fn ui_label_args_set_style_class(args: *mut UiLabelArgs, classname: *const c_char);
+ fn ui_label_args_set_label(args: *mut UiLabelArgs, label: *const c_char);
+ fn ui_label_args_set_align(args: *mut UiLabelArgs, align: c_int);
+ fn ui_label_args_set_style(args: *mut UiLabelArgs, style: c_int);
+ fn ui_label_args_set_value(args: *mut UiLabelArgs, ivalue: *mut UiString);
+ fn ui_label_args_set_varname(args: *mut UiLabelArgs, varname: *const c_char);
+ fn ui_label_args_set_states(args: *mut UiLabelArgs, states: *const c_int, numstates: c_int);
+ fn ui_label_args_set_visibility_states(args: *mut UiLabelArgs, states: *const c_int, numstates: c_int);
+ fn ui_label_args_free(args: *mut UiLabelArgs);
+}
\ No newline at end of file