mirror of
https://github.com/LMMS/lmms.git
synced 2026-05-14 17:55:44 -04:00
Enable mixer color-coding (#5589)
* Enable mixer color-coding * Cleanup * Fix warnings * Improvements * Improvements * Use ColorChooser instead of QColorDialog * Fix default palette being out of range * Remove a redundant function * Rename and make stuff efficient * Comment on the code * Make things more efficient * Fix breaking builds * Improvements * Improvements pt. 2 * Improvements pt. 3 * Improvements pt. 4 * Improvements pt. 5 * Apply suggestions from code review Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com> Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>
This commit is contained in:
@@ -21,21 +21,39 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QColorDialog>
|
||||
#include <QApplication>
|
||||
#include <QColor>
|
||||
#include <QColorDialog>
|
||||
#include <QKeyEvent>
|
||||
#include <QVector>
|
||||
|
||||
class ColorChooser: public QColorDialog
|
||||
{
|
||||
public:
|
||||
ColorChooser(const QColor &initial, QWidget *parent): QColorDialog(initial, parent) {};
|
||||
ColorChooser(QWidget *parent): QColorDialog(parent) {};
|
||||
//! For getting a color without having to initialise a color dialog
|
||||
ColorChooser() {};
|
||||
enum class Palette {Default, Track, Mixer};
|
||||
//! Set global palette via array, checking bounds
|
||||
void setPalette (QVector<QColor>);
|
||||
//! Set global paletter via enum
|
||||
void setPalette (Palette);
|
||||
//! Set palette via enum, return self pointer for chaining
|
||||
ColorChooser* withPalette (Palette);
|
||||
//! Return a certain palette
|
||||
static QVector<QColor> getPalette (Palette);
|
||||
|
||||
protected:
|
||||
// Forward key events to the parent to prevent stuck notes when the dialog gets focus
|
||||
//! Forward key events to the parent to prevent stuck notes when the dialog gets focus
|
||||
void keyReleaseEvent(QKeyEvent *event) override
|
||||
{
|
||||
QKeyEvent ke(*event);
|
||||
QApplication::sendEvent(parentWidget(), &ke);
|
||||
}
|
||||
private:
|
||||
//! Copy the current QColorDialog palette into an array
|
||||
static QVector<QColor> defaultPalette();
|
||||
//! Generate a nice palette, with adjustable value
|
||||
static QVector<QColor> nicePalette (int);
|
||||
};
|
||||
|
||||
@@ -26,10 +26,12 @@
|
||||
#ifndef FX_LINE_H
|
||||
#define FX_LINE_H
|
||||
|
||||
#include <QColorDialog>
|
||||
#include <QGraphicsView>
|
||||
#include <QLineEdit>
|
||||
#include <QWidget>
|
||||
|
||||
#include "ColorChooser.h"
|
||||
#include "Knob.h"
|
||||
#include "LcdWidget.h"
|
||||
#include "SendButtonIndicator.h"
|
||||
@@ -101,6 +103,9 @@ private:
|
||||
|
||||
public slots:
|
||||
void renameChannel();
|
||||
void resetColor();
|
||||
void changeColor();
|
||||
void randomColor();
|
||||
|
||||
private slots:
|
||||
void renameFinished();
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include <QColor>
|
||||
|
||||
class FxRoute;
|
||||
typedef QVector<FxRoute *> FxRouteVector;
|
||||
|
||||
@@ -70,6 +72,11 @@ class FxChannel : public ThreadableJob
|
||||
bool requiresProcessing() const override { return true; }
|
||||
void unmuteForSolo();
|
||||
|
||||
|
||||
// TODO C++17 and above: use std::optional insteads
|
||||
QColor m_color;
|
||||
bool m_hasColor;
|
||||
|
||||
|
||||
std::atomic_int m_dependenciesMet;
|
||||
void incrementDeps();
|
||||
|
||||
@@ -73,6 +73,7 @@ FxChannel::FxChannel( int idx, Model * _parent ) :
|
||||
m_lock(),
|
||||
m_channelIndex( idx ),
|
||||
m_queued( false ),
|
||||
m_hasColor( false ),
|
||||
m_dependenciesMet(0)
|
||||
{
|
||||
BufferManager::clear( m_buffer, Engine::mixer()->framesPerPeriod() );
|
||||
@@ -741,6 +742,7 @@ void FxMixer::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
ch->m_soloModel.saveSettings( _doc, fxch, "soloed" );
|
||||
fxch.setAttribute( "num", i );
|
||||
fxch.setAttribute( "name", ch->m_name );
|
||||
if( ch->m_hasColor ) fxch.setAttribute( "color", ch->m_color.name() );
|
||||
|
||||
// add the channel sends
|
||||
for( int si = 0; si < ch->m_sends.size(); ++si )
|
||||
@@ -786,6 +788,11 @@ void FxMixer::loadSettings( const QDomElement & _this )
|
||||
m_fxChannels[num]->m_muteModel.loadSettings( fxch, "muted" );
|
||||
m_fxChannels[num]->m_soloModel.loadSettings( fxch, "soloed" );
|
||||
m_fxChannels[num]->m_name = fxch.attribute( "name" );
|
||||
if( fxch.hasAttribute( "color" ) )
|
||||
{
|
||||
m_fxChannels[num]->m_hasColor = true;
|
||||
m_fxChannels[num]->m_color.setNamedColor( fxch.attribute( "color" ) );
|
||||
}
|
||||
|
||||
m_fxChannels[num]->m_fxChain.restoreState( fxch.firstChildElement(
|
||||
m_fxChannels[num]->m_fxChain.nodeName() ) );
|
||||
|
||||
@@ -37,6 +37,7 @@ SET(LMMS_SRCS
|
||||
|
||||
gui/dialogs/FileDialog.cpp
|
||||
gui/dialogs/VersionedSaveDialog.cpp
|
||||
gui/dialogs/ColorChooser.cpp
|
||||
|
||||
gui/editors/AutomationEditor.cpp
|
||||
gui/editors/BBEditor.cpp
|
||||
|
||||
93
src/gui/dialogs/ColorChooser.cpp
Normal file
93
src/gui/dialogs/ColorChooser.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/* ColorChooser.cpp - definition of ColorChooser class.
|
||||
*
|
||||
* Copyright (c) 2020 russiankumar <adityakumar4644/at/gmail/dot/com>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ColorChooser.h>
|
||||
|
||||
|
||||
|
||||
|
||||
//! Set global palette via array, checking bounds
|
||||
void ColorChooser::setPalette (QVector<QColor> colors)
|
||||
{
|
||||
const int max = qMin (colors.size(), 48);
|
||||
for (int i = 0; i < max; i++)
|
||||
{
|
||||
ColorChooser::setStandardColor (i, colors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! Set global paletter via enum
|
||||
void ColorChooser::setPalette (Palette palette)
|
||||
{
|
||||
setPalette (getPalette (palette));
|
||||
}
|
||||
|
||||
|
||||
//! Set palette via enum, return self pointer for chaining
|
||||
ColorChooser* ColorChooser::withPalette (Palette palette)
|
||||
{
|
||||
setPalette (palette);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
//! Return a certain palette
|
||||
QVector<QColor> ColorChooser::getPalette (Palette palette)
|
||||
{
|
||||
switch (palette)
|
||||
{
|
||||
case Palette::Mixer: return nicePalette(140);
|
||||
case Palette::Track: return nicePalette(150);
|
||||
default: return defaultPalette();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//! Copy the current QColorDialog palette into an array
|
||||
QVector<QColor> ColorChooser::defaultPalette()
|
||||
{
|
||||
QVector <QColor> result (48);
|
||||
for (int i = 0; i < 48; i++)
|
||||
{
|
||||
result[i] = (QColorDialog::standardColor(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//! Generate a nice palette, with adjustable value
|
||||
QVector<QColor> ColorChooser::nicePalette (int base)
|
||||
{
|
||||
QVector <QColor> result (48);
|
||||
for (int x = 0; x < 8; x++)
|
||||
{
|
||||
for (int y = 0; y < 6; y++)
|
||||
{
|
||||
result[6 * x + y].setHsl (qMax(0, 44 * x - 1), 150 - 20 * y, base - 10 * y);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "FxLine.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <QGraphicsProxyWidget>
|
||||
|
||||
#include "CaptionMenu.h"
|
||||
@@ -120,6 +122,8 @@ FxLine::FxLine( QWidget * _parent, FxMixerView * _mv, int _channelIndex ) :
|
||||
proxyWidget->setPos( 8, 145 );
|
||||
|
||||
connect( m_renameLineEdit, SIGNAL( editingFinished() ), this, SLOT( renameFinished() ) );
|
||||
connect( &Engine::fxMixer()->effectChannel( m_channelIndex )->m_muteModel, SIGNAL( dataChanged() ), this, SLOT( update() ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -144,10 +148,11 @@ void FxLine::setChannelIndex( int index )
|
||||
|
||||
|
||||
|
||||
|
||||
void FxLine::drawFxLine( QPainter* p, const FxLine *fxLine, bool isActive, bool sendToThis, bool receiveFromThis )
|
||||
{
|
||||
QString name = Engine::fxMixer()->effectChannel( m_channelIndex )->m_name;
|
||||
auto channel = Engine::fxMixer()->effectChannel( m_channelIndex );
|
||||
bool muted = channel->m_muteModel.value();
|
||||
QString name = channel->m_name;
|
||||
QString elidedName = elideName( name );
|
||||
if( !m_inRename && m_renameLineEdit->text() != elidedName )
|
||||
{
|
||||
@@ -156,8 +161,16 @@ void FxLine::drawFxLine( QPainter* p, const FxLine *fxLine, bool isActive, bool
|
||||
|
||||
int width = fxLine->rect().width();
|
||||
int height = fxLine->rect().height();
|
||||
|
||||
p->fillRect( fxLine->rect(), isActive ? fxLine->backgroundActive() : p->background() );
|
||||
|
||||
if( channel->m_hasColor && !muted )
|
||||
{
|
||||
p->fillRect( fxLine->rect(), channel->m_color.darker( isActive ? 120 : 150 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
p->fillRect( fxLine->rect(),
|
||||
isActive ? fxLine->backgroundActive().color() : p->background().color() );
|
||||
}
|
||||
|
||||
// inner border
|
||||
p->setPen( isActive ? fxLine->strokeInnerActive() : fxLine->strokeInnerInactive() );
|
||||
@@ -224,7 +237,7 @@ void FxLine::mouseDoubleClickEvent( QMouseEvent * )
|
||||
void FxLine::contextMenuEvent( QContextMenuEvent * )
|
||||
{
|
||||
QPointer<CaptionMenu> contextMenu = new CaptionMenu( Engine::fxMixer()->effectChannel( m_channelIndex )->m_name, this );
|
||||
if( m_channelIndex != 0 ) // no move-options in master
|
||||
if( m_channelIndex != 0 ) // no move-options in master
|
||||
{
|
||||
contextMenu->addAction( tr( "Move &left" ), this, SLOT( moveChannelLeft() ) );
|
||||
contextMenu->addAction( tr( "Move &right" ), this, SLOT( moveChannelRight() ) );
|
||||
@@ -238,6 +251,10 @@ void FxLine::contextMenuEvent( QContextMenuEvent * )
|
||||
contextMenu->addSeparator();
|
||||
}
|
||||
contextMenu->addAction( embed::getIconPixmap( "cancel" ), tr( "Remove &unused channels" ), this, SLOT( removeUnusedChannels() ) );
|
||||
contextMenu->addSeparator();
|
||||
contextMenu->addAction( embed::getIconPixmap( "colorize" ), tr( "Set channel color" ), this, SLOT( changeColor() ) );
|
||||
contextMenu->addAction( embed::getIconPixmap( "colorize" ), tr( "Remove channel color" ), this, SLOT( resetColor() ) );
|
||||
contextMenu->addAction( embed::getIconPixmap( "colorize" ), tr( "Pick random channel color" ), this, SLOT( randomColor() ) );
|
||||
contextMenu->exec( QCursor::pos() );
|
||||
delete contextMenu;
|
||||
}
|
||||
@@ -395,3 +412,34 @@ void FxLine::setStrokeInnerInactive( const QColor & c )
|
||||
{
|
||||
m_strokeInnerInactive = c;
|
||||
}
|
||||
|
||||
|
||||
// Ask user for a color, and set it as the mixer line color
|
||||
void FxLine::changeColor()
|
||||
{
|
||||
auto channel = Engine::fxMixer()->effectChannel( m_channelIndex );
|
||||
auto new_color = ColorChooser( this ).withPalette( ColorChooser::Palette::Mixer )->getColor( channel->m_color );
|
||||
if( ! new_color.isValid() )
|
||||
{ return; }
|
||||
channel->m_color = new_color;
|
||||
channel->m_hasColor = true;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
// Disable the usage of color on this mixer line
|
||||
void FxLine::resetColor()
|
||||
{
|
||||
Engine::fxMixer()->effectChannel( m_channelIndex )->m_hasColor = false;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
// Pick a random color from the mixer palette and set it as our color
|
||||
void FxLine::randomColor()
|
||||
{
|
||||
auto channel = Engine::fxMixer()->effectChannel( m_channelIndex );
|
||||
channel->m_color = ColorChooser::getPalette( ColorChooser::Palette::Mixer )[ rand() % 48 ];
|
||||
channel->m_hasColor = true;
|
||||
update();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user