summaryrefslogtreecommitdiff
path: root/muse2
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2011-04-12 13:24:35 +0000
committerFlorian Jung <flo@windfisch.org>2011-04-12 13:24:35 +0000
commit533f81167c006932a3bd7d95c62abbbd59157228 (patch)
tree02a6e6697b831402699611147c7f526ae7f29efc /muse2
parent384e0d2f6d77ab107268921511dd91464d4accb3 (diff)
first approach of displaying multiple staves in one score window
this revision is fully functional (or at least should be), but maybe new bugs were introduced. TODO: some things in the source are done pretty ugly, need to beautify that and some features (e.g. grand staves) still need to be done
Diffstat (limited to 'muse2')
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp379
-rw-r--r--muse2/muse/midiedit/scoreedit.h32
2 files changed, 240 insertions, 171 deletions
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index 72b0c4de..c7e68f0b 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -68,6 +68,21 @@ using namespace std;
+//TODO: all das unten richtig machen!
+#define TICKS_PER_WHOLE (config.division*4)
+#define SONG_LENGTH (song->len())
+
+#define quant_max 3 //whole, half, quarter = 0,1,2
+#define quant_max_fraction (1 << quant_max) //whole, half, quarter= 1,2,4
+#define FLO_QUANT (TICKS_PER_WHOLE/quant_max_fraction)
+//FLO_QUANT = how many ticks has a single quantisation area?
+
+
+//FINDMICH MARKER
+//TODO: quant_max richtig setzen!
+
+
+
//do NOT put parentheses around this!
#define PAGESTEP 3/4
@@ -78,6 +93,10 @@ using namespace std;
#define SCROLL_SPEED_MAX 500
//SCROLL_SPEED_MAX is in scroll_pixels_per_second
+
+
+#define STAFF_DISTANCE 100
+
//---------------------------------------------------------
// ScoreEdit
//---------------------------------------------------------
@@ -93,18 +112,13 @@ connect(hscroll, SIGNAL(valueChanged(int)), test, SLOT(scroll_event(int)));
connect(test, SIGNAL(xpos_changed(int)), hscroll, SLOT(setValue(int)));connect(song, SIGNAL(songChanged(int)), test, SLOT(song_changed(int)));
connect(test, SIGNAL(canvas_width_changed(int)), SLOT(canvas_width_changed(int)));
connect(test, SIGNAL(viewport_width_changed(int)), SLOT(viewport_width_changed(int)));
-// mainGrid->setRowStretch(0, 100);
-// mainGrid->setColumnStretch(1, 100);
+
mainGrid->addWidget(test, 0, 0);
mainGrid->addWidget(hscroll,1,0);
hscroll->setMinimum(0);
test->song_changed(0);
test->goto_tick(initPos,true);
-// gridS1->addWidget(test,0,0);
-
-// gridS1->addWidget(canvas, 0, 0);
- // hsplitter->addWidget(test);
}
@@ -172,8 +186,26 @@ ScoreCanvas::ScoreCanvas(MidiEditor* pr, QWidget* parent,
last_len=384;
new_len=-1;
-//fertig mit aufbereiten
- cout << "---------------- CALCULATING DONE ------------------" << endl;
+
+
+ //each track gets its own staff
+ staff_t staff;
+ set<Track*> tracks;
+
+ for (ciPart it=editor->parts()->begin(); it!=editor->parts()->end(); it++)
+ tracks.insert(it->second->track());
+
+ for (set<Track*>::iterator it=tracks.begin(); it!=tracks.end(); it++)
+ {
+ staff.parts.clear();
+ for (ciPart part_it=editor->parts()->begin(); part_it!=editor->parts()->end(); part_it++)
+ if (part_it->second->track() == *it)
+ staff.parts.insert(part_it->second);
+
+ staffs.push_back(staff);
+ }
+
+
scroll_speed=0;
@@ -186,11 +218,15 @@ ScoreCanvas::ScoreCanvas(MidiEditor* pr, QWidget* parent,
void ScoreCanvas::song_changed(int)
{
cout << "song changed!" << endl;
- pos_add_list.clear();
- eventlist=create_appropriate_eventlist(editor->parts());
- itemlist=create_itemlist(eventlist);
- process_itemlist(itemlist); // do note- and rest-grouping and collision avoiding
- calc_item_pos(itemlist);
+ for (list<staff_t>::iterator it=staffs.begin(); it!=staffs.end(); it++)
+ {
+ pos_add_list.clear(); //FINDMICHJETZT schöner machen
+ it->eventlist=create_appropriate_eventlist(it->parts);
+ it->itemlist=create_itemlist(it->eventlist);
+ process_itemlist(it->itemlist); // do note- and rest-grouping and collision avoiding
+ calc_item_pos(it->itemlist);
+ }
+
redraw();
cout << "song had changed, recalculation complete" << endl;
@@ -199,7 +235,8 @@ void ScoreCanvas::song_changed(int)
int ScoreCanvas::canvas_width()
{
- return tick_to_x(itemlist.rbegin()->first);
+ //return tick_to_x(staffs.begin()->itemlist.rbegin()->first);
+ return tick_to_x(SONG_LENGTH);
}
int ScoreCanvas::viewport_width()
@@ -336,31 +373,6 @@ bool operator< (const note_pos_t& a, const note_pos_t& b)
}
-//TODO: all das unten richtig machen!
-#define TICKS_PER_WHOLE (config.division*4)
-#define SONG_LENGTH (song->len())
-
-#define quant_max 3 //whole, half, quarter = 0,1,2
-#define quant_max_fraction (1 << quant_max) //whole, half, quarter= 1,2,4
-#define FLO_QUANT (TICKS_PER_WHOLE/quant_max_fraction)
-//FLO_QUANT = how many ticks has a single quantisation area?
-
-
-//FINDMICH MARKER
-//TODO: quant_max richtig setzen!
-
-/* builds the event list used by the score editor.
- * that list contains only note-on and -off, time-sig- and
- * key-change events.
- * it stores them sorted by their time (quantized); if more
- * events with the same time occur, the NOTE-OFFs are
- * put before the NOTE-ONs
- * it only operates on parts which were selected in the
- * arranger when the score viewer was started
- *
- * this abstracts the rest of the renderer from muse's internal
- * data structures, making this easy to port to another application
- */
int flo_quantize(int tick)
{
@@ -373,8 +385,21 @@ int flo_quantize_floor(int tick)
//TODO quantizing must be done with the proper functions, see above
return int(tick / FLO_QUANT) * FLO_QUANT;
}
+
-ScoreEventList ScoreCanvas::create_appropriate_eventlist(PartList* pl)
+/* builds the event list used by the score editor.
+ * that list contains only note-on and -off, time-sig- and
+ * key-change events.
+ * it stores them sorted by their time (quantized); if more
+ * events with the same time occur, the NOTE-OFFs are
+ * put before the NOTE-ONs
+ * it only operates on parts which were selected in the
+ * arranger when the score viewer was started
+ *
+ * this abstracts the rest of the renderer from muse's internal
+ * data structures, making this easy to port to another application
+ */
+ScoreEventList ScoreCanvas::create_appropriate_eventlist(const set<Part*>& parts)
{
using AL::sigmap;
using AL::iSigEvent;
@@ -384,9 +409,9 @@ ScoreEventList ScoreCanvas::create_appropriate_eventlist(PartList* pl)
// phase one: fill the list -----------------------------------------
//insert note on events
- for (iPart partIt=pl->begin(); partIt!=pl->end(); partIt++)
+ for (set<Part*>::const_iterator part_it=parts.begin(); part_it!=parts.end(); part_it++)
{
- Part* part=partIt->second;
+ Part* part=*part_it;
EventList* el=part->events();
for (iEvent it=el->begin(); it!=el->end(); it++)
@@ -845,14 +870,14 @@ void ScoreCanvas::draw_tie (QPainter& p, int x1, int x4, int yo, bool up, QColor
p.drawPath(path);
}
-void ScoreCanvas::draw_accidentials(QPainter& p, int x, const list<int>& acc_list, const QPixmap& pix)
+void ScoreCanvas::draw_accidentials(QPainter& p, int x, int y_offset, const list<int>& acc_list, const QPixmap& pix)
{
int n_acc_drawn=0;
for (list<int>::const_iterator acc_it=acc_list.begin(); acc_it!=acc_list.end(); acc_it++)
{
int y_coord=YDIST+4*YLEN - ( *acc_it -2)*YLEN/2; //Y_MARKER
- draw_pixmap(p,x + n_acc_drawn*KEYCHANGE_ACC_DIST,y_coord,pix);
+ draw_pixmap(p,x + n_acc_drawn*KEYCHANGE_ACC_DIST,y_offset + y_coord,pix);
n_acc_drawn++;
}
}
@@ -1470,14 +1495,14 @@ QRect FloItem::bbox() const
return bbox_center(x,y,pix->size());
}
-void ScoreCanvas::draw_note_lines(QPainter& p)
+void ScoreCanvas::draw_note_lines(QPainter& p, int y)
{
int xend=width();
p.setPen(Qt::black);
for (int i=0;i<5;i++)
- p.drawLine(0,YDIST+i*YLEN,xend,YDIST+i*YLEN);
+ p.drawLine(0,y + YDIST+i*YLEN,xend,y + YDIST+i*YLEN);
}
@@ -1576,7 +1601,7 @@ void ScoreCanvas::calc_item_pos(ScoreItemList& itemlist)
}
}
-void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist, int x1, int x2)
+void ScoreCanvas::draw_items(QPainter& p, int y, ScoreItemList& itemlist, int x1, int x2)
{
int from_tick, to_tick;
ScoreItemList::iterator from_it, to_it;
@@ -1605,15 +1630,15 @@ void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist, int x1, int x
//actually drawn.
if (to_it!=itemlist.end()) to_it++; //do one tick more than neccessary. this will draw ties
- draw_items(p,itemlist,from_it, to_it);
+ draw_items(p,y, from_it, to_it);
}
-void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist)
+void ScoreCanvas::draw_items(QPainter& p, int y, ScoreItemList& itemlist)
{
- draw_items(p,itemlist,x_pos,x_pos+width()-x_left);
+ draw_items(p,y, itemlist,x_pos,x_pos+width()-x_left);
}
-void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist, ScoreItemList::iterator from_it, ScoreItemList::iterator to_it)
+void ScoreCanvas::draw_items(QPainter& p, int y_offset, ScoreItemList::iterator from_it, ScoreItemList::iterator to_it)
{
// init accidentials properly
vorzeichen_t curr_accidential[7];
@@ -1696,13 +1721,13 @@ void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist, ScoreItemList
{ //Y_MARKER
p.setPen(Qt::black);
for (int i=0; i>=it->pos.height; i-=2)
- p.drawLine(it->x-it->pix->width()*AUX_LINE_LEN/2 -x_pos+x_left,YDIST+4*YLEN - (i-2)*YLEN/2,it->x+it->pix->width()*AUX_LINE_LEN/2-x_pos+x_left,YDIST+4*YLEN - (i-2)*YLEN/2);
+ p.drawLine(it->x-it->pix->width()*AUX_LINE_LEN/2 -x_pos+x_left,y_offset + YDIST+4*YLEN - (i-2)*YLEN/2,it->x+it->pix->width()*AUX_LINE_LEN/2-x_pos+x_left,y_offset + YDIST+4*YLEN - (i-2)*YLEN/2);
}
else if (it->pos.height >= 12) //we need auxiliary lines on the top?
{ //Y_MARKER
p.setPen(Qt::black);
for (int i=12; i<=it->pos.height; i+=2)
- p.drawLine(it->x-it->pix->width()*AUX_LINE_LEN/2 -x_pos+x_left,YDIST+4*YLEN - (i-2)*YLEN/2,it->x+it->pix->width()*AUX_LINE_LEN/2-x_pos+x_left,YDIST+4*YLEN - (i-2)*YLEN/2);
+ p.drawLine(it->x-it->pix->width()*AUX_LINE_LEN/2 -x_pos+x_left,y_offset + YDIST+4*YLEN - (i-2)*YLEN/2,it->x+it->pix->width()*AUX_LINE_LEN/2-x_pos+x_left,y_offset + YDIST+4*YLEN - (i-2)*YLEN/2);
}
it->is_active= ( (song->cpos() >= it->source_event->tick() + it->source_part->tick()) &&
@@ -1713,7 +1738,7 @@ void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist, ScoreItemList
if (audio->isPlaying() && it->is_active)
color_index=HIGHLIGHTED_PIXMAP;
- draw_pixmap(p,it->x -x_pos+x_left,it->y,it->pix[color_index]);
+ draw_pixmap(p,it->x -x_pos+x_left,y_offset + it->y,it->pix[color_index]);
//TODO FINDMICH maybe draw a margin around bright colors?
//maybe draw the default color in black?
@@ -1732,7 +1757,7 @@ void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist, ScoreItemList
for (int i=0;i<it->dots;i++)
{
- draw_pixmap(p,it->x+x_dot -x_pos+x_left,it->y+y_dot,pix_dot[color_index]);
+ draw_pixmap(p,it->x+x_dot -x_pos+x_left,y_offset + it->y+y_dot,pix_dot[color_index]);
x_dot+=DOT_XDIST;
}
@@ -1748,7 +1773,7 @@ void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist, ScoreItemList
case SHARP: acc_pix=pix_sharp; break;
case B: acc_pix=pix_b; break;
}
- draw_pixmap(p,it->x-ACCIDENTIAL_DIST -x_pos+x_left,it->y, acc_pix[color_index]);
+ draw_pixmap(p,it->x-ACCIDENTIAL_DIST -x_pos+x_left,y_offset + it->y, acc_pix[color_index]);
curr_accidential[modulo(it->pos.height,7)]=it->pos.vorzeichen;
}
@@ -1758,7 +1783,7 @@ void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist, ScoreItemList
if (it->is_tie_dest)
{
cout << "drawing tie" << endl;
- draw_tie(p,it->tie_from_x-x_pos+x_left,it->x -x_pos+x_left,it->y, (it->len==0) ? true : (it->stem==DOWNWARDS) , config.partColors[color_index]);
+ draw_tie(p,it->tie_from_x-x_pos+x_left,it->x -x_pos+x_left,y_offset + it->y, (it->len==0) ? true : (it->stem==DOWNWARDS) , config.partColors[color_index]);
// in english: "if it's a whole note, tie is upwards (true). if not, tie is upwards if
// stem is downwards and vice versa"
}
@@ -1769,7 +1794,7 @@ void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist, ScoreItemList
for (int i=0;i<it->dots;i++) cout << ".";
cout << " , ausweich="<<it->ausweich<<endl;
- draw_pixmap(p,it->x -x_pos+x_left,it->y,*it->pix);
+ draw_pixmap(p,it->x -x_pos+x_left,y_offset + it->y,*it->pix);
//draw dots
@@ -1786,7 +1811,7 @@ void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist, ScoreItemList
for (int i=0;i<it->dots;i++)
{
- draw_pixmap(p,it->x+x_dot -x_pos+x_left,it->y+y_dot,pix_dot[BLACK_PIXMAP]);
+ draw_pixmap(p,it->x+x_dot -x_pos+x_left,y_offset + it->y+y_dot,pix_dot[BLACK_PIXMAP]);
x_dot+=DOT_XDIST;
}
}
@@ -1795,7 +1820,7 @@ void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist, ScoreItemList
cout << "\tBAR" << endl;
p.setPen(Qt::black); //Y_MARKER
- p.drawLine(it->x -x_pos+x_left,YDIST,it->x -x_pos+x_left,YDIST+4*YLEN);
+ p.drawLine(it->x -x_pos+x_left,y_offset + YDIST,it->x -x_pos+x_left,y_offset + YDIST+4*YLEN);
for (int i=0;i<7;i++)
curr_accidential[i]=default_accidential[i];
@@ -1804,7 +1829,7 @@ void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist, ScoreItemList
{
cout << "\tTIME SIGNATURE: "<<it->num<<"/"<<it->denom<<endl;
- draw_timesig(p, it->x - x_pos+x_left, it->num, it->denom);
+ draw_timesig(p, it->x - x_pos+x_left, y_offset, it->num, it->denom);
}
else if (it->type==FloItem::KEY_CHANGE)
{
@@ -1815,13 +1840,13 @@ void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist, ScoreItemList
list<int> new_acc_list=calc_accidentials(new_key, USED_CLEF);
// vorzeichen aus curr_key auflösen
- draw_accidentials(p, it->x + KEYCHANGE_ACC_LEFTDIST - x_pos+x_left, aufloes_list, pix_noacc[BLACK_PIXMAP]);
+ draw_accidentials(p, it->x + KEYCHANGE_ACC_LEFTDIST - x_pos+x_left, y_offset, aufloes_list, pix_noacc[BLACK_PIXMAP]);
// alle vorzeichen aus new_key zeichnen
QPixmap* pix = is_sharp_key(new_key) ? &pix_sharp[BLACK_PIXMAP] : &pix_b[BLACK_PIXMAP];
vorzeichen_t new_accidential = is_sharp_key(new_key) ? SHARP : B;
- draw_accidentials(p, it->x + aufloes_list.size()*KEYCHANGE_ACC_DIST + KEYCHANGE_ACC_LEFTDIST - x_pos+x_left, new_acc_list, *pix);
+ draw_accidentials(p, it->x + aufloes_list.size()*KEYCHANGE_ACC_DIST + KEYCHANGE_ACC_LEFTDIST - x_pos+x_left, y_offset, new_acc_list, *pix);
for (int i=0;i<7;i++)
curr_accidential[i]=default_accidential[i]=NONE;
@@ -1838,28 +1863,36 @@ void ScoreCanvas::draw_items(QPainter& p, ScoreItemList& itemlist, ScoreItemList
if (upstem_x!=-1)
{
upstem_x=upstem_x-pix_quarter[0].width()/2 +pix_quarter[0].width() -1;
- p.drawLine(upstem_x -x_pos+x_left, upstem_y1, upstem_x -x_pos+x_left, upstem_y2-STEM_LEN);
+ p.drawLine(upstem_x -x_pos+x_left, y_offset + upstem_y1, upstem_x -x_pos+x_left, y_offset + upstem_y2-STEM_LEN);
if (upflag>=3) //if the note needs a flag
- p.drawPixmap(upstem_x -x_pos+x_left,upstem_y2-STEM_LEN,pix_flag_up[upflag-3]);
+ p.drawPixmap(upstem_x -x_pos+x_left,y_offset + upstem_y2-STEM_LEN,pix_flag_up[upflag-3]);
}
if (downstem_x!=-1)
{
downstem_x=downstem_x-pix_quarter[0].width()/2;
- p.drawLine(downstem_x -x_pos+x_left, downstem_y1+STEM_LEN, downstem_x -x_pos+x_left, downstem_y2);
+ p.drawLine(downstem_x -x_pos+x_left, y_offset + downstem_y1+STEM_LEN, downstem_x -x_pos+x_left, y_offset + downstem_y2);
if (downflag>=3) //if the note needs a flag
- p.drawPixmap(downstem_x -x_pos+x_left,downstem_y1+STEM_LEN-pix_flag_down[downflag-3].height(),pix_flag_down[downflag-3]);
+ p.drawPixmap(downstem_x -x_pos+x_left,y_offset + downstem_y1+STEM_LEN-pix_flag_down[downflag-3].height(),pix_flag_down[downflag-3]);
}
}
}
bool ScoreCanvas::need_redraw_for_hilighting()
{
- return need_redraw_for_hilighting(x_pos,x_pos+width()-x_left);
+ for (list<staff_t>::iterator it=staffs.begin(); it!=staffs.end(); it++)
+ if (need_redraw_for_hilighting(it->itemlist)) return true;
+
+ return false;
}
-bool ScoreCanvas::need_redraw_for_hilighting(int x1, int x2)
+bool ScoreCanvas::need_redraw_for_hilighting(ScoreItemList& itemlist)
+{
+ return need_redraw_for_hilighting(itemlist, x_pos,x_pos+width()-x_left);
+}
+
+bool ScoreCanvas::need_redraw_for_hilighting(ScoreItemList& itemlist, int x1, int x2)
{
int from_tick, to_tick;
ScoreItemList::iterator from_it, to_it;
@@ -1917,8 +1950,7 @@ int ScoreCanvas::clef_height(clef_t clef)
#define CLEF_LEFTMARGIN 5
#define CLEF_RIGHTMARGIN 5
-
-void ScoreCanvas::draw_preamble(QPainter& p)
+void ScoreCanvas::draw_preamble(QPainter& p, int y_offset)
{
int x_left_old=x_left;
int tick=x_to_tick(x_pos);
@@ -1927,7 +1959,7 @@ void ScoreCanvas::draw_preamble(QPainter& p)
QPixmap* pix_clef= (USED_CLEF==BASS) ? pix_clef_bass : pix_clef_violin;
int y_coord=YDIST+4*YLEN - ( clef_height(USED_CLEF) -2)*YLEN/2; //Y_MARKER
- draw_pixmap(p,CLEF_LEFTMARGIN + pix_clef->width()/2,y_coord,*pix_clef);
+ draw_pixmap(p,CLEF_LEFTMARGIN + pix_clef->width()/2,y_offset + y_coord,*pix_clef);
x_left= CLEF_LEFTMARGIN + pix_clef->width() + CLEF_RIGHTMARGIN + KEYCHANGE_ACC_LEFTDIST;
@@ -1937,7 +1969,7 @@ void ScoreCanvas::draw_preamble(QPainter& p)
QPixmap* pix_acc=is_sharp_key(key) ? &pix_sharp[BLACK_PIXMAP] : &pix_b[BLACK_PIXMAP];
list<int> acclist=calc_accidentials(key,USED_CLEF);
- draw_accidentials(p,x_left,acclist ,*pix_acc);
+ draw_accidentials(p,x_left, y_offset, acclist ,*pix_acc);
x_left+=acclist.size()*KEYCHANGE_ACC_DIST + KEYCHANGE_ACC_RIGHTDIST + TIMESIG_LEFTMARGIN;
@@ -1945,13 +1977,13 @@ void ScoreCanvas::draw_preamble(QPainter& p)
// draw time signature ----------------------------------------------
timesig_t timesig=timesig_at_tick(tick);
- draw_timesig(p, x_left, timesig.num, timesig.denom);
+ draw_timesig(p, x_left, y_offset, timesig.num, timesig.denom);
x_left+=calc_timesig_width(timesig.num, timesig.denom)+TIMESIG_RIGHTMARGIN;
// draw bar ---------------------------------------------------------
p.setPen(Qt::black); //Y_MARKER
- p.drawLine(x_left,YDIST,x_left,YDIST+4*YLEN);
+ p.drawLine(x_left,y_offset + YDIST,x_left,y_offset + YDIST+4*YLEN);
if (x_left_old!=x_left)
@@ -1959,7 +1991,7 @@ void ScoreCanvas::draw_preamble(QPainter& p)
}
-void ScoreCanvas::draw_timesig(QPainter& p, int x, int num, int denom)
+void ScoreCanvas::draw_timesig(QPainter& p, int x, int y_offset, int num, int denom)
{
int num_width=calc_number_width(num);
int denom_width=calc_number_width(denom);
@@ -1968,8 +2000,8 @@ void ScoreCanvas::draw_timesig(QPainter& p, int x, int num, int denom)
int denom_indent=(width-denom_width)/2 + TIMESIG_LEFTMARGIN;
int y=YDIST+2*YLEN;
- draw_number(p, x+num_indent, y-DIGIT_YDIST, num);
- draw_number(p, x+denom_indent, y+DIGIT_YDIST, denom);
+ draw_number(p, x+num_indent, y_offset + y-DIGIT_YDIST, num);
+ draw_number(p, x+denom_indent, y_offset + y+DIGIT_YDIST, denom);
}
int ScoreCanvas::calc_timesig_width(int num, int denom)
@@ -1999,7 +2031,7 @@ void ScoreCanvas::draw_number(QPainter& p, int x, int y, int n)
}
-void ScoreCanvas::draw(QPainter& p, const QRect& rect)
+void ScoreCanvas::draw(QPainter& p, const QRect&)
{
cout <<"now in ScoreCanvas::draw"<<endl;
@@ -2007,11 +2039,17 @@ void ScoreCanvas::draw(QPainter& p, const QRect& rect)
p.setPen(Qt::black);
- draw_note_lines(p);
- draw_preamble(p);
- p.setClipRect(x_left+1,0,p.device()->width(),p.device()->height());
- draw_items(p, itemlist);
- p.setClipping(false);
+ int y=0;
+ for (list<staff_t>::iterator it=staffs.begin(); it!=staffs.end(); it++)
+ {
+ draw_note_lines(p,y);
+ draw_preamble(p,y);
+ p.setClipRect(x_left+1,0,p.device()->width(),p.device()->height());
+ draw_items(p,y, it->itemlist);
+ p.setClipping(false);
+
+ y+=STAFF_DISTANCE;
+ }
}
@@ -2091,24 +2129,24 @@ int ScoreCanvas::x_to_tick(int x)
return t > min_t ? t : min_t;
}
-tonart_t ScoreCanvas::key_at_tick(int t_)
+tonart_t ScoreCanvas::key_at_tick(int t_) //FINDMICHJETZT besser lösen! nur übergangslösung!
{
tonart_t tmp;
unsigned int t= (t_>=0) ? t_ : 0;
- for (ScoreEventList::iterator it=eventlist.begin(); it!=eventlist.end() && it->first<=t; it++)
+ for (ScoreEventList::iterator it=staffs.begin()->eventlist.begin(); it!=staffs.begin()->eventlist.end() && it->first<=t; it++)
if (it->second.type==FloEvent::KEY_CHANGE)
tmp=it->second.tonart;
return tmp;
}
-timesig_t ScoreCanvas::timesig_at_tick(int t_)
+timesig_t ScoreCanvas::timesig_at_tick(int t_) //FINDMICHJETZT besser lösen! nur übergangslösung!
{
timesig_t tmp;
unsigned int t= (t_>=0) ? t_ : 0;
- for (ScoreEventList::iterator it=eventlist.begin(); it!=eventlist.end() && it->first<=t; it++)
+ for (ScoreEventList::iterator it=staffs.begin()->eventlist.begin(); it!=staffs.begin()->eventlist.end() && it->first<=t; it++)
if (it->second.type==FloEvent::TIME_SIG)
{
tmp.num=it->second.num;
@@ -2170,89 +2208,100 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event)
// denn der "bereich" eines schlags geht von schlag_begin bis nächsterschlag_begin-1
// noten werden aber genau in die mitte dieses bereiches gezeichnet
- int y=event->y();
+ int staff_no= event->y() / STAFF_DISTANCE;
+
+ cout << "STAFF NO = " << staff_no << endl;
+
+ int y=event->y() - staff_no*STAFF_DISTANCE;
int x=event->x()+x_pos-x_left;
int tick=flo_quantize_floor(x_to_tick(x));
//TODO quantizing must (maybe?) be done with the proper functions
-
- cout << "mousePressEvent at "<<x<<"/"<<y<<"; tick="<<tick<<endl;
- set<FloItem, floComp>::iterator it;
- for (it=itemlist[tick].begin(); it!=itemlist[tick].end(); it++)
- if (it->type==FloItem::NOTE)
- if (it->bbox().contains(x,y))
- break;
+ list<staff_t>::iterator it=staffs.begin();
+ for (int i=0; i<staff_no && it!=staffs.end(); i++)
+ it++;
- if (it!=itemlist[tick].end()) //we found something?
+ if (it!=staffs.end())
{
- mouse_down_pos=event->pos();
- mouse_operation=NO_OP;
-
- int t=tick;
- set<FloItem, floComp>::iterator found;
+ ScoreItemList& itemlist=it->itemlist;
+
+ cout << "mousePressEvent at "<<x<<"/"<<y<<"; tick="<<tick<<endl;
+ set<FloItem, floComp>::iterator it;
+ for (it=itemlist[tick].begin(); it!=itemlist[tick].end(); it++)
+ if (it->type==FloItem::NOTE)
+ if (it->bbox().contains(x,y))
+ break;
- do
+ if (it!=itemlist[tick].end()) //we found something?
{
- found=itemlist[t].find(FloItem(FloItem::NOTE, it->pos));
- if (found == itemlist[t].end())
+ mouse_down_pos=event->pos();
+ mouse_operation=NO_OP;
+
+ int t=tick;
+ set<FloItem, floComp>::iterator found;
+
+ do
{
- cout << "FATAL: THIS SHOULD NEVER HAPPEN: could not find the note's tie-destination" << endl;
- break;
+ found=itemlist[t].find(FloItem(FloItem::NOTE, it->pos));
+ if (found == itemlist[t].end())
+ {
+ cout << "FATAL: THIS SHOULD NEVER HAPPEN: could not find the note's tie-destination" << endl;
+ break;
+ }
+ else
+ {
+ t+=calc_len(found->len, found->dots);
+ }
+ } while (found->tied);
+
+ int total_begin=it->begin_tick;
+ int total_end=t;
+
+ int this_begin=tick;
+ int this_end=this_begin+calc_len(it->len, it->dots);
+
+ //that's the only note corresponding to the event?
+ if (this_begin==total_begin && this_end==total_end)
+ {
+ if (x < it->x)
+ mouse_x_drag_operation=BEGIN;
+ else
+ mouse_x_drag_operation=LENGTH;
}
+ //that's NOT the only note?
else
{
- t+=calc_len(found->len, found->dots);
+ if (this_begin==total_begin)
+ mouse_x_drag_operation=BEGIN;
+ else if (this_end==total_end)
+ mouse_x_drag_operation=LENGTH;
+ else
+ mouse_x_drag_operation=NO_OP;
+ }
+
+ cout << "you clicked at a note with begin at "<<it->begin_tick<<" and end at "<<t<<endl;
+ cout << "x-drag-operation will be "<<mouse_x_drag_operation<<endl;
+ cout << "pointer to part is "<<it->source_part;
+ if (!it->source_part) cout << " (WARNING! THIS SHOULD NEVER HAPPEN!)";
+ cout << endl;
+
+ dragged_event=*it->source_event;
+ dragged_event_part=it->source_part;
+ dragged_event_original_pitch=dragged_event.pitch();
+
+ if ((mouse_erases_notes) || (event->button()==Qt::MidButton)) //erase?
+ {
+ audio->msgDeleteEvent(dragged_event, dragged_event_part, true, false, false);
+ }
+ else if (event->button()==Qt::LeftButton) //edit?
+ {
+ setMouseTracking(true);
+ dragging=true;
+ song->startUndo();
}
- } while (found->tied);
-
- int total_begin=it->begin_tick;
- int total_end=t;
-
- int this_begin=tick;
- int this_end=this_begin+calc_len(it->len, it->dots);
-
- //that's the only note corresponding to the event?
- if (this_begin==total_begin && this_end==total_end)
- {
- if (x < it->x)
- mouse_x_drag_operation=BEGIN;
- else
- mouse_x_drag_operation=LENGTH;
- }
- //that's NOT the only note?
- else
- {
- if (this_begin==total_begin)
- mouse_x_drag_operation=BEGIN;
- else if (this_end==total_end)
- mouse_x_drag_operation=LENGTH;
- else
- mouse_x_drag_operation=NO_OP;
- }
-
- cout << "you clicked at a note with begin at "<<it->begin_tick<<" and end at "<<t<<endl;
- cout << "x-drag-operation will be "<<mouse_x_drag_operation<<endl;
- cout << "pointer to part is "<<it->source_part;
- if (!it->source_part) cout << " (WARNING! THIS SHOULD NEVER HAPPEN!)";
- cout << endl;
-
- dragged_event=*it->source_event;
- dragged_event_part=it->source_part;
- dragged_event_original_pitch=dragged_event.pitch();
-
- if ((mouse_erases_notes) || (event->button()==Qt::MidButton)) //erase?
- {
- audio->msgDeleteEvent(dragged_event, dragged_event_part, true, false, false);
}
- else if (event->button()==Qt::LeftButton) //edit?
+ else //we found nothing?
{
- setMouseTracking(true);
- dragging=true;
- song->startUndo();
- }
- }
- else //we found nothing?
- {
if ((event->button()==Qt::LeftButton) && (mouse_inserts_notes))
{
signed int relative_tick=(signed) tick - curr_part->tick();
@@ -2288,7 +2337,7 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event)
}
}
}
-
+ }
}
void ScoreCanvas::mouseReleaseEvent (QMouseEvent* event)
@@ -2545,9 +2594,16 @@ void ScoreCanvas::pos_changed(int index, unsigned tick, bool scroll)
* o when changing color of a displayed part, note heads aren't redrawn
* o when pressing "STOP", the active note isn't redrawn "normally"
*
+ * CURRENT TODO
+ * o menu entries etc for creating new staves etc.
+ * o proper mouse.y -> staff_no translation
+ *
* IMPORTANT TODO
- * o support violin and bass clefs at one time
- * o support multiple note systems
+ * o support adding staves to existing score window
+ * o support changing between "all into one" and "each gets one staff"
+ * o do the STAFF_DISTANCE thingy better
+ * (grand staffs have to be nearer, user-definable distance etc)
+ * o support grand staves
* o let the user select which clef to use
* o removing the part the score's working on isn't handled
* o let the user select the currently edited part
@@ -2587,6 +2643,8 @@ void ScoreCanvas::pos_changed(int index, unsigned tick, bool scroll)
* o refuse to resize so that width gets smaller or equal than x_left
* o set distances properly [looks okay, doesn't it?]
* o maybe eliminate all the compiler warnings
+ * o change iterators into const iterators
+ * o add tracks in correct order to score
*
* stuff for the other muse developers
* o check if dragging notes is done correctly
@@ -2633,5 +2691,8 @@ void ScoreCanvas::pos_changed(int index, unsigned tick, bool scroll)
* (the systems have enough space in between, so there won't be notes
* from sys1 in sys2. if there are, they're ignored for simplicity)
* then we proceed as usual (adding, removing, changing notes)
+ *
+ *
+ * pos_add_list stays the same for each staff, so we only need one
*/
diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h
index 53bcae66..84a74cb0 100644
--- a/muse2/muse/midiedit/scoreedit.h
+++ b/muse2/muse/midiedit/scoreedit.h
@@ -24,6 +24,7 @@
#include "event.h"
#include "view.h"
#include "gconfig.h"
+#include "part.h"
#include <set>
#include <map>
@@ -48,7 +49,6 @@ class QToolBar;
class QPushButton;
class CtrlEdit;
class Splitter;
-class PartList;
class Toolbar1;
class Xml;
class QuantConfig;
@@ -415,6 +415,13 @@ struct timesig_t
int denom;
};
+struct staff_t
+{
+ set<Part*> parts;
+ ScoreEventList eventlist;
+ ScoreItemList itemlist;
+};
+
class ScoreCanvas : public View
{
Q_OBJECT
@@ -423,10 +430,10 @@ class ScoreCanvas : public View
static void draw_pixmap(QPainter& p, int x, int y, const QPixmap& pm);
static void draw_tie (QPainter& p, int x1, int x4, int yo, bool up=true, QColor color=Qt::black);
- static void draw_accidentials(QPainter& p, int x, const list<int>& acc_list, const QPixmap& pix);
+ static void draw_accidentials(QPainter& p, int x, int y_offset, const list<int>& acc_list, const QPixmap& pix);
static list<int> calc_accidentials(tonart_t key, clef_t clef, tonart_t next_key=C);
- static void draw_timesig(QPainter& p, int x, int num, int denom);
+ static void draw_timesig(QPainter& p, int x, int y_offset, int num, int denom);
static int calc_timesig_width(int num, int denom);
static void draw_number(QPainter& p, int x, int y, int n);
@@ -434,7 +441,7 @@ class ScoreCanvas : public View
- static ScoreEventList create_appropriate_eventlist(PartList* pl);
+ static ScoreEventList create_appropriate_eventlist(const set<Part*>& parts);
static ScoreItemList create_itemlist(ScoreEventList& eventlist);
static note_pos_t note_pos_(int note, tonart_t key);
@@ -454,11 +461,11 @@ class ScoreCanvas : public View
void process_itemlist(ScoreItemList& itemlist);
- void draw_note_lines(QPainter& p);
- void draw_preamble(QPainter& p);
- void draw_items(QPainter& p, ScoreItemList& itemlist, ScoreItemList::iterator from_it, ScoreItemList::iterator to_it);
- void draw_items(QPainter& p, ScoreItemList& itemlist, int x1, int x2);
- void draw_items(QPainter& p, ScoreItemList& itemlist);
+ void draw_note_lines(QPainter& p, int y);
+ void draw_preamble(QPainter& p, int y);
+ void draw_items(QPainter& p, int y, ScoreItemList::iterator from_it, ScoreItemList::iterator to_it);
+ void draw_items(QPainter& p, int y, ScoreItemList& itemlist, int x1, int x2);
+ void draw_items(QPainter& p, int y, ScoreItemList& itemlist);
void calc_item_pos(ScoreItemList& itemlist);
@@ -473,7 +480,8 @@ class ScoreCanvas : public View
bool need_redraw_for_hilighting(ScoreItemList::iterator from_it, ScoreItemList::iterator to_it);
- bool need_redraw_for_hilighting(int x1, int x2);
+ bool need_redraw_for_hilighting(ScoreItemList& itemlist, int x1, int x2);
+ bool need_redraw_for_hilighting(ScoreItemList& itemlist);
bool need_redraw_for_hilighting();
int canvas_width();
@@ -491,8 +499,8 @@ class ScoreCanvas : public View
static bool pixmaps_loaded;
std::map<int,int> pos_add_list;
- ScoreEventList eventlist;
- ScoreItemList itemlist;
+
+ list<staff_t> staffs;
// the drawing area is split into a "preamble" containing clef,
// key and time signature, and the "item's area" containing the