~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/xwt/Xwt/Xwt/ReliefFrame.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
ļ»æusing System;
 
2
using System.Collections.Generic;
 
3
using System.Linq;
 
4
using System.Text;
 
5
using Xwt.Drawing;
 
6
 
 
7
namespace Xwt
 
8
{
 
9
        public class ReliefFrame : Canvas
 
10
        {
 
11
                // http://graphics.stanford.edu/courses/cs248-98-fall/Final/q1.html
 
12
                const double ArcToBezier = 0.55228475;
 
13
                double padding = 12.0;
 
14
                double? radius = null;
 
15
                Color bgcolor;
 
16
 
 
17
                public ReliefFrame ()
 
18
                {
 
19
                        bgcolor = base.BackgroundColor;
 
20
                }
 
21
 
 
22
                public ReliefFrame (Widget content)
 
23
                        : this ()
 
24
                {
 
25
                        Content = content;
 
26
                }
 
27
 
 
28
                public new Color BackgroundColor
 
29
                {
 
30
                        get { return bgcolor; }
 
31
                        set
 
32
                        {
 
33
                                bgcolor = value;
 
34
                                QueueDraw ();
 
35
                        }
 
36
                }
 
37
 
 
38
                public new Widget Content
 
39
                {
 
40
                        get { return Children.SingleOrDefault (); }
 
41
                        set
 
42
                        {
 
43
                                if (Content != null)
 
44
                                        RemoveChild (Content);
 
45
                                if (value != null)
 
46
                                        AddChild (value);
 
47
                        }
 
48
                }
 
49
 
 
50
                public double? CornerRadius
 
51
                {
 
52
                        get { return radius; }
 
53
                        set
 
54
                        {
 
55
                                if (radius == value)
 
56
                                        return;
 
57
 
 
58
                                radius = value;
 
59
                                QueueDraw ();
 
60
                        }
 
61
                }
 
62
 
 
63
                public double Padding
 
64
                {
 
65
                        get { return padding; }
 
66
                        set
 
67
                        {
 
68
                                if (padding == value)
 
69
                                        return;
 
70
 
 
71
                                padding = value;
 
72
                                OnPreferredSizeChanged ();
 
73
                        }
 
74
                }
 
75
 
 
76
                protected override WidgetSize OnGetPreferredHeight ()
 
77
                {
 
78
                        return Content.Surface.GetPreferredHeight () + (2 * padding);
 
79
                }
 
80
 
 
81
                protected override WidgetSize OnGetPreferredWidth ()
 
82
                {
 
83
                        return Content.Surface.GetPreferredWidth () + (2 * padding);
 
84
                }
 
85
 
 
86
                protected override WidgetSize OnGetPreferredHeightForWidth (double width)
 
87
                {
 
88
                        return Content.Surface.GetPreferredHeightForWidth (Math.Max (width - (2 * padding), 0)) + (2 * padding);
 
89
                }
 
90
 
 
91
                protected override WidgetSize OnGetPreferredWidthForHeight (double height)
 
92
                {
 
93
                        return Content.Surface.GetPreferredWidthForHeight (Math.Max (height - (2 * padding), 0)) + (2 * padding);
 
94
                }
 
95
 
 
96
                protected override void OnReallocate ()
 
97
                {
 
98
                        base.OnReallocate ();
 
99
                        UpdateChildBounds ();
 
100
                }
 
101
 
 
102
                void UpdateChildBounds ()
 
103
                {
 
104
                        SetChildBounds (Content, new Rectangle (padding, padding, Math.Max (Size.Width - (2 * padding), 0), Math.Max (Size.Height - (2 * padding), 0)));
 
105
                }
 
106
 
 
107
                static void DrawBorder (Context ctx, double x, double y, double w, double h, double radius)
 
108
                {
 
109
                        ctx.NewPath ();
 
110
 
 
111
                        // test limits (without using multiplication)
 
112
                        if (radius > w - radius)
 
113
                                radius = w / 2;
 
114
                        if (radius > h - radius)
 
115
                                radius = h / 2;
 
116
 
 
117
                        // approximate (quite close) the arc using a bezier curve
 
118
                        double arc = ArcToBezier * radius;
 
119
 
 
120
                        // top-left corner
 
121
                        ctx.MoveTo (x + radius, y);
 
122
 
 
123
                        // top edge
 
124
                        ctx.LineTo (x + w - radius, y);
 
125
 
 
126
                        // top-right corner
 
127
                        ctx.CurveTo (x + w - radius + arc, y, x + w, y + arc, x + w, y + radius);
 
128
 
 
129
                        // right edge
 
130
                        ctx.LineTo (x + w, y + h - radius);
 
131
 
 
132
                        // bottom-right corner
 
133
                        ctx.CurveTo (x + w, y + h - radius + arc, x + w + arc - radius, y + h, x + w - radius, y + h);
 
134
 
 
135
                        // bottom edge
 
136
                        ctx.LineTo (x + radius, y + h);
 
137
 
 
138
                        // bottom-left corner
 
139
                        ctx.CurveTo (x + radius - arc, y + h, x, y + h - arc, x, y + h - radius);
 
140
 
 
141
                        // left edge
 
142
                        ctx.LineTo (x, y + radius);
 
143
 
 
144
                        // top-left corner
 
145
                        ctx.CurveTo (x, y + radius - arc, x + radius - arc, y, x + radius, y);
 
146
                }
 
147
 
 
148
                static Color GetColor (Color color, double percent)
 
149
                {
 
150
                        return new Color (color.Red * percent, color.Green * percent, color.Blue * percent);
 
151
                }
 
152
 
 
153
                RadialGradient GetCornerGradient (double x, double y, double radius, double thickness)
 
154
                {
 
155
                        var gradient = new RadialGradient (x, y, radius - thickness, x, y, radius + thickness);
 
156
                        gradient.AddColorStop (0, BackgroundColor);
 
157
                        gradient.AddColorStop (1, GetColor (BackgroundColor, 0.75));
 
158
                        return gradient;
 
159
                }
 
160
 
 
161
                LinearGradient GetBottomEdgeGradient (double bottom, double thickness)
 
162
                {
 
163
                        var gradient = new LinearGradient (0, bottom - thickness, 0, bottom + thickness);
 
164
                        gradient.AddColorStop (0, BackgroundColor);
 
165
                        gradient.AddColorStop (1, GetColor (BackgroundColor, 0.75));
 
166
                        return gradient;
 
167
                }
 
168
 
 
169
                LinearGradient GetTopEdgeGradient (double top, double thickness)
 
170
                {
 
171
                        var gradient = new LinearGradient (0, top - thickness, 0, top + thickness);
 
172
                        gradient.AddColorStop (0, GetColor (BackgroundColor, 0.75));
 
173
                        gradient.AddColorStop (1, BackgroundColor);
 
174
                        return gradient;
 
175
                }
 
176
 
 
177
                LinearGradient GetRightEdgeGradient (double right, double thickness)
 
178
                {
 
179
                        var gradient = new LinearGradient (right - thickness, 0, right + thickness, 0);
 
180
                        gradient.AddColorStop (0, BackgroundColor);
 
181
                        gradient.AddColorStop (1, GetColor (BackgroundColor, 0.75));
 
182
                        return gradient;
 
183
                }
 
184
 
 
185
                LinearGradient GetLeftEdgeGradient (double left, double thickness)
 
186
                {
 
187
                        var gradient = new LinearGradient (left - thickness, 0, left + thickness, 0);
 
188
                        gradient.AddColorStop (0, GetColor (BackgroundColor, 0.75));
 
189
                        gradient.AddColorStop (1, BackgroundColor);
 
190
                        return gradient;
 
191
                }
 
192
 
 
193
                void DrawBorder (Context ctx, double x, double y, double w, double h, double radius, double thickness)
 
194
                {
 
195
                        // test limits (without using multiplication)
 
196
                        if (radius > w - radius)
 
197
                                radius = w / 2;
 
198
                        if (radius > h - radius)
 
199
                                radius = h / 2;
 
200
 
 
201
                        // approximate (quite close) the arc using a bezier curve
 
202
                        double arc = ArcToBezier * radius;
 
203
 
 
204
                        ctx.SetLineWidth (thickness);
 
205
 
 
206
                        // top-left corner
 
207
                        ctx.NewPath ();
 
208
                        ctx.MoveTo (x, y + radius);
 
209
                        ctx.CurveTo (x, y + radius - arc, x + radius - arc, y, x + radius, y);
 
210
                        ctx.Pattern = GetCornerGradient (x + radius, y + radius, radius, thickness / 2);
 
211
                        ctx.Stroke ();
 
212
 
 
213
                        // top edge
 
214
                        ctx.NewPath ();
 
215
                        ctx.MoveTo (x + radius - 0.5, y);
 
216
                        ctx.LineTo (x + w - radius + 0.5, y);
 
217
                        ctx.Pattern = GetTopEdgeGradient (y, thickness / 2);
 
218
                        ctx.Stroke ();
 
219
 
 
220
                        // top-right corner
 
221
                        ctx.NewPath ();
 
222
                        ctx.MoveTo (x + w - radius, y);
 
223
                        ctx.CurveTo (x + w - radius + arc, y, x + w, y + arc, x + w, y + radius);
 
224
                        ctx.Pattern = GetCornerGradient (x + w - radius, y + radius, radius, thickness / 2);
 
225
                        ctx.Stroke ();
 
226
 
 
227
                        // right edge
 
228
                        ctx.NewPath ();
 
229
                        ctx.MoveTo (x + w, y + radius - 0.5);
 
230
                        ctx.LineTo (x + w, y + h - radius + 0.5);
 
231
                        ctx.Pattern = GetRightEdgeGradient (x + w, thickness / 2);
 
232
                        ctx.Stroke ();
 
233
 
 
234
                        // bottom-right corner
 
235
                        ctx.NewPath ();
 
236
                        ctx.MoveTo (x + w, y + h - radius);
 
237
                        ctx.CurveTo (x + w, y + h - radius + arc, x + w + arc - radius, y + h, x + w - radius, y + h);
 
238
                        ctx.Pattern = GetCornerGradient (x + w - radius, y + h - radius, radius, thickness / 2);
 
239
                        ctx.Stroke ();
 
240
 
 
241
                        // bottom edge
 
242
                        ctx.NewPath ();
 
243
                        ctx.MoveTo (x + w - radius + 0.5, y + h);
 
244
                        ctx.LineTo (x + radius - 0.5, y + h);
 
245
                        ctx.Pattern = GetBottomEdgeGradient (y + h, thickness / 2);
 
246
                        ctx.Stroke ();
 
247
 
 
248
                        // bottom-left corner
 
249
                        ctx.NewPath ();
 
250
                        ctx.MoveTo (x + radius, y + h);
 
251
                        ctx.CurveTo (x + radius - arc, y + h, x, y + h - arc, x, y + h - radius);
 
252
                        ctx.Pattern = GetCornerGradient (x + radius, y + h - radius, radius, thickness / 2);
 
253
                        ctx.Stroke ();
 
254
 
 
255
                        // left edge
 
256
                        ctx.NewPath ();
 
257
                        ctx.MoveTo (x, y + h - radius + 0.5);
 
258
                        ctx.LineTo (x, y + radius - 0.5);
 
259
                        ctx.Pattern = GetLeftEdgeGradient (x, thickness / 2);
 
260
                        ctx.Stroke ();
 
261
                }
 
262
 
 
263
                protected override void OnDraw (Context ctx, Rectangle dirtyRect)
 
264
                {
 
265
                        double radius = CornerRadius ?? Math.Min (Size.Width, Size.Height) / 6.4;
 
266
                        double h = Size.Height - 1.0;
 
267
                        double w = Size.Width - 1.0;
 
268
                        double x = 0.5;
 
269
                        double y = 0.5;
 
270
 
 
271
                        ctx.Save ();
 
272
 
 
273
                        // Background
 
274
                        DrawBorder (ctx, x, y, w, h, radius);
 
275
                        ctx.SetColor (BackgroundColor);
 
276
                        ctx.Fill ();
 
277
 
 
278
                        // Border
 
279
                        h = Size.Height - 6;
 
280
                        w = Size.Width - 6;
 
281
                        x = y = 3;
 
282
                        DrawBorder (ctx, x, y, w, h, radius, 6);
 
283
 
 
284
                        ctx.Restore ();
 
285
                }
 
286
        }
 
287
}