pub fn load_profile(
&self,
- profile_id: i32,
+ profile_id: Option<i32>,
host: &str,
user: &str,
) -> Result<usersettings::Model, DbErr> {
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::<usersettings::Model, DbErr>(model);
+ } else {
+ let err = format!("user settings {} not found", id);
+ return Err::<usersettings::Model, DbErr>(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()))
return Ok::<usersettings::Model, DbErr>(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()
let inserted = active.insert(&self.db).await?;
Ok::<usersettings::Model, DbErr>(inserted)
-
})?;
Ok(profile)
mod window;
mod backend;
+use std::env;
use ui_rs::{ui};
use ui_rs::ui::*;
use crate::backend::Backend;
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::<MainWindow>(&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<Backend, ErrMsg> {
+ 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,
}
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])
+ }
+}
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;
}
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;
*/
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) {
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);
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);
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);
}
}
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;
{
GtkWidget *sub = NULL;
GtkWidget *add = NULL;
- UiContainerX *container = NULL;
+ UiContainer *container = NULL;
switch(type) {
default: {
sub = ui_gtk_vbox_new(spacing);
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,
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) {
#endif
}
-UiContainerX* ui_grid_container(
+UiContainer* ui_grid_container(
UiObject *obj,
GtkWidget *grid,
UiBool def_hexpand,
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;
}
}
#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) {
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) {
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) {
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);
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);
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);
}
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);
}
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);
}
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);
}
static GtkWidget* create_tab(UiObject *obj, UiGtkTabView *tabview, const char *title, int tab) {
- UiContainerX *container;
+ UiContainer *container;
GtkWidget *sub;
switch(tabview->subcontainer) {
default: {
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) {
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;
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) {
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) {
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;
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;
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;
}
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);
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) {
typedef struct UiContainerPrivate UiContainerPrivate;
struct UiContainerPrivate {
- UiContainerX container;
+ UiContainer container;
GtkWidget *widget;
UIMENU menu;
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,
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);
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
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
+}
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++;
if(data->callback) {
data->callback(&evt, data->userdata);
}
+
+ ui_app_unref();
}
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));
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;
#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)
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);
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) {
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);
return grid;
}
-UiContainerX* ui_grid_container(
+UiContainer* ui_grid_container(
UiObject *obj,
Widget grid,
UiBool def_hexpand,
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) {
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 = {
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) {
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);
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;
}
-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) {
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;
struct UiContainerPrivate {
- UiContainerX container;
+ UiContainer container;
Widget (*prepare)(UiContainerPrivate*, UiLayout *layout, Arg *, int*);
void (*add)(UiContainerPrivate*, Widget);
Widget widget;
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,
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);
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;
}
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;
#include <QSplitter>
#include <QGroupBox>
-#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() {}
return textarea;
}
+UIWIDGET ui_textarea_gettextwidget(UIWIDGET textarea) {
+ return textarea;
+}
+
void ui_textarea_save(UiText *text) {
// NOOP
}
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) {
cursor.removeSelectedText();
}
+
+void ui_textarea_focus(UIWIDGET textarea) {
+ QTextEdit *edit = static_cast<QTextEdit*>(textarea);
+ edit->setFocus();
+}
+
+void ui_textarea_set_selection(UIWIDGET textarea, int begin, int end) {
+ QTextEdit *edit = static_cast<QTextEdit*>(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<QTextEdit*>(textarea);
+ edit->selectAll();
+}
+
+void ui_textarea_set_editable(UIWIDGET textarea, UiBool editable) {
+ QTextEdit *edit = static_cast<QTextEdit*>(textarea);
+ edit->setReadOnly(!editable);
+}
+
+UiBool ui_textarea_is_editable(UIWIDGET textarea) {
+ QTextEdit *edit = static_cast<QTextEdit*>(textarea);
+ return !edit->isReadOnly();
+}
+
+void ui_textarea_set_position(UIWIDGET textarea, int pos) {
+ QTextEdit *edit = static_cast<QTextEdit*>(textarea);
+ QTextCursor cursor = edit->textCursor();
+ cursor.setPosition(pos);
+ edit->setTextCursor(cursor);
+}
+
+int ui_textarea_get_position(UIWIDGET textarea) {
+ QTextEdit *edit = static_cast<QTextEdit*>(textarea);
+ QTextCursor cursor = edit->textCursor();
+ return cursor.position();
+}
+
+void ui_textarea_scroll_to(UIWIDGET textarea, int pos) {
+ QTextEdit *edit = static_cast<QTextEdit*>(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) {
#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;
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;
}
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);
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);
int rowspan;
};
-struct UiContainerX {
+struct UiContainer {
void *container;
UiBool close;
UiBool newline;
- UiContainerX *prev;
- UiContainerX *next;
+ UiContainer *prev;
+ UiContainer *next;
};
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 */
#endif
typedef struct UiObject UiObject;
-typedef struct UiContainerX UiContainerX;
typedef struct UiEvent UiEvent;
typedef struct UiMouseEvent UiMouseEvent;
typedef struct UiObserver UiObserver;
typedef struct UiThreadpool UiThreadpool;
/* end opaque types */
-typedef struct UiTabbedPane UiTabbedPane;
-
typedef enum UiTri {
UI_DEFAULT = 0,
UI_ON,
* 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
unsigned int ref;
};
-struct UiTabbedPane {
- /*
- * native widget
- */
- UIWIDGET widget;
-
- /*
- * current document
- */
- void *document;
-
- /*
- * parent context
- */
- UiContext *ctx;
-};
-
struct UiEvent {
UiObject *obj;
void *document;
int datatype;
void *data1;
void *data2;
- // TODO: replacefunc, ...
UiObserver *observers;
};
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);
UIEXPORT void ui_app_ref(void);
UIEXPORT void ui_app_unref(void);
+UIEXPORT void ui_open_uri(const char *uri);
+
#ifdef __cplusplus
}
#endif