16
16
// along with this program. If not, see <http://www.gnu.org/licenses/>.
22
using Slingshot.Backend;
24
namespace Slingshot.Widgets {
26
public class CategoryView : EventBox {
28
private Gtk.Grid container;
29
public Sidebar category_switcher;
30
public VSeparator separator;
31
public Widgets.Grid app_view;
32
private Layout layout;
33
public Switcher switcher;
34
private SlingshotView view;
35
private Label empty_cat_label;
37
private Gtk.Grid page_switcher;
39
private const string ALL_APPLICATIONS = _("All Applications");
40
private const string NEW_FILTER = _("Create a new Filter");
41
private int current_position = 0;
42
private bool from_category = false;
44
public HashMap<int, string> category_ids = new HashMap<int, string> ();
46
public CategoryView (SlingshotView parent) {
50
set_visible_window (false);
55
set_size_request (view.columns*130 + 17, view.view_height);
59
private void setup_ui () {
60
container = new Gtk.Grid ();
61
separator = new VSeparator ();
63
layout = new Layout (null, null);
65
app_view = new Widgets.Grid (view.rows, view.columns - 1);
66
layout.put (app_view, 0, 0);
67
empty_cat_label = new Gtk.Label ("");
68
layout.put (empty_cat_label, view.columns*130, view.rows * 130 / 2);
69
layout.set_hexpand (true);
70
layout.set_vexpand (true);
72
// Create the page switcher
73
switcher = new Switcher ();
75
// A bottom widget to keep the page switcher center
76
page_switcher = new Gtk.Grid ();
77
var bottom_separator1 = new Label (""); // A fake label
78
bottom_separator1.set_hexpand(true);
79
var bottom_separator2 = new Label (""); // A fake label
80
bottom_separator2.set_hexpand(true);
81
page_switcher.attach (bottom_separator1, 0, 0, 1, 1);
82
page_switcher.attach (switcher, 1, 0, 1, 1);
83
page_switcher.attach (bottom_separator2, 2, 0, 1, 1);
85
container.attach (separator, 1, 0, 1, 2);
86
container.attach (layout, 2, 0, 1, 1);
92
public void setup_sidebar () {
94
if (category_switcher != null)
95
category_switcher.destroy ();
97
category_switcher = new Sidebar ();
98
category_switcher.can_focus = false;
103
foreach (string cat_name in view.apps.keys) {
104
category_ids.set (n, cat_name);
105
category_switcher.add_category (GLib.dgettext ("gnome-menus-3.0", cat_name).dup ());
109
container.attach (category_switcher, 0, 0, 1, 2);
110
category_switcher.selection_changed.connect ((name, nth) => {
112
view.reset_category_focus ();
113
string category = category_ids.get (nth);
114
show_filtered_apps (category);
117
category_switcher.show_all ();
120
private void connect_events () {
122
layout.scroll_event.connect ((event) => {
123
switch (event.direction.to_string ()) {
124
case "GDK_SCROLL_UP":
125
case "GDK_SCROLL_LEFT":
126
switcher.set_active (switcher.active - 1);
128
case "GDK_SCROLL_DOWN":
129
case "GDK_SCROLL_RIGHT":
130
switcher.set_active (switcher.active + 1);
19
public class Slingshot.Widgets.CategoryView : Gtk.EventBox {
21
private Gtk.Grid container;
22
public Sidebar category_switcher;
23
public Gtk.Separator separator;
24
public Widgets.Grid app_view;
25
private Gtk.Layout layout;
26
public Switcher switcher;
27
private SlingshotView view;
28
private Gtk.Label empty_cat_label;
30
private Gtk.Grid page_switcher;
32
private const string ALL_APPLICATIONS = _("All Applications");
33
private const string NEW_FILTER = _("Create a new Filter");
34
private int current_position = 0;
35
private bool from_category = false;
37
public Gee.HashMap<int, string> category_ids = new Gee.HashMap<int, string> ();
39
public CategoryView (SlingshotView parent) {
43
set_visible_window (false);
48
set_size_request (view.columns*130 + 17, view.view_height);
52
private void setup_ui () {
53
container = new Gtk.Grid ();
54
separator = new Gtk.Separator (Gtk.Orientation.VERTICAL);
56
layout = new Gtk.Layout (null, null);
58
app_view = new Widgets.Grid (view.rows, view.columns - 1);
59
layout.put (app_view, 0, 0);
60
empty_cat_label = new Gtk.Label ("");
61
layout.put (empty_cat_label, view.columns*130, view.rows * 130 / 2);
62
layout.set_hexpand (true);
63
layout.set_vexpand (true);
65
// Create the page switcher
66
switcher = new Switcher ();
68
// A bottom widget to keep the page switcher center
69
page_switcher = new Gtk.Grid ();
70
var bottom_separator1 = new Gtk.Label (""); // A fake label
71
bottom_separator1.set_hexpand(true);
72
var bottom_separator2 = new Gtk.Label (""); // A fake label
73
bottom_separator2.set_hexpand(true);
74
page_switcher.attach (bottom_separator1, 0, 0, 1, 1);
75
page_switcher.attach (switcher, 1, 0, 1, 1);
76
page_switcher.attach (bottom_separator2, 2, 0, 1, 1);
78
container.attach (separator, 1, 0, 1, 2);
79
container.attach (layout, 2, 0, 1, 1);
85
public void setup_sidebar () {
87
if (category_switcher != null)
88
category_switcher.destroy ();
90
category_switcher = new Sidebar ();
91
category_switcher.can_focus = false;
96
foreach (string cat_name in view.apps.keys) {
97
category_ids.set (n, cat_name);
98
category_switcher.add_category (GLib.dgettext ("gnome-menus-3.0", cat_name).dup ());
102
container.attach (category_switcher, 0, 0, 1, 2);
103
category_switcher.selection_changed.connect ((name, nth) => {
105
view.reset_category_focus ();
106
string category = category_ids.get (nth);
107
show_filtered_apps (category);
110
category_switcher.show_all ();
113
private void connect_events () {
115
layout.scroll_event.connect ((event) => {
116
switch (event.direction.to_string ()) {
117
case "GDK_SCROLL_UP":
118
case "GDK_SCROLL_LEFT":
119
switcher.set_active (switcher.active - 1);
121
case "GDK_SCROLL_DOWN":
122
case "GDK_SCROLL_RIGHT":
123
switcher.set_active (switcher.active + 1);
129
app_view.new_page.connect ((page) => {
131
if (switcher.size == 0)
132
switcher.append ("1");
133
switcher.append (page);
135
/* Prevents pages from changing */
136
from_category = true;
139
switcher.active_changed.connect (() => {
140
if (from_category || switcher.active - switcher.old_active == 0) {
141
from_category = false;
145
move_page (switcher.active - switcher.old_active);
146
view.searchbar.grab_focus (); // this is because otherwise focus isn't the current page
149
category_switcher.selected = 0; //Must be after everything else
152
private void add_app (Backend.App app) {
154
var app_entry = new AppEntry (app);
155
app_entry.app_launched.connect (() => view.hide ());
156
app_view.append (app_entry);
157
app_entry.show_all ();
161
public void show_filtered_apps (string category) {
163
switcher.clear_children ();
166
layout.move (empty_cat_label, view.columns*130, view.rows*130 / 2);
167
foreach (Backend.App app in view.apps[category])
170
switcher.set_active (0);
172
layout.move (app_view, 0, 0);
173
current_position = 0;
177
public void move_page (int step) {
179
debug ("Moving: step = " + step.to_string ());
183
if (step < 0 && current_position >= 0) //Left border
185
if (step > 0 && (-current_position) >= ((app_view.get_n_pages () - 1) * app_view.get_page_columns () * 130)) //Right border
189
int increment = -step*130*(view.columns-1)/10;
190
Timeout.add (30/(view.columns-1), () => {
193
current_position += -step*130*(view.columns-1) - 10*increment; //We adjust to end of the page
194
layout.move (app_view, current_position, 0);
136
app_view.new_page.connect ((page) => {
138
if (switcher.size == 0)
139
switcher.append ("1");
140
switcher.append (page);
142
/* Prevents pages from changing */
143
from_category = true;
146
switcher.active_changed.connect (() => {
147
if (from_category || switcher.active - switcher.old_active == 0) {
148
from_category = false;
152
move_page (switcher.active - switcher.old_active);
153
view.searchbar.grab_focus (); // this is because otherwise focus isn't the current page
156
category_switcher.selected = 0; //Must be after everything else
159
private void add_app (App app) {
161
var app_entry = new AppEntry (app);
162
app_entry.app_launched.connect (() => view.hide ());
163
app_view.append (app_entry);
164
app_entry.show_all ();
168
public void show_filtered_apps (string category) {
170
switcher.clear_children ();
173
layout.move (empty_cat_label, view.columns*130, view.rows*130 / 2);
174
foreach (App app in view.apps[category])
177
switcher.set_active (0);
179
layout.move (app_view, 0, 0);
180
current_position = 0;
184
public void move_page (int step) {
186
debug ("Moving: step = " + step.to_string ());
190
if (step < 0 && current_position >= 0) //Left border
192
if (step > 0 && (-current_position) >= ((app_view.get_n_pages () - 1) * app_view.get_page_columns () * 130)) //Right border
196
int increment = -step*130*(view.columns-1)/10;
197
Timeout.add (30/(view.columns-1), () => {
200
current_position += -step*130*(view.columns-1) - 10*increment; //We adjust to end of the page
201
layout.move (app_view, current_position, 0);
205
current_position += increment;
206
layout.move (app_view, current_position, 0);
210
}, Priority.DEFAULT_IDLE);
213
public void show_page_switcher (bool show) {
215
if (page_switcher.get_parent () == null)
216
container.attach (page_switcher, 2, 1, 1, 1);
219
page_switcher.show_all ();
223
page_switcher.hide ();
225
view.searchbar.grab_focus ();
198
current_position += increment;
199
layout.move (app_view, current_position, 0);
203
}, Priority.DEFAULT_IDLE);
206
public void show_page_switcher (bool show) {
208
if (page_switcher.get_parent () == null)
209
container.attach (page_switcher, 2, 1, 1, 1);
212
page_switcher.show_all ();
216
page_switcher.hide ();
218
view.searchbar.grab_focus ();