~ubuntu-branches/ubuntu/natty/gnome-do/natty

« back to all changes in this revision

Viewing changes to Do.Interface.Linux/src/Do.Interface/Do.Interface.AnimationBase/BezelGlassResults.cs

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers
  • Date: 2009-06-27 10:40:45 UTC
  • mfrom: (1.1.8 upstream) (0.1.5 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090627104045-7st10y1cqr6dpz37
Tags: 0.8.2+dfsg-1
* New upstream release
  + No longer uses a plugin repository.  Fixes many plugin-
    related issues. (LP: #343096, LP: #330025, LP #345001)
  + No longer blocks on "About Do" (LP: #361679)
  + Reacts correctly when a Composite manager is enabled/
    disabled at runtime. (LP: #346347, LP: #390150)
  + Fixes for space reserved by Docky blocking drag and 
    drop operations. (LP: #354729, LP: #347052, LP: #382843)
  + Properly sets "Hidden" key on autostart files in response to 
    "Start on login" option.  (Closes: #526023) (LP: #369988)
* debian/patches/10_application_search_path:
  + Drop; included upstream
* debian/patches/10_sk_translation_update:
  + Import sk translation update from Debian BTS.
    (Closes: #531779)
* debian/patches/11_fix_autostart_when_directory_does_not_exist:
  + Patch from upstream.  Fixes the "Start on login" option when the 
    ~/.config/autostart directory does not exist. (LP: #393729)
* debian/control:
  + Update standards version to 3.8.2; no changes required.
  + Add libtool to Build-Depends; required for autoreconf.
  + Add Recommends: on new gnome-do-docklets package.
* debian/gnome-do.1
  + Fix spelling: GNOME-Do => GNOME Do.
  + Miscelaneous lintian fixes; NAME section, escaping minus signs with \-
* debian/copyright:
  + Update for new copyright holders.
  + Minor update to DEP-5 format

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// BezelGlassResults.cs
2
 
// 
3
 
// Copyright (C) 2008 GNOME-Do
4
 
//
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.
9
 
//
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.
14
 
//
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/>.
17
 
//
18
 
 
19
 
using System;
20
 
using System.Collections.Generic;
21
 
using System.Linq;
22
 
using System.Threading;
23
 
 
24
 
using Cairo;
25
 
using Gdk;
26
 
using Gtk;
27
 
 
28
 
using Do.Interface;
29
 
using Do.Interface.CairoUtils;
30
 
using Do.Universe;
31
 
 
32
 
namespace Do.Interface.AnimationBase
33
 
{
34
 
        
35
 
        
36
 
        public class BezelGlassResults : Gtk.DrawingArea
37
 
        {
38
 
                HUDStyle style;
39
 
                IBezelResultItemRenderer ItemRenderer;
40
 
                
41
 
                const int FadeTime = 100;
42
 
                
43
 
                int num_results;
44
 
                int width, height;
45
 
                int border_width, top_border_width;
46
 
                Dictionary <Element, Surface> surface_buffer;
47
 
                Surface highlight_surface, backbuffer, child_inout_surface, triplebuffer, background;
48
 
                
49
 
                DateTime delta_time;
50
 
                double scroll_offset, highlight_offset, child_scroll_offset, slide_offset;
51
 
                int cursor, prev_cursor, delta;
52
 
                uint timer, delta_reset;
53
 
                bool visible;
54
 
                int[] secondary;
55
 
                
56
 
                IDoController controller;
57
 
                
58
 
                IUIContext context = null;
59
 
                BezelColors colors;
60
 
                
61
 
                IList<Element> results;
62
 
                
63
 
                public int X { get; set; }
64
 
                
65
 
                int BottomBorderWidth {
66
 
                        get {
67
 
                                switch (style) {
68
 
                                case HUDStyle.HUD:
69
 
                                        return 25;
70
 
                                case HUDStyle.Classic:
71
 
                                        return 20;
72
 
                                default:
73
 
                                        throw new NotImplementedException ();
74
 
                                }
75
 
                        }
76
 
                }
77
 
                
78
 
                int SurfaceHeight { get { return ItemRenderer.Height; } }
79
 
                
80
 
                private Cairo.Color BackgroundColor
81
 
                {
82
 
                        get {
83
 
                                switch (style) {
84
 
                                case HUDStyle.HUD:
85
 
                                        return colors.BackgroundDark;
86
 
                                case HUDStyle.Classic:
87
 
                                        Gdk.Color bgColor;
88
 
                                        using (Gtk.Style rcstyle = Gtk.Rc.GetStyle (this)) {
89
 
                                                bgColor = rcstyle.BaseColors[(int) StateType.Normal];
90
 
                                        }
91
 
                                        return bgColor.ConvertToCairo (1);
92
 
                                default:
93
 
                                        throw new NotImplementedException ();
94
 
                                }
95
 
                        }
96
 
                }                               
97
 
                
98
 
                public string ItemTextColor {
99
 
                        get {
100
 
                                switch (style) {
101
 
                                case HUDStyle.HUD:
102
 
                                        return "ffffff";
103
 
                                case HUDStyle.Classic:
104
 
                                        Gdk.Color bgColor;
105
 
                                        using (Gtk.Style rcstyle = Gtk.Rc.GetStyle (this)) {
106
 
                                                bgColor = rcstyle.TextColors[(int) StateType.Normal];
107
 
                                        }
108
 
                                        return bgColor.ColorToHexString ();
109
 
                                default:
110
 
                                        throw new NotImplementedException ();
111
 
                                }
112
 
                        }
113
 
                }
114
 
                
115
 
                public string QueryColor {
116
 
                        get {
117
 
                                switch (style) {
118
 
                                case HUDStyle.HUD:
119
 
                                        return "dddddd";
120
 
                                case HUDStyle.Classic:
121
 
                                        return "777777";
122
 
                                default:
123
 
                                        throw new NotImplementedException ();
124
 
                                }
125
 
                        }
126
 
                }
127
 
                
128
 
                public IList<Element> Results {
129
 
                        get {
130
 
                                return results;
131
 
                        }
132
 
                        set {
133
 
                                if (results != null && value != null && results.GetHashCode () == value.GetHashCode ())
134
 
                                        return;
135
 
                                results = value;
136
 
                                scroll_offset = 0;
137
 
                                highlight_offset = 0;
138
 
                        }
139
 
                }
140
 
                
141
 
                public int Cursor {
142
 
                        get {
143
 
                                return cursor;
144
 
                        }
145
 
                        set {
146
 
                                if (cursor == value)
147
 
                                        return;
148
 
                                
149
 
                                int oldStart = StartResult;
150
 
                                prev_cursor = cursor;
151
 
                                cursor = value;
152
 
                                if (oldStart == StartResult) {
153
 
                                        highlight_offset -= value-prev_cursor;
154
 
                                } else {
155
 
                                        scroll_offset += value-prev_cursor;
156
 
                                }
157
 
                                delta++;
158
 
                        }
159
 
                }
160
 
                
161
 
                private int StartResult {
162
 
                        get {
163
 
                                int result = Math.Max (Cursor - (num_results / 2), 0);
164
 
                                if (results == null)
165
 
                                        return 0;
166
 
                                while (result+num_results > results.Count && result > 1)
167
 
                                        result--;
168
 
                                return result;
169
 
                        }
170
 
                }
171
 
                
172
 
                private bool AnimationNeeded {
173
 
                        get {
174
 
                                return CursorMoveNeeded || ScrollNeeded || ChildScrollNeeded || SlideNeeded;
175
 
                        }
176
 
                }
177
 
                
178
 
                private bool CursorMoveNeeded {
179
 
                        get {
180
 
                                return highlight_offset != 0;
181
 
                        }
182
 
                }
183
 
                
184
 
                private bool ScrollNeeded {
185
 
                        get {
186
 
                                return scroll_offset != 0;
187
 
                        }
188
 
                }
189
 
                
190
 
                private bool ChildScrollNeeded {
191
 
                        get {
192
 
                                return child_scroll_offset != 0;
193
 
                        }
194
 
                }
195
 
                
196
 
                private bool SlideNeeded {
197
 
                        get {
198
 
                                return (visible && slide_offset != 1 || !visible && slide_offset != 0);
199
 
                        }
200
 
                }
201
 
                
202
 
                public IUIContext Context
203
 
                {
204
 
                        set {
205
 
                                IUIContext tmp = context;
206
 
                                context = value;
207
 
                                
208
 
                                if (!Visible)
209
 
                                        return;
210
 
 
211
 
                                if (value == null || !value.Results.Any ()) {
212
 
                                        Clear ();
213
 
                                        return;
214
 
                                }
215
 
                                
216
 
                                if (tmp != null) {
217
 
                                        if (context.ParentContext != null && tmp != null &&
218
 
                                            context.ParentContext.Query == tmp.Query && 
219
 
                                            tmp.Results.GetHashCode () == context.ParentContext.Results.GetHashCode ()) {
220
 
                                                InitChildInAnimation ();
221
 
                                        } else if (tmp.ParentContext != null && context != null &&
222
 
                                                   tmp.ParentContext.Query == context.Query && 
223
 
                                                   tmp.ParentContext.Results.GetHashCode () == context.Results.GetHashCode ()) {
224
 
                                                InitChildOutAnimation ();
225
 
                                        }
226
 
                                }
227
 
                                
228
 
                                Cursor = value.Cursor;
229
 
                                Results = value.Results;
230
 
                                Secondary = value.SecondaryCursors;
231
 
                                if (visible)
232
 
                                        Draw ();
233
 
                        }
234
 
                }
235
 
                
236
 
                private int InternalWidth {
237
 
                        get {
238
 
                                return width - 2*border_width;
239
 
                        }
240
 
                }
241
 
 
242
 
                public int[] Secondary {
243
 
                        get {
244
 
                                return secondary;
245
 
                        }
246
 
                        set {
247
 
                                bool ident = true;
248
 
                                if (secondary.Length == value.Length) {
249
 
                                        for (int i = 0; i<secondary.Length; i++) {
250
 
                                                if (secondary[i] != value[i]) {
251
 
                                                        ident = false;
252
 
                                                        break;
253
 
                                                }
254
 
                                        }
255
 
                                } else {
256
 
                                        ident = false;
257
 
                                }
258
 
                                if (ident)
259
 
                                        return;
260
 
                                foreach (Surface s in surface_buffer.Values)
261
 
                                        s.Destroy ();
262
 
                                surface_buffer.Clear ();
263
 
                                secondary = value;
264
 
                        }
265
 
                }
266
 
                
267
 
                public BezelGlassResults(IDoController controller, int width, HUDStyle style, BezelColors colors) : base ()
268
 
                {
269
 
                        this.controller = controller;
270
 
                        this.style = style;
271
 
                        this.colors = colors;
272
 
                        switch (style) {
273
 
                        case HUDStyle.Classic:
274
 
                                ItemRenderer = new BezelFullResultItemRenderer (this);
275
 
                                num_results = 5;
276
 
                                break;
277
 
                        case HUDStyle.HUD:
278
 
                                ItemRenderer = new BezelHalfResultItemRenderer (this);
279
 
                                num_results = 8;
280
 
                                break;
281
 
                        }
282
 
                        
283
 
                        surface_buffer = new Dictionary <Element,Surface> ();
284
 
                        secondary = new int[0];
285
 
                        border_width = 12;
286
 
                        top_border_width = 20;
287
 
                        this.width = width;
288
 
                        height = num_results * SurfaceHeight + top_border_width + BottomBorderWidth;
289
 
                        SetSizeRequest (width, height);
290
 
                        
291
 
                        DoubleBuffered = false;
292
 
                        
293
 
                        this.Shown += delegate {
294
 
                                Context = context;
295
 
                                Draw ();
296
 
                        };
297
 
                        
298
 
                        BezelDrawingArea.ThemeChanged += delegate {
299
 
                                if (background != null)
300
 
                                        background.Destroy ();
301
 
                                if (highlight_surface != null)
302
 
                                        highlight_surface.Destroy ();
303
 
                                if (child_inout_surface != null)
304
 
                                        child_inout_surface.Destroy ();
305
 
                                if (triplebuffer != null)
306
 
                                        triplebuffer.Destroy ();
307
 
                                if (backbuffer != null)
308
 
                                        backbuffer.Destroy ();
309
 
                                
310
 
                                highlight_surface = backbuffer = child_inout_surface = triplebuffer = background = null;
311
 
                        };
312
 
                        
313
 
                        Realized += delegate {
314
 
                                this.GdkWindow.SetBackPixmap (null, false);
315
 
                        };
316
 
                        
317
 
                        StyleSet += delegate {
318
 
                                if (IsRealized)
319
 
                                        GdkWindow.SetBackPixmap (null, false);
320
 
                        };
321
 
                }
322
 
                
323
 
                private void AnimatedDraw ()
324
 
                {
325
 
                        if (!IsDrawable || timer > 0) return;
326
 
                        
327
 
                        Paint ();
328
 
                        
329
 
                        if (!AnimationNeeded)
330
 
                                return;
331
 
                        
332
 
                        delta_time = DateTime.Now;
333
 
                        timer = GLib.Timeout.Add (1000/100, delegate {
334
 
                                double change = (BezelDrawingArea.Animated) ? DateTime.Now.Subtract (delta_time).TotalMilliseconds / FadeTime : 10;
335
 
                                delta_time = DateTime.Now;
336
 
                                
337
 
                                double move = Math.Max (change*delta, change);
338
 
                                
339
 
                                if (ScrollNeeded) {
340
 
                                        if (scroll_offset > 0)
341
 
                                                scroll_offset = Math.Max (0, scroll_offset - move);
342
 
                                        else
343
 
                                                scroll_offset = Math.Min (0, scroll_offset + move);
344
 
                                }
345
 
                                
346
 
                                if (CursorMoveNeeded) {
347
 
                                        if (highlight_offset > 0)
348
 
                                                highlight_offset = Math.Max (0, highlight_offset - move);
349
 
                                        else
350
 
                                                highlight_offset = Math.Min (0, highlight_offset + move);
351
 
                                }
352
 
                                
353
 
                                if (ChildScrollNeeded) {
354
 
                                        if (child_scroll_offset > 0)
355
 
                                                child_scroll_offset = Math.Max (0, child_scroll_offset - change*0.7);
356
 
                                        else
357
 
                                                child_scroll_offset = Math.Min (0, child_scroll_offset + change*0.7);
358
 
                                }
359
 
                                
360
 
                                if (SlideNeeded) {
361
 
                                        if (visible)
362
 
                                                slide_offset = Math.Min (1, slide_offset + change*0.7);
363
 
                                        else
364
 
                                                slide_offset = Math.Max (0, slide_offset - change*0.7);
365
 
                                }
366
 
                                
367
 
                                Paint ();
368
 
                                
369
 
                                if (!AnimationNeeded) {
370
 
                                        timer = 0;
371
 
                                        if (delta_reset > 0)
372
 
                                                GLib.Source.Remove (delta_reset);
373
 
                                        delta_reset = GLib.Timeout.Add (50, delegate {
374
 
                                                if (timer == 0)
375
 
                                                        delta = 0;
376
 
                                                delta_reset = 0;
377
 
                                                return false;
378
 
                                        });
379
 
                                        return false;
380
 
                                }
381
 
                                return true;
382
 
                        });
383
 
                }
384
 
                
385
 
                public void Clear ()
386
 
                {
387
 
                        Results = null;
388
 
                        Cursor = 0;
389
 
                        context = null;
390
 
                        foreach (Surface s in surface_buffer.Values)
391
 
                                s.Destroy ();
392
 
                        
393
 
                        surface_buffer = new Dictionary<Element,Surface> ();
394
 
                        Draw ();
395
 
                }
396
 
                
397
 
                private void Paint ()
398
 
                {
399
 
                        if (!IsDrawable) return;
400
 
//                      DateTime time = DateTime.Now;
401
 
                        Context cr = Gdk.CairoHelper.Create (GdkWindow);
402
 
                        
403
 
                        if (slide_offset == 0) {
404
 
                                cr.Operator = Operator.Source;
405
 
                                cr.Color = new Cairo.Color (0, 0, 0, 0);
406
 
                                cr.Paint ();
407
 
                                (cr as IDisposable).Dispose ();
408
 
                                return;
409
 
                        }
410
 
                        
411
 
                        if (backbuffer == null)
412
 
                                backbuffer = cr.Target.CreateSimilar (cr.Target.Content, width, height);
413
 
                        
414
 
                        
415
 
                        DrawContextOnSurface (backbuffer);
416
 
                        if (child_scroll_offset == 0) {
417
 
                                cr.SetSource (backbuffer, X, -(height*(1-slide_offset)));
418
 
                                cr.Operator = Operator.Source;
419
 
                                cr.Paint ();
420
 
                        } else {
421
 
                                if (triplebuffer == null) {
422
 
                                        triplebuffer = cr.Target.CreateSimilar (cr.Target.Content, width, height);
423
 
                                }
424
 
                                
425
 
                                int old_x, new_x;
426
 
                                if (child_scroll_offset > 0) {
427
 
                                        old_x = (int)(-width*(1-child_scroll_offset));
428
 
                                        new_x = old_x+width;
429
 
                                } else {
430
 
                                        old_x = (int)(-width*(-1-child_scroll_offset));
431
 
                                        new_x = old_x-width;
432
 
                                }
433
 
                                
434
 
                                DrawSlideContexts (child_inout_surface, backbuffer, triplebuffer, old_x, new_x);
435
 
 
436
 
                                cr.SetSource (triplebuffer, X, - (height * (1 - slide_offset)));
437
 
                                cr.Operator = Operator.Source;
438
 
                                cr.Paint ();
439
 
                        }
440
 
                        
441
 
                        (cr as IDisposable).Dispose ();
442
 
                }
443
 
                
444
 
                /// <summary>
445
 
                /// Draws two surfaces offset onto a singel surface.  Useful for making left/right slide animations
446
 
                /// </summary>
447
 
                /// <param name="old_surface">
448
 
                /// A <see cref="Surface"/>
449
 
                /// </param>
450
 
                /// <param name="new_surface">
451
 
                /// A <see cref="Surface"/>
452
 
                /// </param>
453
 
                /// <param name="target_surface">
454
 
                /// A <see cref="Surface"/>
455
 
                /// </param>
456
 
                /// <param name="old_x">
457
 
                /// A <see cref="System.Int32"/>
458
 
                /// </param>
459
 
                /// <param name="new_x">
460
 
                /// A <see cref="System.Int32"/>
461
 
                /// </param>
462
 
                private void DrawSlideContexts (Surface old_surface, Surface new_surface, Surface target_surface,
463
 
                                                int old_x, int new_x)
464
 
                {
465
 
                        Context cr = new Context (target_surface);
466
 
                        cr.Operator = Operator.Source;
467
 
 
468
 
                        // redraw our top and bottom border separately.  This makes the slide only appear to affect
469
 
                        // the center.
470
 
                        cr.Rectangle (0, 0, width, top_border_width);
471
 
                        cr.Rectangle (0, height-BottomBorderWidth, width, BottomBorderWidth);
472
 
                        cr.SetSource (new_surface, 0, 0);
473
 
                        cr.Fill ();
474
 
                        
475
 
                        cr.Rectangle (0, top_border_width, width, height-top_border_width-BottomBorderWidth);
476
 
                        cr.SetSource (old_surface, old_x, 0);
477
 
                        cr.FillPreserve ();
478
 
                        
479
 
                        cr.Operator = Operator.Over;
480
 
                        cr.SetSource (new_surface, new_x, 0);
481
 
                        cr.FillPreserve ();
482
 
                        
483
 
                        (cr as IDisposable).Dispose ();
484
 
                }
485
 
                
486
 
                /// <summary>
487
 
                /// Draws a header.  Currently this relies on being drown on top of the background surface to
488
 
                /// look correct
489
 
                /// </summary>
490
 
                /// <param name="cr">
491
 
                /// A <see cref="Context"/>
492
 
                /// </param>
493
 
                /// <param name="radius">
494
 
                /// A <see cref="System.Int32"/>
495
 
                /// </param>
496
 
                private void DrawHeaderOnContext (Context cr, int radius)
497
 
                {
498
 
                        switch (style) {
499
 
                        case HUDStyle.HUD:
500
 
                                cr.MoveTo (0 + radius, 0);
501
 
                                cr.Arc (0 + width - radius, 0 + radius, radius, Math.PI*1.5, Math.PI*2);
502
 
                                cr.LineTo (0 + width, 0 + top_border_width);
503
 
                                cr.LineTo (0, 0 + top_border_width);
504
 
                                cr.Arc (0 + radius, 0 + radius, radius, Math.PI, Math.PI*1.5);
505
 
                                LinearGradient title_grad = new LinearGradient (0, 0, 0, top_border_width);
506
 
                                title_grad.AddColorStop (0.0, colors.TitleBarGlossLight);
507
 
                                title_grad.AddColorStop (0.5, colors.TitleBarGlossDark);
508
 
                                title_grad.AddColorStop (0.5, colors.TitleBarBase);
509
 
                                cr.Pattern = title_grad;
510
 
                                cr.Fill ();
511
 
                                title_grad.Destroy ();
512
 
                                break;
513
 
                        case HUDStyle.Classic:
514
 
                                cr.Rectangle (0.5, -0.5, width-1, top_border_width);
515
 
                                LinearGradient title_grad1 = new LinearGradient (0, 0, 0, top_border_width);
516
 
                                title_grad1.AddColorStop (0, new Cairo.Color (0.75, 0.75, 0.75));
517
 
                                title_grad1.AddColorStop (1, new Cairo.Color (0.95, 0.95, 0.95));
518
 
                                cr.Pattern = title_grad1;
519
 
                                cr.FillPreserve ();
520
 
                                title_grad1.Destroy ();
521
 
                                
522
 
                                cr.LineWidth = 1;
523
 
                                cr.Color = new Cairo.Color (0.3, 0.3, 0.3, 0.5);
524
 
                                cr.Stroke ();
525
 
                                break;
526
 
                        }
527
 
                }
528
 
                
529
 
                /// <summary>
530
 
                /// Draws a footer.  Currently this relies on being drawn on top of the background surface to
531
 
                /// look correct
532
 
                /// </summary>
533
 
                /// <param name="cr">
534
 
                /// A <see cref="Context"/>
535
 
                /// </param>
536
 
                /// <param name="radius">
537
 
                /// A <see cref="System.Int32"/>
538
 
                /// </param>
539
 
                private void DrawFooterOnContext (Context cr, int radius)
540
 
                {
541
 
                        switch (style) {
542
 
                        case HUDStyle.HUD:
543
 
                                cr.MoveTo (.5, height-BottomBorderWidth+.5);
544
 
                                cr.LineTo (width-1, height-BottomBorderWidth+.5);
545
 
                                cr.Arc (width-radius-.5, height-radius-.5, radius, 0, Math.PI*.5);
546
 
                                cr.Arc (radius+.5, height-radius-.5, radius, Math.PI*.5, Math.PI);
547
 
                                cr.ClosePath ();
548
 
                                cr.Color = colors.TitleBarBase;
549
 
                                cr.FillPreserve ();
550
 
                                cr.LineWidth=1;
551
 
                                cr.Color = new Cairo.Color (.6, .6, .6, .4);
552
 
                                cr.Stroke ();
553
 
                                break;
554
 
                        case HUDStyle.Classic:
555
 
                                cr.Rectangle (0.5, height-BottomBorderWidth+.5, width-1, BottomBorderWidth-1);
556
 
                                LinearGradient title_grad1 = new LinearGradient (0, height-BottomBorderWidth, 0, height);
557
 
                                title_grad1.AddColorStop (0, new Cairo.Color (0.75, 0.75, 0.75));
558
 
                                title_grad1.AddColorStop (1, new Cairo.Color (0.95, 0.95, 0.95));
559
 
                                cr.Pattern = title_grad1;
560
 
                                cr.FillPreserve ();
561
 
                                title_grad1.Destroy ();
562
 
                                
563
 
                                cr.LineWidth = 1;
564
 
                                cr.Color = new Cairo.Color (0.3, 0.3, 0.3, 0.5);
565
 
                                cr.Stroke ();
566
 
                                break;
567
 
                        }
568
 
                }
569
 
                
570
 
                /// <summary>
571
 
                /// Draws the background theme on the passed context
572
 
                /// </summary>
573
 
                /// <param name="cr">
574
 
                /// A <see cref="Context"/>
575
 
                /// </param>
576
 
                private void DrawBackgroundOnContext (Context cr)
577
 
                {
578
 
                        cr.Operator = Operator.Source;
579
 
                        cr.Rectangle (0, 0, width, height);
580
 
                        cr.Color = new Cairo.Color (0, 0, 0, 0);
581
 
                        cr.Fill ();
582
 
                        cr.Operator = Operator.Over;
583
 
                                
584
 
                        int c_size = border_width - 2;
585
 
                        
586
 
                        //Draw rounded rectange around whole border
587
 
                        switch (style) {
588
 
                        case HUDStyle.HUD:
589
 
                                cr.MoveTo (0.5+c_size, -1);
590
 
                                cr.Arc (width-c_size-0.5, c_size-1, c_size, Math.PI*1.5, Math.PI*2);
591
 
                                cr.Arc (width-0.5-c_size, height-c_size-0.5, c_size, 0, Math.PI*.5);
592
 
                                cr.Arc (0.5+c_size, height-c_size-0.5, c_size, Math.PI*.5, Math.PI);
593
 
                                cr.Arc (0.5+c_size, c_size-1, c_size, Math.PI, Math.PI*1.5);
594
 
                                cr.ClosePath ();
595
 
                                cr.Color = BackgroundColor;
596
 
                                cr.FillPreserve ();
597
 
                                
598
 
                                cr.LineWidth = 1;
599
 
                                cr.Color = colors.BackgroundLight;
600
 
                                cr.Stroke ();
601
 
                                break;
602
 
                        case HUDStyle.Classic:
603
 
                                cr.Rectangle (0.5, 0, width-1, height);
604
 
                                cr.Color = BackgroundColor;
605
 
                                cr.FillPreserve ();
606
 
                                
607
 
                                cr.Color = new Cairo.Color (.3, .3, .3, .5);
608
 
                                cr.LineWidth = 1;
609
 
                                cr.Stroke ();
610
 
                                break;
611
 
                        }
612
 
 
613
 
                        DrawHeaderOnContext (cr, c_size);
614
 
                        
615
 
                        cr.Rectangle (border_width, top_border_width, InternalWidth, height-top_border_width);
616
 
                        cr.Color = new Cairo.Color (.9, .9, .9, .05);
617
 
                        cr.Fill ();
618
 
                        
619
 
                        DrawFooterOnContext (cr, c_size);
620
 
                        
621
 
                        cr.MoveTo (border_width + .5, top_border_width);
622
 
                        cr.LineTo (border_width + .5, height-BottomBorderWidth);
623
 
                        cr.MoveTo (width - border_width - .5, top_border_width);
624
 
                        cr.LineTo (width - border_width - .5, height-BottomBorderWidth);
625
 
                        if (style != HUDStyle.Classic) {                        
626
 
                                cr.MoveTo (0, height-BottomBorderWidth-.5);
627
 
                                cr.LineTo (width, height-BottomBorderWidth-.5);
628
 
                        }
629
 
                        
630
 
                        cr.LineWidth = 1;
631
 
                        cr.Color = new Cairo.Color (.6, .6, .6, .15);
632
 
                        cr.Stroke ();
633
 
                }
634
 
                
635
 
                /// <summary>
636
 
                /// Draws the entire view of the results window now on the surface passed in
637
 
                /// </summary>
638
 
                /// <param name="sr">
639
 
                /// A <see cref="Surface"/>
640
 
                /// </param>
641
 
                private void DrawContextOnSurface (Surface sr)
642
 
                {
643
 
                        Context cr = new Context (sr);
644
 
                        if (background == null) {
645
 
                                background = cr.Target.CreateSimilar (cr.Target.Content, width, height);
646
 
                                Context cr2 = new Context (background);
647
 
                                DrawBackgroundOnContext (cr2);
648
 
                                (cr2 as IDisposable).Dispose ();
649
 
                        }
650
 
                        
651
 
                        cr.Operator = Operator.Source;
652
 
                        cr.SetSource (background);
653
 
                        cr.Paint ();
654
 
                        cr.Operator = Operator.Over;
655
 
                        
656
 
                        if (context != null && !string.IsNullOrEmpty (context.Query))
657
 
                                RenderText (cr, new Gdk.Rectangle (10, 3, width-60, 20), 12, context.Query, QueryColor);
658
 
                        
659
 
                        if (Results != null) {
660
 
                                string render_string = context.Cursor+1 + " of " + Results.Count + "  ▸  ";
661
 
                                if (context.ParentContext != null && context.ParentContext.Selection != null) {
662
 
                                        if (context.ParentContext.ParentContext != null && context.ParentContext.ParentContext.Selection != null) {
663
 
                                                render_string += context.ParentContext.ParentContext.Selection.Name + " ▸ ";
664
 
                                        }
665
 
                                        render_string += context.ParentContext.Selection.Name + " ▸ ";
666
 
                                }
667
 
                                
668
 
                                RenderText (cr, new Gdk.Rectangle (10, height-BottomBorderWidth+3, width-20, 20), 11, render_string);
669
 
                                int start_result = StartResult-(int) Math.Ceiling (scroll_offset);
670
 
                                RenderHighlight (cr);
671
 
                                for (int i = start_result; i < start_result+num_results+1 && i < Results.Count; i++) {
672
 
                                        RenderItem (cr, i);
673
 
                                }
674
 
                        }
675
 
                        
676
 
                        (cr as IDisposable).Dispose ();
677
 
                }
678
 
                
679
 
                public void Draw ()
680
 
                {
681
 
                        AnimatedDraw ();
682
 
                }
683
 
                
684
 
                public void InitChildInAnimation ()
685
 
                {
686
 
                        if (child_inout_surface == null) {
687
 
                                Context cr = Gdk.CairoHelper.Create (GdkWindow);
688
 
                                child_inout_surface = cr.Target.CreateSimilar (cr.Target.Content, width, height);
689
 
                                (cr as IDisposable).Dispose ();
690
 
                        }
691
 
                        DrawContextOnSurface (child_inout_surface);
692
 
                        child_scroll_offset = 1;
693
 
                }
694
 
                
695
 
                public void InitChildOutAnimation ()
696
 
                {
697
 
                        if (child_inout_surface == null) {
698
 
                                Context cr = Gdk.CairoHelper.Create (GdkWindow);
699
 
                                child_inout_surface = cr.Target.CreateSimilar (cr.Target.Content, width, height);
700
 
                                (cr as IDisposable).Dispose ();
701
 
                        }
702
 
                        DrawContextOnSurface (child_inout_surface);
703
 
                        child_scroll_offset = -1;
704
 
                }
705
 
                
706
 
                protected override bool OnExposeEvent (EventExpose evnt)
707
 
                {
708
 
                        Draw ();
709
 
                        return base.OnExposeEvent (evnt);
710
 
                }
711
 
 
712
 
                void BufferItem (Element item) 
713
 
                {
714
 
                        if (!IsDrawable)
715
 
                                return;
716
 
                        Context cr = Gdk.CairoHelper.Create (GdkWindow);
717
 
                        Surface surface = cr.Target.CreateSimilar (cr.Target.Content, InternalWidth, SurfaceHeight);
718
 
                        Context cr2 = new Context (surface);
719
 
                        ItemRenderer.RenderElement (cr2, new Gdk.Point (border_width, 0), InternalWidth, item, controller.ElementHasChildren (item));
720
 
                        
721
 
                        surface_buffer[item] = surface;
722
 
                        
723
 
                        (cr2 as IDisposable).Dispose ();
724
 
                        (cr as IDisposable).Dispose ();
725
 
                }
726
 
                
727
 
                void RenderText (Context cr, Gdk.Rectangle region, int size, string text)
728
 
                {
729
 
                        switch (style) {
730
 
                        case HUDStyle.HUD:
731
 
                                RenderText (cr, region, size, text, "ffffff");
732
 
                                break;
733
 
                        case HUDStyle.Classic:
734
 
                                RenderText (cr, region, size, text, "333333");
735
 
                                break;
736
 
                        default:
737
 
                                throw new NotImplementedException ();
738
 
                        }
739
 
                }
740
 
                
741
 
                void RenderText (Context cr, Gdk.Rectangle region, int size, string text, string color_string)
742
 
                {
743
 
                        Pango.Layout layout = new Pango.Layout (this.PangoContext);
744
 
                        layout.Width = Pango.Units.FromPixels (region.Width);
745
 
                        layout.Ellipsize = Pango.EllipsizeMode.End;
746
 
                        layout.SetMarkup ("<span foreground=\"#" + color_string + "\">"+GLib.Markup.EscapeText (text)+"</span>");
747
 
                        layout.FontDescription = Pango.FontDescription.FromString ("normal bold");
748
 
                        layout.FontDescription.AbsoluteSize = Pango.Units.FromPixels (size);
749
 
                        cr.MoveTo (region.X, region.Y);
750
 
                        Pango.CairoHelper.ShowLayout (cr, layout);
751
 
                        layout.Context.Dispose ();
752
 
                        layout.FontDescription.Dispose ();
753
 
                        layout.Dispose ();
754
 
                }
755
 
                
756
 
                Surface GetHighlightSource () 
757
 
                {
758
 
                        if (highlight_surface == null) {
759
 
                                Context cr = Gdk.CairoHelper.Create (GdkWindow);
760
 
                                highlight_surface = cr.Target.CreateSimilar (cr.Target.Content, width, SurfaceHeight);
761
 
                                
762
 
                                Context cr2 = new Context (highlight_surface);
763
 
                                switch (style) {
764
 
                                case HUDStyle.HUD:
765
 
                                        LinearGradient grad = new LinearGradient (0, 0, 0, SurfaceHeight);
766
 
                                        grad.AddColorStop (0, new Cairo.Color (.85, .85, .85, .2));
767
 
                                        grad.AddColorStop (1, new Cairo.Color (.95, .95, .95, .2));
768
 
                                        
769
 
                                        cr2.Pattern = grad;
770
 
                                        double radius=(SurfaceHeight-2)/2;
771
 
                                        double x=4.5, y=1.5;
772
 
                                        int r_width = width-9;
773
 
                                        int r_height = SurfaceHeight-3;
774
 
                                        
775
 
                                        cr2.MoveTo (x, y + radius);
776
 
                                        cr2.Arc (x + radius, y + radius, radius, Math.PI, -Math.PI / 2);
777
 
                                        cr2.LineTo (x + r_width - radius, y);
778
 
                                        cr2.Arc (x + r_width - radius, y + radius, radius, -Math.PI / 2, 0);
779
 
                                        cr2.LineTo (x + r_width, y + r_height - radius);
780
 
                                        cr2.Arc (x + r_width - radius, y + r_height - radius, radius, 0, Math.PI / 2);
781
 
                                        cr2.LineTo (x + radius, y + r_height);
782
 
                                        cr2.Arc (x + radius, y + r_height - radius, radius, Math.PI / 2, Math.PI);
783
 
                                        cr2.ClosePath ();
784
 
 
785
 
                                        cr2.FillPreserve ();
786
 
                                        grad.Destroy ();
787
 
                                        
788
 
                                        cr2.LineWidth = 1;
789
 
                                        cr2.Color = new Cairo.Color (0.9, 0.9, 0.9, 1);
790
 
                                        cr2.Stroke ();
791
 
                                        break;
792
 
                                case HUDStyle.Classic:
793
 
                                        cr2.Rectangle (0, 0, width, SurfaceHeight);
794
 
                                        Gdk.Color gdkColor;
795
 
                                        using (Gtk.Style rcstyle = Gtk.Rc.GetStyle (this)) {
796
 
                                                gdkColor = rcstyle.BaseColors[(int) StateType.Selected];
797
 
                                        }
798
 
                                        cr2.Color = gdkColor.ConvertToCairo (.8);
799
 
                                        cr2.Fill ();
800
 
                                        break;
801
 
                                }
802
 
                                
803
 
                                
804
 
                                (cr as IDisposable).Dispose ();
805
 
                                (cr2 as IDisposable).Dispose ();
806
 
                        }
807
 
                        return highlight_surface;
808
 
                }
809
 
                
810
 
                void RenderItem (Context cr, int item)
811
 
                {
812
 
                        if (item >= Results.Count || item < 0)
813
 
                                return;
814
 
                        int offset = (int) (SurfaceHeight*scroll_offset) + top_border_width;
815
 
                        if (!surface_buffer.ContainsKey (Results[item])) {
816
 
                                BufferItem (Results[item]);
817
 
                        }
818
 
                        
819
 
                        cr.Rectangle (border_width, top_border_width, InternalWidth, height-top_border_width-BottomBorderWidth);
820
 
                        cr.Clip ();
821
 
                        
822
 
                        cr.Rectangle (border_width, offset+(item-StartResult)*SurfaceHeight, InternalWidth, SurfaceHeight);
823
 
                        if (item%2 == 1) {
824
 
                                cr.Color = new Cairo.Color (.2, .2, .2, .2);
825
 
                                cr.Operator = Operator.DestOver;
826
 
                                cr.FillPreserve ();
827
 
                        }
828
 
                        
829
 
                        cr.Operator = Operator.Over;
830
 
                        cr.SetSource (surface_buffer[Results[item]], border_width, offset+(item-StartResult)*SurfaceHeight);
831
 
                        cr.Fill ();
832
 
                }
833
 
                
834
 
                void RenderHighlight (Context cr)
835
 
                {
836
 
                        int offset = (int) (SurfaceHeight*highlight_offset) + top_border_width;
837
 
                        cr.Rectangle (0, offset+(Cursor-StartResult)*SurfaceHeight, width, SurfaceHeight);
838
 
                        cr.SetSource (GetHighlightSource (), 0, offset+(Cursor-StartResult)*SurfaceHeight);
839
 
                        cr.FillPreserve ();
840
 
                }
841
 
                
842
 
                public void SlideIn ()
843
 
                {
844
 
                        if (visible)
845
 
                                return;
846
 
                        visible = true;
847
 
                        slide_offset = 0;
848
 
                        Draw ();
849
 
                }
850
 
                
851
 
                public void SlideOut ()
852
 
                {
853
 
                        if (!visible)
854
 
                                return;
855
 
                        visible = false;
856
 
                        slide_offset = 1;
857
 
                        Draw ();
858
 
                }
859
 
        }
860
 
}