5
// Scott Peterson <lunchtimemama@gmail.com>
7
// Copyright (c) 2008 Scott Peterson
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
10
// of this software and associated documentation files (the "Software"), to deal
11
// in the Software without restriction, including without limitation the rights
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
// copies of the Software, and to permit persons to whom the Software is
14
// furnished to do so, subject to the following conditions:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
32
namespace Hyena.Widgets
34
public class MenuButton : Container
36
private ToggleButton toggle_button = new ToggleButton ();
37
private HBox box = new HBox ();
38
private Alignment alignment;
40
private Widget button_widget;
42
private Widget size_widget;
44
protected MenuButton (IntPtr ptr) : base (ptr) {}
50
public MenuButton (Widget buttonWidget, Menu menu, bool showArrow)
52
Construct (buttonWidget, menu, showArrow);
55
protected void Construct (Widget buttonWidget, Menu menu, bool showArrow)
57
WidgetFlags |= WidgetFlags.NoWindow;
59
button_widget = buttonWidget;
62
toggle_button.Parent = this;
63
toggle_button.FocusOnClick = false;
64
toggle_button.Relief = ReliefStyle.None;
65
toggle_button.Pressed += delegate { ShowMenu (); toggle_button.Active = true; };
66
toggle_button.Activated += delegate { ShowMenu (); };
71
box.PackStart (button_widget, true, true, 0);
72
alignment = new Alignment (0f, 0.5f, 0f, 0f);
73
arrow = new Arrow (ArrowType.Down, ShadowType.None);
74
alignment.Add (arrow);
75
box.PackStart (alignment, false, false, 5);
77
FocusChain = new Widget[] {toggle_button, box};
79
toggle_button.Add (button_widget);
80
size_widget = toggle_button;
86
public Widget ButtonWidget {
87
get { return button_widget; }
97
menu.Deactivated -= OnMenuDeactivated;
100
menu.Deactivated += OnMenuDeactivated;
104
private void OnMenuDeactivated (object o, EventArgs args)
106
toggle_button.Active = false;
109
public ToggleButton ToggleButton {
110
get { return toggle_button; }
114
get { return arrow; }
117
protected override void OnSizeRequested (ref Requisition requisition)
119
requisition = size_widget.SizeRequest ();
122
protected override void OnSizeAllocated (Rectangle allocation)
124
box.SizeAllocate (allocation);
125
toggle_button.SizeAllocate (allocation);
126
base.OnSizeAllocated (allocation);
129
protected override void ForAll (bool include_internals, Callback callback)
131
callback (toggle_button);
135
protected override void OnAdded (Widget widget)
139
protected override void OnRemoved (Widget widget)
143
protected void ShowMenu ()
145
menu.Popup (null, null, PositionMenu, 1, Gtk.Global.CurrentEventTime);
148
private void PositionMenu (Menu menu, out int x, out int y, out bool push_in)
150
Gtk.Requisition menu_req = menu.SizeRequest ();
151
int monitor_num = Screen.GetMonitorAtWindow (GdkWindow);
152
Gdk.Rectangle monitor = Screen.GetMonitorGeometry (monitor_num < 0 ? 0 : monitor_num);
154
GdkWindow.GetOrigin (out x, out y);
157
x += Allocation.X + (Direction == TextDirection.Ltr
158
? Math.Max (Allocation.Width - menu_req.Width, 0)
159
: - (menu_req.Width - Allocation.Width));
161
if (y + Allocation.Height + menu_req.Height <= monitor.Y + monitor.Height) {
162
y += Allocation.Height;
163
} else if (y - menu_req.Height >= monitor.Y) {
164
y -= menu_req.Height;
165
} else if (monitor.Y + monitor.Height - (y + Allocation.Height) > y) {
166
y += Allocation.Height;
168
y -= menu_req.Height;