]> git.sesse.net Git - kdenlive/commitdiff
* Vectorscope added
authorSimon A. Eugster <simon.eu@gmail.com>
Mon, 12 Jul 2010 22:04:38 +0000 (22:04 +0000)
committerSimon A. Eugster <simon.eu@gmail.com>
Mon, 12 Jul 2010 22:04:38 +0000 (22:04 +0000)
* Widgets grouped for more room for the monitors

svn path=/trunk/kdenlive/; revision=4573

src/CMakeLists.txt
src/customtrackview.cpp
src/mainwindow.cpp
src/mainwindow.h
src/renderwidget.cpp
src/renderwidget.h
src/transitionsettings.h
src/vectorscope.cpp [new file with mode: 0644]
src/vectorscope.h [new file with mode: 0644]
src/widgets/vectorscope_ui.ui [new file with mode: 0644]

index c0d4bcd1e5296f26724705c863bc5c0d9611fca5..ff20f2d80e96ae12139da1bf92f091926ebb9c45 100644 (file)
@@ -89,6 +89,7 @@ kde4_add_ui_files(kdenlive_UI
   widgets/timecodedisplay_ui.ui
   widgets/tracksconfigdialog_ui.ui
   widgets/urlval_ui.ui
+  widgets/vectorscope_ui.ui
 )
 
 set(kdenlive_SRCS
@@ -190,6 +191,7 @@ set(kdenlive_SRCS
   timecodedisplay.cpp
   tracksconfigdialog.cpp
   configtrackscommand.cpp
+  vectorscope.cpp
 )
 
 add_definitions( ${KDE4_DEFINITIONS} )
index 4af5b811b1de3cc4b28fd3cef231140f8a7844c7..17c3f0f45eccf348ebae08c7f971398ac9536832 100644 (file)
@@ -700,7 +700,7 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event)
     }
 #if QT_VERSION >= 0x040600
     // Add shadow to dragged item, currently disabled because of painting artifacts
-    //TODO: re-enable when fixed
+    //TODO: re-enable when fixed
     /*QGraphicsDropShadowEffect *eff = new QGraphicsDropShadowEffect();
     eff->setBlurRadius(5);
     eff->setOffset(3, 3);
@@ -1123,7 +1123,7 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event)
     if (m_dragItem && m_dragItem->hasKeyFrames()) {
         /*if (m_moveOpMode == KEYFRAME) {
             // user double clicked on a keyframe, open edit dialog
-            //TODO: update for effects with several values per keyframe
+            //TODO: update for effects with several values per keyframe
             QDialog d(parentWidget());
             Ui::KeyFrameDialog_UI view;
             view.setupUi(&d);
@@ -2132,7 +2132,9 @@ void CustomTrackView::dropEvent(QDropEvent * event)
             if (isLocked) item->setItemLocked(true);
             ItemInfo clipInfo = info;
             clipInfo.track = m_document->tracksCount() - item->track();
-            if (m_document->renderer()->mltInsertClip(clipInfo, item->xml(), item->baseClip()->producer(item->track()), m_scene->editMode() == OVERWRITEEDIT, m_scene->editMode() == INSERTEDIT) == -1) {
+
+            int worked = m_document->renderer()->mltInsertClip(clipInfo, item->xml(), item->baseClip()->producer(item->track()), m_scene->editMode() == OVERWRITEEDIT, m_scene->editMode() == INSERTEDIT);
+            if (worked == -1) {
                 emit displayMessage(i18n("Cannot insert clip in timeline"), ErrorMessage);
                 brokenClips.append(item);
                 continue;
@@ -2159,7 +2161,7 @@ void CustomTrackView::dropEvent(QDropEvent * event)
         setDocumentModified();
 
         /*
-        // debug info
+        // debug info
         QRectF rect(0, 1 * m_tracksHeight + m_tracksHeight / 2, sceneRect().width(), 2);
         QList<QGraphicsItem *> selection = m_scene->items(rect);
         QStringList timelineList;
index 96fe5008850bf4d34a130e2db2ec25803ecb56f7..e6004ae82db805611779fc44072b5e7c10088a9e 100644 (file)
@@ -52,6 +52,7 @@
 #include "kdenlive-config.h"
 #include "cliptranscode.h"
 #include "ui_templateclip_ui.h"
+#include "vectorscope.h"
 
 #include <KApplication>
 #include <KAction>
@@ -140,6 +141,8 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
     m_timelineArea = new KTabWidget(this);
     m_timelineArea->setTabReorderingEnabled(true);
     m_timelineArea->setTabBarHidden(true);
+    m_timelineArea->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
+    m_timelineArea->setMinimumHeight(200);
 
     QToolButton *closeTabButton = new QToolButton;
     connect(closeTabButton, SIGNAL(clicked()), this, SLOT(closeCurrentDocument()));
@@ -158,23 +161,18 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
 
     m_monitorManager = new MonitorManager();
 
+    m_shortcutRemoveFocus = new QShortcut(QKeySequence("Esc"), this);
+    connect(m_shortcutRemoveFocus, SIGNAL(activated()), this, SLOT(slotRemoveFocus()));
+
+
+    /// Add Widgets ///
+
     m_projectListDock = new QDockWidget(i18n("Project Tree"), this);
     m_projectListDock->setObjectName("project_tree");
     m_projectList = new ProjectList(this);
     m_projectListDock->setWidget(m_projectList);
     addDockWidget(Qt::TopDockWidgetArea, m_projectListDock);
 
-    m_shortcutRemoveFocus = new QShortcut(QKeySequence("Esc"), this);
-    connect(m_shortcutRemoveFocus, SIGNAL(activated()), this, SLOT(slotRemoveFocus()));
-
-    m_effectListDock = new QDockWidget(i18n("Effect List"), this);
-    m_effectListDock->setObjectName("effect_list");
-    m_effectList = new EffectsListView();
-
-    //m_effectList = new KListWidget(this);
-    m_effectListDock->setWidget(m_effectList);
-    addDockWidget(Qt::TopDockWidgetArea, m_effectListDock);
-
     m_effectStackDock = new QDockWidget(i18n("Effect Stack"), this);
     m_effectStackDock->setObjectName("effect_stack");
     m_effectStack = new EffectStackView(this);
@@ -187,20 +185,11 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
     m_transitionConfigDock->setWidget(m_transitionConfig);
     addDockWidget(Qt::TopDockWidgetArea, m_transitionConfigDock);
 
-    KdenliveSettings::setCurrent_profile(KdenliveSettings::default_profile());
-    m_fileOpenRecent = KStandardAction::openRecent(this, SLOT(openFile(const KUrl &)), actionCollection());
-    readOptions();
-    m_fileRevert = KStandardAction::revert(this, SLOT(slotRevert()), actionCollection());
-    m_fileRevert->setEnabled(false);
-
-    //slotDetectAudioDriver();
-
     m_clipMonitorDock = new QDockWidget(i18n("Clip Monitor"), this);
     m_clipMonitorDock->setObjectName("clip_monitor");
     m_clipMonitor = new Monitor("clip", m_monitorManager, QString(), this);
     m_clipMonitorDock->setWidget(m_clipMonitor);
     addDockWidget(Qt::TopDockWidgetArea, m_clipMonitorDock);
-    //m_clipMonitor->stop();
 
     m_projectMonitorDock = new QDockWidget(i18n("Project Monitor"), this);
     m_projectMonitorDock->setObjectName("project_monitor");
@@ -219,6 +208,19 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
     connect(m_recMonitor, SIGNAL(showConfigDialog(int, int)), this, SLOT(slotPreferences(int, int)));
 #endif
 
+    m_effectListDock = new QDockWidget(i18n("Effect List"), this);
+    m_effectListDock->setObjectName("effect_list");
+    m_effectList = new EffectsListView();
+    m_effectListDock->setWidget(m_effectList);
+    addDockWidget(Qt::TopDockWidgetArea, m_effectListDock);
+
+    m_vectorscope = new Vectorscope(m_projectMonitor->render, this);
+    m_vectorscopeDock = new QDockWidget(i18n("Vectorscope"), this);
+    m_vectorscopeDock->setObjectName("vectorscope");
+    m_vectorscopeDock->setWidget(m_vectorscope);
+    addDockWidget(Qt::TopDockWidgetArea, m_vectorscopeDock);
+
+
     m_undoViewDock = new QDockWidget(i18n("Undo History"), this);
     m_undoViewDock->setObjectName("undo_history");
     m_undoView = new QUndoView(this);
@@ -234,20 +236,36 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
     //overviewDock->setWidget(m_overView);
     //addDockWidget(Qt::TopDockWidgetArea, overviewDock);
 
+
     setupActions();
-    //tabifyDockWidget(projectListDock, effectListDock);
+
+    /// Tabify Widgets ///
     tabifyDockWidget(m_projectListDock, m_effectStackDock);
     tabifyDockWidget(m_projectListDock, m_transitionConfigDock);
-    //tabifyDockWidget(projectListDock, undoViewDock);
 
 
     tabifyDockWidget(m_clipMonitorDock, m_projectMonitorDock);
 #ifndef Q_WS_MAC
     tabifyDockWidget(m_clipMonitorDock, m_recMonitorDock);
 #endif
+
+    tabifyDockWidget(m_vectorscopeDock, m_undoViewDock);
+    tabifyDockWidget(m_vectorscopeDock, m_effectListDock);
+
+
     setCentralWidget(m_timelineArea);
+
+
+    KdenliveSettings::setCurrent_profile(KdenliveSettings::default_profile());
+    m_fileOpenRecent = KStandardAction::openRecent(this, SLOT(openFile(const KUrl &)), actionCollection());
+    readOptions();
+    m_fileRevert = KStandardAction::revert(this, SLOT(slotRevert()), actionCollection());
+    m_fileRevert->setEnabled(false);
+
+
     setupGUI();
 
+
     // Find QDockWidget tab bars and show / hide widget title bars on right click
     QList <QTabBar *> tabs = findChildren<QTabBar *>();
     for (int i = 0; i < tabs.count(); i++) {
@@ -1929,6 +1947,10 @@ void MainWindow::slotRenderProject()
     m_renderWidget->setDocument(m_activeDocument);*/
     m_renderWidget->show();
     m_renderWidget->showNormal();
+
+    m_activeTimeline->tracksNumber();
+    m_renderWidget->enableAudio(false);
+    //m_renderWidget->export_audio;
 }
 
 void MainWindow::slotCheckRenderStatus()
@@ -3548,17 +3570,19 @@ void MainWindow::slotShowTitleBars(bool show)
         m_transitionConfigDock->setTitleBarWidget(0);
         m_projectListDock->setTitleBarWidget(0);
         m_undoViewDock->setTitleBarWidget(0);
+        m_vectorscopeDock->setTitleBarWidget(0);
     } else {
-        if (!m_effectStackDock->isFloating()) m_effectStackDock->setTitleBarWidget(new QWidget(this));
-        if (!m_clipMonitorDock->isFloating()) m_clipMonitorDock->setTitleBarWidget(new QWidget(this));
-        if (!m_projectMonitorDock->isFloating()) m_projectMonitorDock->setTitleBarWidget(new QWidget(this));
+        if (!m_effectStackDock->isFloating()) { m_effectStackDock->setTitleBarWidget(new QWidget(this)); }
+        if (!m_clipMonitorDock->isFloating()) { m_clipMonitorDock->setTitleBarWidget(new QWidget(this)); }
+        if (!m_projectMonitorDock->isFloating()) { m_projectMonitorDock->setTitleBarWidget(new QWidget(this)); }
 #ifndef Q_WS_MAC
-        if (!m_recMonitorDock->isFloating()) m_recMonitorDock->setTitleBarWidget(new QWidget(this));
+        if (!m_recMonitorDock->isFloating()) { m_recMonitorDock->setTitleBarWidget(new QWidget(this)); }
 #endif
-        if (!m_effectListDock->isFloating()) m_effectListDock->setTitleBarWidget(new QWidget(this));
-        if (!m_transitionConfigDock->isFloating()) m_transitionConfigDock->setTitleBarWidget(new QWidget(this));
-        if (!m_projectListDock->isFloating()) m_projectListDock->setTitleBarWidget(new QWidget(this));
-        if (!m_undoViewDock->isFloating()) m_undoViewDock->setTitleBarWidget(new QWidget(this));
+        if (!m_effectListDock->isFloating()) { m_effectListDock->setTitleBarWidget(new QWidget(this)); }
+        if (!m_transitionConfigDock->isFloating()) { m_transitionConfigDock->setTitleBarWidget(new QWidget(this)); }
+        if (!m_projectListDock->isFloating()) { m_projectListDock->setTitleBarWidget(new QWidget(this)); }
+        if (!m_undoViewDock->isFloating()) { m_undoViewDock->setTitleBarWidget(new QWidget(this)); }
+        if (!m_vectorscopeDock->isFloating()) { m_vectorscopeDock->setTitleBarWidget(new QWidget(this)); }
     }
     KdenliveSettings::setShowtitlebars(show);
 }
index 33885b5079951bbaa9acd1ceb18489f1be58225b..897e0f43602fd8af1a4d9b633f87c88b935329bf 100644 (file)
@@ -61,6 +61,7 @@ class JogShuttle;
 class DocClipBase;
 class Render;
 class Transition;
+class Vectorscope;
 class KActionCollection;
 
 class MainWindow : public KXmlGuiWindow
@@ -150,6 +151,9 @@ private:
     QDockWidget *m_recMonitorDock;
     RecMonitor *m_recMonitor;
 
+    QDockWidget *m_vectorscopeDock;
+    Vectorscope *m_vectorscope;
+
     QDockWidget *m_undoViewDock;
     QUndoView *m_undoView;
     QUndoGroup *m_commandStack;
index 81d657c2672dd6eb7b22df87fc075ece2bb20b21..7d447b7ad2e42578a7d873247626ad7ab27b6126 100644 (file)
@@ -32,7 +32,6 @@
 #include <KColorScheme>
 #include <KNotification>
 #include <KStartupInfo>
-// #include <knewstuff2/engine.h>
 
 #include <QDomDocument>
 #include <QItemDelegate>
@@ -661,8 +660,9 @@ void RenderWidget::slotPrepareExport(bool scriptExport)
         KMessageBox::sorry(this, i18n("Cannot find the melt program required for rendering (part of Mlt)"));
         return;
     }
-    if (m_view.play_after->isChecked() && KdenliveSettings::defaultplayerapp().isEmpty())
+    if (m_view.play_after->isChecked() && KdenliveSettings::defaultplayerapp().isEmpty()) {
         KMessageBox::sorry(this, i18n("Cannot play video after rendering because the default video player application is not set.\nPlease define it in Kdenlive settings dialog."));
+    }
     QString chapterFile;
     if (m_view.create_chapter->isChecked()) chapterFile = m_view.out_file->url().path() + ".dvdchapter";
 
@@ -1787,6 +1787,11 @@ void RenderWidget::missingClips(bool hasMissing)
     } else m_view.errorLabel->setHidden(true);
 }
 
+void RenderWidget::enableAudio(bool enable)
+{
+    m_view.export_audio->setChecked(enable);
+}
+
 void RenderWidget::slotUpdateRescaleWidth(int val)
 {
     KdenliveSettings::setDefaultrescalewidth(val);
index a9988695c0f98df23540656cfbdf381c6b6f4c89..367c6177653e031e6921f88282236a49dc6b4ba1 100644 (file)
@@ -113,6 +113,7 @@ public:
     QString getFreeScriptName(const QString &prefix = QString());
     bool startWaitingRenderJobs();
     void missingClips(bool hasMissing);
+    void enableAudio(bool enable);
 
 public slots:
     void slotExport(bool scriptExport, int zoneIn, int zoneOut, const QString &playlistPath, const QString &scriptPath);
index 998045057d25eaeba706cd36e18965ac269c3de6..62b8445a6a1a355701f6fc24d83d1913675db0cc 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
-                          effecstackedit.h  -  description
+                          transitionsettings.h  -  Transitions widget
                              -------------------
     begin                : Mar 15 2008
     copyright            : (C) 2008 by Marco Gittler
diff --git a/src/vectorscope.cpp b/src/vectorscope.cpp
new file mode 100644 (file)
index 0000000..d3c9b3e
--- /dev/null
@@ -0,0 +1,258 @@
+/***************************************************************************
+ *   Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com)      *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
+/**
+
+  Vectorscope.
+
+  The basis matrix for converting RGB to YUV is:
+
+mRgb2Yuv =                       r =
+
+   0.29900   0.58700   0.11400     1.00000
+  -0.14741  -0.28939   0.43680  x  0.00000
+   0.61478  -0.51480  -0.09998     0.00000
+
+  The resulting YUV value is then drawn on the circle
+  using U and V as coordinate values.
+
+  The maximum length of such an UV vector is reached
+  for the colors Red and Cyan: 0.632.
+  To make optimal use of space in the circle, this value
+  can be used for scaling.
+
+  As we are dealing with RGB values in a range of {0,...,255}
+  and the conversion values are made for [0,1], we already
+  divide the conversion values by 255 previously, e.g. in
+  GNU octave.
+ */
+
+#include <QColor>
+#include <QPainter>
+#include <QDebug>
+
+#include "vectorscope.h"
+
+const float SCALING = 1/.7; // See class docs
+const float P75 = .75;
+const QPointF YUV_R(-.147,  .615);
+const QPointF YUV_G(-.289, -.515);
+const QPointF YUV_B(.437, -.100);
+const QPointF YUV_Cy(.147, -.615);
+const QPointF YUV_Mg(.289,  .515);
+const QPointF YUV_Yl(-.437,  .100);
+
+
+
+Vectorscope::Vectorscope(Render *render, QWidget *parent) :
+    QWidget(parent),
+    m_render(render),
+    iPaintMode(GREEN),
+    scaling(1)
+{
+    setupUi(this);
+    paintMode->insertItem(GREEN, i18n("Green"));
+    paintMode->insertItem(CHROMA, i18n("Chroma"));
+    paintMode->insertItem(ORIG, i18n("Original Color"));
+    connect(paintMode, SIGNAL(currentIndexChanged(int)), this, SLOT(slotPaintModeChanged(int)));
+    connect(cbMagnify, SIGNAL(stateChanged(int)), this, SLOT(slotMagnifyChanged()));
+}
+
+Vectorscope::~Vectorscope()
+{
+}
+
+void Vectorscope::mousePressEvent(QMouseEvent *)
+{
+    this->update();
+}
+
+/**
+
+  Input point is on [-1,1]², 0 being at the center,
+  and positive directions are top/right.
+
+  Maps to a QRect «inside» which is using the
+  0 point in the top left corner. The coordinates of
+  the rect «inside» are relative to «parent». The
+  coordinates returned can be used in the parent.
+
+
+    parent v
+  +-------------------+
+  | inside v          |
+  | +-----------+     |
+  | |    +      |     |
+  | |  --0++    |     | < point
+  | |    -      |     |
+  | +-----------+     |
+  |                   |
+  +-------------------+
+
+ */
+QPoint Vectorscope::mapToCanvas(QRect inside, QPointF point)
+{
+    return QPoint(point.x()/2*inside.width()  + inside.width()/2  + inside.x(),
+                 -point.y()/2*inside.height() + inside.height()/2 + inside.y());
+}
+
+void Vectorscope::paintEvent(QPaintEvent *)
+{
+    // Widget width/height
+    int ww = this->size().width();
+    int wh = this->size().height();
+
+    // Distance from top/left/right
+    int offset = 6;
+
+    // controlsArea contains the controls at the top;
+    // We want to paint below
+    QPoint topleft(offset, controlsArea->geometry().height()+offset);
+
+    // Circle Width: min of width and height
+    int cw = wh - topleft.y();
+    if (ww < cw) { cw = ww; }
+    cw -= 2*offset;
+    QRect scopeRect(topleft, QPoint(cw, cw) + topleft);
+
+
+    // Draw the vectorscope circle
+    QPainter davinci(this);
+    QPoint vinciPoint;
+    davinci.setRenderHint(QPainter::Antialiasing, true);
+    davinci.fillRect(0, 0, ww, wh, QColor(25,25,23));
+
+    davinci.setPen(QPen(QBrush(QColor(250,250,250)), 2, Qt::SolidLine));
+    davinci.drawEllipse(scopeRect);
+
+    // Draw RGB/CMY points with 100% chroma
+    vinciPoint = mapToCanvas(scopeRect, SCALING*YUV_R);
+    davinci.drawEllipse(vinciPoint, 4,4);
+    davinci.drawText(vinciPoint-QPoint(20, -10), "R");
+
+    vinciPoint = mapToCanvas(scopeRect, SCALING*YUV_G);
+    davinci.drawEllipse(vinciPoint, 4,4);
+    davinci.drawText(vinciPoint-QPoint(20, 0), "G");
+
+    vinciPoint = mapToCanvas(scopeRect, SCALING*YUV_B);
+    davinci.drawEllipse(vinciPoint, 4,4);
+    davinci.drawText(vinciPoint+QPoint(15, 10), "B");
+
+    vinciPoint = mapToCanvas(scopeRect, SCALING*YUV_Cy);
+    davinci.drawEllipse(vinciPoint, 4,4);
+    davinci.drawText(vinciPoint+QPoint(15, -5), "Cy");
+
+    vinciPoint = mapToCanvas(scopeRect, SCALING*YUV_Mg);
+    davinci.drawEllipse(vinciPoint, 4,4);
+    davinci.drawText(vinciPoint+QPoint(15, 10), "Mg");
+
+    vinciPoint = mapToCanvas(scopeRect, SCALING*YUV_Yl);
+    davinci.drawEllipse(vinciPoint, 4,4);
+    davinci.drawText(vinciPoint-QPoint(25, 0), "Yl");
+
+    // Draw RGB/CMY points with 75% chroma (for NTSC)
+    davinci.setPen(QPen(QBrush(QColor(250,250,250)), 1, Qt::SolidLine));
+    davinci.drawEllipse(mapToCanvas(scopeRect, QPointF(0,0)), 4,4);
+    davinci.drawEllipse(mapToCanvas(scopeRect, P75*SCALING*YUV_R), 3,3);
+    davinci.drawEllipse(mapToCanvas(scopeRect, P75*SCALING*YUV_G), 3,3);
+    davinci.drawEllipse(mapToCanvas(scopeRect, P75*SCALING*YUV_B), 3,3);
+    davinci.drawEllipse(mapToCanvas(scopeRect, P75*SCALING*YUV_Cy), 3,3);
+    davinci.drawEllipse(mapToCanvas(scopeRect, P75*SCALING*YUV_Mg), 3,3);
+    davinci.drawEllipse(mapToCanvas(scopeRect, P75*SCALING*YUV_Yl), 3,3);
+
+
+    // If no renderer available, there is nothing more to paint now.
+    if (m_render == 0) return;
+
+
+    // Prepare the vectorscope data
+    QImage scope(cw, cw, QImage::Format_ARGB32);
+    scope.fill(qRgba(0,0,0,0));
+
+    QImage img(m_render->extractFrame(m_render->seekFramePosition()));
+    uchar *bits = img.bits();
+
+    davinci.setCompositionMode(QPainter::CompositionMode_Plus);
+    davinci.setPen(QColor(144,255,100,50));
+    
+    int r,g,b;
+    double dy, dr, dg, db, dmax;
+    double y,u,v;
+    QPoint pt;
+    QRgb px;
+
+    for (int i = 0; i < img.byteCount(); i+= 4) {
+        QRgb *col = (QRgb *) bits;
+
+        r = qRed(*col);
+        g = qGreen(*col);
+        b = qBlue(*col);
+
+        y = (double) 0.001173 * r + 0.002302 * g + 0.0004471 * b;
+        u = (double) -0.0005781*r -0.001135*g +0.001713*b;
+        v = (double) 0.002411*r -0.002019*g -0.0003921*b;
+
+        pt = mapToCanvas(QRect(QPoint(0,0), scope.size()), QPointF(SCALING*scaling*u, SCALING*scaling*v));
+
+        if (!(pt.x() <= scopeRect.width() && pt.x() >= 0
+            && pt.y() <= scopeRect.height() && pt.y() >= 0)) {
+            // Point lies outside (because of scaling), don't plot it
+            continue;
+        }
+
+        // Draw the pixel using the chosen draw mode
+        switch (iPaintMode) {
+        case CHROMA:
+            dy = 200;
+            dr = dy + 290.8*v;
+            dg = dy - 100.6*u - 148*v;
+            db = dy + 517.2*u;
+
+            dmax = dr;
+            if (dg > dmax) dmax = dg;
+            if (db > dmax) dmax = db;
+            dmax = 255/dmax;
+
+            dr *= dmax;
+            dg *= dmax;
+            db *= dmax;
+
+            scope.setPixel(pt, qRgba(dr, dg, db, 255));
+            break;
+        case ORIG:
+            scope.setPixel(pt, *col);
+            break;
+        case GREEN:
+            px = scope.pixel(pt);
+            scope.setPixel(pt, qRgba(qRed(px)+(255-qRed(px))/40, 255, qBlue(px)+(255-qBlue(px))/40, qAlpha(px)+(255-qAlpha(px))/20));
+            break;
+        }
+
+        bits += 4;
+    }
+
+    davinci.drawImage(scopeRect.topLeft(), scope);
+
+}
+
+void Vectorscope::slotPaintModeChanged(int index)
+{
+    iPaintMode = index;
+    this->update();
+}
+
+void Vectorscope::slotMagnifyChanged()
+{
+    if (cbMagnify->isChecked()) {
+        scaling = 1.4;
+    } else {
+        scaling = 1;
+    }
+    this->update();
+}
diff --git a/src/vectorscope.h b/src/vectorscope.h
new file mode 100644 (file)
index 0000000..86ceadf
--- /dev/null
@@ -0,0 +1,44 @@
+/***************************************************************************
+ *   Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com)      *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
+#ifndef VECTORSCOPE_H
+#define VECTORSCOPE_H
+
+#include "renderer.h"
+#include "ui_vectorscope_ui.h"
+
+class Render;
+class Vectorscope_UI;
+
+enum PAINT_MODE { GREEN = 0, ORIG = 1, CHROMA = 2 };
+
+class Vectorscope : public QWidget, public Ui::Vectorscope_UI {
+    Q_OBJECT
+
+public:
+    Vectorscope(Render *render, QWidget *parent = 0);
+    ~Vectorscope();
+
+protected:
+    void paintEvent(QPaintEvent *);
+    void mousePressEvent(QMouseEvent *);
+
+private:
+    Render *m_render;
+    int iPaintMode;
+    float scaling;
+    QPoint mapToCanvas(QRect inside, QPointF point);
+
+private slots:
+    void slotPaintModeChanged(int index);
+    void slotMagnifyChanged();
+
+};
+
+#endif // VECTORSCOPE_H
diff --git a/src/widgets/vectorscope_ui.ui b/src/widgets/vectorscope_ui.ui
new file mode 100644 (file)
index 0000000..3d9e66f
--- /dev/null
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Vectorscope_UI</class>
+ <widget class="QWidget" name="Vectorscope_UI">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>450</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="baseSize">
+   <size>
+    <width>400</width>
+    <height>450</height>
+   </size>
+  </property>
+  <property name="palette">
+   <palette>
+    <active>
+     <colorrole role="WindowText">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>250</red>
+        <green>238</green>
+        <blue>226</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="Button">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>40</red>
+        <green>40</green>
+        <blue>39</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="Text">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>250</red>
+        <green>238</green>
+        <blue>226</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="ButtonText">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>250</red>
+        <green>238</green>
+        <blue>226</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="Base">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>40</red>
+        <green>40</green>
+        <blue>39</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="Window">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>40</red>
+        <green>40</green>
+        <blue>39</blue>
+       </color>
+      </brush>
+     </colorrole>
+    </active>
+    <inactive>
+     <colorrole role="WindowText">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>250</red>
+        <green>238</green>
+        <blue>226</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="Button">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>40</red>
+        <green>40</green>
+        <blue>39</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="Text">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>250</red>
+        <green>238</green>
+        <blue>226</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="ButtonText">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>250</red>
+        <green>238</green>
+        <blue>226</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="Base">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>40</red>
+        <green>40</green>
+        <blue>39</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="Window">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>40</red>
+        <green>40</green>
+        <blue>39</blue>
+       </color>
+      </brush>
+     </colorrole>
+    </inactive>
+    <disabled>
+     <colorrole role="WindowText">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>146</red>
+        <green>145</green>
+        <blue>144</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="Button">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>40</red>
+        <green>40</green>
+        <blue>39</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="Text">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>165</red>
+        <green>164</green>
+        <blue>164</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="ButtonText">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>151</red>
+        <green>150</green>
+        <blue>149</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="Base">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>40</red>
+        <green>40</green>
+        <blue>39</blue>
+       </color>
+      </brush>
+     </colorrole>
+     <colorrole role="Window">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>40</red>
+        <green>40</green>
+        <blue>39</blue>
+       </color>
+      </brush>
+     </colorrole>
+    </disabled>
+   </palette>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <widget class="QWidget" name="gridLayoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>401</width>
+     <height>301</height>
+    </rect>
+   </property>
+   <layout class="QGridLayout" name="gridLayout">
+    <property name="sizeConstraint">
+     <enum>QLayout::SetDefaultConstraint</enum>
+    </property>
+    <item row="1" column="0">
+     <layout class="QVBoxLayout" name="controlsArea">
+      <item>
+       <widget class="QComboBox" name="paintMode"/>
+      </item>
+      <item>
+       <widget class="QCheckBox" name="cbMagnify">
+        <property name="text">
+         <string>Magnify</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </item>
+    <item row="2" column="0">
+     <spacer name="verticalSpacer">
+      <property name="orientation">
+       <enum>Qt::Vertical</enum>
+      </property>
+      <property name="sizeHint" stdset="0">
+       <size>
+        <width>20</width>
+        <height>40</height>
+       </size>
+      </property>
+     </spacer>
+    </item>
+   </layout>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>