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 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.
48 #ifndef ABSTRACTSCOPEWIDGET_H
49 #define ABSTRACTSCOPEWIDGET_H
59 class AbstractScopeWidget : public QWidget
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;
68 virtual QString widgetName() const = 0;
73 Monitor *m_projMonitor;
74 Monitor *m_clipMonitor;
75 Render *m_activeRender;
77 /** The context menu. Feel free to add new entries in your implementation. */
79 QAction *m_aAutoRefresh;
82 /** Offset from the widget's borders */
88 QImage m_imgBackground;
91 ///// Unimplemented Methods /////
93 /** Where on the widget we can paint in */
94 virtual QRect scopeRect() = 0;
96 /** @brief HUD renderer.
97 Must emit signalHUDRenderingFinished().
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;
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;
116 void mouseReleaseEvent(QMouseEvent *);
117 void paintEvent(QPaintEvent *);
118 void resizeEvent(QResizeEvent *);
121 void signalHUDRenderingFinished(uint mseconds);
122 void signalScopeRenderingFinished(uint mseconds);
123 void signalBackgroundRenderingFinished(uint mseconds);
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;
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;
139 QSemaphore m_semaphoreHUD;
140 QSemaphore m_semaphoreScope;
141 QSemaphore m_semaphoreBackground;
143 QFuture<QImage> m_threadHUD;
144 QFuture<QImage> m_threadScope;
145 QFuture<QImage> m_threadBackground;
147 bool initialDimensionUpdateDone;
148 void prodHUDThread();
149 void prodScopeThread();
150 void prodBackgroundThread();
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);
165 #endif // ABSTRACTSCOPEWIDGET_H