This commit is contained in:
itsmattkc
2020-05-06 00:11:09 +10:00
41 changed files with 230 additions and 90 deletions
+10
View File
@@ -83,6 +83,16 @@ void Config::SetDefaults()
config_map_["DropWithoutSequenceBehavior"] = TimelineWidget::kDWSAsk;
config_map_["Loop"] = false;
config_map_["NodeCatColor0"] = QVariant::fromValue(Color(0.25, 0.25, 0.65));
config_map_["NodeCatColor1"] = QVariant::fromValue(Color(0.6, 0.6, 0.85));
config_map_["NodeCatColor2"] = QVariant::fromValue(Color(0.75, 0.75, 0.45));
config_map_["NodeCatColor3"] = QVariant::fromValue(Color(0.25, 0.5, 0.25));
config_map_["NodeCatColor4"] = QVariant::fromValue(Color(0.25, 0.65, 0.25));
config_map_["NodeCatColor5"] = QVariant::fromValue(Color(0.35, 0.35, 0.35));
config_map_["NodeCatColor6"] = QVariant::fromValue(Color(0.45, 0.45, 0.45));
config_map_["NodeCatColor7"] = QVariant::fromValue(Color(0.7, 0.3, 0.7));
config_map_["NodeCatColor8"] = QVariant::fromValue(Color(0.85, 0.65, 0.4));
config_map_["AudioOutput"] = QString();
config_map_["AudioInput"] = QString();
@@ -20,10 +20,14 @@
#include "preferencesappearancetab.h"
#include <QColorDialog>
#include <QFileDialog>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QPushButton>
#include "node/node.h"
#include "widget/colorbutton/colorbutton.h"
OLIVE_NAMESPACE_ENTER
@@ -44,7 +48,7 @@ PreferencesAppearanceTab::PreferencesAppearanceTab()
style_list_ = StyleManager::ListInternal();
foreach (StyleDescriptor s, style_list_) {
foreach (const StyleDescriptor& s, style_list_) {
style_->addItem(s.name(), s.path());
if (s.path() == StyleManager::GetStyle()) {
@@ -52,10 +56,34 @@ PreferencesAppearanceTab::PreferencesAppearanceTab()
}
}
appearance_layout->addWidget(style_, row, 1, 1, 2);
appearance_layout->addWidget(style_, row, 1);
row++;
{
QGroupBox* color_group = new QGroupBox();
color_group->setTitle(tr("Node Color Scheme"));
QGridLayout* color_layout = new QGridLayout(color_group);
for (int i=0; i<Node::kCategoryCount; i++) {
QString cat_name = Node::GetCategoryName(static_cast<Node::CategoryID>(i));
color_layout->addWidget(new QLabel(cat_name), i, 0);
Color c = Config::Current()[QStringLiteral("NodeCatColor%1").arg(i)].value<Color>();
colors_.append(c.toQColor());
QPushButton* color_btn = new QPushButton();
connect(color_btn, &QPushButton::clicked, this, &PreferencesAppearanceTab::ColorButtonClicked);
color_layout->addWidget(color_btn, i, 1);
color_btns_.append(color_btn);
UpdateButtonColor(i);
}
appearance_layout->addWidget(color_group, row, 0, 1, 2);
}
layout->addStretch();
}
@@ -67,6 +95,29 @@ void PreferencesAppearanceTab::Accept()
StyleManager::SetStyle(style_path);
Config::Current()["Style"] = style_path;
}
for (int i=0;i<colors_.size();i++) {
Config::Current()[QStringLiteral("NodeCatColor%1").arg(i)] = QVariant::fromValue(Color(colors_.at(i)));
}
}
void PreferencesAppearanceTab::UpdateButtonColor(int index)
{
color_btns_.at(index)->setStyleSheet(QStringLiteral("background: %1;")
.arg(colors_.at(index).name()));
}
void PreferencesAppearanceTab::ColorButtonClicked()
{
int index = color_btns_.indexOf(static_cast<QPushButton*>(sender()));
QColor new_color = QColorDialog::getColor(colors_.at(index), this);
if (new_color.isValid()) {
colors_.replace(index, new_color);
UpdateButtonColor(index);
}
}
OLIVE_NAMESPACE_EXIT
@@ -23,6 +23,7 @@
#include <QComboBox>
#include <QLineEdit>
#include <QPushButton>
#include "preferencestab.h"
#include "ui/style/style.h"
@@ -43,6 +44,8 @@ private:
*/
void BrowseForCSS();
void UpdateButtonColor(int index);
/**
* @brief UI widget for selecting the current UI style
*/
@@ -54,6 +57,14 @@ private:
QList<StyleDescriptor> style_list_;
QString custom_style_path_;
QList<QColor> colors_;
QList<QPushButton*> color_btns_;
private slots:
void ColorButtonClicked();
};
OLIVE_NAMESPACE_EXIT
+3 -3
View File
@@ -49,9 +49,9 @@ QString PanNode::id() const
return QStringLiteral("org.olivevideoeditor.Olive.pan");
}
QString PanNode::Category() const
QList<Node::CategoryID> PanNode::Category() const
{
return tr("Audio");
return {kCategoryChannels};
}
QString PanNode::Description() const
@@ -64,7 +64,7 @@ Node::Capabilities PanNode::GetCapabilities(const NodeValueDatabase &) const
return kSampleProcessor;
}
NodeInput *PanNode::ProcessesSamplesFrom(const NodeValueDatabase &value) const
NodeInput *PanNode::ProcessesSamplesFrom(const NodeValueDatabase &) const
{
return samples_input_;
}
+1 -1
View File
@@ -34,7 +34,7 @@ public:
virtual QString Name() const override;
virtual QString id() const override;
virtual QString Category() const override;
virtual QList<CategoryID> Category() const override;
virtual QString Description() const override;
virtual Capabilities GetCapabilities(const NodeValueDatabase&) const override;
+2 -2
View File
@@ -48,9 +48,9 @@ QString VolumeNode::id() const
return QStringLiteral("org.olivevideoeditor.Olive.volume");
}
QString VolumeNode::Category() const
QList<Node::CategoryID> VolumeNode::Category() const
{
return tr("Audio");
return {kCategoryFilter};
}
QString VolumeNode::Description() const
+1 -1
View File
@@ -34,7 +34,7 @@ public:
virtual QString Name() const override;
virtual QString id() const override;
virtual QString Category() const override;
virtual QList<CategoryID> Category() const override;
virtual QString Description() const override;
virtual Capabilities GetCapabilities(const NodeValueDatabase&) const override;
+2 -2
View File
@@ -63,9 +63,9 @@ Block::Block() :
set_length_and_media_out(1);
}
QString Block::Category() const
QList<Node::CategoryID> Block::Category() const
{
return tr("Block");
return {kCategoryTimeline};
}
const rational &Block::in() const
+1 -1
View File
@@ -49,7 +49,7 @@ public:
virtual Type type() const = 0;
virtual QString Category() const override;
virtual QList<CategoryID> Category() const override;
const rational& in() const;
const rational& out() const;
@@ -50,7 +50,7 @@ QString ExternalTransition::id() const
return meta_.id();
}
QString ExternalTransition::Category() const
QList<Node::CategoryID> ExternalTransition::Category() const
{
return meta_.Category();
}
@@ -37,7 +37,7 @@ public:
virtual QString Name() const override;
virtual QString ShortName() const override;
virtual QString id() const override;
virtual QString Category() const override;
virtual QList<CategoryID> Category() const override;
virtual QString Description() const override;
virtual void Retranslate() override;
+1 -1
View File
@@ -52,7 +52,7 @@ QString ExternalNode::id() const
return meta_.id();
}
QString ExternalNode::Category() const
QList<Node::CategoryID> ExternalNode::Category() const
{
return meta_.Category();
}
+1 -1
View File
@@ -41,7 +41,7 @@ public:
virtual QString Name() const override;
virtual QString ShortName() const override;
virtual QString id() const override;
virtual QString Category() const override;
virtual QList<CategoryID> Category() const override;
virtual QString Description() const override;
virtual void Retranslate() override;
+15 -24
View File
@@ -73,34 +73,25 @@ Menu *NodeFactory::CreateMenu(QWidget* parent)
// Make sure nodes are up-to-date with the current translation
n->Retranslate();
QStringList path = n->Category().split('/');
Menu* destination = nullptr;
Menu* destination = menu;
QString category_name = Node::GetCategoryName(n->Category().isEmpty()
? Node::kCategoryUnknown
: n->Category().first());
// Find destination menu based on category hierarchy
foreach (const QString& dir_name, path) {
// Ignore an empty directory
if (dir_name.isEmpty()) {
continue;
// See if a menu with this category name already exists
QList<QAction*> menu_actions = menu->actions();
foreach (QAction* action, menu_actions) {
if (action->menu() && action->menu()->title() == category_name) {
destination = static_cast<Menu*>(action->menu());
break;
}
}
// See if a menu with this dir_name already exists
bool found_cat = false;
QList<QAction*> menu_actions = destination->actions();
foreach (QAction* action, menu_actions) {
if (action->menu() && action->menu()->title() == dir_name) {
destination = static_cast<Menu*>(action->menu());
found_cat = true;
break;
}
}
// Create menu here if it doesn't exist
if (!found_cat) {
Menu* new_category = new Menu(dir_name, destination);
destination->InsertAlphabetically(new_category);
destination = new_category;
}
// Create menu here if it doesn't exist
if (!destination) {
destination = new Menu(category_name, menu);
menu->InsertAlphabetically(destination);
}
// Add entry to menu
+2 -2
View File
@@ -69,9 +69,9 @@ QString MatrixGenerator::id() const
return QStringLiteral("org.olivevideoeditor.Olive.transform");
}
QString MatrixGenerator::Category() const
QList<Node::CategoryID> MatrixGenerator::Category() const
{
return tr("Generator");
return {kCategoryGenerator, kCategoryMath};
}
QString MatrixGenerator::Description() const
+1 -1
View File
@@ -36,7 +36,7 @@ public:
virtual QString Name() const override;
virtual QString ShortName() const override;
virtual QString id() const override;
virtual QString Category() const override;
virtual QList<CategoryID> Category() const override;
virtual QString Description() const override;
virtual void Retranslate() override;
+2 -2
View File
@@ -35,9 +35,9 @@ MediaInput::MediaInput() :
AddInput(footage_input_);
}
QString MediaInput::Category() const
QList<Node::CategoryID> MediaInput::Category() const
{
return tr("Input");
return {kCategoryInput};
}
StreamPtr MediaInput::footage()
+1 -1
View File
@@ -35,7 +35,7 @@ class MediaInput : public Node
public:
MediaInput();
virtual QString Category() const override;
virtual QList<CategoryID> Category() const override;
StreamPtr footage();
void SetFootage(StreamPtr f);
+2 -2
View File
@@ -41,9 +41,9 @@ QString TimeInput::id() const
return QStringLiteral("org.olivevideoeditor.Olive.time");
}
QString TimeInput::Category() const
QList<Node::CategoryID> TimeInput::Category() const
{
return tr("Input");
return {kCategoryInput};
}
QString TimeInput::Description() const
+1 -1
View File
@@ -35,7 +35,7 @@ public:
virtual QString Name() const override;
virtual QString id() const override;
virtual QString Category() const override;
virtual QList<CategoryID> Category() const override;
virtual QString Description() const override;
virtual NodeValueTable Value(NodeValueDatabase& value) const override;
+2 -2
View File
@@ -61,9 +61,9 @@ QString MathNode::id() const
return QStringLiteral("org.olivevideoeditor.Olive.math");
}
QString MathNode::Category() const
QList<Node::CategoryID> MathNode::Category() const
{
return tr("Math");
return {kCategoryMath};
}
QString MathNode::Description() const
+1 -1
View File
@@ -34,7 +34,7 @@ public:
virtual QString Name() const override;
virtual QString id() const override;
virtual QString Category() const override;
virtual QList<CategoryID> Category() const override;
virtual QString Description() const override;
virtual void Retranslate() override;
+2 -2
View File
@@ -48,9 +48,9 @@ QString TrigonometryNode::id() const
return QStringLiteral("org.olivevideoeditor.Olive.trigonometry");
}
QString TrigonometryNode::Category() const
QList<Node::CategoryID> TrigonometryNode::Category() const
{
return tr("Math");
return {kCategoryMath};
}
QString TrigonometryNode::Description() const
+1 -1
View File
@@ -34,7 +34,7 @@ public:
virtual QString Name() const override;
virtual QString id() const override;
virtual QString Category() const override;
virtual QList<CategoryID> Category() const override;
virtual QString Description() const override;
virtual void Retranslate() override;
+15 -3
View File
@@ -71,9 +71,9 @@ const QString &NodeMetaReader::id() const
return id_;
}
QString NodeMetaReader::Category() const
QList<Node::CategoryID> NodeMetaReader::Category() const
{
return GetStringForCurrentLanguage(&categories_);
return categories_;
}
QString NodeMetaReader::Description() const
@@ -187,7 +187,19 @@ void NodeMetaReader::XMLReadEffect(QXmlStreamReader* reader)
XMLReadLanguageString(reader, &short_names_);
} else if (reader->name() == QStringLiteral("category")) {
// Pick up category
XMLReadLanguageString(reader, &categories_);
QStringList category_ids = reader->readElementText().split(':');
foreach (const QString& id, category_ids) {
bool ok;
int try_parse = id.toInt(&ok);
if (!ok || try_parse < 0 || try_parse >= Node::kCategoryCount) {
continue;
}
categories_.append(static_cast<Node::CategoryID>(try_parse));
}
} else if (reader->name() == QStringLiteral("description")) {
// Pick up description
XMLReadLanguageString(reader, &descriptions_);
+3 -2
View File
@@ -26,6 +26,7 @@
#include <QXmlStreamReader>
#include "input.h"
#include "node/node.h"
OLIVE_NAMESPACE_ENTER
@@ -37,7 +38,7 @@ public:
QString Name() const;
QString ShortName() const;
const QString& id() const;
QString Category() const;
QList<Node::CategoryID> Category() const;
QString Description() const;
const QString& filename() const;
@@ -70,7 +71,7 @@ private:
LanguageMap names_;
LanguageMap short_names_;
LanguageMap descriptions_;
LanguageMap categories_;
QList<Node::CategoryID> categories_;
QMap<QString, LanguageMap > param_names_;
QMap<QString, QList<LanguageMap> > combo_names_;
QMap<QString, QList<LanguageMap> > combo_descriptions_;
+29 -6
View File
@@ -127,12 +127,6 @@ QString Node::ShortName() const
return Name();
}
QString Node::Category() const
{
// Return an empty category for any nodes that don't use one
return QString();
}
QString Node::Description() const
{
// Return an empty string by default
@@ -560,6 +554,35 @@ void Node::DisconnectAll()
}
}
QString Node::GetCategoryName(const CategoryID &c)
{
switch (c) {
case kCategoryInput:
return tr("Input");
case kCategoryOutput:
return tr("Output");
case kCategoryGeneral:
return tr("General");
case kCategoryMath:
return tr("Math");
case kCategoryColor:
return tr("Color");
case kCategoryFilter:
return tr("Filter");
case kCategoryTimeline:
return tr("Timeline");
case kCategoryGenerator:
return tr("Generator");
case kCategoryChannels:
return tr("Channel");
case kCategoryUnknown:
case kCategoryCount:
break;
}
return tr("Uncategorized");
}
QList<TimeRange> Node::TransformTimeTo(const TimeRange &time, Node *target, NodeParam::Type direction)
{
QList<TimeRange> paths_found;
+22 -1
View File
@@ -61,6 +61,22 @@ public:
kSampleProcessor = 0x2
};
enum CategoryID {
kCategoryUnknown = -1,
kCategoryInput,
kCategoryOutput,
kCategoryGenerator,
kCategoryMath,
kCategoryFilter,
kCategoryColor,
kCategoryGeneral,
kCategoryTimeline,
kCategoryChannels,
kCategoryCount
};
Node();
virtual ~Node() override;
@@ -115,7 +131,7 @@ public:
* interpreted as an empty string category. This value should be run through a translator as its largely user
* oriented.
*/
virtual QString Category() const;
virtual QList<CategoryID> Category() const = 0;
/**
* @brief Return a description of this node's purpose (optional for subclassing, but recommended)
@@ -241,6 +257,11 @@ public:
*/
void DisconnectAll();
/**
* @brief Get the human-readable name for any category
*/
static QString GetCategoryName(const CategoryID &c);
/**
* @brief Transforms time from this node through the connections it takes to get to the specified node
*/
+2 -2
View File
@@ -80,9 +80,9 @@ QString TrackOutput::id() const
return QStringLiteral("org.olivevideoeditor.Olive.track");
}
QString TrackOutput::Category() const
QList<Node::CategoryID> TrackOutput::Category() const
{
return tr("Output");
return {kCategoryTimeline};
}
QString TrackOutput::Description() const
+1 -1
View File
@@ -44,7 +44,7 @@ public:
virtual QString Name() const override;
virtual QString id() const override;
virtual QString Category() const override;
virtual QList<CategoryID> Category() const override;
virtual QString Description() const override;
QString GetTrackName();
+2 -2
View File
@@ -72,9 +72,9 @@ QString ViewerOutput::id() const
return QStringLiteral("org.olivevideoeditor.Olive.vieweroutput");
}
QString ViewerOutput::Category() const
QList<Node::CategoryID> ViewerOutput::Category() const
{
return tr("Output");
return {kCategoryOutput};
}
QString ViewerOutput::Description() const
+1 -1
View File
@@ -49,7 +49,7 @@ public:
virtual QString Name() const override;
virtual QString id() const override;
virtual QString Category() const override;
virtual QList<CategoryID> Category() const override;
virtual QString Description() const override;
NodeInput* texture_input() const;
+13
View File
@@ -78,6 +78,14 @@ Color::Color(const char *data, const PixelFormat::Format &format)
}
}
Color::Color(const QColor &c)
{
set_red(c.redF());
set_green(c.greenF());
set_blue(c.blueF());
set_alpha(c.alphaF());
}
void Color::toHsv(float *hue, float *sat, float *val) const
{
float fCMax = qMax(qMax(red(), green()), blue());
@@ -207,6 +215,11 @@ QColor Color::toQColor() const
return c;
}
float Color::GetRoughLuminance() const
{
return (2*red()+blue()+3*green())/6.0f;
}
const Color &Color::operator+=(const Color &rhs)
{
for (int i=0;i<kRGBAChannels;i++) {
+6
View File
@@ -52,6 +52,8 @@ public:
Color(const char *data, const PixelFormat::Format &format);
Color(const QColor& c);
/**
* @brief Creates a Color struct from hue/saturation/value
*
@@ -86,6 +88,10 @@ public:
QColor toQColor() const;
// Suuuuper rough luminance value mostly used for UI (determining whether to overlay with black
// or white text)
float GetRoughLuminance() const;
// Assignment math operators
const Color& operator+=(const Color& rhs);
const Color& operator-=(const Color& rhs);
+1 -1
View File
@@ -4,7 +4,7 @@
<name lang="en_US">Alpha Over</name>
<!-- Effect Category -->
<category lang="en_US">Blend</category>
<category>3</category>
<!-- Effect Description -->
<description lang="en_US">
+1 -1
View File
@@ -4,7 +4,7 @@
<name lang="en_US">Blur</name>
<!-- Effect Category -->
<category lang="en_US">Blur</category>
<category>4</category>
<!-- Effect Description -->
<description lang="en_US">
+1 -1
View File
@@ -4,7 +4,7 @@
<name lang="en_US">Cross Dissolve</name>
<!-- Effect Category -->
<category lang="en_US">Transition</category>
<category></category>
<!-- Effect Description -->
<description lang="en_US">
+1 -1
View File
@@ -4,7 +4,7 @@
<name lang="en_US">Dip to Black</name>
<!-- Effect Category -->
<category lang="en_US">Transition</category>
<category></category>
<!-- Effect Description -->
<description lang="en_US">
+1 -3
View File
@@ -77,9 +77,7 @@ void ColorSwatchWidget::SelectedColorChangedEvent(const Color &, bool)
Qt::GlobalColor ColorSwatchWidget::GetUISelectorColor() const
{
float rough_color_luma = (GetSelectedColor().red()+GetSelectedColor().red()+GetSelectedColor().blue()+GetSelectedColor().green()+GetSelectedColor().green()+GetSelectedColor().green())/6;
if (rough_color_luma > 0.66) {
if (GetSelectedColor().GetRoughLuminance() > 0.66) {
return Qt::black;
} else {
return Qt::white;
+12 -2
View File
@@ -28,6 +28,7 @@
#include "common/flipmodifiers.h"
#include "common/qtutils.h"
#include "config/config.h"
#include "core.h"
#include "nodeview.h"
#include "nodeviewscene.h"
@@ -260,8 +261,11 @@ void NodeViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
// Draw the titlebar
if (!hide_titlebar_ && node_) {
Color node_color = Config::Current()[QStringLiteral("NodeCatColor%1")
.arg(node_->Category().first())].value<Color>();
painter->setPen(Qt::black);
painter->setBrush(css_proxy_.TitleBarColor());
painter->setBrush(node_color.toQColor());
painter->drawRect(title_bar_rect_);
@@ -293,6 +297,12 @@ void NodeViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
}
}
if (node_color.GetRoughLuminance() > 0.66) {
painter->setPen(Qt::black);
} else {
painter->setPen(Qt::white);
}
// Draw the text in a rect (the rect is sized around text already in the constructor)
painter->drawText(title_bar_rect_,
Qt::AlignCenter,
@@ -307,7 +317,7 @@ void NodeViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
if (option->state & QStyle::State_Selected) {
border_pen.setColor(app_pal.color(QPalette::Highlight));
} else {
border_pen.setColor(css_proxy_.BorderColor());
border_pen.setColor(Qt::black);
}
painter->setPen(border_pen);
-7
View File
@@ -130,13 +130,6 @@ private:
*/
QList<NodeInput*> node_inputs_;
/**
* @brief A QWidget that can receive CSS properties that NodeViewItem can use
*
* \see NodeViewItemWidget
*/
NodeViewItemWidget css_proxy_;
/**
* @brief Rectangle of the Node's title bar (equal to rect() when collapsed)
*/