1 /***************************************************************************
2 * Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com) *
3 * This file is part of kdenlive. See www.kdenlive.org. *
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 ***************************************************************************/
12 This abstract widget is a proof that abstract things sometimes *are* useful.
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)
20 The layer order is as follows:
25 ---------------------------
30 ---------------------------
35 ---------------------------
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).
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.
43 Note: Widgets deriving from this class should connect slotActiveMonitorChanged
44 to the appropriate signal.
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.
51 #ifndef ABSTRACTSCOPEWIDGET_H
52 #define ABSTRACTSCOPEWIDGET_H
62 class AbstractScopeWidget : public QWidget
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;
71 virtual QString widgetName() const = 0;
76 Monitor *m_projMonitor;
77 Monitor *m_clipMonitor;
78 Render *m_activeRender;
80 /** The context menu. Feel free to add new entries in your implementation. */
82 QAction *m_aAutoRefresh;
85 /** Offset from the widget's borders */
91 QImage m_imgBackground;
94 ///// Unimplemented Methods /////
96 /** Where on the widget we can paint in */
97 virtual QRect scopeRect() = 0;
99 /** @brief HUD renderer.
100 Must emit signalHUDRenderingFinished().
102 virtual QImage renderHUD() = 0;
103 /** @brief Scope renderer. Must emit signalScopeRenderingFinished(). */
104 virtual QImage renderScope() = 0;
105 /** @brief Background renderer. Must emit signalBackgroundRenderingFinished(). */
106 virtual QImage renderBackground() = 0;
108 /** Must return true if the HUD layer depends on the input monitor.
109 If it does not, then it does not need to be re-calculated when
110 a new frame from the monitor is incoming. */
111 virtual bool isHUDDependingOnInput() const = 0;
112 /** @see isHUDDependingOnInput() */
113 virtual bool isScopeDependingOnInput() const = 0;
114 /** @see isHUDDependingOnInput() */
115 virtual bool isBackgroundDependingOnInput() const = 0;
119 void mouseReleaseEvent(QMouseEvent *);
120 void paintEvent(QPaintEvent *);
121 void resizeEvent(QResizeEvent *);
124 void signalHUDRenderingFinished(uint mseconds);
125 void signalScopeRenderingFinished(uint mseconds);
126 void signalBackgroundRenderingFinished(uint mseconds);
130 /** Counts the number of frames that have been rendered in the active monitor.
131 The frame number will be reset when the calculation starts for the current frame. */
132 QAtomicInt m_newHUDFrames;
133 QAtomicInt m_newScopeFrames;
134 QAtomicInt m_newBackgroundFrames;
136 /** Counts the number of updates that, unlike new frames, force a recalculation
137 of the scope, like for example a resize event. */
138 QAtomicInt m_newHUDUpdates;
139 QAtomicInt m_newScopeUpdates;
140 QAtomicInt m_newBackgroundUpdates;
142 QSemaphore m_semaphoreHUD;
143 QSemaphore m_semaphoreScope;
144 QSemaphore m_semaphoreBackground;
146 QFuture<QImage> m_threadHUD;
147 QFuture<QImage> m_threadScope;
148 QFuture<QImage> m_threadBackground;
150 bool initialDimensionUpdateDone;
151 void prodHUDThread();
152 void prodScopeThread();
153 void prodBackgroundThread();
156 /** @brief Must be called when the active monitor has shown a new frame.
157 This slot must be connected in the implementing class, it is *not*
158 done in this abstract class. */
159 void slotActiveMonitorChanged(bool isClipMonitor);
160 void customContextMenuRequested(const QPoint &pos);
161 void slotRenderZoneUpdated();
162 void slotHUDRenderingFinished(uint mseconds);
163 void slotScopeRenderingFinished(uint mseconds);
164 void slotBackgroundRenderingFinished(uint mseconds);
168 #endif // ABSTRACTSCOPEWIDGET_H