using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using CommonLang.Geometry.SceneGraph2D; using CommonLang.Geometry; using CommonLang; namespace CommonFroms.SceneGraph2D { public partial class Win32ScenePanel : UserControl { static Win32ScenePanel() { Win32SceneGraphFactory.Init(); } private DisplayRoot root; private int fps = 30; private SystemTimeRecoder update_time = new SystemTimeRecoder(); public DisplayRoot RootNode { get { return root; } } public PictureBox RootCanvas { get { return canvas; } } public int Tick { get; private set; } public int FPS { get { return fps; } set { if (fps != value) { timer.Interval = 1000 / fps; } } } public int CurrentIntervalMS { get { return update_time.CurrentIntervalMS; } } public bool AutoUpdate { get { return timer.Enabled; } set { if (timer.Enabled != value) { timer.Enabled = value; update_time.Reset(); if (value) { timer.Start(); } else { timer.Stop(); } } } } public Win32ScenePanel() { InitializeComponent(); this.canvas.MouseDown += this.camera_MouseDown; this.canvas.MouseUp += this.camera_MouseUp; this.canvas.MouseMove += this.camera_MouseMove; this.canvas.MouseWheel += camera_MouseWheel; this.canvas.Paint += canvas_Paint; this.timer.Interval = 1000 / fps; this.timer.Tick += Timer1_Tick; this.MouseRightMoveCamera = true; } //----------------------------------------------------------------------------------------------------- public Vector2 CanvasMouseToRoot(System.Drawing.Point mpos) { var rpos = root.ParentToLocal(new Vector2(mpos.X, mpos.Y)); return rpos; } public Vector2 ScreenMouseToRoot() { var rpos = canvas.PointToClient(MousePosition); return CanvasMouseToRoot(rpos); } protected virtual DisplayRoot CreateRoot() { return new DisplayRoot(); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); this.root = CreateRoot(); this.AutoUpdate = true; } protected virtual void Timer1_Tick(object sender, EventArgs e) { canvas.Refresh(); Tick++; } protected virtual void canvas_Paint(object sender, PaintEventArgs e) { int intervalMS = update_time.Update(); OnCanvasUpdate?.Invoke(intervalMS); var g = e.Graphics; var st = g.Save(); try { if (root != null) { root.Visit(new Win32Graphics(g)); } } catch (Exception err) { Console.WriteLine(err.Message); } finally { g.Restore(st); } OnCanvasDraw?.Invoke(g); } protected virtual void canvas_MouseDown(object sender, MouseEventArgs e) { } protected virtual void canvas_MouseMove(object sender, MouseEventArgs e) { } protected virtual void canvas_MouseUp(object sender, MouseEventArgs e) { } public delegate void CanvasDraw(Graphics g); public event CanvasDraw OnCanvasDraw; public delegate void CanvasUpdate(int intervalMS); public event CanvasUpdate OnCanvasUpdate; //----------------------------------------------------------------------------------------------------- #region Camera private bool is_last_mouse_down = false; private Vector2 last_mouse_pos; private Vector2 last_camera_pos; public bool MouseRightMoveCamera { get; set; } public Vector2 CameraPos { get { return -root.Translation; } set { this.root.Translation = -value; } } public float CameraZoom { get { return root.Scale.X; } set { this.root.Scale = new Vector2(value, value); } } private void camera_MouseDown(object sender, MouseEventArgs e) { if (MouseRightMoveCamera) { canvas.Focus(); if (e.Button == MouseButtons.Right) { is_last_mouse_down = true; last_mouse_pos = new Vector2(e.Location.X, e.Location.Y); last_camera_pos = this.CameraPos; } } RefreshCanvas(); } private void camera_MouseMove(object sender, MouseEventArgs e) { if (MouseRightMoveCamera) { if (is_last_mouse_down && e.Button == MouseButtons.Right) { var offset = new Vector2( last_mouse_pos.X - e.Location.X, last_mouse_pos.Y - e.Location.Y); this.CameraPos = last_camera_pos + offset; } } RefreshCanvas(); } private void camera_MouseUp(object sender, MouseEventArgs e) { is_last_mouse_down = false; RefreshCanvas(); } private void camera_MouseWheel(object sender, MouseEventArgs e) { if (MouseRightMoveCamera) { this.CameraZoom += CMath.getDirect(e.Delta) * 0.1f; } RefreshCanvas(); } public void RefreshCanvas() { if (timer.Enabled == false) { canvas.Refresh(); } } #endregion //----------------------------------------------------------------------------------------------------- } }