public static void Control() { #if PROFILE TimeManager.TimeSection("Object Display Manager Activity"); #endif InputManager.ReceivingInputJustSet = false; mToolTipText = ""; // Eventually we may do this per cursor: if (Cursor.PrimaryClick) { if (nextClickActions.Count > 0) { var items = nextClickActions.ToList(); nextClickActions.Clear(); foreach (var item in items) { item(); } } } if (Cursor.PrimaryPush) { if (nextPushActions.Count > 0) { var items = nextPushActions.ToList(); nextPushActions.Clear(); foreach (var item in items) { item(); } } } foreach (Cursor c in mCursors) { // Do this before the activity so on a click the frame with the click will still have a valid // WindowPushed. if ((c.PrimaryPush && c.WindowOver == null) || c.PrimaryClick) { if (c.WindowPushed != null) { c.WindowPushed = null; } } c.Update(TimeManager.CurrentTime); c.WindowOver = null; c.WindowClosing = null; } UpdateDependencies(); // now we find which button we are over with each cursor ElementActivity(); #region Loop through cursors and perform collision and action vs. Windows foreach (Cursor c in mCursors) { if (c.Active) { #region looping through all perishable windows for (int i = mPerishableArray.Count - 1; i > -1; i--) { IWindow window = mPerishableArray[i]; if (c.IsOn(window)) { window.TestCollision(c); } else if (c.PrimaryClick || c.SecondaryClick) { if (mPerishableWindowsToSurviveClick.Contains(window)) { mPerishableWindowsToSurviveClick.Remove(window); } else { window.Visible = false; mPerishableArray.RemoveAt(i); } } } #endregion #region if we have a dominant window if (DominantWindowActive && c.WindowOver == null) { for (int i = mDominantWindows.Count - 1; i > -1; i--) { IWindow dominantWindow = mDominantWindows[i]; if (dominantWindow.Visible && c.IsOnWindowOrFloatingChildren(dominantWindow)) { dominantWindow.TestCollision(c); } } // If there are any dominant windows, we shouldn't perform any other collision tests continue; } #endregion #region looping through all regular windows if (c.WindowOver == null) { for (int i = mWindowArray.Count - 1; i > -1; i--) { // Code in this loop can call // events. Events may destroy // entire groups of Windows, so we // need to make sure we're still vaild: if (i < mWindowArray.Count) { var window = mWindowArray[i]; // December 3, 2017 // The GuiManager used // to continue the loop // if UI was disabled, but // that means that UI could // be clicked-through. We don't // want that, so we only continue // if the UI is invisible. It's now // the job of the IWindow implementation // to check its own Enabled to figure out // if it should process events or not... //if (window.Visible == false || !window.Enabled) if (window.Visible == false) { continue; } if (!window.IgnoredByCursor && window.HasCursorOver(c)) { window.TestCollision(c); // HasCursorOver simply says "Is the cursor over this object". // You could be over an object but the object may not be enabled UI, // so we should only break the loop if WindowOver was actually assigned: if (c.WindowOver != null) { c.LastWindowOver = c.WindowOver; if (Cursor.PrimaryPush && i < mWindowArray.Count && BringsClickedWindowsToFront == true) {// we pushed a button, so let's bring it to the front mWindowArray.Remove(window); mWindowArray.Add(window); } break; } } } } } #endregion } } #endregion #region call onLosingFocus if (Cursor.PrimaryPush)// && guiResult.windowResult != null) { // Should this be on a per-cursor basis? if (mLastWindowWithFocus != null && mLastWindowWithFocus != Cursor.WindowOver) { mLastWindowWithFocus.OnLosingFocus(); #if SUPPORTS_FRB_DRAWN_GUI UpDownReactToCursorPush(); #endif } mLastWindowWithFocus = Cursor.WindowOver; } #endregion #region If not on anything, set cursor.LastWindowOver to null // Should this be on a per-cursor basis? if (Cursor.WindowOver == null) { Cursor.LastWindowOver = null; } #endregion #region if receivingInput setting and resetting logic foreach (Cursor c in mCursors) { if (c.Active && c.PrimaryClick == true) { FlatRedBall.Gui.IInputReceiver objectClickedOn = c.WindowOver as IInputReceiver; #if SUPPORTS_FRB_DRAWN_GUI UpDownReactToPrimaryClick(c, ref objectClickedOn); #endif #region Check for ReceivingInput being set to null if (InputManager.ReceivingInputJustSet == false && objectClickedOn == null) { #if SUPPORTS_FRB_DRAWN_GUI bool shouldLoseInput = true; if (InputManager.ReceivingInput != null && InputManager.ReceivingInput is TextBox && c.WindowPushed == InputManager.ReceivingInput) { shouldLoseInput = false; } if (shouldLoseInput) { InputManager.ReceivingInput = null; } #endif } #endregion else if (objectClickedOn != null && ((IWindow)objectClickedOn).Visible == true && ((IInputReceiver)objectClickedOn).TakingInput) { InputManager.InputReceiver = objectClickedOn; } } } #endregion #region letting go of any grabbed window if (Cursor.PrimaryClick) { Cursor.WindowGrabbed = null; Cursor.mSidesGrabbed = Sides.None; } #endregion #region Remove invisible Dominant Windows while (mDominantWindows.Count > 0 && mDominantWindows[mDominantWindows.Count - 1].Visible == false && RemoveInvisibleDominantWindows) { mDominantWindows.RemoveAt(mDominantWindows.Count - 1); } #endregion #region Clear the mPerishableWindowsToSurviveClick mPerishableWindowsToSurviveClick.Clear(); #endregion }
public static void Control() { #if PROFILE TimeManager.TimeSection("Object Display Manager Activity"); #endif InputManager.ReceivingInputJustSet = false; mToolTipText = ""; #region Update cursors foreach (Cursor c in mCursors) { #region SET CURSOR WINDOWPUSHED and WindowMiddleButtonPushed TO NULL if we push or click on something that is not a window // Do this before the activity so on a click the frame with the click will still have a valid // WindowPushed. if ((c.PrimaryPush && c.WindowOver == null) || c.PrimaryClick) { if (c.WindowPushed != null) { c.WindowPushed = null; } } #endregion c.Update(TimeManager.CurrentTime); c.WindowOver = null; c.WindowClosing = null; } #endregion UpdateDependencies(); // now we find which button we are over with each cursor ElementActivity(); #region Loop through cursors and perform collision and action vs. Windows foreach (Cursor c in mCursors) { if (c.Active) { #region looping through all perishable windows for (int i = mPerishableArray.Count - 1; i > -1; i--) { IWindow window = mPerishableArray[i]; if (c.IsOn(window)) { window.TestCollision(c); } else if (c.PrimaryClick || c.SecondaryClick) { if (mPerishableWindowsToSurviveClick.Contains(window)) { mPerishableWindowsToSurviveClick.Remove(window); } else { window.Visible = false; mPerishableArray.RemoveAt(i); } } } #endregion #region if we have a dominant window if (DominantWindowActive && c.WindowOver == null) { for (int i = mDominantWindows.Count - 1; i > -1; i--) { IWindow dominantWindow = mDominantWindows[i]; if (dominantWindow.Visible && c.IsOnWindowOrFloatingChildren(dominantWindow)) { dominantWindow.TestCollision(c); } } // If there are any dominant windows, we shouldn't perform any other collision tests continue; } #endregion #region looping through all regular windows // First check all floating windows else if (c.WindowOver == null) { for (int i = mWindowArray.Count - 1; i > -1; i--) { if (!mWindowArray[i].GuiManagerDrawn || mWindowArray[i].Visible == false || !mWindowArray[i].Enabled) { continue; } IWindow windowOver = c.GetDeepestFloatingChildWindowOver(mWindowArray[i]); IWindow tempWindow = mWindowArray[i]; if (windowOver != null) { windowOver.TestCollision(c); if (c.PrimaryPush && i < mWindowArray.Count) {// we pushed a button, so let's bring it to the front mWindowArray.Remove(tempWindow); mWindowArray.Add(tempWindow); } break; } } } if (c.WindowOver == null) { for (int i = mWindowArray.Count - 1; i > -1; i--) { // Code in this loop can call // events. Events may destroy // entire groups of Windows, so we // need to make sure we're still vaild: if (i < mWindowArray.Count) { var window = mWindowArray[i]; if (window.Visible == false || !window.Enabled) { continue; } if (window.GuiManagerDrawn) { if (c.IsOn(window)) { window.TestCollision(c); if (c.PrimaryPush && i < mWindowArray.Count) {// we pushed a button, so let's bring it to the front // Man, what a bug. It's possible // that clicking one window will bring // another to the foreground. If so, then // the index is no longer valid. Typical unnecessary // optimization causing all kinds of problems. //mWindowArray.RemoveAt(i); mWindowArray.Remove(window); mWindowArray.Add(window); } break; } } else if (!window.IgnoredByCursor && window.HasCursorOver(c)) { window.TestCollision(c); // I think we should use the cursor's WindowOver which may be a child of Window c.LastWindowOver = c.WindowOver; if (Cursor.PrimaryPush && i < mWindowArray.Count && BringsClickedWindowsToFront == true) {// we pushed a button, so let's bring it to the front mWindowArray.Remove(window); mWindowArray.Add(window); } break; } } } } #endregion } } #endregion #region call onLosingFocus if (Cursor.PrimaryPush)// && guiResult.windowResult != null) { // Should this be on a per-cursor basis? if (mLastWindowWithFocus != null && mLastWindowWithFocus != Cursor.WindowOver) { mLastWindowWithFocus.OnLosingFocus(); #if SUPPORTS_FRB_DRAWN_GUI UpDownReactToCursorPush(); #endif } mLastWindowWithFocus = Cursor.WindowOver; } #endregion #region If not on anything, set cursor.LastWindowOver to null // Should this be on a per-cursor basis? if (Cursor.WindowOver == null) { Cursor.LastWindowOver = null; } #endregion #region if receivingInput setting and resetting logic foreach (Cursor c in mCursors) { if (c.Active && c.PrimaryClick == true) { FlatRedBall.Gui.IInputReceiver objectClickedOn = c.WindowOver as IInputReceiver; #if SUPPORTS_FRB_DRAWN_GUI UpDownReactToPrimaryClick(c, ref objectClickedOn); #endif #region Check for ReceivingInput being set to null if (InputManager.ReceivingInputJustSet == false && objectClickedOn == null) { #if SUPPORTS_FRB_DRAWN_GUI bool shouldLoseInput = true; if (InputManager.ReceivingInput != null && InputManager.ReceivingInput is TextBox && c.WindowPushed == InputManager.ReceivingInput) { shouldLoseInput = false; } if (shouldLoseInput) { InputManager.ReceivingInput = null; } #endif } #endregion else if (objectClickedOn != null && ((IWindow)objectClickedOn).Visible == true && ((IInputReceiver)objectClickedOn).TakingInput) { InputManager.InputReceiver = objectClickedOn; } } } #endregion #if SUPPORTS_FRB_DRAWN_GUI LoseInputOnTextBox(tempTextBox); #endif #region letting go of any grabbed window if (Cursor.PrimaryClick) { Cursor.mWindowGrabbed = null; Cursor.mSidesGrabbed = Sides.None; } #endregion #region regulate button and toggle button up/down states depending on if the cursor is still over the button pushed if (Cursor.WindowPushed != null && Cursor.WindowOver != Cursor.WindowPushed) { #if SUPPORTS_FRB_DRAWN_GUI ButtonReactToPush(); #endif } #endregion #region Remove invisible Dominant Windows while (mDominantWindows.Count > 0 && mDominantWindows[mDominantWindows.Count - 1].Visible == false && RemoveInvisibleDominantWindows) { mDominantWindows.RemoveAt(mDominantWindows.Count - 1); } #endregion #region Clear the mPerishableWindowsToSurviveClick mPerishableWindowsToSurviveClick.Clear(); #endregion }