Gui stub
This commit is contained in:
parent
988f009913
commit
adcb73594d
@ -4,7 +4,9 @@ members = [
|
||||
"app",
|
||||
"network/icmp",
|
||||
"network/abstract",
|
||||
"network/windows"
|
||||
"network/windows",
|
||||
"gui/abstract",
|
||||
"gui/egui"
|
||||
]
|
||||
|
||||
[workspace.lints]
|
||||
|
||||
@ -7,9 +7,8 @@ edition = "2024"
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
eframe = { version = "0.33.3", default-features = false, features = ["default_fonts", "glow"] }
|
||||
egui_extras = { version = "0.33.3" }
|
||||
bgtu-networks-2-network-abstract = { path = "../network/abstract" }
|
||||
bgtu-networks-2-gui-abstract = { path = "../gui/abstract" }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
bgtu-networks-2-network-windows = { path = "../network/windows" }
|
||||
@ -1,5 +1,6 @@
|
||||
use bgtu_networks_2_network_abstract::{Address, NetworkContext, NetworkScope, ServersContext};
|
||||
use bgtu_networks_2_network_windows::winsocks_scope_2_2;
|
||||
use bgtu_networks_2_gui_abstract::ServersStorage;
|
||||
|
||||
// mod data;
|
||||
|
||||
@ -43,4 +44,4 @@ impl<A: Address> ServersContext<A> for Servers2NetworkCtxTestImpl<A> {
|
||||
println!("{} err", addr.to_string())
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
10
gui/abstract/Cargo.toml
Normal file
10
gui/abstract/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "bgtu-networks-2-gui-abstract"
|
||||
version = "0.0.0"
|
||||
edition = "2024"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
bgtu-networks-2-network-abstract = { path = "../../network/abstract" }
|
||||
11
gui/abstract/src/lib.rs
Normal file
11
gui/abstract/src/lib.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use bgtu_networks_2_network_abstract::Address;
|
||||
|
||||
pub trait ServersStorage {
|
||||
type A: Address;
|
||||
|
||||
fn add_server(&mut self, addr: Self::A, memo: String);
|
||||
fn remove_server(&mut self, addr: &Self::A);
|
||||
|
||||
// type TimeIterator: Iterator<Item = Option<u128>>;
|
||||
fn iter_servers(&self) -> impl Iterator<Item = (&Self::A, &str, impl Iterator<Item = Option<u128>>)>;
|
||||
}
|
||||
13
gui/egui/Cargo.toml
Normal file
13
gui/egui/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "bgtu-networks-2-gui-egui"
|
||||
version = "0.0.0"
|
||||
edition = "2024"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
eframe = { version = "0.33.3", default-features = false, features = ["default_fonts", "glow"] }
|
||||
egui_extras = { version = "0.33.3" }
|
||||
bgtu-networks-2-gui-abstract = { path = "../abstract" }
|
||||
bgtu-networks-2-network-abstract = { path = "../../network/abstract" }
|
||||
104
gui/egui/src/lib.rs
Normal file
104
gui/egui/src/lib.rs
Normal file
@ -0,0 +1,104 @@
|
||||
use bgtu_networks_2_network_abstract::Address;
|
||||
mod plot;
|
||||
mod subwindows;
|
||||
|
||||
use crate::plot::draw_plot;
|
||||
use bgtu_networks_2_gui_abstract::ServersStorage;
|
||||
use eframe::egui::Context;
|
||||
use eframe::{App, Frame, egui};
|
||||
use egui_extras::{Column, TableBuilder};
|
||||
|
||||
pub fn run_eframe_gui<Ctx: ServersStorage>(ctx: &mut Ctx) -> eframe::Result {
|
||||
let options = eframe::NativeOptions {
|
||||
viewport: egui::ViewportBuilder::default().with_inner_size([640.0, 400.0]),
|
||||
..Default::default()
|
||||
};
|
||||
eframe::run_native(
|
||||
"ICMP status monitor",
|
||||
options,
|
||||
Box::new(|_cc| {
|
||||
Ok(Box::new(EguiApp {
|
||||
ctx,
|
||||
modal_windows: ModalWindows::Root,
|
||||
}))
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
enum ModalWindows {
|
||||
Root,
|
||||
Add,
|
||||
Edit,
|
||||
}
|
||||
|
||||
struct EguiApp<'a, Ctx> {
|
||||
ctx: &'a mut Ctx,
|
||||
modal_windows: ModalWindows,
|
||||
}
|
||||
|
||||
impl<Ctx: ServersStorage> App for EguiApp<'_, Ctx> {
|
||||
fn update(&mut self, ctx: &Context, frame: &mut Frame) {
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.add_enabled_ui(self.modal_windows == ModalWindows::Root, |ui| {
|
||||
if ui.button("Add server").clicked() {
|
||||
self.modal_windows = ModalWindows::Add
|
||||
}
|
||||
});
|
||||
|
||||
TableBuilder::new(ui)
|
||||
.striped(true) // Alternating row colors
|
||||
.resizable(true)
|
||||
.vscroll(true)
|
||||
.columns(Column::remainder(), 3)
|
||||
.header(20.0, |mut r| {
|
||||
r.col(|ui| {
|
||||
ui.label("Address");
|
||||
});
|
||||
r.col(|ui| {
|
||||
ui.label("Memo");
|
||||
});
|
||||
r.col(|ui| {
|
||||
ui.label("Graph");
|
||||
});
|
||||
})
|
||||
.body(|mut t| {
|
||||
for (addr, memo, pings) in self.ctx.iter_servers() {
|
||||
t.row(20.0, |mut r| {
|
||||
r.col(|ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.add_enabled_ui(
|
||||
self.modal_windows == ModalWindows::Root,
|
||||
|ui| {
|
||||
if ui.button("-").clicked() {
|
||||
self.modal_windows = ModalWindows::Add
|
||||
}
|
||||
},
|
||||
);
|
||||
ui.label(addr.to_string());
|
||||
});
|
||||
});
|
||||
|
||||
r.col(|ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.add(egui::Label::new(memo).wrap());
|
||||
ui.add_enabled_ui(
|
||||
self.modal_windows == ModalWindows::Root,
|
||||
|ui| {
|
||||
if ui.button("-").clicked() {
|
||||
self.modal_windows = ModalWindows::Add
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
r.col(|ui| {
|
||||
draw_plot(ui, pings);
|
||||
});
|
||||
})
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
14
gui/egui/src/plot.rs
Normal file
14
gui/egui/src/plot.rs
Normal file
@ -0,0 +1,14 @@
|
||||
use eframe::egui::{Color32, Rect, StrokeKind, Ui};
|
||||
use eframe::epaint::{Pos2, Stroke};
|
||||
|
||||
pub(crate) fn draw_plot(ui: &mut Ui, time: impl Iterator<Item = Option<u128>>) {
|
||||
let rect = ui.available_size();
|
||||
let canvas = ui.painter();
|
||||
canvas.rect(
|
||||
Rect::from_min_size(Pos2::new(0.0, 0.0), rect),
|
||||
0,
|
||||
Color32::from_rgb(255, 255, 255),
|
||||
Stroke::new(1.0, Color32::from_rgb(127, 127, 127)),
|
||||
StrokeKind::Inside
|
||||
);
|
||||
}
|
||||
39
gui/egui/src/subwindows.rs
Normal file
39
gui/egui/src/subwindows.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use eframe::egui;
|
||||
use eframe::egui::{Frame, Ui, ViewportBuilder};
|
||||
|
||||
pub fn subwindow(
|
||||
ui: &mut Ui,
|
||||
id: &str,
|
||||
title: &str,
|
||||
extra_settings: impl FnOnce(ViewportBuilder) -> ViewportBuilder,
|
||||
mut content: impl FnMut(&mut Ui),
|
||||
) -> Response {
|
||||
let id = egui::ViewportId::from_hash_of(id);
|
||||
let vb = extra_settings(ViewportBuilder::default().with_title(title));
|
||||
|
||||
let closed = ui.ctx().show_viewport_immediate(id, vb, |ui, _| {
|
||||
egui::CentralPanel::default()
|
||||
.frame(Frame::default().inner_margin(0.0))
|
||||
.show(ui, |ui| content(ui));
|
||||
|
||||
return ui.input(|i| i.viewport().close_requested());
|
||||
});
|
||||
|
||||
return Response { closed };
|
||||
}
|
||||
|
||||
pub struct Response {
|
||||
closed: bool,
|
||||
}
|
||||
|
||||
impl Response {
|
||||
pub fn close_requested(&self) -> bool {
|
||||
return self.closed;
|
||||
}
|
||||
|
||||
pub fn on_close(&self, cb: impl FnOnce()) {
|
||||
if self.closed {
|
||||
cb()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
pub trait Address: Sized + Clone {
|
||||
fn parse(raw: &str) -> Result<Self, String>;
|
||||
fn to_string(self) -> String;
|
||||
fn to_string(&self) -> String;
|
||||
}
|
||||
|
||||
pub trait NetworkContext {
|
||||
|
||||
@ -45,7 +45,7 @@ impl Address for WindowsAddressAny {
|
||||
}
|
||||
}
|
||||
|
||||
fn to_string(self) -> String {
|
||||
fn to_string(&self) -> String {
|
||||
let mut buffer = [0u16; 1024];
|
||||
let mut buf_size = buffer.len() as u32;
|
||||
unsafe {
|
||||
@ -123,7 +123,7 @@ impl Address for WindowsAddressKnown {
|
||||
}
|
||||
}
|
||||
|
||||
fn to_string(self) -> String {
|
||||
fn to_string(&self) -> String {
|
||||
return self.any.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user