Skip to content

Commit

Permalink
#1354 Fix control unit scroll position when matrix dimensions change
Browse files Browse the repository at this point in the history
  • Loading branch information
helgoboss committed Dec 12, 2024
1 parent 6723678 commit efb5558
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 5 deletions.
7 changes: 7 additions & 0 deletions main/src/domain/main_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ use crate::domain::ui_util::{
use base::hash_util::{NonCryptoHashMap, NonCryptoHashSet, NonCryptoIndexSet};
use base::{hash_util, NamedChannelSender, SenderToNormalThread, SenderToRealTimeThread};
use helgoboss_midi::{ControlChange14BitMessage, ParameterNumberMessage, RawShortMessage};
use playtime_api::runtime::ControlUnitId;
use reaper_high::{ChangeEvent, Reaper};
use reaper_medium::ReaperNormalizedFxParamValue;
use rosc::{OscMessage, OscPacket, OscType};
Expand Down Expand Up @@ -4137,6 +4138,12 @@ impl From<UnitId> for u32 {
}
}

impl From<ControlUnitId> for UnitId {
fn from(value: ControlUnitId) -> Self {
UnitId(value.get())
}
}

#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Display)]
pub enum MatchOutcome {
/// Message didn't match at all, was not even consumed.
Expand Down
32 changes: 32 additions & 0 deletions main/src/domain/unit.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::cell::RefCell;
use std::cmp;
use std::cmp::min;
use std::rc::{Rc, Weak};
use std::sync::Arc;

Expand All @@ -14,6 +16,7 @@ use crate::domain::{
};
use base::hash_util::{NonCryptoHashMap, NonCryptoHashSet};
use base::{serde_json_util, NamedChannelSender, SenderToNormalThread};
use playtime_api::persistence::SlotAddress;

pub type SharedUnit = Rc<RefCell<Unit>>;
pub type WeakUnit = Weak<RefCell<Unit>>;
Expand Down Expand Up @@ -260,6 +263,26 @@ impl Unit {
self.control_unit_top_left_corner
}

pub fn invalidate_control_unit_scroll_pos(&mut self, column_count: usize, row_count: usize) {
let actual_column = self.control_unit_top_left_corner.column_index;
let fixed_column = fix_scroll_pos(
actual_column,
self.control_unit_column_count() as usize,
column_count,
);
let actual_row = self.control_unit_top_left_corner.row_index;
let fixed_row = fix_scroll_pos(
actual_row,
self.control_unit_row_count() as usize,
row_count,
);
if actual_column == fixed_column && actual_row == fixed_row {
return;
}
// Control unit scroll position is invalid
self.set_control_unit_top_left_corner(SlotAddress::new(fixed_column, fixed_row));
}

pub fn set_control_unit_top_left_corner(
&mut self,
value: playtime_api::persistence::SlotAddress,
Expand Down Expand Up @@ -620,3 +643,12 @@ impl UnitEvent {
matches!(self, UnitEvent::MappingWhichLearnsTargetChanged { .. })
}
}

fn fix_scroll_pos(start_pos: usize, span: usize, count: usize) -> usize {
if count == 0 || span == 0 {
return 0;
}
let exclusive_end_pos = start_pos + span;
let fixed_exclusive_end_pos = min(count, exclusive_end_pos);
fixed_exclusive_end_pos.saturating_sub(span)
}
37 changes: 33 additions & 4 deletions main/src/infrastructure/plugin/clip_matrix_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ use crate::domain::{
RealTimeInstanceTask, ReaperTarget,
};
use crate::infrastructure::plugin::WeakInstanceShell;
use base::{Global, NamedChannelSender};
use anyhow::Context;
use base::{spawn_in_main_thread, Global, NamedChannelSender};
use helgobox_api::persistence::{
PlaytimeColumnAction, PlaytimeMatrixAction, PlaytimeRowAction, PlaytimeSlotTransportAction,
};
use playtime_api::persistence::SlotAddress;
use playtime_api::runtime::{
ControlUnit, ControlUnitId, SimpleMappingContainer, SimpleMappingTarget,
};
use playtime_clip_engine::base::ClipMatrixEvent;
use reaper_high::Reaper;

#[derive(Debug)]
Expand Down Expand Up @@ -46,7 +49,28 @@ impl MatrixHandler {
}
}

fn do_async_with_session(&self, f: impl FnOnce(SharedUnitModel) + 'static) {
fn invalidate_control_units(&self) {
let weak_instance_shell = self.weak_instance_shell.clone();
spawn_in_main_thread(async move {
let instance_shell = weak_instance_shell
.upgrade()
.context("instance shell gone")?;
let instance = instance_shell.instance().borrow();
let matrix = instance.clip_matrix().context("no matrix")?;
let column_count = matrix.column_count();
let row_count = matrix.row_count();
for unit_model in instance_shell.additional_unit_models() {
unit_model
.borrow()
.unit()
.borrow_mut()
.invalidate_control_unit_scroll_pos(column_count, row_count);
}
Ok(())
});
}

fn do_async_with_main_unit_model(&self, f: impl FnOnce(SharedUnitModel) + 'static) {
let session = self.main_unit_model.clone();
Global::task_support()
.do_later_in_main_thread_from_main_thread_asap(move || {
Expand Down Expand Up @@ -79,6 +103,11 @@ impl playtime_clip_engine::base::ClipMatrixHandler for MatrixHandler {
}

fn emit_event(&self, event: playtime_clip_engine::base::ClipMatrixEvent) {
// Check if we should do something special with that event
if matches!(event, ClipMatrixEvent::EverythingChanged) {
self.invalidate_control_units();
}
// Send event to receiver
let event = QualifiedClipMatrixEvent {
instance_id: self.instance_id,
event,
Expand Down Expand Up @@ -134,7 +163,7 @@ impl playtime_clip_engine::base::ClipMatrixHandler for MatrixHandler {
}

fn toggle_learn_source_by_target(&self, target: SimpleMappingTarget) {
self.do_async_with_session(move |shared_session| {
self.do_async_with_main_unit_model(move |shared_session| {
let mut session = shared_session.borrow_mut();
let mapping_desc = SimpleMappingDesc::from_simple_target(target);
session.toggle_learn_source_for_target(
Expand All @@ -147,7 +176,7 @@ impl playtime_clip_engine::base::ClipMatrixHandler for MatrixHandler {
}

fn remove_mapping_by_target(&self, target: SimpleMappingTarget) {
self.do_async_with_session(move |shared_session| {
self.do_async_with_main_unit_model(move |shared_session| {
let mut session = shared_session.borrow_mut();
let mapping_desc = SimpleMappingDesc::from_simple_target(target);
session.remove_mapping_by_target(CompartmentKind::Main, &mapping_desc.reaper_target);
Expand Down
2 changes: 1 addition & 1 deletion playtime-clip-engine

0 comments on commit efb5558

Please sign in to comment.