From: Olaf Wintermann Date: Sun, 10 May 2026 09:29:20 +0000 (+0200) Subject: add backend initialization error handling X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=3b46f88d8f9925e48d01b838e5e6853694ce1545;p=note.git add backend initialization error handling --- diff --git a/application/src/backend.rs b/application/src/backend.rs index 8cff088..fa8c4d8 100644 --- a/application/src/backend.rs +++ b/application/src/backend.rs @@ -47,7 +47,7 @@ impl Backend { pub fn load_profile( &self, - profile_id: i32, + profile_id: Option, host: &str, user: &str, ) -> Result { @@ -56,22 +56,21 @@ impl Backend { let user = user.to_string(); let profile: usersettings::Model = self.rt.block_on(async { - - // ------------------------------------------------- - // explicit profile id - // ------------------------------------------------- - if profile_id != 0 { - if let Some(model) = UserSettings::find_by_id(profile_id) + // If a profile id was specified, we are trying to use that, + // but if it doesn't exist, an error is returned + if let Some(id) = profile_id { + if let Some(model) = UserSettings::find_by_id(id) .one(&self.db) .await? { return Ok::(model); + } else { + let err = format!("user settings {} not found", id); + return Err::(DbErr::RecordNotFound(err)); } } - // ------------------------------------------------- - // existing host/user profile - // ------------------------------------------------- + // Try to find a profile for the specified host/user if let Some(model) = UserSettings::find() .filter(usersettings::Column::Host.eq(host.clone())) .filter(usersettings::Column::User.eq(user.clone())) @@ -81,13 +80,12 @@ impl Backend { return Ok::(model); } - // ------------------------------------------------- - // create new profile - // ------------------------------------------------- + // Create new profile + let profile_name = format!("{}/{}", host, user); let active = usersettings::ActiveModel { host: Set(host), user: Set(user), - profile: Set("default".to_string()), + profile: Set(profile_name), root_id: Set(0), ..Default::default() @@ -96,7 +94,6 @@ impl Backend { let inserted = active.insert(&self.db).await?; Ok::(inserted) - })?; Ok(profile) diff --git a/application/src/main.rs b/application/src/main.rs index 2709621..537c18d 100644 --- a/application/src/main.rs +++ b/application/src/main.rs @@ -29,6 +29,7 @@ mod window; mod backend; +use std::env; use ui_rs::{ui}; use ui_rs::ui::*; use crate::backend::Backend; @@ -37,24 +38,64 @@ use crate::window::*; fn main() { ui::app_init("note"); - let backend_result = Backend::new(); - if !backend_result.is_ok() { - println!("Error while initializing backend"); - return; - } - let mut backend = backend_result.unwrap(); - backend.migrate().unwrap(); // todo: check error - let settings_result = backend.load_profile(0, "testhost", "testuser"); - if !settings_result.is_ok() { - println!("Error while loading profile"); - return; - } - backend.current_profile = Some(settings_result.unwrap()); + let backend = match init_backend() { + Ok(backend) => backend, + Err(e) => { + app_run_startup_error(e.title.as_str(), e.message.as_str()); + return; + } + }; let mut app = App { backend: backend }; ui::app_run::(&mut app); } +struct ErrMsg { + title: String, + message: String +} + +/// Initializes the backend +/// +/// This includes: +/// +/// - Connecting to the database +/// - Migrating the database +/// - Getting the user profile / settings +/// +/// If no profile exists yet, a new profile is created +fn init_backend() -> Result { + let mut backend = match Backend::new() { + Ok(backend) => backend, + Err(e) => return Err( ErrMsg { + title: "Backend initialization failed".to_string(), + message: e.to_string() + }) + }; + + match backend.migrate() { + Ok(_) => (), + Err(e) => return Err(ErrMsg { + title: "Database migration failed".to_string(), + message: e.to_string() + }) + }; + + let host = hostname(); + let user = username(); + + let profile = match backend.load_profile(None, host.as_str(), user.as_str()) { + Ok(profile) => profile, + Err(e) => return Err(ErrMsg { + title: "Cannot load user settings".to_string(), + message: e.to_string() + }) + }; + backend.current_profile = Some(profile); + + Ok(backend) +} + struct App { backend: Backend, } @@ -80,4 +121,55 @@ fn create_toolbar(app: &AppContext) { app.toolbar_add_default("go_back", ToolbarItemPosition::Left); app.toolbar_add_default("go_forward", ToolbarItemPosition::Left); app.toolbar_add_default("new_note", ToolbarItemPosition::Left); -} \ No newline at end of file +} + + +fn username() -> String { + env::var("USER") + .or_else(|_| env::var("USERNAME")) + .unwrap_or_else(|_| "unknown".to_string()) +} + +#[cfg(unix)] +fn hostname() -> String { + use std::ffi::CStr; + use std::os::raw::{c_char, c_int}; + + unsafe extern "C" { + fn gethostname(name: *mut c_char, len: usize) -> c_int; + } + + let mut buf = [0u8; 256]; + + unsafe { + if gethostname(buf.as_mut_ptr() as *mut c_char, buf.len()-1) != 0 { + return "unknown".into(); + } + + // Ensure termination + buf[buf.len() - 1] = 0; + + CStr::from_ptr(buf.as_ptr() as *const c_char) + .to_string_lossy() + .into_owned() + } +} + +#[cfg(windows)] +fn hostname() -> String { + #[link(name = "Kernel32")] + unsafe extern "system" { + fn GetComputerNameW(lpBuffer: *mut u16, nSize: *mut u32) -> i32; + } + + let mut buf = [0u16; 256]; + let mut size = buf.len() as u32; + + unsafe { + if GetComputerNameW(buf.as_mut_ptr(), &mut size) == 0 { + return "unknown".into(); + } + + String::from_utf16_lossy(&buf[..size as usize]) + } +} diff --git a/ui/common/container.c b/ui/common/container.c index 6f0dde9..12c6267 100644 --- a/ui/common/container.c +++ b/ui/common/container.c @@ -33,13 +33,13 @@ void ui_end_new(UiObject *obj) { if(!obj->container_end) { return; } - UiContainerX *rm = obj->container_end; + UiContainer *rm = obj->container_end; uic_object_pop_container(obj); ui_free(obj->ctx, rm); } void ui_newline(UiObject *obj) { - UiContainerX *container = obj->container_end; + UiContainer *container = obj->container_end; if(container) { container->newline = TRUE; } diff --git a/ui/common/object.c b/ui/common/object.c index 150cd43..4cbd4d9 100644 --- a/ui/common/object.c +++ b/ui/common/object.c @@ -119,7 +119,7 @@ UiObject* uic_ctx_object_new(UiContext *ctx, UIWIDGET widget) { return newobj; } -void uic_object_push_container(UiObject *toplevel, UiContainerX *newcontainer) { +void uic_object_push_container(UiObject *toplevel, UiContainer *newcontainer) { newcontainer->prev = toplevel->container_end; if(toplevel->container_end) { toplevel->container_end->next = newcontainer; @@ -148,8 +148,8 @@ void uic_object_pop_container(UiObject *toplevel) { */ void uic_object_remove_second_last_container(UiObject *toplevel) { if(toplevel->container_end && toplevel->container_end->prev) { - UiContainerX *end = toplevel->container_end; - UiContainerX *rm = toplevel->container_end->prev; + UiContainer *end = toplevel->container_end; + UiContainer *rm = toplevel->container_end->prev; end->prev = rm->prev; if(rm->prev) { diff --git a/ui/common/object.h b/ui/common/object.h index 4327875..c809c82 100644 --- a/ui/common/object.h +++ b/ui/common/object.h @@ -55,7 +55,7 @@ UiObject* uic_object_new_toplevel(void); UiObject* uic_object_new(UiObject *toplevel, UIWIDGET widget); UiObject* uic_ctx_object_new(UiContext *ctx, UIWIDGET widget); -void uic_object_push_container(UiObject *toplevel, UiContainerX *newcontainer); +void uic_object_push_container(UiObject *toplevel, UiContainer *newcontainer); void uic_object_pop_container(UiObject *toplevel); void uic_object_remove_second_last_container(UiObject *toplevel); diff --git a/ui/gtk/button.c b/ui/gtk/button.c index e72f7a7..b8c0867 100644 --- a/ui/gtk/button.c +++ b/ui/gtk/button.c @@ -153,6 +153,47 @@ void ui_button_set_icon(UIWIDGET button, const char *icon) { ui_button_set_icon_name(button, icon); } +void ui_button_set_tooltip(UIWIDGET button, const char *tooltip) { + gtk_widget_set_tooltip_text(GTK_WIDGET(button), tooltip); +} + +void ui_togglebutton_set_label(UIWIDGET button, const char *label) { + ui_button_set_label(button, label); +} + +void ui_togglebutton_set_icon(UIWIDGET button, const char *icon) { + ui_button_set_icon(button, icon); +} + +void ui_togglebutton_set_tooltip(UIWIDGET button, const char *tooltip) { + ui_button_set_tooltip(button, tooltip); +} + +void ui_checkbox_set_label(UIWIDGET button, const char *label) { + ui_button_set_label(button, label); +} + +void ui_checkbox_set_icon(UIWIDGET button, const char *icon) { + ui_button_set_icon(button, icon); +} + +void ui_checkbox_set_tooltip(UIWIDGET button, const char *tooltip) { + ui_button_set_tooltip(button, tooltip); +} + +void ui_radiobutton_set_label(UIWIDGET button, const char *label) { + ui_button_set_label(button, label); +} + +void ui_radiobutton_set_icon(UIWIDGET button, const char *icon) { + ui_button_set_icon(button, icon); +} + +void ui_radiobutton_set_tooltip(UIWIDGET button, const char *tooltip) { + ui_button_set_tooltip(button, tooltip); +} + + int64_t ui_toggle_button_get(UiInteger *integer) { GtkToggleButton *button = integer->obj; integer->value = (int)gtk_toggle_button_get_active(button); @@ -880,16 +921,7 @@ static void linkbutton_callback(GtkWidget *widget, UiLinkButton *data) { static void linkbutton_clicked(GtkWidget *widget, UiLinkButton *data) { linkbutton_callback(widget, data); if(data->link) { -#if GTK_CHECK_VERSION(4, 0, 0) - GtkUriLauncher *launcher = gtk_uri_launcher_new (data->link); - gtk_uri_launcher_launch (launcher, NULL, NULL, NULL, NULL); - g_object_unref (launcher); -#elif GTK_CHECK_VERSION(3, 22, 0) - GError *error = NULL; - gtk_show_uri_on_window(NULL, data->link, GDK_CURRENT_TIME, &error); -#elif - // TODO: call xdg-open -#endif + ui_open_uri(data->link); } } diff --git a/ui/gtk/container.c b/ui/gtk/container.c index 5489ecb..30960ff 100644 --- a/ui/gtk/container.c +++ b/ui/gtk/container.c @@ -43,12 +43,12 @@ void ui_container_begin_close(UiObject *obj) { - UiContainerX *ct = obj->container_end; + UiContainer *ct = obj->container_end; ct->close = 1; } int ui_container_finish(UiObject *obj) { - UiContainerX *ct = obj->container_end; + UiContainer *ct = obj->container_end; if(ct->close) { ui_end_new(obj); return 0; @@ -82,7 +82,7 @@ GtkWidget* ui_subcontainer_create( { GtkWidget *sub = NULL; GtkWidget *add = NULL; - UiContainerX *container = NULL; + UiContainer *container = NULL; switch(type) { default: { sub = ui_gtk_vbox_new(spacing); @@ -125,11 +125,11 @@ void ui_custom_container_create(UiObject *obj, UIWIDGET widget, ui_addwidget_fun container->container.widget = widget; container->add = add_child; container->userdata = userdata; - uic_object_push_container(obj, (UiContainerX*)container); + uic_object_push_container(obj, (UiContainer*)container); } /* -------------------- Box Container -------------------- */ -UiContainerX* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type) { +UiContainer* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type) { UiBoxContainer *ct = cxCalloc( obj->ctx->allocator, 1, @@ -137,7 +137,7 @@ UiContainerX* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType ct->container.widget = box; ct->container.add = ui_box_container_add; ct->type = type; - return (UiContainerX*)ct; + return (UiContainer*)ct; } void ui_box_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { @@ -172,7 +172,7 @@ void ui_box_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *l #endif } -UiContainerX* ui_grid_container( +UiContainer* ui_grid_container( UiObject *obj, GtkWidget *grid, UiBool def_hexpand, @@ -192,7 +192,7 @@ UiContainerX* ui_grid_container( ct->container.add = ui_grid_container_add; UI_GTK_V2(ct->width = 0); UI_GTK_V2(ct->height = 1); - return (UiContainerX*)ct; + return (UiContainer*)ct; } @@ -271,14 +271,14 @@ void ui_grid_container_add(UiContainerPrivate *ct, GtkWidget *widget) { } #endif -UiContainerX* ui_frame_container(UiObject *obj, GtkWidget *frame) { +UiContainer* ui_frame_container(UiObject *obj, GtkWidget *frame) { UiContainerPrivate *ct = cxCalloc( obj->ctx->allocator, 1, sizeof(UiContainerPrivate)); ct->widget = frame; ct->add = ui_frame_container_add; - return (UiContainerX*)ct; + return (UiContainer*)ct; } void ui_frame_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { @@ -286,14 +286,14 @@ void ui_frame_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout FRAME_SET_CHILD(ct->widget, widget); } -UiContainerX* ui_expander_container(UiObject *obj, GtkWidget *expander) { +UiContainer* ui_expander_container(UiObject *obj, GtkWidget *expander) { UiContainerPrivate *ct = cxCalloc( obj->ctx->allocator, 1, sizeof(UiContainerPrivate)); ct->widget = expander; ct->add = ui_expander_container_add; - return (UiContainerX*)ct; + return (UiContainer*)ct; } void ui_expander_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { @@ -307,24 +307,24 @@ void ui_scrolledwindow_container_add(UiContainerPrivate *ct, GtkWidget *widget, SCROLLEDWINDOW_SET_CHILD(ct->widget, widget); } -UiContainerX* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow) { +UiContainer* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow) { UiContainerPrivate *ct = cxCalloc( obj->ctx->allocator, 1, sizeof(UiContainerPrivate)); ct->widget = scrolledwindow; ct->add = ui_scrolledwindow_container_add; - return (UiContainerX*)ct; + return (UiContainer*)ct; } -UiContainerX* ui_tabview_container(UiObject *obj, GtkWidget *tabview) { +UiContainer* ui_tabview_container(UiObject *obj, GtkWidget *tabview) { UiTabViewContainer *ct = cxCalloc( obj->ctx->allocator, 1, sizeof(UiTabViewContainer)); ct->container.widget = tabview; ct->container.add = ui_tabview_container_add; - return (UiContainerX*)ct; + return (UiContainer*)ct; } void ui_tabview_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { @@ -390,7 +390,7 @@ UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs *args, UiSubContainerType ui_set_name_and_style(box, args->name, args->style_class); ct->add(ct, box, &layout); - UiContainerX *container = ui_box_container(obj, box, type); + UiContainer *container = ui_box_container(obj, box, type); uic_object_push_container(obj, container); uic_widget_set_visibility_states(obj->ctx, box, args->visibility_states); @@ -428,7 +428,7 @@ UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs *args) { ui_set_name_and_style(grid, args->name, args->style_class); ct->add(ct, grid, &layout); - UiContainerX *container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill); + UiContainer *container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill); uic_object_push_container(obj, container); uic_widget_set_visibility_states(obj->ctx, grid, args->visibility_states); @@ -476,7 +476,7 @@ UIWIDGET ui_frame_create(UiObject *obj, UiFrameArgs *args) { if(sub) { FRAME_SET_CHILD(frame, sub); } else { - UiContainerX *container = ui_frame_container(obj, frame); + UiContainer *container = ui_frame_container(obj, frame); uic_object_push_container(obj, container); } @@ -502,7 +502,7 @@ UIEXPORT UIWIDGET ui_expander_create(UiObject *obj, UiFrameArgs *args) { if(sub) { EXPANDER_SET_CHILD(expander, sub); } else { - UiContainerX *container = ui_expander_container(obj, expander); + UiContainer *container = ui_expander_container(obj, expander); uic_object_push_container(obj, container); } @@ -529,7 +529,7 @@ UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs *args) { if(sub) { SCROLLEDWINDOW_SET_CHILD(sw, sub); } else { - UiContainerX *container = ui_scrolledwindow_container(obj, sw); + UiContainer *container = ui_scrolledwindow_container(obj, sw); uic_object_push_container(obj, container); } @@ -821,7 +821,7 @@ UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs *args) { UiLayout layout = UI_ARGS2LAYOUT(args); ct->add(ct, widget, &layout); - UiContainerX *container = ui_tabview_container(obj, widget); + UiContainer *container = ui_tabview_container(obj, widget); uic_object_push_container(obj, container); uic_widget_set_visibility_states(obj->ctx, widget, args->visibility_states); @@ -830,7 +830,7 @@ UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs *args) { } static GtkWidget* create_tab(UiObject *obj, UiGtkTabView *tabview, const char *title, int tab) { - UiContainerX *container; + UiContainer *container; GtkWidget *sub; switch(tabview->subcontainer) { default: { @@ -916,7 +916,7 @@ static void hb_set_part(UiObject *obj, int part) { sizeof(UiHeaderbarContainer)); memcpy(hb, ct, sizeof(UiHeaderbarContainer)); hb->part = part; - uic_object_push_container(obj, (UiContainerX*)hb); + uic_object_push_container(obj, (UiContainer*)hb); } void ui_headerbar_start_create(UiObject *obj) { @@ -939,7 +939,7 @@ UIWIDGET ui_headerbar_fallback_create(UiObject *obj, UiHeaderbarArgs *args) { ui_set_name_and_style(box, args->name, args->style_class); ct->add(ct, box, &layout); - UiContainerX *container = ui_headerbar_fallback_container(obj, box); + UiContainer *container = ui_headerbar_fallback_container(obj, box); uic_object_push_container(obj, container); return box; @@ -949,21 +949,21 @@ static void hb_fallback_set_part(UiObject *obj, int part) { UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; GtkWidget *headerbar = ct->widget; - UiContainerX *container = ui_headerbar_container(obj, headerbar); + UiContainer *container = ui_headerbar_container(obj, headerbar); uic_object_push_container(obj, container); UiHeaderbarContainer *hb = (UiHeaderbarContainer*)container; hb->part = part; } -UiContainerX* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar) { +UiContainer* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar) { UiHeaderbarContainer *ct = cxCalloc( obj->ctx->allocator, 1, sizeof(UiHeaderbarContainer)); ct->container.widget = headerbar; ct->container.add = ui_headerbar_fallback_container_add; - return (UiContainerX*)ct; + return (UiContainer*)ct; } void ui_headerbar_fallback_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { @@ -979,20 +979,20 @@ UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs *args) { return ui_headerbar_fallback_create(obj, args); } - UiContainerX *container = ui_headerbar_container(obj, headerbar); + UiContainer *container = ui_headerbar_container(obj, headerbar); uic_object_push_container(obj, container); return headerbar; } -UiContainerX* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar) { +UiContainer* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar) { UiHeaderbarContainer *ct = cxCalloc( obj->ctx->allocator, 1, sizeof(UiHeaderbarContainer)); ct->container.widget = headerbar; ct->container.add = ui_headerbar_container_add; - return (UiContainerX*)ct; + return (UiContainer*)ct; } void ui_headerbar_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { @@ -1035,7 +1035,7 @@ UIWIDGET ui_sidebar_create(UiObject *obj, UiSidebarArgs *args) { ui_gtk_set_margin(box, args->margin, args->margin_left, args->margin_right, args->margin_top, args->margin_bottom); adw_toolbar_view_set_content(ADW_TOOLBAR_VIEW(sidebar_toolbar_view), box); - UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX); + UiContainer *container = ui_box_container(obj, box, UI_CONTAINER_VBOX); uic_object_push_container(obj, container); return box; @@ -1048,7 +1048,7 @@ UIWIDGET ui_sidebar_create(UiObject *obj, UiSidebarArgs *args) { ui_gtk_set_margin(box, args->margin, args->margin_left, args->margin_right, args->margin_top, args->margin_bottom); BOX_ADD_EXPAND(sidebar_vbox, box); - UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX); + UiContainer *container = ui_box_container(obj, box, UI_CONTAINER_VBOX); uic_object_push_container(obj, container); return box; @@ -1068,7 +1068,7 @@ static UIWIDGET splitwindow_panel(UiObject *obj, GtkWidget *pbox, UiSidebarArgs ui_gtk_set_margin(box, args->margin, args->margin_left, args->margin_right, args->margin_top, args->margin_bottom); BOX_ADD_EXPAND(pbox, box); - UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX); + UiContainer *container = ui_box_container(obj, box, UI_CONTAINER_VBOX); uic_object_push_container(obj, container); return box; @@ -1135,7 +1135,7 @@ static UIWIDGET splitpane_create(UiObject *obj, UiOrientation orientation, UiSpl } UiSplitPane *splitpane = ui_create_splitpane_data(pane0, orientation, max, args->initial_position); - UiContainerX *container = ui_splitpane_container(obj, pane0, splitpane); + UiContainer *container = ui_splitpane_container(obj, pane0, splitpane); uic_object_push_container(obj, container); g_object_set_data(G_OBJECT(pane0), "ui_splitpane", splitpane); @@ -1172,12 +1172,12 @@ UiSplitPane* ui_create_splitpane_data(GtkWidget *pane, UiOrientation orientation return ct; } -UiContainerX* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiSplitPane *data) { +UiContainer* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiSplitPane *data) { UiSplitPaneContainer *ct = ui_calloc(obj->ctx, 1, sizeof(UiSplitPaneContainer)); ct->container.widget = pane; ct->container.add = ui_splitpane_container_add; ct->splitpane = data; - return (UiContainerX*)ct; + return (UiContainer*)ct; } void ui_splitpane_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { diff --git a/ui/gtk/container.h b/ui/gtk/container.h index a5e46b2..352b50e 100644 --- a/ui/gtk/container.h +++ b/ui/gtk/container.h @@ -50,7 +50,7 @@ typedef struct UiDocumentView UiDocumentView; typedef struct UiContainerPrivate UiContainerPrivate; struct UiContainerPrivate { - UiContainerX container; + UiContainer container; GtkWidget *widget; UIMENU menu; @@ -160,11 +160,11 @@ GtkWidget* ui_subcontainer_create( GtkWidget* ui_gtk_set_margin(GtkWidget *widget, int margin, int margin_left, int margin_right, int margin_top, int margin_bottom); UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs *args, UiSubContainerType type); -UiContainerX* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type); +UiContainer* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type); void ui_box_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); GtkWidget* ui_create_grid_widget(int colspacing, int rowspacing); -UiContainerX* ui_grid_container( +UiContainer* ui_grid_container( UiObject *obj, GtkWidget *grid, UiBool def_hexpand, @@ -173,20 +173,20 @@ UiContainerX* ui_grid_container( UiBool def_vfill); void ui_grid_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); -UiContainerX* ui_frame_container(UiObject *obj, GtkWidget *frame); +UiContainer* ui_frame_container(UiObject *obj, GtkWidget *frame); void ui_frame_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); -UiContainerX* ui_expander_container(UiObject *obj, GtkWidget *expander); +UiContainer* ui_expander_container(UiObject *obj, GtkWidget *expander); void ui_expander_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); -UiContainerX* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow); +UiContainer* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow); void ui_scrolledwindow_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); -UiContainerX* ui_tabview_container(UiObject *obj, GtkWidget *tabview); +UiContainer* ui_tabview_container(UiObject *obj, GtkWidget *tabview); void ui_tabview_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); UiSplitPane* ui_create_splitpane_data(GtkWidget *pane, UiOrientation orientation, int max, int init); -UiContainerX* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiSplitPane *data); +UiContainer* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiSplitPane *data); void ui_splitpane_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); int64_t ui_splitpane_get(UiInteger *i); @@ -197,11 +197,11 @@ UiGtkTabView* ui_widget_get_tabview_data(UIWIDGET tabview); void ui_gtk_notebook_select_tab(GtkWidget *widget, int tab); #if GTK_CHECK_VERSION(3, 10, 0) -UiContainerX* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar); +UiContainer* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar); void ui_headerbar_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); #endif -UiContainerX* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar); +UiContainer* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar); void ui_headerbar_fallback_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); #ifdef __cplusplus diff --git a/ui/gtk/toolkit.c b/ui/gtk/toolkit.c index 0ad0fe8..6ab00a3 100644 --- a/ui/gtk/toolkit.c +++ b/ui/gtk/toolkit.c @@ -572,3 +572,16 @@ void ui_set_widget_nvisibility_states(UiContext *ctx, GtkWidget *widget, const i ui_set_visible(widget, FALSE); } } + +void ui_open_uri(const char *uri) { +#if GTK_CHECK_VERSION(4, 0, 0) + GtkUriLauncher *launcher = gtk_uri_launcher_new(uri); + gtk_uri_launcher_launch(launcher, NULL, NULL, NULL, NULL); + g_object_unref(launcher); +#elif GTK_CHECK_VERSION(3, 22, 0) + GError *error = NULL; + gtk_show_uri_on_window(NULL, uri, GDK_CURRENT_TIME, &error); +#elif + // TODO: call xdg-open +#endif +} diff --git a/ui/gtk/window.c b/ui/gtk/window.c index 0ef8093..7952570 100644 --- a/ui/gtk/window.c +++ b/ui/gtk/window.c @@ -398,7 +398,7 @@ static UiObject* create_window(const char *title, UiBool sidebar, UiBool splitvi gtk_container_add(GTK_CONTAINER(frame), content_box); obj->container = ui_box_container(obj, content_box); */ - UiContainerX *container = ui_box_container(obj, content_box, UI_CONTAINER_VBOX); + UiContainer *container = ui_box_container(obj, content_box, UI_CONTAINER_VBOX); uic_object_push_container(obj, container); nwindows++; @@ -503,6 +503,8 @@ static void dialog_response(AdwAlertDialog *self, gchar *response, UiEventData * if(data->callback) { data->callback(&evt, data->userdata); } + + ui_app_unref(); } void ui_dialog_create(UiObject *parent, UiDialogArgs *args) { @@ -547,7 +549,8 @@ void ui_dialog_create(UiObject *parent, UiDialogArgs *args) { event); g_signal_connect(dialog, "response", G_CALLBACK(dialog_response), event); - adw_dialog_present(dialog, parent->widget); + ui_app_ref(); + adw_dialog_present(dialog, parent ? parent->widget : NULL); if(entry) { gtk_entry_grab_focus_without_selecting(GTK_ENTRY(entry)); @@ -559,8 +562,14 @@ static void ui_dialog_response (GtkDialog* self, gint response_id, gpointer user UiEventData *data = user_data; UiEvent evt; evt.obj = data->obj; - evt.document = evt.obj->ctx->document; - evt.window = evt.obj->window; + if(evt.obj) { + evt.document = evt.obj->ctx->document; + evt.window = evt.obj->window; + } else { + evt.document = NULL; + evt.window = NULL; + } + evt.eventdata = NULL; evt.intval = 0; @@ -975,7 +984,7 @@ UiObject* ui_dialog_window_create(UiObject *parent, UiDialogWindowArgs *args) { #endif GtkWidget *content_vbox = ui_gtk_vbox_new(0); - UiContainerX *container = ui_box_container(obj, content_vbox, UI_CONTAINER_VBOX); + UiContainer *container = ui_box_container(obj, content_vbox, UI_CONTAINER_VBOX); uic_object_push_container(obj, container); if(args->lbutton1 || args->lbutton2 || args->rbutton3 || args->rbutton4) { #if GTK_CHECK_VERSION(3, 10, 0) diff --git a/ui/motif/container.c b/ui/motif/container.c index 73c9198..d99581a 100644 --- a/ui/motif/container.c +++ b/ui/motif/container.c @@ -87,7 +87,7 @@ static UIWIDGET box_create(UiObject *obj, UiContainerArgs *args, UiBoxOrientatio Widget grid = XtCreateManagedWidget(args->name ? args->name : "boxcontainer", gridClass, parent, xargs, n); ctn->add(ctn, grid); - UiContainerX *container = ui_box_container(obj, grid, orientation); + UiContainer *container = ui_box_container(obj, grid, orientation); uic_object_push_container(obj, container); uic_widget_set_visibility_states(obj->ctx, grid, args->visibility_states); @@ -105,14 +105,14 @@ UIWIDGET ui_hbox_create(UiObject *obj, UiContainerArgs *args) { return box_create(obj, args, UI_BOX_HORIZONTAL); } -UiContainerX* ui_box_container(UiObject *obj, Widget grid, UiBoxOrientation orientation) { +UiContainer* ui_box_container(UiObject *obj, Widget grid, UiBoxOrientation orientation) { UiBoxContainer *ctn = ui_malloc(obj->ctx, sizeof(UiBoxContainer)); memset(ctn, 0, sizeof(UiBoxContainer)); ctn->container.prepare = orientation == UI_BOX_VERTICAL ? ui_vbox_prepare : ui_hbox_prepare; ctn->container.add = ui_box_container_add; ctn->container.widget = grid; ctn->n = 0; - return (UiContainerX*)ctn; + return (UiContainer*)ctn; } static Widget ui_box_container_prepare(UiBoxContainer *box, UiLayout *layout, Arg *args, int *n) { @@ -170,7 +170,7 @@ UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs *args) { Widget grid = XtCreateManagedWidget(args->name ? args->name : "gridcontainer", gridClass, parent, xargs, n); ui_container_add(ctn, grid); - UiContainerX *container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill); + UiContainer *container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill); uic_object_push_container(obj, container); uic_widget_set_visibility_states(obj->ctx, grid, args->visibility_states); @@ -178,7 +178,7 @@ UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs *args) { return grid; } -UiContainerX* ui_grid_container( +UiContainer* ui_grid_container( UiObject *obj, Widget grid, UiBool def_hexpand, @@ -197,7 +197,7 @@ UiContainerX* ui_grid_container( ctn->def_vexpand = def_vexpand; ctn->def_hfill = def_hfill; ctn->def_vfill = def_vfill; - return (UiContainerX*)ctn; + return (UiContainer*)ctn; } Widget ui_grid_container_prepare(UiContainerPrivate *ctn, UiLayout *layout, Arg *args, int *n) { @@ -275,7 +275,7 @@ UIWIDGET ui_frame_create(UiObject *obj, UiFrameArgs *args) { XmStringFree(s); } - UiContainerX *container = ui_frame_container(obj, frame); + UiContainer *container = ui_frame_container(obj, frame); uic_object_push_container(obj, container); UiContainerArgs sub_args = { @@ -308,13 +308,13 @@ UIWIDGET ui_frame_create(UiObject *obj, UiFrameArgs *args) { return frame; } -UiContainerX* ui_frame_container(UiObject *obj, Widget frame) { +UiContainer* ui_frame_container(UiObject *obj, Widget frame) { UiContainerPrivate *ctn = ui_malloc(obj->ctx, sizeof(UiContainerPrivate)); memset(ctn, 0, sizeof(UiContainerPrivate)); ctn->prepare = ui_frame_container_prepare; ctn->add = ui_frame_container_add; ctn->widget = frame; - return (UiContainerX*)ctn; + return (UiContainer*)ctn; } Widget ui_frame_container_prepare(UiContainerPrivate *ctn, UiLayout *layout, Arg *args, int *n) { @@ -472,7 +472,7 @@ UIWIDGET ui_tabview_create(UiObject *obj, UiTabViewArgs *args) { i->set = ui_tabview_set; } - uic_object_push_container(obj, (UiContainerX*)ct); + uic_object_push_container(obj, (UiContainer*)ct); uic_widget_set_visibility_states(obj->ctx, form, args->visibility_states); @@ -556,7 +556,7 @@ UiObject* ui_tabview_add(UIWIDGET tabview, const char *name, int tab_index) { UiObject *newobj = ui_calloc(tabviewdata->obj->ctx, 1, sizeof(UiObject)); newobj->ctx = tabviewdata->obj->ctx; newobj->widget = grid; - UiContainerX *container = ui_box_container(newobj, grid, UI_BOX_VERTICAL); + UiContainer *container = ui_box_container(newobj, grid, UI_BOX_VERTICAL); newobj->container_begin = container; newobj->container_end = container; return newobj; @@ -693,13 +693,13 @@ void ui_scrolledwindow_add(UiContainerPrivate *ctn, Widget widget) { } -static UiContainerX* ui_scrolledwindow_container(UiObject *obj, Widget scrolledwindow) { +static UiContainer* ui_scrolledwindow_container(UiObject *obj, Widget scrolledwindow) { UiContainerPrivate *ctn = ui_malloc(obj->ctx, sizeof(UiContainerPrivate)); memset(ctn, 0, sizeof(UiContainerPrivate)); ctn->prepare = ui_scrolledwindow_prepare; ctn->add = ui_scrolledwindow_add; ctn->widget = scrolledwindow; - return (UiContainerX*)ctn; + return (UiContainer*)ctn; } UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs *args) { @@ -721,7 +721,7 @@ UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs *args) { Widget scrolledwindow = XmCreateScrolledWindow(parent, "scrolledwindow", xargs, n); ui_container_add(ctn, scrolledwindow); - UiContainerX *container = ui_scrolledwindow_container(obj, scrolledwindow); + UiContainer *container = ui_scrolledwindow_container(obj, scrolledwindow); uic_object_push_container(obj, container); return scrolledwindow; diff --git a/ui/motif/container.h b/ui/motif/container.h index 30262e5..afd2c03 100644 --- a/ui/motif/container.h +++ b/ui/motif/container.h @@ -72,7 +72,7 @@ typedef struct UiContainerPrivate UiContainerPrivate; struct UiContainerPrivate { - UiContainerX container; + UiContainer container; Widget (*prepare)(UiContainerPrivate*, UiLayout *layout, Arg *, int*); void (*add)(UiContainerPrivate*, Widget); Widget widget; @@ -144,13 +144,13 @@ void ui_tabview_set(UiInteger *i, int64_t value); Widget ui_tabview_container_prepare(UiContainerPrivate *ctn, UiLayout *layout, Arg *args, int *n); void ui_tabview_container_add(UiContainerPrivate *ctn, Widget widget); -UiContainerX* ui_box_container(UiObject *obj, Widget grid, UiBoxOrientation orientation); +UiContainer* ui_box_container(UiObject *obj, Widget grid, UiBoxOrientation orientation); Widget ui_vbox_prepare(UiContainerPrivate *ctn, UiLayout *layout, Arg *args, int *n); Widget ui_hbox_prepare(UiContainerPrivate *ctn, UiLayout *layout, Arg *args, int *n); void ui_box_container_add(UiContainerPrivate *ctn, Widget widget); -UiContainerX* ui_grid_container( +UiContainer* ui_grid_container( UiObject *obj, Widget grid, UiBool def_hexpand, @@ -160,7 +160,7 @@ UiContainerX* ui_grid_container( Widget ui_grid_container_prepare(UiContainerPrivate *ctn, UiLayout *layout, Arg *args, int *n); void ui_grid_container_add(UiContainerPrivate *ctn, Widget widget); -UiContainerX* ui_frame_container(UiObject *obj, Widget frame); +UiContainer* ui_frame_container(UiObject *obj, Widget frame); Widget ui_frame_container_prepare(UiContainerPrivate *ctn, UiLayout *layout, Arg *args, int *n); void ui_frame_container_add(UiContainerPrivate *ctn, Widget widget); diff --git a/ui/motif/window.c b/ui/motif/window.c index c8d5b1d..dd1c9ba 100644 --- a/ui/motif/window.c +++ b/ui/motif/window.c @@ -142,7 +142,7 @@ static UiObject* create_window(const char *title, Boolean simple) { XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; Widget vbox = XtCreateManagedWidget("window_vbox", gridClass, form, args, n); - UiContainerX *container = ui_box_container(obj, vbox, UI_BOX_VERTICAL); + UiContainer *container = ui_box_container(obj, vbox, UI_BOX_VERTICAL); uic_object_push_container(obj, container); obj->widget = toplevel; diff --git a/ui/qt/container.cpp b/ui/qt/container.cpp index 36e5b46..fcc6228 100644 --- a/ui/qt/container.cpp +++ b/ui/qt/container.cpp @@ -43,7 +43,7 @@ static void delete_container(UiContainerPrivate *ct) { } void ui_obj_add_container(UiObject *obj, UiContainerPrivate *ct) { - UiContainerX *container = (UiContainerX*)ui_malloc(obj->ctx, sizeof(UiContainerX)); + UiContainer *container = (UiContainer*)ui_malloc(obj->ctx, sizeof(UiContainer)); container->close = 0; container->container = ct; container->prev = NULL; diff --git a/ui/qt/container.h b/ui/qt/container.h index 0adf78a..d9ba67a 100644 --- a/ui/qt/container.h +++ b/ui/qt/container.h @@ -41,11 +41,11 @@ #include #include -#define ui_obj_container(obj) (UiContainerPrivate*)((UiContainerX*)obj->container_end)->container +#define ui_obj_container(obj) (UiContainerPrivate*)((UiContainer*)obj->container_end)->container struct UiContainerPrivate { UIWIDGET current; - UiContainerX *container; + UiContainer *container; virtual void add(QWidget *widget, UiLayout& layout) = 0; virtual void end() {} diff --git a/ui/qt/text.cpp b/ui/qt/text.cpp index 2aeab47..bdac8ce 100644 --- a/ui/qt/text.cpp +++ b/ui/qt/text.cpp @@ -96,6 +96,10 @@ UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs *args) { return textarea; } +UIWIDGET ui_textarea_gettextwidget(UIWIDGET textarea) { + return textarea; +} + void ui_textarea_save(UiText *text) { // NOOP } @@ -189,10 +193,7 @@ void ui_textarea_selection(UiText *text, int *begin, int *end) { void ui_textarea_setselection(UiText *text, int begin, int end) { QTextEdit *textview = (QTextEdit*)text->obj; - QTextCursor cursor = textview->textCursor(); - cursor.setPosition(begin, QTextCursor::MoveAnchor); - cursor.setPosition(end, QTextCursor::KeepAnchor); - textview->setTextCursor(cursor); + ui_textarea_set_selection(textview, begin, end); } int ui_textarea_length(UiText *text) { @@ -208,6 +209,56 @@ void ui_textarea_remove(UiText *text, int begin, int end) { cursor.removeSelectedText(); } + +void ui_textarea_focus(UIWIDGET textarea) { + QTextEdit *edit = static_cast(textarea); + edit->setFocus(); +} + +void ui_textarea_set_selection(UIWIDGET textarea, int begin, int end) { + QTextEdit *edit = static_cast(textarea); + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(begin, QTextCursor::MoveAnchor); + cursor.setPosition(end, QTextCursor::KeepAnchor); + edit->setTextCursor(cursor); +} + +void ui_textarea_select_all(UIWIDGET textarea) { + QTextEdit *edit = static_cast(textarea); + edit->selectAll(); +} + +void ui_textarea_set_editable(UIWIDGET textarea, UiBool editable) { + QTextEdit *edit = static_cast(textarea); + edit->setReadOnly(!editable); +} + +UiBool ui_textarea_is_editable(UIWIDGET textarea) { + QTextEdit *edit = static_cast(textarea); + return !edit->isReadOnly(); +} + +void ui_textarea_set_position(UIWIDGET textarea, int pos) { + QTextEdit *edit = static_cast(textarea); + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(pos); + edit->setTextCursor(cursor); +} + +int ui_textarea_get_position(UIWIDGET textarea) { + QTextEdit *edit = static_cast(textarea); + QTextCursor cursor = edit->textCursor(); + return cursor.position(); +} + +void ui_textarea_scroll_to(UIWIDGET textarea, int pos) { + QTextEdit *edit = static_cast(textarea); + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(pos); + edit->setTextCursor(cursor); + edit->ensureCursorVisible(); +} + /* ------------------------------ TextField ------------------------------ */ static UIWIDGET create_textfield(UiObject *obj, UiTextFieldArgs *args, bool password, bool frameless) { diff --git a/ui/server/container.c b/ui/server/container.c index 17a64d4..1196feb 100644 --- a/ui/server/container.c +++ b/ui/server/container.c @@ -34,12 +34,12 @@ #include "args.h" void ui_container_begin_close(UiObject *obj) { - UiContainerX *ct = obj->container_end; + UiContainer *ct = obj->container_end; ct->close = 1; } int ui_container_finish(UiObject *obj) { - UiContainerX *ct = obj->container_end; + UiContainer *ct = obj->container_end; if(ct->close) { ui_end_new(obj); return 0; @@ -47,8 +47,8 @@ int ui_container_finish(UiObject *obj) { return 1; } -UiContainerX* ui_widget_container(UiWidget *w) { - UiContainerX *container = cxZalloc(w->obj->ctx->allocator, sizeof(UiContainerX)); +UiContainer* ui_widget_container(UiWidget *w) { + UiContainer *container = cxZalloc(w->obj->ctx->allocator, sizeof(UiContainer)); container->container = w; return container; } diff --git a/ui/server/container.h b/ui/server/container.h index dc7f3e9..4ddd08a 100644 --- a/ui/server/container.h +++ b/ui/server/container.h @@ -38,7 +38,7 @@ extern "C" { #endif -UiContainerX* ui_widget_container(UiWidget *w); +UiContainer* ui_widget_container(UiWidget *w); cxmutstr ui_container_args_to_string(UiContext *ctx, UiContainerArgs *args); diff --git a/ui/ui/button.h b/ui/ui/button.h index b9c56c4..83d6fd0 100644 --- a/ui/ui/button.h +++ b/ui/ui/button.h @@ -149,6 +149,19 @@ UIEXPORT UIWIDGET ui_linkbutton_create(UiObject *obj, UiLinkButtonArgs *args); UIEXPORT void ui_button_set_label(UIWIDGET button, const char *label); UIEXPORT void ui_button_set_icon(UIWIDGET button, const char *icon); +UIEXPORT void ui_button_set_tooltip(UIWIDGET button, const char *tooltip); + +UIEXPORT void ui_togglebutton_set_label(UIWIDGET button, const char *label); +UIEXPORT void ui_togglebutton_set_icon(UIWIDGET button, const char *icon); +UIEXPORT void ui_togglebutton_set_tooltip(UIWIDGET button, const char *tooltip); + +UIEXPORT void ui_checkbox_set_label(UIWIDGET button, const char *label); +UIEXPORT void ui_checkbox_set_icon(UIWIDGET button, const char *icon); +UIEXPORT void ui_checkbox_set_tooltip(UIWIDGET button, const char *tooltip); + +UIEXPORT void ui_radiobutton_set_label(UIWIDGET button, const char *label); +UIEXPORT void ui_radiobutton_set_icon(UIWIDGET button, const char *icon); +UIEXPORT void ui_radiobutton_set_tooltip(UIWIDGET button, const char *tooltip); UIEXPORT void ui_linkbutton_value_set(UiString *str, const char *label, const char *uri); UIEXPORT void ui_linkbutton_value_set_label(UiString *str, const char *label); diff --git a/ui/ui/container.h b/ui/ui/container.h index 49bc631..187f221 100644 --- a/ui/ui/container.h +++ b/ui/ui/container.h @@ -285,12 +285,12 @@ struct UiLayout { int rowspan; }; -struct UiContainerX { +struct UiContainer { void *container; UiBool close; UiBool newline; - UiContainerX *prev; - UiContainerX *next; + UiContainer *prev; + UiContainer *next; }; @@ -381,10 +381,6 @@ UIEXPORT void ui_newline(UiObject *obj); typedef void(*ui_addwidget_func)(UiObject *obj, UIWIDGET parent, UIWIDGET child, void *userdata); UIEXPORT void ui_custom_container_create(UiObject *obj, UIWIDGET widget, ui_addwidget_func add_child, void *userdata); -// TODO -UIEXPORT UiTabbedPane* ui_tabbed_document_view(UiObject *obj); -UIEXPORT UiObject* ui_document_tab(UiTabbedPane *view); - /* used for macro */ diff --git a/ui/ui/toolkit.h b/ui/ui/toolkit.h index 995c8c2..9cc79af 100644 --- a/ui/ui/toolkit.h +++ b/ui/ui/toolkit.h @@ -183,7 +183,6 @@ typedef bool UiBool; #endif typedef struct UiObject UiObject; -typedef struct UiContainerX UiContainerX; typedef struct UiEvent UiEvent; typedef struct UiMouseEvent UiMouseEvent; typedef struct UiObserver UiObserver; @@ -218,8 +217,6 @@ typedef struct UiDnD UiDnD; typedef struct UiThreadpool UiThreadpool; /* end opaque types */ -typedef struct UiTabbedPane UiTabbedPane; - typedef enum UiTri { UI_DEFAULT = 0, UI_ON, @@ -294,8 +291,8 @@ struct UiObject { * container list * TODO: remove old UiContainer and rename UiContainerX to UiContainer */ - UiContainerX *container_begin; - UiContainerX *container_end; + UiContainer *container_begin; + UiContainer *container_end; /* * next container object @@ -313,23 +310,6 @@ struct UiObject { unsigned int ref; }; -struct UiTabbedPane { - /* - * native widget - */ - UIWIDGET widget; - - /* - * current document - */ - void *document; - - /* - * parent context - */ - UiContext *ctx; -}; - struct UiEvent { UiObject *obj; void *document; @@ -407,7 +387,6 @@ struct UiText { int datatype; void *data1; void *data2; - // TODO: replacefunc, ... UiObserver *observers; }; @@ -574,8 +553,6 @@ UIEXPORT void ui_document_ref(void *doc); UIEXPORT void ui_document_unref(void *doc); UIEXPORT void ui_document_destroy(void *doc); -UIEXPORT void* ui_get_subdocument(void *document); // deprecated - UIEXPORT UiContext* ui_document_context(void *doc); UIEXPORT void* ui_context_document(UiContext *ctx); UIEXPORT UiObject* ui_context_obj(UiContext *ctx); @@ -766,6 +743,8 @@ UIEXPORT void* ui_object_get(UiObject *obj, const char *key); UIEXPORT void ui_app_ref(void); UIEXPORT void ui_app_unref(void); +UIEXPORT void ui_open_uri(const char *uri); + #ifdef __cplusplus } #endif