mirror of
https://gitea.nishi.boats/pyrite-dev/milsko
synced 2026-01-28 03:53:06 +00:00
move
git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@583 b9cfdab3-6d41-4d17-bbe4-086880011989
This commit is contained in:
327
src/dialog/colorpicker.c
Normal file
327
src/dialog/colorpicker.c
Normal file
@@ -0,0 +1,327 @@
|
||||
/* $Id$ */
|
||||
#include <Mw/Milsko.h>
|
||||
|
||||
#define WIN_SIZE 464
|
||||
#define PICKER_SIZE 360
|
||||
#define IMG_POS_X(w) ((w - PICKER_SIZE) / 2)
|
||||
#define IMG_POS_Y(h) ((h - PICKER_SIZE) / 2)
|
||||
#define SCROLL_BAR_WIDTH 16
|
||||
#define MARGIN (PICKER_SIZE / 32)
|
||||
#define COLOR_DISPLAY_HEIGHT 12
|
||||
|
||||
#define HSV_HUE_SEXTANT 256.
|
||||
#define HSV_HUE_STEPS (6. * HSV_HUE_SEXTANT)
|
||||
|
||||
#define HSV_HUE_MIN 0.
|
||||
#define HSV_HUE_MAX (HSV_HUE_STEPS - 1.)
|
||||
#define HSV_SAT_MIN 0.
|
||||
#define HSV_SAT_MAX 255.
|
||||
#define HSV_VAL_MIN 0.
|
||||
#define HSV_VAL_MAX 255.
|
||||
|
||||
typedef struct _MwHSV {
|
||||
MwBool generated : 1;
|
||||
MwU16 h : 11;
|
||||
MwU8 s;
|
||||
MwU8 v;
|
||||
} MwHSV;
|
||||
|
||||
typedef struct color_picker {
|
||||
MwWidget parent;
|
||||
MwWidget color_picker_img;
|
||||
MwWidget value_slider;
|
||||
MwWidget color_display;
|
||||
MwWidget color_display_text;
|
||||
MwWidget finish;
|
||||
MwLLPixmap color_picker_pixmap;
|
||||
double value;
|
||||
MwRGB chosen_color;
|
||||
unsigned char color_picker_image_data[PICKER_SIZE * PICKER_SIZE * 4];
|
||||
MwHSV hue_table[101753];
|
||||
} color_picker_t;
|
||||
|
||||
static void hsv2rgb(MwU32 h, MwU32 s, MwU32 v, MwU16* r, MwU16* g, MwU16* b) {
|
||||
MwU8 sextant = h >> 8;
|
||||
MwU16 ww;
|
||||
MwU32 h_fraction, d;
|
||||
|
||||
#define HSV_SWAPPTR(a, b) \
|
||||
do { \
|
||||
MwU16* tmp = a; \
|
||||
a = b; \
|
||||
b = tmp; \
|
||||
} while(0)
|
||||
|
||||
if(sextant & 2) {
|
||||
HSV_SWAPPTR(r, b);
|
||||
}
|
||||
if(sextant & 4) {
|
||||
|
||||
HSV_SWAPPTR(g, b);
|
||||
}
|
||||
if(!(sextant & 6)) {
|
||||
if(!(sextant & 1)) {
|
||||
HSV_SWAPPTR(r, g);
|
||||
}
|
||||
} else {
|
||||
if(sextant & 1) {
|
||||
HSV_SWAPPTR(r, g);
|
||||
}
|
||||
}
|
||||
|
||||
*g = v; /* Top level */
|
||||
|
||||
/* Perform actual calculations */
|
||||
|
||||
/**
|
||||
* Bottom level: v * (1.0 - s)
|
||||
* --> (v * (255 - s) + error_corr + 1) / 256
|
||||
*/
|
||||
ww = v * (255 - (s)); /* We don't use ~s to prevent size-promotion side effects */
|
||||
ww += 1; /* Error correction */
|
||||
ww += ww >> 8; /* Error correction */
|
||||
*b = ww >> 8;
|
||||
|
||||
h_fraction = h & 0xff; /* 0...255 */
|
||||
|
||||
if(!(sextant & 1)) {
|
||||
/* *r = ...slope_up...; */
|
||||
d = v * (MwU32)((0xff << 8) - (MwU16)(s * (0xff - h_fraction)));
|
||||
*r = d >> 16;
|
||||
} else {
|
||||
/* *r = ...slope_down...; */
|
||||
d = v * (MwU32)((0xff << 8) - (MwU16)(s * h_fraction));
|
||||
*r = d >> 16;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void color_picker_image_update(color_picker_t* picker) {
|
||||
MwU16 y, x;
|
||||
int n = 0;
|
||||
for(y = 0; y < PICKER_SIZE; y++) {
|
||||
for(x = 0; x < PICKER_SIZE; x++) {
|
||||
int i = ((y * PICKER_SIZE) + x) * 4;
|
||||
int _x = x - (PICKER_SIZE / 2);
|
||||
int _y = y - (PICKER_SIZE / 2);
|
||||
double dist = sqrt(_x * _x + _y * _y);
|
||||
|
||||
if(dist >= 180.) {
|
||||
picker->color_picker_image_data[i] = 0;
|
||||
picker->color_picker_image_data[i + 1] = 0;
|
||||
picker->color_picker_image_data[i + 2] = 0;
|
||||
picker->color_picker_image_data[i + 3] = 0;
|
||||
} else {
|
||||
MwHSV hsv_v;
|
||||
MwRGB color;
|
||||
if(picker->hue_table[n].generated == 0) {
|
||||
double xd = (M_PI / 180.) * ((double)_x);
|
||||
double yd = (M_PI / 180.) * ((double)_y);
|
||||
|
||||
float angle = atan2(yd, xd) - M_PI;
|
||||
float hue = (angle * 180.) / M_PI;
|
||||
|
||||
if(hue < 0.0) {
|
||||
hue += 360;
|
||||
}
|
||||
hsv_v.h = (hue) * (HSV_HUE_STEPS / 360.);
|
||||
hsv_v.s = (dist) * (HSV_SAT_MAX / 180.);
|
||||
picker->hue_table[n] = hsv_v;
|
||||
picker->hue_table[n].generated = 1;
|
||||
}
|
||||
|
||||
hsv_v = picker->hue_table[n];
|
||||
hsv_v.v = HSV_VAL_MAX - (picker->value * HSV_VAL_MAX);
|
||||
|
||||
hsv2rgb(hsv_v.h, hsv_v.s, hsv_v.v, &color.red, &color.green, &color.blue);
|
||||
|
||||
picker->color_picker_image_data[i] = color.red;
|
||||
picker->color_picker_image_data[i + 1] = color.green;
|
||||
picker->color_picker_image_data[i + 2] = color.blue;
|
||||
|
||||
picker->color_picker_image_data[i + 3] = 255;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(picker->color_picker_pixmap == NULL) {
|
||||
picker->color_picker_pixmap = MwLoadRaw(
|
||||
picker->parent, picker->color_picker_image_data, PICKER_SIZE, PICKER_SIZE);
|
||||
} else {
|
||||
MwReloadRaw(
|
||||
picker->parent, picker->color_picker_image_data, PICKER_SIZE, PICKER_SIZE, picker->color_picker_pixmap);
|
||||
}
|
||||
MwVaApply(picker->color_picker_img, MwNpixmap, picker->color_picker_pixmap, NULL);
|
||||
// printf("%d\n", n);
|
||||
}
|
||||
|
||||
static void color_picker_click(MwWidget handle, void* user, void* call) {
|
||||
color_picker_t* picker = user;
|
||||
MwLLMouse* mouse = call;
|
||||
char hexColor[8];
|
||||
int i;
|
||||
char fgColor[8];
|
||||
int fr, fg, fb;
|
||||
|
||||
(void)handle;
|
||||
(void)user;
|
||||
(void)call;
|
||||
|
||||
color_picker_image_update(picker);
|
||||
|
||||
i = ((mouse->point.y * PICKER_SIZE) + mouse->point.x) * 4;
|
||||
|
||||
picker->chosen_color.red = picker->color_picker_image_data[i];
|
||||
picker->chosen_color.green = picker->color_picker_image_data[i + 1];
|
||||
picker->chosen_color.blue = picker->color_picker_image_data[i + 2];
|
||||
|
||||
sprintf(hexColor, "#%02X%02X%02X", picker->chosen_color.red, picker->chosen_color.green, picker->chosen_color.blue);
|
||||
|
||||
fr = picker->chosen_color.red > 128 ? 0 : 255;
|
||||
fg = picker->chosen_color.green > 128 ? 0 : 255;
|
||||
fb = picker->chosen_color.blue > 128 ? 0 : 255;
|
||||
|
||||
sprintf(fgColor, "#%02X%02X%02X", fr, fg, fb);
|
||||
MwSetText(picker->color_display, MwNbackground, hexColor);
|
||||
MwSetText(picker->color_display_text, MwNforeground, fgColor);
|
||||
|
||||
MwSetText(picker->color_display_text, MwNbackground, hexColor);
|
||||
MwSetText(picker->color_display_text, MwNtext, hexColor);
|
||||
}
|
||||
static void color_picker_on_change_value(MwWidget handle, void* user,
|
||||
void* call) {
|
||||
color_picker_t* picker = user;
|
||||
|
||||
int value = MwGetInteger(handle, MwNvalue);
|
||||
int diff = MwGetInteger(handle, MwNchangedBy);
|
||||
|
||||
(void)diff;
|
||||
(void)call;
|
||||
|
||||
picker->value = ((double)value / 1024.);
|
||||
|
||||
color_picker_image_update(picker);
|
||||
}
|
||||
|
||||
static void color_picker_destroy(color_picker_t* picker) {
|
||||
MwLLDestroyPixmap(picker->color_picker_pixmap);
|
||||
free(picker);
|
||||
}
|
||||
|
||||
static void color_picker_close(MwWidget handle, void* user,
|
||||
void* call) {
|
||||
color_picker_t* picker = user;
|
||||
|
||||
(void)call;
|
||||
|
||||
color_picker_destroy(picker);
|
||||
MwDestroyWidget(handle);
|
||||
}
|
||||
|
||||
static void color_picker_finish(MwWidget handle, void* user,
|
||||
void* call) {
|
||||
color_picker_t* picker = user;
|
||||
|
||||
(void)call;
|
||||
|
||||
MwDispatchUserHandler(picker->parent, MwNcolorChosenHandler, &picker->chosen_color);
|
||||
|
||||
color_picker_destroy(picker);
|
||||
MwDestroyWidget(handle->parent);
|
||||
}
|
||||
|
||||
color_picker_t* color_picker_setup(MwWidget parent, int w, int h) {
|
||||
color_picker_t* picker = malloc(sizeof(*picker));
|
||||
memset(picker, 0, sizeof(*picker));
|
||||
|
||||
picker->parent = parent;
|
||||
|
||||
picker->color_picker_img =
|
||||
MwVaCreateWidget(MwImageClass, "image", picker->parent, IMG_POS_X(w), IMG_POS_Y(h),
|
||||
PICKER_SIZE, PICKER_SIZE, NULL);
|
||||
|
||||
// picker->color_picker_image_data = malloc(PICKER_SIZE * PICKER_SIZE * 4);
|
||||
|
||||
picker->color_picker_pixmap = NULL;
|
||||
picker->value = 0;
|
||||
|
||||
color_picker_image_update(picker);
|
||||
|
||||
MwAddUserHandler(picker->color_picker_img, MwNmouseDownHandler,
|
||||
color_picker_click, picker);
|
||||
|
||||
picker->color_display = MwCreateWidget(
|
||||
MwFrameClass, "colorDisplayFrame", picker->parent, IMG_POS_X(w),
|
||||
IMG_POS_Y(h) - (PICKER_SIZE / 16) - MARGIN, PICKER_SIZE, PICKER_SIZE / 16);
|
||||
MwSetText(picker->color_display, MwNbackground, "#FFFFFF");
|
||||
MwSetInteger(picker->color_display, MwnhasBorder, 1);
|
||||
MwSetInteger(picker->color_display, MwNinverted, 1);
|
||||
|
||||
picker->color_display_text = MwCreateWidget(
|
||||
MwLabelClass, "colorDisplayFrameText", picker->color_display,
|
||||
MwDefaultBorderWidth(parent), MwDefaultBorderWidth(parent),
|
||||
PICKER_SIZE - MwDefaultBorderWidth(parent),
|
||||
(PICKER_SIZE / 16) - (MwDefaultBorderWidth(parent) * 2));
|
||||
|
||||
MwSetText(picker->color_display_text, MwNtext, "#FFFFFF");
|
||||
|
||||
picker->value_slider = MwVaCreateWidget(
|
||||
MwScrollBarClass, "value-slider", picker->parent,
|
||||
/* x */
|
||||
IMG_POS_X(w) + PICKER_SIZE + MARGIN,
|
||||
|
||||
/* y */
|
||||
IMG_POS_Y(h),
|
||||
|
||||
/* width */
|
||||
SCROLL_BAR_WIDTH,
|
||||
|
||||
/* height */
|
||||
PICKER_SIZE,
|
||||
|
||||
MwNorientation, MwVERTICAL, MwNminValue, 0, MwNmaxValue, 1024, NULL);
|
||||
|
||||
MwAddUserHandler(picker->value_slider, MwNchangedHandler,
|
||||
color_picker_on_change_value, picker);
|
||||
|
||||
picker->finish = MwCreateWidget(
|
||||
MwButtonClass, "colorPickerFinish", picker->parent, IMG_POS_X(w),
|
||||
IMG_POS_Y(h) + PICKER_SIZE + MARGIN, PICKER_SIZE, (WIN_SIZE - PICKER_SIZE - MARGIN * 4) / 2);
|
||||
MwSetText(picker->finish, MwNtext, "Select");
|
||||
MwSetInteger(picker->finish, MwnhasBorder, 1);
|
||||
MwSetInteger(picker->finish, MwNinverted, 1);
|
||||
|
||||
MwAddUserHandler(picker->finish, MwNactivateHandler,
|
||||
color_picker_finish, picker);
|
||||
|
||||
memset(picker->hue_table, 0, sizeof(picker->hue_table));
|
||||
|
||||
return picker;
|
||||
}
|
||||
|
||||
MwWidget MwColorPicker(MwWidget handle, const char* title) {
|
||||
MwPoint p;
|
||||
color_picker_t* wheel;
|
||||
MwWidget window;
|
||||
MwSizeHints sh;
|
||||
|
||||
p.x = p.y = 0;
|
||||
|
||||
sh.min_width = sh.max_width = WIN_SIZE;
|
||||
sh.min_height = sh.max_height = WIN_SIZE;
|
||||
|
||||
window = MwVaCreateWidget(MwWindowClass, "main", handle, MwDEFAULT, MwDEFAULT,
|
||||
WIN_SIZE, WIN_SIZE,
|
||||
MwNtitle, title,
|
||||
MwNsizeHints, &sh,
|
||||
NULL);
|
||||
|
||||
wheel = color_picker_setup(window, WIN_SIZE, WIN_SIZE);
|
||||
|
||||
MwAddUserHandler(window, MwNcloseHandler, color_picker_close, wheel);
|
||||
|
||||
MwLLDetach(window->lowlevel, &p);
|
||||
MwLLMakePopup(window->lowlevel, handle->lowlevel);
|
||||
|
||||
return window;
|
||||
}
|
||||
508
src/dialog/filechooser.c
Normal file
508
src/dialog/filechooser.c
Normal file
@@ -0,0 +1,508 @@
|
||||
/* $Id$ */
|
||||
#include <Mw/Milsko.h>
|
||||
|
||||
#include "../external/stb_ds.h"
|
||||
|
||||
typedef struct filechooser {
|
||||
char* path;
|
||||
char** history;
|
||||
int history_seek;
|
||||
|
||||
MwDirectoryEntry** entries;
|
||||
MwDirectoryEntry** sorted_entries;
|
||||
|
||||
MwWidget nav;
|
||||
MwWidget files;
|
||||
MwWidget addr;
|
||||
MwWidget addr_back;
|
||||
MwWidget addr_fwd;
|
||||
MwWidget addr_up;
|
||||
MwWidget filename_label;
|
||||
MwWidget filename;
|
||||
MwWidget okay;
|
||||
MwWidget cancel;
|
||||
|
||||
MwLLPixmap dir;
|
||||
MwLLPixmap file;
|
||||
MwLLPixmap back;
|
||||
MwLLPixmap forward;
|
||||
MwLLPixmap up;
|
||||
MwLLPixmap computer;
|
||||
} filechooser_t;
|
||||
|
||||
static void scan(MwWidget handle, const char* path, int record);
|
||||
|
||||
static void destroy(MwWidget handle) {
|
||||
filechooser_t* fc = handle->opaque;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < arrlen(fc->history); i++) free(fc->history[i]);
|
||||
arrfree(fc->history);
|
||||
|
||||
arrfree(fc->sorted_entries);
|
||||
for(i = 0; i < arrlen(fc->entries); i++) MwDirectoryFreeEntry(fc->entries[i]);
|
||||
arrfree(fc->entries);
|
||||
|
||||
MwLLDestroyPixmap(fc->dir);
|
||||
MwLLDestroyPixmap(fc->file);
|
||||
MwLLDestroyPixmap(fc->back);
|
||||
MwLLDestroyPixmap(fc->forward);
|
||||
MwLLDestroyPixmap(fc->up);
|
||||
MwLLDestroyPixmap(fc->computer);
|
||||
free(handle->opaque);
|
||||
MwDestroyWidget(handle);
|
||||
}
|
||||
|
||||
static void cancel(MwWidget handle, void* user, void* call) {
|
||||
(void)user;
|
||||
(void)call;
|
||||
|
||||
destroy(handle->parent);
|
||||
}
|
||||
|
||||
static void cancel_window(MwWidget handle, void* user, void* call) {
|
||||
(void)user;
|
||||
(void)call;
|
||||
|
||||
destroy(handle);
|
||||
}
|
||||
|
||||
static void okay(MwWidget handle, void* user, void* call) {
|
||||
(void)user;
|
||||
(void)call;
|
||||
|
||||
destroy(handle->parent);
|
||||
}
|
||||
|
||||
static void msgbox_okay(MwWidget handle, void* user, void* call) {
|
||||
(void)user;
|
||||
(void)call;
|
||||
|
||||
MwMessageBoxDestroy(handle->parent);
|
||||
}
|
||||
|
||||
static void files_activate(MwWidget handle, void* user, void* call) {
|
||||
int index = *(int*)call;
|
||||
filechooser_t* fc = handle->parent->opaque;
|
||||
|
||||
(void)user;
|
||||
|
||||
if(fc->sorted_entries[index - 1]->type == MwDIRECTORY_DIRECTORY) {
|
||||
char* p = MwDirectoryJoin(fc->path, fc->sorted_entries[index - 1]->name);
|
||||
|
||||
scan(handle->parent, p, 1);
|
||||
|
||||
free(p);
|
||||
} else {
|
||||
okay(fc->okay, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void nav_activate(MwWidget handle, void* user, void* call) {
|
||||
int index = *(int*)call;
|
||||
const char* e = MwListBoxGet(handle, index);
|
||||
|
||||
(void)user;
|
||||
|
||||
if(strcmp(e, "Home") == 0) {
|
||||
#ifdef _WIN32
|
||||
#else
|
||||
struct passwd* p = getpwuid(getuid());
|
||||
|
||||
scan(handle->parent, p->pw_dir, 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void addr_up_activate(MwWidget handle, void* user, void* call) {
|
||||
filechooser_t* fc = handle->parent->opaque;
|
||||
char* p = MwDirectoryJoin(fc->path, "..");
|
||||
|
||||
(void)user;
|
||||
(void)call;
|
||||
|
||||
scan(handle->parent, p, 1);
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
static void addr_back_activate(MwWidget handle, void* user, void* call) {
|
||||
filechooser_t* fc = handle->parent->opaque;
|
||||
|
||||
(void)user;
|
||||
(void)call;
|
||||
|
||||
if(fc->history_seek > 1) {
|
||||
fc->history_seek -= 2;
|
||||
scan(handle->parent, fc->history[fc->history_seek], 0);
|
||||
fc->history_seek++;
|
||||
}
|
||||
}
|
||||
|
||||
static void addr_fwd_activate(MwWidget handle, void* user, void* call) {
|
||||
filechooser_t* fc = handle->parent->opaque;
|
||||
|
||||
(void)user;
|
||||
(void)call;
|
||||
|
||||
if(fc->history_seek < arrlen(fc->history)) {
|
||||
scan(handle->parent, fc->history[fc->history_seek++], 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void addr_activate(MwWidget handle, void* user, void* call) {
|
||||
(void)user;
|
||||
(void)call;
|
||||
|
||||
scan(handle->parent, MwGetText(handle, MwNtext), 1);
|
||||
}
|
||||
|
||||
static void layout(MwWidget handle) {
|
||||
filechooser_t* fc = handle->opaque;
|
||||
int w = MwGetInteger(handle, MwNwidth);
|
||||
int h = MwGetInteger(handle, MwNheight);
|
||||
int wx, wy, ww, wh;
|
||||
|
||||
wx = 5;
|
||||
wy = 5 + 24 + 5;
|
||||
ww = 160;
|
||||
wh = h - 10 - 24 - 5 - 24 - 5 - 24 - 5;
|
||||
if(fc->nav == NULL) {
|
||||
MwListBoxPacket* p = MwListBoxCreatePacket();
|
||||
int index;
|
||||
|
||||
index = MwListBoxPacketInsert(p, -1);
|
||||
MwListBoxPacketSet(p, index, 0, "Home");
|
||||
MwListBoxPacketSetIcon(p, index, fc->computer);
|
||||
|
||||
fc->nav = MwVaCreateWidget(MwListBoxClass, "nav", handle, wx, wy, ww, wh,
|
||||
MwNleftPadding, 16,
|
||||
NULL);
|
||||
MwListBoxInsert(fc->nav, -1, p);
|
||||
MwAddUserHandler(fc->nav, MwNactivateHandler, nav_activate, NULL);
|
||||
|
||||
MwListBoxDestroyPacket(p);
|
||||
} else {
|
||||
MwVaApply(fc->nav,
|
||||
MwNx, wx,
|
||||
MwNy, wy,
|
||||
MwNwidth, ww,
|
||||
MwNheight, wh,
|
||||
NULL);
|
||||
}
|
||||
|
||||
wx = 5 + 160 + 5;
|
||||
wy = 5 + 24 + 5;
|
||||
ww = w - 5 - 160 - 5 - 5;
|
||||
wh = h - 10 - 24 - 5 - 24 - 5 - 24 - 5;
|
||||
if(fc->files == NULL) {
|
||||
fc->files = MwVaCreateWidget(MwListBoxClass, "files", handle, wx, wy, ww, wh,
|
||||
MwNhasHeading, 1,
|
||||
MwNleftPadding, 16,
|
||||
NULL);
|
||||
MwAddUserHandler(fc->files, MwNactivateHandler, files_activate, NULL);
|
||||
} else {
|
||||
MwVaApply(fc->files,
|
||||
MwNx, wx,
|
||||
MwNy, wy,
|
||||
MwNwidth, ww,
|
||||
MwNheight, wh,
|
||||
NULL);
|
||||
}
|
||||
|
||||
wx = 5 + ((24 + 5) * 3);
|
||||
wy = 5;
|
||||
ww = w - 10 - ((24 + 5) * 3);
|
||||
wh = 24;
|
||||
if(fc->addr == NULL) {
|
||||
fc->addr = MwCreateWidget(MwEntryClass, "addr", handle, wx, wy, ww, wh);
|
||||
MwAddUserHandler(fc->addr, MwNactivateHandler, addr_activate, NULL);
|
||||
} else {
|
||||
MwVaApply(fc->addr,
|
||||
MwNx, wx,
|
||||
MwNy, wy,
|
||||
MwNwidth, ww,
|
||||
MwNheight, wh,
|
||||
NULL);
|
||||
}
|
||||
|
||||
wx = 5;
|
||||
wy = 5;
|
||||
ww = 24;
|
||||
wh = 24;
|
||||
if(fc->addr_back == NULL) {
|
||||
fc->addr_back = MwVaCreateWidget(MwButtonClass, "addr_back", handle, wx, wy, ww, wh,
|
||||
MwNpixmap, fc->back,
|
||||
NULL);
|
||||
MwAddUserHandler(fc->addr_back, MwNactivateHandler, addr_back_activate, NULL);
|
||||
} else {
|
||||
MwVaApply(fc->addr_back,
|
||||
MwNx, wx,
|
||||
MwNy, wy,
|
||||
MwNwidth, ww,
|
||||
MwNheight, wh,
|
||||
NULL);
|
||||
}
|
||||
|
||||
wx = 5 + 24 + 5;
|
||||
wy = 5;
|
||||
ww = 24;
|
||||
wh = 24;
|
||||
if(fc->addr_fwd == NULL) {
|
||||
fc->addr_fwd = MwVaCreateWidget(MwButtonClass, "addr_fwd", handle, wx, wy, ww, wh,
|
||||
MwNpixmap, fc->forward,
|
||||
NULL);
|
||||
MwAddUserHandler(fc->addr_fwd, MwNactivateHandler, addr_fwd_activate, NULL);
|
||||
} else {
|
||||
MwVaApply(fc->addr_fwd,
|
||||
MwNx, wx,
|
||||
MwNy, wy,
|
||||
MwNwidth, ww,
|
||||
MwNheight, wh,
|
||||
NULL);
|
||||
}
|
||||
|
||||
wx = 5 + 24 + 5 + 24 + 5;
|
||||
wy = 5;
|
||||
ww = 24;
|
||||
wh = 24;
|
||||
if(fc->addr_up == NULL) {
|
||||
fc->addr_up = MwVaCreateWidget(MwButtonClass, "addr_up", handle, wx, wy, ww, wh,
|
||||
MwNpixmap, fc->up,
|
||||
NULL);
|
||||
MwAddUserHandler(fc->addr_up, MwNactivateHandler, addr_up_activate, NULL);
|
||||
} else {
|
||||
MwVaApply(fc->addr_up,
|
||||
MwNx, wx,
|
||||
MwNy, wy,
|
||||
MwNwidth, ww,
|
||||
MwNheight, wh,
|
||||
NULL);
|
||||
}
|
||||
|
||||
wx = 5 + ((24 + 5) * 3);
|
||||
wy = h - 5 - 24 - 5 - 24;
|
||||
ww = w - 10 - ((24 + 5) * 3);
|
||||
wh = 24;
|
||||
if(fc->filename == NULL) {
|
||||
fc->filename = MwCreateWidget(MwEntryClass, "filename", handle, wx, wy, ww, wh);
|
||||
} else {
|
||||
MwVaApply(fc->filename,
|
||||
MwNx, wx,
|
||||
MwNy, wy,
|
||||
MwNwidth, ww,
|
||||
MwNheight, wh,
|
||||
NULL);
|
||||
}
|
||||
|
||||
wx = 5;
|
||||
wy = h - 5 - 24 - 5 - 24;
|
||||
ww = ((24 + 5) * 3);
|
||||
wh = 24;
|
||||
if(fc->filename_label == NULL) {
|
||||
fc->filename_label = MwVaCreateWidget(MwLabelClass, "filename_label", handle, wx, wy, ww, wh,
|
||||
MwNtext, "Filename:",
|
||||
NULL);
|
||||
} else {
|
||||
MwVaApply(fc->filename_label,
|
||||
MwNx, wx,
|
||||
MwNy, wy,
|
||||
MwNwidth, ww,
|
||||
MwNheight, wh,
|
||||
NULL);
|
||||
}
|
||||
|
||||
wx = w - 5 - 24 * 3 - 5 - 24 * 3;
|
||||
wy = h - 5 - 24;
|
||||
ww = 24 * 3;
|
||||
wh = 24;
|
||||
if(fc->okay == NULL) {
|
||||
fc->okay = MwVaCreateWidget(MwButtonClass, "ok", handle, wx, wy, ww, wh,
|
||||
MwNtext, "Okay",
|
||||
NULL);
|
||||
|
||||
MwAddUserHandler(fc->okay, MwNactivateHandler, okay, NULL);
|
||||
} else {
|
||||
MwVaApply(fc->okay,
|
||||
MwNx, wx,
|
||||
MwNy, wy,
|
||||
MwNwidth, ww,
|
||||
MwNheight, wh,
|
||||
NULL);
|
||||
}
|
||||
|
||||
wx = w - 5 - 24 * 3;
|
||||
wy = h - 5 - 24;
|
||||
ww = 24 * 3;
|
||||
wh = 24;
|
||||
if(fc->cancel == NULL) {
|
||||
fc->cancel = MwVaCreateWidget(MwButtonClass, "cancel", handle, wx, wy, ww, wh,
|
||||
MwNtext, "Cancel",
|
||||
NULL);
|
||||
|
||||
MwAddUserHandler(fc->cancel, MwNactivateHandler, cancel, NULL);
|
||||
} else {
|
||||
MwVaApply(fc->cancel,
|
||||
MwNx, wx,
|
||||
MwNy, wy,
|
||||
MwNwidth, ww,
|
||||
MwNheight, wh,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void resize(MwWidget handle, void* user, void* call) {
|
||||
(void)user;
|
||||
(void)call;
|
||||
|
||||
layout(handle);
|
||||
}
|
||||
|
||||
static int qsort_files(const void* a, const void* b) {
|
||||
MwDirectoryEntry* aent = *(MwDirectoryEntry**)a;
|
||||
MwDirectoryEntry* bent = *(MwDirectoryEntry**)b;
|
||||
|
||||
return strcmp(aent->name, bent->name);
|
||||
}
|
||||
|
||||
static void scan(MwWidget handle, const char* path, int record) {
|
||||
filechooser_t* fc = handle->opaque;
|
||||
void* dir = MwDirectoryOpen(path);
|
||||
int i;
|
||||
MwListBoxPacket* p = MwListBoxCreatePacket();
|
||||
int index;
|
||||
|
||||
if(dir != NULL) {
|
||||
MwDirectoryEntry* entry;
|
||||
|
||||
arrfree(fc->sorted_entries);
|
||||
for(i = 0; i < arrlen(fc->entries); i++) MwDirectoryFreeEntry(fc->entries[i]);
|
||||
arrfree(fc->entries);
|
||||
|
||||
while((entry = MwDirectoryRead(dir)) != NULL) arrput(fc->entries, entry);
|
||||
MwDirectoryClose(dir);
|
||||
|
||||
qsort(fc->entries, arrlen(fc->entries), sizeof(MwDirectoryEntry*), qsort_files);
|
||||
|
||||
if(record) {
|
||||
char* str = MwStringDupliacte(path);
|
||||
|
||||
while(arrlen(fc->history) > fc->history_seek) {
|
||||
free(fc->history[fc->history_seek]);
|
||||
arrdel(fc->history, fc->history_seek);
|
||||
}
|
||||
|
||||
arrins(fc->history, fc->history_seek, str);
|
||||
|
||||
fc->history_seek++;
|
||||
}
|
||||
} else {
|
||||
MwWidget msgbox = MwMessageBox(handle, "Directory does not exist!", "Error", MwMB_ICONERROR | MwMB_BUTTONOK);
|
||||
MwAddUserHandler(MwMessageBoxGetChild(msgbox, MwMB_BUTTONOK), MwNactivateHandler, msgbox_okay, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if(fc->path != NULL) free(fc->path);
|
||||
fc->path = MwStringDupliacte(path);
|
||||
|
||||
MwVaApply(fc->addr,
|
||||
MwNtext, path,
|
||||
NULL);
|
||||
|
||||
MwListBoxReset(fc->files);
|
||||
MwListBoxSetWidth(fc->files, 0, -128 - 96);
|
||||
MwListBoxSetWidth(fc->files, 1, 128);
|
||||
MwListBoxSetWidth(fc->files, 2, 0);
|
||||
|
||||
index = MwListBoxPacketInsert(p, -1);
|
||||
MwListBoxPacketSet(p, index, -1, "Name");
|
||||
MwListBoxPacketSet(p, index, -1, "Date modified");
|
||||
MwListBoxPacketSet(p, index, -1, "Size");
|
||||
|
||||
for(i = 0; i < arrlen(fc->entries); i++) {
|
||||
if(strcmp(fc->entries[i]->name, ".") == 0 || strcmp(fc->entries[i]->name, "..") == 0) continue;
|
||||
if(fc->entries[i]->type == MwDIRECTORY_DIRECTORY) {
|
||||
char date[128];
|
||||
|
||||
MwStringTime(date, fc->entries[i]->mtime);
|
||||
|
||||
index = MwListBoxPacketInsert(p, -1);
|
||||
MwListBoxPacketSetIcon(p, index, fc->dir);
|
||||
MwListBoxPacketSet(p, index, -1, fc->entries[i]->name);
|
||||
MwListBoxPacketSet(p, index, -1, date);
|
||||
MwListBoxPacketSet(p, index, -1, NULL);
|
||||
|
||||
arrput(fc->sorted_entries, fc->entries[i]);
|
||||
}
|
||||
}
|
||||
for(i = 0; i < arrlen(fc->entries); i++) {
|
||||
if(fc->entries[i]->type == MwDIRECTORY_FILE) {
|
||||
char date[128];
|
||||
char size[128];
|
||||
|
||||
MwStringTime(date, fc->entries[i]->mtime);
|
||||
MwStringSize(size, fc->entries[i]->size);
|
||||
|
||||
index = MwListBoxPacketInsert(p, -1);
|
||||
MwListBoxPacketSetIcon(p, index, fc->file);
|
||||
MwListBoxPacketSet(p, index, -1, fc->entries[i]->name);
|
||||
MwListBoxPacketSet(p, index, -1, date);
|
||||
MwListBoxPacketSet(p, index, -1, size);
|
||||
|
||||
arrput(fc->sorted_entries, fc->entries[i]);
|
||||
}
|
||||
}
|
||||
MwListBoxInsert(fc->files, -1, p);
|
||||
MwListBoxDestroyPacket(p);
|
||||
}
|
||||
|
||||
MwWidget MwFileChooser(MwWidget handle, const char* title) {
|
||||
MwWidget window;
|
||||
MwPoint p;
|
||||
int ww = MwGetInteger(handle, MwNwidth);
|
||||
int wh = MwGetInteger(handle, MwNheight);
|
||||
int w, h;
|
||||
filechooser_t* fc = malloc(sizeof(*fc));
|
||||
char* path;
|
||||
MwLLPixmap icon;
|
||||
|
||||
memset(fc, 0, sizeof(*fc));
|
||||
|
||||
p.x = 0;
|
||||
p.y = 0;
|
||||
|
||||
w = 700;
|
||||
h = w * 2 / 3;
|
||||
window = MwVaCreateWidget(MwWindowClass, "filechooser", handle, ww, wh, w, h,
|
||||
MwNtitle, title,
|
||||
NULL);
|
||||
|
||||
fc->history_seek = 0;
|
||||
|
||||
fc->dir = MwLoadIcon(window, MwIconDirectory);
|
||||
fc->file = MwLoadIcon(window, MwIconFile);
|
||||
fc->back = MwLoadIcon(window, MwIconBack);
|
||||
fc->forward = MwLoadIcon(window, MwIconForward);
|
||||
fc->up = MwLoadIcon(window, MwIconUp);
|
||||
fc->computer = MwLoadIcon(window, MwIconComputer);
|
||||
|
||||
icon = MwLoadIcon(window, MwIconSearch);
|
||||
MwVaApply(window,
|
||||
MwNiconPixmap, icon,
|
||||
NULL);
|
||||
|
||||
window->opaque = fc;
|
||||
|
||||
layout(window);
|
||||
MwAddUserHandler(window, MwNresizeHandler, resize, NULL);
|
||||
MwAddUserHandler(window, MwNcloseHandler, cancel_window, NULL);
|
||||
|
||||
path = MwDirectoryCurrent();
|
||||
scan(window, path, 1);
|
||||
free(path);
|
||||
|
||||
MwLLDetach(window->lowlevel, &p);
|
||||
MwLLMakePopup(window->lowlevel, handle->lowlevel);
|
||||
|
||||
return window;
|
||||
}
|
||||
116
src/dialog/messagebox.c
Normal file
116
src/dialog/messagebox.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/* $Id$ */
|
||||
#include <Mw/Milsko.h>
|
||||
|
||||
#include "../external/stb_ds.h"
|
||||
|
||||
typedef struct msgbox {
|
||||
int key;
|
||||
MwWidget value;
|
||||
} msgbox_t;
|
||||
|
||||
static void spawn_button(MwWidget handle, int x, int y, int id, const char* text) {
|
||||
msgbox_t* mb = handle->opaque;
|
||||
MwWidget widget = MwVaCreateWidget(MwButtonClass, text, handle, x, y, 80, 24,
|
||||
MwNtext, text,
|
||||
NULL);
|
||||
|
||||
hmput(mb, id, widget);
|
||||
|
||||
handle->opaque = mb;
|
||||
}
|
||||
|
||||
static void messagebox_close(MwWidget handle, void* user, void* call) {
|
||||
(void)user;
|
||||
(void)call;
|
||||
MwMessageBoxDestroy(handle);
|
||||
}
|
||||
|
||||
MwWidget MwMessageBox(MwWidget handle, const char* text, const char* title, unsigned int flag) {
|
||||
MwWidget window;
|
||||
MwPoint p;
|
||||
int w, h;
|
||||
int left = 8;
|
||||
int th;
|
||||
int x = 0;
|
||||
int ww = MwGetInteger(handle, MwNwidth);
|
||||
int wh = MwGetInteger(handle, MwNheight);
|
||||
|
||||
p.x = 0;
|
||||
p.y = 0;
|
||||
|
||||
window = MwVaCreateWidget(MwWindowClass, "messagebox", handle, ww, wh, (w = 512), (h = 32 * 4),
|
||||
MwNtitle, title,
|
||||
NULL);
|
||||
|
||||
window->opaque = NULL;
|
||||
|
||||
if(flag & MwMB_BUTTONOK) spawn_button(window, w - (x += 8 + 80), h - 8 - 24, MwMB_BUTTONOK, "OK");
|
||||
if(flag & MwMB_BUTTONCANCEL) spawn_button(window, w - (x += 8 + 80), h - 8 - 24, MwMB_BUTTONCANCEL, "Cancel");
|
||||
|
||||
if(flag & MwMB_BUTTONNO) spawn_button(window, w - (x += 8 + 80), h - 8 - 24, MwMB_BUTTONNO, "No");
|
||||
if(flag & MwMB_BUTTONYES) spawn_button(window, w - (x += 8 + 80), h - 8 - 24, MwMB_BUTTONYES, "Yes");
|
||||
|
||||
if((flag & MwMB_ICONMASK) != 0) {
|
||||
MwWidget icon;
|
||||
MwLLPixmap px;
|
||||
unsigned int* data = NULL;
|
||||
|
||||
icon = MwCreateWidget(MwImageClass, "image", window, 8, (h - 48) / 2, 48, 48);
|
||||
|
||||
switch(flag & MwMB_ICONMASK) {
|
||||
case MwMB_ICONWARNING: {
|
||||
data = MwIconWarning;
|
||||
break;
|
||||
}
|
||||
case MwMB_ICONINFO: {
|
||||
data = MwIconInfo;
|
||||
break;
|
||||
}
|
||||
case MwMB_ICONNOTE: {
|
||||
data = MwIconNote;
|
||||
break;
|
||||
}
|
||||
case MwMB_ICONNEWS: {
|
||||
data = MwIconNews;
|
||||
break;
|
||||
}
|
||||
case MwMB_ICONERROR: {
|
||||
data = MwIconError;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
px = MwLoadIcon(icon, data);
|
||||
|
||||
MwSetVoid(icon, MwNpixmap, px);
|
||||
|
||||
left = 8 + 48 + 8;
|
||||
}
|
||||
|
||||
th = MwTextHeight(handle, text);
|
||||
(void)MwVaCreateWidget(MwLabelClass, "label", window, left, (h - th) / 2, w - left - 8, th,
|
||||
MwNtext, text,
|
||||
MwNalignment, MwALIGNMENT_BEGINNING,
|
||||
NULL);
|
||||
|
||||
MwLLDetach(window->lowlevel, &p);
|
||||
MwLLSetSizeHints(window->lowlevel, w, h, w, h);
|
||||
MwLLMakePopup(window->lowlevel, handle->lowlevel);
|
||||
|
||||
MwAddUserHandler(window, MwNcloseHandler, messagebox_close, NULL);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
MwWidget MwMessageBoxGetChild(MwWidget handle, int child) {
|
||||
msgbox_t* mb = handle->opaque;
|
||||
|
||||
return hmget(mb, child);
|
||||
}
|
||||
|
||||
void MwMessageBoxDestroy(MwWidget handle) {
|
||||
void* px;
|
||||
|
||||
if((px = MwGetVoid(handle, MwNpixmap)) != NULL) MwLLDestroyPixmap(px);
|
||||
MwDestroyWidget(handle);
|
||||
}
|
||||
Reference in New Issue
Block a user