diff --git a/examples/basic/periodic.c b/examples/basic/periodic.c index b449f09..06a115b 100644 --- a/examples/basic/periodic.c +++ b/examples/basic/periodic.c @@ -245,6 +245,15 @@ int main() { MwNscale, 1, NULL); + f = frame("Clock", -PaddingContent, -PaddingContent, MwClockClass, + MwNhour, 15, + MwNminute, 0, + MwNsecond, 10, + NULL); + + f = frame("Chart", -PaddingContent, -PaddingContent, MwCalendarClass, + NULL); + f = frame("ComboBox", -PaddingContent, 24, MwComboBoxClass, NULL); w = child(f); MwComboBoxAdd(w, -1, "Hello!"); diff --git a/examples/basic/rotate.c b/examples/basic/rotate.c index dbf9c5e..112d5fc 100644 --- a/examples/basic/rotate.c +++ b/examples/basic/rotate.c @@ -4,7 +4,7 @@ #include #ifndef M_PI -#define M_PI 3.14159265 +#define M_PI 3.14159265359 #endif #define SIZE 100 diff --git a/examples/gldemos/gears.c b/examples/gldemos/gears.c index 5d06b06..a1aad90 100644 --- a/examples/gldemos/gears.c +++ b/examples/gldemos/gears.c @@ -13,7 +13,7 @@ #include #ifndef M_PI -#define M_PI 3.14159265 +#define M_PI 3.14159265359 #endif /** diff --git a/include/Mw/Draw.h b/include/Mw/Draw.h index 443835c..542aac5 100644 --- a/include/Mw/Draw.h +++ b/include/Mw/Draw.h @@ -13,6 +13,13 @@ extern "C" { #endif +/*! + * @brief Get a color difference for shadow + * @param handle Widget + * @return Color difference + */ +MWDECL int MWAPI MwGetColorDifference(MwWidget handle); + /*! * @brief Parses a color text * @param handle Widget diff --git a/include/Mw/MachDep.h b/include/Mw/MachDep.h index 4c98b24..7313ce2 100644 --- a/include/Mw/MachDep.h +++ b/include/Mw/MachDep.h @@ -86,7 +86,7 @@ #endif #ifndef M_PI -#define M_PI 3.14159265 +#define M_PI 3.14159265359 #endif /* Windows */ diff --git a/include/Mw/Milsko.h b/include/Mw/Milsko.h index 9860990..7997bb6 100644 --- a/include/Mw/Milsko.h +++ b/include/Mw/Milsko.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Mw/StringDefs.h b/include/Mw/StringDefs.h index 6ad4e46..39730db 100644 --- a/include/Mw/StringDefs.h +++ b/include/Mw/StringDefs.h @@ -54,6 +54,9 @@ #define MwNrowSpan "IrowSpan" #define MwNdisabled "Idisabled" #define MwNacceptsDnD "IacceptsDnD" +#define MwNhour "Ihour" +#define MwNminute "Iminute" +#define MwNsecond "Isecond" #define MwNtitle "Stitle" #define MwNtext "Stext" diff --git a/include/Mw/Widget/Clock.h b/include/Mw/Widget/Clock.h new file mode 100644 index 0000000..a8057fe --- /dev/null +++ b/include/Mw/Widget/Clock.h @@ -0,0 +1,24 @@ +/*! + * @file Mw/Widget/Clock.h + * @brief Clock widget + */ +#ifndef __MW_WIDGET_CLOCK_H__ +#define __MW_WIDGET_CLOCK_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * @brief Clock widget class + */ +MWDECL MwClass MwClockClass; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/milsko.xml b/milsko.xml index a94c847..573b84d 100644 --- a/milsko.xml +++ b/milsko.xml @@ -106,6 +106,9 @@ + + + @@ -654,6 +657,13 @@ + + + + + + + diff --git a/pl/rules.pl b/pl/rules.pl index afc9ef9..220e550 100644 --- a/pl/rules.pl +++ b/pl/rules.pl @@ -66,7 +66,7 @@ if (grep(/^wayland$/, @backends)) { scan_wayland_protocol("unstable", "primary-selection", "-unstable-v1"); scan_wayland_protocol("unstable", "pointer-constraints", "-unstable-v1"); scan_wayland_protocol("unstable", "relative-pointer", "-unstable-v1"); - scan_wayland_protocol("staging", "fifo", "-v1"); + scan_wayland_protocol("staging", "fifo", "-v1"); scan_wayland_protocol_from_file("wlr-layer-shell", "wlr-layer-shell-unstable-v1.xml"); @@ -153,6 +153,8 @@ new_object("src/widget/box.c"); new_object("src/widget/button.c"); new_object("src/widget/calendar.c"); new_object("src/widget/checkbox.c"); +new_object("src/widget/chart.c"); +new_object("src/widget/clock.c"); new_object("src/widget/combobox.c"); new_object("src/widget/entry.c"); new_object("src/widget/frame.c"); diff --git a/src/abstract/charset.c b/src/abstract/charset.c index 2c339d5..4b831d5 100644 --- a/src/abstract/charset.c +++ b/src/abstract/charset.c @@ -2,8 +2,7 @@ char* MwACPTextToUTF8Text(const char* input) { #if defined(_WIN32) && defined(MW_HAS_WCHAR) - int mbbytes = (strlen(input) + 1) * 4; - int wbytes = 0; + int wbytes = 0; int len; wchar_t* wout; @@ -39,7 +38,6 @@ char* MwACPTextToUTF8Text(const char* input) { char* MwUTF8TextToACPText(const char* input) { #if defined(_WIN32) && defined(MW_HAS_WCHAR) int mbbytes = (strlen(input) + 1) * 4; - int wbytes = 0; int len; wchar_t* wout; diff --git a/src/core.c b/src/core.c index 3180922..2982c1e 100644 --- a/src/core.c +++ b/src/core.c @@ -5,7 +5,7 @@ #ifdef USE_COCOA #define PERIODIC #endif - +#define USE_CLASSIC_THEME #define RESIZE_ON_TICK #define DRAW(handle) \ diff --git a/src/draw.c b/src/draw.c index c7869e0..bbd0264 100644 --- a/src/draw.c +++ b/src/draw.c @@ -11,7 +11,7 @@ #include "../external/stb_ds.h" -static int get_color_diff(MwWidget handle) { +int MwGetColorDifference(MwWidget handle) { if(MwGetInteger(handle, MwNmodernLook)) { return 40; } else { @@ -121,7 +121,7 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) { MwLLPixmap pixmap; int y; double darken = 0.; - int ColorDiff = get_color_diff(handle); + int ColorDiff = MwGetColorDifference(handle); double darkenStep = (ColorDiff / 2.) / rect->height; unsigned long sz = 1 * rect->height * 4; unsigned char* data = malloc(sz * 2); @@ -178,7 +178,7 @@ void MwDrawFrameWithBorder(MwWidget handle, MwRect* rect, MwLLColor color, int i if(MwGetInteger(handle, MwNmodernLook)) { MwDrawFrameEx(handle, rect, color, invert, border, 0, 0); } else { - int diff = get_color_diff(handle) / 3 * 2; + int diff = MwGetColorDifference(handle) / 3 * 2; if(border >= 2) { int i; @@ -236,7 +236,7 @@ void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { MwPoint p[6]; int border = MwDefaultBorderWidth(handle); - int ColorDiff = get_color_diff(handle) + (MwGetInteger(handle, MwNmodernLook) ? 48 : 0); + int ColorDiff = MwGetColorDifference(handle) + (MwGetInteger(handle, MwNmodernLook) ? 48 : 0); 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) : MwLightenColor(handle, color, 0, 0, 0); @@ -312,7 +312,7 @@ void MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor back double cx, cy, rx, ry; int border; int x, y; - int ColorDiff = (get_color_diff(handle)); + int ColorDiff = (MwGetColorDifference(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); @@ -385,6 +385,8 @@ void MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor back pout[2] = (MwU8)mixColor->common.blue; pout[3] = 255; + + MwLLFreeColor(mixColor); } } } @@ -402,7 +404,7 @@ void MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor back 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); + int ColorDiff = MwGetColorDifference(handle); MwLLColor darker = MwLightenColor(handle, color, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff); MwLLColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, ColorDiff - diff, ColorDiff - diff, ColorDiff - diff); color_set_disabled_if_disabled(handle, darker); @@ -499,7 +501,7 @@ static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighte } static void MwDrawFrameEx_complex(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) { - int ColorDiff = get_color_diff(handle); + int ColorDiff = MwGetColorDifference(handle); MwLLColor darker = MwLightenColor(handle, color, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff); MwLLColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff); MwRect r = *rect; @@ -539,7 +541,7 @@ void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, i void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int direction) { MwPoint p1[4], p2[4], p3[4], p4[3]; const int border = MwGetInteger(handle, MwNmodernLook) ? 2 : MwDefaultBorderWidth(handle); - int ColorDiff = get_color_diff(handle); + int ColorDiff = MwGetColorDifference(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) : MwLightenColor(handle, color, 0, 0, 0); diff --git a/src/widget/chart.c b/src/widget/chart.c new file mode 100644 index 0000000..e69de29 diff --git a/src/widget/clock.c b/src/widget/clock.c new file mode 100644 index 0000000..547464a --- /dev/null +++ b/src/widget/clock.c @@ -0,0 +1,138 @@ +#include + +static int wcreate(MwWidget handle) { + MwSetDefault(handle); + + MwSetInteger(handle, MwNhour, 0); + MwSetInteger(handle, MwNminute, 0); + MwSetInteger(handle, MwNsecond, 0); + return 0; +} + +static void hand(MwWidget handle, double x, double y, double width, double length, double angle, MwLLColor inside, MwLLColor border) { + double w = MwGetInteger(handle, MwNwidth); + double h = MwGetInteger(handle, MwNheight); + MwPoint p[5]; + int i; + double rad = (angle - 90) / 180 * M_PI; + double c = cos(rad); + double s = sin(rad); + double c2 = cos(rad - 0.5 * M_PI); + double s2 = sin(rad - 0.5 * M_PI); + double c3 = cos(rad - M_PI); + double s3 = sin(rad - M_PI); + + p[0].x = c2 * width / 2; + p[0].y = s2 * width / 2; + + p[1].x = c3 * width / 2 * 2; + p[1].y = s3 * width / 2 * 2; + + p[2].x = -c2 * width / 2; + p[2].y = -s2 * width / 2; + + p[3].x = c * length; + p[3].y = s * length; + + for(i = 0; i < 4; i++) { + p[i].x += w / 2 + x; + p[i].y += h / 2 + y; + } + + p[4] = p[0]; + + MwLLPolygon(handle->lowlevel, p, 4, inside); + MwLLLine(handle->lowlevel, &p[0], border); + MwLLLine(handle->lowlevel, &p[1], border); + MwLLLine(handle->lowlevel, &p[2], border); + MwLLLine(handle->lowlevel, &p[3], border); +} + +static void draw(MwWidget handle) { + int ColorDiff = MwGetColorDifference(handle); + int ShadowDist; + int BaseWidth; + MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); + MwLLColor shadow = MwLightenColor(handle, base, -ColorDiff, -ColorDiff, -ColorDiff); + MwLLColor inside = MwParseColor(handle, MwGetText(handle, MwNsubBackground)); + MwLLColor border = MwParseColor(handle, MwGetText(handle, MwNsubForeground)); + MwRect r; + int i; + double w; + double fs = (MwGetInteger(handle, MwNsecond) % 60); + double fm = (MwGetInteger(handle, MwNminute) % 60) + (MwGetInteger(handle, MwNsecond) % 60) / 60.0; + double s = (double)(MwGetInteger(handle, MwNsecond) % 60) / 60 * 360; + double m = ((double)(MwGetInteger(handle, MwNminute) % 60) + fs / 60.0) / 60 * 360; + double h = ((double)(MwGetInteger(handle, MwNhour) % 12) + fm / 60.0) / 12 * 360; + + r.x = 0; + r.y = 0; + r.width = MwGetInteger(handle, MwNwidth); + r.height = MwGetInteger(handle, MwNheight); + MwDrawRect(handle, &r, base); + + w = r.width < r.height ? r.width : r.height; + + BaseWidth = w / 10; + ShadowDist = BaseWidth / 3; + + for(i = 0; i < 12; i++) { + MwPoint p[2]; + double rad = i * 30 / 180.0 * M_PI; + double c = cos(rad); + double s = sin(rad); + double x, y; + double l = w / 2 / 5; + + x = r.width / 2 + c * w / 2 - l * c; + y = r.height / 2 + s * w / 2 - l * s; + + p[0].x = x + l * c / (i % 3 ? 2 : 1); + p[0].y = y + l * s / (i % 3 ? 2 : 1); + + p[1].x = x; + p[1].y = y; + + MwLLLine(handle->lowlevel, p, border); + } + + hand(handle, ShadowDist, ShadowDist, BaseWidth, w / 2 * 2 / 3, h, shadow, shadow); + hand(handle, ShadowDist, ShadowDist, BaseWidth, w / 2, m, shadow, shadow); + hand(handle, ShadowDist, ShadowDist, BaseWidth / 4, w / 2, s, shadow, shadow); + + hand(handle, 0, 0, w / 10, w / 2 * 2 / 3, h, inside, border); + hand(handle, 0, 0, BaseWidth, w / 2, m, inside, border); + hand(handle, 0, 0, BaseWidth / 4, w / 2, s, inside, border); + + MwLLFreeColor(border); + MwLLFreeColor(inside); + MwLLFreeColor(shadow); + MwLLFreeColor(base); +} + +static void prop_change(MwWidget handle, const char* key) { + if(strcmp(key, MwNhour) == 0 || strcmp(key, MwNminute) == 0 || strcmp(key, MwNsecond) == 0) MwForceRender(handle); +} + +MwClassRec MwClockClassRec = { + wcreate, /* create */ + NULL, /* destroy */ + draw, /* draw */ + NULL, /* click */ + NULL, /* parent_resize */ + prop_change, /* prop_change */ + NULL, /* mouse_move */ + NULL, /* mouse_up */ + NULL, /* 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}; +MwClass MwClockClass = &MwClockClassRec;