clean up some compiler warnings
This commit is contained in:
parent
346baac840
commit
c35b7a31de
|
|
@ -17,7 +17,7 @@ use crate::object::Transform;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
use uuid::Uuid;
|
||||
use vello::kurbo::{Rect, Affine, Shape as KurboShape};
|
||||
use vello::kurbo::{Rect, Shape as KurboShape};
|
||||
|
||||
/// Vector clip containing nested layers
|
||||
///
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use std::path::{Path, PathBuf};
|
|||
use zip::write::FileOptions;
|
||||
use zip::{CompressionMethod, ZipArchive, ZipWriter};
|
||||
use flacenc::error::Verify;
|
||||
use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64_STANDARD};
|
||||
|
||||
/// File format version
|
||||
pub const BEAM_VERSION: &str = "1.0.0";
|
||||
|
|
@ -272,7 +273,7 @@ pub fn save_beam(
|
|||
// Priority 3: No original file - encode PCM as FLAC
|
||||
eprintln!("📊 [SAVE_BEAM] Encoding PCM to FLAC for pool {} (no original file)", entry.pool_index);
|
||||
// Embedded data is always PCM - encode as FLAC
|
||||
let audio_bytes = base64::decode(&embedded_data.data_base64)
|
||||
let audio_bytes = BASE64_STANDARD.decode(&embedded_data.data_base64)
|
||||
.map_err(|e| format!("Failed to decode base64 audio data for pool index {}: {}", entry.pool_index, e))?;
|
||||
|
||||
let zip_filename = format!("media/audio/{}.flac", entry.pool_index);
|
||||
|
|
@ -511,13 +512,13 @@ pub fn load_beam(path: &Path) -> Result<LoadedProject, String> {
|
|||
flac_decode_time += flac_decode_start.elapsed().as_secs_f64() * 1000.0;
|
||||
|
||||
Some(daw_backend::audio::pool::EmbeddedAudioData {
|
||||
data_base64: base64::encode(&pcm_bytes),
|
||||
data_base64: BASE64_STANDARD.encode(&pcm_bytes),
|
||||
format: "wav".to_string(), // Mark as WAV since it's now PCM
|
||||
})
|
||||
} else {
|
||||
// Lossy format - store as-is
|
||||
Some(daw_backend::audio::pool::EmbeddedAudioData {
|
||||
data_base64: base64::encode(&audio_bytes),
|
||||
data_base64: BASE64_STANDARD.encode(&audio_bytes),
|
||||
format: format.clone(),
|
||||
})
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
//! Provides functions for testing if points or rectangles intersect with
|
||||
//! shapes and objects, taking into account transform hierarchies.
|
||||
|
||||
use crate::clip::{ClipInstance, VectorClip, VideoClip};
|
||||
use crate::clip::ClipInstance;
|
||||
use crate::layer::VectorLayer;
|
||||
use crate::object::ShapeInstance;
|
||||
use crate::shape::Shape;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
//! Layers can be nested within other layers for organizational purposes.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Node in the layer tree
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ use crate::animation::TransformProperty;
|
|||
use crate::clip::ImageAsset;
|
||||
use crate::document::Document;
|
||||
use crate::layer::{AnyLayer, LayerTrait, VectorLayer};
|
||||
use crate::object::ShapeInstance;
|
||||
use kurbo::{Affine, Shape};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
/// This module provides a default instrument (bass synthesizer) for MIDI tracks
|
||||
/// until the user implements the node editor to load custom instruments.
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Embedded default MIDI instrument preset (bass synthesizer)
|
||||
const DEFAULT_MIDI_INSTRUMENT: &str = include_str!("../../../src/assets/instruments/synthesizers/bass.json");
|
||||
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ enum SplitPreviewMode {
|
|||
|
||||
/// Icon cache for pane type icons
|
||||
struct IconCache {
|
||||
icons: HashMap<PaneType, egui_extras::RetainedImage>,
|
||||
icons: HashMap<PaneType, egui::TextureHandle>,
|
||||
assets_path: std::path::PathBuf,
|
||||
}
|
||||
|
||||
|
|
@ -172,15 +172,46 @@ impl IconCache {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_or_load(&mut self, pane_type: PaneType) -> Option<&egui_extras::RetainedImage> {
|
||||
fn get_or_load(&mut self, pane_type: PaneType, ctx: &egui::Context) -> Option<&egui::TextureHandle> {
|
||||
if !self.icons.contains_key(&pane_type) {
|
||||
// Load and cache the icon
|
||||
// Load SVG and rasterize using resvg
|
||||
let icon_path = self.assets_path.join(pane_type.icon_file());
|
||||
if let Ok(image) = egui_extras::RetainedImage::from_svg_bytes(
|
||||
pane_type.icon_file(),
|
||||
&std::fs::read(&icon_path).unwrap_or_default(),
|
||||
if let Ok(svg_data) = std::fs::read(&icon_path) {
|
||||
// Rasterize at reasonable size for pane icons
|
||||
let render_size = 64;
|
||||
|
||||
if let Ok(tree) = resvg::usvg::Tree::from_data(&svg_data, &resvg::usvg::Options::default()) {
|
||||
let pixmap_size = tree.size().to_int_size();
|
||||
let scale_x = render_size as f32 / pixmap_size.width() as f32;
|
||||
let scale_y = render_size as f32 / pixmap_size.height() as f32;
|
||||
let scale = scale_x.min(scale_y);
|
||||
|
||||
let final_size = resvg::usvg::Size::from_wh(
|
||||
pixmap_size.width() as f32 * scale,
|
||||
pixmap_size.height() as f32 * scale,
|
||||
).unwrap_or(resvg::usvg::Size::from_wh(render_size as f32, render_size as f32).unwrap());
|
||||
|
||||
if let Some(mut pixmap) = resvg::tiny_skia::Pixmap::new(
|
||||
final_size.width() as u32,
|
||||
final_size.height() as u32,
|
||||
) {
|
||||
self.icons.insert(pane_type, image);
|
||||
let transform = resvg::tiny_skia::Transform::from_scale(scale, scale);
|
||||
resvg::render(&tree, transform, &mut pixmap.as_mut());
|
||||
|
||||
// Convert RGBA8 to egui ColorImage
|
||||
let rgba_data = pixmap.data();
|
||||
let size = [pixmap.width() as usize, pixmap.height() as usize];
|
||||
let color_image = egui::ColorImage::from_rgba_unmultiplied(size, rgba_data);
|
||||
|
||||
// Upload to GPU
|
||||
let texture = ctx.load_texture(
|
||||
pane_type.icon_file(),
|
||||
color_image,
|
||||
egui::TextureOptions::LINEAR,
|
||||
);
|
||||
self.icons.insert(pane_type, texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.icons.get(&pane_type)
|
||||
|
|
@ -1103,7 +1134,7 @@ impl EditorApp {
|
|||
let layer_name = format!("Layer {}", layer_count + 1);
|
||||
|
||||
let action = lightningbeam_core::actions::AddLayerAction::new_vector(layer_name);
|
||||
self.action_executor.execute(Box::new(action));
|
||||
let _ = self.action_executor.execute(Box::new(action));
|
||||
|
||||
// Select the newly created layer (last child in the document)
|
||||
if let Some(last_layer) = self.action_executor.document().root.children.last() {
|
||||
|
|
@ -1135,7 +1166,7 @@ impl EditorApp {
|
|||
// Create audio layer in document
|
||||
let audio_layer = AudioLayer::new_sampled(layer_name.clone());
|
||||
let action = lightningbeam_core::actions::AddLayerAction::new(AnyLayer::Audio(audio_layer));
|
||||
self.action_executor.execute(Box::new(action));
|
||||
let _ = self.action_executor.execute(Box::new(action));
|
||||
|
||||
// Get the newly created layer ID
|
||||
if let Some(last_layer) = self.action_executor.document().root.children.last() {
|
||||
|
|
@ -1168,7 +1199,7 @@ impl EditorApp {
|
|||
// Create MIDI layer in document
|
||||
let midi_layer = AudioLayer::new_midi(layer_name.clone());
|
||||
let action = lightningbeam_core::actions::AddLayerAction::new(AnyLayer::Audio(midi_layer));
|
||||
self.action_executor.execute(Box::new(action));
|
||||
let _ = self.action_executor.execute(Box::new(action));
|
||||
|
||||
// Get the newly created layer ID
|
||||
if let Some(last_layer) = self.action_executor.document().root.children.last() {
|
||||
|
|
@ -1602,7 +1633,7 @@ impl EditorApp {
|
|||
/// Import an audio file via daw-backend
|
||||
fn import_audio(&mut self, path: &std::path::Path) {
|
||||
use daw_backend::io::audio_file::AudioFile;
|
||||
use lightningbeam_core::clip::{AudioClip, AudioClipType};
|
||||
use lightningbeam_core::clip::AudioClip;
|
||||
|
||||
let name = path.file_stem()
|
||||
.and_then(|s| s.to_str())
|
||||
|
|
@ -1768,7 +1799,7 @@ impl EditorApp {
|
|||
|
||||
std::thread::spawn(move || {
|
||||
use lightningbeam_core::video::extract_audio_from_video;
|
||||
use lightningbeam_core::clip::{AudioClip, AudioClipType};
|
||||
use lightningbeam_core::clip::AudioClip;
|
||||
|
||||
// Extract audio from video (slow FFmpeg operation)
|
||||
match extract_audio_from_video(&path_clone) {
|
||||
|
|
@ -2196,7 +2227,7 @@ impl eframe::App for EditorApp {
|
|||
}
|
||||
} else {
|
||||
// No audio system available, execute without backend
|
||||
self.action_executor.execute(action);
|
||||
let _ = self.action_executor.execute(action);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2660,8 +2691,8 @@ fn render_pane(
|
|||
|
||||
// Load and render icon if available
|
||||
if let Some(pane_type) = pane_type {
|
||||
if let Some(icon) = ctx.icon_cache.get_or_load(pane_type) {
|
||||
let icon_texture_id = icon.texture_id(ui.ctx());
|
||||
if let Some(icon) = ctx.icon_cache.get_or_load(pane_type, ui.ctx()) {
|
||||
let icon_texture_id = icon.id();
|
||||
let icon_rect = icon_button_rect.shrink(2.0); // Small padding inside button
|
||||
ui.painter().image(
|
||||
icon_texture_id,
|
||||
|
|
@ -2698,10 +2729,10 @@ fn render_pane(
|
|||
|
||||
for pane_type_option in PaneType::all() {
|
||||
// Load icon for this pane type
|
||||
if let Some(icon) = ctx.icon_cache.get_or_load(*pane_type_option) {
|
||||
if let Some(icon) = ctx.icon_cache.get_or_load(*pane_type_option, ui.ctx()) {
|
||||
ui.horizontal(|ui| {
|
||||
// Show icon
|
||||
let icon_texture_id = icon.texture_id(ui.ctx());
|
||||
let icon_texture_id = icon.id();
|
||||
let icon_size = egui::vec2(16.0, 16.0);
|
||||
ui.add(egui::Image::new((icon_texture_id, icon_size)));
|
||||
|
||||
|
|
|
|||
|
|
@ -1093,7 +1093,7 @@ impl AssetLibraryPane {
|
|||
|
||||
// Use egui's built-in ScrollArea for scrolling
|
||||
let scroll_area_rect = rect;
|
||||
ui.allocate_ui_at_rect(scroll_area_rect, |ui| {
|
||||
ui.allocate_new_ui(egui::UiBuilder::new().max_rect(scroll_area_rect), |ui| {
|
||||
egui::ScrollArea::vertical()
|
||||
.id_salt(("asset_list_scroll", path))
|
||||
.auto_shrink([false, false])
|
||||
|
|
@ -1423,7 +1423,7 @@ impl AssetLibraryPane {
|
|||
let total_height = GRID_SPACING + rows as f32 * (item_height + GRID_SPACING);
|
||||
|
||||
// Use egui's built-in ScrollArea for scrolling
|
||||
ui.allocate_ui_at_rect(rect, |ui| {
|
||||
ui.allocate_new_ui(egui::UiBuilder::new().max_rect(rect), |ui| {
|
||||
egui::ScrollArea::vertical()
|
||||
.id_salt(("asset_grid_scroll", path))
|
||||
.auto_shrink([false, false])
|
||||
|
|
|
|||
|
|
@ -829,7 +829,7 @@ impl egui_wgpu::CallbackTrait for VelloCallback {
|
|||
|
||||
// 7. Draw path drawing preview
|
||||
if let lightningbeam_core::tool::ToolState::DrawingPath { ref points, .. } = self.tool_state {
|
||||
use vello::kurbo::{BezPath, Point};
|
||||
use vello::kurbo::BezPath;
|
||||
|
||||
if points.len() >= 2 {
|
||||
// Build a simple line path from the raw points for preview
|
||||
|
|
@ -1175,15 +1175,15 @@ impl egui_wgpu::CallbackTrait for VelloCallback {
|
|||
|
||||
// Copy the pixel from texture to staging buffer
|
||||
encoder.copy_texture_to_buffer(
|
||||
wgpu::ImageCopyTexture {
|
||||
wgpu::TexelCopyTextureInfo {
|
||||
texture,
|
||||
mip_level: 0,
|
||||
origin: wgpu::Origin3d { x: tex_x, y: tex_y, z: 0 },
|
||||
aspect: wgpu::TextureAspect::All,
|
||||
},
|
||||
wgpu::ImageCopyBuffer {
|
||||
wgpu::TexelCopyBufferInfo {
|
||||
buffer: &staging_buffer,
|
||||
layout: wgpu::ImageDataLayout {
|
||||
layout: wgpu::TexelCopyBufferLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: Some(bytes_per_row),
|
||||
rows_per_image: Some(1),
|
||||
|
|
@ -1554,7 +1554,6 @@ impl StagePane {
|
|||
use std::collections::HashMap;
|
||||
|
||||
// Separate shape instances from clip instances
|
||||
use lightningbeam_core::object::Transform;
|
||||
let mut shape_instance_positions = HashMap::new();
|
||||
let mut clip_instance_transforms = HashMap::new();
|
||||
|
||||
|
|
@ -1795,7 +1794,7 @@ impl StagePane {
|
|||
|
||||
// Create and execute action immediately
|
||||
let action = AddShapeAction::new(active_layer_id, shape, object);
|
||||
shared.action_executor.execute(Box::new(action));
|
||||
let _ = shared.action_executor.execute(Box::new(action));
|
||||
|
||||
// Clear tool state to stop preview rendering
|
||||
*shared.tool_state = ToolState::Idle;
|
||||
|
|
@ -1923,7 +1922,7 @@ impl StagePane {
|
|||
|
||||
// Create and execute action immediately
|
||||
let action = AddShapeAction::new(active_layer_id, shape, object);
|
||||
shared.action_executor.execute(Box::new(action));
|
||||
let _ = shared.action_executor.execute(Box::new(action));
|
||||
|
||||
// Clear tool state to stop preview rendering
|
||||
*shared.tool_state = ToolState::Idle;
|
||||
|
|
@ -2015,7 +2014,7 @@ impl StagePane {
|
|||
|
||||
// Create and execute action immediately
|
||||
let action = AddShapeAction::new(active_layer_id, shape, object);
|
||||
shared.action_executor.execute(Box::new(action));
|
||||
let _ = shared.action_executor.execute(Box::new(action));
|
||||
|
||||
// Clear tool state to stop preview rendering
|
||||
*shared.tool_state = ToolState::Idle;
|
||||
|
|
@ -2106,7 +2105,7 @@ impl StagePane {
|
|||
|
||||
// Create and execute action immediately
|
||||
let action = AddShapeAction::new(active_layer_id, shape, object);
|
||||
shared.action_executor.execute(Box::new(action));
|
||||
let _ = shared.action_executor.execute(Box::new(action));
|
||||
|
||||
// Clear tool state to stop preview rendering
|
||||
*shared.tool_state = ToolState::Idle;
|
||||
|
|
@ -2390,7 +2389,7 @@ impl StagePane {
|
|||
|
||||
// Create and execute action immediately
|
||||
let action = AddShapeAction::new(active_layer_id, shape, object);
|
||||
shared.action_executor.execute(Box::new(action));
|
||||
let _ = shared.action_executor.execute(Box::new(action));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2449,7 +2448,7 @@ impl StagePane {
|
|||
2.0, // tolerance - could be made configurable
|
||||
lightningbeam_core::gap_handling::GapHandlingMode::BridgeSegment,
|
||||
);
|
||||
shared.action_executor.execute(Box::new(action));
|
||||
let _ = shared.action_executor.execute(Box::new(action));
|
||||
println!("Paint bucket action executed");
|
||||
}
|
||||
}
|
||||
|
|
@ -3937,7 +3936,6 @@ impl StagePane {
|
|||
if delta.x.abs() > 0.01 || delta.y.abs() > 0.01 {
|
||||
if let Some(active_layer_id) = shared.active_layer_id {
|
||||
use std::collections::HashMap;
|
||||
use lightningbeam_core::object::Transform;
|
||||
|
||||
let mut shape_instance_positions = HashMap::new();
|
||||
let mut clip_instance_transforms = HashMap::new();
|
||||
|
|
@ -4273,7 +4271,7 @@ impl PaneRenderer for StagePane {
|
|||
let mut add_layer_action = lightningbeam_core::actions::AddLayerAction::new(new_layer);
|
||||
|
||||
// Execute immediately to get the layer ID
|
||||
add_layer_action.execute(shared.action_executor.document_mut());
|
||||
let _ = add_layer_action.execute(shared.action_executor.document_mut());
|
||||
target_layer_id = add_layer_action.created_layer_id();
|
||||
|
||||
// Update active layer to the new layer
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ impl TimelinePane {
|
|||
|
||||
let layers: Vec<_> = document.root.children.iter().rev().collect();
|
||||
let layer = layers.get(hovered_layer_index)?;
|
||||
let layer_data = layer.layer();
|
||||
let _layer_data = layer.layer();
|
||||
|
||||
let clip_instances = match layer {
|
||||
lightningbeam_core::layer::AnyLayer::Vector(vl) => &vl.clip_instances,
|
||||
|
|
@ -848,7 +848,7 @@ impl TimelinePane {
|
|||
|
||||
// Mute button
|
||||
// TODO: Replace with SVG icon (volume-up-fill.svg / volume-mute.svg)
|
||||
let mute_response = ui.allocate_ui_at_rect(mute_button_rect, |ui| {
|
||||
let mute_response = ui.allocate_new_ui(egui::UiBuilder::new().max_rect(mute_button_rect), |ui| {
|
||||
let mute_text = if is_muted { "🔇" } else { "🔊" };
|
||||
let button = egui::Button::new(mute_text)
|
||||
.fill(if is_muted {
|
||||
|
|
@ -872,7 +872,7 @@ impl TimelinePane {
|
|||
|
||||
// Solo button
|
||||
// TODO: Replace with SVG headphones icon
|
||||
let solo_response = ui.allocate_ui_at_rect(solo_button_rect, |ui| {
|
||||
let solo_response = ui.allocate_new_ui(egui::UiBuilder::new().max_rect(solo_button_rect), |ui| {
|
||||
let button = egui::Button::new("🎧")
|
||||
.fill(if is_soloed {
|
||||
egui::Color32::from_rgba_unmultiplied(100, 200, 100, 100)
|
||||
|
|
@ -895,7 +895,7 @@ impl TimelinePane {
|
|||
|
||||
// Lock button
|
||||
// TODO: Replace with SVG lock/lock-open icons
|
||||
let lock_response = ui.allocate_ui_at_rect(lock_button_rect, |ui| {
|
||||
let lock_response = ui.allocate_new_ui(egui::UiBuilder::new().max_rect(lock_button_rect), |ui| {
|
||||
let lock_text = if is_locked { "🔒" } else { "🔓" };
|
||||
let button = egui::Button::new(lock_text)
|
||||
.fill(if is_locked {
|
||||
|
|
@ -918,7 +918,7 @@ impl TimelinePane {
|
|||
}
|
||||
|
||||
// Volume slider (nonlinear: 0-70% slider = 0-100% volume, 70-100% slider = 100-200% volume)
|
||||
let volume_response = ui.allocate_ui_at_rect(volume_slider_rect, |ui| {
|
||||
let volume_response = ui.allocate_new_ui(egui::UiBuilder::new().max_rect(volume_slider_rect), |ui| {
|
||||
// Map volume (0.0-2.0) to slider position (0.0-1.0)
|
||||
let slider_value = if current_volume <= 1.0 {
|
||||
// 0.0-1.0 volume maps to 0.0-0.7 slider (70%)
|
||||
|
|
@ -1086,7 +1086,7 @@ impl TimelinePane {
|
|||
// Instance positioned on the layer's timeline using timeline_start
|
||||
// The layer itself has start_time, so the absolute timeline position is:
|
||||
// layer.start_time + instance.timeline_start
|
||||
let layer_data = layer.layer();
|
||||
let _layer_data = layer.layer();
|
||||
let mut instance_start = clip_instance.timeline_start;
|
||||
|
||||
// Apply drag offset preview for selected clips with snapping
|
||||
|
|
@ -1428,7 +1428,7 @@ impl TimelinePane {
|
|||
if clicked_layer_index < layer_count {
|
||||
let layers: Vec<_> = document.root.children.iter().rev().collect();
|
||||
if let Some(layer) = layers.get(clicked_layer_index) {
|
||||
let layer_data = layer.layer();
|
||||
let _layer_data = layer.layer();
|
||||
|
||||
// Get clip instances for this layer
|
||||
let clip_instances = match layer {
|
||||
|
|
@ -1605,7 +1605,7 @@ impl TimelinePane {
|
|||
// Iterate through all layers to find selected clip instances
|
||||
for layer in &document.root.children {
|
||||
let layer_id = layer.id();
|
||||
let layer_data = layer.layer();
|
||||
let _layer_data = layer.layer();
|
||||
|
||||
let clip_instances = match layer {
|
||||
lightningbeam_core::layer::AnyLayer::Vector(vl) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue