80 setFocusPolicy(Qt::StrongFocus);
96 qreal pixelRatio = devicePixelRatio();
98 height() * pixelRatio );
114 update( 0, 0, width(), height() );
125 update( 0, 0, width(), height() );
152 float fRed, fGreen, fBlue;
156 QColor fullColor = pPref->getColorTheme()->m_patternEditor_noteVelocityFullColor;
157 QColor defaultColor = pPref->getColorTheme()->m_patternEditor_noteVelocityDefaultColor;
158 QColor halfColor = pPref->getColorTheme()->m_patternEditor_noteVelocityHalfColor;
159 QColor zeroColor = pPref->getColorTheme()->m_patternEditor_noteVelocityZeroColor;
164 float fWeightFull = 0;
165 float fWeightDefault = 0;
166 float fWeightHalf = 0;
167 float fWeightZero = 0;
169 if ( fVelocity >= 1.0 ) {
171 }
else if ( fVelocity >= 0.8 ) {
172 fWeightDefault = ( 1.0 - fVelocity )/ ( 1.0 - 0.8 );
173 fWeightFull = 1.0 - fWeightDefault;
174 }
else if ( fVelocity >= 0.5 ) {
175 fWeightHalf = ( 0.8 - fVelocity )/ ( 0.8 - 0.5 );
176 fWeightDefault = 1.0 - fWeightHalf;
178 fWeightZero = ( 0.5 - fVelocity )/ ( 0.5 );
179 fWeightHalf = 1.0 - fWeightZero;
182 fRed = fWeightFull * fullColor.redF() +
183 fWeightDefault * defaultColor.redF() +
184 fWeightHalf * halfColor.redF() + fWeightZero * zeroColor.redF();
185 fGreen = fWeightFull * fullColor.greenF() +
186 fWeightDefault * defaultColor.greenF() +
187 fWeightHalf * halfColor.greenF() + fWeightZero * zeroColor.greenF();
188 fBlue = fWeightFull * fullColor.blueF() +
189 fWeightDefault * defaultColor.blueF() +
190 fWeightHalf * halfColor.blueF() + fWeightZero * zeroColor.blueF();
193 color.setRedF( fRed );
194 color.setGreenF( fGreen );
195 color.setBlueF( fBlue );
209 const QColor noteColor( pPref->getColorTheme()->m_patternEditor_noteVelocityDefaultColor );
210 const QColor noteInactiveColor( pPref->getColorTheme()->m_windowTextColor.darker( 150 ) );
211 const QColor noteoffColor( pPref->getColorTheme()->m_patternEditor_noteOffColor );
212 const QColor noteoffInactiveColor( pPref->getColorTheme()->m_windowTextColor );
214 p.setRenderHint( QPainter::Antialiasing );
219 uint x_pos = pos.x(), y_pos = pos.y();
225 selectedPen.setWidth( 2 );
226 p.setPen( selectedPen );
227 p.setBrush( Qt::NoBrush );
230 bool bMoving = bSelected &&
m_selection.isMoving();
231 QPen movingPen( noteColor );
235 movingPen.setStyle( Qt::DotLine );
236 movingPen.setWidth( 2 );
245 QBrush noteBrush( color );
246 QPen notePen( noteColor );
247 if ( !bIsForeground ) {
250 noteBrush.setColor( noteInactiveColor );
251 notePen.setColor( noteInactiveColor );
254 noteBrush.setStyle( Qt::Dense4Pattern );
255 notePen.setStyle( Qt::DotLine );
259 p.drawEllipse( x_pos -4 -2, y_pos-2, w+4, h+4 );
271 for (
const auto& [ _, ppNote ] : *
m_pPattern->get_notes() ) {
272 if ( ppNote !=
nullptr &&
274 ppNote->get_note_off() &&
281 ppNote->get_position() ) {
284 nLength = std::min( ppNote->get_position() - pNote->
get_position(), nLength );
292 p.drawRoundedRect( x_pos-2, y_pos, width+4, 3+4, 4, 4 );
295 p.setBrush( noteBrush );
302 int nRectOnsetX = x_pos;
303 int nRectWidth = width;
304 if ( ! bIsForeground ) {
305 nRectOnsetX = nRectOnsetX + w/2;
306 nRectWidth = nRectWidth - w/2;
309 p.drawRect( nRectOnsetX, y_pos +2, nRectWidth, 3 );
310 p.drawLine( x_pos+width, y_pos, x_pos+width, y_pos + h );
314 p.setBrush( noteBrush );
315 p.drawEllipse( x_pos -4 , y_pos, w, h );
318 p.setPen( movingPen );
319 p.setBrush( Qt::NoBrush );
320 p.drawEllipse( movingOffset.x() + x_pos -4 -2, movingOffset.y() + y_pos -2 , w + 4, h + 4 );
323 p.setPen( movingPen );
324 p.setBrush( Qt::NoBrush );
325 p.drawRoundedRect( movingOffset.x() + x_pos-2, movingOffset.y() + y_pos, width+4, 3+4, 4, 4 );
331 QBrush noteOffBrush( noteoffColor );
332 if ( !bIsForeground ) {
333 noteOffBrush.setStyle( Qt::Dense4Pattern );
336 noteOffBrush.setColor( noteoffInactiveColor );
341 p.drawEllipse( x_pos -4 -2, y_pos-2, w+4, h+4 );
344 p.setPen( Qt::NoPen );
345 p.setBrush( noteOffBrush );
346 p.drawEllipse( x_pos -4 , y_pos, w, h );
349 p.setPen( movingPen );
350 p.setBrush( Qt::NoBrush );
351 p.drawEllipse( movingOffset.x() + x_pos -4 -2, movingOffset.y() + y_pos -2, w + 4, h + 4 );
359 int nGranularity = 1;
365 nColumn = nColumn * nGranularity;
385 auto pInstrumentList = pHydrogen->
getSong()->getInstrumentList();
390 bool bWroteNote =
false;
392 int nMinColumn, nMinRow, nMaxPitch;
395 const int nPitch = pNote->get_notekey_pitch();
396 const int nColumn = pNote->get_position();
397 const int nRow = pInstrumentList->index( pNote->get_instrument() );
404 nMinColumn = std::min( nColumn, nMinColumn );
405 nMinRow = std::min( nRow, nMinRow );
406 nMaxPitch = std::max( nPitch, nMaxPitch );
408 nMinColumn = nColumn;
414 pNote->save_to( ¬e_node );
418 positionNode.
write_int(
"minColumn", nMinColumn );
419 positionNode.
write_int(
"minRow", nMinRow );
420 positionNode.
write_int(
"maxPitch", nMaxPitch );
428 QClipboard *clipboard = QApplication::clipboard();
429 clipboard->setText( doc.toString() );
451 auto pInstrument = pInstrumentList->get( nInstrument );
455 if ( it->second->get_instrument() == pInstrument ) {
494 if ( QKeyEvent *pEv =
dynamic_cast<QKeyEvent*
>( ev ) ) {
497 bool bPressed = ev->type() == QEvent::KeyPress;
498 if ( pEv->key() == Qt::Key_Control ) {
500 }
else if ( pEv->key() == Qt::Key_Alt ) {
510 setCursor( QCursor( Qt::DragCopyCursor ) );
511 }
else if ( !
m_bCopyNotMove && cursor().shape() != Qt::DragMoveCursor ) {
512 setCursor( QCursor( Qt::DragMoveCursor ) );
535 std::set< Note *> duplicates;
536 for (
Note *pNote : elements ) {
537 if ( duplicates.find( pNote ) != duplicates.end() ) {
545 if ( it->second != pNote && pNote->match( it->second ) ) {
546 duplicates.insert( it->second );
550 if ( !duplicates.empty() ) {
556 QString sMsg ( tr(
"Placing these notes here will overwrite %1 duplicate notes." ) );
557 QMessageBox messageBox ( QMessageBox::Warning,
"Hydrogen", sMsg.arg( duplicates.size() ),
558 QMessageBox::Cancel | QMessageBox::Ok,
this );
559 messageBox.setCheckBox(
new QCheckBox( pCommonStrings->getMutableDialog() ) );
560 messageBox.checkBox()->setChecked(
false );
561 bOk = messageBox.exec() == QMessageBox::Ok;
562 if ( messageBox.checkBox()->isChecked() ) {
570 std::vector< Note *>overwritten;
571 for (
Note *pNote : duplicates ) {
572 overwritten.push_back( pNote );
585 std::vector< H2Core::Note *> &overwritten )
595 for (
auto pSelectedNote : selected ) {
596 m_selection.removeFromSelection( pSelectedNote,
false );
597 bool bFoundExact =
false;
598 int nPosition = pSelectedNote->get_position();
599 for (
auto it = pNotes->lower_bound( nPosition ); it != pNotes->end() && it->first == nPosition; ) {
600 Note *pNote = it->second;
605 }
else if ( pSelectedNote->match( pNote ) && pNote->
get_position() == pSelectedNote->get_position() ) {
607 it = pNotes->erase( it );
621 std::vector< H2Core::Note *> &overwritten )
630 for (
auto pNote : overwritten ) {
635 for (
auto pNote : selected ) {
651 std::shared_ptr<Song> pSong = pHydrogen->
getSong();
656 if ( pSong !=
nullptr ) {
657 PatternList *pPatternList = pSong->getPatternList();
674 int x_bias = nQuantX / 2, y_bias = nQuantY / 2;
675 if ( rawOffset.y() < 0 ) {
678 if ( rawOffset.x() < 0 ) {
681 int x_off = (rawOffset.x() + x_bias) / nQuantX;
682 int y_off = (rawOffset.y() + y_bias) / nQuantY;
683 return QPoint( nFactor * x_off, y_off);
691 const std::vector<QColor> colorsActive = {
692 QColor( pPref->getColorTheme()->m_patternEditor_line1Color ),
693 QColor( pPref->getColorTheme()->m_patternEditor_line2Color ),
694 QColor( pPref->getColorTheme()->m_patternEditor_line3Color ),
695 QColor( pPref->getColorTheme()->m_patternEditor_line4Color ),
696 QColor( pPref->getColorTheme()->m_patternEditor_line5Color ),
698 const std::vector<QColor> colorsInactive = {
699 QColor( pPref->getColorTheme()->m_windowTextColor.darker( 170 ) ),
700 QColor( pPref->getColorTheme()->m_windowTextColor.darker( 190 ) ),
701 QColor( pPref->getColorTheme()->m_windowTextColor.darker( 210 ) ),
702 QColor( pPref->getColorTheme()->m_windowTextColor.darker( 230 ) ),
703 QColor( pPref->getColorTheme()->m_windowTextColor.darker( 250 ) ),
724 p.setPen( QPen( colorsActive[ 0 ], 1, style ) );
730 p.setPen( QPen( colorsInactive[ 0 ], 1, style ) );
737 std::vector<int> availableResolutions = { 8, 16, 32, 64,
MAX_NOTES };
743 for (
int nnRes : availableResolutions ) {
750 p.setPen( QPen( colorsActive[ std::min( nColour,
static_cast<int>(colorsActive.size()) - 1 ) ],
776 p.setPen( QPen( colorsInactive[ std::min( nColour,
static_cast<int>(colorsInactive.size()) - 1 ) ],
802 p.setPen( QPen( colorsActive[ 0 ], 1, style ) );
808 p.setPen( QPen( colorsInactive[ 0 ], 1, style ) );
816 p.setPen( QPen( colorsActive[ 2 ], 1, style ) );
823 p.setPen( QPen( colorsInactive[ 2 ], 1, style ) );
839 const QColor selectHighlightColor( pPref->getColorTheme()->m_selectionHighlightColor );
840 return selectHighlightColor;
842 const QColor selectInactiveColor( pPref->getColorTheme()->m_selectionInactiveColor );
843 return selectInactiveColor;
858 std::set<Note *> valid;
859 std::vector< Note *> invalidated;
862 valid.insert( it->second );
866 if ( valid.find(i) == valid.end()) {
869 invalidated.push_back( i );
872 for (
auto i : invalidated ) {
882#ifdef H2CORE_HAVE_QT6
900 if ( ev->reason() == Qt::TabFocusReason || ev->reason() == Qt::BacktabFocusReason ) {
938 std::vector<Pattern *> patterns;
948 std::set< Pattern *> patternSet;
950 std::vector<const PatternList*> patternLists;
956 for (
const PatternList *pPatternList : patternLists ) {
957 for (
int i = 0; i < pPatternList->size(); i++) {
958 Pattern *pPattern = pPatternList->get( i );
960 patternSet.insert( pPattern );
964 for (
Pattern *pPattern : patternSet ) {
965 patterns.push_back( pPattern );
972 m_pPattern->get_virtual_patterns()->size() > 0 ) {
976 for (
const auto ppVirtualPattern : *
m_pPattern ) {
977 patterns.push_back( ppVirtualPattern );
993 ( pPattern !=
nullptr && pPattern->
isVirtual() ) ||
995 pHydrogen->isPatternEditorLocked() ) ) {
1015 ! pHydrogen->isPatternEditorLocked() ) {
1018 m_pPattern->longestVirtualPatternLength() + 1,
1024 pHydrogen->getAudioEngine()->getPlayingPatterns()->longest_pattern_length(
false ) + 1,
1051 if (
m_nTick == (
int)fTick ) {
1065 update( updateRect );
1066 if ( fDiff > 1.0 || fDiff < -1.0 ) {
1069 updateRect.translate( -fDiff, 0 );
1070 update( updateRect );
1075 if( pNote !=
nullptr ){
1100 int nColumn =
getColumn( pEv->position().x() );
1104 bool bOldCursorHidden = pHydrogenApp->hideKeyboardCursor();
1106 pHydrogenApp->setHideKeyboardCursor(
true );
1109 if ( bOldCursorHidden != pHydrogenApp->hideKeyboardCursor() ) {
1115 int nRealColumn = 0;
1117 if ( ev->button() == Qt::RightButton ) {
1119 int nPressedLine = std::floor(
static_cast<float>(pEv->position().y()) /
1121 int nSelectedInstrumentNumber = pHydrogen->getSelectedInstrumentNumber();
1125 static_cast<int>(std::floor(
1152 int nTickColumn =
getColumn( pEv->position().x() );
1190 fValue = fValue + (fMoveY / 100);
1194 else if ( fValue < 0.0 ) {
1285 int nSelectedPatternNumber,
1286 int nSelectedInstrumentnumber,
1291 auto pSong = pHydrogen->getSong();
1292 auto pPatternList = pSong->getPatternList();
1295 if ( nSelectedPatternNumber != -1 &&
1296 nSelectedPatternNumber < pPatternList->size() ) {
1297 pPattern = pPatternList->get( nSelectedPatternNumber );
1300 if ( pPattern ==
nullptr ) {
1307 Note* pDraggedNote =
nullptr;
1309 auto pSelectedInstrument =
1310 pSong->getInstrumentList()->get( nSelectedInstrumentnumber );
1311 if ( pSelectedInstrument ==
nullptr ) {
1312 ERRORLOG(
"No instrument selected" );
1320 auto pDraggedNote = pPattern->
find_note( nColumn, nRealColumn,
1321 pSelectedInstrument,
1322 pressedNoteKey, pressedOctave,
1326 auto pSelectedInstrument = pSong->getInstrumentList()->get( nRow );
1327 if ( pSelectedInstrument ==
nullptr ) {
1328 ERRORLOG(
"No instrument selected" );
1332 pDraggedNote = pPattern->
find_note( nColumn, nRealColumn, pSelectedInstrument,
false );
1335 ERRORLOG( QString(
"Unsupported editor [%1]" )
1336 .arg(
static_cast<int>(editor) ) );
1341 if ( pDraggedNote !=
nullptr ){
1347 pHydrogen->setIsModified(
true );
1358 int nSelectedPatternNumber,
1359 int nSelectedInstrumentNumber,
1365 float fProbability )
1369 auto pSong = pHydrogen->getSong();
1370 auto pPatternList = pSong->getPatternList();
1373 if ( nSelectedPatternNumber != -1 &&
1374 nSelectedPatternNumber < pPatternList->size() ) {
1375 pPattern = pPatternList->get( nSelectedPatternNumber );
1378 if ( pPattern ==
nullptr ) {
1385 Note* pDraggedNote =
nullptr;
1388 auto pSelectedInstrument =
1389 pSong->getInstrumentList()->get( nSelectedInstrumentNumber );
1390 if ( pSelectedInstrument ==
nullptr ) {
1391 ERRORLOG(
"No instrument selected" );
1399 pDraggedNote = pPattern->
find_note( nColumn, nRealColumn,
1400 pSelectedInstrument,
1401 pressedNoteKey, pressedOctave,
1405 auto pSelectedInstrument = pSong->getInstrumentList()->get( nRow );
1406 if ( pSelectedInstrument ==
nullptr ) {
1407 ERRORLOG(
"No instrument selected" );
1411 pDraggedNote = pPattern->
find_note( nColumn, nRealColumn, pSelectedInstrument,
false );
1414 ERRORLOG( QString(
"Unsupported editor [%1]" )
1415 .arg(
static_cast<int>(editor) ) );
1420 bool bValueChanged =
true;
1422 if ( pDraggedNote !=
nullptr ){
1428 pDraggedNote->
setPan( fPan );
1437 bValueChanged =
true;
1440 ERRORLOG(
"note could not be found");
1445 if ( bValueChanged &&
1447 pHydrogen->setIsModified(
true );
1473 s = QString(
"Unknown mode [%1]" ).arg(
static_cast<int>(mode) ) ;
1483 QString sUnit( tr(
"ticks" ) );
1489 s = QString( tr(
"Set note velocity" ) )
1490 .append( QString(
": [%1]")
1492 sCaller.append(
":Velocity" );
1500 fValue = pNote->
getPan() * 100;
1501 fValue = std::round( fValue );
1502 fValue = fValue / 100;
1504 if ( fValue > 0.0 ) {
1505 s = QString( tr(
"Note panned to the right by" ) ).
1506 append( QString(
": [%1]" ).arg( fValue / 2, 2,
'f', 2 ) );
1507 }
else if ( fValue < 0.0 ) {
1508 s = QString( tr(
"Note panned to the left by" ) ).
1509 append( QString(
": [%1]" ).arg( -1 * fValue / 2, 2,
'f', 2 ) );
1511 s = QString( tr(
"Note centered" ) );
1513 sCaller.append(
":Pan" );
1520 fValue = std::round( fValue );
1521 fValue = fValue / 100;
1522 if ( fValue < 0.0 ) {
1523 s = QString( tr(
"Leading beat by" ) )
1524 .append( QString(
": [%1] " )
1529 else if ( fValue > 0.0 ) {
1530 s = QString( tr(
"Lagging beat by" ) )
1531 .append( QString(
": [%1] " )
1537 s = tr(
"Note on beat" );
1539 sCaller.append(
":LeadLag" );
1543 s = QString( tr(
"Set pitch" ) ).append(
": " ).append( tr(
"key" ) )
1545 .append( tr(
"octave" ) )
1546 .append( QString(
": [%1]" ).arg( pNote->
get_octave() ) );
1547 sCaller.append(
":NoteKey" );
1552 s = tr(
"Set note probability to" )
1553 .append( QString(
": [%1]" ).arg( pNote->
get_probability(), 2,
'f', 2 ) );
1555 sCaller.append(
":Probability" );
1562 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.
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
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_velocity() const
__velocity accessor
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.
Pattern * get(int idx)
get a pattern from the list
Pattern class is a Note container.
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.
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.
@ Stacked
An arbitrary number of pattern can be played.
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.
Compatibility class to support QMouseEvent more esily in Qt5 and Qt6.
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?
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.
static constexpr int nPlayheadWidth
static int getPlayheadShaftOffset()
#define MAX_NOTES
Maximum number of notes.