Commit 2d61e288 authored by Bryant's avatar Bryant

Reworked the styling UI. Now there are 4 options: light, dark, custom_light,...

Reworked the styling UI. Now there are 4 options: light, dark, custom_light, and custom_dark. Things don't quite work right, but the proof-of-concept is done.
parent 2b07ea50
......@@ -96,7 +96,7 @@ MainWindow* MainWindow::instance(QSplashScreen* screen)
MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent),
currentView(VIEW_FLIGHT),
currentStyle(QGC_MAINWINDOW_STYLE_INDOOR),
currentStyle(QGC_MAINWINDOW_STYLE_DARK),
aboutToCloseFlag(false),
changingViewsFlag(false),
centerStackActionGroup(new QActionGroup(this)),
......@@ -111,7 +111,7 @@ MainWindow::MainWindow(QWidget *parent):
loadSettings();
emit initStatusChanged("Loading Style.");
loadStyle(currentStyle);
loadStyle(currentStyle, QString());
if (settings.contains("ADVANCED_MODE"))
{
......@@ -182,8 +182,6 @@ MainWindow::MainWindow(QWidget *parent):
setStatusBar(customStatusBar);
statusBar()->setSizeGripEnabled(true);
emit initStatusChanged("Building common widgets.");
buildCommonWidgets();
......@@ -1220,96 +1218,47 @@ void MainWindow::enableAutoReconnect(bool enabled)
autoReconnect = enabled;
}
void MainWindow::loadNativeStyle()
{
loadStyle(QGC_MAINWINDOW_STYLE_NATIVE);
}
void MainWindow::loadIndoorStyle()
bool MainWindow::loadStyle(QGC_MAINWINDOW_STYLE style, QString cssFile)
{
loadStyle(QGC_MAINWINDOW_STYLE_INDOOR);
}
void MainWindow::loadOutdoorStyle()
{
loadStyle(QGC_MAINWINDOW_STYLE_OUTDOOR);
}
void MainWindow::loadStyle(QGC_MAINWINDOW_STYLE style)
{
switch (style) {
case QGC_MAINWINDOW_STYLE_NATIVE: {
// Native mode means setting no style
// so if we were already in native mode
// take no action
// Only if a style was set, remove it.
if (style != currentStyle) {
qApp->setStyleSheet("");
showInfoMessage(tr("Please restart QGroundControl"), tr("Please restart QGroundControl to switch to fully native look and feel. Currently you have loaded Qt's plastique style."));
}
}
break;
case QGC_MAINWINDOW_STYLE_INDOOR:
qApp->setStyle("plastique");
styleFileName = ":files/styles/style-indoor.css";
reloadStylesheet();
// Set up the
switch (style)
{
default:
style = QGC_MAINWINDOW_STYLE_DARK;
case QGC_MAINWINDOW_STYLE_DARK:
styleFileName = ":files/styles/style-dark.css";
break;
case QGC_MAINWINDOW_STYLE_OUTDOOR:
qApp->setStyle("plastique");
styleFileName = ":files/styles/style-outdoor.css";
reloadStylesheet();
case QGC_MAINWINDOW_STYLE_LIGHT:
styleFileName = ":files/styles/style-light.css";
break;
case QGC_MAINWINDOW_STYLE_CUSTOM_DARK:
case QGC_MAINWINDOW_STYLE_CUSTOM_LIGHT:
styleFileName = cssFile;
break;
}
currentStyle = style;
}
void MainWindow::selectStylesheet()
{
// Let user select style sheet
QString newStyleFileName = QFileDialog::getOpenFileName(this, tr("Specify stylesheet"), styleFileName, tr("CSS Stylesheet (*.css);;"));
// Load the new style sheet if a valid one was selected.
if (!newStyleFileName.isNull())
{
QFile styleSheet(newStyleFileName);
if (styleSheet.exists())
{
styleFileName = newStyleFileName;
reloadStylesheet();
}
}
return loadStyleSheet(styleFileName);
}
void MainWindow::reloadStylesheet()
bool MainWindow::loadStyleSheet(QString cssFile)
{
// Load style sheet
QFile styleSheet(styleFileName);
// Default to the indoor stylesheet if an invalid stylesheet was chosen.
if (!styleSheet.exists())
{
styleSheet.setFileName(":files/styles/style-indoor.css");
}
// Load the new stylesheet.
// We also replace an 'ICONDIR' token here with the proper application path.
QFile styleSheet(cssFile);
// Attempt to open the stylesheet, replacing the 'ICONDIR' token here with the proper application path.
if (styleSheet.open(QIODevice::ReadOnly | QIODevice::Text))
{
QString style = QString(styleSheet.readAll());
style.replace("ICONDIR", QCoreApplication::applicationDirPath()+ "files/styles/");
qApp->setStyleSheet(style);
return true;
}
// Otherwise alert the user to the failure.
else
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Information);
msgBox.setText(tr("QGroundControl did not load a new style"));
msgBox.setInformativeText(tr("Stylesheet file %1 was not readable").arg(styleFileName));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
// Otherwise alert return a failure code.
return false;
}
/**
......@@ -1450,9 +1399,6 @@ void MainWindow::connectCommonActions()
connect(ui.actionFirmwareUpdateView, SIGNAL(triggered()), this, SLOT(loadFirmwareUpdateView()));
connect(ui.actionMavlinkView, SIGNAL(triggered()), this, SLOT(loadMAVLinkView()));
connect(ui.actionReloadStylesheet, SIGNAL(triggered()), this, SLOT(reloadStylesheet()));
connect(ui.actionSelectStylesheet, SIGNAL(triggered()), this, SLOT(selectStylesheet()));
// Help Actions
connect(ui.actionOnline_Documentation, SIGNAL(triggered()), this, SLOT(showHelp()));
connect(ui.actionDeveloper_Credits, SIGNAL(triggered()), this, SLOT(showCredits()));
......
......@@ -103,9 +103,10 @@ public:
enum QGC_MAINWINDOW_STYLE
{
QGC_MAINWINDOW_STYLE_NATIVE,
QGC_MAINWINDOW_STYLE_INDOOR,
QGC_MAINWINDOW_STYLE_OUTDOOR
QGC_MAINWINDOW_STYLE_DARK,
QGC_MAINWINDOW_STYLE_LIGHT,
QGC_MAINWINDOW_STYLE_CUSTOM_DARK,
QGC_MAINWINDOW_STYLE_CUSTOM_LIGHT
};
/** @brief Get current visual style */
......@@ -113,6 +114,12 @@ public:
{
return currentStyle;
}
/** @brief Get current visual style */
QString getStyleSheet()
{
return styleFileName;
}
/** @brief Get auto link reconnect setting */
bool autoReconnectEnabled()
{
......@@ -188,24 +195,17 @@ public slots:
/** @brief Show the project roadmap */
void showRoadMap();
/** @brief Reload the CSS style sheet */
void reloadStylesheet();
/** @brief Let the user select the CSS style sheet */
void selectStylesheet();
/** @breif Enable title bars on dock widgets when no in advanced mode */
void enableDockWidgetTitleBars(bool enabled);
/** @brief Automatically reconnect last link */
void enableAutoReconnect(bool enabled);
/** @brief Save power by reducing update rates */
void enableLowPowerMode(bool enabled) { lowPowerMode = enabled; }
/** @brief Switch to native application style */
void loadNativeStyle();
/** @brief Switch to indoor mission style */
void loadIndoorStyle();
/** @brief Switch to outdoor mission style */
void loadOutdoorStyle();
/** @brief Load a specific style */
void loadStyle(QGC_MAINWINDOW_STYLE style);
/** @brief Load a specific style.
* If it's a custom style, load the file indicated by the cssFile path.
*/
bool loadStyle(QGC_MAINWINDOW_STYLE style, QString cssFile);
bool loadStyleSheet(QString cssFile);
/** @brief Add a custom tool widget */
void createCustomWidget();
......
......@@ -51,27 +51,19 @@
<x>0</x>
<y>0</y>
<width>800</width>
<height>22</height>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuMGround">
<property name="title">
<string>File</string>
</property>
<widget class="QMenu" name="menuPreferences">
<property name="title">
<string>Display</string>
</property>
<addaction name="actionSelectStylesheet"/>
<addaction name="actionReloadStylesheet"/>
</widget>
<addaction name="actionJoystick_Settings"/>
<addaction name="actionSimulate"/>
<addaction name="separator"/>
<addaction name="actionMuteAudioOutput"/>
<addaction name="actionJoystickSettings"/>
<addaction name="actionSettings"/>
<addaction name="menuPreferences"/>
<addaction name="actionAdvanced_Mode"/>
<addaction name="separator"/>
<addaction name="actionExit"/>
......@@ -321,15 +313,6 @@
<string>Meta+M</string>
</property>
</action>
<action name="actionSelectStylesheet">
<property name="icon">
<iconset resource="../../qgroundcontrol.qrc">
<normaloff>:/files/images/categories/applications-internet.svg</normaloff>:/files/images/categories/applications-internet.svg</iconset>
</property>
<property name="text">
<string>Select Stylesheet</string>
</property>
</action>
<action name="actionFlightView">
<property name="checkable">
<bool>true</bool>
......@@ -400,14 +383,6 @@
<string>Shutdown the onboard computer - works not during flight</string>
</property>
</action>
<action name="actionReloadStylesheet">
<property name="text">
<string>Reload Stylesheet</string>
</property>
<property name="shortcut">
<string>Meta+R</string>
</property>
</action>
<action name="actionSettings">
<property name="text">
<string>Settings</string>
......
......@@ -17,6 +17,9 @@ QGCSettingsWidget::QGCSettingsWidget(QWidget *parent, Qt::WindowFlags flags) :
{
ui->setupUi(this);
// Set the frame holding the options for the custom style frame to hidden by default
ui->customStyleFrame->setVisible(false);
// Add all protocols
QList<ProtocolInterface*> protocols = LinkManager::instance()->getProtocols();
foreach (ProtocolInterface* protocol, protocols) {
......@@ -48,29 +51,95 @@ QGCSettingsWidget::QGCSettingsWidget(QWidget *parent, Qt::WindowFlags flags) :
// Style
MainWindow::QGC_MAINWINDOW_STYLE style = (MainWindow::QGC_MAINWINDOW_STYLE)MainWindow::instance()->getStyle();
switch (style) {
case MainWindow::QGC_MAINWINDOW_STYLE_NATIVE:
ui->nativeStyle->setChecked(true);
break;
case MainWindow::QGC_MAINWINDOW_STYLE_INDOOR:
ui->indoorStyle->setChecked(true);
break;
case MainWindow::QGC_MAINWINDOW_STYLE_OUTDOOR:
ui->outdoorStyle->setChecked(true);
break;
}
connect(ui->nativeStyle, SIGNAL(clicked()), MainWindow::instance(), SLOT(loadNativeStyle()));
connect(ui->indoorStyle, SIGNAL(clicked()), MainWindow::instance(), SLOT(loadIndoorStyle()));
connect(ui->outdoorStyle, SIGNAL(clicked()), MainWindow::instance(), SLOT(loadOutdoorStyle()));
ui->styleChooser->setCurrentIndex(style);
connect(ui->styleChooser, SIGNAL(currentIndexChanged(int)), this, SLOT(styleChanged(int)));
connect(ui->customStyleFileButton, SIGNAL(clicked()), this, SLOT(selectStylesheet()));
// Close / destroy
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(deleteLater()));
// Set layout options
ui->generalPaneGridLayout->setAlignment(Qt::AlignTop);
}
QGCSettingsWidget::~QGCSettingsWidget()
{
delete ui;
}
void QGCSettingsWidget::selectStylesheet()
{
// Let user select style sheet. The root directory for the file picker is the user's home directory if they haven't loaded a custom style.
// Otherwise it defaults to the directory of that custom file.
QString findDir;
if (MainWindow::instance()->getStyle() == MainWindow::QGC_MAINWINDOW_STYLE_CUSTOM_DARK || MainWindow::instance()->getStyle() == MainWindow::QGC_MAINWINDOW_STYLE_CUSTOM_LIGHT)
{
findDir = QDir::homePath();
}
else
{
findDir = MainWindow::instance()->getStyleSheet();
}
QString newStyleFileName = QFileDialog::getOpenFileName(this, tr("Specify stylesheet"), findDir, tr("CSS Stylesheet (*.css);;"));
// Load the new style sheet if a valid one was selected.
if (!newStyleFileName.isNull())
{
QFile styleSheet(newStyleFileName);
if (styleSheet.exists())
{
if (!updateStyle())
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Information);
msgBox.setText(tr("QGroundControl did not load a new style"));
msgBox.setInformativeText(tr("Stylesheet file %1 was not readable").arg(newStyleFileName));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
}
else
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Information);
msgBox.setText(tr("QGroundControl did not load a new style"));
msgBox.setInformativeText(tr("Stylesheet file %1 was not readable").arg(newStyleFileName));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
}
}
bool QGCSettingsWidget::updateStyle()
{
switch (ui->styleChooser->currentIndex())
{
case 0:
return MainWindow::instance()->loadStyle(MainWindow::QGC_MAINWINDOW_STYLE_DARK, QString());
case 1:
return MainWindow::instance()->loadStyle(MainWindow::QGC_MAINWINDOW_STYLE_LIGHT, QString());
case 2:
return MainWindow::instance()->loadStyle(MainWindow::QGC_MAINWINDOW_STYLE_CUSTOM_DARK, QString());
case 3:
return MainWindow::instance()->loadStyle(MainWindow::QGC_MAINWINDOW_STYLE_CUSTOM_LIGHT, QString());
default:
return false;
}
}
void QGCSettingsWidget::styleChanged(int index)
{
// If a custom style is selected, enable the advanced view for the custom stylesheet. Otherwise,
// make sure it's hidden.
if (index == 2 || index == 3)
{
ui->customStyleFrame->setVisible(true);
}
else
{
ui->customStyleFrame->setVisible(false);
}
// And trigger a style update.
updateStyle();
}
\ No newline at end of file
......@@ -17,9 +17,12 @@ public:
~QGCSettingsWidget();
public slots:
void styleChanged(int index);
private:
Ui::QGCSettingsWidget *ui;
void selectStylesheet();
bool updateStyle();
};
#endif // QGCSETTINGSWIDGET_H
......@@ -10,6 +10,12 @@
<height>427</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
......@@ -23,8 +29,8 @@
<attribute name="toolTip">
<string>General Settings</string>
</attribute>
<layout class="QGridLayout" name="generalPaneGridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="audioMuteCheckBox">
<property name="text">
<string>Mute all audio output</string>
......@@ -35,7 +41,7 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item>
<widget class="QCheckBox" name="reconnectCheckBox">
<property name="text">
<string>Automatically reconnect last link on application startup</string>
......@@ -46,31 +52,7 @@
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QRadioButton" name="nativeStyle">
<property name="text">
<string>Use native platform look and feel (Windows/Linux/Mac OS)</string>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QRadioButton" name="indoorStyle">
<property name="text">
<string>Use indoor mission style (black background)</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QRadioButton" name="outdoorStyle">
<property name="text">
<string>Use outdoor mission style (light background)</string>
</property>
</widget>
</item>
<item row="2" column="0">
<item>
<widget class="QCheckBox" name="lowPowerCheckBox">
<property name="toolTip">
<string>Lowers all update rates to save battery power</string>
......@@ -80,7 +62,7 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item>
<widget class="QCheckBox" name="titleBarCheckBox">
<property name="text">
<string>Show Docked Widget title bars when NOT in advanced Mode.</string>
......@@ -90,6 +72,76 @@
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="styleFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QComboBox" name="styleChooser">
<item>
<property name="text">
<string>Dark (for indoor use)</string>
</property>
</item>
<item>
<property name="text">
<string>Light (for outdoor use)</string>
</property>
</item>
<item>
<property name="text">
<string>Custom dark (for indoor use)</string>
</property>
</item>
<item>
<property name="text">
<string>Custom light (for outdoor use)</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QFrame" name="customStyleFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QPushButton" name="customStyleFileButton">
<property name="text">
<string>Select</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment