[gnome-contacts] Add menu button
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-contacts] Add menu button
- Date: Wed, 25 May 2011 18:18:44 +0000 (UTC)
commit f7e921ecfbf046d2640c31026e20077890b51768
Author: Alexander Larsson <alexl redhat com>
Date: Wed May 25 20:18:24 2011 +0200
Add menu button
src/Makefile.am | 1 +
src/contacts-app.vala | 26 ++++--
src/contacts-menu-button.vala | 182 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 200 insertions(+), 9 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 8a8e121..4df38bf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,6 +19,7 @@ gnome_contacts_SOURCES = \
contacts-app.vala \
contacts-contact.vala \
contacts-starred-button.vala \
+ contacts-menu-button.vala \
contacts-hover-image.vala \
contacts-store.vala \
contacts-clickable.vala \
diff --git a/src/contacts-app.vala b/src/contacts-app.vala
index 6318cb6..0de1342 100644
--- a/src/contacts-app.vala
+++ b/src/contacts-app.vala
@@ -474,15 +474,23 @@ public class Contacts.App : Window {
button = new Button.with_label(_("Edit"));
bbox.pack_start (button, false, false, 0);
- button = new Button ();
- var label = new Label (_("More"));
- var arrow = new Arrow (ArrowType.DOWN, ShadowType.NONE);
- var hbox2 = new Box (Orientation.HORIZONTAL, 0);
- hbox2.pack_start (label, true, false, 0);
- hbox2.pack_start (arrow, false, false, 0);
- button.add (hbox2);
- bbox.pack_end (button, false, false, 0);
- bbox.set_child_secondary (button, true);
+ MenuButton menu_button = new MenuButton (_("More"));
+
+ bbox.pack_end (menu_button, false, false, 0);
+ bbox.set_child_secondary (menu_button, true);
+
+ var menu = new Menu ();
+ var mi = new MenuItem.with_label (_("Add/Remove linked contacts..."));
+ menu.append (mi);
+ mi.show ();
+ mi = new MenuItem.with_label (_("Send..."));
+ menu.append (mi);
+ mi.show ();
+ mi = new MenuItem.with_label (_("Delete"));
+ menu.append (mi);
+ mi.show ();
+
+ menu_button.set_menu (menu);
grid.show_all ();
}
diff --git a/src/contacts-menu-button.vala b/src/contacts-menu-button.vala
new file mode 100644
index 0000000..9d29808
--- /dev/null
+++ b/src/contacts-menu-button.vala
@@ -0,0 +1,182 @@
+/* -*- Mode: vala; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 8 -*- */
+/*
+ * Copyright (C) 2011 Alexander Larsson <alexl redhat com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+using Gtk;
+
+public class Contacts.MenuButton : ToggleButton {
+ Menu? menu;
+ bool popup_in_progress;
+
+ public MenuButton (string label) {
+ set_focus_on_click (false);
+
+ var label_widget = new Label (label);
+ var arrow = new Arrow (ArrowType.DOWN, ShadowType.NONE);
+ var grid = new Grid ();
+ grid.set_orientation (Orientation.HORIZONTAL);
+ grid.add (label_widget);
+ grid.add (arrow);
+ grid.set_row_spacing (3);
+ grid.set_hexpand (true);
+ grid.set_halign (Align.CENTER);
+ this.add (grid);
+ }
+
+ ~MenuButton () {
+ set_menu (null);
+ }
+
+ private void menu_position (Menu menu, out int x, out int y, out bool push_in) {
+ Allocation allocation;
+ get_allocation (out allocation);
+
+ int sx = 0;
+ int sy = 0;
+
+ if (!get_has_window ()) {
+ sx += allocation.x;
+ sy += allocation.y;
+ }
+
+ get_window ().get_root_coords (sx, sy, out sx, out sy);
+
+ Requisition menu_req;
+ Gdk.Rectangle monitor;
+
+ menu.get_preferred_size (null, out menu_req);
+
+ if (get_direction () == TextDirection.LTR)
+ x = sx;
+ else
+ x = sx + allocation.width - menu_req.width;
+ y = sy;
+
+ var window = get_window ();
+ var screen = get_screen ();
+ var monitor_num = screen.get_monitor_at_window (window);
+ if (monitor_num < 0)
+ monitor_num = 0;
+ screen.get_monitor_geometry (monitor_num, out monitor);
+
+ if (x < monitor.x)
+ x = monitor.x;
+ else if (x + menu_req.width > monitor.x + monitor.width)
+ x = monitor.x + monitor.width - menu_req.width;
+
+ if (monitor.y + monitor.height - y - allocation.height >= menu_req.height)
+ y += allocation.height;
+ else if (y - monitor.y >= menu_req.height)
+ y -= menu_req.height;
+ else if (monitor.y + monitor.height - y - allocation.height > y - monitor.y)
+ y += allocation.height;
+ else
+ y -= menu_req.height;
+
+ menu.set_monitor (monitor_num);
+
+ Window? toplevel = menu.get_parent() as Window;
+ if (toplevel != null && !toplevel.get_visible())
+ toplevel.set_type_hint (Gdk.WindowTypeHint.DROPDOWN_MENU);
+
+ push_in = false;
+ }
+
+ public override void toggled () {
+ if (get_active ()) {
+ if (!popup_in_progress)
+ menu.popup (null, null, menu_position, 1, Gtk.get_current_event_time ());
+ } else {
+ menu.popdown ();
+ }
+ }
+
+ public override bool button_press_event (Gdk.EventButton event) {
+ var ewidget = Gtk.get_event_widget ((Gdk.Event)(&event));
+
+ if (ewidget != this ||
+ get_active ())
+ return false;
+
+ menu.popup (null, null, menu_position, 1, Gtk.get_current_event_time ());
+ set_active (true);
+ popup_in_progress = true;
+ return true;
+ }
+
+ public override bool button_release_event (Gdk.EventButton event) {
+ bool popup_in_progress_saved = popup_in_progress;
+ popup_in_progress = false;
+
+ var ewidget = Gtk.get_event_widget ((Gdk.Event)(&event));
+
+ if (ewidget == this &&
+ !popup_in_progress_saved &&
+ get_active ()) {
+ menu.popdown ();
+ return true;
+ }
+ if (ewidget != this) {
+ menu.popdown ();
+ return true;
+ }
+ return false;
+ }
+
+ private void menu_show (Widget menu) {
+ popup_in_progress = true;
+ set_active (true);
+ popup_in_progress = false;
+ }
+
+ private void menu_hide (Widget menu) {
+ set_active (false);
+ }
+
+ private void menu_detach (Menu menu) {
+ }
+
+ public void set_menu (Menu? menu) {
+ if (this.menu != null) {
+ this.menu.show.disconnect (menu_show);
+ this.menu.hide.disconnect (menu_hide);
+ this.menu.detach ();
+ }
+
+ this.menu = menu;
+
+ if (this.menu != null) {
+ this.menu.show.connect (menu_show);
+ this.menu.hide.connect (menu_hide);
+ this.menu.attach_to_widget (this, menu_detach);
+ }
+ }
+
+ public override bool draw (Cairo.Context cr) {
+ var context = get_style_context ();
+ context.save ();
+ if (get_active ()) {
+ context.add_class (STYLE_CLASS_MENUBAR);
+ context.add_class (STYLE_CLASS_MENUITEM);
+ }
+ base.draw (cr);
+ context.restore ();
+ return false;
+ }
+
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]