Use Qt layouts for mixer channels (#6591)
Use Qt layouts for the mixer channels. These changes will enable several other improvements, like for example making the mixer and faders resizable, adding peak indicators, etc. This is a squash commit which consists of the following individual commits: * Remove extra transparency in send/receive arrows The extra transparency was conflicting with the positioning of the arrows in the layout * Begin reimplementing MixerChannelView MixerChannelView is now a combination of the MixerLine with the previous MixerChannelView * Adjust SendButtonIndicator to use MixerChannelView * Remove MixerLine - Move MixerChannelView into src/gui * Remove MixerView::MixerChannelView * Remove header of MixerLine * Change MixerView.h to use MixerChannelView Change MixerView.h to use MixerChannelView rather than MixerLine Also do some cleanup, such as removing an unused forward declaration of QButtonGroup * Create EffectRackView + Set height of sizeHint() using MIXER_CHANNEL_HEIGHT (287) * Remove include of MixerLine - Include MixerChannelView * Phase 1: Adjust MixerView to use new MixerChannelView * Move children wigets into header file * Phase 2: Adjust MixerView to use new MixerChannelView * Phase 3: Adjust MixerView to use new MixerChannelView * Phase 4: Adjust MixerView to use new MixerChannelView * Phase 5: Adjust MixerView to use new MixerChannelView * Phase 5: Adjust MixerView to use new MixerChannelView * Remove places where MixerChannelView is being deleted Before, MixerChannelView was not inherited by QWidget, meaning it could not have a parent and had to be deleted when necessary. Since the MixerView owns the new MixerChannelView, this is no longer necessary. * Replace MixerLine with MixerChannelView - Include MixerChannelView in MixerView * Replace setCurrentMixerLine calls with setCurrentMixerChannel around codebase * Add event handlers in MixerChannelView * Implement MixerChannelView::eventFilter * Update theme styles to use MixerChannelView * Add QColor properties from style - Set the Qt::WA_StyledBackground attribute on * Add effect rack to rack layout when adding channel * Set size for MixerChannelView - Change nullptr to this for certain widgets - Some custom widgets may expect there to be a parent - Add spacing in channel layout - Increase size of mixer channel * Retain size when widgets are hidden * Implement paintEvent - Rename states in SendReceiveState * Implement send/receive arrow toggling - Make maxTextHeight constexpr in elideName - Remove background changing on mouse press (is now handled in paintEvent) * Implement renaming mixer channels * Implement color functions * Implement channel moving/removing functions * Do some cleanup Not sure if that connection with the mute model was needed, but removing it did not seem to introduce any issues. * Include cassert * Replace references to MixerLine with MixerChannelView * Reduce height + Make m_renameLineEdit transparent + Retain size when LCD is hidden + Remove stretch after renameLineEdit in layout * Remove trailing whitespace * Make m_renameLineEdit read only + Transpose m_renameLineEditView rectangle (with 5px offset) * Set spacing in channel layout back to 0 * Remove sizeHint override and constant size * Use sizeHint for mixerChannelSize + Leave auto fill background to false in MixerChannelView + Only set width for EffectRackView * Set margins to 4 on all sides in MixerChannelView * Move solo and mute closer to each other Move the solo and mute buttons closer to each other in the mixer channels. Technically this is accomplished by putting them into their own layout with minimal margins and spacing. * Fixes for CodeFactor * Code review changes Mostly whitespace and formatting changes: remove tabs, remove spaces in parameter lists, remove underscores from parameter names. Some lines have been shortened by introducing intermediate variables, e.g. in `MixerChannelView`. `MixerView` has many changes but only related to whitespace. Spaces have been introduced for if and for statements. Whitespace at round braces has been removed everywhere in the implementation file even if a line was not touched by the intial changes. Remove duplicate forward declaration of `MixerChannelView`. * Adjust parameter order in MixerChannelView's constructor Make the parent `QWidget` the first parameter as it is a Qt convention. The default parameter had to be removed due to this. * Move styling of rename line edit into style sheets Move the style of the `QGraphicsView` for the rename line edit from the code into the style sheets of the default and classic theme. * More code review changes Fix spaces between types and references/pointers, e.g. use `const QBrush& c` instead of `const QBrush & c`. Remove underscores from parameter names. Remove spaces near parentheses. Replace tabs with spaces. Introduce intermediate variable to resolve "hanging" + operator. Replace the connection for the periodic fader updates with one that uses function pointers instead of `SIGNAL` and `SLOT`. --------- Co-authored-by: Michael Gregorius <michael.gregorius.git@arcor.de>
This commit is contained in:
@@ -27,7 +27,7 @@ SET(LMMS_SRCS
|
||||
gui/MicrotunerConfig.cpp
|
||||
gui/MidiCCRackView.cpp
|
||||
gui/MidiSetupWidget.cpp
|
||||
gui/MixerLine.cpp
|
||||
gui/MixerChannelView.cpp
|
||||
gui/MixerView.cpp
|
||||
gui/ModelView.cpp
|
||||
gui/PeakControllerDialog.cpp
|
||||
@@ -113,7 +113,7 @@ SET(LMMS_SRCS
|
||||
gui/widgets/LedCheckBox.cpp
|
||||
gui/widgets/LeftRightNav.cpp
|
||||
gui/widgets/MeterDialog.cpp
|
||||
gui/widgets/MixerLineLcdSpinBox.cpp
|
||||
gui/widgets/MixerChannelLcdSpinBox.cpp
|
||||
gui/widgets/NStateButton.cpp
|
||||
gui/widgets/Oscilloscope.cpp
|
||||
gui/widgets/PixmapButton.cpp
|
||||
|
||||
447
src/gui/MixerChannelView.cpp
Normal file
447
src/gui/MixerChannelView.cpp
Normal file
@@ -0,0 +1,447 @@
|
||||
/*
|
||||
* MixerChannelView.h - the mixer channel view
|
||||
*
|
||||
* Copyright (c) 2022 saker <sakertooth@gmail.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 "CaptionMenu.h"
|
||||
#include "ColorChooser.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "Mixer.h"
|
||||
#include "MixerChannelView.h"
|
||||
#include "MixerView.h"
|
||||
#include "Song.h"
|
||||
|
||||
#include "gui_templates.h"
|
||||
#include "lmms_math.h"
|
||||
|
||||
#include <QGraphicsProxyWidget>
|
||||
#include <QGraphicsScene>
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
#include <QFont>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace lmms::gui
|
||||
{
|
||||
MixerChannelView::MixerChannelView(QWidget* parent, MixerView* mixerView, int channelIndex) :
|
||||
QWidget(parent),
|
||||
m_mixerView(mixerView),
|
||||
m_channelIndex(channelIndex)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
|
||||
|
||||
auto retainSizeWhenHidden = [](QWidget* widget)
|
||||
{
|
||||
auto sizePolicy = widget->sizePolicy();
|
||||
sizePolicy.setRetainSizeWhenHidden(true);
|
||||
widget->setSizePolicy(sizePolicy);
|
||||
};
|
||||
|
||||
m_sendButton = new SendButtonIndicator{this, this, mixerView};
|
||||
retainSizeWhenHidden(m_sendButton);
|
||||
|
||||
m_sendKnob = new Knob{KnobType::Bright26, this, tr("Channel send amount")};
|
||||
retainSizeWhenHidden(m_sendKnob);
|
||||
|
||||
m_channelNumberLcd = new LcdWidget{2, this};
|
||||
m_channelNumberLcd->setValue(channelIndex);
|
||||
retainSizeWhenHidden(m_channelNumberLcd);
|
||||
|
||||
const auto mixerChannel = Engine::mixer()->mixerChannel(channelIndex);
|
||||
const auto mixerName = mixerChannel->m_name;
|
||||
setToolTip(mixerName);
|
||||
|
||||
m_renameLineEdit = new QLineEdit{mixerName, nullptr};
|
||||
m_renameLineEdit->setFixedWidth(65);
|
||||
m_renameLineEdit->setFont(pointSizeF(font(), 7.5f));
|
||||
m_renameLineEdit->setReadOnly(true);
|
||||
m_renameLineEdit->installEventFilter(this);
|
||||
|
||||
auto renameLineEditScene = new QGraphicsScene{};
|
||||
m_renameLineEditView = new QGraphicsView{};
|
||||
m_renameLineEditView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_renameLineEditView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_renameLineEditView->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
m_renameLineEditView->setScene(renameLineEditScene);
|
||||
|
||||
auto renameLineEditProxy = renameLineEditScene->addWidget(m_renameLineEdit);
|
||||
renameLineEditProxy->setRotation(-90);
|
||||
m_renameLineEditView->setFixedSize(m_renameLineEdit->height() + 5, m_renameLineEdit->width() + 5);
|
||||
|
||||
m_sendArrow = new QLabel{};
|
||||
m_sendArrow->setPixmap(embed::getIconPixmap("send_bg_arrow"));
|
||||
retainSizeWhenHidden(m_sendArrow);
|
||||
m_sendArrow->setVisible(m_sendReceiveState == SendReceiveState::SendToThis);
|
||||
|
||||
m_receiveArrow = new QLabel{};
|
||||
m_receiveArrow->setPixmap(embed::getIconPixmap("receive_bg_arrow"));
|
||||
retainSizeWhenHidden(m_receiveArrow);
|
||||
m_receiveArrow->setVisible(m_sendReceiveState == SendReceiveState::ReceiveFromThis);
|
||||
|
||||
m_muteButton = new PixmapButton(this, tr("Mute"));
|
||||
m_muteButton->setModel(&mixerChannel->m_muteModel);
|
||||
m_muteButton->setActiveGraphic(embed::getIconPixmap("led_off"));
|
||||
m_muteButton->setInactiveGraphic(embed::getIconPixmap("led_green"));
|
||||
m_muteButton->setCheckable(true);
|
||||
m_muteButton->setToolTip(tr("Mute this channel"));
|
||||
|
||||
m_soloButton = new PixmapButton(this, tr("Solo"));
|
||||
m_soloButton->setModel(&mixerChannel->m_soloModel);
|
||||
m_soloButton->setActiveGraphic(embed::getIconPixmap("led_red"));
|
||||
m_soloButton->setInactiveGraphic(embed::getIconPixmap("led_off"));
|
||||
m_soloButton->setCheckable(true);
|
||||
m_soloButton->setToolTip(tr("Solo this channel"));
|
||||
connect(&mixerChannel->m_soloModel, &BoolModel::dataChanged, mixerView, &MixerView::toggledSolo, Qt::DirectConnection);
|
||||
|
||||
QVBoxLayout* soloMuteLayout = new QVBoxLayout();
|
||||
soloMuteLayout->setContentsMargins(0, 0, 0, 0);
|
||||
soloMuteLayout->setSpacing(0);
|
||||
soloMuteLayout->addWidget(m_soloButton, 0, Qt::AlignHCenter);
|
||||
soloMuteLayout->addWidget(m_muteButton, 0, Qt::AlignHCenter);
|
||||
|
||||
m_fader = new Fader{&mixerChannel->m_volumeModel, tr("Fader %1").arg(channelIndex), this};
|
||||
m_fader->setLevelsDisplayedInDBFS();
|
||||
m_fader->setMinPeak(dbfsToAmp(-42));
|
||||
m_fader->setMaxPeak(dbfsToAmp(9));
|
||||
|
||||
m_effectRackView = new EffectRackView{&mixerChannel->m_fxChain, mixerView->m_racksWidget};
|
||||
m_effectRackView->setFixedWidth(EffectRackView::DEFAULT_WIDTH);
|
||||
|
||||
auto mainLayout = new QVBoxLayout{this};
|
||||
mainLayout->setContentsMargins(4, 4, 4, 4);
|
||||
mainLayout->addWidget(m_receiveArrow, 0, Qt::AlignHCenter);
|
||||
mainLayout->addWidget(m_sendButton, 0, Qt::AlignHCenter);
|
||||
mainLayout->addWidget(m_sendKnob, 0, Qt::AlignHCenter);
|
||||
mainLayout->addWidget(m_sendArrow, 0, Qt::AlignHCenter);
|
||||
mainLayout->addWidget(m_channelNumberLcd, 0, Qt::AlignHCenter);
|
||||
mainLayout->addStretch();
|
||||
mainLayout->addWidget(m_renameLineEditView, 0, Qt::AlignHCenter);
|
||||
mainLayout->addLayout(soloMuteLayout, 0);
|
||||
mainLayout->addWidget(m_fader, 0, Qt::AlignHCenter);
|
||||
|
||||
connect(m_renameLineEdit, &QLineEdit::editingFinished, this, &MixerChannelView::renameFinished);
|
||||
}
|
||||
|
||||
void MixerChannelView::contextMenuEvent(QContextMenuEvent*)
|
||||
{
|
||||
auto contextMenu = new CaptionMenu(Engine::mixer()->mixerChannel(m_channelIndex)->m_name, this);
|
||||
|
||||
if (m_channelIndex != 0) // no move-options in master
|
||||
{
|
||||
contextMenu->addAction(tr("Move &left"), this, &MixerChannelView::moveChannelLeft);
|
||||
contextMenu->addAction(tr("Move &right"), this, &MixerChannelView::moveChannelRight);
|
||||
}
|
||||
|
||||
contextMenu->addAction(tr("Rename &channel"), this, &MixerChannelView::renameChannel);
|
||||
contextMenu->addSeparator();
|
||||
|
||||
if (m_channelIndex != 0) // no remove-option in master
|
||||
{
|
||||
contextMenu->addAction(embed::getIconPixmap("cancel"), tr("R&emove channel"), this, &MixerChannelView::removeChannel);
|
||||
contextMenu->addSeparator();
|
||||
}
|
||||
|
||||
contextMenu->addAction(embed::getIconPixmap("cancel"), tr("Remove &unused channels"), this, &MixerChannelView::removeUnusedChannels);
|
||||
contextMenu->addSeparator();
|
||||
|
||||
auto colorMenu = QMenu{tr("Color"), this};
|
||||
colorMenu.setIcon(embed::getIconPixmap("colorize"));
|
||||
colorMenu.addAction(tr("Change"), this, &MixerChannelView::selectColor);
|
||||
colorMenu.addAction(tr("Reset"), this, &MixerChannelView::resetColor);
|
||||
colorMenu.addAction(tr("Pick random"), this, &MixerChannelView::randomizeColor);
|
||||
contextMenu->addMenu(&colorMenu);
|
||||
|
||||
contextMenu->exec(QCursor::pos());
|
||||
delete contextMenu;
|
||||
}
|
||||
|
||||
void MixerChannelView::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
auto * mixer = Engine::mixer();
|
||||
const auto channel = mixer->mixerChannel(m_channelIndex);
|
||||
const bool muted = channel->m_muteModel.value();
|
||||
const auto name = channel->m_name;
|
||||
const auto elidedName = elideName(name);
|
||||
const auto * mixerChannelView = m_mixerView->currentMixerChannel();
|
||||
const auto isActive = mixerChannelView == this;
|
||||
|
||||
if (!m_inRename && m_renameLineEdit->text() != elidedName)
|
||||
{
|
||||
m_renameLineEdit->setText(elidedName);
|
||||
}
|
||||
|
||||
const auto width = rect().width();
|
||||
const auto height = rect().height();
|
||||
auto painter = QPainter{this};
|
||||
|
||||
if (channel->color().has_value() && !muted)
|
||||
{
|
||||
painter.fillRect(rect(), channel->color()->darker(isActive ? 120 : 150));
|
||||
}
|
||||
else
|
||||
{
|
||||
painter.fillRect(rect(), isActive ? backgroundActive().color() : painter.background().color());
|
||||
}
|
||||
|
||||
// inner border
|
||||
painter.setPen(isActive ? strokeInnerActive() : strokeInnerInactive());
|
||||
painter.drawRect(1, 1, width - MIXER_CHANNEL_INNER_BORDER_SIZE, height - MIXER_CHANNEL_INNER_BORDER_SIZE);
|
||||
|
||||
// outer border
|
||||
painter.setPen(isActive ? strokeOuterActive() : strokeOuterInactive());
|
||||
painter.drawRect(0, 0, width - MIXER_CHANNEL_OUTER_BORDER_SIZE, height - MIXER_CHANNEL_OUTER_BORDER_SIZE);
|
||||
|
||||
const auto & currentMixerChannelIndex = mixerChannelView->m_channelIndex;
|
||||
const auto sendToThis = mixer->channelSendModel(currentMixerChannelIndex, m_channelIndex) != nullptr;
|
||||
const auto receiveFromThis = mixer->channelSendModel(m_channelIndex, currentMixerChannelIndex) != nullptr;
|
||||
const auto sendReceiveStateNone = !sendToThis && !receiveFromThis;
|
||||
|
||||
// Only one or none of them can be on
|
||||
assert(sendToThis ^ receiveFromThis || sendReceiveStateNone);
|
||||
|
||||
m_sendArrow->setVisible(sendToThis);
|
||||
m_receiveArrow->setVisible(receiveFromThis);
|
||||
|
||||
if (sendReceiveStateNone)
|
||||
{
|
||||
setSendReceiveState(SendReceiveState::None);
|
||||
}
|
||||
else
|
||||
{
|
||||
setSendReceiveState(sendToThis ? SendReceiveState::SendToThis : SendReceiveState::ReceiveFromThis);
|
||||
}
|
||||
|
||||
QWidget::paintEvent(event);
|
||||
}
|
||||
|
||||
void MixerChannelView::mousePressEvent(QMouseEvent*)
|
||||
{
|
||||
if (m_mixerView->currentMixerChannel() != this)
|
||||
{
|
||||
m_mixerView->setCurrentMixerChannel(this);
|
||||
}
|
||||
}
|
||||
|
||||
void MixerChannelView::mouseDoubleClickEvent(QMouseEvent*)
|
||||
{
|
||||
renameChannel();
|
||||
}
|
||||
|
||||
bool MixerChannelView::eventFilter(QObject* dist, QEvent* event)
|
||||
{
|
||||
// If we are in a rename, capture the enter/return events and handle them
|
||||
if (event->type() == QEvent::KeyPress)
|
||||
{
|
||||
auto keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return)
|
||||
{
|
||||
if (m_inRename)
|
||||
{
|
||||
renameFinished();
|
||||
event->accept(); // Stop the event from propagating
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int MixerChannelView::channelIndex() const
|
||||
{
|
||||
return m_channelIndex;
|
||||
}
|
||||
|
||||
void MixerChannelView::setChannelIndex(int index)
|
||||
{
|
||||
MixerChannel* mixerChannel = Engine::mixer()->mixerChannel(index);
|
||||
m_fader->setModel(&mixerChannel->m_volumeModel);
|
||||
m_muteButton->setModel(&mixerChannel->m_muteModel);
|
||||
m_soloButton->setModel(&mixerChannel->m_soloModel);
|
||||
m_effectRackView->setModel(&mixerChannel->m_fxChain);
|
||||
m_channelIndex = index;
|
||||
}
|
||||
|
||||
MixerChannelView::SendReceiveState MixerChannelView::sendReceiveState() const
|
||||
{
|
||||
return m_sendReceiveState;
|
||||
}
|
||||
|
||||
void MixerChannelView::setSendReceiveState(const SendReceiveState& state)
|
||||
{
|
||||
m_sendReceiveState = state;
|
||||
m_sendArrow->setVisible(state == SendReceiveState::SendToThis);
|
||||
m_receiveArrow->setVisible(state == SendReceiveState::ReceiveFromThis);
|
||||
}
|
||||
|
||||
QBrush MixerChannelView::backgroundActive() const
|
||||
{
|
||||
return m_backgroundActive;
|
||||
}
|
||||
|
||||
void MixerChannelView::setBackgroundActive(const QBrush& c)
|
||||
{
|
||||
m_backgroundActive = c;
|
||||
}
|
||||
|
||||
QColor MixerChannelView::strokeOuterActive() const
|
||||
{
|
||||
return m_strokeOuterActive;
|
||||
}
|
||||
|
||||
void MixerChannelView::setStrokeOuterActive(const QColor& c)
|
||||
{
|
||||
m_strokeOuterActive = c;
|
||||
}
|
||||
|
||||
QColor MixerChannelView::strokeOuterInactive() const
|
||||
{
|
||||
return m_strokeOuterInactive;
|
||||
}
|
||||
|
||||
void MixerChannelView::setStrokeOuterInactive(const QColor& c)
|
||||
{
|
||||
m_strokeOuterInactive = c;
|
||||
}
|
||||
|
||||
QColor MixerChannelView::strokeInnerActive() const
|
||||
{
|
||||
return m_strokeInnerActive;
|
||||
}
|
||||
|
||||
void MixerChannelView::setStrokeInnerActive(const QColor& c)
|
||||
{
|
||||
m_strokeInnerActive = c;
|
||||
}
|
||||
|
||||
QColor MixerChannelView::strokeInnerInactive() const
|
||||
{
|
||||
return m_strokeInnerInactive;
|
||||
}
|
||||
|
||||
void MixerChannelView::setStrokeInnerInactive(const QColor& c)
|
||||
{
|
||||
m_strokeInnerInactive = c;
|
||||
}
|
||||
|
||||
void MixerChannelView::renameChannel()
|
||||
{
|
||||
m_inRename = true;
|
||||
setToolTip("");
|
||||
m_renameLineEdit->setReadOnly(false);
|
||||
|
||||
m_channelNumberLcd->hide();
|
||||
m_renameLineEdit->setFixedWidth(m_renameLineEdit->width());
|
||||
m_renameLineEdit->setText(Engine::mixer()->mixerChannel(m_channelIndex)->m_name);
|
||||
|
||||
m_renameLineEditView->setFocus();
|
||||
m_renameLineEdit->selectAll();
|
||||
m_renameLineEdit->setFocus();
|
||||
}
|
||||
|
||||
void MixerChannelView::renameFinished()
|
||||
{
|
||||
m_inRename = false;
|
||||
|
||||
m_renameLineEdit->deselect();
|
||||
m_renameLineEdit->setReadOnly(true);
|
||||
m_renameLineEdit->setFixedWidth(m_renameLineEdit->width());
|
||||
m_channelNumberLcd->show();
|
||||
|
||||
auto newName = m_renameLineEdit->text();
|
||||
setFocus();
|
||||
|
||||
const auto mixerChannel = Engine::mixer()->mixerChannel(m_channelIndex);
|
||||
if (!newName.isEmpty() && mixerChannel->m_name != newName)
|
||||
{
|
||||
mixerChannel->m_name = newName;
|
||||
m_renameLineEdit->setText(elideName(newName));
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
|
||||
setToolTip(mixerChannel->m_name);
|
||||
}
|
||||
|
||||
void MixerChannelView::resetColor()
|
||||
{
|
||||
Engine::mixer()->mixerChannel(m_channelIndex)->setColor(std::nullopt);
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
}
|
||||
|
||||
void MixerChannelView::selectColor()
|
||||
{
|
||||
const auto channel = Engine::mixer()->mixerChannel(m_channelIndex);
|
||||
|
||||
const auto initialColor = channel->color().value_or(backgroundActive().color());
|
||||
const auto * colorChooser = ColorChooser{this}.withPalette(ColorChooser::Palette::Mixer);
|
||||
const auto newColor = colorChooser->getColor(initialColor);
|
||||
|
||||
if (!newColor.isValid()) { return; }
|
||||
|
||||
channel->setColor(newColor);
|
||||
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
}
|
||||
|
||||
void MixerChannelView::randomizeColor()
|
||||
{
|
||||
auto channel = Engine::mixer()->mixerChannel(m_channelIndex);
|
||||
channel->setColor(ColorChooser::getPalette(ColorChooser::Palette::Mixer)[rand() % 48]);
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
}
|
||||
|
||||
void MixerChannelView::removeChannel()
|
||||
{
|
||||
auto mix = getGUI()->mixerView();
|
||||
mix->deleteChannel(m_channelIndex);
|
||||
}
|
||||
|
||||
void MixerChannelView::removeUnusedChannels()
|
||||
{
|
||||
auto mix = getGUI()->mixerView();
|
||||
mix->deleteUnusedChannels();
|
||||
}
|
||||
|
||||
void MixerChannelView::moveChannelLeft()
|
||||
{
|
||||
auto mix = getGUI()->mixerView();
|
||||
mix->moveChannelLeft(m_channelIndex);
|
||||
}
|
||||
|
||||
void MixerChannelView::moveChannelRight()
|
||||
{
|
||||
auto mix = getGUI()->mixerView();
|
||||
mix->moveChannelRight(m_channelIndex);
|
||||
}
|
||||
|
||||
QString MixerChannelView::elideName(const QString& name)
|
||||
{
|
||||
const auto maxTextHeight = m_renameLineEdit->width();
|
||||
const auto metrics = QFontMetrics{m_renameLineEdit->font()};
|
||||
const auto elidedName = metrics.elidedText(name, Qt::ElideRight, maxTextHeight);
|
||||
return elidedName;
|
||||
}
|
||||
|
||||
} // namespace lmms::gui
|
||||
@@ -1,448 +0,0 @@
|
||||
/*
|
||||
* MixerLine.cpp - Mixer line widget
|
||||
*
|
||||
* Copyright (c) 2009 Andrew Kelley <superjoe30/at/gmail/dot/com>
|
||||
* Copyright (c) 2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* 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 "MixerLine.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <QGraphicsProxyWidget>
|
||||
#include <QGraphicsView>
|
||||
#include <QLineEdit>
|
||||
#include <QPainter>
|
||||
|
||||
#include "CaptionMenu.h"
|
||||
#include "ColorChooser.h"
|
||||
#include "embed.h"
|
||||
#include "Knob.h"
|
||||
#include "LcdWidget.h"
|
||||
#include "Mixer.h"
|
||||
#include "MixerView.h"
|
||||
#include "gui_templates.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "SendButtonIndicator.h"
|
||||
#include "Song.h"
|
||||
|
||||
namespace lmms::gui
|
||||
{
|
||||
|
||||
|
||||
bool MixerLine::eventFilter( QObject *dist, QEvent *event )
|
||||
{
|
||||
// If we are in a rename, capture the enter/return events and handle them
|
||||
if ( event->type() == QEvent::KeyPress )
|
||||
{
|
||||
auto keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if( keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return )
|
||||
{
|
||||
if( m_inRename )
|
||||
{
|
||||
renameFinished();
|
||||
event->accept(); // Stop the event from propagating
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const int MixerLine::MixerLineHeight = 287;
|
||||
|
||||
MixerLine::MixerLine( QWidget * _parent, MixerView * _mv, int _channelIndex ) :
|
||||
QWidget( _parent ),
|
||||
m_mv( _mv ),
|
||||
m_channelIndex( _channelIndex ),
|
||||
m_backgroundActive( Qt::SolidPattern ),
|
||||
m_strokeOuterActive( 0, 0, 0 ),
|
||||
m_strokeOuterInactive( 0, 0, 0 ),
|
||||
m_strokeInnerActive( 0, 0, 0 ),
|
||||
m_strokeInnerInactive( 0, 0, 0 ),
|
||||
m_inRename( false )
|
||||
{
|
||||
setFixedSize( 33, MixerLineHeight );
|
||||
setAttribute( Qt::WA_OpaquePaintEvent, true );
|
||||
setCursor( QCursor( embed::getIconPixmap( "hand" ), 3, 3 ) );
|
||||
|
||||
// mixer sends knob
|
||||
m_sendKnob = new Knob( KnobType::Bright26, this, tr( "Channel send amount" ) );
|
||||
m_sendKnob->move( 3, 22 );
|
||||
m_sendKnob->setVisible( false );
|
||||
|
||||
// send button indicator
|
||||
m_sendBtn = new SendButtonIndicator( this, this, m_mv );
|
||||
m_sendBtn->move( 2, 2 );
|
||||
|
||||
// channel number
|
||||
m_lcd = new LcdWidget( 2, this );
|
||||
m_lcd->setValue( m_channelIndex );
|
||||
m_lcd->move( 4, 58 );
|
||||
m_lcd->setMarginWidth( 1 );
|
||||
|
||||
QString name = Engine::mixer()->mixerChannel( m_channelIndex )->m_name;
|
||||
setToolTip( name );
|
||||
|
||||
m_renameLineEdit = new QLineEdit();
|
||||
m_renameLineEdit->setText( name );
|
||||
m_renameLineEdit->setFixedWidth( 65 );
|
||||
m_renameLineEdit->setFont( pointSizeF( font(), 7.5f ) );
|
||||
m_renameLineEdit->setReadOnly( true );
|
||||
m_renameLineEdit->installEventFilter( this );
|
||||
|
||||
auto scene = new QGraphicsScene();
|
||||
scene->setSceneRect( 0, 0, 33, MixerLineHeight );
|
||||
|
||||
m_view = new QGraphicsView( this );
|
||||
m_view->setStyleSheet( "border-style: none; background: transparent;" );
|
||||
m_view->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
m_view->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
m_view->setAttribute( Qt::WA_TransparentForMouseEvents, true );
|
||||
m_view->setScene( scene );
|
||||
|
||||
QGraphicsProxyWidget * proxyWidget = scene->addWidget( m_renameLineEdit );
|
||||
proxyWidget->setRotation( -90 );
|
||||
proxyWidget->setPos( 8, 145 );
|
||||
|
||||
connect( m_renameLineEdit, SIGNAL(editingFinished()), this, SLOT(renameFinished()));
|
||||
connect( &Engine::mixer()->mixerChannel( m_channelIndex )->m_muteModel, SIGNAL(dataChanged()), this, SLOT(update()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
MixerLine::~MixerLine()
|
||||
{
|
||||
delete m_sendKnob;
|
||||
delete m_sendBtn;
|
||||
delete m_lcd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::setChannelIndex( int index )
|
||||
{
|
||||
m_channelIndex = index;
|
||||
m_lcd->setValue( m_channelIndex );
|
||||
m_lcd->update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MixerLine::drawMixerLine( QPainter* p, const MixerLine *mixerLine, bool isActive, bool sendToThis, bool receiveFromThis )
|
||||
{
|
||||
auto channel = Engine::mixer()->mixerChannel( m_channelIndex );
|
||||
bool muted = channel->m_muteModel.value();
|
||||
QString name = channel->m_name;
|
||||
QString elidedName = elideName( name );
|
||||
if( !m_inRename && m_renameLineEdit->text() != elidedName )
|
||||
{
|
||||
m_renameLineEdit->setText( elidedName );
|
||||
}
|
||||
|
||||
int width = mixerLine->rect().width();
|
||||
int height = mixerLine->rect().height();
|
||||
|
||||
if (channel->color().has_value() && !muted)
|
||||
{
|
||||
p->fillRect(mixerLine->rect(), channel->color()->darker(isActive ? 120 : 150));
|
||||
}
|
||||
else
|
||||
{
|
||||
p->fillRect( mixerLine->rect(),
|
||||
isActive ? mixerLine->backgroundActive().color() : p->background().color() );
|
||||
}
|
||||
|
||||
// inner border
|
||||
p->setPen( isActive ? mixerLine->strokeInnerActive() : mixerLine->strokeInnerInactive() );
|
||||
p->drawRect( 1, 1, width-3, height-3 );
|
||||
|
||||
// outer border
|
||||
p->setPen( isActive ? mixerLine->strokeOuterActive() : mixerLine->strokeOuterInactive() );
|
||||
p->drawRect( 0, 0, width-1, height-1 );
|
||||
|
||||
// draw the mixer send background
|
||||
|
||||
static auto s_sendBgArrow = embed::getIconPixmap("send_bg_arrow", 29, 56);
|
||||
static auto s_receiveBgArrow = embed::getIconPixmap("receive_bg_arrow", 29, 56);
|
||||
p->drawPixmap(2, 0, 29, 56, sendToThis ? s_sendBgArrow : s_receiveBgArrow);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString MixerLine::elideName( const QString & name )
|
||||
{
|
||||
const int maxTextHeight = 60;
|
||||
QFontMetrics metrics( m_renameLineEdit->font() );
|
||||
QString elidedName = metrics.elidedText( name, Qt::ElideRight, maxTextHeight );
|
||||
return elidedName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::paintEvent( QPaintEvent * )
|
||||
{
|
||||
bool sendToThis = Engine::mixer()->channelSendModel( m_mv->currentMixerLine()->m_channelIndex, m_channelIndex ) != nullptr;
|
||||
bool receiveFromThis = Engine::mixer()->channelSendModel( m_channelIndex, m_mv->currentMixerLine()->m_channelIndex ) != nullptr;
|
||||
QPainter painter;
|
||||
painter.begin( this );
|
||||
drawMixerLine( &painter, this, m_mv->currentMixerLine() == this, sendToThis, receiveFromThis );
|
||||
painter.end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::mousePressEvent( QMouseEvent * )
|
||||
{
|
||||
m_mv->setCurrentMixerLine( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::mouseDoubleClickEvent( QMouseEvent * )
|
||||
{
|
||||
renameChannel();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::contextMenuEvent( QContextMenuEvent * )
|
||||
{
|
||||
QPointer<CaptionMenu> contextMenu = new CaptionMenu( Engine::mixer()->mixerChannel( m_channelIndex )->m_name, this );
|
||||
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()));
|
||||
}
|
||||
contextMenu->addAction( tr( "Rename &channel" ), this, SLOT(renameChannel()));
|
||||
contextMenu->addSeparator();
|
||||
|
||||
if( m_channelIndex != 0 ) // no remove-option in master
|
||||
{
|
||||
contextMenu->addAction( embed::getIconPixmap( "cancel" ), tr( "R&emove channel" ), this, SLOT(removeChannel()));
|
||||
contextMenu->addSeparator();
|
||||
}
|
||||
contextMenu->addAction( embed::getIconPixmap( "cancel" ), tr( "Remove &unused channels" ), this, SLOT(removeUnusedChannels()));
|
||||
contextMenu->addSeparator();
|
||||
|
||||
QMenu colorMenu(tr("Color"), this);
|
||||
colorMenu.setIcon(embed::getIconPixmap("colorize"));
|
||||
colorMenu.addAction(tr("Change"), this, SLOT(selectColor()));
|
||||
colorMenu.addAction(tr("Reset"), this, SLOT(resetColor()));
|
||||
colorMenu.addAction(tr("Pick random"), this, SLOT(randomizeColor()));
|
||||
contextMenu->addMenu(&colorMenu);
|
||||
|
||||
contextMenu->exec( QCursor::pos() );
|
||||
delete contextMenu;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::renameChannel()
|
||||
{
|
||||
m_inRename = true;
|
||||
setToolTip( "" );
|
||||
m_renameLineEdit->setReadOnly( false );
|
||||
m_lcd->hide();
|
||||
m_renameLineEdit->setFixedWidth( 135 );
|
||||
m_renameLineEdit->setText( Engine::mixer()->mixerChannel( m_channelIndex )->m_name );
|
||||
m_view->setFocus();
|
||||
m_renameLineEdit->selectAll();
|
||||
m_renameLineEdit->setFocus();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::renameFinished()
|
||||
{
|
||||
m_inRename = false;
|
||||
m_renameLineEdit->deselect();
|
||||
m_renameLineEdit->setReadOnly( true );
|
||||
m_renameLineEdit->setFixedWidth( 65 );
|
||||
m_lcd->show();
|
||||
QString newName = m_renameLineEdit->text();
|
||||
setFocus();
|
||||
if( !newName.isEmpty() && Engine::mixer()->mixerChannel( m_channelIndex )->m_name != newName )
|
||||
{
|
||||
Engine::mixer()->mixerChannel( m_channelIndex )->m_name = newName;
|
||||
m_renameLineEdit->setText( elideName( newName ) );
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
QString name = Engine::mixer()->mixerChannel( m_channelIndex )->m_name;
|
||||
setToolTip( name );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::removeChannel()
|
||||
{
|
||||
MixerView * mix = getGUI()->mixerView();
|
||||
mix->deleteChannel( m_channelIndex );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::removeUnusedChannels()
|
||||
{
|
||||
MixerView * mix = getGUI()->mixerView();
|
||||
mix->deleteUnusedChannels();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::moveChannelLeft()
|
||||
{
|
||||
MixerView * mix = getGUI()->mixerView();
|
||||
mix->moveChannelLeft( m_channelIndex );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::moveChannelRight()
|
||||
{
|
||||
MixerView * mix = getGUI()->mixerView();
|
||||
mix->moveChannelRight( m_channelIndex );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QBrush MixerLine::backgroundActive() const
|
||||
{
|
||||
return m_backgroundActive;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::setBackgroundActive( const QBrush & c )
|
||||
{
|
||||
m_backgroundActive = c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QColor MixerLine::strokeOuterActive() const
|
||||
{
|
||||
return m_strokeOuterActive;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::setStrokeOuterActive( const QColor & c )
|
||||
{
|
||||
m_strokeOuterActive = c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QColor MixerLine::strokeOuterInactive() const
|
||||
{
|
||||
return m_strokeOuterInactive;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::setStrokeOuterInactive( const QColor & c )
|
||||
{
|
||||
m_strokeOuterInactive = c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QColor MixerLine::strokeInnerActive() const
|
||||
{
|
||||
return m_strokeInnerActive;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::setStrokeInnerActive( const QColor & c )
|
||||
{
|
||||
m_strokeInnerActive = c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QColor MixerLine::strokeInnerInactive() const
|
||||
{
|
||||
return m_strokeInnerInactive;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerLine::setStrokeInnerInactive( const QColor & c )
|
||||
{
|
||||
m_strokeInnerInactive = c;
|
||||
}
|
||||
|
||||
// Ask user for a color, and set it as the mixer line color
|
||||
void MixerLine::selectColor()
|
||||
{
|
||||
const auto channel = Engine::mixer()->mixerChannel(m_channelIndex);
|
||||
const auto newColor = ColorChooser{this}
|
||||
.withPalette(ColorChooser::Palette::Mixer)
|
||||
->getColor(channel->color().value_or(backgroundActive().color()));
|
||||
if (!newColor.isValid()) { return; }
|
||||
channel->setColor(newColor);
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
}
|
||||
|
||||
// Disable the usage of color on this mixer line
|
||||
void MixerLine::resetColor()
|
||||
{
|
||||
Engine::mixer()->mixerChannel(m_channelIndex)->setColor(std::nullopt);
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
}
|
||||
|
||||
// Pick a random color from the mixer palette and set it as our color
|
||||
void MixerLine::randomizeColor()
|
||||
{
|
||||
const auto channel = Engine::mixer()->mixerChannel(m_channelIndex);
|
||||
channel->setColor(ColorChooser::getPalette(ColorChooser::Palette::Mixer)[std::rand() % 48]);
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
}
|
||||
|
||||
} // namespace lmms::gui
|
||||
@@ -33,9 +33,9 @@
|
||||
|
||||
#include "lmms_math.h"
|
||||
|
||||
#include "MixerChannelView.h"
|
||||
#include "MixerView.h"
|
||||
#include "Knob.h"
|
||||
#include "MixerLine.h"
|
||||
#include "Mixer.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "MainWindow.h"
|
||||
@@ -54,7 +54,7 @@ namespace lmms::gui
|
||||
|
||||
MixerView::MixerView() :
|
||||
QWidget(),
|
||||
ModelView( nullptr, this ),
|
||||
ModelView(nullptr, this),
|
||||
SerializingObjectHook()
|
||||
{
|
||||
#if QT_VERSION < 0x50C00
|
||||
@@ -68,54 +68,54 @@ MixerView::MixerView() :
|
||||
#endif
|
||||
|
||||
Mixer * m = Engine::mixer();
|
||||
m->setHook( this );
|
||||
m->setHook(this);
|
||||
|
||||
//QPalette pal = palette();
|
||||
//pal.setColor( QPalette::Window, QColor( 72, 76, 88 ) );
|
||||
//setPalette( pal );
|
||||
//pal.setColor(QPalette::Window, QColor(72, 76, 88));
|
||||
//setPalette(pal);
|
||||
|
||||
setAutoFillBackground( true );
|
||||
setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
|
||||
setAutoFillBackground(true);
|
||||
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
|
||||
setWindowTitle( tr( "Mixer" ) );
|
||||
setWindowIcon( embed::getIconPixmap( "mixer" ) );
|
||||
setWindowTitle(tr("Mixer"));
|
||||
setWindowIcon(embed::getIconPixmap("mixer"));
|
||||
|
||||
// main-layout
|
||||
auto ml = new QHBoxLayout;
|
||||
auto ml = new QHBoxLayout{this};
|
||||
|
||||
// Set margins
|
||||
ml->setContentsMargins( 0, 4, 0, 0 );
|
||||
ml->setContentsMargins(0, 4, 0, 0);
|
||||
|
||||
// Channel area
|
||||
m_channelAreaWidget = new QWidget;
|
||||
chLayout = new QHBoxLayout( m_channelAreaWidget );
|
||||
chLayout->setSizeConstraint( QLayout::SetMinimumSize );
|
||||
chLayout->setSpacing( 0 );
|
||||
chLayout = new QHBoxLayout(m_channelAreaWidget);
|
||||
chLayout->setSizeConstraint(QLayout::SetMinimumSize);
|
||||
chLayout->setSpacing(0);
|
||||
chLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_channelAreaWidget->setLayout(chLayout);
|
||||
|
||||
// create rack layout before creating the first channel
|
||||
m_racksWidget = new QWidget;
|
||||
m_racksLayout = new QStackedLayout( m_racksWidget );
|
||||
m_racksLayout->setContentsMargins( 0, 0, 0, 0 );
|
||||
m_racksWidget->setLayout( m_racksLayout );
|
||||
m_racksLayout = new QStackedLayout(m_racksWidget);
|
||||
m_racksLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_racksWidget->setLayout(m_racksLayout);
|
||||
|
||||
// add master channel
|
||||
m_mixerChannelViews.resize( m->numChannels() );
|
||||
m_mixerChannelViews[0] = new MixerChannelView( this, this, 0 );
|
||||
m_mixerChannelViews.resize(m->numChannels());
|
||||
m_mixerChannelViews[0] = new MixerChannelView(this, this, 0);
|
||||
|
||||
m_racksLayout->addWidget( m_mixerChannelViews[0]->m_rackView );
|
||||
m_racksLayout->addWidget(m_mixerChannelViews[0]->m_effectRackView);
|
||||
|
||||
MixerChannelView * masterView = m_mixerChannelViews[0];
|
||||
ml->addWidget( masterView->m_mixerLine, 0, Qt::AlignTop );
|
||||
ml->addWidget(masterView, 0, Qt::AlignTop);
|
||||
|
||||
QSize mixerLineSize = masterView->m_mixerLine->size();
|
||||
auto mixerChannelSize = masterView->sizeHint();
|
||||
|
||||
// add mixer channels
|
||||
for( int i = 1; i < m_mixerChannelViews.size(); ++i )
|
||||
for (int i = 1; i < m_mixerChannelViews.size(); ++i)
|
||||
{
|
||||
m_mixerChannelViews[i] = new MixerChannelView(m_channelAreaWidget, this, i);
|
||||
chLayout->addWidget( m_mixerChannelViews[i]->m_mixerLine );
|
||||
chLayout->addWidget(m_mixerChannelViews[i]);
|
||||
}
|
||||
|
||||
// add the scrolling section to the main layout
|
||||
@@ -123,68 +123,63 @@ MixerView::MixerView() :
|
||||
class ChannelArea : public QScrollArea
|
||||
{
|
||||
public:
|
||||
ChannelArea( QWidget * parent, MixerView * mv ) :
|
||||
QScrollArea( parent ), m_mv( mv ) {}
|
||||
ChannelArea(QWidget* parent, MixerView* mv) :
|
||||
QScrollArea(parent), m_mv(mv) {}
|
||||
~ChannelArea() override = default;
|
||||
void keyPressEvent( QKeyEvent * e ) override
|
||||
void keyPressEvent(QKeyEvent* e) override
|
||||
{
|
||||
m_mv->keyPressEvent( e );
|
||||
m_mv->keyPressEvent(e);
|
||||
}
|
||||
private:
|
||||
MixerView * m_mv;
|
||||
MixerView* m_mv;
|
||||
};
|
||||
channelArea = new ChannelArea( this, this );
|
||||
channelArea->setWidget( m_channelAreaWidget );
|
||||
channelArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
channelArea->setFrameStyle( QFrame::NoFrame );
|
||||
channelArea->setMinimumWidth( mixerLineSize.width() * 6 );
|
||||
channelArea->setFixedHeight( mixerLineSize.height() +
|
||||
style()->pixelMetric( QStyle::PM_ScrollBarExtent ) );
|
||||
ml->addWidget( channelArea, 1, Qt::AlignTop );
|
||||
channelArea = new ChannelArea(this, this);
|
||||
channelArea->setWidget(m_channelAreaWidget);
|
||||
channelArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
channelArea->setFrameStyle(QFrame::NoFrame);
|
||||
channelArea->setMinimumWidth(mixerChannelSize.width() * 6);
|
||||
|
||||
int const scrollBarExtent = style()->pixelMetric(QStyle::PM_ScrollBarExtent);
|
||||
channelArea->setFixedHeight(mixerChannelSize.height() + scrollBarExtent);
|
||||
|
||||
ml->addWidget(channelArea, 1, Qt::AlignTop);
|
||||
|
||||
// show the add new mixer channel button
|
||||
auto newChannelBtn = new QPushButton(embed::getIconPixmap("new_channel"), QString(), this);
|
||||
newChannelBtn->setObjectName( "newChannelBtn" );
|
||||
newChannelBtn->setFixedSize( mixerLineSize );
|
||||
connect( newChannelBtn, SIGNAL(clicked()), this, SLOT(addNewChannel()));
|
||||
ml->addWidget( newChannelBtn, 0, Qt::AlignTop );
|
||||
newChannelBtn->setObjectName("newChannelBtn");
|
||||
newChannelBtn->setFixedSize(mixerChannelSize);
|
||||
connect(newChannelBtn, SIGNAL(clicked()), this, SLOT(addNewChannel()));
|
||||
ml->addWidget(newChannelBtn, 0, Qt::AlignTop);
|
||||
|
||||
|
||||
// add the stacked layout for the effect racks of mixer channels
|
||||
ml->addWidget( m_racksWidget, 0, Qt::AlignTop | Qt::AlignRight );
|
||||
m_racksWidget->setFixedHeight(mixerChannelSize.height());
|
||||
ml->addWidget(m_racksWidget);
|
||||
|
||||
setCurrentMixerLine( m_mixerChannelViews[0]->m_mixerLine );
|
||||
setCurrentMixerChannel(m_mixerChannelViews[0]);
|
||||
|
||||
setLayout( ml );
|
||||
updateGeometry();
|
||||
|
||||
// timer for updating faders
|
||||
connect( getGUI()->mainWindow(), SIGNAL(periodicUpdate()),
|
||||
this, SLOT(updateFaders()));
|
||||
auto* mainWindow = getGUI()->mainWindow();
|
||||
|
||||
// timer for updating faders
|
||||
connect(mainWindow, &MainWindow::periodicUpdate, this, &MixerView::updateFaders);
|
||||
|
||||
// add ourself to workspace
|
||||
QMdiSubWindow * subWin = getGUI()->mainWindow()->addWindowedWidget( this );
|
||||
QMdiSubWindow* subWin = mainWindow->addWindowedWidget(this);
|
||||
Qt::WindowFlags flags = subWin->windowFlags();
|
||||
flags &= ~Qt::WindowMaximizeButtonHint;
|
||||
subWin->setWindowFlags( flags );
|
||||
layout()->setSizeConstraint( QLayout::SetMinimumSize );
|
||||
subWin->layout()->setSizeConstraint( QLayout::SetMinAndMaxSize );
|
||||
subWin->setWindowFlags(flags);
|
||||
layout()->setSizeConstraint(QLayout::SetMinimumSize);
|
||||
subWin->layout()->setSizeConstraint(QLayout::SetMinAndMaxSize);
|
||||
|
||||
parentWidget()->setAttribute( Qt::WA_DeleteOnClose, false );
|
||||
parentWidget()->move( 5, 310 );
|
||||
parentWidget()->setAttribute(Qt::WA_DeleteOnClose, false);
|
||||
parentWidget()->move(5, 310);
|
||||
|
||||
// we want to receive dataChanged-signals in order to update
|
||||
setModel( m );
|
||||
setModel(m);
|
||||
}
|
||||
|
||||
MixerView::~MixerView()
|
||||
{
|
||||
for (auto mixerChannelView : m_mixerChannelViews)
|
||||
{
|
||||
delete mixerChannelView;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -194,12 +189,11 @@ int MixerView::addNewChannel()
|
||||
Mixer * mix = Engine::mixer();
|
||||
|
||||
int newChannelIndex = mix->createChannel();
|
||||
m_mixerChannelViews.push_back(new MixerChannelView(m_channelAreaWidget, this,
|
||||
newChannelIndex));
|
||||
chLayout->addWidget( m_mixerChannelViews[newChannelIndex]->m_mixerLine );
|
||||
m_racksLayout->addWidget( m_mixerChannelViews[newChannelIndex]->m_rackView );
|
||||
m_mixerChannelViews.push_back(new MixerChannelView(m_channelAreaWidget, this, newChannelIndex));
|
||||
chLayout->addWidget(m_mixerChannelViews[newChannelIndex]);
|
||||
m_racksLayout->addWidget(m_mixerChannelViews[newChannelIndex]->m_effectRackView);
|
||||
|
||||
updateMixerLine(newChannelIndex);
|
||||
updateMixerChannel(newChannelIndex);
|
||||
|
||||
updateMaxChannelSelector();
|
||||
|
||||
@@ -210,35 +204,29 @@ int MixerView::addNewChannel()
|
||||
void MixerView::refreshDisplay()
|
||||
{
|
||||
// delete all views and re-add them
|
||||
for( int i = 1; i<m_mixerChannelViews.size(); ++i )
|
||||
for (int i = 1; i<m_mixerChannelViews.size(); ++i)
|
||||
{
|
||||
chLayout->removeWidget(m_mixerChannelViews[i]->m_mixerLine);
|
||||
m_racksLayout->removeWidget( m_mixerChannelViews[i]->m_rackView );
|
||||
delete m_mixerChannelViews[i]->m_fader;
|
||||
delete m_mixerChannelViews[i]->m_muteBtn;
|
||||
delete m_mixerChannelViews[i]->m_soloBtn;
|
||||
delete m_mixerChannelViews[i]->m_mixerLine;
|
||||
delete m_mixerChannelViews[i]->m_rackView;
|
||||
delete m_mixerChannelViews[i];
|
||||
chLayout->removeWidget(m_mixerChannelViews[i]);
|
||||
m_racksLayout->removeWidget(m_mixerChannelViews[i]->m_effectRackView);
|
||||
}
|
||||
m_channelAreaWidget->adjustSize();
|
||||
|
||||
// re-add the views
|
||||
m_mixerChannelViews.resize(Engine::mixer()->numChannels());
|
||||
for( int i = 1; i < m_mixerChannelViews.size(); ++i )
|
||||
for (int i = 1; i < m_mixerChannelViews.size(); ++i)
|
||||
{
|
||||
m_mixerChannelViews[i] = new MixerChannelView(m_channelAreaWidget, this, i);
|
||||
chLayout->addWidget(m_mixerChannelViews[i]->m_mixerLine);
|
||||
m_racksLayout->addWidget( m_mixerChannelViews[i]->m_rackView );
|
||||
chLayout->addWidget(m_mixerChannelViews[i]);
|
||||
m_racksLayout->addWidget(m_mixerChannelViews[i]->m_effectRackView);
|
||||
}
|
||||
|
||||
// set selected mixer line to 0
|
||||
setCurrentMixerLine( 0 );
|
||||
// set selected mixer channel to 0
|
||||
setCurrentMixerChannel(0);
|
||||
|
||||
// update all mixer lines
|
||||
for( int i = 0; i < m_mixerChannelViews.size(); ++i )
|
||||
for (int i = 0; i < m_mixerChannelViews.size(); ++i)
|
||||
{
|
||||
updateMixerLine( i );
|
||||
updateMixerChannel(i);
|
||||
}
|
||||
|
||||
updateMaxChannelSelector();
|
||||
@@ -272,74 +260,21 @@ void MixerView::updateMaxChannelSelector()
|
||||
}
|
||||
|
||||
|
||||
void MixerView::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
void MixerView::saveSettings(QDomDocument& doc, QDomElement& domElement)
|
||||
{
|
||||
MainWindow::saveWidgetState( this, _this );
|
||||
MainWindow::saveWidgetState(this, domElement);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void MixerView::loadSettings( const QDomElement & _this )
|
||||
void MixerView::loadSettings(const QDomElement& domElement)
|
||||
{
|
||||
MainWindow::restoreWidgetState( this, _this );
|
||||
MainWindow::restoreWidgetState(this, domElement);
|
||||
}
|
||||
|
||||
|
||||
MixerView::MixerChannelView::MixerChannelView(QWidget * _parent, MixerView * _mv,
|
||||
int channelIndex )
|
||||
{
|
||||
m_mixerLine = new MixerLine(_parent, _mv, channelIndex);
|
||||
|
||||
MixerChannel *mixerChannel = Engine::mixer()->mixerChannel(channelIndex);
|
||||
|
||||
m_fader = new Fader( &mixerChannel->m_volumeModel,
|
||||
tr( "Fader %1" ).arg( channelIndex ), m_mixerLine );
|
||||
m_fader->setLevelsDisplayedInDBFS();
|
||||
m_fader->setMinPeak(dbfsToAmp(-42));
|
||||
m_fader->setMaxPeak(dbfsToAmp(9));
|
||||
|
||||
m_fader->move( 16-m_fader->width()/2,
|
||||
m_mixerLine->height()-
|
||||
m_fader->height()-5 );
|
||||
|
||||
m_muteBtn = new PixmapButton( m_mixerLine, tr( "Mute" ) );
|
||||
m_muteBtn->setModel( &mixerChannel->m_muteModel );
|
||||
m_muteBtn->setActiveGraphic(
|
||||
embed::getIconPixmap( "led_off" ) );
|
||||
m_muteBtn->setInactiveGraphic(
|
||||
embed::getIconPixmap( "led_green" ) );
|
||||
m_muteBtn->setCheckable( true );
|
||||
m_muteBtn->move( 9, m_fader->y()-11);
|
||||
m_muteBtn->setToolTip(tr("Mute this channel"));
|
||||
|
||||
m_soloBtn = new PixmapButton( m_mixerLine, tr( "Solo" ) );
|
||||
m_soloBtn->setModel( &mixerChannel->m_soloModel );
|
||||
m_soloBtn->setActiveGraphic(
|
||||
embed::getIconPixmap( "led_red" ) );
|
||||
m_soloBtn->setInactiveGraphic(
|
||||
embed::getIconPixmap( "led_off" ) );
|
||||
m_soloBtn->setCheckable( true );
|
||||
m_soloBtn->move( 9, m_fader->y()-21);
|
||||
connect(&mixerChannel->m_soloModel, SIGNAL(dataChanged()),
|
||||
_mv, SLOT ( toggledSolo() ), Qt::DirectConnection );
|
||||
m_soloBtn->setToolTip(tr("Solo this channel"));
|
||||
|
||||
// Create EffectRack for the channel
|
||||
m_rackView = new EffectRackView( &mixerChannel->m_fxChain, _mv->m_racksWidget );
|
||||
m_rackView->setFixedSize( EffectRackView::DEFAULT_WIDTH, MixerLine::MixerLineHeight );
|
||||
}
|
||||
|
||||
|
||||
void MixerView::MixerChannelView::setChannelIndex( int index )
|
||||
{
|
||||
MixerChannel* mixerChannel = Engine::mixer()->mixerChannel( index );
|
||||
|
||||
m_fader->setModel( &mixerChannel->m_volumeModel );
|
||||
m_muteBtn->setModel( &mixerChannel->m_muteModel );
|
||||
m_soloBtn->setModel( &mixerChannel->m_soloModel );
|
||||
m_rackView->setModel( &mixerChannel->m_fxChain );
|
||||
}
|
||||
|
||||
|
||||
void MixerView::toggledSolo()
|
||||
@@ -349,31 +284,31 @@ void MixerView::toggledSolo()
|
||||
|
||||
|
||||
|
||||
void MixerView::setCurrentMixerLine( MixerLine * _line )
|
||||
void MixerView::setCurrentMixerChannel(MixerChannelView* channel)
|
||||
{
|
||||
// select
|
||||
m_currentMixerLine = _line;
|
||||
m_racksLayout->setCurrentWidget( m_mixerChannelViews[ _line->channelIndex() ]->m_rackView );
|
||||
m_currentMixerChannel = channel;
|
||||
m_racksLayout->setCurrentWidget(m_mixerChannelViews[channel->channelIndex()]->m_effectRackView);
|
||||
|
||||
// set up send knob
|
||||
for(int i = 0; i < m_mixerChannelViews.size(); ++i)
|
||||
for (int i = 0; i < m_mixerChannelViews.size(); ++i)
|
||||
{
|
||||
updateMixerLine(i);
|
||||
updateMixerChannel(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MixerView::updateMixerLine(int index)
|
||||
void MixerView::updateMixerChannel(int index)
|
||||
{
|
||||
Mixer * mix = Engine::mixer();
|
||||
|
||||
// does current channel send to this channel?
|
||||
int selIndex = m_currentMixerLine->channelIndex();
|
||||
MixerLine * thisLine = m_mixerChannelViews[index]->m_mixerLine;
|
||||
thisLine->setToolTip( Engine::mixer()->mixerChannel( index )->m_name );
|
||||
int selIndex = m_currentMixerChannel->channelIndex();
|
||||
auto thisLine = m_mixerChannelViews[index];
|
||||
thisLine->setToolTip(Engine::mixer()->mixerChannel(index)->m_name);
|
||||
|
||||
FloatModel * sendModel = mix->channelSendModel(selIndex, index);
|
||||
if( sendModel == nullptr )
|
||||
if (sendModel == nullptr)
|
||||
{
|
||||
// does not send, hide send knob
|
||||
thisLine->m_sendKnob->setVisible(false);
|
||||
@@ -386,8 +321,8 @@ void MixerView::updateMixerLine(int index)
|
||||
}
|
||||
|
||||
// disable the send button if it would cause an infinite loop
|
||||
thisLine->m_sendBtn->setVisible(! mix->isInfiniteLoop(selIndex, index));
|
||||
thisLine->m_sendBtn->updateLightStatus();
|
||||
thisLine->m_sendButton->setVisible(!mix->isInfiniteLoop(selIndex, index));
|
||||
thisLine->m_sendButton->updateLightStatus();
|
||||
thisLine->update();
|
||||
}
|
||||
|
||||
@@ -395,7 +330,7 @@ void MixerView::updateMixerLine(int index)
|
||||
void MixerView::deleteChannel(int index)
|
||||
{
|
||||
// can't delete master
|
||||
if( index == 0 ) return;
|
||||
if (index == 0) return;
|
||||
|
||||
// if there is no user confirmation, do nothing
|
||||
if (!confirmRemoval(index))
|
||||
@@ -404,7 +339,7 @@ void MixerView::deleteChannel(int index)
|
||||
}
|
||||
|
||||
// remember selected line
|
||||
int selLine = m_currentMixerLine->channelIndex();
|
||||
int selLine = m_currentMixerChannel->channelIndex();
|
||||
|
||||
// in case the deleted channel is soloed or the remaining
|
||||
// channels will be left in a muted state
|
||||
@@ -413,23 +348,17 @@ void MixerView::deleteChannel(int index)
|
||||
// delete the real channel
|
||||
Engine::mixer()->deleteChannel(index);
|
||||
|
||||
// delete the view
|
||||
chLayout->removeWidget(m_mixerChannelViews[index]->m_mixerLine);
|
||||
m_racksLayout->removeWidget(m_mixerChannelViews[index]->m_rackView);
|
||||
delete m_mixerChannelViews[index]->m_fader;
|
||||
delete m_mixerChannelViews[index]->m_muteBtn;
|
||||
delete m_mixerChannelViews[index]->m_soloBtn;
|
||||
// delete mixerLine later to prevent a crash when deleting from context menu
|
||||
m_mixerChannelViews[index]->m_mixerLine->hide();
|
||||
m_mixerChannelViews[index]->m_mixerLine->deleteLater();
|
||||
delete m_mixerChannelViews[index]->m_rackView;
|
||||
delete m_mixerChannelViews[index];
|
||||
chLayout->removeWidget(m_mixerChannelViews[index]);
|
||||
m_racksLayout->removeWidget(m_mixerChannelViews[index]);
|
||||
// delete MixerChannelView later to prevent a crash when deleting from context menu
|
||||
m_mixerChannelViews[index]->hide();
|
||||
m_mixerChannelViews[index]->deleteLater();
|
||||
m_channelAreaWidget->adjustSize();
|
||||
|
||||
// make sure every channel knows what index it is
|
||||
for (int i = index + 1; i < m_mixerChannelViews.size(); ++i)
|
||||
{
|
||||
m_mixerChannelViews[i]->m_mixerLine->setChannelIndex(i - 1);
|
||||
m_mixerChannelViews[i]->setChannelIndex(i - 1);
|
||||
}
|
||||
m_mixerChannelViews.remove(index);
|
||||
|
||||
@@ -438,7 +367,7 @@ void MixerView::deleteChannel(int index)
|
||||
{
|
||||
selLine = m_mixerChannelViews.size() - 1;
|
||||
}
|
||||
setCurrentMixerLine(selLine);
|
||||
setCurrentMixerChannel(selLine);
|
||||
|
||||
updateMaxChannelSelector();
|
||||
}
|
||||
@@ -503,39 +432,39 @@ void MixerView::deleteUnusedChannels()
|
||||
void MixerView::moveChannelLeft(int index, int focusIndex)
|
||||
{
|
||||
// can't move master or first channel left or last channel right
|
||||
if( index <= 1 || index >= m_mixerChannelViews.size() ) return;
|
||||
if (index <= 1 || index >= m_mixerChannelViews.size()) return;
|
||||
|
||||
Mixer *m = Engine::mixer();
|
||||
|
||||
// Move instruments channels
|
||||
m->moveChannelLeft( index );
|
||||
m->moveChannelLeft(index);
|
||||
|
||||
// Update widgets models
|
||||
m_mixerChannelViews[index]->setChannelIndex( index );
|
||||
m_mixerChannelViews[index - 1]->setChannelIndex( index - 1 );
|
||||
m_mixerChannelViews[index]->setChannelIndex(index);
|
||||
m_mixerChannelViews[index - 1]->setChannelIndex(index - 1);
|
||||
|
||||
// Focus on new position
|
||||
setCurrentMixerLine( focusIndex );
|
||||
setCurrentMixerChannel(focusIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MixerView::moveChannelLeft(int index)
|
||||
{
|
||||
moveChannelLeft( index, index - 1 );
|
||||
moveChannelLeft(index, index - 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MixerView::moveChannelRight(int index)
|
||||
{
|
||||
moveChannelLeft( index + 1, index + 1 );
|
||||
moveChannelLeft(index + 1, index + 1);
|
||||
}
|
||||
|
||||
|
||||
void MixerView::renameChannel(int index)
|
||||
{
|
||||
m_mixerChannelViews[index]->m_mixerLine->renameChannel();
|
||||
m_mixerChannelViews[index]->renameChannel();
|
||||
}
|
||||
|
||||
|
||||
@@ -545,32 +474,32 @@ void MixerView::keyPressEvent(QKeyEvent * e)
|
||||
switch(e->key())
|
||||
{
|
||||
case Qt::Key_Delete:
|
||||
deleteChannel(m_currentMixerLine->channelIndex());
|
||||
deleteChannel(m_currentMixerChannel->channelIndex());
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
if( e->modifiers() & Qt::AltModifier )
|
||||
if (e->modifiers() & Qt::AltModifier)
|
||||
{
|
||||
moveChannelLeft( m_currentMixerLine->channelIndex() );
|
||||
moveChannelLeft(m_currentMixerChannel->channelIndex());
|
||||
}
|
||||
else
|
||||
{
|
||||
// select channel to the left
|
||||
setCurrentMixerLine( m_currentMixerLine->channelIndex()-1 );
|
||||
setCurrentMixerChannel(m_currentMixerChannel->channelIndex() - 1);
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Right:
|
||||
if( e->modifiers() & Qt::AltModifier )
|
||||
if (e->modifiers() & Qt::AltModifier)
|
||||
{
|
||||
moveChannelRight( m_currentMixerLine->channelIndex() );
|
||||
moveChannelRight(m_currentMixerChannel->channelIndex());
|
||||
}
|
||||
else
|
||||
{
|
||||
// select channel to the right
|
||||
setCurrentMixerLine( m_currentMixerLine->channelIndex()+1 );
|
||||
setCurrentMixerChannel(m_currentMixerChannel->channelIndex() + 1);
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Insert:
|
||||
if ( e->modifiers() & Qt::ShiftModifier )
|
||||
if (e->modifiers() & Qt::ShiftModifier)
|
||||
{
|
||||
addNewChannel();
|
||||
}
|
||||
@@ -578,16 +507,16 @@ void MixerView::keyPressEvent(QKeyEvent * e)
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_F2:
|
||||
renameChannel( m_currentMixerLine->channelIndex() );
|
||||
renameChannel(m_currentMixerChannel->channelIndex());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MixerView::closeEvent( QCloseEvent * _ce )
|
||||
void MixerView::closeEvent(QCloseEvent * ce)
|
||||
{
|
||||
if( parentWidget() )
|
||||
if (parentWidget())
|
||||
{
|
||||
parentWidget()->hide();
|
||||
}
|
||||
@@ -595,16 +524,16 @@ void MixerView::closeEvent( QCloseEvent * _ce )
|
||||
{
|
||||
hide();
|
||||
}
|
||||
_ce->ignore();
|
||||
ce->ignore();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MixerView::setCurrentMixerLine( int _line )
|
||||
void MixerView::setCurrentMixerChannel(int channel)
|
||||
{
|
||||
if( _line >= 0 && _line < m_mixerChannelViews.size() )
|
||||
if (channel >= 0 && channel < m_mixerChannelViews.size())
|
||||
{
|
||||
setCurrentMixerLine( m_mixerChannelViews[_line]->m_mixerLine );
|
||||
setCurrentMixerChannel(m_mixerChannelViews[channel]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -628,31 +557,31 @@ void MixerView::updateFaders()
|
||||
m->mixerChannel(0)->m_peakLeft *= Engine::audioEngine()->masterGain();
|
||||
m->mixerChannel(0)->m_peakRight *= Engine::audioEngine()->masterGain();
|
||||
|
||||
for( int i = 0; i < m_mixerChannelViews.size(); ++i )
|
||||
for (int i = 0; i < m_mixerChannelViews.size(); ++i)
|
||||
{
|
||||
const float opl = m_mixerChannelViews[i]->m_fader->getPeak_L();
|
||||
const float opr = m_mixerChannelViews[i]->m_fader->getPeak_R();
|
||||
const float fallOff = 1.25;
|
||||
if( m->mixerChannel(i)->m_peakLeft >= opl/fallOff )
|
||||
if (m->mixerChannel(i)->m_peakLeft >= opl/fallOff)
|
||||
{
|
||||
m_mixerChannelViews[i]->m_fader->setPeak_L( m->mixerChannel(i)->m_peakLeft );
|
||||
m_mixerChannelViews[i]->m_fader->setPeak_L(m->mixerChannel(i)->m_peakLeft);
|
||||
// Set to -1 so later we'll know if this value has been refreshed yet.
|
||||
m->mixerChannel(i)->m_peakLeft = -1;
|
||||
}
|
||||
else if( m->mixerChannel(i)->m_peakLeft != -1 )
|
||||
else if (m->mixerChannel(i)->m_peakLeft != -1)
|
||||
{
|
||||
m_mixerChannelViews[i]->m_fader->setPeak_L( opl/fallOff );
|
||||
m_mixerChannelViews[i]->m_fader->setPeak_L(opl/fallOff);
|
||||
}
|
||||
|
||||
if( m->mixerChannel(i)->m_peakRight >= opr/fallOff )
|
||||
if (m->mixerChannel(i)->m_peakRight >= opr/fallOff)
|
||||
{
|
||||
m_mixerChannelViews[i]->m_fader->setPeak_R( m->mixerChannel(i)->m_peakRight );
|
||||
m_mixerChannelViews[i]->m_fader->setPeak_R(m->mixerChannel(i)->m_peakRight);
|
||||
// Set to -1 so later we'll know if this value has been refreshed yet.
|
||||
m->mixerChannel(i)->m_peakRight = -1;
|
||||
}
|
||||
else if( m->mixerChannel(i)->m_peakRight != -1 )
|
||||
else if (m->mixerChannel(i)->m_peakRight != -1)
|
||||
{
|
||||
m_mixerChannelViews[i]->m_fader->setPeak_R( opr/fallOff );
|
||||
m_mixerChannelViews[i]->m_fader->setPeak_R(opr/fallOff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "SampleTrackWindow.h"
|
||||
|
||||
#include <QCloseEvent>
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "GuiApplication.h"
|
||||
#include "Knob.h"
|
||||
#include "MainWindow.h"
|
||||
#include "MixerLineLcdSpinBox.h"
|
||||
#include "MixerChannelLcdSpinBox.h"
|
||||
#include "SampleTrackView.h"
|
||||
#include "Song.h"
|
||||
#include "SubWindow.h"
|
||||
@@ -133,7 +133,7 @@ SampleTrackWindow::SampleTrackWindow(SampleTrackView * tv) :
|
||||
|
||||
|
||||
// setup spinbox for selecting Mixer-channel
|
||||
m_mixerChannelNumber = new MixerLineLcdSpinBox(2, nullptr, tr("Mixer channel"), m_stv);
|
||||
m_mixerChannelNumber = new MixerChannelLcdSpinBox(2, nullptr, tr("Mixer channel"), m_stv);
|
||||
|
||||
basicControlsLayout->addWidget(m_mixerChannelNumber, 0, 3);
|
||||
basicControlsLayout->setAlignment(m_mixerChannelNumber, widgetAlignment);
|
||||
|
||||
@@ -2,51 +2,48 @@
|
||||
|
||||
#include "embed.h"
|
||||
#include "Mixer.h"
|
||||
#include "MixerLine.h"
|
||||
#include "MixerChannelView.h"
|
||||
#include "MixerView.h"
|
||||
|
||||
namespace lmms::gui
|
||||
{
|
||||
|
||||
SendButtonIndicator:: SendButtonIndicator( QWidget * _parent, MixerLine * _owner,
|
||||
MixerView * _mv) :
|
||||
QLabel( _parent ),
|
||||
m_parent( _owner ),
|
||||
m_mv( _mv )
|
||||
SendButtonIndicator:: SendButtonIndicator(QWidget* parent, MixerChannelView* owner, MixerView* mv) :
|
||||
QLabel(parent),
|
||||
m_parent(owner),
|
||||
m_mv(mv)
|
||||
{
|
||||
|
||||
// don't do any initializing yet, because the MixerView and MixerLine
|
||||
// don't do any initializing yet, because the MixerView and MixerChannelView
|
||||
// that were passed to this constructor are not done with their constructors
|
||||
// yet.
|
||||
setPixmap(m_qpmOff);
|
||||
}
|
||||
|
||||
void SendButtonIndicator::mousePressEvent( QMouseEvent * e )
|
||||
void SendButtonIndicator::mousePressEvent(QMouseEvent* e)
|
||||
{
|
||||
Mixer * mix = Engine::mixer();
|
||||
int from = m_mv->currentMixerLine()->channelIndex();
|
||||
Mixer* mix = Engine::mixer();
|
||||
int from = m_mv->currentMixerChannel()->channelIndex();
|
||||
int to = m_parent->channelIndex();
|
||||
FloatModel * sendModel = mix->channelSendModel(from, to);
|
||||
if( sendModel == nullptr )
|
||||
FloatModel* sendModel = mix->channelSendModel(from, to);
|
||||
if (sendModel == nullptr)
|
||||
{
|
||||
// not sending. create a mixer send.
|
||||
mix->createChannelSend( from, to );
|
||||
mix->createChannelSend(from, to);
|
||||
}
|
||||
else
|
||||
{
|
||||
// sending. delete the mixer send.
|
||||
mix->deleteChannelSend( from, to );
|
||||
mix->deleteChannelSend(from, to);
|
||||
}
|
||||
|
||||
m_mv->updateMixerLine(m_parent->channelIndex());
|
||||
m_mv->updateMixerChannel(m_parent->channelIndex());
|
||||
updateLightStatus();
|
||||
}
|
||||
|
||||
FloatModel * SendButtonIndicator::getSendModel()
|
||||
FloatModel* SendButtonIndicator::getSendModel()
|
||||
{
|
||||
Mixer * mix = Engine::mixer();
|
||||
return mix->channelSendModel(
|
||||
m_mv->currentMixerLine()->channelIndex(), m_parent->channelIndex());
|
||||
Mixer* mix = Engine::mixer();
|
||||
return mix->channelSendModel(m_mv->currentMixerChannel()->channelIndex(), m_parent->channelIndex());
|
||||
}
|
||||
|
||||
void SendButtonIndicator::updateLightStatus()
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#include "FileBrowser.h"
|
||||
#include "FileDialog.h"
|
||||
#include "GroupBox.h"
|
||||
#include "MixerLineLcdSpinBox.h"
|
||||
#include "MixerChannelLcdSpinBox.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "gui_templates.h"
|
||||
#include "Instrument.h"
|
||||
@@ -206,7 +206,7 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) :
|
||||
|
||||
|
||||
// setup spinbox for selecting Mixer-channel
|
||||
m_mixerChannelNumber = new MixerLineLcdSpinBox( 2, nullptr, tr( "Mixer channel" ), m_itv );
|
||||
m_mixerChannelNumber = new MixerChannelLcdSpinBox(2, nullptr, tr("Mixer channel"), m_itv);
|
||||
|
||||
basicControlsLayout->addWidget( m_mixerChannelNumber, 0, 6 );
|
||||
basicControlsLayout->setAlignment( m_mixerChannelNumber, widgetAlignment );
|
||||
|
||||
@@ -74,7 +74,7 @@ InstrumentTrackView::InstrumentTrackView( InstrumentTrack * _it, TrackContainerV
|
||||
connect(ConfigManager::inst(), SIGNAL(valueChanged(QString,QString,QString)),
|
||||
this, SLOT(handleConfigChange(QString,QString,QString)));
|
||||
|
||||
m_mixerChannelNumber = new MixerLineLcdSpinBox(2, getTrackSettingsWidget(), tr("Mixer channel"), this);
|
||||
m_mixerChannelNumber = new MixerChannelLcdSpinBox(2, getTrackSettingsWidget(), tr("Mixer channel"), this);
|
||||
m_mixerChannelNumber->show();
|
||||
|
||||
m_volumeKnob = new Knob( KnobType::Small17, getTrackSettingsWidget(),
|
||||
@@ -240,7 +240,7 @@ void InstrumentTrackView::assignMixerLine(int channelIndex)
|
||||
{
|
||||
model()->mixerChannelModel()->setValue( channelIndex );
|
||||
|
||||
getGUI()->mixerView()->setCurrentMixerLine( channelIndex );
|
||||
getGUI()->mixerView()->setCurrentMixerChannel(channelIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "SampleTrackView.h"
|
||||
|
||||
#include <QApplication>
|
||||
@@ -58,7 +58,7 @@ SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) :
|
||||
m_tlb->setIcon(embed::getIconPixmap("sample_track"));
|
||||
m_tlb->show();
|
||||
|
||||
m_mixerChannelNumber = new MixerLineLcdSpinBox(2, getTrackSettingsWidget(), tr("Mixer channel"), this);
|
||||
m_mixerChannelNumber = new MixerChannelLcdSpinBox(2, getTrackSettingsWidget(), tr("Mixer channel"), this);
|
||||
m_mixerChannelNumber->show();
|
||||
|
||||
m_volumeKnob = new Knob( KnobType::Small17, getTrackSettingsWidget(),
|
||||
@@ -241,7 +241,7 @@ void SampleTrackView::assignMixerLine(int channelIndex)
|
||||
{
|
||||
model()->mixerChannelModel()->setValue(channelIndex);
|
||||
|
||||
getGUI()->mixerView()->setCurrentMixerLine(channelIndex);
|
||||
getGUI()->mixerView()->setCurrentMixerChannel(channelIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* MixerLineLcdSpinBox.cpp - a specialization of LcdSpnBox for setting mixer channels
|
||||
* MixerChannelLcdSpinBox.cpp - a specialization of LcdSpnBox for setting mixer channels
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -22,7 +22,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "MixerLineLcdSpinBox.h"
|
||||
#include "MixerChannelLcdSpinBox.h"
|
||||
|
||||
#include "CaptionMenu.h"
|
||||
#include "MixerView.h"
|
||||
@@ -33,14 +33,14 @@ namespace lmms::gui
|
||||
{
|
||||
|
||||
|
||||
void MixerLineLcdSpinBox::setTrackView(TrackView * tv)
|
||||
void MixerChannelLcdSpinBox::setTrackView(TrackView * tv)
|
||||
{
|
||||
m_tv = tv;
|
||||
}
|
||||
|
||||
void MixerLineLcdSpinBox::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
void MixerChannelLcdSpinBox::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
{
|
||||
getGUI()->mixerView()->setCurrentMixerLine(model()->value());
|
||||
getGUI()->mixerView()->setCurrentMixerChannel(model()->value());
|
||||
|
||||
getGUI()->mixerView()->parentWidget()->show();
|
||||
getGUI()->mixerView()->show();// show Mixer window
|
||||
@@ -48,7 +48,7 @@ void MixerLineLcdSpinBox::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
//engine::getMixerView()->raise();
|
||||
}
|
||||
|
||||
void MixerLineLcdSpinBox::contextMenuEvent(QContextMenuEvent* event)
|
||||
void MixerChannelLcdSpinBox::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
// for the case, the user clicked right while pressing left mouse-
|
||||
// button, the context-menu appears while mouse-cursor is still hidden
|
||||
Reference in New Issue
Block a user