option parser: make assign_default_once work with non-copyable types
[ncmpcpp.git] / src / screen.h
blob758ce6bcfd8ad6670e517c07003f30055ea29b51
1 /***************************************************************************
2 * Copyright (C) 2008-2014 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 genericMouseButtonPressed(NC::Window &w, MEVENT me);
29 void scrollpadMouseButtonPressed(NC::Scrollpad &w, MEVENT me);
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 struct BaseScreen
36 BaseScreen() : hasToBeResized(false) { }
37 virtual ~BaseScreen() { }
39 /// @see Screen::isActiveWindow()
40 virtual bool isActiveWindow(const NC::Window &w_) = 0;
42 /// @see Screen::activeWindow()
43 virtual void *activeWindow() = 0;
45 /// @see Screen::refresh()
46 virtual void refresh() = 0;
48 /// @see Screen::refreshWindow()
49 virtual void refreshWindow() = 0;
51 /// @see Screen::scroll()
52 virtual void scroll(NC::Scroll where) = 0;
54 /// Method used for switching to screen
55 virtual void switchTo() = 0;
57 /// Method that should resize screen
58 /// if requested by hasToBeResized
59 virtual void resize() = 0;
61 /// @return ncurses timeout parameter for the screen
62 virtual int windowTimeout() = 0;
64 /// @return title of the screen
65 virtual std::wstring title() = 0;
67 /// @return type of the screen
68 virtual ScreenType type() = 0;
70 /// If the screen contantly has to update itself
71 /// somehow, it should be called by this function.
72 virtual void update() = 0;
74 /// Invoked after Enter was pressed
75 virtual void enterPressed() = 0;
77 /// Invoked after Space was pressed
78 virtual void spacePressed() = 0;
80 /// @see Screen::mouseButtonPressed()
81 virtual void mouseButtonPressed(MEVENT me) = 0;
83 /// @return true if screen is mergable, ie. can be "proper" subwindow
84 /// if one of the screens is locked. Screens that somehow resemble popups
85 /// will want to return false here.
86 virtual bool isMergable() = 0;
88 /// Locks current screen.
89 /// @return true if lock was successful, false otherwise. Note that
90 /// if there is already locked screen, it'll not overwrite it.
91 bool lock();
93 /// Should be set to true each time screen needs resize
94 bool hasToBeResized;
96 /// Unlocks a screen, ie. hides merged window (if there is one set).
97 static void unlock();
99 protected:
100 /// @return true if screen can be locked. Note that returning
101 /// false here doesn't neccesarily mean that screen is also not
102 /// mergable (eg. lyrics screen is not lockable since that wouldn't
103 /// make much sense, but it's perfectly fine to merge it).
104 virtual bool isLockable() = 0;
106 /// Gets X offset and width of current screen to be used eg. in resize() function.
107 /// @param adjust_locked_screen indicates whether this function should
108 /// automatically adjust locked screen's dimensions (if there is one set)
109 /// if current screen is going to be subwindow.
110 void getWindowResizeParams(size_t &x_offset, size_t &width, bool adjust_locked_screen = true);
113 void applyToVisibleWindows(std::function<void(BaseScreen *)> f);
114 void updateInactiveScreen(BaseScreen *screen_to_be_set);
115 bool isVisible(BaseScreen *screen);
117 /// Class that all screens should derive from. It provides basic interface
118 /// for the screen to be working properly and assumes that we didn't forget
119 /// about anything vital.
121 template <typename WindowT> struct Screen : public BaseScreen
123 typedef WindowT WindowType;
124 typedef typename std::add_lvalue_reference<WindowType>::type WindowReference;
126 private:
127 template <bool IsPointer, typename Result> struct getObject { };
128 template <typename Result> struct getObject<true, Result> {
129 static Result apply(WindowType w) { return *w; }
131 template <typename Result> struct getObject<false, Result> {
132 static Result apply(WindowReference w) { return w; }
135 typedef getObject<
136 std::is_pointer<WindowT>::value,
137 typename std::add_lvalue_reference<
138 typename std::remove_pointer<WindowT>::type
139 >::type
140 > Accessor;
142 public:
143 Screen() { }
144 Screen(WindowT w_) : w(w_) { }
146 virtual ~Screen() { }
148 virtual bool isActiveWindow(const NC::Window &w_) OVERRIDE {
149 return &Accessor::apply(w) == &w_;
152 /// Since some screens contain more that one window
153 /// it's useful to determine the one that is being
154 /// active
155 /// @return address to window object cast to void *
156 virtual void *activeWindow() OVERRIDE {
157 return &Accessor::apply(w);
160 /// Refreshes whole screen
161 virtual void refresh() OVERRIDE {
162 Accessor::apply(w).display();
165 /// Refreshes active window of the screen
166 virtual void refreshWindow() OVERRIDE {
167 Accessor::apply(w).display();
170 /// Scrolls the screen by given amount of lines and
171 /// if fancy scrolling feature is disabled, enters the
172 /// loop that holds main loop until user releases the key
173 /// @param where indicates where one wants to scroll
174 virtual void scroll(NC::Scroll where) OVERRIDE {
175 Accessor::apply(w).scroll(where);
178 /// @return timeout parameter used for the screen (in ms)
179 /// @default 500
180 virtual int windowTimeout() OVERRIDE {
181 return 500;
184 /// Invoked after there was one of mouse buttons pressed
185 /// @param me struct that contains coords of where the click
186 /// had its place and button actions
187 virtual void mouseButtonPressed(MEVENT me) OVERRIDE {
188 genericMouseButtonPressed(Accessor::apply(w), me);
191 /// @return currently active window
192 WindowReference main() {
193 return w;
196 protected:
197 /// Template parameter that should indicate the main type
198 /// of window used by the screen. What is more, it should
199 /// always be assigned to the currently active window (if
200 /// acreen contains more that one)
201 WindowT w;
204 /// Specialization for Screen<Scrollpad>::mouseButtonPressed that should
205 /// not scroll whole page, but rather a few lines (the number of them is
206 /// defined in the config)
207 template <> inline void Screen<NC::Scrollpad>::mouseButtonPressed(MEVENT me) {
208 scrollpadMouseButtonPressed(w, me);
211 #endif // NCMPCPP_SCREEN_H