aboutsummaryrefslogtreecommitdiffstatsci
path: root/Samples/PathPainter
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2021-03-02 11:57:39 +0100
committerj-p <jp_bruyere@hotmail.com>2021-03-02 12:01:06 +0100
commit25a2b0d668dfea62e53a1fcf50ed32b43cfc2c68 (patch)
treebc77c325f93fb136b7a0ba977982d1262338ecf7 /Samples/PathPainter
parent5b5150e5e7e1eca0aa99de8b8a7aa6f38b7310d8 (diff)
implement theme from directory
Diffstat (limited to 'Samples/PathPainter')
-rw-r--r--Samples/PathPainter/Painter.cs203
-rw-r--r--Samples/PathPainter/PathPainter.csproj7
-rw-r--r--Samples/PathPainter/Program.cs76
-rw-r--r--Samples/PathPainter/ui/Icons/Lines.svg7
-rw-r--r--Samples/PathPainter/ui/Icons/Rect.svg6
-rw-r--r--Samples/PathPainter/ui/Icons/Select.svg6
-rw-r--r--Samples/PathPainter/ui/Painter.style3
-rw-r--r--Samples/PathPainter/ui/Spinner.template14
-rw-r--r--Samples/PathPainter/ui/colorSelector.template11
-rw-r--r--Samples/PathPainter/ui/main.crow43
10 files changed, 376 insertions, 0 deletions
diff --git a/Samples/PathPainter/Painter.cs b/Samples/PathPainter/Painter.cs
new file mode 100644
index 00000000..7e3c97bb
--- /dev/null
+++ b/Samples/PathPainter/Painter.cs
@@ -0,0 +1,203 @@
+using Crow.Cairo;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Text;
+
+namespace Crow
+{
+ public class Painter : ScrollingObject
+ {
+ #region CTOR
+ protected Painter () { }
+ public Painter (Interface iface, string style = null) : base (iface, style) { }
+ #endregion
+
+ public class Point
+ {
+ public double X;
+ public double Y;
+ }
+
+ public enum DrawMode
+ {
+ Select,
+ Lines,
+ Rect,
+ Arc,
+ }
+ DrawMode currentDrawMode = DrawMode.Select;
+ public DrawMode CurrentDrawMode {
+ get => currentDrawMode;
+ set {
+ if (value == currentDrawMode)
+ return;
+ currentDrawMode = value;
+ NotifyValueChanged ("CurrentDrawMode", currentDrawMode);
+ updateMouseCursor ();
+ }
+ }
+
+ void updateMouseCursor () {
+ if (currentDrawMode == DrawMode.Select)
+ MouseCursor = MouseCursor.arrow;
+ else
+ MouseCursor = MouseCursor.crosshair;
+ }
+
+ public double[] Zooms => new double[] { 0.5, 1.0, 2.0, 4.0, 8.0, 16.0 };
+
+ string path;
+ double strokeWidth;
+ Size size;
+ double zoom;
+ Fill shapeBackground, shapeForeground;
+
+ [DefaultValue(1.0)]
+ public double Zoom {
+ get => zoom;
+ set {
+ if (zoom == value)
+ return;
+ zoom = value;
+ NotifyValueChangedAuto (zoom);
+ RegisterForGraphicUpdate ();
+ updateMaxScrolls ();
+ }
+ }
+
+ /// <summary>
+ /// Path expression, for syntax see 'PathParser'.
+ /// </summary>
+ public string Path {
+ get { return path; }
+ set {
+ if (path == value)
+ return;
+ path = value;
+ contentSize = default (Size);
+ NotifyValueChangedAuto (path);
+ RegisterForGraphicUpdate ();
+ }
+ }
+ /// <summary>
+ /// Default stroke width, may be overriden by a 'S' command in the path string.
+ /// </summary>
+ /// <value>The width of the stoke.</value>
+ [DefaultValue (1.0)]
+ public double StrokeWidth {
+ get { return strokeWidth; }
+ set {
+ if (strokeWidth == value)
+ return;
+ strokeWidth = value;
+ contentSize = default (Size);
+ NotifyValueChangedAuto (strokeWidth);
+ RegisterForGraphicUpdate ();
+ }
+ }
+ /// <summary>
+ /// View box size in pixel
+ /// </summary>
+ [DefaultValue ("32,32")]
+ public Size Size {
+ get { return size; }
+ set {
+ if (size == value)
+ return;
+ size = value;
+ NotifyValueChangedAuto (size);
+ //RegisterForLayouting (LayoutingType.Sizing);
+ RegisterForGraphicUpdate ();
+ updateMaxScrolls ();
+ }
+ }
+
+ [DefaultValue ("White")]
+ public virtual Fill ShapeBackground {
+ get => shapeBackground;
+ set {
+ if (shapeBackground == value)
+ return;
+ shapeBackground = value;
+ NotifyValueChangedAuto (shapeBackground);
+ RegisterForRedraw ();
+ }
+ }
+ [DefaultValue ("Black")]
+ public virtual Fill ShapeForeground {
+ get => shapeForeground;
+ set {
+ if (shapeForeground == value)
+ return;
+ shapeForeground = value;
+ NotifyValueChangedAuto (shapeForeground);
+ RegisterForRedraw ();
+ }
+ }
+
+ public override void OnLayoutChanges (LayoutingType layoutType) {
+ base.OnLayoutChanges (layoutType);
+
+ if (layoutType == LayoutingType.Height)
+ NotifyValueChanged ("PageHeight", Slot.Height);
+ else if (layoutType == LayoutingType.Width)
+ NotifyValueChanged ("PageWidth", Slot.Width);
+ else
+ return;
+ updateMaxScrolls ();
+ }
+ public override void onMouseEnter (object sender, MouseMoveEventArgs e) {
+ base.onMouseEnter (sender, e);
+ updateMouseCursor ();
+ }
+ protected override void onDraw (Context gr) {
+ base.onDraw (gr);
+
+ if (string.IsNullOrEmpty (path))
+ return;
+
+ Rectangle cr = ClientRectangle;
+
+ gr.Save ();
+ gr.Translate (-ScrollX, -ScrollY);
+ gr.Scale (Zoom, Zoom);
+
+ Rectangle r = new Rectangle (cr.Position, size);
+ shapeBackground.SetAsSource (IFace, gr);
+ gr.Rectangle (r);
+ gr.Fill ();
+
+ gr.LineWidth = strokeWidth;
+ ShapeForeground.SetAsSource (IFace, gr, cr);
+
+ using (PathParser parser = new PathParser (path))
+ parser.Draw (gr);
+
+ gr.Restore ();
+ }
+
+ public override void onMouseWheel (object sender, MouseWheelEventArgs e) {
+ if (e.Delta > 0)
+ Zoom *= 2.0;
+ else
+ Zoom /= 2.0;
+ e.Handled = true;
+ base.onMouseWheel (sender, e);
+ }
+
+ void updateMaxScrolls () {
+ Rectangle cb = ClientRectangle;
+ Size scalledSize = size * Zoom;
+
+ MaxScrollX = scalledSize.Width - cb.Width;
+ if (scalledSize.Width > 0)
+ NotifyValueChanged ("ChildWidthRatio", (double)cb.Width / scalledSize.Width);
+
+ MaxScrollY = scalledSize.Height - cb.Height;
+ if (scalledSize.Height > 0)
+ NotifyValueChanged ("ChildHeightRatio", (double)cb.Height / scalledSize.Height);
+ }
+ }
+}
diff --git a/Samples/PathPainter/PathPainter.csproj b/Samples/PathPainter/PathPainter.csproj
new file mode 100644
index 00000000..173ecf80
--- /dev/null
+++ b/Samples/PathPainter/PathPainter.csproj
@@ -0,0 +1,7 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <ItemGroup>
+ <EmbeddedResource Include="ui\**\*.*">
+ <LogicalName>ui.%(Filename)%(Extension)</LogicalName>
+ </EmbeddedResource>
+ </ItemGroup>
+</Project>
diff --git a/Samples/PathPainter/Program.cs b/Samples/PathPainter/Program.cs
new file mode 100644
index 00000000..5993c852
--- /dev/null
+++ b/Samples/PathPainter/Program.cs
@@ -0,0 +1,76 @@
+using Crow;
+using System;
+
+namespace PathPainter
+{
+ class Program : SampleBase
+ {
+ static void Main (string[] args) {
+ using (Program app = new Program ())
+ app.Run ();
+ }
+
+ protected override void OnInitialized () {
+ base.OnInitialized ();
+ Load ("#ui.main.crow").DataSource = this;
+ }
+ string currentPath = "M 5.5,0.5 L 10.5,10.5 L 0.5,10.5 Z F";
+ int currentSize = 11;
+ double zoom = 1.0;
+ double strokeWidth = 1.0;
+ Color foreground = Colors.Black;
+ Color background = Colors.White;
+
+ public Measure DesignSize => (int)(zoom * currentSize);
+
+ public double StrokeWidth {
+ get => strokeWidth;
+ set {
+ if (strokeWidth == value)
+ return;
+ strokeWidth = value;
+ NotifyValueChanged (strokeWidth);
+ }
+ }
+ public string CurrentPath {
+ get => currentPath;
+ set {
+ if (currentPath == value)
+ return;
+ currentPath = value;
+ NotifyValueChanged (currentPath);
+ }
+ }
+ public Size Size => new Size (currentSize);
+ public int CurrentSize {
+ get => currentSize;
+ set {
+ if (currentSize == value)
+ return;
+ currentSize = value;
+ NotifyValueChanged (currentSize);
+ NotifyValueChanged ("Size", (object)new Size (currentSize));
+ NotifyValueChanged ("CurrentPath", (object)CurrentPath);
+ }
+ }
+ public Color Foreground {
+ get => foreground;
+ set {
+ if (foreground == value)
+ return;
+ foreground = value;
+ NotifyValueChanged (foreground);
+ }
+ }
+ public Color Background {
+ get => background;
+ set {
+ if (background == value)
+ return;
+ background = value;
+ NotifyValueChanged (background);
+ }
+ }
+
+ }
+}
diff --git a/Samples/PathPainter/ui/Icons/Lines.svg b/Samples/PathPainter/ui/Icons/Lines.svg
new file mode 100644
index 00000000..9fb54c4b
--- /dev/null
+++ b/Samples/PathPainter/ui/Icons/Lines.svg
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M1 11.9l-1 4.1 4.1-1 9.2-9.2-3.1-3.1-9.2 9.2zM1.5 15l-0.4-0.5 0.4-2 2 2-2 0.5zM10.9 4.4l-8.1 8-0.6-0.6 8.1-8 0.6 0.6z"></path>
+<path fill="#dddddd" d="M15.3 0.7c-1.1-1.1-2.6-0.5-2.6-0.5l-1.5 1.5 3.1 3.1 1.5-1.5c0-0.1 0.6-1.5-0.5-2.6zM13.4 1.6l-0.5-0.5c0.6-0.6 1.1-0.1 1.1-0.1l-0.6 0.6z"></path>
+</svg>
diff --git a/Samples/PathPainter/ui/Icons/Rect.svg b/Samples/PathPainter/ui/Icons/Rect.svg
new file mode 100644
index 00000000..d7d1dc8a
--- /dev/null
+++ b/Samples/PathPainter/ui/Icons/Rect.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M15 1h-14v14h14v-14zM14 14h-12v-12h12v12z"></path>
+</svg>
diff --git a/Samples/PathPainter/ui/Icons/Select.svg b/Samples/PathPainter/ui/Icons/Select.svg
new file mode 100644
index 00000000..605c0e28
--- /dev/null
+++ b/Samples/PathPainter/ui/Icons/Select.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M11.6 5c-0.2 0-0.5 0-0.6 0 0-0.2-0.2-0.6-0.4-0.8s-0.6-0.4-1.1-0.4c-0.2 0-0.4 0-0.6 0.1-0.1-0.2-0.2-0.3-0.3-0.5-0.2-0.2-0.5-0.4-1.1-0.4-0.2 0-0.4 0-0.5 0.1v-1.7c0-0.6-0.4-1.4-1.4-1.4-0.4 0-0.8 0.2-1.1 0.4-0.5 0.6-0.5 1.4-0.5 1.4v4.3c-0.6 0.1-1.1 0.3-1.4 0.6-0.6 0.7-0.6 1.6-0.6 2.8 0 0.2 0 0.5 0 0.7 0 1.4 0.7 2.1 1.4 2.8l0.3 0.4c1.3 1.2 2.4 1.6 5.1 1.6 2.9 0 4.2-1.6 4.2-5.1v-2.5c0-0.7-0.2-2.1-1.4-2.4zM12 7.4v2.6c0 3.4-1.3 4.1-3.2 4.1-2.4 0-3.3-0.3-4.3-1.3-0.1-0.1-0.2-0.2-0.4-0.4-0.7-0.8-1.1-1.2-1.1-2.2 0-0.2 0-0.5 0-0.7 0-1 0-1.7 0.3-2.1 0.1-0.1 0.4-0.2 0.7-0.2v0.5l-0.3 1.5c0 0.1 0 0.1 0.1 0.2s0.2 0 0.2 0l1-1.2c0-0.1 0-0.2 0-0.2v-6.2c0-0.1 0-0.5 0.2-0.7 0.1 0 0.2-0.1 0.4-0.1 0.3 0 0.4 0.3 0.4 0.4v3.1c0 0 0 0 0 0v1.2c0 0.3 0.2 0.6 0.5 0.6s0.5-0.3 0.5-0.5v-1.3c0 0 0 0 0 0 0-0.1 0.1-0.5 0.5-0.5 0.3 0 0.5 0.1 0.5 0.4v1.3c0 0.3 0.2 0.6 0.5 0.6s0.5-0.3 0.5-0.5v-0.7c0-0.1 0.1-0.3 0.5-0.3 0.2 0 0.3 0.1 0.3 0.1 0.2 0.1 0.2 0.4 0.2 0.4v0.8c0 0.3 0.2 0.5 0.4 0.5 0.3 0 0.5-0.1 0.5-0.4 0-0.1 0.1-0.2 0.2-0.3 0 0 0.1 0 0.2 0 0.6 0.2 0.7 1.2 0.7 1.5 0-0.1 0-0.1 0 0z"></path>
+</svg>
diff --git a/Samples/PathPainter/ui/Painter.style b/Samples/PathPainter/ui/Painter.style
new file mode 100644
index 00000000..02ad3e34
--- /dev/null
+++ b/Samples/PathPainter/ui/Painter.style
@@ -0,0 +1,3 @@
+DrawModeStyle {
+ Template="#polytest.ui.iconCheckBox.template";
+} \ No newline at end of file
diff --git a/Samples/PathPainter/ui/Spinner.template b/Samples/PathPainter/ui/Spinner.template
new file mode 100644
index 00000000..b4baf524
--- /dev/null
+++ b/Samples/PathPainter/ui/Spinner.template
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<VerticalStack>
+ <Label Text="{./Caption}"/>
+ <Border Style="ControlBorder" Background="{./Background}" CornerRadius="{./CornerRadius}">
+ <HorizontalStack Spacing="1">
+ <TextBox Style="ControlEditableText" Foreground="{./Foreground}" Font="{./Font}" Width="Stretched"
+ Text="{²./Value}" TextAlignment="Right" />
+ <VerticalStack Width="16" Height="Stretched" Spacing="0" Margin="0">
+ <Shape KeepProportions="false" Margin="1" Style="ArrowBut" Height="50%" MouseDown="./onUp" Size="10,10" Path="M 4.5,0.5 L 9.5,9.5 L 0.5,9.5 Z F"/>
+ <Shape KeepProportions="false" Margin="1" Style="ArrowBut" Height="50%" MouseDown="./onDown" Size="10,10" Path="M 0.5,0.5 L 9.5,0.5 L 4.5,9.5 Z F"/>
+ </VerticalStack>
+ </HorizontalStack>
+ </Border>
+</VerticalStack> \ No newline at end of file
diff --git a/Samples/PathPainter/ui/colorSelector.template b/Samples/PathPainter/ui/colorSelector.template
new file mode 100644
index 00000000..cc12a623
--- /dev/null
+++ b/Samples/PathPainter/ui/colorSelector.template
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<CheckBox Caption="{./Caption}" IsChecked="{²./IsPopped}" Foreground="{./Foreground}" Background="{./Background}">
+ <Template>
+ <Border Style="ControlBorder" CornerRadius="{./CornerRadius}">
+ <HorizontalStack Spacing="10" Margin="5">
+ <Label Style="ControlCaption" Text="{./Caption}" />
+ <Border Foreground="White" Width="30" Height="20" Background="{./Background}" CornerRadius="5"/>
+ </HorizontalStack>
+ </Border>
+ </Template>
+</CheckBox> \ No newline at end of file
diff --git a/Samples/PathPainter/ui/main.crow b/Samples/PathPainter/ui/main.crow
new file mode 100644
index 00000000..bb0a6297
--- /dev/null
+++ b/Samples/PathPainter/ui/main.crow
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<HorizontalStack Background="DarkGrey" >
+ <VerticalStack>
+ <HorizontalStack Height="Fit">
+ <EnumSelector Fit="true" Caption="Draw Mode" EnumValue="{²../../painter.CurrentDrawMode}" />
+ <ComboBox Data="{../../painter.Zooms}" SelectedItem="{²../../painter.Zoom}" Width="60"/>
+ </HorizontalStack>
+ <HorizontalStack>
+ <Border Foreground="Black" Width="Stretched" Height="Stretched" Margin="0" HorizontalAlignment="Left" VerticalAlignment="Top">
+ <Painter Name="painter" ShapeForeground="{Foreground}" ShapeBackground="{Background}"
+ Zoom="1"
+ Size="{Size}" Path="{²CurrentPath}" StrokeWidth="{StrokeWidth}"/>
+ </Border>
+ <ScrollBar Value="{²../painter.ScrollY}"
+ LargeIncrement="{../painter.PageHeight}" SmallIncrement="1"
+ CursorRatio="{../painter.ChildHeightRatio}" Maximum="{../painter.MaxScrollY}" />
+ </HorizontalStack>
+ <ScrollBar Style="HScrollBar" Value="{²../painter.ScrollX}"
+ LargeIncrement="{../painter.PageWidth}" SmallIncrement="1"
+ CursorRatio="{../painter.ChildWidthRatio}" Maximum="{../painter.MaxScrollX}" />
+ </VerticalStack>
+ <Splitter/>
+ <VerticalStack Margin="2" Spacing="2">
+ <TextBox Width="Stretched" Text="{²CurrentPath}"/>
+ <HorizontalStack Height="Fit">
+ <Spinner Caption="Stroke Width" SmallIncrement="0.1" LargeIncrement="0.5" Value="{²StrokeWidth}" Width="Fit" Template="#ui.Spinner.template"/>
+ <Spinner Caption="Size" Value="{²CurrentSize}" Width="Fit" Template="#ui.Spinner.template"/>
+ <Popper Caption="Foreground" Background="{Foreground}" Fit="True" Template="#ui.colorSelector.template">
+ <ColorPicker CurrentColor="{²Foreground}" Background="Onyx" Width="{../PopWidth}"/>
+ </Popper>
+ <Popper Caption="Background" Background="{Background}" Fit="True" Template="#ui.colorSelector.template">
+ <ColorPicker CurrentColor="{²Background}" Background="Onyx" Width="{../PopWidth}"/>
+ </Popper>
+ </HorizontalStack>
+ <Group Height="200" Background="Jet">
+ <Shape Left="23" Top="9" Margin="0" Width="16" Height="16" Foreground="{Foreground}" Background="{Background}" Size="{Size}" Path="{CurrentPath}" StrokeWidth="{StrokeWidth}"/>
+ <Shape Left="17" Top="31" Margin="0" Width="32" Height="32" Foreground="{Foreground}" Background="{Background}" Size="{Size}" Path="{CurrentPath}" StrokeWidth="{StrokeWidth}"/>
+ <Shape Left="65" Top="1" Margin="0" Width="64" Height="64" Foreground="{Foreground}" Background="{Background}" Size="{Size}" Path="{CurrentPath}" StrokeWidth="{StrokeWidth}"/>
+ <Shape Left="1" Top="66" Margin="0" Width="128" Height="128" Foreground="{Foreground}" Background="{Background}" Size="{Size}" Path="{CurrentPath}" StrokeWidth="{StrokeWidth}"/>
+ </Group>
+
+ </VerticalStack>
+</HorizontalStack>