From a9c51a48bc1636087d4ccf20e8f2abce9fe8feb0 Mon Sep 17 00:00:00 2001
From: Nicole Tietz-Sokolskaya <me@ntietz.com>
Date: Thu, 26 Dec 2024 19:26:58 -0500
Subject: [PATCH] start on UI

---
 Cargo.toml |  3 +++
 src/ui.rs  | 56 ++++++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 3d493c0..100a2aa 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,3 +12,6 @@ hex = "0.4.3"
 midir = "0.10.0"
 nom = "7.1.3"
 thiserror = "1.0.63"
+
+[lints.clippy]
+unwrap_used = "deny"
diff --git a/src/ui.rs b/src/ui.rs
index ed9ed9a..b984491 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -1,6 +1,6 @@
-use std::{sync::Arc, thread::JoinHandle, time::Instant};
+use std::{sync::Arc, thread::JoinHandle};
 
-use egui::mutex::Mutex;
+use egui::{mutex::Mutex, Color32, Frame, Rounding, SelectableLabel};
 use midir::{MidiInput, MidiInputPort};
 
 /// Launches the UI and runs it until it's done executing.
@@ -16,7 +16,6 @@ pub fn run() {
 }
 
 struct MidiKeysApp {
-    previous_frame_time: Instant,
     midi_input_ports: Arc<Mutex<Vec<MidiInputPort>>>,
     midi_in: MidiInput,
 }
@@ -32,9 +31,7 @@ impl MidiKeysApp {
         // TODO: have a way to shut down the midi daemon?
         let _ = launch_midi_daemon(midi_input_ports.clone());
 
-        let previous_frame_time = Instant::now();
         MidiKeysApp {
-            previous_frame_time,
             midi_input_ports,
             midi_in,
         }
@@ -43,22 +40,53 @@ impl MidiKeysApp {
 
 impl eframe::App for MidiKeysApp {
     fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
-        let duration = self.previous_frame_time.elapsed().as_secs_f32();
-        self.previous_frame_time = Instant::now();
+        ctx.set_theme(egui::Theme::Light);
 
-        egui::CentralPanel::default().show(ctx, |ui| {
-            ui.heading("Hello world");
+        let ports = self.midi_input_ports.lock().clone();
 
-            let framerate = format!("{:>8.2}", 1. / duration);
-            ui.label(framerate);
+        egui::TopBottomPanel::top("menu_bar_panel").show(ctx, |ui| {
+            egui::menu::bar(ui, |ui| {
+                ui.menu_button("File", |ui| {
+                    if ui.button("Quit").clicked() {
+                        ctx.send_viewport_cmd(egui::ViewportCommand::Close);
+                    }
+                });
+                ui.menu_button("Help", |ui| {
+                    if ui.button("About").clicked() {
+                        // TODO: implement something
+                    }
+                });
+            });
+        });
 
-            for input_port in self.midi_input_ports.lock().iter() {
+        egui::SidePanel::left("instrument_panel").show(ctx, |ui| {
+            ui.heading("Connections");
+
+            for (idx, port) in ports.iter().enumerate() {
                 let port_name = self
                     .midi_in
-                    .port_name(input_port)
+                    .port_name(port)
                     .unwrap_or("unknown".to_string());
 
-                ui.label(port_name);
+                ui.add(SelectableLabel::new(idx == 0, port_name));
+            }
+        });
+
+        egui::CentralPanel::default().show(ctx, |ui| {
+            for port in ports.iter() {
+                let mut frame = Frame::default()
+                    .inner_margin(4.0)
+                    .stroke((1.0, Color32::BLACK))
+                    .rounding(Rounding::same(2.0))
+                    .begin(ui);
+
+                let port_name = self
+                    .midi_in
+                    .port_name(port)
+                    .unwrap_or("unknown".to_string());
+                frame.content_ui.label(port_name);
+
+                frame.end(ui);
             }
         });
     }