61 , m_bUseTriplets( false )
62 , m_pDraggedNote( nullptr )
63 , m_pPatternEditorPanel( panel )
64 , m_pPattern( nullptr )
65 , m_bSelectNewNotes( false )
66 , m_bFineGrained( false )
67 , m_bCopyNotMove( false )
70 , m_mode(
Mode::None )
79 setFocusPolicy(Qt::StrongFocus);
95 qreal pixelRatio = devicePixelRatio();
97 height() * pixelRatio );
113 update( 0, 0, width(), height() );
124 update( 0, 0, width(), height() );
151 float fRed, fGreen, fBlue;
155 QColor fullColor = pPref->getColorTheme()->m_patternEditor_noteVelocityFullColor;
156 QColor defaultColor = pPref->getColorTheme()->m_patternEditor_noteVelocityDefaultColor;
157 QColor halfColor = pPref->getColorTheme()->m_patternEditor_noteVelocityHalfColor;
158 QColor zeroColor = pPref->getColorTheme()->m_patternEditor_noteVelocityZeroColor;
163 float fWeightFull = 0;
164 float fWeightDefault = 0;
165 float fWeightHalf = 0;
166 float fWeightZero = 0;
168 if ( fVelocity >= 1.0 ) {
170 }
else if ( fVelocity >= 0.8 ) {
171 fWeightDefault = ( 1.0 - fVelocity )/ ( 1.0 - 0.8 );
172 fWeightFull = 1.0 - fWeightDefault;
173 }
else if ( fVelocity >= 0.5 ) {
174 fWeightHalf = ( 0.8 - fVelocity )/ ( 0.8 - 0.5 );
175 fWeightDefault = 1.0 - fWeightHalf;
177 fWeightZero = ( 0.5 - fVelocity )/ ( 0.5 );
178 fWeightHalf = 1.0 - fWeightZero;
181 fRed = fWeightFull * fullColor.redF() +
182 fWeightDefault * defaultColor.redF() +
183 fWeightHalf * halfColor.redF() + fWeightZero * zeroColor.redF();
184 fGreen = fWeightFull * fullColor.greenF() +
185 fWeightDefault * defaultColor.greenF() +
186 fWeightHalf * halfColor.greenF() + fWeightZero * zeroColor.greenF();
187 fBlue = fWeightFull * fullColor.blueF() +
188 fWeightDefault * defaultColor.blueF() +
189 fWeightHalf * halfColor.blueF() + fWeightZero * zeroColor.blueF();
192 color.setRedF( fRed );
193 color.setGreenF( fGreen );
194 color.setBlueF( fBlue );
208 const QColor noteColor( pPref->getColorTheme()->m_patternEditor_noteVelocityDefaultColor );
209 const QColor noteInactiveColor( pPref->getColorTheme()->m_windowTextColor.darker( 150 ) );
210 const QColor noteoffColor( pPref->getColorTheme()->m_patternEditor_noteOffColor );
211 const QColor noteoffInactiveColor( pPref->getColorTheme()->m_windowTextColor );
213 p.setRenderHint( QPainter::Antialiasing );
218 uint x_pos = pos.x(), y_pos = pos.y();
224 selectedPen.setWidth( 2 );
225 p.setPen( selectedPen );
226 p.setBrush( Qt::NoBrush );
230 QPen movingPen( noteColor );
234 movingPen.setStyle( Qt::DotLine );
235 movingPen.setWidth( 2 );
244 QBrush noteBrush( color );
245 QPen notePen( noteColor );
246 if ( !bIsForeground ) {
249 noteBrush.setColor( noteInactiveColor );
250 notePen.setColor( noteInactiveColor );
253 noteBrush.setStyle( Qt::Dense4Pattern );
254 notePen.setStyle( Qt::DotLine );
258 p.drawEllipse( x_pos -4 -2, y_pos-2, w+4, h+4 );
271 if ( ppNote !=
nullptr &&
273 ppNote->get_note_off() &&
280 ppNote->get_position() ) {
283 nLength = std::min( ppNote->get_position() - pNote->
get_position(), nLength );
291 p.drawRoundedRect( x_pos-2, y_pos, width+4, 3+4, 4, 4 );
294 p.setBrush( noteBrush );
301 int nRectOnsetX = x_pos;
302 int nRectWidth = width;
303 if ( ! bIsForeground ) {
304 nRectOnsetX = nRectOnsetX + w/2;
305 nRectWidth = nRectWidth - w/2;
308 p.drawRect( nRectOnsetX, y_pos +2, nRectWidth, 3 );
309 p.drawLine( x_pos+width, y_pos, x_pos+width, y_pos + h );
313 p.setBrush( noteBrush );
314 p.drawEllipse( x_pos -4 , y_pos, w, h );
317 p.setPen( movingPen );
318 p.setBrush( Qt::NoBrush );
319 p.drawEllipse( movingOffset.x() + x_pos -4 -2, movingOffset.y() + y_pos -2 , w + 4, h + 4 );
322 p.setPen( movingPen );
323 p.setBrush( Qt::NoBrush );
324 p.drawRoundedRect( movingOffset.x() + x_pos-2, movingOffset.y() + y_pos, width+4, 3+4, 4, 4 );
330 QBrush noteOffBrush( noteoffColor );
331 if ( !bIsForeground ) {
332 noteOffBrush.setStyle( Qt::Dense4Pattern );
335 noteOffBrush.setColor( noteoffInactiveColor );
340 p.drawEllipse( x_pos -4 -2, y_pos-2, w+4, h+4 );
343 p.setPen( Qt::NoPen );
344 p.setBrush( noteOffBrush );
345 p.drawEllipse( x_pos -4 , y_pos, w, h );
348 p.setPen( movingPen );
349 p.setBrush( Qt::NoBrush );
350 p.drawEllipse( movingOffset.x() + x_pos -4 -2, movingOffset.y() + y_pos -2, w + 4, h + 4 );
358 int nGranularity = 1;
364 nColumn = nColumn * nGranularity;
384 auto pInstrumentList = pHydrogen->
getSong()->getInstrumentList();
389 bool bWroteNote =
false;
391 int nLowestPos, nLowestInstrument, nHighestPitch;
395 int nPos = pNote->get_position();
396 int nInstrument = pInstrumentList->index( pNote->get_instrument() );
398 nLowestPos = std::min( nPos, nLowestPos );
399 nLowestInstrument = std::min( nInstrument, nLowestInstrument );
400 nHighestPitch = std::max( nPitch, nHighestPitch );
403 nLowestInstrument = nInstrument;
404 nHighestPitch = nPitch;
408 pNote->save_to( ¬e_node );
412 positionNode.
write_int(
"position", nLowestPos );
413 positionNode.
write_int(
"instrument", nLowestInstrument );
414 positionNode.
write_int(
"note", nHighestPitch );
420 QClipboard *clipboard = QApplication::clipboard();
421 clipboard->setText( doc.toString() );
443 auto pInstrument = pInstrumentList->get( nInstrument );
447 if ( it->second->get_instrument() == pInstrument ) {
486 if ( QKeyEvent *pEv =
dynamic_cast<QKeyEvent*
>( ev ) ) {
489 bool bPressed = ev->type() == QEvent::KeyPress;
490 if ( pEv->key() == Qt::Key_Control ) {
492 }
else if ( pEv->key() == Qt::Key_Alt ) {
502 setCursor( QCursor( Qt::DragCopyCursor ) );
503 }
else if ( !
m_bCopyNotMove && cursor().shape() != Qt::DragMoveCursor ) {
504 setCursor( QCursor( Qt::DragMoveCursor ) );
527 std::set< Note *> duplicates;
528 for (
Note *pNote : elements ) {
529 if ( duplicates.find( pNote ) != duplicates.end() ) {
537 if ( it->second != pNote && pNote->match( it->second ) ) {
538 duplicates.insert( it->second );
542 if ( !duplicates.empty() ) {
548 QString sMsg ( tr(
"Placing these notes here will overwrite %1 duplicate notes." ) );
549 QMessageBox messageBox ( QMessageBox::Warning,
"Hydrogen", sMsg.arg( duplicates.size() ),
550 QMessageBox::Cancel | QMessageBox::Ok,
this );
551 messageBox.setCheckBox(
new QCheckBox( pCommonStrings->getMutableDialog() ) );
552 messageBox.checkBox()->setChecked(
false );
553 bOk = messageBox.exec() == QMessageBox::Ok;
554 if ( messageBox.checkBox()->isChecked() ) {
562 std::vector< Note *>overwritten;
563 for (
Note *pNote : duplicates ) {
564 overwritten.push_back( pNote );
577 std::vector< H2Core::Note *> &overwritten )
587 for (
auto pSelectedNote : selected ) {
589 bool bFoundExact =
false;
590 int nPosition = pSelectedNote->get_position();
591 for (
auto it = pNotes->lower_bound( nPosition ); it != pNotes->end() && it->first == nPosition; ) {
592 Note *pNote = it->second;
597 }
else if ( pSelectedNote->match( pNote ) && pNote->
get_position() == pSelectedNote->get_position() ) {
599 it = pNotes->erase( it );
613 std::vector< H2Core::Note *> &overwritten )
622 for (
auto pNote : overwritten ) {
627 for (
auto pNote : selected ) {
643 std::shared_ptr<Song> pSong = pHydrogen->
getSong();
648 if ( pSong !=
nullptr ) {
649 PatternList *pPatternList = pSong->getPatternList();
666 int x_bias = nQuantX / 2, y_bias = nQuantY / 2;
667 if ( rawOffset.y() < 0 ) {
670 if ( rawOffset.x() < 0 ) {
673 int x_off = (rawOffset.x() + x_bias) / nQuantX;
674 int y_off = (rawOffset.y() + y_bias) / nQuantY;
675 return QPoint( nFactor * x_off, y_off);
683 const std::vector<QColor> colorsActive = {
684 QColor( pPref->getColorTheme()->m_patternEditor_line1Color ),
685 QColor( pPref->getColorTheme()->m_patternEditor_line2Color ),
686 QColor( pPref->getColorTheme()->m_patternEditor_line3Color ),
687 QColor( pPref->getColorTheme()->m_patternEditor_line4Color ),
688 QColor( pPref->getColorTheme()->m_patternEditor_line5Color ),
690 const std::vector<QColor> colorsInactive = {
691 QColor( pPref->getColorTheme()->m_windowTextColor.darker( 170 ) ),
692 QColor( pPref->getColorTheme()->m_windowTextColor.darker( 190 ) ),
693 QColor( pPref->getColorTheme()->m_windowTextColor.darker( 210 ) ),
694 QColor( pPref->getColorTheme()->m_windowTextColor.darker( 230 ) ),
695 QColor( pPref->getColorTheme()->m_windowTextColor.darker( 250 ) ),
719 p.setPen( QPen( colorsActive[ 0 ], 1, style ) );
725 p.setPen( QPen( colorsInactive[ 0 ], 1, style ) );
741 p.setPen( QPen( colorsActive[ std::min( nColour,
static_cast<int>(colorsActive.size()) - 1 ) ],
748 p.setPen( QPen( colorsInactive[ std::min( nColour,
static_cast<int>(colorsInactive.size()) - 1 ) ],
764 p.setPen( QPen( colorsActive[ 0 ], 1, style ) );
770 p.setPen( QPen( colorsInactive[ 0 ], 1, style ) );
778 p.setPen( QPen( colorsActive[ 2 ], 1, style ) );
785 p.setPen( QPen( colorsInactive[ 2 ], 1, style ) );
801 const QColor selectHighlightColor( pPref->getColorTheme()->m_selectionHighlightColor );
802 return selectHighlightColor;
804 const QColor selectInactiveColor( pPref->getColorTheme()->m_selectionInactiveColor );
805 return selectInactiveColor;
820 std::set<Note *> valid;
821 std::vector< Note *> invalidated;
824 valid.insert( it->second );
828 if ( valid.find(i) == valid.end()) {
831 invalidated.push_back( i );
834 for (
auto i : invalidated ) {
858 if ( ev->reason() == Qt::TabFocusReason || ev->reason() == Qt::BacktabFocusReason ) {
896 std::vector<Pattern *> patterns;
902 if ( ! ( pHydrogen->
getMode() == Song::Mode::Song &&
906 std::set< Pattern *> patternSet;
908 std::vector<const PatternList*> patternLists;
910 if ( pHydrogen->
getPatternMode() == Song::PatternMode::Stacked ) {
914 for (
const PatternList *pPatternList : patternLists ) {
915 for (
int i = 0; i < pPatternList->size(); i++) {
916 Pattern *pPattern = pPatternList->get( i );
918 patternSet.insert( pPattern );
922 for (
Pattern *pPattern : patternSet ) {
923 patterns.push_back( pPattern );
929 pHydrogen->
getMode() == Song::Mode::Song &&
934 for (
const auto ppVirtualPattern : *
m_pPattern ) {
935 patterns.push_back( ppVirtualPattern );
950 if ( pHydrogen->getPatternMode() == Song::PatternMode::Stacked ||
951 ( pPattern !=
nullptr && pPattern->
isVirtual() ) ||
952 ( pHydrogen->getMode() == Song::Mode::Song &&
953 pHydrogen->isPatternEditorLocked() ) ) {
971 if ( pHydrogen->getMode() == Song::Mode::Song &&
973 ! pHydrogen->isPatternEditorLocked() ) {
982 pHydrogen->getAudioEngine()->getPlayingPatterns()->longest_pattern_length(
false ) + 1,
1009 if (
m_nTick == (
int)fTick ) {
1023 update( updateRect );
1024 if ( fDiff > 1.0 || fDiff < -1.0 ) {
1027 updateRect.translate( -fDiff, 0 );
1028 update( updateRect );
1033 if( pNote !=
nullptr ){
1060 bool bOldCursorHidden = pHydrogenApp->hideKeyboardCursor();
1062 pHydrogenApp->setHideKeyboardCursor(
true );
1065 if ( bOldCursorHidden != pHydrogenApp->hideKeyboardCursor() ) {
1071 int nRealColumn = 0;
1073 if ( ev->button() == Qt::RightButton ) {
1076 std::floor(
static_cast<float>(ev->y()) /
static_cast<float>(
m_nGridHeight));
1077 int nSelectedInstrumentNumber = pHydrogen->getSelectedInstrumentNumber();
1081 static_cast<int>(std::floor(
1144 fValue = fValue + (fMoveY / 100);
1148 else if ( fValue < 0.0 ) {
1239 int nSelectedPatternNumber,
1240 int nSelectedInstrumentnumber,
1245 auto pSong = pHydrogen->getSong();
1246 auto pPatternList = pSong->getPatternList();
1249 if ( nSelectedPatternNumber != -1 &&
1250 nSelectedPatternNumber < pPatternList->size() ) {
1251 pPattern = pPatternList->get( nSelectedPatternNumber );
1254 if ( pPattern ==
nullptr ) {
1261 Note* pDraggedNote =
nullptr;
1263 auto pSelectedInstrument =
1264 pSong->getInstrumentList()->get( nSelectedInstrumentnumber );
1265 if ( pSelectedInstrument ==
nullptr ) {
1266 ERRORLOG(
"No instrument selected" );
1273 auto pDraggedNote = pPattern->
find_note( nColumn, nRealColumn,
1274 pSelectedInstrument,
1275 pressedNoteKey, pressedOctave,
1279 auto pSelectedInstrument = pSong->getInstrumentList()->get( nRow );
1280 if ( pSelectedInstrument ==
nullptr ) {
1281 ERRORLOG(
"No instrument selected" );
1284 pDraggedNote = pPattern->
find_note( nColumn, nRealColumn, pSelectedInstrument,
false );
1287 ERRORLOG( QString(
"Unsupported editor [%1]" )
1288 .arg(
static_cast<int>(editor) ) );
1293 if ( pDraggedNote !=
nullptr ){
1299 pHydrogen->setIsModified(
true );
1310 int nSelectedPatternNumber,
1311 int nSelectedInstrumentNumber,
1317 float fProbability )
1321 auto pSong = pHydrogen->getSong();
1322 auto pPatternList = pSong->getPatternList();
1325 if ( nSelectedPatternNumber != -1 &&
1326 nSelectedPatternNumber < pPatternList->size() ) {
1327 pPattern = pPatternList->get( nSelectedPatternNumber );
1330 if ( pPattern ==
nullptr ) {
1337 Note* pDraggedNote =
nullptr;
1340 auto pSelectedInstrument =
1341 pSong->getInstrumentList()->get( nSelectedInstrumentNumber );
1342 if ( pSelectedInstrument ==
nullptr ) {
1343 ERRORLOG(
"No instrument selected" );
1350 pDraggedNote = pPattern->
find_note( nColumn, nRealColumn,
1351 pSelectedInstrument,
1352 pressedNoteKey, pressedOctave,
1356 auto pSelectedInstrument = pSong->getInstrumentList()->get( nRow );
1357 if ( pSelectedInstrument ==
nullptr ) {
1358 ERRORLOG(
"No instrument selected" );
1361 pDraggedNote = pPattern->
find_note( nColumn, nRealColumn, pSelectedInstrument,
false );
1364 ERRORLOG( QString(
"Unsupported editor [%1]" )
1365 .arg(
static_cast<int>(editor) ) );
1370 bool bValueChanged =
true;
1372 if ( pDraggedNote !=
nullptr ){
1378 pDraggedNote->
setPan( fPan );
1387 bValueChanged =
true;
1390 ERRORLOG(
"note could not be found");
1395 if ( bValueChanged &&
1397 pHydrogen->setIsModified(
true );
1423 s = QString(
"Unknown mode [%1]" ).arg(
static_cast<int>(mode) ) ;
1433 QString sUnit( tr(
"ticks" ) );
1439 s = QString( tr(
"Set note velocity" ) )
1440 .append( QString(
": [%1]")
1442 sCaller.append(
":Velocity" );
1450 fValue = pNote->
getPan() * 100;
1451 fValue = std::round( fValue );
1452 fValue = fValue / 100;
1454 if ( fValue > 0.0 ) {
1455 s = QString( tr(
"Note panned to the right by" ) ).
1456 append( QString(
": [%1]" ).arg( fValue / 2, 2,
'f', 2 ) );
1457 }
else if ( fValue < 0.0 ) {
1458 s = QString( tr(
"Note panned to the left by" ) ).
1459 append( QString(
": [%1]" ).arg( -1 * fValue / 2, 2,
'f', 2 ) );
1461 s = QString( tr(
"Note centered" ) );
1463 sCaller.append(
":Pan" );
1470 fValue = std::round( fValue );
1471 fValue = fValue / 100;
1472 if ( fValue < 0.0 ) {
1473 s = QString( tr(
"Leading beat by" ) )
1474 .append( QString(
": [%1] " )
1479 else if ( fValue > 0.0 ) {
1480 s = QString( tr(
"Lagging beat by" ) )
1481 .append( QString(
": [%1] " )
1487 s = tr(
"Note on beat" );
1489 sCaller.append(
":LeadLag" );
1493 s = QString( tr(
"Set pitch" ) ).append(
": " ).append( tr(
"key" ) )
1495 .append( tr(
"octave" ) )
1496 .append( QString(
": [%1]" ).arg( pNote->
get_octave() ) );
1497 sCaller.append(
":NoteKey" );
1502 s = tr(
"Set note probability to" )
1503 .append( QString(
": [%1]" ).arg( pNote->
get_probability(), 2,
'f', 2 ) );
1505 sCaller.append(
":Probability" );
1512 if ( ! s.isEmpty() ) {
#define RIGHT_HERE
Macro intended to be used for the logging of the locking of the H2Core::AudioEngine.
#define FOREACH_NOTE_CST_IT_BOUND_END(_notes, _it, _bound)
Iterate over all notes in column _bound in an immutable way.
#define FOREACH_NOTE_CST_IT_BEGIN_END(_notes, _it)
Iterate over all provided notes in an immutable way.
#define FOREACH_NOTE_CST_IT_BEGIN_LENGTH(_notes, _it, _pattern)
Iterate over all accessible notes between position 0 and length of _pattern in an immutable way.
const PatternList * getNextPatterns() const
void unlock()
Mutex unlocking of the AudioEngine.
void lock(const char *file, unsigned int line, const char *function)
Mutex locking of the AudioEngine.
const PatternList * getPlayingPatterns() const
static double getLeadLagInTicks()
Maximum lead lag factor in ticks.
static const char * _class_name()
return the class name
std::shared_ptr< Song > getSong() const
Get the current song.
int getSelectedInstrumentNumber() const
Song::Mode getMode() const
int getSelectedPatternNumber() const
void setSelectedInstrumentNumber(int nInstrument, bool bTriggerEvent=true)
static Hydrogen * get_instance()
Returns the current Hydrogen instance __instance.
Song::PatternMode getPatternMode() const
AudioEngine * getAudioEngine() const
void setIsModified(bool bIsModified)
Wrapper around Song::setIsModified() that checks whether a song is set.
bool isPatternEditorLocked() const
Convenience function checking whether using the Pattern Editor is locked in the song settings and the...
A note plays an associated instrument with a velocity left and right pan.
int get_position() const
__position accessor
static Key pitchToKey(int nPitch)
void set_length(int value)
__length setter
float getPanWithRangeFrom0To1() const
get pan of the note, scaling and translating the range from [-1;1] to [0;1]
void set_lead_lag(float value)
__lead_lag setter
static QString KeyToQString(Key key)
static Octave pitchToOctave(int nPitch)
Octave get_octave()
__octave accessor
void set_probability(float value)
std::shared_ptr< Instrument > get_instrument()
__instrument accessor
float get_lead_lag() const
__lead_lag accessor
int get_length() const
__length accessor
float get_notekey_pitch() const
note key pitch accessor
float get_velocity() const
__velocity accessor
void setPanWithRangeFrom0To1(float fVal)
set pan of the note, assuming the input range in [0;1]
bool get_note_off() const
__note_off accessor
void setPan(float val)
set pan of the note.
void set_velocity(float value)
__velocity setter
static double pitchToFrequency(double fPitch)
Convert a logarithmic pitch-space value in semitones to a frequency-domain value.
Key get_key()
__key accessor
float get_probability() const
float getPan() const
get pan of the note.
bool match(std::shared_ptr< Instrument > instrument, Key key, Octave octave) const
return true if instrument, key and octave matches with internal
PatternList is a collection of patterns.
int size() const
returns the numbers of patterns
Pattern * get(int idx)
get a pattern from the list
Pattern class is a Note container.
const virtual_patterns_t * get_virtual_patterns() const
get the flattened virtual pattern set
int get_length() const
set the denominator of the pattern
const notes_t * get_notes() const
get the virtual pattern set
std::multimap< int, Note * > notes_t
< multimap note type
Note * find_note(int idx_a, int idx_b, std::shared_ptr< Instrument > instrument, bool strict=true) const
search for a note at a given index within __notes which correspond to the given arguments
bool isVirtual() const
Whether the pattern holds at least one virtual pattern.
int longestVirtualPatternLength() const
void insert_note(Note *note)
insert a new note within __notes
Manager for User Preferences File (singleton)
static Preferences * get_instance()
Returns a pointer to the current Preferences singleton stored in __instance.
void setShowNoteOverwriteWarning(bool bValue)
bool getShowNoteOverwriteWarning()
Changes
Bitwise or-able options showing which part of the Preferences were altered using the PreferencesDialo...
@ Colors
At least one of the colors has changed.
XMLDoc is a subclass of QDomDocument with read and write methods.
XMLNode set_root(const QString &node_name, const QString &xmlns=nullptr)
create the xml header and root node
XMLNode is a subclass of QDomNode with read and write values methods.
XMLNode createNode(const QString &name)
create a new XMLNode that has to be appended into de XMLDoc
void write_int(const QString &node, const int value)
write an integer into a child node
void setHideKeyboardCursor(bool bHidden)
void addEventListener(EventListener *pListener)
static HydrogenApp * get_instance()
Returns the instance of HydrogenApp class.
std::shared_ptr< CommonStrings > getCommonStrings()
QUndoStack * m_pUndoStack
void showStatusBarMessage(const QString &sMessage, const QString &sCaller="")
void preferencesChanged(H2Core::Preferences::Changes changes)
Propagates a change in the Preferences through the GUI.
void repaintInstrumentLines()
NotePropertiesRuler::Mode getNotePropertiesMode() const
void setCursorPosition(int nCursorPosition)
void updateEditors(bool bPatternOnly=false)
PatternEditorInstrumentList * getInstrumentList()
void ensureCursorVisible()
PatternEditorRuler * getPatternEditorRuler()
virtual bool checkDeselectElements(std::vector< SelectionIndex > &elements) override
Deselecting notes.
static QString modeToQString(Mode mode)
virtual void selectInstrumentNotes(int nInstrument)
virtual void mouseDragUpdateEvent(QMouseEvent *ev) override
virtual void mouseMoveEvent(QMouseEvent *ev) override
int lineToPitch(int nLine)
virtual void validateSelection() override
Ensure that the Selection contains only valid elements.
void editNotePropertiesAction(int nColumn, int nRealColumn, int nRow, int nSelectedPatternNumber, int nSelectedInstrumentNumber, Mode mode, Editor editor, float fVelocity, float fPan, float fLeadLag, float fProbability)
void scrolled(int nValue)
int m_nSelectedPatternNumber
static QColor computeNoteColor(float velocity)
Calculate colour to use for note representation based on note velocity.
virtual void mousePressEvent(QMouseEvent *ev) override
Raw Qt mouse events are passed to the Selection.
virtual void updateModifiers(QInputEvent *ev)
Update the status of modifier keys in response to input events.
virtual void selectNone()
int granularity() const
Granularity of grid positioning (in ticks)
static bool isUsingAdditionalPatterns(const H2Core::Pattern *pPattern)
Determines whether to pattern editor should show further patterns (determined by getPattersToShow()) ...
QColor selectedNoteColor() const
Colour to use for outlining selected notes.
virtual void stackedModeActivationEvent(int nValue) override
virtual void deleteSelection()=0
int m_nSelectedInstrumentNumber
Cached properties used when adjusting a note property via right-press mouse movement.
void storeNoteProperties(const H2Core::Note *pNote)
Stores the properties of pNote in member variables.
void updatePosition(float fTick)
Caches the AudioEngine::m_nPatternTickPosition in the member variable m_nTick and triggers an update(...
static void triggerStatusMessage(H2Core::Note *pNote, Mode mode)
void editNoteLengthAction(int nColumn, int nRealColumn, int nRow, int nLength, int nSelectedPatternNumber, int nSelectedInstrumentnumber, Editor editor)
void drawNoteSymbol(QPainter &p, QPoint pos, H2Core::Note *pNote, bool bIsForeground=true) const
Draw a note.
virtual void updateEditor(bool bPatternOnly=false)=0
bool notesMatchExactly(H2Core::Note *pNoteA, H2Core::Note *pNoteB) const
Do two notes match exactly, from the pattern editor's point of view? They match if all user-editable ...
void onPreferencesChanged(H2Core::Preferences::Changes changes)
virtual void createBackground()
Updates m_pBackgroundPixmap to show the latest content.
static constexpr int nMargin
virtual void songModeActivationEvent() override
PatternEditorPanel * m_pPatternEditorPanel
virtual void focusInEvent(QFocusEvent *ev) override
H2Core::AudioEngine * m_pAudioEngine
void zoomIn()
Zoom in / out on the time axis.
virtual void leaveEvent(QEvent *ev) override
H2Core::Note * m_pDraggedNote
virtual void mouseReleaseEvent(QMouseEvent *ev) override
void deselectAndOverwriteNotes(std::vector< H2Core::Note * > &selected, std::vector< H2Core::Note * > &overwritten)
Deselect some notes, and "overwrite" some others.
void updatePatternInfo()
Update current pattern information.
virtual void mouseDragStartEvent(QMouseEvent *ev) override
virtual void copy()
Copy selection to clipboard in XML.
virtual void focusOutEvent(QFocusEvent *ev) override
void setCurrentInstrument(int nInstrument)
std::vector< H2Core::Pattern * > getPatternsToShow(void)
Get notes to show in pattern editor.
void undoDeselectAndOverwriteNotes(std::vector< H2Core::Note * > &selected, std::vector< H2Core::Note * > &overwritten)
QPixmap * m_pBackgroundPixmap
void setResolution(uint res, bool bUseTriplets)
Set the editor grid resolution, dividing a whole note into res subdivisions.
virtual void mouseDragEndEvent(QMouseEvent *ev) override
PatternEditor(QWidget *pParent, PatternEditorPanel *panel)
virtual void selectAll()=0
int getColumn(int x, bool bUseFineGrained=false) const
H2Core::Pattern * m_pPattern
void invalidateBackground()
void updateWidth()
Adjusts m_nActiveWidth and m_nEditorWidth to the current state of the editor.
virtual void enterEvent(QEvent *ev) override
Selection< SelectionIndex > m_selection
The Selection object.
QPoint movingGridOffset() const
bool m_bEntered
Indicates whether the mouse pointer entered the widget.
bool m_bBackgroundInvalid
void drawGridLines(QPainter &p, Qt::PenStyle style=Qt::SolidLine) const
Draw lines for note grid.
void addToSelection(Elem e)
void mouseReleaseEvent(QMouseEvent *ev)
void removeFromSelection(Elem e, bool bCheck=true)
void updateWidgetGroup()
Update any widgets in this selection group.
void clearSelection(bool bCheck=true)
void cancelGesture()
Cancel any selection gesture (lasso, move, with keyboard or mouse) in progress.
bool isMouseGesture() const
Is there a mouse gesture in progress?
bool isSelected(Elem e) const
Is an element in the set of currently selected elements?
void mousePressEvent(QMouseEvent *ev)
bool isMoving() const
Is there an ongoing (and incomplete) selection movement gesture?
QPoint movingOffset() const
During a selection "move" gesture, return the current movement position relative to the start positio...
void mouseMoveEvent(QMouseEvent *ev)
static constexpr int nPlayheadWidth
static int getPlayheadShaftOffset()
#define MAX_NOTES
Maximum number of notes.