center cursor directly in Menu class
[ncmpcpp.git] / src / sel_items_adder.cpp
blob7d3e7f6d8b45fe443c0ac31b797e6bf899658b10
1 /***************************************************************************
2 * Copyright (C) 2008-2010 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #include "charset.h"
22 #include "browser.h"
23 #include "display.h"
24 #include "global.h"
25 #include "mpdpp.h"
26 #include "playlist.h"
27 #include "playlist_editor.h"
28 #include "sel_items_adder.h"
30 using Global::MainHeight;
31 using Global::MainStartY;
32 using Global::myScreen;
33 using Global::myOldScreen;
35 SelectedItemsAdder *mySelectedItemsAdder = new SelectedItemsAdder;
37 void SelectedItemsAdder::Init()
39 SetDimensions();
40 itsPlaylistSelector = new Menu<std::string>((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY, itsWidth, itsHeight, "Add selected item(s) to...", Config.main_color, Config.window_border);
41 itsPlaylistSelector->CyclicScrolling(Config.use_cyclic_scrolling);
42 itsPlaylistSelector->CenteredCursor(Config.centered_cursor);
43 itsPlaylistSelector->HighlightColor(Config.main_highlight_color);
44 itsPlaylistSelector->SetItemDisplayer(Display::Generic);
46 itsPositionSelector = new Menu<std::string>((COLS-itsPSWidth)/2, (MainHeight-itsPSHeight)/2+MainStartY, itsPSWidth, itsPSHeight, "Where?", Config.main_color, Config.window_border);
47 itsPositionSelector->CyclicScrolling(Config.use_cyclic_scrolling);
48 itsPositionSelector->CenteredCursor(Config.centered_cursor);
49 itsPositionSelector->HighlightColor(Config.main_highlight_color);
50 itsPositionSelector->SetItemDisplayer(Display::Generic);
51 itsPositionSelector->AddOption("At the end of playlist");
52 itsPositionSelector->AddOption("At the beginning of playlist");
53 itsPositionSelector->AddOption("After current track");
54 itsPositionSelector->AddOption("After current album");
55 itsPositionSelector->AddOption("After highlighted item");
56 itsPositionSelector->AddSeparator();
57 itsPositionSelector->AddOption("Cancel");
59 w = itsPlaylistSelector;
60 isInitialized = 1;
63 void SelectedItemsAdder::SwitchTo()
65 if (myScreen == this)
67 myOldScreen->SwitchTo();
68 return;
70 if (!myScreen->allowsSelection())
71 return;
73 if (MainHeight < 5)
75 ShowMessage("Screen is too small to display this window!");
76 return;
79 if (!isInitialized)
80 Init();
82 // default to main window
83 w = itsPlaylistSelector;
85 // Resize() can fall back to old screen, so we need it updated
86 myOldScreen = myScreen;
88 if (hasToBeResized)
89 Resize();
91 bool playlists_not_active = myScreen == myBrowser && myBrowser->isLocal();
92 if (playlists_not_active)
93 ShowMessage("Local items cannot be added to m3u playlist!");
95 w->Clear();
96 w->Reset();
97 if (myOldScreen != myPlaylist)
98 w->AddOption("Current MPD playlist", 0, 0);
99 w->AddOption("New playlist", 0, playlists_not_active);
100 w->AddSeparator();
102 MPD::TagList playlists;
103 Mpd.GetPlaylists(playlists);
104 sort(playlists.begin(), playlists.end(), CaseInsensitiveSorting());
105 for (MPD::TagList::iterator it = playlists.begin(); it != playlists.end(); ++it)
107 utf_to_locale(*it);
108 w->AddOption(*it, 0, playlists_not_active);
110 w->AddSeparator();
111 w->AddOption("Cancel");
113 myScreen = this;
114 w->Window::Clear();
117 void SelectedItemsAdder::Resize()
119 SetDimensions();
120 if (itsHeight < 5) // screen too low to display this window
121 return myOldScreen->SwitchTo();
122 itsPlaylistSelector->Resize(itsWidth, itsHeight);
123 itsPlaylistSelector->MoveTo((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY);
124 size_t poss_width = std::min(itsPSWidth, size_t(COLS));
125 size_t poss_height = std::min(itsPSHeight, size_t(MainHeight));
126 itsPositionSelector->Resize(poss_width, poss_height);
127 itsPositionSelector->MoveTo((COLS-poss_width)/2, (MainHeight-poss_height)/2+MainStartY);
128 if (myOldScreen && myOldScreen->hasToBeResized) // resize background window
130 myOldScreen->Resize();
131 myOldScreen->Refresh();
133 hasToBeResized = 0;
136 void SelectedItemsAdder::Refresh()
138 if (w == itsPositionSelector)
140 itsPlaylistSelector->Display();
141 itsPositionSelector->Display();
143 else
144 itsPlaylistSelector->Display();
147 std::basic_string<my_char_t> SelectedItemsAdder::Title()
149 return myOldScreen->Title();
152 void SelectedItemsAdder::EnterPressed()
154 size_t pos = w->Choice();
156 // adding to current playlist is disabled when playlist is active
157 if (w == itsPlaylistSelector && myOldScreen == myPlaylist && pos == 0)
158 pos++;
160 MPD::SongList list;
161 if ((w != itsPlaylistSelector || pos != 0) && pos != w->Size()-1)
162 myOldScreen->GetSelectedSongs(list);
164 if (w == itsPlaylistSelector)
166 if (pos == 0) // add to mpd playlist
168 w = itsPositionSelector;
169 itsPositionSelector->Reset();
170 return;
172 else if (pos == 1) // create new playlist
174 LockStatusbar();
175 Statusbar() << "Save playlist as: ";
176 std::string playlist = Global::wFooter->GetString();
177 UnlockStatusbar();
178 if (!playlist.empty())
180 std::string utf_playlist = locale_to_utf_cpy(playlist);
181 Mpd.StartCommandsList();
182 for (MPD::SongList::const_iterator it = list.begin(); it != list.end(); ++it)
183 Mpd.AddToPlaylist(utf_playlist, **it);
184 if (Mpd.CommitCommandsList())
185 ShowMessage("Selected item(s) added to playlist \"%s\"!", playlist.c_str());
188 else if (pos > 1 && pos < w->Size()-1) // add items to existing playlist
190 std::string playlist = locale_to_utf_cpy(w->Current());
191 Mpd.StartCommandsList();
192 for (MPD::SongList::const_iterator it = list.begin(); it != list.end(); ++it)
193 Mpd.AddToPlaylist(playlist, **it);
194 if (Mpd.CommitCommandsList())
195 ShowMessage("Selected item(s) added to playlist \"%s\"!", w->Current().c_str());
197 if (pos != w->Size()-1)
199 // refresh playlist's lists
200 if (myBrowser->Main() && !myBrowser->isLocal() && myBrowser->CurrentDir() == "/")
201 myBrowser->GetDirectory("/");
202 if (myPlaylistEditor->Main())
203 myPlaylistEditor->Playlists->Clear(); // make playlist editor update itself
206 else
208 // disable adding after current track/album when stopped
209 if (pos > 1 && pos < 4 && !Mpd.isPlaying())
211 ShowMessage("Player is stopped!");
212 return;
215 bool successful_operation;
216 if (pos == 0) // end of playlist
218 successful_operation = myPlaylist->Add(list, 0);
220 else if (pos == 1) // beginning of playlist
222 successful_operation = myPlaylist->Add(list, 0, 0);
224 else if (pos == 2) // after currently playing track
226 successful_operation = myPlaylist->Add(list, 0, Mpd.GetCurrentSongPos()+1);
228 else if (pos == 3) // after currently playing album
230 std::string album = myPlaylist->NowPlayingSong()->GetAlbum();
231 int i;
232 for (i = Mpd.GetCurrentSongPos()+1; i < int(myPlaylist->Items->Size()); ++i)
233 if ((*myPlaylist->Items)[i].GetAlbum() != album)
234 break;
235 successful_operation = myPlaylist->Add(list, 0, i);
237 else if (pos == 4) // after highlighted item
239 successful_operation = myPlaylist->Add(list, 0, std::min(myPlaylist->Items->Choice()+1, myPlaylist->Items->Size()));
241 else
243 w = itsPlaylistSelector;
244 return;
247 if (successful_operation)
248 ShowMessage("Selected item(s) added!");
250 MPD::FreeSongList(list);
251 SwitchTo();
254 void SelectedItemsAdder::MouseButtonPressed(MEVENT me)
256 if (w->Empty() || !w->hasCoords(me.x, me.y) || size_t(me.y) >= w->Size())
257 return;
258 if (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED))
260 w->Goto(me.y);
261 if (me.bstate & BUTTON3_PRESSED)
262 EnterPressed();
264 else
265 Screen< Menu<std::string> >::MouseButtonPressed(me);
268 void SelectedItemsAdder::SetDimensions()
270 itsWidth = COLS*0.6;
271 itsHeight = std::min(size_t(LINES*0.6), MainHeight);