]> O.S.I.I.S - jp/crow.git/commitdiff
hsv color debug, color slider, enum selector, debug
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Mon, 7 Oct 2019 06:26:46 +0000 (08:26 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Mon, 7 Oct 2019 06:26:46 +0000 (08:26 +0200)
25 files changed:
Crow/Crow.csproj
Crow/Default.style
Crow/Templates/Window.template
Crow/src/Cairo/CairoHelpers.cs
Crow/src/Colors.cs
Crow/src/CompilerServices/CompilerServices.cs
Crow/src/Enums.cs
Crow/src/GraphicObjects/ColorPicker.cs
Crow/src/GraphicObjects/ColorSelector.cs
Crow/src/GraphicObjects/ColorSlider.cs [new file with mode: 0644]
Crow/src/GraphicObjects/EnumSelector.cs [new file with mode: 0644]
Crow/src/GraphicObjects/HueSelector.cs
Crow/src/GraphicObjects/PrivateContainer.cs
Crow/src/GraphicObjects/SaturationValueSelector.cs
Crow/src/GraphicObjects/Shape.cs
Crow/src/GraphicObjects/TemplatedContainer.cs
Crow/src/GraphicObjects/TemplatedControl.cs
Crow/src/GraphicObjects/TemplatedGroup.cs
Crow/src/GraphicObjects/Widget.cs
Crow/src/Interface.cs
Crow/src/Mono.Cairo/Context.cs
Crow/src/Mono.Cairo/MeshPattern.cs
Crow/src/Rectangle.cs
Crow/src/RectangleD.cs
Crow/src/backends/xcb/XCBBackend.cs

index b084eed8993d3e290547958d65369fa7c81d01cf..8e8934e9b2fe62ed44f948648b7fc16ab2218526 100644 (file)
@@ -25,7 +25,7 @@
        </PropertyGroup>
        <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
                <DebugType>full</DebugType>
-               <DefineConstants>TRACE;_DEBUG_BINDING;DESIGN_MODE;_DEBUG_CLIP_RECTANGLE;_DEBUG_FOCUS;_DEBUG_DRAGNDROP;NET471;DEBUG;NETFRAMEWORK;NET461</DefineConstants>
+               <DefineConstants>_DEBUG_DISPOSE;TRACE;_DEBUG_BINDING;DESIGN_MODE;_DEBUG_CLIP_RECTANGLE;_DEBUG_FOCUS;_DEBUG_DRAGNDROP;NET471;NETFRAMEWORK;NET461;DEBUG;NETSTANDARD;NETSTANDARD2_0</DefineConstants>
                <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
        </PropertyGroup>
        <!--  <ItemGroup Condition="$(TargetFramework.StartsWith('net4'))">
index 77b0d3cbd3fdc6b2229a96c834b320627176551f..4108a1fb9c85f80a128fb19507bbec1d2789b38f 100644 (file)
@@ -221,4 +221,9 @@ HScrollBar {
     Value = "0";
     Height = "12";
     Width = "Stretched";
+}
+EnumSelector {
+    Orientation = "Vertical";
+    Height = "Fit";
+    Spacing = "0";
 }
\ No newline at end of file
index ce3cfaeae3e19d91d8480cf42a9bc4573dee9f56..4517279ae7de1cdd97faa8fae4269a43625811fb 100755 (executable)
@@ -34,6 +34,6 @@
                                <Widget Width="5"/>
                        </HorizontalStack>
 <!--           </Border>-->
-               <Container Name="Content" MinimumSize="0,0" Background="0.5,0.5,0.5,0.5"/>
+               <Container Name="Content" MinimumSize="0,0"/>
        </VerticalStack>
 </Border>
index 032980d0164142991507c5787dd88e35c7d59634..0a5bd21bc29799721fc5b545885c9f7efa598059 100644 (file)
@@ -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);
index 8b91807413a4c4c8f9908b4def63c2c0b0e003c5..8cec2f4e71aa1bdd8c320454359fcfd5c3fd9ffd 100644 (file)
@@ -219,21 +219,18 @@ namespace Crow
                /// </summary>
                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;
                        }
                }
                /// <summary>
                /// compute the RGB intensity of the color
                /// </summary>
                /// <value>The value.</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);
                }
-    }
+       }
 }
index e1048eba08d979d09b44675302a0f7e2b1a99744..d1751920c2c919a0dcea1e38a2fcdb56ddd174b4 100644 (file)
@@ -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;
index 42adab57e8676c342f7547ee0440b8961ca323b9..ea163608f021898ebfdc9c9ea6f3c2c1ac01ed64 100644 (file)
@@ -86,4 +86,20 @@ namespace Crow
                SW,
                SE,
        }
+       public enum CursorType
+       {
+               Rectangle,
+               Circle,
+               Pentagone
+       }
+       public enum ColorComponent
+       {
+               Red,
+               Green,
+               Blue,
+               Alpha,
+               Hue,
+               Saturation,
+               Value
+       }
 }
index dd45023cde1624bf32c547ec628b8aa47a3702a5..928377177055f9fdd9085f51bf7a1d234640cae2 100644 (file)
@@ -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)
index 7ef037e90982da5de558910eb5bbae511f25c101..83e69626c48b0358a59b8a8b4dfcbc9d48a7727e 100644 (file)
@@ -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 (file)
index 0000000..9a7e470
--- /dev/null
@@ -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
+{
+       /// <summary>
+       /// simple squarred rgb color selector
+       /// </summary>
+       [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 (file)
index 0000000..932e90e
--- /dev/null
@@ -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
+{
+       /// <summary>
+       /// Convenient widget for selecting value from enum
+       /// </summary>
+       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
+               /// <summary>
+               /// use to define the colors of the 3d border
+               /// </summary>
+               [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
+
+       }
+}
+
index e9a31dfbeb0187bf0ae9df5418f66f9e809d5169..eb00a048b5e6924a7be9e9fae6cb2aacaaa7d58b 100644 (file)
@@ -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);
index 1225cbb385a6235993e6b42888c0e1e59e3ab438..7909a6d9d1fae4c9cf194b6d242e76ca74dc09dc 100644 (file)
@@ -75,6 +75,7 @@ namespace Crow
                                contentSize = default(Size);
                                child.LayoutChanged -= OnChildLayoutChanges;
                                this.RegisterForGraphicUpdate ();
+                               child.Dispose ();
                        }
 
                        child = _child as Widget;
index 535a90df198884774737e0ba1e09c04d921fd161..779a6de69e8e8c9ff32ada26db6a1b9d546b078c 100644 (file)
@@ -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)
                {
index 99678556afc66a9d73f7246f7de285072c65e9a1..952c3738b522d58565beaf8cf159ba78134e5611 100644 (file)
@@ -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);
                         }
index 61078eb3fbfb19e6775c2cc4af51ec9e39efaf71..0acd876505bb84ed4edc242bb856f0a792683470 100644 (file)
@@ -1,28 +1,6 @@
-//
-// TemplatedContainer.cs
+// Copyright (c) 2013-2019  Bruyère Jean-Philippe jp_bruyere@hotmail.com
 //
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// 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;
index d93cf4c8b64d3b6125248377349e8595c1a9976c..563fc0a67668a56a8fb49103389c53075d42e8e6 100644 (file)
@@ -1,34 +1,12 @@
-//
-// TemplatedControl.cs
+// Copyright (c) 2013-2019  Bruyère Jean-Philippe jp_bruyere@hotmail.com
 //
-// Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// 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;
 
index 9d7415d294b63b7ed0f45143ce1d7f45322e79c6..da87b91e578bf3eb05b1e072dd7d03a24e4e1aea 100644 (file)
@@ -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);
index 4ffb1c0cd118dac02da7ef4bfe55c33639b426a8..d6c3a9685bd508ee527a74843d249ad192951375 100644 (file)
@@ -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 ();
index 4da0d1a7a5195882515d11b1e02655b788b8e0aa..2ef26fced6fc1c31c66ac29c04ab08ace3850eda 100644 (file)
@@ -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 () {
+               /// <summary>
+               /// load styling, init default tooltips and context menus, load main.crow resource if exists.
+               /// </summary>
+               public void Init () {
                        loadStyling ();
 
-                       initTooltip ();
-                       initContextMenus ();
-
-                       running = true;
+//                     initTooltip ();
+//                     initContextMenus ();
 
                        Startup ();
-
+               }
+               /// <summary>
+               /// call Init() then enter the running loop performing ProcessEvents until running==false.
+               /// </summary>
+               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
                /// <summary>
@@ -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
index 6bfa49b73fe81ef5c41ac5319c1be20970ec5a0e..edfc8c6690c84920f4a6ef74098c705331238d1a 100644 (file)
@@ -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);
                }
index 96bc3c858caf594f862889f60e3a4bc11a786800..83da70b1932283e31eaccdbf292156f51d3e0895 100644 (file)
@@ -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(){
                        
index 0a85419418519ea723f690119621423f80f69d2e..afbb192d2805f2e702296ddfb23f0e8d41450171 100644 (file)
@@ -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)
index 4e17a17619ba5ec9efbf4502a972629e409595f1..817b3adc5fa8a20ef50c80d19fe4bb85114773be 100644 (file)
@@ -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}";        
index 7397af4f4c6834f9ab646ef9368ff2c094ee41f4..706c59c4ef4c6104921124b819eb30388663734b 100644 (file)
@@ -1,34 +1,11 @@
-//
-// XLibBackend.cs
+// Copyright (c) 2019  Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
 //
-// Author:
-//       Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// 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;