- (void)handleEventWithEventData:(id)sender;
-- (SEL)addDynamicMethod:(unsigned long long)method_id;
-
@end
+
@interface MainWindow : NSWindow
+- (MainWindow*)init:(UiObject*)obj;
+
+@end
+
+
+@interface MainWindowController : NSWindowController<NSMenuItemValidation>
+
@property UiObject *uiobj;
+@property NSMutableDictionary *checkItemStates;
+@property NSMutableDictionary *radioItems;
-- (MainWindow*)init:(UiObject*)obj;
+- (MainWindowController*)initWithWindow:(UiObject*)obj window:(NSWindow*)window;
+
+- (void) windowDidLoad;
+- (void)menuItemAction:(id)sender;
+
+- (BOOL) validateMenuItem:(NSMenuItem *) menuItem;
+
+@end
+
+@interface MenuItemState : NSObject
+@property (weak) MainWindowController *mainWindow;
+@property UiVar *var;
+@property int state;
@end
+
+
+int64_t ui_menu_check_item_get(UiInteger *i);
+void ui_menu_check_item_set(UiInteger *i, int64_t value);
+
+int64_t ui_menu_radio_item_get(UiInteger *i);
+void ui_menu_radio_item_set(UiInteger *i, int64_t value);
#import "Container.h"
#import "GridLayout.h"
#import "../common/object.h"
+#import <objc/runtime.h>
+
+#import "EventData.h"
+#import "menu.h"
@implementation MainWindow
- (MainWindow*)init:(UiObject*)obj {
- self.uiobj = obj;
NSRect frame = NSMakeRect(300, 200, 600, 500);
self = [self initWithContentRect:frame
}
@end
+
+
+
+@implementation MainWindowController
+
+- (MainWindowController*)initWithWindow:(UiObject*)obj window:(NSWindow*)window {
+ self = [super initWithWindow:window];
+ _uiobj = obj;
+
+ self.checkItemStates = [[NSMutableDictionary alloc] init];
+ self.radioItems = [[NSMutableDictionary alloc] init];
+
+ // bind all stateful menu items (checkbox, radiobuttons, lists)
+ NSArray *menuBindItems = ui_get_binding_items(); // returns all items that require binding
+ for(MenuItem *item in menuBindItems) {
+ if(item.checkItem || item.radioItem) {
+ // simple check item (ui_menu_toggleitem_create)
+ UiVar *var = uic_widget_var(obj->ctx, obj->ctx, NULL, item.checkItem ? item.checkItem->varname : item.radioItem->varname, UI_VAR_INTEGER);
+ // create the state object for this item/window
+ MenuItemState *state = [[MenuItemState alloc] init];
+ state.mainWindow = self;
+ state.var = var;
+ if(var) {
+ UiInteger *i = var->value;
+ if(item.checkItem) {
+ // bind toggle item
+ state.state = (int)i->value;
+ i->obj = (__bridge void*)state;
+ i->get = ui_menu_check_item_get;
+ i->set = ui_menu_check_item_set;
+ } else {
+ // bind radio item
+ NSMutableArray *rgroup = nil;
+ if(i->obj) {
+ rgroup = (__bridge NSMutableArray*)i->obj;
+ } else {
+ // create a new rgroup array and register it in the window
+ rgroup = [[NSMutableArray alloc] init];
+ NSString *varname = [[NSString alloc] initWithUTF8String:item.radioItem->varname];
+ [_radioItems setObject:rgroup forKey:varname];
+ i->obj = (__bridge void*)rgroup;
+ }
+ i->get = ui_menu_radio_item_get;
+ i->set = ui_menu_radio_item_set;
+ [rgroup addObject:state]; // add this item state to the radio group
+ // i->value can contain a non-zero value, which means a specific radiobutton
+ // should be pre-selected
+ if(i->value == rgroup.count) {
+ state.state = NSControlStateValueOn;
+ }
+ }
+ } else {
+ state.state = 0;
+ }
+ [_checkItemStates setObject:state forKey:item.itemId];
+ }
+ }
+
+ return self;
+}
+
+- (void) windowDidLoad {
+ [self.window setNextResponder:self];
+}
+
+- (void)menuItemAction:(id)sender {
+ EventData *event = objc_getAssociatedObject(sender, "eventdata");
+ if(event) {
+ event.obj = self.uiobj; // temporary set the event object
+ [event handleEvent:sender];
+ }
+}
+
+- (void)menuCheckItemAction:(id)sender {
+ NSMenuItem *menuItem = sender;
+ MenuItem *item = objc_getAssociatedObject(sender, "menuitem");
+ if(!item || !item.checkItem) {
+ return;
+ }
+
+ MenuItemState *state = [_checkItemStates objectForKey:item.itemId];
+ state.state = state.state == NSControlStateValueOff ? NSControlStateValueOn : NSControlStateValueOff;
+ menuItem.state = state.state;
+
+ UiMenuCheckItem *it = item.checkItem;
+ if(it->callback) {
+ UiEvent event;
+ event.obj = _uiobj;
+ event.window = event.obj->window;
+ event.document = event.obj->ctx->document;
+ event.eventdata = state.var ? state.var->value : NULL;
+ event.intval = state.state;
+ it->callback(&event, it->userdata);
+ }
+}
+
+- (void)menuRadioItemAction:(id)sender {
+ NSMenuItem *menuItem = sender;
+ MenuItem *item = objc_getAssociatedObject(sender, "menuitem");
+ if(!item || !item.radioItem) {
+ return;
+ }
+
+ UiMenuRadioItem *it = item.radioItem;
+ if(!it->varname) {
+ return;
+ }
+
+ MenuItemState *state = [_checkItemStates objectForKey:item.itemId]; // current state of this menu item
+
+ NSString *varname = [[NSString alloc] initWithUTF8String:it->varname];
+ NSArray *radioGroup = [_radioItems objectForKey:varname];
+ if(!radioGroup) {
+ return;
+ }
+ int index = 1;
+ int value = 0;
+ for(MenuItemState *g in radioGroup) {
+ if(g == state) {
+ menuItem.state = NSControlStateValueOn;
+ g.state = NSControlStateValueOn;
+ value = index;
+ } else {
+ menuItem.state = NSControlStateValueOff;
+ g.state = NSControlStateValueOff;
+ }
+ }
+
+ if(it->callback) {
+ UiEvent event;
+ event.obj = _uiobj;
+ event.window = event.obj->window;
+ event.document = event.obj->ctx->document;
+ event.eventdata = state.var ? state.var->value : NULL;
+ event.intval = value;
+ it->callback(&event, it->userdata);
+ }
+}
+
+
+- (BOOL) validateMenuItem:(NSMenuItem *) menuItem {
+ MenuItem *item = objc_getAssociatedObject(menuItem, "menuitem");
+ if(item) {
+ MenuItemState *state = [_checkItemStates objectForKey:item.itemId];
+ if(state) {
+ menuItem.state = state.state;
+ } else {
+ menuItem.state = NSControlStateValueOff;
+ }
+ }
+
+ return YES;
+}
+
+@end
+
+@implementation MenuItemState
+
+@end
+
+int64_t ui_menu_check_item_get(UiInteger *i) {
+ MenuItemState *state = (__bridge MenuItemState*)i->obj;
+ i->value = state.state;
+ return i->value;
+}
+
+void ui_menu_check_item_set(UiInteger *i, int64_t value) {
+ MenuItemState *state = (__bridge MenuItemState*)i->obj;
+ i->value = value;
+ state.state = (int)value;
+}
+
+int64_t ui_menu_radio_item_get(UiInteger *i) {
+ NSArray *rgroup = (__bridge NSArray*)i->obj;
+ i->value = 0;
+ int index = 1;
+ for(MenuItemState *state in rgroup) {
+ if(state.state == NSControlStateValueOn) {
+ i->value = index;
+ break;
+ }
+ index++;
+ }
+ return i->value;
+}
+
+void ui_menu_radio_item_set(UiInteger *i, int64_t value) {
+ NSArray *rgroup = (__bridge NSArray*)i->obj;
+ i->value = 0;
+ int index = 1;
+ for(MenuItemState *state in rgroup) {
+ state.state = value == index;
+ index++;
+ }
+}
int64_t index = 0;
for(UiRadioButton *b in buttons) {
if([b cell].state != 0) {
- i->value = index;
+ i->value = index + 1;
break;
}
index++;
}
- return index;
+ return i->value;
}
void ui_radiobuttons_set(UiInteger *i, int64_t value) {
NSMutableArray *buttons = (__bridge NSMutableArray*)i->obj;
- int64_t index = 0;
+ int64_t index = 1;
for(UiRadioButton *b in buttons) {
if(index == value) {
[b cell].state = NSControlStateValueOn;
}
index++;
}
- return index;
}
#import "../common/menu.h"
+@interface MenuItem : NSObject
+
+@property (strong) NSString *itemId;
+@property UiMenuCheckItem *checkItem;
+@property UiMenuRadioItem *radioItem;
+@property ui_callback callback;
+@property void *userdata;
+
+- (MenuItem*)init:(int)itId;
+
+@end
+
void ui_menu_init(void);
typedef void(*ui_menu_add_f)(NSMenu*, int, UiMenuItemI*);
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);
+
+NSArray* ui_get_binding_items(void);
#import <stdlib.h>
#import <string.h>
#import <stdarg.h>
+#import <objc/runtime.h>
#import "menu.h"
#import "window.h"
+#import "EventData.h"
+
+#pragma GCC diagnostic ignored "-Wundeclared-selector"
+#pragma clang diagnostic ignored "-Wundeclared-selector"
+
+// holds all items that need bindings
+// value type: MenuItem*
+static NSMutableArray *bindingItems;
+
+@implementation MenuItem
+
+- (MenuItem*)init:(int)itId {
+ self.itemId = [[NSString alloc] initWithFormat:@"item%d", itId];
+ return self;
+}
+
+@end
static ui_menu_add_f createMenuItem[] = {
/* UI_MENU */ add_menu_widget,
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:@""];
+ NSMenuItem *menuItem = [parent addItemWithTitle:str action:@selector(menuItemAction:) keyEquivalent:@""];
+
+ if(it->callback) {
+ EventData *event = [[EventData alloc] init:it->callback userdata:it->userdata];
+ objc_setAssociatedObject(menuItem, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
+ }
}
void add_menuseparator_widget(NSMenu *parent, int i, UiMenuItemI *item) {
-
+ NSMenuItem *menuItem = [NSMenuItem separatorItem];
+ [parent addItem:menuItem];
}
+static int nItem = 0;
+
void add_checkitem_widget(NSMenu *parent, int i, UiMenuItemI *item) {
+ UiMenuCheckItem *it = (UiMenuCheckItem*)item;
+
+ NSString *str = [[NSString alloc] initWithUTF8String:it->label];
+ NSMenuItem *menuItem = [parent addItemWithTitle:str action:@selector(menuCheckItemAction:) keyEquivalent:@""];
+ MenuItem *mItem = [[MenuItem alloc] init:nItem++];
+ mItem.callback = it->callback;
+ mItem.userdata = it->userdata;
+ mItem.checkItem = it;
+
+ objc_setAssociatedObject(menuItem, "menuitem", mItem, OBJC_ASSOCIATION_RETAIN);
+ [bindingItems addObject:mItem];
}
void add_radioitem_widget(NSMenu *parent, int index, UiMenuItemI *item) {
+ UiMenuRadioItem *it = (UiMenuRadioItem*)item;
+
+ NSString *str = [[NSString alloc] initWithUTF8String:it->label];
+ NSMenuItem *menuItem = [parent addItemWithTitle:str action:@selector(menuRadioItemAction:) keyEquivalent:@""];
+ MenuItem *mItem = [[MenuItem alloc] init:nItem++];
+ mItem.callback = it->callback;
+ mItem.userdata = it->userdata;
+ mItem.radioItem = it;
+
+ objc_setAssociatedObject(menuItem, "menuitem", mItem, OBJC_ASSOCIATION_RETAIN);
+ [bindingItems addObject:mItem];
}
void add_checkitemnv_widget(NSMenu *parent, int i, UiMenuItemI *item) {
void ui_menu_init(void) {
+ bindingItems = [[NSMutableArray alloc] init];
+
UiMenu *menus_begin = uic_get_menu_list();
UiMenu *ls = menus_begin;
+ int index = 1;
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:@""];
+ NSMenuItem *menuItem = [[NSApp mainMenu] insertItemWithTitle:str action:nil keyEquivalent:@"" atIndex:index];
[[NSApp mainMenu] setSubmenu:menu forItem:menuItem];
add_menu_items(menu, 0, ls);
}
ls = (UiMenu*)ls->item.next;
+ index++;
}
}
+
+NSArray* ui_get_binding_items(void) {
+ return bindingItems;
+}
#import "MainWindow.h"
#import "WindowManager.h"
+#import <objc/runtime.h>
+
#include "../ui/window.h"
#include "../ui/properties.h"
#include "../common/context.h"
#include <cx/mempool.h>
+
static UiObject* create_window(const char *title, BOOL simple) {
CxMempool *mp = cxMempoolCreateSimple(256);
UiObject *obj = cxCalloc(mp->allocator, 1, sizeof(UiObject));
obj->wobj = (__bridge void*)window;
+ MainWindowController *controller = [[MainWindowController alloc] initWithWindow:obj window:window];
+ window.windowController = controller;
+ [window setNextResponder:(NSResponder*)controller];
+ objc_setAssociatedObject(window, "windowcontroller", controller, OBJC_ASSOCIATION_RETAIN);
+
return obj;
}
--- /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.
+ */
+
+#include "list.h"
+#include "container.h"
+
+#include <QTreeView>
+#include <QTreeWidgetItem>
+#include <QListView>
+
+extern "C" void* ui_strmodel_getvalue(void *elm, int column) {
+ return column == 0 ? elm : NULL;
+}
+
+
+UIWIDGET ui_listview_create(UiObject* obj, UiListArgs args) {
+ UiContainerPrivate *ctn = ui_obj_container(obj);
+ UI_APPLY_LAYOUT(ctn->layout, args);
+
+ QListView *view = new QListView();
+
+ ui_getvaluefunc getvalue = args.getvalue ? args.getvalue : ui_strmodel_getvalue;
+ UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.list, args.varname, UI_VAR_LIST);
+
+ ListModel *model = new ListModel(obj, view, var, getvalue);
+ view->setModel(model);
+
+ if(var) {
+ UiList *list = (UiList*)var->value;
+ list->update = ui_listmodel_update;
+ list->getselection = ui_listmodel_getselection;
+ list->setselection = ui_listmodel_setselection;
+ list->obj = model;
+ }
+
+ model->setActivationCallback(args.onactivate, args.onactivatedata);
+ model->setSelectionCallback(args.onselection, args.onselectiondata);
+
+ QItemSelectionModel *s = view->selectionModel();
+ QObject::connect(
+ s,
+ SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
+ model,
+ SLOT(selectionChanged(const QItemSelection &, const QItemSelection &)));
+
+
+ ctn->add(view, false);
+
+ return view;
+}
--- /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.
+ */
+
+#ifndef TREE_H
+#define TREE_H
+
+#include "../ui/tree.h"
+#include "model.h"
+
+#include <QTableView>
+
+
+
+#endif /* TREE_H */
+
#include "model.h"
+
+ListModel::ListModel(UiObject *obj, QListView *view, UiVar *var, ui_getvaluefunc getvalue){
+ this->obj = obj;
+ this->view = view;
+ this->var = var;
+ this->getvalue = getvalue;
+ this->onactivate = nullptr;
+ this->onactivatedata = nullptr;
+ this->onselection = nullptr;
+ this->onselectiondata = nullptr;
+}
+
+void ListModel::setActivationCallback(ui_callback f, void *userdata) {
+ onactivate = f;
+ onactivatedata = userdata;
+}
+
+void ListModel::setSelectionCallback(ui_callback f, void *userdata) {
+ onselection = f;
+ onselectiondata = userdata;
+}
+
+void ListModel::update(int row) {
+ if(row >= 0) {
+ this->update(row);
+ } else {
+ this->beginResetModel();
+ this->endResetModel();
+ }
+}
+
+int ListModel::rowCount(const QModelIndex& parent) const {
+ UiList *list = (UiList*)var->value;
+ return ui_list_count(list);
+}
+
+QVariant ListModel::data(const QModelIndex &index, int role) const {
+ if(role == Qt::DisplayRole) {
+ UiList *ls = (UiList*)var->value;
+ 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 sel = ui_selection_model_to_selection(view->selectionModel());
+
+ UiEvent event;
+ event.obj = obj;
+ event.window = obj->window;
+ event.document = obj->ctx->document;
+ event.eventdata = &sel;
+ event.intval = sel.count;
+ event.set = ui_get_setop();
+
+ if(onactivate) {
+ onactivate(&event, onactivatedata);
+ }
+ if(onselection) {
+ onselection(&event, onselectiondata);
+ }
+
+ free(sel.rows);
+}
+
+
+
+
+UiListSelection ui_selection_model_to_selection(QItemSelectionModel *model) {
+ UiListSelection sel;
+ sel.rows = NULL;
+ sel.count = 0;
+
+ if(model->hasSelection()) {
+ QModelIndexList indices = model->selectedIndexes();
+ sel.count = indices.count();
+ sel.rows = (int*)calloc(sel.count, sizeof(int));
+
+ int i = 0;
+ for (const QModelIndex &index : indices) {
+ sel.rows[i++] = index.row();
+ }
+ }
+
+ return sel;
+}
+
+/* ---------------------- UiList implementation -----------------------------*/
+
+void ui_listmodel_update(UiList *list, int row) {
+ ListModel *model = (ListModel*)list->obj;
+ model->update(row);
+}
+
+void ui_listmodel_setselection(UiList *list, UiListSelection sel) {
+ ListModel *model = (ListModel*)list->obj;
+ QItemSelection selection;
+ for (int i=0;i<sel.count;i++) {
+ QModelIndex index = model->index(sel.rows[i]);
+ selection.select(index, index);
+ }
+ model->view->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect);
+}
+
+UiListSelection ui_listmodel_getselection(UiList *list) {
+ ListModel *model = (ListModel*)list->obj;
+ return ui_selection_model_to_selection(model->view->selectionModel());
+}
#include <QItemSelectionModel>
+
+class ListModel : public QAbstractListModel {
+ Q_OBJECT
+
+ ui_getvaluefunc getvalue;
+ ui_callback onactivate;
+ void *onactivatedata;
+ ui_callback onselection;
+ void *onselectiondata;
+
+public:
+ UiObject *obj;
+ UiVar *var;
+ QListView *view;
+
+ ListModel(UiObject *obj, QListView *view, UiVar *var, ui_getvaluefunc getvalue);
+
+ void setActivationCallback(ui_callback f, void *userdata);
+ void setSelectionCallback(ui_callback f, void *userdata);
+
+ void update(int row);
+
+ 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);
+};
+
+
+UiListSelection ui_selection_model_to_selection(QItemSelectionModel *model);
+
+extern "C" {
+
+ void ui_listmodel_update(UiList *list, int row);
+ void ui_listmodel_setselection(UiList *list, UiListSelection sel);
+ UiListSelection ui_listmodel_getselection(UiList *list);
+
+}
+
#endif /* MODEL_H */
SOURCES += container.cpp
SOURCES += text.cpp
SOURCES += model.cpp
-SOURCES += tree.cpp
+SOURCES += list.cpp
SOURCES += button.cpp
SOURCES += label.cpp
SOURCES += graphics.cpp
HEADERS += container.h
HEADERS += text.h
HEADERS += model.h
-HEADERS += tree.h
+HEADERS += list.h
HEADERS += button.h
HEADERS += label.h
HEADERS += graphics.h
}
void ui_textarea_remove(UiText *text, int begin, int end) {
- // TODO
+ QTextDocument *doc = (QTextDocument*)text->data1;
+ QTextCursor cursor(doc);
+ cursor.setPosition(begin);
+ cursor.setPosition(end, QTextCursor::KeepAnchor);
+ cursor.removeSelectedText();
}
/* ------------------------------ TextField ------------------------------ */
#include "menu.h"
#include "stock.h"
+static void add_items(UiObject *obj, QToolBar *toolbar, CxList *defaults, CxMap *items);
+static void create_item(UiObject *obj, QToolBar *toolbar, UiToolbarItemI *i);
+
+QToolBar* ui_create_toolbar(UiObject *obj) {
+ CxMap *items = uic_get_toolbar_items();
+ CxList *left_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_LEFT);
+ CxList *center_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_CENTER);
+ CxList *right_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_RIGHT);
+
+ if(!items || cxMapSize(items) == 0) {
+ return nullptr;
+ }
+
+ QToolBar *toolbar = new QToolBar();
+ add_items(obj, toolbar, left_defaults, items);
+ add_items(obj, toolbar, center_defaults, items);
+ add_items(obj, toolbar, right_defaults, items);
+
+
+ return toolbar;
+}
+
+static void add_items(UiObject *obj, QToolBar *toolbar, CxList *defaults, CxMap *items) {
+ CxIterator i = cxListIterator(defaults);
+ cx_foreach(char *, name, i) {
+ UiToolbarItemI *item = (UiToolbarItemI*)cxMapGet(items, name);
+ if(item) {
+ create_item(obj, toolbar, item);
+ } else {
+ fprintf(stderr, "UI Error: unknown toolbar item '%s'\n", name);
+ }
+ }
+}
+
+static void create_item(UiObject *obj, QToolBar *toolbar, UiToolbarItemI *i) {
+ switch(i->type) {
+ case UI_TOOLBAR_ITEM: {
+ ui_toolbar_add_item(obj, toolbar, (UiToolbarItem*)i);
+ break;
+ }
+ case UI_TOOLBAR_TOGGLEITEM: {
+ ui_toolbar_add_toggleitem(obj, toolbar, (UiToolbarToggleItem*)i);
+ break;
+ }
+ case UI_TOOLBAR_MENU: {
+ ui_toolbar_add_menu(obj, toolbar, (UiToolbarMenuItem*)i);
+ break;
+ }
+ default: fprintf(stderr, "toolbar item type unimplemented: %d\n", (int)i->type);
+ }
+}
+
+void ui_toolbar_add_item(UiObject *obj, QToolBar *toolbar, UiToolbarItem *item) {
+ QAction *action = new QAction();
+ if(item->args.label) {
+ action->setText(item->args.label);
+ }
+ if(item->args.icon) {
+ action->setIcon(QIcon::fromTheme(item->args.icon));
+ }
+ toolbar->addAction(action);
+
+ UiEventWrapper *event = new UiEventWrapper(obj, item->args.onclick, item->args.onclickdata);
+ action->connect(action, SIGNAL(triggered()), event, SLOT(slot()));
+ action->connect(action, SIGNAL(destroyed()), event, SLOT(destroy()));
+}
+
+static void toolbar_togglebutton_event(UiEvent *event, UiEventWrapper *wrapper) {
+ QAction *action = (QAction*)wrapper->customdata1;
+ event->intval = action->isChecked();
+ if(wrapper->var) {
+ event->eventdata = wrapper->var->value;
+ }
+}
+
+void ui_toolbar_add_toggleitem(UiObject *obj, QToolBar *toolbar, UiToolbarToggleItem *item) {
+ QAction *action = new QAction();
+ action->setCheckable(true);
+ if(item->args.label) {
+ action->setText(item->args.label);
+ }
+ if(item->args.icon) {
+ action->setIcon(QIcon::fromTheme(item->args.icon));
+ }
+ toolbar->addAction(action);
+
+ UiVar* var = uic_widget_var(obj->ctx, obj->ctx, nullptr, item->args.varname, UI_VAR_INTEGER);
+ UiEventWrapper *event = new UiEventWrapper(obj, item->args.onchange, item->args.onchangedata);
+ event->var = var;
+ event->customdata1 = action;
+ event->prepare_event = toolbar_togglebutton_event;
+ action->connect(action, SIGNAL(triggered()), event, SLOT(slot()));
+ action->connect(action, SIGNAL(destroyed()), event, SLOT(destroy()));
+}
+
+void ui_toolbar_add_menu(UiObject *obj, QToolBar *toolbar, UiToolbarMenuItem *item) {
+
+}
#include "toolkit.h"
#include "../ui/toolbar.h"
+#include "../common/toolbar.h"
#include <QToolBar>
+QToolBar* ui_create_toolbar(UiObject *obj);
-
+void ui_toolbar_add_item(UiObject *obj, QToolBar *toolbar, UiToolbarItem *item);
+void ui_toolbar_add_toggleitem(UiObject *obj, QToolBar *toolbar, UiToolbarToggleItem *item);
+void ui_toolbar_add_menu(UiObject *obj, QToolBar *toolbar, UiToolbarMenuItem *item);
#endif /* TOOLBAR_H */
if(!simple) {
ui_add_menus(obj, window);
- //QToolBar *toolbar = ui_create_toolbar(obj);
- //window->addToolBar(Qt::TopToolBarArea, toolbar);
+ QToolBar *toolbar = ui_create_toolbar(obj);
+ if(toolbar) {
+ window->addToolBar(Qt::TopToolBarArea, toolbar);
+ }
}
QBoxLayout *box = new QVBoxLayout();