diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 5d5b835c23..5671d47185 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -673,7 +673,10 @@ namespace OpenRA // World rendering is disabled while the loading screen is displayed if (worldRenderer != null && !worldRenderer.World.IsLoadingGameSave) + { + worldRenderer.Viewport.Tick(); worldRenderer.PrepareRenderables(); + } Ui.PrepareRenderables(); Renderer.WorldModelRenderer.EndFrame(); diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index 3d5bfcf5ed..e39a801d69 100644 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -36,6 +36,8 @@ namespace OpenRA.Graphics public class Viewport { readonly WorldRenderer worldRenderer; + readonly WorldViewportSizes viewportSizes; + readonly GraphicSettings graphicSettings; // Map bounds (world-px) readonly Rectangle mapBounds; @@ -55,14 +57,16 @@ namespace OpenRA.Graphics ProjectedCellRegion allCells; bool allCellsDirty = true; - readonly float[] availableZoomSteps = new[] { 2f, 1f, 0.5f, 0.25f }; + + WorldViewport lastViewportDistance; float zoom = 1f; + float minZoom = 1f; + float maxZoom = 2f; - public float[] AvailableZoomSteps - { - get { return availableZoomSteps; } - } + bool unlockMinZoom; + float unlockedMinZoomScale; + float unlockedMinZoom = 1f; public float Zoom { @@ -71,16 +75,37 @@ namespace OpenRA.Graphics return zoom; } - set + private set { - var newValue = ClosestTo(AvailableZoomSteps, value); - zoom = newValue; + zoom = value; viewportSize = (1f / zoom * new float2(Game.Renderer.Resolution)).ToInt2(); cellsDirty = true; allCellsDirty = true; } } + public void AdjustZoom(float dz) + { + // Exponential ensures that equal positive and negative steps have the same effect + Zoom = (zoom * (float)Math.Exp(dz)).Clamp(unlockMinZoom ? unlockedMinZoom : minZoom, maxZoom); + } + + public void ToggleZoom() + { + // Unlocked zooms always reset to the default zoom + if (zoom < minZoom) + Zoom = minZoom; + else + Zoom = zoom > minZoom ? minZoom : maxZoom; + } + + public void UnlockMinimumZoom(float scale) + { + unlockMinZoom = true; + unlockedMinZoomScale = scale; + UpdateViewportZooms(false); + } + public static long LastMoveRunTime = 0; public static int2 LastMousePos; @@ -120,6 +145,8 @@ namespace OpenRA.Graphics { worldRenderer = wr; var grid = Game.ModData.Manifest.Get(); + viewportSizes = Game.ModData.Manifest.Get(); + graphicSettings = Game.Settings.Graphics; // Calculate map bounds in world-px if (wr.World.Type == WorldType.Editor) @@ -141,8 +168,75 @@ namespace OpenRA.Graphics CenterLocation = (tl + br) / 2; } - Zoom = Game.Settings.Graphics.PixelDouble ? 2 : 1; tileSize = grid.TileSize; + + UpdateViewportZooms(); + } + + public void Tick() + { + if (lastViewportDistance != graphicSettings.ViewportDistance) + UpdateViewportZooms(); + } + + float CalculateMinimumZoom(float minHeight, float maxHeight) + { + var h = Game.Renderer.Resolution.Height; + + // Check the easy case: the native resolution is within the maximum limit + // Also catches the case where the user may force a resolution smaller than the minimum window size + if (h <= maxHeight) + return 1; + + // Find a clean fraction that brings us within the desired range to reduce aliasing + var step = 1f; + while (true) + { + var testZoom = 1f; + while (true) + { + var nextZoom = testZoom + step; + if (h < minHeight * nextZoom) + break; + + testZoom = nextZoom; + } + + if (h < maxHeight * testZoom) + return testZoom; + + step /= 2; + } + } + + void UpdateViewportZooms(bool resetCurrentZoom = true) + { + lastViewportDistance = graphicSettings.ViewportDistance; + + var vd = graphicSettings.ViewportDistance; + if (viewportSizes.AllowNativeZoom && vd == WorldViewport.Native) + minZoom = 1; + else + { + var range = viewportSizes.GetSizeRange(vd); + minZoom = CalculateMinimumZoom(range.X, range.Y); + } + + maxZoom = Math.Min(minZoom * viewportSizes.MaxZoomScale, Game.Renderer.Resolution.Height * 1f / viewportSizes.MaxZoomWindowHeight); + + if (unlockMinZoom) + { + // Specators and the map editor support zooming out by an extra factor of two. + // TODO: Allow zooming out until the full map is visible + // We need to improve our viewport scroll handling to center the map as we zoom out + // before this will work well enough to enable + unlockedMinZoom = minZoom * unlockedMinZoomScale; + } + + if (resetCurrentZoom) + Zoom = minZoom; + else + Zoom = Zoom.Clamp(minZoom, maxZoom); } public CPos ViewToWorld(int2 view) diff --git a/OpenRA.Game/Settings.cs b/OpenRA.Game/Settings.cs index 8c9d5be9c7..55fc2559f5 100644 --- a/OpenRA.Game/Settings.cs +++ b/OpenRA.Game/Settings.cs @@ -13,7 +13,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using OpenRA.Graphics; using OpenRA.Primitives; using OpenRA.Traits; @@ -34,6 +33,8 @@ namespace OpenRA Incompatible = 16 } + public enum WorldViewport { Native, Close, Medium, Far } + public class ServerSettings { [Desc("Sets the server name.")] @@ -145,8 +146,8 @@ namespace OpenRA public bool HardwareCursors = true; - public bool PixelDouble = false; public bool CursorDouble = false; + public WorldViewport ViewportDistance = WorldViewport.Medium; [Desc("Add a frame rate limiter. It is recommended to not disable this.")] public bool CapFramerate = true; @@ -207,6 +208,7 @@ namespace OpenRA public MouseButtonPreference MouseButtonPreference = new MouseButtonPreference(); public float ViewportEdgeScrollStep = 30f; public float UIScrollSpeed = 50f; + public float ZoomSpeed = 0.04f; public int SelectionDeadzone = 24; public int MouseScrollDeadzone = 8; @@ -220,8 +222,7 @@ namespace OpenRA [Desc("Filename of the authentication profile to use.")] public string AuthProfile = "player.oraid"; - public bool AllowZoom = true; - public Modifiers ZoomModifier = Modifiers.Ctrl; + public Modifiers ZoomModifier = Modifiers.None; public bool FetchNews = true; diff --git a/OpenRA.Game/WorldViewportSizes.cs b/OpenRA.Game/WorldViewportSizes.cs new file mode 100644 index 0000000000..469904462a --- /dev/null +++ b/OpenRA.Game/WorldViewportSizes.cs @@ -0,0 +1,33 @@ +#region Copyright & License Information +/* + * Copyright 2007-2019 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System.Collections.Generic; + +namespace OpenRA +{ + public class WorldViewportSizes : IGlobalModData + { + public readonly int2 CloseWindowHeights = new int2(480, 600); + public readonly int2 MediumWindowHeights = new int2(600, 900); + public readonly int2 FarWindowHeights = new int2(900, 1300); + + public readonly float MaxZoomScale = 2.0f; + public readonly int MaxZoomWindowHeight = 240; + public readonly bool AllowNativeZoom = true; + + public int2 GetSizeRange(WorldViewport distance) + { + return distance == WorldViewport.Close ? CloseWindowHeights + : distance == WorldViewport.Medium ? MediumWindowHeights + : FarWindowHeights; + } + } +} diff --git a/OpenRA.Mods.Common/Widgets/EditorViewportControllerWidget.cs b/OpenRA.Mods.Common/Widgets/EditorViewportControllerWidget.cs index 329571fd33..9dab7f1f89 100644 --- a/OpenRA.Mods.Common/Widgets/EditorViewportControllerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/EditorViewportControllerWidget.cs @@ -39,6 +39,9 @@ namespace OpenRA.Mods.Common.Widgets editorActionManager = world.WorldActor.Trait(); editorActionManager.OnChange += EditorActionManagerOnChange; + + // Allow zooming out to full map size + worldRenderer.Viewport.UnlockMinimumZoom(0.25f); } void EditorActionManagerOnChange() @@ -80,26 +83,11 @@ namespace OpenRA.Mods.Common.Widgets tooltipContainer.Value.RemoveTooltip(); } - void Zoom(int amount) - { - var zoomSteps = worldRenderer.Viewport.AvailableZoomSteps; - var currentZoom = worldRenderer.Viewport.Zoom; - - var nextIndex = zoomSteps.IndexOf(currentZoom) - amount; - if (nextIndex < 0 || nextIndex >= zoomSteps.Length) - return; - - var zoom = zoomSteps[nextIndex]; - Parent.Get("ZOOM_BUTTON").SelectedItem = zoom.ToString(); - worldRenderer.Viewport.Zoom = zoom; - } - public override bool HandleMouseInput(MouseInput mi) { - if (mi.Event == MouseInputEvent.Scroll && - Game.Settings.Game.AllowZoom && mi.Modifiers.HasModifier(Game.Settings.Game.ZoomModifier)) + if (mi.Event == MouseInputEvent.Scroll && mi.Modifiers.HasModifier(Game.Settings.Game.ZoomModifier)) { - Zoom(mi.Delta.Y); + worldRenderer.Viewport.AdjustZoom(mi.Delta.Y * Game.Settings.Game.ZoomSpeed); return true; } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorLogic.cs index b3ccf77b49..6943e35d29 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorLogic.cs @@ -25,13 +25,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic MapCopyFilters copyFilters = MapCopyFilters.All; [ObjectCreator.UseCtor] - public MapEditorLogic(Widget widget, ModData modData, World world, WorldRenderer worldRenderer, Dictionary logicArgs) + public MapEditorLogic(Widget widget, World world, WorldRenderer worldRenderer) { - MiniYaml yaml; - var changeZoomKey = new HotkeyReference(); - if (logicArgs.TryGetValue("ChangeZoomKey", out yaml)) - changeZoomKey = modData.Hotkeys[yaml.Value]; - var editorViewport = widget.Get("MAP_EDITOR"); var gridButton = widget.GetOrNull("GRID_BUTTON"); @@ -43,48 +38,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic gridButton.IsHighlighted = () => terrainGeometryTrait.Enabled; } - var zoomDropdown = widget.GetOrNull("ZOOM_BUTTON"); - if (zoomDropdown != null) - { - var selectedZoom = (Game.Settings.Graphics.PixelDouble ? 2f : 1f).ToString(); - - zoomDropdown.SelectedItem = selectedZoom; - Func setupItem = (zoom, itemTemplate) => - { - var item = ScrollItemWidget.Setup( - itemTemplate, - () => - { - return float.Parse(zoomDropdown.SelectedItem) == zoom; - }, - () => - { - zoomDropdown.SelectedItem = selectedZoom = zoom.ToString(); - worldRenderer.Viewport.Zoom = float.Parse(selectedZoom); - }); - - var label = zoom.ToString(); - item.Get("LABEL").GetText = () => label; - - return item; - }; - - var options = worldRenderer.Viewport.AvailableZoomSteps; - zoomDropdown.OnMouseDown = _ => zoomDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, options, setupItem); - zoomDropdown.GetText = () => zoomDropdown.SelectedItem; - zoomDropdown.OnKeyPress = e => - { - if (!changeZoomKey.IsActivatedBy(e)) - return; - - var selected = (options.IndexOf(float.Parse(selectedZoom)) + 1) % options.Length; - var zoom = options[selected]; - worldRenderer.Viewport.Zoom = zoom; - selectedZoom = zoom.ToString(); - zoomDropdown.SelectedItem = zoom.ToString(); - }; - } - var copypasteButton = widget.GetOrNull("COPYPASTE_BUTTON"); if (copypasteButton != null) { diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/TogglePixelDoubleHotkeyLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/ResetZoomHotkey.cs similarity index 51% rename from OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/TogglePixelDoubleHotkeyLogic.cs rename to OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/ResetZoomHotkey.cs index 91aa6d7f59..7cb4d6f085 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/TogglePixelDoubleHotkeyLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/Hotkeys/ResetZoomHotkey.cs @@ -16,31 +16,21 @@ using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets.Logic.Ingame { - [ChromeLogicArgsHotkeys("TogglePixelDoubleKey")] - public class TogglePixelDoubleHotkeyLogic : SingleHotkeyBaseLogic + [ChromeLogicArgsHotkeys("ResetZoomKey")] + public class ResetZoomHotkeyLogic : SingleHotkeyBaseLogic { readonly Viewport viewport; [ObjectCreator.UseCtor] - public TogglePixelDoubleHotkeyLogic(Widget widget, ModData modData, WorldRenderer worldRenderer, Dictionary logicArgs) - : base(widget, modData, "TogglePixelDoubleKey", "WORLD_KEYHANDLER", logicArgs) + public ResetZoomHotkeyLogic(Widget widget, ModData modData, WorldRenderer worldRenderer, Dictionary logicArgs) + : base(widget, modData, "ResetZoomKey", "WORLD_KEYHANDLER", logicArgs) { viewport = worldRenderer.Viewport; } protected override bool OnHotkeyActivated(KeyInput e) { - // Zoom is currently always set directly, so we don't need to worry about floating point imprecision - if (viewport.Zoom == 1f) - viewport.Zoom = 2f; - else - { - // Reset zoom to regular view if it was anything else before - // (like a zoom level only reachable by using the scroll wheel). - viewport.Zoom = 1f; - } - - Game.Settings.Graphics.PixelDouble = viewport.Zoom == 2f; + viewport.ToggleZoom(); return true; } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverShroudSelectorLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverShroudSelectorLogic.cs index 1758d15fdc..724ff2d6ea 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverShroudSelectorLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverShroudSelectorLogic.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Linq; +using OpenRA.Graphics; using OpenRA.Mods.Common.Lint; using OpenRA.Network; using OpenRA.Primitives; @@ -64,7 +65,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic } [ObjectCreator.UseCtor] - public ObserverShroudSelectorLogic(Widget widget, ModData modData, World world, Dictionary logicArgs) + public ObserverShroudSelectorLogic(Widget widget, ModData modData, World world, WorldRenderer worldRenderer, Dictionary logicArgs) { this.world = world; @@ -145,6 +146,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic selected = limitViews ? groups.First().Value.First() : world.WorldActor.Owner.Shroud.ExploreMapEnabled ? combined : disableShroud; selected.OnClick(); + + // Enable zooming out to fractional zoom levels + worldRenderer.Viewport.UnlockMinimumZoom(0.5f); } public bool HandleKeyPress(KeyInput e) diff --git a/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs index 398f0b420a..f53edd9d82 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs @@ -190,13 +190,20 @@ namespace OpenRA.Mods.Common.Widgets.Logic resetPanelActions.Add(type, reset(panel)); } + static readonly Dictionary ViewportSizeNames = new Dictionary() + { + { WorldViewport.Close, "Close" }, + { WorldViewport.Medium, "Medium" }, + { WorldViewport.Far, "Far" }, + { WorldViewport.Native, "Furthest" } + }; + Action InitDisplayPanel(Widget panel) { var ds = Game.Settings.Graphics; var gs = Game.Settings.Game; BindCheckboxPref(panel, "HARDWARECURSORS_CHECKBOX", ds, "HardwareCursors"); - BindCheckboxPref(panel, "PIXELDOUBLE_CHECKBOX", ds, "PixelDouble"); BindCheckboxPref(panel, "CURSORDOUBLE_CHECKBOX", ds, "CursorDouble"); BindCheckboxPref(panel, "FRAME_LIMIT_CHECKBOX", ds, "CapFramerate"); BindCheckboxPref(panel, "PLAYER_STANCE_COLORS_CHECKBOX", gs, "UsePlayerStanceColors"); @@ -220,14 +227,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic targetLinesDropDown.GetText = () => gs.TargetLines == TargetLinesType.Automatic ? "Automatic" : gs.TargetLines == TargetLinesType.Manual ? "Manual" : "Disabled"; - // Update zoom immediately - var pixelDoubleCheckbox = panel.Get("PIXELDOUBLE_CHECKBOX"); - var pixelDoubleOnClick = pixelDoubleCheckbox.OnClick; - pixelDoubleCheckbox.OnClick = () => - { - pixelDoubleOnClick(); - worldRenderer.Viewport.Zoom = ds.PixelDouble ? 2 : 1; - }; + var battlefieldCameraDropDown = panel.Get("BATTLEFIELD_CAMERA_DROPDOWN"); + var battlefieldCameraLabel = new CachedTransform(vs => ViewportSizeNames[vs]); + battlefieldCameraDropDown.OnMouseDown = _ => ShowBattlefieldCameraDropdown(battlefieldCameraDropDown, ds); + battlefieldCameraDropDown.GetText = () => battlefieldCameraLabel.Update(ds.ViewportDistance); panel.Get("WINDOW_RESOLUTION").IsVisible = () => ds.Mode == WindowMode.Windowed; var windowWidth = panel.Get("WINDOW_WIDTH"); @@ -329,10 +332,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic ds.Language = dds.Language; ds.Mode = dds.Mode; ds.WindowedSize = dds.WindowedSize; - - ds.PixelDouble = dds.PixelDouble; ds.CursorDouble = dds.CursorDouble; - worldRenderer.Viewport.Zoom = ds.PixelDouble ? 2 : 1; + ds.ViewportDistance = dds.ViewportDistance; ps.Color = dps.Color; ps.Name = dps.Name; @@ -417,7 +418,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic BindCheckboxPref(panel, "CLASSICORDERS_CHECKBOX", gs, "UseClassicMouseStyle"); BindCheckboxPref(panel, "EDGESCROLL_CHECKBOX", gs, "ViewportEdgeScroll"); BindCheckboxPref(panel, "LOCKMOUSE_CHECKBOX", gs, "LockMouseWindow"); - BindCheckboxPref(panel, "ALLOW_ZOOM_CHECKBOX", gs, "AllowZoom"); + BindSliderPref(panel, "ZOOMSPEED_SLIDER", gs, "ZoomSpeed"); BindSliderPref(panel, "SCROLLSPEED_SLIDER", gs, "ViewportEdgeScrollStep"); BindSliderPref(panel, "UI_SCROLLSPEED_SLIDER", gs, "UIScrollSpeed"); @@ -516,8 +517,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic gs.LockMouseWindow = dgs.LockMouseWindow; gs.ViewportEdgeScroll = dgs.ViewportEdgeScroll; gs.ViewportEdgeScrollStep = dgs.ViewportEdgeScrollStep; + gs.ZoomSpeed = dgs.ZoomSpeed; gs.UIScrollSpeed = dgs.UIScrollSpeed; - gs.AllowZoom = dgs.AllowZoom; gs.ZoomModifier = dgs.ZoomModifier; panel.Get("SCROLLSPEED_SLIDER").Value = gs.ViewportEdgeScrollStep; @@ -738,6 +739,36 @@ namespace OpenRA.Mods.Common.Widgets.Logic dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem); } + static void ShowBattlefieldCameraDropdown(DropDownButtonWidget dropdown, GraphicSettings gs) + { + Func setupItem = (o, itemTemplate) => + { + var item = ScrollItemWidget.Setup(itemTemplate, + () => gs.ViewportDistance == o, + () => gs.ViewportDistance = o); + + var label = ViewportSizeNames[o]; + item.Get("LABEL").GetText = () => label; + return item; + }; + + var viewportSizes = Game.ModData.Manifest.Get(); + var windowHeight = Game.Renderer.Resolution.Height; + + var validSizes = new List() { WorldViewport.Close }; + if (viewportSizes.GetSizeRange(WorldViewport.Medium).X < windowHeight) + validSizes.Add(WorldViewport.Medium); + + var farRange = viewportSizes.GetSizeRange(WorldViewport.Far); + if (farRange.X < windowHeight) + validSizes.Add(WorldViewport.Far); + + if (farRange.Y < windowHeight) + validSizes.Add(WorldViewport.Native); + + dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, validSizes, setupItem); + } + void MakeMouseFocusSettingsLive() { var gameSettings = Game.Settings.Game; diff --git a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs index 07825910bf..85e2c806cb 100644 --- a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs @@ -306,38 +306,11 @@ namespace OpenRA.Mods.Common.Widgets } } - bool IsZoomAllowed(float zoom) - { - return world.IsGameOver || zoom >= 1.0f || world.IsReplay || world.LocalPlayer == null || world.LocalPlayer.Spectating; - } - - void Zoom(int direction) - { - var zoomSteps = worldRenderer.Viewport.AvailableZoomSteps; - var currentZoom = worldRenderer.Viewport.Zoom; - var nextIndex = zoomSteps.IndexOf(currentZoom); - - if (direction < 0) - nextIndex++; - else - nextIndex--; - - if (nextIndex < 0 || nextIndex >= zoomSteps.Count()) - return; - - var zoom = zoomSteps.ElementAt(nextIndex); - if (!IsZoomAllowed(zoom)) - return; - - worldRenderer.Viewport.Zoom = zoom; - } - public override bool HandleMouseInput(MouseInput mi) { - if (mi.Event == MouseInputEvent.Scroll && - Game.Settings.Game.AllowZoom && mi.Modifiers.HasModifier(Game.Settings.Game.ZoomModifier)) + if (mi.Event == MouseInputEvent.Scroll && mi.Modifiers.HasModifier(Game.Settings.Game.ZoomModifier)) { - Zoom(mi.Delta.Y); + worldRenderer.Viewport.AdjustZoom(mi.Delta.Y * Game.Settings.Game.ZoomSpeed); return true; } diff --git a/mods/cnc/chrome/editor.yaml b/mods/cnc/chrome/editor.yaml index 9c4cb2d1d6..74f8f88f6e 100644 --- a/mods/cnc/chrome/editor.yaml +++ b/mods/cnc/chrome/editor.yaml @@ -202,13 +202,15 @@ Container@EDITOR_ROOT: NextMusicKey: NextMusic TakeScreenshotKey: TakeScreenshot MuteAudioKey: ToggleMute + LogicKeyListener@WORLD_KEYHANDLER: + Logic: ResetZoomHotkeyLogic + ResetZoomKey: ResetZoom Container@WORLD_ROOT: Container@MENU_ROOT: TooltipContainer@TOOLTIP_CONTAINER: Container@EDITOR_WORLD_ROOT: Logic: LoadIngamePerfLogic, MapEditorLogic, ActorEditLogic - ChangeZoomKey: TogglePixelDouble EditPanelPadding: 5 Children: Container@PERF_ROOT: @@ -578,6 +580,28 @@ Container@EDITOR_WORLD_ROOT: Height: 25 Text: History Font: Bold + Button@UNDO_BUTTON: + X: WINDOW_RIGHT - 910 + Y: 5 + Height: 25 + Width: 100 + Text: Undo + Font: Bold + Key: z ctrl + TooltipTemplate: BUTTON_TOOLTIP + TooltipText: Undo last step + TooltipContainer: TOOLTIP_CONTAINER + Button@REDO_BUTTON: + X: WINDOW_RIGHT - 800 + Y: 5 + Height: 25 + Width: 100 + Text: Redo + Font: Bold + Key: y ctrl + TooltipTemplate: BUTTON_TOOLTIP + TooltipText: Redo last step + TooltipContainer: TOOLTIP_CONTAINER Button@GRID_BUTTON: X: WINDOW_RIGHT - 690 Y: 5 @@ -589,25 +613,6 @@ Container@EDITOR_WORLD_ROOT: TooltipTemplate: BUTTON_TOOLTIP TooltipText: Toggle the terrain grid TooltipContainer: TOOLTIP_CONTAINER - Label@ZOOM_LABEL: - X: WINDOW_RIGHT - 770 - 55 - Y: 5 - Width: 50 - Height: 25 - Text: Zoom: - Align: Right - Font: Bold - Contrast: true - DropDownButton@ZOOM_BUTTON: - X: WINDOW_RIGHT - 770 - Y: 5 - Width: 70 - Height: 25 - Font: Bold - Key: TogglePixelDouble - TooltipTemplate: BUTTON_TOOLTIP - TooltipText: Zoom - TooltipContainer: TOOLTIP_CONTAINER Button@COPYPASTE_BUTTON: X: WINDOW_RIGHT - 580 Y: 5 @@ -639,26 +644,6 @@ Container@EDITOR_WORLD_ROOT: Align: Left Font: Bold Contrast: true - Button@UNDO_BUTTON: - X: 200 - Height: 25 - Width: 100 - Text: Undo - Font: Bold - Key: z ctrl - TooltipTemplate: BUTTON_TOOLTIP - TooltipText: Undo last step - TooltipContainer: TOOLTIP_CONTAINER - Button@REDO_BUTTON: - X: 305 - Height: 25 - Width: 100 - Text: Redo - Font: Bold - Key: y ctrl - TooltipTemplate: BUTTON_TOOLTIP - TooltipText: Redo last step - TooltipContainer: TOOLTIP_CONTAINER ScrollPanel@CATEGORY_FILTER_PANEL: Width: 190 diff --git a/mods/cnc/chrome/ingame.yaml b/mods/cnc/chrome/ingame.yaml index 5e87f48533..d04ef71fc7 100644 --- a/mods/cnc/chrome/ingame.yaml +++ b/mods/cnc/chrome/ingame.yaml @@ -10,13 +10,13 @@ Container@INGAME_ROOT: TakeScreenshotKey: TakeScreenshot MuteAudioKey: ToggleMute LogicKeyListener@WORLD_KEYHANDLER: - Logic: CycleBasesHotkeyLogic, CycleProductionActorsHotkeyLogic, JumpToLastEventHotkeyLogic, JumpToSelectedActorsHotkeyLogic, TogglePixelDoubleHotkeyLogic, TogglePlayerStanceColorHotkeyLogic, CycleStatusBarsHotkeyLogic, PauseHotkeyLogic, RemoveFromControlGroupHotkeyLogic + Logic: CycleBasesHotkeyLogic, CycleProductionActorsHotkeyLogic, JumpToLastEventHotkeyLogic, JumpToSelectedActorsHotkeyLogic, ResetZoomHotkeyLogic, TogglePlayerStanceColorHotkeyLogic, CycleStatusBarsHotkeyLogic, PauseHotkeyLogic, RemoveFromControlGroupHotkeyLogic RemoveFromControlGroupKey: RemoveFromControlGroup CycleBasesKey: CycleBase CycleProductionActorsKey: CycleProductionBuildings JumpToLastEventKey: ToLastEvent JumpToSelectedActorsKey: ToSelection - TogglePixelDoubleKey: TogglePixelDouble + ResetZoomKey: ResetZoom TogglePlayerStanceColorKey: TogglePlayerStanceColor CycleStatusBarsKey: CycleStatusBars PauseKey: Pause diff --git a/mods/cnc/chrome/settings.yaml b/mods/cnc/chrome/settings.yaml index de4fe6fdf5..45366fef24 100644 --- a/mods/cnc/chrome/settings.yaml +++ b/mods/cnc/chrome/settings.yaml @@ -132,7 +132,7 @@ Container@SETTINGS_PANEL: Font: Regular Text: Use Hardware Cursors Checkbox@CURSORDOUBLE_CHECKBOX: - X: 300 + X: 310 Y: 75 Width: 200 Height: 20 @@ -152,13 +152,6 @@ Container@SETTINGS_PANEL: Height: 20 Font: Regular Text: Enable Frame Limiter - Checkbox@PIXELDOUBLE_CHECKBOX: - X: 310 - Y: 125 - Width: 200 - Height: 20 - Font: Regular - Text: Enable Pixel Doubling Label@FRAME_LIMIT_DESC_A: X: 45 Y: 153 @@ -209,6 +202,18 @@ Container@SETTINGS_PANEL: Y: 6 Width: PARENT_RIGHT - 35 Height: PARENT_BOTTOM - 12 + Label@BATTLEFIELD_CAMERA: + X: 15 + Y: 227 + Width: 120 + Text: Battlefield Camera: + Align: Right + DropDownButton@BATTLEFIELD_CAMERA_DROPDOWN: + X: 140 + Y: 215 + Width: 145 + Height: 25 + Font: Regular Label@STATUS_BARS: X: 250 Y: 257 @@ -223,7 +228,7 @@ Container@SETTINGS_PANEL: Font: Regular Label@TARGET_LINES: X: 250 - Y: 228 + Y: 227 Width: 145 Text: Target Lines: Align: Right @@ -404,7 +409,7 @@ Container@SETTINGS_PANEL: Width: 160 Height: 20 Font: Regular - Text: Scroll-zoom Modifier: + Text: Mouse Wheel Zoom Modifier: Align: Right DropDownButton@ZOOM_MODIFIER: X: PARENT_RIGHT - WIDTH - 15 @@ -420,29 +425,22 @@ Container@SETTINGS_PANEL: Height: 20 Font: Regular Text: Edge Scrolling - Checkbox@ALLOW_ZOOM_CHECKBOX: + Checkbox@LOCKMOUSE_CHECKBOX: X: 15 Y: 100 Width: 130 Height: 20 Font: Regular - Text: Scroll Zooming - Checkbox@LOCKMOUSE_CHECKBOX: - X: 15 - Y: 130 - Width: 130 - Height: 20 - Font: Regular Text: Lock Mouse to Window Label@SCROLL_SPEED_LABEL: - X: PARENT_RIGHT - WIDTH - 270 + X: 15 Y: 128 - Width: 95 + Width: 85 Height: 25 Text: Scroll Speed: Align: Right Slider@SCROLLSPEED_SLIDER: - X: PARENT_RIGHT - WIDTH - 170 + X: 95 Y: 133 Width: 100 Height: 20 @@ -450,20 +448,35 @@ Container@SETTINGS_PANEL: MinimumValue: 10 MaximumValue: 50 Label@UI_SCROLL_SPEED_LABEL: - X: PARENT_RIGHT - WIDTH - 106 + X: PARENT_RIGHT - WIDTH - 320 Y: 128 Width: 95 Height: 25 Text: UI Scroll: Align: Right Slider@UI_SCROLLSPEED_SLIDER: - X: PARENT_RIGHT - WIDTH - 6 + X: PARENT_RIGHT - WIDTH - 220 Y: 133 Width: 100 Height: 20 Ticks: 5 MinimumValue: 1 MaximumValue: 100 + Label@ZOOM_SPEED_LABEL: + X: PARENT_RIGHT - WIDTH - 106 + Y: 129 + Width: 95 + Height: 25 + Text: Zoom Speed: + Align: Right + ExponentialSlider@ZOOMSPEED_SLIDER: + X: PARENT_RIGHT - WIDTH - 6 + Y: 133 + Width: 100 + Height: 20 + Ticks: 5 + MinimumValue: 0.01 + MaximumValue: 0.4 Container@HOTKEYS_PANEL: X: 15 Y: 15 diff --git a/mods/common/chrome/editor.yaml b/mods/common/chrome/editor.yaml index 0b706eb9b9..c02e1d1274 100644 --- a/mods/common/chrome/editor.yaml +++ b/mods/common/chrome/editor.yaml @@ -193,13 +193,15 @@ Container@EDITOR_ROOT: NextMusicKey: NextMusic TakeScreenshotKey: TakeScreenshot MuteAudioKey: ToggleMute + LogicKeyListener@WORLD_KEYHANDLER: + Logic: ResetZoomHotkeyLogic + ResetZoomKey: ResetZoom Container@WORLD_ROOT: Container@MENU_ROOT: TooltipContainer@TOOLTIP_CONTAINER: Container@EDITOR_WORLD_ROOT: Logic: LoadIngamePerfLogic, MapEditorLogic, ActorEditLogic - ChangeZoomKey: TogglePixelDouble EditPanelPadding: 14 Children: Container@PERF_ROOT: @@ -584,25 +586,8 @@ Container@EDITOR_WORLD_ROOT: TooltipContainer: TOOLTIP_CONTAINER Font: Bold Key: f1 - Label@ZOOM_LABEL: - X: 495 - Width: 50 - Height: 25 - Text: Zoom: - Align: Right - Font: Bold - Contrast: true - DropDownButton@ZOOM_BUTTON: - X: 550 - Width: 70 - Height: 25 - Font: Bold - Key: TogglePixelDouble - TooltipTemplate: BUTTON_TOOLTIP - TooltipText: Zoom - TooltipContainer: TOOLTIP_CONTAINER Button@UNDO_BUTTON: - X: 630 + X: 500 Height: 25 Width: 90 Text: Undo @@ -612,7 +597,7 @@ Container@EDITOR_WORLD_ROOT: TooltipText: Undo last step TooltipContainer: TOOLTIP_CONTAINER Button@REDO_BUTTON: - X: 730 + X: 600 Height: 25 Width: 90 Text: Redo diff --git a/mods/common/chrome/ingame.yaml b/mods/common/chrome/ingame.yaml index 3f2b9780b4..27bf3b10f6 100644 --- a/mods/common/chrome/ingame.yaml +++ b/mods/common/chrome/ingame.yaml @@ -10,13 +10,13 @@ Container@INGAME_ROOT: TakeScreenshotKey: TakeScreenshot MuteAudioKey: ToggleMute LogicKeyListener@WORLD_KEYHANDLER: - Logic: CycleBasesHotkeyLogic, CycleProductionActorsHotkeyLogic, JumpToLastEventHotkeyLogic, JumpToSelectedActorsHotkeyLogic, TogglePixelDoubleHotkeyLogic, TogglePlayerStanceColorHotkeyLogic, CycleStatusBarsHotkeyLogic, PauseHotkeyLogic, RemoveFromControlGroupHotkeyLogic + Logic: CycleBasesHotkeyLogic, CycleProductionActorsHotkeyLogic, JumpToLastEventHotkeyLogic, JumpToSelectedActorsHotkeyLogic, ResetZoomHotkeyLogic, TogglePlayerStanceColorHotkeyLogic, CycleStatusBarsHotkeyLogic, PauseHotkeyLogic, RemoveFromControlGroupHotkeyLogic RemoveFromControlGroupKey: RemoveFromControlGroup CycleBasesKey: CycleBase CycleProductionActorsKey: CycleProductionBuildings JumpToLastEventKey: ToLastEvent JumpToSelectedActorsKey: ToSelection - TogglePixelDoubleKey: TogglePixelDouble + ResetZoomKey: ResetZoom TogglePlayerStanceColorKey: TogglePlayerStanceColor CycleStatusBarsKey: CycleStatusBars PauseKey: Pause diff --git a/mods/common/chrome/settings.yaml b/mods/common/chrome/settings.yaml index 4ff8ac4635..3cf2df5e34 100644 --- a/mods/common/chrome/settings.yaml +++ b/mods/common/chrome/settings.yaml @@ -95,7 +95,7 @@ Background@SETTINGS_PANEL: Children: Label@MODE_LABEL: X: 110 - Y: 41 + Y: 40 Width: 45 Height: 25 Align: Right @@ -146,7 +146,7 @@ Background@SETTINGS_PANEL: Font: Regular Text: Use Hardware Cursors Checkbox@CURSORDOUBLE_CHECKBOX: - X: 300 + X: 310 Y: 75 Width: 200 Height: 20 @@ -166,13 +166,6 @@ Background@SETTINGS_PANEL: Height: 20 Font: Regular Text: Enable Frame Limiter - Checkbox@PIXELDOUBLE_CHECKBOX: - X: 310 - Y: 125 - Width: 200 - Height: 20 - Font: Regular - Text: Enable Pixel Doubling Label@FRAME_LIMIT_DESC_A: X: 45 Y: 159 @@ -223,29 +216,41 @@ Background@SETTINGS_PANEL: Y: 6 Width: PARENT_RIGHT - 35 Height: PARENT_BOTTOM - 12 + Label@BATTLEFIELD_CAMERA: + X: 15 + Y: 242 + Width: 120 + Text: Battlefield Camera: + Align: Right + DropDownButton@BATTLEFIELD_CAMERA_DROPDOWN: + X: 140 + Y: 230 + Width: 145 + Height: 25 + Font: Regular Label@STATUS_BARS: X: 250 - Y: 278 + Y: 277 Width: 145 Text: Status Bars: Align: Right DropDownButton@STATUS_BAR_DROPDOWN: X: 400 Y: 265 - Width: 170 + Width: 180 Height: 25 Font: Regular Text: Standard Label@TARGET_LINES: X: 250 - Y: 243 + Y: 242 Width: 145 Text: Target Lines: Align: Right DropDownButton@TARGET_LINES_DROPDOWN: X: 400 Y: 230 - Width: 170 + Width: 180 Height: 25 Font: Regular Label@LOCALIZATION_TITLE: @@ -410,7 +415,7 @@ Background@SETTINGS_PANEL: Width: 160 Height: 20 Font: Regular - Text: Scroll-zoom Modifier: + Text: Mouse Wheel Zoom Modifier: Align: Right DropDownButton@ZOOM_MODIFIER: X: PARENT_RIGHT - WIDTH - 15 @@ -426,29 +431,22 @@ Background@SETTINGS_PANEL: Height: 20 Font: Regular Text: Edge Scrolling - Checkbox@ALLOW_ZOOM_CHECKBOX: + Checkbox@LOCKMOUSE_CHECKBOX: X: 15 Y: 100 Width: 130 Height: 20 Font: Regular - Text: Scroll Zooming - Checkbox@LOCKMOUSE_CHECKBOX: - X: 15 - Y: 130 - Width: 130 - Height: 20 - Font: Regular Text: Lock mouse to window Label@SCROLL_SPEED_LABEL: - X: PARENT_RIGHT - WIDTH - 270 + X: 15 Y: 129 - Width: 95 + Width: 85 Height: 25 Text: Scroll Speed: Align: Right Slider@SCROLLSPEED_SLIDER: - X: PARENT_RIGHT - WIDTH - 170 + X: 95 Y: 133 Width: 100 Height: 20 @@ -456,20 +454,35 @@ Background@SETTINGS_PANEL: MinimumValue: 10 MaximumValue: 50 Label@UI_SCROLL_SPEED_LABEL: - X: PARENT_RIGHT - WIDTH - 106 + X: PARENT_RIGHT - WIDTH - 320 Y: 129 Width: 95 Height: 25 Text: UI Scroll: Align: Right Slider@UI_SCROLLSPEED_SLIDER: - X: PARENT_RIGHT - WIDTH - 6 + X: PARENT_RIGHT - WIDTH - 220 Y: 133 Width: 100 Height: 20 Ticks: 5 MinimumValue: 1 MaximumValue: 100 + Label@ZOOM_SPEED_LABEL: + X: PARENT_RIGHT - WIDTH - 106 + Y: 129 + Width: 95 + Height: 25 + Text: Zoom Speed: + Align: Right + ExponentialSlider@ZOOMSPEED_SLIDER: + X: PARENT_RIGHT - WIDTH - 6 + Y: 133 + Width: 95 + Height: 20 + Ticks: 5 + MinimumValue: 0.01 + MaximumValue: 0.4 Container@HOTKEYS_PANEL: X: 5 Y: 50 diff --git a/mods/common/hotkeys/game.yaml b/mods/common/hotkeys/game.yaml index bfcc24a52f..728e4b833b 100644 --- a/mods/common/hotkeys/game.yaml +++ b/mods/common/hotkeys/game.yaml @@ -42,8 +42,8 @@ CycleStatusBars: COMMA Description: Cycle status bars display Types: World, Player, Spectator -TogglePixelDouble: PERIOD - Description: Toggle pixel doubling +ResetZoom: PERIOD + Description: Reset zoom Types: World, Player, Spectator ToggleMute: M