--- /dev/null
+Win_x86
+
+Debug
+
+/*.sln
+
+/GOLib.suo
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">Linux_x86</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{C2980F9B-4798-4C05-99E2-E174810F7C7B}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>go</RootNamespace>
+ <AssemblyName>Interface</AssemblyName>
+ <FileAlignment>512</FileAlignment>
+ <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
+ <NoStdLib>False</NoStdLib>
+ <TreatWarningsAsErrors>False</TreatWarningsAsErrors>
+ <OutputPath>bin\$(configuration)\$(Platform)</OutputPath>
+ <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
+ <WarningLevel>4</WarningLevel>
+ <NoWin32Manifest>False</NoWin32Manifest>
+ <SignAssembly>false</SignAssembly>
+ <DelaySign>False</DelaySign>
+ <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <Optimize>False</Optimize>
+ <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
+ <BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
+ <DebugType>Full</DebugType>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Platform)' == 'Win_x86' ">
+ <BaseAddress>4194304</BaseAddress>
+ <PlatformTarget>x86</PlatformTarget>
+ <Prefer32Bit>False</Prefer32Bit>
+ <RegisterForComInterop>False</RegisterForComInterop>
+ <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <BaseAddress>4194304</BaseAddress>
+ <RegisterForComInterop>False</RegisterForComInterop>
+ <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Platform)' == 'Linux_x86' ">
+ <PlatformTarget>x86</PlatformTarget>
+ <BaseAddress>4194304</BaseAddress>
+ <RegisterForComInterop>False</RegisterForComInterop>
+ <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+ <Optimize>True</Optimize>
+ <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
+ <BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
+ <DebugType>None</DebugType>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Linux_x86' ">
+ <DefineConstants>TRACE;DEBUG;__linux__</DefineConstants>
+ <OutputPath>..\bin\Debug\Linux_x86</OutputPath>
+ <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win_x86' ">
+ <DefineConstants>TRACE;DEBUG;_WIN32</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Linux_x86' ">
+ <DefineConstants>__linux__</DefineConstants>
+ <OutputPath>..\bin\Release\Linux_x86</OutputPath>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win_x86' ">
+ <DefineConstants>_WIN32</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>none</DebugType>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="src\Button.cs" />
+ <Compile Include="src\Colors.cs" />
+ <Compile Include="src\directories.cs" />
+ <Compile Include="src\enums.cs" />
+ <Compile Include="src\GroupBox.cs" />
+ <Compile Include="src\HorizontalStack.cs" />
+ <Compile Include="src\HorizontalWrappingWidget.cs" />
+ <Compile Include="src\Image.cs" />
+ <Compile Include="src\Label.cs" />
+ <Compile Include="src\Mouse.cs" />
+ <Compile Include="src\Panel.cs" />
+ <Compile Include="src\PanelWithTitle.cs" />
+ <Compile Include="src\Point.cs" />
+ <Compile Include="src\AssemblyInfo.cs" />
+ <Compile Include="src\Rectangle.cs" />
+ <Compile Include="src\Rectangles.cs" />
+ <Compile Include="src\ScrollingWidget.cs" />
+ <Compile Include="src\Size.cs" />
+ <Compile Include="src\Slider.cs" />
+ <Compile Include="src\Spinner.cs" />
+ <Compile Include="src\TextBox.cs" />
+ <Compile Include="src\GenericStack.cs" />
+ <Compile Include="src\VerticalStack.cs" />
+ <Compile Include="src\VerticalWrappingWidget.cs" />
+ <Compile Include="src\GraphicObject.cs" />
+ <Compile Include="src\Group.cs" />
+ <Compile Include="src\Container.cs" />
+ <Compile Include="src\Win32.cs" />
+ <Compile Include="src\WrappedWidgetGroup.cs" />
+ <Compile Include="src\Interface.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="lib\freetype6.dll">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="lib\intl.dll">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="lib\libcairo-2.dll">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="lib\libcairo-gobject-2.dll">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="lib\libcairo-script-interpreter-2.dll">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="lib\libexpat-1.dll">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="lib\libfontconfig-1.dll">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="lib\libpng14-14.dll">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="lib\zlib1.dll">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="Mono.Cairo" />
+ <Reference Condition="'$(Platform)'=='Win_x86'" Include="OpenTK, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>lib\OpenTK.dll</HintPath>
+ </Reference>
+ <Reference Condition="'$(Platform)'=='Win_x86'" Include="OpenTK.Compatibility, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>lib\OpenTK.Compatibility.dll</HintPath>
+ </Reference>
+ <Reference Condition="'$(Platform)'=='Win_x86'" Include="OpenTK.GLControl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>lib\OpenTK.GLControl.dll</HintPath>
+ </Reference>
+ <Reference Condition="'$(Platform)'=='Linux_x86'" Include="OpenTK.Compatibility">
+ <HintPath>..\..\..\OpenTK\1.0\Binaries\OpenTK\Debug\OpenTK.Compatibility.dll</HintPath>
+ </Reference>
+ <Reference Condition="'$(Platform)'=='Linux_x86'" Include="OpenTK">
+ <HintPath>..\..\..\OpenTK\1.0\Binaries\OpenTK\Debug\OpenTK.dll</HintPath>
+ </Reference>
+ <Reference Condition="'$(Platform)'=='Linux_x86'" Include="OpenTK.GLControl">
+ <HintPath>..\..\..\OpenTK\1.0\Binaries\OpenTK\Debug\OpenTK.GLControl.dll</HintPath>
+ </Reference>
+ <Reference Condition="'$(Platform)'=='Linux_x86'" Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
+ <Private>False</Private>
+ <Package>gtk-sharp-2.0</Package>
+ </Reference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <ItemGroup Condition="'$(Platform)'=='Linux_x86'">
+ <None Include="lib\libfb.so">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ <None Include="lib\libgo.so">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ <None Include="Pointeurs\left_ptr.png">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <ItemGroup />
+</Project>
\ No newline at end of file
--- /dev/null
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GOLib")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("GOLib")]
+[assembly: AssemblyCopyright("Copyright © 2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("150376dc-e648-46a2-b692-6429d0a62362")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
--- /dev/null
+using System;
+
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+//using OpenTK.Graphics.OpenGL;
+
+using Cairo;
+
+using winColors = System.Drawing.Color;
+using System.Diagnostics;
+
+namespace go
+{
+ public class Button : Group
+ {
+ public static class Theme
+ {
+ public static Color background = Color.Gray;
+ public static Color borderColor = Color.Black;
+ public static int margin = 1;
+ public static int borderWidth = 1;
+ public static VerticalAlignment verticalAlignment = VerticalAlignment.None;
+ public static HorizontalAlignment horizontalAlignment = HorizontalAlignment.None;
+ public static bool sizeToContent = false;
+ }
+
+ public Button(ButtonWidgetClick _clickEvent, string _text, bool _checkable = false, int width = 0, int height = 0)
+ : base(width, height)
+ {
+ initButtonWidget(_clickEvent, _checkable);
+ label = new Label(_text);
+ sizeToContent = true;
+ label.fontColor = Color.Black;
+ label.fontSize = 14;
+ label.horizontalAlignment = HorizontalAlignment.Stretch;
+ label.verticalAlignment = VerticalAlignment.Stretch;
+ label.textAlignment = Alignment.Center;
+
+ }
+ public Button(System.Drawing.Bitmap iconBitmap, ButtonWidgetClick _clickEvent, bool _checkable, int width, int height)
+ : base(width, height)
+ {
+ icon = new Image(iconBitmap);
+ initButtonWidget(_clickEvent, _checkable);
+ }
+ public Button(string iconFile, ButtonWidgetClick _clickEvent = null, bool _checkable = false, bool _affectMultiSelectState = true)
+ : base()
+ {
+ affectMultiSelectState = _affectMultiSelectState;
+ icon = new Image(iconFile);
+ initButtonWidget(_clickEvent, _checkable);
+ sizeToContent = true;
+ }
+ public Button(string iconFile, ButtonWidgetClick _clickEvent, bool _checkable, int width, int height, bool _affectMultiSelectState = true)
+ : base(width, height)
+ {
+ affectMultiSelectState = _affectMultiSelectState;
+ icon = new Image(iconFile);
+ initButtonWidget(_clickEvent, _checkable);
+ }
+ public Button(string iconFile, string checkedIconFile, ButtonWidgetClick _clickEvent, bool _checkable = false, int width = 30, int height = 30, bool _affectMultiSelectState = true)
+ : base(width, height)
+ {
+ affectMultiSelectState = _affectMultiSelectState;
+ icon = new Image(iconFile);
+ checkedIcon = new Image(checkedIconFile);
+ checkedIcon.isVisible = false;
+
+ initButtonWidget(_clickEvent, _checkable);
+ }
+
+ void initButtonWidget(ButtonWidgetClick _clickEvent = null, bool _checkable = false)
+ {
+ focusable = true;
+ IsCheckable = _checkable;
+ clickEvent = _clickEvent;
+
+ background = Theme.background;
+ borderColor = Theme.borderColor;
+ borderWidth = Theme.borderWidth;
+ margin = Theme.margin;
+ horizontalAlignment = Theme.horizontalAlignment;
+ verticalAlignment = Theme.verticalAlignment;
+ sizeToContent = Theme.sizeToContent;
+ }
+
+ public enum ButtonStates
+ {
+ normal,
+ mouseOver,
+ mouseDown,
+ Disable
+ }
+
+ public static int maxIconSize = 22;
+
+ ButtonStates _CurrentState = ButtonStates.normal;
+ public ButtonStates CurrentState
+ {
+ get { return _CurrentState; }
+ set
+ {
+ if (value == _CurrentState)
+ return;
+ _CurrentState = value;
+ registerForRedraw();
+ //registerForGraphicUpdate();
+ //needGraphicalUpdate = true;
+ }
+ }
+
+ public ButtonWidgetClick clickEvent;
+
+ bool _isChecked = false;
+ public bool IsChecked
+ {
+ get { return _isChecked; }
+ set
+ {
+ if (value == _isChecked)
+ return;
+
+ _isChecked = value;
+
+ if (clickEvent != null)
+ clickEvent(this);
+
+ registerForGraphicUpdate();
+ }
+ }
+
+ public bool IsCheckable = false;
+ public bool affectMultiSelectState = true;
+ public bool border3D = false;
+
+ Image _icon;
+ Image _checkedIcon;
+ Label _label;
+
+ public Image icon
+ {
+ get { return _icon; }
+ set
+ {
+ if (_icon != null)
+ removeChild(_icon);
+
+ if (value == null)
+ _icon = null;
+ else
+ {
+ _icon = addChild(value) as Image;
+ _icon.horizontalAlignment = go.HorizontalAlignment.Stretch;
+ _icon.verticalAlignment = go.VerticalAlignment.Stretch;
+ _icon.background = Color.Transparent;
+ putWidgetOnBottom(_icon);
+ //_icon.borderWidth = 5;
+ }
+ }
+ }
+ public Image checkedIcon
+ {
+ get { return _checkedIcon; }
+ set
+ {
+ if (_checkedIcon != null)
+ removeChild(_checkedIcon);
+
+ if (value == null)
+ _checkedIcon = null;
+ else
+ {
+ _checkedIcon = addChild(value) as Image;
+ _checkedIcon.horizontalAlignment = go.HorizontalAlignment.Stretch;
+ _checkedIcon.verticalAlignment = go.VerticalAlignment.Stretch;
+ _checkedIcon.background = Color.Transparent;
+
+ putWidgetOnBottom(_checkedIcon);
+ }
+ }
+ }
+ public Label label
+ {
+ get { return _label; }
+ set
+ {
+ if (_label != null)
+ removeChild(_label);
+
+ if (value == null)
+ _label = null;
+ else
+ {
+ _label = addChild(value) as Label;
+ _label.horizontalAlignment = go.HorizontalAlignment.Stretch;
+ _label.verticalAlignment = go.VerticalAlignment.Stretch;
+ _label.textAlignment = Alignment.VerticalStretch;
+ putWidgetOnTop(_label);
+ }
+ }
+ }
+
+ public string text
+ {
+ get { return label.text; }
+ set
+ {
+ label = new Label(value);
+ }
+ }
+
+ //public ButtonWidget(string iconFile, int _x, int _y, bool _checkable = false):base()
+ //{
+ // IsCheckable = _checkable;
+ // x = _x;
+ // y = _y;
+
+ // icon = new ImageWidget(iconFile);
+ // icon.Parent = this;
+ //}
+
+
+
+ public override bool ProcessMousePosition(Point mousePos)
+ {
+ if (CurrentState == ButtonStates.Disable)
+ return false;
+
+ bool result = base.ProcessMousePosition(mousePos);
+
+ if (result && CurrentState != ButtonStates.mouseDown)
+ CurrentState = ButtonStates.mouseOver;
+ else
+ CurrentState = ButtonStates.normal;
+
+ return result;
+
+ }
+ public override void ProcessMouseDown(Point mousePos)
+ {
+ //base.ProcessMouseDown(mousePos);
+
+
+ if (CurrentState != Button.ButtonStates.Disable)
+ {
+ Interface.activeWidget = this;
+
+ if (IsCheckable)
+ {
+ if (IsChecked)
+ IsChecked = false;
+ else
+ {
+ Group wg = Parent as Group;
+ if (wg != null)
+ {
+ if (affectMultiSelectState && !multiSelect)
+ {
+ foreach (Button but in wg.Children.OfType<Button>())
+ {
+ if (but.IsCheckable)
+ {
+ if (but.IsChecked && but.affectMultiSelectState)
+ {
+ but.IsChecked = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+ IsChecked = true;
+ }
+ }
+ else if (clickEvent != null)
+ clickEvent(this);
+
+ CurrentState = Button.ButtonStates.mouseDown;
+ }
+
+
+ }
+ public override void ProcessMouseUp(Point mousePos)
+ {
+ if (CurrentState != Button.ButtonStates.Disable)
+ {
+ CurrentState = ButtonStates.normal;
+ ProcessMousePosition(mousePos);
+ }
+
+ //base.ProcessMouseUp(mousePos);
+ }
+
+ internal override void updateGraphic()
+ {
+ if (IsChecked)
+ {
+ if (checkedIcon != null)
+ {
+ icon.isVisible = false;
+ checkedIcon.isVisible = true;
+ }
+ }
+ else
+ {
+ if (checkedIcon != null)
+ {
+ icon.isVisible = true;
+ checkedIcon.isVisible = false;
+ }
+
+ }
+
+ base.updateGraphic();
+ }
+ public override void registerForRedraw()
+ {
+ base.registerForRedraw();
+ }
+ public override void cairoDraw(ref Context ctx, Rectangles clip = null)
+ {
+ base.cairoDraw(ref ctx, clip);
+
+ //int stride = 4 * renderBounds.Width;
+ //int bmpSize = Math.Abs(stride) * renderBounds.Height;
+ //bmp = new byte[bmpSize];
+
+ //using (ImageSurface draw =
+ // new ImageSurface(bmp, Format.Argb32, renderBounds.Width, renderBounds.Height, stride))
+ //{
+
+ Rectangle r = renderBoundsInContextCoordonate.Clone;
+
+ ctx.Save();
+ ctx.ResetClip();
+ ctx.Antialias = Antialias.Subpixel;
+ if (IsCheckable)
+ {
+ if (IsChecked)
+ {
+ if (border3D)
+ Interface.StrokeLoweredRectangle(ctx, r);
+
+ }
+ else
+ {
+ if (checkedIcon == null)
+ {
+ ctx.Color = new Color(0.3, 0.3, 0.3, 0.4);
+ ctx.Rectangle(r);
+ ctx.Fill();
+ }
+ if (border3D)
+ Interface.StrokeRaisedRectangle(ctx, r);
+ }
+ }
+ switch (CurrentState)
+ {
+ case ButtonStates.normal:
+ break;
+ case ButtonStates.mouseOver:
+ ctx.Operator = Operator.Add;
+ ctx.Rectangle(r);
+ ctx.Color = new Color(0.2, 0.2, 0.2, 1.0);
+ ctx.Fill();
+ ctx.Operator = Operator.Over;
+ break;
+ case ButtonStates.mouseDown:
+ //ctx.Scale(0.7, 0.7);
+ ctx.Operator = Operator.Add;
+ ctx.Rectangle(r);
+ ctx.Color = Color.Red1;
+ ctx.Fill();
+ ctx.Operator = Operator.Over;
+ break;
+ case ButtonStates.Disable:
+ ctx.Color = new Color(0.2, 0.2, 0.2, 0.7);
+ ctx.Rectangle(r);
+ ctx.Fill();
+ break;
+
+ }
+ ctx.Restore();
+
+ }
+ //ctx.Target.WriteToPng(directories.rootDir + @"test.png");
+
+ //public override void Render()
+ //{
+ // if (!isVisible)
+ // return;
+
+ // switch (CurrentState)
+ // {
+ // case ButtonStates.normal:
+ // if (IsCheckable)
+ // {
+ // if (IsChecked)
+ // Interface.setTeint(1.0f);
+ // else
+ // Interface.setTeint(0.6f);
+ // }
+ // else
+ // Interface.setTeint(1.0f);
+ // break;
+ // case ButtonStates.mouseOver:
+ // //GL.PixelZoom(1.2f, 1.2f);
+ // Interface.setTeint(1.1f);
+ // GL.Color3(winColors.Red);
+ // break;
+ // case ButtonStates.mouseDown:
+ // GL.PixelZoom(0.9f, 0.9f);
+ // break;
+ // case ButtonStates.Disable:
+ // Interface.setTeint(0.3f);
+ // break;
+ // }
+
+ // ImageWidget img = icon;
+
+ // if (icon != null)
+ // {
+ // if (IsCheckable)
+ // {
+ // if (checkedIcon != null && IsChecked)
+ // {
+ // img = checkedIcon;
+ // }
+ // }
+ // }
+
+ // if (invalidateLayout)
+ // updateLayout();
+
+
+ // if (label != null)
+ // label.Render();
+
+ // if (img != null)
+ // img.Render();
+
+
+ // GL.PixelZoom(1.0f, 1.0f);
+ // Interface.setTeint(1.0f);
+
+ // //if (CurrentState == ButtonStates.mouseOver)
+ // //{
+ // // GL.PixelTransfer(PixelTransferParameter.BlueScale, 5.0f);
+ // // GL.PixelTransfer(PixelTransferParameter.RedScale, 2.5f);
+ // // GL.PixelTransfer(PixelTransferParameter.GreenScale, 2.5f);
+ // //}
+
+ // base.renderBaseWidgetOnly();
+
+ // Interface.setTeint(1.0f);
+ //}
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+
+
+namespace go
+{
+ public struct Color
+ {
+ public double A;
+ public double R;
+ public double G;
+ public double B;
+
+ public Color(double _R, double _G, double _B, double _A)
+ {
+ A = _A;
+ R = _R;
+ G = _G;
+ B = _B;
+ }
+ public static implicit operator System.Drawing.Color(Color c)
+ {
+ return System.Drawing.Color.FromArgb((int)(c.A * 255), (int)(c.R * 255), (int)(c.G * 255), (int)(c.B * 255));
+ }
+ public static implicit operator Cairo.Color(Color c)
+ {
+ return new Cairo.Color(c.R, c.G, c.B, c.A);
+ }
+ public static readonly Color White = new Color(1, 1, 1, 1);
+ public static readonly Color Black = new Color(0, 0, 0, 1);
+ public static readonly Color LightGray = new Color(0.8, 0.8, 0.8, 1);
+ public static readonly Color DarkGray = new Color(0.2, 0.2, 0.2, 1);
+ public static readonly Color Gray = new Color(0.5, 0.5, 0.5, 1);
+ public static readonly Color DimGray = new Color(0.2, 0.2, 0.2, 0.8);
+ public static readonly Color Transparent = new Color(0.0, 0.0, 0.0, 0.0);
+ public static readonly Color Red1 = new Color(0.9, 0.4, 0.4, 0.9);
+ public static readonly Color DimWhite = new Color(0.9, 0.9, 0.9, 0.8);
+ public static readonly Color ElectricBlue = new Color(0.3, 0.3, 0.6, 1);
+ public static readonly Color SkyBlue = new Color(0.7, 0.8, 1, 1);
+ public static readonly Color Lavande = new Color(0.8, 0.8, 1, 1);
+ public static readonly Color YellowGreen = new Color(0.8, 0.8, 0.1, 1);
+ public static readonly Color blue1 = new Color(0.3, 0.3, 0.4, 1);
+ public static readonly Color Green = new Color(0, 1, 0, 1);
+ public static readonly Color Blue = new Color(0, 0, 1, 1);
+ public static readonly Color Red = new Color(1, 0, 0, 1);
+ public static readonly Color LightGoldenrodYellow = new Color(0.5, 0.5, 0, 0.5);
+ public static readonly Color DarkOrange = new Color(1, 0.2, 0, 1);
+ public static readonly Color MediumBlue = new Color(0, 0, 1, 1);
+ public static readonly Color LightBlue = new Color(0.7, 0.7, 1, 1);
+ public static readonly Color Navy = new Color(0, 0, 1, 1);
+ public static readonly Color MediumTurquoise = new Color(0, 0, 1, 1);
+ public static readonly Color Goldenrod = new Color(0, 0, 1, 1);
+ public static readonly Color Yellow = new Color(1, 1, 0, 1);
+ }
+}
--- /dev/null
+using System;
+
+namespace go
+{
+ public class Container : GraphicObject
+ {
+ public Container()
+ : base()
+ {
+ }
+ public Container(Rectangle _bounds)
+ : base(_bounds)
+ {
+ }
+
+ public GraphicObject child;
+ public T setChild<T>(T _child)
+ {
+
+ if (child != null)
+ child.Parent = null;
+
+ child = _child as GraphicObject;
+
+ if (child != null)
+ child.Parent = this;
+
+ return (T)_child;
+ }
+ public override void invalidateLayout()
+ {
+ base.invalidateLayout();
+
+ if (child != null)
+ child.invalidateLayout();
+ }
+ public override bool layoutIsValid
+ {
+ get
+ {
+ if (!isVisible)
+ return true;
+
+ if (!base.layoutIsValid)
+ return false;
+ else if (child != null)
+ if (!child.layoutIsValid)
+ return false;
+
+ return true;
+ }
+ set
+ {
+ base.layoutIsValid = value;
+ }
+ }
+
+ public override void updateLayout()
+ {
+ if (!isVisible)
+ return;
+
+ if (!(sizeIsValid && positionIsValid))
+ base.updateLayout();
+
+ if (child != null)
+ {
+ child.updateLayout();
+ if (sizeToContent && child.sizeIsValid)
+ {
+ renderBounds.Size = child.renderBounds.Size + 2 * margin + 2 * borderWidth;
+ child.renderBounds.TopLeft = clientBounds.TopLeft;
+ sizeIsValid = true;
+ }
+ }
+
+ if (layoutIsValid)
+ registerForRedraw();
+ }
+
+ public override bool ProcessMousePosition(Point mousePos)
+ {
+ if (!isVisible)
+ return false;
+
+ bool result = base.ProcessMousePosition(mousePos);
+
+ //if (this is Panel)
+ // return result;
+ //else
+
+ if (result)
+ if (child != null)
+ child.ProcessMousePosition(mousePos);
+
+ return result;
+ }
+ public override void ProcessMouseWeel(int delta)
+ {
+ if (!isVisible)
+ return;
+
+ if (child != null)
+ child.ProcessMouseWeel(delta);
+ }
+
+ public override void cairoDraw(ref Cairo.Context ctx, Rectangles clip = null)
+ {
+ if (!isVisible)//check if necessary??
+ return;
+
+ ctx.Save();
+
+ ctx.Rectangle(renderBoundsInContextCoordonate);
+ ctx.Clip();
+
+ if (clip != null)
+ clip.clip(ctx);
+
+ base.cairoDraw(ref ctx, clip);
+
+ //clip to client zone
+
+ ctx.Rectangle(ClientBoundsInContextCoordonate);
+ ctx.Clip();
+
+ if (clip != null)
+ clip.Rebase(this);
+
+ if (child != null)
+ child.cairoDraw(ref ctx, clip);
+
+ ctx.Restore();
+ //ctx.Target.WriteToPng(@"/home/jp/test.png");
+
+ }
+ }
+}
+
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace go
+{
+ public class GenericStack : Group
+ {
+ public int widgetSpacing = 5;
+ public Orientation Orientation = Orientation.Horizontal;
+
+ public GenericStack()
+ : base()
+ {
+ borderWidth = 0;
+ sizeToContent = true;
+
+ }
+
+ int currentXForWidget = 0;
+ int currentYForWidget = 0;
+
+ public override void updateLayout()
+ {
+ //if (!(sizeIsValid && positionIsValid))
+ base.updateLayout();
+
+ currentXForWidget = clientBounds.X;
+ currentYForWidget = clientBounds.Y;
+
+
+ Rectangle contentBounds = Rectangle.Zero;
+
+ GraphicObject[] widgets = new GraphicObject[Children.Count];
+ Children.CopyTo(widgets);
+ foreach (GraphicObject w in widgets)
+ {
+ if (!enoughtSpaceForWidget(w))
+ advance(w);
+
+ if (enoughtSpaceForWidget(w))
+ {
+ w.renderBounds.X = currentXForWidget;
+ w.renderBounds.Y = currentYForWidget;
+
+ w.positionIsValid = true;
+
+ contentBounds += w.renderBounds;
+
+ advance(w);
+ }
+ else
+ break;
+ }
+
+ contentBounds.Width += borderWidth + margin;
+ contentBounds.Height += borderWidth + margin;
+
+ if (sizeToContent)
+ renderBounds.Size = contentBounds.Size;
+ else if (VerticalScrolling)
+ renderBounds.Size = new Size(renderBounds.Size.Width, contentBounds.Size.Height);
+ else if (HorizontalScrolling)
+ renderBounds.Size = new Size(contentBounds.Size.Width, renderBounds.Size.Height);
+
+ if (layoutIsValid)
+ registerForRedraw();
+ }
+
+
+ bool enoughtSpaceForWidget(GraphicObject w)
+ {
+ if (!sizeToContent)
+ {
+ int nextXForWidget = 0;
+ int nextYForWidget = 0;
+
+ if (Orientation == Orientation.Horizontal)
+ nextXForWidget = currentXForWidget + w.renderBounds.Width;
+ else
+ nextYForWidget = nextYForWidget + w.renderBounds.Height;
+
+
+ if (nextXForWidget > clientBounds.Right && !HorizontalScrolling)
+ return false;
+ if (currentYForWidget > clientBounds.Bottom && !VerticalScrolling)
+ return false;
+ }
+ return true;
+ }
+ void advance(GraphicObject w)
+ {
+ if (Orientation == Orientation.Horizontal)
+ currentXForWidget = currentXForWidget + widgetSpacing + w.renderBounds.Width;
+ else
+ currentYForWidget = currentYForWidget + widgetSpacing + w.renderBounds.Height;
+
+ }
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+//using OpenTK.Graphics.OpenGL;
+using System.Drawing.Imaging;
+using System.Diagnostics;
+using OpenTK.Input;
+
+using Cairo;
+
+
+namespace go
+{
+ public class GraphicObject
+ {
+ public GraphicObject()
+ {
+ init();
+ registerForGraphicUpdate();
+ }
+ public GraphicObject(Rectangle _bounds)
+ {
+ bounds = _bounds;
+ init();
+ registerForGraphicUpdate();
+ }
+
+ void init()
+ {
+ background = Theme.background;
+ foreground = Theme.foreground;
+ borderColor = Theme.borderColor;
+ borderWidth = Theme.borderWidth;
+ margin = Theme.margin;
+ horizontalAlignment = Theme.horizontalAlignment;
+ verticalAlignment = Theme.verticalAlignment;
+ sizeToContent = Theme.sizeToContent;
+ }
+
+ public virtual int x
+ {
+ get { return bounds.X; }
+ set
+ {
+ if (bounds.X == value)
+ return;
+
+ bounds.X = value;
+
+ layoutIsValid = false;
+ registerForGraphicUpdate();
+ }
+ }
+ public virtual int y
+ {
+ get { return bounds.Y; }
+ set
+ {
+ if (bounds.Y == value)
+ return;
+
+ bounds.Y = value;
+
+ layoutIsValid = false;
+ registerForGraphicUpdate();
+ }
+ }
+ public int width
+ {
+ get { return bounds.Width; }
+ set
+ {
+ if (bounds.Width == value)
+ return;
+
+ bounds.Width = value;
+
+ invalidateLayout();
+ }
+ }
+ public int height
+ {
+ get { return bounds.Height; }
+ set
+ {
+ if (bounds.Height == value)
+ return;
+
+ bounds.Height = value;
+
+ invalidateLayout();
+ }
+ }
+
+ public virtual Rectangle renderBoundsInContextCoordonate
+ {
+ get
+ {
+ if (Parent == null)
+ return renderBounds.Clone;
+ //if (Parent.isCached)
+ // return renderBounds.Clone;
+
+ Rectangle tmp = Parent.renderBoundsInContextCoordonate;
+
+ return new Rectangle(
+ tmp.X + renderBounds.X,
+ tmp.Y + renderBounds.Y,
+ renderBounds.Width,
+ renderBounds.Height);
+ }
+ }
+ public virtual Rectangle ClientBoundsInContextCoordonate
+ {
+ get
+ {
+ if (Parent == null)
+ return new Rectangle(
+ renderBounds.X + clientBounds.X,
+ renderBounds.Y + clientBounds.Y,
+ clientBounds.Width,
+ clientBounds.Height);
+
+ //if (Parent is Panel && !(this is ScrollingWidget))
+ // return Parent.clientBounds;
+
+ Rectangle tmp = Parent.renderBoundsInContextCoordonate;
+
+ return new Rectangle(
+ tmp.X + renderBounds.X + clientBounds.X,
+ tmp.Y + renderBounds.Y + clientBounds.Y,
+ clientBounds.Width,
+ clientBounds.Height);
+ }
+
+ }
+
+ //public virtual Rectangle rectangleInContextCoordonate(Rectangle r)
+ //{
+ // if (Parent == null)
+ // return r;
+
+ // Rectangle tmp = Parent.rectangleInContextCoordonate(r);
+
+ // return new Rectangle(
+ // tmp.X + r.X,
+ // tmp.Y + r.Y,
+ // r.Width,
+ // r.Height);
+ //}
+ public virtual Rectangle renderBoundsInBackendSurfaceCoordonate
+ {
+ get
+ {
+ Rectangle tmp = Parent.renderBoundsInBackendSurfaceCoordonate;
+
+ return new Rectangle(
+ tmp.X + renderBounds.X,
+ tmp.Y + renderBounds.Y,
+ renderBounds.Width,
+ renderBounds.Height);
+ }
+ }
+ public virtual Rectangle ClientBoundsInBackendSurfaceCoordonate
+ {
+ get
+ {
+ if (Parent == null)
+ return new Rectangle(
+ renderBounds.X + clientBounds.X,
+ renderBounds.Y + clientBounds.Y,
+ clientBounds.Width,
+ clientBounds.Height); ;
+
+ //if (Parent is Panel && !(this is ScrollingWidget))
+ // return Parent.clientBounds;
+
+ Rectangle tmp = Parent.ClientBoundsInBackendSurfaceCoordonate;
+
+ return new Rectangle(
+ tmp.X + renderBounds.X + clientBounds.X,
+ tmp.Y + renderBounds.Y + clientBounds.Y,
+ clientBounds.Width,
+ clientBounds.Height);
+ }
+
+ }
+ public virtual Rectangle rectInScreenCoord(Rectangle r)
+ {
+ return
+ new Rectangle(
+ ScreenCoordBounds.X + r.X,
+ ScreenCoordBounds.Y + r.Y,
+ r.Width,
+ r.Height);
+ }
+ public virtual Rectangle ScreenCoordBounds
+ {
+ get
+ {
+ return Parent == null ? bounds :
+ new Rectangle(
+ Parent.ScreenCoordBounds.X + renderBounds.X,
+ Parent.ScreenCoordBounds.Y + renderBounds.Y,
+ renderBounds.Width,
+ renderBounds.Height);
+ }
+ }
+ public virtual Rectangle ScreenCoordClientBounds
+ {
+ get
+ {
+ return Parent == null ?
+ new Rectangle(
+ renderBounds.X + clientBounds.X,
+ renderBounds.Y + clientBounds.Y,
+ clientBounds.Width,
+ clientBounds.Height) :
+ new Rectangle(
+ Parent.ScreenCoordClientBounds.X + clientBounds.X,
+ Parent.ScreenCoordClientBounds.Y + clientBounds.Y,
+ clientBounds.Width,
+ clientBounds.Height);
+ }
+ }
+
+ public Rectangle bounds = new Rectangle();
+ public Rectangle renderBounds = new Rectangle();
+
+ public virtual Rectangle clientBounds
+ {
+ get
+ {
+ //if (renderBounds == Rectangle.Empty)
+ // Debugger.Break();
+ Rectangle cb = renderBounds.Clone;
+ cb.X = 0;
+ cb.Y = 0;
+ cb.Inflate(-(borderWidth + margin), -(borderWidth + margin));
+ return cb;
+ }
+ }
+
+ //static copy of themable proporties,
+ //set default value for all newly created item
+ public static class Theme
+ {
+ public static Color background = Color.DimGray;
+ public static Color foreground = Color.White;
+ public static Color borderColor = Color.Gray;
+ public static int margin = 0;
+ public static int borderWidth = 0;
+ public static VerticalAlignment verticalAlignment = VerticalAlignment.Stretch;
+ public static HorizontalAlignment horizontalAlignment = HorizontalAlignment.Stretch;
+ public static bool sizeToContent = false;
+ }
+
+ Color _background;
+ Color _foreground;
+ Color _borderColor;
+ int _borderWidth;
+ int _margin;
+
+ public VerticalAlignment verticalAlignment;
+ public HorizontalAlignment horizontalAlignment;
+ public bool sizeToContent;
+
+ public Color background
+ {
+ get { return _background; }
+ set
+ {
+ _background = value;
+ registerForGraphicUpdate();
+ }
+ }
+ public Color foreground
+ {
+ get { return _foreground; }
+ set
+ {
+ _foreground = value;
+ registerForGraphicUpdate();
+ }
+ }
+ public Color borderColor
+ {
+ get { return _borderColor; }
+ set
+ {
+ _borderColor = value;
+ registerForGraphicUpdate();
+ }
+ }
+ public int borderWidth
+ {
+ get { return _borderWidth; }
+ set
+ {
+ _borderWidth = value;
+ registerForGraphicUpdate();
+ }
+ }
+ public int margin
+ {
+ get { return _margin; }
+ set
+ {
+ _margin = value;
+ registerForGraphicUpdate();
+ }
+ }
+
+ public object Tag;
+
+ public GraphicObject Parent;
+
+ public bool focusable = false;
+
+ private bool _hasFocus = false;
+ protected bool _isVisible = true;
+
+ public virtual bool hasFocus
+ {
+ get { return _hasFocus; }
+ set
+ {
+ _hasFocus = value;
+ }
+ }
+ public virtual bool isVisible
+ {
+ get { return _isVisible; }
+ set
+ {
+ if (value == _isVisible)
+ return;
+
+ _isVisible = value;
+ if (Parent != null)
+ Parent.invalidateLayout();
+ //else
+ // registerForRedraw();
+ }
+ }
+
+
+ internal bool sizeIsValid = false;
+ internal bool positionIsValid = false;
+
+ public virtual void invalidateLayout()
+ {
+ bmp = null;
+ layoutIsValid = false;
+ }
+ public virtual bool layoutIsValid
+ {
+ get { return sizeIsValid & positionIsValid; }
+ set
+ {
+ if (value == sizeIsValid && value == positionIsValid)
+ return;
+
+ //_layoutIsValid = value;
+
+ sizeIsValid = value;
+ positionIsValid = value;
+
+ //if (!layoutIsValid && Parent != null)
+ // Parent.layoutIsValid = false;
+ }
+ }
+
+ public virtual bool isCached
+ {
+ get { return false; }
+ }
+ public virtual bool cachingInProgress
+ {
+ get { return false; }
+ set { return; }
+ }
+
+
+ public byte[] bmp;
+
+
+
+ Panel _panel;
+ public Panel panel
+ {
+ get
+ {
+ if (_panel == null)
+ {
+ GraphicObject w = Parent;
+
+ while (w != null)
+ {
+ Panel p = w as Panel;
+ if (p != null)
+ {
+ _panel = p;
+ break;
+ }
+ w = w.Parent;
+ }
+ }
+
+ return _panel;
+ }
+ }
+
+ public virtual void registerForGraphicUpdate()
+ {
+ bmp = null;
+ registerForRedraw();
+ //Interface.registerForGraphicUpdate(this);
+ }
+ public virtual void registerForRedraw()
+ {
+ if (layoutIsValid && isVisible)
+ Interface.redrawClip.AddRectangle(this.renderBoundsInBackendSurfaceCoordonate);
+ }
+ public virtual void updatePosition()
+ {
+ renderBounds.X = bounds.X;
+ renderBounds.Y = bounds.Y;
+ }
+ public virtual Size measureRawSize()
+ {
+ return bounds.Size;
+ }
+
+ public virtual void computeSize()
+ {
+ Size rawSize = measureRawSize();
+
+ float vRatio = 1f;
+ float hRatio = 1f;
+
+ sizeIsValid = true;
+
+ if (bounds.Width == 0)
+ if (rawSize.Width == 0)
+ {
+ if (horizontalAlignment != go.HorizontalAlignment.Stretch)
+ {
+ Debug.WriteLine("Not able to find width for item");
+ sizeIsValid = false;
+ }
+ }
+ else
+ renderBounds.Width = rawSize.Width;
+ else
+ renderBounds.Width = bounds.Width;
+
+ if (bounds.Height == 0)
+ if (rawSize.Height == 0)
+ {
+ if (verticalAlignment != go.VerticalAlignment.Stretch)
+ {
+ Debug.WriteLine("Not able to find height for item");
+ sizeIsValid = false;
+ }
+ }
+ else
+ renderBounds.Height = (int)rawSize.Height;
+ else
+ renderBounds.Height = bounds.Height;
+
+ if (verticalAlignment == VerticalAlignment.Stretch)
+ {
+ if (Parent != null)
+ {
+ if (Parent.sizeIsValid)
+ {
+ Rectangle pcb = Parent.clientBounds;
+ //vRatio = (float)pcb.Height / renderBounds.Height;
+ renderBounds.Height = pcb.Height;
+ //renderBounds.Width = (int)(vRatio * renderBounds.Width);
+ }
+ }
+ else
+ {
+ Debug.WriteLine("parent can't be null for streched item");
+ sizeIsValid = false;
+ }
+ }
+
+ if (horizontalAlignment == HorizontalAlignment.Stretch)
+ {
+ if (Parent != null)
+ {
+ if (Parent.sizeIsValid)
+ {
+ Rectangle pcb = Parent.clientBounds;
+ //hRatio = (float)pcb.Width / renderBounds.Width;
+ renderBounds.Width = pcb.Width;
+ //renderBounds.Height = (int)(hRatio * renderBounds.Height);
+ }
+ }
+ else
+ {
+ Debug.WriteLine("parent can't be null for streched item");
+ sizeIsValid = false;
+ }
+ }
+
+ }
+ public virtual void updateLayout()
+ {
+ if (layoutIsValid)
+ return;
+
+ Rectangle oldRenderBounds = renderBounds.Clone;
+
+
+
+ if (!sizeIsValid)
+ computeSize();
+
+ if (!positionIsValid)
+ {
+ //on aligne par rapport aux parent que si le parent contient une taille
+ if (Parent != null)
+ {
+ //if (Parent is WrappedWidgetGroup)
+ // positionIsValid = false;
+ //else
+ {
+ if (Parent.sizeIsValid)
+ {
+ positionIsValid = true;
+
+ Rectangle pcb = Parent.clientBounds;
+
+ switch (horizontalAlignment)
+ {
+ case HorizontalAlignment.Stretch:
+ case HorizontalAlignment.Left:
+ renderBounds.X = pcb.Left;
+ break;
+ case HorizontalAlignment.Right:
+ if (sizeIsValid)
+ renderBounds.X = pcb.Right - renderBounds.Width;
+ else
+ positionIsValid = false;
+ break;
+ case HorizontalAlignment.Center:
+ if (sizeIsValid)
+ renderBounds.X = pcb.X + pcb.Width / 2 - renderBounds.Width / 2;
+ else
+ positionIsValid = false;
+ break;
+ case HorizontalAlignment.None:
+ //if (bounds.X == 0)
+ //{
+ // Debug.WriteLine("Not able to set X position for item");
+ // positionIsValid = false;
+ //}
+ //else
+ renderBounds.X = bounds.X;
+ break;
+ }
+
+ switch (verticalAlignment)
+ {
+ case VerticalAlignment.Stretch:
+ case VerticalAlignment.Top:
+ renderBounds.Y = pcb.Top;
+ break;
+ case VerticalAlignment.Bottom:
+ if (sizeIsValid)
+ renderBounds.Y = pcb.Bottom - renderBounds.Height;
+ else
+ positionIsValid = false;
+ break;
+ case VerticalAlignment.Center:
+ if (sizeIsValid)
+ renderBounds.Y = pcb.Y + pcb.Height / 2 - renderBounds.Height / 2;
+ else
+ positionIsValid = false;
+ break;
+ case VerticalAlignment.None:
+ //if (bounds.Y == 0)
+ //{
+ // Debug.WriteLine("Not able to set Y position for item");
+ // positionIsValid = false;
+ //}
+ //else
+ renderBounds.Y = bounds.Y;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ positionIsValid = true;
+ renderBounds.TopLeft = bounds.TopLeft;
+ }
+ }
+
+ if (layoutIsValid)
+ registerForRedraw();
+ }
+ internal virtual void updateGraphic()
+ {
+ int stride = 4 * renderBounds.Width;
+
+ int bmpSize = Math.Abs(stride) * renderBounds.Height;
+ bmp = new byte[bmpSize];
+
+ using (ImageSurface draw =
+ new ImageSurface(bmp, Format.Argb32, renderBounds.Width, renderBounds.Height, stride))
+ {
+ using (Context gr = new Context(draw))
+ {
+ gr.Antialias = Antialias.Subpixel;
+ Rectangle rBack = new Rectangle(renderBounds.Size);// renderBoundsInContextCoordonate.Clone;
+ gr.Color = background;
+ gr.Rectangle(rBack);
+ gr.Fill();
+
+ if (borderWidth > 0)
+ {
+ rBack.Inflate(-borderWidth / 2, -borderWidth / 2);
+ gr.LineWidth = borderWidth;
+ gr.Color = borderColor;
+ gr.Rectangle(rBack);
+ gr.Stroke();
+ }
+ }
+ draw.Flush();
+ //draw.WriteToPng(directories.rootDir + @"test.png");
+ }
+
+ //if (layoutIsValid)
+ // registerForRedraw();
+ }
+ public virtual void cairoDraw(ref Context ctx, Rectangles clip = null)
+ {
+ if (!isVisible)
+ return;
+
+ if (bmp == null)
+ updateGraphic();
+
+ Rectangle tmp;
+
+ tmp = renderBoundsInContextCoordonate;//.Clone;
+
+ int stride = 4 * renderBounds.Width;
+ using (ImageSurface source = new ImageSurface(bmp, Format.Argb32, tmp.Width, tmp.Height, stride))
+ {
+
+ //ctx.Save();
+ //if (Parent != null)
+ //{
+ //ctx.ResetClip();
+ // //ctx.Rectangle(Parent.clientBounds);
+ // ctx.Rectangle(tmp);
+ // ctx.Clip();
+ //}
+ ctx.SetSourceSurface(source, tmp.X, tmp.Y);
+ ctx.Paint();
+ //ctx.Restore();
+ //source.WriteToPng(directories.rootDir + @"test.png");
+ }
+ //ctx.Target.WriteToPng(directories.rootDir + @"test.png");
+
+ }
+
+ #region Keyboard handling
+ public virtual void ProcessKeyboard(Key key)
+ { }
+ #endregion
+
+ #region Mouse handling
+ public virtual bool ProcessMousePosition(Point mousePos)
+ {
+ if (!isVisible)
+ return false;
+
+ if (ScreenCoordBounds.Contains(mousePos))
+ {
+ if (focusable)
+ Interface.hoverWidget = this;
+ return true;
+ }
+ else
+ {
+ //if (focusable)
+ // Interface.hoverWidget = null;
+ return false;
+ }
+ }
+ public virtual void ProcessMouseDown(Point mousePos)
+ {
+ if (!isVisible)
+ return;
+ Panel.activeWidget = this;
+ }
+ public virtual void ProcessMouseUp(Point mousePos)
+ {
+ //Interface.activeWidget = null;
+
+ if (!isVisible)
+ return;
+ }
+
+ public virtual void ProcessMouseWeel(int delta)
+ {
+ if (!isVisible)
+ return;
+ }
+ #endregion
+
+ public override string ToString()
+ {
+ string tmp = this.GetType().ToString().Split(new char[] { '.' }).Last() + ":-";
+ if (!layoutIsValid)
+ tmp += "L-";
+ //if (Interface.graphicUpdateList.Contains(this))
+ // tmp += "GU-";
+ if (Interface.redrawClip.intersect(this.renderBoundsInBackendSurfaceCoordonate))
+ tmp += "D-";
+ return tmp + string.Format("rb:{0}", renderBounds);
+ }
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Drawing;
+using System.Diagnostics;
+using Cairo;
+
+namespace go
+{
+ public class Group : ScrollingWidget
+ {
+ public List<GraphicObject> Children = new List<GraphicObject>();
+
+ public ImageSurface cairoCache;
+
+ bool _cachingInProgress = false;
+ public override bool cachingInProgress
+ {
+ get { return _cachingInProgress; }
+ set { _cachingInProgress = value; }
+ }
+
+ public Group(int _width = 30, int _height = 30)
+ : base(_width, _height)
+ {
+ init();
+ }
+
+ public Group()
+ : base()
+ {
+ init();
+ }
+ void init()
+ {
+ focusable = true;
+ borderWidth = 0;
+ background = Color.Transparent;
+ }
+
+ //public Widget addChild(Widget child)
+ //{
+ // Children.Add(child);
+ // child.Parent = this;
+ // layoutIsValid = false;
+ // return child;
+ //}
+ public T addChild<T>(T child)
+ {
+ Children.Add(child as GraphicObject);
+ (child as GraphicObject).Parent = this as GraphicObject;
+ layoutIsValid = false;
+ return (T)child;
+ }
+ public void removeChild(GraphicObject child)
+ {
+ Children.Remove(child);
+ child.Parent = null;
+ layoutIsValid = false;
+ }
+
+ public GraphicObject activeWidget;
+ public bool multiSelect = false;
+ public override void invalidateLayout()
+ {
+ base.invalidateLayout();
+ foreach (GraphicObject w in Children)
+ w.invalidateLayout();
+ }
+ public override bool layoutIsValid
+ {
+ get
+ {
+ if (!isVisible)
+ return true;
+
+ if (!base.layoutIsValid)
+ return false;
+ else//le layout n'est valide que si tous les enfents sont validés aussi
+ {
+
+ foreach (GraphicObject w in Children)
+ if (!w.layoutIsValid)
+ return false;
+
+ }
+
+ return true;
+ }
+ set
+ {
+ base.layoutIsValid = value;
+ }
+ }
+
+ ////limit to clientbounds of wg for drawing on cached imagesurface
+ ////if called by wg itself, call base.BoundsInPanelCoordonate
+ //public override Rectangle renderBoundsInContextCoordonate
+ //{
+ // get
+ // {
+ // if (Parent == null)
+ // return new Rectangle(renderBounds.Size);
+
+ // //if (Parent is Panel && !(this is ScrollingWidget))
+ // // return Parent.clientBounds;
+
+ // Rectangle tmp = Parent.renderBoundsInContextCoordonate;
+
+ // return new Rectangle(
+ // tmp.X + renderBounds.X,
+ // tmp.Y + renderBounds.Y,
+ // renderBounds.Width,
+ // renderBounds.Height);
+
+ // return cachingInProgress ? new Rectangle(
+ // clientBounds.X + scrollX,
+ // clientBounds.Y + scrollY,
+ // clientBounds.Width,
+ // clientBounds.Height)
+ // : base.renderBoundsInContextCoordonate;
+ // }
+ //}
+ //public override bool needGraphicalUpdate
+ //{
+ // get { return _needGraphicalUpdate; }
+ // set
+ // {
+ // if (value == _needGraphicalUpdate)
+ // return;
+
+ // base.needGraphicalUpdate = value;
+
+ // if (_needGraphicalUpdate)
+ // {
+
+ // Widget[] widgets = new Widget[Children.Count];
+ // Children.CopyTo(widgets);
+ // foreach (Widget w in widgets)
+ // {
+ // //if (w.isCached)
+ // // w.needGraphicalUpdate = true;
+ // //else
+ // w.needRedraw = true;
+ // }
+ // }
+ // }
+ //}
+ //nécessaire becose no cached of widgetgroup...TODO
+ //public override bool needRedraw
+ //{
+ // get
+ // {
+ // return base.needRedraw;
+ // }
+ // set
+ // {
+ // if (value == _needRedraw)
+ // return;
+
+ // base.needRedraw = value;
+ // if (_needRedraw && !isCached)
+ // {
+ // Widget[] widgets = new Widget[Children.Count];
+ // Children.CopyTo(widgets);
+ // foreach (Widget w in widgets)
+ // w.needRedraw = true;
+ // }
+ // }
+ //}
+
+ public override void ProcessMouseDown(Point mousePos)
+ {
+ if (!isVisible)
+ return;
+
+ if (activeWidget == null)
+ return;
+
+ //if (activeWidget.ScreenCoordBounds.Contains(mousePos))
+ //{
+ // activeWidget.ProcessMouseDown(mousePos);
+
+ // //WrappedWidgetGroup wg = activeWidget as WrappedWidgetGroup;
+ // //if (wg != null)
+ // //{
+ // // wg.ProcessMouseDown(mousePos);
+ // //}
+ //}
+ }
+ public override bool ProcessMousePosition(Point mousePos)
+ {
+ if (!isVisible)
+ return false;
+
+ bool baseResult = base.ProcessMousePosition(mousePos);
+
+ if (activeWidget != null)
+ {
+ if (activeWidget.ProcessMousePosition(mousePos))
+ return true;
+ else
+ activeWidget = null;
+ }
+
+ foreach (GraphicObject w in Children)
+ {
+ if (w.isVisible)
+ {
+ if (w.ProcessMousePosition(mousePos))
+ {
+ activeWidget = w;
+ return true;
+ }
+ }
+ }
+
+ activeWidget = null;
+ return baseResult;
+ }
+ public override bool isCached
+ {
+ get
+ {
+ return cairoCache == null ? false : true;
+ }
+ }
+ public void putWidgetOnTop(GraphicObject w)
+ {
+ if (Children.Contains(w))
+ {
+ Children.Remove(w);
+ Children.Add(w);
+ }
+ }
+ public void putWidgetOnBottom(GraphicObject w)
+ {
+ if (Children.Contains(w))
+ {
+ Children.Remove(w);
+ Children.Insert(0, w);
+ }
+ }
+
+ #region widget overrides
+ public override void updateLayout()
+ {
+ //while (!layoutIsValid)
+ //{
+ //le layout ne se fait à la base que si _LayoutIsValid = false
+ if (!(sizeIsValid && positionIsValid))
+ base.updateLayout();
+
+ Rectangle contentBounds = Rectangle.Zero;
+
+ GraphicObject[] widgets = new GraphicObject[Children.Count];
+ Children.CopyTo(widgets);
+ foreach (GraphicObject w in widgets)
+ {
+ if (!w.layoutIsValid)
+ w.updateLayout();
+
+ contentBounds = contentBounds + w.renderBounds;
+ }
+
+ contentBounds.Width += borderWidth + margin;
+ contentBounds.Height += borderWidth + margin;
+
+ if (sizeToContent || VerticalScrolling || HorizontalScrolling)
+ {
+ sizeIsValid = true;
+
+ foreach (GraphicObject w in widgets)
+ {
+ if (!w.sizeIsValid && w.isVisible)
+ {
+ sizeIsValid = false;
+ break;
+ }
+ }
+
+ // contentBounds.Width += borderWidth + margin;
+ //contentBounds.Height += borderWidth + margin;
+ if (sizeIsValid)
+ {
+ if (sizeToContent)
+ renderBounds.Size = contentBounds.Size;
+ else if (VerticalScrolling)
+ renderBounds.Size = new Size(renderBounds.Size.Width, contentBounds.Size.Height);
+ else if (HorizontalScrolling)
+ renderBounds.Size = new Size(contentBounds.Size.Width, renderBounds.Size.Height);
+ }
+ }
+ //if (sizeToContent)
+ // renderBounds.Size = contentBounds.Size;
+ //else if (VerticalScrolling)
+ // renderBounds.Size = new Size(renderBounds.Size.Width, contentBounds.Size.Height);
+ //else if (HorizontalScrolling)
+ // renderBounds.Size = new Size(contentBounds.Size.Width, renderBounds.Size.Height);
+
+ //}
+ if (layoutIsValid)
+ registerForRedraw();
+ }
+ internal override void updateGraphic()
+ {
+ if (cairoCache != null)
+ cairoCache.Dispose();
+
+ cairoCache = null;
+
+ base.updateGraphic();
+ }
+ public override void cairoDraw(ref Context ctx, Rectangles clip = null)
+ {
+ if (!isVisible)//check if necessary??
+ return;
+
+ if (bmp == null) //update graphic before caching because UG reset cache
+ updateGraphic();
+
+ Rectangle rBoundsInContext = null;
+ Rectangles containedRects = null;
+ Rectangles smallerContainedRect = null;
+
+ //if (isCached)
+ // rBoundsInContext = new Rectangle(rBoundsInContext.Size);
+
+ bool rectsInBounds = false;
+ bool rebuildCache = false;
+
+ if (cairoCache == null)
+ {
+ cairoCache =
+ new ImageSurface(Format.Argb32, renderBounds.Width, renderBounds.Height);
+
+ rebuildCache = true;
+ }
+
+ cachingInProgress = true;
+
+ if (clip != null)
+ {
+ clip.Rebase(this);
+
+
+ if (!rebuildCache)
+ {
+ rBoundsInContext = this.renderBoundsInContextCoordonate;
+
+ containedRects = clip.containedRects(rBoundsInContext);
+ smallerContainedRect = containedRects.SmallerRects(rBoundsInContext);
+
+ if (smallerContainedRect.count > 0)
+ rectsInBounds = true;
+ }
+ }
+
+ if (rectsInBounds || rebuildCache)
+ {
+ Context gr = new Context(cairoCache);
+
+ if (rectsInBounds)
+ smallerContainedRect.clearAndClip(gr);
+
+ //gr.Target.WriteToPng(directories.rootDir + @"test.png");
+
+ base.cairoDraw(ref gr);
+
+ //gr.Target.WriteToPng(directories.rootDir + @"test.png");
+
+ GraphicObject[] widgets = new GraphicObject[Children.Count];
+ Children.CopyTo(widgets);
+ foreach (GraphicObject w in widgets)
+ {
+ if (rebuildCache)
+ w.cairoDraw(ref gr);
+ else
+ {
+ Rectangle r = w.renderBoundsInContextCoordonate;
+ Rectangles clipRects = smallerContainedRect.intersectingRects(r);
+ //gr.Rectangle(r);
+ //gr.LineWidth = 1;
+ //gr.Color = new Cairo.Color(1, 0, 1, 1);
+ //gr.Stroke();
+
+ if (clipRects.count > 0)
+ w.cairoDraw(ref gr, clipRects);
+ //gr.Target.WriteToPng(directories.rootDir + @"test.png");
+ }
+ }
+
+ cairoCache.Flush();
+
+ //cairoCache.WriteToPng(directories.rootDir + @"test.png");
+ }
+
+ cachingInProgress = false;
+
+ //draw cache
+ //Rectangle rCBPC = Parent.ClientBoundsInPanelCoordonate;
+ //cachingInProgress change context coordonate system
+ rBoundsInContext = this.renderBoundsInContextCoordonate;
+ //ctx.ResetClip();
+ ctx.SetSourceSurface(cairoCache, rBoundsInContext.X, rBoundsInContext.Y);
+ //ctx.Rectangle(r);
+ ctx.Paint();
+
+ //ctx.ResetClip();
+ //ctx.Rectangle(rBoundsInContext);
+ //ctx.Color = Color.Red;
+ //ctx.Fill();
+ //ctx.Target.WriteToPng(directories.rootDir + @"test.png");
+
+ }
+ #endregion
+
+ public override string ToString()
+ {
+ string tmp = base.ToString();
+ foreach (GraphicObject w in Children)
+ {
+ tmp += "\n" + w.ToString();
+ }
+ return tmp;
+ }
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Cairo;
+
+namespace go
+{
+ public class GroupBox : Container
+ {
+ public GroupBox(Rectangle _bounds, string _title = "GroupBox")
+ : base(_bounds)
+ {
+ title = _title;
+ init();
+ }
+ public GroupBox(string _title = "GroupBox")
+ : base()
+ {
+ title = _title;
+ sizeToContent = true;
+ init();
+ }
+ void init()
+ {
+ horizontalAlignment = go.HorizontalAlignment.None;
+ verticalAlignment = go.VerticalAlignment.None;
+ borderColor = Color.White;
+ borderWidth = 1;
+ margin = 5;
+ }
+ string _title;
+ public string title
+ {
+ get { return _title; }
+ set
+ {
+ _title = value;
+ registerForGraphicUpdate();
+ }
+ }
+
+ int _fontSize = 10;
+ public int fontSize
+ {
+ get { return _fontSize; }
+ set
+ {
+ _fontSize = value;
+ registerForGraphicUpdate();
+ }
+ }
+ public override Rectangle ClientBoundsInContextCoordonate
+ {
+ get
+ {
+ return base.ClientBoundsInContextCoordonate;
+ }
+ }
+ public override Rectangle clientBounds
+ {
+ get
+ {
+ Size ts = titleSize();
+
+ Rectangle cb = renderBounds.Clone;
+ cb.X = 0;
+ cb.Y = ts.Height;
+ cb.Height -= ts.Height;
+ cb.Inflate(-borderWidth - margin, -borderWidth - margin);
+
+ return cb;
+ }
+ }
+ public Size titleSize()
+ {
+#if _WIN32 || _WIN64
+ byte[] txt = System.Text.UTF8Encoding.UTF8.GetBytes(_title);
+#endif
+
+ Size s;
+
+ using (Context gr = new Context(new ImageSurface(Format.Argb32, 1, 1)))
+ {
+ gr.SetFontSize(fontSize);
+ TextExtents te;
+#if _WIN32 || _WIN64
+ te = gr.TextExtents(txt);
+#elif __linux__
+ te = gr.TextExtents(title);
+#endif
+ FontExtents fe = gr.FontExtents;
+ s = new Size((int)Math.Ceiling(te.XAdvance), (int)Math.Ceiling(fe.Height));
+ }
+ return s;// +borderWidth;
+ }
+
+ public override void updateLayout()
+ {
+ if (!layoutIsValid)
+ {
+ base.updateLayout();
+
+ if (layoutIsValid)
+ renderBounds.Height += titleSize().Height;//??????????
+ }
+ }
+ internal override void updateGraphic()
+ {
+ int stride = 4 * renderBounds.Width;
+
+ int bmpSize = Math.Abs(stride) * renderBounds.Height;
+ bmp = new byte[bmpSize];
+
+ byte[] txt = System.Text.UTF8Encoding.UTF8.GetBytes(title);// utf = new System.Text.Decoder();
+
+ using (ImageSurface draw = new ImageSurface(bmp, Format.Argb32, renderBounds.Width, renderBounds.Height, stride))
+ {
+ using (Context gr = new Context(draw))
+ {
+
+
+ Rectangle r = new Rectangle(renderBounds.Size);
+ //gr.Rotate(Math.PI);
+ gr.SetFontSize(fontSize);
+ FontExtents fe = gr.FontExtents;
+ TextExtents te = gr.TextExtents(title);
+ // double a = Math.PI;
+ //gr.Transform(new c.Matrix(Math.Cos(a),-Math.Sin(a),Math.Sin(a),Math.Cos(a),renderBounds.Width,renderBounds.Height));
+ gr.Antialias = Antialias.Subpixel;
+ gr.LineWidth = borderWidth;
+ gr.Color = background;
+ //gr.MoveTo(renderBounds.X+1,renderBounds.Y+1);
+
+
+ gr.Rectangle(r);
+ gr.Fill();
+
+ Rectangle rTitle = r.Clone;
+
+ int th = (int)Math.Ceiling(fe.Height / 2);
+ r.Y += th;
+ r.Height -= th;
+
+ const int titleGap = 5;
+
+ if (borderWidth > 0)
+ {
+ gr.Color = borderColor;
+ gr.LineWidth = borderWidth;
+
+ r.Inflate(-borderWidth / 2, -borderWidth / 2);
+
+
+ rTitle.X = r.X + titleGap;
+ rTitle.Width = (int)Math.Ceiling(te.XAdvance) + 2 * titleGap;
+ rTitle.Height = (int)Math.Ceiling(fe.Height);
+ gr.Save();
+ gr.FillRule = FillRule.EvenOdd;
+ gr.Rectangle(new Rectangle(renderBounds.Size));
+ gr.Rectangle(rTitle);
+ gr.Clip();
+
+
+ gr.Rectangle(r);
+ gr.Stroke();
+ gr.Restore();
+ }
+
+ gr.MoveTo(rTitle.X + titleGap, rTitle.Y + (int)Math.Ceiling(fe.Height - fe.Descent));
+
+#if _WIN32 || _WIN64
+ gr.ShowText(txt);
+#elif __linux__
+ gr.ShowText(title);
+#endif
+ gr.Color = borderColor;
+ gr.FillExtents();
+
+ }
+ //draw.Flush();
+ //draw.WriteToPng(directories.rootDir + @"test.png");
+ }
+
+ //registerForRedraw();
+ }
+ public override void cairoDraw(ref Context ctx, Rectangles clip = null)
+ {
+ base.cairoDraw(ref ctx, clip);
+ }
+ //public override void cairoDraw(ref Context ctx, Rectangles clip = null)
+ //{
+ // if (!isVisible)//check if necessary??
+ // return;
+
+ // base.cairoDraw(ref ctx, clip);
+
+ // if (clip != null)
+ // clip.Rebase(this);
+
+ // if (child != null)
+ // child.cairoDraw(ref ctx, clip);
+
+ // //ctx.Target.WriteToPng(@"/home/jp/test.png");
+ //}
+
+ public override string ToString()
+ {
+ return this.title + ":" + base.ToString();
+ }
+ }
+}
+
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace go
+{
+ public class HorizontalStack : GenericStack
+ {
+ public HorizontalStack()
+ : base()
+ {
+ Orientation = go.Orientation.Horizontal;
+ }
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Cairo;
+
+namespace go
+{
+ public class HorizontalWrappingWidget : WrappedWidgetGroup
+ {
+ public HorizontalWrappingWidget(int _borderWidth = 0) :
+ base()
+ {
+ Orientation = Orientation.Horizontal;
+ borderWidth = _borderWidth;
+ sizeToContent = true;
+ background = Color.Transparent;
+ }
+ public HorizontalWrappingWidget(Color _borderColor, int _borderWidth = 1) :
+ base()
+ {
+ Orientation = Orientation.Horizontal;
+ borderWidth = _borderWidth;
+ borderColor = _borderColor;
+ background = Color.Transparent;
+ sizeToContent = true;
+ }
+ public HorizontalWrappingWidget(Color _borderColor, Color _background, int _borderWidth = 1) :
+ base()
+ {
+ Orientation = Orientation.Horizontal;
+ borderWidth = _borderWidth;
+ borderColor = _borderColor;
+ background = _background;
+ sizeToContent = true;
+ }
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+//using OpenTK.Graphics.OpenGL;
+using Cairo;
+using System.IO;
+
+namespace go
+{
+ public class Image : GraphicObject
+ {
+
+ byte[] image;
+ Size imgSize;
+
+ public System.Drawing.Bitmap imgBitmap {
+ set {
+ loadImage (value);
+ }
+ }
+
+ string _imgPath;
+
+ public string imgPath {
+ get { return _imgPath; }
+ set {
+ _imgPath = value;
+ loadImage (_imgPath);
+ }
+ }
+
+ public Image () : base()
+ {
+ }
+
+ public Image (string ImagePath, Rectangle _bounds)
+ : base(_bounds)
+ {
+ imgPath = ImagePath;
+ }
+
+ public Image (string ImagePath)
+ : base()
+ {
+ imgPath = ImagePath;
+ }
+
+ public Image (System.Drawing.Bitmap _bitmap)
+ : base()
+ {
+ imgBitmap = _bitmap;
+ }
+
+ public override Size measureRawSize ()
+ {
+ if (image == null)
+ loadImage (directories.rootDir + @"Images/Icons/icon_alert.gif");
+
+ return new Size (imgSize.Width + borderWidth + margin, imgSize.Height + borderWidth + margin);
+ }
+
+ //load image via System.Drawing.Bitmap, cairo load png only
+ public void loadImage (string path)
+ {
+ if (File.Exists (path))
+ loadImage (new System.Drawing.Bitmap (path));
+ }
+
+ public void loadImage (System.Drawing.Bitmap bitmap)
+ {
+ if (bitmap == null)
+ return;
+
+ System.Drawing.Imaging.BitmapData data = bitmap.LockBits
+ (new System.Drawing.Rectangle (0, 0, bitmap.Width, bitmap.Height),
+ System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+
+ imgSize = new Size (bitmap.Width, bitmap.Height);
+
+ int stride = data.Stride;
+ int bitmapSize = Math.Abs (data.Stride) * bitmap.Height;
+
+ image = new byte[bitmapSize];
+ System.Runtime.InteropServices.Marshal.Copy (data.Scan0, image, 0, bitmapSize);
+
+ bitmap.UnlockBits (data);
+ //bitmap.Dispose();
+ }
+
+ internal override void updateGraphic ()
+ {
+ //int maxUV = 0;
+ float ratio = 1f;
+
+
+ //Image.WriteToPng(directories.rootDir + @"test.png");
+ //maxUV = Math.Max(Image.Width, Image.Height);
+
+ float widthRatio = (float)clientBounds.Width / imgSize.Width;
+ float heightRatio = (float)clientBounds.Height / imgSize.Height;
+
+ ratio = Math.Min (widthRatio, heightRatio);
+
+ int stride = 4 * renderBounds.Width;
+
+ //init bmp with widget background and border
+ base.updateGraphic ();
+
+ using (ImageSurface draw =
+ new ImageSurface(bmp, Format.Argb32, renderBounds.Width, renderBounds.Height, stride)) {
+ using (Context gr = new Context(draw)) {
+ //Rectangle r = new Rectangle(0, 0, renderBounds.Width, renderBounds.Height);
+ gr.Antialias = Antialias.Subpixel;
+
+ Rectangle rImg = clientBounds.Clone;
+
+ gr.Scale (widthRatio, heightRatio);
+ using (ImageSurface imgSurf = new ImageSurface(image, Format.Argb32, imgSize.Width, imgSize.Height, 4 * imgSize.Width)) {
+ gr.SetSourceSurface (imgSurf, (int)(rImg.X / widthRatio), (int)(rImg.Y / heightRatio));
+
+ gr.Paint ();
+ }
+ draw.Flush ();
+ }
+ //draw.WriteToPng(directories.rootDir + @"test.png");
+ }
+
+ //Image.Dispose();
+
+ //registerForRedraw();
+ }
+
+
+
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using OpenTK.Graphics.OpenGL;
+
+using GLU = OpenTK.Graphics.Glu;
+using OpenTK.Input;
+using OpenTK;
+using Cairo;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace go
+{
+ public delegate void WidgetEvent (GraphicObject sender);
+
+ public delegate void ButtonWidgetClick (Button sender);
+ //public delegate object ValueGetter(Widget sender);
+
+
+ public static class Interface
+ {
+
+ [DllImport ("libgo.so")]
+ private static extern void TTY_init ();
+
+ [DllImport ("libgo.so")]
+ private static extern void TTY_attend ();
+
+ [DllImport ("libgo.so")]
+ private static extern void FB_init (out Framebuffer fb);
+
+ [DllImport ("libgo.so")]
+ public static extern void DEV_init (int largeur, int hauteur);
+
+ [DllImport ("libgo.so")]
+ public static extern void DEV_lectureEvenement (out Evenement e);
+
+ [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
+ public struct Framebuffer
+ {
+ public IntPtr ptr;
+ public int hauteur;
+ public int largeur;
+ public int linelength;
+ }
+
+ [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
+ public struct Evenement
+ {
+ public int type;
+ public int data1;
+ public int data2;
+ public int data3;
+ public IntPtr emetteur;
+ public const int MOUSE_DOWN = 0x21;
+ public const int MOUSE_UP = 0x22;
+ public const int MOUSE_MVT = 0x23;
+ }
+
+ public static List<Panel> panels = new List<Panel> ();
+ public static Panel activePanel;
+
+ #region cairo contexte
+ public static Context ctx;
+ public static Surface surf;
+ public static byte[] buffer; //opengl byte buffer for rastering
+
+ public static Surface mouseGraphic;
+
+ public static void createFrameBufferSurface ()
+ {
+
+
+ Framebuffer fb;
+ FB_init (out fb);
+ surf = new Cairo.ImageSurface (fb.ptr, Format.ARGB32, fb.largeur, fb.hauteur, fb.linelength);
+ ctx = new Context (surf);
+
+ DEV_init (fb.largeur, fb.hauteur);
+ TTY_init();
+
+ initMouseGraphic ();
+
+ }
+
+ public static void createWin32Surface ()
+ {
+ IntPtr hdc = Win32.GetDC (IntPtr.Zero);
+ surf = new Win32Surface (hdc);
+ ctx = new Context (surf);
+ }
+ public static void createOpenGLSurface()
+ {
+ int stride = 4 * renderBounds.Width;
+
+ int bmpSize = Math.Abs(stride) * renderBounds.Height;
+ buffer = new byte[bmpSize];
+ surf = new ImageSurface(buffer, Format.Argb32, renderBounds.Width, renderBounds.Height, stride);
+ ctx = new Context(surf);
+ }
+ public static void createOpenGLSurface (Rectangle bounds)
+ {
+ renderBounds = bounds;
+
+ createOpenGLSurface();
+ }
+
+ public static void initMouseGraphic ()
+ {
+ mouseGraphic = new ImageSurface (@"Pointeurs/left_ptr.png");
+ //mouseGraphic = new ImageSurface(@"test.png");
+ Thread t = new Thread (deviceThread);
+ t.Start ();
+ }
+
+ public static void deviceThread ()
+ {
+ while (true)
+ {
+ TTY_attend();
+
+ Interface.Evenement e;
+ Interface.DEV_lectureEvenement (out e);
+
+ switch (e.type) {
+ case Evenement.MOUSE_MVT:
+ //erase previouse mouse
+// ctx.Operator = Operator.Clear;
+// ctx.SetSourceSurface(mouseGraphic,mouseX,mouseY);
+// ctx.Paint();
+// ctx.Operator = Operator.Over;
+ lock(redrawClip)
+ {
+ redrawClip.AddRectangle (new Rectangle (mouseX, mouseY, 48, 48));
+ }
+ mouseX = e.data1;
+ mouseY = e.data2;
+
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ #endregion
+
+ //for panel only
+ public static Rectangles redrawClip = new Rectangles ();
+ public static char decimalSeparator = '.';
+
+ #region Mouse Handling"
+ public static bool MouseIsInInterface = false;
+ //used only for pannel mouse grabbing, should extend it to other go
+ public static bool grabMouse = false;
+ public static MouseDevice Mouse;
+
+ public static bool ProcessMousePosition (Point mousePos, Vector2 Delta)
+ {
+ if (checkMouse (mousePos)) {
+ if (Delta != Vector2.Zero) {
+ if (Interface.activePanel != null) {
+ Interface.activePanel.updateMouseCursor ();
+ }
+
+
+ if (Mouse [MouseButton.Left]) {
+ if (Interface.activePanel != null) {
+ if (Interface.grabMouse) {
+ go.Panel p = Interface.activePanel;
+ p.registerForRedraw (); //add previous clip rect
+ switch (Interface.activePanel.mouseBorderPosition) {
+ case PanelBorderPosition.Top:
+ p.y -= (int)Delta.Y;
+ p.height += (int)Delta.Y;
+ break;
+ case PanelBorderPosition.Left:
+ p.x -= (int)Delta.X;
+ p.width += (int)Delta.X;
+ break;
+ case PanelBorderPosition.Right:
+ p.width -= (int)Delta.X;
+ break;
+ case PanelBorderPosition.Bottom:
+ p.height -= (int)Delta.Y;
+ break;
+ case PanelBorderPosition.TopLeft:
+ p.y -= (int)Delta.Y;
+ p.height += (int)Delta.Y;
+ p.x -= (int)Delta.X;
+ p.width += (int)Delta.X;
+ break;
+ case PanelBorderPosition.TopRight:
+ p.y -= (int)Delta.Y;
+ p.height += (int)Delta.Y;
+ p.width -= (int)Delta.X;
+ break;
+ case PanelBorderPosition.BottomLeft:
+ p.height -= (int)Delta.Y;
+ p.x -= (int)Delta.X;
+ p.width += (int)Delta.X;
+ break;
+ case PanelBorderPosition.BottomRight:
+ p.height -= (int)Delta.Y;
+ p.width -= (int)Delta.X;
+ break;
+ case PanelBorderPosition.Moving:
+ p.x -= (int)Delta.X;
+ p.y -= (int)Delta.Y;
+ p.updatePosition ();
+ break;
+ case PanelBorderPosition.ClientArea:
+ break;
+ default:
+ break;
+ }
+ p.invalidateLayout ();
+ }
+ }
+ }
+ }
+ return true;
+ } else
+ return false;
+ }
+
+ public static void ProcessMouseWheel (int delta)
+ {
+ int step = 15;
+ if (activePanel != null)
+ activePanel.ProcessMouseWeel (delta * step);
+ }
+
+ static bool checkMouse (Point mousePos)
+ {
+ if (grabMouse)
+ return true;
+ else if (activePanel != null) {
+ if (activePanel.ProcessMousePosition (mousePos))
+ return true;
+ else
+ activePanel = null;
+ }
+
+ foreach (Panel p in panels) {
+ if (p.isVisible) {
+ if (p.ProcessMousePosition (mousePos)) {
+ activePanel = p;
+ activePanel.putOnTop ();
+ Interface.MouseIsInInterface = true;
+ return true;
+ }
+ }
+ }
+ activePanel = null;
+
+ Interface.MouseIsInInterface = false;
+ return false;
+ }
+
+ public static void Mouse_ButtonDown (object sender, MouseButtonEventArgs e)
+ {
+ if (!MouseIsInInterface)
+ return;
+
+ Point m = e.Position;
+
+ if (activePanel != null) {
+ activePanel.putOnTop ();
+
+ Rectangle r = Interface.activePanel.ScreenCoordClientBounds;
+
+ if (r.Contains (m)) {
+ grabMouse = false;
+ } else {
+ grabMouse = true;
+ }
+ activePanel.ProcessMouseDown (e.Position);
+ activePanel.updateMouseCursor ();
+ }
+
+ if (hoverWidget != null)
+ hoverWidget.ProcessMouseDown (e.Position);
+ }
+
+ public static void Mouse_ButtonUp (object sender, MouseButtonEventArgs e)
+ {
+
+ grabMouse = false;
+
+ if (activeWidget != null) {
+ activeWidget.ProcessMouseUp (e.Position);
+ }
+ }
+
+ #endregion
+
+ #region keyboard handling
+ public static KeyboardDevice Keyboard;
+ private static bool _capitalOn = false;
+
+ public static bool capitalOn {
+ get {
+ return
+ Keyboard [Key.ShiftLeft] || Keyboard [Key.ShiftRight] ?
+ !_capitalOn : _capitalOn;
+ }
+ set { _capitalOn = value; }
+ }
+
+ public static void ProcessKeyboard (Key k)
+ {
+ switch (k) {
+ case Key.CapsLock:
+ capitalOn = !capitalOn;
+ break;
+ }
+
+ if (activeWidget != null)
+ activeWidget.ProcessKeyboard (k);
+ }
+ #endregion
+
+
+
+
+ //used to manage focusable widget like textboxes or buttons
+ private static GraphicObject _activeWidget;
+
+ public static GraphicObject activeWidget {
+ get { return _activeWidget; }
+ set { _activeWidget = value; }
+ }
+
+ static GraphicObject _hoverWidget;
+
+ public static GraphicObject hoverWidget {
+ get { return _hoverWidget; }
+ set {
+ if (value == _hoverWidget)
+ return;
+
+ _hoverWidget = value;
+ }
+ }
+
+ static Rectangle _renderBounds = new Rectangle(0, 0, 800, 600);
+ public static Rectangle renderBounds
+ {
+ get { return _renderBounds; }
+ set
+ {
+ _renderBounds = value;
+ ctx = null;
+ if (surf != null)
+ surf.Dispose();
+ createOpenGLSurface();
+ foreach (Panel p in panels)
+ {
+ p.invalidateLayout();
+ }
+ }
+ }
+
+ public static Panel addPanel (Rectangle _bounds)
+ {
+ Panel p = new Panel (_bounds);
+ panels.Add (p);
+ return p;
+ }
+
+ public static PanelWithTitle addPanel (Rectangle _bounds, string _title)
+ {
+ PanelWithTitle p = new PanelWithTitle (_bounds);
+ p.title = _title;
+ panels.Add (p);
+ return p;
+ }
+
+ public static int mouseX = 0;
+ public static int mouseY = 0;
+
+ public static void update ()
+ {
+
+
+
+ Stopwatch layoutTime = new Stopwatch ();
+ Stopwatch guTime = new Stopwatch ();
+ Stopwatch drawingTime = new Stopwatch ();
+
+
+ Panel[] inversedPanels = new Panel[panels.Count];
+ panels.CopyTo (inversedPanels);
+ inversedPanels = inversedPanels.Reverse ().ToArray ();
+
+ foreach (Panel p in inversedPanels) {
+ if (p.isVisible) {
+ layoutTime.Start ();
+ p.processkLayouting ();
+ layoutTime.Stop ();
+
+
+ }
+ }
+ lock(redrawClip)
+ {
+ if (redrawClip.count > 0) {
+ redrawClip.clearAndClip (ctx);
+
+
+ foreach (Panel p in inversedPanels) {
+ if (p.isVisible) {
+ drawingTime.Start ();
+
+ ctx.Save ();
+
+ if (redrawClip.count > 0) {
+
+
+ Rectangle r = p.renderBounds;
+ Rectangles clip = redrawClip.intersectingRects (r);
+
+ if (clip.count > 0)
+ p.cairoDraw (ref ctx, clip);
+ //p.processDrawing(ctx);
+ }
+ drawingTime.Stop ();
+
+ ctx.Restore ();
+ }
+ }
+ //ctx.SetSourceSurface (mouseGraphic, mouseX, mouseY);
+ //ctx.Paint ();
+ ctx.ResetClip ();
+ redrawClip.Reset ();
+ }
+
+ }
+
+ //Debug.WriteLine("INTERFACE: layouting: {0} ticks \t graphical update {1} ticks \t drawing {2} ticks",
+ // layoutTime.ElapsedTicks,
+ // guTime.ElapsedTicks,
+ // drawingTime.ElapsedTicks);
+ Debug.WriteLine ("INTERFACE: layouting: {0} ms \t graphical update {1} ms \t drawing {2} ms",
+ layoutTime.ElapsedMilliseconds,
+ guTime.ElapsedMilliseconds,
+ drawingTime.ElapsedMilliseconds);
+
+ }
+
+ public static void setTeint (float colorScale)
+ {
+ GL.PixelTransfer (PixelTransferParameter.RedScale, colorScale);
+ GL.PixelTransfer (PixelTransferParameter.BlueScale, colorScale);
+ GL.PixelTransfer (PixelTransferParameter.GreenScale, colorScale);
+ }
+
+ public static byte[] flitY (byte[] source, int stride, int height)
+ {
+ byte[] bmp = new byte[source.Length];
+ source.CopyTo (bmp, 0);
+
+ for (int y = 0; y < height / 2; y++) {
+ for (int x = 0; x < stride; x++) {
+ byte tmp = bmp [y * stride + x];
+ bmp [y * stride + x] = bmp [(height - 1 - y) * stride + x];
+ bmp [(height - y - 1) * stride + x] = tmp;
+ }
+ }
+ return bmp;
+ }
+
+ public static double min (params double[] arr)
+ {
+ int minp = 0;
+ for (int i = 1; i < arr.Length; i++)
+ if (arr [i] < arr [minp])
+ minp = i;
+
+ return arr [minp];
+ }
+
+ public static void DrawRoundedRectangle (Cairo.Context gr, Rectangle r, double radius)
+ {
+ DrawRoundedRectangle (gr, r.X, r.Y, r.Width, r.Height, radius);
+ }
+
+ public static void DrawCurvedRectangle (Cairo.Context gr, Rectangle r)
+ {
+ DrawCurvedRectangle (gr, r.X, r.Y, r.Width, r.Height);
+ }
+
+ public static void DrawRoundedRectangle (Cairo.Context gr, double x, double y, double width, double height, double radius)
+ {
+ gr.Save ();
+
+ if ((radius > height / 2) || (radius > width / 2))
+ radius = min (height / 2, width / 2);
+
+ gr.MoveTo (x, y + radius);
+ gr.Arc (x + radius, y + radius, radius, Math.PI, -Math.PI / 2);
+ gr.LineTo (x + width - radius, y);
+ gr.Arc (x + width - radius, y + radius, radius, -Math.PI / 2, 0);
+ gr.LineTo (x + width, y + height - radius);
+ gr.Arc (x + width - radius, y + height - radius, radius, 0, Math.PI / 2);
+ gr.LineTo (x + radius, y + height);
+ gr.Arc (x + radius, y + height - radius, radius, Math.PI / 2, Math.PI);
+ gr.ClosePath ();
+ gr.Restore ();
+ }
+
+ public static void DrawCurvedRectangle (Cairo.Context gr, double x, double y, double width, double height)
+ {
+ gr.Save ();
+ gr.MoveTo (x, y + height / 2);
+ gr.CurveTo (x, y, x, y, x + width / 2, y);
+ gr.CurveTo (x + width, y, x + width, y, x + width, y + height / 2);
+ gr.CurveTo (x + width, y + height, x + width, y + height, x + width / 2, y + height);
+ gr.CurveTo (x, y + height, x, y + height, x, y + height / 2);
+ gr.Restore ();
+ }
+
+ public static void StrokeRaisedRectangle (Cairo.Context gr, Rectangle r, double width = 1)
+ {
+ gr.Save ();
+ r.Inflate ((int)-width / 2, (int)-width / 2);
+ gr.LineWidth = width;
+ gr.Color = Color.White;
+ gr.MoveTo (r.BottomLeft);
+ gr.LineTo (r.TopLeft);
+ gr.LineTo (r.TopRight);
+ gr.Stroke ();
+
+ gr.Color = Color.DarkGray;
+ gr.MoveTo (r.TopRight);
+ gr.LineTo (r.BottomRight);
+ gr.LineTo (r.BottomLeft);
+ gr.Stroke ();
+
+ gr.Restore ();
+ }
+
+ public static void StrokeLoweredRectangle (Cairo.Context gr, Rectangle r, double width = 1)
+ {
+ gr.Save ();
+ r.Inflate ((int)-width / 2, (int)-width / 2);
+ gr.LineWidth = width;
+ gr.Color = Color.DarkGray;
+ gr.MoveTo (r.BottomLeft);
+ gr.LineTo (r.TopLeft);
+ gr.LineTo (r.TopRight);
+ gr.Stroke ();
+ gr.Color = Color.White;
+ gr.MoveTo (r.TopRight);
+ gr.LineTo (r.BottomRight);
+ gr.LineTo (r.BottomLeft);
+ gr.Stroke ();
+
+ gr.Restore ();
+ }
+ }
+
+
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Diagnostics;
+using Cairo;
+
+namespace go
+{
+ public class Label : GraphicObject
+ {
+ //static constructor to init label specific theme value
+ public static class Theme
+ {
+ public static Color background = Color.Transparent;
+ public static Color borderColor = Color.White;
+ public static int margin = 0;
+ public static int borderWidth = 0;
+ public static VerticalAlignment verticalAlignment = VerticalAlignment.None;
+ public static HorizontalAlignment horizontalAlignment = HorizontalAlignment.None;
+ public static bool sizeToContent = false;
+ //label specific
+ public static int fontSize = 10;
+ public static Color fontColor = Color.White;
+ }
+
+ public Label(string _text)
+ : base()
+ {
+ init();
+ updateFont();
+ text = _text;
+
+ }
+
+ void init()
+ {
+ background = Theme.background;
+ borderColor = Theme.borderColor;
+ borderWidth = Theme.borderWidth;
+ margin = Theme.margin;
+ horizontalAlignment = Theme.horizontalAlignment;
+ verticalAlignment = Theme.verticalAlignment;
+ sizeToContent = Theme.sizeToContent;
+ fontSize = Theme.fontSize;
+ fontColor = Theme.fontColor;
+ }
+
+
+
+ protected string _text = "label";
+ int _fontSize;
+ Color _fontColor;
+
+ public string text
+ {
+ get { return _text; }
+ set
+ {
+ if (_text == value)
+ return;
+
+ registerForGraphicUpdate();
+
+ //if (value.Length != _text.Length)
+ // layoutIsValid = false;
+
+ _text = value;
+ }
+ }
+ public int fontSize
+ {
+ get { return _fontSize; }
+ set
+ {
+ _fontSize = value;
+ registerForGraphicUpdate();
+ }
+ }
+ public Color fontColor
+ {
+ get { return _fontColor; }
+ set
+ {
+ _fontColor = value;
+ registerForGraphicUpdate();
+ }
+ }
+
+ public byte[] utf8Text
+ {
+ get { return System.Text.UTF8Encoding.UTF8.GetBytes(text); }
+ }
+
+ protected Rectangle rText;
+
+ //public FontStyle fontStyle
+ //{
+ // get { return _fontStyle; }
+ // set
+ // {
+ // _fontStyle = value;
+ // updateFont();
+ // }
+ //}
+ //public FontFamily fontFamily
+ //{
+ // get { return _fontFamily; }
+ // set
+ // {
+ // _fontFamily = value;
+ // updateFont();
+ // }
+ //}
+
+
+
+ //Font TextFont;
+
+ public Alignment textAlignment = Alignment.LeftCenter;
+
+
+
+ void updateFont()
+ {
+ //TextFont = new Font(fontFamily, fontSize, fontStyle, GraphicsUnit.Pixel);
+ bmp = null;
+ }
+
+ public override Size measureRawSize()
+ {
+ byte[] txt = utf8Text;
+
+ Size s;
+
+ using (Context gr = new Context(new ImageSurface(Format.Argb32,1,1)))
+ {
+ gr.SetFontSize(fontSize);
+ TextExtents te;
+#if _WIN32 || _WIN64
+ te = gr.TextExtents(utf8Text);
+#elif __linux__
+ te = gr.TextExtents(text);
+#endif
+ FontExtents fe = gr.FontExtents;
+ s = new Size((int)Math.Ceiling(te.XAdvance),(int)Math.Ceiling(fe.Height));
+ }
+ return s;// +borderWidth;
+ }
+
+ internal override void updateGraphic()
+ {
+ byte[] txt = utf8Text;
+ int stride = 4 * renderBounds.Width;
+
+
+ //init bmp with widget background and border
+ base.updateGraphic();
+
+ using (ImageSurface bitmap =
+ new ImageSurface(bmp, Format.Argb32, renderBounds.Width, renderBounds.Height, stride))
+ {
+ using (Context gr = new Context(bitmap))
+ {
+ gr.FontOptions.Antialias = Antialias.Subpixel;
+ gr.FontOptions.HintMetrics = HintMetrics.On;
+ gr.SetFontSize(fontSize);
+ FontExtents fe = gr.FontExtents;
+ rText = new Rectangle(new Point(0,0), measureRawSize());
+ //gr.Rotate(Math.PI);
+
+ // double a = Math.PI;
+ //gr.Transform(new c.Matrix(Math.Cos(a),-Math.Sin(a),Math.Sin(a),Math.Cos(a),renderBounds.Width,renderBounds.Height));
+ gr.Antialias = Antialias.Subpixel;
+ gr.LineWidth = borderWidth;
+
+ float widthRatio = 1f;
+ float heightRatio = 1f;
+
+ Rectangle cb = clientBounds;
+
+ //ignore text alignment if size to content = true
+ if (!sizeToContent)
+ {
+ switch (textAlignment)
+ {
+ case Alignment.None:
+ break;
+ case Alignment.TopLeft: //ok
+ rText.X = cb.X;
+ rText.Y = cb.Y;
+ break;
+ case Alignment.TopCenter: //ok
+ rText.Y = cb.Y;
+ rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
+ break;
+ case Alignment.TopRight: //ok
+ rText.X = cb.Right - rText.Width;
+ rText.Y = cb.Y;
+ break;
+ case Alignment.TopStretch://ok
+ heightRatio = widthRatio = (float)cb.Width / rText.Width;
+ rText.X = cb.X;
+ rText.Y = cb.Y;
+ rText.Width = cb.Width;
+ rText.Height = (int)(rText.Height * heightRatio);
+ break;
+ case Alignment.LeftCenter://ok
+ rText.X = cb.X;
+ rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+ break;
+ case Alignment.LeftStretch://ok
+ heightRatio = widthRatio = (float)cb.Height / rText.Height;
+ rText.X = cb.X;
+ rText.Y = cb.Y;
+ rText.Height = cb.Height;
+ rText.Width = (int)(widthRatio * cb.Width);
+ break;
+ case Alignment.RightCenter://ok
+ rText.X = cb.X + cb.Width - rText.Width;
+ rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+ break;
+ case Alignment.RightStretch://ok
+ heightRatio = widthRatio = (float)cb.Height / rText.Height;
+ rText.Height = cb.Height;
+ rText.Width = (int)(widthRatio * cb.Width);
+ rText.X = cb.X;
+ rText.Y = cb.Y;
+ break;
+ case Alignment.BottomCenter://ok
+ rText.X = cb.Width / 2 - rText.Width / 2;
+ rText.Y = cb.Height - rText.Height;
+ break;
+ case Alignment.BottomStretch://ok
+ heightRatio = widthRatio = (float)cb.Width / rText.Width;
+ rText.Width = cb.Width;
+ rText.Height = (int)(rText.Height * heightRatio);
+ rText.Y = cb.Bottom - rText.Height;
+ rText.X = cb.X;
+ break;
+ case Alignment.BottomLeft://ok
+ rText.X = cb.X;
+ rText.Y = cb.Bottom - rText.Height;
+ break;
+ case Alignment.BottomRight://ok
+ rText.Y = cb.Bottom - rText.Height;
+ rText.X = cb.Right - rText.Width;
+ break;
+ case Alignment.Center://ok
+ rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
+ rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+ break;
+ case Alignment.Fit://ok, peut être mieu aligné
+ widthRatio = (float)cb.Width / rText.Width;
+ heightRatio = (float)cb.Height / rText.Height;
+ rText = cb.Clone;
+ break;
+ case Alignment.HorizontalStretch://ok
+ heightRatio = widthRatio = (float)cb.Width / rText.Width;
+ rText.Width = cb.Width;
+ rText.Height = (int)(heightRatio * rText.Height);
+ rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+ rText.X = cb.X;
+ break;
+ case Alignment.VerticalStretch://ok
+ heightRatio = widthRatio = (float)cb.Height / rText.Height;
+ rText.Height = cb.Height;
+ rText.Width = (int)(widthRatio * rText.Width);
+ rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
+ rText.Y = cb.Y;
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ gr.Color = fontColor;
+
+ gr.FontMatrix = new Matrix(widthRatio * fontSize, 0, 0, heightRatio * fontSize, 0, 0);
+
+ fe = gr.FontExtents;
+
+ gr.MoveTo(rText.X, rText.Y + fe.Ascent);
+#if _WIN32 || _WIN64
+ gr.ShowText(txt);
+#elif __linux__
+ gr.ShowText(text);
+#endif
+
+ gr.Fill();
+
+ }
+ bitmap.Flush();
+ //bitmap.WriteToPng(directories.rootDir + @"test.png");
+ }
+
+ //registerForRedraw();
+ }
+
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace go
+{
+ public static class Mouse2d
+ {
+ public static Point position;
+
+ public static int X
+ {
+ get { return position.X; }
+ set { position.X = value; }
+ }
+ public static int Y
+ {
+ get { return position.Y; }
+ set { position.Y = value; }
+ }
+
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using OpenTK;
+using OpenTK.Graphics.OpenGL;
+using System.Drawing;
+using System.Diagnostics;
+using OTKGL;
+using OpenTK.Input;
+
+namespace OTKGL
+{
+
+
+
+ public static class Mouse3d
+ {
+ #region winApi
+
+ [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
+ public struct Point
+ {
+
+ /// LONG->int
+ public int x;
+
+ /// LONG->int
+ public int y;
+ }
+ [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
+ public struct HICON__
+ {
+
+ /// int
+ public int unused;
+ }
+
+#if _WIN32 || _WIN64
+ /// Return Type: HCURSOR->HICON->HICON__*
+ ///hCursor: HCURSOR->HICON->HICON__*
+ [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "SetCursor")]
+ public static extern System.IntPtr SetCursor([System.Runtime.InteropServices.InAttribute()] System.IntPtr hCursor);
+#elif __linux__
+ public static System.IntPtr SetCursor(System.IntPtr hCursor)
+ {
+ return (IntPtr)0;
+ }
+#endif
+
+ /// Return Type: BOOL->int
+ ///lpPoint: LPPOINT->tagPOINT*
+ [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "GetCursorPos")]
+ [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
+ public static extern bool GetCursorPos([System.Runtime.InteropServices.OutAttribute()] out Point lpPoint);
+
+ /// Return Type: BOOL->int
+ ///X: int
+ ///Y: int
+ [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "SetCursorPos")]
+ [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
+ public static extern bool SetCursorPos(int X, int Y);
+
+ #endregion
+
+ public static float RotationSpeed = 0.005f;
+
+ public static Vector3 Position;
+ public static bool MouseLeftIsDown = false;
+ public static bool MouseRightIsDown = false;
+ public static bool MouseMiddleIsDown = false;
+
+
+ static int oldMouseX;
+ static int oldMouseY;
+
+ public static void setPosition(Vector3 newPos)
+ {
+ Position = newPos;
+ Point pt;
+ GetCursorPos(out pt);
+ oldMouseX = pt.x;
+ oldMouseY = pt.y;
+ }
+
+ public static void update()
+ {
+ //SetCursor((IntPtr)0);
+
+ Point pt;
+ GetCursorPos(out pt);
+
+ //mise a jour mouse 3d
+
+ int mDiffX = oldMouseX - pt.x;
+ int mDiffY = oldMouseY - pt.y;
+
+
+
+ GetCursorPos(out pt);
+
+ oldMouseX = pt.x;
+ oldMouseY = pt.y;
+
+ Delta = new Vector2(mDiffX, mDiffY);
+
+
+ //if (Delta != Vector2.Zero)
+ //{
+ // if (MouseRightIsDown )
+ // {
+ // //camera rotation
+ // Matrix4 m = Matrix4.CreateRotationZ(Delta.X * RotationSpeed);
+ // vLook = Vector3.Transform(vLook, m);
+
+ // //vecteur perpendiculaire sur le plan x,y
+ // Vector3 vLookPerpendicularOnXYPlane = new Vector3(new Vector2(vLook).PerpendicularLeft);
+ // vLookPerpendicularOnXYPlane.Normalize();
+
+ // Matrix4 m2 = Matrix4.Rotate(vLookPerpendicularOnXYPlane, -Delta.Y * RotationSpeed);
+
+ // vLook = Vector3.Transform(vLook, m2);
+ // }
+
+ //}
+ //return vLook;
+ }
+
+ public static Vector2 Delta = Vector2.Zero;
+
+
+ public static float X
+ { get { return Position.X; } }
+ public static float Y
+ { get { return Position.Y; } }
+
+
+ public static void init()
+ {
+ float initpos = 40f;
+ Position = new Vector3(initpos,initpos,World.CurrentWorld.getHeight(initpos,initpos));
+ }
+ public static void render()
+ {
+ GL.PushAttrib(AttribMask.EnableBit);
+ GL.Disable(EnableCap.Texture2D);
+ GL.Disable(EnableCap.Lighting);
+ GL.Disable(EnableCap.DepthTest);
+
+ GL.PointSize(5.0f);
+ GL.Color3(Color.Aqua);
+
+ GL.Begin(BeginMode.Points);
+ GL.Vertex3(Position);
+ GL.End();
+
+ GL.Color3(Color.White);
+ GL.PopAttrib();
+ }
+
+ public static void Mouse_ButtonDown(object sender, MouseButtonEventArgs e)
+ {
+ if (e.Button == MouseButton.Left)
+ MouseLeftIsDown = true;
+ if (e.Button == MouseButton.Right)
+ MouseRightIsDown = true;
+ if (e.Button == MouseButton.Middle)
+ MouseMiddleIsDown = true;
+ }
+ public static void Mouse_ButtonUp(object sender, MouseButtonEventArgs e)
+ {
+ if (e.Button == MouseButton.Left)
+ MouseLeftIsDown = false;
+ if (e.Button == MouseButton.Right)
+ MouseRightIsDown = false;
+ if (e.Button == MouseButton.Middle)
+ MouseMiddleIsDown = false;
+
+ }
+
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using OpenTK.Graphics.OpenGL;
+using System.Windows.Forms;
+
+using Cairo;
+using OpenTK;
+
+namespace go
+{
+ public class Panel : Container
+ {
+ private static GraphicObject _activeWidget;
+
+ public static GraphicObject activeWidget
+ {
+ get { return _activeWidget; }
+ set
+ {
+ if (_activeWidget != null)
+ _activeWidget.hasFocus = false;
+ _activeWidget = value;
+ if (_activeWidget != null)
+ _activeWidget.hasFocus = true;
+ }
+ }
+
+ public override int x
+ {
+ get { return bounds.X; }
+ set
+ {
+ if (value < 0)
+ bounds.X = 0;
+ else if (value > Interface.renderBounds.Right)
+ value = (int)Interface.renderBounds.Right - bounds.Width;
+ else
+ bounds.X = value;
+ }
+ }
+ public override int y
+ {
+ get { return bounds.Y; }
+ set
+ {
+ if (value < 0)
+ bounds.Y = 0;
+ else if (value > Interface.renderBounds.Bottom - bounds.Height)
+ bounds.Y = (int)Interface.renderBounds.Bottom - bounds.Height;
+ else
+ bounds.Y = value;
+ }
+ }
+ public override bool isVisible
+ {
+ get { return _isVisible; }
+ set
+ {
+ if (value == _isVisible)
+ return;
+
+ if (!value)//register old clip while visible for backend clearing
+ registerForRedraw();
+
+ _isVisible = value;
+
+ invalidateLayout();
+
+ //callForRedraw();
+ }
+ }
+ bool _cachingInProgress = false;
+ public override bool cachingInProgress
+ {
+ get { return _cachingInProgress; }
+ set { _cachingInProgress = value; }
+ }
+
+ public override void registerForRedraw()
+ {
+ base.registerForRedraw();
+ }
+ //smart array of clipping rectangles
+ //public Rectangles redrawClip = new Rectangles();
+
+
+ public PanelBorderPosition mouseBorderPosition = PanelBorderPosition.ClientArea;
+
+ public override Rectangle renderBoundsInBackendSurfaceCoordonate
+ { get { return renderBounds.Clone; } }
+
+ public Panel(Rectangle _bounds)
+ : base(_bounds)
+ {
+ borderWidth = 1;
+ margin = 5;
+ verticalAlignment = go.VerticalAlignment.None;
+ horizontalAlignment = go.HorizontalAlignment.None;
+ }
+
+
+ public void processkLayouting()
+ {
+ if (!isVisible)
+ return;
+
+ while (!this.layoutIsValid)
+ {
+
+ this.updateLayout();
+
+ }
+ }
+
+ public void processDrawing(Context ctx)
+ {
+ //if (bmp == null)
+ //{
+ // updateGraphic();
+ // cachingInProgress = true;
+ //}
+ //if (redrawClip.count > 0)
+ //{
+ // if (!cachingInProgress) //not full redraw of cache
+ // {
+ // //clip to panel client zone;
+ // ctx.Rectangle(renderBoundsInBackSurfaceCoordonate);
+ // ctx.Clip();
+ // redrawClip.clearAndClip(ctx);
+ // }
+
+ // cairoDraw(ref ctx);
+
+ // //clip to panel client zone;
+ // ctx.Rectangle(renderBoundsInBackSurfaceCoordonate);
+ // ctx.Clip();
+ // //ctx.Target.WriteToPng(directories.rootDir + @"test.png");
+
+
+ // if (child != null)
+ // {
+ // Rectangle r = child.renderBoundsInBackSurfaceCoordonate;
+
+ // Rectangles clip = redrawClip.intersectingRects(r);
+
+ // if (clip.count > 0 || cachingInProgress)
+ // child.cairoDraw(ref ctx, clip);
+ // }
+
+ // cachingInProgress = false;
+
+ // ctx.ResetClip();
+ // redrawClip.Reset();
+ //}
+ }
+
+ #region widget overides
+
+ //public override void registerForRedraw()
+ //{
+ // Interface.redrawClip.AddRectangle(this.renderBoundsInContextCoordonate);
+ //}
+
+
+ #region Mouse handling
+ public override void ProcessMouseDown(Point mousePos)
+ {
+ if (!isVisible)
+ return;
+
+ if (mouseBorderPosition == PanelBorderPosition.Closing)
+ isVisible = false;
+
+ //base.ProcessMouseDown(mousePos);
+
+ //if (child != null)
+ // child.ProcessMouseDown(mousePos);
+
+
+ }
+ public override bool ProcessMousePosition(Point mousePos)
+ {
+ if (!isVisible)
+ return false;
+
+ if (base.ProcessMousePosition(mousePos))
+ {
+ if (ScreenCoordClientBounds.Contains(mousePos))
+ {
+ mouseBorderPosition = PanelBorderPosition.ClientArea;
+
+ if (child != null)
+ child.ProcessMousePosition(mousePos);
+ }
+ else
+ {
+ Point m = mousePos;
+
+ if (this is PanelWithTitle)
+ {
+ if (rectInScreenCoord((this as PanelWithTitle).rClose).Contains(m))
+ {
+ mouseBorderPosition = PanelBorderPosition.Closing;
+ return true;
+ }
+ }
+
+ Rectangle r = ScreenCoordClientBounds.Clone;
+
+ if (m.X <= r.X)
+ {
+ if (m.Y <= r.Y)
+ mouseBorderPosition = PanelBorderPosition.TopLeft;
+ else if (m.Y >= r.Bottom)
+ mouseBorderPosition = PanelBorderPosition.BottomLeft;
+ else
+ mouseBorderPosition = PanelBorderPosition.Left;
+ }
+ else if (m.X >= r.Right)
+ {
+ if (m.Y <= r.Y)
+ mouseBorderPosition = PanelBorderPosition.TopRight;
+ else if (m.Y >= r.Bottom)
+ mouseBorderPosition = PanelBorderPosition.BottomRight;
+ else
+ mouseBorderPosition = PanelBorderPosition.Right;
+ }
+ else
+ {
+ if (m.Y <= r.Y)
+ {
+ if (this is PanelWithTitle)
+ {
+ if (m.Y <= r.Y - ((this as PanelWithTitle).titleSize().Height + 2 * borderWidth))
+ mouseBorderPosition = PanelBorderPosition.Top;
+ else
+ mouseBorderPosition = PanelBorderPosition.Moving;
+
+
+ return true;
+ }
+ else
+ mouseBorderPosition = PanelBorderPosition.Top;
+ }
+ else if (m.Y >= r.Bottom)
+ mouseBorderPosition = PanelBorderPosition.Bottom;
+ else
+ mouseBorderPosition = PanelBorderPosition.ClientArea;
+ }
+ }
+
+ return true;
+ }
+ else
+ return false;
+ }
+
+ #endregion
+
+ #endregion
+
+ public void updateMouseCursor()
+ {
+ switch (mouseBorderPosition)
+ {
+ case PanelBorderPosition.Top:
+ Win32.SetCursor(Cursors.SizeNS.Handle);
+ break;
+ case PanelBorderPosition.Left:
+ Win32.SetCursor(Cursors.SizeWE.Handle);
+ break;
+ case PanelBorderPosition.Right:
+ Win32.SetCursor(Cursors.SizeWE.Handle);
+ break;
+ case PanelBorderPosition.Bottom:
+ Win32.SetCursor(Cursors.SizeNS.Handle);
+ break;
+ case PanelBorderPosition.TopLeft:
+ Win32.SetCursor(Cursors.SizeNWSE.Handle);
+ break;
+ case PanelBorderPosition.TopRight:
+ Win32.SetCursor(Cursors.SizeNESW.Handle);
+ break;
+ case PanelBorderPosition.BottomLeft:
+ Win32.SetCursor(Cursors.SizeNESW.Handle);
+ break;
+ case PanelBorderPosition.BottomRight:
+ Win32.SetCursor(Cursors.SizeNWSE.Handle);
+ break;
+ case PanelBorderPosition.Moving:
+ Win32.SetCursor(Cursors.SizeAll.Handle);
+ break;
+ case PanelBorderPosition.Closing:
+ Win32.SetCursor(Cursors.Default.Handle);
+ break;
+ case PanelBorderPosition.ClientArea:
+ //Interface.SetCursor(Cursors.Hand.Handle);
+ break;
+ default:
+ break;
+ }
+ }
+ public void putOnTop()
+ {
+ if (Interface.panels.IndexOf(this) > 0)
+ {
+ Interface.panels.Remove(this);
+ Interface.panels.Insert(0, this);
+ this.registerForRedraw();
+ }
+ }
+
+
+
+ public override string ToString()
+ {
+ string tmp = this.GetType().ToString().Split(new char[] { '.' }).Last() + ":-";
+ return tmp + string.Format("rb:{0}", renderBounds);
+ }
+ }
+}
+
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Cairo;
+
+namespace go
+{
+ public class PanelWithTitle : Panel
+ {
+ public PanelWithTitle(Rectangle _bounds)
+ : base(_bounds)
+ {
+ background = Color.DimGray;
+ }
+
+ string _title = "Panel";
+ public string title
+ {
+ get { return _title; }
+ set
+ {
+ _title = value;
+ registerForGraphicUpdate();
+ }
+ }
+
+ int _fontSize = 10;
+ public int fontSize
+ {
+ get { return _fontSize; }
+ set
+ {
+ _fontSize = value;
+ registerForGraphicUpdate();
+ }
+ }
+ public Color titleBackground = new Color(0.5, 0.5, 0.7, 0.8);
+ public Color titleTextColor = new Color(0.9, 0.9, 0.9, 1);
+ public Size titleSize ()
+ {
+#if _WIN32 || _WIN64
+ byte[] txt = System.Text.UTF8Encoding.UTF8.GetBytes(_title);
+#endif
+
+ Size s;
+
+ using (Context gr = new Context(new ImageSurface(Format.Argb32,1,1)))
+ {
+ gr.SetFontSize(fontSize);
+ TextExtents te;
+#if _WIN32 || _WIN64
+ te = gr.TextExtents(txt);
+#elif __linux__
+ te = gr.TextExtents(title);
+#endif
+ FontExtents fe = gr.FontExtents;
+ s = new Size((int)Math.Ceiling(te.XAdvance),(int)Math.Ceiling(fe.Height));
+ }
+ return s;// +borderWidth;
+ }
+ public override Rectangle clientBounds
+ {
+ get
+ {
+ Size st = titleSize() + borderWidth*2;
+ Rectangle cb = bounds.Clone;
+ cb.X = 0;
+ cb.Y = st.Height;
+ cb.Height -= st.Height;
+ cb.Inflate(-borderWidth-margin, -borderWidth-margin);
+
+ //cb.Y += titleHeight;
+ return cb;
+ }
+ }
+
+ internal Rectangle rClose = new Rectangle();//close button
+ internal override void updateGraphic()
+ {
+
+ int stride = 4 * renderBounds.Width;
+
+ int bmpSize = Math.Abs(stride) * renderBounds.Height;
+ bmp = new byte[bmpSize];
+
+ byte[] txt = System.Text.UTF8Encoding.UTF8.GetBytes(title);// utf = new System.Text.Decoder();
+
+ using (ImageSurface draw = new ImageSurface(bmp, Format.Argb32, renderBounds.Width, renderBounds.Height, stride))
+ {
+ using (Context gr = new Context(draw))
+ {
+
+
+ Rectangle r = new Rectangle(0, 0, renderBounds.Width, renderBounds.Height);
+ //gr.Rotate(Math.PI);
+ gr.SetFontSize(fontSize);
+ FontExtents fe = gr.FontExtents;
+ // double a = Math.PI;
+ //gr.Transform(new c.Matrix(Math.Cos(a),-Math.Sin(a),Math.Sin(a),Math.Cos(a),renderBounds.Width,renderBounds.Height));
+ gr.Antialias = Antialias.Subpixel;
+ gr.LineWidth = borderWidth;
+ gr.Color = background;
+ //gr.MoveTo(renderBounds.X+1,renderBounds.Y+1);
+ gr.Rectangle(r);
+ gr.Fill();
+ draw.Flush();
+
+ Rectangle rTitle = r.Clone;
+ rTitle.Height = titleSize().Height + borderWidth * 2;
+ gr.Color = Color.blue1;
+ gr.Rectangle(rTitle);
+ gr.Fill();
+ rTitle.Inflate(-borderWidth / 2, -borderWidth / 2);
+ gr.Rectangle(rTitle);
+ gr.Color = borderColor;
+ gr.Stroke();
+
+ r.Inflate(-borderWidth / 2, -borderWidth / 2);
+ gr.Rectangle(r);
+ gr.Color = borderColor;
+ gr.Stroke();
+ //gr.TextExtents(txt);
+
+
+ gr.MoveTo(borderWidth + 1, fe.Height - fe.Descent + borderWidth);
+#if _WIN32 || _WIN64
+ gr.ShowText(txt);
+#elif __linux__
+ gr.ShowText(title);
+#endif
+ gr.Fill();
+ //gr.Stroke();
+ gr.LineWidth = 1;
+
+ rClose = rTitle.Clone;
+ rClose.Width = rClose.Height;
+ rClose.Left = rTitle.Right - rClose.Width;
+ rClose.Inflate(-6, -6);
+ gr.MoveTo(rClose.X, rClose.Y);
+ gr.LineTo(rClose.Right, rClose.Bottom);
+ gr.MoveTo(rClose.X, rClose.Bottom);
+ gr.LineTo(rClose.Right, rClose.Top);
+ gr.Stroke();
+ rClose.Inflate(3, 3);
+ gr.Rectangle(rClose);
+ gr.Stroke();
+ }
+ draw.Flush();
+ //draw.WriteToPng(directories.rootDir + @"test.png");
+ }
+
+ //registerForRedraw();
+ }
+ public override string ToString()
+ {
+ return this.title + ":" + base.ToString();
+ }
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace go
+{
+ public struct Point
+ {
+ int _x;
+ int _y;
+
+ public int X
+ {
+ get { return _x; }
+ set { _x = value; }
+ }
+ public int Y
+ {
+ get { return _y; }
+ set { _y = value; }
+ }
+ public Point(int x, int y)
+ {
+ _x = x;
+ _y = y;
+ }
+
+ public static implicit operator Cairo.Point(Point p)
+ {
+ return new Cairo.Point(p.X, p.Y);
+ }
+ public static implicit operator Cairo.PointD(Point p)
+ {
+ return new Cairo.PointD(p.X, p.Y);
+ }
+ public static implicit operator System.Drawing.Point(Point p)
+ {
+ return new System.Drawing.Point(p.X, p.Y);
+ }
+ public static implicit operator Point(System.Drawing.Point p)
+ {
+ return new Point(p.X, p.Y);
+ }
+ public static implicit operator Point(int i)
+ {
+ return new Point(i, i);
+ }
+
+ public static Point operator +(Point p1, Point p2)
+ {
+ return new Point(p1.X + p2.X, p1.Y + p2.Y);
+ }
+ public static Point operator -(Point p1, Point p2)
+ {
+ return new Point(p1.X - p2.X, p1.Y - p2.Y);
+ }
+ public static bool operator >=(Point p1, Point p2)
+ {
+ return p1.X >= p2.X && p1.Y >= p2.Y ? true : false;
+ }
+ public static bool operator <=(Point p1, Point p2)
+ {
+ return p1.X <= p2.X && p1.Y <= p2.Y ? true : false;
+ }
+ public static bool operator ==(Point s, int i)
+ {
+ if (s.X == i && s.Y == i)
+ return true;
+ else
+ return false;
+ }
+ public static bool operator !=(Point s, int i)
+ {
+ if (s.X == i && s.Y == i)
+ return false;
+ else
+ return true;
+ }
+ public static bool operator >(Point s, int i)
+ {
+ if (s.X > i && s.Y > i)
+ return true;
+ else
+ return false;
+ }
+ public static bool operator <(Point s, int i)
+ {
+ if (s.X < i && s.Y < i)
+ return true;
+ else
+ return false;
+ }
+ public static bool operator ==(Point s1, Point s2)
+ {
+ if (s1.X == s2.X && s1.Y == s2.Y)
+ return true;
+ else
+ return false;
+ }
+ public static bool operator !=(Point s1, Point s2)
+ {
+ if (s1.X == s2.X && s1.Y == s2.Y)
+ return false;
+ else
+ return true;
+ }
+
+ public override string ToString()
+ {
+ return string.Format("({0},{1})", X, Y);
+ }
+
+ public override bool Equals(object obj)
+ {
+ return base.Equals(obj);
+ }
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+ }
+
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace go
+{
+ //should try to change it to struct
+ public class Rectangle
+ {
+ int _x = 0;
+ int _y = 0;
+ int _width = 0;
+ int _height = 0;
+
+ public Rectangle()
+ { }
+ public Rectangle(Point p, Size s)
+ {
+ _x = p.X;
+ _y = p.Y;
+ _width = s.Width;
+ _height = s.Height;
+ }
+ public Rectangle(Size s)
+ {
+ _x = 0;
+ _y = 0;
+ _width = s.Width;
+ _height = s.Height;
+ }
+ public Rectangle(int x, int y, int width, int height)
+ {
+ _x = x;
+ _y = y;
+ _width = width;
+ _height = height;
+ }
+
+ public int X
+ {
+ get { return _x; }
+ set { _x = value; }
+ }
+ public int Y
+ {
+ get { return _y; }
+ set { _y = value; }
+ }
+ public int Left
+ {
+ get { return _x; }
+ set { _x = value; }
+ }
+ public int Top
+ {
+ get { return _y; }
+ set { _y = value; }
+ }
+ public int Right
+ {
+ get { return _x + _width; }
+ }
+ public int Bottom
+ {
+ get { return _y + _height; }
+ }
+
+ public int Width
+ {
+ get { return _width; }
+ set { _width = value; }
+ }
+ public int Height
+ {
+ get { return _height; }
+ set { _height = value; }
+ }
+ public Size Size
+ {
+ get { return new Size(Width, Height); }
+ set
+ {
+ Width = value.Width;
+ Height = value.Height;
+ }
+ }
+ public Point TopLeft
+ {
+ set
+ {
+ X = value.X;
+ Y = value.Y;
+ }
+ get { return new Point(X, Y); }
+ }
+ public Point TopRight
+ {
+ get { return new Point(Right, Y); }
+ }
+ public Point BottomLeft
+ {
+ get { return new Point(X, Bottom); }
+ }
+ public Point BottomRight
+ {
+ get { return new Point(Right, Bottom); }
+ }
+ public void Inflate(int xDelta, int yDelta)
+ {
+ this.X -= xDelta;
+ this.Width += 2 * xDelta;
+ this.Y -= yDelta;
+ this.Height += 2 * yDelta;
+ }
+ public bool Contains(Point p)
+ {
+ return (p.X >= X && p.X <= X + Width && p.Y >= Y && p.Y <= Y + Height) ?
+ true : false;
+ }
+ public bool Contains(Rectangle r)
+ {
+ return r.TopLeft >= this.TopLeft && r.BottomRight <= this.BottomRight ? true : false;
+ }
+ public bool Intersect(Rectangle r)
+ {
+ int maxLeft = Math.Max(this.Left, r.Left);
+ int minRight = Math.Min(this.Right, r.Right);
+ int maxTop = Math.Max(this.Top, r.Top);
+ int minBottom = Math.Min(this.Bottom, r.Bottom);
+
+ if (maxLeft < minRight && maxTop < minBottom)
+ return true;
+
+ return false;
+
+ }
+ public Rectangle Intersection(Rectangle r)
+ {
+ Rectangle result = new Rectangle();
+
+ if (r.Left >= this.Left)
+ result.Left = r.Left;
+ else
+ result.TopLeft = this.TopLeft;
+
+ if (r.Right >= this.Right)
+ result.Width = this.Right - result.Left;
+ else
+ result.Width = r.Right - result.Left;
+
+ if (r.Top >= this.Top)
+ result.Top = r.Top;
+ else
+ result.Top = this.Top;
+
+ if (r.Bottom >= this.Bottom)
+ result.Height = this.Bottom - result.Top;
+ else
+ result.Height = r.Bottom - result.Top;
+
+ return result;
+ }
+ public static implicit operator Rectangle(System.Drawing.Rectangle r)
+ {
+ return new Rectangle(r.X, r.Y, r.Width, r.Height);
+ }
+ public static implicit operator System.Drawing.Rectangle(Rectangle r)
+ {
+ return new System.Drawing.Rectangle(r.X, r.Y, r.Width, r.Height);
+ }
+ public static implicit operator Cairo.Rectangle(Rectangle r)
+ {
+ return new Cairo.Rectangle((double)r.X, (double)r.Y, (double)r.Width, (double)r.Height);
+ }
+ public static Rectangle operator +(Rectangle r1, Rectangle r2)
+ {
+ int x = Math.Min(r1.X, r2.X);
+ int y = Math.Min(r1.Y, r2.Y);
+ int x2 = Math.Max(r1.Right, r2.Right);
+ int y2 = Math.Max(r1.Bottom, r2.Bottom);
+ return new Rectangle(x, y, x2 - x, y2 - y);
+ }
+ public static bool operator ==(Rectangle r1, Rectangle r2)
+ {
+ return r1.TopLeft == r2.TopLeft && r1.Size == r2.Size ? true : false;
+ }
+ public static bool operator !=(Rectangle r1, Rectangle r2)
+ {
+ return r1.TopLeft == r2.TopLeft && r1.Size == r2.Size ? false : true;
+ }
+
+ public RectanglesRelations test(Rectangle r)
+ {
+ if (r == this)
+ return RectanglesRelations.Equal;
+
+ int nbrPtIncluded = 0;
+
+ if (this.Contains(r.TopLeft))
+ nbrPtIncluded++;
+ if (this.Contains(r.TopRight))
+ nbrPtIncluded++;
+ if (this.Contains(r.BottomLeft))
+ nbrPtIncluded++;
+ if (this.Contains(r.BottomRight))
+ nbrPtIncluded++;
+
+ switch (nbrPtIncluded)
+ {
+ case 0:
+ return RectanglesRelations.NoRelation;
+ case 4:
+ return RectanglesRelations.Contains;
+ default:
+ return RectanglesRelations.Intersect;
+ }
+ }
+ public Rectangle Clone
+ {
+ get
+ {
+ return new Rectangle(X, Y, Width, Height);
+ }
+ }
+ public static Rectangle Zero
+ {
+ get { return new Rectangle(0, 0, 0, 0); }
+ }
+ public static Rectangle Empty
+ {
+ get { return Zero; }
+ }
+ public override string ToString()
+ {
+ return string.Format("({0},{1},{2},{3})", X, Y, Width, Height);
+ }
+ }
+
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Cairo;
+using System.Diagnostics;
+
+namespace go
+{
+ public class Rectangles
+ {
+ public List<Rectangle> list = new List<Rectangle>();
+ public int count
+ {
+ get { return list.Count; }
+ }
+
+ public void AddRectangle(Rectangle r)
+ {
+ //if (r.Left == 0)
+ // Debugger.Break();
+ if (addRect(r))
+ list.Add(r);
+ }
+ public void Reset()
+ {
+ list = new List<Rectangle>();
+ }
+ bool addRect(Rectangle r)
+ {
+ foreach (Rectangle rInList in list)
+ if (rInList.Contains(r))
+ return false;
+ return true;
+ }
+
+ public bool intersect(Rectangle r)
+ {
+ foreach (Rectangle rInList in list)
+ if (rInList.Intersect(r))
+ return true;
+ return false;
+ }
+
+ public Rectangles intersectingRects(Rectangle r)
+ {
+ Rectangles tmp = new Rectangles();
+
+ foreach (Rectangle rInList in list)
+ if (rInList.Intersect(r))
+ tmp.list.Add(rInList.Clone);//on bypass le test déjà fait a l'ajout intial du rect dans la liste
+
+ return tmp;
+ }
+ public Rectangles SmallerContainedRects(Rectangle r)
+ {
+ Rectangles tmp = new Rectangles();
+
+ foreach (Rectangle rInList in list)
+ if (r.Contains(rInList) && rInList.Size < r.Size)
+ tmp.list.Add(rInList.Clone);
+
+ return tmp;
+ }
+ public Rectangles SmallerRects(Rectangle r)
+ {
+ Rectangles tmp = new Rectangles();
+
+ foreach (Rectangle rInList in list)
+ if (rInList.Size < r.Size)
+ tmp.list.Add(rInList.Clone);
+
+ return tmp;
+ }
+ public Rectangles containedRects(Rectangle r)
+ {
+ Rectangles tmp = new Rectangles();
+
+ foreach (Rectangle rInList in list)
+ if (r.Contains(rInList) && rInList.Size <= r.Size)
+ tmp.list.Add(rInList.Clone);
+
+ return tmp;
+ }
+ public void Rebase(GraphicObject w)
+ {
+ Rectangle r = w.renderBounds;
+ List<Rectangle> newList = new List<Rectangle>();
+
+ foreach (Rectangle rInList in list)
+ {
+ Rectangle rebasedR = rInList.Clone;
+ rebasedR.TopLeft-= r.TopLeft;
+
+ ScrollingWidget sw = w as ScrollingWidget;
+ if (sw != null)
+ {
+ if (sw.VerticalScrolling)
+ rebasedR.Top -= sw.scrollY;
+ if (sw.HorizontalScrolling)
+ rebasedR.Left -= sw.scrollX;
+ }
+ newList.Add(rebasedR);
+ }
+ list = newList;
+ }
+ public void clearAndClip(Context ctx)
+ {
+ //ctx.Save();
+
+ foreach (Rectangle r in list)
+ {
+ ctx.Rectangle(r);
+ }
+
+ ctx.ClipPreserve();
+ ctx.Operator = Operator.Clear;
+ ctx.Fill();
+ ctx.Operator = Operator.Over;
+ //ctx.Restore();
+ }
+ public void clip(Context ctx)
+ {
+ foreach (Rectangle r in list)
+ {
+ ctx.Rectangle(r);
+ }
+
+ ctx.Clip();
+ }
+ public void clear(Context ctx)
+ {
+ //ctx.Save();
+
+ foreach (Rectangle r in list)
+ {
+ ctx.Rectangle(r);
+ }
+ ctx.Operator = Operator.Clear;
+ ctx.Fill();
+ ctx.Operator = Operator.Over;
+ //ctx.Restore();
+ }
+ //public RectanglesRelations test(Rectangle r)
+ //{
+ // foreach (Rectangle rInList in list)
+ // {
+ // switch (rInList.test(r))
+ // {
+ // case RectanglesRelations.NoRelation:
+ // break;
+ // case RectanglesRelations.Intersect:
+ // break;
+ // case RectanglesRelations.Contains:
+ // break;
+ // case RectanglesRelations.Equal:
+ // break;
+ // default:
+ // break;
+ // }
+ // }
+ //}
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Drawing;
+using Cairo;
+
+namespace go
+{
+ public class ScrollingWidget : GraphicObject
+ {
+ public ScrollingWidget(int _width = 30, int _height = 30)
+ : base(new Rectangle(0, 0, _width, _height))
+ {
+
+ }
+
+ public ScrollingWidget()
+ : base()
+ {
+
+ }
+ public bool VerticalScrolling = false;
+ public bool HorizontalScrolling = false;
+
+ public int scrollX = 0;
+ public int scrollY = 0;
+
+
+ public override Rectangle ScreenCoordBounds
+ {
+ get
+ {
+ return Parent == null ? bounds :
+ new Rectangle(
+ Parent.ScreenCoordBounds.X + renderBounds.X + scrollX,
+ Parent.ScreenCoordBounds.Y + renderBounds.Y + scrollY,
+ renderBounds.Width,
+ renderBounds.Height);
+ }
+ }
+
+ public override Rectangle renderBoundsInContextCoordonate
+ {
+ get
+ {
+ //should be in go with cache, scrolling widget have no cache
+ if (cachingInProgress)
+ return new Rectangle(renderBounds.Size);
+ //if (Parent.isCached)
+ // return renderBounds.Clone;
+
+ Rectangle tmp = Parent.renderBoundsInContextCoordonate;
+
+ return new Rectangle(
+ tmp.X + renderBounds.X + scrollX,
+ tmp.Y + renderBounds.Y + scrollY,
+ renderBounds.Width,
+ renderBounds.Height);
+
+ }
+ }
+
+ public override Rectangle ClientBoundsInContextCoordonate
+ {
+ get
+ {
+ if (cachingInProgress)
+ return new Rectangle(
+ clientBounds.X,
+ clientBounds.Y,
+ clientBounds.Width,
+ clientBounds.Height);
+
+ //if (Parent is Panel && !(this is ScrollingWidget))
+ // return Parent.clientBounds;
+
+ Rectangle tmp = Parent.renderBoundsInContextCoordonate;
+
+ return new Rectangle(
+ tmp.X + renderBounds.X + clientBounds.X + scrollX,
+ tmp.Y + renderBounds.Y + clientBounds.Y + scrollY,
+ clientBounds.Width,
+ clientBounds.Height);
+ }
+ }
+ public override Rectangle renderBoundsInBackendSurfaceCoordonate
+ {
+ get
+ {
+ Rectangle tmp = Parent.renderBoundsInBackendSurfaceCoordonate;
+
+ return new Rectangle(
+ tmp.X + renderBounds.X + scrollX,
+ tmp.Y + renderBounds.Y + scrollY,
+ renderBounds.Width,
+ renderBounds.Height);
+ }
+ }
+
+ public override bool ProcessMousePosition(Point mousePos)
+ {
+ return base.ProcessMousePosition(mousePos);
+ }
+ public override void ProcessMouseWeel(int delta)
+ {
+ if (!isVisible)
+ return;
+
+
+ if (VerticalScrolling && renderBounds.Height > Parent.clientBounds.Height)
+ {
+ //add redraw call with old bounds to errase old position
+ registerForRedraw();
+
+ scrollY += delta;
+
+ if (scrollY > 0)
+ scrollY = 0;
+ else if (scrollY < -renderBounds.Height + Parent.clientBounds.Height)
+ scrollY = -renderBounds.Height + Parent.clientBounds.Height;
+
+ }
+ if (HorizontalScrolling && renderBounds.Width > Parent.clientBounds.Width)
+ {
+ //add redraw call with old bounds to errase old position
+ registerForRedraw();
+
+ scrollX += delta;
+ }
+
+
+ //renderBounds.Y = -scrollY;
+ registerForRedraw();
+ }
+
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace go
+{
+ public struct Size
+ {
+ public static Size Zero
+ { get { return new Size(0, 0); } }
+ int _width;
+ int _height;
+
+ //public Size()
+ //{ }
+ public Size(int width, int height)
+ {
+ _width = width;
+ _height = height;
+ }
+ public int Width
+ {
+ get { return _width; }
+ set { _width = value; }
+ }
+ public int Height
+ {
+ get { return _height; }
+ set { _height = value; }
+ }
+ public override string ToString()
+ {
+ return string.Format("({0},{1})", Width, Height);
+ }
+ public static implicit operator Size(int i)
+ {
+ return new Size(i, i);
+ }
+ public static bool operator ==(Size s1, Size s2)
+ {
+ if (s1.Width == s2.Width && s1.Height == s2.Height)
+ return true;
+ else
+ return false;
+ }
+ public static bool operator !=(Size s1, Size s2)
+ {
+ if (s1.Width == s2.Width && s1.Height == s2.Height)
+ return false;
+ else
+ return true;
+ }
+ public static bool operator >(Size s1, Size s2)
+ {
+ if (s1.Width > s2.Width && s1.Height > s2.Height)
+ return true;
+ else
+ return false;
+ }
+ public static bool operator >=(Size s1, Size s2)
+ {
+ if (s1.Width >= s2.Width && s1.Height >= s2.Height)
+ return true;
+ else
+ return false;
+ }
+ public static bool operator <(Size s1, Size s2)
+ {
+ if (s1.Width < s2.Width)
+ if (s1.Height <= s2.Height)
+ return true;
+ else
+ return false;
+ else if (s1.Width == s2.Width && s1.Height < s2.Height)
+ return true;
+
+ return false;
+ }
+ public static bool operator <=(Size s1, Size s2)
+ {
+ if (s1.Width <= s2.Width && s1.Height <= s2.Height)
+ return true;
+ else
+ return false;
+ }
+ public static bool operator ==(Size s, int i)
+ {
+ if (s.Width == i && s.Height == i)
+ return true;
+ else
+ return false;
+ }
+ public static bool operator !=(Size s, int i)
+ {
+ if (s.Width == i && s.Height == i)
+ return false;
+ else
+ return true;
+ }
+ public static Size operator +(Size s, int i)
+ {
+ return new Size(s.Width + i, s.Height + i);
+ }
+ }
+
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Cairo;
+
+namespace go
+{
+ public class Slider : GraphicObject
+ {
+ double _actualValue, _minValue, _maxValue, _smallStep, _bigStep, unity;
+ Rectangle cursor;
+ bool holdCursor = false;
+
+ public double value
+ {
+ get { return _actualValue; }
+ set
+ {
+ if (value < _minValue)
+ _actualValue = _minValue;
+ else if (value > _maxValue)
+ _actualValue = _maxValue;
+ else
+ _actualValue = value;
+
+ registerForGraphicUpdate();
+ }
+ }
+ public Slider(double minimum, double maximum, double step)
+ : base()
+ {
+ _minValue = minimum;
+ _maxValue = maximum;
+ _smallStep = step;
+ _bigStep = step * 5;
+ horizontalAlignment = HorizontalAlignment.None;
+ verticalAlignment = VerticalAlignment.None;
+ focusable = true;
+ }
+
+ void computeCursorPosition()
+ {
+ cursor = new Rectangle(new Size(4, 10));
+ Rectangle r = clientBounds;
+ PointD p1 = r.TopLeft + new Point(0, r.Height / 2);
+
+ unity = (double)r.Width / (_maxValue - _minValue);
+
+ cursor.TopLeft = new Point((int)(_actualValue * unity - cursor.Width / 2),
+ (int)(p1.Y - cursor.Height / 2));
+
+ }
+ public override void ProcessMouseDown(Point mousePos)
+ {
+ Interface.activeWidget = this;
+
+ base.ProcessMouseDown(mousePos);
+
+
+ Rectangle cursInScreenCoord = rectInScreenCoord(cursor);
+ if (cursInScreenCoord.Contains(mousePos))
+ {
+ holdCursor = true;
+ }
+ else if (mousePos.X < cursInScreenCoord.Left)
+ {
+ value -= _bigStep;
+ }
+ else
+ {
+ value += _bigStep;
+ }
+
+ }
+ public override void ProcessMouseUp(Point mousePos)
+ {
+ holdCursor = false;
+ base.ProcessMouseUp(mousePos);
+ }
+ public override bool ProcessMousePosition(Point mousePos)
+ {
+ return base.ProcessMousePosition(mousePos);
+ }
+ internal override void updateGraphic()
+ {
+ int stride = 4 * renderBounds.Width;
+
+
+ //init bmp with widget background and border
+ base.updateGraphic();
+ computeCursorPosition();
+
+ using (ImageSurface bitmap =
+ new ImageSurface(bmp, Format.Argb32, renderBounds.Width, renderBounds.Height, stride))
+ {
+ using (Context gr = new Context(bitmap))
+ {
+ gr.FontOptions.Antialias = Antialias.Subpixel;
+
+ gr.Color = foreground;
+
+ Rectangle r = clientBounds.Clone;
+ PointD p1 = r.TopLeft + new Point(0, r.Height / 2);
+ PointD p2 = r.TopRight + new Point(0, r.Height / 2);
+
+ gr.LineWidth = 1;
+ gr.MoveTo(p1);
+ gr.LineTo(p2);
+
+ gr.Stroke();
+ gr.LineWidth = 0.5;
+
+ double sst = unity * _smallStep;
+ double bst = unity * _bigStep;
+
+
+ PointD vBar = new PointD(0, sst);
+ for (double x = _minValue; x <= _maxValue - _minValue; x += _smallStep)
+ {
+ double lineLength = 2.5;
+ if (x % _bigStep == 0)
+ lineLength *= 2;
+ PointD p = new PointD(p1.X + x * unity, p1.Y);
+ gr.MoveTo(p);
+ gr.LineTo(new PointD(p.X, p.Y + lineLength));
+ }
+
+ gr.Stroke();
+
+
+ gr.Rectangle(cursor);
+ gr.Fill();
+
+
+ }
+
+ bitmap.Flush();
+ //bitmap.WriteToPng(@"d:\test.png");
+ }
+ }
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Drawing;
+using System.Diagnostics;
+
+namespace go
+{
+ public class Spinner : HorizontalStack
+ {
+ Label Label;
+ Button up;
+ Button down;
+
+ float _actualValue, _minValue, _maxValue, _increment;
+ WidgetEvent _onValueChange;
+
+
+ public float Value
+ {
+ get { return _actualValue; }
+ set
+ {
+ _actualValue = value;
+ Label.text = _actualValue.ToString();
+ }
+ }
+
+ public void Init(float _initialValue, float _min, float _max, float _step, WidgetEvent onValueChange, string _label = "")
+ {
+ sizeToContent = true;
+
+ if (!string.IsNullOrEmpty(_label))
+ {
+ Label = addChild(new Label(_label));
+ Label.verticalAlignment = go.VerticalAlignment.None;
+ Label.horizontalAlignment = go.HorizontalAlignment.None;
+
+ Label.width = 100;
+ Label.textAlignment = Alignment.LeftCenter;
+ }
+
+ Label = addChild(new TextBoxWidget(_initialValue.ToString()));
+ Label.borderColor = Color.LightGray;
+ Label.background = Color.DimWhite;
+ Label.fontColor = Color.Black;
+ Label.borderWidth = 1;
+ Label.width = 50;
+ Label.verticalAlignment = go.VerticalAlignment.None;
+ Label.horizontalAlignment = go.HorizontalAlignment.None;
+ Label.textAlignment = Alignment.RightCenter;
+
+
+
+ VerticalStack arrows = new VerticalStack();
+ arrows.widgetSpacing = 0;
+ arrows.horizontalAlignment = go.HorizontalAlignment.Center;
+ arrows.verticalAlignment = go.VerticalAlignment.Stretch;
+ arrows.width = 15;
+ arrows.borderWidth = 0;
+ arrows.sizeToContent = true;
+
+ up = arrows.addChild(new Button(directories.rootDir + @"Images/Icons/spin_up.png", spinUp, false, 15, 10));
+ up.borderWidth = 0;
+ up.margin = 0;
+
+ //up.alignment = Alignment.HorizontalStretch;
+
+
+ down = arrows.addChild(new Button(directories.rootDir + @"Images/Icons/spin_down.png", spinDown, false, 15, 10));
+ down.borderWidth = 0;
+ down.margin = 0;
+ //down.alignment = Alignment.HorizontalStretch;
+
+ addChild(arrows);
+
+ _actualValue = _initialValue;
+ _minValue = _min;
+ _maxValue = _max;
+ _increment = Math.Abs(_step);
+ _onValueChange = onValueChange;
+ }
+
+ public Spinner(float _initialValue, float _min, float _max, float _step, WidgetEvent onValueChange)
+ : base()
+ {
+ Init(_initialValue, _min, _max, _step, onValueChange);
+ }
+ public Spinner(string _label, float _initialValue, float _min, float _max, float _step, WidgetEvent onValueChange)
+ : base()
+ {
+ Init(_initialValue, _min, _max, _step, onValueChange,_label);
+ }
+ public void spinUp(Button sender)
+ {
+ _actualValue += _increment;
+ if (_actualValue > _maxValue)
+ _actualValue = _maxValue;
+
+ Label.text = _actualValue.ToString();
+
+ _onValueChange(this);
+ }
+ public void spinDown(Button sender)
+ {
+ _actualValue -= _increment;
+ if (_actualValue < _minValue)
+ _actualValue = _minValue;
+
+ Label.text = _actualValue.ToString();
+
+ _onValueChange(this);
+ }
+
+ public override void updateLayout()
+ {
+ base.updateLayout();
+ up.height = Label.renderBounds.Height / 2;
+ down.height = Label.renderBounds.Height / 2;
+ down.y = Label.renderBounds.Top + Label.renderBounds.Height / 2;
+ }
+
+ public override bool ProcessMousePosition(Point mousePos)
+ {
+ //if (base.ProcessMousePosition(mousePos))
+ // Debugger.Break();
+
+ return base.ProcessMousePosition(mousePos);
+ }
+ public override void cairoDraw(ref Cairo.Context ctx, Rectangles clip = null)
+ {
+ base.cairoDraw(ref ctx, clip);
+ }
+ }
+
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using OpenTK.Input;
+using Cairo;
+using System.Diagnostics;
+
+namespace go
+{
+ public class TextBoxWidget : Label
+ {
+ public TextBoxWidget(string _initialValue, WidgetEvent _onTextChanged = null)
+ : base(_initialValue)
+ {
+ onTextChanged = _onTextChanged;
+ focusable = true;
+ selColor = Color.SkyBlue;
+ selFontColor = Color.Black;
+ fontColor = Color.Black;
+ background = Color.White;
+ textAlignment = Alignment.LeftCenter;
+ }
+
+ //trigger update when lost focus to errase text beam
+ public override bool hasFocus
+ {
+ get
+ {
+ return base.hasFocus;
+ }
+ set
+ {
+ base.hasFocus = value;
+ registerForGraphicUpdate();
+ }
+ }
+ public WidgetEvent onTextChanged;
+
+ Color selColor;
+ Color selFontColor;
+
+ //mouse coord in widget space, filled only when clicked
+ Point mouseLocalPos;
+
+ //0 based cursor position in string
+ private int _currentPos;
+ public int currentPos
+ {
+ get { return _currentPos; }
+ set { _currentPos = value; }
+ }
+ public int selStartPos;
+ public int selEndPos;
+ //ordered selection start and end positions
+ public int selectionStart
+ {
+ get { return selEndPos < 0 ? selStartPos : Math.Min(selStartPos, selEndPos); }
+ }
+ public int selectionEnd
+ { get { return selEndPos < 0 ? selEndPos : Math.Max(selStartPos, selEndPos); } }
+
+
+ //cursor position in cairo units in widget client coord.
+ double textCursorPos;
+ double SelStartCursorPos = -1;
+ double SelEndCursorPos = -1;
+
+ bool SelectionInProgress = false;
+
+ public string selectedText
+ { get { return selectionEnd < 0 ? null : text.Substring(selectionStart, selectionEnd - selectionStart); } }
+ public bool selectionIsEmpty
+ { get { return string.IsNullOrEmpty(selectedText); } }
+
+ #region Keyboard handling
+ public override void ProcessKeyboard(Key key)
+ {
+ switch (key)
+ {
+ case Key.Back:
+ if (!selectionIsEmpty)
+ {
+ text = text.Remove(selectionStart, selectionEnd - selectionStart);
+ selEndPos = -1;
+ currentPos = selStartPos;
+ }
+ else if (currentPos > 0)
+ {
+ currentPos--;
+ text = text.Remove(currentPos, 1);
+ }
+ break;
+ case Key.Clear:
+ break;
+ case Key.Delete:
+ if (!selectionIsEmpty)
+ {
+ text = text.Remove(selectionStart, selectionEnd - selectionStart);
+ selEndPos = -1;
+ currentPos = selStartPos;
+ }
+ else if (currentPos < text.Length)
+ text = text.Remove(currentPos, 1);
+ break;
+ case Key.Down:
+ break;
+ case Key.End:
+ currentPos = text.Length;
+ break;
+ case Key.Enter:
+ case Key.KeypadEnter:
+ if (onTextChanged != null)
+ onTextChanged(this);
+ break;
+ case Key.Escape:
+ text = "";
+ currentPos = 0;
+ selEndPos = -1;
+ break;
+ case Key.Home:
+ currentPos = 0;
+ break;
+ case Key.Insert:
+ break;
+ case Key.Left:
+ if (currentPos > 0)
+ currentPos--;
+ break;
+ case Key.Menu:
+ break;
+ case Key.NumLock:
+ break;
+ case Key.PageDown:
+ break;
+ case Key.PageUp:
+ break;
+ case Key.RWin:
+ break;
+ case Key.Right:
+ if (currentPos < text.Length)
+ currentPos++;
+ break;
+ case Key.Tab:
+ text = text.Insert(currentPos, "\t");
+ currentPos++;
+ break;
+ case Key.Up:
+ break;
+ case Key.KeypadDecimal:
+ text = text.Insert(currentPos, new string(new char[] { Interface.decimalSeparator }));
+ currentPos++;
+ break;
+ case Key.Space:
+ text = text.Insert(currentPos, " ");
+ currentPos++;
+ break;
+ case Key.KeypadDivide:
+ case Key.Slash:
+ text = text.Insert(currentPos, "/");
+ currentPos++;
+ break;
+ case Key.KeypadMultiply:
+ text = text.Insert(currentPos, "*");
+ currentPos++;
+ break;
+ case Key.KeypadMinus:
+ case Key.Minus:
+ text = text.Insert(currentPos, "-");
+ currentPos++;
+ break;
+ case Key.KeypadPlus:
+ case Key.Plus:
+ text = text.Insert(currentPos, "+");
+ currentPos++;
+ break;
+ default:
+ if (!selectionIsEmpty)
+ {
+ text = text.Remove(selectionStart, selectionEnd - selectionStart);
+ currentPos = selStartPos;
+ }
+
+ string k = "?";
+ if ((char)key >= 67 && (char)key <= 76)
+ k = ((int)key - 67).ToString();
+ else if ((char)key >= 109 && (char)key <= 118)
+ k = ((int)key - 109).ToString();
+ else if (Interface.capitalOn)
+ k = key.ToString();
+ else
+ k = key.ToString().ToLower();
+
+ text = text.Insert(currentPos, k);
+ currentPos++;
+
+ selEndPos = -1;
+ selStartPos = currentPos;
+
+ break;
+ }
+ registerForGraphicUpdate();
+
+ }
+ #endregion
+
+ #region Mouse handling
+ public override bool ProcessMousePosition(Point mousePos)
+ {
+ Rectangle scb = ScreenCoordBounds;
+
+ if (scb.Contains(mousePos))
+ {
+ Interface.hoverWidget = this;
+
+ //Interface.SetCursor(System.Windows.Forms.Cursors.IBeam.Handle);
+
+ if (Interface.Mouse[MouseButton.Left])
+ {
+ SelectionInProgress = true;
+ Debug.WriteLine("selection in progress");
+ mouseLocalPos = mousePos - ScreenCoordBounds.TopLeft - rText.TopLeft;
+ registerForGraphicUpdate();
+ }
+
+ return true;
+ }
+ else
+ {
+ Interface.hoverWidget = null;
+ return false;
+ }
+ }
+ public override void ProcessMouseDown(Point mousePos)
+ {
+ Interface.activeWidget = this;
+
+ if (!this.hasFocus)
+ {
+ selStartPos = 0;
+ selEndPos = text.Length;
+ }
+ else
+ {
+ mouseLocalPos = mousePos - ScreenCoordBounds.TopLeft - rText.TopLeft;
+ selStartPos = -1;
+ selEndPos = -1;
+ }
+ base.ProcessMouseDown(mousePos);
+
+ registerForGraphicUpdate();
+ }
+ public override void ProcessMouseUp(Point mousePos)
+ {
+ SelectionInProgress = false;
+ }
+ #endregion
+
+ void computeTextCursor(Context gr)
+ {
+ FontExtents fe = gr.FontExtents;
+ TextExtents te;
+
+ double cPos = 0f;
+ for (int i = 0; i < _text.Length; i++)
+ {
+#if _WIN32 || _WIN64
+ byte[] c = System.Text.UTF8Encoding.UTF8.GetBytes(text.Substring(i, 1));
+ te = gr.TextExtents(c);
+#elif __linux__
+ te = gr.TextExtents(text.Substring(i, 1));
+#endif
+ double halfWidth = te.XAdvance / 2;
+
+ if (mouseLocalPos.X <= cPos + halfWidth)
+ {
+ currentPos = i;
+ textCursorPos = cPos;
+ mouseLocalPos = -1;
+ return;
+ }
+
+ cPos += te.XAdvance;
+ }
+ currentPos = _text.Length;
+ textCursorPos = cPos;
+
+ //reset mouseLocalPos
+ mouseLocalPos = -1;
+ }
+ void computeTextCursorPosition(Context gr)
+ {
+ FontExtents fe = gr.FontExtents;
+ TextExtents te;
+
+ double cPos = 0f;
+
+ int limit = currentPos;
+
+ if (selectionEnd > 0)
+ limit = Math.Max(currentPos, selectionEnd);
+
+ for (int i = 0; i <= limit; i++)
+ {
+ if (i == currentPos)
+ textCursorPos = cPos;
+ if (i == selectionStart)
+ SelStartCursorPos = cPos;
+ if (i == selectionEnd)
+ SelEndCursorPos = cPos;
+
+ if (i < text.Length)
+ {
+#if _WIN32 || _WIN64
+ byte[] c = System.Text.UTF8Encoding.UTF8.GetBytes(text.Substring(i, 1));
+ te = gr.TextExtents(c);
+#elif __linux__
+ te = gr.TextExtents(text.Substring(i,1));
+#endif
+ cPos += te.XAdvance;
+ }
+ }
+
+ }
+
+ internal override void updateGraphic()
+ {
+ byte[] txt = utf8Text;
+ int stride = 4 * renderBounds.Width;
+
+
+ //init bmp with widget background and border
+ base.updateGraphic();
+
+ using (ImageSurface bitmap =
+ new ImageSurface(bmp, Format.Argb32, renderBounds.Width, renderBounds.Height, stride))
+ {
+ using (Context gr = new Context(bitmap))
+ {
+ gr.FontOptions.Antialias = Antialias.Subpixel;
+ gr.FontOptions.HintMetrics = HintMetrics.On;
+ gr.SetFontSize(fontSize);
+ FontExtents fe = gr.FontExtents;
+ rText = new Rectangle(new Point(0, 0), measureRawSize());
+ //gr.Rotate(Math.PI);
+
+ // double a = Math.PI;
+ //gr.Transform(new c.Matrix(Math.Cos(a),-Math.Sin(a),Math.Sin(a),Math.Cos(a),renderBounds.Width,renderBounds.Height));
+ gr.Antialias = Antialias.Subpixel;
+ gr.LineWidth = borderWidth;
+
+ float widthRatio = 1f;
+ float heightRatio = 1f;
+
+ Rectangle cb = clientBounds;
+ Interface.StrokeLoweredRectangle(gr, cb, 1);
+ //ignore text alignment if size to content = true
+ if (!sizeToContent)
+ {
+ switch (textAlignment)
+ {
+ case Alignment.None:
+ break;
+ case Alignment.TopLeft: //ok
+ rText.X = cb.X;
+ rText.Y = cb.Y;
+ break;
+ case Alignment.TopCenter: //ok
+ rText.Y = cb.Y;
+ rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
+ break;
+ case Alignment.TopRight: //ok
+ rText.X = cb.Right - rText.Width;
+ rText.Y = cb.Y;
+ break;
+ case Alignment.TopStretch://ok
+ heightRatio = widthRatio = (float)cb.Width / rText.Width;
+ rText.X = cb.X;
+ rText.Y = cb.Y;
+ rText.Width = cb.Width;
+ rText.Height = (int)(rText.Height * heightRatio);
+ break;
+ case Alignment.LeftCenter://ok
+ rText.X = cb.X;
+ rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+ break;
+ case Alignment.LeftStretch://ok
+ heightRatio = widthRatio = (float)cb.Height / rText.Height;
+ rText.X = cb.X;
+ rText.Y = cb.Y;
+ rText.Height = cb.Height;
+ rText.Width = (int)(widthRatio * cb.Width);
+ break;
+ case Alignment.RightCenter://ok
+ rText.X = cb.X + cb.Width - rText.Width;
+ rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+ break;
+ case Alignment.RightStretch://ok
+ heightRatio = widthRatio = (float)cb.Height / rText.Height;
+ rText.Height = cb.Height;
+ rText.Width = (int)(widthRatio * cb.Width);
+ rText.X = cb.X;
+ rText.Y = cb.Y;
+ break;
+ case Alignment.BottomCenter://ok
+ rText.X = cb.Width / 2 - rText.Width / 2;
+ rText.Y = cb.Height - rText.Height;
+ break;
+ case Alignment.BottomStretch://ok
+ heightRatio = widthRatio = (float)cb.Width / rText.Width;
+ rText.Width = cb.Width;
+ rText.Height = (int)(rText.Height * heightRatio);
+ rText.Y = cb.Bottom - rText.Height;
+ rText.X = cb.X;
+ break;
+ case Alignment.BottomLeft://ok
+ rText.X = cb.X;
+ rText.Y = cb.Bottom - rText.Height;
+ break;
+ case Alignment.BottomRight://ok
+ rText.Y = cb.Bottom - rText.Height;
+ rText.X = cb.Right - rText.Width;
+ break;
+ case Alignment.Center://ok
+ rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
+ rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+ break;
+ case Alignment.Fit://ok, peut être mieu aligné
+ widthRatio = (float)cb.Width / rText.Width;
+ heightRatio = (float)cb.Height / rText.Height;
+ rText = cb.Clone;
+ break;
+ case Alignment.HorizontalStretch://ok
+ heightRatio = widthRatio = (float)cb.Width / rText.Width;
+ rText.Width = cb.Width;
+ rText.Height = (int)(heightRatio * rText.Height);
+ rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+ rText.X = cb.X;
+ break;
+ case Alignment.VerticalStretch://ok
+ heightRatio = widthRatio = (float)cb.Height / rText.Height;
+ rText.Height = cb.Height;
+ rText.Width = (int)(widthRatio * rText.Width);
+ rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
+ rText.Y = cb.Y;
+ break;
+ default:
+ break;
+ }
+ }
+
+
+
+ gr.FontMatrix = new Matrix(widthRatio * fontSize, 0, 0, heightRatio * fontSize, 0, 0);
+
+ fe = gr.FontExtents;
+
+ #region draw text cursor
+ if (mouseLocalPos > 0)
+ {
+ computeTextCursor(gr);
+
+ if (SelectionInProgress)
+ {
+ selEndPos = currentPos;
+ SelEndCursorPos = textCursorPos;
+ }
+ else if (selStartPos < 0)
+ {
+ selStartPos = currentPos;
+ SelStartCursorPos = textCursorPos;
+ selEndPos = -1;
+ }
+ else
+ computeTextCursorPosition(gr);
+
+ }
+ else
+ computeTextCursorPosition(gr);
+ if (hasFocus)
+ {
+ gr.LineWidth = 1;
+ gr.MoveTo(new PointD(textCursorPos + rText.TopLeft.X, rText.Y + rText.TopLeft.Y));
+ gr.LineTo(new PointD(textCursorPos + rText.TopLeft.X, rText.Y + fe.Height + rText.TopLeft.Y));
+ gr.Stroke();
+ }
+
+ #endregion
+
+ if (selEndPos >= 0)
+ {
+ gr.Color = selColor;
+ Rectangle selRect =
+ new Rectangle((int)SelStartCursorPos + rText.TopLeft.X, (int)(rText.Y) + rText.TopLeft.Y, (int)(SelEndCursorPos - SelStartCursorPos), (int)fe.Height);
+ gr.Rectangle(selRect);
+ gr.Fill();
+
+ gr.Color = selFontColor;
+ }
+ else
+ gr.Color = fontColor;
+
+ gr.MoveTo(rText.X, rText.Y + fe.Ascent);
+#if _WIN32 || _WIN64
+ gr.ShowText(txt);
+#elif __linux__
+ gr.ShowText(text);
+#endif
+ gr.Fill();
+
+
+
+
+ //gr.LineWidth = 1;
+ //gr.MoveTo(new PointD(rText.TopLeft.X, rText.Y));
+ //gr.LineTo(new PointD(rText.TopLeft.X, rText.Y + fe.Ascent));
+ //gr.Stroke();
+
+ }
+ bitmap.Flush();
+ //bitmap.WriteToPng(directories.rootDir + @"test.png");
+ }
+
+ //registerForRedraw();
+ }
+
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace go
+{
+ public class VerticalStack : GenericStack
+ {
+ public VerticalStack()
+ : base()
+ {
+ Orientation = go.Orientation.Vertical;
+ }
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Cairo;
+
+namespace go
+{
+ public class VerticalWrappingWidget : WrappedWidgetGroup
+ {
+ public VerticalWrappingWidget(int _borderWidth = 0) :
+ base()
+ {
+ Orientation = Orientation.Vertical;
+ borderWidth = _borderWidth;
+ sizeToContent = true;
+ background = Color.Transparent;
+ }
+ public VerticalWrappingWidget(Color _borderColor, int _borderWidth = 1) :
+ base()
+ {
+ Orientation = Orientation.Vertical;
+ borderWidth = _borderWidth;
+ borderColor = _borderColor;
+ background = Color.Transparent;
+ sizeToContent = true;
+ }
+ public VerticalWrappingWidget(Color _borderColor, Color _background, int _borderWidth = 1) :
+ base()
+ {
+ Orientation = Orientation.Vertical;
+ borderWidth = _borderWidth;
+ borderColor = _borderColor;
+ background = _background;
+ sizeToContent = true;
+ }
+
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Runtime.InteropServices;
+
+namespace go
+{
+ public static class Win32
+ {
+ [DllImport("user32.dll")]
+ public static extern IntPtr GetDC(IntPtr hWnd);
+ #region mouse winApi
+
+ [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
+ public struct Point
+ {
+
+ /// LONG->int
+ public int x;
+
+ /// LONG->int
+ public int y;
+ }
+ [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
+ public struct HICON__
+ {
+
+ /// int
+ public int unused;
+ }
+
+#if _WIN32 || _WIN64
+ /// Return Type: HCURSOR->HICON->HICON__*
+ ///hCursor: HCURSOR->HICON->HICON__*
+ [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "SetCursor")]
+ public static extern System.IntPtr SetCursor([System.Runtime.InteropServices.InAttribute()] System.IntPtr hCursor);
+#elif __linux__
+ public static System.IntPtr SetCursor(System.IntPtr hCursor)
+ {
+ return (IntPtr)0;
+ }
+#endif
+
+ /// Return Type: BOOL->int
+ ///lpPoint: LPPOINT->tagPOINT*
+ [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "GetCursorPos")]
+ [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
+ public static extern bool GetCursorPos([System.Runtime.InteropServices.OutAttribute()] out Point lpPoint);
+
+ /// Return Type: BOOL->int
+ ///X: int
+ ///Y: int
+ [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "SetCursorPos")]
+ [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
+ public static extern bool SetCursorPos(int X, int Y);
+
+ #endregion
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Drawing;
+using OpenTK.Graphics.OpenGL;
+using System.Diagnostics;
+
+namespace go
+{
+ public class WrappedWidgetGroup : Group
+ {
+
+ public int widgetSpacing = 2;
+
+ public Orientation Orientation = Orientation.Horizontal;
+
+
+ public WrappedWidgetGroup()
+ : base()
+ {
+ borderWidth = 0;
+ }
+
+ int currentXForWidget = 0;
+ int currentYForWidget = 0;
+
+ int highestWidget = 0;
+ int largestWidget = 0;
+
+
+ public override void updateLayout()
+ {
+ //while (!layoutIsValid)
+ //{
+ //if (!(sizeIsValid && positionIsValid))
+ base.updateLayout();
+
+ //if (!base.layoutIsValid)
+ // return;
+
+ currentXForWidget = clientBounds.X;
+ currentYForWidget = clientBounds.Y;
+
+ highestWidget = 0;
+ largestWidget = 0;
+
+ Rectangle contentBounds = Rectangle.Zero;
+
+ GraphicObject[] widgets = new GraphicObject[Children.Count];
+ Children.CopyTo(widgets);
+ foreach (GraphicObject w in widgets)
+ {
+ if (w.renderBounds.Width > largestWidget)
+ largestWidget = w.renderBounds.Width;
+ if (w.renderBounds.Height > highestWidget)
+ highestWidget = w.renderBounds.Height;
+
+ if (!enoughtSpaceForWidget(w))
+ advance(w);
+
+ if (enoughtSpaceForWidget(w))
+ {
+ w.renderBounds.X = currentXForWidget;
+ w.renderBounds.Y = currentYForWidget;
+
+ w.positionIsValid = true;
+
+ contentBounds += w.renderBounds;
+
+ advance(w);
+ }
+ else
+ break;
+ }
+
+ contentBounds.Width += borderWidth + margin;
+ contentBounds.Height += borderWidth + margin;
+
+ if (sizeToContent)
+ renderBounds.Size = contentBounds.Size;
+ else if (VerticalScrolling)
+ renderBounds.Size = new Size(renderBounds.Size.Width, contentBounds.Size.Height);
+ else if (HorizontalScrolling)
+ renderBounds.Size = new Size(contentBounds.Size.Width, renderBounds.Size.Height);
+
+ if (layoutIsValid)
+ registerForRedraw();
+ }
+
+
+ bool enoughtSpaceForWidget(GraphicObject w)
+ {
+ int nextXForWidget = 0;
+ int nextYForWidget = 0;
+
+ if (Orientation == Orientation.Horizontal)
+ nextXForWidget = currentXForWidget + w.renderBounds.Width;
+ else
+ nextYForWidget = nextYForWidget + w.renderBounds.Height;
+
+ if (!sizeToContent)
+ {
+ if (nextXForWidget > clientBounds.Right && !HorizontalScrolling)
+ return false;
+ if (currentYForWidget > clientBounds.Bottom && !VerticalScrolling)
+ return false;
+ }
+ return true;
+ }
+ void advance(GraphicObject w)
+ {
+ if (Orientation == Orientation.Horizontal)
+ {
+ //if (w is LabelWidget)
+ // Debugger.Break();
+ currentXForWidget = currentXForWidget + widgetSpacing + w.renderBounds.Width;
+ }
+ else
+ currentYForWidget = currentYForWidget + widgetSpacing + w.renderBounds.Height;
+
+ if (!sizeToContent)
+ {
+ if (currentXForWidget > clientBounds.Right && !HorizontalScrolling)
+ {
+ if (Orientation == Orientation.Vertical)
+ {
+ //not scrolling
+ }
+ else
+ {
+ currentXForWidget = clientBounds.X;
+ currentYForWidget += widgetSpacing + highestWidget;
+ highestWidget = 0;
+ }
+ }
+ if (currentYForWidget > clientBounds.Bottom && !VerticalScrolling)
+ {
+ if (Orientation == Orientation.Horizontal)
+ {
+ //not scrolling
+ }
+ else
+ {
+ currentXForWidget += widgetSpacing + largestWidget;
+ currentYForWidget = clientBounds.Y;
+ largestWidget = 0;
+ }
+
+ }
+ }
+ }
+ }
+}
--- /dev/null
+using System;
+
+namespace go
+{
+ public static class directories
+ {
+#if _WIN32 || _WIN64
+ public const string rootDir = @"d:/";
+#elif __linux__
+ public const string rootDir = @"/mnt/data/";
+#endif
+
+ }
+}
+
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace go
+{
+ public enum Orientation
+ {
+ Horizontal,
+ Vertical
+ }
+ public enum Alignment
+ {
+ None,
+ TopCenter,
+ TopStretch,
+ LeftCenter,
+ LeftStretch,
+ RightCenter,
+ RightStretch,
+ BottomCenter,
+ BottomStretch,
+ TopLeft,
+ TopRight,
+ BottomLeft,
+ BottomRight,
+ Center,
+ Fit,
+ HorizontalStretch,
+ VerticalStretch
+ }
+
+ public enum PanelBorderPosition
+ {
+ Top,
+ Left,
+ Right,
+ Bottom,
+ TopLeft,
+ TopRight,
+ BottomLeft,
+ BottomRight,
+ Moving,
+ Closing,
+ ClientArea
+ }
+ public enum HorizontalAlignment
+ {
+ Stretch,
+ Left,
+ Right,
+ Center,
+ None
+ }
+ public enum VerticalAlignment
+ {
+ Stretch,
+ Top,
+ Bottom,
+ Center,
+ None
+ }
+
+ public enum RectanglesRelations
+ {
+ NoRelation, //nothing to do
+ Intersect, //clipped clear & repaint, no test
+ Contains, //clipped clear & repaint, test children
+ Equal //repaint, no test
+ }
+}