1 /* contexts.cpp
2 * Context finders: functions that find the current clef, key, and time
3 * signature contexts for the measures being displayed
4 *
5 * These functions are also invoked when a staff is created
6 *
7 *
8 * for Denemo, a gtk+ frontend to GNU Lilypond
9 * (c) 1999-2005 Matthew Hiller, Adam Tee
10 */
11
12 #include "command/contexts.h"
13 #include "display/drawingprims.h"
14 #include "command/object.h"
15 #include "command/staff.h"
16 #include "command/measure.h"
17
18 /**
19 * This function finds the first DenemoObject of type thetype *before* measure
20 * curmeasure. It returns NULL if it was unable to find such a DenemoObject
21 *
22 * @param curmeasure the current measure to search
23 * @param thetype type of DenemoObject to find
24 * @return the first DenemoObject of type the type
25 */
26 static DenemoObject *
find_measure_context(measurenode * curmeasure,DenemoObjType thetype)27 find_measure_context (measurenode * curmeasure, DenemoObjType thetype)
28 {
29 objnode *curobj;
30 if (curmeasure && curmeasure->prev)
31 curmeasure = curmeasure->prev;
32 else
33 return NULL;
34
35 curobj = measure_last_obj_node (curmeasure);
36 while (1)
37 {
38 while (!curobj)
39 { /* Cycle back to preceding measure */
40 if (!curmeasure->prev)
41 return NULL; /* That is, we've fallen off the beginnig */
42 curmeasure = curmeasure->prev;
43 curobj = measure_last_obj_node (curmeasure);
44 }
45 if (((DenemoObject *) curobj->data)->type == thetype)
46 return (DenemoObject *) curobj->data;
47 else
48 curobj = curobj->prev;
49 }
50 }
51
52
53
54 /**
55 * This function finds the first DenemoObject of type thetype before si->currentobject
56 * It returns NULL if it was unable to find such a DenemoObject
57 * @param si the DenemoMovement with si->currentobject and si->currentmeasure set
58 * @param thetype type of DenemoObject to find
59 * @return the first DenemoObject of type thetype
60 */
61 static DenemoObject *
find_context_of_object(DenemoMovement * si,DenemoObjType thetype)62 find_context_of_object (DenemoMovement * si, DenemoObjType thetype)
63 {
64 objnode *curobj = si->currentobject;
65 measurenode *curmeasure = si->currentmeasure;
66 if (curmeasure == NULL)
67 return NULL;
68 if (curobj == NULL)
69 while (curmeasure->prev)
70 {
71 curmeasure = curmeasure->prev;
72 curobj = measure_last_obj_node (curmeasure);
73 if (curobj)
74 break;
75 }
76
77 if (curobj == NULL || curmeasure == NULL)
78 return NULL;
79
80 while (curobj)
81 {
82 if (((DenemoObject *) curobj->data)->type == thetype)
83 return (DenemoObject *) curobj->data;
84 else
85 curobj = curobj->prev;
86 if (curobj == NULL)
87 { /* go back to preceding measure */
88 while (curmeasure->prev)
89 {
90 curmeasure = curmeasure->prev;
91 curobj = measure_last_obj_node (curmeasure);
92 if (curobj)
93 break;
94 }
95 }
96 }
97 return NULL;
98 }
99
100
101 DenemoObject *
get_clef_before_object(objnode * obj)102 get_clef_before_object (objnode * obj)
103 {
104 DenemoObject *ret;
105 objnode *curobj = Denemo.project->movement->currentobject;
106 Denemo.project->movement->currentobject = obj;
107 ret = find_context_of_object (Denemo.project->movement, CLEF);
108 Denemo.project->movement->currentobject = curobj;
109 return ret;
110 }
111
112 /* find the clef in which the currentobject lies */
113 gint
find_prevailing_clef(DenemoMovement * si)114 find_prevailing_clef (DenemoMovement * si)
115 {
116 return ((clef*)get_prevailing_context (CLEF))->type;
117 /*
118 DenemoStaff *curstaff = ((DenemoStaff *) si->currentstaff->data);
119 DenemoObject *obj = find_context_of_object (si, CLEF);
120 //g_debug("prevailing clef %d\n", obj? ((clef *) obj->object)->type:curstaff->clef.type);
121 return obj ? ((clef *) obj->object)->type : curstaff->clef.type;
122 * */
123 }
124
125 /* returns a pointer to a CLEF TIMESIG or KEYSIG structure which holds the information on the prevailing context for the current object */
126 gpointer
get_prevailing_context(DenemoObjType type)127 get_prevailing_context (DenemoObjType type)
128 {
129 DenemoStaff *curstaff = ((DenemoStaff *) Denemo.project->movement->currentstaff->data);
130 gpointer *obj;
131 switch (type)
132 {
133 case CLEF:
134 obj = (gpointer)(Denemo.project->movement->currentobject?((DenemoObject*)Denemo.project->movement->currentobject->data)->clef:((DenemoMeasure*)Denemo.project->movement->currentmeasure->data)->clef);
135 break;
136 case KEYSIG:
137 obj = (gpointer)(Denemo.project->movement->currentobject?((DenemoObject*)Denemo.project->movement->currentobject->data)->keysig:((DenemoMeasure*)Denemo.project->movement->currentmeasure->data)->keysig);
138
139 break;
140 case TIMESIG:
141 obj = (gpointer)((DenemoMeasure*)Denemo.project->movement->currentmeasure->data)->timesig;
142
143 break;
144 default:
145 g_critical ("Wrong type in call to get_prevailing_context");
146 obj = NULL;
147 break;
148 }
149 return obj;
150 }
151
152 /**
153 * Finds the first occurrences of the clef, keysig and timesig of the
154 * current staff inserting them into the passed CURSTAFFSTRUCT
155 *
156 * @param curstaffstruct the current staff
157 * @param si the scoreinfo structure
158 * @return none
159 */
160 void
find_leftmost_staffcontext(DenemoStaff * curstaffstruct,DenemoMovement * si)161 find_leftmost_staffcontext (DenemoStaff * curstaffstruct, DenemoMovement * si)
162 {
163 measurenode *leftmeasure = g_list_nth (curstaffstruct->themeasures,
164 si->leftmeasurenum - 1);
165 DenemoObject *obj;
166
167 if ((obj = find_measure_context (leftmeasure, CLEF)))
168 curstaffstruct->leftmost_clefcontext = ((clef *) obj->object);
169 else
170 curstaffstruct->leftmost_clefcontext = &curstaffstruct->clef;
171 if ((obj = find_measure_context (leftmeasure, KEYSIG)))
172 curstaffstruct->leftmost_keysig = (keysig *) obj->object;
173 else
174 curstaffstruct->leftmost_keysig = &curstaffstruct->keysig;
175
176 // initkeyaccs (curstaffstruct->leftmost_keysig->accs,
177 // curstaffstruct->leftmost_keysig->number);
178
179 si->maxkeywidth = MAX (si->maxkeywidth, draw_key (NULL, 0, 0, curstaffstruct->leftmost_keysig->number, 0, 0, FALSE, curstaffstruct->leftmost_keysig));
180 if ((obj = find_measure_context (leftmeasure, TIMESIG)))
181 {
182 curstaffstruct->leftmost_timesig = (timesig *) obj->object;
183 }
184 else
185 {
186 curstaffstruct->leftmost_timesig = &curstaffstruct->timesig;
187 }
188 if ((obj = find_measure_context (leftmeasure, STEMDIRECTIVE)))
189 curstaffstruct->leftmost_stem_directive = ((stemdirective *) obj->object)->type;
190 else
191 curstaffstruct->leftmost_stem_directive = DENEMO_STEMBOTH;
192 }
193
194 /**
195 * Finds the first occurrences of the clef, keysig and timesig of the
196 * across the entir score
197 * @param si the scoreinfo structure
198 * @return none
199 */
200 void
find_leftmost_allcontexts(DenemoMovement * si)201 find_leftmost_allcontexts (DenemoMovement * si)
202 {
203 staffnode *curstaff = si->thescore;
204
205 si->maxkeywidth = G_MININT;
206 for (; curstaff; curstaff = curstaff->next)
207 {
208 find_leftmost_staffcontext ((DenemoStaff *) curstaff->data, si);
209
210 }
211 }
212