vive la révolution !!
This commit is contained in:
parent
13b6effb91
commit
027af2d36e
10 changed files with 42 additions and 207 deletions
20
Cargo.toml
20
Cargo.toml
|
@ -1,19 +1,3 @@
|
||||||
[package]
|
|
||||||
name = "bent"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
license = "Unlicense"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
anyhow = "1.0"
|
|
||||||
derive-new = "0.6.0"
|
|
||||||
eframe = "0.27"
|
|
||||||
egui_dock = "0.12"
|
|
||||||
egui_extras = "0.27.2"
|
|
||||||
rfd = "0.14"
|
|
||||||
strum = { version = "0.26", features = ["derive"] }
|
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["bingus"]
|
resolver = "2"
|
||||||
|
members = ["bent", "bingus", "bong"]
|
||||||
|
|
17
bent.wsd
Normal file
17
bent.wsd
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
@startuml "bingus"
|
||||||
|
title "Project organization"
|
||||||
|
package bong
|
||||||
|
note bottom
|
||||||
|
cli bin
|
||||||
|
endnote
|
||||||
|
package bingus
|
||||||
|
note bottom
|
||||||
|
core lib
|
||||||
|
endnote
|
||||||
|
package bent
|
||||||
|
note bottom
|
||||||
|
gui bin
|
||||||
|
endnote
|
||||||
|
bong -> bingus
|
||||||
|
bingus <- bent
|
||||||
|
@enduml
|
8
bent/Cargo.toml
Normal file
8
bent/Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "bent"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
3
bent/src/main.rs
Normal file
3
bent/src/main.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
name = "bingus"
|
name = "bingus"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
license = "Unlicense"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
|
8
bong/Cargo.toml
Normal file
8
bong/Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "bong"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
3
bong/src/main.rs
Normal file
3
bong/src/main.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
47
src/app.rs
47
src/app.rs
|
@ -1,47 +0,0 @@
|
||||||
use derive_new::new;
|
|
||||||
use eframe::egui::{self, menu, CentralPanel, Frame};
|
|
||||||
use egui_dock::{DockArea, DockState};
|
|
||||||
|
|
||||||
mod tabs;
|
|
||||||
use tabs::{chefs_dish, Tab, TabViewer};
|
|
||||||
|
|
||||||
use self::tabs::TabKind;
|
|
||||||
|
|
||||||
#[derive(new)]
|
|
||||||
pub(super) struct App {
|
|
||||||
tree: DockState<Tab>,
|
|
||||||
tab_viewer: TabViewer,
|
|
||||||
open_summary: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl eframe::App for App {
|
|
||||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
|
||||||
CentralPanel::default()
|
|
||||||
.frame(Frame::central_panel(&ctx.style()))
|
|
||||||
.show(ctx, |ui| {
|
|
||||||
menu::bar(ui, |ui| {
|
|
||||||
ui.menu_button("Tabs", |ui| {
|
|
||||||
if ui.checkbox(&mut self.open_summary, "Summary").changed() {
|
|
||||||
match self.open_summary {
|
|
||||||
true => self.tree.push_to_focused_leaf(Tab::new(TabKind::Summary)),
|
|
||||||
false => {
|
|
||||||
self.tree = self
|
|
||||||
.tree
|
|
||||||
.filter_tabs(|tab| !matches!(tab.kind, TabKind::Summary))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
DockArea::new(&mut self.tree).show_inside(ui, &mut self.tab_viewer);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for App {
|
|
||||||
fn default() -> Self {
|
|
||||||
let tree = DockState::new(chefs_dish());
|
|
||||||
|
|
||||||
Self::new(tree, TabViewer::default(), false)
|
|
||||||
}
|
|
||||||
}
|
|
123
src/app/tabs.rs
123
src/app/tabs.rs
|
@ -1,123 +0,0 @@
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use derive_new::new;
|
|
||||||
use eframe::egui::{ScrollArea, Sense, TextStyle, Ui, WidgetText};
|
|
||||||
use egui_extras::{Column, Size, StripBuilder, TableBuilder};
|
|
||||||
use rfd::FileDialog;
|
|
||||||
use strum::{AsRefStr, EnumIter, IntoEnumIterator};
|
|
||||||
|
|
||||||
#[derive(Clone, AsRefStr, PartialEq, EnumIter)]
|
|
||||||
pub(super) enum TabKind {
|
|
||||||
Input,
|
|
||||||
Decode,
|
|
||||||
Process,
|
|
||||||
Encode,
|
|
||||||
Output,
|
|
||||||
Summary,
|
|
||||||
Help,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(new, Clone)]
|
|
||||||
pub(super) struct Tab {
|
|
||||||
#[allow(private_interfaces)]
|
|
||||||
pub(super) kind: TabKind,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TabKind {
|
|
||||||
fn is_optional(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
Self::Input | Self::Decode | Self::Process | Self::Encode | Self::Output => false,
|
|
||||||
_ => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Tab {
|
|
||||||
fn is_optional(&self) -> bool {
|
|
||||||
self.kind.is_optional()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn chefs_dish() -> Vec<Tab> {
|
|
||||||
TabKind::iter().take(5).map(|kind| Tab::new(kind)).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub(super) struct TabViewer {
|
|
||||||
input_files: Vec<PathBuf>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl egui_dock::TabViewer for TabViewer {
|
|
||||||
type Tab = Tab;
|
|
||||||
|
|
||||||
fn title(&mut self, tab: &mut Self::Tab) -> WidgetText {
|
|
||||||
tab.kind.as_ref().into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ui(&mut self, ui: &mut Ui, tab: &mut Self::Tab) {
|
|
||||||
ui.heading(tab.kind.as_ref());
|
|
||||||
match tab.kind {
|
|
||||||
TabKind::Input => {
|
|
||||||
let button_size = TextStyle::Button.resolve(ui.style()).size;
|
|
||||||
StripBuilder::new(ui)
|
|
||||||
.size(Size::remainder().at_least(20.0)) // for the table
|
|
||||||
.size(Size::remainder().at_most(button_size * 4.0)) // for the add and clear buttons
|
|
||||||
.vertical(|mut strip| {
|
|
||||||
strip.cell(|ui| {
|
|
||||||
ScrollArea::horizontal().show(ui, |ui| {
|
|
||||||
TableBuilder::new(ui)
|
|
||||||
.striped(true)
|
|
||||||
.sense(Sense::click())
|
|
||||||
.column(Column::remainder())
|
|
||||||
.body(|body| {
|
|
||||||
body.rows(18.0, self.input_files.len(), |mut row| {
|
|
||||||
let index = row.index();
|
|
||||||
row.col(|ui| {
|
|
||||||
ui.label(
|
|
||||||
&self
|
|
||||||
.input_files
|
|
||||||
.get(index)
|
|
||||||
.map(|buf| {
|
|
||||||
buf.to_str()
|
|
||||||
.unwrap_or("[invalid UTF-8]")
|
|
||||||
.to_string()
|
|
||||||
})
|
|
||||||
.unwrap_or("???".to_string()),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
});
|
|
||||||
});
|
|
||||||
strip.cell(|ui| {
|
|
||||||
ui.vertical_centered_justified(|ui| {
|
|
||||||
if ui.button("Clear").clicked() {
|
|
||||||
self.input_files.clear();
|
|
||||||
}
|
|
||||||
if ui.button("Add").clicked() {
|
|
||||||
if let Some(mut paths) = FileDialog::new().pick_files() {
|
|
||||||
self.input_files.append(&mut paths);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// https://github.com/emilk/egui/blob/master/examples/file_dialog/src/main.rs
|
|
||||||
}
|
|
||||||
TabKind::Decode => todo!(),
|
|
||||||
TabKind::Process => todo!(),
|
|
||||||
TabKind::Encode => todo!(),
|
|
||||||
TabKind::Output => todo!(),
|
|
||||||
TabKind::Summary => todo!(),
|
|
||||||
TabKind::Help => todo!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn allowed_in_windows(&self, tab: &mut Self::Tab) -> bool {
|
|
||||||
tab.is_optional()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn closeable(&mut self, tab: &mut Self::Tab) -> bool {
|
|
||||||
tab.is_optional()
|
|
||||||
}
|
|
||||||
}
|
|
19
src/main.rs
19
src/main.rs
|
@ -1,19 +0,0 @@
|
||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
|
||||||
use eframe::egui;
|
|
||||||
|
|
||||||
mod app;
|
|
||||||
use app::App;
|
|
||||||
|
|
||||||
fn main() -> Result<(), eframe::Error> {
|
|
||||||
let options = eframe::NativeOptions {
|
|
||||||
viewport: egui::ViewportBuilder::default()
|
|
||||||
.with_inner_size([640.0, 240.0]) // wide enough for the drag-drop overlay text
|
|
||||||
.with_drag_and_drop(true),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
eframe::run_native(
|
|
||||||
"Native file dialogs and drag-and-drop files",
|
|
||||||
options,
|
|
||||||
Box::new(|_cc| Box::<App>::default()),
|
|
||||||
)
|
|
||||||
}
|
|
Loading…
Reference in a new issue