3
// Copyright (C) 2008 GNOME Do
5
// This program is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
10
// This program is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
// GNU General Public License for more details.
15
// You should have received a copy of the GNU General Public License
16
// along with this program. If not, see <http://www.gnu.org/licenses/>.
20
using System.Collections.Generic;
28
using Do.Interface.CairoUtils;
31
using Docky.Utilities;
33
namespace Docky.Interface
37
public class DockPopupMenu : Gtk.Window
39
const int TailHeight = 25;
40
new const int BorderWidth = 2;
41
const int Radius = 10;
42
const int Width = 230;
43
const int TailOffset = 2;
44
const double Pointiness = 2;
45
const double BaseCurviness = 1.2;
46
const double TailCurviness = .8;
48
int horizontal_offset;
50
public Gtk.VBox Container { get; private set; }
52
public DockPopupMenu() : base (Gtk.WindowType.Popup)
58
SkipTaskbarHint = true;
61
TypeHint = WindowTypeHint.PopupMenu;
65
this.SetCompositeColormap ();
67
AddEvents ((int) EventMask.PointerMotionMask |
68
(int) EventMask.LeaveNotifyMask |
69
(int) EventMask.ButtonPressMask |
70
(int) EventMask.ButtonReleaseMask |
71
(int) EventMask.FocusChangeMask);
73
Container = new Gtk.VBox ();
77
protected virtual void Build ()
79
VBox space = new VBox ();
80
space.Add (Container);
81
space.Add (new Label (" "));
82
Container.BorderWidth = 5;
88
public virtual void PopUp (IEnumerable<AbstractMenuButtonArgs> args, int x, int y)
91
Gdk.Rectangle geo = LayoutUtils.MonitorGemonetry ();
92
Gtk.Requisition req = SizeRequest ();
94
int posx = Math.Min (Math.Max (0, x - req.Width / TailOffset), geo.X + geo.Width - req.Width);
95
horizontal_offset = (x - req.Width / TailOffset) - posx;
96
Move (posx, y - req.Height);
98
Do.Interface.Windowing.PresentWindow (this);
101
protected override bool OnExposeEvent (Gdk.EventExpose evnt)
103
using (Context cr = Gdk.CairoHelper.Create (GdkWindow)) {
108
return base.OnExposeEvent (evnt);
111
protected override bool OnButtonReleaseEvent (Gdk.EventButton evnt)
114
GetSize (out rect.Width, out rect.Height);
116
if (evnt.X < 0 || evnt.Y < 0 || evnt.X > rect.Width || evnt.Y > rect.Height)
118
return base.OnButtonReleaseEvent (evnt);
121
protected override bool OnKeyReleaseEvent (Gdk.EventKey evnt)
123
if (evnt.Key == Gdk.Key.Escape)
125
return base.OnKeyReleaseEvent (evnt);
129
void DrawBackground (Context cr)
132
GetSize (out rect.Width, out rect.Height);
134
cr.MoveTo (BorderWidth + Radius, BorderWidth);
135
cr.Arc (rect.Width - BorderWidth - Radius, BorderWidth + Radius, Radius, Math.PI * 1.5, Math.PI * 2);
137
Cairo.PointD rightCurveStart = new Cairo.PointD (rect.Width - BorderWidth, rect.Height - BorderWidth - TailHeight);
138
Cairo.PointD leftCurveStart = new Cairo.PointD (BorderWidth, rect.Height - BorderWidth - TailHeight);
139
Cairo.PointD apex = new Cairo.PointD (rect.Width / 2 + horizontal_offset, rect.Height - BorderWidth);
140
cr.LineTo (rightCurveStart);
142
cr.CurveTo (rightCurveStart.X, rightCurveStart.Y + TailHeight * BaseCurviness,
143
apex.X + 10 * Pointiness, apex.Y - TailHeight * TailCurviness,
146
cr.CurveTo (apex.X - 10 * Pointiness,
147
apex.Y - TailHeight * TailCurviness,
148
leftCurveStart.X, leftCurveStart.Y + TailHeight * BaseCurviness,
149
leftCurveStart.X, leftCurveStart.Y);
151
cr.Arc (BorderWidth + Radius, BorderWidth + Radius, Radius, Math.PI, Math.PI * 1.5);
153
cr.Color = new Cairo.Color (0.1, 0.1, 0.1, .9);
156
cr.Color = new Cairo.Color (.2, .2, .2, .8);