}
fn create_toolbar(app: &AppContext<MainWindow>) {
- app.toolbar_item("new_notebook").icon("folder-new").action("new_notebook").create();
- app.toolbar_item("go_back").icon("go-previous").action("go_back").create();
- app.toolbar_item("go_forward").icon("go-next").action("go_forward").create();
- app.toolbar_item("new_note").icon("document-new").action("new_note").create();
+ app.toolbar_item("new_notebook").icon(UiIconSet::NewFolder.as_str()).action("new_notebook").create();
+ app.toolbar_item("go_back").icon(UiIconSet::GoBack.as_str()).action("go_back").create();
+ 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("go_back", ToolbarItemPosition::Left);
--- /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 std::ffi::{c_char, CStr};
+use std::fmt::{Display, Formatter};
+
+#[repr(i32)]
+#[derive(Copy, Clone)]
+pub enum UiIconSet {
+ Home = 0,
+ NewWindow,
+ Refresh,
+ NewFolder,
+ Add,
+ Upload,
+ SaveLocal,
+ Delete,
+ DockLeft,
+ DockRight,
+ GoBack,
+ GoForward,
+ GoUp,
+ GoDown
+}
+
+impl UiIconSet {
+ pub fn as_str(self) -> &'static str {
+ let ptr = unsafe { ui_icon_name(self as i32) };
+ let cstr = unsafe { CStr::from_ptr(ptr) };
+ cstr.to_str().expect("ui_icon_name returned invalid UTF-8")
+ }
+}
+
+extern "C" {
+ fn ui_icon_name(id: i32) -> *const c_char ;
+}
\ No newline at end of file
mod menu;
mod toolbar;
mod label;
+mod icon;
pub use toolkit::*;
pub use event::*;
pub use list::*;
pub use toolbar::*;
pub use menu::*;
+pub use icon::*;
event.eventdatatype = UI_EVENT_DATA_LIST_SELECTION;
event.intval = 0;
event.set = ui_get_setop();
-
_onselection(&event, _onselectiondata);
}
}
data.onactivate = args->onactivate;
data.onactivatedata = args->onactivatedata;
data.onbuttonclick = args->onbuttonclick;
- data.onactivatedata = args->onbuttonclickdata;
+ data.onbuttonclickdata = args->onbuttonclickdata;
[data update:-1];
outline.dataSource = data;
[_sections removeAllObjects];
- CxIterator i = cxListIterator(_sublists);
- int index = 0;
- int rownum = 0;
- cx_foreach(UiSubList *, sl, i) {
- UiSourceListItem *section = [[UiSourceListItem alloc] init:self sublist:sl];
- section.sublistIndex = index;
- section.rownum = rownum;
- section.sublistStartRow = rownum;
- [section update:-1];
- [_sections addObject:section];
- index++;
- rownum += 1 + section.items.count;
+ if(_sublists) {
+ CxIterator i = cxListIterator(_sublists);
+ int index = 0;
+ int rownum = 0;
+ cx_foreach(UiSubList *, sl, i) {
+ UiSourceListItem *section = [[UiSourceListItem alloc] init:self sublist:sl];
+ section.sublistIndex = index;
+ section.rownum = rownum;
+ section.sublistStartRow = rownum;
+ [section update:-1];
+ [_sections addObject:section];
+ index++;
+ rownum += 1 + section.items.count;
+ }
+ } else if (_dynamic_sublists) {
+ UiList *sublists = _dynamic_sublists->value;
+ UiSubList *sl = sublists->first(sublists);
+ int index = 0;
+ int rownum = 0;
+ while(sl) {
+ UiSourceListItem *section = [[UiSourceListItem alloc] init:self sublist:sl];
+ section.sublistIndex = index;
+ section.rownum = rownum;
+ section.sublistStartRow = rownum;
+ [section update:-1];
+ [_sections addObject:section];
+ index++;
+ rownum += 1 + section.items.count;
+
+ sl = sublists->next(sublists);
+ }
}
[_outlineView reloadData];
--- /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.
+ */
+
+#include "icons.h"
+
+const char* ui_icon_name(enum UiIconId icon_id) {
+ switch(icon_id) {
+ case UI_ICON_ID_HOME : return UI_ICON_HOME;
+ case UI_ICON_ID_NEW_WINDOW : return UI_ICON_NEW_WINDOW;
+ case UI_ICON_ID_REFRESH : return UI_ICON_REFRESH;
+ case UI_ICON_ID_NEW_FOLDER : return UI_ICON_NEW_FOLDER;
+ case UI_ICON_ID_ADD : return UI_ICON_ADD;
+ case UI_ICON_ID_UPLOAD : return UI_ICON_UPLOAD;
+ case UI_ICON_ID_SAVE_LOCAL : return UI_ICON_SAVE_LOCAL;
+ case UI_ICON_ID_DELETE : return UI_ICON_DELETE;
+ case UI_ICON_ID_DOCK_LEFT : return UI_ICON_DOCK_LEFT;
+ case UI_ICON_ID_DOCK_RIGHT : return UI_ICON_DOCK_RIGHT;
+ case UI_ICON_ID_GO_BACK : return UI_ICON_GO_BACK;
+ case UI_ICON_ID_GO_FORWARD : return UI_ICON_GO_FORWARD;
+ case UI_ICON_ID_GO_UP : return UI_ICON_GO_UP;
+ case UI_ICON_ID_GO_DOWN : return UI_ICON_GO_DOWN;
+ }
+ return NULL;
+}
--- /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.
+ */
+
+#ifndef UIC_ICONS_H
+#define UIC_ICONS_H
+
+#include "../ui/icons.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UIC_ICONS_H */
+
COMMON_OBJ += wrapper$(OBJ_EXT)
COMMON_OBJ += utils$(OBJ_EXT)
COMMON_OBJ += message$(OBJ_EXT)
+COMMON_OBJ += icons$(OBJ_EXT)
TOOLKITOBJS += $(COMMON_OBJ:%=$(COMMON_OBJPRE)uic_%)
TOOLKITSOURCE += $(COMMON_OBJ:%$(OBJ_EXT)=common/%.c)
ui_call_mainthread(doc_unref, doc);
}
+static int app_unref(void *unused) {
+ ui_app_unref();
+ return 0;
+}
+
+void ui_mainthread_app_unref() {
+ ui_call_mainthread(app_unref, NULL);
+}
/* ---------------------------- UiList ---------------------------- */
UIEXPORT void ui_mainthread_object_unref(UiObject *obj);
UIEXPORT void ui_mainthread_document_unref(void *doc);
+UIEXPORT void ui_mainthread_app_unref();
UIEXPORT void* ui_list_get_data(UiList *list);
UIEXPORT void* ui_list_get_iter(UiList *list);
char *path = g_file_get_path(file);
if(!path) {
icon = ui_icon("application-x-generic", size);
+ } else {
+ g_free(path);
}
#else
if(!icon) {
GError *error = NULL;
char *path = g_file_get_path(file);
icon->pixbuf = gdk_pixbuf_new_from_file(path, &error);
+ g_free(path);
}
return icon->pixbuf;
}
} else if(type == UI_BOOL_EDITABLE) {
GtkWidget *checkbox = gtk_check_button_new();
gtk_list_item_set_child(item, checkbox);
- }else {
+ } else {
GtkWidget *label = gtk_label_new(NULL);
gtk_label_set_xalign(GTK_LABEL(label), 0);
gtk_list_item_set_child(item, label);
}
case UI_STRING: {
gtk_label_set_label(GTK_LABEL(child), data);
+ gtk_label_set_ellipsize(GTK_LABEL(child), PANGO_ELLIPSIZE_END);
if(freevalue) {
free(data);
}
#endif /* UI_GTK */
+#ifdef UI_QT
+#define UI_ICON_HOME "go-home"
+#define UI_ICON_NEW_WINDOW "list-add"
+#define UI_ICON_REFRESH "view-refresh"
+#define UI_ICON_NEW_FOLDER "folder-new"
+#define UI_ICON_ADD "document-new"
+#define UI_ICON_UPLOAD "document-open"
+#define UI_ICON_SAVE_LOCAL "document-save-as"
+#define UI_ICON_DELETE "edit-delete"
+#define UI_ICON_DOCK_LEFT ""
+#define UI_ICON_DOCK_RIGHT ""
+#define UI_ICON_GO_BACK "go-previous"
+#define UI_ICON_GO_FORWARD "go-next"
+#define UI_ICON_GO_UP "go-up"
+#define UI_ICON_GO_DOWN "go-down"
+
+#endif /* UI_QT */
#ifdef UI_WINUI
#endif /* UI_COCOA */
+#ifdef UI_MOTIF
+
+#define UI_ICON_HOME ""
+#define UI_ICON_NEW_WINDOW ""
+#define UI_ICON_REFRESH ""
+#define UI_ICON_NEW_FOLDER ""
+#define UI_ICON_ADD ""
+#define UI_ICON_UPLOAD ""
+#define UI_ICON_SAVE_LOCAL ""
+#define UI_ICON_DELETE ""
+#define UI_ICON_DOCK_LEFT ""
+#define UI_ICON_DOCK_RIGHT ""
+#define UI_ICON_GO_BACK ""
+#define UI_ICON_GO_FORWARD ""
+#define UI_ICON_GO_UP ""
+#define UI_ICON_GO_DOWN ""
+
+#endif /* UI_MOTIF */
+
+#ifdef UI_WIN32
+
+#define UI_ICON_HOME ""
+#define UI_ICON_NEW_WINDOW ""
+#define UI_ICON_REFRESH ""
+#define UI_ICON_NEW_FOLDER ""
+#define UI_ICON_ADD ""
+#define UI_ICON_UPLOAD ""
+#define UI_ICON_SAVE_LOCAL ""
+#define UI_ICON_DELETE ""
+#define UI_ICON_DOCK_LEFT ""
+#define UI_ICON_DOCK_RIGHT ""
+#define UI_ICON_GO_BACK ""
+#define UI_ICON_GO_FORWARD ""
+#define UI_ICON_GO_UP ""
+#define UI_ICON_GO_DOWN ""
+
+#endif /* UI_MOTIF */
+
+
+enum UiIconId {
+ UI_ICON_ID_HOME = 0,
+ UI_ICON_ID_NEW_WINDOW,
+ UI_ICON_ID_REFRESH,
+ UI_ICON_ID_NEW_FOLDER,
+ UI_ICON_ID_ADD,
+ UI_ICON_ID_UPLOAD,
+ UI_ICON_ID_SAVE_LOCAL,
+ UI_ICON_ID_DELETE,
+ UI_ICON_ID_DOCK_LEFT,
+ UI_ICON_ID_DOCK_RIGHT,
+ UI_ICON_ID_GO_BACK,
+ UI_ICON_ID_GO_FORWARD,
+ UI_ICON_ID_GO_UP,
+ UI_ICON_ID_GO_DOWN
+};
UIEXPORT UiIcon* ui_icon(const char* name, size_t size);
UIEXPORT UiIcon* ui_icon_unscaled(const char *name, int size);
UIEXPORT UiIcon* ui_fileicon(size_t size);
+UIEXPORT const char* ui_icon_name(enum UiIconId icon_id);
+
#ifdef __cplusplus
}
#endif