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