I mentioned this on the list a little while back in a discussion on Shiny, 
and now it is finally up and available.

https://github.com/TheGrum/renderview

So... what is it? RenderView is a simple GUI wrapper that makes it easy to 
wrap any image generation function and make it interactive. 

It is NOT a replacement for writing full graphical interfaces. This is not 
for front-end developers, this is for the more general Go crowd, the people 
writing back-end code, micro-services, web services, composable 
applications and the like, who don't *want* to have to learn the 
nitty-gritty of a particular graphical toolkit, but would like to be able 
to have a rapid-turnaround way to test/view the graphical outputs of their 
work.

My own intention in writing this came after writing a tool to parse some 
log files, and another to render them as visualizations saved as PNGs, 
produced several gigabytes of data. I want to be able to peek into some of 
my algorithms as they are running, to confirm their behavior is as desired, 
not merely their final output, but I don't want to fill up my disks to do 
it.

I've included several examples of various levels, but basically, given a 
function that produces an image.Image:

func DrawSomething(bounds image.Rect, input1 int, input2 float64, input3 
etc) image.Image {
}

RenderView asks you to provide a RenderModel that simply wraps this image 
generation function, a bag of parameters, and your code for setting up 
those parameters to feed into your drawing function, and it gives you a 
graphical application with various interactive features. Which features you 
get depends on what parameters you use, and which you pay attention to. If 
using a backend that can produce editable widgets (at the moment, this is 
only go-gtk), you can add arbitrary additional parameters to be exposed to 
the user for editing.

The Maze example provides an illustration of how simple it can be. Aside 
from the functions to generate, and to draw the maze, both of which are 
ordinary Go code, the added work is this:

func main() {
sig := ""
rand.Seed(time.Now().UnixNano())
m := rv.NewBasicRenderModel()
m.AddParameters(
rv.SetHints(rv.HINT_HIDE,
rv.NewIntRP("width", 0),
rv.NewIntRP("height", 0),
)...)
m.AddParameters(
rv.NewIntRP("page", 0),
rv.NewIntRP("linewidth", 1),
rv.NewIntRP("cellwidth", 5),
rv.NewIntRP("mazewidth", 100),
rv.NewIntRP("mazeheight", 100))
m.InnerRender = func() {
z := NewDepthFirstMaze(m.Params[5].GetValueInt(), m.Params[6].GetValueInt())
m.Img = RenderMaze(m, z)
m.RequestPaint()
}
}
driver.Main(m)
}

The mandelbrot example, specifically, is code by Sonia Keys taken from 
RosettaCode, used by permission, and shows a concrete instance where I took 
code that literally produced a single, static png, elevated a few constants 
and variables to parameters, had it return the image instead of saving it, 
wrapped it in a simple model - the actual executable for it is in cmd/demo.

The intention is that your library or backend code could live unchanged and 
uncontaminated, while you add a cmd/gui/ folder, drop in a model and a main 
and produce a GUI that lets you exercise your code dynamically. Or, for 
that matter, your GUI could live in its own package, just importing your 
backend code, never to even visit your production environment.

If you look at this and think, you know, with just a little work you could 
do this in any language wrapped around an executable in Go that produced 
the images, well, you're right. There is no reason the frontend code has to 
be in Go. But by the same token, there is no reason the backend code has to 
be in Go either! In cmd/cmdgui, cmdgui is a utility that does just this, 
wrapping a command-line call, with parameters passed both in the 
environment, and optionally interpolated into the arguments using Go 
Templates. The examples show taking a simple Python script for quickly 
generating a function plot, and making it interactive, and using curl to 
call a webservice to make it interactive.

Give it a try with 

go get github.com/TheGrum/renderview

and let me know what you think. Have fun!


Howard C. Shaw III, the Grum

P.S. I guess I have not documented the default parameters it cares about 
yet, I should do that:

left,top,right,bottom - these can be either int or float64, and when 
available, operate panning, and if float64, zooming. - two way, you can 
change these in your code to move the viewport if you are paying attention 
to them
width,height - these get populated with the window width and height - 
changing these in your code has no effect.
options - maybe more later, right now these just control the zooming (done 
with the scroll-wheel)
const (
OPT_NONE        = iota      // 0
OPT_CENTER_ZOOM = 1 << iota // 1
OPT_AUTO_ZOOM   = 1 << iota // 2
)
zoom - int or float64, this gets incremented/decremented when the 
scroll-wheel is turned, and can be used to implement your own zoom.
mouseX, mouseY - float64, these get populated with the current mouse 
position in the window
page - this gets incremented/decremented by PgUp and PgDown when the 
graphical window has the focus, allowing for a paged environment. You can 
manipulated these from a custom zoom parameter to tie scrolling to paging 
if desired.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to