Skip to content

Commit

Permalink
fix #279471 Set note cutoff length
Browse files Browse the repository at this point in the history
Adding dialog to allow user to specify a fraction of a beat that notes should be cutoff at.  Right click in the paino note area and select 'Note Tweaker' to activate dialog.
  • Loading branch information
blackears committed Dec 6, 2018
1 parent 39501b5 commit ca3af5a
Show file tree
Hide file tree
Showing 8 changed files with 365 additions and 14 deletions.
5 changes: 3 additions & 2 deletions mscore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ QT5_WRAP_UI (ui_headers
note_groups.ui resourceManager.ui stafftypetemplates.ui
startcenter.ui scorePreview.ui scoreBrowser.ui
logindialog.ui uploadscoredialog.ui breaksdialog.ui
toolbarEditor.ui workspacedialog.ui
toolbarEditor.ui workspacedialog.ui notetweakerdialog.ui

importmidi/importmidi_panel.ui

Expand Down Expand Up @@ -290,7 +290,7 @@ add_executable ( ${ExecutableName}
keycanvas.h keyedit.h layer.h licence.h logindialog.h loginmanager.h magbox.h masterpalette.h
measureproperties.h mediadialog.h metaedit.h miconengine.h mididriver.h
mixer.h mixertrack.h mixertrackchannel.h mixertrackgroup.h mixertrackitem.h mixertrackpart.h mixerdetails.h musedata.h
musescore.h musicxml.h musicxmlfonthandler.h musicxmlsupport.h navigator.h newwizard.h noteGroups.h
musescore.h musicxml.h musicxmlfonthandler.h musicxmlsupport.h navigator.h newwizard.h noteGroups.h notetweakerdialog.h
omrpanel.h ove.h pa.h pagesettings.h palette.h palettebox.h paletteBoxButton.h partedit.h parteditbase.h
pathlistdialog.h piano.h pianolevels.h pianolevelschooser.h pianolevelsfilter.h
pianokeyboard.h pianoroll.h pianoruler.h pianotools.h pianoview.h
Expand Down Expand Up @@ -329,6 +329,7 @@ add_executable ( ${ExecutableName}
synthcontrol.cpp drumroll.cpp pianoroll.cpp piano.cpp
pianokeyboard.cpp pianolevels.cpp pianolevelschooser.cpp pianolevelsfilter.cpp
pianoruler.cpp pianoview.cpp drumview.cpp scoretab.cpp keyedit.cpp harmonyedit.cpp
notetweakerdialog.cpp
updatechecker.cpp
importove.cpp
ove.cpp
Expand Down
139 changes: 139 additions & 0 deletions mscore/notetweakerdialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#include "notetweakerdialog.h"
#include "ui_notetweakerdialog.h"

#include "libmscore/segment.h"
#include "libmscore/score.h"
#include "libmscore/staff.h"
#include "libmscore/chord.h"
#include "libmscore/rest.h"
#include "libmscore/note.h"
#include "libmscore/slur.h"
#include "libmscore/tie.h"
#include "libmscore/tuplet.h"
#include "libmscore/noteevent.h"
#include "libmscore/undo.h"

namespace Ms{


NoteTweakerDialog::NoteTweakerDialog(QWidget *parent) :
QDialog(parent),
_staff(nullptr),
ui(new Ui::NoteTweakerDialog)
{
ui->setupUi(this);

connect(ui->bnClose, &QPushButton::clicked, this, &QDialog::close);
connect(ui->bnSetNoteOffTime, &QPushButton::clicked, this, &NoteTweakerDialog::setNoteOffTime);
}

NoteTweakerDialog::~NoteTweakerDialog()
{
delete ui;
}

void NoteTweakerDialog::setNoteOffTime()
{
if (!_staff)
return;

QString s = ui->comboOffTimeFrac->currentText();
QStringList parts = s.split("/");
int num = parts[0].toInt();
double denom = parts[1].toInt();
double gapTicks = MScore::division * num / denom;

Score* score = _staff->score();

score->startCmd();

for(Note* note: noteList) {
if (!note->selected())
continue;

Chord* chord = note->chord();
int ticks = chord->duration().ticks();

int scalar = 1000 * (ticks - gapTicks) / ticks;
if (scalar <= 0)
scalar = 1;

for (NoteEvent& e : note->playEvents()) {
NoteEvent ne = e;
ne.setLen(scalar);
score->undo(new ChangeNoteEvent(note, &e, ne));
}
}

score->endCmd();

emit notesChanged();
}

//---------------------------------------------------------
// setStaff
//---------------------------------------------------------

void NoteTweakerDialog::setStaff(Staff* s)
{
if (_staff == s)
return;

_staff = s;
updateNotes();
}

//---------------------------------------------------------
// addChord
//---------------------------------------------------------

void NoteTweakerDialog::addChord(Chord* chord, int voice)
{
for (Chord* c : chord->graceNotes())
addChord(c, voice);
for (Note* note : chord->notes()) {
if (note->tieBack())
continue;
noteList.append(note);
}
}

//---------------------------------------------------------
// updateNotes
//---------------------------------------------------------

void NoteTweakerDialog::updateNotes()
{
clearNoteData();

if (!_staff) {
return;
}

int staffIdx = _staff->idx();
if (staffIdx == -1)
return;

SegmentType st = SegmentType::ChordRest;
for (Segment* s = _staff->score()->firstSegment(st); s; s = s->next1(st)) {
for (int voice = 0; voice < VOICES; ++voice) {
int track = voice + staffIdx * VOICES;
Element* e = s->element(track);
if (e && e->isChord())
addChord(toChord(e), voice);
}
}

update();
}

//---------------------------------------------------------
// clearNoteData
//---------------------------------------------------------

void NoteTweakerDialog::clearNoteData()
{
noteList.clear();
}

}
46 changes: 46 additions & 0 deletions mscore/notetweakerdialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#ifndef NOTETWEAKERDIALOG_H
#define NOTETWEAKERDIALOG_H

#include <QDialog>

namespace Ui {
class NoteTweakerDialog;
}

namespace Ms {

class Staff;
class Note;
class Chord;

class NoteTweakerDialog : public QDialog
{
Q_OBJECT

Staff* _staff;
QList<Note*> noteList;

public:
explicit NoteTweakerDialog(QWidget *parent = nullptr);
~NoteTweakerDialog();

void setStaff(Staff* s);

signals:
void notesChanged();

public slots:
void setNoteOffTime();

private:
void addChord(Chord* chord, int voice);
void updateNotes();
void clearNoteData();


Ui::NoteTweakerDialog *ui;
};

}

#endif // NOTETWEAKERDIALOG_H
128 changes: 128 additions & 0 deletions mscore/notetweakerdialog.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NoteTweakerDialog</class>
<widget class="QDialog" name="NoteTweakerDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>206</width>
<height>137</height>
</rect>
</property>
<property name="windowTitle">
<string>Note Tweaker</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Note Off Time</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Fraction of beat:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboOffTimeFrac">
<item>
<property name="text">
<string>1/2</string>
</property>
</item>
<item>
<property name="text">
<string>1/4</string>
</property>
</item>
<item>
<property name="text">
<string>1/8</string>
</property>
</item>
<item>
<property name="text">
<string>1/16</string>
</property>
</item>
<item>
<property name="text">
<string>1/32</string>
</property>
</item>
<item>
<property name="text">
<string>1/64</string>
</property>
</item>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="bnSetNoteOffTime">
<property name="text">
<string>Set</string>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="bnClose">
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
Loading

0 comments on commit ca3af5a

Please sign in to comment.