diff --git a/examples/basic/periodic.c b/examples/basic/periodic.c index 92dab70..b449f09 100644 --- a/examples/basic/periodic.c +++ b/examples/basic/periodic.c @@ -237,8 +237,7 @@ int main() { sprintf(buf, "%sBox %d", i == 0 ? "Check" : "Radio", j + 1); MwVaCreateWidget(MwLabelClass, "label", b, 0, 0, 0, 0, MwNtext, buf, - MwNalignment, MwALIGNMENT_BEGINNING, - NULL); + MwNalignment, MwALIGNMENT_BEGINNING, MwNdisabled, (j == 5) ? 1 : 0, NULL); } } diff --git a/include/Mw/Draw.h b/include/Mw/Draw.h index deefe0f..443835c 100644 --- a/include/Mw/Draw.h +++ b/include/Mw/Draw.h @@ -187,6 +187,17 @@ MWDECL MwLLPixmap MWAPI MwLoadIcon(MwWidget handle, MwU32* data); */ MWDECL void MWAPI MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert); +/*! + * @brief Draws a circle + * @param handle Widget + * @param rect Rectangle area + * @param color Color + * @param color Background to fade to; widget background used if NULL + * @param filled Fill the circle or not + * @param outward + */ +MWDECL void MWAPI MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor background, int filled); + /* text.c */ /*! diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h index ad072a3..a9bc3cf 100644 --- a/include/Mw/TypeDefs.h +++ b/include/Mw/TypeDefs.h @@ -92,6 +92,7 @@ struct _MwWidget { MwPoint mouse_point; int close; int prop_event; + int held; void* internal; void* opaque; diff --git a/src/draw.c b/src/draw.c index 2314c02..c7869e0 100644 --- a/src/draw.c +++ b/src/draw.c @@ -124,7 +124,7 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) { int ColorDiff = get_color_diff(handle); double darkenStep = (ColorDiff / 2.) / rect->height; unsigned long sz = 1 * rect->height * 4; - unsigned char* data = malloc(sz*2); + unsigned char* data = malloc(sz * 2); MwRect r = *rect; if(!data) { return; @@ -303,6 +303,103 @@ void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { MwLLFreeColor(darker); } +void MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor background, int filled) { + MwLLPixmap pixmap; + int width = rect->width; + int height = rect->height; + unsigned long sz = (unsigned long)width * height * 4; + unsigned char* data; + double cx, cy, rx, ry; + int border; + int x, y; + int ColorDiff = (get_color_diff(handle)); + MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff); + MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff); + MwLLColor base = MwLightenColor(handle, color, 0, 0, 0); + + color_set_disabled_if_disabled(handle, darker); + color_set_disabled_if_disabled(handle, lighter); + color_set_disabled_if_disabled(handle, base); + + if(width <= 0 || height <= 0) return; + + data = malloc(sz); + if(!data) return; + memset(data, 0, sz); + + cx = width / 2.0; + cy = height / 2.0; + rx = width / 2.0; + ry = height / 2.0; + border = filled ? 0 : MwDefaultBorderWidth(handle); + + for(y = 0; y < height; y++) { + for(x = 0; x < width; x++) { + double nx = (x + 0.5 - cx) / rx; + double ny = (y + 0.5 - cy) / ry; + double dist = nx * nx + ny * ny; + int inside; + double inx = (x + 0.5 - cx) / (rx - border); + double iny = (y + 0.5 - cy) / (ry - border); + double innerDist = inx * inx + iny * iny; + if(filled) { + inside = dist <= 1.0; + } else if(rx > border && ry > border) { + inside = dist <= 1.0 && innerDist > 1.0; + } else { + inside = dist <= 1.0; + } + + if(inside) { + MwLLColor mixColor; + MwLLColor c = background ? background : (handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground))); + double mod; + unsigned char* pout = &data[(y * width + x) * 4]; + + if(MwGetInteger(handle, MwNdarkTheme)) { + mixColor = MwLightenColor(handle, base, -ColorDiff, -ColorDiff, -ColorDiff); + } else { + mixColor = MwLightenColor(handle, base, ColorDiff, ColorDiff, ColorDiff); + } + + if(MwGetInteger(handle, MwNdisabled)) { + mod = (innerDist * 2.) - 1; + } else { + mod = (innerDist / 2.) + 0.5; + } + color_set_disabled_if_disabled(handle, mixColor); + + if(c != NULL) { + mixColor->common.red = (MwU8)(mixColor->common.red + (c->common.red - mixColor->common.red) * mod); + mixColor->common.green = (MwU8)(mixColor->common.green + (c->common.green - mixColor->common.green) * mod); + mixColor->common.blue = (MwU8)(mixColor->common.blue + (c->common.blue - mixColor->common.blue) * mod); + MwLLColorUpdate(handle->lowlevel, mixColor, mixColor->common.red, mixColor->common.green, mixColor->common.blue); + + if(c != background) { + MwLLFreeColor(c); + } + } + + pout[0] = (MwU8)mixColor->common.red; + pout[1] = (MwU8)mixColor->common.green; + pout[2] = (MwU8)mixColor->common.blue; + + pout[3] = 255; + } + } + } + + pixmap = MwLLCreatePixmap(handle->lowlevel, data, width, height); + MwLLDrawPixmap(handle->lowlevel, rect, pixmap); + MwLLDestroyPixmap(pixmap); + + MwLLFreeColor(lighter); + MwLLFreeColor(darker); + MwLLFreeColor(base); + + free(data); +}; + static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) { MwPoint p[7]; int ColorDiff = get_color_diff(handle); @@ -952,8 +1049,8 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) { } } - rgb = malloc(row * col * 4); - comp = malloc(cpp + 1); + rgb = malloc(row * col * 4); + comp = malloc(cpp + 1); if(!rgb || !comp) { printf("Null malloc! Out of memory?"); return NULL; diff --git a/src/widget/radiobox.c b/src/widget/radiobox.c index c93e054..1930259 100644 --- a/src/widget/radiobox.c +++ b/src/widget/radiobox.c @@ -30,7 +30,37 @@ static void draw(MwWidget handle) { r.x = (MwGetInteger(handle, MwNwidth) - r.width) / 2; r.y = (MwGetInteger(handle, MwNheight) - r.height) / 2; - MwDrawDiamond(handle, &r, base, (handle->pressed || MwGetInteger(handle, MwNchecked)) ? 1 : 0); + if(MwGetInteger(handle, MwNmodernLook) == 1) { + int is_checked = (handle->pressed || MwGetInteger(handle, MwNchecked)); + MwLLColor darker; + MwLLColor inner; + MwLLColor innerunsel = base; + + if(MwGetInteger(handle, MwNdarkTheme) == 1) { + darker = MwLLAllocColor(handle->lowlevel, 255, 255, 255); + innerunsel = MwLightenColor(handle, base, 80, 80, 80); + inner = darker; + } else { + darker = MwLLAllocColor(handle->lowlevel, 0, 0, 0); + inner = MwLightenColor(handle, is_checked ? darker : base, -80, -80, -80); + } + MwDrawCircle(handle, &r, darker, NULL, 1); + + if(!MwGetInteger(handle, MwNdisabled)) { + r.x += 2; + r.y += 2; + r.width -= 4; + r.height -= 4; + if(!is_checked) { + MwDrawCircle(handle, &r, innerunsel, innerunsel, 1); + } else { + MwDrawCircle(handle, &r, inner, innerunsel, 1); + } + } + MwLLFreeColor(darker); + } else { + MwDrawDiamond(handle, &r, base, (handle->pressed || MwGetInteger(handle, MwNchecked)) ? 1 : 0); + } MwLLFreeColor(base); } @@ -49,29 +79,38 @@ static void click(MwWidget handle) { MwDispatchUserHandler(handle, MwNchangedHandler, NULL); } +static void mouse_down(MwWidget handle, void* ptr) { + handle->held = 1; + MwForceRender2(handle, ptr); +} + +static void mouse_up(MwWidget handle, void* ptr) { + handle->held = 0; + MwForceRender2(handle, ptr); +} static void prop_change(MwWidget handle, const char* key) { if(strcmp(key, MwNchecked) == 0) MwForceRender(handle); } MwClassRec MwRadioBoxClassRec = { - wcreate, /* 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, /* tick */ - NULL, /* resize */ - NULL, /* children_update */ - NULL, /* children_prop_change */ - NULL, /* clipboard */ - NULL, /* props_change */ + wcreate, /* create */ + NULL, /* destroy */ + draw, /* draw */ + click, /* click */ + NULL, /* parent_resize */ + prop_change, /* prop_change */ + NULL, /* mouse_move */ + mouse_up, /* mouse_up */ + mouse_down, /* mouse_down */ + NULL, /* key */ + NULL, /* execute */ + NULL, /* tick */ + NULL, /* resize */ + NULL, /* children_update */ + NULL, /* children_prop_change */ + NULL, /* clipboard */ + NULL, /* props_change */ NULL, NULL, NULL};