9
// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
11
// Permission is hereby granted, free of charge, to any person obtaining
12
// a copy of this software and associated documentation files (the
13
// "Software"), to deal in the Software without restriction, including
14
// without limitation the rights to use, copy, modify, merge, publish,
15
// distribute, sublicense, and/or sell copies of the Software, and to
16
// permit persons to whom the Software is furnished to do so, subject to
17
// the following conditions:
19
// The above copyright notice and this permission notice shall be
20
// included in all copies or substantial portions of the Software.
22
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
namespace MonoDevelop.Components.Docking
37
class AutoHideBox: DockFrameTopLevel
39
static Gdk.Cursor resizeCursorW = new Gdk.Cursor (Gdk.CursorType.SbHDoubleArrow);
40
static Gdk.Cursor resizeCursorH = new Gdk.Cursor (Gdk.CursorType.SbVDoubleArrow);
52
ScrollableContainer scrollable;
53
Gtk.PositionType position;
57
const int gripSize = 8;
59
public AutoHideBox (DockFrame frame, DockItem item, Gtk.PositionType pos, int size)
63
this.targetSize = size;
64
horiz = pos == PositionType.Left || pos == PositionType.Right;
65
startPos = pos == PositionType.Top || pos == PositionType.Left;
66
Events = Events | Gdk.EventMask.EnterNotifyMask | Gdk.EventMask.LeaveNotifyMask;
69
CustomFrame cframe = new CustomFrame ();
71
case PositionType.Left: cframe.SetMargins (1, 1, 0, 1); break;
72
case PositionType.Right: cframe.SetMargins (1, 1, 1, 0); break;
73
case PositionType.Top: cframe.SetMargins (0, 1, 1, 1); break;
74
case PositionType.Bottom: cframe.SetMargins (1, 0, 1, 1); break;
76
EventBox sepBox = new EventBox ();
81
sepBox.Realized += delegate { sepBox.GdkWindow.Cursor = resizeCursorW; };
82
sepBox.WidthRequest = gripSize;
85
sepBox.Realized += delegate { sepBox.GdkWindow.Cursor = resizeCursorH; };
86
sepBox.HeightRequest = gripSize;
89
sepBox.Events = EventMask.AllEventsMask;
91
if (pos == PositionType.Left || pos == PositionType.Top)
92
fr.PackEnd (cframe, false, false, 0);
94
fr.PackStart (cframe, false, false, 0);
100
scrollable = new ScrollableContainer ();
101
scrollable.ScrollMode = false;
105
scrollable.Add (item.Widget);
106
fr.PackStart (scrollable, true, true, 0);
108
sepBox.ButtonPressEvent += OnSizeButtonPress;
109
sepBox.ButtonReleaseEvent += OnSizeButtonRelease;
110
sepBox.MotionNotifyEvent += OnSizeMotion;
111
sepBox.ExposeEvent += OnGripExpose;
112
sepBox.EnterNotifyEvent += delegate { insideGrip = true; sepBox.QueueDraw (); };
113
sepBox.LeaveNotifyEvent += delegate { insideGrip = false; sepBox.QueueDraw (); };
116
public bool Disposed {
117
get { return disposed; }
118
set { disposed = value; }
121
public void AnimateShow ()
124
scrollable.ScrollMode = true;
125
scrollable.SetSize (position, targetSize);
128
case PositionType.Left:
131
case PositionType.Right:
132
targetPos = X = X + WidthRequest;
135
case PositionType.Top:
138
case PositionType.Bottom:
139
targetPos = Y = Y + HeightRequest;
144
GLib.Timeout.Add (10, RunAnimateShow);
147
protected override void OnShown ()
153
public void AnimateHide ()
156
scrollable.ScrollMode = true;
157
scrollable.SetSize (position, targetSize);
158
GLib.Timeout.Add (10, RunAnimateHide);
161
bool RunAnimateShow ()
167
case PositionType.Left:
168
WidthRequest += 1 + (targetSize - WidthRequest) / 3;
169
if (WidthRequest < targetSize)
172
case PositionType.Right:
173
WidthRequest += 1 + (targetSize - WidthRequest) / 3;
174
X = targetPos - WidthRequest;
175
if (WidthRequest < targetSize)
178
case PositionType.Top:
179
HeightRequest += 1 + (targetSize - HeightRequest) / 3;
180
if (HeightRequest < targetSize)
183
case PositionType.Bottom:
184
HeightRequest += 1 + (targetSize - HeightRequest) / 3;
185
Y = targetPos - HeightRequest;
186
if (HeightRequest < targetSize)
191
scrollable.ScrollMode = false;
193
WidthRequest = targetSize;
195
HeightRequest = targetSize;
200
bool RunAnimateHide ()
206
case PositionType.Left: {
207
int ns = WidthRequest - 1 - WidthRequest / 3;
214
case PositionType.Right: {
215
int ns = WidthRequest - 1 - WidthRequest / 3;
223
case PositionType.Top: {
224
int ns = HeightRequest - 1 - HeightRequest / 3;
231
case PositionType.Bottom: {
232
int ns = HeightRequest - 1 - HeightRequest / 3;
247
protected override void OnHidden ()
256
return horiz ? WidthRequest : HeightRequest;
260
void OnSizeButtonPress (object ob, Gtk.ButtonPressEventArgs args)
262
if (args.Event.Button == 1 && !animating) {
265
Toplevel.GetPointer (out resizePos, out n);
266
origSize = WidthRequest;
268
origPos = X + origSize;
271
Toplevel.GetPointer (out n, out resizePos);
272
origSize = HeightRequest;
274
origPos = Y + origSize;
281
void OnSizeButtonRelease (object ob, Gtk.ButtonReleaseEventArgs args)
286
void OnSizeMotion (object ob, Gtk.MotionNotifyEventArgs args)
291
Toplevel.GetPointer (out newPos, out n);
292
int diff = startPos ? (newPos - resizePos) : (resizePos - newPos);
293
int newSize = origSize + diff;
294
if (newSize < Child.SizeRequest ().Width)
295
newSize = Child.SizeRequest ().Width;
297
X = origPos - newSize;
299
WidthRequest = newSize;
301
Toplevel.GetPointer (out n, out newPos);
302
int diff = startPos ? (newPos - resizePos) : (resizePos - newPos);
303
int newSize = origSize + diff;
304
if (newSize < Child.SizeRequest ().Height)
305
newSize = Child.SizeRequest ().Height;
307
Y = origPos - newSize;
309
HeightRequest = newSize;
311
frame.QueueResize ();
315
void OnGripExpose (object ob, Gtk.ExposeEventArgs args)
317
EventBox w = (EventBox) ob;
318
Gdk.Rectangle handleRect = w.Allocation;
319
// w.GdkWindow.DrawRectangle (w.Style.DarkGC (StateType.Normal), true, handleRect);
320
handleRect.X = handleRect.Y = 0;
322
/* switch (position) {
323
case PositionType.Top:
324
handleRect.Height -= 4; handleRect.Y += 1;
325
Gtk.Style.PaintHline (w.Style, w.GdkWindow, StateType.Normal, args.Event.Area, w, "", 0, w.Allocation.Width, gripSize - 2);
327
case PositionType.Bottom:
328
handleRect.Height -= 4; handleRect.Y += 3;
329
Gtk.Style.PaintHline (w.Style, w.GdkWindow, StateType.Normal, args.Event.Area, w, "", 0, w.Allocation.Width, 0);
331
case PositionType.Left:
332
handleRect.Width -= 4; handleRect.X += 1;
333
Gtk.Style.PaintVline (w.Style, w.GdkWindow, StateType.Normal, args.Event.Area, w, "", 0, w.Allocation.Height, gripSize - 2);
335
case PositionType.Right:
336
handleRect.Width -= 4; handleRect.X += 3;
337
Gtk.Style.PaintVline (w.Style, w.GdkWindow, StateType.Normal, args.Event.Area, w, "", 0, w.Allocation.Height, 0);
341
Orientation or = horiz ? Orientation.Vertical : Orientation.Horizontal;
342
StateType s = insideGrip ? StateType.Prelight : StateType.Normal;
343
Gtk.Style.PaintHandle (w.Style, w.GdkWindow, s, ShadowType.None, args.Event.Area, w, "paned", handleRect.Left, handleRect.Top, handleRect.Width, handleRect.Height, or);
347
class ScrollableContainer: EventBox
349
PositionType expandPos;
353
public bool ScrollMode {
363
public void SetSize (PositionType expandPosition, int targetSize)
365
this.expandPos = expandPosition;
366
this.targetSize = targetSize;
370
protected override void OnSizeRequested (ref Requisition req)
372
base.OnSizeRequested (ref req);
373
if (scrollMode || Child == null) {
378
req = Child.SizeRequest ();
381
protected override void OnSizeAllocated (Rectangle alloc)
383
if (scrollMode && Child != null) {
385
case PositionType.Bottom:
386
alloc = new Rectangle (alloc.X, alloc.Y, alloc.Width, targetSize);
388
case PositionType.Top:
389
alloc = new Rectangle (alloc.X, alloc.Y - targetSize + alloc.Height, alloc.Width, targetSize);
391
case PositionType.Right:
392
alloc = new Rectangle (alloc.X, alloc.Y, targetSize, alloc.Height);
394
case PositionType.Left:
395
alloc = new Rectangle (alloc.X - targetSize + alloc.Width, alloc.Y, targetSize, alloc.Height);
399
base.OnSizeAllocated (alloc);