1 /***************************************************************************
2 * Copyright (C) 2008-2014 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
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. *
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. *
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
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.
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 /// Invoked after Enter was pressed
77 virtual void enterPressed() = 0;
79 /// @see Screen::mouseButtonPressed()
80 virtual void mouseButtonPressed(MEVENT me
) = 0;
82 /// @return true if screen can be locked. Note that returning
83 /// false here doesn't neccesarily mean that screen is also not
84 /// mergable (eg. lyrics screen is not lockable since that wouldn't
85 /// make much sense, but it's perfectly fine to merge it).
86 virtual bool isLockable() = 0;
88 /// @return true if screen is mergable, ie. can be "proper" subwindow
89 /// if one of the screens is locked. Screens that somehow resemble popups
90 /// will want to return false here.
91 virtual bool isMergable() = 0;
93 /// Locks current screen.
94 /// @return true if lock was successful, false otherwise. Note that
95 /// if there is already locked screen, it'll not overwrite it.
98 /// Should be set to true each time screen needs resize
101 /// Unlocks a screen, ie. hides merged window (if there is one set).
102 static void unlock();
104 const static int defaultWindowTimeout
= 500;
107 /// Gets X offset and width of current screen to be used eg. in resize() function.
108 /// @param adjust_locked_screen indicates whether this function should
109 /// automatically adjust locked screen's dimensions (if there is one set)
110 /// if current screen is going to be subwindow.
111 void getWindowResizeParams(size_t &x_offset
, size_t &width
, bool adjust_locked_screen
= true);
114 void applyToVisibleWindows(std::function
<void(BaseScreen
*)> f
);
115 void updateInactiveScreen(BaseScreen
*screen_to_be_set
);
116 bool isVisible(BaseScreen
*screen
);
118 /// Class that all screens should derive from. It provides basic interface
119 /// for the screen to be working properly and assumes that we didn't forget
120 /// about anything vital.
122 template <typename WindowT
> struct Screen
: public BaseScreen
124 typedef WindowT WindowType
;
125 typedef typename
std::add_lvalue_reference
<
127 >::type WindowReference
;
128 typedef typename
std::add_lvalue_reference
<
129 typename
std::add_const
<WindowType
>::type
130 >::type ConstWindowReference
;
133 template <bool IsPointer
, typename Result
, typename ConstResult
>
135 static Result
&apply(WindowReference w
) { return w
; }
136 static ConstResult
&constApply(ConstWindowReference w
) { return w
; }
138 template <typename Result
, typename ConstResult
>
139 struct getObject
<true, Result
, ConstResult
> {
140 static Result
&apply(WindowType w
) { return *w
; }
141 static ConstResult
&constApply(const WindowType w
) { return *w
; }
145 std::is_pointer
<WindowT
>::value
,
146 typename
std::remove_pointer
<WindowT
>::type
,
147 typename
std::add_const
<
148 typename
std::remove_pointer
<WindowT
>::type
154 Screen(WindowT w_
) : w(w_
) { }
156 virtual ~Screen() { }
158 virtual bool isActiveWindow(const NC::Window
&w_
) const OVERRIDE
{
159 return &Accessor::constApply(w
) == &w_
;
162 /// Since some screens contain more that one window
163 /// it's useful to determine the one that is being
165 /// @return address to window object cast to void *
166 virtual NC::Window
*activeWindow() OVERRIDE
{
167 return &Accessor::apply(w
);
169 virtual const NC::Window
*activeWindow() const OVERRIDE
{
170 return &Accessor::constApply(w
);
173 /// Refreshes whole screen
174 virtual void refresh() OVERRIDE
{
175 Accessor::apply(w
).display();
178 /// Refreshes active window of the screen
179 virtual void refreshWindow() OVERRIDE
{
180 Accessor::apply(w
).display();
183 /// Scrolls the screen by given amount of lines and
184 /// if fancy scrolling feature is disabled, enters the
185 /// loop that holds main loop until user releases the key
186 /// @param where indicates where one wants to scroll
187 virtual void scroll(NC::Scroll where
) OVERRIDE
{
188 Accessor::apply(w
).scroll(where
);
191 /// @return timeout parameter used for the screen (in ms)
192 /// @default defaultWindowTimeout
193 virtual int windowTimeout() OVERRIDE
{
194 return defaultWindowTimeout
;
197 /// Invoked after there was one of mouse buttons pressed
198 /// @param me struct that contains coords of where the click
199 /// had its place and button actions
200 virtual void mouseButtonPressed(MEVENT me
) OVERRIDE
{
201 genericMouseButtonPressed(Accessor::apply(w
), me
);
204 /// @return currently active window
205 WindowReference
main() {
208 ConstWindowReference
main() const {
213 /// Template parameter that should indicate the main type
214 /// of window used by the screen. What is more, it should
215 /// always be assigned to the currently active window (if
216 /// acreen contains more that one)
220 /// Specialization for Screen<Scrollpad>::mouseButtonPressed that should
221 /// not scroll whole page, but rather a few lines (the number of them is
222 /// defined in the config)
223 template <> inline void Screen
<NC::Scrollpad
>::mouseButtonPressed(MEVENT me
) {
224 scrollpadMouseButtonPressed(w
, me
);
227 #endif // NCMPCPP_SCREEN_H