]> git.sesse.net Git - kdenlive/blob - src/videoglwidget.cpp
When missing or invalid clips, open only one dialog box instead of one for each clip
[kdenlive] / src / videoglwidget.cpp
1
2 #include <QtGui>
3 #include <QtOpenGL>
4 #include "videoglwidget.h"
5
6 #ifndef GL_TEXTURE_RECTANGLE_EXT
7 #define GL_TEXTURE_RECTANGLE_EXT GL_TEXTURE_RECTANGLE_NV
8 #endif
9
10 VideoGLWidget::VideoGLWidget(QWidget *parent)
11     : QGLWidget(parent)
12     , m_image_width(0)
13     , m_image_height(0)
14     , m_texture(0)
15     , m_display_ratio(4.0 / 3.0)
16     , m_backgroundColor(Qt::gray)
17 {
18     setAttribute(Qt::WA_PaintOnScreen);
19     setAttribute(Qt::WA_OpaquePaintEvent);
20 }
21
22 VideoGLWidget::~VideoGLWidget()
23 {
24     makeCurrent();
25     if (m_texture)
26         glDeleteTextures(1, &m_texture);
27 }
28
29 QSize VideoGLWidget::minimumSizeHint() const
30 {
31     return QSize(40, 30);
32 }
33
34 QSize VideoGLWidget::sizeHint() const
35 {
36     return QSize(400, 300);
37 }
38
39 void VideoGLWidget::initializeGL()
40 {
41     qglClearColor(m_backgroundColor);
42     glShadeModel(GL_FLAT);
43     glDisable(GL_DEPTH_TEST);
44     glDisable(GL_CULL_FACE);
45     glDisable(GL_LIGHTING);
46     glDisable(GL_DITHER);
47     glDisable(GL_BLEND);
48     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
49 }
50
51 void VideoGLWidget::resizeEvent(QResizeEvent* event)
52 {
53     resizeGL(event->size().width(),event->size().height());
54 }
55 void VideoGLWidget::resizeGL(int width, int height)
56 {
57
58     double this_aspect = (double) width / height;
59
60     // Special case optimisation to negate odd effect of sample aspect ratio
61     // not corresponding exactly with image resolution.
62     if ((int)(this_aspect * 1000) == (int)(m_display_ratio * 1000)) {
63         w = width;
64         h = height;
65     }
66     // Use OpenGL to normalise sample aspect ratio
67     else if (height * m_display_ratio > width) {
68         w = width;
69         h = width / m_display_ratio;
70     } else {
71         w = height * m_display_ratio;
72         h = height;
73     }
74     x = (width - w) / 2;
75     y = (height - h) / 2;
76
77     glViewport(0, 0, width, height);
78     glMatrixMode(GL_PROJECTION);
79     glLoadIdentity();
80     gluOrtho2D(0, width, height, 0);
81     glMatrixMode(GL_MODELVIEW);
82     glClear(GL_COLOR_BUFFER_BIT);
83 }
84
85 void VideoGLWidget::paintGL()
86 {
87     if (m_texture) {
88 #ifdef Q_WS_MAC
89                 glClear(GL_COLOR_BUFFER_BIT);
90 #endif
91         glEnable(GL_TEXTURE_RECTANGLE_EXT);
92         glBegin(GL_QUADS);
93         glTexCoord2i(0, 0);
94         glVertex2i(x, y);
95         glTexCoord2i(m_image_width, 0);
96         glVertex2i(x + w, y);
97         glTexCoord2i(m_image_width, m_image_height);
98         glVertex2i(x + w, y + h);
99         glTexCoord2i(0, m_image_height);
100         glVertex2i(x, y + h);
101         glEnd();
102         glDisable(GL_TEXTURE_RECTANGLE_EXT);
103     }
104 }
105
106 void VideoGLWidget::showImage(QImage image)
107 {
108     m_image_width = image.width();
109     m_image_height = image.height();
110
111     makeCurrent();
112     if (m_texture)
113         glDeleteTextures(1, &m_texture);
114
115     glPixelStorei(GL_UNPACK_ROW_LENGTH, m_image_width);
116     glGenTextures(1, &m_texture);
117     glBindTexture(GL_TEXTURE_RECTANGLE_EXT, m_texture);
118     glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
119     glTexParameterf(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
120     glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA8, m_image_width, m_image_height, 0, GL_RGBA,
121                  GL_UNSIGNED_BYTE, image.bits());
122     updateGL();
123 }
124
125 void VideoGLWidget::mouseDoubleClickEvent(QMouseEvent * event)
126 {
127     // TODO: disable screensaver?
128     Qt::WindowFlags flags = windowFlags();
129     if (!isFullScreen()) {
130         // Check if we ahave a multiple monitor setup
131 #if QT_VERSION >= 0x040600
132         int monitors = QApplication::desktop()->screenCount();
133 #else
134         int monitors = QApplication::desktop()->numScreens();
135 #endif
136         if (monitors > 1) {
137             QRect screenres;
138             // Move monitor widget to the second screen (one screen for Kdenlive, the other one for the Monitor widget
139             int currentScreen = QApplication::desktop()->screenNumber(this);
140             if (currentScreen < monitors - 1)
141                 screenres = QApplication::desktop()->screenGeometry(currentScreen + 1);
142             else
143                 screenres = QApplication::desktop()->screenGeometry(currentScreen - 1);
144             move(QPoint(screenres.x(), screenres.y()));
145             resize(screenres.width(), screenres.height());
146         }
147
148         m_baseFlags = flags & (Qt::Window | Qt::SubWindow);
149         flags |= Qt::Window;
150         flags ^= Qt::SubWindow;
151         setWindowFlags(flags);
152 #ifdef Q_WS_X11
153         // This works around a bug with Compiz
154         // as the window must be visible before we can set the state
155         show();
156         raise();
157         setWindowState(windowState() | Qt::WindowFullScreen);   // set
158 #else
159         setWindowState(windowState() | Qt::WindowFullScreen);   // set
160         show();
161 #endif
162     } else {
163         flags ^= (Qt::Window | Qt::SubWindow); //clear the flags...
164         flags |= m_baseFlags; //then we reset the flags (window and subwindow)
165         setWindowFlags(flags);
166         setWindowState(windowState()  ^ Qt::WindowFullScreen);   // reset
167         show();
168     }
169     event->accept();
170 }
171