예제 #1
0
파일: MapHud.cs 프로젝트: joshlatte/goarrow
		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();
			}
		}
예제 #2
0
		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;
			}
		}