1 // 2 // GdkExtensions.cs 3 // 4 // Author: 5 // Jonathan Pobst <monkey@jpobst.com> 6 // 7 // Copyright (c) 2010 Jonathan Pobst 8 // 9 // Permission is hereby granted, free of charge, to any person obtaining a copy 10 // of this software and associated documentation files (the "Software"), to deal 11 // in the Software without restriction, including without limitation the rights 12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 // copies of the Software, and to permit persons to whom the Software is 14 // furnished to do so, subject to the following conditions: 15 // 16 // The above copyright notice and this permission notice shall be included in 17 // all copies or substantial portions of the Software. 18 // 19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 // THE SOFTWARE. 26 27 using System; 28 using Gdk; 29 30 namespace Pinta.Core 31 { 32 public static class GdkExtensions 33 { 34 // Invalidate the whole thing Invalidate(this Window w)35 public static void Invalidate (this Window w) 36 { 37 int width; 38 int height; 39 40 w.GetSize (out width, out height); 41 42 w.InvalidateRect (new Rectangle (0, 0, width, height), true); 43 } 44 GetBounds(this Window w)45 public static Rectangle GetBounds (this Window w) 46 { 47 int width; 48 int height; 49 50 w.GetSize (out width, out height); 51 52 return new Rectangle (0, 0, width, height); 53 } 54 GetSize(this Window w)55 public static Size GetSize (this Window w) 56 { 57 int width; 58 int height; 59 60 w.GetSize (out width, out height); 61 62 return new Size (width, height); 63 } 64 ToCairoColor(this Gdk.Color color)65 public static Cairo.Color ToCairoColor (this Gdk.Color color) 66 { 67 return new Cairo.Color ((double)color.Red / ushort.MaxValue, (double)color.Green / ushort.MaxValue, (double)color.Blue / ushort.MaxValue); 68 } 69 GetCairoColor(this Gtk.ColorSelection selection)70 public static Cairo.Color GetCairoColor (this Gtk.ColorSelection selection) 71 { 72 Cairo.Color cairo_color = selection.CurrentColor.ToCairoColor (); 73 return new Cairo.Color (cairo_color.R, cairo_color.G, cairo_color.B, (double)selection.CurrentAlpha / ushort.MaxValue); 74 } 75 Center(this Gdk.Rectangle rect)76 public static Gdk.Point Center (this Gdk.Rectangle rect) 77 { 78 return new Gdk.Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2); 79 } 80 ToBgraColor(this Gdk.Color color)81 public static ColorBgra ToBgraColor (this Gdk.Color color) 82 { 83 return ColorBgra.FromBgr ((byte)(color.Blue * 255 / ushort.MaxValue), (byte)(color.Green * 255 / ushort.MaxValue), (byte)(color.Red * 255 / ushort.MaxValue)); 84 } 85 IsNotSet(this Point p)86 public static bool IsNotSet (this Point p) 87 { 88 return p.X == int.MinValue && p.Y == int.MinValue; 89 } 90 IsShiftPressed(this ModifierType m)91 public static bool IsShiftPressed (this ModifierType m) 92 { 93 return (m & ModifierType.ShiftMask) == ModifierType.ShiftMask; 94 } 95 IsControlPressed(this ModifierType m)96 public static bool IsControlPressed (this ModifierType m) 97 { 98 return (m & ModifierType.ControlMask) == ModifierType.ControlMask; 99 } 100 IsAltPressed(this ModifierType m)101 public static bool IsAltPressed (this ModifierType m) 102 { 103 return (m & ModifierType.Mod1Mask) == ModifierType.Mod1Mask; 104 } 105 IsShiftPressed(this EventButton ev)106 public static bool IsShiftPressed (this EventButton ev) 107 { 108 return ev.State.IsShiftPressed (); 109 } 110 IsControlPressed(this EventButton ev)111 public static bool IsControlPressed (this EventButton ev) 112 { 113 return ev.State.IsControlPressed (); 114 } 115 IsAltPressed(this EventButton ev)116 public static bool IsAltPressed (this EventButton ev) 117 { 118 return ev.State.IsAltPressed (); 119 } 120 121 /// <summary> 122 /// Filters out all modifier keys except Ctrl/Shift/Alt. This prevents Caps Lock, Num Lock, etc 123 /// from appearing as active modifier keys. 124 /// </summary> FilterModifierKeys(this ModifierType current_state)125 public static ModifierType FilterModifierKeys (this ModifierType current_state) 126 { 127 var state = Gdk.ModifierType.None; 128 129 state |= (current_state & Gdk.ModifierType.ControlMask); 130 state |= (current_state & Gdk.ModifierType.ShiftMask); 131 state |= (current_state & Gdk.ModifierType.Mod1Mask); 132 state |= (current_state & Gdk.ModifierType.MetaMask); // Command key on macOS. 133 134 return state; 135 } 136 GetPoint(this EventButton ev)137 public static Cairo.PointD GetPoint (this EventButton ev) 138 { 139 return new Cairo.PointD (ev.X, ev.Y); 140 } 141 142 /// <summary> 143 /// The implementation of Rectangle.Bottom was changed in 2.12.11 to fix an off-by-one error, 144 /// and this function provides the newer behaviour for backwards compatibility with older versions. 145 /// </summary> GetBottom(this Rectangle r)146 public static int GetBottom(this Rectangle r) 147 { 148 return r.Y + r.Height - 1; 149 } 150 151 /// <summary> 152 /// The implementation of Rectangle.Right was changed in 2.12.11 to fix an off-by-one error, 153 /// and this function provides the newer behaviour for backwards compatibility with older versions. 154 /// </summary> GetRight(this Rectangle r)155 public static int GetRight(this Rectangle r) 156 { 157 return r.X + r.Width - 1; 158 } 159 ToSurface(this Pixbuf pixbuf)160 public static Cairo.Surface ToSurface (this Pixbuf pixbuf) 161 { 162 var surface = CairoExtensions.CreateImageSurface (Cairo.Format.ARGB32, pixbuf.Width, pixbuf.Height); 163 164 using (var g = new Cairo.Context (surface)) { 165 Gdk.CairoHelper.SetSourcePixbuf (g, pixbuf, 0, 0); 166 g.Paint (); 167 } 168 169 return surface; 170 } 171 CreateColorSwatch(int size, Color color)172 public static Pixbuf CreateColorSwatch (int size, Color color) 173 { 174 using (var pmap = new Pixmap (Screen.Default.RootWindow, size, size)) 175 using (var gc = new Gdk.GC (pmap)) { 176 gc.RgbFgColor = color; 177 pmap.DrawRectangle (gc, true, 0, 0, size, size); 178 179 gc.RgbFgColor = new Color (0, 0, 0); 180 pmap.DrawRectangle (gc, false, 0, 0, (size - 1), (size - 1)); 181 182 return Pixbuf.FromDrawable (pmap, pmap.Colormap, 0, 0, 0, 0, size, size); 183 } 184 } 185 CreateTransparentColorSwatch(bool drawBorder)186 public static Pixbuf CreateTransparentColorSwatch (bool drawBorder) 187 { 188 var size = 16; 189 190 using (var pmap = new Pixmap (Screen.Default.RootWindow, size, size)) 191 using (var gc = new Gdk.GC (pmap)) { 192 gc.RgbFgColor = new Color (255, 255, 255); 193 pmap.DrawRectangle (gc, true, 0, 0, size, size); 194 195 gc.RgbFgColor = new Color (200, 200, 200); 196 pmap.DrawRectangle (gc, true, 0, 0, (size / 2), (size / 2)); 197 pmap.DrawRectangle (gc, true, size / 2, size / 2, (size / 2), (size / 2)); 198 199 if (drawBorder) { 200 gc.RgbFgColor = new Color (0, 0, 0); 201 pmap.DrawRectangle (gc, false, 0, 0, (size - 1), (size - 1)); 202 } 203 204 return Pixbuf.FromDrawable (pmap, pmap.Colormap, 0, 0, 0, 0, size, size); 205 } 206 } 207 } 208 } 209