new feature: support for merging screens together

This commit is contained in:
Andrzej Rybczak
2011-11-12 19:47:47 +01:00
parent e31dec7005
commit 56467eaac6
44 changed files with 633 additions and 218 deletions

View File

@@ -349,6 +349,13 @@
#screen_switcher_mode = "sequence: 2 -> 3" #screen_switcher_mode = "sequence: 2 -> 3"
# #
## ##
## Default width of locked screen (in %).
## Acceptable values are from 20 to 80.
##
#
#locked_screen_width_part = "50"
#
##
## Note: You can define startup screen for ncmpcpp ## Note: You can define startup screen for ncmpcpp
## by choosing screen number from the list above. ## by choosing screen number from the list above.
## ##

View File

@@ -249,9 +249,12 @@ If set to "playlist", Search engine will perform searching in current MPD playli
.B display_screens_numbers_on_start = yes/no .B display_screens_numbers_on_start = yes/no
If enabled, screens' names and their keybindings will be shown in header window until key is pressed, otherwise they won't be displayed at all. If enabled, screens' names and their keybindings will be shown in header window until key is pressed, otherwise they won't be displayed at all.
.TP .TP
.B screen_switcher_previous = SWITCHER_MODE .B screen_switcher_mode = SWITCHER_MODE
If set to "previous", key_screen_switcher will switch between current and last used screen. If set to "sequence: user_defined_sequence", it will switch between given sequence of screens. Syntax clarification can be found in example config file. If set to "previous", key_screen_switcher will switch between current and last used screen. If set to "sequence: user_defined_sequence", it will switch between given sequence of screens. Syntax clarification can be found in example config file.
.TP .TP
.B locked_screen_width_part = 20-80
If you want to lock a screen, ncmpcpp asks for % of locked screen's width to be reserved before that and provides a default value, which is the one you can set here.
.TP
.B startup_screen = SCREEN_NUMBER .B startup_screen = SCREEN_NUMBER
Screen that has to be displayed at start (playlist by default). Screen that has to be displayed at start (playlist by default).
.TP .TP

View File

@@ -2,9 +2,9 @@ bin_PROGRAMS = ncmpcpp
ncmpcpp_SOURCES = browser.cpp charset.cpp clock.cpp conv.cpp curl_handle.cpp \ ncmpcpp_SOURCES = browser.cpp charset.cpp clock.cpp conv.cpp curl_handle.cpp \
display.cpp error.cpp help.cpp helpers.cpp lastfm.cpp lastfm_service.cpp lyrics.cpp \ display.cpp error.cpp help.cpp helpers.cpp lastfm.cpp lastfm_service.cpp lyrics.cpp \
lyrics_fetcher.cpp media_library.cpp menu.cpp mpdpp.cpp ncmpcpp.cpp outputs.cpp \ lyrics_fetcher.cpp media_library.cpp menu.cpp mpdpp.cpp ncmpcpp.cpp outputs.cpp \
playlist.cpp playlist_editor.cpp scrollpad.cpp search_engine.cpp sel_items_adder.cpp \ playlist.cpp playlist_editor.cpp screen.cpp scrollpad.cpp search_engine.cpp \
server_info.cpp settings.cpp song.cpp song_info.cpp status.cpp tag_editor.cpp \ sel_items_adder.cpp server_info.cpp settings.cpp song.cpp song_info.cpp status.cpp \
tiny_tag_editor.cpp tolower.cpp visualizer.cpp window.cpp tag_editor.cpp tiny_tag_editor.cpp tolower.cpp visualizer.cpp window.cpp
# set the include path found by configure # set the include path found by configure
INCLUDES= $(all_includes) INCLUDES= $(all_includes)

View File

@@ -59,7 +59,7 @@ void Browser::Init()
{ {
static Display::ScreenFormat sf = { this, &Config.song_list_format }; static Display::ScreenFormat sf = { this, &Config.song_list_format };
w = new Menu<MPD::Item>(0, MainStartY, COLS, MainHeight, Config.columns_in_browser && Config.titles_visibility ? Display::Columns() : "", Config.main_color, brNone); w = new Menu<MPD::Item>(0, MainStartY, COLS, MainHeight, Config.columns_in_browser && Config.titles_visibility ? Display::Columns(COLS) : "", Config.main_color, brNone);
w->HighlightColor(Config.main_highlight_color); w->HighlightColor(Config.main_highlight_color);
w->CyclicScrolling(Config.use_cyclic_scrolling); w->CyclicScrolling(Config.use_cyclic_scrolling);
w->CenteredCursor(Config.centered_cursor); w->CenteredCursor(Config.centered_cursor);
@@ -73,14 +73,19 @@ void Browser::Init()
void Browser::Resize() void Browser::Resize()
{ {
w->Resize(COLS, MainHeight); size_t x_offset, width;
w->MoveTo(0, MainStartY); GetWindowResizeParams(x_offset, width);
w->SetTitle(Config.columns_in_browser && Config.titles_visibility ? Display::Columns() : ""); w->Resize(width, MainHeight);
w->MoveTo(x_offset, MainStartY);
w->SetTitle(Config.columns_in_browser && Config.titles_visibility ? Display::Columns(w->GetWidth()) : "");
hasToBeResized = 0; hasToBeResized = 0;
} }
void Browser::SwitchTo() void Browser::SwitchTo()
{ {
using Global::myLockedScreen;
using Global::myInactiveScreen;
if (myScreen == this) if (myScreen == this)
{ {
# ifndef WIN32 # ifndef WIN32
@@ -91,7 +96,10 @@ void Browser::SwitchTo()
if (!isInitialized) if (!isInitialized)
Init(); Init();
if (hasToBeResized) if (myLockedScreen)
UpdateInactiveScreen(this);
if (hasToBeResized || myLockedScreen)
Resize(); Resize();
if (isLocal()) // local browser doesn't support sorting by mtime if (isLocal()) // local browser doesn't support sorting by mtime
@@ -108,7 +116,7 @@ void Browser::SwitchTo()
std::basic_string<my_char_t> Browser::Title() std::basic_string<my_char_t> Browser::Title()
{ {
std::basic_string<my_char_t> result = U("Browse: "); std::basic_string<my_char_t> result = U("Browse: ");
result += Scroller(TO_WSTRING(itsBrowsedDir), itsScrollBeginning, w->GetWidth()-result.length()-(Config.new_design ? 2 : Global::VolumeState.length())); result += Scroller(TO_WSTRING(itsBrowsedDir), itsScrollBeginning, COLS-result.length()-(Config.new_design ? 2 : Global::VolumeState.length()));
return result; return result;
} }

View File

@@ -50,6 +50,8 @@ class Browser : public Screen< Menu<MPD::Item> >
virtual List *GetList() { return w; } virtual List *GetList() { return w; }
virtual bool isMergable() { return true; }
const std::string &CurrentDir() { return itsBrowsedDir; } const std::string &CurrentDir() { return itsBrowsedDir; }
bool isLocal() { return itsBrowseLocally; } bool isLocal() { return itsBrowseLocally; }
@@ -65,6 +67,7 @@ class Browser : public Screen< Menu<MPD::Item> >
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return true; }
private: private:
static bool hasSupportedExtension(const std::string &); static bool hasSupportedExtension(const std::string &);

View File

@@ -54,47 +54,57 @@ void Clock::Init()
{ {
Width = Config.clock_display_seconds ? 60 : 40; Width = Config.clock_display_seconds ? 60 : 40;
itsPane = new Window(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
w = new Window((COLS-Width)/2, (MainHeight-Height)/2+MainStartY, Width, Height-1, "", Config.main_color, Border(Config.main_color)); w = new Window((COLS-Width)/2, (MainHeight-Height)/2+MainStartY, Width, Height-1, "", Config.main_color, Border(Config.main_color));
isInitialized = 1; isInitialized = 1;
} }
void Clock::Resize() void Clock::Resize()
{ {
if (Width <= size_t(COLS) && Height <= MainHeight) size_t x_offset, width;
{ GetWindowResizeParams(x_offset, width);
w->MoveTo((COLS-Width)/2, (MainHeight-Height)/2+MainStartY);
if (myScreen == this) // used for clearing area out of clock window while resizing terminal
{ itsPane->Resize(width, MainHeight);
if (myPlaylist->hasToBeResized) itsPane->MoveTo(x_offset, MainStartY);
myPlaylist->Resize(); itsPane->Refresh();
myPlaylist->Items->Hide();
w->Display(); if (Width <= width && Height <= MainHeight)
} w->MoveTo(x_offset+(width-Width)/2, MainStartY+(MainHeight-Height)/2);
}
} }
void Clock::SwitchTo() void Clock::SwitchTo()
{ {
if (Width > size_t(COLS) || Height > MainHeight) using Global::myLockedScreen;
{
ShowMessage("Screen is too small to display clock!");
return;
}
if (myScreen == this) if (myScreen == this)
return; return;
if (!isInitialized) if (!isInitialized)
Init(); Init();
if (hasToBeResized) if (myLockedScreen)
UpdateInactiveScreen(this);
size_t x_offset, width;
GetWindowResizeParams(x_offset, width, false);
if (Width > width || Height > MainHeight)
{
ShowMessage("Screen is too small to display clock!");
if (myLockedScreen)
UpdateInactiveScreen(myLockedScreen);
return;
}
if (hasToBeResized || myLockedScreen)
Resize(); Resize();
if (myScreen != this && myScreen->isTabbable()) if (myScreen != this && myScreen->isTabbable())
Global::myPrevScreen = myScreen; Global::myPrevScreen = myScreen;
myScreen = this; myScreen = this;
myPlaylist->Items->Hide();
Global::RedrawHeader = 1; Global::RedrawHeader = 1;
Prepare(); Prepare();
itsPane->Refresh();
// clearing screen apparently fixes the problem with last digits being misrendered // clearing screen apparently fixes the problem with last digits being misrendered
w->Clear(); w->Clear();
w->Display(); w->Display();
@@ -107,8 +117,20 @@ std::basic_string<my_char_t> Clock::Title()
void Clock::Update() void Clock::Update()
{ {
if (Width > size_t(COLS) || Height > MainHeight) if (Width > itsPane->GetWidth() || Height > MainHeight)
myPlaylist->SwitchTo(); {
using Global::myLockedScreen;
using Global::myInactiveScreen;
if (myLockedScreen)
{
if (myInactiveScreen != myLockedScreen)
myScreen = myInactiveScreen;
myLockedScreen->SwitchTo();
}
else
myPlaylist->SwitchTo();
}
static timeval past = { 0, 0 }; static timeval past = { 0, 0 };
gettimeofday(&past, 0); gettimeofday(&past, 0);

View File

@@ -50,10 +50,15 @@ class Clock : public Screen<Window>
virtual List *GetList() { return 0; } virtual List *GetList() { return 0; }
virtual bool isMergable() { return true; }
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return false; }
private: private:
Window *itsPane;
static void Prepare(); static void Prepare();
static void Set(int, int); static void Set(int, int);

View File

@@ -69,7 +69,7 @@ namespace
} }
} }
std::string Display::Columns() std::string Display::Columns(size_t list_width)
{ {
if (Config.columns.empty()) if (Config.columns.empty())
return ""; return "";
@@ -86,11 +86,11 @@ std::string Display::Columns()
for (std::vector<Column>::const_iterator it = Config.columns.begin(); it != Config.columns.end(); ++it) for (std::vector<Column>::const_iterator it = Config.columns.begin(); it != Config.columns.end(); ++it)
{ {
if (it == Config.columns.end()-1) if (it == Config.columns.end()-1)
width = COLS-where; width = list_width-where;
else if (last_fixed && it == next2last) else if (last_fixed && it == next2last)
width = COLS-where-1-(++next2last)->width; width = list_width-where-1-(++next2last)->width;
else else
width = it->width*(it->fixed ? 1 : COLS/100.0); width = it->width*(it->fixed ? 1 : list_width/100.0);
std::basic_string<my_char_t> tag; std::basic_string<my_char_t> tag;
if (it->type.length() >= 1 && it->name.empty()) if (it->type.length() >= 1 && it->name.empty())
@@ -122,6 +122,7 @@ std::string Display::Columns()
else else
result.resize(std::min(where+1, size_t(COLS)), ' '); result.resize(std::min(where+1, size_t(COLS)), ' ');
} }
result.resize(list_width);
return TO_STRING(result); return TO_STRING(result);
} }
@@ -175,9 +176,9 @@ void Display::SongsInColumns(const MPD::Song &s, void *data, Menu<MPD::Song> *me
if (it == Config.columns.end()-1) if (it == Config.columns.end()-1)
width = menu->GetWidth()-where; width = menu->GetWidth()-where;
else if (last_fixed && it == next2last) else if (last_fixed && it == next2last)
width = COLS-where-1-(++next2last)->width; width = menu->GetWidth()-where-1-(++next2last)->width;
else else
width = it->width*(it->fixed ? 1 : COLS/100.0); width = it->width*(it->fixed ? 1 : menu->GetWidth()/100.0);
MPD::Song::GetFunction get = 0; MPD::Song::GetFunction get = 0;

View File

@@ -34,7 +34,7 @@ namespace Display
std::string *format; std::string *format;
}; };
std::string Columns(); std::string Columns(size_t);
template <typename T> void Generic(const T &t, void *, Menu<T> *menu) template <typename T> void Generic(const T &t, void *, Menu<T> *menu)
{ {

View File

@@ -30,6 +30,8 @@ namespace Global
extern BasicScreen *myScreen; extern BasicScreen *myScreen;
extern BasicScreen *myOldScreen; // for info, lyrics, popups extern BasicScreen *myOldScreen; // for info, lyrics, popups
extern BasicScreen *myPrevScreen; // "real" screen switching (browser, search, etc.) extern BasicScreen *myPrevScreen; // "real" screen switching (browser, search, etc.)
extern BasicScreen *myLockedScreen; // points at the screen that was locked (or is null if no screen is locked)
extern BasicScreen *myInactiveScreen; // points at inactive screen, if locking was enabled and two screens are displayed
extern Window *wHeader; extern Window *wHeader;
extern Window *wFooter; extern Window *wFooter;

View File

@@ -40,14 +40,17 @@ void Help::Init()
void Help::Resize() void Help::Resize()
{ {
w->Resize(COLS, MainHeight); size_t x_offset, width;
w->MoveTo(0, MainStartY); GetWindowResizeParams(x_offset, width);
w->Resize(width, MainHeight);
w->MoveTo(x_offset, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
void Help::SwitchTo() void Help::SwitchTo()
{ {
using Global::myScreen; using Global::myScreen;
using Global::myLockedScreen;
if (myScreen == this) if (myScreen == this)
return; return;
@@ -55,7 +58,10 @@ void Help::SwitchTo()
if (!isInitialized) if (!isInitialized)
Init(); Init();
if (hasToBeResized) if (myLockedScreen)
UpdateInactiveScreen(this);
if (hasToBeResized || myLockedScreen)
Resize(); Resize();
if (myScreen != this && myScreen->isTabbable()) if (myScreen != this && myScreen->isTabbable())
@@ -211,6 +217,7 @@ void Help::GetKeybindings()
*w << DisplayKeys(Key.ToggleFindMode) << "Toggle find mode (normal/wrapped)\n"; *w << DisplayKeys(Key.ToggleFindMode) << "Toggle find mode (normal/wrapped)\n";
*w << DisplayKeys(Key.GoToContainingDir) << "Locate song in browser\n"; *w << DisplayKeys(Key.GoToContainingDir) << "Locate song in browser\n";
*w << DisplayKeys(Key.GoToMediaLibrary) << "Locate current song in media library\n"; *w << DisplayKeys(Key.GoToMediaLibrary) << "Locate current song in media library\n";
*w << DisplayKeys(Key.ToggleScreenLock) << "Lock/unlock current screen\n";
# ifdef HAVE_TAGLIB_H # ifdef HAVE_TAGLIB_H
*w << DisplayKeys(Key.GoToTagEditor) << "Locate current song in tag editor\n"; *w << DisplayKeys(Key.GoToTagEditor) << "Locate current song in tag editor\n";
# endif // HAVE_TAGLIB_H # endif // HAVE_TAGLIB_H

View File

@@ -40,8 +40,11 @@ class Help : public Screen<Scrollpad>
virtual List *GetList() { return 0; } virtual List *GetList() { return 0; }
virtual bool isMergable() { return true; }
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return true; }
private: private:
std::string DisplayKeys(int *, int = 2); std::string DisplayKeys(int *, int = 2);

View File

@@ -461,3 +461,28 @@ std::basic_string<my_char_t> Scroller(const std::basic_string<my_char_t> &str, s
return result; return result;
} }
bool SwitchToNextColumn(BasicScreen *screen)
{
if (screen == myLibrary)
return myLibrary->NextColumn();
else if (screen == myPlaylistEditor)
return myPlaylistEditor->NextColumn();
# ifdef HAVE_TAGLIB_H
else if (screen == myTagEditor)
return myTagEditor->NextColumn();
# endif // HAVE_TAGLIB_H
return false;
}
bool SwitchToPrevColumn(BasicScreen *screen)
{
if (screen == myLibrary)
return myLibrary->PrevColumn();
else if (screen == myPlaylistEditor)
return myPlaylistEditor->PrevColumn();
# ifdef HAVE_TAGLIB_H
else if (screen == myTagEditor)
return myTagEditor->PrevColumn();
# endif // HAVE_TAGLIB_H
return false;
}

View File

@@ -219,5 +219,8 @@ std::string GetLineValue(std::string &, char = '"', char = '"', bool = 0);
std::basic_string<my_char_t> Scroller(const std::basic_string<my_char_t> &str, size_t &pos, size_t width); std::basic_string<my_char_t> Scroller(const std::basic_string<my_char_t> &str, size_t &pos, size_t width);
bool SwitchToNextColumn(BasicScreen *);
bool SwitchToPrevColumn(BasicScreen *);
#endif #endif

View File

@@ -38,8 +38,6 @@
using Global::MainHeight; using Global::MainHeight;
using Global::MainStartY; using Global::MainStartY;
using Global::myScreen;
using Global::myOldScreen;
Lastfm *myLastfm = new Lastfm; Lastfm *myLastfm = new Lastfm;
@@ -51,8 +49,10 @@ void Lastfm::Init()
void Lastfm::Resize() void Lastfm::Resize()
{ {
w->Resize(COLS, MainHeight); size_t x_offset, width;
w->MoveTo(0, MainStartY); GetWindowResizeParams(x_offset, width);
w->Resize(width, MainHeight);
w->MoveTo(x_offset, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
@@ -79,13 +79,20 @@ void Lastfm::Take()
void Lastfm::SwitchTo() void Lastfm::SwitchTo()
{ {
using Global::myScreen;
using Global::myOldScreen;
using Global::myLockedScreen;
if (myScreen == this) if (myScreen == this)
return myOldScreen->SwitchTo(); return myOldScreen->SwitchTo();
if (!isInitialized) if (!isInitialized)
Init(); Init();
if (hasToBeResized) if (myLockedScreen)
UpdateInactiveScreen(this);
if (hasToBeResized || myLockedScreen)
Resize(); Resize();
// get an old info if it waits // get an old info if it waits

View File

@@ -52,6 +52,8 @@ class Lastfm : public Screen<Scrollpad>
virtual List *GetList() { return 0; } virtual List *GetList() { return 0; }
virtual bool isMergable() { return true; }
void Refetch(); void Refetch();
bool isDownloading() { return isDownloadInProgress && !isReadyToTake; } bool isDownloading() { return isDownloadInProgress && !isReadyToTake; }
@@ -59,6 +61,7 @@ class Lastfm : public Screen<Scrollpad>
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return false; }
private: private:
std::basic_string<my_char_t> itsTitle; std::basic_string<my_char_t> itsTitle;

View File

@@ -65,8 +65,10 @@ void Lyrics::Init()
void Lyrics::Resize() void Lyrics::Resize()
{ {
w->Resize(COLS, MainHeight); size_t x_offset, width;
w->MoveTo(0, MainStartY); GetWindowResizeParams(x_offset, width);
w->Resize(width, MainHeight);
w->MoveTo(x_offset, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
@@ -98,6 +100,9 @@ void Lyrics::Update()
void Lyrics::SwitchTo() void Lyrics::SwitchTo()
{ {
using Global::myLockedScreen;
using Global::myInactiveScreen;
if (myScreen == this) if (myScreen == this)
return myOldScreen->SwitchTo(); return myOldScreen->SwitchTo();
@@ -134,14 +139,25 @@ void Lyrics::SwitchTo()
Global::RedrawHeader = 1; Global::RedrawHeader = 1;
} }
else else
{
ShowMessage("Song must have both artist and title tag set!"); ShowMessage("Song must have both artist and title tag set!");
return;
}
}
// if we resize for locked screen, we have to do that in the end since
// fetching lyrics may fail (eg. if tags are missing) and we don't want
// to adjust screen size then.
if (myLockedScreen)
{
UpdateInactiveScreen(this);
Resize();
} }
} }
std::basic_string<my_char_t> Lyrics::Title() std::basic_string<my_char_t> Lyrics::Title()
{ {
std::basic_string<my_char_t> result = U("Lyrics: "); std::basic_string<my_char_t> result = U("Lyrics: ");
result += Scroller(TO_WSTRING(itsSong.toString("{%a - %t}")), itsScrollBegin, w->GetWidth()-result.length()-(Config.new_design ? 2 : Global::VolumeState.length())); result += Scroller(TO_WSTRING(itsSong.toString("{%a - %t}")), itsScrollBegin, COLS-result.length()-(Config.new_design ? 2 : Global::VolumeState.length()));
return result; return result;
} }

View File

@@ -51,6 +51,8 @@ class Lyrics : public Screen<Scrollpad>
virtual List *GetList() { return 0; } virtual List *GetList() { return 0; }
virtual bool isMergable() { return true; }
void Edit(); void Edit();
void Refetch(); void Refetch();
@@ -63,6 +65,7 @@ class Lyrics : public Screen<Scrollpad>
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return false; }
private: private:
void Load(); void Load();

View File

@@ -36,6 +36,7 @@ using Global::myScreen;
MediaLibrary *myLibrary = new MediaLibrary; MediaLibrary *myLibrary = new MediaLibrary;
bool MediaLibrary::hasTwoColumns; bool MediaLibrary::hasTwoColumns;
size_t MediaLibrary::itsLeftColStartX;
size_t MediaLibrary::itsLeftColWidth; size_t MediaLibrary::itsLeftColWidth;
size_t MediaLibrary::itsMiddleColWidth; size_t MediaLibrary::itsMiddleColWidth;
size_t MediaLibrary::itsMiddleColStartX; size_t MediaLibrary::itsMiddleColStartX;
@@ -93,27 +94,30 @@ void MediaLibrary::Init()
void MediaLibrary::Resize() void MediaLibrary::Resize()
{ {
size_t x_offset, width;
GetWindowResizeParams(x_offset, width);
if (!hasTwoColumns) if (!hasTwoColumns)
{ {
itsLeftColWidth = COLS/3-1; itsLeftColStartX = x_offset;
itsMiddleColStartX = itsLeftColWidth+1; itsLeftColWidth = width/3-1;
itsMiddleColWidth = COLS/3; itsMiddleColStartX = itsLeftColStartX+itsLeftColWidth+1;
itsRightColStartX = itsLeftColWidth+itsMiddleColWidth+2; itsMiddleColWidth = width/3;
itsRightColWidth = COLS-COLS/3*2-1; itsRightColStartX = itsMiddleColStartX+itsMiddleColWidth+1;
itsRightColWidth = width-width/3*2-1;
} }
else else
{ {
itsMiddleColStartX = 0; itsMiddleColStartX = x_offset;
itsMiddleColWidth = COLS/2; itsMiddleColWidth = width/2;
itsRightColStartX = itsMiddleColWidth+1; itsRightColStartX = x_offset+itsMiddleColWidth+1;
itsRightColWidth = COLS-itsMiddleColWidth-1; itsRightColWidth = width-itsMiddleColWidth-1;
} }
Artists->Resize(itsLeftColWidth, MainHeight); Artists->Resize(itsLeftColWidth, MainHeight);
Albums->Resize(itsMiddleColWidth, MainHeight); Albums->Resize(itsMiddleColWidth, MainHeight);
Songs->Resize(itsRightColWidth, MainHeight); Songs->Resize(itsRightColWidth, MainHeight);
Artists->MoveTo(0, MainStartY); Artists->MoveTo(itsLeftColStartX, MainStartY);
Albums->MoveTo(itsMiddleColStartX, MainStartY); Albums->MoveTo(itsMiddleColStartX, MainStartY);
Songs->MoveTo(itsRightColStartX, MainStartY); Songs->MoveTo(itsRightColStartX, MainStartY);
@@ -136,6 +140,8 @@ void MediaLibrary::Refresh()
void MediaLibrary::SwitchTo() void MediaLibrary::SwitchTo()
{ {
using Global::myLockedScreen;
if (myScreen == this) if (myScreen == this)
{ {
if (Config.media_library_disable_two_column_mode) if (Config.media_library_disable_two_column_mode)
@@ -169,7 +175,10 @@ void MediaLibrary::SwitchTo()
if (!isInitialized) if (!isInitialized)
Init(); Init();
if (hasToBeResized) if (myLockedScreen)
UpdateInactiveScreen(this);
if (hasToBeResized || myLockedScreen)
Resize(); Resize();
if (myScreen != this && myScreen->isTabbable()) if (myScreen != this && myScreen->isTabbable())
@@ -544,18 +553,18 @@ void MediaLibrary::ApplyFilter(const std::string &s)
GetList()->ApplyFilter(s, 0, REG_ICASE | Config.regex_type); GetList()->ApplyFilter(s, 0, REG_ICASE | Config.regex_type);
} }
void MediaLibrary::NextColumn() bool MediaLibrary::NextColumn()
{ {
if (w == Artists) if (w == Artists)
{ {
if (!hasTwoColumns && Songs->ReallyEmpty()) if (!hasTwoColumns && Songs->ReallyEmpty())
return; return false;
Artists->HighlightColor(Config.main_highlight_color); Artists->HighlightColor(Config.main_highlight_color);
w->Refresh(); w->Refresh();
w = Albums; w = Albums;
Albums->HighlightColor(Config.active_column_color); Albums->HighlightColor(Config.active_column_color);
if (!Albums->ReallyEmpty()) if (!Albums->ReallyEmpty())
return; return true;
} }
if (w == Albums && !Songs->ReallyEmpty()) if (w == Albums && !Songs->ReallyEmpty())
{ {
@@ -563,10 +572,12 @@ void MediaLibrary::NextColumn()
w->Refresh(); w->Refresh();
w = Songs; w = Songs;
Songs->HighlightColor(Config.active_column_color); Songs->HighlightColor(Config.active_column_color);
return true;
} }
return false;
} }
void MediaLibrary::PrevColumn() bool MediaLibrary::PrevColumn()
{ {
if (w == Songs) if (w == Songs)
{ {
@@ -575,7 +586,7 @@ void MediaLibrary::PrevColumn()
w = Albums; w = Albums;
Albums->HighlightColor(Config.active_column_color); Albums->HighlightColor(Config.active_column_color);
if (!Albums->ReallyEmpty()) if (!Albums->ReallyEmpty())
return; return true;
} }
if (w == Albums && !hasTwoColumns) if (w == Albums && !hasTwoColumns)
{ {
@@ -583,7 +594,9 @@ void MediaLibrary::PrevColumn()
w->Refresh(); w->Refresh();
w = Artists; w = Artists;
Artists->HighlightColor(Config.active_column_color); Artists->HighlightColor(Config.active_column_color);
return true;
} }
return false;
} }
void MediaLibrary::LocateSong(const MPD::Song &s) void MediaLibrary::LocateSong(const MPD::Song &s)

View File

@@ -66,9 +66,11 @@ class MediaLibrary : public Screen<Window>
virtual List *GetList(); virtual List *GetList();
virtual bool isMergable() { return true; }
int Columns() { return hasTwoColumns ? 2 : 3; } int Columns() { return hasTwoColumns ? 2 : 3; }
void NextColumn(); bool NextColumn();
void PrevColumn(); bool PrevColumn();
void LocateSong(const MPD::Song &); void LocateSong(const MPD::Song &);
@@ -78,6 +80,7 @@ class MediaLibrary : public Screen<Window>
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return true; }
private: private:
void AddToPlaylist(bool); void AddToPlaylist(bool);
@@ -92,6 +95,7 @@ class MediaLibrary : public Screen<Window>
static bool SortAllTracks(MPD::Song *, MPD::Song *); static bool SortAllTracks(MPD::Song *, MPD::Song *);
static bool hasTwoColumns; static bool hasTwoColumns;
static size_t itsLeftColStartX;
static size_t itsLeftColWidth; static size_t itsLeftColWidth;
static size_t itsMiddleColWidth; static size_t itsMiddleColWidth;
static size_t itsMiddleColStartX; static size_t itsMiddleColStartX;

View File

@@ -75,6 +75,8 @@ using namespace MPD;
BasicScreen *Global::myScreen; BasicScreen *Global::myScreen;
BasicScreen *Global::myOldScreen; BasicScreen *Global::myOldScreen;
BasicScreen *Global::myPrevScreen; BasicScreen *Global::myPrevScreen;
BasicScreen *Global::myLockedScreen;
BasicScreen *Global::myInactiveScreen;
Window *Global::wHeader; Window *Global::wHeader;
Window *Global::wFooter; Window *Global::wFooter;
@@ -107,6 +109,40 @@ namespace
} }
} }
void set_resize_flags()
{
myHelp->hasToBeResized = 1;
myPlaylist->hasToBeResized = 1;
myBrowser->hasToBeResized = 1;
mySearcher->hasToBeResized = 1;
myLibrary->hasToBeResized = 1;
myPlaylistEditor->hasToBeResized = 1;
myLyrics->hasToBeResized = 1;
mySelectedItemsAdder->hasToBeResized = 1;
mySongInfo->hasToBeResized = 1;
# ifdef HAVE_CURL_CURL_H
myLastfm->hasToBeResized = 1;
# endif // HAVE_CURL_CURL_H
# ifdef HAVE_TAGLIB_H
myTinyTagEditor->hasToBeResized = 1;
myTagEditor->hasToBeResized = 1;
# endif // HAVE_TAGLIB_H
# ifdef ENABLE_VISUALIZER
myVisualizer->hasToBeResized = 1;
# endif // ENABLE_VISUALIZER
# ifdef ENABLE_OUTPUTS
myOutputs->hasToBeResized = 1;
# endif // ENABLE_OUTPUTS
# ifdef ENABLE_CLOCK
myClock->hasToBeResized = 1;
# endif // ENABLE_CLOCK
}
void resize_screen() void resize_screen()
{ {
order_resize = 0; order_resize = 0;
@@ -139,38 +175,9 @@ namespace
if (!Config.statusbar_visibility) if (!Config.statusbar_visibility)
MainHeight++; MainHeight++;
myHelp->hasToBeResized = 1; set_resize_flags();
myPlaylist->hasToBeResized = 1;
myBrowser->hasToBeResized = 1;
mySearcher->hasToBeResized = 1;
myLibrary->hasToBeResized = 1;
myPlaylistEditor->hasToBeResized = 1;
myLyrics->hasToBeResized = 1;
mySelectedItemsAdder->hasToBeResized = 1;
mySongInfo->hasToBeResized = 1;
# ifdef HAVE_CURL_CURL_H ApplyToVisibleWindows(&BasicScreen::Resize);
myLastfm->hasToBeResized = 1;
# endif // HAVE_CURL_CURL_H
# ifdef HAVE_TAGLIB_H
myTinyTagEditor->hasToBeResized = 1;
myTagEditor->hasToBeResized = 1;
# endif // HAVE_TAGLIB_H
# ifdef ENABLE_VISUALIZER
myVisualizer->hasToBeResized = 1;
# endif // ENABLE_VISUALIZER
# ifdef ENABLE_OUTPUTS
myOutputs->hasToBeResized = 1;
# endif // ENABLE_OUTPUTS
# ifdef ENABLE_CLOCK
myClock->hasToBeResized = 1;
# endif // ENABLE_CLOCK
myScreen->Resize();
if (Config.header_visibility || Config.new_design) if (Config.header_visibility || Config.new_design)
wHeader->Resize(COLS, header_height); wHeader->Resize(COLS, header_height);
@@ -179,7 +186,7 @@ namespace
wFooter->MoveTo(0, footer_start_y); wFooter->MoveTo(0, footer_start_y);
wFooter->Resize(COLS, Config.statusbar_visibility ? 2 : 1); wFooter->Resize(COLS, Config.statusbar_visibility ? 2 : 1);
myScreen->Refresh(); ApplyToVisibleWindows(&BasicScreen::Refresh);
RedrawStatusbar = 1; RedrawStatusbar = 1;
StatusChanges changes; StatusChanges changes;
if (!Mpd.isPlaying() || design_changed) if (!Mpd.isPlaying() || design_changed)
@@ -201,6 +208,7 @@ namespace
ShowMessage("User interface: %s", Config.new_design ? "Alternative" : "Classic"); ShowMessage("User interface: %s", Config.new_design ? "Alternative" : "Classic");
} }
wFooter->Refresh(); wFooter->Refresh();
refresh();
} }
# if !defined(WIN32) # if !defined(WIN32)
@@ -440,6 +448,7 @@ int main(int argc, char *argv[])
// header stuff end // header stuff end
if (input != ERR) if (input != ERR)
//ApplyToVisibleWindows(&BasicScreen::RefreshWindow);
myScreen->RefreshWindow(); myScreen->RefreshWindow();
wFooter->ReadKey(input); wFooter->ReadKey(input);
@@ -450,9 +459,6 @@ int main(int argc, char *argv[])
RedrawHeader = 1; RedrawHeader = 1;
title_allowed = 1; title_allowed = 1;
if (myScreen == myPlaylist)
myPlaylist->EnableHighlighting();
// key mapping beginning // key mapping beginning
if (Keypressed(input, Key.Up)) if (Keypressed(input, Key.Up))
@@ -607,53 +613,25 @@ int main(int argc, char *argv[])
{ {
myScreen->SpacePressed(); myScreen->SpacePressed();
} }
else if (Keypressed(input, Key.PrevColumn) else if (Keypressed(input, Key.PrevColumn) && SwitchToPrevColumn(myScreen)) { }
&& (myScreen == myLibrary else if (Keypressed(input, Key.NextColumn) && SwitchToNextColumn(myScreen)) { }
|| myScreen == myPlaylistEditor else if (Keypressed(input, Key.PrevColumn) && myLockedScreen && myInactiveScreen && myScreen->isMergable())
# ifdef HAVE_TAGLIB_H
|| myScreen == myTagEditor
# endif // HAVE_TAGLIB_H)
)
)
{ {
if (myScreen == myLibrary) if (myScreen != myLockedScreen)
{ {
myLibrary->PrevColumn(); myInactiveScreen = myScreen;
myScreen = myLockedScreen;
RedrawHeader = 1;
} }
else if (myScreen == myPlaylistEditor)
{
myPlaylistEditor->PrevColumn();
}
# ifdef HAVE_TAGLIB_H
else if (myScreen == myTagEditor)
{
myTagEditor->PrevColumn();
}
# endif // HAVE_TAGLIB_H
} }
else if (Keypressed(input, Key.NextColumn) else if (Keypressed(input, Key.NextColumn) && myLockedScreen && myInactiveScreen && myScreen->isMergable())
&& (myScreen == myLibrary
|| myScreen == myPlaylistEditor
# ifdef HAVE_TAGLIB_H
|| myScreen == myTagEditor
# endif // HAVE_TAGLIB_H)
)
)
{ {
if (myScreen == myLibrary) if (myScreen == myLockedScreen)
{ {
myLibrary->NextColumn(); myScreen = myInactiveScreen;
myInactiveScreen = myLockedScreen;
RedrawHeader = 1;
} }
else if (myScreen == myPlaylistEditor)
{
myPlaylistEditor->NextColumn();
}
# ifdef HAVE_TAGLIB_H
else if (myScreen == myTagEditor)
{
myTagEditor->NextColumn();
}
# endif // HAVE_TAGLIB_H
} }
else if (Keypressed(input, Key.VolumeUp)) else if (Keypressed(input, Key.VolumeUp))
{ {
@@ -1397,7 +1375,7 @@ int main(int argc, char *argv[])
if (Config.columns_in_playlist) if (Config.columns_in_playlist)
{ {
myPlaylist->Items->SetItemDisplayer(Display::SongsInColumns); myPlaylist->Items->SetItemDisplayer(Display::SongsInColumns);
myPlaylist->Items->SetTitle(Config.titles_visibility ? Display::Columns() : ""); myPlaylist->Items->SetTitle(Config.titles_visibility ? Display::Columns(myPlaylist->Items->GetWidth()) : "");
myPlaylist->Items->SetGetStringFunction(Playlist::SongInColumnsToString); myPlaylist->Items->SetGetStringFunction(Playlist::SongInColumnsToString);
} }
else else
@@ -1411,7 +1389,7 @@ int main(int argc, char *argv[])
{ {
Config.columns_in_browser = !Config.columns_in_browser; Config.columns_in_browser = !Config.columns_in_browser;
ShowMessage("Browser display mode: %s", Config.columns_in_browser ? "Columns" : "Classic"); ShowMessage("Browser display mode: %s", Config.columns_in_browser ? "Columns" : "Classic");
myBrowser->Main()->SetTitle(Config.columns_in_browser && Config.titles_visibility ? Display::Columns() : ""); myBrowser->Main()->SetTitle(Config.columns_in_browser && Config.titles_visibility ? Display::Columns(myBrowser->Main()->GetWidth()) : "");
} }
else if (myScreen == mySearcher) else if (myScreen == mySearcher)
@@ -1419,7 +1397,7 @@ int main(int argc, char *argv[])
Config.columns_in_search_engine = !Config.columns_in_search_engine; Config.columns_in_search_engine = !Config.columns_in_search_engine;
ShowMessage("Search engine display mode: %s", Config.columns_in_search_engine ? "Columns" : "Classic"); ShowMessage("Search engine display mode: %s", Config.columns_in_search_engine ? "Columns" : "Classic");
if (mySearcher->Main()->Size() > SearchEngine::StaticOptions) if (mySearcher->Main()->Size() > SearchEngine::StaticOptions)
mySearcher->Main()->SetTitle(Config.columns_in_search_engine && Config.titles_visibility ? Display::Columns() : ""); mySearcher->Main()->SetTitle(Config.columns_in_search_engine && Config.titles_visibility ? Display::Columns(mySearcher->Main()->GetWidth()) : "");
} }
} }
else if (Keypressed(input, Key.ToggleSeparatorsInPlaylist)) else if (Keypressed(input, Key.ToggleSeparatorsInPlaylist))
@@ -1736,6 +1714,35 @@ int main(int argc, char *argv[])
if (s) if (s)
myLibrary->LocateSong(*s); myLibrary->LocateSong(*s);
} }
else if (Keypressed(input, Key.ToggleScreenLock))
{
if (myLockedScreen != 0)
{
BasicScreen::Unlock();
set_resize_flags();
ShowMessage("Screen unlocked");
}
else
{
LockStatusbar();
Statusbar() << "% of the locked screen's width to be reserved (20-80): ";
std::string str_part = wFooter->GetString(IntoStr(Config.locked_screen_width_part*100));
UnlockStatusbar();
if (str_part.empty())
continue;
unsigned part = StrToInt(str_part);
if (part < 20 || part > 80)
{
ShowMessage("Invalid number!");
continue;
}
Config.locked_screen_width_part = part/100.0;
if (myScreen->Lock())
ShowMessage("Screen locked (with %d%% width)", part);
else
ShowMessage("Screen cannot be locked");
}
}
# ifdef HAVE_TAGLIB_H # ifdef HAVE_TAGLIB_H
else if (Keypressed(input, Key.GoToTagEditor)) else if (Keypressed(input, Key.GoToTagEditor))
{ {
@@ -2353,10 +2360,13 @@ int main(int argc, char *argv[])
} }
} }
if (myScreen == myPlaylist)
myPlaylist->EnableHighlighting();
# ifdef ENABLE_VISUALIZER # ifdef ENABLE_VISUALIZER
// visualizer sets timmeout to 40ms, but since only it needs such small // visualizer sets timmeout to 40ms, but since only it needs such small
// value, we should restore defalt one after switching to another screen. // value, we should restore defalt one after switching to another screen.
if (wFooter->GetTimeout() < ncmpcpp_window_timeout && myScreen != myVisualizer) if (wFooter->GetTimeout() < ncmpcpp_window_timeout && !isVisible(myVisualizer))
wFooter->SetTimeout(ncmpcpp_window_timeout); wFooter->SetTimeout(ncmpcpp_window_timeout);
# endif // ENABLE_VISUALIZER # endif // ENABLE_VISUALIZER
} }

View File

@@ -45,13 +45,18 @@ void Outputs::Init()
void Outputs::SwitchTo() void Outputs::SwitchTo()
{ {
using Global::myLockedScreen;
if (myScreen == this) if (myScreen == this)
return; return;
if (!isInitialized) if (!isInitialized)
Init(); Init();
if (hasToBeResized) if (myLockedScreen)
UpdateInactiveScreen(this);
if (hasToBeResized || myLockedScreen)
Resize(); Resize();
if (myScreen != this && myScreen->isTabbable()) if (myScreen != this && myScreen->isTabbable())
@@ -64,8 +69,10 @@ void Outputs::SwitchTo()
void Outputs::Resize() void Outputs::Resize()
{ {
w->Resize(COLS, MainHeight); size_t x_offset, width;
w->MoveTo(0, MainStartY); GetWindowResizeParams(x_offset, width);
w->Resize(width, MainHeight);
w->MoveTo(x_offset, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }

View File

@@ -48,10 +48,13 @@ class Outputs : public Screen< Menu<MPD::Output> >
virtual List *GetList() { return w; } virtual List *GetList() { return w; }
virtual bool isMergable() { return true; }
void FetchList(); void FetchList();
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return true; }
}; };
extern Outputs *myOutputs; extern Outputs *myOutputs;

View File

@@ -49,7 +49,7 @@ void Playlist::Init()
{ {
static Display::ScreenFormat sf = { this, &Config.song_list_format }; static Display::ScreenFormat sf = { this, &Config.song_list_format };
Items = new Menu<MPD::Song>(0, MainStartY, COLS, MainHeight, Config.columns_in_playlist && Config.titles_visibility ? Display::Columns() : "", Config.main_color, brNone); Items = new Menu<MPD::Song>(0, MainStartY, COLS, MainHeight, Config.columns_in_playlist && Config.titles_visibility ? Display::Columns(COLS) : "", Config.main_color, brNone);
Items->CyclicScrolling(Config.use_cyclic_scrolling); Items->CyclicScrolling(Config.use_cyclic_scrolling);
Items->CenteredCursor(Config.centered_cursor); Items->CenteredCursor(Config.centered_cursor);
Items->HighlightColor(Config.main_highlight_color); Items->HighlightColor(Config.main_highlight_color);
@@ -92,6 +92,8 @@ void Playlist::Init()
void Playlist::SwitchTo() void Playlist::SwitchTo()
{ {
using Global::myScreen; using Global::myScreen;
using Global::myLockedScreen;
using Global::myInactiveScreen;
if (myScreen == this) if (myScreen == this)
return; return;
@@ -101,7 +103,10 @@ void Playlist::SwitchTo()
itsScrollBegin = 0; itsScrollBegin = 0;
if (hasToBeResized) if (myLockedScreen)
UpdateInactiveScreen(this);
if (hasToBeResized || myLockedScreen)
Resize(); Resize();
if (myScreen != this && myScreen->isTabbable()) if (myScreen != this && myScreen->isTabbable())
@@ -116,9 +121,12 @@ void Playlist::SwitchTo()
void Playlist::Resize() void Playlist::Resize()
{ {
Items->Resize(COLS, MainHeight); size_t x_offset, width;
Items->MoveTo(0, MainStartY); GetWindowResizeParams(x_offset, width);
Items->SetTitle(Config.columns_in_playlist && Config.titles_visibility ? Display::Columns() : ""); Items->Resize(width, MainHeight);
Items->MoveTo(x_offset, MainStartY);
Items->SetTitle(Config.columns_in_playlist && Config.titles_visibility ? Display::Columns(Items->GetWidth()) : "");
if (w == SortDialog) // if sorting window is active, playlist needs refreshing if (w == SortDialog) // if sorting window is active, playlist needs refreshing
Items->Display(); Items->Display();
@@ -126,7 +134,7 @@ void Playlist::Resize()
if (Items->GetWidth() >= SortDialogWidth && MainHeight >= 5) if (Items->GetWidth() >= SortDialogWidth && MainHeight >= 5)
{ {
SortDialog->Resize(SortDialogWidth, SortDialogHeight); SortDialog->Resize(SortDialogWidth, SortDialogHeight);
SortDialog->MoveTo((COLS-SortDialogWidth)/2, (MainHeight-SortDialogHeight)/2+MainStartY); SortDialog->MoveTo(x_offset+(width-SortDialogWidth)/2, (MainHeight-SortDialogHeight)/2+MainStartY);
} }
else // if screen is too low to display sorting window, fall back to items list else // if screen is too low to display sorting window, fall back to items list
w = Items; w = Items;
@@ -139,7 +147,7 @@ std::basic_string<my_char_t> Playlist::Title()
std::basic_string<my_char_t> result = U("Playlist "); std::basic_string<my_char_t> result = U("Playlist ");
if (ReloadTotalLength || ReloadRemaining) if (ReloadTotalLength || ReloadRemaining)
itsBufferedStats = TotalLength(); itsBufferedStats = TotalLength();
result += Scroller(TO_WSTRING(itsBufferedStats), itsScrollBegin, Items->GetWidth()-result.length()-(Config.new_design ? 2 : Global::VolumeState.length())); result += Scroller(TO_WSTRING(itsBufferedStats), itsScrollBegin, COLS-result.length()-(Config.new_design ? 2 : Global::VolumeState.length()));
return result; return result;
} }

View File

@@ -55,6 +55,8 @@ class Playlist : public Screen<Window>
virtual List *GetList() { return w == Items ? Items : 0; } virtual List *GetList() { return w == Items ? Items : 0; }
virtual bool isMergable() { return true; }
bool isPlaying() { return NowPlaying >= 0 && !Items->Empty(); } bool isPlaying() { return NowPlaying >= 0 && !Items->Empty(); }
const MPD::Song *NowPlayingSong(); const MPD::Song *NowPlayingSong();
@@ -85,6 +87,7 @@ class Playlist : public Screen<Window>
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return true; }
private: private:
std::string TotalLength(); std::string TotalLength();

View File

@@ -35,6 +35,7 @@ using Global::MainStartY;
PlaylistEditor *myPlaylistEditor = new PlaylistEditor; PlaylistEditor *myPlaylistEditor = new PlaylistEditor;
size_t PlaylistEditor::LeftColumnStartX;
size_t PlaylistEditor::LeftColumnWidth; size_t PlaylistEditor::LeftColumnWidth;
size_t PlaylistEditor::RightColumnStartX; size_t PlaylistEditor::RightColumnStartX;
size_t PlaylistEditor::RightColumnWidth; size_t PlaylistEditor::RightColumnWidth;
@@ -70,14 +71,18 @@ void PlaylistEditor::Init()
void PlaylistEditor::Resize() void PlaylistEditor::Resize()
{ {
LeftColumnWidth = COLS/3-1; size_t x_offset, width;
RightColumnStartX = LeftColumnWidth+1; GetWindowResizeParams(x_offset, width);
RightColumnWidth = COLS-LeftColumnWidth-1;
LeftColumnStartX = x_offset;
LeftColumnWidth = width/3-1;
RightColumnStartX = LeftColumnStartX+LeftColumnWidth+1;
RightColumnWidth = width-LeftColumnWidth-1;
Playlists->Resize(LeftColumnWidth, MainHeight); Playlists->Resize(LeftColumnWidth, MainHeight);
Content->Resize(RightColumnWidth, MainHeight); Content->Resize(RightColumnWidth, MainHeight);
Playlists->MoveTo(0, MainStartY); Playlists->MoveTo(LeftColumnStartX, MainStartY);
Content->MoveTo(RightColumnStartX, MainStartY); Content->MoveTo(RightColumnStartX, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
@@ -98,6 +103,7 @@ void PlaylistEditor::Refresh()
void PlaylistEditor::SwitchTo() void PlaylistEditor::SwitchTo()
{ {
using Global::myScreen; using Global::myScreen;
using Global::myLockedScreen;
if (myScreen == this) if (myScreen == this)
return; return;
@@ -105,7 +111,10 @@ void PlaylistEditor::SwitchTo()
if (!isInitialized) if (!isInitialized)
Init(); Init();
if (hasToBeResized) if (myLockedScreen)
UpdateInactiveScreen(this);
if (hasToBeResized || myLockedScreen)
Resize(); Resize();
if (myScreen != this && myScreen->isTabbable()) if (myScreen != this && myScreen->isTabbable())
@@ -139,7 +148,11 @@ void PlaylistEditor::Update()
MPD::SongList list; MPD::SongList list;
Mpd.GetPlaylistContent(locale_to_utf_cpy(Playlists->Current()), list); Mpd.GetPlaylistContent(locale_to_utf_cpy(Playlists->Current()), list);
if (!list.empty()) if (!list.empty())
Content->SetTitle(Config.titles_visibility ? "Playlist's content (" + IntoStr(list.size()) + " item" + (list.size() == 1 ? ")" : "s)") : ""); {
std::string title = Config.titles_visibility ? "Playlist's content (" + IntoStr(list.size()) + " item" + (list.size() == 1 ? ")" : "s)") : "";
title.resize(Content->GetWidth());
Content->SetTitle(title);
}
else else
Content->SetTitle(Config.titles_visibility ? "Playlist's content" : ""); Content->SetTitle(Config.titles_visibility ? "Playlist's content" : "");
bool bold = 0; bool bold = 0;
@@ -175,7 +188,7 @@ void PlaylistEditor::Update()
} }
} }
void PlaylistEditor::NextColumn() bool PlaylistEditor::NextColumn()
{ {
if (w == Playlists) if (w == Playlists)
{ {
@@ -183,10 +196,12 @@ void PlaylistEditor::NextColumn()
w->Refresh(); w->Refresh();
w = Content; w = Content;
Content->HighlightColor(Config.active_column_color); Content->HighlightColor(Config.active_column_color);
return true;
} }
return false;
} }
void PlaylistEditor::PrevColumn() bool PlaylistEditor::PrevColumn()
{ {
if (w == Content) if (w == Content)
{ {
@@ -194,7 +209,9 @@ void PlaylistEditor::PrevColumn()
w->Refresh(); w->Refresh();
w = Playlists; w = Playlists;
Playlists->HighlightColor(Config.active_column_color); Playlists->HighlightColor(Config.active_column_color);
return true;
} }
return false;
} }
void PlaylistEditor::AddToPlaylist(bool add_n_play) void PlaylistEditor::AddToPlaylist(bool add_n_play)

View File

@@ -52,18 +52,22 @@ class PlaylistEditor : public Screen<Window>
virtual List *GetList(); virtual List *GetList();
void NextColumn(); virtual bool isMergable() { return true; }
void PrevColumn();
bool NextColumn();
bool PrevColumn();
Menu<std::string> *Playlists; Menu<std::string> *Playlists;
Menu<MPD::Song> *Content; Menu<MPD::Song> *Content;
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return true; }
private: private:
void AddToPlaylist(bool); void AddToPlaylist(bool);
static size_t LeftColumnStartX;
static size_t LeftColumnWidth; static size_t LeftColumnWidth;
static size_t RightColumnStartX; static size_t RightColumnStartX;
static size_t RightColumnWidth; static size_t RightColumnWidth;

107
src/screen.cpp Normal file
View File

@@ -0,0 +1,107 @@
/***************************************************************************
* Copyright (C) 2008-2011 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include <cassert>
#include "screen.h"
#include "global.h"
using Global::myScreen;
using Global::myLockedScreen;
using Global::myInactiveScreen;
void ApplyToVisibleWindows(void (BasicScreen::*f)())
{
if (myLockedScreen)
{
if (myScreen == myLockedScreen)
{
if (myInactiveScreen)
(myInactiveScreen->*f)();
}
else
(myLockedScreen->*f)();
}
(myScreen->*f)();
}
void UpdateInactiveScreen(BasicScreen *screen)
{
myInactiveScreen = myLockedScreen == screen ? 0 : myScreen;
}
bool isVisible(BasicScreen *screen)
{
assert(screen != 0);
if (myLockedScreen)
return screen == myScreen || screen == myInactiveScreen || screen == myLockedScreen;
else
return screen == myScreen;
}
void BasicScreen::GetWindowResizeParams(size_t &x_offset, size_t &width, bool adjust_locked_screen)
{
width = COLS;
x_offset = 0;
if (myLockedScreen && myInactiveScreen)
{
size_t locked_width = COLS*Config.locked_screen_width_part;
if (myLockedScreen == this)
width = locked_width;
else
{
width = COLS-locked_width-1;
x_offset = locked_width+1;
if (adjust_locked_screen)
{
myLockedScreen->Resize();
myLockedScreen->Refresh();
attron(COLOR_PAIR(Config.main_color));
mvvline(Global::MainStartY, x_offset-1, 0, Global::MainHeight);
attroff(COLOR_PAIR(Config.main_color));
refresh();
}
}
}
}
bool BasicScreen::Lock()
{
if (myLockedScreen)
return false;
if (isLockable())
{
myLockedScreen = this;
return true;
}
else
return false;
}
void BasicScreen::Unlock()
{
if (myInactiveScreen && myInactiveScreen != myLockedScreen)
myScreen = myInactiveScreen;
myLockedScreen->SwitchTo();
myLockedScreen = 0;
myInactiveScreen = 0;
}

View File

@@ -28,6 +28,10 @@
#include "settings.h" #include "settings.h"
#include "status.h" #include "status.h"
void ApplyToVisibleWindows(void (BasicScreen::*f)());
void UpdateInactiveScreen(BasicScreen *);
bool isVisible(BasicScreen *);
/// An interface for various instantiations of Screen template class. Since C++ doesn't like /// An interface for various instantiations of Screen template class. Since C++ doesn't like
/// comparison of two different instantiations of the same template class we need the most /// comparison of two different instantiations of the same template class we need the most
/// basic class to be non-template to allow it. /// basic class to be non-template to allow it.
@@ -43,7 +47,7 @@ class BasicScreen
/// @see Screen::ActiveWindow() /// @see Screen::ActiveWindow()
/// ///
virtual void *ActiveWindow() = 0; virtual Window *ActiveWindow() = 0;
/// Method used for switching to screen /// Method used for switching to screen
/// ///
@@ -129,10 +133,23 @@ class BasicScreen
/// ///
virtual bool isTabbable() { return false; } virtual bool isTabbable() { return false; }
/// @return true if screen is mergable, ie. can be "proper" subwindow
/// if one of the screens is locked. Screens that somehow resemble popups
/// will want to return false here.
virtual bool isMergable() = 0;
/// Locks current screen.
/// @return true if lock was successful, false otherwise. Note that
/// if there is already locked screen, it'll not overwrite it.
bool Lock();
/// Should be set to true each time screen needs resize /// Should be set to true each time screen needs resize
/// ///
bool hasToBeResized; bool hasToBeResized;
/// Unlocks a screen, ie. hides merged window (if there is one set).
static void Unlock();
protected: protected:
/// Since screens initialization is lazy, we don't want to do /// Since screens initialization is lazy, we don't want to do
/// this in the constructor. This function should be invoked /// this in the constructor. This function should be invoked
@@ -141,6 +158,18 @@ class BasicScreen
/// ///
virtual void Init() = 0; virtual void Init() = 0;
/// @return true if screen can be locked. Note that returning
/// false here doesn't neccesarily mean that screen is also not
/// mergable (eg. lyrics screen is not lockable since that wouldn't
/// make much sense, but it's perfectly fine to merge it).
virtual bool isLockable() = 0;
/// Gets X offset and width of current screen to be used eg. in Resize() function.
/// @param adjust_locked_screen indicates whether this function should
/// automatically adjust locked screen's dimensions (is there is one set)
/// if current screen is going to be subwindow.
void GetWindowResizeParams(size_t &x_offset, size_t &width, bool adjust_locked_screen = true);
/// Flag that inditates whether the screen is initialized or not /// Flag that inditates whether the screen is initialized or not
/// ///
bool isInitialized; bool isInitialized;
@@ -161,7 +190,7 @@ template <typename WindowType> class Screen : public BasicScreen
/// active /// active
/// @return address to window object cast to void * /// @return address to window object cast to void *
/// ///
virtual void *ActiveWindow(); virtual Window *ActiveWindow();
/// @return pointer to currently active window /// @return pointer to currently active window
/// ///
@@ -203,7 +232,7 @@ template <typename WindowType> class Screen : public BasicScreen
WindowType *w; WindowType *w;
}; };
template <typename WindowType> void *Screen<WindowType>::ActiveWindow() template <typename WindowType> Window *Screen<WindowType>::ActiveWindow()
{ {
return w; return w;
} }

View File

@@ -78,15 +78,18 @@ void SearchEngine::Init()
void SearchEngine::Resize() void SearchEngine::Resize()
{ {
w->Resize(COLS, MainHeight); size_t x_offset, width;
w->MoveTo(0, MainStartY); GetWindowResizeParams(x_offset, width);
w->SetTitle(Config.columns_in_search_engine && Config.titles_visibility ? Display::Columns() : ""); w->Resize(width, MainHeight);
w->MoveTo(x_offset, MainStartY);
w->SetTitle(Config.columns_in_search_engine && Config.titles_visibility ? Display::Columns(w->GetWidth()) : "");
hasToBeResized = 0; hasToBeResized = 0;
} }
void SearchEngine::SwitchTo() void SearchEngine::SwitchTo()
{ {
using Global::myScreen; using Global::myScreen;
using Global::myLockedScreen;
if (myScreen == this) if (myScreen == this)
{ {
@@ -97,7 +100,10 @@ void SearchEngine::SwitchTo()
if (!isInitialized) if (!isInitialized)
Init(); Init();
if (hasToBeResized) if (myLockedScreen)
UpdateInactiveScreen(this);
if (hasToBeResized || myLockedScreen)
Resize(); Resize();
if (w->Empty()) if (w->Empty())
@@ -156,7 +162,7 @@ void SearchEngine::EnterPressed()
if (!w->Back().first) if (!w->Back().first)
{ {
if (Config.columns_in_search_engine) if (Config.columns_in_search_engine)
w->SetTitle(Config.titles_visibility ? Display::Columns() : ""); w->SetTitle(Config.titles_visibility ? Display::Columns(w->GetWidth()) : "");
size_t found = w->Size()-SearchEngine::StaticOptions; size_t found = w->Size()-SearchEngine::StaticOptions;
found += 3; // don't count options inserted below found += 3; // don't count options inserted below
w->InsertSeparator(ResetButton+1); w->InsertSeparator(ResetButton+1);

View File

@@ -48,6 +48,8 @@ class SearchEngine : public Screen< Menu< std::pair<Buffer *, MPD::Song *> > >
virtual List *GetList() { return w->Size() >= StaticOptions ? w : 0; } virtual List *GetList() { return w->Size() >= StaticOptions ? w : 0; }
virtual bool isMergable() { return true; }
void UpdateFoundList(); void UpdateFoundList();
void Scroll(int); void Scroll(int);
void SelectAlbum(); void SelectAlbum();
@@ -58,6 +60,7 @@ class SearchEngine : public Screen< Menu< std::pair<Buffer *, MPD::Song *> > >
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return true; }
private: private:
void Prepare(); void Prepare();

View File

@@ -43,8 +43,11 @@ class SelectedItemsAdder : public Screen< Menu<std::string> >
virtual List *GetList() { return w; } virtual List *GetList() { return w; }
virtual bool isMergable() { return false; }
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return false; }
private: private:
void SetDimensions(); void SetDimensions();

View File

@@ -40,8 +40,11 @@ class ServerInfo : public Screen<Scrollpad>
virtual List *GetList() { return 0; } virtual List *GetList() { return 0; }
virtual bool isMergable() { return false; }
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return false; }
private: private:
void SetDimensions(); void SetDimensions();

View File

@@ -252,6 +252,7 @@ void NcmpcppKeys::SetDefaults()
ToggleSeparatorsInPlaylist[0] = '!'; ToggleSeparatorsInPlaylist[0] = '!';
ToggleLyricsDB[0] = 'L'; ToggleLyricsDB[0] = 'L';
ToggleFetchingLyricsInBackground[0] = 'F'; ToggleFetchingLyricsInBackground[0] = 'F';
ToggleScreenLock[0] = 12;
GoToParentDir[0] = KEY_BACKSPACE; GoToParentDir[0] = KEY_BACKSPACE;
SwitchTagTypeList[0] = '`'; SwitchTagTypeList[0] = '`';
Quit[0] = 'q'; Quit[0] = 'q';
@@ -341,6 +342,7 @@ void NcmpcppKeys::SetDefaults()
ToggleSeparatorsInPlaylist[1] = NullKey; ToggleSeparatorsInPlaylist[1] = NullKey;
ToggleLyricsDB[1] = NullKey; ToggleLyricsDB[1] = NullKey;
ToggleFetchingLyricsInBackground[1] = NullKey; ToggleFetchingLyricsInBackground[1] = NullKey;
ToggleScreenLock[1] = NullKey;
GoToParentDir[1] = 127; GoToParentDir[1] = 127;
SwitchTagTypeList[1] = NullKey; SwitchTagTypeList[1] = NullKey;
Quit[1] = 'Q'; Quit[1] = 'Q';
@@ -446,6 +448,7 @@ void NcmpcppConfig::SetDefaults()
lines_scrolled = 2; lines_scrolled = 2;
search_engine_default_search_mode = 0; search_engine_default_search_mode = 0;
visualizer_sync_interval = 30; visualizer_sync_interval = 30;
locked_screen_width_part = 0.5;
selected_item_suffix_length = 0; selected_item_suffix_length = 0;
now_playing_suffix_length = 0; now_playing_suffix_length = 0;
# ifdef HAVE_LANGINFO_H # ifdef HAVE_LANGINFO_H
@@ -1131,6 +1134,12 @@ void NcmpcppConfig::Read()
if (interval) if (interval)
visualizer_sync_interval = interval; visualizer_sync_interval = interval;
} }
else if (cl.find("locked_screen_width_part") != std::string::npos)
{
unsigned part = StrToInt(v);
if (part)
locked_screen_width_part = part/100.0;
}
else if (cl.find("song_window_title_format") != std::string::npos) else if (cl.find("song_window_title_format") != std::string::npos)
{ {
if (!v.empty() && MPD::Song::isFormatOk("song_window_title_format", v)) if (!v.empty() && MPD::Song::isFormatOk("song_window_title_format", v))

View File

@@ -143,6 +143,7 @@ struct NcmpcppKeys
int ToggleSeparatorsInPlaylist[2]; int ToggleSeparatorsInPlaylist[2];
int ToggleLyricsDB[2]; int ToggleLyricsDB[2];
int ToggleFetchingLyricsInBackground[2]; int ToggleFetchingLyricsInBackground[2];
int ToggleScreenLock[2];
int GoToParentDir[2]; int GoToParentDir[2];
int SwitchTagTypeList[2]; int SwitchTagTypeList[2];
int Quit[2]; int Quit[2];
@@ -270,6 +271,8 @@ struct NcmpcppConfig
unsigned search_engine_default_search_mode; unsigned search_engine_default_search_mode;
unsigned visualizer_sync_interval; unsigned visualizer_sync_interval;
double locked_screen_width_part;
size_t selected_item_suffix_length; size_t selected_item_suffix_length;
size_t now_playing_suffix_length; size_t now_playing_suffix_length;

View File

@@ -24,8 +24,6 @@
using Global::MainHeight; using Global::MainHeight;
using Global::MainStartY; using Global::MainStartY;
using Global::myScreen;
using Global::myOldScreen;
SongInfo *mySongInfo = new SongInfo; SongInfo *mySongInfo = new SongInfo;
@@ -53,8 +51,10 @@ void SongInfo::Init()
void SongInfo::Resize() void SongInfo::Resize()
{ {
w->Resize(COLS, MainHeight); size_t x_offset, width;
w->MoveTo(0, MainStartY); GetWindowResizeParams(x_offset, width);
w->Resize(width, MainHeight);
w->MoveTo(x_offset, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
@@ -65,18 +65,25 @@ std::basic_string<my_char_t> SongInfo::Title()
void SongInfo::SwitchTo() void SongInfo::SwitchTo()
{ {
using Global::myScreen;
using Global::myOldScreen;
using Global::myLockedScreen;
if (myScreen == this) if (myScreen == this)
return myOldScreen->SwitchTo(); return myOldScreen->SwitchTo();
if (!isInitialized) if (!isInitialized)
Init(); Init();
if (myLockedScreen)
UpdateInactiveScreen(this);
MPD::Song *s = myScreen->CurrentSong(); MPD::Song *s = myScreen->CurrentSong();
if (!s) if (!s)
return; return;
if (hasToBeResized) if (hasToBeResized || myLockedScreen)
Resize(); Resize();
myOldScreen = myScreen; myOldScreen = myScreen;

View File

@@ -46,10 +46,13 @@ class SongInfo : public Screen<Scrollpad>
virtual List *GetList() { return 0; } virtual List *GetList() { return 0; }
virtual bool isMergable() { return true; }
static const Metadata Tags[]; static const Metadata Tags[];
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return false; }
private: private:
void PrepareSong(MPD::Song &); void PrepareSong(MPD::Song &);

View File

@@ -41,6 +41,8 @@
#include "visualizer.h" #include "visualizer.h"
using Global::myScreen; using Global::myScreen;
using Global::myLockedScreen;
using Global::myInactiveScreen;
using Global::wFooter; using Global::wFooter;
using Global::Timer; using Global::Timer;
using Global::wHeader; using Global::wHeader;
@@ -156,6 +158,16 @@ void TraceMpdStatus()
Global::UpdateStatusImmediately = 0; Global::UpdateStatusImmediately = 0;
} }
if (myLockedScreen)
{
if (myScreen == myLockedScreen)
{
if (myInactiveScreen)
myInactiveScreen->Update();
}
else
myLockedScreen->Update();
}
myScreen->Update(); myScreen->Update();
if (myScreen->ActiveWindow() == myPlaylist->Items if (myScreen->ActiveWindow() == myPlaylist->Items
@@ -283,19 +295,19 @@ void NcmpcppStatusChanged(MPD::Connection *, MPD::StatusChanges changed, void *)
if (!Global::BlockItemListUpdate) if (!Global::BlockItemListUpdate)
{ {
if (myScreen == myBrowser) if (isVisible(myBrowser))
{ {
myBrowser->UpdateItemList(); myBrowser->UpdateItemList();
} }
else if (myScreen == mySearcher) else if (isVisible(mySearcher))
{ {
mySearcher->UpdateFoundList(); mySearcher->UpdateFoundList();
} }
else if (myScreen == myLibrary) else if (isVisible(myLibrary))
{ {
UpdateSongList(myLibrary->Songs); UpdateSongList(myLibrary->Songs);
} }
else if (myScreen == myPlaylistEditor) else if (isVisible(myPlaylistEditor))
{ {
UpdateSongList(myPlaylistEditor->Content); UpdateSongList(myPlaylistEditor->Content);
} }
@@ -305,7 +317,7 @@ void NcmpcppStatusChanged(MPD::Connection *, MPD::StatusChanges changed, void *)
{ {
if (myBrowser->Main()) if (myBrowser->Main())
{ {
if (myScreen == myBrowser) if (isVisible(myBrowser))
myBrowser->GetDirectory(myBrowser->CurrentDir()); myBrowser->GetDirectory(myBrowser->CurrentDir());
else else
myBrowser->Main()->Clear(); myBrowser->Main()->Clear();
@@ -370,7 +382,7 @@ void NcmpcppStatusChanged(MPD::Connection *, MPD::StatusChanges changed, void *)
else else
player_state.clear(); player_state.clear();
# ifdef ENABLE_VISUALIZER # ifdef ENABLE_VISUALIZER
if (myScreen == myVisualizer) if (isVisible(myVisualizer))
myVisualizer->Main()->Clear(); myVisualizer->Main()->Clear();
# endif // ENABLE_VISUALIZER # endif // ENABLE_VISUALIZER
break; break;
@@ -412,7 +424,7 @@ void NcmpcppStatusChanged(MPD::Connection *, MPD::StatusChanges changed, void *)
if (Config.autocenter_mode && !myPlaylist->Items->isFiltered()) if (Config.autocenter_mode && !myPlaylist->Items->isFiltered())
myPlaylist->Items->Highlight(myPlaylist->NowPlaying); myPlaylist->Items->Highlight(myPlaylist->NowPlaying);
if (Config.now_playing_lyrics && myScreen == myLyrics && Global::myOldScreen == myPlaylist) if (Config.now_playing_lyrics && isVisible(myLyrics) && Global::myOldScreen == myPlaylist)
myLyrics->ReloadNP = 1; myLyrics->ReloadNP = 1;
} }
Playlist::ReloadRemaining = 1; Playlist::ReloadRemaining = 1;
@@ -647,7 +659,7 @@ void NcmpcppStatusChanged(MPD::Connection *, MPD::StatusChanges changed, void *)
if (changed.PlayerState || (changed.ElapsedTime && (!Config.new_design || Mpd.GetState() == MPD::psPlay))) if (changed.PlayerState || (changed.ElapsedTime && (!Config.new_design || Mpd.GetState() == MPD::psPlay)))
wFooter->Refresh(); wFooter->Refresh();
if (changed.Playlist || changed.Database || changed.PlayerState || changed.SongID) if (changed.Playlist || changed.Database || changed.PlayerState || changed.SongID)
myScreen->RefreshWindow(); ApplyToVisibleWindows(&BasicScreen::RefreshWindow);
} }
Window &Statusbar() Window &Statusbar()

View File

@@ -48,6 +48,7 @@ const std::string TagEditor::PatternsFile = config_dir + "patterns.list";
std::list<std::string> TagEditor::Patterns; std::list<std::string> TagEditor::Patterns;
size_t TagEditor::LeftColumnWidth; size_t TagEditor::LeftColumnWidth;
size_t TagEditor::LeftColumnStartX;
size_t TagEditor::MiddleColumnWidth; size_t TagEditor::MiddleColumnWidth;
size_t TagEditor::MiddleColumnStartX; size_t TagEditor::MiddleColumnStartX;
size_t TagEditor::RightColumnWidth; size_t TagEditor::RightColumnWidth;
@@ -62,7 +63,7 @@ size_t TagEditor::FParserHeight;
void TagEditor::Init() void TagEditor::Init()
{ {
SetDimensions(); SetDimensions(0, COLS);
Albums = new Menu<string_pair>(0, MainStartY, LeftColumnWidth, MainHeight, Config.titles_visibility ? "Albums" : "", Config.main_color, brNone); Albums = new Menu<string_pair>(0, MainStartY, LeftColumnWidth, MainHeight, Config.titles_visibility ? "Albums" : "", Config.main_color, brNone);
Albums->HighlightColor(Config.active_column_color); Albums->HighlightColor(Config.active_column_color);
@@ -133,17 +134,18 @@ void TagEditor::Init()
isInitialized = 1; isInitialized = 1;
} }
void TagEditor::SetDimensions() void TagEditor::SetDimensions(size_t x_offset, size_t width)
{ {
MiddleColumnWidth = std::min(26, COLS-2); MiddleColumnWidth = std::min(26, COLS-2);
LeftColumnWidth = (COLS-MiddleColumnWidth)/2; LeftColumnStartX = x_offset;
MiddleColumnStartX = LeftColumnWidth+1; LeftColumnWidth = (width-MiddleColumnWidth)/2;
RightColumnWidth = COLS-LeftColumnWidth-MiddleColumnWidth-2; MiddleColumnStartX = LeftColumnStartX+LeftColumnWidth+1;
RightColumnStartX = LeftColumnWidth+MiddleColumnWidth+2; RightColumnWidth = width-LeftColumnWidth-MiddleColumnWidth-2;
RightColumnStartX = MiddleColumnStartX+MiddleColumnWidth+1;
FParserDialogWidth = std::min(30, COLS); FParserDialogWidth = std::min(30, COLS);
FParserDialogHeight = std::min(size_t(6), MainHeight); FParserDialogHeight = std::min(size_t(6), MainHeight);
FParserWidth = COLS*0.9; FParserWidth = width*0.9;
FParserHeight = std::min(size_t(LINES*0.8), MainHeight); FParserHeight = std::min(size_t(LINES*0.8), MainHeight);
FParserWidthOne = FParserWidth/2; FParserWidthOne = FParserWidth/2;
FParserWidthTwo = FParserWidth-FParserWidthOne; FParserWidthTwo = FParserWidth-FParserWidthOne;
@@ -151,7 +153,9 @@ void TagEditor::SetDimensions()
void TagEditor::Resize() void TagEditor::Resize()
{ {
SetDimensions(); size_t x_offset, width;
GetWindowResizeParams(x_offset, width);
SetDimensions(x_offset, width);
Albums->Resize(LeftColumnWidth, MainHeight); Albums->Resize(LeftColumnWidth, MainHeight);
Dirs->Resize(LeftColumnWidth, MainHeight); Dirs->Resize(LeftColumnWidth, MainHeight);
@@ -162,15 +166,15 @@ void TagEditor::Resize()
FParserLegend->Resize(FParserWidthTwo, FParserHeight); FParserLegend->Resize(FParserWidthTwo, FParserHeight);
FParserPreview->Resize(FParserWidthTwo, FParserHeight); FParserPreview->Resize(FParserWidthTwo, FParserHeight);
Albums->MoveTo(0, MainStartY); Albums->MoveTo(LeftColumnStartX, MainStartY);
Dirs->MoveTo(0, MainStartY); Dirs->MoveTo(LeftColumnStartX, MainStartY);
TagTypes->MoveTo(MiddleColumnStartX, MainStartY); TagTypes->MoveTo(MiddleColumnStartX, MainStartY);
Tags->MoveTo(RightColumnStartX, MainStartY); Tags->MoveTo(RightColumnStartX, MainStartY);
FParserDialog->MoveTo((COLS-FParserDialogWidth)/2, (MainHeight-FParserDialogHeight)/2+MainStartY); FParserDialog->MoveTo(x_offset+(width-FParserDialogWidth)/2, (MainHeight-FParserDialogHeight)/2+MainStartY);
FParser->MoveTo((COLS-FParserWidth)/2, (MainHeight-FParserHeight)/2+MainStartY); FParser->MoveTo(x_offset+(width-FParserWidth)/2, (MainHeight-FParserHeight)/2+MainStartY);
FParserLegend->MoveTo((COLS-FParserWidth)/2+FParserWidthOne, (MainHeight-FParserHeight)/2+MainStartY); FParserLegend->MoveTo(x_offset+(width-FParserWidth)/2+FParserWidthOne, (MainHeight-FParserHeight)/2+MainStartY);
FParserPreview->MoveTo((COLS-FParserWidth)/2+FParserWidthOne, (MainHeight-FParserHeight)/2+MainStartY); FParserPreview->MoveTo(x_offset+(width-FParserWidth)/2+FParserWidthOne, (MainHeight-FParserHeight)/2+MainStartY);
if (MainHeight < 5 && (w == FParserDialog || w == FParser || w == FParserHelper)) // screen too low if (MainHeight < 5 && (w == FParserDialog || w == FParser || w == FParserHelper)) // screen too low
w = TagTypes; // fall back to main columns w = TagTypes; // fall back to main columns
@@ -186,6 +190,7 @@ std::basic_string<my_char_t> TagEditor::Title()
void TagEditor::SwitchTo() void TagEditor::SwitchTo()
{ {
using Global::myScreen; using Global::myScreen;
using Global::myLockedScreen;
if (myScreen == this) if (myScreen == this)
return; return;
@@ -193,7 +198,10 @@ void TagEditor::SwitchTo()
if (!isInitialized) if (!isInitialized)
Init(); Init();
if (hasToBeResized) if (myLockedScreen)
UpdateInactiveScreen(this);
if (hasToBeResized || myLockedScreen)
Resize(); Resize();
if (myScreen != this && myScreen->isTabbable()) if (myScreen != this && myScreen->isTabbable())
@@ -800,7 +808,7 @@ List *TagEditor::GetList()
return 0; return 0;
} }
void TagEditor::NextColumn() bool TagEditor::NextColumn()
{ {
if (w == LeftColumn) if (w == LeftColumn)
{ {
@@ -808,6 +816,7 @@ void TagEditor::NextColumn()
w->Refresh(); w->Refresh();
w = TagTypes; w = TagTypes;
TagTypes->HighlightColor(Config.active_column_color); TagTypes->HighlightColor(Config.active_column_color);
return true;
} }
else if (w == TagTypes && TagTypes->Choice() < 12 && !Tags->ReallyEmpty()) else if (w == TagTypes && TagTypes->Choice() < 12 && !Tags->ReallyEmpty())
{ {
@@ -815,6 +824,7 @@ void TagEditor::NextColumn()
w->Refresh(); w->Refresh();
w = Tags; w = Tags;
Tags->HighlightColor(Config.active_column_color); Tags->HighlightColor(Config.active_column_color);
return true;
} }
else if (w == FParser) else if (w == FParser)
{ {
@@ -823,10 +833,12 @@ void TagEditor::NextColumn()
w = FParserHelper; w = FParserHelper;
FParserHelper->SetBorder(Config.active_window_border); FParserHelper->SetBorder(Config.active_window_border);
FParserHelper->Display(); FParserHelper->Display();
return true;
} }
return false;
} }
void TagEditor::PrevColumn() bool TagEditor::PrevColumn()
{ {
if (w == Tags) if (w == Tags)
{ {
@@ -834,6 +846,7 @@ void TagEditor::PrevColumn()
w->Refresh(); w->Refresh();
w = TagTypes; w = TagTypes;
TagTypes->HighlightColor(Config.active_column_color); TagTypes->HighlightColor(Config.active_column_color);
return true;
} }
else if (w == TagTypes) else if (w == TagTypes)
{ {
@@ -841,6 +854,7 @@ void TagEditor::PrevColumn()
w->Refresh(); w->Refresh();
w = LeftColumn; w = LeftColumn;
LeftColumn->HighlightColor(Config.active_column_color); LeftColumn->HighlightColor(Config.active_column_color);
return true;
} }
else if (w == FParserHelper) else if (w == FParserHelper)
{ {
@@ -849,7 +863,9 @@ void TagEditor::PrevColumn()
w = FParser; w = FParser;
FParser->SetBorder(Config.active_window_border); FParser->SetBorder(Config.active_window_border);
FParser->Display(); FParser->Display();
return true;
} }
return false;
} }
void TagEditor::LocateSong(const MPD::Song &s) void TagEditor::LocateSong(const MPD::Song &s)

View File

@@ -66,8 +66,10 @@ class TagEditor : public Screen<Window>
virtual List *GetList(); virtual List *GetList();
void NextColumn(); virtual bool isMergable() { return true; }
void PrevColumn();
bool NextColumn();
bool PrevColumn();
void LocateSong(const MPD::Song &s); void LocateSong(const MPD::Song &s);
@@ -85,9 +87,10 @@ class TagEditor : public Screen<Window>
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return true; }
private: private:
void SetDimensions(); void SetDimensions(size_t, size_t);
MPD::SongList EditedSongs; MPD::SongList EditedSongs;
Menu<std::string> *FParserDialog; Menu<std::string> *FParserDialog;
@@ -118,6 +121,7 @@ class TagEditor : public Screen<Window>
static std::list<std::string> Patterns; static std::list<std::string> Patterns;
static size_t MiddleColumnWidth; static size_t MiddleColumnWidth;
static size_t LeftColumnStartX;
static size_t LeftColumnWidth; static size_t LeftColumnWidth;
static size_t MiddleColumnStartX; static size_t MiddleColumnStartX;
static size_t RightColumnWidth; static size_t RightColumnWidth;

View File

@@ -54,23 +54,32 @@ void TinyTagEditor::Init()
void TinyTagEditor::Resize() void TinyTagEditor::Resize()
{ {
w->Resize(COLS, MainHeight); size_t x_offset, width;
w->MoveTo(0, MainStartY); GetWindowResizeParams(x_offset, width);
w->Resize(width, MainHeight);
w->MoveTo(x_offset, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
void TinyTagEditor::SwitchTo() void TinyTagEditor::SwitchTo()
{ {
using Global::myScreen;
using Global::myLockedScreen;
if (itsEdited.isStream()) if (itsEdited.isStream())
{ {
ShowMessage("Streams cannot be edited!"); ShowMessage("Streams cannot be edited!");
} }
else if (GetTags()) else if (GetTags())
{ {
if (hasToBeResized) if (myLockedScreen)
UpdateInactiveScreen(this);
if (hasToBeResized || myLockedScreen)
Resize(); Resize();
myOldScreen = Global::myScreen;
Global::myScreen = this; myOldScreen = myScreen;
myScreen = this;
Global::RedrawHeader = 1; Global::RedrawHeader = 1;
} }
else else

View File

@@ -48,10 +48,13 @@ class TinyTagEditor : public Screen< Menu<Buffer> >
virtual List *GetList() { return 0; } virtual List *GetList() { return 0; }
virtual bool isMergable() { return true; }
bool SetEdited(MPD::Song *); bool SetEdited(MPD::Song *);
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return true; }
private: private:
bool GetTags(); bool GetTags();

View File

@@ -61,6 +61,7 @@ void Visualizer::Init()
void Visualizer::SwitchTo() void Visualizer::SwitchTo()
{ {
using Global::myScreen; using Global::myScreen;
using Global::myLockedScreen;
if (myScreen == this) if (myScreen == this)
return; return;
@@ -68,7 +69,10 @@ void Visualizer::SwitchTo()
if (!isInitialized) if (!isInitialized)
Init(); Init();
if (hasToBeResized) if (myLockedScreen)
UpdateInactiveScreen(this);
if (hasToBeResized || myLockedScreen)
Resize(); Resize();
if (myScreen != this && myScreen->isTabbable()) if (myScreen != this && myScreen->isTabbable())
@@ -88,8 +92,10 @@ void Visualizer::SwitchTo()
void Visualizer::Resize() void Visualizer::Resize()
{ {
w->Resize(COLS, MainHeight); size_t x_offset, width;
w->MoveTo(0, MainStartY); GetWindowResizeParams(x_offset, width);
w->Resize(width, MainHeight);
w->MoveTo(x_offset, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
@@ -154,11 +160,12 @@ void Visualizer::SpacePressed()
void Visualizer::DrawSoundWave(int16_t *buf, ssize_t samples, size_t y_offset, size_t height) void Visualizer::DrawSoundWave(int16_t *buf, ssize_t samples, size_t y_offset, size_t height)
{ {
const int samples_per_col = samples/COLS; const int samples_per_col = samples/w->GetWidth();
const int half_height = height/2; const int half_height = height/2;
*w << fmtAltCharset; *w << fmtAltCharset;
double prev_point_pos = 0; double prev_point_pos = 0;
for (int i = 0; i < COLS; ++i) const size_t win_width = w->GetWidth();
for (size_t i = 0; i < win_width; ++i)
{ {
double point_pos = 0; double point_pos = 0;
for (int j = 0; j < samples_per_col; ++j) for (int j = 0; j < samples_per_col; ++j)
@@ -198,8 +205,9 @@ void Visualizer::DrawFrequencySpectrum(int16_t *buf, ssize_t samples, size_t y_o
for (unsigned i = 0; i < itsFFTResults; ++i) for (unsigned i = 0; i < itsFFTResults; ++i)
itsFreqsMagnitude[i] = sqrt(itsOutput[i][0]*itsOutput[i][0] + itsOutput[i][1]*itsOutput[i][1])/1e5*height/5; itsFreqsMagnitude[i] = sqrt(itsOutput[i][0]*itsOutput[i][0] + itsOutput[i][1]*itsOutput[i][1])/1e5*height/5;
const int freqs_per_col = itsFFTResults/COLS /* cut bandwidth a little to achieve better look */ * 4/5; const size_t win_width = w->GetWidth();
for (int i = 0; i < COLS; ++i) const int freqs_per_col = itsFFTResults/win_width /* cut bandwidth a little to achieve better look */ * 7/10;
for (size_t i = 0; i < win_width; ++i)
{ {
size_t bar_height = 0; size_t bar_height = 0;
for (int j = 0; j < freqs_per_col; ++j) for (int j = 0; j < freqs_per_col; ++j)

View File

@@ -54,6 +54,8 @@ class Visualizer : public Screen<Window>
virtual bool allowsSelection() { return false; } virtual bool allowsSelection() { return false; }
virtual bool isMergable() { return true; }
void SetFD(); void SetFD();
void ResetFD(); void ResetFD();
void FindOutputID(); void FindOutputID();
@@ -62,6 +64,7 @@ class Visualizer : public Screen<Window>
protected: protected:
virtual void Init(); virtual void Init();
virtual bool isLockable() { return true; }
private: private:
void DrawSoundWave(int16_t *, ssize_t, size_t, size_t); void DrawSoundWave(int16_t *, ssize_t, size_t, size_t);