it werks!
[instimg] / src / widgets.c
index 2d37973..1b97637 100644 (file)
@@ -3,6 +3,7 @@
 #include <string.h>
 #include <assert.h>
 #include <windows.h>
+#include <commctrl.h>
 #include "widgets.h"
 
 struct wgt_window {
@@ -12,6 +13,9 @@ struct wgt_window {
        HDC dc;
        char cname[32];
        struct wgt_widget *wlist;
+
+       int close_quit;
+       int (*cb_close)(struct wgt_window*);
 };
 
 struct wgt_widget {
@@ -34,6 +38,28 @@ struct wgt_widget {
 static LRESULT WINAPI event_handler(HWND win, unsigned int msg, WPARAM wparam, LPARAM lparam);
 static struct wgt_widget *find_widget(struct wgt_window *win, HWND handle);
 
+
+void *wgt_window_handle(struct wgt_window *win)
+{
+       return win->handle;
+}
+
+void *wgt_widget_handle(struct wgt_widget *w)
+{
+       return w->handle;
+}
+
+unsigned int wgt_window_xid(struct wgt_window *win)
+{
+       return 0;
+}
+
+unsigned int wgt_widget_xid(struct wgt_widget *w)
+{
+       return 0;
+}
+
+
 struct wgt_window *wgt_window(const char *title, int width, int height)
 {
        struct wgt_window *win;
@@ -43,11 +69,11 @@ struct wgt_window *wgt_window(const char *title, int width, int height)
        DWORD err;
        RECT rect;
 
-       if(!(win = malloc(sizeof *win))) {
+       if(!(win = calloc(1, sizeof *win))) {
                fprintf(stderr, "wgl_create_window: failed to allocate window structure\n");
                return 0;
        }
-       win->wlist = 0;
+       win->close_quit = 1;    /* by default quit when the window closes */
 
        tlen = strlen(title);
        if(tlen > sizeof win->cname - 10) {
@@ -72,7 +98,7 @@ struct wgt_window *wgt_window(const char *title, int width, int height)
                return 0;
        }
 
-       if(!(win->handle = CreateWindow(win->cname, title, WS_OVERLAPPEDWINDOW,
+       if(!(win->handle = CreateWindow(win->cname, title, WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME,
                        CW_USEDEFAULT, CW_USEDEFAULT, width, height, 0, 0, hinst, 0))) {
                fprintf(stderr, "wgt_create_window: failed to create window\n");
                UnregisterClass(title, hinst);
@@ -107,10 +133,16 @@ void wgt_destroy_window(struct wgt_window *win)
                free(w);
        }
 
-       ReleaseDC(win->handle, win->dc);
-       DestroyWindow(win->handle);
-       UnregisterClass(win->cname, GetModuleHandle(0));
+       if(win->handle) {
+               ReleaseDC(win->handle, win->dc);
+               DestroyWindow(win->handle);
+               UnregisterClass(win->cname, GetModuleHandle(0));
+       }
+}
 
+void wgt_free_window(struct wgt_window *win)
+{
+       wgt_destroy_window(win);
        free(win);
 }
 
@@ -120,6 +152,23 @@ void wgt_destroy_widget(struct wgt_widget *w)
        free(w->itemlist);
 }
 
+void wgt_resize_window(struct wgt_window *win, int width, int height)
+{
+       MoveWindow(win->handle, win->rect.x, win->rect.y, width, height, TRUE);
+       win->rect.width = width;
+       win->rect.height = height;
+}
+
+void wgt_quit_on_close(struct wgt_window *win, int quit)
+{
+       win->close_quit = quit;
+}
+
+void wgt_close_action(struct wgt_window *win, int (*func)(struct wgt_window*))
+{
+       win->cb_close = func;
+}
+
 void wgt_enable_widget(struct wgt_widget *w)
 {
        w->disabled = 0;
@@ -150,6 +199,20 @@ struct wgt_rect *wgt_widget_rect(struct wgt_widget *w, struct wgt_rect *rect)
        return &w->rect;
 }
 
+void wgt_move_widget(struct wgt_widget *w, int x, int y)
+{
+       MoveWindow(w->handle, x, y, w->rect.width, w->rect.height, TRUE);
+       w->rect.x = x;
+       w->rect.y = y;
+}
+
+void wgt_resize_widget(struct wgt_widget *w, int width, int height)
+{
+       MoveWindow(w->handle, w->rect.x, w->rect.y, width, height, TRUE);
+       w->rect.width = width;
+       w->rect.height = height;
+}
+
 int wgt_xpos_after(struct wgt_widget *w, int pad)
 {
        if(pad == WGT_AUTO) {
@@ -273,6 +336,7 @@ struct wgt_widget *wgt_checkbox(struct wgt_window *win, const char *text, int on
                free(w);
                return 0;
        }
+       SendMessage(w->handle, BM_SETCHECK, on ? BST_CHECKED : BST_UNCHECKED, 0);
 
        w->rect.x = x;
        w->rect.y = y;
@@ -361,6 +425,56 @@ struct wgt_widget *wgt_combo(struct wgt_window *win, const char **items, int num
        return w;
 }
 
+struct wgt_widget *wgt_progbar(struct wgt_window *win, int x, int y, int width, int height, int p)
+{
+       struct wgt_widget *w;
+       INITCOMMONCONTROLSEX commctrl;
+
+       commctrl.dwSize = sizeof commctrl;
+       commctrl.dwICC = ICC_PROGRESS_CLASS;
+       InitCommonControlsEx(&commctrl);
+
+       if(!(w = calloc(1, sizeof *w))) {
+               fprintf(stderr, "wgt_progbar: failed to allocate widget structure\n");
+               return 0;
+       }
+       w->win = win;
+
+       if(height < 0) {
+               height = GetSystemMetrics(SM_CYVSCROLL);
+       }
+
+       if(!(w->handle = CreateWindow(PROGRESS_CLASS, 0, WS_CHILD | WS_VISIBLE, x, y,
+                       width, height, win->handle, 0, GetModuleHandle(0), 0))) {
+               fprintf(stderr, "wgt_progbar: failed to create window\n");
+               free(w);
+               return 0;
+       }
+
+       /*
+       SendMessage(w->handle, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
+       SendMessage(w->handle, PBM_SETSTEP, 1, 0);
+       */
+       SendMessage(w->handle, PBM_SETPOS, p, 0);
+
+       w->rect.x = x;
+       w->rect.y = y;
+       w->rect.width = width;
+       w->rect.height = height;
+
+       w->next = win->wlist;
+       win->wlist = w;
+       return w;
+}
+
+void wgt_set_text(struct wgt_widget *w, const char *text)
+{
+       SendMessage(w->handle, WM_SETTEXT, 0, (long)text);
+
+       w->rect.width = wgt_string_size(w->win, text, 0);
+       MoveWindow(w->handle, w->rect.x, w->rect.y, w->rect.width, w->rect.height, TRUE);
+}
+
 void wgt_checkbox_check(struct wgt_widget *w)
 {
        SendMessage(w->handle, BM_SETCHECK, BST_CHECKED, 0);
@@ -432,6 +546,11 @@ const char *wgt_get_combo_item(struct wgt_widget *w, int idx)
        return w->itemlist[idx];
 }
 
+void wgt_set_progress(struct wgt_widget *w, int p)
+{
+       SendMessage(w->handle, PBM_SETPOS, p, 0);
+}
+
 static LRESULT WINAPI event_handler(HWND wnd, unsigned int msg, WPARAM wparam, LPARAM lparam)
 {
        int ncode;
@@ -442,8 +561,22 @@ static LRESULT WINAPI event_handler(HWND wnd, unsigned int msg, WPARAM wparam, L
 
        switch(msg) {
        case WM_CLOSE:
+               if(!win->cb_close || win->cb_close(win)) {
+                       if(win) {
+                               int quit = win->close_quit;
+                               wgt_destroy_window(win);
+                               memset(win, 0, sizeof *win);
+                               win->close_quit = quit;
+                       } else {
+                               DestroyWindow(wnd);
+                       }
+               }
+               break;
+
        case WM_DESTROY:
-               PostQuitMessage(0);
+               if(win && win->close_quit) {
+                       PostQuitMessage(0);
+               }
                break;
 
        case WM_COMMAND: