MultiGeometryWidget template class abstracts window geometry changes

This commit is contained in:
Bill Somerville 2020-11-27 01:14:12 +00:00
parent 95cd992300
commit 3663b3ea32
No known key found for this signature in database
GPG Key ID: D864B06D1E81618F
4 changed files with 171 additions and 69 deletions

View File

@ -0,0 +1,92 @@
#ifndef MULTI_GEOMETRY_WIDGET_HPP__
#define MULTI_GEOMETRY_WIDGET_HPP__
#include <cstddef>
#include <utility>
#include <array>
#include <QWidget>
#include <QByteArray>
#include <QEvent>
//
// Class MultiGeometryWidget<N, Widget> - Decorate a QWidget type with
// switchable geometries
//
// The abstract base class imbues a Qt Widget type with N alternative
// geometries. Sub-classes can initialise the currently selected
// geometry and the initial geometries using geometries. To switch
// geometry call select_geometry(n) which saves the current geometry
// and switches to the n'th saved geometry.
//
template<std::size_t N, typename Widget=QWidget>
class MultiGeometryWidget
: public Widget
{
public:
template<typename... Args>
explicit MultiGeometryWidget (Args&&... args)
: Widget {std::forward<Args> (args)...}
, current_geometry_ {0}
{
}
void geometries (std::size_t current
, std::array<QByteArray, N> const& the_geometries = std::array<QByteArray, N> {})
{
Q_ASSERT (current < the_geometries.size ());
saved_geometries_ = the_geometries;
current_geometry_ = current;
Widget::restoreGeometry (saved_geometries_[current_geometry_]);
}
std::array<QByteArray, N> const& geometries () const {return saved_geometries_;}
std::size_t current () {return current_geometry_;}
// Call this to select a new geometry denoted by the 'n' argument,
// any actual layout changes should be made in the implementation of
// the change_layout operation below.
void select_geometry (std::size_t n)
{
Q_ASSERT (n < N);
auto geometry = Widget::saveGeometry ();
change_layout (n);
saved_geometries_[current_geometry_] = geometry;
current_geometry_ = n;
// Defer restoration of the window geometry until the layour
// request event has been processed, this is necessary otherwise
// the final geometry may be affected by widgets not shown in the
// new layout.
desired_geometry_ = saved_geometries_[n];
}
protected:
virtual ~MultiGeometryWidget () {}
private:
// Override this operation to implement any layout changes for the
// geometry specified by the argument 'n'.
virtual void change_layout (std::size_t n) = 0;
bool event (QEvent * e) override
{
auto ret = Widget::event (e);
if (QEvent::LayoutRequest == e->type ()
&& desired_geometry_.size ())
{
// Restore the new desired geometry and flag that we have done
// so by clearing the desired_geometry_ member variable.
QByteArray geometry;
std::swap (geometry, desired_geometry_);
Widget::restoreGeometry (geometry);
}
return ret;
}
std::size_t current_geometry_;
std::array<QByteArray, N> saved_geometries_;
QByteArray desired_geometry_;
};
#endif

View File

@ -236,7 +236,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
MultiSettings * multi_settings, QSharedMemory *shdmem,
unsigned downSampleFactor,
QSplashScreen * splash, QProcessEnvironment const& env, QWidget *parent) :
QMainWindow(parent),
MultiGeometryWidget {parent},
m_env {env},
m_network_manager {this},
m_valid {true},
@ -1022,10 +1022,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
}
ui->pbBestSP->setVisible(m_mode=="FT4");
if(!ui->cbMenus->isChecked()) {
ui->cbMenus->setChecked(true);
ui->cbMenus->setChecked(false);
}
// this must be the last statement of constructor
if (!m_valid) throw std::runtime_error {"Fatal initialization exception"};
}
@ -1094,8 +1091,33 @@ MainWindow::~MainWindow()
void MainWindow::writeSettings()
{
m_settings->beginGroup("MainWindow");
m_settings->setValue ("geometry", saveGeometry ());
m_settings->setValue ("geometryNoControls", m_geometryNoControls);
if (ui->actionSWL_Mode->isChecked ())
{
m_settings->setValue ("SWLView", true);
m_settings->setValue ("ShowMenus", ui->cbMenus->isChecked ());
m_settings->setValue ("geometry", geometries ()[0]);
m_settings->setValue ("SWLModeGeometry", saveGeometry ());
m_settings->setValue ("geometryNoControls", geometries ()[2]);
}
else
{
if (ui->cbMenus->isChecked())
{
m_settings->setValue ("SWLView", ui->actionSWL_Mode->isChecked ());
m_settings->setValue ("ShowMenus", true);
m_settings->setValue ("geometry", saveGeometry ());
m_settings->setValue ("SWLModeGeometry", geometries ()[1]);
m_settings->setValue ("geometryNoControls", geometries ()[2]);
}
else
{
m_settings->setValue ("SWLView", ui->actionSWL_Mode->isChecked ());
m_settings->setValue ("ShowMenus", false);
m_settings->setValue ("geometry", geometries ()[0]);
m_settings->setValue ("SWLModeGeometry", geometries ()[1]);
m_settings->setValue ("geometryNoControls", saveGeometry ());
}
}
m_settings->setValue ("state", saveState ());
m_settings->setValue("MRUdir", m_path);
m_settings->setValue("TxFirst",m_txFirst);
@ -1105,7 +1127,6 @@ void MainWindow::writeSettings()
m_settings->setValue ("MsgAvgDisplayed", m_msgAvgWidget && m_msgAvgWidget->isVisible ());
m_settings->setValue ("FoxLogDisplayed", m_foxLogWindow && m_foxLogWindow->isVisible ());
m_settings->setValue ("ContestLogDisplayed", m_contestLogWindow && m_contestLogWindow->isVisible ());
m_settings->setValue("ShowMenus",ui->cbMenus->isChecked());
m_settings->setValue("CallFirst",ui->cbFirst->isChecked());
m_settings->setValue("HoundSort",ui->comboBoxHoundSort->currentIndex());
m_settings->setValue("FoxNlist",ui->sbNlist->value());
@ -1159,9 +1180,8 @@ void MainWindow::writeSettings()
m_settings->setValue("pwrBandTuneMemory",m_pwrBandTuneMemory);
m_settings->setValue ("FT8AP", ui->actionEnable_AP_FT8->isChecked ());
m_settings->setValue ("JT65AP", ui->actionEnable_AP_JT65->isChecked ());
m_settings->setValue("SplitterState",ui->splitter->saveState());
m_settings->setValue("SplitterState",ui->decodes_splitter->saveState());
m_settings->setValue("Blanker",ui->sbNB->value());
m_settings->setValue ("SWLView", ui->actionSWL_Mode->isChecked ());
{
QList<QVariant> coeffs; // suitable for QSettings
@ -1180,8 +1200,17 @@ void MainWindow::readSettings()
ui->cbAutoSeq->setVisible(false);
ui->cbFirst->setVisible(false);
m_settings->beginGroup("MainWindow");
restoreGeometry (m_settings->value ("geometry", saveGeometry ()).toByteArray ());
m_geometryNoControls = m_settings->value ("geometryNoControls",saveGeometry()).toByteArray();
std::array<QByteArray, 3> the_geometries;
the_geometries[0] = m_settings->value ("geometry", saveGeometry ()).toByteArray ();
the_geometries[1] = m_settings->value ("SWLModeGeometry", saveGeometry ()).toByteArray ();
the_geometries[2] = m_settings->value ("geometryNoControls", saveGeometry ()).toByteArray ();
auto SWL_mode = m_settings->value ("SWLView", false).toBool ();
auto show_menus = m_settings->value ("ShowMenus", true).toBool ();
ui->actionSWL_Mode->setChecked (SWL_mode);
ui->cbMenus->setChecked (show_menus);
auto current_view_mode = SWL_mode ? 1 : show_menus ? 0 : 2;
change_layout (current_view_mode);
geometries (current_view_mode, the_geometries);
restoreState (m_settings->value ("state", saveState ()).toByteArray ());
ui->dxCallEntry->setText (m_settings->value ("DXcall", QString {}).toString ());
ui->dxGridEntry->setText (m_settings->value ("DXgrid", QString {}).toString ());
@ -1191,7 +1220,6 @@ void MainWindow::readSettings()
auto displayMsgAvg = m_settings->value ("MsgAvgDisplayed", false).toBool ();
auto displayFoxLog = m_settings->value ("FoxLogDisplayed", false).toBool ();
auto displayContestLog = m_settings->value ("ContestLogDisplayed", false).toBool ();
ui->cbMenus->setChecked(m_settings->value("ShowMenus",true).toBool());
ui->cbFirst->setChecked(m_settings->value("CallFirst",true).toBool());
ui->comboBoxHoundSort->setCurrentIndex(m_settings->value("HoundSort",3).toInt());
ui->sbNlist->setValue(m_settings->value("FoxNlist",12).toInt());
@ -1265,10 +1293,8 @@ void MainWindow::readSettings()
m_pwrBandTuneMemory=m_settings->value("pwrBandTuneMemory").toHash();
ui->actionEnable_AP_FT8->setChecked (m_settings->value ("FT8AP", false).toBool());
ui->actionEnable_AP_JT65->setChecked (m_settings->value ("JT65AP", false).toBool());
ui->splitter->restoreState(m_settings->value("SplitterState").toByteArray());
ui->decodes_splitter->restoreState(m_settings->value("SplitterState").toByteArray());
ui->sbNB->setValue(m_settings->value("Blanker",0).toInt());
ui->actionSWL_Mode->setChecked (m_settings->value ("SWLView", false).toBool ());
on_actionSWL_Mode_triggered (ui->actionSWL_Mode->isChecked ());
{
auto const& coeffs = m_settings->value ("PhaseEqualizationCoefficients"
, QList<QVariant> {0., 0., 0., 0., 0.}).toList ();
@ -2568,34 +2594,47 @@ void MainWindow::on_actionCopyright_Notice_triggered()
MessageBox::warning_message(this, message);
}
// Implement the MultiGeometryWidget::change_layout() operation.
void MainWindow::change_layout (std::size_t n)
{
switch (n)
{
case 1: // SWL view
ui->menuBar->show ();
ui->lower_panel_widget->hide ();
trim_view (false); // ensure we can switch back
break;
case 2: // hide menus view
ui->menuBar->hide ();
ui->lower_panel_widget->show ();
trim_view (true);
break;
default: // normal view
ui->menuBar->setVisible (ui->cbMenus->isChecked ());
ui->lower_panel_widget->show ();
trim_view (!ui->cbMenus->isChecked ());
break;
}
}
void MainWindow::on_actionSWL_Mode_triggered (bool checked)
{
ui->lower_panel_widget->setVisible (!checked);
if (checked)
{
hideMenus (false); // make sure we can be turned off
}
select_geometry (checked ? 1 : ui->cbMenus->isChecked () ? 0 : 2);
}
// This allows the window to shrink by removing certain things
// and reducing space used by controls
void MainWindow::hideMenus(bool checked)
void MainWindow::trim_view (bool checked)
{
int spacing = checked ? 1 : 6;
if (checked) {
statusBar ()->removeWidget (&auto_tx_label);
minimumSize().setHeight(450);
minimumSize().setWidth(700);
restoreGeometry(m_geometryNoControls);
updateGeometry();
} else {
m_geometryNoControls = saveGeometry();
statusBar ()->addWidget(&auto_tx_label);
minimumSize().setHeight(520);
minimumSize().setWidth(770);
}
ui->menuBar->setVisible(!checked);
if(m_mode!="FreqCal" and m_mode!="WSPR" and m_mode!="FST4W") {
if (m_mode != "FreqCal" && m_mode != "WSPR" && m_mode != "FST4W") {
ui->lh_decodes_title_label->setVisible(!checked);
ui->rh_decodes_title_label->setVisible(!checked);
}
@ -8437,7 +8476,7 @@ void MainWindow::update_watchdog_label ()
void MainWindow::on_cbMenus_toggled(bool b)
{
hideMenus(!b);
select_geometry (!b ? 2 : ui->actionSWL_Mode->isChecked () ? 1 : 0);
}
void MainWindow::on_cbCQonly_toggled(bool)

View File

@ -26,6 +26,7 @@
#include <QFuture>
#include <QFutureWatcher>
#include "MultiGeometryWidget.hpp"
#include "NonInheritingProcess.hpp"
#include "Audio/AudioDevice.hpp"
#include "commons.h"
@ -94,7 +95,8 @@ class MultiSettings;
class EqualizationToolsDialog;
class DecodedText;
class MainWindow : public QMainWindow
class MainWindow
: public MultiGeometryWidget<3, QMainWindow>
{
Q_OBJECT;
@ -130,7 +132,8 @@ public slots:
void msgAvgDecode2();
void fastPick(int x0, int x1, int y);
protected:
private:
void change_layout (std::size_t) override;
void keyPressEvent (QKeyEvent *) override;
void closeEvent(QCloseEvent *) override;
void childEvent(QChildEvent *) override;
@ -353,7 +356,7 @@ private:
void astroUpdate ();
void writeAllTxt(QString message);
void auto_sequence (DecodedText const& message, unsigned start_tolerance, unsigned stop_tolerance);
void hideMenus(bool b);
void trim_view (bool b);
void foxTest();
void setColorHighlighting();
void chkFT4();

View File

@ -2,20 +2,6 @@
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>692</width>
<height>498</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>WSJT-X by K1JT</string>
</property>
@ -25,7 +11,7 @@
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout_6" stretch="0,0">
<item>
<widget class="QSplitter" name="splitter">
<widget class="QSplitter" name="decodes_splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@ -148,18 +134,6 @@
</item>
<item>
<widget class="DisplayText" name="decodedTextBrowser">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>10</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>100</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
@ -307,12 +281,6 @@
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>100</height>
</size>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
@ -2857,7 +2825,7 @@ Double-click to reset to the standard 73 message</string>
<rect>
<x>0</x>
<y>0</y>
<width>692</width>
<width>834</width>
<height>21</height>
</rect>
</property>