3
* GNOME Do is the legal property of its developers. Please refer to the
4
* COPYRIGHT file distributed with this source distribution.
6
* This program is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
24
namespace Do.Interface.Widgets
26
public class Frame : Bin
28
protected Rectangle childAlloc;
29
protected double radius;
31
protected bool drawFrame;
32
protected Color frameColor;
33
protected double frameAlpha;
34
protected bool drawGradient;
37
protected Color fillColor;
38
protected double fillAlpha;
40
protected Cairo.Context cairo;
41
protected int height, width;
44
public Frame () : base ()
51
fillColor = frameColor = new Color (0, 0, 0);
56
get { return radius; }
59
if (IsDrawable) QueueDraw ();
65
get { return drawFrame; }
68
if (IsDrawable) QueueDraw ();
72
public Color FrameColor
74
get { return frameColor; }
76
frameColor = new Color ((byte)value.Red, (byte)value.Green, (byte)value.Blue);
77
if (IsDrawable) QueueDraw ();
81
public double FrameAlpha
83
get { return frameAlpha; }
86
if (IsDrawable) QueueDraw ();
95
if (IsDrawable) QueueDraw ();
99
public Color FillColor
101
get { return fillColor; }
103
fillColor = new Color ((byte)value.Red, (byte)value.Green, (byte)value.Blue);
104
if (IsDrawable) QueueDraw ();
108
public double FillAlpha
110
get { return fillAlpha; }
113
if (IsDrawable) QueueDraw ();
117
protected virtual void GetFrame (Cairo.Context cairo)
122
cairo.Rectangle (x, y, width, height);
124
cairo.MoveTo (x+radius, y);
125
cairo.Arc (x+width-radius, y+radius, radius, (Math.PI*1.5), (Math.PI*2));
126
cairo.Arc (x+width-radius, y+height-radius, radius, 0, (Math.PI*0.5));
127
cairo.Arc (x+radius, y+height-radius, radius, (Math.PI*0.5), Math.PI);
128
cairo.Arc (x+radius, y+radius, radius, Math.PI, (Math.PI*1.5));
132
protected virtual void GetBorderFrame (Cairo.Context cairo)
134
/* Override coordinates to align to the cairo grid */
135
double X, Y, Width, Height;
136
X = x + cairo.LineWidth/2.0;
137
Y = y + cairo.LineWidth/2.0;
138
Width = width - cairo.LineWidth;
139
Height = height - cairo.LineWidth;
144
cairo.Rectangle (X, Y, Width, Height);
146
cairo.MoveTo (X+radius, Y);
147
cairo.Arc (X+Width-radius, Y+radius, radius, (Math.PI*1.5), (Math.PI*2));
148
cairo.Arc (X+Width-radius, Y+Height-radius, radius, 0, (Math.PI*0.5));
149
cairo.Arc (X+radius, Y+Height-radius, radius, (Math.PI*0.5), Math.PI);
150
cairo.Arc (X+radius, Y+radius, radius, Math.PI, (Math.PI*1.5));
154
protected virtual void Paint (Gdk.Rectangle area)
159
if (!drawFrame && !fill) {
160
/* Nothing to draw. */
164
/* You shouldn't change the size of the drawing area
165
* to avoid glitches when switching panes, though
166
* you can enlarge the big frame.
167
* This workaround is enlarging only the frame which has
168
* radius == 0, so when the window is not composited.
169
* Pretty ugly, I should think on something better.
171
* int offset = radius == 0 ? 1 : 0;
173
* x = childAlloc.X - offset;
174
* y = childAlloc.Y - offset;
175
* width = childAlloc.Width + offset * 2;
176
* height = childAlloc.Height + offset * 2;
181
width = childAlloc.Width;
182
height = childAlloc.Height;
184
if (this.radius < 0.0) {
185
radius = Math.Min (width, height);
186
radius = (radius / 100) * 10;
189
using (cairo = Gdk.CairoHelper.Create (GdkWindow)) {
190
cairo.Operator = Cairo.Operator.Over;
202
((IDisposable)cairo.Target).Dispose ();
206
protected virtual Cairo.LinearGradient GetGradient ()
208
return new Cairo.LinearGradient (x, y, x, y+height);
211
protected virtual void PaintFill ()
215
r = (double) fillColor.Red / ushort.MaxValue;
216
g = (double) fillColor.Green / ushort.MaxValue;
217
b = (double) fillColor.Blue / ushort.MaxValue;
223
cairo.Color = new Cairo.Color (r, g, b, fillAlpha);
225
cairo.Pattern = GetGradient ();
227
cairo.FillPreserve ();
231
protected virtual void PaintBorder ()
235
r = (double) frameColor.Red / ushort.MaxValue;
236
g = (double) frameColor.Green / ushort.MaxValue;
237
b = (double) frameColor.Blue / ushort.MaxValue;
241
GetBorderFrame (cairo);
243
cairo.Color = new Cairo.Color (r, g, b, frameAlpha);
248
protected override bool OnExposeEvent (EventExpose evnt)
252
base.OnExposeEvent (evnt);
257
protected override void OnSizeRequested (ref Requisition requisition)
261
requisition.Height = requisition.Width = 0;
262
if (Child != null && Child.Visible) {
263
cr = Child.SizeRequest ();
264
requisition.Width = Math.Max (requisition.Width, cr.Width);
265
requisition.Height += cr.Height;
267
requisition.Width += (int)(BorderWidth + 2);
268
requisition.Height += (int)(BorderWidth + 2);
271
protected override void OnSizeAllocated (Rectangle allocation)
275
new_alloc.X = (int) BorderWidth + 1;
276
new_alloc.Width = Math.Max (1, allocation.Width - new_alloc.X * 2);
277
new_alloc.Y = (int) BorderWidth + 1;
278
new_alloc.Height = Math.Max (1, allocation.Height - new_alloc.Y * 2);
279
new_alloc.X += allocation.X;
280
new_alloc.Y += allocation.Y;
281
if (IsMapped && new_alloc != childAlloc) {
282
GdkWindow.InvalidateRect (new_alloc, false);
284
if (Child != null && Child.Visible) {
285
Child.SizeAllocate (new_alloc);
287
childAlloc = new_alloc;