OpenTTD Source  12.0-beta2
music_gui.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD 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, version 2.
4  * OpenTTD 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.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "stdafx.h"
11 #include <vector>
12 #include "openttd.h"
13 #include "base_media_base.h"
14 #include "music/music_driver.hpp"
15 #include "window_gui.h"
16 #include "strings_func.h"
17 #include "window_func.h"
18 #include "sound_func.h"
19 #include "gfx_func.h"
20 #include "zoom_func.h"
21 #include "core/random_func.hpp"
22 #include "error.h"
23 #include "core/geometry_func.hpp"
24 #include "string_func.h"
25 #include "settings_type.h"
26 #include "settings_gui.h"
27 #include "widgets/dropdown_func.h"
28 #include "widgets/dropdown_type.h"
29 #include "widgets/slider_func.h"
30 
31 #include "widgets/music_widget.h"
32 
33 #include "table/strings.h"
34 #include "table/sprites.h"
35 
36 #include "safeguards.h"
37 
38 
39 struct MusicSystem {
41  const MusicSet *set;
42  uint set_index;
43 
45  bool IsValid() const { return !StrEmpty(this->songname); }
46  };
47  typedef std::vector<PlaylistEntry> Playlist;
48 
49  enum PlaylistChoices {
50  PLCH_ALLMUSIC,
51  PLCH_OLDSTYLE,
52  PLCH_NEWSTYLE,
53  PLCH_EZYSTREET,
54  PLCH_CUSTOM1,
55  PLCH_CUSTOM2,
56  PLCH_THEMEONLY,
57  PLCH_MAX,
58  };
59 
60  Playlist active_playlist;
61  Playlist displayed_playlist;
62  Playlist music_set;
63 
64  PlaylistChoices selected_playlist;
65 
66  void BuildPlaylists();
67 
68  void ChangePlaylist(PlaylistChoices pl);
69  void ChangeMusicSet(const std::string &set_name);
70  void Shuffle();
71  void Unshuffle();
72 
73  void Play();
74  void Stop();
75  void Next();
76  void Prev();
77  void CheckStatus();
78 
79  bool IsPlaying() const;
80  bool IsShuffle() const;
82 
83  bool IsCustomPlaylist() const;
84  void PlaylistAdd(size_t song_index);
85  void PlaylistRemove(size_t song_index);
86  void PlaylistClear();
87 
88 private:
89  void ChangePlaylistPosition(int ofs);
90  int playlist_position;
91 
92  void SaveCustomPlaylist(PlaylistChoices pl);
93 
94  Playlist standard_playlists[PLCH_MAX];
95 };
96 
98 
99 
102 {
103  const MusicSet *set = BaseMusic::GetUsedSet();
104 
105  /* Clear current playlists */
106  for (size_t i = 0; i < lengthof(this->standard_playlists); ++i) this->standard_playlists[i].clear();
107  this->music_set.clear();
108 
109  /* Build standard playlists, and a list of available music */
110  for (uint i = 0; i < NUM_SONGS_AVAILABLE; i++) {
111  PlaylistEntry entry(set, i);
112  if (!entry.IsValid()) continue;
113 
114  this->music_set.push_back(entry);
115 
116  /* Add theme song to theme-only playlist */
117  if (i == 0) this->standard_playlists[PLCH_THEMEONLY].push_back(entry);
118 
119  /* Don't add the theme song to standard playlists */
120  if (i > 0) {
121  this->standard_playlists[PLCH_ALLMUSIC].push_back(entry);
122  uint theme = (i - 1) / NUM_SONGS_CLASS;
123  this->standard_playlists[PLCH_OLDSTYLE + theme].push_back(entry);
124  }
125  }
126 
127  /* Load custom playlists
128  * Song index offsets are 1-based, zero indicates invalid/end-of-list value */
129  for (uint i = 0; i < NUM_SONGS_PLAYLIST; i++) {
130  if (_settings_client.music.custom_1[i] > 0) {
131  PlaylistEntry entry(set, _settings_client.music.custom_1[i] - 1);
132  if (entry.IsValid()) this->standard_playlists[PLCH_CUSTOM1].push_back(entry);
133  }
134  if (_settings_client.music.custom_2[i] > 0) {
135  PlaylistEntry entry(set, _settings_client.music.custom_2[i] - 1);
136  if (entry.IsValid()) this->standard_playlists[PLCH_CUSTOM2].push_back(entry);
137  }
138  }
139 }
140 
145 void MusicSystem::ChangePlaylist(PlaylistChoices pl)
146 {
147  assert(pl < PLCH_MAX && pl >= PLCH_ALLMUSIC);
148 
149  this->displayed_playlist = this->standard_playlists[pl];
150  this->active_playlist = this->displayed_playlist;
151  this->selected_playlist = pl;
152  this->playlist_position = 0;
153 
154  if (this->selected_playlist != PLCH_THEMEONLY) _settings_client.music.playlist = this->selected_playlist;
155 
157  this->Shuffle();
158  /* Shuffle() will also Play() if necessary, only start once */
159  } else if (_settings_client.music.playing) {
160  this->Play();
161  }
162 
165 }
166 
171 void MusicSystem::ChangeMusicSet(const std::string &set_name)
172 {
173  BaseMusic::SetSet(set_name);
174  BaseMusic::ini_set = set_name;
175 
176  this->BuildPlaylists();
177  this->ChangePlaylist(this->selected_playlist);
178 
180 }
181 
184 {
186 
187  this->active_playlist = this->displayed_playlist;
188  for (size_t i = 0; i < this->active_playlist.size(); i++) {
189  size_t shuffle_index = InteractiveRandom() % (this->active_playlist.size() - i);
190  std::swap(this->active_playlist[i], this->active_playlist[i + shuffle_index]);
191  }
192 
193  if (_settings_client.music.playing) this->Play();
194 
196 }
197 
200 {
202  this->active_playlist = this->displayed_playlist;
203 
204  if (_settings_client.music.playing) this->Play();
205 
207 }
208 
211 {
212  /* Always set the playing flag, even if there is no music */
215  /* Make sure playlist_position is a valid index, if playlist has changed etc. */
216  this->ChangePlaylistPosition(0);
217 
218  /* If there is no music, don't try to play it */
219  if (this->active_playlist.empty()) return;
220 
221  MusicSongInfo song = this->active_playlist[this->playlist_position];
222  if (_game_mode == GM_MENU && this->selected_playlist == PLCH_THEMEONLY) song.loop = true;
224 
226 }
227 
230 {
233 
235 }
236 
239 {
240  this->ChangePlaylistPosition(+1);
241  if (_settings_client.music.playing) this->Play();
242 
244 }
245 
248 {
249  this->ChangePlaylistPosition(-1);
250  if (_settings_client.music.playing) this->Play();
251 
253 }
254 
257 {
258  if ((_game_mode == GM_MENU) != (this->selected_playlist == PLCH_THEMEONLY)) {
259  /* Make sure the theme-only playlist is active when on the title screen, and not during gameplay */
260  this->ChangePlaylist((_game_mode == GM_MENU) ? PLCH_THEMEONLY : (PlaylistChoices)_settings_client.music.playlist);
261  }
262  if (this->active_playlist.empty()) return;
263  /* If we were supposed to be playing, but music has stopped, move to next song */
264  if (this->IsPlaying() && !MusicDriver::GetInstance()->IsSongPlaying()) this->Next();
265 }
266 
269 {
270  return _settings_client.music.playing && !this->active_playlist.empty();
271 }
272 
275 {
277 }
278 
281 {
282  if (!this->IsPlaying()) return PlaylistEntry(BaseMusic::GetUsedSet(), 0);
283  return this->active_playlist[this->playlist_position];
284 }
285 
288 {
289  return (this->selected_playlist == PLCH_CUSTOM1) || (this->selected_playlist == PLCH_CUSTOM2);
290 }
291 
297 void MusicSystem::PlaylistAdd(size_t song_index)
298 {
299  if (!this->IsCustomPlaylist()) return;
300 
301  /* Pick out song from the music set */
302  if (song_index >= this->music_set.size()) return;
303  PlaylistEntry entry = this->music_set[song_index];
304 
305  /* Check for maximum length */
306  if (this->standard_playlists[this->selected_playlist].size() >= NUM_SONGS_PLAYLIST) return;
307 
308  /* Add it to the appropriate playlist, and the display */
309  this->standard_playlists[this->selected_playlist].push_back(entry);
310  this->displayed_playlist.push_back(entry);
311 
312  /* Add it to the active playlist, if playback is shuffled select a random position to add at */
313  if (this->active_playlist.empty()) {
314  this->active_playlist.push_back(entry);
315  if (this->IsPlaying()) this->Play();
316  } else if (this->IsShuffle()) {
317  /* Generate a random position between 0 and n (inclusive, new length) to insert at */
318  size_t maxpos = this->displayed_playlist.size();
319  size_t newpos = InteractiveRandom() % maxpos;
320  this->active_playlist.insert(this->active_playlist.begin() + newpos, entry);
321  /* Make sure to shift up the current playback position if the song was inserted before it */
322  if ((int)newpos <= this->playlist_position) this->playlist_position++;
323  } else {
324  this->active_playlist.push_back(entry);
325  }
326 
327  this->SaveCustomPlaylist(this->selected_playlist);
328 
330 }
331 
336 void MusicSystem::PlaylistRemove(size_t song_index)
337 {
338  if (!this->IsCustomPlaylist()) return;
339 
340  Playlist &pl = this->standard_playlists[this->selected_playlist];
341  if (song_index >= pl.size()) return;
342 
343  /* Remove from "simple" playlists */
344  PlaylistEntry song = pl[song_index];
345  pl.erase(pl.begin() + song_index);
346  this->displayed_playlist.erase(this->displayed_playlist.begin() + song_index);
347 
348  /* Find in actual active playlist (may be shuffled) and remove,
349  * if it's the current song restart playback */
350  for (size_t i = 0; i < this->active_playlist.size(); i++) {
351  Playlist::iterator s2 = this->active_playlist.begin() + i;
352  if (s2->filename == song.filename && s2->cat_index == song.cat_index) {
353  this->active_playlist.erase(s2);
354  if ((int)i == this->playlist_position && this->IsPlaying()) this->Play();
355  break;
356  }
357  }
358 
359  this->SaveCustomPlaylist(this->selected_playlist);
360 
362 }
363 
369 {
370  if (!this->IsCustomPlaylist()) return;
371 
372  this->standard_playlists[this->selected_playlist].clear();
373  this->ChangePlaylist(this->selected_playlist);
374 
375  this->SaveCustomPlaylist(this->selected_playlist);
376 }
377 
384 {
385  if (this->active_playlist.empty()) {
386  this->playlist_position = 0;
387  } else {
388  this->playlist_position += ofs;
389  while (this->playlist_position >= (int)this->active_playlist.size()) this->playlist_position -= (int)this->active_playlist.size();
390  while (this->playlist_position < 0) this->playlist_position += (int)this->active_playlist.size();
391  }
392 }
393 
398 void MusicSystem::SaveCustomPlaylist(PlaylistChoices pl)
399 {
400  byte *settings_pl;
401  if (pl == PLCH_CUSTOM1) {
402  settings_pl = _settings_client.music.custom_1;
403  } else if (pl == PLCH_CUSTOM2) {
404  settings_pl = _settings_client.music.custom_2;
405  } else {
406  return;
407  }
408 
409  size_t num = 0;
410  MemSetT(settings_pl, 0, NUM_SONGS_PLAYLIST);
411 
412  for (Playlist::const_iterator song = this->standard_playlists[pl].begin(); song != this->standard_playlists[pl].end(); ++song) {
413  /* Music set indices in the settings playlist are 1-based, 0 means unused slot */
414  settings_pl[num++] = (byte)song->set_index + 1;
415  }
416 }
417 
418 
423 void MusicLoop()
424 {
425  _music.CheckStatus();
426 }
427 
432 void ChangeMusicSet(int index)
433 {
434  if (BaseMusic::GetIndexOfUsedSet() == index) return;
435  _music.ChangeMusicSet(BaseMusic::GetSet(index)->name);
436 }
437 
443 {
444  _music.BuildPlaylists();
445 }
446 
447 
450  {
451  this->InitNested(number);
456  }
457 
458  void SetStringParameters(int widget) const override
459  {
460  switch (widget) {
461  case WID_MTS_PLAYLIST:
462  SetDParam(0, STR_MUSIC_PLAYLIST_ALL + _settings_client.music.playlist);
463  break;
464  case WID_MTS_CAPTION:
466  break;
467  }
468  }
469 
475  void OnInvalidateData(int data = 0, bool gui_scope = true) override
476  {
477  if (!gui_scope) return;
478  for (int i = 0; i < 6; i++) {
480  }
482  this->SetDirty();
483  }
484 
485  void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
486  {
487  switch (widget) {
488  case WID_MTS_PLAYLIST: {
489  Dimension d = {0, 0};
490 
491  for (int i = 0; i < 6; i++) {
492  SetDParam(0, STR_MUSIC_PLAYLIST_ALL + i);
493  d = maxdim(d, GetStringBoundingBox(STR_PLAYLIST_PROGRAM));
494  }
495  d.width += padding.width;
496  d.height += padding.height;
497  *size = maxdim(*size, d);
498  break;
499  }
500 
502  Dimension d = {0, 0};
503 
504  for (MusicSystem::Playlist::const_iterator song = _music.music_set.begin(); song != _music.music_set.end(); ++song) {
505  SetDParam(0, song->tracknr);
506  SetDParam(1, 2);
507  SetDParamStr(2, song->songname);
508  Dimension d2 = GetStringBoundingBox(STR_PLAYLIST_TRACK_NAME);
509  d.width = std::max(d.width, d2.width);
510  d.height += d2.height;
511  }
512  d.width += padding.width;
513  d.height += padding.height;
514  *size = maxdim(*size, d);
515  break;
516  }
517  }
518  }
519 
520  void DrawWidget(const Rect &r, int widget) const override
521  {
522  switch (widget) {
523  case WID_MTS_LIST_LEFT: {
524  GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK);
525 
526  int y = r.top + WD_FRAMERECT_TOP;
527  for (MusicSystem::Playlist::const_iterator song = _music.music_set.begin(); song != _music.music_set.end(); ++song) {
528  SetDParam(0, song->tracknr);
529  SetDParam(1, 2);
530  SetDParamStr(2, song->songname);
531  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME);
532  y += FONT_HEIGHT_SMALL;
533  }
534  break;
535  }
536 
537  case WID_MTS_LIST_RIGHT: {
538  GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK);
539 
540  int y = r.top + WD_FRAMERECT_TOP;
541  for (MusicSystem::Playlist::const_iterator song = _music.active_playlist.begin(); song != _music.active_playlist.end(); ++song) {
542  SetDParam(0, song->tracknr);
543  SetDParam(1, 2);
544  SetDParamStr(2, song->songname);
545  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME);
546  y += FONT_HEIGHT_SMALL;
547  }
548  break;
549  }
550  }
551  }
552 
553  void OnClick(Point pt, int widget, int click_count) override
554  {
555  switch (widget) {
556  case WID_MTS_LIST_LEFT: { // add to playlist
557  int y = this->GetRowFromWidget(pt.y, widget, 0, FONT_HEIGHT_SMALL);
558  _music.PlaylistAdd(y);
559  break;
560  }
561 
562  case WID_MTS_LIST_RIGHT: { // remove from playlist
563  int y = this->GetRowFromWidget(pt.y, widget, 0, FONT_HEIGHT_SMALL);
564  _music.PlaylistRemove(y);
565  break;
566  }
567 
568  case WID_MTS_MUSICSET: {
569  int selected = 0;
570  ShowDropDownList(this, BuildMusicSetDropDownList(&selected), selected, widget, 0, true, false);
571  break;
572  }
573 
574  case WID_MTS_CLEAR: // clear
575  _music.PlaylistClear();
576  break;
577 
578  case WID_MTS_ALL: case WID_MTS_OLD: case WID_MTS_NEW:
579  case WID_MTS_EZY: case WID_MTS_CUSTOM1: case WID_MTS_CUSTOM2: // set playlist
580  _music.ChangePlaylist((MusicSystem::PlaylistChoices)(widget - WID_MTS_ALL));
581  break;
582  }
583  }
584 
585  void OnDropdownSelect(int widget, int index) override
586  {
587  switch (widget) {
588  case WID_MTS_MUSICSET:
589  ChangeMusicSet(index);
590  break;
591  default:
592  NOT_REACHED();
593  }
594  }
595 };
596 
597 static const NWidgetPart _nested_music_track_selection_widgets[] = {
599  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
600  NWidget(WWT_CAPTION, COLOUR_GREY, WID_MTS_CAPTION), SetDataTip(STR_PLAYLIST_MUSIC_SELECTION_SETNAME, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
601  NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_MTS_MUSICSET), SetDataTip(STR_PLAYLIST_CHANGE_SET, STR_PLAYLIST_TOOLTIP_CHANGE_SET),
602  EndContainer(),
603  NWidget(WWT_PANEL, COLOUR_GREY),
604  NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2),
605  /* Left panel. */
607  NWidget(WWT_LABEL, COLOUR_GREY), SetDataTip(STR_PLAYLIST_TRACK_INDEX, STR_NULL),
608  NWidget(WWT_PANEL, COLOUR_GREY, WID_MTS_LIST_LEFT), SetMinimalSize(180, 194), SetDataTip(0x0, STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK), EndContainer(),
610  EndContainer(),
611  /* Middle buttons. */
613  NWidget(NWID_SPACER), SetMinimalSize(60, 30), // Space above the first button from the title bar.
614  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_ALL), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_ALL, STR_MUSIC_TOOLTIP_SELECT_ALL_TRACKS_PROGRAM),
615  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_OLD), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_OLD_STYLE, STR_MUSIC_TOOLTIP_SELECT_OLD_STYLE_MUSIC),
616  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_NEW), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_NEW_STYLE, STR_MUSIC_TOOLTIP_SELECT_NEW_STYLE_MUSIC),
617  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_EZY), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_EZY_STREET, STR_MUSIC_TOOLTIP_SELECT_EZY_STREET_STYLE),
618  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_CUSTOM1), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_CUSTOM_1, STR_MUSIC_TOOLTIP_SELECT_CUSTOM_1_USER_DEFINED),
619  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MTS_CUSTOM2), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_CUSTOM_2, STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED),
620  NWidget(NWID_SPACER), SetMinimalSize(0, 16), // Space above 'clear' button
621  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_MTS_CLEAR), SetFill(1, 0), SetDataTip(STR_PLAYLIST_CLEAR, STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1),
622  NWidget(NWID_SPACER), SetFill(0, 1),
623  EndContainer(),
624  /* Right panel. */
626  NWidget(WWT_LABEL, COLOUR_GREY, WID_MTS_PLAYLIST), SetDataTip(STR_PLAYLIST_PROGRAM, STR_NULL),
627  NWidget(WWT_PANEL, COLOUR_GREY, WID_MTS_LIST_RIGHT), SetMinimalSize(180, 194), SetDataTip(0x0, STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK), EndContainer(),
629  EndContainer(),
630  EndContainer(),
631  EndContainer(),
632 };
633 
634 static WindowDesc _music_track_selection_desc(
635  WDP_AUTO, "music_track", 0, 0,
637  0,
638  _nested_music_track_selection_widgets, lengthof(_nested_music_track_selection_widgets)
639 );
640 
641 static void ShowMusicTrackSelection()
642 {
643  AllocateWindowDescFront<MusicTrackSelectionWindow>(&_music_track_selection_desc, 0);
644 }
645 
646 struct MusicWindow : public Window {
647  MusicWindow(WindowDesc *desc, WindowNumber number) : Window(desc)
648  {
649  this->InitNested(number);
652 
653  UpdateDisabledButtons();
654  }
655 
656  void UpdateDisabledButtons()
657  {
658  /* Disable music control widgets if there is no music
659  * -- except Programme button! So you can still select a music set. */
661  BaseMusic::GetUsedSet()->num_available == 0,
665  );
666  }
667 
668  void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
669  {
670  switch (widget) {
671  /* Make sure that WID_M_SHUFFLE and WID_M_PROGRAMME have the same size.
672  * This can't be done by using NC_EQUALSIZE as the WID_M_INFO is
673  * between those widgets and of different size. */
674  case WID_M_SHUFFLE: case WID_M_PROGRAMME: {
675  Dimension d = maxdim(GetStringBoundingBox(STR_MUSIC_PROGRAM), GetStringBoundingBox(STR_MUSIC_SHUFFLE));
676  d.width += padding.width;
677  d.height += padding.height;
678  *size = maxdim(*size, d);
679  break;
680  }
681 
682  case WID_M_TRACK_NR: {
683  Dimension d = GetStringBoundingBox(STR_MUSIC_TRACK_NONE);
686  *size = maxdim(*size, d);
687  break;
688  }
689 
690  case WID_M_TRACK_NAME: {
691  Dimension d = GetStringBoundingBox(STR_MUSIC_TITLE_NONE);
692  for (MusicSystem::Playlist::const_iterator song = _music.music_set.begin(); song != _music.music_set.end(); ++song) {
693  SetDParamStr(0, song->songname);
694  d = maxdim(d, GetStringBoundingBox(STR_MUSIC_TITLE_NAME));
695  }
698  *size = maxdim(*size, d);
699  break;
700  }
701 
702  /* Hack-ish: set the proper widget data; only needs to be done once
703  * per (Re)Init as that's the only time the language changes. */
704  case WID_M_PREV: this->GetWidget<NWidgetCore>(WID_M_PREV)->widget_data = _current_text_dir == TD_RTL ? SPR_IMG_SKIP_TO_NEXT : SPR_IMG_SKIP_TO_PREV; break;
705  case WID_M_NEXT: this->GetWidget<NWidgetCore>(WID_M_NEXT)->widget_data = _current_text_dir == TD_RTL ? SPR_IMG_SKIP_TO_PREV : SPR_IMG_SKIP_TO_NEXT; break;
706  case WID_M_PLAY: this->GetWidget<NWidgetCore>(WID_M_PLAY)->widget_data = _current_text_dir == TD_RTL ? SPR_IMG_PLAY_MUSIC_RTL : SPR_IMG_PLAY_MUSIC; break;
707  }
708  }
709 
710  void DrawWidget(const Rect &r, int widget) const override
711  {
712  switch (widget) {
713  case WID_M_TRACK_NR: {
714  GfxFillRect(r.left + 1, r.top + 1, r.right, r.bottom, PC_BLACK);
715  if (BaseMusic::GetUsedSet()->num_available == 0) {
716  break;
717  }
718  StringID str = STR_MUSIC_TRACK_NONE;
719  if (_music.IsPlaying()) {
720  SetDParam(0, _music.GetCurrentSong().tracknr);
721  SetDParam(1, 2);
722  str = STR_MUSIC_TRACK_DIGIT;
723  }
724  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str);
725  break;
726  }
727 
728  case WID_M_TRACK_NAME: {
729  GfxFillRect(r.left, r.top + 1, r.right - 1, r.bottom, PC_BLACK);
730  StringID str = STR_MUSIC_TITLE_NONE;
731  MusicSystem::PlaylistEntry entry(_music.GetCurrentSong());
732  if (BaseMusic::GetUsedSet()->num_available == 0) {
733  str = STR_MUSIC_TITLE_NOMUSIC;
734  } else if (_music.IsPlaying()) {
735  str = STR_MUSIC_TITLE_NAME;
736  SetDParamStr(0, entry.songname);
737  }
738  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_FROMSTRING, SA_HOR_CENTER);
739  break;
740  }
741 
742  case WID_M_MUSIC_VOL:
744  break;
745 
746  case WID_M_EFFECT_VOL:
748  break;
749  }
750  }
751 
757  void OnInvalidateData(int data = 0, bool gui_scope = true) override
758  {
759  if (!gui_scope) return;
760  for (int i = 0; i < 6; i++) {
762  }
763 
764  UpdateDisabledButtons();
765 
766  this->SetDirty();
767  }
768 
769  void OnClick(Point pt, int widget, int click_count) override
770  {
771  switch (widget) {
772  case WID_M_PREV: // skip to prev
773  _music.Prev();
774  break;
775 
776  case WID_M_NEXT: // skip to next
777  _music.Next();
778  break;
779 
780  case WID_M_STOP: // stop playing
781  _music.Stop();
782  break;
783 
784  case WID_M_PLAY: // start playing
785  _music.Play();
786  break;
787 
788  case WID_M_MUSIC_VOL: case WID_M_EFFECT_VOL: { // volume sliders
790  if (ClickVolumeSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, vol)) {
791  if (widget == WID_M_MUSIC_VOL) MusicDriver::GetInstance()->SetVolume(vol);
792  this->SetWidgetDirty(widget);
794  }
795 
796  if (click_count > 0) this->mouse_capture_widget = widget;
797  break;
798  }
799 
800  case WID_M_SHUFFLE: // toggle shuffle
801  if (_music.IsShuffle()) {
802  _music.Unshuffle();
803  } else {
804  _music.Shuffle();
805  }
808  break;
809 
810  case WID_M_PROGRAMME: // show track selection
811  ShowMusicTrackSelection();
812  break;
813 
814  case WID_M_ALL: case WID_M_OLD: case WID_M_NEW:
815  case WID_M_EZY: case WID_M_CUSTOM1: case WID_M_CUSTOM2: // playlist
816  _music.ChangePlaylist((MusicSystem::PlaylistChoices)(widget - WID_M_ALL));
817  break;
818  }
819  }
820 };
821 
822 static const NWidgetPart _nested_music_window_widgets[] = {
824  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
825  NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_MUSIC_JAZZ_JUKEBOX_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
826  NWidget(WWT_SHADEBOX, COLOUR_GREY),
827  NWidget(WWT_STICKYBOX, COLOUR_GREY),
828  EndContainer(),
829 
832  NWidget(WWT_PANEL, COLOUR_GREY, -1), SetFill(1, 1), EndContainer(),
834  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_M_PREV), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_SKIP_TO_PREV, STR_MUSIC_TOOLTIP_SKIP_TO_PREVIOUS_TRACK),
835  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_M_NEXT), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_SKIP_TO_NEXT, STR_MUSIC_TOOLTIP_SKIP_TO_NEXT_TRACK_IN_SELECTION),
836  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_M_STOP), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_STOP_MUSIC, STR_MUSIC_TOOLTIP_STOP_PLAYING_MUSIC),
837  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_M_PLAY), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_PLAY_MUSIC, STR_MUSIC_TOOLTIP_START_PLAYING_MUSIC),
838  EndContainer(),
839  NWidget(WWT_PANEL, COLOUR_GREY, -1), SetFill(1, 1), EndContainer(),
840  EndContainer(),
841  NWidget(WWT_PANEL, COLOUR_GREY, WID_M_SLIDERS),
842  NWidget(NWID_HORIZONTAL), SetPIP(4, 0, 4),
844  NWidget(WWT_LABEL, COLOUR_GREY, -1), SetFill(1, 0), SetDataTip(STR_MUSIC_MUSIC_VOLUME, STR_NULL),
845  NWidget(WWT_EMPTY, COLOUR_GREY, WID_M_MUSIC_VOL), SetMinimalSize(67, 0), SetPadding(2), SetMinimalTextLines(1, 0), SetFill(1, 0), SetDataTip(0x0, STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC),
846  EndContainer(),
848  NWidget(WWT_LABEL, COLOUR_GREY, -1), SetFill(1, 0), SetDataTip(STR_MUSIC_EFFECTS_VOLUME, STR_NULL),
849  NWidget(WWT_EMPTY, COLOUR_GREY, WID_M_EFFECT_VOL), SetMinimalSize(67, 0), SetPadding(2), SetMinimalTextLines(1, 0), SetFill(1, 0), SetDataTip(0x0, STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC),
850  EndContainer(),
851  EndContainer(),
852  EndContainer(),
853  EndContainer(),
854  NWidget(WWT_PANEL, COLOUR_GREY, WID_M_BACKGROUND),
855  NWidget(NWID_HORIZONTAL), SetPIP(6, 0, 6),
857  NWidget(NWID_SPACER), SetFill(0, 1),
858  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_M_SHUFFLE), SetMinimalSize(50, 8), SetDataTip(STR_MUSIC_SHUFFLE, STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE),
859  NWidget(NWID_SPACER), SetFill(0, 1),
860  EndContainer(),
861  NWidget(NWID_VERTICAL), SetPadding(0, 0, 3, 3),
862  NWidget(WWT_LABEL, COLOUR_GREY, WID_M_TRACK), SetFill(0, 0), SetDataTip(STR_MUSIC_TRACK, STR_NULL),
863  NWidget(WWT_PANEL, COLOUR_GREY, WID_M_TRACK_NR), EndContainer(),
864  EndContainer(),
865  NWidget(NWID_VERTICAL), SetPadding(0, 3, 3, 0),
866  NWidget(WWT_LABEL, COLOUR_GREY, WID_M_TRACK_TITLE), SetFill(1, 0), SetDataTip(STR_MUSIC_XTITLE, STR_NULL),
867  NWidget(WWT_PANEL, COLOUR_GREY, WID_M_TRACK_NAME), SetFill(1, 0), EndContainer(),
868  EndContainer(),
870  NWidget(NWID_SPACER), SetFill(0, 1),
871  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_M_PROGRAMME), SetMinimalSize(50, 8), SetDataTip(STR_MUSIC_PROGRAM, STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION),
872  NWidget(NWID_SPACER), SetFill(0, 1),
873  EndContainer(),
874  EndContainer(),
875  EndContainer(),
877  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_M_ALL), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_ALL, STR_MUSIC_TOOLTIP_SELECT_ALL_TRACKS_PROGRAM),
878  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_M_OLD), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_OLD_STYLE, STR_MUSIC_TOOLTIP_SELECT_OLD_STYLE_MUSIC),
879  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_M_NEW), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_NEW_STYLE, STR_MUSIC_TOOLTIP_SELECT_NEW_STYLE_MUSIC),
880  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_M_EZY), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_EZY_STREET, STR_MUSIC_TOOLTIP_SELECT_EZY_STREET_STYLE),
881  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_M_CUSTOM1), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_CUSTOM_1, STR_MUSIC_TOOLTIP_SELECT_CUSTOM_1_USER_DEFINED),
882  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_M_CUSTOM2), SetFill(1, 0), SetDataTip(STR_MUSIC_PLAYLIST_CUSTOM_2, STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED),
883  EndContainer(),
884 };
885 
886 static WindowDesc _music_window_desc(
887  WDP_AUTO, "music", 0, 0,
889  0,
890  _nested_music_window_widgets, lengthof(_nested_music_window_widgets)
891 );
892 
893 void ShowMusicWindow()
894 {
895  AllocateWindowDescFront<MusicWindow>(&_music_window_desc, 0);
896 }
MusicWindow::UpdateWidgetSize
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
Update size and resize step of a widget in the window.
Definition: music_gui.cpp:668
MusicSystem::Shuffle
void Shuffle()
Enable shuffle mode and restart playback.
Definition: music_gui.cpp:183
WID_MTS_CUSTOM2
@ WID_MTS_CUSTOM2
Custom2 button.
Definition: music_widget.h:25
MusicSystem::ChangePlaylist
void ChangePlaylist(PlaylistChoices pl)
Switch to another playlist, or reload the current one.
Definition: music_gui.cpp:145
WD_FRAMERECT_TOP
@ WD_FRAMERECT_TOP
Offset at top to draw the frame rectangular area.
Definition: window_gui.h:64
InvalidateWindowData
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition: window.cpp:3218
sound_func.h
MusicSystem::PlaylistClear
void PlaylistClear()
Remove all songs from the current custom playlist.
Definition: music_gui.cpp:368
MusicSystem
Definition: music_gui.cpp:39
BaseMedia< MusicSet >::GetIndexOfUsedSet
static int GetIndexOfUsedSet()
Get the index of the currently active graphics set.
Definition: base_media_func.h:326
Dimension
Dimensions (a width and height) of a rectangle in 2D.
Definition: geometry_type.hpp:27
WWT_STICKYBOX
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition: widget_type.h:64
SetPadding
static NWidgetPart SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
Widget part function for setting additional space around a widget.
Definition: widget_type.h:1139
MusicTrackSelectionWindow::UpdateWidgetSize
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
Update size and resize step of a widget in the window.
Definition: music_gui.cpp:485
dropdown_func.h
WID_MTS_CUSTOM1
@ WID_MTS_CUSTOM1
Custom1 button.
Definition: music_widget.h:24
MusicDriver::PlaySong
virtual void PlaySong(const MusicSongInfo &song)=0
Play a particular song.
DrawVolumeSliderWidget
void DrawVolumeSliderWidget(Rect r, byte value)
Draw a volume slider widget with know at given value.
Definition: slider.cpp:26
WWT_CAPTION
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition: widget_type.h:59
MusicDriver::SetVolume
virtual void SetVolume(byte vol)=0
Set the volume, if possible.
MusicSystem::IsShuffle
bool IsShuffle() const
Is shuffle mode enabled?
Definition: music_gui.cpp:274
MusicSystem::IsCustomPlaylist
bool IsCustomPlaylist() const
Is one of the custom playlists selected?
Definition: music_gui.cpp:287
MusicSettings::shuffle
bool shuffle
Whether to shuffle the music.
Definition: settings_type.h:223
WWT_LABEL
@ WWT_LABEL
Centered label.
Definition: widget_type.h:55
NUM_SONGS_AVAILABLE
static const uint NUM_SONGS_AVAILABLE
Maximum number of songs in the full playlist; theme song + the classes.
Definition: base_media_base.h:276
WID_M_TRACK_NR
@ WID_M_TRACK_NR
Track number.
Definition: music_widget.h:40
NWID_HORIZONTAL
@ NWID_HORIZONTAL
Horizontal container.
Definition: widget_type.h:73
maxdim
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Definition: geometry_func.cpp:22
WID_MTS_NEW
@ WID_MTS_NEW
New button.
Definition: music_widget.h:22
MusicSystem::PlaylistAdd
void PlaylistAdd(size_t song_index)
Append a song to a custom playlist.
Definition: music_gui.cpp:297
MusicSongInfo::loop
bool loop
song should play in a tight loop if possible, never ending
Definition: base_media_base.h:297
music_widget.h
zoom_func.h
base_media_base.h
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:52
DrawString
int DrawString(int left, int right, int top, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition: gfx.cpp:642
WID_M_CUSTOM1
@ WID_M_CUSTOM1
Custom1 button.
Definition: music_widget.h:49
WWT_EMPTY
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget array.
Definition: widget_type.h:46
MusicTrackSelectionWindow::SetStringParameters
void SetStringParameters(int widget) const override
Initialize string parameters for a widget.
Definition: music_gui.cpp:458
MusicSystem::Play
void Play()
Start/restart playback at current song.
Definition: music_gui.cpp:210
WindowNumber
int32 WindowNumber
Number to differentiate different windows of the same class.
Definition: window_type.h:711
WC_MUSIC_WINDOW
@ WC_MUSIC_WINDOW
Music window; Window numbers:
Definition: window_type.h:588
MusicWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition: music_gui.cpp:757
MusicLoop
void MusicLoop()
Check music playback status and start/stop/song-finished.
Definition: music_gui.cpp:423
MusicSystem::Prev
void Prev()
Skip to previous track.
Definition: music_gui.cpp:247
MusicTrackSelectionWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition: music_gui.cpp:475
Window::Window
Window(WindowDesc *desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition: window.cpp:1799
SetDParam
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings_func.h:196
NWidgetPart
Partial widget specification to allow NWidgets to be written nested.
Definition: widget_type.h:971
MusicSystem::displayed_playlist
Playlist displayed_playlist
current playlist as displayed in GUI, never in shuffled order
Definition: music_gui.cpp:61
SetDataTip
static NWidgetPart SetDataTip(uint32 data, StringID tip)
Widget part function for setting the data and tooltip.
Definition: widget_type.h:1107
MusicSettings::playing
bool playing
Whether music is playing.
Definition: settings_type.h:222
GetStringBoundingBox
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition: gfx.cpp:888
WID_M_TRACK_NAME
@ WID_M_TRACK_NAME
Track name.
Definition: music_widget.h:42
MusicSystem::Next
void Next()
Skip to next track.
Definition: music_gui.cpp:238
MusicWindow::OnClick
void OnClick(Point pt, int widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition: music_gui.cpp:769
WN_GAME_OPTIONS_GAME_OPTIONS
@ WN_GAME_OPTIONS_GAME_OPTIONS
Game options.
Definition: window_type.h:18
gfx_func.h
BaseMedia< MusicSet >::ini_set
static std::string ini_set
The set as saved in the config file.
Definition: base_media_base.h:179
WindowDesc
High level window description.
Definition: window_gui.h:168
WID_MTS_CAPTION
@ WID_MTS_CAPTION
Window caption.
Definition: music_widget.h:15
WID_M_EZY
@ WID_M_EZY
Ezy button.
Definition: music_widget.h:48
window_gui.h
NC_EQUALSIZE
@ NC_EQUALSIZE
Value of the NCB_EQUALSIZE flag.
Definition: widget_type.h:463
MusicTrackSelectionWindow
Definition: music_gui.cpp:448
WDP_AUTO
@ WDP_AUTO
Find a place automatically.
Definition: window_gui.h:156
Window::resize
ResizeInfo resize
Resize information.
Definition: window_gui.h:317
MusicSystem::PlaylistEntry
Definition: music_gui.cpp:40
MusicDriver::GetInstance
static MusicDriver * GetInstance()
Get the currently active instance of the music driver.
Definition: music_driver.hpp:46
Window::InitNested
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition: window.cpp:1789
MusicWindow::DrawWidget
void DrawWidget(const Rect &r, int widget) const override
Draw the contents of a nested widget.
Definition: music_gui.cpp:710
MusicSystem::CheckStatus
void CheckStatus()
Check that music is playing if it should, and that appropriate playlist is active for game/main menu.
Definition: music_gui.cpp:256
Window::SetDirty
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition: window.cpp:993
WD_FRAMERECT_LEFT
@ WD_FRAMERECT_LEFT
Offset at left to draw the frame rectangular area.
Definition: window_gui.h:62
MusicSongInfo::songname
char songname[32]
name of song displayed in UI
Definition: base_media_base.h:292
WID_MTS_MUSICSET
@ WID_MTS_MUSICSET
Music set selection.
Definition: music_widget.h:19
MusicSystem::ChangeMusicSet
void ChangeMusicSet(const std::string &set_name)
Change to named music set, and reset playback.
Definition: music_gui.cpp:171
WID_M_MUSIC_VOL
@ WID_M_MUSIC_VOL
Music volume.
Definition: music_widget.h:36
WID_M_BACKGROUND
@ WID_M_BACKGROUND
Background of the window.
Definition: music_widget.h:38
WD_FRAMERECT_RIGHT
@ WD_FRAMERECT_RIGHT
Offset at right to draw the frame rectangular area.
Definition: window_gui.h:63
WD_FRAMERECT_BOTTOM
@ WD_FRAMERECT_BOTTOM
Offset at bottom to draw the frame rectangular area.
Definition: window_gui.h:65
WWT_PUSHTXTBTN
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
Definition: widget_type.h:104
MusicSystem::BuildPlaylists
void BuildPlaylists()
Rebuild all playlists for the current music set.
Definition: music_gui.cpp:101
ShowDropDownList
void ShowDropDownList(Window *w, DropDownList &&list, int selected, int button, uint width, bool auto_width, bool instant_close)
Show a drop down list.
Definition: dropdown.cpp:443
MusicSystem::IsPlaying
bool IsPlaying() const
Is the player getting music right now?
Definition: music_gui.cpp:268
WID_M_STOP
@ WID_M_STOP
Stop button.
Definition: music_widget.h:33
dropdown_type.h
MusicSongInfo
Metadata about a music track.
Definition: base_media_base.h:291
MusicSystem::Unshuffle
void Unshuffle()
Disable shuffle and restart playback.
Definition: music_gui.cpp:199
MusicSettings::custom_2
byte custom_2[33]
The order of the second custom playlist.
Definition: settings_type.h:221
MusicTrackSelectionWindow::OnClick
void OnClick(Point pt, int widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition: music_gui.cpp:553
Window::SetWidgetDisabledState
void SetWidgetDisabledState(byte widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition: window_gui.h:386
safeguards.h
music_driver.hpp
StrEmpty
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:64
MusicSet
All data of a music set.
Definition: base_media_base.h:303
MusicSettings::playlist
byte playlist
The playlist (number) to play.
Definition: settings_type.h:217
WID_MTS_LIST_LEFT
@ WID_MTS_LIST_LEFT
Left button.
Definition: music_widget.h:16
settings_type.h
sprites.h
Point
Coordinates of a point in 2D.
Definition: geometry_type.hpp:21
error.h
WID_M_PLAY
@ WID_M_PLAY
Play button.
Definition: music_widget.h:34
stdafx.h
PC_BLACK
static const uint8 PC_BLACK
Black palette colour.
Definition: gfx_func.h:190
GfxFillRect
void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
Definition: gfx.cpp:116
WID_M_ALL
@ WID_M_ALL
All button.
Definition: music_widget.h:45
Window::mouse_capture_widget
int mouse_capture_widget
Widgetindex of current mouse capture widget (e.g. dragged scrollbar). -1 if no widget has mouse captu...
Definition: window_gui.h:330
WC_NONE
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition: window_type.h:37
SA_HOR_CENTER
@ SA_HOR_CENTER
Horizontally center the text.
Definition: gfx_type.h:329
NUM_SONGS_CLASS
static const uint NUM_SONGS_CLASS
Maximum number of songs in the 'class' playlists.
Definition: base_media_base.h:272
NWID_VERTICAL
@ NWID_VERTICAL
Vertical container.
Definition: widget_type.h:75
FONT_HEIGHT_SMALL
#define FONT_HEIGHT_SMALL
Height of characters in the small (FS_SMALL) font.
Definition: gfx_func.h:162
ClickVolumeSliderWidget
bool ClickVolumeSliderWidget(Rect r, Point pt, byte &value)
Handle click on a volume slider widget to change the value.
Definition: slider.cpp:55
WWT_CLOSEBOX
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition: widget_type.h:67
string_func.h
StringID
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
WWT_PUSHIMGBTN
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
Definition: widget_type.h:105
WC_GAME_OPTIONS
@ WC_GAME_OPTIONS
Game options window; Window numbers:
Definition: window_type.h:604
EndContainer
static NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
Definition: widget_type.h:1092
strings_func.h
WID_MTS_ALL
@ WID_MTS_ALL
All button.
Definition: music_widget.h:20
WID_M_NEXT
@ WID_M_NEXT
Next button.
Definition: music_widget.h:32
InitializeMusic
void InitializeMusic()
Prepare the music system for use.
Definition: music_gui.cpp:442
WID_M_TRACK
@ WID_M_TRACK
Track playing.
Definition: music_widget.h:39
WID_M_NEW
@ WID_M_NEW
New button.
Definition: music_widget.h:47
NUM_SONGS_PLAYLIST
static const uint NUM_SONGS_PLAYLIST
Maximum number of songs in the (custom) playlist.
Definition: base_media_base.h:279
WIDGET_LIST_END
static const int WIDGET_LIST_END
indicate the end of widgets' list for vararg functions
Definition: widget_type.h:20
_music
static IDirectMusic * _music
The direct music object manages buffers and ports.
Definition: dmusic.cpp:144
MusicWindow
Definition: music_gui.cpp:646
WID_MTS_CLEAR
@ WID_MTS_CLEAR
Clear button.
Definition: music_widget.h:26
NWidget
static NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx=-1)
Widget part function for starting a new 'real' widget.
Definition: widget_type.h:1207
MusicSystem::SaveCustomPlaylist
void SaveCustomPlaylist(PlaylistChoices pl)
Save a custom playlist to settings after modification.
Definition: music_gui.cpp:398
geometry_func.hpp
SetMinimalSize
static NWidgetPart SetMinimalSize(int16 x, int16 y)
Widget part function for setting the minimal size.
Definition: widget_type.h:1010
MusicTrackSelectionWindow::OnDropdownSelect
void OnDropdownSelect(int widget, int index) override
A dropdown option associated to this window has been selected.
Definition: music_gui.cpp:585
WWT_PANEL
@ WWT_PANEL
Simple depressed panel.
Definition: widget_type.h:48
Window::SetWidgetsDisabledState
void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets,...)
Sets the enabled/disabled status of a list of widgets.
Definition: window.cpp:547
WID_M_OLD
@ WID_M_OLD
Old button.
Definition: music_widget.h:46
WID_M_SHUFFLE
@ WID_M_SHUFFLE
Shuffle button.
Definition: music_widget.h:43
openttd.h
MusicSystem::GetCurrentSong
PlaylistEntry GetCurrentSong() const
Return the current song, or a dummy if none.
Definition: music_gui.cpp:280
NWID_SPACER
@ NWID_SPACER
Invisible widget that takes some space.
Definition: widget_type.h:77
WID_M_EFFECT_VOL
@ WID_M_EFFECT_VOL
Effect volume.
Definition: music_widget.h:37
WID_MTS_PLAYLIST
@ WID_MTS_PLAYLIST
Playlist.
Definition: music_widget.h:17
WID_MTS_LIST_RIGHT
@ WID_MTS_LIST_RIGHT
Right button.
Definition: music_widget.h:18
WID_M_TRACK_TITLE
@ WID_M_TRACK_TITLE
Track title.
Definition: music_widget.h:41
MusicSongInfo::filename
const char * filename
file on disk containing song (when used in MusicSet class, this pointer is owned by MD5File object fo...
Definition: base_media_base.h:294
window_func.h
BaseMedia< MusicSet >::GetSet
static const MusicSet * GetSet(int index)
Get the name of the graphics set at the specified index.
Definition: base_media_func.h:342
lengthof
#define lengthof(x)
Return the length of an fixed size array.
Definition: stdafx.h:378
MusicSettings::effect_vol
byte effect_vol
The requested effects volume.
Definition: settings_type.h:219
WID_MTS_EZY
@ WID_MTS_EZY
Ezy button.
Definition: music_widget.h:23
WID_M_PROGRAMME
@ WID_M_PROGRAMME
Program button.
Definition: music_widget.h:44
random_func.hpp
SetPIP
static NWidgetPart SetPIP(uint8 pre, uint8 inter, uint8 post)
Widget part function for setting a pre/inter/post spaces.
Definition: widget_type.h:1169
MemSetT
static void MemSetT(T *ptr, byte value, size_t num=1)
Type-safe version of memset().
Definition: mem_func.hpp:49
SetFill
static NWidgetPart SetFill(uint fill_x, uint fill_y)
Widget part function for setting filling.
Definition: widget_type.h:1076
WID_M_PREV
@ WID_M_PREV
Previous button.
Definition: music_widget.h:31
MusicTrackSelectionWindow::DrawWidget
void DrawWidget(const Rect &r, int widget) const override
Draw the contents of a nested widget.
Definition: music_gui.cpp:520
MusicSystem::PlaylistEntry::set
const MusicSet * set
music set the song comes from
Definition: music_gui.cpp:41
MusicSystem::PlaylistEntry::set_index
uint set_index
index of song in set
Definition: music_gui.cpp:42
MusicSystem::Stop
void Stop()
Stop playback and set flag that we don't intend to play music.
Definition: music_gui.cpp:229
Window
Data structure for an opened window.
Definition: window_gui.h:279
BaseMedia< MusicSet >::GetUsedSet
static const MusicSet * GetUsedSet()
Return the used set.
Definition: base_media_func.h:357
MusicSystem::ChangePlaylistPosition
void ChangePlaylistPosition(int ofs)
Change playlist position pointer by the given offset, making sure to keep it within valid range.
Definition: music_gui.cpp:383
MusicSystem::active_playlist
Playlist active_playlist
current play order of songs, including any shuffle
Definition: music_gui.cpp:60
settings_gui.h
WID_MTS_OLD
@ WID_MTS_OLD
Old button.
Definition: music_widget.h:21
WID_M_SLIDERS
@ WID_M_SLIDERS
Sliders.
Definition: music_widget.h:35
Window::SetWidgetDirty
void SetWidgetDirty(byte widget_index) const
Invalidate a widget, i.e.
Definition: window.cpp:608
Rect
Specification of a rectangle with absolute coordinates of all edges.
Definition: geometry_type.hpp:47
Window::LowerWidget
void LowerWidget(byte widget_index)
Marks a widget as lowered.
Definition: window_gui.h:468
SetWindowClassesDirty
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition: window.cpp:3146
Window::GetRowFromWidget
int GetRowFromWidget(int clickpos, int widget, int padding, int line_height=-1) const
Compute the row of a widget that a user clicked in.
Definition: window.cpp:212
ClientSettings::music
MusicSettings music
settings related to music/sound
Definition: settings_type.h:597
Window::SetWidgetLoweredState
void SetWidgetLoweredState(byte widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition: window_gui.h:447
ChangeMusicSet
void ChangeMusicSet(int index)
Change the configured music set and reset playback.
Definition: music_gui.cpp:432
MusicSettings::music_vol
byte music_vol
The requested music volume.
Definition: settings_type.h:218
MusicSystem::music_set
Playlist music_set
all songs in current music set, in set order
Definition: music_gui.cpp:62
TD_RTL
@ TD_RTL
Text is written right-to-left by default.
Definition: strings_type.h:24
_current_text_dir
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition: strings.cpp:48
MusicSongInfo::cat_index
int cat_index
entry index in CAT file, for filetype==MTT_MPSMIDI
Definition: base_media_base.h:296
MusicSettings::custom_1
byte custom_1[33]
The order of the first custom playlist.
Definition: settings_type.h:220
WID_M_CUSTOM2
@ WID_M_CUSTOM2
Custom2 button.
Definition: music_widget.h:50
SetDParamStr
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition: strings.cpp:296
WC_MUSIC_TRACK_SELECTION
@ WC_MUSIC_TRACK_SELECTION
Music track selection; Window numbers:
Definition: window_type.h:594
MusicSystem::PlaylistRemove
void PlaylistRemove(size_t song_index)
Remove a song from a custom playlist.
Definition: music_gui.cpp:336
WWT_TEXTBTN
@ WWT_TEXTBTN
(Toggle) Button with text
Definition: widget_type.h:53
SetMinimalTextLines
static NWidgetPart SetMinimalTextLines(uint8 lines, uint8 spacing, FontSize size=FS_NORMAL)
Widget part function for setting the minimal text lines.
Definition: widget_type.h:1028
WWT_DROPDOWN
@ WWT_DROPDOWN
Drop down list.
Definition: widget_type.h:68
MusicDriver::StopSong
virtual void StopSong()=0
Stop playing the current song.
WWT_SHADEBOX
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition: widget_type.h:62
BaseMedia< MusicSet >::SetSet
static bool SetSet(const std::string &name)
Set the set to be used.
Definition: base_media_func.h:228