//});
create_toolbar(app);
+ self.on_new_window(app);
+ }
+ fn on_new_window(&mut self, app: &AppContext<MainWindow>) {
create_window(self, app);
}
}
app.toolbar_item("go_forward").icon(UiIconSet::GoForward.as_str()).action("go_forward").create();
app.toolbar_item("new_note").icon(UiIconSet::Add.as_str()).action("new_note").create();
- app.toolbar_add_default("new_notebook", ToolbarItemPosition::SidebarRight);
+ app.toolbar_add_default("new_notebook", ToolbarItemPosition::SidebarLeft);
app.toolbar_add_default("go_back", ToolbarItemPosition::Left);
app.toolbar_add_default("go_forward", ToolbarItemPosition::Left);
app.toolbar_add_default("new_note", ToolbarItemPosition::Left);
+
+ app.toolbar_appmenu(|menu|{
+ menu.item("New Window").onclick(|f| new_app_window() ).create();
+ });
}
use std::marker::PhantomData;
use ui_rs_derive::UiModel;
use crate::ui::ffi::{UiCallback, UiEvent};
-use crate::ui::{dialog, toolkit, ui_global_context, UiActions, UiContext, UiModel};
+use crate::ui::{call_mainthread, dialog, toolkit, ui_call_mainthread, ui_global_context, UiActions, UiContext, UiModel};
pub trait Application<T: UiModel + UiActions> {
fn on_startup(&mut self, app: &AppContext<T>);
+ fn on_new_window(&mut self, app: &AppContext<T>) {}
+
fn on_exit(&mut self, _app: &AppContext<T>) { }
}
fn ui_main();
fn ui_onstartup(callback: UiCallback, userdata: *mut c_void);
+ fn ui_onnewwindow(callback: UiCallback, userdata: *mut c_void);
fn ui_onexit(callback: UiCallback, userdata: *mut c_void);
+
+ fn ui_newwindow();
}
extern "C" fn app_startup<T: UiModel + UiActions>(_event: *const UiEvent, data: *mut c_void) {
}
}
+extern "C" fn app_new_window<T: UiModel + UiActions>(_event: *const UiEvent, data: *mut c_void) {
+ unsafe {
+ let app_ptr = data as *mut AppWrapper<T>;
+ let app_ref: &mut AppWrapper<T> = &mut *app_ptr;
+ let global_ctx = toolkit::UiContext::from_ptr(ui_global_context());
+ let ctx = AppContext::<T> {
+ ctx: global_ctx,
+ _marker: PhantomData,
+ };
+ app_ref.app.on_new_window(&ctx);
+ }
+}
+
extern "C" fn app_exit<T: UiModel + UiActions>(_event: *const UiEvent, data: *mut c_void) {
unsafe {
let app_ptr = data as *mut AppWrapper<T>;
let ptr: *mut AppWrapper<T> = &mut wrapper;
let c_ptr: *mut c_void = ptr as *mut c_void;
ui_onstartup(Some(app_startup::<T>), c_ptr);
+ ui_onnewwindow(Some(app_new_window::<T>), c_ptr);
ui_onexit(Some(app_exit::<T>), c_ptr);
ui_main();
}
}
+pub fn new_app_window() {
+ unsafe {
+ call_mainthread(||{
+ ui_newwindow();
+ });
+ }
+}
+
struct ErrApp<'a> {
}
}
- pub fn toolbar_menuitem(&self, name: &str) -> ToolbarMenuItemBuilder<T> {
+ pub fn toolbar_menu(&self, name: &str) -> ToolbarMenuItemBuilder<T> {
unsafe {
ToolbarMenuItemBuilder {
args: ui_toolbar_menu_args_new(),
ui_toolbar_add_default(cstr.as_ptr(), pos as c_int);
}
}
+
+ pub fn toolbar_appmenu<F>(&self, f: F)
+ where F: FnOnce(&mut Menu<T>) {
+ unsafe {
+ let args = ui_toolbar_menu_args_new();
+ ui_toolbar_menu_create(std::ptr::null(), args);
+ ui_toolbar_menu_args_free(args);
+
+ let mut menu = Menu::<T> {
+ ctx: toolkit::ui_global_context(),
+ _marker: PhantomData
+ };
+ f(&mut menu);
+ ui_menu_end();
+ }
+ }
}
pub struct ToolbarItemBuilder<T: UiModel + UiActions> {
}
impl<T: UiModel + UiActions> ToolbarMenuItemBuilder<T> {
- pub fn create(&mut self) {
+ pub fn create<F>(&mut self, f: F)
+ where F: FnOnce(&mut Menu<T>) {
unsafe {
ui_toolbar_menu_create(self.name.as_ptr(), self.args);
+ let mut menu = Menu::<T> {
+ ctx: toolkit::ui_global_context(),
+ _marker: PhantomData
+ };
+ f(&mut menu);
+ ui_menu_end();
}
}
pub fn label(&mut self, label: &str) -> &mut Self {
void ui_tableview_update(UiList *list, int i) {
NSTableView *tableview = (__bridge NSTableView*)list->obj;
if(i < 0) {
+ [tableview deselectAll: tableview];
[tableview reloadData];
} else {
[tableview reloadData]; // TODO: optimize
static ui_callback startup_func;
static void *startup_data;
+static ui_callback newwindow_func;
+static void *newwindow_data;
static ui_callback open_func;
void *open_data;
static ui_callback exit_func;
startup_data = userdata;
}
+void ui_onnewwindow(ui_callback f, void *userdata) {
+ newwindow_func = f;
+ newwindow_data = userdata;
+}
+
void ui_onopen(ui_callback f, void *userdata) {
open_func = f;
open_data = userdata;
}
}
+void uic_application_newwindow(UiEvent *event) {
+ if(newwindow_func) {
+ newwindow_func(event, newwindow_data);
+ }
+}
+
void uic_application_open(UiEvent *event) {
if(open_func) {
open_func(event, open_data);
exit_func(event, exit_data);
}
}
+
+void ui_newwindow(void) {
+ uic_application_newwindow(NULL);
+}
#endif
void uic_application_startup(UiEvent *event);
+void uic_application_newwindow(UiEvent *event);
void uic_application_open(UiEvent *event);
void uic_application_exit(UiEvent *event);
return store;
}
+static void ui_destroy_tree_eventdata(GtkWidget *object, UiTreeEventData *data) {
+ free(data->activate_action);
+ free(data->selection_action);
+ free(data);
+}
UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) {
// create treeview
event->obj = obj;
event->activate = args->onactivate;
event->activatedata = args->onactivatedata;
+ event->activate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL;
event->selection = args->onselection;
event->selectiondata = args->onselectiondata;
+ event->selection_action = args->onselection_action ? strdup(args->onselection_action) : NULL;
g_signal_connect(
view,
"destroy",
- G_CALLBACK(ui_destroy_userdata),
+ G_CALLBACK(ui_destroy_tree_eventdata),
event);
-
- if(args->onactivate) {
+ if(args->onactivate || args->onactivate_action) {
g_signal_connect(
view,
"row-activated",
G_CALLBACK(ui_listview_activate_event),
event);
}
- if(args->onselection) {
+ if(args->onselection || args->onselection_action) {
GtkTreeSelection *selection = gtk_tree_view_get_selection(
GTK_TREE_VIEW(view));
g_signal_connect(
list->obj = tableview;
// add callback
- UiTreeEventData *event = ui_malloc(obj->ctx, sizeof(UiTreeEventData));
+ UiTreeEventData *event = malloc(sizeof(UiTreeEventData));
event->obj = obj;
event->activate = args->onactivate;
- event->selection = args->onselection;
event->activatedata = args->onactivatedata;
+ event->activate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL;
+ event->selection = args->onselection;
event->selectiondata = args->onselectiondata;
- if(args->onactivate) {
+ event->selection_action = args->onselection_action ? strdup(args->onselection_action) : NULL;
+ g_signal_connect(
+ view,
+ "destroy",
+ G_CALLBACK(ui_destroy_tree_eventdata),
+ event);
+ if(args->onactivate || args->onactivate_action) {
g_signal_connect(
view,
"row-activated",
G_CALLBACK(ui_listview_activate_event),
event);
}
- if(args->onselection) {
+ if(args->onselection || args->onselection_action) {
GtkTreeSelection *selection = gtk_tree_view_get_selection(
GTK_TREE_VIEW(view));
g_signal_connect(
G_CALLBACK(ui_listview_selection_event),
event);
}
- // TODO: destroy callback
-
if(args->ondragstart) {
ui_listview_add_dnd(tableview, args);
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.eventdata = &selection;
+ e.eventdatatype = UI_EVENT_DATA_LIST_SELECTION;
e.intval = selection.count > 0 ? selection.rows[0] : -1;
e.set = ui_get_setop();
- event->activate(&e, event->activatedata);
- if(selection.count > 0) {
- free(selection.rows);
+ if(event->activate) {
+ event->activate(&e, event->activatedata);
+ }
+ if(event->activate_action) {
+ uic_action_callback(&e, event->activate_action);
}
+
+ free(selection.rows);
}
void ui_listview_selection_event(
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.eventdata = &selection;
+ e.eventdatatype = UI_EVENT_DATA_LIST_SELECTION;
e.intval = selection.count > 0 ? selection.rows[0] : -1;
e.set = ui_get_setop();
- event->selection(&e, event->selectiondata);
-
- if(selection.count > 0) {
- free(selection.rows);
+ if(event->selection) {
+ event->selection(&e, event->selectiondata);
}
+ if(event->selection_action) {
+ uic_action_callback(&e, event->selection_action);
+ }
+
+ free(selection.rows);
}
UiListSelection ui_listview_get_selection(
ui_callback selection;
void *activatedata;
void *selectiondata;
+ char *activate_action;
+ char *selection_action;
} UiTreeEventData;
typedef struct UiListBox UiListBox;
UIEXPORT int ui_object_unref(UiObject *obj);
UIEXPORT void ui_onstartup(ui_callback f, void *userdata);
+UIEXPORT void ui_onnewwindow(ui_callback f, void *userdata);
UIEXPORT void ui_onopen(ui_callback f, void *userdata);
UIEXPORT void ui_onexit(ui_callback f, void *userdata);
+UIEXPORT void ui_newwindow(void);
+
UIEXPORT int ui_app_save_settings(void);
UIEXPORT void ui_app_exit_on_shutdown(UiBool exitapp);