gui: Port to Blueprint

This was mostly done with `blueprint-compiler port`.

Since Blueprint doesn't know about custom templates, I had to manually change some values from strings to literals.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-calendar/-/merge_requests/567>
This commit is contained in:
Jamie Gravendeel
2025-06-08 14:31:01 +02:00
parent 2aceaa816f
commit a509de8b1e
90 changed files with 3278 additions and 3867 deletions
+38
View File
@@ -0,0 +1,38 @@
using Gtk 4.0;
template $GcalAgendaView: Box {
orientation: vertical;
$GcalDateChooser date_chooser {
split-month-year: false;
vexpand: false;
valign: end;
active-date: bind template.active-date no-sync-create bidirectional;
}
ScrolledWindow scrolled_window {
hexpand: true;
vexpand: true;
ListBox list_box {
hexpand: true;
selection-mode: none;
vexpand: true;
row-activated => $on_list_box_row_activated_cb(template) not-swapped;
ListBoxRow no_events_row {
activatable: false;
child: Label {
label: _("No events");
xalign: 0;
styles [
"no-events",
"dim-label",
]
};
}
}
}
}
-43
View File
@@ -1,43 +0,0 @@
<?xml version="1.0"?>
<interface>
<template class="GcalAgendaView" parent="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GcalDateChooser" id="date_chooser">
<property name="split-month-year">False</property>
<property name="vexpand">False</property>
<property name="valign">end</property>
<property name="active-date" bind-source="GcalAgendaView" bind-property="active-date" bind-flags="bidirectional" />
</object>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolled_window">
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child>
<object class="GtkListBox" id="list_box">
<property name="hexpand">True</property>
<property name="selection-mode">none</property>
<property name="vexpand">True</property>
<signal name="row-activated" handler="on_list_box_row_activated_cb" object="GcalAgendaView" swapped="no" />
<child>
<object class="GtkListBoxRow" id="no_events_row">
<property name="activatable">False</property>
<property name="child">
<object class="GtkLabel">
<property name="label" translatable="yes">No events</property>
<property name="xalign">0</property>
<style>
<class name="no-events" />
<class name="dim-label" />
</style>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>
+75
View File
@@ -0,0 +1,75 @@
using Gtk 4.0;
using Adw 1;
template $GcalMonthCell: Adw.BreakpointBin {
Adw.Breakpoint breakpoint_narrow {
condition ("max-width: 120sp")
setters {
weather_icon.halign: end;
weather_icon.hexpand: true;
weather_icon.margin-start: 6;
temp_label.visible: false;
}
}
width-request: 50;
height-request: 50;
hexpand: true;
vexpand: true;
focusable: true;
Overlay overlay {
[overlay]
Box header_box {
valign: start;
spacing: 6;
margin-top: 6;
margin-bottom: 6;
margin-start: 6;
margin-end: 6;
Label day_label {
styles [
"day-label",
"numeric",
]
}
Label month_name_label {}
Image weather_icon {
pixel-size: 16;
margin-start: 12;
styles [
"dim-label",
]
}
Label temp_label {
styles [
"dim-label",
"temp-label",
]
}
}
[overlay]
Button overflow_button {
valign: end;
sensitive: false;
clicked => $overflow_button_clicked_cb(template) not-swapped;
styles [
"flat",
]
Box {
Inscription overflow_inscription {
text-overflow: ellipsize_end;
}
}
}
}
}
-87
View File
@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GcalMonthCell" parent="AdwBreakpointBin">
<child>
<object class="AdwBreakpoint" id="breakpoint_narrow">
<condition>max-width: 120sp</condition>
<setter object="weather_icon" property="halign">end</setter>
<setter object="weather_icon" property="hexpand">True</setter>
<setter object="weather_icon" property="margin-start">6</setter>
<setter object="temp_label" property="visible">False</setter>
</object>
</child>
<property name="width-request">50</property>
<property name="height-request">50</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="focusable">True</property>
<child>
<object class="GtkOverlay" id="overlay">
<child type="overlay">
<object class="GtkBox" id="header_box">
<property name="valign">start</property>
<property name="spacing">6</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<child>
<object class="GtkLabel" id="day_label">
<style>
<class name="day-label" />
<class name="numeric" />
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="month_name_label" />
</child>
<!-- Weather forecast -->
<child>
<object class="GtkImage" id="weather_icon">
<property name="pixel_size">16</property>
<property name="margin-start">12</property>
<style>
<class name="dim-label" />
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="temp_label">
<style>
<class name="dim-label" />
<class name="temp-label" />
</style>
</object>
</child>
</object>
</child>
<child type="overlay">
<object class="GtkButton" id="overflow_button">
<property name="valign">end</property>
<property name="sensitive">False</property>
<signal name="clicked" handler="overflow_button_clicked_cb" object="GcalMonthCell" swapped="no" />
<style>
<class name="flat" />
</style>
<child>
<object class="GtkBox">
<child>
<object class="GtkInscription" id="overflow_inscription">
<property name="text-overflow">ellipsize-end</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>
+64
View File
@@ -0,0 +1,64 @@
using Gtk 4.0;
template $GcalMonthPopover: Widget {
visible: false;
ShortcutController {
Shortcut {
trigger: "Escape";
action: "action(month-popover.popdown)";
}
}
Box main_box {
orientation: vertical;
spacing: 12;
styles [
"card",
"view",
]
Box {
Label day_label {
label: "12";
xalign: 0.0;
hexpand: true;
styles [
"large-title",
]
}
Button {
halign: end;
valign: start;
icon-name: "window-close-symbolic";
clicked => $close_button_clicked_cb(template);
styles [
"flat",
"circular",
]
}
}
ListBox listbox {
vexpand: true;
selection-mode: none;
styles [
"calendar-list",
]
}
Button new_event_button {
label: _("New Event…");
clicked => $new_event_button_clicked_cb(template) not-swapped;
styles [
"flat",
]
}
}
}
-80
View File
@@ -1,80 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GcalMonthPopover" parent="GtkWidget">
<property name="visible">False</property>
<child>
<object class="GtkShortcutController">
<child>
<object class="GtkShortcut">
<property name="trigger">Escape</property>
<property name="action">action(month-popover.popdown)</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="main_box">
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<style>
<class name="card" />
<class name="view" />
</style>
<!-- Day label & close button-->
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="day_label">
<property name="label">12</property>
<property name="xalign">0.0</property>
<property name="hexpand">true</property>
<style>
<class name="large-title" />
</style>
</object>
</child>
<child>
<object class="GtkButton">
<property name="halign">end</property>
<property name="valign">start</property>
<property name="icon-name">window-close-symbolic</property>
<signal name="clicked" handler="close_button_clicked_cb" object="GcalMonthPopover" swapped="yes" />
<style>
<class name="flat" />
<class name="circular" />
</style>
</object>
</child>
</object>
</child>
<!-- Event list -->
<child>
<object class="GtkListBox" id="listbox">
<property name="vexpand">True</property>
<property name="selection-mode">none</property>
<style>
<class name="calendar-list" />
</style>
</object>
</child>
<!-- New Event button -->
<child>
<object class="GtkButton" id="new_event_button">
<property name="label" translatable="yes">New Event…</property>
<signal name="clicked" handler="new_event_button_clicked_cb" object="GcalMonthPopover" swapped="no" />
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
</template>
</interface>
+109
View File
@@ -0,0 +1,109 @@
using Gtk 4.0;
template $GcalMonthView: Widget {
overflow: hidden;
EventControllerScroll {
flags: vertical | kinetic;
scroll-begin => $on_scroll_controller_scroll_begin_cb(template) not-swapped;
scroll => $on_scroll_controller_scroll_cb(template) not-swapped;
scroll-end => $on_scroll_controller_scroll_end_cb(template) not-swapped;
decelerate => $on_scroll_controller_decelerate_cb(template) not-swapped;
}
EventControllerScroll {
flags: vertical | discrete;
scroll => $on_discrete_scroll_controller_scroll_cb(template) not-swapped;
}
GestureClick {
button: 1;
pressed => $on_click_gesture_pressed_cb(template) not-swapped;
released => $on_click_gesture_released_cb(template) not-swapped;
}
EventControllerMotion motion_controller {
propagation-phase: none;
motion => $on_motion_controller_motion_cb(template) not-swapped;
}
[header]
Box {
styles [
"month-header",
"view",
]
homogeneous: true;
Label label_0 {
margin-start: 6;
hexpand: true;
xalign: 0.0;
styles [
"header",
]
}
Label label_1 {
margin-start: 6;
hexpand: true;
xalign: 0.0;
styles [
"header",
]
}
Label label_2 {
margin-start: 6;
hexpand: true;
xalign: 0.0;
styles [
"header",
]
}
Label label_3 {
margin-start: 6;
hexpand: true;
xalign: 0.0;
styles [
"header",
]
}
Label label_4 {
margin-start: 6;
hexpand: true;
xalign: 0.0;
styles [
"header",
]
}
Label label_5 {
margin-start: 6;
hexpand: true;
xalign: 0.0;
styles [
"header",
]
}
Label label_6 {
margin-start: 6;
hexpand: true;
xalign: 0.0;
styles [
"header",
]
}
}
}
-126
View File
@@ -1,126 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GcalMonthView" parent="GtkWidget">
<property name="overflow">hidden</property>
<child>
<object class="GtkEventControllerScroll">
<property name="flags">vertical|kinetic</property>
<signal name="scroll-begin" handler="on_scroll_controller_scroll_begin_cb" object="GcalMonthView" swapped="no" />
<signal name="scroll" handler="on_scroll_controller_scroll_cb" object="GcalMonthView" swapped="no" />
<signal name="scroll-end" handler="on_scroll_controller_scroll_end_cb" object="GcalMonthView" swapped="no" />
<signal name="decelerate" handler="on_scroll_controller_decelerate_cb" object="GcalMonthView" swapped="no" />
</object>
</child>
<child>
<object class="GtkEventControllerScroll">
<property name="flags">vertical|discrete</property>
<signal name="scroll" handler="on_discrete_scroll_controller_scroll_cb" object="GcalMonthView" swapped="no" />
</object>
</child>
<child>
<object class="GtkGestureClick">
<property name="button">1</property>
<signal name="pressed" handler="on_click_gesture_pressed_cb" object="GcalMonthView" swapped="no" />
<signal name="released" handler="on_click_gesture_released_cb" object="GcalMonthView" swapped="no" />
</object>
</child>
<child>
<object class="GtkEventControllerMotion" id="motion_controller">
<property name="propagation-phase">none</property>
<signal name="motion" handler="on_motion_controller_motion_cb" object="GcalMonthView" swapped="no" />
</object>
</child>
<!-- Header -->
<child type="header">
<object class="GtkBox">
<style>
<class name="month-header" />
<class name="view" />
</style>
<property name="homogeneous">True</property>
<child>
<object class="GtkLabel" id="label_0">
<property name="margin-start">6</property>
<property name="hexpand">true</property>
<property name="xalign">0.0</property>
<style>
<class name="header" />
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="label_1">
<property name="margin-start">6</property>
<property name="hexpand">true</property>
<property name="xalign">0.0</property>
<style>
<class name="header" />
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="label_2">
<property name="margin-start">6</property>
<property name="hexpand">true</property>
<property name="xalign">0.0</property>
<style>
<class name="header" />
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="label_3">
<property name="margin-start">6</property>
<property name="hexpand">true</property>
<property name="xalign">0.0</property>
<style>
<class name="header" />
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="label_4">
<property name="margin-start">6</property>
<property name="hexpand">true</property>
<property name="xalign">0.0</property>
<style>
<class name="header" />
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="label_5">
<property name="margin-start">6</property>
<property name="hexpand">true</property>
<property name="xalign">0.0</property>
<style>
<class name="header" />
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="label_6">
<property name="margin-start">6</property>
<property name="hexpand">true</property>
<property name="xalign">0.0</property>
<style>
<class name="header" />
</style>
</object>
</child>
</object>
</child>
</template>
</interface>
+49
View File
@@ -0,0 +1,49 @@
using Gtk 4.0;
template $GcalWeekHeader: Widget {
Box main_box {
hexpand: true;
vexpand: false;
orientation: vertical;
styles [
"week-header",
]
Box {
orientation: vertical;
GestureClick {
button: 1;
pressed => $on_button_pressed(template) not-swapped;
released => $on_button_released(template) not-swapped;
}
EventControllerMotion motion_controller {
propagation-phase: none;
motion => $on_motion_notify(template) not-swapped;
}
Box weekdays_box {
homogeneous: true;
}
ScrolledWindow scrolledwindow {
hscrollbar-policy: never;
vscrollbar-policy: never;
propagate-natural-height: true;
margin-bottom: 2;
Viewport {
Grid grid {
column-homogeneous: true;
hexpand: true;
column-spacing: 6;
row-spacing: 2;
margin-start: 6;
}
}
}
}
}
}
-68
View File
@@ -1,68 +0,0 @@
<?xml version="1.0"?>
<interface>
<template class="GcalWeekHeader" parent="GtkWidget">
<child>
<object class="GtkBox" id="main_box">
<property name="hexpand">True</property>
<property name="vexpand">False</property>
<property name="orientation">vertical</property>
<style>
<class name="week-header" />
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<!-- Gestures -->
<child>
<object class="GtkGestureClick">
<property name="button">1</property>
<signal name="pressed" handler="on_button_pressed" object="GcalWeekHeader" swapped="no" />
<signal name="released" handler="on_button_released" object="GcalWeekHeader" swapped="no" />
</object>
</child>
<child>
<object class="GtkEventControllerMotion" id="motion_controller">
<property name="propagation-phase">none</property>
<signal name="motion" handler="on_motion_notify" object="GcalWeekHeader" swapped="no" />
</object>
</child>
<child>
<object class="GtkBox" id="weekdays_box">
<property name="homogeneous">True</property>
</object>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow">
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">never</property>
<property name="propagate-natural-height">True</property>
<property name="margin-bottom">2</property>
<child>
<object class="GtkViewport">
<child>
<object class="GtkGrid" id="grid">
<property name="column-homogeneous">True</property>
<property name="hexpand">True</property>
<property name="column-spacing">6</property>
<property name="row-spacing">2</property>
<property name="margin-start">6</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>
+89
View File
@@ -0,0 +1,89 @@
using Gtk 4.0;
template $GcalWeekView: Box {
orientation: vertical;
styles [
"week-view",
]
Box {
orientation: horizontal;
Box expand_button_box {
hexpand: false;
ToggleButton {
visible: bind header.can-expand;
active: bind header.expanded bidirectional;
hexpand: true;
halign: center;
valign: end;
margin-bottom: 6;
icon-name: "go-down-symbolic";
styles [
"flat",
"circular",
"week-header-expander",
]
}
}
$GcalWeekHeader header {
hexpand: true;
event-activated => $on_event_activated(template);
}
}
Separator {}
ScrolledWindow scrolled_window {
hexpand: true;
vexpand: true;
GestureZoom {
scale-changed => $on_zoom_gesture_scale_changed_cb(template) not-swapped;
begin => $on_zoom_gesture_begin_cb(template) not-swapped;
end => $on_zoom_gesture_end_cb(template) not-swapped;
}
EventControllerScroll {
propagation-phase: capture;
flags: vertical | kinetic;
scroll-begin => $on_scroll_controller_scroll_begin_cb(template) not-swapped;
scroll => $on_scroll_controller_scroll_cb(template) not-swapped;
scroll-end => $on_scroll_controller_scroll_end_cb(template) not-swapped;
}
EventControllerMotion {
propagation-phase: capture;
enter => $on_motion_controller_enter_cb(template) not-swapped;
motion => $on_motion_controller_motion_cb(template) not-swapped;
leave => $on_motion_controller_leave_cb(template) not-swapped;
}
Viewport {
Box content {
orientation: horizontal;
$GcalWeekHourBar hours_bar {}
$GcalWeekGrid week_grid {
hexpand: true;
vexpand: true;
event-activated => $on_event_activated(template);
}
}
}
}
}
SizeGroup sizegroup {
mode: horizontal;
widgets [
expand_button_box,
hours_bar,
]
}
-116
View File
@@ -1,116 +0,0 @@
<?xml version="1.0"?>
<interface>
<template class="GcalWeekView" parent="GtkBox">
<property name="orientation">vertical</property>
<style>
<class name="week-view" />
</style>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<!-- Expand / Collapse button -->
<child>
<object class="GtkBox" id="expand_button_box">
<property name="hexpand">False</property>
<child>
<object class="GtkToggleButton">
<property name="visible" bind-source="header" bind-property="can-expand" bind-flags="sync-create" />
<property name="active" bind-source="header" bind-property="expanded" bind-flags="sync-create|bidirectional" />
<property name="hexpand">True</property>
<property name="halign">center</property>
<property name="valign">end</property>
<property name="margin-bottom">6</property>
<property name="icon-name">go-down-symbolic</property>
<style>
<class name="flat" />
<class name="circular" />
<class name="week-header-expander" />
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GcalWeekHeader" id="header">
<property name="hexpand">True</property>
<signal name="event-activated" handler="on_event_activated" object="GcalWeekView" swapped="yes" />
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparator" />
</child>
<child>
<object class="GtkScrolledWindow" id="scrolled_window">
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<!-- Zoom Gesture -->
<child>
<object class="GtkGestureZoom">
<signal name="scale-changed" handler="on_zoom_gesture_scale_changed_cb" object="GcalWeekView" swapped="no" />
<signal name="begin" handler="on_zoom_gesture_begin_cb" object="GcalWeekView" swapped="no" />
<signal name="end" handler="on_zoom_gesture_end_cb" object="GcalWeekView" swapped="no" />
</object>
</child>
<!-- Scroll Event Controller -->
<child>
<object class="GtkEventControllerScroll">
<property name="propagation-phase">capture</property>
<property name="flags">vertical|kinetic</property>
<signal name="scroll-begin" handler="on_scroll_controller_scroll_begin_cb" object="GcalWeekView" swapped="no" />
<signal name="scroll" handler="on_scroll_controller_scroll_cb" object="GcalWeekView" swapped="no" />
<signal name="scroll-end" handler="on_scroll_controller_scroll_end_cb" object="GcalWeekView" swapped="no" />
</object>
</child>
<!-- Motion Event Controller -->
<child>
<object class="GtkEventControllerMotion">
<property name="propagation-phase">capture</property>
<signal name="enter" handler="on_motion_controller_enter_cb" object="GcalWeekView" swapped="no" />
<signal name="motion" handler="on_motion_controller_motion_cb" object="GcalWeekView" swapped="no" />
<signal name="leave" handler="on_motion_controller_leave_cb" object="GcalWeekView" swapped="no" />
</object>
</child>
<child>
<object class="GtkViewport">
<child>
<object class="GtkBox" id="content">
<property name="orientation">horizontal</property>
<child>
<object class="GcalWeekHourBar" id="hours_bar">
</object>
</child>
<child>
<object class="GcalWeekGrid" id="week_grid">
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<signal name="event-activated" handler="on_event_activated" object="GcalWeekView" swapped="yes" />
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
<object class="GtkSizeGroup" id="sizegroup">
<property name="mode">horizontal</property>
<widgets>
<widget name="expand_button_box" />
<widget name="hours_bar" />
</widgets>
</object>
</interface>
+21
View File
@@ -1,9 +1,30 @@
calendar_incs += include_directories('.')
blueprints = custom_target(
'blueprints',
input: files(
'gcal-agenda-view.blp',
'gcal-month-cell.blp',
'gcal-month-popover.blp',
'gcal-month-view.blp',
'gcal-week-header.blp',
'gcal-week-view.blp',
),
output: '.',
command: [
find_program('blueprint-compiler'),
'batch-compile',
'@OUTPUT@',
'@CURRENT_SOURCE_DIR@',
'@INPUT@',
],
)
built_sources += gnome.compile_resources(
'views-resources',
'views.gresource.xml',
c_name: 'views',
dependencies: blueprints,
)
sources += files(