Example #1
0
        public static void PopupMenu(Gtk.Menu menu, Gdk.EventButton ev, Gtk.MenuPositionFunc mpf)
        {
            menu.Deactivated += DeactivateMenu;
            try {
                menu.Popup(null,
                           null,
                           mpf,
                           (ev == null) ? 0 : ev.Button,
                           (ev == null) ? Gtk.Global.CurrentEventTime : ev.Time);
            } catch {
                Logger.Debug("Menu popup failed with custom MenuPositionFunc; trying again without");
                menu.Popup(null,
                           null,
                           null,
                           (ev == null) ? 0 : ev.Button,
                           (ev == null) ? Gtk.Global.CurrentEventTime : ev.Time);
            }

            // Highlight the parent
            if (menu.AttachWidget != null)
            {
                menu.AttachWidget.State = Gtk.StateType.Selected;
            }

#if WIN32
            BringToForeground();
#endif
        }
Example #2
0
 public MenuPositionFuncWrapper(Gtk.MenuPositionFunc managed)
 {
     this.managed = managed;
     if (managed != null)
     {
         NativeDelegate = new MenuPositionFuncNative(NativeCallback);
     }
 }
Example #3
0
        public static int MenuDoPopupModal(Gtk.Widget popup, Gtk.MenuPositionFunc pos_func, Gdk.EventButton evnt, IntPtr user_data, Gtk.Widget for_widget)
        {
            GtkSharp.MenuPositionFuncWrapper pos_func_wrapper = new GtkSharp.MenuPositionFuncWrapper(pos_func);
            int raw_ret = gnome_popup_menu_do_popup_modal(popup == null ? IntPtr.Zero : popup.Handle, pos_func_wrapper.NativeDelegate, IntPtr.Zero, evnt == null ? IntPtr.Zero : evnt.Handle, user_data, for_widget == null ? IntPtr.Zero : for_widget.Handle);
            int ret     = raw_ret;

            return(ret);
        }
Example #4
0
 public void PopupForDevice(Gdk.Device device, Gtk.Widget parent_menu_shell, Gtk.Widget parent_menu_item, Gtk.MenuPositionFunc func, GLib.DestroyNotify destroy, uint button, uint activate_time)
 {
     GtkSharp.MenuPositionFuncWrapper func_wrapper = new GtkSharp.MenuPositionFuncWrapper(func);
     func_wrapper.PersistUntilCalled();
     gtk_menu_popup_for_device(Handle, device == null ? IntPtr.Zero : device.Handle, parent_menu_shell == null ? IntPtr.Zero : parent_menu_shell.Handle, parent_menu_item == null ? IntPtr.Zero : parent_menu_item.Handle, func_wrapper.NativeDelegate, IntPtr.Zero, destroy, button, activate_time);
 }
Example #5
0
 public void Popup(Gtk.Widget parent_menu_shell, Gtk.Widget parent_menu_item, Gtk.MenuPositionFunc func, uint button, uint activate_time)
 {
     GtkSharp.MenuPositionFuncWrapper func_wrapper = new GtkSharp.MenuPositionFuncWrapper(func);
     func_wrapper.PersistUntilCalled();
     gtk_menu_popup(Handle, parent_menu_shell == null ? IntPtr.Zero : parent_menu_shell.Handle, parent_menu_item == null ? IntPtr.Zero : parent_menu_item.Handle, func_wrapper.NativeDelegate, IntPtr.Zero, button, activate_time);
 }
Example #6
0
 public void Popup(Gtk.Widget parent_menu_shell, Gtk.Widget parent_menu_item, Gtk.MenuPositionFunc func, IntPtr data, uint button, uint activate_time)
 {
     Popup(parent_menu_shell, parent_menu_item, func, button, activate_time);
 }
Example #7
0
        /// <summary>Shows a context menu.</summary>
        /// <param name='menu'>The menu.</param>
        /// <param name='parent'>The parent widget.</param>
        /// <param name='evt'>The mouse event. May be null if triggered by keyboard.</param>
        /// <param name='caret'>The caret/selection position within the parent, if the EventButton is null.</param>
        public static void ShowContextMenu(Gtk.Menu menu, Gtk.Widget parent, Gdk.EventButton evt, Gdk.Rectangle caret)
        {
            Gtk.MenuPositionFunc posFunc = null;

            if (parent != null)
            {
                menu.AttachToWidget(parent, null);
                posFunc = delegate(Gtk.Menu m, out int x, out int y, out bool pushIn) {
                    Gdk.Window window = evt != null? evt.Window : parent.GdkWindow;
                    window.GetOrigin(out x, out y);
                    var alloc = parent.Allocation;
                    if (evt != null)
                    {
                        x += (int)evt.X;
                        y += (int)evt.Y;
                    }
                    else if (caret.X >= alloc.X && caret.Y >= alloc.Y)
                    {
                        x += caret.X;
                        y += caret.Y + caret.Height;
                    }
                    else
                    {
                        x += alloc.X;
                        y += alloc.Y;
                    }
                    Gtk.Requisition request  = m.SizeRequest();
                    var             screen   = parent.Screen;
                    Gdk.Rectangle   geometry = GetUsableMonitorGeometry(screen, screen.GetMonitorAtPoint(x, y));

                    //whether to push or flip menus that would extend offscreen
                    //FIXME: this is the correct behaviour for mac, check other platforms
                    bool flip_left = true;
                    bool flip_up   = false;

                    if (x + request.Width > geometry.Right)
                    {
                        if (flip_left)
                        {
                            x -= request.Width;
                        }
                        else
                        {
                            x = geometry.Right - request.Width;
                        }

                        if (x < geometry.Left)
                        {
                            x = geometry.Left;
                        }
                    }

                    if (y + request.Height > geometry.Bottom)
                    {
                        if (flip_up)
                        {
                            y -= request.Height;
                        }
                        else
                        {
                            y = geometry.Bottom - request.Height;
                        }

                        if (y < geometry.Top)
                        {
                            y = geometry.Top;
                        }
                    }

                    pushIn = false;
                };
            }

            uint time;
            uint button;

            if (evt == null)
            {
                time   = Gtk.Global.CurrentEventTime;
                button = 0;
            }
            else
            {
                time   = evt.Time;
                button = evt.Button;
            }

            //HACK: work around GTK menu issues on mac when passing button to menu.Popup
            //some menus appear and immediately hide, and submenus don't activate
            if (Platform.IsMac)
            {
                button = 0;
            }

            menu.Popup(null, null, posFunc, button, time);
        }
Example #8
0
 public static void MenuDoPopup(Gtk.Widget popup, Gtk.MenuPositionFunc pos_func, IntPtr data, Gdk.EventButton evnt, IntPtr user_data, Gtk.Widget for_widget)
 {
     MenuDoPopup(popup, pos_func, evnt, user_data, for_widget);
 }
Example #9
0
 public static int MenuDoPopupModal(Gtk.Widget popup, Gtk.MenuPositionFunc pos_func, IntPtr data, Gdk.EventButton evnt, IntPtr user_data, Gtk.Widget for_widget)
 {
     return(MenuDoPopupModal(popup, pos_func, evnt, user_data, for_widget));
 }
Example #10
0
        /// <summary>Shows a context menu.</summary>
        /// <param name='menu'>The menu.</param>
        /// <param name='parent'>The parent widget.</param>
        /// <param name='evt'>The mouse event. May be null if triggered by keyboard.</param>
        /// <param name='caret'>The caret/selection position within the parent, if the EventButton is null.</param>
        public static void ShowContextMenu(Gtk.Menu menu, Gtk.Widget parent, Gdk.EventButton evt, Gdk.Rectangle caret)
        {
            Gtk.MenuPositionFunc posFunc = null;

            // NOTE: we don't gtk_menu_attach_to_widget to the parent because it seems to cause issues.
            // The expanders in other treeviews in MD stop working when we detach it, and detaching is necessary
            // to prevent memory leaks.
            // Attaching means menu moves when parent is moved and is destroyed when parent is destroyed. Neither is
            // particularly important for us.
            // See https://bugzilla.xamarin.com/show_bug.cgi?id=4388
            if (parent != null)
            {
                posFunc = delegate(Gtk.Menu m, out int x, out int y, out bool pushIn) {
                    Gdk.Window window = evt != null? evt.Window : parent.GdkWindow;
                    window.GetOrigin(out x, out y);
                    var alloc = parent.Allocation;
                    if (evt != null)
                    {
                        x += (int)evt.X;
                        y += (int)evt.Y;
                    }
                    else if (caret.X >= alloc.X && caret.Y >= alloc.Y)
                    {
                        x += caret.X;
                        y += caret.Y + caret.Height;
                    }
                    else
                    {
                        x += alloc.X;
                        y += alloc.Y;
                    }
                    Gtk.Requisition request  = m.SizeRequest();
                    var             screen   = parent.Screen;
                    Gdk.Rectangle   geometry = GetUsableMonitorGeometry(screen, screen.GetMonitorAtPoint(x, y));

                    //whether to push or flip menus that would extend offscreen
                    //FIXME: this is the correct behaviour for mac, check other platforms
                    bool flip_left = true;
                    bool flip_up   = false;

                    if (x + request.Width > geometry.X + geometry.Width)
                    {
                        if (flip_left)
                        {
                            x -= request.Width;
                        }
                        else
                        {
                            x = geometry.X + geometry.Width - request.Width;
                        }

                        if (x < geometry.Left)
                        {
                            x = geometry.Left;
                        }
                    }

                    if (y + request.Height > geometry.Y + geometry.Height)
                    {
                        if (flip_up)
                        {
                            y -= request.Height;
                        }
                        else
                        {
                            y = geometry.Y + geometry.Height - request.Height;
                        }

                        if (y < geometry.Top)
                        {
                            y = geometry.Top;
                        }
                    }

                    pushIn = false;
                };
            }

            uint time;
            uint button;

            if (evt == null)
            {
                time   = Gtk.Global.CurrentEventTime;
                button = 0;
            }
            else
            {
                time   = evt.Time;
                button = evt.Button;
            }

            //HACK: work around GTK menu issues on mac when passing button to menu.Popup
            //some menus appear and immediately hide, and submenus don't activate
            if (Platform.IsMac)
            {
                button = 0;
            }

            menu.Popup(null, null, posFunc, button, time);
        }