actions: use unique_ptr for storing actions
[ncmpcpp.git] / src / screen.h
blob87fe91152a8d51f41aa7af8973b011f191167e8c
1 /***************************************************************************
2 * Copyright (C) 2008-2016 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 NCMPCPP_SCREEN_H
22 #define NCMPCPP_SCREEN_H
24 #include "menu.h"
25 #include "scrollpad.h"
26 #include "screen_type.h"
28 void drawSeparator(int x);
29 void genericMouseButtonPressed(NC::Window &w, MEVENT me);
30 void scrollpadMouseButtonPressed(NC::Scrollpad &w, MEVENT me);
32 /// An interface for various instantiations of Screen template class. Since C++ doesn't like
33 /// comparison of two different instantiations of the same template class we need the most
34 /// basic class to be non-template to allow it.
35 struct BaseScreen
37 BaseScreen() : hasToBeResized(false) { }
38 virtual ~BaseScreen() { }
40 /// @see Screen::isActiveWindow()
41 virtual bool isActiveWindow(const NC::Window &w_) const = 0;
43 /// @see Screen::activeWindow()
44 virtual NC::Window *activeWindow() = 0;
45 virtual const NC::Window *activeWindow() const = 0;
47 /// @see Screen::refresh()
48 virtual void refresh() = 0;
50 /// @see Screen::refreshWindow()
51 virtual void refreshWindow() = 0;
53 /// @see Screen::scroll()
54 virtual void scroll(NC::Scroll where) = 0;
56 /// Method used for switching to screen
57 virtual void switchTo() = 0;
59 /// Method that should resize screen
60 /// if requested by hasToBeResized
61 virtual void resize() = 0;
63 /// @return ncurses timeout parameter for the screen
64 virtual int windowTimeout() = 0;
66 /// @return title of the screen
67 virtual std::wstring title() = 0;
69 /// @return type of the screen
70 virtual ScreenType type() = 0;
72 /// If the screen contantly has to update itself
73 /// somehow, it should be called by this function.
74 virtual void update() = 0;
76 /// @see Screen::mouseButtonPressed()
77 virtual void mouseButtonPressed(MEVENT me) = 0;
79 /// @return true if screen can be locked. Note that returning
80 /// false here doesn't neccesarily mean that screen is also not
81 /// mergable (eg. lyrics screen is not lockable since that wouldn't
82 /// make much sense, but it's perfectly fine to merge it).
83 virtual bool isLockable() = 0;
85 /// @return true if screen is mergable, ie. can be "proper" subwindow
86 /// if one of the screens is locked. Screens that somehow resemble popups
87 /// will want to return false here.
88 virtual bool isMergable() = 0;
90 /// Locks current screen.
91 /// @return true if lock was successful, false otherwise. Note that
92 /// if there is already locked screen, it'll not overwrite it.
93 bool lock();
95 /// Should be set to true each time screen needs resize
96 bool hasToBeResized;
98 /// Unlocks a screen, ie. hides merged window (if there is one set).
99 static void unlock();
101 const static int defaultWindowTimeout = 500;
103 protected:
104 /// Gets X offset and width of current screen to be used eg. in resize() function.
105 /// @param adjust_locked_screen indicates whether this function should
106 /// automatically adjust locked screen's dimensions (if there is one set)
107 /// if current screen is going to be subwindow.
108 void getWindowResizeParams(size_t &x_offset, size_t &width, bool adjust_locked_screen = true);
111 void applyToVisibleWindows(std::function<void(BaseScreen *)> f);
112 void updateInactiveScreen(BaseScreen *screen_to_be_set);
113 bool isVisible(BaseScreen *screen);
115 /// Class that all screens should derive from. It provides basic interface
116 /// for the screen to be working properly and assumes that we didn't forget
117 /// about anything vital.
119 template <typename WindowT> struct Screen : public BaseScreen
121 typedef WindowT WindowType;
122 typedef typename std::add_lvalue_reference<
123 WindowType
124 >::type WindowReference;
125 typedef typename std::add_lvalue_reference<
126 typename std::add_const<WindowType>::type
127 >::type ConstWindowReference;
129 private:
130 template <bool IsPointer, typename Result, typename ConstResult>
131 struct getObject {
132 static Result &apply(WindowReference w) { return w; }
133 static ConstResult &constApply(ConstWindowReference w) { return w; }
135 template <typename Result, typename ConstResult>
136 struct getObject<true, Result, ConstResult> {
137 static Result &apply(WindowType w) { return *w; }
138 static ConstResult &constApply(const WindowType w) { return *w; }
141 typedef getObject<
142 std::is_pointer<WindowT>::value,
143 typename std::remove_pointer<WindowT>::type,
144 typename std::add_const<
145 typename std::remove_pointer<WindowT>::type
146 >::type
147 > Accessor;
149 public:
150 Screen() { }
151 Screen(WindowT w_) : w(w_) { }
153 virtual ~Screen() { }
155 virtual bool isActiveWindow(const NC::Window &w_) const override {
156 return &Accessor::constApply(w) == &w_;
159 /// Since some screens contain more that one window
160 /// it's useful to determine the one that is being
161 /// active
162 /// @return address to window object cast to void *
163 virtual NC::Window *activeWindow() override {
164 return &Accessor::apply(w);
166 virtual const NC::Window *activeWindow() const override {
167 return &Accessor::constApply(w);
170 /// Refreshes whole screen
171 virtual void refresh() override {
172 Accessor::apply(w).display();
175 /// Refreshes active window of the screen
176 virtual void refreshWindow() override {
177 Accessor::apply(w).display();
180 /// Scrolls the screen by given amount of lines and
181 /// if fancy scrolling feature is disabled, enters the
182 /// loop that holds main loop until user releases the key
183 /// @param where indicates where one wants to scroll
184 virtual void scroll(NC::Scroll where) override {
185 Accessor::apply(w).scroll(where);
188 /// @return timeout parameter used for the screen (in ms)
189 /// @default defaultWindowTimeout
190 virtual int windowTimeout() override {
191 return defaultWindowTimeout;
194 /// Invoked after there was one of mouse buttons pressed
195 /// @param me struct that contains coords of where the click
196 /// had its place and button actions
197 virtual void mouseButtonPressed(MEVENT me) override {
198 genericMouseButtonPressed(Accessor::apply(w), me);
201 /// @return currently active window
202 WindowReference main() {
203 return w;
205 ConstWindowReference main() const {
206 return w;
209 protected:
210 /// Template parameter that should indicate the main type
211 /// of window used by the screen. What is more, it should
212 /// always be assigned to the currently active window (if
213 /// acreen contains more that one)
214 WindowT w;
217 /// Specialization for Screen<Scrollpad>::mouseButtonPressed that should
218 /// not scroll whole page, but rather a few lines (the number of them is
219 /// defined in the config)
220 template <> inline void Screen<NC::Scrollpad>::mouseButtonPressed(MEVENT me) {
221 scrollpadMouseButtonPressed(w, me);
224 #endif // NCMPCPP_SCREEN_H