gled 2.28.5

gled is an application for creating animations and effects on artnet or dmx installations
use crate::{midi::runtime::TestCommand, storage::asset::midi_controller::MidiController};
use egui::{ComboBox, Ui};
use egui_phosphor_icons::icons;
use midir::MidiOutput;
use std::collections::BTreeSet;

use super::{MidiControllerTestState, iconized, monitor};

fn is_selectable_output_port(name: &str) -> bool {
    !name.trim().is_empty()
        && !name.contains("gled_read_input")
        && !name.contains("gled_write_output")
        && !name.contains("Midi Through")
}

fn available_output_ports() -> Vec<String> {
    let Ok(output) = MidiOutput::new("gled_test_device_scan") else {
        return Vec::new();
    };

    output
        .ports()
        .into_iter()
        .filter_map(|port| output.port_name(&port).ok())
        .filter(|name| is_selectable_output_port(name))
        .collect()
}

fn test_device_port_options(diagnostics: &[monitor::MidiPortDiagnostics]) -> Vec<String> {
    let mut ports = BTreeSet::new();

    for diag in diagnostics {
        if diag.output_connected && is_selectable_output_port(&diag.port_name) {
            ports.insert(diag.port_name.clone());
        }
    }
    for port in available_output_ports() {
        ports.insert(port);
    }

    ports.into_iter().collect()
}

pub(super) fn render_test_device_box(
    ui: &mut Ui,
    test_state: &mut MidiControllerTestState,
    diagnostics: &[monitor::MidiPortDiagnostics],
    controller_id: crate::storage::asset_id::AssetId<MidiController>,
    test_command_sender: &kanal::Sender<TestCommand>,
) -> Option<String> {
    let mut selected_test_port = None;
    let port_options = test_device_port_options(diagnostics);
    egui::Frame::group(ui.style())
        .fill(ui.visuals().extreme_bg_color)
        .show(ui, |ui| {
            ui.horizontal(|ui| {
                ui.label(iconized(ui, icons::RADIO_BUTTON, " Test Device"));
                ComboBox::new(format!("{}_test_output_port", controller_id), "")
                    .selected_text(if test_state.selected_output_port.is_none() {
                        "No Test Device"
                    } else {
                        test_state
                            .selected_output_port
                            .as_deref()
                            .unwrap_or("No Test Device")
                    })
                    .show_ui(ui, |ui| {
                        if ui
                            .selectable_label(
                                test_state.selected_output_port.is_none(),
                                "No Test Device",
                            )
                            .clicked()
                        {
                            test_state.selected_output_port = None;
                            let _ = test_command_sender.send(TestCommand::UnsetTestDevice);
                        }
                        for port_name in &port_options {
                            if ui
                                .selectable_label(
                                    test_state
                                        .selected_output_port
                                        .as_deref()
                                        .is_some_and(|port| port == port_name),
                                    port_name,
                                )
                                .clicked()
                            {
                                test_state.selected_output_port = Some(port_name.clone());
                                selected_test_port = Some(port_name.clone());
                                let _ = test_command_sender.send(TestCommand::SetTestDevice {
                                    port_name: port_name.clone(),
                                });
                            }
                        }
                    });
            });
        });

    selected_test_port
}