From: Jean-Philippe Bruyère Date: Mon, 7 Oct 2019 06:26:46 +0000 (+0200) Subject: hsv color debug, color slider, enum selector, debug X-Git-Tag: v0.9.5-beta~137^2~12 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=83472f05d2debe504b957d80109fb9e1a24937db;p=jp%2Fcrow.git hsv color debug, color slider, enum selector, debug --- diff --git a/Crow/Crow.csproj b/Crow/Crow.csproj index b084eed8..8e8934e9 100644 --- a/Crow/Crow.csproj +++ b/Crow/Crow.csproj @@ -25,7 +25,7 @@ full - TRACE;_DEBUG_BINDING;DESIGN_MODE;_DEBUG_CLIP_RECTANGLE;_DEBUG_FOCUS;_DEBUG_DRAGNDROP;NET471;DEBUG;NETFRAMEWORK;NET461 + _DEBUG_DISPOSE;TRACE;_DEBUG_BINDING;DESIGN_MODE;_DEBUG_CLIP_RECTANGLE;_DEBUG_FOCUS;_DEBUG_DRAGNDROP;NET471;NETFRAMEWORK;NET461;DEBUG;NETSTANDARD;NETSTANDARD2_0 true - + diff --git a/Crow/src/Cairo/CairoHelpers.cs b/Crow/src/Cairo/CairoHelpers.cs index 032980d0..0a5bd21b 100644 --- a/Crow/src/Cairo/CairoHelpers.cs +++ b/Crow/src/Cairo/CairoHelpers.cs @@ -57,23 +57,23 @@ namespace Crow return arr[minp]; } - public static void CairoRectangle(Cairo.Context gr, Rectangle r, double radius, double stroke = 0.0) + public static void CairoRectangle(Cairo.Context gr, RectangleD r, double radius, double stroke = 0.0) { if (radius > 0) - CairoHelpers.DrawRoundedRectangle (gr, r, radius, stroke); + DrawRoundedRectangle (gr, r, radius, stroke); else gr.Rectangle (r, stroke); } - public static void CairoCircle(Cairo.Context gr, Rectangle r) + public static void CairoCircle(Cairo.Context gr, RectangleD r) { - gr.Arc(r.X + r.Width/2, r.Y + r.Height/2, Math.Min(r.Width,r.Height)/2, 0, 2*Math.PI); + gr.Arc(r.X + r.Width/2.0, r.Y + r.Height/2.0, Math.Min(r.Width,r.Height)/2.0, 0, 2.0*Math.PI); } - public static void DrawRoundedRectangle(Cairo.Context gr, Rectangle r, double radius, double stroke = 0.0) + public static void DrawRoundedRectangle(Cairo.Context gr, RectangleD r, double radius, double stroke = 0.0) { if (stroke>0.0) { gr.LineWidth = stroke; double hsw = stroke / 2.0; - DrawRoundedRectangle (gr, hsw + r.X, hsw + r.Y, (double)r.Width - stroke, (double)r.Height - stroke, radius); + DrawRoundedRectangle (gr, hsw + r.X, hsw + r.Y, r.Width - stroke, r.Height - stroke, radius); gr.Stroke (); }else DrawRoundedRectangle(gr, r.X, r.Y, r.Width, r.Height, radius); diff --git a/Crow/src/Colors.cs b/Crow/src/Colors.cs index 8b918074..8cec2f4e 100644 --- a/Crow/src/Colors.cs +++ b/Crow/src/Colors.cs @@ -219,21 +219,18 @@ namespace Crow /// public double Saturation { get { - return Math.Max (R, Math.Max (G, B)); //Max. value of RGB + double min = Math.Min (R, Math.Min (G, B)); //Min. value of RGB + double max = Math.Max (R, Math.Max (G, B)); //Max. value of RGB + double diff = max - min; //Delta RGB value + return diff == 0 ? 0 : diff / max; } } /// /// compute the RGB intensity of the color /// /// The value. - public double Value { - get { - double min = Math.Min (R, Math.Min (G, B)); //Min. value of RGB - double max = Math.Max (R, Math.Max (G, B)); //Max. value of RGB - double diff = max - min; //Delta RGB value - return diff == 0 ? 0 : diff / max; - } - } + public double Value => Math.Max (R, Math.Max (G, B)); //Max. value of RGB + public string HtmlCode { get { string tmp = "#" + @@ -261,6 +258,7 @@ namespace Crow public void ResetName(){ Name = ""; htmlCode = ""; + predefinied = false; } #region Predefined colors @@ -446,35 +444,55 @@ namespace Crow { return (Color)s; } - public static Color FromHSV(double _h, double _v = 1.0, double _s = 1.0, double _alpha = 1.0){ - Color c = Color.Black; - c.ResetName (); - c.A = _alpha; - if (_s == 0) {//HSV from 0 to 1 - c.R = _v; - c.G = _v; - c.B = _v; - }else{ - double var_h = _h * 6.0; + //public static Color FromHSV(double _h, double _v = 1.0, double _s = 1.0, double _alpha = 1.0){ + // Color c = Color.Black; + // c.ResetName (); + // c.A = _alpha; + // if (_s == 0) {//HSV from 0 to 1 + // c.R = _v; + // c.G = _v; + // c.B = _v; + // }else{ + // double var_h = _h * 6.0; - if (var_h == 6.0) - var_h = 0; //H must be < 1 - double var_i = Math.Floor( var_h ); //Or ... var_i = floor( var_h ) - double var_1 = _v * ( 1.0 - _s ); - double var_2 = _v * (1.0 - _s * (var_h - var_i)); - double var_3 = _v * (1.0 - _s * (1.0 - (var_h - var_i))); + // if (var_h == 6.0) + // var_h = 0; //H must be < 1 + // double var_i = Math.Floor( var_h ); //Or ... var_i = floor( var_h ) + // double var_1 = _v * ( 1.0 - _s ); + // double var_2 = _v * (1.0 - _s * (var_h - var_i)); + // double var_3 = _v * (1.0 - _s * (1.0 - (var_h - var_i))); - if (var_i == 0.0) { - c.R = _v; - c.G = var_3; - c.B = var_1; - }else if ( var_i == 1.0 ) { c.R = var_2 ; c.G = _v ; c.B = var_1; } - else if ( var_i == 2 ) { c.R = var_1 ; c.G = _v ; c.B = var_3; } - else if ( var_i == 3 ) { c.R = var_1 ; c.G = var_2 ; c.B = _v; } - else if ( var_i == 4 ) { c.R = var_3 ; c.G = var_1 ; c.B = _v; } - else { c.R = _v ; c.G = var_1 ; c.B = var_2; } - } - return c; + // if (var_i == 0.0) { + // c.R = _v; + // c.G = var_3; + // c.B = var_1; + // }else if ( var_i == 1.0 ) { c.R = var_2 ; c.G = _v ; c.B = var_1; } + // else if ( var_i == 2 ) { c.R = var_1 ; c.G = _v ; c.B = var_3; } + // else if ( var_i == 3 ) { c.R = var_1 ; c.G = var_2 ; c.B = _v; } + // else if ( var_i == 4 ) { c.R = var_3 ; c.G = var_1 ; c.B = _v; } + // else { c.R = _v ; c.G = var_1 ; c.B = var_2; } + // } + // return c; + //} + public static Color FromHSV (double _h, double _v = 1.0, double _s = 1.0, double _alpha = 1.0) { + double H = _h * 360; + double C = _v * _s; + //X = C × (1 - | (H / 60°) mod 2 - 1 |) + double X = C * (1 - Math.Abs((H/60.0) % 2 - 1)); + double m = _v - C; + + if (H >= 300) + return new Color (C + m, m, X + m, _alpha); + if (H >= 240) + return new Color (X + m, m, C + m, _alpha); + if (H >= 180) + return new Color (m, X + m, C + m, _alpha); + if (H >= 120) + return new Color (m, C + m, X + m, _alpha); + if (H >= 60) + return new Color (X + m, C + m, m, _alpha); + + return new Color (C + m, X + m, m, _alpha); } - } + } } diff --git a/Crow/src/CompilerServices/CompilerServices.cs b/Crow/src/CompilerServices/CompilerServices.cs index e1048eba..d1751920 100644 --- a/Crow/src/CompilerServices/CompilerServices.cs +++ b/Crow/src/CompilerServices/CompilerServices.cs @@ -533,7 +533,7 @@ namespace Crow.IML internal static void emitConvert(ILGenerator il, Type origType, Type destType){ if (destType == typeof(object)) return; - if (destType == typeof(string)) { + if (destType == typeof (string)) { System.Reflection.Emit.Label emitNullStr = il.DefineLabel (); System.Reflection.Emit.Label endConvert = il.DefineLabel (); il.Emit (OpCodes.Dup); @@ -544,46 +544,46 @@ namespace Crow.IML il.Emit (OpCodes.Pop);//remove null string from stack il.Emit (OpCodes.Ldstr, "");//replace with empty string il.MarkLabel (endConvert); - }else if (origType.IsValueType) { + } else if ((origType.IsEnum || origType == typeof (Enum)) && destType.IsEnum) { + il.Emit (OpCodes.Unbox_Any, destType); + return; + } else if (origType.IsValueType) { if (destType != origType) { MethodInfo miIO = getImplicitOp (origType, destType); - if (miIO != null) - { - System.Reflection.Emit.Label emitCreateDefault = il.DefineLabel(); - System.Reflection.Emit.Label emitContinue = il.DefineLabel(); - LocalBuilder lbStruct = il.DeclareLocal(origType); - il.Emit(OpCodes.Dup); - il.Emit(OpCodes.Brfalse, emitCreateDefault); - il.Emit(OpCodes.Unbox_Any, origType); - il.Emit(OpCodes.Br, emitContinue); - il.MarkLabel(emitCreateDefault); - il.Emit(OpCodes.Pop);//pop null value - il.Emit(OpCodes.Ldloca, lbStruct); - il.Emit(OpCodes.Initobj, origType); - il.Emit(OpCodes.Ldloc, lbStruct); - il.MarkLabel(emitContinue); - il.Emit(OpCodes.Call, miIO); - } - else - { - MethodInfo miconv = CompilerServices.GetConvertMethod(destType); - if (miconv.IsStatic) - il.Emit(OpCodes.Call, miconv); - else - il.Emit(OpCodes.Callvirt, miconv); - } - }else + if (miIO != null) { + System.Reflection.Emit.Label emitCreateDefault = il.DefineLabel (); + System.Reflection.Emit.Label emitContinue = il.DefineLabel (); + LocalBuilder lbStruct = il.DeclareLocal (origType); + il.Emit (OpCodes.Dup); + il.Emit (OpCodes.Brfalse, emitCreateDefault); + il.Emit (OpCodes.Unbox_Any, origType); + il.Emit (OpCodes.Br, emitContinue); + il.MarkLabel (emitCreateDefault); + il.Emit (OpCodes.Pop);//pop null value + il.Emit (OpCodes.Ldloca, lbStruct); + il.Emit (OpCodes.Initobj, origType); + il.Emit (OpCodes.Ldloc, lbStruct); + il.MarkLabel (emitContinue); + il.Emit (OpCodes.Call, miIO); + } else { + MethodInfo miconv = CompilerServices.GetConvertMethod (destType); + if (miconv.IsStatic) + il.Emit (OpCodes.Call, miconv); + else + il.Emit (OpCodes.Callvirt, miconv); + } + } else il.Emit (OpCodes.Unbox_Any, destType);//TODO:double check this } else { - if (destType.IsAssignableFrom(origType)) + if (destType.IsAssignableFrom (origType)) il.Emit (OpCodes.Castclass, destType); else { //implicit conversion can't be defined from or to object base class, //so we will check if object underlying type is one of the implicit converter of destType - if (origType == typeof(object)) {//test all implicit converter to destType on obj + if (origType == typeof (object)) {//test all implicit converter to destType on obj System.Reflection.Emit.Label emitTestNextImpOp; System.Reflection.Emit.Label emitImpOpFound = il.DefineLabel (); - foreach (MethodInfo mi in destType.GetMethods(BindingFlags.Public|BindingFlags.Static)) { + foreach (MethodInfo mi in destType.GetMethods (BindingFlags.Public | BindingFlags.Static)) { if (mi.Name == "op_Implicit") { if (mi.GetParameters () [0].ParameterType == destType) continue; diff --git a/Crow/src/Enums.cs b/Crow/src/Enums.cs index 42adab57..ea163608 100644 --- a/Crow/src/Enums.cs +++ b/Crow/src/Enums.cs @@ -86,4 +86,20 @@ namespace Crow SW, SE, } + public enum CursorType + { + Rectangle, + Circle, + Pentagone + } + public enum ColorComponent + { + Red, + Green, + Blue, + Alpha, + Hue, + Saturation, + Value + } } diff --git a/Crow/src/GraphicObjects/ColorPicker.cs b/Crow/src/GraphicObjects/ColorPicker.cs index dd45023c..92837717 100644 --- a/Crow/src/GraphicObjects/ColorPicker.cs +++ b/Crow/src/GraphicObjects/ColorPicker.cs @@ -133,7 +133,7 @@ namespace Crow get { return new SolidColor(curColor); } set { if (value == null) - curColor = default(Color); + curColor = Color.White; else if (value is SolidColor) { Color c = (value as SolidColor).color; if (curColor == c) diff --git a/Crow/src/GraphicObjects/ColorSelector.cs b/Crow/src/GraphicObjects/ColorSelector.cs index 7ef037e9..83e69626 100644 --- a/Crow/src/GraphicObjects/ColorSelector.cs +++ b/Crow/src/GraphicObjects/ColorSelector.cs @@ -41,8 +41,6 @@ namespace Crow public ColorSelector (Interface iface) : base(iface){} #endregion - const double div = 255.0; - const double colDiv = 1.0 / div; protected Point mousePos; public override void onMouseMove (object sender, MouseMoveEventArgs e) @@ -68,6 +66,8 @@ namespace Crow mousePos.X = Math.Min(cb.Right, mousePos.X); mousePos.Y = Math.Max(cb.Y, mousePos.Y); mousePos.Y = Math.Min(cb.Bottom, mousePos.Y); + + RegisterForRedraw (); } } } diff --git a/Crow/src/GraphicObjects/ColorSlider.cs b/Crow/src/GraphicObjects/ColorSlider.cs new file mode 100644 index 00000000..9a7e470b --- /dev/null +++ b/Crow/src/GraphicObjects/ColorSlider.cs @@ -0,0 +1,287 @@ +// Copyright (c) 2013-2019 Bruyère Jean-Philippe jp_bruyere@hotmail.com +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; +using System.ComponentModel; +using Crow.Cairo; + +namespace Crow +{ + /// + /// simple squarred rgb color selector + /// + [DesignIgnore] + public class ColorSlider : Widget + { + #region CTOR + protected ColorSlider() : base(){} + public ColorSlider (Interface iface) : base(iface){} + #endregion + + protected Point mousePos; + Orientation orientation; + CursorType cursorType = CursorType.Pentagone; + ColorComponent component; + Color currentColor = Color.Black; + double currentValue; + + [DefaultValue (Orientation.Horizontal)] + public Orientation Orientation { + get => orientation; + set { + if (orientation == value) + return; + orientation = value; + NotifyValueChanged ("Orientation", orientation); + RegisterForGraphicUpdate (); + } + } + [DefaultValue (CursorType.Pentagone)] + public CursorType CursorType { + get => cursorType; + set { + if (cursorType == value) + return; + cursorType = value; + NotifyValueChanged ("CursorType", cursorType); + RegisterForRedraw (); + } + } + [DefaultValue (ColorComponent.Value)] + public ColorComponent Component { + get => component; + set { + if (component == value) + return; + component = value; + NotifyValueChanged ("Component", component); + RegisterForRedraw (); + } + } + public Color CurrentColor { + get => currentColor; + set { + if (currentColor == value) + return; + currentColor = value; + switch (component) { + case ColorComponent.Red: + if (currentValue != currentColor.R) { + currentValue = currentColor.R; + updateMousePosFromComponentValue (); + } + break; + case ColorComponent.Green: + if (currentValue != currentColor.G) { + currentValue = currentColor.G; + updateMousePosFromComponentValue (); + } + break; + case ColorComponent.Blue: + if (currentValue != currentColor.B) { + currentValue = currentColor.B; + updateMousePosFromComponentValue (); + } + break; + case ColorComponent.Alpha: + if (currentValue != currentColor.A) { + currentValue = currentColor.A; + updateMousePosFromComponentValue (); + } + break; + case ColorComponent.Hue: + if (currentValue != currentColor.Hue) { + currentValue = currentColor.Hue; + updateMousePosFromComponentValue (); + } + break; + case ColorComponent.Saturation: + if (currentValue != currentColor.Saturation) { + currentValue = currentColor.Saturation; + updateMousePosFromComponentValue (); + } + break; + case ColorComponent.Value: + if (currentValue != currentColor.Value) { + currentValue = currentColor.Value; + updateMousePosFromComponentValue (); + } + break; + } + NotifyValueChanged ("CurrentColor", currentColor); + RegisterForRedraw (); + } + } + public override void onMouseMove (object sender, MouseMoveEventArgs e) + { + base.onMouseMove (sender, e); + if (IFace.Mouse.LeftButton == ButtonState.Released) + return; + updateMouseLocalPos (e.Position); + } + public override void onMouseDown (object sender, MouseButtonEventArgs e) + { + base.onMouseDown (sender, e); + if (e.Button == MouseButton.Left) + updateMouseLocalPos (e.Position); + } + + protected override void onDraw (Context gr) { + base.onDraw (gr); + + RectangleD r = ClientRectangle; + r.Height -= 4; + r.Y += 2; + + Gradient.Type gt = Gradient.Type.Horizontal; + if (Orientation == Orientation.Vertical) + gt = Gradient.Type.Vertical; + + Gradient grad = new Gradient (gt); + Color c = currentColor; + + switch (component) { + case ColorComponent.Red: + grad.Stops.Add (new Gradient.ColorStop (0, new Color (0, c.G, c.B, c.A))); + grad.Stops.Add (new Gradient.ColorStop (1, new Color (1, c.G, c.B, c.A))); + break; + case ColorComponent.Green: + grad.Stops.Add (new Gradient.ColorStop (0, new Color (c.R, 0, c.B, c.A))); + grad.Stops.Add (new Gradient.ColorStop (1, new Color (c.R, 1, c.B, c.A))); + break; + case ColorComponent.Blue: + grad.Stops.Add (new Gradient.ColorStop (0, new Color (c.R, c.G, 0, c.A))); + grad.Stops.Add (new Gradient.ColorStop (1, new Color (c.R, c.G, 1, c.A))); + break; + case ColorComponent.Alpha: + grad.Stops.Add (new Gradient.ColorStop (0, new Color (c.R, c.G, c.B, 0))); + grad.Stops.Add (new Gradient.ColorStop (1, new Color (c.R, c.G, c.B, 1))); + break; + case ColorComponent.Hue: + grad.Stops.Add (new Gradient.ColorStop (0, new Color (1, 0, 0, 1))); + grad.Stops.Add (new Gradient.ColorStop (0.167, new Color (1, 1, 0, 1))); + grad.Stops.Add (new Gradient.ColorStop (0.333, new Color (0, 1, 0, 1))); + grad.Stops.Add (new Gradient.ColorStop (0.5, new Color (0, 1, 1, 1))); + grad.Stops.Add (new Gradient.ColorStop (0.667, new Color (0, 0, 1, 1))); + grad.Stops.Add (new Gradient.ColorStop (0.833, new Color (1, 0, 1, 1))); + grad.Stops.Add (new Gradient.ColorStop (1, new Color (1, 0, 0, 1))); + break; + case ColorComponent.Saturation: + grad.Stops.Add (new Gradient.ColorStop (0, Color.FromHSV (c.Hue, c.Value, 0.0, c.A))); + grad.Stops.Add (new Gradient.ColorStop (1, Color.FromHSV (c.Hue, c.Value, 1.0, c.A))); + break; + case ColorComponent.Value: + grad.Stops.Add (new Gradient.ColorStop (0, Color.FromHSV (c.Hue, 0.0, c.Saturation, c.A))); + grad.Stops.Add (new Gradient.ColorStop (1, Color.FromHSV (c.Hue, 1.0, c.Saturation, c.A))); + break; + } + + grad.SetAsSource (gr, r); + CairoHelpers.CairoRectangle (gr, r, CornerRadius); + gr.Fill (); + + r = ClientRectangle; + + switch (cursorType) { + case CursorType.Rectangle: + if (Orientation == Orientation.Horizontal) { + r.Width = 5; + r.X = mousePos.X - 2.5; + } else { + r.Height = 5; + r.Y = mousePos.Y - 2.5; + } + CairoHelpers.CairoRectangle (gr, r, 1); + break; + case CursorType.Circle: + if (Orientation == Orientation.Horizontal) + gr.Arc (mousePos.X, r.Center.Y, 3.5, 0, Math.PI * 2.0); + else + gr.Arc (r.Center.X, mousePos.Y, 3.5, 0, Math.PI * 2.0); + break; + case CursorType.Pentagone: + if (Orientation == Orientation.Horizontal) { + r.Width = 5; + r.X = mousePos.X - 2.5; + double y = r.CenterD.Y - r.Height * 0.2; + gr.MoveTo (mousePos.X, y); + y += r.Height * 0.15; + gr.LineTo (r.Right, y); + gr.LineTo (r.Right, r.Bottom - 0.5); + gr.LineTo (r.Left, r.Bottom - 0.5); + gr.LineTo (r.Left, y); + gr.ClosePath (); + } else { + } + break; + } + + gr.SetSourceColor (Color.Black); + gr.LineWidth = 2.0; + gr.StrokePreserve (); + gr.SetSourceColor (Color.White); + gr.LineWidth = 1.0; + gr.Stroke (); + } + public override void OnLayoutChanges (LayoutingType layoutType) { + base.OnLayoutChanges (layoutType); + + if (Orientation == Orientation.Horizontal) { + if (layoutType == LayoutingType.Width) + updateMousePosFromComponentValue (); + } else if (layoutType == LayoutingType.Height) + updateMousePosFromComponentValue (); + } + void updateMousePosFromComponentValue () { + if (Orientation == Orientation.Horizontal) + mousePos.X = (int)Math.Floor (currentValue * ClientRectangle.Width); + else + mousePos.Y = (int)Math.Floor (currentValue * ClientRectangle.Height); + RegisterForRedraw (); + } + + protected virtual void updateMouseLocalPos(Point mPos){ + Rectangle r = ScreenCoordinates (Slot); + Rectangle cb = ClientRectangle; + mousePos = mPos - r.Position; + + mousePos.X = Math.Max(cb.X, mousePos.X); + mousePos.X = Math.Min(cb.Right, mousePos.X); + mousePos.Y = Math.Max(cb.Y, mousePos.Y); + mousePos.Y = Math.Min(cb.Bottom, mousePos.Y); + + if (Orientation == Orientation.Horizontal) + currentValue = (double)mousePos.X / ClientRectangle.Width; + else + currentValue = (double)mousePos.Y / ClientRectangle.Height; + Color c = currentColor; + switch (component) { + case ColorComponent.Red: + CurrentColor = new Color(currentValue, c.G, c.B, c.A); + break; + case ColorComponent.Green: + CurrentColor = new Color (c.R, currentValue, c.B, c.A); + break; + case ColorComponent.Blue: + CurrentColor = new Color (c.R, c.G, currentValue, c.A); + break; + case ColorComponent.Alpha: + CurrentColor = new Color (c.R, c.G, c.B, currentValue); + break; + case ColorComponent.Hue: + CurrentColor = Color.FromHSV (currentValue, c.Value, c.Saturation, c.A); + break; + case ColorComponent.Saturation: + CurrentColor = Color.FromHSV (c.Hue, c.Value, currentValue, c.A); + break; + case ColorComponent.Value: + CurrentColor = Color.FromHSV (c.Hue, currentValue, c.Saturation, c.A); + break; + } + //NotifyValueChanged ("CurrentColor", currentColor); + //RegisterForRedraw (); + } + } +} + diff --git a/Crow/src/GraphicObjects/EnumSelector.cs b/Crow/src/GraphicObjects/EnumSelector.cs new file mode 100644 index 00000000..932e90e2 --- /dev/null +++ b/Crow/src/GraphicObjects/EnumSelector.cs @@ -0,0 +1,63 @@ +// Copyright (c) 2019 Bruyère Jean-Philippe jp_bruyere@hotmail.com +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; +using System.ComponentModel; + +namespace Crow +{ + /// + /// Convenient widget for selecting value from enum + /// + public class EnumSelector : GenericStack + { + #region CTOR + protected EnumSelector () : base(){} + public EnumSelector (Interface iface) : base(iface){} + #endregion + + #region private fields + Enum enumValue; + Type enumType; + #endregion + + #region public properties + /// + /// use to define the colors of the 3d border + /// + [DefaultValue(null)] + public virtual Enum EnumValue { + get { return enumValue; } + set { + if (enumValue == value) + return; + + enumValue = value; + + if (enumValue != null) { + if (enumType != enumValue.GetType ()) { + ClearChildren (); + enumType = enumValue.GetType (); + foreach (string en in enumType.GetEnumNames ()) { + RadioButton rb = new RadioButton (IFace); + rb.Caption = en; + if (enumValue.ToString() == en) + rb.IsChecked = true; + rb.Checked += (sender, e) => (((RadioButton)sender).Parent as EnumSelector).EnumValue = (Enum)Enum.Parse (enumType, (sender as RadioButton).Caption); + AddChild (rb); + RegisterForLayouting (LayoutingType.All); + } + } + } else + ClearChildren (); + + NotifyValueChanged ("EnumValue", enumValue); + RegisterForRedraw (); + } + } + #endregion + + } +} + diff --git a/Crow/src/GraphicObjects/HueSelector.cs b/Crow/src/GraphicObjects/HueSelector.cs index e9a31dfb..eb00a048 100644 --- a/Crow/src/GraphicObjects/HueSelector.cs +++ b/Crow/src/GraphicObjects/HueSelector.cs @@ -43,6 +43,7 @@ namespace Crow Orientation _orientation; double hue; + CursorType cursor = CursorType.Pentagone; [DefaultValue(Orientation.Horizontal)] public virtual Orientation Orientation @@ -72,7 +73,7 @@ namespace Crow { base.onDraw (gr); - Rectangle r = ClientRectangle; + RectangleD r = ClientRectangle; r.Height -= 4; r.Y += 2; @@ -80,7 +81,7 @@ namespace Crow if (Orientation == Orientation.Vertical) gt = Gradient.Type.Vertical; - Crow.Gradient grad = new Gradient (gt); + Gradient grad = new Gradient (gt); grad.Stops.Add (new Gradient.ColorStop (0, new Color (1, 0, 0, 1))); grad.Stops.Add (new Gradient.ColorStop (0.167, new Color (1, 1, 0, 1))); @@ -93,33 +94,51 @@ namespace Crow grad.SetAsSource (gr, r); CairoHelpers.CairoRectangle (gr, r, CornerRadius); gr.Fill(); - } - - public override void Paint (ref Context ctx) - { - base.Paint (ref ctx); - - Rectangle rb = Slot + Parent.ClientRectangle.Position; - ctx.Save (); - ctx.Translate (rb.X, rb.Y); - - ctx.SetSourceColor (Color.White); - Rectangle r = ClientRectangle; - if (Orientation == Orientation.Horizontal) { - r.Width = 4; - r.X = mousePos.X - 2; - } else { - r.Height = 4; - r.Y = mousePos.Y - 2; + r = ClientRectangle; + + switch (cursor) { + case CursorType.Rectangle: + if (Orientation == Orientation.Horizontal) { + r.Width = 5; + r.X = mousePos.X - 2.5; + } else { + r.Height = 5; + r.Y = mousePos.Y - 2.5; + } + CairoHelpers.CairoRectangle (gr, r, 1); + break; + case CursorType.Circle: + if (Orientation == Orientation.Horizontal) + gr.Arc (mousePos.X, r.Center.Y, 3.5, 0, Math.PI * 2.0); + else + gr.Arc (r.Center.X, mousePos.Y, 3.5, 0, Math.PI * 2.0); + break; + case CursorType.Pentagone: + if (Orientation == Orientation.Horizontal) { + r.Width = 5; + r.X = mousePos.X - 2.5; + double y = r.CenterD.Y-r.Height*0.2; + gr.MoveTo (mousePos.X, y); + y += r.Height * 0.15; + gr.LineTo (r.Right, y); + gr.LineTo (r.Right, r.Bottom-0.5); + gr.LineTo (r.Left, r.Bottom-0.5); + gr.LineTo (r.Left, y); + gr.ClosePath (); + } else { + } + break; } - CairoHelpers.CairoRectangle (ctx, r, 1); - ctx.SetSourceColor (Color.White); - ctx.LineWidth = 1.0; - ctx.Stroke(); - ctx.Restore (); + gr.SetSourceColor (Color.Black); + gr.LineWidth = 2.0; + gr.StrokePreserve (); + gr.SetSourceColor (Color.White); + gr.LineWidth = 1.0; + gr.Stroke (); } + public override void OnLayoutChanges (LayoutingType layoutType) { base.OnLayoutChanges (layoutType); diff --git a/Crow/src/GraphicObjects/PrivateContainer.cs b/Crow/src/GraphicObjects/PrivateContainer.cs index 1225cbb3..7909a6d9 100644 --- a/Crow/src/GraphicObjects/PrivateContainer.cs +++ b/Crow/src/GraphicObjects/PrivateContainer.cs @@ -75,6 +75,7 @@ namespace Crow contentSize = default(Size); child.LayoutChanged -= OnChildLayoutChanges; this.RegisterForGraphicUpdate (); + child.Dispose (); } child = _child as Widget; diff --git a/Crow/src/GraphicObjects/SaturationValueSelector.cs b/Crow/src/GraphicObjects/SaturationValueSelector.cs index 535a90df..779a6de6 100644 --- a/Crow/src/GraphicObjects/SaturationValueSelector.cs +++ b/Crow/src/GraphicObjects/SaturationValueSelector.cs @@ -39,8 +39,7 @@ namespace Crow } double v, s; - - + public virtual double V { get { return v; } set { @@ -91,28 +90,36 @@ namespace Crow CairoHelpers.CairoRectangle (gr, r, CornerRadius); gr.Fill(); + + gr.Arc (mousePos.X, mousePos.Y, 3.5, 0, Math.PI * 2.0); + gr.SetSourceColor (Color.Black); + gr.LineWidth = 2.0; + gr.StrokePreserve (); + gr.SetSourceColor (Color.White); + gr.LineWidth = 1.0; + gr.Stroke (); } - public override void Paint (ref Context ctx) - { - base.Paint (ref ctx); + //public override void Paint (ref Context ctx) + //{ + // base.Paint (ref ctx); - Rectangle rb = Slot + Parent.ClientRectangle.Position; - ctx.Save (); + // Rectangle rb = Slot + Parent.ClientRectangle.Position; + // ctx.Save (); - ctx.Translate (rb.X, rb.Y); + // ctx.Translate (rb.X, rb.Y); - ctx.SetSourceColor (Color.DimGrey); - ctx.Arc (mousePos.X, mousePos.Y, 3.5, 0, Math.PI * 2.0); - ctx.LineWidth = 0.5; - ctx.Stroke (); - ctx.Translate (-0.5, -0.5); - ctx.Arc (mousePos.X, mousePos.Y, 3.5, 0, Math.PI * 2.0); - ctx.SetSourceColor (Color.White); - ctx.Stroke (); + // ctx.SetSourceColor (Color.DimGrey); + // ctx.Arc (mousePos.X, mousePos.Y, 3.5, 0, Math.PI * 2.0); + // ctx.LineWidth = 0.5; + // ctx.Stroke (); + // ctx.Translate (-0.5, -0.5); + // ctx.Arc (mousePos.X, mousePos.Y, 3.5, 0, Math.PI * 2.0); + // ctx.SetSourceColor (Color.White); + // ctx.Stroke (); - ctx.Restore (); - } + // ctx.Restore (); + //} protected override void updateMouseLocalPos (Point mPos) { diff --git a/Crow/src/GraphicObjects/Shape.cs b/Crow/src/GraphicObjects/Shape.cs index 99678556..952c3738 100644 --- a/Crow/src/GraphicObjects/Shape.cs +++ b/Crow/src/GraphicObjects/Shape.cs @@ -1,30 +1,8 @@ -// -// Shape.cs +// Copyright (c) 2013-2019 Bruyère Jean-Philippe jp_bruyere@hotmail.com // -// Author: -// jp <> -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + using System; -using System.Xml.Serialization; using System.ComponentModel; using System.IO; using System.Text; @@ -36,7 +14,7 @@ namespace Crow { public PathParser (string str) : base (str) {} - public double ReadDouble () { + double readDouble () { StringBuilder tmp = new StringBuilder(); while (Peek () >= 0) { @@ -52,7 +30,44 @@ namespace Crow } return double.Parse (tmp.ToString ()); } - + public void Draw (Context gr) { + while (Peek () >= 0) { + char c = (char)Read (); + if (c.IsWhiteSpaceOrNewLine ()) + continue; + switch (c) { + case 'M': + gr.MoveTo (readDouble (), readDouble ()); + break; + case 'm': + gr.RelMoveTo (readDouble (), readDouble ()); + break; + case 'L': + gr.LineTo (readDouble (), readDouble ()); + break; + case 'l': + gr.RelLineTo (readDouble (), readDouble ()); + break; + case 'C': + gr.CurveTo (readDouble (), readDouble (), readDouble (), readDouble (), readDouble (), readDouble ()); + break; + case 'c': + gr.RelCurveTo (readDouble (), readDouble (), readDouble (), readDouble (), readDouble (), readDouble ()); + break; + case 'Z': + gr.ClosePath (); + break; + case 'F': + gr.Fill (); + break; + case 'G': + gr.Stroke (); + break; + default: + throw new Exception ("Invalid character in path string of Shape control"); + } + } + } } public class Shape : Widget { @@ -119,9 +134,9 @@ namespace Crow gr.Translate(r.Left, r.Top); gr.Scale (sx,sy); - - executePath (gr); - + using (PathParser parser = new PathParser (path)) + parser.Draw (gr); + Background.SetAsSource (gr, r); gr.FillPreserve (); gr.LineWidth = strokeWidth; @@ -130,46 +145,7 @@ namespace Crow gr.Restore(); } - void executePath (Context gr){ - using (PathParser sr = new PathParser (path)) { - while (sr.Peek () >= 0) { - char c = (char)sr.Read (); - if (c.IsWhiteSpaceOrNewLine ()) - continue; - switch (c) { - case 'M': - gr.MoveTo (sr.ReadDouble (), sr.ReadDouble ()); - break; - case 'm': - gr.RelMoveTo (sr.ReadDouble (), sr.ReadDouble ()); - break; - case 'L': - gr.LineTo (sr.ReadDouble (), sr.ReadDouble ()); - break; - case 'l': - gr.RelLineTo (sr.ReadDouble (), sr.ReadDouble ()); - break; - case 'C': - gr.CurveTo (sr.ReadDouble (), sr.ReadDouble (), sr.ReadDouble (), sr.ReadDouble (), sr.ReadDouble (), sr.ReadDouble ()); - break; - case 'c': - gr.RelCurveTo (sr.ReadDouble (), sr.ReadDouble (), sr.ReadDouble (), sr.ReadDouble (), sr.ReadDouble (), sr.ReadDouble ()); - break; - case 'Z': - gr.ClosePath (); - break; - case 'F': - gr.Fill (); - break; - case 'G': - gr.Stroke (); - break; - default: - throw new Exception ("Invalid character in path string of Shape control"); - } - } - } - } + protected override int measureRawSize (LayoutingType lt) { if ((lt == LayoutingType.Width && contentSize.Width == 0) || (lt == LayoutingType.Height && contentSize.Height == 0)) { @@ -181,7 +157,8 @@ namespace Crow { using (Context ctx = new Context(drawing)) { - executePath(ctx); + using (PathParser parser = new PathParser (path)) + parser.Draw (ctx); Rectangle r = ctx.StrokeExtents(); contentSize = new Size(r.Right, r.Bottom); } diff --git a/Crow/src/GraphicObjects/TemplatedContainer.cs b/Crow/src/GraphicObjects/TemplatedContainer.cs index 61078eb3..0acd8765 100644 --- a/Crow/src/GraphicObjects/TemplatedContainer.cs +++ b/Crow/src/GraphicObjects/TemplatedContainer.cs @@ -1,28 +1,6 @@ -// -// TemplatedContainer.cs +// Copyright (c) 2013-2019 Bruyère Jean-Philippe jp_bruyere@hotmail.com // -// Author: -// Jean-Philippe Bruyère -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; using System.Xml.Serialization; diff --git a/Crow/src/GraphicObjects/TemplatedControl.cs b/Crow/src/GraphicObjects/TemplatedControl.cs index d93cf4c8..563fc0a6 100644 --- a/Crow/src/GraphicObjects/TemplatedControl.cs +++ b/Crow/src/GraphicObjects/TemplatedControl.cs @@ -1,34 +1,12 @@ -// -// TemplatedControl.cs +// Copyright (c) 2013-2019 Bruyère Jean-Philippe jp_bruyere@hotmail.com // -// Author: -// Jean-Philippe Bruyère -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; using System.ComponentModel; using System.IO; -using System.Xml; using System.Reflection; +using System.Xml; using Crow.Cairo; namespace Crow @@ -69,7 +47,7 @@ namespace Crow public string Template { get { return _template; } set { - if (Template == value) + if (_template == value) return; _template = value; diff --git a/Crow/src/GraphicObjects/TemplatedGroup.cs b/Crow/src/GraphicObjects/TemplatedGroup.cs index 9d7415d2..da87b91e 100644 --- a/Crow/src/GraphicObjects/TemplatedGroup.cs +++ b/Crow/src/GraphicObjects/TemplatedGroup.cs @@ -206,7 +206,7 @@ namespace Crow { NotifyValueChanged ("Data", data); - lock (IFace.LayoutMutex) + lock (IFace.UpdateMutex) ClearItems (); if (data == null) @@ -393,6 +393,8 @@ namespace Crow { // isPaged = true; // } + if (_data == null) + return; foreach (object d in _data) { loadItem (d, page, _dataTest); diff --git a/Crow/src/GraphicObjects/Widget.cs b/Crow/src/GraphicObjects/Widget.cs index 4ffb1c0c..d6c3a968 100644 --- a/Crow/src/GraphicObjects/Widget.cs +++ b/Crow/src/GraphicObjects/Widget.cs @@ -163,22 +163,22 @@ namespace Crow GC.SuppressFinalize(this); } ~Widget(){ - Debug.WriteLine(this.ToString() + " not disposed by user"); + Console.WriteLine(this.ToString() + " not disposed by user"); Dispose(false); } protected virtual void Dispose(bool disposing){ if (disposed){ #if DEBUG_DISPOSE - Debug.WriteLine ("Trying to dispose already disposed obj: {0}", this.ToString()); + Console.WriteLine ("Trying to dispose already disposed obj: {0}", this.ToString()); #endif return; } if (disposing) { #if DEBUG_DISPOSE - Debug.WriteLine ("Disposing: {0}", this.ToString()); - if (IsQueueForRedraw) - throw new Exception("Trying to dispose an object queued for Redraw: " + this.ToString()); + Console.WriteLine ("Disposing: {0}", this.ToString()); + //if () + //throw new Exception("Trying to dispose an object queued for Redraw: " + this.ToString()); #endif unshownPostActions (); diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs index 4da0d1a7..2ef26fce 100644 --- a/Crow/src/Interface.cs +++ b/Crow/src/Interface.cs @@ -50,6 +50,7 @@ namespace Crow } #endregion + public IBackend Backend => backend; protected IBackend backend; protected bool running; @@ -127,18 +128,25 @@ namespace Crow Load ("#main.crow").DataSource = this; } catch { } } - public virtual void Run () { + /// + /// load styling, init default tooltips and context menus, load main.crow resource if exists. + /// + public void Init () { loadStyling (); - initTooltip (); - initContextMenus (); - - running = true; +// initTooltip (); +// initContextMenus (); Startup (); - + } + /// + /// call Init() then enter the running loop performing ProcessEvents until running==false. + /// + public virtual void Run () { + Init (); + running = true; while (running) { - ProcessEvents (); + backend?.ProcessEvents (); Thread.Sleep(1); } } @@ -190,9 +198,8 @@ namespace Crow } #endregion - public void ProcessEvents () + /*public void ProcessEvents () { - //if (armedClick != null) { // if (lastClickTime.ElapsedMilliseconds > DOUBLECLICK_TRESHOLD) { // //cancel double click and @@ -200,27 +207,7 @@ namespace Crow // armedClick = null; // } //} - - Widget w = _hoverWidget; //previous hover widget - - backend.ProcessEvents (); - - if (DragAndDropOperation != null) - return; - - if (!FOCUS_ON_HOVER || (w == _hoverWidget)) - return; - - w = _hoverWidget; - while (w != null) { - if (w.Focusable) { - FocusedWidget = w; - break; - } - w = w.FocusParent; - } - - } + }*/ #region Static and constants /// @@ -597,7 +584,18 @@ namespace Crow #if DEBUG_FOCUS NotifyValueChanged("HoverWidget", _hoverWidget); - #endif +#endif + + if (DragAndDropOperation == null && FOCUS_ON_HOVER) { + Widget w = _hoverWidget; + while (w != null) { + if (w.Focusable) { + FocusedWidget = w; + break; + } + w = w.FocusParent; + } + } if (_hoverWidget != null) { @@ -624,7 +622,15 @@ namespace Crow NotifyValueChanged("FocusedWidget", _focusedWidget); #endif if (_focusedWidget != null) + { _focusedWidget.HasFocus = true; +#if DEBUG_FOCUS + Debug.WriteLine ("Focus => " + _hoverWidget.ToString ()); + } else + Debug.WriteLine ("Focus => null"); +#else + } +#endif } } #endregion diff --git a/Crow/src/Mono.Cairo/Context.cs b/Crow/src/Mono.Cairo/Context.cs index 6bfa49b7..edfc8c66 100644 --- a/Crow/src/Mono.Cairo/Context.cs +++ b/Crow/src/Mono.Cairo/Context.cs @@ -431,7 +431,7 @@ namespace Crow.Cairo { { NativeMethods.cairo_arc (handle, xc, yc, radius, angle1, angle2); } - public void Arc (Point center, double radius, double angle1, double angle2) + public void Arc (PointD center, double radius, double angle1, double angle2) { NativeMethods.cairo_arc (handle, center.X, center.Y, radius, angle1, angle2); } diff --git a/Crow/src/Mono.Cairo/MeshPattern.cs b/Crow/src/Mono.Cairo/MeshPattern.cs index 96bc3c85..83da70b1 100644 --- a/Crow/src/Mono.Cairo/MeshPattern.cs +++ b/Crow/src/Mono.Cairo/MeshPattern.cs @@ -62,9 +62,15 @@ namespace Crow.Cairo { public void MoveTo(double x, double y){ NativeMethods.cairo_mesh_pattern_move_to (Handle, x, y); } + public void MoveTo (PointD p) { + NativeMethods.cairo_mesh_pattern_move_to (Handle, p.X, p.Y); + } public void LineTo(double x, double y){ NativeMethods.cairo_mesh_pattern_line_to (Handle, x, y); } + public void LineTo (PointD p) { + NativeMethods.cairo_mesh_pattern_line_to (Handle, p.X, p.Y); + } public void CurveTo(double x1, double y1, double x2, double y2, double x3, double y3) { NativeMethods.cairo_mesh_pattern_curve_to (Handle, x1, y1, x2, y2, x3, y3); @@ -72,12 +78,18 @@ namespace Crow.Cairo { public void SetControlPoint(uint point_num, double x, double y){ NativeMethods.cairo_mesh_pattern_set_control_point (Handle, point_num, x, y); } + public void SetControlPoint (uint point_num, PointD p) { + NativeMethods.cairo_mesh_pattern_set_control_point (Handle, point_num, p.X, p.Y); + } public void SetCornerColorRGB(uint corner_num, double r, double g, double b){ NativeMethods.cairo_mesh_pattern_set_corner_color_rgb (Handle, corner_num, r, g, b); } public void SetCornerColorRGBA(uint corner_num, double r, double g, double b, double a){ NativeMethods.cairo_mesh_pattern_set_corner_color_rgba (Handle, corner_num, r, g, b, a); } + public void SetCornerColor (uint corner_num, Color c) { + NativeMethods.cairo_mesh_pattern_set_corner_color_rgba (Handle, corner_num, c.R, c.G, c.B, c.A); + } public uint PatchCount { get { uint count = 0; @@ -88,7 +100,9 @@ namespace Crow.Cairo { public Path GetPath(uint patch_num){ return new Path(NativeMethods.cairo_mesh_pattern_get_path(Handle, patch_num)); } - public void GetControlPoint(){ + public PointD GetControlPoint(uint point_num, uint patch_num = 0) { + NativeMethods.cairo_mesh_pattern_get_control_point (Handle, patch_num, point_num, out double x, out double y); + return new PointD (x, y); } public void GetCornerColorRGBA(){ diff --git a/Crow/src/Rectangle.cs b/Crow/src/Rectangle.cs index 0a854194..afbb192d 100644 --- a/Crow/src/Rectangle.cs +++ b/Crow/src/Rectangle.cs @@ -132,8 +132,11 @@ namespace Crow { public static Rectangle operator + (Rectangle r, Point p) => new Rectangle (r.X + p.X, r.Y + p.Y, r.Width, r.Height); public static Rectangle operator - (Rectangle r, Point p) => new Rectangle (r.X - p.X, r.Y - p.Y, r.Width, r.Height); public static bool operator == (Rectangle r1, Rectangle r2) => r1.TopLeft == r2.TopLeft && r1.Size == r2.Size; - public static bool operator != (Rectangle r1, Rectangle r2) => !(r1.TopLeft == r2.TopLeft && r1.Size == r2.Size); - #endregion + public static bool operator != (Rectangle r1, Rectangle r2) => !(r1.TopLeft == r2.TopLeft && r1.Size == r2.Size); + + public static implicit operator Rectangle (RectangleD r) => new Rectangle ((int)Math.Round(r.X), (int)Math.Round (r.Y), + (int)Math.Round (r.Width), (int)Math.Round (r.Height)); + #endregion public override string ToString () => $"{X},{Y},{Width},{Height}"; public static Rectangle Parse(string s) diff --git a/Crow/src/RectangleD.cs b/Crow/src/RectangleD.cs index 4e17a176..817b3adc 100644 --- a/Crow/src/RectangleD.cs +++ b/Crow/src/RectangleD.cs @@ -132,7 +132,9 @@ namespace Crow { public static RectangleD operator + (RectangleD r, PointD p) => new RectangleD (r.X + p.X, r.Y + p.Y, r.Width, r.Height); public static RectangleD operator - (RectangleD r, PointD p) => new RectangleD (r.X - p.X, r.Y - p.Y, r.Width, r.Height); public static bool operator == (RectangleD r1, RectangleD r2) => r1.TopLeft == r2.TopLeft && r1.Size == r2.Size; - public static bool operator != (RectangleD r1, RectangleD r2) => !(r1.TopLeft == r2.TopLeft && r1.Size == r2.Size); + public static bool operator != (RectangleD r1, RectangleD r2) => !(r1.TopLeft == r2.TopLeft && r1.Size == r2.Size); + + public static implicit operator RectangleD(Rectangle r) => new RectangleD(r.X,r.Y,r.Width,r.Height); #endregion public override string ToString () => $"{X},{Y},{Width},{Height}"; diff --git a/Crow/src/backends/xcb/XCBBackend.cs b/Crow/src/backends/xcb/XCBBackend.cs index 7397af4f..706c59c4 100644 --- a/Crow/src/backends/xcb/XCBBackend.cs +++ b/Crow/src/backends/xcb/XCBBackend.cs @@ -1,34 +1,11 @@ -// -// XLibBackend.cs +// Copyright (c) 2019 Bruyère Jean-Philippe // -// Author: -// Jean-Philippe Bruyère -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + using System; using System.Collections.Generic; using System.Runtime.InteropServices; - - namespace Crow.XCB { using xcb_window_t = System.UInt32;