summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2011-05-19 16:02:25 +0000
committerFlorian Jung <flo@windfisch.org>2011-05-19 16:02:25 +0000
commit6ddc310885d4dc3dfd2bdea44c2f6f1568fbd6bb (patch)
tree354020a5e218eb64ab35562304a7a5c44142c7a3
parentdef56ecf12f25a643e72c38ecf78226f5e87c11c (diff)
added a modified MTScale to the score editor
-rw-r--r--muse2/muse/midiedit/prcanvas.h2
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp38
-rw-r--r--muse2/muse/midiedit/scoreedit.h20
-rw-r--r--muse2/muse/widgets/CMakeLists.txt2
-rw-r--r--muse2/muse/widgets/mtscale_flo.cpp325
-rw-r--r--muse2/muse/widgets/mtscale_flo.h51
6 files changed, 414 insertions, 24 deletions
diff --git a/muse2/muse/midiedit/prcanvas.h b/muse2/muse/midiedit/prcanvas.h
index 6995bdbe..a04ca514 100644
--- a/muse2/muse/midiedit/prcanvas.h
+++ b/muse2/muse/midiedit/prcanvas.h
@@ -42,7 +42,7 @@ class PianoCanvas : public EventCanvas {
int playedPitch;
QTimer* chordTimer;
- int chordTimer_setToTick;
+ unsigned chordTimer_setToTick;
Q_OBJECT
virtual void viewMouseDoubleClickEvent(QMouseEvent*);
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index 46fa1914..dccac615 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -170,9 +170,10 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
apply_velo=false;
- score_canvas=new ScoreCanvas(this, mainw, 1, 1);
+ score_canvas=new ScoreCanvas(this, mainw);
xscroll = new QScrollBar(Qt::Horizontal, mainw);
yscroll = new QScrollBar(Qt::Vertical, mainw);
+ time_bar = new MTScaleFlo(score_canvas, mainw);
connect(xscroll, SIGNAL(valueChanged(int)), score_canvas, SLOT(x_scroll_event(int)));
connect(score_canvas, SIGNAL(xscroll_changed(int)), xscroll, SLOT(setValue(int)));
@@ -187,9 +188,14 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
connect(song, SIGNAL(songChanged(int)), score_canvas, SLOT(song_changed(int)));
- mainGrid->addWidget(score_canvas, 0, 0);
- mainGrid->addWidget(xscroll,1,0);
- mainGrid->addWidget(yscroll,0,1);
+ connect(xscroll, SIGNAL(valueChanged(int)), time_bar, SLOT(set_xpos(int)));
+ connect(score_canvas, SIGNAL(pos_add_changed()), time_bar, SLOT(pos_add_changed()));
+ connect(score_canvas, SIGNAL(preamble_width_changed(int)), time_bar, SLOT(set_xoffset(int)));
+
+ mainGrid->addWidget(time_bar, 0,0);
+ mainGrid->addWidget(score_canvas, 1,0);
+ mainGrid->addWidget(xscroll,2,0);
+ mainGrid->addWidget(yscroll,1,1);
xscroll->setMinimum(0);
yscroll->setMinimum(0);
@@ -957,8 +963,7 @@ void ScoreCanvas::add_staves(PartList* pl, bool all_in_one)
}
-ScoreCanvas::ScoreCanvas(ScoreEdit* pr, QWidget* parent_widget,
- int sx, int sy) : View(parent_widget, sx, sy)
+ScoreCanvas::ScoreCanvas(ScoreEdit* pr, QWidget* parent_widget) : View(parent_widget, 1, 1)
{
parent = pr;
setFocusPolicy(Qt::StrongFocus);
@@ -2667,6 +2672,8 @@ void ScoreCanvas::calc_pos_add_list()
curr_key=new_key;
}
+
+ emit pos_add_changed();
}
void ScoreCanvas::draw_items(QPainter& p, int y, staff_t& staff, int x1, int x2)
@@ -3088,7 +3095,10 @@ void ScoreCanvas::draw_preamble(QPainter& p, int y_offset, clef_t clef)
if (x_left_old!=x_left)
+ {
emit viewport_width_changed(viewport_width());
+ emit preamble_width_changed(x_left);
+ }
}
@@ -3206,6 +3216,11 @@ int ScoreCanvas::tick_to_x(int t)
return x;
}
+int ScoreCanvas::delta_tick_to_delta_x(int t)
+{
+ return t*pixels_per_whole()/TICKS_PER_WHOLE;
+}
+
int ScoreCanvas::calc_posadd(int t)
{
int result=0;
@@ -4205,17 +4220,15 @@ void staff_t::apply_lasso(QRect rect, set<Event*>& already_processed)
* x nothing atm
*
* IMPORTANT TODO
- * o display blue loop markers in score editor
- * o transpose: support in-key-transpose
- * o drum-loop-editor (like in sq korg ds xD)
- *
* o add a select-clef-toolbox for tracks
* o respect the track's clef (has to be implemented first in muse)
* o do partial recalculating; recalculating can take pretty long
* (0,5 sec) when displaying a whole song in scores
* o transpose etc. must also transpose key-pressure events
+ * o transpose: support in-key-transpose
*
* less important stuff
+ * o controller view in score editor
* o quantize-templates (everything is forced into a specified
* rhythm)
* o part-templates (you specify some notes and a control-chord;
@@ -4251,11 +4264,6 @@ void staff_t::apply_lasso(QRect rect, set<Event*>& already_processed)
* msgNewEvent functions (see my e-mail)
*
* o make quantize and other stuff faster (by assymetric communication)
- *
- * GUI stuff
- * o velocity/release-velo for already existing notes
- * - do this by right-click -> some dialog shows up?
- * - or by controller graphs, as used by the piano roll
*/
diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h
index c26bdd84..4004452f 100644
--- a/muse2/muse/midiedit/scoreedit.h
+++ b/muse2/muse/midiedit/scoreedit.h
@@ -31,6 +31,7 @@
#include "gconfig.h"
#include "part.h"
#include "keyevent.h"
+#include "mtscale_flo.h"
#include <set>
#include <map>
@@ -109,6 +110,7 @@ class ScoreEdit : public TopWin
QScrollBar* xscroll;
QScrollBar* yscroll;
ScoreCanvas* score_canvas;
+ MTScaleFlo* time_bar;
QLabel* apply_velo_to_label;
bool apply_velo;
@@ -583,13 +585,6 @@ class ScoreCanvas : public View
void recalc_staff_pos();
list<staff_t>::iterator staff_at_y(int y);
-
- timesig_t timesig_at_tick(int t);
- key_enum key_at_tick(int t);
- int tick_to_x(int t);
- int x_to_tick(int x);
- int calc_posadd(int t);
-
bool need_redraw_for_hilighting(ScoreItemList::iterator from_it, ScoreItemList::iterator to_it);
@@ -722,9 +717,11 @@ class ScoreCanvas : public View
void yscroll_changed(int);
void viewport_width_changed(int);
void canvas_width_changed(int);
+ void preamble_width_changed(int);
void viewport_height_changed(int);
void canvas_height_changed(int);
void pixels_per_whole_changed(int);
+ void pos_add_changed();
protected:
virtual void draw(QPainter& p, const QRect& rect);
@@ -737,7 +734,7 @@ class ScoreCanvas : public View
virtual void keyPressEvent(QKeyEvent* event);
public:
- ScoreCanvas(ScoreEdit*, QWidget*, int, int);
+ ScoreCanvas(ScoreEdit*, QWidget*);
~ScoreCanvas(){};
void add_staves(PartList* pl, bool all_in_one);
@@ -763,6 +760,13 @@ class ScoreCanvas : public View
set<Part*> get_all_parts();
void write_staves(int level, Xml& xml) const;
+
+ timesig_t timesig_at_tick(int t);
+ key_enum key_at_tick(int t);
+ int tick_to_x(int t);
+ int delta_tick_to_delta_x(int t);
+ int x_to_tick(int x);
+ int calc_posadd(int t);
};
int calc_measure_len(const list<int>& nums, int denom);
diff --git a/muse2/muse/widgets/CMakeLists.txt b/muse2/muse/widgets/CMakeLists.txt
index 5989df11..7589ddf0 100644
--- a/muse2/muse/widgets/CMakeLists.txt
+++ b/muse2/muse/widgets/CMakeLists.txt
@@ -53,6 +53,7 @@ QT4_WRAP_CPP (widget_mocs
mixdowndialog.h
mlabel.h
mtscale.h
+ mtscale_flo.h
mtrackinfo.h
nentry.h
noteinfo.h
@@ -149,6 +150,7 @@ file (GLOB widgets_source_files
mmath.cpp
mtrackinfo.cpp
mtscale.cpp
+ mtscale_flo.cpp
nentry.cpp
noteinfo.cpp
pitchedit.cpp
diff --git a/muse2/muse/widgets/mtscale_flo.cpp b/muse2/muse/widgets/mtscale_flo.cpp
new file mode 100644
index 00000000..e18a7d11
--- /dev/null
+++ b/muse2/muse/widgets/mtscale_flo.cpp
@@ -0,0 +1,325 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: mtscale_flo.cpp,v 1.8.2.7 2011/05/19 04:14:01 flo Exp $
+// (C) Copyright 1999 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#include <values.h>
+
+#include <QMouseEvent>
+#include <QPainter>
+
+#include "mtscale_flo.h"
+#include "song.h"
+#include "icons.h"
+#include "gconfig.h"
+#include "scoreedit.h"
+
+//---------------------------------------------------------
+// MTScale
+// Midi Time Scale
+//---------------------------------------------------------
+
+MTScaleFlo::MTScaleFlo(ScoreCanvas* parent_editor, QWidget* parent_widget)
+ : View(parent_widget, 1, 1)
+ {
+ setToolTip(tr("bar scale"));
+ pos[0] = song->cpos();
+ pos[1] = song->lpos();
+ pos[2] = song->rpos();
+ button = Qt::NoButton;
+ setMouseTracking(true);
+ connect(song, SIGNAL(posChanged(int, unsigned, bool)), SLOT(setPos(int, unsigned, bool)));
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ connect(song, SIGNAL(markerChanged(int)), SLOT(redraw()));
+
+ parent=parent_editor;
+
+ setFixedHeight(28);
+ setBg(QColor(0xe0, 0xe0, 0xe0));
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MTScaleFlo::songChanged(int type)
+ {
+ if (type & (SC_SIG|SC_TEMPO))
+ redraw();
+ }
+
+//---------------------------------------------------------
+// setPos
+//---------------------------------------------------------
+
+void MTScaleFlo::setPos(int idx, unsigned val, bool)
+ {
+ if ((val == MAXINT) || (val == pos[idx]))
+ return;
+
+ int opos = parent->tick_to_x(pos[idx] == MAXINT ? val : pos[idx]) + xoffset - xpos;
+
+ pos[idx] = val;
+
+// if (isVisible())
+// redraw();
+ if (isVisible()) {
+
+ int tval = parent->tick_to_x(val) + xoffset - xpos;
+ int x = -9;
+ int w = 18;
+
+ if (tval < 0) { // tval<0 occurs whenever the window is scrolled left, so I switched to signed int (ml)
+ redraw();
+ }
+ else if (opos > tval) {
+ w += opos - tval;
+ x += tval;
+ }
+ else {
+ w += tval - opos;
+ x += opos;
+ }
+ redraw(QRect(x, 0, w, height()));
+ }
+ }
+
+//---------------------------------------------------------
+// mousePressEvent
+//---------------------------------------------------------
+
+void MTScaleFlo::mousePressEvent(QMouseEvent* event)
+ {
+ button = event->button();
+ mouseMoveEvent(event);
+ }
+
+//---------------------------------------------------------
+// mouseReleaseEvent
+//---------------------------------------------------------
+
+void MTScaleFlo::mouseReleaseEvent(QMouseEvent*)
+ {
+ button = Qt::NoButton;
+ }
+
+//---------------------------------------------------------
+// mouseMoveEvent
+//---------------------------------------------------------
+
+void MTScaleFlo::mouseMoveEvent(QMouseEvent* event)
+ {
+ if (event->modifiers() & Qt::ShiftModifier )
+ setCursor(QCursor(Qt::PointingHandCursor));
+ else
+ setCursor(QCursor(Qt::ArrowCursor));
+
+ int tick = AL::sigmap.raster(parent->x_to_tick(event->x()-xoffset+xpos), parent->quant_ticks());
+ if (tick<0) tick=0;
+
+ int i;
+ switch (button) {
+ case Qt::LeftButton:
+ i = 0;
+ break;
+ case Qt::MidButton:
+ i = 1;
+ break;
+ case Qt::RightButton:
+ i = 2;
+ break;
+ default:
+ return; // if no button is pressed the function returns here
+ }
+ Pos p(tick, true);
+
+ if(i== 0 && (event->modifiers() & Qt::ShiftModifier )) { // If shift +LMB we add a marker
+ Marker *alreadyExists = song->getMarkerAt(tick);
+ if (!alreadyExists)
+ song->addMarker(QString(""), tick, false);
+ }
+ else if (i== 2 && (event->modifiers() & Qt::ShiftModifier )) { // If shift +RMB we remove a marker
+ Marker *toRemove = song->getMarkerAt(tick);
+ if (toRemove)
+ song->removeMarker(toRemove);
+ else
+ printf("No marker to remove\n");
+ }
+ else
+ song->setPos(i, p); // all other cases: relocating one of the locators
+ }
+
+
+
+//---------------------------------------------------------
+// draw
+//---------------------------------------------------------
+
+void MTScaleFlo::draw(QPainter& p, const QRect& r)
+ {
+ int x = r.x();
+ int w = r.width();
+
+ x -= 20;
+ w += 40; // wg. Text
+
+ //---------------------------------------------------
+ // draw Marker
+ //---------------------------------------------------
+
+ int y = 12;
+ p.setPen(Qt::black);
+ p.setFont(config.fonts[4]);
+ p.drawLine(r.x(), y+1, r.x() + r.width(), y+1);
+ QRect tr(r);
+ tr.setHeight(12);
+ MarkerList* marker = song->marker();
+ for (iMarker m = marker->begin(); m != marker->end(); ++m) {
+
+ int xp = parent->tick_to_x(m->second.tick()) + xoffset - xpos;
+ if (xp > x+w)
+ break;
+ int xe = r.x() + r.width();
+ iMarker mm = m;
+ ++mm;
+ if (mm != marker->end())
+ xe = parent->tick_to_x(mm->first) + xoffset - xpos;
+
+ QRect tr(xp, 0, xe-xp, 13);
+
+ QRect wr = r.intersect(tr);
+ if(!wr.isEmpty())
+ {
+ if (m->second.current())
+ p.fillRect(wr, Qt::white);
+
+ int x2;
+ if (mm != marker->end())
+ x2 = parent->tick_to_x(mm->first) + xoffset - xpos;
+ else
+ x2 = xp+200;
+
+ if(xp >= -32)
+ p.drawPixmap(xp, 0, *flagIconS);
+
+ if(xp >= -1023)
+ {
+ QRect r = QRect(xp+10, 0, x2-xp, 12);
+ p.setPen(Qt::black);
+ p.drawText(r, Qt::AlignLeft|Qt::AlignVCenter, m->second.name());
+ }
+
+ if(xp >= 0)
+ {
+ p.setPen(Qt::green);
+ p.drawLine(xp, y, xp, height());
+ }
+ }
+ }
+
+ //---------------------------------------------------
+ // draw location marker
+ //---------------------------------------------------
+
+ int h = height()-12;
+
+ for (int i = 0; i < 3; ++i) {
+ int xp = parent->tick_to_x(pos[i]) + xoffset - xpos;
+ if (xp >= x && xp < x+w) {
+ QPixmap* pm = markIcon[i];
+ p.drawPixmap(xp - pm->width()/2, y-1, *pm);
+ }
+ }
+
+
+ //---------------------------------------------------
+ // draw beats
+ //---------------------------------------------------
+
+
+ p.setPen(Qt::black);
+
+ unsigned ctick;
+ int bar1, bar2, beat;
+ unsigned tick;
+
+ ctick = parent->x_to_tick(x - xoffset + xpos);
+ AL::sigmap.tickValues(ctick, &bar1, &beat, &tick);
+ AL::sigmap.tickValues(parent->x_to_tick(x+w - xoffset + xpos), &bar2, &beat, &tick);
+
+
+ int stick = AL::sigmap.bar2tick(bar1, 0, 0);
+ int ntick;
+ for (int bar = bar1; bar <= bar2; bar++, stick = ntick) {
+ ntick = AL::sigmap.bar2tick(bar+1, 0, 0);
+ int tpix = parent->delta_tick_to_delta_x(ntick - stick);
+ if (tpix < 64) {
+ // don�t show beats if measure is this small
+ int n = 1;
+ if (tpix < 32)
+ n = 2;
+ if (tpix <= 16)
+ n = 4;
+ if (tpix < 8)
+ n = 8;
+ if (tpix <= 4)
+ n = 16;
+ if (tpix <= 2)
+ n = 32;
+ if (bar % n)
+ continue;
+ p.setFont(config.fonts[3]);
+ int x = parent->tick_to_x(stick) + xoffset - xpos;
+ QString s;
+ s.setNum(bar + 1);
+ p.drawLine(x, y+1, x, y+1+h);
+// QRect r = QRect(x+2, y, 0, h);
+ QRect r = QRect(x+2, y, 1000, h);
+ p.drawText(r, Qt::AlignLeft|Qt::AlignVCenter|Qt::TextDontClip, s);
+ }
+ else {
+ int z, n;
+ AL::sigmap.timesig(stick, z, n);
+ for (int beat = 0; beat < z; beat++) {
+ int xp = parent->tick_to_x(AL::sigmap.bar2tick(bar, beat, 0)) + xoffset - xpos;
+ QString s;
+ QRect r(xp+2, y, 1000, h);
+ int y1;
+ int num;
+ if (beat == 0) {
+ num = bar + 1;
+ y1 = y + 1;
+ p.setFont(config.fonts[3]);
+ }
+ else {
+ num = beat + 1;
+ y1 = y + 7;
+ p.setFont(config.fonts[1]);
+ r.setY(y+3);
+ }
+ s.setNum(num);
+ p.drawLine(xp, y1, xp, y+1+h);
+ p.drawText(r, Qt::AlignLeft|Qt::AlignVCenter|Qt::TextDontClip, s);
+ }
+ }
+ }
+ }
+
+void MTScaleFlo::set_xpos(int pos)
+{
+ xpos=pos;
+ redraw();
+}
+
+void MTScaleFlo::set_xoffset(int o)
+{
+ xoffset=o;
+ redraw();
+}
+
+void MTScaleFlo::pos_add_changed()
+{
+ redraw();
+}
diff --git a/muse2/muse/widgets/mtscale_flo.h b/muse2/muse/widgets/mtscale_flo.h
new file mode 100644
index 00000000..b7856207
--- /dev/null
+++ b/muse2/muse/widgets/mtscale_flo.h
@@ -0,0 +1,51 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: mtscale_flo.h,v 1.3 2011/05/19 22:27:06 flo Exp $
+// (C) Copyright 1999 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#ifndef __MTSCALE_FLO_H__
+#define __MTSCALE_FLO_H__
+
+#include "view.h"
+
+
+class ScoreCanvas;
+
+//---------------------------------------------------------
+// MTScaleFlo
+// scale for midi track
+//---------------------------------------------------------
+
+class MTScaleFlo : public View {
+ Q_OBJECT
+ unsigned pos[3];
+ int button;
+ ScoreCanvas* parent;
+ int xpos;
+ int xoffset;
+
+ private slots:
+ void songChanged(int);
+
+ protected:
+ virtual void draw(QPainter&, const QRect&);
+ virtual void mousePressEvent(QMouseEvent* event);
+ virtual void mouseMoveEvent(QMouseEvent* event);
+ virtual void mouseReleaseEvent(QMouseEvent* event);
+
+ signals:
+ void timeChanged(unsigned);
+
+ public slots:
+ void setPos(int, unsigned, bool);
+ void set_xpos(int);
+ void pos_add_changed();
+ void set_xoffset(int);
+
+ public:
+ MTScaleFlo(ScoreCanvas* parent_editor, QWidget* parent_widget);
+ };
+#endif
+