make defining screens with main window type as non-pointer possible

This commit is contained in:
Andrzej Rybczak
2012-09-14 15:40:31 +02:00
parent 9e93f7baf9
commit 4d6ea660bc
34 changed files with 358 additions and 203 deletions

View File

@@ -104,6 +104,7 @@ void Action::InitializeScreens()
myLyrics = new Lyrics;
mySelectedItemsAdder = new SelectedItemsAdder;
mySongInfo = new SongInfo;
myServerInfo = new ServerInfo;
mySortPlaylistDialog = new SortPlaylistDialog;
# ifdef HAVE_CURL_CURL_H
@@ -140,6 +141,7 @@ void Action::SetResizeFlags()
myLyrics->hasToBeResized = 1;
mySelectedItemsAdder->hasToBeResized = 1;
mySongInfo->hasToBeResized = 1;
myServerInfo->hasToBeResized = 1;
mySortPlaylistDialog->hasToBeResized = 1;
# ifdef HAVE_CURL_CURL_H
@@ -1921,10 +1923,10 @@ void Find::Run()
Statusbar::unlock();
Statusbar::msg("Searching...");
Screen<NC::Scrollpad> *s = static_cast<Screen<NC::Scrollpad> *>(myScreen);
s->main()->removeFormatting();
Statusbar::msg("%s", findme.empty() || s->main()->setFormatting(NC::fmtReverse, ToWString(findme), NC::fmtReverseEnd, 0) ? "Done" : "No matching patterns found");
s->main()->flush();
auto s = static_cast<Screen<NC::Scrollpad> *>(myScreen);
s->main().removeFormatting();
Statusbar::msg("%s", findme.empty() || s->main().setFormatting(NC::fmtReverse, ToWString(findme), NC::fmtReverseEnd, 0) ? "Done" : "No matching patterns found");
s->main().flush();
}
bool FindItemBackward::canBeRun() const

View File

@@ -253,7 +253,7 @@ void Browser::mouseButtonPressed(MEVENT me)
}
}
else
Screen< NC::Menu<MPD::Item> >::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
}
/***********************************************************************/

View File

@@ -25,7 +25,7 @@
#include "mpdpp.h"
#include "screen.h"
struct Browser : public Screen< NC::Menu<MPD::Item> >, public Filterable, public HasSongs, public Searchable
struct Browser : public Screen<NC::Menu<MPD::Item> *>, public Filterable, public HasSongs, public Searchable
{
Browser();

View File

@@ -28,7 +28,7 @@
#include "window.h"
#include "screen.h"
struct Clock : public Screen<NC::Window>
struct Clock : public Screen<NC::Window *>
{
Clock();

View File

@@ -96,18 +96,18 @@ std::string keyToString(const Key &key, bool *print_backspace)
}
Help::Help()
: Screen(NC::Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, NC::brNone))
{
w = new NC::Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, NC::brNone);
GetKeybindings();
w->flush();
w.flush();
}
void Help::resize()
{
size_t x_offset, width;
getWindowResizeParams(x_offset, width);
w->resize(width, MainHeight);
w->moveTo(x_offset, MainStartY);
w.resize(width, MainHeight);
w.moveTo(x_offset, MainStartY);
hasToBeResized = 0;
}
@@ -154,25 +154,25 @@ std::string Help::DisplayKeys(const ActionType at)
void Help::Section(const char *type, const char *title_)
{
*w << L"\n " << NC::fmtBold << ToWString(type) << L" - ";
*w << ToWString(title_) << NC::fmtBoldEnd << L"\n\n";
w << L"\n " << NC::fmtBold << ToWString(type) << L" - ";
w << ToWString(title_) << NC::fmtBoldEnd << L"\n\n";
}
void Help::KeyDesc(const ActionType at, const char *desc)
{
*w << L" " << DisplayKeys(at) << L" : " << ToWString(desc) << '\n';
w << L" " << DisplayKeys(at) << L" : " << ToWString(desc) << '\n';
}
void Help::MouseDesc(std::string action, const char *desc, bool indent)
{
action.resize(31 - (indent ? 2 : 0), ' ');
*w << L" " << (indent ? L" " : L"") << ToWString(action);
*w << L": " << ToWString(desc) << '\n';
w << L" " << (indent ? L" " : L"") << ToWString(action);
w << L": " << ToWString(desc) << '\n';
}
void Help::MouseColumn(const char *column)
{
*w << NC::fmtBold << L" " << ToWString(column) << L" column:\n" << NC::fmtBoldEnd;
w << NC::fmtBold << L" " << ToWString(column) << L" column:\n" << NC::fmtBoldEnd;
}
void Help::GetKeybindings()
@@ -188,7 +188,7 @@ void Help::GetKeybindings()
KeyDesc(aPageDown, "Page down");
KeyDesc(aMoveHome, "Home");
KeyDesc(aMoveEnd, "End");
*w << '\n';
w << '\n';
if (Config.screen_switcher_previous)
{
KeyDesc(aNextScreen, "Switch between current and last screen");
@@ -217,7 +217,7 @@ void Help::GetKeybindings()
# ifdef ENABLE_CLOCK
KeyDesc(aShowClock, "Show clock");
# endif // ENABLE_CLOCK
*w << '\n';
w << '\n';
KeyDesc(aShowServerInfo, "Show server info");
KeysSection("Global");
@@ -230,7 +230,7 @@ void Help::GetKeybindings()
KeyDesc(aSeekBackward, "Seek backward in playing song");
KeyDesc(aVolumeDown, "Decrease volume by 2%");
KeyDesc(aVolumeUp, "Increase volume by 2%");
*w << '\n';
w << '\n';
KeyDesc(aToggleSpaceMode, "Toggle space mode (select/add)");
KeyDesc(aToggleAddMode, "Toggle add mode (add or remove/always add)");
KeyDesc(aToggleMouse, "Toggle mouse support");
@@ -239,7 +239,7 @@ void Help::GetKeybindings()
KeyDesc(aSelectAlbum, "Select songs of album around the cursor");
KeyDesc(aAddSelectedItems, "Add selected items to playlist");
KeyDesc(aAddRandomItems, "Add random items to playlist");
*w << '\n';
w << '\n';
KeyDesc(aToggleRepeat, "Toggle repeat mode");
KeyDesc(aToggleRandom, "Toggle random mode");
KeyDesc(aToggleSingle, "Toggle single mode");
@@ -250,7 +250,7 @@ void Help::GetKeybindings()
KeyDesc(aToggleCrossfade, "Toggle crossfade mode");
KeyDesc(aSetCrossfade, "Set crossfade");
KeyDesc(aUpdateDatabase, "Start music database update");
*w << '\n';
w << '\n';
KeyDesc(aApplyFilter, "Apply filter");
KeyDesc(aFindItemForward, "Find item forward");
KeyDesc(aFindItemBackward, "Find item backward");
@@ -276,7 +276,7 @@ void Help::GetKeybindings()
KeyDesc(aToggleFetchingLyricsInBackground, "Toggle fetching lyrics for playing songs in background");
# endif // HAVE_CURL_CURL_H
KeyDesc(aShowLyrics, "Show/hide song lyrics");
*w << '\n';
w << '\n';
KeyDesc(aQuit, "Quit");
KeysSection("Playlist");
@@ -386,7 +386,7 @@ void Help::GetKeybindings()
MouseSection("Global");
MouseDesc("Left click on \"Playing/Paused\"", "Play/pause");
MouseDesc("Left click on progressbar", "Jump to pointed position in playing song");
*w << '\n';
w << '\n';
MouseDesc("Mouse wheel on \"Volume: xx\"", "Play/pause");
MouseDesc("Mouse wheel on main window", "Scroll");
@@ -397,7 +397,7 @@ void Help::GetKeybindings()
MouseSection("Browser");
MouseDesc("Left click on directory", "Enter pointed directory");
MouseDesc("Right click on directory", "Add pointed directory to playlist");
*w << '\n';
w << '\n';
MouseDesc("Left click on song/playlist", "Add pointed item to playlist");
MouseDesc("Right click on song/playlist", "Add pointed item to playlist and play it");
@@ -409,7 +409,7 @@ void Help::GetKeybindings()
MouseColumn("Left/middle");
MouseDesc("Left click", "Select pointed item", true);
MouseDesc("Right click", "Add item to playlist", true);
*w << '\n';
w << '\n';
MouseColumn("Right");
MouseDesc("Left Click", "Add pointed item to playlist", true);
MouseDesc("Right Click", "Add pointed item to playlist and play it", true);
@@ -418,7 +418,7 @@ void Help::GetKeybindings()
MouseColumn("Left");
MouseDesc("Left click", "Select pointed item", true);
MouseDesc("Right click", "Add item to playlist", true);
*w << '\n';
w << '\n';
MouseColumn("Right");
MouseDesc("Left click", "Add pointed item to playlist", true);
MouseDesc("Right click", "Add pointed item to playlist and play it", true);
@@ -432,11 +432,11 @@ void Help::GetKeybindings()
MouseColumn("Left");
MouseDesc("Left click", "Enter pointed directory/select pointed album", true);
MouseDesc("Right click", "Toggle view (directories/albums)", true);
*w << '\n';
w << '\n';
MouseColumn("Middle");
MouseDesc("Left click", "Select option", true);
MouseDesc("Right click", "Set value/execute", true);
*w << '\n';
w << '\n';
MouseColumn("Right");
MouseDesc("Left click", "Select pointed item", true);
MouseDesc("Right click", "Set value", true);

View File

@@ -45,17 +45,17 @@ using Global::MainStartY;
Lastfm *myLastfm;
Lastfm::Lastfm() : isReadyToTake(0), isDownloadInProgress(0)
{
w = new NC::Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, NC::brNone);
}
Lastfm::Lastfm()
: Screen(NC::Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, NC::brNone))
, isReadyToTake(0), isDownloadInProgress(0)
{ }
void Lastfm::resize()
{
size_t x_offset, width;
getWindowResizeParams(x_offset, width);
w->resize(width, MainHeight);
w->moveTo(x_offset, MainStartY);
w.resize(width, MainHeight);
w.moveTo(x_offset, MainStartY);
hasToBeResized = 0;
}
@@ -74,8 +74,8 @@ void Lastfm::Take()
{
assert(isReadyToTake);
pthread_join(itsDownloader, 0);
w->flush();
w->refresh();
w.flush();
w.refresh();
isDownloadInProgress = 0;
isReadyToTake = 0;
}
@@ -116,8 +116,8 @@ void Lastfm::Load()
SetTitleAndFolder();
w->clear();
w->reset();
w.clear();
w.reset();
std::string artist = itsArgs.find("artist")->second;
std::string file = lowercase(artist + ".txt");
@@ -139,21 +139,21 @@ void Lastfm::Load()
while (getline(input, line))
{
if (!first)
*w << '\n';
w << '\n';
IConv::utf8ToLocale_(line);
*w << line;
w << line;
first = 0;
}
input.close();
itsService->colorizeOutput(*w);
itsService->colorizeOutput(w);
}
else
{
*w << L"Fetching informations... ";
w << L"Fetching informations... ";
pthread_create(&itsDownloader, 0, DownloadWrapper, this);
isDownloadInProgress = 1;
}
w->flush();
w.flush();
}
void Lastfm::SetTitleAndFolder()
@@ -179,13 +179,13 @@ void Lastfm::Download()
if (result.first)
{
Save(result.second);
w->clear();
w.clear();
IConv::utf8ToLocale_(result.second);
*w << result.second;
itsService->colorizeOutput(*w);
w << result.second;
itsService->colorizeOutput(w);
}
else
*w << NC::clRed << result.second << NC::clEnd;
w << NC::clRed << result.second << NC::clEnd;
isReadyToTake = 1;
}

View File

@@ -35,7 +35,6 @@ struct Lastfm : public Screen<NC::Scrollpad>
{
Lastfm();
// Screen<NC::Scrollpad>
virtual void switchTo() OVERRIDE;
virtual void resize() OVERRIDE;

View File

@@ -50,21 +50,21 @@ size_t Lyrics::itsWorkersNumber = 0;
Lyrics *myLyrics;
Lyrics::Lyrics() : ReloadNP(0),
Lyrics::Lyrics()
: Screen(NC::Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, NC::brNone))
, ReloadNP(0),
#ifdef HAVE_CURL_CURL_H
isReadyToTake(0), isDownloadInProgress(0),
isReadyToTake(0), isDownloadInProgress(0),
#endif // HAVE_CURL_CURL_H
itsScrollBegin(0)
{
w = new NC::Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, NC::brNone);
}
{ }
void Lyrics::resize()
{
size_t x_offset, width;
getWindowResizeParams(x_offset, width);
w->resize(width, MainHeight);
w->moveTo(x_offset, MainStartY);
w.resize(width, MainHeight);
w.moveTo(x_offset, MainStartY);
hasToBeResized = 0;
}
@@ -76,8 +76,8 @@ void Lyrics::update()
if (isDownloadInProgress)
{
w->flush();
w->refresh();
w.flush();
w.refresh();
}
# endif // HAVE_CURL_CURL_H
if (ReloadNP)
@@ -255,10 +255,10 @@ void *Lyrics::Download()
bool fetcher_defined = itsFetcher && *itsFetcher;
for (LyricsFetcher **plugin = fetcher_defined ? itsFetcher : lyricsPlugins; *plugin != 0; ++plugin)
{
*w << L"Fetching lyrics from " << NC::fmtBold << ToWString((*plugin)->name()) << NC::fmtBoldEnd << L"... ";
w << L"Fetching lyrics from " << NC::fmtBold << ToWString((*plugin)->name()) << NC::fmtBoldEnd << L"... ";
result = (*plugin)->fetch(artist, title_);
if (result.first == false)
*w << NC::clRed << ToWString(result.second) << NC::clEnd << '\n';
w << NC::clRed << ToWString(result.second) << NC::clEnd << '\n';
else
break;
if (fetcher_defined)
@@ -268,12 +268,12 @@ void *Lyrics::Download()
if (result.first == true)
{
Save(itsFilename, result.second);
w->clear();
w.clear();
IConv::utf8ToLocale_(result.second);
*w << result.second;
w << result.second;
}
else
*w << '\n' << L"Lyrics weren't found.";
w << '\n' << L"Lyrics weren't found.";
isReadyToTake = 1;
pthread_exit(0);
@@ -332,8 +332,8 @@ void Lyrics::Load()
CreateDir(Config.lyrics_directory);
w->clear();
w->reset();
w.clear();
w.reset();
std::ifstream input(itsFilename.c_str());
if (input.is_open())
@@ -343,14 +343,14 @@ void Lyrics::Load()
while (getline(input, line))
{
if (!first)
*w << '\n';
w << '\n';
IConv::utf8ToLocale_(line);
*w << line;
w << line;
first = 0;
}
w->flush();
w.flush();
if (ReloadNP)
w->refresh();
w.refresh();
}
else
{
@@ -358,8 +358,8 @@ void Lyrics::Load()
pthread_create(&itsDownloader, 0, DownloadWrapper, this);
isDownloadInProgress = 1;
# else
*w << U("Local lyrics not found. As ncmpcpp has been compiled without curl support, you can put appropriate lyrics into ") << TO_WSTRING(Config.lyrics_directory) << U(" directory (file syntax is \"$ARTIST - $TITLE.txt\") or recompile ncmpcpp with curl support.");
w->flush();
w << U("Local lyrics not found. As ncmpcpp has been compiled without curl support, you can put appropriate lyrics into ") << TO_WSTRING(Config.lyrics_directory) << U(" directory (file syntax is \"$ARTIST - $TITLE.txt\") or recompile ncmpcpp with curl support.");
w.flush();
# endif
}
}
@@ -429,8 +429,8 @@ void Lyrics::Take()
{
assert(isReadyToTake);
pthread_join(itsDownloader, 0);
w->flush();
w->refresh();
w.flush();
w.refresh();
isDownloadInProgress = 0;
isReadyToTake = 0;
}

View File

@@ -444,7 +444,7 @@ void MediaLibrary::mouseButtonPressed(MEVENT me)
}
}
else
Screen<NC::Window>::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
Albums->clear();
Songs->clear();
}
@@ -472,7 +472,7 @@ void MediaLibrary::mouseButtonPressed(MEVENT me)
}
}
else
Screen<NC::Window>::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
Songs->clear();
}
else if (!Songs->empty() && Songs->hasCoords(me.x, me.y))
@@ -493,7 +493,7 @@ void MediaLibrary::mouseButtonPressed(MEVENT me)
enterPressed();
}
else
Screen<NC::Window>::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
}
}

View File

@@ -24,7 +24,7 @@
#include "interfaces.h"
#include "screen.h"
struct MediaLibrary : public Screen<NC::Window>, public Filterable, public HasColumns, public HasSongs, public Searchable
struct MediaLibrary : public Screen<NC::Window *>, public Filterable, public HasColumns, public HasSongs, public Searchable
{
MediaLibrary();

View File

@@ -176,6 +176,8 @@ public:
typedef std::function<bool(const Item &)> FilterFunction;
Menu() { }
/// Constructs an empty menu with given parameters
/// @param startx X position of left upper corner of constructed menu
/// @param starty Y position of left upper corner of constructed menu
@@ -187,8 +189,9 @@ public:
Menu(size_t startx, size_t starty, size_t width, size_t height,
const std::string &title, Color color, Border border);
Menu(const Menu &) = delete;
Menu &operator=(const Menu &) = delete;
Menu(const Menu &rhs);
Menu(Menu &&rhs);
Menu &operator=(Menu rhs);
/// Sets helper function that is responsible for displaying items
/// @param ptr function pointer that matches the ItemDisplayer prototype
@@ -410,7 +413,7 @@ private:
typedef Item element_type;
ItemProxy() { }
ItemProxy(Item &&item) : m_ptr(std::make_shared<Item>(item)) { }
ItemProxy(Item item) : m_ptr(std::make_shared<Item>(item)) { }
Item &operator*() const { return *m_ptr; }
Item *operator->() const { return m_ptr.get(); }
@@ -470,6 +473,78 @@ template <typename T> Menu<T>::Menu(size_t startx,
{
}
template <typename T> Menu<T>::Menu(const Menu &rhs)
: Window(rhs)
, m_item_displayer(rhs.m_item_displayer)
, m_filter(rhs.m_filter)
, m_searcher(rhs.m_searcher)
, m_found_positions(rhs.m_found_positions)
, m_beginning(rhs.m_beginning)
, m_highlight(rhs.m_highlight)
, m_highlight_color(rhs.m_highlight_color)
, m_highlight_enabled(rhs.m_highlight_enabled)
, m_cyclic_scroll_enabled(rhs.m_cyclic_scroll_enabled)
, m_autocenter_cursor(rhs.m_autocenter_cursor)
, m_drawn_position(rhs.m_drawn_position)
, m_selected_prefix(rhs.m_selected_prefix)
, m_selected_suffix(rhs.m_selected_suffix)
{
// there is no way to properly fill m_filtered_options
// (if rhs is filtered), so we just don't do it.
m_options.reserve(rhs.m_options.size());
for (auto it = rhs.m_options.begin(); it != rhs.m_options.end(); ++it)
m_options.push_back(ItemProxy(**it));
m_options_ptr = &m_options;
}
template <typename T> Menu<T>::Menu(Menu &&rhs)
: Window(rhs)
, m_item_displayer(rhs.m_item_displayer)
, m_filter(rhs.m_filter)
, m_searcher(rhs.m_searcher)
, m_options(std::move(rhs.m_options))
, m_filtered_options(std::move(rhs.m_filtered_options))
, m_found_positions(std::move(rhs.m_found_positions))
, m_beginning(rhs.m_beginning)
, m_highlight(rhs.m_highlight)
, m_highlight_color(rhs.m_highlight_color)
, m_highlight_enabled(rhs.m_highlight_enabled)
, m_cyclic_scroll_enabled(rhs.m_cyclic_scroll_enabled)
, m_autocenter_cursor(rhs.m_autocenter_cursor)
, m_drawn_position(rhs.m_drawn_position)
, m_selected_prefix(std::move(rhs.m_selected_prefix))
, m_selected_suffix(std::move(rhs.m_selected_suffix))
{
if (rhs.m_options_ptr == &rhs.m_options)
m_options_ptr = &m_options;
else
m_options_ptr = &m_filtered_options;
}
template <typename T> Menu<T> &Menu<T>::operator=(Menu rhs)
{
std::swap(m_item_displayer, rhs.m_item_displayer);
std::swap(m_filter, rhs.m_filter);
std::swap(m_searcher, rhs.m_searcher);
std::swap(m_options, rhs.m_options);
std::swap(m_filtered_options, rhs.m_filtered_options);
std::swap(m_found_positions, rhs.m_found_positions);
std::swap(m_beginning, rhs.m_beginning);
std::swap(m_highlight, rhs.m_highlight);
std::swap(m_highlight_color, rhs.m_highlight_color);
std::swap(m_highlight_enabled, rhs.m_highlight_enabled);
std::swap(m_cyclic_scroll_enabled, rhs.m_cyclic_scroll_enabled);
std::swap(m_autocenter_cursor, rhs.m_autocenter_cursor);
std::swap(m_drawn_position, rhs.m_drawn_position);
std::swap(m_selected_prefix, rhs.m_selected_prefix);
std::swap(m_selected_suffix, rhs.m_selected_suffix);
if (rhs.m_options_ptr == &rhs.m_options)
m_options_ptr = &m_options;
else
m_options_ptr = &m_filtered_options;
return *this;
}
template <typename T> void Menu<T>::reserve(size_t size_)
{
m_options.reserve(size_);

View File

@@ -189,11 +189,6 @@ int main(int argc, char **argv)
timeval past = { 0, 0 };
// local variables end
# ifndef WIN32
signal(SIGPIPE, sighandler);
signal(SIGWINCH, sighandler);
# endif // !WIN32
mouseinterval(0);
if (Config.mouse_support)
mousemask(ALL_MOUSE_EVENTS, 0);
@@ -207,6 +202,11 @@ int main(int argc, char **argv)
myPlaylist->main()->highlight(curr_pos);
}
# ifndef WIN32
signal(SIGPIPE, sighandler);
signal(SIGWINCH, sighandler);
# endif // !WIN32
while (!Action::ExitMainLoop)
{
if (!Mpd.Connected())

View File

@@ -107,7 +107,7 @@ void Outputs::mouseButtonPressed(MEVENT me)
enterPressed();
}
else
Screen< NC::Menu<MPD::Output> >::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
}
void Outputs::FetchList()

View File

@@ -29,7 +29,7 @@
#include "mpdpp.h"
#include "screen.h"
struct Outputs : public Screen< NC::Menu<MPD::Output> >
struct Outputs : public Screen<NC::Menu<MPD::Output> *>
{
Outputs();

View File

@@ -27,7 +27,7 @@
#include "screen.h"
#include "song.h"
struct Playlist : public Screen<NC::Menu<MPD::Song>>, public Filterable, public HasSongs, public Searchable
struct Playlist : public Screen<NC::Menu<MPD::Song> *>, public Filterable, public HasSongs, public Searchable
{
Playlist();

View File

@@ -295,7 +295,7 @@ void PlaylistEditor::mouseButtonPressed(MEVENT me)
}
}
else
Screen<NC::Window>::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
Content->clear();
}
else if (!Content->empty() && Content->hasCoords(me.x, me.y))
@@ -321,7 +321,7 @@ void PlaylistEditor::mouseButtonPressed(MEVENT me)
enterPressed();
}
else
Screen<NC::Window>::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
}
}

View File

@@ -24,7 +24,7 @@
#include "interfaces.h"
#include "screen.h"
struct PlaylistEditor : public Screen<NC::Window>, public Filterable, public HasColumns, public HasSongs, public Searchable
struct PlaylistEditor : public Screen<NC::Window *>, public Filterable, public HasColumns, public HasSongs, public Searchable
{
PlaylistEditor();

View File

@@ -40,37 +40,37 @@ void drawScreenSeparator(int x)
}
void genericMouseButtonPressed(NC::Window *w, MEVENT me)
void genericMouseButtonPressed(NC::Window &w, MEVENT me)
{
if (me.bstate & BUTTON2_PRESSED)
{
if (Config.mouse_list_scroll_whole_page)
w->scroll(NC::wPageDown);
w.scroll(NC::wPageDown);
else
for (size_t i = 0; i < Config.lines_scrolled; ++i)
w->scroll(NC::wDown);
w.scroll(NC::wDown);
}
else if (me.bstate & BUTTON4_PRESSED)
{
if (Config.mouse_list_scroll_whole_page)
w->scroll(NC::wPageUp);
w.scroll(NC::wPageUp);
else
for (size_t i = 0; i < Config.lines_scrolled; ++i)
w->scroll(NC::wUp);
w.scroll(NC::wUp);
}
}
void scrollpadMouseButtonPressed(NC::Scrollpad *w, MEVENT me)
void scrollpadMouseButtonPressed(NC::Scrollpad &w, MEVENT me)
{
if (me.bstate & BUTTON2_PRESSED)
{
for (size_t i = 0; i < Config.lines_scrolled; ++i)
w->scroll(NC::wDown);
w.scroll(NC::wDown);
}
else if (me.bstate & BUTTON4_PRESSED)
{
for (size_t i = 0; i < Config.lines_scrolled; ++i)
w->scroll(NC::wUp);
w.scroll(NC::wUp);
}
}

View File

@@ -24,8 +24,8 @@
#include "menu.h"
#include "scrollpad.h"
void genericMouseButtonPressed(NC::Window *w, MEVENT me);
void scrollpadMouseButtonPressed(NC::Scrollpad *w, MEVENT me);
void genericMouseButtonPressed(NC::Window &w, MEVENT me);
void scrollpadMouseButtonPressed(NC::Scrollpad &w, MEVENT me);
/// 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
@@ -36,7 +36,7 @@ struct BasicScreen
virtual ~BasicScreen() { }
/// @see Screen::activeWindow()
virtual NC::Window *activeWindow() = 0;
virtual void *activeWindow() = 0;
/// @see Screen::refresh()
virtual void refresh() = 0;
@@ -112,29 +112,47 @@ bool isVisible(BasicScreen *screen);
/// for the screen to be working properly and assumes that we didn't forget
/// about anything vital.
///
template <typename WindowT> struct Screen : public BasicScreen
template <typename WindowT> class Screen : public BasicScreen
{
template <bool IsPointer, typename Result> struct access { };
template <typename Result> struct access<true, Result> {
static Result apply(WindowT w) { return *w; }
};
template <typename Result> struct access<false, Result> {
static Result apply(WindowT &w) { return w; }
};
typedef access<
std::is_pointer<WindowT>::value,
typename std::add_lvalue_reference<
typename std::remove_pointer<WindowT>::type
>::type
> accessor;
public:
typedef WindowT ScreenType;
Screen() : w(0) { }
Screen() { }
Screen(WindowT w_) : w(w_) { }
virtual ~Screen() { }
/// Since some screens contain more that one window
/// it's useful to determine the one that is being
/// active
/// @return address to window object cast to void *
virtual NC::Window *activeWindow() OVERRIDE {
return w;
virtual void *activeWindow() OVERRIDE {
return &accessor::apply(w);
}
/// Refreshes whole screen
virtual void refresh() OVERRIDE {
w->display();
accessor::apply(w).display();
}
/// Refreshes active window of the screen
virtual void refreshWindow() OVERRIDE {
w->display();
accessor::apply(w).display();
}
/// Scrolls the screen by given amount of lines and
@@ -142,18 +160,18 @@ template <typename WindowT> struct Screen : public BasicScreen
/// loop that holds main loop until user releases the key
/// @param where indicates where one wants to scroll
virtual void scroll(NC::Where where) OVERRIDE {
w->scroll(where);
accessor::apply(w).scroll(where);
}
/// Invoked after there was one of mouse buttons pressed
/// @param me struct that contains coords of where the click
/// had its place and button actions
virtual void mouseButtonPressed(MEVENT me) OVERRIDE {
genericMouseButtonPressed(w, me);
genericMouseButtonPressed(accessor::apply(w), me);
}
/// @return pointer to currently active window
WindowT *main() {
/// @return currently active window
typename std::add_lvalue_reference<WindowT>::type main() {
return w;
}
@@ -162,10 +180,10 @@ protected:
/// of window used by the screen. What is more, it should
/// always be assigned to the currently active window (if
/// acreen contains more that one)
WindowT *w;
WindowT w;
};
/// Specialization for Screen<Scrollpad>::mouseButtonPressed, that should
/// Specialization for Screen<Scrollpad>::mouseButtonPressed that should
/// not scroll whole page, but rather a few lines (the number of them is
/// defined in the config)
template <> inline void Screen<NC::Scrollpad>::mouseButtonPressed(MEVENT me) {

View File

@@ -30,6 +30,8 @@ namespace NC {//
/// supports scrolling if the amount of it is bigger than the window area.
struct Scrollpad: public Window
{
Scrollpad() { }
/// Constructs an empty scrollpad with given parameters
/// @param startx X position of left upper corner of constructed window
/// @param starty Y position of left upper corner of constructed window

View File

@@ -264,7 +264,7 @@ void SearchEngine::mouseButtonPressed(MEVENT me)
}
}
else
Screen< NC::Menu<SEItem> >::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
}
/***********************************************************************/

View File

@@ -73,7 +73,7 @@ struct SEItem
MPD::Song itsSong;
};
struct SearchEngine : public Screen< NC::Menu<SEItem> >, public Filterable, public HasSongs, public Searchable
struct SearchEngine : public Screen<NC::Menu<SEItem> *>, public Filterable, public HasSongs, public Searchable
{
SearchEngine();

View File

@@ -244,7 +244,7 @@ void SelectedItemsAdder::mouseButtonPressed(MEVENT me)
enterPressed();
}
else
Screen< NC::Menu<std::string> >::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
}
void SelectedItemsAdder::SetDimensions()

View File

@@ -23,7 +23,7 @@
#include "screen.h"
struct SelectedItemsAdder : public Screen< NC::Menu<std::string> >
struct SelectedItemsAdder : public Screen<NC::Menu<std::string> *>
{
SelectedItemsAdder();

View File

@@ -30,13 +30,12 @@ using Global::MainHeight;
using Global::MainStartY;
using Global::myOldScreen;
ServerInfo *myServerInfo = new ServerInfo;
ServerInfo *myServerInfo;
ServerInfo::ServerInfo()
{
SetDimensions();
w = new NC::Scrollpad((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY, itsWidth, itsHeight, "MPD server info", Config.main_color, Config.window_border);
w = NC::Scrollpad((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY, itsWidth, itsHeight, "MPD server info", Config.main_color, Config.window_border);
itsURLHandlers = Mpd.GetURLHandlers();
itsTagTypes = Mpd.GetTagTypes();
}
@@ -58,7 +57,7 @@ void ServerInfo::switchTo()
resize();
myScreen = this;
//w->Window::clear();
//w.Window::clear();
}
void ServerInfo::resize()
@@ -66,8 +65,8 @@ void ServerInfo::resize()
SetDimensions();
if (itsHeight < 5) // screen too low to display this window
return myOldScreen->switchTo();
w->resize(itsWidth, itsHeight);
w->moveTo((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY);
w.resize(itsWidth, itsHeight);
w.moveTo((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY);
if (myOldScreen && myOldScreen->hasToBeResized) // resize background window
{
myOldScreen->resize();
@@ -92,33 +91,33 @@ void ServerInfo::update()
if (stats.empty())
return;
w->clear();
w.clear();
*w << NC::fmtBold << L"Version: " << NC::fmtBoldEnd << L"0." << Mpd.Version() << L".*\n";
*w << NC::fmtBold << L"Uptime: " << NC::fmtBoldEnd;
ShowTime(*w, stats.uptime(), 1);
*w << '\n';
*w << NC::fmtBold << L"Time playing: " << NC::fmtBoldEnd << MPD::Song::ShowTime(stats.playTime()) << '\n';
*w << '\n';
*w << NC::fmtBold << L"Total playtime: " << NC::fmtBoldEnd;
ShowTime(*w, stats.dbPlayTime(), 1);
*w << '\n';
*w << NC::fmtBold << L"Artist names: " << NC::fmtBoldEnd << stats.artists() << '\n';
*w << NC::fmtBold << L"Album names: " << NC::fmtBoldEnd << stats.albums() << '\n';
*w << NC::fmtBold << L"Songs in database: " << NC::fmtBoldEnd << stats.songs() << '\n';
*w << '\n';
*w << NC::fmtBold << L"Last DB update: " << NC::fmtBoldEnd << Timestamp(stats.dbUpdateTime()) << '\n';
*w << '\n';
*w << NC::fmtBold << L"URL Handlers:" << NC::fmtBoldEnd;
w << NC::fmtBold << L"Version: " << NC::fmtBoldEnd << L"0." << Mpd.Version() << L".*\n";
w << NC::fmtBold << L"Uptime: " << NC::fmtBoldEnd;
ShowTime(w, stats.uptime(), 1);
w << '\n';
w << NC::fmtBold << L"Time playing: " << NC::fmtBoldEnd << MPD::Song::ShowTime(stats.playTime()) << '\n';
w << '\n';
w << NC::fmtBold << L"Total playtime: " << NC::fmtBoldEnd;
ShowTime(w, stats.dbPlayTime(), 1);
w << '\n';
w << NC::fmtBold << L"Artist names: " << NC::fmtBoldEnd << stats.artists() << '\n';
w << NC::fmtBold << L"Album names: " << NC::fmtBoldEnd << stats.albums() << '\n';
w << NC::fmtBold << L"Songs in database: " << NC::fmtBoldEnd << stats.songs() << '\n';
w << '\n';
w << NC::fmtBold << L"Last DB update: " << NC::fmtBoldEnd << Timestamp(stats.dbUpdateTime()) << '\n';
w << '\n';
w << NC::fmtBold << L"URL Handlers:" << NC::fmtBoldEnd;
for (auto it = itsURLHandlers.begin(); it != itsURLHandlers.end(); ++it)
*w << (it != itsURLHandlers.begin() ? L", " : L" ") << *it;
*w << L"\n\n";
*w << NC::fmtBold << L"Tag Types:" << NC::fmtBoldEnd;
w << (it != itsURLHandlers.begin() ? L", " : L" ") << *it;
w << L"\n\n";
w << NC::fmtBold << L"Tag Types:" << NC::fmtBoldEnd;
for (auto it = itsTagTypes.begin(); it != itsTagTypes.end(); ++it)
*w << (it != itsTagTypes.begin() ? L", " : L" ") << *it;
w << (it != itsTagTypes.begin() ? L", " : L" ") << *it;
w->flush();
w->refresh();
w.flush();
w.refresh();
}
void ServerInfo::SetDimensions()

View File

@@ -51,16 +51,15 @@ const SongInfo::Metadata SongInfo::Tags[] =
};
SongInfo::SongInfo()
{
w = new NC::Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, NC::brNone);
}
: Screen(NC::Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, NC::brNone))
{ }
void SongInfo::resize()
{
size_t x_offset, width;
getWindowResizeParams(x_offset, width);
w->resize(width, MainHeight);
w->moveTo(x_offset, MainStartY);
w.resize(width, MainHeight);
w.moveTo(x_offset, MainStartY);
hasToBeResized = 0;
}
@@ -91,10 +90,10 @@ void SongInfo::switchTo()
myOldScreen = myScreen;
myScreen = this;
w->clear();
w->reset();
w.clear();
w.reset();
PrepareSong(*s);
w->flush();
w.flush();
// redraw header after we're done with the file, since reading it from disk
// takes a bit of time and having header updated before content of a window
@@ -112,24 +111,24 @@ void SongInfo::PrepareSong(MPD::Song &s)
TagLib::FileRef f(path_to_file.c_str());
# endif // HAVE_TAGLIB_H
*w << NC::fmtBold << Config.color1 << L"Filename: " << NC::fmtBoldEnd << Config.color2 << s.getName() << '\n' << NC::clEnd;
*w << NC::fmtBold << L"Directory: " << NC::fmtBoldEnd << Config.color2;
ShowTag(*w, s.getDirectory());
*w << L"\n\n" << NC::clEnd;
*w << NC::fmtBold << L"Length: " << NC::fmtBoldEnd << Config.color2 << s.getLength() << '\n' << NC::clEnd;
w << NC::fmtBold << Config.color1 << L"Filename: " << NC::fmtBoldEnd << Config.color2 << s.getName() << '\n' << NC::clEnd;
w << NC::fmtBold << L"Directory: " << NC::fmtBoldEnd << Config.color2;
ShowTag(w, s.getDirectory());
w << L"\n\n" << NC::clEnd;
w << NC::fmtBold << L"Length: " << NC::fmtBoldEnd << Config.color2 << s.getLength() << '\n' << NC::clEnd;
# ifdef HAVE_TAGLIB_H
if (!f.isNull())
{
*w << NC::fmtBold << L"Bitrate: " << NC::fmtBoldEnd << Config.color2 << f.audioProperties()->bitrate() << L" kbps\n" << NC::clEnd;
*w << NC::fmtBold << L"Sample rate: " << NC::fmtBoldEnd << Config.color2 << f.audioProperties()->sampleRate() << L" Hz\n" << NC::clEnd;
*w << NC::fmtBold << L"Channels: " << NC::fmtBoldEnd << Config.color2 << (f.audioProperties()->channels() == 1 ? L"Mono" : L"Stereo") << '\n' << NC::clDefault;
w << NC::fmtBold << L"Bitrate: " << NC::fmtBoldEnd << Config.color2 << f.audioProperties()->bitrate() << L" kbps\n" << NC::clEnd;
w << NC::fmtBold << L"Sample rate: " << NC::fmtBoldEnd << Config.color2 << f.audioProperties()->sampleRate() << L" Hz\n" << NC::clEnd;
w << NC::fmtBold << L"Channels: " << NC::fmtBoldEnd << Config.color2 << (f.audioProperties()->channels() == 1 ? L"Mono" : L"Stereo") << '\n' << NC::clDefault;
}
# endif // HAVE_TAGLIB_H
*w << NC::clDefault;
w << NC::clDefault;
for (const Metadata *m = Tags; m->Name; ++m)
{
*w << NC::fmtBold << '\n' << ToWString(m->Name) << L": " << NC::fmtBoldEnd;
ShowTag(*w, s.getTags(m->Get, Config.tags_separator));
w << NC::fmtBold << '\n' << ToWString(m->Name) << L": " << NC::fmtBoldEnd;
ShowTag(w, s.getTags(m->Get, Config.tags_separator));
}
}

View File

@@ -24,7 +24,7 @@
#include "screen.h"
#include "song.h"
struct SortPlaylistDialog : public Screen< NC::Menu< std::pair<std::string, MPD::Song::GetFunction> > >
struct SortPlaylistDialog : public Screen<NC::Menu< std::pair<std::string, MPD::Song::GetFunction> > *>
{
SortPlaylistDialog();
@@ -56,8 +56,8 @@ private:
size_t m_height;
size_t m_width;
const ScreenType::Item::Type m_sort_entry;
const ScreenType::Item::Type m_cancel_entry;
const std::remove_pointer<ScreenType>::type::Item::Type m_sort_entry;
const std::remove_pointer<ScreenType>::type::Item::Type m_cancel_entry;
};
extern SortPlaylistDialog *mySortPlaylistDialog;

View File

@@ -641,7 +641,7 @@ void TagEditor::mouseButtonPressed(MEVENT me)
enterPressed();
}
else
Screen<NC::Window>::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
}
}
else if (w == FParser || w == FParserHelper)
@@ -662,7 +662,7 @@ void TagEditor::mouseButtonPressed(MEVENT me)
enterPressed();
}
else
Screen<NC::Window>::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
}
else if (FParserHelper->hasCoords(me.x, me.y))
{
@@ -673,7 +673,7 @@ void TagEditor::mouseButtonPressed(MEVENT me)
else
return;
}
scrollpadMouseButtonPressed(FParserHelper, me);
scrollpadMouseButtonPressed(*FParserHelper, me);
}
}
else if (!Dirs->empty() && Dirs->hasCoords(me.x, me.y))
@@ -689,7 +689,7 @@ void TagEditor::mouseButtonPressed(MEVENT me)
spacePressed();
}
else
Screen<NC::Window>::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
Tags->clear();
}
else if (!TagTypes->empty() && TagTypes->hasCoords(me.x, me.y))
@@ -714,7 +714,7 @@ void TagEditor::mouseButtonPressed(MEVENT me)
enterPressed();
}
else
Screen<NC::Window>::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
}
else if (!Tags->empty() && Tags->hasCoords(me.x, me.y))
{
@@ -728,7 +728,7 @@ void TagEditor::mouseButtonPressed(MEVENT me)
enterPressed();
}
else
Screen<NC::Window>::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
}
}

View File

@@ -33,7 +33,7 @@
#include "regex_filter.h"
#include "screen.h"
struct TagEditor : public Screen<NC::Window>, public Filterable, public HasColumns, public HasSongs, public Searchable
struct TagEditor : public Screen<NC::Window *>, public Filterable, public HasColumns, public HasSongs, public Searchable
{
TagEditor();

View File

@@ -167,7 +167,7 @@ void TinyTagEditor::mouseButtonPressed(MEVENT me)
}
}
else
Screen< NC::Menu<NC::Buffer> >::mouseButtonPressed(me);
Screen<ScreenType>::mouseButtonPressed(me);
}
void TinyTagEditor::SetEdited(const MPD::Song &s)

View File

@@ -28,7 +28,7 @@
#include "mutable_song.h"
#include "screen.h"
struct TinyTagEditor : public Screen< NC::Menu<NC::Buffer> >
struct TinyTagEditor : public Screen<NC::Menu<NC::Buffer> *>
{
TinyTagEditor();

View File

@@ -32,7 +32,7 @@
# include <fftw3.h>
#endif
struct Visualizer : public Screen<NC::Window>
struct Visualizer : public Screen<NC::Window *>
{
Visualizer();

View File

@@ -127,33 +127,93 @@ Window::Window(size_t startx,
keypad(m_window, 1);
}
Window::Window(const Window &w) : m_window(dupwin(w.m_window)),
m_border_window(dupwin(w.m_border_window)),
m_start_x(w.m_start_x),
m_start_y(w.m_start_y),
m_width(w.m_width),
m_height(w.m_height),
m_window_timeout(w.m_window_timeout),
m_color(w.m_color),
m_bg_color(w.m_bg_color),
m_base_color(w.m_base_color),
m_base_bg_color(w.m_base_bg_color),
m_border(w.m_border),
m_get_string_helper(w.m_get_string_helper),
m_title(w.m_title),
m_color_stack(w.m_color_stack),
m_history(w.m_history),
m_bold_counter(w.m_bold_counter),
m_underline_counter(w.m_underline_counter),
m_reverse_counter(w.m_reverse_counter),
m_alt_charset_counter(w.m_alt_charset_counter)
Window::Window(const Window &rhs)
: m_window(dupwin(rhs.m_window))
, m_border_window(dupwin(rhs.m_border_window))
, m_start_x(rhs.m_start_x)
, m_start_y(rhs.m_start_y)
, m_width(rhs.m_width)
, m_height(rhs.m_height)
, m_window_timeout(rhs.m_window_timeout)
, m_color(rhs.m_color)
, m_bg_color(rhs.m_bg_color)
, m_base_color(rhs.m_base_color)
, m_base_bg_color(rhs.m_base_bg_color)
, m_border(rhs.m_border)
, m_get_string_helper(rhs.m_get_string_helper)
, m_title(rhs.m_title)
, m_color_stack(rhs.m_color_stack)
, m_input_queue(rhs.m_input_queue)
, m_fds(rhs.m_fds)
, m_history(rhs.m_history ? new std::list<std::wstring>(*rhs.m_history) : 0)
, m_bold_counter(rhs.m_bold_counter)
, m_underline_counter(rhs.m_underline_counter)
, m_reverse_counter(rhs.m_reverse_counter)
, m_alt_charset_counter(rhs.m_alt_charset_counter)
{
}
Window::Window(Window &&rhs)
: m_window(rhs.m_window)
, m_border_window(rhs.m_border_window)
, m_start_x(rhs.m_start_x)
, m_start_y(rhs.m_start_y)
, m_width(rhs.m_width)
, m_height(rhs.m_height)
, m_window_timeout(rhs.m_window_timeout)
, m_color(rhs.m_color)
, m_bg_color(rhs.m_bg_color)
, m_base_color(rhs.m_base_color)
, m_base_bg_color(rhs.m_base_bg_color)
, m_border(rhs.m_border)
, m_get_string_helper(rhs.m_get_string_helper)
, m_title(std::move(rhs.m_title))
, m_color_stack(std::move(rhs.m_color_stack))
, m_input_queue(std::move(rhs.m_input_queue))
, m_fds(std::move(rhs.m_fds))
, m_history(rhs.m_history)
, m_bold_counter(rhs.m_bold_counter)
, m_underline_counter(rhs.m_underline_counter)
, m_reverse_counter(rhs.m_reverse_counter)
, m_alt_charset_counter(rhs.m_alt_charset_counter)
{
rhs.m_window = 0;
rhs.m_border_window = 0;
rhs.m_history = 0;
}
Window &Window::operator=(Window rhs)
{
std::swap(m_window, rhs.m_window);
std::swap(m_border_window, rhs.m_border_window);
std::swap(m_start_x, rhs.m_start_x);
std::swap(m_start_y, rhs.m_start_y);
std::swap(m_width, rhs.m_width);
std::swap(m_height, rhs.m_height);
std::swap(m_window_timeout, rhs.m_window_timeout);
std::swap(m_color, rhs.m_color);
std::swap(m_bg_color, rhs.m_bg_color);
std::swap(m_base_color, rhs.m_base_color);
std::swap(m_base_bg_color, rhs.m_base_bg_color);
std::swap(m_border, rhs.m_border);
std::swap(m_get_string_helper, rhs.m_get_string_helper);
std::swap(m_title, rhs.m_title);
std::swap(m_color_stack, rhs.m_color_stack);
std::swap(m_input_queue, rhs.m_input_queue);
std::swap(m_fds, rhs.m_fds);
std::swap(m_history, rhs.m_history);
std::swap(m_bold_counter, rhs.m_bold_counter);
std::swap(m_underline_counter, rhs.m_underline_counter);
std::swap(m_reverse_counter, rhs.m_reverse_counter);
std::swap(m_alt_charset_counter, rhs.m_alt_charset_counter);
return *this;
}
Window::~Window()
{
delwin(m_window);
delwin(m_border_window);
delete m_history;
}
void Window::setColor(Color fg, Color bg)

View File

@@ -163,6 +163,8 @@ struct XY
/// Main class of NCurses namespace, used as base for other specialized windows
struct Window
{
Window() : m_window(0), m_border_window(0), m_history(0) { }
/// Constructs an empty window with given parameters
/// @param startx X position of left upper corner of constructed window
/// @param starty Y position of left upper corner of constructed window
@@ -174,11 +176,10 @@ struct Window
Window(size_t startx, size_t starty, size_t width, size_t height,
const std::string &title, Color color, Border border);
/// Copies thw window
/// @param w copied window
Window(const Window &w);
Window(const Window &rhs);
Window(Window &&rhs);
Window &operator=(Window w);
/// Destroys the window and frees memory
virtual ~Window();
/// Allows for direct access to internal WINDOW pointer in case there