]> git.sesse.net Git - kdenlive/blob - src/abstractscopewidget.h
Abstract Scope Widget extended.
[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   If you intend to write an own widget inheriting from this one, please read
44   the comments on the unimplemented methods carefully. They are not only here
45   for optical amusement, but also contain important information.
46  */
47
48 #ifndef ABSTRACTSCOPEWIDGET_H
49 #define ABSTRACTSCOPEWIDGET_H
50
51 #include <QtCore>
52 #include <QWidget>
53
54 class QMenu;
55
56 class Monitor;
57 class Render;
58
59 class AbstractScopeWidget : public QWidget
60 {
61     Q_OBJECT
62
63 public:
64     AbstractScopeWidget(Monitor *projMonitor, Monitor *clipMonitor, QWidget *parent = 0);
65     virtual ~AbstractScopeWidget(); // Must be virtual because of inheritance, to avoid memory leaks
66     QPalette m_scopePalette;
67
68     virtual QString widgetName() const = 0;
69
70 protected:
71     ///// Variables /////
72
73     Monitor *m_projMonitor;
74     Monitor *m_clipMonitor;
75     Render *m_activeRender;
76
77     /** The context menu. Feel free to add new entries in your implementation. */
78     QMenu *m_menu;
79     QAction *m_aAutoRefresh;
80     QAction *m_aRealtime;
81
82     /** Offset from the widget's borders */
83     const uchar offset;
84
85     QRect m_scopeRect;
86     QImage m_imgHUD;
87     QImage m_imgScope;
88     QImage m_imgBackground;
89
90
91     ///// Unimplemented Methods /////
92
93     /** Where on the widget we can paint in */
94     virtual QRect scopeRect() = 0;
95
96     /** @brief HUD renderer.
97       Must emit signalHUDRenderingFinished().
98       Should */
99     virtual QImage renderHUD() = 0;
100     /** @brief Scope renderer. Must emit signalScopeRenderingFinished(). */
101     virtual QImage renderScope() = 0;
102     /** @brief Background renderer. Must emit signalBackgroundRenderingFinished(). */
103     virtual QImage renderBackground() = 0;
104
105     /** Must return true if the HUD layer depends on the input monitor.
106       If it does not, then it does not need to be re-calculated when
107       a new frame from the monitor is incoming. */
108     virtual bool isHUDDependingOnInput() const = 0;
109     /** @see isHUDDependingOnInput() */
110     virtual bool isScopeDependingOnInput() const = 0;
111     /** @see isHUDDependingOnInput() */
112     virtual bool isBackgroundDependingOnInput() const = 0;
113
114     ///// Methods /////
115
116     void mouseReleaseEvent(QMouseEvent *);
117     void paintEvent(QPaintEvent *);
118     void resizeEvent(QResizeEvent *);
119
120 signals:
121     void signalHUDRenderingFinished(uint mseconds);
122     void signalScopeRenderingFinished(uint mseconds);
123     void signalBackgroundRenderingFinished(uint mseconds);
124
125 private:
126
127     /** Counts the number of frames that have been rendered in the active monitor.
128       The frame number will be reset when the calculation starts for the current frame. */
129     QAtomicInt m_newHUDFrames;
130     QAtomicInt m_newScopeFrames;
131     QAtomicInt m_newBackgroundFrames;
132
133     /** Counts the number of updates that, unlike new frames, force a recalculation
134       of the scope, like for example a resize event. */
135     QAtomicInt m_newHUDUpdates;
136     QAtomicInt m_newScopeUpdates;
137     QAtomicInt m_newBackgroundUpdates;
138
139     QSemaphore m_semaphoreHUD;
140     QSemaphore m_semaphoreScope;
141     QSemaphore m_semaphoreBackground;
142
143     QFuture<QImage> m_threadHUD;
144     QFuture<QImage> m_threadScope;
145     QFuture<QImage> m_threadBackground;
146
147     bool initialDimensionUpdateDone;
148     void prodHUDThread();
149     void prodScopeThread();
150     void prodBackgroundThread();
151
152 private slots:
153     /** @brief Must be called when the active monitor has shown a new frame.
154       This slot must be connected in the implementing class, it is *not*
155       done in this abstract class. */
156     void slotActiveMonitorChanged(bool isClipMonitor);
157     void customContextMenuRequested(const QPoint &pos);
158     void slotRenderZoneUpdated();
159     void slotHUDRenderingFinished(uint mseconds);
160     void slotScopeRenderingFinished(uint mseconds);
161     void slotBackgroundRenderingFinished(uint mseconds);
162
163 };
164
165 #endif // ABSTRACTSCOPEWIDGET_H