private bool m_DragVisible; // true if the current drag is moving the visible area. False means it is rearranging pages // once the user moves far enough to trigger page rearrangement, it never reverts to adjusting the visible area private void ctrPages_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { if (Globals.Root.CurrentConfig.ReadBoolean(Config.Context_Menus)) { DisplayContextMenu?.Invoke(e.Location); } return; } int pageIndex = HitTest(e.Location); if (pageIndex < 0 || pageIndex >= m_Document.Count) { return; } if (pageIndex != m_DisplayedIndex) { DisplayPage?.Invoke(pageIndex); } // don't also move within page (tried it and OK, but I think can be confusing) else if (!m_DisplayArea.IsEmpty) { // if m_rctDisplayArea is empty it implies that the entire page is displayed at once, so no point asking to scroll the display Rectangle pageBounds = PageBounds(pageIndex); Page page = m_Document.Page(pageIndex); PointF data = new PointF((e.X - pageBounds.Left) * page.Size.Width / pageBounds.Width, (pageBounds.Bottom - e.Y) * page.Size.Height / pageBounds.Height); //note that the Y coordinate is inverted between the screen and page CentreViewOn?.Invoke(data); } }
private void ctrPages_MouseMove(object sender, MouseEventArgs e) { if (!m_DragTrigger.IsEmpty && !m_DragTrigger.Contains(e.X, e.Y) && m_HitPage >= 0) { m_DragPage = m_HitPage; m_DragTrigger = Rectangle.Empty; // will flow thru into next condition... m_DragPageLocation = PageBounds(m_DragPage); Capture = true; Invalidate(); if (m_DragPage != m_DisplayedIndex) { DisplayPage?.Invoke(m_DragPage); } } if (m_DragPage >= 0) { // already dragging. If the drag is quite small we will just move the visible area. If it is larger we will start rearranging pages Rectangle visible = VisibleAreaLocal(); visible.X = e.X + m_VisibleOffset.Width; visible.Y = e.Y + m_VisibleOffset.Height; // this is where the visible area would be if we just drag it // if this has gone significantly outside the page that we will treat this as page rearranging Rectangle pageBounds = PageBounds(m_DragPage); pageBounds.Inflate(12, 20); if (!m_HasDraggedOutside && !m_DragVisible) { Invalidate(m_DragPageLocation); } if (m_DragVisible && pageBounds.Contains(visible)) { pageBounds.Inflate(-12, -20); Page page = m_Document.Page(m_DragPage); // we then centre the view on the centre of this rectangle (see MouseClick) Point local = new Point(visible.X + visible.Width / 2, visible.Y + visible.Height / 2); PointF data = new PointF((local.X - pageBounds.Left) * page.Size.Width / pageBounds.Width, (pageBounds.Bottom - local.Y) * page.Size.Height / pageBounds.Height); //note that the Y coordinate is inverted between the screen and page CentreViewOn?.Invoke(data); } else { if (m_DragVisible) { Invalidate(PageBounds(m_DragPage)); } m_DragVisible = false; // keep width and height of drag version, but move TL m_DragPageLocation.X = e.X + m_DragPageOffset.Width; m_DragPageLocation.Y = e.Y + m_DragPageOffset.Height; m_HasDraggedOutside = e.X <0 || e.Y <0 || e.X> Width || e.Y> Height; if (m_HasDraggedOutside) { if (m_DropBefore >= 0) { Invalidate(InsertMarkerBounds(m_DropBefore)); } m_DropBefore = -1; } else { int newIndex = HitTestInsert(e.Location); if (newIndex == m_DragPage || newIndex == m_DragPage + 1) { newIndex = -1; // moving page before or after itself want actually change anything! } if (newIndex != m_DropBefore) { Invalidate(InsertMarkerBounds(m_DropBefore)); Invalidate(InsertMarkerBounds(newIndex)); } m_DropBefore = newIndex; Invalidate(m_DragPageLocation); } } } }