diff --git a/GNUmakefile b/GNUmakefile index 195e1eb..6c818d4 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -36,7 +36,7 @@ L_OBJS = src/core.o src/default.o src/draw.o src/lowlevel.o src/font.o src/boldf L_OBJS += external/ds.o external/image.o L_OBJS += src/widget/window.o src/widget/button.o src/widget/frame.o src/widget/menu.o src/widget/submenu.o src/widget/image.o src/widget/scrollbar.o src/widget/checkbox.o src/widget/label.o src/widget/entry.o src/widget/numberentry.o src/widget/viewport.o src/widget/listbox.o L_OBJS += src/cursor/default.o src/cursor/cross.o src/cursor/text.o -L_OBJS += src/icon/question.o src/icon/warning.o src/icon/note.o src/icon/info.o src/icon/news.o src/icon/error.o src/icon/file.o src/icon/directory.o +L_OBJS += src/icon/question.o src/icon/warning.o src/icon/note.o src/icon/info.o src/icon/news.o src/icon/error.o src/icon/file.o src/icon/directory.o src/icon/back.o src/icon/forward.o src/icon/up.o OOL_CXXFLAGS = $(DEPINC) $(CFLAGS) -std=c++98 -fPIC OOL_LDFLAGS = $(LDFLAGS) -L src diff --git a/include/Mw/FileChooser.h b/include/Mw/FileChooser.h index c7eb544..faee031 100644 --- a/include/Mw/FileChooser.h +++ b/include/Mw/FileChooser.h @@ -2,7 +2,7 @@ /*! * %file Mw/FileChoose.h * %brief File chooser - */ + */ #ifndef __MW_FILECHOOSER_H__ #define __MW_FILECHOOSER_H__ diff --git a/include/Mw/Icon.h b/include/Mw/Icon.h index 406366a..8a2fc4c 100644 --- a/include/Mw/Icon.h +++ b/include/Mw/Icon.h @@ -12,6 +12,11 @@ extern "C" { #endif +/*! + * %brief Back icon + */ +MWDECL char* MwIconBack[]; + /*! * %brief Directory icon */ @@ -27,6 +32,11 @@ MWDECL char* MwIconError[]; */ MWDECL char* MwIconFile[]; +/*! + * %brief Forward icon + */ +MWDECL char* MwIconForward[]; + /*! * %brief Info icon */ @@ -47,6 +57,11 @@ MWDECL char* MwIconNote[]; */ MWDECL char* MwIconQuestion[]; +/*! + * %brief Up icon + */ +MWDECL char* MwIconUp[]; + /*! * %brief Warning icon */ diff --git a/include/Mw/Widget/ListBox.h b/include/Mw/Widget/ListBox.h index 4a07ec1..a3519e0 100644 --- a/include/Mw/Widget/ListBox.h +++ b/include/Mw/Widget/ListBox.h @@ -80,6 +80,12 @@ MWDECL const char* MwListBoxGet(MwWidget handle, int index); */ MWDECL void MwListBoxSetWidth(MwWidget handle, int index, int width); +/*! + * %brief Resets the listbox + * %param handle Widget + */ +MWDECL void MwListBoxReset(MwWidget handle); + #ifdef __cplusplus } #endif diff --git a/resource/icon/back.png b/resource/icon/back.png new file mode 100644 index 0000000..a97b41e Binary files /dev/null and b/resource/icon/back.png differ diff --git a/resource/icon/forward.png b/resource/icon/forward.png new file mode 100644 index 0000000..34ef3ae Binary files /dev/null and b/resource/icon/forward.png differ diff --git a/resource/icon/up.png b/resource/icon/up.png new file mode 100644 index 0000000..4aa8faf Binary files /dev/null and b/resource/icon/up.png differ diff --git a/src/draw.c b/src/draw.c index 4c92ad9..ba0ef21 100644 --- a/src/draw.c +++ b/src/draw.c @@ -363,13 +363,18 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, } void MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color) { - int i = 0, x, y, sx, sy; - int tw = MwTextWidth(handle, text); - int th = MwTextHeight(handle, text); - unsigned char* px = malloc(tw * th * 4); + int i = 0, x, y, sx, sy; + int tw; + int th; + unsigned char* px; MwRect r; MwLLPixmap p; + if(strlen(text) == 0) text = " "; + tw = MwTextWidth(handle, text); + th = MwTextHeight(handle, text); + px = malloc(tw * th * 4); + memset(px, 0, tw * th * 4); sx = 0; diff --git a/src/filechooser.c b/src/filechooser.c index d498eff..b143b80 100644 --- a/src/filechooser.c +++ b/src/filechooser.c @@ -1,22 +1,274 @@ /* $Id$ */ #include -MwWidget MwFileChooser(MwWidget handle, const char* title){ - MwWidget window; - MwPoint p; - int ww = MwGetInteger(handle, MwNwidth); - int wh = MwGetInteger(handle, MwNheight); - int w, h; +typedef struct filechooser { + 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; +} filechooser_t; + +static void destroy(MwWidget handle) { + filechooser_t* fc = handle->opaque; + + MwLLDestroyPixmap(fc->dir); + MwLLDestroyPixmap(fc->file); + free(handle->opaque); + MwDestroyWidget(handle); +} + +static void cancel(MwWidget handle, void* user, void* call) { + (void)user; + (void)call; + + destroy(handle->parent); +} + +static void okay(MwWidget handle, void* user, void* call) { + (void)user; + (void)call; + + destroy(handle->parent); +} + +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) { + fc->nav = MwCreateWidget(MwListBoxClass, "nav", handle, wx, wy, ww, wh); + } 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, + 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); + } 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); + } 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); + } 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); + } 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 void scan(MwWidget handle, const char* path) { + filechooser_t* fc = handle->opaque; + + MwListBoxReset(fc->files); + MwListBoxInsert(fc->files, -1, NULL, "Name", "Date modified", "Size", NULL); + MwListBoxSetWidth(fc->files, 0, -128 - 64); + MwListBoxSetWidth(fc->files, 1, 128); + MwListBoxSetWidth(fc->files, 2, 0); +} + +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)); + + memset(fc, 0, sizeof(*fc)); p.x = 0; p.y = 0; - window = MwVaCreateWidget(MwWindowClass, "filechooser", handle, ww, wh, (w = 640), (h = 300), - MwNtitle, title, - NULL); + w = 700; + h = w * 2 / 3; + window = MwVaCreateWidget(MwWindowClass, "filechooser", handle, ww, wh, w, h, + MwNtitle, title, + NULL); + + fc->dir = MwLoadXPM(window, MwIconDirectory); + fc->file = MwLoadXPM(window, MwIconFile); + fc->back = MwLoadXPM(window, MwIconBack); + fc->forward = MwLoadXPM(window, MwIconForward); + fc->up = MwLoadXPM(window, MwIconUp); + + window->opaque = fc; + + layout(window); + MwAddUserHandler(window, MwNresizeHandler, resize, NULL); + + scan(window, "."); MwLLDetach(window->lowlevel, &p); MwLLMakePopup(window->lowlevel, handle->lowlevel); - + return window; } diff --git a/src/icon/back.c b/src/icon/back.c new file mode 100644 index 0000000..a4286ce --- /dev/null +++ b/src/icon/back.c @@ -0,0 +1,36 @@ +/* $Id$ */ +#include + +/* XPM */ +char* MwIconBack[] = { + /* columns rows colors chars-per-pixel */ + "20 22 6 1 ", + " c white", + ". c None", + "X c gray60", + "o c gray40", + "O c gray20", + "+ c black", + /* pixels */ + "....................", + "........o.OO........", + "........XOOOOOO.....", + "........o.OOOOOOO...", + "........XOOOOOOOOO..", + "........o.OOOOOOOOO.", + "........XOOOOOOOOOOO", + "........o.OOOOOOOO.+", + "..........OOOOOO..++", + "............O..XO+++", + ".....+......XO++++++", + "....++...XO+++++++++", + "...+++++++++++++++++", + "..+++++++++++++++++O", + ".++++++++++++++++++X", + "++++++++++++++++++o.", + ".+++++++++++++++OX..", + "..+++++++++++OX.....", + "...++++++OX.........", + "....++..............", + ".....+..............", + "...................."}; diff --git a/src/icon/forward.c b/src/icon/forward.c new file mode 100644 index 0000000..9ba1463 --- /dev/null +++ b/src/icon/forward.c @@ -0,0 +1,36 @@ +/* $Id$ */ +#include + +/* XPM */ +char* MwIconForward[] = { + /* columns rows colors chars-per-pixel */ + "20 22 6 1 ", + " c white", + ". c None", + "X c gray60", + "o c gray40", + "O c gray20", + "+ c black", + /* pixels */ + "....................", + "........OO.o........", + ".....OOOOOOX........", + "...OOOOOOO.o........", + "..OOOOOOOOOX........", + ".OOOOOOOOO.o........", + "OOOOOOOOOOOX........", + "+.OOOOOOOO.o........", + "++..OOOOOO..........", + "+++OX..O............", + "++++++OX......+.....", + "+++++++++OX...++....", + "+++++++++++++++++...", + "O+++++++++++++++++..", + "X++++++++++++++++++.", + ".o++++++++++++++++++", + "..XO+++++++++++++++.", + ".....XO+++++++++++..", + ".........XO++++++...", + "..............++....", + "..............+.....", + "...................."}; diff --git a/src/icon/up.c b/src/icon/up.c new file mode 100644 index 0000000..66e8922 --- /dev/null +++ b/src/icon/up.c @@ -0,0 +1,33 @@ +/* $Id$ */ +#include + +/* XPM */ +char* MwIconUp[] = { + /* columns rows colors chars-per-pixel */ + "20 22 3 1 ", + " c white", + ". c None", + "X c black", + /* pixels */ + "....................", + "....................", + "....................", + "....................", + "....................", + "....................", + ".........XX.........", + "........XXXX........", + ".......XXXXXX.......", + "......XXXXXXXX......", + ".....XXXXXXXXXX.....", + "....XXXXXXXXXXXX....", + "...XXXXXXXXXXXXXX...", + "..XXXXXXXXXXXXXXXX..", + ".XXXXXXXXXXXXXXXXXX.", + "....................", + "....................", + "....................", + "....................", + "....................", + "....................", + "...................."}; diff --git a/src/widget/button.c b/src/widget/button.c index 405fec7..c3e2da9 100644 --- a/src/widget/button.c +++ b/src/widget/button.c @@ -39,8 +39,8 @@ static void draw(MwWidget handle) { r.width = px->width * sh; r.height = px->height * sh; } - r.width -= 10; - r.height -= 10; + r.width -= MwDefaultBorderWidth * 2; + r.height -= MwDefaultBorderWidth * 2; r.x += (double)(ow - r.width) / 2; r.y += (double)(oh - r.height) / 2; diff --git a/src/widget/listbox.c b/src/widget/listbox.c index e36bbe7..e6d1b82 100644 --- a/src/widget/listbox.c +++ b/src/widget/listbox.c @@ -169,7 +169,7 @@ static void frame_draw(MwWidget handle) { p.x = 0; for(j = 0; j < arrlen(lb->list[i].name); j++) { p.x += MwDefaultBorderWidth; - if(strlen(lb->list[i].name[j]) > 0) MwDrawText(handle, &p, lb->list[i].name[j], 0, MwALIGNMENT_BEGINNING, selected ? base : text); + MwDrawText(handle, &p, lb->list[i].name[j], 0, MwALIGNMENT_BEGINNING, selected ? base : text); p.x += get_col_width(lb, j) - MwDefaultBorderWidth; } p.y += MwTextHeight(handle, "M") / 2; @@ -249,10 +249,7 @@ static int create(MwWidget handle) { static void destroy(MwWidget handle) { MwListBox lb = handle->internal; - int i; - for(i = 0; i < arrlen(lb->list); i++) { - free(lb->list[i].name); - } + MwListBoxReset(handle); arrfree(lb->list); arrfree(lb->width); free(handle->internal); @@ -413,6 +410,24 @@ void MwListBoxDelete(MwWidget handle, int index) { } } +void MwListBoxReset(MwWidget handle) { + MwListBox lb = handle->internal; + int i; + + while(arrlen(lb->list) > 0) { + for(i = 0; i < arrlen(lb->list[0].name); i++) { + if(lb->list[0].name[i] != NULL) free(lb->list[0].name[i]); + } + arrfree(lb->list[0].name); + arrdel(lb->list, 0); + } + + lb->selected = -1; + + resize(handle); + MwForceRender(lb->frame); +} + void MwListBoxInsertMultiple(MwWidget handle, int index, int count, MwLLPixmap* pixmap, ...) { va_list va; va_start(va, pixmap);