GithubHelp home page GithubHelp logo

ryo33 / egui_cable Goto Github PK

View Code? Open in Web Editor NEW
107.0 6.0 6.0 194 KB

Generic and extensible egui widgets to create analog synthesizer-like UI with data-oriented API

Rust 99.23% Shell 0.77%
egui data-flow-diagram node-based data-oriented

egui_cable's Introduction

egui_cable

GitHub MIT/Apache 2.0 Crates.io docs.rs

A generic and extensible data-oriented widget for connecting ports by cables.

I create this for the visual programming editor of Hihaheho/Desk.

It's good for:

  • analog synthesizer-like UI
  • node-based UI
  • anything you can imagine

The code is good for studying how to write egui widgets.

Features

  • connect ports by data
  • dynamic connect and disconnect
  • lock connection
  • custom plug widget
  • custom port widget
  • custom cable widget
  • multiple connections on a single port.
  • on-connect event
  • on-disconnect event
  • on-hover event
  • garbage collection
  • multi-touch support (help me)

Examples

Click the images to see the source code. See /examples for more examples.

Simple example

Connect example

egui_cable's People

Contributors

ryo33 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

egui_cable's Issues

[Question] Store state in egui UI?

Hey Ryo, nice project! I might use it in mine as well.

Quick question. Is it normal practice to store widget state in the egui::Ui?

I know that usually egui widgets are stateless and are just builders as it is stated in the doc. But I store state right in my widget (I am also creating widget for egui https://github.com/blitzarx1/egui_graphs) implementing Widget trait for &mut MyWidget. I wanted to ask why you chose to store state in the Ui, is it intended usage of the Ui, won't it affect egui performance is state is rather big.

Thanks for the answer in advance.

Basic example doesn't work in eframe template, widgets aren't recognized

Hi, I cloned the eframe starter and tried to add the widgets to it by copying the basic example into my update function

        let Self { label, value } = self;

        // Examples of how to create different panels and windows.
        // Pick whichever suits you.
        // Tip: a good default choice is to just keep the `CentralPanel`.
        // For inspiration and more examples, go to https://emilk.github.io/egui

        #[cfg(not(target_arch = "wasm32"))] // no File->Quit on web pages!
        egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
            // The top panel is often a good place for a menu bar:
            egui::menu::bar(ui, |ui| {
                ui.menu_button("File", |ui| {
                    if ui.button("Quit").clicked() {
                        _frame.close();
                    }
                });
            });
        });

        egui::CentralPanel::default().show(ctx, |ui| {
            // The central panel the region left after adding TopPanel's and SidePanel's

            ui.heading("eframe template");
            ui.hyperlink("https://github.com/emilk/eframe_template");
            ui.add(egui::github_link_file!(
                "https://github.com/emilk/eframe_template/blob/master/",
                "Source code."
            ));
            egui::warn_if_debug_build(ui);
        });
        egui::Window::new("My window")
            .default_pos(pos2(20.0, 100.0))
            .show(ctx, |ui| {
                ui.add(Port::new(0));
            });
        egui::Window::new("My window 2")
            .default_pos(pos2(200.0, 20.0))
            .show(ctx, |ui| {
                ui.add(Port::new(1));
                ui.add_space(10.0);
                ui.add(Port::new(2));
            });
        egui::Window::new("My window 3")
            .default_pos(pos2(200.0, 200.0))
            .show(ctx, |ui| {
                ui.add(Port::new(3));

                ui.add(Cable::new(0, Plug::to(0), Plug::to(1)));
                ui.add(Cable::new(1, Plug::to(0), Plug::to(3)));
                ui.add(Cable::new(2, Plug::to(2), Plug::unplugged()));
            });
    }
}

But then I get the error:

error[E0277]: expected a `FnOnce<(&mut egui::Ui,)>` closure, found `egui_cable::port::Port`
    --> src/app.rs:85:24
     |
85   |                 ui.add(Port::new(0));
     |                    --- ^^^^^^^^^^^^ expected an `FnOnce<(&mut egui::Ui,)>` closure, found `egui_cable::port::Port`
     |                    |
     |                    required by a bound introduced by this call
     |
     = help: the trait `for<'a> FnOnce<(&'a mut egui::Ui,)>` is not implemented for `egui_cable::port::Port`
     = help: the following other types implement trait `egui::Widget`:
               &eframe::epaint::PaintStats
               &mut eframe::epaint::TessellationOptions
               egui::Button
               egui::Checkbox<'a>
               egui::DragValue<'a>
               egui::Hyperlink
               egui::Image
               egui::ImageButton
             and 9 others
     = note: required for `egui_cable::port::Port` to implement `egui::Widget`
note: required by a bound in `egui::Ui::add`
    --> /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/egui-0.21.0/src/ui.rs:1055:40
     |
1055 |     pub fn add(&mut self, widget: impl Widget) -> Response {
     |                                        ^^^^^^ required by this bound in `egui::Ui::add`

I get the same error for all the egui_cable widgets.

Do you have any idea what I might've done wrong or if it is a bug?

Re-export egui

When I try to use the examples in my own code, I get an error that Port and similar types don't implement Widget. To use the Widget trait, I need to import it. I can't just import egui myself, because it has to be the same version egui_cable is using.
Unfortunately, egui isn't re-exported by egui_cable, so the Widget implementation is completely private. If egui_cable put pub use egui; in lib.rs that would solve the issue, because then I could import Widget from egui_cable::egui and have it be guaranteed to be the right version.

Possible features

Feel free to comment feature requests. I’ll add it to the following list if I think it’s needed.

  • connect ports by supplying port ids
  • connect between two any ports by drag.
  • disconnect cable by mouse
  • #4
  • lock connection
  • custom port widget
  • custom cable widget
  • custom cable data
  • multiple connections on a single port.
  • on-connect event
  • #2
  • on-hover event
  • #3
  • garbage collection

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.