Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change input locks to fix map spin, Fixes #2126 #2403

Merged
merged 1 commit into from
Jan 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions src/kOS/Screen/GUIWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,7 @@ void OnHideUI()
void OnShowUI()
{
uiGloballyHidden = false;
}

public override void GetFocus()
{
}

public override void LoseFocus()
{
}
}

public override void Open()
{
Expand Down
34 changes: 27 additions & 7 deletions src/kOS/Screen/KOSManagedWindow.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;

namespace kOS.Screen
Expand All @@ -13,7 +13,7 @@ namespace kOS.Screen
public abstract class KOSManagedWindow : MonoBehaviour
{
// The static values are for the way the windows keep track of each other:

// Give each instance of TermWindow a unique ID block to ensure it can create
// Unity windows that don't clash:
private static int termWindowIDRange = 215300; // I literally just mashed the keyboard to get a unique number.
Expand Down Expand Up @@ -43,11 +43,18 @@ public abstract class KOSManagedWindow : MonoBehaviour

private bool isOpen;

protected KOSManagedWindow()
private string lockIdName;

protected KOSManagedWindow(string lockIdName = "")
{
// multiply by 50 so there's a range for future expansion for other GUI objects inside the window:
uniqueId = termWindowIDRange + (windowsMadeSoFar * 50);
++windowsMadeSoFar;
++windowsMadeSoFar;
// When the lockIdName is not given, then manufacture a unique one:
if (lockIdName.Length == 0)
this.lockIdName = "KOSManagedWindow ID:" + uniqueId;
else
this.lockIdName = lockIdName;
}

public bool IsPowered { get; set; }
Expand Down Expand Up @@ -130,14 +137,27 @@ protected Vector2 MouseButtonDownPosRelative


/// <summary>
/// Implement this for how to make your widget get the keyboard focus:
/// Implement this for how to make your widget get the keyboard focus.
/// It is VITAL that if you override this method in a derived class,
/// that you also call this base version in that overridden method. Otherwise
/// you will get the map view spinning bug when the focus is in this window.
/// </summary>
public abstract void GetFocus();
public virtual void GetFocus()
{
if (HighLogic.LoadedSceneIsFlight || HighLogic.LoadedSceneHasPlanetarium)
InputLockManager.SetControlLock(ControlTypes.ALLBUTCAMERAS, lockIdName);
}

/// <summary>
/// Implement this for how to make your widget give up the keyboard focus:
/// It is VITAL that if you override this method in a derived class,
/// that you also call this base version in that overridden method. Otherwise
/// you will get the map view spinning bug when the focus is in this window.
/// </summary>
public abstract void LoseFocus();
public virtual void LoseFocus()
{
InputLockManager.RemoveControlLock(lockIdName);
}

/// <summary>
/// Implement this to make the window appear when it wasn't there before.
Expand Down
10 changes: 5 additions & 5 deletions src/kOS/Screen/TermWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace kOS.Screen
// Blockotronix 550 Computor Monitor
public class TermWindow : KOSManagedWindow , ITermWindow
{
private const string CONTROL_LOCKOUT = "kOSTerminal";
public const string CONTROL_LOCKOUT = "kOSTerminal";

/// <summary>
/// Set to true only when compiling a version specifically for the purpose
Expand Down Expand Up @@ -259,11 +259,13 @@ void OnShowUI()

public override void GetFocus()
{
base.GetFocus();
Lock();
}

public override void LoseFocus()
{
base.LoseFocus();
Unlock();
}

Expand Down Expand Up @@ -322,9 +324,7 @@ private void Lock()
BringToFront();


// Exclude the TARGETING ControlType so that we can set the target vessel with the terminal open.
InputLockManager.SetControlLock(ControlTypes.All & ~ControlTypes.TARGETING, CONTROL_LOCKOUT);

InputLockManager.SetControlLock(ControlTypes.All, CONTROL_LOCKOUT);
// Prevent editor keys from being pressed while typing
EditorLogic editor = EditorLogic.fetch;
//TODO: POST 0.90 REVIEW
Expand Down
19 changes: 19 additions & 0 deletions src/kOS/Utilities/VesselUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,26 @@ public static void SetTarget(ITargetable val, Vessel currentVessel)
else if (val.GetVessel() == currentVessel)
throw new Safe.Exceptions.KOSInvalidTargetException("A ship cannot set TARGET to a part of itself.");

// If any kOS terminal (not just the one this CPU uses as its Shared.Window, but ANY kOS terminal
// from any kOS CPU) is the focused window right now, causing input lockouts, we must
// temporarily turn off that input lock in order for the main game allow the SetVesselTarget()
// call in the lines below to perform its task fully:
//
// Note the preferred solution would be to walk all control locks and suppress *any* that are turning
// off the targeting, regardless of whether they're kOS or not, but InputLockManager does not provide
// any methods for iteratinng the collection of all control lock masks, and it's also not possible to turn
// a lock OFF by masking it with a new control lock, since all the locks in the stack are OR'ed together.)

ControlTypes termInputLock = InputLockManager.GetControlLock(Screen.TermWindow.CONTROL_LOCKOUT);
// (Note, KSP returns ControlTypes.None rather than null when no such lock was found, because it's
// a non-nullable enum)
if (termInputLock != ControlTypes.None)
InputLockManager.RemoveControlLock(Screen.TermWindow.CONTROL_LOCKOUT);

FlightGlobals.fetch.SetVesselTarget(val, true);

if (termInputLock != ControlTypes.None)
InputLockManager.SetControlLock(termInputLock, Screen.TermWindow.CONTROL_LOCKOUT);
}

public static float AngleDelta(float a, float b)
Expand Down