aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/GraphicObjects
diff options
context:
space:
mode:
authorjpbruyere <jp.bruyere@hotmail.com>2016-02-02 12:19:06 +0100
committerjpbruyere <jp.bruyere@hotmail.com>2016-02-02 12:19:06 +0100
commit2b087282dd73152d21140ea7312a90e046c84f61 (patch)
tree5d03225090e39c1d14465bdbaf1882e87026402b /src/GraphicObjects
parent73b7c1d82226e4d10708e858a011991e3f598655 (diff)
Fix CRLF
Diffstat (limited to 'src/GraphicObjects')
-rw-r--r--src/GraphicObjects/Button.cs210
-rw-r--r--src/GraphicObjects/CheckBox.cs188
-rw-r--r--src/GraphicObjects/ComboBox.cs730
-rw-r--r--src/GraphicObjects/Container.cs156
-rw-r--r--src/GraphicObjects/Expandable.cs260
-rw-r--r--src/GraphicObjects/GenericStack.cs356
-rw-r--r--src/GraphicObjects/GraduatedSlider.cs108
-rw-r--r--src/GraphicObjects/GraphicObject.cs2762
-rw-r--r--src/GraphicObjects/Grid.cs298
-rw-r--r--src/GraphicObjects/Group.cs634
-rw-r--r--src/GraphicObjects/GroupBox.cs136
-rw-r--r--src/GraphicObjects/HorizontalStack.cs46
-rw-r--r--src/GraphicObjects/Image.cs230
-rw-r--r--src/GraphicObjects/Label.cs1358
-rw-r--r--src/GraphicObjects/Popper.cs376
-rw-r--r--src/GraphicObjects/ProgressBar.cs208
-rw-r--r--src/GraphicObjects/RadioButton.cs186
-rw-r--r--src/GraphicObjects/ScrollBar.cs194
-rw-r--r--src/GraphicObjects/Scroller.cs454
-rw-r--r--src/GraphicObjects/Slider.cs398
-rw-r--r--src/GraphicObjects/TextBox.cs404
-rw-r--r--src/GraphicObjects/TextRun.cs666
-rw-r--r--src/GraphicObjects/VerticalStack.cs50
-rwxr-xr-xsrc/GraphicObjects/WrappedWidgetGroup.cs308
24 files changed, 5358 insertions, 5358 deletions
diff --git a/src/GraphicObjects/Button.cs b/src/GraphicObjects/Button.cs
index 17fbe328..5bf11f68 100644
--- a/src/GraphicObjects/Button.cs
+++ b/src/GraphicObjects/Button.cs
@@ -1,105 +1,105 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-//using OpenTK.Graphics.OpenGL;
-
-using System.Diagnostics;
-
-using System.Xml.Serialization;
-using Cairo;
-using OpenTK.Input;
-using System.ComponentModel;
-
-namespace Crow
-{
- [DefaultTemplate("#Crow.Templates.Button.crow")]
- public class Button : TemplatedContainer
- {
- #region CTOR
- public Button() : base()
- {
- //MouseEnter += delegate { Background = Color.RedDevil;};
- //MouseLeave += delegate { Background = Color.Transparent;};
-// MouseButtonDown += delegate { BackImgSub = "pressed"; registerForGraphicUpdate();};
-// MouseButtonUp += delegate { BackImgSub = "normal";registerForGraphicUpdate();};
- }
- #endregion
-
- string caption;
- string image;
- Container _contentContainer;
-
- public override GraphicObject Content {
- get {
- return _contentContainer == null ? null : _contentContainer.Child;
- }
- set {
- if (_contentContainer != null)
- _contentContainer.SetChild(value);
- }
- }
- protected override void loadTemplate(GraphicObject template = null)
- {
- base.loadTemplate (template);
-
- _contentContainer = this.child.FindByName ("Content") as Container;
- }
-
- #region GraphicObject Overrides
-// [XmlAttributeAttribute()][DefaultValue(50)]
-// public override int Width {
-// get { return base.Width; }
-// set { base.Width = value; }
-// }
-// [XmlAttributeAttribute()][DefaultValue(20)]
-// public override int Height {
-// get { return base.Height; }
-// set { base.Height = value; }
-// }
- [XmlAttributeAttribute()][DefaultValue(true)]
- public override bool Focusable
- {
- get { return base.Focusable; }
- set { base.Focusable = value; }
- }
- public override void ResolveBindings ()
- {
- base.ResolveBindings ();
- if (Content != null)
- Content.ResolveBindings ();
- }
- public override void onMouseDown (object sender, MouseButtonEventArgs e)
- {
- base.onMouseDown (sender, e);
- NotifyValueChanged ("State", "pressed");
- }
- public override void onMouseUp (object sender, MouseButtonEventArgs e)
- {
- base.onMouseUp (sender, e);
- NotifyValueChanged ("State", "normal");
- }
- #endregion
-
- [XmlAttributeAttribute()][DefaultValue("Button")]
- public string Caption {
- get { return caption; }
- set {
- if (caption == value)
- return;
- caption = value;
- NotifyValueChanged ("Caption", caption);
- }
- }
- [XmlAttributeAttribute()][DefaultValue("#Crow.Images.button.svg")]
- public string Image {
- get { return image; }
- set {
- if (image == value)
- return;
- image = value;
- NotifyValueChanged ("Image", image);
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+//using OpenTK.Graphics.OpenGL;
+
+using System.Diagnostics;
+
+using System.Xml.Serialization;
+using Cairo;
+using OpenTK.Input;
+using System.ComponentModel;
+
+namespace Crow
+{
+ [DefaultTemplate("#Crow.Templates.Button.crow")]
+ public class Button : TemplatedContainer
+ {
+ #region CTOR
+ public Button() : base()
+ {
+ //MouseEnter += delegate { Background = Color.RedDevil;};
+ //MouseLeave += delegate { Background = Color.Transparent;};
+// MouseButtonDown += delegate { BackImgSub = "pressed"; registerForGraphicUpdate();};
+// MouseButtonUp += delegate { BackImgSub = "normal";registerForGraphicUpdate();};
+ }
+ #endregion
+
+ string caption;
+ string image;
+ Container _contentContainer;
+
+ public override GraphicObject Content {
+ get {
+ return _contentContainer == null ? null : _contentContainer.Child;
+ }
+ set {
+ if (_contentContainer != null)
+ _contentContainer.SetChild(value);
+ }
+ }
+ protected override void loadTemplate(GraphicObject template = null)
+ {
+ base.loadTemplate (template);
+
+ _contentContainer = this.child.FindByName ("Content") as Container;
+ }
+
+ #region GraphicObject Overrides
+// [XmlAttributeAttribute()][DefaultValue(50)]
+// public override int Width {
+// get { return base.Width; }
+// set { base.Width = value; }
+// }
+// [XmlAttributeAttribute()][DefaultValue(20)]
+// public override int Height {
+// get { return base.Height; }
+// set { base.Height = value; }
+// }
+ [XmlAttributeAttribute()][DefaultValue(true)]
+ public override bool Focusable
+ {
+ get { return base.Focusable; }
+ set { base.Focusable = value; }
+ }
+ public override void ResolveBindings ()
+ {
+ base.ResolveBindings ();
+ if (Content != null)
+ Content.ResolveBindings ();
+ }
+ public override void onMouseDown (object sender, MouseButtonEventArgs e)
+ {
+ base.onMouseDown (sender, e);
+ NotifyValueChanged ("State", "pressed");
+ }
+ public override void onMouseUp (object sender, MouseButtonEventArgs e)
+ {
+ base.onMouseUp (sender, e);
+ NotifyValueChanged ("State", "normal");
+ }
+ #endregion
+
+ [XmlAttributeAttribute()][DefaultValue("Button")]
+ public string Caption {
+ get { return caption; }
+ set {
+ if (caption == value)
+ return;
+ caption = value;
+ NotifyValueChanged ("Caption", caption);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue("#Crow.Images.button.svg")]
+ public string Image {
+ get { return image; }
+ set {
+ if (image == value)
+ return;
+ image = value;
+ NotifyValueChanged ("Image", image);
+ }
+ }
+ }
+}
diff --git a/src/GraphicObjects/CheckBox.cs b/src/GraphicObjects/CheckBox.cs
index a08f9fdb..fa34522d 100644
--- a/src/GraphicObjects/CheckBox.cs
+++ b/src/GraphicObjects/CheckBox.cs
@@ -1,94 +1,94 @@
-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;
-using System.Xml.Serialization;
-using OpenTK.Input;
-using System.ComponentModel;
-
-namespace Crow
-{
- [DefaultTemplate("#Crow.Templates.CheckBox.goml")]
- public class CheckBox : TemplatedControl
- {
- string caption;
- string image;
- bool isChecked;
-
- #region CTOR
- public CheckBox() : base()
- {
- }
- #endregion
-
- public event EventHandler Checked;
- public event EventHandler Unchecked;
-
- #region GraphicObject overrides
-// [XmlAttributeAttribute()][DefaultValue(-1)]
-// public override int Height {
-// get { return base.Height; }
-// set { base.Height = value; }
-// }
- [XmlAttributeAttribute()][DefaultValue(true)]//overiden to get default to true
- public override bool Focusable
- {
- get { return base.Focusable; }
- set { base.Focusable = value; }
- }
- #endregion
-
- [XmlAttributeAttribute()][DefaultValue("Checkbox")]
- public string Caption {
- get { return caption; }
- set {
- if (caption == value)
- return;
- caption = value;
- NotifyValueChanged ("Caption", caption);
- }
- }
- [XmlAttributeAttribute()][DefaultValue("#Crow.Images.Icons.checkbox.svg")]
- public string Image {
- get { return image; }
- set {
- if (image == value)
- return;
- image = value;
- NotifyValueChanged ("Image", image);
- }
- }
-
- [XmlAttributeAttribute()][DefaultValue(false)]
- public bool IsChecked
- {
- get { return isChecked; }
- set
- {
- isChecked = value;
-
- NotifyValueChanged ("IsChecked", value);
- if (isChecked) {
- NotifyValueChanged ("SvgSub", "checked");
- Checked.Raise (this, null);
- } else {
- NotifyValueChanged ("SvgSub", "unchecked");
- Unchecked.Raise (this, null);
- }
- }
- }
- public override void onMouseClick (object sender, MouseButtonEventArgs e)
- {
- IsChecked = !IsChecked;
- base.onMouseClick (sender, e);
- }
- }
-}
+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;
+using System.Xml.Serialization;
+using OpenTK.Input;
+using System.ComponentModel;
+
+namespace Crow
+{
+ [DefaultTemplate("#Crow.Templates.CheckBox.goml")]
+ public class CheckBox : TemplatedControl
+ {
+ string caption;
+ string image;
+ bool isChecked;
+
+ #region CTOR
+ public CheckBox() : base()
+ {
+ }
+ #endregion
+
+ public event EventHandler Checked;
+ public event EventHandler Unchecked;
+
+ #region GraphicObject overrides
+// [XmlAttributeAttribute()][DefaultValue(-1)]
+// public override int Height {
+// get { return base.Height; }
+// set { base.Height = value; }
+// }
+ [XmlAttributeAttribute()][DefaultValue(true)]//overiden to get default to true
+ public override bool Focusable
+ {
+ get { return base.Focusable; }
+ set { base.Focusable = value; }
+ }
+ #endregion
+
+ [XmlAttributeAttribute()][DefaultValue("Checkbox")]
+ public string Caption {
+ get { return caption; }
+ set {
+ if (caption == value)
+ return;
+ caption = value;
+ NotifyValueChanged ("Caption", caption);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue("#Crow.Images.Icons.checkbox.svg")]
+ public string Image {
+ get { return image; }
+ set {
+ if (image == value)
+ return;
+ image = value;
+ NotifyValueChanged ("Image", image);
+ }
+ }
+
+ [XmlAttributeAttribute()][DefaultValue(false)]
+ public bool IsChecked
+ {
+ get { return isChecked; }
+ set
+ {
+ isChecked = value;
+
+ NotifyValueChanged ("IsChecked", value);
+ if (isChecked) {
+ NotifyValueChanged ("SvgSub", "checked");
+ Checked.Raise (this, null);
+ } else {
+ NotifyValueChanged ("SvgSub", "unchecked");
+ Unchecked.Raise (this, null);
+ }
+ }
+ }
+ public override void onMouseClick (object sender, MouseButtonEventArgs e)
+ {
+ IsChecked = !IsChecked;
+ base.onMouseClick (sender, e);
+ }
+ }
+}
diff --git a/src/GraphicObjects/ComboBox.cs b/src/GraphicObjects/ComboBox.cs
index b958a81b..ed979d75 100644
--- a/src/GraphicObjects/ComboBox.cs
+++ b/src/GraphicObjects/ComboBox.cs
@@ -1,365 +1,365 @@
-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;
-using System.Xml.Serialization;
-using OpenTK.Input;
-using System.ComponentModel;
-using System.Xml;
-using System.IO;
-using System.Collections;
-using System.Threading;
-
-namespace Crow
-{
- [DefaultTemplate("#Crow.Templates.ComboBox.goml")]
- [DefaultOverlayTemplate("#Crow.Templates.ComboBoxOverlay.goml")]
- public class ComboBox : TemplatedContainer
- {
- #region CTOR
- public ComboBox() : base(){ }
- #endregion
-
- bool _isPopped;
- string caption;
- GraphicObject _overlay;
- Group _list;
- IList data;
- int _selectedIndex;
- object _selectedItem;
- string _itemTemplate;
- string _overlayTemplate;
-
- public event EventHandler Pop;
- public event EventHandler Unpop;
- public event EventHandler<SelectionChangeEventArgs> SelectedItemChanged;
-
- #region implemented abstract members of TemplatedControl
- protected override void loadTemplate (GraphicObject template)
- {
- base.loadTemplate (template);
- loadOverlayTemplate (null);
- }
- public override GraphicObject Content {
- get {
- throw new NotImplementedException ();
- }
- set {
- throw new NotImplementedException ();
- }
- }
- #endregion
-
- protected virtual void loadOverlayTemplate(GraphicObject overlayTemplate)
- {
- if (overlayTemplate == null) {
- DefaultOverlayTemplate dt = (DefaultOverlayTemplate)this.GetType ().GetCustomAttributes (typeof(DefaultOverlayTemplate), true).FirstOrDefault ();
- Overlay = Interface.Load (dt.Path);
- Overlay.ResolveBindings ();
- } else
- Overlay = overlayTemplate;
- _list = Overlay.FindByName ("List") as Group;
- }
-
- [XmlAttributeAttribute][DefaultValue("#Crow.Templates.ItemTemplate.goml")]
- public string ItemTemplate {
- get { return _itemTemplate; }
- set {
- //TODO:reload list with new template?
- _itemTemplate = value;
- }
- }
- [XmlAttributeAttribute][DefaultValue("#Crow.Templates.ComboBoxOverlay.goml")]
- public string OverlayTemplate {
- get { return _overlayTemplate; }
- set {
- //TODO:reload list with new template?
- _overlayTemplate = value;
-
- Overlay = Interface.Load (_overlayTemplate);
- Overlay.ResolveBindings ();
- _list = Overlay.FindByName ("List") as Group;
- }
- }
- [XmlAttributeAttribute][DefaultValue(-1)]
- public int SelectedIndex{
- get { return _selectedIndex; }
- set {
- //store value event if data is null, because in xml parsing selindex is always
- //before data, so it's impossible without that trick to set a default index in goml
- _selectedIndex = value;
-
- if (data == null)
- return;
-
- if (_selectedIndex > data.Count - 1 || _selectedIndex < 0)
- throw new Exception ("Combobox SelectedIndex out of range");
-
-
- _selectedItem = data [_selectedIndex];
- NotifyValueChanged ("SelectedIndex", SelectedIndex);
- SelectedItemChanged.Raise (this, new SelectionChangeEventArgs(_selectedItem));
-
- if (SelectedItem == null)
- Caption = "";
- else
- Caption = _selectedItem.ToString ();
- }
- }
- public object SelectedItem{
- set {
- if (_selectedItem == value)
- return;
-
- _selectedItem = value;
- _selectedIndex = data.IndexOf (_selectedItem);
- NotifyValueChanged ("SelectedIndex", _selectedIndex);
- SelectedItemChanged.Raise (this, new SelectionChangeEventArgs(_selectedItem));
-
- if (SelectedItem == null)
- Caption = "";
- else
- Caption = _selectedItem.ToString ();
- }
-
- get { return _selectedItem; }
- }
- [XmlAttributeAttribute][DefaultValue(null)]
- public IList Data {
- get {
- return data;
- }
- set {
- data = value;
- if (_list == null)
- return;
-
- foreach (GraphicObject c in _list.Children) {
- c.ClearBinding ();
- }
- _list.Children.Clear ();
- _list.registerForGraphicUpdate ();
- if (data == null)
- return;
- if (SelectedIndex < 0)
- return;
-
- //force raise of changes
- SelectedIndex = SelectedIndex;
-
- pendingChildrenAddition = new Queue<GraphicObject> ();
- threadedLoadingFinished = false;
-
- Thread t = new Thread (loadingThread);
- t.Start ();
- t.Join ();
-
- }
- }
- public override void UpdateLayout (LayoutingType layoutType)
- {
- CheckPendingChildrenAddition ();
- base.UpdateLayout (layoutType);
- }
- internal void CheckPendingChildrenAddition()
- {
- if (pendingChildrenAddition == null)
- return;
- lock (pendingChildrenAddition) {
- if (!threadedLoadingFinished && pendingChildrenAddition.Count < 50)
- return;
- while (pendingChildrenAddition.Count > 0) {
- _list.addChild (pendingChildrenAddition.Dequeue ());
- }
- }
- }
-
- volatile Queue<GraphicObject> pendingChildrenAddition;
- volatile bool threadedLoadingFinished = false;
-
- void loadingThread()
- {
- #if DEBUG_LOAD_TIME
- Stopwatch loadingTime = new Stopwatch ();
- loadingTime.Start ();
- #endif
-
- MemoryStream ms = new MemoryStream ();
- lock (ItemTemplate) {
- using (Stream stream = Interface.GetStreamFromPath (ItemTemplate))
- stream.CopyTo (ms);
- }
-
- Type t = Interface.GetTopContainerOfGOMLStream (ms);
-
- foreach (var item in data) {
- ms.Seek(0,SeekOrigin.Begin);
- GraphicObject g = Interface.Load (ms, t);
- g.DataSource = item;
- g.MouseClick += itemClick;
-
- lock (pendingChildrenAddition) {
- pendingChildrenAddition.Enqueue (g);
- }
- }
-
- ms.Dispose ();
-
- threadedLoadingFinished = true;
-
- #if DEBUG_LOAD_TIME
- loadingTime.Stop ();
- Debug.WriteLine("Listbox {2} Loading: {0} ticks \t, {1} ms",
- loadingTime.ElapsedTicks,
- loadingTime.ElapsedMilliseconds, this.ToString());
- #endif
- }
- public GraphicObject Overlay {
- get { return _overlay; }
- set {
- if (_overlay != null) {
- _overlay.LayoutChanged -= _overlay_LayoutChanged;
- _overlay.MouseLeave -= _overlay_MouseLeave;
- _overlay.LogicalParent = null;
- }
-
- _overlay = value;
-
- if (_overlay == null)
- return;
-
- _overlay.LogicalParent = this;
- _overlay.Focusable = true;
- _overlay.LayoutChanged += _overlay_LayoutChanged;
- _overlay.MouseLeave += _overlay_MouseLeave;
- }
- }
- [XmlAttributeAttribute()][DefaultValue("Combobox")]
- public string Caption {
- get { return caption; }
- set {
- if (caption == value)
- return;
- caption = value;
- NotifyValueChanged ("Caption", caption);
- }
- }
- [XmlAttributeAttribute()][DefaultValue(false)]
- public bool IsPopped
- {
- get { return _isPopped; }
- set
- {
- _isPopped = value;
-
- if (_isPopped) {
- onPop (this, null);
- NotifyValueChanged ("SvgSub", "expanded");
- return;
- }
-
- onUnpop (this, null);
- NotifyValueChanged ("SvgSub", "collapsed");
- }
- }
-
- void itemClick(object sender, OpenTK.Input.MouseButtonEventArgs e){
- object datasource = (sender as GraphicObject).DataSource;
- SelectedItem = datasource;
- IsPopped = false;
- //Debug.WriteLine ((sender as GraphicObject).DataSource);
- }
- void _overlay_MouseLeave (object sender, MouseMoveEventArgs e)
- {
- IsPopped = false;
- }
- void _overlay_LayoutChanged (object sender, LayoutChangeEventArgs e)
- {
- ILayoutable tc = Overlay.Parent as ILayoutable;
- if (tc == null)
- return;
- Rectangle r = this.ScreenCoordinates (this.Slot);
- if (e.LayoutType == LayoutingType.Width) {
- if (Overlay.Slot.Width < tc.ClientRectangle.Width) {
- if (r.Left + Overlay.Slot.Width > tc.ClientRectangle.Right)
- Overlay.Left = tc.ClientRectangle.Right - Overlay.Slot.Width;
- else
- Overlay.Left = r.Left;
- }else
- Overlay.Left = 0;
- }else if (e.LayoutType == LayoutingType.Height) {
- if (Overlay.Slot.Height < tc.ClientRectangle.Height) {
- if (r.Bottom + Overlay.Slot.Height > tc.ClientRectangle.Bottom)
- Overlay.Top = r.Top - Overlay.Slot.Height;
- else
- Overlay.Top = r.Bottom;
- }else
- Overlay.Top = 0;
- }
- }
-
- [XmlAttributeAttribute()][DefaultValue(true)]//overiden to get default to true
- public override bool Focusable
- {
- get { return base.Focusable; }
- set { base.Focusable = value; }
- }
-
-
- public virtual void onPop(object sender, EventArgs e)
- {
- IGOLibHost tc = HostContainer;
- if (tc == null)
- return;
- if (Overlay != null) {
- Overlay.Visible = true;
- if (Overlay.Parent == null)
- tc.AddWidget (Overlay);
- (tc as OpenTKGameWindow).PutOnTop (Overlay);
- }
- Pop.Raise (this, e);
- }
- public virtual void onUnpop(object sender, EventArgs e)
- {
- IGOLibHost tc = HostContainer;
- if (tc == null)
- return;
- Overlay.Visible = false;
- Unpop.Raise (this, e);
- }
-
- public override void onMouseClick (object sender, MouseButtonEventArgs e)
- {
- IsPopped = !IsPopped;
- base.onMouseClick (sender, e);
- }
-
- public override void ClearBinding ()
- {
- //ensure popped window is cleared
- if (Overlay != null) {
- if (Overlay.Parent != null) {
- IGOLibHost tc = Overlay.Parent as IGOLibHost;
- if (tc != null)
- tc.DeleteWidget (Overlay);
- }
- }
- base.ClearBinding ();
-
- }
- public override void ResolveBindings ()
- {
- base.ResolveBindings ();
- if (Overlay != null)
- Overlay.ResolveBindings ();
- }
- }
-}
+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;
+using System.Xml.Serialization;
+using OpenTK.Input;
+using System.ComponentModel;
+using System.Xml;
+using System.IO;
+using System.Collections;
+using System.Threading;
+
+namespace Crow
+{
+ [DefaultTemplate("#Crow.Templates.ComboBox.goml")]
+ [DefaultOverlayTemplate("#Crow.Templates.ComboBoxOverlay.goml")]
+ public class ComboBox : TemplatedContainer
+ {
+ #region CTOR
+ public ComboBox() : base(){ }
+ #endregion
+
+ bool _isPopped;
+ string caption;
+ GraphicObject _overlay;
+ Group _list;
+ IList data;
+ int _selectedIndex;
+ object _selectedItem;
+ string _itemTemplate;
+ string _overlayTemplate;
+
+ public event EventHandler Pop;
+ public event EventHandler Unpop;
+ public event EventHandler<SelectionChangeEventArgs> SelectedItemChanged;
+
+ #region implemented abstract members of TemplatedControl
+ protected override void loadTemplate (GraphicObject template)
+ {
+ base.loadTemplate (template);
+ loadOverlayTemplate (null);
+ }
+ public override GraphicObject Content {
+ get {
+ throw new NotImplementedException ();
+ }
+ set {
+ throw new NotImplementedException ();
+ }
+ }
+ #endregion
+
+ protected virtual void loadOverlayTemplate(GraphicObject overlayTemplate)
+ {
+ if (overlayTemplate == null) {
+ DefaultOverlayTemplate dt = (DefaultOverlayTemplate)this.GetType ().GetCustomAttributes (typeof(DefaultOverlayTemplate), true).FirstOrDefault ();
+ Overlay = Interface.Load (dt.Path);
+ Overlay.ResolveBindings ();
+ } else
+ Overlay = overlayTemplate;
+ _list = Overlay.FindByName ("List") as Group;
+ }
+
+ [XmlAttributeAttribute][DefaultValue("#Crow.Templates.ItemTemplate.goml")]
+ public string ItemTemplate {
+ get { return _itemTemplate; }
+ set {
+ //TODO:reload list with new template?
+ _itemTemplate = value;
+ }
+ }
+ [XmlAttributeAttribute][DefaultValue("#Crow.Templates.ComboBoxOverlay.goml")]
+ public string OverlayTemplate {
+ get { return _overlayTemplate; }
+ set {
+ //TODO:reload list with new template?
+ _overlayTemplate = value;
+
+ Overlay = Interface.Load (_overlayTemplate);
+ Overlay.ResolveBindings ();
+ _list = Overlay.FindByName ("List") as Group;
+ }
+ }
+ [XmlAttributeAttribute][DefaultValue(-1)]
+ public int SelectedIndex{
+ get { return _selectedIndex; }
+ set {
+ //store value event if data is null, because in xml parsing selindex is always
+ //before data, so it's impossible without that trick to set a default index in goml
+ _selectedIndex = value;
+
+ if (data == null)
+ return;
+
+ if (_selectedIndex > data.Count - 1 || _selectedIndex < 0)
+ throw new Exception ("Combobox SelectedIndex out of range");
+
+
+ _selectedItem = data [_selectedIndex];
+ NotifyValueChanged ("SelectedIndex", SelectedIndex);
+ SelectedItemChanged.Raise (this, new SelectionChangeEventArgs(_selectedItem));
+
+ if (SelectedItem == null)
+ Caption = "";
+ else
+ Caption = _selectedItem.ToString ();
+ }
+ }
+ public object SelectedItem{
+ set {
+ if (_selectedItem == value)
+ return;
+
+ _selectedItem = value;
+ _selectedIndex = data.IndexOf (_selectedItem);
+ NotifyValueChanged ("SelectedIndex", _selectedIndex);
+ SelectedItemChanged.Raise (this, new SelectionChangeEventArgs(_selectedItem));
+
+ if (SelectedItem == null)
+ Caption = "";
+ else
+ Caption = _selectedItem.ToString ();
+ }
+
+ get { return _selectedItem; }
+ }
+ [XmlAttributeAttribute][DefaultValue(null)]
+ public IList Data {
+ get {
+ return data;
+ }
+ set {
+ data = value;
+ if (_list == null)
+ return;
+
+ foreach (GraphicObject c in _list.Children) {
+ c.ClearBinding ();
+ }
+ _list.Children.Clear ();
+ _list.registerForGraphicUpdate ();
+ if (data == null)
+ return;
+ if (SelectedIndex < 0)
+ return;
+
+ //force raise of changes
+ SelectedIndex = SelectedIndex;
+
+ pendingChildrenAddition = new Queue<GraphicObject> ();
+ threadedLoadingFinished = false;
+
+ Thread t = new Thread (loadingThread);
+ t.Start ();
+ t.Join ();
+
+ }
+ }
+ public override void UpdateLayout (LayoutingType layoutType)
+ {
+ CheckPendingChildrenAddition ();
+ base.UpdateLayout (layoutType);
+ }
+ internal void CheckPendingChildrenAddition()
+ {
+ if (pendingChildrenAddition == null)
+ return;
+ lock (pendingChildrenAddition) {
+ if (!threadedLoadingFinished && pendingChildrenAddition.Count < 50)
+ return;
+ while (pendingChildrenAddition.Count > 0) {
+ _list.addChild (pendingChildrenAddition.Dequeue ());
+ }
+ }
+ }
+
+ volatile Queue<GraphicObject> pendingChildrenAddition;
+ volatile bool threadedLoadingFinished = false;
+
+ void loadingThread()
+ {
+ #if DEBUG_LOAD_TIME
+ Stopwatch loadingTime = new Stopwatch ();
+ loadingTime.Start ();
+ #endif
+
+ MemoryStream ms = new MemoryStream ();
+ lock (ItemTemplate) {
+ using (Stream stream = Interface.GetStreamFromPath (ItemTemplate))
+ stream.CopyTo (ms);
+ }
+
+ Type t = Interface.GetTopContainerOfGOMLStream (ms);
+
+ foreach (var item in data) {
+ ms.Seek(0,SeekOrigin.Begin);
+ GraphicObject g = Interface.Load (ms, t);
+ g.DataSource = item;
+ g.MouseClick += itemClick;
+
+ lock (pendingChildrenAddition) {
+ pendingChildrenAddition.Enqueue (g);
+ }
+ }
+
+ ms.Dispose ();
+
+ threadedLoadingFinished = true;
+
+ #if DEBUG_LOAD_TIME
+ loadingTime.Stop ();
+ Debug.WriteLine("Listbox {2} Loading: {0} ticks \t, {1} ms",
+ loadingTime.ElapsedTicks,
+ loadingTime.ElapsedMilliseconds, this.ToString());
+ #endif
+ }
+ public GraphicObject Overlay {
+ get { return _overlay; }
+ set {
+ if (_overlay != null) {
+ _overlay.LayoutChanged -= _overlay_LayoutChanged;
+ _overlay.MouseLeave -= _overlay_MouseLeave;
+ _overlay.LogicalParent = null;
+ }
+
+ _overlay = value;
+
+ if (_overlay == null)
+ return;
+
+ _overlay.LogicalParent = this;
+ _overlay.Focusable = true;
+ _overlay.LayoutChanged += _overlay_LayoutChanged;
+ _overlay.MouseLeave += _overlay_MouseLeave;
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue("Combobox")]
+ public string Caption {
+ get { return caption; }
+ set {
+ if (caption == value)
+ return;
+ caption = value;
+ NotifyValueChanged ("Caption", caption);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(false)]
+ public bool IsPopped
+ {
+ get { return _isPopped; }
+ set
+ {
+ _isPopped = value;
+
+ if (_isPopped) {
+ onPop (this, null);
+ NotifyValueChanged ("SvgSub", "expanded");
+ return;
+ }
+
+ onUnpop (this, null);
+ NotifyValueChanged ("SvgSub", "collapsed");
+ }
+ }
+
+ void itemClick(object sender, OpenTK.Input.MouseButtonEventArgs e){
+ object datasource = (sender as GraphicObject).DataSource;
+ SelectedItem = datasource;
+ IsPopped = false;
+ //Debug.WriteLine ((sender as GraphicObject).DataSource);
+ }
+ void _overlay_MouseLeave (object sender, MouseMoveEventArgs e)
+ {
+ IsPopped = false;
+ }
+ void _overlay_LayoutChanged (object sender, LayoutChangeEventArgs e)
+ {
+ ILayoutable tc = Overlay.Parent as ILayoutable;
+ if (tc == null)
+ return;
+ Rectangle r = this.ScreenCoordinates (this.Slot);
+ if (e.LayoutType == LayoutingType.Width) {
+ if (Overlay.Slot.Width < tc.ClientRectangle.Width) {
+ if (r.Left + Overlay.Slot.Width > tc.ClientRectangle.Right)
+ Overlay.Left = tc.ClientRectangle.Right - Overlay.Slot.Width;
+ else
+ Overlay.Left = r.Left;
+ }else
+ Overlay.Left = 0;
+ }else if (e.LayoutType == LayoutingType.Height) {
+ if (Overlay.Slot.Height < tc.ClientRectangle.Height) {
+ if (r.Bottom + Overlay.Slot.Height > tc.ClientRectangle.Bottom)
+ Overlay.Top = r.Top - Overlay.Slot.Height;
+ else
+ Overlay.Top = r.Bottom;
+ }else
+ Overlay.Top = 0;
+ }
+ }
+
+ [XmlAttributeAttribute()][DefaultValue(true)]//overiden to get default to true
+ public override bool Focusable
+ {
+ get { return base.Focusable; }
+ set { base.Focusable = value; }
+ }
+
+
+ public virtual void onPop(object sender, EventArgs e)
+ {
+ IGOLibHost tc = HostContainer;
+ if (tc == null)
+ return;
+ if (Overlay != null) {
+ Overlay.Visible = true;
+ if (Overlay.Parent == null)
+ tc.AddWidget (Overlay);
+ (tc as OpenTKGameWindow).PutOnTop (Overlay);
+ }
+ Pop.Raise (this, e);
+ }
+ public virtual void onUnpop(object sender, EventArgs e)
+ {
+ IGOLibHost tc = HostContainer;
+ if (tc == null)
+ return;
+ Overlay.Visible = false;
+ Unpop.Raise (this, e);
+ }
+
+ public override void onMouseClick (object sender, MouseButtonEventArgs e)
+ {
+ IsPopped = !IsPopped;
+ base.onMouseClick (sender, e);
+ }
+
+ public override void ClearBinding ()
+ {
+ //ensure popped window is cleared
+ if (Overlay != null) {
+ if (Overlay.Parent != null) {
+ IGOLibHost tc = Overlay.Parent as IGOLibHost;
+ if (tc != null)
+ tc.DeleteWidget (Overlay);
+ }
+ }
+ base.ClearBinding ();
+
+ }
+ public override void ResolveBindings ()
+ {
+ base.ResolveBindings ();
+ if (Overlay != null)
+ Overlay.ResolveBindings ();
+ }
+ }
+}
diff --git a/src/GraphicObjects/Container.cs b/src/GraphicObjects/Container.cs
index 144eb764..360eee51 100644
--- a/src/GraphicObjects/Container.cs
+++ b/src/GraphicObjects/Container.cs
@@ -1,78 +1,78 @@
-using System;
-using System.Xml.Serialization;
-using System.Reflection;
-using OpenTK.Input;
-using System.ComponentModel;
-using System.Linq;
-
-namespace Crow
-{
- public class Container : PrivateContainer, IXmlSerializable
- {
- #region CTOR
- public Container()
- : base()
- {
- }
- public Container(Rectangle _bounds)
- : base(_bounds)
- {
- }
- #endregion
-
- [XmlIgnore]
- public GraphicObject Child {
- get { return child; }
- set { child = value; }
- }
- public virtual T SetChild<T> (T _child)
- {
- return base.SetChild (_child);
- }
-
- #region IXmlSerializable
-
- public override System.Xml.Schema.XmlSchema GetSchema()
- {
- return null;
- }
- public override void ReadXml(System.Xml.XmlReader reader)
- {
- //only read attributes in GraphicObject IXmlReader implementation
- base.ReadXml(reader);
-
-
- using (System.Xml.XmlReader subTree = reader.ReadSubtree())
- {
- subTree.Read(); //skip current node
- subTree.Read(); //read first child
-
- if (!subTree.IsStartElement())
- return;
-
- Type t = Type.GetType("Crow." + subTree.Name);
- GraphicObject go = (GraphicObject)Activator.CreateInstance(t);
-
- (go as IXmlSerializable).ReadXml(subTree);
-
- SetChild(go);
-
- subTree.Read();//closing tag
- }
- }
- public override void WriteXml(System.Xml.XmlWriter writer)
- {
- base.WriteXml(writer);
-
- if (Child == null)
- return;
-
- writer.WriteStartElement(Child.GetType().Name);
- (Child as IXmlSerializable).WriteXml(writer);
- writer.WriteEndElement();
- }
-
- #endregion
- }
-}
-
+using System;
+using System.Xml.Serialization;
+using System.Reflection;
+using OpenTK.Input;
+using System.ComponentModel;
+using System.Linq;
+
+namespace Crow
+{
+ public class Container : PrivateContainer, IXmlSerializable
+ {
+ #region CTOR
+ public Container()
+ : base()
+ {
+ }
+ public Container(Rectangle _bounds)
+ : base(_bounds)
+ {
+ }
+ #endregion
+
+ [XmlIgnore]
+ public GraphicObject Child {
+ get { return child; }
+ set { child = value; }
+ }
+ public virtual T SetChild<T> (T _child)
+ {
+ return base.SetChild (_child);
+ }
+
+ #region IXmlSerializable
+
+ public override System.Xml.Schema.XmlSchema GetSchema()
+ {
+ return null;
+ }
+ public override void ReadXml(System.Xml.XmlReader reader)
+ {
+ //only read attributes in GraphicObject IXmlReader implementation
+ base.ReadXml(reader);
+
+
+ using (System.Xml.XmlReader subTree = reader.ReadSubtree())
+ {
+ subTree.Read(); //skip current node
+ subTree.Read(); //read first child
+
+ if (!subTree.IsStartElement())
+ return;
+
+ Type t = Type.GetType("Crow." + subTree.Name);
+ GraphicObject go = (GraphicObject)Activator.CreateInstance(t);
+
+ (go as IXmlSerializable).ReadXml(subTree);
+
+ SetChild(go);
+
+ subTree.Read();//closing tag
+ }
+ }
+ public override void WriteXml(System.Xml.XmlWriter writer)
+ {
+ base.WriteXml(writer);
+
+ if (Child == null)
+ return;
+
+ writer.WriteStartElement(Child.GetType().Name);
+ (Child as IXmlSerializable).WriteXml(writer);
+ writer.WriteEndElement();
+ }
+
+ #endregion
+ }
+}
+
diff --git a/src/GraphicObjects/Expandable.cs b/src/GraphicObjects/Expandable.cs
index f1e2bdeb..f44e5e27 100644
--- a/src/GraphicObjects/Expandable.cs
+++ b/src/GraphicObjects/Expandable.cs
@@ -1,130 +1,130 @@
-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;
-using System.Xml.Serialization;
-using OpenTK.Input;
-using System.ComponentModel;
-using System.Xml;
-using System.IO;
-
-namespace Crow
-{
- [DefaultTemplate("#Crow.Templates.Expandable.goml")]
- public class Expandable : TemplatedContainer
- {
- bool _isExpanded;
- string caption;
- string image;
- Container _contentContainer;
-
- public event EventHandler Expand;
- public event EventHandler Collapse;
-
- public override GraphicObject Content {
- get {
- return _contentContainer == null ? null : _contentContainer.Child;
- }
- set {
- _contentContainer.SetChild(value);
- }
- }
-
- public Expandable() : base()
- {
- }
-
- protected override void loadTemplate(GraphicObject template = null)
- {
- base.loadTemplate (template);
-
- _contentContainer = this.child.FindByName ("Content") as Container;
- }
-
- [XmlAttributeAttribute()][DefaultValue(true)]//overiden to get default to true
- public override bool Focusable
- {
- get { return base.Focusable; }
- set { base.Focusable = value; }
- }
- [XmlAttributeAttribute()][DefaultValue(-1)]
- public override int Height {
- get { return base.Height; }
- set { base.Height = value; }
- }
-
- [XmlAttributeAttribute()][DefaultValue("Expandable")]
- public string Caption {
- get { return caption; }
- set {
- if (caption == value)
- return;
- caption = value;
- NotifyValueChanged ("Caption", caption);
- }
- }
- [XmlAttributeAttribute()][DefaultValue("#Crow.Images.Icons.expandable.svg")]
- public string Image {
- get { return image; }
- set {
- if (image == value)
- return;
- image = value;
- NotifyValueChanged ("Image", image);
- }
- }
- [XmlAttributeAttribute()][DefaultValue(false)]
- public bool IsExpanded
- {
- get { return _isExpanded; }
- set
- {
- _isExpanded = value;
-
- if (_isExpanded) {
- onExpand (this, null);
- NotifyValueChanged ("SvgSub", "expanded");
- return;
- }
-
- onCollapse (this, null);
- NotifyValueChanged ("SvgSub", "collapsed");
- }
- }
-
- public virtual void onExpand(object sender, EventArgs e)
- {
- if (_contentContainer != null)
- _contentContainer.Visible = true;
-
- Expand.Raise (this, e);
- }
- public virtual void onCollapse(object sender, EventArgs e)
- {
- if (_contentContainer != null)
- _contentContainer.Visible = false;
-
- Collapse.Raise (this, e);
- }
-
- public override void onMouseClick (object sender, MouseButtonEventArgs e)
- {
- IsExpanded = !IsExpanded;
- base.onMouseClick (sender, e);
- }
- public override void ResolveBindings ()
- {
- base.ResolveBindings ();
- if (Content != null)
- Content.ResolveBindings ();
- }
- }
-}
+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;
+using System.Xml.Serialization;
+using OpenTK.Input;
+using System.ComponentModel;
+using System.Xml;
+using System.IO;
+
+namespace Crow
+{
+ [DefaultTemplate("#Crow.Templates.Expandable.goml")]
+ public class Expandable : TemplatedContainer
+ {
+ bool _isExpanded;
+ string caption;
+ string image;
+ Container _contentContainer;
+
+ public event EventHandler Expand;
+ public event EventHandler Collapse;
+
+ public override GraphicObject Content {
+ get {
+ return _contentContainer == null ? null : _contentContainer.Child;
+ }
+ set {
+ _contentContainer.SetChild(value);
+ }
+ }
+
+ public Expandable() : base()
+ {
+ }
+
+ protected override void loadTemplate(GraphicObject template = null)
+ {
+ base.loadTemplate (template);
+
+ _contentContainer = this.child.FindByName ("Content") as Container;
+ }
+
+ [XmlAttributeAttribute()][DefaultValue(true)]//overiden to get default to true
+ public override bool Focusable
+ {
+ get { return base.Focusable; }
+ set { base.Focusable = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue(-1)]
+ public override int Height {
+ get { return base.Height; }
+ set { base.Height = value; }
+ }
+
+ [XmlAttributeAttribute()][DefaultValue("Expandable")]
+ public string Caption {
+ get { return caption; }
+ set {
+ if (caption == value)
+ return;
+ caption = value;
+ NotifyValueChanged ("Caption", caption);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue("#Crow.Images.Icons.expandable.svg")]
+ public string Image {
+ get { return image; }
+ set {
+ if (image == value)
+ return;
+ image = value;
+ NotifyValueChanged ("Image", image);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(false)]
+ public bool IsExpanded
+ {
+ get { return _isExpanded; }
+ set
+ {
+ _isExpanded = value;
+
+ if (_isExpanded) {
+ onExpand (this, null);
+ NotifyValueChanged ("SvgSub", "expanded");
+ return;
+ }
+
+ onCollapse (this, null);
+ NotifyValueChanged ("SvgSub", "collapsed");
+ }
+ }
+
+ public virtual void onExpand(object sender, EventArgs e)
+ {
+ if (_contentContainer != null)
+ _contentContainer.Visible = true;
+
+ Expand.Raise (this, e);
+ }
+ public virtual void onCollapse(object sender, EventArgs e)
+ {
+ if (_contentContainer != null)
+ _contentContainer.Visible = false;
+
+ Collapse.Raise (this, e);
+ }
+
+ public override void onMouseClick (object sender, MouseButtonEventArgs e)
+ {
+ IsExpanded = !IsExpanded;
+ base.onMouseClick (sender, e);
+ }
+ public override void ResolveBindings ()
+ {
+ base.ResolveBindings ();
+ if (Content != null)
+ Content.ResolveBindings ();
+ }
+ }
+}
diff --git a/src/GraphicObjects/GenericStack.cs b/src/GraphicObjects/GenericStack.cs
index 1624c530..53aff76b 100644
--- a/src/GraphicObjects/GenericStack.cs
+++ b/src/GraphicObjects/GenericStack.cs
@@ -1,178 +1,178 @@
-using System;
-using System.Diagnostics;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Xml.Serialization;
-using System.ComponentModel;
-
-namespace Crow
-{
- public class GenericStack : Group
- {
- internal class Page
- {
- public byte[] bmp;
- public int Size;
- }
-
- #region CTOR
- public GenericStack()
- : base()
- {
- }
- #endregion
-
- #region Private fields
- int _spacing;
- Orientation _orientation;
- #endregion
-
- public override T addChild<T> (T child)
- {
- T tmp = base.addChild (child);
- this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
- return tmp;
- }
- public override void removeChild (GraphicObject child)
- {
- base.removeChild (child);
- this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
- }
-
- #region Public Properties
- [XmlAttributeAttribute()][DefaultValue(2)]
- public int Spacing
- {
- get { return _spacing; }
- set {
- if (_spacing == value)
- return;
- _spacing = value;
- NotifyValueChanged ("Spacing", Spacing);
- }
- }
- [XmlAttributeAttribute()][DefaultValue(Orientation.Horizontal)]
- public virtual Orientation Orientation
- {
- get { return _orientation; }
- set { _orientation = value; }
- }
- #endregion
-
- #region GraphicObject Overrides
- protected override Size measureRawSize ()
- {
- Size tmp = new Size ();
-
- if (Orientation == Orientation.Horizontal) {
- foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
- tmp.Width += c.Slot.Width + Spacing;
- tmp.Height = Math.Max (tmp.Height, Math.Max(c.Slot.Bottom, c.Slot.Height));
- }
- if (tmp.Width > 0)
- tmp.Width -= Spacing;
- } else {
- foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
- tmp.Width = Math.Max (tmp.Width, Math.Max(c.Slot.Right, c.Slot.Width));
- tmp.Height += c.Slot.Height + Spacing;
- }
- if (tmp.Height > 0)
- tmp.Height -= Spacing;
- }
-
- tmp.Width += 2 * Margin;
- tmp.Height += 2 * Margin;
-
- return tmp;
- }
- public virtual void ComputeChildrenPositions()
- {
- #if DEBUG_LAYOUTING
- Debug.WriteLine("ComputeChildrenPosition: " + this.ToString());
- #endif
- int d = 0;
- if (Orientation == Orientation.Horizontal) {
- foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
- c.Slot.X = d;
- d += c.Slot.Width + Spacing;
- c.RegisterForLayouting ((int)LayoutingType.Y);
- }
- } else {
- foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
- c.Slot.Y = d;
- d += c.Slot.Height + Spacing;
- c.RegisterForLayouting ((int)LayoutingType.X);
- }
- }
- }
-
- public override void RegisterForLayouting (int layoutType)
- {
- if (Parent == null)
- return;
-
- base.RegisterForLayouting (layoutType);
-
- if ((layoutType & (int)LayoutingType.PositionChildren) > 0)
- Interface.LayoutingQueue.Enqueue (LayoutingType.PositionChildren, this);
-
- }
- public override void UpdateLayout (LayoutingType layoutType)
- {
- if (layoutType == LayoutingType.PositionChildren) {
- //allow 1 child to have size to 0 if stack has fixed or streched size,
- //this child will occupy remaining space
- if (Orientation == Orientation.Horizontal) {
- if (Width >= 0) {
- GraphicObject[] gobjs = Children.Where (c => c.Width == 0 && c.Visible).ToArray();
- if (gobjs.Length > 1)
- throw new Exception ("Only one child in stack may have size to stretched");
- else if (gobjs.Length == 1) {
- int sz = Children.Where(ch=>ch.Visible).Except (gobjs).Sum (g => g.Slot.Width);
- if (sz < Slot.Width) {
- gobjs [0].Slot.Width = Slot.Width - sz - (Children.Count-1) * Spacing - 2 * Margin;
- int idx = Children.IndexOf (gobjs [0]);
- if (idx > 0 && idx < Children.Count - 1)
- gobjs [0].Slot.Width -= Spacing;
- if (gobjs [0].LastSlots.Width != gobjs [0].Slot.Width) {
- gobjs [0].bmp = null;
- gobjs [0].OnLayoutChanges (LayoutingType.Width);
- gobjs [0].LastSlots.Width = gobjs [0].Slot.Width;
- }
- }
- }
- }
- } else {
- if (Height >= 0) {
- GraphicObject[] gobjs = Children.Where(ch=>ch.Visible).Where (c => c.Height == 0).ToArray();
- if (gobjs.Length > 1)
- throw new Exception ("Only one child in stack may have size to stretched");
- else if (gobjs.Length == 1) {
- int sz = Children.Where(ch=>ch.Visible).Except (gobjs).Sum (g => g.Slot.Height);
- if (sz < Slot.Height) {
- gobjs [0].Slot.Height = Slot.Height - sz- (Children.Count-1) * Spacing - 2 * Margin;
- int idx = Children.IndexOf (gobjs [0]);
- if (idx > 0 && idx < Children.Count - 1)
- gobjs [0].Slot.Height -= Spacing;
- if (gobjs [0].LastSlots.Height != gobjs [0].Slot.Height) {
- gobjs [0].bmp = null;
- gobjs [0].OnLayoutChanges (LayoutingType.Height);
- gobjs [0].LastSlots.Height = gobjs [0].Slot.Height;
- }
- }
- }
- }
- }
- ComputeChildrenPositions ();
- //if no layouting remains in queue for item, registre for redraw
- if (Interface.LayoutingQueue.Where (lq => lq.GraphicObject == this).Count () <= 0 && bmp==null)
- this.RegisterForRedraw ();
- }else
- base.UpdateLayout(layoutType);
- }
- #endregion
-
-
- }
-}
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml.Serialization;
+using System.ComponentModel;
+
+namespace Crow
+{
+ public class GenericStack : Group
+ {
+ internal class Page
+ {
+ public byte[] bmp;
+ public int Size;
+ }
+
+ #region CTOR
+ public GenericStack()
+ : base()
+ {
+ }
+ #endregion
+
+ #region Private fields
+ int _spacing;
+ Orientation _orientation;
+ #endregion
+
+ public override T addChild<T> (T child)
+ {
+ T tmp = base.addChild (child);
+ this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
+ return tmp;
+ }
+ public override void removeChild (GraphicObject child)
+ {
+ base.removeChild (child);
+ this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
+ }
+
+ #region Public Properties
+ [XmlAttributeAttribute()][DefaultValue(2)]
+ public int Spacing
+ {
+ get { return _spacing; }
+ set {
+ if (_spacing == value)
+ return;
+ _spacing = value;
+ NotifyValueChanged ("Spacing", Spacing);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(Orientation.Horizontal)]
+ public virtual Orientation Orientation
+ {
+ get { return _orientation; }
+ set { _orientation = value; }
+ }
+ #endregion
+
+ #region GraphicObject Overrides
+ protected override Size measureRawSize ()
+ {
+ Size tmp = new Size ();
+
+ if (Orientation == Orientation.Horizontal) {
+ foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
+ tmp.Width += c.Slot.Width + Spacing;
+ tmp.Height = Math.Max (tmp.Height, Math.Max(c.Slot.Bottom, c.Slot.Height));
+ }
+ if (tmp.Width > 0)
+ tmp.Width -= Spacing;
+ } else {
+ foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
+ tmp.Width = Math.Max (tmp.Width, Math.Max(c.Slot.Right, c.Slot.Width));
+ tmp.Height += c.Slot.Height + Spacing;
+ }
+ if (tmp.Height > 0)
+ tmp.Height -= Spacing;
+ }
+
+ tmp.Width += 2 * Margin;
+ tmp.Height += 2 * Margin;
+
+ return tmp;
+ }
+ public virtual void ComputeChildrenPositions()
+ {
+ #if DEBUG_LAYOUTING
+ Debug.WriteLine("ComputeChildrenPosition: " + this.ToString());
+ #endif
+ int d = 0;
+ if (Orientation == Orientation.Horizontal) {
+ foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
+ c.Slot.X = d;
+ d += c.Slot.Width + Spacing;
+ c.RegisterForLayouting ((int)LayoutingType.Y);
+ }
+ } else {
+ foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
+ c.Slot.Y = d;
+ d += c.Slot.Height + Spacing;
+ c.RegisterForLayouting ((int)LayoutingType.X);
+ }
+ }
+ }
+
+ public override void RegisterForLayouting (int layoutType)
+ {
+ if (Parent == null)
+ return;
+
+ base.RegisterForLayouting (layoutType);
+
+ if ((layoutType & (int)LayoutingType.PositionChildren) > 0)
+ Interface.LayoutingQueue.Enqueue (LayoutingType.PositionChildren, this);
+
+ }
+ public override void UpdateLayout (LayoutingType layoutType)
+ {
+ if (layoutType == LayoutingType.PositionChildren) {
+ //allow 1 child to have size to 0 if stack has fixed or streched size,
+ //this child will occupy remaining space
+ if (Orientation == Orientation.Horizontal) {
+ if (Width >= 0) {
+ GraphicObject[] gobjs = Children.Where (c => c.Width == 0 && c.Visible).ToArray();
+ if (gobjs.Length > 1)
+ throw new Exception ("Only one child in stack may have size to stretched");
+ else if (gobjs.Length == 1) {
+ int sz = Children.Where(ch=>ch.Visible).Except (gobjs).Sum (g => g.Slot.Width);
+ if (sz < Slot.Width) {
+ gobjs [0].Slot.Width = Slot.Width - sz - (Children.Count-1) * Spacing - 2 * Margin;
+ int idx = Children.IndexOf (gobjs [0]);
+ if (idx > 0 && idx < Children.Count - 1)
+ gobjs [0].Slot.Width -= Spacing;
+ if (gobjs [0].LastSlots.Width != gobjs [0].Slot.Width) {
+ gobjs [0].bmp = null;
+ gobjs [0].OnLayoutChanges (LayoutingType.Width);
+ gobjs [0].LastSlots.Width = gobjs [0].Slot.Width;
+ }
+ }
+ }
+ }
+ } else {
+ if (Height >= 0) {
+ GraphicObject[] gobjs = Children.Where(ch=>ch.Visible).Where (c => c.Height == 0).ToArray();
+ if (gobjs.Length > 1)
+ throw new Exception ("Only one child in stack may have size to stretched");
+ else if (gobjs.Length == 1) {
+ int sz = Children.Where(ch=>ch.Visible).Except (gobjs).Sum (g => g.Slot.Height);
+ if (sz < Slot.Height) {
+ gobjs [0].Slot.Height = Slot.Height - sz- (Children.Count-1) * Spacing - 2 * Margin;
+ int idx = Children.IndexOf (gobjs [0]);
+ if (idx > 0 && idx < Children.Count - 1)
+ gobjs [0].Slot.Height -= Spacing;
+ if (gobjs [0].LastSlots.Height != gobjs [0].Slot.Height) {
+ gobjs [0].bmp = null;
+ gobjs [0].OnLayoutChanges (LayoutingType.Height);
+ gobjs [0].LastSlots.Height = gobjs [0].Slot.Height;
+ }
+ }
+ }
+ }
+ }
+ ComputeChildrenPositions ();
+ //if no layouting remains in queue for item, registre for redraw
+ if (Interface.LayoutingQueue.Where (lq => lq.GraphicObject == this).Count () <= 0 && bmp==null)
+ this.RegisterForRedraw ();
+ }else
+ base.UpdateLayout(layoutType);
+ }
+ #endregion
+
+
+ }
+}
diff --git a/src/GraphicObjects/GraduatedSlider.cs b/src/GraphicObjects/GraduatedSlider.cs
index 9ed5e19e..3d916a8c 100644
--- a/src/GraphicObjects/GraduatedSlider.cs
+++ b/src/GraphicObjects/GraduatedSlider.cs
@@ -1,54 +1,54 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Cairo;
-using System.Xml.Serialization;
-
-namespace Crow
-{
- public class GraduatedSlider : Slider
- {
- #region CTOR
- public GraduatedSlider() : base()
- {}
- public GraduatedSlider(double minimum, double maximum, double step)
- : base()
- {
- Minimum = minimum;
- Maximum = maximum;
- SmallIncrement = step;
- LargeIncrement = step * 5;
- }
- #endregion
-
- protected override void DrawGraduations(Context gr, PointD pStart, PointD pEnd)
- {
- Rectangle r = ClientRectangle;
- gr.SetSourceColor(Foreground);
-
- gr.LineWidth = 2;
- gr.MoveTo(pStart);
- gr.LineTo(pEnd);
-
- gr.Stroke();
- gr.LineWidth = 1;
-
- double sst = unity * SmallIncrement;
- double bst = unity * LargeIncrement;
-
-
- PointD vBar = new PointD(0, sst);
- for (double x = Minimum; x <= Maximum - Minimum; x += SmallIncrement)
- {
- double lineLength = r.Height / 3;
- if (x % LargeIncrement != 0)
- lineLength /= 3;
- PointD p = new PointD(pStart.X + x * unity, pStart.Y);
- gr.MoveTo(p);
- gr.LineTo(new PointD(p.X, p.Y + lineLength));
- }
- gr.Stroke();
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Cairo;
+using System.Xml.Serialization;
+
+namespace Crow
+{
+ public class GraduatedSlider : Slider
+ {
+ #region CTOR
+ public GraduatedSlider() : base()
+ {}
+ public GraduatedSlider(double minimum, double maximum, double step)
+ : base()
+ {
+ Minimum = minimum;
+ Maximum = maximum;
+ SmallIncrement = step;
+ LargeIncrement = step * 5;
+ }
+ #endregion
+
+ protected override void DrawGraduations(Context gr, PointD pStart, PointD pEnd)
+ {
+ Rectangle r = ClientRectangle;
+ gr.SetSourceColor(Foreground);
+
+ gr.LineWidth = 2;
+ gr.MoveTo(pStart);
+ gr.LineTo(pEnd);
+
+ gr.Stroke();
+ gr.LineWidth = 1;
+
+ double sst = unity * SmallIncrement;
+ double bst = unity * LargeIncrement;
+
+
+ PointD vBar = new PointD(0, sst);
+ for (double x = Minimum; x <= Maximum - Minimum; x += SmallIncrement)
+ {
+ double lineLength = r.Height / 3;
+ if (x % LargeIncrement != 0)
+ lineLength /= 3;
+ PointD p = new PointD(pStart.X + x * unity, pStart.Y);
+ gr.MoveTo(p);
+ gr.LineTo(new PointD(p.X, p.Y + lineLength));
+ }
+ gr.Stroke();
+ }
+ }
+}
diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs
index cef2c501..5613c0c9 100644
--- a/src/GraphicObjects/GraphicObject.cs
+++ b/src/GraphicObjects/GraphicObject.cs
@@ -1,1381 +1,1381 @@
-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;
-
-using System.Xml.Serialization;
-using System.Reflection;
-using System.ComponentModel;
-using System.IO;
-//using System.Xml;
-using System.Xml;
-using System.Runtime.CompilerServices;
-using System.Reflection.Emit;
-
-namespace Crow
-{
- public class GraphicObject : IXmlSerializable, ILayoutable, IValueChange
- {
- #if DEBUG_LAYOUTING
- internal static ulong currentUid = 0;
- internal ulong uid = 0;
- #endif
-
- internal List<Binding> Bindings = new List<Binding> ();
-
- #region IValueChange implementation
- public event EventHandler<ValueChangeEventArgs> ValueChanged;
- public virtual void NotifyValueChanged(string MemberName, object _value)
- {
- ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value));
- }
- #endregion
-
- #region CTOR
- public GraphicObject ()
- {
- #if DEBUG_LAYOUTING
- uid = currentUid;
- currentUid++;
- #endif
-
- if (Interface.XmlSerializerInit)
- return;
-
- loadDefaultValues ();
- registerForGraphicUpdate ();
- }
- public GraphicObject (Rectangle _bounds)
- {
- if (Interface.XmlSerializerInit)
- return;
-
- loadDefaultValues ();
- Bounds = _bounds;
- registerForGraphicUpdate ();
- }
- #endregion
-
- #region private fields
- ILayoutable _parent;
- string _name = "unamed";
- Color _background = Color.Transparent;
- Color _foreground = Color.White;
- Font _font = "droid, 10";
- double _cornerRadius = 0;
- int _margin = 0;
- bool _focusable = false;
- bool _hasFocus = false;
- bool _mouseRepeat;
- protected bool _isVisible = true;
- VerticalAlignment _verticalAlignment = VerticalAlignment.Center;
- HorizontalAlignment _horizontalAlignment = HorizontalAlignment.Center;
- Size _maximumSize = "0;0";
- Size _minimumSize = "0;0";
-
- Picture _backgroundImage;
- string _backgroundImagePath;
- #endregion
-
- #region public fields
- public GraphicObject LogicalParent;
- public Rectangle Bounds;
- public Rectangle Slot = new Rectangle ();
- public object Tag;
- public byte[] bmp;
- #endregion
-
- #region ILayoutable
- //TODO: it would save the recurent cost of a cast in event bubbling if parent type was GraphicObject
- // or we could add to the interface the mouse events
- [XmlIgnore]public ILayoutable Parent {
- get { return _parent; }
- set {
-// if (_parent == value)
-// return;
-// if (_parent != null)
-// ClearBinding ();
-//
- _parent = value;
-//
-// if (DataSource != null)
-// ResolveBindings ();
- }
- }
-
-
- [XmlIgnore]public virtual Rectangle ClientRectangle {
- get {
- Rectangle cb = Slot.Size;
- cb.Inflate ( - Margin);
- return cb;
- }
- }
- [XmlIgnore]public virtual IGOLibHost HostContainer {
- get { return Parent == null ? null : Parent.HostContainer; }
- }
- public virtual Rectangle ContextCoordinates(Rectangle r){
- return
- Parent.ContextCoordinates (r);// + ClientRectangle.Position;
- }
- public virtual Rectangle ScreenCoordinates (Rectangle r){
- //r += Slot.Position;
-
- return
- Parent.ScreenCoordinates(r) + Parent.getSlot().Position + Parent.ClientRectangle.Position;
- }
- public virtual Rectangle getSlot()
- {
- return Slot;
- }
- public virtual Rectangle getBounds()
- {
- return Bounds;
- }
- #endregion
-
- #region EVENT HANDLERS
- public event EventHandler<MouseWheelEventArgs> MouseWheelChanged;
- public event EventHandler<MouseButtonEventArgs> MouseUp;
- public event EventHandler<MouseButtonEventArgs> MouseDown;
- public event EventHandler<MouseButtonEventArgs> MouseClick;
- public event EventHandler<MouseMoveEventArgs> MouseMove;
- public event EventHandler<MouseMoveEventArgs> MouseEnter;
- public event EventHandler<MouseMoveEventArgs> MouseLeave;
- public event EventHandler<KeyboardKeyEventArgs> KeyDown;
- public event EventHandler<KeyboardKeyEventArgs> KeyUp;
- public event EventHandler Focused;
- public event EventHandler Unfocused;
- public event EventHandler<LayoutChangeEventArgs> LayoutChanged;
- #endregion
-
- #region public properties
- [XmlAttributeAttribute()][DefaultValue("unamed")]
- public virtual string Name {
- get { return _name; }
- set {
- if (_name == value)
- return;
- _name = value;
- NotifyValueChanged("Name", _verticalAlignment);
- }
- }
- [XmlAttributeAttribute ()][DefaultValue(VerticalAlignment.Center)]
- public virtual VerticalAlignment VerticalAlignment {
- get { return _verticalAlignment; }
- set {
- if (_verticalAlignment == value)
- return;
-
- _verticalAlignment = value;
- NotifyValueChanged("VerticalAlignment", _verticalAlignment);
- }
- }
- [XmlAttributeAttribute()][DefaultValue(HorizontalAlignment.Center)]
- public virtual HorizontalAlignment HorizontalAlignment {
- get { return _horizontalAlignment; }
- set {
- if (_horizontalAlignment == value)
- return;
-
- _horizontalAlignment = value;
- NotifyValueChanged("HorizontalAlignment", _horizontalAlignment);
- }
- }
- [XmlAttributeAttribute()][DefaultValue(0)]
- public virtual int Left {
- get { return Bounds.X; }
- set {
- if (Bounds.X == value)
- return;
-
- Bounds.X = value;
- NotifyValueChanged ("Left", Bounds.X);
- this.RegisterForLayouting ((int)LayoutingType.X);
- }
- }
- [XmlAttributeAttribute()][DefaultValue(0)]
- public virtual int Top {
- get { return Bounds.Y; }
- set {
- if (Bounds.Y == value)
- return;
-
- Bounds.Y = value;
- NotifyValueChanged ("Top", Bounds.Y);
- this.RegisterForLayouting ((int)LayoutingType.Y);
- }
- }
- [XmlAttributeAttribute()][DefaultValue(0)]
- public virtual int Width {
- get { return Bounds.Width; }
- set {
- if (Bounds.Width == value)
- return;
-
- Bounds.Width = value;
- NotifyValueChanged ("Width", Bounds.Width);
- this.RegisterForLayouting ((int)LayoutingType.Width);
- }
- }
- [XmlAttributeAttribute()][DefaultValue(0)]
- public virtual int Height {
- get { return Bounds.Height; }
- set {
- if (Bounds.Height == value)
- return;
-
- Bounds.Height = value;
- NotifyValueChanged ("Height", Bounds.Height);
- this.RegisterForLayouting ((int)LayoutingType.Height);
- }
- }
- [XmlAttributeAttribute()][DefaultValue(false)]
- public virtual bool Fit {
- get { return Bounds.Width < 0 && Bounds.Height < 0 ? true : false; }
- set {
- if (value == Fit)
- return;
-
- Bounds.Width = Bounds.Height = -1;
- }
- }
- [XmlAttributeAttribute()][DefaultValue(false)]
- public virtual bool Focusable {
- get { return _focusable; }
- set {
- if (_focusable == value)
- return;
- _focusable = value;
- NotifyValueChanged ("Focusable", _focusable);
- }
- }
- [XmlIgnore]public virtual bool HasFocus {
- get { return _hasFocus; }
- set {
- if (value == _hasFocus)
- return;
-
- _hasFocus = value;
- NotifyValueChanged ("HasFocus", _hasFocus);
- }
- }
- [XmlAttributeAttribute()][DefaultValue(false)]
- public virtual bool MouseRepeat {
- get { return _mouseRepeat; }
- set {
- if (_mouseRepeat == value)
- return;
- _mouseRepeat = value;
- NotifyValueChanged ("MouseRepeat", _mouseRepeat);
- }
- }
- [XmlAttributeAttribute()][DefaultValue("Transparent")]
- public virtual Color Background {
- get { return _background; }
- set {
- if (_background == value)
- return;
- _background = value;
- NotifyValueChanged ("Background", _background);
- registerForGraphicUpdate ();
- }
- }
- [XmlAttributeAttribute()][DefaultValue("White")]
- public virtual Color Foreground {
- get { return _foreground; }
- set {
- if (_foreground == value)
- return;
- _foreground = value;
- NotifyValueChanged ("Foreground", _foreground);
- registerForGraphicUpdate ();
- }
- }
- [XmlAttributeAttribute()][DefaultValue("droid,10")]
- public virtual Font Font {
- get { return _font; }
- set {
- if (value == _font)
- return;
- _font = value;
- NotifyValueChanged ("Font", _font);
- registerForGraphicUpdate ();
- }
- }
- [XmlAttributeAttribute()][DefaultValue(0.0)]
- public virtual double CornerRadius {
- get { return _cornerRadius; }
- set {
- if (value == _cornerRadius)
- return;
- _cornerRadius = value;
- NotifyValueChanged ("CornerRadius", _cornerRadius);
- registerForGraphicUpdate ();
- }
- }
- [XmlAttributeAttribute()][DefaultValue(0)]
- public virtual int Margin {
- get { return _margin; }
- set {
- if (value == _margin)
- return;
- _margin = value;
- NotifyValueChanged ("Margin", _margin);
- registerForGraphicUpdate ();
- }
- }
- [XmlAttributeAttribute()][DefaultValue(true)]
- public virtual bool Visible {
- get { return _isVisible; }
- set {
- if (value == _isVisible)
- return;
-
- _isVisible = value;
-
- if (HostContainer == null)
- return;
- //add slot to clipping to redraw
- HostContainer.gobjsToRedraw.Add (this);
-
- //ensure main win doesn't keep hidden childrens ref
- if (this.Contains (HostContainer.hoverWidget))
- HostContainer.hoverWidget = null;
- if (Parent is GenericStack)
- Parent.RegisterForLayouting ((int)LayoutingType.Sizing | (int)LayoutingType.PositionChildren);
-
- NotifyValueChanged ("Visible", _isVisible);
- }
- }
- //TODO: only used in group, should be removed from base go object
- [XmlIgnore]public virtual bool DrawingIsValid
- { get { return bmp == null ?
- false :
- true; } }
- [XmlAttributeAttribute()][DefaultValue("0;0")]
- public virtual Size MaximumSize {
- get { return _maximumSize; }
- set { _maximumSize = value; }
- }
- [XmlAttributeAttribute()][DefaultValue("0;0")]
- public virtual Size MinimumSize {
- get { return _minimumSize; }
- set { _minimumSize = value; }
- }
- object dataSource;
-
- [XmlIgnore]public virtual object DataSource {
- set {
- if (dataSource == value)
- return;
-
- if (dataSource != null)
- this.ClearBinding ();
-
- dataSource = value;
-
- if (dataSource != null)
- this.ResolveBindings();
- }
- get {
- return dataSource == null ?
- LogicalParent == null ?
- Parent is GraphicObject ? (Parent as GraphicObject).DataSource : null : LogicalParent.DataSource : dataSource;
- }
- }
- #endregion
-
-
- /// <summary>
- /// Loads the default values from XML attributes default
- /// </summary>
- protected virtual void loadDefaultValues()
- {
- foreach (PropertyInfo pi in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
- if (pi.GetSetMethod () == null)
- continue;
- string name = "";
-
- object[] att = pi.GetCustomAttributes (false);
-
- foreach (object o in att) {
- XmlAttributeAttribute xaa = o as XmlAttributeAttribute;
- if (xaa != null) {
- if (string.IsNullOrEmpty (xaa.AttributeName))
- name = pi.Name;
- else
- name = xaa.AttributeName;
- continue;
- }
-
- XmlIgnoreAttribute xia = o as XmlIgnoreAttribute;
- if (xia != null)
- continue;
-
- DefaultValueAttribute dv = o as DefaultValueAttribute;
- if (dv != null) {
- object defaultValue = dv.Value;
- //avoid system types automaticaly converted by parser
- if (defaultValue != null && !pi.PropertyType.Namespace.StartsWith("System")) {
- if (pi.PropertyType != defaultValue.GetType()) {
- MethodInfo miParse = pi.PropertyType.GetMethod ("Parse", BindingFlags.Static | BindingFlags.Public);
- if (miParse != null) {
- pi.SetValue (this, miParse.Invoke (null, new object[]{ defaultValue }), null);
- continue;
- }
- }
- }
- pi.SetValue (this, defaultValue, null);
- }
- }
- }
- }
-
- public virtual GraphicObject FindByName(string nameToFind){
- return nameToFind == _name ? this : null;
- }
- public virtual bool Contains(GraphicObject goToFind){
- return false;
- }
-
-
- /// <summary>
- /// Clear chached object and add clipping region in redraw list of interface
- /// </summary>
- public virtual void registerForGraphicUpdate ()
- {
- bmp = null;
- if (HostContainer != null)
- HostContainer.gobjsToRedraw.Add (this);
- }
- /// <summary>
- /// Add clipping region in redraw list of interface, dont update cached object content
- /// </summary>
- public virtual void RegisterForRedraw ()
- {
- if (HostContainer != null)
- HostContainer.gobjsToRedraw.Add (this);
- }
-
- /// <summary>
- /// keep last slot components for each layouting pass to track
- /// changes and trigger update of other component accordingly
- /// </summary>
- public Rectangle LastSlots;
- /// <summary>
- /// keep last slot painted on screen to clear traces if moved or resized
- /// TODO: we should ensure the whole parsed widget tree is the last painted
- /// version to clear effective oldslot if parents have been moved or resized.
- /// IDEA is to add a ScreenCoordinates function that use only lastPaintedSlots
- /// </summary>
- public Rectangle LastPaintedSlot;
-
- public virtual void registerClipRect()
- {
- HostContainer.redrawClip.AddRectangle (ScreenCoordinates(Slot));
- //this clipping should take only last painted slots in ancestor tree which
- //is not the case for now.
- HostContainer.redrawClip.AddRectangle (ScreenCoordinates(LastPaintedSlot));
- }
- /// <summary> return size of content + margins </summary>
- protected virtual Size measureRawSize ()
- {
- return Bounds.Size;
- }
- /// <summary> clear current layoutingQueue items for object and
- /// trigger a new layouting pass for a layoutType </summary>
- public virtual void RegisterForLayouting(int layoutType)
- {
- if (Parent == null)
- return;
- #if DEBUG_LAYOUTING
- Debug.WriteLine ("RegisterForLayouting => {1}->{0}", layoutType, this.ToString());
- #endif
- lock (Interface.LayoutingQueue) {
- Interface.LayoutingQueue.RemoveAll (lq => lq.GraphicObject == this && (layoutType & (int)lq.LayoutType) > 0);
-
- if ((layoutType & (int)LayoutingType.Width) > 0) {
- if (Bounds.Width == 0) //stretch in parent
- Interface.LayoutingQueue.EnqueueAfterParentSizing (LayoutingType.Width, this);
- else if (Bounds.Width < 0) //fit
- Interface.LayoutingQueue.EnqueueBeforeParentSizing (LayoutingType.Width, this);
- else
- Interface.LayoutingQueue.Insert (0, new LayoutingQueueItem (LayoutingType.Width, this));
- }
-
- if ((layoutType & (int)LayoutingType.Height) > 0) {
- if (Bounds.Height == 0) //stretch in parent
- Interface.LayoutingQueue.EnqueueAfterParentSizing (LayoutingType.Height, this);
- else if (Bounds.Height < 0) //fit
- Interface.LayoutingQueue.EnqueueBeforeParentSizing (LayoutingType.Height, this);
- else
- Interface.LayoutingQueue.Insert (0, new LayoutingQueueItem (LayoutingType.Height, this));
- }
-
- if ((layoutType & (int)LayoutingType.X) > 0)
- //for x positionning, sizing of parent and this have to be done
- Interface.LayoutingQueue.EnqueueAfterThisAndParentSizing (LayoutingType.X, this);
-
- if ((layoutType & (int)LayoutingType.Y) > 0)
- //for x positionning, sizing of parent and this have to be done
- Interface.LayoutingQueue.EnqueueAfterThisAndParentSizing (LayoutingType.Y, this);
- }
- }
-
- /// <summary> trigger dependant sizing component update </summary>
- public virtual void OnLayoutChanges(LayoutingType layoutType)
- {
- if (Parent==null)
- return;
- #if DEBUG_LAYOUTING
- Debug.WriteLine ("Layout change: " + this.ToString () + ":" + LastSlots.ToString() + "=>" + Slot.ToString ());
- #endif
-
- switch (layoutType) {
- case LayoutingType.Width:
- if (Parent.getBounds ().Width < 0) {
- Group gw = Parent as Group;
- if (gw != null) {
- if (Slot.Width > gw.maxChildrenWidth)
- gw.maxChildrenWidth = Slot.Width;
- }
- this.Parent.RegisterForLayouting ((int)LayoutingType.Width);
- }else if (Width != 0) //update position in parent
- this.RegisterForLayouting ((int)LayoutingType.X);
- GenericStack gsw = Parent as GenericStack;
- if (gsw == null)
- break;
- if ((Parent as GenericStack).Orientation == Orientation.Horizontal) {
-// ulong idx = (ulong)gsw.Children.IndexOf (this);
-// if (idx < gsw.stackingUpdateStartIndex)
-// gsw.stackingUpdateStartIndex = idx;
- this.Parent.RegisterForLayouting ((int)LayoutingType.PositionChildren);
- }
- break;
- case LayoutingType.Height:
- if (Parent.getBounds ().Height < 0) {
- Group gh = Parent as Group;
- if (gh != null) {
- if (Slot.Width > gh.maxChildrenHeight)
- gh.maxChildrenHeight = Slot.Height;
- }
- this.Parent.RegisterForLayouting ((int)LayoutingType.Height);
- }else if (Height != 0) //update position in parent
- this.RegisterForLayouting ((int)LayoutingType.Y);
- GenericStack gsh = Parent as GenericStack;
- if (gsh==null)
- break;
- if (gsh.Orientation == Orientation.Vertical) {
-// ulong idx = (ulong)gsh.Children.IndexOf (this);
-// if (idx < gsh.stackingUpdateStartIndex)
-// gsh.stackingUpdateStartIndex = idx;
- this.Parent.RegisterForLayouting ((int)LayoutingType.PositionChildren);
- }
- break;
- }
- LayoutChanged.Raise (this, new LayoutChangeEventArgs (layoutType));
- }
- /// <summary> Update layout component, this is where the computation of alignement
- /// and size take place </summary>
- public virtual void UpdateLayout (LayoutingType layoutType)
- {
- switch (layoutType) {
- case LayoutingType.X:
- if (Bounds.X == 0) {
- switch (HorizontalAlignment) {
- case HorizontalAlignment.Left:
- Slot.X = 0;
- break;
- case HorizontalAlignment.Right:
- Slot.X = Parent.ClientRectangle.Width - Slot.Width;
- break;
- case HorizontalAlignment.Center:
- Slot.X = Parent.ClientRectangle.Width / 2 - Slot.Width / 2;
- break;
- }
- } else
- Slot.X = Bounds.X;
-
- if (LastSlots.X == Slot.X)
- break;
-
- bmp = null;
-
- OnLayoutChanges (layoutType);
-
- LastSlots.X = Slot.X;
- break;
- case LayoutingType.Y:
- if (Bounds.Y == 0) {
- switch (VerticalAlignment) {
- case VerticalAlignment.Top:
- Slot.Y = 0;
- break;
- case VerticalAlignment.Bottom:
- Slot.Y = Parent.ClientRectangle.Height - Slot.Height;
- break;
- case VerticalAlignment.Center:
- Slot.Y = Parent.ClientRectangle.Height / 2 - Slot.Height / 2;
- break;
- }
- }else
- Slot.Y = Bounds.Y;
-
- if (LastSlots.Y == Slot.Y)
- break;
-
- bmp = null;
-
- OnLayoutChanges (layoutType);
-
- LastSlots.Y = Slot.Y;
- break;
- case LayoutingType.Width:
- //force sizing to fit if parent is sizing on children and
- //this object has stretched size
- if (Parent.getBounds ().Width < 0 && Width == 0)
- Width = -1;
-
- if (Width > 0)
- Slot.Width = Width;
- else if (Width < 0)
- Slot.Width = measureRawSize ().Width;
- else
- Slot.Width = Parent.ClientRectangle.Width;
-
- //size constrain
- if (Slot.Width < MinimumSize.Width)
- Slot.Width = MinimumSize.Width;
- else if (Slot.Width > MaximumSize.Width && MaximumSize.Width > 0)
- Slot.Width = MaximumSize.Width;
-
- if (LastSlots.Width == Slot.Width)
- break;
-
- bmp = null;
-
- OnLayoutChanges (layoutType);
-
- LastSlots.Width = Slot.Width;
- break;
- case LayoutingType.Height:
- //force sizing to fit if parent is sizing on children
- if (Parent.getBounds ().Height < 0 && Height == 0)
- Height = -1;
-
- if (Height > 0)
- Slot.Height = Height;
- else if (Height < 0)
- Slot.Height = measureRawSize ().Height;
- else
- Slot.Height = Parent.ClientRectangle.Height;
-
- //size constrain
- if (Slot.Height < MinimumSize.Height)
- Slot.Height = MinimumSize.Height;
- else if (Slot.Height > MaximumSize.Height && MaximumSize.Height > 0)
- Slot.Height = MaximumSize.Height;
-
-
- if (LastSlots.Height == Slot.Height)
- break;
-
- bmp = null;
-
- OnLayoutChanges (layoutType);
-
- LastSlots.Height = Slot.Height;
- break;
- }
- lock (Interface.LayoutingQueue) {
- //if no layouting remains in queue for item, registre for redraw
- if (Interface.LayoutingQueue.Where (lq => lq.GraphicObject == this).Count () <= 0 && bmp == null)
- this.RegisterForRedraw ();
- }
- }
-
- /// <summary> This is the common overridable drawing routine to create new widget </summary>
- protected virtual void onDraw(Context gr)
- {
- Rectangle rBack = new Rectangle (Slot.Size);
-
- Background.SetAsSource (gr);
- CairoHelpers.CairoRectangle(gr,rBack,_cornerRadius);
- gr.Fill ();
- }
-
- /// <summary>
- /// Interfal drawing context creation on a cached surface limited to slot size
- /// this trigger the effective drawing routine </summary>
- protected virtual void UpdateGraphic ()
- {
- LastPaintedSlot = Slot;
-
- int stride = 4 * Slot.Width;
-
- int bmpSize = Math.Abs (stride) * Slot.Height;
- bmp = new byte[bmpSize];
-
- using (ImageSurface draw =
- new ImageSurface(bmp, Format.Argb32, Slot.Width, Slot.Height, stride)) {
- using (Context gr = new Context (draw)) {
- gr.Antialias = Antialias.Subpixel;
- onDraw (gr);
- }
- draw.Flush ();
- //draw.WriteToPng ("/mnt/data/test.png");
- }
- }
- /// <summary> Chained painting routine on the parent context of the actual cached version
- /// of the widget </summary>
- public virtual void Paint (ref Context ctx, Rectangles clip = null)
- {
- if (!Visible)
- return;
-
- if (bmp == null)
- UpdateGraphic ();
-
- Rectangle rb = Parent.ContextCoordinates(Slot);
-
- using (ImageSurface source = new ImageSurface(bmp, Format.Argb32, Slot.Width, Slot.Height, 4 * Slot.Width)) {
- if (this.Background == Color.Clear) {
- ctx.Save ();
- ctx.Operator = Operator.Clear;
- ctx.Rectangle(rb);
- ctx.Fill ();
- ctx.Restore ();
- }
- ctx.SetSourceSurface (source, rb.X, rb.Y);
- ctx.Paint ();
- }
- }
-
- #region Keyboard handling
- public virtual void onKeyDown(object sender, KeyboardKeyEventArgs e){
- KeyDown.Raise (sender, e);
- }
- #endregion
-
- #region Mouse handling
- public virtual bool MouseIsIn(Point m)
- {
- if (!Visible)
- return false;
- if (ScreenCoordinates (Slot).ContainsOrIsEqual (m)) {
- Scroller scr = Parent as Scroller;
- if (scr == null)
- return true;
- return scr.MouseIsIn (scr.savedMousePos);
- }
- return false;
- }
- public virtual void checkHoverWidget(MouseMoveEventArgs e)
- {
- IGOLibHost glh = HostContainer;
- if (glh.hoverWidget != this) {
- glh.hoverWidget = this;
- onMouseEnter (this, e);
- }
-
- this.onMouseMove (this, e);
- }
- public virtual void onMouseMove(object sender, MouseMoveEventArgs e)
- {
- //bubble event to the top
- GraphicObject p = Parent as GraphicObject;
- if (p != null)
- p.onMouseMove(sender,e);
-
- MouseMove.Raise (sender, e);
- }
- public virtual void onMouseDown(object sender, MouseButtonEventArgs e){
- IGOLibHost hc = HostContainer;
- if (hc.activeWidget == null)
- hc.activeWidget = this;
- if (this.Focusable && !Interface.FocusOnHover) {
- BubblingMouseButtonEventArg be = e as BubblingMouseButtonEventArg;
- if (be.Focused == null) {
- be.Focused = this;
- hc.FocusedWidget = this;
- }
- }
- //bubble event to the top
- GraphicObject p = Parent as GraphicObject;
- if (p != null)
- p.onMouseDown(sender,e);
-
- MouseDown.Raise (this, e);
- }
- public virtual void onMouseUp(object sender, MouseButtonEventArgs e){
- //bubble event to the top
- GraphicObject p = Parent as GraphicObject;
- if (p != null)
- p.onMouseUp(sender,e);
-
- MouseUp.Raise (this, e);
-
- if (MouseIsIn (e.Position)&&HasFocus)
- onMouseClick(sender,e);
- }
- public virtual void onMouseClick(object sender, MouseButtonEventArgs e){
- MouseClick.Raise (this, e);
- }
- public virtual void onMouseWheel(object sender, MouseWheelEventArgs e){
- GraphicObject p = Parent as GraphicObject;
- if (p != null)
- p.onMouseWheel(this,e);
-
- MouseWheelChanged.Raise (this, e);
- }
- public virtual void onFocused(object sender, EventArgs e){
- Focused.Raise (this, e);
- this.HasFocus = true;
- }
- public virtual void onUnfocused(object sender, EventArgs e){
- Unfocused.Raise (this, e);
- this.HasFocus = false;
- }
- public virtual void onMouseEnter(object sender, MouseMoveEventArgs e)
- {
- MouseEnter.Raise (this, e);
- }
- public virtual void onMouseLeave(object sender, MouseMoveEventArgs e)
- {
- MouseLeave.Raise (this, e);
- }
- #endregion
-
- public override string ToString ()
- {
- string tmp ="";
-
- if (Parent != null)
- tmp = Parent.ToString () + tmp;
- #if DEBUG_LAYOUTING
- return Name == "unamed" ? tmp + "." + this.GetType ().Name + uid.ToString(): tmp + "." + Name;
- #else
- return Name == "unamed" ? tmp + "." + this.GetType ().Name : tmp + "." + Name;
- #endif
- }
-
- #region Binding
- public virtual void ResolveBindings()
- {
- #if DEBUG_BINDING
- Debug.WriteLine ("ResolveBinding => " + this.ToString ());
- #endif
- List<Binding> resolved = new List<Binding> ();
- foreach (Binding b in Bindings) {
- if (!string.IsNullOrEmpty (b.DynMethodId))
- continue;
- if (b.Source.Member.MemberType == MemberTypes.Event) {
- if (b.Expression.StartsWith("{")){
- CompileEventSource(b);
- continue;
- }
- }
- if (!b.FindTarget ())
- continue;
- if (b.Source.Member.MemberType == MemberTypes.Event) {
- //register handler for event
- if (b.Target.Method == null) {
- Debug.WriteLine ("Handler Method not found: " + b.Expression);
- continue;
- }
-
- MethodInfo addHandler = b.Source.Event.GetAddMethod ();
- Delegate del = Delegate.CreateDelegate (b.Source.Event.EventHandlerType, b.Target.Instance, b.Target.Method);
- addHandler.Invoke (this, new object[] { del });
- continue;
- }
- resolved.Add (b);
- }
- //group;only one dynMethods by target (valuechanged event source)
- //changed value name tested in switch
- IEnumerable<Binding[]> groupedByTarget = resolved.GroupBy (g => g.Target.Instance, g => g, (k, g) => g.ToArray ());
- foreach (Binding[] grouped in groupedByTarget) {
- int i = 0;
- Type targetType = grouped[0].Target.Instance.GetType();
- Type sourceType = this.GetType();
-
- DynamicMethod dm = null;
- ILGenerator il = null;
-
- MethodInfo stringEquals = typeof(string).GetMethod
- ("op_Equality", new Type[2] {typeof(string), typeof(string)});
-
-
- System.Reflection.Emit.Label[] jumpTable = null;
- System.Reflection.Emit.Label endMethod = new System.Reflection.Emit.Label();
-
- #region Retrieve EventHandler parameter type
- EventInfo ei = targetType.GetEvent ("ValueChanged");
- //no dynamic update if ValueChanged interface is not implemented
- if (ei != null){
- MethodInfo evtInvoke = ei.EventHandlerType.GetMethod ("Invoke");
- ParameterInfo[] evtParams = evtInvoke.GetParameters ();
- Type handlerArgsType = evtParams [1].ParameterType;
-
- Type[] args = {typeof(object), typeof(object),handlerArgsType};
- dm = new DynamicMethod(grouped[0].NewDynMethodId,
- MethodAttributes.Family | MethodAttributes.FamANDAssem | MethodAttributes.NewSlot,
- CallingConventions.Standard,
- typeof(void),
- args,
- sourceType,true);
-
- il = dm.GetILGenerator(256);
-
- endMethod = il.DefineLabel();
- jumpTable = new System.Reflection.Emit.Label[grouped.Length];
- for (i = 0; i < grouped.Length; i++)
- jumpTable [i] = il.DefineLabel ();
- il.DeclareLocal(typeof(string));
- il.DeclareLocal(typeof(object));
-
- il.Emit(OpCodes.Nop);
- il.Emit(OpCodes.Ldarg_0);
- //il.Emit(OpCodes.Isinst, sourceType);
- //push new value onto stack
- il.Emit(OpCodes.Ldarg_2);
- FieldInfo fiNewValue = typeof(ValueChangeEventArgs).GetField("NewValue");
- il.Emit(OpCodes.Ldfld, fiNewValue);
- il.Emit(OpCodes.Stloc_1);
- //push name
- il.Emit(OpCodes.Ldarg_2);
- FieldInfo fiMbName = typeof(ValueChangeEventArgs).GetField("MemberName");
- il.Emit(OpCodes.Ldfld, fiMbName);
- il.Emit(OpCodes.Stloc_0);
- il.Emit(OpCodes.Ldloc_0);
- il.Emit(OpCodes.Brfalse, endMethod);
- }
- #endregion
-
- i = 0;
- foreach (Binding b in grouped) {
- #region initialize target with actual value
- object targetValue = null;
- if (b.Target.Member != null){
- if (b.Target.Member.MemberType == MemberTypes.Property)
- targetValue = b.Target.Property.GetGetMethod ().Invoke (b.Target.Instance, null);
- else if (b.Target.Member.MemberType == MemberTypes.Field)
- targetValue = b.Target.Field.GetValue (b.Target.Instance);
- else if (b.Target.Member.MemberType == MemberTypes.Method){
- MethodInfo mthSrc = b.Target.Method;
- if (mthSrc.IsDefined(typeof(ExtensionAttribute), false))
- targetValue = mthSrc.Invoke(null, new object[] {b.Target.Instance});
- else
- targetValue = mthSrc.Invoke(b.Target.Instance, null);
- }else
- throw new Exception ("unandled source member type for binding");
- }else if (string.IsNullOrEmpty(b.Expression))
- targetValue= grouped [0].Target.Instance;//empty binding exp=> bound to target object by default
- //TODO: handle other dest type conversions
- if (b.Source.Property.PropertyType == typeof(string)){
- if (targetValue == null){
- //set default value
-
- }else
- targetValue = targetValue.ToString ();
- }
- b.Source.Property.GetSetMethod ().Invoke (this, new object[] { targetValue });
- #endregion
-
- //if no dyn update, skip jump table
- if (il == null)
- continue;
-
- il.Emit (OpCodes.Ldloc_0);
- if (b.Target.Member != null)
- il.Emit (OpCodes.Ldstr, b.Target.Member.Name);
- else
- il.Emit (OpCodes.Ldstr, b.Expression.Split('/').LastOrDefault());
- il.Emit (OpCodes.Callvirt, stringEquals);
- il.Emit (OpCodes.Brtrue, jumpTable[i]);
- i++;
- }
-
- if (il == null)
- continue;
-
- il.Emit (OpCodes.Br, endMethod);
-
- i = 0;
- foreach (Binding b in grouped) {
-
- il.MarkLabel (jumpTable [i]);
- il.Emit(OpCodes.Ldloc_1);
-
- //by default, target value type is deducted from source member type to allow
- //memberless binding, if targetMember exists, it will be used to determine target
- //value type for conversion
- Type targetValueType = b.Source.Property.PropertyType;
- if (b.Target.Member != null) {
- if (b.Target.Member.MemberType == MemberTypes.Property)
- targetValueType = b.Target.Property.PropertyType;
- else if (b.Target.Member.MemberType == MemberTypes.Field)
- targetValueType = b.Target.Field.FieldType;
- else
- throw new Exception ("unhandle target member type in binding");
- }
-
- if (!targetValueType.IsValueType)
- il.Emit(OpCodes.Castclass, targetValueType);
- else if (b.Source.Property.PropertyType != targetValueType)
- il.Emit(OpCodes.Callvirt, CompilerServices.GetConvertMethod( b.Source.Property.PropertyType ));
- else
- il.Emit(OpCodes.Unbox_Any, b.Source.Property.PropertyType);
-
- il.Emit(OpCodes.Callvirt, b.Source.Property.GetSetMethod());
- il.Emit (OpCodes.Br, endMethod);
- i++;
-
- }
- il.MarkLabel(endMethod);
- il.Emit(OpCodes.Pop);
- il.Emit(OpCodes.Ret);
-
- Delegate del = dm.CreateDelegate(ei.EventHandlerType, this);
- MethodInfo addHandler = ei.GetAddMethod ();
- addHandler.Invoke(grouped [0].Target.Instance, new object[] {del});
- }
- }
- /// <summary>
- /// Compile events expression in GOML attributes
- /// </summary>
- /// <param name="es">Event binding details</param>
- public void CompileEventSource(Binding binding)
- {
- Type sourceType = this.GetType();
-
- #region Retrieve EventHandler parameter type
- MethodInfo evtInvoke = binding.Source.Event.EventHandlerType.GetMethod ("Invoke");
- ParameterInfo[] evtParams = evtInvoke.GetParameters ();
- Type handlerArgsType = evtParams [1].ParameterType;
- #endregion
-
- Type[] args = {typeof(object), typeof(object),handlerArgsType};
- DynamicMethod dm = new DynamicMethod(binding.NewDynMethodId,
- typeof(void),
- args,
- sourceType);
-
-
- #region IL generation
- ILGenerator il = dm.GetILGenerator(256);
-
- string src = binding.Expression.Trim();
-
- if (! (src.StartsWith("{") || src.EndsWith ("}")))
- throw new Exception (string.Format("GOML:Malformed {0} Event handler: {1}", binding.Source.Member.Name, binding.Expression));
-
- src = src.Substring (1, src.Length - 2);
- string[] srcLines = src.Split (new char[] { ';' });
-
- foreach (string srcLine in srcLines) {
- string statement = srcLine.Trim ();
-
- string[] operandes = statement.Split (new char[] { '=' });
- if (operandes.Length < 2) //not an affectation
- {
- continue;
- }
- string lop = operandes [0].Trim ();
- string rop = operandes [operandes.Length-1].Trim ();
-
- #region LEFT OPERANDES
- GraphicObject lopObj = this; //default left operand base object is
- //the first arg (object sender) of the event handler
-
- il.Emit(OpCodes.Ldarg_0); //load sender ref onto the stack
-
- string[] lopParts = lop.Split (new char[] { '.' });
- if (lopParts.Length > 1) {//should search also for member of es.Source
- MethodInfo FindByNameMi = typeof(GraphicObject).GetMethod("FindByName");
- for (int j = 0; j < lopParts.Length - 1; j++) {
- il.Emit (OpCodes.Ldstr, lopParts[j]);
- il.Emit(OpCodes.Callvirt, FindByNameMi);
- }
- }
-
- int i = lopParts.Length -1;
-
- MemberInfo[] lopMbis = lopObj.GetType().GetMember (lopParts[i]);
-
- if (lopMbis.Length<1)
- throw new Exception (string.Format("CROW BINDING: Member not found '{0}'", lop));
-
- OpCode lopSetOC;
- dynamic lopSetMbi;
- Type lopT = null;
- switch (lopMbis[0].MemberType) {
- case MemberTypes.Property:
- PropertyInfo lopPi = sourceType.GetProperty (lopParts[i]);
- MethodInfo dstMi = lopPi.GetSetMethod ();
- lopT = lopPi.PropertyType;
- lopSetMbi = dstMi;
- lopSetOC = OpCodes.Callvirt;
- break;
- case MemberTypes.Field:
- FieldInfo dstFi = sourceType.GetField(lopParts[i]);
- lopT = dstFi.FieldType;
- lopSetMbi = dstFi;
- lopSetOC = OpCodes.Stfld;
- break;
- default:
- throw new Exception (string.Format("GOML:member type not handle: {0}", lopParts[i]));
- }
- #endregion
-
- #region RIGHT OPERANDES
- if (rop.StartsWith("\'")){
- if (!rop.EndsWith("\'"))
- throw new Exception (string.Format
- ("GOML:malformed string constant in handler: {0}", rop));
- string strcst = rop.Substring (1, rop.Length - 2);
-
- il.Emit(OpCodes.Ldstr,strcst);
-
- }else{
- //search for a static field in left operand type named 'rop name'
- FieldInfo ropFi = lopT.GetField (rop, BindingFlags.Static|BindingFlags.Public);
- if (ropFi != null)
- {
- il.Emit (OpCodes.Ldsfld, ropFi);
- }else{
- //search if parsing methods are present
- MethodInfo lopTryParseMi = lopT.GetMethod("TryParse");
- //TODO
- }
- }
-
- #endregion
-
- //emit left operand assignment
- il.Emit(lopSetOC, lopSetMbi);
- }
-
- il.Emit(OpCodes.Ret);
-
- #endregion
-
- Delegate del = dm.CreateDelegate(binding.Source.Event.EventHandlerType,this);
- MethodInfo addHandler = binding.Source.Event.GetAddMethod ();
- addHandler.Invoke(this, new object[] {del});
- }
- /// <summary>
- /// Remove dynamic delegates by ids from dataSource
- /// and delete ref of this in Shared interface refs
- /// </summary>
- public virtual void ClearBinding(){
- foreach (Binding b in Bindings) {
- if (string.IsNullOrEmpty (b.DynMethodId))
- continue;
- MemberReference mr = null;
- if (b.Target == null)
- mr = b.Source;
- else
- mr = b.Target;
- Type dataSourceType = mr.Instance.GetType();
- EventInfo evtInfo = dataSourceType.GetEvent ("ValueChanged");
- FieldInfo evtFi = CompilerServices.GetEventHandlerField (dataSourceType, "ValueChanged");
- MulticastDelegate multicastDelegate = evtFi.GetValue (mr.Instance) as MulticastDelegate;
- if (multicastDelegate != null) {
- foreach (Delegate d in multicastDelegate.GetInvocationList()) {
- if (d.Method.Name == b.DynMethodId)
- evtInfo.RemoveEventHandler (mr.Instance, d);
- }
- }
- b.Reset ();
- }
- }
- #endregion
-
- #region IXmlSerializable
- public virtual System.Xml.Schema.XmlSchema GetSchema ()
- {
- return null;
- }
- public virtual void ReadXml (System.Xml.XmlReader reader)
- {
- if (!reader.HasAttributes)
- return;
- Type thisType = this.GetType ();
- while (reader.MoveToNextAttribute ()) {
- string attName = reader.Name;
- string attValue = reader.Value;
-
- if (string.IsNullOrEmpty (attValue))
- continue;
-
- MemberInfo mi = thisType.GetMember (attName).FirstOrDefault();
- if (mi == null) {
- Debug.WriteLine ("GOML: Unknown attribute in " + thisType.ToString() + " : " + attName);
- continue;
- }
- if (mi.MemberType == MemberTypes.Event) {
- this.Bindings.Add (new Binding (new MemberReference(this, mi), attValue));
- continue;
- }
- if (mi.MemberType == MemberTypes.Property) {
- PropertyInfo pi = mi as PropertyInfo;
-
- if (pi.GetSetMethod () == null)
- continue;
-
- bool isAttribute = false;
- object defaultValue = null;
-
- foreach (object attrib in pi.GetCustomAttributes ()) {
- XmlAttributeAttribute xaa = attrib as XmlAttributeAttribute;
- if (xaa != null) {
- isAttribute = true;
- if (!string.IsNullOrEmpty (xaa.AttributeName))
- attName = xaa.AttributeName;
- continue;
- }
- if (attrib is XmlIgnoreAttribute)
- break;
- DefaultValueAttribute dv = attrib as DefaultValueAttribute;
- if (dv != null)
- defaultValue = dv.Value;
- }
- if (!isAttribute)
- continue;
-// {
-// //avoid system types automaticaly converted by parser
-// if (defaultValue != null && !pi.PropertyType.Namespace.StartsWith("System")) {
-// if (pi.PropertyType != defaultValue.GetType()) {
-// MethodInfo miParse = pi.PropertyType.GetMethod ("Parse", BindingFlags.Static | BindingFlags.Public);
-// if (miParse != null) {
-// pi.SetValue (this, miParse.Invoke (null, new object[]{ defaultValue }), null);
-// continue;
-// }
-// }
-// }
-// pi.SetValue (this, defaultValue, null);
-// } else {
-
- if (attValue.StartsWith("{")) {
- //binding
- if (!attValue.EndsWith("}"))
- throw new Exception (string.Format("GOML:Malformed binding: {0}", attValue));
-
- this.Bindings.Add (new Binding (new MemberReference(this, pi), attValue.Substring (1, attValue.Length - 2)));
- continue;
- }
-
- if (pi.PropertyType == typeof(string)) {
- pi.SetValue (this, attValue, null);
- continue;
- }
-
- if (pi.PropertyType.IsEnum) {
- pi.SetValue (this, Enum.Parse (pi.PropertyType, attValue), null);
- } else {
- MethodInfo me = pi.PropertyType.GetMethod ("Parse", new Type[] { typeof(string) });
- pi.SetValue (this, me.Invoke (null, new string[] { attValue }), null);
- }
- }
- }
- reader.MoveToElement();
- }
- public virtual void WriteXml (System.Xml.XmlWriter writer)
- {
- foreach (PropertyInfo pi in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
- if (pi.GetSetMethod () == null)
- continue;
-
- bool isAttribute = false;
- bool hasDefaultValue = false;
- bool ignore = false;
- string name = "";
- object value = null;
- Type valueType = null;
-
-
- MemberInfo mi = pi.GetGetMethod ();
-
- if (mi == null)
- continue;
-
- value = pi.GetValue (this, null);
- valueType = pi.PropertyType;
- name = pi.Name;
-
-
-
- object[] att = pi.GetCustomAttributes (false);
-
- foreach (object o in att) {
- XmlAttributeAttribute xaa = o as XmlAttributeAttribute;
- if (xaa != null) {
- isAttribute = true;
- if (string.IsNullOrEmpty (xaa.AttributeName))
- name = pi.Name;
- else
- name = xaa.AttributeName;
- continue;
- }
-
- XmlIgnoreAttribute xia = o as XmlIgnoreAttribute;
- if (xia != null) {
- ignore = true;
- continue;
- }
-
- DefaultValueAttribute dv = o as DefaultValueAttribute;
- if (dv != null) {
- if (dv.Value.Equals (value))
- hasDefaultValue = true;
- if (dv.Value.ToString () == value.ToString ())
- hasDefaultValue = true;
-
- continue;
- }
-
-
- }
-
- if (hasDefaultValue || ignore || value==null)
- continue;
-
- if (isAttribute)
- writer.WriteAttributeString (name, value.ToString ());
- else {
- if (valueType.GetInterface ("IXmlSerializable") == null)
- continue;
-
- (pi.GetValue (this, null) as IXmlSerializable).WriteXml (writer);
- }
- }
- foreach (EventInfo ei in this.GetType().GetEvents()) {
- FieldInfo fi = this.GetType().GetField(ei.Name,
- BindingFlags.NonPublic |
- BindingFlags.Instance |
- BindingFlags.GetField);
-
- Delegate dg = (System.Delegate)fi.GetValue (this);
-
- if (dg == null)
- continue;
-
- foreach (Delegate d in dg.GetInvocationList()) {
- if (!d.Method.Name.StartsWith ("<"))//Skipping empty handler, not clear it's trikky
- writer.WriteAttributeString (ei.Name, d.Method.Name);
- }
- }
- }
- #endregion
-
- }
-}
+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;
+
+using System.Xml.Serialization;
+using System.Reflection;
+using System.ComponentModel;
+using System.IO;
+//using System.Xml;
+using System.Xml;
+using System.Runtime.CompilerServices;
+using System.Reflection.Emit;
+
+namespace Crow
+{
+ public class GraphicObject : IXmlSerializable, ILayoutable, IValueChange
+ {
+ #if DEBUG_LAYOUTING
+ internal static ulong currentUid = 0;
+ internal ulong uid = 0;
+ #endif
+
+ internal List<Binding> Bindings = new List<Binding> ();
+
+ #region IValueChange implementation
+ public event EventHandler<ValueChangeEventArgs> ValueChanged;
+ public virtual void NotifyValueChanged(string MemberName, object _value)
+ {
+ ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value));
+ }
+ #endregion
+
+ #region CTOR
+ public GraphicObject ()
+ {
+ #if DEBUG_LAYOUTING
+ uid = currentUid;
+ currentUid++;
+ #endif
+
+ if (Interface.XmlSerializerInit)
+ return;
+
+ loadDefaultValues ();
+ registerForGraphicUpdate ();
+ }
+ public GraphicObject (Rectangle _bounds)
+ {
+ if (Interface.XmlSerializerInit)
+ return;
+
+ loadDefaultValues ();
+ Bounds = _bounds;
+ registerForGraphicUpdate ();
+ }
+ #endregion
+
+ #region private fields
+ ILayoutable _parent;
+ string _name = "unamed";
+ Color _background = Color.Transparent;
+ Color _foreground = Color.White;
+ Font _font = "droid, 10";
+ double _cornerRadius = 0;
+ int _margin = 0;
+ bool _focusable = false;
+ bool _hasFocus = false;
+ bool _mouseRepeat;
+ protected bool _isVisible = true;
+ VerticalAlignment _verticalAlignment = VerticalAlignment.Center;
+ HorizontalAlignment _horizontalAlignment = HorizontalAlignment.Center;
+ Size _maximumSize = "0;0";
+ Size _minimumSize = "0;0";
+
+ Picture _backgroundImage;
+ string _backgroundImagePath;
+ #endregion
+
+ #region public fields
+ public GraphicObject LogicalParent;
+ public Rectangle Bounds;
+ public Rectangle Slot = new Rectangle ();
+ public object Tag;
+ public byte[] bmp;
+ #endregion
+
+ #region ILayoutable
+ //TODO: it would save the recurent cost of a cast in event bubbling if parent type was GraphicObject
+ // or we could add to the interface the mouse events
+ [XmlIgnore]public ILayoutable Parent {
+ get { return _parent; }
+ set {
+// if (_parent == value)
+// return;
+// if (_parent != null)
+// ClearBinding ();
+//
+ _parent = value;
+//
+// if (DataSource != null)
+// ResolveBindings ();
+ }
+ }
+
+
+ [XmlIgnore]public virtual Rectangle ClientRectangle {
+ get {
+ Rectangle cb = Slot.Size;
+ cb.Inflate ( - Margin);
+ return cb;
+ }
+ }
+ [XmlIgnore]public virtual IGOLibHost HostContainer {
+ get { return Parent == null ? null : Parent.HostContainer; }
+ }
+ public virtual Rectangle ContextCoordinates(Rectangle r){
+ return
+ Parent.ContextCoordinates (r);// + ClientRectangle.Position;
+ }
+ public virtual Rectangle ScreenCoordinates (Rectangle r){
+ //r += Slot.Position;
+
+ return
+ Parent.ScreenCoordinates(r) + Parent.getSlot().Position + Parent.ClientRectangle.Position;
+ }
+ public virtual Rectangle getSlot()
+ {
+ return Slot;
+ }
+ public virtual Rectangle getBounds()
+ {
+ return Bounds;
+ }
+ #endregion
+
+ #region EVENT HANDLERS
+ public event EventHandler<MouseWheelEventArgs> MouseWheelChanged;
+ public event EventHandler<MouseButtonEventArgs> MouseUp;
+ public event EventHandler<MouseButtonEventArgs> MouseDown;
+ public event EventHandler<MouseButtonEventArgs> MouseClick;
+ public event EventHandler<MouseMoveEventArgs> MouseMove;
+ public event EventHandler<MouseMoveEventArgs> MouseEnter;
+ public event EventHandler<MouseMoveEventArgs> MouseLeave;
+ public event EventHandler<KeyboardKeyEventArgs> KeyDown;
+ public event EventHandler<KeyboardKeyEventArgs> KeyUp;
+ public event EventHandler Focused;
+ public event EventHandler Unfocused;
+ public event EventHandler<LayoutChangeEventArgs> LayoutChanged;
+ #endregion
+
+ #region public properties
+ [XmlAttributeAttribute()][DefaultValue("unamed")]
+ public virtual string Name {
+ get { return _name; }
+ set {
+ if (_name == value)
+ return;
+ _name = value;
+ NotifyValueChanged("Name", _verticalAlignment);
+ }
+ }
+ [XmlAttributeAttribute ()][DefaultValue(VerticalAlignment.Center)]
+ public virtual VerticalAlignment VerticalAlignment {
+ get { return _verticalAlignment; }
+ set {
+ if (_verticalAlignment == value)
+ return;
+
+ _verticalAlignment = value;
+ NotifyValueChanged("VerticalAlignment", _verticalAlignment);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(HorizontalAlignment.Center)]
+ public virtual HorizontalAlignment HorizontalAlignment {
+ get { return _horizontalAlignment; }
+ set {
+ if (_horizontalAlignment == value)
+ return;
+
+ _horizontalAlignment = value;
+ NotifyValueChanged("HorizontalAlignment", _horizontalAlignment);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(0)]
+ public virtual int Left {
+ get { return Bounds.X; }
+ set {
+ if (Bounds.X == value)
+ return;
+
+ Bounds.X = value;
+ NotifyValueChanged ("Left", Bounds.X);
+ this.RegisterForLayouting ((int)LayoutingType.X);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(0)]
+ public virtual int Top {
+ get { return Bounds.Y; }
+ set {
+ if (Bounds.Y == value)
+ return;
+
+ Bounds.Y = value;
+ NotifyValueChanged ("Top", Bounds.Y);
+ this.RegisterForLayouting ((int)LayoutingType.Y);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(0)]
+ public virtual int Width {
+ get { return Bounds.Width; }
+ set {
+ if (Bounds.Width == value)
+ return;
+
+ Bounds.Width = value;
+ NotifyValueChanged ("Width", Bounds.Width);
+ this.RegisterForLayouting ((int)LayoutingType.Width);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(0)]
+ public virtual int Height {
+ get { return Bounds.Height; }
+ set {
+ if (Bounds.Height == value)
+ return;
+
+ Bounds.Height = value;
+ NotifyValueChanged ("Height", Bounds.Height);
+ this.RegisterForLayouting ((int)LayoutingType.Height);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(false)]
+ public virtual bool Fit {
+ get { return Bounds.Width < 0 && Bounds.Height < 0 ? true : false; }
+ set {
+ if (value == Fit)
+ return;
+
+ Bounds.Width = Bounds.Height = -1;
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(false)]
+ public virtual bool Focusable {
+ get { return _focusable; }
+ set {
+ if (_focusable == value)
+ return;
+ _focusable = value;
+ NotifyValueChanged ("Focusable", _focusable);
+ }
+ }
+ [XmlIgnore]public virtual bool HasFocus {
+ get { return _hasFocus; }
+ set {
+ if (value == _hasFocus)
+ return;
+
+ _hasFocus = value;
+ NotifyValueChanged ("HasFocus", _hasFocus);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(false)]
+ public virtual bool MouseRepeat {
+ get { return _mouseRepeat; }
+ set {
+ if (_mouseRepeat == value)
+ return;
+ _mouseRepeat = value;
+ NotifyValueChanged ("MouseRepeat", _mouseRepeat);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue("Transparent")]
+ public virtual Color Background {
+ get { return _background; }
+ set {
+ if (_background == value)
+ return;
+ _background = value;
+ NotifyValueChanged ("Background", _background);
+ registerForGraphicUpdate ();
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue("White")]
+ public virtual Color Foreground {
+ get { return _foreground; }
+ set {
+ if (_foreground == value)
+ return;
+ _foreground = value;
+ NotifyValueChanged ("Foreground", _foreground);
+ registerForGraphicUpdate ();
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue("droid,10")]
+ public virtual Font Font {
+ get { return _font; }
+ set {
+ if (value == _font)
+ return;
+ _font = value;
+ NotifyValueChanged ("Font", _font);
+ registerForGraphicUpdate ();
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(0.0)]
+ public virtual double CornerRadius {
+ get { return _cornerRadius; }
+ set {
+ if (value == _cornerRadius)
+ return;
+ _cornerRadius = value;
+ NotifyValueChanged ("CornerRadius", _cornerRadius);
+ registerForGraphicUpdate ();
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(0)]
+ public virtual int Margin {
+ get { return _margin; }
+ set {
+ if (value == _margin)
+ return;
+ _margin = value;
+ NotifyValueChanged ("Margin", _margin);
+ registerForGraphicUpdate ();
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(true)]
+ public virtual bool Visible {
+ get { return _isVisible; }
+ set {
+ if (value == _isVisible)
+ return;
+
+ _isVisible = value;
+
+ if (HostContainer == null)
+ return;
+ //add slot to clipping to redraw
+ HostContainer.gobjsToRedraw.Add (this);
+
+ //ensure main win doesn't keep hidden childrens ref
+ if (this.Contains (HostContainer.hoverWidget))
+ HostContainer.hoverWidget = null;
+ if (Parent is GenericStack)
+ Parent.RegisterForLayouting ((int)LayoutingType.Sizing | (int)LayoutingType.PositionChildren);
+
+ NotifyValueChanged ("Visible", _isVisible);
+ }
+ }
+ //TODO: only used in group, should be removed from base go object
+ [XmlIgnore]public virtual bool DrawingIsValid
+ { get { return bmp == null ?
+ false :
+ true; } }
+ [XmlAttributeAttribute()][DefaultValue("0;0")]
+ public virtual Size MaximumSize {
+ get { return _maximumSize; }
+ set { _maximumSize = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue("0;0")]
+ public virtual Size MinimumSize {
+ get { return _minimumSize; }
+ set { _minimumSize = value; }
+ }
+ object dataSource;
+
+ [XmlIgnore]public virtual object DataSource {
+ set {
+ if (dataSource == value)
+ return;
+
+ if (dataSource != null)
+ this.ClearBinding ();
+
+ dataSource = value;
+
+ if (dataSource != null)
+ this.ResolveBindings();
+ }
+ get {
+ return dataSource == null ?
+ LogicalParent == null ?
+ Parent is GraphicObject ? (Parent as GraphicObject).DataSource : null : LogicalParent.DataSource : dataSource;
+ }
+ }
+ #endregion
+
+
+ /// <summary>
+ /// Loads the default values from XML attributes default
+ /// </summary>
+ protected virtual void loadDefaultValues()
+ {
+ foreach (PropertyInfo pi in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
+ if (pi.GetSetMethod () == null)
+ continue;
+ string name = "";
+
+ object[] att = pi.GetCustomAttributes (false);
+
+ foreach (object o in att) {
+ XmlAttributeAttribute xaa = o as XmlAttributeAttribute;
+ if (xaa != null) {
+ if (string.IsNullOrEmpty (xaa.AttributeName))
+ name = pi.Name;
+ else
+ name = xaa.AttributeName;
+ continue;
+ }
+
+ XmlIgnoreAttribute xia = o as XmlIgnoreAttribute;
+ if (xia != null)
+ continue;
+
+ DefaultValueAttribute dv = o as DefaultValueAttribute;
+ if (dv != null) {
+ object defaultValue = dv.Value;
+ //avoid system types automaticaly converted by parser
+ if (defaultValue != null && !pi.PropertyType.Namespace.StartsWith("System")) {
+ if (pi.PropertyType != defaultValue.GetType()) {
+ MethodInfo miParse = pi.PropertyType.GetMethod ("Parse", BindingFlags.Static | BindingFlags.Public);
+ if (miParse != null) {
+ pi.SetValue (this, miParse.Invoke (null, new object[]{ defaultValue }), null);
+ continue;
+ }
+ }
+ }
+ pi.SetValue (this, defaultValue, null);
+ }
+ }
+ }
+ }
+
+ public virtual GraphicObject FindByName(string nameToFind){
+ return nameToFind == _name ? this : null;
+ }
+ public virtual bool Contains(GraphicObject goToFind){
+ return false;
+ }
+
+
+ /// <summary>
+ /// Clear chached object and add clipping region in redraw list of interface
+ /// </summary>
+ public virtual void registerForGraphicUpdate ()
+ {
+ bmp = null;
+ if (HostContainer != null)
+ HostContainer.gobjsToRedraw.Add (this);
+ }
+ /// <summary>
+ /// Add clipping region in redraw list of interface, dont update cached object content
+ /// </summary>
+ public virtual void RegisterForRedraw ()
+ {
+ if (HostContainer != null)
+ HostContainer.gobjsToRedraw.Add (this);
+ }
+
+ /// <summary>
+ /// keep last slot components for each layouting pass to track
+ /// changes and trigger update of other component accordingly
+ /// </summary>
+ public Rectangle LastSlots;
+ /// <summary>
+ /// keep last slot painted on screen to clear traces if moved or resized
+ /// TODO: we should ensure the whole parsed widget tree is the last painted
+ /// version to clear effective oldslot if parents have been moved or resized.
+ /// IDEA is to add a ScreenCoordinates function that use only lastPaintedSlots
+ /// </summary>
+ public Rectangle LastPaintedSlot;
+
+ public virtual void registerClipRect()
+ {
+ HostContainer.redrawClip.AddRectangle (ScreenCoordinates(Slot));
+ //this clipping should take only last painted slots in ancestor tree which
+ //is not the case for now.
+ HostContainer.redrawClip.AddRectangle (ScreenCoordinates(LastPaintedSlot));
+ }
+ /// <summary> return size of content + margins </summary>
+ protected virtual Size measureRawSize ()
+ {
+ return Bounds.Size;
+ }
+ /// <summary> clear current layoutingQueue items for object and
+ /// trigger a new layouting pass for a layoutType </summary>
+ public virtual void RegisterForLayouting(int layoutType)
+ {
+ if (Parent == null)
+ return;
+ #if DEBUG_LAYOUTING
+ Debug.WriteLine ("RegisterForLayouting => {1}->{0}", layoutType, this.ToString());
+ #endif
+ lock (Interface.LayoutingQueue) {
+ Interface.LayoutingQueue.RemoveAll (lq => lq.GraphicObject == this && (layoutType & (int)lq.LayoutType) > 0);
+
+ if ((layoutType & (int)LayoutingType.Width) > 0) {
+ if (Bounds.Width == 0) //stretch in parent
+ Interface.LayoutingQueue.EnqueueAfterParentSizing (LayoutingType.Width, this);
+ else if (Bounds.Width < 0) //fit
+ Interface.LayoutingQueue.EnqueueBeforeParentSizing (LayoutingType.Width, this);
+ else
+ Interface.LayoutingQueue.Insert (0, new LayoutingQueueItem (LayoutingType.Width, this));
+ }
+
+ if ((layoutType & (int)LayoutingType.Height) > 0) {
+ if (Bounds.Height == 0) //stretch in parent
+ Interface.LayoutingQueue.EnqueueAfterParentSizing (LayoutingType.Height, this);
+ else if (Bounds.Height < 0) //fit
+ Interface.LayoutingQueue.EnqueueBeforeParentSizing (LayoutingType.Height, this);
+ else
+ Interface.LayoutingQueue.Insert (0, new LayoutingQueueItem (LayoutingType.Height, this));
+ }
+
+ if ((layoutType & (int)LayoutingType.X) > 0)
+ //for x positionning, sizing of parent and this have to be done
+ Interface.LayoutingQueue.EnqueueAfterThisAndParentSizing (LayoutingType.X, this);
+
+ if ((layoutType & (int)LayoutingType.Y) > 0)
+ //for x positionning, sizing of parent and this have to be done
+ Interface.LayoutingQueue.EnqueueAfterThisAndParentSizing (LayoutingType.Y, this);
+ }
+ }
+
+ /// <summary> trigger dependant sizing component update </summary>
+ public virtual void OnLayoutChanges(LayoutingType layoutType)
+ {
+ if (Parent==null)
+ return;
+ #if DEBUG_LAYOUTING
+ Debug.WriteLine ("Layout change: " + this.ToString () + ":" + LastSlots.ToString() + "=>" + Slot.ToString ());
+ #endif
+
+ switch (layoutType) {
+ case LayoutingType.Width:
+ if (Parent.getBounds ().Width < 0) {
+ Group gw = Parent as Group;
+ if (gw != null) {
+ if (Slot.Width > gw.maxChildrenWidth)
+ gw.maxChildrenWidth = Slot.Width;
+ }
+ this.Parent.RegisterForLayouting ((int)LayoutingType.Width);
+ }else if (Width != 0) //update position in parent
+ this.RegisterForLayouting ((int)LayoutingType.X);
+ GenericStack gsw = Parent as GenericStack;
+ if (gsw == null)
+ break;
+ if ((Parent as GenericStack).Orientation == Orientation.Horizontal) {
+// ulong idx = (ulong)gsw.Children.IndexOf (this);
+// if (idx < gsw.stackingUpdateStartIndex)
+// gsw.stackingUpdateStartIndex = idx;
+ this.Parent.RegisterForLayouting ((int)LayoutingType.PositionChildren);
+ }
+ break;
+ case LayoutingType.Height:
+ if (Parent.getBounds ().Height < 0) {
+ Group gh = Parent as Group;
+ if (gh != null) {
+ if (Slot.Width > gh.maxChildrenHeight)
+ gh.maxChildrenHeight = Slot.Height;
+ }
+ this.Parent.RegisterForLayouting ((int)LayoutingType.Height);
+ }else if (Height != 0) //update position in parent
+ this.RegisterForLayouting ((int)LayoutingType.Y);
+ GenericStack gsh = Parent as GenericStack;
+ if (gsh==null)
+ break;
+ if (gsh.Orientation == Orientation.Vertical) {
+// ulong idx = (ulong)gsh.Children.IndexOf (this);
+// if (idx < gsh.stackingUpdateStartIndex)
+// gsh.stackingUpdateStartIndex = idx;
+ this.Parent.RegisterForLayouting ((int)LayoutingType.PositionChildren);
+ }
+ break;
+ }
+ LayoutChanged.Raise (this, new LayoutChangeEventArgs (layoutType));
+ }
+ /// <summary> Update layout component, this is where the computation of alignement
+ /// and size take place </summary>
+ public virtual void UpdateLayout (LayoutingType layoutType)
+ {
+ switch (layoutType) {
+ case LayoutingType.X:
+ if (Bounds.X == 0) {
+ switch (HorizontalAlignment) {
+ case HorizontalAlignment.Left:
+ Slot.X = 0;
+ break;
+ case HorizontalAlignment.Right:
+ Slot.X = Parent.ClientRectangle.Width - Slot.Width;
+ break;
+ case HorizontalAlignment.Center:
+ Slot.X = Parent.ClientRectangle.Width / 2 - Slot.Width / 2;
+ break;
+ }
+ } else
+ Slot.X = Bounds.X;
+
+ if (LastSlots.X == Slot.X)
+ break;
+
+ bmp = null;
+
+ OnLayoutChanges (layoutType);
+
+ LastSlots.X = Slot.X;
+ break;
+ case LayoutingType.Y:
+ if (Bounds.Y == 0) {
+ switch (VerticalAlignment) {
+ case VerticalAlignment.Top:
+ Slot.Y = 0;
+ break;
+ case VerticalAlignment.Bottom:
+ Slot.Y = Parent.ClientRectangle.Height - Slot.Height;
+ break;
+ case VerticalAlignment.Center:
+ Slot.Y = Parent.ClientRectangle.Height / 2 - Slot.Height / 2;
+ break;
+ }
+ }else
+ Slot.Y = Bounds.Y;
+
+ if (LastSlots.Y == Slot.Y)
+ break;
+
+ bmp = null;
+
+ OnLayoutChanges (layoutType);
+
+ LastSlots.Y = Slot.Y;
+ break;
+ case LayoutingType.Width:
+ //force sizing to fit if parent is sizing on children and
+ //this object has stretched size
+ if (Parent.getBounds ().Width < 0 && Width == 0)
+ Width = -1;
+
+ if (Width > 0)
+ Slot.Width = Width;
+ else if (Width < 0)
+ Slot.Width = measureRawSize ().Width;
+ else
+ Slot.Width = Parent.ClientRectangle.Width;
+
+ //size constrain
+ if (Slot.Width < MinimumSize.Width)
+ Slot.Width = MinimumSize.Width;
+ else if (Slot.Width > MaximumSize.Width && MaximumSize.Width > 0)
+ Slot.Width = MaximumSize.Width;
+
+ if (LastSlots.Width == Slot.Width)
+ break;
+
+ bmp = null;
+
+ OnLayoutChanges (layoutType);
+
+ LastSlots.Width = Slot.Width;
+ break;
+ case LayoutingType.Height:
+ //force sizing to fit if parent is sizing on children
+ if (Parent.getBounds ().Height < 0 && Height == 0)
+ Height = -1;
+
+ if (Height > 0)
+ Slot.Height = Height;
+ else if (Height < 0)
+ Slot.Height = measureRawSize ().Height;
+ else
+ Slot.Height = Parent.ClientRectangle.Height;
+
+ //size constrain
+ if (Slot.Height < MinimumSize.Height)
+ Slot.Height = MinimumSize.Height;
+ else if (Slot.Height > MaximumSize.Height && MaximumSize.Height > 0)
+ Slot.Height = MaximumSize.Height;
+
+
+ if (LastSlots.Height == Slot.Height)
+ break;
+
+ bmp = null;
+
+ OnLayoutChanges (layoutType);
+
+ LastSlots.Height = Slot.Height;
+ break;
+ }
+ lock (Interface.LayoutingQueue) {
+ //if no layouting remains in queue for item, registre for redraw
+ if (Interface.LayoutingQueue.Where (lq => lq.GraphicObject == this).Count () <= 0 && bmp == null)
+ this.RegisterForRedraw ();
+ }
+ }
+
+ /// <summary> This is the common overridable drawing routine to create new widget </summary>
+ protected virtual void onDraw(Context gr)
+ {
+ Rectangle rBack = new Rectangle (Slot.Size);
+
+ Background.SetAsSource (gr);
+ CairoHelpers.CairoRectangle(gr,rBack,_cornerRadius);
+ gr.Fill ();
+ }
+
+ /// <summary>
+ /// Interfal drawing context creation on a cached surface limited to slot size
+ /// this trigger the effective drawing routine </summary>
+ protected virtual void UpdateGraphic ()
+ {
+ LastPaintedSlot = Slot;
+
+ int stride = 4 * Slot.Width;
+
+ int bmpSize = Math.Abs (stride) * Slot.Height;
+ bmp = new byte[bmpSize];
+
+ using (ImageSurface draw =
+ new ImageSurface(bmp, Format.Argb32, Slot.Width, Slot.Height, stride)) {
+ using (Context gr = new Context (draw)) {
+ gr.Antialias = Antialias.Subpixel;
+ onDraw (gr);
+ }
+ draw.Flush ();
+ //draw.WriteToPng ("/mnt/data/test.png");
+ }
+ }
+ /// <summary> Chained painting routine on the parent context of the actual cached version
+ /// of the widget </summary>
+ public virtual void Paint (ref Context ctx, Rectangles clip = null)
+ {
+ if (!Visible)
+ return;
+
+ if (bmp == null)
+ UpdateGraphic ();
+
+ Rectangle rb = Parent.ContextCoordinates(Slot);
+
+ using (ImageSurface source = new ImageSurface(bmp, Format.Argb32, Slot.Width, Slot.Height, 4 * Slot.Width)) {
+ if (this.Background == Color.Clear) {
+ ctx.Save ();
+ ctx.Operator = Operator.Clear;
+ ctx.Rectangle(rb);
+ ctx.Fill ();
+ ctx.Restore ();
+ }
+ ctx.SetSourceSurface (source, rb.X, rb.Y);
+ ctx.Paint ();
+ }
+ }
+
+ #region Keyboard handling
+ public virtual void onKeyDown(object sender, KeyboardKeyEventArgs e){
+ KeyDown.Raise (sender, e);
+ }
+ #endregion
+
+ #region Mouse handling
+ public virtual bool MouseIsIn(Point m)
+ {
+ if (!Visible)
+ return false;
+ if (ScreenCoordinates (Slot).ContainsOrIsEqual (m)) {
+ Scroller scr = Parent as Scroller;
+ if (scr == null)
+ return true;
+ return scr.MouseIsIn (scr.savedMousePos);
+ }
+ return false;
+ }
+ public virtual void checkHoverWidget(MouseMoveEventArgs e)
+ {
+ IGOLibHost glh = HostContainer;
+ if (glh.hoverWidget != this) {
+ glh.hoverWidget = this;
+ onMouseEnter (this, e);
+ }
+
+ this.onMouseMove (this, e);
+ }
+ public virtual void onMouseMove(object sender, MouseMoveEventArgs e)
+ {
+ //bubble event to the top
+ GraphicObject p = Parent as GraphicObject;
+ if (p != null)
+ p.onMouseMove(sender,e);
+
+ MouseMove.Raise (sender, e);
+ }
+ public virtual void onMouseDown(object sender, MouseButtonEventArgs e){
+ IGOLibHost hc = HostContainer;
+ if (hc.activeWidget == null)
+ hc.activeWidget = this;
+ if (this.Focusable && !Interface.FocusOnHover) {
+ BubblingMouseButtonEventArg be = e as BubblingMouseButtonEventArg;
+ if (be.Focused == null) {
+ be.Focused = this;
+ hc.FocusedWidget = this;
+ }
+ }
+ //bubble event to the top
+ GraphicObject p = Parent as GraphicObject;
+ if (p != null)
+ p.onMouseDown(sender,e);
+
+ MouseDown.Raise (this, e);
+ }
+ public virtual void onMouseUp(object sender, MouseButtonEventArgs e){
+ //bubble event to the top
+ GraphicObject p = Parent as GraphicObject;
+ if (p != null)
+ p.onMouseUp(sender,e);
+
+ MouseUp.Raise (this, e);
+
+ if (MouseIsIn (e.Position)&&HasFocus)
+ onMouseClick(sender,e);
+ }
+ public virtual void onMouseClick(object sender, MouseButtonEventArgs e){
+ MouseClick.Raise (this, e);
+ }
+ public virtual void onMouseWheel(object sender, MouseWheelEventArgs e){
+ GraphicObject p = Parent as GraphicObject;
+ if (p != null)
+ p.onMouseWheel(this,e);
+
+ MouseWheelChanged.Raise (this, e);
+ }
+ public virtual void onFocused(object sender, EventArgs e){
+ Focused.Raise (this, e);
+ this.HasFocus = true;
+ }
+ public virtual void onUnfocused(object sender, EventArgs e){
+ Unfocused.Raise (this, e);
+ this.HasFocus = false;
+ }
+ public virtual void onMouseEnter(object sender, MouseMoveEventArgs e)
+ {
+ MouseEnter.Raise (this, e);
+ }
+ public virtual void onMouseLeave(object sender, MouseMoveEventArgs e)
+ {
+ MouseLeave.Raise (this, e);
+ }
+ #endregion
+
+ public override string ToString ()
+ {
+ string tmp ="";
+
+ if (Parent != null)
+ tmp = Parent.ToString () + tmp;
+ #if DEBUG_LAYOUTING
+ return Name == "unamed" ? tmp + "." + this.GetType ().Name + uid.ToString(): tmp + "." + Name;
+ #else
+ return Name == "unamed" ? tmp + "." + this.GetType ().Name : tmp + "." + Name;
+ #endif
+ }
+
+ #region Binding
+ public virtual void ResolveBindings()
+ {
+ #if DEBUG_BINDING
+ Debug.WriteLine ("ResolveBinding => " + this.ToString ());
+ #endif
+ List<Binding> resolved = new List<Binding> ();
+ foreach (Binding b in Bindings) {
+ if (!string.IsNullOrEmpty (b.DynMethodId))
+ continue;
+ if (b.Source.Member.MemberType == MemberTypes.Event) {
+ if (b.Expression.StartsWith("{")){
+ CompileEventSource(b);
+ continue;
+ }
+ }
+ if (!b.FindTarget ())
+ continue;
+ if (b.Source.Member.MemberType == MemberTypes.Event) {
+ //register handler for event
+ if (b.Target.Method == null) {
+ Debug.WriteLine ("Handler Method not found: " + b.Expression);
+ continue;
+ }
+
+ MethodInfo addHandler = b.Source.Event.GetAddMethod ();
+ Delegate del = Delegate.CreateDelegate (b.Source.Event.EventHandlerType, b.Target.Instance, b.Target.Method);
+ addHandler.Invoke (this, new object[] { del });
+ continue;
+ }
+ resolved.Add (b);
+ }
+ //group;only one dynMethods by target (valuechanged event source)
+ //changed value name tested in switch
+ IEnumerable<Binding[]> groupedByTarget = resolved.GroupBy (g => g.Target.Instance, g => g, (k, g) => g.ToArray ());
+ foreach (Binding[] grouped in groupedByTarget) {
+ int i = 0;
+ Type targetType = grouped[0].Target.Instance.GetType();
+ Type sourceType = this.GetType();
+
+ DynamicMethod dm = null;
+ ILGenerator il = null;
+
+ MethodInfo stringEquals = typeof(string).GetMethod
+ ("op_Equality", new Type[2] {typeof(string), typeof(string)});
+
+
+ System.Reflection.Emit.Label[] jumpTable = null;
+ System.Reflection.Emit.Label endMethod = new System.Reflection.Emit.Label();
+
+ #region Retrieve EventHandler parameter type
+ EventInfo ei = targetType.GetEvent ("ValueChanged");
+ //no dynamic update if ValueChanged interface is not implemented
+ if (ei != null){
+ MethodInfo evtInvoke = ei.EventHandlerType.GetMethod ("Invoke");
+ ParameterInfo[] evtParams = evtInvoke.GetParameters ();
+ Type handlerArgsType = evtParams [1].ParameterType;
+
+ Type[] args = {typeof(object), typeof(object),handlerArgsType};
+ dm = new DynamicMethod(grouped[0].NewDynMethodId,
+ MethodAttributes.Family | MethodAttributes.FamANDAssem | MethodAttributes.NewSlot,
+ CallingConventions.Standard,
+ typeof(void),
+ args,
+ sourceType,true);
+
+ il = dm.GetILGenerator(256);
+
+ endMethod = il.DefineLabel();
+ jumpTable = new System.Reflection.Emit.Label[grouped.Length];
+ for (i = 0; i < grouped.Length; i++)
+ jumpTable [i] = il.DefineLabel ();
+ il.DeclareLocal(typeof(string));
+ il.DeclareLocal(typeof(object));
+
+ il.Emit(OpCodes.Nop);
+ il.Emit(OpCodes.Ldarg_0);
+ //il.Emit(OpCodes.Isinst, sourceType);
+ //push new value onto stack
+ il.Emit(OpCodes.Ldarg_2);
+ FieldInfo fiNewValue = typeof(ValueChangeEventArgs).GetField("NewValue");
+ il.Emit(OpCodes.Ldfld, fiNewValue);
+ il.Emit(OpCodes.Stloc_1);
+ //push name
+ il.Emit(OpCodes.Ldarg_2);
+ FieldInfo fiMbName = typeof(ValueChangeEventArgs).GetField("MemberName");
+ il.Emit(OpCodes.Ldfld, fiMbName);
+ il.Emit(OpCodes.Stloc_0);
+ il.Emit(OpCodes.Ldloc_0);
+ il.Emit(OpCodes.Brfalse, endMethod);
+ }
+ #endregion
+
+ i = 0;
+ foreach (Binding b in grouped) {
+ #region initialize target with actual value
+ object targetValue = null;
+ if (b.Target.Member != null){
+ if (b.Target.Member.MemberType == MemberTypes.Property)
+ targetValue = b.Target.Property.GetGetMethod ().Invoke (b.Target.Instance, null);
+ else if (b.Target.Member.MemberType == MemberTypes.Field)
+ targetValue = b.Target.Field.GetValue (b.Target.Instance);
+ else if (b.Target.Member.MemberType == MemberTypes.Method){
+ MethodInfo mthSrc = b.Target.Method;
+ if (mthSrc.IsDefined(typeof(ExtensionAttribute), false))
+ targetValue = mthSrc.Invoke(null, new object[] {b.Target.Instance});
+ else
+ targetValue = mthSrc.Invoke(b.Target.Instance, null);
+ }else
+ throw new Exception ("unandled source member type for binding");
+ }else if (string.IsNullOrEmpty(b.Expression))
+ targetValue= grouped [0].Target.Instance;//empty binding exp=> bound to target object by default
+ //TODO: handle other dest type conversions
+ if (b.Source.Property.PropertyType == typeof(string)){
+ if (targetValue == null){
+ //set default value
+
+ }else
+ targetValue = targetValue.ToString ();
+ }
+ b.Source.Property.GetSetMethod ().Invoke (this, new object[] { targetValue });
+ #endregion
+
+ //if no dyn update, skip jump table
+ if (il == null)
+ continue;
+
+ il.Emit (OpCodes.Ldloc_0);
+ if (b.Target.Member != null)
+ il.Emit (OpCodes.Ldstr, b.Target.Member.Name);
+ else
+ il.Emit (OpCodes.Ldstr, b.Expression.Split('/').LastOrDefault());
+ il.Emit (OpCodes.Callvirt, stringEquals);
+ il.Emit (OpCodes.Brtrue, jumpTable[i]);
+ i++;
+ }
+
+ if (il == null)
+ continue;
+
+ il.Emit (OpCodes.Br, endMethod);
+
+ i = 0;
+ foreach (Binding b in grouped) {
+
+ il.MarkLabel (jumpTable [i]);
+ il.Emit(OpCodes.Ldloc_1);
+
+ //by default, target value type is deducted from source member type to allow
+ //memberless binding, if targetMember exists, it will be used to determine target
+ //value type for conversion
+ Type targetValueType = b.Source.Property.PropertyType;
+ if (b.Target.Member != null) {
+ if (b.Target.Member.MemberType == MemberTypes.Property)
+ targetValueType = b.Target.Property.PropertyType;
+ else if (b.Target.Member.MemberType == MemberTypes.Field)
+ targetValueType = b.Target.Field.FieldType;
+ else
+ throw new Exception ("unhandle target member type in binding");
+ }
+
+ if (!targetValueType.IsValueType)
+ il.Emit(OpCodes.Castclass, targetValueType);
+ else if (b.Source.Property.PropertyType != targetValueType)
+ il.Emit(OpCodes.Callvirt, CompilerServices.GetConvertMethod( b.Source.Property.PropertyType ));
+ else
+ il.Emit(OpCodes.Unbox_Any, b.Source.Property.PropertyType);
+
+ il.Emit(OpCodes.Callvirt, b.Source.Property.GetSetMethod());
+ il.Emit (OpCodes.Br, endMethod);
+ i++;
+
+ }
+ il.MarkLabel(endMethod);
+ il.Emit(OpCodes.Pop);
+ il.Emit(OpCodes.Ret);
+
+ Delegate del = dm.CreateDelegate(ei.EventHandlerType, this);
+ MethodInfo addHandler = ei.GetAddMethod ();
+ addHandler.Invoke(grouped [0].Target.Instance, new object[] {del});
+ }
+ }
+ /// <summary>
+ /// Compile events expression in GOML attributes
+ /// </summary>
+ /// <param name="es">Event binding details</param>
+ public void CompileEventSource(Binding binding)
+ {
+ Type sourceType = this.GetType();
+
+ #region Retrieve EventHandler parameter type
+ MethodInfo evtInvoke = binding.Source.Event.EventHandlerType.GetMethod ("Invoke");
+ ParameterInfo[] evtParams = evtInvoke.GetParameters ();
+ Type handlerArgsType = evtParams [1].ParameterType;
+ #endregion
+
+ Type[] args = {typeof(object), typeof(object),handlerArgsType};
+ DynamicMethod dm = new DynamicMethod(binding.NewDynMethodId,
+ typeof(void),
+ args,
+ sourceType);
+
+
+ #region IL generation
+ ILGenerator il = dm.GetILGenerator(256);
+
+ string src = binding.Expression.Trim();
+
+ if (! (src.StartsWith("{") || src.EndsWith ("}")))
+ throw new Exception (string.Format("GOML:Malformed {0} Event handler: {1}", binding.Source.Member.Name, binding.Expression));
+
+ src = src.Substring (1, src.Length - 2);
+ string[] srcLines = src.Split (new char[] { ';' });
+
+ foreach (string srcLine in srcLines) {
+ string statement = srcLine.Trim ();
+
+ string[] operandes = statement.Split (new char[] { '=' });
+ if (operandes.Length < 2) //not an affectation
+ {
+ continue;
+ }
+ string lop = operandes [0].Trim ();
+ string rop = operandes [operandes.Length-1].Trim ();
+
+ #region LEFT OPERANDES
+ GraphicObject lopObj = this; //default left operand base object is
+ //the first arg (object sender) of the event handler
+
+ il.Emit(OpCodes.Ldarg_0); //load sender ref onto the stack
+
+ string[] lopParts = lop.Split (new char[] { '.' });
+ if (lopParts.Length > 1) {//should search also for member of es.Source
+ MethodInfo FindByNameMi = typeof(GraphicObject).GetMethod("FindByName");
+ for (int j = 0; j < lopParts.Length - 1; j++) {
+ il.Emit (OpCodes.Ldstr, lopParts[j]);
+ il.Emit(OpCodes.Callvirt, FindByNameMi);
+ }
+ }
+
+ int i = lopParts.Length -1;
+
+ MemberInfo[] lopMbis = lopObj.GetType().GetMember (lopParts[i]);
+
+ if (lopMbis.Length<1)
+ throw new Exception (string.Format("CROW BINDING: Member not found '{0}'", lop));
+
+ OpCode lopSetOC;
+ dynamic lopSetMbi;
+ Type lopT = null;
+ switch (lopMbis[0].MemberType) {
+ case MemberTypes.Property:
+ PropertyInfo lopPi = sourceType.GetProperty (lopParts[i]);
+ MethodInfo dstMi = lopPi.GetSetMethod ();
+ lopT = lopPi.PropertyType;
+ lopSetMbi = dstMi;
+ lopSetOC = OpCodes.Callvirt;
+ break;
+ case MemberTypes.Field:
+ FieldInfo dstFi = sourceType.GetField(lopParts[i]);
+ lopT = dstFi.FieldType;
+ lopSetMbi = dstFi;
+ lopSetOC = OpCodes.Stfld;
+ break;
+ default:
+ throw new Exception (string.Format("GOML:member type not handle: {0}", lopParts[i]));
+ }
+ #endregion
+
+ #region RIGHT OPERANDES
+ if (rop.StartsWith("\'")){
+ if (!rop.EndsWith("\'"))
+ throw new Exception (string.Format
+ ("GOML:malformed string constant in handler: {0}", rop));
+ string strcst = rop.Substring (1, rop.Length - 2);
+
+ il.Emit(OpCodes.Ldstr,strcst);
+
+ }else{
+ //search for a static field in left operand type named 'rop name'
+ FieldInfo ropFi = lopT.GetField (rop, BindingFlags.Static|BindingFlags.Public);
+ if (ropFi != null)
+ {
+ il.Emit (OpCodes.Ldsfld, ropFi);
+ }else{
+ //search if parsing methods are present
+ MethodInfo lopTryParseMi = lopT.GetMethod("TryParse");
+ //TODO
+ }
+ }
+
+ #endregion
+
+ //emit left operand assignment
+ il.Emit(lopSetOC, lopSetMbi);
+ }
+
+ il.Emit(OpCodes.Ret);
+
+ #endregion
+
+ Delegate del = dm.CreateDelegate(binding.Source.Event.EventHandlerType,this);
+ MethodInfo addHandler = binding.Source.Event.GetAddMethod ();
+ addHandler.Invoke(this, new object[] {del});
+ }
+ /// <summary>
+ /// Remove dynamic delegates by ids from dataSource
+ /// and delete ref of this in Shared interface refs
+ /// </summary>
+ public virtual void ClearBinding(){
+ foreach (Binding b in Bindings) {
+ if (string.IsNullOrEmpty (b.DynMethodId))
+ continue;
+ MemberReference mr = null;
+ if (b.Target == null)
+ mr = b.Source;
+ else
+ mr = b.Target;
+ Type dataSourceType = mr.Instance.GetType();
+ EventInfo evtInfo = dataSourceType.GetEvent ("ValueChanged");
+ FieldInfo evtFi = CompilerServices.GetEventHandlerField (dataSourceType, "ValueChanged");
+ MulticastDelegate multicastDelegate = evtFi.GetValue (mr.Instance) as MulticastDelegate;
+ if (multicastDelegate != null) {
+ foreach (Delegate d in multicastDelegate.GetInvocationList()) {
+ if (d.Method.Name == b.DynMethodId)
+ evtInfo.RemoveEventHandler (mr.Instance, d);
+ }
+ }
+ b.Reset ();
+ }
+ }
+ #endregion
+
+ #region IXmlSerializable
+ public virtual System.Xml.Schema.XmlSchema GetSchema ()
+ {
+ return null;
+ }
+ public virtual void ReadXml (System.Xml.XmlReader reader)
+ {
+ if (!reader.HasAttributes)
+ return;
+ Type thisType = this.GetType ();
+ while (reader.MoveToNextAttribute ()) {
+ string attName = reader.Name;
+ string attValue = reader.Value;
+
+ if (string.IsNullOrEmpty (attValue))
+ continue;
+
+ MemberInfo mi = thisType.GetMember (attName).FirstOrDefault();
+ if (mi == null) {
+ Debug.WriteLine ("GOML: Unknown attribute in " + thisType.ToString() + " : " + attName);
+ continue;
+ }
+ if (mi.MemberType == MemberTypes.Event) {
+ this.Bindings.Add (new Binding (new MemberReference(this, mi), attValue));
+ continue;
+ }
+ if (mi.MemberType == MemberTypes.Property) {
+ PropertyInfo pi = mi as PropertyInfo;
+
+ if (pi.GetSetMethod () == null)
+ continue;
+
+ bool isAttribute = false;
+ object defaultValue = null;
+
+ foreach (object attrib in pi.GetCustomAttributes ()) {
+ XmlAttributeAttribute xaa = attrib as XmlAttributeAttribute;
+ if (xaa != null) {
+ isAttribute = true;
+ if (!string.IsNullOrEmpty (xaa.AttributeName))
+ attName = xaa.AttributeName;
+ continue;
+ }
+ if (attrib is XmlIgnoreAttribute)
+ break;
+ DefaultValueAttribute dv = attrib as DefaultValueAttribute;
+ if (dv != null)
+ defaultValue = dv.Value;
+ }
+ if (!isAttribute)
+ continue;
+// {
+// //avoid system types automaticaly converted by parser
+// if (defaultValue != null && !pi.PropertyType.Namespace.StartsWith("System")) {
+// if (pi.PropertyType != defaultValue.GetType()) {
+// MethodInfo miParse = pi.PropertyType.GetMethod ("Parse", BindingFlags.Static | BindingFlags.Public);
+// if (miParse != null) {
+// pi.SetValue (this, miParse.Invoke (null, new object[]{ defaultValue }), null);
+// continue;
+// }
+// }
+// }
+// pi.SetValue (this, defaultValue, null);
+// } else {
+
+ if (attValue.StartsWith("{")) {
+ //binding
+ if (!attValue.EndsWith("}"))
+ throw new Exception (string.Format("GOML:Malformed binding: {0}", attValue));
+
+ this.Bindings.Add (new Binding (new MemberReference(this, pi), attValue.Substring (1, attValue.Length - 2)));
+ continue;
+ }
+
+ if (pi.PropertyType == typeof(string)) {
+ pi.SetValue (this, attValue, null);
+ continue;
+ }
+
+ if (pi.PropertyType.IsEnum) {
+ pi.SetValue (this, Enum.Parse (pi.PropertyType, attValue), null);
+ } else {
+ MethodInfo me = pi.PropertyType.GetMethod ("Parse", new Type[] { typeof(string) });
+ pi.SetValue (this, me.Invoke (null, new string[] { attValue }), null);
+ }
+ }
+ }
+ reader.MoveToElement();
+ }
+ public virtual void WriteXml (System.Xml.XmlWriter writer)
+ {
+ foreach (PropertyInfo pi in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
+ if (pi.GetSetMethod () == null)
+ continue;
+
+ bool isAttribute = false;
+ bool hasDefaultValue = false;
+ bool ignore = false;
+ string name = "";
+ object value = null;
+ Type valueType = null;
+
+
+ MemberInfo mi = pi.GetGetMethod ();
+
+ if (mi == null)
+ continue;
+
+ value = pi.GetValue (this, null);
+ valueType = pi.PropertyType;
+ name = pi.Name;
+
+
+
+ object[] att = pi.GetCustomAttributes (false);
+
+ foreach (object o in att) {
+ XmlAttributeAttribute xaa = o as XmlAttributeAttribute;
+ if (xaa != null) {
+ isAttribute = true;
+ if (string.IsNullOrEmpty (xaa.AttributeName))
+ name = pi.Name;
+ else
+ name = xaa.AttributeName;
+ continue;
+ }
+
+ XmlIgnoreAttribute xia = o as XmlIgnoreAttribute;
+ if (xia != null) {
+ ignore = true;
+ continue;
+ }
+
+ DefaultValueAttribute dv = o as DefaultValueAttribute;
+ if (dv != null) {
+ if (dv.Value.Equals (value))
+ hasDefaultValue = true;
+ if (dv.Value.ToString () == value.ToString ())
+ hasDefaultValue = true;
+
+ continue;
+ }
+
+
+ }
+
+ if (hasDefaultValue || ignore || value==null)
+ continue;
+
+ if (isAttribute)
+ writer.WriteAttributeString (name, value.ToString ());
+ else {
+ if (valueType.GetInterface ("IXmlSerializable") == null)
+ continue;
+
+ (pi.GetValue (this, null) as IXmlSerializable).WriteXml (writer);
+ }
+ }
+ foreach (EventInfo ei in this.GetType().GetEvents()) {
+ FieldInfo fi = this.GetType().GetField(ei.Name,
+ BindingFlags.NonPublic |
+ BindingFlags.Instance |
+ BindingFlags.GetField);
+
+ Delegate dg = (System.Delegate)fi.GetValue (this);
+
+ if (dg == null)
+ continue;
+
+ foreach (Delegate d in dg.GetInvocationList()) {
+ if (!d.Method.Name.StartsWith ("<"))//Skipping empty handler, not clear it's trikky
+ writer.WriteAttributeString (ei.Name, d.Method.Name);
+ }
+ }
+ }
+ #endregion
+
+ }
+}
diff --git a/src/GraphicObjects/Grid.cs b/src/GraphicObjects/Grid.cs
index a3233c96..6ce9a3c5 100644
--- a/src/GraphicObjects/Grid.cs
+++ b/src/GraphicObjects/Grid.cs
@@ -1,149 +1,149 @@
-using System;
-using System.Diagnostics;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Xml.Serialization;
-using System.ComponentModel;
-
-namespace Crow
-{
- /// <summary>
- /// Simple grid container
- /// Allow symetric placement of children on a grid,
- /// excedental child (above grid sizing) are ignored
- /// and invisible child keep their place in the grid
- /// </summary>
- public class Grid : Group
- {
- #region CTOR
- public Grid()
- : base()
- {
- }
- #endregion
-
- #region Private fields
- int _spacing;
- int _columnCount;
- int _rowCount;
- #endregion
-
- public override T addChild<T> (T child)
- {
- T tmp = base.addChild (child);
- this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
- return tmp;
- }
- public override void removeChild (GraphicObject child)
- {
- base.removeChild (child);
- this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
- }
-
- #region Public Properties
- [XmlAttributeAttribute()][DefaultValue(2)]
- public int Spacing
- {
- get { return _spacing; }
- set { _spacing = value; }
- }
- [XmlAttributeAttribute()][DefaultValue(1)]
- public virtual int ColumnCount
- {
- get { return _columnCount; }
- set {
- if (_columnCount == value)
- return;
-
- _columnCount = value;
-
- NotifyValueChanged ("ColumnCount", ColumnCount);
- this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
- }
- }
- [XmlAttributeAttribute()][DefaultValue(1)]
- public virtual int RowCount
- {
- get { return _rowCount; }
- set {
- if (_rowCount == value)
- return;
-
- _rowCount = value;
-
- NotifyValueChanged ("RowCount", RowCount);
- this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
- }
- }
- public virtual int CaseWidth {
- get { return (Slot.Width - (ColumnCount - 1) * Spacing) / ColumnCount; }
- }
- public virtual int CaseHeight {
- get { return (Slot.Height - (RowCount - 1) * Spacing) / RowCount; }
- }
-
- #endregion
-
- #region GraphicObject Overrides
-// protected override Size measureRawSize ()
-// {
-// Size tmp = new Size ();
-//
-// foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
-// tmp.Width = Math.Max (tmp.Width, c.Slot.Width);
-// tmp.Height = Math.Max (tmp.Height, c.Slot.Height);
-// }
-//
-// tmp.Width *= (ColumnCount - 1) * Spacing / ColumnCount;;
-// tmp.Height *= (RowCount - 1) * Spacing / RowCount;
-// tmp.Width += 2 * Margin;
-// tmp.Height += 2 * Margin;
-//
-// return tmp;
-// }
- public virtual void ComputeChildrenPositions()
- {
- int slotWidth = CaseWidth;
- int slotHeight = CaseHeight;
- for (int curY = 0; curY < RowCount; curY++) {
- for (int curX = 0; curX < ColumnCount; curX++) {
- int idx = curY * ColumnCount + curX;
- if (idx >= Children.Count)
- return;
- GraphicObject c = Children [idx];
- if (!c.Visible)
- continue;
- //ensure Item are not realigned
- c.HorizontalAlignment = HorizontalAlignment.Left;
- c.VerticalAlignment = VerticalAlignment.Top;
- c.Left = curX * (slotWidth + Spacing);
- c.Top = curY * (slotHeight + Spacing);
- c.Width = slotWidth;
- c.Height = slotHeight;
- }
- }
- }
-
- public override void RegisterForLayouting (int layoutType)
- {
- base.RegisterForLayouting (layoutType);
-
- if ((layoutType & (int)LayoutingType.PositionChildren) > 0)
- Interface.LayoutingQueue.Enqueue (LayoutingType.PositionChildren, this);
- }
- public override void UpdateLayout (LayoutingType layoutType)
- {
- if (layoutType == LayoutingType.PositionChildren) {
- ComputeChildrenPositions ();
- //if no layouting remains in queue for item, registre for redraw
- if (Interface.LayoutingQueue.Where (lq => lq.GraphicObject == this).Count () <= 0 && bmp==null)
- this.RegisterForRedraw ();
- }else
- base.UpdateLayout(layoutType);
- }
- #endregion
-
-
- }
-}
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml.Serialization;
+using System.ComponentModel;
+
+namespace Crow
+{
+ /// <summary>
+ /// Simple grid container
+ /// Allow symetric placement of children on a grid,
+ /// excedental child (above grid sizing) are ignored
+ /// and invisible child keep their place in the grid
+ /// </summary>
+ public class Grid : Group
+ {
+ #region CTOR
+ public Grid()
+ : base()
+ {
+ }
+ #endregion
+
+ #region Private fields
+ int _spacing;
+ int _columnCount;
+ int _rowCount;
+ #endregion
+
+ public override T addChild<T> (T child)
+ {
+ T tmp = base.addChild (child);
+ this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
+ return tmp;
+ }
+ public override void removeChild (GraphicObject child)
+ {
+ base.removeChild (child);
+ this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
+ }
+
+ #region Public Properties
+ [XmlAttributeAttribute()][DefaultValue(2)]
+ public int Spacing
+ {
+ get { return _spacing; }
+ set { _spacing = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue(1)]
+ public virtual int ColumnCount
+ {
+ get { return _columnCount; }
+ set {
+ if (_columnCount == value)
+ return;
+
+ _columnCount = value;
+
+ NotifyValueChanged ("ColumnCount", ColumnCount);
+ this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(1)]
+ public virtual int RowCount
+ {
+ get { return _rowCount; }
+ set {
+ if (_rowCount == value)
+ return;
+
+ _rowCount = value;
+
+ NotifyValueChanged ("RowCount", RowCount);
+ this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
+ }
+ }
+ public virtual int CaseWidth {
+ get { return (Slot.Width - (ColumnCount - 1) * Spacing) / ColumnCount; }
+ }
+ public virtual int CaseHeight {
+ get { return (Slot.Height - (RowCount - 1) * Spacing) / RowCount; }
+ }
+
+ #endregion
+
+ #region GraphicObject Overrides
+// protected override Size measureRawSize ()
+// {
+// Size tmp = new Size ();
+//
+// foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
+// tmp.Width = Math.Max (tmp.Width, c.Slot.Width);
+// tmp.Height = Math.Max (tmp.Height, c.Slot.Height);
+// }
+//
+// tmp.Width *= (ColumnCount - 1) * Spacing / ColumnCount;;
+// tmp.Height *= (RowCount - 1) * Spacing / RowCount;
+// tmp.Width += 2 * Margin;
+// tmp.Height += 2 * Margin;
+//
+// return tmp;
+// }
+ public virtual void ComputeChildrenPositions()
+ {
+ int slotWidth = CaseWidth;
+ int slotHeight = CaseHeight;
+ for (int curY = 0; curY < RowCount; curY++) {
+ for (int curX = 0; curX < ColumnCount; curX++) {
+ int idx = curY * ColumnCount + curX;
+ if (idx >= Children.Count)
+ return;
+ GraphicObject c = Children [idx];
+ if (!c.Visible)
+ continue;
+ //ensure Item are not realigned
+ c.HorizontalAlignment = HorizontalAlignment.Left;
+ c.VerticalAlignment = VerticalAlignment.Top;
+ c.Left = curX * (slotWidth + Spacing);
+ c.Top = curY * (slotHeight + Spacing);
+ c.Width = slotWidth;
+ c.Height = slotHeight;
+ }
+ }
+ }
+
+ public override void RegisterForLayouting (int layoutType)
+ {
+ base.RegisterForLayouting (layoutType);
+
+ if ((layoutType & (int)LayoutingType.PositionChildren) > 0)
+ Interface.LayoutingQueue.Enqueue (LayoutingType.PositionChildren, this);
+ }
+ public override void UpdateLayout (LayoutingType layoutType)
+ {
+ if (layoutType == LayoutingType.PositionChildren) {
+ ComputeChildrenPositions ();
+ //if no layouting remains in queue for item, registre for redraw
+ if (Interface.LayoutingQueue.Where (lq => lq.GraphicObject == this).Count () <= 0 && bmp==null)
+ this.RegisterForRedraw ();
+ }else
+ base.UpdateLayout(layoutType);
+ }
+ #endregion
+
+
+ }
+}
diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs
index 034a2616..e03399e9 100644
--- a/src/GraphicObjects/Group.cs
+++ b/src/GraphicObjects/Group.cs
@@ -1,317 +1,317 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Drawing;
-using System.Diagnostics;
-using Cairo;
-using System.Xml.Serialization;
-using System.ComponentModel;
-
-namespace Crow
-{
- public class Group : GraphicObject, IXmlSerializable
- {
- #region CTOR
- public Group()
- : base()
- {
- }
- #endregion
-
- #region EVENT HANDLERS
- public event EventHandler<EventArgs> ChildrenCleared;
- #endregion
-
- internal int maxChildrenWidth = 0;
- internal int maxChildrenHeight = 0;
-
- bool _multiSelect = false;
- List<GraphicObject> children = new List<GraphicObject>();
-
- public GraphicObject activeWidget;
-
- public virtual List<GraphicObject> Children {
- get { return children; }
- set { children = value; }
- }
- [XmlAttributeAttribute()][DefaultValue(false)]
- public bool MultiSelect
- {
- get { return _multiSelect; }
- set { _multiSelect = value; }
- }
-
-
- public virtual T addChild<T>(T child)
- {
- GraphicObject g = child as GraphicObject;
- Children.Add(g);
- g.Parent = this as GraphicObject;
- g.RegisterForLayouting ((int)LayoutingType.Sizing);
- return (T)child;
- }
- public virtual void removeChild(GraphicObject child)
- {
- child.ClearBinding ();
- child.Parent = null;
- Children.Remove(child);
- this.RegisterForLayouting ((int)LayoutingType.Sizing);
- }
- public virtual void ClearChildren()
- {
- int lim = children.Count;
- for (int i = 0; i < lim; i++) {
- GraphicObject g = Children [0];
- g.ClearBinding ();
- g.Parent = null;
- Children.Remove(g);
- }
- this.RegisterForLayouting ((int)LayoutingType.Sizing);
- ChildrenCleared.Raise (this, new EventArgs ());
- }
- 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 GraphicObject overrides
- [XmlIgnore]public override bool DrawingIsValid {
- get {
- if (!base.DrawingIsValid)
- return false;
- foreach (GraphicObject g in Children) {
- if (!g.DrawingIsValid)
- return false;
- }
- return true;
- }
- }
- public override void ResolveBindings ()
- {
- base.ResolveBindings ();
- foreach (GraphicObject w in Children)
- w.ResolveBindings ();
- }
- public override GraphicObject FindByName (string nameToFind)
- {
- if (Name == nameToFind)
- return this;
-
- foreach (GraphicObject w in Children) {
- GraphicObject r = w.FindByName (nameToFind);
- if (r != null)
- return r;
- }
- return null;
- }
- public override bool Contains (GraphicObject goToFind)
- {
- foreach (GraphicObject w in Children) {
- if (w == goToFind)
- return true;
- if (w.Contains (goToFind))
- return true;
- }
- return false;
- }
- protected override Size measureRawSize ()
- {
-// Size tmp = new Size ();
-//
-// foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
-// tmp.Width = Math.Max (tmp.Width, c.Slot.Right);
-// tmp.Height = Math.Max (tmp.Height, c.Slot.Bottom);
-// }
-//
-// tmp.Width += 2*Margin;
-// tmp.Height += 2*Margin;
-//
-// return tmp;
- return new Size(maxChildrenWidth + 2 * Margin, maxChildrenHeight + 2 * Margin);
- }
-
- public override void OnLayoutChanges (LayoutingType layoutType)
- {
- base.OnLayoutChanges (layoutType);
-
- GenericStack gs = this as GenericStack;
- //position smaller objects in group when group size is fit
- switch (layoutType) {
- case LayoutingType.Width:
- if (gs != null) {
- if (gs.Orientation == Orientation.Horizontal) {
- this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
- break;
- }
- }
- foreach (GraphicObject c in Children.Where(ch => ch.Visible)) {
- if (c.getBounds ().Width == 0)
- c.RegisterForLayouting ((int)LayoutingType.Width);
- else
- c.RegisterForLayouting ((int)LayoutingType.X);
- }
- break;
- case LayoutingType.Height:
- if (gs != null) {
- if (gs.Orientation == Orientation.Vertical) {
- this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
- break;
- }
- }
- foreach (GraphicObject c in Children.Where(ch => ch.Visible)) {
- if (c.getBounds ().Height == 0)
- c.RegisterForLayouting ((int)LayoutingType.Height);
- else
- c.RegisterForLayouting ((int)LayoutingType.Y);
- }
- break;
- }
- }
-
- public override Rectangle ContextCoordinates(Rectangle r){
- return r + ClientRectangle.Position;
- }
-
- protected override void onDraw (Context gr)
- {
- Rectangle rBack = new Rectangle (Slot.Size);
- gr.SetSourceColor(Background);
- CairoHelpers.CairoRectangle(gr,rBack,CornerRadius);
- gr.Fill ();
-
- foreach (GraphicObject g in Children) {
- g.Paint (ref gr);
- }
- }
-
- public override void Paint(ref Context ctx, Rectangles clip = null)
- {
- if ( !Visible )
- return;
-
- if (bmp == null)
- UpdateGraphic ();
- else {
- if (clip != null)
- clip.Rebase (this);
- else {
- clip = new Rectangles ();
- //TODO:added lately slot to empty clip,
- //should rework this precise case causing expandable not
- //to show image changes
- clip.AddRectangle (ContextCoordinates (Slot.Size));
- }
-
- if (!DrawingIsValid || clip != null) {//false when 1 child has changed
- //child having their content changed has to be repainted
- //and those with slot intersecting clip rectangle have also to be repainted
-
- using (ImageSurface cache =
- new ImageSurface (bmp, Format.Argb32, Slot.Width, Slot.Height, Slot.Width * 4)) {
- Context gr = new Context (cache);
- clip.clearAndClip (gr);
-
- Rectangle rBack = Slot.Size;
- gr.SetSourceColor(Background);
- CairoHelpers.CairoRectangle(gr,rBack,CornerRadius);
- gr.Fill ();
- #if DEBUG_CLIP_RECTANGLE
- clip.stroke (gr, Color.Amaranth.AdjustAlpha (0.8));
- #endif
- foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
- Rectangles childClip = clip.intersectingRects (ContextCoordinates(c.Slot));
- if (!c.DrawingIsValid || childClip.count > 0)
- c.Paint (ref gr, childClip);//, localClip);
- }
-
- gr.Dispose ();
- }
- }
- }
-
- base.Paint (ref ctx, clip);
- }
- #endregion
-
-
- #region Mouse handling
- public override void checkHoverWidget (OpenTK.Input.MouseMoveEventArgs e)
- {
- if (HostContainer.hoverWidget != this) {
- HostContainer.hoverWidget = this;
- onMouseEnter (this, e);
- }
- foreach (GraphicObject g in Children)
- {
- if (g.MouseIsIn(e.Position))
- {
- g.checkHoverWidget (e);
- return;
- }
- }
- base.checkHoverWidget (e);
- }
- #endregion
-
- #region IXmlSerializable
-
- public override System.Xml.Schema.XmlSchema GetSchema()
- {
- return null;
- }
- public override void ReadXml(System.Xml.XmlReader reader)
- {
- base.ReadXml(reader);
-
- using (System.Xml.XmlReader subTree = reader.ReadSubtree())
- {
- subTree.Read();
-
- while (!subTree.EOF)
- {
- subTree.Read();
-
- if (!subTree.IsStartElement())
- break;
-
- Type t = Type.GetType("Crow." + subTree.Name);
- GraphicObject go = (GraphicObject)Activator.CreateInstance(t);
- (go as IXmlSerializable).ReadXml(subTree);
- addChild(go);
- }
- }
- }
- public override void WriteXml(System.Xml.XmlWriter writer)
- {
- base.WriteXml(writer);
-
- foreach (GraphicObject go in Children)
- {
- writer.WriteStartElement(go.GetType().Name);
- (go as IXmlSerializable).WriteXml(writer);
- writer.WriteEndElement();
- }
- }
-
- #endregion
-
- public override void ClearBinding(){
- foreach (GraphicObject c in children)
- c.ClearBinding ();
- base.ClearBinding ();
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Drawing;
+using System.Diagnostics;
+using Cairo;
+using System.Xml.Serialization;
+using System.ComponentModel;
+
+namespace Crow
+{
+ public class Group : GraphicObject, IXmlSerializable
+ {
+ #region CTOR
+ public Group()
+ : base()
+ {
+ }
+ #endregion
+
+ #region EVENT HANDLERS
+ public event EventHandler<EventArgs> ChildrenCleared;
+ #endregion
+
+ internal int maxChildrenWidth = 0;
+ internal int maxChildrenHeight = 0;
+
+ bool _multiSelect = false;
+ List<GraphicObject> children = new List<GraphicObject>();
+
+ public GraphicObject activeWidget;
+
+ public virtual List<GraphicObject> Children {
+ get { return children; }
+ set { children = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue(false)]
+ public bool MultiSelect
+ {
+ get { return _multiSelect; }
+ set { _multiSelect = value; }
+ }
+
+
+ public virtual T addChild<T>(T child)
+ {
+ GraphicObject g = child as GraphicObject;
+ Children.Add(g);
+ g.Parent = this as GraphicObject;
+ g.RegisterForLayouting ((int)LayoutingType.Sizing);
+ return (T)child;
+ }
+ public virtual void removeChild(GraphicObject child)
+ {
+ child.ClearBinding ();
+ child.Parent = null;
+ Children.Remove(child);
+ this.RegisterForLayouting ((int)LayoutingType.Sizing);
+ }
+ public virtual void ClearChildren()
+ {
+ int lim = children.Count;
+ for (int i = 0; i < lim; i++) {
+ GraphicObject g = Children [0];
+ g.ClearBinding ();
+ g.Parent = null;
+ Children.Remove(g);
+ }
+ this.RegisterForLayouting ((int)LayoutingType.Sizing);
+ ChildrenCleared.Raise (this, new EventArgs ());
+ }
+ 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 GraphicObject overrides
+ [XmlIgnore]public override bool DrawingIsValid {
+ get {
+ if (!base.DrawingIsValid)
+ return false;
+ foreach (GraphicObject g in Children) {
+ if (!g.DrawingIsValid)
+ return false;
+ }
+ return true;
+ }
+ }
+ public override void ResolveBindings ()
+ {
+ base.ResolveBindings ();
+ foreach (GraphicObject w in Children)
+ w.ResolveBindings ();
+ }
+ public override GraphicObject FindByName (string nameToFind)
+ {
+ if (Name == nameToFind)
+ return this;
+
+ foreach (GraphicObject w in Children) {
+ GraphicObject r = w.FindByName (nameToFind);
+ if (r != null)
+ return r;
+ }
+ return null;
+ }
+ public override bool Contains (GraphicObject goToFind)
+ {
+ foreach (GraphicObject w in Children) {
+ if (w == goToFind)
+ return true;
+ if (w.Contains (goToFind))
+ return true;
+ }
+ return false;
+ }
+ protected override Size measureRawSize ()
+ {
+// Size tmp = new Size ();
+//
+// foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
+// tmp.Width = Math.Max (tmp.Width, c.Slot.Right);
+// tmp.Height = Math.Max (tmp.Height, c.Slot.Bottom);
+// }
+//
+// tmp.Width += 2*Margin;
+// tmp.Height += 2*Margin;
+//
+// return tmp;
+ return new Size(maxChildrenWidth + 2 * Margin, maxChildrenHeight + 2 * Margin);
+ }
+
+ public override void OnLayoutChanges (LayoutingType layoutType)
+ {
+ base.OnLayoutChanges (layoutType);
+
+ GenericStack gs = this as GenericStack;
+ //position smaller objects in group when group size is fit
+ switch (layoutType) {
+ case LayoutingType.Width:
+ if (gs != null) {
+ if (gs.Orientation == Orientation.Horizontal) {
+ this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
+ break;
+ }
+ }
+ foreach (GraphicObject c in Children.Where(ch => ch.Visible)) {
+ if (c.getBounds ().Width == 0)
+ c.RegisterForLayouting ((int)LayoutingType.Width);
+ else
+ c.RegisterForLayouting ((int)LayoutingType.X);
+ }
+ break;
+ case LayoutingType.Height:
+ if (gs != null) {
+ if (gs.Orientation == Orientation.Vertical) {
+ this.RegisterForLayouting ((int)LayoutingType.PositionChildren);
+ break;
+ }
+ }
+ foreach (GraphicObject c in Children.Where(ch => ch.Visible)) {
+ if (c.getBounds ().Height == 0)
+ c.RegisterForLayouting ((int)LayoutingType.Height);
+ else
+ c.RegisterForLayouting ((int)LayoutingType.Y);
+ }
+ break;
+ }
+ }
+
+ public override Rectangle ContextCoordinates(Rectangle r){
+ return r + ClientRectangle.Position;
+ }
+
+ protected override void onDraw (Context gr)
+ {
+ Rectangle rBack = new Rectangle (Slot.Size);
+ gr.SetSourceColor(Background);
+ CairoHelpers.CairoRectangle(gr,rBack,CornerRadius);
+ gr.Fill ();
+
+ foreach (GraphicObject g in Children) {
+ g.Paint (ref gr);
+ }
+ }
+
+ public override void Paint(ref Context ctx, Rectangles clip = null)
+ {
+ if ( !Visible )
+ return;
+
+ if (bmp == null)
+ UpdateGraphic ();
+ else {
+ if (clip != null)
+ clip.Rebase (this);
+ else {
+ clip = new Rectangles ();
+ //TODO:added lately slot to empty clip,
+ //should rework this precise case causing expandable not
+ //to show image changes
+ clip.AddRectangle (ContextCoordinates (Slot.Size));
+ }
+
+ if (!DrawingIsValid || clip != null) {//false when 1 child has changed
+ //child having their content changed has to be repainted
+ //and those with slot intersecting clip rectangle have also to be repainted
+
+ using (ImageSurface cache =
+ new ImageSurface (bmp, Format.Argb32, Slot.Width, Slot.Height, Slot.Width * 4)) {
+ Context gr = new Context (cache);
+ clip.clearAndClip (gr);
+
+ Rectangle rBack = Slot.Size;
+ gr.SetSourceColor(Background);
+ CairoHelpers.CairoRectangle(gr,rBack,CornerRadius);
+ gr.Fill ();
+ #if DEBUG_CLIP_RECTANGLE
+ clip.stroke (gr, Color.Amaranth.AdjustAlpha (0.8));
+ #endif
+ foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
+ Rectangles childClip = clip.intersectingRects (ContextCoordinates(c.Slot));
+ if (!c.DrawingIsValid || childClip.count > 0)
+ c.Paint (ref gr, childClip);//, localClip);
+ }
+
+ gr.Dispose ();
+ }
+ }
+ }
+
+ base.Paint (ref ctx, clip);
+ }
+ #endregion
+
+
+ #region Mouse handling
+ public override void checkHoverWidget (OpenTK.Input.MouseMoveEventArgs e)
+ {
+ if (HostContainer.hoverWidget != this) {
+ HostContainer.hoverWidget = this;
+ onMouseEnter (this, e);
+ }
+ foreach (GraphicObject g in Children)
+ {
+ if (g.MouseIsIn(e.Position))
+ {
+ g.checkHoverWidget (e);
+ return;
+ }
+ }
+ base.checkHoverWidget (e);
+ }
+ #endregion
+
+ #region IXmlSerializable
+
+ public override System.Xml.Schema.XmlSchema GetSchema()
+ {
+ return null;
+ }
+ public override void ReadXml(System.Xml.XmlReader reader)
+ {
+ base.ReadXml(reader);
+
+ using (System.Xml.XmlReader subTree = reader.ReadSubtree())
+ {
+ subTree.Read();
+
+ while (!subTree.EOF)
+ {
+ subTree.Read();
+
+ if (!subTree.IsStartElement())
+ break;
+
+ Type t = Type.GetType("Crow." + subTree.Name);
+ GraphicObject go = (GraphicObject)Activator.CreateInstance(t);
+ (go as IXmlSerializable).ReadXml(subTree);
+ addChild(go);
+ }
+ }
+ }
+ public override void WriteXml(System.Xml.XmlWriter writer)
+ {
+ base.WriteXml(writer);
+
+ foreach (GraphicObject go in Children)
+ {
+ writer.WriteStartElement(go.GetType().Name);
+ (go as IXmlSerializable).WriteXml(writer);
+ writer.WriteEndElement();
+ }
+ }
+
+ #endregion
+
+ public override void ClearBinding(){
+ foreach (GraphicObject c in children)
+ c.ClearBinding ();
+ base.ClearBinding ();
+ }
+ }
+}
diff --git a/src/GraphicObjects/GroupBox.cs b/src/GraphicObjects/GroupBox.cs
index 81bac117..9206792a 100644
--- a/src/GraphicObjects/GroupBox.cs
+++ b/src/GraphicObjects/GroupBox.cs
@@ -1,68 +1,68 @@
-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;
-using System.Xml.Serialization;
-using OpenTK.Input;
-using System.ComponentModel;
-using System.Xml;
-using System.IO;
-
-namespace Crow
-{
- [DefaultTemplate("#Crow.Templates.GroupBox.goml")]
- public class GroupBox : TemplatedContainer
- {
- string caption;
- Container _contentContainer;
-
- #region CTOR
- public GroupBox() : base(){}
- #endregion
-
- #region Template overrides
- public override GraphicObject Content {
- get {
- return _contentContainer == null ? null : _contentContainer.Child;
- }
- set {
- _contentContainer.SetChild(value);
- }
- }
- protected override void loadTemplate(GraphicObject template = null)
- {
- base.loadTemplate (template);
-
- _contentContainer = this.child.FindByName ("Content") as Container;
- }
- #endregion
-
- #region GraphicObject overrides
- [XmlAttributeAttribute()][DefaultValue(true)]//overiden to get default to true
- public override bool Focusable
- {
- get { return base.Focusable; }
- set { base.Focusable = value; }
- }
- #endregion
-
- [XmlAttributeAttribute()][DefaultValue("Groupbox")]
- public string Caption {
- get { return caption; }
- set {
- if (caption == value)
- return;
- caption = value;
- NotifyValueChanged ("Caption", caption);
- }
- }
- }
-}
+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;
+using System.Xml.Serialization;
+using OpenTK.Input;
+using System.ComponentModel;
+using System.Xml;
+using System.IO;
+
+namespace Crow
+{
+ [DefaultTemplate("#Crow.Templates.GroupBox.goml")]
+ public class GroupBox : TemplatedContainer
+ {
+ string caption;
+ Container _contentContainer;
+
+ #region CTOR
+ public GroupBox() : base(){}
+ #endregion
+
+ #region Template overrides
+ public override GraphicObject Content {
+ get {
+ return _contentContainer == null ? null : _contentContainer.Child;
+ }
+ set {
+ _contentContainer.SetChild(value);
+ }
+ }
+ protected override void loadTemplate(GraphicObject template = null)
+ {
+ base.loadTemplate (template);
+
+ _contentContainer = this.child.FindByName ("Content") as Container;
+ }
+ #endregion
+
+ #region GraphicObject overrides
+ [XmlAttributeAttribute()][DefaultValue(true)]//overiden to get default to true
+ public override bool Focusable
+ {
+ get { return base.Focusable; }
+ set { base.Focusable = value; }
+ }
+ #endregion
+
+ [XmlAttributeAttribute()][DefaultValue("Groupbox")]
+ public string Caption {
+ get { return caption; }
+ set {
+ if (caption == value)
+ return;
+ caption = value;
+ NotifyValueChanged ("Caption", caption);
+ }
+ }
+ }
+}
diff --git a/src/GraphicObjects/HorizontalStack.cs b/src/GraphicObjects/HorizontalStack.cs
index 21991a9a..30fded86 100644
--- a/src/GraphicObjects/HorizontalStack.cs
+++ b/src/GraphicObjects/HorizontalStack.cs
@@ -1,23 +1,23 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Xml.Serialization;
-
-namespace Crow
-{
- public class HorizontalStack : GenericStack
- {
- public HorizontalStack()
- : base()
- {
- Orientation = Crow.Orientation.Horizontal;
- }
-
- [XmlIgnore]
- public override Orientation Orientation
- {
- get { return Orientation.Horizontal; }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml.Serialization;
+
+namespace Crow
+{
+ public class HorizontalStack : GenericStack
+ {
+ public HorizontalStack()
+ : base()
+ {
+ Orientation = Crow.Orientation.Horizontal;
+ }
+
+ [XmlIgnore]
+ public override Orientation Orientation
+ {
+ get { return Orientation.Horizontal; }
+ }
+ }
+}
diff --git a/src/GraphicObjects/Image.cs b/src/GraphicObjects/Image.cs
index e7f75fe8..b8260c55 100644
--- a/src/GraphicObjects/Image.cs
+++ b/src/GraphicObjects/Image.cs
@@ -1,115 +1,115 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Cairo;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Xml.Serialization;
-using System.ComponentModel;
-using System.Diagnostics;
-
-namespace Crow
-{
- public class Image : GraphicObject
- {
- Picture _pic;
- string _svgSub;
- bool scaled;
- [XmlAttributeAttribute()][DefaultValue(true)]
- public virtual bool Scaled {
- get { return scaled; }
- set {
- if (scaled == value)
- return;
- scaled = value;
- NotifyValueChanged ("Scaled", scaled);
- if (_pic == null)
- return;
- _pic.Scaled = scaled;
- registerForGraphicUpdate ();
- }
- }
- bool keepProps;
- [XmlAttributeAttribute()][DefaultValue(true)]
- public virtual bool KeepProportions {
- get { return keepProps; }
- set {
- if (keepProps == value)
- return;
- keepProps = value;
- NotifyValueChanged ("KeepProportions", keepProps);
- if (_pic == null)
- return;
- _pic.KeepProportions = keepProps;
- registerForGraphicUpdate ();
- }
- }
- [XmlAttributeAttribute("Path")]
- public string Path {
- get { return _pic == null ? null : _pic.Path; }
- set {
- try {
- if (string.IsNullOrEmpty(value)){
- _pic = null;
- return;
- }
- LoadImage (value);
- _pic.Scaled = scaled;
- _pic.KeepProportions = keepProps;
- } catch (Exception ex) {
- Debug.WriteLine (ex.Message);
- _pic = null;
- }
- }
- }
-
- [XmlAttributeAttribute()][DefaultValue(null)]
- public string SvgSub {
- get { return _svgSub; }
- set {
- _svgSub = value;
- registerForGraphicUpdate ();
- }
- }
-
- #region CTOR
- public Image () : base()
- {
- }
- #endregion
-
- #region Image Loading
- public void LoadImage (string path)
- {
-
- if (path.EndsWith (".svg", true, System.Globalization.CultureInfo.InvariantCulture))
- _pic = new SvgPicture ();
- else
- _pic = new BmpPicture ();
-
- _pic.LoadImage (path);
- registerForGraphicUpdate ();
- }
- #endregion
-
- #region GraphicObject overrides
- protected override Size measureRawSize ()
- {
-// if (_pic == null)
-// _pic = "#Crow.Images.Icons.IconAlerte.svg";
-
- return _pic.Dimensions + Margin * 2;
- }
- protected override void onDraw (Context gr)
- {
- base.onDraw (gr);
-
- if (_pic == null)
- return;
-
- _pic.Paint (gr, ClientRectangle, _svgSub);
- }
- #endregion
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Cairo;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Xml.Serialization;
+using System.ComponentModel;
+using System.Diagnostics;
+
+namespace Crow
+{
+ public class Image : GraphicObject
+ {
+ Picture _pic;
+ string _svgSub;
+ bool scaled;
+ [XmlAttributeAttribute()][DefaultValue(true)]
+ public virtual bool Scaled {
+ get { return scaled; }
+ set {
+ if (scaled == value)
+ return;
+ scaled = value;
+ NotifyValueChanged ("Scaled", scaled);
+ if (_pic == null)
+ return;
+ _pic.Scaled = scaled;
+ registerForGraphicUpdate ();
+ }
+ }
+ bool keepProps;
+ [XmlAttributeAttribute()][DefaultValue(true)]
+ public virtual bool KeepProportions {
+ get { return keepProps; }
+ set {
+ if (keepProps == value)
+ return;
+ keepProps = value;
+ NotifyValueChanged ("KeepProportions", keepProps);
+ if (_pic == null)
+ return;
+ _pic.KeepProportions = keepProps;
+ registerForGraphicUpdate ();
+ }
+ }
+ [XmlAttributeAttribute("Path")]
+ public string Path {
+ get { return _pic == null ? null : _pic.Path; }
+ set {
+ try {
+ if (string.IsNullOrEmpty(value)){
+ _pic = null;
+ return;
+ }
+ LoadImage (value);
+ _pic.Scaled = scaled;
+ _pic.KeepProportions = keepProps;
+ } catch (Exception ex) {
+ Debug.WriteLine (ex.Message);
+ _pic = null;
+ }
+ }
+ }
+
+ [XmlAttributeAttribute()][DefaultValue(null)]
+ public string SvgSub {
+ get { return _svgSub; }
+ set {
+ _svgSub = value;
+ registerForGraphicUpdate ();
+ }
+ }
+
+ #region CTOR
+ public Image () : base()
+ {
+ }
+ #endregion
+
+ #region Image Loading
+ public void LoadImage (string path)
+ {
+
+ if (path.EndsWith (".svg", true, System.Globalization.CultureInfo.InvariantCulture))
+ _pic = new SvgPicture ();
+ else
+ _pic = new BmpPicture ();
+
+ _pic.LoadImage (path);
+ registerForGraphicUpdate ();
+ }
+ #endregion
+
+ #region GraphicObject overrides
+ protected override Size measureRawSize ()
+ {
+// if (_pic == null)
+// _pic = "#Crow.Images.Icons.IconAlerte.svg";
+
+ return _pic.Dimensions + Margin * 2;
+ }
+ protected override void onDraw (Context gr)
+ {
+ base.onDraw (gr);
+
+ if (_pic == null)
+ return;
+
+ _pic.Paint (gr, ClientRectangle, _svgSub);
+ }
+ #endregion
+ }
+}
diff --git a/src/GraphicObjects/Label.cs b/src/GraphicObjects/Label.cs
index 1af9e04b..0b93924a 100644
--- a/src/GraphicObjects/Label.cs
+++ b/src/GraphicObjects/Label.cs
@@ -1,679 +1,679 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Diagnostics;
-using Cairo;
-using System.Text.RegularExpressions;
-using System.Xml.Serialization;
-using System.ComponentModel;
-using OpenTK.Input;
-
-namespace Crow
-{
- [Serializable]
- public class Label : GraphicObject
- {
- #region CTOR
- public Label()
- {
-
- }
- public Label(string _text)
- : base()
- {
- Text = _text;
- }
- #endregion
-
- //TODO:change protected to private
-
- #region private and protected fields
- string _text = "label";
- Alignment _textAlignment = Alignment.LeftCenter;
- bool _multiline = false;
- Color selColor;
- Color selFontColor;
- Point mouseLocalPos = -1;//mouse coord in widget space, filled only when clicked
- int _currentCol; //0 based cursor position in string
- int _currentLine;
- Point _selBegin = -1; //selection start (row,column)
- Point _selRelease = -1; //selection end (row,column)
- double textCursorPos; //cursor position in cairo units in widget client coord.
- double SelStartCursorPos = -1;
- double SelEndCursorPos = -1;
- bool SelectionInProgress = false;
-
- protected Rectangle rText;
- protected float widthRatio = 1f;
- protected float heightRatio = 1f;
- protected FontExtents fe;
- protected TextExtents te;
- #endregion
-
- [XmlAttributeAttribute()][DefaultValue("SteelBlue")]
- public virtual Color SelectionBackground {
- get { return selColor; }
- set {
- if (value == selColor)
- return;
- selColor = value;
- NotifyValueChanged ("SelectionBackground", selColor);
- registerForGraphicUpdate ();
- }
- }
- [XmlAttributeAttribute()][DefaultValue("White")]
- public virtual Color SelectionForeground {
- get { return selFontColor; }
- set {
- if (value == selFontColor)
- return;
- selFontColor = value;
- NotifyValueChanged ("SelectionForeground", selFontColor);
- registerForGraphicUpdate ();
- }
- }
- [XmlAttributeAttribute()][DefaultValue(Alignment.LeftCenter)]
- public Alignment TextAlignment
- {
- get { return _textAlignment; }
- set {
- if (value == _textAlignment)
- return;
- _textAlignment = value;
- registerForGraphicUpdate ();
- NotifyValueChanged ("TextAlignment", _textAlignment);
- }
- }
- [XmlAttributeAttribute()][DefaultValue("label")]
- public string Text
- {
- get {
- return lines == null ?
- _text : lines.Aggregate((i, j) => i + Interface.LineBreak + j);
- }
- set
- {
- if (_text == value)
- return;
-
- _text = value;
-
- if (string.IsNullOrEmpty(_text))
- _text = "";
-
- lines = getLines;
-
- this.registerForGraphicUpdate ();
- this.RegisterForLayouting ((int)LayoutingType.Sizing);
- NotifyValueChanged ("Text", Text);
- }
- }
- [XmlAttributeAttribute()][DefaultValue(false)]
- public bool Multiline
- {
- get { return _multiline; }
- set
- {
- if (value == _multiline)
- return;
- _multiline = value;
- NotifyValueChanged ("Multiline", _multiline);
- registerForGraphicUpdate();
- }
- }
- [XmlIgnore]public int CurrentColumn{
- get { return _currentCol; }
- set {
- if (value == _currentCol)
- return;
- if (value < 0)
- _currentCol = 0;
- else if (value > lines [_currentLine].Count ())
- _currentCol = lines [_currentLine].Count ();
- else
- _currentCol = value;
- NotifyValueChanged ("CurrentColumn", _currentCol);
- }
- }
- [XmlIgnore]public int CurrentLine{
- get { return _currentLine; }
- set {
- if (value == _currentLine)
- return;
- if (value > lines.Count)
- _currentLine = lines.Count;
- else if (value < 0)
- _currentLine = 0;
- else
- _currentLine = value;
- NotifyValueChanged ("CurrentLine", _currentLine);
- }
- }
- [XmlIgnore]public Point SelBegin {
- get {
- return _selBegin;
- }
- set {
- if (value == _selBegin)
- return;
- _selBegin = value;
- NotifyValueChanged ("SelectedText", SelectedText);
- }
- }
- [XmlIgnore]public Point SelRelease {
- get {
- return _selRelease;
- }
- set {
- if (value == _selRelease)
- return;
- _selRelease = value;
- NotifyValueChanged ("SelectedText", SelectedText);
- }
- }
-
- [XmlIgnore]protected Point selectionStart //ordered selection start and end positions
- {
- get {
- return SelRelease < 0 || SelBegin.Y < SelRelease.Y ? SelBegin :
- SelBegin.Y > SelRelease.Y ? SelRelease :
- SelBegin.X < SelRelease.X ? SelBegin : SelRelease;
- }
- }
- [XmlIgnore]public Point selectionEnd
- {
- get {
- return SelRelease < 0 || SelBegin.Y > SelRelease.Y ? SelBegin :
- SelBegin.Y < SelRelease.Y ? SelRelease :
- SelBegin.X > SelRelease.X ? SelBegin : SelRelease;
- }
- }
- [XmlIgnore]public string SelectedText
- {
- get {
-
- if (SelRelease < 0 || SelBegin < 0)
- return "";
- if (selectionStart.Y == selectionEnd.Y)
- return lines [selectionStart.Y].Substring (selectionStart.X, selectionEnd.X - selectionStart.X);
- string tmp = "";
- tmp = lines [selectionStart.Y].Substring (selectionStart.X);
- for (int l = selectionStart.Y + 1; l < selectionEnd.Y; l++) {
- tmp += Interface.LineBreak + lines [l];
- }
- tmp += Interface.LineBreak + lines [selectionEnd.Y].Substring (0, selectionEnd.X);
- return tmp;
- }
- }
- [XmlIgnore]public bool selectionIsEmpty
- { get { return SelRelease < 0; } }
-
- List<string> lines;
- List<string> getLines {
- get {
- return _multiline ?
- Regex.Split (_text, "\r\n|\r|\n|" + @"\\n").ToList() :
- new List<string>(new string[] { _text });
- }
- }
-
- public void DeleteChar()
- {
- if (selectionIsEmpty) {
- if (CurrentColumn == 0) {
- if (CurrentLine == 0)
- return;
- CurrentLine--;
- CurrentColumn = lines [CurrentLine].Count ();
- lines [CurrentLine] += lines [CurrentLine + 1];
- lines.RemoveAt (CurrentLine + 1);
- return;
- }
- CurrentColumn--;
- lines [CurrentLine] = lines [CurrentLine].Remove (CurrentColumn, 1);
- } else {
- Debug.WriteLine (selectionEnd.ToString());
- int linesToRemove = selectionEnd.Y - selectionStart.Y;
- int l = selectionStart.Y;
-
- if (linesToRemove > 0) {
- lines [l] = lines [l].Remove (selectionStart.X, lines [l].Length - selectionStart.X) +
- lines [selectionEnd.Y].Substring (selectionEnd.X, lines [selectionEnd.Y].Length - selectionEnd.X);
- l++;
- for (int c = 0; c < linesToRemove-1; c++)
- lines.RemoveAt (l);
- CurrentColumn = selectionStart.X;
- CurrentLine = selectionStart.Y;
- } else
- lines [l] = lines [l].Remove (selectionStart.X, selectionEnd.X - selectionStart.X);
- CurrentColumn = selectionStart.X;
- SelBegin = -1;
- SelRelease = -1;
- }
- }
- /// <summary>
- /// Insert new string at caret position, should be sure no line break is inside.
- /// </summary>
- /// <param name="str">String.</param>
- protected void Insert(string str)
- {
- lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, str);
- CurrentColumn += str.Length;
- }
-
- #region GraphicObject overrides
- [XmlAttributeAttribute()][DefaultValue(-1)]
- public override int Width {
- get { return base.Width; }
- set { base.Width = value; }
- }
- [XmlAttributeAttribute()][DefaultValue(-1)]
- public override int Height {
- get { return base.Height; }
- set { base.Height = value; }
- }
-
- protected override Size measureRawSize()
- {
- Size size;
-
- if (lines == null)
- lines = getLines;
-
- using (ImageSurface img = new ImageSurface (Format.Argb32, 10, 10)) {
- using (Context gr = new Context (img)) {
- //Cairo.FontFace cf = gr.GetContextFontFace ();
-
- gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
- gr.SetFontSize (Font.Size);
-
- te = new TextExtents();
-
- foreach (string s in lines) {
- string l = s.Replace("\t", new String (' ', Interface.TabSize));
-
-#if _WIN32 || _WIN64
- TextExtents tmp = gr.TextExtents(str.ToUtf8());
-#elif __linux__
- TextExtents tmp = gr.TextExtents (l);
-#endif
- if (tmp.XAdvance > te.XAdvance)
- te = tmp;
- }
- fe = gr.FontExtents;
- int lc = lines.Count;
- //ensure minimal height = text line height
- if (lc == 0)
- lc = 1;
- size = new Size ((int)Math.Ceiling (te.XAdvance) + Margin * 2, (int)(fe.Height * lc) + Margin*2);
- }
- }
-
- return size;;
- }
- protected override void onDraw (Context gr)
- {
- base.onDraw (gr);
-
- gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
- gr.SetFontSize (Font.Size);
-
- gr.Antialias = Antialias.Subpixel;
- //gr.FontOptions.Antialias = Antialias.Subpixel;
- //gr.FontOptions.HintMetrics = HintMetrics.On;
-
- rText = new Rectangle(measureRawSize());
- rText.Width -= 2 * Margin;
- rText.Height -= 2 * Margin;
-
- widthRatio = 1f;
- heightRatio = 1f;
-
- Rectangle cb = ClientRectangle;
-
- //ignore text alignment if size to content = true
- if (Bounds.Size < 0)
- {
- rText.X = cb.X;
- rText.Y = cb.Y;
- }else{
- 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 * rText.Width);
- rText.X = cb.Right - rText.Width;
- 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;
- 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 * Font.Size, 0, 0, heightRatio * Font.Size, 0, 0);
- fe = gr.FontExtents;
-
- #region draw text cursor
- if (mouseLocalPos >= 0)
- {
- computeTextCursor(gr);
-
- if (SelectionInProgress)
- {
- if (SelBegin < 0){
- SelBegin = new Point(CurrentColumn, CurrentLine);
- SelStartCursorPos = textCursorPos;
- SelRelease = -1;
- }else{
- SelRelease = new Point(CurrentColumn, CurrentLine);
- if (SelRelease == SelBegin)
- SelRelease = -1;
- else
- SelEndCursorPos = textCursorPos;
- }
- }
- }else
- computeTextCursorPosition(gr);
-
-
- #endregion
-
- //****** debug selection *************
-// if (SelRelease >= 0) {
-// gr.Color = Color.Green;
-// Rectangle R = new Rectangle (
-// rText.X + (int)SelEndCursorPos - 2,
-// rText.Y + (int)(SelRelease.Y * fe.Height),
-// 4,
-// (int)fe.Height);
-// gr.Rectangle (R);
-// gr.Fill ();
-// }
-// if (SelBegin >= 0) {
-// gr.Color = Color.UnmellowYellow;
-// Rectangle R = new Rectangle (
-// rText.X + (int)SelStartCursorPos - 2,
-// rText.Y + (int)(SelBegin.Y * fe.Height),
-// 4,
-// (int)fe.Height);
-// gr.Rectangle (R);
-// gr.Fill ();
-// }
- //*******************
-
- if (HasFocus )
- {
- gr.SetSourceColor(Foreground);
- gr.LineWidth = 1.5;
- gr.MoveTo(new PointD(textCursorPos + rText.X, rText.Y + CurrentLine * fe.Height));
- gr.LineTo(new PointD(textCursorPos + rText.X, rText.Y + (CurrentLine + 1) * fe.Height));
- gr.Stroke();
- }
-
- for (int i = 0; i < lines.Count; i++) {
- string l = lines [i].Replace ("\t", new String (' ', Interface.TabSize));
- int lineLength = (int)gr.TextExtents (l).XAdvance;
- Rectangle lineRect = new Rectangle (
- rText.X,
- rText.Y + (int)(i * fe.Height),
- lineLength,
- (int)fe.Height);
-
-// if (TextAlignment == Alignment.Center ||
-// TextAlignment == Alignment.TopCenter ||
-// TextAlignment == Alignment.BottomCenter)
-// lineRect.X += (rText.Width - lineLength) / 2;
-// else if (TextAlignment == Alignment.RightCenter ||
-// TextAlignment == Alignment.TopRight ||
-// TextAlignment == Alignment.BottomRight)
-// lineRect.X += (rText.Width - lineLength);
-
- if (SelRelease >= 0 && i >= selectionStart.Y && i <= selectionEnd.Y) {
- gr.SetSourceColor(selColor);
-
- Rectangle selRect = lineRect ;
-
- int cpStart = (int)SelStartCursorPos,
- cpEnd = (int)SelEndCursorPos;
-
- if (SelBegin.Y > SelRelease.Y) {
- cpStart = cpEnd;
- cpEnd = (int)SelStartCursorPos;
- }
-
- if (i == selectionStart.Y) {
- selRect.Width -= cpStart;
- selRect.Left += cpStart;
- }
- if (i == selectionEnd.Y)
- selRect.Width -= (lineLength - cpEnd);
-
- gr.Rectangle (selRect);
- gr.Fill ();
- }
-
- if (string.IsNullOrWhiteSpace (l))
- continue;
-
- gr.SetSourceColor(Foreground);
- gr.MoveTo (lineRect.X, rText.Y + fe.Ascent + fe.Height * i);
-
- #if _WIN32 || _WIN64
- gr.ShowText(l.ToUtf8());
- #elif __linux__
- gr.ShowText (l);
- #endif
- gr.Fill ();
- }
- }
- #endregion
-
- #region Mouse handling
- void updatemouseLocalPos(Point mpos){
- mouseLocalPos = mpos - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft;
- if (mouseLocalPos.X < 0)
- mouseLocalPos.X = 0;
- if (mouseLocalPos.Y < 0)
- mouseLocalPos.Y = 0;
- }
- public override void onFocused (object sender, EventArgs e)
- {
- base.onFocused (sender, e);
-
- SelBegin = new Point(0,0);
- SelRelease = new Point (lines.LastOrDefault ().Length, lines.Count-1);
- registerForGraphicUpdate ();
- }
- public override void onUnfocused (object sender, EventArgs e)
- {
- base.onUnfocused (sender, e);
-
- SelBegin = -1;
- SelRelease = -1;
- registerForGraphicUpdate ();
- }
- public override void onMouseMove (object sender, MouseMoveEventArgs e)
- {
- base.onMouseMove (sender, e);
-
- if (!(SelectionInProgress && HasFocus))
- return;
-
- updatemouseLocalPos (e.Position);
-
- registerForGraphicUpdate();
- }
- public override void onMouseDown (object sender, MouseButtonEventArgs e)
- {
- if (this.HasFocus){
- updatemouseLocalPos (e.Position);
- SelBegin = -1;
- SelRelease = -1;
- SelectionInProgress = true;
- }
-
- //done at the end to set 'hasFocus' value after testing it
- base.onMouseDown (sender, e);
-
- registerForGraphicUpdate();
- }
- public override void onMouseUp (object sender, MouseButtonEventArgs e)
- {
- base.onMouseUp (sender, e);
-
- if (!SelectionInProgress)
- return;
-
- updatemouseLocalPos (e.Position);
- SelectionInProgress = false;
- registerForGraphicUpdate ();
- }
- #endregion
- /// <summary>
- /// Update Current Column, line and TextCursorPos
- /// from mouseLocalPos
- /// </summary>
- void computeTextCursor(Context gr)
- {
- TextExtents te;
-
- double cPos = 0f;
-
- CurrentLine = (int)(mouseLocalPos.Y / fe.Height);
-
- //fix cu
- if (CurrentLine >= lines.Count)
- CurrentLine = lines.Count - 1;
-
- for (int i = 0; i < lines[CurrentLine].Length; i++)
- {
- string c = lines [CurrentLine].Substring (i, 1);
- if (c == "\t")
- c = new string (' ', Interface.TabSize);
-
- #if _WIN32 || _WIN64
- byte[] c = System.Text.UTF8Encoding.UTF8.GetBytes(Text.Substring(i, 1));
- te = gr.TextExtents(c);
- #elif __linux__
- te = gr.TextExtents(c);
- #endif
- double halfWidth = te.XAdvance / 2;
-
- if (mouseLocalPos.X <= cPos + halfWidth)
- {
- CurrentColumn = i;
- textCursorPos = cPos;
- mouseLocalPos = -1;
- return;
- }
-
- cPos += te.XAdvance;
- }
- CurrentColumn = lines[CurrentLine].Length;
- textCursorPos = cPos;
-
- //reset mouseLocalPos
- mouseLocalPos = -1;
- }
- /// <summary> Computes offsets in cairo units </summary>
- void computeTextCursorPosition(Context gr)
- {
- if (SelBegin >= 0)
- SelStartCursorPos = GetXFromTextPointer (gr, SelBegin);
- if (SelRelease >= 0)
- SelEndCursorPos = GetXFromTextPointer (gr, SelRelease);
- textCursorPos = GetXFromTextPointer (gr, new Point(CurrentColumn, CurrentLine));
- }
- /// <summary> Compute x offset in cairo unit from text position </summary>
- double GetXFromTextPointer(Context gr, Point pos)
- {
- try {
- string l = lines [pos.Y].Substring (0, pos.X).
- Replace ("\t", new String (' ', Interface.TabSize));
- return gr.TextExtents (l).XAdvance;
- } catch{
- return -1;
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Diagnostics;
+using Cairo;
+using System.Text.RegularExpressions;
+using System.Xml.Serialization;
+using System.ComponentModel;
+using OpenTK.Input;
+
+namespace Crow
+{
+ [Serializable]
+ public class Label : GraphicObject
+ {
+ #region CTOR
+ public Label()
+ {
+
+ }
+ public Label(string _text)
+ : base()
+ {
+ Text = _text;
+ }
+ #endregion
+
+ //TODO:change protected to private
+
+ #region private and protected fields
+ string _text = "label";
+ Alignment _textAlignment = Alignment.LeftCenter;
+ bool _multiline = false;
+ Color selColor;
+ Color selFontColor;
+ Point mouseLocalPos = -1;//mouse coord in widget space, filled only when clicked
+ int _currentCol; //0 based cursor position in string
+ int _currentLine;
+ Point _selBegin = -1; //selection start (row,column)
+ Point _selRelease = -1; //selection end (row,column)
+ double textCursorPos; //cursor position in cairo units in widget client coord.
+ double SelStartCursorPos = -1;
+ double SelEndCursorPos = -1;
+ bool SelectionInProgress = false;
+
+ protected Rectangle rText;
+ protected float widthRatio = 1f;
+ protected float heightRatio = 1f;
+ protected FontExtents fe;
+ protected TextExtents te;
+ #endregion
+
+ [XmlAttributeAttribute()][DefaultValue("SteelBlue")]
+ public virtual Color SelectionBackground {
+ get { return selColor; }
+ set {
+ if (value == selColor)
+ return;
+ selColor = value;
+ NotifyValueChanged ("SelectionBackground", selColor);
+ registerForGraphicUpdate ();
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue("White")]
+ public virtual Color SelectionForeground {
+ get { return selFontColor; }
+ set {
+ if (value == selFontColor)
+ return;
+ selFontColor = value;
+ NotifyValueChanged ("SelectionForeground", selFontColor);
+ registerForGraphicUpdate ();
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(Alignment.LeftCenter)]
+ public Alignment TextAlignment
+ {
+ get { return _textAlignment; }
+ set {
+ if (value == _textAlignment)
+ return;
+ _textAlignment = value;
+ registerForGraphicUpdate ();
+ NotifyValueChanged ("TextAlignment", _textAlignment);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue("label")]
+ public string Text
+ {
+ get {
+ return lines == null ?
+ _text : lines.Aggregate((i, j) => i + Interface.LineBreak + j);
+ }
+ set
+ {
+ if (_text == value)
+ return;
+
+ _text = value;
+
+ if (string.IsNullOrEmpty(_text))
+ _text = "";
+
+ lines = getLines;
+
+ this.registerForGraphicUpdate ();
+ this.RegisterForLayouting ((int)LayoutingType.Sizing);
+ NotifyValueChanged ("Text", Text);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(false)]
+ public bool Multiline
+ {
+ get { return _multiline; }
+ set
+ {
+ if (value == _multiline)
+ return;
+ _multiline = value;
+ NotifyValueChanged ("Multiline", _multiline);
+ registerForGraphicUpdate();
+ }
+ }
+ [XmlIgnore]public int CurrentColumn{
+ get { return _currentCol; }
+ set {
+ if (value == _currentCol)
+ return;
+ if (value < 0)
+ _currentCol = 0;
+ else if (value > lines [_currentLine].Count ())
+ _currentCol = lines [_currentLine].Count ();
+ else
+ _currentCol = value;
+ NotifyValueChanged ("CurrentColumn", _currentCol);
+ }
+ }
+ [XmlIgnore]public int CurrentLine{
+ get { return _currentLine; }
+ set {
+ if (value == _currentLine)
+ return;
+ if (value > lines.Count)
+ _currentLine = lines.Count;
+ else if (value < 0)
+ _currentLine = 0;
+ else
+ _currentLine = value;
+ NotifyValueChanged ("CurrentLine", _currentLine);
+ }
+ }
+ [XmlIgnore]public Point SelBegin {
+ get {
+ return _selBegin;
+ }
+ set {
+ if (value == _selBegin)
+ return;
+ _selBegin = value;
+ NotifyValueChanged ("SelectedText", SelectedText);
+ }
+ }
+ [XmlIgnore]public Point SelRelease {
+ get {
+ return _selRelease;
+ }
+ set {
+ if (value == _selRelease)
+ return;
+ _selRelease = value;
+ NotifyValueChanged ("SelectedText", SelectedText);
+ }
+ }
+
+ [XmlIgnore]protected Point selectionStart //ordered selection start and end positions
+ {
+ get {
+ return SelRelease < 0 || SelBegin.Y < SelRelease.Y ? SelBegin :
+ SelBegin.Y > SelRelease.Y ? SelRelease :
+ SelBegin.X < SelRelease.X ? SelBegin : SelRelease;
+ }
+ }
+ [XmlIgnore]public Point selectionEnd
+ {
+ get {
+ return SelRelease < 0 || SelBegin.Y > SelRelease.Y ? SelBegin :
+ SelBegin.Y < SelRelease.Y ? SelRelease :
+ SelBegin.X > SelRelease.X ? SelBegin : SelRelease;
+ }
+ }
+ [XmlIgnore]public string SelectedText
+ {
+ get {
+
+ if (SelRelease < 0 || SelBegin < 0)
+ return "";
+ if (selectionStart.Y == selectionEnd.Y)
+ return lines [selectionStart.Y].Substring (selectionStart.X, selectionEnd.X - selectionStart.X);
+ string tmp = "";
+ tmp = lines [selectionStart.Y].Substring (selectionStart.X);
+ for (int l = selectionStart.Y + 1; l < selectionEnd.Y; l++) {
+ tmp += Interface.LineBreak + lines [l];
+ }
+ tmp += Interface.LineBreak + lines [selectionEnd.Y].Substring (0, selectionEnd.X);
+ return tmp;
+ }
+ }
+ [XmlIgnore]public bool selectionIsEmpty
+ { get { return SelRelease < 0; } }
+
+ List<string> lines;
+ List<string> getLines {
+ get {
+ return _multiline ?
+ Regex.Split (_text, "\r\n|\r|\n|" + @"\\n").ToList() :
+ new List<string>(new string[] { _text });
+ }
+ }
+
+ public void DeleteChar()
+ {
+ if (selectionIsEmpty) {
+ if (CurrentColumn == 0) {
+ if (CurrentLine == 0)
+ return;
+ CurrentLine--;
+ CurrentColumn = lines [CurrentLine].Count ();
+ lines [CurrentLine] += lines [CurrentLine + 1];
+ lines.RemoveAt (CurrentLine + 1);
+ return;
+ }
+ CurrentColumn--;
+ lines [CurrentLine] = lines [CurrentLine].Remove (CurrentColumn, 1);
+ } else {
+ Debug.WriteLine (selectionEnd.ToString());
+ int linesToRemove = selectionEnd.Y - selectionStart.Y;
+ int l = selectionStart.Y;
+
+ if (linesToRemove > 0) {
+ lines [l] = lines [l].Remove (selectionStart.X, lines [l].Length - selectionStart.X) +
+ lines [selectionEnd.Y].Substring (selectionEnd.X, lines [selectionEnd.Y].Length - selectionEnd.X);
+ l++;
+ for (int c = 0; c < linesToRemove-1; c++)
+ lines.RemoveAt (l);
+ CurrentColumn = selectionStart.X;
+ CurrentLine = selectionStart.Y;
+ } else
+ lines [l] = lines [l].Remove (selectionStart.X, selectionEnd.X - selectionStart.X);
+ CurrentColumn = selectionStart.X;
+ SelBegin = -1;
+ SelRelease = -1;
+ }
+ }
+ /// <summary>
+ /// Insert new string at caret position, should be sure no line break is inside.
+ /// </summary>
+ /// <param name="str">String.</param>
+ protected void Insert(string str)
+ {
+ lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, str);
+ CurrentColumn += str.Length;
+ }
+
+ #region GraphicObject overrides
+ [XmlAttributeAttribute()][DefaultValue(-1)]
+ public override int Width {
+ get { return base.Width; }
+ set { base.Width = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue(-1)]
+ public override int Height {
+ get { return base.Height; }
+ set { base.Height = value; }
+ }
+
+ protected override Size measureRawSize()
+ {
+ Size size;
+
+ if (lines == null)
+ lines = getLines;
+
+ using (ImageSurface img = new ImageSurface (Format.Argb32, 10, 10)) {
+ using (Context gr = new Context (img)) {
+ //Cairo.FontFace cf = gr.GetContextFontFace ();
+
+ gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+ gr.SetFontSize (Font.Size);
+
+ te = new TextExtents();
+
+ foreach (string s in lines) {
+ string l = s.Replace("\t", new String (' ', Interface.TabSize));
+
+#if _WIN32 || _WIN64
+ TextExtents tmp = gr.TextExtents(str.ToUtf8());
+#elif __linux__
+ TextExtents tmp = gr.TextExtents (l);
+#endif
+ if (tmp.XAdvance > te.XAdvance)
+ te = tmp;
+ }
+ fe = gr.FontExtents;
+ int lc = lines.Count;
+ //ensure minimal height = text line height
+ if (lc == 0)
+ lc = 1;
+ size = new Size ((int)Math.Ceiling (te.XAdvance) + Margin * 2, (int)(fe.Height * lc) + Margin*2);
+ }
+ }
+
+ return size;;
+ }
+ protected override void onDraw (Context gr)
+ {
+ base.onDraw (gr);
+
+ gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+ gr.SetFontSize (Font.Size);
+
+ gr.Antialias = Antialias.Subpixel;
+ //gr.FontOptions.Antialias = Antialias.Subpixel;
+ //gr.FontOptions.HintMetrics = HintMetrics.On;
+
+ rText = new Rectangle(measureRawSize());
+ rText.Width -= 2 * Margin;
+ rText.Height -= 2 * Margin;
+
+ widthRatio = 1f;
+ heightRatio = 1f;
+
+ Rectangle cb = ClientRectangle;
+
+ //ignore text alignment if size to content = true
+ if (Bounds.Size < 0)
+ {
+ rText.X = cb.X;
+ rText.Y = cb.Y;
+ }else{
+ 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 * rText.Width);
+ rText.X = cb.Right - rText.Width;
+ 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;
+ 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 * Font.Size, 0, 0, heightRatio * Font.Size, 0, 0);
+ fe = gr.FontExtents;
+
+ #region draw text cursor
+ if (mouseLocalPos >= 0)
+ {
+ computeTextCursor(gr);
+
+ if (SelectionInProgress)
+ {
+ if (SelBegin < 0){
+ SelBegin = new Point(CurrentColumn, CurrentLine);
+ SelStartCursorPos = textCursorPos;
+ SelRelease = -1;
+ }else{
+ SelRelease = new Point(CurrentColumn, CurrentLine);
+ if (SelRelease == SelBegin)
+ SelRelease = -1;
+ else
+ SelEndCursorPos = textCursorPos;
+ }
+ }
+ }else
+ computeTextCursorPosition(gr);
+
+
+ #endregion
+
+ //****** debug selection *************
+// if (SelRelease >= 0) {
+// gr.Color = Color.Green;
+// Rectangle R = new Rectangle (
+// rText.X + (int)SelEndCursorPos - 2,
+// rText.Y + (int)(SelRelease.Y * fe.Height),
+// 4,
+// (int)fe.Height);
+// gr.Rectangle (R);
+// gr.Fill ();
+// }
+// if (SelBegin >= 0) {
+// gr.Color = Color.UnmellowYellow;
+// Rectangle R = new Rectangle (
+// rText.X + (int)SelStartCursorPos - 2,
+// rText.Y + (int)(SelBegin.Y * fe.Height),
+// 4,
+// (int)fe.Height);
+// gr.Rectangle (R);
+// gr.Fill ();
+// }
+ //*******************
+
+ if (HasFocus )
+ {
+ gr.SetSourceColor(Foreground);
+ gr.LineWidth = 1.5;
+ gr.MoveTo(new PointD(textCursorPos + rText.X, rText.Y + CurrentLine * fe.Height));
+ gr.LineTo(new PointD(textCursorPos + rText.X, rText.Y + (CurrentLine + 1) * fe.Height));
+ gr.Stroke();
+ }
+
+ for (int i = 0; i < lines.Count; i++) {
+ string l = lines [i].Replace ("\t", new String (' ', Interface.TabSize));
+ int lineLength = (int)gr.TextExtents (l).XAdvance;
+ Rectangle lineRect = new Rectangle (
+ rText.X,
+ rText.Y + (int)(i * fe.Height),
+ lineLength,
+ (int)fe.Height);
+
+// if (TextAlignment == Alignment.Center ||
+// TextAlignment == Alignment.TopCenter ||
+// TextAlignment == Alignment.BottomCenter)
+// lineRect.X += (rText.Width - lineLength) / 2;
+// else if (TextAlignment == Alignment.RightCenter ||
+// TextAlignment == Alignment.TopRight ||
+// TextAlignment == Alignment.BottomRight)
+// lineRect.X += (rText.Width - lineLength);
+
+ if (SelRelease >= 0 && i >= selectionStart.Y && i <= selectionEnd.Y) {
+ gr.SetSourceColor(selColor);
+
+ Rectangle selRect = lineRect ;
+
+ int cpStart = (int)SelStartCursorPos,
+ cpEnd = (int)SelEndCursorPos;
+
+ if (SelBegin.Y > SelRelease.Y) {
+ cpStart = cpEnd;
+ cpEnd = (int)SelStartCursorPos;
+ }
+
+ if (i == selectionStart.Y) {
+ selRect.Width -= cpStart;
+ selRect.Left += cpStart;
+ }
+ if (i == selectionEnd.Y)
+ selRect.Width -= (lineLength - cpEnd);
+
+ gr.Rectangle (selRect);
+ gr.Fill ();
+ }
+
+ if (string.IsNullOrWhiteSpace (l))
+ continue;
+
+ gr.SetSourceColor(Foreground);
+ gr.MoveTo (lineRect.X, rText.Y + fe.Ascent + fe.Height * i);
+
+ #if _WIN32 || _WIN64
+ gr.ShowText(l.ToUtf8());
+ #elif __linux__
+ gr.ShowText (l);
+ #endif
+ gr.Fill ();
+ }
+ }
+ #endregion
+
+ #region Mouse handling
+ void updatemouseLocalPos(Point mpos){
+ mouseLocalPos = mpos - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft;
+ if (mouseLocalPos.X < 0)
+ mouseLocalPos.X = 0;
+ if (mouseLocalPos.Y < 0)
+ mouseLocalPos.Y = 0;
+ }
+ public override void onFocused (object sender, EventArgs e)
+ {
+ base.onFocused (sender, e);
+
+ SelBegin = new Point(0,0);
+ SelRelease = new Point (lines.LastOrDefault ().Length, lines.Count-1);
+ registerForGraphicUpdate ();
+ }
+ public override void onUnfocused (object sender, EventArgs e)
+ {
+ base.onUnfocused (sender, e);
+
+ SelBegin = -1;
+ SelRelease = -1;
+ registerForGraphicUpdate ();
+ }
+ public override void onMouseMove (object sender, MouseMoveEventArgs e)
+ {
+ base.onMouseMove (sender, e);
+
+ if (!(SelectionInProgress && HasFocus))
+ return;
+
+ updatemouseLocalPos (e.Position);
+
+ registerForGraphicUpdate();
+ }
+ public override void onMouseDown (object sender, MouseButtonEventArgs e)
+ {
+ if (this.HasFocus){
+ updatemouseLocalPos (e.Position);
+ SelBegin = -1;
+ SelRelease = -1;
+ SelectionInProgress = true;
+ }
+
+ //done at the end to set 'hasFocus' value after testing it
+ base.onMouseDown (sender, e);
+
+ registerForGraphicUpdate();
+ }
+ public override void onMouseUp (object sender, MouseButtonEventArgs e)
+ {
+ base.onMouseUp (sender, e);
+
+ if (!SelectionInProgress)
+ return;
+
+ updatemouseLocalPos (e.Position);
+ SelectionInProgress = false;
+ registerForGraphicUpdate ();
+ }
+ #endregion
+ /// <summary>
+ /// Update Current Column, line and TextCursorPos
+ /// from mouseLocalPos
+ /// </summary>
+ void computeTextCursor(Context gr)
+ {
+ TextExtents te;
+
+ double cPos = 0f;
+
+ CurrentLine = (int)(mouseLocalPos.Y / fe.Height);
+
+ //fix cu
+ if (CurrentLine >= lines.Count)
+ CurrentLine = lines.Count - 1;
+
+ for (int i = 0; i < lines[CurrentLine].Length; i++)
+ {
+ string c = lines [CurrentLine].Substring (i, 1);
+ if (c == "\t")
+ c = new string (' ', Interface.TabSize);
+
+ #if _WIN32 || _WIN64
+ byte[] c = System.Text.UTF8Encoding.UTF8.GetBytes(Text.Substring(i, 1));
+ te = gr.TextExtents(c);
+ #elif __linux__
+ te = gr.TextExtents(c);
+ #endif
+ double halfWidth = te.XAdvance / 2;
+
+ if (mouseLocalPos.X <= cPos + halfWidth)
+ {
+ CurrentColumn = i;
+ textCursorPos = cPos;
+ mouseLocalPos = -1;
+ return;
+ }
+
+ cPos += te.XAdvance;
+ }
+ CurrentColumn = lines[CurrentLine].Length;
+ textCursorPos = cPos;
+
+ //reset mouseLocalPos
+ mouseLocalPos = -1;
+ }
+ /// <summary> Computes offsets in cairo units </summary>
+ void computeTextCursorPosition(Context gr)
+ {
+ if (SelBegin >= 0)
+ SelStartCursorPos = GetXFromTextPointer (gr, SelBegin);
+ if (SelRelease >= 0)
+ SelEndCursorPos = GetXFromTextPointer (gr, SelRelease);
+ textCursorPos = GetXFromTextPointer (gr, new Point(CurrentColumn, CurrentLine));
+ }
+ /// <summary> Compute x offset in cairo unit from text position </summary>
+ double GetXFromTextPointer(Context gr, Point pos)
+ {
+ try {
+ string l = lines [pos.Y].Substring (0, pos.X).
+ Replace ("\t", new String (' ', Interface.TabSize));
+ return gr.TextExtents (l).XAdvance;
+ } catch{
+ return -1;
+ }
+ }
+ }
+}
diff --git a/src/GraphicObjects/Popper.cs b/src/GraphicObjects/Popper.cs
index 2ed1c06f..a7e1290c 100644
--- a/src/GraphicObjects/Popper.cs
+++ b/src/GraphicObjects/Popper.cs
@@ -1,188 +1,188 @@
-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;
-using System.Xml.Serialization;
-using OpenTK.Input;
-using System.ComponentModel;
-using System.Xml;
-using System.IO;
-
-namespace Crow
-{
- [DefaultTemplate("#Crow.Templates.Popper.goml")]
- public class Popper : TemplatedContainer
- {
- #region CTOR
- public Popper() : base()
- {
- }
- #endregion
- bool _isPopped;
- string caption;
- string image;
- GraphicObject _content;
-
- public event EventHandler Pop;
- public event EventHandler Unpop;
-
- public override GraphicObject Content {
- get { return _content; }
- set {
- if (_content != null) {
- _content.LogicalParent = null;
- _content.LayoutChanged -= _content_LayoutChanged;
- _content.MouseLeave -= _content_MouseLeave;
- }
-
- _content = value;
-
- if (_content == null)
- return;
-
- _content.LogicalParent = this;
- _content.Focusable = true;
- _content.LayoutChanged += _content_LayoutChanged;
- _content.MouseLeave += _content_MouseLeave;
- }
- }
-
- void _content_MouseLeave (object sender, MouseMoveEventArgs e)
- {
- IsPopped = false;
- }
-
- void _content_LayoutChanged (object sender, LayoutChangeEventArgs e)
- {
- ILayoutable tc = Content.Parent as ILayoutable;
- if (tc == null)
- return;
- Rectangle r = this.ScreenCoordinates (this.Slot);
- if (((int)e.LayoutType & (int)LayoutingType.Width) > 0) {
- if (Content.Slot.Width < tc.ClientRectangle.Width) {
- if (r.Left + Content.Slot.Width > tc.ClientRectangle.Right)
- Content.Left = tc.ClientRectangle.Right - Content.Slot.Width;
- else
- Content.Left = r.Left;
- } else
- Content.Left = 0;
- }
- if (((int)e.LayoutType & (int)LayoutingType.Height) > 0) {
- if (Content.Slot.Height < tc.ClientRectangle.Height) {
- if (r.Bottom + Content.Slot.Height > tc.ClientRectangle.Bottom)
- Content.Top = r.Top - Content.Slot.Height;
- else
- Content.Top = r.Bottom;
- }else
- Content.Top = 0;
- }
- }
- public override void ClearBinding ()
- {
- //ensure popped window is cleared
- if (Content != null) {
- if (Content.Parent != null) {
- IGOLibHost tc = Content.Parent as IGOLibHost;
- if (tc != null)
- tc.DeleteWidget (Content);
- }
- }
- base.ClearBinding ();
- }
- public override void ResolveBindings ()
- {
- base.ResolveBindings ();
- if (Content != null)
- Content.ResolveBindings ();
- }
-
- [XmlAttributeAttribute()][DefaultValue(true)]//overiden to get default to true
- public override bool Focusable
- {
- get { return base.Focusable; }
- set { base.Focusable = value; }
- }
- [XmlAttributeAttribute()][DefaultValue(-1)]
- public override int Height {
- get { return base.Height; }
- set { base.Height = value; }
- }
-
- [XmlAttributeAttribute()][DefaultValue("Popper")]
- public string Caption {
- get { return caption; }
- set {
- if (caption == value)
- return;
- caption = value;
- NotifyValueChanged ("Caption", caption);
- }
- }
- [XmlAttributeAttribute()][DefaultValue("#Crow.Images.Icons.expandable.svg")]
- public string Image {
- get { return image; }
- set {
- if (image == value)
- return;
- image = value;
- NotifyValueChanged ("Image", image);
- }
- }
-
- [XmlAttributeAttribute()][DefaultValue(false)]
- public bool IsPopped
- {
- get { return _isPopped; }
- set
- {
- _isPopped = value;
-
- if (_isPopped) {
- onPop (this, null);
- NotifyValueChanged ("SvgSub", "expanded");
- return;
- }
-
- onUnpop (this, null);
- NotifyValueChanged ("SvgSub", "collapsed");
- }
- }
-
- public virtual void onPop(object sender, EventArgs e)
- {
- IGOLibHost tc = HostContainer;
- if (tc == null)
- return;
- if (Content != null) {
- Content.Visible = true;
- if (Content.Parent == null)
- tc.AddWidget (Content);
- tc.PutOnTop (Content);
- _content_LayoutChanged (this, new LayoutChangeEventArgs (LayoutingType.Sizing));
- }
- Pop.Raise (this, e);
- }
- public virtual void onUnpop(object sender, EventArgs e)
- {
- IGOLibHost tc = HostContainer;
- if (tc == null)
- return;
- Content.Visible = false;
- Unpop.Raise (this, e);
- }
-
- public override void onMouseClick (object sender, MouseButtonEventArgs e)
- {
- IsPopped = !IsPopped;
- base.onMouseClick (sender, e);
- }
- }
-}
+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;
+using System.Xml.Serialization;
+using OpenTK.Input;
+using System.ComponentModel;
+using System.Xml;
+using System.IO;
+
+namespace Crow
+{
+ [DefaultTemplate("#Crow.Templates.Popper.goml")]
+ public class Popper : TemplatedContainer
+ {
+ #region CTOR
+ public Popper() : base()
+ {
+ }
+ #endregion
+ bool _isPopped;
+ string caption;
+ string image;
+ GraphicObject _content;
+
+ public event EventHandler Pop;
+ public event EventHandler Unpop;
+
+ public override GraphicObject Content {
+ get { return _content; }
+ set {
+ if (_content != null) {
+ _content.LogicalParent = null;
+ _content.LayoutChanged -= _content_LayoutChanged;
+ _content.MouseLeave -= _content_MouseLeave;
+ }
+
+ _content = value;
+
+ if (_content == null)
+ return;
+
+ _content.LogicalParent = this;
+ _content.Focusable = true;
+ _content.LayoutChanged += _content_LayoutChanged;
+ _content.MouseLeave += _content_MouseLeave;
+ }
+ }
+
+ void _content_MouseLeave (object sender, MouseMoveEventArgs e)
+ {
+ IsPopped = false;
+ }
+
+ void _content_LayoutChanged (object sender, LayoutChangeEventArgs e)
+ {
+ ILayoutable tc = Content.Parent as ILayoutable;
+ if (tc == null)
+ return;
+ Rectangle r = this.ScreenCoordinates (this.Slot);
+ if (((int)e.LayoutType & (int)LayoutingType.Width) > 0) {
+ if (Content.Slot.Width < tc.ClientRectangle.Width) {
+ if (r.Left + Content.Slot.Width > tc.ClientRectangle.Right)
+ Content.Left = tc.ClientRectangle.Right - Content.Slot.Width;
+ else
+ Content.Left = r.Left;
+ } else
+ Content.Left = 0;
+ }
+ if (((int)e.LayoutType & (int)LayoutingType.Height) > 0) {
+ if (Content.Slot.Height < tc.ClientRectangle.Height) {
+ if (r.Bottom + Content.Slot.Height > tc.ClientRectangle.Bottom)
+ Content.Top = r.Top - Content.Slot.Height;
+ else
+ Content.Top = r.Bottom;
+ }else
+ Content.Top = 0;
+ }
+ }
+ public override void ClearBinding ()
+ {
+ //ensure popped window is cleared
+ if (Content != null) {
+ if (Content.Parent != null) {
+ IGOLibHost tc = Content.Parent as IGOLibHost;
+ if (tc != null)
+ tc.DeleteWidget (Content);
+ }
+ }
+ base.ClearBinding ();
+ }
+ public override void ResolveBindings ()
+ {
+ base.ResolveBindings ();
+ if (Content != null)
+ Content.ResolveBindings ();
+ }
+
+ [XmlAttributeAttribute()][DefaultValue(true)]//overiden to get default to true
+ public override bool Focusable
+ {
+ get { return base.Focusable; }
+ set { base.Focusable = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue(-1)]
+ public override int Height {
+ get { return base.Height; }
+ set { base.Height = value; }
+ }
+
+ [XmlAttributeAttribute()][DefaultValue("Popper")]
+ public string Caption {
+ get { return caption; }
+ set {
+ if (caption == value)
+ return;
+ caption = value;
+ NotifyValueChanged ("Caption", caption);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue("#Crow.Images.Icons.expandable.svg")]
+ public string Image {
+ get { return image; }
+ set {
+ if (image == value)
+ return;
+ image = value;
+ NotifyValueChanged ("Image", image);
+ }
+ }
+
+ [XmlAttributeAttribute()][DefaultValue(false)]
+ public bool IsPopped
+ {
+ get { return _isPopped; }
+ set
+ {
+ _isPopped = value;
+
+ if (_isPopped) {
+ onPop (this, null);
+ NotifyValueChanged ("SvgSub", "expanded");
+ return;
+ }
+
+ onUnpop (this, null);
+ NotifyValueChanged ("SvgSub", "collapsed");
+ }
+ }
+
+ public virtual void onPop(object sender, EventArgs e)
+ {
+ IGOLibHost tc = HostContainer;
+ if (tc == null)
+ return;
+ if (Content != null) {
+ Content.Visible = true;
+ if (Content.Parent == null)
+ tc.AddWidget (Content);
+ tc.PutOnTop (Content);
+ _content_LayoutChanged (this, new LayoutChangeEventArgs (LayoutingType.Sizing));
+ }
+ Pop.Raise (this, e);
+ }
+ public virtual void onUnpop(object sender, EventArgs e)
+ {
+ IGOLibHost tc = HostContainer;
+ if (tc == null)
+ return;
+ Content.Visible = false;
+ Unpop.Raise (this, e);
+ }
+
+ public override void onMouseClick (object sender, MouseButtonEventArgs e)
+ {
+ IsPopped = !IsPopped;
+ base.onMouseClick (sender, e);
+ }
+ }
+}
diff --git a/src/GraphicObjects/ProgressBar.cs b/src/GraphicObjects/ProgressBar.cs
index e7be280d..c8dcbb77 100644
--- a/src/GraphicObjects/ProgressBar.cs
+++ b/src/GraphicObjects/ProgressBar.cs
@@ -1,104 +1,104 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Cairo;
-using System.Diagnostics;
-using System.Xml.Serialization;
-using System.ComponentModel;
-
-namespace Crow
-{
- [Serializable]
- public class ProgressBar : Border
- {
- #region CTOR
- public ProgressBar() : base(){}
- public ProgressBar(int _max) : base()
- {
- Maximum = _max;
- }
- #endregion
-
- #region private fields
- int _currentValue = 0;
- int _minimum = 0;
- int _maximum = 100;
- #endregion
-
- #region public properties
- [XmlAttributeAttribute()][DefaultValue(0)]
- public int Value
- {
- get { return _currentValue; }
- set
- {
- if (_currentValue == value)
- return;
-
- _currentValue = value;
-
- if (_currentValue > Maximum)
- _currentValue = Maximum;
-
- registerForGraphicUpdate();
- }
- }
- [XmlAttributeAttribute()][DefaultValue(0)]
- public int Minimum {
- get {return _minimum;}
- set {
- if (_minimum == value || _minimum >= Maximum)
- return;
- _minimum = value;
- registerForGraphicUpdate ();
- }
- }
- [XmlAttributeAttribute()][DefaultValue(100)]
- public int Maximum {
- get {return _maximum;}
- set {
- if (_maximum == value || _maximum <= _minimum)
- return;
- _maximum = value;
- registerForGraphicUpdate();
- }
- }
- #endregion
-
- #region GraphicObject overrides
- [XmlAttributeAttribute()][DefaultValue("Gray")]
- public override Color Background {
- get { return base.Background; }
- set { base.Background = value; }
- }
- [XmlAttributeAttribute()][DefaultValue(0)]
- public override int BorderWidth {
- get { return base.BorderWidth; }
- set { base.BorderWidth = value; }
- }
- [XmlAttributeAttribute()][DefaultValue("BlueCrayola")]
- public override Color Foreground {
- get { return base.Foreground; }
- set { base.Foreground = value; }
- }
-
- protected override void onDraw (Context gr)
- {
- base.onDraw (gr);
-
- Rectangle rBack = Slot.Size;
-
- if (BorderWidth > 0)
- rBack.Inflate(-BorderWidth, -BorderWidth);
-
- rBack.Width = (int)((double)rBack.Width / Maximum * Value);
-
- gr.SetSourceColor(Foreground);
-
- CairoHelpers.CairoRectangle(gr,rBack,CornerRadius);
- gr.Fill();
- }
- #endregion
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Cairo;
+using System.Diagnostics;
+using System.Xml.Serialization;
+using System.ComponentModel;
+
+namespace Crow
+{
+ [Serializable]
+ public class ProgressBar : Border
+ {
+ #region CTOR
+ public ProgressBar() : base(){}
+ public ProgressBar(int _max) : base()
+ {
+ Maximum = _max;
+ }
+ #endregion
+
+ #region private fields
+ int _currentValue = 0;
+ int _minimum = 0;
+ int _maximum = 100;
+ #endregion
+
+ #region public properties
+ [XmlAttributeAttribute()][DefaultValue(0)]
+ public int Value
+ {
+ get { return _currentValue; }
+ set
+ {
+ if (_currentValue == value)
+ return;
+
+ _currentValue = value;
+
+ if (_currentValue > Maximum)
+ _currentValue = Maximum;
+
+ registerForGraphicUpdate();
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(0)]
+ public int Minimum {
+ get {return _minimum;}
+ set {
+ if (_minimum == value || _minimum >= Maximum)
+ return;
+ _minimum = value;
+ registerForGraphicUpdate ();
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(100)]
+ public int Maximum {
+ get {return _maximum;}
+ set {
+ if (_maximum == value || _maximum <= _minimum)
+ return;
+ _maximum = value;
+ registerForGraphicUpdate();
+ }
+ }
+ #endregion
+
+ #region GraphicObject overrides
+ [XmlAttributeAttribute()][DefaultValue("Gray")]
+ public override Color Background {
+ get { return base.Background; }
+ set { base.Background = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue(0)]
+ public override int BorderWidth {
+ get { return base.BorderWidth; }
+ set { base.BorderWidth = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue("BlueCrayola")]
+ public override Color Foreground {
+ get { return base.Foreground; }
+ set { base.Foreground = value; }
+ }
+
+ protected override void onDraw (Context gr)
+ {
+ base.onDraw (gr);
+
+ Rectangle rBack = Slot.Size;
+
+ if (BorderWidth > 0)
+ rBack.Inflate(-BorderWidth, -BorderWidth);
+
+ rBack.Width = (int)((double)rBack.Width / Maximum * Value);
+
+ gr.SetSourceColor(Foreground);
+
+ CairoHelpers.CairoRectangle(gr,rBack,CornerRadius);
+ gr.Fill();
+ }
+ #endregion
+ }
+}
diff --git a/src/GraphicObjects/RadioButton.cs b/src/GraphicObjects/RadioButton.cs
index 5985b2c3..66e63ce4 100644
--- a/src/GraphicObjects/RadioButton.cs
+++ b/src/GraphicObjects/RadioButton.cs
@@ -1,93 +1,93 @@
-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;
-using System.Xml.Serialization;
-using OpenTK.Input;
-using System.ComponentModel;
-
-namespace Crow
-{
- [DefaultTemplate("#Crow.Templates.RadioButton.goml")]
- public class RadioButton : TemplatedControl
- {
- string caption;
- string image;
- bool isChecked;
-
- #region CTOR
- public RadioButton() : base(){}
- #endregion
-
- #region GraphicObject overrides
- [XmlAttributeAttribute()][DefaultValue(true)]//overiden to get default to true
- public override bool Focusable
- {
- get { return base.Focusable; }
- set { base.Focusable = value; }
- }
- [XmlAttributeAttribute()][DefaultValue(-1)]
- public override int Height {
- get { return base.Height; }
- set { base.Height = value; }
- }
- #endregion
-
- [XmlAttributeAttribute()][DefaultValue("RadioButton")]
- public string Caption {
- get { return caption; }
- set {
- if (caption == value)
- return;
- caption = value;
- NotifyValueChanged ("Caption", caption);
- }
- }
- [XmlAttributeAttribute()][DefaultValue("#Crow.Images.Icons.radiobutton.svg")]
- public string Image {
- get { return image; }
- set {
- if (image == value)
- return;
- image = value;
- NotifyValueChanged ("Image", image);
- }
- }
-
- [XmlAttributeAttribute()][DefaultValue(false)]
- public bool IsChecked
- {
- get { return isChecked; }
- set
- {
- isChecked = value;
-
- NotifyValueChanged ("IsChecked", value);
- if (isChecked)
- NotifyValueChanged ("SvgSub", "checked");
- else
- NotifyValueChanged ("SvgSub", "unchecked");
- }
- }
-
- public override void onMouseClick (object sender, MouseButtonEventArgs e)
- {
- Group pg = Parent as Group;
- if (pg != null) {
- foreach (RadioButton c in pg.Children.OfType<RadioButton>())
- c.IsChecked = (c == this);
- } else
- IsChecked = !IsChecked;
-
- base.onMouseClick (sender, e);
- }
- }
-}
+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;
+using System.Xml.Serialization;
+using OpenTK.Input;
+using System.ComponentModel;
+
+namespace Crow
+{
+ [DefaultTemplate("#Crow.Templates.RadioButton.goml")]
+ public class RadioButton : TemplatedControl
+ {
+ string caption;
+ string image;
+ bool isChecked;
+
+ #region CTOR
+ public RadioButton() : base(){}
+ #endregion
+
+ #region GraphicObject overrides
+ [XmlAttributeAttribute()][DefaultValue(true)]//overiden to get default to true
+ public override bool Focusable
+ {
+ get { return base.Focusable; }
+ set { base.Focusable = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue(-1)]
+ public override int Height {
+ get { return base.Height; }
+ set { base.Height = value; }
+ }
+ #endregion
+
+ [XmlAttributeAttribute()][DefaultValue("RadioButton")]
+ public string Caption {
+ get { return caption; }
+ set {
+ if (caption == value)
+ return;
+ caption = value;
+ NotifyValueChanged ("Caption", caption);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue("#Crow.Images.Icons.radiobutton.svg")]
+ public string Image {
+ get { return image; }
+ set {
+ if (image == value)
+ return;
+ image = value;
+ NotifyValueChanged ("Image", image);
+ }
+ }
+
+ [XmlAttributeAttribute()][DefaultValue(false)]
+ public bool IsChecked
+ {
+ get { return isChecked; }
+ set
+ {
+ isChecked = value;
+
+ NotifyValueChanged ("IsChecked", value);
+ if (isChecked)
+ NotifyValueChanged ("SvgSub", "checked");
+ else
+ NotifyValueChanged ("SvgSub", "unchecked");
+ }
+ }
+
+ public override void onMouseClick (object sender, MouseButtonEventArgs e)
+ {
+ Group pg = Parent as Group;
+ if (pg != null) {
+ foreach (RadioButton c in pg.Children.OfType<RadioButton>())
+ c.IsChecked = (c == this);
+ } else
+ IsChecked = !IsChecked;
+
+ base.onMouseClick (sender, e);
+ }
+ }
+}
diff --git a/src/GraphicObjects/ScrollBar.cs b/src/GraphicObjects/ScrollBar.cs
index 32bc8807..9a598aba 100644
--- a/src/GraphicObjects/ScrollBar.cs
+++ b/src/GraphicObjects/ScrollBar.cs
@@ -1,97 +1,97 @@
-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;
-using System.Xml.Serialization;
-using OpenTK.Input;
-using System.ComponentModel;
-
-namespace Crow
-{
- [DefaultTemplate("#Crow.Templates.ScrollBar.goml")]
- public class ScrollBar : TemplatedControl
- {
- Orientation _orientation;
- Slider _slider;
- double _maximumScroll;
- double _scroll;
-
- public ScrollBar() : base()
- {
- }
-
- protected override void loadTemplate(GraphicObject template = null)
- {
- base.loadTemplate (template);
- _slider = this.child.FindByName ("Slider") as Slider;
- }
-
- [XmlAttributeAttribute()][DefaultValue(0.0)]
- public virtual double MaximumScroll
- {
- get { return _maximumScroll; }
- set {
- if (_maximumScroll == value)
- return;
- _maximumScroll = value;
- registerForGraphicUpdate ();
- NotifyValueChanged ("MaximumScroll", _maximumScroll);
- }
- }
- [XmlAttributeAttribute()][DefaultValue(0.0)]
- public virtual double Scroll
- {
- get { return _scroll; }
- set {
- if (_scroll == value)
- return;
- _scroll = value;
- if (_scroll < 0.0)
- _scroll = 0.0;
- else if (_scroll > _maximumScroll)
- _scroll = _maximumScroll;
- registerForGraphicUpdate ();
- NotifyValueChanged ("Scroll", _scroll);
- }
- }
- [XmlAttributeAttribute()][DefaultValue(Orientation.Vertical)]
- public virtual Orientation Orientation
- {
- get { return _orientation; }
- set {
- if (_orientation == value)
- return;
- _orientation = value;
- NotifyValueChanged ("Orientation", _orientation);
- registerForGraphicUpdate ();
- }
- }
- public void onScrollBack (object sender, MouseButtonEventArgs e)
- {
- Scroll -= _slider.LargeIncrement;
- }
- public void onScrollForth (object sender, MouseButtonEventArgs e)
- {
- Scroll += _slider.LargeIncrement;
-
- }
-
- public void onSliderValueChange(object sender, ValueChangeEventArgs e){
- Scroll = Convert.ToDouble(e.NewValue);
- }
-
- public override void OnLayoutChanges (LayoutingType layoutType)
- {
- OpenTKGameWindow.currentWindow.CursorVisible = true;
- base.OnLayoutChanges (layoutType);
- }
- }
-}
+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;
+using System.Xml.Serialization;
+using OpenTK.Input;
+using System.ComponentModel;
+
+namespace Crow
+{
+ [DefaultTemplate("#Crow.Templates.ScrollBar.goml")]
+ public class ScrollBar : TemplatedControl
+ {
+ Orientation _orientation;
+ Slider _slider;
+ double _maximumScroll;
+ double _scroll;
+
+ public ScrollBar() : base()
+ {
+ }
+
+ protected override void loadTemplate(GraphicObject template = null)
+ {
+ base.loadTemplate (template);
+ _slider = this.child.FindByName ("Slider") as Slider;
+ }
+
+ [XmlAttributeAttribute()][DefaultValue(0.0)]
+ public virtual double MaximumScroll
+ {
+ get { return _maximumScroll; }
+ set {
+ if (_maximumScroll == value)
+ return;
+ _maximumScroll = value;
+ registerForGraphicUpdate ();
+ NotifyValueChanged ("MaximumScroll", _maximumScroll);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(0.0)]
+ public virtual double Scroll
+ {
+ get { return _scroll; }
+ set {
+ if (_scroll == value)
+ return;
+ _scroll = value;
+ if (_scroll < 0.0)
+ _scroll = 0.0;
+ else if (_scroll > _maximumScroll)
+ _scroll = _maximumScroll;
+ registerForGraphicUpdate ();
+ NotifyValueChanged ("Scroll", _scroll);
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(Orientation.Vertical)]
+ public virtual Orientation Orientation
+ {
+ get { return _orientation; }
+ set {
+ if (_orientation == value)
+ return;
+ _orientation = value;
+ NotifyValueChanged ("Orientation", _orientation);
+ registerForGraphicUpdate ();
+ }
+ }
+ public void onScrollBack (object sender, MouseButtonEventArgs e)
+ {
+ Scroll -= _slider.LargeIncrement;
+ }
+ public void onScrollForth (object sender, MouseButtonEventArgs e)
+ {
+ Scroll += _slider.LargeIncrement;
+
+ }
+
+ public void onSliderValueChange(object sender, ValueChangeEventArgs e){
+ Scroll = Convert.ToDouble(e.NewValue);
+ }
+
+ public override void OnLayoutChanges (LayoutingType layoutType)
+ {
+ OpenTKGameWindow.currentWindow.CursorVisible = true;
+ base.OnLayoutChanges (layoutType);
+ }
+ }
+}
diff --git a/src/GraphicObjects/Scroller.cs b/src/GraphicObjects/Scroller.cs
index 9808fef8..be6e8993 100644
--- a/src/GraphicObjects/Scroller.cs
+++ b/src/GraphicObjects/Scroller.cs
@@ -1,227 +1,227 @@
-using System;
-using System.Diagnostics;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Drawing;
-using Cairo;
-using System.Xml.Serialization;
-using OpenTK.Input;
-using System.ComponentModel;
-
-namespace Crow
-{
- public class Scroller : Container
- {
- bool _verticalScrolling;
- bool _horizontalScrolling;
- bool _scrollbarVisible;
- double _scrollX = 0.0;
- double _scrollY = 0.0;
- int scrollSpeed;
-
-
-
- #region public properties
- [XmlAttributeAttribute][DefaultValue(false)]
- public bool VerticalScrolling {
- get { return _verticalScrolling; }
- set { _verticalScrolling = value; }
- }
-
- [XmlAttributeAttribute][DefaultValue(false)]
- public bool HorizontalScrolling {
- get { return _horizontalScrolling; }
- set { _horizontalScrolling = value; }
- }
- [XmlAttributeAttribute][DefaultValue(true)]
- public bool ScrollbarVisible {
- get { return _scrollbarVisible; }
- set { _scrollbarVisible = value; }
- }
- [XmlAttributeAttribute][DefaultValue(0.0)]
- public double ScrollX {
- get {
- return _scrollX;
- }
- set {
- if (_scrollX == value)
- return;
- if (value < 0.0)
- _scrollX = 0.0;
- else if (value > Child.Slot.Width - ClientRectangle.Width)
- _scrollX = Math.Max(0.0, Child.Slot.Width - ClientRectangle.Width);
- else
- _scrollX = value;
- NotifyValueChanged("ScrollX", _scrollX);
- RegisterForRedraw();
- }
- }
- [XmlAttributeAttribute][DefaultValue(0.0)]
- public double ScrollY {
- get {
- return _scrollY;
- }
- set {
- if (_scrollY == value)
- return;
- if (value < 0.0)
- _scrollY = 0.0;
- else if (value > Child.Slot.Height - ClientRectangle.Height)
- _scrollY = Math.Max(0.0,Child.Slot.Height - ClientRectangle.Height);
- else
- _scrollY = value;
- NotifyValueChanged("ScrollY", _scrollY);
- RegisterForRedraw();
- }
- }
-
- [XmlIgnore]
- public int MaximumScroll {
- get {
- return VerticalScrolling ?
- child == null ? 0 : Child.Slot.Height - ClientRectangle.Height :
- Child.Slot.Width - ClientRectangle.Width;
- }
- }
-
- [XmlAttributeAttribute][DefaultValue(30)]
- public int ScrollSpeed {
- get { return scrollSpeed; }
- set {
- scrollSpeed = value;
- NotifyValueChanged("ScrollSpeed", scrollSpeed);
- }
- }
- #endregion
-
-
- public Scroller()
- : base(){}
-
- #region GraphicObject Overrides
- void OnChildLayoutChanges (object sender, LayoutChangeEventArgs arg)
- {
- int maxScroll = MaximumScroll;
- if (_verticalScrolling) {
- if (arg.LayoutType == LayoutingType.Height) {
- if (maxScroll < ScrollY) {
- Debug.WriteLine ("scrolly={0} maxscroll={1}", ScrollY, maxScroll);
- ScrollY = 0;
- }
- NotifyValueChanged("MaximumScroll", maxScroll);
- }
- } else if (arg.LayoutType == LayoutingType.Width) {
- if (maxScroll < ScrollX)
- ScrollX = 0;
- NotifyValueChanged("MaximumScroll", maxScroll);
- }
- }
- void onChildListCleared(object sender, EventArgs e){
- ScrollY = 0;
- ScrollX = 0;
- }
- public override T SetChild<T> (T _child)
- {
- GraphicObject c = child as GraphicObject;
- Group g = child as Group;
- if (c != null) {
- c.LayoutChanged -= OnChildLayoutChanges;
- if (g != null)
- g.ChildrenCleared -= onChildListCleared;
- }
- c = _child as GraphicObject;
- g = _child as Group;
- if (c != null) {
- c.LayoutChanged += OnChildLayoutChanges;
- if (g != null)
- g.ChildrenCleared += onChildListCleared;
- }
- return base.SetChild (_child);
- }
- #endregion
-
- #region Mouse handling
- internal Point savedMousePos;
- public override bool MouseIsIn (Point m)
- {
-// Debug.WriteLine ("Mouse in scroller: {0} scr coord:{1} mouse:{2}",
-// base.ScreenCoordinates (Slot).ContainsOrIsEqual (m),
-// base.ScreenCoordinates (Slot), m);
-
- return Visible ? base.ScreenCoordinates(Slot).ContainsOrIsEqual (m) : false;
- }
- public override void checkHoverWidget (MouseMoveEventArgs e)
- {
- savedMousePos = e.Position;
- Point m = e.Position - new Point ((int)ScrollX, (int)ScrollY);
- base.checkHoverWidget (new MouseMoveEventArgs(m.X,m.Y,e.XDelta,e.YDelta));
- }
- public override void onMouseWheel (object sender, MouseWheelEventArgs e)
- {
- //base.onMouseWheel (sender, e); base event buble to the top
-// if (MouseWheelChanged!=null)
-// MouseWheelChanged (this, e);
-
- if (Child == null)
- return;
-
- if (VerticalScrolling )
- ScrollY -= e.Delta * ScrollSpeed;
- if (HorizontalScrolling )
- ScrollX -= e.Delta * ScrollSpeed;
- }
- public override void onMouseMove (object sender, MouseMoveEventArgs e)
- {
- savedMousePos.X += e.XDelta;
- savedMousePos.Y += e.YDelta;
- base.onMouseMove (sender, new MouseMoveEventArgs(savedMousePos.X,savedMousePos.Y,e.XDelta,e.YDelta));
- }
- #endregion
-
- public override Rectangle ContextCoordinates (Rectangle r)
- {
- return base.ContextCoordinates (r) - new Point((int)ScrollX,(int)ScrollY);
- }
- public override Rectangle ScreenCoordinates (Rectangle r)
- {
- return base.ScreenCoordinates (r) - new Point((int)ScrollX,(int)ScrollY);
- }
-
- public override void registerClipRect ()
- {
- HostContainer.redrawClip.AddRectangle (base.ScreenCoordinates(Slot));
- }
-
- public override void Paint(ref Cairo.Context ctx, Rectangles clip = null)
- {
- if (!Visible)//check if necessary??
- return;
-
- ctx.Save();
-
- // ctx.Rectangle(ContextCoordinates(Slot));
- // ctx.Clip();
- //
-// if (clip != null)
-// clip.clip(ctx);
- //clip.Srcoll (this);
-
- base.Paint (ref ctx, clip);
-
- //clip to client zone
- ctx.Rectangle(Parent.ContextCoordinates(ClientRectangle + Slot.Position));
- ctx.Clip();
-
-// if (clip != null)
-// clip.Srcoll (this);
- // if (clip != null)
- // clip.Rebase(this);
-
- if (Child != null)
- Child.Paint(ref ctx, clip);
-
- ctx.Restore();
- }
- }
-}
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Drawing;
+using Cairo;
+using System.Xml.Serialization;
+using OpenTK.Input;
+using System.ComponentModel;
+
+namespace Crow
+{
+ public class Scroller : Container
+ {
+ bool _verticalScrolling;
+ bool _horizontalScrolling;
+ bool _scrollbarVisible;
+ double _scrollX = 0.0;
+ double _scrollY = 0.0;
+ int scrollSpeed;
+
+
+
+ #region public properties
+ [XmlAttributeAttribute][DefaultValue(false)]
+ public bool VerticalScrolling {
+ get { return _verticalScrolling; }
+ set { _verticalScrolling = value; }
+ }
+
+ [XmlAttributeAttribute][DefaultValue(false)]
+ public bool HorizontalScrolling {
+ get { return _horizontalScrolling; }
+ set { _horizontalScrolling = value; }
+ }
+ [XmlAttributeAttribute][DefaultValue(true)]
+ public bool ScrollbarVisible {
+ get { return _scrollbarVisible; }
+ set { _scrollbarVisible = value; }
+ }
+ [XmlAttributeAttribute][DefaultValue(0.0)]
+ public double ScrollX {
+ get {
+ return _scrollX;
+ }
+ set {
+ if (_scrollX == value)
+ return;
+ if (value < 0.0)
+ _scrollX = 0.0;
+ else if (value > Child.Slot.Width - ClientRectangle.Width)
+ _scrollX = Math.Max(0.0, Child.Slot.Width - ClientRectangle.Width);
+ else
+ _scrollX = value;
+ NotifyValueChanged("ScrollX", _scrollX);
+ RegisterForRedraw();
+ }
+ }
+ [XmlAttributeAttribute][DefaultValue(0.0)]
+ public double ScrollY {
+ get {
+ return _scrollY;
+ }
+ set {
+ if (_scrollY == value)
+ return;
+ if (value < 0.0)
+ _scrollY = 0.0;
+ else if (value > Child.Slot.Height - ClientRectangle.Height)
+ _scrollY = Math.Max(0.0,Child.Slot.Height - ClientRectangle.Height);
+ else
+ _scrollY = value;
+ NotifyValueChanged("ScrollY", _scrollY);
+ RegisterForRedraw();
+ }
+ }
+
+ [XmlIgnore]
+ public int MaximumScroll {
+ get {
+ return VerticalScrolling ?
+ child == null ? 0 : Child.Slot.Height - ClientRectangle.Height :
+ Child.Slot.Width - ClientRectangle.Width;
+ }
+ }
+
+ [XmlAttributeAttribute][DefaultValue(30)]
+ public int ScrollSpeed {
+ get { return scrollSpeed; }
+ set {
+ scrollSpeed = value;
+ NotifyValueChanged("ScrollSpeed", scrollSpeed);
+ }
+ }
+ #endregion
+
+
+ public Scroller()
+ : base(){}
+
+ #region GraphicObject Overrides
+ void OnChildLayoutChanges (object sender, LayoutChangeEventArgs arg)
+ {
+ int maxScroll = MaximumScroll;
+ if (_verticalScrolling) {
+ if (arg.LayoutType == LayoutingType.Height) {
+ if (maxScroll < ScrollY) {
+ Debug.WriteLine ("scrolly={0} maxscroll={1}", ScrollY, maxScroll);
+ ScrollY = 0;
+ }
+ NotifyValueChanged("MaximumScroll", maxScroll);
+ }
+ } else if (arg.LayoutType == LayoutingType.Width) {
+ if (maxScroll < ScrollX)
+ ScrollX = 0;
+ NotifyValueChanged("MaximumScroll", maxScroll);
+ }
+ }
+ void onChildListCleared(object sender, EventArgs e){
+ ScrollY = 0;
+ ScrollX = 0;
+ }
+ public override T SetChild<T> (T _child)
+ {
+ GraphicObject c = child as GraphicObject;
+ Group g = child as Group;
+ if (c != null) {
+ c.LayoutChanged -= OnChildLayoutChanges;
+ if (g != null)
+ g.ChildrenCleared -= onChildListCleared;
+ }
+ c = _child as GraphicObject;
+ g = _child as Group;
+ if (c != null) {
+ c.LayoutChanged += OnChildLayoutChanges;
+ if (g != null)
+ g.ChildrenCleared += onChildListCleared;
+ }
+ return base.SetChild (_child);
+ }
+ #endregion
+
+ #region Mouse handling
+ internal Point savedMousePos;
+ public override bool MouseIsIn (Point m)
+ {
+// Debug.WriteLine ("Mouse in scroller: {0} scr coord:{1} mouse:{2}",
+// base.ScreenCoordinates (Slot).ContainsOrIsEqual (m),
+// base.ScreenCoordinates (Slot), m);
+
+ return Visible ? base.ScreenCoordinates(Slot).ContainsOrIsEqual (m) : false;
+ }
+ public override void checkHoverWidget (MouseMoveEventArgs e)
+ {
+ savedMousePos = e.Position;
+ Point m = e.Position - new Point ((int)ScrollX, (int)ScrollY);
+ base.checkHoverWidget (new MouseMoveEventArgs(m.X,m.Y,e.XDelta,e.YDelta));
+ }
+ public override void onMouseWheel (object sender, MouseWheelEventArgs e)
+ {
+ //base.onMouseWheel (sender, e); base event buble to the top
+// if (MouseWheelChanged!=null)
+// MouseWheelChanged (this, e);
+
+ if (Child == null)
+ return;
+
+ if (VerticalScrolling )
+ ScrollY -= e.Delta * ScrollSpeed;
+ if (HorizontalScrolling )
+ ScrollX -= e.Delta * ScrollSpeed;
+ }
+ public override void onMouseMove (object sender, MouseMoveEventArgs e)
+ {
+ savedMousePos.X += e.XDelta;
+ savedMousePos.Y += e.YDelta;
+ base.onMouseMove (sender, new MouseMoveEventArgs(savedMousePos.X,savedMousePos.Y,e.XDelta,e.YDelta));
+ }
+ #endregion
+
+ public override Rectangle ContextCoordinates (Rectangle r)
+ {
+ return base.ContextCoordinates (r) - new Point((int)ScrollX,(int)ScrollY);
+ }
+ public override Rectangle ScreenCoordinates (Rectangle r)
+ {
+ return base.ScreenCoordinates (r) - new Point((int)ScrollX,(int)ScrollY);
+ }
+
+ public override void registerClipRect ()
+ {
+ HostContainer.redrawClip.AddRectangle (base.ScreenCoordinates(Slot));
+ }
+
+ public override void Paint(ref Cairo.Context ctx, Rectangles clip = null)
+ {
+ if (!Visible)//check if necessary??
+ return;
+
+ ctx.Save();
+
+ // ctx.Rectangle(ContextCoordinates(Slot));
+ // ctx.Clip();
+ //
+// if (clip != null)
+// clip.clip(ctx);
+ //clip.Srcoll (this);
+
+ base.Paint (ref ctx, clip);
+
+ //clip to client zone
+ ctx.Rectangle(Parent.ContextCoordinates(ClientRectangle + Slot.Position));
+ ctx.Clip();
+
+// if (clip != null)
+// clip.Srcoll (this);
+ // if (clip != null)
+ // clip.Rebase(this);
+
+ if (Child != null)
+ Child.Paint(ref ctx, clip);
+
+ ctx.Restore();
+ }
+ }
+}
diff --git a/src/GraphicObjects/Slider.cs b/src/GraphicObjects/Slider.cs
index 27c162a0..a931934a 100644
--- a/src/GraphicObjects/Slider.cs
+++ b/src/GraphicObjects/Slider.cs
@@ -1,199 +1,199 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Cairo;
-using System.Xml.Serialization;
-using System.ComponentModel;
-using System.Diagnostics;
-
-namespace Crow
-{
- public class Slider : NumericControl
- {
- #region CTOR
- public Slider() : base()
- {}
- public Slider(double minimum, double maximum, double step)
- : base(minimum,maximum,step)
- {
- }
- #endregion
-
- #region implemented abstract members of TemplatedControl
-
- protected override void loadTemplate (GraphicObject template = null)
- {
-
- }
-
- #endregion
-
- #region private fields
- Rectangle cursor;
- int _cursorSize;
- Color _cursorColor;
- Orientation _orientation;
- bool holdCursor = false;
- #endregion
-
- protected double unity;
-
- #region Public properties
- [XmlAttributeAttribute()][DefaultValue("BlueGray")]
- public virtual Color CursorColor {
- get { return _cursorColor; }
- set {
- _cursorColor = value;
- registerForGraphicUpdate ();
- }
- }
- [XmlAttributeAttribute()][DefaultValue(20)]
- public virtual int CursorSize {
- get { return _cursorSize; }
- set {
- _cursorSize = value;
- registerForGraphicUpdate ();
- }
- }
- [XmlAttributeAttribute()][DefaultValue(Orientation.Horizontal)]
- public virtual Orientation Orientation
- {
- get { return _orientation; }
- set { _orientation = value; }
- }
- #endregion
- [XmlAttributeAttribute()][DefaultValue(10.0)]
- public override double Maximum {
- get { return base.Maximum; }
- set {
- if (value == base.Maximum)
- return;
- base.Maximum = value;
- LargeIncrement = base.Maximum / 10.0;
- SmallIncrement = LargeIncrement / 5.0;
-
- }
- }
- #region GraphicObject Overrides
- [XmlAttributeAttribute()][DefaultValue("Gray")]
- public override Color Background {
- get { return base.Background; }
- set { base.Background = value; }
- }
- [XmlAttributeAttribute()][DefaultValue(true)]
- public override bool Focusable
- {
- get { return base.Focusable; }
- set { base.Focusable = value; }
- }
- //TODO:seems strange to trigger layout computation in an
- //overriding of updateGraphic
- protected override void UpdateGraphic ()
- {
- if (Maximum > 0)
- computeCursorPosition();
- base.UpdateGraphic ();
- }
-
- protected override void onDraw (Context gr)
- {
- base.onDraw (gr);
- if (Maximum <= 0)
- return;
- Rectangle r = ClientRectangle;
- PointD pStart;
- PointD pEnd;
- if (_orientation == Orientation.Horizontal) {
- pStart = r.TopLeft + new Point (_cursorSize / 2, r.Height / 2);
- pEnd = r.TopRight + new Point (-_cursorSize / 2, r.Height / 2);
- } else {
- pStart = r.TopLeft + new Point (r.Width / 2, _cursorSize / 2);
- pEnd = r.BottomLeft + new Point (r.Width / 2,- _cursorSize / 2);
- }
-
- DrawGraduations (gr, pStart,pEnd);
-
- DrawCursor (gr, cursor);
- }
- #endregion
-
- protected virtual void DrawGraduations(Context gr, PointD pStart, PointD pEnd)
- {
- gr.SetSourceColor(Foreground);
-
- gr.LineWidth = 1;
- gr.MoveTo(pStart);
- gr.LineTo(pEnd);
-
- gr.Stroke();
-
- }
- protected virtual void DrawCursor(Context gr, Rectangle _cursor)
- {
- gr.SetSourceColor(CursorColor);
- CairoHelpers.CairoRectangle (gr, _cursor, CornerRadius);
- gr.FillPreserve();
- }
-
- void computeCursorPosition()
- {
- Rectangle r = ClientRectangle;
- PointD p1;
-
- if (_orientation == Orientation.Horizontal) {
- cursor = new Rectangle (new Size (_cursorSize, (int)(r.Height)));
- p1 = r.TopLeft + new Point (_cursorSize / 2, r.Height / 2);
- unity = (double)(r.Width - _cursorSize) / (Maximum - Minimum);
- cursor.TopLeft = new Point (r.Left + (int)(Value * unity),
- (int)(p1.Y - cursor.Height / 2));
- } else {
- cursor = new Rectangle (new Size ((int)(r.Width), _cursorSize));
- p1 = r.TopLeft + new Point (r.Width / 2, _cursorSize / 2);
- unity = (double)(r.Height - _cursorSize) / (Maximum - Minimum);
- cursor.TopLeft = new Point ((int)(p1.X - r.Width / 2),
- r.Top + (int)(Value * unity));
- }
- cursor.Inflate (-1);
- }
-
- #region mouse handling
- public override void onMouseDown (object sender, OpenTK.Input.MouseButtonEventArgs e)
- {
- base.onMouseDown (sender, e);
-
- Rectangle cursInScreenCoord = ScreenCoordinates (cursor + Slot.Position);
- if (cursInScreenCoord.ContainsOrIsEqual (e.Position))
- holdCursor = true;
- else if (_orientation == Orientation.Horizontal) {
- if (e.Position.X < cursInScreenCoord.Left)
- Value -= LargeIncrement;
- else
- Value += LargeIncrement;
- } else {
- if (e.Position.Y < cursInScreenCoord.Top)
- Value -= LargeIncrement;
- else
- Value += LargeIncrement;
- }
- }
- public override void onMouseUp (object sender, OpenTK.Input.MouseButtonEventArgs e)
- {
- base.onMouseUp (sender, e);
-
- holdCursor = false;
- }
- public override void onMouseMove (object sender, OpenTK.Input.MouseMoveEventArgs e)
- {
- if (holdCursor) {
- if (_orientation == Orientation.Horizontal)
- Value += (double)e.XDelta / unity;
- else
- Value += (double)e.YDelta / unity;
- }
-
- base.onMouseMove (sender, e);
- }
- #endregion
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Cairo;
+using System.Xml.Serialization;
+using System.ComponentModel;
+using System.Diagnostics;
+
+namespace Crow
+{
+ public class Slider : NumericControl
+ {
+ #region CTOR
+ public Slider() : base()
+ {}
+ public Slider(double minimum, double maximum, double step)
+ : base(minimum,maximum,step)
+ {
+ }
+ #endregion
+
+ #region implemented abstract members of TemplatedControl
+
+ protected override void loadTemplate (GraphicObject template = null)
+ {
+
+ }
+
+ #endregion
+
+ #region private fields
+ Rectangle cursor;
+ int _cursorSize;
+ Color _cursorColor;
+ Orientation _orientation;
+ bool holdCursor = false;
+ #endregion
+
+ protected double unity;
+
+ #region Public properties
+ [XmlAttributeAttribute()][DefaultValue("BlueGray")]
+ public virtual Color CursorColor {
+ get { return _cursorColor; }
+ set {
+ _cursorColor = value;
+ registerForGraphicUpdate ();
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(20)]
+ public virtual int CursorSize {
+ get { return _cursorSize; }
+ set {
+ _cursorSize = value;
+ registerForGraphicUpdate ();
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(Orientation.Horizontal)]
+ public virtual Orientation Orientation
+ {
+ get { return _orientation; }
+ set { _orientation = value; }
+ }
+ #endregion
+ [XmlAttributeAttribute()][DefaultValue(10.0)]
+ public override double Maximum {
+ get { return base.Maximum; }
+ set {
+ if (value == base.Maximum)
+ return;
+ base.Maximum = value;
+ LargeIncrement = base.Maximum / 10.0;
+ SmallIncrement = LargeIncrement / 5.0;
+
+ }
+ }
+ #region GraphicObject Overrides
+ [XmlAttributeAttribute()][DefaultValue("Gray")]
+ public override Color Background {
+ get { return base.Background; }
+ set { base.Background = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue(true)]
+ public override bool Focusable
+ {
+ get { return base.Focusable; }
+ set { base.Focusable = value; }
+ }
+ //TODO:seems strange to trigger layout computation in an
+ //overriding of updateGraphic
+ protected override void UpdateGraphic ()
+ {
+ if (Maximum > 0)
+ computeCursorPosition();
+ base.UpdateGraphic ();
+ }
+
+ protected override void onDraw (Context gr)
+ {
+ base.onDraw (gr);
+ if (Maximum <= 0)
+ return;
+ Rectangle r = ClientRectangle;
+ PointD pStart;
+ PointD pEnd;
+ if (_orientation == Orientation.Horizontal) {
+ pStart = r.TopLeft + new Point (_cursorSize / 2, r.Height / 2);
+ pEnd = r.TopRight + new Point (-_cursorSize / 2, r.Height / 2);
+ } else {
+ pStart = r.TopLeft + new Point (r.Width / 2, _cursorSize / 2);
+ pEnd = r.BottomLeft + new Point (r.Width / 2,- _cursorSize / 2);
+ }
+
+ DrawGraduations (gr, pStart,pEnd);
+
+ DrawCursor (gr, cursor);
+ }
+ #endregion
+
+ protected virtual void DrawGraduations(Context gr, PointD pStart, PointD pEnd)
+ {
+ gr.SetSourceColor(Foreground);
+
+ gr.LineWidth = 1;
+ gr.MoveTo(pStart);
+ gr.LineTo(pEnd);
+
+ gr.Stroke();
+
+ }
+ protected virtual void DrawCursor(Context gr, Rectangle _cursor)
+ {
+ gr.SetSourceColor(CursorColor);
+ CairoHelpers.CairoRectangle (gr, _cursor, CornerRadius);
+ gr.FillPreserve();
+ }
+
+ void computeCursorPosition()
+ {
+ Rectangle r = ClientRectangle;
+ PointD p1;
+
+ if (_orientation == Orientation.Horizontal) {
+ cursor = new Rectangle (new Size (_cursorSize, (int)(r.Height)));
+ p1 = r.TopLeft + new Point (_cursorSize / 2, r.Height / 2);
+ unity = (double)(r.Width - _cursorSize) / (Maximum - Minimum);
+ cursor.TopLeft = new Point (r.Left + (int)(Value * unity),
+ (int)(p1.Y - cursor.Height / 2));
+ } else {
+ cursor = new Rectangle (new Size ((int)(r.Width), _cursorSize));
+ p1 = r.TopLeft + new Point (r.Width / 2, _cursorSize / 2);
+ unity = (double)(r.Height - _cursorSize) / (Maximum - Minimum);
+ cursor.TopLeft = new Point ((int)(p1.X - r.Width / 2),
+ r.Top + (int)(Value * unity));
+ }
+ cursor.Inflate (-1);
+ }
+
+ #region mouse handling
+ public override void onMouseDown (object sender, OpenTK.Input.MouseButtonEventArgs e)
+ {
+ base.onMouseDown (sender, e);
+
+ Rectangle cursInScreenCoord = ScreenCoordinates (cursor + Slot.Position);
+ if (cursInScreenCoord.ContainsOrIsEqual (e.Position))
+ holdCursor = true;
+ else if (_orientation == Orientation.Horizontal) {
+ if (e.Position.X < cursInScreenCoord.Left)
+ Value -= LargeIncrement;
+ else
+ Value += LargeIncrement;
+ } else {
+ if (e.Position.Y < cursInScreenCoord.Top)
+ Value -= LargeIncrement;
+ else
+ Value += LargeIncrement;
+ }
+ }
+ public override void onMouseUp (object sender, OpenTK.Input.MouseButtonEventArgs e)
+ {
+ base.onMouseUp (sender, e);
+
+ holdCursor = false;
+ }
+ public override void onMouseMove (object sender, OpenTK.Input.MouseMoveEventArgs e)
+ {
+ if (holdCursor) {
+ if (_orientation == Orientation.Horizontal)
+ Value += (double)e.XDelta / unity;
+ else
+ Value += (double)e.YDelta / unity;
+ }
+
+ base.onMouseMove (sender, e);
+ }
+ #endregion
+ }
+}
diff --git a/src/GraphicObjects/TextBox.cs b/src/GraphicObjects/TextBox.cs
index 7d67e825..6af75f1e 100644
--- a/src/GraphicObjects/TextBox.cs
+++ b/src/GraphicObjects/TextBox.cs
@@ -1,202 +1,202 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using OpenTK.Input;
-using Cairo;
-using System.Diagnostics;
-using System.Xml.Serialization;
-using System.Globalization;
-using System.ComponentModel;
-using System.Runtime.InteropServices;
-
-namespace Crow
-{
- public class TextBox : Label
- {
- #region CTOR
- public TextBox(string _initialValue)
- : base(_initialValue)
- {
-
- }
-
- public TextBox()
- { }
- #endregion
-
- #region GraphicObject overrides
- [XmlIgnore]public override bool HasFocus //trigger update when lost focus to errase text beam
- {
- get
- {
- return base.HasFocus;
- }
- set
- {
- base.HasFocus = value;
- registerForGraphicUpdate();
- }
- }
- [XmlAttributeAttribute()][DefaultValue(true)]
- public override bool Focusable
- {
- get { return base.Focusable; }
- set { base.Focusable = value; }
- }
- [XmlAttributeAttribute()][DefaultValue("White")]
- public override Color Background {
- get { return base.Background; }
- set { base.Background = value; }
- }
- [XmlAttributeAttribute()][DefaultValue("Black")]
- public override Color Foreground {
- get { return base.Foreground; }
- set { base.Foreground = value; }
- }
-
- protected override void onDraw (Context gr)
- {
- base.onDraw (gr);
- FontExtents fe = gr.FontExtents;
- }
- #endregion
-
- public event EventHandler<TextChangeEventArgs> TextChanged;
-
- public virtual void OnTextChanged(Object sender, TextChangeEventArgs e)
- {
- TextChanged.Raise (this, e);
- }
-
- #region Keyboard handling
- public override void onKeyDown (object sender, KeyboardKeyEventArgs e)
- {
- base.onKeyDown (sender, e);
-
- Key key = e.Key;
-
- switch (key)
- {
- case Key.Back:
- if (!selectionIsEmpty)
- {
-// Text = Text.Remove(selectionStart, selectionEnd - selectionStart);
-// selReleasePos = -1;
-// currentCol = selBeginPos;
- }
- else
- this.DeleteChar();
- break;
- case Key.Clear:
- break;
- case Key.Delete:
- if (selectionIsEmpty)
- CurrentColumn++;
- this.DeleteChar ();
- break;
- case Key.Enter:
- case Key.KeypadEnter:
- OnTextChanged(this,new TextChangeEventArgs(Text));
- break;
- case Key.Escape:
- Text = "";
- CurrentColumn = 0;
- SelRelease = -1;
- break;
- case Key.Home:
- //TODO
- if (e.Control)
- CurrentLine = 0;
- CurrentColumn = 0;
- break;
- case Key.End:
- if (e.Control)
- CurrentLine = int.MaxValue;
- CurrentColumn = int.MaxValue;
- break;
- case Key.Insert:
- break;
- case Key.Left:
- CurrentColumn--;
- break;
- case Key.Right:
- CurrentColumn++;
- break;
- case Key.Up:
- CurrentLine--;
- break;
- case Key.Down:
- CurrentLine++;
- break;
- case Key.Menu:
- break;
- case Key.NumLock:
- break;
- case Key.PageDown:
- break;
- case Key.PageUp:
- break;
- case Key.RWin:
- break;
- case Key.Tab:
- this.Insert("\t");
- break;
- case Key.KeypadDecimal:
- this.Insert (".");
- break;
- case Key.Space:
- this.Insert(" ");
- break;
- case Key.KeypadDivide:
- case Key.Slash:
- this.Insert("/");
- break;
- case Key.KeypadMultiply:
- this.Insert("*");
- break;
- case Key.KeypadMinus:
- case Key.Minus:
- this.Insert("-");
- break;
- case Key.KeypadPlus:
- case Key.Plus:
- this.Insert("+");
- break;
- case Key.ShiftLeft:
- case Key.ShiftRight:
- case Key.AltLeft:
- case Key.AltRight:
- break;
- case Key.Semicolon:
- this.Insert(";");
- break;
- default:
- if (!selectionIsEmpty)
- {
-// Text = Text.Remove(selectionStart, selectionEnd - selectionStart);
-// currentCol = selBeginPos;
- }
-
- 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 (e.Shift)
- k = key.ToString();
- else
- k = key.ToString().ToLower();
-
- this.Insert (k);
-
- SelRelease = -1;
- SelBegin = new Point(CurrentColumn, SelBegin.Y);
-
- break;
- }
- registerForGraphicUpdate();
- }
- #endregion
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using OpenTK.Input;
+using Cairo;
+using System.Diagnostics;
+using System.Xml.Serialization;
+using System.Globalization;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+namespace Crow
+{
+ public class TextBox : Label
+ {
+ #region CTOR
+ public TextBox(string _initialValue)
+ : base(_initialValue)
+ {
+
+ }
+
+ public TextBox()
+ { }
+ #endregion
+
+ #region GraphicObject overrides
+ [XmlIgnore]public override bool HasFocus //trigger update when lost focus to errase text beam
+ {
+ get
+ {
+ return base.HasFocus;
+ }
+ set
+ {
+ base.HasFocus = value;
+ registerForGraphicUpdate();
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(true)]
+ public override bool Focusable
+ {
+ get { return base.Focusable; }
+ set { base.Focusable = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue("White")]
+ public override Color Background {
+ get { return base.Background; }
+ set { base.Background = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue("Black")]
+ public override Color Foreground {
+ get { return base.Foreground; }
+ set { base.Foreground = value; }
+ }
+
+ protected override void onDraw (Context gr)
+ {
+ base.onDraw (gr);
+ FontExtents fe = gr.FontExtents;
+ }
+ #endregion
+
+ public event EventHandler<TextChangeEventArgs> TextChanged;
+
+ public virtual void OnTextChanged(Object sender, TextChangeEventArgs e)
+ {
+ TextChanged.Raise (this, e);
+ }
+
+ #region Keyboard handling
+ public override void onKeyDown (object sender, KeyboardKeyEventArgs e)
+ {
+ base.onKeyDown (sender, e);
+
+ Key key = e.Key;
+
+ switch (key)
+ {
+ case Key.Back:
+ if (!selectionIsEmpty)
+ {
+// Text = Text.Remove(selectionStart, selectionEnd - selectionStart);
+// selReleasePos = -1;
+// currentCol = selBeginPos;
+ }
+ else
+ this.DeleteChar();
+ break;
+ case Key.Clear:
+ break;
+ case Key.Delete:
+ if (selectionIsEmpty)
+ CurrentColumn++;
+ this.DeleteChar ();
+ break;
+ case Key.Enter:
+ case Key.KeypadEnter:
+ OnTextChanged(this,new TextChangeEventArgs(Text));
+ break;
+ case Key.Escape:
+ Text = "";
+ CurrentColumn = 0;
+ SelRelease = -1;
+ break;
+ case Key.Home:
+ //TODO
+ if (e.Control)
+ CurrentLine = 0;
+ CurrentColumn = 0;
+ break;
+ case Key.End:
+ if (e.Control)
+ CurrentLine = int.MaxValue;
+ CurrentColumn = int.MaxValue;
+ break;
+ case Key.Insert:
+ break;
+ case Key.Left:
+ CurrentColumn--;
+ break;
+ case Key.Right:
+ CurrentColumn++;
+ break;
+ case Key.Up:
+ CurrentLine--;
+ break;
+ case Key.Down:
+ CurrentLine++;
+ break;
+ case Key.Menu:
+ break;
+ case Key.NumLock:
+ break;
+ case Key.PageDown:
+ break;
+ case Key.PageUp:
+ break;
+ case Key.RWin:
+ break;
+ case Key.Tab:
+ this.Insert("\t");
+ break;
+ case Key.KeypadDecimal:
+ this.Insert (".");
+ break;
+ case Key.Space:
+ this.Insert(" ");
+ break;
+ case Key.KeypadDivide:
+ case Key.Slash:
+ this.Insert("/");
+ break;
+ case Key.KeypadMultiply:
+ this.Insert("*");
+ break;
+ case Key.KeypadMinus:
+ case Key.Minus:
+ this.Insert("-");
+ break;
+ case Key.KeypadPlus:
+ case Key.Plus:
+ this.Insert("+");
+ break;
+ case Key.ShiftLeft:
+ case Key.ShiftRight:
+ case Key.AltLeft:
+ case Key.AltRight:
+ break;
+ case Key.Semicolon:
+ this.Insert(";");
+ break;
+ default:
+ if (!selectionIsEmpty)
+ {
+// Text = Text.Remove(selectionStart, selectionEnd - selectionStart);
+// currentCol = selBeginPos;
+ }
+
+ 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 (e.Shift)
+ k = key.ToString();
+ else
+ k = key.ToString().ToLower();
+
+ this.Insert (k);
+
+ SelRelease = -1;
+ SelBegin = new Point(CurrentColumn, SelBegin.Y);
+
+ break;
+ }
+ registerForGraphicUpdate();
+ }
+ #endregion
+ }
+}
diff --git a/src/GraphicObjects/TextRun.cs b/src/GraphicObjects/TextRun.cs
index 6201f7c1..1c539c67 100644
--- a/src/GraphicObjects/TextRun.cs
+++ b/src/GraphicObjects/TextRun.cs
@@ -1,333 +1,333 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Diagnostics;
-using Cairo;
-using System.Text.RegularExpressions;
-using System.Xml.Serialization;
-using System.ComponentModel;
-using OpenTK.Input;
-
-namespace Crow
-{
- [Serializable]
- public class TextRun : GraphicObject
- {
- #region CTOR
- public TextRun()
- {
-
- }
- public TextRun(string _text)
- : base()
- {
- Text = _text;
- }
- #endregion
-
- //TODO:change protected to private
-
- #region private and protected fields
- protected string _text = "label";
- Alignment _textAlignment = Alignment.LeftCenter;
- bool _multiline;
- bool wordWrap;
- protected Rectangle rText;
- protected float widthRatio = 1f;
- protected float heightRatio = 1f;
- protected FontExtents fe;
- protected TextExtents te;
- #endregion
-
-
- [XmlAttributeAttribute()][DefaultValue(Alignment.LeftCenter)]
- public Alignment TextAlignment
- {
- get { return _textAlignment; }
- set { _textAlignment = value; }
- }
- [XmlAttributeAttribute()][DefaultValue("label")]
- public string Text
- {
- get {
- return lines == null ?
- _text : lines.Aggregate((i, j) => i + Interface.LineBreak + j);
- }
- set
- {
- if (_text == value)
- return;
-
- registerForGraphicUpdate();
- this.RegisterForLayouting ((int)LayoutingType.Sizing);
-
-
- _text = value;
-
- if (string.IsNullOrEmpty(_text))
- _text = "";
-
- lines = getLines;
- }
- }
- [XmlAttributeAttribute()][DefaultValue(false)]
- public bool Multiline
- {
- get { return _multiline; }
- set
- {
- _multiline = value;
- registerForGraphicUpdate();
- }
- }
- [XmlAttributeAttribute()][DefaultValue(false)]
- public bool WordWrap {
- get {
- return wordWrap;
- }
- set {
- if (wordWrap == value)
- return;
- wordWrap = value;
- registerForGraphicUpdate();
- }
- }
-
- List<string> lines;
- List<string> getLines {
- get {
- return _multiline ?
- Regex.Split (_text, "\r\n|\r|\n").ToList() :
- new List<string>(new string[] { _text });
- }
- }
-
- #region GraphicObject overrides
- [XmlAttributeAttribute()][DefaultValue(-1)]
- public override int Width {
- get { return base.Width; }
- set { base.Width = value; }
- }
- [XmlAttributeAttribute()][DefaultValue(-1)]
- public override int Height {
- get { return base.Height; }
- set { base.Height = value; }
- }
- [XmlAttributeAttribute()][DefaultValue(2)]
- public override int Margin {
- get { return base.Margin; }
- set { base.Margin = value; }
- }
-
- protected override Size measureRawSize()
- {
- Size size;
-
- if (lines == null)
- lines = getLines;
-
- using (ImageSurface img = new ImageSurface (Format.Argb32, 10, 10)) {
- using (Context gr = new Context (img)) {
- //Cairo.FontFace cf = gr.GetContextFontFace ();
-
- gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
- gr.SetFontSize (Font.Size);
-
- te = new TextExtents();
-
- foreach (string s in lines) {
- string l = s.Replace("\t", new String (' ', Interface.TabSize));
-
-#if _WIN32 || _WIN64
- TextExtents tmp = gr.TextExtents(str.ToUtf8());
-#elif __linux__
- TextExtents tmp = gr.TextExtents (l);
-#endif
- if (tmp.XAdvance > te.XAdvance)
- te = tmp;
- }
- fe = gr.FontExtents;
- int lc = lines.Count;
- //ensure minimal height = text line height
- if (lc == 0)
- lc = 1;
- size = new Size ((int)Math.Ceiling (te.XAdvance) + Margin * 2, (int)(fe.Height * lc) + Margin*2);
- }
- }
-
- return size;;
- }
- protected override void onDraw (Context gr)
- {
- base.onDraw (gr);
-
- gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
- gr.SetFontSize (Font.Size);
-
- gr.Antialias = Antialias.Subpixel;
- //gr.FontOptions.Antialias = Antialias.Subpixel;
- //gr.FontOptions.HintMetrics = HintMetrics.On;
-
- rText = new Rectangle(measureRawSize());
- rText.Width -= 2 * Margin;
- rText.Height -= 2 * Margin;
-
- widthRatio = 1f;
- heightRatio = 1f;
-
- Rectangle cb = ClientRectangle;
-
- //ignore text alignment if size to content = true
- //or if text size is larger than client bounds
- if (Bounds.Size < 0 || rText.Width > cb.Width)
- {
- rText.X = cb.X;
- rText.Y = cb.Y;
- }else {
-
- 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;
- 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 * Font.Size, 0, 0, heightRatio * Font.Size, 0, 0);
-
-
- int curLineCount = 0;
- for (int i = 0;i < lines.Count;i++) {
- string l = lines [i].Replace ("\t", new String (' ', Interface.TabSize));
- List<string> wl = new List<string> ();
- int lineLength = (int)gr.TextExtents (l).XAdvance;
-
- if (wordWrap && lineLength > cb.Width) {
- string tmpLine = "";
- int curChar = 0;
- while (curChar < l.Length) {
- tmpLine += l [curChar];
- if ((int)gr.TextExtents (tmpLine).XAdvance > cb.Width) {
- tmpLine = tmpLine.Remove (tmpLine.Length - 1);
- wl.Add (tmpLine);
- tmpLine = "";
- continue;
- }
- curChar++;
- }
- wl.Add (tmpLine);
- } else
- wl.Add (l);
-
- foreach (string ll in wl) {
- lineLength = (int)gr.TextExtents (ll).XAdvance;
-
-
- if (string.IsNullOrWhiteSpace (ll)) {
- curLineCount++;
- continue;
- }
-
- gr.SetSourceColor (Foreground);
- gr.MoveTo (rText.X, rText.Y + fe.Ascent + fe.Height * curLineCount);
-
- #if _WIN32 || _WIN64
- gr.ShowText(ll.ToUtf8());
- #elif __linux__
- gr.ShowText (ll);
- #endif
- gr.Fill ();
-
- curLineCount++;
-
- }
- }
- }
- #endregion
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Diagnostics;
+using Cairo;
+using System.Text.RegularExpressions;
+using System.Xml.Serialization;
+using System.ComponentModel;
+using OpenTK.Input;
+
+namespace Crow
+{
+ [Serializable]
+ public class TextRun : GraphicObject
+ {
+ #region CTOR
+ public TextRun()
+ {
+
+ }
+ public TextRun(string _text)
+ : base()
+ {
+ Text = _text;
+ }
+ #endregion
+
+ //TODO:change protected to private
+
+ #region private and protected fields
+ protected string _text = "label";
+ Alignment _textAlignment = Alignment.LeftCenter;
+ bool _multiline;
+ bool wordWrap;
+ protected Rectangle rText;
+ protected float widthRatio = 1f;
+ protected float heightRatio = 1f;
+ protected FontExtents fe;
+ protected TextExtents te;
+ #endregion
+
+
+ [XmlAttributeAttribute()][DefaultValue(Alignment.LeftCenter)]
+ public Alignment TextAlignment
+ {
+ get { return _textAlignment; }
+ set { _textAlignment = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue("label")]
+ public string Text
+ {
+ get {
+ return lines == null ?
+ _text : lines.Aggregate((i, j) => i + Interface.LineBreak + j);
+ }
+ set
+ {
+ if (_text == value)
+ return;
+
+ registerForGraphicUpdate();
+ this.RegisterForLayouting ((int)LayoutingType.Sizing);
+
+
+ _text = value;
+
+ if (string.IsNullOrEmpty(_text))
+ _text = "";
+
+ lines = getLines;
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(false)]
+ public bool Multiline
+ {
+ get { return _multiline; }
+ set
+ {
+ _multiline = value;
+ registerForGraphicUpdate();
+ }
+ }
+ [XmlAttributeAttribute()][DefaultValue(false)]
+ public bool WordWrap {
+ get {
+ return wordWrap;
+ }
+ set {
+ if (wordWrap == value)
+ return;
+ wordWrap = value;
+ registerForGraphicUpdate();
+ }
+ }
+
+ List<string> lines;
+ List<string> getLines {
+ get {
+ return _multiline ?
+ Regex.Split (_text, "\r\n|\r|\n").ToList() :
+ new List<string>(new string[] { _text });
+ }
+ }
+
+ #region GraphicObject overrides
+ [XmlAttributeAttribute()][DefaultValue(-1)]
+ public override int Width {
+ get { return base.Width; }
+ set { base.Width = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue(-1)]
+ public override int Height {
+ get { return base.Height; }
+ set { base.Height = value; }
+ }
+ [XmlAttributeAttribute()][DefaultValue(2)]
+ public override int Margin {
+ get { return base.Margin; }
+ set { base.Margin = value; }
+ }
+
+ protected override Size measureRawSize()
+ {
+ Size size;
+
+ if (lines == null)
+ lines = getLines;
+
+ using (ImageSurface img = new ImageSurface (Format.Argb32, 10, 10)) {
+ using (Context gr = new Context (img)) {
+ //Cairo.FontFace cf = gr.GetContextFontFace ();
+
+ gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+ gr.SetFontSize (Font.Size);
+
+ te = new TextExtents();
+
+ foreach (string s in lines) {
+ string l = s.Replace("\t", new String (' ', Interface.TabSize));
+
+#if _WIN32 || _WIN64
+ TextExtents tmp = gr.TextExtents(str.ToUtf8());
+#elif __linux__
+ TextExtents tmp = gr.TextExtents (l);
+#endif
+ if (tmp.XAdvance > te.XAdvance)
+ te = tmp;
+ }
+ fe = gr.FontExtents;
+ int lc = lines.Count;
+ //ensure minimal height = text line height
+ if (lc == 0)
+ lc = 1;
+ size = new Size ((int)Math.Ceiling (te.XAdvance) + Margin * 2, (int)(fe.Height * lc) + Margin*2);
+ }
+ }
+
+ return size;;
+ }
+ protected override void onDraw (Context gr)
+ {
+ base.onDraw (gr);
+
+ gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+ gr.SetFontSize (Font.Size);
+
+ gr.Antialias = Antialias.Subpixel;
+ //gr.FontOptions.Antialias = Antialias.Subpixel;
+ //gr.FontOptions.HintMetrics = HintMetrics.On;
+
+ rText = new Rectangle(measureRawSize());
+ rText.Width -= 2 * Margin;
+ rText.Height -= 2 * Margin;
+
+ widthRatio = 1f;
+ heightRatio = 1f;
+
+ Rectangle cb = ClientRectangle;
+
+ //ignore text alignment if size to content = true
+ //or if text size is larger than client bounds
+ if (Bounds.Size < 0 || rText.Width > cb.Width)
+ {
+ rText.X = cb.X;
+ rText.Y = cb.Y;
+ }else {
+
+ 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;
+ 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 * Font.Size, 0, 0, heightRatio * Font.Size, 0, 0);
+
+
+ int curLineCount = 0;
+ for (int i = 0;i < lines.Count;i++) {
+ string l = lines [i].Replace ("\t", new String (' ', Interface.TabSize));
+ List<string> wl = new List<string> ();
+ int lineLength = (int)gr.TextExtents (l).XAdvance;
+
+ if (wordWrap && lineLength > cb.Width) {
+ string tmpLine = "";
+ int curChar = 0;
+ while (curChar < l.Length) {
+ tmpLine += l [curChar];
+ if ((int)gr.TextExtents (tmpLine).XAdvance > cb.Width) {
+ tmpLine = tmpLine.Remove (tmpLine.Length - 1);
+ wl.Add (tmpLine);
+ tmpLine = "";
+ continue;
+ }
+ curChar++;
+ }
+ wl.Add (tmpLine);
+ } else
+ wl.Add (l);
+
+ foreach (string ll in wl) {
+ lineLength = (int)gr.TextExtents (ll).XAdvance;
+
+
+ if (string.IsNullOrWhiteSpace (ll)) {
+ curLineCount++;
+ continue;
+ }
+
+ gr.SetSourceColor (Foreground);
+ gr.MoveTo (rText.X, rText.Y + fe.Ascent + fe.Height * curLineCount);
+
+ #if _WIN32 || _WIN64
+ gr.ShowText(ll.ToUtf8());
+ #elif __linux__
+ gr.ShowText (ll);
+ #endif
+ gr.Fill ();
+
+ curLineCount++;
+
+ }
+ }
+ }
+ #endregion
+ }
+}
diff --git a/src/GraphicObjects/VerticalStack.cs b/src/GraphicObjects/VerticalStack.cs
index b23e6813..afd26429 100644
--- a/src/GraphicObjects/VerticalStack.cs
+++ b/src/GraphicObjects/VerticalStack.cs
@@ -1,25 +1,25 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Crow
-{
- public class VerticalStack : GenericStack
- {
- public VerticalStack()
- : base()
- {
- Orientation = Crow.Orientation.Vertical;
- }
-
- [System.Xml.Serialization.XmlIgnore]
- public override Orientation Orientation
- {
- get { return Orientation.Vertical; }
- //set { }
- }
-
-
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Crow
+{
+ public class VerticalStack : GenericStack
+ {
+ public VerticalStack()
+ : base()
+ {
+ Orientation = Crow.Orientation.Vertical;
+ }
+
+ [System.Xml.Serialization.XmlIgnore]
+ public override Orientation Orientation
+ {
+ get { return Orientation.Vertical; }
+ //set { }
+ }
+
+
+ }
+}
diff --git a/src/GraphicObjects/WrappedWidgetGroup.cs b/src/GraphicObjects/WrappedWidgetGroup.cs
index afd54e6c..fa033b5e 100755
--- a/src/GraphicObjects/WrappedWidgetGroup.cs
+++ b/src/GraphicObjects/WrappedWidgetGroup.cs
@@ -1,154 +1,154 @@
-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 = ClientRectangle.X;
- currentYForWidget = ClientRectangle.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 > ClientRectangle.Right && !HorizontalScrolling)
- return false;
- if (currentYForWidget > ClientRectangle.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 > ClientRectangle.Right && !HorizontalScrolling)
- {
- if (Orientation == Orientation.Vertical)
- {
- //not scrolling
- }
- else
- {
- currentXForWidget = ClientRectangle.X;
- currentYForWidget += widgetSpacing + highestWidget;
- highestWidget = 0;
- }
- }
- if (currentYForWidget > ClientRectangle.Bottom && !VerticalScrolling)
- {
- if (Orientation == Orientation.Horizontal)
- {
- //not scrolling
- }
- else
- {
- currentXForWidget += widgetSpacing + largestWidget;
- currentYForWidget = ClientRectangle.Y;
- largestWidget = 0;
- }
-
- }
- }
- }
- }
-}
+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 = ClientRectangle.X;
+ currentYForWidget = ClientRectangle.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 > ClientRectangle.Right && !HorizontalScrolling)
+ return false;
+ if (currentYForWidget > ClientRectangle.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 > ClientRectangle.Right && !HorizontalScrolling)
+ {
+ if (Orientation == Orientation.Vertical)
+ {
+ //not scrolling
+ }
+ else
+ {
+ currentXForWidget = ClientRectangle.X;
+ currentYForWidget += widgetSpacing + highestWidget;
+ highestWidget = 0;
+ }
+ }
+ if (currentYForWidget > ClientRectangle.Bottom && !VerticalScrolling)
+ {
+ if (Orientation == Orientation.Horizontal)
+ {
+ //not scrolling
+ }
+ else
+ {
+ currentXForWidget += widgetSpacing + largestWidget;
+ currentYForWidget = ClientRectangle.Y;
+ largestWidget = 0;
+ }
+
+ }
+ }
+ }
+ }
+}