visualizer: refresh screen immediately after clearing it
[ncmpcpp.git] / src / screen.h
blob24ef6b55953ae6ab955efcbd7206003e4306ccdf
1 /***************************************************************************
2 * Copyright (C) 2008-2010 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #ifndef _SCREEN_H
22 #define _SCREEN_H
24 #include "window.h"
25 #include "menu.h"
26 #include "mpdpp.h"
27 #include "helpers.h"
28 #include "settings.h"
29 #include "status.h"
31 /// An interface for various instantiations of Screen template class. Since C++ doesn't like
32 /// comparison of two different instantiations of the same template class we need the most
33 /// basic class to be non-template to allow it.
34 ///
35 class BasicScreen
37 public:
38 /// Initializes all variables to zero
39 ///
40 BasicScreen() : hasToBeResized(0), isInitialized(0) { }
42 virtual ~BasicScreen() { }
44 /// @see Screen::ActiveWindow()
45 ///
46 virtual void *ActiveWindow() = 0;
48 /// Method used for switching to screen
49 ///
50 virtual void SwitchTo() = 0;
52 /// Method that should resize screen
53 /// if requested by hasToBeResized
54 ///
55 virtual void Resize() = 0;
57 /// @return title of the screen
58 ///
59 virtual std::basic_string<my_char_t> Title() = 0;
61 /// If the screen contantly has to update itself
62 /// somehow, it should be called by this function.
63 ///
64 virtual void Update() { }
66 /// @see Screen::Refresh()
67 ///
68 virtual void Refresh() = 0;
70 /// @see Screen::RefreshWindow()
71 ///
72 virtual void RefreshWindow() = 0;
74 /// see Screen::ReadKey()
75 ///
76 virtual void ReadKey(int &key) = 0;
78 /// @see Screen::Scroll()
79 ///
80 virtual void Scroll(Where where, const int key[2] = 0) = 0;
82 /// Invoked after Enter was pressed
83 ///
84 virtual void EnterPressed() = 0;
86 /// Invoked after Space was pressed
87 ///
88 virtual void SpacePressed() = 0;
90 /// @see Screen::MouseButtonPressed()
91 ///
92 virtual void MouseButtonPressed(MEVENT) { }
94 /// @return pointer to currently selected song in the screen
95 /// (if screen provides one) or null pointer otherwise.
96 ///
97 virtual MPD::Song *CurrentSong() { return 0; }
99 /// @return true if the screen allows selecting items, false otherwise
101 virtual bool allowsSelection() = 0;
103 /// Reverses selection. Does nothing by default since pure
104 /// virtual allowsSelection() should remind of this function
105 /// to be defined
107 virtual void ReverseSelection() { }
109 /// Gets selected songs' positions from the screen
110 /// @param v vector to be filled with positions
112 virtual void GetSelectedSongs(GNUC_UNUSED MPD::SongList &v) { }
114 /// Applies a filter to the screen
115 virtual void ApplyFilter(GNUC_UNUSED const std::string &filter) { }
117 /// @return pointer to instantiation of Menu template class
118 /// cast to List if available or null pointer otherwise
120 virtual List *GetList() = 0;
122 /// When this is overwritten with a function returning true, the
123 /// screen will be used in tab switching.
125 virtual bool isTabbable() { return false; }
127 /// Should be set to true each time screen needs resize
129 bool hasToBeResized;
131 protected:
132 /// Since screens initialization is lazy, we don't want to do
133 /// this in the constructor. This function should be invoked
134 /// only once and after that isInitialized flag has to be set
135 /// to true to somehow avoid next attempt of initialization.
137 virtual void Init() = 0;
139 /// Flag that inditates whether the screen is initialized or not
141 bool isInitialized;
144 /// Class that all screens should derive from. It provides basic interface
145 /// for the screen to be working properly and assumes that we didn't forget
146 /// about anything vital.
148 template <typename WindowType> class Screen : public BasicScreen
150 public:
151 Screen() : w(0) { }
152 virtual ~Screen() { }
154 /// Since some screens contain more that one window
155 /// it's useful to determine the one that is being
156 /// active
157 /// @return address to window object cast to void *
159 virtual void *ActiveWindow();
161 /// @return pointer to currently active window
163 WindowType *Main();
165 /// Refreshes whole screen
167 virtual void Refresh();
169 /// Refreshes active window of the screen
171 virtual void RefreshWindow();
173 /// Reads a key from the screen
175 virtual void ReadKey(int &key);
177 /// Scrolls the screen by given amount of lines and
178 /// if fancy scrolling feature is disabled, enters the
179 /// loop that holds main loop until user releases the key
180 /// @param where indicates where one wants to scroll
181 /// @param key needed if fancy scrolling is disabled to
182 /// define the conditional for while loop
184 virtual void Scroll(Where where, const int key[2] = 0);
186 /// Invoked after there was one of mouse buttons pressed
187 /// @param me struct that contains coords of where the click
188 /// had its place and button actions
190 virtual void MouseButtonPressed(MEVENT me);
192 protected:
193 /// Template parameter that should indicate the main type
194 /// of window used by the screen. What is more, it should
195 /// always be assigned to the currently active window (if
196 /// acreen contains more that one)
198 WindowType *w;
201 template <typename WindowType> void *Screen<WindowType>::ActiveWindow()
203 return w;
206 template <typename WindowType> WindowType *Screen<WindowType>::Main()
208 return w;
211 template <typename WindowType> void Screen<WindowType>::Refresh()
213 w->Display();
216 template <typename WindowType> void Screen<WindowType>::RefreshWindow()
218 w->Display();
221 template <typename WindowType> void Screen<WindowType>::ReadKey(int &key)
223 w->ReadKey(key);
226 template <typename WindowType> void Screen<WindowType>::Scroll(Where where, const int key[2])
228 if (!Config.fancy_scrolling && key)
230 int in = key[0];
231 w->SetTimeout(50);
232 while (Keypressed(in, key))
234 TraceMpdStatus();
235 w->Scroll(where);
236 w->Refresh();
237 ReadKey(in);
239 w->SetTimeout(ncmpcpp_window_timeout);
241 else
242 w->Scroll(where);
245 template <typename WindowType> void Screen<WindowType>::MouseButtonPressed(MEVENT me)
247 if (me.bstate & BUTTON2_PRESSED)
249 Scroll(wPageDown);
251 else if (me.bstate & BUTTON4_PRESSED)
253 Scroll(wPageUp);
257 /// Specialization for Screen<Scrollpad>::MouseButtonPressed, that should
258 /// not scroll whole page, but rather a few lines (the number of them is
259 /// defined in the config)
261 template <> inline void Screen<Scrollpad>::MouseButtonPressed(MEVENT me)
263 if (me.bstate & BUTTON2_PRESSED)
265 for (size_t i = 0; i < Config.lines_scrolled; ++i)
266 Scroll(wDown);
268 else if (me.bstate & BUTTON4_PRESSED)
270 for (size_t i = 0; i < Config.lines_scrolled; ++i)
271 Scroll(wUp);
275 #endif