summaryrefslogtreecommitdiff
path: root/muse2/muse
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2011-04-10 15:45:54 +0000
committerFlorian Jung <flo@windfisch.org>2011-04-10 15:45:54 +0000
commit95d9d855ab60dfb05e499d877d725aed9aead6ed (patch)
treef84d23ea36107a0d75a08b9f1a0f8eab1982b90d /muse2/muse
parentcb193f62e79ae5f2ba75d8c7435ac10dc85499ee (diff)
implemented automatic scrolling and did some cosmetic stuff:
corrected time-sig and key-change order, full-measure-rests are now drawn properly and distances have been set properly
Diffstat (limited to 'muse2/muse')
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp121
-rw-r--r--muse2/muse/midiedit/scoreedit.h11
2 files changed, 100 insertions, 32 deletions
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index 5405bf24..85065e62 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -3,6 +3,14 @@
//the trailing slash is necessary
#define FONT_PATH "/home/flo/muse-glyphs/"
+//=========================================================
+// MusE
+// Linux Music Editor
+// scoreedit.cpp
+// (C) Copyright 2011 Florian Jung (florian.a.jung@web.de)
+//=========================================================
+
+
#include <QLayout>
#include <QSizeGrip>
#include <QLabel>
@@ -175,6 +183,8 @@ ScoreCanvas::ScoreCanvas(MidiEditor* pr, QWidget* parent,
//fertig mit aufbereiten
cout << "---------------- CALCULATING DONE ------------------" << endl;
+
+ connect(song, SIGNAL(posChanged(int, unsigned, bool)), SLOT(pos_changed(int,unsigned,bool)));
}
void ScoreCanvas::song_changed(int)
@@ -188,7 +198,17 @@ void ScoreCanvas::song_changed(int)
redraw();
cout << "song had changed, recalculation complete" << endl;
- emit canvas_width_changed(tick_to_x(itemlist.rbegin()->first));
+ emit canvas_width_changed(canvas_width());
+}
+
+int ScoreCanvas::canvas_width()
+{
+ return tick_to_x(itemlist.rbegin()->first);
+}
+
+int ScoreCanvas::viewport_width()
+{
+ return (width() - x_left);
}
//flo code starting here
@@ -740,8 +760,8 @@ list<note_len_t> ScoreCanvas::parse_note_len(int len_ticks, int begin_tick, vect
#define ACCIDENTIAL_DIST 11
#define KEYCHANGE_ACC_DIST 9
-#define KEYCHANGE_ACC_LEFTDIST 3
-#define KEYCHANGE_ACC_RIGHTDIST 3
+#define KEYCHANGE_ACC_LEFTDIST 9
+#define KEYCHANGE_ACC_RIGHTDIST 0
#define stdmap std::map
@@ -802,7 +822,7 @@ ScoreItemList ScoreCanvas::create_itemlist(ScoreEventList& eventlist)
tonart_t tmp_key=C;
int lastevent=0;
int next_measure=-1;
- int last_measure=0;
+ int last_measure=-1;
vector<int> emphasize_list=create_emphasize_list(4,4); //actually unneccessary, for safety
for (ScoreEventList::iterator it=eventlist.begin(); it!=eventlist.end(); it++)
@@ -825,23 +845,36 @@ ScoreItemList ScoreCanvas::create_itemlist(ScoreEventList& eventlist)
if (type==FloEvent::BAR)
{
- // if neccessary, insert rest at between last note and end-of-measure
- int rest=t-lastevent;
- if (rest)
+ if (last_measure!=-1) //i.e.: "this is NOT the first bar"
{
- printf("\tend-of-measure: set rest at %i with len %i\n",lastevent,rest);
-
- list<note_len_t> lens=parse_note_len(rest,lastevent-last_measure,emphasize_list,DOTTED_RESTS,UNSPLIT_RESTS);
- unsigned tmppos=lastevent;
- for (list<note_len_t>::iterator x=lens.begin(); x!=lens.end(); x++)
+ if (lastevent==last_measure) //there was no note?
{
- cout << "\t\tpartial rest with len="<<x->len<<", dots="<<x->dots<<endl;
- itemlist[tmppos].insert( FloItem(FloItem::REST,notepos,x->len,x->dots) );
- tmppos+=calc_len(x->len,x->dots);
- itemlist[tmppos].insert( FloItem(FloItem::REST_END,notepos,0,0) );
+ unsigned tmppos=(last_measure+t-FLO_QUANT)/2;
+ cout << "\tend-of-measure: this was an empty measure. inserting rest in between at t="<<tmppos << endl;
+ itemlist[tmppos].insert( FloItem(FloItem::REST,notepos,0,0) );
+ itemlist[t].insert( FloItem(FloItem::REST_END,notepos,0,0) );
+ }
+ else
+ {
+ // if neccessary, insert rest at between last note and end-of-measure
+ int rest=t-lastevent;
+ if (rest)
+ {
+ printf("\tend-of-measure: set rest at %i with len %i\n",lastevent,rest);
+
+ list<note_len_t> lens=parse_note_len(rest,lastevent-last_measure,emphasize_list,DOTTED_RESTS,UNSPLIT_RESTS);
+ unsigned tmppos=lastevent;
+ for (list<note_len_t>::iterator x=lens.begin(); x!=lens.end(); x++)
+ {
+ cout << "\t\tpartial rest with len="<<x->len<<", dots="<<x->dots<<endl;
+ itemlist[tmppos].insert( FloItem(FloItem::REST,notepos,x->len,x->dots) );
+ tmppos+=calc_len(x->len,x->dots);
+ itemlist[tmppos].insert( FloItem(FloItem::REST_END,notepos,0,0) );
+ }
+ }
}
}
-
+
lastevent=t;
last_measure=t;
next_measure=t+len;
@@ -1832,7 +1865,7 @@ void ScoreCanvas::draw_preamble(QPainter& p)
if (x_left_old!=x_left)
- emit viewport_width_changed(width() - x_left);
+ emit viewport_width_changed(viewport_width());
}
@@ -2283,12 +2316,33 @@ void ScoreCanvas::scroll_event(int x)
//the position goto would set it to, nothing happens
void ScoreCanvas::goto_tick(int tick, bool force)
{
- //TODO FINDMICH: implement force
-
- x_pos=tick_to_x(tick);
- redraw();
-
- emit xpos_changed(x_pos);
+ if (!force)
+ {
+ if (tick < x_to_tick(x_pos))
+ {
+ x_pos=tick_to_x(tick) - x_left;
+ if (x_pos<0) x_pos=0;
+ if (x_pos>canvas_width()) x_pos=canvas_width();
+
+ emit xpos_changed(x_pos);
+ }
+ else if (tick > x_to_tick(x_pos+viewport_width()*PAGESTEP))
+ {
+ x_pos=tick_to_x(tick);
+ if (x_pos<0) x_pos=0;
+ if (x_pos>canvas_width()) x_pos=canvas_width();
+
+ emit xpos_changed(x_pos);
+ }
+ }
+ else
+ {
+ x_pos=tick_to_x(tick)-viewport_width()/2;
+ if (x_pos<0) x_pos=0;
+ if (x_pos>canvas_width()) x_pos=canvas_width();
+
+ emit xpos_changed(x_pos);
+ }
}
//---------------------------------------------------------
@@ -2299,9 +2353,21 @@ void ScoreCanvas::resizeEvent(QResizeEvent* ev)
{
QWidget::resizeEvent(ev); //TODO is this really neccessary?
- emit viewport_width_changed( ev->size().width() - x_left );
+ emit viewport_width_changed( viewport_width() );
}
+void ScoreCanvas::pos_changed(int index, unsigned tick, bool scroll)
+{
+ if ((index==0) && scroll) //potential need to scroll?
+ {
+ switch (song->follow())
+ {
+ case Song::NO: break;
+ case Song::JUMP: goto_tick(tick,false); break;
+ case Song::CONTINUOUS: goto_tick(tick,true); break;
+ }
+ }
+}
// TODO: testen: kommen die segfaults von muse oder von mir? [ von mir ]
// TODO: testen, ob das noten-splitten korrekt arbeitet [ scheint zu klappen ]
// TODO: testen, ob shift immer korrekt gesetzt wird [ scheint zu klappen ]
@@ -2348,7 +2414,6 @@ void ScoreCanvas::resizeEvent(QResizeEvent* ev)
* o let the user select the currently edited part
* o let the user select between "colors after the parts",
* "colors after selected/unselected part" and "all black"
- * o automatically scroll when playing
* o support selections
*
* less important stuff
@@ -2356,7 +2421,6 @@ void ScoreCanvas::resizeEvent(QResizeEvent* ev)
* o let the user select whether the preamble should have
* a fixed length (?)
* o let the user select what the preamble has to contain
- * o set distances properly
* o use timesig_t in all timesig-stuff
* o emit a "song-changed" signal instead of calling our
* internal song_changed() function
@@ -2368,10 +2432,9 @@ void ScoreCanvas::resizeEvent(QResizeEvent* ev)
* o deal with expanding parts or clip (expanding is better)
* o check if making the program clef-aware hasn't broken anything
* e.g. accidentials, creating notes, rendering etc.
- * o replace all kinds of "full-measure-rests" with the whole rest
- * in the middle of the measure
* o check if the new function for drawing accidential works
* the change was introduced after 873815e57a5d1edc147710b524936b6f6260f555
+ * o set distances properly [looks okay, doesn't it?]
*
* stuff for the other muse developers
* o check if dragging notes is done correctly
diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h
index bb091e6a..f927cf69 100644
--- a/muse2/muse/midiedit/scoreedit.h
+++ b/muse2/muse/midiedit/scoreedit.h
@@ -149,7 +149,7 @@ bool operator< (const note_pos_t& a, const note_pos_t& b);
class FloEvent
{
public:
- enum typeEnum { NOTE_ON = 30, NOTE_OFF = 10, BAR = 20, TIME_SIG=23, KEY_CHANGE=26 }; //the order matters!
+ enum typeEnum { NOTE_ON = 30, NOTE_OFF = 10, BAR = 20, KEY_CHANGE=23, TIME_SIG=26 }; //the order matters!
typeEnum type;
unsigned tick;
Part* source_part;
@@ -196,7 +196,7 @@ class FloEvent
class FloItem
{
public:
- enum typeEnum { NOTE=21, REST=22, NOTE_END=01, REST_END=02, BAR =10, TIME_SIG=13, KEY_CHANGE=16}; //the order matters!
+ enum typeEnum { NOTE=21, REST=22, NOTE_END=01, REST_END=02, BAR =10, KEY_CHANGE=13, TIME_SIG=16}; //the order matters!
typeEnum type;
unsigned begin_tick;
Event* source_event;
@@ -450,6 +450,10 @@ class ScoreCanvas : public View
int tick_to_x(int t);
int x_to_tick(int x);
int calc_posadd(int t);
+
+
+ int canvas_width();
+ int viewport_width();
QPixmap pix_whole[NUM_PARTCOLORS+1], pix_half[NUM_PARTCOLORS+1], pix_quarter[NUM_PARTCOLORS+1];
QPixmap pix_r1, pix_r2, pix_r4, pix_r8, pix_r16;
@@ -502,8 +506,9 @@ class ScoreCanvas : public View
void scroll_event(int);
void song_changed(int);
void goto_tick(int,bool);
+ void pos_changed(int i, unsigned u, bool b);
- signals:
+ signals:
void xpos_changed(int);
void viewport_width_changed(int);
void canvas_width_changed(int);