add clock widget (closes #35)

This commit is contained in:
Nishi 2026-09-13 20:11:01 +09:00
commit c6aaf54656
15 changed files with 210 additions and 16 deletions

View file

@ -245,6 +245,15 @@ int main() {
MwNscale, 1, MwNscale, 1,
NULL); 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); f = frame("ComboBox", -PaddingContent, 24, MwComboBoxClass, NULL);
w = child(f); w = child(f);
MwComboBoxAdd(w, -1, "Hello!"); MwComboBoxAdd(w, -1, "Hello!");

View file

@ -4,7 +4,7 @@
#include <math.h> #include <math.h>
#ifndef M_PI #ifndef M_PI
#define M_PI 3.14159265 #define M_PI 3.14159265359
#endif #endif
#define SIZE 100 #define SIZE 100

View file

@ -13,7 +13,7 @@
#include <stdlib.h> #include <stdlib.h>
#ifndef M_PI #ifndef M_PI
#define M_PI 3.14159265 #define M_PI 3.14159265359
#endif #endif
/** /**

View file

@ -13,6 +13,13 @@
extern "C" { extern "C" {
#endif #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 * @brief Parses a color text
* @param handle Widget * @param handle Widget

View file

@ -86,7 +86,7 @@
#endif #endif
#ifndef M_PI #ifndef M_PI
#define M_PI 3.14159265 #define M_PI 3.14159265359
#endif #endif
/* Windows */ /* Windows */

View file

@ -37,6 +37,7 @@
#include <Mw/Widget/Button.h> #include <Mw/Widget/Button.h>
#include <Mw/Widget/Calendar.h> #include <Mw/Widget/Calendar.h>
#include <Mw/Widget/CheckBox.h> #include <Mw/Widget/CheckBox.h>
#include <Mw/Widget/Clock.h>
#include <Mw/Widget/ComboBox.h> #include <Mw/Widget/ComboBox.h>
#include <Mw/Widget/Entry.h> #include <Mw/Widget/Entry.h>
#include <Mw/Widget/Frame.h> #include <Mw/Widget/Frame.h>

View file

@ -54,6 +54,9 @@
#define MwNrowSpan "IrowSpan" #define MwNrowSpan "IrowSpan"
#define MwNdisabled "Idisabled" #define MwNdisabled "Idisabled"
#define MwNacceptsDnD "IacceptsDnD" #define MwNacceptsDnD "IacceptsDnD"
#define MwNhour "Ihour"
#define MwNminute "Iminute"
#define MwNsecond "Isecond"
#define MwNtitle "Stitle" #define MwNtitle "Stitle"
#define MwNtext "Stext" #define MwNtext "Stext"

24
include/Mw/Widget/Clock.h Normal file
View file

@ -0,0 +1,24 @@
/*!
* @file Mw/Widget/Clock.h
* @brief Clock widget
*/
#ifndef __MW_WIDGET_CLOCK_H__
#define __MW_WIDGET_CLOCK_H__
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @brief Clock widget class
*/
MWDECL MwClass MwClockClass;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -106,6 +106,9 @@
<integer name="columns" /> <integer name="columns" />
<integer name="columnSpan" column="yes" /> <integer name="columnSpan" column="yes" />
<integer name="rowSpan" column="yes" /> <integer name="rowSpan" column="yes" />
<integer name="hour" />
<integer name="minute" />
<integer name="second" />
<!-- waitMS is a special property, only applies to toplevel widget --> <!-- waitMS is a special property, only applies to toplevel widget -->
<integer name="waitMS" common="yes" /> <integer name="waitMS" common="yes" />
@ -654,6 +657,13 @@
<handler name="changed" /> <handler name="changed" />
</handlers> </handlers>
</widget> </widget>
<widget name="Clock">
<properties>
<property name="hour" />
<property name="minute" />
<property name="second" />
</properties>
</widget>
<widget name="Entry"> <widget name="Entry">
<properties> <properties>
<property name="text" /> <property name="text" />

View file

@ -66,7 +66,7 @@ if (grep(/^wayland$/, @backends)) {
scan_wayland_protocol("unstable", "primary-selection", "-unstable-v1"); scan_wayland_protocol("unstable", "primary-selection", "-unstable-v1");
scan_wayland_protocol("unstable", "pointer-constraints", "-unstable-v1"); scan_wayland_protocol("unstable", "pointer-constraints", "-unstable-v1");
scan_wayland_protocol("unstable", "relative-pointer", "-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", scan_wayland_protocol_from_file("wlr-layer-shell",
"wlr-layer-shell-unstable-v1.xml"); "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/button.c");
new_object("src/widget/calendar.c"); new_object("src/widget/calendar.c");
new_object("src/widget/checkbox.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/combobox.c");
new_object("src/widget/entry.c"); new_object("src/widget/entry.c");
new_object("src/widget/frame.c"); new_object("src/widget/frame.c");

View file

@ -2,8 +2,7 @@
char* MwACPTextToUTF8Text(const char* input) { char* MwACPTextToUTF8Text(const char* input) {
#if defined(_WIN32) && defined(MW_HAS_WCHAR) #if defined(_WIN32) && defined(MW_HAS_WCHAR)
int mbbytes = (strlen(input) + 1) * 4; int wbytes = 0;
int wbytes = 0;
int len; int len;
wchar_t* wout; wchar_t* wout;
@ -39,7 +38,6 @@ char* MwACPTextToUTF8Text(const char* input) {
char* MwUTF8TextToACPText(const char* input) { char* MwUTF8TextToACPText(const char* input) {
#if defined(_WIN32) && defined(MW_HAS_WCHAR) #if defined(_WIN32) && defined(MW_HAS_WCHAR)
int mbbytes = (strlen(input) + 1) * 4; int mbbytes = (strlen(input) + 1) * 4;
int wbytes = 0;
int len; int len;
wchar_t* wout; wchar_t* wout;

View file

@ -5,7 +5,7 @@
#ifdef USE_COCOA #ifdef USE_COCOA
#define PERIODIC #define PERIODIC
#endif #endif
#define USE_CLASSIC_THEME
#define RESIZE_ON_TICK #define RESIZE_ON_TICK
#define DRAW(handle) \ #define DRAW(handle) \

View file

@ -11,7 +11,7 @@
#include "../external/stb_ds.h" #include "../external/stb_ds.h"
static int get_color_diff(MwWidget handle) { int MwGetColorDifference(MwWidget handle) {
if(MwGetInteger(handle, MwNmodernLook)) { if(MwGetInteger(handle, MwNmodernLook)) {
return 40; return 40;
} else { } else {
@ -121,7 +121,7 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) {
MwLLPixmap pixmap; MwLLPixmap pixmap;
int y; int y;
double darken = 0.; double darken = 0.;
int ColorDiff = get_color_diff(handle); int ColorDiff = MwGetColorDifference(handle);
double darkenStep = (ColorDiff / 2.) / rect->height; double darkenStep = (ColorDiff / 2.) / rect->height;
unsigned long sz = 1 * rect->height * 4; unsigned long sz = 1 * rect->height * 4;
unsigned char* data = malloc(sz * 2); unsigned char* data = malloc(sz * 2);
@ -178,7 +178,7 @@ void MwDrawFrameWithBorder(MwWidget handle, MwRect* rect, MwLLColor color, int i
if(MwGetInteger(handle, MwNmodernLook)) { if(MwGetInteger(handle, MwNmodernLook)) {
MwDrawFrameEx(handle, rect, color, invert, border, 0, 0); MwDrawFrameEx(handle, rect, color, invert, border, 0, 0);
} else { } else {
int diff = get_color_diff(handle) / 3 * 2; int diff = MwGetColorDifference(handle) / 3 * 2;
if(border >= 2) { if(border >= 2) {
int i; 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) { void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) {
MwPoint p[6]; MwPoint p[6];
int border = MwDefaultBorderWidth(handle); 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 darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = 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); 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; double cx, cy, rx, ry;
int border; int border;
int x, y; int x, y;
int ColorDiff = (get_color_diff(handle)); int ColorDiff = (MwGetColorDifference(handle));
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff); MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff); MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff);
MwLLColor base = MwLightenColor(handle, color, 0, 0, 0); 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[2] = (MwU8)mixColor->common.blue;
pout[3] = 255; 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) { static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) {
MwPoint p[7]; 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 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); 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); 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) { 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 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); MwLLColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff);
MwRect r = *rect; 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) { void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int direction) {
MwPoint p1[4], p2[4], p3[4], p4[3]; MwPoint p1[4], p2[4], p3[4], p4[3];
const int border = MwGetInteger(handle, MwNmodernLook) ? 2 : MwDefaultBorderWidth(handle); 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 darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = 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); MwLLColor col = invert ? MwLightenColor(handle, color, -8, -8, -8) : MwLightenColor(handle, color, 0, 0, 0);

0
src/widget/chart.c Normal file
View file

138
src/widget/clock.c Normal file
View file

@ -0,0 +1,138 @@
#include <Mw/Milsko.h>
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;