Skip to content

Commit

Permalink
added pianoview context menu for first/last/base, fixed small reset v…
Browse files Browse the repository at this point in the history
…alue bug
  • Loading branch information
spechtstatt committed Jan 15, 2022
1 parent 7b1c5a8 commit 1945d97
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 42 deletions.
5 changes: 3 additions & 2 deletions include/PianoView.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ class PianoView : public QWidget, public ModelView
int getKeyWidth(int key_num) const;
int getKeyHeight(int key_num) const;
IntModel *getNearestMarker(int key, QString* title = nullptr);
void setMarkerKeyValue(IntModel *noteModel, int key_num);
bool setMarkerKeyValue(IntModel *noteModel, int key_num, bool ignoreConstraints = false);
bool firstMarkerAllowed(int key_num);
bool lastMarkerAllowed(int key_num);

static QPixmap * s_whiteKeyPm;
static QPixmap * s_blackKeyPm;
Expand All @@ -85,7 +87,6 @@ class PianoView : public QWidget, public ModelView
IntModel *m_movedNoteModel; //!< note marker which is being moved
int m_lastContextMenuKey; //!< previous key selected by the context menu


private slots:
void pianoScrolled( int _new_pos );
void setBaseNote();
Expand Down
117 changes: 77 additions & 40 deletions src/gui/PianoView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
#include <QPainter>
#include <QPainterPath>
#include <QVBoxLayout>
#include <QtWidgets>
#include <QtGui>

#include "PianoView.h"
#include "Piano.h"
Expand Down Expand Up @@ -94,7 +96,7 @@ PianoView::PianoView(QWidget *parent) :
m_piano(nullptr), /*!< Our piano Model */
m_startKey(Key_C + Octave_3*KeysPerOctave), /*!< The first key displayed? */
m_lastKey(-1), /*!< The last key displayed? */
m_movedNoteModel(nullptr) /*!< Key marker which is being moved */
m_movedNoteModel(nullptr)
{
if (s_whiteKeyPm == nullptr)
{
Expand Down Expand Up @@ -453,8 +455,8 @@ void PianoView::contextMenuEvent(QContextMenuEvent *me)
contextMenu.addAction(tr( "Set single key" ),
this, SLOT( setSingleKey() ) );

actionFirst->setEnabled(key_num != m_piano->instrumentTrack()->firstKeyModel()->value());
actionLast->setEnabled(key_num != m_piano->instrumentTrack()->lastKeyModel()->value());
actionFirst->setEnabled(key_num != m_piano->instrumentTrack()->firstKeyModel()->value() && firstMarkerAllowed(key_num));
actionLast->setEnabled(key_num != m_piano->instrumentTrack()->lastKeyModel()->value() && lastMarkerAllowed(key_num));
actionBase->setEnabled(key_num != m_piano->instrumentTrack()->baseNoteModel()->value());

contextMenu.exec(QCursor::pos());
Expand Down Expand Up @@ -542,11 +544,26 @@ void PianoView::mousePressEvent(QMouseEvent *me)
}
}


void PianoView::setMarkerKeyValue(IntModel *noteModel, int key_num)
bool PianoView::setMarkerKeyValue(IntModel *noteModel, int key_num, bool ignoreConstraints)
{
if (!ignoreConstraints)
{
if (m_piano->instrumentTrack()->firstKeyModel() == noteModel && !firstMarkerAllowed(key_num)) return false;
if (m_piano->instrumentTrack()->lastKeyModel() == noteModel && !lastMarkerAllowed(key_num)) return false;
}
noteModel->setValue(static_cast<float>(key_num));
if (noteModel == m_piano->instrumentTrack()->baseNoteModel()) { emit baseNoteChanged(); } // TODO: not actually used by anything?
return true;
}

bool PianoView::firstMarkerAllowed(int key_num)
{
return key_num <= m_piano->instrumentTrack()->lastKeyModel()->value();
}

bool PianoView::lastMarkerAllowed(int key_num)
{
return key_num >= m_piano->instrumentTrack()->firstKeyModel()->value();
}


Expand All @@ -558,26 +575,24 @@ void PianoView::setBaseNote()

void PianoView::setFirstKey()
{
setMarkerKeyValue(m_piano->instrumentTrack()->firstKeyModel(), m_lastContextMenuKey);
update();
if (setMarkerKeyValue(m_piano->instrumentTrack()->firstKeyModel(), m_lastContextMenuKey)) update();
}

void PianoView::setLastKey()
{
setMarkerKeyValue(m_piano->instrumentTrack()->lastKeyModel(), m_lastContextMenuKey);
update();
if (setMarkerKeyValue(m_piano->instrumentTrack()->lastKeyModel(), m_lastContextMenuKey)) update();
}


void PianoView::setSingleKey()
{
setMarkerKeyValue(m_piano->instrumentTrack()->firstKeyModel(), m_lastContextMenuKey);
setMarkerKeyValue(m_piano->instrumentTrack()->lastKeyModel(), m_lastContextMenuKey);
setMarkerKeyValue(m_piano->instrumentTrack()->firstKeyModel(), m_lastContextMenuKey, true);
setMarkerKeyValue(m_piano->instrumentTrack()->lastKeyModel(), m_lastContextMenuKey, true);
update();
}




// handler for mouse-release-event
/*! \brief Handle a mouse release event on the piano display view
*
Expand Down Expand Up @@ -921,49 +936,72 @@ void PianoView::paintEvent( QPaintEvent * )

// draw bar above the keyboard (there will be the labels
// for all C's)
p.fillRect( QRect( 0, 1, width(), PIANO_BASE-2 ), p.background() );

// draw the line above the keyboard
p.setPen( Qt::black );
p.drawLine( 0, 0, width(), 0 );
p.drawLine( 0, PIANO_BASE-1, width(), PIANO_BASE-1 );

p.setPen( Qt::white );
p.fillRect( QRect( 0, 1, width(), PIANO_BASE-2 ), p.background() );

// Controls for first / last / base key models are shown only if microtuner or its key range import are disabled
if (m_piano != nullptr && !m_piano->instrumentTrack()->keyRangeImport())
{
// Draw the base note marker and first / last note boundary markers
QColor slider_foreColor = QApplication::palette().color(QPalette::Active, QPalette::Text).darker(200);
QColor marker_fillColor = QApplication::palette().color(QPalette::Active, QPalette::WindowText);
QColor marker_borderColor = marker_fillColor.darker(200);

// get the marker model instances
const int base_key = m_piano->instrumentTrack()->baseNoteModel()->value();
const int first_key = m_piano->instrumentTrack()->firstKeyModel()->value();
const int last_key = m_piano->instrumentTrack()->lastKeyModel()->value();
QColor marker_color = QApplication::palette().color(QPalette::Active, QPalette::BrightText);

// - prepare triangle shapes for start/end/base markers

// arrow pointing right
// prepare arrow pointing right
QPainterPath first_marker(QPoint(getKeyX(first_key) + 1, 1));
first_marker.lineTo(getKeyX(first_key) + 1, PIANO_BASE);
first_marker.lineTo(getKeyX(first_key) + PIANO_BASE / 2 + 1, PIANO_BASE / 2);

// arrow pointing left
// prepare arrow pointing left
QPainterPath last_marker(QPoint(getKeyX(last_key) + getKeyWidth(last_key), 1));
last_marker.lineTo(getKeyX(last_key) + getKeyWidth(last_key), PIANO_BASE);
last_marker.lineTo(getKeyX(last_key) + getKeyWidth(last_key) - PIANO_BASE / 2, PIANO_BASE / 2);

// arrow pointing down
QPainterPath base_marker(QPoint(getKeyX(base_key)+1, 1));
base_marker.lineTo(getKeyX(base_key) + getKeyWidth(base_key) + 1, 1);
base_marker.lineTo(getKeyX(base_key) + getKeyWidth(base_key) / 2 + 1, PIANO_BASE);
// prepare slider stlye "arrow" pointing down
int posDelta = getKeyWidth(base_key) - PW_BLACK_KEY_WIDTH; // make sure the width is constant
posDelta = posDelta > 0 ? posDelta /2 : 0;

// - fill all markers
p.fillPath(base_marker, marker_color);
p.fillPath(first_marker, marker_color);
p.fillPath(last_marker, marker_color);
QPainterPath base_marker(QPoint(getKeyX(base_key) + posDelta + 2, 1));
base_marker.lineTo(getKeyX(base_key) + getKeyWidth(base_key) - posDelta, 1);
base_marker.lineTo(getKeyX(base_key) + getKeyWidth(base_key) - posDelta, PIANO_BASE / 2);
base_marker.lineTo(getKeyX(base_key) + getKeyWidth(base_key) / 2 + 1, PIANO_BASE);
base_marker.lineTo(getKeyX(base_key) + posDelta + 2, PIANO_BASE / 2);

// draw the "slider" line inside the bar
p.setPen(slider_foreColor);
p.drawLine(2, PIANO_BASE/2, width() - 4, PIANO_BASE/2 );

// we do some slight corrections on C and H because we have more space
if ((Keys)(base_key % KeysPerOctave) == Key_H) base_marker.translate(1,0);
if ((Keys)(base_key % KeysPerOctave) == Key_C) base_marker.translate(-1,0);

// draw the markers with a simple left/right "border"
// drawpath and strokepath give no satisfying results and
// changing the compositionmode may be overkill
p.fillPath(base_marker.translated(-1,0), marker_borderColor);
p.fillPath(base_marker.translated(1,0), marker_borderColor);
p.fillPath(base_marker, marker_fillColor);

p.fillPath(first_marker.translated(-1,0), marker_borderColor);
p.fillPath(first_marker.translated(1,0), marker_borderColor);
p.fillPath(first_marker, marker_fillColor);

p.fillPath(last_marker.translated(-1,0), marker_borderColor);
p.fillPath(last_marker.translated(1,0), marker_borderColor);
p.fillPath(last_marker, marker_fillColor);
}

int cur_key = m_startKey;
// draw the dark border lines of the bar above the keyboard
p.setPen( Qt::black );
p.drawLine( 0, 0, width(), 0 );
p.drawLine( 0, PIANO_BASE-1, width(), PIANO_BASE-1 );

int cur_key = m_startKey;
//p.setPen(Qt::white);
p.setPen(Qt::black);
// draw all white keys...
for (int x = 0; x < width();)
{
Expand All @@ -989,14 +1027,13 @@ void PianoView::paintEvent( QPaintEvent * )
p.drawPixmap(x, PIANO_BASE, *s_whiteKeyDisabledPm);
}

x += PW_WHITE_KEY_WIDTH;

if ((Keys)(cur_key % KeysPerOctave) == Key_C)
{
// label key of note C with "C" and number of current octave
p.drawText(x - PW_WHITE_KEY_WIDTH, LABEL_TEXT_SIZE + 2,
QString("C") + QString::number(FirstOctave + cur_key / KeysPerOctave));
p.rotate(-90);
p.drawText(-PIANO_BASE-PW_WHITE_KEY_HEIGHT+4, x+PW_WHITE_KEY_WIDTH-1, getNoteStringByKey(cur_key));
p.rotate(90);
}
x += PW_WHITE_KEY_WIDTH;
++cur_key;
}

Expand Down

0 comments on commit 1945d97

Please sign in to comment.