aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/GraphicObjects/GraphicObject.cs
diff options
context:
space:
mode:
authorj-p <jp.bruyere@live.be>2018-04-14 12:15:08 +0200
committerGitHub <noreply@github.com>2018-04-14 12:15:08 +0200
commit907358fed63b4a89e8dee5184cc9901a7107ab9f (patch)
tree18c473a86b553dbe9f08cfe345b6278c71e9594e /src/GraphicObjects/GraphicObject.cs
parent7c735fa149bf23223eda734f19d5547797ca8ac2 (diff)
parent5a06966fd4be89263988d0838556b78a7988b5a9 (diff)
Merge pull request #40 from jpbruyere/devel
Devel
Diffstat (limited to 'src/GraphicObjects/GraphicObject.cs')
-rw-r--r--src/GraphicObjects/GraphicObject.cs603
1 files changed, 413 insertions, 190 deletions
diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs
index f671239d..bc955368 100644
--- a/src/GraphicObjects/GraphicObject.cs
+++ b/src/GraphicObjects/GraphicObject.cs
@@ -36,6 +36,12 @@ using System.Diagnostics;
using Crow.IML;
using System.Threading;
+
+#if DESIGN_MODE
+using System.Xml;
+using System.IO;
+#endif
+
namespace Crow
{
/// <summary>
@@ -45,6 +51,101 @@ namespace Crow
{
internal ReaderWriterLockSlim parentRWLock = new ReaderWriterLockSlim();
+ #if DESIGN_MODE
+ static MethodInfo miDesignAddDefLoc = typeof(GraphicObject).GetMethod("design_add_style_location",
+ BindingFlags.Instance | BindingFlags.NonPublic);
+ static MethodInfo miDesignAddValLoc = typeof(GraphicObject).GetMethod("design_add_iml_location",
+ BindingFlags.Instance | BindingFlags.NonPublic);
+
+ public volatile bool design_HasChanged = false;
+ public string design_id;
+ public int design_line;
+ public int design_column;
+ public string design_imlPath;
+ public bool design_isTGItem = false;//true if this is a templated item's root
+ public Dictionary<string,string> design_iml_values = new Dictionary<string, string>();
+ public Dictionary<string,string> design_style_values = new Dictionary<string, string>();
+ //public Dictionary<string,FileLocation> design_iml_locations = new Dictionary<string, FileLocation>();
+ public Dictionary<string,FileLocation> design_style_locations = new Dictionary<string, FileLocation>();
+
+ internal void design_add_style_location (string memberName, string path, int line, int col) {
+ if (design_style_locations.ContainsKey(memberName)){
+ Console.WriteLine ("default value localtion already set for {0}{1}.{2}", this.GetType().Name, this.design_id, memberName);
+ return;
+ }
+ design_style_locations.Add(memberName, new FileLocation(path,line,col));
+ }
+// internal void design_add_iml_location (string memberName, string path, int line, int col) {
+// if (design_iml_locations.ContainsKey(memberName)){
+// Console.WriteLine ("IML value localtion already set for {0}{1}.{2}", this.GetType().Name, this.design_id, memberName);
+// return;
+// }
+// design_iml_locations.Add(memberName, new FileLocation(path,line,col));
+// }
+
+ public virtual bool FindByDesignID(string designID, out GraphicObject go){
+ go = null;
+ if (this.design_id == designID){
+ go = this;
+ return true;
+ }
+ return false;
+ }
+
+ public string GetIML(){
+ XmlDocument doc = new XmlDocument( );
+
+ using (StringWriter sw = new StringWriter ()) {
+ XmlWriterSettings settings = new XmlWriterSettings {
+ Indent = true,
+ IndentChars = "\t",
+ };
+ using (XmlWriter xtw = XmlWriter.Create (sw, settings)) {
+ //(1) the xml declaration is recommended, but not mandatory
+ XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration ("1.0", "UTF-8", null);
+ doc.InsertBefore (xmlDeclaration, null);
+ getIML (doc, (XmlNode)doc);
+ doc.WriteTo (xtw);
+ }
+ this.design_HasChanged = false;
+ return sw.ToString ();
+ }
+ }
+
+ public virtual void getIML(XmlDocument doc, XmlNode parentElem) {
+ if (this.design_isTGItem)
+ return;
+
+ XmlElement xe = doc.CreateElement(this.GetType().Name);
+
+ foreach (KeyValuePair<string,string> kv in design_iml_values) {
+ XmlAttribute xa = doc.CreateAttribute (kv.Key);
+ xa.Value = kv.Value;
+ xe.Attributes.Append (xa);
+ }
+
+ parentElem.AppendChild (xe);
+ }
+ public Surface CreateIcon (int dragIconSize = 32) {
+ ImageSurface di = new ImageSurface (Format.Argb32, dragIconSize, dragIconSize);
+ using (Context ctx = new Context (di)) {
+ double div = Math.Max (LastPaintedSlot.Width, LastPaintedSlot.Height);
+ double s = (double)dragIconSize / div;
+ ctx.Scale (s, s);
+ if (bmp == null)
+ this.onDraw (ctx);
+ else {
+ if (LastPaintedSlot.Width>LastPaintedSlot.Height)
+ ctx.SetSourceSurface (bmp, 0, (LastPaintedSlot.Width-LastPaintedSlot.Height)/2);
+ else
+ ctx.SetSourceSurface (bmp, (LastPaintedSlot.Height-LastPaintedSlot.Width)/2, 0);
+ ctx.Paint ();
+ }
+ }
+ return di;
+ }
+ #endif
+
#region IDisposable implementation
protected bool disposed = false;
@@ -53,6 +154,7 @@ namespace Crow
GC.SuppressFinalize(this);
}
~GraphicObject(){
+ Debug.WriteLine(this.ToString() + " not disposed by user");
Dispose(false);
}
protected virtual void Dispose(bool disposing){
@@ -70,18 +172,8 @@ namespace Crow
throw new Exception("Trying to dispose an object queued for Redraw: " + this.ToString());
#endif
- if (CurrentInterface.HoverWidget != null) {
- if (CurrentInterface.HoverWidget.IsOrIsInside(this))
- CurrentInterface.HoverWidget = null;
- }
- if (CurrentInterface.ActiveWidget != null) {
- if (CurrentInterface.ActiveWidget.IsOrIsInside (this))
- CurrentInterface.ActiveWidget = null;
- }
- if (CurrentInterface.FocusedWidget != null) {
- if (CurrentInterface.FocusedWidget.IsOrIsInside (this))
- CurrentInterface.FocusedWidget = null;
- }
+ unshownPostActions ();
+
if (!localDataSourceIsNull)
DataSource = null;
@@ -100,14 +192,14 @@ namespace Crow
internal ulong uid = 0;
internal bool isPopup = false;
- internal GraphicObject focusParent {
+ public GraphicObject focusParent {
get { return (isPopup ? LogicalParent : parent) as GraphicObject; }
}
/// <summary>
/// interface this widget is bound to, this should not be changed once the instance is created
/// </summary>
- public Interface CurrentInterface = null;
+ public Interface IFace = null;
/// <summary>
/// contains the dirty rectangles in the coordinate system of the cache. those dirty zones
@@ -159,17 +251,17 @@ namespace Crow
/// <param name="iface">Iface.</param>
public GraphicObject (Interface iface) : this()
{
- CurrentInterface = iface;
+ IFace = iface;
Initialize ();
}
#endregion
- internal bool initialized = false;
+ //internal bool initialized = false;
/// <summary>
/// Initialize this Graphic object instance by setting style and default values and loading template if required
/// </summary>
public virtual void Initialize(){
loadDefaultValues ();
- initialized = true;
+ //initialized = true;
}
#region private fields
LayoutingType registeredLayoutings = LayoutingType.All;
@@ -186,6 +278,7 @@ namespace Crow
bool focusable = false;
bool hasFocus = false;
bool isActive = false;
+ bool isHover = false;
bool mouseRepeat;
protected bool isVisible = true;
bool isEnabled = true;
@@ -196,6 +289,7 @@ namespace Crow
bool cacheEnabled = false;
bool clipToClientRect = true;
protected object dataSource;
+ bool rootDataLevel;
string style;
object tag;
bool isDragged;
@@ -252,6 +346,7 @@ namespace Crow
parentRWLock.EnterWriteLock();
parent = value;
+ Slot = LastSlots = default(Rectangle);
parentRWLock.ExitWriteLock();
onParentChanged (this, e);
@@ -288,11 +383,24 @@ namespace Crow
Parent.ContextCoordinates (r);
}
public virtual Rectangle ScreenCoordinates (Rectangle r){
- return
- Parent.ScreenCoordinates(r) + Parent.getSlot().Position + Parent.ClientRectangle.Position;
+ try {
+ return
+ Parent.ScreenCoordinates(r) + Parent.getSlot().Position + Parent.ClientRectangle.Position;
+ } catch (Exception ex) {
+ Debug.WriteLine (ex);
+ return default(Rectangle);
+ }
}
public virtual Rectangle getSlot () { return Slot;}
#endregion
+ public Point ScreenPointToLocal(Point p){
+ Point pt = p - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft;
+ if (pt.X < 0)
+ pt.X = 0;
+ if (pt.Y < 0)
+ pt.Y = 0;
+ return pt;
+ }
#region EVENT HANDLERS
/// <summary>Occurs when mouse wheel is rolled in this object. It bubbles to the root</summary>
@@ -321,15 +429,29 @@ namespace Crow
public event EventHandler Focused;
/// <summary>Occurs when this object loose focus</summary>
public event EventHandler Unfocused;
- /// <summary>Occurs when the enabled state this object is set to true</summary>
+ /// <summary>Occurs when mouse is over</summary>
+ public event EventHandler Hover;
+ /// <summary>Occurs when this control is no longer the Hover one</summary>
+ public event EventHandler UnHover;
+ /// <summary>Occurs when this object loose focus</summary>
public event EventHandler Enabled;
/// <summary>Occurs when the enabled state this object is set to false</summary>
public event EventHandler Disabled;
- public event EventHandler StartDrag;
- public event EventHandler DragEnter;
- public event EventHandler DragLeave;
- public event EventHandler EndDrag;
- public event EventHandler Drop;
+
+ #region DragAndDrop Events
+ public event EventHandler<DragDropEventArgs> StartDrag;
+ public event EventHandler<DragDropEventArgs> DragEnter;
+ public event EventHandler<DragDropEventArgs> DragLeave;
+ public event EventHandler<DragDropEventArgs> EndDrag;
+ public event EventHandler<DragDropEventArgs> Drop;
+ #endregion
+
+ /// <summary>
+ /// Occurs when default value and styling are loaded, and for templated control,
+ /// template is also loaded. Bindings should be functionnal as well.
+ /// </summary>
+ public event EventHandler Initialized;
+
/// <summary>Occurs when one part of the rendering slot changed</summary>
public event EventHandler<LayoutingEventArgs> LayoutChanged;
/// <summary>Occurs when DataSource changed</summary>
@@ -342,7 +464,7 @@ namespace Crow
#region public properties
/// <summary>Random value placeholder</summary>
- [XmlAttributeAttribute]
+ [DesignCategory ("Divers")]
public object Tag {
get { return tag; }
set {
@@ -356,7 +478,7 @@ namespace Crow
/// If enabled, resulting bitmap of graphic object is cached
/// speeding up rendering of complex object. Default is enabled.
/// </summary>
- [XmlAttributeAttribute][DefaultValue(true)]
+ [DesignCategory ("Behavior")][DefaultValue(true)]
public virtual bool CacheEnabled {
get { return cacheEnabled; }
set {
@@ -369,7 +491,7 @@ namespace Crow
/// <summary>
/// If true, rendering of GraphicObject is clipped inside client rectangle
/// </summary>
- [XmlAttributeAttribute][DefaultValue(true)]
+ [DesignCategory ("Appearance")][DefaultValue(true)]
public virtual bool ClipToClientRect {
get { return clipToClientRect; }
set {
@@ -390,7 +512,7 @@ namespace Crow
/// and by template controls to find special element in their template implementation such
/// as a container or a group to put children in.
/// </summary>
- [XmlAttributeAttribute][DefaultValue(null)]
+ [DesignCategory ("Divers")][DefaultValue(null)]
public virtual string Name {
get {
#if DEBUG
@@ -410,7 +532,7 @@ namespace Crow
/// Vertical alignment inside parent, disabled if height is stretched
/// or top coordinate is not null
/// </summary>
- [XmlAttributeAttribute ()][DefaultValue(VerticalAlignment.Center)]
+ [DesignCategory ("Layout")][DefaultValue(VerticalAlignment.Center)]
public virtual VerticalAlignment VerticalAlignment {
get { return verticalAlignment; }
set {
@@ -426,7 +548,7 @@ namespace Crow
/// Horizontal alignment inside parent, disabled if width is stretched
/// or left coordinate is not null
/// </summary>
- [XmlAttributeAttribute()][DefaultValue(HorizontalAlignment.Center)]
+ [DesignCategory ("Layout")][DefaultValue(HorizontalAlignment.Center)]
public virtual HorizontalAlignment HorizontalAlignment {
get { return horizontalAlignment; }
set {
@@ -440,7 +562,7 @@ namespace Crow
/// <summary>
/// x position inside parent
/// </summary>
- [XmlAttributeAttribute()][DefaultValue(0)]
+ [DesignCategory ("Layout")][DefaultValue(0)]
public virtual int Left {
get { return left; }
set {
@@ -454,7 +576,7 @@ namespace Crow
/// <summary>
/// y position inside parent
/// </summary>
- [XmlAttributeAttribute()][DefaultValue(0)]
+ [DesignCategory ("Layout")][DefaultValue(0)]
public virtual int Top {
get { return top; }
set {
@@ -468,7 +590,7 @@ namespace Crow
/// <summary>
/// Helper property used to set width and height to fit in one call
/// </summary>
- [XmlAttributeAttribute()][DefaultValue(false)]
+ [DesignCategory ("Layout")][DefaultValue(false)]
public virtual bool Fit {
get { return Width == Measure.Fit && Height == Measure.Fit ? true : false; }
set {
@@ -482,7 +604,7 @@ namespace Crow
/// Width of this control, by default inherited from parent. May have special values
/// such as Stretched or Fit. It may be proportionnal or absolute.
/// </summary>
- [XmlAttributeAttribute()][DefaultValue("Inherit")]
+ [DesignCategory ("Layout")][DefaultValue("Inherit")]
public virtual Measure Width {
get {
return width.Units == Unit.Inherit ?
@@ -496,23 +618,24 @@ namespace Crow
if (value < MinimumSize.Width || (value > MaximumSize.Width && MaximumSize.Width > 0))
return;
}
- Measure lastWP = WidthPolicy;
+ Measure old = width;
width = value;
NotifyValueChanged ("Width", width);
- if (WidthPolicy != lastWP) {
- NotifyValueChanged ("WidthPolicy", WidthPolicy);
+ if (width == Measure.Stretched || old == Measure.Stretched) {
+ //NotifyValueChanged ("WidthPolicy", width.Policy);
//contentSize in Stacks are only update on childLayoutChange, and the single stretched
//child of the stack is not counted in contentSize, so when changing size policy of a child
//we should adapt contentSize
//TODO:check case when child become stretched, and another stretched item already exists.
- if (parent is GenericStack) {//TODO:check if I should test Group instead
- if ((parent as GenericStack).Orientation == Orientation.Horizontal) {
- if (lastWP == Measure.Fit)
- (parent as GenericStack).contentSize.Width -= this.LastSlots.Width;
+ GenericStack gs = Parent as GenericStack;
+ if (gs != null){ //TODO:check if I should test Group instead
+ if (gs.Orientation == Orientation.Horizontal) {
+ if (width == Measure.Stretched)
+ gs.contentSize.Width -= this.LastSlots.Width;
else
- (parent as GenericStack).contentSize.Width += this.LastSlots.Width;
+ gs.contentSize.Width += this.LastSlots.Width;
}
- }
+ }
}
this.RegisterForLayouting (LayoutingType.Width);
@@ -522,7 +645,7 @@ namespace Crow
/// Height of this control, by default inherited from parent. May have special values
/// such as Stretched or Fit. It may be proportionnal or absolute.
/// </summary>
- [XmlAttributeAttribute()][DefaultValue("Inherit")]
+ [DesignCategory ("Layout")][DefaultValue("Inherit")]
public virtual Measure Height {
get {
return height.Units == Unit.Inherit ?
@@ -536,17 +659,18 @@ namespace Crow
if (value < MinimumSize.Height || (value > MaximumSize.Height && MaximumSize.Height > 0))
return;
}
- Measure lastHP = HeightPolicy;
+ Measure old = height;
height = value;
NotifyValueChanged ("Height", height);
- if (HeightPolicy != lastHP) {
- NotifyValueChanged ("HeightPolicy", HeightPolicy);
- if (parent is GenericStack) {
- if ((parent as GenericStack).Orientation == Orientation.Vertical) {
- if (lastHP == Measure.Fit)
- (parent as GenericStack).contentSize.Height -= this.LastSlots.Height;
+ if (height == Measure.Stretched || old == Measure.Stretched) {
+ //NotifyValueChanged ("HeightPolicy", HeightPolicy);
+ GenericStack gs = Parent as GenericStack;
+ if (gs != null){ //TODO:check if I should test Group instead
+ if (gs.Orientation == Orientation.Vertical) {
+ if (height == Measure.Stretched)
+ gs.contentSize.Height -= this.LastSlots.Height;
else
- (parent as GenericStack).contentSize.Height += this.LastSlots.Height;
+ gs.contentSize.Height += this.LastSlots.Height;
}
}
}
@@ -555,13 +679,13 @@ namespace Crow
}
}
/// <summary>
- /// Used for binding on dimensions, this property will never hold fixed size, but instead only
+ /// Was Used for binding on dimensions, this property will never hold fixed size, but instead only
/// Fit or Stretched, **with inherited state implementation, it is not longer used in binding**
/// </summary>
[XmlIgnore]public virtual Measure WidthPolicy { get {
return Width.IsFit ? Measure.Fit : Measure.Stretched; } }
/// <summary>
- /// Used for binding on dimensions, this property will never hold fixed size, but instead only
+ /// Was Used for binding on dimensions, this property will never hold fixed size, but instead only
/// Fit or Stretched, **with inherited state implementation, it is not longer used in binding**
/// </summary>
[XmlIgnore]public virtual Measure HeightPolicy { get {
@@ -570,7 +694,7 @@ namespace Crow
/// Indicate that this object may received focus or not, if not focusable all the descendants are
/// affected.
/// </summary>
- [XmlAttributeAttribute()][DefaultValue(false)]
+ [DesignCategory ("Behaviour")][DefaultValue(false)]
public virtual bool Focusable {
get { return focusable; }
set {
@@ -612,9 +736,28 @@ namespace Crow
}
}
/// <summary>
+ /// true if this control has the pointer hover
+ /// </summary>
+ [XmlIgnore]public virtual bool IsHover {
+ get { return isHover; }
+ set {
+ if (value == isHover)
+ return;
+
+ isHover = value;
+
+ if (isHover)
+ onHover (this, null);
+ else
+ onUnHover (this, null);
+
+ NotifyValueChanged ("IsHover", isHover);
+ }
+ }
+ /// <summary>
/// true if holding mouse button down should trigger multiple click events
/// </summary>
- [XmlAttributeAttribute()][DefaultValue(false)]
+ [DesignCategory ("Behaviour")][DefaultValue(false)]
public virtual bool MouseRepeat {
get { return mouseRepeat; }
set {
@@ -628,7 +771,7 @@ namespace Crow
/// <summary>
/// background fill of the control, maybe solid color, gradient, image, or svg
/// </summary>
- [XmlAttributeAttribute()][DefaultValue("Transparent")]
+ [DesignCategory ("Appearance")][DefaultValue("Transparent")]
public virtual Fill Background {
get { return background; }
set {
@@ -649,7 +792,7 @@ namespace Crow
/// <summary>
/// Foreground fill of the control, usage may be different among derived controls
/// </summary>
- [XmlAttributeAttribute()][DefaultValue("White")]
+ [DesignCategory ("Appearance")][DefaultValue("White")]
public virtual Fill Foreground {
get { return foreground; }
set {
@@ -663,7 +806,7 @@ namespace Crow
/// <summary>
/// Font being used in many controls, it is defined in the base GraphicObject class.
/// </summary>
- [XmlAttributeAttribute()][DefaultValue("sans,10")]
+ [DesignCategory ("Appearance")][DefaultValue("sans,10")]
public virtual Font Font {
get { return font; }
set {
@@ -677,7 +820,7 @@ namespace Crow
/// <summary>
/// to get rounded corners
/// </summary>
- [XmlAttributeAttribute()][DefaultValue(0.0)]
+ [DesignCategory ("Appearance")][DefaultValue(0.0)]
public virtual double CornerRadius {
get { return cornerRadius; }
set {
@@ -692,7 +835,7 @@ namespace Crow
/// This is a single integer for the 4 direction, a gap between the control and it's container,
/// by default it is filled with the background.
/// </summary>
- [XmlAttributeAttribute()][DefaultValue(0)]
+ [DesignCategory ("Layout")][DefaultValue(0)]
public virtual int Margin {
get { return margin; }
set {
@@ -706,7 +849,7 @@ namespace Crow
/// <summary>
/// set the visible state of the control, invisible controls does reserve space in the layouting system.
/// </summary>
- [XmlAttributeAttribute][DefaultValue(true)]
+ [DesignCategory ("Appearance")][DefaultValue(true)]
public virtual bool Visible {
get { return isVisible; }
set {
@@ -717,8 +860,8 @@ namespace Crow
RegisterForLayouting (LayoutingType.Sizing);
- //trigger a mouse to handle possible hover changes
- //CurrentInterface.ProcessMouseMove (CurrentInterface.Mouse.X, CurrentInterface.Mouse.Y);
+ if (!isVisible)
+ unshownPostActions ();
NotifyValueChanged ("Visible", isVisible);
}
@@ -727,7 +870,7 @@ namespace Crow
/// get or set the enabled state, disabling a control will affect focuability and
/// also it's rendering which will be grayed
/// </summary>
- [XmlAttributeAttribute][DefaultValue(true)]
+ [DesignCategory ("Behaviour")][DefaultValue(true)]
public virtual bool IsEnabled {
get { return isEnabled; }
set {
@@ -748,7 +891,7 @@ namespace Crow
/// <summary>
/// Minimal width and height for this control
/// </summary>
- [XmlAttributeAttribute()][DefaultValue("1,1")]
+ [DesignCategory ("Layout")][DefaultValue("1,1")]
public virtual Size MinimumSize {
get { return minimumSize; }
set {
@@ -764,7 +907,7 @@ namespace Crow
/// <summary>
/// Maximum width and height for this control, unlimited if null.
/// </summary>
- [XmlAttributeAttribute()][DefaultValue("0,0")]
+ [DesignCategory ("Layout")][DefaultValue("0,0")]
public virtual Size MaximumSize {
get { return maximumSize; }
set {
@@ -781,7 +924,7 @@ namespace Crow
/// Seek first logical tree upward if logicalParent is set, or seek graphic tree for
/// a not null dataSource that will be active for all descendants having dataSource=null
/// </summary>
- [XmlAttributeAttribute]
+ [DesignCategory ("Data")]
public virtual object DataSource {
set {
if (DataSource == value)
@@ -793,19 +936,36 @@ namespace Crow
if (dse.NewDataSource == dse.OldDataSource)
return;
-
- OnDataSourceChanged (this, dse);
-
- NotifyValueChanged ("DataSource", DataSource);
+ if (value != null)
+ rootDataLevel = true;
+
+ lock (IFace.LayoutMutex) {
+ OnDataSourceChanged (this, dse);
+ NotifyValueChanged ("DataSource", DataSource);
+ }
}
get {
- return dataSource == null ?
+ return rootDataLevel ? dataSource : dataSource == null ?
LogicalParent == null ? null :
LogicalParent is GraphicObject ? (LogicalParent as GraphicObject).DataSource : null :
dataSource;
}
}
+ /// <summary>
+ /// If true, rendering of GraphicObject is clipped inside client rectangle
+ /// </summary>
+ [DesignCategory ("Data")][DefaultValue(false)]
+ public virtual bool RootDataLevel {
+ get { return rootDataLevel; }
+ set {
+ if (rootDataLevel == value)
+ return;
+ rootDataLevel = value;
+ NotifyValueChanged ("RootDataLevel", rootDataLevel);
+ this.RegisterForRedraw ();
+ }
+ }
protected virtual void onLogicalParentDataSourceChanged(object sender, DataSourceChangeEventArgs e){
if (localDataSourceIsNull)
OnDataSourceChanged (this, e);
@@ -822,7 +982,7 @@ namespace Crow
/// <summary>
/// Style key to use for this control
/// </summary>
- [XmlAttributeAttribute]
+ [DesignCategory ("Appearance")]
public virtual string Style {
get { return style; }
set {
@@ -834,7 +994,7 @@ namespace Crow
NotifyValueChanged ("Style", style);
}
}
- [XmlAttributeAttribute]
+ [DesignCategory ("Divers")]
public virtual string Tooltip {
get { return tooltip; }
set {
@@ -844,7 +1004,7 @@ namespace Crow
NotifyValueChanged("Tooltip", tooltip);
}
}
- [XmlAttributeAttribute]
+ [DesignCategory ("Divers")]
public IList<Command> ContextCommands {
get { return contextCommands; }
set {
@@ -867,20 +1027,19 @@ namespace Crow
Type thisType = this.GetType ();
if (!string.IsNullOrEmpty (Style)) {
- if (CurrentInterface.DefaultValuesLoader.ContainsKey (Style)) {
- CurrentInterface.DefaultValuesLoader [Style] (this);
+ if (IFace.DefaultValuesLoader.ContainsKey (Style)) {
+ IFace.DefaultValuesLoader [Style] (this);
+ onInitialized (this, null);
return;
}
- } else {
- if (CurrentInterface.DefaultValuesLoader.ContainsKey (thisType.FullName)) {
- CurrentInterface.DefaultValuesLoader [thisType.FullName] (this);
- return;
- } else if (!CurrentInterface.Styling.ContainsKey (thisType.FullName)) {
- if (CurrentInterface.DefaultValuesLoader.ContainsKey (thisType.Name)) {
- CurrentInterface.DefaultValuesLoader [thisType.Name] (this);
- return;
- }
- }
+ } else if (IFace.DefaultValuesLoader.ContainsKey (thisType.FullName)) {
+ IFace.DefaultValuesLoader [thisType.FullName] (this);
+ onInitialized (this, null);
+ return;
+ } else if (IFace.DefaultValuesLoader.ContainsKey (thisType.Name)) {
+ IFace.DefaultValuesLoader [thisType.Name] (this);
+ onInitialized (this, null);
+ return;
}
List<Style> styling = new List<Style>();
@@ -892,17 +1051,17 @@ namespace Crow
// those files being placed in a Styles folder
string styleKey = Style;
if (!string.IsNullOrEmpty (Style)) {
- if (CurrentInterface.Styling.ContainsKey (Style)) {
- styling.Add (CurrentInterface.Styling [Style]);
+ if (IFace.Styling.ContainsKey (Style)) {
+ styling.Add (IFace.Styling [Style]);
}
}
- if (CurrentInterface.Styling.ContainsKey (thisType.FullName)) {
- styling.Add (CurrentInterface.Styling [thisType.FullName]);
+ if (IFace.Styling.ContainsKey (thisType.FullName)) {
+ styling.Add (IFace.Styling [thisType.FullName]);
if (string.IsNullOrEmpty (styleKey))
styleKey = thisType.FullName;
}
- if (CurrentInterface.Styling.ContainsKey (thisType.Name)) {
- styling.Add (CurrentInterface.Styling [thisType.Name]);
+ if (IFace.Styling.ContainsKey (thisType.Name)) {
+ styling.Add (IFace.Styling [thisType.Name]);
if (string.IsNullOrEmpty (styleKey))
styleKey = thisType.Name;
}
@@ -910,7 +1069,6 @@ namespace Crow
if (string.IsNullOrEmpty (styleKey))
styleKey = thisType.FullName;
-
//Reflexion being very slow compared to dyn method or delegates,
//I compile the initial values coded in the CustomAttribs of the class,
//all other instance of this type would not longer use reflexion to init properly
@@ -962,21 +1120,76 @@ namespace Crow
foreach (PropertyInfo pi in thisType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
if (pi.GetSetMethod () == null)
continue;
- object defaultValue;
- if (!getDefaultValue (pi, styling, out defaultValue))
+ XmlIgnoreAttribute xia = (XmlIgnoreAttribute)pi.GetCustomAttribute (typeof(XmlIgnoreAttribute));
+ if (xia != null)
continue;
+ object defaultValue;
+ string name = "";
+ XmlAttributeAttribute xaa = (XmlAttributeAttribute)pi.GetCustomAttribute (typeof(XmlAttributeAttribute));
+ if (xaa != null) {
+ if (string.IsNullOrEmpty (xaa.AttributeName))
+ name = pi.Name;
+ else
+ name = xaa.AttributeName;
+ }else
+ name = pi.Name;
+
+ int styleIndex = -1;
+ if (styling.Count > 0){
+ for (int i = 0; i < styling.Count; i++) {
+ if (styling[i].ContainsKey (name)){
+ styleIndex = i;
+ break;
+ }
+ }
+ }
+ if (styleIndex >= 0){
+ if (pi.PropertyType.IsEnum)//maybe should be in parser..
+ defaultValue = Enum.Parse(pi.PropertyType, (string)styling[styleIndex] [name], true);
+ else
+ defaultValue = styling[styleIndex] [name];
+
+ #if DESIGN_MODE
+ if (defaultValue != null){
+ FileLocation fl = styling[styleIndex].Locations[name];
+ il.Emit (OpCodes.Ldloc_0);
+ il.Emit (OpCodes.Ldstr, name);
+ il.Emit (OpCodes.Ldstr, fl.FilePath);
+ il.Emit (OpCodes.Ldc_I4, fl.Line);
+ il.Emit (OpCodes.Ldc_I4, fl.Column);
+ il.Emit (OpCodes.Call, miDesignAddDefLoc);
+
+ il.Emit (OpCodes.Ldloc_0);
+ il.Emit (OpCodes.Ldfld, typeof(GraphicObject).GetField("design_style_values"));
+ il.Emit (OpCodes.Ldstr, name);
+ il.Emit (OpCodes.Ldstr, defaultValue.ToString());
+ il.Emit (OpCodes.Call, CompilerServices.miDicStrStrAdd);
+ }
+ #endif
+
+ }else {
+ DefaultValueAttribute dv = (DefaultValueAttribute)pi.GetCustomAttribute (typeof (DefaultValueAttribute));
+ if (dv == null)
+ continue;
+ defaultValue = dv.Value;
+ }
+
CompilerServices.EmitSetValue (il, pi, defaultValue);
}
il.Emit(OpCodes.Ret);
#endregion
try {
- CurrentInterface.DefaultValuesLoader[styleKey] = (Interface.LoaderInvoker)dm.CreateDelegate(typeof(Interface.LoaderInvoker));
- CurrentInterface.DefaultValuesLoader[styleKey] (this);
+ IFace.DefaultValuesLoader[styleKey] = (Interface.LoaderInvoker)dm.CreateDelegate(typeof(Interface.LoaderInvoker));
+ IFace.DefaultValuesLoader[styleKey] (this);
} catch (Exception ex) {
throw new Exception ("Error applying style <" + styleKey + ">:", ex);
}
+ onInitialized (this, null);
+ }
+ protected virtual void onInitialized (object sender, EventArgs e){
+ Initialized.Raise(sender, e);
}
bool getDefaultEvent(EventInfo ei, List<Style> styling,
out string expression){
@@ -991,51 +1204,6 @@ namespace Crow
}
return false;
}
- /// <summary>
- /// Gets the default value of the widget's property from either the style, or from xml default
- /// </summary>
- /// <returns><c>true</c>, if default value is defined, <c>false</c> otherwise.</returns>
- /// <param name="pi">PropertyInfo</param>
- /// <param name="styling">Styling informations</param>
- /// <param name="defaultValue">output of Default value, null if not found</param>
- bool getDefaultValue(PropertyInfo pi, List<Style> styling,
- out object defaultValue){
- defaultValue = null;
- string name = "";
-
- XmlIgnoreAttribute xia = (XmlIgnoreAttribute)pi.GetCustomAttribute (typeof(XmlIgnoreAttribute));
- if (xia != null)
- return false;
- XmlAttributeAttribute xaa = (XmlAttributeAttribute)pi.GetCustomAttribute (typeof(XmlAttributeAttribute));
- if (xaa != null) {
- if (string.IsNullOrEmpty (xaa.AttributeName))
- name = pi.Name;
- else
- name = xaa.AttributeName;
- }
-
- int styleIndex = -1;
- if (styling.Count > 0){
- for (int i = 0; i < styling.Count; i++) {
- if (styling[i].ContainsKey (name)){
- styleIndex = i;
- break;
- }
- }
- }
- if (styleIndex >= 0){
- if (pi.PropertyType.IsEnum)//maybe should be in parser..
- defaultValue = Enum.Parse(pi.PropertyType, (string)styling[styleIndex] [name], true);
- else
- defaultValue = styling[styleIndex] [name];
- }else {
- DefaultValueAttribute dv = (DefaultValueAttribute)pi.GetCustomAttribute (typeof (DefaultValueAttribute));
- if (dv == null)
- return false;
- defaultValue = dv.Value;
- }
- return true;
- }
#endregion
public virtual GraphicObject FindByName(string nameToFind){
@@ -1060,7 +1228,7 @@ namespace Crow
}
#region Drag&Drop
- [XmlAttributeAttribute][DefaultValue(false)]
+ [DesignCategory ("DragAndDrop")][DefaultValue(false)]
public virtual bool AllowDrag {
get { return allowDrag; }
set {
@@ -1070,7 +1238,7 @@ namespace Crow
NotifyValueChanged ("AllowDrag", allowDrag);
}
}
- [XmlAttributeAttribute][DefaultValue(false)]
+ [DesignCategory ("DragAndDrop")][DefaultValue(false)]
public virtual bool AllowDrop {
get { return allowDrop; }
set {
@@ -1105,10 +1273,12 @@ namespace Crow
/// fired when drag and drop operation start
/// </summary>
protected virtual void onStartDrag (object sender, DragDropEventArgs e){
- CurrentInterface.HoverWidget = null;
+ IFace.HoverWidget = null;
IsDragged = true;
StartDrag.Raise (this, e);
+ #if DEBUG_DRAGNDROP
Debug.WriteLine(this.ToString() + " : START DRAG => " + e.ToString());
+ #endif
}
/// <summary>
/// Occured when dragging ends without dropping
@@ -1116,22 +1286,34 @@ namespace Crow
protected virtual void onEndDrag (object sender, DragDropEventArgs e){
IsDragged = false;
EndDrag.Raise (this, e);
+ #if DEBUG_DRAGNDROP
Debug.WriteLine(this.ToString() + " : END DRAG => " + e.ToString());
+ #endif
}
protected virtual void onDragEnter (object sender, DragDropEventArgs e){
e.DropTarget = this;
DragEnter.Raise (this, e);
+ #if DEBUG_DRAGNDROP
Debug.WriteLine(this.ToString() + " : DRAG Enter => " + e.ToString());
+ #endif
}
protected virtual void onDragLeave (object sender, DragDropEventArgs e){
e.DropTarget = null;
DragLeave.Raise (this, e);
+ #if DEBUG_DRAGNDROP
Debug.WriteLine(this.ToString() + " : DRAG Leave => " + e.ToString());
+ #endif
}
protected virtual void onDrop (object sender, DragDropEventArgs e){
IsDragged = false;
Drop.Raise (this, e);
+ //e.DropTarget.onDragLeave (this, e);//raise drag leave in target
+ #if DEBUG_DRAGNDROP
Debug.WriteLine(this.ToString() + " : DROP => " + e.ToString());
+ #endif
+ }
+ public bool IsDropTarget {
+ get { return IFace.DragAndDropOperation?.DropTarget == this; }
}
#endregion
@@ -1180,7 +1362,7 @@ namespace Crow
if (Width.IsFit || Height.IsFit)
RegisterForLayouting (LayoutingType.Sizing);
else if (RegisteredLayoutings == LayoutingType.None)
- CurrentInterface.EnqueueForRepaint (this);
+ IFace.EnqueueForRepaint (this);
}
/// <summary> query an update of the content, a redraw </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -1191,7 +1373,7 @@ namespace Crow
#endif
IsDirty = true;
if (RegisteredLayoutings == LayoutingType.None)
- CurrentInterface.EnqueueForRepaint (this);
+ IFace.EnqueueForRepaint (this);
}
#endregion
@@ -1209,7 +1391,7 @@ namespace Crow
public virtual void RegisterForLayouting(LayoutingType layoutType){
if (Parent == null)
return;
- lock (CurrentInterface.LayoutMutex) {
+ lock (IFace.LayoutMutex) {
//prevent queueing same LayoutingType for this
layoutType &= (~RegisteredLayoutings);
@@ -1236,27 +1418,21 @@ namespace Crow
//enqueue LQI LayoutingTypes separately
if (layoutType.HasFlag (LayoutingType.Width))
- CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this));
+ IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this));
if (layoutType.HasFlag (LayoutingType.Height))
- CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this));
+ IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this));
if (layoutType.HasFlag (LayoutingType.X))
- CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this));
+ IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this));
if (layoutType.HasFlag (LayoutingType.Y))
- CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this));
+ IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this));
if (layoutType.HasFlag (LayoutingType.ArrangeChildren))
- CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this));
+ IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this));
}
}
/// <summary> trigger dependant sizing component update </summary>
public virtual void OnLayoutChanges(LayoutingType layoutType)
{
- #if DEBUG_LAYOUTING
- CurrentInterface.currentLQI.Slot = LastSlots;
- CurrentInterface.currentLQI.NewSlot = Slot;
- Debug.WriteLine ("\t\t{0} => {1}",LastSlots,Slot);
- #endif
-
switch (layoutType) {
case LayoutingType.Width:
RegisterForLayouting (LayoutingType.X);
@@ -1420,7 +1596,7 @@ namespace Crow
//if no layouting remains in queue for item, registre for redraw
if (this.registeredLayoutings == LayoutingType.None && IsDirty)
- CurrentInterface.EnqueueForRepaint (this);
+ IFace.EnqueueForRepaint (this);
return true;
}
@@ -1557,8 +1733,8 @@ namespace Crow
}
public virtual void checkHoverWidget(MouseMoveEventArgs e)
{
- if (CurrentInterface.HoverWidget != this) {
- CurrentInterface.HoverWidget = this;
+ if (IFace.HoverWidget != this) {
+ IFace.HoverWidget = this;
onMouseEnter (this, e);
}
@@ -1567,12 +1743,17 @@ namespace Crow
public virtual void onMouseMove(object sender, MouseMoveEventArgs e)
{
if (AllowDrag & HasFocus & e.Mouse.LeftButton == ButtonState.Pressed) {
- if (CurrentInterface.DragAndDropOperation == null) {
- CurrentInterface.DragAndDropOperation = new DragDropEventArgs (this);
- onStartDrag (this, CurrentInterface.DragAndDropOperation);
+ if (IFace.DragAndDropOperation == null) {
+ IFace.DragAndDropOperation = new DragDropEventArgs (this);
+ onStartDrag (this, IFace.DragAndDropOperation);
}
}
+ //dont bubble event if dragged, mouse move is routed directely from iface
+ //to let other control behind have mouse entering
+ if (isDragged)
+ return;
+
//bubble event to the top
GraphicObject p = focusParent;
if (p != null)
@@ -1585,15 +1766,15 @@ namespace Crow
Debug.WriteLine("MOUSE DOWN => " + this.ToString());
#endif
- if (CurrentInterface.ActiveWidget == null)
- CurrentInterface.ActiveWidget = this;
+ if (IFace.ActiveWidget == null)
+ IFace.ActiveWidget = this;
if (this.Focusable && !Interface.FocusOnHover) {
BubblingMouseButtonEventArg be = e as BubblingMouseButtonEventArg;
if (be.Focused == null) {
be.Focused = this;
- CurrentInterface.FocusedWidget = this;
+ IFace.FocusedWidget = this;
if (e.Button == MouseButton.Right && this.ContextCommands != null)
- CurrentInterface.ShowContextMenu (this);
+ IFace.ShowContextMenu (this);
}
}
//bubble event to the top
@@ -1608,13 +1789,13 @@ namespace Crow
Debug.WriteLine("MOUSE UP => " + this.ToString());
#endif
- if (CurrentInterface.DragAndDropOperation != null){
- if (CurrentInterface.DragAndDropOperation.DragSource == this) {
- if (CurrentInterface.DragAndDropOperation.DropTarget != null)
- onDrop (this, CurrentInterface.DragAndDropOperation);
+ if (IFace.DragAndDropOperation != null){
+ if (IFace.DragAndDropOperation.DragSource == this) {
+ if (IFace.DragAndDropOperation.DropTarget != null)
+ onDrop (this, IFace.DragAndDropOperation);
else
- onEndDrag (this, CurrentInterface.DragAndDropOperation);
- CurrentInterface.DragAndDropOperation = null;
+ onEndDrag (this, IFace.DragAndDropOperation);
+ IFace.DragAndDropOperation = null;
}
}
@@ -1655,14 +1836,6 @@ namespace Crow
#if DEBUG_FOCUS
Debug.WriteLine("MouseEnter => " + this.ToString());
#endif
-
- if (CurrentInterface.DragAndDropOperation != null) {
- if (this.AllowDrop) {
- if (CurrentInterface.DragAndDropOperation.DragSource != this && CurrentInterface.DragAndDropOperation.DropTarget != this)
- onDragEnter (this, CurrentInterface.DragAndDropOperation);
- }
- }
-
MouseEnter.Raise (this, e);
}
public virtual void onMouseLeave(object sender, MouseMoveEventArgs e)
@@ -1670,12 +1843,36 @@ namespace Crow
#if DEBUG_FOCUS
Debug.WriteLine("MouseLeave => " + this.ToString());
#endif
- if (CurrentInterface.DragAndDropOperation != null) {
- if (CurrentInterface.DragAndDropOperation.DropTarget == this)
- onDragLeave (this, CurrentInterface.DragAndDropOperation);
- }
MouseLeave.Raise (this, e);
}
+ public virtual void onHover(object sender, EventArgs e)
+ {
+ #if DEBUG_FOCUS
+ Debug.WriteLine("MouseHover => " + this.ToString());
+ #endif
+ if (IFace.DragAndDropOperation != null) {
+ GraphicObject g = this;
+ while (g != null) {
+ if (g.AllowDrop) {
+ if (IFace.DragAndDropOperation.DragSource != this && IFace.DragAndDropOperation.DropTarget != this) {
+ if (IFace.DragAndDropOperation.DropTarget != null)
+ IFace.DragAndDropOperation.DropTarget.onDragLeave (this, IFace.DragAndDropOperation);
+ g.onDragEnter (this, IFace.DragAndDropOperation);
+ }
+ break;
+ }
+ g = g.focusParent;
+ }
+ }
+ Hover.Raise (this, e);
+ }
+ public virtual void onUnHover(object sender, EventArgs e)
+ {
+ #if DEBUG_FOCUS
+ Debug.WriteLine("MouseUnHover => " + this.ToString());
+ #endif
+ UnHover.Raise (this, e);
+ }
#endregion
protected virtual void onFocused(object sender, EventArgs e){
@@ -1697,6 +1894,13 @@ namespace Crow
Disabled.Raise (this, e);
}
protected virtual void onParentChanged(object sender, DataSourceChangeEventArgs e) {
+// if (e.NewDataSource != null) {
+// if (width == Measure.Inherit)
+// RegisterForLayouting (LayoutingType.Width);
+// if (height == Measure.Inherit)
+// RegisterForLayouting (LayoutingType.Height);
+// }
+
ParentChanged.Raise (this, e);
if (logicalParent == null)
LogicalParentChanged.Raise (this, e);
@@ -1732,5 +1936,24 @@ namespace Crow
return Name == "unamed" ? tmp + "." + this.GetType ().Name : tmp + "." + Name;
#endif
}
+ /// <summary>
+ /// Checks to handle when widget is removed from the visible graphic tree
+ /// </summary>
+ void unshownPostActions () {
+ if (IFace.ActiveWidget != null) {
+ if (IFace.ActiveWidget.IsOrIsInside (this))
+ IFace.ActiveWidget = null;
+ }
+ if (IFace.FocusedWidget != null) {
+ if (IFace.FocusedWidget.IsOrIsInside (this))
+ IFace.FocusedWidget = null;
+ }
+ if (IFace.HoverWidget != null) {
+ if (IFace.HoverWidget.IsOrIsInside (this)) {
+ IFace.HoverWidget = null;
+ IFace.ProcessMouseMove (IFace.Mouse.X, IFace.Mouse.Y);
+ }
+ }
+ }
}
}