~paolorotolo/pinta/fix-for-1093971

« back to all changes in this revision

Viewing changes to Pinta/DockLibrary/AutoHideBox.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields, Jo Shields, Iain Lane
  • Date: 2010-07-06 07:09:12 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100706070912-da3ughgbrph20vav
Tags: 0.4+dfsg-1
[ Jo Shields ]
* New upstream release
* +DFSG release of Pinta 0.4. Deleted files:
  + ./Pinta.Gui.Widgets/bin/Debug/Pinta.Gui.Widgets.dll
* debian/rules:
  + Switch to entirely minimal DH7 rules file, since the Automake
    wrapper for xbuild handles things we were having to do by hand
* debian/pinta.sh,
  debian/pinta.desktop,
  debian/pinta.xpm,
  debian/pinta.install:
  + Upstream now takes care of providing an icon and a .desktop file,
    and DH7 takes care of putting everything where it should be, so
    all these files have been deleted
* debian/copyright:
  + Updated (thanks to Maia Kozheva <sikon@ubuntu.com>)

[ Iain Lane ]
* [a8be0d2] Remove BD on libglade2.0-cil-dev; no longer necessary
* [41bfc27] debian/watch: Mangle version for +dfsg
* [9c1ad07] Standards-Version → 3.9.0, no changes required
* [0232079] Work around buggy upstream make clean target, fixing
  double build

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// AutoHideBox.cs
 
3
//
 
4
// Author:
 
5
//   Lluis Sanchez Gual
 
6
//
 
7
 
 
8
//
 
9
// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
 
10
//
 
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:
 
18
// 
 
19
// The above copyright notice and this permission notice shall be
 
20
// included in all copies or substantial portions of the Software.
 
21
// 
 
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.
 
29
//
 
30
 
 
31
using System;
 
32
using Gtk;
 
33
using Gdk;
 
34
 
 
35
namespace MonoDevelop.Components.Docking
 
36
{
 
37
        class AutoHideBox: DockFrameTopLevel
 
38
        {
 
39
                static Gdk.Cursor resizeCursorW = new Gdk.Cursor (Gdk.CursorType.SbHDoubleArrow);
 
40
                static Gdk.Cursor resizeCursorH = new Gdk.Cursor (Gdk.CursorType.SbVDoubleArrow);
 
41
                
 
42
                bool resizing;
 
43
                int resizePos;
 
44
                int origSize;
 
45
                int origPos;
 
46
                bool horiz;
 
47
                bool startPos;
 
48
                DockFrame frame;
 
49
                bool animating;
 
50
                int targetSize;
 
51
                int targetPos;
 
52
                ScrollableContainer scrollable;
 
53
                Gtk.PositionType position;
 
54
                bool disposed;
 
55
                bool insideGrip;
 
56
                
 
57
                const int gripSize = 8;
 
58
                
 
59
                public AutoHideBox (DockFrame frame, DockItem item, Gtk.PositionType pos, int size)
 
60
                {
 
61
                        this.position = pos;
 
62
                        this.frame = frame;
 
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;
 
67
                        
 
68
                        Box fr;
 
69
                        CustomFrame cframe = new CustomFrame ();
 
70
                        switch (pos) {
 
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;
 
75
                        }
 
76
                        EventBox sepBox = new EventBox ();
 
77
                        cframe.Add (sepBox);
 
78
                        
 
79
                        if (horiz) {
 
80
                                fr = new HBox ();
 
81
                                sepBox.Realized += delegate { sepBox.GdkWindow.Cursor = resizeCursorW; };
 
82
                                sepBox.WidthRequest = gripSize;
 
83
                        } else {
 
84
                                fr = new VBox ();
 
85
                                sepBox.Realized += delegate { sepBox.GdkWindow.Cursor = resizeCursorH; };
 
86
                                sepBox.HeightRequest = gripSize;
 
87
                        }
 
88
                        
 
89
                        sepBox.Events = EventMask.AllEventsMask;
 
90
                        
 
91
                        if (pos == PositionType.Left || pos == PositionType.Top)
 
92
                                fr.PackEnd (cframe, false, false, 0);
 
93
                        else
 
94
                                fr.PackStart (cframe, false, false, 0);
 
95
 
 
96
                        Add (fr);
 
97
                        ShowAll ();
 
98
                        Hide ();
 
99
                        
 
100
                        scrollable = new ScrollableContainer ();
 
101
                        scrollable.ScrollMode = false;
 
102
                        scrollable.Show ();
 
103
 
 
104
                        item.Widget.Show ();
 
105
                        scrollable.Add (item.Widget);
 
106
                        fr.PackStart (scrollable, true, true, 0);
 
107
                        
 
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 (); };
 
114
                }
 
115
                
 
116
                public bool Disposed {
 
117
                        get { return disposed; }
 
118
                        set { disposed = value; }
 
119
                }
 
120
                
 
121
                public void AnimateShow ()
 
122
                {
 
123
                        animating = true;
 
124
                        scrollable.ScrollMode = true;
 
125
                        scrollable.SetSize (position, targetSize);
 
126
                        
 
127
                        switch (position) {
 
128
                        case PositionType.Left:
 
129
                                WidthRequest = 0;
 
130
                                break;
 
131
                        case PositionType.Right:
 
132
                                targetPos = X = X + WidthRequest;
 
133
                                WidthRequest = 0;
 
134
                                break;
 
135
                        case PositionType.Top:
 
136
                                HeightRequest = 0;
 
137
                                break;
 
138
                        case PositionType.Bottom:
 
139
                                targetPos = Y = Y + HeightRequest;
 
140
                                HeightRequest = 0;
 
141
                                break;
 
142
                        }
 
143
                        Show ();
 
144
                        GLib.Timeout.Add (10, RunAnimateShow);
 
145
                }
 
146
                
 
147
                protected override void OnShown ()
 
148
                {
 
149
                        base.OnShown ();
 
150
                }
 
151
 
 
152
                
 
153
                public void AnimateHide ()
 
154
                {
 
155
                        animating = true;
 
156
                        scrollable.ScrollMode = true;
 
157
                        scrollable.SetSize (position, targetSize);
 
158
                        GLib.Timeout.Add (10, RunAnimateHide);
 
159
                }
 
160
                
 
161
                bool RunAnimateShow ()
 
162
                {
 
163
                        if (!animating)
 
164
                                return false;
 
165
 
 
166
                        switch (position) {
 
167
                        case PositionType.Left:
 
168
                                WidthRequest += 1 + (targetSize - WidthRequest) / 3;
 
169
                                if (WidthRequest < targetSize)
 
170
                                        return true;
 
171
                                break;
 
172
                        case PositionType.Right:
 
173
                                WidthRequest += 1 + (targetSize - WidthRequest) / 3;
 
174
                                X = targetPos - WidthRequest;
 
175
                                if (WidthRequest < targetSize)
 
176
                                        return true;
 
177
                                break;
 
178
                        case PositionType.Top:
 
179
                                HeightRequest += 1 + (targetSize - HeightRequest) / 3;
 
180
                                if (HeightRequest < targetSize)
 
181
                                        return true;
 
182
                                break;
 
183
                        case PositionType.Bottom:
 
184
                                HeightRequest += 1 + (targetSize - HeightRequest) / 3;
 
185
                                Y = targetPos - HeightRequest;
 
186
                                if (HeightRequest < targetSize)
 
187
                                        return true;
 
188
                                break;
 
189
                        }
 
190
                        
 
191
                        scrollable.ScrollMode = false;
 
192
                        if (horiz)
 
193
                                WidthRequest = targetSize;
 
194
                        else
 
195
                                HeightRequest = targetSize;
 
196
                        animating = false;
 
197
                        return false;
 
198
                }
 
199
                
 
200
                bool RunAnimateHide ()
 
201
                {
 
202
                        if (!animating)
 
203
                                return false;
 
204
 
 
205
                        switch (position) {
 
206
                        case PositionType.Left: {
 
207
                                int ns = WidthRequest - 1 - WidthRequest / 3;
 
208
                                if (ns > 0) {
 
209
                                        WidthRequest = ns;
 
210
                                        return true;
 
211
                                }
 
212
                                break;
 
213
                        }
 
214
                        case PositionType.Right: {
 
215
                                int ns = WidthRequest - 1 - WidthRequest / 3;
 
216
                                if (ns > 0) {
 
217
                                        WidthRequest = ns;
 
218
                                        X = targetPos - ns;
 
219
                                        return true;
 
220
                                }
 
221
                                break;
 
222
                        }
 
223
                        case PositionType.Top: {
 
224
                                int ns = HeightRequest - 1 - HeightRequest / 3;
 
225
                                if (ns > 0) {
 
226
                                        HeightRequest = ns;
 
227
                                        return true;
 
228
                                }
 
229
                                break;
 
230
                        }
 
231
                        case PositionType.Bottom: {
 
232
                                int ns = HeightRequest - 1 - HeightRequest / 3;
 
233
                                if (ns > 0) {
 
234
                                        HeightRequest = ns;
 
235
                                        Y = targetPos - ns;
 
236
                                        return true;
 
237
                                }
 
238
                                break;
 
239
                        }
 
240
                        }
 
241
 
 
242
                        Hide ();
 
243
                        animating = false;
 
244
                        return false;
 
245
                }
 
246
                
 
247
                protected override void OnHidden ()
 
248
                {
 
249
                        base.OnHidden ();
 
250
                        animating = false;
 
251
                }
 
252
 
 
253
                
 
254
                public int Size {
 
255
                        get {
 
256
                                return horiz ? WidthRequest : HeightRequest;
 
257
                        }
 
258
                }
 
259
                
 
260
                void OnSizeButtonPress (object ob, Gtk.ButtonPressEventArgs args)
 
261
                {
 
262
                        if (args.Event.Button == 1 && !animating) {
 
263
                                int n;
 
264
                                if (horiz) {
 
265
                                        Toplevel.GetPointer (out resizePos, out n);
 
266
                                        origSize = WidthRequest;
 
267
                                        if (!startPos) {
 
268
                                                origPos = X + origSize;
 
269
                                        }
 
270
                                } else {
 
271
                                        Toplevel.GetPointer (out n, out resizePos);
 
272
                                        origSize = HeightRequest;
 
273
                                        if (!startPos) {
 
274
                                                origPos = Y + origSize;
 
275
                                        }
 
276
                                }
 
277
                                resizing = true;
 
278
                        }
 
279
                }
 
280
                
 
281
                void OnSizeButtonRelease (object ob, Gtk.ButtonReleaseEventArgs args)
 
282
                {
 
283
                        resizing = false;
 
284
                }
 
285
                
 
286
                void OnSizeMotion (object ob, Gtk.MotionNotifyEventArgs args)
 
287
                {
 
288
                        if (resizing) {
 
289
                                int newPos, n;
 
290
                                if (horiz) {
 
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;
 
296
                                        if (!startPos) {
 
297
                                                X = origPos - newSize;
 
298
                                        }
 
299
                                        WidthRequest = newSize;
 
300
                                } else {
 
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;
 
306
                                        if (!startPos) {
 
307
                                                Y = origPos - newSize;
 
308
                                        }
 
309
                                        HeightRequest = newSize;
 
310
                                }
 
311
                                frame.QueueResize ();
 
312
                        }
 
313
                }
 
314
                
 
315
                void OnGripExpose (object ob, Gtk.ExposeEventArgs args)
 
316
                {
 
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;
 
321
                        
 
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);
 
326
                                break;
 
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);
 
330
                                break;
 
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);
 
334
                                break;
 
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);
 
338
                                break;
 
339
                        }*/
 
340
                        
 
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);
 
344
                }
 
345
        }
 
346
        
 
347
        class ScrollableContainer: EventBox
 
348
        {
 
349
                PositionType expandPos;
 
350
                bool scrollMode;
 
351
                int targetSize;
 
352
                
 
353
                public bool ScrollMode {
 
354
                        get {
 
355
                                return scrollMode;
 
356
                        }
 
357
                        set {
 
358
                                scrollMode = value;
 
359
                                QueueResize ();
 
360
                        }
 
361
                }
 
362
                
 
363
                public void SetSize (PositionType expandPosition, int targetSize)
 
364
                {
 
365
                        this.expandPos = expandPosition;
 
366
                        this.targetSize = targetSize;
 
367
                        QueueResize ();
 
368
                }
 
369
                
 
370
                protected override void OnSizeRequested (ref Requisition req)
 
371
                {
 
372
                        base.OnSizeRequested (ref req);
 
373
                        if (scrollMode || Child == null) {
 
374
                                req.Width = 0;
 
375
                                req.Height = 0;
 
376
                        }
 
377
                        else
 
378
                                req = Child.SizeRequest ();
 
379
                }
 
380
 
 
381
                protected override void OnSizeAllocated (Rectangle alloc)
 
382
                {
 
383
                        if (scrollMode && Child != null) {
 
384
                                switch (expandPos) {
 
385
                                case PositionType.Bottom:
 
386
                                        alloc = new Rectangle (alloc.X, alloc.Y, alloc.Width, targetSize);
 
387
                                        break;
 
388
                                case PositionType.Top:
 
389
                                        alloc = new Rectangle (alloc.X, alloc.Y - targetSize + alloc.Height, alloc.Width, targetSize);
 
390
                                        break;
 
391
                                case PositionType.Right:
 
392
                                        alloc = new Rectangle (alloc.X, alloc.Y, targetSize, alloc.Height);
 
393
                                        break;
 
394
                                case PositionType.Left:
 
395
                                        alloc = new Rectangle (alloc.X - targetSize + alloc.Width, alloc.Y, targetSize, alloc.Height);
 
396
                                        break;
 
397
                                }
 
398
                        }
 
399
                        base.OnSizeAllocated (alloc);
 
400
                }
 
401
        }
 
402
 
 
403
}