[gnome-boxes] Start the basics of the selection mode
- From: Marc-Andre Lureau <malureau src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-boxes] Start the basics of the selection mode
- Date: Sat, 5 Nov 2011 03:20:22 +0000 (UTC)
commit 9322602ea6933b89e09a5705125f733243e4eff7
Author: Marc-Andrà Lureau <marcandre lureau gmail com>
Date: Sat Nov 5 04:16:22 2011 +0100
Start the basics of the selection mode
src/app.vala | 24 +++++++++++++++++++++-
src/collection-view.vala | 45 +++++++++++++++++++++++++++++++++++--------
src/display-config.vala | 12 +++++++++++
src/selectionbar.vala | 47 ++++++++++++++++++++++++++++++++++++++++++++-
src/topbar.vala | 18 ++++++++++++++++-
5 files changed, 132 insertions(+), 14 deletions(-)
---
diff --git a/src/app.vala b/src/app.vala
index 0bde562..dd79942 100644
--- a/src/app.vala
+++ b/src/app.vala
@@ -222,9 +222,9 @@ private class Boxes.App: Boxes.UI {
box.add_constraint (new Clutter.BindConstraint (stage, BindCoordinate.SIZE, 0));
stage.add_actor (box);
- topbar = new Topbar (this);
sidebar = new Sidebar (this);
view = new CollectionView (this, sidebar.category);
+ topbar = new Topbar (this);
selectionbar = new Selectionbar (this);
selectionbar.actor.add_constraint (new Clutter.AlignConstraint (view.actor, AlignAxis.X_AXIS, 0.5f));
@@ -268,6 +268,8 @@ private class Boxes.App: Boxes.UI {
case UIState.COLLECTION:
set_main_ui_state ("collection");
+ actor_unpin (topbar.actor);
+ actor_unpin (view.actor);
actor_remove (topbar.actor);
actor_remove (sidebar.actor);
actor_remove (view.actor);
@@ -310,6 +312,24 @@ private class Boxes.App: Boxes.UI {
return false;
}
+ private bool _selection_mode;
+ public bool selection_mode { get { return _selection_mode; }
+ set {
+ return_if_fail (ui_state == UIState.COLLECTION);
+
+ _selection_mode = value;
+ }
+ }
+
+ public List<CollectionItem> selected_items {
+ owned get { return view.get_selected_items (); }
+ }
+
+ public void remove_item (CollectionItem item) {
+ debug ("FIXME: this is not yet fully implemented");
+ view.remove_item (item);
+ }
+
private bool on_key_pressed (Widget widget, Gdk.EventKey event) {
if (event.keyval == F11_KEY) {
if (fullscreen)
@@ -324,7 +344,7 @@ private class Boxes.App: Boxes.UI {
}
public bool item_selected (CollectionItem item) {
- if (ui_state == UIState.COLLECTION) {
+ if (ui_state == UIState.COLLECTION && !selection_mode) {
current_item = item;
if (current_item is Machine) {
diff --git a/src/collection-view.vala b/src/collection-view.vala
index ad5d119..fa17822 100644
--- a/src/collection-view.vala
+++ b/src/collection-view.vala
@@ -28,7 +28,12 @@ private class Boxes.CollectionView: Boxes.UI {
public CollectionView (App app, Category category) {
this.app = app;
this.category = category;
+
setup_view ();
+ app.notify["selection-mode"].connect (() => {
+ var mode = app.selection_mode ? Gtk.SelectionMode.MULTIPLE : Gtk.SelectionMode.SINGLE;
+ icon_view.set_selection_mode (mode);
+ });
}
public void set_over_boxes (Clutter.Actor actor, bool center = false) {
@@ -122,7 +127,7 @@ private class Boxes.CollectionView: Boxes.UI {
model.set (iter, ModelColumns.TITLE, title);
model.set (iter, ModelColumns.ITEM, item);
- set_data<Gtk.TreeIter?> ("iter", iter);
+ item.set_data<Gtk.TreeIter?> ("iter", iter);
return iter;
}
@@ -136,10 +141,11 @@ private class Boxes.CollectionView: Boxes.UI {
}
var iter = append (machine.pixbuf, machine.name, item);
- machine.notify["pixbuf"].connect (() => {
+ var pixbuf_id = machine.notify["pixbuf"].connect (() => {
// apparently iter is stable after insertion/removal/sort
model.set (iter, ModelColumns.SCREENSHOT, machine.pixbuf);
});
+ item.set_data<ulong> ("pixbuf_id", pixbuf_id);
item.ui_state = UIState.COLLECTION;
actor_remove (item.actor);
@@ -147,12 +153,35 @@ private class Boxes.CollectionView: Boxes.UI {
update_item_visible (item);
}
+ public List<CollectionItem> get_selected_items () {
+ var list = new List<CollectionItem> ();
+ var selected = icon_view.get_selected_items ();
+
+ foreach (var path in selected)
+ list.append (get_item_for_path (path));
+
+ return list;
+ }
+
public void remove_item (CollectionItem item) {
var iter = item.get_data<Gtk.TreeIter?> ("iter");
+ var pixbuf_id = item.get_data<ulong> ("pixbuf_id");
+
return_if_fail (iter != null);
model.remove (iter);
item.set_data<Gtk.TreeIter?> ("iter", null);
+ item.disconnect (pixbuf_id);
+ }
+
+ private CollectionItem get_item_for_path (Gtk.TreePath path) {
+ Gtk.TreeIter iter;
+ GLib.Value value;
+
+ model.get_iter (out iter, path);
+ model.get_value (iter, ModelColumns.ITEM, out value);
+
+ return (CollectionItem) value;
}
private void setup_view () {
@@ -180,14 +209,12 @@ private class Boxes.CollectionView: Boxes.UI {
icon_view_activate_on_single_click (icon_view, true);
icon_view.set_selection_mode (Gtk.SelectionMode.SINGLE);
icon_view.item_activated.connect ((view, path) => {
- Gtk.TreeIter iter;
- GLib.Value value;
-
- model.get_iter (out iter, path);
- model.get_value (iter, ModelColumns.ITEM, out value);
- app.item_selected ((CollectionItem) value);
+ var item = get_item_for_path (path);
+ app.item_selected (item);
+ });
+ icon_view.selection_changed.connect (() => {
+ app.notify_property ("selected-items");
});
-
var pixbuf_renderer = new Gtk.CellRendererPixbuf ();
pixbuf_renderer.xalign = 0.5f;
pixbuf_renderer.yalign = 0.5f;
diff --git a/src/display-config.vala b/src/display-config.vala
index 560e4d1..df787e9 100644
--- a/src/display-config.vala
+++ b/src/display-config.vala
@@ -30,6 +30,18 @@ private class Boxes.DisplayConfig: GLib.Object, Boxes.IConfig {
this.group += " " + subgroup;
}
+ public void add_category (string category) {
+ if (category in categories)
+ return;
+
+ // FIXME: vala bug if in one line
+ string[] categories = categories;
+ categories += category;
+ this.categories = categories;
+
+ save ();
+ }
+
public void save_display_property (Object display, string property_name) {
var value = Value (display.get_class ().find_property (property_name).value_type);
diff --git a/src/selectionbar.vala b/src/selectionbar.vala
index fdc61ba..1551a73 100644
--- a/src/selectionbar.vala
+++ b/src/selectionbar.vala
@@ -27,7 +27,11 @@ private class Boxes.Selectionbar: GLib.Object {
toolbar.insert (favorite_btn, 0);
favorite_btn.icon_name = "emblem-favorite-symbolic";
favorite_btn.clicked.connect (() => {
- message ("fixme");
+ foreach (var item in app.selected_items) {
+ var machine = item as Machine;
+ if (machine != null)
+ machine.config.add_category ("favourite");
+ }
});
var separator = new Gtk.SeparatorToolItem();
@@ -37,13 +41,52 @@ private class Boxes.Selectionbar: GLib.Object {
toolbar.insert (remove_btn, 2);
remove_btn.icon_name = "edit-delete-symbolic";
remove_btn.clicked.connect (() => {
- message ("fixme");
+ foreach (var item in app.selected_items)
+ app.remove_item (item);
});
toolbar.show_all ();
actor.reactive = true;
actor.hide ();
+ app.notify["selection-mode"].connect (() => {
+ update_visible ();
+ });
+
+ app.notify["selected-items"].connect (() => {
+ update_visible ();
+ });
+
app.stage.add (actor);
}
+
+ private void update_visible () {
+ if (!app.selection_mode)
+ visible = false;
+ else
+ visible = app.selected_items.length () > 0;
+ }
+
+ private bool visible {
+ set {
+ if (value)
+ show ();
+ else
+ hide ();
+ }
+ }
+ private void show () {
+ actor.show ();
+ actor.queue_redraw ();
+ actor.animate (Clutter.AnimationMode.LINEAR, Boxes.App.duration,
+ "opacity", 255);
+ }
+
+ private void hide () {
+ var anim = actor.animate (Clutter.AnimationMode.LINEAR, Boxes.App.duration,
+ "opacity", 0);
+ anim.completed.connect (() => {
+ actor.hide ();
+ });
+ }
}
diff --git a/src/topbar.vala b/src/topbar.vala
index f1beb09..044d1a4 100644
--- a/src/topbar.vala
+++ b/src/topbar.vala
@@ -25,11 +25,16 @@ private class Boxes.Topbar: Boxes.UI {
private Gtk.ToolButton spinner_btn;
private Gtk.ToolButton back_btn;
private Gtk.Button new_btn;
+ private Gtk.Label selection_label;
public Topbar (App app) {
this.app = app;
setup_topbar ();
+
+ app.notify["selected-items"].connect (() => {
+ update_selection_label ();
+ });
}
private void setup_topbar () {
@@ -89,6 +94,7 @@ private class Boxes.Topbar: Boxes.UI {
select_btn.valign = Gtk.Align.CENTER;
select_btn.clicked.connect (() => {
notebook.page = TopbarPage.SELECTION;
+ app.selection_mode = true;
});
toolbar_end.insert (select_btn, 1);
@@ -107,7 +113,8 @@ private class Boxes.Topbar: Boxes.UI {
toolbar_selection.set_show_arrow (false);
hbox.pack_start (toolbar_selection, true, true, 0);
- var selection_label = new Gtk.Label ("<i>" + _("Click on items to select them") + "</i>");
+ selection_label = new Gtk.Label ("");
+ update_selection_label ();
selection_label.use_markup = true;
tool_item = new Gtk.ToolItem ();
tool_item.set_expand (true);
@@ -120,6 +127,7 @@ private class Boxes.Topbar: Boxes.UI {
toolbar_selection.insert (cancel_btn, 1);
cancel_btn.clicked.connect (() => {
select_btn.active = false;
+ app.selection_mode = false;
notebook.page = TopbarPage.COLLECTION;
});
@@ -141,6 +149,14 @@ private class Boxes.Topbar: Boxes.UI {
app.state.set_key (null, "display", gtk_actor, "y", AnimationMode.EASE_OUT_QUAD, -(float) height, 0, 0);
}
+ private void update_selection_label () {
+ var items = app.selected_items.length ();
+ if (items > 0)
+ selection_label.set_markup ("<b>" + _("%d selected").printf (items) + "</b>");
+ else
+ selection_label.set_markup ("<i>" + _("Click on items to select them") + "</i>");
+ }
+
public override void ui_state_changed () {
switch (ui_state) {
case UIState.COLLECTION:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]