~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to src/core/Mono.Texteditor/Mono.TextEditor.Theatrics/BounceFadePopupWindow.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
        /// </summary>
36
36
        public abstract class BounceFadePopupWindow : Gtk.Window
37
37
        {
38
 
                Rectangle bounds;
39
 
                TextEditor editor;
40
38
                Stage<BounceFadePopupWindow> stage = new Stage<BounceFadePopupWindow> ();
41
39
                Gdk.Pixbuf textImage = null;
42
 
                
43
 
                double scale = 0.0;
44
 
                double opacity = 1.0;
45
 
                
46
 
                public BounceFadePopupWindow (TextEditor editor, Rectangle bounds) : base (Gtk.WindowType.Popup)
 
40
                TextEditor editor;
 
41
                
 
42
                protected double scale = 0.0;
 
43
                protected double opacity = 1.0;
 
44
                
 
45
                public BounceFadePopupWindow (TextEditor editor) : base (Gtk.WindowType.Popup)
47
46
                {
48
 
                        this.Decorated = false;
49
 
                        this.BorderWidth = 0;
50
 
                        this.HasFrame = true;
 
47
                        if (!IsComposited)
 
48
                                throw new InvalidOperationException ("Only works with composited screen. Check Widget.IsComposited.");
 
49
                        DoubleBuffered = true;
 
50
                        Decorated = false;
 
51
                        BorderWidth = 0;
 
52
                        HasFrame = true;
51
53
                        this.editor = editor;
52
 
                        this.bounds = bounds;
53
 
                        this.Duration = 500;
 
54
                        Events = Gdk.EventMask.ExposureMask;
 
55
                        Duration = 500;
54
56
                        ExpandWidth = 12;
55
57
                        ExpandHeight = 2;
56
58
                        BounceEasing = Easing.Sine;
 
59
                        
 
60
                        var rgbaColormap = Screen.RgbaColormap;
 
61
                        if (rgbaColormap == null)
 
62
                                return;
 
63
                        Colormap = rgbaColormap;
 
64
 
 
65
                        stage.ActorStep += OnAnimationActorStep;
 
66
                        stage.Iteration += OnAnimationIteration;
 
67
                        stage.UpdateFrequency = 10;
57
68
                }
58
69
                
 
70
                protected TextEditor Editor { get { return editor; } }
 
71
                
59
72
                /// <summary>Duration of the animation, in milliseconds.</summary>
60
73
                public uint Duration { get; set; }
61
74
                
68
81
                /// <summary>The easing used for the bounce part of the animation.</summary>
69
82
                public Easing BounceEasing { get; set; }
70
83
                
71
 
                public void Popup ()
 
84
                int x, y;
 
85
                protected int width, height;
 
86
                double vValue, hValue;
 
87
                protected Rectangle bounds;
 
88
 
 
89
                public virtual void Popup ()
72
90
                {
73
 
                        if (!IsComposited)
74
 
                                throw new InvalidOperationException ("Only works with composited screen. Check Widget.IsComposited.");
75
 
                        
76
 
                        var rgbaColormap = Screen.RgbaColormap;
77
 
                        if (rgbaColormap == null)
78
 
                                return;
79
 
                        Colormap = rgbaColormap;
80
 
                        
81
 
                        int x, y;
82
91
                        editor.GdkWindow.GetOrigin (out x, out y);
83
 
                        Move (x + bounds.X - (int)(ExpandWidth / 2), y + bounds.Y - (int)(ExpandHeight / 2));
84
 
                        Resize (bounds.Width + (int)ExpandWidth, bounds.Height + (int)ExpandHeight);
85
 
                        
86
 
                        stage.ActorStep += OnAnimationActorStep;
87
 
                        stage.Iteration += OnAnimationIteration;
88
 
                        
89
 
                        stage.UpdateFrequency = 10;
90
 
                        stage.Add (this, Duration);
91
 
                        
 
92
                        bounds = CalculateInitialBounds ();
 
93
                        x = x + bounds.X - (int)(ExpandWidth / 2);
 
94
                        y = y + bounds.Y - (int)(ExpandHeight / 2);
 
95
                        Move (x, y);
 
96
                        
 
97
                        width = bounds.Width + (int)ExpandWidth;
 
98
                        height = bounds.Height + (int)ExpandHeight;
 
99
                        Resize (width, height);
 
100
                        
 
101
                        
 
102
                        stage.AddOrReset (this, Duration);
 
103
                        stage.Play ();
 
104
                        ListenToEvents ();
92
105
                        Show ();
93
106
                }
94
 
                
 
107
 
 
108
                protected void ListenToEvents ()
 
109
                {
 
110
                        editor.VAdjustment.ValueChanged += HandleEditorVAdjustmentValueChanged;
 
111
                        editor.HAdjustment.ValueChanged += HandleEditorHAdjustmentValueChanged;
 
112
                        vValue = editor.VAdjustment.Value;
 
113
                        hValue = editor.HAdjustment.Value;
 
114
                }
 
115
 
 
116
                protected override void OnShown ()
 
117
                {
 
118
                        base.OnShown ();
 
119
                }
 
120
                
 
121
                protected void DetachEvents ()
 
122
                {
 
123
                        editor.VAdjustment.ValueChanged -= HandleEditorVAdjustmentValueChanged;
 
124
                        editor.HAdjustment.ValueChanged -= HandleEditorHAdjustmentValueChanged;
 
125
                }
 
126
 
 
127
                protected override void OnHidden ()
 
128
                {
 
129
                        base.OnHidden ();
 
130
                        DetachEvents ();
 
131
                }
 
132
                
 
133
                void HandleEditorVAdjustmentValueChanged (object sender, EventArgs e)
 
134
                {
 
135
                        y += (int)(vValue - editor.VAdjustment.Value);
 
136
                        Move (x, y);
 
137
                        vValue = editor.VAdjustment.Value;
 
138
                }
 
139
                
 
140
                void HandleEditorHAdjustmentValueChanged (object sender, EventArgs e)
 
141
                {
 
142
                        x += (int)(hValue - editor.HAdjustment.Value);
 
143
                        Move (x, y);
 
144
                        hValue = editor.HAdjustment.Value;
 
145
                }
95
146
                
96
147
                void OnAnimationIteration (object sender, EventArgs args)
97
148
                {
98
149
                        QueueDraw ();
99
150
                }
100
151
                
101
 
                bool OnAnimationActorStep (Actor<BounceFadePopupWindow> actor)
 
152
                protected virtual bool OnAnimationActorStep (Actor<BounceFadePopupWindow> actor)
102
153
                {
103
154
                        if (actor.Expired) {
104
 
                                Destroy ();
 
155
                                OnAnimationCompleted ();
105
156
                                return false;
106
157
                        }
107
158
                        
112
163
                        }
113
164
                        //for the second half, vary opacity linearly from 1 to 0.
114
165
                        else {
115
 
                                scale = scale = Choreographer.Compose (1.0, BounceEasing);
 
166
                                scale = Choreographer.Compose (1.0, BounceEasing);
116
167
                                opacity = 2.0 - actor.Percent * 2;
117
168
                        }
118
169
                        return true;
119
170
                }
 
171
 
 
172
                protected virtual void OnAnimationCompleted ()
 
173
                {
 
174
                        StopPlaying ();
 
175
                }
120
176
                
121
177
                protected override void OnDestroyed ()
122
178
                {
 
179
                        editor.VAdjustment.ValueChanged -= HandleEditorVAdjustmentValueChanged;
123
180
                        base.OnDestroyed ();
 
181
                        StopPlaying ();
 
182
                }
 
183
                
 
184
                internal virtual void StopPlaying ()
 
185
                {
124
186
                        stage.Playing = false;
125
187
                        
126
188
                        if (textImage != null) {
128
190
                                textImage = null;
129
191
                        }
130
192
                }
131
 
                
132
 
                protected abstract Pixbuf RenderInitialPixbuf (Gdk.Window parentwindow, Rectangle bounds);
133
 
                
134
 
                
135
 
                protected override bool OnExposeEvent (Gdk.EventExpose evnt)
136
 
                {
137
 
                        try {
138
 
                                using (var g = Gdk.CairoHelper.Create (evnt.Window)) {
139
 
                                        g.SetSourceRGBA (1, 1, 1, 0);
140
 
                                        g.Operator = Cairo.Operator.Source;
141
 
                                        g.Paint ();
142
 
                                }
143
 
                                
144
 
                                if (textImage == null) {
145
 
                                        var img = RenderInitialPixbuf (evnt.Window, bounds);
146
 
                                        if (!img.HasAlpha) {
147
 
                                                textImage = img.AddAlpha (false, 0, 0, 0);
148
 
                                                img.Dispose ();
149
 
                                        } else {
150
 
                                                textImage = img;
151
 
                                        }
152
 
                                }
153
 
                                
154
 
                                int i = (int)(ExpandWidth * scale);
155
 
                                int j = (int)(ExpandHeight * scale);
156
 
                                int winw = Allocation.Width, winh = Allocation.Height;
157
 
                                int scaledw = winw - (int)(ExpandWidth - i);
158
 
                                int scaledh = winh - (int)(ExpandHeight - j);
159
 
                                
160
 
                                using (var scaled = textImage.ScaleSimple (scaledw, scaledh, Gdk.InterpType.Bilinear)) {
161
 
                                        if (scaled != null) {
162
 
                                                SetPixbufChannel (scaled, 4, (byte)(opacity*255));
163
 
                                                using (var gc = new Gdk.GC (evnt.Window)) {
164
 
                                                        scaled.RenderToDrawable (evnt.Window, gc, 0, 0, (winw - scaledw) / 2, (winh - scaledh) / 2, 
165
 
                                                                                 scaledw, scaledh, Gdk.RgbDither.None, 0, 0);
166
 
                                                }
167
 
                                        }
168
 
                                }
169
 
                        } catch (Exception e) {
170
 
                                Console.WriteLine ("Exception in animation:" + e);
171
 
                        }
172
 
                        return false;
173
 
                }
174
 
                
175
 
                /// <summary>
176
 
                /// Utility method for setting a single channel in a pixbuf.
177
 
                /// </summary>
178
 
                /// <param name="channel">Channel indexx, 1-based.</param>
179
 
                /// <param name="value">Value for all pixels in that channel.</param>
180
 
                unsafe void SetPixbufChannel (Gdk.Pixbuf p, int channel, byte value)
181
 
                {
182
 
                        int nChannels = p.NChannels;
183
 
                        
184
 
                        if (channel > nChannels)
185
 
                                throw new ArgumentException ("channel");
186
 
                        
187
 
                        byte *start = (byte*) p.Pixels;
188
 
                        int rowStride = p.Rowstride;
189
 
                        int width = p.Width;
190
 
                        byte *lastRow = start + p.Rowstride * (p.Height - 1);
191
 
                        for (byte *row = start; row <= lastRow; row += rowStride) {
192
 
                                byte *colEnd = row + width * nChannels;
193
 
                                for (byte *col = row + channel - 1; col < colEnd; col += nChannels)
194
 
                                        *col = value;
195
 
                        }
196
 
                }
 
193
 
 
194
                protected abstract Rectangle CalculateInitialBounds ();
 
195
                
 
196
                
 
197
                
197
198
        }
198
199
}
199