<Compile Include="src\rsvg\Pixbuf.cs" />
<Compile Include="src\rsvg\RsvgSharp.SizeFuncNative.cs" />
<Compile Include="src\rsvg\SizeFunc.cs" />
+ <Compile Include="src\MouseCursorChangedEventArgs.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
namespace Crow
{
- public class OpenTKGameWindow : Gtk.Window, ILayoutable, IGOLibHost
+ public class OpenTKGameWindow : Gtk.Window
{
+ public Interface CrowInterface;
+
+
#region ctor
public OpenTKGameWindow(int _width, int _height, string _title="Crow")
: base(Gtk.WindowType.Toplevel)
{
- currentWindow = this;
+ CrowInterface = new Interface ();
+ CrowInterface.Quit += Quit;
+
Decorated = false;
this.AddEvents ((int)Gdk.EventMask.PointerMotionMask);
this.Drawn += Win_Drawn;
this.OverrideBackgroundColor (Gtk.StateFlags.Normal, Gdk.RGBA.Zero);
this.Visual = Gdk.Global.DefaultRootWindow.Screen.RgbaVisual;
- // this.AcceptFocus = false;
- // this.CanFocus = false;
this.ButtonPressEvent += OpenTKGameWindow_ButtonPressEvent;
this.ButtonReleaseEvent += OpenTKGameWindow_ButtonReleaseEvent;
this.MotionNotifyEvent += OpenTKGameWindow_MotionNotifyEvent;
this.KeyPressEvent += OpenTKGameWindow_KeyPressEvent;
-
this.SizeAllocated += OpenTKGameWindow_SizeAllocated;
this.Show ();
this.Maximize ();
- OnLoad (null);
GLib.Idle.Add (new GLib.IdleHandler (idleHandler));
GLib.Timeout.Add (10, new GLib.TimeoutHandler (updateHandler));
interval.Start ();
}
+ #endregion
+
+
+ #region Timers
Stopwatch interval = new Stopwatch();
bool updateHandler(){
- update();
+ CrowInterface.Update();
return true;
}
bool idleHandler(){
- if (isDirty && interval.ElapsedMilliseconds > 1) {
+ if (CrowInterface.IsDirty && interval.ElapsedMilliseconds > 1) {
Debug.WriteLine (interval.ElapsedTicks.ToString ());
- QueueDrawArea (DirtyRect.X, DirtyRect.Y, DirtyRect.Width, DirtyRect.Height);
+ QueueDrawArea (CrowInterface.DirtyRect.X, CrowInterface.DirtyRect.Y, CrowInterface.DirtyRect.Width, CrowInterface.DirtyRect.Height);
interval.Restart ();
}
return true;
}
#endregion
+<<<<<<< 70bcdc77ff42c74fcd8e6e7dffd4eb6b16f24f39
public List<GraphicObject> GraphicObjects = new List<GraphicObject>();
public Color Background = Color.Transparent;
Surface surf;
byte[] bmp;
+=======
+ protected void Quit (object sender, EventArgs e)
+ {
+ Gtk.Application.Quit ();
+ }
+>>>>>>> CrowInterface object holding common functions, IGOLibHost removed
void Win_Drawn (object o, Gtk.DrawnArgs args)
{
- if (isDirty) {
- byte[] tmp = new byte[4 * DirtyRect.Width * DirtyRect.Height];
- for (int y = 0; y < DirtyRect.Height; y++) {
- Array.Copy(bmp,
- ((DirtyRect.Top + y) * ClientRectangle.Width * 4) + DirtyRect.Left * 4,
- tmp, y * DirtyRect.Width * 4, DirtyRect.Width *4);
+ if (CrowInterface.IsDirty) {
+ byte[] tmp = new byte[4 * CrowInterface.DirtyRect.Width * CrowInterface.DirtyRect.Height];
+ for (int y = 0; y < CrowInterface.DirtyRect.Height; y++) {
+ Array.Copy(CrowInterface.bmp,
+ ((CrowInterface.DirtyRect.Top + y) * CrowInterface.ClientRectangle.Width * 4) + CrowInterface.DirtyRect.Left * 4,
+ tmp, y * CrowInterface.DirtyRect.Width * 4, CrowInterface.DirtyRect.Width *4);
}
- using (ImageSurface img = new ImageSurface (tmp, Format.Argb32, DirtyRect.Width, DirtyRect.Height, 4 * DirtyRect.Width)) {
- args.Cr.SetSourceSurface (img, DirtyRect.X, DirtyRect.Y);
+ using (ImageSurface img = new ImageSurface (tmp, Format.Argb32, CrowInterface.DirtyRect.Width, CrowInterface.DirtyRect.Height, 4 * CrowInterface.DirtyRect.Width)) {
+ args.Cr.SetSourceSurface (img, CrowInterface.DirtyRect.X, CrowInterface.DirtyRect.Y);
args.Cr.Paint();
}
- isDirty = false;
+ CrowInterface.IsDirty = false;
return;
}
- if (bmp == null)
+ if (CrowInterface.bmp == null)
return;
- using (ImageSurface img = new ImageSurface (bmp, Format.Argb32, ClientRectangle.Width, ClientRectangle.Height, 4 * ClientRectangle.Width)) {
- args.Cr.SetSourceSurface (img, ClientRectangle.X, ClientRectangle.Y);
+ using (ImageSurface img = new ImageSurface (CrowInterface.bmp, Format.Argb32, CrowInterface.ClientRectangle.Width, CrowInterface.ClientRectangle.Height, 4 * CrowInterface.ClientRectangle.Width)) {
+ args.Cr.SetSourceSurface (img, CrowInterface.ClientRectangle.X, CrowInterface.ClientRectangle.Y);
args.Cr.Paint();
}
}
-
void Win_DeleteEvent (object o, Gtk.DeleteEventArgs args)
{
Gtk.Application.Quit ();
}
-
-
void OpenTKGameWindow_SizeAllocated (object o, Gtk.SizeAllocatedArgs args)
{
- int stride = 4 * ClientRectangle.Width;
- int bmpSize = Math.Abs (stride) * ClientRectangle.Height;
- bmp = new byte[bmpSize];
-
- foreach (GraphicObject g in GraphicObjects)
- g.RegisterForLayouting (LayoutingType.All);
-
- //_redrawClip.AddRectangle (ClientRectangle);
- }
- #endregion
-
- protected virtual void OnLoad (EventArgs e){
- Interface.LoadCursors ();
- }
-
- #if MEASURE_TIME
- public Stopwatch updateTime = new Stopwatch ();
- public Stopwatch layoutTime = new Stopwatch ();
- public Stopwatch guTime = new Stopwatch ();
- public Stopwatch drawingTime = new Stopwatch ();
- #endif
-
- bool isDirty = false;
- Rectangle DirtyRect;
-
- #region update
- void update ()
- {
- if (mouseRepeatCount > 0) {
- int mc = mouseRepeatCount;
- mouseRepeatCount -= mc;
- for (int i = 0; i < mc; i++) {
- //FocusedWidget.onMouseClick (this, new MouseButtonEventArgs (Mouse.X, Mouse.Y, MouseButton.Left, true));
- }
- }
- #if MEASURE_TIME
- layoutTime.Reset ();
- guTime.Reset ();
- drawingTime.Reset ();
- updateTime.Restart ();
- #endif
-
- #if MEASURE_TIME
- layoutTime.Start ();
- #endif
- //Debug.WriteLine ("======= Layouting queue start =======");
-
- while (Interface.LayoutingQueue.Count > 0) {
- LayoutingQueueItem lqi = Interface.LayoutingQueue.Dequeue ();
- lqi.ProcessLayouting ();
- }
-
- #if MEASURE_TIME
- layoutTime.Stop ();
- #endif
-
- //Debug.WriteLine ("otd:" + gobjsToRedraw.Count.ToString () + "-");
- //final redraw clips should be added only when layout is completed among parents,
- //that's why it take place in a second pass
- GraphicObject[] gotr = new GraphicObject[gobjsToRedraw.Count];
- gobjsToRedraw.CopyTo (gotr);
- gobjsToRedraw.Clear ();
- foreach (GraphicObject p in gotr) {
- p.IsQueuedForRedraw = false;
- p.Parent.RegisterClip (p.LastPaintedSlot);
- p.Parent.RegisterClip (p.getSlot());
- }
-
- #if MEASURE_TIME
- updateTime.Stop ();
- drawingTime.Start ();
- #endif
-
- using (surf = new ImageSurface (bmp, Format.Argb32, ClientRectangle.Width, ClientRectangle.Height, ClientRectangle.Width * 4)) {
- using (ctx = new Context (surf)){
-
-
- if (clipping.count > 0) {
- //Link.draw (ctx);
- clipping.clearAndClip(ctx);
-
- GraphicObject[] invGOList = new GraphicObject[GraphicObjects.Count];
- GraphicObjects.CopyTo (invGOList, 0);
- invGOList = invGOList.Reverse ().ToArray ();
-
- foreach (GraphicObject p in invGOList) {
- if (!p.Visible)
- continue;
- if (!clipping.intersect (p.Slot))
- continue;
- ctx.Save ();
-
- p.Paint (ref ctx);
-
- ctx.Restore ();
- }
-
- #if DEBUG_CLIP_RECTANGLE
- clipping.stroke (ctx, Color.Red.AdjustAlpha(0.5));
- #endif
-
- if (isDirty)
- DirtyRect += clipping.Bounds;
- else
- DirtyRect = clipping.Bounds;
- isDirty = true;
-
- DirtyRect.Left = Math.Max (0, DirtyRect.Left);
- DirtyRect.Top = Math.Max (0, DirtyRect.Top);
- DirtyRect.Width = Math.Min (ClientRectangle.Width - DirtyRect.Left, DirtyRect.Width);
- DirtyRect.Height = Math.Min (ClientRectangle.Height - DirtyRect.Top, DirtyRect.Height);
-
- clipping.Reset ();
- }
-
- #if MEASURE_TIME
- drawingTime.Stop ();
- #endif
- //surf.WriteToPng (@"/mnt/data/test.png");
- }
- }
-// if (ToolTip.isVisible) {
-// ToolTip.panel.processkLayouting();
-// if (ToolTip.panel.layoutIsValid)
-// ToolTip.panel.Paint(ref ctx);
-// }
-// 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);
-
-// Debug.WriteLine("UPDATE: {0} ticks \t, {1} ms",
-// updateTime.ElapsedTicks,
-// updateTime.ElapsedMilliseconds);
- }
- #endregion
-
- #region loading
- public GraphicObject LoadInterface (string path)
- {
- GraphicObject tmp = Interface.Load (path, this);
- AddWidget (tmp);
- return tmp;
- }
- #endregion
-
-
- MouseState mouse;
- KeyboardState Keyboard;
-
+ CrowInterface.ProcessResize (new Rectangle (args.Allocation.X, args.Allocation.Y, args.Allocation.Width, args.Allocation.Height));
+ }
void OpenTKGameWindow_MotionNotifyEvent (object o, Gtk.MotionNotifyEventArgs args)
{
- int deltaX = (int)args.Event.X - mouse.X;
- int deltaY = (int)args.Event.Y - mouse.Y;
- MouseMoveEventArgs e = new MouseMoveEventArgs ((int)args.Event.X, (int)args.Event.Y, deltaX, deltaY);
- mouse.X = (int)args.Event.X;
- mouse.Y = (int)args.Event.Y;
- e.Mouse = mouse;
-
- if (_activeWidget != null) {
- //first, ensure object is still in the graphic tree
- if (_activeWidget.HostContainer == null) {
- activeWidget = null;
- } else {
-
- //send move evt even if mouse move outside bounds
- _activeWidget.onMouseMove (this, e);
- return;
- }
- }
-
- if (hoverWidget != null) {
- //first, ensure object is still in the graphic tree
- if (hoverWidget.HostContainer == null) {
- hoverWidget = null;
- } else {
- //check topmost graphicobject first
- GraphicObject tmp = hoverWidget;
- GraphicObject topc = null;
- while (tmp is GraphicObject) {
- topc = tmp;
- tmp = tmp.Parent as GraphicObject;
- }
- int idxhw = GraphicObjects.IndexOf (topc);
- if (idxhw != 0) {
- int i = 0;
- while (i < idxhw) {
- if (GraphicObjects [i].MouseIsIn (e.Position)) {
- hoverWidget.onMouseLeave (this, e);
- GraphicObjects [i].checkHoverWidget (e);
- return;
- }
- i++;
- }
- }
-
-
- if (hoverWidget.MouseIsIn (e.Position)) {
- hoverWidget.checkHoverWidget (e);
- return;
- } else {
- hoverWidget.onMouseLeave (this, e);
- //seek upward from last focused graph obj's
- while (hoverWidget.Parent as GraphicObject != null) {
- hoverWidget = hoverWidget.Parent as GraphicObject;
- if (hoverWidget.MouseIsIn (e.Position)) {
- hoverWidget.checkHoverWidget (e);
- return;
- } else
- hoverWidget.onMouseLeave (this, e);
- }
- }
- }
- }
-
- //top level graphic obj's parsing
- for (int i = 0; i < GraphicObjects.Count; i++) {
- GraphicObject g = GraphicObjects[i];
- if (g.MouseIsIn (e.Position)) {
- g.checkHoverWidget (e);
- PutOnTop (g);
- return;
- }
- }
- hoverWidget = null;
- //MouseMove.Raise (this, otk_e);
- }
+ CrowInterface.ProcessMouseMove ((int)args.Event.X, (int)args.Event.Y);
+ }
void OpenTKGameWindow_ButtonReleaseEvent (object o, Gtk.ButtonReleaseEventArgs args)
{
- MouseButtonEventArgs e = new MouseButtonEventArgs ((int)args.Event.X, (int)args.Event.Y, (Crow.MouseButton)args.Event.Button-1, false);
- mouse.DisableBit ((int)args.Event.Button-1);
- e.Mouse = mouse;
-
- if (_activeWidget == null) {
- //MouseButtonUp.Raise (this, otk_e);
- return;
- }
-
- if (mouseRepeatThread != null) {
- mouseRepeatOn = false;
- mouseRepeatThread.Abort();
- mouseRepeatThread.Join ();
- }
-
- _activeWidget.onMouseUp (this, e);
- activeWidget = null;
+ CrowInterface.ProcessMouseButtonUp ((int)args.Event.Button - 1);
}
void OpenTKGameWindow_ButtonPressEvent (object o, Gtk.ButtonPressEventArgs args)
{
- MouseButtonEventArgs e = new MouseButtonEventArgs ((int)args.Event.X, (int)args.Event.Y, (Crow.MouseButton)args.Event.Button - 1, true);
- mouse.EnableBit ((int)args.Event.Button - 1);
- e.Mouse = mouse;
-
- if (hoverWidget == null) {
- //MouseButtonDown.Raise (this, otk_e);
- return;
- }
-
- hoverWidget.onMouseDown(hoverWidget,new BubblingMouseButtonEventArg(e));
-
- if (FocusedWidget == null)
- return;
- if (!FocusedWidget.MouseRepeat)
- return;
- mouseRepeatThread = new Thread (mouseRepeatThreadFunc);
- mouseRepeatThread.Start ();
+ CrowInterface.ProcessMouseButtonDown ((int)args.Event.Button - 1);
}
// void Mouse_WheelChanged(object sender, OpenTK.Input.MouseWheelEventArgs otk_e)
// hoverWidget.onMouseWheel (this, e);
// }
- volatile bool mouseRepeatOn;
- volatile int mouseRepeatCount;
- Thread mouseRepeatThread;
- void mouseRepeatThreadFunc()
- {
- mouseRepeatOn = true;
- Thread.Sleep (Interface.DeviceRepeatDelay);
- while (mouseRepeatOn) {
- mouseRepeatCount++;
- Thread.Sleep (Interface.DeviceRepeatInterval);
- }
- mouseRepeatCount = 0;
- }
#region keyboard Handling
// }
void OpenTKGameWindow_KeyPressEvent (object o, Gtk.KeyPressEventArgs args)
{
- if (_focusedWidget == null) {
-// KeyboardKeyDown.Raise (this, otk_e);
- return;
- }
- Keyboard.SetKeyState ((Crow.Key)args.Event.KeyValue, true);
- KeyboardKeyEventArgs e = new KeyboardKeyEventArgs((Crow.Key)args.Event.KeyValue, false, Keyboard);
- _focusedWidget.onKeyDown (o, e);
- }
- #endregion
-
- #region ILayoutable implementation
- public void RegisterClip(Rectangle r){
- clipping.AddRectangle (r);
- }
- public bool ArrangeChildren { get { return false; }}
- public int LayoutingTries {
- get { throw new NotImplementedException (); }
- set { throw new NotImplementedException (); }
- }
- public LayoutingType RegisteredLayoutings {
- get { return LayoutingType.None; }
- set { throw new NotImplementedException (); }
- }
- public void RegisterForLayouting (LayoutingType layoutType) { throw new NotImplementedException (); }
- public bool UpdateLayout (LayoutingType layoutType) { throw new NotImplementedException (); }
- public Rectangle ContextCoordinates (Rectangle r) => r;
- public Rectangle ScreenCoordinates (Rectangle r) => r;
-
- public ILayoutable Parent {
- get { return null; }
- set { throw new NotImplementedException (); }
- }
- public ILayoutable LogicalParent {
- get { return null; }
- set { throw new NotImplementedException (); }
}
- public Rectangle ClientRectangle {
- get {
- int width, height;
- this.GetSize (out width, out height);
- return new Size(width, height);
- }
- }
- public IGOLibHost HostContainer {
- get { return this; }
- }
- public Rectangle getSlot () => ClientRectangle;
- public Rectangle getBounds () => ClientRectangle;
- #endregion
+ #endregion
}
}
}
#endregion
- #if MEASURE_TIME
- public Stopwatch updateTime = new Stopwatch ();
- public Stopwatch layoutTime = new Stopwatch ();
- public Stopwatch guTime = new Stopwatch ();
- public Stopwatch drawingTime = new Stopwatch ();
- #endif
bool isDirty = false;
Rectangle DirtyRect;
FocusedWidget.onMouseClick (this, new MouseButtonEventArgs (Mouse.X, Mouse.Y, MouseButton.Left, true));
}
}
- #if MEASURE_TIME
- layoutTime.Reset ();
- guTime.Reset ();
- drawingTime.Reset ();
- updateTime.Restart ();
- #endif
GraphicObject[] invGOList = new GraphicObject[GraphicObjects.Count];
GraphicObjects.CopyTo (invGOList, 0);
invGOList = invGOList.Reverse ().ToArray ();
- #if MEASURE_TIME
- layoutTime.Start ();
- #endif
//Debug.WriteLine ("======= Layouting queue start =======");
while (Interface.LayoutingQueue.Count > 0) {
lqi.ProcessLayouting ();
}
- #if MEASURE_TIME
- layoutTime.Stop ();
- #endif
//Debug.WriteLine ("otd:" + gobjsToRedraw.Count.ToString () + "-");
//final redraw clips should be added only when layout is completed among parents,
p.Parent.RegisterClip (p.getSlot());
}
- #if MEASURE_TIME
- updateTime.Stop ();
- drawingTime.Start ();
- #endif
-
using (surf = new ImageSurface (bmp, Format.Argb32, ClientRectangle.Width, ClientRectangle.Height, ClientRectangle.Width * 4)) {
using (ctx = new Context (surf)){
DirtyRect.Left = Math.Max (0, DirtyRect.Left);
DirtyRect.Top = Math.Max (0, DirtyRect.Top);
- DirtyRect.Width = Math.Min (ClientRectangle.Width - DirtyRect.Left, DirtyRect.Width);
- DirtyRect.Height = Math.Min (ClientRectangle.Height - DirtyRect.Top, DirtyRect.Height);
+ DirtyRect.Width = Math.Min (ClientRectangle.Right, DirtyRect.Width);
+ DirtyRect.Height = Math.Min (ClientRectangle.Bottom, DirtyRect.Height);
clipping.Reset ();
}
-
- #if MEASURE_TIME
- drawingTime.Stop ();
- #endif
- //surf.WriteToPng (@"/mnt/data/test.png");
}
}
-// if (ToolTip.isVisible) {
-// ToolTip.panel.processkLayouting();
-// if (ToolTip.panel.layoutIsValid)
-// ToolTip.panel.Paint(ref ctx);
-// }
-// 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);
-
-// Debug.WriteLine("UPDATE: {0} ticks \t, {1} ms",
-// updateTime.ElapsedTicks,
-// updateTime.ElapsedMilliseconds);
- }
+ }
#endregion
#region loading
: base(800, 600,"test: press spacebar to toogle test files")
{
//VSync = VSyncMode.Off;
+ Interface.CurrentInterface = CrowInterface;
+ GraphicObject obj = CrowInterface.LoadInterface("Interfaces/" + testFiles[idx]);
+ obj.DataSource = this;
+
}
int frameCpt = 0;
"0.crow",
"testImage.crow",
"testOutOfClipUpdate.crow",
-<<<<<<< 328c6d4eab1127cd9799540f253deda66060b68a
- "testTreeView.crow",
- "testWindow.goml",
-=======
// "test_Listbox.goml",
// "testTreeView.crow",
"1.crow",
->>>>>>> GtkCrowContainer test, functionnal, keyboard issue
"clip4.crow",
"clip3.crow",
"clip2.crow",
ValueChanged.Raise(this, new ValueChangeEventArgs ("fps", _fps));
#if MEASURE_TIME
ValueChanged.Raise (this, new ValueChangeEventArgs ("update",
- this.updateTime.ElapsedTicks.ToString () + " ticks"));
+ this.CrowInterface.updateTime.ElapsedTicks.ToString () + " ticks"));
ValueChanged.Raise (this, new ValueChangeEventArgs ("layouting",
- this.layoutTime.ElapsedTicks.ToString () + " ticks"));
+ this.CrowInterface.layoutTime.ElapsedTicks.ToString () + " ticks"));
ValueChanged.Raise (this, new ValueChangeEventArgs ("drawing",
- this.drawingTime.ElapsedTicks.ToString () + " ticks"));
+ this.CrowInterface.drawingTime.ElapsedTicks.ToString () + " ticks"));
#endif
}
}
TestList = Color.ColorDic.ToList();
}
- protected override void OnLoad (EventArgs e)
- {
- base.OnLoad (e);
- //this.AddWidget(new test4());
- //KeyboardKeyDown += GOLIBTests_KeyboardKeyDown1;;
-
- GraphicObject obj = LoadInterface("Interfaces/" + testFiles[idx]);
- obj.DataSource = this;
- }
void GOLIBTests_KeyboardKeyDown1 (object sender, OpenTK.Input.KeyboardKeyEventArgs e)
{
if (e.Key == OpenTK.Input.Key.Escape) {
- this.Quit ();
+ Quit (null, null);
return;
} else if (e.Key == OpenTK.Input.Key.L) {
TestList.Add ("new string");
NotifyValueChanged ("TestList", TestList);
return;
} else if (e.Key == OpenTK.Input.Key.W) {
- GraphicObject w = LoadInterface("Interfaces/testWindow.goml");
+ GraphicObject w = CrowInterface.LoadInterface("Interfaces/testWindow.goml");
w.DataSource = this;
return;
}
- ClearInterface ();
+ CrowInterface.ClearInterface ();
idx++;
if (idx == testFiles.Length)
idx = 0;
this.Title = testFiles [idx];
- GraphicObject obj = LoadInterface("Interfaces/" + testFiles[idx]);
+ GraphicObject obj = CrowInterface.LoadInterface("Interfaces/" + testFiles[idx]);
obj.DataSource = this;
}
}
void onAddTabButClick(object sender, MouseButtonEventArgs e){
- TabView tv = this.FindByName("tabview1") as TabView;
+ TabView tv = CrowInterface.FindByName("tabview1") as TabView;
if (tv == null)
return;
tv.AddChild (new TabItem () { Caption = "NewTab" });
}
void Win_KeyPressEvent (object o, Gtk.KeyPressEventArgs args)
{
- ClearInterface ();
+ CrowInterface.ClearInterface ();
idx++;
if (idx == testFiles.Length)
idx = 0;
this.Title = testFiles [idx];
- GraphicObject obj = LoadInterface("Interfaces/" + testFiles[idx]);
- obj.DataSource = this;
+ GraphicObject obj = CrowInterface.LoadInterface("Interfaces/" + testFiles[idx]);
+ obj.DataSource = this;
}
}
}
ILayoutable tmp = Target.Instance as ILayoutable;
if (string.IsNullOrEmpty (bindingExp [0])) {
//if exp start with '/' => Graphic tree parsing start at top container
- tmp = tmp.HostContainer as ILayoutable;
+ tmp = Interface.CurrentInterface as ILayoutable;
ptr++;
}
while (ptr < bindingExp.Length - 1) {
return cb;
}
}
- [XmlIgnore]public virtual IGOLibHost HostContainer {
- get { return Parent == null ? null : Parent.HostContainer; }
- }
+
public virtual Rectangle ContextCoordinates(Rectangle r){
GraphicObject go = Parent as GraphicObject;
if (go == null)
_isVisible = value;
- if (HostContainer == null)
+ if (Interface.CurrentInterface == null)
return;
//ensure main win doesn't keep hidden childrens ref
- if (!_isVisible && this.Contains (HostContainer.hoverWidget))
- HostContainer.hoverWidget = null;
+ if (!_isVisible && this.Contains (Interface.CurrentInterface.hoverWidget))
+ Interface.CurrentInterface.hoverWidget = null;
if (Parent is GraphicObject)
Parent.RegisterForLayouting (LayoutingType.Sizing);
{
if (IsQueuedForRedraw)
return;
- if (HostContainer == null)
+ if (Interface.CurrentInterface == null)
return;
- HostContainer.gobjsToRedraw.Add (this);
+ Interface.CurrentInterface.gobjsToRedraw.Add (this);
IsQueuedForRedraw = true;
}
}
public virtual void checkHoverWidget(MouseMoveEventArgs e)
{
- IGOLibHost glh = HostContainer;
- if (glh.hoverWidget != this) {
- glh.hoverWidget = this;
+ if (Interface.CurrentInterface.hoverWidget != this) {
+ Interface.CurrentInterface.hoverWidget = this;
onMouseEnter (this, e);
}
MouseMove.Raise (sender, e);
}
public virtual void onMouseDown(object sender, MouseButtonEventArgs e){
- IGOLibHost hc = HostContainer;
- if (hc.activeWidget == null)
- hc.activeWidget = this;
+ if (Interface.CurrentInterface.activeWidget == null)
+ Interface.CurrentInterface.activeWidget = this;
if (this.Focusable && !Interface.FocusOnHover) {
BubblingMouseButtonEventArg be = e as BubblingMouseButtonEventArg;
if (be.Focused == null) {
be.Focused = this;
- hc.FocusedWidget = this;
+ Interface.CurrentInterface.FocusedWidget = this;
}
}
//bubble event to the top
#region Mouse handling
public override void checkHoverWidget (MouseMoveEventArgs e)
{
- if (HostContainer.hoverWidget != this) {
- HostContainer.hoverWidget = this;
+ if (Interface.CurrentInterface.hoverWidget != this) {
+ Interface.CurrentInterface.hoverWidget = this;
onMouseEnter (this, e);
}
for (int i = Children.Count - 1; i >= 0; i--) {
Rectangle getSlot();
Rectangle getBounds();
- IGOLibHost HostContainer { get; }
-
bool ArrangeChildren { get; }
LayoutingType RegisteredLayoutings { get; set; }
void RegisterForLayouting(LayoutingType layoutType);
public virtual void onPop(object sender, EventArgs e)
{
- IGOLibHost tc = HostContainer;
- if (tc == null)
+ if (Interface.CurrentInterface == null)
return;
if (Content != null) {
Content.Visible = true;
if (Content.Parent == null)
- tc.AddWidget (Content);
- tc.PutOnTop (Content);
+ Interface.CurrentInterface.AddWidget (Content);
+ Interface.CurrentInterface.PutOnTop (Content);
_content_LayoutChanged (this, new LayoutingEventArgs (LayoutingType.Sizing));
}
Pop.Raise (this, e);
}
public virtual void onUnpop(object sender, EventArgs e)
{
- IGOLibHost tc = HostContainer;
- if (tc == null)
+ if (Interface.CurrentInterface == null)
return;
Content.Visible = false;
Unpop.Raise (this, e);
{
base.onMouseEnter (sender, e);
if ((Parent as GenericStack).Orientation == Orientation.Horizontal)
- this.HostContainer.MouseCursor = XCursor.H;
+ Interface.CurrentInterface.MouseCursor = XCursor.H;
else
- this.HostContainer.MouseCursor = XCursor.V;
+ Interface.CurrentInterface.MouseCursor = XCursor.V;
}
public override void onMouseLeave (object sender, MouseMoveEventArgs e)
{
base.onMouseLeave (sender, e);
- this.HostContainer.MouseCursor = XCursor.Default;
+ Interface.CurrentInterface.MouseCursor = XCursor.Default;
}
public override void onMouseMove (object sender, MouseMoveEventArgs e)
{
#region Mouse handling
public override void checkHoverWidget (MouseMoveEventArgs e)
{
- if (HostContainer.hoverWidget != this) {
- HostContainer.hoverWidget = this;
+ if (Interface.CurrentInterface.hoverWidget != this) {
+ Interface.CurrentInterface.hoverWidget = this;
onMouseEnter (this, e);
}
{
base.onMouseMove (sender, e);
- IGOLibHost otkgw = HostContainer;
+ Interface otkgw = Interface.CurrentInterface;
if (e.Mouse.IsButtonDown (MouseButton.Left)) {
if (!HasFocus)
{
base.onMouseLeave (sender, e);
currentDirection = Direction.None;
- HostContainer.MouseCursor = XCursor.Default;
+ Interface.CurrentInterface.MouseCursor = XCursor.Default;
}
protected override void loadTemplate(GraphicObject template = null)
ILayoutable parent = (sender as GraphicObject).Parent;
while(!(parent is Window))
parent = parent.Parent;
- HostContainer.DeleteWidget (parent as GraphicObject);
+ Interface.CurrentInterface.DeleteWidget (parent as GraphicObject);
}
public override void ResolveBindings ()
using System.CodeDom;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
+using System.Threading;
+using Cairo;
namespace Crow
{
- public static class Interface
+ public class Interface : ILayoutable
{
+ #region CTOR
+ static Interface(){
+ Interface.LoadCursors ();
+ }
+ #endregion
+
+ #region Static and constants
/// <summary> Used to prevent spurious loading of templates </summary>
internal static bool XmlSerializerInit = false;
/// <summary> keep ressource path for debug msg </summary>
public static int BorderThreshold = 5;
public const int MaxCacheSize = 2048;
public const int MaxLayoutingTries = 50;
+ #endregion
public static Queue<LayoutingQueueItem> LayoutingQueue = new Queue<LayoutingQueueItem>();
+ #region default values loading helpers
public delegate void loadDefaultInvoker(object instance);
public static Dictionary<String, loadDefaultInvoker> DefaultValuesLoader = new Dictionary<string, loadDefaultInvoker>();
+ #endregion
public static void LoadCursors(){
//Load cursors
}
#region Load/Save
-
- public static void Save<T> (string file, T graphicObject)
- {
- XmlSerializerNamespaces xn = new XmlSerializerNamespaces ();
- xn.Add ("", "");
- XmlSerializer xs = new XmlSerializer (typeof(T));
-
- xs = new XmlSerializer (typeof(T));
- using (Stream s = new FileStream (file, FileMode.Create)) {
- xs.Serialize (s, graphicObject, xn);
- }
- }
-
public static Stream GetStreamFromPath (string path)
{
Stream stream = null;
return t;
}
+ public static void Save<T> (string file, T graphicObject)
+ {
+ XmlSerializerNamespaces xn = new XmlSerializerNamespaces ();
+ xn.Add ("", "");
+ XmlSerializer xs = new XmlSerializer (typeof(T));
+ xs = new XmlSerializer (typeof(T));
+ using (Stream s = new FileStream (file, FileMode.Create)) {
+ xs.Serialize (s, graphicObject, xn);
+ }
+ }
public static GraphicObject Load (string path, object hostClass = null)
{
Interface.XmlLoaderCount ++;
Interface.XmlLoaderCount --;
return tmp;
}
-
-
-
public static GraphicObject Load (Stream stream, Type type, object hostClass = null)
{
#if DEBUG_LOAD
return result;
}
+ public GraphicObject LoadInterface (string path)
+ {
+ GraphicObject tmp = Interface.Load (path, this);
+ AddWidget (tmp);
+ return tmp;
+ }
+
+ #endregion
+
+ #if MEASURE_TIME
+ public Stopwatch updateTime = new Stopwatch ();
+ public Stopwatch layoutTime = new Stopwatch ();
+ public Stopwatch guTime = new Stopwatch ();
+ public Stopwatch drawingTime = new Stopwatch ();
+ #endif
+
+ public List<GraphicObject> GraphicObjects = new List<GraphicObject>();
+ public Color Background = Color.Transparent;
+
+ internal static Interface currentWindow;
+ public static Interface CurrentInterface;
+
+ Rectangles _redrawClip = new Rectangles();//should find another way to access it from child
+ List<GraphicObject> _gobjsToRedraw = new List<GraphicObject>();
+
+ Context ctx;
+ Surface surf;
+ public byte[] bmp;
+ public bool IsDirty = false;
+ public Rectangle DirtyRect;
+
+ #region focus
+ GraphicObject _activeWidget; //button is pressed on widget
+ GraphicObject _hoverWidget; //mouse is over
+ GraphicObject _focusedWidget; //has keyboard (or other perif) focus
+
+ public GraphicObject activeWidget
+ {
+ get { return _activeWidget; }
+ set
+ {
+ if (_activeWidget == value)
+ return;
+
+ if (_activeWidget != null)
+ _activeWidget.IsActive = false;
+
+ _activeWidget = value;
+
+ if (_activeWidget != null)
+ _activeWidget.IsActive = true;
+ }
+ }
+ public GraphicObject hoverWidget
+ {
+ get { return _hoverWidget; }
+ set {
+ if (_hoverWidget == value)
+ return;
+ _hoverWidget = value;
+ }
+ }
+ public GraphicObject FocusedWidget {
+ get { return _focusedWidget; }
+ set {
+ if (_focusedWidget == value)
+ return;
+ if (_focusedWidget != null)
+ _focusedWidget.onUnfocused (this, null);
+ _focusedWidget = value;
+ if (_focusedWidget != null)
+ _focusedWidget.onFocused (this, null);
+ }
+ }
+ #endregion
+
+
+ public void Update(){
+ if (mouseRepeatCount > 0) {
+ int mc = mouseRepeatCount;
+ mouseRepeatCount -= mc;
+ for (int i = 0; i < mc; i++) {
+ FocusedWidget.onMouseClick (this, new MouseButtonEventArgs (Mouse.X, Mouse.Y, MouseButton.Left, true));
+ }
+ }
+ #if MEASURE_TIME
+ layoutTime.Reset ();
+ guTime.Reset ();
+ drawingTime.Reset ();
+ updateTime.Restart ();
+ #endif
+
+ GraphicObject[] invGOList = new GraphicObject[GraphicObjects.Count];
+ GraphicObjects.CopyTo (invGOList, 0);
+ invGOList = invGOList.Reverse ().ToArray ();
+
+ #if MEASURE_TIME
+ layoutTime.Start ();
+ #endif
+ //Debug.WriteLine ("======= Layouting queue start =======");
+
+ while (Interface.LayoutingQueue.Count > 0) {
+ LayoutingQueueItem lqi = Interface.LayoutingQueue.Dequeue ();
+ lqi.ProcessLayouting ();
+ }
+
+ #if MEASURE_TIME
+ layoutTime.Stop ();
+ #endif
+
+ //Debug.WriteLine ("otd:" + gobjsToRedraw.Count.ToString () + "-");
+ //final redraw clips should be added only when layout is completed among parents,
+ //that's why it take place in a second pass
+ GraphicObject[] gotr = new GraphicObject[gobjsToRedraw.Count];
+ gobjsToRedraw.CopyTo (gotr);
+ gobjsToRedraw.Clear ();
+ foreach (GraphicObject p in gotr) {
+ p.IsQueuedForRedraw = false;
+ p.Parent.RegisterClip (p.LastPaintedSlot);
+ p.Parent.RegisterClip (p.getSlot());
+ }
+
+ #if MEASURE_TIME
+ updateTime.Stop ();
+ drawingTime.Start ();
+ #endif
+
+ using (surf = new ImageSurface (bmp, Format.Argb32, ClientRectangle.Width, ClientRectangle.Height, ClientRectangle.Width * 4)) {
+ using (ctx = new Context (surf)){
+
+
+ if (clipping.count > 0) {
+ //Link.draw (ctx);
+ clipping.clearAndClip(ctx);
+
+ foreach (GraphicObject p in invGOList) {
+ if (!p.Visible)
+ continue;
+ if (!clipping.intersect (p.Slot))
+ continue;
+ ctx.Save ();
+
+ p.Paint (ref ctx);
+
+ ctx.Restore ();
+ }
+
+ #if DEBUG_CLIP_RECTANGLE
+ clipping.stroke (ctx, Color.Red.AdjustAlpha(0.5));
+ #endif
+
+ if (IsDirty)
+ DirtyRect += clipping.Bounds;
+ else
+ DirtyRect = clipping.Bounds;
+ IsDirty = true;
+
+ DirtyRect.Left = Math.Max (0, DirtyRect.Left);
+ DirtyRect.Top = Math.Max (0, DirtyRect.Top);
+ DirtyRect.Width = Math.Min (ClientRectangle.Width - DirtyRect.Left, DirtyRect.Width);
+ DirtyRect.Height = Math.Min (ClientRectangle.Height - DirtyRect.Top, DirtyRect.Height);
+
+ clipping.Reset ();
+ }
+
+ #if MEASURE_TIME
+ drawingTime.Stop ();
+ #endif
+ //surf.WriteToPng (@"/mnt/data/test.png");
+ }
+ }
+ // if (ToolTip.isVisible) {
+ // ToolTip.panel.processkLayouting();
+ // if (ToolTip.panel.layoutIsValid)
+ // ToolTip.panel.Paint(ref ctx);
+ // }
+ // 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);
+
+ // Debug.WriteLine("UPDATE: {0} ticks \t, {1} ms",
+ // updateTime.ElapsedTicks,
+ // updateTime.ElapsedMilliseconds);
+ }
+ public Rectangles clipping {
+ get { return _redrawClip; }
+ set { _redrawClip = value; }
+ }
+ public List<GraphicObject> gobjsToRedraw {
+ get { return _gobjsToRedraw; }
+ set { _gobjsToRedraw = value; }
+ }
+ public void AddWidget(GraphicObject g)
+ {
+ g.Parent = this;
+ GraphicObjects.Insert (0, g);
+
+ g.RegisterForLayouting (LayoutingType.Sizing);
+ }
+ public void DeleteWidget(GraphicObject g)
+ {
+ g.Visible = false;//trick to ensure clip is added to refresh zone
+ g.ClearBinding();
+ GraphicObjects.Remove (g);
+ }
+ public void PutOnTop(GraphicObject g)
+ {
+ if (GraphicObjects.IndexOf(g) > 0)
+ {
+ GraphicObjects.Remove(g);
+ GraphicObjects.Insert(0, g);
+ //g.registerClipRect ();
+ }
+ }
+ /// <summary> Remove all Graphic objects from top container </summary>
+ public void ClearInterface()
+ {
+ int i = 0;
+ while (GraphicObjects.Count>0) {
+ //TODO:parent is not reset to null because object will be added
+ //to ObjectToRedraw list, and without parent, it fails
+ GraphicObject g = GraphicObjects [i];
+ g.Visible = false;
+ g.ClearBinding ();
+ GraphicObjects.RemoveAt (0);
+ }
+ }
+ public GraphicObject FindByName (string nameToFind)
+ {
+ foreach (GraphicObject w in GraphicObjects) {
+ GraphicObject r = w.FindByName (nameToFind);
+ if (r != null)
+ return r;
+ }
+ return null;
+ }
+ public void ProcessResize(Rectangle bounds){
+ clientRectangle = bounds;
+
+ int stride = 4 * ClientRectangle.Width;
+ int bmpSize = Math.Abs (stride) * ClientRectangle.Height;
+ bmp = new byte[bmpSize];
+
+ foreach (GraphicObject g in GraphicObjects)
+ g.RegisterForLayouting (LayoutingType.All);
+ }
+
+ XCursor cursor = XCursor.Default;
+ public MouseState Mouse;
+ public KeyboardState Keyboard;
+ Rectangle clientRectangle;
+
+ public event EventHandler<MouseCursorChangedEventArgs> MouseCursorChanged;
+ public event EventHandler Quit;
+
+ #region Mouse Handling
+
+ public XCursor MouseCursor {
+ set {
+ if (value == cursor)
+ return;
+ cursor = value;
+ MouseCursorChanged.Raise (this,new MouseCursorChangedEventArgs(value));
+ }
+ }
+ public bool ProcessMouseMove(int x, int y)
+ {
+ int deltaX = x - Mouse.X;
+ int deltaY = y - Mouse.Y;
+ Mouse.X = x;
+ Mouse.Y = y;
+ MouseMoveEventArgs e = new MouseMoveEventArgs (x, y, deltaX, deltaY);
+ e.Mouse = Mouse;
+
+ if (_activeWidget != null) {
+ //TODO, ensure object is still in the graphic tree
+ //send move evt even if mouse move outside bounds
+ _activeWidget.onMouseMove (this, e);
+ return true;
+ }
+
+ if (hoverWidget != null) {
+ //TODO, ensure object is still in the graphic tree
+ //check topmost graphicobject first
+ GraphicObject tmp = hoverWidget;
+ GraphicObject topc = null;
+ while (tmp is GraphicObject) {
+ topc = tmp;
+ tmp = tmp.Parent as GraphicObject;
+ }
+ int idxhw = GraphicObjects.IndexOf (topc);
+ if (idxhw != 0) {
+ int i = 0;
+ while (i < idxhw) {
+ if (GraphicObjects [i].MouseIsIn (e.Position)) {
+ hoverWidget.onMouseLeave (this, e);
+ GraphicObjects [i].checkHoverWidget (e);
+ return true;
+ }
+ i++;
+ }
+ }
+
+
+ if (hoverWidget.MouseIsIn (e.Position)) {
+ hoverWidget.checkHoverWidget (e);
+ return true;
+ } else {
+ hoverWidget.onMouseLeave (this, e);
+ //seek upward from last focused graph obj's
+ while (hoverWidget.Parent as GraphicObject != null) {
+ hoverWidget = hoverWidget.Parent as GraphicObject;
+ if (hoverWidget.MouseIsIn (e.Position)) {
+ hoverWidget.checkHoverWidget (e);
+ return true;
+ } else
+ hoverWidget.onMouseLeave (this, e);
+ }
+ }
+ }
+
+ //top level graphic obj's parsing
+ for (int i = 0; i < GraphicObjects.Count; i++) {
+ GraphicObject g = GraphicObjects[i];
+ if (g.MouseIsIn (e.Position)) {
+ g.checkHoverWidget (e);
+ PutOnTop (g);
+ return true;
+ }
+ }
+ hoverWidget = null;
+ return false;
+ }
+ public bool ProcessMouseButtonUp(int button)
+ {
+ Mouse.DisableBit (button);
+ MouseButtonEventArgs e = new MouseButtonEventArgs () { Mouse = Mouse };
+
+ if (_activeWidget == null)
+ return false;
+
+ if (mouseRepeatThread != null) {
+ mouseRepeatOn = false;
+ mouseRepeatThread.Abort();
+ mouseRepeatThread.Join ();
+ }
+
+ _activeWidget.onMouseUp (this, e);
+ activeWidget = null;
+ return true;
+ }
+ public bool ProcessMouseButtonDown(int button)
+ {
+ Mouse.EnableBit (button);
+ MouseButtonEventArgs e = new MouseButtonEventArgs () { Mouse = Mouse };
+
+ if (hoverWidget == null)
+ return false;
+
+ hoverWidget.onMouseDown(hoverWidget,new BubblingMouseButtonEventArg(e));
+
+ if (FocusedWidget == null)
+ return true;
+ if (!FocusedWidget.MouseRepeat)
+ return true;
+ mouseRepeatThread = new Thread (mouseRepeatThreadFunc);
+ mouseRepeatThread.Start ();
+ return true;
+ }
+// public bool ProcessMouseWheelChanged(int delta)
+// {
+// if (hoverWidget == null)
+// return false;
+// hoverWidget.onMouseWheel (this, e);
+// return true;
+// }
+
+ volatile bool mouseRepeatOn;
+ volatile int mouseRepeatCount;
+ Thread mouseRepeatThread;
+ void mouseRepeatThreadFunc()
+ {
+ mouseRepeatOn = true;
+ Thread.Sleep (Interface.DeviceRepeatDelay);
+ while (mouseRepeatOn) {
+ mouseRepeatCount++;
+ Thread.Sleep (Interface.DeviceRepeatInterval);
+ }
+ mouseRepeatCount = 0;
+ }
+ #endregion
+ #region ILayoutable implementation
+ public void RegisterClip(Rectangle r){
+ clipping.AddRectangle (r);
+ }
+ public bool ArrangeChildren { get { return false; }}
+ public int LayoutingTries {
+ get { throw new NotImplementedException (); }
+ set { throw new NotImplementedException (); }
+ }
+ public LayoutingType RegisteredLayoutings {
+ get { return LayoutingType.None; }
+ set { throw new NotImplementedException (); }
+ }
+ public void RegisterForLayouting (LayoutingType layoutType) { throw new NotImplementedException (); }
+ public bool UpdateLayout (LayoutingType layoutType) { throw new NotImplementedException (); }
+ public Rectangle ContextCoordinates (Rectangle r) => r;
+ public Rectangle ScreenCoordinates (Rectangle r) => r;
+
+ public ILayoutable Parent {
+ get { return null; }
+ set { throw new NotImplementedException (); }
+ }
+ public ILayoutable LogicalParent {
+ get { return null; }
+ set { throw new NotImplementedException (); }
+ }
+
+ public Rectangle ClientRectangle {
+ get { return clientRectangle; }
+ }
+ public Interface HostContainer {
+ get { return this; }
+ }
+ public Rectangle getSlot () => ClientRectangle;
+ public Rectangle getBounds () => ClientRectangle;
#endregion
}
}
--- /dev/null
+//
+// MouseCursorChangedEventArg.cs
+//
+// Author:
+// Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// Copyright (c) 2016 jp
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+using System;
+
+namespace Crow
+{
+ public class MouseCursorChangedEventArgs : EventArgs
+ {
+ public XCursor NewCursor;
+ public MouseCursorChangedEventArgs (XCursor NewCursor) : base()
+ {
+ NewCursor = NewCursor;
+ }
+ }
+}