From 2b25958d8c88b68d467ff56625024fd542319153 Mon Sep 17 00:00:00 2001 From: abakkk Date: Mon, 11 Mar 2019 17:53:35 +0100 Subject: [PATCH] add persistence feature --- draw.js | 74 ++++++++++++++++-- extension.js | 8 +- locale/draw-on-your-screen.pot | 6 ++ prefs.js | 14 ++++ schemas/gschemas.compiled | Bin 3040 -> 3088 bytes ...extensions.draw-on-your-screen.gschema.xml | 5 ++ 6 files changed, 96 insertions(+), 11 deletions(-) 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 dbb5659c1cdf79516ddc2a987422cb1ec692a57e..a0f2bb139b3b31cc557b0443ac9d4271972ccb93 100644 GIT binary patch literal 3088 zcmaJ@TWl0n7(OVKa_w>vC{!sZP)ugmr4(9ID%A>zn3Ob_qEVdgoZTIEc4nQKUcts& zBZ-$7Uu=v-hzW@a5locuV6-O27!wlkLHk$|A0Sau6CWT(@%yG{XJ)t6O}>2Je*5o# z{&PS3p3z-Xw|${LYr(xUy6G&P$8fhW(x1`uFPJ)-z2vKvd5O?rdxCDkcD3*W| zfaB(pIom19q?ebLm6Suiv^~?Yy`y*N32t50N)2R0-J!%F>HY*wkoj3bKfs| zeJPmzuM-2J5u652zj!fApL#j`{oo_OV?)1Rp-;UOeja=hcwG6^^vA)MfWlwR4UDH= z0sjj48qlTUsTn^FPGC@;P(C&NM(`fs{X5sbWFG3p@Vmh}keG7+p-;UM{t$Q!*sJnT z2laq20sE9sP5%e*bzr~psp;PWuU#O-MAlr*{M4-fVQ?oR#74R6)zx(ic`qZ44aqy>rfBbS6 zeQNp>;H$v-r%#=rPdy+0BzPJaJ<#wged<;4YZnUf05JN-g^%b{*TdffJ_3k!zx+*~ zdKvsY_yn-+Myi%RHQRj;dD|k0>_F&;Qed;yvd%@2Gz2g@@p-;_vO5j(4b3eYbmOeH6I}ZK~ zICXxLL!X-KY6AQd@WMCWTJ)(Ie;s@q`0(xHH|bNeo&+}UMquLQ(ZxJFsB7Rifu93D z`0CIF##3{BmcU~`P5SI2`qZo8p9X&p{8?-a>Y)zm0bd2))tOPu|qSInoeLQUtzCE4~@!O;L?d5n?tM^jB?n({NgEFE>dyYDq zE9+>EqMOTkRri8Ac2w1|BZ}V<#_I!U-qXB+Tu?wb4xVb?zRNeD6$fBINYq|nk zESS~#ma2ZB|1D9wEn&Me(-73Tv#QRWQT)!i;&)ZW?~3AgmE+a;W*ytt2Bn$Hs~a-x z-=OLra+U8K91Fp{vH`pv;GMD+;Qg`+z_AwGX}r&HbPF7p0$aD@K1<;HM&N#69&qPUL;r1jOgF72m`9F|MuAx7MnDmvmcNnr<7K z;baQhfa#fire*rW;s5hC-cXoa^-42L6gq7}uxbTxmFQzr81KX8n#4j3T$MA@ShgA`G^*o#f{UaOPt&mwrZ?o7Z;0e^9qVCmN4F}tlQAN%5|%&-<^`QvAM9C WP^a|6|2yh;?3{}IF`|4mtN#Mb&d@Ue literal 3040 zcmai0TWB0*7@caOxtKP+m?mx1SgYL#v)kM^5Tnu9CN)Ars6-!3C%gadPIh)?ota## z!7D0iDZUuQVni%H1kwks3Zn5vicp9zYQcvHeG#?f!H0-wJ!kgcnaLV-;BdY@bLRW+ z|F_2<(`;QcT}3|i;ITp+xj||>z-8<69b~?XDg(+Z;EggxDZf=wuH(5<4M7=Fegv-r zmYt5KO)Dp&PDU6;RLr`?4OWY`dW|VT^ zW{C=LB~T@C3%CZ@DX|M&idty9fjt1a?4b_K@iqVlfJWeU;0~Y(xDz-890u+IjsQ!i zE~c29W8bYzD;4Ni12DFD@qOxysUHRR0dHRa>0|1QtDz5rHDLLhH|nV~-UodadGFTXOVGp4TGg!X~jb^CAXjQ2v1fIEQZpJNr& z8MB`Q;KzZtUq5|~I^#Xi^Wf(IV`Th(>WmwpFM&S++|!r)sWWDtOW-TO)O{ycs57R% z0p5XyyY^A^dFqU7px1&A1FI>$jyhwu8wU>p#eKz?`)UY$6*!|lahZO`yWrmhS7Jk~ zJbLbF>Ws^n9~=QzpINBp{$yMZ{U|sAY<&0H2>pzALZ1b{3MdD@|BE_f>WkoI;KAA7 z)~GXP|5w55K=#kJM(T{&|4ncuHs?dq&zSyta2)8DI%Dbs;0*Av)EQHs1up^%FJ5?u z`5ANmKLvja9Fu;=^sj??Al~|XdWrx` zfmeYOQfEwk4ZHyyYiadf!}jY7W>1P`@bIC3@m?L^#XOqT*o+g5IDDT z$n!I%e+)bc)co4`1^tZae-``_aDFKJ2X)5#p)Y|y0A7CY-XEwlZi0RZ%sa{vhDf-o zX_-QGGFo21!>4E1)^nOY*PBPP5zT3qMnm6f^nFIrr%el0b5v(Ky(Nz$-|HrBxSTLu z)k`&_C*4fAy+?+}`;tkeHr%Ls%;QoC^P^eu|C}mU>kdNX&;!!9#@W6`&g&;0(SvN0M<9w zFe@+2!aAWAi$baQ`)|qq+ahVf>+3zE89n9p&f`|&97OY)w{K%8>@lyf$GpNG3krK| zo5CK$iIY2l+drY@(FPyCovdtMx{3=CUWcSy2f3sP%dqU0LYg2C&QVM7t3}z_5MDdy zsVU9IIkkmW_|R|Pl6x7@Lt>cp1XL` z(oKK=Om2OTKfB%*_un6D!P)gD&zotH#7VTRti0aPQe>hzXQ773ozH*9N#SH&OCA-x kmuDldnZi&tGpQ!6L{^>F9eqMKbeA`)-(E)chl9ZL4-03%!2kdN 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