diff --git a/OpenRA.Game/Widgets/CheckboxWidget.cs b/OpenRA.Game/Widgets/CheckboxWidget.cs index dd286ef852..fb7413aa99 100644 --- a/OpenRA.Game/Widgets/CheckboxWidget.cs +++ b/OpenRA.Game/Widgets/CheckboxWidget.cs @@ -11,6 +11,7 @@ using System; using System.Drawing; using OpenRA.Graphics; +using System.Reflection; namespace OpenRA.Widgets { @@ -19,7 +20,12 @@ namespace OpenRA.Widgets public string Text = ""; public int baseLine = 1; public bool Bold = false; - public Func Checked = () => false; + public Func IsChecked = () => false; + public event Action OnChange = _ => {}; + + object boundObject; + bool boundReadOnly; + FieldInfo boundField; public override void DrawInner( WorldRenderer wr ) { @@ -35,19 +41,37 @@ namespace OpenRA.Widgets new float2(rect.Left + rect.Height * 1.5f, pos.Y - baseLine + (Bounds.Height - textSize.Y)/2), Color.White); - if (Checked()) + if ((boundObject != null && (bool)boundField.GetValue(boundObject)) || IsChecked()) WidgetUtils.DrawRGBA( ChromeProvider.GetImage("checkbox", "checked"), new float2(rect.Left + 2, rect.Top + 2)); } + + public void Bind(object obj, string field) { Bind(obj, field, false); } + public void BindReadOnly(object obj, string field) { Bind(obj, field, true); } + void Bind(object obj, string field, bool readOnly) + { + boundObject = obj; + boundReadOnly = readOnly; + boundField = obj.GetType().GetField(field); + } + // TODO: SliderWidget doesn't support delegate methods for mouse input public override bool HandleMouseInput(MouseInput mi) { // Checkboxes require lmb - if (mi.Button != MouseButton.Left) + if (mi.Button != MouseButton.Left || mi.Event != MouseInputEvent.Down) return false; - return base.HandleMouseInput(mi); + bool newVal = !IsChecked(); + if (boundObject != null && !boundReadOnly) + { + newVal = !(bool)boundField.GetValue(boundObject); + boundField.SetValue(boundObject, newVal); + } + + OnChange(newVal); + return true; } public CheckboxWidget() : base() { } @@ -56,7 +80,6 @@ namespace OpenRA.Widgets : base(other) { Text = other.Text; - Checked = other.Checked; } public override Widget Clone() { return new CheckboxWidget(this); } diff --git a/OpenRA.Mods.RA/Widgets/Delegates/CreateServerMenuDelegate.cs b/OpenRA.Mods.RA/Widgets/Delegates/CreateServerMenuDelegate.cs index 8ebf0fdea4..ab39ad30f9 100644 --- a/OpenRA.Mods.RA/Widgets/Delegates/CreateServerMenuDelegate.cs +++ b/OpenRA.Mods.RA/Widgets/Delegates/CreateServerMenuDelegate.cs @@ -41,18 +41,10 @@ namespace OpenRA.Mods.RA.Widgets.Delegates cs.GetWidget("GAME_TITLE").Text = settings.Server.Name; cs.GetWidget("LISTEN_PORT").Text = settings.Server.ListenPort.ToString(); cs.GetWidget("EXTERNAL_PORT").Text = settings.Server.ExternalPort.ToString(); - cs.GetWidget("CHECKBOX_ONLINE").Checked = () => settings.Server.AdvertiseOnline; - cs.GetWidget("CHECKBOX_ONLINE").OnMouseDown = mi => { - settings.Server.AdvertiseOnline ^= true; - settings.Save(); - return true; - }; - cs.GetWidget("CHECKBOX_CHEATS").Checked = () => settings.Server.AllowCheats; - cs.GetWidget("CHECKBOX_CHEATS").OnMouseDown = mi => { - settings.Server.AllowCheats ^=true; - settings.Save(); - return true; - }; + cs.GetWidget("CHECKBOX_ONLINE").Bind(settings.Server, "AdvertiseOnline"); + cs.GetWidget("CHECKBOX_ONLINE").OnChange += _ => settings.Save(); + cs.GetWidget("CHECKBOX_CHEATS").Bind(settings.Server, "AllowCheats"); + cs.GetWidget("CHECKBOX_CHEATS").OnChange += _ => settings.Save(); } } } diff --git a/OpenRA.Mods.RA/Widgets/Delegates/DeveloperModeDelegate.cs b/OpenRA.Mods.RA/Widgets/Delegates/DeveloperModeDelegate.cs index d2e712a394..401c8a9494 100644 --- a/OpenRA.Mods.RA/Widgets/Delegates/DeveloperModeDelegate.cs +++ b/OpenRA.Mods.RA/Widgets/Delegates/DeveloperModeDelegate.cs @@ -39,67 +39,33 @@ namespace OpenRA.Mods.RA.Widgets.Delegates return true; }; - devmodeBG.GetWidget("CHECKBOX_SHROUD").Checked = - () => world.LocalPlayer.PlayerActor.Trait().DisableShroud; - devmodeBG.GetWidget("CHECKBOX_SHROUD").OnMouseDown = mi => - { - world.IssueOrder(new Order("DevShroud", world.LocalPlayer.PlayerActor, false)); - return true; - }; - - devmodeBG.GetWidget("CHECKBOX_UNITDEBUG").Checked = - () => world.LocalPlayer.PlayerActor.Trait().UnitInfluenceDebug; - devmodeBG.GetWidget("CHECKBOX_UNITDEBUG").OnMouseDown = mi => - { - world.IssueOrder(new Order("DevUnitDebug", world.LocalPlayer.PlayerActor, false)); - return true; - }; - - devmodeBG.GetWidget("CHECKBOX_PATHDEBUG").Checked = - () => world.LocalPlayer.PlayerActor.Trait().PathDebug; - devmodeBG.GetWidget("CHECKBOX_PATHDEBUG").OnMouseDown = mi => - { - world.IssueOrder(new Order("DevPathDebug", world.LocalPlayer.PlayerActor, false)); - return true; - }; + var devTrait = world.LocalPlayer.PlayerActor.Trait(); + devmodeBG.GetWidget("CHECKBOX_SHROUD").BindReadOnly(devTrait, "DisableShroud"); + devmodeBG.GetWidget("CHECKBOX_SHROUD").OnChange += _ => Order(world, "DevShroud"); + + devmodeBG.GetWidget("CHECKBOX_UNITDEBUG").BindReadOnly(devTrait, "UnitInfluenceDebug"); + devmodeBG.GetWidget("CHECKBOX_UNITDEBUG").OnChange += _ => Order(world, "DevUnitDebug"); + devmodeBG.GetWidget("CHECKBOX_PATHDEBUG").BindReadOnly(devTrait, "PathDebug"); + devmodeBG.GetWidget("CHECKBOX_PATHDEBUG").OnChange += _ => Order(world, "DevPathDebug"); + devmodeBG.GetWidget("GIVE_CASH").OnMouseUp = mi => { world.IssueOrder(new Order("DevGiveCash", world.LocalPlayer.PlayerActor, false)); return true; }; - devmodeBG.GetWidget("INSTANT_BUILD").Checked = - () => world.LocalPlayer.PlayerActor.Trait().FastBuild; - devmodeBG.GetWidget("INSTANT_BUILD").OnMouseDown = mi => - { - world.IssueOrder(new Order("DevFastBuild", world.LocalPlayer.PlayerActor, false)); - return true; - }; + devmodeBG.GetWidget("INSTANT_BUILD").BindReadOnly(devTrait, "FastBuild"); + devmodeBG.GetWidget("INSTANT_BUILD").OnChange += _ => Order(world, "DevFastBuild"); - devmodeBG.GetWidget("INSTANT_CHARGE").Checked = - () => world.LocalPlayer.PlayerActor.Trait().FastCharge; - devmodeBG.GetWidget("INSTANT_CHARGE").OnMouseDown = mi => - { - world.IssueOrder(new Order("DevFastCharge", world.LocalPlayer.PlayerActor, false)); - return true; - }; + devmodeBG.GetWidget("INSTANT_CHARGE").BindReadOnly(devTrait, "FastCharge"); + devmodeBG.GetWidget("INSTANT_CHARGE").OnChange += _ => Order(world, "DevFastCharge"); + + devmodeBG.GetWidget("ENABLE_TECH").BindReadOnly(devTrait, "AllTech"); + devmodeBG.GetWidget("ENABLE_TECH").OnChange += _ => Order(world, "DevEnableTech"); - devmodeBG.GetWidget("ENABLE_TECH").Checked = - () => world.LocalPlayer.PlayerActor.Trait().AllTech; - devmodeBG.GetWidget("ENABLE_TECH").OnMouseDown = mi => - { - world.IssueOrder(new Order("DevEnableTech", world.LocalPlayer.PlayerActor, false)); - return true; - }; - - devmodeBG.GetWidget("UNLIMITED_POWER").Checked = - () => world.LocalPlayer.PlayerActor.Trait().UnlimitedPower; - devmodeBG.GetWidget("UNLIMITED_POWER").OnMouseDown = mi => - { - world.IssueOrder(new Order("DevUnlimitedPower", world.LocalPlayer.PlayerActor, false)); - return true; - }; + devmodeBG.GetWidget("UNLIMITED_POWER").BindReadOnly(devTrait, "UnlimitedPower"); + devmodeBG.GetWidget("UNLIMITED_POWER").OnChange += _ => Order(world, "DevUnlimitedPower"); devmodeBG.GetWidget("GIVE_EXPLORATION").OnMouseUp = mi => { @@ -109,5 +75,10 @@ namespace OpenRA.Mods.RA.Widgets.Delegates devModeButton.IsVisible = () => { return world.LobbyInfo.GlobalSettings.AllowCheats; }; } + + public void Order(World world, string order) + { + world.IssueOrder(new Order(order, world.LocalPlayer.PlayerActor, false)); + } } } diff --git a/OpenRA.Mods.RA/Widgets/Delegates/LobbyDelegate.cs b/OpenRA.Mods.RA/Widgets/Delegates/LobbyDelegate.cs index 714a3cfb13..5007da0ce3 100755 --- a/OpenRA.Mods.RA/Widgets/Delegates/LobbyDelegate.cs +++ b/OpenRA.Mods.RA/Widgets/Delegates/LobbyDelegate.cs @@ -102,16 +102,14 @@ namespace OpenRA.Mods.RA.Widgets.Delegates Game.Disconnect(); return true; }; - + var lockTeamsCheckbox = lobby.GetWidget("LOCKTEAMS_CHECKBOX"); - lockTeamsCheckbox.IsVisible = () => lockTeamsCheckbox.Visible && true; - lockTeamsCheckbox.Checked = () => orderManager.LobbyInfo.GlobalSettings.LockTeams; - lockTeamsCheckbox.OnMouseDown = mi => + lockTeamsCheckbox.BindReadOnly(orderManager.LobbyInfo.GlobalSettings, "LockTeams"); + lockTeamsCheckbox.OnChange += _ => { if (Game.IsHost) orderManager.IssueOrder(Order.Command( "lockteams {0}".F(!orderManager.LobbyInfo.GlobalSettings.LockTeams))); - return true; }; var startGameButton = lobby.GetWidget("START_GAME_BUTTON"); @@ -400,8 +398,8 @@ namespace OpenRA.Mods.RA.Widgets.Delegates team.GetText = () => (c.Team == 0) ? "-" : c.Team.ToString(); var status = template.GetWidget("STATUS"); - status.Checked = () => c.State == Session.ClientState.Ready; - status.OnMouseDown = CycleReady; + status.IsChecked = () => c.State == Session.ClientState.Ready; + status.OnChange += CycleReady; var spectator = template.GetWidget("SPECTATOR"); @@ -432,8 +430,9 @@ namespace OpenRA.Mods.RA.Widgets.Delegates team.GetText = () => (c.Team == 0) ? "-" : c.Team.ToString(); var status = template.GetWidget("STATUS"); - status.Checked = () => c.State == Session.ClientState.Ready; - if (c.Index == orderManager.LocalClient.Index) status.OnMouseDown = CycleReady; + status.IsChecked = () => c.State == Session.ClientState.Ready; + if (c.Index == orderManager.LocalClient.Index) + status.OnChange += CycleReady; var spectator = template.GetWidget("SPECTATOR"); @@ -462,10 +461,9 @@ namespace OpenRA.Mods.RA.Widgets.Delegates bool SpawnPointAvailable(int index) { return (index == 0) || orderManager.LobbyInfo.Clients.All(c => c.SpawnPoint != index); } - bool CycleReady(MouseInput mi) + void CycleReady(bool ready) { orderManager.IssueOrder(Order.Command("ready")); - return true; } } } diff --git a/OpenRA.Mods.RA/Widgets/Delegates/MusicPlayerDelegate.cs b/OpenRA.Mods.RA/Widgets/Delegates/MusicPlayerDelegate.cs index f9434f589d..fdd753511d 100644 --- a/OpenRA.Mods.RA/Widgets/Delegates/MusicPlayerDelegate.cs +++ b/OpenRA.Mods.RA/Widgets/Delegates/MusicPlayerDelegate.cs @@ -72,22 +72,9 @@ namespace OpenRA.Mods.RA.Widgets.Delegates return bg.GetWidget("BUTTON_PLAY").OnMouseUp(mi); }; - var shuffle = bg.GetWidget("SHUFFLE"); - shuffle.OnMouseDown = mi => - { - Game.Settings.Sound.Shuffle ^= true; - return true; - }; - shuffle.Checked = () => Game.Settings.Sound.Shuffle; - - var repeat = bg.GetWidget("REPEAT"); - repeat.OnMouseDown = mi => - { - Game.Settings.Sound.Repeat ^= true; - return true; - }; - repeat.Checked = () => Game.Settings.Sound.Repeat; - + bg.GetWidget("SHUFFLE").Bind(Game.Settings.Sound, "Shuffle"); + bg.GetWidget("REPEAT").Bind(Game.Settings.Sound, "Repeat"); + bg.GetWidget("TIME").GetText = () => { if (CurrentSong == null) diff --git a/OpenRA.Mods.RA/Widgets/Delegates/SettingsMenuDelegate.cs b/OpenRA.Mods.RA/Widgets/Delegates/SettingsMenuDelegate.cs index 2cacb6d14f..c4b6a130e3 100755 --- a/OpenRA.Mods.RA/Widgets/Delegates/SettingsMenuDelegate.cs +++ b/OpenRA.Mods.RA/Widgets/Delegates/SettingsMenuDelegate.cs @@ -46,13 +46,7 @@ namespace OpenRA.Mods.RA.Widgets.Delegates }; name.OnEnterKey = () => { name.LoseFocus(); return true; }; - var edgeScroll = general.GetWidget("EDGE_SCROLL"); - edgeScroll.Checked = () => Game.Settings.Game.ViewportEdgeScroll; - edgeScroll.OnMouseDown = mi => - { - Game.Settings.Game.ViewportEdgeScroll ^= true; - return true; - }; + general.GetWidget("EDGE_SCROLL").Bind(Game.Settings.Game, "ViewportEdgeScroll"); // Added scroll sensitivity - Gecko var edgeScrollSlider = general.GetWidget("EDGE_SCROLL_AMOUNT"); @@ -63,21 +57,9 @@ namespace OpenRA.Mods.RA.Widgets.Delegates Game.Settings.Game.ViewportEdgeScrollStep = edgeScrollSlider.GetOffset(); } - var inverseScroll = general.GetWidget("INVERSE_SCROLL"); - inverseScroll.Checked = () => Game.Settings.Game.InverseDragScroll; - inverseScroll.OnMouseDown = mi => - { - Game.Settings.Game.InverseDragScroll ^= true; - return true; - }; + general.GetWidget("INVERSE_SCROLL").Bind(Game.Settings.Game, "InverseDragScroll"); + general.GetWidget("TEAMCHAT_TOGGLE").Bind(Game.Settings.Game, "TeamChatToggle"); - var teamChatToggle = general.GetWidget("TEAMCHAT_TOGGLE"); - teamChatToggle.Checked = () => Game.Settings.Game.TeamChatToggle; - teamChatToggle.OnMouseDown = mi => - { - Game.Settings.Game.TeamChatToggle ^= true; - return true; - }; // Audio var audio = bg.GetWidget("AUDIO_PANE"); @@ -95,14 +77,12 @@ namespace OpenRA.Mods.RA.Widgets.Delegates // Display var display = bg.GetWidget("DISPLAY_PANE"); + display.GetWidget("FULLSCREEN_CHECKBOX").Bind(Game.Settings.Game, "TeamChatToggle"); + var fullscreen = display.GetWidget("FULLSCREEN_CHECKBOX"); - fullscreen.Checked = () => {return Game.Settings.Graphics.Mode != WindowMode.Windowed;}; - fullscreen.OnMouseDown = mi => - { - Game.Settings.Graphics.Mode = (Game.Settings.Graphics.Mode == WindowMode.Windowed) ? WindowMode.PseudoFullscreen : WindowMode.Windowed; - return true; - }; - + fullscreen.IsChecked = () => Game.Settings.Graphics.Mode != WindowMode.Windowed; + fullscreen.OnChange += c => Game.Settings.Graphics.Mode = (Game.Settings.Graphics.Mode == WindowMode.Windowed) ? WindowMode.PseudoFullscreen : WindowMode.Windowed; + var width = display.GetWidget("SCREEN_WIDTH"); Game.Settings.Graphics.WindowedSize.X = (Game.Settings.Graphics.WindowedSize.X < Game.Settings.Graphics.MinResolution.X)? Game.Settings.Graphics.MinResolution.X : Game.Settings.Graphics.WindowedSize.X; @@ -141,22 +121,9 @@ namespace OpenRA.Mods.RA.Widgets.Delegates // Debug var debug = bg.GetWidget("DEBUG_PANE"); - var perfdebug = debug.GetWidget("PERFDEBUG_CHECKBOX"); - perfdebug.Checked = () => {return Game.Settings.Debug.PerfGraph;}; - perfdebug.OnMouseDown = mi => - { - Game.Settings.Debug.PerfGraph ^= true; - return true; - }; - - var timedebug = debug.GetWidget("GAMETIME_CHECKBOX"); - timedebug.Checked = () => {return Game.Settings.Game.MatchTimer;}; - timedebug.OnMouseDown = mi => - { - Game.Settings.Game.MatchTimer ^= true; - return true; - }; - + debug.GetWidget("PERFDEBUG_CHECKBOX").Bind(Game.Settings.Debug, "PerfGraph"); + debug.GetWidget("GAMETIME_CHECKBOX").Bind(Game.Settings.Game, "MatchTimer"); + bg.GetWidget("BUTTON_CLOSE").OnMouseUp = mi => { Game.Settings.Save(); Widget.CloseWindow();