diff --git a/Cargo.lock b/Cargo.lock
index 2688bc2..1e3e5f8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -413,6 +413,8 @@ dependencies = [
"anyhow",
"gstreamer",
"gtk4",
+ "log",
+ "once_cell",
]
[[package]]
@@ -542,6 +544,15 @@ version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
+[[package]]
+name = "log"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+dependencies = [
+ "cfg-if",
+]
+
[[package]]
name = "memoffset"
version = "0.6.4"
diff --git a/Cargo.toml b/Cargo.toml
index 45a6a42..fa45240 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,3 +9,5 @@ edition = "2018"
gtk = { version = "0.3", package = "gtk4" }
anyhow = "1"
gstreamer = "0.16"
+log = "0.4.11"
+once_cell = "1.7.2"
\ No newline at end of file
diff --git a/TODO.md b/TODO.md
index a70b13b..9cc690a 100644
--- a/TODO.md
+++ b/TODO.md
@@ -4,12 +4,24 @@ TODO:
- [x] Create Element structure with pads and connections
- [x] Get a list of GStreamer elements in dialog add plugin
- [x] Add plugin details in the element dialog
-- [] Draw element with its pad
-- [] Be able to move the element on Screen
-- [] Create connection between element
+- [x] Draw element with its pad
+- [x] Be able to move the element on Screen
+- [x] Create connection between element
+- [] Control the connection between element
+ - [x] unable to connect in and in out and out
+ - [] unable to connnec element with incompatible caps.
+ - [x] unable to connect a port which is already connected
+- [] create contextual menu on pad or element
+- [] upclass the element
+- [] create a crate for graphview/node/port
+- [] save/load pipeline
- [] Run a pipeline with GStreamer
- [] Run the pipeline with GStreamer
- [] Control the pipeline with GStreamer
- [x] Define the license
- [] Connect the logs to the window
- [] Create a window for the video output
+
+## Code cleanup
+
+[] remove useless code from graphview
diff --git a/src/app.rs b/src/app.rs
index 5195384..02b8d6a 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -16,28 +16,27 @@
// along with this program. If not, see .
//
// SPDX-License-Identifier: GPL-3.0-only
-use gtk::cairo::Context;
use gtk::prelude::*;
use gtk::{gio, glib};
use gtk::{
- AboutDialog, Application, ApplicationWindow, Builder, Button, DrawingArea, FileChooserDialog,
- ResponseType, Statusbar, Viewport,
+ AboutDialog, Application, ApplicationWindow, Builder, Button, FileChooserDialog, ResponseType,
+ Statusbar, Viewport,
};
use std::cell::RefCell;
use std::rc::{Rc, Weak};
use std::{error, ops};
-use crate::graph::{Element, Graph};
use crate::pipeline::Pipeline;
use crate::pluginlist;
+use crate::graphmanager::{GraphView, Node};
+
#[derive(Debug)]
pub struct GPSAppInner {
pub window: gtk::ApplicationWindow,
- pub drawing_area: DrawingArea,
+ pub graphview: RefCell,
pub builder: Builder,
pub pipeline: RefCell,
- pub graph: RefCell,
}
// This represents our main application window.
@@ -66,13 +65,6 @@ impl GPSAppWeak {
}
}
-fn draw_elements(elements: &Vec, c: &Context) {
- for element in elements {
- c.rectangle(element.position.0, element.position.1, 80.0, 45.0);
- c.fill().expect("Can not draw into context");
- }
-}
-
impl GPSApp {
fn new(application: >k::Application) -> anyhow::Result> {
let glade_src = include_str!("gps.ui");
@@ -82,13 +74,11 @@ impl GPSApp {
window.set_title(Some("GstPipelineStudio"));
window.set_size_request(800, 600);
let pipeline = Pipeline::new().expect("Unable to initialize the pipeline");
- let drawing_area = DrawingArea::new();
let app = GPSApp(Rc::new(GPSAppInner {
window,
- drawing_area,
+ graphview: RefCell::new(GraphView::new()),
builder,
pipeline: RefCell::new(pipeline),
- graph: RefCell::new(Graph::default()),
}));
Ok(app)
}
@@ -125,36 +115,15 @@ impl GPSApp {
}
pub fn build_ui(&self, application: &Application) {
- let app_weak = self.downgrade();
- let drawing_area = gtk::DrawingArea::builder()
- .content_height(24)
- .content_width(24)
- .build();
+ //let app_weak = self.downgrade();
- drawing_area.set_draw_func(move |_, c, width, height| {
- let app = upgrade_weak!(app_weak);
- println!("w: {} h: {} c:{}", width, height, c);
- let mut graph = app.graph.borrow_mut();
- let elements = graph.elements();
- draw_elements(&elements, c);
- c.paint().expect("Invalid cairo surface state");
- });
let drawing_area_window: Viewport = self
.builder
.object("drawing_area")
.expect("Couldn't get window");
- drawing_area_window.set_child(Some(&drawing_area));
- // let app_weak = self.downgrade();
- // event_box.connect_button_release_event(move |_w, evt| {
- // let app = upgrade_weak!(app_weak, gtk::Inhibit(false));
- // let mut element: Element = Default::default();
- // element.position.0 = evt.position().0;
- // element.position.1 = evt.position().1;
- // app.add_new_element(element);
- // app.drawing_area.queue_draw();
- // gtk::Inhibit(false)
- // });
+ drawing_area_window.set_child(Some(&*self.graphview.borrow()));
+
let window = &self.window;
window.show();
@@ -214,7 +183,6 @@ impl GPSApp {
.object("dialog-open-file")
.expect("Couldn't get window");
open_button.connect_clicked(glib::clone!(@weak window => move |_| {
- // entry.set_text("Clicked!");
open_dialog.connect_response(|dialog, _| dialog.close());
open_dialog.add_buttons(&[
("Open", ResponseType::Ok),
@@ -230,6 +198,50 @@ impl GPSApp {
});
open_dialog.show();
}));
+
+ // let add_button: Button = self
+ // .builder
+ // .object("button-play")
+ // .expect("Couldn't get app_button");
+ // let app_weak = self.downgrade();
+ // add_button.connect_clicked(glib::clone!(@weak window => move |_| {
+ // // entry.set_text("Clicked!");
+ // let app = upgrade_weak!(app_weak);
+
+ // }));
+ let add_button: Button = self
+ .builder
+ .object("button-stop")
+ .expect("Couldn't get app_button");
+ let app_weak = self.downgrade();
+ add_button.connect_clicked(glib::clone!(@weak window => move |_| {
+ let app = upgrade_weak!(app_weak);
+ let graph_view = app.graphview.borrow_mut();
+ graph_view.remove_all_nodes();
+ let node_id = graph_view.get_next_node_id();
+ let element_name = String::from("appsink");
+ let pads = Pipeline::get_pads(&element_name, false);
+ graph_view.add_node(node_id, Node::new(node_id, &element_name, Pipeline::get_element_type(&element_name)), pads.0, pads.1);
+ let node_id = graph_view.get_next_node_id();
+ let element_name = String::from("videotestsrc");
+ let pads = Pipeline::get_pads(&element_name, false);
+ graph_view.add_node(node_id, Node::new(node_id, &element_name, Pipeline::get_element_type(&element_name)), pads.0, pads.1);
+ let node_id = graph_view.get_next_node_id();
+ let element_name = String::from("videoconvert");
+ let pads = Pipeline::get_pads(&element_name, false);
+ graph_view.add_node(node_id, Node::new(node_id, &element_name, Pipeline::get_element_type(&element_name)), pads.0, pads.1);
+
+ }));
+ let add_button: Button = self
+ .builder
+ .object("button-clear")
+ .expect("Couldn't get app_button");
+ let app_weak = self.downgrade();
+ add_button.connect_clicked(glib::clone!(@weak window => move |_| {
+ let app = upgrade_weak!(app_weak);
+ let graph_view = app.graphview.borrow_mut();
+ graph_view.remove_all_nodes();
+ }));
}
// Downgrade to a weak reference
@@ -240,8 +252,19 @@ impl GPSApp {
// Called when the application shuts down. We drop our app struct here
fn drop(self) {}
- pub fn add_new_element(&self, element: Element) {
- self.graph.borrow_mut().add_element(element);
- self.drawing_area.queue_draw();
+ pub fn add_new_element(&self, element_name: String) {
+ let graph_view = self.graphview.borrow_mut();
+ let node_id = graph_view.next_node_id();
+ let pads = Pipeline::get_pads(&element_name, false);
+ graph_view.add_node(
+ node_id,
+ Node::new(
+ node_id,
+ &element_name,
+ Pipeline::get_element_type(&element_name),
+ ),
+ pads.0,
+ pads.1,
+ );
}
}
diff --git a/src/gps.ui b/src/gps.ui
index bbf2c64..2af55fc 100644
--- a/src/gps.ui
+++ b/src/gps.ui
@@ -133,7 +133,9 @@
-