Skip to content

Commit e9ad245

Browse files
committed
Added calendar widget
The widget is an embedded gtk4 calendar which can be styled as such. Written with the assistance of Qwen Code.
1 parent 1043ef9 commit e9ad245

8 files changed

Lines changed: 253 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ These widgets can be customized, added, removed and even reordered
9393
- Do Not Disturb
9494
- Notifications (Will always be visible)
9595
- Label
96+
- Calendar
9697
- Mpris (Media player controls for Spotify, Firefox, Chrome, etc...)
9798
- Menubar with dropdown and buttons
9899
- Button grid

data/style/style.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,3 +398,5 @@ notificationwindow, blankwindow {
398398
@import "widgets/backlight";
399399
/* Inhibitors widget */
400400
@import "widgets/inhibitors";
401+
/* Calendar widget */
402+
@import "widgets/calendar";

data/style/widgets/calendar.scss

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
:root {
2+
--widget-calendar-font-size-day: 1.1rem;
3+
--widget-calendar-font-size-date: 1.4rem;
4+
}
5+
6+
.widget-calendar {
7+
padding: 12px;
8+
margin: 8px;
9+
10+
.calendar-container {
11+
.day-label {
12+
font-size: var(--widget-calendar-font-size-day);
13+
font-weight: bold;
14+
color: var(--text-color);
15+
margin-bottom: 2px;
16+
}
17+
18+
.date-label {
19+
font-size: var(--widget-calendar-font-size-date);
20+
color: var(--text-color);
21+
opacity: 0.8;
22+
margin-bottom: 8px;
23+
}
24+
25+
calendar {
26+
background: rgba(var(--noti-bg), var(--noti-bg-alpha));
27+
border: var(--border);
28+
border-radius: var(--border-radius);
29+
padding: 8px;
30+
color: var(--text-color);
31+
font-size: 0.9rem;
32+
}
33+
}
34+
}

man/swaync.5.scd

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,8 @@ config file to be able to detect config errors
341341
#END pulse-audio
342342
*backlight*++
343343
optional: true ++
344+
*calendar*++
345+
optional: true ++
344346
*inhibitors*++
345347
optional: true ++
346348
description: ++
@@ -738,6 +740,51 @@ config file to be able to detect config errors
738740
default: 0 ++
739741
description: Lowest possible value for brightness ++
740742
description: Slider to control screen brightness ++
743+
*calendar*++
744+
type: object ++
745+
css classes: ++
746+
widget-calendar ++
747+
calendar-container ++
748+
day-label ++
749+
date-label ++
750+
properties: ++
751+
show-day-label: ++
752+
type: bool ++
753+
optional: true ++
754+
default: true ++
755+
description: Whether to show the day of the week label ++
756+
show-date-label: ++
757+
type: bool ++
758+
optional: true ++
759+
default: true ++
760+
description: Whether to show the date label ++
761+
show-heading: ++
762+
type: bool ++
763+
optional: true ++
764+
default: true ++
765+
description: Whether to show the month/year heading in the calendar grid ++
766+
show-day-names: ++
767+
type: bool ++
768+
optional: true ++
769+
default: true ++
770+
description: Whether to show the day of week abbreviations in the calendar grid ++
771+
show-week-numbers: ++
772+
type: bool ++
773+
optional: true ++
774+
default: false ++
775+
description: Whether to show ISO week numbers in the calendar grid ++
776+
day-format: ++
777+
type: string ++
778+
optional: true ++
779+
default: "%A" ++
780+
description: strftime format for the day label (e.g. "Monday") ++
781+
date-format: ++
782+
type: string ++
783+
optional: true ++
784+
default: "%B %-d, %Y" ++
785+
description: strftime format for the date label (e.g. "January 1, 2024") ++
786+
description: A calendar widget displaying the day, date, and a GTK4 calendar grid. ++
787+
Today's date is automatically marked. Clicking a day updates the labels. ++
741788
*inhibitors*++
742789
type: object ++
743790
css class: widget-inhibitors ++

src/configSchema.json

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,9 @@
423423
"^inhibitors(#[a-zA-Z0-9_-]{1,}){0,1}?$": {
424424
"$comment": "References the widget structure from \"widgets\" below",
425425
"$ref": "#/widgets/inhibitors"
426+
},
427+
"^calendar(#[a-zA-Z0-9_-]{1,}){0,1}?$": {
428+
"$ref": "#/widgets/calendar"
426429
}
427430
}
428431
}
@@ -790,6 +793,48 @@
790793
"default": "Clear All"
791794
}
792795
}
796+
},
797+
"calendar": {
798+
"type": "object",
799+
"description": "Control Center Calendar Widget",
800+
"additionalProperties": false,
801+
"properties": {
802+
"show-day-label": {
803+
"type": "boolean",
804+
"description": "Whether to show the day label (e.g., \"Monday\")",
805+
"default": true
806+
},
807+
"show-date-label": {
808+
"type": "boolean",
809+
"description": "Whether to show the date label (e.g., \"January 1, 2024\")",
810+
"default": true
811+
},
812+
"show-heading": {
813+
"type": "boolean",
814+
"description": "Whether to show the month/year heading in the calendar grid",
815+
"default": true
816+
},
817+
"show-day-names": {
818+
"type": "boolean",
819+
"description": "Whether to show the day of week abbreviations in the calendar grid",
820+
"default": true
821+
},
822+
"show-week-numbers": {
823+
"type": "boolean",
824+
"description": "Whether to show ISO week numbers in the calendar grid",
825+
"default": false
826+
},
827+
"day-format": {
828+
"type": "string",
829+
"description": "strftime format for the day label",
830+
"default": "%A"
831+
},
832+
"date-format": {
833+
"type": "string",
834+
"description": "strftime format for the date label",
835+
"default": "%B %-d, %Y"
836+
}
837+
}
793838
}
794839
}
795840
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
namespace SwayNotificationCenter.Widgets {
2+
public class Calendar : BaseWidget {
3+
public override string widget_name {
4+
get {
5+
return "calendar";
6+
}
7+
}
8+
9+
Gtk.Calendar calendar;
10+
Gtk.Label date_label;
11+
Gtk.Label day_label;
12+
13+
string day_format = "%A";
14+
string date_format = "%B %-d, %Y";
15+
16+
public Calendar (string suffix) {
17+
base (suffix);
18+
19+
Json.Object ?config = get_config (this);
20+
21+
var container = new Gtk.Box (Gtk.Orientation.VERTICAL, 6);
22+
container.add_css_class ("calendar-container");
23+
container.set_hexpand (true);
24+
25+
day_label = new Gtk.Label (null);
26+
day_label.add_css_class ("day-label");
27+
day_label.set_halign (Gtk.Align.START);
28+
29+
date_label = new Gtk.Label (null);
30+
date_label.add_css_class ("date-label");
31+
date_label.set_halign (Gtk.Align.START);
32+
33+
calendar = new Gtk.Calendar ();
34+
calendar.set_hexpand (true);
35+
36+
if (config != null) {
37+
bool show_day_label_found;
38+
bool ?show_day_label = get_prop<bool> (config, "show-day-label",
39+
out show_day_label_found);
40+
if (show_day_label_found && show_day_label == false) {
41+
day_label.set_visible (false);
42+
}
43+
44+
bool show_date_label_found;
45+
bool ?show_date_label = get_prop<bool> (config, "show-date-label",
46+
out show_date_label_found);
47+
if (show_date_label_found && show_date_label == false) {
48+
date_label.set_visible (false);
49+
}
50+
51+
bool show_heading_found;
52+
bool ?show_heading = get_prop<bool> (config, "show-heading",
53+
out show_heading_found);
54+
if (show_heading_found) {
55+
calendar.show_heading = show_heading;
56+
}
57+
58+
bool show_day_names_found;
59+
bool ?show_day_names = get_prop<bool> (config, "show-day-names",
60+
out show_day_names_found);
61+
if (show_day_names_found) {
62+
calendar.show_day_names = show_day_names;
63+
}
64+
65+
bool show_week_numbers_found;
66+
bool ?show_week_numbers = get_prop<bool> (config, "show-week-numbers",
67+
out show_week_numbers_found);
68+
if (show_week_numbers_found) {
69+
calendar.show_week_numbers = show_week_numbers;
70+
}
71+
72+
string ?df = get_prop<string> (config, "day-format");
73+
if (df != null) {
74+
day_format = df;
75+
}
76+
77+
string ?dtf = get_prop<string> (config, "date-format");
78+
if (dtf != null) {
79+
date_format = dtf;
80+
}
81+
}
82+
83+
mark_today ();
84+
85+
container.append (day_label);
86+
container.append (date_label);
87+
container.append (calendar);
88+
append (container);
89+
90+
calendar.day_selected.connect (update_labels);
91+
calendar.next_month.connect (update_labels);
92+
calendar.prev_month.connect (update_labels);
93+
update_labels ();
94+
}
95+
96+
void mark_today () {
97+
calendar.clear_marks ();
98+
var now = new DateTime.now_local ();
99+
calendar.mark_day ((uint) now.get_day_of_month ());
100+
}
101+
102+
void update_labels () {
103+
var selected = calendar.get_date ();
104+
var dt = new DateTime.local ((int) selected.get_year (),
105+
(int) selected.get_month (),
106+
(int) selected.get_day_of_month (),
107+
0, 0, 0.0);
108+
day_label.set_label (dt.format (day_format));
109+
date_label.set_label (dt.format (date_format));
110+
}
111+
112+
public override void on_cc_visibility_change (bool value) {
113+
if (value) {
114+
mark_today ();
115+
update_labels ();
116+
}
117+
}
118+
}
119+
}

src/controlCenter/widgets/factory.vala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ namespace SwayNotificationCenter.Widgets {
3737
case "slider":
3838
widget = new Slider (suffix);
3939
break;
40+
case "calendar":
41+
widget = new Calendar (suffix);
42+
break;
4043
#if HAVE_PULSE_AUDIO
4144
case "volume":
4245
widget = new Volume (suffix);

src/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ widget_sources = [
5050
'controlCenter/widgets/backlight/backlightUtil.vala',
5151
# Widget: Inhibitors
5252
'controlCenter/widgets/inhibitors/inhibitors.vala',
53+
# Widget: Calendar
54+
'controlCenter/widgets/calendar/calendar.vala',
5355
]
5456

5557
app_sources = [

0 commit comments

Comments
 (0)