Type t = instance.GetType ();
FieldInfo fiEvt = getEventHandlerField (t, eventName);
if (fiEvt == null) {
+ #if DEBUG_BINDING
Debug.WriteLine ("RemoveHandlerByName: Event '" + eventName + "' not found in " + instance);
+ #endif
return;
}
EventInfo eiEvt = t.GetEvent (eventName);
/// Thread monitored by current interface with Finished event when state==Stopped
/// </summary>
public class CrowThread {
+ public bool cancel = false;
Thread thread;
public event EventHandler Finished;
public GraphicObject Host;
public void Start() { thread.Start();}
public void Cancel(){
if (thread.IsAlive){
+ cancel = true;
//cancelLoading = true;
thread.Join ();
//cancelLoading = false;
namespace Crow
{
- public class GraphicObject : ILayoutable, IValueChange
+ public class GraphicObject : ILayoutable, IValueChange, IDisposable
{
+ #region IDisposable implementation
+
+ public virtual void Dispose ()
+ {
+ #if DEBUG_DISPOSE
+ Debug.WriteLine ("{0} Disposed", this.ToString());
+ #endif
+
+ parent = null;
+ if (IsQueueForRedraw)
+ Debugger.Break ();
+ if (!localDataSourceIsNull)
+ DataSource = null;
+ Clipping?.Dispose ();
+ bmp?.Dispose ();
+ }
+
+ #endregion
+
internal static ulong currentUid = 0;
internal ulong uid = 0;
public virtual bool Contains(GraphicObject goToFind){
return false;
}
+ /// <summary>
+ /// return true if this is contained inside go
+ /// </summary>
+ public bool IsInside(GraphicObject go){
+ ILayoutable p = this.Parent;
+ while (p != null) {
+ if (p == go)
+ return true;
+ p = p.Parent;
+ }
+ return false;
+ }
#region Queuing
/// <summary>
/// Register old and new slot for clipping
/// </summary>
public virtual void ClippingRegistration(){
+ #if DEBUG_UPDATE
+ Debug.WriteLine (string.Format("ClippingRegistration -> {0}", this.ToString ()));
+ #endif
IsQueueForRedraw = false;
if (Parent == null)
return;
/// </summary>
/// <param name="clip">Clip rectangle</param>
public virtual void RegisterClip(Rectangle clip){
+ #if DEBUG_UPDATE
+ Debug.WriteLine (string.Format("RegisterClip -> {1}:{0}", clip, this.ToString ()));
+ #endif
Rectangle r = clip + ClientRectangle.Position;
if (CacheEnabled && !IsDirty)
Clipping.UnionRectangle (r);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RegisterForGraphicUpdate ()
{
+ #if DEBUG_UPDATE
+ Debug.WriteLine (string.Format("RegisterForGraphicUpdate -> {0}", this.ToString ()));
+ #endif
IsDirty = true;
if (Width.IsFit || Height.IsFit)
RegisterForLayouting (LayoutingType.Sizing);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RegisterForRedraw ()
{
+ #if DEBUG_UPDATE
+ Debug.WriteLine (string.Format("RegisterForRedraw -> {0}", this.ToString ()));
+ #endif
IsDirty = true;
if (RegisteredLayoutings == LayoutingType.None)
currentInterface.EnqueueForRepaint (this);
/// this trigger the effective drawing routine </summary>
protected virtual void RecreateCache ()
{
+ #if DEBUG_UPDATE
+ Debug.WriteLine ("RecreateCache -> {0}", this.ToString ());
+ #endif
IsDirty = false;
if (bmp != null)
bmp.Dispose ();
bmp.Flush ();
}
protected virtual void UpdateCache(Context ctx){
+ #if DEBUG_UPDATE
+ Debug.WriteLine ("UpdateCache -> {0}", this.ToString ());
+ #endif
Rectangle rb = Slot + Parent.ClientRectangle.Position;
if (clearBackground) {
ctx.Save ();
/// of the widget </summary>
public virtual void Paint (ref Context ctx)
{
+ #if DEBUG_UPDATE
+ Debug.WriteLine (string.Format("Paint -> {0}", this.ToString ()));
+ #endif
//TODO:this test should not be necessary
if (Slot.Height < 0 || Slot.Width < 0 || parent == null)
return;
protected virtual void onLogicalParentChanged(object sender, DataSourceChangeEventArgs e) {
LogicalParentChanged.Raise (this, e);
}
-
+ internal void ClearTemplateBinding(){
+ #if DEBUG_UPDATE
+ Debug.WriteLine (string.Format("ClearTemplateBinding: {0}", this.ToString()));
+ #endif
+ if (ValueChanged == null)
+ return;
+ EventInfo eiEvt = this.GetType().GetEvent ("ValueChanged");
+ foreach (Delegate d in ValueChanged.GetInvocationList()) {
+ if (d.Method.Name == "dyn_tmpValueChanged") {
+ eiEvt.RemoveEventHandler (this, d);
+ #if DEBUG_BINDING
+ Debug.WriteLine ("\t{0} template binding handler removed in {1} for: {2}", d.Method.Name, this, "ValueChanged");
+ #endif
+ }
+ }
+ }
public override string ToString ()
{
string tmp ="";
public virtual void RemoveChild(GraphicObject child)
{
child.LayoutChanged -= OnChildLayoutChanges;
- //child.Parent = null;
+ child.Parent = null;
//check if HoverWidget is removed from Tree
if (currentInterface.HoverWidget != null) {
- if (this.Contains (currentInterface.HoverWidget))
+ if (currentInterface.HoverWidget.IsInside(this))
currentInterface.HoverWidget = null;
}
lock (children)
Children.Remove(child);
+ child.Dispose ();
if (child == largestChild && Width == Measure.Fit)
searchLargestChild ();
while (Children.Count > 0) {
GraphicObject g = Children [Children.Count - 1];
g.LayoutChanged -= OnChildLayoutChanges;
- g.Parent = null;
Children.RemoveAt (Children.Count - 1);
+ g.Dispose ();
}
}
base.checkHoverWidget (e);
}
#endregion
+
+ public override void Dispose ()
+ {
+ foreach (GraphicObject c in children)
+ c.Dispose ();
+ base.Dispose ();
+ }
}
}
if (child != null) {
//check if HoverWidget is removed from Tree
if (currentInterface.HoverWidget != null) {
- if (this.Contains (currentInterface.HoverWidget))
+ if (currentInterface.HoverWidget.IsInside(this))
currentInterface.HoverWidget = null;
}
contentSize = new Size (0, 0);
child.LayoutChanged -= OnChildLayoutChanges;
+ child.Dispose ();
child.Parent = null;
this.RegisterForGraphicUpdate ();
}
}
#endregion
+ public override void Dispose ()
+ {
+ if (child != null)
+ child.Dispose ();
+ base.Dispose ();
+ }
}
}
string _template;
string caption;
+ /// <summary>
+ /// Template path
+ /// </summary>
[XmlAttributeAttribute][DefaultValue(null)]
public string Template {
get { return _template; }
protected virtual void loadTemplate(GraphicObject template = null)
{
+ if (this.child != null)//template change, bindings has to be reset
+ this.ClearTemplateBinding();
+
if (template == null) {
if (!Interface.DefaultTemplates.ContainsKey (this.GetType ().FullName))
throw new Exception (string.Format ("No default template found for '{0}'", this.GetType ().FullName));
int itemPerPage = 50;
CrowThread loadingThread = null;
- volatile bool cancelLoading = false;
bool isPaged = false;
ItemTemplates ["default"] = Interface.GetItemTemplate (ItemTemplate);
for (int i = 1; i <= (data.Count / itemPerPage) + 1; i++) {
- if (cancelLoading)
+ if ((bool)loadingThread?.cancel)
return;
loadPage (i);
Thread.Sleep (1);
for (int i = (pageNum - 1) * itemPerPage; i < pageNum * itemPerPage; i++) {
if (i >= data.Count)
break;
- if (cancelLoading)
+ if ((bool)loadingThread?.cancel)
return;
loadItem (i, page);
internal virtual void itemClick(object sender, MouseButtonEventArgs e){
SelectedIndex = data.IndexOf((sender as GraphicObject).DataSource);
}
+
+ public override void Dispose ()
+ {
+ if (loadingThread != null)
+ loadingThread.Cancel ();
+ base.Dispose ();
+ }
}
}
public void DeleteWidget(GraphicObject g)
{
if (_hoverWidget != null) {
- if (g.Contains (_hoverWidget))
+ if (_hoverWidget.IsInside(g))
HoverWidget = null;
}
lock (UpdateMutex) {
- g.DataSource = null;
- g.Visible = false;
+ RegisterClip (g.ScreenCoordinates (g.LastPaintedSlot));
GraphicTree.Remove (g);
+ g.Parent = null;
+ g.Dispose ();
}
}
+ /// <summary> Remove all Graphic objects from top container </summary>
+ public void ClearInterface()
+ {
+ lock (UpdateMutex) {
+ while (GraphicTree.Count > 0) {
+ //TODO:parent is not reset to null because object will be added
+ //to ObjectToRedraw list, and without parent, it fails
+ GraphicObject g = GraphicTree [0];
+ if (_hoverWidget != null) {
+ if (_hoverWidget.IsInside(g))
+ HoverWidget = null;
+ }
+ RegisterClip (g.ScreenCoordinates (g.LastPaintedSlot));
+ GraphicTree.RemoveAt (0);
+ g.Dispose ();
+ }
+ }
+ #if DEBUG_LAYOUTING
+ LQIsTries = new List<LQIList>();
+ curLQIsTries = new LQIList();
+ LQIs = new List<LQIList>();
+ curLQIs = new LQIList();
+ #endif
+ }
/// <summary> Put widget on top of other root widgets</summary>
public void PutOnTop(GraphicObject g, bool isOverlay = false)
{
EnqueueForRepaint (g);
}
}
- /// <summary> Remove all Graphic objects from top container </summary>
- public void ClearInterface()
- {
- lock (UpdateMutex) {
- while (GraphicTree.Count > 0) {
- //TODO:parent is not reset to null because object will be added
- //to ObjectToRedraw list, and without parent, it fails
- GraphicObject g = GraphicTree [0];
- g.DataSource = null;
- g.Visible = false;
- GraphicTree.RemoveAt (0);
- }
- }
- #if DEBUG_LAYOUTING
- LQIsTries = new List<LQIList>();
- curLQIsTries = new LQIList();
- LQIs = new List<LQIList>();
- curLQIs = new LQIList();
- #endif
- }
/// <summary>Search a Graphic object in the tree named 'nameToFind'</summary>
public GraphicObject FindByName (string nameToFind)