|
@@ -1,6 +1,7 @@
|
|
using System;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Drawing;
|
|
|
|
+using System.Linq;
|
|
using System.Windows.Forms;
|
|
using System.Windows.Forms;
|
|
|
|
|
|
namespace NTERA.Console
|
|
namespace NTERA.Console
|
|
@@ -9,7 +10,9 @@ namespace NTERA.Console
|
|
{
|
|
{
|
|
public int LineHeight = 16;
|
|
public int LineHeight = 16;
|
|
|
|
|
|
- public List<IRenderItem> Items { get; protected set; } = new List<IRenderItem>();
|
|
|
|
|
|
+ public List<List<IRenderItem>> Items { get; protected set; } = new List<List<IRenderItem>>();
|
|
|
|
+
|
|
|
|
+ public List<Rectangle> UpdateRegions = new List<Rectangle>();
|
|
|
|
|
|
public int offset;
|
|
public int offset;
|
|
|
|
|
|
@@ -18,9 +21,22 @@ namespace NTERA.Console
|
|
public delegate void AddedItemEventHandler(IRenderItem item);
|
|
public delegate void AddedItemEventHandler(IRenderItem item);
|
|
public event AddedItemEventHandler AddedItem;
|
|
public event AddedItemEventHandler AddedItem;
|
|
|
|
|
|
- public void AddItem(IRenderItem item)
|
|
|
|
|
|
+ public ConsoleRenderer()
|
|
|
|
+ {
|
|
|
|
+ Items.Add(new List<IRenderItem>());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void WriteItem(IRenderItem item)
|
|
|
|
+ {
|
|
|
|
+ Items[Items.Count - 1].Add(item);
|
|
|
|
+
|
|
|
|
+ AddedItem?.Invoke(item);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void PrintItem(IRenderItem item)
|
|
{
|
|
{
|
|
- Items.Add(item);
|
|
|
|
|
|
+ Items[Items.Count - 1].Add(item);
|
|
|
|
+ Items.Add(new List<IRenderItem>());
|
|
|
|
|
|
AddedItem?.Invoke(item);
|
|
AddedItem?.Invoke(item);
|
|
}
|
|
}
|
|
@@ -32,12 +48,14 @@ namespace NTERA.Console
|
|
int screenLineCount = (int)Math.Ceiling(clientArea.Height / (float)LineHeight);
|
|
int screenLineCount = (int)Math.Ceiling(clientArea.Height / (float)LineHeight);
|
|
|
|
|
|
int firstItem = Math.Max(0, lastItem - screenLineCount);
|
|
int firstItem = Math.Max(0, lastItem - screenLineCount);
|
|
-
|
|
|
|
|
|
+
|
|
for (int i = firstItem; i < lastItem; i++)
|
|
for (int i = firstItem; i < lastItem; i++)
|
|
{
|
|
{
|
|
|
|
+ int x = 0;
|
|
|
|
+
|
|
int y = clientArea.Height - (lastItem - i) * LineHeight;
|
|
int y = clientArea.Height - (lastItem - i) * LineHeight;
|
|
|
|
|
|
- var itemArea = new Rectangle(0, y, clientArea.Width, LineHeight);
|
|
|
|
|
|
+ var itemArea = new Rectangle(x, y, clientArea.Width - x, LineHeight);
|
|
|
|
|
|
if (!invalidateArea.IntersectsWith(itemArea))
|
|
if (!invalidateArea.IntersectsWith(itemArea))
|
|
continue;
|
|
continue;
|
|
@@ -46,7 +64,17 @@ namespace NTERA.Console
|
|
itemArea.Y -= LineHeight - itemArea.Height;
|
|
itemArea.Y -= LineHeight - itemArea.Height;
|
|
itemArea.Height = LineHeight;
|
|
itemArea.Height = LineHeight;
|
|
|
|
|
|
- Items[i].Render(graphics, itemArea, mousePointer);
|
|
|
|
|
|
+ foreach (var renderItem in Items[i].ToArray())
|
|
|
|
+ {
|
|
|
|
+ int newX = renderItem.Render(graphics, itemArea, invalidateArea, mousePointer);
|
|
|
|
+
|
|
|
|
+ itemArea.Width = newX - x;
|
|
|
|
+ itemArea.X = newX;
|
|
|
|
+
|
|
|
|
+ renderItem.Region = itemArea;
|
|
|
|
+
|
|
|
|
+ x = newX;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
LastLineCount = screenLineCount;
|
|
LastLineCount = screenLineCount;
|
|
@@ -54,25 +82,22 @@ namespace NTERA.Console
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
- protected RectangleF? lastUpdateRange = null;
|
|
|
|
|
|
+ protected Rectangle? lastUpdateRange = null;
|
|
|
|
|
|
public void MouseHoverEvent(Point mousePoint, Control control)
|
|
public void MouseHoverEvent(Point mousePoint, Control control)
|
|
{
|
|
{
|
|
- foreach (var item in Items.ToArray())
|
|
|
|
|
|
+ foreach (var item in Items.SelectMany(x => x))
|
|
{
|
|
{
|
|
- foreach (var rect in item.UpdateRegions)
|
|
|
|
|
|
+ if (!item.InvalidateOnMouseStateChange || !item.Region.Contains(mousePoint))
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ if (item.Region != lastUpdateRange)
|
|
{
|
|
{
|
|
- if (!rect.Contains(mousePoint))
|
|
|
|
- continue;
|
|
|
|
-
|
|
|
|
- if (rect != lastUpdateRange)
|
|
|
|
- {
|
|
|
|
- control.Invalidate(Rectangle.Round(rect), true);
|
|
|
|
- lastUpdateRange = rect;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return;
|
|
|
|
|
|
+ control.Invalidate(item.Region, true);
|
|
|
|
+ lastUpdateRange = item.Region;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
|
|
if (lastUpdateRange != null)
|
|
if (lastUpdateRange != null)
|