1 /*****************************************************************************
2  * controller.hpp : Controller for the main interface
3  ****************************************************************************
4  * Copyright (C) 2006-2008 the VideoLAN team
5  * $Id: 25d4f4b00cf5ab1dfb7a29dff41875cc1e5f34af $
6  *
7  * Authors: Jean-Baptiste Kempf <jb@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23 
24 #ifndef QVLC_CONTROLLER_H_
25 #define QVLC_CONTROLLER_H_
26 
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30 
31 #include "qt.hpp"
32 
33 #include <QFrame>
34 #include <QString>
35 #include <QSizeGrip>
36 
37 #define MAIN_TB1_DEFAULT "64;39;64;38;65"
38 #define MAIN_TB2_DEFAULT "0-2;64;3;1;4;64;7;9;64;10;20;19;64-4;37;65;35-4"
39 #define ADV_TB_DEFAULT "12;11;13;14"
40 #define INPT_TB_DEFAULT "43;33-4;44"
41 #define FSC_TB_DEFAULT "0-2;64;3;1;4;64;37;64;38;64;8;65;25;35-4;34"
42 
43 #define I_PLAY_TOOLTIP N_("Play\nIf the playlist is empty, open a medium")
44 
45 class QBoxLayout;
46 class QHBoxLayout;
47 
48 class QAbstractButton;
49 class QToolButton;
50 
51 class WidgetListing;
52 
53 class QSignalMapper;
54 class QTimer;
55 
56 typedef enum buttonType_e
57 {
58     PLAY_BUTTON,
59     STOP_BUTTON,
60     OPEN_BUTTON,
61     PREV_SLOW_BUTTON,
62     NEXT_FAST_BUTTON,
63     SLOWER_BUTTON,
64     FASTER_BUTTON,
65     FULLSCREEN_BUTTON,
66     DEFULLSCREEN_BUTTON,
67     EXTENDED_BUTTON,
68     PLAYLIST_BUTTON,
69     SNAPSHOT_BUTTON,
70     RECORD_BUTTON,
71     ATOB_BUTTON,
72     FRAME_BUTTON,
73     REVERSE_BUTTON,
74     SKIP_BACK_BUTTON,
75     SKIP_FW_BUTTON,
76     QUIT_BUTTON,
77     RANDOM_BUTTON,
78     LOOP_BUTTON,
79     INFO_BUTTON,
80     PREVIOUS_BUTTON,
81     NEXT_BUTTON,
82     OPEN_SUB_BUTTON,
83     FULLWIDTH_BUTTON,
84     BUTTON_MAX,
85 
86     SPLITTER = 0x20,
87     INPUT_SLIDER,
88     TIME_LABEL,
89     VOLUME,
90     VOLUME_SPECIAL,
91     MENU_BUTTONS,
92     TELETEXT_BUTTONS,
93     ADVANCED_CONTROLLER,
94     PLAYBACK_BUTTONS,
95     ASPECT_RATIO_COMBOBOX,
96     SPEED_LABEL,
97     TIME_LABEL_ELAPSED,
98     TIME_LABEL_REMAINING,
99     SPECIAL_MAX,
100 
101     WIDGET_SPACER = 0x40,
102     WIDGET_SPACER_EXTEND,
103     WIDGET_MAX,
104 } buttonType_e;
105 
106 
107 static const char* const nameL[BUTTON_MAX] = { N_("Play"), N_("Stop"), N_("Open"),
108     N_("Previous / Backward"), N_("Next / Forward"), N_("Slower"), N_("Faster"), N_("Fullscreen"),
109     N_("De-Fullscreen"), N_("Extended panel"), N_("Playlist"), N_("Snapshot"),
110     N_("Record"), N_("A→B Loop"), N_("Frame By Frame"), N_("Trickplay Reverse"),
111     N_("Step backward" ), N_("Step forward"), N_("Quit"), N_("Random"),
112     N_("Loop / Repeat"), N_("Information"), N_("Previous"), N_("Next"),
113     N_("Open subtitles"), N_("Dock fullscreen controller")
114 };
115 static const char* const tooltipL[BUTTON_MAX] = { I_PLAY_TOOLTIP,
116     N_("Stop playback"), N_("Open a medium"),
117     N_("Previous media in the playlist, skip backward when held"),
118     N_("Next media in the playlist, skip forward when held"), N_("Slower"), N_("Faster"),
119     N_("Toggle the video in fullscreen"), N_("Toggle the video out fullscreen"),
120     N_("Show extended settings" ), N_( "Toggle playlist" ),
121     N_( "Take a snapshot" ), N_( "Record" ),
122     N_( "Loop from point A to point B continuously." ), N_("Frame by frame"),
123     N_("Reverse"), N_("Step backward"), N_("Step forward"), N_("Quit"),
124     N_("Random"), N_("Change the loop and repeat modes"), N_("Information"),
125     N_("Previous media in the playlist"), N_("Next media in the playlist"),
126     N_("Open subtitle file"),
127     N_("Dock/undock fullscreen controller to/from bottom of screen"),
128 };
129 static const QString iconL[BUTTON_MAX] ={ ":/toolbar/play_b.svg", ":/toolbar/stop_b.svg",
130     ":/toolbar/eject.svg", ":/toolbar/previous_b.svg", ":/toolbar/next_b.svg",
131     ":/toolbar/slower.svg", ":/toolbar/faster.svg", ":/toolbar/fullscreen.svg",
132     ":/toolbar/defullscreen.svg", ":/toolbar/extended.svg", ":/toolbar/playlist.svg",
133     ":/toolbar/snapshot.svg", ":/toolbar/record.svg", ":/toolbar/atob_nob.svg",
134     ":/toolbar/frame.svg", ":/toolbar/reverse.svg", ":/toolbar/skip_back.svg",
135     ":/toolbar/skip_fw.svg", ":/toolbar/clear.svg", ":/buttons/playlist/shuffle_on.svg",
136     ":/buttons/playlist/repeat_all.svg", ":/menu/info.svg",
137     ":/toolbar/previous_b.svg", ":/toolbar/next_b.svg", ":/toolbar/eject.svg", ":/toolbar/space.svg"
138 };
139 
140 enum
141 {
142    WIDGET_NORMAL = 0x0,
143    WIDGET_FLAT   = 0x1,
144    WIDGET_BIG    = 0x2,
145    WIDGET_SHINY  = 0x4,
146 };
147 
148 class AdvControlsWidget;
149 class AbstractController : public QFrame
150 {
151     friend class WidgetListing; /* For ToolBar Edition HACKS */
152 
153     Q_OBJECT
154 public:
155     AbstractController( intf_thread_t  *_p_i, QWidget *_parent = 0 );
156 
157 protected:
158     intf_thread_t       *p_intf;
159 
160     QSignalMapper       *toolbarActionsMapper;
161     QBoxLayout          *controlLayout;
162     /* Change to BoxLayout if both dir are needed */
163 
164     AdvControlsWidget   *advControls;
165 
166     void parseAndCreate( const QString& config, QBoxLayout *controlLayout );
167 
168     virtual void createAndAddWidget( QBoxLayout *controlLayout, int i_index,
169                                      buttonType_e i_type, int i_option );
170 
171     QWidget *createWidget( buttonType_e, int options = WIDGET_NORMAL );
172 private:
173     static void setupButton( QAbstractButton * );
174     QFrame *discFrame();
175     QFrame *telexFrame();
176     void applyAttributes( QToolButton *, bool b_flat, bool b_big );
177 
178     QHBoxLayout         *buttonGroupLayout;
179 protected slots:
180     virtual void setStatus( int );
181 
182 signals:
183     void inputExists( bool ); /// This might be useful in the IM ?
184     void inputPlaying( bool ); /// This might be useful in the IM ?
185     void inputIsRecordable( bool ); /// same ?
186     void inputIsTrickPlayable( bool ); /// same ?
187 };
188 
189 /* Advanced Button Bar */
190 class AdvControlsWidget : public AbstractController
191 {
192     Q_OBJECT
193 public:
194     AdvControlsWidget( intf_thread_t *, QWidget *_parent = 0 );
195 };
196 
197 /* Slider Bar */
198 class InputControlsWidget : public AbstractController
199 {
200     Q_OBJECT
201 public:
202     InputControlsWidget( intf_thread_t * , QWidget *_parent = 0 );
203 };
204 
205 /* Button Bar */
206 class ControlsWidget : public AbstractController
207 {
208     Q_OBJECT
209 public:
210     /* p_intf, advanced control visible or not, blingbling or not */
211     ControlsWidget( intf_thread_t *_p_i, bool b_advControls,
212                     QWidget *_parent = 0 );
213 
setGripVisible(bool b_visible)214     void setGripVisible( bool b_visible )
215     { grip->setVisible( b_visible ); }
216 
217 protected:
218     friend class MainInterface;
219 
220     bool b_advancedVisible;
221 
222 private:
223     QSizeGrip *grip;
224 
225 protected slots:
226     void toggleAdvanced();
227 
228 signals:
229     void advancedControlsToggled( bool );
230 };
231 
232 
233 /* to trying transparency with fullscreen controller on windows enable that */
234 /* it can be enabled on-non windows systems,
235    but it will be transparent only with composite manager */
236 #define HAVE_TRANSPARENCY 1
237 
238 /* Default value of opacity for FS controller */
239 #define DEFAULT_OPACITY 0.70
240 
241 /* Used to restore the minimum width after a full-width switch */
242 #define FSC_WIDTH 800
243 
244 /***********************************
245  * Fullscreen controller
246  ***********************************/
247 class FullscreenControllerWidget : public AbstractController
248 {
249     Q_OBJECT
250 public:
251     FullscreenControllerWidget( intf_thread_t *, QWidget *_parent = 0  );
252     virtual ~FullscreenControllerWidget();
253 
254     /* Vout */
255     void fullscreenChanged( vout_thread_t *, bool b_fs, int i_timeout );
256     void mouseChanged( vout_thread_t *, int i_mousex, int i_mousey );
257     void toggleFullwidth();
258     void updateFullwidthGeometry( int number );
259     int targetScreen();
260     void setTargetScreen( int );
261 
262 private:
263     static int FullscreenChanged( vlc_object_t *obj,
264                     const char *, vlc_value_t, vlc_value_t new_val, void *data );
265 
266 signals:
267     void keyPressed( QKeyEvent * );
268     void fullscreenChanged( bool );
269 
270 public slots:
271     void setVoutList( vout_thread_t **, int );
272 
273 protected:
274     friend class MainInterface;
275 
276     void mouseMoveEvent( QMouseEvent *event ) Q_DECL_OVERRIDE;
277     void mousePressEvent( QMouseEvent *event ) Q_DECL_OVERRIDE;
278     void mouseReleaseEvent( QMouseEvent *event ) Q_DECL_OVERRIDE;
279     void enterEvent( QEvent *event ) Q_DECL_OVERRIDE;
280     void leaveEvent( QEvent *event ) Q_DECL_OVERRIDE;
281     void keyPressEvent( QKeyEvent *event ) Q_DECL_OVERRIDE;
282 
283     void customEvent( QEvent *event ) Q_DECL_OVERRIDE;
284 
285 private slots:
286     void showFSC();
287     void planHideFSC();
hideFSC()288     void hideFSC() { hide(); }
289     void slowHideFSC();
290     void restoreFSC();
291     void centerFSC( int );
292 
293 private:
294     QTimer *p_hideTimer;
295 #if HAVE_TRANSPARENCY
296     QTimer *p_slowHideTimer;
297     bool b_slow_hide_begin;
298     int  i_slow_hide_timeout;
299     float f_opacity;
300 #endif
301 
302     int i_mouse_last_x, i_mouse_last_y;
303     bool b_mouse_over;
304     int i_screennumber;
305     QRect screenRes;
306     QRect previousScreenRes;
307     QPoint previousPosition;
308 
309     /* List of vouts currently tracked */
310     QList<vout_thread_t *> vout;
311 
312     /* Shared variable between FSC and VLC (protected by a lock) */
313     vlc_mutex_t lock;
314     bool        b_fullscreen;
315     int         i_hide_timeout;  /* FSC hiding timeout, same as mouse hiding timeout */
316     int i_mouse_last_move_x;
317     int i_mouse_last_move_y;
318 
319     bool isWideFSC;
320     int i_sensitivity;
321 
322 #ifdef QT5_HAS_WAYLAND
323     bool b_hasWayland;
324 #endif
325 };
326 
327 #endif
328