add persistence feature

This commit is contained in:
abakkk 2019-03-11 17:53:35 +01:00
parent 0c17e2cfbe
commit 2b25958d8c
6 changed files with 96 additions and 11 deletions

74
draw.js
View File

@ -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'}" ` +

View File

@ -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);

View File

@ -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 ""

View File

@ -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: "<small>" + _("Persistent drawing through restart") + "</small>" });
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 });

Binary file not shown.

View File

@ -11,6 +11,11 @@
<summary>move drawing on desktop</summary>
<description>move drawing on desktop</description>
</key>
<key type="b" name="persistent-drawing">
<default>false</default>
<summary>persistent drawing</summary>
<description>persistent drawing</description>
</key>
<key type="as" name="toggle-drawing">
<default>["&lt;Alt&gt;&lt;Super&gt;d"]</default>
<summary>toggle drawing</summary>