1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2013 Werner Schweer and others
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License version 2
9 //  as published by the Free Software Foundation and appearing in
10 //  the file LICENSE.GPL
11 //=============================================================================
12 
13 #include "noteGroups.h"
14 #include "libmscore/chord.h"
15 #include "libmscore/mcursor.h"
16 #include "libmscore/timesig.h"
17 #include "libmscore/score.h"
18 #include "libmscore/part.h"
19 #include "libmscore/key.h"
20 #include "libmscore/icon.h"
21 #include "libmscore/staff.h"
22 #include "menus.h"
23 #include "musescore.h"
24 
25 namespace Ms {
26 
27 //---------------------------------------------------------
28 //   createScore
29 //---------------------------------------------------------
30 
createScore(int n,TDuration::DurationType t,std::vector<Chord * > * chords)31 Score* NoteGroups::createScore(int n, TDuration::DurationType t, std::vector<Chord*>* chords)
32       {
33       MCursor c;
34       c.setTimeSig(_sig);
35       c.createScore("");
36       c.addPart("voice");
37       c.move(0, Fraction(0,1));
38       c.addKeySig(Key::C);
39       TimeSig* nts = c.addTimeSig(_sig);
40       if (!_z.isEmpty())
41             nts->setNumeratorString(_z);
42       if (!_n.isEmpty())
43             nts->setDenominatorString(_n);
44       GroupNode node {0, 0};
45       Groups ng;
46       ng.push_back(node);
47       nts->setGroups(ng);
48 
49       for (int i = 0; i < n; ++i) {
50             Chord* chord = c.addChord(77, t);
51             Fraction tick = chord->rtick();
52             chord->setBeamMode(_groups.beamMode(tick.ticks(), t));
53             chord->setStemDirection(Direction::UP);
54             chords->push_back(chord);
55             }
56 
57       c.score()->style().set(Sid::pageOddLeftMargin, 0.0);
58       c.score()->style().set(Sid::pageOddTopMargin, 10.0/INCH);
59       c.score()->style().set(Sid::startBarlineSingle, true);
60 
61       StaffType* st = c.score()->staff(0)->staffType(Fraction(0,1));
62       st->setLines(1);          // single line only
63       st->setGenClef(false);    // no clef
64 //      st->setGenTimesig(false); // don't display time sig since ExampleView is unable to reflect custom time sig text/symbols
65 
66       return c.score();
67       }
68 
69 //---------------------------------------------------------
70 //   NoteGroups
71 //---------------------------------------------------------
72 
NoteGroups(QWidget * parent)73 NoteGroups::NoteGroups(QWidget* parent)
74    : QGroupBox(parent)
75       {
76       setupUi(this);
77       static const IconAction bpa[] = {
78             { IconType::SBEAM,    "beam-start" },
79             { IconType::MBEAM,    "beam-mid" },
80             { IconType::BEAM32,   "beam32" },
81             { IconType::BEAM64,   "beam64" },
82             { IconType::NONE,     ""}
83             };
84 
85       iconPalette->setName(QT_TRANSLATE_NOOP("Palette", "Beam Properties"));
86       iconPalette->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
87       //iconPalette->setMag(.5);
88       iconPalette->setGrid(27, 40);
89       iconPalette->setMinimumWidth(27 * 4 * Palette::guiMag() + 1);     // enough room for all icons, with roundoff
90       iconPalette->setDrawGrid(true);
91       populateIconPalette(iconPalette, bpa);
92       iconPalette->setReadOnly(true);
93       iconPalette->setFixedHeight(iconPalette->heightForWidth(iconPalette->width()));
94       iconPalette->updateGeometry();
95 
96       connect(resetGroups, SIGNAL(clicked()), SLOT(resetClicked()));
97       connect(view8,  SIGNAL(noteClicked(Note*)), SLOT(noteClicked(Note*)));
98       connect(view16, SIGNAL(noteClicked(Note*)), SLOT(noteClicked(Note*)));
99       connect(view32, SIGNAL(noteClicked(Note*)), SLOT(noteClicked(Note*)));
100       connect(view8,  SIGNAL(beamPropertyDropped(Chord*,Icon*)), SLOT(beamPropertyDropped(Chord*,Icon*)));
101       connect(view16, SIGNAL(beamPropertyDropped(Chord*,Icon*)), SLOT(beamPropertyDropped(Chord*,Icon*)));
102       connect(view32, SIGNAL(beamPropertyDropped(Chord*,Icon*)), SLOT(beamPropertyDropped(Chord*,Icon*)));
103       }
104 
105 //---------------------------------------------------------
106 //   setSig
107 //---------------------------------------------------------
108 
setSig(Fraction sig,const Groups & g,const QString & z,const QString & n)109 void NoteGroups::setSig(Fraction sig, const Groups& g, const QString& z, const QString& n)
110       {
111       _sig    = sig;
112       _z      = z;
113       _n      = n;
114       _groups = g;
115       chords8.clear();
116       chords16.clear();
117       chords32.clear();
118       Fraction f = _sig.reduced();
119       int nn   = f.numerator() * (8 / f.denominator());
120       view8->setScore(createScore(nn, TDuration::DurationType::V_EIGHTH, &chords8));
121       nn   = f.numerator() * (16 / f.denominator());
122       view16->setScore(createScore(nn, TDuration::DurationType::V_16TH, &chords16));
123       nn   = f.numerator() * (32 / f.denominator());
124       view32->setScore(createScore(nn, TDuration::DurationType::V_32ND, &chords32));
125       view8->resetMatrix();
126       view16->resetMatrix();
127       view32->resetMatrix();
128       }
129 
130 //---------------------------------------------------------
131 //   groups
132 //---------------------------------------------------------
133 
groups()134 Groups NoteGroups::groups()
135       {
136       Groups g;
137       for (Chord* chord : chords8)
138             g.addStop(chord->rtick().ticks(), chord->durationType().type(), chord->beamMode());
139       for (Chord* chord : chords16)
140             g.addStop(chord->rtick().ticks(), chord->durationType().type(), chord->beamMode());
141       for (Chord* chord : chords32)
142             g.addStop(chord->rtick().ticks(), chord->durationType().type(), chord->beamMode());
143       return g;
144       }
145 
146 //---------------------------------------------------------
147 //   resetClicked
148 //---------------------------------------------------------
149 
resetClicked()150 void NoteGroups::resetClicked()
151       {
152       setSig(_sig, _groups, _z, _n);
153       }
154 
155 //---------------------------------------------------------
156 //   noteClicked
157 //---------------------------------------------------------
158 
noteClicked(Note * note)159 void NoteGroups::noteClicked(Note* note)
160       {
161       Chord* chord = note->chord();
162       if (chord->beamMode() == Beam::Mode::AUTO)
163             updateBeams(chord, Beam::Mode::BEGIN);
164       else if (chord->beamMode() == Beam::Mode::BEGIN)
165             updateBeams(chord, Beam::Mode::AUTO);
166       }
167 
168 //---------------------------------------------------------
169 //   beamPropertyDropped
170 //---------------------------------------------------------
171 
beamPropertyDropped(Chord * chord,Icon * icon)172 void NoteGroups::beamPropertyDropped(Chord* chord, Icon* icon)
173       {
174       switch (icon->iconType()) {
175             case IconType::SBEAM:
176                   updateBeams(chord, Beam::Mode::BEGIN);
177                   break;
178             case IconType::MBEAM:
179                   updateBeams(chord, Beam::Mode::AUTO);
180                   break;
181             case IconType::BEAM32:
182                   updateBeams(chord, Beam::Mode::BEGIN32);
183                   break;
184             case IconType::BEAM64:
185                   updateBeams(chord, Beam::Mode::BEGIN64);
186                   break;
187             default:
188                   break;
189             }
190       }
191 
192 //---------------------------------------------------------
193 //   updateBeams
194 //     takes into account current state of changeShorterCheckBox to update smaller valued notes as well
195 //---------------------------------------------------------
196 
updateBeams(Chord * chord,Beam::Mode m)197 void NoteGroups::updateBeams(Chord* chord, Beam::Mode m)
198       {
199       chord->setBeamMode(m);
200       chord->score()->doLayout();
201 
202       if (changeShorterCheckBox->checkState() == Qt::Checked) {
203             Fraction tick = chord->tick();
204             bool foundChord = false;
205             for (Chord* c : chords8) {
206                   if (c == chord) {
207                         foundChord = true;
208                         break;
209                         }
210                   }
211             for (Chord* c : chords16) {
212                   if (foundChord) {
213                         if (c->tick() == tick) {
214                               c->setBeamMode(m);
215                               c->score()->doLayout();
216                               break;
217                               }
218                         }
219                   else if (c == chord) {
220                         foundChord = true;
221                         break;
222                         }
223                   }
224             for (Chord* c : chords32) {
225                   if (foundChord) {
226                         if (c->tick() == tick) {
227                               c->setBeamMode(m);
228                               c->score()->doLayout();
229                               break;
230                               }
231                         }
232                   }
233             }
234 
235       view8->update();
236       view16->update();
237       view32->update();
238       }
239 
240 }
241 
242