all: $(APP_BIN) $(TEST_BIN)
-$(APP_BIN): $(MAIN_OBJ) $(OBJ) $(BUILD_ROOT)/build/lib/libuitk.a
- $(CC) -o $(APP_BIN) $(MAIN_OBJ) $(OBJ) -L$(BUILD_ROOT)/build/lib -luitk -lucx -lidav -ldbutils -lmd4c $(LDFLAGS) $(TK_LDFLAGS) $(DAV_LDFLAGS) $(DBU_LDFLAGS)
+$(APP_BIN): $(MAIN_OBJ) $(OBJ)
+ $(LD) -o $(APP_BIN) $(MAIN_OBJ) $(OBJ) -L$(BUILD_ROOT)/build/lib -luitk -lucx -lidav -ldbutils -lmd4c $(LDFLAGS) $(TK_LDFLAGS) $(DAV_LDFLAGS) $(DBU_LDFLAGS)
$(TEST_BIN): $(OBJ) $(TEST_OBJ) $(BUILD_ROOT)/build/lib/libuitk.a
$(CC) -o $(TEST_BIN) $(TEST_OBJ) $(OBJ) -L$(BUILD_ROOT)/build/lib -luitk -lucx -lidav -ldbutils -lmd4c $(LDFLAGS) $(TK_LDFLAGS) $(DAV_LDFLAGS) $(DBU_LDFLAGS)
Attachment *attachment = elm;
if(attachment->type == NOTE_ATTACHMENT_IMAGE) {
- ui_imageviewer(obj, .value = attachment->ui->img, .scrollarea = FALSE);
+ UIWIDGET imgviewer = ui_imageviewer(obj, .value = attachment->ui->img, .scrollarea = FALSE, .autoscale = TRUE);
+ ui_widget_set_size(imgviewer, 100, 80);
}
}
ui_button(obj, .icon = "insert-link");
}
ui_hbox_w(obj, wdata->attachments, .margin = 10, .fill = UI_OFF) {
- ui_scrolledwindow(obj, .name = "note_attachments_sw") {
+ void *sw;
+ ui_scrolledwindow_w(obj, sw, .name = "note_attachments_sw") {
ui_itemlist(obj, .varname = "note_attachments", .container = UI_CONTAINER_HBOX, .create_ui = attachment_item, .userdata = wdata);
}
+ ui_widget_set_size(sw, -1, 120);
}
//ui_set_visible(wdata->attachments, FALSE);
//ui_widget_set_groups(obj->ctx, wdata->attachments, (ui_enablefunc)ui_set_visible, APP_STATE_NOTE_HAS_ATTACHMENTS, -1);
Options:
--debug add extra compile flags for debug builds
--release add extra compile flags for release builds
- --toolkit=(libadwaita|gtk4|gtk3|cocoa|motif)
+ --toolkit=(libadwaita|gtk4|gtk3|cocoa|qt5|motif)
__EOF__
}
# check languages
lang_c=
lang_cpp=
+if detect_cpp_compiler ; then
+ lang_cpp=1
+fi
if detect_c_compiler ; then
lang_c=1
fi
dep_checked_gtk2legacy=1
return 0
}
+dependency_error_qt5()
+{
+ print_check_msg "$dep_checked_qt5" "checking for qt5... "
+ # dependency qt5
+ while true
+ do
+ if [ -z "$lang_cpp" ] ; then
+ break
+ fi
+ if [ -z "$PKG_CONFIG" ]; then
+ break
+ fi
+ if which qmake-qt5 > /dev/null ; then
+ :
+ else
+ break
+ fi
+ if test_pkg_config "Qt5Widgets" "" "" "" ; then
+ TEMP_CFLAGS="$TEMP_CFLAGS `"$PKG_CONFIG" --cflags Qt5Widgets`"
+ TEMP_LDFLAGS="$TEMP_LDFLAGS `"$PKG_CONFIG" --libs Qt5Widgets`"
+ else
+ break
+ fi
+ TEMP_CFLAGS="$TEMP_CFLAGS -DUI_QT5"
+ cat >> $TEMP_DIR/make.mk << __EOF__
+# Dependency: qt5
+QMAKE = qmake-qt5
+QT_PRO_FILE = qt5.pro
+__EOF__
+ print_check_msg "$dep_checked_qt5" "yes\n"
+ dep_checked_qt5=1
+ return 1
+ done
+
+ print_check_msg "$dep_checked_qt5" "no\n"
+ dep_checked_qt5=1
+ return 0
+}
dependency_error_openssl()
{
print_check_msg "$dep_checked_openssl" "checking for openssl... "
break
fi
+ cat >> "$TEMP_DIR/make.mk" << __EOF__
+LD = \$(CC)
+__EOF__
break
done
break
cat >> "$TEMP_DIR/make.mk" << __EOF__
OBJ_EXT = .o
LIB_EXT = .a
+LIB_PREFIX = lib
PACKAGE_SCRIPT = package_osx.sh
__EOF__
break
cat >> "$TEMP_DIR/make.mk" << __EOF__
OBJ_EXT = .o
LIB_EXT = .a
+LIB_PREFIX = lib
PACKAGE_SCRIPT = package_unix.sh
__EOF__
break
__EOF__
return 0
}
+checkopt_toolkit_qt5()
+{
+ VERR=0
+ if dependency_error_qt5 ; then
+ VERR=1
+ fi
+ if [ $VERR -ne 0 ]; then
+ return 1
+ fi
+ cat >> "$TEMP_DIR/make.mk" << __EOF__
+TOOLKIT = qt
+LD = \$(CXX)
+__EOF__
+ return 0
+}
checkopt_toolkit_motif()
{
VERR=0
ERROR=1
DEPENDENCIES_FAILED="option 'toolkit' $DEPENDENCIES_FAILED"
fi
+ elif [ "$OPT_TOOLKIT" = "qt5" ]; then
+ echo " toolkit: $OPT_TOOLKIT" >> $TEMP_DIR/options
+ if checkopt_toolkit_qt5 ; then
+ :
+ else
+ ERROR=1
+ DEPENDENCIES_FAILED="option 'toolkit' $DEPENDENCIES_FAILED"
+ fi
elif [ "$OPT_TOOLKIT" = "motif" ]; then
echo " toolkit: $OPT_TOOLKIT" >> $TEMP_DIR/options
if checkopt_toolkit_motif ; then
<project version="0.3" xmlns="http://unixwork.de/uwproj">
<dependency>
<lang>c</lang>
+ <make>LD = \$(CC)</make>
</dependency>
<dependency name="curl" platform="macos">
<!-- webview unsupported -->
</dependency>
- <!--
- <dependency name="qt4">
- <test>which qmake-qt4</test>
- <cflags exec="true">qmake-qt4 -o - /dev/null | grep DEFINES\ </cflags>
- <cflags exec="true">qmake-qt4 -o - /dev/null | grep INCPATH\ </cflags>
- <ldflags exec="true">qmake-qt4 -o - /dev/null | grep LIBS\ </ldflags>
- </dependency>
-
<dependency name="qt5">
<test>which qmake-qt5</test>
- <cflags exec="true">qmake-qt5 -o - /dev/null | grep DEFINES\ </cflags>
- <cflags exec="true">qmake-qt5 -o - /dev/null | grep INCPATH\ </cflags>
- <ldflags exec="true">qmake-qt5 -o - /dev/null | grep LIBS\ </ldflags>
+ <lang>cpp</lang>
+ <cflags>-DUI_QT5</cflags>
+ <pkgconfig>Qt5Widgets</pkgconfig>
+ <make>QMAKE = qmake-qt5</make>
+ <make>QT_PRO_FILE = qt5.pro</make>
</dependency>
- -->
+
<dependency name="cocoa" platform="macos">
<cflags>-DUI_COCOA</cflags>
<ldflags>-lobjc -framework Cocoa</ldflags>
<dependency platform="macos">
<make>OBJ_EXT = .o</make>
<make>LIB_EXT = .a</make>
+ <make>LIB_PREFIX = lib</make>
<make>PACKAGE_SCRIPT = package_osx.sh</make>
</dependency>
<dependency platform="unix" not="macos">
<make>OBJ_EXT = .o</make>
<make>LIB_EXT = .a</make>
+ <make>LIB_PREFIX = lib</make>
<make>PACKAGE_SCRIPT = package_unix.sh</make>
</dependency>
<make>TOOLKIT = cocoa</make>
<make>APP_PLATFORM_SRC = cocoa-text.m</make>
</value>
- <!--
- <value str="gtk2">
- <dependencies>gtk2</dependencies>
- <make>TOOLKIT = gtk</make>
- <make>GTKOBJ = draw_cairo.o</make>
- </value>
- <value str="gtk2legacy">
- <dependencies>gtk2legacy</dependencies>
- <make>TOOLKIT = gtk</make>
- <make>GTKOBJ = draw_gdk.o</make>
- </value>
<value str="qt5">
<dependencies>qt5</dependencies>
<make>TOOLKIT = qt</make>
- <make>LD = $(CXX)</make>
+ <make>LD = \$(CXX)</make>
</value>
- <value str="qt4">
- <dependencies>qt4</dependencies>
- <make>TOOLKIT = qt</make>
- <make>LD = $(CXX)</make>
- </value>
- -->
<value str="motif">
<dependencies>motif</dependencies>
<make>TOOLKIT = motif</make>
include common/objs.mk
-UI_LIB = ../build/lib/libuitk$(LIB_EXT)
+UI_LIB = ../build/lib/$(LIB_PREFIX)uitk$(LIB_EXT)
include $(TOOLKIT)/objs.mk
OBJ = $(TOOLKITOBJS) $(COMMONOBJS)
include $(TOOLKIT)/Makefile
-$(COMMON_OBJPRE)%.o: common/%.c
+$(COMMON_OBJPRE)uic_%$(OBJ_EXT): common/%.c
$(CC) -o $@ -c -I../ucx/ $(CFLAGS) $(TK_CFLAGS) $<
NSSize s1 = _test.intrinsicContentSize;
NSEdgeInsets e1 = _test.alignmentRectInsets;
- printf("fuck\n");
}
*/
GridDef *row = &rows[y];
NSSize size = elm->view.intrinsicContentSize;
+ NSSize size2 = elm->view.fittingSize;
NSEdgeInsets alignment = elm->view.alignmentRectInsets;
+ // TODO: remove alignment
+ alignment.left = 0;
+ alignment.right = 0;
+ alignment.top = 0;
+ alignment.bottom = 0;
+ if(size.width == NSViewNoIntrinsicMetric) {
+ size.width = size2.width;
+ }
+ if(size.height == NSViewNoIntrinsicMetric) {
+ size.height = size2.height;
+ }
if(size.width != NSViewNoIntrinsicMetric) {
CGFloat width = size.width + alignment.left + alignment.right;
if(width > cols[elm->x].preferred_size && elm->colspan <= 1 && span_max == 1) {
for(int c=elm->x;c<end_col;c++) {
cwidth += cols[c].size;
}
- frame.size.width = cwidth;
+ frame.size.width = cwidth + + alignment.left + alignment.right;
} else {
- frame.size.width = col->size;
+ frame.size.width = col->size + alignment.left + alignment.right;
}
} else {
- frame.size.width = elm->preferred_width;
+ frame.size.width = elm->preferred_width + alignment.left + alignment.right;
}
if(elm->vfill) {
if(elm->rowspan > 1) {
frame.size.height = elm->preferred_height;
}
frame.origin.x = col->pos - (alignment.left+alignment.right)/2;
- frame.origin.y = viewFrame.size.height - row->pos - frame.size.height + ((alignment.top+alignment.right)/2);
+ //frame.origin.y = viewFrame.size.height - row->pos - frame.size.height + ((alignment.top+alignment.right)/2);
+ frame.origin.y = viewFrame.size.height - row->pos - frame.size.height;
elm->view.frame = frame;
}
elm.margin = 0;
elm.colspan = _uilayout.colspan;
elm.rowspan = _uilayout.rowspan;
- elm.hfill = _uilayout.hfill;
- elm.vfill = _uilayout.vfill;
- elm.hexpand = _uilayout.hexpand;
- elm.vexpand = _uilayout.vexpand;
+ if(_uilayout.fill) {
+ elm.hfill = TRUE;
+ elm.vfill = TRUE;
+ elm.hexpand = TRUE;
+ elm.vexpand = TRUE;
+ } else {
+ elm.hfill = _uilayout.hfill;
+ elm.vfill = _uilayout.vfill;
+ elm.hexpand = _uilayout.hexpand;
+ elm.vexpand = _uilayout.vexpand;
+ }
elm.view = view;
cxListAdd(_children, &elm);
#import "AppDelegate.h"
#import "toolkit.h"
+#import "menu.h"
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ ui_menu_init();
ui_cocoa_onstartup();
}
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2014 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 "../ui/menu.h"
+#import "toolkit.h"
+
+#import "../common/menu.h"
+
+void ui_menu_init(void);
+
+typedef void(*ui_menu_add_f)(NSMenu*, int, UiMenuItemI*);
+
+void add_menu_widget(NSMenu *parent, int i, UiMenuItemI *item);
+void add_menuitem_widget(NSMenu *parent, int i, UiMenuItemI *item);
+void add_menuseparator_widget(NSMenu *parent, int i, UiMenuItemI *item);
+void add_checkitem_widget(NSMenu *parent, int i, UiMenuItemI *item);
+void add_radioitem_widget(NSMenu *parent, int index, UiMenuItemI *item);
+void add_checkitemnv_widget(NSMenu *parent, int i, UiMenuItemI *item);
+void add_menuitem_list_widget(NSMenu *parent, int i, UiMenuItemI *item);
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2014 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 <stdio.h>
+#import <stdlib.h>
+#import <string.h>
+#import <stdarg.h>
+
+#import "menu.h"
+#import "window.h"
+
+static ui_menu_add_f createMenuItem[] = {
+ /* UI_MENU */ add_menu_widget,
+ /* UI_MENU_ITEM */ add_menuitem_widget,
+ /* UI_MENU_CHECK_ITEM */ add_checkitem_widget,
+ /* UI_MENU_RADIO_ITEM */ add_radioitem_widget,
+ /* UI_MENU_ITEM_LIST */ add_menuitem_list_widget,
+ /* UI_MENU_CHECKITEM_LIST */ add_menuitem_list_widget,
+ /* UI_MENU_RADIOITEM_LIST */ add_menuitem_list_widget,
+ /* UI_MENU_SEPARATOR */ add_menuseparator_widget
+};
+
+static void add_menu_items(NSMenu *parent, int i, UiMenu *menu) {
+ UiMenuItemI *it = menu->items_begin;
+ int index = 0;
+ while(it) {
+ createMenuItem[it->type](parent, index, it);
+ it = it->next;
+ index++;
+ }
+}
+
+void add_menu_widget(NSMenu *parent, int i, UiMenuItemI *item) {
+ UiMenu *it = (UiMenu*)item;
+ NSString *str = [[NSString alloc] initWithUTF8String:it->label];
+ NSMenu *menu = [[NSMenu alloc] initWithTitle: str];
+ NSMenuItem *menuItem = [parent addItemWithTitle:str action:nil keyEquivalent:@""];
+ [parent setSubmenu:menu forItem:menuItem];
+
+ add_menu_items(menu, i, it);
+}
+
+void add_menuitem_widget(NSMenu *parent, int i, UiMenuItemI *item) {
+ UiMenuItem *it = (UiMenuItem*)item;
+ NSString *str = [[NSString alloc] initWithUTF8String:it->label];
+ NSMenuItem *menuItem = [parent addItemWithTitle:str action:nil keyEquivalent:@""];
+}
+
+void add_menuseparator_widget(NSMenu *parent, int i, UiMenuItemI *item) {
+
+}
+
+void add_checkitem_widget(NSMenu *parent, int i, UiMenuItemI *item) {
+
+}
+
+void add_radioitem_widget(NSMenu *parent, int index, UiMenuItemI *item) {
+
+}
+
+void add_checkitemnv_widget(NSMenu *parent, int i, UiMenuItemI *item) {
+
+}
+
+void add_menuitem_list_widget(NSMenu *parent, int i, UiMenuItemI *item) {
+
+}
+
+
+void ui_menu_init(void) {
+ UiMenu *menus_begin = uic_get_menu_list();
+ UiMenu *ls = menus_begin;
+ while(ls) {
+ if(ls->item.type == UI_MENU) {
+ NSString *str = [[NSString alloc] initWithUTF8String:ls->label];
+ NSMenu *menu = [[NSMenu alloc] initWithTitle: str];
+ NSMenuItem *menuItem = [[NSApp mainMenu] addItemWithTitle:str action:nil keyEquivalent:@""];
+ [[NSApp mainMenu] setSubmenu:menu forItem:menuItem];
+
+ add_menu_items(menu, 0, ls);
+ }
+ ls = (UiMenu*)ls->item.next;
+ }
+}
COCOAOBJ += Container.o
COCOAOBJ += button.o
COCOAOBJ += text.o
+COCOAOBJ += menu.o
TOOLKITOBJS += $(COCOAOBJ:%=$(COCOA_OBJPRE)%)
TOOLKITSOURCE += $(COCOAOBJ:%.o=cocoa/%.m)
#import <objc/runtime.h>
UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs args) {
- //NSScrollView *scrollview = [[NSScrollView alloc] initWithFrame:(NSRect){ 0, 0, 40, 40}];
- NSTextView *textview = [[NSTextView alloc] initWithFrame:(NSRect){ 0, 0, 40, 40}];
- //scrollview.documentView = textview;
+ NSTextView *textview = [[NSTextView alloc] init];
+ textview.autoresizingMask = NSViewWidthSizable;
+ textview.minSize = NSMakeSize(0, 0);
+ textview.maxSize = NSMakeSize(FLT_MAX, FLT_MAX);
+
+ NSScrollView *scrollview = [[NSScrollView alloc] init];
+ scrollview.hasVerticalScroller = YES;
+ scrollview.documentView = textview;
UiLayout layout = UI_INIT_LAYOUT(args);
- ui_container_add(obj, textview, &layout, TRUE);
+ ui_container_add(obj, scrollview, &layout, TRUE);
- return (__bridge void*)textview;
+ return (__bridge void*)scrollview;
}
#include "../common/toolbar.h"
#include "../common/threadpool.h"
+#import "menu.h"
+
#import "AppDelegate.h"
static const char *application_name;
* POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef _WIN32
+
#include "condvar.h"
#include <stdlib.h>
free(p);
}
+
+#endif
\ No newline at end of file
typedef struct UiListVar UiListVar;
typedef struct UiGroupWidget UiGroupWidget;
-typedef enum UiVarType UiVarType;
-
-enum UiVarType {
+typedef enum UiVarType {
UI_VAR_SPECIAL = 0,
UI_VAR_INTEGER,
UI_VAR_DOUBLE,
UI_VAR_LIST,
UI_VAR_RANGE,
UI_VAR_GENERIC
-};
+} UiVarType;
struct UiContext {
UiContext *parent;
COMMON_SRC_DIR = ui/common/
COMMON_OBJPRE = $(OBJ_DIR)$(COMMON_SRC_DIR)
-COMMON_OBJ = context.o
-COMMON_OBJ += document.o
-COMMON_OBJ += object.o
-COMMON_OBJ += types.o
-COMMON_OBJ += menu.o
-COMMON_OBJ += properties.o
-COMMON_OBJ += menu.o
-COMMON_OBJ += toolbar.o
-COMMON_OBJ += ucx_properties.o
-COMMON_OBJ += threadpool.o
-COMMON_OBJ += condvar.o
+COMMON_OBJ = context$(OBJ_EXT)
+COMMON_OBJ += document$(OBJ_EXT)
+COMMON_OBJ += object$(OBJ_EXT)
+COMMON_OBJ += types$(OBJ_EXT)
+COMMON_OBJ += menu$(OBJ_EXT)
+COMMON_OBJ += properties$(OBJ_EXT)
+COMMON_OBJ += menu$(OBJ_EXT)
+COMMON_OBJ += toolbar$(OBJ_EXT)
+COMMON_OBJ += ucx_properties$(OBJ_EXT)
+COMMON_OBJ += threadpool$(OBJ_EXT)
+COMMON_OBJ += condvar$(OBJ_EXT)
-TOOLKITOBJS += $(COMMON_OBJ:%=$(COMMON_OBJPRE)%)
-TOOLKITSOURCE += $(COMMON_OBJ:%.o=common/%.c)
+TOOLKITOBJS += $(COMMON_OBJ:%=$(COMMON_OBJPRE)uic_%)
+TOOLKITSOURCE += $(COMMON_OBJ:%$(OBJ_EXT)=common/%.c)
static int ui_mkdir(char *path) {
#ifdef _WIN32
- return mkdir(path);
+ return _mkdir(path);
#else
return mkdir(path, S_IRWXU);
#endif
* POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef _WIN32
+
#include "threadpool.h"
#include "context.h"
-#ifndef _WIN32
-
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
-
+
#define ui_reset_layout(layout) memset(&(layout), 0, sizeof(UiLayout))
#define ui_lb2bool(b) ((b) == UI_LAYOUT_TRUE ? TRUE : FALSE)
#define ui_bool2lb(b) ((b) ? UI_LAYOUT_TRUE : UI_LAYOUT_FALSE)
typedef struct UiDocumentView UiDocumentView;
-typedef struct UiLayout UiLayout;
-typedef enum UiLayoutBool UiLayoutBool;
-enum UiLayoutBool {
+typedef enum UiLayoutBool {
UI_LAYOUT_UNDEFINED = 0,
UI_LAYOUT_TRUE,
UI_LAYOUT_FALSE,
-};
+} UiLayoutBool;
+typedef struct UiLayout UiLayout;
struct UiLayout {
UiLayoutBool fill;
UiBool newline;
#include "../common/context.h"
#include "../common/object.h"
+static void imageviewer_destroy(UiImageViewer *iv) {
+ if(iv->pixbuf) {
+ g_object_unref(iv->pixbuf);
+ }
+ free(iv);
+}
+
+#if GTK_MAJOR_VERSION >= 4
+
+static void imageviewer_draw(
+ GtkDrawingArea *drawingarea,
+ cairo_t *cr,
+ int width,
+ int height,
+ gpointer userdata)
+{
+ ui_cairo_draw_image(userdata, cr, width, height);
+}
-UIWIDGET ui_imageviewer_create(UiObject *obj, UiImageViewerArgs args) {
- UiObject *current = uic_current_obj(obj);
-
- GtkWidget *scrolledwindow = SCROLLEDWINDOW_NEW();
-#if GTK_CHECK_VERSION(4, 0, 0)
- GtkWidget *image = gtk_picture_new();
#else
- GtkWidget *image = gtk_image_new();
+
+static gboolean imageviewer_draw(GtkWidget *widget, cairo_t *cr, gpointer userdata) {
+ int width = gtk_widget_get_allocated_width(widget);
+ int height = gtk_widget_get_allocated_height(widget);
+ ui_cairo_draw_image(userdata, cr, width, height);
+ return FALSE;
+}
+
#endif
+
+UIWIDGET ui_imageviewer_create(UiObject *obj, UiImageViewerArgs args) {
+ UiObject *current = uic_current_obj(obj);
- ui_set_name_and_style(image, args.name, args.style_class);
+ GtkWidget *drawingarea = gtk_drawing_area_new();
+ GtkWidget *toplevel;
+ GtkWidget *widget = drawingarea;
+
+ gtk_widget_set_size_request(drawingarea, 100, 100);
#if GTK_MAJOR_VERSION < 4
GtkWidget *eventbox = gtk_event_box_new();
- SCROLLEDWINDOW_SET_CHILD(scrolledwindow, eventbox);
- gtk_container_add(GTK_CONTAINER(eventbox), image);
-#else
- SCROLLEDWINDOW_SET_CHILD(scrolledwindow, image);
- GtkWidget *eventbox = image;
+ gtk_container_add(GTK_CONTAINER(eventbox), drawingarea);
+ widget = eventbox;
#endif
- UI_APPLY_LAYOUT1(current, args);
- current->container->add(current->container, scrolledwindow, TRUE);
+ if(args.scrollarea) {
+ toplevel = SCROLLEDWINDOW_NEW();
+ SCROLLEDWINDOW_SET_CHILD(toplevel, widget);
+ args.adjustwidgetsize = TRUE;
+ } else {
+ toplevel = widget;
+ }
+
+ UiImageViewer *imgviewer = malloc(sizeof(UiImageViewer));
+ memset(imgviewer, 0, sizeof(UiImageViewer));
+ if(args.image_padding > 0) {
+ imgviewer->padding_left = args.image_padding;
+ imgviewer->padding_right = args.image_padding;
+ imgviewer->padding_top = args.image_padding;
+ imgviewer->padding_bottom = args.image_padding;
+ } else {
+ imgviewer->padding_left = args.image_padding_left;
+ imgviewer->padding_right = args.image_padding_right;
+ imgviewer->padding_top = args.image_padding_top;
+ imgviewer->padding_bottom = args.image_padding_bottom;
+ }
+ imgviewer->adjustwidgetsize = args.adjustwidgetsize;
+ imgviewer->autoscale = args.autoscale;
+ imgviewer->useradjustable = args.useradjustable;
+ imgviewer->zoom_scale = 20;
+
+ g_object_set_data_full(G_OBJECT(drawingarea), "uiimageviewer", imgviewer, (GDestroyNotify)imageviewer_destroy);
UiVar *var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_GENERIC);
+ imgviewer->var = var;
+ imgviewer->widget = drawingarea;
+
if(var) {
UiGeneric *value = var->value;
value->get = ui_imageviewer_get;
value->get_type = ui_imageviewer_get_type;
value->set = ui_imageviewer_set;
- value->obj = image;
+ value->obj = imgviewer;
if(value->value && value->type && !strcmp(value->type, UI_IMAGE_OBJECT_TYPE)) {
GdkPixbuf *pixbuf = value->value;
value->value = NULL;
}
}
+#if GTK_MAJOR_VERSION >= 4
+ gtk_drawing_area_set_draw_func(
+ GTK_DRAWING_AREA(drawingarea),
+ imageviewer_draw,
+ imgviewer,
+ NULL);
+
+ if(args.useradjustable) {
+ gtk_widget_set_focusable(drawingarea, TRUE);
+ }
+
+ GtkEventController *scrollcontroller = gtk_event_controller_scroll_new(GTK_EVENT_CONTROLLER_SCROLL_VERTICAL);
+ g_signal_connect(scrollcontroller, "scroll", G_CALLBACK(ui_imageviewer_scroll), imgviewer);
+ gtk_widget_add_controller(GTK_WIDGET(drawingarea), GTK_EVENT_CONTROLLER(scrollcontroller));
+
+ GtkGesture *drag = gtk_gesture_drag_new();
+ g_signal_connect(drag, "drag-begin", G_CALLBACK(ui_imageviewer_drag_begin_cb), imgviewer);
+ g_signal_connect(drag, "drag-end", G_CALLBACK(ui_imageviewer_drag_end_cb), imgviewer);
+ g_signal_connect(drag, "drag-update", G_CALLBACK(ui_imageviewer_drag_update_cb), imgviewer);
+ gtk_widget_add_controller(GTK_WIDGET(drawingarea), GTK_EVENT_CONTROLLER(drag));
+
+#elif GTK_MAJOR_VERSION == 3
+ g_signal_connect(
+ drawingarea,
+ "draw",
+ G_CALLBACK(imageviewer_draw),
+ imgviewer);
+
+ gtk_widget_add_events(eventbox, GDK_SCROLL_MASK);
+
+ g_signal_connect(
+ eventbox,
+ "scroll-event",
+ G_CALLBACK(ui_imageviewer_scroll_event),
+ imgviewer);
+ g_signal_connect(
+ eventbox,
+ "button-press-event",
+ G_CALLBACK(ui_imageviewer_button_press_event),
+ imgviewer);
+ g_signal_connect(
+ eventbox,
+ "button-release-event",
+ G_CALLBACK(ui_imageviewer_button_release_event),
+ imgviewer);
+
+#endif
+
if(args.contextmenu) {
- UIMENU menu = ui_contextmenu_create(args.contextmenu, obj, eventbox);
- ui_widget_set_contextmenu(eventbox, menu);
+ UIMENU menu = ui_contextmenu_create(args.contextmenu, obj, widget);
+ ui_widget_set_contextmenu(widget, menu);
}
+
+ UI_APPLY_LAYOUT1(current, args);
+ current->container->add(current->container, toplevel, TRUE);
- return scrolledwindow;
+ return toplevel;
+}
+
+static void imageviewer_reset(UiImageViewer *imgviewer) {
+ imgviewer->isautoscaled = FALSE;
+ imgviewer->transx = 0;
+ imgviewer->transy;
+ imgviewer->begin_transx = 0;
+ imgviewer->begin_transy = 0;
+ imgviewer->scale = 1;
+ imgviewer->user_scale = 1;
+}
+
+UIWIDGET ui_imageviewer_reset(UIWIDGET w) {
+ UiImageViewer *imgviewer = g_object_get_data(G_OBJECT(w), "uiimageviewer");
+ if(imgviewer) {
+ imageviewer_reset(imgviewer);
+ gtk_widget_queue_draw(w);
+ }
+}
+
+UIWIDGET ui_imageviewer_set_autoscale(UIWIDGET w, UiBool set) {
+ UiImageViewer *imgviewer = g_object_get_data(G_OBJECT(w), "uiimageviewer");
+ if(imgviewer) {
+ imgviewer->autoscale = set;
+ }
+}
+
+UIWIDGET ui_imageviewer_set_adjustwidgetsize(UIWIDGET w, UiBool set) {
+ UiImageViewer *imgviewer = g_object_get_data(G_OBJECT(w), "uiimageviewer");
+ if(imgviewer) {
+ imgviewer->adjustwidgetsize = set;
+ }
+}
+
+UIWIDGET ui_imageviewer_set_useradjustable(UIWIDGET w, UiBool set) {
+ UiImageViewer *imgviewer = g_object_get_data(G_OBJECT(w), "uiimageviewer");
+ if(imgviewer) {
+ imgviewer->useradjustable = set;
+ }
+}
+
+void ui_cairo_draw_image(UiImageViewer *imgviewer, cairo_t *cr, int width, int height) {
+ if(!imgviewer->pixbuf) {
+ return;
+ }
+
+ GdkPixbuf *pixbuf = imgviewer->pixbuf;
+ double dpixwidth = (double)gdk_pixbuf_get_width(pixbuf);
+ double dpixheight = (double)gdk_pixbuf_get_height(pixbuf);
+
+ double dwidth = width;
+ double dheight = height;
+ double scale = 1;
+ // if autoscale is enabled, scale the image to fill available space
+ // if useradjustable is also enabled, the autoscaling is only done once
+ if(imgviewer->autoscale && imgviewer->scale != 0) {
+ if(!imgviewer->isautoscaled) {
+ scale = dwidth / dpixwidth;
+ if(dpixheight * scale > dheight) {
+ scale = dheight / dpixheight;
+ }
+
+ if(imgviewer->useradjustable) {
+ imgviewer->isautoscaled = TRUE;
+ }
+
+ imgviewer->scale = scale;
+ } else {
+ scale = imgviewer->scale;
+ }
+
+ imgviewer->user_scale = scale;
+ } else {
+ // user-adjusted scaling
+ //scale = 1 + ((double)imgviewer->zoom / (double)imgviewer->zoom_scale);
+ scale = imgviewer->user_scale;
+ }
+
+ dpixwidth *= scale;
+ dpixheight *= scale;
+ double x = (dwidth - dpixwidth) / 2;
+ double y = (dheight - dpixheight) / 2;
+
+ x += imgviewer->transx;
+ y += imgviewer->transy;
+
+ cairo_translate(cr, x, y);
+ cairo_scale(cr, scale, scale);
+
+ gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
+ cairo_paint(cr);
}
void* ui_imageviewer_get(UiGeneric *g) {
+ UiImageViewer *imgviewer = g->obj;
+ g->value = imgviewer->pixbuf;
return g->value;
}
const char* ui_imageviewer_get_type(UiGeneric *g) {
-
+ return UI_IMAGE_OBJECT_TYPE;
}
int ui_imageviewer_set(UiGeneric *g, void *value, const char *type) {
return 1;
}
- // TODO: do we need to free the previous value here?
-
- g->value = value;
- g->type = type;
GdkPixbuf *pixbuf = value;
- if(pixbuf) {
+ UiImageViewer *imgviewer = g->obj;
+ g->value = pixbuf;
+
+ imageviewer_reset(imgviewer);
+
+ if(imgviewer->pixbuf) {
+ g_object_unref(imgviewer->pixbuf);
+ }
+ imgviewer->pixbuf = pixbuf;
+
+ if(imgviewer->adjustwidgetsize && !imgviewer->autoscale) {
int width = gdk_pixbuf_get_width(pixbuf);
int height = gdk_pixbuf_get_height(pixbuf);
-
-#if GTK_CHECK_VERSION(4, 0, 0)
- GdkTexture *texture = gdk_texture_new_for_pixbuf(pixbuf);
- gtk_picture_set_paintable(GTK_PICTURE(g->obj), GDK_PAINTABLE(texture));
-#else
- gtk_image_set_from_pixbuf(GTK_IMAGE(g->obj), pixbuf);
-#endif
- gtk_widget_set_size_request(g->obj, width, height);
+ gtk_widget_set_size_request(imgviewer->widget, width, height);
}
-
+ gtk_widget_queue_draw(imgviewer->widget);
return 0;
}
} else {
obj->value = pixbuf;
}
-
+
return 0;
}
+
+#if GTK_MAJOR_VERSION >= 4
+
+gboolean ui_imageviewer_scroll(
+ GtkEventControllerScroll *widget,
+ gdouble dx,
+ gdouble dy,
+ gpointer userdata)
+{
+ UiImageViewer *imgviewer = userdata;
+ if(imgviewer->useradjustable) {
+ double step = dy / imgviewer->zoom_scale;
+ if(imgviewer->user_scale - step > 0) {
+ imgviewer->user_scale -= step;
+ }
+
+ imgviewer->scale = 0; // disable autoscale
+ gtk_widget_queue_draw(imgviewer->widget);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void ui_imageviewer_drag_begin_cb(
+ GtkGestureDrag* self,
+ gdouble start_x,
+ gdouble start_y,
+ gpointer userdata)
+{
+ UiImageViewer *imgviewer = userdata;
+ imgviewer->begin_transx = imgviewer->transx;
+ imgviewer->begin_transy = imgviewer->transy;
+}
+
+void ui_imageviewer_drag_end_cb(
+ GtkGestureDrag* self,
+ gdouble x,
+ gdouble y,
+ gpointer userdata)
+{
+
+}
+
+void ui_imageviewer_drag_update_cb(
+ GtkGestureDrag* self,
+ gdouble x,
+ gdouble y,
+ gpointer userdata)
+{
+ UiImageViewer *imgviewer = userdata;
+ if(imgviewer->useradjustable) {
+ imgviewer->transx = imgviewer->begin_transx + x;
+ imgviewer->transy = imgviewer->begin_transy + y;
+ gtk_widget_queue_draw(imgviewer->widget);
+ }
+}
+
+#else
+
+gboolean ui_imageviewer_scroll_event(
+ GtkWidget *widget,
+ GdkEventScroll event,
+ gpointer userdata)
+{
+ printf("scroll event\n");
+ return FALSE;
+}
+
+gboolean ui_imageviewer_button_press_event(
+ GtkWidget *widget,
+ GdkEventButton event,
+ gpointer userdata)
+{
+ printf("button pressed\n");
+}
+
+gboolean ui_imageviewer_button_release_event(
+ GtkWidget *widget,
+ GdkEventButton event,
+ gpointer userdata)
+{
+ printf("button released\n");
+}
+
+#endif
extern "C" {
#endif
+typedef struct UiImageViewer {
+ GtkWidget *widget;
+ UiVar *var;
+ int padding_left;
+ int padding_right;
+ int padding_top;
+ int padding_bottom;
+ UiBool autoscale;
+ UiBool adjustwidgetsize;
+ UiBool useradjustable;
+ GdkPixbuf *pixbuf;
+
+ double zoom_scale;
+ int transx;
+ int transy;
+ int begin_transx;
+ int begin_transy;
+ UiBool isautoscaled;
+ double user_scale;
+ double scale;
+} UiImageViewer;
+
+void ui_cairo_draw_image(UiImageViewer *imgviewer, cairo_t *cr, int width, int height);
void* ui_imageviewer_get(UiGeneric *g);
const char* ui_imageviewer_get_type(UiGeneric *g);
int ui_imageviewer_set(UiGeneric *g, void *value, const char *type);
+#if GTK_MAJOR_VERSION >= 4
+
+gboolean ui_imageviewer_scroll(
+ GtkEventControllerScroll *widget,
+ gdouble dx,
+ gdouble dy,
+ gpointer userdata);
+
+void ui_imageviewer_drag_begin_cb(
+ GtkGestureDrag* self,
+ gdouble start_x,
+ gdouble start_y,
+ gpointer userdata);
+
+void ui_imageviewer_drag_end_cb(
+ GtkGestureDrag* self,
+ gdouble x,
+ gdouble y,
+ gpointer userdata);
+
+void ui_imageviewer_drag_update_cb(
+ GtkGestureDrag* self,
+ gdouble x,
+ gdouble y,
+ gpointer userdata);
+
+#else
+
+gboolean ui_imageviewer_scroll_event(
+ GtkWidget *widget,
+ GdkEventScroll event,
+ gpointer userdata);
+
+gboolean ui_imageviewer_button_press_event(
+ GtkWidget *widget,
+ GdkEventButton event,
+ gpointer userdata);
+
+gboolean ui_imageviewer_button_release_event(
+ GtkWidget *widget,
+ GdkEventButton event,
+ gpointer userdata);
+
+#endif
+
#ifdef __cplusplus
}
#endif
GTKOBJ += dnd.o
GTKOBJ += headerbar.o
GTKOBJ += webview.o
+GTKOBJ += widget.o
TOOLKITOBJS += $(GTKOBJ:%=$(GTK_OBJPRE)%)
TOOLKITSOURCE += $(GTKOBJ:%.o=gtk/%.c)
return widget;
}
+
+UIWIDGET ui_separator_create(UiObject *obj, UiWidgetArgs *args) {
+ UiObject* current = uic_current_obj(obj);
+ GtkWidget *widget = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
+ ui_set_name_and_style(widget, args->name, args->style_class);
+ UI_APPLY_LAYOUT1(current, (*args));
+ current->container->add(current->container, widget, FALSE);
+ return widget;
+}
+
+void ui_widget_set_size(UIWIDGET w, int width, int height) {
+ gtk_widget_set_size_request(w, width, height);
+}
+
+void ui_widget_redraw(UIWIDGET w) {
+ gtk_widget_queue_draw(w);
+}
UI_QT_LIB = ../build/ui/qt/
-$(QT_MAKEFILE): qt/qt4.pro
- qmake-qt4 -o - qt/qt4.pro > $(QT_MAKEFILE)
+$(QT_MAKEFILE): qt/$(QT_PRO_FILE)
+ $(QMAKE) -o - $< > $(QT_MAKEFILE)
$(UI_LIB): $(QT_MAKEFILE) $(OBJ) FORCE
$(MAKE) -f $(QT_MAKEFILE)
#include "container.h"
#include "toolkit.h"
-UIWIDGET ui_button(UiObject *obj, char *label, ui_callback f, void *data) {
- QString str = QString::fromUtf8(label);
+UIWIDGET ui_button_create(UiObject* obj, UiButtonArgs args) {
+ UiContainerPrivate *ctn = ui_obj_container(obj);
+ UI_APPLY_LAYOUT(ctn->layout, args);
+
+ QString str = QString::fromUtf8(args.label);
+ QPushButton *button = new QPushButton(str);
+
+ if(args.onclick) {
+ UiEventWrapper *event = new UiEventWrapper(obj, args.onclick, args.onclickdata);
+ button->connect(button, SIGNAL(clicked()), event, SLOT(slot()));
+ button->connect(button, SIGNAL(destroyed()), event, SLOT(destroy()));
+ }
+
+ ctn->add(button, false);
+
+ return button;
+}
+
+static void togglebutton_event(UiEvent *event, UiEventWrapper *wrapper) {
+ QPushButton *button = (QPushButton*)wrapper->customdata1;
+ event->intval = button->isChecked();
+ if(wrapper->var) {
+ event->eventdata = wrapper->var->value;
+ }
+}
+
+UIWIDGET ui_togglebutton_create(UiObject* obj, UiToggleArgs args) {
+ UiContainerPrivate *ctn = ui_obj_container(obj);
+ UI_APPLY_LAYOUT(ctn->layout, args);
+
+ QString str = QString::fromUtf8(args.label);
QPushButton *button = new QPushButton(str);
+ button->setCheckable(true);
- if(f) {
- UiEventWrapper *event = new UiEventWrapper(obj, f, data);
+ UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.value, args.varname, UI_VAR_INTEGER);
+
+ if(args.onchange) {
+ UiEventWrapper *event = new UiEventWrapper(obj, args.onchange, args.onchangedata);
+ event->var = var;
+ event->customdata1 = button;
+ event->prepare_event = togglebutton_event;
button->connect(button, SIGNAL(clicked()), event, SLOT(slot()));
+ button->connect(button, SIGNAL(destroyed()), event, SLOT(destroy()));
+ }
+
+ if(var) {
+ UiInteger *i = (UiInteger*)var->value;
+
+ if(i->value) {
+ button->setChecked(true);
+ }
+
+ i->obj = button;
+ i->get = ui_togglebutton_get;
+ i->set = ui_togglebutton_set;
}
- UiContainer *ct = uic_get_current_container(obj);
- ct->add(button, false);
+ ctn->add(button, false);
return button;
}
+int64_t ui_togglebutton_get(UiInteger *value) {
+ QPushButton *button = (QPushButton*)value->obj;
+ value->value = button->isChecked();
+ return value->value;
+}
+void ui_togglebutton_set(UiInteger *value, int64_t i) {
+ QPushButton *button = (QPushButton*)value->obj;
+ value->value = i;
+ if(i != 0) {
+ button->setChecked(true);
+ }
+}
-// TODO: checkbox
+static void checkbox_event(UiEvent *event, UiEventWrapper *wrapper) {
+ QPushButton *button = (QPushButton*)wrapper->customdata1;
+ event->intval = button->isChecked();
+ if(wrapper->var) {
+ event->eventdata = wrapper->var->value;
+ }
+}
-UIWIDGET ui_radiobutton(UiObject *obj, char *label, UiInteger *rgroup) {
- QString str = QString::fromUtf8(label);
- QRadioButton *button = new QRadioButton(str);
- button->setAutoExclusive(false);
-
- if(rgroup) {
- QButtonGroup *buttonGroup = (QButtonGroup*)rgroup->obj;
- if(!buttonGroup) {
- buttonGroup = new QButtonGroup();
- rgroup->obj = buttonGroup;
- button->setChecked(true);
+UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) {
+ UiContainerPrivate *ctn = ui_obj_container(obj);
+ UI_APPLY_LAYOUT(ctn->layout, args);
+
+ QString str = QString::fromUtf8(args.label);
+ QCheckBox *checkbox = new QCheckBox(str);
+
+ UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.value, args.varname, UI_VAR_INTEGER);
+
+ if(args.onchange) {
+ UiEventWrapper *event = new UiEventWrapper(obj, args.onchange, args.onchangedata);
+ event->var = var;
+ event->customdata1 = checkbox;
+ event->prepare_event = checkbox_event;
+ checkbox->connect(checkbox, SIGNAL(clicked()), event, SLOT(slot()));
+ checkbox->connect(checkbox, SIGNAL(destroyed()), event, SLOT(destroy()));
+ }
+
+ if(var) {
+ UiInteger *i = (UiInteger*)var->value;
+
+ if(i->value) {
+ checkbox->setChecked(true);
}
- buttonGroup->addButton(button, buttonGroup->buttons().size());
- rgroup->get = ui_radiobutton_get;
- rgroup->set = ui_radiobutton_set;
+ i->obj = checkbox;
+ i->get = ui_checkbox_get;
+ i->set = ui_checkbox_set;
}
- UiContainer *ct = uic_get_current_container(obj);
- ct->add(button, false);
+ ctn->add(checkbox, false);
- return button;
+ return checkbox;
}
-int ui_radiobutton_get(UiInteger *value) {
- QButtonGroup *buttonGroup = (QButtonGroup*)value->obj;
- value->value = buttonGroup->checkedId();
+int64_t ui_checkbox_get(UiInteger *value) {
+ QPushButton *button = (QPushButton*)value->obj;
+ value->value = button->isChecked();
return value->value;
}
-void ui_radiobutton_set(UiInteger *value, int i) {
- QButtonGroup *buttonGroup = (QButtonGroup*)value->obj;
- QAbstractButton *button = buttonGroup->button(i);
- if(button) {
+void ui_checkbox_set(UiInteger *value, int64_t i) {
+ QPushButton *button = (QPushButton*)value->obj;
+ value->value = i;
+ if(i != 0) {
button->setChecked(true);
- value->value = i;
}
}
#include <QPushButton>
#include <QRadioButton>
#include <QButtonGroup>
+#include <QCheckBox>
extern "C" {
-int ui_radiobutton_get(UiInteger *value);
+
+int64_t ui_togglebutton_get(UiInteger *value);
+void ui_togglebutton_set(UiInteger *value, int64_t i);
-void ui_radiobutton_set(UiInteger *value, int i);
+int64_t ui_checkbox_get(UiInteger *value);
+void ui_checkbox_set(UiInteger *value, int64_t i);
+
+int64_t ui_radiobutton_get(UiInteger *value);
+void ui_radiobutton_set(UiInteger *value, int64_t i);
}
#include <stdio.h>
#include "container.h"
+#include "../common/object.h"
+
+#include <cx/mempool.h>
#include <QSpacerItem>
#include <QStackedWidget>
+#include <QLabel>
+static void delete_container(UiContainerPrivate *ct) {
+ delete ct;
+}
+
+void ui_container_add(UiObject *obj, UiContainerPrivate *ct) {
+ UiContainerX *container = (UiContainerX*)ui_malloc(obj->ctx, sizeof(UiContainerX));
+ container->close = 0;
+ container->container = ct;
+ container->prev = NULL;
+ container->next = NULL;
+ cxMempoolRegister(obj->ctx->mp, ct, (cx_destructor_func)delete_container);
+ uic_object_push_container(obj, container);
+}
/* -------------------- UiBoxContainer -------------------- */
UiBoxContainer::UiBoxContainer(QBoxLayout* box) {
- this->current = NULL;
- this->menu = NULL;
this->box = box;
box->setContentsMargins(QMargins(0,0,0,0));
box->setSpacing(0);
current = widget;
}
-UIWIDGET ui_box(UiObject *obj, QBoxLayout::Direction dir) {
- UiContainer *ct = uic_get_current_container(obj);
+UIWIDGET ui_box(UiObject *obj, UiContainerArgs args, QBoxLayout::Direction dir) {
+ UiContainerPrivate *ctn = (UiContainerPrivate*)ui_obj_container(obj);
+ UI_APPLY_LAYOUT(ctn->layout, args);
+
QWidget *widget = new QWidget();
QBoxLayout *box = new QBoxLayout(dir);
widget->setLayout(box);
- ct->add(widget, true);
+ ctn->add(widget, true);
- UiObject *newobj = uic_object_new(obj, widget);
- newobj->container = new UiBoxContainer(box);
- uic_obj_add(obj, newobj);
+ ui_container_add(obj, new UiBoxContainer(box));
return widget;
}
-UIWIDGET ui_vbox(UiObject *obj) {
- return ui_box(obj, QBoxLayout::TopToBottom);
+UIWIDGET ui_vbox_create(UiObject *obj, UiContainerArgs args) {
+ return ui_box(obj, args, QBoxLayout::TopToBottom);
}
-UIWIDGET ui_hbox(UiObject *obj) {
- return ui_box(obj, QBoxLayout::LeftToRight);
+UIWIDGET ui_hbox_create(UiObject *obj, UiContainerArgs args) {
+ return ui_box(obj, args, QBoxLayout::LeftToRight);
}
-
/* -------------------- UiGridContainer -------------------- */
-UiGridContainer::UiGridContainer(QGridLayout* grid, int margin, int columnspacing, int rowspacing) {
+UiGridContainer::UiGridContainer(
+ QGridLayout *grid,
+ int margin,
+ int columnspacing,
+ int rowspacing,
+ bool def_hexpand,
+ bool def_vexpand,
+ bool def_hfill,
+ bool def_vfill)
+{
this->current = NULL;
- this->menu = NULL;
this->grid = grid;
+ this->def_hexpand = def_hexpand;
+ this->def_vexpand = def_vexpand;
+ this->def_hfill = def_hfill;
+ this->def_vfill = def_vfill;
grid->setContentsMargins(QMargins(margin, margin, margin, margin));
grid->setHorizontalSpacing(columnspacing);
grid->setVerticalSpacing(rowspacing);
y++;
}
- Qt::Alignment alignment = Qt::AlignTop;
- grid->setColumnStretch(x, layout.hexpand ? 1 : 0);
+ int hexpand = false;
+ int vexpand = false;
+ int hfill = false;
+ int vfill = false;
+ if(!layout.override_defaults) {
+ if(def_hexpand) {
+ hexpand = true;
+ hfill = true;
+ } else if(def_hfill) {
+ hfill = true;
+ }
+ if(def_vexpand) {
+ vexpand = true;
+ vfill = true;
+ } else if(def_vfill) {
+ vfill = true;
+ }
+ }
+
+ if(layout.fill != UI_LAYOUT_UNDEFINED) {
+ fill = ui_lb2bool(layout.fill);
+ }
+ if(layout.hexpand) {
+ hexpand = true;
+ //hfill = true;
+ } else if(layout.hfill) {
+ hfill = true;
+ }
if(layout.vexpand) {
+ vexpand = true;
+ //vfill = true;
+ } else if(layout.vfill) {
+ vfill = true;
+ }
+ if(fill) {
+ hfill = true;
+ vfill = true;
+ }
+
+ if(hexpand) {
+ col_expanding = true;
+ }
+ if(vexpand) {
+ row_expanding = true;
+ }
+
+ if(hexpand) {
+ grid->setColumnStretch(x, 1);
+ }
+ if(vexpand) {
grid->setRowStretch(y, 1);
- alignment = 0;
- } else {
- grid->setRowStretch(y, 0);
}
- int gwidth = layout.gridwidth > 0 ? layout.gridwidth : 1;
+ Qt::Alignment alignment = 0;
+ if(!hfill) {
+ alignment = Qt::AlignLeft;
+ }
+ if(!vfill) {
+ alignment = Qt::AlignTop;
+ }
+
+ int colspan = layout.colspan > 0 ? layout.colspan : 1;
+ int rowspan = layout.rowspan > 0 ? layout.rowspan : 1;
+
+ grid->addWidget(widget, y, x, rowspan, colspan, alignment);
+
+ if(x > max_x) {
+ max_x = x;
+ }
+ if(y > max_y) {
+ max_y = y;
+ }
- grid->addWidget(widget, y, x, 1, gwidth, alignment);
- x += gwidth;
+ x += colspan;
ui_reset_layout(layout);
current = widget;
}
-UIWIDGET ui_grid(UiObject *obj) {
- return ui_grid_sp(obj, 0, 0, 0);
+void UiGridContainer::end() {
+ if(!col_expanding) {
+ QSpacerItem *filler = new QSpacerItem(0, 0);
+ x = max_x + 1;
+ grid->setColumnStretch(x, 1);
+ grid->addItem(filler, 0, x, 1, 1, 0);
+ }
+ if(!row_expanding) {
+ QSpacerItem *filler = new QSpacerItem(0, 0);
+ y++;
+ grid->setRowStretch(y, 1);
+ grid->addItem(filler, y, 0, 1, 1, 0);
+ }
}
-UIWIDGET ui_grid_sp(UiObject *obj, int margin, int columnspacing, int rowspacing) {
- UiContainer *ct = uic_get_current_container(obj);
+UIEXPORT UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs args) {
+ UiContainerPrivate *ctn = (UiContainerPrivate*)ui_obj_container(obj);
+ UI_APPLY_LAYOUT(ctn->layout, args);
+
QWidget *widget = new QWidget();
QGridLayout *grid = new QGridLayout();
widget->setLayout(grid);
- ct->add(widget, true);
+ ctn->add(widget, true);
- UiObject *newobj = uic_object_new(obj, widget);
- newobj->container = new UiGridContainer(grid, margin, columnspacing, rowspacing);
- uic_obj_add(obj, newobj);
+ ui_container_add(obj, new UiGridContainer(
+ grid,
+ args.margin,
+ args.columnspacing,
+ args.rowspacing,
+ args.def_hexpand,
+ args.def_vexpand,
+ args.def_hfill,
+ args.def_vfill));
return widget;
}
-/* -------------------- UiTabViewContainer -------------------- */
-UiTabViewContainer::UiTabViewContainer(QTabWidget* tabwidget) {
- this->current = NULL;
- this->menu = NULL;
- this->tabwidget = tabwidget;
-}
+/* -------------------- Container Helper Functions -------------------- */
-void UiTabViewContainer::add(QWidget* widget, bool fill) {
- QString str = QString::fromUtf8(layout.label);
- tabwidget->addTab(widget, str);
+void ui_container_begin_close(UiObject *obj) {
+ obj->container_end->close = true;
}
-
-/* -------------------- UiStackContainer -------------------- */
-
-UiStackContainer::UiStackContainer(QStackedWidget *stack) {
- this->stack = stack;
-}
-
-void UiStackContainer::add(QWidget* widget, bool fill) {
- stack->addWidget(widget);
- current = widget;
-}
-
-UIWIDGET ui_tabview(UiObject *obj) {
- QStackedWidget *tabwidget = new QStackedWidget();
-
- UiContainer *ct = uic_get_current_container(obj);
- ct->add(tabwidget, true);
-
- UiObject *tabviewobj = uic_object_new(obj, tabwidget);
- tabviewobj->container = new UiStackContainer(tabwidget);
- uic_obj_add(obj, tabviewobj);
-
- return tabwidget;
-}
-
-void ui_tab(UiObject *obj, char *title) {
- UiContainer *ct = uic_get_current_container(obj);
- ct->layout.label = title;
- ui_vbox(obj);
-}
-
-void ui_select_tab(UIWIDGET tabview, int tab) {
- QStackedWidget *w = (QStackedWidget*)tabview;
- w->setCurrentIndex(tab);
-}
-
-
-/* -------------------- UiSidebarContainer -------------------- */
-
-UiSidebarContainer::UiSidebarContainer(QSplitter *splitter) {
- this->splitter = splitter;
-}
-
-UIWIDGET ui_sidebar(UiObject *obj) {
- QSplitter *splitter = new QSplitter(Qt::Horizontal);
- UiContainer *ct = uic_get_current_container(obj);
- ct->add(splitter, true);
-
- UiObject *left = uic_object_new(obj, splitter);
- left->container = new UiSidebarContainer(splitter);
-
- UiObject *right = uic_object_new(obj, splitter);
- right->container = new UiSidebarContainer(splitter);
-
- uic_obj_add(obj, right);
- uic_obj_add(obj, left);
-
- return splitter;
-}
-
-void UiSidebarContainer::add(QWidget *widget, bool fill) {
- splitter->addWidget(widget);
-}
-
-
-/* -------------------- layout functions -------------------- */
-
-void ui_layout_fill(UiObject *obj, UiBool fill) {
- UiContainer *ct = uic_get_current_container(obj);
- ct->layout.fill = ui_bool2lb(fill);
-}
-
-void ui_layout_hexpand(UiObject *obj, UiBool expand) {
- UiContainer *ct = uic_get_current_container(obj);
- ct->layout.hexpand = expand;
+int ui_container_finish(UiObject *obj) {
+ if(obj->container_end->close) {
+ UiContainerPrivate *ctn = (UiContainerPrivate*)obj->container_end->container;
+ ctn->end();
+ ui_end_new(obj);
+ return 0;
+ }
+ return 1;
}
-void ui_layout_vexpand(UiObject *obj, UiBool expand) {
- UiContainer *ct = uic_get_current_container(obj);
- ct->layout.vexpand = expand;
-}
-void ui_layout_gridwidth(UiObject *obj, int width) {
- UiContainer *ct = uic_get_current_container(obj);
- ct->layout.gridwidth = width;
-}
+/*
+ * -------------------- Layout Functions --------------------
+ *
+ * functions for setting layout attributes for the current container
+ *
+ */
void ui_newline(UiObject *obj) {
- UiContainer *ct = uic_get_current_container(obj);
+ UiContainerPrivate *ct = ui_obj_container(obj);
ct->layout.newline = TRUE;
}
#define CONTAINER_H
#include "toolkit.h"
+#include "../ui/container.h"
#include "window.h"
#include <string.h>
#include <QStackedWidget>
#include <QSplitter>
+#define UI_APPLY_LAYOUT(layout, args) \
+ layout.fill = args.fill; \
+ layout.hexpand = args.hexpand; \
+ layout.vexpand = args.vexpand; \
+ layout.hfill = args.hfill; \
+ layout.vfill = args.vfill; \
+ layout.override_defaults = args.override_defaults; \
+ layout.colspan = args.colspan; \
+ layout.rowspan = args.rowspan
+
+#define ui_reset_layout(layout) memset(&(layout), 0, sizeof(UiLayout))
#define ui_lb2bool(b) ((b) == UI_LAYOUT_TRUE ? TRUE : FALSE)
#define ui_bool2lb(b) ((b) ? UI_LAYOUT_TRUE : UI_LAYOUT_FALSE)
-#define ui_reset_layout(layout) memset(&(layout), 0, sizeof(UiLayout))
-typedef struct UiLayout UiLayout;
+#define ui_obj_container(obj) (UiContainerPrivate*)((UiContainerX*)obj->container_end)->container
-enum UiLayoutBool {
+typedef enum UiLayoutBool {
UI_LAYOUT_UNDEFINED = 0,
UI_LAYOUT_TRUE,
UI_LAYOUT_FALSE,
-};
-typedef enum UiLayoutBool UiLayoutBool;
+} UiLayoutBool;
+typedef struct UiLayout UiLayout;
struct UiLayout {
- UiLayoutBool fill;
- bool newline;
- char *label;
- bool hexpand;
- bool vexpand;
- int gridwidth;
+ UiTri fill;
+ UiBool newline;
+ char *label;
+ UiBool hexpand;
+ UiBool vexpand;
+ UiBool hfill;
+ UiBool vfill;
+ UiBool override_defaults;
+ int width;
+ int colspan;
+ int rowspan;
};
-struct UiContainer {
+struct UiContainerPrivate {
UiLayout layout;
UIWIDGET current;
- QMenu *menu;
virtual void add(QWidget *widget, bool fill) = 0;
+ virtual void end() {}
};
-class UiBoxContainer : public UiContainer {
+class UiBoxContainer : public UiContainerPrivate {
public:
QBoxLayout *box;
bool hasStretchedWidget = false;
virtual void add(QWidget *widget, bool fill);
};
-class UiGridContainer : public UiContainer {
+class UiGridContainer : public UiContainerPrivate {
public:
QGridLayout *grid;
int x = 0;
int y = 0;
+ bool def_hexpand;
+ bool def_vexpand;
+ bool def_hfill;
+ bool def_vfill;
+ bool col_expanding = false;
+ bool row_expanding = false;
+ int max_x;
+ int max_y;
- UiGridContainer(QGridLayout *grid, int margin, int columnspacing, int rowspacing);
+ UiGridContainer(
+ QGridLayout *grid,
+ int margin,
+ int columnspacing,
+ int rowspacing,
+ bool def_hexpand,
+ bool def_vexpand,
+ bool def_hfill,
+ bool def_vfill);
virtual void add(QWidget *widget, bool fill);
+ virtual void end();
};
-class UiTabViewContainer : public UiContainer {
-public:
- QTabWidget *tabwidget;
-
- UiTabViewContainer(QTabWidget *tabwidget);
- virtual void add(QWidget *widget, bool fill);
-};
+void ui_container_add(UiObject *obj, UiContainerPrivate *ct);
-class UiStackContainer : public UiContainer {
-public:
- QStackedWidget *stack;
-
- UiStackContainer(QStackedWidget *stack);
- virtual void add(QWidget *widget, bool fill);
-};
-
-class UiSidebarContainer : public UiContainer {
-public:
- QSplitter *splitter;
-
- UiSidebarContainer(QSplitter *splitter);
- virtual void add(QWidget *widget, bool fill);
-};
#endif /* CONTAINER_H */
#include "container.h"
-DrawingArea::DrawingArea(UiObject *obj, ui_drawfunc cb, void *data) {
- object = obj;
- drawCallback = cb;
- userdata = data;
-}
-
-DrawingArea::~DrawingArea() {
-
-}
-
-void DrawingArea::paintEvent(QPaintEvent *event) {
- QPainter painter(this);
-
- UiQtGraphics g;
- g.g.width = this->width();
- g.g.height = this->height();
- g.painter = &painter;
-
- UiEvent ev;
- ev.obj = object;
- ev.window = object->window;
- ev.document = object->ctx->document;
- ev.eventdata = NULL;
- ev.intval = 0;
-
- drawCallback(&ev, &g.g, userdata);
-}
-
-
-
-UIWIDGET ui_drawingarea(UiObject *obj, ui_drawfunc f, void *userdata) {
- DrawingArea *widget = new DrawingArea(obj, f, userdata);
-
- UiContainer *ct = uic_get_current_container(obj);
- ct->add(widget, true);
-
- return widget;
-}
-
-void ui_drawingarea_mousehandler(UiObject *obj, UIWIDGET widget, ui_callback f, void *u) {
-
-}
-
-void ui_drawingarea_getsize(UIWIDGET drawingarea, int *width, int *height) {
-
-}
-
-void ui_drawingarea_redraw(UIWIDGET drawingarea) {
-
-}
-
-
-/* -------------------- text layout functions -------------------- */
-
-UiTextLayout* ui_text(UiGraphics *g) {
- UiTextLayout *textlayout = new UiTextLayout();
- return textlayout;
-}
-
-void ui_text_free(UiTextLayout *text) {
- delete text;
-}
-
-void ui_text_setstring(UiTextLayout *layout, char *str) {
- layout->text.setText(QString::fromUtf8(str));
-}
-
-void ui_text_setstringl(UiTextLayout *layout, char *str, int len) {
- layout->text.setText(QString::fromUtf8(str, len));
-}
-
-void ui_text_setfont(UiTextLayout *layout, char *font, int size) {
- layout->font = QFont(QString::fromUtf8(font), size);
-}
-
-void ui_text_getsize(UiTextLayout *layout, int *width, int *height) {
- QSizeF size = layout->text.size();
- *width = (int)size.width();
- *height = (int)size.height();
-}
-
-void ui_text_setwidth(UiTextLayout *layout, int width) {
- layout->text.setTextWidth((qreal)width);
-}
-
-
-/* -------------------- drawing functions -------------------- */
-
-void ui_graphics_color(UiGraphics *g, int red, int green, int blue) {
- UiQtGraphics *gr = (UiQtGraphics*)g;
- gr->color = QColor(red, green, blue);
- gr->painter->setPen(gr->color);
-}
-
-void ui_draw_line(UiGraphics *g, int x1, int y1, int x2, int y2) {
- UiQtGraphics *gr = (UiQtGraphics*)g;
-
- gr->painter->drawLine(x1, y1, x2, y2);
-}
-
-void ui_draw_rect(UiGraphics *g, int x, int y, int w, int h, int fill) {
- UiQtGraphics *gr = (UiQtGraphics*)g;
-
- QRect rect(x, y, w, h);
- if(fill) {
- gr->painter->fillRect(rect, gr->color);
-
- } else {
- gr->painter->drawRect(rect);
- }
-}
-
-void ui_draw_text(UiGraphics *g, int x, int y, UiTextLayout *text) {
- UiQtGraphics *gr = (UiQtGraphics*)g;
-
- gr->painter->setFont(text->font);
- gr->painter->drawStaticText(x, y, text->text);
-}
#include <QColor>
#include <QStaticText>
-typedef struct UiQtGraphics {
- UiGraphics g;
- QPainter *painter;
- QColor color;
-} UiXlibGraphics;
-
-struct UiTextLayout {
- QStaticText text;
- QFont font;
-};
-
-
-class DrawingArea : public QWidget {
- Q_OBJECT
-
- UiObject *object;
- ui_drawfunc drawCallback;
- void *userdata;
-
-public:
- DrawingArea(UiObject *obj, ui_drawfunc cb, void *data);
- ~DrawingArea();
-
- virtual void paintEvent(QPaintEvent * event);
-};
#endif /* GRAPHICS_H */
#include "label.h"
#include "container.h"
#include "toolkit.h"
+#include "ui/display.h"
-UIWIDGET ui_label(UiObject *obj, char *label) {
- QString str = QString::fromUtf8(label);
+
+UIWIDGET ui_label_create(UiObject* obj, UiLabelArgs args) {
+ UiContainerPrivate *ctn = ui_obj_container(obj);
+ UI_APPLY_LAYOUT(ctn->layout, args);
+
+ QString str = QString::fromUtf8(args.label);
QLabel *widget = new QLabel(str);
- UiContainer *ct = uic_get_current_container(obj);
- ct->add(widget, false);
+ Qt::AlignmentFlag align = Qt::AlignCenter;
+ if(args.align == UI_ALIGN_LEFT) {
+ align = Qt::AlignLeft;
+ } else if(args.align == UI_ALIGN_RIGHT) {
+ align = Qt::AlignRight;
+ }
+ widget->setAlignment(align);
+
+ ctn->add(widget, false);
return widget;
}
-UIWIDGET ui_space(UiObject *obj) {
- // TODO: maybe there is a better widget for this purpose
- QLabel *widget = new QLabel();
-
- UiContainer *ct = uic_get_current_container(obj);
- ct->add(widget, true);
-
- return widget;
+UIWIDGET ui_llabel_create(UiObject* obj, UiLabelArgs args) {
+ args.align = UI_ALIGN_LEFT;
+ return ui_label_create(obj, args);
+}
+
+UIWIDGET ui_rlabel_create(UiObject* obj, UiLabelArgs args) {
+ args.align = UI_ALIGN_RIGHT;
+ return ui_label_create(obj, args);
}
#include "menu.h"
#include "toolkit.h"
#include "../common/context.h"
+#include "../common/menu.h"
#include "../ui/properties.h"
#include "../ui/window.h"
#include "stock.h"
#include "container.h"
-static UcxList *menus;
-static UcxList *current;
-/* -------------------------- UiMenu -------------------------- */
+static ui_menu_add_f createMenuItem[] = {
+ /* UI_MENU */ add_menu_widget,
+ /* UI_MENU_ITEM */ add_menuitem_widget,
+ /* UI_MENU_CHECK_ITEM */ add_checkitem_widget,
+ /* UI_MENU_RADIO_ITEM */ add_radioitem_widget,
+ /* UI_MENU_ITEM_LIST */ add_menuitem_list_widget,
+ /* UI_MENU_CHECKITEM_LIST */ add_menuitem_list_widget,
+ /* UI_MENU_RADIOITEM_LIST */ add_menuitem_list_widget,
+ /* UI_MENU_SEPARATOR */ add_menuseparator_widget
+};
-UiMenu::UiMenu(char* label) {
- this->items = NULL;
- this->label = label;
-}
-
-void UiMenu::addMenuItem(UiMenuItemI* item) {
- items = ucx_list_append(items, item);
-}
-
-void UiMenu::addTo(UiObject *obj, QMenuBar *menubar, QMenu *menu) {
- QMenu *m = NULL;
- if(menubar) {
- m = menubar->addMenu(label);
- } else {
- m = menu->addMenu(label);
+/*
+ * create all menu child items
+ */
+static void add_menu_items(QMenu *parent, int i, UiMenu *menu, UiObject *obj) {
+ UiMenuItemI *it = menu->items_begin;
+ int index = 0;
+ while(it) {
+ createMenuItem[it->type](parent, index, it, obj);
+ it = it->next;
+ index++;
+ }
+}
+
+void add_menu_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj) {
+ UiMenu *m = (UiMenu*)item;
+ QMenu *menu = parent->addMenu(m->label);
+ add_menu_items(menu, i, m, obj);
+}
+
+static UiAction* create_action(
+ UiObject *obj,
+ const char *icon,
+ const char *label,
+ ui_callback callback,
+ void *userdata,
+ int *states)
+{
+ QString str = QString::fromUtf8(label);
+ UiAction *action = new UiAction(obj, str, callback, userdata);
+ if(icon) {
+ action->setIcon(QIcon::fromTheme(icon));
+ action->setIconVisibleInMenu(true);
}
- UCX_FOREACH(elm, items) {
- UiMenuItemI *item = (UiMenuItemI*)elm->data;
- item->addTo(obj, NULL, m);
+ if(states) {
+ size_t nstates = uic_group_array_size(states);
+ uic_add_group_widget_i(obj->ctx, action, (ui_enablefunc)ui_action_enable, states, nstates);
+ action->setEnabled(false);
}
+
+ return action;
}
-
-/* -------------------------- UiMenuItem -------------------------- */
-
-UiMenuItem::UiMenuItem(char* label, ui_callback f, void* userdata) {
- this->label = label;
- this->callback = f;
- this->userdata = userdata;
- this->groups = NULL;
-}
-
-void UiMenuItem::addGroup(int group) {
- groups = ucx_list_append(groups, (void*)(intptr_t)group);
-}
-
-void UiMenuItem::setCheckable(bool c) {
- checkable = c;
-}
-
-void UiMenuItem::addTo(UiObject *obj, QMenuBar *menubar, QMenu *menu) {
- QString str = QString::fromUtf8(label);
- UiAction *action = new UiAction(obj, str, callback, userdata);
- action->setCheckable(checkable);
- if(checkable) {
- action->setChecked(false);
- }
- menu->addAction(action);
+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->groups);
+ parent->addAction(action);
QObject::connect(action, SIGNAL(triggered()), action, SLOT(trigger()));
}
-
-/* -------------------------- UiStMenuItem -------------------------- */
-
-UiStMenuItem::UiStMenuItem(char* stockid, ui_callback f, void* userdata) {
- this->stockid = stockid;
- this->callback = f;
- this->userdata = userdata;
- this->groups = NULL;
-}
-
-void UiStMenuItem::addGroup(int group) {
- groups = ucx_list_append(groups, (void*)(intptr_t)group);
+void add_menuseparator_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj) {
+ parent->addSeparator();
}
-void UiStMenuItem::addTo(UiObject *obj, QMenuBar *menubar, QMenu *menu) {
- UiStockItem *stockItem = ui_get_stock_item(stockid);
+void add_checkitem_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj) {
+ UiMenuCheckItem *it = (UiMenuCheckItem*)item;
- QString str = QString::fromUtf8(stockItem->label);
- UiAction *action = new UiAction(obj, str, callback, userdata);
- action->setIcon(QIcon::fromTheme(stockItem->icon_name));
- action->setIconVisibleInMenu(true);
- menu->addAction(action);
- //UiEventWrapper *ev = new UiEventWrapper(callback, userdata);
- QObject::connect(action, SIGNAL(triggered()), action, SLOT(trigger()));
-}
-
-
-/* -------------------------- UiMenuSeparator -------------------------- */
-
-void UiMenuSeparator::addTo(UiObject* obj, QMenuBar* menubar, QMenu* menu) {
- menu->addSeparator();
-}
-
-
-/* -------------------------- UiCheckItemNV -------------------------- */
-
-UiCheckItemNV::UiCheckItemNV(char* label, char* varname) {
- this->label = label;
- this->varname = varname;
-}
-
-void UiCheckItemNV::addTo(UiObject* obj, QMenuBar* menubar, QMenu* menu) {
- QString str = QString::fromUtf8(label);
- UiAction *action = new UiAction(obj, str, NULL, NULL);
+ UiAction *action = create_action(obj, it->icon, it->label, it->callback, it->userdata, it->groups);
+ parent->addAction(action);
action->setCheckable(true);
- menu->addAction(action);
- QObject::connect(action, SIGNAL(triggered()), action, SLOT(trigger()));
+ action->prepare_event = ui_checkableaction_prepare_event;
- UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_INTEGER);
+ UiVar* var = uic_widget_var(obj->ctx, obj->ctx, NULL, it->varname, UI_VAR_INTEGER);
if(var) {
UiInteger *value = (UiInteger*)var->value;
- action->setChecked(value->value);
value->obj = action;
- value->get = ui_checkitem_get;
- value->set = ui_checkitem_set;
- value = 0;
- } else {
- // TODO: error
+ value->get = ui_checkableaction_get;
+ value->set = ui_checkableaction_set;
+
+ action->setChecked((bool)value->value);
}
+ action->var = var;
}
-
-/* -------------------------- UiAction -------------------------- */
-
-UiAction::UiAction(UiObject *obj, QString &label, ui_callback f, void* userdata) : QAction(label, NULL) {
- //QAction(label, NULL);
- this->obj = obj;
- this->callback = f;
- this->userdata = userdata;
-}
-
-void UiAction::trigger() {
- if(!callback) {
- return;
- }
+void add_radioitem_widget(QMenu *parent, int index, UiMenuItemI *item, UiObject *obj) {
+ UiMenuRadioItem *it = (UiMenuRadioItem*)item;
- UiEvent e;
- e.obj = obj;
- e.window = obj->window;
- e.document = obj->ctx->document;
- e.eventdata = NULL;
+ UiAction *action = create_action(obj, it->icon, it->label, it->callback, it->userdata, it->groups);
+ parent->addAction(action);
+ action->setCheckable(true);
+ action->prepare_event = ui_actiongroup_prepare_event;
- if(isCheckable()) {
- e.intval = isChecked();
+ UiVar* var = uic_widget_var(obj->ctx, obj->ctx, NULL, it->varname, UI_VAR_INTEGER);
+ if(var) {
+ UiInteger *value = (UiInteger*)var->value;
+ QActionGroup *group = (QActionGroup*)value->obj;
+ if(!group) {
+ group = new QActionGroup(parent);
+ value->obj = group;
+ }
+ group->addAction(action);
+ value->get = ui_actiongroup_get;
+ value->set = ui_actiongroup_set;
+ if(value->value != 0) {
+ ui_actiongroup_set(value, value->value);
+ }
+ }
+ action->var;
+}
+
+void ui_actiongroup_prepare_event(UiEvent *event, UiAction *action) {
+ if(action->var) {
+ UiInteger *value = (UiInteger*)action->var->value;
+ event->eventdata = value;
+ event->intval = value->get(value);
+ }
+}
+
+int64_t ui_actiongroup_get(UiInteger *value) {
+ QActionGroup *group = (QActionGroup*)value->obj;
+ auto actions = group->actions();
+ int i = 1;
+ foreach(const QAction *action, actions) {
+ if(action->isChecked()) {
+ value->value = i;
+ break;
+ }
+ i++;
+ }
+ return value->value;
+}
+
+void ui_actiongroup_set(UiInteger *value, int64_t i) {
+ QActionGroup *group = (QActionGroup*)value->obj;
+ auto actions = group->actions();
+ if(i > 0) {
+ if(i-1 < actions.size()) {
+ actions[i]->setEnabled(true);
+ }
+ value->value = i;
} else {
- e.intval = 0;
- }
-
- callback(&e, userdata);
-}
-
-
-void ui_menu(char *label) {
- // free current menu hierarchy
- ucx_list_free(current);
-
- // create menu
- UiMenu *menu = new UiMenu(label);
-
- current = ucx_list_prepend(NULL, menu);
- menus = ucx_list_append(menus, menu);
-}
-
-void ui_submenu(char *label) {
- UiMenu *menu = new UiMenu(label);
-
- // add submenu to current menu
- UiMenu *cm = (UiMenu*)current->data;
- cm->addMenuItem(menu);
-
- // set the submenu to current menu
- current = ucx_list_prepend(current, menu);
-}
-
-void ui_submenu_end() {
- if(ucx_list_size(current) < 2) {
- return;
- }
- current = ucx_list_remove(current, current);
- //UcxList *c = current;
-}
-
-
-void ui_menuitem(char *label, ui_callback f, void *userdata) {
- ui_menuitem_gr(label, f, userdata, -1);
-}
-
-void ui_menuitem_st(char *stockid, ui_callback f, void *userdata) {
- ui_menuitem_stgr(stockid, f, userdata, -1);
-}
-
-void ui_menuitem_gr(char *label, ui_callback f, void *userdata, ...) {
- if(!current) {
- return;
+ foreach(QAction *action, actions) {
+ action->setEnabled(false);
+ }
+ value->value = 0;
}
-
- UiMenuItem *item = new UiMenuItem(label, f, userdata);
-
- // add groups
- va_list ap;
- va_start(ap, userdata);
- int group;
- while((group = va_arg(ap, int)) != -1) {
- item->addGroup(group);
- }
- va_end(ap);
-
- UiMenu *cm = (UiMenu*)current->data;
- cm->addMenuItem(item);
}
-void ui_menuitem_stgr(char *stockid, ui_callback f, void *userdata, ...) {
- if(!current) {
- return;
- }
-
- UiStMenuItem *item = new UiStMenuItem(stockid, f, userdata);
-
- // add groups
- va_list ap;
- va_start(ap, userdata);
- int group;
- while((group = va_arg(ap, int)) != -1) {
- item->addGroup(group);
- }
- va_end(ap);
-
- UiMenu *cm = (UiMenu*)current->data;
- cm->addMenuItem(item);
-}
-
-void ui_menuseparator() {
- if(!current) {
- return;
- }
+void add_menuitem_list_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj) {
- UiMenuSeparator *item = new UiMenuSeparator();
- UiMenu *cm = (UiMenu*)current->data;
- cm->addMenuItem(item);
}
-void ui_checkitem(char *label, ui_callback f, void *userdata) {
- if(!current) {
- return;
- }
-
- UiMenuItem *item = new UiMenuItem(label, f, userdata);
- item->setCheckable(true);
-
- UiMenu *cm = (UiMenu*)current->data;
- cm->addMenuItem(item);
-}
-void ui_checkitem_nv(char *label, char *vname) {
- if(!current) {
+void ui_add_menus(UiObject *obj, QMainWindow *window) {
+ UiMenu *menus_begin = uic_get_menu_list();
+ if(menus_begin == NULL) {
return;
}
- UiCheckItemNV *item = new UiCheckItemNV(label, vname);
-
- UiMenu *cm = (UiMenu*)current->data;
- cm->addMenuItem(item);
-}
-
-void ui_menuitem_list(UiList *items, ui_callback f, void *userdata) {
-
-}
-
-void ui_add_menus(UiObject *obj, QMainWindow *window) {
QMenuBar *mb = window->menuBar();
- UCX_FOREACH(elm, menus) {
- UiMenu *menu = (UiMenu*)elm->data;
- menu->addTo(obj, mb, NULL);
+ UiMenu *ls = menus_begin;
+ while(ls) {
+ if(ls->item.type == UI_MENU) {
+ QMenu *menu = mb->addMenu(ls->label);
+ add_menu_items(menu, 0, ls, obj);
+ }
+ ls = (UiMenu*)ls->item.next;
}
}
-int ui_checkitem_get(UiInteger *i) {
- QAction *action = (QAction*)i->obj;
- i->value = action->isChecked();
- return i->value;
-}
-
-void ui_checkitem_set(UiInteger *i, int value) {
- QAction *action = (QAction*)i->obj;
- i->value = value;
- action->setChecked(value);
-}
-
-
-/*
- * widget menu functions
- */
-
-UiContextMenuHandler::UiContextMenuHandler(QWidget *widget, QMenu* menu) {
- this->widget = widget;
- this->menu = menu;
-}
-
-void UiContextMenuHandler::contextMenuEvent(const QPoint & pos) {
- menu->popup(widget->mapToGlobal(pos));
-}
-UIMENU ui_contextmenu(UiObject *obj) {
- UiContainer *ct = uic_get_current_container(obj);
- return ui_contextmenu_w(obj, ct->current);
-}
-
-UIMENU ui_contextmenu_w(UiObject *obj, UIWIDGET widget) {
- UiContainer *ct = uic_get_current_container(obj);
-
- QMenu *menu = new QMenu(widget);
- widget->setContextMenuPolicy(Qt::CustomContextMenu);
-
- UiContextMenuHandler *handler = new UiContextMenuHandler(widget, menu);
- QObject::connect(
- widget,
- SIGNAL(customContextMenuRequested(QPoint)),
- handler,
- SLOT(contextMenuEvent(QPoint)));
-
- ct->menu = menu;
-
- return menu;
-}
-
-void ui_contextmenu_popup(UIMENU menu) {
-
-}
-
-void ui_widget_menuitem(UiObject *obj, char *label, ui_callback f, void *userdata) {
- ui_widget_menuitem_gr(obj, label, f, userdata, -1);
-}
-
-void ui_widget_menuitem_gr(UiObject *obj, char *label, ui_callback f, void *userdata, ...) {
- UiContainer *ct = uic_get_current_container(obj);
- if(!ct->menu) {
- return;
+void ui_checkableaction_prepare_event(UiEvent *event, UiAction *action) {
+ if(action->var) {
+ event->eventdata = action->var->value;
}
-
- // add groups
- UcxList *groups = NULL;
- va_list ap;
- va_start(ap, userdata);
- int group;
- while((group = va_arg(ap, int)) != -1) {
- ucx_list_append(groups, (void*)(intptr_t)group);
- }
- va_end(ap);
-
- // create menuitem
- QString str = QString::fromUtf8(label);
- UiAction *action = new UiAction(obj, str, f, userdata);
- ct->menu->addAction(action);
- QObject::connect(action, SIGNAL(triggered()), action, SLOT(trigger()));
+ event->intval = action->isChecked();
}
-void ui_widget_menuitem_st(UiObject *obj, char *stockid, ui_callback f, void *userdata) {
- ui_widget_menuitem_stgr(obj, stockid, f, userdata, -1);
+int64_t ui_checkableaction_get(UiInteger *value) {
+ UiAction *action= (UiAction*)value->obj;
+ value->value = action->isChecked();
+ return value->value;
}
-void ui_widget_menuitem_stgr(UiObject *obj, char *stockid, ui_callback f, void *userdata, ...) {
- UiContainer *ct = uic_get_current_container(obj);
- if(!ct->menu) {
- return;
- }
-
- // add groups
- UcxList *groups = NULL;
- va_list ap;
- va_start(ap, userdata);
- int group;
- while((group = va_arg(ap, int)) != -1) {
- ucx_list_append(groups, (void*)(intptr_t)group);
+void ui_checkableaction_set(UiInteger *value, int64_t i) {
+ UiAction *action = (UiAction*)value->obj;
+ value->value = i;
+ if(i != 0) {
+ action->setChecked((bool)i);
}
- va_end(ap);
-
- // create menuitem
- UiStockItem *stockItem = ui_get_stock_item(stockid);
-
- QString str = QString::fromUtf8(stockItem->label);
- UiAction *action = new UiAction(obj, str, f, userdata);
- action->setIcon(QIcon::fromTheme(stockItem->icon_name));
- action->setIconVisibleInMenu(true);
- ct->menu->addAction(action);
- QObject::connect(action, SIGNAL(triggered()), action, SLOT(trigger()));
}
+
#define MENU_H
#include "../ui/menu.h"
-#include <ucx/list.h>
+#include "../common/menu.h"
+
+#include "toolkit.h"
#include <QMainWindow>
#include <QMenu>
#include <QMenuBar>
#include <QContextMenuEvent>
-class UiMenuItemI {
-public:
- virtual void addTo(UiObject *obj, QMenuBar *menubar, QMenu *menu) = 0;
-};
-
-class UiMenu : public UiMenuItemI {
-public:
-
- UcxList *items;
- char *label;
-
- UiMenu(char *label);
-
- void addMenuItem(UiMenuItemI *item);
-
- virtual void addTo(UiObject *obj, QMenuBar *menubar, QMenu *menu);
-};
-
-class UiMenuItem : public UiMenuItemI {
- char *label;
- ui_callback callback;
- void *userdata;
- UcxList *groups;
- bool checkable = false;
-
-public:
- UiMenuItem(char *label, ui_callback f, void *userdata);
- void addGroup(int group);
- void setCheckable(bool c);
-
- virtual void addTo(UiObject *obj, QMenuBar *menubar, QMenu *menu);
-};
-
-class UiStMenuItem : public UiMenuItemI {
- char *stockid;
- ui_callback callback;
- void *userdata;
- UcxList *groups;
-
-public:
- UiStMenuItem(char *stockid, ui_callback f, void *userdata);
- void addGroup(int group);
-
- virtual void addTo(UiObject *obj, QMenuBar *menubar, QMenu *menu);
-};
-
-class UiMenuSeparator : public UiMenuItemI {
-public:
- virtual void addTo(UiObject *obj, QMenuBar *menubar, QMenu *menu);
-};
-
-class UiCheckItemNV : public UiMenuItemI {
- char *label;
- char *varname;
-
-public:
- UiCheckItemNV(char *label, char *varname);
- virtual void addTo(UiObject *obj, QMenuBar *menubar, QMenu *menu);
-};
-
-
-class UiAction : public QAction {
- Q_OBJECT
-
- UiObject *obj;
- ui_callback callback;
- void *userdata;
-
-public:
- UiAction(UiObject *obj, QString &label, ui_callback f, void *userdata);
+void ui_add_menus(UiObject *obj, QMainWindow *window);
-private slots:
- void trigger();
-};
+typedef void(*ui_menu_add_f)(QMenu*, int, UiMenuItemI*, UiObject*);
-void ui_add_menus(UiObject *obj, QMainWindow *window);
+void add_menu_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj);
+void add_menuitem_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj);
+void add_menuseparator_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj);
+void add_checkitem_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj);
+void add_radioitem_widget(QMenu *parent, int index, UiMenuItemI *item, UiObject *obj);
+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);
-extern "C" int ui_checkitem_get(UiInteger *i);
-extern "C" void ui_checkitem_set(UiInteger *i, int value);
+void ui_checkableaction_prepare_event(UiEvent *event, UiAction *action);
+int64_t ui_checkableaction_get(UiInteger *value);
+void ui_checkableaction_set(UiInteger *value, int64_t i);
-class UiContextMenuHandler : public QObject {
- Q_OBJECT
-
- QWidget *widget;
- QMenu *menu;
-
-public:
- UiContextMenuHandler(QWidget *widget, QMenu *menu);
-
-public slots:
- void contextMenuEvent(const QPoint & pos);
-};
+void ui_actiongroup_prepare_event(UiEvent *event, UiAction *action);
+int64_t ui_actiongroup_get(UiInteger *value);
+void ui_actiongroup_set(UiInteger *value, int64_t i);
#endif /* MENU_H */
#include "model.h"
-UiListSelection* listSelection(QItemSelectionModel *s) {
- UiListSelection *selection = new UiListSelection();
-
- QModelIndexList list = s->selectedRows();
- selection->count = list.count();
- if(selection->count > 0) {
- selection->rows = new int[selection->count];
- }
-
- QModelIndex index;
- int i=0;
- foreach(index, list) {
- selection->rows[i] = index.row();
- i++;
- }
- return selection;
-}
-
-ListModel::ListModel(UiObject* obj, QListView* view, UiListPtr* list, ui_model_getvalue_f getvalue, ui_callback f, void* userdata) {
- this->obj = obj;
- this->view = view;
- this->list = list;
- this->getvalue = getvalue;
- this->callback = f;
- this->userdata = userdata;
-}
-
-int ListModel::rowCount(const QModelIndex& parent) const {
- return list->list->count(list->list);
-}
-
-QVariant ListModel::data(const QModelIndex &index, int role) const {
- if(role == Qt::DisplayRole) {
- UiList *ls = list->list;
- void *rowData = ls->get(ls, index.row());
- if(rowData && getvalue) {
- void *value = getvalue(rowData, 0);
- return QString::fromUtf8((char*)value);
- }
- }
- return QVariant();
-}
-
-void ListModel::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) {
- UiListSelection *selection = listSelection(view->selectionModel());
-
- UiEvent e;
- e.obj = obj;
- e.window = obj->window;
- e.document = obj->ctx->document;
- e.eventdata = selection;
- e.intval = selection->count > 0 ? selection->rows[0] : -1;
- callback(&e, userdata);
-
- if(selection->count > 0) {
- delete selection->rows;
- }
- delete selection;
-}
-
-TableModel::TableModel(UiObject *obj, QTreeView *view, UiListPtr *list, UiModelInfo *info) {
- this->obj = obj;
- this->list = list;
- this->info = info;
- this->view = view;
-}
-
-int TableModel::rowCount(const QModelIndex &parent) const {
- return list->list->count(list->list);
-}
-
-int TableModel::columnCount(const QModelIndex &parent) const {
- return info->columns;
-}
-
-QVariant TableModel::data(const QModelIndex &index, int role) const {
- if(role == Qt::DisplayRole) {
- UiList *ls = list->list;
- void *rowData = ls->get(ls, index.row());
- if(rowData && info->getvalue) {
- void *value = info->getvalue(rowData, index.column());
- switch(info->types[index.column()]) {
- case UI_STRING: {
- return QString::fromUtf8((char*)value);
- }
- case UI_INTEGER: {
- int *intptr = (int*)value;
- return QVariant(*intptr);
- }
- }
- }
- }
- return QVariant();
-}
-
-QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const {
- if(role == Qt::DisplayRole) {
- char *label = info->titles[section];
- return QString::fromUtf8(label);
- }
- return QVariant();
-}
-
-void TableModel::update() {
- emit dataChanged(QModelIndex(),QModelIndex());
-}
-
-void TableModel::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) {
- UiListSelection *selection = listSelection(view->selectionModel());
-
- UiEvent e;
- e.obj = obj;
- e.window = obj->window;
- e.document = obj->ctx->document;
- e.eventdata = selection;
- e.intval = selection->count > 0 ? selection->rows[0] : -1;
- info->selection(&e, info->userdata);
-
- if(selection->count > 0) {
- delete selection->rows;
- }
- delete selection;
-}
-
-void TableModel::activate(const QModelIndex &) {
- UiListSelection *selection = listSelection(view->selectionModel());
-
- UiEvent e;
- e.obj = obj;
- e.window = obj->window;
- e.document = obj->ctx->document;
- e.eventdata = selection;
- e.intval = selection->count > 0 ? selection->rows[0] : -1;
- info->activate(&e, info->userdata);
-
- if(selection->count > 0) {
- delete selection->rows;
- }
- delete selection;
-}
#include <QAbstractItemModel>
#include <QItemSelectionModel>
-class ListModel : public QAbstractListModel {
- Q_OBJECT
-
- UiObject *obj;
- UiListPtr *list;
- ui_model_getvalue_f getvalue;
- ui_callback callback;
- void *userdata;
- QListView *view;
-
-public:
- ListModel(UiObject *obj, QListView *view, UiListPtr *list, ui_model_getvalue_f getvalue, ui_callback f, void *userdata);
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
-
-public slots:
- void selectionChanged(
- const QItemSelection & selected,
- const QItemSelection & deselected);
-};
-
-class TableModel : public QAbstractTableModel {
- Q_OBJECT
-
- UiObject *obj;
- UiListPtr *list;
- UiModelInfo *info;
- QTreeView *view;
-public:
- TableModel(UiObject *obj, QTreeView *view, UiListPtr *list, UiModelInfo *info);
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- int columnCount(const QModelIndex &parent = QModelIndex()) const;
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
- QVariant headerData(int section, Qt::Orientation orientation, int role) const;
-
- void update();
-
-public slots:
- void selectionChanged(
- const QItemSelection & selected,
- const QItemSelection & deselected);
- void activate(const QModelIndex &);
-};
-
-UiListSelection* listSelection(QItemSelectionModel *s);
#endif /* MODEL_H */
--- /dev/null
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2025 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.
+#
+
+TARGET = uitk
+TEMPLATE = lib
+CONFIG += staticlib warn_off debug
+DESTDIR = ../build/lib
+MOC_DIR = ../build/ui/qt
+OBJECTS_DIR = ../build/ui/qt
+
+QT += core gui widgets
+
+DEFINES += UI_QT5
+
+SOURCES += toolkit.cpp
+SOURCES += window.cpp
+SOURCES += menu.cpp
+SOURCES += toolbar.cpp
+SOURCES += stock.cpp
+SOURCES += container.cpp
+SOURCES += text.cpp
+SOURCES += model.cpp
+SOURCES += tree.cpp
+SOURCES += button.cpp
+SOURCES += label.cpp
+SOURCES += graphics.cpp
+
+HEADERS += toolkit.h
+HEADERS += window.h
+HEADERS += menu.h
+HEADERS += toolbar.h
+HEADERS += stock.h
+HEADERS += container.h
+HEADERS += text.h
+HEADERS += model.h
+HEADERS += tree.h
+HEADERS += button.h
+HEADERS += label.h
+HEADERS += graphics.h
+
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <ucx/map.h>
#include "stock.h"
#include "../ui/properties.h"
-static UcxMap *stock_items;
-void ui_stock_init() {
- stock_items = ucx_map_new(64);
-
- ui_add_stock_item(UI_STOCK_NEW, "New", "document-new");
- ui_add_stock_item(UI_STOCK_OPEN, "Open", "document-open");
- ui_add_stock_item(UI_STOCK_SAVE, "Save", "document-save");
- ui_add_stock_item(UI_STOCK_SAVE_AS, "Save as ...", "document-save-as");
- ui_add_stock_item(UI_STOCK_REVERT_TO_SAVED, "Revert to saved", "document-revert");
- ui_add_stock_item(UI_STOCK_CLOSE, "Close", "window-close");
- ui_add_stock_item(UI_STOCK_UNDO, "Undo", "edit-undo");
- ui_add_stock_item(UI_STOCK_REDO, "Redo", "edit-redo");
- ui_add_stock_item(UI_STOCK_GO_BACK, "Back", "go-previous");
- ui_add_stock_item(UI_STOCK_GO_FORWARD, "Forward", "go-next");
- ui_add_stock_item(UI_STOCK_CUT, "Cut", "edit-cut");
- ui_add_stock_item(UI_STOCK_COPY, "Copy", "edit-copy");
- ui_add_stock_item(UI_STOCK_PASTE, "Paste", "edit-paste");
- ui_add_stock_item(UI_STOCK_DELETE, "Delete", "edit-delete");
-}
-
-void ui_add_stock_item(char *id, char *label, char *icon) {
- UiStockItem *item = new UiStockItem(label, icon);
- ucx_map_cstr_put(stock_items, id, item);
-}
-
-UiStockItem* ui_get_stock_item(char *id) {
- UiStockItem *item = (UiStockItem*)ucx_map_cstr_get(stock_items, id);
- if(item) {
- char *label = uistr_n(id);
- if(label) {
- item->label = label;
- }
- }
- return item;
-}
-
-
-UiStockItem::UiStockItem(char* label, char* icon_name) {
- this->label = label;
- this->icon_name = icon_name;
-}
#include "../ui/stock.h"
-class UiStockItem {
-public:
-
- char *label;
- char *icon_name;
-
- UiStockItem(char *label, char *icon_name);
-};
-void ui_stock_init();
-void ui_add_stock_item(char *id, char *label, char *icon);
-UiStockItem* ui_get_stock_item(char *id);
-
#endif /* STOCK_H */
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
- * Copyright 2014 Olaf Wintermann. All rights reserved.
+ * Copyright 2025 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:
#include "../common/context.h"
#include "../common/document.h"
-UIWIDGET ui_textarea(UiObject *obj, UiText *value) {
- QTextDocument *txtdoc = value && value->obj ? (QTextDocument*)value->obj : new QTextDocument();
-
- if(value) {
- if(value->value && value->obj) {
- QString str = QString::fromUtf8(value->value);
- txtdoc->setPlainText(str);
+/*
+ * Gets or creates a QTextDocument for the UiText value and initializes it
+ * with the UiText string value
+ */
+static QTextDocument* get_or_create_doc(UiText *value) {
+ QTextDocument *document = nullptr;
+ if(value->data1) {
+ document = (QTextDocument*)value->data1;
+ } else {
+ document = new QTextDocument();
+ if(value->value.ptr) {
+ QString str = QString::fromUtf8(value->value.ptr);
+ document->setPlainText(str);
}
+ }
+
+ if(value->value.free) {
+ value->value.free(value->value.ptr);
+ }
+ value->value.ptr = NULL;
+ value->value.free = NULL;
+
+ return document;
+}
+
+UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs args) {
+ UiContainerPrivate *ctn = ui_obj_container(obj);
+ UI_APPLY_LAYOUT(ctn->layout, args);
+
+ QTextEdit *textarea = new QTextEdit();
+ ctn->add(textarea, true);
+
+ QTextDocument *document = nullptr;
+
+ UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.value, args.varname, UI_VAR_STRING);
+ if(var) {
+ UiText *value = (UiText*)var->value;
+
+ document = get_or_create_doc(value);
+ value->save = ui_textarea_save;
+ value->restore = ui_textarea_restore;
+ value->destroy = ui_textarea_text_destroy;
value->get = ui_textarea_get;
value->set = ui_textarea_set;
value->getsubstr = ui_textarea_getsubstr;
value->insert = ui_textarea_insert;
value->setposition = ui_textarea_setposition;
value->position = ui_textarea_position;
+ value->setselection = ui_textarea_setselection;
value->selection = ui_textarea_selection;
value->length = ui_textarea_length;
value->remove = ui_textarea_remove;
- value->obj = txtdoc;
- value->value = NULL;
+ value->obj = textarea;
+ value->data1 = document;
+ } else {
+ document = new QTextDocument();
}
- UiContainer *ct = uic_get_current_container(obj);
- QTextEdit *textedit = new QTextEdit();
- textedit->setDocument(txtdoc);
- ct->add(textedit, true);
+ textarea->setDocument(document);
- return textedit;
+ return textarea;
}
-UIWIDGET ui_textarea_nv(UiObject *obj, char *varname) {
- UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_TEXT);
- if(var) {
- UiText *value = (UiText*)var->value;
- return ui_textarea(obj, value);
- } else {
- // TODO: error
- }
- return NULL;
+void ui_textarea_save(UiText *text) {
+ // NOOP
+}
+
+void ui_textarea_restore(UiText *text) {
+ QTextEdit *textarea = (QTextEdit*)text->obj;
+ QTextDocument *document = get_or_create_doc(text);
+ textarea->setDocument(document);
}
+void ui_textarea_text_destroy(UiText *text) {
+ QTextDocument *document = (QTextDocument*)text->data1;
+ if(document) {
+ delete document;
+ }
+}
char* ui_textarea_get(UiText *text) {
- if(text->value) {
- free(text->value);
+ // clean previous value
+ if(text->value.free) {
+ text->value.free(text->value.ptr);
}
- QTextDocument *doc = (QTextDocument*)text->obj;
+ // get string
+ QTextDocument *doc = (QTextDocument*)text->data1;
QString str = doc->toPlainText();
- QByteArray array = str.toLocal8Bit();
+ QByteArray array = str.toUtf8();
const char *cstr = array.constData();
- if(text->value) {
- free(text->value);
- }
- text->value = strdup(cstr);
- return text->value;
+ // store a copy of the string in the UiText value
+ text->value.ptr = strdup(cstr);
+ text->value.free = free;
+ return text->value.ptr;
}
-void ui_textarea_set(UiText *text, char *str) {
- // set text
- QTextDocument *doc = (QTextDocument*)text->obj;
+void ui_textarea_set(UiText *text, const char *str) {
+ if(text->value.free) {
+ text->value.free(text->value.ptr);
+ }
+ text->value.ptr = NULL;
+ text->value.free = NULL;
+
+ QTextDocument *doc = (QTextDocument*)text->data1;
QString qstr = QString::fromUtf8(str);
doc->setPlainText(qstr);
- // cleanup
- if(text->value) {
- free(text->value);
- }
- text->value = NULL;
}
char* ui_textarea_getsubstr(UiText *text, int begin, int end) {
- QTextDocument *doc = (QTextDocument*)text->obj;
- return NULL; // TODO
+ QTextDocument *doc = (QTextDocument*)text->data1;
+ QTextCursor cursor(doc);
+ cursor.setPosition(begin, QTextCursor::MoveAnchor);
+ cursor.setPosition(end, QTextCursor::KeepAnchor);
+ QString str = cursor.selectedText();
+ QByteArray bytes = str.toUtf8();
+ const char *cstr = bytes.constData();
+ return cstr ? strdup(cstr) : NULL;
}
void ui_textarea_insert(UiText *text, int pos, char *str) {
- QTextDocument *doc = (QTextDocument*)text->obj;
+ QTextDocument *doc = (QTextDocument*)text->data1;
+ QTextCursor cursor(doc);
+ cursor.setPosition(pos);
+ cursor.insertText(str);
}
void ui_textarea_setposition(UiText *text, int pos) {
- // TODO
+ QTextEdit *textview = (QTextEdit*)text->obj;
+ QTextCursor cursor = textview->textCursor();
+ cursor.setPosition(pos);
+ textview->setTextCursor(cursor);
}
int ui_textarea_position(UiText *text) {
- QTextDocument *doc = (QTextDocument*)text->obj;
- return 0; // TODO
+ QTextEdit *textview = (QTextEdit*)text->obj;
+ QTextCursor cursor = textview->textCursor();
+ return cursor.position();
}
void ui_textarea_selection(UiText *text, int *begin, int *end) {
- QTextDocument *doc = (QTextDocument*)text->obj;
+ QTextEdit *textview = (QTextEdit*)text->obj;
+ QTextCursor cursor = textview->textCursor();
+ if(cursor.hasSelection()) {
+ if(begin) {
+ *begin = cursor.selectionStart();
+ }
+ if(end) {
+ *end = cursor.selectionEnd();
+ }
+ }
+}
+
+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);
}
int ui_textarea_length(UiText *text) {
- QTextDocument *doc = (QTextDocument*)text->obj;
- return 0; // TODO
+ QTextDocument *doc = (QTextDocument*)text->data1;
+ return doc->characterCount();
}
void ui_textarea_remove(UiText *text, int begin, int end) {
- QTextDocument *doc = (QTextDocument*)text->obj;
+ // TODO
}
+/* ------------------------------ TextField ------------------------------ */
-/* ------------------- TextField ------------------- */
-
-UIWIDGET ui_textfield(UiObject *obj, UiString *value) {
+static UIWIDGET create_textfield(UiObject *obj, UiTextFieldArgs args, bool password, bool frameless) {
+ UiContainerPrivate *ctn = ui_obj_container(obj);
+ UI_APPLY_LAYOUT(ctn->layout, args);
+
QLineEdit *textfield = new QLineEdit();
+ ctn->add(textfield, false);
- UiContainer *ct = uic_get_current_container(obj);
- ct->add(textfield, false);
+ if(password) {
+ textfield->setEchoMode(QLineEdit::Password);
+ }
- if(value) {
- if(value->value) {
- QString str = QString::fromUtf8(value->value);
+ UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.value, args.varname, UI_VAR_STRING);
+ if(var) {
+ UiString *value = (UiString*)var->value;
+ if(value->value.ptr) {
+ QString str = QString::fromUtf8(value->value.ptr);
textfield->setText(str);
- free(value->value);
- value->value = NULL;
+ if(value->value.free) {
+ value->value.free(value->value.ptr);
+ }
+ value->value.ptr = NULL;
}
+
value->set = ui_textfield_set;
value->get = ui_textfield_get;
value->obj = textfield;
return textfield;
}
-UIWIDGET ui_textfield_nv(UiObject *obj, char *varname) {
- UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_STRING);
- if(var) {
- UiString *value = (UiString*)var->value;
- return ui_textfield(obj, value);
- } else {
- // TODO: error
- }
- return NULL;
+UIWIDGET ui_textfield_create(UiObject *obj, UiTextFieldArgs args) {
+ return create_textfield(obj, args, false, false);
+}
+
+UIWIDGET ui_frameless_textfield_create(UiObject* obj, UiTextFieldArgs args) {
+ return create_textfield(obj, args, false, true);
+}
+
+UIWIDGET ui_passwordfield_create(UiObject* obj, UiTextFieldArgs args) {
+ return create_textfield(obj, args, true, false);
}
char* ui_textfield_get(UiString *str) {
QLineEdit *textfield = (QLineEdit*)str->obj;
QString qstr = textfield->text();
- if(str->value) {
- free(str->value);
+ if(str->value.free) {
+ str->value.free(str->value.ptr);
}
- QByteArray array = qstr.toLocal8Bit();
+ QByteArray array = qstr.toUtf8();
const char *cstr = array.constData();
- str->value = strdup(cstr);
+ str->value.ptr = strdup(cstr);
+ str->value.free = free;
- return str->value;
+ return str->value.ptr;
}
-void ui_textfield_set(UiString *str, char *value) {
+void ui_textfield_set(UiString *str, const char *value) {
QLineEdit *textfield = (QLineEdit*)str->obj;
QString qstr = QString::fromUtf8(value);
textfield->setText(qstr);
- if(str->value) {
- free(str->value);
+ if(str->value.free) {
+ str->value.free(str->value.ptr);
}
- str->value = NULL;
+ str->value.ptr = NULL;
}
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
- * Copyright 2014 Olaf Wintermann. All rights reserved.
+ * Copyright 2025 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:
// value implementations
extern "C" {
- char* ui_textarea_get(UiText *text);
- void ui_textarea_set(UiText *text, 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_setposition(UiText *text, int pos);
- int ui_textarea_position(UiText *text);
- 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);
- char* ui_textfield_get(UiString *str);
- void ui_textfield_set(UiString *str, char *value);
+void ui_textarea_save(UiText *text);
+void ui_textarea_restore(UiText *text);
+void ui_textarea_text_destroy(UiText *text);
+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_setposition(UiText *text, int pos);
+int ui_textarea_position(UiText *text);
+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);
+
+char* ui_textfield_get(UiString *str) ;
+void ui_textfield_set(UiString *str, const char *value);
+
}
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <ucx/map.h>
#include <inttypes.h>
#include "toolbar.h"
#include "menu.h"
#include "stock.h"
-static UcxMap *toolbar_items = ucx_map_new(16);
-static UcxList *defaults;
-
-/* ------------------------- UiToolItem ------------------------- */
-
-UiToolItem::UiToolItem(char *label, ui_callback f, void *userdata) {
- this->label = label;
- this->image = NULL;
- this->callback = f;
- this->userdata = userdata;
- this->isimportant = false;
- this->groups = NULL;
-}
-
-void UiToolItem::addGroup(int group) {
- groups = ucx_list_append(groups, (void*)(intptr_t)group);
-}
-
-void UiToolItem::addTo(UiObject *obj, QToolBar *toolbar) {
- QString str = QString::fromUtf8(label);
- UiAction *action = new UiAction(obj, str, callback, userdata);
- action->setIcon(QIcon::fromTheme(image));
- toolbar->addAction(action);
- QObject::connect(action, SIGNAL(triggered()), action, SLOT(trigger()));
-}
-
-
-/* ------------------------- UiStockToolItem ------------------------- */
-
-UiStockToolItem::UiStockToolItem(char *stockid, ui_callback f, void *userdata) {
- this->stockid = stockid;
- this->callback = f;
- this->userdata = userdata;
- this->isimportant = false;
- this->groups = NULL;
-}
-
-void UiStockToolItem::addGroup(int group) {
- groups = ucx_list_append(groups, (void*)(intptr_t)group);
-}
-
-void UiStockToolItem::addTo(UiObject *obj, QToolBar *toolbar) {
- UiStockItem *stockItem = ui_get_stock_item(stockid);
- QString str = QString::fromUtf8(stockItem->label);
-
- UiAction *action = new UiAction(obj, str, callback, userdata);
- action->setIcon(QIcon::fromTheme(stockItem->icon_name));
- toolbar->addAction(action);
- QObject::connect(action, SIGNAL(triggered()), action, SLOT(trigger()));
-}
-
-
-
-void ui_toolitem_vstgr(
- char *name,
- char *stockid,
- int isimportant,
- ui_callback f,
- void *userdata,
- va_list ap)
-{
- UiStockToolItem *item = new UiStockToolItem(stockid, f, userdata);
- item->isimportant = isimportant;
-
- // add groups
- int group;
- while((group = va_arg(ap, int)) != -1) {
- item->addGroup(group);
- }
-
- ucx_map_cstr_put(toolbar_items, name, item);
-}
-
-void ui_toolitem_img(char *name, char *label, char *img, ui_callback f, void *udata) {
- UiToolItem *item = new UiToolItem(label, f, udata);
- item->image = img;
- item->isimportant = false;
-
- ucx_map_cstr_put(toolbar_items, name, item);
-}
-
-void ui_toolitem(char *name, char *label, ui_callback f, void *udata) {
- ui_toolitem_img(name, label, NULL, f, udata);
-}
-
-void ui_toolitem_st(char *name, char *stockid, ui_callback f, void *userdata) {
- ui_toolitem_stgr(name, stockid, f, userdata, -1);
-}
-
-void ui_toolitem_sti(char *name, char *stockid, ui_callback f, void *userdata) {
- ui_toolitem_stgri(name, stockid, f, userdata, -1);
-}
-
-void ui_toolitem_stgr(char *name, char *stockid, ui_callback f, void *userdata, ...) {
- va_list ap;
- va_start(ap, userdata);
- ui_toolitem_vstgr(name, stockid, 0, f, userdata, ap);
- va_end(ap);
-}
-
-void ui_toolitem_stgri(char *name, char *stockid, ui_callback f, void *userdata, ...) {
- va_list ap;
- va_start(ap, userdata);
- ui_toolitem_vstgr(name, stockid, 1, f, userdata, ap);
- va_end(ap);
-}
-
-
-void ui_toolbar_add_default(char *name) {
- char *s = strdup(name);
- defaults = ucx_list_append(defaults, s);
-}
-
-
-QToolBar* ui_create_toolbar(UiObject *obj) {
- QToolBar *toolbar = new QToolBar();
-
- UCX_FOREACH(elm, defaults) {
- UiToolItemI *item = (UiToolItemI*)ucx_map_cstr_get(toolbar_items, (char*)elm->data);
- if(item) {
- item->addTo(obj, toolbar);
- } else if(!strcmp((char*)elm->data, "@separator")) {
-
- } else {
- fprintf(stderr, "UI Error: Unknown toolbar item: %s\n", elm->data);
- }
- }
-
- return toolbar;
-}
#include "toolkit.h"
#include "../ui/toolbar.h"
-#include <ucx/list.h>
#include <QToolBar>
-class UiToolItemI {
-public:
- virtual void addTo(UiObject *obj, QToolBar *toolbar) = 0;
-};
-class UiToolItem : public UiToolItemI {
-public:
- char *label;
- char *image;
- ui_callback callback;
- void *userdata;
- UcxList *groups;
- bool isimportant;
-
- UiToolItem(char *label, ui_callback f, void *userdata);
- void addGroup(int group);
- virtual void addTo(UiObject *obj, QToolBar *toolbar);
-};
-
-class UiStockToolItem : public UiToolItemI {
-public:
- char *stockid;
- ui_callback callback;
- void *userdata;
- UcxList *groups;
- bool isimportant;
-
- UiStockToolItem(char *stockid, ui_callback f, void *userdata);
- void addGroup(int group);
- virtual void addTo(UiObject *obj, QToolBar *toolbar);
-};
-
-
-void ui_toolitem_vstgr(
- char *name,
- char *stockid,
- int isimportant,
- ui_callback f,
- void *userdata,
- va_list ap);
-
-
-QToolBar* ui_create_toolbar(UiObject *obj);
#endif /* TOOLBAR_H */
#include "../common/document.h"
#include "../common/properties.h"
+#include "../common/menu.h"
+#include "../common/toolbar.h"
-static char *application_name;
+static const char *application_name;
-static ui_callback appclose_fnc;
-static void *appclose_udata;
+static ui_callback startup_func;
+static void *startup_data;
+static ui_callback open_func;
+void *open_data;
+static ui_callback exit_func;
+void *exit_data;
+
+static int is_toplevel_realized = 0;
-//static QApplication app(qargc, qargv);
int app_argc;
char **app_argv;
QApplication *application = NULL;
-void ui_init(char *appname, int argc, char **argv) {
+void ui_init(const char *appname, int argc, char **argv) {
application_name = appname;
app_argc = argc;
application = new QApplication(app_argc, app_argv);
uic_docmgr_init();
+ uic_menu_init();
+ uic_toolbar_init();
uic_load_app_properties();
-
- ui_stock_init();
+
}
-char* ui_appname() {
+const char* ui_appname() {
return application_name;
}
-void ui_exitfunc(ui_callback f, void *udata) {
- appclose_fnc = f;
- appclose_udata = udata;
+void ui_onstartup(ui_callback f, void *userdata) {
+ startup_func = f;
+ startup_data = userdata;
}
-void ui_openfilefunc(ui_callback f, void *userdata) {
- // OS X only
+void ui_onopen(ui_callback f, void *userdata) {
+ open_func = f;
+ open_data = userdata;
+}
+
+void ui_onexit(ui_callback f, void *userdata) {
+ exit_func = f;
+ exit_data = userdata;
}
void ui_main() {
+ if(startup_func) {
+ startup_func(NULL, startup_data);
+ }
application->exec();
-
- if(appclose_fnc) {
- appclose_fnc(NULL, appclose_udata);
+ if(exit_func) {
+ exit_func(NULL, exit_data);
}
uic_store_app_properties();
+/* --------------------- Implemtation UiEventWrapper --------------------- */
UiEventWrapper::UiEventWrapper(UiObject *obj, ui_callback f, void* userdata) {
this->obj = obj;
}
void UiEventWrapper::slot() {
+ if(!callback) {
+ return;
+ }
+
+ UiEvent e;
+ e.obj = obj;
+ e.window = obj->window;
+ e.document = obj->ctx->document;
+ e.eventdata = NULL;
+ e.intval = 0;
+ e.set = ui_get_setop();
+ if(prepare_event) {
+ prepare_event(&e, this);
+ }
+ callback(&e, userdata);
+
+ // TODO: notify var observers
+}
+
+void UiEventWrapper::destroy() {
+ delete this;
+}
+
+
+/* --------------------- Implemtation UiAction --------------------- */
+
+UiAction::UiAction(UiObject *obj, QString &label, ui_callback f, void *userdata) : QAction(label, NULL) {
+ this->obj = obj;
+ this->callback = f;
+ this->userdata = userdata;
+}
+
+UiAction::~UiAction() {
+
+}
+
+void UiAction::trigger() {
+ if(!callback) {
+ return;
+ }
+
UiEvent e;
e.obj = obj;
e.window = obj->window;
e.document = obj->ctx->document;
e.eventdata = NULL;
e.intval = 0;
+ e.set = ui_get_setop();
+ if(prepare_event) {
+ prepare_event(&e, this);
+ }
callback(&e, userdata);
+
+ // TODO: notify var observers
+}
+
+// ui_enablefunc for UiAction
+void ui_action_enable(UiAction *action, int enable) {
+ action->setEnabled((bool)enable);
}
+
#include <QApplication>
+class UiEventWrapper;
+
+typedef void (*ui_prepare_event_func)(UiEvent *event, UiEventWrapper *wrapper);
+
class UiEventWrapper : public QObject {
Q_OBJECT
UiObject *obj;
ui_callback callback;
void *userdata;
-
+
public:
+ UiVar *var;
+
+ void *customdata1 = nullptr;
+ void *customdata2 = nullptr;
+ int customvalue1 = 0;
+ int customvalue2 = 0;
+
+ ui_prepare_event_func prepare_event = nullptr;
+
UiEventWrapper(UiObject *obj, ui_callback f, void *userdata);
public slots:
void slot();
+ void destroy();
+};
+
+class UiAction;
+
+typedef void (*ui_prepare_action_event_func)(UiEvent *event, UiAction *action);
+
+class UiAction : public QAction {
+ Q_OBJECT
+
+ UiObject *obj;
+ ui_callback callback;
+ void *userdata;
+
+public:
+ UiVar *var;
+
+ ui_prepare_action_event_func prepare_event = nullptr;
+ void *customdata1 = nullptr;
+ void *customdata2 = nullptr;
+ int customvalue1 = 0;
+ int customvalue2 = 0;
+
+ UiAction(UiObject *obj, QString &label, ui_callback f, void *userdata);
+ ~UiAction();
+
+private slots:
+ void trigger();
};
+void ui_action_enable(UiAction *action, int enable);
#endif /* TOOLKIT_H */
#include <QListView>
-extern "C" void* ui_strmodel_getvalue(void *elm, int column) {
- return column == 0 ? elm : NULL;
-}
-
-UIWIDGET ui_listview_str(UiObject *obj, UiList *list, ui_callback f, void *udata) {
- return ui_listview(obj, list, ui_strmodel_getvalue, f, udata);
-}
-UIWIDGET ui_listview_var(UiObject *obj, UiListPtr *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) {
- QListView *view = new QListView();
- ListModel *model = new ListModel(obj, view, list, getvalue, f, udata);
- view->setModel(model);
-
- // TODO: observer update
-
- QItemSelectionModel *s = view->selectionModel();
- QObject::connect(
- s,
- SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
- model,
- SLOT(selectionChanged(const QItemSelection &, const QItemSelection &)));
-
- UiContainer *ct = uic_get_current_container(obj);
- ct->add(view, true);
- return view;
-}
-
-UIWIDGET ui_listview(UiObject *obj, UiList *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) {
- UiListPtr *listptr = (UiListPtr*)ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListPtr));
- listptr->list = list;
- return ui_listview_var(obj, listptr, getvalue, f, udata);
-}
-
-UIWIDGET ui_listview_nv(UiObject *obj, char *varname, ui_model_getvalue_f getvalue, ui_callback f, void *udata) {
- UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_LIST);
- if(var) {
- UiListVar *value = (UiListVar*)var->value;
- return ui_listview_var(obj, value->listptr, getvalue, f, udata);
- } else {
- // TODO: error
- }
- return NULL;
-}
-
-
-UIWIDGET ui_table_var(UiObject *obj, UiListPtr *list, UiModelInfo *modelinfo) {
- QTreeView *view = new QTreeView();
- TableModel *model = new TableModel(obj, view, list, modelinfo);
- view->setModel(model);
-
- view->setItemsExpandable(false);
- view->setRootIsDecorated(false);
-
- // TODO: observer update
- UiTableView *u = new UiTableView();
- u->widget = view;
- u->model = model;
- list->list->observers = ui_add_observer(
- list->list->observers,
- (ui_callback)ui_table_update,
- u);
-
- view->setSelectionMode(QAbstractItemView::ExtendedSelection);
- QItemSelectionModel *s = view->selectionModel();
- QObject::connect(
- s,
- SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
- model,
- SLOT(selectionChanged(const QItemSelection &, const QItemSelection &)));
- QObject::connect(
- view,
- SIGNAL(doubleClicked(const QModelIndex &)),
- model,
- SLOT(activate(const QModelIndex &)));
-
-
- UiContainer *ct = uic_get_current_container(obj);
- ct->add(view, true);
- return view;
-}
-
-void ui_table_update(UiEvent *event, UiTableView *view) {
- // TODO
- printf("update\n");
-
- //view->model->update();
- view->widget->setModel(NULL);
- view->widget->setModel(view->model);
-}
-
-UIWIDGET ui_table(UiObject *obj, UiList *list, UiModelInfo *modelinfo) {
- UiListPtr *listptr = (UiListPtr*)ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListPtr));
- listptr->list = list;
- return ui_table_var(obj, listptr, modelinfo);
-}
-
-UIWIDGET ui_table_nv(UiObject *obj, char *varname, UiModelInfo *modelinfo) {
- UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_LIST);
- if(var) {
- UiListVar *value = (UiListVar*)var->value;
- return ui_table_var(obj, value->listptr, modelinfo);
- } else {
- // TODO: error
- }
- return NULL;
-}
-
#include <QTableView>
-class UiTableView {
-public:
- QTreeView *widget;
- TableModel *model;
-};
-extern "C" void ui_table_update(UiEvent *event, UiTableView *view);
#endif /* TREE_H */
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <ucx/mempool.h>
+#include <cx/mempool.h>
#include "../common/context.h"
#include "window.h"
#include <QVBoxLayout>
#include <QFileDialog>
+#include <QPushButton>
-static UiObject* create_window(char *title, void *window_data, bool simple) {
- UcxMempool *mp = ucx_mempool_new(256);
- UiObject *obj = (UiObject*)ucx_mempool_calloc(mp, 1, sizeof(UiObject));
+static UiObject* create_window(const char *title, void *window_data, bool simple) {
+ CxMempool *mp = cxMempoolCreateSimple(256);
+ UiObject *obj = (UiObject*)cxCalloc(mp->allocator, 1, sizeof(UiObject));
obj->ctx = uic_context(obj, mp);
obj->window = window_data;
obj->next = NULL;
QMainWindow *window = new QMainWindow();
+ window->setWindowTitle(title);
obj->widget = window;
if(!simple) {
ui_add_menus(obj, window);
- QToolBar *toolbar = ui_create_toolbar(obj);
- window->addToolBar(Qt::TopToolBarArea, toolbar);
+ //QToolBar *toolbar = ui_create_toolbar(obj);
+ //window->addToolBar(Qt::TopToolBarArea, toolbar);
}
QBoxLayout *box = new QVBoxLayout();
QWidget *boxWidget = new QWidget();
boxWidget->setLayout(box);
window->setCentralWidget(boxWidget);
- obj->container = new UiBoxContainer(box);
+ ui_container_add(obj, new UiBoxContainer(box));
obj->widget = window;
return obj;
}
-UiObject* ui_window(char *title, void *window_data) {
+UiObject* ui_window(const char *title, void *window_data) {
return create_window(title, window_data, FALSE);
}
#define ui_hbox_w(obj, w, ...) for(w = ui_hbox_create(obj, (UiContainerArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
#define ui_grid_w(obj, w, ...) for(w = ui_grid_create(obj, (UiContainerArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
#define ui_tabview_w(obj, w, ...) for(w = ui_tabview_create(obj, (UiTabViewArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
+#define ui_scrolledwindow_w(obj, w, ...) for(w = ui_scrolledwindow_create(obj, (UiFrameArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
#define ui_hsplitpane(obj, ...) for(ui_hsplitpane_create(obj, (UiSplitPaneArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
#define ui_vsplitpane(obj, ...) for(ui_vsplitpane_create(obj, (UiSplitPaneArgs){ __VA_ARGS__ });ui_container_finish(obj);ui_container_begin_close(obj))
UiBool scrollarea;
UiBool autoscale;
+ UiBool adjustwidgetsize;
+ UiBool useradjustable;
+ int image_padding;
+ int image_padding_left;
+ int image_padding_right;
+ int image_padding_top;
+ int image_padding_bottom;
UiGeneric *value;
const char *varname;
UiMenuBuilder *contextmenu;
UIEXPORT UIWIDGET ui_imageviewer_create(UiObject *obj, UiImageViewerArgs args);
+UIEXPORT UIWIDGET ui_imageviewer_reset(UIWIDGET w);
+UIEXPORT UIWIDGET ui_imageviewer_set_autoscale(UIWIDGET w, UiBool set);
+UIEXPORT UIWIDGET ui_imageviewer_set_adjustwidgetsize(UIWIDGET w, UiBool set);
+UIEXPORT UIWIDGET ui_imageviewer_set_useradjustable(UIWIDGET w, UiBool set);
+
UIEXPORT int ui_image_load_file(UiGeneric *obj, const char *path);
#ifdef __cplusplus
#define UI_TOOLKIT_H
#include <inttypes.h>
+#include <stdlib.h>
#ifdef UI_COCOA
#include <adwaita.h>
#endif
-#elif UI_MOTIF
-
-#include <Xm/XmAll.h>
-#define UIWIDGET Widget
-#define UIMENU Widget
-
#elif defined(UI_QT4) || defined(UI_QT5)
+#define UI_QT
+
#ifdef __cplusplus
+
#include <QApplication>
#include <QWidget>
#include <QMenu>
+
#define UIWIDGET QWidget*
+#define UIWINDOW QWidget*
#define UIMENU QMenu*
#else /* __cplusplus */
#define UIWIDGET void*
+#define UIWINDOW void*
#define UIMENU void*
#endif
+#elif UI_MOTIF
+
+#include <Xm/XmAll.h>
+#define UIWIDGET Widget
+#define UIMENU Widget
+
+
+#elif UI_WIN32
+
+#include <Windows.h>
+
+#define UIEXPORT __declspec(dllexport)
+
+#define UIWIDGET void*
+#define UIWINDOW void*
+#define UIMENU void*
+
#elif UI_WINUI
#define UIEXPORT __declspec(dllexport)
typedef struct UiTabbedPane UiTabbedPane;
-typedef enum UiTri UiTri;
-typedef enum UiLabelType UiLabelType;
+typedef enum UiTri {
+ UI_DEFAULT = 0,
+ UI_ON,
+ UI_OFF
+} UiTri;
-typedef enum UiDnDAction UiDnDAction;
enum UiMouseEventType { UI_PRESS = 0, UI_PRESS2 };
-enum UiLabelType { UI_LABEL_DEFAULT, UI_LABEL_TEXT, UI_LABEL_ICON, UI_LABEL_TEXT_ICON };
-
-enum UiDnDAction { UI_DND_ACTION_NONE, UI_DND_ACTION_COPY, UI_DND_ACTION_MOVE, UI_DND_ACTION_LINK, UI_DND_ACTION_CUSTOM };
+typedef enum UiLabelType {
+ UI_LABEL_DEFAULT,
+ UI_LABEL_TEXT,
+ UI_LABEL_ICON,
+ UI_LABEL_TEXT_ICON
+} UiLabelType;
+
+typedef enum UiDnDAction {
+ UI_DND_ACTION_NONE,
+ UI_DND_ACTION_COPY,
+ UI_DND_ACTION_MOVE,
+ UI_DND_ACTION_LINK,
+ UI_DND_ACTION_CUSTOM
+} UiDnDAction;
typedef void(*ui_callback)(UiEvent*, void*); /* event, user data */
void (*insert)(UiText*, int, char*);
void (*setposition)(UiText*,int);
int (*position)(UiText*);
+ 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 */
UiObserver *observers;
};
-enum UiTri {
- UI_DEFAULT = 0,
- UI_ON,
- UI_OFF
-};
-
struct UiFileList {
char **files;
size_t nfiles;
#ifdef UI_GTK
typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs args, void *userdata);
+#elif defined(UI_QT)
+typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs args, void *userdata);
#elif defined(UI_MOTIF)
typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs args, void *userdata, Widget parent, Arg *a, int n);
#elif defined(UI_COCOA)
typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs args, void *userdata);
#elif defined(UI_WINUI)
typedef UIWIDGET(*ui_createwidget_func)(UiObject *obj, UiWidgetArgs args, void *userdata);
+#elif defined(UI_WIN32)
+typedef UIWIDGET(*ui_createwidget_func)(UiObject *obj, UiWidgetArgs args, void *userdata);
#endif
UIEXPORT UIWIDGET ui_customwidget_create(UiObject *obj, ui_createwidget_func create_widget, void *userdata, UiWidgetArgs args);
#define ui_separator(obj, ...) ui_separator_create(obj, &(UiWidgetArgs){ __VA_ARGS__ } )
+UIEXPORT void ui_widget_set_size(UIWIDGET w, int width, int height);
+UIEXPORT void ui_widget_redraw(UIWIDGET w);
+
#ifdef __cplusplus
}
--- /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.
+#
+
+$(WIN32_OBJPRE)%.obj: win32/%.c
+ $(CC) -o $@ -c -I../ucx $(CFLAGS) $(TK_CFLAGS) $<
+
+$(UI_LIB): $(OBJ)
+ $(AR) $(ARFLAGS) $(UI_LIB) $(OBJ)
--- /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.
+#
+
+WIN32_SRC_DIR = ui/win32/
+WIN32_OBJPRE = $(OBJ_DIR)$(WIN32_SRC_DIR)
+
+WIN32OBJ = toolkit.obj
+
+TOOLKITOBJS += $(WIN32OBJ:%=$(WIN32_OBJPRE)%)
+TOOLKITSOURCE += $(WIN32OBJ:%.obj=win32/%.c)
--- /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 "toolkit.h"
+#include "Windows.h"
+
+#include "../common/properties.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static const char *application_name;
+
+static ui_callback startup_func;
+static void *startup_data;
+static ui_callback open_func;
+void *open_data;
+static ui_callback exit_func;
+void *exit_data;
+
+void ui_init(const char *appname, int argc, char **argv) {
+ application_name = appname;
+}
+
+const char* ui_appname() {
+ return application_name;
+}
+
+void ui_onstartup(ui_callback f, void *userdata) {
+ startup_func = f;
+ startup_data = userdata;
+}
+
+void ui_onopen(ui_callback f, void *userdata) {
+ open_func = f;
+ open_data = userdata;
+}
+
+void ui_onexit(ui_callback f, void *userdata) {
+ exit_func = f;
+ exit_data = userdata;
+}
+
+void ui_main() {
+ if(startup_func) {
+ startup_func(NULL, startup_data);
+ }
+
+ // event loop
+ MSG msg;
+ while (GetMessage(&msg, NULL, 0, 0)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ if(exit_func) {
+ exit_func(NULL, exit_data);
+ }
+ uic_store_app_properties();
+}
--- /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.
+ */
+
+#ifndef TOOLKIT_H
+#define TOOLKIT_H
+
+#include <inttypes.h>
+#include "../ui/toolkit.h"
+#include "../common/context.h"
+#include "../common/object.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOOLKIT_H */
+