From a7034c86c14acec92bbe03249970963bc311543f Mon Sep 17 00:00:00 2001 From: Anton Arbring Date: Wed, 9 Jul 2014 10:31:03 +0200 Subject: [PATCH] qv4l2: alignment and size mods To get a more structured and professional look, everything is left aligned. All buttons, line edits etc. gets a fixed minimum width and expand stepwise. The window minimum size is set accordingly. Signed-off-by: Anton Arbring Signed-off-by: Hans Verkuil --- utils/qv4l2/ctrl-tab.cpp | 62 ++++++++++++++++++++++--- utils/qv4l2/general-tab.cpp | 111 +++++++++++++++++++++++++++++++++++++------- utils/qv4l2/general-tab.h | 10 +++- utils/qv4l2/qv4l2.cpp | 8 +++- utils/qv4l2/qv4l2.h | 9 +++- 5 files changed, 172 insertions(+), 28 deletions(-) diff --git a/utils/qv4l2/ctrl-tab.cpp b/utils/qv4l2/ctrl-tab.cpp index c8aff55..fb3c027 100644 --- a/utils/qv4l2/ctrl-tab.cpp +++ b/utils/qv4l2/ctrl-tab.cpp @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -58,6 +59,10 @@ static bool is_valid_type(__u32 type) void ApplicationWindow::addWidget(QGridLayout *grid, QWidget *w, Qt::Alignment align) { + if (m_col % 2) + w->setMinimumWidth(m_minWidth); + if (w->sizeHint().width() > m_maxw[m_col]) + m_maxw[m_col] = w->sizeHint().width(); grid->addWidget(w, m_row, m_col, align | Qt::AlignVCenter); m_col++; if (m_col == m_cols) { @@ -66,7 +71,7 @@ void ApplicationWindow::addWidget(QGridLayout *grid, QWidget *w, Qt::Alignment a } } -void ApplicationWindow::addTabs() +void ApplicationWindow::addTabs(int size[]) { v4l2_queryctrl qctrl; unsigned ctrl_class; @@ -130,6 +135,9 @@ void ApplicationWindow::addTabs() id = ctrl_class | 1; m_col = m_row = 0; m_cols = 4; + for (int j = 0; j < m_cols; j++) { + m_maxw[j] = 0; + } const v4l2_queryctrl &qctrl = m_ctrlMap[id]; QWidget *t = new QWidget(m_tabs); @@ -139,8 +147,6 @@ void ApplicationWindow::addTabs() vbox->addWidget(w); QGridLayout *grid = new QGridLayout(w); - - grid->setSpacing(3); m_tabs->addTab(t, (char *)qctrl.name); for (i = 0; i < iter->second.size(); i++) { if (i & 1) @@ -153,11 +159,51 @@ void ApplicationWindow::addTabs() grid->setRowStretch(grid->rowCount() - 1, 1); w = new QWidget(t); vbox->addWidget(w); + fixWidth(grid); + + int totalw = 0; + int totalh = 0; + for (int i = 0; i < m_cols; i++) { + if (i % 2) + totalw += m_maxw[i] + m_pxw; + else + totalw += m_maxw[i]; + } + totalh = grid->rowCount() * 20; + if (totalw > size[0]) + size[0] = totalw; + if (totalh > size[1]) + size[1] = totalh; + setMinimumSize(size[0] + 50, size[1] + 150); + grid = new QGridLayout(w); finishGrid(grid, ctrl_class); } } +void ApplicationWindow::fixWidth(QGridLayout *grid) +{ + double m_pxw = 25.0; + grid->setContentsMargins(15, 5, 15, 5); + grid->setColumnStretch(1, 1); + QList list = grid->parentWidget()->parentWidget()->findChildren(); + QList::iterator it; + + for (it = list.begin(); it != list.end(); ++it) { + if (((*it)->sizeHint().width()) > m_minWidth) { + m_increment = (int) ceil(((*it)->sizeHint().width() - m_minWidth) / m_pxw); + (*it)->setMinimumWidth(m_minWidth + m_increment * m_pxw); // for stepsize expantion of widgets + } + } + + for (int j = 0; j < m_cols; j++) { + if (j % 2) // only add possible expansion for odd columns + grid->setColumnMinimumWidth(j, m_maxw[j] + m_pxw); + else + grid->setColumnMinimumWidth(j, m_maxw[j]); + } +} + void ApplicationWindow::finishGrid(QGridLayout *grid, unsigned ctrl_class) { QWidget *w = grid->parentWidget(); @@ -169,6 +215,9 @@ void ApplicationWindow::finishGrid(QGridLayout *grid, unsigned ctrl_class) m_col = 0; m_row = grid->rowCount(); + QWidget *m_w = new QWidget(); + QHBoxLayout *m_boxLayoutBottom = new QHBoxLayout(m_w); + QCheckBox *cbox = new QCheckBox("Update on change", w); m_widgetMap[ctrl_class | CTRL_UPDATE_ON_CHANGE] = cbox; addWidget(grid, cbox); @@ -179,23 +228,24 @@ void ApplicationWindow::finishGrid(QGridLayout *grid, unsigned ctrl_class) QPushButton *defBut = new QPushButton("Set Defaults", w); m_widgetMap[ctrl_class | CTRL_DEFAULTS] = defBut; - addWidget(grid, defBut); + m_boxLayoutBottom->addWidget(defBut); connect(defBut, SIGNAL(clicked()), m_sigMapper, SLOT(map())); m_sigMapper->setMapping(defBut, ctrl_class | CTRL_DEFAULTS); QPushButton *refreshBut = new QPushButton("Refresh", w); m_widgetMap[ctrl_class | CTRL_REFRESH] = refreshBut; - addWidget(grid, refreshBut); + m_boxLayoutBottom->addWidget(refreshBut); connect(refreshBut, SIGNAL(clicked()), m_sigMapper, SLOT(map())); m_sigMapper->setMapping(refreshBut, ctrl_class | CTRL_REFRESH); QPushButton *button = new QPushButton("Update", w); m_widgetMap[ctrl_class | CTRL_UPDATE] = button; - addWidget(grid, button); + m_boxLayoutBottom->addWidget(button); connect(button, SIGNAL(clicked()), m_sigMapper, SLOT(map())); m_sigMapper->setMapping(button, ctrl_class | CTRL_UPDATE); connect(cbox, SIGNAL(toggled(bool)), button, SLOT(setDisabled(bool))); + grid->addWidget(m_w, m_row, 3, Qt::AlignRight); cbox->setChecked(true); refresh(ctrl_class); diff --git a/utils/qv4l2/general-tab.cpp b/utils/qv4l2/general-tab.cpp index 97316ae..16feb2c 100644 --- a/utils/qv4l2/general-tab.cpp +++ b/utils/qv4l2/general-tab.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -99,22 +100,25 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) m_composeTop(NULL) { m_device.append(device); - setSpacing(3); setSizeConstraint(QLayout::SetMinimumSize); + m_minWidth = 175; + for (int i = 0; i < n; i++) { + m_maxw[i] = 0; + } if (querycap(m_querycap)) { addLabel("Device:"); - addLabel(device + (useWrapper() ? " (wrapped)" : ""), Qt::AlignLeft); + addLabel(device + (useWrapper() ? " (wrapped)" : "")); addLabel("Driver:"); - addLabel((char *)m_querycap.driver, Qt::AlignLeft); + addLabel((char *)m_querycap.driver); addLabel("Card:"); - addLabel((char *)m_querycap.card, Qt::AlignLeft); + addLabel((char *)m_querycap.card); addLabel("Bus:"); - addLabel((char *)m_querycap.bus_info, Qt::AlignLeft); + addLabel((char *)m_querycap.bus_info); } g_tuner(m_tuner); @@ -182,18 +186,19 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) QWidget *wStd = new QWidget(); QGridLayout *m_stdRow = new QGridLayout(wStd); + m_grids.append(m_stdRow); if (needsStd) { v4l2_std_id tmp; m_tvStandard = new QComboBox(parent); - m_stdRow->addWidget(new QLabel("TV Standard", parentWidget()), 0, 0, Qt::AlignRight); + m_stdRow->addWidget(new QLabel("TV Standard", parentWidget()), 0, 0, Qt::AlignLeft); m_stdRow->addWidget(m_tvStandard, 0, 1, Qt::AlignLeft); connect(m_tvStandard, SIGNAL(activated(int)), SLOT(standardChanged(int))); refreshStandards(); if (ioctl_exists(VIDIOC_QUERYSTD, &tmp)) { m_qryStandard = new QPushButton("Query Standard", parent); - m_stdRow->addWidget(new QLabel("", parentWidget()), 0, 2, Qt::AlignRight); + m_stdRow->addWidget(new QLabel("", parentWidget()), 0, 2, Qt::AlignLeft); m_stdRow->addWidget(m_qryStandard, 0, 3, Qt::AlignLeft); connect(m_qryStandard, SIGNAL(clicked()), SLOT(qryStdClicked())); } @@ -201,15 +206,16 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) QWidget *wTim = new QWidget(); QGridLayout *m_timRow = new QGridLayout(wTim); + m_grids.append(m_timRow); if (needsTimings) { m_videoTimings = new QComboBox(parent); - m_timRow->addWidget(new QLabel("Video Timings", parentWidget()), 0, 0, Qt::AlignRight); + m_timRow->addWidget(new QLabel("Video Timings", parentWidget()), 0, 0, Qt::AlignLeft); m_timRow->addWidget(m_videoTimings, 0, 1, Qt::AlignLeft); connect(m_videoTimings, SIGNAL(activated(int)), SLOT(timingsChanged(int))); refreshTimings(); m_qryTimings = new QPushButton("Query Timings", parent); - m_timRow->addWidget(new QLabel("", parentWidget()), 0, 2, Qt::AlignRight); + m_timRow->addWidget(new QLabel("", parentWidget()), 0, 2, Qt::AlignLeft); m_timRow->addWidget(m_qryTimings, 0, 3, Qt::AlignLeft); connect(m_qryTimings, SIGNAL(clicked()), SLOT(qryTimingsClicked())); } @@ -223,24 +229,26 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) QWidget *wFrameSR = new QWidget(); QGridLayout *m_wh = new QGridLayout(wFrameWH); QGridLayout *m_sr = new QGridLayout(wFrameSR); + m_grids.append(m_wh); + m_grids.append(m_sr); - m_wh->addWidget(new QLabel("Frame Width", parentWidget()), 0, 0, Qt::AlignRight); + m_wh->addWidget(new QLabel("Frame Width", parentWidget()), 0, 0, Qt::AlignLeft); m_frameWidth = new QSpinBox(parent); m_wh->addWidget(m_frameWidth, 0, 1, Qt::AlignLeft); connect(m_frameWidth, SIGNAL(editingFinished()), SLOT(frameWidthChanged())); - m_wh->addWidget(new QLabel("Frame Height", parentWidget()), 0, 2, Qt::AlignRight); + m_wh->addWidget(new QLabel("Frame Height", parentWidget()), 0, 2, Qt::AlignLeft); m_frameHeight = new QSpinBox(parent); m_wh->addWidget(m_frameHeight, 0, 3, Qt::AlignLeft); connect(m_frameHeight, SIGNAL(editingFinished()), SLOT(frameHeightChanged())); - m_sr->addWidget(new QLabel("Frame Size", parentWidget()), 0, 0, Qt::AlignRight); + m_sr->addWidget(new QLabel("Frame Size", parentWidget()), 0, 0, Qt::AlignLeft); m_frameSize = new QComboBox(parent); m_frameSize->setSizeAdjustPolicy(QComboBox::AdjustToContents); m_sr->addWidget(m_frameSize, 0, 1, Qt::AlignLeft); connect(m_frameSize, SIGNAL(activated(int)), SLOT(frameSizeChanged(int))); - m_sr->addWidget(new QLabel("Frame Rate", parentWidget()), 0, 2, Qt::AlignRight); + m_sr->addWidget(new QLabel("Frame Rate", parentWidget()), 0, 2, Qt::AlignLeft); m_frameInterval = new QComboBox(parent); m_frameInterval->setSizeAdjustPolicy(QComboBox::AdjustToContents); m_sr->addWidget(m_frameInterval, 0, 3, Qt::AlignLeft); @@ -254,6 +262,7 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) QWidget *wFreq = new QWidget(); QGridLayout *m_freqRows = new QGridLayout(wFreq); + m_grids.append(m_freqRows); if (m_tuner.capability) { const char *unit = (m_tuner.capability & V4L2_TUNER_CAP_LOW) ? " kHz" : @@ -273,14 +282,14 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) m_freq->setStatusTip(m_freq->whatsThis()); connect(m_freq, SIGNAL(valueChanged(double)), SLOT(freqChanged(double))); updateFreq(); - m_freqRows->addWidget(new QLabel("Frequency", parentWidget()), 0, 0, Qt::AlignRight); + m_freqRows->addWidget(new QLabel("Frequency", parentWidget()), 0, 0, Qt::AlignLeft); m_freqRows->addWidget(m_freq, 0, 1, Qt::AlignLeft); } if (m_tuner.capability && !isSDR()) { m_subchannels = new QLabel("", parent); m_detectSubchans = new QPushButton("Refresh Tuner Status", parent); - m_freqRows->addWidget(m_subchannels, 0, 2, Qt::AlignRight); + m_freqRows->addWidget(m_subchannels, 0, 2, Qt::AlignLeft); m_freqRows->addWidget(m_detectSubchans, 0, 3, Qt::AlignLeft); connect(m_detectSubchans, SIGNAL(clicked()), SLOT(detectSubchansClicked())); detectSubchansClicked(); @@ -291,13 +300,13 @@ GeneralTab::GeneralTab(const QString &device, v4l2 &fd, int n, QWidget *parent) for (int i = 0; v4l2_channel_lists[i].name; i++) { m_freqTable->addItem(v4l2_channel_lists[i].name); } - m_freqRows->addWidget(new QLabel("Frequency Table", parentWidget()), 1, 0, Qt::AlignRight); + m_freqRows->addWidget(new QLabel("Frequency Table", parentWidget()), 1, 0, Qt::AlignLeft); m_freqRows->addWidget(m_freqTable, 1, 1, Qt::AlignLeft); connect(m_freqTable, SIGNAL(activated(int)), SLOT(freqTableChanged(int))); m_freqChannel = new QComboBox(parent); m_freqChannel->setSizeAdjustPolicy(QComboBox::AdjustToContents); - m_freqRows->addWidget(new QLabel("Channels", parentWidget()), 1, 2, Qt::AlignRight); + m_freqRows->addWidget(new QLabel("Channels", parentWidget()), 1, 2, Qt::AlignLeft); m_freqRows->addWidget(m_freqChannel, 1, 3, Qt::AlignLeft); connect(m_freqChannel, SIGNAL(activated(int)), SLOT(freqChannelChanged(int))); updateFreqChannel(); @@ -691,6 +700,52 @@ done: updateGUI(m_videoInput->currentIndex()); else updateGUI(0); + fixWidth(); +} + +void GeneralTab::fixWidth() +{ + m_pxw = 25.0; + setContentsMargins(20, 10, 20, 10); + setColumnStretch(1, 1); + + QList list = parentWidget()->findChildren(); + QList::iterator it; + for (it = list.begin(); it != list.end(); ++it) { + if (((*it)->sizeHint().width()) > m_minWidth) { + m_increment = (int) ceil(((*it)->sizeHint().width() - m_minWidth) / m_pxw); + (*it)->setMinimumWidth(m_minWidth + m_increment * m_pxw); // for stepsize expansion of widgets + } + } + + // fix width of subgrids + QList::iterator i; + for (i = m_grids.begin(); i != m_grids.end(); ++i) { + (*i)->setColumnStretch(1, 1); + (*i)->setContentsMargins(0, 0, 0, 0); + for (int n = 0; n < (*i)->count(); n++) { + if ((*i)->itemAt(n)->widget()->sizeHint().width() > m_maxw[n % 4]) { + m_maxw[n % 4] = (*i)->itemAt(n)->widget()->sizeHint().width(); + } + if (n % 2) + (*i)->itemAt(n)->widget()->setMinimumWidth(m_minWidth); + else + (*i)->itemAt(n)->widget()->setMinimumWidth(m_maxw[n % 4]); + } + for (int j = 0; j < m_cols; j++) { + if (j % 2) + (*i)->setColumnMinimumWidth(j,m_maxw[j] + m_pxw); + else + (*i)->setColumnMinimumWidth(j,m_maxw[j]); + } + } + + for (int j = 0; j < m_cols; j++) { + if (j % 2) + setColumnMinimumWidth(j, m_maxw[j] + m_pxw); + else + setColumnMinimumWidth(j, m_maxw[j]); + } } unsigned GeneralTab::getColorspace() const @@ -939,6 +994,10 @@ void GeneralTab::changeAudioDevice() void GeneralTab::addWidget(QWidget *w, Qt::Alignment align) { + if (m_col % 2) + w->setMinimumWidth(m_minWidth); + if (w->sizeHint().width() > m_maxw[m_col]) + m_maxw[m_col] = w->sizeHint().width(); QGridLayout::addWidget(w, m_row, m_col, align | Qt::AlignVCenter); m_col++; if (m_col == m_cols) { @@ -947,6 +1006,24 @@ void GeneralTab::addWidget(QWidget *w, Qt::Alignment align) } } +int GeneralTab::getWidth() +{ + int total = 0; + + for (int i = 0; i < m_cols; i++) { + if (i % 2) + total += m_maxw[i] + m_pxw; + else + total += m_maxw[i]; + } + return total; +} + +int GeneralTab::getHeight() +{ + return m_row * 20; +} + bool GeneralTab::isSlicedVbi() const { return m_vbiMethods && m_vbiMethods->currentText() == "Sliced"; diff --git a/utils/qv4l2/general-tab.h b/utils/qv4l2/general-tab.h index 20b336f..bc09f2d 100644 --- a/utils/qv4l2/general-tab.h +++ b/utils/qv4l2/general-tab.h @@ -85,6 +85,8 @@ public: void sourceChange(const v4l2_event &ev); unsigned getDisplayColorspace() const; unsigned getColorspace() const; + int getWidth(); + int getHeight(); public slots: void showAllAudioDevices(bool use); @@ -128,6 +130,7 @@ private slots: void composeChanged(); private: + void fixWidth(); void updateGUI(int); void updateVideoInput(); void updateVideoOutput(); @@ -164,7 +167,7 @@ private: #endif void addWidget(QWidget *w, Qt::Alignment align = Qt::AlignLeft); - void addLabel(const QString &text, Qt::Alignment align = Qt::AlignRight) + void addLabel(const QString &text, Qt::Alignment align = Qt::AlignLeft) { addWidget(new QLabel(text, parentWidget()), align); } @@ -180,6 +183,10 @@ private: int m_row; int m_col; int m_cols; + int m_minWidth; + double m_pxw; + int m_increment; + int m_maxw[4]; bool m_isRadio; bool m_isSDR; bool m_isVbi; @@ -206,6 +213,7 @@ private: std::map m_audioOutDeviceMap; // General tab + QList m_grids; QStackedWidget *m_stackedStandards; QStackedWidget *m_stackedFrameSettings; QStackedWidget *m_stackedFrequency; diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp index 7ec477b..01df22b 100644 --- a/utils/qv4l2/qv4l2.cpp +++ b/utils/qv4l2/qv4l2.cpp @@ -74,6 +74,7 @@ ApplicationWindow::ApplicationWindow() : m_nbuffers = 0; m_buffers = NULL; m_makeSnapshot = false; + m_minWidth = 175; QAction *openAct = new QAction(QIcon(":/fileopen.png"), "&Open Device", this); openAct->setStatusTip("Open a v4l device, use libv4l2 wrapper if possible"); @@ -194,7 +195,6 @@ ApplicationWindow::ApplicationWindow() : statusBar()->showMessage("Ready", 2000); m_tabs = new QTabWidget; - m_tabs->setMinimumSize(300, 200); setCentralWidget(m_tabs); } @@ -223,6 +223,10 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen) QWidget *w = new QWidget(m_tabs); m_genTab = new GeneralTab(device, *this, 4, w); + int size[2]; + size[0] = m_genTab->getWidth(); + size[1] = m_genTab->getHeight(); + setMinimumSize(size[0] + 50, size[1] + 150); // +margins, menus #ifdef HAVE_ALSA if (m_genTab->hasAlsaAudio()) { @@ -241,7 +245,7 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen) connect(m_genTab, SIGNAL(displayColorspaceChanged()), this, SLOT(updateDisplayColorspace())); connect(m_genTab, SIGNAL(clearBuffers()), this, SLOT(clearBuffers())); m_tabs->addTab(w, "General Settings"); - addTabs(); + addTabs(size); if (caps() & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)) { w = new QWidget(m_tabs); m_vbiTab = new VbiTab(w); diff --git a/utils/qv4l2/qv4l2.h b/utils/qv4l2/qv4l2.h index 72e0095..2f21ddc 100644 --- a/utils/qv4l2/qv4l2.h +++ b/utils/qv4l2/qv4l2.h @@ -105,6 +105,7 @@ private: void startAudio(); void stopAudio(); + int m_maxw[4]; struct buffer *m_buffers; struct v4l2_format m_capSrcFormat; struct v4l2_format m_capDestFormat; @@ -155,11 +156,12 @@ public: private: void addWidget(QGridLayout *grid, QWidget *w, Qt::Alignment align = Qt::AlignLeft); - void addLabel(QGridLayout *grid, const QString &text, Qt::Alignment align = Qt::AlignRight) + void addLabel(QGridLayout *grid, const QString &text, Qt::Alignment align = Qt::AlignLeft) { addWidget(grid, new QLabel(text, parentWidget()), align); } - void addTabs(); + void fixWidth(QGridLayout *grid); + void addTabs(int size[]); void finishGrid(QGridLayout *grid, unsigned ctrl_class); void addCtrl(QGridLayout *grid, const struct v4l2_queryctrl &qctrl); void updateCtrl(unsigned id); @@ -186,6 +188,9 @@ private: void updateFreqChannel(); bool showFrames(); + double m_pxw; + double m_minWidth; + int m_increment; GeneralTab *m_genTab; VbiTab *m_vbiTab; QAction *m_capStartAct; -- 2.7.4