From b44e02e2d855e4b0b090c1897ef5bdb8e1b1d582 Mon Sep 17 00:00:00 2001 From: Benjamin Klum Date: Wed, 21 Feb 2024 00:09:31 +0100 Subject: [PATCH] Use reaper-common-types instead of defining our own --- Cargo.lock | 76 +++++++++++- Cargo.toml | 2 + main/Cargo.toml | 1 + main/lib/helgoboss-learn | 2 +- main/src/domain/midi_clock_calculator.rs | 4 +- main/src/domain/real_time_processor.rs | 2 +- .../targets/playtime_slot_volume_target.rs | 10 +- main/src/domain/targets/seek_target.rs | 14 +-- main/src/domain/targets/track_peak_target.rs | 2 +- .../infrastructure/plugin/helgobox_plugin.rs | 2 +- main/src/infrastructure/plugin/unit_shell.rs | 4 +- .../proto/playtime_request_handler.rs | 16 +-- main/src/infrastructure/ui/util.rs | 14 +-- playtime-api/Cargo.toml | 4 +- playtime-api/src/persistence/mod.rs | 108 ++---------------- playtime-clip-engine | 2 +- pot-browser/src/pot_browser_panel.rs | 4 +- swell-ui/Cargo.toml | 4 +- swell-ui/src/brush.rs | 6 +- swell-ui/src/color.rs | 95 +-------------- swell-ui/src/device_context.rs | 5 +- swell-ui/src/lib.rs | 2 - swell-ui/src/view_manager.rs | 5 +- 23 files changed, 137 insertions(+), 247 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9892f5fd0..511bd1420 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1199,6 +1199,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "copypasta" version = "0.8.1" @@ -1605,7 +1614,7 @@ version = "0.99.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" dependencies = [ - "convert_case", + "convert_case 0.4.0", "proc-macro2", "quote", "rustc_version 0.3.3", @@ -2767,6 +2776,7 @@ dependencies = [ "num_enum 0.7.2", "once_cell", "partial-min-max", + "reaper-common-types", "reaper-low", "regex", "rosc", @@ -3267,6 +3277,27 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "kinded" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce4bdbb2f423660b19f0e9f7115182214732d8dd5f840cd0a3aee3e22562f34c" +dependencies = [ + "kinded_macros", +] + +[[package]] +name = "kinded_macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13b4ddc5dcb32f45dac3d6f606da2a52fdb9964a18427e63cd5ef6c0d13288d" +dependencies = [ + "convert_case 0.6.0", + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "kurbo" version = "0.9.5" @@ -4038,6 +4069,27 @@ dependencies = [ "libc", ] +[[package]] +name = "nutype" +version = "0.4.1-beta.1" +source = "git+https://github.com/helgoboss/nutype.git?branch=feature/new_unchecked_const#e186e09268b5f411d502b0afaa6678532aabf970" +dependencies = [ + "nutype_macros", +] + +[[package]] +name = "nutype_macros" +version = "0.4.1-beta.1" +source = "git+https://github.com/helgoboss/nutype.git?branch=feature/new_unchecked_const#e186e09268b5f411d502b0afaa6678532aabf970" +dependencies = [ + "cfg-if", + "kinded", + "proc-macro2", + "quote", + "syn 2.0.48", + "urlencoding", +] + [[package]] name = "objc" version = "0.2.7" @@ -4413,6 +4465,7 @@ dependencies = [ "derive_more", "nanoid", "realearn-macros", + "reaper-common-types", "reaper-low", "rmp-serde", "serde", @@ -4917,6 +4970,7 @@ dependencies = [ "realearn-api", "realearn-csi", "realearn-dialogs", + "reaper-common-types", "reaper-high", "reaper-low", "reaper-macros", @@ -5015,6 +5069,16 @@ dependencies = [ name = "realearn-macros" version = "0.1.0" +[[package]] +name = "reaper-common-types" +version = "0.1.0" +dependencies = [ + "hex-literal", + "nutype", + "palette", + "serde", +] + [[package]] name = "reaper-fluent" version = "0.1.0" @@ -5085,6 +5149,7 @@ dependencies = [ "enumflags2", "helgoboss-midi", "libc", + "reaper-common-types", "reaper-low", "reaper-macros", "ref-cast", @@ -6183,11 +6248,10 @@ dependencies = [ "base", "bindgen", "fragile", - "hex-literal", "libloading 0.8.0", "objc2", - "palette", "raw-window-handle 0.4.3", + "reaper-common-types", "reaper-low", "reaper-medium", "rx-util", @@ -6981,6 +7045,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "usvg" version = "0.37.0" diff --git a/Cargo.toml b/Cargo.toml index 848eaf775..c99d9eda8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ members = [ base = { path = "base" } pot = { path = "pot" } pot-browser = { path = "pot-browser" } +reaper-common-types = { git = "https://github.com/helgoboss/reaper-rs.git", branch = "master" } reaper-rx = { git = "https://github.com/helgoboss/reaper-rs.git", branch = "master" } reaper-fluent = { git = "https://github.com/helgoboss/reaper-rs.git", branch = "master" } reaper-high = { git = "https://github.com/helgoboss/reaper-rs.git", branch = "master", features = ["serde"] } @@ -155,6 +156,7 @@ vst = { git = "https://github.com/helgoboss/vst-rs.git", branch = "feature/param # This is for temporary development with local reaper-rs. [patch.'https://github.com/helgoboss/reaper-rs.git'] +reaper-common-types = { path = "../reaper-rs/main/common-types" } reaper-fluent = { path = "../reaper-rs/main/fluent" } reaper-high = { path = "../reaper-rs/main/high" } reaper-medium = { path = "../reaper-rs/main/medium" } diff --git a/main/Cargo.toml b/main/Cargo.toml index 665a544b0..cbcddc73e 100644 --- a/main/Cargo.toml +++ b/main/Cargo.toml @@ -30,6 +30,7 @@ base.workspace = true reaper-rx.workspace = true reaper-high.workspace = true reaper-medium.workspace = true +reaper-common-types = { workspace = true, features = ["color-macros", "palette"] } reaper-low.workspace = true reaper-macros.workspace = true swell-ui.workspace = true diff --git a/main/lib/helgoboss-learn b/main/lib/helgoboss-learn index 0c3a1cd04..931610161 160000 --- a/main/lib/helgoboss-learn +++ b/main/lib/helgoboss-learn @@ -1 +1 @@ -Subproject commit 0c3a1cd04da93387e0dc52612b0e562ab42bd961 +Subproject commit 93161016161e4ee27379d025eee170fe41ce3358 diff --git a/main/src/domain/midi_clock_calculator.rs b/main/src/domain/midi_clock_calculator.rs index c200d4df9..7cf902a8a 100644 --- a/main/src/domain/midi_clock_calculator.rs +++ b/main/src/domain/midi_clock_calculator.rs @@ -1,7 +1,7 @@ use crate::base::MovingAverageCalculator; -use helgoboss_learn::Bpm; use crate::domain::SampleOffset; +use reaper_common_types::Bpm; use reaper_medium::Hz; use std::convert::TryInto; @@ -16,7 +16,7 @@ pub struct MidiClockCalculator { impl Default for MidiClockCalculator { fn default() -> Self { Self { - sample_rate: Hz::new(1.0), + sample_rate: Hz::new_panic(1.0), sample_counter: 0, previous_midi_clock_timestamp_in_samples: 0, bpm_calculator: Default::default(), diff --git a/main/src/domain/real_time_processor.rs b/main/src/domain/real_time_processor.rs index feb29d53e..fe0d61a03 100644 --- a/main/src/domain/real_time_processor.rs +++ b/main/src/domain/real_time_processor.rs @@ -96,7 +96,7 @@ impl RealTimeProcessor { midi_clock_calculator: Default::default(), control_is_globally_enabled: false, feedback_is_globally_enabled: false, - sample_rate: Hz::new(1.0), + sample_rate: Hz::new_panic(1.0), } } diff --git a/main/src/domain/targets/playtime_slot_volume_target.rs b/main/src/domain/targets/playtime_slot_volume_target.rs index 98266229d..ef7b5086e 100644 --- a/main/src/domain/targets/playtime_slot_volume_target.rs +++ b/main/src/domain/targets/playtime_slot_volume_target.rs @@ -72,7 +72,6 @@ mod playtime_impl { rt::{ClipChangeEvent, QualifiedClipChangeEvent}, }; use reaper_high::SliderVolume; - use reaper_medium::Db; use std::borrow::Cow; impl RealearnTarget for PlaytimeSlotVolumeTarget { @@ -109,12 +108,11 @@ mod playtime_impl { SliderVolume::try_from_normalized_slider_value(value.to_unit_value()?.get()) .unwrap_or_default(); let db = volume.db(); - let api_db = playtime_api::persistence::Db::new(db.get())?; Backbone::get() .with_clip_matrix_mut( context.control_context.instance(), |matrix| -> anyhow::Result { - matrix.set_slot_volume(self.slot_coordinates, api_db)?; + matrix.set_slot_volume(self.slot_coordinates, db)?; Ok(HitResponse::processed_with_effect()) }, ) @@ -141,9 +139,7 @@ mod playtime_impl { }, )) if clip_address.slot_address == self.slot_coordinates => ( true, - Some(AbsoluteValue::Continuous(db_unit_value(Db::new( - new_value.get(), - )))), + Some(AbsoluteValue::Continuous(db_unit_value(*new_value))), ), _ => (false, None), } @@ -167,7 +163,7 @@ mod playtime_impl { Backbone::get() .with_clip_matrix(context.instance(), |matrix| { let db = matrix.find_slot(self.slot_coordinates)?.volume().ok()?; - Some(SliderVolume::from_db(Db::new(db.get()))) + Some(SliderVolume::from_db(db)) }) .ok()? } diff --git a/main/src/domain/targets/seek_target.rs b/main/src/domain/targets/seek_target.rs index 34f39f135..bf8ad63ae 100644 --- a/main/src/domain/targets/seek_target.rs +++ b/main/src/domain/targets/seek_target.rs @@ -60,10 +60,10 @@ impl RealearnTarget for SeekTarget { let value = value.to_unit_value()?; let info = get_seek_info(self.project, self.options, false); let desired_pos_within_range = value.get() * info.length(); - let desired_pos = info.start_pos.get() + desired_pos_within_range; + let desired_pos = info.start_pos + desired_pos_within_range; with_seek_behavior(self.behavior, || { self.project.set_edit_cursor_position( - PositionInSeconds::new(desired_pos), + desired_pos, SetEditCurPosOptions { move_view: self.options.move_view, seek_play: self.options.seek_play, @@ -330,17 +330,13 @@ fn get_seek_info(project: Project, options: SeekOptions, ignore_project_length: if ignore_project_length { return SeekInfo::new( SeekContext::Project, - PositionInSeconds::new(0.0), - PositionInSeconds::new(f64::MAX), + PositionInSeconds::ZERO, + PositionInSeconds::new_panic(f64::MAX), ); } else { let length = project.length(); if length.get() > 0.0 { - return SeekInfo::new( - SeekContext::Project, - PositionInSeconds::new(0.0), - PositionInSeconds::new(length.get()), - ); + return SeekInfo::new(SeekContext::Project, PositionInSeconds::ZERO, length.into()); } } } diff --git a/main/src/domain/targets/track_peak_target.rs b/main/src/domain/targets/track_peak_target.rs index b4192125b..c1a37a25e 100644 --- a/main/src/domain/targets/track_peak_target.rs +++ b/main/src/domain/targets/track_peak_target.rs @@ -71,7 +71,7 @@ impl TrackPeakTarget { } let sum: f64 = peaks.map(|v| v.get()).sum(); let avg = sum / channel_count as f64; - let vol = ReaperVolumeValue::new(avg); + let vol = ReaperVolumeValue::new_panic(avg); Some(SliderVolume::from_reaper_value(vol)) } } diff --git a/main/src/infrastructure/plugin/helgobox_plugin.rs b/main/src/infrastructure/plugin/helgobox_plugin.rs index dfe87287e..57024002e 100644 --- a/main/src/infrastructure/plugin/helgobox_plugin.rs +++ b/main/src/infrastructure/plugin/helgobox_plugin.rs @@ -267,7 +267,7 @@ impl Plugin for HelgoboxPlugin { fn set_sample_rate(&mut self, rate: f32) { firewall(|| { tracing::debug!("VST set sample rate"); - self.sample_rate = Hz::new(rate as _); + self.sample_rate = Hz::new_panic(rate as _); if let Some(lazy_data) = self.lazy_data.get() { lazy_data.instance_shell.set_sample_rate(rate); } diff --git a/main/src/infrastructure/plugin/unit_shell.rs b/main/src/infrastructure/plugin/unit_shell.rs index 38143123d..308edcaff 100644 --- a/main/src/infrastructure/plugin/unit_shell.rs +++ b/main/src/infrastructure/plugin/unit_shell.rs @@ -247,7 +247,9 @@ impl UnitShell { // If task queue is full or audio not running, so what. Don't spam the user with error // messages. self.normal_real_time_task_sender - .send_if_space(NormalRealTimeTask::UpdateSampleRate(Hz::new(rate as _))); + .send_if_space(NormalRealTimeTask::UpdateSampleRate(Hz::new_panic( + rate as _, + ))); } } diff --git a/main/src/infrastructure/proto/playtime_request_handler.rs b/main/src/infrastructure/proto/playtime_request_handler.rs index 8cb237853..72b274581 100644 --- a/main/src/infrastructure/proto/playtime_request_handler.rs +++ b/main/src/infrastructure/proto/playtime_request_handler.rs @@ -427,7 +427,7 @@ impl PlaytimeProtoRequestHandler { } pub fn set_matrix_tempo(&self, req: SetMatrixTempoRequest) -> Result, Status> { - let bpm = Bpm::try_from(req.bpm).map_err(|e| Status::invalid_argument(e.as_ref()))?; + let bpm = Bpm::try_from(req.bpm).map_err(|e| Status::invalid_argument(e.to_string()))?; self.handle_matrix_command(&req.matrix_id, |matrix| { matrix.set_tempo(bpm); Ok(()) @@ -453,11 +453,11 @@ impl PlaytimeProtoRequestHandler { &self, req: SetMatrixVolumeRequest, ) -> Result, Status> { - let db = Db::try_from(req.db).map_err(|e| Status::invalid_argument(e.as_ref()))?; + let db = Db::try_from(req.db).map_err(|e| Status::invalid_argument(e.to_string()))?; self.handle_matrix_command(&req.matrix_id, |matrix| { let project = matrix.permanent_project().or_current_project(); project.master_track()?.set_volume( - db.to_reaper_volume_value(), + db.to_linear_volume_value(), GangBehavior::DenyGang, GroupingBehavior::PreventGrouping, ); @@ -466,8 +466,8 @@ impl PlaytimeProtoRequestHandler { } pub fn set_matrix_pan(&self, req: SetMatrixPanRequest) -> Result, Status> { - let pan = - ReaperPanValue::try_from(req.pan).map_err(|e| Status::invalid_argument(e.as_ref()))?; + let pan = ReaperPanValue::try_from(req.pan) + .map_err(|e| Status::invalid_argument(e.to_string()))?; self.handle_matrix_command(&req.matrix_id, |matrix| { let project = matrix.permanent_project().or_current_project(); project.master_track()?.set_pan( @@ -480,10 +480,10 @@ impl PlaytimeProtoRequestHandler { } pub fn set_track_volume(&self, req: SetTrackVolumeRequest) -> Result, Status> { - let db = Db::try_from(req.db).map_err(|e| Status::invalid_argument(e.as_ref()))?; + let db = Db::try_from(req.db).map_err(|e| Status::invalid_argument(e.to_string()))?; self.handle_track_command(&req.track_address, |_matrix, track| { track.set_volume( - db.to_reaper_volume_value(), + db.to_linear_volume_value(), GangBehavior::DenyGang, GroupingBehavior::PreventGrouping, ); @@ -492,7 +492,7 @@ impl PlaytimeProtoRequestHandler { } pub fn set_track_pan(&self, req: SetTrackPanRequest) -> Result, Status> { - let pan = ReaperPanValue::new(req.pan.clamp(-1.0, 1.0)); + let pan = ReaperPanValue::new_panic(req.pan.clamp(-1.0, 1.0)); self.handle_track_command(&req.track_address, |_matrix, track| { track.set_pan( Pan::from_reaper_value(pan), diff --git a/main/src/infrastructure/ui/util.rs b/main/src/infrastructure/ui/util.rs index 2ce0baeb5..cc72e2a13 100644 --- a/main/src/infrastructure/ui/util.rs +++ b/main/src/infrastructure/ui/util.rs @@ -192,16 +192,16 @@ pub mod fonts { pub mod colors { use palette::{Hsl, Lighten}; - use swell_ui::{color, Color}; + use reaper_common_types::{color, RgbColor}; #[derive(Copy, Clone, Debug)] pub struct ColorPair { - pub light: Color, - pub dark: Color, + pub light: RgbColor, + pub dark: RgbColor, } impl ColorPair { - pub fn generate_from_light(light: Color) -> Self { + pub fn generate_from_light(light: RgbColor) -> Self { Self { light, dark: invert_lightness(light), @@ -209,7 +209,7 @@ pub mod colors { } } - fn invert_lightness(color: Color) -> Color { + fn invert_lightness(color: RgbColor) -> RgbColor { let hsl = color.to_hsl(); Hsl::new_const(hsl.hue, hsl.saturation, 1.0 - hsl.lightness).into() } @@ -219,7 +219,7 @@ pub mod colors { lighten_for_light_theme: f32, /// For dark theme, lightens all colors by this factor *after* inverting their lightness. lighten_for_dark_theme: f32, - colors: [Color; 5], + colors: [RgbColor; 5], } impl ColorPalette { @@ -313,7 +313,7 @@ pub mod colors { // }; pub mod tailwind { - use swell_ui::colors; + use reaper_common_types::colors; colors! { SLATE_50 = "f8fafc"; diff --git a/playtime-api/Cargo.toml b/playtime-api/Cargo.toml index dcfb97066..b4c0beddd 100644 --- a/playtime-api/Cargo.toml +++ b/playtime-api/Cargo.toml @@ -7,7 +7,9 @@ publish = false [dependencies] serde.workspace = true -# For exposing an API within REAPER +# For reusing common sound-related types that conveniently happen to be compatible with REAPER +reaper-common-types.workspace = true +# For exposing a runtime API within REAPER reaper-low.workspace = true # For being able to use the API macro realearn-macros.workspace = true diff --git a/playtime-api/src/persistence/mod.rs b/playtime-api/src/persistence/mod.rs index 34245b97b..9f89de490 100644 --- a/playtime-api/src/persistence/mod.rs +++ b/playtime-api/src/persistence/mod.rs @@ -26,10 +26,10 @@ mod serialization; use base64::engine::general_purpose::URL_SAFE_NO_PAD as BASE64_ENGINE; use base64::Engine; use chrono::NaiveDateTime; +use reaper_common_types::{Bpm, Db, DurationInBeats, DurationInSeconds}; use serde::{Deserialize, Serialize}; use std::cmp; use std::fmt::{Display, Formatter}; -use std::ops::Add; use std::path::PathBuf; // TODO-medium Add start time detection @@ -248,8 +248,8 @@ impl TempoRange { impl Default for TempoRange { fn default() -> Self { Self { - min: Bpm(60.0), - max: Bpm(200.0), + min: Bpm::new_panic(60.0), + max: Bpm::new_panic(200.0), } } } @@ -336,7 +336,7 @@ impl MatrixClipRecordSettings { &self, initial_play_start_timing: ClipPlayStartTiming, time_signature: TimeSignature, - downbeat: PositiveBeat, + downbeat: DurationInBeats, ) -> ClipTimeBase { use ClipRecordTimeBase::*; let beat_based = match self.time_base { @@ -1297,7 +1297,7 @@ pub struct Section { /// Position in the source from which to start. /// /// If this is greater than zero, a fade-in will be used to avoid clicks. - pub start_pos: PositiveSecond, + pub start_pos: DurationInSeconds, /// Length of the material to be played, starting from `start_pos`. /// /// - `None` means until original source end. @@ -1305,7 +1305,7 @@ pub struct Section { /// - If this makes the section end be located before the original source end, a fade-out will /// be used to avoid clicks. #[serde(skip_serializing_if = "Option::is_none")] - pub length: Option, + pub length: Option, } impl Section { @@ -1413,7 +1413,7 @@ pub struct BeatTimeBase { /// If provided, this information is used for certain aspects of the user interface. pub time_signature: TimeSignature, /// Defines which position (in beats) is the downbeat. - pub downbeat: PositiveBeat, + pub downbeat: DurationInBeats, } #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] @@ -1477,100 +1477,6 @@ impl TrackId { } } -#[derive(Copy, Clone, PartialEq, PartialOrd, Debug, Serialize, Deserialize)] -pub struct Bpm(f64); - -impl Bpm { - /// # Safety - /// - /// If you pass a value < 1.0 or > 960.0, you get an invalid Bpm value. - pub const unsafe fn new_unchecked(value: f64) -> Self { - Self(value) - } - - pub fn new(value: f64) -> PlaytimeApiResult { - if value < 1.0 || value > 960.0 { - return Err("BPM value must be >= 1.0 and <= 960.0".into()); - } - Ok(Self(value)) - } - - pub const fn get(&self) -> f64 { - self.0 - } -} - -#[derive(Copy, Clone, PartialEq, Debug, Default, Serialize, Deserialize)] -#[serde(try_from = "f64")] -pub struct PositiveSecond(f64); - -impl PositiveSecond { - pub fn new(value: f64) -> PlaytimeApiResult { - if value < 0.0 { - return Err("second value must be positive".into()); - } - Ok(Self(value)) - } - - pub const fn get(&self) -> f64 { - self.0 - } - - pub fn saturating_sub(&self, rhs: Self) -> Self { - Self(0.0f64.max(self.0 - rhs.0)) - } -} - -impl TryFrom for PositiveSecond { - type Error = PlaytimeApiError; - - fn try_from(value: f64) -> Result { - Self::new(value) - } -} - -impl Add for PositiveSecond { - type Output = Self; - - fn add(self, rhs: Self) -> Self::Output { - Self(self.0 + rhs.0) - } -} - -#[derive(Copy, Clone, PartialEq, Debug, Default, Serialize, Deserialize)] -pub struct PositiveBeat(f64); - -impl PositiveBeat { - pub fn new(value: f64) -> PlaytimeApiResult { - if value < 0.0 { - return Err("beat value must be positive".into()); - } - Ok(Self(value)) - } - - pub const fn get(&self) -> f64 { - self.0 - } -} - -#[derive(Copy, Clone, PartialEq, Debug, Default, Serialize, Deserialize)] -pub struct Db(f64); - -impl Db { - pub const ZERO: Db = Db(0.0); - - pub fn new(value: f64) -> PlaytimeApiResult { - if value.is_nan() { - return Err("dB value must not be NaN".into()); - } - Ok(Self(value)) - } - - pub const fn get(&self) -> f64 { - self.0 - } -} - #[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] pub struct RgbColor(pub u8, pub u8, pub u8); diff --git a/playtime-clip-engine b/playtime-clip-engine index 3a4cb696b..bb2f4ac24 160000 --- a/playtime-clip-engine +++ b/playtime-clip-engine @@ -1 +1 @@ -Subproject commit 3a4cb696b43902f0b96b0f89b6f7f387ee887fe0 +Subproject commit bb2f4ac2414d7e62c1de48a2be93a84a313c3c96 diff --git a/pot-browser/src/pot_browser_panel.rs b/pot-browser/src/pot_browser_panel.rs index 135fc5da5..2667f4ee6 100644 --- a/pot-browser/src/pot_browser_panel.rs +++ b/pot-browser/src/pot_browser_panel.rs @@ -1965,12 +1965,12 @@ fn add_right_options_dropdown(input: RightOptionsDropdownInput, ui: &mut Ui) { .speed(0.01) .custom_formatter(|v, _| { // TODO-low It's useless to first convert into a slider volume - SliderVolume::from_reaper_value(ReaperVolumeValue::new(v)).to_string() + SliderVolume::from_reaper_value(ReaperVolumeValue::new_panic(v)).to_string() }) .clamp_range(0.0..=1.0) .ui(ui) .on_hover_text("Change volume of the sound previews"); - let new_volume = ReaperVolumeValue::new(new_volume_raw); + let new_volume = ReaperVolumeValue::new_panic(new_volume_raw); if new_volume != old_volume { input.pot_unit.set_preview_volume(new_volume); } diff --git a/swell-ui/Cargo.toml b/swell-ui/Cargo.toml index 2f9e5a113..7cc86db60 100644 --- a/swell-ui/Cargo.toml +++ b/swell-ui/Cargo.toml @@ -9,15 +9,13 @@ publish = false base.workspace = true reaper-medium.workspace = true reaper-low.workspace = true +reaper-common-types.workspace = true rxrust.workspace = true rx-util.workspace = true scopeguard.workspace = true raw-window-handle.workspace = true tracing.workspace = true -palette.workspace = true fragile.workspace = true -# For easily defining colors -hex-literal = "0.4.1" [target.'cfg(windows)'.dependencies] winapi.workspace = true diff --git a/swell-ui/src/brush.rs b/swell-ui/src/brush.rs index 76ba3bf53..d0638e178 100644 --- a/swell-ui/src/brush.rs +++ b/swell-ui/src/brush.rs @@ -1,5 +1,5 @@ -use crate::Color; use base::hash_util::NonCryptoHashMap; +use reaper_common_types::RgbColor; use reaper_low::Swell; use reaper_medium::Hbrush; use std::cell::RefCell; @@ -26,11 +26,11 @@ impl BrushCache { #[derive(Eq, PartialEq, Copy, Clone, Hash, Debug)] pub struct BrushDescriptor { - color: Color, + color: RgbColor, } impl BrushDescriptor { - pub const fn solid(color: Color) -> Self { + pub const fn solid(color: RgbColor) -> Self { Self { color } } } diff --git a/swell-ui/src/color.rs b/swell-ui/src/color.rs index 0d56698a3..ca694e37f 100644 --- a/swell-ui/src/color.rs +++ b/swell-ui/src/color.rs @@ -1,96 +1,13 @@ -use palette::rgb::Rgb; -use palette::{Hsl, IntoColor, LinSrgb, Srgb}; +use reaper_common_types::RgbColor; use reaper_low::Swell; -/// Construct a color like this: `color!("EFEFEF")` -#[macro_export] -macro_rules! color { - ($arr:literal) => { - swell_ui::Color::from_array(swell_ui::hex!($arr)) - }; -} - -#[macro_export] -macro_rules! colors { - ( - $( - $name:ident = $arr:literal; - )+ - ) => { - $( - pub const $name: swell_ui::Color = swell_ui::color!($arr); - )+ - }; -} - -/// A color for being used in Win32/SWELL. -/// -/// A non-linear sRGB color to be specific. -#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -pub struct Color { - pub r: u8, - pub g: u8, - pub b: u8, -} - -impl Color { - /// Converts an arbitrary palette RGB color to our color type. - pub fn from_palette(color: Rgb) -> Self - where - Srgb: From>, - { - // We want non-linear sRGB - let srgb: Srgb = color.into(); - Self::rgb(srgb.red, srgb.green, srgb.blue) - } - - /// Creates this color by providing the non-linear sRGB components contained in an array. - pub const fn from_array(rgb: [u8; 3]) -> Self { - Self::rgb(rgb[0], rgb[1], rgb[2]) - } - - /// Creates this color by providing the non-linear sRGB components. - pub const fn rgb(r: u8, g: u8, b: u8) -> Self { - Self { r, g, b } - } - - /// Converts this color to its closest palette color type (24-bit sRGB without alpha). - pub fn to_palette(&self) -> Srgb { - Srgb::new(self.r, self.g, self.b) - } - - /// Convenience function to start working with the color in the RGB color space. - /// - /// Can be converted back into our color type using `.into()`. - pub fn to_linear_srgb(&self) -> LinSrgb { - self.to_palette().into_linear() - } - - /// Convenience function to start working with the color in the HSL color space. - pub fn to_hsl(&self) -> Hsl { - let srgb: Srgb = self.to_palette().into_format(); - srgb.into_color() - } - +pub trait SwellRgbColorExt { /// Converts this color to a single integer as expected by Win32/SWELL. - pub const fn to_raw(&self) -> u32 { - Swell::RGB(self.r, self.g, self.b) - } -} - -impl From> for Color -where - Srgb: From>, -{ - fn from(value: Rgb) -> Self { - Color::from_palette(value) - } + fn to_raw(&self) -> u32; } -impl From for Color { - fn from(value: Hsl) -> Self { - let srgb: Srgb = value.into_color(); - let srgb: Srgb = srgb.into_format(); - Color::from_palette(srgb) +impl SwellRgbColorExt for RgbColor { + fn to_raw(&self) -> u32 { + Swell::RGB(self.r, self.g, self.b) } } diff --git a/swell-ui/src/device_context.rs b/swell-ui/src/device_context.rs index 4f5fa1a21..b786adbcb 100644 --- a/swell-ui/src/device_context.rs +++ b/swell-ui/src/device_context.rs @@ -1,4 +1,5 @@ -use crate::Color; +use crate::SwellRgbColorExt; +use reaper_common_types::RgbColor; use reaper_low::{raw, Swell}; use reaper_medium::Hdc; @@ -21,7 +22,7 @@ impl DeviceContext { } } - pub fn set_text_color(&self, color: Color) { + pub fn set_text_color(&self, color: RgbColor) { unsafe { Swell::get().SetTextColor(self.as_ptr(), color.to_raw() as _); } diff --git a/swell-ui/src/lib.rs b/swell-ui/src/lib.rs index 3cd3f2462..b85a774f5 100644 --- a/swell-ui/src/lib.rs +++ b/swell-ui/src/lib.rs @@ -1,8 +1,6 @@ mod view_manager; pub use view_manager::*; -pub use hex_literal::hex; - mod window; pub use window::*; diff --git a/swell-ui/src/view_manager.rs b/swell-ui/src/view_manager.rs index e4d6bfdf3..f69b7fcb6 100644 --- a/swell-ui/src/view_manager.rs +++ b/swell-ui/src/view_manager.rs @@ -1,6 +1,6 @@ //! This file is supposed to encapsulate most of the (ugly) win32 API glue code use crate::{ - BrushCache, BrushDescriptor, Color, DeviceContext, FontCache, FontDescriptor, Pixels, Point, + BrushCache, BrushDescriptor, DeviceContext, FontCache, FontDescriptor, Pixels, Point, SharedView, View, WeakView, Window, }; use std::cell::{Cell, RefCell}; @@ -13,6 +13,7 @@ use std::ptr::null_mut; use base::hash_util::NonCryptoHashMap; use fragile::Fragile; +use reaper_common_types::RgbColor; use reaper_medium::{Hbrush, Hdc, Hfont, Hwnd}; use std::sync::OnceLock; @@ -58,7 +59,7 @@ pub struct ViewManager { } impl ViewManager { - pub fn get_solid_brush(&'static self, color: Color) -> Option { + pub fn get_solid_brush(&'static self, color: RgbColor) -> Option { self.brush_cache.get_brush(BrushDescriptor::solid(color)) }