committed by
GitHub
parent
ddf69feebc
commit
b701e82e3b
@@ -30,7 +30,7 @@
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
#include "Track.h"
|
||||
#include "TrackContentObject.h"
|
||||
|
||||
|
||||
class AutomationTrack;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "AutomationPattern.h"
|
||||
#include "Song.h"
|
||||
#include "SongEditor.h"
|
||||
#include "Track.h"
|
||||
#include "TrackContentObjectView.h"
|
||||
|
||||
|
||||
class AutomationPatternView : public TrackContentObjectView
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define AUTOMATION_TRACK_H
|
||||
|
||||
#include "Track.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
|
||||
class AutomationTrack : public Track
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#ifndef BB_EDITOR_H
|
||||
#define BB_EDITOR_H
|
||||
|
||||
|
||||
#include "Editor.h"
|
||||
#include "TrackContainerView.h"
|
||||
|
||||
|
||||
@@ -31,7 +31,9 @@
|
||||
#include <QtCore/QMap>
|
||||
#include <QStaticText>
|
||||
|
||||
#include "TrackContentObjectView.h"
|
||||
#include "Track.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
class TrackLabelButton;
|
||||
class TrackContainer;
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "Pitch.h"
|
||||
#include "Plugin.h"
|
||||
#include "Track.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -34,16 +34,10 @@
|
||||
|
||||
|
||||
#include "Note.h"
|
||||
#include "Track.h"
|
||||
#include "TrackContentObjectView.h"
|
||||
|
||||
|
||||
class QAction;
|
||||
class QProgressBar;
|
||||
class QPushButton;
|
||||
|
||||
class InstrumentTrack;
|
||||
class SampleBuffer;
|
||||
|
||||
|
||||
|
||||
class LMMS_EXPORT Pattern : public TrackContentObject
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "NotePlayHandle.h"
|
||||
|
||||
|
||||
class DataFile;
|
||||
class InstrumentTrack;
|
||||
class PreviewTrackContainer;
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include "FxMixer.h"
|
||||
#include "FxLineLcdSpinBox.h"
|
||||
#include "Track.h"
|
||||
#include "TrackContentObjectView.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
class EffectRackView;
|
||||
class Knob;
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <QtCore/QSharedMemory>
|
||||
#include <QtCore/QVector>
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
|
||||
#include "TrackContainer.h"
|
||||
#include "Controller.h"
|
||||
|
||||
627
include/Track.h
627
include/Track.h
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Track.h - declaration of classes concerning tracks -> necessary for all
|
||||
* track-like objects (beat/bassline, sample-track...)
|
||||
* Track.h - declaration of Track class
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -26,43 +25,22 @@
|
||||
#ifndef TRACK_H
|
||||
#define TRACK_H
|
||||
|
||||
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QList>
|
||||
#include <QWidget>
|
||||
#include <QSize>
|
||||
#include <QColor>
|
||||
#include <QMimeData>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "TimePos.h"
|
||||
#include "Rubberband.h"
|
||||
#include "JournallingObject.h"
|
||||
#include "AutomatableModel.h"
|
||||
#include "ModelView.h"
|
||||
#include "DataFile.h"
|
||||
#include "FadeButton.h"
|
||||
#include "JournallingObject.h"
|
||||
#include "lmms_basics.h"
|
||||
|
||||
|
||||
class QMenu;
|
||||
class QPushButton;
|
||||
|
||||
class PixmapButton;
|
||||
class TextFloat;
|
||||
class Track;
|
||||
class TrackContentObjectView;
|
||||
class TimePos;
|
||||
class TrackContainer;
|
||||
class TrackContainerView;
|
||||
class TrackContentWidget;
|
||||
class TrackContentObject;
|
||||
class TrackView;
|
||||
|
||||
|
||||
const int DEFAULT_SETTINGS_WIDGET_WIDTH = 224;
|
||||
const int TRACK_OP_WIDTH = 78;
|
||||
// This shaves 150-ish pixels off track buttons,
|
||||
// ruled from config: ui.compacttrackbuttons
|
||||
const int DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT = 96;
|
||||
const int TRACK_OP_WIDTH_COMPACT = 62;
|
||||
|
||||
/*! The minimum track height in pixels
|
||||
*
|
||||
* Tracks can be resized by shift-dragging anywhere inside the track
|
||||
@@ -71,483 +49,10 @@ const int TRACK_OP_WIDTH_COMPACT = 62;
|
||||
const int MINIMAL_TRACK_HEIGHT = 32;
|
||||
const int DEFAULT_TRACK_HEIGHT = 32;
|
||||
|
||||
const int TCO_BORDER_WIDTH = 2;
|
||||
|
||||
char const *const FILENAME_FILTER = "[\\0000-\x1f\"*/:<>?\\\\|\x7f]";
|
||||
|
||||
|
||||
class LMMS_EXPORT TrackContentObject : public Model, public JournallingObject
|
||||
{
|
||||
Q_OBJECT
|
||||
MM_OPERATORS
|
||||
mapPropertyFromModel(bool,isMuted,setMuted,m_mutedModel);
|
||||
mapPropertyFromModel(bool,isSolo,setSolo,m_soloModel);
|
||||
public:
|
||||
TrackContentObject( Track * track );
|
||||
virtual ~TrackContentObject();
|
||||
|
||||
inline Track * getTrack() const
|
||||
{
|
||||
return m_track;
|
||||
}
|
||||
|
||||
inline const QString & name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
inline void setName( const QString & name )
|
||||
{
|
||||
m_name = name;
|
||||
emit dataChanged();
|
||||
}
|
||||
|
||||
QString displayName() const override
|
||||
{
|
||||
return name();
|
||||
}
|
||||
|
||||
|
||||
inline const TimePos & startPosition() const
|
||||
{
|
||||
return m_startPosition;
|
||||
}
|
||||
|
||||
inline TimePos endPosition() const
|
||||
{
|
||||
const int sp = m_startPosition;
|
||||
return sp + m_length;
|
||||
}
|
||||
|
||||
inline const TimePos & length() const
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
|
||||
inline void setAutoResize( const bool r )
|
||||
{
|
||||
m_autoResize = r;
|
||||
}
|
||||
|
||||
inline const bool getAutoResize() const
|
||||
{
|
||||
return m_autoResize;
|
||||
}
|
||||
|
||||
QColor color() const
|
||||
{
|
||||
return m_color;
|
||||
}
|
||||
|
||||
void setColor( const QColor & c )
|
||||
{
|
||||
m_color = c;
|
||||
}
|
||||
|
||||
bool hasColor();
|
||||
|
||||
void useCustomClipColor( bool b );
|
||||
|
||||
bool usesCustomClipColor()
|
||||
{
|
||||
return m_useCustomClipColor;
|
||||
}
|
||||
|
||||
virtual void movePosition( const TimePos & pos );
|
||||
virtual void changeLength( const TimePos & length );
|
||||
|
||||
virtual TrackContentObjectView * createView( TrackView * tv ) = 0;
|
||||
|
||||
inline void selectViewOnCreate( bool select )
|
||||
{
|
||||
m_selectViewOnCreate = select;
|
||||
}
|
||||
|
||||
inline bool getSelectViewOnCreate()
|
||||
{
|
||||
return m_selectViewOnCreate;
|
||||
}
|
||||
|
||||
/// Returns true if and only if a->startPosition() < b->startPosition()
|
||||
static bool comparePosition(const TrackContentObject* a, const TrackContentObject* b);
|
||||
|
||||
TimePos startTimeOffset() const;
|
||||
void setStartTimeOffset( const TimePos &startTimeOffset );
|
||||
|
||||
void updateColor();
|
||||
|
||||
// Will copy the state of a TCO to another TCO
|
||||
static void copyStateTo( TrackContentObject *src, TrackContentObject *dst );
|
||||
|
||||
public slots:
|
||||
void toggleMute();
|
||||
|
||||
|
||||
signals:
|
||||
void lengthChanged();
|
||||
void positionChanged();
|
||||
void destroyedTCO();
|
||||
void trackColorChanged();
|
||||
|
||||
|
||||
private:
|
||||
enum Actions
|
||||
{
|
||||
NoAction,
|
||||
Move,
|
||||
Resize
|
||||
} ;
|
||||
|
||||
Track * m_track;
|
||||
QString m_name;
|
||||
|
||||
TimePos m_startPosition;
|
||||
TimePos m_length;
|
||||
TimePos m_startTimeOffset;
|
||||
|
||||
BoolModel m_mutedModel;
|
||||
BoolModel m_soloModel;
|
||||
bool m_autoResize;
|
||||
|
||||
bool m_selectViewOnCreate;
|
||||
|
||||
QColor m_color;
|
||||
bool m_useCustomClipColor;
|
||||
|
||||
friend class TrackContentObjectView;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
class TrackContentObjectView : public selectableObject, public ModelView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
// theming qproperties
|
||||
Q_PROPERTY( QColor mutedColor READ mutedColor WRITE setMutedColor )
|
||||
Q_PROPERTY( QColor mutedBackgroundColor READ mutedBackgroundColor WRITE setMutedBackgroundColor )
|
||||
Q_PROPERTY( QColor selectedColor READ selectedColor WRITE setSelectedColor )
|
||||
Q_PROPERTY( QColor textColor READ textColor WRITE setTextColor )
|
||||
Q_PROPERTY( QColor textBackgroundColor READ textBackgroundColor WRITE setTextBackgroundColor )
|
||||
Q_PROPERTY( QColor textShadowColor READ textShadowColor WRITE setTextShadowColor )
|
||||
Q_PROPERTY( QColor BBPatternBackground READ BBPatternBackground WRITE setBBPatternBackground )
|
||||
Q_PROPERTY( bool gradient READ gradient WRITE setGradient )
|
||||
// We have to use a QSize here because using QPoint isn't supported.
|
||||
// width -> x, height -> y
|
||||
Q_PROPERTY( QSize mouseHotspotHand WRITE setMouseHotspotHand )
|
||||
|
||||
public:
|
||||
TrackContentObjectView( TrackContentObject * tco, TrackView * tv );
|
||||
virtual ~TrackContentObjectView();
|
||||
|
||||
bool fixedTCOs();
|
||||
|
||||
inline TrackContentObject * getTrackContentObject()
|
||||
{
|
||||
return m_tco;
|
||||
}
|
||||
|
||||
inline TrackView * getTrackView()
|
||||
{
|
||||
return m_trackView;
|
||||
}
|
||||
|
||||
// qproperty access func
|
||||
QColor mutedColor() const;
|
||||
QColor mutedBackgroundColor() const;
|
||||
QColor selectedColor() const;
|
||||
QColor textColor() const;
|
||||
QColor textBackgroundColor() const;
|
||||
QColor textShadowColor() const;
|
||||
QColor BBPatternBackground() const;
|
||||
bool gradient() const;
|
||||
void setMutedColor( const QColor & c );
|
||||
void setMutedBackgroundColor( const QColor & c );
|
||||
void setSelectedColor( const QColor & c );
|
||||
void setTextColor( const QColor & c );
|
||||
void setTextBackgroundColor( const QColor & c );
|
||||
void setTextShadowColor( const QColor & c );
|
||||
void setBBPatternBackground( const QColor & c );
|
||||
void setGradient( const bool & b );
|
||||
void setMouseHotspotHand(const QSize & s);
|
||||
|
||||
// access needsUpdate member variable
|
||||
bool needsUpdate();
|
||||
void setNeedsUpdate( bool b );
|
||||
|
||||
// Method to get a QVector of TCOs to be affected by a context menu action
|
||||
QVector<TrackContentObjectView *> getClickedTCOs();
|
||||
|
||||
// Methods to remove, copy, cut, paste and mute a QVector of TCO views
|
||||
void copy( QVector<TrackContentObjectView *> tcovs );
|
||||
void cut( QVector<TrackContentObjectView *> tcovs );
|
||||
void paste();
|
||||
// remove and toggleMute are static because they don't depend
|
||||
// being called from a particular TCO view, but can be called anywhere as long
|
||||
// as a valid TCO view list is given, while copy/cut require an instance for
|
||||
// some metadata to be written to the clipboard.
|
||||
static void remove( QVector<TrackContentObjectView *> tcovs );
|
||||
static void toggleMute( QVector<TrackContentObjectView *> tcovs );
|
||||
|
||||
QColor getColorForDisplay( QColor );
|
||||
|
||||
public slots:
|
||||
virtual bool close();
|
||||
void remove();
|
||||
void update() override;
|
||||
|
||||
void changeClipColor();
|
||||
void useTrackColor();
|
||||
|
||||
protected:
|
||||
enum ContextMenuAction
|
||||
{
|
||||
Remove,
|
||||
Cut,
|
||||
Copy,
|
||||
Paste,
|
||||
Mute
|
||||
};
|
||||
|
||||
virtual void constructContextMenu( QMenu * )
|
||||
{
|
||||
}
|
||||
|
||||
void contextMenuEvent( QContextMenuEvent * cme ) override;
|
||||
void contextMenuAction( ContextMenuAction action );
|
||||
void dragEnterEvent( QDragEnterEvent * dee ) override;
|
||||
void dropEvent( QDropEvent * de ) override;
|
||||
void leaveEvent( QEvent * e ) override;
|
||||
void mousePressEvent( QMouseEvent * me ) override;
|
||||
void mouseMoveEvent( QMouseEvent * me ) override;
|
||||
void mouseReleaseEvent( QMouseEvent * me ) override;
|
||||
void resizeEvent( QResizeEvent * re ) override
|
||||
{
|
||||
m_needsUpdate = true;
|
||||
selectableObject::resizeEvent( re );
|
||||
}
|
||||
|
||||
float pixelsPerBar();
|
||||
|
||||
|
||||
DataFile createTCODataFiles(const QVector<TrackContentObjectView *> & tcos) const;
|
||||
|
||||
virtual void paintTextLabel(QString const & text, QPainter & painter);
|
||||
|
||||
|
||||
protected slots:
|
||||
void updateLength();
|
||||
void updatePosition();
|
||||
|
||||
|
||||
private:
|
||||
enum Actions
|
||||
{
|
||||
NoAction,
|
||||
Move,
|
||||
MoveSelection,
|
||||
Resize,
|
||||
ResizeLeft,
|
||||
CopySelection,
|
||||
ToggleSelected
|
||||
} ;
|
||||
|
||||
static TextFloat * s_textFloat;
|
||||
|
||||
TrackContentObject * m_tco;
|
||||
TrackView * m_trackView;
|
||||
Actions m_action;
|
||||
QPoint m_initialMousePos;
|
||||
QPoint m_initialMouseGlobalPos;
|
||||
TimePos m_initialTCOPos;
|
||||
TimePos m_initialTCOEnd;
|
||||
QVector<TimePos> m_initialOffsets;
|
||||
|
||||
TextFloat * m_hint;
|
||||
|
||||
// qproperty fields
|
||||
QColor m_mutedColor;
|
||||
QColor m_mutedBackgroundColor;
|
||||
QColor m_selectedColor;
|
||||
QColor m_textColor;
|
||||
QColor m_textBackgroundColor;
|
||||
QColor m_textShadowColor;
|
||||
QColor m_BBPatternBackground;
|
||||
bool m_gradient;
|
||||
QSize m_mouseHotspotHand; // QSize must be used because QPoint isn't supported by property system
|
||||
bool m_cursorSetYet;
|
||||
|
||||
bool m_needsUpdate;
|
||||
inline void setInitialPos( QPoint pos )
|
||||
{
|
||||
m_initialMousePos = pos;
|
||||
m_initialMouseGlobalPos = mapToGlobal( pos );
|
||||
m_initialTCOPos = m_tco->startPosition();
|
||||
m_initialTCOEnd = m_initialTCOPos + m_tco->length();
|
||||
}
|
||||
void setInitialOffsets();
|
||||
|
||||
bool mouseMovedDistance( QMouseEvent * me, int distance );
|
||||
TimePos draggedTCOPos( QMouseEvent * me );
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TrackContentWidget : public QWidget, public JournallingObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
// qproperties for track background gradients
|
||||
Q_PROPERTY( QBrush darkerColor READ darkerColor WRITE setDarkerColor )
|
||||
Q_PROPERTY( QBrush lighterColor READ lighterColor WRITE setLighterColor )
|
||||
Q_PROPERTY( QBrush gridColor READ gridColor WRITE setGridColor )
|
||||
Q_PROPERTY( QBrush embossColor READ embossColor WRITE setEmbossColor )
|
||||
|
||||
public:
|
||||
TrackContentWidget( TrackView * parent );
|
||||
virtual ~TrackContentWidget();
|
||||
|
||||
/*! \brief Updates the background tile pixmap. */
|
||||
void updateBackground();
|
||||
|
||||
void addTCOView( TrackContentObjectView * tcov );
|
||||
void removeTCOView( TrackContentObjectView * tcov );
|
||||
void removeTCOView( int tcoNum )
|
||||
{
|
||||
if( tcoNum >= 0 && tcoNum < m_tcoViews.size() )
|
||||
{
|
||||
removeTCOView( m_tcoViews[tcoNum] );
|
||||
}
|
||||
}
|
||||
|
||||
bool canPasteSelection( TimePos tcoPos, const QDropEvent *de );
|
||||
bool canPasteSelection( TimePos tcoPos, const QMimeData *md, bool allowSameBar = false );
|
||||
bool pasteSelection( TimePos tcoPos, QDropEvent * de );
|
||||
bool pasteSelection( TimePos tcoPos, const QMimeData * md, bool skipSafetyCheck = false );
|
||||
|
||||
TimePos endPosition( const TimePos & posStart );
|
||||
|
||||
// qproperty access methods
|
||||
|
||||
QBrush darkerColor() const;
|
||||
QBrush lighterColor() const;
|
||||
QBrush gridColor() const;
|
||||
QBrush embossColor() const;
|
||||
|
||||
void setDarkerColor( const QBrush & c );
|
||||
void setLighterColor( const QBrush & c );
|
||||
void setGridColor( const QBrush & c );
|
||||
void setEmbossColor( const QBrush & c);
|
||||
|
||||
public slots:
|
||||
void update();
|
||||
void changePosition( const TimePos & newPos = TimePos( -1 ) );
|
||||
|
||||
protected:
|
||||
enum ContextMenuAction
|
||||
{
|
||||
Paste
|
||||
};
|
||||
|
||||
void contextMenuEvent( QContextMenuEvent * cme ) override;
|
||||
void contextMenuAction( QContextMenuEvent * cme, ContextMenuAction action );
|
||||
void dragEnterEvent( QDragEnterEvent * dee ) override;
|
||||
void dropEvent( QDropEvent * de ) override;
|
||||
void mousePressEvent( QMouseEvent * me ) override;
|
||||
void paintEvent( QPaintEvent * pe ) override;
|
||||
void resizeEvent( QResizeEvent * re ) override;
|
||||
|
||||
QString nodeName() const override
|
||||
{
|
||||
return "trackcontentwidget";
|
||||
}
|
||||
|
||||
void saveSettings( QDomDocument& doc, QDomElement& element ) override
|
||||
{
|
||||
Q_UNUSED(doc)
|
||||
Q_UNUSED(element)
|
||||
}
|
||||
|
||||
void loadSettings( const QDomElement& element ) override
|
||||
{
|
||||
Q_UNUSED(element)
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
Track * getTrack();
|
||||
TimePos getPosition( int mouseX );
|
||||
|
||||
TrackView * m_trackView;
|
||||
|
||||
typedef QVector<TrackContentObjectView *> tcoViewVector;
|
||||
tcoViewVector m_tcoViews;
|
||||
|
||||
QPixmap m_background;
|
||||
|
||||
// qproperty fields
|
||||
QBrush m_darkerColor;
|
||||
QBrush m_lighterColor;
|
||||
QBrush m_gridColor;
|
||||
QBrush m_embossColor;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TrackOperationsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TrackOperationsWidget( TrackView * parent );
|
||||
~TrackOperationsWidget();
|
||||
|
||||
|
||||
protected:
|
||||
void mousePressEvent( QMouseEvent * me ) override;
|
||||
void paintEvent( QPaintEvent * pe ) override;
|
||||
|
||||
|
||||
private slots:
|
||||
void cloneTrack();
|
||||
void removeTrack();
|
||||
void updateMenu();
|
||||
void changeTrackColor();
|
||||
void randomTrackColor();
|
||||
void resetTrackColor();
|
||||
void useTrackColor();
|
||||
void toggleRecording(bool on);
|
||||
void recordingOn();
|
||||
void recordingOff();
|
||||
void clearTrack();
|
||||
|
||||
private:
|
||||
TrackView * m_trackView;
|
||||
|
||||
QPushButton * m_trackOps;
|
||||
PixmapButton * m_muteBtn;
|
||||
PixmapButton * m_soloBtn;
|
||||
|
||||
|
||||
friend class TrackView;
|
||||
|
||||
signals:
|
||||
void trackRemovalScheduled( TrackView * t );
|
||||
void colorChanged( QColor & c );
|
||||
void colorParented();
|
||||
void colorReset();
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// base-class for all tracks
|
||||
//! Base-class for all tracks
|
||||
class LMMS_EXPORT Track : public Model, public JournallingObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -729,122 +234,4 @@ signals:
|
||||
|
||||
|
||||
|
||||
|
||||
class TrackView : public QWidget, public ModelView, public JournallingObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TrackView( Track * _track, TrackContainerView* tcv );
|
||||
virtual ~TrackView();
|
||||
|
||||
inline const Track * getTrack() const
|
||||
{
|
||||
return m_track;
|
||||
}
|
||||
|
||||
inline Track * getTrack()
|
||||
{
|
||||
return m_track;
|
||||
}
|
||||
|
||||
inline TrackContainerView* trackContainerView()
|
||||
{
|
||||
return m_trackContainerView;
|
||||
}
|
||||
|
||||
inline TrackOperationsWidget * getTrackOperationsWidget()
|
||||
{
|
||||
return &m_trackOperationsWidget;
|
||||
}
|
||||
|
||||
inline QWidget * getTrackSettingsWidget()
|
||||
{
|
||||
return &m_trackSettingsWidget;
|
||||
}
|
||||
|
||||
inline TrackContentWidget * getTrackContentWidget()
|
||||
{
|
||||
return &m_trackContentWidget;
|
||||
}
|
||||
|
||||
bool isMovingTrack() const
|
||||
{
|
||||
return m_action == MoveTrack;
|
||||
}
|
||||
|
||||
virtual void update();
|
||||
|
||||
// Create a menu for assigning/creating channels for this track
|
||||
// Currently instrument track and sample track supports it
|
||||
virtual QMenu * createFxMenu(QString title, QString newFxLabel);
|
||||
|
||||
|
||||
public slots:
|
||||
virtual bool close();
|
||||
|
||||
|
||||
protected:
|
||||
void modelChanged() override;
|
||||
|
||||
void saveSettings( QDomDocument& doc, QDomElement& element ) override
|
||||
{
|
||||
Q_UNUSED(doc)
|
||||
Q_UNUSED(element)
|
||||
}
|
||||
|
||||
void loadSettings( const QDomElement& element ) override
|
||||
{
|
||||
Q_UNUSED(element)
|
||||
}
|
||||
|
||||
QString nodeName() const override
|
||||
{
|
||||
return "trackview";
|
||||
}
|
||||
|
||||
|
||||
void dragEnterEvent( QDragEnterEvent * dee ) override;
|
||||
void dropEvent( QDropEvent * de ) override;
|
||||
void mousePressEvent( QMouseEvent * me ) override;
|
||||
void mouseMoveEvent( QMouseEvent * me ) override;
|
||||
void mouseReleaseEvent( QMouseEvent * me ) override;
|
||||
void paintEvent( QPaintEvent * pe ) override;
|
||||
void resizeEvent( QResizeEvent * re ) override;
|
||||
|
||||
|
||||
private:
|
||||
enum Actions
|
||||
{
|
||||
NoAction,
|
||||
MoveTrack,
|
||||
ResizeTrack
|
||||
} ;
|
||||
|
||||
Track * m_track;
|
||||
TrackContainerView * m_trackContainerView;
|
||||
|
||||
TrackOperationsWidget m_trackOperationsWidget;
|
||||
QWidget m_trackSettingsWidget;
|
||||
TrackContentWidget m_trackContentWidget;
|
||||
|
||||
Actions m_action;
|
||||
|
||||
virtual FadeButton * getActivityIndicator()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void setIndicatorMute(FadeButton* indicator, bool muted);
|
||||
|
||||
friend class TrackLabelButton;
|
||||
|
||||
|
||||
private slots:
|
||||
void createTCOView( TrackContentObject * tco );
|
||||
void muteChanged();
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,12 +31,15 @@
|
||||
#include <QWidget>
|
||||
#include <QThread>
|
||||
|
||||
#include "Track.h"
|
||||
#include "JournallingObject.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "ModelView.h"
|
||||
#include "Rubberband.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
|
||||
class QVBoxLayout;
|
||||
|
||||
class InstrumentTrack;
|
||||
class TrackContainer;
|
||||
|
||||
|
||||
|
||||
183
include/TrackContentObject.h
Normal file
183
include/TrackContentObject.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* TrackConteintObject.h - declaration of TrackContentObject class
|
||||
*
|
||||
* Copyright (c) 2004-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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TRACK_CONTENT_OBJECT_H
|
||||
#define TRACK_CONTENT_OBJECT_H
|
||||
|
||||
#include <QColor>
|
||||
|
||||
#include "AutomatableModel.h"
|
||||
#include "lmms_basics.h"
|
||||
|
||||
|
||||
class Track;
|
||||
class TrackContentObjectView;
|
||||
class TrackContainer;
|
||||
class TrackView;
|
||||
|
||||
|
||||
class LMMS_EXPORT TrackContentObject : public Model, public JournallingObject
|
||||
{
|
||||
Q_OBJECT
|
||||
MM_OPERATORS
|
||||
mapPropertyFromModel(bool,isMuted,setMuted,m_mutedModel);
|
||||
mapPropertyFromModel(bool,isSolo,setSolo,m_soloModel);
|
||||
public:
|
||||
TrackContentObject( Track * track );
|
||||
virtual ~TrackContentObject();
|
||||
|
||||
inline Track * getTrack() const
|
||||
{
|
||||
return m_track;
|
||||
}
|
||||
|
||||
inline const QString & name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
inline void setName( const QString & name )
|
||||
{
|
||||
m_name = name;
|
||||
emit dataChanged();
|
||||
}
|
||||
|
||||
QString displayName() const override
|
||||
{
|
||||
return name();
|
||||
}
|
||||
|
||||
|
||||
inline const TimePos & startPosition() const
|
||||
{
|
||||
return m_startPosition;
|
||||
}
|
||||
|
||||
inline TimePos endPosition() const
|
||||
{
|
||||
const int sp = m_startPosition;
|
||||
return sp + m_length;
|
||||
}
|
||||
|
||||
inline const TimePos & length() const
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
|
||||
inline void setAutoResize( const bool r )
|
||||
{
|
||||
m_autoResize = r;
|
||||
}
|
||||
|
||||
inline const bool getAutoResize() const
|
||||
{
|
||||
return m_autoResize;
|
||||
}
|
||||
|
||||
QColor color() const
|
||||
{
|
||||
return m_color;
|
||||
}
|
||||
|
||||
void setColor( const QColor & c )
|
||||
{
|
||||
m_color = c;
|
||||
}
|
||||
|
||||
bool hasColor();
|
||||
|
||||
void useCustomClipColor( bool b );
|
||||
|
||||
bool usesCustomClipColor()
|
||||
{
|
||||
return m_useCustomClipColor;
|
||||
}
|
||||
|
||||
virtual void movePosition( const TimePos & pos );
|
||||
virtual void changeLength( const TimePos & length );
|
||||
|
||||
virtual TrackContentObjectView * createView( TrackView * tv ) = 0;
|
||||
|
||||
inline void selectViewOnCreate( bool select )
|
||||
{
|
||||
m_selectViewOnCreate = select;
|
||||
}
|
||||
|
||||
inline bool getSelectViewOnCreate()
|
||||
{
|
||||
return m_selectViewOnCreate;
|
||||
}
|
||||
|
||||
/// Returns true if and only if a->startPosition() < b->startPosition()
|
||||
static bool comparePosition(const TrackContentObject* a, const TrackContentObject* b);
|
||||
|
||||
TimePos startTimeOffset() const;
|
||||
void setStartTimeOffset( const TimePos &startTimeOffset );
|
||||
|
||||
void updateColor();
|
||||
|
||||
// Will copy the state of a TCO to another TCO
|
||||
static void copyStateTo( TrackContentObject *src, TrackContentObject *dst );
|
||||
|
||||
public slots:
|
||||
void toggleMute();
|
||||
|
||||
|
||||
signals:
|
||||
void lengthChanged();
|
||||
void positionChanged();
|
||||
void destroyedTCO();
|
||||
void trackColorChanged();
|
||||
|
||||
|
||||
private:
|
||||
enum Actions
|
||||
{
|
||||
NoAction,
|
||||
Move,
|
||||
Resize
|
||||
} ;
|
||||
|
||||
Track * m_track;
|
||||
QString m_name;
|
||||
|
||||
TimePos m_startPosition;
|
||||
TimePos m_length;
|
||||
TimePos m_startTimeOffset;
|
||||
|
||||
BoolModel m_mutedModel;
|
||||
BoolModel m_soloModel;
|
||||
bool m_autoResize;
|
||||
|
||||
bool m_selectViewOnCreate;
|
||||
|
||||
QColor m_color;
|
||||
bool m_useCustomClipColor;
|
||||
|
||||
friend class TrackContentObjectView;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
218
include/TrackContentObjectView.h
Normal file
218
include/TrackContentObjectView.h
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* TrackContentObjectView.h - declaration of TrackContentObjectView class
|
||||
*
|
||||
* Copyright (c) 2004-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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TRACK_CONTENT_OBJECT_VIEW_H
|
||||
#define TRACK_CONTENT_OBJECT_VIEW_H
|
||||
|
||||
|
||||
#include <QtCore/QVector>
|
||||
|
||||
#include "ModelView.h"
|
||||
#include "Rubberband.h"
|
||||
#include "TrackContentObject.h"
|
||||
|
||||
|
||||
class QMenu;
|
||||
class QContextMenuEvent;
|
||||
|
||||
class DataFile;
|
||||
class TextFloat;
|
||||
class TrackContentObject;
|
||||
class TrackView;
|
||||
|
||||
|
||||
class TrackContentObjectView : public selectableObject, public ModelView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
// theming qproperties
|
||||
Q_PROPERTY( QColor mutedColor READ mutedColor WRITE setMutedColor )
|
||||
Q_PROPERTY( QColor mutedBackgroundColor READ mutedBackgroundColor WRITE setMutedBackgroundColor )
|
||||
Q_PROPERTY( QColor selectedColor READ selectedColor WRITE setSelectedColor )
|
||||
Q_PROPERTY( QColor textColor READ textColor WRITE setTextColor )
|
||||
Q_PROPERTY( QColor textBackgroundColor READ textBackgroundColor WRITE setTextBackgroundColor )
|
||||
Q_PROPERTY( QColor textShadowColor READ textShadowColor WRITE setTextShadowColor )
|
||||
Q_PROPERTY( QColor BBPatternBackground READ BBPatternBackground WRITE setBBPatternBackground )
|
||||
Q_PROPERTY( bool gradient READ gradient WRITE setGradient )
|
||||
// We have to use a QSize here because using QPoint isn't supported.
|
||||
// width -> x, height -> y
|
||||
Q_PROPERTY( QSize mouseHotspotHand WRITE setMouseHotspotHand )
|
||||
|
||||
public:
|
||||
TrackContentObjectView( TrackContentObject * tco, TrackView * tv );
|
||||
virtual ~TrackContentObjectView();
|
||||
|
||||
bool fixedTCOs();
|
||||
|
||||
inline TrackContentObject * getTrackContentObject()
|
||||
{
|
||||
return m_tco;
|
||||
}
|
||||
|
||||
inline TrackView * getTrackView()
|
||||
{
|
||||
return m_trackView;
|
||||
}
|
||||
|
||||
// qproperty access func
|
||||
QColor mutedColor() const;
|
||||
QColor mutedBackgroundColor() const;
|
||||
QColor selectedColor() const;
|
||||
QColor textColor() const;
|
||||
QColor textBackgroundColor() const;
|
||||
QColor textShadowColor() const;
|
||||
QColor BBPatternBackground() const;
|
||||
bool gradient() const;
|
||||
void setMutedColor( const QColor & c );
|
||||
void setMutedBackgroundColor( const QColor & c );
|
||||
void setSelectedColor( const QColor & c );
|
||||
void setTextColor( const QColor & c );
|
||||
void setTextBackgroundColor( const QColor & c );
|
||||
void setTextShadowColor( const QColor & c );
|
||||
void setBBPatternBackground( const QColor & c );
|
||||
void setGradient( const bool & b );
|
||||
void setMouseHotspotHand(const QSize & s);
|
||||
|
||||
// access needsUpdate member variable
|
||||
bool needsUpdate();
|
||||
void setNeedsUpdate( bool b );
|
||||
|
||||
// Method to get a QVector of TCOs to be affected by a context menu action
|
||||
QVector<TrackContentObjectView *> getClickedTCOs();
|
||||
|
||||
// Methods to remove, copy, cut, paste and mute a QVector of TCO views
|
||||
void copy( QVector<TrackContentObjectView *> tcovs );
|
||||
void cut( QVector<TrackContentObjectView *> tcovs );
|
||||
void paste();
|
||||
// remove and toggleMute are static because they don't depend
|
||||
// being called from a particular TCO view, but can be called anywhere as long
|
||||
// as a valid TCO view list is given, while copy/cut require an instance for
|
||||
// some metadata to be written to the clipboard.
|
||||
static void remove( QVector<TrackContentObjectView *> tcovs );
|
||||
static void toggleMute( QVector<TrackContentObjectView *> tcovs );
|
||||
|
||||
QColor getColorForDisplay( QColor );
|
||||
|
||||
public slots:
|
||||
virtual bool close();
|
||||
void remove();
|
||||
void update() override;
|
||||
|
||||
void changeClipColor();
|
||||
void useTrackColor();
|
||||
|
||||
protected:
|
||||
enum ContextMenuAction
|
||||
{
|
||||
Remove,
|
||||
Cut,
|
||||
Copy,
|
||||
Paste,
|
||||
Mute
|
||||
};
|
||||
|
||||
virtual void constructContextMenu( QMenu * )
|
||||
{
|
||||
}
|
||||
|
||||
void contextMenuEvent( QContextMenuEvent * cme ) override;
|
||||
void contextMenuAction( ContextMenuAction action );
|
||||
void dragEnterEvent( QDragEnterEvent * dee ) override;
|
||||
void dropEvent( QDropEvent * de ) override;
|
||||
void leaveEvent( QEvent * e ) override;
|
||||
void mousePressEvent( QMouseEvent * me ) override;
|
||||
void mouseMoveEvent( QMouseEvent * me ) override;
|
||||
void mouseReleaseEvent( QMouseEvent * me ) override;
|
||||
void resizeEvent( QResizeEvent * re ) override
|
||||
{
|
||||
m_needsUpdate = true;
|
||||
selectableObject::resizeEvent( re );
|
||||
}
|
||||
|
||||
float pixelsPerBar();
|
||||
|
||||
|
||||
DataFile createTCODataFiles(const QVector<TrackContentObjectView *> & tcos) const;
|
||||
|
||||
virtual void paintTextLabel(QString const & text, QPainter & painter);
|
||||
|
||||
|
||||
protected slots:
|
||||
void updateLength();
|
||||
void updatePosition();
|
||||
|
||||
|
||||
private:
|
||||
enum Actions
|
||||
{
|
||||
NoAction,
|
||||
Move,
|
||||
MoveSelection,
|
||||
Resize,
|
||||
ResizeLeft,
|
||||
CopySelection,
|
||||
ToggleSelected
|
||||
} ;
|
||||
|
||||
static TextFloat * s_textFloat;
|
||||
|
||||
TrackContentObject * m_tco;
|
||||
TrackView * m_trackView;
|
||||
Actions m_action;
|
||||
QPoint m_initialMousePos;
|
||||
QPoint m_initialMouseGlobalPos;
|
||||
TimePos m_initialTCOPos;
|
||||
TimePos m_initialTCOEnd;
|
||||
QVector<TimePos> m_initialOffsets;
|
||||
|
||||
TextFloat * m_hint;
|
||||
|
||||
// qproperty fields
|
||||
QColor m_mutedColor;
|
||||
QColor m_mutedBackgroundColor;
|
||||
QColor m_selectedColor;
|
||||
QColor m_textColor;
|
||||
QColor m_textBackgroundColor;
|
||||
QColor m_textShadowColor;
|
||||
QColor m_BBPatternBackground;
|
||||
bool m_gradient;
|
||||
QSize m_mouseHotspotHand; // QSize must be used because QPoint isn't supported by property system
|
||||
bool m_cursorSetYet;
|
||||
|
||||
bool m_needsUpdate;
|
||||
inline void setInitialPos( QPoint pos )
|
||||
{
|
||||
m_initialMousePos = pos;
|
||||
m_initialMouseGlobalPos = mapToGlobal( pos );
|
||||
m_initialTCOPos = m_tco->startPosition();
|
||||
m_initialTCOEnd = m_initialTCOPos + m_tco->length();
|
||||
}
|
||||
void setInitialOffsets();
|
||||
|
||||
bool mouseMovedDistance( QMouseEvent * me, int distance );
|
||||
TimePos draggedTCOPos( QMouseEvent * me );
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
142
include/TrackContentWidget.h
Normal file
142
include/TrackContentWidget.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* TrackContentWidget.h - declaration of TrackContentWidget class
|
||||
*
|
||||
* Copyright (c) 2004-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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TRACK_CONTENT_WIDGET_H
|
||||
#define TRACK_CONTENT_WIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "JournallingObject.h"
|
||||
#include "TimePos.h"
|
||||
|
||||
|
||||
class QMimeData;
|
||||
|
||||
class Track;
|
||||
class TrackContentObjectView;
|
||||
class TrackView;
|
||||
|
||||
|
||||
class TrackContentWidget : public QWidget, public JournallingObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
// qproperties for track background gradients
|
||||
Q_PROPERTY( QBrush darkerColor READ darkerColor WRITE setDarkerColor )
|
||||
Q_PROPERTY( QBrush lighterColor READ lighterColor WRITE setLighterColor )
|
||||
Q_PROPERTY( QBrush gridColor READ gridColor WRITE setGridColor )
|
||||
Q_PROPERTY( QBrush embossColor READ embossColor WRITE setEmbossColor )
|
||||
|
||||
public:
|
||||
TrackContentWidget( TrackView * parent );
|
||||
virtual ~TrackContentWidget();
|
||||
|
||||
/*! \brief Updates the background tile pixmap. */
|
||||
void updateBackground();
|
||||
|
||||
void addTCOView( TrackContentObjectView * tcov );
|
||||
void removeTCOView( TrackContentObjectView * tcov );
|
||||
void removeTCOView( int tcoNum )
|
||||
{
|
||||
if( tcoNum >= 0 && tcoNum < m_tcoViews.size() )
|
||||
{
|
||||
removeTCOView( m_tcoViews[tcoNum] );
|
||||
}
|
||||
}
|
||||
|
||||
bool canPasteSelection( TimePos tcoPos, const QDropEvent *de );
|
||||
bool canPasteSelection( TimePos tcoPos, const QMimeData *md, bool allowSameBar = false );
|
||||
bool pasteSelection( TimePos tcoPos, QDropEvent * de );
|
||||
bool pasteSelection( TimePos tcoPos, const QMimeData * md, bool skipSafetyCheck = false );
|
||||
|
||||
TimePos endPosition( const TimePos & posStart );
|
||||
|
||||
// qproperty access methods
|
||||
|
||||
QBrush darkerColor() const;
|
||||
QBrush lighterColor() const;
|
||||
QBrush gridColor() const;
|
||||
QBrush embossColor() const;
|
||||
|
||||
void setDarkerColor( const QBrush & c );
|
||||
void setLighterColor( const QBrush & c );
|
||||
void setGridColor( const QBrush & c );
|
||||
void setEmbossColor( const QBrush & c);
|
||||
|
||||
public slots:
|
||||
void update();
|
||||
void changePosition( const TimePos & newPos = TimePos( -1 ) );
|
||||
|
||||
protected:
|
||||
enum ContextMenuAction
|
||||
{
|
||||
Paste
|
||||
};
|
||||
|
||||
void contextMenuEvent( QContextMenuEvent * cme ) override;
|
||||
void contextMenuAction( QContextMenuEvent * cme, ContextMenuAction action );
|
||||
void dragEnterEvent( QDragEnterEvent * dee ) override;
|
||||
void dropEvent( QDropEvent * de ) override;
|
||||
void mousePressEvent( QMouseEvent * me ) override;
|
||||
void paintEvent( QPaintEvent * pe ) override;
|
||||
void resizeEvent( QResizeEvent * re ) override;
|
||||
|
||||
QString nodeName() const override
|
||||
{
|
||||
return "trackcontentwidget";
|
||||
}
|
||||
|
||||
void saveSettings( QDomDocument& doc, QDomElement& element ) override
|
||||
{
|
||||
Q_UNUSED(doc)
|
||||
Q_UNUSED(element)
|
||||
}
|
||||
|
||||
void loadSettings( const QDomElement& element ) override
|
||||
{
|
||||
Q_UNUSED(element)
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
Track * getTrack();
|
||||
TimePos getPosition( int mouseX );
|
||||
|
||||
TrackView * m_trackView;
|
||||
|
||||
typedef QVector<TrackContentObjectView *> tcoViewVector;
|
||||
tcoViewVector m_tcoViews;
|
||||
|
||||
QPixmap m_background;
|
||||
|
||||
// qproperty fields
|
||||
QBrush m_darkerColor;
|
||||
QBrush m_lighterColor;
|
||||
QBrush m_gridColor;
|
||||
QBrush m_embossColor;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
79
include/TrackOperationsWidget.h
Normal file
79
include/TrackOperationsWidget.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* TrackOperationsWidget.h - declaration of TrackOperationsWidget class
|
||||
*
|
||||
* Copyright (c) 2004-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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TRACK_OPERATIONS_WIDGET_H
|
||||
#define TRACK_OPERATIONS_WIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QPushButton;
|
||||
|
||||
class PixmapButton;
|
||||
class TrackView;
|
||||
|
||||
class TrackOperationsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TrackOperationsWidget( TrackView * parent );
|
||||
~TrackOperationsWidget();
|
||||
|
||||
|
||||
protected:
|
||||
void mousePressEvent( QMouseEvent * me ) override;
|
||||
void paintEvent( QPaintEvent * pe ) override;
|
||||
|
||||
|
||||
private slots:
|
||||
void cloneTrack();
|
||||
void removeTrack();
|
||||
void updateMenu();
|
||||
void changeTrackColor();
|
||||
void randomTrackColor();
|
||||
void resetTrackColor();
|
||||
void useTrackColor();
|
||||
void toggleRecording(bool on);
|
||||
void recordingOn();
|
||||
void recordingOff();
|
||||
void clearTrack();
|
||||
|
||||
private:
|
||||
TrackView * m_trackView;
|
||||
|
||||
QPushButton * m_trackOps;
|
||||
PixmapButton * m_muteBtn;
|
||||
PixmapButton * m_soloBtn;
|
||||
|
||||
|
||||
friend class TrackView;
|
||||
|
||||
signals:
|
||||
void trackRemovalScheduled( TrackView * t );
|
||||
void colorChanged( QColor & c );
|
||||
void colorParented();
|
||||
void colorReset();
|
||||
|
||||
} ;
|
||||
|
||||
#endif
|
||||
173
include/TrackView.h
Normal file
173
include/TrackView.h
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* TrackView.h - declaration of TrackView class
|
||||
*
|
||||
* Copyright (c) 2004-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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef TRACK_VIEW_H
|
||||
#define TRACK_VIEW_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "JournallingObject.h"
|
||||
#include "ModelView.h"
|
||||
#include "TrackContentWidget.h"
|
||||
#include "TrackOperationsWidget.h"
|
||||
|
||||
|
||||
class QMenu;
|
||||
|
||||
class FadeButton;
|
||||
class Track;
|
||||
class TrackContainerView;
|
||||
class TrackContentObject;
|
||||
|
||||
|
||||
const int DEFAULT_SETTINGS_WIDGET_WIDTH = 224;
|
||||
const int TRACK_OP_WIDTH = 78;
|
||||
// This shaves 150-ish pixels off track buttons,
|
||||
// ruled from config: ui.compacttrackbuttons
|
||||
const int DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT = 96;
|
||||
const int TRACK_OP_WIDTH_COMPACT = 62;
|
||||
|
||||
const int TCO_BORDER_WIDTH = 2;
|
||||
|
||||
|
||||
class TrackView : public QWidget, public ModelView, public JournallingObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TrackView( Track * _track, TrackContainerView* tcv );
|
||||
virtual ~TrackView();
|
||||
|
||||
inline const Track * getTrack() const
|
||||
{
|
||||
return m_track;
|
||||
}
|
||||
|
||||
inline Track * getTrack()
|
||||
{
|
||||
return m_track;
|
||||
}
|
||||
|
||||
inline TrackContainerView* trackContainerView()
|
||||
{
|
||||
return m_trackContainerView;
|
||||
}
|
||||
|
||||
inline TrackOperationsWidget * getTrackOperationsWidget()
|
||||
{
|
||||
return &m_trackOperationsWidget;
|
||||
}
|
||||
|
||||
inline QWidget * getTrackSettingsWidget()
|
||||
{
|
||||
return &m_trackSettingsWidget;
|
||||
}
|
||||
|
||||
inline TrackContentWidget * getTrackContentWidget()
|
||||
{
|
||||
return &m_trackContentWidget;
|
||||
}
|
||||
|
||||
bool isMovingTrack() const
|
||||
{
|
||||
return m_action == MoveTrack;
|
||||
}
|
||||
|
||||
virtual void update();
|
||||
|
||||
// Create a menu for assigning/creating channels for this track
|
||||
// Currently instrument track and sample track supports it
|
||||
virtual QMenu * createFxMenu(QString title, QString newFxLabel);
|
||||
|
||||
|
||||
public slots:
|
||||
virtual bool close();
|
||||
|
||||
|
||||
protected:
|
||||
void modelChanged() override;
|
||||
|
||||
void saveSettings( QDomDocument& doc, QDomElement& element ) override
|
||||
{
|
||||
Q_UNUSED(doc)
|
||||
Q_UNUSED(element)
|
||||
}
|
||||
|
||||
void loadSettings( const QDomElement& element ) override
|
||||
{
|
||||
Q_UNUSED(element)
|
||||
}
|
||||
|
||||
QString nodeName() const override
|
||||
{
|
||||
return "trackview";
|
||||
}
|
||||
|
||||
|
||||
void dragEnterEvent( QDragEnterEvent * dee ) override;
|
||||
void dropEvent( QDropEvent * de ) override;
|
||||
void mousePressEvent( QMouseEvent * me ) override;
|
||||
void mouseMoveEvent( QMouseEvent * me ) override;
|
||||
void mouseReleaseEvent( QMouseEvent * me ) override;
|
||||
void paintEvent( QPaintEvent * pe ) override;
|
||||
void resizeEvent( QResizeEvent * re ) override;
|
||||
|
||||
|
||||
private:
|
||||
enum Actions
|
||||
{
|
||||
NoAction,
|
||||
MoveTrack,
|
||||
ResizeTrack
|
||||
} ;
|
||||
|
||||
Track * m_track;
|
||||
TrackContainerView * m_trackContainerView;
|
||||
|
||||
TrackOperationsWidget m_trackOperationsWidget;
|
||||
QWidget m_trackSettingsWidget;
|
||||
TrackContentWidget m_trackContentWidget;
|
||||
|
||||
Actions m_action;
|
||||
|
||||
virtual FadeButton * getActivityIndicator()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void setIndicatorMute(FadeButton* indicator, bool muted);
|
||||
|
||||
friend class TrackLabelButton;
|
||||
|
||||
|
||||
private slots:
|
||||
void createTCOView( TrackContentObject * tco );
|
||||
void muteChanged();
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "lmms_math.h"
|
||||
#include "TrackContainer.h"
|
||||
#include "BBTrack.h"
|
||||
#include "DataFile.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "LocaleHelper.h"
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ set(LMMS_SRCS
|
||||
core/ToolPlugin.cpp
|
||||
core/Track.cpp
|
||||
core/TrackContainer.cpp
|
||||
core/TrackContentObject.cpp
|
||||
core/ValueBuffer.cpp
|
||||
core/VstSyncController.cpp
|
||||
core/StepRecorder.cpp
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
#include "FxMixerView.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "ExportFilter.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "NotePlayHandle.h"
|
||||
#include "Pattern.h"
|
||||
#include "PianoRoll.h"
|
||||
#include "ProjectJournal.h"
|
||||
|
||||
2825
src/core/Track.cpp
2825
src/core/Track.cpp
File diff suppressed because it is too large
Load Diff
206
src/core/TrackContentObject.cpp
Normal file
206
src/core/TrackContentObject.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* TrackContentObject.cpp - implementation of TrackContentObject class
|
||||
*
|
||||
* Copyright (c) 2004-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 "TrackContentObject.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
|
||||
#include "AutomationEditor.h"
|
||||
#include "AutomationPattern.h"
|
||||
#include "Engine.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "Song.h"
|
||||
|
||||
|
||||
/*! \brief Create a new TrackContentObject
|
||||
*
|
||||
* Creates a new track content object for the given track.
|
||||
*
|
||||
* \param _track The track that will contain the new object
|
||||
*/
|
||||
TrackContentObject::TrackContentObject( Track * track ) :
|
||||
Model( track ),
|
||||
m_track( track ),
|
||||
m_startPosition(),
|
||||
m_length(),
|
||||
m_mutedModel( false, this, tr( "Mute" ) ),
|
||||
m_selectViewOnCreate( false ),
|
||||
m_color( 128, 128, 128 ),
|
||||
m_useCustomClipColor( false )
|
||||
{
|
||||
if( getTrack() )
|
||||
{
|
||||
getTrack()->addTCO( this );
|
||||
}
|
||||
setJournalling( false );
|
||||
movePosition( 0 );
|
||||
changeLength( 0 );
|
||||
setJournalling( true );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Destroy a TrackContentObject
|
||||
*
|
||||
* Destroys the given track content object.
|
||||
*
|
||||
*/
|
||||
TrackContentObject::~TrackContentObject()
|
||||
{
|
||||
emit destroyedTCO();
|
||||
|
||||
if( getTrack() )
|
||||
{
|
||||
getTrack()->removeTCO( this );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Move this TrackContentObject's position in time
|
||||
*
|
||||
* If the track content object has moved, update its position. We
|
||||
* also add a journal entry for undo and update the display.
|
||||
*
|
||||
* \param _pos The new position of the track content object.
|
||||
*/
|
||||
void TrackContentObject::movePosition( const TimePos & pos )
|
||||
{
|
||||
TimePos newPos = qMax(0, pos.getTicks());
|
||||
if (m_startPosition != newPos)
|
||||
{
|
||||
Engine::mixer()->requestChangeInModel();
|
||||
m_startPosition = newPos;
|
||||
Engine::mixer()->doneChangeInModel();
|
||||
Engine::getSong()->updateLength();
|
||||
emit positionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Change the length of this TrackContentObject
|
||||
*
|
||||
* If the track content object's length has changed, update it. We
|
||||
* also add a journal entry for undo and update the display.
|
||||
*
|
||||
* \param _length The new length of the track content object.
|
||||
*/
|
||||
void TrackContentObject::changeLength( const TimePos & length )
|
||||
{
|
||||
m_length = length;
|
||||
Engine::getSong()->updateLength();
|
||||
emit lengthChanged();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool TrackContentObject::comparePosition(const TrackContentObject *a, const TrackContentObject *b)
|
||||
{
|
||||
return a->startPosition() < b->startPosition();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Copies the state of a TrackContentObject to another TrackContentObject
|
||||
*
|
||||
* This method copies the state of a TCO to another TCO
|
||||
*/
|
||||
void TrackContentObject::copyStateTo( TrackContentObject *src, TrackContentObject *dst )
|
||||
{
|
||||
// If the node names match we copy the state
|
||||
if( src->nodeName() == dst->nodeName() ){
|
||||
QDomDocument doc;
|
||||
QDomElement parent = doc.createElement( "StateCopy" );
|
||||
src->saveState( doc, parent );
|
||||
|
||||
const TimePos pos = dst->startPosition();
|
||||
dst->restoreState( parent.firstChild().toElement() );
|
||||
dst->movePosition( pos );
|
||||
|
||||
AutomationPattern::resolveAllIDs();
|
||||
GuiApplication::instance()->automationEditor()->m_editor->updateAfterPatternChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Mutes this TrackContentObject
|
||||
*
|
||||
* Restore the previous state of this track content object. This will
|
||||
* restore the position or the length of the track content object
|
||||
* depending on what was changed.
|
||||
*
|
||||
* \param _je The journal entry to undo
|
||||
*/
|
||||
void TrackContentObject::toggleMute()
|
||||
{
|
||||
m_mutedModel.setValue( !m_mutedModel.value() );
|
||||
emit dataChanged();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
TimePos TrackContentObject::startTimeOffset() const
|
||||
{
|
||||
return m_startTimeOffset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TrackContentObject::setStartTimeOffset( const TimePos &startTimeOffset )
|
||||
{
|
||||
m_startTimeOffset = startTimeOffset;
|
||||
}
|
||||
|
||||
// Update TCO color if it follows the track color
|
||||
void TrackContentObject::updateColor()
|
||||
{
|
||||
if( ! m_useCustomClipColor )
|
||||
{
|
||||
emit trackColorChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TrackContentObject::useCustomClipColor( bool b )
|
||||
{
|
||||
m_useCustomClipColor = b;
|
||||
updateColor();
|
||||
}
|
||||
|
||||
|
||||
bool TrackContentObject::hasColor()
|
||||
{
|
||||
return usesCustomClipColor() || getTrack()->useColor();
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
|
||||
#include "MainApplication.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "DataFile.h"
|
||||
#include "NotePlayHandle.h"
|
||||
#include "embed.h"
|
||||
#include "Engine.h"
|
||||
|
||||
@@ -35,6 +35,8 @@ SET(LMMS_SRCS
|
||||
gui/TimeLineWidget.cpp
|
||||
gui/ToolPluginView.cpp
|
||||
gui/TrackContainerView.cpp
|
||||
gui/TrackContentObjectView.cpp
|
||||
gui/TrackView.cpp
|
||||
|
||||
gui/dialogs/FileDialog.cpp
|
||||
gui/dialogs/VersionedSaveDialog.cpp
|
||||
@@ -98,6 +100,8 @@ SET(LMMS_SRCS
|
||||
gui/widgets/ToolButton.cpp
|
||||
gui/widgets/ToolTip.cpp
|
||||
gui/widgets/TrackLabelButton.cpp
|
||||
gui/widgets/TrackContentWidget.cpp
|
||||
gui/widgets/TrackOperationsWidget.cpp
|
||||
gui/widgets/TrackRenameLineEdit.cpp
|
||||
gui/widgets/StepRecorderWidget.cpp
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "FileBrowser.h"
|
||||
#include "BBTrackContainer.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "DataFile.h"
|
||||
#include "embed.h"
|
||||
#include "Engine.h"
|
||||
#include "GuiApplication.h"
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "ConfigManager.h"
|
||||
#include "ControllerRackView.h"
|
||||
#include "FxMixerView.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "MainWindow.h"
|
||||
#include "PianoRoll.h"
|
||||
#include "ProjectNotes.h"
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <QMdiArea>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QScrollBar>
|
||||
#include <QShortcut>
|
||||
#include <QLibrary>
|
||||
#include <QSplitter>
|
||||
@@ -50,6 +51,7 @@
|
||||
#include "FxMixerView.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "ImportFilter.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "PianoRoll.h"
|
||||
#include "PluginBrowser.h"
|
||||
#include "PluginFactory.h"
|
||||
@@ -71,6 +73,7 @@
|
||||
|
||||
#include "lmmsversion.h"
|
||||
|
||||
|
||||
#if !defined(LMMS_BUILD_WIN32) && !defined(LMMS_BUILD_APPLE) && !defined(LMMS_BUILD_HAIKU)
|
||||
//Work around an issue on KDE5 as per https://bugs.kde.org/show_bug.cgi?id=337491#c21
|
||||
void disableAutoKeyAccelerators(QWidget* mainWindow)
|
||||
|
||||
@@ -29,15 +29,18 @@
|
||||
#include <QApplication>
|
||||
#include <QLayout>
|
||||
#include <QMdiArea>
|
||||
#include <QScrollBar>
|
||||
#include <QWheelEvent>
|
||||
|
||||
#include "TrackContainer.h"
|
||||
#include "BBTrack.h"
|
||||
#include "DataFile.h"
|
||||
#include "MainWindow.h"
|
||||
#include "Mixer.h"
|
||||
#include "FileBrowser.h"
|
||||
#include "ImportFilter.h"
|
||||
#include "Instrument.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "Song.h"
|
||||
#include "StringPairDrag.h"
|
||||
#include "GuiApplication.h"
|
||||
|
||||
1243
src/gui/TrackContentObjectView.cpp
Normal file
1243
src/gui/TrackContentObjectView.cpp
Normal file
File diff suppressed because it is too large
Load Diff
458
src/gui/TrackView.cpp
Normal file
458
src/gui/TrackView.cpp
Normal file
@@ -0,0 +1,458 @@
|
||||
/*
|
||||
* TrackView.cpp - implementation of TrackView class
|
||||
*
|
||||
* Copyright (c) 2004-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 "TrackView.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMenu>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
#include <QtGlobal>
|
||||
|
||||
|
||||
#include "ConfigManager.h"
|
||||
#include "DataFile.h"
|
||||
#include "Engine.h"
|
||||
#include "FadeButton.h"
|
||||
#include "Mixer.h"
|
||||
#include "PixmapButton.h"
|
||||
#include "StringPairDrag.h"
|
||||
#include "ToolTip.h"
|
||||
#include "Track.h"
|
||||
#include "TrackContainerView.h"
|
||||
#include "TrackContentObjectView.h"
|
||||
|
||||
|
||||
/*! \brief Create a new track View.
|
||||
*
|
||||
* The track View is handles the actual display of the track, including
|
||||
* displaying its various widgets and the track segments.
|
||||
*
|
||||
* \param track The track to display.
|
||||
* \param tcv The track Container View for us to be displayed in.
|
||||
* \todo Is my description of these properties correct?
|
||||
*/
|
||||
TrackView::TrackView( Track * track, TrackContainerView * tcv ) :
|
||||
QWidget( tcv->contentWidget() ), /*!< The Track Container View's content widget. */
|
||||
ModelView( NULL, this ), /*!< The model view of this track */
|
||||
m_track( track ), /*!< The track we're displaying */
|
||||
m_trackContainerView( tcv ), /*!< The track Container View we're displayed in */
|
||||
m_trackOperationsWidget( this ), /*!< Our trackOperationsWidget */
|
||||
m_trackSettingsWidget( this ), /*!< Our trackSettingsWidget */
|
||||
m_trackContentWidget( this ), /*!< Our trackContentWidget */
|
||||
m_action( NoAction ) /*!< The action we're currently performing */
|
||||
{
|
||||
setAutoFillBackground( true );
|
||||
QPalette pal;
|
||||
pal.setColor( backgroundRole(), QColor( 32, 36, 40 ) );
|
||||
setPalette( pal );
|
||||
|
||||
m_trackSettingsWidget.setAutoFillBackground( true );
|
||||
|
||||
QHBoxLayout * layout = new QHBoxLayout( this );
|
||||
layout->setMargin( 0 );
|
||||
layout->setSpacing( 0 );
|
||||
layout->addWidget( &m_trackOperationsWidget );
|
||||
layout->addWidget( &m_trackSettingsWidget );
|
||||
layout->addWidget( &m_trackContentWidget, 1 );
|
||||
setFixedHeight( m_track->getHeight() );
|
||||
|
||||
resizeEvent( NULL );
|
||||
|
||||
setAcceptDrops( true );
|
||||
setAttribute( Qt::WA_DeleteOnClose, true );
|
||||
|
||||
|
||||
connect( m_track, SIGNAL( destroyedTrack() ), this, SLOT( close() ) );
|
||||
connect( m_track,
|
||||
SIGNAL( trackContentObjectAdded( TrackContentObject * ) ),
|
||||
this, SLOT( createTCOView( TrackContentObject * ) ),
|
||||
Qt::QueuedConnection );
|
||||
|
||||
connect( &m_track->m_mutedModel, SIGNAL( dataChanged() ),
|
||||
&m_trackContentWidget, SLOT( update() ) );
|
||||
|
||||
connect(&m_track->m_mutedModel, SIGNAL(dataChanged()),
|
||||
this, SLOT(muteChanged()));
|
||||
|
||||
connect( &m_track->m_soloModel, SIGNAL( dataChanged() ),
|
||||
m_track, SLOT( toggleSolo() ), Qt::DirectConnection );
|
||||
|
||||
connect( &m_trackOperationsWidget, SIGNAL( colorChanged( QColor & ) ),
|
||||
m_track, SLOT( trackColorChanged( QColor & ) ) );
|
||||
|
||||
connect( &m_trackOperationsWidget, SIGNAL( colorReset() ),
|
||||
m_track, SLOT( trackColorReset() ) );
|
||||
|
||||
// create views for already existing TCOs
|
||||
for( Track::tcoVector::iterator it =
|
||||
m_track->m_trackContentObjects.begin();
|
||||
it != m_track->m_trackContentObjects.end(); ++it )
|
||||
{
|
||||
createTCOView( *it );
|
||||
}
|
||||
|
||||
m_trackContainerView->addTrackView( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Destroy this track View.
|
||||
*
|
||||
*/
|
||||
TrackView::~TrackView()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Resize this track View.
|
||||
*
|
||||
* \param re the Resize Event to handle.
|
||||
*/
|
||||
void TrackView::resizeEvent( QResizeEvent * re )
|
||||
{
|
||||
if( ConfigManager::inst()->value( "ui",
|
||||
"compacttrackbuttons" ).toInt() )
|
||||
{
|
||||
m_trackOperationsWidget.setFixedSize( TRACK_OP_WIDTH_COMPACT, height() - 1 );
|
||||
m_trackSettingsWidget.setFixedSize( DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT, height() - 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_trackOperationsWidget.setFixedSize( TRACK_OP_WIDTH, height() - 1 );
|
||||
m_trackSettingsWidget.setFixedSize( DEFAULT_SETTINGS_WIDGET_WIDTH, height() - 1 );
|
||||
}
|
||||
m_trackContentWidget.setFixedHeight( height() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Update this track View and all its content objects.
|
||||
*
|
||||
*/
|
||||
void TrackView::update()
|
||||
{
|
||||
m_trackContentWidget.update();
|
||||
if( !m_trackContainerView->fixedTCOs() )
|
||||
{
|
||||
m_trackContentWidget.changePosition();
|
||||
}
|
||||
QWidget::update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Create a menu for assigning/creating channels for this track.
|
||||
*
|
||||
*/
|
||||
QMenu * TrackView::createFxMenu(QString title, QString newFxLabel)
|
||||
{
|
||||
Q_UNUSED(title)
|
||||
Q_UNUSED(newFxLabel)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Close this track View.
|
||||
*
|
||||
*/
|
||||
bool TrackView::close()
|
||||
{
|
||||
m_trackContainerView->removeTrackView( this );
|
||||
return QWidget::close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Register that the model of this track View has changed.
|
||||
*
|
||||
*/
|
||||
void TrackView::modelChanged()
|
||||
{
|
||||
m_track = castModel<Track>();
|
||||
Q_ASSERT( m_track != NULL );
|
||||
connect( m_track, SIGNAL( destroyedTrack() ), this, SLOT( close() ) );
|
||||
m_trackOperationsWidget.m_muteBtn->setModel( &m_track->m_mutedModel );
|
||||
m_trackOperationsWidget.m_soloBtn->setModel( &m_track->m_soloModel );
|
||||
ModelView::modelChanged();
|
||||
setFixedHeight( m_track->getHeight() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Start a drag event on this track View.
|
||||
*
|
||||
* \param dee the DragEnterEvent to start.
|
||||
*/
|
||||
void TrackView::dragEnterEvent( QDragEnterEvent * dee )
|
||||
{
|
||||
StringPairDrag::processDragEnterEvent( dee, "track_" +
|
||||
QString::number( m_track->type() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Accept a drop event on this track View.
|
||||
*
|
||||
* We only accept drop events that are of the same type as this track.
|
||||
* If so, we decode the data from the drop event by just feeding it
|
||||
* back into the engine as a state.
|
||||
*
|
||||
* \param de the DropEvent to handle.
|
||||
*/
|
||||
void TrackView::dropEvent( QDropEvent * de )
|
||||
{
|
||||
QString type = StringPairDrag::decodeKey( de );
|
||||
QString value = StringPairDrag::decodeValue( de );
|
||||
if( type == ( "track_" + QString::number( m_track->type() ) ) )
|
||||
{
|
||||
// value contains our XML-data so simply create a
|
||||
// DataFile which does the rest for us...
|
||||
DataFile dataFile( value.toUtf8() );
|
||||
Engine::mixer()->requestChangeInModel();
|
||||
m_track->restoreState( dataFile.content().firstChild().toElement() );
|
||||
Engine::mixer()->doneChangeInModel();
|
||||
de->accept();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Handle a mouse press event on this track View.
|
||||
*
|
||||
* If this track container supports rubber band selection, let the
|
||||
* widget handle that and don't bother with any other handling.
|
||||
*
|
||||
* If the left mouse button is pressed, we handle two things. If
|
||||
* SHIFT is pressed, then we resize vertically. Otherwise we start
|
||||
* the process of moving this track to a new position.
|
||||
*
|
||||
* Otherwise we let the widget handle the mouse event as normal.
|
||||
*
|
||||
* \param me the MouseEvent to handle.
|
||||
*/
|
||||
void TrackView::mousePressEvent( QMouseEvent * me )
|
||||
{
|
||||
|
||||
// If previously dragged too small, restore on shift-leftclick
|
||||
if( height() < DEFAULT_TRACK_HEIGHT &&
|
||||
me->modifiers() & Qt::ShiftModifier &&
|
||||
me->button() == Qt::LeftButton )
|
||||
{
|
||||
setFixedHeight( DEFAULT_TRACK_HEIGHT );
|
||||
m_track->setHeight( DEFAULT_TRACK_HEIGHT );
|
||||
}
|
||||
|
||||
|
||||
int widgetTotal = ConfigManager::inst()->value( "ui",
|
||||
"compacttrackbuttons" ).toInt()==1 ?
|
||||
DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT :
|
||||
DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH;
|
||||
if( m_trackContainerView->allowRubberband() == true && me->x() > widgetTotal )
|
||||
{
|
||||
QWidget::mousePressEvent( me );
|
||||
}
|
||||
else if( me->button() == Qt::LeftButton )
|
||||
{
|
||||
if( me->modifiers() & Qt::ShiftModifier )
|
||||
{
|
||||
m_action = ResizeTrack;
|
||||
QCursor::setPos( mapToGlobal( QPoint( me->x(),
|
||||
height() ) ) );
|
||||
QCursor c( Qt::SizeVerCursor);
|
||||
QApplication::setOverrideCursor( c );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( me->x()>10 ) // 10 = The width of the grip + 2 pixels to the left and right.
|
||||
{
|
||||
QWidget::mousePressEvent( me );
|
||||
return;
|
||||
}
|
||||
|
||||
m_action = MoveTrack;
|
||||
|
||||
QCursor c( Qt::SizeVerCursor );
|
||||
QApplication::setOverrideCursor( c );
|
||||
// update because in move-mode, all elements in
|
||||
// track-op-widgets are hidden as a visual feedback
|
||||
m_trackOperationsWidget.update();
|
||||
}
|
||||
|
||||
me->accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
QWidget::mousePressEvent( me );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Handle a mouse move event on this track View.
|
||||
*
|
||||
* If this track container supports rubber band selection, let the
|
||||
* widget handle that and don't bother with any other handling.
|
||||
*
|
||||
* Otherwise if we've started the move process (from mousePressEvent())
|
||||
* then move ourselves into that position, reordering the track list
|
||||
* with moveTrackViewUp() and moveTrackViewDown() to suit. We make a
|
||||
* note of this in the undo journal in case the user wants to undo this
|
||||
* move.
|
||||
*
|
||||
* Likewise if we've started a resize process, handle this too, making
|
||||
* sure that we never go below the minimum track height.
|
||||
*
|
||||
* \param me the MouseEvent to handle.
|
||||
*/
|
||||
void TrackView::mouseMoveEvent( QMouseEvent * me )
|
||||
{
|
||||
int widgetTotal = ConfigManager::inst()->value( "ui",
|
||||
"compacttrackbuttons" ).toInt()==1 ?
|
||||
DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT :
|
||||
DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH;
|
||||
if( m_trackContainerView->allowRubberband() == true && me->x() > widgetTotal )
|
||||
{
|
||||
QWidget::mouseMoveEvent( me );
|
||||
}
|
||||
else if( m_action == MoveTrack )
|
||||
{
|
||||
// look which track-widget the mouse-cursor is over
|
||||
const int yPos =
|
||||
m_trackContainerView->contentWidget()->mapFromGlobal( me->globalPos() ).y();
|
||||
const TrackView * trackAtY = m_trackContainerView->trackViewAt( yPos );
|
||||
|
||||
// debug code
|
||||
// qDebug( "y position %d", yPos );
|
||||
|
||||
// a track-widget not equal to ourself?
|
||||
if( trackAtY != NULL && trackAtY != this )
|
||||
{
|
||||
// then move us up/down there!
|
||||
if( me->y() < 0 )
|
||||
{
|
||||
m_trackContainerView->moveTrackViewUp( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_trackContainerView->moveTrackViewDown( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( m_action == ResizeTrack )
|
||||
{
|
||||
setFixedHeight( qMax<int>( me->y(), MINIMAL_TRACK_HEIGHT ) );
|
||||
m_trackContainerView->realignTracks();
|
||||
m_track->setHeight( height() );
|
||||
}
|
||||
|
||||
if( height() < DEFAULT_TRACK_HEIGHT )
|
||||
{
|
||||
ToolTip::add( this, m_track->m_name );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*! \brief Handle a mouse release event on this track View.
|
||||
*
|
||||
* \param me the MouseEvent to handle.
|
||||
*/
|
||||
void TrackView::mouseReleaseEvent( QMouseEvent * me )
|
||||
{
|
||||
m_action = NoAction;
|
||||
while( QApplication::overrideCursor() != NULL )
|
||||
{
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
m_trackOperationsWidget.update();
|
||||
|
||||
QWidget::mouseReleaseEvent( me );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Repaint this track View.
|
||||
*
|
||||
* \param pe the PaintEvent to start.
|
||||
*/
|
||||
void TrackView::paintEvent( QPaintEvent * pe )
|
||||
{
|
||||
QStyleOption opt;
|
||||
opt.initFrom( this );
|
||||
QPainter p( this );
|
||||
style()->drawPrimitive( QStyle::PE_Widget, &opt, &p, this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Create a TrackContentObject View in this track View.
|
||||
*
|
||||
* \param tco the TrackContentObject to create the view for.
|
||||
* \todo is this a good description for what this method does?
|
||||
*/
|
||||
void TrackView::createTCOView( TrackContentObject * tco )
|
||||
{
|
||||
TrackContentObjectView * tv = tco->createView( this );
|
||||
if( tco->getSelectViewOnCreate() == true )
|
||||
{
|
||||
tv->setSelected( true );
|
||||
}
|
||||
tco->selectViewOnCreate( false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TrackView::muteChanged()
|
||||
{
|
||||
FadeButton * indicator = getActivityIndicator();
|
||||
if (indicator) { setIndicatorMute(indicator, m_track->m_mutedModel.value()); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TrackView::setIndicatorMute(FadeButton* indicator, bool muted)
|
||||
{
|
||||
QPalette::ColorRole role = muted ? QPalette::Highlight : QPalette::BrightText;
|
||||
indicator->setActiveColor(QApplication::palette().color(QPalette::Active, role));
|
||||
}
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "ComboBox.h"
|
||||
#include "BBTrack.h"
|
||||
#include "BBTrackContainer.h"
|
||||
#include "DataFile.h"
|
||||
#include "embed.h"
|
||||
#include "MainWindow.h"
|
||||
#include "Song.h"
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "Clipboard.h"
|
||||
#include "ComboBox.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "DataFile.h"
|
||||
#include "debug.h"
|
||||
#include "DeprecationHelper.h"
|
||||
#include "DetuningHelper.h"
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <QMdiArea>
|
||||
#include <QMdiSubWindow>
|
||||
#include <QPainter>
|
||||
#include <QScrollBar>
|
||||
#include <QTimeLine>
|
||||
|
||||
#include "AudioDevice.h"
|
||||
@@ -293,7 +294,7 @@ float SongEditor::getSnapSize() const
|
||||
{
|
||||
val = val - m_zoomingModel->value() + 3;
|
||||
}
|
||||
val = max(val, -6); // -6 gives 1/64th bar snapping. Lower values cause crashing.
|
||||
val = std::max(val, -6); // -6 gives 1/64th bar snapping. Lower values cause crashing.
|
||||
|
||||
if ( val >= 0 ){
|
||||
return 1 << val;
|
||||
@@ -307,7 +308,7 @@ QString SongEditor::getSnapSizeString() const
|
||||
{
|
||||
int val = -m_snappingModel->value() + 3;
|
||||
val = val - m_zoomingModel->value() + 3;
|
||||
val = max(val, -6); // -6 gives 1/64th bar snapping. Lower values cause crashing.
|
||||
val = std::max(val, -6); // -6 gives 1/64th bar snapping. Lower values cause crashing.
|
||||
|
||||
if ( val >= 0 ){
|
||||
int bars = 1 << val;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "CaptionMenu.h"
|
||||
#include "FxMixerView.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "Track.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
void FxLineLcdSpinBox::setTrackView(TrackView * tv)
|
||||
{
|
||||
|
||||
710
src/gui/widgets/TrackContentWidget.cpp
Normal file
710
src/gui/widgets/TrackContentWidget.cpp
Normal file
@@ -0,0 +1,710 @@
|
||||
/*
|
||||
* TrackContentWidget.cpp - implementation of TrackContentWidget class
|
||||
*
|
||||
* Copyright (c) 2004-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 "TrackContentWidget.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QContextMenuEvent>
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
|
||||
#include "AutomationPattern.h"
|
||||
#include "BBEditor.h"
|
||||
#include "BBTrackContainer.h"
|
||||
#include "Clipboard.h"
|
||||
#include "DataFile.h"
|
||||
#include "Engine.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "Song.h"
|
||||
#include "SongEditor.h"
|
||||
#include "StringPairDrag.h"
|
||||
#include "TrackContainerView.h"
|
||||
#include "TrackContentObjectView.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
|
||||
/*! Alternate between a darker and a lighter background color every 4 bars
|
||||
*/
|
||||
const int BARS_PER_GROUP = 4;
|
||||
|
||||
|
||||
/*! \brief Create a new trackContentWidget
|
||||
*
|
||||
* Creates a new track content widget for the given track.
|
||||
* The content widget comprises the 'grip bar' and the 'tools' button
|
||||
* for the track's context menu.
|
||||
*
|
||||
* \param parent The parent track.
|
||||
*/
|
||||
TrackContentWidget::TrackContentWidget( TrackView * parent ) :
|
||||
QWidget( parent ),
|
||||
m_trackView( parent ),
|
||||
m_darkerColor( Qt::SolidPattern ),
|
||||
m_lighterColor( Qt::SolidPattern ),
|
||||
m_gridColor( Qt::SolidPattern ),
|
||||
m_embossColor( Qt::SolidPattern )
|
||||
{
|
||||
setAcceptDrops( true );
|
||||
|
||||
connect( parent->trackContainerView(),
|
||||
SIGNAL( positionChanged( const TimePos & ) ),
|
||||
this, SLOT( changePosition( const TimePos & ) ) );
|
||||
|
||||
setStyle( QApplication::style() );
|
||||
|
||||
updateBackground();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Destroy this trackContentWidget
|
||||
*
|
||||
* Destroys the trackContentWidget.
|
||||
*/
|
||||
TrackContentWidget::~TrackContentWidget()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TrackContentWidget::updateBackground()
|
||||
{
|
||||
const TrackContainerView * tcv = m_trackView->trackContainerView();
|
||||
|
||||
// Assume even-pixels-per-bar. Makes sense, should be like this anyways
|
||||
int ppb = static_cast<int>( tcv->pixelsPerBar() );
|
||||
|
||||
int w = ppb * BARS_PER_GROUP;
|
||||
int h = height();
|
||||
m_background = QPixmap( w * 2, height() );
|
||||
QPainter pmp( &m_background );
|
||||
|
||||
pmp.fillRect( 0, 0, w, h, darkerColor() );
|
||||
pmp.fillRect( w, 0, w , h, lighterColor() );
|
||||
|
||||
// draw lines
|
||||
// vertical lines
|
||||
pmp.setPen( QPen( gridColor(), 1 ) );
|
||||
for( float x = 0; x < w * 2; x += ppb )
|
||||
{
|
||||
pmp.drawLine( QLineF( x, 0.0, x, h ) );
|
||||
}
|
||||
|
||||
pmp.setPen( QPen( embossColor(), 1 ) );
|
||||
for( float x = 1.0; x < w * 2; x += ppb )
|
||||
{
|
||||
pmp.drawLine( QLineF( x, 0.0, x, h ) );
|
||||
}
|
||||
|
||||
// horizontal line
|
||||
pmp.setPen( QPen( gridColor(), 1 ) );
|
||||
pmp.drawLine( 0, h-1, w*2, h-1 );
|
||||
|
||||
pmp.end();
|
||||
|
||||
// Force redraw
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Adds a trackContentObjectView to this widget.
|
||||
*
|
||||
* Adds a(nother) trackContentObjectView to our list of views. We also
|
||||
* check that our position is up-to-date.
|
||||
*
|
||||
* \param tcov The trackContentObjectView to add.
|
||||
*/
|
||||
void TrackContentWidget::addTCOView( TrackContentObjectView * tcov )
|
||||
{
|
||||
TrackContentObject * tco = tcov->getTrackContentObject();
|
||||
|
||||
m_tcoViews.push_back( tcov );
|
||||
|
||||
tco->saveJournallingState( false );
|
||||
changePosition();
|
||||
tco->restoreJournallingState();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Removes the given trackContentObjectView to this widget.
|
||||
*
|
||||
* Removes the given trackContentObjectView from our list of views.
|
||||
*
|
||||
* \param tcov The trackContentObjectView to add.
|
||||
*/
|
||||
void TrackContentWidget::removeTCOView( TrackContentObjectView * tcov )
|
||||
{
|
||||
tcoViewVector::iterator it = std::find( m_tcoViews.begin(),
|
||||
m_tcoViews.end(),
|
||||
tcov );
|
||||
if( it != m_tcoViews.end() )
|
||||
{
|
||||
m_tcoViews.erase( it );
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Update ourselves by updating all the tCOViews attached.
|
||||
*
|
||||
*/
|
||||
void TrackContentWidget::update()
|
||||
{
|
||||
for( tcoViewVector::iterator it = m_tcoViews.begin();
|
||||
it != m_tcoViews.end(); ++it )
|
||||
{
|
||||
( *it )->setFixedHeight( height() - 1 );
|
||||
( *it )->update();
|
||||
}
|
||||
QWidget::update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// resposible for moving track-content-widgets to appropriate position after
|
||||
// change of visible viewport
|
||||
/*! \brief Move the trackContentWidget to a new place in time
|
||||
*
|
||||
* \param newPos The MIDI time to move to.
|
||||
*/
|
||||
void TrackContentWidget::changePosition( const TimePos & newPos )
|
||||
{
|
||||
if( m_trackView->trackContainerView() == gui->getBBEditor()->trackContainerView() )
|
||||
{
|
||||
const int curBB = Engine::getBBTrackContainer()->currentBB();
|
||||
setUpdatesEnabled( false );
|
||||
|
||||
// first show TCO for current BB...
|
||||
for( tcoViewVector::iterator it = m_tcoViews.begin();
|
||||
it != m_tcoViews.end(); ++it )
|
||||
{
|
||||
if( ( *it )->getTrackContentObject()->
|
||||
startPosition().getBar() == curBB )
|
||||
{
|
||||
( *it )->move( 0, ( *it )->y() );
|
||||
( *it )->raise();
|
||||
( *it )->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
( *it )->lower();
|
||||
}
|
||||
}
|
||||
// ...then hide others to avoid flickering
|
||||
for( tcoViewVector::iterator it = m_tcoViews.begin();
|
||||
it != m_tcoViews.end(); ++it )
|
||||
{
|
||||
if( ( *it )->getTrackContentObject()->
|
||||
startPosition().getBar() != curBB )
|
||||
{
|
||||
( *it )->hide();
|
||||
}
|
||||
}
|
||||
setUpdatesEnabled( true );
|
||||
return;
|
||||
}
|
||||
|
||||
TimePos pos = newPos;
|
||||
if( pos < 0 )
|
||||
{
|
||||
pos = m_trackView->trackContainerView()->currentPosition();
|
||||
}
|
||||
|
||||
const int begin = pos;
|
||||
const int end = endPosition( pos );
|
||||
const float ppb = m_trackView->trackContainerView()->pixelsPerBar();
|
||||
|
||||
setUpdatesEnabled( false );
|
||||
for( tcoViewVector::iterator it = m_tcoViews.begin();
|
||||
it != m_tcoViews.end(); ++it )
|
||||
{
|
||||
TrackContentObjectView * tcov = *it;
|
||||
TrackContentObject * tco = tcov->getTrackContentObject();
|
||||
|
||||
tco->changeLength( tco->length() );
|
||||
|
||||
const int ts = tco->startPosition();
|
||||
const int te = tco->endPosition()-3;
|
||||
if( ( ts >= begin && ts <= end ) ||
|
||||
( te >= begin && te <= end ) ||
|
||||
( ts <= begin && te >= end ) )
|
||||
{
|
||||
tcov->move( static_cast<int>( ( ts - begin ) * ppb /
|
||||
TimePos::ticksPerBar() ),
|
||||
tcov->y() );
|
||||
if( !tcov->isVisible() )
|
||||
{
|
||||
tcov->show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tcov->move( -tcov->width()-10, tcov->y() );
|
||||
}
|
||||
}
|
||||
setUpdatesEnabled( true );
|
||||
|
||||
// redraw background
|
||||
// update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Return the position of the trackContentWidget in bars.
|
||||
*
|
||||
* \param mouseX the mouse's current X position in pixels.
|
||||
*/
|
||||
TimePos TrackContentWidget::getPosition( int mouseX )
|
||||
{
|
||||
TrackContainerView * tv = m_trackView->trackContainerView();
|
||||
return TimePos( tv->currentPosition() +
|
||||
mouseX *
|
||||
TimePos::ticksPerBar() /
|
||||
static_cast<int>( tv->pixelsPerBar() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Respond to a drag enter event on the trackContentWidget
|
||||
*
|
||||
* \param dee the Drag Enter Event to respond to
|
||||
*/
|
||||
void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee )
|
||||
{
|
||||
TimePos tcoPos = getPosition( dee->pos().x() );
|
||||
if( canPasteSelection( tcoPos, dee ) == false )
|
||||
{
|
||||
dee->ignore();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringPairDrag::processDragEnterEvent( dee, "tco_" +
|
||||
QString::number( getTrack()->type() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Returns whether a selection of TCOs can be pasted into this
|
||||
*
|
||||
* \param tcoPos the position of the TCO slot being pasted on
|
||||
* \param de the DropEvent generated
|
||||
*/
|
||||
bool TrackContentWidget::canPasteSelection( TimePos tcoPos, const QDropEvent* de )
|
||||
{
|
||||
const QMimeData * mimeData = de->mimeData();
|
||||
|
||||
// If the source of the DropEvent is the current instance of LMMS we don't allow pasting in the same bar
|
||||
// if it's another instance of LMMS we allow it
|
||||
return de->source()
|
||||
? canPasteSelection( tcoPos, mimeData )
|
||||
: canPasteSelection( tcoPos, mimeData, true );
|
||||
}
|
||||
|
||||
// Overloaded method to make it possible to call this method without a Drag&Drop event
|
||||
bool TrackContentWidget::canPasteSelection( TimePos tcoPos, const QMimeData* md , bool allowSameBar )
|
||||
{
|
||||
// For decodeKey() and decodeValue()
|
||||
using namespace Clipboard;
|
||||
|
||||
Track * t = getTrack();
|
||||
QString type = decodeKey( md );
|
||||
QString value = decodeValue( md );
|
||||
|
||||
// We can only paste into tracks of the same type
|
||||
if( type != ( "tco_" + QString::number( t->type() ) ) ||
|
||||
m_trackView->trackContainerView()->fixedTCOs() == true )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// value contains XML needed to reconstruct TCOs and place them
|
||||
DataFile dataFile( value.toUtf8() );
|
||||
|
||||
// Extract the metadata and which TCO was grabbed
|
||||
QDomElement metadata = dataFile.content().firstChildElement( "copyMetadata" );
|
||||
QDomAttr tcoPosAttr = metadata.attributeNode( "grabbedTCOPos" );
|
||||
TimePos grabbedTCOPos = tcoPosAttr.value().toInt();
|
||||
TimePos grabbedTCOBar = TimePos( grabbedTCOPos.getBar(), 0 );
|
||||
|
||||
// Extract the track index that was originally clicked
|
||||
QDomAttr tiAttr = metadata.attributeNode( "initialTrackIndex" );
|
||||
const int initialTrackIndex = tiAttr.value().toInt();
|
||||
|
||||
// Get the current track's index
|
||||
const TrackContainer::TrackList tracks = t->trackContainer()->tracks();
|
||||
const int currentTrackIndex = tracks.indexOf( t );
|
||||
|
||||
// Don't paste if we're on the same bar and allowSameBar is false
|
||||
auto sourceTrackContainerId = metadata.attributeNode( "trackContainerId" ).value().toUInt();
|
||||
if( !allowSameBar && sourceTrackContainerId == t->trackContainer()->id() &&
|
||||
tcoPos == grabbedTCOBar && currentTrackIndex == initialTrackIndex )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract the tco data
|
||||
QDomElement tcoParent = dataFile.content().firstChildElement( "tcos" );
|
||||
QDomNodeList tcoNodes = tcoParent.childNodes();
|
||||
|
||||
// Determine if all the TCOs will land on a valid track
|
||||
for( int i = 0; i < tcoNodes.length(); i++ )
|
||||
{
|
||||
QDomElement tcoElement = tcoNodes.item( i ).toElement();
|
||||
int trackIndex = tcoElement.attributeNode( "trackIndex" ).value().toInt();
|
||||
int finalTrackIndex = trackIndex + currentTrackIndex - initialTrackIndex;
|
||||
|
||||
// Track must be in TrackContainer's tracks
|
||||
if( finalTrackIndex < 0 || finalTrackIndex >= tracks.size() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Track must be of the same type
|
||||
auto startTrackType = tcoElement.attributeNode("trackType").value().toInt();
|
||||
Track * endTrack = tracks.at( finalTrackIndex );
|
||||
if( startTrackType != endTrack->type() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! \brief Pastes a selection of TCOs onto the track
|
||||
*
|
||||
* \param tcoPos the position of the TCO slot being pasted on
|
||||
* \param de the DropEvent generated
|
||||
*/
|
||||
bool TrackContentWidget::pasteSelection( TimePos tcoPos, QDropEvent * de )
|
||||
{
|
||||
const QMimeData * mimeData = de->mimeData();
|
||||
|
||||
if( canPasteSelection( tcoPos, de ) == false )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// We set skipSafetyCheck to true because we already called canPasteSelection
|
||||
return pasteSelection( tcoPos, mimeData, true );
|
||||
}
|
||||
|
||||
// Overloaded method so we can call it without a Drag&Drop event
|
||||
bool TrackContentWidget::pasteSelection( TimePos tcoPos, const QMimeData * md, bool skipSafetyCheck )
|
||||
{
|
||||
// For decodeKey() and decodeValue()
|
||||
using namespace Clipboard;
|
||||
|
||||
// When canPasteSelection was already called before, skipSafetyCheck will skip this
|
||||
if( !skipSafetyCheck && canPasteSelection( tcoPos, md ) == false )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QString type = decodeKey( md );
|
||||
QString value = decodeValue( md );
|
||||
|
||||
getTrack()->addJournalCheckPoint();
|
||||
|
||||
// value contains XML needed to reconstruct TCOs and place them
|
||||
DataFile dataFile( value.toUtf8() );
|
||||
|
||||
// Extract the tco data
|
||||
QDomElement tcoParent = dataFile.content().firstChildElement( "tcos" );
|
||||
QDomNodeList tcoNodes = tcoParent.childNodes();
|
||||
|
||||
// Extract the track index that was originally clicked
|
||||
QDomElement metadata = dataFile.content().firstChildElement( "copyMetadata" );
|
||||
QDomAttr tiAttr = metadata.attributeNode( "initialTrackIndex" );
|
||||
int initialTrackIndex = tiAttr.value().toInt();
|
||||
QDomAttr tcoPosAttr = metadata.attributeNode( "grabbedTCOPos" );
|
||||
TimePos grabbedTCOPos = tcoPosAttr.value().toInt();
|
||||
|
||||
// Snap the mouse position to the beginning of the dropped bar, in ticks
|
||||
const TrackContainer::TrackList tracks = getTrack()->trackContainer()->tracks();
|
||||
const int currentTrackIndex = tracks.indexOf( getTrack() );
|
||||
|
||||
bool wasSelection = m_trackView->trackContainerView()->rubberBand()->selectedObjects().count();
|
||||
|
||||
// Unselect the old group
|
||||
const QVector<selectableObject *> so =
|
||||
m_trackView->trackContainerView()->selectedObjects();
|
||||
for( QVector<selectableObject *>::const_iterator it = so.begin();
|
||||
it != so.end(); ++it )
|
||||
{
|
||||
( *it )->setSelected( false );
|
||||
}
|
||||
|
||||
|
||||
// TODO -- Need to draw the hovericon either way, or ghost the TCOs
|
||||
// onto their final position.
|
||||
|
||||
float snapSize = gui->songEditor()->m_editor->getSnapSize();
|
||||
// All patterns should be offset the same amount as the grabbed pattern
|
||||
TimePos offset = TimePos(tcoPos - grabbedTCOPos);
|
||||
// Users expect clips to "fall" backwards, so bias the offset
|
||||
offset = offset - TimePos::ticksPerBar() * snapSize / 2;
|
||||
// The offset is quantized (rather than the positions) to preserve fine adjustments
|
||||
offset = offset.quantize(snapSize);
|
||||
|
||||
// Get the leftmost TCO and fix the offset if it reaches below bar 0
|
||||
TimePos leftmostPos = grabbedTCOPos;
|
||||
for(int i = 0; i < tcoNodes.length(); ++i)
|
||||
{
|
||||
QDomElement outerTCOElement = tcoNodes.item(i).toElement();
|
||||
QDomElement tcoElement = outerTCOElement.firstChildElement();
|
||||
|
||||
TimePos pos = tcoElement.attributeNode("pos").value().toInt();
|
||||
|
||||
if(pos < leftmostPos) { leftmostPos = pos; }
|
||||
}
|
||||
// Fix offset if it sets the left most TCO to a negative position
|
||||
offset = std::max(offset.getTicks(), -leftmostPos.getTicks());
|
||||
|
||||
for( int i = 0; i<tcoNodes.length(); i++ )
|
||||
{
|
||||
QDomElement outerTCOElement = tcoNodes.item( i ).toElement();
|
||||
QDomElement tcoElement = outerTCOElement.firstChildElement();
|
||||
|
||||
int trackIndex = outerTCOElement.attributeNode( "trackIndex" ).value().toInt();
|
||||
int finalTrackIndex = trackIndex + ( currentTrackIndex - initialTrackIndex );
|
||||
Track * t = tracks.at( finalTrackIndex );
|
||||
|
||||
// The new position is the old position plus the offset.
|
||||
TimePos pos = tcoElement.attributeNode( "pos" ).value().toInt() + offset;
|
||||
// If we land on ourselves, offset by one snap
|
||||
TimePos shift = TimePos::ticksPerBar() * gui->songEditor()->m_editor->getSnapSize();
|
||||
if (offset == 0) { pos += shift; }
|
||||
|
||||
TrackContentObject * tco = t->createTCO( pos );
|
||||
tco->restoreState( tcoElement );
|
||||
tco->movePosition(pos); // Because we restored the state, we need to move the TCO again.
|
||||
if( wasSelection )
|
||||
{
|
||||
tco->selectViewOnCreate( true );
|
||||
}
|
||||
}
|
||||
|
||||
AutomationPattern::resolveAllIDs();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Respond to a drop event on the trackContentWidget
|
||||
*
|
||||
* \param de the Drop Event to respond to
|
||||
*/
|
||||
void TrackContentWidget::dropEvent( QDropEvent * de )
|
||||
{
|
||||
TimePos tcoPos = TimePos( getPosition( de->pos().x() ) );
|
||||
if( pasteSelection( tcoPos, de ) == true )
|
||||
{
|
||||
de->accept();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Respond to a mouse press on the trackContentWidget
|
||||
*
|
||||
* \param me the mouse press event to respond to
|
||||
*/
|
||||
void TrackContentWidget::mousePressEvent( QMouseEvent * me )
|
||||
{
|
||||
if( m_trackView->trackContainerView()->allowRubberband() == true )
|
||||
{
|
||||
QWidget::mousePressEvent( me );
|
||||
}
|
||||
else if( me->modifiers() & Qt::ShiftModifier )
|
||||
{
|
||||
QWidget::mousePressEvent( me );
|
||||
}
|
||||
else if( me->button() == Qt::LeftButton &&
|
||||
!m_trackView->trackContainerView()->fixedTCOs() )
|
||||
{
|
||||
QVector<selectableObject*> so = m_trackView->trackContainerView()->rubberBand()->selectedObjects();
|
||||
for( int i = 0; i < so.count(); ++i )
|
||||
{
|
||||
so.at( i )->setSelected( false);
|
||||
}
|
||||
getTrack()->addJournalCheckPoint();
|
||||
const TimePos pos = getPosition( me->x() ).getBar() *
|
||||
TimePos::ticksPerBar();
|
||||
getTrack()->createTCO(pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Repaint the trackContentWidget on command
|
||||
*
|
||||
* \param pe the Paint Event to respond to
|
||||
*/
|
||||
void TrackContentWidget::paintEvent( QPaintEvent * pe )
|
||||
{
|
||||
// Assume even-pixels-per-bar. Makes sense, should be like this anyways
|
||||
const TrackContainerView * tcv = m_trackView->trackContainerView();
|
||||
int ppb = static_cast<int>( tcv->pixelsPerBar() );
|
||||
QPainter p( this );
|
||||
// Don't draw background on BB-Editor
|
||||
if( m_trackView->trackContainerView() != gui->getBBEditor()->trackContainerView() )
|
||||
{
|
||||
p.drawTiledPixmap( rect(), m_background, QPoint(
|
||||
tcv->currentPosition().getBar() * ppb, 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Updates the background tile pixmap on size changes.
|
||||
*
|
||||
* \param resizeEvent the resize event to pass to base class
|
||||
*/
|
||||
void TrackContentWidget::resizeEvent( QResizeEvent * resizeEvent )
|
||||
{
|
||||
// Update backgroud
|
||||
updateBackground();
|
||||
// Force redraw
|
||||
QWidget::resizeEvent( resizeEvent );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Return the track shown by the trackContentWidget
|
||||
*
|
||||
*/
|
||||
Track * TrackContentWidget::getTrack()
|
||||
{
|
||||
return m_trackView->getTrack();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Return the end position of the trackContentWidget in Bars.
|
||||
*
|
||||
* \param posStart the starting position of the Widget (from getPosition())
|
||||
*/
|
||||
TimePos TrackContentWidget::endPosition( const TimePos & posStart )
|
||||
{
|
||||
const float ppb = m_trackView->trackContainerView()->pixelsPerBar();
|
||||
const int w = width();
|
||||
return posStart + static_cast<int>( w * TimePos::ticksPerBar() / ppb );
|
||||
}
|
||||
|
||||
void TrackContentWidget::contextMenuEvent( QContextMenuEvent * cme )
|
||||
{
|
||||
// For hasFormat(), MimeType enum class and getMimeData()
|
||||
using namespace Clipboard;
|
||||
|
||||
if( cme->modifiers() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If we don't have TCO data in the clipboard there's no need to create this menu
|
||||
// since "paste" is the only action at the moment.
|
||||
if( ! hasFormat( MimeType::StringPair ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QMenu contextMenu( this );
|
||||
QAction *pasteA = contextMenu.addAction( embed::getIconPixmap( "edit_paste" ),
|
||||
tr( "Paste" ), [this, cme](){ contextMenuAction( cme, Paste ); } );
|
||||
// If we can't paste in the current TCW for some reason, disable the action so the user knows
|
||||
pasteA->setEnabled( canPasteSelection( getPosition( cme->x() ), getMimeData() ) ? true : false );
|
||||
|
||||
contextMenu.exec( QCursor::pos() );
|
||||
}
|
||||
|
||||
void TrackContentWidget::contextMenuAction( QContextMenuEvent * cme, ContextMenuAction action )
|
||||
{
|
||||
// For getMimeData()
|
||||
using namespace Clipboard;
|
||||
|
||||
switch( action )
|
||||
{
|
||||
case Paste:
|
||||
// Paste the selection on the TimePos of the context menu event
|
||||
TimePos tcoPos = getPosition( cme->x() );
|
||||
|
||||
pasteSelection( tcoPos, getMimeData() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// qproperty access methods
|
||||
//! \brief CSS theming qproperty access method
|
||||
QBrush TrackContentWidget::darkerColor() const
|
||||
{ return m_darkerColor; }
|
||||
|
||||
//! \brief CSS theming qproperty access method
|
||||
QBrush TrackContentWidget::lighterColor() const
|
||||
{ return m_lighterColor; }
|
||||
|
||||
//! \brief CSS theming qproperty access method
|
||||
QBrush TrackContentWidget::gridColor() const
|
||||
{ return m_gridColor; }
|
||||
|
||||
//! \brief CSS theming qproperty access method
|
||||
QBrush TrackContentWidget::embossColor() const
|
||||
{ return m_embossColor; }
|
||||
|
||||
//! \brief CSS theming qproperty access method
|
||||
void TrackContentWidget::setDarkerColor( const QBrush & c )
|
||||
{ m_darkerColor = c; }
|
||||
|
||||
//! \brief CSS theming qproperty access method
|
||||
void TrackContentWidget::setLighterColor( const QBrush & c )
|
||||
{ m_lighterColor = c; }
|
||||
|
||||
//! \brief CSS theming qproperty access method
|
||||
void TrackContentWidget::setGridColor( const QBrush & c )
|
||||
{ m_gridColor = c; }
|
||||
|
||||
//! \brief CSS theming qproperty access method
|
||||
void TrackContentWidget::setEmbossColor( const QBrush & c )
|
||||
{ m_embossColor = c; }
|
||||
|
||||
353
src/gui/widgets/TrackOperationsWidget.cpp
Normal file
353
src/gui/widgets/TrackOperationsWidget.cpp
Normal file
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* TrackOperationsWidget.cpp - implementation of TrackOperationsWidget class
|
||||
*
|
||||
* Copyright (c) 2004-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 "TrackOperationsWidget.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "AutomationPattern.h"
|
||||
#include "AutomationTrack.h"
|
||||
#include "ColorChooser.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "DataFile.h"
|
||||
#include "embed.h"
|
||||
#include "Engine.h"
|
||||
#include "gui_templates.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "PixmapButton.h"
|
||||
#include "Song.h"
|
||||
#include "StringPairDrag.h"
|
||||
#include "ToolTip.h"
|
||||
#include "Track.h"
|
||||
#include "TrackContainerView.h"
|
||||
#include "TrackView.h"
|
||||
|
||||
/*! \brief Create a new trackOperationsWidget
|
||||
*
|
||||
* The trackOperationsWidget is the grip and the mute button of a track.
|
||||
*
|
||||
* \param parent the trackView to contain this widget
|
||||
*/
|
||||
TrackOperationsWidget::TrackOperationsWidget( TrackView * parent ) :
|
||||
QWidget( parent ), /*!< The parent widget */
|
||||
m_trackView( parent ) /*!< The parent track view */
|
||||
{
|
||||
ToolTip::add( this, tr( "Press <%1> while clicking on move-grip "
|
||||
"to begin a new drag'n'drop action." ).arg(UI_CTRL_KEY) );
|
||||
|
||||
QMenu * toMenu = new QMenu( this );
|
||||
toMenu->setFont( pointSize<9>( toMenu->font() ) );
|
||||
connect( toMenu, SIGNAL( aboutToShow() ), this, SLOT( updateMenu() ) );
|
||||
|
||||
|
||||
setObjectName( "automationEnabled" );
|
||||
|
||||
|
||||
m_trackOps = new QPushButton( this );
|
||||
m_trackOps->move( 12, 1 );
|
||||
m_trackOps->setFocusPolicy( Qt::NoFocus );
|
||||
m_trackOps->setMenu( toMenu );
|
||||
ToolTip::add( m_trackOps, tr( "Actions" ) );
|
||||
|
||||
|
||||
m_muteBtn = new PixmapButton( this, tr( "Mute" ) );
|
||||
m_muteBtn->setActiveGraphic( embed::getIconPixmap( "led_off" ) );
|
||||
m_muteBtn->setInactiveGraphic( embed::getIconPixmap( "led_green" ) );
|
||||
m_muteBtn->setCheckable( true );
|
||||
|
||||
m_soloBtn = new PixmapButton( this, tr( "Solo" ) );
|
||||
m_soloBtn->setActiveGraphic( embed::getIconPixmap( "led_red" ) );
|
||||
m_soloBtn->setInactiveGraphic( embed::getIconPixmap( "led_off" ) );
|
||||
m_soloBtn->setCheckable( true );
|
||||
|
||||
if( ConfigManager::inst()->value( "ui",
|
||||
"compacttrackbuttons" ).toInt() )
|
||||
{
|
||||
m_muteBtn->move( 46, 0 );
|
||||
m_soloBtn->move( 46, 16 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_muteBtn->move( 46, 8 );
|
||||
m_soloBtn->move( 62, 8 );
|
||||
}
|
||||
|
||||
m_muteBtn->show();
|
||||
ToolTip::add( m_muteBtn, tr( "Mute" ) );
|
||||
|
||||
m_soloBtn->show();
|
||||
ToolTip::add( m_soloBtn, tr( "Solo" ) );
|
||||
|
||||
connect( this, SIGNAL( trackRemovalScheduled( TrackView * ) ),
|
||||
m_trackView->trackContainerView(),
|
||||
SLOT( deleteTrackView( TrackView * ) ),
|
||||
Qt::QueuedConnection );
|
||||
|
||||
connect( m_trackView->getTrack()->getMutedModel(), SIGNAL( dataChanged() ),
|
||||
this, SLOT( update() ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Destroy an existing trackOperationsWidget
|
||||
*
|
||||
*/
|
||||
TrackOperationsWidget::~TrackOperationsWidget()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Respond to trackOperationsWidget mouse events
|
||||
*
|
||||
* If it's the left mouse button, and Ctrl is held down, and we're
|
||||
* not a Beat+Bassline Editor track, then start a new drag event to
|
||||
* copy this track.
|
||||
*
|
||||
* Otherwise, ignore all other events.
|
||||
*
|
||||
* \param me The mouse event to respond to.
|
||||
*/
|
||||
void TrackOperationsWidget::mousePressEvent( QMouseEvent * me )
|
||||
{
|
||||
if( me->button() == Qt::LeftButton &&
|
||||
me->modifiers() & Qt::ControlModifier &&
|
||||
m_trackView->getTrack()->type() != Track::BBTrack )
|
||||
{
|
||||
DataFile dataFile( DataFile::DragNDropData );
|
||||
m_trackView->getTrack()->saveState( dataFile, dataFile.content() );
|
||||
new StringPairDrag( QString( "track_%1" ).arg(
|
||||
m_trackView->getTrack()->type() ),
|
||||
dataFile.toString(), m_trackView->getTrackSettingsWidget()->grab(),
|
||||
this );
|
||||
}
|
||||
else if( me->button() == Qt::LeftButton )
|
||||
{
|
||||
// track-widget (parent-widget) initiates track-move
|
||||
me->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Repaint the trackOperationsWidget
|
||||
*
|
||||
* If we're not moving, and in the Beat+Bassline Editor, then turn
|
||||
* automation on or off depending on its previous state and show
|
||||
* ourselves.
|
||||
*
|
||||
* Otherwise, hide ourselves.
|
||||
*
|
||||
* \todo Flesh this out a bit - is it correct?
|
||||
* \param pe The paint event to respond to
|
||||
*/
|
||||
void TrackOperationsWidget::paintEvent( QPaintEvent * pe )
|
||||
{
|
||||
QPainter p( this );
|
||||
|
||||
p.fillRect( rect(), palette().brush(QPalette::Background) );
|
||||
|
||||
if( m_trackView->getTrack()->useColor() && ! m_trackView->getTrack()->getMutedModel()->value() )
|
||||
{
|
||||
QRect coloredRect( 0, 0, 10, m_trackView->getTrack()->getHeight() );
|
||||
|
||||
p.fillRect( coloredRect, m_trackView->getTrack()->color() );
|
||||
}
|
||||
|
||||
if( m_trackView->isMovingTrack() == false )
|
||||
{
|
||||
p.drawPixmap( 2, 2, embed::getIconPixmap("track_op_grip"));
|
||||
}
|
||||
else
|
||||
{
|
||||
p.drawPixmap( 2, 2, embed::getIconPixmap("track_op_grip_c"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Clone this track
|
||||
*
|
||||
*/
|
||||
void TrackOperationsWidget::cloneTrack()
|
||||
{
|
||||
TrackContainerView *tcView = m_trackView->trackContainerView();
|
||||
|
||||
Track *newTrack = m_trackView->getTrack()->clone();
|
||||
TrackView *newTrackView = tcView->createTrackView( newTrack );
|
||||
|
||||
int index = tcView->trackViews().indexOf( m_trackView );
|
||||
int i = tcView->trackViews().size();
|
||||
while ( i != index + 1 )
|
||||
{
|
||||
tcView->moveTrackView( newTrackView, i - 1 );
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Clear this track - clears all TCOs from the track */
|
||||
void TrackOperationsWidget::clearTrack()
|
||||
{
|
||||
Track * t = m_trackView->getTrack();
|
||||
t->addJournalCheckPoint();
|
||||
t->lock();
|
||||
t->deleteTCOs();
|
||||
t->unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*! \brief Remove this track from the track list
|
||||
*
|
||||
*/
|
||||
void TrackOperationsWidget::removeTrack()
|
||||
{
|
||||
emit trackRemovalScheduled( m_trackView );
|
||||
}
|
||||
|
||||
void TrackOperationsWidget::changeTrackColor()
|
||||
{
|
||||
QColor new_color = ColorChooser( this ).withPalette( ColorChooser::Palette::Track )-> \
|
||||
getColor( m_trackView->getTrack()->color() );
|
||||
|
||||
if( ! new_color.isValid() )
|
||||
{ return; }
|
||||
|
||||
emit colorChanged( new_color );
|
||||
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
}
|
||||
|
||||
void TrackOperationsWidget::resetTrackColor()
|
||||
{
|
||||
emit colorReset();
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
}
|
||||
|
||||
void TrackOperationsWidget::randomTrackColor()
|
||||
{
|
||||
QColor buffer = ColorChooser::getPalette( ColorChooser::Palette::Track )[ rand() % 48 ];
|
||||
|
||||
emit colorChanged( buffer );
|
||||
Engine::getSong()->setModified();
|
||||
update();
|
||||
}
|
||||
|
||||
void TrackOperationsWidget::useTrackColor()
|
||||
{
|
||||
emit colorParented();
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Update the trackOperationsWidget context menu
|
||||
*
|
||||
* For all track types, we have the Clone and Remove options.
|
||||
* For instrument-tracks we also offer the MIDI-control-menu
|
||||
* For automation tracks, extra options: turn on/off recording
|
||||
* on all TCOs (same should be added for sample tracks when
|
||||
* sampletrack recording is implemented)
|
||||
*/
|
||||
void TrackOperationsWidget::updateMenu()
|
||||
{
|
||||
QMenu * toMenu = m_trackOps->menu();
|
||||
toMenu->clear();
|
||||
toMenu->addAction( embed::getIconPixmap( "edit_copy", 16, 16 ),
|
||||
tr( "Clone this track" ),
|
||||
this, SLOT( cloneTrack() ) );
|
||||
toMenu->addAction( embed::getIconPixmap( "cancel", 16, 16 ),
|
||||
tr( "Remove this track" ),
|
||||
this, SLOT( removeTrack() ) );
|
||||
|
||||
if( ! m_trackView->trackContainerView()->fixedTCOs() )
|
||||
{
|
||||
toMenu->addAction( tr( "Clear this track" ), this, SLOT( clearTrack() ) );
|
||||
}
|
||||
if (QMenu *fxMenu = m_trackView->createFxMenu(tr("FX %1: %2"), tr("Assign to new FX Channel")))
|
||||
{
|
||||
toMenu->addMenu(fxMenu);
|
||||
}
|
||||
|
||||
if (InstrumentTrackView * trackView = dynamic_cast<InstrumentTrackView *>(m_trackView))
|
||||
{
|
||||
toMenu->addSeparator();
|
||||
toMenu->addMenu(trackView->midiMenu());
|
||||
}
|
||||
if( dynamic_cast<AutomationTrackView *>( m_trackView ) )
|
||||
{
|
||||
toMenu->addAction( tr( "Turn all recording on" ), this, SLOT( recordingOn() ) );
|
||||
toMenu->addAction( tr( "Turn all recording off" ), this, SLOT( recordingOff() ) );
|
||||
}
|
||||
|
||||
toMenu->addSeparator();
|
||||
toMenu->addAction( embed::getIconPixmap( "colorize" ),
|
||||
tr( "Change color" ), this, SLOT( changeTrackColor() ) );
|
||||
toMenu->addAction( embed::getIconPixmap( "colorize" ),
|
||||
tr( "Reset color to default" ), this, SLOT( resetTrackColor() ) );
|
||||
toMenu->addAction( embed::getIconPixmap( "colorize" ),
|
||||
tr( "Set random color" ), this, SLOT( randomTrackColor() ) );
|
||||
toMenu->addSeparator();
|
||||
toMenu->addAction( embed::getIconPixmap( "colorize" ),
|
||||
tr( "Clear clip colors" ), this, SLOT( useTrackColor() ) );
|
||||
}
|
||||
|
||||
|
||||
void TrackOperationsWidget::toggleRecording( bool on )
|
||||
{
|
||||
AutomationTrackView * atv = dynamic_cast<AutomationTrackView *>( m_trackView );
|
||||
if( atv )
|
||||
{
|
||||
for( TrackContentObject * tco : atv->getTrack()->getTCOs() )
|
||||
{
|
||||
AutomationPattern * ap = dynamic_cast<AutomationPattern *>( tco );
|
||||
if( ap ) { ap->setRecording( on ); }
|
||||
}
|
||||
atv->update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TrackOperationsWidget::recordingOn()
|
||||
{
|
||||
toggleRecording( true );
|
||||
}
|
||||
|
||||
|
||||
void TrackOperationsWidget::recordingOff()
|
||||
{
|
||||
toggleRecording( false );
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
*/
|
||||
#include "BBTrack.h"
|
||||
|
||||
#include <QDomElement>
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "CaptionMenu.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "ControllerConnection.h"
|
||||
#include "DataFile.h"
|
||||
#include "EffectChain.h"
|
||||
#include "EffectRackView.h"
|
||||
#include "embed.h"
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
#include "SampleTrack.h"
|
||||
|
||||
#include <QDomElement>
|
||||
#include <QDropEvent>
|
||||
#include <QFileInfo>
|
||||
#include <QMenu>
|
||||
|
||||
Reference in New Issue
Block a user