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 Graphics.Core; using Tao.Platform.Windows; namespace UI.Winforms.CustomControls { public partial class GraphicsViewport : UserControl { IWindowHandle _drawableSurface = null; public GraphicsViewport() { InitializeComponent(); } DrawQueue _drawQueue = null; bool _suspendDrawing = false; public void Draw() { _drawQueue.Draw(_drawableSurface); _drawableSurface.SubmitDrawCalls(); } public void ProperMoveResizeBehavior() { System.Windows.Forms.FormWindowState lastState = this.WindowState; int oldPosX = Bounds.Left; int oldPosY = Bounds.Top; bool isBeingResized = false; Shown += delegate(object sender, EventArgs e) { oldPosX = Bounds.Left; oldPosY = Bounds.Top; }; ResizeBegin += delegate(object sender, EventArgs e) { isBeingResized = false; //we might just be drag moving the window around oldPosX = Bounds.Left; oldPosY = Bounds.Top; }; this.SizeChanged += delegate(object sender, EventArgs e) { isBeingResized = true; // we definitely resized and not just dragged if (WindowState == System.Windows.Forms.FormWindowState.Maximized) //on maximize { int deltaX = Bounds.Left - oldPosX; int deltaY = Bounds.Top - oldPosY; _drawableSurface.Resize(displayBox.Width, displayBox.Height, deltaX, deltaY); _suspendDrawing = false; oldPosX = Bounds.Left; oldPosY = Bounds.Top; } else if (WindowState == System.Windows.Forms.FormWindowState.Minimized) { //do nothing, but suspend drawing _suspendDrawing = true; } else if (lastState == System.Windows.Forms.FormWindowState.Minimized) //unminimizing { _suspendDrawing = false; } else if (lastState == System.Windows.Forms.FormWindowState.Maximized) //on unmaximize { int deltaX = Bounds.Left - oldPosX; int deltaY = Bounds.Top - oldPosY; _drawableSurface.Resize(displayBox.Width, displayBox.Height, deltaX, deltaY); _suspendDrawing = false; oldPosX = Bounds.Left; oldPosY = Bounds.Top; Draw(); } else { _suspendDrawing = true; } lastState = WindowState; }; ResizeEnd += delegate(object sender, EventArgs e) { int deltaX = isBeingResized ? Bounds.Left - oldPosX : 0; int deltaY = isBeingResized ? Bounds.Top - oldPosY : 0; isBeingResized = false; if (_suspendDrawing) { _suspendDrawing = false; _drawableSurface.Resize(displayBox.Width, displayBox.Height, deltaX, deltaY); } Draw(); oldPosX = Bounds.Left; oldPosY = Bounds.Top; }; } public void MouseDragNavigationBehavior(System.Windows.Forms.Control control, System.Windows.Forms.MouseButtons dragButton) { bool isDragNavigating = false; int? dragStartX = null; int? dragStartY = null; control.MouseDown += delegate(object sender, System.Windows.Forms.MouseEventArgs e) { if (e.Button == dragButton) { //First, check to see if anything was clicked on //Second, start a drag process isDragNavigating = true; dragStartX = e.X; dragStartY = e.Y; } }; control.MouseMove += delegate(object sender, System.Windows.Forms.MouseEventArgs e) { if (isDragNavigating) { int deltaX = e.X - (dragStartX ?? e.X); int deltaY = e.Y - (dragStartY ?? e.Y); dragStartX = e.X; dragStartY = e.Y; _drawableSurface.Camera.TranslateSS(new Vector(deltaX, deltaY)); Draw(); } }; control.MouseUp += delegate(object sender, System.Windows.Forms.MouseEventArgs e) { if (e.Button == dragButton) { isDragNavigating = false; dragStartX = null; dragStartY = null; } }; } public void ZoomBehavior(System.Windows.Forms.Control control, Azimuth.Scalar spinSpeed, bool spinWheelForwardToZoom, bool zoomToMouseCursorInsteadOfScreenCenter) { Azimuth.Scalar ticks = 0; bool isInControl = false; //HookMouseWheel.HookMouseEvents(); Disposed += delegate(object sender, EventArgs e) { //HookMouseWheel.UnhookMouseEvents(); }; //HookMouseWheel.MouseWheel control.MouseWheel += delegate(object sender, System.Windows.Forms.MouseEventArgs e) { if (isInControl) { Azimuth.Scalar deltaTicks = spinSpeed * (spinWheelForwardToZoom ? 1 : -1) * e.Delta / 120.0; ticks += deltaTicks; var newMag = Math.Exp(ticks); Vector pointSS = new Vector(0.5, 0.5); if (zoomToMouseCursorInsteadOfScreenCenter) { pointSS = new Azimuth.Vector( e.X / (Scalar)control.Bounds.Width, 1.0 - e.Y / (Scalar)control.Bounds.Height); } _drawableSurface.Camera.ZoomInAroundPointSS(newMag, pointSS); Draw(); } }; control.MouseClick += delegate(object sender, System.Windows.Forms.MouseEventArgs e) { if (e.Button == MouseButtons.Left) { control.Focus(); } }; control.MouseEnter += delegate(object sender, EventArgs e) { isInControl = true; }; control.Leave += delegate(object sender, EventArgs e) { isInControl = false; }; } } /*public class Testbed{ public Testbed(Graphics.Core.IModule graphicsModule, DrawQueue drawQueue) { InitializeComponent(); ProperMoveResizeBehavior(); MouseDragNavigationBehavior(displayBox, System.Windows.Forms.MouseButtons.Left); ZoomBehavior(displayBox, 1.0 / 10.0, true, true); displayBox.Paint += delegate(object obj, System.Windows.Forms.PaintEventArgs args) { if (!_suspendDrawing) { Draw(); } }; Shown += delegate(object obj, EventArgs args) { displayBox.Focus(); }; _drawableSurface = graphicsModule.CreateDrawableSurfaceOnWindow(this.displayBox.Handle); _drawQueue = drawQueue; } private void Testbed_Load(object sender, EventArgs e) { Invalidate(); displayBox.Focus(); } private void Testbed_Paint(object sender, System.Windows.Forms.PaintEventArgs e) { } private void Testbed_Deactivate(object sender, EventArgs e) { } private void Testbed_Shown(object sender, EventArgs e) { } }*/ }