diff --git a/editor/svg-editor.css b/editor/svg-editor.css
index 683c7804..7639f931 100644
--- a/editor/svg-editor.css
+++ b/editor/svg-editor.css
@@ -31,6 +31,7 @@ body {
vertical-align: middle;
width: 640px;
height: 480px;
+ -apple-dashboard-region:dashboard-region(control rectangle 0px 0px 0px 0px); /* for widget regions that shouldn't react to dragging */
}
#svg_editor div#palette_holder {
diff --git a/editor/svg-editor.html b/editor/svg-editor.html
index 3a8d5781..72a7906e 100644
--- a/editor/svg-editor.html
+++ b/editor/svg-editor.html
@@ -42,6 +42,7 @@
diff --git a/editor/svg-editor.js b/editor/svg-editor.js
index b5d91d08..0898cb0f 100644
--- a/editor/svg-editor.js
+++ b/editor/svg-editor.js
@@ -33,7 +33,35 @@ function svg_edit_setup() {
// with a gradient will appear black in Firefox, etc. See bug 308590
// https://bugzilla.mozilla.org/show_bug.cgi?id=308590
var saveHandler = function(window,svg) {
- window.open("data:image/svg+xml;base64," + Utils.encode64(svg));
+ if(window.opera && window.opera.io && window.opera.io.filesystem)
+ {
+ try {
+ window.opera.io.filesystem.browseForSave(
+ new Date().getTime(), /* mountpoint name */
+ "", /* default location */
+ function(file) {
+ try {
+ if (file) {
+ var fstream = file.open(file, "w");
+ fstream.write(svg, "UTF-8");
+ fstream.close();
+ }
+ }
+ catch(e) {
+ console.log("Write to file failed.");
+ }
+ },
+ false /* not persistent */
+ );
+ }
+ catch(e) {
+ console.log("Save file failed.");
+ }
+ }
+ else
+ {
+ window.open("data:image/svg+xml;base64," + Utils.encode64(svg));
+ }
};
// called when we've selected a different element
@@ -469,6 +497,10 @@ function svg_edit_setup() {
var clickSave = function(){
svgCanvas.save();
};
+
+ var clickOpen = function(){
+ svgCanvas.open();
+ };
var clickUndo = function(){
if (svgCanvas.getUndoStackSize() > 0)
@@ -568,6 +600,7 @@ function svg_edit_setup() {
$('#tool_poly').click(clickPoly);
$('#tool_clear').click(clickClear);
$('#tool_save').click(clickSave);
+ $('#tool_open').click(clickOpen);
$('#tool_source').click(showSourceEditor);
$('#tool_source_cancel,#svg_source_overlay').click(cancelSourceEditor);
$('#tool_source_save').click(saveSourceEditor);
@@ -594,7 +627,7 @@ function svg_edit_setup() {
// added these event handlers for all the push buttons so they
// behave more like buttons being pressed-in and not images
function setPushButtons() {
- var toolnames = ['clear','save','source','delete','delete_multi','paste','clone','clone_multi','move_top','move_bottom'];
+ var toolnames = ['clear','open','save','source','delete','delete_multi','paste','clone','clone_multi','move_top','move_bottom'];
var all_tools = '';
var cur_class = 'tool_button_current';
@@ -646,6 +679,7 @@ function svg_edit_setup() {
['7', clickPoly],
[modKey+'N', function(evt){clickClear();evt.preventDefault();}],
[modKey+'S', function(evt){editingsource?saveSourceEditor():clickSave();evt.preventDefault();}],
+ [modKey+'O', function(evt){clickOpen();evt.preventDefault();}],
['del', function(evt){deleteSelected();evt.preventDefault();}],
['backspace', function(evt){deleteSelected();evt.preventDefault();}],
['shift+up', moveToTopSelected],
@@ -829,5 +863,13 @@ function svg_edit_setup() {
$('#stroke_width').SpinButton({ min: 1, max: 99, step: 1, callback: changeStrokeWidth });
$('#angle').SpinButton({ min: -359, max: 359, step: 5, callback: changeRotationAngle });
+ // if Opera and in widget form, enable the Open button
+ if (window.opera) {
+ opera.postError('opera.io=' + opera.io);
+ if(opera && opera.io && opera.io.filesystem) {
+ $('#tool_open').show();
+ }
+ }
+
return svgCanvas;
};
diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js
index 689ca44c..29b7d62a 100644
--- a/editor/svgcanvas.js
+++ b/editor/svgcanvas.js
@@ -1360,8 +1360,6 @@ function SvgCanvas(c)
freehand_max_y = Math.max(y, freehand_max_y);
// break; missing on purpose
case "path":
-// var dx = x - start_x;
-// var dy = y - start_y;
start_x = x;
start_y = y;
d_attr += + x + "," + y + " ";
@@ -1379,8 +1377,29 @@ function SvgCanvas(c)
// if we are dragging a point, let's move it
if (current_poly_pt_drag != -1 && current_poly) {
var i = current_poly_pt_drag * 2;
- var dx = x - current_poly_pts[i],
- dy = y - current_poly_pts[i+1];
+
+ // if the image is rotated, then we must modify the x,y mouse coordinates
+ // and rotate them into the shape's rotated coordinate system
+
+ // FIXME: the problem is that the element's rotation is controlled by
+ // two things: an angle and a rotation point (the center of the element).
+ // If the element's bbox is changed, its center changes. In this case,
+ // we keep the rotation center where it is (parse it out from the transform
+ // attribute), and move the poly point appropriately). This looks good while
+ // dragging, but looks funny when you subsequently rotate the element again.
+ if (angle) {
+ // extract the shape's (potentially) old 'center' from the transform attribute
+ var matched_numbers = current_poly.getAttribute('transform').match(/([\d\.\-\+]+)/g);
+ var cx = parseFloat(matched_numbers[1]),
+ cy = parseFloat(matched_numbers[2]);
+ var bbox = canvas.getBBox(current_poly);
+ var dx = x - cx, dy = y - cy;
+ var r = Math.sqrt( dx*dx + dy*dy );
+ var theta = Math.atan2(dy,dx) - angle;
+ x = cx + r * Math.cos(theta);
+ y = cy + r * Math.sin(theta);
+ }
+
current_poly_pts[i] = x;
current_poly_pts[i+1] = y;
@@ -1394,7 +1413,7 @@ function SvgCanvas(c)
arr[0] = ["M", curx, ",", cury].join('');
for (var j = 1; j < len; ++j) {
var px = current_poly_pts[j*2], py = current_poly_pts[j*2+1];
- arr[j] = ["l", (px-curx), ",", (py-cury)].join('');
+ arr[j] = ["l", parseInt(px-curx), ",", parseInt(py-cury)].join('');
curx = px;
cury = py;
}
@@ -1785,6 +1804,40 @@ function SvgCanvas(c)
// public functions
+ this.open = function() {
+ if(window.opera && window.opera.io && window.opera.io.filesystem)
+ {
+ try {
+ window.opera.io.filesystem.browseForFile(
+ new Date().getTime(), /* mountpoint name */
+ "", /* default location */
+ function(file) {
+ try {
+ if (file) {
+ fstream = file.open(file, "r");
+ var output = "";
+ while (!fstream.eof) {
+ output += fstream.readLine("UTF-16");
+ }
+
+ canvas.setSvgString(output); /* 'this' is bound to the filestream object here */
+ }
+ }
+ catch(e) {
+ console.log("Reading file failed.");
+ }
+ },
+ false, /* not persistent */
+ false, /* no multiple selections */
+ "*.svg" /* file extension filter */
+ );
+ }
+ catch(e) {
+ console.log("Open file failed.");
+ }
+ }
+ };
+
this.save = function() {
// remove the selected outline before serializing
this.clearSelection();
diff --git a/widget/Makefile b/widget/Makefile
new file mode 100644
index 00000000..84deba88
--- /dev/null
+++ b/widget/Makefile
@@ -0,0 +1,12 @@
+ZIP = zip
+PACKAGE = svgedit-2.3
+FILEMASK = \*.html \*.css \*.js \*.txt \*.png \*.jpg \*.gif \*.svg \*.xml
+
+clean:
+ rm -f *.*~
+ rm -rf ./editor/
+
+widget: clean
+ rm -f $(PACKAGE).wgt
+ cp -r ../editor .
+ $(ZIP) $(PACKAGE).wgt -r . -i $(FILEMASK)
diff --git a/widget/config.xml b/widget/config.xml
new file mode 100644
index 00000000..81af90aa
--- /dev/null
+++ b/widget/config.xml
@@ -0,0 +1,16 @@
+
+
+ SVG Edit
+
+ A simple SVG Editor.
+
+ 800
+ 600
+
+ SVG Edit
+ 2009-08
+
+
+
+
+
\ No newline at end of file
diff --git a/widget/index.html b/widget/index.html
new file mode 100644
index 00000000..28d30cc0
--- /dev/null
+++ b/widget/index.html
@@ -0,0 +1,11 @@
+
+
+ SVG Edit
+
+
+
+
+
+
\ No newline at end of file
diff --git a/widget/style.css b/widget/style.css
new file mode 100644
index 00000000..b3b268ea
--- /dev/null
+++ b/widget/style.css
@@ -0,0 +1,2 @@
+body { margin: 0px; padding: 0px; }
+#container { width: 100%; height: 100%; border: none; }
\ No newline at end of file