GPS: introduce the graph object

The graph object stores information about the graphical
representation of a gst pipeline including
the element box, the pads and the connections.
This commit is contained in:
Stéphane Cerveau 2021-11-19 17:51:06 +01:00
parent 05749a7009
commit 0851f0545b
4 changed files with 76 additions and 27 deletions

View file

@ -27,14 +27,17 @@ use std::cell::RefCell;
use std::rc::{Rc, Weak};
use std::{error, ops};
use crate::graph::{Element, Graph};
use crate::pipeline::Pipeline;
use crate::pluginlistwindow;
#[derive(Debug)]
pub struct GPSAppInner {
pub window: gtk::ApplicationWindow,
pub drawing_area: DrawingArea,
pub builder: Builder,
pipeline: Pipeline,
pub pipeline: RefCell<Pipeline>,
pub graph: RefCell<Graph>,
}
// This represents our main application window.
@ -63,12 +66,6 @@ impl GPSAppWeak {
}
}
#[derive(Debug, Clone, Default)]
struct Element {
name: String,
position: (f64, f64),
size: (f64, f64),
}
fn draw_elements(elements: &Vec<Element>, c: &Context) {
for element in elements {
c.rectangle(element.position.0, element.position.1, 80.0, 45.0);
@ -86,11 +83,13 @@ impl GPSApp {
window.set_position(WindowPosition::Center);
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,
builder,
pipeline,
pipeline: RefCell::new(pipeline),
graph: RefCell::new(Graph::default()),
}));
Ok(app)
}
@ -126,29 +125,31 @@ impl GPSApp {
}
pub fn build_ui(&self) {
let drawing_area = DrawingArea::new();
let view_port: Viewport = self
.builder
.object("drawing_area")
.expect("Couldn't get window");
let event_box = EventBox::new();
event_box.add(&drawing_area);
event_box.add(&self.drawing_area);
view_port.add(&event_box);
let elements: Rc<RefCell<Vec<Element>>> = Rc::new(RefCell::new(vec![]));
let e_clone = elements.clone();
drawing_area.connect_draw(move |w, c| {
println!("w: {} c:{} e: {:?}", w, c, e_clone);
draw_elements(&e_clone.borrow().to_vec(), c);
let app_weak = self.downgrade();
self.drawing_area.connect_draw(move |w, c| {
let app = upgrade_weak!(app_weak, gtk::Inhibit(false));
println!("w: {} c:{}", w, c);
let mut graph = app.graph.borrow_mut();
let elements = graph.elements();
draw_elements(&elements, c);
gtk::Inhibit(false)
});
let app_weak = self.downgrade();
event_box.connect_button_release_event(move |_w, evt| {
let mut elements = elements.borrow_mut();
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;
elements.push(element);
drawing_area.queue_draw();
app.add_new_element(element);
app.drawing_area.queue_draw();
gtk::Inhibit(false)
});
let window = &self.window;
@ -235,4 +236,9 @@ 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();
}
}

36
src/graph.rs Normal file
View file

@ -0,0 +1,36 @@
#[derive(Debug, Clone, Default)]
pub struct Element {
pub name: String,
pub position: (f64, f64),
pub size: (f64, f64),
}
#[derive(Debug)]
pub struct Graph {
elements: Vec<Element>,
last_x_position: u32,
}
impl Default for Graph {
fn default() -> Graph {
Graph {
elements: vec![],
last_x_position: 0,
}
}
}
impl Graph {
pub fn elements(&mut self) -> &Vec<Element> {
&self.elements
}
pub fn add_element(&mut self, element: Element) {
self.elements.push(element);
}
pub fn remove_element(&mut self, name: &str) {
let index = self.elements.iter().position(|x| x.name == name).unwrap();
self.elements.remove(index);
}
}

View file

@ -20,6 +20,7 @@
#[macro_use]
mod macros;
mod app;
mod graph;
mod pipeline;
mod pluginlistwindow;

View file

@ -1,4 +1,5 @@
use crate::app::GPSApp;
use crate::graph::Element;
use crate::pipeline::ElementInfo;
use gtk::{
glib::{self, clone},
@ -75,7 +76,9 @@ pub fn build_plugin_list(app: &GPSApp, elements: &Vec<ElementInfo>) {
// The closure responds to selection changes by connection to "::cursor-changed" signal,
// that gets emitted when the cursor moves (focus changes).
let app_weak = app.downgrade();
tree.connect_cursor_changed(clone!(@weak dialog => move |tree_view| {
let app = upgrade_weak!(app_weak);
let selection = tree_view.selection();
if let Some((model, iter)) = selection.selected() {
// Now getting back the values from the row corresponding to the
@ -93,18 +96,21 @@ pub fn build_plugin_list(app: &GPSApp, elements: &Vec<ElementInfo>) {
.get::<u32>()
.expect("Treeview selection, column 0"),
));
println!(
"{}",
model
.value(&iter, 1)
.get::<String>()
.expect("Treeview selection, column 1")
);
let element = Element {
name: model
.value(&iter, 1)
.get::<String>()
.expect("Treeview selection, column 1"),
position: (100.0,100.0),
size: (100.0,100.0),
};
let element_name = model
.value(&iter, 1)
.get::<String>()
.expect("Treeview selection, column 1");
app.add_new_element(element);
//dialog.close();
println!("{}", element_name);
}