diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
index e95a424..e9e4b33 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
@@ -226,6 +226,9 @@
Component
+
+ Component
+
Component
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KComboBox.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KComboBox.cs
index 3f14873..309b49c 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KComboBox.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KComboBox.cs
@@ -28,12 +28,22 @@ namespace Acacia.Controls
private readonly KComboBox _owner;
private int _committedIndex = -1;
- public DropList(KComboBox owner)
+ public DropList(KComboBox owner, bool ownerDraw)
{
this._owner = owner;
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.Selectable, false);
BorderStyle = BorderStyle.None;
+
+ if (ownerDraw)
+ {
+ DrawMode = DrawMode.OwnerDrawFixed;
+ }
+ }
+
+ protected override void OnDrawItem(DrawItemEventArgs e)
+ {
+ _owner.OnDrawItem(e);
}
protected override void OnMouseMove(MouseEventArgs e)
@@ -98,7 +108,6 @@ namespace Acacia.Controls
public void ItemsChanged(int selectIndex)
{
_committedIndex = SelectedIndex = selectIndex;
-
}
}
@@ -127,10 +136,14 @@ namespace Acacia.Controls
private DisplayItem _selectedItem;
- public KComboBox()
+ public KComboBox() : this(false)
{
+ }
+
+ protected internal KComboBox(bool ownerDraw)
+ {
MaxDropDownItems = 8;
- _list = new DropList(this);
+ _list = new DropList(this, ownerDraw);
_list.IntegralHeight = true;
_list.TabStop = false;
_list.SelectedIndexChanged += _list_SelectedIndexChanged;
@@ -164,31 +177,30 @@ namespace Acacia.Controls
///
/// Wrapper for list items to use custom string formatting
///
- private class DisplayItem
+ public class DisplayItem
{
private readonly KComboBox _owner;
- private readonly object _item;
+ public readonly object Item;
public DisplayItem(KComboBox owner, object item)
{
this._owner = owner;
- this._item = item;
+ this.Item = item;
}
public override string ToString()
{
- return _owner.DataSource.GetItemText(_item);
+ return _owner.DataSource.GetItemText(Item);
}
public override bool Equals(object obj)
{
- bool result = obj is DisplayItem && ((DisplayItem)obj)._item == _item;
- return result;
+ return obj is DisplayItem && ((DisplayItem)obj).Item == Item;
}
public override int GetHashCode()
{
- return ToString().GetHashCode();
+ return Item.GetHashCode();
}
}
@@ -226,12 +238,46 @@ namespace Acacia.Controls
// Select the current item only if new number of items is smaller. This means we don't keep selection
// when the user is removing text, only when they are typing more.
_list.ItemsChanged(_list.Items.Count < oldCount ? selected : -1);
+
+ MeasureItems();
+ UpdateDropDownLayout();
}
finally
{
_list.EndUpdate();
}
- UpdateDropDownLayout();
+ }
+
+ protected IEnumerable DisplayItems
+ {
+ get
+ {
+ foreach (object item in _list.Items)
+ yield return (DisplayItem)item;
+ }
+ }
+
+ protected DisplayItem GetDisplayItem(int index)
+ {
+ return (DisplayItem)_list.Items[index];
+ }
+
+ protected int DisplayItemCount
+ {
+ get { return _list.Items.Count; }
+ }
+
+ virtual protected void OnDrawItem(DrawItemEventArgs e) { }
+
+ protected virtual void MeasureItems()
+ {
+ // Virtual placeholder
+ }
+
+ protected void SetItemSize(Size size)
+ {
+ ItemHeight = size.Height;
+ _list.Width = size.Width;
}
protected override void OnTextChanged(EventArgs e)
@@ -265,6 +311,10 @@ namespace Acacia.Controls
// Forward cursor keys to the list
case Keys.Down:
case Keys.Up:
+ case Keys.PageDown:
+ case Keys.PageUp:
+ case Keys.Home:
+ case Keys.End:
User32.SendMessage(_list.Handle, (int)WM.KEYDOWN, new IntPtr((int)e.KeyCode), IntPtr.Zero);
e.IsInputKey = true;
break;
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KComboBoxCustomDraw.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KComboBoxCustomDraw.cs
new file mode 100644
index 0000000..cb15187
--- /dev/null
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KComboBoxCustomDraw.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Acacia.Controls
+{
+ abstract public class KComboBoxCustomDraw : KComboBox
+ {
+ public class MeasureItemEventArgs : EventArgs
+ {
+ public readonly Graphics Graphics;
+ public readonly DisplayItem DisplayItem;
+ public object Item { get { return DisplayItem.Item; } }
+ public int ItemWidth { get; set; }
+ public int ItemHeight { get; set; }
+
+ public MeasureItemEventArgs(Graphics graphics, DisplayItem item)
+ {
+ this.Graphics = graphics;
+ this.DisplayItem = item;
+ }
+ }
+
+ public class DrawItemEventArgs : System.Windows.Forms.DrawItemEventArgs
+ {
+ public readonly DisplayItem DisplayItem;
+
+ public object Item { get { return DisplayItem.Item; } }
+
+ public DrawItemEventArgs(System.Windows.Forms.DrawItemEventArgs e, DisplayItem item)
+ :
+ base(e.Graphics, e.Font, e.Bounds, e.Index, e.State, e.ForeColor, e.BackColor)
+ {
+ DisplayItem = item;
+ }
+
+ }
+
+ public KComboBoxCustomDraw() : base(true)
+ {
+ }
+
+ sealed protected override void OnDrawItem(System.Windows.Forms.DrawItemEventArgs e)
+ {
+ OnDrawItem(new DrawItemEventArgs(e, GetDisplayItem(e.Index)));
+ }
+
+ abstract protected void OnDrawItem(DrawItemEventArgs e);
+
+ protected abstract void OnMeasureItem(MeasureItemEventArgs e);
+
+ private readonly Dictionary _sizeCache = new Dictionary();
+
+ protected override void MeasureItems()
+ {
+ int maxWidth = 0, maxHeight = 0;
+ using (Graphics graphics = CreateGraphics())
+ {
+ foreach (DisplayItem item in DisplayItems)
+ {
+ Size s;
+ if (!_sizeCache.TryGetValue(item, out s))
+ {
+ MeasureItemEventArgs e = new MeasureItemEventArgs(graphics, item);
+ OnMeasureItem(e);
+ s = new Size(e.ItemWidth, e.ItemHeight);
+ _sizeCache.Add(item, s);
+ }
+
+ maxWidth = Math.Max(maxWidth, s.Width);
+ maxHeight = Math.Max(maxHeight, s.Height);
+ }
+ }
+
+ if (maxHeight > 0)
+ {
+ SetItemSize(new Size(maxWidth, maxHeight));
+ }
+ }
+ }
+}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KUIUtil.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KUIUtil.cs
index 2e4d15f..07ad8be 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KUIUtil.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KUIUtil.cs
@@ -24,7 +24,7 @@ using System.Windows.Forms;
namespace Acacia.Controls
{
- internal static class KUIUtil
+ public static class KUIUtil
{
#region Geometry
@@ -126,6 +126,11 @@ namespace Acacia.Controls
return r;
}
+ public static Point TopLeft(this Rectangle _this)
+ {
+ return new Point(_this.Left, _this.Top);
+ }
+
#endregion
}
}