#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "toolbar.h"
#include "button.h"
#include "image.h"
#include "tree.h"
#include <ucx/mempool.h>
#include "../common/context.h"
static UcxMap *toolbar_items;
static UcxList *defaults;
void ui_toolbar_init() {
toolbar_items = ucx_map_new(
16);
}
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_toolitem_img(
char *name,
char *label,
char *img, ui_callback f,
void *udata) {
UiToolItem *item = malloc(
sizeof(UiToolItem));
item->item.add_to = (ui_toolbar_add_f)add_toolitem_widget;
item->label = label;
item->image = img;
item->callback = f;
item->userdata = udata;
item->isimportant =
0;
item->groups =
NULL;
ucx_map_cstr_put(toolbar_items, name, item);
}
void ui_toolitem_vstgr(
char *name,
char *stockid,
int isimportant,
ui_callback f,
void *userdata,
va_list ap)
{
UiStToolItem *item = malloc(
sizeof(UiStToolItem));
item->item.add_to = (ui_toolbar_add_f)add_toolitem_st_widget;
item->stockid = stockid;
item->callback = f;
item->userdata = userdata;
item->groups =
NULL;
item->isimportant = isimportant;
int group;
while((group = va_arg(ap,
int)) != -
1) {
item->groups = ucx_list_append(item->groups, (
void*)(
intptr_t)group);
}
ucx_map_cstr_put(toolbar_items, name, item);
}
void ui_toolitem_toggle(
const char *name,
const char *label,
const char *img, UiInteger *i) {
UiToggleToolItem *item = malloc(
sizeof(UiToggleToolItem));
item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget;
item->label = label;
item->image = img;
item->stockid =
NULL;
item->groups =
NULL;
item->isimportant =
0;
item->value = i;
item->var =
NULL;
ucx_map_cstr_put(toolbar_items, name, item);
}
void ui_toolitem_toggle_st(
const char *name,
const char *stockid, UiInteger *i) {
UiToggleToolItem *item = malloc(
sizeof(UiToggleToolItem));
item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget;
item->label =
NULL;
item->image =
NULL;
item->stockid = stockid;
item->groups =
NULL;
item->isimportant =
0;
item->value = i;
item->var =
NULL;
ucx_map_cstr_put(toolbar_items, name, item);
}
void ui_toolitem_toggle_nv(
const char *name,
const char *label,
const char *img,
const char *intvar) {
UiToggleToolItem *item = malloc(
sizeof(UiToggleToolItem));
item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget;
item->label = label;
item->image = img;
item->stockid =
NULL;
item->groups =
NULL;
item->isimportant =
0;
item->value =
NULL;
item->var = intvar;
ucx_map_cstr_put(toolbar_items, name, item);
}
void ui_toolitem_toggle_stnv(
const char *name,
const char *stockid,
const char *intvar) {
UiToggleToolItem *item = malloc(
sizeof(UiToggleToolItem));
item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget;
item->label =
NULL;
item->image =
NULL;
item->stockid = stockid;
item->groups =
NULL;
item->isimportant =
0;
item->value =
NULL;
item->var = intvar;
ucx_map_cstr_put(toolbar_items, name, item);
}
void ui_toolbar_combobox(
char *name,
UiList *list,
ui_getvaluefunc getvalue,
ui_callback f,
void *udata)
{
UiToolbarComboBox *cb = malloc(
sizeof(UiToolbarComboBox));
cb->item.add_to = (ui_toolbar_add_f)add_toolbar_combobox;
UiVar *var = malloc(
sizeof(UiVar));
var->value = list;
var->type =
UI_VAR_SPECIAL;
var->from =
NULL;
var->from_ctx =
NULL;
cb->var = var;
cb->getvalue = getvalue;
cb->callback = f;
cb->userdata = udata;
ucx_map_cstr_put(toolbar_items, name, cb);
}
void ui_toolbar_combobox_str(
char *name,
UiList *list,
ui_callback f,
void *udata)
{
ui_toolbar_combobox(name, list, ui_strmodel_getvalue, f, udata);
}
void ui_toolbar_combobox_nv(
char *name,
char *listname,
ui_getvaluefunc getvalue,
ui_callback f,
void *udata)
{
UiToolbarComboBoxNV *cb = malloc(
sizeof(UiToolbarComboBoxNV));
cb->item.add_to = (ui_toolbar_add_f)add_toolbar_combobox_nv;
cb->listname = listname;
cb->getvalue = getvalue;
cb->callback = f;
cb->userdata = udata;
ucx_map_cstr_put(toolbar_items, name, cb);
}
void ui_toolbar_add_default(
char *name) {
char *s = strdup(name);
defaults = ucx_list_append(defaults, s);
}
GtkWidget* ui_create_toolbar(UiObject *obj) {
if(!defaults) {
return NULL;
}
GtkWidget *toolbar = gtk_toolbar_new();
#ifdef UI_GTK3
gtk_style_context_add_class(
gtk_widget_get_style_context(toolbar),
GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
#endif
GtkToolbar *tb =
GTK_TOOLBAR(toolbar);
UCX_FOREACH(elm, defaults) {
UiToolItemI *item = ucx_map_cstr_get(toolbar_items, elm->data);
if(item) {
item->add_to(tb, item, obj);
}
else if(!strcmp(elm->data,
"@separator")) {
gtk_toolbar_insert(tb, gtk_separator_tool_item_new(), -
1);
}
else {
fprintf(stderr,
"UI Error: Unknown toolbar item: %s\n", elm->data);
}
}
return toolbar;
}
void add_toolitem_widget(GtkToolbar *tb, UiToolItem *item, UiObject *obj) {
GtkToolItem *button = gtk_tool_button_new(
NULL, item->label);
gtk_tool_item_set_homogeneous(button,
FALSE);
if(item->image) {
GdkPixbuf *pixbuf = ui_get_image(item->image);
GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf);
gtk_tool_button_set_icon_widget(
GTK_TOOL_BUTTON(button), image);
}
else {
gtk_tool_item_set_is_important(button,
TRUE);
}
if(item->callback) {
UiEventData *event = ucx_mempool_malloc(
obj->ctx->mempool,
sizeof(UiEventData));
event->obj = obj;
event->userdata = item->userdata;
event->callback = item->callback;
g_signal_connect(
button,
"clicked",
G_CALLBACK(ui_button_clicked),
event);
}
gtk_toolbar_insert(tb, button, -
1);
if(item->groups) {
uic_add_group_widget(obj->ctx, button, (ui_enablefunc)ui_set_enabled, item->groups);
}
}
void add_toolitem_st_widget(GtkToolbar *tb, UiStToolItem *item, UiObject *obj) {
GtkToolItem *button = gtk_tool_button_new_from_stock(item->stockid);
gtk_tool_item_set_homogeneous(button,
FALSE);
if(item->isimportant) {
gtk_tool_item_set_is_important(button,
TRUE);
}
if(item->callback) {
UiEventData *event = ucx_mempool_malloc(
obj->ctx->mempool,
sizeof(UiEventData));
event->obj = obj;
event->userdata = item->userdata;
event->callback = item->callback;
g_signal_connect(
button,
"clicked",
G_CALLBACK(ui_button_clicked),
event);
}
gtk_toolbar_insert(tb, button, -
1);
if(item->groups) {
uic_add_group_widget(obj->ctx, button, (ui_enablefunc)ui_set_enabled, item->groups);
}
}
void add_toolitem_toggle_widget(GtkToolbar *tb, UiToggleToolItem *item, UiObject *obj) {
GtkToolItem *button;
if(item->stockid) {
button = gtk_toggle_tool_button_new_from_stock(item->stockid);
}
else {
button = gtk_toggle_tool_button_new();
gtk_tool_item_set_homogeneous(button,
FALSE);
if(item->label) {
gtk_tool_button_set_label(
GTK_TOOL_BUTTON(button), item->label);
}
if(item->image) {
GdkPixbuf *pixbuf = ui_get_image(item->image);
GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf);
gtk_tool_button_set_icon_widget(
GTK_TOOL_BUTTON(button), image);
}
}
UiVar *var;
if(item->value) {
var = malloc(
sizeof(UiVar));
var->value = item->value;
var->type =
UI_VAR_SPECIAL;
var->from =
NULL;
var->from_ctx =
NULL;
}
else {
var = uic_create_var(obj->ctx, item->var,
UI_VAR_INTEGER);
}
if(var->value) {
UiInteger *i = var->value;
i->get = ui_tool_toggle_button_get;
i->set = ui_tool_toggle_button_set;
i->obj = button;
if(i->value !=
0) {
gtk_toggle_tool_button_set_active(
GTK_TOGGLE_TOOL_BUTTON(button),
TRUE);
}
}
UiEventData *event = ucx_mempool_malloc(
obj->ctx->mempool,
sizeof(UiEventData));
event->obj = obj;
event->userdata = var;
event->callback =
NULL;
g_signal_connect(
button,
"toggled",
G_CALLBACK(ui_tool_button_toggled),
event);
gtk_toolbar_insert(tb, button, -
1);
if(item->groups) {
uic_add_group_widget(obj->ctx, button, (ui_enablefunc)ui_set_enabled, item->groups);
}
}
void ui_tool_button_toggled(GtkToggleToolButton *widget, UiEventData *event) {
UiEvent e;
e.obj = event->obj;
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.eventdata =
NULL;
e.intval = gtk_toggle_tool_button_get_active(widget);
UiVar *var = event->userdata;
UiInteger *i = var->value;
ui_notify_evt(i->observers, &e);
}
int64_t ui_tool_toggle_button_get(UiInteger *integer) {
integer->value = gtk_toggle_tool_button_get_active(
GTK_TOGGLE_TOOL_BUTTON(integer->obj));
return integer->value;
}
void ui_tool_toggle_button_set(UiInteger *integer,
int64_t value) {
gboolean s = value !=
0 ?
TRUE :
FALSE;
gtk_toggle_tool_button_set_active(
GTK_TOGGLE_TOOL_BUTTON(integer->obj), s);
integer->value = s;
}
void add_toolbar_combobox(GtkToolbar *tb, UiToolbarComboBox *cb, UiObject *obj) {
UiModel *modelinfo = ui_model(obj->ctx,
UI_STRING,
"", -
1);
modelinfo->getvalue = cb->getvalue;
UiListModel *model = ui_list_model_new(obj, cb->var, modelinfo);
GtkWidget *combobox = ui_create_combobox(obj, model, cb->callback, cb->userdata);
GtkToolItem *item = gtk_tool_item_new();
gtk_container_add(
GTK_CONTAINER(item), combobox);
gtk_toolbar_insert(tb, item, -
1);
}
void add_toolbar_combobox_nv(GtkToolbar *tb, UiToolbarComboBoxNV *cb, UiObject *obj) {
UiVar *var = uic_create_var(obj->ctx, cb->listname,
UI_VAR_LIST);
if(var) {
UiModel *modelinfo = ui_model(obj->ctx,
UI_STRING,
"", -
1);
modelinfo->getvalue = cb->getvalue;
UiListModel *model = ui_list_model_new(obj, var, modelinfo);
GtkWidget *combobox = ui_create_combobox(obj, model, cb->callback, cb->userdata);
GtkToolItem *item = gtk_tool_item_new();
gtk_container_add(
GTK_CONTAINER(item), combobox);
gtk_toolbar_insert(tb, item, -
1);
}
}