Esempio n. 1
0
int32_t Screen::GetMouseControlledDialogCount()
	{
	Dialog *pDlg; int32_t iResult=0;
	for (Element *pEl = GetFirst(); pEl; pEl = pEl->GetNext())
		if (pDlg = pEl->GetDlg())
			if (pDlg->IsShown() && pDlg->IsMouseControlled())
				++iResult;
	return iResult;
	}
Esempio n. 2
0
Dialog *Screen::GetTopDialog()
	{
	// search backwards in component list
	Dialog *pDlg;
	for (Element *pEl = pLast; pEl; pEl = pEl->GetPrev())
		if (pDlg = pEl->GetDlg())
			if (pDlg->IsShown())
				return pDlg;
	// no dlg found
	return NULL;
	}
Esempio n. 3
0
bool Screen::MouseInput(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam, Dialog *pForDlg, class C4Viewport *pForVP)
	{
	// help mode and button pressed: Abort help and discard button
	if (Game.MouseControl.IsHelp())
		{
		switch (iButton)
			{
			case C4MC_Button_None:
				// just movement
				break;
			case C4MC_Button_LeftDown:
			case C4MC_Button_RightDown:
				// special for left/right down: Just ignore them, but don't stop help yet
				// help should be stopped on button-up, so these won't be processed
				iButton = C4MC_Button_None;
				break;
			default:
				// buttons stop help
				Game.MouseControl.AbortHelp();
				iButton = C4MC_Button_None;
				break;
			}
		}
	// forward to mouse
	Mouse.Input(iButton, iX, iY, dwKeyParam);
	// dragging
	if (Mouse.pDragElement)
		{
		int32_t iX2=iX, iY2=iY;
		Mouse.pDragElement->ScreenPos2ClientPos(iX2, iY2);
		if (!Mouse.IsLDown())
			{
			// stop dragging
			Mouse.pDragElement->StopDragging(Mouse, iX2, iY2, dwKeyParam);
			Mouse.pDragElement = NULL;
			}
		else
			{
			// continue dragging
			Mouse.pDragElement->DoDragging(Mouse, iX2, iY2, dwKeyParam);
			}
		}
	// backup previous MouseOver-element
	Mouse.pPrevMouseOverElement = Mouse.pMouseOverElement;
	Mouse.pMouseOverElement = NULL;
	bool fProcessed = false;
	// active context menu?
	if (!pForVP && pContext && pContext->CtxMouseInput(Mouse, iButton, iX, iY, dwKeyParam))
		{
		// processed by context menu: OK!
		}
	// otherwise: active dlg and inside screen? (or direct forward to specific dlg/viewport dlg)
	else if (rcBounds.Contains(iX, iY) || pForDlg || pForVP)
		{
		// context menu open but mouse down command issued? close context then
		if (pContext && (iButton == C4MC_Button_LeftDown || iButton == C4MC_Button_RightDown))
			AbortContext(true);
		// get client pos
		if (!pForDlg && !pForVP)
			{
			C4Rect &rcClientArea = GetClientRect();
			iX -= rcClientArea.x; iY -= rcClientArea.y;
			}
		// exclusive mode: process active dialog only
		if (IsExclusive() && !pForDlg && !pForVP)
			{
			if (pActiveDlg && pActiveDlg->IsVisible() && !pActiveDlg->IsFading())
				{
				// bounds check to dlg: only if not dragging
				C4Rect &rcDlgBounds = pActiveDlg->GetBounds();
				if (Mouse.IsLDown() || rcDlgBounds.Contains(iX, iY))
					// forward to active dialog
					pActiveDlg->MouseInput(Mouse, iButton, iX - rcDlgBounds.x, iY - rcDlgBounds.y, dwKeyParam);
				else
					Mouse.pMouseOverElement = NULL;
				}
			else
				// outside dialog: own handling (for screen context menu)
				Window::MouseInput(Mouse, iButton, iX, iY, dwKeyParam);
			}
		else
			{
			// non-exclusive mode: process all dialogs; make them active on left-click
			Dialog *pDlg;
			for (Element *pEl = pLast; pEl; pEl = pEl->GetPrev())
				if (pDlg = pEl->GetDlg())
					if (pDlg->IsShown())
						{
						// if specified: process specified dlg only
						if (pForDlg && pDlg != pForDlg) continue;
						// if specified: process specified viewport only
						bool fIsExternalDrawDialog = pDlg->IsExternalDrawDialog();
						C4Viewport *pVP = fIsExternalDrawDialog ? pDlg->GetViewport() : NULL;
						if (pForVP && pForVP != pVP) continue;
						// calc offset
						C4Rect &rcDlgBounds = pDlg->GetBounds();
						int32_t iOffX=0, iOffY=0;
						// special handling for viewport dialogs
						if (fIsExternalDrawDialog)
							{
							// ignore external drawing dialogs without a viepwort assigned
							if (!pVP) continue;
							// always clip to viewport bounds
							C4Rect rcOut(pVP->GetOutputRect());
							if (!rcOut.Contains(iX + rcBounds.x, iY + rcBounds.y)) continue;
							// viewport dialogs: Offset determined by viewport position
							iOffX = rcOut.x; iOffY = rcOut.y;
							}
						// hit test; or special: dragging possible outside active dialog
						if (rcDlgBounds.Contains(iX-iOffX, iY-iOffY) || (pDlg == pActiveDlg && Mouse.pDragElement))
							{
							// Okay; do input
							pDlg->MouseInput(Mouse, iButton, iX - rcDlgBounds.x - iOffX, iY - rcDlgBounds.y - iOffY, dwKeyParam);
							// dlgs may destroy GUI
							if (!IsGUIValid()) return false;
							// CAUTION: pDlg may be invalid now!
							// set processed-flag manually
							fProcessed = true;
							// inactive dialogs get activated by clicks
							if (Mouse.IsLDown() && pDlg != pActiveDlg)
								// but not viewport dialogs!
								if (!pDlg->IsExternalDrawDialog())
									ActivateDialog(pDlg);
							// one dlg only; break loop here
							break;
							}
						}
			}
		// check valid GUI; might be destroyed by mouse input
		if (!IsGUIValid()) return false;
		}

	// check if MouseOver has changed
	if (Mouse.pPrevMouseOverElement != Mouse.pMouseOverElement)
		{
		// send events
		if (Mouse.pPrevMouseOverElement) Mouse.pPrevMouseOverElement->MouseLeave(Mouse);
		if (Mouse.pMouseOverElement) Mouse.pMouseOverElement->MouseEnter(Mouse);
		}
	// return whether anything processed it
	return fProcessed || Mouse.pDragElement || (Mouse.pMouseOverElement && Mouse.pMouseOverElement!=this) || pContext;
	}