private void MapHud_ClientMouseDrag(object sender, HudMouseDragEventArgs e) { if ((e.Button & DragButton) != 0) { mOffset.X = (e.Location.X - mMouseDownOffset.X * Zoom) / Zoom; mOffset.Y = (e.Location.Y - mMouseDownOffset.Y * Zoom) / Zoom; mNeedsPlayerRecenter = false; RepaintAll(); } }
void IManagedHud.WindowMessage(WindowMessageEventArgs e) { if (WindowMessage != null) WindowMessage(this, e); // Only process mouse messages when the window is visible if (!Visible || e.Msg < WM_MOUSEFIRST || e.Msg > WM_MOUSELAST) return; Point prevLocation = mMouseLocation; bool prevOnWindow = mMouseOnWindow; bool prevOnClient = mMouseOnClient; mMouseLocation = new Point(e.LParam); if (e.Msg == WM_MOUSEWHEEL) { // WM_MOUSEWHEEL messages are apparently absolute on the screen, // not relative to the AC window; fix with ScreenToClient ScreenToClient(Host.Decal.Hwnd, ref mMouseLocation); } mMouseOnWindow = CalcMouseOnWindow(); mMouseOnWindow = mMouseOnWindow && Manager.MouseHoveringOnHud(this); mMouseOnClient = CalcMouseOnClient(); // Calculate relative coordinates int wX = mMouseLocation.X - mRegion.X; int wY = mMouseLocation.Y - mRegion.Y; int cX = mMouseLocation.X - mClientRegion.X; int cY = mMouseLocation.Y - mClientRegion.Y; short fwKeys = (short)(e.WParam & 0xFFFF); MouseButtons button = MouseButtons.None; if (e.Msg == WM_MOUSEMOVE) { } else if (e.Msg == WM_LBUTTONDOWN || e.Msg == WM_LBUTTONUP) button = MouseButtons.Left; else if (e.Msg == WM_RBUTTONDOWN || e.Msg == WM_RBUTTONUP) button = MouseButtons.Right; else if (e.Msg == WM_MBUTTONDOWN || e.Msg == WM_MBUTTONUP) button = MouseButtons.Middle; bool dblClick = false; if (e.Msg == WM_LBUTTONDOWN || e.Msg == WM_RBUTTONDOWN || e.Msg == WM_MBUTTONDOWN) { dblClick = (mMouseLastClickButton == button) && Math.Abs(mMouseLocation.X - mMouseLastClickLocation.X) <= msDblClickRect.Width && Math.Abs(mMouseLocation.Y - mMouseLastClickLocation.Y) <= msDblClickRect.Height && Math.Abs(DateTime.Now.Ticks - mMouseLastClickTicks) <= msDblClickTicks; mMouseLastClickTicks = dblClick ? long.MinValue : DateTime.Now.Ticks; mMouseLastClickLocation = mMouseLocation; mMouseLastClickButton = button; } #region Handle Moving, Resizing, and Control Button Clicks if (e.Msg == WM_MOUSEMOVE) { // Handle moving the window if (IsMoving) { mRegion.X = mOriginalRegion.X + mMouseLocation.X - mMouseDownLocation.X; mRegion.Y = mOriginalRegion.Y + mMouseLocation.Y - mMouseDownLocation.Y; mRegion = ConstrainRegion(mRegion); mClientRegion = CalculateClientRegion(mRegion); // Recalculate whether the mouse is on the window and // client, since the regions have changed mMouseOnWindow = CalcMouseOnWindow(); mMouseOnClient = CalcMouseOnClient(); if (HudsAreCreated) { mHud.Region = new Rectangle(mRegion.Location, mHud.Region.Size); } if (Moving != null) { Moving(this, EventArgs.Empty); } } // Handle resizing the window else if (IsResizing) { if ((mMoveResizeMode & MoveResizeMode.ResizeN) != 0) { int oldBottom = mRegion.Bottom; mRegion.Y = mOriginalRegion.Y + mMouseLocation.Y - mMouseDownLocation.Y; mRegion.Height = oldBottom - mRegion.Y; if (mRegion.Height < MinHeight) { mRegion.Y = oldBottom - MinHeight; mRegion.Height = MinHeight; } else if (mRegion.Height > MaxHeight) { mRegion.Y = oldBottom - MaxHeight; mRegion.Height = MaxHeight; } } else if ((mMoveResizeMode & MoveResizeMode.ResizeS) != 0) { mRegion.Height = mOriginalRegion.Height + mMouseLocation.Y - mMouseDownLocation.Y; } if ((mMoveResizeMode & MoveResizeMode.ResizeW) != 0) { int oldRight = mRegion.Right; mRegion.X = mOriginalRegion.X + mMouseLocation.X - mMouseDownLocation.X; mRegion.Width = oldRight - mRegion.X; if (mRegion.Width < MinWidth) { mRegion.X = oldRight - MinWidth; mRegion.Width = MinWidth; } else if (mRegion.Width > MaxWidth) { mRegion.X = oldRight - MaxWidth; mRegion.Width = MaxWidth; } } else if ((mMoveResizeMode & MoveResizeMode.ResizeE) != 0) { mRegion.Width = mOriginalRegion.Width + mMouseLocation.X - mMouseDownLocation.X; } mRegion = ConstrainRegion(mRegion); mClientRegion = CalculateClientRegion(mRegion); // Recalculate whether the mouse is on the window and // client, since the regions have changed mMouseOnWindow = CalcMouseOnWindow(); mMouseOnClient = CalcMouseOnClient(); if (Resizing != null) { Resizing(this, EventArgs.Empty); } RepaintWindow(); if (ResizeDrawMode == HudResizeDrawMode.Repaint) Repaint(); } CalculateHighlightedBorder(); // Handle the mouse entering/leaving the control boxes if (mMouseOnClose || mMouseOnMinRestore || mMouseOnSticky) { DrawControlBoxes(false); } } // if (e.Msg == WM_MOUSEMOVE) else if (e.Msg == WM_LBUTTONDOWN && mMouseOnWindow) { // Put this window on top of other windows Manager.BringToFront(this, false); if (CloseBoxRect.Contains(mMouseLocation)) { mMouseOnClose = true; DrawControlBoxes(false); e.Eat = true; } else if (MinRestoreBoxRect.Contains(mMouseLocation)) { mMouseOnMinRestore = true; DrawControlBoxes(false); e.Eat = true; } else if (AlphaFadingEnabled && StickyBoxRect.Contains(mMouseLocation)) { mMouseOnSticky = true; DrawControlBoxes(false); e.Eat = true; } else if (TitleBarRect.Contains(mMouseLocation)) { if (dblClick) { Minimized = !Minimized; } else { mMoveResizeMode = MoveResizeMode.Moving; mMouseDownLocation = mMouseLocation; mOriginalRegion = mRegion; } e.Eat = true; } else { mMoveResizeMode = MoveResizeMode.Idle; if (!Minimized) { if (mMouseLocation.X <= mRegion.Left + BorderPaddedWidth) mMoveResizeMode |= MoveResizeMode.ResizeW; else if (mMouseLocation.X >= mRegion.Right - BorderPaddedWidth) mMoveResizeMode |= MoveResizeMode.ResizeE; if (mMouseLocation.Y <= mRegion.Top + BorderPaddedWidth) mMoveResizeMode |= MoveResizeMode.ResizeN; else if (mMouseLocation.Y >= mRegion.Bottom - BorderPaddedWidth) mMoveResizeMode |= MoveResizeMode.ResizeS; if (mMoveResizeMode != MoveResizeMode.Idle) { mMouseDownLocation = mMouseLocation; mOriginalRegion = mRegion; e.Eat = true; } } } } // else if (e.Msg == WM_LBUTTONDOWN && mMouseOnWindow) else if (e.Msg == WM_LBUTTONUP) { if (MoveEnd != null && mMoveResizeMode == MoveResizeMode.Moving) { MoveEnd(this, EventArgs.Empty); } else if ((mMoveResizeMode & MoveResizeMode.Resizing) != 0) { if (ResizeEnd != null) { ResizeEnd(this, EventArgs.Empty); } // If the ResizeDrawMode is something other than Repaint, // we need to repaint it now that we're done resizing. if (ResizeDrawMode != HudResizeDrawMode.Repaint) { Repaint(); } if (!mMouseOnWindow) { MouseEvent(MouseLeave, e, mMouseButtons, 0, wX, wY, 0, fwKeys); } } mMoveResizeMode = MoveResizeMode.Idle; if (mMouseOnClose || mMouseOnMinRestore || mMouseOnSticky) { if (mMouseOnClose && CloseBoxRect.Contains(mMouseLocation)) { Visible = false; } else if (mMouseOnMinRestore && MinRestoreBoxRect.Contains(mMouseLocation)) { Minimized = !Minimized; } else if (mMouseOnSticky && StickyBoxRect.Contains(mMouseLocation)) { Sticky = !Sticky; } mMouseOnClose = false; mMouseOnMinRestore = false; mMouseOnSticky = false; DrawControlBoxes(false); } } // else if (e.Msg == WM_LBUTTONUP) #endregion #region Generate Mouse Events if (mMouseOnWindow) { switch (e.Msg) { case WM_MOUSEMOVE: MouseEvent(MouseMove, e, mMouseButtons, 0, wX, wY, 0, fwKeys); if (mMouseOnClient) { MouseEvent(ClientMouseMove, e, mClientMouseButtons, 0, cX, cY, 0, fwKeys); } break; case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: mMouseButtons |= button; if (dblClick) { MouseEvent(MouseDoubleClick, e, button, 2, wX, wY, 0, fwKeys); } else { MouseEvent(MouseDown, e, button, 1, wX, wY, 0, fwKeys); } if (mMouseOnClient) { if (mClientMouseButtons == MouseButtons.None) { mMouseDownLocation = mMouseLocation; } mClientMouseButtons |= button; if (dblClick) { MouseEvent(ClientMouseDoubleClick, e, button, 2, cX, cY, 0, fwKeys); } else { MouseEvent(ClientMouseDown, e, button, 1, cX, cY, 0, fwKeys); } } break; case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: MouseEvent(MouseUp, e, button, 1, wX, wY, 0, fwKeys, false); if (mMouseOnClient) { MouseEvent(ClientMouseUp, e, button, 1, cX, cY, 0, fwKeys, false); } break; case WM_MOUSEWHEEL: int zDelta = e.WParam >> 16; MouseEvent(MouseWheel, e, button, 0, wX, wY, zDelta, fwKeys); if (mMouseOnClient) { MouseEvent(ClientMouseWheel, e, button, 0, cX, cY, zDelta, fwKeys); } break; } // switch (e.Msg) } // if (mMouseOnWindow) // Additional WM_MOUSEMOVE messages that don't require the mouse to be on the window if (e.Msg == WM_MOUSEMOVE) { // Alert the client about dragging if (ClientMouseDrag != null && mClientMouseButtons != MouseButtons.None) { int x = mMouseLocation.X - mClientRegion.X; int y = mMouseLocation.Y - mClientRegion.Y; int dX = mMouseLocation.X - prevLocation.X; int dY = mMouseLocation.Y - prevLocation.Y; HudMouseDragEventArgs args = new HudMouseDragEventArgs(mClientMouseButtons, 0, x, y, 0, fwKeys, mMouseDownLocation.X, mMouseDownLocation.Y, dX, dY); ClientMouseDrag(this, args); if (args.Eat) e.Eat = true; } // Handle mouse entering/leaving the window or client // This must be done after moving/resizing if (!IsResizing) { // Mouse enter window if (mMouseOnWindow && !prevOnWindow) { MouseEvent(MouseEnter, e, mMouseButtons, 0, wX, wY, 0, fwKeys); } // Mouse leave window else if (!mMouseOnWindow && prevOnWindow) { MouseEvent(MouseLeave, e, mMouseButtons, 0, wX, wY, 0, fwKeys); } } // Mouse enter client if (mMouseOnClient && !prevOnClient) { MouseEvent(ClientMouseEnter, e, mClientMouseButtons, 0, cX, cY, 0, fwKeys); } // Mouse leave client else if (!mMouseOnClient && prevOnClient) { MouseEvent(ClientMouseLeave, e, mClientMouseButtons, 0, cX, cY, 0, fwKeys); } } #endregion if (e.Eat && (e.Msg == WM_LBUTTONDOWN || e.Msg == WM_RBUTTONDOWN || e.Msg == WM_MBUTTONDOWN)) { mMouseDownEaten |= button; } // Update which buttons are on the window and client // This must be done after mouse events are generated if (e.Msg == WM_LBUTTONUP || e.Msg == WM_RBUTTONUP || e.Msg == WM_MBUTTONUP) { mMouseButtons &= ~button; mClientMouseButtons &= ~button; if ((mMouseDownEaten & button) != 0) { e.Eat = true; } mMouseDownEaten &= ~button; } }