ListWindow: replace callback function with abstract class
authorMax Kellermann <max@musicpd.org>
Sun, 25 Feb 2018 08:57:44 +0000 (09:57 +0100)
committerMax Kellermann <max@musicpd.org>
Sat, 17 Mar 2018 07:39:50 +0000 (08:39 +0100)
14 files changed:
src/AlbumListPage.cxx
src/AlbumListPage.hxx
src/ArtistListPage.cxx
src/ArtistListPage.hxx
src/ListRenderer.hxx [new file with mode: 0644]
src/ListWindow.cxx
src/ListWindow.hxx
src/screen_browser.cxx
src/screen_browser.hxx
src/screen_find.cxx
src/screen_find.hxx
src/screen_help.cxx
src/screen_outputs.cxx
src/screen_queue.cxx

index ce71de1..7005427 100644 (file)
@@ -128,21 +128,20 @@ AlbumListPage::Reload(struct mpdclient &c)
  * the parent directory, and at the end, there's the item "All tracks"
  * to view the tracks of all albums.
  */
-static void
-paint_album_callback(WINDOW *w, unsigned i,
-                    gcc_unused unsigned y, unsigned width,
-                    bool selected, const void *data)
+void
+AlbumListPage::PaintListItem(WINDOW *w, unsigned i,
+                            gcc_unused unsigned y, unsigned width,
+                            bool selected) const
 {
-       const auto &list = *(const std::vector<std::string> *)data;
        const char *p;
        char *q = nullptr;
 
        if (i == 0)
                p = "..";
-       else if (i == list.size() + 1)
+       else if (i == album_list.size() + 1)
                p = _("All tracks");
        else
-               p = q = utf8_to_locale(list[i - 1].c_str());
+               p = q = utf8_to_locale(album_list[i - 1].c_str());
 
        screen_browser_paint_directory(w, width, selected, p);
        g_free(q);
@@ -151,7 +150,7 @@ paint_album_callback(WINDOW *w, unsigned i,
 void
 AlbumListPage::Paint() const
 {
-       lw.Paint(paint_album_callback, &album_list);
+       lw.Paint(*this);
 }
 
 const char *
@@ -249,7 +248,7 @@ AlbumListPage::OnCommand(struct mpdclient &c, command_t cmd)
        case CMD_LIST_JUMP:
                screen_jump(screen, &lw,
                            AlbumListCallback, &album_list,
-                           paint_album_callback, &album_list);
+                           this);
                SetDirty();
                return true;
 
index 7871c78..8e2f7c1 100644 (file)
 #define NCMPC_ALBUM_LIST_PAGE_HXX
 
 #include "ListPage.hxx"
+#include "ListRenderer.hxx"
 
 #include <vector>
 #include <string>
 
 class ScreenManager;
 
-class AlbumListPage final : public ListPage {
+class AlbumListPage final : public ListPage, ListRenderer {
        ScreenManager &screen;
        std::vector<std::string> album_list;
        std::string artist;
@@ -66,6 +67,10 @@ public:
        void Update(struct mpdclient &c, unsigned events) override;
        bool OnCommand(struct mpdclient &c, command_t cmd) override;
        const char *GetTitle(char *s, size_t size) const override;
+
+       /* virtual methods from class ListRenderer */
+       void PaintListItem(WINDOW *w, unsigned i, unsigned y, unsigned width,
+                          bool selected) const override;
 };
 
 #endif
index bac116e..3844678 100644 (file)
@@ -100,23 +100,19 @@ ArtistListPage::Reload(struct mpdclient &c)
        LoadArtistList(c);
 }
 
-/**
- * Paint one item in the artist list.
- */
-static void
-paint_artist_callback(WINDOW *w, unsigned i,
-                     gcc_unused unsigned y, unsigned width,
-                     bool selected, const void *data)
+void
+ArtistListPage::PaintListItem(WINDOW *w, unsigned i,
+                             gcc_unused unsigned y, unsigned width,
+                             bool selected) const
 {
-       const auto &list = *(const std::vector<std::string> *)data;
        screen_browser_paint_directory(w, width, selected,
-                                      Utf8ToLocale(list[i].c_str()).c_str());
+                                      Utf8ToLocale(artist_list[i].c_str()).c_str());
 }
 
 void
 ArtistListPage::Paint() const
 {
-       lw.Paint(paint_artist_callback, &artist_list);
+       lw.Paint(*this);
 }
 
 const char *
@@ -203,7 +199,7 @@ ArtistListPage::OnCommand(struct mpdclient &c, command_t cmd)
        case CMD_LIST_JUMP:
                screen_jump(screen, &lw,
                            screen_artist_lw_callback, &artist_list,
-                           paint_artist_callback, &artist_list);
+                           this);
                SetDirty();
                return true;
 
index 075177c..7bad8a0 100644 (file)
 #define NCMPC_ARTIST_LIST_PAGE_HXX
 
 #include "ListPage.hxx"
+#include "ListRenderer.hxx"
 
 #include <vector>
 #include <string>
 
 class ScreenManager;
 
-class ArtistListPage final : public ListPage {
+class ArtistListPage final : public ListPage, ListRenderer {
        ScreenManager &screen;
        std::vector<std::string> artist_list;
 
@@ -53,6 +54,10 @@ public:
        void Update(struct mpdclient &c, unsigned events) override;
        bool OnCommand(struct mpdclient &c, command_t cmd) override;
        const char *GetTitle(char *s, size_t size) const override;
+
+       /* virtual methods from class ListRenderer */
+       void PaintListItem(WINDOW *w, unsigned i, unsigned y, unsigned width,
+                          bool selected) const override;
 };
 
 #endif
diff --git a/src/ListRenderer.hxx b/src/ListRenderer.hxx
new file mode 100644 (file)
index 0000000..7ba24ed
--- /dev/null
@@ -0,0 +1,32 @@
+/* ncmpc (Ncurses MPD Client)
+ * (c) 2004-2018 The Music Player Daemon Project
+ * Project homepage: http://musicpd.org
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef LIST_RENDERER_HXX
+#define LIST_RENDERER_HXX
+
+#include "ncmpc_curses.h"
+
+class ListRenderer {
+public:
+       virtual void PaintListItem(WINDOW *w, unsigned i,
+                                  unsigned y, unsigned width,
+                                  bool selected) const = 0;
+};
+
+#endif
index f4142c1..112cd96 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include "ListWindow.hxx"
+#include "ListRenderer.hxx"
 #include "config.h"
 #include "options.hxx"
 #include "charset.hxx"
@@ -335,8 +336,7 @@ ListWindow::Paint(list_window_callback_fn_t callback,
 }
 
 void
-ListWindow::Paint(list_window_paint_callback_t paint_callback,
-                 const void *callback_data) const
+ListWindow::Paint(const ListRenderer &renderer) const
 {
        bool show_cursor = !hide_cursor &&
                (!options.hardware_cursor || range_selection);
@@ -356,8 +356,8 @@ ListWindow::Paint(list_window_paint_callback_t paint_callback,
                bool is_selected = show_cursor &&
                        range.Contains(start + i);
 
-               paint_callback(w, start + i, i, size.width,
-                              is_selected, callback_data);
+               renderer.PaintListItem(w, start + i, i, size.width,
+                                      is_selected);
        }
 
        if (options.hardware_cursor && selected >= start &&
index 468b970..ea11ffd 100644 (file)
 #include "ncmpc_curses.h"
 #include "Size.hxx"
 
+class ListRenderer;
+
 typedef const char *
 (*list_window_callback_fn_t)(unsigned i, void *data);
 
-typedef void
-(*list_window_paint_callback_t)(WINDOW *w, unsigned i,
-                               unsigned y, unsigned width,
-                               bool selected,
-                               const void *data);
-
 /**
  * The bounds of a range selection, see list_window_get_range().
  */
@@ -125,8 +121,7 @@ struct ListWindow {
        void Paint(list_window_callback_fn_t callback,
                   void *callback_data) const;
 
-       void Paint(list_window_paint_callback_t paint_callback,
-                  const void *callback_data) const;
+       void Paint(const ListRenderer &renderer) const;
 
        /** perform basic list window commands (movement) */
        bool HandleCommand(command_t cmd);
index 3f1667c..a683a8e 100644 (file)
@@ -387,7 +387,7 @@ FileListPage::OnCommand(struct mpdclient &c, command_t cmd)
        case CMD_LIST_JUMP:
                screen_jump(screen, &lw,
                            browser_lw_callback, filelist,
-                           PaintRow, this);
+                           this);
                SetDirty();
                return true;
 
@@ -481,16 +481,14 @@ screen_browser_paint_playlist(WINDOW *w, unsigned width,
 }
 
 void
-FileListPage::PaintRow(WINDOW *w, unsigned i,
-                      unsigned y, unsigned width,
-                      bool selected, const void *data)
+FileListPage::PaintListItem(WINDOW *w, unsigned i,
+                           unsigned y, unsigned width,
+                           bool selected) const
 {
-       const auto &page = *(const FileListPage *) data;
+       assert(filelist != nullptr);
+       assert(i < filelist->size());
 
-       assert(page.filelist != nullptr);
-       assert(i < page.filelist->size());
-
-       const auto &entry = (*page.filelist)[i];
+       const auto &entry = (*filelist)[i];
        const struct mpd_entity *entity = entry.entity;
        if (entity == nullptr) {
                screen_browser_paint_directory(w, width, selected, "..");
@@ -518,7 +516,7 @@ FileListPage::PaintRow(WINDOW *w, unsigned i,
        case MPD_ENTITY_TYPE_SONG:
                paint_song_row(w, y, width, selected, highlight,
                               mpd_entity_get_song(entity), nullptr,
-                              page.song_format);
+                              song_format);
                break;
 
        case MPD_ENTITY_TYPE_PLAYLIST:
@@ -537,5 +535,5 @@ FileListPage::PaintRow(WINDOW *w, unsigned i,
 void
 FileListPage::Paint() const
 {
-       lw.Paint(PaintRow, this);
+       lw.Paint(*this);
 }
index 45e1406..1502c22 100644 (file)
@@ -24,6 +24,7 @@
 #include "config.h"
 #include "ncmpc_curses.h"
 #include "ListPage.hxx"
+#include "ListRenderer.hxx"
 
 struct mpdclient;
 struct MpdQueue;
@@ -31,7 +32,7 @@ class ScreenManager;
 class FileList;
 struct FileListEntry;
 
-class FileListPage : public ListPage {
+class FileListPage : public ListPage, ListRenderer {
 protected:
        ScreenManager &screen;
 
@@ -71,6 +72,11 @@ private:
                             unsigned y, unsigned width,
                             bool selected, const void *data);
 
+       /* virtual methods from class ListRenderer */
+       void PaintListItem(WINDOW *w, unsigned i,
+                          unsigned y, unsigned width,
+                          bool selected) const final;
+
 public:
        /* virtual methods from class Page */
        void Paint() const override;
index 5362cb6..ff3e3c9 100644 (file)
@@ -89,7 +89,7 @@ screen_find(ScreenManager &screen, ListWindow *lw, command_t findcmd,
 void
 screen_jump(ScreenManager &screen, ListWindow *lw,
            list_window_callback_fn_t callback_fn, void *callback_data,
-           list_window_paint_callback_t paint_callback, void *paint_data)
+           const ListRenderer *renderer)
 {
        constexpr size_t WRLN_MAX_LINE_SIZE = 1024;
        int key = 65;
@@ -125,8 +125,8 @@ screen_jump(ScreenManager &screen, ListWindow *lw,
                lw->Jump(callback_fn, callback_data, search_str);
 
                /* repaint the list_window */
-               if (paint_callback != nullptr)
-                       lw->Paint(paint_callback, paint_data);
+               if (renderer != nullptr)
+                       lw->Paint(*renderer);
                else
                        lw->Paint(callback_fn, callback_data);
                wrefresh(lw->w);
index 5b60eb3..872ac0e 100644 (file)
@@ -24,6 +24,7 @@
 #include "ListWindow.hxx"
 
 class ScreenManager;
+class ListRenderer;
 
 /**
  * query user for a string and find it in a list window
@@ -45,6 +46,6 @@ screen_find(ScreenManager &screen, ListWindow *lw,
 void
 screen_jump(ScreenManager &screen, ListWindow *lw,
            list_window_callback_fn_t callback_fn, void *callback_data,
-           list_window_paint_callback_t paint_callback, void *paint_data);
+           const ListRenderer *renderer);
 
 #endif
index a746733..3000b00 100644 (file)
@@ -20,6 +20,7 @@
 #include "screen_help.hxx"
 #include "screen_interface.hxx"
 #include "ListPage.hxx"
+#include "ListRenderer.hxx"
 #include "screen_find.hxx"
 #include "paint.hxx"
 #include "charset.hxx"
@@ -197,7 +198,7 @@ static const struct help_text_row help_text[] = {
 #endif
 };
 
-class HelpPage final : public ListPage {
+class HelpPage final : public ListPage, ListRenderer {
        ScreenManager &screen;
 
 public:
@@ -208,6 +209,11 @@ public:
        }
 
 public:
+       /* virtual methods from class ListRenderer */
+       void PaintListItem(WINDOW *w, unsigned i,
+                          unsigned y, unsigned width,
+                          bool selected) const override;
+
        /* virtual methods from class Page */
        void Paint() const override;
        bool OnCommand(struct mpdclient &c, command_t cmd) override;
@@ -239,11 +245,10 @@ help_init(ScreenManager &screen, WINDOW *w, Size size)
        return new HelpPage(screen, w, size);
 }
 
-static void
-screen_help_paint_callback(WINDOW *w, unsigned i,
-                          unsigned y, unsigned width,
-                          gcc_unused bool selected,
-                          gcc_unused const void *data)
+void
+HelpPage::PaintListItem(WINDOW *w, unsigned i,
+                       unsigned y, unsigned width,
+                       gcc_unused bool selected) const
 {
        const struct help_text_row *row = &help_text[i];
 
@@ -275,7 +280,7 @@ screen_help_paint_callback(WINDOW *w, unsigned i,
 void
 HelpPage::Paint() const
 {
-       lw.Paint(screen_help_paint_callback, nullptr);
+       lw.Paint(*this);
 }
 
 bool
index 6f951dd..ef0bf4a 100644 (file)
@@ -20,6 +20,7 @@
 #include "screen_outputs.hxx"
 #include "screen_interface.hxx"
 #include "ListPage.hxx"
+#include "ListRenderer.hxx"
 #include "screen_status.hxx"
 #include "paint.hxx"
 #include "i18n.h"
@@ -38,7 +39,7 @@ struct OutputDeleter {
        }
 };
 
-class OutputsPage final : public ListPage {
+class OutputsPage final : public ListPage, ListRenderer {
        std::vector<std::unique_ptr<struct mpd_output, OutputDeleter>> items;
 
 public:
@@ -56,6 +57,10 @@ public:
        void Update(struct mpdclient &c, unsigned events) override;
        bool OnCommand(struct mpdclient &c, command_t cmd) override;
        const char *GetTitle(char *s, size_t size) const override;
+
+       /* virtual methods from class ListRenderer */
+       void PaintListItem(WINDOW *w, unsigned i, unsigned y, unsigned width,
+                          bool selected) const override;
 };
 
 bool
@@ -139,12 +144,11 @@ OutputsPage::GetTitle(gcc_unused char *str, gcc_unused size_t size) const
        return _("Outputs");
 }
 
-static void
-screen_outputs_paint_callback(WINDOW *w, unsigned i,
-                             gcc_unused unsigned y, unsigned width,
-                             bool selected, const void *data)
+void
+OutputsPage::PaintListItem(WINDOW *w, unsigned i,
+                          gcc_unused unsigned y, unsigned width,
+                          bool selected) const
 {
-       const auto &items = *(const std::vector<std::unique_ptr<struct mpd_output, OutputDeleter>> *)data;
        assert(i < items.size());
        const auto *output = items[i].get();
 
@@ -157,7 +161,7 @@ screen_outputs_paint_callback(WINDOW *w, unsigned i,
 void
 OutputsPage::Paint() const
 {
-       lw.Paint(screen_outputs_paint_callback, &items);
+       lw.Paint(*this);
 }
 
 void
index fb272e1..89c86c7 100644 (file)
@@ -20,6 +20,7 @@
 #include "screen_queue.hxx"
 #include "screen_interface.hxx"
 #include "ListPage.hxx"
+#include "ListRenderer.hxx"
 #include "screen_file.hxx"
 #include "screen_status.hxx"
 #include "screen_find.hxx"
@@ -55,7 +56,7 @@
 
 #define MAX_SONG_LENGTH 512
 
-class QueuePage final : public ListPage {
+class QueuePage final : public ListPage, ListRenderer {
        ScreenManager &screen;
 
 #ifndef NCMPC_MINI
@@ -103,9 +104,11 @@ private:
        bool OnSongChange(const struct mpd_status *status);
 
        static gboolean OnHideCursorTimer(gpointer data);
-       static void PaintRow(WINDOW *w, unsigned i,
-                            unsigned y, unsigned width,
-                            bool selected, const void *data);
+
+       /* virtual methods from class ListRenderer */
+       void PaintListItem(WINDOW *w, unsigned i,
+                          unsigned y, unsigned width,
+                          bool selected) const override;
 
 public:
        /* virtual methods from class Page */
@@ -374,22 +377,21 @@ QueuePage::GetTitle(char *str, size_t size) const
 }
 
 void
-QueuePage::PaintRow(WINDOW *w, unsigned i, unsigned y, unsigned width,
-                   bool selected, const void *data)
+QueuePage::PaintListItem(WINDOW *w, unsigned i, unsigned y, unsigned width,
+                        bool selected) const
 {
-       const auto &q = *(const QueuePage *)data;
-       assert(q.playlist != nullptr);
-       assert(i < q.playlist->size());
-       const auto &song = (*q.playlist)[i];
+       assert(playlist != nullptr);
+       assert(i < playlist->size());
+       const auto &song = (*playlist)[i];
 
        class hscroll *row_hscroll = nullptr;
 #ifndef NCMPC_MINI
-       row_hscroll = selected && options.scroll && q.lw.selected == i
-               ? &q.hscroll : nullptr;
+       row_hscroll = selected && options.scroll && lw.selected == i
+               ? &hscroll : nullptr;
 #endif
 
        paint_song_row(w, y, width, selected,
-                      (int)mpd_song_get_id(&song) == q.current_song_id,
+                      (int)mpd_song_get_id(&song) == current_song_id,
                       &song, row_hscroll, options.list_format);
 }
 
@@ -401,7 +403,7 @@ QueuePage::Paint() const
                hscroll.Clear();
 #endif
 
-       lw.Paint(PaintRow, this);
+       lw.Paint(*this);
 }
 
 void
@@ -517,7 +519,7 @@ QueuePage::OnCommand(struct mpdclient &c, command_t cmd)
                return true;
        case CMD_LIST_JUMP:
                screen_jump(screen, &lw, screen_queue_lw_callback, &c.playlist,
-                           nullptr, nullptr);
+                           this);
                SaveSelection();
                SetDirty();
                return true;