From a8bb866af2d7de01b1af8f075adfe8cf0b19c5eb Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Fri, 31 Oct 2025 15:02:40 +0000 Subject: [PATCH] radiobox works git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@528 b9cfdab3-6d41-4d17-bbe4-086880011989 --- GNUmakefile | 4 +-- examples/basic/radiobox.c | 25 ++++++++++++++ include/Mw/Draw.h | 9 +++++ include/Mw/Milsko.h | 1 + include/Mw/Widget/RadioBox.h | 25 ++++++++++++++ src/backend/x11.c | 2 +- src/draw.c | 67 ++++++++++++++++++++++++++++++++++++ src/widget/radiobox.c | 64 ++++++++++++++++++++++++++++++++++ 8 files changed, 194 insertions(+), 3 deletions(-) create mode 100644 examples/basic/radiobox.c create mode 100644 include/Mw/Widget/RadioBox.h create mode 100644 src/widget/radiobox.c diff --git a/GNUmakefile b/GNUmakefile index a4db9fb..c104063 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -24,7 +24,7 @@ L_LIBS = $(LIBS) L_OBJS = src/core.o src/default.o src/draw.o src/lowlevel.o src/error.o src/unicode.o src/color.o src/messagebox.o src/directory.o src/string.o src/filechooser.o L_OBJS += external/stb_ds.o external/stb_image.o external/stb_truetype.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 src/widget/progressbar.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 src/widget/progressbar.o src/widget/radiobox.o L_OBJS += src/cursor/hidden.o src/cursor/default.o src/cursor/cross.o src/cursor/text.o L_OBJS += 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 src/icon/down.o src/icon/left.o src/icon/right.o src/icon/computer.o src/icon/search.o L_OBJS += src/text/font.o src/text/boldfont.o src/text/ttf.o src/text/boldttf.o src/text/draw.o @@ -33,7 +33,7 @@ E_CFLAGS = $(CFLAGS) E_LDFLAGS = $(LDFLAGS) -Lsrc -Wl,-rpath,$(shell pwd)/src E_LIBS = $(LIBS) -lMw -EXAMPLES = examples/basic/example$(EXEC) examples/basic/rotate$(EXEC) examples/basic/image$(EXEC) examples/basic/scrollbar$(EXEC) examples/basic/checkbox$(EXEC) examples/basic/messagebox$(EXEC) examples/basic/viewport$(EXEC) examples/basic/listbox$(EXEC) examples/basic/progressbar$(EXEC) examples/color_picker$(EXEC) +EXAMPLES = examples/basic/example$(EXEC) examples/basic/rotate$(EXEC) examples/basic/image$(EXEC) examples/basic/scrollbar$(EXEC) examples/basic/checkbox$(EXEC) examples/basic/radiobox$(EXEC) examples/basic/messagebox$(EXEC) examples/basic/viewport$(EXEC) examples/basic/listbox$(EXEC) examples/basic/progressbar$(EXEC) examples/color_picker$(EXEC) include mk/platform.mk include mk/flags.mk diff --git a/examples/basic/radiobox.c b/examples/basic/radiobox.c new file mode 100644 index 0000000..a8d7a28 --- /dev/null +++ b/examples/basic/radiobox.c @@ -0,0 +1,25 @@ +/* $Id$ */ +#include + +int main() { + MwWidget window = MwVaCreateWidget(MwWindowClass, "test", NULL, MwDEFAULT, MwDEFAULT, 8 + 16 + 8 + 16 * 10 + 8, 8 + 16 + 8 + 16 + 8, + MwNtitle, "checkbox", + NULL); + + MwVaCreateWidget(MwRadioBoxClass, "cb1", window, 8, 8, 16, 16, + NULL); + MwVaCreateWidget(MwRadioBoxClass, "cb2", window, 8, 8 + 16 + 8, 16, 16, + MwNchecked, 1, + NULL); + + MwVaCreateWidget(MwLabelClass, "lab1", window, 8 + 16 + 8, 8, 16 * 10, 16, + MwNtext, "lorem ipsum 1", + MwNalignment, MwALIGNMENT_BEGINNING, + NULL); + MwVaCreateWidget(MwLabelClass, "lab2", window, 8 + 16 + 8, 8 + 16 + 8, 16 * 10, 16, + MwNtext, "lorem ipsum 2", + MwNalignment, MwALIGNMENT_BEGINNING, + NULL); + + MwLoop(window); +} diff --git a/include/Mw/Draw.h b/include/Mw/Draw.h index 7d84270..1c2dbcb 100644 --- a/include/Mw/Draw.h +++ b/include/Mw/Draw.h @@ -159,6 +159,15 @@ MWDECL MwLLPixmap MwLoadXPM(MwWidget handle, char** data); */ MWDECL MwLLPixmap MwLoadIcon(MwWidget handle, unsigned int* data); +/*! + * @brief Draws a diamond + * @param handle Widget + * @param rect Rectangle area + * @param color Color + * @param invert Invert the 3D border color or not + */ +MWDECL void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert); + /* color.c */ /*! diff --git a/include/Mw/Milsko.h b/include/Mw/Milsko.h index 83725dd..30d33f4 100644 --- a/include/Mw/Milsko.h +++ b/include/Mw/Milsko.h @@ -39,5 +39,6 @@ #include #include #include +#include #endif diff --git a/include/Mw/Widget/RadioBox.h b/include/Mw/Widget/RadioBox.h new file mode 100644 index 0000000..8f5212f --- /dev/null +++ b/include/Mw/Widget/RadioBox.h @@ -0,0 +1,25 @@ +/* $Id: RadioBox.h 206 2025-10-07 15:10:46Z nishi $ */ +/*! + * @file Mw/Widget/RadioBox.h + * @brief RadioBox widget + */ +#ifndef __MW_WIDGET_RADIOBOX_H__ +#define __MW_WIDGET_RADIOBOX_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * @brief RadioBox widget class + */ +MWDECL MwClass MwRadioBoxClass; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/backend/x11.c b/src/backend/x11.c index ae58421..070defc 100644 --- a/src/backend/x11.c +++ b/src/backend/x11.c @@ -195,7 +195,7 @@ void MwLLPolygon(MwLL handle, MwPoint* points, int points_count, MwLLColor color p[i].x = points[i].x; p[i].y = points[i].y; } - XFillPolygon(handle->display, handle->pixmap, handle->gc, p, points_count, Convex, CoordModeOrigin); + XFillPolygon(handle->display, handle->pixmap, handle->gc, p, points_count, Nonconvex, CoordModeOrigin); free(p); } diff --git a/src/draw.c b/src/draw.c index bde23d4..0349696 100644 --- a/src/draw.c +++ b/src/draw.c @@ -144,6 +144,73 @@ void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert if(col != color) MwLLFreeColor(col); } +void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { + MwPoint p[6]; + int border = MwDefaultBorderWidth(handle); + int ColorDiff = get_color_diff(handle); + MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff); + MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff); + MwLLColor col = invert ? MwLightenColor(handle, color, -8, -8, -8) : color; + + p[0].x = rect->x; + p[0].y = rect->y + rect->height / 2; + + p[1].x = rect->x + rect->width / 2; + p[1].y = rect->y; + + p[2].x = rect->x + rect->width; + p[2].y = rect->y + rect->height / 2; + + p[3].x = rect->x + rect->width - border; + p[3].y = rect->y + rect->height / 2; + + p[4].x = rect->x + rect->width / 2; + p[4].y = rect->y + border; + + p[5].x = rect->x + border; + p[5].y = rect->y + rect->height / 2; + + MwLLPolygon(handle->lowlevel, p, 6, invert ? darker : lighter); + + p[0].x = rect->x; + p[0].y = rect->y + rect->height / 2; + + p[1].x = rect->x + rect->width / 2; + p[1].y = rect->y + rect->height; + + p[2].x = rect->x + rect->width; + p[2].y = rect->y + rect->height / 2; + + p[3].x = rect->x + rect->width - border; + p[3].y = rect->y + rect->height / 2; + + p[4].x = rect->x + rect->width / 2; + p[4].y = rect->y + rect->height - border; + + p[5].x = rect->x + border; + p[5].y = rect->y + rect->height / 2; + + MwLLPolygon(handle->lowlevel, p, 6, invert ? lighter : darker); + + p[0].x = rect->x + rect->width / 2; + p[0].y = border; + + p[1].x = rect->x + rect->width - border; + p[1].y = rect->height / 2; + + p[2].x = rect->x + rect->width / 2; + p[2].y = rect->y + rect->height - border; + + p[3].x = rect->x + border; + p[3].y = rect->height / 2; + + MwLLPolygon(handle->lowlevel, p, 4, col); + + if(col != color) MwLLFreeColor(col); + MwLLFreeColor(lighter); + MwLLFreeColor(darker); +} + void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border) { MwPoint p[6]; int ColorDiff = get_color_diff(handle); diff --git a/src/widget/radiobox.c b/src/widget/radiobox.c new file mode 100644 index 0000000..ef60ce3 --- /dev/null +++ b/src/widget/radiobox.c @@ -0,0 +1,64 @@ +/* $Id: button.c 168 2025-10-04 19:30:58Z nishi $ */ +#include + +#include "../../external/stb_ds.h" + +static int create(MwWidget handle) { + MwSetDefault(handle); + + MwSetInteger(handle, MwNchecked, 0); + + return 0; +} + +static void draw(MwWidget handle) { + MwRect r; + MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); + + r.x = 0; + r.y = 0; + r.width = MwGetInteger(handle, MwNwidth); + r.height = MwGetInteger(handle, MwNheight); + + MwDrawRect(handle, &r, base); + MwDrawDiamond(handle, &r, base, (handle->pressed || MwGetInteger(handle, MwNchecked)) ? 1 : 0); + + MwLLFreeColor(base); +} + +static void click(MwWidget handle) { + MwSetInteger(handle, MwNchecked, MwGetInteger(handle, MwNchecked) ? 0 : 1); + if(MwGetInteger(handle, MwNchecked) && handle->parent != NULL) { + int i; + for(i = 0; i < arrlen(handle->parent->children); i++) { + MwWidget w = handle->parent->children[i]; + if(w != handle && w->widget_class == MwRadioBoxClass && MwGetInteger(w, MwNchecked)) { + MwSetInteger(w, MwNchecked, 0); + } + } + } + + MwDispatchUserHandler(handle, MwNchangedHandler, NULL); +} + +static void prop_change(MwWidget handle, const char* key) { + if(strcmp(key, MwNchecked) == 0) MwForceRender(handle); +} + +MwClassRec MwRadioBoxClassRec = { + create, /* create */ + NULL, /* destroy */ + draw, /* draw */ + click, /* click */ + NULL, /* parent_resize */ + prop_change, /* prop_change */ + NULL, /* mouse_move */ + MwForceRender2, /* mouse_up */ + MwForceRender2, /* mouse_down */ + NULL, /* key */ + NULL, /* execute */ + NULL, + NULL, + NULL, + NULL}; +MwClass MwRadioBoxClass = &MwRadioBoxClassRec;