basics of autoscroll for pianoroll (mostly shared with Editor)

More work to do moving/testing pianoroll autoscroll variant back into EditingContext
and sharing it with Editor.
This commit is contained in:
Paul Davis 2024-02-23 11:25:07 -07:00
parent 3fccf2b458
commit 48a6e8dfcf
10 changed files with 526 additions and 171 deletions

View file

@ -124,6 +124,10 @@ EditingContext::EditingContext (std::string const & name)
, vertical_adjustment (0.0, 0.0, 10.0, 400.0)
, horizontal_adjustment (0.0, 0.0, 1e16)
, mouse_mode (MouseObject)
, visual_change_queued (false)
, autoscroll_horizontal_allowed (false)
, autoscroll_vertical_allowed (false)
, autoscroll_cnt (0)
{
if (!button_bindings) {
button_bindings = new Bindings ("editor-mouse");
@ -2362,3 +2366,89 @@ EditingContext::register_grid_actions ()
ActionManager::register_radio_action (snap_actions, grid_choice_group, X_("grid-type-none"), grid_type_strings[(int)GridTypeNone].c_str(), (sigc::bind (sigc::mem_fun(*this, &EditingContext::grid_type_chosen), Editing::GridTypeNone)));
}
void
EditingContext::ensure_visual_change_idle_handler ()
{
if (pending_visual_change.idle_handler_id < 0) {
/* see comment in add_to_idle_resize above. */
pending_visual_change.idle_handler_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE + 10, _idle_visual_changer, this, NULL);
pending_visual_change.being_handled = false;
}
}
int
EditingContext::_idle_visual_changer (void* arg)
{
return static_cast<EditingContext*>(arg)->idle_visual_changer ();
}
int
EditingContext::idle_visual_changer ()
{
pending_visual_change.idle_handler_id = -1;
if (pending_visual_change.pending == 0) {
return 0;
}
/* set_horizontal_position() below (and maybe other calls) call
gtk_main_iteration(), so it's possible that a signal will be handled
half-way through this method. If this signal wants an
idle_visual_changer we must schedule another one after this one, so
mark the idle_handler_id as -1 here to allow that. Also make a note
that we are doing the visual change, so that changes in response to
super-rapid-screen-update can be dropped if we are still processing
the last one.
*/
if (visual_change_queued) {
return 0;
}
pending_visual_change.being_handled = true;
VisualChange vc = pending_visual_change;
pending_visual_change.pending = (VisualChange::Type) 0;
visual_changer (vc);
pending_visual_change.being_handled = false;
visual_change_queued = true;
return 0; /* this is always a one-shot call */
}
/** Queue up a change to the viewport x origin.
* @param sample New x origin.
*/
void
EditingContext::reset_x_origin (samplepos_t sample)
{
pending_visual_change.add (VisualChange::TimeOrigin);
pending_visual_change.time_origin = sample;
ensure_visual_change_idle_handler ();
}
void
EditingContext::reset_y_origin (double y)
{
pending_visual_change.add (VisualChange::YOrigin);
pending_visual_change.y_origin = y;
ensure_visual_change_idle_handler ();
}
void
EditingContext::reset_zoom (samplecnt_t spp)
{
if (spp == samples_per_pixel) {
return;
}
pending_visual_change.add (VisualChange::ZoomLevel);
pending_visual_change.samples_per_pixel = spp;
ensure_visual_change_idle_handler ();
}