Added mousewheel zooming

This commit is contained in:
Philipp Schärer
2016-01-25 18:28:06 +01:00
committed by Oliver Brakmann
parent 386acdcfc9
commit ea74499ec2
10 changed files with 198 additions and 30 deletions

View File

@@ -53,8 +53,15 @@ namespace OpenRA.Graphics
ProjectedCellRegion allCells; ProjectedCellRegion allCells;
bool allCellsDirty = true; bool allCellsDirty = true;
readonly float[] availableZoomSteps = new[] { 2f, 1f, 0.5f, 0.25f };
float zoom = 1f; float zoom = 1f;
public float[] AvailableZoomSteps
{
get { return availableZoomSteps; }
}
public float Zoom public float Zoom
{ {
get get
@@ -64,7 +71,8 @@ namespace OpenRA.Graphics
set set
{ {
zoom = value; var newValue = ClosestTo(AvailableZoomSteps, value);
zoom = newValue;
viewportSize = (1f / zoom * new float2(Game.Renderer.Resolution)).ToInt2(); viewportSize = (1f / zoom * new float2(Game.Renderer.Resolution)).ToInt2();
cellsDirty = true; cellsDirty = true;
allCellsDirty = true; allCellsDirty = true;
@@ -74,6 +82,23 @@ namespace OpenRA.Graphics
public static int TicksSinceLastMove = 0; public static int TicksSinceLastMove = 0;
public static int2 LastMousePos; public static int2 LastMousePos;
float ClosestTo(float[] collection, float target)
{
var closestValue = collection.First();
var subtractResult = Math.Abs(closestValue - target);
foreach (var element in collection)
{
if (Math.Abs(element - target) < subtractResult)
{
subtractResult = Math.Abs(element - target);
closestValue = element;
}
}
return closestValue;
}
public ScrollDirection GetBlockedDirections() public ScrollDirection GetBlockedDirections()
{ {
var ret = ScrollDirection.None; var ret = ScrollDirection.None;

View File

@@ -174,6 +174,9 @@ namespace OpenRA
public bool AllowDownloading = true; public bool AllowDownloading = true;
public string MapRepository = "http://resource.openra.net/map/"; public string MapRepository = "http://resource.openra.net/map/";
public bool AllowZoom = true;
public Modifiers ZoomModifier = Modifiers.Ctrl;
public bool FetchNews = true; public bool FetchNews = true;
public string NewsUrl = "http://www.openra.net/gamenews"; public string NewsUrl = "http://www.openra.net/gamenews";
} }

View File

@@ -26,6 +26,7 @@ namespace OpenRA.Mods.Common.Widgets
Widget panelRoot; Widget panelRoot;
public string PanelRoot; public string PanelRoot;
public string SelectedItem;
[ObjectCreator.UseCtor] [ObjectCreator.UseCtor]
public DropDownButtonWidget(Ruleset modRules) public DropDownButtonWidget(Ruleset modRules)

View File

@@ -69,8 +69,29 @@ namespace OpenRA.Mods.Common.Widgets
tooltipContainer.Value.RemoveTooltip(); 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<DropDownButtonWidget>("ZOOM_BUTTON").SelectedItem = zoom.ToString();
worldRenderer.Viewport.Zoom = zoom;
}
public override bool HandleMouseInput(MouseInput mi) public override bool HandleMouseInput(MouseInput mi)
{ {
if (mi.Event == MouseInputEvent.Scroll &&
Game.Settings.Game.AllowZoom && mi.Modifiers.HasModifier(Game.Settings.Game.ZoomModifier))
{
Zoom(mi.ScrollDelta);
return true;
}
if (CurrentBrush.HandleMouseInput(mi)) if (CurrentBrush.HandleMouseInput(mi))
return true; return true;

View File

@@ -35,13 +35,22 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var zoomDropdown = widget.GetOrNull<DropDownButtonWidget>("ZOOM_BUTTON"); var zoomDropdown = widget.GetOrNull<DropDownButtonWidget>("ZOOM_BUTTON");
if (zoomDropdown != null) if (zoomDropdown != null)
{ {
var selectedZoom = Game.Settings.Graphics.PixelDouble ? 2f : 1f; var selectedZoom = (Game.Settings.Graphics.PixelDouble ? 2f : 1f).ToString();
var selectedLabel = selectedZoom.ToString();
zoomDropdown.SelectedItem = selectedZoom;
Func<float, ScrollItemWidget, ScrollItemWidget> setupItem = (zoom, itemTemplate) => Func<float, ScrollItemWidget, ScrollItemWidget> setupItem = (zoom, itemTemplate) =>
{ {
var item = ScrollItemWidget.Setup(itemTemplate, var item = ScrollItemWidget.Setup(
() => selectedZoom == zoom, itemTemplate,
() => { worldRenderer.Viewport.Zoom = selectedZoom = zoom; selectedLabel = zoom.ToString(); }); () =>
{
return float.Parse(zoomDropdown.SelectedItem) == zoom;
},
() =>
{
zoomDropdown.SelectedItem = selectedZoom = zoom.ToString();
worldRenderer.Viewport.Zoom = float.Parse(selectedZoom);
});
var label = zoom.ToString(); var label = zoom.ToString();
item.Get<LabelWidget>("LABEL").GetText = () => label; item.Get<LabelWidget>("LABEL").GetText = () => label;
@@ -49,9 +58,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return item; return item;
}; };
var options = new[] { 2f, 1f, 0.5f, 0.25f }; var options = worldRenderer.Viewport.AvailableZoomSteps;
zoomDropdown.OnMouseDown = _ => zoomDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, options, setupItem); zoomDropdown.OnMouseDown = _ => zoomDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, options, setupItem);
zoomDropdown.GetText = () => selectedLabel; zoomDropdown.GetText = () => zoomDropdown.SelectedItem;
zoomDropdown.GetKey = _ => Game.Settings.Keys.TogglePixelDoubleKey; zoomDropdown.GetKey = _ => Game.Settings.Keys.TogglePixelDoubleKey;
zoomDropdown.OnKeyPress = e => zoomDropdown.OnKeyPress = e =>
{ {
@@ -59,9 +68,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (key != Game.Settings.Keys.TogglePixelDoubleKey) if (key != Game.Settings.Keys.TogglePixelDoubleKey)
return; return;
var selected = (options.IndexOf(selectedZoom) + 1) % options.Length; var selected = (options.IndexOf(float.Parse(selectedZoom)) + 1) % options.Length;
worldRenderer.Viewport.Zoom = selectedZoom = options[selected]; var zoom = options[selected];
selectedLabel = selectedZoom.ToString(); worldRenderer.Viewport.Zoom = zoom;
selectedZoom = zoom.ToString();
zoomDropdown.SelectedItem = zoom.ToString();
}; };
} }

View File

@@ -381,6 +381,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
BindCheckboxPref(panel, "CLASSICORDERS_CHECKBOX", gs, "UseClassicMouseStyle"); BindCheckboxPref(panel, "CLASSICORDERS_CHECKBOX", gs, "UseClassicMouseStyle");
BindCheckboxPref(panel, "EDGESCROLL_CHECKBOX", gs, "ViewportEdgeScroll"); BindCheckboxPref(panel, "EDGESCROLL_CHECKBOX", gs, "ViewportEdgeScroll");
BindCheckboxPref(panel, "LOCKMOUSE_CHECKBOX", gs, "LockMouseWindow"); BindCheckboxPref(panel, "LOCKMOUSE_CHECKBOX", gs, "LockMouseWindow");
BindCheckboxPref(panel, "ALLOW_ZOOM_CHECKBOX", gs, "AllowZoom");
BindSliderPref(panel, "SCROLLSPEED_SLIDER", gs, "ViewportEdgeScrollStep"); BindSliderPref(panel, "SCROLLSPEED_SLIDER", gs, "ViewportEdgeScrollStep");
BindSliderPref(panel, "UI_SCROLLSPEED_SLIDER", gs, "UIScrollSpeed"); BindSliderPref(panel, "UI_SCROLLSPEED_SLIDER", gs, "UIScrollSpeed");
@@ -400,6 +401,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
mouseScrollDropdown.OnMouseDown = _ => ShowMouseScrollDropdown(mouseScrollDropdown, gs); mouseScrollDropdown.OnMouseDown = _ => ShowMouseScrollDropdown(mouseScrollDropdown, gs);
mouseScrollDropdown.GetText = () => gs.MouseScroll.ToString(); mouseScrollDropdown.GetText = () => gs.MouseScroll.ToString();
var zoomModifierDropdown = panel.Get<DropDownButtonWidget>("ZOOM_MODIFIER");
zoomModifierDropdown.OnMouseDown = _ => ShowZoomModifierDropdown(zoomModifierDropdown, gs);
zoomModifierDropdown.GetText = () => gs.ZoomModifier.ToString();
var hotkeyList = panel.Get<ScrollPanelWidget>("HOTKEY_LIST"); var hotkeyList = panel.Get<ScrollPanelWidget>("HOTKEY_LIST");
hotkeyList.Layout = new GridLayout(hotkeyList); hotkeyList.Layout = new GridLayout(hotkeyList);
var hotkeyHeader = hotkeyList.Get<ScrollItemWidget>("HEADER"); var hotkeyHeader = hotkeyList.Get<ScrollItemWidget>("HEADER");
@@ -562,6 +567,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
gs.ViewportEdgeScroll = dgs.ViewportEdgeScroll; gs.ViewportEdgeScroll = dgs.ViewportEdgeScroll;
gs.ViewportEdgeScrollStep = dgs.ViewportEdgeScrollStep; gs.ViewportEdgeScrollStep = dgs.ViewportEdgeScrollStep;
gs.UIScrollSpeed = dgs.UIScrollSpeed; gs.UIScrollSpeed = dgs.UIScrollSpeed;
gs.AllowZoom = dgs.AllowZoom;
gs.ZoomModifier = dgs.ZoomModifier;
foreach (var f in ks.GetType().GetFields()) foreach (var f in ks.GetType().GetFields())
{ {
@@ -637,6 +644,29 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return true; return true;
} }
static bool ShowZoomModifierDropdown(DropDownButtonWidget dropdown, GameSettings s)
{
var options = new Dictionary<string, Modifiers>()
{
{ "Alt", Modifiers.Alt },
{ "Ctrl", Modifiers.Ctrl },
{ "Meta", Modifiers.Meta },
{ "Shift", Modifiers.Shift },
};
Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
{
var item = ScrollItemWidget.Setup(itemTemplate,
() => s.ZoomModifier == options[o],
() => s.ZoomModifier = options[o]);
item.Get<LabelWidget>("LABEL").GetText = () => o;
return item;
};
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem);
return true;
}
bool ShowAudioDeviceDropdown(DropDownButtonWidget dropdown, SoundDevice[] devices) bool ShowAudioDeviceDropdown(DropDownButtonWidget dropdown, SoundDevice[] devices)
{ {
var i = 0; var i = 0;

View File

@@ -189,8 +189,41 @@ 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) public override bool HandleMouseInput(MouseInput mi)
{ {
if (mi.Event == MouseInputEvent.Scroll &&
Game.Settings.Game.AllowZoom && mi.Modifiers.HasModifier(Game.Settings.Game.ZoomModifier))
{
Zoom(mi.ScrollDelta);
return true;
}
var scrolltype = Game.Settings.Game.MouseScroll; var scrolltype = Game.Settings.Game.MouseScroll;
if (scrolltype == MouseScrollType.Disabled) if (scrolltype == MouseScrollType.Disabled)
return false; return false;

View File

@@ -124,7 +124,7 @@ namespace OpenRA.Platforms.Default
int x, y; int x, y;
SDL.SDL_GetMouseState(out x, out y); SDL.SDL_GetMouseState(out x, out y);
scrollDelta = e.wheel.y; scrollDelta = e.wheel.y;
inputHandler.OnMouseInput(new MouseInput(MouseInputEvent.Scroll, MouseButton.None, scrollDelta, new int2(x, y), Modifiers.None, 0)); inputHandler.OnMouseInput(new MouseInput(MouseInputEvent.Scroll, MouseButton.None, scrollDelta, new int2(x, y), mods, 0));
break; break;
} }

View File

@@ -353,30 +353,52 @@ Container@SETTINGS_PANEL:
Height: 25 Height: 25
Font: Regular Font: Regular
Text: Enabled Text: Enabled
Checkbox@EDGESCROLL_CHECKBOX: Checkbox@ALLOW_ZOOM_CHECKBOX:
X: 15 X: 15
Y: 70 Y: 70
Width: 130 Width: 130
Height: 20 Height: 20
Font: Regular Font: Regular
Text: Allow zoom
Label@ZOOM_MODIFIER_LABEL:
X: PARENT_RIGHT - WIDTH - 120
Y: 68
Width: 160
Height: 20
Font: Regular
Text: Modifier used to zoom:
Align: Right
DropDownButton@ZOOM_MODIFIER:
X: PARENT_RIGHT - WIDTH - 15
Y: 68
Width: 100
Height: 25
Font: Regular
Text: Alt
Checkbox@EDGESCROLL_CHECKBOX:
X: 15
Y: 100
Width: 130
Height: 20
Font: Regular
Text: Edge Scrolling Text: Edge Scrolling
Checkbox@LOCKMOUSE_CHECKBOX: Checkbox@LOCKMOUSE_CHECKBOX:
X: 15 X: 15
Y: 100 Y: 130
Width: 130 Width: 130
Height: 20 Height: 20
Font: Regular Font: Regular
Text: Lock mouse to window Text: Lock mouse to window
Label@SCROLL_SPEED_LABEL: Label@SCROLL_SPEED_LABEL:
X: PARENT_RIGHT - WIDTH - 270 X: PARENT_RIGHT - WIDTH - 270
Y: 67 Y: 97
Width: 95 Width: 95
Height: 25 Height: 25
Text: Scroll Speed: Text: Scroll Speed:
Align: Right Align: Right
Slider@SCROLLSPEED_SLIDER: Slider@SCROLLSPEED_SLIDER:
X: PARENT_RIGHT - WIDTH - 15 X: PARENT_RIGHT - WIDTH - 15
Y: 73 Y: 103
Width: 250 Width: 250
Height: 20 Height: 20
Ticks: 5 Ticks: 5
@@ -384,32 +406,32 @@ Container@SETTINGS_PANEL:
MaximumValue: 50 MaximumValue: 50
Label@UI_SCROLL_SPEED_LABEL: Label@UI_SCROLL_SPEED_LABEL:
X: PARENT_RIGHT - WIDTH - 270 X: PARENT_RIGHT - WIDTH - 270
Y: 97 Y: 127
Width: 95 Width: 95
Height: 25 Height: 25
Text: UI Scroll Speed: Text: UI Scroll Speed:
Align: Right Align: Right
Slider@UI_SCROLLSPEED_SLIDER: Slider@UI_SCROLLSPEED_SLIDER:
X: PARENT_RIGHT - WIDTH - 15 X: PARENT_RIGHT - WIDTH - 15
Y: 103 Y: 133
Width: 250 Width: 250
Height: 20 Height: 20
Ticks: 5 Ticks: 5
MinimumValue: 1 MinimumValue: 1
MaximumValue: 100 MaximumValue: 100
Label@HOTKEYS_TITLE: Label@HOTKEYS_TITLE:
Y: 135 Y: 165
Width: PARENT_RIGHT Width: PARENT_RIGHT
Font: Bold Font: Bold
Text: Hotkeys Text: Hotkeys
Align: Center Align: Center
ScrollPanel@HOTKEY_LIST: ScrollPanel@HOTKEY_LIST:
X: 15 X: 15
Y: 155 Y: 185
Width: 560 Width: 560
TopBottomSpacing: 4 TopBottomSpacing: 4
ItemSpacing: 4 ItemSpacing: 4
Height: 190 Height: 160
Children: Children:
ScrollItem@HEADER: ScrollItem@HEADER:
Width: 528 Width: 528

View File

@@ -357,30 +357,52 @@ Background@SETTINGS_PANEL:
Height: 25 Height: 25
Font: Regular Font: Regular
Text: Enabled Text: Enabled
Checkbox@EDGESCROLL_CHECKBOX: Checkbox@ALLOW_ZOOM_CHECKBOX:
X: 15 X: 15
Y: 70 Y: 70
Width: 130 Width: 130
Height: 20 Height: 20
Font: Regular Font: Regular
Text: Allow zoom
Label@ZOOM_MODIFIER_LABEL:
X: PARENT_RIGHT - WIDTH - 120
Y: 68
Width: 160
Height: 20
Font: Regular
Text: Modifier used to zoom:
Align: Right
DropDownButton@ZOOM_MODIFIER:
X: PARENT_RIGHT - WIDTH - 15
Y: 68
Width: 100
Height: 25
Font: Regular
Text: Alt
Checkbox@EDGESCROLL_CHECKBOX:
X: 15
Y: 100
Width: 130
Height: 20
Font: Regular
Text: Edge Scrolling Text: Edge Scrolling
Checkbox@LOCKMOUSE_CHECKBOX: Checkbox@LOCKMOUSE_CHECKBOX:
X: 15 X: 15
Y: 100 Y: 130
Width: 130 Width: 130
Height: 20 Height: 20
Font: Regular Font: Regular
Text: Lock mouse to window Text: Lock mouse to window
Label@SCROLL_SPEED_LABEL: Label@SCROLL_SPEED_LABEL:
X: PARENT_RIGHT - WIDTH - 270 X: PARENT_RIGHT - WIDTH - 270
Y: 67 Y: 97
Width: 95 Width: 95
Height: 25 Height: 25
Text: Scroll Speed: Text: Scroll Speed:
Align: Right Align: Right
Slider@SCROLLSPEED_SLIDER: Slider@SCROLLSPEED_SLIDER:
X: PARENT_RIGHT - WIDTH - 15 X: PARENT_RIGHT - WIDTH - 15
Y: 73 Y: 103
Width: 250 Width: 250
Height: 20 Height: 20
Ticks: 5 Ticks: 5
@@ -388,32 +410,32 @@ Background@SETTINGS_PANEL:
MaximumValue: 50 MaximumValue: 50
Label@UI_SCROLL_SPEED_LABEL: Label@UI_SCROLL_SPEED_LABEL:
X: PARENT_RIGHT - WIDTH - 270 X: PARENT_RIGHT - WIDTH - 270
Y: 97 Y: 127
Width: 95 Width: 95
Height: 25 Height: 25
Text: UI Scroll Speed: Text: UI Scroll Speed:
Align: Right Align: Right
Slider@UI_SCROLLSPEED_SLIDER: Slider@UI_SCROLLSPEED_SLIDER:
X: PARENT_RIGHT - WIDTH - 15 X: PARENT_RIGHT - WIDTH - 15
Y: 103 Y: 133
Width: 250 Width: 250
Height: 20 Height: 20
Ticks: 5 Ticks: 5
MinimumValue: 1 MinimumValue: 1
MaximumValue: 100 MaximumValue: 100
Label@HOTKEYS_TITLE: Label@HOTKEYS_TITLE:
Y: 135 Y: 165
Width: PARENT_RIGHT Width: PARENT_RIGHT
Font: Bold Font: Bold
Text: Hotkeys Text: Hotkeys
Align: Center Align: Center
ScrollPanel@HOTKEY_LIST: ScrollPanel@HOTKEY_LIST:
X: 15 X: 15
Y: 155 Y: 185
Width: 560 Width: 560
TopBottomSpacing: 4 TopBottomSpacing: 4
ItemSpacing: 4 ItemSpacing: 4
Height: 190 Height: 160
Children: Children:
ScrollItem@HEADER: ScrollItem@HEADER:
BaseName: scrollheader BaseName: scrollheader