diff --git a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj index 70872d0c8b..0072033ca7 100644 --- a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj +++ b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj @@ -80,6 +80,7 @@ + diff --git a/OpenRA.Mods.Cnc/Widgets/CncIngameChromeLogic.cs b/OpenRA.Mods.Cnc/Widgets/CncIngameChromeLogic.cs index c6a6748d64..7ee6de97a6 100755 --- a/OpenRA.Mods.Cnc/Widgets/CncIngameChromeLogic.cs +++ b/OpenRA.Mods.Cnc/Widgets/CncIngameChromeLogic.cs @@ -89,7 +89,10 @@ namespace OpenRA.Mods.Cnc.Widgets { menu = widget.GetWidget("INGAME_MENU"); world.WorldActor.Trait().Active = true; - + + bool hideButtons = false; + menu.GetWidget("MENU_BUTTONS").IsVisible = () => !hideButtons; + var onQuit = (Action)(() => { Game.DisconnectOnly(); @@ -108,7 +111,15 @@ namespace OpenRA.Mods.Cnc.Widgets surrenderButton.OnClick = () => PromptConfirmAction("Surrender", "Are you sure you want to surrender?", onSurrender, doNothing); - menu.GetWidget("MUSIC_BUTTON").IsDisabled = () => true; + menu.GetWidget("MUSIC_BUTTON").OnClick = () => + { + hideButtons = true; + Widget.OpenWindow("MUSIC_PANEL", new Dictionary() + { + { "onExit", new Action(() => { hideButtons = false; Widget.CloseWindow(); }) }, + }); + }; + menu.GetWidget("PREFERENCES_BUTTON").IsDisabled = () => true; menu.GetWidget("RESUME_BUTTON").OnClick = () => diff --git a/OpenRA.Mods.Cnc/Widgets/CncMenuLogic.cs b/OpenRA.Mods.Cnc/Widgets/CncMenuLogic.cs index 5113b4a898..4be5310c24 100755 --- a/OpenRA.Mods.Cnc/Widgets/CncMenuLogic.cs +++ b/OpenRA.Mods.Cnc/Widgets/CncMenuLogic.cs @@ -99,7 +99,15 @@ namespace OpenRA.Mods.Cnc.Widgets settingsMenu.IsVisible = () => Menu == MenuType.Settings; settingsMenu.GetWidget("MODS_BUTTON").IsDisabled = () => true; - settingsMenu.GetWidget("MUSIC_BUTTON").IsDisabled = () => true; + settingsMenu.GetWidget("MUSIC_BUTTON").OnClick = () => + { + Menu = MenuType.None; + Widget.OpenWindow("MUSIC_PANEL", new Dictionary() + { + { "onExit", new Action(() => ReturnToMenu(MenuType.Main)) }, + }); + }; + settingsMenu.GetWidget("PREFERENCES_BUTTON").IsDisabled = () => true; settingsMenu.GetWidget("BACK_BUTTON").OnClick = () => Menu = MenuType.Main; } diff --git a/OpenRA.Mods.Cnc/Widgets/CncMusicPlayerLogic.cs b/OpenRA.Mods.Cnc/Widgets/CncMusicPlayerLogic.cs new file mode 100644 index 0000000000..1f661ce170 --- /dev/null +++ b/OpenRA.Mods.Cnc/Widgets/CncMusicPlayerLogic.cs @@ -0,0 +1,167 @@ +#region Copyright & License Information +/* + * Copyright 2007-2011 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. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Drawing; +using System.Linq; +using OpenRA.FileFormats; +using OpenRA.Support; +using OpenRA.Widgets; +using OpenRA.Traits; +using OpenRA.Graphics; + +namespace OpenRA.Mods.Cnc.Widgets +{ + public class CncMusicPlayerLogic : IWidgetDelegate + { + bool installed; + string currentSong = null; + Widget panel; + string[] music; + string[] random; + + [ObjectCreator.UseCtor] + public CncMusicPlayerLogic([ObjectCreator.Param] Widget widget, + [ObjectCreator.Param] Action onExit) + { + panel = widget.GetWidget("MUSIC_PANEL"); + BuildMusicTable(panel); + + currentSong = GetNextSong(); + installed = Rules.Music.Where(m => m.Value.Exists).Any(); + Func noMusic = () => !installed; + + panel.GetWidget("BACK_BUTTON").OnClick = onExit; + panel.GetWidget("INSTALL_BUTTON").IsDisabled = () => true; + panel.GetWidget("NO_MUSIC_LABEL").IsVisible = noMusic; + + var playButton = panel.GetWidget("BUTTON_PLAY"); + playButton.OnClick = Play; + playButton.IsDisabled = noMusic; + + var pauseButton = panel.GetWidget("BUTTON_PAUSE"); + pauseButton.OnClick = Pause; + pauseButton.IsDisabled = noMusic; + + var stopButton = panel.GetWidget("BUTTON_STOP"); + stopButton.OnClick = Stop; + stopButton.IsDisabled = noMusic; + + var nextButton = panel.GetWidget("BUTTON_NEXT"); + nextButton.OnClick = () => { currentSong = GetNextSong(); Play(); }; + nextButton.IsDisabled = noMusic; + + var prevButton = panel.GetWidget("BUTTON_PREV"); + prevButton.OnClick = () => { currentSong = GetPrevSong(); Play(); }; + prevButton.IsDisabled = noMusic; + + var shuffleCheckbox = panel.GetWidget("SHUFFLE"); + shuffleCheckbox.IsChecked = () => Game.Settings.Sound.Shuffle; + shuffleCheckbox.OnClick = () => Game.Settings.Sound.Shuffle ^= true; + + var repeatCheckbox = panel.GetWidget("REPEAT"); + repeatCheckbox.IsChecked = () => Game.Settings.Sound.Repeat; + repeatCheckbox.OnClick = () => Game.Settings.Sound.Repeat ^= true; + + panel.GetWidget("TIME_LABEL").GetText = () => (currentSong == null) ? "" : + "{0:D2}:{1:D2} / {2:D2}:{3:D2}".F((int)Sound.MusicSeekPosition / 60, (int)Sound.MusicSeekPosition % 60, + Rules.Music[currentSong].Length / 60, Rules.Music[currentSong].Length % 60); + } + + void BuildMusicTable(Widget panel) + { + music = Rules.Music.Where(a => a.Value.Exists) + .Select(a => a.Key).ToArray(); + random = music.Shuffle(Game.CosmeticRandom).ToArray(); + + var ml = panel.GetWidget("MUSIC_LIST"); + var itemTemplate = ml.GetWidget("MUSIC_TEMPLATE"); + + foreach (var s in music) + { + var song = s; + if (currentSong == null) + currentSong = song; + + var template = itemTemplate.Clone() as ContainerWidget; + template.GetBackground = () => (template.RenderBounds.Contains(Viewport.LastMousePos) ? "button-hover" : (song == currentSong) ? "button-pressed" : null); + template.OnMouseDown = mi => + { + if (mi.Button != MouseButton.Left) return false; + currentSong = song; + Play(); + return true; + }; + + template.IsVisible = () => true; + template.GetWidget("TITLE").GetText = () => Rules.Music[song].Title; + template.GetWidget("LENGTH").GetText = () => SongLengthLabel(song); + ml.AddChild(template); + } + } + + + void Play() + { + if (currentSong == null) + return; + + Sound.PlayMusicThen(Rules.Music[currentSong].Filename, () => + { + if (!Game.Settings.Sound.Repeat) + currentSong = GetNextSong(); + Play(); + }); + + panel.GetWidget("BUTTON_PLAY").Visible = false; + panel.GetWidget("BUTTON_PAUSE").Visible = true; + } + + void Pause() + { + Sound.PauseMusic(); + panel.GetWidget("BUTTON_PAUSE").Visible = false; + panel.GetWidget("BUTTON_PLAY").Visible = true; + } + + void Stop() + { + Sound.StopMusic(); + panel.GetWidget("BUTTON_PAUSE").Visible = false; + panel.GetWidget("BUTTON_PLAY").Visible = true; + } + + string SongLengthLabel(string song) + { + return "{0:D1}:{1:D2}".F(Rules.Music[song].Length / 60, + Rules.Music[song].Length % 60); + } + + string GetNextSong() + { + if (!music.Any()) + return null; + + var songs = Game.Settings.Sound.Shuffle ? random : music; + return songs.SkipWhile(m => m != currentSong) + .Skip(1).FirstOrDefault() ?? songs.FirstOrDefault(); + } + + string GetPrevSong() + { + if (!music.Any()) + return null; + + var songs = Game.Settings.Sound.Shuffle ? random : music; + return songs.Reverse().SkipWhile(m => m != currentSong) + .Skip(1).FirstOrDefault() ?? songs.FirstOrDefault(); + } + } +} diff --git a/mods/cnc/chrome/ingamemenu.yaml b/mods/cnc/chrome/ingamemenu.yaml index 26b83b16f2..9f70a84c83 100644 --- a/mods/cnc/chrome/ingamemenu.yaml +++ b/mods/cnc/chrome/ingamemenu.yaml @@ -19,7 +19,8 @@ Container@INGAME_MENU: Width:WINDOW_RIGHT Height:WINDOW_BOTTOM Background:shellmapborder - Container@MENUS: + Container@MENU_BUTTONS: + Id:MENU_BUTTONS X:(WINDOW_RIGHT-WIDTH)/2 Y:WINDOW_BOTTOM-33-HEIGHT-10 Width:740 diff --git a/mods/cnc/chrome/music.yaml b/mods/cnc/chrome/music.yaml new file mode 100644 index 0000000000..d12102ad4d --- /dev/null +++ b/mods/cnc/chrome/music.yaml @@ -0,0 +1,185 @@ +Container@MUSIC_PANEL: + Id:MUSIC_PANEL + Delegate:CncMusicPlayerLogic + X:(WINDOW_RIGHT - WIDTH)/2 + Y:(WINDOW_BOTTOM - 400)/2 + Width:360 + Height:435 + Children: + Label@TITLE: + Width:360 + Y:0-25 + Font:BigBold + Contrast:true + Align:Center + Text:Music Player + Background@bg: + Width:360 + Height:400 + Background:panel-black + Children: + CncScrollPanel@MUSIC_LIST: + Id:MUSIC_LIST + X:15 + Y:30 + Width:330 + Height:275 + Children: + Container@MUSIC_TEMPLATE: + Id:MUSIC_TEMPLATE + Width:PARENT_RIGHT-27 + Height:25 + X:2 + Y:0 + Visible:false + Children: + Label@TITLE: + X:10 + Id:TITLE + Width:PARENT_RIGHT-50 + Height:25 + Label@LENGTH: + Id:LENGTH + Width:50 + X:PARENT_RIGHT-60 + Align:Right + Height:25 + Label@NO_MUSIC_LABEL: + Id:NO_MUSIC_LABEL + X:15 + Y:147 + Width:330 + Height:25 + Font:Bold + Align:Center + Visible:false + Text:No Music Installed + Container@LABEL_CONTAINER: + X:25 + Y:5 + Width:330 + Children: + Label@TITLE: + Width:100 + Height:25 + Text:Track + Align:Center + Bold:True + Label@TYPE: + X:PARENT_RIGHT-85 + Height:25 + Width:50 + Text:Length + Align:Right + Bold:True + Container@BUTTONS: + X:(PARENT_RIGHT-WIDTH)/2 + Y:320 + Width:170 + Children: + CncMenuButton@BUTTON_PREV: + Id:BUTTON_PREV + Width:35 + Height:35 + Children: + Image@IMAGE_PREV: + Id:IMAGE_PREV + X:5 + Y:5 + Width:25 + Height:25 + ImageCollection:music + ImageName:prev + CncMenuButton@BUTTON_PLAY: + Id:BUTTON_PLAY + X:45 + Width:35 + Height:35 + Children: + Image@IMAGE_PLAY: + Id:IMAGE_PLAY + X:5 + Y:5 + Width:25 + Height:25 + ImageCollection:music + ImageName:play + CncMenuButton@BUTTON_PAUSE: + Id:BUTTON_PAUSE + Visible:false + X:45 + Width:35 + Height:35 + Children: + Image@IMAGE_PAUSE: + Id:IMAGE_PAUSE + X:5 + Y:5 + Width:25 + Height:25 + ImageCollection:music + ImageName:pause + CncMenuButton@BUTTON_STOP: + Id:BUTTON_STOP + X:90 + Width:35 + Height:35 + Children: + Image@IMAGE_STOP: + Id:IMAGE_STOP + X:5 + Y:5 + Width:25 + Height:25 + ImageCollection:music + ImageName:stop + CncMenuButton@BUTTON_NEXT: + Id:BUTTON_NEXT + X:135 + Width:35 + Height:35 + Children: + Image@IMAGE_NEXT: + Id:IMAGE_NEXT + X:5 + Y:5 + Width:25 + Height:25 + ImageCollection:music + ImageName:next + Label@TIME_LABEL: + Id:TIME_LABEL + X:(PARENT_RIGHT-WIDTH)/2 + Y:PARENT_BOTTOM-13-HEIGHT + Width:140 + Height:25 + Align:Center + Font:Bold + CncCheckbox@SHUFFLE: + Id:SHUFFLE + X:15 + Y:PARENT_BOTTOM-15-HEIGHT + Width:85 + Height:20 + Text:Shuffle + CncCheckbox@REPEAT: + Id:REPEAT + X:PARENT_RIGHT-15-WIDTH + Y:PARENT_BOTTOM-15-HEIGHT + Width:70 + Height:20 + Text:Loop + CncMenuButton@BACK_BUTTON: + Id:BACK_BUTTON + X:0 + Y:399 + Width:140 + Height:35 + Text:Back + CncMenuButton@INSTALL_BUTTON: + Id:INSTALL_BUTTON + X:220 + Y:399 + Width:140 + Height:35 + Text:Install Music \ No newline at end of file diff --git a/mods/cnc/chrome/unused/music.yaml b/mods/cnc/chrome/unused/music.yaml deleted file mode 100644 index 8cead0b75c..0000000000 --- a/mods/cnc/chrome/unused/music.yaml +++ /dev/null @@ -1,161 +0,0 @@ -Background@MUSIC_MENU: - Id:MUSIC_MENU - Delegate:MusicPlayerDelegate - X:(WINDOW_RIGHT - WIDTH)/2 - Y:(WINDOW_BOTTOM - HEIGHT)/2 - Width: 450 - Height: 250 - Children: - Label@SETTINGS_LABEL_TITLE: - Id:SETTINGS_LABEL_TITLE - X:0 - Y:20 - Width:450 - Height:25 - Text:Music - Align:Center - Font:Bold - Button@BUTTON_INSTALL: - Id:BUTTON_INSTALL - X:20 - Y:PARENT_BOTTOM - 45 - Width:160 - Height:25 - Text:Install Music - Font:Bold - Button@BUTTON_CLOSE: - Id:BUTTON_CLOSE - X:PARENT_RIGHT - 180 - Y:PARENT_BOTTOM - 45 - Width:160 - Height:25 - Text:Close - Font:Bold - Container@BUTTONS: - X:PARENT_RIGHT - 150 - Y:50 - Children: - Button@BUTTON_PLAY: - Id:BUTTON_PLAY - X:35 - Y:0 - Width:25 - Height:25 - Children: - Image@IMAGE_PLAY: - Id:IMAGE_PLAY - X:0 - Y:0 - Width:25 - Height:25 - ImageCollection:music - ImageName:play - Button@BUTTON_PAUSE: - Id:BUTTON_PAUSE - Visible:false - X:35 - Y:0 - Width:25 - Height:25 - Children: - Image@IMAGE_PAUSE: - Id:IMAGE_PAUSE - X:0 - Y:0 - Width:25 - Height:25 - ImageCollection:music - ImageName:pause - Button@BUTTON_STOP: - Id:BUTTON_STOP - X:70 - Y:0 - Width:25 - Height:25 - Children: - Image@IMAGE_STOP: - Id:IMAGE_STOP - X:0 - Y:0 - Width:25 - Height:25 - ImageCollection:music - ImageName:stop - Button@BUTTON_NEXT: - Id:BUTTON_NEXT - X:105 - Y:0 - Width:25 - Height:25 - Children: - Image@IMAGE_NEXT: - Id:IMAGE_NEXT - X:0 - Y:0 - Width:25 - Height:25 - ImageCollection:music - ImageName:next - Button@BUTTON_PREV: - Id:BUTTON_PREV - X:0 - Y:0 - Width:25 - Height:25 - Children: - Image@IMAGE_PREV: - Id:IMAGE_PREV - X:0 - Y:0 - Width:25 - Height:25 - ImageCollection:music - ImageName:prev - Label@TIME: - Id:TIME - X:PARENT_RIGHT - 150 - Y:75 - Width:140 - Height:25 - Align: Center - ScrollPanel@MUSIC_LIST: - Id:MUSIC_LIST - X:10 - Y:50 - Width:280 - Height:140 - Children: - Label@MUSIC_TEMPLATE: - Id:MUSIC_TEMPLATE - Width:PARENT_RIGHT-28 - Height:25 - X:2 - Y:0 - Visible:false - Children: - Label@TITLE: - Id:TITLE - X:5 - Width:PARENT_RIGHT - 10 - Height:PARENT_BOTTOM - Align: Left - Label@LENGTH: - Id:LENGTH - X:5 - Width:PARENT_RIGHT - 10 - Height:PARENT_BOTTOM - Align: Right - Checkbox@SHUFFLE: - Id:SHUFFLE - X:PARENT_RIGHT - 150 - Y:110 - Width:100 - Height:20 - Text:Shuffle - Checkbox@REPEAT: - Id:REPEAT - X:PARENT_RIGHT - 150 - Y:140 - Width:100 - Height:20 - Text:Loop \ No newline at end of file diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index c773aa5c16..5174895fd1 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -72,6 +72,7 @@ ChromeLayout: mods/cnc/chrome/replaybrowser.yaml mods/cnc/chrome/ingame.yaml mods/cnc/chrome/ingamemenu.yaml + mods/cnc/chrome/music.yaml Weapons: mods/cnc/weapons.yaml