From 7f9fc92c6f6327c62202ebb881f728131b7ec3b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Iv=C3=A1n?= Date: Tue, 8 Aug 2023 10:31:19 -0600 Subject: [PATCH 1/4] library: Port Wallpaper and Screenshot demos to Vala --- src/Library/demos/Screenshot/main.vala | 37 ++++++++++++++++++++++++++ src/Library/demos/Wallpaper/main.vala | 33 +++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 src/Library/demos/Screenshot/main.vala create mode 100644 src/Library/demos/Wallpaper/main.vala diff --git a/src/Library/demos/Screenshot/main.vala b/src/Library/demos/Screenshot/main.vala new file mode 100644 index 000000000..6cb7d6c4e --- /dev/null +++ b/src/Library/demos/Screenshot/main.vala @@ -0,0 +1,37 @@ +#!/usr/bin/env -S vala workbench.vala --pkg libadwaita-1 --pkg libportal-gtk4 + +private Xdp.Portal portal; +private Xdp.Parent parent; +private Gtk.Picture picture; + +public void main () { + portal = new Xdp.Portal (); + parent = Xdp.parent_new_gtk (workbench.window); + picture = (Gtk.Picture) workbench.builder.get_object ("picture"); + + var button = (Gtk.Button) workbench.builder.get_object ("button"); + button.clicked.connect (on_button_clicked); +} + +private async void on_button_clicked () { + try { + string uri = yield portal.take_screenshot (parent, NONE, null); + picture.file = File.new_for_uri (uri); + } catch (Error e) { + show_permission_error (); + } +} + +private void show_permission_error () { + var dialog = new Adw.MessageDialog ( + workbench.window, + "Permission Error", + "Ensure Screenshot permission is enabled in\nSettings → Apps → Workbench" + ) { + close_response = "ok", + modal = true, + }; + + dialog.add_response ("ok", "OK"); + dialog.present (); +} diff --git a/src/Library/demos/Wallpaper/main.vala b/src/Library/demos/Wallpaper/main.vala new file mode 100644 index 000000000..dd7e610cf --- /dev/null +++ b/src/Library/demos/Wallpaper/main.vala @@ -0,0 +1,33 @@ +#!/usr/bin/env -S vala workbench.vala --pkg libadwaita-1 --pkg libportal-gtk4 + +private Xdp.Portal portal; +private Xdp.Parent parent; +private string image_uri; + +public void main () { + portal = new Xdp.Portal (); + parent = Xdp.parent_new_gtk (workbench.window); + image_uri = workbench.resolve ("./wallpaper.png"); + + var button = (Gtk.Button) workbench.builder.get_object ("button"); + button.clicked.connect (on_button_clicked); +} + +private async void on_button_clicked () { + try { + bool success = yield portal.set_wallpaper ( + parent, + image_uri, + PREVIEW | BACKGROUND | LOCKSCREEN, + null + ); + + if (success) { + message ("Wallpaper set successfully"); + return; + } + message ("Could not set wallpaper"); + } catch (Error e) { + critical (e.message); + } +} From f1a8032a01216213baf48bdd9f0e325ae54377f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Iv=C3=A1n?= Date: Wed, 9 Aug 2023 15:34:52 -0600 Subject: [PATCH 2/4] library: Port Account and Color Picker demos to Vala --- src/Library/demos/Account/main.vala | 54 ++++++++++++++++++++++++ src/Library/demos/Color Picker/main.vala | 36 ++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 src/Library/demos/Account/main.vala create mode 100644 src/Library/demos/Color Picker/main.vala diff --git a/src/Library/demos/Account/main.vala b/src/Library/demos/Account/main.vala new file mode 100644 index 000000000..b1e1cfcf8 --- /dev/null +++ b/src/Library/demos/Account/main.vala @@ -0,0 +1,54 @@ +#!/usr/bin/env -S vala workbench.vala --pkg libadwaita-1 --pkg libportal-gtk4 + +private Gtk.Revealer revealer; +private Adw.EntryRow entry; +private Adw.Avatar avatar; +private Gtk.Label username; +private Gtk.Label display; +private Xdp.Portal portal; +private Xdp.Parent parent; + +public void main () { + portal = new Xdp.Portal (); + parent = Xdp.parent_new_gtk (workbench.window); + + revealer = (Gtk.Revealer) workbench.builder.get_object ("revealer"); + entry = (Adw.EntryRow) workbench.builder.get_object ("entry"); + avatar = (Adw.Avatar) workbench.builder.get_object ("avatar"); + username = (Gtk.Label) workbench.builder.get_object ("username"); + display = (Gtk.Label) workbench.builder.get_object ("name"); + + var button = (Gtk.Button) workbench.builder.get_object ("button"); + button.clicked.connect (on_button_clicked); +} + +private async void on_button_clicked () { + try { + string reason = entry.text; + Variant result = yield portal.get_user_information (parent, reason, NONE, null); + + /* + * result is a Variant dictionary containing the following fields: + * id (s): the user id + * name (s): the users real name + * image (s): the uri of an image file for the users avatar picture + */ + + var id = (string) result.lookup_value ("id", VariantType.STRING); + var name = (string) result.lookup_value ("name", VariantType.STRING); + var uri = (string) result.lookup_value ("image", VariantType.STRING); + + var file = File.new_for_uri (uri); + var texture = Gdk.Texture.from_file (file); + + username.label = id; + display.label = name; + avatar.custom_image = texture; + revealer.reveal_child = true; + + entry.text = ""; + message ("Information Retrieved"); + } catch (Error e) { + critical (e.message); + } +} diff --git a/src/Library/demos/Color Picker/main.vala b/src/Library/demos/Color Picker/main.vala new file mode 100644 index 000000000..7663a5174 --- /dev/null +++ b/src/Library/demos/Color Picker/main.vala @@ -0,0 +1,36 @@ +#!/usr/bin/env -S vala workbench.vala --pkg libadwaita-1 --pkg libportal-gtk4 + +private Xdp.Portal portal; +private Xdp.Parent parent; + +public void main () { + portal = new Xdp.Portal (); + parent = Xdp.parent_new_gtk (workbench.window); + + var button = (Gtk.Button) workbench.builder.get_object ("button"); + button.clicked.connect (on_button_clicked); +} + +private async void on_button_clicked () { + try { + // result is a variant of the form (ddd), containing red green and blue components in the range [0,1] + Variant result = yield portal.pick_color (parent, null); + + double r, g, b; + VariantIter iter = result.iterator (); // Iterate over the array in the variant + iter.next ("d", out r); + iter.next ("d", out g); + iter.next ("d", out b); + + var color = Gdk.RGBA () { + red = (float) r, + green = (float) g, + blue = (float) b, + alpha = 1.0f + }; + + message (@"Selected color is $color"); + } catch (Error e) { + critical (e.message); + } +} From 4a7ecdea6a5029d5adea9f73f4b6347b175a41e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Iv=C3=A1n?= Date: Wed, 9 Aug 2023 15:44:59 -0600 Subject: [PATCH 3/4] library: Port Email demo to Vala --- src/Library/demos/Email/main.vala | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/Library/demos/Email/main.vala diff --git a/src/Library/demos/Email/main.vala b/src/Library/demos/Email/main.vala new file mode 100644 index 000000000..a4624c526 --- /dev/null +++ b/src/Library/demos/Email/main.vala @@ -0,0 +1,40 @@ +#!/usr/bin/env -S vala workbench.vala --pkg libadwaita-1 --pkg libportal-gtk4 + +private Xdp.Portal portal; +private Xdp.Parent parent; +private Gtk.Entry entry; + +public void main () { + portal = new Xdp.Portal (); + parent = Xdp.parent_new_gtk (workbench.window); + + entry = (Gtk.Entry) workbench.builder.get_object ("entry"); + var button = (Gtk.Button) workbench.builder.get_object ("button"); + button.clicked.connect (on_button_clicked); +} + +private async void on_button_clicked () { + string email_address = entry.text; + + try { + bool success = yield portal.compose_email ( + parent, + { email_address }, // addresses + null, // cc + null, // bcc + "Email from Workbench", // subject + "Hello World!", // body + null, + NONE, + null + ); + + if (success) { + message ("Success"); + return; + } + message ("Failure: verify that you have an email application."); + } catch (Error e) { + critical (e.message); + } +} From 764fd8c1cd97236da0eb438fe0da32d539f20394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Iv=C3=A1n?= Date: Wed, 9 Aug 2023 22:05:14 -0600 Subject: [PATCH 4/4] library: Port Location demo to Vala --- src/Library/demos/Location/main.vala | 125 +++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/Library/demos/Location/main.vala diff --git a/src/Library/demos/Location/main.vala b/src/Library/demos/Location/main.vala new file mode 100644 index 000000000..34a0ebe32 --- /dev/null +++ b/src/Library/demos/Location/main.vala @@ -0,0 +1,125 @@ +#!/usr/bin/env -S vala workbench.vala --pkg libadwaita-1 --pkg libportal-gtk4 + +private Xdp.Portal portal; +private Xdp.Parent parent; + +private Gtk.Revealer revealer; +private Gtk.Button start_button; +private Gtk.Button close_button; +private Gtk.SpinButton distance_threshold; +private Gtk.SpinButton time_threshold; +private Adw.ComboRow accuracy_button; + +private Gtk.Label latitude_label; +private Gtk.Label longitude_label; +private Gtk.Label accuracy_label; +private Gtk.Label altitude_label; +private Gtk.Label speed_label; +private Gtk.Label heading_label; +private Gtk.Label description_label; +private Gtk.Label timestamp_label; + +public void main () { + portal = new Xdp.Portal (); + parent = Xdp.parent_new_gtk (workbench.window); + + revealer = (Gtk.Revealer) workbench.builder.get_object ("revealer"); + start_button = (Gtk.Button) workbench.builder.get_object ("start"); + close_button = (Gtk.Button) workbench.builder.get_object ("close"); + distance_threshold = (Gtk.SpinButton) workbench.builder.get_object ("distance_threshold"); + time_threshold = (Gtk.SpinButton) workbench.builder.get_object ("time_threshold"); + accuracy_button = (Adw.ComboRow) workbench.builder.get_object ("accuracy_button"); + + latitude_label = (Gtk.Label) workbench.builder.get_object ("latitude"); + longitude_label = (Gtk.Label) workbench.builder.get_object ("longitude"); + accuracy_label = (Gtk.Label) workbench.builder.get_object ("accuracy"); + altitude_label = (Gtk.Label) workbench.builder.get_object ("altitude"); + speed_label = (Gtk.Label) workbench.builder.get_object ("speed"); + heading_label = (Gtk.Label) workbench.builder.get_object ("heading"); + description_label = (Gtk.Label) workbench.builder.get_object ("description"); + timestamp_label = (Gtk.Label) workbench.builder.get_object ("timestamp"); + + start_button.clicked.connect (start_session); + close_button.clicked.connect (close_session); + + time_threshold.value_changed.connect (() => { + message ("Time threshold changed"); + restart_session (); + }); + + distance_threshold.value_changed.connect (() => { + message ("Distance threshold changed"); + restart_session (); + }); + + accuracy_button.notify["selected-item"].connect (() => { + message ("Accuracy changed"); + restart_session (); + }); + + portal.location_updated.connect (on_location_updated); +} + +private void on_location_updated ( + double latitude, + double longitude, + double altitude, + double accuracy, + double speed, + double heading, + string description, + int64 timestamp_seconds, + int64 timestamp_ms +) { + message ("Location updated"); + latitude_label.label = latitude.to_string (); + longitude_label.label = longitude.to_string (); + accuracy_label.label = accuracy.to_string (); + altitude_label.label = altitude.to_string (); + speed_label.label = speed.to_string (); + heading_label.label = heading.to_string (); + description_label.label = description; + + // Convert UNIX timestamp to local date and time string + var timestamp = new DateTime.from_unix_local (timestamp_ms); + timestamp_label.label = timestamp.to_string (); +} + +private void restart_session () { + portal.location_monitor_stop (); + revealer.reveal_child = false; + start_session.begin (); +} + +private async void start_session () { + start_button.sensitive = false; + close_button.sensitive = true; + + try { + bool result = yield portal.location_monitor_start ( + parent, + (uint) distance_threshold.value, + (uint) time_threshold.value, + (Xdp.LocationAccuracy) accuracy_button.selected, + NONE, + null + ); + + if (result) { + message ("Location access granted"); + revealer.reveal_child = true; + return; + } + message ("Error retrieving location"); + } catch (Error e) { + critical (e.message); + } +} + +private void close_session () { + start_button.sensitive = false; + close_button.sensitive = false; + portal.location_monitor_stop (); + revealer.reveal_child = false; + message ("Session Closed"); +}