[longomatch] Add a first Gtk+Cairo drawing backend



commit bdccbc3357efd386e0f0849b7fe1d5700d23a34c
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date:   Wed May 14 19:17:24 2014 +0200

    Add a first Gtk+Cairo drawing backend

 LongoMatch.Drawing.Cairo/CairoBackend.cs           |  249 ++++++++++++++++++++
 .../LongoMatch.Drawing.Cairo.mdp                   |   27 ++
 LongoMatch.Drawing.Cairo/WidgetWrapper.cs          |  197 ++++++++++++++++
 3 files changed, 473 insertions(+), 0 deletions(-)
---
diff --git a/LongoMatch.Drawing.Cairo/CairoBackend.cs b/LongoMatch.Drawing.Cairo/CairoBackend.cs
new file mode 100644
index 0000000..8693789
--- /dev/null
+++ b/LongoMatch.Drawing.Cairo/CairoBackend.cs
@@ -0,0 +1,249 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using System.Collections.Generic;
+using Cairo;
+using LongoMatch.Interfaces;
+using LongoMatch.Common;
+using LColor = LongoMatch.Common.Color;
+using Point = LongoMatch.Common.Point;
+using Color = Cairo.Color;
+using LFontSlant = LongoMatch.Common.FontSlant;
+using LFontWeight = LongoMatch.Common.FontWeight;
+using FontSlant = Cairo.FontSlant;
+using FontWeight = Cairo.FontWeight;
+
+namespace LongoMatch.Drawing.Cairo
+{
+       public class CairoBackend: IDrawingToolkit
+       {
+               Context context;
+               Color strokeColor;
+               Color fillColor;
+               FontSlant fSlant;
+               FontWeight fWeight;
+               
+               public CairoBackend ()
+               {
+                       Translation = new Point (0, 0);
+                       StrokeColor = new LColor (0, 0, 0, 0);
+                       FillColor = new LColor (0, 0, 0, 0);
+                       LineWidth = 2;
+                       FontSize = 12;
+                       FontFamily = "Verdana";
+                       FontWeight = LFontWeight.Normal;
+                       FontSlant = LFontSlant.Normal;
+               }
+               
+               public object Context {
+                       set {
+                               context = value as Context;
+                       }
+               }
+               
+               public int LineWidth {
+                       set;
+                       protected get;
+               }
+               
+               public Point Translation {
+                       set;
+                       protected get;
+               }
+               
+               public LColor StrokeColor {
+                       set {
+                               strokeColor = ColorToCairoColor (value);
+                       }
+               }
+               
+               public LColor FillColor {
+                       set {
+                               fillColor = ColorToCairoColor (value);
+                       }
+               }
+               
+               public string FontFamily {
+                       set;
+                       protected get;
+                       
+               }
+               
+               public int FontSize {
+                       set;
+                       protected get;
+               }
+               
+               public LFontSlant FontSlant {
+                       set {
+                               switch (value) {
+                               case LFontSlant.Italic:
+                                       fSlant = FontSlant.Italic;
+                                       break;
+                               case LFontSlant.Normal:
+                                       fSlant = FontSlant.Normal;
+                                       break;
+                               case LFontSlant.Oblique:
+                                       fSlant = FontSlant.Oblique;
+                                       break;
+                               }
+                       }
+               }
+               
+               public LFontWeight FontWeight {
+                       set {
+                               switch (value) {
+                               case LFontWeight.Bold:
+                                       fWeight = FontWeight.Bold;
+                                       break;
+                               case LFontWeight.Normal:
+                                       fWeight = FontWeight.Normal;
+                                       break;
+                               }
+                       }
+               }
+               
+               public void Begin() {
+                       context.Save ();
+                       context.Translate (Translation.X, Translation.Y);
+               }
+               
+               public void End() {
+                       context.Restore ();
+               }
+               
+               public void DrawLine (Point start, Point stop) {
+                       context.Color = strokeColor;
+                       context.LineWidth = LineWidth;
+                       context.MoveTo (start.X, start.Y);
+                       context.LineTo (stop.X, stop.Y);
+                       context.Stroke();
+               }
+               
+               public void DrawTriangle (Point corner, double width, double height) {
+                       double x, y;
+                       
+                       x = corner.X;
+                       y = corner.Y;
+                       context.Color = strokeColor;
+                       context.MoveTo (x, y);
+                       context.LineTo (x + width/2, y + height);
+                       context.LineTo (x - width/2, y - height);
+                       context.ClosePath();
+                       context.StrokePreserve ();
+                       context.Color = fillColor;
+                       context.Fill();
+               }
+               
+               public void DrawArea (List<Point> vertices) {
+                       for (int i=0; i < vertices.Count - 1; i++) {
+                               double x1, y1, x2, y2;
+                               
+                               x1 = vertices[i].X;
+                               y1 = vertices[i].Y;
+                               x2 = vertices[i+1].X;
+                               y2 = vertices[i+1].Y;
+                               
+                               context.MoveTo (x1, y1);
+                               context.LineTo (x2, y2);
+                       }
+                       context.ClosePath();
+                       StrokeAndFill ();
+               }
+               
+               public void DrawRectangle (Point start, double width, double height) {
+                       context.Rectangle (new PointD (start.X + LineWidth / 2, start.Y + LineWidth / 2),
+                                          width - LineWidth, height - LineWidth);
+                       StrokeAndFill ();
+               }
+               
+               public void DrawRoundedRectangle (Point start, double width, double height, double radius) {
+                       double x, y;
+                       
+                       x = start.X + LineWidth / 2;
+                       y = start.Y + LineWidth / 2;
+                       height -= LineWidth;
+                       width -= LineWidth;
+
+                       if((radius > height / 2) || (radius > width / 2))
+                               radius = Math.Min (height / 2, width / 2);
+
+                       context.MoveTo (x, y + radius);
+                       context.Arc (x + radius, y + radius, radius, Math.PI, -Math.PI / 2);
+                       context.LineTo (x + width - radius, y);
+                       context.Arc (x + width - radius, y + radius, radius, -Math.PI / 2, 0);
+                       context.LineTo (x + width, y + height - radius);
+                       context.Arc (x + width - radius, y + height - radius, radius, 0, Math.PI / 2);
+                       context.LineTo (x + radius, y + height);
+                       context.Arc (x + radius, y + height - radius, radius, Math.PI / 2, Math.PI);
+                       context.ClosePath();
+                       StrokeAndFill ();
+               }
+
+               public void DrawCircle (Point center, double radius) {
+                       context.MoveTo (center.X, center.Y);
+                       context.Arc (center.X, center.Y, radius, 0, 2 * Math.PI);
+                       StrokeAndFill ();
+               }
+
+               public void DrawPoint (Point point) {
+                       DrawCircle (point, LineWidth);
+               }
+               
+               public void DrawText (Point point, double width, double height, string text) {
+                       TextExtents extents;
+                       FontExtents fextents;
+                       double x, y;
+                       
+                       context.Color = strokeColor;
+                       context.SelectFontFace (FontFamily, fSlant, fWeight);
+                       context.SetFontSize (FontSize);
+                       extents = context.TextExtents (text);
+                       fextents = context.FontExtents;
+                       x = point.X + width / 2 - (extents.Width / 2 + extents.XBearing);
+                       y = point.Y + height / 2 - (extents.Height / 2 + extents.YBearing);
+                       context.MoveTo (x, y);
+                       context.ShowText (text);
+               }
+               
+               public void DrawImage (Point start, double width, double height, Image image) {
+               }
+
+               public void DrawEllipse (Point center, double axisX, double axisY) {
+               }
+               
+               void StrokeAndFill () {
+                       context.LineCap = LineCap.Round;
+                       context.LineJoin = LineJoin.Round;
+                       context.LineWidth = LineWidth;
+                       context.Color = strokeColor;
+                       context.StrokePreserve();
+                       context.Color = fillColor;
+                       context.Fill();
+               }
+               
+               Color ColorToCairoColor (LColor color) {
+                       return new Color ((double) color.R / ushort.MaxValue,
+                                         (double) color.G / ushort.MaxValue,
+                                         (double) color.B / ushort.MaxValue,
+                                         (double) color.A / ushort.MaxValue);
+               }
+               
+       }
+}
+
diff --git a/LongoMatch.Drawing.Cairo/LongoMatch.Drawing.Cairo.mdp 
b/LongoMatch.Drawing.Cairo/LongoMatch.Drawing.Cairo.mdp
new file mode 100644
index 0000000..225d372
--- /dev/null
+++ b/LongoMatch.Drawing.Cairo/LongoMatch.Drawing.Cairo.mdp
@@ -0,0 +1,27 @@
+<Project name="LongoMatch.Drawing.Cairo" fileversion="2.0" DefaultNamespace="LongoMatch.Drawing.Cairo" 
language="C#" targetFramework="4.0" ctype="DotNetProject">
+  <Configurations active="Release">
+    <Configuration name="Debug" ctype="DotNetProjectConfiguration">
+      <Output directory="bin/Debug" assembly="LongoMatch.Drawing.Cairo" />
+      <Build debugmode="True" target="Library" />
+      <Execution consolepause="False" runwithwarnings="True" runtime="MsNet" />
+      <CodeGeneration compiler="Mcs" warninglevel="4" optimize="False" unsafecodeallowed="False" 
generateoverflowchecks="False" definesymbols="DEBUG;" generatexmldocumentation="False" 
ctype="CSharpCompilerParameters" />
+    </Configuration>
+    <Configuration name="Release" ctype="DotNetProjectConfiguration">
+      <Output directory="bin/Release" assembly="LongoMatch.Drawing.Cairo" />
+      <Build debugmode="False" target="Library" />
+      <Execution consolepause="False" runwithwarnings="True" runtime="MsNet" />
+      <CodeGeneration compiler="Mcs" warninglevel="4" optimize="True" unsafecodeallowed="False" 
generateoverflowchecks="False" generatexmldocumentation="False" ctype="CSharpCompilerParameters" />
+    </Configuration>
+  </Configurations>
+  <Contents>
+    <File subtype="Code" buildaction="Compile" name="CairoBackend.cs" />
+    <File subtype="Code" buildaction="Compile" name="WidgetWrapper.cs" />
+  </Contents>
+  <References>
+    <ProjectReference type="Gac" localcopy="True" refto="System, Version=4.0.0.0, Culture=neutral, 
PublicKeyToken=b77a5c561934e089" />
+    <ProjectReference specificVersion="False" type="Gac" localcopy="False" refto="Mono.Cairo, 
Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
+    <ProjectReference type="Project" localcopy="True" refto="LongoMatch.Core" />
+    <ProjectReference type="Gac" localcopy="False" refto="gtk-sharp, Version=2.12.0.0, Culture=neutral, 
PublicKeyToken=35e10195dab3c99f" />
+    <ProjectReference type="Gac" localcopy="False" refto="gdk-sharp, Version=2.12.0.0, Culture=neutral, 
PublicKeyToken=35e10195dab3c99f" />
+  </References>
+</Project>
\ No newline at end of file
diff --git a/LongoMatch.Drawing.Cairo/WidgetWrapper.cs b/LongoMatch.Drawing.Cairo/WidgetWrapper.cs
new file mode 100644
index 0000000..3100d40
--- /dev/null
+++ b/LongoMatch.Drawing.Cairo/WidgetWrapper.cs
@@ -0,0 +1,197 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using Gtk;
+using Gdk;
+using Cairo;
+using LongoMatch.Common;
+using LongoMatch.Interfaces.Drawing;
+using LongoMatch.Handlers.Drawing;
+
+using Rectangle = Gdk.Rectangle;
+using Point = LongoMatch.Common.Point;
+using CursorType = LongoMatch.Common.CursorType;
+using GCursorType = Gdk.CursorType;
+
+namespace LongoMatch.Drawing.Cairo
+{
+       public class WidgetWrapper: IWidget
+       {
+               public event DrawingHandler DrawEvent;
+               public event ButtonPressedHandler ButtonPressEvent;
+               public event ButtonReleasedHandler ButtonReleasedEvent;
+               public event MotionHandler MotionEvent;
+
+               DrawingArea widget;
+               
+               public WidgetWrapper (DrawingArea widget)
+               {
+                       this.widget = widget;
+                       widget.Events |= EventMask.PointerMotionMask;
+                       widget.Events |= EventMask.ButtonPressMask;
+                       widget.Events |= EventMask.ButtonReleaseMask ;
+                       widget.ExposeEvent += HandleExposeEvent;
+                       widget.ButtonPressEvent += HandleButtonPressEvent;
+                       widget.ButtonReleaseEvent += HandleButtonReleaseEvent;
+                       widget.MotionNotifyEvent += HandleMotionNotifyEvent;
+               }
+
+               public double Width {
+                       get {
+                               return widget.Allocation.Width;
+                       }
+                       set {
+                               widget.WidthRequest = (int) value;
+                       }
+               }
+
+               public double Height {
+                       get {
+                               return widget.Allocation.Height;
+                       }
+                       set {
+                               widget.HeightRequest = (int) value;
+                       }
+               }
+               
+               public void QueueDraw () {
+                       widget.QueueDraw ();
+               }
+               
+               public void Redraw (Area area) {
+                       if (DrawEvent != null) {
+                               using (Context c = CairoHelper.Create (widget.GdkWindow)) {
+                                       if (area == null) {
+                                               area = new Area (new Point (0, 0), Width, Height);
+                                       }
+                                       DrawEvent (c, area);
+                               }
+                       }
+               }
+               
+               public void Redraw (ICanvasObject obj) {
+                       using (Context c = CairoHelper.Create (widget.GdkWindow)) {
+                               Config.DrawingToolkit.Context = c;
+                               obj.Draw (Config.DrawingToolkit, new Area (new Point (0, 0), Width, Height));
+                       }
+               }
+               
+               public void SetCursor (CursorType type) {
+                       GCursorType gtype;
+                       
+                       switch (type) {
+                       case CursorType.Arrow:
+                               gtype = GCursorType.Arrow;
+                               break;
+                       case CursorType.DoubleArrow:
+                               gtype = GCursorType.SbHDoubleArrow;
+                               break;
+                       case CursorType.Selection:
+                               gtype = GCursorType.Fleur;
+                               break;
+                       case CursorType.Cross:
+                               gtype = GCursorType.Cross;
+                               break;
+                       default:
+                               gtype = GCursorType.Arrow;
+                               break;
+                       }
+                       widget.GdkWindow.Cursor = new Cursor (gtype);
+               }
+
+               ButtonType ParseButtonType (uint button) {
+                       ButtonType bt;
+                       
+                       switch (button) {
+                       case 1:
+                               bt = ButtonType.Left;
+                               break;
+                       case 2:
+                               bt = ButtonType.Center;
+                               break;
+                       case 3:
+                               bt = ButtonType.Right;
+                               break;
+                       default:
+                               bt = ButtonType.None;
+                               break;
+                       }
+                       return bt;
+               }
+               
+               ButtonModifier ParseButtonModifier (ModifierType modifier) {
+                       ButtonModifier bm;
+                       
+                       switch (modifier) {
+                       case ModifierType.ControlMask:
+                               bm = ButtonModifier.Control;
+                               break;
+                       case ModifierType.ShiftMask:
+                               bm = ButtonModifier.Shift;
+                               break;
+                       default:
+                               bm = ButtonModifier.None;
+                               break;
+                       }
+                       return bm;
+               }
+
+               void HandleMotionNotifyEvent (object o, MotionNotifyEventArgs args)
+               {
+                       if (MotionEvent != null) {
+                               MotionEvent (new Point (args.Event.X, args.Event.Y));
+                       }
+               }
+
+               void HandleButtonReleaseEvent (object o, ButtonReleaseEventArgs args)
+               {
+                       if (ButtonReleasedEvent != null) {
+                               ButtonType bt;
+                               ButtonModifier bm;
+                               
+                               bt = ParseButtonType (args.Event.Button);
+                               bm = ParseButtonModifier (args.Event.State);
+                               ButtonReleasedEvent (new Point (args.Event.X, args.Event.Y), bt, bm);
+                       }
+               }
+
+               void HandleButtonPressEvent (object o, ButtonPressEventArgs args)
+               {
+                       if (ButtonPressEvent != null) {
+                               ButtonType bt;
+                               ButtonModifier bm;
+                               
+                               bt = ParseButtonType (args.Event.Button);
+                               bm = ParseButtonModifier (args.Event.State);
+                               ButtonPressEvent (new Point (args.Event.X, args.Event.Y),
+                                                 args.Event.Time, bt, bm);
+                       }
+               }
+               
+               void HandleExposeEvent (object o, ExposeEventArgs args)
+               {
+                       Rectangle r;
+                       Area a;
+                       
+                       r = args.Event.Area;
+                       a = new Area (new Point (r.X, r.Y), r.Width, r.Height);
+                       Redraw (a);
+               }
+       }
+}
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]