char **itemlist;
int num_items;
+ int disabled;
+
wgt_callback cb_click;
wgt_callback cb_modify;
};
memset(&wc, 0, sizeof wc);
wc.hInstance = hinst;
- wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
+ wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.lpszClassName = win->cname;
win->dc = GetDC(win->handle);
SetLastError(0);
if(!SetWindowLong(win->handle, GWL_USERDATA, (long)win) && (err = GetLastError())) {
- fprintf(stderr, "wgt_create_window: failed to store window user data (err: %d)\n", err);
+ fprintf(stderr, "wgt_create_window: failed to store window user data (err: %d)\n", (int)err);
UnregisterClass(title, hinst);
DestroyWindow(win->handle);
return 0;
free(w->itemlist);
}
+void wgt_enable_widget(struct wgt_widget *w)
+{
+ w->disabled = 0;
+ EnableWindow(w->handle, 1);
+}
+
+void wgt_disable_widget(struct wgt_widget *w)
+{
+ w->disabled = 1;
+ EnableWindow(w->handle, 0);
+}
+
+int wgt_widget_enabled(struct wgt_widget *w)
+{
+ return !w->disabled;
+}
+
struct wgt_window *wgt_widget_window(struct wgt_widget *w)
{
return w->win;
{
struct wgt_widget *w;
struct wgt_rect textsz;
+ int check_width;
if(!(w = calloc(1, sizeof *w))) {
fprintf(stderr, "wgt_checkbox: failed to allocate widget structure\n");
}
w->win = win;
+ check_width = GetSystemMetrics(SM_CXMENUCHECK);
+
if(width < 0 || height < 0) {
wgt_string_size(win, text, &textsz);
- if(width < 0) width = textsz.width + 32; /* XXX */
+ if(width < 0) width = textsz.width + check_width + 10;
if(height < 0) height = textsz.height;
}
w->rect.width = width;
w->rect.height = height;
- w->cb_modify = modfunc;
+ w->cb_click = modfunc; /* BN_CLICKED is sent for checkbox state changes */
w->next = win->wlist;
win->wlist = w;
return w;
}
+static void combosize(struct wgt_window *win, const char **items, int num_items,
+ int width, int height, struct wgt_rect *sz)
+{
+ int i, max_width, max_height, sum_height;
+ struct wgt_rect textsz;
+
+ wgt_string_size(win, "00", &textsz);
+ max_width = width < 0 && width != WGT_AUTO ? -width : textsz.width;
+ max_height = height < 0 && height != WGT_AUTO ? -height : textsz.height;
+ sum_height = num_items ? 0 : max_height;
+
+ for(i=0; i<num_items; i++) {
+ wgt_string_size(win, items[i], &textsz);
+ if(textsz.width > max_width) max_width = textsz.width;
+ if(textsz.height > max_height) max_height = textsz.height;
+ sum_height += textsz.height;
+ }
+ if(width < 0) width = max_width * 3 / 2;
+ if(height < 0) height = sum_height * 2;
+
+ sz->width = width;
+ sz->y = max_height;
+ sz->height = height;
+}
+
struct wgt_widget *wgt_combo(struct wgt_window *win, const char **items, int num_items,
int sel, int x, int y, int width, int height, wgt_callback modfunc)
{
- int i, max_width, max_height, sum_height, res;
+ int i, res;
struct wgt_widget *w;
- struct wgt_rect textsz;
+ struct wgt_rect rect;
if(!(w = calloc(1, sizeof *w))) {
fprintf(stderr, "wgt_combo: failed to allocate widget structure\n");
return 0;
}
- max_width = max_height = sum_height = 0;
-
- for(i=0; i<num_items; i++) {
- wgt_string_size(win, items[i], &textsz);
- if(textsz.width > max_width) max_width = textsz.width;
- if(textsz.height > max_height) max_height = textsz.height;
- sum_height += textsz.height;
- }
- if(width < 0) width = max_width * 3 / 2;
- if(height < 0) height = sum_height * 2;
-
+ combosize(win, items, num_items, width, height, &rect);
- if(!(w->handle = CreateWindow("COMBOBOX", items[0],
+ if(!(w->handle = CreateWindow("COMBOBOX", items[0] ? items[0] : "",
WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS,
- x, y, width, height, win->handle, 0, GetModuleHandle(0), 0))) {
+ x, y, rect.width, rect.height, win->handle, 0, GetModuleHandle(0), 0))) {
fprintf(stderr, "wgt_combo: failed to create window\n");
free(w);
return 0;
if(sel < 0) sel = 0;
if(sel >= num_items) sel = num_items - 1;
- SendMessage(w->handle, CB_SETCURSEL, sel, 0);
+ if(sel >= 0) {
+ SendMessage(w->handle, CB_SETCURSEL, sel, 0);
+ }
w->rect.x = x;
w->rect.y = y;
- w->rect.width = width;
- w->rect.height = max_height;
+ w->rect.width = rect.width;
+ w->rect.height = rect.y; /* single line height for layout purposes */
w->cb_modify = modfunc;
w->next = win->wlist;
return w;
}
+void wgt_checkbox_check(struct wgt_widget *w)
+{
+ SendMessage(w->handle, BM_SETCHECK, BST_CHECKED, 0);
+}
+
+void wgt_checkbox_uncheck(struct wgt_widget *w)
+{
+ SendMessage(w->handle, BM_SETCHECK, BST_UNCHECKED, 0);
+}
+
+int wgt_checkbox_checked(struct wgt_widget *w)
+{
+ return SendMessage(w->handle, BM_GETCHECK, 0, 0) == BST_CHECKED;
+}
+
+int wgt_combo_setitems(struct wgt_widget *w, const char **items, int num_items)
+{
+ int i;
+ char **newit;
+ struct wgt_rect size;
+
+ if(!(newit = malloc(num_items * sizeof *newit))) {
+ fprintf(stderr, "wgt_combo_setitems: failed to allocate item list\n");
+ return -1;
+ }
+ for(i=0; i<num_items; i++) {
+ if(!(newit[i] = strdup(items[i]))) {
+ fprintf(stderr, "wgt_combo_setitems: failed to allocate item\n");
+ while(--i >= 0) {
+ free(newit[i]);
+ }
+ free(newit);
+ return -1;
+ }
+ }
+
+ for(i=0; i<w->num_items; i++) {
+ free(w->itemlist[i]);
+ }
+ free(w->itemlist);
+ SendMessage(w->handle, CB_RESETCONTENT, 0, 0);
+
+ w->itemlist = newit;
+ w->num_items = num_items;
+
+ for(i=0; i<num_items; i++) {
+ SendMessage(w->handle, CB_ADDSTRING, 0, (long)w->itemlist[i]);
+ }
+
+ combosize(w->win, items, num_items, w->rect.width, WGT_AUTO, &size);
+ MoveWindow(w->handle, w->rect.x, w->rect.y, w->rect.width, size.height, TRUE);
+ return 0;
+}
+
int wgt_combo_selected(struct wgt_widget *w)
{
int sel = SendMessage(w->handle, CB_GETCURSEL, 0, 0);
default:
break;
}
-
+
default:
return DefWindowProc(wnd, msg, wparam, lparam);
}
w = w->next;
}
return 0;
-}
\ No newline at end of file
+}