Skip to content

Commit

Permalink
Provide Badge and Progress support for an Application (#288)
Browse files Browse the repository at this point in the history
  • Loading branch information
Corentin Noël authored and danirabbit committed Jul 8, 2019
1 parent 88d9fa5 commit bebf1ed
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 1 deletion.
2 changes: 2 additions & 0 deletions demo/GraniteDemo.vala
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public class Granite.Demo : Gtk.Application {
var welcome = new WelcomeView ();
var message_dialog_view = new MessageDialogView (window);
var async_image_view = new AsyncImageView ();
var application_view = new ApplicationView ();

var main_stack = new Gtk.Stack ();
main_stack.add_titled (welcome, "welcome", "Welcome");
Expand All @@ -67,6 +68,7 @@ public class Granite.Demo : Gtk.Application {
main_stack.add_titled (utils_view, "utils", "Utils");
main_stack.add_titled (message_dialog_view, "message", "MessageDialog");
main_stack.add_titled (async_image_view, "asyncimage", "AsyncImage");
main_stack.add_titled (application_view, "application", "Application");

var stack_sidebar = new Gtk.StackSidebar ();
stack_sidebar.stack = main_stack;
Expand Down
91 changes: 91 additions & 0 deletions demo/Views/ApplicationView.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright 2019 elementary, Inc. (https://elementary.io)
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*/

public class ApplicationView : Gtk.Grid {
construct {
var progress_visible_label = new Gtk.Label ("Show Progress:");

var progress_visible_switch = new Gtk.Switch ();
progress_visible_switch.valign = Gtk.Align.CENTER;

var progress_scale = new Gtk.Scale.with_range (Gtk.Orientation.HORIZONTAL, 0, 1, 0.05);

var badge_visible_label = new Gtk.Label ("Show Badge:");

var badge_visible_switch = new Gtk.Switch ();
badge_visible_switch.valign = Gtk.Align.CENTER;

var badge_spin = new Gtk.SpinButton.with_range (0, int64.MAX, 1);

column_spacing = 12;
row_spacing = 6;
orientation = Gtk.Orientation.VERTICAL;
halign = Gtk.Align.CENTER;
valign = Gtk.Align.CENTER;
attach (progress_visible_label, 0, 0);
attach (progress_visible_switch, 1, 0);
attach (progress_scale, 2, 0);
attach (badge_visible_label, 0, 1);
attach (badge_visible_switch, 1, 1);
attach (badge_spin, 2, 1);

progress_visible_switch.bind_property ("active", progress_scale, "sensitive", GLib.BindingFlags.SYNC_CREATE);
badge_visible_switch.bind_property ("active", badge_spin, "sensitive", GLib.BindingFlags.SYNC_CREATE);

progress_scale.value_changed.connect (() => {
Granite.Services.Application.set_progress.begin (progress_scale.get_value (), (obj, res) => {
try {
Granite.Services.Application.set_progress.end (res);
} catch (GLib.Error e) {
critical (e.message);
}
});
});

progress_visible_switch.notify["active"].connect (() => {
Granite.Services.Application.set_progress_visible.begin (progress_visible_switch.active, (obj, res) => {
try {
Granite.Services.Application.set_progress_visible.end (res);
} catch (GLib.Error e) {
critical (e.message);
}
});
});

badge_spin.value_changed.connect (() => {
Granite.Services.Application.set_badge.begin ((int64)badge_spin.value, (obj, res) => {
try {
Granite.Services.Application.set_badge.end (res);
} catch (GLib.Error e) {
critical (e.message);
}
});
});

badge_visible_switch.notify["active"].connect (() => {
Granite.Services.Application.set_badge_visible.begin (badge_visible_switch.active, (obj, res) => {
try {
Granite.Services.Application.set_badge_visible.end (res);
} catch (GLib.Error e) {
critical (e.message);
}
});
});
}
}
File renamed without changes.
3 changes: 2 additions & 1 deletion demo/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ executable(
'GraniteDemo.vala',

'Views/AlertViewView.vala',
'Views/ApplicationView.vala',
'Views/AsyncImageView.vala',
'Views/AvatarView.vala',
'Views/CSSView.vala',
Expand Down Expand Up @@ -34,7 +35,7 @@ applications_dir = join_paths(
)

install_data(
'granite-demo.desktop',
'io.elementary.granite.demo.desktop',
install_dir: applications_dir
)

124 changes: 124 additions & 0 deletions lib/Services/Application.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright 2019 elementary, Inc. (https://elementary.io)
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*/

[CCode (gir_namespace = "GraniteServices", gir_version = "1.0")]
namespace Granite.Services {
/**
* Utilities for Applications
*/
namespace Application {
[DBus (name = "com.canonical.Unity.LauncherEntry")]
private class UnityLauncherEntry : GLib.Object {
private static UnityLauncherEntry instance;
internal static async unowned UnityLauncherEntry get_instance () throws GLib.Error {
lock (instance) {
if (instance != null)
return instance;

weak GLib.Application app = GLib.Application.get_default ();
if (app == null) {
throw new GLib.IOError.FAILED ("No GApplication has been defined");
}

if (app.application_id == null) {
throw new GLib.IOError.FAILED ("The GApplication has no application-id defined");
}

var local_instance = new UnityLauncherEntry ();
local_instance.app_uri = "application://%s.desktop".printf (app.application_id);
var object_path = new GLib.ObjectPath ("/com/canonical/unity/launcherentry/%u".printf (local_instance.app_uri.hash ()));
try {
var session_connection = yield GLib.Bus.@get (GLib.BusType.SESSION, null);
session_connection.register_object (object_path, local_instance);
instance = local_instance;
} catch (GLib.Error e) {
throw e;
}
}

return instance;
}

construct {
properties = new GLib.HashTable<string,GLib.Variant> (str_hash, str_equal);
properties["urgent"] = new GLib.Variant.boolean (false);
properties["count"] = new GLib.Variant.int64 (0);
properties["count-visible"] = new GLib.Variant.boolean (false);
properties["progress"] = new GLib.Variant.double (0.0);
properties["progress-visible"] = new GLib.Variant.boolean (false);
}

private string app_uri;
private GLib.HashTable<string,GLib.Variant> properties;

internal void set_app_property (string property, GLib.Variant var) {
var updated_properties = new GLib.HashTable<string,GLib.Variant> (str_hash, str_equal);
updated_properties[property] = var;
properties[property] = var;
update (app_uri, updated_properties);
}

public signal void update (string app_uri, GLib.HashTable<string,GLib.Variant> properties);

public GLib.HashTable<string,Variant> query () throws GLib.Error {
return properties;
}
}

/**
* Set the badge count, usually visible with the dock in the desktop. There is no guarantee
* that the target environment supports it in any way.
* For it to be visible, one has to make sure to call set_badge_visible().
*/
public static async bool set_badge (int64 count) throws GLib.Error {
unowned UnityLauncherEntry instance = yield UnityLauncherEntry.get_instance ();
instance.set_app_property ("count", new GLib.Variant.int64 (count));
return true;
}

/**
* Set the badge visibility.
*/
public static async bool set_badge_visible (bool visible) throws GLib.Error {
unowned UnityLauncherEntry instance = yield UnityLauncherEntry.get_instance ();
instance.set_app_property ("count-visible", new GLib.Variant.boolean (visible));
return true;
}

/**
* Set the progress of the application, usually visible with the dock in the desktop.
* There is no guarantee that the target environment supports it in any way.
* For it to be visible, one has to make sure to call set_progress_visible().
*/
public static async bool set_progress (double progress) throws GLib.Error {
unowned UnityLauncherEntry instance = yield UnityLauncherEntry.get_instance ();
instance.set_app_property ("progress", new GLib.Variant.double (progress));
return true;
}

/**
* Set the progress visibility.
*/
public static async bool set_progress_visible (bool visible) throws GLib.Error {
unowned UnityLauncherEntry instance = yield UnityLauncherEntry.get_instance ();
instance.set_app_property ("progress-visible", new GLib.Variant.boolean (visible));
return true;
}
}
}
1 change: 1 addition & 0 deletions lib/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ libgranite_sources = files(

'GtkPatch/AboutDialog.vala',

'Services/Application.vala',
'Services/ContractorProxy.vala',
'Services/IconFactory.vala',
'Services/Logger.vala',
Expand Down

0 comments on commit bebf1ed

Please sign in to comment.