Improve title bar

This commit is contained in:
Michael Mikovsky
2025-11-29 16:38:12 -07:00
parent c83e2f1527
commit f85a0c0295
8 changed files with 80 additions and 30 deletions
+6 -1
View File
@@ -1,7 +1,10 @@
use egui::Frame;
use egui_tiles::Tree;
use crate::app::{AppState, windows::WindowWrapper};
use crate::{
FORCE_REDRAW_DELAY,
app::{AppState, windows::WindowWrapper},
};
/// We derive Deserialize/Serialize so we can persist app state on shutdown.
#[derive(serde::Deserialize, serde::Serialize)]
@@ -83,5 +86,7 @@ impl eframe::App for TemplateApp {
.frame(Frame::central_panel(&ctx.style()).inner_margin(0))
.show(ctx, |ui| self.tree.ui(&mut self.state, ui));
}
ctx.request_repaint_after(FORCE_REDRAW_DELAY);
}
}
+15 -2
View File
@@ -19,7 +19,7 @@ pub struct AppState {
impl AppState {
pub fn labels(&mut self, tree: &mut Tree<WindowWrapper>, ui: &mut egui::Ui) {
for (i, (key, name)) in (vec![
for (_, (key, name)) in (vec![
(AppWindow::Flowchart, "Flowchart"),
(AppWindow::Config, "Config"),
])
@@ -38,7 +38,7 @@ impl AppState {
// if self.open_windows.is_empty()
} else {
let tid = tree.tiles.insert_pane(WindowWrapper {
nr: i + 1,
name: name.to_string(),
window: *key,
});
@@ -78,4 +78,17 @@ impl AppWindow {
AppWindow::Config => state.config.update(&mut state.auth, ui),
}
}
fn render_title_buttons(&self, state: &mut AppState, ui: &mut egui::Ui) {
match self {
AppWindow::Flowchart => {
if ui.button("Arrange").clicked() {
state.flowchart.arrange();
}
}
_ => {
ui.label("");
}
}
}
}
+36 -13
View File
@@ -1,14 +1,16 @@
use egui::Rect;
use crate::app::{AppState, AppWindow};
#[derive(serde::Deserialize, serde::Serialize)]
pub struct WindowWrapper {
pub nr: usize,
pub name: String,
pub window: AppWindow,
}
impl egui_tiles::Behavior<WindowWrapper> for AppState {
fn tab_title_for_pane(&mut self, pane: &WindowWrapper) -> egui::WidgetText {
format!("Pane {}", pane.nr).into()
format!("{}", pane.name).into()
}
fn pane_ui(
@@ -19,28 +21,49 @@ impl egui_tiles::Behavior<WindowWrapper> for AppState {
) -> egui_tiles::UiResponse {
let mut ret = egui_tiles::UiResponse::None;
let mut rect = Rect::NOTHING;
ui.horizontal(|ui| {
let titlebar = ui.interact(
ui.max_rect(),
ui.id().with(&format!("Pane_{}_sense", pane.nr)),
rect = ui.max_rect();
let bg_color = ui.style().visuals.extreme_bg_color;
ui.painter().rect_filled(rect, 0.0, bg_color);
ui.vertical_centered(|ui| {
ui.label(&pane.name);
});
});
let mut open_space = Rect::NOTHING;
#[allow(deprecated)]
ui.allocate_ui_at_rect(rect, |ui| {
ui.horizontal(|ui| {
pane.window.render_title_buttons(self, ui);
open_space = ui.available_rect_before_wrap();
})
});
let drag_sense = ui.interact(
open_space,
ui.id().with(&format!("Pane_{}_sense", pane.name)),
egui::Sense::drag(),
);
if titlebar.drag_started() {
if drag_sense.drag_started() {
ret = egui_tiles::UiResponse::DragStarted;
}
if titlebar.hovered() {
if drag_sense.hovered() {
ui.ctx().set_cursor_icon(egui::CursorIcon::Grab);
}
let color = egui::epaint::Hsva::new(0.103 * pane.nr as f32, 0.5, 0.5, 1.0);
ui.painter().rect_filled(ui.max_rect(), 0.0, color);
ui.label("Test");
});
pane.window.update(self, ui);
ret
}
fn tab_bar_color(&self, visuals: &egui::Visuals) -> egui::Color32 {
visuals.panel_fill // same as the tab contents
}
}
+2 -4
View File
@@ -1,8 +1,6 @@
use serde_json::json;
use std::{collections::HashMap, sync::Arc, time::Duration};
use chrono::Utc;
use egui::{Align2, Area, Frame, Order, Sense, UiKind, Vec2, mutex::Mutex};
use serde_json::json;
use std::sync::Arc;
use wasm_bindgen::prelude::Closure;
#[derive(serde::Deserialize, serde::Serialize)]
+3 -1
View File
@@ -1,7 +1,9 @@
use crate::auth::Auth;
#[derive(Default, serde::Deserialize, serde::Serialize)]
pub struct Config {}
pub struct Config {
response_text: String,
}
impl Config {
pub fn update(&mut self, auth: &mut Auth, ui: &mut egui::Ui) {
+9 -6
View File
@@ -2,6 +2,8 @@ use egui::{Color32, Painter, Pos2, Rect, Scene, Shape, Ui};
use crate::flowchart::CONNECTION_STROKE;
use crate::flowchart::GROUP_BORDER_MARGIN;
use crate::flowchart::ITERATIONS;
use crate::flowchart::RESOLUTION;
use crate::flowchart::container::DraggableContainer;
use crate::flowchart::group::convex_hull;
use crate::flowchart::{BG_STROKE, TARGET_LINE_GAP};
@@ -34,12 +36,19 @@ impl Default for FlowChart {
};
this.arrange_circle();
this.arrange();
this
}
}
impl FlowChart {
pub fn arrange(&mut self) {
for _ in 0..ITERATIONS {
self.force(RESOLUTION);
}
}
fn paint_bg(rect: &Rect, painter: &Painter) {
let h_start = (rect.min.x / TARGET_LINE_GAP).round() as i32;
let h_end = ((rect.min.x + rect.width()) / TARGET_LINE_GAP).round() as i32 + 1;
@@ -93,12 +102,6 @@ impl FlowChart {
}
pub fn paint(&mut self, ui: &mut Ui) {
if ui.button("Arrange").clicked() {
for _ in 0..1_000 {
self.force(0.1);
}
}
let scene = Scene::new()
// .max_inner_size([350.0, 1000.0])
.zoom_range(0.1..=2.0);
+3
View File
@@ -6,6 +6,9 @@ mod group;
use egui::{Color32, Stroke};
pub use flowchart::FlowChart;
const ITERATIONS: usize = 1_000;
const RESOLUTION: f32 = 0.6;
const TARGET_LINE_GAP: f32 = 80.;
const BG_STROKE: Stroke = Stroke {
+3
View File
@@ -8,6 +8,9 @@ mod auth;
mod config;
mod flowchart;
use std::time::Duration;
const FORCE_REDRAW_DELAY: Duration = Duration::from_millis(300);
// mod JsFunc {
// use wasm_bindgen::JsValue;
use wasm_bindgen::prelude::*;