added styling options and rearranged preferences

This commit is contained in:
itsmattkc
2019-03-13 21:34:23 +11:00
parent 654c6f32c6
commit c634070368
14 changed files with 282 additions and 85 deletions
+83 -42
View File
@@ -194,7 +194,8 @@ void PreferencesDialog::save() {
// Check if any settings will require a restart of Olive
if (olive::CurrentConfig.use_software_fallback != use_software_fallbacks_checkbox->isChecked()
|| olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value()
|| olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) {
|| olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()
|| olive::CurrentConfig.style != static_cast<olive::styling::Style>(ui_style->currentData().toInt())) {
// any changes to these settings will require a restart - ask the user if we should do one now or later
@@ -234,8 +235,10 @@ void PreferencesDialog::save() {
}
// save settings from UI to backend
olive::CurrentConfig.css_path = custom_css_fn->text();
olive::MainWindow->load_css_from_file(olive::CurrentConfig.css_path);
if (olive::CurrentConfig.css_path != custom_css_fn->text()) {
olive::CurrentConfig.css_path = custom_css_fn->text();
olive::MainWindow->Restyle();
}
olive::CurrentConfig.recording_mode = recordingComboBox->currentIndex() + 1;
olive::CurrentConfig.img_seq_formats = imgSeqFormatEdit->text();
@@ -254,6 +257,9 @@ void PreferencesDialog::save() {
olive::CurrentConfig.use_software_fallback = use_software_fallbacks_checkbox->isChecked();
olive::CurrentConfig.language_file = language_combobox->currentData().toString();
olive::CurrentConfig.style = static_cast<olive::styling::Style>(ui_style->currentData().toInt());
// Check if the thumbnail or waveform icon
if (olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value()
|| olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) {
// we're changing the size of thumbnails and waveforms, so let's delete them and regenerate them next start
@@ -500,19 +506,6 @@ void PreferencesDialog::setup_ui() {
row++;
// General -> Custom CSS
general_layout->addWidget(new QLabel(tr("Custom CSS:"), this), row, 0);
custom_css_fn = new QLineEdit(general_tab);
custom_css_fn->setText(olive::CurrentConfig.css_path);
general_layout->addWidget(custom_css_fn, row, 1, 1, 3);
QPushButton* custom_css_browse = new QPushButton(tr("Browse"), general_tab);
connect(custom_css_browse, SIGNAL(clicked(bool)), this, SLOT(browse_css_file()));
general_layout->addWidget(custom_css_browse, row, 4);
row++;
// General -> Image Sequence Formats
general_layout->addWidget(new QLabel(tr("Image sequence formats:"), this), row, 0);
@@ -522,26 +515,6 @@ void PreferencesDialog::setup_ui() {
row++;
// General -> Audio Recording
general_layout->addWidget(new QLabel(tr("Audio Recording:"), this), row, 0);
recordingComboBox = new QComboBox(general_tab);
recordingComboBox->addItem(tr("Mono"));
recordingComboBox->addItem(tr("Stereo"));
general_layout->addWidget(recordingComboBox, row, 1, 1, 4);
row++;
// General -> Effect Textbox Lines
general_layout->addWidget(new QLabel(tr("Effect Textbox Lines:"), this), row, 0);
effect_textbox_lines_field = new QSpinBox(general_tab);
effect_textbox_lines_field->setMinimum(1);
effect_textbox_lines_field->setValue(olive::CurrentConfig.effect_textbox_lines);
general_layout->addWidget(effect_textbox_lines_field, row, 1, 1, 4);
row++;
// General -> Thumbnail and Waveform Resolution
general_layout->addWidget(new QLabel(tr("Thumbnail Resolution:"), this), row, 0);
@@ -583,6 +556,50 @@ void PreferencesDialog::setup_ui() {
add_default_effects_to_clips->setChecked(olive::CurrentConfig.add_default_effects_to_clips);
behavior_tab_layout->addWidget(add_default_effects_to_clips);
// Appearance
QWidget* appearance_tab = new QWidget(this);
tabWidget->addTab(appearance_tab, tr("Appearance"));
row = 0;
QGridLayout* appearance_layout = new QGridLayout(appearance_tab);
// Appearance -> Theme
appearance_layout->addWidget(new QLabel(tr("Theme")), row, 0);
ui_style = new QComboBox();
ui_style->addItem(tr("Olive Dark (Default)"), olive::styling::kOliveDefaultDark);
ui_style->addItem(tr("Olive Light"), olive::styling::kOliveDefaultLight);
ui_style->addItem(tr("Native"), olive::styling::kNativeDarkIcons);
ui_style->addItem(tr("Native (Light Icons)"), olive::styling::kNativeLightIcons);
ui_style->setCurrentIndex(olive::CurrentConfig.style);
appearance_layout->addWidget(ui_style, row, 1, 1, 2);
row++;
// Appearance -> Custom CSS
appearance_layout->addWidget(new QLabel(tr("Custom CSS:"), this), row, 0);
custom_css_fn = new QLineEdit(general_tab);
custom_css_fn->setText(olive::CurrentConfig.css_path);
appearance_layout->addWidget(custom_css_fn, row, 1);
QPushButton* custom_css_browse = new QPushButton(tr("Browse"), general_tab);
connect(custom_css_browse, SIGNAL(clicked(bool)), this, SLOT(browse_css_file()));
appearance_layout->addWidget(custom_css_browse, row, 2);
row++;
// Appearance -> Effect Textbox Lines
appearance_layout->addWidget(new QLabel(tr("Effect Textbox Lines:"), this), row, 0);
effect_textbox_lines_field = new QSpinBox(general_tab);
effect_textbox_lines_field->setMinimum(1);
effect_textbox_lines_field->setValue(olive::CurrentConfig.effect_textbox_lines);
appearance_layout->addWidget(effect_textbox_lines_field, row, 1, 1, 2);
row++;
// Playback
QWidget* playback_tab = new QWidget(this);
QVBoxLayout* playback_tab_layout = new QVBoxLayout(playback_tab);
@@ -630,7 +647,11 @@ void PreferencesDialog::setup_ui() {
QGridLayout* audio_tab_layout = new QGridLayout(audio_tab);
audio_tab_layout->addWidget(new QLabel(tr("Output Device:")), 0, 0);
row = 0;
// Audio -> Output Device
audio_tab_layout->addWidget(new QLabel(tr("Output Device:")), row, 0);
audio_output_devices = new QComboBox();
audio_output_devices->addItem(tr("Default"), "");
@@ -647,9 +668,13 @@ void PreferencesDialog::setup_ui() {
}
}
audio_tab_layout->addWidget(audio_output_devices, 0, 1);
audio_tab_layout->addWidget(audio_output_devices, row, 1);
audio_tab_layout->addWidget(new QLabel(tr("Input Device:")), 1, 0);
row++;
// Audio -> Input Device
audio_tab_layout->addWidget(new QLabel(tr("Input Device:")), row, 0);
audio_input_devices = new QComboBox();
audio_input_devices->addItem(tr("Default"), "");
@@ -666,9 +691,13 @@ void PreferencesDialog::setup_ui() {
}
}
audio_tab_layout->addWidget(audio_input_devices, 1, 1);
audio_tab_layout->addWidget(audio_input_devices, row, 1);
audio_tab_layout->addWidget(new QLabel(tr("Sample Rate:")), 2, 0);
row++;
// Audio -> Sample Rate
audio_tab_layout->addWidget(new QLabel(tr("Sample Rate:")), row, 0);
audio_sample_rate = new QComboBox();
combobox_audio_sample_rates(audio_sample_rate);
@@ -679,7 +708,19 @@ void PreferencesDialog::setup_ui() {
}
}
audio_tab_layout->addWidget(audio_sample_rate, 2, 1);
audio_tab_layout->addWidget(audio_sample_rate, row, 1);
row++;
// Audio -> Audio Recording
audio_tab_layout->addWidget(new QLabel(tr("Audio Recording:"), this), row, 0);
recordingComboBox = new QComboBox(general_tab);
recordingComboBox->addItem(tr("Mono"));
recordingComboBox->addItem(tr("Stereo"));
audio_tab_layout->addWidget(recordingComboBox, row, 1);
row++;
tabWidget->addTab(audio_tab, tr("Audio"));
+1
View File
@@ -93,6 +93,7 @@ private:
QSpinBox* thumbnail_res_spinbox;
QSpinBox* waveform_res_spinbox;
QCheckBox* add_default_effects_to_clips;
QComboBox* ui_style;
QVector<QAction*> key_shortcut_actions;
QVector<QTreeWidgetItem*> key_shortcut_items;
+1 -1
View File
@@ -595,7 +595,7 @@ void Effect::save(QXmlStreamWriter& stream) {
for (int j=0;j<row->FieldCount();j++) {
EffectField* field = row->Field(j);
if (field->id().isEmpty()) {
if (!field->id().isEmpty()) {
stream.writeStartElement("field"); // field
stream.writeAttribute("id", field->id());
for (int k=0;k<field->keyframes.size();k++) {
+4 -1
View File
@@ -85,6 +85,8 @@ void EffectRow::SetKeyframingEnabled(bool enabled) {
olive::UndoStack.push(ca);
update_ui(false);
} else {
// Confirm with the user whether they really want to disable keyframing
@@ -105,7 +107,8 @@ void EffectRow::SetKeyframingEnabled(bool enabled) {
ca->append(new SetIsKeyframing(this, false));
olive::UndoStack.push(ca);
panel_effect_controls->update_keyframes();
update_ui(false);
} else {
+6 -1
View File
@@ -71,7 +71,8 @@ Config::Config()
waveform_resolution(64),
thumbnail_resolution(120),
add_default_effects_to_clips(true),
invert_timeline_scroll_axes(true)
invert_timeline_scroll_axes(true),
style(olive::styling::kOliveDefaultDark)
{}
void Config::load(QString path) {
@@ -211,6 +212,9 @@ void Config::load(QString path) {
} else if (stream.name() == "AddDefaultEffectsToClips") {
stream.readNext();
add_default_effects_to_clips = (stream.text() == "1");
} else if (stream.name() == "Style") {
stream.readNext();
style = static_cast<olive::styling::Style>(stream.text().toInt());
}
}
}
@@ -278,6 +282,7 @@ void Config::save(QString path) {
stream.writeTextElement("ThumbnailResolution", QString::number(thumbnail_resolution));
stream.writeTextElement("WaveformResolution", QString::number(waveform_resolution));
stream.writeTextElement("AddDefaultEffectsToClips", QString::number(add_default_effects_to_clips));
stream.writeTextElement("Style", QString::number(style));
stream.writeEndElement(); // configuration
stream.writeEndDocument(); // doc
+9
View File
@@ -23,6 +23,8 @@
#include <QString>
#include "ui/styling.h"
namespace olive {
/**
* @brief Version identifier for saved projects
@@ -517,6 +519,13 @@ struct Config {
*/
bool invert_timeline_scroll_axes;
/**
* @brief Style to use when theming Olive.
*
* Set to a member of olive::styling::Style.
*/
olive::styling::Style style;
/**
* @brief Load config from file
*
+4 -2
View File
@@ -170,7 +170,8 @@ SOURCES += \
effects/fields/labelfield.cpp \
effects/fields/buttonfield.cpp \
ui/effectui.cpp \
effects/transition.cpp
effects/transition.cpp \
ui/styling.cpp
HEADERS += \
ui/mainwindow.h \
@@ -294,7 +295,8 @@ HEADERS += \
effects/fields/buttonfield.h \
effects/fields/colorfield.h \
effects/fields/combofield.h \
effects/transition.h
effects/transition.h \
ui/styling.h
FORMS +=
+16 -2
View File
@@ -1,6 +1,7 @@
#include "icons.h"
#include "oliveglobal.h"
#include "global/global.h"
#include "global/config.h"
QIcon olive::icon::LeftArrow;
QIcon olive::icon::RightArrow;
@@ -27,14 +28,27 @@ QIcon olive::icon::CreateIconFromSVG(const QString &path)
{
QIcon icon;
QPainter p;
// Draw the icon as a solid color
QPixmap normal(path);
if (olive::styling::UseDarkIcons()) {
p.begin(&normal);
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
p.fillRect(normal.rect(), QColor(32, 32, 32));
p.end();
}
icon.addPixmap(normal, QIcon::Normal, QIcon::On);
// Create semi-transparent disabled icon
QPixmap disabled(normal.size());
disabled.fill(Qt::transparent);
// draw semi-transparent version of icon for the disabled variant
QPainter p(&disabled);
p.begin(&disabled);
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
p.setOpacity(0.5);
p.drawPixmap(0, 0, normal);
p.end();
+8 -1
View File
@@ -25,6 +25,7 @@
#include "global/config.h"
#include "global/math.h"
#include "global/debug.h"
#include "ui/styling.h"
#include <QMouseEvent>
#include <QInputDialog>
@@ -119,7 +120,13 @@ QString LabelSlider::ValueToString() {
}
void LabelSlider::SetColor(QString c) {
if (c.isEmpty()) c = "#ffc000";
if (c.isEmpty()) {
if (olive::styling::UseDarkIcons()) {
c = "#0080ff";
} else {
c = "#ffc000";
}
}
setStyleSheet("QLabel{color:" + c + ";text-decoration:underline;}QLabel:disabled{color:#808080;}");
}
+46 -31
View File
@@ -194,7 +194,6 @@ MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
first_show(true)
{
olive::icon::Initialize();
olive::cursor::Initialize();
open_debug_file();
@@ -203,29 +202,6 @@ MainWindow::MainWindow(QWidget *parent) :
olive::MainWindow = this;
// set up style?
qApp->setStyle(QStyleFactory::create("Fusion"));
setStyleSheet(DEFAULT_CSS);
QPalette darkPalette;
darkPalette.setColor(QPalette::Window, QColor(53,53,53));
darkPalette.setColor(QPalette::WindowText, Qt::white);
darkPalette.setColor(QPalette::Base, QColor(25,25,25));
darkPalette.setColor(QPalette::AlternateBase, QColor(53,53,53));
darkPalette.setColor(QPalette::ToolTipBase, QColor(25,25,25));
darkPalette.setColor(QPalette::ToolTipText, Qt::white);
darkPalette.setColor(QPalette::Text, Qt::white);
darkPalette.setColor(QPalette::Button, QColor(53,53,53));
darkPalette.setColor(QPalette::ButtonText, Qt::white); darkPalette.setColor(QPalette::BrightText, Qt::red);
darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(128, 128, 128));
darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
darkPalette.setColor(QPalette::HighlightedText, Qt::black);
qApp->setPalette(darkPalette);
// end style
QWidget* centralWidget = new QWidget(this);
centralWidget->setMaximumSize(QSize(0, 0));
setCentralWidget(centralWidget);
@@ -296,13 +272,13 @@ MainWindow::MainWindow(QWidget *parent) :
QString config_fn = config_dir.filePath("config.xml");
if (QFileInfo::exists(config_fn)) {
olive::CurrentConfig.load(config_fn);
if (!olive::CurrentConfig.css_path.isEmpty()) {
load_css_from_file(olive::CurrentConfig.css_path);
}
}
}
Restyle();
olive::icon::Initialize();
alloc_panels(this);
// populate menu bars
@@ -413,14 +389,53 @@ void MainWindow::save_shortcuts(const QString& fn) {
}
}
void MainWindow::load_css_from_file(const QString &fn) {
bool MainWindow::load_css_from_file(const QString &fn) {
QFile css_file(fn);
if (css_file.exists() && css_file.open(QFile::ReadOnly)) {
setStyleSheet(css_file.readAll());
css_file.close();
return true;
}
return false;
}
void MainWindow::Restyle()
{
// Set up UI style
if (olive::styling::UseNativeUI()) {
qApp->setStyle(QStyleFactory::create(""));
} else {
// set default stylesheet
setStyleSheet(DEFAULT_CSS);
qApp->setStyle(QStyleFactory::create("Fusion"));
// Set up whether to load custom CSS or default CSS+palette
if (!olive::CurrentConfig.css_path.isEmpty()
&& load_css_from_file(olive::CurrentConfig.css_path)) {
setPalette(QPalette());
} else {
// set default palette
QPalette darkPalette;
darkPalette.setColor(QPalette::Window, QColor(53,53,53));
darkPalette.setColor(QPalette::WindowText, Qt::white);
darkPalette.setColor(QPalette::Base, QColor(25,25,25));
darkPalette.setColor(QPalette::AlternateBase, QColor(53,53,53));
darkPalette.setColor(QPalette::ToolTipBase, QColor(25,25,25));
darkPalette.setColor(QPalette::ToolTipText, Qt::white);
darkPalette.setColor(QPalette::Text, Qt::white);
darkPalette.setColor(QPalette::Button, QColor(53,53,53));
darkPalette.setColor(QPalette::ButtonText, Qt::white);
darkPalette.setColor(QPalette::BrightText, Qt::red);
darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(128, 128, 128));
darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
darkPalette.setColor(QPalette::HighlightedText, Qt::black);
qApp->setPalette(darkPalette);
// set default CSS
setStyleSheet(DEFAULT_CSS);
}
}
}
+10 -2
View File
@@ -73,8 +73,17 @@ public:
* @param fn
*
* URL to load the CSS file from.
*
* @return
*
* **TRUE** if CSS was successfully loaded.
*/
void load_css_from_file(const QString& fn);
bool load_css_from_file(const QString& fn);
/**
* @brief Set application's QStyle based on values from Config
*/
void Restyle();
public slots:
/**
@@ -248,7 +257,6 @@ private:
QAction* ripple_delete_inout_point_;
QAction* setedit_marker_;
// view menu actions
QMenu* view_menu;
QAction* zoom_in_;
+24
View File
@@ -0,0 +1,24 @@
#include "styling.h"
#include "global/config.h"
bool olive::styling::UseDarkIcons()
{
return olive::CurrentConfig.style == kOliveDefaultLight || olive::CurrentConfig.style == kNativeDarkIcons;
}
QColor olive::styling::GetIconColor()
{
if (UseDarkIcons()) {
return Qt::black;
} else {
return Qt::white;
}
}
bool olive::styling::UseNativeUI()
{
return olive::CurrentConfig.style == kNativeLightIcons || olive::CurrentConfig.style == kNativeDarkIcons;
}
+67
View File
@@ -0,0 +1,67 @@
#ifndef STYLING_H
#define STYLING_H
#include <QColor>
namespace olive {
namespace styling {
/**
* @brief Officially supported styles to use in Olive
*/
enum Style {
/**
Qt Fusion-based cross-platform UI. The default styling of Olive. Can also be heavily customized with a CSS
file.
*/
kOliveDefaultDark,
/**
Qt Fusion-based cross-platform UI. The default styling of Olive. Can also be heavily customized with a CSS
file. This will use the
*/
kOliveDefaultLight,
/**
Use current OS's native styling (or at least Qt's default). Most UIs use a light theming, so this will
automatically implement dark icons/UI elements.
*/
kNativeDarkIcons,
/**
Use current OS's native styling (or at least Qt's default). Most UIs use a light theming, but in case one
doesn't, this option will provide light icons for use with a dark theme.
*/
kNativeLightIcons
};
/**
* @brief Return whether to use dark icons or light icons
* @return
*
* **TRUE** if icons should be dark.
*/
bool UseDarkIcons();
/**
* @brief Return whether to use native UI or Fusion
* @return
*
* **TRUE** if UI should use native styling
*/
bool UseNativeUI();
/**
* @brief Return the current icon color based on Config::use_dark_icons.
*
* Also used by some other UI elements like the lines and text on the TimelineHeader
*
* @return
*
* Either white or black depending on Config::use_dark_icons
*/
QColor GetIconColor();
}
}
#endif // STYLING_H
+3 -2
View File
@@ -28,6 +28,7 @@
#include "project/media.h"
#include "panels/viewer.h"
#include "global/config.h"
#include "global/global.h"
#include "ui/menuhelper.h"
#include "global/debug.h"
@@ -393,7 +394,7 @@ void TimelineHeader::paintEvent(QPaintEvent*) {
if (lineX > lastLineX+LINE_MIN_PADDING) {
if (draw_text) {
p.setPen(Qt::white);
p.setPen(olive::styling::GetIconColor());
p.drawText(QRect(text_x, 0, fullTextWidth, yoff), timecode);
}
@@ -419,7 +420,7 @@ void TimelineHeader::paintEvent(QPaintEvent*) {
in_x = getHeaderScreenPointFromFrame((resizing_workarea ? temp_workarea_in : viewer->seq->workarea_in));
int out_x = getHeaderScreenPointFromFrame((resizing_workarea ? temp_workarea_out : viewer->seq->workarea_out));
p.fillRect(QRect(in_x, 0, out_x-in_x, height()), QColor(0, 192, 255, 128));
p.setPen(Qt::white);
p.setPen(olive::styling::GetIconColor());
p.drawLine(in_x, 0, in_x, height());
p.drawLine(out_x, 0, out_x, height());
}