#region license // This file is part of Vocaluxe. // // Vocaluxe is free software: you can redistribute it and/or modify // it 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. // // Vocaluxe is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Vocaluxe. If not, see . #endregion using System.Diagnostics; using System.Xml.Serialization; using VocaluxeLib.PartyModes; using VocaluxeLib.Songs; namespace VocaluxeLib.Menu.SongMenu { [XmlType("SongMenu")] public struct SThemeSongMenu { [XmlAttribute(AttributeName = "Name")] public string Name; public string CoverBackground; public string CoverBigBackground; public string DuetIcon; public string VideoIcon; public string MedleyCalcIcon; public string MedleyTagIcon; public SThemeColor Color; //public SThemeSongMenuBook songMenuBook; //public SThemeSongMenuDreidel songMenuDreidel; public SThemeSongMenuList SongMenuList; public SThemeSongMenuTileBoard SongMenuTileBoard; } public struct SThemeSongMenuList { /// /// Number of visible songs in list /// public int ListLength; /// /// Space between tiles horizontal /// public float SpaceW; /// /// Space between tiles vertical /// public float SpaceH; public SRectF TileRect; public SRectF TileRectSmall; public SThemeText TextArtist; public SThemeText TextTitle; public SThemeText TextSongLength; public SThemeStatic StaticCoverBig; public SThemeStatic StaticTextBG; public SThemeStatic StaticDuetIcon; public SThemeStatic StaticVideoIcon; public SThemeStatic StaticMedleyCalcIcon; public SThemeStatic StaticMedleyTagIcon; } public struct SThemeSongMenuTileBoard { /// /// Number of tiles horizontal /// public int NumW; /// /// Number of tiles vertical /// public int NumH; /// /// Number of tiles horizontal in small-modus /// public int NumWsmall; /// /// Number of tiles vertical in small-modus /// public int NumHsmall; /// /// Space between tiles horizontal /// public float SpaceW; /// /// Space between tiles vertical /// public float SpaceH; public SRectF TileRect; public SRectF TileRectSmall; public SThemeText TextArtist; public SThemeText TextTitle; public SThemeText TextSongLength; public SThemeStatic StaticCoverBig; public SThemeStatic StaticTextBG; public SThemeStatic StaticDuetIcon; public SThemeStatic StaticVideoIcon; public SThemeStatic StaticMedleyCalcIcon; public SThemeStatic StaticMedleyTagIcon; } public abstract class CSongMenuFramework : CMenuElementBase, ISongMenu { protected readonly int _PartyModeID; protected SThemeSongMenu _Theme; public bool ThemeLoaded { get; private set; } public bool Selectable { get { return Visible; } } protected bool _Initialized; private int _PreviewNrInternal = -1; protected virtual int _PreviewNr { get { return _PreviewNrInternal; } set { if (_PreviewNrInternal == value) return; if (CBase.Songs.IsInCategory()) { if (value >= CBase.Songs.GetNumSongsVisible()) value = -1; _PlaySong(value); } else if (value >= CBase.Songs.GetNumCategories()) { value = -1; CBase.BackgroundMusic.SetPlayingPreview(false); } _PreviewNrInternal = value; } } protected int _AutoplayDelayinMs = CBase.Config.GetAutoplayPreviewDelay(); protected System.Timers.Timer _AutoplayTimer = new System.Timers.Timer(); private SColorF _ColorInternal; protected SColorF _Color { get { return _ColorInternal; } } public int GetPreviewSong() { return _PreviewNr; } public virtual bool SmallView { get; set; } public abstract float SelectedTileZoomFactor { get; } // This is the nr of the current selection (song or category) protected virtual int _SelectionNr { get; set; } protected CSongMenuFramework(int partyModeID) { Visible = true; _PartyModeID = partyModeID; } protected CSongMenuFramework(SThemeSongMenu theme, int partyModeID) { Visible = true; _PartyModeID = partyModeID; _Theme = theme; ThemeLoaded = true; } #region Theme public string GetThemeName() { return _Theme.Name; } public virtual object GetTheme() { return _Theme; } #endregion Theme public virtual void Init() { _ResetPreview(false); _InitializeAutoplayTimer(); _Initialized = true; } public abstract void Update(SScreenSongOptions songOptions); public abstract void OnShow(); public virtual void OnHide() { EScreen check = CBase.Graphics.GetNextScreenType(); if (CBase.Graphics.GetNextScreenType() == EScreen.Sing) _ResetPreview(false); else if ((CBase.Graphics.GetNextScreenType() != EScreen.Names && CBase.Graphics.GetNextScreenType() != EScreen.Highscore) || CBase.Config.GetBackgroundMusicStatus() == EBackgroundMusicOffOn.TR_CONFIG_OFF) _ResetPreview(); } public abstract bool HandleInput(ref SKeyEvent keyEvent, SScreenSongOptions options); public abstract bool HandleMouse(ref SMouseEvent mouseEvent, SScreenSongOptions songOptions); public virtual void Draw() { if (!_Initialized || !Visible) return; if (CBase.BackgroundMusic.IsPlaying()) CBase.Drawing.DrawTexture(CBase.BackgroundMusic.GetVideoTexture(), new SRectF(0, 0, 1280, 720, 0)); } public virtual bool IsMouseOverSelectedSong(SMouseEvent mEvent) { CStatic selCov = GetSelectedSongCover(); return selCov != null && CHelper.IsInBounds(selCov.Rect.Scale(SelectedTileZoomFactor), mEvent); } public int GetPreviewSongNr() { if (CBase.Songs.IsInCategory()) return _PreviewNr; return -1; } public int GetSelectedSongNr() { if (CBase.Songs.IsInCategory()) return _SelectionNr; return -1; } public abstract CStatic GetSelectedSongCover(); public int GetSelectedCategory() { if (!CBase.Songs.IsInCategory()) return _SelectionNr; return -1; } public void SetSelectedSong(int visibleSongNr) { Debug.Assert(CBase.Songs.IsInCategory()); if (visibleSongNr >= 0 && visibleSongNr < CBase.Songs.GetNumSongsVisible()) _SelectionNr = visibleSongNr; else _SelectionNr = -1; _PreviewNr = _SelectionNr; } public void SetSelectedCategory(int categoryNr) { Debug.Assert(!CBase.Songs.IsInCategory()); if (categoryNr >= 0 && categoryNr < CBase.Songs.GetNumCategories()) _SelectionNr = categoryNr; else _SelectionNr = -1; _PreviewNr = _SelectionNr; } public void LeaveSelectedCategory() { // Stefan1200: This was implemented with the pull request #359 and is the reason for the bug described in issue #390. // Currently disabled until we know if this is still needed or we find a better solution! // _LeaveCategory(); } public virtual void UnloadSkin() {} public virtual void LoadSkin() { Init(); _Theme.Color.Get(_PartyModeID, out _ColorInternal); } public void ReloadSkin() { UnloadSkin(); LoadSkin(); } public bool EnterSelectedCategory() { if (!_Initialized) return false; if (CBase.Songs.IsInCategory() || GetSelectedCategory() < 0 || GetSelectedCategory() >= CBase.Songs.GetNumCategories()) return false; _EnterCategory(GetSelectedCategory()); return true; } protected virtual void _EnterCategory(int categoryNr) { if (!_Initialized) return; if (categoryNr >= CBase.Songs.GetNumCategories()) return; _ResetPreview(false); CBase.Songs.SetCategory(categoryNr); } protected virtual void _LeaveCategory() { if (!_Initialized) return; if (!CBase.Songs.IsInCategory()) return; _ResetPreview(); CBase.Songs.SetCategory(-1); } private void _PlaySong(int nr) { _PreviewNrInternal = -1; CSong song = CBase.Songs.GetVisibleSong(nr); if (song == null) return; CBase.BackgroundMusic.LoadPreview(song, song.Preview.StartTime); } protected void _ResetPreview(bool playBGagain = true) { if (_PreviewNrInternal == -1) return; CBase.BackgroundMusic.StopPreview(); CBase.Sound.SetGlobalVolume(CBase.Config.GetMusicVolume(EMusicType.Background)); if (playBGagain) CBase.BackgroundMusic.Play(); //Make sure we don't have a preview here otherwise a change won't be recognized //(e.g. leave a category with one song and set preview to 0 --> previewOld=previewNew=0 --> No change --> Old data shown //Use internal nr because this function gets called from withing setPreviewNr _PreviewNrInternal = -1; } protected void _PreviewSelectedSong() { _PreviewNr = _SelectionNr; } protected void _InitializeAutoplayTimer() { _AutoplayTimer.Interval = _AutoplayDelayinMs; _AutoplayTimer.AutoReset = false; _AutoplayTimer.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) => { _PreviewSelectedSong(); }; } protected void _AutoplayPreviewIfEnabled() { if (CBase.Config.GetAutoplayPreviews() == EOffOn.TR_CONFIG_ON) { _PlayPreviewAfterDelay(); } } protected void _PlayPreviewAfterDelay() { if (!_AutoplayTimer.Enabled) { _AutoplayTimer.Start(); } else { _AutoplayTimer.Stop(); _AutoplayTimer.Start(); } } #region ThemeEdit public void MoveElement(int stepX, int stepY) { X += stepX; Y += stepY; Init(); } public void ResizeElement(int stepW, int stepH) { W += stepW; if (W < 100) W = 100; H += stepH; if (H < 100) H = 100; Init(); } #endregion ThemeEdit } }