Fix: clean ratatui > egui interaction

This commit is contained in:
2026-03-18 02:28:57 +01:00
parent f1c83c66a0
commit 68bd62f57f
6 changed files with 133 additions and 240 deletions

View File

@@ -36,13 +36,12 @@ required-features = ["desktop"]
[features]
default = ["cli"]
cli = ["dep:cpal", "dep:midir", "dep:confy", "dep:clap", "dep:thread-priority"]
block-renderer = ["dep:soft_ratatui", "dep:rustc-hash", "dep:egui"]
block-renderer = ["dep:soft_ratatui", "dep:rustc-hash", "dep:egui", "dep:egui_ratatui"]
desktop = [
"cli",
"block-renderer",
"cagire-forth/desktop",
"dep:eframe",
"dep:egui_ratatui",
"dep:image",
]
asio = ["doux/asio", "cpal/asio"]

View File

@@ -6,128 +6,22 @@ use std::time::Instant;
use arc_swap::ArcSwap;
use crossbeam_channel::Sender;
use egui_ratatui::RataguiBackend;
use nih_plug::prelude::*;
use nih_plug_egui::egui;
use nih_plug_egui::{create_egui_editor, EguiState};
use ratatui::Terminal;
use soft_ratatui::embedded_graphics_unicodefonts::{
mono_10x20_atlas, mono_6x13_atlas, mono_6x13_bold_atlas, mono_6x13_italic_atlas,
mono_7x13_atlas, mono_7x13_bold_atlas, mono_7x13_italic_atlas, mono_8x13_atlas,
mono_8x13_bold_atlas, mono_8x13_italic_atlas, mono_9x15_atlas, mono_9x15_bold_atlas,
mono_9x18_atlas, mono_9x18_bold_atlas,
};
use soft_ratatui::{EmbeddedGraphics, SoftBackend};
use cagire::block_renderer::BlockCharBackend;
use cagire::app::App;
use cagire::engine::{AudioCommand, LinkState, SequencerSnapshot};
use cagire::input::{handle_key, handle_mouse, InputContext};
use cagire::input_egui::{convert_egui_events, convert_egui_mouse, EguiMouseState};
use cagire::model::{Dictionary, Rng, Variables};
use cagire::terminal::{create_terminal, FontChoice, TerminalType};
use cagire::theme;
use cagire::views;
use cagire::input_egui::{convert_egui_events, convert_egui_mouse, EguiMouseState};
use crate::params::CagireParams;
use crate::PluginBridge;
type TerminalType = Terminal<RataguiBackend<BlockCharBackend>>;
#[derive(Clone, Copy, PartialEq)]
enum FontChoice {
Size6x13,
Size7x13,
Size8x13,
Size9x15,
Size9x18,
Size10x20,
}
impl FontChoice {
fn from_setting(s: &str) -> Self {
match s {
"6x13" => Self::Size6x13,
"7x13" => Self::Size7x13,
"9x15" => Self::Size9x15,
"9x18" => Self::Size9x18,
"10x20" => Self::Size10x20,
_ => Self::Size8x13,
}
}
fn to_setting(self) -> &'static str {
match self {
Self::Size6x13 => "6x13",
Self::Size7x13 => "7x13",
Self::Size8x13 => "8x13",
Self::Size9x15 => "9x15",
Self::Size9x18 => "9x18",
Self::Size10x20 => "10x20",
}
}
fn label(self) -> &'static str {
match self {
Self::Size6x13 => "6x13 (Compact)",
Self::Size7x13 => "7x13",
Self::Size8x13 => "8x13 (Default)",
Self::Size9x15 => "9x15",
Self::Size9x18 => "9x18",
Self::Size10x20 => "10x20 (Large)",
}
}
const ALL: [Self; 6] = [
Self::Size6x13,
Self::Size7x13,
Self::Size8x13,
Self::Size9x15,
Self::Size9x18,
Self::Size10x20,
];
}
fn create_terminal(font: FontChoice) -> TerminalType {
let (regular, bold, italic) = match font {
FontChoice::Size6x13 => (
mono_6x13_atlas(),
Some(mono_6x13_bold_atlas()),
Some(mono_6x13_italic_atlas()),
),
FontChoice::Size7x13 => (
mono_7x13_atlas(),
Some(mono_7x13_bold_atlas()),
Some(mono_7x13_italic_atlas()),
),
FontChoice::Size8x13 => (
mono_8x13_atlas(),
Some(mono_8x13_bold_atlas()),
Some(mono_8x13_italic_atlas()),
),
FontChoice::Size9x15 => (mono_9x15_atlas(), Some(mono_9x15_bold_atlas()), None),
FontChoice::Size9x18 => (mono_9x18_atlas(), Some(mono_9x18_bold_atlas()), None),
FontChoice::Size10x20 => (mono_10x20_atlas(), None, None),
};
let eg = SoftBackend::<EmbeddedGraphics>::new(80, 24, regular, bold, italic);
let soft = SoftBackend {
buffer: eg.buffer,
cursor: eg.cursor,
cursor_pos: eg.cursor_pos,
char_width: eg.char_width,
char_height: eg.char_height,
blink_counter: eg.blink_counter,
blinking_fast: eg.blinking_fast,
blinking_slow: eg.blinking_slow,
rgb_pixmap: eg.rgb_pixmap,
always_redraw_list: eg.always_redraw_list,
raster_backend: BlockCharBackend {
inner: eg.raster_backend,
},
};
Terminal::new(RataguiBackend::new("cagire", soft)).expect("terminal")
}
struct EditorState {
app: App,
terminal: TerminalType,

View File

@@ -4,24 +4,15 @@ use std::sync::atomic::{AtomicBool, AtomicI64, AtomicU32, AtomicU64, Ordering};
use std::sync::Arc;
use std::time::Duration;
use cagire::block_renderer::BlockCharBackend;
use clap::Parser;
use doux::EngineMetrics;
use eframe::NativeOptions;
use egui_ratatui::RataguiBackend;
use ratatui::Terminal;
use soft_ratatui::embedded_graphics_unicodefonts::{
mono_10x20_atlas, mono_6x13_atlas, mono_6x13_bold_atlas, mono_6x13_italic_atlas,
mono_7x13_atlas, mono_7x13_bold_atlas, mono_7x13_italic_atlas, mono_8x13_atlas,
mono_8x13_bold_atlas, mono_8x13_italic_atlas, mono_9x15_atlas, mono_9x15_bold_atlas,
mono_9x18_atlas, mono_9x18_bold_atlas,
};
use soft_ratatui::{EmbeddedGraphics, SoftBackend};
use cagire::engine::{
build_stream, AnalysisHandle, AudioStreamConfig, LinkState, ScopeBuffer,
SequencerHandle, SpectrumBuffer,
};
use cagire::terminal::{create_terminal, FontChoice, TerminalType};
use cagire::init::{init, InitArgs};
use cagire::input::{handle_key, handle_mouse, InputContext, InputResult};
use cagire::input_egui::{convert_egui_events, convert_egui_mouse, EguiMouseState};
@@ -47,103 +38,6 @@ struct Args {
buffer: Option<u32>,
}
#[derive(Clone, Copy, PartialEq)]
enum FontChoice {
Size6x13,
Size7x13,
Size8x13,
Size9x15,
Size9x18,
Size10x20,
}
impl FontChoice {
fn from_setting(s: &str) -> Self {
match s {
"6x13" => Self::Size6x13,
"7x13" => Self::Size7x13,
"9x15" => Self::Size9x15,
"9x18" => Self::Size9x18,
"10x20" => Self::Size10x20,
_ => Self::Size8x13,
}
}
fn to_setting(self) -> &'static str {
match self {
Self::Size6x13 => "6x13",
Self::Size7x13 => "7x13",
Self::Size8x13 => "8x13",
Self::Size9x15 => "9x15",
Self::Size9x18 => "9x18",
Self::Size10x20 => "10x20",
}
}
fn label(self) -> &'static str {
match self {
Self::Size6x13 => "6x13 (Compact)",
Self::Size7x13 => "7x13",
Self::Size8x13 => "8x13 (Default)",
Self::Size9x15 => "9x15",
Self::Size9x18 => "9x18",
Self::Size10x20 => "10x20 (Large)",
}
}
const ALL: [Self; 6] = [
Self::Size6x13,
Self::Size7x13,
Self::Size8x13,
Self::Size9x15,
Self::Size9x18,
Self::Size10x20,
];
}
type TerminalType = Terminal<RataguiBackend<BlockCharBackend>>;
fn create_terminal(font: FontChoice) -> TerminalType {
let (regular, bold, italic) = match font {
FontChoice::Size6x13 => (
mono_6x13_atlas(),
Some(mono_6x13_bold_atlas()),
Some(mono_6x13_italic_atlas()),
),
FontChoice::Size7x13 => (
mono_7x13_atlas(),
Some(mono_7x13_bold_atlas()),
Some(mono_7x13_italic_atlas()),
),
FontChoice::Size8x13 => (
mono_8x13_atlas(),
Some(mono_8x13_bold_atlas()),
Some(mono_8x13_italic_atlas()),
),
FontChoice::Size9x15 => (mono_9x15_atlas(), Some(mono_9x15_bold_atlas()), None),
FontChoice::Size9x18 => (mono_9x18_atlas(), Some(mono_9x18_bold_atlas()), None),
FontChoice::Size10x20 => (mono_10x20_atlas(), None, None),
};
let eg = SoftBackend::<EmbeddedGraphics>::new(80, 24, regular, bold, italic);
let soft = SoftBackend {
buffer: eg.buffer,
cursor: eg.cursor,
cursor_pos: eg.cursor_pos,
char_width: eg.char_width,
char_height: eg.char_height,
blink_counter: eg.blink_counter,
blinking_fast: eg.blinking_fast,
blinking_slow: eg.blinking_slow,
rgb_pixmap: eg.rgb_pixmap,
always_redraw_list: eg.always_redraw_list,
raster_backend: BlockCharBackend {
inner: eg.raster_backend,
},
};
Terminal::new(RataguiBackend::new("cagire", soft)).expect("terminal")
}
struct CagireDesktop {
app: cagire::app::App,
terminal: TerminalType,
@@ -336,7 +230,9 @@ impl CagireDesktop {
let term = self.terminal.get_frame().area();
let widget_rect = ctx.content_rect();
for mouse in convert_egui_mouse(ctx, widget_rect, term, &mut self.egui_mouse) {
let mouse_events = convert_egui_mouse(ctx, widget_rect, term, &mut self.egui_mouse);
let key_events = convert_egui_events(ctx);
let mut input_ctx = InputContext {
app: &mut self.app,
link: &self.link,
@@ -346,20 +242,11 @@ impl CagireDesktop {
seq_cmd_tx: &sequencer.cmd_tx,
nudge_us: &self.nudge_us,
};
for mouse in mouse_events {
handle_mouse(&mut input_ctx, mouse, term);
}
for key in convert_egui_events(ctx) {
let mut input_ctx = InputContext {
app: &mut self.app,
link: &self.link,
snapshot: &seq_snapshot,
playing: &self.playing,
audio_tx: &sequencer.audio_tx,
seq_cmd_tx: &sequencer.cmd_tx,
nudge_us: &self.nudge_us,
};
for key in key_events {
if let InputResult::Quit = handle_key(&mut input_ctx, key) {
return true;
}

View File

@@ -242,7 +242,7 @@ fn color_to_rgb(color: &Color, is_fg: bool) -> [u8; 3] {
Color::Yellow => [255, 215, 0],
Color::Blue => [0, 0, 139],
Color::Magenta => [255, 0, 255],
Color::Cyan => [0, 0, 255],
Color::Cyan => [0, 255, 255],
Color::Gray => [128, 128, 128],
Color::DarkGray => [64, 64, 64],
Color::LightRed => [255, 0, 0],

View File

@@ -21,3 +21,6 @@ pub mod block_renderer;
#[cfg(feature = "block-renderer")]
pub mod input_egui;
#[cfg(feature = "block-renderer")]
pub mod terminal;

110
src/terminal.rs Normal file
View File

@@ -0,0 +1,110 @@
use egui_ratatui::RataguiBackend;
use ratatui::Terminal;
use soft_ratatui::embedded_graphics_unicodefonts::{
mono_10x20_atlas, mono_6x13_atlas, mono_6x13_bold_atlas, mono_6x13_italic_atlas,
mono_7x13_atlas, mono_7x13_bold_atlas, mono_7x13_italic_atlas, mono_8x13_atlas,
mono_8x13_bold_atlas, mono_8x13_italic_atlas, mono_9x15_atlas, mono_9x15_bold_atlas,
mono_9x18_atlas, mono_9x18_bold_atlas,
};
use soft_ratatui::{EmbeddedGraphics, SoftBackend};
use crate::block_renderer::BlockCharBackend;
pub type TerminalType = Terminal<RataguiBackend<BlockCharBackend>>;
#[derive(Clone, Copy, PartialEq)]
pub enum FontChoice {
Size6x13,
Size7x13,
Size8x13,
Size9x15,
Size9x18,
Size10x20,
}
impl FontChoice {
pub fn from_setting(s: &str) -> Self {
match s {
"6x13" => Self::Size6x13,
"7x13" => Self::Size7x13,
"9x15" => Self::Size9x15,
"9x18" => Self::Size9x18,
"10x20" => Self::Size10x20,
_ => Self::Size8x13,
}
}
pub fn to_setting(self) -> &'static str {
match self {
Self::Size6x13 => "6x13",
Self::Size7x13 => "7x13",
Self::Size8x13 => "8x13",
Self::Size9x15 => "9x15",
Self::Size9x18 => "9x18",
Self::Size10x20 => "10x20",
}
}
pub fn label(self) -> &'static str {
match self {
Self::Size6x13 => "6x13 (Compact)",
Self::Size7x13 => "7x13",
Self::Size8x13 => "8x13 (Default)",
Self::Size9x15 => "9x15",
Self::Size9x18 => "9x18",
Self::Size10x20 => "10x20 (Large)",
}
}
pub const ALL: [Self; 6] = [
Self::Size6x13,
Self::Size7x13,
Self::Size8x13,
Self::Size9x15,
Self::Size9x18,
Self::Size10x20,
];
}
pub fn create_terminal(font: FontChoice) -> TerminalType {
let (regular, bold, italic) = match font {
FontChoice::Size6x13 => (
mono_6x13_atlas(),
Some(mono_6x13_bold_atlas()),
Some(mono_6x13_italic_atlas()),
),
FontChoice::Size7x13 => (
mono_7x13_atlas(),
Some(mono_7x13_bold_atlas()),
Some(mono_7x13_italic_atlas()),
),
FontChoice::Size8x13 => (
mono_8x13_atlas(),
Some(mono_8x13_bold_atlas()),
Some(mono_8x13_italic_atlas()),
),
FontChoice::Size9x15 => (mono_9x15_atlas(), Some(mono_9x15_bold_atlas()), None),
FontChoice::Size9x18 => (mono_9x18_atlas(), Some(mono_9x18_bold_atlas()), None),
FontChoice::Size10x20 => (mono_10x20_atlas(), None, None),
};
// SoftBackend fields are copied individually to wrap raster_backend in BlockCharBackend.
// If soft_ratatui changes its field layout, this will fail to compile — that's intentional.
let eg = SoftBackend::<EmbeddedGraphics>::new(80, 24, regular, bold, italic);
let soft = SoftBackend {
buffer: eg.buffer,
cursor: eg.cursor,
cursor_pos: eg.cursor_pos,
char_width: eg.char_width,
char_height: eg.char_height,
blink_counter: eg.blink_counter,
blinking_fast: eg.blinking_fast,
blinking_slow: eg.blinking_slow,
rgb_pixmap: eg.rgb_pixmap,
always_redraw_list: eg.always_redraw_list,
raster_backend: BlockCharBackend {
inner: eg.raster_backend,
},
};
Terminal::new(RataguiBackend::new("cagire", soft)).expect("terminal")
}