using System; using System.Drawing; using System.Windows.Forms; namespace SpriteWave { public class DragObject { private bool _escaped = false; public bool Started { get { return _escaped; } } private const float curScale = 4f; private const float curAlpha = 0.6f; private Cursor _cur; private Position _orgPos; private TileWindow _orgWnd; private int _lastX, _lastY; private TileWindow _lastWnd; public TileWindow Window { get { return _lastWnd; } } private IPiece _selObj; public bool IsEdge { get { return _selObj is Edge; } } public Selection Current() { if (_lastWnd == null) return null; bool wasOob; Position pos = _lastWnd.GetPosition(_lastX, _lastY, out wasOob); Edge edge = _selObj as Edge; if (edge == null) { _lastWnd.Selected = !wasOob; return wasOob ? null : new Selection(_selObj, _lastWnd, pos); } if (_lastWnd == _orgWnd) edge.Distance = new Position( pos.col - _orgPos.col, pos.row - _orgPos.row ); else edge.Distance = new Position(0, 0); return new Selection(_selObj, _lastWnd, pos); } public DragObject(TileWindow wnd, int x, int y) { _lastX = x; _lastY = y; _lastWnd = wnd; _orgWnd = wnd; bool wasOob; _orgPos = _orgWnd.GetPosition(x, y, out wasOob); if (wasOob) throw new ArgumentOutOfRangeException(); _selObj = _orgWnd.PieceAt(_orgPos); if (_selObj is Tile) { Bitmap img = _orgWnd.TileBitmap(_selObj as Tile); img = img.SetAlpha(curAlpha).Scale(curScale); _cur = new Cursor(img.GetHicon()); } _orgWnd.Cursor = new Selection(_selObj, _orgWnd, _orgPos); _orgWnd.AdoptCursor(); Transfer.Source = _orgWnd.Cursor; } public void End() { if (_lastWnd == null) return; _lastWnd.AdoptCursor(); _lastWnd.Cursor = null; } public Selection Cancel() { // maybe clear inputcontrolstab sample? _orgWnd.Cursor = null; _orgWnd.Selected = true; return _orgWnd.CurrentSelection(); } private void Escape() { _escaped = true; if (_cur != null) Cursor.Current = _cur; Transfer.Start(); } private bool HasLeft(TileWindow wnd) { if (wnd == null || wnd != _orgWnd) return true; if (_selObj is Edge) { var dist = ((Edge)_selObj).Distance; return (dist.col != 0 || dist.row != 0); } bool wasOob; Position loc = wnd.GetPosition(_lastX, _lastY, out wasOob); return !wasOob && (loc.col != _orgPos.col || loc.row != _orgPos.row); } public Selection Update(TileWindow wnd, int x, int y) { _lastX = x; _lastY = y; if (!_escaped && this.HasLeft(wnd)) Escape(); if (_selObj is Edge) wnd = _orgWnd; if (wnd != _lastWnd && _lastWnd != null) { _lastWnd.Cursor = null; _lastWnd.Selected = false; _lastWnd.Draw(); } _lastWnd = wnd; Selection sel = this.Current(); if (_lastWnd != null) _lastWnd.Cursor = sel; return sel; } } }