Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ default-members = ["src/redrop"]
resolver = "2"

[profile.release]
opt-level = 2 # fast and small wasm
opt-level = "z"
codegen-units = 1
lto = "fat"
panic = "abort"
strip = "symbols"
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,9 @@ ProjectM (Milkdrop) Music Visualization in Rust.

### ReDrop App

- [ ] Search Preset:
- [ ] Search Categories
- [ ] Hide Empty Categories
- [ ] Grid Layout: auto calcul columns
- [ ] Show Flat Preset: Align text to the left
- [X] Filter Preset / Hide Empty Categories
- [X] Grid Layout: Responsive
- [X] Show Flat Preset: Align text to the left
- [ ] Change preset time interval on nBar (4 beat)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question (documentation): Clarify 'Set Window default size (persistence !?)'

The exclamation and question marks might be confusing. Consider rephrasing to 'Set Window default size (persistent?)' or clarify the intended meaning.

160 bpm, 32 bar -> 48s [4 / ( (160 / 60) ) * 32]
- [ ] Set Window default size (persistence !?)
Expand Down
Binary file removed projectM-4.dll
Binary file not shown.
Binary file removed redrop.exe
Binary file not shown.
Binary file removed redrop_player.exe
Binary file not shown.
24 changes: 22 additions & 2 deletions src/common/src/preset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub struct Preset {
pub img: Option<PathBuf>,
}

#[derive(Debug, Clone)]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Added Debug and Clone traits

Adding Debug and Clone traits is useful for logging and copying. Ensure that these traits are necessary for the Node enum to avoid unnecessary trait implementations.

pub enum Node {
PresetId(usize),
InnerNode(BTreeMap<String, Node>),
Expand Down Expand Up @@ -50,7 +51,7 @@ impl Presets {
path: path.clone(),
img: if img.exists() { Some(img) } else { None },
};
node.insert(name, Node::PresetId(preset_id));
node.insert(name.to_lowercase(), Node::PresetId(preset_id));
self.lists.push(preset);
}
}
Expand All @@ -59,7 +60,26 @@ impl Presets {
println!("Error: Check `presets path` in config ! ({})", e);
}
}

node
}
}

pub fn filter_presets_tree(query: &str, node: &BTreeMap<String, Node>) -> BTreeMap<String, Node> {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (performance): New filter_presets_tree function

The new filter_presets_tree function is a good addition for filtering. Ensure that this function is optimized for large trees to avoid performance bottlenecks.

Suggested change
pub fn filter_presets_tree(query: &str, node: &BTreeMap<String, Node>) -> BTreeMap<String, Node> {
pub fn filter_presets_tree<'a>(query: &str, node: &'a BTreeMap<String, Node>) -> BTreeMap<String, Node> {
node.iter()
.filter(|(name, _)| name.contains(query))
.map(|(name, node)| (name.clone(), node.clone()))
.collect()
}

let mut filtered_node = BTreeMap::new();
for (name, node) in node {
match node {
Node::PresetId(_) => {
if name.contains(query.to_lowercase().as_str()) {
filtered_node.insert(name.clone(), node.clone());
}
}
Node::InnerNode(inner_node) => {
let filtered_inner = filter_presets_tree(query, inner_node);
if !filtered_inner.is_empty() {
filtered_node.insert(name.clone(), Node::InnerNode(filtered_inner));
}
}
}
}
filtered_node
}
6 changes: 3 additions & 3 deletions src/player/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ edition = "2021"
[dependencies]
common = { path = "../common" }

libc = "*"
# libc = "*"
projectm = "2.0.1-alpha"
egui = "0.27.2"
eframe = { version = "0.27.2", default-features = false, features = [
"accesskit",
# "accesskit",
"default_fonts",
"glow",
] }
log = "0.4"
env_logger = "0.11.3"
ipc-channel = "0.18.1"
ipc-channel = "0.18.1"
8 changes: 4 additions & 4 deletions src/redrop/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ edition = "2021"
common = { path = "../common" }
egui = "0.27.2"
eframe = { version = "0.27.2", default-features = false, features = [
"accesskit",
# "accesskit",
"default_fonts",
"glow",
] }
egui_extras = { version = "0.27.2", features = ["all_loaders"] }
egui_extras = { version = "0.27.2", features = ["file", "image"] }
image = { version = "0.24", features = [
"jpeg",
"png",
# "png
] } # The version needs to be same as the version used by `egui_extra`. (Not working with 0.25.x)
log = "0.4"
env_logger = "0.11.3"
serde = { version = "1.0.203", features = ["derive"] }
ipc-channel = "0.18.1"
rand = "0.8.5"
rfd = "0.14.1"
rfd = "0.14.1"
3 changes: 3 additions & 0 deletions src/redrop/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use eframe::egui;

use std::collections::BTreeMap;
use std::path::Path;

use crate::ipc_message::{IpcExchange, Message};
Expand Down Expand Up @@ -34,6 +35,7 @@ struct ReDropApp {
config_draft: config::Config,
show_config: bool,
presets: preset::Presets,
filtered_presets_tree: BTreeMap<String, preset::Node>,
smooth: bool,
preset_search_query: String,
player_app: Option<std::process::Child>,
Expand All @@ -48,6 +50,7 @@ impl ReDropApp {
slf.config_draft = slf.config.clone();
slf.presets
.update_presets_lists_and_tree(Path::new(&slf.config.presets_path));
slf.filtered_presets_tree = slf.presets.tree.clone();

let (ipc_server, server_name) = IpcOneShotServer::<IpcExchange>::new().unwrap();

Expand Down
15 changes: 10 additions & 5 deletions src/redrop/src/main_ui.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
use crate::ReDropApp;
use common::ipc_message::Message;
use common::preset::filter_presets_tree;

impl ReDropApp {
pub fn show_main_ui(&mut self, ctx: &egui::Context) {
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
ui.horizontal(|ui| {
ui.text_edit_singleline(&mut self.preset_search_query);
if ui
.add(egui::TextEdit::singleline(&mut self.preset_search_query))
.changed()
{
self.filtered_presets_tree =
filter_presets_tree(&self.preset_search_query, &self.presets.tree);
Comment on lines +13 to +14
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (performance): Filtering presets on search query change

Filtering presets on search query change is a good approach. Ensure that the UI updates efficiently to reflect the filtered results without noticeable lag.

Suggested change
self.filtered_presets_tree =
filter_presets_tree(&self.preset_search_query, &self.presets.tree);
self.filtered_presets_tree = {
let query = self.preset_search_query.clone();
let tree = self.presets.tree.clone();
filter_presets_tree(&query, &tree)
};

}
if ui.button("Config").clicked() {
self.show_config = true;
}
Expand Down Expand Up @@ -68,11 +75,9 @@ impl ReDropApp {
// self.show_presets_into_flat_tree(ui, &self.presets.tree);
let option_grid = true; // TODO: Option in config [ReDrop]
if option_grid {
self.show_presets_into_tree_grid(ui, &self.presets.tree);
// TODO: Move presets_tree in the fn
self.show_presets_into_tree_grid(ui, &self.filtered_presets_tree);
} else {
self.show_presets_into_flat_tree(ui, &self.presets.tree);
// TODO: Move presets_tree in the fn
self.show_presets_into_flat_tree(ui, &self.filtered_presets_tree);
}
});
});
Expand Down
34 changes: 10 additions & 24 deletions src/redrop/src/presets_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,20 @@ impl ReDropApp {
ui: &mut egui::Ui,
node: &BTreeMap<String, preset::Node>,
) {
const MAX_PRESETS_PER_ROW: usize = 8; // TODO: Autosize with ui.available_width() / preset_width

egui::Grid::new("preset_grid")
.num_columns(MAX_PRESETS_PER_ROW)
.num_columns(1)
.spacing([4., 4.])
.show(ui, |ui| {
let mut preset_count = 0;
let max_preset_per_row = (ui.available_width() / 68.) as usize; // Preset width = 64. + 4. (spacing)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Magic number for preset width

Consider defining a constant or a configuration parameter for the preset width (68) to improve readability and maintainability.

Suggested change
let max_preset_per_row = (ui.available_width() / 68.) as usize; // Preset width = 64. + 4. (spacing)
const PRESET_WIDTH: f32 = 68.0;
let max_preset_per_row = (ui.available_width() / PRESET_WIDTH) as usize;

for (name, node) in node {
match node {
preset::Node::PresetId(preset_id) => {
if self.presets.lists[*preset_id]
.name
.contains(&self.preset_search_query)
Comment on lines -20 to -22
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (performance): Removed search query filtering

The removal of the search query filtering might lead to performance issues if the preset list is large. Ensure that the filtering is handled elsewhere effectively.

{
self.show_preset(ui, preset_id);
preset_count += 1;
if preset_count >= MAX_PRESETS_PER_ROW {
ui.end_row();
preset_count = 0;
}
self.show_preset(ui, preset_id);
preset_count += 1;
if preset_count >= max_preset_per_row {
ui.end_row();
preset_count = 0;
}
}
preset::Node::InnerNode(inner_node) => {
Expand All @@ -41,7 +36,6 @@ impl ReDropApp {
}

fn show_preset(&self, ui: &mut egui::Ui, preset_id: &usize) {
// TODO: Add image button into a Grid (Responsive ?)
let preset = &self.presets.lists[*preset_id];
if let Some(img_path) = &preset.img {
let file_path = "file://".to_owned() + img_path.to_str().unwrap();
Expand Down Expand Up @@ -82,12 +76,7 @@ impl ReDropApp {
for (name, node) in node {
match node {
preset::Node::PresetId(preset_id) => {
if self.presets.lists[*preset_id]
.name
.contains(&self.preset_search_query)
{
self.show_preset_flat(ui, preset_id);
}
self.show_preset_flat(ui, preset_id);
}
preset::Node::InnerNode(inner_node) => {
egui::CollapsingHeader::new(name).show(ui, |ui| {
Expand All @@ -101,10 +90,7 @@ impl ReDropApp {
fn show_preset_flat(&self, ui: &mut egui::Ui, preset_id: &usize) {
let preset = &self.presets.lists[*preset_id];
if ui
.add_sized(
[ui.available_width(), 0.],
egui::Button::new(&preset.name).wrap(true), // TODO: Text to left
) // TODO Fix: Button size "overflow" if name is too long / This can be a problem with grid..
.add(egui::Button::new(&preset.name).wrap(true).frame(false))
.clicked()
{
self.send_load_preset_file(preset.id, self.smooth)
Expand Down