diff --git a/draw.js b/draw.js
index 2dbe213..ba9c738 100644
--- a/draw.js
+++ b/draw.js
@@ -52,7 +52,7 @@ var DrawingArea = new Lang.Class({
Name: 'DrawOnYourScreenDrawingArea',
Extends: St.DrawingArea,
- _init: function(params, monitor, helper) {
+ _init: function(params, monitor, helper, loadJson) {
this.parent({ style_class: 'draw-on-your-screen', name: params && params.name ? params.name : ""});
// 'style-changed' is emitted when 'this' is added to an actor
@@ -74,6 +74,9 @@ var DrawingArea = new Lang.Class({
this.textHasCursor = false;
this.dashedLine = false;
this.colors = [Clutter.Color.new(0, 0, 0, 255)];
+
+ if (loadJson)
+ this._loadJson();
},
_redisplay: function() {
@@ -225,12 +228,12 @@ var DrawingArea = new Lang.Class({
this.smoothedStroke = this.settings.get_boolean('smoothed-stroke');
this.currentElement = new DrawingElement ({
- color: this.currentColor,
+ shape: this.currentShape == Shapes.TEXT ? Shapes.RECTANGLE : this.currentShape,
+ color: this.currentColor.to_string(),
line: { lineWidth: this.currentLineWidth, lineJoin: this.currentLineJoin, lineCap: this.currentLineCap },
dash: { array: this.dashedLine ? this.dashArray : [0, 0] , offset: this.dashedLine ? this.dashOffset : 0 },
fill: fill,
eraser: eraser,
- shape: this.currentShape == Shapes.TEXT ? Shapes.RECTANGLE : this.currentShape,
transform: { active: false, center: [0, 0], angle: 0, startAngle: 0, ratio: 1 },
text: '',
font: { family: (this.currentFontFamilyId == 0 ? this.fontFamily : FontFamilyNames[this.currentFontFamilyId]), weight: this.currentFontWeight, style: this.currentFontStyle },
@@ -390,7 +393,7 @@ var DrawingArea = new Lang.Class({
selectColor: function(index) {
this.currentColor = this.colors[index];
if (this.currentElement) {
- this.currentElement.color = this.currentColor;
+ this.currentElement.color = this.currentColor.to_string();
this._redisplay();
}
this.emitter.emit('show-osd', this.currentColor.to_string(), null);
@@ -469,7 +472,7 @@ var DrawingArea = new Lang.Class({
this.get_parent().set_background_color(this.hasBackground ? this.activeBackgroundColor : null);
},
- leaveDrawingMode: function() {
+ leaveDrawingMode: function(save) {
if (this.keyPressedHandler) {
this.disconnect(this.keyPressedHandler);
this.keyPressedHandler = null;
@@ -499,9 +502,11 @@ var DrawingArea = new Lang.Class({
this.dashedLine = false;
this._redisplay();
this.get_parent().set_background_color(null);
+ if (save)
+ this._saveAsJson();
},
- save: function() {
+ saveAsSvg: function() {
// stop drawing or writing
if (this.currentElement && this.currentElement.shape == Shapes.TEXT) {
this._stopWriting();
@@ -535,6 +540,41 @@ var DrawingArea = new Lang.Class({
}
},
+ _saveAsJson: function() {
+ let filename = `DrawOnYourScreen.json`;
+ let dir = GLib.get_user_data_dir();
+ let path = GLib.build_filenamev([dir, filename]);
+
+ let oldContents;
+ if (GLib.file_test(path, GLib.FileTest.EXISTS)) {
+ oldContents = GLib.file_get_contents(path)[1];
+ if (oldContents instanceof Uint8Array)
+ oldContents = imports.byteArray.toString(oldContents);
+ }
+
+ // do not use "content = JSON.stringify(this.elements, null, 2);", neither "content = JSON.stringify(this.elements);"
+ // because of compromise between disk usage and human readability
+ let contents = `[\n ` + new Array(...this.elements.map(element => JSON.stringify(element))).join(`,\n\n `) + `\n]`;
+
+ if (contents != oldContents)
+ GLib.file_set_contents(path, contents);
+ },
+
+ _loadJson: function() {
+ let filename = `DrawOnYourScreen.json`;
+ let dir = GLib.get_user_data_dir();
+ let path = GLib.build_filenamev([dir, filename]);
+
+ if (!GLib.file_test(path, GLib.FileTest.EXISTS))
+ return;
+ let [success, contents] = GLib.file_get_contents(path);
+ if (!success)
+ return;
+ if (contents instanceof Uint8Array)
+ contents = imports.byteArray.toString(contents);
+ this.elements.push(...JSON.parse(contents).map(object => new DrawingElement(object)));
+ },
+
disable: function() {
this.erase();
}
@@ -560,6 +600,22 @@ var DrawingElement = new Lang.Class({
this[key] = params[key];
},
+ // toJSON is called by JSON.stringify
+ toJSON: function() {
+ return {
+ shape: this.shape,
+ color: this.color,
+ line: this.line,
+ dash: this.dash,
+ fill: this.fill,
+ eraser: this.eraser,
+ transform: this.transform,
+ text: this.text,
+ font: this.font,
+ points: this.points.map((point) => [Math.round(point[0]*100)/100, Math.round(point[1]*100)/100])
+ };
+ },
+
buildCairo: function(cr, showTextCursor) {
cr.setLineCap(this.line.lineCap);
cr.setLineJoin(this.line.lineJoin);
@@ -575,7 +631,9 @@ var DrawingElement = new Lang.Class({
else
cr.setOperator(Cairo.Operator.OVER);
- Clutter.cairo_set_source_color(cr, this.color);
+ let [success, color] = Clutter.Color.from_string(this.color);
+ if (success)
+ Clutter.cairo_set_source_color(cr, color);
let [points, shape, trans] = [this.points, this.shape, this.transform];
@@ -614,7 +672,7 @@ var DrawingElement = new Lang.Class({
buildSVG: function(bgColor) {
let row = "\n ";
let points = this.points.map((point) => [Math.round(point[0]*100)/100, Math.round(point[1]*100)/100]);
- let color = this.eraser ? bgColor : this.color.to_string();
+ let color = this.eraser ? bgColor : this.color;
let isStraightLine = this.shape == Shapes.LINE && (points.length < 3 || points[2] == points[1] || points[2] == points[0]);
let fill = this.fill && !isStraightLine;
let attributes = `fill="${fill ? color : 'transparent'}" ` +
diff --git a/extension.js b/extension.js
index 813719b..4b35eff 100644
--- a/extension.js
+++ b/extension.js
@@ -98,7 +98,8 @@ var AreaManager = new Lang.Class({
let monitor = this.monitors[i];
let container = new St.Widget({ name: 'drawOnYourSreenContainer' + i });
let helper = new Draw.DrawingHelper({ name: 'drawOnYourSreenHelper' + i }, monitor);
- let area = new Draw.DrawingArea({ name: 'drawOnYourSreenArea' + i }, monitor, helper);
+ let load = i == Main.layoutManager.primaryIndex && this.settings.get_boolean('persistent-drawing');
+ let area = new Draw.DrawingArea({ name: 'drawOnYourSreenArea' + i }, monitor, helper, load);
container.add_child(area);
container.add_child(helper);
@@ -122,7 +123,7 @@ var AreaManager = new Lang.Class({
'redo': this.activeArea.redo.bind(this.activeArea),
'delete-last-element': this.activeArea.deleteLastElement.bind(this.activeArea),
'smooth-last-element': this.activeArea.smoothLastElement.bind(this.activeArea),
- 'save-as-svg': this.activeArea.save.bind(this.activeArea),
+ 'save-as-svg': this.activeArea.saveAsSvg.bind(this.activeArea),
'toggle-background': this.activeArea.toggleBackground.bind(this.activeArea),
'toggle-square-area': this.activeArea.toggleSquareArea.bind(this.activeArea),
'increment-line-width': () => this.activeArea.incrementLineWidth(1),
@@ -223,6 +224,7 @@ var AreaManager = new Lang.Class({
if (this.activeArea) {
let activeIndex = this.areas.indexOf(this.activeArea);
let activeContainer = this.activeArea.get_parent();
+ let save = activeIndex == Main.layoutManager.primaryIndex && this.settings.get_boolean('persistent-drawing');
if (this.hiddenList)
this.togglePanelAndDockOpacity();
@@ -230,7 +232,7 @@ var AreaManager = new Lang.Class({
Main.popModal(this.activeArea);
this.removeInternalKeybindings();
this.activeArea.reactive = false;
- this.activeArea.leaveDrawingMode();
+ this.activeArea.leaveDrawingMode(save);
this.activeArea = null;
activeContainer.get_parent().remove_actor(activeContainer);
diff --git a/locale/draw-on-your-screen.pot b/locale/draw-on-your-screen.pot
index 94c8019..009c315 100644
--- a/locale/draw-on-your-screen.pot
+++ b/locale/draw-on-your-screen.pot
@@ -223,6 +223,12 @@ msgstr ""
msgid "Draw On Your Screen becomes Draw On Your Desktop"
msgstr ""
+msgid "Persistent"
+msgstr ""
+
+msgid "Persistent drawing through restart"
+msgstr ""
+
msgid "Internal"
msgstr ""
diff --git a/prefs.js b/prefs.js
index 772c85d..7089bba 100644
--- a/prefs.js
+++ b/prefs.js
@@ -139,6 +139,20 @@ const PrefsPage = new GObject.Class({
desktopBox.pack_start(desktopLabelBox, true, true, 4);
desktopBox.pack_start(desktopSwitch, false, false, 4);
listBox.add(desktopBox);
+
+ let persistentBox = new Gtk.Box({ margin: MARGIN });
+ let persistentLabelBox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
+ let persistentLabel1 = new Gtk.Label({label: _("Persistent")});
+ let persistentLabel2 = new Gtk.Label({ use_markup: true, halign: 1, label: "" + _("Persistent drawing through restart") + "" });
+ persistentLabel1.set_halign(1);
+ persistentLabel2.get_style_context().add_class("dim-label");
+ persistentLabelBox.pack_start(persistentLabel1, true, true, 0);
+ persistentLabelBox.pack_start(persistentLabel2, true, true, 0);
+ let persistentSwitch = new Gtk.Switch({valign: 3});
+ this.settings.bind("persistent-drawing", persistentSwitch, "active", 0);
+ persistentBox.pack_start(persistentLabelBox, true, true, 4);
+ persistentBox.pack_start(persistentSwitch, false, false, 4);
+ listBox.add(persistentBox);
this.addSeparator(listBox);
let internalTitleBox = new Gtk.Box({ margin: MARGIN });
diff --git a/schemas/gschemas.compiled b/schemas/gschemas.compiled
index dbb5659..a0f2bb1 100644
Binary files a/schemas/gschemas.compiled and b/schemas/gschemas.compiled differ
diff --git a/schemas/org.gnome.shell.extensions.draw-on-your-screen.gschema.xml b/schemas/org.gnome.shell.extensions.draw-on-your-screen.gschema.xml
index a41ba91..225c21d 100644
--- a/schemas/org.gnome.shell.extensions.draw-on-your-screen.gschema.xml
+++ b/schemas/org.gnome.shell.extensions.draw-on-your-screen.gschema.xml
@@ -11,6 +11,11 @@
move drawing on desktop
move drawing on desktop
+
+ false
+ persistent drawing
+ persistent drawing
+
["<Alt><Super>d"]
toggle drawing