Skip to content

Commit

Permalink
different layout engine
Browse files Browse the repository at this point in the history
  • Loading branch information
SeaDve committed Dec 7, 2023
1 parent 5a1e18f commit d5f9a16
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 21 deletions.
26 changes: 21 additions & 5 deletions data/resources/ui/window.ui
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,28 @@
</object>
</property>
<property name="end-child">
<object class="GtkScrolledWindow">
<property name="child">
<object class="GtkPicture" id="picture">
<property name="width-request">20</property>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow">
<property name="vexpand">True</property>
<property name="child">
<object class="GtkPicture" id="picture">
<property name="width-request">20</property>
</object>
</property>
</object>
</property>
</child>
<child>
<object class="GtkBox">
<style>
<class name="toolbar"/>
</style>
<child>
<object class="GtkDropDown" id="layout_drop_down"/>
</child>
</object>
</child>
</object>
</property>
</object>
Expand Down
64 changes: 52 additions & 12 deletions src/graphviz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,74 @@ use std::{io::Write, path::Path};

use anyhow::Result;
use async_process::Command;
use gtk::glib::{self, translate::TryFromGlib};
use tempfile::NamedTempFile;

#[derive(Debug, Clone, Copy, glib::Enum)]
#[enum_type(name = "DaggerLayout")]
pub enum Layout {
Dot,
Neato,
Twopi,
Circo,
Fdp,
// Asage,
Patchwork,
Sfdp,
}

impl TryFrom<i32> for Layout {
type Error = i32;

fn try_from(val: i32) -> Result<Self, Self::Error> {
unsafe { Self::try_from_glib(val) }
}
}

impl Layout {
fn as_arg(self) -> &'static str {
match self {
Self::Dot => "dot",
Self::Neato => "neato",
Self::Twopi => "twopi",
Self::Circo => "circo",
Self::Fdp => "fdp",
Self::Patchwork => "patchwork",
Self::Sfdp => "sfdp",
}
}
}

/// Generate a PNG from the given DOT contents.
pub async fn run_with_str(contents: &str) -> Result<Vec<u8>> {
let mut in_file = NamedTempFile::new()?;
in_file.write_all(contents.as_bytes())?;
pub async fn run_with_str(contents: &str, layout: Layout) -> Result<Vec<u8>> {
let mut input_file = NamedTempFile::new()?;
input_file.write_all(contents.as_bytes())?;

let in_path = in_file.into_temp_path();
let input_path = input_file.into_temp_path();

run(&in_path).await
run(&input_path, layout).await
}

/// Generate a PNG from the given DOT file.
pub async fn run(in_path: &Path) -> Result<Vec<u8>> {
let out_path = NamedTempFile::new()?.into_temp_path();
pub async fn run(input_path: &Path, layout: Layout) -> Result<Vec<u8>> {
let output_path = NamedTempFile::new()?.into_temp_path();

let format = "png";

let child = Command::new("dot")
.arg(input_path)
.arg("-T")
.arg("png")
.arg(in_path)
.arg(format)
.arg("-K")
.arg(layout.as_arg())
.arg("-o")
.arg(&out_path)
.arg(&output_path)
.spawn()?;

let output = child.output().await?;
tracing::debug!(?output, "Child exited");

let out_bytes = async_fs::read(&out_path).await?;
let output_bytes = async_fs::read(&output_path).await?;

Ok(out_bytes)
Ok(output_bytes)
}
31 changes: 27 additions & 4 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ use anyhow::Result;
use gettextrs::gettext;
use gtk::{
gdk, gio,
glib::{self, clone},
glib::{self, clone, closure},
};
use gtk_source::prelude::*;

use crate::{
application::Application,
config::{APP_ID, PROFILE},
graphviz,
graphviz::{self, Layout},
};

const DRAW_GRAPH_INTERVAL: Duration = Duration::from_millis(200);
const DRAW_GRAPH_INTERVAL: Duration = Duration::from_millis(100);

mod imp {
use std::cell::Cell;
Expand All @@ -29,6 +29,8 @@ mod imp {
pub(super) buffer: TemplateChild<gtk_source::Buffer>,
#[template_child]
pub(super) picture: TemplateChild<gtk::Picture>,
#[template_child]
pub(super) layout_drop_down: TemplateChild<gtk::DropDown>,

pub(super) queued_draw_graph: Cell<bool>,
}
Expand Down Expand Up @@ -74,6 +76,19 @@ mod imp {
obj.queue_draw_graph();
}));

self.layout_drop_down.set_expression(Some(
&gtk::ClosureExpression::new::<glib::GString>(
&[] as &[gtk::Expression],
closure!(|list_item: adw::EnumListItem| list_item.name()),
),
));
self.layout_drop_down
.set_model(Some(&adw::EnumListModel::new(Layout::static_type())));
self.layout_drop_down
.connect_selected_notify(clone!(@weak obj => move |_| {
obj.queue_draw_graph();
}));

glib::spawn_future_local(clone!(@weak obj => async move {
obj.start_draw_graph_loop().await;
}));
Expand Down Expand Up @@ -209,7 +224,15 @@ impl Window {
return Ok(None);
}

let png_bytes = graphviz::run_with_str(&contents).await?;
let selected_item = imp
.layout_drop_down
.selected_item()
.unwrap()
.downcast::<adw::EnumListItem>()
.unwrap();
let selected_layout = Layout::try_from(selected_item.value()).unwrap();

let png_bytes = graphviz::run_with_str(&contents, selected_layout).await?;
let texture = gdk::Texture::from_bytes(&glib::Bytes::from_owned(png_bytes))?;
Ok(Some(texture))
}
Expand Down

0 comments on commit d5f9a16

Please sign in to comment.