copyright 2001 ro it systems gmbh ro it systems gmbh building an svg gui with perl ronan oger ro it...

31
Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH www.roitsystems.com Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan @ roasp . com Ronan . oger @ roitsystems . com SVG Open 2003 SVG Open 2003

Upload: ethan-carroll

Post on 26-Mar-2015

214 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Building an SVG GUIwith Perl

Ronan Oger

RO IT Systems [email protected]

[email protected]

SVG Open 2003

SVG Open 2003

Page 2: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Perl

• Freely available for download• Cross-platform• Freely available for download• Cross-platform

– Tested on Sun, Windows, Mac OSX, Cygwin, Linux, FreeBSD

– Pure-perl: designed to avoid

Page 3: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

SVG.pm

• Freely available for download under Perl Artistic License

• Installable many ways:– PPM– FreeBSD– Make– CPAN installation through Perl

• Pure-Perl: – Root access not required to implement– Cross-platform

Page 4: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Installing SVG.pm

• CPAN:Perl –MCPAN –e `install SVG‘

• Perl Package Manager (win32):PPM

PPM>Install SVG

• Make:Gunzip svg-xx.xxx.tar.gz

Tar –xvf svg-xx-xxx.tar

Make

Make test

Make install

Page 5: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

SVG.pm Features

• Free – Perl Artistic License• You get what you pay for...• You can ask for special features...

Page 6: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

SVG.Pm Usage Examples

• Hello SVG World!• Draw a line• Navigating the DOM• Tessalate• YAPH

Page 7: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Hello SVG World!

#!/usr/bin/perl -w

use strict;

use SVG;

print "Content-Type: image/svg+xml\n\n";

my $svg=new SVG();

$svg->rect(id=>'rect1',x=>'20px',y=>'55px',

width=>10,height=>10,fill=>'yellow');

my $text = $svg->text(x=>20, y=>55,

fill=>'red', stroke=>'black');

$text->cdata("Hello SVG world!");

#grab the fill element

my $fill = $svg->getElementByID('rect1')

->getAttribute('fill');

#modify the fill attribute of the text element

$text->setAttribute('fill',$fill);

print $svg->render(); #xmlify

http://www.roitsystems.com/conferences/yapc_eu/code/hello_world.txt

Page 8: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Draw a Line

#!/usr/bin/perl -w

use strict;

use SVG;

print "Content-Type: image/svg+xml\n\n";

my $svg=new SVG(width=>60, height=>45);

my $group1=$svg->group(id=>"outer_group");

my $group2=$group1->group(id=>"inner_group");

$group2->line(x1=>20, y1=>30, x2=>50, y2=>35, stroke=>"blue");

print $svg->render();

http://www.roitsystems.com/conferences/yapc_eu2003/code/01b-GroupedLine.txt

Page 9: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Navigate the DOM ...Part 1#!/usr/bin/perl –w

use strict;

use SVG;

print "Content-Type: image/svg+xml\n\n";

my $svg=new SVG(width=>60, height=>60);

my $group1=$svg->group(id=>"outer_group");

$group1->rect(x=>10, y=>10, width=>40, height=>40, fill=>"yellow");

my $group2=$group1->group(id=>"inner_group", stroke=>"blue");

$group2->line(x1=>10, y1=>30, x2=>50, y2=>40);

$group2->line(x1=>30, y1=>10, x2=>40, y2=>50);

$group2->line(x1=>10, y1=>40, x2=>40, y2=>10);

my $anchor = $group1->anchor(-href=>'http://example.net');

my $circle = $anchor->circle(cx=>30, cy=>30, r=>6, fill=>"red");

$circle->set(begin=>"mouseover", end=>"mouseout",

attributeName=>'fill', to=>'cyan');

print $svg->render(); #or xmlify or serialize

http://www.roitsystems.com/conferences/yapc_eu2003/code/01i-FirstNextIterator.txt

Page 10: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Navigate the DOM ...Part 2

iterate($svg);

sub iterate {

my ($element,$depth)=@_;

$depth=0 unless defined $depth;

my $child=$element->getFirstChild();

return unless $child;

do {

print "\t"x$depth,

"Element $child is a ",

$child->getElementName(),

"\n";

iterate($child,$depth+1) if $child->hasChildren;

} while ($child = $child->getNextSibling);

}

Page 11: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

#!/usr/bin/perl -w

use strict;

use SVG;

my $svg = SVG->new(width=>"100%", height=>"100%");

my $g = $svg->group(style=>{"fill-rule"=>"evenodd","stroke-linejoin"=>"round", "stroke-linecap"=>"round"});

my $d1 = $g->defs();

my $path = $svg->get_path(-type=>"path", x=>[0,90,60], y=>[0,60,90], -closed=>1);

my $d1g1p = $d1->group(id=>"Tess0p")->path(%$path);

my $d1g0 = $d1->group( id=>"Tess0", fill=>"rgb(255,255,0)",

stroke=>"none")->use(-href=>"#Tess0p");

Tessalate ...Part 1

http://www.roitsystems.com/conferences/yapc_eu2003/code/tessalate.txt

Page 12: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Tessalate ...Part 2

my $d1g1 = $d1->group(id=>"Tess1", fill=>"none", stroke=>"rgb(0,0,0)", "stroke-width"=>"2.413")->use(-href=>"#Tess0p");

$path = $svg->get_path(-type=>"path", x=>[15,75,50], y=>[15,50,75], -closed=>1);

my $d1g2p = $d1->group( id=>"Tess2p")->path(%$path);

my $d1g2 = $d1->group(id=>"Tess2", fill=>"rgb(255,170,255)", stroke=>"none")->use(-href=>"#Tess2p");

my $d1g3 = $d1->group( id=>"Tess3", fill=>"none", stroke=>"rgb(0,0,0)", "stroke-width"=>"2.413")->use(-href=>"#Tess2p");

my $d2p2 = $g->defs()->pattern(id=>"TessPattern", patternUnits=>"userSpaceOnUse", x=>"0", y=>"0",

width=>"100", height=>"100", viewBox=>"0 0 100 100", overflow=>"visible");

$d2p2->group()->use(-href=>"#Tess0");

$d2p2->group()->use(-href=>"#Tess1");

$d2p2->group()->use(-href=>"#Tess2");

$d2p2->group()->use(-href=>"#Tess3");

Page 13: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Tessalate ...Part 3

$svg->comment('Now let us define the polygon with the fill inside it refered to by url reference');

$svg->polygon(points=>"163.816,337.5 ".(140+rand(20)).",".(400+rand(60))." 234.868,344.079 334.868,428.289 291.447,299.342 480.921,284.868 326.974,".(160+rand(60))." 344.079,30.9211 232.237,167.763 123.026,29.6053 150.658,191.447 37.5,94.0789 ".(100+rand(10)).','.(200+rand(40))." 7.23684,288.816 84.8684,287.5 33.5526,333.553 111.184,320.395 82.2368,448.026",fill=>"url(#TessPattern)", stroke=>"black");

$svg->text(x=>100,y=>20)->cdata("Using A tessalated pattern to create a fill");

$svg->anchor(-href=>'http://roasp.com/tutorial/source/tessalate.txt')->text(x=>50,y=>400, fill=>'red' )->cdata("View Script Source");

print "Content-type: image/svg+xml\n\n";

print $svg->xmlify;

Page 14: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

• Minimize client-side functional requirements

• Keep business logic on the server• Facilitate functional extension• Require planing and vision

Thin-client Applications

Page 15: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

• Now: HTML-style form process model.– Render->modify->submit.– Familar with users.

• (Possibly) Later: XFORMS support in SVG.– Embedded form content within the XML

vocabulary.– Problem: Not in 1.2. Not finalized. No

processing model.– Too complex. Never worked with it...

Forms Processing in SVG

Page 16: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

• HTML:– declarative form

processing– Must submit all values and

refresh page

• SVG 1.0-1-2:– No support for declarative

information processing– Reliant on scripting

HTML-Style Forms

Page 17: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

HTML-style Architecture Concept

• Keep the widget a ‘black box‘• Wiget changes modify a text field• Maintain state at server• Use commit event to update state

Page 18: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Examples

• Rotary control

• Sliding control

• Pull-down menu

http://www.roitsystems.com/conferences/yapc_eu2003/svg/knob.svg

http://www.roitsystems.com/conferences/yapc_eu2003/svg/slider.svg

http://www.roitsystems.com/conferences/yapc_eu2003/svg/pulldown.svg

Page 19: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

How This Works...

• Commit button.• Do_process_form.• getURL (postURL).• Callback_method – rendering

commands.– Old: delete by id.– New: append to the workspace.– Message: server messages for the

user.

Page 20: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Script Components

• Do_set_string: Assign the interface values

• Do_process_form: Submit the form• Show_callback: handle the result

from getURL

Page 21: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

do_set_string()

// set a string

function do_set_string(Doc, id, string) {

Doc.getElementById(id).getFirstChild.setData(string);

}

• Provides a single method for assigning values to the form interface.

• Required due to a shortcoming in SMIL which does not support declarative animation on text elements.

Page 22: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

do_process_form()

// submit the form for processing

function do_process_form(IDArray,ValueArray) {

var url = 'GISMax.cgi?edit=;act=processform;';

for (var i=0; i<IDArray.length; i++) {

url = url +

eval("'"+IDArray[i]+"'") + "=„ +

getFormFieldValue(evt,eval("'"+ValueArray[i]+"'"))+';';

}

getURL(url+';uid='+uid,show_callback);

setCommand(evt,'');

}

• Form handler for submit. • Required due to a shortcoming in SMIL which does not

support declarative animation on text elements.

Page 23: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Show_callback() ...Start

function show_callback(test) {

//handle the raw return and parse the data

grp=parseXML('<g>'+test.content+'</g>',document);

if (grp.hasChildNodes) {

vp = document.getElementById('canvas');

//handle <old> nodes

engine = grp.getFirstChild();

xml = engine.getFirstChild();

//...continued next slide

• Form handler for submit. • Required due to a shortcoming in SMIL which does not

support declarative animation on text elements.

Page 24: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Show_callback() ...Old

oldgroup = xml.getElementsByTagName('obj'); // I think this is now an array

var length = oldgroup.getLength();

i=0;

var oldId = "none";

while (i < length) {

thisElement=oldgroup.item(i);

oldId = thisElement.getAttribute("id");

myself = document.getElementById("g."+oldId);

if (myself) {

myself.parentNode.removeChild(myself);

myself = null;

}

i++;

do_set_string(document,'message',"Attached anchor "+oldId);

}

// ...continued

• Dispose of old elements by ID that the server declares as deletable

Page 25: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Show_callback() ...msg

//message handler

//grab the message we recieved

message_body = xml.getElementsByTagName('message');

if (message_body) {

if (messageElement=message_body.item(0)) {

message = messageElement.getAttribute('value');

do_set_string(SVGDoc,'message',message);

}

}

• Message handler for feedback at the client side

Page 26: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Show_callback() ...News

//handle new elements. Each element to be added is actually a group.

news = xml.getElementsByTagName('new');

length = news.getLength();

if (length == 0) {return}

var i=0;

while (i<length) {

xml = news.item(0);

newgroup = xml.getElementsByTagName('g');

var groups = newgroup.getLength();

//catch error (2): missing <g> tags in <new> tag

if (groups == 0) {return}

var j = 0;

while (j<length) {

vp.appendChild(newgroup.item(j));

j++;

}

}

} //for completeness. End of subroutine

• Insert new SVG snippet into workspace

Page 27: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

XML snippet result

<engine id="engine">

<old id="oldgroups">

<OldID id="text_from_server" />

</old>

<NewGroup id="newgroup">

<g id="g.text_from_server">

<rect width="100" y="20" fill="green"

stroke="blue" x="10" height="60" />

<text y="24" fill="red" x="23">

Hey... you said: Dog</text>

</g>

</NewGroup>

<messages id="messages">

<message value="Hey, you said something" />

</messages>

</engine>

• Script function do_process_form causes a query to be called by getURL and to be parsed by parsXML

• Result of pulldown.svg server query

http://localhost/cgi-bin/svgopen2003/gui_workshop/processor.pl?gui_form_x_value=Dog

Page 28: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Why this stuff is Good• Keep the client-side functionality simple

– Reduce implementation risk– Minimize cross-platform incompatibilities

• No large clientside codebase– Reduce user wait before getting started

• Obfuscates code base – some people like this– Client-side machine has minimal business logic– Applications can not be reverse-engineered by users

• Well suited for collaboration applications• All data stored on centralized servers

– Reduces workstation failure risk– Increases security– No user access to data unless explicitly enabled

Page 29: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Down sides

• Must stay connected to the server – no standalone apps.– Not always on line.

• Bandwidth.– Mass-market sites not a good idea.– Better suited for intranet systems.– Distance to host affects user experience.

• Server load – Requires powerful hardware.– Server intensive.– Can be minimized by using caching.

Page 30: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Down sides ...2

• Lag: Round-tripping data takes time– Not suitabable for very fast response systems– Need to allow for communication failures

• Incomplete Browser support– Requires SVG and JS– Limited to Adobe 3+, Corel batik.– ASV3 is broken on Mozilla 1.– Native SVG support in Mozilla still

experimental– JS/SVG has Issues on non-Windows platforms

Page 31: Copyright 2001 RO IT Systems GmbH RO IT Systems GmbH Building an SVG GUI with Perl Ronan Oger RO IT Systems GmbH Ronan@roasp.com Ronan.oger@roitsystems.com

Copyright 2001 RO IT Systems GmbHRO IT Systems GmbH www.roitsystems.com

Resources• Sites

– http//www.roasp.com/ Serverside SVG portal – by RO IT systems– http://www.w3.org/TR/SVG/ SVG recommendation – Comprehensive SVG

documentation with extensive examples– http://www.svgopen.org SVG Open conference home – Repository of papers

and presentations from past conferences dating back to SVG Open 2002– http://www.scale-a-vector.de/home-e.htm Petra Kukofka‘s SVG design page –

SVG cartoons and animations, discussions, SVG articles– http://www.schemasoft.org/ SPARK project: SVG Programmers'

Application Resource Kit. Sponsored by SchemaSoft.– http://www.pinkjuice.com/svg/ Prolific SVG page by Tobias rief in Berlin– http://www.svgfoundation.org SVG Foundation – http://www.protocol7.com/svg-wiki/ The SVG wiki – excellent site for cross-

reference– http://www.svg-cafe.com/ an SVG discussion forum sponsored by EvolGrafiX.– http://www.carto.net/ A rich cartography-specific SVG site with a number of

high quality academic papers and demos.

• Newsgroups– [email protected]