1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
|
/* moveviewport.c
functions that change leftmeasurenum, rightmeasurenum, top_measure,
bottom_measure
for Denemo, a gtk+ frontend to GNU Lilypond
(c) 2000, 2001 Matthew Hiller
*/
#include "commandfuncs.h"
#include "contexts.h"
#include "moveviewport.h"
#include "staffops.h"
#include "utils.h"
/* update_hscrollbar should be called as a cleanup whenever
si->leftmeasurenum or si->rightmeasurenum may have been altered,
e.g., by preceding calls to set_rightmeasurenum; or when the
number of measures may have changed. */
void
update_hscrollbar (struct scoreinfo *si)
{
GtkAdjustment *adj = GTK_ADJUSTMENT (si->hadjustment);
adj->upper = g_list_length (si->measurewidths) + 1.0;
adj->page_size = adj->page_increment
= si->rightmeasurenum - si->leftmeasurenum + 1.0;
adj->value = si->leftmeasurenum;
gtk_range_slider_update (GTK_RANGE (si->hscrollbar));
}
/* update_vscrollbar should be called as a cleanup whenever
si->top_staff or si->bottom_staff may have been altered,
e.g., by preceding calls to set_bottom_staff; or when the number of
staffs may have changed.
For simplicity, this function treats nonprimary voices as
full-fledged staffs, which'll be visually confusing. I'll fix it
soon. */
void
update_vscrollbar (struct scoreinfo *si)
{
GtkAdjustment *adj = GTK_ADJUSTMENT (si->vadjustment);
adj->upper = g_list_length (si->thescore) + 1.0;
adj->page_size = adj->page_increment
= si->bottom_staff - si->top_staff + 1.0;
adj->value = si->top_staff;
gtk_range_slider_update (GTK_RANGE (si->vscrollbar));
}
void
set_rightmeasurenum (struct scoreinfo *si)
{
gint spaceleft = si->widthtoworkwith;
GList *mwidthiterator =
g_list_nth (si->measurewidths, si->leftmeasurenum - 1);
for (si->rightmeasurenum = si->leftmeasurenum;
mwidthiterator && spaceleft >= GPOINTER_TO_INT (mwidthiterator->data);
spaceleft -=
(GPOINTER_TO_INT (mwidthiterator->data) + SPACE_FOR_BARLINE),
mwidthiterator = mwidthiterator->next, si->rightmeasurenum++)
;
si->rightmeasurenum = MAX (si->rightmeasurenum - 1, si->leftmeasurenum);
}
/* Utility function for advancing a staff number and staff iterator to
the next primary voice, or to one off the end and NULL if there are
none remaining. */
static void
to_next_primary_voice (gint * staff_number, staffnode ** staff_iterator)
{
do
{
(*staff_number)++;
*staff_iterator = (*staff_iterator)->next;
}
while (*staff_iterator
&& ((staff *) (*staff_iterator)->data)->voicenumber == 2);
}
/* This function also has a side effect of bumping si->top_staff
up to the staff number of the next primary voice if si->top_staff
initially points to a nonprimary voice. */
void
set_bottom_staff (struct scoreinfo *si)
{
gint space_left;
staffnode *staff_iterator;
gint staff_number;
/* Bump up si->top_staff, if necessary. */
staff_iterator = g_list_nth (si->thescore, si->top_staff - 1);
if (((staff *) staff_iterator->data)->voicenumber == 2)
to_next_primary_voice (&si->top_staff, &staff_iterator);
/* With that settled, now determine how many additional (primary)
staves will fit into the window. */
staff_number = si->top_staff;
space_left = si->scorearea->allocation.height;
do
{
space_left -= si->staffspace;
to_next_primary_voice (&staff_number, &staff_iterator);
}
while (staff_iterator && space_left >= si->staffspace);
si->bottom_staff = staff_number - 1;
}
void
isoffleftside (struct scoreinfo *si)
{
while (si->currentmeasurenum < si->leftmeasurenum)
{
si->leftmeasurenum
-= MAX ((si->rightmeasurenum - si->leftmeasurenum + 1) / 2, 1);
if (si->leftmeasurenum < 1)
si->leftmeasurenum = 1;
set_rightmeasurenum (si);
}
find_leftmost_allcontexts (si);
update_hscrollbar (si);
}
void
isoffrightside (struct scoreinfo *si)
{
while (si->currentmeasurenum > si->rightmeasurenum)
{
si->leftmeasurenum
+= MAX ((si->rightmeasurenum - si->leftmeasurenum + 1) / 2, 1);
set_rightmeasurenum (si);
}
find_leftmost_allcontexts (si);
update_hscrollbar (si);
}
void
move_viewport_up (struct scoreinfo *si)
{
staffnode *staff_iterator;
staff_iterator = g_list_nth (si->thescore, si->top_staff - 1);
while (si->currentstaffnum < si->top_staff
|| ((staff *) staff_iterator->data)->voicenumber == 2)
{
si->top_staff--;
staff_iterator = staff_iterator->prev;
}
set_bottom_staff (si);
update_vscrollbar (si);
}
void
move_viewport_down (struct scoreinfo *si)
{
staffnode *staff_iterator;
staff_iterator = g_list_nth (si->thescore, si->top_staff - 1);
while (si->currentstaffnum > si->bottom_staff)
{
to_next_primary_voice (&si->top_staff, &staff_iterator);
set_bottom_staff (si);
}
update_vscrollbar (si);
}
void
set_currentmeasurenum (struct scoreinfo *si, gint dest)
{
if (dest > 0 && dest <= g_list_length (si->measurewidths))
{
si->leftmeasurenum = dest;
si->currentmeasurenum = dest;
setcurrents (si);
set_rightmeasurenum (si);
find_leftmost_allcontexts (si);
update_hscrollbar (si);
gtk_widget_draw (si->scorearea, NULL);
}
}
void
vertical_scroll (GtkAdjustment * adjust, struct scoreinfo *si)
{
gint dest;
if ((dest = (gint) (adjust->value + 0.5)) != si->top_staff)
{
si->top_staff = dest;
set_bottom_staff (si);
if (si->currentstaffnum > si->bottom_staff)
{
si->currentstaffnum = si->bottom_staff;
si->currentstaff = g_list_nth (si->thescore, si->bottom_staff - 1);
setcurrentprimarystaff (si);
setcurrents (si);
}
else if (si->currentstaffnum < si->top_staff)
{
si->currentstaffnum = si->top_staff;
si->currentstaff = g_list_nth (si->thescore, si->top_staff - 1);
setcurrentprimarystaff (si);
setcurrents (si);
}
gtk_widget_draw (si->scorearea, NULL);
}
update_vscrollbar (si);
}
void
horizontal_scroll (GtkAdjustment * adjust, struct scoreinfo *si)
{
gint dest;
if ((dest = (gint) (adjust->value + 0.5)) != si->leftmeasurenum)
{
si->leftmeasurenum = dest;
set_rightmeasurenum (si);
if (si->currentmeasurenum > si->rightmeasurenum)
{
si->currentmeasurenum = si->rightmeasurenum;
setcurrents (si);
}
else if (si->currentmeasurenum < si->leftmeasurenum)
{
si->currentmeasurenum = si->leftmeasurenum;
setcurrents (si);
}
find_leftmost_allcontexts (si);
gtk_widget_draw (si->scorearea, NULL);
}
update_hscrollbar (si);
}
|