all: $(UI_LIB) $(UI_SHLIB)
+include common/Makefile
include $(TOOLKIT)/Makefile
-
-$(COMMON_OBJPRE)uic_%$(OBJ_EXT): common/%.c
- $(CC) -o $@ -c -I../ucx/ $(CFLAGS) $(SHLIB_CFLAGS) $(TK_CFLAGS) $<
-
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2024 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 "../ui/toolkit.h"
+#include "../common/context.h"
+#include "../common/object.h"
+
+@interface AppDelegate : NSObject <NSApplicationDelegate>
+
+
+@end
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2024 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.
+ */
+
+#import "AppDelegate.h"
+#import "WindowManager.h"
+
+#import "toolkit.h"
+#import "menu.h"
+
+#import "../common/app.h"
+
+@implementation AppDelegate
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ NSLog(@"toolkit applicationDidFinishLaunching");
+ uic_application_startup(NULL);
+ // The menu init func can be called multiple times and is also called
+ // when a new window is created
+ // The only usecase for calling init here is, that an application might not
+ // open a window on startup, but wants a working menubar
+ ui_menu_init();
+}
+
+- (void)applicationWillTerminate:(NSNotification *)aNotification {
+ NSLog(@"toolkit applicationWillTerminate");
+ uic_application_exit(NULL);
+ [[WindowManager sharedWindowManager] shutdown];
+ ui_app_save_settings();
+}
+
+
+- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app {
+ return YES;
+}
+
+
+@end
* POSSIBILITY OF SUCH DAMAGE.
*/
-#import "Container.h"
+#import "container.h"
#import "GridLayout.h"
@interface BoxContainer : GridLayout
#import "../ui/toolkit.h"
#import "../common/context.h"
-typedef void(*get_eventdata_func)(id sender, UiVar *var, void **eventdata, int *value);
+typedef void(*get_eventdata_func)(id sender, UiVar *var, void **eventdata, UiEventType *eventdatatype, int *value);
@interface EventData : NSObject
@property UiObject *obj;
@property int vartype;
@property ui_callback callback;
@property void *userdata;
+@property NSString *action;
@property void *data;
@property int value;
@property get_eventdata_func get_eventdata;
-- (EventData*)init:(ui_callback)cb userdata:(void*)userdata;
+- (EventData*)init:(ui_callback)cb userdata:(void*)userdata action:(const char*)action;
- (void)handleEvent:(id)sender;
*/
#import "EventData.h"
+#import "action.h"
#import <objc/runtime.h>
@implementation EventData
-- (EventData*)init:(ui_callback)cb userdata:(void*)userdata {
+- (EventData*)init:(ui_callback)cb userdata:(void*)userdata action:(const char*)action {
_callback = cb;
_userdata = userdata;
+ if(action != nil) {
+ _action = [[NSString alloc]initWithUTF8String:action];
+ }
return self;
}
- (void)handleEvent:(id)sender {
- if(_callback) {
- UiEvent event;
- event.obj = self.obj;
- event.window = event.obj->window;
- event.document = event.obj->ctx->document;
- event.eventdata = self.data;
- event.intval = self.value;
- event.set = ui_get_setop();
+ UiEvent event;
+ event.obj = self.obj;
+ event.window = event.obj->window;
+ event.document = event.obj->ctx->document;
+ event.eventdata = self.data;
+ event.intval = self.value;
+ event.set = ui_get_setop();
+
+ if(_callback != nil) {
self.callback(&event, self.userdata);
}
+
+ if(_action != nil) {
+ uic_action_callback(&event, self.action.UTF8String);
+ }
}
- (void)handleEventWithEventData:(id)sender {
event.intval = 0;
event.set = ui_get_setop();
if(_get_eventdata) {
- _get_eventdata(sender, _var, &event.eventdata, &event.intval);
+ _get_eventdata(sender, _var, &event.eventdata, &event.eventdatatype, &event.intval);
}
if(self.callback) {
self.callback(&event, self.userdata);
#import "toolkit.h"
-#import "Container.h"
+#import "container.h"
#import <cx/array_list.h>
@interface GridLayout : NSView<Container>
-@property UiContainerX *container;
+@property UiContainer *container;
@property int columnspacing;
@property int rowspacing;
@property UiObject *obj;
@property ui_callback onselection;
@property void *onselectiondata;
+@property NSString *onselection_action;
@property ui_callback onactivate;
@property void *onactivatedata;
+@property NSString *onactivate_action;
- (id)init:(NSTableView*) tableview obj:(UiObject*)obj;
- (void)activateEvent:(id)sender {
NSTableView *table = sender;
+
+ int row = (int)table.clickedRow;
+
+ UiListSelection sel;
+ sel.count = 1;
+ sel.rows = &row;
+
+ UiEvent event;
+ event.obj = _obj;
+ event.window = event.obj->window;
+ event.document = event.obj->ctx->document;
+ event.eventdata = &sel;
+ event.eventdatatype = UI_EVENT_DATA_LIST_SELECTION;
+ event.intval = row;
+ event.set = ui_get_setop();
+
if(_onactivate) {
- int row = (int)table.clickedRow;
-
- UiListSelection sel;
- sel.count = 1;
- sel.rows = &row;
-
- UiEvent event;
- event.obj = _obj;
- event.window = event.obj->window;
- event.document = event.obj->ctx->document;
- event.eventdata = &sel;
- event.eventdatatype = UI_EVENT_DATA_LIST_SELECTION;
- event.intval = row;
- event.set = ui_get_setop();
-
_onactivate(&event, _onactivatedata);
}
+
+ if(_onselection_action) {
+ uic_action_callback(&event, _onselection_action.UTF8String);
+ }
}
- (void) tableViewSelectionDidChange:(NSNotification *) notification {
- if(_onselection) {
+ if(ui_selection_events_is_enabled()) {
UiListSelection sel = ui_tableview_selection(_tableview);
- UiEvent event;
+ UiEvent event;
event.obj = _obj;
event.window = event.obj->window;
event.document = event.obj->ctx->document;
event.intval = 0;
event.set = ui_get_setop();
- _onselection(&event, _onselectiondata);
+ if(_onselection) {
+ _onselection(&event, _onselectiondata);
+ }
+
+ if(_onselection_action) {
+ uic_action_callback(&event, _onselection_action.UTF8String);
+ }
}
}
#import "toolkit.h"
#import "../ui/window.h"
-@interface MainWindow : NSWindow<UiToplevelObject>
+@interface MainWindow : NSWindow<UiToplevelObject, NSWindowDelegate>
@property UiObject *obj;
@property (strong) NSSplitView *splitview;
@property (strong) NSView *rightPanel;
@property int topOffset;
-- (MainWindow*)init:(UiObject*)obj withSidebar:(BOOL)hasSidebar withSplitview:(BOOL)hasSplitview;
+- (MainWindow*)init:(UiObject*)obj withSidebar:(BOOL)hasSidebar withSplitview:(BOOL)hasSplitview width:(int)width height:(int)height;
+- (void) saveWindowSize;
@end
*/
#import "MainWindow.h"
-#import "Container.h"
+#import "WindowManager.h"
+#import "container.h"
#import "GridLayout.h"
#import "BoxContainer.h"
#import "../common/object.h"
#import "menu.h"
#import "Toolbar.h"
+
+
@implementation MainWindow
-- (MainWindow*)init:(UiObject*)obj withSidebar:(BOOL)hasSidebar withSplitview:(BOOL)hasSplitview{
- NSRect frame = NSMakeRect(300, 200, 600, 500);
+- (MainWindow*)init:(UiObject*)obj withSidebar:(BOOL)hasSidebar withSplitview:(BOOL)hasSplitview width:(int)width height:(int)height {
+ NSRect frame = NSMakeRect(300, 200, width, height);
self = [self initWithContentRect:frame
styleMask:NSWindowStyleMaskTitled |
backing:NSBackingStoreBuffered
defer:false];
_obj = obj;
-
+ self.delegate = self;
int top = 4;
NSView *content = self.contentView;
[vbox.trailingAnchor constraintEqualToAnchor:content.trailingAnchor],
[vbox.bottomAnchor constraintEqualToAnchor:content.bottomAnchor],
]];
- UiContainerX *container = ui_create_container(obj, vbox);
+ UiContainer *container = ui_create_container(obj, vbox);
vbox.container = container;
uic_object_push_container(obj, container);
}
[self setToolbar:toolbar];
}
-
return self;
}
+- (void) saveWindowSize {
+ CGSize size = self.frame.size;
+ if(size.width > 0 && size.height > 0) {
+ char width_str[32];
+ char height_str[32];
+ snprintf(width_str, 32, "%d", (int)size.width);
+ snprintf(height_str, 32, "%d", (int)size.height);
+ ui_set_property("ui.window.width", width_str);
+ ui_set_property("ui.window.height", height_str);
+ }
+}
+
- (BOOL) getIsVisible {
return [self isVisible];
}
}
}
+- (void) windowWillClose:(NSNotification *) notification {
+ UiObject *obj = _obj;
+
+ if(obj->onclose) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ event.obj = obj;
+ event.window = obj->window;
+ event.document = obj->ctx->document;
+ obj->onclose(&event, obj->onclosedata);
+ }
+
+ if(obj->ref > 0) {
+ obj->ref--;
+ } else {
+ // warn about invalid reference counting
+ NSLog(@"Error: UiObject %p ref == 0\n", obj);
+ }
+
+ if(obj->ref == 0) {
+ [self saveWindowSize];
+ // this cleans up any widget references from the context
+ uic_context_prepare_close(obj->ctx);
+ [[WindowManager sharedWindowManager] closeWindow:self];
+ }
+}
+- (void) dealloc {
+ uic_object_destroy(_obj);
+ NSLog(@"MainWindow dealloc");
+}
@end
* POSSIBILITY OF SUCH DAMAGE.
*/
-#import "Container.h"
+#import "container.h"
@protocol TabView
UiObject *newobj = uic_object_new_toplevel();
newobj->widget = (__bridge void*)sub;
- UiContainerX *container = ui_create_container(newobj, sub);
+ UiContainer *container = ui_create_container(newobj, sub);
uic_object_push_container(newobj, container);
return newobj;
NSMutableArray<NSString*> *defaultItems;
}
-@property MainWindow *window;
+@property (weak) MainWindow *window;
@property UiObject *obj;
- (UiToolbar*) initWithWindow:(MainWindow*)window;
}
+static void toolitem_set_enabled(void *item, int enabled) {
+ NSToolbarItem *i = (__bridge NSToolbarItem*)item;
+ i.enabled = enabled;
+}
+static void toolitem_bind_action(UiContext *ctx, NSToolbarItem *item, const char *action) {
+ if(action) {
+ void *widget = (__bridge void*)item;
+ uic_bind_action(ctx, action, widget, (ui_enablefunc)toolitem_set_enabled);
+ UiAction *ui_action = uic_resolve_action(ctx, action);
+ if(!ui_action) {
+ toolitem_set_enabled(widget, FALSE);
+ }
+ }
+}
/* --------------------- UiToolbar --------------------- */
button.image = ui_cocoa_named_icon(item->args.icon);
}
- if(item->args.onclick) {
- EventData *event = [[EventData alloc] init:item->args.onclick userdata:item->args.onclickdata];
+ if(item->args.onclick || item->args.action) {
+ EventData *event = [[EventData alloc] init:item->args.onclick userdata:item->args.onclickdata action:item->args.action];
event.obj = obj;
button.target = event;
button.action = @selector(handleEvent:);
objc_setAssociatedObject(button, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
+
+ toolitem_bind_action(obj->ctx, button, item->args.action);
}
return button;
}
}
objc_setAssociatedObject(button, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
- NSSegmentedControl *seg;
+ NSSegmentedControl *seg = nil;
if(!item->args.icon) {
- NSArray *labels = @[[[NSString alloc] initWithUTF8String:item->args.label]];
- seg = [NSSegmentedControl segmentedControlWithLabels:labels trackingMode:NSSegmentSwitchTrackingSelectAny target:event action:@selector(handleEvent:)];
- button.view = seg;
+ if(item->args.label) {
+ NSArray *labels = @[[[NSString alloc] initWithUTF8String:item->args.label]];
+ seg = [NSSegmentedControl segmentedControlWithLabels:labels trackingMode:NSSegmentSwitchTrackingSelectAny target:event action:@selector(handleEvent:)];
+ button.view = seg;
+ } else {
+ NSLog(@"UI Error: toggle button has no icon or label");
+ }
} else {
- NSArray *images = @[ui_cocoa_named_icon(item->args.icon)];
- seg = [NSSegmentedControl segmentedControlWithImages:images trackingMode:NSSegmentSwitchTrackingSelectAny target:event action:@selector(handleEvent:)];
+ NSImage *image = ui_cocoa_named_icon(item->args.icon);
+ if(image != nil) {
+ NSArray *images = @[image];
+ seg = [NSSegmentedControl segmentedControlWithImages:images trackingMode:NSSegmentSwitchTrackingSelectAny target:event action:@selector(handleEvent:)];
+ } else {
+ NSLog(@"UI Error: icon %s not found", item->args.icon);
+ }
}
button.view = seg;
}
i->obj = (__bridge void*)seg;
- printf("seg: %p\n", seg);
i->get = ui_toolbar_seg_toggleitem_get;
i->set = ui_toolbar_seg_toggleitem_set;
}
#import "toolkit.h"
-@interface WindowManager : NSObject<NSWindowDelegate>
+@interface WindowManager : NSObject
-@property NSMutableArray<NSWindow*> *windows;
+@property NSMutableArray<NSWindowController*> *windows;
+ (WindowManager*) sharedWindowManager;
- (WindowManager*)init;
-- (void)addWindow:(NSWindow*)win;
+- (void)addWindow:(NSWindowController*)win;
+
+- (void)closeWindow:(NSWindow*)win;
+
+- (void)shutdown;
@end
*/
#import "WindowManager.h"
+#import "MainWindow.h"
@implementation WindowManager
return self;
}
-- (void)addWindow:(NSWindow*)win {
+- (void)addWindow:(NSWindowController*)win {
[_windows addObject:win];
- [win setDelegate:self];
}
-- (void) windowWillClose:(NSNotification *) notification {
- NSWindow *window = notification.object;
- [_windows removeObject:window];
+- (void)closeWindow:(NSWindow*)win {
+ [_windows removeObject:win.windowController];
+}
+
+- (void)shutdown {
+ if(_windows.count > 0) {
+ NSWindowController *controller = _windows.firstObject;
+ MainWindow *win = (MainWindow*)controller.window;
+ [win saveWindowSize];
+ }
+ [_windows removeAllObjects];
}
@end
--- /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 "../ui/toolkit.h"
+#include "../common/action.h"
+
+#import "widget.h"
+
+void ui_cocoa_view_bind_action(UiContext *ctx, NSView *view, const char *action);
--- /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 "action.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+
+/* ------------------------------ public API ------------------------------ */
+
+void ui_add_action(UiContext *ctx, const char *name, ui_callback callback, void *userdata) {
+ uic_add_action(ctx, name, callback, userdata, NULL, NULL);
+}
+
+void ui_add_action_with_accelerator(
+ UiContext *ctx,
+ const char *name,
+ ui_callback callback,
+ void *userdata,
+ const char *accelerator,
+ const char *accelerator_text)
+{
+ uic_add_action(ctx, name, callback, userdata, accelerator, accelerator_text);
+
+ // TODO: accelerator
+}
+
+
+void ui_cocoa_view_bind_action(UiContext *ctx, NSView *view, const char *action) {
+ if(action) {
+ void *widget = (__bridge void*)view;
+ uic_bind_action(ctx, action, widget, (ui_enablefunc)ui_set_enabled);
+ UiAction *ui_action = uic_resolve_action(ctx, action);
+ if(!ui_action) {
+ ui_set_enabled(widget, FALSE);
+ }
+ }
+}
#import "button.h"
#import "EventData.h"
-#import "Container.h"
+#import "container.h"
#import "image.h"
+#import "action.h"
#import <objc/runtime.h>
#import <cx/buffer.h>
button.image = ui_cocoa_named_icon(args->icon);;
}
- if(args->onclick) {
- EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata];
+ if(args->onclick || args->action) {
+ EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata action:args->action];
event.obj = obj;
button.target = event;
button.action = @selector(handleEvent:);
objc_setAssociatedObject(button, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
+
+ ui_cocoa_view_bind_action(obj->ctx, button, args->action);
}
UiLayout layout = UI_INIT_LAYOUT(args);
}
-static void togglebutton_eventdata(id button, UiVar *var, void **eventdata, int *value) {
+static void togglebutton_eventdata(id button, UiVar *var, void **eventdata, UiEventType *eventdatatype, int *value) {
NSButton *btn = (NSButton*)button;
NSControlStateValue state = btn.state;
*value = (int)state;
i->set = ui_togglebutton_set;
}
- if(args->onchange) {
- EventData *event = [[EventData alloc] init:args->onchange userdata:args->onchangedata];
+ if(args->onchange || args->action) {
+ EventData *event = [[EventData alloc] init:args->onchange userdata:args->onchangedata action:args->action];
event.get_eventdata = togglebutton_eventdata;
event.obj = obj;
event.var = var;
button.target = event;
button.action = @selector(handleEventWithEventData:);
objc_setAssociatedObject(button, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
+
+ ui_cocoa_view_bind_action(obj->ctx, button, args->action);
}
UiLayout layout = UI_INIT_LAYOUT(args);
return togglebutton_create(obj, args, NSButtonTypeSwitch);
}
-static void switch_eventdata(id button, UiVar *var, void **eventdata, int *value) {
+static void switch_eventdata(id button, UiVar *var, void **eventdata, UiEventType *eventdatatype, int *value) {
NSSwitch *btn = (NSSwitch*)button;
NSControlStateValue state = btn.state;
*value = (int)state;
i->set = ui_switch_set;
}
- if(args->onchange) {
- EventData *event = [[EventData alloc] init:args->onchange userdata:args->onchangedata];
+ if(args->onchange || args->action) {
+ EventData *event = [[EventData alloc] init:args->onchange userdata:args->onchangedata action:args->action];
event.get_eventdata = switch_eventdata;
event.obj = obj;
event.var = var;
button.target = event;
button.action = @selector(handleEventWithEventData:);
objc_setAssociatedObject(button, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
+ ui_cocoa_view_bind_action(obj->ctx, button, args->action);
}
UiLayout layout = UI_INIT_LAYOUT(args);
@end
-static void radiobutton_eventdata(id button, UiVar *var, void **eventdata, int *value) {
+static void radiobutton_eventdata(id button, UiVar *var, void **eventdata, UiEventType *eventdatatype, int *value) {
if(var) {
- UiInteger *value = var->value;
- NSMutableArray *buttons = (__bridge NSMutableArray*)value->obj;
+ UiInteger *i = var->value;
+ NSMutableArray *buttons = (__bridge NSMutableArray*)i->obj;
for(UiRadioButton *b in buttons) {
if(b != button) {
b.direct_state = YES;
objc_setAssociatedObject(button, "radiogroup", buttons, OBJC_ASSOCIATION_RETAIN);
}
- if(args->onchange || var) {
- EventData *event = [[EventData alloc] init:args->onchange userdata:args->onchangedata];
+ if(args->onchange || args->action || var) {
+ EventData *event = [[EventData alloc] init:args->onchange userdata:args->onchangedata action:args->action];
event.get_eventdata = radiobutton_eventdata;
event.obj = obj;
event.var = var;
event.vartype = UI_VAR_INTEGER;
button.target = event;
-
button.action = @selector(handleEventWithEventData:);
objc_setAssociatedObject(button, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
+
+ ui_cocoa_view_bind_action(obj->ctx, button, args->action);
}
UiLayout layout = UI_INIT_LAYOUT(args);
CxJsonWriter writer = cxJsonWriterCompact();
CxBuffer buf;
- cxBufferInit(&buf, NULL, 128, NULL, CX_BUFFER_AUTO_EXTEND);
+ cxBufferInit(&buf, NULL, NULL, 128, CX_BUFFER_AUTO_EXTEND);
cxJsonWrite(&buf, obj, (cx_write_func)cxBufferWrite, &writer);
cxJsonValueFree(obj);
cxBufferTerminate(&buf);
@protocol Container
-@property UiContainerX *container;
+@property UiContainer *container;
- (void) addView:(NSView*)view layout:(UiLayout*)layout;
@end
-UiContainerX* ui_create_container(UiObject *obj, id<Container> container);
+UiContainer* ui_create_container(UiObject *obj, id<Container> container);
void ui_container_add(UiObject *obj, NSView *view, UiLayout *layout);
* POSSIBILITY OF SUCH DAMAGE.
*/
-#import "Container.h"
+#import "container.h"
#import "GridLayout.h"
#import "BoxContainer.h"
#import "TabView.h"
static UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs *args, NSUserInterfaceLayoutOrientation orientation) {
BoxContainer *box = [[BoxContainer alloc] init:orientation spacing:args->spacing];
box.translatesAutoresizingMaskIntoConstraints = false;
- UiContainerX *container = ui_create_container(obj, box);
+ UiContainer *container = ui_create_container(obj, box);
// add box to the parent
UiLayout layout = UI_INIT_LAYOUT(args);
grid.translatesAutoresizingMaskIntoConstraints = false;
grid.columnspacing = args->columnspacing;
grid.rowspacing = args->rowspacing;
- UiContainerX *container = ui_create_container(obj, grid);
+ UiContainer *container = ui_create_container(obj, grid);
grid.container = container;
// add box to the parent
ui_container_add(obj, frame, &layout);
// add container to the chain
- UiContainerX *container;
+ UiContainer *container;
UiLayout subLayout = {0};
switch(args->subcontainer) {
default: {
UiLayout layout = UI_ARGS2LAYOUT(args);
ui_container_add(obj, scrollview, &layout);
- UiContainerX *container = ui_create_container(obj, scrollview);
+ UiContainer *container = ui_create_container(obj, scrollview);
uic_object_push_container(obj, container);
return (__bridge void*)scrollview;
}
+static int64_t tabview_get(UiInteger *i) {
+ NSView<TabView, Container> *tabview = (__bridge id)i->obj;
+ return 0;
+}
+
+static void tabview_set(UiInteger *i, int64_t value) {
+ NSView<TabView, Container> *tabview = (__bridge id)i->obj;
+
+}
+
UIWIDGET ui_tabview_create(UiObject *obj, UiTabViewArgs *args) {
NSView<TabView, Container> *tabview;
switch(args->tabview) {
UiLayout layout = UI_ARGS2LAYOUT(args);
ui_container_add(obj, tabview, &layout);
- UiContainerX *container = ui_create_container(obj, tabview);
+ UiContainer *container = ui_create_container(obj, tabview);
uic_object_push_container(obj, container);
return (__bridge void*)tabview;
}
void ui_tab_create(UiObject *obj, const char* title) {
- UiContainerX *ctn = obj->container_end;
+ UiContainer *ctn = obj->container_end;
id<TabView> tabview = (__bridge id<TabView>)ctn->container;
NSString *s = title ? [[NSString alloc]initWithUTF8String:title] : @"";
NSView<Container> *sub = [tabview createTab:-1 title:s];
- UiContainerX *container = ui_create_container(obj, sub);
+ UiContainer *container = ui_create_container(obj, sub);
uic_object_push_container(obj, container);
}
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;
/* ------------------------- private functions ------------------------- */
-UiContainerX* ui_create_container(UiObject *obj, id<Container> container) {
- UiContainerX *ctn = ui_malloc(obj->ctx, sizeof(UiContainerX));
+UiContainer* ui_create_container(UiObject *obj, id<Container> container) {
+ UiContainer *ctn = ui_malloc(obj->ctx, sizeof(UiContainer));
ctn->container = (__bridge void*)container;
ctn->close = 0;
ctn->prev = NULL;
}
void ui_container_add(UiObject *obj, NSView *view, UiLayout *layout) {
- UiContainerX *ctn = obj->container_end;
+ UiContainer *ctn = obj->container_end;
id<Container> container = (__bridge id<Container>)ctn->container;
UiLayout adjustedLayout = *layout;
if(adjustedLayout.margin > 0) {
*/
#import "toolkit.h"
-#import "Container.h"
+#import "container.h"
#import "../ui/entry.h"
#include "../ui/image.h"
-#include "Container.h"
+#include "container.h"
typedef struct UiImage {
void *nsimage;
NSImage* ui_cocoa_named_icon(const char *name) {
NSString *imageName = [[NSString alloc] initWithUTF8String:name];
- NSString *imgName = [standardIconNames objectForKey:imageName];
- if(imgName) {
- imageName = imgName;
- }
- return [NSImage imageNamed:imageName];
+ //NSString *imgName = [standardIconNames objectForKey:imageName];
+ //if(imgName) {
+ // imageName = imgName;
+ //}
+ //return [NSImage imageNamed:imageName];
+ return [NSImage imageWithSystemSymbolName:imageName accessibilityDescription:nil];
}
static UIIMAGE create_image(NSImage *image) {
*/
#import "label.h"
-#import "Container.h"
+#import "container.h"
#import <string.h>
*/
#import "toolkit.h"
-#import "Container.h"
+#import "container.h"
#import "../ui/list.h"
#import "ListDataSource.h"
ListDelegate *delegate = [[ListDelegate alloc] init:tableview obj:obj];
delegate.onactivate = args->onactivate;
delegate.onactivatedata = args->onactivatedata;
+ if(args->onactivate_action) {
+ delegate.onactivate_action = [[NSString alloc]initWithUTF8String:args->onactivate_action];
+ }
delegate.onselection = args->onselection;
delegate.onselectiondata = args->onselectiondata;
+ if(args->onselection_action) {
+ delegate.onselection_action = [[NSString alloc]initWithUTF8String:args->onselection_action];
+ }
tableview.delegate = delegate;
objc_setAssociatedObject(tableview, "ui_listdelegate", delegate, OBJC_ASSOCIATION_RETAIN);
tableview.doubleAction = @selector(activateEvent:);
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
event.eventdatatype = UI_EVENT_DATA_LIST_ELM;
event.intval = index;
- if(_onselection) {
+ if(_onselection && ui_selection_events_is_enabled()) {
_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];
UiMenuItem *it = (UiMenuItem*)item;
NSString *str = [[NSString alloc] initWithUTF8String:it->label];
- NSMenuItem *menuItem = [parent addItemWithTitle:str action:@selector(menuItemAction) keyEquivalent:@""];
+ NSMenuItem *menuItem = [parent addItemWithTitle:str action:@selector(menuItemAction:) keyEquivalent:@""];
if(it->callback) {
- EventData *event = [[EventData alloc] init:it->callback userdata:it->userdata];
+ EventData *event = [[EventData alloc] init:it->callback userdata:it->userdata action:it->action];
if(obj) {
event.obj = obj;
menuItem.target = event;
}
+static BOOL menu_is_initialized = NO;
+
void ui_menu_init(void) {
- bindingItems = [[NSMutableArray alloc] init];
-
UiMenu *menus_begin = uic_get_menu_list();
UiMenu *ls = menus_begin;
+
+ if(menu_is_initialized || !ls) {
+ return;
+ }
+ menu_is_initialized = YES;
+
+ bindingItems = [[NSMutableArray alloc] init];
+
int index = 1;
while(ls) {
if(ls->item.type == UI_MENU) {
COCOAOBJ += MainWindow.o
COCOAOBJ += WindowManager.o
COCOAOBJ += window.o
-COCOAOBJ += Container.o
+COCOAOBJ += container.o
COCOAOBJ += button.o
COCOAOBJ += text.o
COCOAOBJ += menu.o
COCOAOBJ += image.o
COCOAOBJ += entry.o
COCOAOBJ += TabView.o
+COCOAOBJ += action.o
TOOLKITOBJS += $(COCOAOBJ:%=$(COCOA_OBJPRE)%)
TOOLKITSOURCE += $(COCOAOBJ:%.o=cocoa/%.m)
void ui_textarea_set(UiText *text, const char *str);
char* ui_textarea_get(UiText *text);
char* ui_textarea_getsubstr(UiText *text, int begin, int end);
-void ui_textarea_insert(UiText *text, int pos, char *str);
+void ui_textarea_insert(UiText *text, int pos, const char *str);
void ui_textarea_setposition(UiText *text, int pos);
int ui_textarea_position(UiText *text);
void ui_textarea_setselection(UiText *text, int begin, int end);
char* ui_textfield_get(UiString *s);
void ui_textfield_set(UiString *s, const char *value);
+
+
+@interface TextAreaDelegate: NSObject<NSTextViewDelegate, NSTextDelegate>
+
+@property UiObject *obj;
+@property UiVar *var;
+@property ui_callback onchange;
+@property void *onchangedata;
+@property NSString *onchange_action;
+@property ui_callback ontextchanged;
+@property void *ontextchangeddata;
+@property NSString *ontextchanged_action;
+
+- (id)init:(UiObject*)obj var:(UiVar*)var args:(UiTextAreaArgs*)args;
+
+@end
+
+@interface TextFieldDelegate : NSObject<NSTextFieldDelegate>
+
+@property UiObject *obj;
+@property UiVar *var;
+@property ui_callback onchange;
+@property void *onchangedata;
+@property NSString *onchange_action;
+
+- (id)init:(UiObject*)obj var:(UiVar*)var;
+
+@end
#import "text.h"
#import "EventData.h"
-#import "Container.h"
+#import "container.h"
+#import "action.h"
#import <objc/runtime.h>
UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs *args) {
scrollview.hasVerticalScroller = YES;
scrollview.documentView = textview;
+ // store link to the textview
+ // associate it with the textview and the scrollview to support both widgets in ui_textarea_gettextwidget
+ objc_setAssociatedObject(textview, "ui_textarea", textview, OBJC_ASSOCIATION_ASSIGN);
+ objc_setAssociatedObject(scrollview, "ui_textarea", textview, OBJC_ASSOCIATION_ASSIGN);
+
UiLayout layout = UI_INIT_LAYOUT(args);
ui_container_add(obj, scrollview, &layout);
text->remove = ui_textarea_remove;
}
+ if(args->onchange || args->ontextchanged || args->onchange_action || args->ontextchanged_action) {
+ TextAreaDelegate * tad = [[TextAreaDelegate alloc] init:obj var:var args:args];
+ textview.delegate = tad;
+ objc_setAssociatedObject(textview, "delegate", tad, OBJC_ASSOCIATION_RETAIN);
+ }
+
return (__bridge void*)scrollview;
}
+UIWIDGET ui_textarea_gettextwidget(UIWIDGET textarea) {
+ id view = (__bridge id)textarea;
+ id textview = objc_getAssociatedObject(view, "ui_textarea");
+ return (__bridge void*)textview;
+}
+void ui_textarea_focus(UIWIDGET textarea) {
+ textarea = ui_textarea_gettextwidget(textarea);
+ if(!textarea) {
+ fprintf(stderr, "Error: ui_textarea_focus: widget is not a textarea\n");
+ return;
+ }
+ NSTextView *view = (__bridge NSTextView*)textarea;
+ [view.window makeFirstResponder:view];
+}
+
+void ui_textarea_set_selection(UIWIDGET textarea, int begin, int end) {
+ textarea = ui_textarea_gettextwidget(textarea);
+ if(!textarea) {
+ fprintf(stderr, "Error: ui_textarea_set_selection: widget is not a textarea\n");
+ return;
+ }
+ NSTextView *view = (__bridge NSTextView*)textarea;
+ NSRange range = NSMakeRange(begin, end-begin);
+ [view setSelectedRange:range];
+}
+
+void ui_textarea_select_all(UIWIDGET textarea) {
+ textarea = ui_textarea_gettextwidget(textarea);
+ if(!textarea) {
+ fprintf(stderr, "Error: ui_textarea_select_all: widget is not a textarea\n");
+ return;
+ }
+}
+
+void ui_textarea_set_editable(UIWIDGET textarea, UiBool editable) {
+ textarea = ui_textarea_gettextwidget(textarea);
+ if(!textarea) {
+ fprintf(stderr, "Error: ui_textarea_set_editable: widget is not a textarea\n");
+ return;
+ }
+ NSTextView *view = (__bridge NSTextView*)textarea;
+ view.editable = editable;
+}
+
+UiBool ui_textarea_is_editable(UIWIDGET textarea) {
+ textarea = ui_textarea_gettextwidget(textarea);
+ if(!textarea) {
+ fprintf(stderr, "Error: ui_textarea_is_editable: widget is not a textarea\n");
+ return 0;
+ }
+ NSTextView *view = (__bridge NSTextView*)textarea;
+ return view.isEditable;
+}
+
+void ui_textarea_set_position(UIWIDGET textarea, int pos) {
+ textarea = ui_textarea_gettextwidget(textarea);
+ if(!textarea) {
+ fprintf(stderr, "Error: ui_textarea_set_position: widget is not a textarea\n");
+ return;
+ }
+ NSTextView *view = (__bridge NSTextView*)textarea;
+ NSRange range = NSMakeRange(pos, 0);
+ [view setSelectedRange:range];
+}
+
+int ui_textarea_get_position(UIWIDGET textarea) {
+ textarea = ui_textarea_gettextwidget(textarea);
+ if(!textarea) {
+ fprintf(stderr, "Error: ui_textarea_get_position: widget is not a textarea\n");
+ return 0;
+ }
+ NSTextView *view = (__bridge NSTextView*)textarea;
+ NSRange range = view.selectedRange;
+ return (int)range.location;
+}
+
+void ui_textarea_scroll_to(UIWIDGET textarea, int pos) {
+ textarea = ui_textarea_gettextwidget(textarea);
+ if(!textarea) {
+ fprintf(stderr, "Error: ui_textarea_scroll_to: widget is not a textarea\n");
+ return;
+ }
+ NSTextView *view = (__bridge NSTextView*)textarea;
+ NSRange range = NSMakeRange(pos, 0);
+ [view scrollRangeToVisible:range];
+}
+
+
+// UiText textarea functions
void ui_textarea_save(UiText *text) {
return strdup(sub.UTF8String);
}
-void ui_textarea_insert(UiText *text, int pos, char *str) {
+void ui_textarea_insert(UiText *text, int pos, const char *str) {
NSTextView *textview = (__bridge NSTextView*)text->obj;
NSString *s = [[NSString alloc] initWithUTF8String:str];
NSAttributedString *attributedStr = [[NSAttributedString alloc] initWithString:s];
+@implementation TextAreaDelegate
+
+- (id)init:(UiObject*)obj var:(UiVar*)var args:(UiTextAreaArgs*)args {
+ self.onchange = args->onchange;
+ self.onchangedata = args->onchangedata;
+ if(args->onchange_action) {
+ self.onchange_action = [[NSString alloc]initWithUTF8String:args->onchange_action];
+ }
+ self.ontextchanged = args->ontextchanged;
+ self.ontextchangeddata = args->ontextchangeddata;
+ if(args->ontextchanged_action) {
+ self.ontextchanged_action = [[NSString alloc]initWithUTF8String:args->ontextchanged_action];
+ }
+ self.obj = obj;
+ self.var = var;
+ return self;
+}
+
+- (BOOL) textView:(NSTextView *) textView
+ shouldChangeTextInRange:(NSRange) affectedCharRange
+ replacementString:(NSString *) replacementString {
+
+ if(_onchange == nil && _onchange_action == nil) {
+ return YES;
+ }
+
+ UiEvent event;
+ event.obj = _obj;
+ event.window = event.obj->window;
+ event.document = event.obj->ctx->document;
+ event.intval = 0;
+ event.set = ui_get_setop();
+ // event data not set yet
+
+ if(affectedCharRange.length > 0) {
+ UiTextChangeEventData eventdata;
+ eventdata.type = UI_TEXT_DELETE;
+ eventdata.begin = (int)affectedCharRange.location;
+ eventdata.end = (int)(affectedCharRange.location + affectedCharRange.length);
+ eventdata.text = NULL;
+ eventdata.length = 0;
+
+ event.eventdata = &eventdata;
+ event.eventdatatype = UI_EVENT_DATA_TEXT_CHANGED;
+
+ if(_onchange) {
+ _onchange(&event, _onchangedata);
+ }
+
+ if(_onchange_action) {
+ uic_action_callback(&event, _onchange_action.UTF8String);
+ }
+ }
+
+ if(replacementString.length > 0) {
+ UiTextChangeEventData eventdata;
+ eventdata.type = UI_TEXT_INSERT;
+ eventdata.begin = (int)affectedCharRange.location;
+ eventdata.end = 0;
+ eventdata.text = replacementString.UTF8String;
+ eventdata.length = (int)replacementString.length;
+
+ event.eventdata = &eventdata;
+ event.eventdatatype = UI_EVENT_DATA_TEXT_CHANGED;
+
+ if(_onchange) {
+ _onchange(&event, _onchangedata);
+ }
+
+ if(_onchange_action) {
+ uic_action_callback(&event, _onchange_action.UTF8String);
+ }
+ }
+
+ return YES;
+}
+
+- (void) textDidChange:(NSNotification *) notification {
+ UiEvent event;
+ event.obj = _obj;
+ event.window = event.obj->window;
+ event.document = event.obj->ctx->document;
+ if(_var) {
+ event.eventdata = _var->value;
+ event.eventdatatype = UI_EVENT_DATA_TEXT_VALUE;
+ } else {
+ event.eventdata = NULL;
+ event.eventdatatype = 0;
+ }
+ event.intval = 0;
+ event.set = ui_get_setop();
+
+ if(_ontextchanged) {
+ _ontextchanged(&event, _ontextchangeddata);
+ }
+
+ if(_ontextchanged_action) {
+ uic_action_callback(&event, _ontextchanged_action.UTF8String);
+ }
+}
+
+@end
+
+
/* -------------------------- TextField -------------------------- */
+static void textfield_geteventdata(id sender, UiVar *var, void **eventdata, UiEventType *eventdatatype, int *value) {
+
+}
+
static UIWIDGET textfield_create(UiObject *obj, UiTextFieldArgs *args, BOOL password, BOOL frameless) {
NSTextField *textfield;
if(password) {
s->set = ui_textfield_set;
}
+ if(args->onactivate || args->onactivate_action) {
+ EventData *event = [[EventData alloc] init:args->onactivate userdata:args->onactivatedata action:args->onactivate_action];
+ event.get_eventdata = textfield_geteventdata;
+ event.obj = obj;
+ textfield.target = event;
+ textfield.action = @selector(handleEventWithEventData:);
+ objc_setAssociatedObject(textfield, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
+ ui_cocoa_view_bind_action(obj->ctx, textfield, args->onactivate_action);
+ }
+
+ if(args->onchange || args->onchange_action) {
+ TextFieldDelegate *tfd = [[TextFieldDelegate alloc]init:obj var:var];
+ tfd.onchange = args->onchange;
+ tfd.onchangedata = args->onchangedata;
+ if(args->onchange_action) {
+ tfd.onchange_action = [[NSString alloc]initWithUTF8String:args->onchange_action];
+ }
+ objc_setAssociatedObject(textfield, "delegate", tfd, OBJC_ASSOCIATION_RETAIN);
+ textfield.delegate = tfd;
+ }
+
return (__bridge void*)textfield;
}
NSTextField *textfield = (__bridge NSTextField*)s->obj;
textfield.stringValue = [[NSString alloc] initWithUTF8String:value];
}
+
+/* -------------------------- public Textfield functions -------------------------- */
+
+void ui_textfield_focus(UIWIDGET textfield) {
+ NSTextField *tf = (__bridge NSTextField*)textfield;
+ [tf.window makeFirstResponder:tf];
+ [tf selectText:nil];
+}
+
+void ui_textfield_focus_without_selecting(UIWIDGET textfield) {
+ NSTextField *tf = (__bridge NSTextField*)textfield;
+ [tf.window makeFirstResponder:tf];
+}
+
+void ui_textfield_set_selection(UIWIDGET textfield, int begin, int end) {
+ NSTextField *tf = (__bridge NSTextField*)textfield;
+ [tf.window makeFirstResponder:tf];
+ NSTextView *fieldEditor = (NSTextView *)[tf.window fieldEditor:YES forObject:tf];
+ [fieldEditor setSelectedRange:NSMakeRange(begin, end-begin)];
+}
+
+void ui_textfield_select_all(UIWIDGET textfield) {
+ NSTextField *tf = (__bridge NSTextField*)textfield;
+ [tf selectText:nil];
+}
+
+void ui_textfield_set_editable(UIWIDGET textfield, UiBool editable) {
+ NSTextField *tf = (__bridge NSTextField*)textfield;
+ tf.editable = editable;
+}
+
+UiBool ui_textfield_is_editable(UIWIDGET textfield) {
+ NSTextField *tf = (__bridge NSTextField*)textfield;
+ return tf.isEditable;
+}
+
+void ui_textfield_set_position(UIWIDGET textfield, int pos) {
+ NSTextField *tf = (__bridge NSTextField*)textfield;
+ NSTextView *editor = (NSTextView *)[tf currentEditor];
+ [editor setSelectedRange:NSMakeRange(pos, 0)];
+}
+
+int ui_textfield_get_position(UIWIDGET textfield) {
+ NSTextField *tf = (__bridge NSTextField*)textfield;
+ NSTextView *editor = (NSTextView *)[tf currentEditor];
+ NSRange selectedRange = [editor selectedRange];
+ return (int)selectedRange.location;
+}
+
+
+/* -------------------- textfield delegate -------------------- */
+
+@implementation TextFieldDelegate
+
+- (id)init:(UiObject*)obj var:(UiVar*)var {
+ self.obj = obj;
+ self.var = var;
+ return self;
+}
+
+- (void)controlTextDidChange:(NSNotification *)obj {
+ UiString *value = _var ? _var->value : NULL;
+
+ UiEvent e;
+ e.obj = _obj;
+ e.window = e.obj->window;
+ e.document = e.obj->ctx->document;
+ e.eventdata = value;
+ e.eventdatatype = value ? UI_EVENT_DATA_STRING_VALUE : 0;
+ e.intval = 0;
+ e.set = ui_get_setop();
+
+ if(_onchange) {
+ _onchange(&e, _onchangedata);
+ }
+
+ if(_var) {
+ ui_notify_evt(value->observers, &e);
+ }
+
+ if(_onchange_action) {
+ uic_action_callback(&e, _onchange_action.UTF8String);
+ }
+}
+
+@end
@end
-void ui_cocoa_onstartup(void);
-void ui_cocoa_onopen(const char *file);
-void ui_cocoa_onexit(void);
#import "toolkit.h"
+#include <stdlib.h>
+#include <string.h>
+
#include "../common/document.h"
#include "../common/properties.h"
#include "../common/menu.h"
static int app_argc;
static const char **app_argv;
-static UiBool exit_on_shutdown;
+static UiBool exit_on_shutdown;
+
+static char *main_thread_error_msg;
+
+// This function is only used by language bindings, to improve error messages
+// for example, when using java bindings, this can provide infos how to fix
+// this (-XstartOnFirstThread)
+void ui_set_main_thread_error_msg(const char *msg) {
+ main_thread_error_msg = msg ? strdup(msg) : NULL;
+}
/* ------------------- App Init / Event Loop functions ------------------- */
+static AppDelegate *app_delegate;
+
+static void main_thr_check(const char *func) {
+ if(![NSThread isMainThread]) {
+ fprintf(stderr, "Error: %s must run on the main thread.\n", func);
+ if(main_thread_error_msg) {
+ fprintf(stderr, "%s\n", main_thread_error_msg);
+ }
+ exit(1);
+ }
+}
void ui_init(const char *appname, int argc, char **argv) {
- application_name = appname;
+ main_thr_check("ui_init");
+
+ application_name = appname ? strdup(appname) : NULL;
app_argc = argc;
app_argv = (const char**)argv;
uic_init_global_context();
-
+
uic_menu_init();
uic_toolbar_init();
-
+
uic_load_app_properties();
-
+
NSApplication *app = [NSApplication sharedApplication];
- //[app setActivationPolicy:NSApplicationActivationPolicyRegular];
+ [app setActivationPolicy:NSApplicationActivationPolicyRegular];
//[NSBundle loadNibNamed:@"MainMenu" owner:NSApp ];
//[[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:NSApp topLevelObjects:&topLevelObjects];
+ app_delegate = [[AppDelegate alloc] init];
+
+ fflush(stdout);
+ app.delegate = app_delegate;
+
+
ui_icon_init();
ui_toolbar_init();
}
-const char* ui_appname() {
+const char* ui_appname(void) {
return application_name;
}
exit_on_shutdown = exitapp;
}
-void ui_cocoa_onstartup(void) {
- UiEvent e;
- e.obj = NULL;
- e.window = NULL;
- e.document = NULL;
- e.eventdata = NULL;
- e.intval = 0;
- uic_application_startup(&e);
+void ui_main(void) {
+ main_thr_check("ui_main");
+
+ NSApplicationMain(app_argc,app_argv);
+ //[NSApp finishLaunching];
+ //[NSApp activateIgnoringOtherApps:YES];
+ //[NSApp run];
+ if(exit_on_shutdown) {
+ exit(0);
+ }
}
-void ui_cocoa_onopen(const char *file) {
- UiEvent e;
- e.obj = NULL;
- e.window = NULL;
- e.document = NULL;
- e.eventdata = NULL;
- e.intval = 0;
- uic_application_open(&e);
+void ui_app_ref(void) {
+ // TODO
}
-void ui_cocoa_onexit(void) {
- UiEvent e;
- e.obj = NULL;
- e.window = NULL;
- e.document = NULL;
- e.eventdata = NULL;
- e.intval = 0;
- uic_application_exit(&e);
+void ui_app_unref(void) {
+ // TODO
}
-void ui_main(void) {
- NSApplicationMain(app_argc, app_argv);
- if(exit_on_shutdown) {
- exit(0);
- }
+void ui_app_quit(void) {
+ [[NSApplication sharedApplication] terminate:nil];
+}
+
+void ui_open_uri(const char *uri) {
+ NSString *urlString = [NSString stringWithUTF8String:uri];
+ NSURL *url = [NSURL URLWithString:urlString];
+ [[NSWorkspace sharedWorkspace] openURL:url];
}
/* ------------------- Window Visibility functions ------------------- */
@end
void ui_call_mainthread(ui_threadfunc tf, void* td) {
+ if(uic_mainthread_calls_is_buffered()) {
+ uic_add_buffered_mainthread_call(tf, td);
+ return;
+ }
+
UiAppCallback *cb = [[UiAppCallback alloc]initWithCallback:tf userdata:td];
[cb callMainThread];
}
data->webview = (__bridge void*)webview;
data->javascript = TRUE;
data->zoom = 1;
- value->value = value;
+ value->value = data;
}
}
*/
#import "toolkit.h"
-#import "Container.h"
+#import "container.h"
#import "../ui/widget.h"
view.hidden = !visible;
}
+void ui_widget_set_size(UIWIDGET w, int width, int height) {
+ NSView *view = (__bridge NSView*)w;
+ NSRect frame = view.frame;
+ frame.size.width = width;
+ frame.size.height = height;
+ view.frame = frame;
+}
+
UIWIDGET ui_separator_create(UiObject *obj, UiWidgetArgs *args) {
// TODO
#import "WindowManager.h"
#import "BoxContainer.h"
#import "EventData.h"
+#import "menu.h"
#import <objc/runtime.h>
#include "../common/menu.h"
#include "../common/toolbar.h"
#include "../common/object.h"
+#include "../common/utils.h"
#include <cx/mempool.h>
static int splitview_window_default_pos = -1;
static UiBool splitview_window_use_prop = TRUE;
+static void main_window_destroy(UiObject *obj) {
+ MainWindow *window = (__bridge MainWindow*)obj->wobj;
+ [window saveWindowSize];
+ [[WindowManager sharedWindowManager] closeWindow:window];
+}
+
static UiObject* create_window(const char *title, BOOL simple, BOOL sidebar, BOOL splitview) {
+ ui_menu_init();
UiObject *obj = uic_object_new_toplevel();
- MainWindow *window = [[MainWindow alloc] init:obj withSidebar:sidebar withSplitview:splitview];
- [[WindowManager sharedWindowManager] addWindow:window];
- window.releasedWhenClosed = false; // TODO: we still need a cleanup strategy
+ int width = window_default_width;
+ int height = window_default_height;
+ if(!simple) {
+ ui_get_window_default_width(&width, &height);
+ }
+
+ MainWindow *window = [[MainWindow alloc] init:obj withSidebar:sidebar withSplitview:splitview width:width height:height];
obj->wobj = (__bridge void*)window;
+ obj->destroy = main_window_destroy;
MainWindowController *controller = [[MainWindowController alloc] initWithWindow:obj window:window];
window.windowController = controller;
[window setNextResponder:(NSResponder*)controller];
- objc_setAssociatedObject(window, "windowcontroller", controller, OBJC_ASSOCIATION_RETAIN);
+ [[WindowManager sharedWindowManager] addWindow:controller];
return obj;
}
window_default_height = height;
}
+/* ------------------------------- SplitView Window-------------------------------- */
+
+void ui_splitview_window_set_pos(UiObject *obj, int pos) {
+ MainWindow *window = (__bridge MainWindow*)obj->wobj;
+ int divider = window.sidebar != nil ? 1 : 0;
+ [window.splitview setPosition:pos ofDividerAtIndex:divider];
+}
+
+int ui_splitview_window_get_pos(UiObject *obj) {
+ MainWindow *window = (__bridge MainWindow*)obj->wobj;
+ int divider = window.sidebar != nil ? 1 : 0;
+ return window.splitview.subviews[divider].frame.size.width;
+}
+
+void ui_splitview_window_set_default_pos(int pos) {
+ splitview_window_default_pos = pos;
+}
+
+void ui_splitview_window_use_property(UiBool enable) {
+ splitview_window_use_prop = enable;
+}
+
+void ui_splitview_window_set_visible(UiObject *obj, int pane, UiBool visible) {
+ MainWindow *window = (__bridge MainWindow*)obj->wobj;
+ if(pane >= 0 && pane < 2) {
+ window.splitview.subviews[pane].hidden = visible;
+ }
+}
+
/* --------------------------------- File Dialogs --------------------------------- */
void ui_openfiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata) {
NSWindowStyleMaskUtilityWindow)
backing:NSBackingStoreBuffered
defer:NO];
+ NSWindowController *controller = [[NSWindowController alloc] initWithWindow:panel];
+ panel.windowController = controller;
panel.parent = (__bridge NSWindow*)parent->wobj;
panel.obj = obj;
panel.modal = args->modal;
panel.onclick = args->onclick;
panel.onclickdata = args->onclickdata;
[panel center];
- [[WindowManager sharedWindowManager] addWindow:panel];
+ [[WindowManager sharedWindowManager] addWindow:controller];
obj->wobj = (__bridge void*)panel;
NSView *content = panel.contentView;
[lbutton1.leadingAnchor constraintEqualToAnchor:buttonArea.leadingAnchor constant:0]
]];
- EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata];
+ EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata action:nil];
event.obj = obj;
event.value = 1;
lbutton1.target = event;
[lbutton2.leadingAnchor constraintEqualToAnchor:anchor constant:off]
]];
- EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata];
+ EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata action:nil];
event.obj = obj;
event.value = 2;
lbutton2.target = event;
[rbutton4.trailingAnchor constraintEqualToAnchor:buttonArea.trailingAnchor constant:0]
]];
- EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata];
+ EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata action:nil];
event.obj = obj;
event.value = 2;
rbutton4.target = event;
[rbutton3.trailingAnchor constraintEqualToAnchor:anchor constant:off]
]];
- EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata];
+ EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata action:nil];
event.obj = obj;
event.value = 2;
rbutton3.target = event;
[vbox.bottomAnchor constraintEqualToAnchor:buttonArea.topAnchor constant:0]
]];
- UiContainerX *container = ui_create_container(obj, vbox);
+ UiContainer *container = ui_create_container(obj, vbox);
vbox.container = container;
uic_object_push_container(obj, container);
--- /dev/null
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2012 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.
+#
+
+FORCE:
+
+$(COMMON_OBJPRE)uic_action$(OBJ_EXT): common/action.c common/action.h \
+ common/../ui/toolkit.h common/context.h common/object.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_app$(OBJ_EXT): common/app.c common/app.h \
+ common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_args$(OBJ_EXT): common/args.c common/args.h \
+ common/../ui/window.h common/../ui/toolkit.h common/../ui/container.h \
+ common/../ui/display.h common/../ui/button.h common/../ui/entry.h \
+ common/../ui/menu.h common/../ui/toolbar.h common/../ui/list.h \
+ common/../ui/text.h common/../ui/webview.h common/../ui/widget.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_condvar$(OBJ_EXT): common/condvar.c common/condvar.h \
+ common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_container$(OBJ_EXT): common/container.c \
+ common/container.h common/../ui/container.h common/../ui/toolkit.h \
+ common/object.h common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_context$(OBJ_EXT): common/context.c common/context.h \
+ common/../ui/toolkit.h common/action.h common/../ui/window.h \
+ common/../ui/toolkit.h common/../ui/widget.h common/document.h \
+ common/types.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_document$(OBJ_EXT): common/document.c \
+ common/document.h common/../ui/toolkit.h common/context.h \
+ common/action.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_icons$(OBJ_EXT): common/icons.c common/icons.h \
+ common/../ui/icons.h common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_menu$(OBJ_EXT): common/menu.c common/menu.h \
+ common/../ui/menu.h common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_message$(OBJ_EXT): common/message.c common/message.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_object$(OBJ_EXT): common/object.c common/object.h \
+ common/../ui/toolkit.h common/context.h common/action.h \
+ common/../ui/container.h common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_properties$(OBJ_EXT): common/properties.c \
+ common/../ui/toolkit.h common/properties.h common/../ui/properties.h \
+ common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_threadpool$(OBJ_EXT): common/threadpool.c \
+ common/threadpool.h common/../ui/toolkit.h common/context.h \
+ common/action.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_toolbar$(OBJ_EXT): common/toolbar.c common/toolbar.h \
+ common/../ui/toolbar.h common/../ui/toolkit.h common/menu.h \
+ common/../ui/menu.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_types$(OBJ_EXT): common/types.c common/../ui/list.h \
+ common/../ui/toolkit.h common/types.h common/../ui/toolkit.h \
+ common/context.h common/action.h common/../ui/image.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_utils$(OBJ_EXT): common/utils.c common/utils.h \
+ common/../ui/toolkit.h common/../ui/text.h common/../ui/toolkit.h \
+ common/properties.h common/../ui/properties.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_wrapper$(OBJ_EXT): common/wrapper.c common/wrapper.h \
+ common/../ui/toolkit.h common/../ui/list.h common/../ui/toolkit.h \
+ common/../ui/text.h common/types.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
--- /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 "action.h"
+#include "context.h"
+#include "object.h"
+
+#include <cx/string.h>
+
+void uic_add_action(
+ UiContext *ctx,
+ const char *name,
+ ui_callback callback,
+ void *userdata,
+ const char *accelerator,
+ const char *accelerator_text)
+{
+ if(!name) {
+ return;
+ }
+
+ UiAction action;
+ action.name = ui_strdup(ctx, name);
+ action.callback = callback;
+ action.userdata = userdata;
+ action.accelerator = accelerator ? ui_strdup(ctx, accelerator) : NULL;
+ action.accelerator_text = accelerator_text ? ui_strdup(ctx, accelerator_text) : NULL;
+ action.ctx = ctx;
+ cxMapPut(ctx->actions, name, &action);
+ cxMapRehash(ctx->actions);
+}
+
+void uic_bind_action(
+ UiContext *ctx,
+ const char *action,
+ void *bind_obj,
+ ui_enablefunc set_enabled)
+{
+ if(!action) {
+ return;
+ }
+
+ UiActionBinding binding;
+ binding.action = ui_strdup(ctx, action);
+ binding.userdata = bind_obj;
+ binding.set_enabled = set_enabled;
+ cxListAdd(ctx->action_bindings, &binding);
+}
+
+UiAction* uic_resolve_action(UiContext *ctx, const char *action) {
+ UiAction *a = NULL;
+ if(ctx->actions) {
+ a = cxMapGet(ctx->actions, action);
+ }
+ // check if any sub-document defines this action
+ // sub-document actions have precedence, the most specific action will
+ // be returned
+ CxIterator i = cxListIterator(ctx->documents);
+ cx_foreach(void *, doc, i) {
+ UiContext *doc_ctx = ui_document_context(doc);
+ UiAction *sub_action = uic_resolve_action(doc_ctx, action);
+ if(sub_action) {
+ a = sub_action;
+ // if one sub-tree has an action, we don't care about other
+ // subtrees
+ break;
+ }
+ }
+
+ if(!a && ctx->parent) {
+ // check parents
+ a = uic_resolve_action_from_parents(ctx, action);
+ }
+
+ return a;
+}
+
+UiAction* uic_resolve_action_from_parents(UiContext *ctx, const char *action) {
+ UiContext *parent = ctx->parent;
+ if(parent == NULL) {
+ return NULL;
+ }
+ if(parent->actions) {
+ UiAction *a = cxMapGet(parent->actions, action);
+ if(a) {
+ return a;
+ }
+ }
+ return uic_resolve_action_from_parents(parent, action);
+}
+
+
+
+void ui_update_action_bindings(UiContext *ctx) {
+ CxIterator i = cxListIterator(ctx->action_bindings);
+ cx_foreach(UiActionBinding*, binding, i) {
+ UiAction *action = uic_resolve_action(ctx, binding->action);
+ if(binding->set_enabled) {
+ binding->set_enabled(binding->userdata, action != NULL);
+ }
+ }
+}
+
+void uic_action_callback(UiEvent *event, const char *action_name) {
+ UiContext *ctx = ui_global_context();
+ if(event->obj) {
+ ctx = event->obj->ctx;
+ }
+
+ UiAction *action = uic_resolve_action(ctx, action_name);
+ if(action) {
+ // override event document: for actions we know that the event is
+ // for a specific document
+ event->document = action->ctx->self_doc;
+ if(action->callback) {
+ action->callback(event, action->userdata);
+ }
+ }
+}
+
+static int call_action(UiContext *ctx, const char *action_name, void *eventdata, UiEventType eventdatatype, int intval) {
+ UiAction *action = uic_resolve_action(ctx, action_name);
+ if(action && action->callback) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ event.obj = ctx->obj;
+ event.window = event.obj ? event.obj->window : NULL;
+ event.document = ctx->self_doc ? ctx->self_doc : ctx->document;
+ if(eventdata) {
+ event.eventdata = eventdata;
+ event.eventdatatype = eventdatatype;
+ }
+ event.intval = intval;
+ action->callback(&event, action->userdata);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+int ui_call_action(UiContext *ctx, const char *action_name) {
+ return ui_call_action2(ctx, action_name, NULL, 0);
+}
+
+int ui_call_action2(UiContext *ctx, const char *action_name, void *eventdata, int intval) {
+ return call_action(ctx, action_name, eventdata, UI_EVENT_DATA_POINTER, intval);
+}
+
+int ui_call_action3(UiContext *ctx, const char *action_name, void *ptr, uint64_t type_id) {
+ UiTypedObj *obj = malloc(sizeof(UiTypedObj));
+ obj->ptr = ptr;
+ obj->type = type_id;
+ int ret = call_action(ctx, action_name, obj, UI_EVENT_DATA_TYPED_OBJECT, 0);
+ free(obj);
+ return ret;
+}
+
+static void call_action_recursive(const char *action_name, UiContext *ctx, void *eventdata, UiEventType eventdatatype, int intval, UiBool call_children) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ event.obj = ctx->obj;
+ event.window = event.obj ? event.obj->window : NULL;
+ event.document = ctx->self_doc ? ctx->self_doc : ctx->document;
+ if(eventdata) {
+ event.eventdata = eventdata;
+ event.eventdatatype = eventdatatype;
+ }
+ event.intval = intval;
+
+ UiAction *a = NULL;
+ if(ctx->actions) {
+ a = cxMapGet(ctx->actions, action_name);
+ }
+ if(a && a->callback) {
+ a->callback(&event, a->userdata);
+ }
+
+ if(call_children) {
+ CxIterator i = cxListIterator(ctx->documents);
+ cx_foreach(void *, doc, i) {
+ UiContext *doc_ctx = ui_document_context(doc);
+ call_action_recursive(action_name, doc_ctx, eventdata, eventdatatype, intval, TRUE);
+ }
+ }
+}
+
+static void broadcast_action(const char *action_name, void *eventdata, UiEventType eventdatatype, int intval) {
+ CxList *objects = uic_object_list();
+ CxIterator i = cxListIterator(objects);
+ cx_foreach(UiObject*, obj, i) {
+ call_action_recursive(action_name, obj->ctx, eventdata, eventdatatype, intval, TRUE);
+ }
+
+ call_action_recursive(action_name, ui_global_context(), eventdata, eventdatatype, intval, FALSE);
+}
+
+void ui_broadcast_action(const char *action_name) {
+ broadcast_action(action_name, NULL, UI_EVENT_DATA_NULL, 0);
+}
+
+void ui_broadcast_action2(const char *action_name, void *eventdata, int intval) {
+ broadcast_action(action_name, eventdata, UI_EVENT_DATA_POINTER, intval);
+}
+
+void ui_call_action_on(UiContext *ctx, const char *action) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ event.obj = ctx->obj;
+ event.window = event.obj ? event.obj->window : NULL;
+ event.document = ctx->self_doc ? ctx->self_doc : ctx->document;
+
+ UiAction *a = NULL;
+ if(ctx->actions) {
+ a = cxMapGet(ctx->actions, action);
+ }
+ if(a && a->callback) {
+ a->callback(&event, a->userdata);
+ }
+}
+
+typedef struct UiActionBroadcast {
+ char *action;
+ void *eventdata;
+ UiEventType eventdatataype;
+ int intval;
+} UiActionBroadcast;
+
+void ui_mainthread_broadcast(const char *action_name) {
+ ui_mainthread_broadcast2(action_name, NULL, 0);
+}
+
+static int mainthread_action_broadcast(void *data) {
+ UiActionBroadcast *broadcast = data;
+ broadcast_action(broadcast->action, broadcast->eventdata, broadcast->eventdatataype, broadcast->intval);
+ if(broadcast->eventdatataype == UI_EVENT_DATA_TYPED_OBJECT) {
+ free(broadcast->eventdata);
+ }
+ free(broadcast->action);
+ free(broadcast);
+ return 0;
+}
+
+void ui_mainthread_broadcast2(const char *action_name, void *eventdata, int intval) {
+ UiActionBroadcast *broadcast = malloc(sizeof(UiActionBroadcast));
+ broadcast->action = strdup(action_name);
+ broadcast->eventdata = eventdata;
+ broadcast->eventdatataype = UI_EVENT_DATA_POINTER;
+ broadcast->intval = intval;
+ ui_call_mainthread(mainthread_action_broadcast, broadcast);
+}
+
+void ui_mainthread_broadcast3(const char *action_name, void *ptr, uint64_t type_id) {
+ UiTypedObj *obj = malloc(sizeof(UiTypedObj));
+ obj->ptr = ptr;
+ obj->type = type_id;
+
+ UiActionBroadcast *broadcast = malloc(sizeof(UiActionBroadcast));
+ broadcast->action = strdup(action_name);
+ broadcast->eventdata = obj;
+ broadcast->eventdatataype = UI_EVENT_DATA_TYPED_OBJECT;
+ broadcast->intval = 0;
+ ui_call_mainthread(mainthread_action_broadcast, broadcast);
+}
--- /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_ACTION_H
+#define UIC_ACTION_H
+
+#include "../ui/toolkit.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct UiAction UiAction;
+typedef struct UiActionBinding UiActionBinding;
+
+struct UiAction {
+ char *name;
+ char *accelerator;
+ char *accelerator_text;
+ ui_callback callback;
+ void *userdata;
+ UiContext *ctx;
+};
+
+struct UiActionBinding {
+ const char *action;
+ ui_enablefunc set_enabled;
+ void *userdata;
+};
+
+void uic_add_action(
+ UiContext *ctx,
+ const char *name,
+ ui_callback callback,
+ void *userdata,
+ const char *accelerator,
+ const char *accelerator_text);
+
+void uic_bind_action(
+ UiContext *ctx,
+ const char *action,
+ void *bind_obj,
+ ui_enablefunc set_enabled);
+
+UiAction* uic_resolve_action(UiContext *ctx, const char *action);
+UiAction* uic_resolve_action_from_parents(UiContext *ctx, const char *action);
+
+// action event wrapper
+void uic_action_callback(UiEvent *event, const char *action_name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UIC_ACTION_H */
+
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;
exit_data = userdata;
}
-
void uic_application_startup(UiEvent *event) {
if(startup_func) {
startup_func(event, startup_data);
}
}
+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);
args->onclickdata = onclickdata;
}
+void ui_menuitem_args_set_action(UiMenuItemArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
void ui_menuitem_args_free(UiMenuItemArgs *args) {
free((void*)args->label);
free((void*)args->icon);
+ free((void*)args->action);
free(args);
}
args->onchangedata = onclickdata;
}
+void ui_menutoggleitem_args_set_action(UiMenuToggleItemArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
void ui_menutoggleitem_args_free(UiMenuToggleItemArgs *args) {
free((void*)args->label);
free((void*)args->icon);
free((void*)args->varname);
+ free((void*)args->action);
free(args);
}
args->getvalue = func;
}
+void ui_menuitemlist_args_set_getvalue2(UiMenuItemListArgs *args, ui_getvaluefunc2 func) {
+ args->getvalue2 = func;
+}
+
+void ui_menuitemlist_args_set_getvaluedata(UiMenuItemListArgs *args, void *data) {
+ args->getvaluedata = data;
+}
+
void ui_menuitemlist_args_set_onselect(UiMenuItemListArgs *args, ui_callback callback) {
args->onselect = callback;
}
args->tooltip = strdup(tooltip);
}
+void ui_toolbar_item_args_set_action(UiToolbarItemArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
void ui_toolbar_item_args_set_onclick(UiToolbarItemArgs *args, ui_callback callback) {
args->onclick = callback;
}
free((void*)args->label);
free((void*)args->icon);
free((void*)args->tooltip);
+ free((void*)args->action);
free((void*)args->states);
free(args);
}
args->varname = strdup(varname);
}
+void ui_toolbar_toggleitem_args_set_action(UiToolbarToggleItemArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
void ui_toolbar_toggleitem_args_set_onchange(UiToolbarToggleItemArgs *args, ui_callback callback) {
args->onchange = callback;
}
free((void*)args->icon);
free((void*)args->tooltip);
free((void*)args->varname);
+ free((void*)args->action);
+ free((void*)args->states);
+ free(args);
+}
+
+/* ---------------------------- UiToolbarContentToggleItemArgs ---------------------------- */
+
+UiToolbarContentToggleItemArgs* ui_toolbar_content_toggleitem_args_new(void) {
+ UiToolbarContentToggleItemArgs *args = malloc(sizeof(UiToolbarContentToggleItemArgs));
+ memset(args, 0, sizeof(UiToolbarContentToggleItemArgs));
+ return args;
+}
+
+void ui_toolbar_content_toggleitem_args_set_label0(UiToolbarContentToggleItemArgs *args, const char *label) {
+ args->label0 = strdup(label);
+}
+
+void ui_toolbar_content_toggleitem_args_set_icon0(UiToolbarContentToggleItemArgs *args, const char *icon) {
+ args->icon0 = strdup(icon);
+}
+
+void ui_toolbar_content_toggleitem_args_set_tooltip0(UiToolbarContentToggleItemArgs *args, const char *tooltip) {
+ args->tooltip0 = strdup(tooltip);
+}
+
+void ui_toolbar_content_toggleitem_args_set_label1(UiToolbarContentToggleItemArgs *args, const char *label) {
+ args->label1 = strdup(label);
+}
+
+void ui_toolbar_content_toggleitem_args_set_icon1(UiToolbarContentToggleItemArgs *args, const char *icon) {
+ args->icon1 = strdup(icon);
+}
+
+void ui_toolbar_content_toggleitem_args_set_tooltip1(UiToolbarContentToggleItemArgs *args, const char *tooltip) {
+ args->tooltip1 = strdup(tooltip);
+}
+
+void ui_toolbar_content_toggleitem_args_set_varname(UiToolbarContentToggleItemArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+void ui_toolbar_content_toggleitem_args_set_action(UiToolbarContentToggleItemArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
+void ui_toolbar_content_toggleitem_args_set_onchange(UiToolbarContentToggleItemArgs *args, ui_callback callback) {
+ args->onchange = callback;
+}
+
+void ui_toolbar_content_toggleitem_args_set_onchangedata(UiToolbarContentToggleItemArgs *args, void *onchangedata) {
+ args->onchangedata = onchangedata;
+}
+
+void ui_toolbar_content_toggleitem_args_set_istogglebutton(UiToolbarContentToggleItemArgs *args, UiBool value) {
+ args->istogglebutton = value;
+}
+
+void ui_toolbar_content_toggleitem_args_set_toggled_by_state(UiToolbarContentToggleItemArgs *args, int state) {
+ args->toggled_by_state = state;
+}
+
+void ui_toolbar_content_toggleitem_args_set_states(UiToolbarContentToggleItemArgs *args,int *states, int numstates) {
+ args->states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->states, states, numstates * sizeof(int));
+ ((int*)args->states)[numstates] = -1;
+}
+
+void ui_toolbar_content_toggleitem_args_free(UiToolbarContentToggleItemArgs *args) {
+ free((void*)args->label0);
+ free((void*)args->icon0);
+ free((void*)args->tooltip0);
+ free((void*)args->label1);
+ free((void*)args->icon1);
+ free((void*)args->tooltip1);
+ free((void*)args->varname);
+ free((void*)args->action);
free((void*)args->states);
free(args);
}
args->rowspacing = value;
}
+void ui_container_args_set_visibility_states(UiContainerArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_container_args_free(UiContainerArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
+ free((void*)args->visibility_states);
free(args);
}
args->label = strdup(label);
}
+void ui_frame_args_set_visibility_states(UiFrameArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_frame_args_free(UiFrameArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->label);
+ free((void*)args->visibility_states);
free(args);
}
args->max_panes = max;
}
+void ui_splitpane_args_set_visibility_states(UiSplitPaneArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_splitpane_args_free(UiSplitPaneArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->varname);
free((void*)args->position_property);
+ free((void*)args->visibility_states);
free(args);
}
args->subcontainer = subcontainer;
}
+void ui_tabview_args_set_visibility_states(UiTabViewArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_tabview_args_free(UiTabViewArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->varname);
+ free((void*)args->visibility_states);
free(args);
}
args->value = value;
}
+void ui_label_args_set_visibility_states(UiLabelArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_label_args_free(UiLabelArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->label);
free((void*)args->varname);
+ free((void*)args->visibility_states);
free(args);
}
args->value = value;
}
+void ui_progressbar_args_set_visibility_states(UiProgressbarArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_progressbar_args_free(UiProgressbarArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->varname);
+ free((void*)args->visibility_states);
free(args);
}
args->value = value;
}
+void ui_progress_spinner_args_set_visibility_states(UiProgressbarSpinnerArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_progress_spinner_args_free(UiProgressbarSpinnerArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->varname);
+ free((void*)args->visibility_states);
free(args);
}
args->onclickdata = onclickdata;
}
+void ui_button_args_set_action(UiButtonArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
void ui_button_args_set_states(UiButtonArgs *args, int *states, int numstates) {
args->states = calloc(numstates+1, sizeof(int));
memcpy((void*)args->states, states, numstates * sizeof(int));
((int*)args->states)[numstates] = -1;
}
+void ui_button_args_set_visibility_states(UiButtonArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_button_args_free(UiButtonArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->label);
free((void*)args->icon);
free((void*)args->tooltip);
+ free((void*)args->action);
free((void*)args->states);
+ free((void*)args->visibility_states);
free(args);
}
args->onchangedata = onchangedata;
}
+void ui_toggle_args_set_action(UiToggleArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
void ui_toggle_args_set_varname(UiToggleArgs *args, const char *varname) {
args->varname = strdup(varname);
}
((int*)args->states)[numstates] = -1;
}
+void ui_toggle_args_set_visibility_states(UiToggleArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_toggle_args_free(UiToggleArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->icon);
free((void*)args->tooltip);
free((void*)args->varname);
+ free((void*)args->action);
free((void*)args->states);
+ free((void*)args->visibility_states);
+ free(args);
+}
+
+/* ------------------------- UiContentToggleArgs ----------------------------*/
+
+
+UiContentToggleArgs* ui_content_toggle_args_new(void) {
+ UiContentToggleArgs *args = malloc(sizeof(UiContentToggleArgs));
+ memset(args, 0, sizeof(UiContentToggleArgs));
+ return args;
+}
+
+void ui_content_toggle_args_set_fill(UiContentToggleArgs *args, UiBool fill) {
+ args->fill = fill;
+}
+
+void ui_content_toggle_args_set_hexpand(UiContentToggleArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+void ui_content_toggle_args_set_vexpand(UiContentToggleArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+void ui_content_toggle_args_set_hfill(UiContentToggleArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+void ui_content_toggle_args_set_vfill(UiContentToggleArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+void ui_content_toggle_args_set_override_defaults(UiContentToggleArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+void ui_content_toggle_args_set_margin(UiContentToggleArgs *args, int value) {
+ args->margin = value;
+}
+
+void ui_content_toggle_args_set_margin_left(UiContentToggleArgs *args, int value) {
+ args->margin_left = value;
+}
+
+void ui_content_toggle_args_set_margin_right(UiContentToggleArgs *args, int value) {
+ args->margin_right = value;
+}
+
+void ui_content_toggle_args_set_margin_top(UiContentToggleArgs *args, int value) {
+ args->margin_top = value;
+}
+
+void ui_content_toggle_args_set_margin_bottom(UiContentToggleArgs *args, int value) {
+ args->margin_bottom = value;
+}
+
+void ui_content_toggle_args_set_colspan(UiContentToggleArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+void ui_content_toggle_args_set_rowspan(UiContentToggleArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+
+void ui_content_toggle_args_set_name(UiContentToggleArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+void ui_content_toggle_args_set_style_class(UiContentToggleArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+void ui_content_toggle_args_set_label0(UiContentToggleArgs *args, const char *label){
+ args->label0 = strdup(label);
+}
+
+void ui_content_toggle_args_set_icon0(UiContentToggleArgs *args, const char *icon){
+ args->icon0 = strdup(icon);
+}
+
+void ui_content_toggle_args_set_tooltip0(UiContentToggleArgs *args, const char *tooltip) {
+ args->tooltip0 = strdup(tooltip);
+}
+
+void ui_content_toggle_args_set_label1(UiContentToggleArgs *args, const char *label){
+ args->label1 = strdup(label);
+}
+
+void ui_content_toggle_args_set_icon1(UiContentToggleArgs *args, const char *icon){
+ args->icon1 = strdup(icon);
+}
+
+void ui_content_toggle_args_set_tooltip1(UiContentToggleArgs *args, const char *tooltip) {
+ args->tooltip1 = strdup(tooltip);
+}
+
+void ui_content_toggle_args_set_labeltype(UiContentToggleArgs *args, int labeltype){
+ args->labeltype = labeltype;
+}
+
+void ui_content_toggle_args_set_onchange(UiContentToggleArgs *args, ui_callback callback){
+ args->onchange = callback;
+}
+
+void ui_content_toggle_args_set_onchangedata(UiContentToggleArgs *args, void *onchangedata){
+ args->onchangedata = onchangedata;
+}
+
+void ui_content_toggle_args_set_action(UiContentToggleArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
+void ui_content_toggle_args_set_varname(UiContentToggleArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+void ui_content_toggle_args_set_value(UiContentToggleArgs *args, UiInteger *value) {
+ args->value = value;
+}
+
+void ui_content_toggle_args_set_toggled_by_state(UiContentToggleArgs *args, int state) {
+ args->toggled_by_state = state;
+}
+
+void ui_content_toggle_args_set_istogglebutton(UiContentToggleArgs *args, UiBool value) {
+ args->istogglebutton = value;
+}
+
+void ui_content_toggle_args_set_enablestate(UiContentToggleArgs *args, int state) {
+ args->enable_state = state;
+}
+
+void ui_content_toggle_args_set_states(UiContentToggleArgs *args, int *states, int numstates) {
+ args->states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->states, states, numstates * sizeof(int));
+ ((int*)args->states)[numstates] = -1;
+}
+
+void ui_content_toggle_args_set_visibility_states(UiContentToggleArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
+void ui_content_toggle_args_free(UiContentToggleArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free((void*)args->label0);
+ free((void*)args->icon0);
+ free((void*)args->tooltip0);
+ free((void*)args->label1);
+ free((void*)args->icon1);
+ free((void*)args->tooltip1);
+ free((void*)args->varname);
+ free((void*)args->action);
+ free((void*)args->states);
+ free((void*)args->visibility_states);
free(args);
}
args->onclickdata = userdata;
}
+void ui_linkbutton_args_set_action(UiLinkButtonArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
void ui_linkbutton_args_set_nofollow(UiLinkButtonArgs *args, UiBool value) {
args->nofollow = value;
}
((int*)args->states)[numstates] = -1;
}
+void ui_linkbutton_args_set_visibility_states(UiLinkButtonArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_linkbutton_args_free(UiLinkButtonArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->label);
free((void*)args->uri);
+ free((void*)args->action);
free((void*)args->varname);
free((void*)args->states);
free(args);
args->onactivatedata = userdata;
}
+void ui_list_args_set_onactivate_action(UiListArgs *args, const char *action) {
+ args->onactivate_action = strdup(action);
+}
+
void ui_list_args_set_onselection(UiListArgs *args, ui_callback callback) {
args->onselection = callback;
}
args->onselectiondata = userdata;
}
+void ui_list_args_set_onselection_action(UiListArgs *args, const char *action) {
+ args->onselection_action = strdup(action);
+}
+
void ui_list_args_set_ondragstart(UiListArgs *args, ui_callback callback) {
args->ondragstart = callback;
}
args->ondragstartdata = userdata;
}
+void ui_list_args_set_ondragstart_action(UiListArgs *args, const char *action) {
+ args->ondragstart_action = strdup(action);
+}
+
void ui_list_args_set_ondragcomplete(UiListArgs *args, ui_callback callback) {
args->ondragcomplete = callback;
}
args->ondragcompletedata = userdata;
}
+void ui_list_args_set_ondragcomplete_action(UiListArgs *args, const char *action) {
+ args->ondragcomplete_action = strdup(action);
+}
+
void ui_list_args_set_ondrop(UiListArgs *args, ui_callback callback) {
args->ondrop = callback;
}
args->ondropdata = userdata;
}
+void ui_list_args_set_ondrop_action(UiListArgs *args, const char *action) {
+ args->ondrop_action = strdup(action);
+}
+
void ui_list_args_set_onsave(UiListArgs *args, ui_list_savefunc onsave) {
args->onsave = onsave;
}
((int*)args->states)[numstates] = -1;
}
+void ui_list_args_set_visibility_states(UiListArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_list_args_free(UiListArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->varname);
+ free((void*)args->onactivate_action);
+ free((void*)args->onselection_action);
+ free((void*)args->ondragstart_action);
+ free((void*)args->ondragcomplete_action);
+ free((void*)args->ondrop_action);
if(args->static_elements) {
for(int i=0;i<args->static_nelm;i++) {
free(args->static_elements[i]);
free(args->static_elements);
}
free((void*)args->states);
+ free((void*)args->visibility_states);
free(args);
}
}
-
void ui_sourcelist_args_set_onbuttonclickdata(UiSourceListArgs *args, void *userdata) {
args->onbuttonclickdata = userdata;
}
args->header_is_item = value;
}
+UIEXPORT void ui_sourcelist_args_set_states(UiSourceListArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->states, states, numstates * sizeof(int));
+ ((int*)args->states)[numstates] = -1;
+}
+
+void ui_sourcelist_args_set_visibility_states(UiSourceListArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_sourcelist_args_free(UiSourceListArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->varname);
free((void*)args->sublists);
free((void*)args->states);
+ free((void*)args->visibility_states);
free(args);
}
args->onchangedata = onchangedata;
}
+void ui_textarea_args_set_onchange_action(UiTextAreaArgs *args, const char *action) {
+ args->onchange_action = strdup(action);
+}
+
+void ui_textarea_args_set_ontextchanged(UiTextAreaArgs *args, ui_callback callback) {
+ args->ontextchanged = callback;
+}
+
+void ui_textarea_args_set_ontextchangeddata(UiTextAreaArgs *args, void *onchangedata) {
+ args->ontextchangeddata = onchangedata;
+}
+
+void ui_textarea_args_set_ontextchanged_action(UiTextAreaArgs *args, const char *action) {
+ args->ontextchanged_action = strdup(action);
+}
+
void ui_textarea_args_set_varname(UiTextAreaArgs *args, const char *varname) {
args->varname = strdup(varname);
}
((int*)args->states)[numstates] = -1;
}
+void ui_textarea_args_set_visibility_states(UiTextAreaArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_textarea_args_free(UiTextAreaArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->varname);
+ free((void*)args->onchange_action);
+ free((void*)args->ontextchanged_action);
free((void*)args->states);
+ free((void*)args->visibility_states);
free(args);
}
args->onactivatedata = onactivatedata;
}
+void ui_textfield_args_set_onactivate_action(UiTextFieldArgs *args, const char *action) {
+ args->onactivate_action = strdup(action);
+}
+
+void ui_textfield_args_set_onchange_action(UiTextFieldArgs *args, const char *action) {
+ args->onchange_action = action;
+}
+
void ui_textfield_args_set_varname(UiTextFieldArgs *args, const char *varname) {
args->varname = strdup(varname);
}
((int*)args->states)[numstates] = -1;
}
+void ui_textfield_args_set_visibility_states(UiTextFieldArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_textfield_args_free(UiTextFieldArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->varname);
+ free((void*)args->onactivate_action);
+ free((void*)args->onchange_action);
free((void*)args->states);
+ free((void*)args->visibility_states);
free(args);
}
((int*)args->states)[numstates] = -1;
}
+void ui_spinbox_args_set_visibility_states(UiSpinBoxArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_spinbox_args_free(UiSpinBoxArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->varname);
free((void*)args->states);
+ free((void*)args->visibility_states);
free(args);
}
((int*)args->states)[numstates] = -1;
}
+void ui_webview_args_set_visibility_states(UiWebviewArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
void ui_webview_args_free(UiWebviewArgs *args) {
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->varname);
free((void*)args->states);
+ free((void*)args->visibility_states);
free(args);
}
UIEXPORT void ui_menuitem_args_set_icon(UiMenuItemArgs *args, const char *icon);
UIEXPORT void ui_menuitem_args_set_onclick(UiMenuItemArgs *args, ui_callback callback);
UIEXPORT void ui_menuitem_args_set_onclickdata(UiMenuItemArgs *args, void *onclickdata);
+UIEXPORT void ui_menuitem_args_set_action(UiMenuItemArgs *args, const char *action);
UIEXPORT void ui_menuitem_args_free(UiMenuItemArgs *args);
UIEXPORT UiMenuToggleItemArgs* ui_menutoggleitem_args_new(void);
UIEXPORT void ui_menutoggleitem_args_set_varname(UiMenuToggleItemArgs *args, const char *varname);
UIEXPORT void ui_menutoggleitem_args_set_onchange(UiMenuToggleItemArgs *args, ui_callback callback);
UIEXPORT void ui_menutoggleitem_args_set_onchangedata(UiMenuToggleItemArgs *args, void *onchangedata);
+UIEXPORT void ui_menutoggleitem_args_set_action(UiMenuToggleItemArgs *args, const char *action);
UIEXPORT void ui_menutoggleitem_args_free(UiMenuToggleItemArgs *args);
UIEXPORT UiMenuItemListArgs* ui_menuitemlist_args_new(void);
UIEXPORT void ui_menuitemlist_args_set_varname(UiMenuItemListArgs *args, const char *varname);
UIEXPORT void ui_menuitemlist_args_set_getvalue(UiMenuItemListArgs *args, ui_getvaluefunc func);
+UIEXPORT void ui_menuitemlist_args_set_getvalue2(UiMenuItemListArgs *args, ui_getvaluefunc2 func);
+UIEXPORT void ui_menuitemlist_args_set_getvaluedata(UiMenuItemListArgs *args, void *data);
UIEXPORT void ui_menuitemlist_args_set_onselect(UiMenuItemListArgs *args, ui_callback callback);
UIEXPORT void ui_menuitemlist_args_set_onselectdata(UiMenuItemListArgs *args, void *data);
UIEXPORT void ui_menuitemlist_args_set_addseparator(UiMenuItemListArgs *args, UiBool value);
UIEXPORT void ui_toolbar_item_args_set_label(UiToolbarItemArgs *args, const char *label);
UIEXPORT void ui_toolbar_item_args_set_icon(UiToolbarItemArgs *args, const char *icon);
UIEXPORT void ui_toolbar_item_args_set_tooltip(UiToolbarItemArgs *args, const char *tooltip);
+UIEXPORT void ui_toolbar_item_args_set_action(UiToolbarItemArgs *args, const char *action);
UIEXPORT void ui_toolbar_item_args_set_onclick(UiToolbarItemArgs *args, ui_callback callback);
UIEXPORT void ui_toolbar_item_args_set_onclickdata(UiToolbarItemArgs *args, void *onclickdata);
UIEXPORT void ui_toolbar_item_args_set_states(UiToolbarItemArgs *args, int *states, int numstates);
UIEXPORT void ui_toolbar_toggleitem_args_set_icon(UiToolbarToggleItemArgs *args, const char *icon);
UIEXPORT void ui_toolbar_toggleitem_args_set_tooltip(UiToolbarToggleItemArgs *args, const char *tooltip);
UIEXPORT void ui_toolbar_toggleitem_args_set_varname(UiToolbarToggleItemArgs *args, const char *varname);
+UIEXPORT void ui_toolbar_toggleitem_args_set_action(UiToolbarToggleItemArgs *args, const char *action);
UIEXPORT void ui_toolbar_toggleitem_args_set_onchange(UiToolbarToggleItemArgs *args, ui_callback callback);
UIEXPORT void ui_toolbar_toggleitem_args_set_onchangedata(UiToolbarToggleItemArgs *args, void *onchangedata);
UIEXPORT void ui_toolbar_toggleitem_args_set_states(UiToolbarToggleItemArgs *args, int *states, int numstates);
UIEXPORT void ui_toolbar_toggleitem_args_free(UiToolbarToggleItemArgs *args);
+UIEXPORT UiToolbarContentToggleItemArgs* ui_toolbar_content_toggleitem_args_new(void);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_label0(UiToolbarContentToggleItemArgs *args, const char *label);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_icon0(UiToolbarContentToggleItemArgs *args, const char *icon);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_tooltip0(UiToolbarContentToggleItemArgs *args, const char *tooltip);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_label1(UiToolbarContentToggleItemArgs *args, const char *label);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_icon1(UiToolbarContentToggleItemArgs *args, const char *icon);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_tooltip1(UiToolbarContentToggleItemArgs *args, const char *tooltip);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_varname(UiToolbarContentToggleItemArgs *args, const char *varname);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_action(UiToolbarContentToggleItemArgs *args, const char *action);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_onchange(UiToolbarContentToggleItemArgs *args, ui_callback callback);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_onchangedata(UiToolbarContentToggleItemArgs *args, void *onchangedata);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_states(UiToolbarContentToggleItemArgs *args, int *states, int numstates);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_istogglebutton(UiToolbarContentToggleItemArgs *args, UiBool value);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_toggled_by_state(UiToolbarContentToggleItemArgs *args, int state);
+UIEXPORT void ui_toolbar_content_toggleitem_args_free(UiToolbarContentToggleItemArgs *args);
+
UIEXPORT UiToolbarMenuArgs* ui_toolbar_menu_args_new(void);
UIEXPORT void ui_toolbar_menu_args_set_label(UiToolbarMenuArgs *args, const char *label);
UIEXPORT void ui_toolbar_menu_args_set_icon(UiToolbarMenuArgs *args, const char *icon);
UIEXPORT void ui_container_args_set_spacing(UiContainerArgs *args, int value);
UIEXPORT void ui_container_args_set_columnspacing(UiContainerArgs *args, int value);
UIEXPORT void ui_container_args_set_rowspacing(UiContainerArgs *args, int value);
+UIEXPORT void ui_container_args_set_visibility_states(UiContainerArgs *args, int *states, int numstates);
UIEXPORT void ui_container_args_free(UiContainerArgs *args);
UIEXPORT UiFrameArgs* ui_frame_args_new(void);
UIEXPORT void ui_frame_args_set_rowspacing(UiFrameArgs *args, int value);
UIEXPORT void ui_frame_args_set_expanded(UiFrameArgs *args, UiBool value);
UIEXPORT void ui_frame_args_set_label(UiFrameArgs *args, const char *label);
+UIEXPORT void ui_frame_args_set_visibility_states(UiFrameArgs *args, int *states, int numstates);
UIEXPORT void ui_frame_args_free(UiFrameArgs *args);
UIEXPORT UiSidebarArgs* ui_sidebar_args_new(void);
UIEXPORT void ui_splitpane_args_set_varname(UiSplitPaneArgs *args, const char *varname);
UIEXPORT void ui_splitpane_args_set_value(UiSplitPaneArgs *args, UiInteger *value);
UIEXPORT void ui_splitpane_args_set_max_panes(UiSplitPaneArgs *args, int max);
+UIEXPORT void ui_splitpane_args_set_visibility_states(UiSplitPaneArgs *args, int *states, int numstates);
UIEXPORT void ui_splitpane_args_free(UiSplitPaneArgs *args);
UIEXPORT UiTabViewArgs* ui_tabview_args_new(void);
UIEXPORT void ui_tabview_args_set_varname(UiTabViewArgs *args, const char *varname);
UIEXPORT void ui_tabview_args_set_value(UiTabViewArgs *args, UiInteger *value);
UIEXPORT void ui_tabview_args_set_subcontainer(UiTabViewArgs *args, UiSubContainerType subcontainer);
+UIEXPORT void ui_tabview_args_set_visibility_states(UiTabViewArgs *args, int *states, int numstates);
UIEXPORT void ui_tabview_args_free(UiTabViewArgs *args);
UIEXPORT UiWidgetArgs* ui_widget_args_new(void);
UIEXPORT void ui_label_args_set_style(UiLabelArgs *args, UiLabelStyle style);
UIEXPORT void ui_label_args_set_value(UiLabelArgs *args, UiString *value);
UIEXPORT void ui_label_args_set_varname(UiLabelArgs *args, const char *varname);
+UIEXPORT void ui_label_args_set_visibility_states(UiLabelArgs *args, int *states, int numstates);
UIEXPORT void ui_label_args_free(UiLabelArgs *args);
UIEXPORT UiProgressbarArgs* ui_progressbar_args_new(void);
UIEXPORT void ui_progressbar_args_set_max(UiProgressbarArgs *args, double max);
UIEXPORT void ui_progressbar_args_set_value(UiProgressbarArgs *args, UiDouble *value);
UIEXPORT void ui_progressbar_args_set_varname(UiProgressbarArgs *args, const char *varname);
+UIEXPORT void ui_progressbar_args_set_visibility_states(UiProgressbarArgs *args, int *states, int numstates);
UIEXPORT void ui_progressbar_args_free(UiProgressbarArgs *args);
UIEXPORT UiProgressbarSpinnerArgs* ui_progress_spinner_args_new(void);
UIEXPORT void ui_progress_spinner_args_set_style_class(UiProgressbarSpinnerArgs *args, const char *classname);
UIEXPORT void ui_progress_spinner_args_set_value(UiProgressbarSpinnerArgs *args, UiInteger *value);
UIEXPORT void ui_progress_spinner_args_set_varname(UiProgressbarSpinnerArgs *args, const char *varname);
+UIEXPORT void ui_progress_spinner_args_set_visibility_states(UiProgressbarSpinnerArgs *args, int *states, int numstates);
UIEXPORT void ui_progress_spinner_args_free(UiProgressbarSpinnerArgs *args);
UIEXPORT UiButtonArgs* ui_button_args_new(void);
UIEXPORT void ui_button_args_set_labeltype(UiButtonArgs *args, int labeltype);
UIEXPORT void ui_button_args_set_onclick(UiButtonArgs *args, ui_callback callback);
UIEXPORT void ui_button_args_set_onclickdata(UiButtonArgs *args, void *onclickdata);
+UIEXPORT void ui_button_args_set_action(UiButtonArgs *args, const char *action);
UIEXPORT void ui_button_args_set_states(UiButtonArgs *args, int *states, int numstates);
+UIEXPORT void ui_button_args_set_visibility_states(UiButtonArgs *args, int *states, int numstates);
UIEXPORT void ui_button_args_free(UiButtonArgs *args);
UIEXPORT UiToggleArgs* ui_toggle_args_new(void);
UIEXPORT void ui_toggle_args_set_labeltype(UiToggleArgs *args, int labeltype);
UIEXPORT void ui_toggle_args_set_onchange(UiToggleArgs *args, ui_callback callback);
UIEXPORT void ui_toggle_args_set_onchangedata(UiToggleArgs *args, void *onchangedata);
+UIEXPORT void ui_toggle_args_set_action(UiToggleArgs *args, const char *action);
UIEXPORT void ui_toggle_args_set_varname(UiToggleArgs *args, const char *varname);
UIEXPORT void ui_toggle_args_set_value(UiToggleArgs *args, UiInteger *value);
UIEXPORT void ui_toggle_args_set_enablestate(UiToggleArgs *args, int state);
UIEXPORT void ui_toggle_args_set_states(UiToggleArgs *args, int *states, int numstates);
+UIEXPORT void ui_toggle_args_set_visibility_states(UiToggleArgs *args, int *states, int numstates);
UIEXPORT void ui_toggle_args_free(UiToggleArgs *args);
+UIEXPORT UiContentToggleArgs* ui_content_toggle_args_new(void);
+UIEXPORT void ui_content_toggle_args_set_fill(UiContentToggleArgs *args, UiBool fill);
+UIEXPORT void ui_content_toggle_args_set_hexpand(UiContentToggleArgs *args, UiBool value);
+UIEXPORT void ui_content_toggle_args_set_vexpand(UiContentToggleArgs *args, UiBool value);
+UIEXPORT void ui_content_toggle_args_set_hfill(UiContentToggleArgs *args, UiBool value);
+UIEXPORT void ui_content_toggle_args_set_vfill(UiContentToggleArgs *args, UiBool value);
+UIEXPORT void ui_content_toggle_args_set_override_defaults(UiContentToggleArgs *args, UiBool value);
+UIEXPORT void ui_content_toggle_args_set_margin(UiContentToggleArgs *args, int value);
+UIEXPORT void ui_content_toggle_args_set_margin_left(UiContentToggleArgs *args, int value);
+UIEXPORT void ui_content_toggle_args_set_margin_right(UiContentToggleArgs *args, int value);
+UIEXPORT void ui_content_toggle_args_set_margin_top(UiContentToggleArgs *args, int value);
+UIEXPORT void ui_content_toggle_args_set_margin_bottom(UiContentToggleArgs *args, int value);
+UIEXPORT void ui_content_toggle_args_set_colspan(UiContentToggleArgs *args, int colspan);
+UIEXPORT void ui_content_toggle_args_set_rowspan(UiContentToggleArgs *args, int rowspan);
+UIEXPORT void ui_content_toggle_args_set_name(UiContentToggleArgs *args, const char *name);
+UIEXPORT void ui_content_toggle_args_set_style_class(UiContentToggleArgs *args, const char *classname);
+UIEXPORT void ui_content_toggle_args_set_label0(UiContentToggleArgs *args, const char *label);
+UIEXPORT void ui_content_toggle_args_set_icon0(UiContentToggleArgs *args, const char *icon);
+UIEXPORT void ui_content_toggle_args_set_tooltip0(UiContentToggleArgs *args, const char *tooltip);
+UIEXPORT void ui_content_toggle_args_set_label1(UiContentToggleArgs *args, const char *label);
+UIEXPORT void ui_content_toggle_args_set_icon1(UiContentToggleArgs *args, const char *icon);
+UIEXPORT void ui_content_toggle_args_set_tooltip1(UiContentToggleArgs *args, const char *tooltip);
+UIEXPORT void ui_content_toggle_args_set_labeltype(UiContentToggleArgs *args, int labeltype);
+UIEXPORT void ui_content_toggle_args_set_onchange(UiContentToggleArgs *args, ui_callback callback);
+UIEXPORT void ui_content_toggle_args_set_onchangedata(UiContentToggleArgs *args, void *onchangedata);
+UIEXPORT void ui_content_toggle_args_set_action(UiContentToggleArgs *args, const char *action);
+UIEXPORT void ui_content_toggle_args_set_varname(UiContentToggleArgs *args, const char *varname);
+UIEXPORT void ui_content_toggle_args_set_value(UiContentToggleArgs *args, UiInteger *value);
+UIEXPORT void ui_content_toggle_args_set_toggled_by_state(UiContentToggleArgs *args, int state);
+UIEXPORT void ui_content_toggle_args_set_istogglebutton(UiContentToggleArgs *args, UiBool value);
+UIEXPORT void ui_content_toggle_args_set_enablestate(UiContentToggleArgs *args, int state);
+UIEXPORT void ui_content_toggle_args_set_states(UiContentToggleArgs *args, int *states, int numstates);
+UIEXPORT void ui_content_toggle_args_set_visibility_states(UiContentToggleArgs *args, int *states, int numstates);
+UIEXPORT void ui_content_toggle_args_free(UiContentToggleArgs *args);
+
UIEXPORT UiLinkButtonArgs* ui_linkbutton_args_new(void);
UIEXPORT void ui_linkbutton_args_set_fill(UiLinkButtonArgs *args, UiBool fill);
UIEXPORT void ui_linkbutton_args_set_hexpand(UiLinkButtonArgs *args, UiBool value);
UIEXPORT void ui_linkbutton_args_set_uri(UiLinkButtonArgs *args, const char *uri);
UIEXPORT void ui_linkbutton_args_set_onclick(UiLinkButtonArgs *args, ui_callback callback);
UIEXPORT void ui_linkbutton_args_set_onclickdata(UiLinkButtonArgs *args, void *userdata);
+UIEXPORT void ui_linkbutton_args_set_action(UiLinkButtonArgs *args, const char *action);
UIEXPORT void ui_linkbutton_args_set_nofollow(UiLinkButtonArgs *args, UiBool value);
UIEXPORT void ui_linkbutton_args_set_type(UiLinkButtonArgs *args, UiLinkType type);
UIEXPORT void ui_linkbutton_args_set_states(UiLinkButtonArgs *args, int *states, int numstates);
+UIEXPORT void ui_linkbutton_args_set_visibility_states(UiLinkButtonArgs *args, int *states, int numstates);
UIEXPORT void ui_linkbutton_args_free(UiLinkButtonArgs *args);
UIEXPORT UiListArgs* ui_list_args_new(void);
UIEXPORT void ui_list_args_set_getstyle_data(UiListArgs *args, void *userdata);
UIEXPORT void ui_list_args_set_onactivate(UiListArgs *args, ui_callback callback);
UIEXPORT void ui_list_args_set_onactivatedata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_onactivate_action(UiListArgs *args, const char *action);
UIEXPORT void ui_list_args_set_onselection(UiListArgs *args, ui_callback callback);
UIEXPORT void ui_list_args_set_onselectiondata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_onselection_action(UiListArgs *args, const char *action);
UIEXPORT void ui_list_args_set_ondragstart(UiListArgs *args, ui_callback callback);
UIEXPORT void ui_list_args_set_ondragstartdata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_ondragstart_action(UiListArgs *args, const char *action);
UIEXPORT void ui_list_args_set_ondragcomplete(UiListArgs *args, ui_callback callback);
UIEXPORT void ui_list_args_set_ondragcompletedata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_ondragcomplete_action(UiListArgs *args, const char *action);
UIEXPORT void ui_list_args_set_ondrop(UiListArgs *args, ui_callback callback);
UIEXPORT void ui_list_args_set_ondropdata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_ondrop_action(UiListArgs *args, const char *action);
UIEXPORT void ui_list_args_set_onsave(UiListArgs *args, ui_list_savefunc onsave);
UIEXPORT void ui_list_args_set_onsavedata(UiListArgs *args, void *userdata);
UIEXPORT void ui_list_args_set_multiselection(UiListArgs *args, UiBool multiselection);
UIEXPORT void ui_list_args_set_contextmenu(UiListArgs *args, UiMenuBuilder *menubuilder);
UIEXPORT void ui_list_args_set_states(UiListArgs *args, int *states, int numstates);
+UIEXPORT void ui_list_args_set_visibility_states(UiListArgs *args, int *states, int numstates);
UIEXPORT void ui_list_args_free(UiListArgs *args);
UIEXPORT UiSourceListArgs* ui_sourcelist_args_new(void);
UIEXPORT void ui_sourcelist_args_set_onbuttonclickdata(UiSourceListArgs *args, void *userdata);
UIEXPORT void ui_sourcelist_args_set_contextmenu(UiSourceListArgs *args, UiMenuBuilder *menubuilder);
UIEXPORT void ui_sourcelist_args_set_header_is_item(UiSourceListArgs *args, UiBool value);
+UIEXPORT void ui_sourcelist_args_set_states(UiSourceListArgs *args, int *states, int numstates);
+UIEXPORT void ui_sourcelist_args_set_visibility_states(UiSourceListArgs *args, int *states, int numstates);
UIEXPORT void ui_sourcelist_args_free(UiSourceListArgs *args);
UIEXPORT UiTextAreaArgs* ui_textarea_args_new(void);
UIEXPORT void ui_textarea_args_set_style_class(UiTextAreaArgs *args, const char *classname);
UIEXPORT void ui_textarea_args_set_onchange(UiTextAreaArgs *args, ui_callback callback);
UIEXPORT void ui_textarea_args_set_onchangedata(UiTextAreaArgs *args, void *onchangedata);
+UIEXPORT void ui_textarea_args_set_onchange_action(UiTextAreaArgs *args, const char *action);
+UIEXPORT void ui_textarea_args_set_ontextchanged(UiTextAreaArgs *args, ui_callback callback);
+UIEXPORT void ui_textarea_args_set_ontextchangeddata(UiTextAreaArgs *args, void *onchangedata);
+UIEXPORT void ui_textarea_args_set_ontextchanged_action(UiTextAreaArgs *args, const char *action);
UIEXPORT void ui_textarea_args_set_varname(UiTextAreaArgs *args, const char *varname);
UIEXPORT void ui_textarea_args_set_value(UiTextAreaArgs *args, UiText *value);
UIEXPORT void ui_textarea_args_set_states(UiTextAreaArgs *args, int *states, int numstates);
+UIEXPORT void ui_textarea_args_set_visibility_states(UiTextAreaArgs *args, int *states, int numstates);
UIEXPORT void ui_textarea_args_free(UiTextAreaArgs *args);
UIEXPORT UiTextFieldArgs* ui_textfield_args_new(void);
UIEXPORT void ui_textfield_args_set_onchangedata(UiTextFieldArgs *args, void *onchangedata);
UIEXPORT void ui_textfield_args_set_onactivate(UiTextFieldArgs *args, ui_callback callback);
UIEXPORT void ui_textfield_args_set_onactivatedata(UiTextFieldArgs *args, void *onactivatedata);
+UIEXPORT void ui_textfield_args_set_onactivate_action(UiTextFieldArgs *args, const char *action);
+UIEXPORT void ui_textfield_args_set_onchange_action(UiTextFieldArgs *args, const char *action);
UIEXPORT void ui_textfield_args_set_varname(UiTextFieldArgs *args, const char *varname);
UIEXPORT void ui_textfield_args_set_value(UiTextFieldArgs *args, UiString *value);
UIEXPORT void ui_textfield_args_set_states(UiTextFieldArgs *args, int *states, int numstates);
+UIEXPORT void ui_textfield_args_set_visibility_states(UiTextFieldArgs *args, int *states, int numstates);
UIEXPORT void ui_textfield_args_free(UiTextFieldArgs *args);
UIEXPORT UiSpinBoxArgs* ui_spinbox_args_new(void);
UIEXPORT void ui_spinbox_args_set_doublevalue(UiSpinBoxArgs *args, UiDouble *value);
UIEXPORT void ui_spinbox_args_set_rangevalue(UiSpinBoxArgs *args, UiRange *value);
UIEXPORT void ui_spinbox_args_set_states(UiSpinBoxArgs *args, int *states, int numstates);
+UIEXPORT void ui_spinbox_args_set_visibility_states(UiSpinBoxArgs *args, int *states, int numstates);
UIEXPORT void ui_spinbox_args_free(UiSpinBoxArgs *args);
UIEXPORT UiWebviewArgs* ui_webview_args_new(void);
UIEXPORT void ui_webview_args_set_varname(UiWebviewArgs *args, const char *varname);
UIEXPORT void ui_webview_args_set_value(UiWebviewArgs *args, UiGeneric *value);
UIEXPORT void ui_webview_args_set_states(UiWebviewArgs *args, int *states, int numstates);
+UIEXPORT void ui_webview_args_set_visibility_states(UiWebviewArgs *args, int *states, int numstates);
UIEXPORT void ui_webview_args_free(UiWebviewArgs *args);
#ifdef __cplusplus
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;
}
ctx->state_widgets = cxLinkedListCreate(mp->allocator, sizeof(UiStateWidget));
ctx->states = cxArrayListCreate(mp->allocator, sizeof(int), 32);
cxSetCompareFunc(ctx->states, cx_cmp_int);
+ ctx->suppressed_states = cxArrayListCreate(mp->allocator, sizeof(int), 16);
+ cxSetCompareFunc(ctx->suppressed_states, cx_cmp_int);
- ctx->attach_document = uic_context_attach_document;
- ctx->detach_document2 = uic_context_detach_document;
+ ctx->actions = cxHashMapCreate(ctx->allocator, sizeof(UiAction), 8);
+ ctx->action_bindings = cxArrayListCreate(ctx->allocator, sizeof(UiActionBinding), 0);
#if UI_GTK2 || UI_GTK3
if(toplevel && toplevel->widget) {
}
#endif
+ ctx->ref = 1;
+
return ctx;
}
cxListAdd(ctx->destroy_handler, &handler);
}
+void uic_context_remove_destructor(UiContext *ctx, void *data) {
+ CxIterator i = cxListIterator(ctx->destroy_handler);
+ cx_foreach(UiDestroyHandler *, handler, i) {
+ if(handler->data == data) {
+ cxIteratorFlagRemoval(i);
+ }
+ }
+}
+
void uic_context_prepare_close(UiContext *ctx) {
cxListClear(ctx->states);
cxListClear(ctx->state_widgets);
+ cxListClear(ctx->action_bindings);
+ uic_context_detach_all(ctx);
}
-void uic_context_attach_document(UiContext *ctx, void *document) {
- if(ctx->single_document_mode) {
- if(ctx->document) {
- uic_context_detach_document(ctx, ctx->document);
- }
+void uic_context_destroy(UiContext *ctx, void *document) {
+ if(!ctx) {
+ return;
}
- cxListAdd(ctx->documents, document);
- ctx->document = document;
+ UiEvent ev;
+ ev.obj = ctx->obj;
+ ev.window = ev.obj ? ev.obj->window : NULL;
+ ev.document = document;
+ ev.eventdata = NULL;
+ ev.eventdatatype = 0;
+ ev.intval = 0;
+ ev.set = 0;
+
+ if(ctx->onclose) {
+ ctx->onclose(&ev, ctx->onclosedata);
+ }
- UiContext *doc_ctx = ui_document_context(document);
- doc_ctx->parent = ctx;
+ CxIterator i = cxListIterator(ctx->destroy_handler);
+ cx_foreach(UiDestroyHandler *, h, i) {
+ h->destructor(h->data);
+ }
+ uic_context_detach_all(ctx);
+
+ cxMempoolFree(ctx->mp);
+}
+
+void uic_context_update_bindings(UiContext *ctx) {
+ int onchange_enabled = ui_onchange_events_is_enabled();
+ int onselection_enabled = ui_selection_events_is_enabled();
+ ui_onchange_events_enable(FALSE);
+ ui_selection_events_enable(FALSE);
// if a document variable has the same name as a parent variable,
// move the bindings to the document
- UiContext *var_ctx = ctx;
+ UiContext *var_ctx = ctx->parent;
while(var_ctx) {
CxMapIterator i = cxMapIterator(var_ctx->vars);
cx_foreach(CxMapEntry*, entry, i) {
- printf("attach %.*s\n", (int)entry->key->len, (char*)entry->key->data);
+ // printf("attach %.*s\n", (int)entry->key->len, (char*)entry->key->data);
UiVar *var = entry->value;
- UiVar *docvar = cxMapGet(doc_ctx->vars, *entry->key);
+ UiVar *docvar = cxMapGet(ctx->vars, *entry->key);
if(docvar) {
// bind var to document var
uic_copy_var_binding(var, docvar, TRUE);
var_ctx = var_ctx->parent;
}
+
+ ui_update_action_bindings(ctx);
+
+ if(ctx->documents) {
+ CxIterator i = cxListIterator(ctx->documents);
+ cx_foreach(void *, doc, i) {
+ UiContext *subctx = ui_document_context(doc);
+ uic_context_update_bindings(subctx);
+ }
+ }
+ ui_onchange_events_enable(onchange_enabled);
+ ui_selection_events_enable(onselection_enabled);
+}
+
+void uic_context_attach_document(UiContext *ctx, void *document) {
+ if(ctx->single_document_mode) {
+ if(ctx->document) {
+ uic_context_detach_document(ctx, ctx->document);
+ }
+ }
+
+ cxListAdd(ctx->documents, document);
+ ctx->document = document;
+
+ UiContext *doc_ctx = ui_document_context(document);
+ doc_ctx->parent = ctx;
+ doc_ctx->ref++;
+
+ uic_context_update_bindings(doc_ctx);
+ if(doc_ctx->onattach) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ event.document = document;
+ doc_ctx->onattach(&event, doc_ctx->onattachdata);
+ }
+ uic_check_state_widgets(ui_context_toplevel_parent(ctx));
+ UiObject *obj = ui_context_get_parent_obj(ctx);
+ uic_send_status_change(doc_ctx, obj);
+
+ UiContext *obj_ctx = uic_obj_context(ctx);
+ if(obj_ctx) {
+ ui_update_action_bindings(obj_ctx);
+ }
}
static void uic_context_unbind_vars(UiContext *ctx) {
+ int onchange_enabled = ui_onchange_events_is_enabled();
+ int onselection_enabled = ui_selection_events_is_enabled();
ui_onchange_events_enable(FALSE);
+ ui_selection_events_enable(FALSE);
CxMapIterator mi = cxMapIterator(ctx->vars);
cx_foreach(CxMapEntry*, entry, mi) {
- printf("detach %.*s\n", (int)entry->key->len, (char*)entry->key->data);
+ //printf("detach %.*s\n", (int)entry->key->len, (char*)entry->key->data);
UiVar *var = entry->value;
// var->from && var->from_ctx && var->from_ctx != ctx
uic_save_var(var);
}
}
- ui_onchange_events_enable(TRUE);
+ ui_onchange_events_enable(onchange_enabled);
+ ui_selection_events_enable(onselection_enabled);
}
void uic_context_detach_document(UiContext *ctx, void *document) {
cxListRemove(ctx->documents, docIndex);
ctx->document = cxListAt(ctx->documents, 0);
- UiContext *docctx = ui_document_context(document);
- uic_context_unbind_vars(docctx); // unbind all doc/subdoc vars from the parent
- docctx->parent = NULL;
+ UiContext *doc_ctx = ui_document_context(document);
+ uic_context_unbind_vars(doc_ctx); // unbind all doc/subdoc vars from the parent
+ doc_ctx->parent = NULL;
+
+ UiContext *obj_ctx = uic_obj_context(ctx);
+ if(obj_ctx) {
+ ui_update_action_bindings(obj_ctx);
+ }
+ if(doc_ctx->ondetach) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ event.document = document;
+ doc_ctx->ondetach(&event, doc_ctx->ondetachdata);
+ }
+
+ uic_check_state_widgets(ui_context_toplevel_parent(ctx));
+ uic_send_status_change(doc_ctx, NULL);
+ ui_document_unref(document);
}
void uic_context_detach_all(UiContext *ctx) {
// detach documents
i = cxListIterator(ls);
cx_foreach(void *, doc, i) {
- ctx->detach_document2(ctx, doc);
+ uic_context_detach_document(ctx, doc);
}
cxListFree(ls);
+ ui_update_action_bindings(ctx);
}
+static void send_status_change(UiContext *ctx, UiEvent *event, UiObject *obj) {
+ CxIterator i = cxListIterator(ctx->documents);
+ cx_foreach(void *, doc, i) {
+ UiContext *doc_ctx = ui_document_context(doc);
+ if(doc_ctx->onattachmentstatuschange) {
+ event->obj = doc_ctx->obj ? doc_ctx->obj : obj;
+ event->window = event->obj ? event->obj->window : NULL;
+ event->document = doc_ctx->self_doc ? doc_ctx->self_doc : doc_ctx->document;
+ doc_ctx->onattachmentstatuschange(event, doc_ctx->onattachmentstatuschangedata);
+ }
+ }
+
+ if(ctx->onattachmentstatuschange) {
+ event->obj = ctx->obj ? ctx->obj : obj;
+ event->window = event->obj ? event->obj->window : NULL;
+ event->document = ctx->self_doc ? ctx->self_doc : ctx->document;
+ ctx->onattachmentstatuschange(event, ctx->onattachmentstatuschangedata);
+ }
+}
+
+void uic_send_status_change(UiContext *ctx, UiObject *obj) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ send_status_change(ctx, &event, obj);
+}
+
+
static UiVar* ctx_getvar(UiContext *ctx, CxHashKey key) {
UiVar *var = cxMapGet(ctx->vars, key);
if(!var && ctx->documents) {
case UI_VAR_LIST: {
UiList *f = from;
UiList *t = to;
+ // save selection
+ ui_list_selection_free(f->saved_selection);
+ if(f->getselection && f->save_selection) {
+ f->saved_selection = ui_list_get_selection_allocated(f);
+ } else {
+ f->saved_selection = NULL;
+ }
+
uic_list_copy(f, t);
ui_list_update(t);
+ if(t->setselection && t->saved_selection) {
+ t->setselection(t, *t->saved_selection);
+ }
+ ui_list_selection_free(t->saved_selection);
+ t->saved_selection = NULL;
break;
}
case UI_VAR_RANGE: {
}
void ui_context_closefunc(UiContext *ctx, ui_callback fnc, void *udata) {
- ctx->close_callback = fnc;
- ctx->close_data = udata;
-}
-
-void ui_context_destroy(UiContext *ctx) {
- CxIterator i = cxListIterator(ctx->destroy_handler);
- cx_foreach(UiDestroyHandler *, h, i) {
- h->destructor(h->data);
- }
- cxMempoolFree(ctx->mp);
+ ctx->onclose = fnc;
+ ctx->onclosedata = udata;
}
UiContext* ui_context_parent(UiContext *ctx) {
return ctx->parent;
}
+UiContext* ui_context_toplevel_parent(UiContext *ctx) {
+ if(ctx->obj) {
+ return ctx;
+ } else if (ctx->parent) {
+ return ui_context_toplevel_parent(ctx->parent);
+ }
+ return NULL;
+}
+
void ui_set_state(UiContext *ctx, int state) {
if(!cxListIndexValid(ctx->states, cxListFind(ctx->states, &state))) {
}
// enable/disable group widgets
- uic_check_state_widgets(ctx);
+ uic_check_state_widgets(ui_context_toplevel_parent(ctx));
}
void ui_unset_state(UiContext *ctx, int state) {
}
// enable/disable group widgets
- uic_check_state_widgets(ctx);
+ uic_check_state_widgets(ui_context_toplevel_parent(ctx));
+}
+
+void ui_suppress_state(UiContext *ctx, int state) {
+ if(!cxListIndexValid(ctx->suppressed_states, cxListFind(ctx->suppressed_states, &state))) {
+ cxListAdd(ctx->suppressed_states, &state);
+ }
+
+ // enable/disable group widgets
+ uic_check_state_widgets(ui_context_toplevel_parent(ctx));
+}
+
+void ui_unsuppress_state(UiContext *ctx, int state) {
+ int i = cxListFind(ctx->suppressed_states, &state);
+ if(i != -1) {
+ cxListRemove(ctx->suppressed_states, i);
+ }
+
+ // enable/disable group widgets
+ uic_check_state_widgets(ui_context_toplevel_parent(ctx));
+}
+
+typedef struct StatesList {
+ CX_ARRAY(int, states);
+ CX_ARRAY(int, suppressed);
+} StatesList;
+
+static void add_ctx_states(UiContext *ctx, StatesList *states) {
+ size_t nstates = cxListSize(ctx->states);
+ int *ctx_states = cxListAt(ctx->states, 0);
+
+ size_t nsuppressed = cxListSize(ctx->suppressed_states);
+ int *ctx_suppressed_states = cxListAt(ctx->suppressed_states, 0);
+
+ cx_array_add_array(states->states, ctx_states, nstates);
+ cx_array_add_array(states->suppressed, ctx_suppressed_states, nsuppressed);
+
+ CxIterator i = cxListIterator(ctx->documents);
+ cx_foreach(void *, doc, i) {
+ UiContext *doc_ctx = ui_document_context(doc);
+ add_ctx_states(doc_ctx, states);
+ }
}
int* ui_active_states(UiContext *ctx, int *nstates) {
- *nstates = cxListSize(ctx->states);
- return cxListAt(ctx->states, 0);
+ StatesList states;
+ cx_array_init(states.states, 32);
+ cx_array_init(states.suppressed, 8);
+ add_ctx_states(ctx, &states);
+
+ // remove suppressed states
+ for(size_t i=0;i<states.suppressed.size;i++) {
+ int suppressed = states.suppressed.data[i];
+ // important to use ssize_t for the index here
+ for(ssize_t s=0;s<states.states.size;s++) {
+ if(states.states.data[s] == suppressed) {
+ // this state is suppressed
+ if(s+1 < states.states.size) {
+ // copy last element to the current position
+ states.states.data[s] = states.states.data[states.states.size-1];
+ // we need to check the current index again
+ s--;
+ }
+ states.states.size--;
+ }
+ }
+ }
+
+ free(states.suppressed.data);
+ *nstates = (int)states.states.size;
+ return states.states.data;
}
void uic_check_state_widgets(UiContext *ctx) {
- int ngroups = 0;
- int *groups = ui_active_states(ctx, &ngroups);
+ if(!ctx) {
+ return;
+ }
+
+ int nstates = 0;
+ int *states = ui_active_states(ctx, &nstates);
CxIterator i = cxListIterator(ctx->state_widgets);
cx_foreach(UiStateWidget *, gw, i) {
char *check = calloc(1, gw->numstates);
- for(int i=0;i<ngroups;i++) {
+ for(int i=0;i<nstates;i++) {
for(int k=0;k<gw->numstates;k++) {
- if(groups[i] == gw->states[k]) {
+ if(states[i] == gw->states[k]) {
check[k] = 1;
}
}
free(check);
gw->enable(gw->widget, enable);
}
+
+ free(states);
}
void ui_widget_set_states(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, ...) {
ui_widget_set_states2(ctx, widget, (ui_enablefunc)ui_set_visible, states, nstates);
}
+void uic_widget_set_visibility_states(UiContext *ctx, UIWIDGET widget, const int *states) {
+ if(states) {
+ size_t nstates = uic_state_array_size(states);
+ ui_widget_set_visibility_states(ctx, widget, states, (int)nstates);
+ }
+}
+
size_t uic_state_array_size(const int *states) {
int i;
for(i=0;states[i] >= 0;i++) { }
}
void* ui_malloc(UiContext *ctx, size_t size) {
- return ctx ? cxMalloc(ctx->allocator, size) : NULL;
+ return ctx ? cxMalloc(ctx->allocator, size) : malloc(size);
}
void* ui_calloc(UiContext *ctx, size_t nelem, size_t elsize) {
- return ctx ? cxCalloc(ctx->allocator, nelem, elsize) : NULL;
+ return ctx ? cxCalloc(ctx->allocator, nelem, elsize) : calloc(nelem, elsize);
}
void ui_free(UiContext *ctx, void *ptr) {
- if(ctx && ptr) {
- cxFree(ctx->allocator, ptr);
+ if(ptr) {
+ if(ctx) {
+ cxFree(ctx->allocator, ptr);
+ } else {
+ free(ptr);
+ }
}
}
void* ui_realloc(UiContext *ctx, void *ptr, size_t size) {
- return ctx ? cxRealloc(ctx->allocator, ptr, size) : NULL;
+ return ctx ? cxRealloc(ctx->allocator, ptr, size) : realloc(ptr, size);
}
char* ui_strdup(UiContext *ctx, const char *str) {
if(!ctx) {
- return NULL;
+ return strdup(str ? str : "");
}
cxstring s = cx_str(str);
cxmutstr d = cx_strdup_a(ctx->allocator, s);
}
void ui_reg_destructor(UiContext *ctx, void *data, ui_destructor_func destr) {
- cxMempoolRegister(ctx->mp, data, (cx_destructor_func)destr);
+ //cxMempoolRegister(ctx->mp, data, (cx_destructor_func)destr);
+ uic_context_add_destructor(ctx, destr, data);
+}
+
+void ui_remove_destructor(UiContext *ctx, void *data) {
+ uic_context_remove_destructor(ctx, data);
}
void ui_set_destructor(void *mem, ui_destructor_func destr) {
UiVar *var = uic_get_var_t(ctx, name, UI_VAR_GENERIC);
return var ? var->value : NULL;
}
+
+
+
+void ui_context_onattach(UiContext *ctx, ui_callback cb, void *data) {
+ ctx->onattach = cb;
+ ctx->onattachdata = data;
+}
+
+void ui_context_ondetach(UiContext *ctx, ui_callback cb, void *data) {
+ ctx->ondetach = cb;
+ ctx->ondetachdata = data;
+}
+
+void ui_context_onattachmentstatuschange(UiContext *ctx, ui_callback cb, void *data) {
+ ctx->onattachmentstatuschange = cb;
+ ctx->onattachmentstatuschangedata = data;
+}
+
+static void attachment_action_callback(UiEvent *event, void *action) {
+ if(event->document) {
+ UiContext *ctx = ui_document_context(event->document);
+ ui_call_action_on(ctx, action);
+ }
+}
+
+void ui_context_onattach_action(UiContext *ctx, const char *action) {
+ ctx->onattach = attachment_action_callback;
+ ctx->onattachdata = ui_strdup(ctx, action);
+}
+
+void ui_context_ondetach_action(UiContext *ctx, const char *action) {
+ ctx->ondetach = attachment_action_callback;
+ ctx->ondetachdata = ui_strdup(ctx, action);
+}
+
+void ui_context_onattachmentstatuschange_action(UiContext *ctx, const char *action) {
+ ctx->onattachmentstatuschange = attachment_action_callback;
+ ctx->onattachmentstatuschangedata = ui_strdup(ctx, action);
+}
+
+
+int ui_context_is_attached(UiContext *ctx) {
+ return ctx->parent != NULL;
+}
+
+int ui_context_is_attached_to_obj(UiContext *ctx) {
+ return uic_obj_context(ctx) != NULL;
+}
+
+UIEXPORT UiObject* ui_context_get_parent_obj(UiContext *ctx) {
+ UiContext *obj_ctx = uic_obj_context(ctx);
+ return obj_ctx ? obj_ctx->obj : NULL;
+}
+
+UiContext* uic_obj_context(UiContext *ctx) {
+ if(ctx->obj) {
+ return ctx;
+ }
+ if(ctx->parent == NULL) {
+ return NULL;
+ }
+ return uic_obj_context(ctx->parent);
+}
#include <cx/list.h>
#include <cx/linked_list.h>
+#include "action.h"
+
#ifdef __cplusplus
extern "C" {
#endif
struct UiContext {
UiContext *parent;
UiObject *obj;
- CxMempool *mp;
+ CxMempool *mp;
const CxAllocator *allocator;
CxList *destroy_handler;
+ // document pointer, if this is a document context
+ void *self_doc;
+
void *document;
CxList *documents;
CxMap *vars;
CxList *states; // int list
+ CxList *suppressed_states; // int list
CxList *state_widgets; // UiGroupWidget list
- void (*attach_document)(UiContext *ctx, void *document);
- void (*detach_document2)(UiContext *ctx, void *document);
+ CxMap *actions; // key: action name (string), value: UiAction
+ CxList *action_bindings; // UiActionBinding list
char *title;
// attaching a document will automatically detach the current document
UiBool single_document_mode;
- ui_callback close_callback;
- void *close_data;
+ ui_callback onattach;
+ void *onattachdata;
+
+ ui_callback ondetach;
+ void *ondetachdata;
+
+ ui_callback onattachmentstatuschange;
+ void *onattachmentstatuschangedata;
+
+ ui_callback onclose;
+ void *onclosedata;
+
+ unsigned int ref;
};
struct UiVar {
UiContext* uic_context(UiObject *toplevel, CxMempool *mp);
UiContext* uic_root_context(UiContext *ctx);
void uic_context_add_destructor(UiContext *ctx, cx_destructor_func func, void *data);
+void uic_context_remove_destructor(UiContext *ctx, void *data);
void uic_context_prepare_close(UiContext *ctx);
+void uic_context_destroy(UiContext *ctx, void *document);
+void uic_context_update_bindings(UiContext *ctx);
void uic_context_attach_document(UiContext *ctx, void *document);
void uic_context_detach_document(UiContext *ctx, void *document);
void uic_context_attach_context(UiContext *ctx, UiContext *doc_ctx); // TODO
void uic_context_detach_context(UiContext *ctx, UiContext *doc_ctx); // TODO
void uic_context_detach_all(UiContext *ctx);
+void uic_send_status_change(UiContext *ctx, UiObject *obj);
+
UiVar* uic_get_var(UiContext *ctx, const char *name);
UiVar* uic_get_var_t(UiContext *ctx, const char *name, UiVarType type);
UiVar* uic_create_var(UiContext *ctx, const char *name, UiVarType type);
void uic_reg_var(UiContext *ctx, const char *name, UiVarType type, void *value);
+void uic_widget_set_visibility_states(UiContext *ctx, UIWIDGET widget, const int *states);
size_t uic_state_array_size(const int *states);
void uic_check_state_widgets(UiContext *ctx);
void uic_add_state_widget(UiContext *ctx, void *widget, ui_enablefunc enable, CxList *states);
void uic_add_state_widget_i(UiContext *ctx, void *widget, ui_enablefunc enable, const int *states, size_t numstates);
void uic_remove_state_widget(UiContext *ctx, void *widget);
+UiContext* uic_obj_context(UiContext *ctx);
+
+UIEXPORT void ui_context_onattach(UiContext *ctx, ui_callback cb, void *data);
+UIEXPORT void ui_context_ondetach(UiContext *ctx, ui_callback cb, void *data);
+UIEXPORT void ui_context_onattachmentstatuschange(UiContext *ctx, ui_callback cb, void *data);
+UIEXPORT void ui_context_onattach_action(UiContext *ctx, const char *action);
+UIEXPORT void ui_context_ondetach_action(UiContext *ctx, const char *action);
+UIEXPORT void ui_context_onattachmentstatuschange_action(UiContext *ctx, const char *action);
+
+UIEXPORT int ui_context_is_attached(UiContext *ctx);
+UIEXPORT int ui_context_is_attached_to_obj(UiContext *ctx);
+UIEXPORT UiObject* ui_context_get_parent_obj(UiContext *ctx);
+
#ifdef __cplusplus
}
#endif
UiDoc *document = cxCalloc(a, sizeof(UiDoc) + size, 1);
document->ctx = ctx;
- return &document->doc;
+ ctx->self_doc = &document->doc;
+ return ctx->self_doc;
}
void ui_document_destroy(void *doc) {
+ uic_context_destroy(ui_document_context(doc), doc);
+}
+
+void ui_document_ref(void *doc) {
UiContext *ctx = ui_document_context(doc);
if(ctx) {
- UiEvent ev;
- ev.window = NULL;
- ev.document = doc;
- ev.obj = NULL;
- ev.eventdata = NULL;
- ev.eventdatatype = 0;
- ev.intval = 0;
-
- if(ctx->close_callback) {
- ctx->close_callback(&ev, ctx->close_data);
+ ctx->ref++;
+ }
+}
+
+void ui_document_unref(void *doc) {
+ UiContext *ctx = ui_document_context(doc);
+ if(ctx) {
+ if(--ctx->ref == 0) {
+ uic_context_destroy(ctx, doc);
}
- cxMempoolFree(ctx->mp);
}
}
return NULL;
}
}
+
+void* ui_context_document(UiContext *ctx) {
+ return ctx->self_doc;
+}
+
+UiObject* ui_context_obj(UiContext *ctx) {
+ return ctx->obj;
+}
+
+void ui_document_onattach(void *doc, ui_callback cb, void *data) {
+ UiContext *ctx = ui_document_context(doc);
+ ui_context_onattach(ctx, cb, data);
+}
+
+void ui_document_ondetach(void *doc, ui_callback cb, void *data) {
+ UiContext *ctx = ui_document_context(doc);
+ ui_context_ondetach(ctx, cb, data);
+}
+
+void ui_document_onattachmentstatuschange(void *doc, ui_callback cb, void *data) {
+ UiContext *ctx = ui_document_context(doc);
+ ui_context_onattachmentstatuschange(ctx, cb, data);
+}
+
+void ui_document_onattach_action(void *doc, const char *action) {
+ UiContext *ctx = ui_document_context(doc);
+ ui_context_onattach_action(ctx, action);
+}
+
+void ui_document_ondetach_action(void *doc, const char *action) {
+ UiContext *ctx = ui_document_context(doc);
+ ui_context_ondetach_action(ctx, action);
+}
+
+void ui_document_onattachmentstatuschange_action(void *doc, const char *action) {
+ UiContext *ctx = ui_document_context(doc);
+ ui_context_onattachmentstatuschange_action(ctx, action);
+}
+
+
+int ui_document_is_attached(void *doc) {
+ UiContext *ctx = ui_document_context(doc);
+ return ui_context_is_attached(ctx);
+}
+
+int ui_document_is_attached_to_obj(void *doc) {
+ UiContext *ctx = ui_document_context(doc);
+ return ui_context_is_attached_to_obj(ctx);
+}
--- /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_NEW_TAB : return UI_ICON_NEW_TAB;
+ case UI_ICON_ID_NEW_FOLDER : return UI_ICON_NEW_FOLDER;
+ case UI_ICON_ID_NEW_DOCUMENT : return UI_ICON_NEW_DOCUMENT;
+ case UI_ICON_ID_NEW_APPOINTMENT : return UI_ICON_NEW_APPOINTMENT;
+ case UI_ICON_ID_NEW_CHAT_MESSAGE : return UI_ICON_NEW_CHAT_MESSAGE;
+ case UI_ICON_ID_NEW_CONTACT : return UI_ICON_NEW_CONTACT;
+ case UI_ICON_ID_NEW_MAIL : return UI_ICON_NEW_MAIL;
+ case UI_ICON_ID_ADD_BOOKMARK : return UI_ICON_ADD_BOOKMARK;
+ case UI_ICON_ID_ADD_IMAGE : return UI_ICON_ADD_IMAGE;
+ case UI_ICON_ID_ADD_LINK : return UI_ICON_ADD_LINK;
+ case UI_ICON_ID_ADD_TEXT : return UI_ICON_ADD_TEXT;
+ case UI_ICON_ID_ADD : return UI_ICON_ADD;
+ case UI_ICON_ID_REMOVE : return UI_ICON_REMOVE;
+ case UI_ICON_ID_REFRESH : return UI_ICON_REFRESH;
+ case UI_ICON_ID_UPLOAD : return UI_ICON_UPLOAD;
+ case UI_ICON_ID_SAVE_LOCAL : return UI_ICON_SAVE_LOCAL;
+ case UI_ICON_ID_EDIT_COPY : return UI_ICON_EDIT_COPY;
+ case UI_ICON_ID_EDIT_CUT : return UI_ICON_EDIT_CUT;
+ case UI_ICON_ID_EDIT_DELETE : return UI_ICON_EDIT_DELETE;
+ case UI_ICON_ID_EDIT_PASTE : return UI_ICON_EDIT_PASTE ;
+ case UI_ICON_ID_UNDO : return UI_ICON_UNDO;
+ case UI_ICON_ID_REDO : return UI_ICON_REDO;
+ case UI_ICON_ID_SIDEBAR_LEFT : return UI_ICON_SIDEBAR_LEFT;
+ case UI_ICON_ID_SIDEBAR_RIGHT : return UI_ICON_SIDEBAR_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;
+ case UI_ICON_ID_VIEW_LIST : return UI_ICON_VIEW_LIST;
+ case UI_ICON_ID_VIEW_GRID : return UI_ICON_VIEW_GRID;
+ case UI_ICON_ID_VIEW_DUAL : return UI_ICON_VIEW_DUAL;
+ case UI_ICON_ID_VIEW_FULLSCREEN : return UI_ICON_VIEW_FULLSCREEN;
+ case UI_ICON_ID_VIEW_RESTORE : return UI_ICON_VIEW_RESTORE;
+ case UI_ICON_ID_TEXT_BOLD : return UI_ICON_TEXT_BOLD;
+ case UI_ICON_ID_TEXT_ITALIC : return UI_ICON_TEXT_ITALIC;
+ case UI_ICON_ID_TEXT_UNDERLINE : return UI_ICON_TEXT_UNDERLINE;
+ case UI_ICON_ID_LIST_BULLET : return UI_ICON_LIST_BULLET ;
+ case UI_ICON_ID_LIST_ORDERED : return UI_ICON_LIST_ORDERED;
+ case UI_ICON_ID_LIST_CHECK : return UI_ICON_LIST_CHECK;
+ case UI_ICON_ID_CHECKBOX : return UI_ICON_CHECKBOX;
+ case UI_ICON_ID_STAR : return UI_ICON_STAR;
+ case UI_ICON_ID_VIEW_REVEAL : return UI_ICON_VIEW_REVEAL;
+ case UI_ICON_ID_VIEW_CONCEAL : return UI_ICON_VIEW_CONCEAL;
+ case UI_ICON_ID_SETTINGS : return UI_ICON_SETTINGS;
+ case UI_ICON_ID_MEDIA_PLAY : return UI_ICON_MEDIA_PLAY;
+ case UI_ICON_ID_MEDIA_STOP : return UI_ICON_MEDIA_STOP;
+ case UI_ICON_ID_MEDIA_PAUSE : return UI_ICON_MEDIA_PAUSE;
+ case UI_ICON_ID_MEDIA_SEEK_BACKWARD : return UI_ICON_MEDIA_SEEK_BACKWARD;
+ case UI_ICON_ID_MEDIA_SEEK_FORWARD : return UI_ICON_MEDIA_SEEK_FORWARD;
+ case UI_ICON_ID_MEDIA_SKIP_BACKWARD : return UI_ICON_MEDIA_SKIP_BACKWARD;
+ case UI_ICON_ID_MEDIA_SKIP_FORWARD : return UI_ICON_MEDIA_SKIP_FORWARD;
+ case UI_ICON_ID_CALL_START : return UI_ICON_CALL_START;
+ case UI_ICON_ID_CALL_STOP : return UI_ICON_CALL_STOP;
+ case UI_ICON_ID_CALL_INCOMING : return UI_ICON_CALL_INCOMING;
+ case UI_ICON_ID_CALL_OUTGOING : return UI_ICON_CALL_OUTGOING;
+ case UI_ICON_ID_MICROPHONE_ON : return UI_ICON_MICROPHONE_ON;
+ case UI_ICON_ID_MICROPHONE_OFF : return UI_ICON_MICROPHONE_OFF;
+ case UI_ICON_ID_LOCKED : return UI_ICON_LOCKED;
+ case UI_ICON_ID_UNLOCKED : return UI_ICON_UNLOCKED;
+ case UI_ICON_ID_SECURE : return UI_ICON_SECURE;
+ case UI_ICON_ID_INSECURE : return UI_ICON_INSECURE;
+ }
+ 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 */
+
static void *tmp_eventdata;
static int tmp_eventdata_type;
+
+static void* getvalue_wrapper(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) {
+ ui_getvaluefunc getvalue = (ui_getvaluefunc)userdata;
+ return getvalue(elm, col);
+}
+
+static void* str_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) {
+ return elm;
+}
+
+
void uic_set_tmp_eventdata(void *eventdata, int type) {
tmp_eventdata = eventdata;
tmp_eventdata_type = type;
item->item.next = NULL;
item->item.type = UI_MENU_ITEM;
+ item->action = nl_strdup(args->action);
item->label = nl_strdup(args->label);
item->icon = nl_strdup(args->icon);
item->userdata = args->onclickdata;
item->item.prev = NULL;
item->item.next = NULL;
item->item.type = UI_MENU_ITEM_LIST;
- item->getvalue = args->getvalue;
+ if(args->getvalue2) {
+ item->getvalue = args->getvalue2;
+ item->getvaluedata = args->getvaluedata;
+ } else if(args->getvalue) {
+ item->getvalue = getvalue_wrapper;
+ item->getvaluedata = (void*)args->getvalue;
+ } else {
+ item->getvalue = str_getvalue;
+ }
item->callback = args->onselect;
item->userdata = args->onselectdata;
item->varname = nl_strdup(args->varname);
item->item.prev = NULL;
item->item.next = NULL;
item->item.type = UI_MENU_CHECKITEM_LIST;
+ if(args->getvalue2) {
+ item->getvalue = args->getvalue2;
+ item->getvaluedata = args->getvaluedata;
+ } else if(args->getvalue) {
+ item->getvalue = getvalue_wrapper;
+ item->getvaluedata = (void*)args->getvalue;
+ } else {
+ item->getvalue = str_getvalue;
+ }
item->callback = args->onselect;
item->userdata = args->onselectdata;
item->varname = nl_strdup(args->varname);
item->item.prev = NULL;
item->item.next = NULL;
item->item.type = UI_MENU_RADIOITEM_LIST;
+ if(args->getvalue2) {
+ item->getvalue = args->getvalue2;
+ item->getvaluedata = args->getvaluedata;
+ } else if(args->getvalue) {
+ item->getvalue = getvalue_wrapper;
+ item->getvaluedata = (void*)args->getvalue;
+ } else {
+ item->getvalue = str_getvalue;
+ }
item->callback = args->onselect;
item->userdata = args->onselectdata;
item->varname = nl_strdup(args->varname);
struct UiMenuItem {
UiMenuItemI item;
ui_callback callback;
+ char *action;
char *label;
char *icon;
void *userdata;
};
struct UiMenuItemList {
- UiMenuItemI item;
- ui_getvaluefunc getvalue;
- ui_callback callback;
- void *userdata;
- char *varname;
- UiBool addseparator;
+ UiMenuItemI item;
+ ui_getvaluefunc2 getvalue;
+ void *getvaluedata;
+ ui_callback callback;
+ void *userdata;
+ char *varname;
+ UiBool addseparator;
};
static CxList *creation_callbacks;
static CxList *destruction_callbacks;
+static CxList *objects;
+
typedef struct objcallback {
ui_object_callback func;
void *userdata;
cxListAdd(destruction_callbacks, &cb);
}
+UiObject* ui_dummy_object(void) {
+ UiObject *obj = uic_object_new_toplevel();
+ obj->ref = 1;
+ return obj;
+}
+
void uic_object_created(UiObject *obj) {
+ if(!objects) {
+ objects = cxLinkedListCreate(NULL, CX_STORE_POINTERS);
+ }
+ cxListAdd(objects, obj);
+
CxIterator i = cxListIterator(creation_callbacks);
cx_foreach(objcallback *, cb, i) {
cb->func(obj, cb->userdata);
}
void uic_object_destroyed(UiObject *obj) {
+ if(objects) {
+ cxListFindRemove(objects, obj);
+ }
+
CxIterator i = cxListIterator(destruction_callbacks);
cx_foreach(objcallback *, cb, i) {
cb->func(obj, cb->userdata);
}
}
+CxList* uic_object_list(void) {
+ return objects ? objects : cxEmptyList;
+}
+
void ui_object_ref(UiObject *obj) {
obj->ref++;
}
// it is possible to have 0 references, in case
// a window was created but ui_show was never called
if(obj->ref == 0 || --obj->ref == 0) {
+ uic_context_prepare_close(obj->ctx);
if(obj->destroy) {
obj->destroy(obj);
+ } else {
+ uic_object_destroy(obj);
}
- uic_object_destroy(obj);
return 0;
}
return 1;
}
void uic_object_destroy(UiObject *obj) {
- if(obj->ctx->close_callback) {
- UiEvent ev;
- ev.window = obj->window;
- ev.document = obj->ctx->document;
- ev.obj = obj;
- ev.eventdata = NULL;
- ev.eventdatatype = 0;
- ev.intval = 0;
- obj->ctx->close_callback(&ev, obj->ctx->close_data);
- }
uic_object_destroyed(obj);
- cxMempoolFree(obj->ctx->mp);
+ uic_context_destroy(obj->ctx, obj->ctx->document);
}
UiObject* uic_object_new_toplevel(void) {
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) {
void uic_object_destroyed(UiObject *obj);
void uic_object_destroy(UiObject *obj);
+
+CxList* uic_object_list(void);
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);
COMMON_OBJ = context$(OBJ_EXT)
COMMON_OBJ += document$(OBJ_EXT)
COMMON_OBJ += object$(OBJ_EXT)
+COMMON_OBJ += action$(OBJ_EXT)
COMMON_OBJ += container$(OBJ_EXT)
COMMON_OBJ += types$(OBJ_EXT)
COMMON_OBJ += app$(OBJ_EXT)
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)
static void *properties_data = NULL;
static size_t properties_data_length = 0;
+static char *config_root = NULL;
+
void ui_load_properties_file_on_startup(UiBool enable) {
load_on_startup = enable;
}
}
char* ui_getappdir(void) {
- if(ui_appname() == NULL) {
+ if(ui_appname() == NULL && config_root == NULL) {
return NULL;
}
return ui_configfile(NULL);
}
+void ui_setappdir(const char *path) {
+ free(config_root);
+ if(path) {
+ cxmutstr cfgpath = cx_strdup(path);
+ config_root = cfgpath.ptr;
+ if(cfgpath.length > 0 && cfgpath.ptr[cfgpath.length-1] == '/') {
+ config_root[cfgpath.length-1] = 0;
+ }
+ } else {
+ config_root = NULL;
+ }
+}
+
#ifndef _WIN32
#define UI_PATH_SEPARATOR '/'
#define UI_ENV_HOME "HOME"
#define UI_XDG_CONFIG_HOME_VAR "XDG_CONFIG_HOME"
char* ui_configfile(const char *name) {
+ if(config_root) {
+ if(!name) {
+ return strdup(config_root);
+ } else if(name[0] == '/') {
+ return cx_strdup(cx_strcat(CX_NULLSTR, 2, cx_str(config_root), cx_str(name))).ptr;
+ } else {
+ return cx_strdup(cx_strcat(CX_NULLSTR, 3, cx_str(config_root), cx_str("/"), cx_str(name))).ptr;
+ }
+ }
+
const char *appname = ui_appname();
if(!appname) {
return NULL;
return;
}
- if(!ui_appname()) {
- // applications without name cannot load app properties
- return;
- }
-
char *dir = ui_configfile(NULL);
if(!dir) {
return;
#include "threadpool.h"
#include "context.h"
+#include <cx/linked_list.h>
#include <pthread.h>
#include <stdio.h>
static threadpool_job kill_job;
+
+
+static pthread_mutex_t mc_buffer_mutex;
+static pthread_cond_t mc_buffer_available;
+static CxList *mainthread_call_buffer;
+static volatile int mainthread_call_buffered = 0;
+
+typedef struct UiMainCall {
+ ui_threadfunc func;
+ void *data;
+} UiMainCall;
+
+void uic_init_threads(void) {
+ pthread_mutex_init(&mc_buffer_mutex, NULL);
+ pthread_cond_init(&mc_buffer_available, NULL);
+ mainthread_call_buffer = cxLinkedListCreate(NULL, sizeof(UiMainCall));
+}
+
+int uic_mainthread_calls_is_buffered(void) {
+ return mainthread_call_buffered;
+}
+
+void uic_add_buffered_mainthread_call(ui_threadfunc func, void *data) {
+ pthread_mutex_lock(&mc_buffer_mutex);
+ UiMainCall call;
+ call.func = func;
+ call.data = data;
+ cxListAdd(mainthread_call_buffer, &call);
+ pthread_cond_signal(&mc_buffer_available);
+ pthread_mutex_unlock(&mc_buffer_mutex);
+}
+
+
+void ui_buffer_mainthread_calls(UiBool enable_buffering) {
+ mainthread_call_buffered = enable_buffering;
+ if(!enable_buffering) {
+ ui_exec_buffered_mainthread_calls();
+ }
+}
+
+static void exec_buffered_calls(void) {
+ CxIterator i = cxListIterator(mainthread_call_buffer);
+ cx_foreach(UiMainCall *, call, i) {
+ if(call->func) {
+ call->func(call->data);
+ }
+ }
+ cxListClear(mainthread_call_buffer);
+}
+
+void ui_exec_buffered_mainthread_calls(void) {
+ pthread_mutex_lock(&mc_buffer_mutex);
+ exec_buffered_calls();
+ pthread_mutex_unlock(&mc_buffer_mutex);
+}
+
+UIEXPORT void ui_exec_buffered_mainthread_calls_wait(int timeout) {
+ struct timespec ts;
+ if(timeout > 0) {
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += timeout;
+ }
+
+ pthread_mutex_lock(&mc_buffer_mutex);
+ while(cxListSize(mainthread_call_buffer) == 0) {
+ if(timeout > 0) {
+ if(pthread_cond_timedwait(&mc_buffer_available, &mc_buffer_mutex, &ts)) {
+ break;
+ }
+ } else {
+ pthread_cond_wait(&mc_buffer_available, &mc_buffer_mutex);
+ }
+ }
+ exec_buffered_calls();
+ pthread_mutex_unlock(&mc_buffer_mutex);
+}
+
UiThreadpool* threadpool_new(int min, int max) {
UiThreadpool *pool = malloc(sizeof(UiThreadpool));
pool->queue = ui_queue_create();
extern "C" {
#endif
+void uic_init_threads(void);
+int uic_mainthread_calls_is_buffered(void);
+void uic_add_buffered_mainthread_call(ui_threadfunc func, void *data);
+
typedef struct UiQueueElm UiQueueElm;
typedef struct UiQueue UiQueue;
newargs.tooltip = nl_strdup(args->tooltip);\r
newargs.onclick = args->onclick;\r
newargs.onclickdata = args->onclickdata;\r
+ newargs.action = nl_strdup(args->action);\r
newargs.states = uic_copy_states(args->states, ngroups);\r
newargs.visibility_states = uic_copy_states(args->visibility_states, nvstates);\r
return newargs;\r
newargs.varname = nl_strdup(args->varname);\r
newargs.onchange = args->onchange;\r
newargs.onchangedata = args->onchangedata;\r
+ newargs.action = nl_strdup(args->action);\r
+ newargs.states = uic_copy_states(args->states, ngroups);\r
+ newargs.visibility_states = uic_copy_states(args->visibility_states, nvstates);\r
+ return newargs;\r
+}\r
+\r
+static UiToolbarContentToggleItemArgs contenttoggleitemargs_copy(UiToolbarContentToggleItemArgs *args, size_t *ngroups, size_t *nvstates) {\r
+ UiToolbarContentToggleItemArgs newargs;\r
+ newargs.label0 = nl_strdup(args->label0);\r
+ newargs.icon0 = nl_strdup(args->icon0);\r
+ newargs.tooltip0 = nl_strdup(args->tooltip0);\r
+ newargs.label1 = nl_strdup(args->label1);\r
+ newargs.icon1 = nl_strdup(args->icon1);\r
+ newargs.tooltip1 = nl_strdup(args->tooltip1);\r
+ newargs.varname = nl_strdup(args->varname);\r
+ newargs.onchange = args->onchange;\r
+ newargs.onchangedata = args->onchangedata;\r
+ newargs.action = nl_strdup(args->action);\r
+ newargs.toggled_by_state = args->toggled_by_state;\r
+ newargs.istogglebutton = args->istogglebutton;\r
newargs.states = uic_copy_states(args->states, ngroups);\r
newargs.visibility_states = uic_copy_states(args->visibility_states, nvstates);\r
return newargs;\r
cxMapPut(toolbar_items, name, item);\r
}\r
\r
+void ui_toolbar_content_toggleitem_create(const char* name, UiToolbarContentToggleItemArgs *args) {\r
+ UiToolbarContentToggleItem* item = malloc(sizeof(UiToolbarContentToggleItem));\r
+ item->item.type = UI_TOOLBAR_CONTENT_TOGGLEITEM;\r
+ item->args = contenttoggleitemargs_copy(args, &item->nstates, &item->nvstates);\r
+ cxMapPut(toolbar_items, name, item);\r
+}\r
+\r
static UiToolbarMenuArgs menuargs_copy(UiToolbarMenuArgs *args, size_t *nvstates) {\r
UiToolbarMenuArgs newargs;\r
newargs.label = nl_strdup(args->label);\r
extern "C" {\r
#endif\r
\r
-typedef struct UiToolbarItemI UiToolbarItemI;\r
+typedef struct UiToolbarItemI UiToolbarItemI;\r
\r
-typedef struct UiToolbarItem UiToolbarItem;\r
-typedef struct UiToolbarToggleItem UiToolbarToggleItem;\r
+typedef struct UiToolbarItem UiToolbarItem;\r
+typedef struct UiToolbarToggleItem UiToolbarToggleItem;\r
+typedef struct UiToolbarContentToggleItem UiToolbarContentToggleItem;\r
\r
-typedef struct UiToolbarMenuItem UiToolbarMenuItem;\r
+typedef struct UiToolbarMenuItem UiToolbarMenuItem;\r
\r
enum UiToolbarItemType {\r
UI_TOOLBAR_ITEM = 0,\r
UI_TOOLBAR_TOGGLEITEM,\r
+ UI_TOOLBAR_CONTENT_TOGGLEITEM,\r
UI_TOOLBAR_MENU\r
};\r
\r
size_t nvstates;\r
};\r
\r
+struct UiToolbarContentToggleItem {\r
+ UiToolbarItemI item;\r
+ UiToolbarContentToggleItemArgs args;\r
+ size_t nstates;\r
+ size_t nvstates;\r
+};\r
+\r
struct UiToolbarMenuItem {\r
UiToolbarItemI item;\r
UiMenu menu;\r
/* --------------------------- UiList --------------------------- */
void uic_ucx_list_init(UiContext *ctx, UiList *list, void *unused) {
- list->data = cxArrayListCreate(ctx->mp->allocator, CX_STORE_POINTERS, 32);
+ const CxAllocator *a = ctx ? ctx->allocator : cxDefaultAllocator;
+ list->destroy = uic_ucx_list_destroy;
+ list->data = cxArrayListCreate(a, CX_STORE_POINTERS, 32);
list->first = ui_list_first;
list->next = ui_list_next;
list->get = ui_list_get;
void uic_ucx_list_destroy(UiContext *ctx, UiList *list, void *unused) {
cxListFree(list->data);
- ui_free(ctx, list);
}
UiList* ui_list_new(UiContext *ctx, const char *name) {
}
UiList* ui_list_new2(UiContext *ctx, const char *name, ui_list_init_func listinit, void *userdata) {
- UiList *list = cxMalloc(ctx->mp->allocator, sizeof(UiList));
+ UiList *list = ui_malloc(ctx, sizeof(UiList));
memset(list, 0, sizeof(UiList));
listinit(ctx, list, userdata);
+ list->save_selection = TRUE;
- if(name) {
+ if(name && ctx) {
uic_reg_var(ctx, name, UI_VAR_LIST, list);
}
}
void ui_list_free(UiContext *ctx, UiList *list) {
- if(!default_list_destroy) {
+ if(list->destroy) {
+ list->destroy(ctx, list, NULL);
+ } else if(!default_list_destroy) {
uic_ucx_list_destroy(ctx, list, NULL);
} else {
default_list_destroy(ctx, list, default_list_destroy_userdata);
}
-
+ ui_list_selection_free(list->saved_selection);
+ ui_free(ctx, list);
}
void* ui_list_first(UiList *list) {
}
void* ui_list_get(UiList *list, int i) {
- return cxListAt(list->data, i);
+ return i >= 0 ? cxListAt(list->data, i) : NULL;
}
int ui_list_count(UiList *list) {
cxListInsert(list->data, 0, data);
}
+void ui_list_insert(UiList *list, int index, void *data) {
+ cxListInsert(list->data, (size_t)index, data);
+}
+
void ui_list_remove(UiList *list, int i) {
- cxListRemove(list->data, i);
+ if(i >= 0) {
+ cxListRemove(list->data, i);
+ }
}
void ui_list_clear(UiList *list) {
}
}
+UIEXPORT void ui_list_set_selection(UiList *list, UiListSelection sel) {
+ if(list->setselection) {
+ list->setselection(list, sel);
+ }
+}
+
void ui_list_addobsv(UiList *list, ui_callback f, void *data) {
list->observers = ui_add_observer(list->observers, f, data);
}
ui_notify(list->observers, list);
}
+void ui_list_clear_saved_selection(UiList *list) {
+ ui_list_selection_free(list->saved_selection);
+ list->saved_selection = NULL;
+}
+
typedef struct {
int type;
UiModel* ui_model(UiContext *ctx, ...) {
UiModel *info = ui_calloc(ctx, 1, sizeof(UiModel));
info->ctx = ctx;
+ info->ref = 1;
va_list ap;
va_start(ap, ctx);
UiModel* ui_model_new(UiContext *ctx) {
UiModel *info = ui_calloc(ctx, 1, sizeof(UiModel));
info->ctx = ctx;
+ info->ref = 1;
info->alloc = UI_MODEL_DEFAULT_ALLOC_SIZE;
info->types = ui_calloc(ctx, UI_MODEL_DEFAULT_ALLOC_SIZE, sizeof(UiModelType));
info->titles = ui_calloc(ctx, UI_MODEL_DEFAULT_ALLOC_SIZE, sizeof(char*));
void ui_model_free(UiModel *mi) {
UiContext *ctx = mi->ctx;
- const CxAllocator* a = ctx->allocator;
+ const CxAllocator* a = ctx ? ctx->allocator : cxDefaultAllocator;
for(int i=0;i<mi->columns;i++) {
ui_free(ctx, mi->titles[i]);
}
UiInteger* ui_int_new(UiContext *ctx, const char *name) {
UiInteger *i = ui_malloc(ctx, sizeof(UiInteger));
memset(i, 0, sizeof(UiInteger));
- if(name) {
+ if(name && ctx) {
uic_reg_var(ctx, name, UI_VAR_INTEGER, i);
}
return i;
UiDouble* ui_double_new(UiContext *ctx, const char *name) {
UiDouble *d = ui_malloc(ctx, sizeof(UiDouble));
memset(d, 0, sizeof(UiDouble));
- if(name) {
+ if(name && ctx) {
uic_reg_var(ctx, name, UI_VAR_DOUBLE, d);
}
return d;
UiString *s = ui_malloc(ctx, sizeof(UiString));
memset(s, 0, sizeof(UiString));
ui_set_destructor(s, (ui_destructor_func)string_destroy);
- if(name) {
+ if(name && ctx) {
uic_reg_var(ctx, name, UI_VAR_STRING, s);
}
return s;
}
static void text_destroy(UiText *t) {
+ if(t->value.free) {
+ t->value.free(t->value.ptr);
+ }
if(t->destroy) {
t->destroy(t);
}
UiText *t = ui_malloc(ctx, sizeof(UiText));
memset(t, 0, sizeof(UiText));
ui_set_destructor(t, (ui_destructor_func)text_destroy);
- if(name) {
+ if(name && ctx) {
uic_reg_var(ctx, name, UI_VAR_TEXT, t);
}
return t;
UiRange* ui_range_new(UiContext *ctx, const char *name) {
UiRange *r = ui_malloc(ctx, sizeof(UiRange));
memset(r, 0, sizeof(UiRange));
- if(name) {
+ if(name && ctx) {
uic_reg_var(ctx, name, UI_VAR_RANGE, r);
}
return r;
UiGeneric* ui_generic_new(UiContext *ctx, const char *name) {
UiGeneric *g = ui_malloc(ctx, sizeof(UiGeneric));
memset(g, 0, sizeof(UiGeneric));
- ui_set_destructor(g, (ui_destructor_func)generic_destroy);
- if(name) {
+ if(ctx) {
+ ui_set_destructor(g, (ui_destructor_func)generic_destroy);
+ }
+ if(name && ctx) {
uic_reg_var(ctx, name, UI_VAR_GENERIC, g);
}
return g;
if (s) {
if (s->set) {
ui_setop_enable(TRUE);
- s->set(s, value);
+ s->set(s, value ? value : "");
ui_setop_enable(FALSE);
} else {
if(s->value.free) {
if (s) {
if (s->set) {
ui_setop_enable(TRUE);
- s->set(s, value);
+ s->set(s, value ? value : "");
ui_setop_enable(FALSE);
} else {
if(s->value.free) {
to->set = from->set;
to->getsubstr = from->getsubstr;
to->insert = from->insert;
+ to->replace = from->replace;
to->setposition = from->setposition;
to->position = from->position;
+ to->showposition = from->showposition;
+ to->setselection = from->setselection;
to->selection = from->selection;
to->length = from->length;
to->remove = from->remove;
+ to->setreadonly = from->setreadonly;
to->restore = from->restore;
to->save = from->save;
to->destroy = from->destroy;
void uic_generic_save(UiGeneric *g) {
if(!g->obj) return;
+ // TODO: this leaks memory
+ // we can't just use get on Generic and ignore the result
+ // probably a separate save method is required
g->get(g);
}
}
void uic_text_unbind(UiText *t) {
+ t->obj = NULL;
+ if(t->data1 && t->datatype == UI_TEXT_TYPE_BUFFER) {
+ // the binding functions all work with t->data1, not t->obj
+ // and we don't want to NULL them, because they will be still
+ // functional even without a widget binding
+ return;
+ }
+
t->set = NULL;
t->get = NULL;
t->getsubstr = NULL;
t->insert = NULL;
+ t->replace = NULL;
t->setposition = NULL;
t->position = NULL;
+ t->showposition = NULL;
t->selection = NULL;
+ t->setselection = NULL;
t->length = NULL;
t->remove = NULL;
- t->obj = NULL;
+ t->setreadonly = NULL;
}
void uic_range_unbind(UiRange *r) {
}
-UIEXPORT UiListSelection ui_list_getselection(UiList *list) {
+
+UiListSelection* ui_list_get_selection_allocated(UiList *list) {
+ UiListSelection *sel = malloc(sizeof(UiListSelection));
+ *sel = ui_list_get_selection(list);
+ return sel;
+
+}
+
+void ui_list_selection_free(UiListSelection *sel) {
+ if(!sel) {
+ return;
+ }
+ ui_listselection_free(*sel);
+ free(sel);
+}
+
+
+UIEXPORT int ui_list_getselection(UiList *list) {
+ int selection = -1;
if (list->getselection) {
- return list->getselection(list);
+ UiListSelection sel = list->getselection(list);
+ if(sel.count > 0) {
+ selection = sel.rows[0];
+ }
+ ui_listselection_free(sel);
}
- return (UiListSelection){ 0, NULL };
+ return selection;
}
UIEXPORT void ui_list_setselection(UiList *list, int index) {
+ ui_list_setselection2(list, index, TRUE);
+}
+
+UIEXPORT void ui_list_setselection2(UiList *list, int index, UiBool selection_event) {
if (list->setselection) {
UiListSelection sel = { 0, NULL };
if(index >= 0) {
sel.count = 1;
sel.rows = &index;
}
+ UiBool events = ui_selection_events_is_enabled();
+ if(!selection_event) {
+ ui_selection_events_enable(FALSE);
+ }
list->setselection(list, sel);
+ ui_selection_events_enable(events);
}
}
static int ui_set_op = 0;
static int ui_onchange_events_enabled = TRUE;
+static int ui_selection_events_enabled = TRUE;
void ui_setop_enable(int set) {
ui_set_op = set;
return ui_onchange_events_enabled;
}
+void ui_selection_events_enable(UiBool enable) {
+ ui_selection_events_enabled = enable;
+}
+
+UiBool ui_selection_events_is_enabled(void) {
+ return ui_selection_events_enabled;
+}
+
/* ---------------- List initializers and wrapper functions ---------------- */
void ui_global_list_initializer(ui_list_init_func func, void *userdata) {
default_list_destroy_userdata = userdata;
}
+UIEXPORT void ui_list_class_set_destructor(UiList *list, ui_list_destroy_func destroy) {
+ list->destroy = destroy;
+}
+
void ui_list_class_set_first(UiList *list, void*(*first)(UiList *list)) {
list->first = first;
}
void ui_list_class_set_iter(UiList *list, void *iter) {
list->iter = iter;
}
+
+/* ---------------- Text functions ---------------- */
+
+char* ui_text_getsubstr(UiText *text, int begin, int end) {
+ if(text->getsubstr) {
+ return text->getsubstr(text, begin, end);
+ } else {
+ return NULL;
+ }
+}
+
+void ui_text_insert(UiText *text, int pos, const char *str) {
+ if(text->insert) {
+ text->insert(text, pos, str);
+ }
+}
+
+void ui_text_replace(UiText *text, int begin, int end, const char *str) {
+ if(text->replace) {
+ text->replace(text, begin, end, str);
+ }
+}
+
+void ui_text_setposition(UiText *text, int pos) {
+ if(text->setposition) {
+ text->setposition(text, pos);
+ }
+}
+
+int ui_text_position(UiText *text) {
+ if(text->position) {
+ return text->position(text);
+ } else {
+ return 0;
+ }
+}
+
+void ui_text_showposition(UiText *text, int pos) {
+ if(text->showposition) {
+ text->showposition(text, pos);
+ }
+}
+
+void ui_text_setselection(UiText *text, int begin, int end) {
+ if(text->setselection) {
+ text->setselection(text, begin, end);
+ }
+}
+
+void ui_text_selection(UiText *text, int *begin, int *end) {
+ if(text->selection) {
+ text->selection(text, begin, end);
+ } else {
+ if(begin) {
+ *begin = 0;
+ }
+ if(end) {
+ *end = 0;
+ }
+ }
+}
+
+int ui_text_length(UiText *text) {
+ if(text->length) {
+ return text->length(text);
+ } else {
+ return 0;
+ }
+}
+void ui_text_remove(UiText *text, int begin, int end) {
+ if(text->remove) {
+ text->remove(text, begin, end);
+ }
+}
+
+void ui_text_setreadonly(UiText *text, int readonly) {
+ if(text->setreadonly) {
+ text->setreadonly(text, readonly);
+ } else {
+ text->readonly = readonly;
+ }
+}
void uic_list_unbind(UiList *l);
void uic_generic_unbind(UiGeneric *g);
+UIEXPORT UiListSelection* ui_list_get_selection_allocated(UiList *list);
+UIEXPORT void ui_list_selection_free(UiListSelection *sel);
+
void uic_list_register_observer_destructor(UiContext *ctx, UiList *list, UiObserver *observer);
#ifdef __cplusplus
obj->window = windowdata;
}
+void ui_object_set_onclose(UiObject *obj, ui_callback callback, void *userdata) {
+ obj->onclose = callback;
+ obj->onclosedata = userdata;
+}
+
+static int obj_unref(void *ptr) {
+ ui_object_unref(ptr);
+ return 0;
+}
+
+void ui_mainthread_object_unref(UiObject *obj) {
+ // TODO: detect if this is already the main thread and call
+ // ui_object_unref directly in that case
+ ui_call_mainthread(obj_unref, obj);
+}
+
+static int doc_unref(void *ptr) {
+ ui_document_unref(ptr);
+ return 0;
+}
+
+void ui_mainthread_document_unref(void *doc) {
+ // TODO: see ui_mainthread_object_unref
+ 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 ---------------------------- */
list->iter = iter;
}
+void ui_list_set_save_selection(UiList *list, UiBool value) {
+ list->save_selection = value;
+}
+
+UiBool ui_list_get_save_selection(UiList *list) {
+ return list->save_selection;
+}
/* ------------------------------ UiSublist ------------------------------ */
}
+/* ---------------------------- UiTypedObj ---------------------------- */
+
+void* ui_typed_obj_get_ptr(UiTypedObj *obj) {
+ return obj->ptr;
+}
+
+uint64_t ui_typed_obj_get_type(UiTypedObj *obj) {
+ return obj->type;
+}
+
+
/* ------------------------- SubListItem (public) ------------------------- */
void ui_sublist_item_set_icon(UiSubListItem *item, const char *icon) {
/* ---------------------------- UiListSelection ---------------------------- */
-UiListSelection* ui_list_get_selection_allocated(UiList *list) {
- UiListSelection *sel = malloc(sizeof(UiListSelection));
- *sel = ui_list_get_selection(list);
- return sel;
-
-}
-
int ui_list_selection_get_count(UiListSelection *sel) {
return sel->count;
}
}
}
-void ui_list_selection_free(UiListSelection *sel) {
- ui_listselection_free(*sel);
- free(sel);
+
+/* -------------------------- UiTextChangedEvent -------------------------- */
+
+int ui_text_change_event_get_type(UiTextChangeEventData *event) {
+ return event->type;
+}
+
+int ui_text_change_event_get_begin(UiTextChangeEventData *event) {
+ return event->begin;
+}
+
+int ui_text_change_event_get_end(UiTextChangeEventData *event) {
+ return event->end;
+}
+
+const char* ui_text_change_event_get_text(UiTextChangeEventData *event) {
+ return event->text;
+}
+
+int ui_text_change_event_get_length(UiTextChangeEventData *event) {
+ return event->length;
}
/* ---------------------------- UiFileList ---------------------------- */
#include "../ui/toolkit.h"
#include "../ui/list.h"
+#include "../ui/text.h"
#ifdef __cplusplus
extern "C" {
UIEXPORT UiContext* ui_object_get_context(UiObject *obj);
UIEXPORT void* ui_object_get_windowdata(UiObject *obj);
UIEXPORT void ui_object_set_windowdata(UiObject *obj, void *windowdata);
+UIEXPORT void ui_object_set_onclose(UiObject *obj, ui_callback callback, void *userdata);
+
+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);
UIEXPORT void ui_list_set_iter(UiList *list, void *iter);
+UIEXPORT void ui_list_set_save_selection(UiList *list, UiBool value);
+UIEXPORT UiBool ui_list_get_save_selection(UiList *list);
UIEXPORT UiSubList* ui_sublist_new(void);
UIEXPORT void ui_sublist_set_value(UiSubList *sublist, UiList *value);
UIEXPORT int ui_event_get_int(UiEvent *event);
UIEXPORT int ui_event_get_set(UiEvent *event);
-UIEXPORT UiListSelection* ui_list_get_selection_allocated(UiList *list);
+UIEXPORT void* ui_typed_obj_get_ptr(UiTypedObj *obj);
+UIEXPORT uint64_t ui_typed_obj_get_type(UiTypedObj *obj);
+
UIEXPORT int ui_list_selection_get_count(UiListSelection *sel);
UIEXPORT int* ui_list_selection_get_rows(UiListSelection *sel);
UIEXPORT void ui_list_set_selected_indices(UiList *list, int *indices, int num);
-UIEXPORT void ui_list_selection_free(UiListSelection *sel);
+
+UIEXPORT int ui_text_change_event_get_type(UiTextChangeEventData *event);
+UIEXPORT int ui_text_change_event_get_begin(UiTextChangeEventData *event);
+UIEXPORT int ui_text_change_event_get_end(UiTextChangeEventData *event);
+UIEXPORT const char* ui_text_change_event_get_text(UiTextChangeEventData *event);
+UIEXPORT int ui_text_change_event_get_length(UiTextChangeEventData *event);
UIEXPORT int ui_filelist_count(UiFileList *flist);
UIEXPORT char* ui_filelist_get(UiFileList *flist, int index);
# POSSIBILITY OF SUCH DAMAGE.
#
-$(GTK_OBJPRE)%.o: gtk/%.c
- $(CC) -o $@ -c -I../ucx $(CFLAGS) $(SHLIB_CFLAGS) $(TK_CFLAGS) $<
-
$(UI_LIB): $(OBJ)
$(AR) $(ARFLAGS) $(UI_LIB) $(OBJ)
$(UI_SHLIB): $(OBJ)
$(CC) -o $(UI_SHLIB) $(LDFLAGS) $(SHLIB_LDFLAGS) $(TK_LDFLAGS) $(OBJ) -L../build/lib -lucx
+
+FORCE:
+
+$(GTK_OBJPRE)action.o: gtk/action.c gtk/action.h gtk/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)button.o: gtk/button.c gtk/button.h gtk/../ui/toolkit.h \
+ gtk/../ui/button.h gtk/../ui/toolkit.h gtk/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/container.h \
+ gtk/../ui/container.h gtk/widget.h gtk/../ui/widget.h \
+ gtk/../common/action.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)container.o: gtk/container.c gtk/container.h \
+ gtk/../ui/toolkit.h gtk/../ui/container.h gtk/../ui/toolkit.h \
+ gtk/toolkit.h gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/headerbar.h \
+ gtk/../ui/toolbar.h gtk/../common/toolbar.h \
+ gtk/../common/../ui/toolbar.h gtk/../common/menu.h \
+ gtk/../common/../ui/menu.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/container.h gtk/../common/../ui/container.h \
+ gtk/../ui/properties.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)display.o: gtk/display.c gtk/display.h gtk/../ui/toolkit.h \
+ gtk/toolkit.h gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/container.h \
+ gtk/../ui/container.h gtk/../ui/toolkit.h gtk/../ui/display.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)dnd.o: gtk/dnd.c gtk/dnd.h gtk/../ui/dnd.h \
+ gtk/../ui/toolkit.h gtk/toolkit.h gtk/../ui/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)draw_cairo.o: gtk/draw_cairo.c gtk/container.h \
+ gtk/../ui/toolkit.h gtk/../ui/container.h gtk/../ui/toolkit.h \
+ gtk/toolkit.h gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/draw_cairo.h \
+ gtk/graphics.h gtk/../ui/graphics.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)draw_gdk.o: gtk/draw_gdk.c gtk/container.h \
+ gtk/../ui/toolkit.h gtk/../ui/container.h gtk/../ui/toolkit.h \
+ gtk/toolkit.h gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/draw_gdk.h \
+ gtk/graphics.h gtk/../ui/graphics.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)entry.o: gtk/entry.c gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/object.h gtk/container.h gtk/../ui/toolkit.h \
+ gtk/../ui/container.h gtk/../ui/toolkit.h gtk/toolkit.h gtk/entry.h \
+ gtk/../ui/entry.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)graphics.o: gtk/graphics.c gtk/graphics.h \
+ gtk/../ui/graphics.h gtk/../ui/toolkit.h gtk/toolkit.h \
+ gtk/../ui/toolkit.h gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/object.h gtk/container.h gtk/../ui/container.h \
+ gtk/draw_cairo.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)headerbar.o: gtk/headerbar.c gtk/headerbar.h gtk/toolkit.h \
+ gtk/../ui/toolkit.h gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/object.h gtk/../ui/toolbar.h gtk/../ui/toolkit.h \
+ gtk/../common/toolbar.h gtk/../common/../ui/toolbar.h \
+ gtk/../common/menu.h gtk/../common/../ui/menu.h \
+ gtk/../common/../ui/toolkit.h gtk/button.h gtk/../ui/button.h gtk/menu.h \
+ gtk/../ui/menu.h gtk/../common/menu.h gtk/../ui/properties.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)icon.o: gtk/icon.c gtk/toolkit.h gtk/../ui/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/icon.h \
+ gtk/../ui/icons.h gtk/../ui/toolkit.h gtk/../common/properties.h \
+ gtk/../common/../ui/properties.h gtk/../common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)image.o: gtk/image.c gtk/image.h gtk/../ui/image.h \
+ gtk/../ui/toolkit.h gtk/toolkit.h gtk/../ui/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/container.h \
+ gtk/../ui/container.h gtk/menu.h gtk/../ui/menu.h gtk/../common/menu.h \
+ gtk/../common/../ui/menu.h gtk/widget.h gtk/../ui/widget.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)list.o: gtk/list.c gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/object.h gtk/../common/action.h gtk/container.h \
+ gtk/../ui/toolkit.h gtk/../ui/container.h gtk/../ui/toolkit.h \
+ gtk/toolkit.h gtk/list.h gtk/../ui/list.h gtk/button.h \
+ gtk/../ui/button.h gtk/icon.h gtk/../ui/icons.h gtk/menu.h \
+ gtk/../ui/menu.h gtk/../common/menu.h gtk/../common/../ui/menu.h \
+ gtk/dnd.h gtk/../ui/dnd.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)menu.o: gtk/menu.c gtk/menu.h gtk/../ui/menu.h \
+ gtk/../ui/toolkit.h gtk/../common/menu.h gtk/../common/../ui/menu.h \
+ gtk/toolkit.h gtk/../ui/toolkit.h gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/object.h gtk/widget.h gtk/../ui/widget.h \
+ gtk/../common/types.h gtk/../common/action.h gtk/../ui/properties.h \
+ gtk/../ui/window.h gtk/container.h gtk/../ui/container.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)range.o: gtk/range.c gtk/range.h gtk/toolkit.h \
+ gtk/../ui/toolkit.h gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/object.h gtk/../ui/range.h gtk/../ui/toolkit.h \
+ gtk/container.h gtk/../ui/container.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)text.o: gtk/text.c gtk/text.h gtk/../ui/text.h \
+ gtk/../ui/toolkit.h gtk/toolkit.h gtk/../ui/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/container.h \
+ gtk/../ui/container.h gtk/widget.h gtk/../ui/widget.h \
+ gtk/../common/types.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)toolbar.o: gtk/toolbar.c gtk/toolbar.h gtk/../ui/toolbar.h \
+ gtk/../ui/toolkit.h gtk/../common/toolbar.h \
+ gtk/../common/../ui/toolbar.h gtk/../common/menu.h \
+ gtk/../common/../ui/menu.h gtk/../common/../ui/toolkit.h gtk/list.h \
+ gtk/../ui/list.h gtk/toolkit.h gtk/../ui/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/menu.h \
+ gtk/../ui/menu.h gtk/../common/menu.h gtk/button.h gtk/../ui/button.h \
+ gtk/icon.h gtk/../ui/icons.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)toolkit.o: gtk/toolkit.c gtk/toolkit.h gtk/../ui/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/toolbar.h \
+ gtk/../ui/toolbar.h gtk/../ui/toolkit.h gtk/../common/toolbar.h \
+ gtk/../common/../ui/toolbar.h gtk/../common/menu.h \
+ gtk/../common/../ui/menu.h gtk/../common/../ui/toolkit.h gtk/list.h \
+ gtk/../ui/list.h gtk/window.h gtk/icon.h gtk/../ui/icons.h \
+ gtk/../common/document.h gtk/../common/context.h \
+ gtk/../common/properties.h gtk/../common/../ui/properties.h \
+ gtk/../common/menu.h gtk/../common/threadpool.h gtk/../common/app.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)webview.o: gtk/webview.c gtk/toolkit.h gtk/../ui/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/container.h \
+ gtk/../ui/container.h gtk/../ui/toolkit.h gtk/webview.h \
+ gtk/../ui/webview.h gtk/widget.h gtk/../ui/widget.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)widget.o: gtk/widget.c gtk/widget.h gtk/../ui/widget.h \
+ gtk/../ui/toolkit.h gtk/container.h gtk/../ui/toolkit.h \
+ gtk/../ui/container.h gtk/toolkit.h gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/object.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)window.o: gtk/window.c gtk/../ui/window.h \
+ gtk/../ui/toolkit.h gtk/../ui/properties.h gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/menu.h gtk/../common/../ui/menu.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/toolbar.h \
+ gtk/../common/../ui/toolbar.h gtk/../common/menu.h gtk/../common/utils.h \
+ gtk/../common/../ui/text.h gtk/menu.h gtk/../ui/menu.h gtk/toolkit.h \
+ gtk/../ui/toolkit.h gtk/../common/object.h gtk/toolbar.h \
+ gtk/../ui/toolbar.h gtk/list.h gtk/../ui/list.h gtk/container.h \
+ gtk/../ui/container.h gtk/headerbar.h gtk/button.h gtk/../ui/button.h \
+ gtk/window.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
--- /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 "action.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+
+/* ------------------------------ public API ------------------------------ */
+
+void ui_add_action(UiContext *ctx, const char *name, ui_callback callback, void *userdata) {
+ uic_add_action(ctx, name, callback, userdata, NULL, NULL);
+}
+
+void ui_add_action_with_accelerator(
+ UiContext *ctx,
+ const char *name,
+ ui_callback callback,
+ void *userdata,
+ const char *accelerator,
+ const char *accelerator_text)
+{
+ uic_add_action(ctx, name, callback, userdata, accelerator, accelerator_text);
+
+ // TODO: accelerator
+}
--- /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 ACTION_H
+#define ACTION_H
+
+#include "../ui/toolkit.h"
+#include "../common/action.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ACTION_H */
+
#include "button.h"
#include "container.h"
+#include "widget.h"
#include <cx/allocator.h>
#include <cx/buffer.h>
#include <cx/json.h>
#include "../common/context.h"
#include "../common/object.h"
+#include "../common/action.h"
void ui_button_set_icon_name(GtkWidget *button, const char *icon) {
if(!icon) {
const char *tooltip,
ui_callback onclick,
void *userdata,
+ const char *action,
int event_value,
bool activate_event)
{
gtk_widget_set_tooltip_text(button, tooltip);
}
- if(onclick) {
+ if(onclick || action) {
UiEventData *event = malloc(sizeof(UiEventData));
event->obj = obj;
event->userdata = userdata;
event->callback = onclick;
event->value = event_value;
+ event->action = action ? strdup(action) : NULL;
event->customdata = NULL;
event->customint = 0;
g_signal_connect(
button,
"destroy",
- G_CALLBACK(ui_destroy_userdata),
+ G_CALLBACK(ui_destroy_eventdata),
event);
if(activate_event) {
g_signal_connect(
G_CALLBACK(ui_button_clicked),
event);
}
+
+ if(action) {
+ uic_bind_action(obj->ctx, action, button, (ui_enablefunc)ui_set_enabled);
+ UiAction *ui_action = uic_resolve_action(obj->ctx, action);
+ if(!ui_action) {
+ ui_set_enabled(button, FALSE);
+ }
+ }
}
return button;
}
UIWIDGET ui_button_create(UiObject *obj, UiButtonArgs *args) {
- GtkWidget *button = ui_create_button(obj, args->label, args->icon, args->tooltip, args->onclick, args->onclickdata, 0, FALSE);
+ GtkWidget *button = ui_create_button(obj, args->label, args->icon, args->tooltip, args->onclick, args->onclickdata, args->action, 0, FALSE);
ui_set_name_and_style(button, args->name, args->style_class);
ui_set_widget_states(obj->ctx, button, args->states);
UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
UiLayout layout = UI_ARGS2LAYOUT(args);
ct->add(ct, button, &layout);
+ uic_widget_set_visibility_states(obj->ctx, button, args->visibility_states);
return button;
}
e.eventdatatype = 0;
e.intval = event->value;
e.set = ui_get_setop();
- event->callback(&e, event->userdata);
+ if(event->callback) {
+ event->callback(&e, event->userdata);
+ }
+
+ if(event->action) {
+ uic_action_callback(&e, event->action);
+ }
}
void ui_button_set_label(UIWIDGET button, const char *label) {
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);
e.eventdatatype = 0;
e.intval = gtk_toggle_button_get_active(widget);
e.set = ui_get_setop();
- event->callback(&e, event->userdata);
+
+ if(event->callback) {
+ event->callback(&e, event->userdata);
+ }
+
+ if(event->action) {
+ uic_action_callback(&e, event->action);
+ }
}
static void ui_togglebutton_enable_state_callback(GtkToggleButton *widget, UiEventData *event) {
UiInteger *value,
ui_callback onchange,
void *onchangedata,
+ const char *action,
int enable_state)
{
if(label) {
gtk_widget_set_tooltip_text(togglebutton, tooltip);
}
+ if(action) {
+ uic_bind_action(obj->ctx, action, togglebutton, (ui_enablefunc)ui_set_enabled);
+ UiAction *ui_action = uic_resolve_action(obj->ctx, action);
+ if(!ui_action) {
+ ui_set_enabled(togglebutton, FALSE);
+ }
+ }
+
ui_bind_togglebutton(
obj,
togglebutton,
(ui_toggled_func)ui_toggled_callback,
onchange,
onchangedata,
+ action,
(ui_toggled_func)ui_togglebutton_enable_state_callback,
enable_state
);
void (*toggled_callback)(void*, void*),
ui_callback onchange,
void *onchangedata,
+ const char *action,
void (*enable_state_func)(void*, void*),
int enable_state)
{
event);
}
- if(onchange) {
+ if(onchange || action) {
UiEventData *event = malloc(sizeof(UiEventData));
event->obj = obj;
event->userdata = onchangedata;
event->callback = onchange;
+ event->action = action ? strdup(action) : NULL,
event->value = 0;
event->customdata = NULL;
event->customint = 0;
g_signal_connect(
widget,
"destroy",
- G_CALLBACK(ui_destroy_userdata),
+ G_CALLBACK(ui_destroy_eventdata),
event);
}
-
+
if(enable_state > 0) {
UiEventData *event = malloc(sizeof(UiEventData));
event->obj = obj;
args->value,
args->onchange,
args->onchangedata,
+ args->action,
args->enable_state);
ui_set_name_and_style(widget, args->name, args->style_class);
ui_set_widget_states(obj->ctx, widget, args->states);
UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
UiLayout layout = UI_ARGS2LAYOUT(args);
ct->add(ct, widget, &layout);
+ uic_widget_set_visibility_states(obj->ctx, widget, args->visibility_states);
return widget;
}
(ui_toggled_func)ui_checkbox_callback,
args->onchange,
args->onchangedata,
+ args->action,
(ui_toggled_func)ui_checkbox_enable_state,
args->enable_state);
UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
UiLayout layout = UI_ARGS2LAYOUT(args);
ct->add(ct, widget, &layout);
+ uic_widget_set_visibility_states(obj->ctx, widget, args->visibility_states);
return widget;
}
UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
UiLayout layout = UI_ARGS2LAYOUT(args);
ct->add(ct, widget, &layout);
+ uic_widget_set_visibility_states(obj->ctx, widget, args->visibility_states);
return widget;
}
#endif
+static void content_toggle_button_changed(UiContentToggleButton *button) {
+ if(button->toggled) {
+ gtk_button_set_label(GTK_BUTTON(button->widget), button->label1);
+ ui_button_set_icon_name(button->widget, button->icon1);
+ gtk_widget_set_tooltip_text(button->widget, button->tooltip1);
+ } else {
+ gtk_button_set_label(GTK_BUTTON(button->widget), button->label0);
+ ui_button_set_icon_name(button->widget, button->icon0);
+ gtk_widget_set_tooltip_text(button->widget, button->tooltip0);
+ }
+
+ UiEvent e;
+ e.obj = button->obj;
+ e.window = button->obj->window;
+ e.document = button->obj->ctx->document;
+ e.eventdata = NULL;
+ e.eventdatatype = 0;
+ e.intval = button->toggled;
+ e.set = ui_get_setop();
+
+ if(button->onchange) {
+ button->onchange(&e, button->onchangedata);
+ }
+
+ if(button->onchange_action) {
+ uic_action_callback(&e, button->onchange_action);
+ }
+}
+
+static void ui_content_toggle_button_toggled(GtkWidget *widget, UiContentToggleButton *button) {
+ button->toggled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+ if(ui_get_setop() == 0) {
+ content_toggle_button_changed(button);
+ }
+}
+
+static void ui_content_toggle_button_clicked(GtkWidget *widget, UiContentToggleButton *button) {
+ button->toggled = !button->toggled;
+ content_toggle_button_changed(button);
+}
+
+static void ui_destroy_content_togglebutton(GtkWidget *widget, UiContentToggleButton *button) {
+ free(button->label0);
+ free(button->icon0);
+ free(button->tooltip0);
+ free(button->label1);
+ free(button->icon1);
+ free(button->tooltip1);
+ free(button->onchange_action);
+ free(button);
+}
+
+static void ui_content_togglebutton_enabled_by_state(void *data, int enabled) {
+ UiContentToggleButton *button = data;
+ if(button->toggled != enabled) {
+ button->toggled = enabled;
+ content_toggle_button_changed(button);
+ }
+}
+
+UIWIDGET ui_create_content_togglebutton(UiObject *obj, UiContentToggleArgs *args) {
+ UiContentToggleButton *button = malloc(sizeof(UiContentToggleButton));
+ memset(button, 0, sizeof(UiContentToggleButton));
+ button->obj = obj;
+ button->label0 = args->label0 ? strdup(args->label0) : NULL;
+ button->icon0 = args->icon0 ? strdup(args->icon0) : NULL;
+ button->tooltip0 = args->tooltip0 ? strdup(args->tooltip0) : NULL;
+ button->label1 = args->label1 ? strdup(args->label1) : NULL;
+ button->icon1 = args->icon1 ? strdup(args->icon1) : NULL;
+ button->tooltip1 = args->tooltip1 ? strdup(args->tooltip1) : NULL;
+ button->enable_state = args->enable_state;
+ button->var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_INTEGER);
+ button->onchange = args->onchange;
+ button->onchangedata = args->onchangedata;
+ button->onchange_action = args->action ? strdup(args->action) : NULL;
+
+ const char *label = args->label0;
+ const char *icon = args->icon0;
+ const char *tooltip = args->tooltip0;
+ if(button->var) {
+ UiInteger *i = button->var->value;
+ i->obj = button;
+ i->get = ui_ctntogglebutton_get;
+ i->set = ui_ctntogglebutton_set;
+
+ if(i->value) {
+ label = args->label1;
+ icon = args->label1;
+ tooltip = args->tooltip1;
+ button->toggled = 1;
+ }
+ }
+
+ GtkWidget *widget;
+ if(args->istogglebutton) {
+ widget = gtk_toggle_button_new_with_label(label);
+
+ g_signal_connect(
+ widget,
+ "toggled",
+ G_CALLBACK(ui_content_toggle_button_toggled),
+ button);
+ } else {
+ widget = gtk_button_new_with_label(label);
+
+ g_signal_connect(
+ widget,
+ "clicked",
+ G_CALLBACK(ui_content_toggle_button_clicked),
+ button);
+ }
+ ui_button_set_icon_name(widget, icon);
+ gtk_widget_set_tooltip_text(widget, tooltip);
+ button->widget = widget;
+
+ if(args->action) {
+ uic_bind_action(obj->ctx, args->action, widget, (ui_enablefunc)ui_set_enabled);
+ UiAction *ui_action = uic_resolve_action(obj->ctx, args->action);
+ if(!ui_action) {
+ ui_set_enabled(widget, FALSE);
+ }
+ }
+
+ if(args->toggled_by_state != 0) {
+ CxList *ls = cxArrayListCreate(NULL, sizeof(int), 1);
+ cxListAdd(ls, &args->toggled_by_state);
+ uic_add_state_widget(obj->ctx, button, ui_content_togglebutton_enabled_by_state, ls);
+ cxListFree(ls);
+ }
+
+ g_signal_connect(
+ widget,
+ "destroy",
+ G_CALLBACK(ui_destroy_content_togglebutton),
+ button);
+
+ g_object_set_data(G_OBJECT(widget), "ui_content_togglebutton", button);
+ return widget;
+}
+
+UIWIDGET ui_content_togglebutton_create(UiObject *obj, UiContentToggleArgs *args) {
+ GtkWidget *widget = ui_create_content_togglebutton(obj, args);
+
+ ui_set_name_and_style(widget, args->name, args->style_class);
+ ui_set_widget_states(obj->ctx, widget, args->states);
+ UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
+ UiLayout layout = UI_ARGS2LAYOUT(args);
+ ct->add(ct, widget, &layout);
+ uic_widget_set_visibility_states(obj->ctx, widget, args->visibility_states);
+ return widget;
+}
+
+int64_t ui_ctntogglebutton_get(UiInteger *value) {
+ UiContentToggleButton *button = value->obj;
+ value->value = button->toggled;
+ return value->value;
+}
+
+void ui_ctntogglebutton_set(UiInteger *value, int64_t i) {
+ UiContentToggleButton *button = value->obj;
+ button->toggled = i != 0;
+ value->value = button->toggled;
+ content_toggle_button_changed(button);
+}
+
#if GTK_MAJOR_VERSION >= 4
#define RADIOBUTTON_NEW(group, label) gtk_check_button_new_with_label(label)
#define RADIOBUTTON_SET_GROUP(button, group)
UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
UiLayout layout = UI_ARGS2LAYOUT(args);
ct->add(ct, rbutton, &layout);
+ uic_widget_set_visibility_states(obj->ctx, rbutton, args->visibility_states);
return rbutton;
}
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);
}
}
UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
UiLayout layout = UI_ARGS2LAYOUT(args);
ct->add(ct, button, &layout);
+ uic_widget_set_visibility_states(obj->ctx, button, args->visibility_states);
return button;
}
if(s->value.free) {
s->value.free(s->value.ptr);
}
+ s->value.ptr = NULL;
#if GTK_MAJOR_VERSION == 3
UiLinkButton *data = s->obj;
GtkWidget *child = gtk_bin_get_child(GTK_BIN(data->widget));
extern "C" {
#endif
+typedef struct UiContentToggleButton {
+ UiObject *obj;
+ UiVar *var;
+ GtkWidget *widget;
+ char *label0;
+ char *icon0;
+ char *tooltip0;
+ char *label1;
+ char *icon1;
+ char *tooltip1;
+ ui_callback onchange;
+ void *onchangedata;
+ char *onchange_action;
+ int toggled;
+ int enable_state;
+} UiContentToggleButton;
+
typedef struct UiLinkButton {
UiObject *obj;
GtkWidget *widget;
const char *tooltip,
ui_callback onclick,
void *userdata,
+ const char *action,
int event_value,
bool activate_event);
UiInteger *value,
ui_callback onchange,
void *onchangedata,
+ const char *action,
int enable_state);
void ui_bind_togglebutton(
void (*toggled_callback)(void*, void*),
ui_callback onchange,
void *onchangedata,
+ const char *action,
void (*enable_state_func)(void*, void*),
int enable_state);
void ui_radio_obs(GtkToggleButton *widget, UiVarEventData *event);
+UIWIDGET ui_create_content_togglebutton(UiObject *obj, UiContentToggleArgs *args);
+
int64_t ui_switch_get(UiInteger *value);
void ui_switch_set(UiInteger *value, int64_t i);
+int64_t ui_ctntogglebutton_get(UiInteger *value);
+void ui_ctntogglebutton_set(UiInteger *value, int64_t i);
+
int64_t ui_radiobutton_get(UiInteger *value);
void ui_radiobutton_set(UiInteger *value, int64_t i);
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);
+
return box;
}
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);
+
return grid;
}
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);
}
+ uic_widget_set_visibility_states(obj->ctx, frame, args->visibility_states);
+
return frame;
}
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);
}
+ uic_widget_set_visibility_states(obj->ctx, expander, args->visibility_states);
+
return expander;
}
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);
}
+ uic_widget_set_visibility_states(obj->ctx, sw, args->visibility_states);
+
return sw;
}
UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs *args) {
UiGtkTabView *data = malloc(sizeof(UiGtkTabView));
memset(data, 0, sizeof(UiGtkTabView));
+ data->obj = obj;
data->padding = args->padding;
data->spacing = args->spacing;
data->columnspacing = args->columnspacing;
data->rowspacing = args->rowspacing;
+ data->onchange = args->onchange;
+ data->onchangedata = args->onchangedata;
ui_tabview_get_func getfunc = NULL;
ui_tabview_set_func setfunc = NULL;
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);
+
return widget;
}
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
UiLayout layout = UI_ARGS2LAYOUT(args);
ct->add(ct, widget, &layout);
+ uic_widget_set_visibility_states(obj->ctx, widget, args->visibility_states);
+
return widget;
}
UiLayout layout = UI_ARGS2LAYOUT(args);
ct->add(ct, progressbar, &layout);
+ uic_widget_set_visibility_states(obj->ctx, progressbar, args->visibility_states);
+
return progressbar;
}
UiLayout layout = UI_ARGS2LAYOUT(args);
ct->add(ct, spinner, &layout);
+ uic_widget_set_visibility_states(obj->ctx, spinner, args->visibility_states);
+
return spinner;
}
#include "button.h"
#include "menu.h"
+#include "../ui/widget.h"
+
+#include <cx/array_list.h>
#include "../ui/properties.h"
}
// main toolbar
- ui_headerbar_add_items(obj, main_headerbar, left_defaults, UI_TOOLBAR_LEFT);
- ui_headerbar_add_items(obj, main_headerbar, center_defaults, UI_TOOLBAR_CENTER);
+ ui_headerbar_add_items(obj, main_headerbar, left_defaults, UI_TOOLBAR_LEFT, NULL);
+ ui_headerbar_add_items(obj, main_headerbar, center_defaults, UI_TOOLBAR_CENTER, NULL);
if(appmenu && appmenu_pos == UI_TOOLBAR_RIGHT) {
ui_add_headerbar_menu(main_headerbar, NULL, appmenu, obj, UI_TOOLBAR_RIGHT);
}
- ui_headerbar_add_items(obj, main_headerbar, right_defaults, UI_TOOLBAR_RIGHT);
+ ui_headerbar_add_items(obj, main_headerbar, right_defaults, UI_TOOLBAR_RIGHT, NULL);
// sidebar
if(sidebar_headerbar) {
// ui_headerbar_add_items pos parameter uses only UI_TOOLBAR_LEFT, UI_TOOLBAR_CENTER, UI_TOOLBAR_RIGHT
- ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_left_defaults, UI_TOOLBAR_LEFT);
+ ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_left_defaults, UI_TOOLBAR_LEFT, NULL);
if(appmenu && appmenu_pos == UI_TOOLBAR_SIDEBAR_RIGHT) {
ui_add_headerbar_menu(sidebar_headerbar, NULL, appmenu, obj, UI_TOOLBAR_RIGHT);
}
- ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_right_defaults, UI_TOOLBAR_RIGHT);
+ ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_right_defaults, UI_TOOLBAR_RIGHT, NULL);
}
// right panel
if(right_headerbar) {
- ui_headerbar_add_items(obj, right_headerbar, rightpanel_left_defaults, UI_TOOLBAR_LEFT);
- ui_headerbar_add_items(obj, right_headerbar, rightpanel_center_defaults, UI_TOOLBAR_CENTER);
+ // also add central toolbar items, in case the central pane is hidden
+ CxList *backup_toolbar_widgets = cxArrayListCreate(obj->ctx->allocator, CX_STORE_POINTERS, 16);
+ ui_headerbar_add_items(obj, right_headerbar, left_defaults, UI_TOOLBAR_LEFT, backup_toolbar_widgets);
+ ui_headerbar_add_items(obj, right_headerbar, center_defaults, UI_TOOLBAR_LEFT, backup_toolbar_widgets);
+ ui_headerbar_add_items(obj, right_headerbar, right_defaults, UI_TOOLBAR_LEFT, backup_toolbar_widgets);
+ CxIterator i = cxListIterator(backup_toolbar_widgets);
+ cx_foreach(GtkWidget *, w, i) {
+ ui_set_visible(w, FALSE);
+ }
+ g_object_set_data(G_OBJECT(obj->widget), "ui_toolbar_center_backup", backup_toolbar_widgets);
+
+ // main items for the right panel
+ ui_headerbar_add_items(obj, right_headerbar, rightpanel_left_defaults, UI_TOOLBAR_LEFT, NULL);
+ ui_headerbar_add_items(obj, right_headerbar, rightpanel_center_defaults, UI_TOOLBAR_CENTER, NULL);
if(appmenu && appmenu_pos == UI_TOOLBAR_RIGHTPANEL_RIGHT) {
ui_add_headerbar_menu(right_headerbar, NULL, appmenu, obj, UI_TOOLBAR_RIGHT);
}
- ui_headerbar_add_items(obj, right_headerbar, rightpanel_right_defaults, UI_TOOLBAR_RIGHT);
+ ui_headerbar_add_items(obj, right_headerbar, rightpanel_right_defaults, UI_TOOLBAR_RIGHT, NULL);
}
}
-static void create_item(UiObject *obj, GtkWidget *headerbar, GtkWidget *box, UiToolbarItemI *i, enum UiToolbarPos pos) {
+static GtkWidget* create_item(UiObject *obj, GtkWidget *headerbar, GtkWidget *box, UiToolbarItemI *i, enum UiToolbarPos pos) {
switch(i->type) {
case UI_TOOLBAR_ITEM: {
- ui_add_headerbar_item(headerbar, box, (UiToolbarItem*)i, obj, pos);
- break;
+ return ui_add_headerbar_item(headerbar, box, (UiToolbarItem*)i, obj, pos);
}
case UI_TOOLBAR_TOGGLEITEM: {
- ui_add_headerbar_toggleitem(headerbar, box, (UiToolbarToggleItem*)i, obj, pos);
- break;
+ return ui_add_headerbar_toggleitem(headerbar, box, (UiToolbarToggleItem*)i, obj, pos);
+ }
+ case UI_TOOLBAR_CONTENT_TOGGLEITEM: {
+ return ui_add_headerbar_content_toggleitem(headerbar, box, (UiToolbarContentToggleItem*)i, obj, pos);
}
case UI_TOOLBAR_MENU: {
- ui_add_headerbar_menu(headerbar, box, (UiToolbarMenuItem*)i, obj, pos);
- break;
+ return ui_add_headerbar_menu(headerbar, box, (UiToolbarMenuItem*)i, obj, pos);
}
default: fprintf(stderr, "toolbar item type unimplemented: %d\n", (int)i->type);
}
+ return NULL;
}
static void headerbar_add(GtkWidget *headerbar, GtkWidget *box, GtkWidget *item, enum UiToolbarPos pos) {
}
}
-void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos) {
+void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos, CxList *out_items) {
GtkWidget *box = NULL;
if(pos == UI_TOOLBAR_CENTER && cxListSize(items) > 0) {
box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
UI_HEADERBAR_SET_TITLE_WIDGET(headerbar, box);
+ if(out_items) {
+ cxListAdd(out_items, box);
+ }
}
CxIterator i = pos == UI_TOOLBAR_RIGHT ? cxListBackwardsIterator(items) : cxListIterator(items);
fprintf(stderr, "unknown toolbar item: %s\n", def);
continue;
}
- create_item(obj, headerbar, box, item, pos);
+ GtkWidget *item_widget = create_item(obj, headerbar, box, item, pos);
+ if(out_items && !box) {
+ cxListAdd(out_items, item_widget);
+ }
}
}
-void ui_add_headerbar_item(
+GtkWidget* ui_add_headerbar_item(
GtkWidget *headerbar,
GtkWidget *box,
UiToolbarItem *item,
UiObject *obj,
enum UiToolbarPos pos)
{
- GtkWidget *button = ui_create_button(obj, item->args.label, item->args.icon, item->args.tooltip, item->args.onclick, item->args.onclickdata, 0, FALSE);
+ GtkWidget *button = ui_create_button(obj, item->args.label, item->args.icon, item->args.tooltip, item->args.onclick, item->args.onclickdata, item->args.action, 0, FALSE);
ui_set_widget_states(obj->ctx, button, item->args.states);
ui_set_widget_visibility_states(obj->ctx, button, item->args.visibility_states);
WIDGET_ADD_CSS_CLASS(button, "flat");
headerbar_add(headerbar, box, button, pos);
+ return button;
}
-void ui_add_headerbar_toggleitem(
+GtkWidget* ui_add_headerbar_toggleitem(
GtkWidget *headerbar,
GtkWidget *box,
UiToolbarToggleItem *item,
ui_set_widget_states(obj->ctx, button, item->args.states);
ui_set_widget_visibility_states(obj->ctx, button, item->args.visibility_states);
WIDGET_ADD_CSS_CLASS(button, "flat");
- ui_setup_togglebutton(obj, button, item->args.label, item->args.icon, item->args.tooltip, item->args.varname, NULL, item->args.onchange, item->args.onchangedata, 0);
+ ui_setup_togglebutton(obj, button, item->args.label, item->args.icon, item->args.tooltip, item->args.varname, NULL, item->args.onchange, item->args.onchangedata, item->args.action, 0);
headerbar_add(headerbar, box, button, pos);
+ return button;
}
-void ui_add_headerbar_menu(
+GtkWidget* ui_add_headerbar_content_toggleitem(
+ GtkWidget *headerbar,
+ GtkWidget *box,
+ UiToolbarContentToggleItem *item,
+ UiObject *obj,
+ enum UiToolbarPos pos)
+{
+ UiContentToggleArgs args = { 0 };
+ args.label0 = item->args.label0;
+ args.icon0 = item->args.icon0;
+ args.tooltip0 = item->args.tooltip0;
+ args.label1 = item->args.label1;
+ args.icon1 = item->args.icon1;
+ args.tooltip1 = item->args.tooltip1;
+ args.varname = item->args.varname;
+ args.onchange = item->args.onchange;
+ args.onchangedata = item->args.onchangedata;
+ args.action = item->args.action;
+ args.istogglebutton = item->args.istogglebutton;
+ args.toggled_by_state = item->args.toggled_by_state;
+
+ GtkWidget *button = ui_create_content_togglebutton(obj, &args);
+ WIDGET_ADD_CSS_CLASS(button, "flat");
+ headerbar_add(headerbar, box, button, pos);
+ return button;
+}
+
+GtkWidget* ui_add_headerbar_menu(
GtkWidget *headerbar,
GtkWidget *box,
UiToolbarMenuItem *item,
#endif
headerbar_add(headerbar, box, menubutton, pos);
+
+ return menubutton;
}
#endif // GTK_CHECK_VERSION(3, 10, 0)
void ui_fill_headerbar(UiObject *obj, GtkWidget *sidebar_headerbar, GtkWidget *main_headerbar, GtkWidget *right_headerbar);
-void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos);
+void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos, CxList *out_items);
-void ui_add_headerbar_item(
+GtkWidget* ui_add_headerbar_item(
GtkWidget *headerbar,
GtkWidget *box,
UiToolbarItem *item,
UiObject *obj,
enum UiToolbarPos pos);
-void ui_add_headerbar_toggleitem(
+GtkWidget* ui_add_headerbar_toggleitem(
GtkWidget *headerbar,
GtkWidget *box,
UiToolbarToggleItem *item,
UiObject *obj,
enum UiToolbarPos pos);
-void ui_add_headerbar_menu(
+GtkWidget* ui_add_headerbar_content_toggleitem(
+ GtkWidget *headerbar,
+ GtkWidget *box,
+ UiToolbarContentToggleItem *item,
+ UiObject *obj,
+ enum UiToolbarPos pos);
+
+GtkWidget* ui_add_headerbar_menu(
GtkWidget *headerbar,
GtkWidget *box,
UiToolbarMenuItem *item,
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;
}
#include "../common/context.h"
#include "../common/object.h"
+#include "../common/action.h"
#include "container.h"
#include <cx/array_list.h>
tableview->multiselection = args->multiselection;
tableview->onactivate = args->onactivate;
tableview->onactivatedata = args->onactivatedata;
+ tableview->onactivate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL;
tableview->onselection = args->onselection;
tableview->onselectiondata = args->onselectiondata;
+ tableview->onselection_action = args->onselection_action ? strdup(args->onselection_action) : NULL;
tableview->ondragstart = args->ondragstart;
tableview->ondragstartdata = args->ondragstartdata;
+ tableview->ondragstart_action = args->ondragstart_action ? strdup(args->ondragstart_action) : NULL;
tableview->ondragcomplete = args->ondragcomplete;
tableview->ondragcompletedata = args->ondragcompletedata;
+ tableview->ondragcomplete_action = args->ondragcomplete_action ? strdup(args->ondragcomplete_action) : NULL;
tableview->ondrop = args->ondrop;
tableview->ondropdata = args->ondropdata;
+ tableview->ondrop_action = args->ondrop_action ? strdup(args->ondrop_action) : NULL;
tableview->selection.count = 0;
tableview->selection.rows = NULL;
tableview->current_row = -1;
} 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);
}
}
// event handling
- if(args->onactivate) {
+ if(args->onactivate || args->onactivate_action) {
// columnview and listview can use the same callback function, because
// the first parameter (which is technically a different pointer type)
// is ignored
GtkSelectionModel *selection_model = create_selection_model(tableview, ls, args->multiselection);
GtkWidget *view = gtk_column_view_new(GTK_SELECTION_MODEL(selection_model));
+ if(args->hide_header) {
+ gtk_widget_set_visible(gtk_widget_get_first_child(view), FALSE);
+ }
UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST);
}
// event handling
- if(args->onactivate) {
+ if(args->onactivate || args->onactivate_action) {
g_signal_connect(view, "activate", G_CALLBACK(ui_columnview_activate), tableview);
}
if(args->contextmenu) {
return sel;
}
-static void listview_event(ui_callback cb, void *cbdata, UiListView *view) {
+static void listview_event(ui_callback cb, void *cbdata, const char *action, UiListView *view) {
UiEvent event;
event.obj = view->obj;
event.document = event.obj->ctx->document;
if(cb) {
cb(&event, cbdata);
}
+
+ if(action) {
+ uic_action_callback(&event, action);
+ }
}
static void listview_update_selection(UiListView *view) {
if(view->selection.count == 0) {
listview_update_selection(view);
}
- listview_event(view->onactivate, view->onactivatedata, view);
+ listview_event(view->onactivate, view->onactivatedata, view->onactivate_action, view);
}
void ui_listview_selection_changed(GtkSelectionModel* self, guint position, guint n_items, gpointer userdata) {
UiListView *view = userdata;
listview_update_selection(view);
- listview_event(view->onselection, view->onselectiondata, view);
+ if(ui_selection_events_is_enabled()) {
+ listview_event(view->onselection, view->onselectiondata, view->onselection_action, view);
+ }
}
void ui_dropdown_activate(GtkDropDown* self, gpointer userdata) {
if(i < 0) {
cxMapClear(view->bound_rows);
ui_update_liststore(view->liststore, list);
+ free(view->selection.rows);
+ view->selection.rows = NULL;
+ view->selection.count = 0;
} else {
void *value = list->get(list, i);
if(value) {
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(
UIWIDGET ui_table_create(UiObject *obj, UiListArgs *args) {
// create treeview
GtkWidget *view = gtk_tree_view_new();
+ if(args->hide_header) {
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
+ }
UiModel *model = args->model;
int columns = model ? model->columns : 0;
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(
GtkTreeSelection *treeselection,
UiTreeEventData *event)
{
+ if(!ui_selection_events_is_enabled()) {
+ return;
+ }
+
UiListSelection selection = ui_listview_get_selection(treeselection, event);
UiEvent e;
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(
*/
void ui_listview_destroy(GtkWidget *w, UiListView *v) {
+ free(v->onactivate_action);
+ free(v->onselection_action);
+ free(v->ondragstart_action);
+ free(v->ondragcomplete_action);
+ free(v->ondrop_action);
//gtk_tree_view_set_model(GTK_TREE_VIEW(w), NULL);
if(v->var) {
ui_destroy_boundvar(v->obj->ctx, v->var);
#endif
ui_callback onactivate;
void *onactivatedata;
+ char *onactivate_action;
ui_callback onselection;
void *onselectiondata;
+ char *onselection_action;
ui_callback ondragstart;
void *ondragstartdata;
+ char *ondragstart_action;
ui_callback ondragcomplete;
void *ondragcompletedata;
+ char *ondragcomplete_action;
ui_callback ondrop;
void *ondropdata;
+ char *ondrop_action;
ui_list_savefunc onsave;
void *onsavedata;
UiListSelection selection;
ui_callback selection;
void *activatedata;
void *selectiondata;
+ char *activate_action;
+ char *selection_action;
} UiTreeEventData;
typedef struct UiListBox UiListBox;
#include "../common/context.h"
#include "../common/menu.h"
#include "../common/types.h"
+#include "../common/action.h"
#include "../ui/properties.h"
#include "../ui/window.h"
#include "container.h"
ls->index = index;
ls->oldcount = 0;
ls->getvalue = il->getvalue;
+ ls->getvaluedata = il->getvaluedata;
UiVar* var = uic_create_var(ui_global_context(), il->varname, UI_VAR_LIST);
//UiVar* var = uic_create_var(obj->ctx, il->varname, UI_VAR_LIST);
gtk_widget_show(widget);
}
- ui_getvaluefunc getvalue = list->getvalue;
+ ui_getvaluefunc2 getvalue = list->getvalue;
+ void *getvaluedata = list->getvaluedata;
int i = 1;
+ int row = 0;
while(elm) {
- char *label = (char*) (getvalue ? getvalue(elm, 0) : elm);
+ UiBool freeResult = FALSE;
+ char *label = (char*) (getvalue ? getvalue(ls, elm, row, 0, getvaluedata, &freeResult) : elm);
GtkWidget *widget = gtk_menu_item_new_with_label(label);
gtk_menu_shell_insert(list->menu, widget, list->index + i);
elm = ui_list_next(ls);
i++;
+ row++;
+
+ if(freeResult) {
+ free(label);
+ }
}
list->oldcount = i;
cxListFree(groups);
}
- if(i->callback != NULL) {
+ if(i->action) {
+ uic_bind_action(obj->ctx, i->action, action, (ui_enablefunc)action_enable);
+ UiAction *ui_action = uic_resolve_action(obj->ctx, i->action);
+ if(!ui_action) {
+ action_enable(action, FALSE);
+ }
+ }
+
+ if(i->callback != NULL || i->action) {
UiEventData *event = malloc(sizeof(UiEventData));
event->obj = obj;
event->userdata = i->userdata;
event->value = 0;
event->customdata = NULL;
event->customint = 0;
+ event->action = i->action ? strdup(i->action) : NULL;
g_signal_connect(
action,
g_signal_connect(
obj->widget,
"destroy",
- G_CALLBACK(ui_destroy_userdata),
+ G_CALLBACK(ui_destroy_eventdata),
event);
}
char action_name[32];
snprintf(action_name, 32, "win.%s", item->id);
-
+
g_menu_append(parent, i->label, action_name);
}
CxIterator iter = cxListIterator(group->callbacks);
cx_foreach(UiCallbackData *, cb, iter) {
- event.intval = intval == iter.index;
+ event.intval = intval-1 == iter.index;
if(cb->callback) {
cb->callback(&event, cb->userdata);
}
cxListAdd(group->callbacks, &cb);
- cxmutstr action_name = cx_asprintf("win.%s::%d", i->varname, (int)item_index);
+ cxmutstr action_name = cx_asprintf("win.%s::%d", i->varname, (int)item_index+1);
g_menu_append(parent, i->label, action_name.ptr);
free(action_name.ptr);
}
ls->index = index;
ls->oldcount = 0;
ls->getvalue = il->getvalue;
+ ls->getvaluedata = il->getvalue;
GSimpleAction *action = g_simple_action_new(item->id, g_variant_type_new("i"));
g_action_map_add_action(obj->ctx->action_map, G_ACTION(action));
evt.eventdatatype = uic_get_tmp_eventdata_type();
}
evt.intval = intval;
- event->callback(&evt, event->userdata);
+ if(event->callback) {
+ event->callback(&evt, event->userdata);
+ }
+ if(event->action) {
+ uic_action_callback(&evt, event->action);
+ }
uic_set_tmp_eventdata(NULL, 0);
}
UiList *ls = list->var->value;
// add list items
- ui_getvaluefunc getvalue = list->getvalue;
+ ui_getvaluefunc2 getvalue = list->getvalue;
+ void *getvaluedata = list->getvaluedata;
int i = 0;
void* elm = ui_list_first(ls);
while(elm) {
- char *label = (char*) (getvalue ? getvalue(elm, 0) : elm);
+ UiBool freeResult = FALSE;
+ char *label = (char*) (getvalue ? getvalue(ls, elm, i, 0, getvaluedata, &freeResult) : elm);
GMenuItem *item = g_menu_item_new(label, NULL);
GVariant *v = g_variant_new("i", i);
elm = ui_list_next(ls);
i++;
+
+ if(freeResult) {
+ free(label);
+ }
}
list->oldcount = i;
int index;
int oldcount;
UiVar *var;
- ui_getvaluefunc getvalue;
+ ui_getvaluefunc2 getvalue;
+ void *getvaluedata;
ui_callback callback;
void *userdata;
};
int index;
int oldcount;
UiVar *var;
- ui_getvaluefunc getvalue;
+ ui_getvaluefunc2 getvalue;
+ void *getvaluedata;
ui_callback callback;
void *userdata;
};
GTKOBJ += headerbar.o
GTKOBJ += webview.o
GTKOBJ += widget.o
+GTKOBJ += action.o
TOOLKITOBJS += $(GTKOBJ:%=$(GTK_OBJPRE)%)
TOOLKITSOURCE += $(GTKOBJ:%.o=gtk/%.c)
int sel = gtk_text_buffer_get_selection_bounds (buf, &begin, &end);
if(sel != textview->last_selection_state) {
if(sel) {
- ui_set_state(textview->ctx, UI_GROUP_SELECTION);
+ ui_set_state(textview->ctx, UI_STATE_SELECTION);
} else {
- ui_unset_state(textview->ctx, UI_GROUP_SELECTION);
+ ui_unset_state(textview->ctx, UI_STATE_SELECTION);
}
}
textview->last_selection_state = sel;
"changed",
G_CALLBACK(ui_textbuf_changed),
textarea);
+
+ g_signal_connect(
+ buf,
+ "insert-text",
+ G_CALLBACK(ui_textbuf_change_insert),
+ textarea);
+ g_signal_connect(
+ buf,
+ "delete-range",
+ G_CALLBACK(ui_textbuf_change_delete),
+ textarea);
} else {
fprintf(stderr, "Error: create_textbuffer: textarea == NULL\n");
}
uitext->last_selection_state = 0;
uitext->onchange = args->onchange;
uitext->onchangedata = args->onchangedata;
+ uitext->onchange_action = args->onchange_action ? strdup(args->onchange_action) : NULL;
+ uitext->ontextchanged = args->ontextchanged;
+ uitext->ontextchangeddata = args->ontextchangeddata;
+ uitext->ontextchanged_action = args->ontextchanged_action ? strdup(args->ontextchanged_action) : NULL;
g_object_set_data(G_OBJECT(text_area), "ui_textarea", uitext);
+ g_object_set_data(G_OBJECT(text_area), "ui_textarea_widget", text_area);
g_signal_connect(
text_area,
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS
SCROLLEDWINDOW_SET_CHILD(scroll_area, text_area);
+ g_object_set_data(G_OBJECT(scroll_area), "ui_textarea_widget", text_area);
ui_widget_size_request(scroll_area, args->width, args->height);
UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
UiLayout layout = UI_ARGS2LAYOUT(args);
ct->add(ct, scroll_area, &layout);
+ uic_widget_set_visibility_states(obj->ctx, scroll_area, args->visibility_states);
// bind value
if(var) {
value->value.free(value->value.ptr);
}
}
+
+ if(value->readonly) {
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(text_area), FALSE);
+ }
+
gtk_text_view_set_buffer(GTK_TEXT_VIEW(text_area), buf);
value->obj = text_area;
value->save = ui_textarea_save;
value->set = ui_textarea_set;
value->getsubstr = ui_textarea_getsubstr;
value->insert = ui_textarea_insert;
+ value->replace = ui_textarea_replace;
value->setposition = ui_textarea_setposition;
value->position = ui_textarea_position;
+ value->showposition = ui_textarea_showposition;
+ value->setselection = ui_textarea_setselection;
value->selection = ui_textarea_selection;
value->length = ui_textarea_length;
value->remove = ui_textarea_remove;
+ value->setreadonly = ui_textarea_setreadonly;
value->data1 = buf;
value->data2 = NULL;
value->datatype == UI_TEXT_TYPE_BUFFER;
if(textarea->var) {
ui_destroy_boundvar(textarea->ctx, textarea->var);
}
+ free(textarea->onchange_action);
+ free(textarea->ontextchanged_action);
free(textarea);
}
+void ui_textarea_scroll_to(UIWIDGET textarea, int pos) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_scroll_to: widget is not a textarea\n");
+ return;
+ }
+ GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
+
+ GtkTextIter offset;
+ gtk_text_buffer_get_iter_at_offset(buf, &offset, pos);
+
+ gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(widget), &offset, 0.2, FALSE, 0, 0);
+}
+
+void ui_textarea_focus(UIWIDGET textarea) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_focus: widget is not a textarea\n");
+ return;
+ }
+ gtk_widget_grab_focus(widget);
+}
+
+void ui_textarea_set_selection(UIWIDGET textarea, int begin, int end) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_set_selection: widget is not a textarea\n");
+ return;
+ }
+
+ GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
+ GtkTextIter ib;
+ GtkTextIter ie;
+ gtk_text_buffer_get_iter_at_offset(buf, &ib, begin);
+ gtk_text_buffer_get_iter_at_offset(buf, &ie, end);
+ gtk_text_buffer_select_range(buf, &ib, &ie);
+}
+
+void ui_textarea_select_all(UIWIDGET textarea) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_select_all: widget is not a textarea\n");
+ return;
+ }
+ GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
+ GtkTextIter start;
+ GtkTextIter end;
+ gtk_text_buffer_get_bounds(buf, &start, &end);
+ gtk_text_buffer_select_range(buf, &start, &end);
+}
+
+void ui_textarea_set_editable(UIWIDGET textarea, UiBool editable) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_set_editable: widget is not a textarea\n");
+ return;
+ }
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(widget), editable);
+}
+
+UiBool ui_textarea_is_editable(UIWIDGET textarea) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_is_editable: widget is not a textarea\n");
+ return 0;
+ }
+ return gtk_text_view_get_editable(GTK_TEXT_VIEW(widget));
+}
+
+void ui_textarea_set_position(UIWIDGET textarea, int pos) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_set_position: widget is not a textarea\n");
+ return;
+ }
+ GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
+ GtkTextIter iter;
+ gtk_text_buffer_get_iter_at_offset(buf, &iter, pos);
+ gtk_text_buffer_place_cursor(buf, &iter);
+}
+
+int ui_textarea_get_position(UIWIDGET textarea) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_get_position: widget is not a textarea\n");
+ return 0;
+ }
+ GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
+ GtkTextIter begin;
+ GtkTextIter end;
+ gtk_text_buffer_get_selection_bounds(buf, &begin, &end);
+ return gtk_text_iter_get_offset(&begin);
+}
+
UIWIDGET ui_textarea_gettextwidget(UIWIDGET textarea) {
- return SCROLLEDWINDOW_GET_CHILD(textarea);
+ return g_object_get_data(G_OBJECT(textarea), "ui_textarea_widget");
}
void ui_textarea_save(UiText *text) {
text->datatype = UI_TEXT_TYPE_BUFFER;
}
gtk_text_view_set_buffer(GTK_TEXT_VIEW(textarea), text->data1);
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(textarea), !text->readonly);
}
void ui_textarea_text_destroy(UiText *text) {
return str;
}
-void ui_textarea_insert(UiText *text, int pos, char *str) {
+void ui_textarea_insert(UiText *text, int pos, const char *str) {
GtkTextIter offset;
gtk_text_buffer_get_iter_at_offset(text->data1, &offset, pos);
gtk_text_buffer_insert(text->data1, &offset, str, -1);
text->value.free = NULL;
}
+void ui_textarea_replace(UiText *text, int begin, int end, const char *replacement) {
+ GtkTextBuffer *buffer = text->data1;
+ GtkTextIter begin_offset;
+ GtkTextIter end_offset;
+ gtk_text_buffer_get_iter_at_offset(buffer, &begin_offset, begin);
+ gtk_text_buffer_get_iter_at_offset(buffer, &end_offset, end);
+ gtk_text_buffer_begin_user_action(buffer);
+ gtk_text_buffer_delete(buffer, &begin_offset, &end_offset);
+ if(replacement) {
+ gtk_text_buffer_insert(buffer, &begin_offset, replacement, -1);
+ }
+ gtk_text_buffer_end_user_action(buffer);
+}
+
void ui_textarea_setposition(UiText *text, int pos) {
GtkTextIter iter;
gtk_text_buffer_get_iter_at_offset(text->data1, &iter, pos);
return text->pos;
}
+void ui_textarea_showposition(UiText *text, int pos) {
+ if(text->obj) {
+ ui_textarea_scroll_to(text->obj, pos);
+ }
+}
+
+void ui_textarea_setselection(UiText *text, int begin, int end) {
+ GtkTextBuffer *buf = text->data1;
+ GtkTextIter ib;
+ GtkTextIter ie;
+ gtk_text_buffer_get_iter_at_offset(text->data1, &ib, begin);
+ gtk_text_buffer_get_iter_at_offset(text->data1, &ie, end);
+ gtk_text_buffer_select_range(buf, &ib, &ie);
+}
+
void ui_textarea_selection(UiText *text, int *begin, int *end) {
GtkTextIter b;
GtkTextIter e;
gtk_text_buffer_delete(buf, &ib, &ie);
}
+void ui_textarea_setreadonly(UiText *text, int readonly) {
+ if(text->obj) {
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(text->obj), !readonly);
+ }
+ text->readonly = readonly;
+}
+
void ui_textarea_realize_event(GtkWidget *widget, gpointer data) {
gtk_widget_grab_focus(widget);
}
+static void textbuf_change_event(UiTextArea *textarea, UiTextChangeEventData *data) {
+ if(!ui_onchange_events_is_enabled()) {
+ return;
+ }
+
+ UiEvent e;
+ e.obj = textarea->obj;
+ e.window = e.obj->window;
+ e.document = textarea->ctx->document;
+ e.eventdata = data;
+ e.eventdatatype = UI_EVENT_DATA_TEXT_CHANGED;
+ e.intval = 0;
+ e.set = ui_get_setop();
+
+ if(textarea->onchange) {
+ textarea->onchange(&e, textarea->onchangedata);
+ }
+
+ if(textarea->onchange_action) {
+ uic_action_callback(&e, textarea->onchange_action);
+ }
+}
+
+void ui_textbuf_change_insert(
+ GtkTextBuffer *textbuffer,
+ GtkTextIter *location,
+ char *text,
+ int length,
+ UiTextArea *textarea)
+{
+ UiTextChangeEventData event;
+ event.type = UI_TEXT_INSERT;
+ event.begin = gtk_text_iter_get_offset(location);
+ event.end = event.begin + length;
+ event.text = text;
+ event.length = length;
+ textbuf_change_event(textarea, &event);
+}
+
+void ui_textbuf_change_delete(
+ GtkTextBuffer *self,
+ const GtkTextIter *start,
+ const GtkTextIter *end,
+ UiTextArea *textarea)
+{
+ UiTextChangeEventData event;
+ event.type = UI_TEXT_DELETE;
+ event.begin = gtk_text_iter_get_offset(start);
+ event.end = gtk_text_iter_get_offset(end);
+ event.text = NULL;
+ event.length = 0;
+ textbuf_change_event(textarea, &event);
+}
+
void ui_textbuf_changed(GtkTextBuffer *textbuffer, UiTextArea *textarea) {
if(!ui_onchange_events_is_enabled()) {
e.intval = 0;
e.set = ui_get_setop();
- if(textarea->onchange) {
- textarea->onchange(&e, textarea->onchangedata);
+ if(textarea->ontextchanged) {
+ textarea->ontextchanged(&e, textarea->ontextchangeddata);
+ }
+
+ if(textarea->ontextchanged_action) {
+ uic_action_callback(&e, textarea->ontextchanged_action);
}
if(value->observers) {
if(!value->data2) {
value->data2 = ui_create_undomgr();
}
+ GtkTextBuffer *buf = value->data1;
UiUndoMgr *mgr = value->data2;
if(!mgr->event) {
return;
}
}
- char *text = gtk_text_buffer_get_text(value->obj, start, end, FALSE);
+ char *text = gtk_text_buffer_get_text(buf, start, end, FALSE);
UiTextBufOp *op = malloc(sizeof(UiTextBufOp));
op->prev = NULL;
}
void ui_text_undo(UiText *value) {
+ GtkTextBuffer *buf = value->data1;
UiUndoMgr *mgr = value->data2;
if(mgr->cur) {
case UI_TEXTBUF_INSERT: {
GtkTextIter begin;
GtkTextIter end;
- gtk_text_buffer_get_iter_at_offset(value->obj, &begin, op->start);
- gtk_text_buffer_get_iter_at_offset(value->obj, &end, op->end);
- gtk_text_buffer_delete(value->obj, &begin, &end);
+ gtk_text_buffer_get_iter_at_offset(buf, &begin, op->start);
+ gtk_text_buffer_get_iter_at_offset(buf, &end, op->end);
+ gtk_text_buffer_delete(buf, &begin, &end);
break;
}
case UI_TEXTBUF_DELETE: {
GtkTextIter begin;
GtkTextIter end;
- gtk_text_buffer_get_iter_at_offset(value->obj, &begin, op->start);
- gtk_text_buffer_get_iter_at_offset(value->obj, &end, op->end);
- gtk_text_buffer_insert(value->obj, &begin, op->text, op->len);
+ gtk_text_buffer_get_iter_at_offset(buf, &begin, op->start);
+ gtk_text_buffer_get_iter_at_offset(buf, &end, op->end);
+ gtk_text_buffer_insert(buf, &begin, op->text, op->len);
break;
}
}
}
void ui_text_redo(UiText *value) {
+ GtkTextBuffer *buf = value->data1;
UiUndoMgr *mgr = value->data2;
UiTextBufOp *elm = NULL;
case UI_TEXTBUF_INSERT: {
GtkTextIter begin;
GtkTextIter end;
- gtk_text_buffer_get_iter_at_offset(value->obj, &begin, op->start);
- gtk_text_buffer_get_iter_at_offset(value->obj, &end, op->end);
- gtk_text_buffer_insert(value->obj, &begin, op->text, op->len);
+ gtk_text_buffer_get_iter_at_offset(buf, &begin, op->start);
+ gtk_text_buffer_get_iter_at_offset(buf, &end, op->end);
+ gtk_text_buffer_insert(buf, &begin, op->text, op->len);
break;
}
case UI_TEXTBUF_DELETE: {
GtkTextIter begin;
GtkTextIter end;
- gtk_text_buffer_get_iter_at_offset(value->obj, &begin, op->start);
- gtk_text_buffer_get_iter_at_offset(value->obj, &end, op->end);
- gtk_text_buffer_delete(value->obj, &begin, &end);
+ gtk_text_buffer_get_iter_at_offset(buf, &begin, op->start);
+ gtk_text_buffer_get_iter_at_offset(buf, &end, op->end);
+ gtk_text_buffer_delete(buf, &begin, &end);
break;
}
}
uitext->onchangedata = args->onchangedata;
uitext->onactivate = args->onactivate;
uitext->onactivatedata = args->onactivatedata;
+ uitext->onactivate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL;
+ uitext->onchange_action = args->onchange_action ? strdup(args->onchange_action) : NULL;
g_signal_connect(
textfield,
UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
UiLayout layout = UI_ARGS2LAYOUT(args);
ct->add(ct, textfield, &layout);
+ uic_widget_set_visibility_states(obj->ctx, textfield, args->visibility_states);
if(var) {
UiString *value = var->value;
value->obj = GTK_ENTRY(textfield);
}
- if(args->onchange || var) {
+ if(args->onchange || args->onchange_action || var) {
g_signal_connect(
textfield,
"changed",
uitext);
}
- if(args->onactivate) {
+ if(args->onactivate || args->onactivate_action) {
g_signal_connect(
textfield,
"activate",
return create_textfield(obj, FALSE, TRUE, args);
}
+void ui_textfield_focus(UIWIDGET textfield) {
+ gtk_widget_grab_focus(textfield);
+}
+
+void ui_textfield_focus_without_selecting(UIWIDGET textfield) {
+#if GTK_CHECK_VERSION(3, 16, 0)
+ gtk_entry_grab_focus_without_selecting(GTK_ENTRY(textfield));
+#else
+ gtk_widget_grab_focus(textfield);
+#endif
+}
+
+void ui_textfield_set_selection(UIWIDGET textfield, int begin, int end) {
+ ENTRY_SET_SELECTION(textfield, begin, end);
+}
+
+void ui_textfield_select_all(UIWIDGET textfield) {
+ ENTRY_SET_SELECTION(textfield, 0, -1);
+}
+
+void ui_textfield_set_editable(UIWIDGET textfield, UiBool editable) {
+ ENTRY_SET_EDITABLE(textfield, editable);
+}
+
+UiBool ui_textfield_is_editable(UIWIDGET textfield) {
+ ENTRY_IS_EDITABLE(textfield);
+}
+
+void ui_textfield_set_position(UIWIDGET textfield, int pos) {
+ ENTRY_SET_POSITION(textfield, pos);
+}
+
+int ui_textfield_get_position(UIWIDGET textfield) {
+ return ENTRY_GET_POSITION(textfield);
+}
void ui_textfield_destroy(GtkWidget *object, UiTextField *textfield) {
+ free(textfield->onactivate_action);
+ free(textfield->onchange_action);
free(textfield);
}
e.window = e.obj->window;
e.document = textfield->obj->ctx->document;
e.eventdata = value;
- e.eventdatatype = value ? UI_EVENT_DATA_TEXT_VALUE : 0;
+ e.eventdatatype = value ? UI_EVENT_DATA_STRING_VALUE : 0;
e.intval = 0;
e.set = ui_get_setop();
if(textfield->var) {
ui_notify_evt(value->observers, &e);
}
+
+ if(textfield->onchange_action) {
+ uic_action_callback(&e, textfield->onchange_action);
+ }
}
void ui_textfield_activate(GtkEntry* self, UiTextField *textfield) {
- if(textfield->onactivate) {
- UiString *value = textfield->var ? textfield->var->value : NULL;
+ UiString *value = textfield->var ? textfield->var->value : NULL;
- UiEvent e;
- e.obj = textfield->obj;
- e.window = e.obj->window;
- e.document = textfield->obj->ctx->document;
- e.eventdata = value;
- e.eventdatatype = value ? UI_EVENT_DATA_TEXT_VALUE : 0;
- e.intval = 0;
- e.set = ui_get_setop();
+ UiEvent e;
+ e.obj = textfield->obj;
+ e.window = e.obj->window;
+ e.document = textfield->obj->ctx->document;
+ e.eventdata = value;
+ e.eventdatatype = value ? UI_EVENT_DATA_TEXT_VALUE : 0;
+ e.intval = 0;
+ e.set = ui_get_setop();
+
+ if(textfield->onactivate) {
textfield->onactivate(&e, textfield->onactivatedata);
}
+
+ if(textfield->onactivate_action) {
+ uic_action_callback(&e, textfield->onactivate_action);
+ }
}
char* ui_textfield_get(UiString *str) {
UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
UiLayout layout = UI_ARGS2LAYOUT(args);
ct->add(ct, pathtf->stack, &layout);
+ uic_widget_set_visibility_states(obj->ctx, pathtf->stack, args->visibility_states);
pathtf->entry_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
pathtf->entry = gtk_entry_new();
UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
UiLayout layout = UI_ARGS2LAYOUT(args);
ct->add(ct, eventbox, &layout);
+ uic_widget_set_visibility_states(obj->ctx, eventbox, args->visibility_states);
// hbox as parent for the GtkEntry and GtkButtonBox
GtkWidget *hbox = ui_gtk_hbox_new(0);
int last_selection_state;
ui_callback onchange;
void *onchangedata;
+ char *onchange_action;
+ ui_callback ontextchanged;
+ void *ontextchangeddata;
+ char *ontextchanged_action;
} UiTextArea;
typedef struct UiTextField {
void *onchangedata;
ui_callback onactivate;
void *onactivatedata;
+ char *onactivate_action;
+ char *onchange_action;
} UiTextField;
typedef struct UiPathTextField {
char* ui_textarea_get(UiText *text);
void ui_textarea_set(UiText *text, const char *str);
char* ui_textarea_getsubstr(UiText *text, int begin, int end);
-void ui_textarea_insert(UiText *text, int pos, char *str);
+void ui_textarea_insert(UiText *text, int pos, const char *str);
+void ui_textarea_replace(UiText *text, int begin, int end, const char *replacement);
void ui_textarea_setposition(UiText *text, int pos);
int ui_textarea_position(UiText *text);
+void ui_textarea_showposition(UiText *text, int pos);
+void ui_textarea_setselection(UiText *text, int begin, int end);
void ui_textarea_selection(UiText *text, int *begin, int *end);
int ui_textarea_length(UiText *text);
void ui_textarea_remove(UiText *text, int begin, int end);
+void ui_textarea_setreadonly(UiText *text, int readonly);
void ui_textarea_realize_event(GtkWidget *widget, gpointer data);
+//void ui_textbuf_changed(GtkTextBuffer *textbuffer, UiTextArea *textarea);
+void ui_textbuf_change_insert(
+ GtkTextBuffer *textbuffer,
+ GtkTextIter *location,
+ char *text,
+ int length,
+ UiTextArea *textarea);
+void ui_textbuf_change_delete(
+ GtkTextBuffer *self,
+ const GtkTextIter *start,
+ const GtkTextIter *end,
+ UiTextArea *textarea);
+
void ui_textbuf_changed(GtkTextBuffer *textbuffer, UiTextArea *textarea);
void ui_textbuf_insert(
ui_set_widget_nstates(obj->ctx, GTK_WIDGET(button), item->args.states, item->nstates);
- if(item->args.onclick) {
+ if(item->args.onclick || item->args.action) {
UiEventData *event = cxMalloc(
obj->ctx->allocator,
sizeof(UiEventData));
event->obj = obj;
event->callback = item->args.onclick;
event->userdata = item->args.onclickdata;
+ event->action = item->args.action ? ui_strdup(obj->ctx, item->args.action) : NULL;
event->customdata = NULL;
event->customint = 0;
event->value = 0;
event->obj = obj;
event->callback = item->args.onchange;
event->userdata = item->args.onchangedata;
+ event->action = item->args.action ? ui_strdup(obj->ctx, item->args.action) : NULL;;
event->var = var;
g_signal_connect(
if(i) {
ui_notify_evt(i->observers, &e);
}
+
+ if(event->action) {
+ uic_action_callback(&e, event->action);
+ }
}
int64_t ui_tool_toggle_button_get(UiInteger *integer) {
#if UI_GTK2 || UI_GTK3
-typedef struct UiToolItemI UiToolItemI;
-typedef struct UiToolItem UiToolItem;
-typedef struct UiStToolItem UiStToolItem;
-typedef struct UiToggleToolItem UiToggleToolItem;
-
-typedef struct UiToolbarComboBox UiToolbarComboBox;
-typedef struct UiToolbarComboBoxNV UiToolbarComboBoxNV;
-
-typedef void(*ui_toolbar_add_f)(GtkToolbar*, UiToolItemI*, UiObject*);
-
-struct UiToolItemI {
- ui_toolbar_add_f add_to;
-};
-
-struct UiToolItem {
- UiToolItemI item;
- const char *label;
- const char *image;
- ui_callback callback;
- void *userdata;
- const char *varname;
- CxList *groups;
- int isimportant;
-};
-
-struct UiStToolItem {
- UiToolItemI item;
- const char *stockid;
- ui_callback callback;
- void *userdata;
- const char *varname;
- CxList *groups;
- int isimportant;
-};
-
-struct UiToggleToolItem {
- UiToolItemI item;
- const char *label;
- const char *image;
- const char *stockid;
- UiInteger *value;
- const char *var;
- CxList *groups;
- int isimportant;
-};
-
-struct UiToolbarComboBox {
- UiToolItemI item;
- UiVar *var;
- ui_getvaluefunc getvalue;
- ui_callback callback;
- void *userdata;
-};
-
-struct UiToolbarComboBoxNV {
- UiToolItemI item;
- char *listname;
- ui_getvaluefunc getvalue;
- ui_callback callback;
- void *userdata;
-};
-
void ui_toolitem_vstgr(
char *name,
#include "toolkit.h"
#include "toolbar.h"
+#include "window.h"
#include "icon.h"
#include "../common/document.h"
#include "../common/properties.h"
static UiBool exit_on_shutdown;
+// NOOP on most platforms, expect macos
+void ui_set_main_thread_error_msg(const char *msg) {}
+
UIEXPORT void ui_init(const char *appname, int argc, char **argv) {
- application_name = appname;
+ application_name = appname ? strdup(appname) : NULL;
uic_init_global_context();
#if GTK_MAJOR_VERSION >= 4
uic_toolbar_init();
ui_image_init();
uic_load_app_properties();
+ uic_init_threads();
#if GTK_MAJOR_VERSION >= 4
scale_factor = 1; // TODO
}
}
+
+void ui_app_ref(void) {
+#ifdef UI_APPLICATION
+ g_application_hold(G_APPLICATION(app));
+#else
+ // TODO
+#endif
+}
+
+void ui_app_unref(void) {
+#ifdef UI_APPLICATION
+ g_application_release(G_APPLICATION(app));
+#else
+ // TODO
+#endif
+}
+
+
#ifndef UI_GTK2
void ui_app_quit() {
g_application_quit(G_APPLICATION(app)); // TODO: fix, does not work
#endif
void ui_show(UiObject *obj) {
- gboolean visible = gtk_widget_is_visible(obj->widget);
-
- uic_check_state_widgets(obj->ctx);
+ gboolean visible = FALSE;
+ if(obj->widget) {
+ visible = gtk_widget_is_visible(obj->widget);
#if GTK_MAJOR_VERSION >= 4
- gtk_window_present(GTK_WINDOW(obj->widget));
+ gtk_window_present(GTK_WINDOW(obj->widget));
#elif GTK_MAJOR_VERSION <= 3
- gtk_widget_show_all(obj->widget);
+ gtk_widget_show_all(obj->widget);
#endif
-
+ }
+ uic_check_state_widgets(obj->ctx);
+
if(!visible) {
obj->ref++;
}
}
void ui_close(UiObject *obj) {
- uic_context_prepare_close(obj->ctx);
-#if GTK_CHECK_VERSION(4, 0, 0)
- gtk_window_close(GTK_WINDOW(obj->widget));
-#else
- gtk_widget_destroy(obj->widget);
-#endif
+ ui_window_close_request(obj);
}
}
void ui_call_mainthread(ui_threadfunc tf, void* td) {
+ if(uic_mainthread_calls_is_buffered()) {
+ uic_add_buffered_mainthread_call(tf, td);
+ return;
+ }
+
UiJob *job = malloc(sizeof(UiJob));
job->job_func = tf;
job->job_data = td;
#endif
}
-void ui_set_visible(UIWIDGET widget, UiBool visible) {
+void ui_set_visible(UIWIDGET widget, int visible) {
#if GTK_MAJOR_VERSION >= 4
gtk_widget_set_visible(widget, visible);
#else
free(userdata);
}
+void ui_destroy_eventdata(GtkWidget *object, UiEventData *data) {
+ free(data->action);
+ free(data);
+}
+
void ui_destroy_vardata(GtkWidget *unused, UiVarEventData *data) {
if(data->var) {
ui_destroy_boundvar(data->obj->ctx, data->var);
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
+}
#define BOX_REMOVE(box, child) gtk_box_remove(GTK_BOX(box), child)
#define ENTRY_SET_TEXT(entry, text) gtk_editable_set_text(GTK_EDITABLE(entry), text)
#define ENTRY_GET_TEXT(entry) gtk_editable_get_text(GTK_EDITABLE(entry))
+#define ENTRY_SET_SELECTION(entry, begin, end) gtk_editable_select_region(GTK_EDITABLE(entry), begin, end)
+#define ENTRY_SET_EDITABLE(entry, editable) gtk_editable_set_editable(GTK_EDITABLE(entry), editable)
+#define ENTRY_IS_EDITABLE(entry) gtk_editable_get_editable(GTK_EDITABLE(entry))
+#define ENTRY_SET_POSITION(entry, pos) gtk_editable_set_position(GTK_EDITABLE(entry), pos)
+#define ENTRY_GET_POSITION(entry) gtk_editable_get_position(GTK_EDITABLE(entry))
#define SCROLLEDWINDOW_NEW() gtk_scrolled_window_new()
#define SCROLLEDWINDOW_SET_CHILD(sw, child) gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), child)
#define SCROLLEDWINDOW_GET_CHILD(sw) gtk_scrolled_window_get_child(GTK_SCROLLED_WINDOW(sw))
#define BOX_REMOVE(box, child) gtk_container_remove(GTK_CONTAINER(box), child)
#define ENTRY_SET_TEXT(entry, text) gtk_entry_set_text(GTK_ENTRY(entry), text)
#define ENTRY_GET_TEXT(entry) gtk_entry_get_text(GTK_ENTRY(entry))
+#define ENTRY_SET_SELECTION(entry, begin, end) gtk_editable_select_region(GTK_EDITABLE(entry), begin, end)
+#define ENTRY_SET_EDITABLE(entry, editable) gtk_editable_set_editable(GTK_EDITABLE(entry), editable)
+#define ENTRY_IS_EDITABLE(entry) gtk_editable_get_editable(GTK_EDITABLE(entry))
+#define ENTRY_SET_POSITION(entry, pos) gtk_editable_set_position(GTK_EDITABLE(entry), pos)
+#define ENTRY_GET_POSITION(entry) gtk_editable_get_position(GTK_EDITABLE(entry))
#define SCROLLEDWINDOW_NEW() gtk_scrolled_window_new(NULL, NULL)
#define SCROLLEDWINDOW_SET_CHILD(sw, child) gtk_container_add(GTK_CONTAINER(sw), child)
#define SCROLLEDWINDOW_GET_CHILD(sw) gtk_bin_get_child(GTK_BIN(sw))
int value;
int customint;
void *customdata;
+ char *action;
} UiEventData;
typedef struct UiEventDataExt {
UiVar *var;
UiObserver **observers;
ui_callback callback;
+ char *action;
void *userdata;
int customint1;
int customint2;
void ui_set_widget_nvisibility_states(UiContext *ctx, GtkWidget *widget, const int *states, size_t ngroups);
void ui_destroy_userdata(GtkWidget *object, void *userdata);
+void ui_destroy_eventdata(GtkWidget *object, UiEventData *data);
void ui_destroy_vardata(GtkWidget *unused, UiVarEventData *data);
void ui_destroy_widget_var(GtkWidget *object, UiVar *var);
void ui_destroy_boundvar(UiContext *ctx, UiVar *var);
#include "container.h"
#include "headerbar.h"
#include "button.h"
+#include "window.h"
+#include "widget.h"
static int nwindows = 0;
g_idle_add(ui_window_destroy, data);
}
-static gboolean ui_window_close_request(UiObject *obj) {
+gboolean ui_window_close_request(UiObject *obj) {
if(obj->widget) {
void *appwindow = g_object_get_data(G_OBJECT(obj->widget), "ui.appwindow");
if(appwindow) {
}
}
- uic_context_prepare_close(obj->ctx);
- obj->ref--;
+ if(obj->ref > 0) {
+ obj->ref--;
+ } else {
+ // warn about invalid reference counting
+ fprintf(stderr, "Error: UiObject %p ref == 0\n", obj);
+ }
if(obj->ref > 0) {
#if GTK_CHECK_VERSION(2, 18, 0)
gtk_widget_set_visible(obj->widget, FALSE);
#endif
return TRUE;
} else {
+ // this cleans up any widget references from the context
+ uic_context_prepare_close(obj->ctx);
+ ui_window_widget_destroy(obj);
return FALSE;
}
}
+static void window_onclose_callback(UiObject *obj) {
+ if(obj->onclose) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ event.obj = obj;
+ event.window = obj->window;
+ event.document = obj->ctx->document;
+ obj->onclose(&event, obj->onclosedata);
+ }
+}
+
#if GTK_MAJOR_VERSION >= 4
static gboolean close_request(GtkWindow* self, UiObject *obj) {
+ window_onclose_callback(obj);
return ui_window_close_request(obj);
}
#else
static gboolean close_request(GtkWidget* self, GdkEvent* event, UiObject *obj) {
+ window_onclose_callback(obj);
return ui_window_close_request(obj);
}
#endif
obj->widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
#endif
+#if GTK_MAJOR_VERSION < 4
+ const char *window_pos = ui_get_property("ui.gtk.window.position");
+ GtkWindowPosition wpos = GTK_WIN_POS_CENTER;
+ if(window_pos) {
+ if(!strcmp(window_pos, "none")) {
+ wpos = GTK_WIN_POS_NONE;
+ } else if(!strcmp(window_pos, "center")) {
+ //wpos = GTK_WIN_POS_CENTER;
+ } else if(!strcmp(window_pos, "mouse")) {
+ wpos = GTK_WIN_POS_MOUSE;
+ } else if(!strcmp(window_pos, "center_always")) {
+ wpos = GTK_WIN_POS_CENTER_ALWAYS;
+ } else {
+ fprintf(stderr, "Error: unknown value '%s' for property ui.gtk.window.positionhint", window_pos);
+ }
+ }
+ gtk_window_set_position(GTK_WINDOW(obj->widget), wpos);
+#endif
+
#if GTK_CHECK_VERSION(4, 0, 0)
obj->ctx->action_map = G_ACTION_MAP(obj->widget);
#endif
g_object_set_data(G_OBJECT(obj->widget), "ui_window_splitview", content);
g_object_set_data(G_OBJECT(obj->widget), "ui_left_panel", vbox);
g_object_set_data(G_OBJECT(obj->widget), "ui_right_panel", right_vbox);
+ g_object_set_data(G_OBJECT(obj->widget), "ui_left_panel_top", toolbar_view);
+ g_object_set_data(G_OBJECT(obj->widget), "ui_right_panel_top", right_panel);
}
GtkWidget *content_box = vbox;
adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE);
} else if(!strcmp(show_title, "sidebar")) {
adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_main), FALSE);
- adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), TRUE);
+ if(headerbar_sidebar) {
+ adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), TRUE);
+ }
} else if(!strcmp(show_title, "false")) {
- adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE);
+ if(headerbar_sidebar) {
+ adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE);
+ }
adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_main), FALSE);
} else {
fprintf(stderr, "Unknown value '%s' for property ui.gtk.window.showtitle\n", show_title);
- adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE);
+ if(headerbar_sidebar) {
+ adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE);
+ }
}
} else {
adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_main), FALSE);
- if(sidebar) {
+ if(headerbar_sidebar) {
adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), TRUE);
}
}
g_object_set_data(G_OBJECT(obj->widget), "ui_window_splitview", content_paned);
g_object_set_data(G_OBJECT(obj->widget), "ui_left_panel", content_box);
g_object_set_data(G_OBJECT(obj->widget), "ui_right_panel", right_content_box);
+ g_object_set_data(G_OBJECT(obj->widget), "ui_left_panel_top", content_box);
+ g_object_set_data(G_OBJECT(obj->widget), "ui_right_panel_top", right_content_box);
} else {
PANED_SET_CHILD2(paned, content_box);
}
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++;
UIEXPORT void ui_splitview_window_set_visible(UiObject *obj, int pane, UiBool visible) {
GtkWidget *panel = NULL;
+ CxList *backup_items = NULL;
if(pane == 0) {
- panel = g_object_get_data(G_OBJECT(obj->widget), "ui_left_panel");
+ panel = g_object_get_data(G_OBJECT(obj->widget), "ui_left_panel_top");
+ backup_items = g_object_get_data(G_OBJECT(obj->widget), "ui_toolbar_center_backup");
} else if(pane == 1) {
- panel = g_object_get_data(G_OBJECT(obj->widget), "ui_right_panel");
+ panel = g_object_get_data(G_OBJECT(obj->widget), "ui_right_panel_top");
+ // TODO: backup toolbar items
}
if(panel == NULL) {
}
gtk_widget_set_visible(panel, visible);
+
+ if(backup_items) {
+ CxIterator i = cxListIterator(backup_items);
+ cx_foreach(GtkWidget*, w, i) {
+ ui_set_visible(w, !visible);
+ }
+ }
}
#ifdef UI_LIBADWAITA
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)
}
if(args->lbutton1) {
- GtkWidget *button = ui_create_button(obj, args->lbutton1, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 1, args->default_button == 1);
+ GtkWidget *button = ui_create_button(obj, args->lbutton1, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 1, args->default_button == 1);
gtk_header_bar_pack_start(GTK_HEADER_BAR(headerbar), button);
if(args->default_button == 1) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
}
}
if(args->lbutton2) {
- GtkWidget *button = ui_create_button(obj, args->lbutton2, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 2, args->default_button == 2);
+ GtkWidget *button = ui_create_button(obj, args->lbutton2, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 2, args->default_button == 2);
gtk_header_bar_pack_start(GTK_HEADER_BAR(headerbar), button);
if(args->default_button == 2) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
}
if(args->rbutton4) {
- GtkWidget *button = ui_create_button(obj, args->rbutton4, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 4, args->default_button == 4);
+ GtkWidget *button = ui_create_button(obj, args->rbutton4, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 4, args->default_button == 4);
gtk_header_bar_pack_end(GTK_HEADER_BAR(headerbar), button);
if(args->default_button == 4) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
}
}
if(args->rbutton3) {
- GtkWidget *button = ui_create_button(obj, args->rbutton3, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 3, args->default_button == 3);
+ GtkWidget *button = ui_create_button(obj, args->rbutton3, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 3, args->default_button == 3);
gtk_header_bar_pack_end(GTK_HEADER_BAR(headerbar), button);
if(args->default_button == 3) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
if(args->lbutton1) {
- GtkWidget *button = ui_create_button(obj, args->lbutton1, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 1, args->default_button == 1);
+ GtkWidget *button = ui_create_button(obj, args->lbutton1, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 1, args->default_button == 1);
gtk_grid_attach(GTK_GRID(grid), button, 0, 0, 1, 1);
if(args->default_button == 1) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
}
}
if(args->lbutton2) {
- GtkWidget *button = ui_create_button(obj, args->lbutton2, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 2, args->default_button == 2);
+ GtkWidget *button = ui_create_button(obj, args->lbutton2, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 2, args->default_button == 2);
gtk_grid_attach(GTK_GRID(grid), button, 1, 0, 1, 1);
if(args->default_button == 2) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
gtk_widget_set_hexpand(space, TRUE);
gtk_grid_attach(GTK_GRID(grid), space, 2, 0, 1, 1);
if(args->rbutton3) {
- GtkWidget *button = ui_create_button(obj, args->rbutton3, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 3, args->default_button == 3);
+ GtkWidget *button = ui_create_button(obj, args->rbutton3, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 3, args->default_button == 3);
gtk_grid_attach(GTK_GRID(grid), button, 3, 0, 1, 1);
if(args->default_button == 3) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
}
}
if(args->rbutton4) {
- GtkWidget *button = ui_create_button(obj, args->rbutton4, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 4, args->default_button == 4);
+ GtkWidget *button = ui_create_button(obj, args->rbutton4, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 4, args->default_button == 4);
gtk_grid_attach(GTK_GRID(grid), button, 4, 0, 1, 1);
if(args->default_button == 4) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
--- /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 WINDOW_H
+#define WINDOW_H
+
+#include "toolkit.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+gboolean ui_window_close_request(UiObject *obj);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WINDOW_H */
+
NULL, // set_values_hook
XtInheritSetValuesAlmost, // set_values_almost
NULL, // get_values_hook
- (XtAcceptFocusProc)grid_acceptfocus, // accept_focus
+ (XtAcceptFocusProc)NULL, // accept_focus
XtVersion, // version
NULL, // callback_offsets
//NULL, // tm_table
- defaultTranslations,
+ XtInheritTranslations, //defaultTranslations,
XtInheritQueryGeometry, // query_geometry
NULL, // display_accelerator
NULL, // extension
void grid_realize(Widget w,XtValueMask *valueMask,XSetWindowAttributes *attributes) {
Grid grid = (Grid)w;
XtMakeResizeRequest(w, 400, 400, NULL, NULL);
- (coreClassRec.core_class.realize)((Widget)w, valueMask, attributes);
+ (*xmManagerClassRec.core_class.realize)(w, valueMask, attributes);
grid_place_children(grid);
}
return False;
}
-Boolean grid_acceptfocus(Widget w, Time *t) {
-
-}
void grid_getfocus(Widget myw, XEvent *event, String *params, Cardinal *nparam) {
# POSSIBILITY OF SUCH DAMAGE.
#
-$(MOTIF_OBJPRE)%.o: motif/%.c
- $(CC) -o $@ -c -I../ucx $(CFLAGS) $(SHLIB_CFLAGS) $(TK_CFLAGS) $<
-
$(UI_LIB): $(OBJ)
$(AR) $(ARFLAGS) $(UI_LIB) $(OBJ)
$(UI_SHLIB): $(OBJ)
$(CC) -o $(UI_SHLIB) $(LDFLAGS) $(SHLIB_LDFLAGS) $(TK_LDFLAGS) $(OBJ) -L../build/lib -lucx
+
+FORCE:
+
+$(MOTIF_OBJPRE)button.o: motif/button.c motif/button.h \
+ motif/../ui/button.h motif/../ui/toolkit.h motif/toolkit.h \
+ motif/../ui/toolkit.h motif/../common/context.h \
+ motif/../common/../ui/toolkit.h motif/../common/action.h \
+ motif/../common/object.h motif/container.h motif/../ui/container.h \
+ motif/../common/action.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)container.o: motif/container.c motif/container.h \
+ motif/../ui/toolkit.h motif/../ui/container.h motif/../ui/toolkit.h \
+ motif/../common/context.h motif/../common/../ui/toolkit.h \
+ motif/../common/action.h motif/../common/object.h \
+ motif/../common/container.h motif/../common/../ui/container.h \
+ motif/Grid.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)dnd.o: motif/dnd.c motif/dnd.h motif/../ui/dnd.h \
+ motif/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)entry.o: motif/entry.c motif/entry.h motif/../ui/entry.h \
+ motif/../ui/toolkit.h motif/container.h motif/../ui/toolkit.h \
+ motif/../ui/container.h motif/toolkit.h motif/../common/context.h \
+ motif/../common/../ui/toolkit.h motif/../common/action.h \
+ motif/../common/object.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)Fsb.o: motif/Fsb.c motif/Fsb.h motif/FsbP.h \
+ motif/pathbar.h motif/../ui/text.h motif/../ui/toolkit.h \
+ motif/../common/utils.h motif/../common/../ui/toolkit.h \
+ motif/../common/../ui/text.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)graphics.o: motif/graphics.c motif/graphics.h \
+ motif/../ui/graphics.h motif/../ui/toolkit.h motif/toolkit.h \
+ motif/../ui/toolkit.h motif/../common/context.h \
+ motif/../common/../ui/toolkit.h motif/../common/action.h \
+ motif/../common/object.h motif/container.h motif/../ui/container.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)Grid.o: motif/Grid.c motif/Grid.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)image.o: motif/image.c motif/image.h motif/../ui/image.h \
+ motif/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)label.o: motif/label.c motif/label.h motif/../ui/display.h \
+ motif/../ui/toolkit.h motif/../common/context.h \
+ motif/../common/../ui/toolkit.h motif/../common/action.h \
+ motif/container.h motif/../ui/toolkit.h motif/../ui/container.h \
+ motif/../common/object.h motif/Grid.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)list.o: motif/list.c motif/container.h \
+ motif/../ui/toolkit.h motif/../ui/container.h motif/../ui/toolkit.h \
+ motif/list.h motif/toolkit.h motif/../common/context.h \
+ motif/../common/../ui/toolkit.h motif/../common/action.h \
+ motif/../common/object.h motif/../ui/list.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)menu.o: motif/menu.c motif/menu.h motif/../ui/menu.h \
+ motif/../ui/toolkit.h motif/../common/menu.h \
+ motif/../common/../ui/menu.h motif/../common/context.h \
+ motif/../common/../ui/toolkit.h motif/../common/action.h motif/button.h \
+ motif/../ui/button.h motif/toolkit.h motif/../ui/toolkit.h \
+ motif/../common/object.h motif/container.h motif/../ui/container.h \
+ motif/../common/types.h motif/../ui/window.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)pathbar.o: motif/pathbar.c motif/pathbar.h \
+ motif/../ui/text.h motif/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)range.o: motif/range.c motif/range.h motif/toolkit.h \
+ motif/../ui/toolkit.h motif/../common/context.h \
+ motif/../common/../ui/toolkit.h motif/../common/action.h \
+ motif/../common/object.h motif/../ui/range.h motif/../ui/toolkit.h \
+ motif/container.h motif/../ui/container.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)text.o: motif/text.c motif/text.h motif/../ui/text.h \
+ motif/../ui/toolkit.h motif/toolkit.h motif/../ui/toolkit.h \
+ motif/../common/context.h motif/../common/../ui/toolkit.h \
+ motif/../common/action.h motif/../common/object.h motif/container.h \
+ motif/../ui/container.h motif/pathbar.h motif/../common/utils.h \
+ motif/../common/../ui/text.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)toolbar.o: motif/toolbar.c motif/toolbar.h \
+ motif/../ui/toolbar.h motif/../ui/toolkit.h motif/button.h \
+ motif/../ui/button.h motif/toolkit.h motif/../ui/toolkit.h \
+ motif/../common/context.h motif/../common/../ui/toolkit.h \
+ motif/../common/action.h motif/../common/object.h motif/list.h \
+ motif/../ui/list.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)toolkit.o: motif/toolkit.c motif/toolkit.h \
+ motif/../ui/toolkit.h motif/../common/context.h \
+ motif/../common/../ui/toolkit.h motif/../common/action.h \
+ motif/../common/object.h motif/toolbar.h motif/../ui/toolbar.h \
+ motif/../ui/toolkit.h motif/container.h motif/../ui/container.h \
+ motif/../common/menu.h motif/../common/../ui/menu.h \
+ motif/../common/../ui/toolkit.h motif/../common/toolbar.h \
+ motif/../common/../ui/toolbar.h motif/../common/menu.h \
+ motif/../common/document.h motif/../common/context.h \
+ motif/../common/properties.h motif/../common/../ui/properties.h \
+ motif/../common/app.h motif/../common/threadpool.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)widget.o: motif/widget.c motif/../ui/widget.h \
+ motif/../ui/toolkit.h motif/container.h motif/../ui/toolkit.h \
+ motif/../ui/container.h motif/../common/context.h \
+ motif/../common/../ui/toolkit.h motif/../common/action.h \
+ motif/../common/object.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(MOTIF_OBJPRE)window.o: motif/window.c motif/window.h \
+ motif/../ui/window.h motif/../ui/toolkit.h motif/../ui/widget.h \
+ motif/toolkit.h motif/../ui/toolkit.h motif/../common/context.h \
+ motif/../common/../ui/toolkit.h motif/../common/action.h \
+ motif/../common/object.h motif/menu.h motif/../ui/menu.h \
+ motif/../common/menu.h motif/../common/../ui/menu.h motif/toolbar.h \
+ motif/../ui/toolbar.h motif/container.h motif/../ui/container.h \
+ motif/pathbar.h motif/../ui/text.h motif/../common/utils.h \
+ motif/../common/../ui/text.h motif/Grid.h motif/Fsb.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
#include "button.h"
#include "container.h"
#include "../common/context.h"
+#include "../common/action.h"
#include <cx/mempool.h>
#include <cx/linked_list.h>
Widget button = XmCreatePushButton(parent, name, xargs, n);
XtManageChild(button);
ui_container_add(ctn, button);
+ uic_widget_set_visibility_states(obj->ctx, button, args->visibility_states);
ui_set_widget_groups(obj->ctx, button, args->states);
eventdata->userdata = args->onclickdata;
eventdata->obj = obj;
eventdata->value = 0;
+ eventdata->action = args->action ? strdup(args->action) : NULL;
XtAddCallback(
button,
XmNactivateCallback,
XtAddCallback(
button,
XmNdestroyCallback,
- (XtCallbackProc)ui_destroy_data,
+ (XtCallbackProc)ui_destroy_event_data,
eventdata);
}
e.intval = event->value;
e.set = 0;
event->callback(&e, event->userdata);
+
+ if(event->action) {
+ uic_action_callback(&e, event->action);
+ }
}
UIWIDGET ui_togglebutton_create(UiObject* obj, UiToggleArgs *args) {
Widget button = XmCreateToggleButton(parent, name, xargs, n);
XtManageChild(button);
ui_container_add(ctn, button);
+ uic_widget_set_visibility_states(obj->ctx, button, args->visibility_states);
ui_set_widget_groups(obj->ctx, button, args->states);
- ui_bind_togglebutton(obj, button, args->varname, args->value, args->onchange, args->onchangedata, args->enable_state);
+ ui_bind_togglebutton(obj, button, args->varname, args->value, args->onchange, args->onchangedata, args->action, args->enable_state);
XmStringFree(label);
return button;
Widget button = XmCreateToggleButton(parent, name, xargs, n);
XtManageChild(button);
ui_container_add(ctn, button);
+ uic_widget_set_visibility_states(obj->ctx, button, args->visibility_states);
ui_set_widget_groups(obj->ctx, button, args->states);
- ui_bind_togglebutton(obj, button, args->varname, args->value, args->onchange, args->onchangedata, args->enable_state);
+ ui_bind_togglebutton(obj, button, args->varname, args->value, args->onchange, args->onchangedata, args->action, args->enable_state);
XmStringFree(label);
return button;
event->callback(&e, event->userdata);
}
+ if(event->action) {
+ uic_action_callback(&e, event->action);
+ }
+
if(event->var && event->var->value) {
UiInteger *v = event->var->value;
v->value = e.intval;
UiInteger *value,
ui_callback onchange,
void *onchangedata,
+ const char *action,
int enable_state)
{
UiVar* var = uic_widget_var(obj->ctx, obj->ctx, value, varname, UI_VAR_INTEGER);
event->obj = obj;
event->callback = onchange;
event->userdata = onchangedata;
+ event->action = action ? strdup(action) : NULL;
event->var = var;
event->observers = NULL;
event->value = enable_state;
XtAddCallback(
widget,
XmNdestroyCallback,
- (XtCallbackProc)ui_destroy_data,
+ (XtCallbackProc)ui_destroy_var_event_data,
event);
}
event->callback(&e, event->userdata);
}
+ if(event->action) {
+ uic_action_callback(&e, event->action);
+ }
+
if(value) {
ui_notify_evt(value->observers, &e);
}
}
-void ui_bind_radiobutton(UiObject *obj, Widget rbutton, UiInteger *value, const char *varname, ui_callback onchange, void *onchangedata, int enable_group) {
+void ui_bind_radiobutton(UiObject *obj, Widget rbutton, UiInteger *value, const char *varname, ui_callback onchange, void *onchangedata, const char *action, int enable_group) {
UiVar* var = uic_widget_var(obj->ctx, obj->ctx, value, varname, UI_VAR_INTEGER);
if(var) {
UiInteger *value = var->value;
event->obj = obj;
event->callback = onchange;
event->userdata = onchangedata;
+ event->action = action ? strdup(action) : NULL;
event->observers = NULL;
event->var = var;
event->value = enable_group;
Widget button = XmCreateToggleButton(parent, name, xargs, n);
XtManageChild(button);
ui_container_add(ctn, button);
+ uic_widget_set_visibility_states(obj->ctx, button, args->visibility_states);
ui_set_widget_groups(obj->ctx, button, args->states);
event->obj = obj;
event->callback = args->onchange;
event->userdata = args->onchangedata;
+ event->action = args->action ? strdup(args->action) : NULL;
event->observers = NULL;
event->var = var;
event->value = args->enable_state;
UiInteger *value,
ui_callback onchange,
void *onchangedata,
+ const char *action,
int enable_state);
int64_t ui_togglebutton_get(UiInteger *i);
void ui_togglebutton_set(UiInteger *i, int64_t value);
-void ui_bind_radiobutton(UiObject *obj, Widget rbutton, UiInteger *value, const char *varname, ui_callback onchange, void *onchangedata, int enable_group);
+void ui_bind_radiobutton(UiObject *obj, Widget rbutton, UiInteger *value, const char *varname, ui_callback onchange, void *onchangedata, const char *action, int enable_group);
int64_t ui_radiobutton_get(UiInteger *i);
void ui_radiobutton_set(UiInteger *i, int64_t value);
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 grid;
}
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 = {
}
}
+ uic_widget_set_visibility_states(obj->ctx, frame, args->visibility_states);
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);
return form;
}
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);
Widget w = XmCreateLabel(parent, name, xargs, n);
XtManageChild(w);
ui_container_add(ctn, w);
+ uic_widget_set_visibility_states(obj->ctx, w, args->visibility_states);
XmStringFree(label);
char *name = args->name ? (char*)args->name : "progressbar";
Widget frame = XmCreateFrame(parent, name, xargs, n);
ui_container_add(ctn, frame);
+ uic_widget_set_visibility_states(obj->ctx, frame, args->visibility_states);
// create a button and get some informations about the height, shadow, highlight, ....
// we want the frame to have the same dimensions as a normal button
Widget w = XmCreateLabel(parent, name, xargs, n);
XtManageChild(w);
ui_container_add(ctn, w);
+ uic_widget_set_visibility_states(obj->ctx, w, args->visibility_states);
UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_INTEGER);
if(var) {
XmStringFree(s);
}
- ui_bind_togglebutton(obj, checkbox, it->varname, NULL, it->callback, it->userdata, 0);
+ ui_bind_togglebutton(obj, checkbox, it->varname, NULL, it->callback, it->userdata, NULL, 0);
ui_set_widget_groups(obj->ctx, checkbox, it->states);
}
Widget button = XmCreateToggleButton(p, "menuradiobutton", args, n);
XtManageChild(button);
- ui_bind_radiobutton(obj, button, NULL, it->varname, it->callback, it->userdata, 0);
+ ui_bind_radiobutton(obj, button, NULL, it->varname, it->callback, it->userdata, NULL, 0);
}
static void menuitem_list_remove_binding(void *obj) {
i++;
}
- ui_getvaluefunc getvalue = list->getvalue;
+ int row = 0;
+ ui_getvaluefunc2 getvalue = list->getvalue;
+ void *getvaluedata = list->getvaluedata;
int pos = list->index;
while(elm) {
n = 0;
- char *label = (char*) (getvalue ? getvalue(elm, 0) : elm);
+ UiBool freeResult = FALSE;
+ char *label = (char*) (getvalue ? getvalue(ls, elm, row, 0, getvaluedata, &freeResult) : elm);
if(label) {
s = XmStringCreateLocalized(label);
XtSetArg(args[n], XmNlabelString, s); n++;
eventdata);
}
+ if(freeResult) {
+ free(label);
+ }
+
elm = ui_list_next(ls);
+ row++;
i++;
}
int index;
int oldcount;
UiVar *var;
- ui_getvaluefunc getvalue;
+ ui_getvaluefunc2 getvalue;
+ void *getvaluedata;
ui_callback callback;
void *userdata;
bool addseparator;
Widget widget = XmCreateScrolledText(parent, name, xargs, n);
XtManageChild(widget);
ui_container_add(ctn, widget);
+ uic_widget_set_visibility_states(obj->ctx, widget, args->visibility_states);
UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_TEXT);
var);
}
+ if(args->onchange || args->onchange_action) {
+
+ }
+
return widget;
}
return str;
}
-void ui_textarea_insert(UiText *text, int pos, char *str) {
+void ui_textarea_insert(UiText *text, int pos, const char *str) {
text->value.ptr = NULL;
- XmTextInsert(text->obj, pos, str);
+ XmTextInsert(text->obj, pos, (char*)str);
if(text->value.ptr) {
text->value.free(text->value.ptr);
}
int sel = left < right ? 1 : 0;
if(sel != textarea->last_selection_state) {
if(sel) {
- ui_set_state(textarea->obj->ctx, UI_GROUP_SELECTION);
+ ui_set_state(textarea->obj->ctx, UI_STATE_SELECTION);
} else {
- ui_unset_state(textarea->obj->ctx, UI_GROUP_SELECTION);
+ ui_unset_state(textarea->obj->ctx, UI_STATE_SELECTION);
}
}
textarea->last_selection_state = sel;
XtManageChild(textfield);
ui_container_add(ctn, textfield);
+ uic_widget_set_visibility_states(obj->ctx, textfield, args->visibility_states);
ui_set_widget_groups(obj->ctx, textfield, args->states);
UiEventDataExt *eventdata = malloc(sizeof(UiEventDataExt));
return create_textfield(obj, args, FALSE, FALSE);
}
+void ui_textfield_focus(UIWIDGET textfield) {
+ ui_textfield_focus_without_selecting(textfield);
+ ui_textfield_select_all(textfield);
+}
+
+void ui_textfield_focus_without_selecting(UIWIDGET textfield) {
+ XmProcessTraversal(textfield, XmTRAVERSE_CURRENT);
+}
+
+void ui_textfield_set_selection(UIWIDGET textfield, int begin, int end) {
+ XmTextSetSelection(textfield, begin, end, 0);
+}
+
+void ui_textfield_select_all(UIWIDGET textfield) {
+ XmTextSetSelection(textfield, 0, XmTextGetLastPosition(textfield), 0);
+}
+
+void ui_textfield_set_editable(UIWIDGET textfield, UiBool editable) {
+ XmTextFieldSetEditable(textfield, editable);
+}
+
+UiBool ui_textfield_is_editable(UIWIDGET textfield) {
+ return XmTextFieldGetEditable(textfield);
+}
+
+void ui_textfield_set_position(UIWIDGET textfield, int pos) {
+ XmTextFieldSetInsertionPosition(textfield, pos);
+}
+
+int ui_textfield_get_position(UIWIDGET textfield) {
+ return (int)XmTextFieldGetInsertionPosition(textfield);
+}
+
char* ui_textfield_get(UiString *str) {
if(str->value.free) {
str->value.free(str->value.ptr);
XtManageChild(pathbar->widget);
ui_container_add(ctn, pathbar->widget);
+ uic_widget_set_visibility_states(obj->ctx, pathbar->widget, args->visibility_states);
UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_STRING);
if (var) {
char* ui_textarea_get(UiText *text);
void ui_textarea_set(UiText *text, const char *str);
char* ui_textarea_getsubstr(UiText *text, int begin, int end);
-void ui_textarea_insert(UiText *text, int pos, char *str);
+void ui_textarea_insert(UiText *text, int pos, const char *str);
void ui_textarea_setposition(UiText *text, int pos);
int ui_textarea_position(UiText *text);
void ui_textarea_selection(UiText *text, int *begin, int *end);
#include "../common/document.h"
#include "../common/properties.h"
#include "../common/app.h"
+#include "../common/threadpool.h"
#include <cx/buffer.h>
#include <X11/Intrinsic.h>
fallback_resources = fallbackres;
}
+// NOOP on most platforms, expect macos
+void ui_set_main_thread_error_msg(const char *msg) {}
+
void ui_init(const char *appname, int argc, char **argv) {
- application_name = appname;
+ application_name = appname ? strdup(appname) : NULL;
uic_init_global_context();
XtToolkitInitialize();
app = XtCreateApplicationContext();
XtAppSetFallbackResources(app, fallback_resources);
- display = XtOpenDisplay(app, NULL, appname, appname, NULL, 0, &argc, argv);
+ display = XtOpenDisplay(app, NULL, application_name, application_name, NULL, 0, &argc, argv);
uic_menu_init();
uic_toolbar_init();
}
}
+void ui_app_ref(void) {
+ // TODO
+}
+
+void ui_app_unref(void) {
+ // TODO
+}
+
void ui_app_quit() {
XtAppSetExitFlag(app);
}
void ui_show(UiObject *obj) {
uic_check_state_widgets(obj->ctx);
- if(!XtIsRealized(obj->widget)) {
- XtRealizeWidget(obj->widget);
+ if(obj->widget) {
+ if(!XtIsRealized(obj->widget)) {
+ XtRealizeWidget(obj->widget);
+ obj->ref++;
+ }
+ } else {
obj->ref++;
}
}
}
void ui_call_mainthread(ui_threadfunc tf, void* td) {
+ if(uic_mainthread_calls_is_buffered()) {
+ uic_add_buffered_mainthread_call(tf, td);
+ return;
+ }
+
UiJob *job = malloc(sizeof(UiJob));
memset(job, 0, sizeof(UiJob));
job->job_func = tf;
free(data);
}
+void ui_destroy_event_data(Widget w, UiEventData *data, XtPointer d) {
+ free(data->action);
+ free(data);
+}
+
+void ui_destroy_var_event_data(Widget w, UiVarEventData *data, XtPointer d) {
+ free(data->action);
+ free(data);
+}
+
void ui_set_widget_groups(UiContext *ctx, Widget widget, const int *groups) {
if(!groups) {
return;
void *userdata;
int value;
void *customdata;
+ char *action;
} UiEventData;
typedef struct UiEventDataExt {
UiObserver **observers;
ui_callback callback;
void *userdata;
+ char *action;
int value;
} UiVarEventData;
void ui_destroy_data(Widget w, XtPointer data, XtPointer d);
+void ui_destroy_event_data(Widget w, UiEventData *data, XtPointer d);
+
+void ui_destroy_var_event_data(Widget w, UiVarEventData *data, XtPointer d);
+
void ui_set_widget_groups(UiContext *ctx, Widget widget, const int *groups) ;
void ui_set_widget_ngroups(UiContext *ctx, Widget widget, const int *groups, size_t ngroups);
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() {}
if(args->multiselection) {
view->setSelectionMode(QAbstractItemView::ExtendedSelection);
}
+ if(args->hide_header) {
+ view->setHeaderHidden(true);
+ }
UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST);
add_menu_items(menu, i, m, obj);
}
-static UiAction* create_action(
+static UiQAction* create_action(
UiObject *obj,
const char *icon,
const char *label,
int *states)
{
QString str = QString::fromUtf8(label);
- UiAction *action = new UiAction(obj, str, callback, userdata);
+ UiQAction *action = new UiQAction(obj, str, callback, userdata);
if(icon) {
action->setIcon(QIcon::fromTheme(icon));
action->setIconVisibleInMenu(true);
void add_menuitem_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj) {
UiMenuItem *it = (UiMenuItem*)item;
- UiAction *action = create_action(obj, it->icon, it->label, it->callback, it->userdata, it->states);
+ UiQAction *action = create_action(obj, it->icon, it->label, it->callback, it->userdata, it->states);
parent->addAction(action);
QObject::connect(action, SIGNAL(triggered()), action, SLOT(trigger()));
}
void add_checkitem_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj) {
UiMenuCheckItem *it = (UiMenuCheckItem*)item;
- UiAction *action = create_action(obj, it->icon, it->label, it->callback, it->userdata, it->states);
+ UiQAction *action = create_action(obj, it->icon, it->label, it->callback, it->userdata, it->states);
parent->addAction(action);
action->setCheckable(true);
action->prepare_event = ui_checkableaction_prepare_event;
void add_radioitem_widget(QMenu *parent, int index, UiMenuItemI *item, UiObject *obj) {
UiMenuRadioItem *it = (UiMenuRadioItem*)item;
- UiAction *action = create_action(obj, it->icon, it->label, it->callback, it->userdata, it->states);
+ UiQAction *action = create_action(obj, it->icon, it->label, it->callback, it->userdata, it->states);
parent->addAction(action);
action->setCheckable(true);
action->prepare_event = ui_actiongroup_prepare_event;
action->var;
}
-void ui_actiongroup_prepare_event(UiEvent *event, UiAction *action) {
+void ui_actiongroup_prepare_event(UiEvent *event, UiQAction *action) {
if(action->var) {
UiInteger *value = (UiInteger*)action->var->value;
event->eventdata = value;
}
}
-void ui_checkableaction_prepare_event(UiEvent *event, UiAction *action) {
+void ui_checkableaction_prepare_event(UiEvent *event, UiQAction *action) {
if(action->var) {
event->eventdata = action->var->value;
event->eventdatatype = UI_EVENT_DATA_INTEGER_VALUE;
}
int64_t ui_checkableaction_get(UiInteger *value) {
- UiAction *action= (UiAction*)value->obj;
+ UiQAction *action= (UiQAction*)value->obj;
value->value = action->isChecked();
return value->value;
}
void ui_checkableaction_set(UiInteger *value, int64_t i) {
- UiAction *action = (UiAction*)value->obj;
+ UiQAction *action = (UiQAction*)value->obj;
value->value = i;
if(i != 0) {
action->setChecked((bool)i);
void add_checkitemnv_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj);
void add_menuitem_list_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj);
-void ui_checkableaction_prepare_event(UiEvent *event, UiAction *action);
+void ui_checkableaction_prepare_event(UiEvent *event, UiQAction *action);
int64_t ui_checkableaction_get(UiInteger *value);
void ui_checkableaction_set(UiInteger *value, int64_t i);
-void ui_actiongroup_prepare_event(UiEvent *event, UiAction *action);
+void ui_actiongroup_prepare_event(UiEvent *event, UiQAction *action);
int64_t ui_actiongroup_get(UiInteger *value);
void ui_actiongroup_set(UiInteger *value, int64_t i);
}
void ListModel::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) {
+ if(!ui_selection_events_is_enabled()) {
+ return;
+ }
+
UiListSelection sel;
if(listview) {
sel = ui_selection_model_to_selection(listview->selectionModel());
return textarea;
}
+UIWIDGET ui_textarea_gettextwidget(UIWIDGET textarea) {
+ return textarea;
+}
+
void ui_textarea_save(UiText *text) {
// NOOP
}
return cstr ? strdup(cstr) : NULL;
}
-void ui_textarea_insert(UiText *text, int pos, char *str) {
+void ui_textarea_insert(UiText *text, int pos, const char *str) {
QTextDocument *doc = (QTextDocument*)text->data1;
QTextCursor cursor(doc);
cursor.setPosition(pos);
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) {
}
str->value.ptr = NULL;
}
+
+void ui_textfield_focus(UIWIDGET textfield) {
+ QLineEdit *edit = static_cast<QLineEdit*>(textfield);
+ edit->setFocus();
+ edit->selectAll();
+}
+
+void ui_textfield_focus_without_selecting(UIWIDGET textfield) {
+ QLineEdit *edit = static_cast<QLineEdit*>(textfield);
+ edit->setFocus();
+}
+
+void ui_textfield_set_selection(UIWIDGET textfield, int begin, int end) {
+ QLineEdit *edit = static_cast<QLineEdit*>(textfield);
+ if (begin < 0) {
+ begin = 0;
+ }
+ if (end < begin) {
+ end = begin;
+ }
+ edit->setSelection(begin, end - begin);
+}
+
+void ui_textfield_select_all(UIWIDGET textfield) {
+ QLineEdit *edit = static_cast<QLineEdit*>(textfield);
+ edit->selectAll();
+}
+
+void ui_textfield_set_editable(UIWIDGET textfield, UiBool editable) {
+ QLineEdit *edit = static_cast<QLineEdit*>(textfield);
+ edit->setReadOnly(!editable);
+}
+
+UiBool ui_textfield_is_editable(UIWIDGET textfield) {
+ QLineEdit *edit = static_cast<QLineEdit*>(textfield);
+ return !edit->isReadOnly();
+}
+
+void ui_textfield_set_position(UIWIDGET textfield, int pos) {
+ QLineEdit *edit = static_cast<QLineEdit*>(textfield);
+ edit->setCursorPosition(pos);
+}
+
+int ui_textfield_get_position(UIWIDGET textfield) {
+ QLineEdit *edit = static_cast<QLineEdit*>(textfield);
+ return edit->cursorPosition();
+}
char* ui_textarea_get(UiText *text);
void ui_textarea_set(UiText *text, const char *str);
char* ui_textarea_getsubstr(UiText *text, int begin, int end);
-void ui_textarea_insert(UiText *text, int pos, char *str);
+void ui_textarea_insert(UiText *text, int pos, const char *str);
void ui_textarea_setposition(UiText *text, int pos);
int ui_textarea_position(UiText *text);
void ui_textarea_setselection(UiText *text, int begin, int end);
static UiBool exit_on_shutdown;
+// NOOP on most platforms, expect macos
+extern "C" UIEXPORT void ui_set_main_thread_error_msg(const char *msg) {}
+
void ui_init(const char *appname, int argc, char **argv) {
- application_name = appname;
+ application_name = appname ? strdup(appname) : NULL;
app_argc = argc;
app_argv = argv;
}
}
+void ui_app_ref(void) {
+ // TODO
+}
+
+void ui_app_unref(void) {
+ // TODO
+}
+
void ui_show(UiObject *obj) {
obj->widget->show();
}
/* --------------------- Implemtation UiAction --------------------- */
-UiAction::UiAction(UiObject *obj, QString &label, ui_callback f, void *userdata) : QAction(label, NULL) {
+UiQAction::UiQAction(UiObject *obj, QString &label, ui_callback f, void *userdata) : QAction(label, NULL) {
this->obj = obj;
this->callback = f;
this->userdata = userdata;
}
-UiAction::~UiAction() {
+UiQAction::~UiQAction() {
// TODO: unbind var
}
-void UiAction::trigger() {
+void UiQAction::trigger() {
if(!callback) {
return;
}
}
// ui_enablefunc for UiAction
-void ui_action_enable(UiAction *action, int enable) {
+void ui_action_enable(UiQAction *action, int enable) {
action->setEnabled((bool)enable);
}
void destroy();
};
-class UiAction;
+class UiQAction;
-typedef void (*ui_prepare_action_event_func)(UiEvent *event, UiAction *action);
+typedef void (*ui_prepare_action_event_func)(UiEvent *event, UiQAction *action);
-class UiAction : public QAction {
+class UiQAction : public QAction {
Q_OBJECT
UiObject *obj;
int customvalue1 = 0;
int customvalue2 = 0;
- UiAction(UiObject *obj, QString &label, ui_callback f, void *userdata);
- ~UiAction();
+ UiQAction(UiObject *obj, QString &label, ui_callback f, void *userdata);
+ ~UiQAction();
private slots:
void trigger();
};
-void ui_action_enable(UiAction *action, int enable);
+void ui_action_enable(UiQAction *action, int enable);
#endif /* TOOLKIT_H */
static UiObject* create_window(const char *title, bool simple, bool sidebar = false) {
UiObject *obj = uic_object_new_toplevel();
- obj->next = NULL;
QMainWindow *window = new QMainWindow();
window->setWindowTitle(title);
const char *tooltip;
UiLabelType labeltype;
ui_callback onclick;
- void *onclickdata;
+ void *onclickdata;
+ const char *action;
const int *states;
+ const int *visibility_states;
} UiButtonArgs;
typedef struct UiToggleArgs {
const char *name;
const char *style_class;
- const char *label;
- const char *icon;
- const char *tooltip;
+ const char *label;
+ const char *icon;
+ const char *tooltip;
UiLabelType labeltype;
- UiInteger *value;
- const char *varname;
+ UiInteger *value;
+ const char *varname;
ui_callback onchange;
- void *onchangedata;
- int enable_state;
+ void *onchangedata;
+ const char *action;
+ int enable_state;
- const int *states;
+ const int *states;
+ const int *visibility_states;
} UiToggleArgs;
+typedef struct UiContentToggleArgs {
+ UiBool fill;
+ UiBool hexpand;
+ UiBool vexpand;
+ UiBool hfill;
+ UiBool vfill;
+ UiBool override_defaults;
+ int margin;
+ int margin_left;
+ int margin_right;
+ int margin_top;
+ int margin_bottom;
+ int colspan;
+ int rowspan;
+ const char *name;
+ const char *style_class;
+
+ const char *label0;
+ const char *icon0;
+ const char *tooltip0;
+ const char *label1;
+ const char *icon1;
+ const char *tooltip1;
+ UiLabelType labeltype;
+ UiInteger *value;
+ const char *varname;
+ ui_callback onchange;
+ void *onchangedata;
+ const char *action;
+ UiBool istogglebutton;
+ int enable_state;
+ int toggled_by_state;
+
+ const int *states;
+ const int *visibility_states;
+} UiContentToggleArgs;
+
typedef struct UiLinkButtonArgs {
UiBool fill;
UiBool hexpand;
const char *varname;
ui_callback onclick;
void *onclickdata;
+ const char *action;
UiBool nofollow;
UiLinkType type;
const int *states;
+ const int *visibility_states;
} UiLinkButtonArgs;
#define ui_button(obj, ...) ui_button_create(obj, &(UiButtonArgs){ __VA_ARGS__ } )
#define ui_togglebutton(obj, ...) ui_togglebutton_create(obj, &(UiToggleArgs){ __VA_ARGS__ } )
#define ui_checkbox(obj, ...) ui_checkbox_create(obj, &(UiToggleArgs){ __VA_ARGS__ } )
#define ui_switch(obj, ...) ui_switch_create(obj, &(UiToggleArgs){ __VA_ARGS__ } )
+#define ui_content_togglebutton(obj, ...) ui_content_togglebutton_create(obj, &(UiContentToggleArgs){ __VA_ARGS__ } )
#define ui_radiobutton(obj, ...) ui_radiobutton_create(obj, &(UiToggleArgs){ __VA_ARGS__ } )
#define ui_linkbutton(obj, ...) ui_linkbutton_create(obj, &(UiLinkButtonArgs){ __VA_ARGS__ })
UIEXPORT UIWIDGET ui_togglebutton_create(UiObject *obj, UiToggleArgs *args);
UIEXPORT UIWIDGET ui_checkbox_create(UiObject *obj, UiToggleArgs *args);
UIEXPORT UIWIDGET ui_switch_create(UiObject *obj, UiToggleArgs *args);
+UIEXPORT UIWIDGET ui_content_togglebutton_create(UiObject *obj, UiContentToggleArgs *args);
UIEXPORT UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs *args);
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);
UiBool def_vfill;
UiBool def_hexpand;
UiBool def_vexpand;
+
+ const int *visibility_states;
} UiContainerArgs;
typedef struct UiFrameArgs {
const char* label;
UiBool isexpanded;
+
+ const int *visibility_states;
} UiFrameArgs;
typedef struct UiTabViewArgs {
int spacing;
int columnspacing;
int rowspacing;
+
+ const int *visibility_states;
} UiTabViewArgs;
typedef struct UiHeaderbarArgs {
UiInteger *value;
const char* varname;
int max_panes;
+
+ const int *visibility_states;
} UiSplitPaneArgs;
typedef struct UiItemListContainerArgs {
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 */
UiLabelStyle style;
UiString* value;
const char* varname;
+
+ const int *visibility_states;
} UiLabelArgs;
typedef struct UiProgressbarArgs {
double max;
UiDouble* value;
const char* varname;
+
+ const int *visibility_states;
} UiProgressbarArgs;
typedef struct UiProgressbarSpinnerArgs {
UiInteger* value;
const char* varname;
+
+ const int *visibility_states;
} UiProgressbarSpinnerArgs;
/* label widgets */
void* onchangedata;
const int *states;
+ const int *visibility_states;;
} UiSpinBoxArgs;
#ifdef UI_GTK
#define UI_ICON_HOME "go-home"
-#define UI_ICON_NEW_WINDOW "list-add"
-#define UI_ICON_REFRESH "view-refresh"
+#define UI_ICON_NEW_WINDOW "window-new"
+#define UI_ICON_NEW_TAB "tab-new"
#define UI_ICON_NEW_FOLDER "folder-new"
-#define UI_ICON_ADD "document-new"
+#define UI_ICON_NEW_DOCUMENT "document-new"
+#define UI_ICON_NEW_APPOINTMENT "appointment-new"
+#define UI_ICON_NEW_CHAT_MESSAGE "chat-message-new"
+#define UI_ICON_NEW_CONTACT "contact-new"
+#define UI_ICON_NEW_MAIL "mail-message-new"
+#define UI_ICON_ADD_BOOKMARK "bookmark-new"
+#define UI_ICON_ADD_IMAGE "insert-image"
+#define UI_ICON_ADD_LINK "insert-link"
+#define UI_ICON_ADD_TEXT "insert-text"
+#define UI_ICON_ADD "list-add"
+#define UI_ICON_REMOVE "list-remove"
+#define UI_ICON_REFRESH "view-refresh"
#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_EDIT_COPY "edit-copy"
+#define UI_ICON_EDIT_CUT "edit-cut"
+#define UI_ICON_EDIT_DELETE "edit-delete"
+#define UI_ICON_EDIT_PASTE "edit-paste"
+#define UI_ICON_UNDO "edit-undo"
+#define UI_ICON_REDO "edit-redo"
+#define UI_ICON_SIDEBAR_LEFT "sidebar-show"
+#define UI_ICON_SIDEBAR_RIGHT "sidebar-show-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"
+#define UI_ICON_VIEW_LIST "view-list"
+#define UI_ICON_VIEW_GRID "view-grid"
+#define UI_ICON_VIEW_DUAL "view-dual"
+#define UI_ICON_VIEW_FULLSCREEN "view-fullscreen"
+#define UI_ICON_VIEW_RESTORE "view-restore"
+#define UI_ICON_TEXT_BOLD "format-text-bold"
+#define UI_ICON_TEXT_ITALIC "format-text-italic"
+#define UI_ICON_TEXT_UNDERLINE "format-text-underline"
+#define UI_ICON_LIST_BULLET "view-list-bullet"
+#define UI_ICON_LIST_ORDERED "view-list-ordered"
+#define UI_ICON_LIST_CHECK "checkbox-checked"
+#define UI_ICON_CHECKBOX "checkbox-checked"
+#define UI_ICON_STAR "starred"
+#define UI_ICON_VIEW_REVEAL "view-reveal"
+#define UI_ICON_VIEW_CONCEAL "view-conceal"
+#define UI_ICON_SETTINGS "applications-system"
+#define UI_ICON_MEDIA_PLAY "media-playback-start"
+#define UI_ICON_MEDIA_STOP "media-playback-stop"
+#define UI_ICON_MEDIA_PAUSE "media-playback-pause"
+#define UI_ICON_MEDIA_SEEK_BACKWARD "media-seek-backward"
+#define UI_ICON_MEDIA_SEEK_FORWARD "media-seek-forward"
+#define UI_ICON_MEDIA_SKIP_BACKWARD "media-skip-backward"
+#define UI_ICON_MEDIA_SKIP_FORWARD "media-skip-forward"
+#define UI_ICON_CALL_START "call-start"
+#define UI_ICON_CALL_STOP "call-stop"
+#define UI_ICON_CALL_INCOMING "call-incoming"
+#define UI_ICON_CALL_OUTGOING "call-outgoing"
+#define UI_ICON_MICROPHONE_ON "microphone-sensitivity-high"
+#define UI_ICON_MICROPHONE_OFF "microphone-disabled"
+#define UI_ICON_LOCKED "changes-allow"
+#define UI_ICON_UNLOCKED "changes-prevent"
+#define UI_ICON_SECURE "channel-secure"
+#define UI_ICON_INSECURE "channel-insecure"
+
#endif /* UI_GTK */
+#ifdef UI_QT
+
+#define UI_ICON_HOME "go-home"
+#define UI_ICON_NEW_WINDOW "window-new"
+#define UI_ICON_NEW_TAB "tab-new"
+#define UI_ICON_NEW_FOLDER "folder-new"
+#define UI_ICON_NEW_DOCUMENT "document-new"
+#define UI_ICON_NEW_APPOINTMENT "appointment-new"
+#define UI_ICON_NEW_CHAT_MESSAGE "chat-message-new"
+#define UI_ICON_NEW_CONTACT "contact-new"
+#define UI_ICON_NEW_MAIL "mail-message-new"
+#define UI_ICON_ADD_BOOKMARK "bookmark-new"
+#define UI_ICON_ADD_IMAGE "insert-image"
+#define UI_ICON_ADD_LINK "insert-link"
+#define UI_ICON_ADD_TEXT "insert-text"
+#define UI_ICON_ADD "list-add"
+#define UI_ICON_REMOVE "list-remove"
+#define UI_ICON_REFRESH "view-refresh"
+#define UI_ICON_UPLOAD "document-open"
+#define UI_ICON_SAVE_LOCAL "document-save-as"
+#define UI_ICON_EDIT_COPY "edit-copy"
+#define UI_ICON_EDIT_CUT "edit-cut"
+#define UI_ICON_EDIT_DELETE "edit-delete"
+#define UI_ICON_EDIT_PASTE "edit-paste"
+#define UI_ICON_UNDO "edit-undo"
+#define UI_ICON_REDO "edit-redo"
+#define UI_ICON_SIDEBAR_LEFT "sidebar-show"
+#define UI_ICON_SIDEBAR_RIGHT "sidebar-show-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"
+#define UI_ICON_VIEW_LIST "view-list"
+#define UI_ICON_VIEW_GRID "view-grid"
+#define UI_ICON_VIEW_DUAL "view-dual"
+#define UI_ICON_VIEW_FULLSCREEN "view-fullscreen"
+#define UI_ICON_VIEW_RESTORE "view-restore"
+#define UI_ICON_TEXT_BOLD "format-text-bold"
+#define UI_ICON_TEXT_ITALIC "format-text-italic"
+#define UI_ICON_TEXT_UNDERLINE "format-text-underline"
+#define UI_ICON_LIST_BULLET "view-list-bullet"
+#define UI_ICON_LIST_ORDERED "view-list-ordered"
+#define UI_ICON_LIST_CHECK "checkbox-checked"
+#define UI_ICON_CHECKBOX "checkbox-checked"
+#define UI_ICON_STAR "starred"
+#define UI_ICON_VIEW_REVEAL "view-reveal"
+#define UI_ICON_VIEW_CONCEAL "view-conceal"
+#define UI_ICON_SETTINGS "applications-system"
+#define UI_ICON_MEDIA_PLAY "media-playback-start"
+#define UI_ICON_MEDIA_STOP "media-playback-stop"
+#define UI_ICON_MEDIA_PAUSE "media-playback-pause"
+#define UI_ICON_MEDIA_SEEK_BACKWARD "media-seek-backward"
+#define UI_ICON_MEDIA_SEEK_FORWARD "media-seek-forward"
+#define UI_ICON_MEDIA_SKIP_BACKWARD "media-skip-backward"
+#define UI_ICON_MEDIA_SKIP_FORWARD "media-skip-forward"
+#define UI_ICON_CALL_START "call-start"
+#define UI_ICON_CALL_STOP "call-stop"
+#define UI_ICON_CALL_INCOMING "call-incoming"
+#define UI_ICON_CALL_OUTGOING "call-outgoing"
+#define UI_ICON_MICROPHONE_ON "microphone-sensitivity-high"
+#define UI_ICON_MICROPHONE_OFF "microphone-disabled"
+#define UI_ICON_LOCKED "changes-allow"
+#define UI_ICON_UNLOCKED "changes-prevent"
+#define UI_ICON_SECURE "channel-secure"
+#define UI_ICON_INSECURE "channel-insecure"
+#endif /* UI_QT */
#ifdef UI_WINUI
#define UI_ICON_GO_FORWARD "Forward"
#define UI_ICON_GO_UP "Up"
#define UI_ICON_GO_DOWN "" // TODO: implement workaround for missing down symbol
+#define UI_ICON_LIST "List"
#endif /* UI_WINUI */
+
+#ifdef UI_COCOA
+
+#define UI_ICON_HOME "go-home"
+#define UI_ICON_NEW_WINDOW "macwindow.badge.plus"
+#define UI_ICON_NEW_TAB "plus.square"
+#define UI_ICON_NEW_FOLDER "folder.badge.plus"
+#define UI_ICON_NEW_DOCUMENT "document.badge.plus"
+#define UI_ICON_NEW_APPOINTMENT "calendar.badge.plus"
+#define UI_ICON_NEW_CHAT_MESSAGE "plus.bubble"
+#define UI_ICON_NEW_CONTACT "person.badge.plus"
+#define UI_ICON_NEW_MAIL "envelope.badge.plus"
+#define UI_ICON_ADD_BOOKMARK "book.badge.plus"
+#define UI_ICON_ADD_IMAGE "photo.badge.plus"
+#define UI_ICON_ADD_LINK "link.badge.plus"
+#define UI_ICON_ADD_TEXT "text.badge.plus"
+#define UI_ICON_ADD "plus"
+#define UI_ICON_REMOVE "minus"
+#define UI_ICON_REFRESH "arrow.clockwise"
+#define UI_ICON_UPLOAD "square.and.arrow.up"
+#define UI_ICON_SAVE_LOCAL "square.and.arrow.down"
+#define UI_ICON_EDIT_COPY "document.on.document"
+#define UI_ICON_EDIT_CUT "scissors"
+#define UI_ICON_EDIT_DELETE "minus.circle"
+#define UI_ICON_EDIT_PASTE "document.on.clipboard"
+#define UI_ICON_UNDO "arrow.uturn.backward"
+#define UI_ICON_REDO "arrow.uturn.forward"
+#define UI_ICON_SIDEBAR_LEFT "sidebar.left"
+#define UI_ICON_SIDEBAR_RIGHT "sidebar.right"
+#define UI_ICON_GO_BACK "chevron.left"
+#define UI_ICON_GO_FORWARD "chevron.right"
+#define UI_ICON_GO_UP "chevron.up"
+#define UI_ICON_GO_DOWN "chevron.down"
+#define UI_ICON_VIEW_LIST "list.bullet"
+#define UI_ICON_VIEW_GRID "square.grid.2x2"
+#define UI_ICON_VIEW_DUAL "rectangle.split.2x1"
+#define UI_ICON_VIEW_FULLSCREEN "arrow.up.left.and.arrow.down.right.rectangle"
+#define UI_ICON_VIEW_RESTORE "arrow.down.forward.and.arrow.up.backward.rectangle"
+#define UI_ICON_TEXT_BOLD "bold"
+#define UI_ICON_TEXT_ITALIC "italic"
+#define UI_ICON_TEXT_UNDERLINE "underline"
+#define UI_ICON_LIST_BULLET "list.bullet"
+#define UI_ICON_LIST_ORDERED "list.number"
+#define UI_ICON_LIST_CHECK "checklist"
+#define UI_ICON_CHECKBOX "checkmark.square"
+#define UI_ICON_STAR "star"
+#define UI_ICON_VIEW_REVEAL "eye"
+#define UI_ICON_VIEW_CONCEAL "eye.slash"
+#define UI_ICON_SETTINGS "gearshape"
+#define UI_ICON_MEDIA_PLAY "play.fill"
+#define UI_ICON_MEDIA_STOP "stop.fill"
+#define UI_ICON_MEDIA_PAUSE "pause.fill"
+#define UI_ICON_MEDIA_SEEK_BACKWARD "backward.fill"
+#define UI_ICON_MEDIA_SEEK_FORWARD "forward.fill"
+#define UI_ICON_MEDIA_SKIP_BACKWARD "backward.end.fill"
+#define UI_ICON_MEDIA_SKIP_FORWARD "forward.end.fill"
+#define UI_ICON_CALL_START "phone"
+#define UI_ICON_CALL_STOP "phone.down"
+#define UI_ICON_CALL_INCOMING "phone.arrow.down.left"
+#define UI_ICON_CALL_OUTGOING "phone.arrow.up.right"
+#define UI_ICON_MICROPHONE_ON "microphone"
+#define UI_ICON_MICROPHONE_OFF "microphone.slash"
+#define UI_ICON_LOCKED "lock"
+#define UI_ICON_UNLOCKED "lock.open"
+#define UI_ICON_SECURE "lock"
+#define UI_ICON_INSECURE "lock.trianglebadge.exclamationmark"
+
+#endif /* UI_COCOA */
+
+#ifdef UI_MOTIF
+
+#define UI_ICON_HOME ""
+#define UI_ICON_NEW_WINDOW ""
+#define UI_ICON_NEW_TAB ""
+#define UI_ICON_NEW_FOLDER ""
+#define UI_ICON_NEW_DOCUMENT ""
+#define UI_ICON_NEW_APPOINTMENT ""
+#define UI_ICON_NEW_CHAT_MESSAGE ""
+#define UI_ICON_NEW_CONTACT ""
+#define UI_ICON_NEW_MAIL ""
+#define UI_ICON_ADD_BOOKMARK ""
+#define UI_ICON_ADD_IMAGE ""
+#define UI_ICON_ADD_LINK ""
+#define UI_ICON_ADD_TEXT ""
+#define UI_ICON_ADD ""
+#define UI_ICON_REMOVE ""
+#define UI_ICON_REFRESH ""
+#define UI_ICON_UPLOAD ""
+#define UI_ICON_SAVE_LOCAL ""
+#define UI_ICON_EDIT_COPY ""
+#define UI_ICON_EDIT_CUT ""
+#define UI_ICON_EDIT_DELETE ""
+#define UI_ICON_EDIT_PASTE ""
+#define UI_ICON_UNDO ""
+#define UI_ICON_REDO ""
+#define UI_ICON_SIDEBAR_LEFT ""
+#define UI_ICON_SIDEBAR_RIGHT ""
+#define UI_ICON_GO_BACK ""
+#define UI_ICON_GO_FORWARD ""
+#define UI_ICON_GO_UP ""
+#define UI_ICON_GO_DOWN ""
+#define UI_ICON_VIEW_LIST ""
+#define UI_ICON_VIEW_GRID ""
+#define UI_ICON_VIEW_DUAL ""
+#define UI_ICON_VIEW_FULLSCREEN ""
+#define UI_ICON_VIEW_RESTORE ""
+#define UI_ICON_TEXT_BOLD ""
+#define UI_ICON_TEXT_ITALIC ""
+#define UI_ICON_TEXT_UNDERLINE ""
+#define UI_ICON_LIST_BULLET ""
+#define UI_ICON_LIST_ORDERED ""
+#define UI_ICON_LIST_CHECK ""
+#define UI_ICON_CHECKBOX ""
+#define UI_ICON_STAR ""
+#define UI_ICON_VIEW_REVEAL ""
+#define UI_ICON_VIEW_CONCEAL ""
+#define UI_ICON_SETTINGS ""
+#define UI_ICON_MEDIA_PLAY ""
+#define UI_ICON_MEDIA_STOP ""
+#define UI_ICON_MEDIA_PAUSE ""
+#define UI_ICON_MEDIA_SEEK_BACKWARD ""
+#define UI_ICON_MEDIA_SEEK_FORWARD ""
+#define UI_ICON_MEDIA_SKIP_BACKWARD ""
+#define UI_ICON_MEDIA_SKIP_FORWARD ""
+#define UI_ICON_CALL_START ""
+#define UI_ICON_CALL_STOP ""
+#define UI_ICON_CALL_INCOMING ""
+#define UI_ICON_CALL_OUTGOING ""
+#define UI_ICON_MICROPHONE_ON ""
+#define UI_ICON_MICROPHONE_OFF ""
+#define UI_ICON_LOCKED ""
+#define UI_ICON_UNLOCKED ""
+#define UI_ICON_SECURE ""
+#define UI_ICON_INSECURE ""
+#endif /* UI_MOTIF */
+
+#ifdef UI_WIN32
+
+#define UI_ICON_HOME ""
+#define UI_ICON_NEW_WINDOW ""
+#define UI_ICON_NEW_TAB ""
+#define UI_ICON_NEW_FOLDER ""
+#define UI_ICON_NEW_DOCUMENT ""
+#define UI_ICON_NEW_APPOINTMENT ""
+#define UI_ICON_NEW_CHAT_MESSAGE ""
+#define UI_ICON_NEW_CONTACT ""
+#define UI_ICON_NEW_MAIL ""
+#define UI_ICON_ADD_BOOKMARK ""
+#define UI_ICON_ADD_IMAGE ""
+#define UI_ICON_ADD_LINK ""
+#define UI_ICON_ADD_TEXT ""
+#define UI_ICON_ADD ""
+#define UI_ICON_REMOVE ""
+#define UI_ICON_REFRESH ""
+#define UI_ICON_UPLOAD ""
+#define UI_ICON_SAVE_LOCAL ""
+#define UI_ICON_EDIT_COPY ""
+#define UI_ICON_EDIT_CUT ""
+#define UI_ICON_EDIT_DELETE ""
+#define UI_ICON_EDIT_PASTE ""
+#define UI_ICON_UNDO ""
+#define UI_ICON_REDO ""
+#define UI_ICON_SIDEBAR_LEFT ""
+#define UI_ICON_SIDEBAR_RIGHT ""
+#define UI_ICON_GO_BACK ""
+#define UI_ICON_GO_FORWARD ""
+#define UI_ICON_GO_UP ""
+#define UI_ICON_GO_DOWN ""
+#define UI_ICON_VIEW_LIST ""
+#define UI_ICON_VIEW_GRID ""
+#define UI_ICON_VIEW_DUAL ""
+#define UI_ICON_VIEW_FULLSCREEN ""
+#define UI_ICON_VIEW_RESTORE ""
+#define UI_ICON_TEXT_BOLD ""
+#define UI_ICON_TEXT_ITALIC ""
+#define UI_ICON_TEXT_UNDERLINE ""
+#define UI_ICON_LIST_BULLET ""
+#define UI_ICON_LIST_ORDERED ""
+#define UI_ICON_LIST_CHECK ""
+#define UI_ICON_CHECKBOX ""
+#define UI_ICON_STAR ""
+#define UI_ICON_VIEW_REVEAL ""
+#define UI_ICON_VIEW_CONCEAL ""
+#define UI_ICON_SETTINGS ""
+#define UI_ICON_MEDIA_PLAY ""
+#define UI_ICON_MEDIA_STOP ""
+#define UI_ICON_MEDIA_PAUSE ""
+#define UI_ICON_MEDIA_SEEK_BACKWARD ""
+#define UI_ICON_MEDIA_SEEK_FORWARD ""
+#define UI_ICON_MEDIA_SKIP_BACKWARD ""
+#define UI_ICON_MEDIA_SKIP_FORWARD ""
+#define UI_ICON_CALL_START ""
+#define UI_ICON_CALL_STOP ""
+#define UI_ICON_CALL_INCOMING ""
+#define UI_ICON_CALL_OUTGOING ""
+#define UI_ICON_MICROPHONE_ON ""
+#define UI_ICON_MICROPHONE_OFF ""
+#define UI_ICON_LOCKED ""
+#define UI_ICON_UNLOCKED ""
+#define UI_ICON_SECURE ""
+#define UI_ICON_INSECURE ""
+
+#endif /* UI_MOTIF */
+
+
+enum UiIconId {
+ UI_ICON_ID_HOME,
+ UI_ICON_ID_NEW_WINDOW,
+ UI_ICON_ID_NEW_TAB,
+ UI_ICON_ID_NEW_FOLDER,
+ UI_ICON_ID_NEW_DOCUMENT,
+ UI_ICON_ID_NEW_APPOINTMENT,
+ UI_ICON_ID_NEW_CHAT_MESSAGE,
+ UI_ICON_ID_NEW_CONTACT,
+ UI_ICON_ID_NEW_MAIL,
+ UI_ICON_ID_ADD_BOOKMARK,
+ UI_ICON_ID_ADD_IMAGE,
+ UI_ICON_ID_ADD_LINK,
+ UI_ICON_ID_ADD_TEXT,
+ UI_ICON_ID_ADD,
+ UI_ICON_ID_REMOVE,
+ UI_ICON_ID_REFRESH,
+ UI_ICON_ID_UPLOAD,
+ UI_ICON_ID_SAVE_LOCAL,
+ UI_ICON_ID_EDIT_COPY,
+ UI_ICON_ID_EDIT_CUT,
+ UI_ICON_ID_EDIT_DELETE,
+ UI_ICON_ID_EDIT_PASTE,
+ UI_ICON_ID_UNDO,
+ UI_ICON_ID_REDO,
+ UI_ICON_ID_SIDEBAR_LEFT,
+ UI_ICON_ID_SIDEBAR_RIGHT,
+ UI_ICON_ID_GO_BACK,
+ UI_ICON_ID_GO_FORWARD,
+ UI_ICON_ID_GO_UP,
+ UI_ICON_ID_GO_DOWN,
+ UI_ICON_ID_VIEW_LIST,
+ UI_ICON_ID_VIEW_GRID,
+ UI_ICON_ID_VIEW_DUAL,
+ UI_ICON_ID_VIEW_FULLSCREEN,
+ UI_ICON_ID_VIEW_RESTORE,
+ UI_ICON_ID_TEXT_BOLD,
+ UI_ICON_ID_TEXT_ITALIC,
+ UI_ICON_ID_TEXT_UNDERLINE,
+ UI_ICON_ID_LIST_BULLET,
+ UI_ICON_ID_LIST_ORDERED,
+ UI_ICON_ID_LIST_CHECK,
+ UI_ICON_ID_CHECKBOX,
+ UI_ICON_ID_STAR,
+ UI_ICON_ID_VIEW_REVEAL,
+ UI_ICON_ID_VIEW_CONCEAL,
+ UI_ICON_ID_SETTINGS,
+ UI_ICON_ID_MEDIA_PLAY,
+ UI_ICON_ID_MEDIA_STOP,
+ UI_ICON_ID_MEDIA_PAUSE,
+ UI_ICON_ID_MEDIA_SEEK_BACKWARD,
+ UI_ICON_ID_MEDIA_SEEK_FORWARD,
+ UI_ICON_ID_MEDIA_SKIP_BACKWARD,
+ UI_ICON_ID_MEDIA_SKIP_FORWARD,
+ UI_ICON_ID_CALL_START,
+ UI_ICON_ID_CALL_STOP,
+ UI_ICON_ID_CALL_INCOMING,
+ UI_ICON_ID_CALL_OUTGOING,
+ UI_ICON_ID_MICROPHONE_ON,
+ UI_ICON_ID_MICROPHONE_OFF,
+ UI_ICON_ID_LOCKED,
+ UI_ICON_ID_UNLOCKED,
+ UI_ICON_ID_SECURE,
+ UI_ICON_ID_INSECURE
+};
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
void *getstyledata;
ui_callback onactivate;
void *onactivatedata;
+ const char *onactivate_action;
ui_callback onselection;
void *onselectiondata;
+ const char *onselection_action;
ui_callback ondragstart;
void *ondragstartdata;
+ const char *ondragstart_action;
ui_callback ondragcomplete;
void *ondragcompletedata;
+ const char *ondragcomplete_action;
ui_callback ondrop;
void *ondropdata;
+ const char *ondrop_action;
UiBool multiselection;
+ UiBool hide_header;
UiMenuBuilder *contextmenu;
ui_list_savefunc onsave;
void *onsavedata;
const int *states;
+ const int *visibility_states;
};
typedef void (*ui_sublist_getvalue_func)(UiList *list, void *sublist_userdata, void *rowdata, int index, UiSubListItem *item, void *userdata);
void *onbuttonclickdata;
UiMenuBuilder *contextmenu;
+
+ const int *visibility_states;;
};
#define UI_SUBLIST(...) (UiSubList){ __VA_ARGS__ }
typedef struct UiMenuItemArgs {
- const char* label;
- const char* icon;
-
+ const char *label;
+ const char *icon;
+
ui_callback onclick;
- void* onclickdata;
+ void *onclickdata;
+ const char *action;
+ const char *accelerator;
+ const char *accelerator_text;
- const int* states;
+ const int *states;
} UiMenuItemArgs;
typedef struct UiMenuToggleItemArgs {
- const char* label;
- const char* icon;
+ const char *label;
+ const char *icon;
- const char* varname;
+ const char *varname;
ui_callback onchange;
- void* onchangedata;
+ void *onchangedata;
+ const char *action;
+ const char *accelerator;
+ const char *accelerator_text;
- const int* nstates;
+ const int *nstates;
} UiMenuToggleItemArgs;
typedef struct UiMenuItemListArgs {
- const char* varname;
+ const char *varname;
ui_getvaluefunc getvalue;
+ ui_getvaluefunc2 getvalue2;
+ void *getvaluedata;
ui_callback onselect;
- void* onselectdata;
+ void *onselectdata;
+ const char *action;
UiBool addseparator;
} UiMenuItemListArgs;
const char *varname;
ui_callback onchange;
void *onchangedata;
+ const char *onchange_action;
+ ui_callback ontextchanged;
+ void *ontextchangeddata;
+ const char *ontextchanged_action;
const int *states;
+ const int *visibility_states;
} UiTextAreaArgs;
+
+typedef enum UiTextChangedEventType {
+ UI_TEXT_INSERT = 0,
+ UI_TEXT_DELETE
+} UiTextChangedEventType;
+
+typedef struct UiTextChangeEventData {
+ UiTextChangedEventType type;
+ int begin;
+ int end;
+ const char *text;
+ int length;
+} UiTextChangeEventData;
typedef struct UiTextFieldArgs {
UiBool fill;
void *onchangedata;
ui_callback onactivate;
void *onactivatedata;
+ const char *onactivate_action;
+ const char *onchange_action;
const int *states;
+ const int *visibility_states;
} UiTextFieldArgs;
typedef struct UiPathElmRet {
ui_callback onactivate;
void *onactivatedata;
+ const char *action;
ui_callback ondragstart;
void *ondragstartdata;
void *ondragcompletedata;
ui_callback ondrop;
void *ondropsdata;
+
+ const int *visibility_states;
} UiPathTextFieldArgs;
#define ui_textarea(obj, ...) ui_textarea_create(obj, &(UiTextAreaArgs) { __VA_ARGS__ })
UIEXPORT void ui_text_undo(UiText *value);
UIEXPORT void ui_text_redo(UiText *value);
+UIEXPORT void ui_textarea_focus(UIWIDGET textarea);
+UIEXPORT void ui_textarea_set_selection(UIWIDGET textarea, int begin, int end);
+UIEXPORT void ui_textarea_select_all(UIWIDGET textarea);
+UIEXPORT void ui_textarea_set_editable(UIWIDGET textarea, UiBool editable);
+UIEXPORT UiBool ui_textarea_is_editable(UIWIDGET textarea);
+UIEXPORT void ui_textarea_set_position(UIWIDGET textarea, int pos);
+UIEXPORT int ui_textarea_get_position(UIWIDGET textarea);
+UIEXPORT void ui_textarea_scroll_to(UIWIDGET textarea, int pos);
+
#define ui_textfield(obj, ...) ui_textfield_create(obj, &(UiTextFieldArgs) { __VA_ARGS__ })
#define ui_frameless_textfield(obj, ...) ui_frameless_field_create(obj, &(UiTextFieldArgs) { __VA_ARGS__ })
#define ui_passwordfield(obj, ...) ui_passwordfield_create(obj, &(UiTextFieldArgs) { __VA_ARGS__ })
UIEXPORT UIWIDGET ui_passwordfield_create(UiObject* obj, UiTextFieldArgs *args);
UIEXPORT UIWIDGET ui_path_textfield_create(UiObject* obj, UiPathTextFieldArgs *args);
+
+UIEXPORT void ui_textfield_focus(UIWIDGET textfield);
+UIEXPORT void ui_textfield_focus_without_selecting(UIWIDGET textfield);
+UIEXPORT void ui_textfield_set_selection(UIWIDGET textfield, int begin, int end);
+UIEXPORT void ui_textfield_select_all(UIWIDGET textfield);
+UIEXPORT void ui_textfield_set_editable(UIWIDGET textfield, UiBool editable);
+UIEXPORT UiBool ui_textfield_is_editable(UIWIDGET textfield);
+UIEXPORT void ui_textfield_set_position(UIWIDGET textfield, int pos);
+UIEXPORT int ui_textfield_get_position(UIWIDGET textfield);
#ifdef __cplusplus
}
const char *tooltip;
ui_callback onclick;
- void* onclickdata;
+ void *onclickdata;
+ const char *action;
+ const char *accelerator;
+ const char *accelerator_text;
const int *states;
const int *visibility_states;
const char *varname;
ui_callback onchange;
void *onchangedata;
+ const char *action;
+ const char *accelerator;
+ const char *accelerator_text;
const int *states;
const int *visibility_states;
} UiToolbarToggleItemArgs;
+typedef struct UiToolbarContentToggleItemArgs {
+ const char *label0;
+ const char *icon0;
+ const char *tooltip0;
+ const char *label1;
+ const char *icon1;
+ const char *tooltip1;
+
+ const char *varname;
+ ui_callback onchange;
+ void *onchangedata;
+ const char *action;
+ const char *accelerator;
+ const char *accelerator_text;
+
+ int toggled_by_state;
+ UiBool istogglebutton;
+
+ const int *states;
+ const int *visibility_states;
+} UiToolbarContentToggleItemArgs;
+
typedef struct UiToolbarMenuArgs {
const char *label;
const char *icon;
#define ui_toolbar_item(name, ...) ui_toolbar_item_create(name, &(UiToolbarItemArgs){ __VA_ARGS__ } )
#define ui_toolbar_toggleitem(name, ...) ui_toolbar_toggleitem_create(name, &(UiToolbarToggleItemArgs){ __VA_ARGS__ } )
+#define ui_toolbar_content_toggleitem(name, ...) ui_toolbar_toggleitem_create(name, &(UiToolbarToggleItemArgs){ __VA_ARGS__ } )
#define ui_toolbar_menu(name, ...) for(ui_toolbar_menu_create(name, &(UiToolbarMenuArgs){ __VA_ARGS__ });ui_menu_is_open();ui_menu_close())
#define ui_toolbar_appmenu() for(ui_toolbar_menu_create(NULL, &(UiToolbarMenuArgs){ 0 });ui_menu_is_open();ui_menu_close())
UIEXPORT void ui_toolbar_item_create(const char* name, UiToolbarItemArgs *args);
UIEXPORT void ui_toolbar_toggleitem_create(const char* name, UiToolbarToggleItemArgs *args);
+UIEXPORT void ui_toolbar_content_toggleitem_create(const char* name, UiToolbarContentToggleItemArgs *args);
UIEXPORT void ui_toolbar_menu_create(const char* name, UiToolbarMenuArgs *args);
UIEXPORT void ui_toolbar_add_default(const char *name, enum UiToolbarPos pos);
#include <gtk/gtk.h>
#define UIWIDGET GtkWidget*
+#define UIWINDOW void*
#if UI_GTK2 || UI_GTK3
#define UIMENU GtkMenu*
#include <Xm/XmAll.h>
#define UIWIDGET Widget
+#define UIWINDOW void*
#define UIMENU Widget
#define UIWINDOW UiWidget*
#define UIMENU void*
+#else
+
+#define UI_GENERIC
+#define UIWIDGET void*
+#define UIWINDOW void*
+#define UIMENU void*
+
#endif
#ifndef TRUE
extern "C" {
#endif
-#define UI_GROUP_SELECTION 20000
+#define UI_STATE_SELECTION 20000
-#define UI_GROUPS(...) (const int[]){ __VA_ARGS__, -1 }
+#define UI_STATES(...) (const int[]){ __VA_ARGS__, -1 }
/* public types */
#ifndef __cplusplus
#endif
typedef struct UiObject UiObject;
-typedef struct UiContainerX UiContainerX;
typedef struct UiEvent UiEvent;
typedef struct UiMouseEvent UiMouseEvent;
typedef struct UiObserver UiObserver;
typedef struct UiTextStyle UiTextStyle;
typedef struct UiColor UiColor;
+typedef enum UiEventType UiEventType;
+
/* begin opaque types */
typedef struct UiContext UiContext;
typedef struct UiContainer UiContainer;
typedef struct UiThreadpool UiThreadpool;
/* end opaque types */
-typedef struct UiTabbedPane UiTabbedPane;
-
typedef enum UiTri {
UI_DEFAULT = 0,
UI_ON,
*/
UIWIDGET widget;
-#if defined(UI_COCOA) || defined(UI_WINUI)
/*
* native window object
*/
UIWINDOW wobj;
-#endif
/*
* user window data
/*
* 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
+ * called when someone requests to close the window
*/
- UiObject *next;
+ void (*onclose)(UiEvent *event, void *userdata);
+ void *onclosedata;
/*
* obj destroy func
unsigned int ref;
};
-struct UiTabbedPane {
- /*
- * native widget
- */
- UIWIDGET widget;
-
- /*
- * current document
- */
- void *document;
-
- /*
- * parent context
- */
- UiContext *ctx;
+enum UiEventType {
+ UI_EVENT_DATA_NULL = 0,
+ UI_EVENT_DATA_POINTER,
+ UI_EVENT_DATA_STRING,
+ UI_EVENT_DATA_INTEGER_VALUE,
+ UI_EVENT_DATA_STRING_VALUE,
+ UI_EVENT_DATA_TEXT_VALUE,
+ UI_EVENT_DATA_DOUBLE_VALUE,
+ UI_EVENT_DATA_RANGE_VALUE,
+ UI_EVENT_DATA_TEXT_CHANGED,
+ UI_EVENT_DATA_LIST_SELECTION,
+ UI_EVENT_DATA_LIST_ELM,
+ UI_EVENT_DATA_DND,
+ UI_EVENT_DATA_SUBLIST,
+ UI_EVENT_DATA_FILE_LIST,
+ UI_EVENT_DATA_TYPED_OBJECT
};
struct UiEvent {
- UiObject *obj;
- void *document;
- void *window;
- void *eventdata;
- int eventdatatype;
- int intval;
- int set;
+ UiObject *obj;
+ void *document;
+ void *window;
+ void *eventdata;
+ UiEventType eventdatatype;
+ int intval;
+ int set;
};
struct UiMouseEvent {
void (*set)(UiText*, const char*);
char* (*get)(UiText*);
char* (*getsubstr)(UiText*, int, int); /* text, begin, end */
- void (*insert)(UiText*, int, char*);
+ void (*insert)(UiText*, int, const char*);
+ void (*replace)(UiText*, int, int, const char*);
void (*setposition)(UiText*,int);
int (*position)(UiText*);
+ void (*showposition)(UiText*, int);
void (*setselection)(UiText*, int, int); /* text, begin, end */
void (*selection)(UiText*, int*, int*); /* text, begin, end */
int (*length)(UiText*);
void (*remove)(UiText*, int, int); /* text, begin, end */
+ void (*setreadonly)(UiText*, int);
UiStr value;
int pos;
+ int readonly;
void *obj;
int datatype;
void *data1;
void *data2;
- // TODO: replacefunc, ...
UiObserver *observers;
};
* abstract list
*/
struct UiList {
- /* get the first element */
+ // destructor
+ ui_list_destroy_func destroy;
+ // get the first element
void*(*first)(UiList *list);
- /* get the next element */
+ // get the next element
void*(*next)(UiList *list);
- /* get the nth element */
+ // get the nth element
void*(*get)(UiList *list, int i);
- /* get the number of elements */
+ // get the number of elements
int(*count)(UiList *list);
- /* iterator changes after first() next() and get() */
+ // iterator changes after first() next() and get()
void *iter;
- /* private - implementation dependent */
+ // private - implementation dependent
void *data;
- /* binding functions */
+ // binding functions
void (*update)(UiList *list, int i);
UiListSelection (*getselection)(UiList *list);
void (*setselection)(UiList *list, UiListSelection selection);
- /* binding object */
+ // binding object
void *obj;
+ // saved selection after unbind
+ UiListSelection *saved_selection;
+ // enable selection saving
+ UiBool save_selection;
- /* list of observers */
+ // list of observers
UiObserver *observers;
};
int intdata;
} UiCondVar;
-enum UiEventType {
- UI_EVENT_DATA_NULL = 0,
- UI_EVENT_DATA_POINTER,
- UI_EVENT_DATA_STRING,
- UI_EVENT_DATA_INTEGER_VALUE,
- UI_EVENT_DATA_STRING_VALUE,
- UI_EVENT_DATA_TEXT_VALUE,
- UI_EVENT_DATA_DOUBLE_VALUE,
- UI_EVENT_DATA_RANGE_VALUE,
- UI_EVENT_DATA_LIST_SELECTION,
- UI_EVENT_DATA_LIST_ELM,
- UI_EVENT_DATA_DND,
- UI_EVENT_DATA_SUBLIST,
- UI_EVENT_DATA_FILE_LIST
-};
+// eventdata in case eventdatatype is UI_EVENT_DATA_TYPED_OBJECT
+typedef struct UiTypedObj {
+ void *ptr;
+ uint64_t type;
+} UiTypedObj;
#define UI_COLOR(r, g, b) (UiColor){r, g, b}
struct UiColor {
UIEXPORT void ui_init(const char *appname, int argc, char **argv);
-UIEXPORT const char* ui_appname();
+UIEXPORT const char* ui_appname(void);
UIEXPORT void ui_add_styledata(const char *styledata, int len);
UIEXPORT void ui_context_closefunc(UiContext *ctx, ui_callback fnc, void *udata);
-UIEXPORT void ui_context_destroy(UiContext *ctx);
-
UIEXPORT UiContext* ui_context_parent(UiContext *ctx);
+UIEXPORT UiContext* ui_context_toplevel_parent(UiContext *ctx);
UIEXPORT void ui_object_ref(UiObject *obj);
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);
UIEXPORT void ui_show(UiObject *obj);
UIEXPORT void ui_close(UiObject *obj);
+UIEXPORT UiObject* ui_dummy_object(void);
+
UIEXPORT void ui_job(UiObject *obj, ui_threadfunc tf, void *td, ui_callback f, void *fd);
UIEXPORT void ui_call_mainthread(ui_threadfunc tf, void* td);
+
+UIEXPORT void ui_buffer_mainthread_calls(UiBool enable_buffering);
+UIEXPORT void ui_exec_buffered_mainthread_calls(void);
+UIEXPORT void ui_exec_buffered_mainthread_calls_wait(int timeout);
+
UIEXPORT UiThreadpool* ui_threadpool_create(int nthreads);
UIEXPORT void ui_threadpool_destroy(UiThreadpool* pool);
UIEXPORT void ui_threadpool_job(UiThreadpool* pool, UiObject* obj, ui_threadfunc tf, void* td, ui_callback f, void* fd);
UIEXPORT void* ui_document_new(size_t size);
+UIEXPORT void ui_document_ref(void *doc);
+UIEXPORT void ui_document_unref(void *doc);
UIEXPORT void ui_document_destroy(void *doc);
+UIEXPORT void ui_document_onattach(void *doc, ui_callback cb, void *data);
+UIEXPORT void ui_document_ondetach(void *doc, ui_callback cb, void *data);
+UIEXPORT void ui_document_onattachmentstatuschange(void *doc, ui_callback cb, void *data);
+UIEXPORT void ui_document_onattach_action(void *doc, const char *action);
+UIEXPORT void ui_document_ondetach_action(void *doc, const char *action);
+UIEXPORT void ui_document_onattachmentstatuschange_action(void *doc, const char *action);
-UIEXPORT void* ui_get_subdocument(void *document); // deprecated
+UIEXPORT int ui_document_is_attached(void *doc);
+UIEXPORT int ui_document_is_attached_to_obj(void *doc);
UIEXPORT UiContext* ui_document_context(void *doc);
+UIEXPORT void* ui_context_document(UiContext *ctx);
+UIEXPORT UiObject* ui_context_obj(UiContext *ctx);
UIEXPORT void* ui_context_get_document(UiContext *ctx);
UIEXPORT void ui_context_single_attachment_mode(UiContext *ctx, UiBool enable);
UIEXPORT void ui_widget_set_states2(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, const int *states, int nstates);
UIEXPORT void ui_widget_set_visibility_states(UiContext *ctx, UIWIDGET widget, const int *states, int nstates);
+UIEXPORT void ui_add_action(UiContext *ctx, const char *name, ui_callback callback, void *userdata);
+UIEXPORT void ui_add_action_with_accelerator(
+ UiContext *ctx,
+ const char *name,
+ ui_callback callback,
+ void *userdata,
+ const char *accelerator,
+ const char *accelerator_text);
+UIEXPORT void ui_update_action_bindings(UiContext *ctx);
+UIEXPORT int ui_call_action(UiContext *ctx, const char *action_name);
+UIEXPORT int ui_call_action2(UiContext *ctx, const char *action_name, void *eventdata, int intval);
+UIEXPORT int ui_call_action3(UiContext *ctx, const char *action_name, void *ptr, uint64_t type_id);
+UIEXPORT void ui_broadcast_action(const char *action_name);
+UIEXPORT void ui_broadcast_action2(const char *action_name, void *eventdata, int intval);
+UIEXPORT void ui_broadcast_action3(const char *action_name, void *ptr, uint64_t type_id);
+UIEXPORT void ui_mainthread_broadcast(const char *action_name);
+UIEXPORT void ui_mainthread_broadcast2(const char *action_name, void *eventdata, int intval);
+UIEXPORT void ui_mainthread_broadcast3(const char *action_name, void *ptr, uint64_t type_id);
+UIEXPORT void ui_call_action_on(UiContext *ctx, const char *action);
+
UIEXPORT void ui_set_state(UiContext *ctx, int state);
UIEXPORT void ui_unset_state(UiContext *ctx, int state);
+UIEXPORT void ui_suppress_state(UiContext *ctx, int state);
+UIEXPORT void ui_unsuppress_state(UiContext *ctx, int state);
UIEXPORT int* ui_active_states(UiContext *ctx, int *nstates);
UIEXPORT void* ui_allocator(UiContext *ctx);
UIEXPORT void* ui_realloc(UiContext *ctx, void *ptr, size_t size);
UIEXPORT char* ui_strdup(UiContext *ctx, const char *str);
UIEXPORT void ui_reg_destructor(UiContext *ctx, void *data, ui_destructor_func destr);
+UIEXPORT void ui_remove_destructor(UiContext *ctx, void *data);
UIEXPORT void ui_set_destructor(void *mem, ui_destructor_func destr);
// types
UIEXPORT int ui_list_count(UiList *list);
UIEXPORT void ui_list_append(UiList *list, void *data);
UIEXPORT void ui_list_prepend(UiList *list, void *data);
+UIEXPORT void ui_list_insert(UiList *list, int index, void *data);
UIEXPORT void ui_list_remove(UiList *list, int i);
UIEXPORT void ui_list_clear(UiList *list);
UIEXPORT void ui_list_update(UiList *list);
UIEXPORT void ui_list_update_row(UiList *list, int row);
UIEXPORT UiListSelection ui_list_get_selection(UiList *list);
+UIEXPORT void ui_list_set_selection(UiList *list, UiListSelection sel);
UIEXPORT void ui_list_addobsv(UiList *list, ui_callback f, void *data);
UIEXPORT void ui_list_notify(UiList *list);
+UIEXPORT void ui_list_clear_saved_selection(UiList *list);
-UIEXPORT UiListSelection ui_list_getselection(UiList *list);
+UIEXPORT int ui_list_getselection(UiList *list);
UIEXPORT void ui_list_setselection(UiList *list, int index);
+UIEXPORT void ui_list_setselection2(UiList *list, int index, UiBool selection_event);
+
+UIEXPORT void ui_listselection_free(UiListSelection selection);
UIEXPORT UiFileList ui_filelist_copy(UiFileList list);
UIEXPORT void ui_filelist_free(UiFileList list);
UIEXPORT void ui_add_image(char *imgname, char *filename); // TODO: remove?
-
-
-UIEXPORT void ui_listselection_free(UiListSelection selection);
-
+UIEXPORT char* ui_text_getsubstr(UiText *text, int begin, int end);
+UIEXPORT void ui_text_insert(UiText *text, int pos, const char *str);
+UIEXPORT void ui_text_replace(UiText *text, int begin, int end, const char *str);
+UIEXPORT void ui_text_setposition(UiText *text, int pos);
+UIEXPORT int ui_text_position(UiText *text);
+UIEXPORT void ui_text_showposition(UiText *text, int pos);
+UIEXPORT void ui_text_setselection(UiText *text, int begin, int end);
+UIEXPORT void ui_text_selection(UiText *text, int *begin, int *end);
+UIEXPORT int ui_text_length(UiText *text);
+UIEXPORT void ui_text_remove(UiText *text, int begin, int end);
+UIEXPORT void ui_text_setreadonly(UiText *text, int readonly);
UIEXPORT UiStr ui_str(char *cstr);
UIEXPORT UiStr ui_str_free(char *str, void (*free)(void *v));
UIEXPORT char* ui_getappdir(void);
+UIEXPORT void ui_setappdir(const char *path);
UIEXPORT char* ui_configfile(const char *name);
UIEXPORT UiCondVar* ui_condvar_create(void);
UIEXPORT int ui_get_setop(void);
UIEXPORT void ui_onchange_events_enable(UiBool enable);
UIEXPORT UiBool ui_onchange_events_is_enabled(void);
+UIEXPORT void ui_selection_events_enable(UiBool enable);
+UIEXPORT UiBool ui_selection_events_is_enabled(void);
UIEXPORT void ui_global_list_initializer(ui_list_init_func func, void *userdata);
UIEXPORT void ui_global_list_destructor(ui_list_destroy_func func, void *userdata);
+UIEXPORT void ui_list_class_set_destructor(UiList *list, ui_list_destroy_func destroy);
UIEXPORT void ui_list_class_set_first(UiList *list, void*(*first)(UiList *list));
UIEXPORT void ui_list_class_set_next(UiList *list, void*(*next)(UiList *list));
UIEXPORT void ui_list_class_set_get(UiList *list, void*(*get)(UiList *list, int i));
UIEXPORT void ui_object_set(UiObject *obj, const char *key, void *data);
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
const char *varname;
const int* states;
+ const int *visibility_states;
} UiWebviewArgs;
#define ui_webview(obj, ...) ui_webview_create(obj, &(UiWebviewArgs){ __VA_ARGS__ } )
const char *style_class;
} UiWidgetArgs;
+#ifndef UI_GENERIC
+
#ifdef UI_GTK
typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs *args, void *userdata);
#elif defined(UI_QT)
#define ui_customwidget(obj, create_widget, userdata, ...) ui_customwidget_create(obj, create_widget, userdata, &(UiWidgetArgs) { __VA_ARGS__ })
+#endif
UIEXPORT UIWIDGET ui_separator_create(UiObject *obj, UiWidgetArgs *args);