Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ These widgets can be customized, added, removed and even reordered
- Do Not Disturb
- Notifications (Will always be visible)
- Label
- Calendar
- Mpris (Media player controls for Spotify, Firefox, Chrome, etc...)
- Menubar with dropdown and buttons
- Button grid
Expand Down
2 changes: 2 additions & 0 deletions data/style/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -398,3 +398,5 @@ notificationwindow, blankwindow {
@import "widgets/backlight";
/* Inhibitors widget */
@import "widgets/inhibitors";
/* Calendar widget */
@import "widgets/calendar";
34 changes: 34 additions & 0 deletions data/style/widgets/calendar.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
:root {
--widget-calendar-font-size-day: 1.1rem;
--widget-calendar-font-size-date: 1.4rem;
}

.widget-calendar {
padding: 12px;
margin: 8px;

.calendar-container {
.day-label {
font-size: var(--widget-calendar-font-size-day);
font-weight: bold;
color: var(--text-color);
margin-bottom: 2px;
}

.date-label {
font-size: var(--widget-calendar-font-size-date);
color: var(--text-color);
opacity: 0.8;
margin-bottom: 8px;
}

calendar {
background: rgba(var(--noti-bg), var(--noti-bg-alpha));
border: var(--border);
border-radius: var(--border-radius);
padding: 8px;
color: var(--text-color);
font-size: 0.9rem;
}
}
}
47 changes: 47 additions & 0 deletions man/swaync.5.scd
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ config file to be able to detect config errors
#END pulse-audio
*backlight*++
optional: true ++
*calendar*++
optional: true ++
*inhibitors*++
optional: true ++
description: ++
Expand Down Expand Up @@ -738,6 +740,51 @@ config file to be able to detect config errors
default: 0 ++
description: Lowest possible value for brightness ++
description: Slider to control screen brightness ++
*calendar*++
type: object ++
css classes: ++
widget-calendar ++
calendar-container ++
day-label ++
date-label ++
properties: ++
show-day-label: ++
type: bool ++
optional: true ++
default: true ++
description: Whether to show the day of the week label ++
show-date-label: ++
type: bool ++
optional: true ++
default: true ++
description: Whether to show the date label ++
show-heading: ++
type: bool ++
optional: true ++
default: true ++
description: Whether to show the month/year heading in the calendar grid ++
show-day-names: ++
type: bool ++
optional: true ++
default: true ++
description: Whether to show the day of week abbreviations in the calendar grid ++
show-week-numbers: ++
type: bool ++
optional: true ++
default: false ++
description: Whether to show ISO week numbers in the calendar grid ++
day-format: ++
type: string ++
optional: true ++
default: "%A" ++
description: strftime format for the day label (e.g. "Monday") ++
date-format: ++
type: string ++
optional: true ++
default: "%B %-d, %Y" ++
description: strftime format for the date label (e.g. "January 1, 2024") ++
description: A calendar widget displaying the day, date, and a GTK4 calendar grid. ++
Today's date is automatically marked. Clicking a day updates the labels. ++
*inhibitors*++
type: object ++
css class: widget-inhibitors ++
Expand Down
45 changes: 45 additions & 0 deletions src/configSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,9 @@
"^inhibitors(#[a-zA-Z0-9_-]{1,}){0,1}?$": {
"$comment": "References the widget structure from \"widgets\" below",
"$ref": "#/widgets/inhibitors"
},
"^calendar(#[a-zA-Z0-9_-]{1,}){0,1}?$": {
"$ref": "#/widgets/calendar"
}
}
}
Expand Down Expand Up @@ -790,6 +793,48 @@
"default": "Clear All"
}
}
},
"calendar": {
"type": "object",
"description": "Control Center Calendar Widget",
"additionalProperties": false,
"properties": {
"show-day-label": {
"type": "boolean",
"description": "Whether to show the day label (e.g., \"Monday\")",
"default": true
},
"show-date-label": {
"type": "boolean",
"description": "Whether to show the date label (e.g., \"January 1, 2024\")",
"default": true
},
"show-heading": {
"type": "boolean",
"description": "Whether to show the month/year heading in the calendar grid",
"default": true
},
"show-day-names": {
"type": "boolean",
"description": "Whether to show the day of week abbreviations in the calendar grid",
"default": true
},
"show-week-numbers": {
"type": "boolean",
"description": "Whether to show ISO week numbers in the calendar grid",
"default": false
},
"day-format": {
"type": "string",
"description": "strftime format for the day label",
"default": "%A"
},
"date-format": {
"type": "string",
"description": "strftime format for the date label",
"default": "%B %-d, %Y"
}
}
}
}
}
131 changes: 131 additions & 0 deletions src/controlCenter/widgets/calendar/calendar.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
namespace SwayNotificationCenter.Widgets {
public class Calendar : BaseWidget {
public override string widget_name {
get {
return "calendar";
}
}

Gtk.Calendar calendar;
Gtk.Label date_label;
Gtk.Label day_label;

string day_format = "%A";
string date_format = "%B %-d, %Y";

public Calendar (string suffix) {
base (suffix);

Json.Object ?config = get_config (this);

var container = new Gtk.Box (Gtk.Orientation.VERTICAL, 6);
container.add_css_class ("calendar-container");
container.set_hexpand (true);

day_label = new Gtk.Label (null);
day_label.add_css_class ("day-label");
day_label.set_halign (Gtk.Align.START);

date_label = new Gtk.Label (null);
date_label.add_css_class ("date-label");
date_label.set_halign (Gtk.Align.START);

calendar = new Gtk.Calendar ();
calendar.set_hexpand (true);

if (config != null) {
bool show_day_label_found;
bool ?show_day_label = get_prop<bool> (config, "show-day-label",
out show_day_label_found);
if (show_day_label_found && show_day_label == false) {
day_label.set_visible (false);
}

bool show_date_label_found;
bool ?show_date_label = get_prop<bool> (config, "show-date-label",
out show_date_label_found);
if (show_date_label_found && show_date_label == false) {
date_label.set_visible (false);
}

bool show_heading_found;
bool ?show_heading = get_prop<bool> (config, "show-heading",
out show_heading_found);
if (show_heading_found) {
calendar.show_heading = show_heading;
}

bool show_day_names_found;
bool ?show_day_names = get_prop<bool> (config, "show-day-names",
out show_day_names_found);
if (show_day_names_found) {
calendar.show_day_names = show_day_names;
}

bool show_week_numbers_found;
bool ?show_week_numbers = get_prop<bool> (config, "show-week-numbers",
out show_week_numbers_found);
if (show_week_numbers_found) {
calendar.show_week_numbers = show_week_numbers;
}

string ?df = get_prop<string> (config, "day-format");
if (df != null) {
day_format = df;
}

string ?dtf = get_prop<string> (config, "date-format");
if (dtf != null) {
date_format = dtf;
}
}

container.append (day_label);
container.append (date_label);
container.append (calendar);
append (container);

calendar.day_selected.connect (update_labels);
calendar.next_month.connect (update_labels);
calendar.prev_month.connect (update_labels);
calendar.next_year.connect (update_labels);
calendar.prev_year.connect (update_labels);
reset_to_today ();
}

void update_marks (DateTime selected) {
var today = new DateTime.now_local ();

calendar.clear_marks ();

if (selected.get_year () == today.get_year ()
&& selected.get_month () == today.get_month ()) {
calendar.mark_day ((uint) today.get_day_of_month ());
}
}

void reset_to_today () {
var today = new DateTime.now_local ();
calendar.select_day (today);
update_labels ();
}

void update_labels () {
var selected = calendar.get_date ();
update_marks (selected);

var dt = new DateTime.local ((int) selected.get_year (),
(int) selected.get_month (),
(int) selected.get_day_of_month (),
0, 0, 0.0);
day_label.set_label (dt.format (day_format));
date_label.set_label (dt.format (date_format));
}

public override void on_cc_visibility_change (bool value) {
if (value) {
reset_to_today ();
}
}
}
}
3 changes: 3 additions & 0 deletions src/controlCenter/widgets/factory.vala
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ namespace SwayNotificationCenter.Widgets {
case "slider":
widget = new Slider (suffix);
break;
case "calendar":
widget = new Calendar (suffix);
break;
#if HAVE_PULSE_AUDIO
case "volume":
widget = new Volume (suffix);
Expand Down
2 changes: 2 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ widget_sources = [
'controlCenter/widgets/backlight/backlightUtil.vala',
# Widget: Inhibitors
'controlCenter/widgets/inhibitors/inhibitors.vala',
# Widget: Calendar
'controlCenter/widgets/calendar/calendar.vala',
]

app_sources = [
Expand Down
Loading