1 //=============================================================================
2 // MuseScore
3 // Music Composition & Notation
4 //
5 // Copyright (C) 2011 Werner Schweer
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 "libmscore/score.h"
14 #include "libmscore/chord.h"
15 #include "libmscore/note.h"
16 #include "libmscore/notedot.h"
17 #include "libmscore/beam.h"
18 #include "libmscore/stem.h"
19 #include "libmscore/hook.h"
20 #include "libmscore/tuplet.h"
21 #include "libmscore/staff.h"
22 #include "inspector.h"
23 #include "inspectorNote.h"
24
25 namespace Ms {
26
27 //---------------------------------------------------------
28 // InspectorNote
29 //---------------------------------------------------------
30
InspectorNote(QWidget * parent)31 InspectorNote::InspectorNote(QWidget* parent)
32 : InspectorElementBase(parent)
33 {
34 s.setupUi(addWidget());
35 c.setupUi(addWidget());
36 n.setupUi(addWidget());
37
38 static const NoteHead::Scheme schemes[] = {
39 NoteHead::Scheme::HEAD_AUTO,
40 NoteHead::Scheme::HEAD_NORMAL,
41 NoteHead::Scheme::HEAD_PITCHNAME,
42 NoteHead::Scheme::HEAD_PITCHNAME_GERMAN,
43 NoteHead::Scheme::HEAD_SOLFEGE,
44 NoteHead::Scheme::HEAD_SOLFEGE_FIXED,
45 NoteHead::Scheme::HEAD_SHAPE_NOTE_4,
46 NoteHead::Scheme::HEAD_SHAPE_NOTE_7_AIKIN,
47 NoteHead::Scheme::HEAD_SHAPE_NOTE_7_FUNK,
48 NoteHead::Scheme::HEAD_SHAPE_NOTE_7_WALKER
49 };
50
51 static const NoteHead::Group heads[] = {
52 NoteHead::Group::HEAD_NORMAL,
53 NoteHead::Group::HEAD_CROSS,
54 NoteHead::Group::HEAD_PLUS,
55 NoteHead::Group::HEAD_XCIRCLE,
56 NoteHead::Group::HEAD_WITHX,
57 NoteHead::Group::HEAD_TRIANGLE_UP,
58 NoteHead::Group::HEAD_TRIANGLE_DOWN,
59 NoteHead::Group::HEAD_SLASHED1,
60 NoteHead::Group::HEAD_SLASHED2,
61 NoteHead::Group::HEAD_DIAMOND,
62 NoteHead::Group::HEAD_DIAMOND_OLD,
63 NoteHead::Group::HEAD_CIRCLED,
64 NoteHead::Group::HEAD_CIRCLED_LARGE,
65 NoteHead::Group::HEAD_LARGE_ARROW,
66
67 NoteHead::Group::HEAD_SLASH,
68 NoteHead::Group::HEAD_BREVIS_ALT,
69
70 NoteHead::Group::HEAD_DO,
71 NoteHead::Group::HEAD_RE,
72 NoteHead::Group::HEAD_MI,
73 NoteHead::Group::HEAD_FA,
74 NoteHead::Group::HEAD_SOL,
75 NoteHead::Group::HEAD_LA,
76 NoteHead::Group::HEAD_TI
77 };
78
79 //
80 // fix order of noteheads
81 //
82 for (auto head : heads)
83 n.noteHeadGroup->addItem(NoteHead::group2userName(head), int(head));
84
85 for (auto scheme : schemes)
86 n.noteHeadScheme->addItem(NoteHead::scheme2userName(scheme), int(scheme));
87
88 // noteHeadType starts at -1: correct values and count one item more (HEAD_AUTO)
89 for (int i = 0; i <= int(NoteHead::Type::HEAD_TYPES); ++i) {
90 n.noteHeadType->addItem(NoteHead::type2userName(NoteHead::Type(i - 1)));
91 n.noteHeadType->setItemData(i, i - 1);
92 }
93
94 const std::vector<InspectorItem> iiList = {
95 { Pid::SMALL, 0, n.small, n.resetSmall },
96 { Pid::HEAD_SCHEME, 0, n.noteHeadScheme, n.resetNoteHeadScheme },
97 { Pid::HEAD_GROUP, 0, n.noteHeadGroup, n.resetNoteHeadGroup },
98 { Pid::HEAD_TYPE, 0, n.noteHeadType, n.resetNoteHeadType },
99 { Pid::MIRROR_HEAD, 0, n.mirrorHead, n.resetMirrorHead },
100 { Pid::PLAY, 0, n.play, n.resetPlay },
101 { Pid::TUNING, 0, n.tuning, n.resetTuning },
102 { Pid::VELO_TYPE, 0, n.velocityType, n.resetVelocityType },
103 { Pid::VELO_OFFSET, 0, n.velocity, n.resetVelocity },
104 { Pid::FIXED, 0, n.fixed, n.resetFixed },
105 { Pid::FIXED_LINE, 0, n.fixedLine, n.resetFixedLine },
106
107 { Pid::OFFSET, 1, c.offset, c.resetOffset },
108 { Pid::SMALL, 1, c.small, c.resetSmall },
109 { Pid::NO_STEM, 1, c.stemless, c.resetStemless },
110 { Pid::STEM_DIRECTION, 1, c.stemDirection, c.resetStemDirection },
111
112 { Pid::LEADING_SPACE, 2, s.leadingSpace, s.resetLeadingSpace },
113 };
114 const std::vector<InspectorPanel> ppList = {
115 { s.title, s.panel },
116 { c.title, c.panel },
117 { n.title, n.panel },
118 };
119 mapSignals(iiList, ppList);
120
121 connect(n.noteHeadScheme, SIGNAL(currentIndexChanged(int)), SLOT(noteHeadSchemeChanged(int)));
122
123 connect(n.dot1, SIGNAL(clicked()), SLOT(dot1Clicked()));
124 connect(n.dot2, SIGNAL(clicked()), SLOT(dot2Clicked()));
125 connect(n.dot3, SIGNAL(clicked()), SLOT(dot3Clicked()));
126 connect(n.dot4, SIGNAL(clicked()), SLOT(dot4Clicked()));
127 connect(n.hook, SIGNAL(clicked()), SLOT(hookClicked()));
128 connect(n.stem, SIGNAL(clicked()), SLOT(stemClicked()));
129 connect(n.beam, SIGNAL(clicked()), SLOT(beamClicked()));
130 connect(n.tuplet, SIGNAL(clicked()), SLOT(tupletClicked()));
131 }
132
133 //---------------------------------------------------------
134 // setElement
135 //---------------------------------------------------------
136
setElement()137 void InspectorNote::setElement()
138 {
139 Note* note = toNote(inspector->element());
140
141 int i = note->dots().size();
142 n.dot1->setEnabled(i > 0);
143 n.dot2->setEnabled(i > 1);
144 n.dot3->setEnabled(i > 2);
145 n.dot4->setEnabled(i > 3);
146 n.stem->setEnabled(note->chord()->stem());
147 n.hook->setEnabled(note->chord()->hook());
148 n.beam->setEnabled(note->chord()->beam());
149 n.tuplet->setEnabled(note->chord()->tuplet());
150
151 InspectorElementBase::setElement();
152
153 //must be placed after InspectorBase::setElement() cause the last one sets resetButton enability
154 if (note->staffType()->group() == StaffGroup::STANDARD)
155 noteHeadSchemeChanged(n.noteHeadScheme->currentIndex());
156 else {
157 n.noteHeadScheme->setEnabled(false);
158 n.resetNoteHeadScheme->setEnabled(false);
159 n.noteHeadGroup->setEnabled(false);
160 n.resetNoteHeadGroup->setEnabled(false);
161 }
162
163 bool nograce = !note->chord()->isGrace();
164 s.leadingSpace->setEnabled(nograce);
165 s.resetLeadingSpace->setEnabled(nograce && s.leadingSpace->value());
166
167 if (!n.fixed->isChecked())
168 n.fixedLine->setEnabled(false);
169 if (!n.play->isChecked())
170 n.playWidget->setVisible(false);
171 }
172
173 //---------------------------------------------------------
174 // noteHeadSchemeChanged
175 //---------------------------------------------------------
176
noteHeadSchemeChanged(int index)177 void InspectorNote::noteHeadSchemeChanged(int index)
178 {
179 Note* note = toNote(inspector->element());
180 NoteHead::Scheme scheme = (index == 0 ? note->staffType()->noteHeadScheme() : NoteHead::Scheme(index - 1));
181 if (scheme == NoteHead::Scheme::HEAD_NORMAL) {
182 n.noteHeadGroup->setEnabled(true);
183 n.resetNoteHeadGroup->setEnabled(note->headGroup() != NoteHead::Group::HEAD_NORMAL);
184 }
185 else {
186 n.noteHeadGroup->setEnabled(false);
187 n.resetNoteHeadGroup->setEnabled(false);
188 }
189 }
190
191 //---------------------------------------------------------
192 // dot1Clicked
193 //---------------------------------------------------------
194
dot1Clicked()195 void InspectorNote::dot1Clicked()
196 {
197 Note* note = toNote(inspector->element());
198 if (note == 0)
199 return;
200 if (note->dots().size() > 0) {
201 NoteDot* dot = note->dot(0);
202 dot->score()->select(dot);
203 dot->score()->update();
204 inspector->update();
205 }
206 }
207
208 //---------------------------------------------------------
209 // dot2Clicked
210 //---------------------------------------------------------
211
dot2Clicked()212 void InspectorNote::dot2Clicked()
213 {
214 Note* note = toNote(inspector->element());
215 if (note == 0)
216 return;
217 if (note->dots().size() > 1) {
218 NoteDot* dot = note->dot(1);
219 dot->score()->select(dot);
220 dot->score()->update();
221 inspector->update();
222 }
223 }
224
225 //---------------------------------------------------------
226 // dot3Clicked
227 //---------------------------------------------------------
228
dot3Clicked()229 void InspectorNote::dot3Clicked()
230 {
231 Note* note = toNote(inspector->element());
232 if (note == 0)
233 return;
234 if (note->dots().size() > 2) {
235 NoteDot* dot = note->dot(2);
236 dot->score()->select(dot);
237 dot->score()->update();
238 inspector->update();
239 }
240 }
241
242 //---------------------------------------------------------
243 // dot4Clicked
244 //---------------------------------------------------------
245
dot4Clicked()246 void InspectorNote::dot4Clicked()
247 {
248 Note* note = toNote(inspector->element());
249 if (note == 0)
250 return;
251 if (note->dots().size() > 3) {
252 NoteDot* dot = note->dot(3);
253 dot->score()->select(dot);
254 dot->score()->update();
255 inspector->update();
256 }
257 }
258
259 //---------------------------------------------------------
260 // hookClicked
261 //---------------------------------------------------------
262
hookClicked()263 void InspectorNote::hookClicked()
264 {
265 Note* note = toNote(inspector->element());
266 if (note == 0)
267 return;
268 Hook* hook = note->chord()->hook();
269 if (hook) {
270 note->score()->select(hook);
271 note->score()->update();
272 inspector->update();
273 }
274 }
275
276 //---------------------------------------------------------
277 // stemClicked
278 //---------------------------------------------------------
279
stemClicked()280 void InspectorNote::stemClicked()
281 {
282 Note* note = toNote(inspector->element());
283 if (note == 0)
284 return;
285 Stem* stem = note->chord()->stem();
286 if (stem) {
287 note->score()->select(stem);
288 note->score()->update();
289 inspector->update();
290 }
291 }
292
293 //---------------------------------------------------------
294 // beamClicked
295 //---------------------------------------------------------
296
beamClicked()297 void InspectorNote::beamClicked()
298 {
299 Note* note = toNote(inspector->element());
300 if (note == 0)
301 return;
302 Beam* beam = note->chord()->beam();
303 if (beam) {
304 note->score()->select(beam);
305 note->score()->update();
306 inspector->update();
307 }
308 }
309
310 //---------------------------------------------------------
311 // tupletClicked
312 //---------------------------------------------------------
313
tupletClicked()314 void InspectorNote::tupletClicked()
315 {
316 Note* note = toNote(inspector->element());
317 if (note == 0)
318 return;
319 Tuplet* tuplet = note->chord()->tuplet();
320 if (tuplet) {
321 note->score()->select(tuplet);
322 note->score()->update();
323 inspector->update();
324 }
325 }
326
327 }
328
329