A Quark or a Plug-in visualising SynthDef

I finally found a way to make scDot work in Windows. Using it on Mac and Linux is now easier!
Please have a look at the following video:
https://www.dropbox.com/scl/fi/4oa5j370danjkunreeusq/Dot-simple.mov?rlkey=msvrr3bzp97icrto0zsdq08b6&dl=0

This is available after revising some method definitions for the Dot class as follows (I just added some preliminary code to skip some steps and added the correct implementation for Windows… It would be great if you could reflect this! I currently only use github… Or I can submit a PR and ask for a merge…):

Dot {

	classvar <>directory, <>dotCmd, <>dotViewer, <>svgViewer, <>pdfViewer, <>renderMode, <>drawInputName, <>useSplines, <>useTables, <>fontSize, <>fontName, <>fixEdgeLocation, <>verbose, <>truncateInputsAt;

	*defaultSettings {
		directory = Platform.defaultTempDir;
		dotCmd = "dot";
		dotViewer = nil;
		svgViewer = nil;
		pdfViewer = nil;
		renderMode = 'dot'; // dot | svg | pdf | hsc3
		drawInputName = false;
		useSplines = false;
		useTables = true;
		fontSize = 10;
		fontName = "Helvetica";
		fixEdgeLocation = false;
		verbose = false;
		truncateInputsAt = 32
	}

	*initClass {
		this.defaultSettings
	}

	*baseFileNameFor { | synthDef |
		^directory.standardizePath +/+ synthDef.name.asString;
	}

	*fileNameForWithExtension { | synthDef extension |
		^Dot.baseFileNameFor(synthDef) ++ extension;
	}

	*asyncCmd { | message command |
		verbose.if {
			["asyncCmd", message, command].postln
		};
		command.unixCmd // asynchronous
	}

	*syncCmd { | message command |
		verbose.if {
			["syncCmd", message, command].postln
		};
		command.systemCmd // synchronous
	}

	*viewDotFile { | fileName |
		var viewerDefault = (osx: "open", linux: "dot -Txlib", windows: "start" + "".quote + dotCmd.quote);
		var viewer = dotViewer ? viewerDefault.at(thisProcess.platform.name);
		var command = if(thisProcess.platform.asString != "a WindowsPlatform") {
			"% %".format(viewer, fileName.shellQuote)
		} {
			"% %".format(viewer, fileName)
		};
		Dot.asyncCmd("viewDotFile", command)
	}

	*viewDotFileFor { | synthDef |
		Dot.viewDotFile(Dot.fileNameForWithExtension(synthDef, ".dot"))
	}

	*dotFileToSvgFileFor { | synthDef |
		var dotFileName = Dot.fileNameForWithExtension(synthDef, ".dot");
		var svgFileName = Dot.fileNameForWithExtension(synthDef, ".svg");
		var command = if(thisProcess.platform.asString != "a WindowsPlatform") {
			"% -Tsvg % -o %".format(dotCmd, dotFileName.shellQuote, svgFileName.shellQuote)
		} {
			"% -Tsvg % -o %".format(dotCmd, dotFileName, svgFileName)
		};
		Dot.syncCmd("dotFileToSvgFileFor", command)
	}

	*viewSvgFileFor { | synthDef |
		svgViewer.notNil.if {
			var command = "% %".format(svgViewer, Dot.fileNameForWithExtension(synthDef, ".svg").shellQuote);
			Dot.asyncCmd("viewSvgFileFor", command)
		} {
			var image = Image.openSVG(Dot.fileNameForWithExtension(synthDef, ".svg"));
			var window = Window.new(synthDef.name.asString, Rect(100, 100, image.bounds.width, image.bounds.height), false, true, nil, false);
			window.onClose_ {
				image.free
			};
			window.view.setBackgroundImage(image, 1, 1, nil);
			window.view.fixedSize_(Size.new(width: image.width, height: image.height));
			window.front
		}
	}

	*dotFileToPdfFileFor { | synthDef |
		var dotFileName = Dot.fileNameForWithExtension(synthDef, ".dot");
		var pdfFileName = Dot.fileNameForWithExtension(synthDef, ".pdf");
		var command = if(thisProcess.platform.asString != "a WindowsPlatform") {
			"% -Tpdf % -o %".format(dotCmd, dotFileName.shellQuote, pdfFileName.shellQuote)
		} {
			"% -Tpdf % -o %".format(dotCmd, dotFileName, pdfFileName)
		};
		Dot.syncCmd("dotFileToPdfFileFor", command)
	}

	*viewPdfFileFor { | synthDef |
		var viewerDefault = (osx: "open", linux: "xdg-open", windows: "start" + "".quote + "C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe".quote);
		var viewer = pdfViewer ? viewerDefault.at(thisProcess.platform.name);
		var command = if(thisProcess.platform.asString != "a WindowsPlatform") {
			"% %".format(viewer, Dot.fileNameForWithExtension(synthDef, ".pdf").shellQuote)
		} {
			"% %".format(viewer, Dot.fileNameForWithExtension(synthDef, ".pdf"))
		};
		Dot.asyncCmd("viewPdfFileFor", command)
	}

	*drawHsc3 { | synthDef |
		var command = if(thisProcess.platform.asString != "a WindowsPlatform") {
			"hsc3-dot scsyndef-draw %".format(Dot.fileNameForWithExtension(synthDef, ".scsyndef").shellQuote)
		} {
			"hsc3-dot scsyndef-draw %".format(Dot.fileNameForWithExtension(synthDef, ".scsyndef"))
		};
		synthDef.writeDefFile(directory.standardizePath,true);
		Dot.asyncCmd("drawHsc3", command)
	}

	*writeDotFileFor { | synthDef |
		var file = File(Dot.fileNameForWithExtension(synthDef, ".dot"), "w");
		synthDef.dot(file);
		file.close
	}

	*draw { | synthDef |
		renderMode.switch(
			'hsc3', {
			    Dot.drawHsc3(synthDef)
			},
			'dot', {
			    Dot.writeDotFileFor(synthDef);
			    Dot.viewDotFileFor(synthDef)
			},
			'svg', {
			    Dot.writeDotFileFor(synthDef);
			    Dot.dotFileToSvgFileFor(synthDef);
			    Dot.viewSvgFileFor(synthDef)
			},
			'pdf', {
			    Dot.writeDotFileFor(synthDef);
			    Dot.dotFileToPdfFileFor(synthDef);
			    Dot.viewPdfFileFor(synthDef)
			},
			{
				"Dot.draw: unknown renderMode".error
			}
		)
	}

}
1 Like