aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2014-08-08 11:51:47 +0200
committerHans Verkuil <hans.verkuil@cisco.com>2014-08-08 11:51:47 +0200
commit313bd4abb6b838ab0507d5eb734514d439e6a1fb (patch)
tree5b87e1b66ab3f0694c4069578aac9618ae6daacd
parentae1dee94de5f4a496e74be67681320aab9abd020 (diff)
qv4l2: Integrating capture-win in main window.
With the use of QDockWidgets, the capturewin is now by default created as a tab in the main window. All tabs are made floatable so that the user can choose what tabs to view simultaneously. Signed-off-by: Anton Arbring <aarbring@cisco.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
-rw-r--r--utils/qv4l2/Makefile.am2
-rw-r--r--utils/qv4l2/capture-win.cpp14
-rw-r--r--utils/qv4l2/capture-win.h2
-rw-r--r--utils/qv4l2/ctrl-tab.cpp31
-rw-r--r--utils/qv4l2/floatingframe.pngbin0 -> 345 bytes
-rw-r--r--utils/qv4l2/floatingframe.xcfbin0 -> 1339 bytes
-rw-r--r--utils/qv4l2/general-tab.cpp2
-rw-r--r--utils/qv4l2/qv4l2.cpp158
-rw-r--r--utils/qv4l2/qv4l2.h61
-rw-r--r--utils/qv4l2/qv4l2.qrc1
-rw-r--r--utils/qv4l2/tpg-tab.cpp26
11 files changed, 234 insertions, 63 deletions
diff --git a/utils/qv4l2/Makefile.am b/utils/qv4l2/Makefile.am
index ab570565..56b33459 100644
--- a/utils/qv4l2/Makefile.am
+++ b/utils/qv4l2/Makefile.am
@@ -23,7 +23,7 @@ qv4l2_LDFLAGS += $(ALSA_LIBS) -pthread
EXTRA_DIST = enterbutt.png exit.png fileopen.png qv4l2_24x24.png qv4l2_64x64.png qv4l2.png qv4l2.svg \
snapshot.png video-television.png fileclose.png qv4l2_16x16.png qv4l2_32x32.png qv4l2.desktop \
- qv4l2.qrc record.png saveraw.png qv4l2.pro qv4l2.1 fullscreenexit.png fullscreen.png
+ qv4l2.qrc record.png saveraw.png qv4l2.pro qv4l2.1 fullscreenexit.png fullscreen.png floatingframe.png
clean-local:
-rm -vf moc_*.cpp qrc_*.cpp qrc_*.o ui_*.h
diff --git a/utils/qv4l2/capture-win.cpp b/utils/qv4l2/capture-win.cpp
index 66bfa249..f0efce3c 100644
--- a/utils/qv4l2/capture-win.cpp
+++ b/utils/qv4l2/capture-win.cpp
@@ -39,11 +39,7 @@ CaptureWin::CaptureWin(ApplicationWindow *aw) :
m_appWin(aw)
{
setWindowTitle("V4L2 Capture");
- m_hotkeyClose = new QShortcut(Qt::CTRL+Qt::Key_W, this);
- connect(m_hotkeyClose, SIGNAL(activated()), this, SLOT(close()));
connect(new QShortcut(Qt::Key_Q, this), SIGNAL(activated()), this, SLOT(close()));
- m_hotkeyScaleReset = new QShortcut(Qt::CTRL+Qt::Key_F, this);
- connect(m_hotkeyScaleReset, SIGNAL(activated()), this, SLOT(resetSize()));
connect(aw->m_resetScalingAct, SIGNAL(triggered()), this, SLOT(resetSize()));
m_hotkeyExitFullscreen = new QShortcut(Qt::Key_Escape, this);
connect(m_hotkeyExitFullscreen, SIGNAL(activated()), this, SLOT(escape()));
@@ -78,8 +74,6 @@ CaptureWin::~CaptureWin()
layout()->removeWidget(this);
delete layout();
- delete m_hotkeyClose;
- delete m_hotkeyScaleReset;
}
void CaptureWin::setFrame(int width, int height, __u32 format,
@@ -249,6 +243,7 @@ void CaptureWin::setWindowSize(QSize frameSize)
m_frame.size = frameSize;
QWidget::resize(windowSize);
+ m_appWin->resetToFrame(windowSize);
}
QSize CaptureWin::scaleFrameSize(QSize window, QSize frame)
@@ -321,10 +316,9 @@ void CaptureWin::makeFullScreen(bool enable)
if (enable) {
showFullScreen();
setStyleSheet("background-color:#000000;");
- } else {
- showNormal();
+ } else
setStyleSheet("background-color:none;");
- }
+
QSize resetFrameSize = m_origFrameSize;
m_origFrameSize.setWidth(0);
m_origFrameSize.setHeight(0);
@@ -343,7 +337,7 @@ void CaptureWin::customMenuRequested(QPoint pos)
menu->addAction(m_enterFullScreen);
}
- menu->addAction(m_appWin->m_resetScalingAct);
+ menu->addAction(m_appWin->m_scalingAct);
menu->addAction(m_appWin->m_useBlendingAct);
menu->addAction(m_appWin->m_snapshotAct);
menu->addAction(m_appWin->m_showFramesAct);
diff --git a/utils/qv4l2/capture-win.h b/utils/qv4l2/capture-win.h
index fb048c5c..ebc906db 100644
--- a/utils/qv4l2/capture-win.h
+++ b/utils/qv4l2/capture-win.h
@@ -213,8 +213,6 @@ private:
ApplicationWindow *m_appWin;
static double m_pixelAspectRatio;
static CropMethod m_cropMethod;
- QShortcut *m_hotkeyClose;
- QShortcut *m_hotkeyScaleReset;
QShortcut *m_hotkeyExitFullscreen;
QShortcut *m_hotkeyToggleFullscreen;
QVBoxLayout *m_vboxLayout;
diff --git a/utils/qv4l2/ctrl-tab.cpp b/utils/qv4l2/ctrl-tab.cpp
index 7478a866..9554066a 100644
--- a/utils/qv4l2/ctrl-tab.cpp
+++ b/utils/qv4l2/ctrl-tab.cpp
@@ -34,6 +34,7 @@
#include <QPushButton>
#include <QToolButton>
#include <QToolTip>
+#include <QDockWidget>
#include <math.h>
#include <fcntl.h>
@@ -117,7 +118,7 @@ void ApplicationWindow::addTabs(int m_winWidth)
}
const v4l2_query_ext_ctrl &qec = m_ctrlMap[id];
- QWidget *t = new QWidget(m_tabs);
+ QWidget *t = new QWidget();
QVBoxLayout *vbox = new QVBoxLayout(t);
QWidget *w = new QWidget(t);
@@ -126,22 +127,18 @@ void ApplicationWindow::addTabs(int m_winWidth)
QGridLayout *grid = new QGridLayout(w);
QString tabName(qec.name);
- if (tabName.length()) {
- QLabel *title_tab = new QLabel(tabName, parentWidget());
- QFont f = title_tab->font();
- f.setBold(true);
- title_tab->setFont(f);
- grid->addWidget(title_tab, m_row, m_col, 1, m_cols, Qt::AlignLeft);
- grid->setRowMinimumHeight(m_row, 25);
- m_row++;
-
- QFrame *m_line = new QFrame(grid->parentWidget());
- m_line->setFrameShape(QFrame::HLine);
- m_line->setFrameShadow(QFrame::Sunken);
- grid->addWidget(m_line, m_row, m_col, 1, m_cols, Qt::AlignVCenter);
- m_row++;
- }
- m_tabs->addTab(t, tabName);
+ m_current = new QDockWidget(tabName);
+ m_dockTabs->push_back(m_current);
+ m_current->setWidget(t);
+ //styleDockTitle(m_current);
+ m_current->setTitleBarWidget(new CustomTitleBar(this, m_current));
+ m_current->setFeatures(QDockWidget::DockWidgetFloatable);
+ m_mainWin->addDockWidget(Qt::TopDockWidgetArea, m_current);
+ connect(m_current, SIGNAL(topLevelChanged(bool)), this, SLOT(toggleDockWidgets(bool)));
+ m_current->toggleViewAction()->setEnabled(true);
+ m_tabMenu->addAction(m_current->toggleViewAction());
+ m_mainWin->tabifyDockWidget(m_general,m_current);
+
for (i = 0; i < iter->second.size(); i++) {
if (i & 1)
id = iter->second[(1+iter->second.size()) / 2 + i / 2];
diff --git a/utils/qv4l2/floatingframe.png b/utils/qv4l2/floatingframe.png
new file mode 100644
index 00000000..74b5f4cb
--- /dev/null
+++ b/utils/qv4l2/floatingframe.png
Binary files differ
diff --git a/utils/qv4l2/floatingframe.xcf b/utils/qv4l2/floatingframe.xcf
new file mode 100644
index 00000000..4ee4c9ed
--- /dev/null
+++ b/utils/qv4l2/floatingframe.xcf
Binary files differ
diff --git a/utils/qv4l2/general-tab.cpp b/utils/qv4l2/general-tab.cpp
index 4b80ede8..d5b0f959 100644
--- a/utils/qv4l2/general-tab.cpp
+++ b/utils/qv4l2/general-tab.cpp
@@ -123,8 +123,6 @@ GeneralTab::GeneralTab(const QString &device, cv4l_fd *fd, int n, QWidget *paren
querycap(m_querycap);
- addTitle("General Information");
-
addLabel("Device");
addLabel(device + (m_fd->g_direct() ? "" : " (wrapped)"));
diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp
index 0e168e83..1ea9d103 100644
--- a/utils/qv4l2/qv4l2.cpp
+++ b/utils/qv4l2/qv4l2.cpp
@@ -45,6 +45,7 @@ extern "C" {
#include <QThread>
#include <QCloseEvent>
#include <QInputDialog>
+#include <QDockWidget>
#include <assert.h>
#include <sys/mman.h>
@@ -162,6 +163,7 @@ ApplicationWindow::ApplicationWindow() :
m_resetScalingAct = new QAction("Resize to &Frame Size", this);
m_resetScalingAct->setStatusTip("Resizes the capture window to match frame size");
m_resetScalingAct->setShortcut(Qt::CTRL+Qt::Key_F);
+ m_resetScalingAct->setEnabled(false);
QMenu *captureMenu = menuBar()->addMenu("&Capture");
captureMenu->addAction(m_capStartAct);
@@ -189,7 +191,7 @@ ApplicationWindow::ApplicationWindow() :
}
captureMenu->addAction(m_resetScalingAct);
- m_makeFullScreenAct = new QAction(QIcon(":/fullscreen.png"), "Show Fullscreen", this);
+ m_makeFullScreenAct = new QAction(QIcon(":/fullscreen.png"), "Show &Fullscreen", this);
m_makeFullScreenAct->setStatusTip("Capture in fullscreen mode");
m_makeFullScreenAct->setCheckable(true);
connect(m_makeFullScreenAct, SIGNAL(toggled(bool)), this, SLOT(makeFullScreen(bool)));
@@ -211,6 +213,8 @@ ApplicationWindow::ApplicationWindow() :
captureMenu->addAction(m_audioBufferAct);
#endif
+ m_tabMenu = menuBar()->addMenu("&Tabs");
+
QMenu *helpMenu = menuBar()->addMenu("&Help");
helpMenu->addAction("&About", this, SLOT(about()), Qt::Key_F1);
@@ -222,6 +226,11 @@ ApplicationWindow::ApplicationWindow() :
m_tabs = new QTabWidget;
setCentralWidget(m_tabs);
+
+ m_dockTabs = new QList<QDockWidget *>();
+ m_mainWin = qobject_cast<QMainWindow*>(this);
+ m_mainWin->setDockOptions(QMainWindow::ForceTabbedDocks | QMainWindow::AnimatedDocks);
+ m_mainWin->setTabPosition(Qt::TopDockWidgetArea, QTabWidget::North);
}
@@ -246,6 +255,11 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen)
return;
}
+ m_captureTab = new QDockWidget("Capture");
+ m_captureTab->setFeatures(QDockWidget::DockWidgetFloatable);
+ connect(m_captureTab, SIGNAL(topLevelChanged(bool)), this, SLOT(toggleDockWidgets(bool)));
+ m_captureTab->setTitleBarWidget(new CustomTitleBar(this, m_captureTab));
+
newCaptureWin();
QWidget *w = new QWidget(m_tabs);
@@ -268,7 +282,16 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen)
connect(m_genTab, SIGNAL(colorspaceChanged()), this, SLOT(updateColorspace()));
connect(m_genTab, SIGNAL(displayColorspaceChanged()), this, SLOT(updateDisplayColorspace()));
connect(m_genTab, SIGNAL(clearBuffers()), this, SLOT(clearBuffers()));
- m_tabs->addTab(w, "General Settings");
+
+ m_general = new QDockWidget("General Settings");
+ m_dockTabs->push_back(m_general);
+ m_general->setWidget(w);
+ m_general->setFeatures(QDockWidget::DockWidgetFloatable);
+ m_general->setTitleBarWidget(new CustomTitleBar(this, m_general));
+ connect(m_general, SIGNAL(topLevelChanged(bool)), this, SLOT(toggleDockWidgets(bool)));
+ m_mainWin->addDockWidget(Qt::TopDockWidgetArea, m_general);
+ m_general->toggleViewAction()->setEnabled(true);
+ m_tabMenu->addAction(m_general->toggleViewAction());
if (has_vid_out()) {
addTpgTab(m_minWidth);
@@ -281,7 +304,16 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen)
if (has_vbi_cap()) {
w = new QWidget(m_tabs);
m_vbiTab = new VbiTab(w);
- m_tabs->addTab(w, "VBI");
+ QDockWidget *m_vbi = new QDockWidget("VBI");
+ m_dockTabs->push_back(m_vbi);
+ m_vbi->setWidget(w);
+ m_vbi->setTitleBarWidget(new CustomTitleBar(this, m_vbi));
+ m_vbi->setFeatures(QDockWidget::DockWidgetFloatable);
+ m_mainWin->addDockWidget(Qt::TopDockWidgetArea, m_vbi);
+ connect(m_vbi, SIGNAL(topLevelChanged(bool)), this, SLOT(toggleDockWidgets(bool)));
+ m_vbi->toggleViewAction()->setEnabled(true);
+ m_tabMenu->addAction(m_vbi->toggleViewAction());
+ m_mainWin->tabifyDockWidget(m_general, m_vbi);
}
if (QWidget *current = m_tabs->currentWidget()) {
current->show();
@@ -289,12 +321,25 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen)
statusBar()->clearMessage();
m_tabs->show();
m_tabs->setFocus();
+
+ QList<QTabBar *> tabList = findChildren<QTabBar *>();
+ if(!tabList.isEmpty()){
+ m_tabBar = tabList.at(0);
+ for (int i = 0; i < m_tabBar->count(); i++) {
+ if (m_tabBar->tabText(i)=="General Settings") {
+ m_tabBar->setCurrentIndex(i);
+ }
+ }
+ }
+
m_convertData = v4lconvert_create(g_fd());
bool canStream = g_fd() >= 0 && (v4l_type_is_capture(g_type()) || has_vid_out()) &&
!has_radio_rx() && !has_radio_tx();
m_capStartAct->setEnabled(canStream);
m_saveRawAct->setEnabled(canStream);
m_snapshotAct->setEnabled(canStream && has_vid_cap());
+ m_makeFullScreenAct->setEnabled(canStream);
+ m_captureTab->toggleViewAction()->setEnabled(canStream && !m_genTab->isRadio());
#ifdef HAVE_QTGL
m_useGLAct->setEnabled(CaptureWinGL::isSupported());
#endif
@@ -302,6 +347,48 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen)
subscribeCtrlEvents();
m_ctrlNotifier = new QSocketNotifier(g_fd(), QSocketNotifier::Exception, m_tabs);
connect(m_ctrlNotifier, SIGNAL(activated(int)), this, SLOT(ctrlEvent()));
+
+ QList<QDockWidget *>::iterator it;
+ for (it = m_dockTabs->begin(); it != m_dockTabs->end(); ++it) {
+ if ((*it) != m_captureTab && !(*it)->windowTitle().contains("VBI")) {
+ (*it)->setFixedHeight((*it)->sizeHint().height());
+ }
+ }
+ m_mainWin->adjustSize();
+}
+
+void ApplicationWindow::closeCaptureWin()
+{
+ m_capStartAct->setChecked(false);
+}
+
+void ApplicationWindow::resetToFrame(QSize framesize)
+{
+ if (!m_captureTab->isFloating()) {
+ m_capture->resize(m_capture->scaleFrameSize(m_captureTab->size(), framesize));
+ return;
+ } else {
+ m_capture->resize(framesize);
+ QSize hint = m_capture->sizeHint();
+ m_capture->setMinimumSize(framesize);
+ m_captureTab->adjustSize();
+ m_capture->setMinimumSize(hint);
+ }
+}
+
+void ApplicationWindow::toggleDockWidgets(bool floating)
+{
+ if (QDockWidget* dock = dynamic_cast<QDockWidget*>(QObject::sender()))
+ {
+ if (dock != m_general)
+ tabifyDockWidget(m_general, dock);
+ if (dock == m_captureTab) {
+ m_resetScalingAct->setEnabled(floating);
+ } if (dock->isFloating()) {
+ dock->adjustSize();
+ dock->move(m_mainWin->pos().x() + 0.6 * dock->width(), m_mainWin->pos().y() + 150);
+ }
+ }
}
void ApplicationWindow::opendev()
@@ -427,15 +514,18 @@ void ApplicationWindow::newCaptureWin()
switch (m_renderMethod) {
case QV4L2_RENDER_GL:
m_capture = new CaptureWinGL(this);
+ m_captureTab->setWindowTitle("GL Capture");
break;
default:
m_capture = new CaptureWinQt(this);
+ m_captureTab->setWindowTitle("QT Capture");
break;
}
m_capture->setPixelAspectRatio(1.0);
m_capture->enableScaling(m_scalingAct->isChecked());
- connect(m_capture, SIGNAL(close()), this, SLOT(closeCaptureWin()));
+ m_tabMenu->addAction(m_captureTab->toggleViewAction());
+ m_captureTab->setWidget(m_capture);
}
bool ApplicationWindow::startStreaming()
@@ -1073,11 +1163,6 @@ void ApplicationWindow::changeAudioDevice()
}
}
-void ApplicationWindow::closeCaptureWin()
-{
- m_capStartAct->setChecked(false);
-}
-
void ApplicationWindow::outStart(bool start)
{
if (start) {
@@ -1175,7 +1260,16 @@ void ApplicationWindow::capStart(bool start)
m_capNotifier = NULL;
delete m_capImage;
m_capImage = NULL;
+ m_mainWin->removeDockWidget(m_captureTab);
+ m_dockTabs->removeOne(m_captureTab);
+ m_captureTab->toggleViewAction()->setEnabled(false);
return;
+ } else if (showFrames()) {
+ m_captureTab->toggleViewAction()->setEnabled(true);
+ m_tabMenu->addAction(m_captureTab->toggleViewAction());
+ m_mainWin->addDockWidget(Qt::TopDockWidgetArea, m_captureTab);
+ m_dockTabs->push_back(m_captureTab);
+ m_mainWin->tabifyDockWidget(m_general, m_captureTab);
}
m_frame = m_lastFrame = m_fps = 0;
m_capMethod = m_genTab->capMethod();
@@ -1238,9 +1332,13 @@ void ApplicationWindow::capStart(bool start)
m_capture->setWindowSize(QSize(m_vbiWidth, m_vbiHeight));
m_capture->setFrame(m_capImage->width(), m_capImage->height(),
m_capDestFormat.fmt.pix.pixelformat, m_capImage->bits(), NULL);
+ makeFullScreen(m_makeFullScreenAct->isChecked());
if (showFrames())
m_capture->show();
+ m_scalingAct->setChecked(false);
+ m_scalingAct->setEnabled(false);
+
statusBar()->showMessage("No frame");
if (startStreaming()) {
m_capNotifier = new QSocketNotifier(g_fd(), QSocketNotifier::Read, m_tabs);
@@ -1267,6 +1365,7 @@ void ApplicationWindow::capStart(bool start)
m_capture->setWindowSize(QSize(SDR_WIDTH, SDR_HEIGHT));
m_capture->setFrame(m_capImage->width(), m_capImage->height(),
m_capDestFormat.fmt.pix.pixelformat, m_capImage->bits(), NULL);
+ makeFullScreen(m_makeFullScreenAct->isChecked());
if (showFrames())
m_capture->show();
@@ -1345,9 +1444,7 @@ void ApplicationWindow::capStart(bool start)
m_capture->setWindowSize(QSize(width, height));
m_capture->setFrame(m_capImage->width(), m_capImage->height(),
pixfmt, m_capImage->bits(), NULL);
- m_capture->makeFullScreen(m_makeFullScreenAct->isChecked());
- if (showFrames())
- m_capture->show();
+ makeFullScreen(m_makeFullScreenAct->isChecked());
statusBar()->showMessage("No frame");
if (startStreaming()) {
@@ -1358,8 +1455,30 @@ void ApplicationWindow::capStart(bool start)
void ApplicationWindow::makeFullScreen(bool checked)
{
- if (m_capture && m_capStartAct->isChecked())
- m_capture->makeFullScreen(checked);
+ if (m_capture != NULL && m_capStartAct->isChecked()) {
+ if (checked) {
+ QPoint prevPos;
+ if (m_captureTab->isFloating())
+ prevPos = m_captureTab->mapToGlobal(m_captureTab->pos());
+ else
+ prevPos = pos();
+ m_mainWin->removeDockWidget(m_captureTab);
+ m_capture->setParent(NULL);
+ m_capture->show();
+ m_capture->move(prevPos); // To call fullscreen from previous position
+ m_capture->makeFullScreen(checked);
+ m_captureTab->toggleViewAction()->setEnabled(false);
+ } else {
+ m_capture->makeFullScreen(checked);
+ m_captureTab->setWidget(m_capture);
+ m_captureTab->show();
+ m_mainWin->addDockWidget(Qt::TopDockWidgetArea, m_captureTab);
+ m_tabMenu->addAction(m_captureTab->toggleViewAction());
+ m_mainWin->tabifyDockWidget(m_general, m_captureTab);
+ m_captureTab->toggleViewAction()->setEnabled(true);
+ m_captureTab->setFocus(Qt::ActiveWindowFocusReason);
+ }
+ }
}
void ApplicationWindow::closeDevice()
@@ -1370,6 +1489,7 @@ void ApplicationWindow::closeDevice()
m_capStartAct->setEnabled(false);
m_capStartAct->setChecked(false);
m_saveRawAct->setEnabled(false);
+ m_makeFullScreenAct->setEnabled(false);
if (g_fd() >= 0) {
if (m_capNotifier) {
delete m_capNotifier;
@@ -1392,9 +1512,13 @@ void ApplicationWindow::closeDevice()
delete m_capture;
m_capture = NULL;
}
- while (QWidget *page = m_tabs->widget(0)) {
- m_tabs->removeTab(0);
- delete page;
+ QList<QDockWidget *>::iterator it;
+ for (it = m_dockTabs->begin(); it != m_dockTabs->end(); ++it) {
+ if (*it != NULL) {
+ m_mainWin->removeDockWidget(*it);
+ m_dockTabs->removeOne(*it);
+ delete *it;
+ }
}
m_genTab = NULL;
m_ctrlMap.clear();
diff --git a/utils/qv4l2/qv4l2.h b/utils/qv4l2/qv4l2.h
index fd648684..5380b93a 100644
--- a/utils/qv4l2/qv4l2.h
+++ b/utils/qv4l2/qv4l2.h
@@ -33,6 +33,11 @@
#include <map>
#include <vector>
+//CustomTitleBar
+#include <QToolButton>
+#include <QDockWidget>
+#include <QSizePolicy>
+
// Must come before cv4l-helpers.h
#include <libv4l2.h>
@@ -158,6 +163,7 @@ private slots:
void updateDisplayColorspace();
void clearBuffers();
void about();
+ void toggleDockWidgets(bool floating);
// tpg
private slots:
@@ -196,6 +202,7 @@ private:
addWidget(grid, new QLabel(text, parentWidget()), align);
}
void fixWidth(QGridLayout *grid);
+ void resetToFrame(QSize framesize);
void addTabs(int m_winWidth);
void addTpgTab(int m_winWidth);
void finishGrid(QGridLayout *grid, unsigned ctrl_class);
@@ -241,8 +248,15 @@ private:
const int m_hMargin;
int m_maxw[4];
int m_increment;
+ QList<QDockWidget *> *m_dockTabs;
+ QTabBar *m_tabBar;
GeneralTab *m_genTab;
VbiTab *m_vbiTab;
+ QMainWindow *m_mainWin;
+ QDockWidget *m_general;
+ QDockWidget *m_captureTab;
+ QDockWidget *m_current;
+ QMenu *m_tabMenu;
QAction *m_capStartAct;
QAction *m_saveRawAct;
QAction *m_useGLAct;
@@ -295,4 +309,51 @@ private:
unsigned m_size;
};
+class CustomTitleBar : public QWidget
+{
+ Q_OBJECT
+
+ private:
+ QWidget *parent;
+ QDockWidget *m_dockWidget;
+
+ public:
+ CustomTitleBar( QWidget *parent, QDockWidget *dock) :
+ parent(parent),
+ m_dockWidget(dock)
+ {
+ QToolButton *m_floatButton = new QToolButton(parentWidget());
+ m_floatButton->setIcon(QIcon(":/floatingframe.png"));
+ m_floatButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
+ QWidget *w = new QWidget(parent);
+ QHBoxLayout *hlayout = new QHBoxLayout(w);
+ QVBoxLayout *vlayout = new QVBoxLayout(this);
+
+ QString tabName = dock->windowTitle();
+
+ QLabel *title = new QLabel(tabName, parent);
+ QFont f = title->font();
+ f.setBold(true);
+ title->setFont(f);
+ hlayout->addWidget(title);
+
+ hlayout->addWidget(m_floatButton);
+ hlayout->setContentsMargins(20,10,20,0);
+ hlayout->setSpacing(0);
+ vlayout->addWidget(w);
+
+ QFrame *m_line = new QFrame(parent);
+ m_line->setFrameShape(QFrame::HLine);
+ m_line->setFrameShadow(QFrame::Sunken);
+ vlayout->addWidget(m_line);
+ connect(m_floatButton, SIGNAL(clicked()), this, SLOT(toggleDockWidgets()));
+ }
+
+ public slots:
+ void toggleDockWidgets()
+ {
+ m_dockWidget->setFloating(!m_dockWidget->isFloating());
+ }
+};
+
#endif
diff --git a/utils/qv4l2/qv4l2.qrc b/utils/qv4l2/qv4l2.qrc
index 3a91a0c2..05c0f558 100644
--- a/utils/qv4l2/qv4l2.qrc
+++ b/utils/qv4l2/qv4l2.qrc
@@ -11,5 +11,6 @@
<file>enterbutt.png</file>
<file>fullscreen.png</file>
<file>fullscreenexit.png</file>
+ <file>floatingframe.png</file>
</qresource>
</RCC>
diff --git a/utils/qv4l2/tpg-tab.cpp b/utils/qv4l2/tpg-tab.cpp
index 8ef1bbe9..46ddfc0d 100644
--- a/utils/qv4l2/tpg-tab.cpp
+++ b/utils/qv4l2/tpg-tab.cpp
@@ -34,6 +34,7 @@
#include <QPushButton>
#include <QToolButton>
#include <QToolTip>
+#include <QDockWidget>
#include <math.h>
#include <fcntl.h>
@@ -42,7 +43,7 @@
void ApplicationWindow::addTpgTab(int m_winWidth)
{
- QWidget *t = new QWidget(m_tabs);
+ QWidget *t = new QWidget();
QVBoxLayout *vbox = new QVBoxLayout(t);
QWidget *w = new QWidget(t);
QCheckBox *check;
@@ -58,21 +59,18 @@ void ApplicationWindow::addTpgTab(int m_winWidth)
vbox->addWidget(w);
QGridLayout *grid = new QGridLayout(w);
- QLabel *title_tab = new QLabel("Test Pattern Generator", parentWidget());
- QFont f = title_tab->font();
- f.setBold(true);
- title_tab->setFont(f);
- grid->addWidget(title_tab, m_row, m_col, 1, m_cols, Qt::AlignLeft);
- grid->setRowMinimumHeight(m_row, 25);
- m_row++;
- QFrame *m_line = new QFrame(grid->parentWidget());
- m_line->setFrameShape(QFrame::HLine);
- m_line->setFrameShadow(QFrame::Sunken);
- grid->addWidget(m_line, m_row, m_col, 1, m_cols, Qt::AlignVCenter);
- m_row++;
+ QDockWidget *m_tpgTab = new QDockWidget("Test Pattern Generator");
+ m_dockTabs->push_back(m_tpgTab);
+ m_tpgTab->setWidget(t);
+ m_tpgTab->setTitleBarWidget(new CustomTitleBar(this, m_tpgTab));
+ m_tpgTab->setFeatures(QDockWidget::DockWidgetFloatable);
+ m_mainWin->addDockWidget(Qt::TopDockWidgetArea, m_tpgTab);
+ connect(m_tpgTab, SIGNAL(topLevelChanged(bool)), this, SLOT(toggleDockWidgets(bool)));
+ m_tpgTab->toggleViewAction()->setEnabled(true);
+ m_tabMenu->addAction(m_tpgTab->toggleViewAction());
+ m_mainWin->tabifyDockWidget(m_general,m_tpgTab);
- m_tabs->addTab(t, "Test Pattern Generator");
grid->addWidget(new QWidget(w), grid->rowCount(), 0, 1, m_cols);
addLabel(grid, "Test Pattern");

Privacy Policy