Skip to content

Commit

Permalink
Enable mixer color-coding (#5589)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
ryuukumar and PhysSong committed Aug 11, 2020
1 parent f2887bd commit 1bb8d12
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 7 deletions.
22 changes: 20 additions & 2 deletions include/ColorChooser.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
5 changes: 5 additions & 0 deletions include/FxLine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -101,6 +103,9 @@ class FxLine : public QWidget

public slots:
void renameChannel();
void resetColor();
void changeColor();
void randomColor();

private slots:
void renameFinished();
Expand Down
7 changes: 7 additions & 0 deletions include/FxMixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

#include <atomic>

#include <QColor>

class FxRoute;
typedef QVector<FxRoute *> FxRouteVector;

Expand Down Expand Up @@ -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();
Expand Down
7 changes: 7 additions & 0 deletions src/core/FxMixer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() );
Expand Down Expand Up @@ -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 )
Expand Down Expand Up @@ -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() ) );
Expand Down
1 change: 1 addition & 0 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
93 changes: 93 additions & 0 deletions src/gui/dialogs/ColorChooser.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
58 changes: 53 additions & 5 deletions src/gui/widgets/FxLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

#include "FxLine.h"

#include <cstdlib>

#include <QGraphicsProxyWidget>

#include "CaptionMenu.h"
Expand Down Expand Up @@ -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() ) );

}


Expand All @@ -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 )
{
Expand All @@ -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() );
Expand Down Expand Up @@ -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() ) );
Expand All @@ -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;
}
Expand Down Expand Up @@ -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();
}

0 comments on commit 1bb8d12

Please sign in to comment.