Skip to content
Draft
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
33 changes: 33 additions & 0 deletions src/AccountChooser/AccountButton.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* SPDX-FileCopyrigthText: 2021 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

public class AccountChooser.AccountButton : Gtk.Button {
public string account_id { get; construct; }

public AccountButton (string account_id) {
Object (account_id: account_id);
}

construct {
get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);

var name = new Gtk.Label (account_id) {
halign = Gtk.Align.CENTER,
justify = Gtk.Justification.CENTER,
lines = 2,
max_width_chars = 16,
width_chars = 16,
wrap_mode = Pango.WrapMode.WORD_CHAR
};
name.set_ellipsize (Pango.EllipsizeMode.END);

var grid = new Gtk.Box (Gtk.Orientation.VERTICAL, 6) {
halign = Gtk.Align.CENTER
};
grid.add (name);

add (grid);
}
}
125 changes: 125 additions & 0 deletions src/AccountChooser/Dialog.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* SPDX-FileCopyrigthText: 2021 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

[DBus (name = "org.freedesktop.impl.portal.Request")]
public class AccountChooser.Dialog : Hdy.Window {
public string app_id { get; construct; }
private DBusConnection connection;
private uint register_id;

private HashTable<string, AccountButton> buttons;
private AccountButton selected;

private Hdy.Carousel carousel;
private weak Gtk.Box last_box;

public signal void choiced (string account_id);

public Dialog (DBusConnection conn, ObjectPath handle, string app_id, string parent_window) {
Object (app_id: app_id, default_width: 700, resizable: false);
connection = conn;

try {
register_id = connection.register_object<Dialog> (handle, this);
} catch (Error e) {
critical (e.message);
}

realize ();

if (parent_window != "") {
var parent = ExternalWindow.from_handle (parent_window);

if (parent == null) {
warning ("Failed to associate portal window with parent window %s", parent_window);
} else {
parent.set_parent_of (get_window ());
}
}
}

construct {
buttons = new HashTable<string, AccountButton> (str_hash, str_equal);
AppInfo? info = app_id == "" ? null : new DesktopAppInfo (app_id + ".desktop");
Hdy.init ();

var handle = new Hdy.WindowHandle ();

var cancel = new Gtk.Button.with_label ("Cancel");
var select = new Gtk.Button.with_label ("Select");
select.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);

var button_box = new Gtk.ButtonBox (Gtk.Orientation.HORIZONTAL) {
layout_style = Gtk.ButtonBoxStyle.END,
valign = Gtk.Align.END,
margin_top = 12,
expand = true,
spacing = 6
};

button_box.add (cancel);
button_box.add (select);

var grid = new Gtk.Grid () {
orientation = Gtk.Orientation.VERTICAL,
column_spacing = 12,
row_spacing = 6,
margin = 12
};

grid.attach (button_box, 0, 0);

handle.add (grid);
add (handle);

select.clicked.connect (() => choiced (selected.account_id));
cancel.clicked.connect (() => choiced (""));

// close the dialog after a selection;
choiced.connect_after (() => destroy ());

destroy.connect (() => {
if (register_id != 0) {
connection.unregister_object (register_id);
register_id = 0;
}
});

create_box ();
}

private void create_box () {
var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
box.add.connect_after (() => {
if (box.get_children ().length () == 5) {
create_box ();
}
});

carousel.insert (box, -1);
last_box = box;
}

private void add_choice (string choice) {
var button = new AccountButton (choice);
button.clicked.connect (() => { selected = button; });
buttons[choice] = button;
last_box.add (button);
}

[DBus (visible = false)]
public void update_choices (string[] choices) {
foreach (var choice in choices) {
if (!(choice in buttons)) {
add_choice (choice);
}
}
}

[DBus (name = "Close")]
public void on_close () throws DBusError, IOError {
destroy ();
}
}
68 changes: 68 additions & 0 deletions src/AccountChooser/Portal.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* SPDX-FileCopyrigthText: 2021 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

[DBus (name = "org.freedesktop.impl.portal.AccountChooser")]
public class AccountChooser.Portal : Object {
private HashTable<ObjectPath, Dialog> handles;
private DBusConnection connection;

public Portal (DBusConnection connection) {
handles = new HashTable<ObjectPath, Dialog> (str_hash, str_equal);
this.connection = connection;
}

public async void choose_application (
ObjectPath handle,
string app_id,
string parent_window,
string[] choices,
HashTable<string, Variant> options,
out uint response,
out HashTable<string, Variant> results
) throws DBusError, IOError {
var dialog = new Dialog (connection, handle, app_id, parent_window);

/*if ("last_choice" in options && options["last_choice"].is_of_type (VariantType.STRING)) {
dialog.last_choice = options["last_choice"].get_string ();
} if ("modal" in options && options["modal"].is_of_type (VariantType.BOOLEAN)) {
dialog.modal = options["modal"].get_boolean ();
} if ("content_type" in options && options["content_type"].is_of_type (VariantType.STRING)) {
dialog.content_type = options["content_type"].get_string ();
} if ("filename" in options && options["filename"].is_of_type (VariantType.STRING)) {
dialog.filename = options["filename"].get_string ();
}

dialog.update_choices (choices);
var _results = new HashTable<string, Variant> (str_hash, str_equal);
uint _response = 2;

var destroy_id = dialog.destroy.connect_after (() => {
_results["choice"] = "";
choose_application.callback ();
});

dialog.choiced.connect ((app_id) => {
dialog.disconnect (destroy_id);

_results["choice"] = app_id.replace (".desktop", "");
_response = app_id == "" ? 1 : 0;

choose_application.callback ();
});*/

handles[handle] = dialog;
dialog.show_all ();
yield;

//results = _results;
//response = _response;
}

/*public async void update_choices (ObjectPath handle, string[] choices) throws DBusError, IOError {
if (handle in handles) {
handles[handle].update_choices (choices);
}
}*/
}
3 changes: 3 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ executable(
'ExternalWindow.vala',
'Access/Portal.vala',
'Access/Dialog.vala',
'AccountChooser/Portal.vala',
'AccountChooser/Dialog.vala',
'AccountChooser/AccountButton.vala',
'AppChooser/Portal.vala',
'AppChooser/Dialog.vala',
'AppChooser/AppButton.vala',
Expand Down