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 } }