new feature: alternative user interface

This commit is contained in:
Andrzej Rybczak
2009-08-12 02:08:13 +02:00
parent dbca4a80ee
commit 101f01941d
33 changed files with 428 additions and 127 deletions

View File

@@ -89,6 +89,26 @@
# #
#selected_item_suffix = "$9" #selected_item_suffix = "$9"
# #
##
## Note: Below variables are for alternative version of user's interface.
## Their syntax supports all tags and colors listed above plus some extra
## markers used for text attributes. They are followed by character '$'.
## After that you can put:
##
## - b - bold text
## - r - reverse colors
## - a - use alternative character set
##
## If you don't want to use an attribute anymore, just put it again, but
## this time insert character '/' between '$' and attribute character,
## e.g. {$b%t$/b}|{$r%f$/r} will display bolded title tag or filename
## with reversed colors.
##
#
#alternative_header_first_line_format = "$b$1$aqqu$/a$9 {%t}|{%f} $1$atqq$/a$9$/b"
#
#alternative_header_second_line_format = "{$4$b%a$/b$9}{ - $7%b$9}{ ($4%y$9)}"
#
## colors are not supported for below veriables ## colors are not supported for below veriables
# #
#song_status_format = "{(%l) }{%a - }{%t}|{%f}" #song_status_format = "{(%l) }{%a - }{%t}|{%f}"
@@ -139,6 +159,8 @@
# #
#default_place_to_search_in = "database" (database/playlist) #default_place_to_search_in = "database" (database/playlist)
# #
#user_interface = "classic" (classic/alternative)
#
#media_library_left_column = "a" (possible values: a,y,g,c,p, legend above) #media_library_left_column = "a" (possible values: a,y,g,c,p, legend above)
# #
#default_find_mode = "wrapped" (wrapped/normal) #default_find_mode = "wrapped" (wrapped/normal)

View File

@@ -111,6 +111,12 @@ Prefix for selected items.
.B selected_item_suffix = TEXT .B selected_item_suffix = TEXT
Suffix for selected items. Suffix for selected items.
.TP .TP
.B alternative_header_first_line_format = TEXT
Now playing song format for the first line in alternative user interface header window.
.TP
.B alternative_header_second_line_format = TEXT
Now playing song format for the second line in alternative user interface header window.
.TP
.B color1 = COLOR .B color1 = COLOR
One of colors used in Song info, Tiny tag editor and Search engine. One of colors used in Song info, Tiny tag editor and Search engine.
.TP .TP
@@ -211,6 +217,9 @@ Type of currently used regular expressions.
Number of lyrics database in use. Currently supported DBs are: Number of lyrics database in use. Currently supported DBs are:
1 - lyricsplugin.com 1 - lyricsplugin.com
.TP .TP
.B user_iterface = classic/alternative
Default user interface used by ncmpcpp at start.
.TP
.B media_library_left_column = a/y/g/c/p .B media_library_left_column = a/y/g/c/p
Default tag type for left column in media library. Legend for possible letters is in SONG FORMAT section. Default tag type for left column in media library. Legend for possible letters is in SONG FORMAT section.
.TP .TP

View File

@@ -65,6 +65,7 @@ void Browser::Init()
void Browser::Resize() void Browser::Resize()
{ {
w->Resize(COLS, MainHeight); w->Resize(COLS, MainHeight);
w->MoveTo(0, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
@@ -84,10 +85,10 @@ void Browser::SwitchTo()
RedrawHeader = 1; RedrawHeader = 1;
} }
std::string Browser::Title() std::basic_string<my_char_t> Browser::Title()
{ {
std::string result = "Browse: "; std::basic_string<my_char_t> result = U("Browse: ");
result += TO_STRING(Scroller(itsBrowsedDir, COLS-result.length()-VolumeState.length(), itsScrollBeginning)); result += Scroller(itsBrowsedDir, COLS-result.length()-(Config.new_design ? 2 : VolumeState.length()), itsScrollBeginning);
return result; return result;
} }

View File

@@ -32,7 +32,7 @@ class Browser : public Screen< Menu<MPD::Item> >
virtual void Resize(); virtual void Resize();
virtual void SwitchTo(); virtual void SwitchTo();
virtual std::string Title(); virtual std::basic_string<my_char_t> Title();
virtual void EnterPressed(); virtual void EnterPressed();
virtual void SpacePressed(); virtual void SpacePressed();

View File

@@ -51,7 +51,7 @@ void Clock::Init()
{ {
Width = Config.clock_display_seconds ? 60 : 40; Width = Config.clock_display_seconds ? 60 : 40;
w = new Window((COLS-Width)/2, (LINES-Height)/2, 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));
w->SetTimeout(ncmpcpp_window_timeout); w->SetTimeout(ncmpcpp_window_timeout);
isInitialized = 1; isInitialized = 1;
} }
@@ -60,7 +60,7 @@ void Clock::Resize()
{ {
if (Width <= size_t(COLS) && Height <= MainHeight) if (Width <= size_t(COLS) && Height <= MainHeight)
{ {
w->MoveTo((COLS-Width)/2, (LINES-Height)/2); w->MoveTo((COLS-Width)/2, (MainHeight-Height)/2+MainStartY);
if (myScreen == this) if (myScreen == this)
{ {
if (myPlaylist->hasToBeResized) if (myPlaylist->hasToBeResized)
@@ -96,9 +96,9 @@ void Clock::SwitchTo()
w->Display(); w->Display();
} }
std::string Clock::Title() std::basic_string<my_char_t> Clock::Title()
{ {
return "Clock"; return U("Clock");
} }
void Clock::Update() void Clock::Update()

View File

@@ -36,7 +36,7 @@ class Clock : public Screen<Window>
virtual void Resize(); virtual void Resize();
virtual void SwitchTo(); virtual void SwitchTo();
virtual std::string Title(); virtual std::basic_string<my_char_t> Title();
virtual void Update(); virtual void Update();
virtual void Scroll(Where, const int *) { } virtual void Scroll(Where, const int *) { }

View File

@@ -41,6 +41,7 @@ void Help::Init()
void Help::Resize() void Help::Resize()
{ {
w->Resize(COLS, MainHeight); w->Resize(COLS, MainHeight);
w->MoveTo(0, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
@@ -60,9 +61,9 @@ void Help::SwitchTo()
} }
std::string Help::Title() std::basic_string<my_char_t> Help::Title()
{ {
return "Help"; return U("Help");
} }
std::string Help::DisplayKeys(int *key, int size) std::string Help::DisplayKeys(int *key, int size)
@@ -185,6 +186,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.ToggleDisplayMode) << "Toggle display mode\n"; *w << DisplayKeys(Key.ToggleDisplayMode) << "Toggle display mode\n";
*w << DisplayKeys(Key.ToggleInterface) << "Toggle user interface\n";
*w << DisplayKeys(Key.GoToPosition) << "Go to given position in current song (in % by default)\n"; *w << DisplayKeys(Key.GoToPosition) << "Go to given position in current song (in % by default)\n";
*w << DisplayKeys(Key.SongInfo) << "Show song's info\n"; *w << DisplayKeys(Key.SongInfo) << "Show song's info\n";
# ifdef HAVE_CURL_CURL_H # ifdef HAVE_CURL_CURL_H

View File

@@ -30,7 +30,7 @@ class Help : public Screen<Scrollpad>
virtual void Resize(); virtual void Resize();
virtual void SwitchTo(); virtual void SwitchTo();
virtual std::string Title(); virtual std::basic_string<my_char_t> Title();
virtual void EnterPressed() { } virtual void EnterPressed() { }
virtual void SpacePressed() { } virtual void SpacePressed() { }

View File

@@ -321,26 +321,24 @@ Buffer ShowTag(const std::string &tag)
return result; return result;
} }
#ifdef _UTF8
std::basic_string<my_char_t> Scroller(const std::string &str, size_t width, size_t &pos) std::basic_string<my_char_t> Scroller(const std::string &str, size_t width, size_t &pos)
{ {
std::basic_string<my_char_t> s = TO_WSTRING(str); return Scroller(TO_WSTRING(str), width, pos);
}
#endif // _UTF8
std::basic_string<my_char_t> Scroller(const std::basic_string<my_char_t> &str, size_t width, size_t &pos)
{
std::basic_string<my_char_t> s(str);
if (!Config.header_text_scrolling) if (!Config.header_text_scrolling)
return s; return s;
std::basic_string<my_char_t> result; std::basic_string<my_char_t> result;
size_t len; size_t len = Window::Length(s);
# ifdef _UTF8
len = Window::Length(s);
# else
len = s.length();
# endif
if (len > width) if (len > width)
{ {
# ifdef _UTF8 s += U(" ** ");
s += L" ** ";
# else
s += " ** ";
# endif
len = 0; len = 0;
std::basic_string<my_char_t>::const_iterator b = s.begin(), e = s.end(); std::basic_string<my_char_t>::const_iterator b = s.begin(), e = s.end();
for (std::basic_string<my_char_t>::const_iterator it = b+pos; it < e && len < width; ++it) for (std::basic_string<my_char_t>::const_iterator it = b+pos; it < e && len < width; ++it)

View File

@@ -52,6 +52,49 @@ template <typename A, typename B> std::string StringPairToString(const std::pair
return pair.first; return pair.first;
} }
template <typename C> void String2Buffer(const std::basic_string<C> &s, basic_buffer<C> &buf)
{
for (typename std::basic_string<C>::const_iterator it = s.begin(); it != s.end(); ++it)
{
if (*it != '$')
buf << *it;
else if (isdigit(*++it))
buf << Color(*it-'0');
else
{
switch (*it)
{
case '$':
buf << *it;
break;
case 'b':
buf << fmtBold;
break;
case 'a':
buf << fmtAltCharset;
break;
case 'r':
buf << fmtReverse;
break;
case '/':
switch (*++it)
{
case 'b':
buf << fmtBoldEnd;
break;
case 'a':
buf << fmtAltCharsetEnd;
break;
case 'r':
buf << fmtReverseEnd;
break;
}
break;
}
}
}
}
inline bool Keypressed(int in, const int *key) inline bool Keypressed(int in, const int *key)
{ {
return in == key[0] || in == key[1]; return in == key[0] || in == key[1];
@@ -72,7 +115,10 @@ std::string ExtractTopDirectory(const std::string &);
Buffer ShowTag(const std::string &); Buffer ShowTag(const std::string &);
#ifdef _UTF8
std::basic_string<my_char_t> Scroller(const std::string &, size_t, size_t &); std::basic_string<my_char_t> Scroller(const std::string &, size_t, size_t &);
#endif // _UTF8
std::basic_string<my_char_t> Scroller(const std::basic_string<my_char_t> &, size_t, size_t &);
#ifdef HAVE_CURL_CURL_H #ifdef HAVE_CURL_CURL_H
size_t write_data(char *, size_t, size_t, void *); size_t write_data(char *, size_t, size_t, void *);

View File

@@ -65,12 +65,13 @@ void Info::Init()
void Info::Resize() void Info::Resize()
{ {
w->Resize(COLS, MainHeight); w->Resize(COLS, MainHeight);
w->MoveTo(0, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
std::string Info::Title() std::basic_string<my_char_t> Info::Title()
{ {
return itsTitle; return TO_WSTRING(itsTitle);
} }
#if defined(HAVE_CURL_CURL_H) && defined(HAVE_PTHREAD_H) #if defined(HAVE_CURL_CURL_H) && defined(HAVE_PTHREAD_H)

View File

@@ -31,7 +31,7 @@ class Info : public Screen<Scrollpad>
virtual void SwitchTo() { } virtual void SwitchTo() { }
virtual void Resize(); virtual void Resize();
virtual std::string Title(); virtual std::basic_string<my_char_t> Title();
# if defined(HAVE_CURL_CURL_H) && defined(HAVE_PTHREAD_H) # if defined(HAVE_CURL_CURL_H) && defined(HAVE_PTHREAD_H)
virtual void Update(); virtual void Update();

View File

@@ -75,6 +75,7 @@ void Lyrics::Init()
void Lyrics::Resize() void Lyrics::Resize()
{ {
w->Resize(COLS, MainHeight); w->Resize(COLS, MainHeight);
w->MoveTo(0, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
@@ -187,10 +188,10 @@ void Lyrics::SwitchTo()
} }
} }
std::string Lyrics::Title() std::basic_string<my_char_t> Lyrics::Title()
{ {
std::string result = "Lyrics: "; std::basic_string<my_char_t> result = U("Lyrics: ");
result += TO_STRING(Scroller(itsSong.toString("%a - %t"), COLS-result.length()-VolumeState.length(), itsScrollBegin)); result += Scroller(itsSong.toString("%a - %t"), COLS-result.length()-(Config.new_design ? 2 : VolumeState.length()), itsScrollBegin);
return result; return result;
} }

View File

@@ -46,7 +46,7 @@ class Lyrics : public Screen<Scrollpad>
virtual void Resize(); virtual void Resize();
virtual void SwitchTo(); virtual void SwitchTo();
virtual std::string Title(); virtual std::basic_string<my_char_t> Title();
virtual void Update(); virtual void Update();

View File

@@ -99,6 +99,7 @@ void MediaLibrary::Resize()
Albums->Resize(itsMiddleColWidth, MainHeight); Albums->Resize(itsMiddleColWidth, MainHeight);
Songs->Resize(itsRightColWidth, MainHeight); Songs->Resize(itsRightColWidth, MainHeight);
Artists->MoveTo(0, MainStartY);
Albums->MoveTo(itsMiddleColStartX, MainStartY); Albums->MoveTo(itsMiddleColStartX, MainStartY);
Songs->MoveTo(itsRightColStartX, MainStartY); Songs->MoveTo(itsRightColStartX, MainStartY);
@@ -153,9 +154,9 @@ void MediaLibrary::SwitchTo()
UpdateSongList(Songs); UpdateSongList(Songs);
} }
std::string MediaLibrary::Title() std::basic_string<my_char_t> MediaLibrary::Title()
{ {
return "Media library"; return U("Media library");
} }
void MediaLibrary::Update() void MediaLibrary::Update()

View File

@@ -40,7 +40,7 @@ class MediaLibrary : public Screen<Window>
virtual void SwitchTo(); virtual void SwitchTo();
virtual void Resize(); virtual void Resize();
virtual std::string Title(); virtual std::basic_string<my_char_t> Title();
virtual void Refresh(); virtual void Refresh();
virtual void Update(); virtual void Update();

View File

@@ -115,26 +115,24 @@ int main(int argc, char *argv[])
InitScreen("ncmpc++ ver. "VERSION, Config.colors_enabled); InitScreen("ncmpc++ ver. "VERSION, Config.colors_enabled);
MainStartY = 2; bool real_header_visibility = Config.header_visibility;
MainHeight = LINES-4; bool real_statusbar_visibility = Config.statusbar_visibility;
if (!Config.header_visibility) if (Config.new_design)
{ {
MainStartY -= 2; Config.header_visibility = 1;
MainHeight += 2; Config.statusbar_visibility = 0;
} }
if (!Config.statusbar_visibility)
MainHeight++; size_t header_height, footer_start_y, footer_height;
SetWindowsDimensions(header_height, footer_start_y, footer_height);
if (Config.header_visibility) if (Config.header_visibility)
{ {
wHeader = new Window(0, 0, COLS, 1, "", Config.header_color, brNone); wHeader = new Window(0, 0, COLS, header_height, "", Config.header_color, brNone);
wHeader->Display(); wHeader->Display();
} }
size_t footer_start_y = LINES-(Config.statusbar_visibility ? 2 : 1);
size_t footer_height = Config.statusbar_visibility ? 2 : 1;
wFooter = new Window(0, footer_start_y, COLS, footer_height, "", Config.statusbar_color, brNone); wFooter = new Window(0, footer_start_y, COLS, footer_height, "", Config.statusbar_color, brNone);
wFooter->SetTimeout(ncmpcpp_window_timeout); wFooter->SetTimeout(ncmpcpp_window_timeout);
wFooter->SetGetStringHelper(StatusbarGetStringHelper); wFooter->SetGetStringHelper(StatusbarGetStringHelper);
@@ -150,6 +148,7 @@ int main(int argc, char *argv[])
int input; int input;
bool main_exit = 0; bool main_exit = 0;
bool design_changed = 0;
bool title_allowed = !Config.display_screens_numbers_on_start; bool title_allowed = !Config.display_screens_numbers_on_start;
std::string screen_title; std::string screen_title;
@@ -201,7 +200,19 @@ int main(int argc, char *argv[])
{ {
if (title_allowed) if (title_allowed)
{ {
*wHeader << XY(0, 0) << wclrtoeol << fmtBold << myScreen->Title() << fmtBoldEnd; if (Config.new_design)
{
std::basic_string<my_char_t> title = myScreen->Title();
*wHeader << XY(0, 3) << wclrtoeol;
*wHeader << fmtBold << clBlack;
mvwhline(wHeader->Raw(), 2, 0, 0, COLS);
mvwhline(wHeader->Raw(), 4, 0, 0, COLS);
*wHeader << XY((COLS-Window::Length(title))/2, 3);
*wHeader << Config.statusbar_color << title << clEnd;
*wHeader << clEnd << fmtBoldEnd;
}
else
*wHeader << XY(0, 0) << wclrtoeol << fmtBold << myScreen->Title() << fmtBoldEnd;
} }
else else
{ {
@@ -286,6 +297,24 @@ int main(int argc, char *argv[])
// key mapping beginning // key mapping beginning
if (Keypressed(input, Key.ToggleInterface))
{
Config.new_design = !Config.new_design;
if (Config.new_design)
{
Config.header_visibility = 1;
Config.statusbar_visibility = 0;
}
else
{
Config.header_visibility = real_header_visibility;
Config.statusbar_visibility = real_statusbar_visibility;
}
SetWindowsDimensions(header_height, footer_start_y, footer_height);
UnlockProgressbar();
UnlockStatusbar();
design_changed = 1;
}
if (Keypressed(input, Key.Up)) if (Keypressed(input, Key.Up))
{ {
myScreen->Scroll(wUp, Key.Up); myScreen->Scroll(wUp, Key.Up);
@@ -328,9 +357,9 @@ int main(int argc, char *argv[])
UpdateStatusImmediately = 1; UpdateStatusImmediately = 1;
} }
else if (mouse_event.bstate & BUTTON1_PRESSED else if (mouse_event.bstate & BUTTON1_PRESSED
&& Config.statusbar_visibility && (Config.statusbar_visibility || Config.new_design)
&& Mpd.GetState() > psStop && Mpd.GetState() > psStop
&& mouse_event.y == LINES-1 && mouse_event.x < 9 && mouse_event.y == (Config.new_design ? 1 : LINES-1) && mouse_event.x < 9
) // playing/paused ) // playing/paused
{ {
Mpd.Pause(); Mpd.Pause();
@@ -349,7 +378,7 @@ int main(int argc, char *argv[])
else else
myScreen->MouseButtonPressed(mouse_event); myScreen->MouseButtonPressed(mouse_event);
} }
else if (input == KEY_RESIZE) else if (input == KEY_RESIZE || design_changed)
{ {
# ifdef USE_PDCURSES # ifdef USE_PDCURSES
resize_term(0, 0); resize_term(0, 0);
@@ -364,7 +393,7 @@ int main(int argc, char *argv[])
return 1; return 1;
} }
MainHeight = LINES-4; MainHeight = LINES-(Config.new_design ? 7 : 4);
if (!Config.header_visibility) if (!Config.header_visibility)
MainHeight += 2; MainHeight += 2;
@@ -392,19 +421,30 @@ int main(int argc, char *argv[])
myScreen->Resize(); myScreen->Resize();
if (Config.header_visibility) if (Config.header_visibility)
wHeader->Resize(COLS, wHeader->GetHeight()); wHeader->Resize(COLS, header_height);
footer_start_y = LINES-(Config.statusbar_visibility ? 2 : 1); footer_start_y = LINES-(Config.statusbar_visibility ? 2 : 1);
wFooter->MoveTo(0, footer_start_y); wFooter->MoveTo(0, footer_start_y);
wFooter->Resize(COLS, wFooter->GetHeight()); wFooter->Resize(COLS, Config.statusbar_visibility ? 2 : 1);
myScreen->Refresh(); myScreen->Refresh();
RedrawStatusbar = 1; RedrawStatusbar = 1;
StatusChanges changes; StatusChanges changes;
if (Mpd.GetState() < psPlay) if (Mpd.GetState() < psPlay || design_changed)
{
changes.PlayerState = 1; changes.PlayerState = 1;
if (design_changed)
changes.Volume = 1;
}
changes.StatusFlags = 1; // force status update changes.StatusFlags = 1; // force status update
NcmpcppStatusChanged(&Mpd, changes, NULL); NcmpcppStatusChanged(&Mpd, changes, 0);
if (design_changed)
{
RedrawStatusbar = 1;
NcmpcppStatusChanged(&Mpd, StatusChanges(), 0);
design_changed = 0;
ShowMessage("User interface: %s", Config.new_design ? "Alternative" : "Classic");
}
} }
else if (Keypressed(input, Key.GoToParentDir)) else if (Keypressed(input, Key.GoToParentDir))
{ {
@@ -1071,9 +1111,21 @@ int main(int argc, char *argv[])
songpos = 0; songpos = 0;
} }
std::string tracklength;
*wFooter << fmtBold; *wFooter << fmtBold;
std::string tracklength = "[" + Song::ShowTime(songpos) + "/" + s->GetLength() + "]"; if (Config.new_design)
*wFooter << XY(wFooter->GetWidth()-tracklength.length(), 1) << tracklength; {
tracklength = Song::ShowTime(songpos);
tracklength += "/";
tracklength += s->GetLength();
*wHeader << XY(0, 0) << tracklength << " ";
wHeader->Refresh();
}
else
{
tracklength = "[" + Song::ShowTime(songpos) + "/" + s->GetLength() + "]";
*wFooter << XY(wFooter->GetWidth()-tracklength.length(), 1) << tracklength;
}
double progressbar_size = songpos/double(s->GetTotalLength()); double progressbar_size = songpos/double(s->GetTotalLength());
int howlong = wFooter->GetWidth()*progressbar_size; int howlong = wFooter->GetWidth()*progressbar_size;

View File

@@ -61,12 +61,13 @@ void Outputs::SwitchTo()
void Outputs::Resize() void Outputs::Resize()
{ {
w->Resize(COLS, MainHeight); w->Resize(COLS, MainHeight);
w->MoveTo(0, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
std::string Outputs::Title() std::basic_string<my_char_t> Outputs::Title()
{ {
return "Outputs"; return U("Outputs");
} }
void Outputs::EnterPressed() void Outputs::EnterPressed()

View File

@@ -37,7 +37,7 @@ class Outputs : public Screen< Menu<MPD::Output> >
virtual void SwitchTo(); virtual void SwitchTo();
virtual void Resize(); virtual void Resize();
virtual std::string Title(); virtual std::basic_string<my_char_t> Title();
virtual void EnterPressed(); virtual void EnterPressed();
virtual void SpacePressed() { } virtual void SpacePressed() { }

View File

@@ -105,6 +105,7 @@ void Playlist::SwitchTo()
void Playlist::Resize() void Playlist::Resize()
{ {
w->Resize(COLS, MainHeight); w->Resize(COLS, MainHeight);
w->MoveTo(0, MainStartY);
w->SetTitle(Config.columns_in_playlist ? Display::Columns() : ""); w->SetTitle(Config.columns_in_playlist ? Display::Columns() : "");
SortDialogHeight = std::min(int(MainHeight-2), 18); SortDialogHeight = std::min(int(MainHeight-2), 18);
if (MainHeight > 6) if (MainHeight > 6)
@@ -113,12 +114,12 @@ void Playlist::Resize()
hasToBeResized = 0; hasToBeResized = 0;
} }
std::string Playlist::Title() std::basic_string<my_char_t> Playlist::Title()
{ {
std::string result = "Playlist "; std::basic_string<my_char_t> result = U("Playlist ");
if (ReloadTotalLength || ReloadRemaining) if (ReloadTotalLength || ReloadRemaining)
itsBufferedStats = TotalLength(); itsBufferedStats = TotalLength();
result += TO_STRING(Scroller(itsBufferedStats, w->GetWidth()-result.length()-VolumeState.length(), itsScrollBegin)); result += Scroller(itsBufferedStats, w->GetWidth()-result.length()-(Config.new_design ? 2 : VolumeState.length()), itsScrollBegin);
return result; return result;
} }

View File

@@ -36,7 +36,7 @@ class Playlist : public Screen< Menu<MPD::Song> >
virtual void SwitchTo(); virtual void SwitchTo();
virtual void Resize(); virtual void Resize();
virtual std::string Title(); virtual std::basic_string<my_char_t> Title();
virtual void EnterPressed(); virtual void EnterPressed();
virtual void SpacePressed(); virtual void SpacePressed();

View File

@@ -75,14 +75,15 @@ void PlaylistEditor::Resize()
Playlists->Resize(LeftColumnWidth, MainHeight); Playlists->Resize(LeftColumnWidth, MainHeight);
Content->Resize(RightColumnWidth, MainHeight); Content->Resize(RightColumnWidth, MainHeight);
Playlists->MoveTo(0, MainStartY);
Content->MoveTo(RightColumnStartX, MainStartY); Content->MoveTo(RightColumnStartX, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
std::string PlaylistEditor::Title() std::basic_string<my_char_t> PlaylistEditor::Title()
{ {
return "Playlist editor"; return U("Playlist editor");
} }
void PlaylistEditor::Refresh() void PlaylistEditor::Refresh()

View File

@@ -29,7 +29,7 @@ class PlaylistEditor : public Screen<Window>
virtual void SwitchTo(); virtual void SwitchTo();
virtual void Resize(); virtual void Resize();
virtual std::string Title(); virtual std::basic_string<my_char_t> Title();
virtual void Refresh(); virtual void Refresh();
virtual void Update(); virtual void Update();

View File

@@ -39,7 +39,7 @@ class BasicScreen
virtual void SwitchTo() = 0; virtual void SwitchTo() = 0;
virtual void Resize() = 0; virtual void Resize() = 0;
virtual std::string Title() = 0; virtual std::basic_string<my_char_t> Title() = 0;
virtual void Update() { } virtual void Update() { }
virtual void Refresh() = 0; virtual void Refresh() = 0;

View File

@@ -57,6 +57,7 @@ void SearchEngine::Init()
void SearchEngine::Resize() void SearchEngine::Resize()
{ {
w->Resize(COLS, MainHeight); w->Resize(COLS, MainHeight);
w->MoveTo(0, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
@@ -83,9 +84,9 @@ void SearchEngine::SwitchTo()
} }
} }
std::string SearchEngine::Title() std::basic_string<my_char_t> SearchEngine::Title()
{ {
return "Search engine"; return U("Search engine");
} }
void SearchEngine::EnterPressed() void SearchEngine::EnterPressed()

View File

@@ -43,7 +43,7 @@ class SearchEngine : public Screen< Menu< std::pair<Buffer *, MPD::Song *> > >
virtual void Resize(); virtual void Resize();
virtual void SwitchTo(); virtual void SwitchTo();
virtual std::string Title(); virtual std::basic_string<my_char_t> Title();
virtual void EnterPressed(); virtual void EnterPressed();
virtual void SpacePressed(); virtual void SpacePressed();

View File

@@ -25,6 +25,7 @@
#endif // WIN32 #endif // WIN32
#include <fstream> #include <fstream>
#include "global.h"
#include "helpers.h" #include "helpers.h"
#include "lyrics.h" #include "lyrics.h"
#include "settings.h" #include "settings.h"
@@ -60,17 +61,6 @@ namespace
key[1] = !two.empty() && two[0] == '\'' ? two[1] : (atoi(two.c_str()) == 0 ? null_key : atoi(two.c_str())); key[1] = !two.empty() && two[0] == '\'' ? two[1] : (atoi(two.c_str()) == 0 ? null_key : atoi(two.c_str()));
} }
void String2Buffer(const std::string &s, Buffer &buf)
{
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it)
{
if (*it != '$')
buf << *it;
else
buf << Color(*++it-'0');
}
}
Border IntoBorder(const std::string &color) Border IntoBorder(const std::string &color)
{ {
return Border(IntoColor(color)); return Border(IntoColor(color));
@@ -86,6 +76,24 @@ void CreateConfigDir()
); );
} }
void SetWindowsDimensions(size_t &header_height, size_t &footer_start_y, size_t &footer_height)
{
Global::MainStartY = Config.new_design ? 5 : 2;
Global::MainHeight = LINES-(Config.new_design ? 7 : 4);
if (!Config.header_visibility)
{
Global::MainStartY -= 2;
Global::MainHeight += 2;
}
if (!Config.statusbar_visibility)
Global::MainHeight++;
header_height = Config.new_design ? 5 : 1;
footer_start_y = LINES-(Config.statusbar_visibility ? 2 : 1);
footer_height = Config.statusbar_visibility ? 2 : 1;
}
void DefaultKeys(ncmpcpp_keys &keys) void DefaultKeys(ncmpcpp_keys &keys)
{ {
keys.Up[0] = KEY_UP; keys.Up[0] = KEY_UP;
@@ -152,6 +160,7 @@ void DefaultKeys(ncmpcpp_keys &keys)
keys.GoToContainingDir[0] = 'G'; keys.GoToContainingDir[0] = 'G';
keys.ToggleAutoCenter[0] = 'U'; keys.ToggleAutoCenter[0] = 'U';
keys.ToggleDisplayMode[0] = 'p'; keys.ToggleDisplayMode[0] = 'p';
keys.ToggleInterface[0] = '\\';
keys.ToggleLyricsDB[0] = 'L'; keys.ToggleLyricsDB[0] = 'L';
keys.GoToParentDir[0] = KEY_BACKSPACE; keys.GoToParentDir[0] = KEY_BACKSPACE;
keys.SwitchTagTypeList[0] = '`'; keys.SwitchTagTypeList[0] = '`';
@@ -221,6 +230,7 @@ void DefaultKeys(ncmpcpp_keys &keys)
keys.GoToContainingDir[1] = null_key; keys.GoToContainingDir[1] = null_key;
keys.ToggleAutoCenter[1] = null_key; keys.ToggleAutoCenter[1] = null_key;
keys.ToggleDisplayMode[1] = null_key; keys.ToggleDisplayMode[1] = null_key;
keys.ToggleInterface[1] = null_key;
keys.ToggleLyricsDB[1] = null_key; keys.ToggleLyricsDB[1] = null_key;
keys.GoToParentDir[1] = 127; keys.GoToParentDir[1] = 127;
keys.SwitchTagTypeList[1] = null_key; keys.SwitchTagTypeList[1] = null_key;
@@ -237,6 +247,8 @@ void DefaultConfiguration(ncmpcpp_config &conf)
conf.song_window_title_format = "{%a - }{%t}|{%f}"; conf.song_window_title_format = "{%a - }{%t}|{%f}";
conf.song_library_format = "{%n - }{%t}|{%f}"; conf.song_library_format = "{%n - }{%t}|{%f}";
conf.tag_editor_album_format = "{(%y) }%b"; conf.tag_editor_album_format = "{(%y) }%b";
conf.new_header_first_line = "$b$1$aqqu$/a$9 {%t}|{%f} $1$atqq$/a$9$/b";
conf.new_header_second_line = "{$4$b%a$/b$9}{ - $7%b$9}{ ($4%y$9)}";
conf.browser_playlist_prefix << clRed << "(playlist)" << clEnd << ' '; conf.browser_playlist_prefix << clRed << "(playlist)" << clEnd << ' ';
conf.pattern = "%n - %t"; conf.pattern = "%n - %t";
conf.selected_item_prefix << clMagenta; conf.selected_item_prefix << clMagenta;
@@ -284,6 +296,7 @@ void DefaultConfiguration(ncmpcpp_config &conf)
conf.allow_physical_files_deletion = false; conf.allow_physical_files_deletion = false;
conf.allow_physical_directories_deletion = false; conf.allow_physical_directories_deletion = false;
conf.mouse_support = true; conf.mouse_support = true;
conf.new_design = false;
conf.set_window_title = true; conf.set_window_title = true;
conf.mpd_port = 6600; conf.mpd_port = 6600;
conf.mpd_connection_timeout = 15; conf.mpd_connection_timeout = 15;
@@ -546,6 +559,16 @@ void ReadConfiguration(ncmpcpp_config &conf)
if (!v.empty()) if (!v.empty())
conf.execute_on_song_change = v; conf.execute_on_song_change = v;
} }
else if (cl.find("alternative_header_first_line_format") != std::string::npos)
{
if (!v.empty())
conf.new_header_first_line = v;
}
else if (cl.find("alternative_header_second_line_format") != std::string::npos)
{
if (!v.empty())
conf.new_header_second_line = v;
}
else if (cl.find("browser_playlist_prefix") != std::string::npos) else if (cl.find("browser_playlist_prefix") != std::string::npos)
{ {
if (!v.empty()) if (!v.empty())
@@ -693,6 +716,10 @@ void ReadConfiguration(ncmpcpp_config &conf)
{ {
conf.mouse_support = v == "yes"; conf.mouse_support = v == "yes";
} }
else if (cl.find("user_interface") != std::string::npos)
{
conf.new_design = v == "alternative";
}
else if (cl.find("enable_window_title") != std::string::npos) else if (cl.find("enable_window_title") != std::string::npos)
{ {
conf.set_window_title = v == "yes"; conf.set_window_title = v == "yes";

View File

@@ -111,6 +111,7 @@ struct ncmpcpp_keys
int GoToContainingDir[2]; int GoToContainingDir[2];
int ToggleAutoCenter[2]; int ToggleAutoCenter[2];
int ToggleDisplayMode[2]; int ToggleDisplayMode[2];
int ToggleInterface[2];
int ToggleLyricsDB[2]; int ToggleLyricsDB[2];
int GoToParentDir[2]; int GoToParentDir[2];
int SwitchTagTypeList[2]; int SwitchTagTypeList[2];
@@ -131,6 +132,8 @@ struct ncmpcpp_config
std::string external_editor; std::string external_editor;
std::string system_encoding; std::string system_encoding;
std::string execute_on_song_change; std::string execute_on_song_change;
std::string new_header_first_line;
std::string new_header_second_line;
std::string pattern; std::string pattern;
@@ -187,6 +190,7 @@ struct ncmpcpp_config
bool allow_physical_files_deletion; bool allow_physical_files_deletion;
bool allow_physical_directories_deletion; bool allow_physical_directories_deletion;
bool mouse_support; bool mouse_support;
bool new_design;
int mpd_port; int mpd_port;
int mpd_connection_timeout; int mpd_connection_timeout;
@@ -204,6 +208,7 @@ extern ncmpcpp_config Config;
extern ncmpcpp_keys Key; extern ncmpcpp_keys Key;
void CreateConfigDir(); void CreateConfigDir();
void SetWindowsDimensions(size_t &header_height, size_t &footer_start_y, size_t &footer_height);
void DefaultKeys(ncmpcpp_keys &); void DefaultKeys(ncmpcpp_keys &);
void DefaultConfiguration(ncmpcpp_config &); void DefaultConfiguration(ncmpcpp_config &);
void ReadKeys(ncmpcpp_keys &); void ReadKeys(ncmpcpp_keys &);

View File

@@ -168,6 +168,8 @@ void NcmpcppErrorCallback(Connection *, int errorid, const char *msg, void *)
void NcmpcppStatusChanged(Connection *, StatusChanges changed, void *) void NcmpcppStatusChanged(Connection *, StatusChanges changed, void *)
{ {
static size_t playing_song_scroll_begin = 0; static size_t playing_song_scroll_begin = 0;
static size_t first_line_scroll_begin = 0;
static size_t second_line_scroll_begin = 0;
static std::string player_state; static std::string player_state;
static int elapsed; static int elapsed;
static MPD::Song np; static MPD::Song np;
@@ -315,14 +317,14 @@ void NcmpcppStatusChanged(Connection *, StatusChanges changed, void *)
case psPlay: case psPlay:
{ {
WindowTitle(utf_to_locale_cpy(np.toString(Config.song_window_title_format))); WindowTitle(utf_to_locale_cpy(np.toString(Config.song_window_title_format)));
player_state = "Playing: "; player_state = Config.new_design ? "[playing]" : "Playing: ";
Playlist::ReloadRemaining = 1; Playlist::ReloadRemaining = 1;
changed.ElapsedTime = 1; changed.ElapsedTime = 1;
break; break;
} }
case psPause: case psPause:
{ {
player_state = "[Paused] "; player_state = Config.new_design ? "[paused] " : "[Paused] ";
break; break;
} }
case psStop: case psStop:
@@ -333,11 +335,24 @@ void NcmpcppStatusChanged(Connection *, StatusChanges changed, void *)
wFooter->SetColor(Config.statusbar_color); wFooter->SetColor(Config.statusbar_color);
Playlist::ReloadRemaining = 1; Playlist::ReloadRemaining = 1;
myPlaylist->NowPlaying = -1; myPlaylist->NowPlaying = -1;
player_state.clear(); if (Config.new_design)
{
*wHeader << XY(0, 0) << wclrtoeol << XY(0, 1) << wclrtoeol;
player_state = "[stopped]";
changed.Volume = 1;
changed.StatusFlags = 1;
}
else
player_state.clear();
break; break;
} }
} }
if (!block_statusbar_update && Config.statusbar_visibility) if (Config.new_design)
{
*wHeader << XY(0, 1) << fmtBold << player_state << fmtBoldEnd;
wHeader->Refresh();
}
else if (!block_statusbar_update && Config.statusbar_visibility)
{ {
*wFooter << XY(0, 1); *wFooter << XY(0, 1);
if (player_state.empty()) if (player_state.empty())
@@ -351,6 +366,7 @@ void NcmpcppStatusChanged(Connection *, StatusChanges changed, void *)
if (myPlaylist->isPlaying()) if (myPlaylist->isPlaying())
{ {
np = Mpd.GetCurrentSong(); np = Mpd.GetCurrentSong();
if (!Config.execute_on_song_change.empty()) if (!Config.execute_on_song_change.empty())
system(np.toString(Config.execute_on_song_change).c_str()); system(np.toString(Config.execute_on_song_change).c_str());
if (Mpd.GetState() > psStop) if (Mpd.GetState() > psStop)
@@ -367,11 +383,11 @@ void NcmpcppStatusChanged(Connection *, StatusChanges changed, void *)
Playlist::ReloadRemaining = 1; Playlist::ReloadRemaining = 1;
playing_song_scroll_begin = 0; playing_song_scroll_begin = 0;
first_line_scroll_begin = 0;
second_line_scroll_begin = 0;
if (Mpd.GetState() == psPlay) if (Mpd.GetState() == psPlay)
{
changed.ElapsedTime = 1; changed.ElapsedTime = 1;
}
} }
static time_t now, past = 0; static time_t now, past = 0;
time(&now); time(&now);
@@ -383,7 +399,7 @@ void NcmpcppStatusChanged(Connection *, StatusChanges changed, void *)
np = Mpd.GetCurrentSong(); np = Mpd.GetCurrentSong();
WindowTitle(utf_to_locale_cpy(np.toString(Config.song_window_title_format))); WindowTitle(utf_to_locale_cpy(np.toString(Config.song_window_title_format)));
} }
if (!np.Empty() && !player_state.empty()) if (!np.Empty() && Mpd.GetState() > psStop)
{ {
int mpd_elapsed = Mpd.GetElapsedTime(); int mpd_elapsed = Mpd.GetElapsedTime();
if (elapsed < mpd_elapsed-2 || elapsed+1 > mpd_elapsed) if (elapsed < mpd_elapsed-2 || elapsed+1 > mpd_elapsed)
@@ -391,9 +407,43 @@ void NcmpcppStatusChanged(Connection *, StatusChanges changed, void *)
else if (Mpd.GetState() == psPlay && !RedrawStatusbar) else if (Mpd.GetState() == psPlay && !RedrawStatusbar)
elapsed++; elapsed++;
if (!block_statusbar_update && Config.statusbar_visibility) std::string tracklength;
if (Config.new_design)
{
tracklength = Song::ShowTime(elapsed);
if (np.GetTotalLength())
{
tracklength += "/";
tracklength += np.GetLength();
}
basic_buffer<my_char_t> first, second;
String2Buffer(TO_WSTRING(np.toString(Config.new_header_first_line)), first);
String2Buffer(TO_WSTRING(np.toString(Config.new_header_second_line)), second);
size_t first_len = Window::Length(first.Str());
size_t first_margin = (std::max(tracklength.length()+1, VolumeState.length()))*2;
size_t first_start = first_len < COLS-first_margin ? (COLS-first_len)/2 : tracklength.length()+1;
size_t second_len = Window::Length(second.Str());
size_t second_margin = (std::max(player_state.length(), size_t(8))+1)*2;
size_t second_start = second_len < COLS-second_margin ? (COLS-second_len)/2 : player_state.length()+1;
if (!block_progressbar_update) // if blocked, seeking in progress
*wHeader << XY(0, 0) << wclrtoeol << tracklength;
*wHeader << XY(first_start, 0);
first.Write(*wHeader, first_line_scroll_begin, COLS-tracklength.length()-VolumeState.length()-1, U(" ** "));
*wHeader << XY(0, 1) << wclrtoeol << fmtBold << player_state << fmtBoldEnd;
*wHeader << XY(second_start, 1);
second.Write(*wHeader, second_line_scroll_begin, COLS-player_state.length()-8-2, U(" ** "));
*wHeader << XY(wHeader->GetWidth()-VolumeState.length(), 0) << Config.volume_color << VolumeState << clEnd;
changed.StatusFlags = 1;
}
else if (!block_statusbar_update && Config.statusbar_visibility)
{ {
std::string tracklength;
if (np.GetTotalLength()) if (np.GetTotalLength())
{ {
tracklength = " ["; tracklength = " [";
@@ -478,38 +528,54 @@ void NcmpcppStatusChanged(Connection *, StatusChanges changed, void *)
{ {
std::string switch_state; std::string switch_state;
if (mpd_repeat) if (Config.new_design)
switch_state += mpd_repeat;
if (mpd_random)
switch_state += mpd_random;
if (mpd_single)
switch_state += mpd_single;
if (mpd_consume)
switch_state += mpd_consume;
if (mpd_crossfade)
switch_state += mpd_crossfade;
if (mpd_db_updating)
switch_state += mpd_db_updating;
// this is done by raw ncurses because creating another
// window only for handling this is quite silly
attrset(A_BOLD|COLOR_PAIR(Config.state_line_color));
mvhline(1, 0, 0, COLS);
if (!switch_state.empty())
{ {
switch_state += '[';
mvprintw(1, COLS-switch_state.length()-3, "["); switch_state += mpd_repeat ? mpd_repeat : '-';
attron(COLOR_PAIR(Config.state_flags_color)); switch_state += mpd_random ? mpd_random : '-';
mvprintw(1, COLS-switch_state.length()-2, "%s", switch_state.c_str()); switch_state += mpd_single ? mpd_single : '-';
attron(COLOR_PAIR(Config.state_line_color)); switch_state += mpd_consume ? mpd_consume : '-';
mvprintw(1, COLS-2, "]"); switch_state += mpd_crossfade ? mpd_crossfade : '-';
switch_state += mpd_db_updating ? mpd_db_updating : '-';
switch_state += ']';
*wHeader << XY(COLS-switch_state.length(), 1) << fmtBold << Config.state_flags_color << switch_state << clEnd << fmtBoldEnd;
wHeader->Refresh();
}
else
{
if (mpd_repeat)
switch_state += mpd_repeat;
if (mpd_random)
switch_state += mpd_random;
if (mpd_single)
switch_state += mpd_single;
if (mpd_consume)
switch_state += mpd_consume;
if (mpd_crossfade)
switch_state += mpd_crossfade;
if (mpd_db_updating)
switch_state += mpd_db_updating;
// this is done by raw ncurses because creating another
// window only for handling this is quite silly
attrset(A_BOLD|COLOR_PAIR(Config.state_line_color));
mvhline(1, 0, 0, COLS);
if (!switch_state.empty())
{
mvprintw(1, COLS-switch_state.length()-3, "[");
attron(COLOR_PAIR(Config.state_flags_color));
mvprintw(1, COLS-switch_state.length()-2, "%s", switch_state.c_str());
attroff(COLOR_PAIR(Config.state_flags_color));
attron(COLOR_PAIR(Config.state_line_color));
mvprintw(1, COLS-2, "]");
}
attroff(A_BOLD|COLOR_PAIR(Config.state_line_color));
refresh();
} }
attroff(A_BOLD|COLOR_PAIR(Config.state_line_color));
refresh();
} }
if (changed.Volume && Config.header_visibility) if (changed.Volume && Config.header_visibility)
{ {
VolumeState = " Volume: "; VolumeState = Config.new_design ? " Vol: " : " Volume: ";
int volume = Mpd.GetVolume(); int volume = Mpd.GetVolume();
if (volume < 0) if (volume < 0)
VolumeState += "n/a"; VolumeState += "n/a";

View File

@@ -58,6 +58,7 @@ namespace NCurses
bool SetFormatting(short vb, const std::basic_string<C> &s, short ve, bool for_each = 1); bool SetFormatting(short vb, const std::basic_string<C> &s, short ve, bool for_each = 1);
void RemoveFormatting(short vb, const std::basic_string<C> &s, short ve, bool for_each = 1); void RemoveFormatting(short vb, const std::basic_string<C> &s, short ve, bool for_each = 1);
void SetTemp(std::basic_string<C> *); void SetTemp(std::basic_string<C> *);
void Write(Window &w, size_t &pos, size_t width, const std::basic_string<C> &sep);
void Clear(); void Clear();
template <typename T> basic_buffer<C> &operator<<(const T &t) template <typename T> basic_buffer<C> &operator<<(const T &t)
@@ -72,6 +73,9 @@ namespace NCurses
basic_buffer<C> &operator<<(const basic_buffer<C> &buf); basic_buffer<C> &operator<<(const basic_buffer<C> &buf);
friend Window &operator<< <>(Window &, const basic_buffer<C> &); friend Window &operator<< <>(Window &, const basic_buffer<C> &);
private:
void LoadAttribute(Window &w, short value) const;
}; };
typedef basic_buffer<char> Buffer; typedef basic_buffer<char> Buffer;
@@ -140,12 +144,71 @@ template <typename C> void NCurses::basic_buffer<C>::SetTemp(std::basic_string<C
itsTempString = tmp; itsTempString = tmp;
} }
template <typename C> void NCurses::basic_buffer<C>::Write(Window &w, size_t &pos, size_t width, const std::basic_string<C> &sep)
{
std::basic_string<C> s = itsString.str();
size_t len = Window::Length(s);
if (len > width)
{
s += sep;
len = 0;
typename std::list<typename NCurses::basic_buffer<C>::FormatPos>::const_iterator lb = itsFormat.begin();
if (itsFormat.back().Position > pos) // if there is no attributes from current position, don't load them
{
// load all attributes that are before start position
for (; lb->Position < pos; ++lb)
LoadAttribute(w, lb->Value);
}
for (size_t i = pos; i < s.length() && len < width; ++i)
{
while (i == lb->Position && lb != itsFormat.end())
{
LoadAttribute(w, lb->Value);
++lb;
}
len += wcwidth(s[i]);
w << s[i];
}
if (++pos >= s.length())
pos = 0;
if (len < width)
lb = itsFormat.begin();
for (size_t i = 0; len < width; ++i)
{
while (i == lb->Position && lb != itsFormat.end())
{
LoadAttribute(w, lb->Value);
++lb;
}
len += wcwidth(s[i]);
w << s[i];
}
// load all remained attributes to clean up
for (; lb != itsFormat.end(); ++lb)
LoadAttribute(w, lb->Value);
}
else
w << *this;
}
template <typename C> void NCurses::basic_buffer<C>::Clear() template <typename C> void NCurses::basic_buffer<C>::Clear()
{ {
itsString.str(std::basic_string<C>()); itsString.str(std::basic_string<C>());
itsFormat.clear(); itsFormat.clear();
} }
template <typename C> void NCurses::basic_buffer<C>::LoadAttribute(Window &w, short value) const
{
if (value < NCurses::fmtNone)
w << NCurses::Color(value);
else
w << NCurses::Format(value);
}
template <typename C> NCurses::basic_buffer<C> &NCurses::basic_buffer<C>::operator<<(std::ostream &(*os)(std::ostream&)) template <typename C> NCurses::basic_buffer<C> &NCurses::basic_buffer<C>::operator<<(std::ostream &(*os)(std::ostream&))
{ {
itsString << os; itsString << os;
@@ -199,10 +262,7 @@ template <typename C> NCurses::Window &operator<<(NCurses::Window &w, const NCur
w << tmp; w << tmp;
tmp.clear(); tmp.clear();
} }
if (b->Value < NCurses::fmtNone) buf.LoadAttribute(w, b->Value);
w << NCurses::Color(b->Value);
else
w << NCurses::Format(b->Value);
b++; b++;
} }
if (i < s.length()) if (i < s.length())

View File

@@ -58,6 +58,7 @@ void TinyTagEditor::Init()
void TinyTagEditor::Resize() void TinyTagEditor::Resize()
{ {
w->Resize(COLS, MainHeight); w->Resize(COLS, MainHeight);
w->MoveTo(0, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
@@ -86,9 +87,9 @@ void TinyTagEditor::SwitchTo()
} }
} }
std::string TinyTagEditor::Title() std::basic_string<my_char_t> TinyTagEditor::Title()
{ {
return "Tiny tag editor"; return U("Tiny tag editor");
} }
void TinyTagEditor::EnterPressed() void TinyTagEditor::EnterPressed()
@@ -375,15 +376,17 @@ void TagEditor::Resize()
TagTypes->Resize(MiddleColumnWidth, MainHeight); TagTypes->Resize(MiddleColumnWidth, MainHeight);
Tags->Resize(RightColumnWidth, MainHeight); Tags->Resize(RightColumnWidth, MainHeight);
Albums->MoveTo(0, MainStartY);
Dirs->MoveTo(0, MainStartY);
TagTypes->MoveTo(MiddleColumnStartX, MainStartY); TagTypes->MoveTo(MiddleColumnStartX, MainStartY);
Tags->MoveTo(RightColumnStartX, MainStartY); Tags->MoveTo(RightColumnStartX, MainStartY);
hasToBeResized = 0; hasToBeResized = 0;
} }
std::string TagEditor::Title() std::basic_string<my_char_t> TagEditor::Title()
{ {
return "Tag editor"; return U("Tag editor");
} }
void TagEditor::SwitchTo() void TagEditor::SwitchTo()

View File

@@ -39,7 +39,7 @@ class TinyTagEditor : public Screen< Menu<Buffer> >
virtual void Resize(); virtual void Resize();
virtual void SwitchTo(); virtual void SwitchTo();
virtual std::string Title(); virtual std::basic_string<my_char_t> Title();
virtual void EnterPressed(); virtual void EnterPressed();
virtual void SpacePressed() { } virtual void SpacePressed() { }
@@ -69,7 +69,7 @@ class TagEditor : public Screen<Window>
virtual void Resize(); virtual void Resize();
virtual void SwitchTo(); virtual void SwitchTo();
virtual std::string Title(); virtual std::basic_string<my_char_t> Title();
virtual void Refresh(); virtual void Refresh();
virtual void Update(); virtual void Update();

View File

@@ -47,10 +47,12 @@
#ifdef _UTF8 #ifdef _UTF8
# define my_char_t wchar_t # define my_char_t wchar_t
# define U(x) L##x
# define TO_STRING(x) ToString(x) # define TO_STRING(x) ToString(x)
# define TO_WSTRING(x) ToWString(x) # define TO_WSTRING(x) ToWString(x)
#else #else
# define my_char_t char # define my_char_t char
# define U(x) x
# define TO_STRING(x) (x) # define TO_STRING(x) (x)
# define TO_WSTRING(x) (x) # define TO_WSTRING(x) (x)
#endif #endif
@@ -155,6 +157,7 @@ namespace NCurses
virtual Window *Clone() const { return new Window(*this); } virtual Window *Clone() const { return new Window(*this); }
virtual Window *EmptyClone() const; virtual Window *EmptyClone() const;
static size_t Length(const std::string &s) { return s.length(); }
static size_t Length(const std::wstring &); static size_t Length(const std::wstring &);
protected: protected: