Reimplement music player

This commit is contained in:
Paul Chote
2011-05-10 20:27:51 +12:00
parent 7c18614bf3
commit c4f40babb5
8 changed files with 378 additions and 165 deletions

View File

@@ -80,6 +80,7 @@
<Compile Include="Widgets\CncConnectionLogic.cs" />
<Compile Include="Widgets\CncIngameChromeLogic.cs" />
<Compile Include="Widgets\CncInstallLogic.cs" />
<Compile Include="Widgets\CncMusicPlayerLogic.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">

View File

@@ -90,6 +90,9 @@ namespace OpenRA.Mods.Cnc.Widgets
menu = widget.GetWidget("INGAME_MENU");
world.WorldActor.Trait<DesaturatedPaletteEffect>().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<CncMenuButtonWidget>("MUSIC_BUTTON").IsDisabled = () => true;
menu.GetWidget<CncMenuButtonWidget>("MUSIC_BUTTON").OnClick = () =>
{
hideButtons = true;
Widget.OpenWindow("MUSIC_PANEL", new Dictionary<string, object>()
{
{ "onExit", new Action(() => { hideButtons = false; Widget.CloseWindow(); }) },
});
};
menu.GetWidget<CncMenuButtonWidget>("PREFERENCES_BUTTON").IsDisabled = () => true;
menu.GetWidget<CncMenuButtonWidget>("RESUME_BUTTON").OnClick = () =>

View File

@@ -99,7 +99,15 @@ namespace OpenRA.Mods.Cnc.Widgets
settingsMenu.IsVisible = () => Menu == MenuType.Settings;
settingsMenu.GetWidget<CncMenuButtonWidget>("MODS_BUTTON").IsDisabled = () => true;
settingsMenu.GetWidget<CncMenuButtonWidget>("MUSIC_BUTTON").IsDisabled = () => true;
settingsMenu.GetWidget<CncMenuButtonWidget>("MUSIC_BUTTON").OnClick = () =>
{
Menu = MenuType.None;
Widget.OpenWindow("MUSIC_PANEL", new Dictionary<string, object>()
{
{ "onExit", new Action(() => ReturnToMenu(MenuType.Main)) },
});
};
settingsMenu.GetWidget<CncMenuButtonWidget>("PREFERENCES_BUTTON").IsDisabled = () => true;
settingsMenu.GetWidget<CncMenuButtonWidget>("BACK_BUTTON").OnClick = () => Menu = MenuType.Main;
}

View File

@@ -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<bool> noMusic = () => !installed;
panel.GetWidget<CncMenuButtonWidget>("BACK_BUTTON").OnClick = onExit;
panel.GetWidget<CncMenuButtonWidget>("INSTALL_BUTTON").IsDisabled = () => true;
panel.GetWidget("NO_MUSIC_LABEL").IsVisible = noMusic;
var playButton = panel.GetWidget<CncMenuButtonWidget>("BUTTON_PLAY");
playButton.OnClick = Play;
playButton.IsDisabled = noMusic;
var pauseButton = panel.GetWidget<CncMenuButtonWidget>("BUTTON_PAUSE");
pauseButton.OnClick = Pause;
pauseButton.IsDisabled = noMusic;
var stopButton = panel.GetWidget<CncMenuButtonWidget>("BUTTON_STOP");
stopButton.OnClick = Stop;
stopButton.IsDisabled = noMusic;
var nextButton = panel.GetWidget<CncMenuButtonWidget>("BUTTON_NEXT");
nextButton.OnClick = () => { currentSong = GetNextSong(); Play(); };
nextButton.IsDisabled = noMusic;
var prevButton = panel.GetWidget<CncMenuButtonWidget>("BUTTON_PREV");
prevButton.OnClick = () => { currentSong = GetPrevSong(); Play(); };
prevButton.IsDisabled = noMusic;
var shuffleCheckbox = panel.GetWidget<CncCheckboxWidget>("SHUFFLE");
shuffleCheckbox.IsChecked = () => Game.Settings.Sound.Shuffle;
shuffleCheckbox.OnClick = () => Game.Settings.Sound.Shuffle ^= true;
var repeatCheckbox = panel.GetWidget<CncCheckboxWidget>("REPEAT");
repeatCheckbox.IsChecked = () => Game.Settings.Sound.Repeat;
repeatCheckbox.OnClick = () => Game.Settings.Sound.Repeat ^= true;
panel.GetWidget<LabelWidget>("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<ScrollPanelWidget>("MUSIC_LIST");
var itemTemplate = ml.GetWidget<ContainerWidget>("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<LabelWidget>("TITLE").GetText = () => Rules.Music[song].Title;
template.GetWidget<LabelWidget>("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();
}
}
}

View File

@@ -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

185
mods/cnc/chrome/music.yaml Normal file
View File

@@ -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

View File

@@ -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

View File

@@ -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