summaryrefslogtreecommitdiff
path: root/muse2/muse
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2011-04-12 15:04:11 +0000
committerFlorian Jung <flo@windfisch.org>2011-04-12 15:04:11 +0000
commit585c061fe77c03bb108c9f56671068a061498535 (patch)
treeabaa5088e742f867810848dfb37607e1c9d78808 /muse2/muse
parent533f81167c006932a3bd7d95c62abbbd59157228 (diff)
introduced keymap, fixed all the ugly stuff from the last commit
Diffstat (limited to 'muse2/muse')
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp112
-rw-r--r--muse2/muse/midiedit/scoreedit.h38
2 files changed, 118 insertions, 32 deletions
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index c7e68f0b..94baad4c 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -97,6 +97,37 @@ using namespace std;
#define STAFF_DISTANCE 100
+
+KeyList keymap;
+
+
+
+KeyList::KeyList()
+{
+ clear();
+}
+
+void KeyList::clear()
+{
+ _KeyList::clear(); //DEBUG -- remove these lines and use the commented out below
+ insert(std::pair<const unsigned, KeyEvent> (1536, KeyEvent(A, 0)));
+ insert(std::pair<const unsigned, KeyEvent> (MAX_TICK, KeyEvent(ES, 1536)));
+
+ //insert(std::pair<const unsigned, KeyEvent> (MAX_TICK, KeyEvent(A, 0)));
+}
+
+tonart_t KeyList::key_at_tick(unsigned tick)
+{
+ ciKeyEvent it = upper_bound(tick);
+ if (it == end())
+ {
+ cout << "THIS SHOULD NEVER HAPPEN: key at "<<tick<<" not found!" << endl;
+ return C;
+ }
+
+ return it->second.key;
+}
+
//---------------------------------------------------------
// ScoreEdit
//---------------------------------------------------------
@@ -218,9 +249,11 @@ ScoreCanvas::ScoreCanvas(MidiEditor* pr, QWidget* parent,
void ScoreCanvas::song_changed(int)
{
cout << "song changed!" << endl;
+
+ calc_pos_add_list();
+
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
@@ -449,10 +482,9 @@ ScoreEventList ScoreCanvas::create_appropriate_eventlist(const set<Part*>& parts
result.insert(pair<unsigned, FloEvent>(t, FloEvent(t,0,0,ticks_per_measure,FloEvent::BAR) ) );
}
-
- //TODO FINDMICH MARKER
- result.insert(pair<unsigned, FloEvent>(0, FloEvent(0,FloEvent::KEY_CHANGE, A ) ) );
- result.insert(pair<unsigned, FloEvent>(4*384, FloEvent(4*384,FloEvent::KEY_CHANGE, ES ) ) );
+ //insert key changes
+ for (iKeyEvent it=keymap.begin(); it!=keymap.end(); it++)
+ result.insert(pair<unsigned, FloEvent>(it->second.tick, FloEvent(it->second.tick,FloEvent::KEY_CHANGE, it->second.key ) ) );
// phase two: deal with overlapping notes ---------------------------
@@ -1578,9 +1610,6 @@ void ScoreCanvas::calc_item_pos(ScoreItemList& itemlist)
{
int add=calc_timesig_width(it->num, it->denom);
pos_add+=add;
- pos_add_list[it2->first]+=add;
- //+= is used instead of =, because a key- and time-
- //change can occur at the same time.
}
else if (it->type==FloItem::KEY_CHANGE)
{
@@ -1591,9 +1620,6 @@ void ScoreCanvas::calc_item_pos(ScoreItemList& itemlist)
int n_acc_drawn=aufloes_list.size() + new_acc_list.size();
pos_add+=n_acc_drawn*KEYCHANGE_ACC_DIST+ KEYCHANGE_ACC_LEFTDIST+ KEYCHANGE_ACC_RIGHTDIST;
- pos_add_list[it2->first]+=n_acc_drawn*KEYCHANGE_ACC_DIST+ KEYCHANGE_ACC_LEFTDIST+ KEYCHANGE_ACC_RIGHTDIST;
- //+= is used instead of =, because a key- and time-
- //change can occur at the same time.
curr_key=new_key;
}
@@ -1601,12 +1627,39 @@ void ScoreCanvas::calc_item_pos(ScoreItemList& itemlist)
}
}
+void ScoreCanvas::calc_pos_add_list()
+{
+ using AL::sigmap;
+ using AL::iSigEvent;
+
+
+ pos_add_list.clear();
+
+ //process time signatures
+ for (iSigEvent it=sigmap.begin(); it!=sigmap.end(); it++)
+ pos_add_list[it->second->tick]+=calc_timesig_width(it->second->sig.z, it->second->sig.n);
+
+
+ //process key changes
+ tonart_t curr_key=C;
+ for (iKeyEvent it=keymap.begin(); it!=keymap.end(); it++)
+ {
+ tonart_t new_key=it->second.key;
+ list<int> aufloes_list=calc_accidentials(curr_key, USED_CLEF, new_key);
+ list<int> new_acc_list=calc_accidentials(new_key, USED_CLEF);
+ int n_acc_drawn=aufloes_list.size() + new_acc_list.size();
+ pos_add_list[it->second.tick]+=n_acc_drawn*KEYCHANGE_ACC_DIST+ KEYCHANGE_ACC_LEFTDIST+ KEYCHANGE_ACC_RIGHTDIST;
+
+ curr_key=new_key;
+ }
+}
+
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;
- //in general: drawing too much isn't bad. drawing too few is.
+ //drawing too much isn't bad. drawing too few is.
from_tick=x_to_tick(x1);
from_it=itemlist.lower_bound(from_tick);
@@ -2129,30 +2182,20 @@ int ScoreCanvas::x_to_tick(int x)
return t > min_t ? t : min_t;
}
-tonart_t ScoreCanvas::key_at_tick(int t_) //FINDMICHJETZT besser lösen! nur übergangslösung!
+tonart_t ScoreCanvas::key_at_tick(int t_)
{
- tonart_t tmp;
unsigned int t= (t_>=0) ? t_ : 0;
- 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;
+ return keymap.key_at_tick(t);
}
-timesig_t ScoreCanvas::timesig_at_tick(int t_) //FINDMICHJETZT besser lösen! nur übergangslösung!
+timesig_t ScoreCanvas::timesig_at_tick(int t_)
{
timesig_t tmp;
unsigned int t= (t_>=0) ? t_ : 0;
- 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;
- tmp.denom=it->second.denom;
- }
-
+ AL::sigmap.timesig(t, tmp.num, tmp.denom);
+
return tmp;
}
@@ -2591,12 +2634,14 @@ void ScoreCanvas::pos_changed(int index, unsigned tick, bool scroll)
/* BUGS and potential bugs
+ * o when adding a note, it's added to the first stave
+ * the problem is: there's always the first part selected
* 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
+ * o proper mouse.y -> staff_no translation (plus rounding problems)
*
* IMPORTANT TODO
* o support adding staves to existing score window
@@ -2615,6 +2660,11 @@ void ScoreCanvas::pos_changed(int index, unsigned tick, bool scroll)
* o check if "moving away" works for whole notes [seems to NOT work properly]
*
* less important stuff
+ * o support different keys in different tracks at the same time
+ * calc_pos_add_list and calc_item_pos will be affected by this
+ * calc_pos_add_list must be called before calc_item_pos then,
+ * and calc_item_pos must respect the pos_add_list instead of
+ * keeping its own pos_add variable (which is only an optimisation)
* o use nearest part instead of curr_part, maybe expand
* o draw measure numbers
* o use "unsigned" whereever "unsigned" is meant
@@ -2631,7 +2681,7 @@ void ScoreCanvas::pos_changed(int index, unsigned tick, bool scroll)
* 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 use timesig_t in all timesig-stuff
+ * > o use timesig_t in all timesig-stuff
* o draw a margin around notes which are in a bright color
* o maybe override color 0 with "black"?
* o use bars instead of flags over groups of 8ths / 16ths etc
@@ -2642,16 +2692,16 @@ void ScoreCanvas::pos_changed(int index, unsigned tick, bool scroll)
* o check if the new function for drawing accidential works
* 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 OFFER A WAY TO EDIT THE KEYMAP (and integrate the keymap properly)
+ *
* o check if dragging notes is done correctly
* o after doing the undo stuff right, the "pianoroll isn't informed
* about score-editor's changes"-bug has vanished. did it vanish
* "by accident", or is that the correct solution for this?
- * o process key from muse's event list (has to be implemented first in muse)
* o process accurate timesignatures from muse's list (has to be implemented first in muse)
* ( (2+2+3)/4 or (3+2+2)/4 instead of 7/4 )
* o maybe do expanding parts inside the msgChangeEvent or
diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h
index 84a74cb0..95dde6c2 100644
--- a/muse2/muse/midiedit/scoreedit.h
+++ b/muse2/muse/midiedit/scoreedit.h
@@ -65,6 +65,11 @@ class QScrollArea;
+
+
+
+
+
//---------------------------------------------------------
// ScoreEdit
//---------------------------------------------------------
@@ -147,6 +152,37 @@ struct note_pos_t
bool operator< (const note_pos_t& a, const note_pos_t& b);
+
+// FINDMICH put that keymap-stuff to its appropriate place
+struct KeyEvent
+{
+ tonart_t key;
+ unsigned tick;
+
+ KeyEvent(tonart_t k, unsigned t)
+ {
+ key=k;
+ tick=t;
+ }
+};
+
+typedef std::map<unsigned, KeyEvent, std::less<unsigned> > _KeyList;
+typedef _KeyList::iterator iKeyEvent;
+typedef _KeyList::const_iterator ciKeyEvent;
+typedef _KeyList::reverse_iterator riKeyEvent;
+typedef _KeyList::const_reverse_iterator criKeyEvent;
+
+class KeyList : public _KeyList
+{
+ public:
+ KeyList();
+ void clear();
+ tonart_t key_at_tick(unsigned tick);
+ //TODO FINDMICH: more functions, like add(), remove() have to be implemented
+};
+
+
+
class FloEvent
{
public:
@@ -467,7 +503,7 @@ class ScoreCanvas : public View
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);
-
+ void calc_pos_add_list();