foo
authorJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 9 Jan 2020 08:17:59 +0000 (10:17 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 9 Jan 2020 08:17:59 +0000 (10:17 +0200)
src/main.c
src/widgets.c
src/widgets.h

index b49c9e3..12c6ced 100644 (file)
@@ -1,29 +1,28 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <ctype.h>
 #include <windows.h>
 #include "widgets.h"
 #include "rawdisk.h"
 
 static struct wgt_window *win;
 static struct wgt_widget *lb_instto, *bn_inst, *bn_cancel, *cb_devs, *ck_usbonly;
+
 static struct rawdisk_device rawdev[64];
+static const char *items[64];
 static int num_rawdev;
 
+
+static void update_disks(void);
 static void onclick(struct wgt_widget *w);
 static void onmodify(struct wgt_widget *w);
 
+
 int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprevinst, char *cmdline, int showcmd)
 {
-       int i, x, y;
+       int x, y;
        MSG msg;
-       static const char *items[64];
 
-       if((num_rawdev = rawdisk_detect(rawdev, sizeof rawdev / sizeof *rawdev)) == -1) {
-               return 1;
-       }
-       for(i=0; i<num_rawdev; i++) {
-               items[i] = rawdev[i].name;
-       }
 
        if(!(win = wgt_window("256boss USB stick installer", 400, 300))) {
                return 1;
@@ -31,8 +30,7 @@ int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprevinst, char *cmdline, int show
        lb_instto = wgt_label(win, "Install to device:", 10, 10);
 
        x = wgt_xpos_after(lb_instto, WGT_AUTO);
-       cb_devs = wgt_combo(win, items, num_rawdev, 0, x, 10, WGT_AUTOMIN(30), WGT_AUTO,
-                       onmodify);
+       cb_devs = wgt_combo(win, items, num_rawdev, 0, x, 10, 200, WGT_AUTO, onmodify);
 
        y = wgt_ypos_after(cb_devs, 16);
        ck_usbonly = wgt_checkbox(win, "only show USB devices", 1, x, y,
@@ -44,10 +42,7 @@ int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprevinst, char *cmdline, int show
        x = wgt_xpos_after(bn_inst, WGT_AUTO);
        bn_cancel = wgt_button(win, "Cancel", x, y, WGT_AUTO, WGT_AUTO, onclick);
 
-       if(!num_rawdev) {
-               wgt_disable_widget(cb_devs);
-               wgt_disable_widget(bn_inst);
-       }
+       update_disks();
 
        while(GetMessage(&msg, 0, 0, 0)) {
                TranslateMessage(&msg);
@@ -58,9 +53,71 @@ int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprevinst, char *cmdline, int show
        return 0;
 }
 
+static int isusbdev(struct rawdisk_device *dev)
+{
+       char *ptr = dev->path;
+       while(*ptr) {
+               int i;
+               char buf[3];
+               for(i=0; i<3; i++) {
+                       buf[i] = tolower(ptr[i]);
+               }
+               if(memcmp(buf, "usb", 3) == 0) {
+                       return 1;
+               }
+               ptr++;
+       }
+       return 0;
+}
+
+static void update_disks(void)
+{
+       int i;
+
+       for(i=0; i<num_rawdev; i++) {
+               free(rawdev[i].name);
+               free(rawdev[i].path);
+       }
+
+       if((num_rawdev = rawdisk_detect(rawdev, sizeof rawdev / sizeof *rawdev)) == -1) {
+               MessageBox(0, "Failed to detect storage devices!", 0, MB_OK);
+               exit(1);
+       }
+
+       if(wgt_checkbox_checked(ck_usbonly)) {
+               for(i=0; i<num_rawdev; i++) {
+                       if(!isusbdev(rawdev + i)) {
+                               free(rawdev[i].name);
+                               free(rawdev[i].path);
+                               rawdev[i] = rawdev[--num_rawdev];
+                       }
+               }
+       }
+
+       for(i=0; i<num_rawdev; i++) {
+               items[i] = rawdev[i].name;
+       }
+
+       wgt_combo_setitems(cb_devs, items, num_rawdev);
+
+       if(num_rawdev) {
+               wgt_enable_widget(cb_devs);
+               wgt_enable_widget(bn_inst);
+       } else {
+               wgt_disable_widget(cb_devs);
+               wgt_disable_widget(bn_inst);
+       }
+}
+
 static void onclick(struct wgt_widget *w)
 {
-       MessageBox(0, "clicked", "clicked", MB_OK);
+       if(w == bn_inst) {
+               MessageBox(0, "clicked", "clicked", MB_OK);
+       } else if(w == bn_cancel) {
+               PostQuitMessage(0);
+       } else if(w == ck_usbonly) {
+               update_disks();
+       }
 }
 
 static void onmodify(struct wgt_widget *w)
index 707d515..2ad9983 100644 (file)
@@ -285,25 +285,12 @@ struct wgt_widget *wgt_checkbox(struct wgt_window *win, const char *text, int on
        return w;
 }
 
-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)
+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, res;
-       struct wgt_widget *w;
+       int i, max_width, max_height, sum_height;
        struct wgt_rect textsz;
 
-       if(!(w = calloc(1, sizeof *w))) {
-               fprintf(stderr, "wgt_combo: failed to allocate widget structure\n");
-               return 0;
-       }
-       w->win = win;
-
-       if(!(w->itemlist = malloc(num_items * sizeof *w->itemlist))) {
-               fprintf(stderr, "wgt_combo: failed to allocate item list\n");
-               free(w);
-               return 0;
-       }
-
        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;
@@ -318,10 +305,35 @@ struct wgt_widget *wgt_combo(struct wgt_window *win, const char **items, int num
        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, res;
+       struct wgt_widget *w;
+       struct wgt_rect rect;
+
+       if(!(w = calloc(1, sizeof *w))) {
+               fprintf(stderr, "wgt_combo: failed to allocate widget structure\n");
+               return 0;
+       }
+       w->win = win;
+
+       if(!(w->itemlist = malloc(num_items * sizeof *w->itemlist))) {
+               fprintf(stderr, "wgt_combo: failed to allocate item list\n");
+               free(w);
+               return 0;
+       }
+
+       combosize(win, items, num_items, width, height, &rect);
 
        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;
@@ -350,8 +362,8 @@ struct wgt_widget *wgt_combo(struct wgt_window *win, const char **items, int num
 
        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;
@@ -359,6 +371,60 @@ struct wgt_widget *wgt_combo(struct wgt_window *win, const char **items, int num
        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);
index 33cd490..caf4a4e 100644 (file)
@@ -37,6 +37,11 @@ struct wgt_widget *wgt_checkbox(struct wgt_window *win, const char *text, int on
 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);
 
+void wgt_checkbox_check(struct wgt_widget *w);
+void wgt_checkbox_uncheck(struct wgt_widget *w);
+int wgt_checkbox_checked(struct wgt_widget *w);
+
+int wgt_combo_setitems(struct wgt_widget *w, const char **items, int num_items);
 int wgt_combo_selected(struct wgt_widget *w);
 const char *wgt_get_combo_item(struct wgt_widget *w, int idx);