using CommonLang;
using CommonLang.Geometry;
using CommonLang.Geometry.SceneGraph2D;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace CommonFroms.SceneGraph2D.Edit
{
public class SceneEditPanel : Win32ScenePanel
{
///
/// 开始拖拽时距离
///
public static float DRAG_MOVE_START_DISTANCE = 4.0f;
public SceneEditPanel()
{
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.AutoUpdate = false;
}
//--------------------------------------------------------------------------------------
protected override DisplayRoot CreateRoot()
{
return new EditorDisplayRoot(this);
}
public class EditorDisplayRoot : DisplayRoot
{
private readonly SceneEditPanel panel;
private Brush bg_brush = new TextureBrush(global::CommonFroms.Properties.Resources.canvasBg2);
private Pen bg_pen = new Pen(System.Drawing.Color.Black);
internal EditorDisplayRoot(SceneEditPanel panel)
{
this.panel = panel;
}
public override void Visit(IGraphics g)
{
{
var pos = Translation;
pos.X = Math.Min(pos.X, panel.canvas.Width);
pos.X = Math.Max(pos.X, 0);
pos.Y = Math.Min(pos.Y, panel.canvas.Height);
pos.Y = Math.Max(pos.Y, 0);
var gfx = (g as Win32Graphics).gfx;
gfx.TranslateTransform(pos.X, pos.Y);
gfx.FillRectangle(bg_brush, -panel.Width, -panel.Height, panel.Width << 1, panel.Height << 1);
gfx.DrawLine(bg_pen, -panel.canvas.Width, 0, panel.canvas.Width, 0);
gfx.DrawLine(bg_pen, 0, -panel.canvas.Height, 0, panel.canvas.Height);
gfx.TranslateTransform(-pos.X, -pos.Y);
}
this.Rotation = 0f;
base.Visit(g);
//this.Translation = new Vector2(cx, cy);
//this.Scale = new Vector2(1f, 1f);
}
protected override void OnDrawBegin(IGraphics g)
{
base.OnDrawBegin(g);
var gfx = (g as Win32Graphics).gfx;
}
}
//--------------------------------------------------------------------------------------
protected override void canvas_Paint(object sender, PaintEventArgs e)
{
var g = e.Graphics;
base.canvas_Paint(sender, e);
using (var list = ListObjectPool.AllocAutoRelease())
{
RootNode.GetChildren(list, true);
foreach (var node in list)
{
if (node is EditorNode)
{
(node as EditorNode).VisitHUD(g);
}
}
}
}
//--------------------------------------------------------------------------------------
#region Selection
private bool multi_select = true;
public bool IsMultiSelect
{
get { return multi_select; }
set
{
if (value != multi_select)
{
multi_select = value;
if (!value)
{
if (selected_list.Count > 0)
{
SelectNode(selected_list[0]);
}
}
}
}
}
private List selected_list = new List();
private HashMap selected_list_old_pos = new HashMap();
public EditorNode[] SelectedNodes
{
get { return selected_list.ToArray(); }
}
private EditorNode last_mouse_down_node;
protected override void canvas_MouseDown(object sender, MouseEventArgs e)
{
var rpos = CanvasMouseToRoot(e.Location);
var hitted = RootNode.HitTest(rpos);
this.last_mouse_down_node = hitted as EditorNode;
if (e.Button == MouseButtons.Left)
{
if (IsMultiSelect && Keyboard.IsCtrlDown)
{
AddSelectNode(hitted);
}
else
{
SelectNode(hitted);
}
}
}
protected override void canvas_MouseMove(object sender, MouseEventArgs e)
{
var rpos = CanvasMouseToRoot(e.Location);
var hitted = RootNode.HitTest(rpos);
if (e.Button == MouseButtons.None)
{
PickNode(hitted);
}
else
{
PickNode(null);
if (e.Button == MouseButtons.Left)
{
if (selected_list.Count > 0)
{
}
}
}
}
protected override void canvas_MouseUp(object sender, MouseEventArgs e)
{
}
private void PickNode(DisplayNode hitted)
{
RootNode.ForEachChildren((c) =>
{
if (c is EditorNode)
{
var ec = (c as EditorNode);
ec.IsPicked = (ec.IsPickable) && (c == hitted);
}
return false;
}, true);
}
public void AddSelectNode(DisplayNode hitted)
{
if (selected_list.Count > 0 && !IsMultiSelect)
{
return;
}
RootNode.ForEachChildren((c) =>
{
if (c is EditorNode)
{
var se = (c as EditorNode);
if (c == hitted && se.IsSelectable)
{
se.IsSelected = true;
if (!selected_list.Contains(se))
{
selected_list.Add(se);
}
}
}
return false;
}, true);
}
public void SelectNode(DisplayNode hitted)
{
selected_list.Clear();
RootNode.ForEachChildren((c) =>
{
if (c is EditorNode)
{
var se = (c as EditorNode);
if (c == hitted && se.IsSelectable)
{
se.IsSelected = true;
selected_list.Add(se);
}
else
{
se.IsSelected = false;
}
}
return false;
}, true);
}
#endregion
}
}