Add databinding support to ScrollPanelWidget
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using OpenRA.FileFormats.Primitives;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
|
|
||||||
namespace OpenRA.Widgets
|
namespace OpenRA.Widgets
|
||||||
@@ -45,6 +46,7 @@ namespace OpenRA.Widgets
|
|||||||
base.RemoveChildren();
|
base.RemoveChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void AddChild(Widget child)
|
public override void AddChild(Widget child)
|
||||||
{
|
{
|
||||||
// Initial setup of margins/height
|
// Initial setup of margins/height
|
||||||
@@ -61,7 +63,6 @@ namespace OpenRA.Widgets
|
|||||||
|
|
||||||
public void ReplaceChild(Widget oldChild, Widget newChild)
|
public void ReplaceChild(Widget oldChild, Widget newChild)
|
||||||
{
|
{
|
||||||
|
|
||||||
oldChild.Removed();
|
oldChild.Removed();
|
||||||
newChild.Parent = this;
|
newChild.Parent = this;
|
||||||
Children[Children.IndexOf(oldChild)] = newChild;
|
Children[Children.IndexOf(oldChild)] = newChild;
|
||||||
@@ -69,8 +70,6 @@ namespace OpenRA.Widgets
|
|||||||
Scroll(0);
|
Scroll(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public override void DrawOuter()
|
public override void DrawOuter()
|
||||||
{
|
{
|
||||||
if (!IsVisible())
|
if (!IsVisible())
|
||||||
@@ -145,6 +144,11 @@ namespace OpenRA.Widgets
|
|||||||
ListOffset = 0;
|
ListOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool ScrolledToBottom
|
||||||
|
{
|
||||||
|
get { return ListOffset == Math.Min(0, Bounds.Height - ContentHeight); }
|
||||||
|
}
|
||||||
|
|
||||||
public void ScrollToItem(string itemKey)
|
public void ScrollToItem(string itemKey)
|
||||||
{
|
{
|
||||||
var item = Children.FirstOrDefault(c =>
|
var item = Children.FirstOrDefault(c =>
|
||||||
@@ -226,5 +230,116 @@ namespace OpenRA.Widgets
|
|||||||
|
|
||||||
return UpPressed || DownPressed || ThumbPressed;
|
return UpPressed || DownPressed || ThumbPressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IObservableCollection collection;
|
||||||
|
Func<object, Widget> makeWidget;
|
||||||
|
Func<Widget, object, bool> widgetItemEquals;
|
||||||
|
bool autoScroll;
|
||||||
|
|
||||||
|
public void Unbind()
|
||||||
|
{
|
||||||
|
Bind(null, null, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Bind(IObservableCollection c, Func<object, Widget> makeWidget, Func<Widget, object, bool> widgetItemEquals, bool autoScroll)
|
||||||
|
{
|
||||||
|
this.autoScroll = autoScroll;
|
||||||
|
|
||||||
|
Game.RunAfterTick(() =>
|
||||||
|
{
|
||||||
|
if (collection != null)
|
||||||
|
{
|
||||||
|
collection.OnAdd -= BindingAdd;
|
||||||
|
collection.OnRemove -= BindingRemove;
|
||||||
|
collection.OnRemoveAt -= BindingRemoveAt;
|
||||||
|
collection.OnSet -= BindingSet;
|
||||||
|
collection.OnRefresh -= BindingRefresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.makeWidget = makeWidget;
|
||||||
|
this.widgetItemEquals = widgetItemEquals;
|
||||||
|
|
||||||
|
RemoveChildren();
|
||||||
|
collection = c;
|
||||||
|
|
||||||
|
if (c != null)
|
||||||
|
{
|
||||||
|
foreach (var item in c.ObservedItems)
|
||||||
|
BindingAddImpl(item);
|
||||||
|
|
||||||
|
c.OnAdd += BindingAdd;
|
||||||
|
c.OnRemove += BindingRemove;
|
||||||
|
c.OnRemoveAt += BindingRemoveAt;
|
||||||
|
c.OnSet += BindingSet;
|
||||||
|
c.OnRefresh += BindingRefresh;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingAdd(object item)
|
||||||
|
{
|
||||||
|
Game.RunAfterTick(() => BindingAddImpl(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingAddImpl(object item)
|
||||||
|
{
|
||||||
|
var widget = makeWidget(item);
|
||||||
|
var scrollToBottom = autoScroll && ScrolledToBottom;
|
||||||
|
|
||||||
|
AddChild(widget);
|
||||||
|
|
||||||
|
if (scrollToBottom)
|
||||||
|
ScrollToBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingRemove(object item)
|
||||||
|
{
|
||||||
|
Game.RunAfterTick(() =>
|
||||||
|
{
|
||||||
|
var widget = Children.FirstOrDefault(w => widgetItemEquals(w, item));
|
||||||
|
if (widget != null)
|
||||||
|
RemoveChild(widget);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingRemoveAt(int index)
|
||||||
|
{
|
||||||
|
Game.RunAfterTick(() =>
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= Children.Count)
|
||||||
|
return;
|
||||||
|
RemoveChild(Children[index]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingSet(object oldItem, object newItem)
|
||||||
|
{
|
||||||
|
Game.RunAfterTick(() =>
|
||||||
|
{
|
||||||
|
var newWidget = makeWidget(newItem);
|
||||||
|
newWidget.Parent = this;
|
||||||
|
|
||||||
|
var i = Children.FindIndex(w => widgetItemEquals(w, oldItem));
|
||||||
|
if (i >= 0)
|
||||||
|
{
|
||||||
|
var oldWidget = Children[i];
|
||||||
|
oldWidget.Removed();
|
||||||
|
Children[i] = newWidget;
|
||||||
|
Layout.AdjustChildren();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
AddChild(newWidget);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingRefresh()
|
||||||
|
{
|
||||||
|
Game.RunAfterTick(() =>
|
||||||
|
{
|
||||||
|
RemoveChildren();
|
||||||
|
foreach (var item in collection.ObservedItems)
|
||||||
|
BindingAddImpl(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user