diff --git a/.editorconfig b/.editorconfig index 55820fb6..d108df48 100644 --- a/.editorconfig +++ b/.editorconfig @@ -18,7 +18,7 @@ csharp_new_line_before_else = true #require members of object initializers to be on the same line csharp_new_line_before_members_in_object_initializers = false #require braces to be on a new line for lambdas, control_blocks, types, properties, accessors, and methods (also known as "Allman" style) -csharp_new_line_before_open_brace = lambdas, control_blocks, types, properties, accessors, methods +csharp_new_line_before_open_brace = lambdas, control_blocks, types, accessors, methods #Formatting - organize using options @@ -49,7 +49,7 @@ csharp_space_between_method_declaration_parameter_list_parentheses = false #Formatting - wrapping options #leave code block on separate lines -csharp_preserve_single_line_blocks = false +csharp_preserve_single_line_blocks = true #leave statements and member declarations on the same line csharp_preserve_single_line_statements = true diff --git a/Docs/todo.md b/Docs/todo.md index 89cfb3ce..b1566f65 100644 --- a/Docs/todo.md +++ b/Docs/todo.md @@ -1,6 +1,5 @@ # priority stuff -- gizmo stuff - undo bug - stats bugs - getinfo @@ -50,8 +49,6 @@ ## Scale Gizmo -- [ ] support arrow keys - # Backwards Compatibilty - [ ] make sure we can load crafts saved with TS/L @@ -216,6 +213,7 @@ - [x] gizmo: clamp min/max sizes - [x] use angle snap and shift to control snapping to step intervals - [x] on-screen message showing current scale (like fairings) +- [x] support arrow keys ====== diff --git a/Source/ConstructionModeScale.cs b/Source/ConstructionModeScale.cs index 435eea7e..5d8212c6 100644 --- a/Source/ConstructionModeScale.cs +++ b/Source/ConstructionModeScale.cs @@ -267,10 +267,8 @@ private void onScaleGizmoHandleDragStart(GizmoOffsetHandle handle, Vector3 axis) previousScaleFactor = tweakScaleModule.currentScaleFactor; } - private void onScaleGizmoHandleDrag(GizmoOffsetHandle handle, Vector3 axis, float amount) + static ScaleFactorSnapMode GetScaleSnapMode() { - var tweakScaleModule = selectedPart.FindModuleImplementing(); - float newScaleFactor = previousScaleFactor + amount; ScaleFactorSnapMode snapMode = ScaleFactorSnapMode.None; if (GameSettings.VAB_USE_ANGLE_SNAP) @@ -278,7 +276,14 @@ private void onScaleGizmoHandleDrag(GizmoOffsetHandle handle, Vector3 axis, floa snapMode = GameSettings.Editor_fineTweak.GetKey() ? ScaleFactorSnapMode.FineSteps : ScaleFactorSnapMode.CoarseSteps; } - tweakScaleModule.SetScaleFactor(newScaleFactor, snapMode); + return snapMode; + } + + private void onScaleGizmoHandleDrag(GizmoOffsetHandle handle, Vector3 axis, float amount) + { + var tweakScaleModule = selectedPart.FindModuleImplementing(); + float newScaleFactor = previousScaleFactor + amount; + tweakScaleModule.SetScaleFactor(newScaleFactor, GetScaleSnapMode()); } private void onScaleGizmoUpdated(Vector3 arg1) @@ -293,6 +298,7 @@ private void onScaleGizmoUpdated(Vector3 arg1) private void partscaleInputUpdate() { + // hook up events if necessary if (gizmoScale.useGrid) { foreach (var handle in gizmoScale.handles) @@ -309,28 +315,45 @@ private void partscaleInputUpdate() $"Scale: {tweakScaleModule.GetScaleString()}\n" + $"[{GameSettings.Editor_toggleAngleSnap.name}] Toggle Snap\n" + $"[{GameSettings.Editor_fineTweak.name}] Fine control\n" + + $"[{TweakScaleEditorLogic.Instance.IncreaseScaleKey}/{TweakScaleEditorLogic.Instance.DecreaseScaleKey}] Inc/Dec Scale\n" + + $"[{TweakScaleEditorLogic.Instance.NextScaleIntervalKey}/{TweakScaleEditorLogic.Instance.PrevScaleIntervalKey}] Next/Prev Scale\n" + $"[{GameSettings.Editor_resetRotation.name}] Reset"; ScreenMessages.PostScreenMessage(message, 0f, ScreenMessageStyle.LOWER_CENTER); KerbalFSM fsm = EditorLogic.fetch.fsm; - // did we press the reset button? - if (InputLockManager.IsUnlocked(ControlTypes.EDITOR_GIZMO_TOOLS) && GameSettings.Editor_resetRotation.GetKeyDown() && selectedPart.transform == selectedPart.GetReferenceTransform()) + if (InputLockManager.IsUnlocked(ControlTypes.EDITOR_GIZMO_TOOLS)) { - tweakScaleModule.SetScaleFactor(1.0f); - - //srfAttachCursorOffset = Vector3.zero; - //if (symUpdateMode != 0) - //{ - // UpdateSymmetry(selectedPart, symUpdateMode, symUpdateParent, symUpdateAttachNode); - //} + int incrementDirection = Input.GetKeyDown(TweakScaleEditorLogic.Instance.IncreaseScaleKey).GetHashCode() - Input.GetKeyDown(TweakScaleEditorLogic.Instance.DecreaseScaleKey).GetHashCode(); + if (incrementDirection != 0) + { + tweakScaleModule.IncrementScaleFactor(incrementDirection, GetScaleSnapMode()); + } - if (fsm.CurrentState == st_scale_tweak) + int jumpDirection = Input.GetKeyDown(TweakScaleEditorLogic.Instance.NextScaleIntervalKey).GetHashCode() - Input.GetKeyDown(TweakScaleEditorLogic.Instance.PrevScaleIntervalKey).GetHashCode(); + if (jumpDirection != 0) { - fsm.RunEvent(on_scaleReset); + tweakScaleModule.JumpScaleFactor(jumpDirection); } - //GameEvents.onEditorPartEvent.Fire(ConstructionEventType.PartOffset, selectedPart); + // did we press the reset button? + if (GameSettings.Editor_resetRotation.GetKeyDown() && selectedPart.transform == selectedPart.GetReferenceTransform()) + { + tweakScaleModule.SetScaleFactor(1.0f); + + //srfAttachCursorOffset = Vector3.zero; + //if (symUpdateMode != 0) + //{ + // UpdateSymmetry(selectedPart, symUpdateMode, symUpdateParent, symUpdateAttachNode); + //} + + if (fsm.CurrentState == st_scale_tweak) + { + fsm.RunEvent(on_scaleReset); + } + + //GameEvents.onEditorPartEvent.Fire(ConstructionEventType.PartOffset, selectedPart); + } } //Part part = null; diff --git a/Source/ModuleTweakScale.cs b/Source/ModuleTweakScale.cs index 38ad1789..84fb62ef 100644 --- a/Source/ModuleTweakScale.cs +++ b/Source/ModuleTweakScale.cs @@ -877,6 +877,39 @@ internal string GetScaleString() } } + void GetIntervalInfo(ScaleFactorSnapMode snapMode, float scaleValue, bool preferLower, out float min, out float max, out float step) + { + int intervalIndex = Tools.FindIntervalIndex(scaleValue, ScaleFactors, preferLower); + + min = ScaleFactors[intervalIndex]; + max = ScaleFactors[intervalIndex + 1]; + step = ScaleType.IncrementSlide[intervalIndex]; + if (step > 0f) + { + if (snapMode == ScaleFactorSnapMode.CoarseSteps) + { + int numSteps = (int)Mathf.Round((max - min) / step); + + if (numSteps % 10 == 0) + { + step = (max - min) / 10; + } + else if (numSteps % 5 == 0) + { + step = (max - min) / 5; + } + else if (numSteps % 4 == 0) + { + step = (max - min) / 4; + } + else if (numSteps % 2 == 0) + { + step = (max - min) / 2; + } + } + } + } + internal void SetScaleFactor(float scaleFactor, ScaleFactorSnapMode snapMode = ScaleFactorSnapMode.None) { float newGuiScaleValue = scaleFactor * guiDefaultScale; @@ -889,36 +922,14 @@ internal void SetScaleFactor(float scaleFactor, ScaleFactorSnapMode snapMode = S if (snapMode != ScaleFactorSnapMode.None && ScaleFactors.Length >= 2) { - int intervalIndex = Tools.FindIntervalIndex(newGuiScaleValue, ScaleFactors); + bool decreasing = scaleFactor < currentScaleFactor; + GetIntervalInfo(snapMode, newGuiScaleValue, decreasing, out float min, out float max, out float step); - float min = ScaleFactors[intervalIndex]; - float max = ScaleFactors[intervalIndex + 1]; - float step = ScaleType.IncrementSlide[intervalIndex]; - if (step > 0f) + newGuiScaleValue = min + (float)Math.Round((newGuiScaleValue - min) / step) * step; + + if (Mathf.Approximately(newGuiScaleValue, max)) { - if (snapMode == ScaleFactorSnapMode.CoarseSteps) - { - int numSteps = (int)Mathf.Round((max - min) / step); - - if (numSteps % 10 == 0) - { - step = (max - min) / 10; - } - else if (numSteps % 5 == 0) - { - step = (max - min) / 5; - } - else if (numSteps % 4 == 0) - { - step = (max - min) / 4; - } - else if (numSteps % 2 == 0) - { - step = (max - min) / 2; - } - } - - newGuiScaleValue = min + (float)Math.Round((newGuiScaleValue - min) / step) * step; + newGuiScaleValue = max; } } } @@ -935,6 +946,42 @@ internal void SetScaleFactor(float scaleFactor, ScaleFactorSnapMode snapMode = S OnTweakScaleChanged(GetScaleFactorFromGUI()); UpdatePartActionWindow(true); } + + internal void IncrementScaleFactor(int incrementDirection, ScaleFactorSnapMode snapMode) + { + if (isFreeScale) + { + float incrementAmount = 0.01f * incrementDirection; + + if (snapMode != ScaleFactorSnapMode.None && ScaleFactors.Length >= 2) + { + bool decreasing = incrementDirection < 0; + GetIntervalInfo(snapMode, guiScaleValue, decreasing, out float min, out float max, out float step); + incrementAmount = step * incrementDirection / guiDefaultScale; + } + + SetScaleFactor(currentScaleFactor + incrementAmount, snapMode); + } + else + { + JumpScaleFactor(incrementDirection); + } + } + + internal void JumpScaleFactor(int jumpDirection) + { + // if we're in the middle of an interval and jumpDirection is negative, we want to just go to the current interval + // but if it's right on the boundary, go to the previous one (which will be returned from FindIntervalIndex by passing true as preferLower) + int intervalIndex = Tools.FindIntervalIndex(guiScaleValue, ScaleFactors, jumpDirection < 0); + if (jumpDirection > 0) + { + intervalIndex++; + } + + intervalIndex = Mathf.Clamp(intervalIndex, 0, ScaleFactors.Length - 1); + + SetScaleFactor(ScaleFactors[intervalIndex] / guiDefaultScale); + } } internal enum ScaleFactorSnapMode diff --git a/Source/Tools.cs b/Source/Tools.cs index bec70d14..c442f355 100644 --- a/Source/Tools.cs +++ b/Source/Tools.cs @@ -62,14 +62,16 @@ public static int ClosestIndex(float x, IEnumerable values) return result; } - public static int FindIntervalIndex(float value, float[] intervals) + public static int FindIntervalIndex(float value, float[] intervals, bool preferLower) { for (int index = 0; index < intervals.Length - 1; ++index) { if (value < intervals[index + 1]) return index; + // if we're right on the boundary, the caller decides which interval + if (Mathf.Approximately(value, intervals[index + 1]) && preferLower) return index; } - return intervals.Length - 1; + return intervals.Length - 2; } private static string BuildLogString(string format, object[] args) diff --git a/Source/TweakScaleEditorLogic.cs b/Source/TweakScaleEditorLogic.cs index 17ecf61a..e2013d53 100644 --- a/Source/TweakScaleEditorLogic.cs +++ b/Source/TweakScaleEditorLogic.cs @@ -14,6 +14,11 @@ internal class TweakScaleEditorLogic : SingletonBehavior PluginConfiguration _config; HotkeyManager _hotkeyManager; + public KeyCode IncreaseScaleKey { get; private set; } = KeyCode.W; + public KeyCode DecreaseScaleKey { get; private set; } = KeyCode.S; + public KeyCode NextScaleIntervalKey { get; private set; } = KeyCode.D; + public KeyCode PrevScaleIntervalKey { get; private set; } = KeyCode.A; + public Hotkeyable ScaleChildren { get; private set; } public Hotkeyable MatchNodeSize { get; private set; } @@ -46,6 +51,11 @@ void Start() _hotkeyManager = new HotkeyManager(_config); + IncreaseScaleKey = _config.GetValue(nameof(IncreaseScaleKey), IncreaseScaleKey); + DecreaseScaleKey = _config.GetValue(nameof(DecreaseScaleKey), DecreaseScaleKey); + NextScaleIntervalKey = _config.GetValue(nameof(NextScaleIntervalKey), NextScaleIntervalKey); + PrevScaleIntervalKey = _config.GetValue(nameof(PrevScaleIntervalKey), PrevScaleIntervalKey); + ScaleChildren = _hotkeyManager.AddHotkey("Scale Children", KeyCode.LeftControl, new[] { KeyCode.K }, true); MatchNodeSize = _hotkeyManager.AddHotkey("Match Node Size", KeyCode.LeftControl, new[] { KeyCode.M }, true);