]> git.sesse.net Git - kdenlive/blob - src/abstractscopewidget.h
Remember render settings for project (zone, guides,...):
[kdenlive] / src / abstractscopewidget.h
1 /***************************************************************************
2  *   Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com)      *
3  *   This file is part of kdenlive. See www.kdenlive.org.                  *
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
11 /**
12   This abstract widget is a proof that abstract things sometimes *are* useful.
13
14   The widget expects three layers which
15   * Will be painted on top of each other on each update
16   * Are rendered in a separate thread so that the UI is not blocked
17   * Are rendered only if necessary (e.g., if a layer does not depend
18     on input images, it will not be re-rendered for incoming frames)
19
20   The layer order is as follows:
21      _____________________
22     /                     \
23    /      HUD Layer        \
24   /                         \
25   ---------------------------
26      _____________________
27     /                     \
28    /     Scope Layer       \
29   /                         \
30   ---------------------------
31      _____________________
32     /                     \
33    /   Background Layer    \
34   /                         \
35   ---------------------------
36
37   Colors of Scope Widgets are defined in here (and thus don't need to be
38   re-defined in the implementation of the widget's .ui file).
39
40   The custom context menu already contains entries, like for enabling auto-
41   refresh. It can certainly be extended in the implementation of the widget.
42
43   Note: Widgets deriving from this class should connect slotActiveMonitorChanged
44   to the appropriate signal.
45
46   If you intend to write an own widget inheriting from this one, please read
47   the comments on the unimplemented methods carefully. They are not only here
48   for optical amusement, but also contain important information.
49  */
50
51 #ifndef ABSTRACTSCOPEWIDGET_H
52 #define ABSTRACTSCOPEWIDGET_H
53
54 #include <QtCore>
55 #include <QWidget>
56
57 class QMenu;
58
59 class Monitor;
60 class Render;
61
62 class AbstractScopeWidget : public QWidget
63 {
64     Q_OBJECT
65
66 public:
67     AbstractScopeWidget(Monitor *projMonitor, Monitor *clipMonitor, QWidget *parent = 0);
68     virtual ~AbstractScopeWidget(); // Must be virtual because of inheritance, to avoid memory leaks
69     QPalette m_scopePalette;
70
71     ///// Unimplemented /////
72
73     virtual QString widgetName() const = 0;
74
75 protected:
76     ///// Variables /////
77
78     Monitor *m_projMonitor;
79     Monitor *m_clipMonitor;
80     Render *m_activeRender;
81
82
83     /** The context menu. Feel free to add new entries in your implementation. */
84     QMenu *m_menu;
85
86     /** Enables auto refreshing of the scope.
87         This is when a new frame is shown on the active monitor.
88         Resize events always force a recalculation. */
89     QAction *m_aAutoRefresh;
90
91     /** Realtime rendering. Should be disabled if it is not supported.
92         Use the accelerationFactor variable passed to the render functions as a hint of
93         how many times faster the scope should be calculated. */
94     QAction *m_aRealtime;
95
96
97     /** Offset from the widget's borders */
98     const uchar offset;
99
100     /** The rect on the widget we're painting in.
101         Can be used by the implementing widget, e.g. in the render methods.
102         Is updated when necessary (size changes). */
103     QRect m_scopeRect;
104
105     /** Images storing the calculated layers. Will be used on repaint events. */
106     QImage m_imgHUD;
107     QImage m_imgScope;
108     QImage m_imgBackground;
109
110     /** The acceleration factors can be accessed also by other renderer tasks,
111         e.g. to display the scope's acceleration factor in the HUD renderer. */
112     int m_accelFactorHUD;
113     int m_accelFactorScope;
114     int m_accelFactorBackground;
115
116
117     ///// Unimplemented Methods /////
118
119     /** Where on the widget we can paint in.
120         May also update other variables that depend on the widget's size.  */
121     virtual QRect scopeRect() = 0;
122
123     /** @brief HUD renderer. Must emit signalHUDRenderingFinished(). @see renderScope */
124     virtual QImage renderHUD(uint accelerationFactor) = 0;
125     /** @brief Scope renderer. Must emit signalScopeRenderingFinished()
126         when calculation has finished, to allow multi-threading.
127         accelerationFactor hints how much faster than usual the calculation should be accomplished, if possible. */
128     virtual QImage renderScope(uint accelerationFactor) = 0;
129     /** @brief Background renderer. Must emit signalBackgroundRenderingFinished(). @see renderScope */
130     virtual QImage renderBackground(uint accelerationFactor) = 0;
131
132     /** Must return true if the HUD layer depends on the input monitor.
133         If it does not, then it does not need to be re-calculated when
134         a new frame from the monitor is incoming. */
135     virtual bool isHUDDependingOnInput() const = 0;
136     /** @see isHUDDependingOnInput() */
137     virtual bool isScopeDependingOnInput() const = 0;
138     /** @see isHUDDependingOnInput() */
139     virtual bool isBackgroundDependingOnInput() const = 0;
140
141     ///// Can be reimplemented /////
142     /** Calculates the acceleration factor to be used by the render thread.
143         This method can be refined in the subclass if required. */
144     virtual uint calculateAccelFactorHUD(uint oldMseconds, uint oldFactor);
145     virtual uint calculateAccelFactorScope(uint oldMseconds, uint oldFactor);
146     virtual uint calculateAccelFactorBackground(uint oldMseconds, uint oldFactor);
147
148     ///// Reimplemented /////
149
150     void mouseReleaseEvent(QMouseEvent *);
151     void paintEvent(QPaintEvent *);
152     void raise();
153     void resizeEvent(QResizeEvent *);
154     void showEvent(QShowEvent *);
155
156 protected slots:
157     /** Forces an update of all layers. */
158     void forceUpdate();
159     void forceUpdateHUD();
160     void forceUpdateScope();
161     void forceUpdateBackground();
162     void slotAutoRefreshToggled(bool);
163
164 signals:
165     /** mseconds represent the time taken for the calculation,
166         accelerationFactor the acceleration factor that has been used. */
167     void signalHUDRenderingFinished(uint mseconds, uint accelerationFactor);
168     void signalScopeRenderingFinished(uint mseconds, uint accelerationFactor);
169     void signalBackgroundRenderingFinished(uint mseconds, uint accelerationFactor);
170
171 private:
172
173     /** Counts the number of frames that have been rendered in the active monitor.
174       The frame number will be reset when the calculation starts for the current frame. */
175     QAtomicInt m_newHUDFrames;
176     QAtomicInt m_newScopeFrames;
177     QAtomicInt m_newBackgroundFrames;
178
179     /** Counts the number of updates that, unlike new frames, force a recalculation
180       of the scope, like for example a resize event. */
181     QAtomicInt m_newHUDUpdates;
182     QAtomicInt m_newScopeUpdates;
183     QAtomicInt m_newBackgroundUpdates;
184
185     /** The semaphores ensure that the QFutures for the HUD/Scope/Background threads cannot
186       be assigned a new thread while it is still running. (Could cause deadlocks and other
187       nasty things known from parallelism. */
188     QSemaphore m_semaphoreHUD;
189     QSemaphore m_semaphoreScope;
190     QSemaphore m_semaphoreBackground;
191
192     QFuture<QImage> m_threadHUD;
193     QFuture<QImage> m_threadScope;
194     QFuture<QImage> m_threadBackground;
195
196     bool initialDimensionUpdateDone;
197     void prodHUDThread();
198     void prodScopeThread();
199     void prodBackgroundThread();
200
201
202 private slots:
203     /** @brief Must be called when the active monitor has shown a new frame.
204       This slot must be connected in the implementing class, it is *not*
205       done in this abstract class. */
206     void slotActiveMonitorChanged(bool isClipMonitor);
207     void customContextMenuRequested(const QPoint &pos);
208     void slotRenderZoneUpdated();
209     void slotHUDRenderingFinished(uint mseconds, uint accelerationFactor);
210     void slotScopeRenderingFinished(uint mseconds, uint accelerationFactor);
211     void slotBackgroundRenderingFinished(uint mseconds, uint accelerationFactor);
212
213     /** Resets the acceleration factors to 1 when realtime rendering is disabled. */
214     void slotResetRealtimeFactor(bool realtimeChecked);
215
216 };
217
218 #endif // ABSTRACTSCOPEWIDGET_H