If the window manager does not support _NET_ACTIVE_WINDOW, fall back to XGetInputFocus
[mono.git] / mcs / class / WindowsBase / System.Windows / Rect.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2007 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //      Chris Toshok <toshok@novell.com>
24 //      Sebastien Pouliot  <sebastien@ximian.com>
25 //
26
27 using System;
28 using System.ComponentModel;
29 using System.Globalization;
30 using System.Text;
31 using System.Windows.Converters;
32 using System.Windows.Markup;
33 using System.Windows.Media;
34
35 namespace System.Windows {
36
37         [Serializable]
38         [ValueSerializer (typeof (RectValueSerializer))]
39         [TypeConverter (typeof (RectConverter))]
40         public struct Rect : IFormattable
41         {
42                 public Rect (Size size)
43                 {
44                         x = y = 0.0;
45                         width = size.Width;
46                         height = size.Height;
47                 }
48
49                 public Rect (Point point, Vector vector) : this (point, Point.Add (point, vector))
50                 { }
51
52                 public Rect (Point point1, Point point2)
53                 {
54                         if (point1.X < point2.X) {
55                                 x = point1.X;
56                                 width = point2.X - point1.X;
57                         }
58                         else {
59                                 x = point2.X;
60                                 width = point1.X - point2.X;
61                         }
62
63                         if (point1.Y < point2.Y) {
64                                 y = point1.Y;
65                                 height = point2.Y - point1.Y;
66                         }
67                         else {
68                                 y = point2.Y;
69                                 height = point1.Y - point2.Y;
70                         }
71                 }
72
73                 public Rect (double x, double y, double width, double height)
74                 {
75                         if (width < 0 || height < 0)
76                                 throw new ArgumentException ("width and height must be non-negative.");
77                         this.x = x;
78                         this.y = y;
79                         this.width = width;
80                         this.height = height;
81                 }
82
83                 public Rect (Point location, Size size)
84                 {
85                         x = location.X;
86                         y = location.Y;
87                         width = size.Width;
88                         height = size.Height;
89                 }
90
91                 public bool Equals (Rect rect)
92                 {
93                         return (x == rect.X &&
94                                 y == rect.Y &&
95                                 width == rect.Width &&
96                                 height == rect.Height);
97                 }
98
99                 public static bool operator != (Rect rect1, Rect rect2)
100                 {
101                         return !(rect1.Location == rect2.Location && rect1.Size == rect2.Size);
102                 }
103
104                 public static bool operator == (Rect rect1, Rect rect2)
105                 {
106                         return rect1.Location == rect2.Location && rect1.Size == rect2.Size;
107                 }
108
109                 public override bool Equals (object o)
110                 {
111                         if (!(o is Rect))
112                                 return false;
113
114                         return Equals ((Rect)o);
115                 }
116
117                 public static bool Equals (Rect rect1, Rect rect2)
118                 {
119                         return rect1.Equals (rect2);
120                 }
121
122                 public override int GetHashCode ()
123                 {
124                         throw new NotImplementedException ();
125                 }
126
127                 public bool Contains (Rect rect)
128                 {
129                         if (rect.Left < this.Left ||
130                             rect.Right > this.Right)
131                                 return false;
132
133                         if (rect.Top < this.Top ||
134                             rect.Bottom > this.Bottom)
135                                 return false;
136
137                         return true;
138                 }
139
140                 public bool Contains (double x, double y)
141                 {
142                         if (x < Left || x > Right)
143                                 return false;
144                         if (y < Top || y > Bottom)
145                                 return false;
146
147                         return true;
148                 }
149
150                 public bool Contains (Point p)
151                 {
152                         return Contains (p.X, p.Y);
153                 }
154
155                 public static Rect Inflate (Rect rect, double width, double height)
156                 {
157                         if (width < rect.Width * -2)
158                                 return Rect.Empty;
159                         if (height < rect.Height * -2)
160                                 return Rect.Empty;
161
162                         Rect result = rect;
163                         result.Inflate (width, height);
164                         return result;
165                 }
166
167                 public static Rect Inflate (Rect rect, Size size)
168                 {
169                         return Rect.Inflate (rect, size.Width, size.Height);
170                 }
171
172                 public void Inflate (double width, double height)
173                 {
174                         // XXX any error checking like in the static case?
175                         x -= width;
176                         y -= height;
177
178                         this.width += 2*width;
179                         this.height += 2*height;
180                 }
181
182                 public void Inflate (Size size)
183                 {
184                         Inflate (size.Width, size.Height);
185                 }
186
187                 public bool IntersectsWith(Rect rect)
188                 {
189                         return !((Left >= rect.Right) || (Right <= rect.Left) ||
190                             (Top >= rect.Bottom) || (Bottom <= rect.Top));
191                 }
192
193                 public void Intersect(Rect rect)
194                 {
195                         double _x = Math.Max (x, rect.x);
196                         double _y = Math.Max (y, rect.y);
197                         double _width = Math.Min (Right, rect.Right) - _x;
198                         double _height = Math.Min (Bottom, rect.Bottom) - _y; 
199
200                         if (_width < 0 || _height < 0) {
201                                 x = y = Double.PositiveInfinity;
202                                 width = height = Double.NegativeInfinity;
203                         }
204                         else {
205                                 x = _x;
206                                 y = _y;
207                                 width = _width;
208                                 height = _height;
209                         }
210                 }
211
212                 public static Rect Intersect(Rect rect1, Rect rect2)
213                 {
214                         Rect result = rect1;
215                         result.Intersect (rect2);
216                         return result;
217                 }
218
219                 public void Offset(double offsetX, double offsetY)
220                 {
221                         x += offsetX;
222                         y += offsetY;
223                 }
224
225                 public static Rect Offset(Rect rect, double offsetX, double offsetY)
226                 {
227                         Rect result = rect;
228                         result.Offset (offsetX, offsetY);
229                         return result;
230                 }
231
232                 public void Offset (Vector offsetVector)
233                 {
234                         x += offsetVector.X;
235                         y += offsetVector.Y;
236                 }
237
238                 public static Rect Offset (Rect rect, Vector offsetVector)
239                 {
240                         Rect result = rect;
241                         result.Offset (offsetVector);
242                         return result;
243                 }
244
245                 public void Scale(double scaleX, double scaleY)
246                 {
247                         x *= scaleX;
248                         y *= scaleY;
249                         width *= scaleX;
250                         height *= scaleY;
251                 }
252
253                 public void Transform (Matrix matrix)
254                 {
255                         throw new NotImplementedException ();
256                 }
257
258                 public static Rect Transform (Rect rect, Matrix matrix)
259                 {
260                         Rect result = rect;
261                         result.Transform (matrix);
262                         return result;
263                 }
264
265                 public static Rect Union(Rect rect1, Rect rect2)
266                 {
267                         Rect result = rect1;
268                         result.Union (rect2);
269                         return result;
270                 }
271
272                 public static Rect Union(Rect rect, Point point)
273                 {
274                         Rect result = rect;
275                         result.Union (point);
276                         return result;
277                 }
278                 
279                 public void Union(Rect rect)
280                 {
281                         x = Math.Min (x, rect.x);
282                         y = Math.Min (y, rect.y);
283                         width = Math.Max (Right, rect.Right) - x;
284                         height = Math.Max (Bottom, rect.Bottom) - y;
285                 }
286
287                 public void Union(Point point)
288                 {
289                         Union (new Rect (point, point));
290                 }
291
292                 public static Rect Parse (string source)
293                 {
294                         throw new NotImplementedException ();
295                 }
296
297                 public override string ToString ()
298                 {
299                         return ToString (null);
300                 }
301
302                 public string ToString (IFormatProvider provider)
303                 {
304                         return ToString (null, provider);
305                 }
306
307                 string IFormattable.ToString (string format, IFormatProvider provider)
308                 {
309                         return ToString (format, provider);
310                 }
311
312                 private string ToString (string format, IFormatProvider provider)
313                 {
314                         if (IsEmpty)
315                                 return "Empty";
316
317                         if (provider == null)
318                                 provider = CultureInfo.CurrentCulture;
319
320                         if (format == null)
321                                 format = string.Empty;
322
323                         string separator = ",";
324                         NumberFormatInfo numberFormat =
325                                 provider.GetFormat (typeof (NumberFormatInfo)) as NumberFormatInfo;
326                         if (numberFormat != null &&
327                             numberFormat.NumberDecimalSeparator == separator)
328                                 separator = ";";
329
330                         string rectFormat = String.Format (
331                                 "{{0:{0}}}{1}{{1:{0}}}{1}{{2:{0}}}{1}{{3:{0}}}",
332                                 format, separator);
333                         return String.Format (provider, rectFormat,
334                                 x, y, width, height);
335                 }
336
337                 public static Rect Empty { 
338                         get {
339                                 Rect r = new Rect ();
340                                 r.x = r.y = Double.PositiveInfinity;
341                                 r.width = r.height = Double.NegativeInfinity;
342                                 return r;
343                         } 
344                 }
345                 
346                 public bool IsEmpty { 
347                         get {
348                                 return (x == Double.PositiveInfinity &&
349                                         y == Double.PositiveInfinity &&
350                                         width == Double.NegativeInfinity &&
351                                         height == Double.NegativeInfinity);
352                         }
353                 }
354                 
355                 public Point Location { 
356                         get {
357                                 return new Point (x, y);
358                         }
359                         set {
360                                 if (IsEmpty)
361                                         throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
362
363                                 x = value.X;
364                                 y = value.Y;
365                         }
366                 }
367                 
368                 public Size Size { 
369                         get { 
370                                 if (IsEmpty)
371                                         return Size.Empty; 
372                                 return new Size (width, height);
373                         }
374                         set {
375                                 if (IsEmpty)
376                                         throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
377
378                                 width = value.Width;
379                                 height = value.Height;
380                         }
381                 }
382
383                 public double X {
384                         get { return x; }
385                         set {
386                                 if (IsEmpty)
387                                         throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
388
389                                 x = value;
390                         }
391                 }
392
393                 public double Y {
394                         get { return y; }
395                         set {
396                                 if (IsEmpty)
397                                         throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
398
399                                 y = value;
400                         }
401                 }
402
403                 public double Width {
404                         get { return width; }
405                         set {
406                                 if (IsEmpty)
407                                         throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
408
409                                 if (value < 0)
410                                         throw new ArgumentException ("width must be non-negative.");
411
412                                 width = value;
413                         }
414                 }
415
416                 public double Height {
417                         get { return height; }
418                         set {
419                                 if (IsEmpty)
420                                         throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
421
422                                 if (value < 0)
423                                         throw new ArgumentException ("height must be non-negative.");
424
425                                 height = value;
426                         }
427                 }
428
429                 public double Left { 
430                         get { return x; }
431                 }
432
433                 public double Top { 
434                         get { return y; }
435                 }
436                 
437                 public double Right { 
438                         get { return x + width; }
439                 }
440                 
441                 public double Bottom { 
442                         get { return y + height; }
443                 }
444                 
445                 public Point TopLeft { 
446                         get { return new Point (Left, Top); }
447                 }
448                 
449                 public Point TopRight { 
450                         get { return new Point (Right, Top); }
451                 }
452                 
453                 public Point BottomLeft { 
454                         get { return new Point (Left, Bottom); }
455                 }
456
457                 public Point BottomRight { 
458                         get { return new Point (Right, Bottom); }
459                 }
460                 
461                 double x;
462                 double y;
463                 double width;
464                 double height;
465         }
466 }