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 ();
}
}
///
/// Path expression, for syntax see 'PathParser'.
///
public string Path {
get { return path; }
set {
if (path == value)
return;
path = value;
contentSize = default (Size);
NotifyValueChangedAuto (path);
RegisterForGraphicUpdate ();
}
}
///
/// Default stroke width, may be overriden by a 'S' command in the path string.
///
/// The width of the stoke.
[DefaultValue (1.0)]
public double StrokeWidth {
get { return strokeWidth; }
set {
if (strokeWidth == value)
return;
strokeWidth = value;
contentSize = default (Size);
NotifyValueChangedAuto (strokeWidth);
RegisterForGraphicUpdate ();
}
}
///
/// View box size in pixel
///
[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);
}
}
}