#include "button.h"
#include "widget.h"
#include <stdio.h>
#include <stdlib.h>
#include <cx/array_list.h>
#include <commctrl.h>
static W32WidgetClass button_widget_class = {
.eventproc = ui_button_eventproc,
.enable = w32_widget_default_enable,
.show = w32_widget_default_show,
.get_preferred_size = ui_button_get_preferred_size,
.destroy = w32_widget_default_destroy
};
static W32WidgetClass togglebutton_widget_class = {
.eventproc = ui_togglebutton_eventproc,
.enable = w32_widget_default_enable,
.show = w32_widget_default_show,
.get_preferred_size = ui_button_get_preferred_size,
.destroy = w32_widget_default_destroy
};
static W32WidgetClass radiobutton_widget_class = {
.eventproc = ui_radiobutton_eventproc,
.enable = w32_widget_default_enable,
.show = w32_widget_default_show,
.get_preferred_size = ui_button_get_preferred_size,
.destroy = w32_widget_default_destroy
};
UIWIDGET ui_button_create(UiObject *obj, UiButtonArgs *args) {
HINSTANCE hInstance = GetModuleHandle(
NULL);
UiContainerPrivate *container = ui_obj_container(obj);
HWND parent = ui_container_get_parent(container);
UiLayout layout =
UI_ARGS2LAYOUT(args);
HWND hwnd = CreateWindow(
"BUTTON",
args->label,
WS_VISIBLE |
WS_CHILD |
BS_PUSHBUTTON,
0,
0,
100,
30,
parent,
(
HMENU)
1,
hInstance,
NULL);
ui_win32_set_ui_font(hwnd);
W32Widget *widget = w32_widget_create(&button_widget_class, hwnd,
sizeof(UiWidget));
ui_container_add(container, widget, &layout);
UiWidget *btn = (UiWidget*)widget;
btn->obj = obj;
btn->callback = args->onclick;
btn->callbackdata = args->onclickdata;
return widget;
}
W32Size ui_button_get_preferred_size(W32Widget *widget) {
W32Size size;
size.width =
100;
size.height =
30;
SIZE sz;
if (Button_GetIdealSize(widget->hwnd, &sz)) {
size.width = sz.cx;
size.height = sz.cy;
}
return size;
}
int ui_button_eventproc(W32Widget *widget,
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam) {
UiWidget *w = (UiWidget*)widget;
if (uMsg !=
WM_COMMAND) {
return 0;
}
UiEvent e;
e.obj = w->obj;
e.document = e.obj->ctx->document;
e.window = e.obj->window;
e.eventdata =
NULL;
e.eventdatatype =
0;
e.intval =
0;
e.set = ui_get_setop();
if (w->callback) {
w->callback(&e, w->callbackdata);
}
return 0;
}
static UIWIDGET create_togglebutton(UiObject *obj, UiToggleArgs *args,
unsigned long type) {
HINSTANCE hInstance = GetModuleHandle(
NULL);
UiContainerPrivate *container = ui_obj_container(obj);
HWND parent = ui_container_get_parent(container);
UiLayout layout =
UI_ARGS2LAYOUT(args);
HWND hwnd = CreateWindow(
"BUTTON",
args->label,
WS_VISIBLE |
WS_CHILD | type,
0,
0,
100,
30,
parent,
(
HMENU)
1,
hInstance,
NULL);
ui_win32_set_ui_font(hwnd);
W32Widget *widget = w32_widget_create(&togglebutton_widget_class, hwnd,
sizeof(UiWidget));
ui_container_add(container, widget, &layout);
UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname,
UI_VAR_INTEGER);
if (var) {
UiInteger *i = var->value;
i->obj = widget;
i->get = ui_togglebutton_get;
i->set = ui_togglebutton_set;
if (i->value !=
0) {
SendMessage(hwnd,
BM_SETCHECK,
BST_CHECKED,
0);
}
}
UiWidget *btn = (UiWidget*)widget;
btn->obj = obj;
btn->var = var;
btn->callback = args->onchange;
btn->callbackdata = args->onchangedata;
return widget;
}
UIWIDGET ui_togglebutton_create(UiObject *obj, UiToggleArgs *args) {
return create_togglebutton(obj, args,
BS_AUTOCHECKBOX |
BS_PUSHLIKE);
}
UIWIDGET ui_checkbox_create(UiObject *obj, UiToggleArgs *args) {
return create_togglebutton(obj, args,
BS_AUTOCHECKBOX);
}
UIWIDGET ui_switch_create(UiObject *obj, UiToggleArgs *args) {
return create_togglebutton(obj, args,
BS_AUTOCHECKBOX);
}
int64_t ui_togglebutton_get(UiInteger *i) {
UiWidget *btn = (UiWidget*)i->obj;
LRESULT state = SendMessage(btn->widget.hwnd,
BM_GETCHECK,
0,
0);
i->value = state;
return state;
}
void ui_togglebutton_set(UiInteger *i,
int64_t v) {
UiWidget *btn = (UiWidget*)i->obj;
WPARAM state = v ?
BST_CHECKED :
BST_UNCHECKED;
SendMessage(btn->widget.hwnd,
BM_SETCHECK, state,
0);
i->value = v;
}
int ui_togglebutton_eventproc(W32Widget *widget,
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam) {
if (uMsg !=
WM_COMMAND) {
return 0;
}
UiWidget *w = (UiWidget*)widget;
UiEvent e;
e.obj = w->obj;
e.document = e.obj->ctx->document;
e.window = e.obj->window;
e.eventdata =
NULL;
e.eventdatatype =
0;
e.intval = SendMessage(w->widget.hwnd,
BM_GETCHECK,
0,
0);
e.set = ui_get_setop();
if (w->callback) {
w->callback(&e, w->callbackdata);
}
return 0;
}
UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs *args) {
HINSTANCE hInstance = GetModuleHandle(
NULL);
UiContainerPrivate *container = ui_obj_container(obj);
HWND parent = ui_container_get_parent(container);
UiLayout layout =
UI_ARGS2LAYOUT(args);
HWND hwnd = CreateWindow(
"BUTTON",
args->label,
WS_VISIBLE |
WS_CHILD |
BS_AUTORADIOBUTTON |
WS_GROUP ,
0,
0,
100,
30,
parent,
(
HMENU)
1,
hInstance,
NULL);
ui_win32_set_ui_font(hwnd);
W32Widget *widget = w32_widget_create(&radiobutton_widget_class, hwnd,
sizeof(UiWidget));
ui_container_add(container, widget, &layout);
UiWidget *btn = (UiWidget*)widget;
UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname,
UI_VAR_INTEGER);
if (var) {
UiInteger *i = var->value;
CxList *group =
NULL;
if (i->obj) {
group = i->obj;
}
else {
group = cxArrayListCreate(obj->ctx->allocator,
NULL,
CX_STORE_POINTERS,
8);
i->obj = group;
}
cxListAdd(group, btn);
if (i->value == cxListSize(group)) {
}
}
btn->obj = obj;
btn->var = var;
btn->callback = args->onchange;
btn->callbackdata = args->onchangedata;
return widget;
}
int ui_radiobutton_eventproc(W32Widget *widget,
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam) {
if (uMsg !=
WM_COMMAND) {
return 0;
}
UiWidget *w = (UiWidget*)widget;
int checked = SendMessage(w->widget.hwnd,
BM_GETCHECK,
0,
0);
if (!checked) {
return 0;
}
int b =
0;
if (w->var) {
UiInteger *i = w->var->value;
CxList *group = i->obj;
CxIterator iter = cxListIterator(group);
cx_foreach(UiWidget *, radiobutton, iter) {
if (radiobutton == w) {
i->value = iter.index
+1;
b = i->value;
}
else {
SendMessage(radiobutton->widget.hwnd,
BM_SETCHECK,
BST_UNCHECKED,
0);
}
}
}
UiEvent e;
e.obj = w->obj;
e.document = e.obj->ctx->document;
e.window = e.obj->window;
e.eventdata =
NULL;
e.eventdatatype =
0;
e.intval = b;
e.set = ui_get_setop();
if (w->callback) {
w->callback(&e, w->callbackdata);
}
return 0;
}
int64_t ui_radiobutton_get(UiInteger *i) {
return i->value;
}
void ui_radiobutton_set(UiInteger *i,
int64_t v) {
CxList *group = i->obj;
CxIterator iter = cxListIterator(group);
cx_foreach(UiWidget *, radiobutton, iter) {
SendMessage(radiobutton->widget.hwnd,
BM_SETCHECK, iter.index
+1 == v ?
BST_CHECKED :
BST_UNCHECKED,
0);
}
i->value = v;
}