]> O.S.I.I.S - jp/crow.git/commitdiff
shape widget
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 7 Feb 2018 20:48:11 +0000 (21:48 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 7 Feb 2018 20:48:11 +0000 (21:48 +0100)
scrollbar improvments
debug:perform mousemove event if mouseup had active widget.

14 files changed:
Crow.csproj
Default.style
Templates/FileDialog.template
Templates/ScrollBar.template
Templates/ScrollingListBox.template
Templates/TreeView.template
Tests/Interfaces/Divers/testShape.crow [new file with mode: 0644]
Tests/Tests.csproj
Tests/ui/showcase.crow
src/GraphicObjects/ScrollBar.cs
src/GraphicObjects/Scroller.cs
src/GraphicObjects/Shape.cs [new file with mode: 0644]
src/GraphicObjects/Slider.cs
src/Interface.cs

index c45642b5022f6d5e0a1af17834793c13707847be..90cc449596f16544570d606c2f33b0f104091e89 100644 (file)
     <Compile Include="src\Mono.Cairo\XlibSurface.cs" />
     <Compile Include="src\IML\IMLContext.cs" />
     <Compile Include="src\Mono.Cairo\MeshPattern.cs" />
+    <Compile Include="src\GraphicObjects\Shape.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="System" />
index 98c10255584089ec4a68d7d1b369ff4afe4cfd3a..b0cbbb82a6987eb1474c2db14db043863de670da 100644 (file)
@@ -146,4 +146,17 @@ CheckBoxAlt {
        Background = Transparent;
        Checked={Background=DarkSlateGray;Foreground=LightGray;};
        Unchecked = {Background=Transparent;Foreground=DimGray;};
+}
+
+ArrowBut {
+       MouseRepeat=true;
+       Height=Fit;
+       Width=Fit;
+       Focusable=true;
+       Foreground=Jet;
+       Background=hgradient|0:Gray|1:Jet;
+       MouseDown={Background=hgradient|0:White|0.2:BlueCrayola|1:Jet};
+       MouseUp={Background=hgradient|0:Gray|1:Jet};
+       MouseEnter={Foreground=Black};
+       MouseLeave={Foreground=Jet};
 }
\ No newline at end of file
index 62a7dc6d6e228467a7921a4d24f7c9b5df6ef85a..d9f93ed4452131203b49f5491193837663e7fd92 100644 (file)
@@ -38,6 +38,8 @@
                                                                                        Name="ItemsContainer" Margin="0" Spacing="1"/>
                                                                        </Scroller>
                                                                        <ScrollBar Name="scrollbar1" Value="{²../scroller1.ScrollY}"
+                                                                               LargeIncrement="{../scroller1.PageHeight}" SmallIncrement="30"
+                                                                               CursorSize="{../scroller1.ChildHeightRatio}"
                                                                                Maximum="{../scroller1.MaximumScroll}" Orientation="Vertical"
                                                                                Width="14" />
                                                                </HorizontalStack>
index f64b6c8e4f4cf1d44b397eb5bb9a84611dacba66..c2b9a1ba1aaff8afa77563fe2c7c348aaac7b7d3 100755 (executable)
@@ -1,21 +1,18 @@
 <?xml version="1.0"?>
-<Border BorderWidth="1" Foreground="LightGray">
+<Border BorderWidth="1" Foreground="Jet">
        <GenericStack Orientation="{./Orientation}" Spacing="0">
-               <Button MouseRepeat="true" Width="12" Height="12" MouseClick="./onScrollBack"
-                       Template="#Crow.Templates.ArrowBut.template">
-                       <Image Margin="1" Path="#Crow.Images.Icons.updown.svg" SvgSub="up"/>
-               </Button>
+               <Shape Style="ArrowBut" MouseClick="./onScrollBack" Path="M 5.5,0.5 L 10.5,10.5 L 0.5,10.5 Z"/>
                <Slider Name="Slider"
                        Orientation="{./Orientation}"
                        Value="{²./Value}"
                        Maximum="{./Maximum}"
+                       CursorSize="{./CursorSize}"
                        Height="{./HeightPolicy}" Width="{./WidthPolicy}"
                        LargeIncrement="{./LargeIncrement}"
                        SmallIncrement="{./SmallIncrement}"
+                       CursorColor="hgradient|0:Gray|1:Jet"
+                       Foreground="Jet"
                        Background="hgradient|0:DimGray|0.1:Gray|0.95:Gray|1:White"/>
-               <Button MouseRepeat="true" Width="12" Height="12" MouseClick="./onScrollForth"
-                       Template="#Crow.Templates.ArrowBut.template">
-                       <Image Margin="1" Path="#Crow.Images.Icons.updown.svg" SvgSub="down"/>
-               </Button>
+               <Shape Style="ArrowBut" MouseClick="./onScrollForth" Path="M 0.5,0.5 L 10.5,0.5 L 5.5,10.5 Z"/>
        </GenericStack>
 </Border>
\ No newline at end of file
index f294aea6635fdc735d2b308dd37a21bd31c3bb2c..56b08c037b6d163b04b9076a33d7c7896d866d88 100644 (file)
@@ -6,7 +6,8 @@
                        <VerticalStack Height="Fit" MinimumSize="10,10"
                                Name="ItemsContainer" Margin="0" VerticalAlignment="Top"/>
                </Scroller>
-               <ScrollBar Name="scrollbar1" Value="{²../scroller1.ScrollY}" 
+               <ScrollBar Name="scrollbar1" Value="{²../scroller1.ScrollY}"
+                       LargeIncrement="{../scroller1.PageHeight}" SmallIncrement="30" CursorSize="{../scroller1.ChildHeightRatio}"
                        Maximum="{../scroller1.MaximumScroll}" Orientation="Vertical" 
                        Width="14" />
        </HorizontalStack>
index c29e34c5ae5bafe9b80e781ec877e97b537eec9c..a1d9bc7237d093463d783599bef2d13cd3c6b015 100644 (file)
@@ -8,6 +8,8 @@
        </Scroller>
        <ScrollBar
                Name="scrollbar1"
+               LargeIncrement="{../scroller1.PageHeight}" SmallIncrement="30"
+               CursorSize="{../scroller1.ChildHeightRatio}"
                Value="{../scroller1.ScrollY}"
                Maximum="{../scroller1.MaximumScroll}"
                Width="14" Orientation="Vertical"/>
diff --git a/Tests/Interfaces/Divers/testShape.crow b/Tests/Interfaces/Divers/testShape.crow
new file mode 100644 (file)
index 0000000..61501b5
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<Container Fit="true" >
+       <Shape Foreground="Transparent" Background="Onyx" Path="M 5.5,0.5 L 10.5,10.5 L 0.5,10.5 Z"
+               MouseEnter="{Background=hgradient|0:Jet|0.5:BlueCrayola|1:Black}"
+               MouseLeave="{Background=Onyx}"/>
+</Container>
\ No newline at end of file
index ef4500a1e4b6006690bf099c90cbe15558237f4d..8096d9a8ae4b4eb3c170a64e422efa543d73b304 100644 (file)
     </None>
     <None Include="OpenTK.dll.config" />
     <None Include="packages.config" />
+    <None Include="Interfaces\Divers\testShape.crow">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
   </ItemGroup>
   <ItemGroup>
     <Folder Include="Interfaces\" />
index 24b038d658b38819d95f4009babf14cc6c2c51ea..20353e3321121c8883165a11550ca0aa6f989544 100755 (executable)
@@ -14,6 +14,8 @@
                                        Font="Courriernew 10"/>
                        </Scroller>
                        <ScrollBar Name="scrollbar1" Value="{../scroller1.ScrollY}"
+                               LargeIncrement="{../scroller1.PageHeight}" SmallIncrement="30"
+                               CursorSize="{../scroller1.ChildHeightRatio}"
                                Maximum="{../scroller1.MaximumScroll}" Orientation="Vertical"
                                Width="14" />
                </HorizontalStack>
index 31ff7acfe8af8cac52f9219a588329bd2c25090f..5dac20e17fd4447b25bbf9ec12acad9a082e35bd 100644 (file)
@@ -38,6 +38,7 @@ namespace Crow
                //TODO:could be replaced by a template for a Slider
 
                Orientation _orientation;
+               int _cursorSize;
 
                #region CTOR
                protected ScrollBar () : base(){}
@@ -56,6 +57,17 @@ namespace Crow
                                RegisterForGraphicUpdate ();
                        }
                }
+               [XmlAttributeAttribute()][DefaultValue(20)]
+               public virtual int CursorSize {
+                       get { return _cursorSize; }
+                       set {
+                               if (_cursorSize == value)
+                                       return;
+                               _cursorSize = value;
+                               RegisterForGraphicUpdate ();
+                               NotifyValueChanged ("CursorSize", _cursorSize);
+                       }
+               }
                public void onScrollBack (object sender, MouseButtonEventArgs e)
                {
                        Value -= SmallIncrement;
index 8dfed1ebb87327897fef2a498251c0c91d44e1cb..ec3bc47d47cc10d660d9b31a525d39fe821ed78d 100644 (file)
@@ -136,6 +136,15 @@ namespace Crow
                        base.OnLayoutChanges (layoutType);
 
                        NotifyValueChanged("MaximumScroll", MaximumScroll);
+                       if (layoutType == LayoutingType.Height) {
+                               NotifyValueChanged ("PageHeight", Slot.Height);
+                               if (child?.Slot.Height > 0)
+                                       NotifyValueChanged ("ChildHeightRatio", Slot.Height * Slot.Height / child.Slot.Height);
+                       } else {
+                               NotifyValueChanged ("PageWidth", Slot.Width);
+                               if (child?.Slot.Width > 0)
+                                       NotifyValueChanged ("ChildWidthRatio", Slot.Width * Slot.Width / child.Slot.Width);
+                       }
                }
                void OnChildLayoutChanges (object sender, LayoutingEventArgs arg)
                {
@@ -149,6 +158,8 @@ namespace Crow
                                                ScrollY = maxScroll;
                                        }
                                        NotifyValueChanged("MaximumScroll", maxScroll);
+                                       if (child?.Slot.Height > 0)
+                                               NotifyValueChanged ("ChildHeightRatio", Slot.Height * Slot.Height / child.Slot.Height);
                                }
                        } else if (arg.LayoutType == LayoutingType.Width) {
                                if (maxScroll < ScrollX) {
@@ -156,6 +167,8 @@ namespace Crow
                                        ScrollX = maxScroll;
                                }
                                NotifyValueChanged("MaximumScroll", maxScroll);
+                               if (child?.Slot.Width > 0)
+                                       NotifyValueChanged ("ChildWidthRatio", Slot.Width * Slot.Width / child.Slot.Width);
                        }
                }
                void onChildListCleared(object sender, EventArgs e){
diff --git a/src/GraphicObjects/Shape.cs b/src/GraphicObjects/Shape.cs
new file mode 100644 (file)
index 0000000..a4b3193
--- /dev/null
@@ -0,0 +1,164 @@
+//
+// Shape.cs
+//
+// 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.
+using System;
+using System.Xml.Serialization;
+using System.ComponentModel;
+using System.IO;
+using System.Text;
+using Cairo;
+
+namespace Crow
+{
+       public class PathParser : StringReader
+       {
+               public PathParser (string str) : base (str) {}
+
+               public double ReadDouble () {
+                       StringBuilder tmp = new StringBuilder();
+
+                       while (Peek () >= 0) {                          
+                               char c = (char)Read();
+                               if (c.IsWhiteSpaceOrNewLine()) {
+                                       if (tmp.Length == 0)
+                                               continue;
+                                       else
+                                               break;
+                               } else if (c == ',')
+                                       break;                          
+                               tmp.Append (c);
+                       }
+                       return double.Parse (tmp.ToString ());
+               }
+               
+       }
+       public class Shape : GraphicObject
+       {
+               #region CTOR
+               protected Shape () : base() {}
+               public Shape (Interface iface) : base (iface) {}
+               #endregion
+
+               string path;
+               double strokeWidth;
+
+               public string Path {
+                       get { return path; }
+                       set {
+                               if (path == value)
+                                       return;
+                               path = value;
+                               contentSize = default (Size);
+                               NotifyValueChanged ("Path", path);
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+               [XmlAttributeAttribute][DefaultValue(1.0)]
+               public double StokeWidth {
+                       get { return strokeWidth; }
+                       set {
+                               if (strokeWidth == value)
+                                       return;
+                               strokeWidth = value;
+                               contentSize = default (Size);
+                               NotifyValueChanged ("StrokeWidth", strokeWidth);
+                               RegisterForGraphicUpdate ();
+                       }
+               }
+
+               protected override void onDraw (Context gr)
+               {
+                       
+                       if (string.IsNullOrEmpty (path))
+                               return;
+
+                       Rectangle r = ClientRectangle;
+
+                       executePath (gr);
+
+                       Background.SetAsSource (gr, r);
+                       gr.FillPreserve ();
+                       gr.LineWidth = strokeWidth;
+                       Foreground.SetAsSource (gr, r);
+                       gr.Stroke ();                   
+               }
+
+               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)) {
+                               using (Surface drawing = new ImageSurface (Format.A1, 1,1)) {
+                                       using (Context ctx = new Context (drawing)) {
+                                               executePath (ctx);
+                                               Rectangle r = ctx.StrokeExtents ();
+                                               contentSize = new Size (r.Right, r.Bottom);
+                                       }
+                               }
+                       }
+                       return lt == LayoutingType.Width ?
+                               contentSize.Width + 2 * Margin: contentSize.Height + 2 * Margin;
+               }
+       }
+}
+
index a664f4e74174b0338fcd9359ed38412c3f06a1fb..2e4a5fef73fcc0a2a2ec25c3ebc23faf543a30d2 100644 (file)
@@ -83,7 +83,7 @@ namespace Crow
                public virtual int CursorSize {
                        get { return _cursorSize; }
                        set {
-                               if (_cursorSize == value)
+                               if (_cursorSize == value || value < 8)
                                        return;
                                _cursorSize = value;
                                RegisterForGraphicUpdate ();
@@ -132,9 +132,14 @@ namespace Crow
                        if (_orientation == Orientation.Horizontal) {
                                pStart = r.TopLeft + new Point (_cursorSize / 2, r.Height / 2);
                                pEnd = r.TopRight + new Point (-_cursorSize / 2, r.Height / 2);
+                               pStart.Y += 0.5;
+                               pEnd.Y += 0.5;
                        } else {
                                pStart = r.TopLeft + new Point (r.Width / 2, _cursorSize / 2);
                                pEnd = r.BottomLeft + new Point (r.Width / 2,- _cursorSize / 2);
+                               pStart.X += 0.5;
+                               pEnd.X += 0.5;
+
                        }
 
                        DrawGraduations (gr, pStart,pEnd);
index 7ea6128797b1a6aad2ef32d2d83c1fb6a786f80a..ab78e42d138ec19d8f0558e0464a7c50c3bedbe6 100644 (file)
@@ -848,7 +848,11 @@ namespace Crow
                        }
 
                        _activeWidget.onMouseUp (_activeWidget, e);
+                       GraphicObject lastActive = _activeWidget;
                        ActiveWidget = null;
+                       if (!lastActive.MouseIsIn (Mouse.Position)) {
+                               ProcessMouseMove (Mouse.X, Mouse.Y);
+                       }
                        return true;
                }
                /// <summary>