#include <stdio.h>
#include <stdlib.h>
#include "button.h"
#include "container.h"
#include "../common/context.h"
#include <cx/mempool.h>
#include <cx/linked_list.h>
#include <cx/array_list.h>
#include <cx/compare.h>
#include <Xm/XmAll.h>
UIWIDGET ui_button_create(UiObject* obj, UiButtonArgs args) {
Arg xargs[
16];
int n =
0;
UiContainerPrivate *ctn = ui_obj_container(obj);
UI_APPLY_LAYOUT(ctn->layout, args);
Widget parent = ctn->prepare(ctn, xargs, &n);
XmString label =
NULL;
if(args.label) {
label = XmStringCreateLocalized((
char*)args.label);
XtSetArg(xargs[n], XmNlabelString, label); n++;
}
char *name = args.name ? (
char*)args.name :
"button";
Widget button = XmCreatePushButton(parent, name, xargs, n);
XtManageChild(button);
ctn->add(ctn, button);
ui_set_widget_groups(obj->ctx, button, args.groups);
if(args.onclick) {
UiEventData *eventdata = malloc(
sizeof(UiEventData));
eventdata->callback = args.onclick;
eventdata->userdata = args.onclickdata;
eventdata->obj = obj;
eventdata->value =
0;
XtAddCallback(
button,
XmNactivateCallback,
(XtCallbackProc)ui_push_button_callback,
eventdata);
XtAddCallback(
button,
XmNdestroyCallback,
(XtCallbackProc)ui_destroy_eventdata,
eventdata);
}
XmStringFree(label);
return button;
}
void ui_push_button_callback(Widget widget, UiEventData *event, XtPointer d) {
UiEvent e;
e.obj = event->obj;
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.intval = event->value;
event->callback(&e, event->userdata);
}
UIWIDGET ui_togglebutton_create(UiObject* obj, UiToggleArgs args) {
Arg xargs[
16];
int n =
0;
UiContainerPrivate *ctn = ui_obj_container(obj);
UI_APPLY_LAYOUT(ctn->layout, args);
Widget parent = ctn->prepare(ctn, xargs, &n);
XtSetArg(xargs[n], XmNfillOnSelect, True); n++;
XtSetArg(xargs[n], XmNindicatorOn, False); n++;
XmString label =
NULL;
if(args.label) {
label = XmStringCreateLocalized((
char*)args.label);
XtSetArg(xargs[n], XmNlabelString, label); n++;
}
char *name = args.name ? (
char*)args.name :
"togglebutton";
Widget button = XmCreateToggleButton(parent, name, xargs, n);
XtManageChild(button);
ctn->add(ctn, button);
ui_set_widget_groups(obj->ctx, button, args.groups);
ui_bind_togglebutton(obj, button, args.varname, args.value, args.onchange, args.onchangedata, args.enable_group);
XmStringFree(label);
return button;
}
UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) {
Arg xargs[
16];
int n =
0;
UiContainerPrivate *ctn = ui_obj_container(obj);
UI_APPLY_LAYOUT(ctn->layout, args);
Widget parent = ctn->prepare(ctn, xargs, &n);
XmString label =
NULL;
if(args.label) {
label = XmStringCreateLocalized((
char*)args.label);
XtSetArg(xargs[n], XmNlabelString, label); n++;
}
char *name = args.name ? (
char*)args.name :
"button";
Widget button = XmCreateToggleButton(parent, name, xargs, n);
XtManageChild(button);
ctn->add(ctn, button);
ui_set_widget_groups(obj->ctx, button, args.groups);
ui_bind_togglebutton(obj, button, args.varname, args.value, args.onchange, args.onchangedata, args.enable_group);
XmStringFree(label);
return button;
}
UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs args) {
return ui_checkbox_create(obj, args);
}
static void togglebutton_changed(Widget w, UiVarEventData *event, XmToggleButtonCallbackStruct *tb) {
if(event->value >
0) {
if(tb->set) {
ui_set_group(event->obj->ctx, event->value);
}
else {
ui_unset_group(event->obj->ctx, event->value);
}
}
UiEvent e;
e.obj = event->obj;
e.window = e.obj->window;
e.document = e.obj->ctx->document;
e.eventdata =
NULL;
e.intval = XmToggleButtonGetState(w);
if(event->callback) {
event->callback(&e, event->userdata);
}
if(event->var && event->var->value) {
UiInteger *v = event->var->value;
v->value = e.intval;
ui_notify_evt(v->observers, &e);
}
}
void ui_bind_togglebutton(
UiObject *obj,
Widget widget,
const char *varname,
UiInteger *value,
ui_callback onchange,
void *onchangedata,
int enable_state)
{
UiVar* var = uic_widget_var(obj->ctx, obj->ctx, value, varname,
UI_VAR_INTEGER);
if(var) {
value = (UiInteger*)var->value;
value->obj = widget;
value->get = ui_togglebutton_get;
value->set = ui_togglebutton_set;
if(value->value) {
XmToggleButtonSetState(widget, True, False);
}
}
UiVarEventData *event = malloc(
sizeof(UiVarEventData));
event->obj = obj;
event->callback = onchange;
event->userdata = onchangedata;
event->var = var;
event->observers =
NULL;
event->value = enable_state;
XtAddCallback(
widget,
XmNvalueChangedCallback,
(XtCallbackProc)togglebutton_changed,
event);
XtAddCallback(
widget,
XmNdestroyCallback,
(XtCallbackProc)ui_destroy_eventdata,
event);
}
int64_t ui_togglebutton_get(UiInteger *i) {
Widget togglebutton = i->obj;
Boolean state = XmToggleButtonGetState(togglebutton);
i->value = state;
return state;
}
void ui_togglebutton_set(UiInteger *i,
int64_t value) {
Widget togglebutton = i->obj;
i->value = value;
XmToggleButtonSetState(togglebutton, (Boolean)value, False);
}
static void destroy_list(Widget w, CxList *list, XtPointer d) {
cxListDestroy(list);
}
static void radiobutton_changed(Widget w, UiVarEventData *event, XmToggleButtonCallbackStruct *tb) {
if(event->value >
0) {
if(tb->set) {
ui_set_group(event->obj->ctx, event->value);
}
else {
ui_unset_group(event->obj->ctx, event->value);
}
}
if(!tb->set) {
return;
}
UiInteger *value =
NULL;
int64_t v =
0;
if(event->var) {
value = event->var->value;
CxList *list = value->obj;
CxIterator i = cxListIterator(list);
cx_foreach(Widget, button, i) {
Boolean state = False;
if(button == w) {
value->value = i.index+
1;
state = True;
}
XmToggleButtonSetState(button, state, False);
}
v = value->value;
}
UiEvent e;
e.obj = event->obj;
e.window = e.obj->window;
e.document = e.obj->ctx->document;
e.eventdata = value;
e.intval = v;
if(event->callback) {
event->callback(&e, event->userdata);
}
if(value) {
ui_notify_evt(value->observers, &e);
}
}
UIWIDGET ui_radiobutton_create(UiObject* obj, UiToggleArgs args) {
Arg xargs[
16];
int n =
0;
UiContainerPrivate *ctn = ui_obj_container(obj);
UI_APPLY_LAYOUT(ctn->layout, args);
Widget parent = ctn->prepare(ctn, xargs, &n);
XtSetArg(xargs[n], XmNindicatorType, XmONE_OF_MANY_ROUND); n++;
XmString label =
NULL;
if(args.label) {
label = XmStringCreateLocalized((
char*)args.label);
XtSetArg(xargs[n], XmNlabelString, label); n++;
}
char *name = args.name ? (
char*)args.name :
"button";
Widget button = XmCreateToggleButton(parent, name, xargs, n);
XtManageChild(button);
ctn->add(ctn, button);
ui_set_widget_groups(obj->ctx, button, args.groups);
UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.value, args.varname,
UI_VAR_INTEGER);
if(var) {
UiInteger *value = var->value;
CxList *rb = value->obj;
if(!rb) {
rb = cxArrayListCreateSimple(
CX_STORE_POINTERS,
4);
value->obj = rb;
value->get = ui_radiobutton_get;
value->set = ui_radiobutton_set;
XtAddCallback(
button,
XmNdestroyCallback,
(XtCallbackProc)destroy_list,
rb);
}
cxListAdd(rb, button);
if(cxListSize(rb) == value->value) {
XmToggleButtonSetState(button, True, False);
}
}
UiVarEventData *event = malloc(
sizeof(UiVarEventData));
event->obj = obj;
event->callback = args.onchange;
event->userdata = args.onchangedata;
event->observers =
NULL;
event->var = var;
event->value = args.enable_group;
XtAddCallback(
button,
XmNvalueChangedCallback,
(XtCallbackProc)radiobutton_changed,
event);
XtAddCallback(
button,
XmNdestroyCallback,
(XtCallbackProc)ui_destroy_eventdata,
event);
XmStringFree(label);
return button;
}
int64_t ui_radiobutton_get(UiInteger *i) {
return i->value;
}
void ui_radiobutton_set(UiInteger *i,
int64_t value) {
CxList *list = i->obj;
if(i->value >
0) {
Widget current = cxListAt(list, i->value-
1);
if(current) {
XmToggleButtonSetState(current, False, False);
}
}
if(value >
0 && value <= cxListSize(list)) {
Widget button = cxListAt(list, value-
1);
if(button) {
XmToggleButtonSetState(button, True, False);
i->value = value;
}
}
}