From ba333b928e8382e7df96bd8c567f90e1d2fc9a82 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 27 Dec 2024 13:38:08 -0500 Subject: [PATCH] Overhaul UI --- rust-learning/src/gui/model_response.rs | 61 +++++++++++++----------- rust-learning/src/gui/model_selection.rs | 35 +++++++++----- rust-learning/src/gui/prompt_input.rs | 9 ++-- rust-learning/src/gui/state.rs | 25 ++++++++-- 4 files changed, 80 insertions(+), 50 deletions(-) diff --git a/rust-learning/src/gui/model_response.rs b/rust-learning/src/gui/model_response.rs index f5ada50..36d5a11 100644 --- a/rust-learning/src/gui/model_response.rs +++ b/rust-learning/src/gui/model_response.rs @@ -5,16 +5,16 @@ use crate::groq::GROQ_CLIENT; pub struct ModelResponse { pub name: String, pub message: String, - pub status: i32, + pub tokens: i32, pub time: f32, } impl ModelResponse { - pub fn new(name: String, message: String, status: i32, time: f32) -> Self { + pub fn new(name: String, message: String, tokens: i32, time: f32) -> Self { Self { name, message, - status, + tokens, time, } } @@ -22,40 +22,43 @@ impl ModelResponse { pub async fn chat_completion(&mut self, prompt: String) { let response = GROQ_CLIENT.chat_completion(self.name.clone(), prompt).await; self.message = response.choices[0].message.content.clone(); - self.status = 200; + self.tokens = response.usage.total_tokens; self.time = response.usage.total_time; } } impl Widget for &ModelResponse { fn ui(self, ui: &mut Ui) -> Response { - egui::Frame::none() - .inner_margin(8.0) - .rounding(4.0) - .fill(egui::Color32::DARK_GRAY) - .show(ui, |ui| { - ui.label(RichText::new(&self.name).strong()); + ui.vertical(|ui| { + egui::Frame::none() + .inner_margin(8.0) + .rounding(4.0) + .fill(egui::Color32::DARK_GRAY) + .show(ui, |ui| { + ui.label(RichText::new(&self.name).strong()); - ui.horizontal(|ui| { - ui.horizontal(|ui| { - ui.label("Status:"); - ui.label(self.status.to_string()); + ui.horizontal_wrapped(|ui| { + ui.horizontal(|ui| { + ui.label("Tokens:"); + ui.label(self.tokens.to_string()); + }); + + ui.horizontal(|ui| { + ui.label("Time:"); + ui.label(self.time.to_string()); + }); }); - ui.horizontal(|ui| { - ui.label("Time:"); - ui.label(self.time.to_string()); - }); - }); - - egui::Frame::none() - .inner_margin(8.0) - .rounding(4.0) - .fill(egui::Color32::WHITE) - .show(ui, |ui| { - ui.label(egui::RichText::new(&self.message).color(egui::Color32::BLACK)); - }); - }) - .response + egui::Frame::none() + .inner_margin(8.0) + .rounding(4.0) + .fill(egui::Color32::WHITE) + .show(ui, |ui| { + ui.label( + egui::RichText::new(&self.message).color(egui::Color32::BLACK), + ); + }); + }) + }).response } } diff --git a/rust-learning/src/gui/model_selection.rs b/rust-learning/src/gui/model_selection.rs index 221f189..3d6b9c3 100644 --- a/rust-learning/src/gui/model_selection.rs +++ b/rust-learning/src/gui/model_selection.rs @@ -1,4 +1,4 @@ -use eframe::egui::{self, Response, Ui, Widget}; +use eframe::egui::{self, Response, RichText, Ui, Widget}; use super::{model_response::ModelResponse, state::AppState}; @@ -33,28 +33,37 @@ impl<'a> Widget for ModelSelection<'a> { self.app_state.selected_models.push(ModelResponse { name: model.clone(), message: "No message".to_string(), - status: 0, + tokens: 0, time: 0.0, }); } } }); + let selection_frame = egui::Frame::none() + .inner_margin(4.0) + .rounding(4.0) + .fill(egui::Color32::DARK_GRAY); + + if self.app_state.selected_models.len() == 0 { + selection_frame.show(ui, |ui| { + ui.label(RichText::new("No models selected").strong()); + }); + + return; + } + let mut model_to_remove: Option = None; for model in &self.app_state.selected_models { - egui::Frame::none() - .inner_margin(8.0) - .rounding(4.0) - .fill(egui::Color32::WHITE) - .show(ui, |ui| { - ui.horizontal(|ui| { - ui.label(model.name.clone()); - if ui.button("X").clicked() { - model_to_remove.replace(model.name.clone()); - } - }); + selection_frame.show(ui, |ui| { + ui.horizontal(|ui| { + ui.label(RichText::new(model.name.clone()).strong()); + if ui.button("X").clicked() { + model_to_remove.replace(model.name.clone()); + } }); + }); } if let Some(model) = model_to_remove { diff --git a/rust-learning/src/gui/prompt_input.rs b/rust-learning/src/gui/prompt_input.rs index 9a99365..7204c8e 100644 --- a/rust-learning/src/gui/prompt_input.rs +++ b/rust-learning/src/gui/prompt_input.rs @@ -1,4 +1,4 @@ -use eframe::egui::{Response, Ui, Widget}; +use eframe::egui::{Response, TextEdit, Ui, Vec2, Widget}; use super::state::AppState; @@ -15,8 +15,11 @@ impl<'a> PromptInput<'a> { impl<'a> Widget for PromptInput<'a> { fn ui(self, ui: &mut Ui) -> Response { let label = ui.label("Prompt:"); - ui.text_edit_multiline(&mut self.app_state.prompt_input) - .labelled_by(label.id); + ui.add_sized( + Vec2::new(ui.available_width(), 100.0), + TextEdit::multiline(&mut self.app_state.prompt_input), + ) + .labelled_by(label.id); ui.horizontal(|ui| { if ui.button("Submit").clicked() { diff --git a/rust-learning/src/gui/state.rs b/rust-learning/src/gui/state.rs index 8cf4157..c32aea3 100644 --- a/rust-learning/src/gui/state.rs +++ b/rust-learning/src/gui/state.rs @@ -1,4 +1,7 @@ -use eframe::{egui, CreationContext}; +use eframe::{ + egui::{self, Layout, Separator}, + CreationContext, +}; use super::{model_response::ModelResponse, model_selection, prompt_input}; @@ -38,10 +41,22 @@ impl eframe::App for AppState { ui.add(prompt_input::PromptInput::new(self)); - ui.horizontal(|ui| { - for model in &self.selected_models { - ui.vertical(|ui| ui.add(model)); - } + ui.add(Separator::default().spacing(16.0)); + + let size = ui.available_size_before_wrap(); + let widget_size = egui::Vec2 { + x: size.x / 4.0, + y: size.y, + }; + + ui.allocate_ui_with_layout(size, Layout::left_to_right(egui::Align::Min), |ui| { + egui::ScrollArea::both().show(ui, |ui| { + ui.horizontal_top(|ui| { + for model in &self.selected_models { + ui.add_sized(widget_size, model); + } + }); + }); }); }); }