Skip to content

Commit

Permalink
Merge pull request LMMS#1987 from Wallacoloo/instrument-nav-btns
Browse files Browse the repository at this point in the history
Add instrument switcher buttons to InstrumentTrackWindow
  • Loading branch information
tresf committed May 2, 2015
2 parents 9888cb9 + 26fc16b commit 9f95c04
Show file tree
Hide file tree
Showing 9 changed files with 266 additions and 3 deletions.
6 changes: 5 additions & 1 deletion include/InstrumentTrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class InstrumentMidiIOView;
class InstrumentMiscView;
class Knob;
class LcdSpinBox;
class LeftRightNav;
class midiPortMenu;
class DataFile;
class PluginView;
Expand Down Expand Up @@ -416,16 +417,19 @@ public slots:

protected slots:
void saveSettingsBtnClicked();

void viewNextInstrument();
void viewPrevInstrument();

private:
virtual void modelChanged();
void viewInstrumentInDirection(int d);

InstrumentTrack * m_track;
InstrumentTrackView * m_itv;

// widgets on the top of an instrument-track-window
QLineEdit * m_nameLineEdit;
LeftRightNav * m_leftRightNav;
Knob * m_volumeKnob;
Knob * m_panningKnob;
Knob * m_pitchKnob;
Expand Down
49 changes: 49 additions & 0 deletions include/LeftRightNav.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* LeftRightNav.cpp - side-by-side left-facing and right-facing arrows for navigation (looks like < > )
*
* Copyright (c) 2015 Colin Wallace <wallacoloo/at/gmail.com>
*
* This file is part of LMMS - http://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.
*
*/

#ifndef LEFT_RIGHT_NAV_H
#define LEFT_RIGHT_NAV_H

#include "PixmapButton.h"

#include <QLayout>

class LeftRightNav : public QWidget
{
Q_OBJECT
public:
LeftRightNav(QWidget *parent=NULL);
PixmapButton* getLeftBtn();
PixmapButton* getRightBtn();
void setShortcuts(const QKeySequence &leftShortcut=Qt::Key_Minus, const QKeySequence &rightShortcut=Qt::Key_Plus);
signals:
void onNavLeft();
void onNavRight();
private:
QHBoxLayout m_layout;
PixmapButton m_leftBtn;
PixmapButton m_rightBtn;
};

#endif
1 change: 1 addition & 0 deletions include/PixmapButton.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class EXPORT PixmapButton : public AutomatableButton
void setActiveGraphic( const QPixmap & _pm );
void setInactiveGraphic( const QPixmap & _pm, bool _update = true );

QSize sizeHint() const;

signals:
void doubleClicked();
Expand Down
1 change: 1 addition & 0 deletions include/TrackContainerView.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class TrackContainerView : public QWidget, public ModelView,
void moveTrackView( TrackView * trackView, int indexTo );
void moveTrackViewUp( TrackView * trackView );
void moveTrackViewDown( TrackView * trackView );
void scrollToTrackView( TrackView * _tv );

// -- for usage by trackView only ---------------
TrackView * addTrackView( TrackView * _tv );
Expand Down
1 change: 1 addition & 0 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ SET(LMMS_SRCS
gui/widgets/InstrumentFunctionViews.cpp
gui/widgets/InstrumentMidiIOView.cpp
gui/widgets/InstrumentSoundShapingView.cpp
gui/widgets/LeftRightNav.cpp
gui/widgets/Knob.cpp
gui/widgets/LadspaControlView.cpp
gui/widgets/LcdSpinBox.cpp
Expand Down
23 changes: 23 additions & 0 deletions src/gui/TrackContainerView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*
*/

#include <algorithm>

#include <QApplication>
#include <QLayout>
Expand Down Expand Up @@ -200,6 +201,28 @@ void TrackContainerView::moveTrackViewDown( TrackView * trackView )
moveTrackView( trackView, index + 1 );
}

void TrackContainerView::scrollToTrackView( TrackView * _tv )
{
if (!m_trackViews.contains(_tv))
{
qWarning("TrackContainerView::scrollToTrackView: TrackView is not owned by this");
}
else
{
int currentScrollTop = m_scrollArea->verticalScrollBar()->value();
int scrollAreaHeight = m_scrollArea->size().height();
int trackViewTop = _tv->pos().y();
int trackViewBottom = trackViewTop + _tv->size().height();

// displayed_location = widget_location - currentScrollTop
// want to make sure that the widget top has displayed location > 0,
// and widget bottom < scrollAreaHeight
// trackViewTop - scrollY > 0 && trackViewBottom - scrollY < scrollAreaHeight
// therefore scrollY < trackViewTop && scrollY > trackViewBottom - scrollAreaHeight
int newScroll = std::max( trackViewBottom-scrollAreaHeight, std::min(currentScrollTop, trackViewTop) );
m_scrollArea->verticalScrollBar()->setValue(newScroll);
}
}



Expand Down
91 changes: 91 additions & 0 deletions src/gui/widgets/LeftRightNav.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* LeftRightNav.cpp - side-by-side left-facing and right-facing arrows for navigation (looks like < > )
*
* Copyright (c) 2015 Colin Wallace <wallacoloo/at/gmail.com>
*
* This file is part of LMMS - http://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 "LeftRightNav.h"
#include "ToolTip.h"
#include "embed.h"


LeftRightNav::LeftRightNav(QWidget *parent)
: QWidget(parent),
m_layout(this),
m_leftBtn(this, tr("Previous")),
m_rightBtn(this, tr("Next"))
{
m_layout.setContentsMargins(0, 0, 0, 0);
m_layout.setSpacing(2);

m_leftBtn.setCheckable(false);
m_rightBtn.setCheckable(false);

m_leftBtn.setCursor(Qt::PointingHandCursor);
m_rightBtn.setCursor(Qt::PointingHandCursor);

m_leftBtn.setActiveGraphic(embed::getIconPixmap(
"stepper-left-press"));
m_rightBtn.setActiveGraphic(embed::getIconPixmap(
"stepper-right-press" ));

m_leftBtn.setInactiveGraphic(embed::getIconPixmap(
"stepper-left" ));
m_rightBtn.setInactiveGraphic(embed::getIconPixmap(
"stepper-right"));

connect(&m_leftBtn, SIGNAL(clicked()), this,
SIGNAL(onNavLeft()));
connect(&m_rightBtn, SIGNAL(clicked()), this,
SIGNAL(onNavRight()));

ToolTip::add(&m_leftBtn, tr("Previous"));
ToolTip::add(&m_rightBtn, tr("Next"));

m_leftBtn.setWindowTitle(tr("Previous"));
m_rightBtn.setWindowTitle(tr("Next"));

// AutomatableButton's right click menu (contains irrelevant options like copying and pasting values)
m_leftBtn.setContextMenuPolicy(Qt::NoContextMenu);
m_rightBtn.setContextMenuPolicy(Qt::NoContextMenu);

m_layout.addWidget(&m_leftBtn);
m_layout.addWidget(&m_rightBtn);
}

PixmapButton* LeftRightNav::getLeftBtn()
{
return &m_leftBtn;
}
PixmapButton* LeftRightNav::getRightBtn()
{
return &m_rightBtn;
}

void LeftRightNav::setShortcuts(const QKeySequence &leftShortcut, const QKeySequence &rightShortcut)
{
m_leftBtn.setShortcut(leftShortcut);
m_rightBtn.setShortcut(rightShortcut);

ToolTip::add(&m_leftBtn, tr("Previous (%1)").arg(leftShortcut.toString()));
ToolTip::add(&m_rightBtn, tr("Next (%1)").arg(rightShortcut.toString()));
}
12 changes: 11 additions & 1 deletion src/gui/widgets/PixmapButton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,17 @@ void PixmapButton::setInactiveGraphic( const QPixmap & _pm, bool _update )
}
}


QSize PixmapButton::sizeHint() const
{
if( ( model() != NULL && model()->value() ) || m_pressed )
{
return m_activePixmap.size();
}
else
{
return m_inactivePixmap.size();
}
}



Expand Down
85 changes: 84 additions & 1 deletion src/tracks/InstrumentTrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include "Knob.h"
#include "LcdSpinBox.h"
#include "LedCheckbox.h"
#include "LeftRightNav.h"
#include "MainWindow.h"
#include "MidiClient.h"
#include "MidiPortMenu.h"
Expand All @@ -79,6 +80,7 @@
#include "StringPairDrag.h"
#include "TabWidget.h"
#include "ToolTip.h"
#include "TrackContainerView.h"
#include "TrackLabelButton.h"
#include "ValueBuffer.h"
#include "volume.h"
Expand Down Expand Up @@ -1279,13 +1281,36 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) :
generalSettingsLayout->setContentsMargins( 8, 18, 8, 8 );
generalSettingsLayout->setSpacing( 6 );

QWidget* nameAndChangeTrackWidget = new QWidget( generalSettingsWidget );
QHBoxLayout* nameAndChangeTrackLayout = new QHBoxLayout( nameAndChangeTrackWidget );
nameAndChangeTrackLayout->setContentsMargins( 0, 0, 0, 0 );
nameAndChangeTrackLayout->setSpacing( 2 );

// setup line edit for changing instrument track name
m_nameLineEdit = new QLineEdit;
m_nameLineEdit->setFont( pointSize<9>( m_nameLineEdit->font() ) );
connect( m_nameLineEdit, SIGNAL( textChanged( const QString & ) ),
this, SLOT( textChanged( const QString & ) ) );

generalSettingsLayout->addWidget( m_nameLineEdit );
m_nameLineEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred));
nameAndChangeTrackLayout->addWidget(m_nameLineEdit);


// set up left/right arrows for changing instrument
m_leftRightNav = new LeftRightNav(this);
connect( m_leftRightNav, SIGNAL( onNavLeft() ), this,
SLOT( viewPrevInstrument() ) );
connect( m_leftRightNav, SIGNAL( onNavRight() ), this,
SLOT( viewNextInstrument() ) );
m_leftRightNav->setWhatsThis(
tr( "Use these controls to view and edit the next/previous track in the song editor." ) );
// m_leftRightNav->setShortcuts();
nameAndChangeTrackLayout->addWidget(m_leftRightNav);


generalSettingsLayout->addWidget( nameAndChangeTrackWidget );



QHBoxLayout* basicControlsLayout = new QHBoxLayout;
basicControlsLayout->setSpacing( 3 );
Expand Down Expand Up @@ -1692,3 +1717,61 @@ void InstrumentTrackWindow::loadSettings( const QDomElement& thisElement )
m_itv->m_tlb->setChecked( true );
}
}

void InstrumentTrackWindow::viewInstrumentInDirection(int d)
{
// helper routine for viewNextInstrument, viewPrevInstrument
// d=-1 to view the previous instrument,
// d=+1 to view the next instrument

const QList<TrackView *> &trackViews = m_itv->trackContainerView()->trackViews();
int idxOfMe = trackViews.indexOf(m_itv);

// search for the next InstrumentTrackView (i.e. skip AutomationViews, etc)
// sometimes, the next InstrumentTrackView may already be open, in which case
// replace our window contents with the *next* closed Instrument Track and
// give focus to the InstrumentTrackView we skipped.
int idxOfNext = idxOfMe;
InstrumentTrackView *newView = nullptr;
InstrumentTrackView *bringToFront = nullptr;
do
{
idxOfNext = (idxOfNext + d + trackViews.size()) % trackViews.size();
newView = dynamic_cast<InstrumentTrackView*>(trackViews[idxOfNext]);
// the window that should be brought to focus is the FIRST InstrumentTrackView that comes after us
if (bringToFront == nullptr && newView != nullptr)
{
bringToFront = newView;
}
// if the next instrument doesn't have an active window, then exit loop & load that one into our window.
if (newView != nullptr && !newView->m_tlb->isChecked())
{
break;
}
} while (idxOfNext != idxOfMe);

// avoid reloading the window if there is only one instrument, as that will just change the active tab
if (idxOfNext != idxOfMe)
{
// save current window pos and then hide the window by unchecking its button in the track list
QPoint curPos = parentWidget()->pos();
m_itv->m_tlb->setChecked(false);

// enable the new window by checking its track list button & moving it to where our window just was
newView->m_tlb->setChecked(true);
newView->getInstrumentTrackWindow()->parentWidget()->move(curPos);

// scroll the SongEditor/BB-editor to make sure the new trackview label is visible
bringToFront->trackContainerView()->scrollToTrackView(bringToFront);
}
bringToFront->getInstrumentTrackWindow()->setFocus();
}

void InstrumentTrackWindow::viewNextInstrument()
{
viewInstrumentInDirection(+1);
}
void InstrumentTrackWindow::viewPrevInstrument()
{
viewInstrumentInDirection(-1);
}

0 comments on commit 9f95c04

Please sign in to comment.