Merge lp:~artem-anufrij/webby-browser/welcome-screen-and-about-dialog into lp:webby-browser

Proposed by Artem Anufrij on 2015-10-13
Status: Merged
Approved by: Erasmo Marín on 2015-10-16
Approved revision: 17
Merged at revision: 15
Proposed branch: lp:~artem-anufrij/webby-browser/welcome-screen-and-about-dialog
Merge into: lp:webby-browser
Diff against target: 698 lines (+348/-251)
7 files modified
CMakeLists.txt (+2/-1)
data/webby.desktop (+5/-0)
src/AppWindow.vala (+124/-27)
src/ApplicationsView.vala (+0/-220)
src/Webby.vala (+2/-3)
src/Widgets/ApplicationIcon.vala (+129/-0)
src/Widgets/ApplicationsView.vala (+86/-0)
To merge this branch: bzr merge lp:~artem-anufrij/webby-browser/welcome-screen-and-about-dialog
Reviewer Review Type Date Requested Status
Erasmo Marín 2015-10-13 Pending
Review via email: mp+274318@code.launchpad.net

Commit message

new fetures:
- Welcome screen
- About dialog
- Run a Web App on double click

Description of the change

new fetures:
- Welcome screen
- About dialog

Double click for run WebApp

To post a comment you must log in.
16. By Artem Anufrij on 2015-10-13

double click for open/run selected app

Erasmo Marín (erasmo-marin) wrote :

This is great! Just some little fixes:

1.- Add my email in about dialog <email address hidden>
2.- Add a tooltip to the "add" button

That's all, thanks!

17. By Artem Anufrij on 2015-10-16

added email and tooltip

Artem Anufrij (artem-anufrij) wrote :

done :)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-03-23 18:07:08 +0000
3+++ CMakeLists.txt 2015-10-16 13:27:49 +0000
4@@ -108,7 +108,8 @@
5
6
7 set(SRC_FILES
8- src/ApplicationsView.vala
9+ src/Widgets/ApplicationIcon.vala
10+ src/Widgets/ApplicationsView.vala
11 src/AppWindow.vala
12 src/Assistant.vala
13 src/DesktopFile.vala
14
15=== modified file 'data/webby.desktop'
16--- data/webby.desktop 2015-02-24 05:12:05 +0000
17+++ data/webby.desktop 2015-10-16 13:27:49 +0000
18@@ -13,3 +13,8 @@
19 X-GNOME-Gettext-Domain=webby
20 X-GNOME-FullName=Webby
21 StartupWMClass=Webby
22+Actions=AboutDialog;
23+
24+[Desktop Action AboutDialog]
25+Exec=webby --about
26+Name=About Webby
27
28=== modified file 'src/AppWindow.vala'
29--- src/AppWindow.vala 2015-10-12 21:53:39 +0000
30+++ src/AppWindow.vala 2015-10-16 13:27:49 +0000
31@@ -1,35 +1,97 @@
32-public class AppWindow : Gtk.ApplicationWindow {
33+public class AppWindow : Granite.Application {
34+
35+ public Gtk.Window mainwindow;
36
37 private Gtk.Stack stack;
38 private Gtk.HeaderBar headerbar;
39 private Gtk.Button back_button;
40+ private Gtk.Button add_button;
41
42 private WebbyAssistant assistant;
43-
44- public AppWindow () {
45-
46- set_default_size (700, 500);
47- set_wmclass("Webby", "Webby");
48+ private ApplicationsView apps_view;
49+
50+ construct {
51+ program_name = "Webby";
52+ exec_name = "webby";
53+
54+ app_years = "2015";
55+ app_icon = "webby";
56+ app_launcher = "webby.desktop";
57+ application_id = "net.launchpad.webby-browser";
58+
59+ main_url = "https://code.launchpad.net/webby-browser";
60+ bug_url = "https://bugs.launchpad.net/webby-browser";
61+ help_url = "https://code.launchpad.net/webby-browser";
62+ translate_url = "https://translations.launchpad.net/webby-browser";
63+
64+ about_authors = {"Erasmo Marín <erasmo.marin@gmail.com>",
65+ "Artem Anufrij <artem.anufrij@live.de>"};
66+ about_documenters = {"Erasmo Marín",
67+ "Artem Anufrij <artem.anufrij@live.de>"};
68+ about_artists = {"Erasmo Marín <erasmo.marin@gmail.com>",
69+ "Artem Anufrij <artem.anufrij@live.de>"};
70+ about_comments = "Development release, not all features implemented";
71+ about_translators = "";
72+ about_license_type = Gtk.License.GPL_3_0;
73+ }
74+
75+ public static AppWindow _instance = null;
76+
77+ public static AppWindow instance {
78+ get {
79+ if (_instance == null)
80+ _instance = new AppWindow ();
81+ return _instance;
82+ }
83+ }
84+
85+ protected override void activate () {
86+
87+ if (mainwindow != null) {
88+ mainwindow.present (); // present window if app is already running
89+ return;
90+ }
91+
92+ mainwindow = new Gtk.Window ();
93+
94+ mainwindow.set_default_size (700, 500);
95+ mainwindow.set_wmclass ("Webby", "Webby");
96
97 //headerbar
98 headerbar = new Gtk.HeaderBar ();
99 headerbar.show_close_button = true;
100 headerbar.title = "Webby";
101- this.set_titlebar (headerbar);
102-
103- back_button = new Gtk.Button.with_label(_("Applications"));
104- back_button.get_style_context().add_class("back-button");
105-
106- var apps_view = new ApplicationsView();
107+ mainwindow.set_titlebar (headerbar);
108+
109+ back_button = new Gtk.Button.with_label (_("Applications"));
110+ back_button.get_style_context ().add_class ("back-button");
111+ headerbar.pack_start (back_button);
112+
113+ add_button = new Gtk.Button ();
114+ add_button.image = new Gtk.Image.from_icon_name ("add", Gtk.IconSize.LARGE_TOOLBAR);
115+ add_button.tooltip_text = _("Add a new Web App");
116+ headerbar.pack_start (add_button);
117+
118+ var welcome = new Granite.Widgets.Welcome (_("No Web Apps Availible"), _("Create a new Webby Web App."));
119+ welcome.append ("add", _("Create App"), _("Create a new Webby web app."));
120+ welcome.activated.connect ((index) => {
121+ switch (index) {
122+ case 0:
123+ show_assistant ();
124+ break;
125+ }
126+ });
127+
128+ apps_view = new ApplicationsView();
129 assistant = new WebbyAssistant();
130 stack = new Gtk.Stack ();
131 stack.set_transition_duration (500);
132
133+ stack.add_named (welcome, "welcome");
134 stack.add_named (apps_view, "apps_view");
135 stack.add_named (assistant, "assistant");
136- stack.set_visible_child_name("apps_view");
137
138- add (stack);
139+ mainwindow.add (stack);
140
141 apps_view.add_request.connect (() => {
142 show_assistant ();
143@@ -39,40 +101,75 @@
144 show_assistant (desktop_file);
145 });
146
147+ apps_view.app_deleted.connect (() => {
148+ if (!apps_view.has_items) {
149+ show_welcome_view (Gtk.StackTransitionType.NONE);
150+ }
151+ });
152+
153 assistant.application_created.connect ((new_file) => {
154- show_apps_view ();
155 apps_view.add_button (new_file);
156 apps_view.select_last_item ();
157+ show_apps_view ();
158 });
159
160 assistant.application_edited.connect ((edited_file) => {
161- show_apps_view ();
162 apps_view.update_button (edited_file);
163+ show_apps_view ();
164 });
165
166 back_button.clicked.connect (() => {
167- show_apps_view ();
168- });
169-
170- this.destroy.connect (Gtk.main_quit);
171+ if (apps_view.has_items)
172+ show_apps_view ();
173+ else
174+ show_welcome_view ();
175+ });
176+
177+ add_button.clicked.connect (() => {
178+ show_assistant ();
179+ });
180+
181+ mainwindow.destroy.connect (Gtk.main_quit);
182+
183+ mainwindow.show_all ();
184+
185+ if (apps_view.has_items)
186+ show_apps_view (Gtk.StackTransitionType.NONE);
187+ else
188+ show_welcome_view (Gtk.StackTransitionType.NONE);
189+
190+ Gtk.main ();
191 }
192
193 private void show_assistant (DesktopFile? desktop_file = null) {
194 stack.set_transition_type (Gtk.StackTransitionType.SLIDE_LEFT);
195 stack.set_visible_child_name("assistant");
196- headerbar.pack_start (back_button);
197 back_button.show_all ();
198+ add_button.hide ();
199 //fix ugly border at the bottom of headerbar
200- queue_draw ();
201+ mainwindow.queue_draw ();
202
203 if (desktop_file != null)
204 assistant.edit_desktop_file (desktop_file);
205 }
206
207- private void show_apps_view () {
208- stack.set_transition_type (Gtk.StackTransitionType.SLIDE_RIGHT);
209- stack.set_visible_child_name("apps_view");
210- headerbar.remove (back_button);
211- assistant.reset_fields ();
212+ private void show_apps_view (Gtk.StackTransitionType slide = Gtk.StackTransitionType.SLIDE_RIGHT) {
213+ stack.set_transition_type (slide);
214+ stack.set_visible_child_name ("apps_view");
215+ back_button.hide ();
216+ add_button.show_all ();
217+ assistant.reset_fields ();
218+ //fix ugly border at the bottom of headerbar
219+ mainwindow.queue_draw ();
220+ }
221+
222+ private void show_welcome_view (Gtk.StackTransitionType slide = Gtk.StackTransitionType.SLIDE_RIGHT) {
223+ stack.set_transition_type (slide);
224+ stack.set_visible_child_name ("welcome");
225+ back_button.hide ();
226+ add_button.hide ();
227+ assistant.reset_fields ();
228+ //fix ugly border at the bottom of headerbar
229+ mainwindow.queue_draw ();
230 }
231 }
232
233=== removed file 'src/ApplicationsView.vala'
234--- src/ApplicationsView.vala 2015-10-12 21:53:39 +0000
235+++ src/ApplicationsView.vala 1970-01-01 00:00:00 +0000
236@@ -1,220 +0,0 @@
237-public class ApplicationsView : Gtk.Box {
238-
239- public signal void add_request();
240- public signal void edit_request(DesktopFile desktop_file);
241-
242- private Gtk.FlowBox icon_view;
243- private Gee.HashMap<string, GLib.DesktopAppInfo> applications;
244-
245- public ApplicationsView () {
246-
247- GLib.Object (orientation: Gtk.Orientation.VERTICAL);
248- var scrolled = new Gtk.ScrolledWindow (null, null);
249- scrolled.hscrollbar_policy = Gtk.PolicyType.NEVER;
250-
251- icon_view = new Gtk.FlowBox();
252- icon_view.valign = Gtk.Align.START;
253- icon_view.vexpand = false;
254- icon_view.homogeneous = true;
255- icon_view.column_spacing = 15;
256- icon_view.row_spacing = 15;
257- icon_view.margin = 15;
258-
259- load_applications ();
260-
261- scrolled.add(icon_view);
262- this.pack_start(scrolled, true, true, 0);
263-
264- }
265-
266- public void load_applications () {
267-
268- var add_button = new Gtk.Button ();
269- var add_image = new Gtk.Image();
270- add_image.icon_name = "add";
271- add_image.pixel_size = 64;
272- add_button.set_image(add_image);
273- add_button.get_style_context ().remove_class ("button");
274- add_button.get_style_context ().add_class ("titlebutton");
275- icon_view.add (add_button);
276-
277- add_button.clicked.connect (()=>{
278- add_request();
279- });
280-
281- applications = DesktopFile.get_webby_applications();
282-
283- foreach (GLib.DesktopAppInfo app in applications.values) {
284- this.add_button (app);
285- }
286-
287- this.show_all();
288- }
289-
290- public void add_button (GLib.DesktopAppInfo app) {
291- var image = new ApplicationIcon (app);
292- image.edit_request.connect ((desktop_file) => {
293- edit_request (desktop_file);
294- icon_view.unselect_all ();
295- });
296- image.deleted.connect ((parent) => {
297- this.icon_view.remove (parent);
298- this.select_first_item ();
299- });
300- icon_view.add (image);
301- icon_view.show_all ();
302- }
303-
304- public void select_last_item () {
305- icon_view.select_child (icon_view.get_child_at_index ((int)icon_view.get_children ().length () - 1));
306- }
307-
308- public void select_first_item () {
309- icon_view.select_child (icon_view.get_child_at_index (0));
310- }
311-
312- public void update_button (GLib.DesktopAppInfo app) {
313- foreach (var item in icon_view.get_children ()) {
314- if ((item as Gtk.FlowBoxChild).get_child () is ApplicationIcon) {
315- var app_icon = (item as Gtk.FlowBoxChild).get_child () as ApplicationIcon;
316-
317- if (app_icon.desktop_file.name == app.get_display_name ()) {
318- app_icon.set_new_desktopfile (new DesktopFile.from_desktopappinfo (app));
319- icon_view.select_child (item as Gtk.FlowBoxChild);
320- break;
321- }
322- }
323- }
324- }
325-}
326-
327-
328-public class ApplicationIcon : Gtk.Overlay {
329-
330- Gtk.Image image;
331- Gtk.Label label;
332- Gtk.MenuButton conf_btn;
333- Gtk.Box box;
334- Gtk.ActionGroup action_group;
335-
336- internal DesktopFile desktop_file { get; private set; }
337-
338- public signal void deleted (Gtk.Container? parent);
339- public signal void edit_request (DesktopFile desktop_file);
340-
341- public ApplicationIcon (GLib.DesktopAppInfo app) {
342- this.desktop_file = new DesktopFile.from_desktopappinfo (app);
343-
344- hexpand = false;
345- vexpand = false;
346-
347- label = new Gtk.Label (this.desktop_file.name);
348-
349- set_icon (this.desktop_file.icon);
350-
351- this.margin = 6;
352- this.margin_start = 20;
353- this.margin_end = 20;
354-
355- var menu = new ActionMenu ();
356- menu.halign = Gtk.Align.CENTER;
357- menu.delete_clicked.connect (() => { remove_application (); });
358- menu.edit_clicked.connect (() => { edit_request (desktop_file); });
359-
360- box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
361- box.pack_start (image, false, false, 0);
362- box.pack_start (label, false, false, 0);
363- box.pack_start (menu, false, false, 0);
364-
365- box.hexpand = false;
366- box.vexpand = false;
367-
368- var event_box = new Gtk.EventBox ();
369- event_box.add (box);
370- event_box.events |= Gdk.EventMask.ENTER_NOTIFY_MASK|Gdk.EventMask.LEAVE_NOTIFY_MASK;
371-
372- event_box.enter_notify_event.connect ((event) => {
373- menu.set_reveal_child (true);
374- return false;
375- });
376-
377- event_box.leave_notify_event.connect ((event) => {
378- if (event.detail == Gdk.NotifyType.INFERIOR)
379- return false;
380- menu.set_reveal_child (false);
381- return false;
382- });
383-
384- this.add (event_box);
385- }
386-
387- public void set_new_desktopfile (DesktopFile desktop_file) {
388- this.desktop_file = desktop_file;
389- set_icon (this.desktop_file.icon);
390- }
391-
392- private void set_icon (string icon) {
393- if (File.new_for_path (icon).query_exists ()) {
394- var pix = new Gdk.Pixbuf.from_file (icon);
395-
396- int new_height = 64;
397- int new_width = 64;
398- int margin_vertical = 0;
399- int margin_horizontal = 0;
400-
401- if (pix.height > pix.width) {
402- new_width = new_width * pix.width / pix.height;
403- margin_horizontal = (new_height - new_width) / 2;
404- } else if (pix.height < pix.width) {
405- new_height = new_height * pix.height / pix.width;
406- margin_vertical = (new_width - new_height) / 2;
407- }
408- if (image == null)
409- image = new Gtk.Image.from_pixbuf (pix.scale_simple (new_width, new_height, Gdk.InterpType.BILINEAR));
410- else
411- image.set_from_pixbuf (pix.scale_simple (new_width, new_height, Gdk.InterpType.BILINEAR));
412-
413- image.margin_top = margin_vertical;
414- image.margin_bottom = margin_vertical;
415- image.margin_right = margin_horizontal;
416- image.margin_left = margin_horizontal;
417- } else {
418- image = new Gtk.Image ();
419- image.icon_name = icon;
420- image.pixel_size = 64;
421- }
422- }
423-
424- private void remove_application () {
425- desktop_file.delete_file ();
426- deleted (this.get_parent());
427- this.destroy ();
428- }
429-}
430-
431-public class ActionMenu : Gtk.Revealer {
432-
433- public signal void delete_clicked ();
434- public signal void edit_clicked ();
435-
436- public ActionMenu () {
437- var delete_button = new Gtk.Button.from_icon_name ("edit-delete-symbolic", Gtk.IconSize.BUTTON);
438- delete_button.tooltip_text = _("Delete Webapp");
439- delete_button.relief = Gtk.ReliefStyle.NONE;
440- delete_button.clicked.connect (() => { delete_clicked (); });
441-
442- var edit_button = new Gtk.Button.from_icon_name ("edit-symbolic", Gtk.IconSize.BUTTON);
443- edit_button.tooltip_text = _("Edit Webapp Properties");
444- edit_button.relief = Gtk.ReliefStyle.NONE;
445- edit_button.clicked.connect (() => { edit_clicked (); });
446-
447- var buttons = new Gtk.Grid ();
448- buttons.orientation = Gtk.Orientation.HORIZONTAL;
449- buttons.add (edit_button);
450- buttons.add (delete_button);
451- buttons.opacity = 0.5;
452-
453- this.transition_type = Gtk.RevealerTransitionType.CROSSFADE;
454- this.add (buttons);
455- }
456-}
457
458=== modified file 'src/Webby.vala'
459--- src/Webby.vala 2015-03-23 18:07:08 +0000
460+++ src/Webby.vala 2015-10-16 13:27:49 +0000
461@@ -2,9 +2,8 @@
462
463 Gtk.init (ref args);
464
465- if (args.length < 2) {
466- var window = new AppWindow ();
467- window.show_all ();
468+ if (args.length < 2 || args[1] == "--about" || args[1] == "-d") {
469+ return AppWindow.instance.run (args);
470 } else {
471 var app_info = DesktopFile.get_app_by_url (args[1]);
472 var app = new WebAppWindow(app_info.get_display_name (), args[1]);
473
474=== added directory 'src/Widgets'
475=== added file 'src/Widgets/ApplicationIcon.vala'
476--- src/Widgets/ApplicationIcon.vala 1970-01-01 00:00:00 +0000
477+++ src/Widgets/ApplicationIcon.vala 2015-10-16 13:27:49 +0000
478@@ -0,0 +1,129 @@
479+public class ApplicationIcon : Gtk.Overlay {
480+
481+ Gtk.Image image;
482+ Gtk.Label label;
483+ Gtk.MenuButton conf_btn;
484+ Gtk.Box box;
485+ Gtk.ActionGroup action_group;
486+
487+ internal DesktopFile desktop_file { get; private set; }
488+
489+ public signal void deleted (Gtk.Container? parent);
490+ public signal void edit_request (DesktopFile desktop_file);
491+
492+ public ApplicationIcon (GLib.DesktopAppInfo app) {
493+ this.desktop_file = new DesktopFile.from_desktopappinfo (app);
494+
495+ hexpand = false;
496+ vexpand = false;
497+
498+ label = new Gtk.Label (this.desktop_file.name);
499+
500+ set_icon (this.desktop_file.icon);
501+
502+ this.margin = 6;
503+ this.margin_start = 20;
504+ this.margin_end = 20;
505+
506+ var menu = new ActionMenu ();
507+ menu.halign = Gtk.Align.CENTER;
508+ menu.delete_clicked.connect (() => { remove_application (); });
509+ menu.edit_clicked.connect (() => { edit_request (desktop_file); });
510+
511+ box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
512+ box.pack_start (image, false, false, 0);
513+ box.pack_start (label, false, false, 0);
514+ box.pack_start (menu, false, false, 0);
515+
516+ box.hexpand = false;
517+ box.vexpand = false;
518+
519+ var event_box = new Gtk.EventBox ();
520+ event_box.add (box);
521+ event_box.events |= Gdk.EventMask.ENTER_NOTIFY_MASK|Gdk.EventMask.LEAVE_NOTIFY_MASK;
522+
523+ event_box.enter_notify_event.connect ((event) => {
524+ menu.set_reveal_child (true);
525+ return false;
526+ });
527+
528+ event_box.leave_notify_event.connect ((event) => {
529+ if (event.detail == Gdk.NotifyType.INFERIOR)
530+ return false;
531+ menu.set_reveal_child (false);
532+ return false;
533+ });
534+
535+ this.add (event_box);
536+ }
537+
538+ public void set_new_desktopfile (DesktopFile desktop_file) {
539+ this.desktop_file = desktop_file;
540+ set_icon (this.desktop_file.icon);
541+ }
542+
543+ private void set_icon (string icon) {
544+ if (File.new_for_path (icon).query_exists ()) {
545+ var pix = new Gdk.Pixbuf.from_file (icon);
546+
547+ int new_height = 64;
548+ int new_width = 64;
549+ int margin_vertical = 0;
550+ int margin_horizontal = 0;
551+
552+ if (pix.height > pix.width) {
553+ new_width = new_width * pix.width / pix.height;
554+ margin_horizontal = (new_height - new_width) / 2;
555+ } else if (pix.height < pix.width) {
556+ new_height = new_height * pix.height / pix.width;
557+ margin_vertical = (new_width - new_height) / 2;
558+ }
559+ if (image == null)
560+ image = new Gtk.Image.from_pixbuf (pix.scale_simple (new_width, new_height, Gdk.InterpType.BILINEAR));
561+ else
562+ image.set_from_pixbuf (pix.scale_simple (new_width, new_height, Gdk.InterpType.BILINEAR));
563+
564+ image.margin_top = margin_vertical;
565+ image.margin_bottom = margin_vertical;
566+ image.margin_right = margin_horizontal;
567+ image.margin_left = margin_horizontal;
568+ } else {
569+ image = new Gtk.Image ();
570+ image.icon_name = icon;
571+ image.pixel_size = 64;
572+ }
573+ }
574+
575+ private void remove_application () {
576+ desktop_file.delete_file ();
577+ deleted (this.get_parent());
578+ this.destroy ();
579+ }
580+}
581+
582+public class ActionMenu : Gtk.Revealer {
583+
584+ public signal void delete_clicked ();
585+ public signal void edit_clicked ();
586+
587+ public ActionMenu () {
588+ var delete_button = new Gtk.Button.from_icon_name ("edit-delete-symbolic", Gtk.IconSize.BUTTON);
589+ delete_button.tooltip_text = _("Delete Webapp");
590+ delete_button.relief = Gtk.ReliefStyle.NONE;
591+ delete_button.clicked.connect (() => { delete_clicked (); });
592+
593+ var edit_button = new Gtk.Button.from_icon_name ("edit-symbolic", Gtk.IconSize.BUTTON);
594+ edit_button.tooltip_text = _("Edit Webapp Properties");
595+ edit_button.relief = Gtk.ReliefStyle.NONE;
596+ edit_button.clicked.connect (() => { edit_clicked (); });
597+
598+ var buttons = new Gtk.Grid ();
599+ buttons.orientation = Gtk.Orientation.HORIZONTAL;
600+ buttons.add (edit_button);
601+ buttons.add (delete_button);
602+ buttons.opacity = 0.5;
603+
604+ this.transition_type = Gtk.RevealerTransitionType.CROSSFADE;
605+ this.add (buttons);
606+ }
607+}
608
609=== added file 'src/Widgets/ApplicationsView.vala'
610--- src/Widgets/ApplicationsView.vala 1970-01-01 00:00:00 +0000
611+++ src/Widgets/ApplicationsView.vala 2015-10-16 13:27:49 +0000
612@@ -0,0 +1,86 @@
613+public class ApplicationsView : Gtk.Box {
614+
615+ public signal void add_request();
616+ public signal void edit_request(DesktopFile desktop_file);
617+ public signal void app_deleted ();
618+
619+ private Gtk.FlowBox icon_view;
620+ private Gee.HashMap<string, GLib.DesktopAppInfo> applications;
621+
622+ public bool has_items { get { return icon_view.get_children ().length () > 0; } }
623+
624+ public ApplicationsView () {
625+
626+ GLib.Object (orientation: Gtk.Orientation.VERTICAL);
627+ var scrolled = new Gtk.ScrolledWindow (null, null);
628+ scrolled.hscrollbar_policy = Gtk.PolicyType.NEVER;
629+
630+ icon_view = new Gtk.FlowBox();
631+ icon_view.valign = Gtk.Align.START;
632+ icon_view.vexpand = false;
633+ icon_view.homogeneous = true;
634+ icon_view.column_spacing = 15;
635+ icon_view.row_spacing = 15;
636+ icon_view.margin = 15;
637+ icon_view.activate_on_single_click = false;
638+ icon_view.child_activated.connect ((child) => {
639+ if ((child as Gtk.FlowBoxChild).get_child () is ApplicationIcon) {
640+ var app_icon = (child as Gtk.FlowBoxChild).get_child () as ApplicationIcon;
641+ try {
642+ Process.spawn_command_line_async ("webby " + app_icon.desktop_file.url);
643+ } catch (SpawnError e) {
644+ debug ("Error: %s\n", e.message);
645+ }
646+ }
647+ });
648+ load_applications ();
649+
650+ scrolled.add(icon_view);
651+ this.pack_start(scrolled, true, true, 0);
652+
653+ }
654+
655+ public void load_applications () {
656+ applications = DesktopFile.get_webby_applications();
657+
658+ foreach (GLib.DesktopAppInfo app in applications.values) {
659+ this.add_button (app);
660+ }
661+ }
662+
663+ public void add_button (GLib.DesktopAppInfo app) {
664+ var image = new ApplicationIcon (app);
665+ image.edit_request.connect ((desktop_file) => {
666+ edit_request (desktop_file);
667+ icon_view.unselect_all ();
668+ });
669+ image.deleted.connect ((parent) => {
670+ this.icon_view.remove (parent);
671+ app_deleted ();
672+ });
673+ icon_view.add (image);
674+ icon_view.show_all ();
675+ }
676+
677+ public void select_last_item () {
678+ icon_view.select_child (icon_view.get_child_at_index ((int)icon_view.get_children ().length () - 1));
679+ }
680+
681+ public void select_first_item () {
682+ icon_view.select_child (icon_view.get_child_at_index (0));
683+ }
684+
685+ public void update_button (GLib.DesktopAppInfo app) {
686+ foreach (var item in icon_view.get_children ()) {
687+ if ((item as Gtk.FlowBoxChild).get_child () is ApplicationIcon) {
688+ var app_icon = (item as Gtk.FlowBoxChild).get_child () as ApplicationIcon;
689+
690+ if (app_icon.desktop_file.name == app.get_display_name ()) {
691+ app_icon.set_new_desktopfile (new DesktopFile.from_desktopappinfo (app));
692+ icon_view.select_child (item as Gtk.FlowBoxChild);
693+ break;
694+ }
695+ }
696+ }
697+ }
698+}

Subscribers

People subscribed via source and target branches

to all changes: