Improve device panel
This commit is contained in:
parent
b4625849f1
commit
0c4e217fa7
7 changed files with 103 additions and 53 deletions
|
@ -4,9 +4,15 @@ use crate::color_hex_utils::*;
|
|||
use crate::device::Device;
|
||||
use crate::editor_state::GraphEditorState;
|
||||
use crate::graph_node_ui::*;
|
||||
use crate::node_finder::NodeFinder;
|
||||
use crate::node_finder::{NodeFinder, SelectedDevice};
|
||||
use crate::virtual_device::VirtualDevice;
|
||||
|
||||
pub fn draw_graph_editor(ctx: &CtxRef, state: &mut GraphEditorState, devices: &[Device]) {
|
||||
pub fn draw_graph_editor(
|
||||
ctx: &CtxRef,
|
||||
state: &mut GraphEditorState,
|
||||
devices: &[Device],
|
||||
virtual_device: &mut Option<VirtualDevice>,
|
||||
) {
|
||||
let mouse = &ctx.input().pointer;
|
||||
let cursor_pos = mouse.hover_pos().unwrap_or(Pos2::ZERO);
|
||||
|
||||
|
@ -49,12 +55,17 @@ pub fn draw_graph_editor(ctx: &CtxRef, state: &mut GraphEditorState, devices: &[
|
|||
node_finder_area = node_finder_area.current_pos(pos);
|
||||
}
|
||||
node_finder_area.show(ctx, |ui| {
|
||||
if let Some(node_device) = node_finder.show(devices, ui) {
|
||||
if let Some(node_device) = node_finder.show(devices, virtual_device.is_none(), ui) {
|
||||
let new_node = state.graph.add_node(node_device.to_descriptor());
|
||||
state
|
||||
.node_positions
|
||||
.insert(new_node, cursor_pos - state.pan_zoom.pan);
|
||||
should_close_node_finder = true;
|
||||
|
||||
if let SelectedDevice::Virtual(mut virt) = node_device {
|
||||
virt.connect_id(new_node);
|
||||
*virtual_device = Some(virt);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -115,6 +126,12 @@ pub fn draw_graph_editor(ctx: &CtxRef, state: &mut GraphEditorState, devices: &[
|
|||
state.run_side_effect = Some(node_id);
|
||||
}
|
||||
DrawGraphNodeResponse::DeleteNode(node_id) => {
|
||||
if let Some(virt) = virtual_device {
|
||||
if node_id == virt.node_id() {
|
||||
*virtual_device = None;
|
||||
}
|
||||
}
|
||||
|
||||
state.graph.remove_node(node_id);
|
||||
state.node_positions.remove(&node_id);
|
||||
// Make sure to not leave references to old nodes hanging
|
||||
|
|
|
@ -159,10 +159,4 @@ impl Node {
|
|||
.map(|x| x.1)
|
||||
.ok_or_else(|| anyhow!("Node {:?} has no parameter named {}", self.id, name))
|
||||
}
|
||||
|
||||
// Can this node be enabled on the UI? I.e. does it output a mesh?
|
||||
// pub fn can_be_enabled(&self, graph: &Graph) -> bool {
|
||||
// self.outputs(graph)
|
||||
// .any(|output| output.typ == DataType::Mesh)
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -114,34 +114,12 @@ impl<'a> GraphNodeWidget<'a> {
|
|||
}
|
||||
|
||||
let outputs = graph[node_id].outputs.clone();
|
||||
for (param_name, _param) in outputs {
|
||||
for (param_name, param) in outputs {
|
||||
let height_before = ui.min_rect().bottom();
|
||||
ui.label(¶m_name);
|
||||
graph.output(param).value_widget(¶m_name, ui);
|
||||
let height_after = ui.min_rect().bottom();
|
||||
output_port_heights.push((height_before + height_after) / 2.0);
|
||||
}
|
||||
|
||||
// // Button row
|
||||
// ui.horizontal(|ui| {
|
||||
// // Show 'Enable' button for nodes that output a mesh
|
||||
// if graph[node_id].can_be_enabled(graph) {
|
||||
// ui.horizontal(|ui| {
|
||||
// if !active {
|
||||
// if ui.button("👁 Set active").clicked() {
|
||||
// response = Some(DrawGraphNodeResponse::SetActiveNode(node_id));
|
||||
// }
|
||||
// } else {
|
||||
// let button = egui::Button::new(
|
||||
// RichText::new("👁 Active").color(egui::Color32::BLACK),
|
||||
// )
|
||||
// .fill(egui::Color32::GOLD);
|
||||
// if ui.add(button).clicked() {
|
||||
// response = Some(DrawGraphNodeResponse::ClearActiveNode);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// })
|
||||
});
|
||||
|
||||
// Second pass, iterate again to draw the ports. This happens outside
|
||||
|
@ -162,6 +140,7 @@ impl<'a> GraphNodeWidget<'a> {
|
|||
port_locations: &mut PortLocations,
|
||||
ongoing_drag: Option<(NodeId, ID)>,
|
||||
is_connected_input: bool,
|
||||
color: Color32,
|
||||
) {
|
||||
let port_rect = Rect::from_center_size(port_pos, egui::vec2(10.0, 10.0));
|
||||
|
||||
|
@ -175,7 +154,7 @@ impl<'a> GraphNodeWidget<'a> {
|
|||
let port_color = if resp.hovered() {
|
||||
Color32::WHITE
|
||||
} else {
|
||||
color_from_hex("#4b7f52").unwrap()
|
||||
color
|
||||
};
|
||||
ui.painter()
|
||||
.circle(port_rect.center(), 5.0, port_color, Stroke::none());
|
||||
|
@ -222,6 +201,7 @@ impl<'a> GraphNodeWidget<'a> {
|
|||
port_locations,
|
||||
ongoing_drag,
|
||||
graph.connection(*param).is_some(),
|
||||
color_from_hex("#4b7f52").unwrap(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -243,6 +223,7 @@ impl<'a> GraphNodeWidget<'a> {
|
|||
port_locations,
|
||||
ongoing_drag,
|
||||
false,
|
||||
color_from_hex("#cd131f").unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
17
src/main.rs
17
src/main.rs
|
@ -12,20 +12,24 @@ mod id_types;
|
|||
mod index_impls;
|
||||
mod node_finder;
|
||||
mod param_ui;
|
||||
mod virtual_device;
|
||||
|
||||
use device::Device;
|
||||
use virtual_device::VirtualDevice;
|
||||
|
||||
#[derive(Default)]
|
||||
struct App {
|
||||
pub state: GraphEditorState,
|
||||
pub devices: Vec<Device>,
|
||||
state: GraphEditorState,
|
||||
devices: Vec<Device>,
|
||||
virtual_device: Option<VirtualDevice>,
|
||||
}
|
||||
|
||||
impl App {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
state: GraphEditorState::default(),
|
||||
devices: dbg!(Device::query()),
|
||||
devices: Device::query(),
|
||||
virtual_device: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +37,12 @@ impl App {
|
|||
impl epi::App for App {
|
||||
fn update(&mut self, ctx: &egui::CtxRef, _frame: &epi::Frame) {
|
||||
egui::CentralPanel::default().show(ctx, |_| {
|
||||
graph_editor_egui::draw_graph_editor(&ctx, &mut self.state, &self.devices);
|
||||
graph_editor_egui::draw_graph_editor(
|
||||
&ctx,
|
||||
&mut self.state,
|
||||
&self.devices,
|
||||
&mut self.virtual_device,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,22 @@ use egui::*;
|
|||
|
||||
use crate::color_hex_utils::*;
|
||||
use crate::device::Device;
|
||||
use crate::graph_types::NodeDescriptor;
|
||||
use crate::virtual_device::VirtualDevice;
|
||||
|
||||
pub enum SelectedDevice<'a> {
|
||||
Virtual(VirtualDevice),
|
||||
Physical(&'a Device),
|
||||
}
|
||||
|
||||
impl<'a> SelectedDevice<'a> {
|
||||
pub fn to_descriptor(&self) -> NodeDescriptor {
|
||||
match self {
|
||||
SelectedDevice::Virtual(dev) => dev.to_descriptor(),
|
||||
SelectedDevice::Physical(dev) => dev.to_descriptor(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct NodeFinder {
|
||||
|
@ -23,7 +39,12 @@ impl NodeFinder {
|
|||
/// Shows the node selector panel with a search bar. Returns whether a node
|
||||
/// archetype was selected and, in that case, the finder should be hidden on
|
||||
/// the next frame.
|
||||
pub fn show<'a>(&mut self, devices: &'a [Device], ui: &mut Ui) -> Option<&'a Device> {
|
||||
pub fn show<'a>(
|
||||
&mut self,
|
||||
devices: &'a [Device],
|
||||
allow_virt_dev: bool,
|
||||
ui: &mut Ui,
|
||||
) -> Option<SelectedDevice<'a>> {
|
||||
let background_color = color_from_hex("#3f3f3f").unwrap();
|
||||
let _titlebar_color = background_color.linear_multiply(0.8);
|
||||
let text_color = color_from_hex("#fefefe").unwrap();
|
||||
|
@ -38,24 +59,20 @@ impl NodeFinder {
|
|||
let mut submitted_device = None;
|
||||
frame.show(ui, |ui| {
|
||||
ui.vertical(|ui| {
|
||||
let resp = ui.text_edit_singleline(&mut self.query);
|
||||
if self.just_spawned {
|
||||
resp.request_focus();
|
||||
self.just_spawned = false;
|
||||
}
|
||||
|
||||
let mut query_submit = resp.lost_focus() && ui.input().key_down(Key::Enter);
|
||||
|
||||
Frame::default().margin(vec2(10.0, 10.0)).show(ui, |ui| {
|
||||
if allow_virt_dev {
|
||||
if ui.selectable_label(false, "New Virtual Device").clicked() {
|
||||
submitted_device = Some(SelectedDevice::Virtual(VirtualDevice::new(
|
||||
"New Virtual Device",
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
for device in devices {
|
||||
let device_name = device.name();
|
||||
if device_name.contains(self.query.as_str()) {
|
||||
if query_submit {
|
||||
submitted_device = Some(device);
|
||||
query_submit = false;
|
||||
}
|
||||
if ui.selectable_label(false, device_name).clicked() {
|
||||
submitted_device = Some(device);
|
||||
submitted_device = Some(SelectedDevice::Physical(device));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ impl Param {
|
|||
ui.label(name);
|
||||
}
|
||||
Descriptor::Button => {
|
||||
ui.label(name);
|
||||
ui.horizontal(|ui| ui.centered_and_justified(|ui| ui.label(name)));
|
||||
}
|
||||
Descriptor::Slider { min, max } => {
|
||||
ui.horizontal(|ui| {
|
||||
|
@ -20,6 +20,7 @@ impl Param {
|
|||
.text(format!("{}", 0)),
|
||||
);
|
||||
ui.label(format!("{}", max));
|
||||
ui.label(name);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
31
src/virtual_device.rs
Normal file
31
src/virtual_device.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
use crate::{graph_types::NodeDescriptor, id_types::NodeId};
|
||||
|
||||
pub struct VirtualDevice {
|
||||
name: String,
|
||||
node_id: Option<NodeId>,
|
||||
}
|
||||
|
||||
impl VirtualDevice {
|
||||
pub fn new(name: impl ToString) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
node_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn connect_id(&mut self, node_id: NodeId) {
|
||||
self.node_id = Some(node_id);
|
||||
}
|
||||
|
||||
pub fn node_id(&self) -> NodeId {
|
||||
self.node_id.unwrap()
|
||||
}
|
||||
|
||||
pub fn to_descriptor(&self) -> NodeDescriptor {
|
||||
NodeDescriptor {
|
||||
op_name: self.name.clone(),
|
||||
inputs: Vec::new(),
|
||||
outputs: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue