From 17bbe345affd79ecead8b060219c75fe7dfb407c Mon Sep 17 00:00:00 2001 From: abakkk Date: Sat, 4 Jan 2020 00:16:20 +0100 Subject: [PATCH] new "Open" and "Save" drawing features * Use a "drawOnYourScreen" subdir in the xdg user data dir * Info item with the name of the last saved/open json file * "Open drawing" sub menu with data dir content * "Save drawing" sub menu with entry * "Save", "Open previous" and "Open next" keybindings --- draw.js | 311 +++++++++++++++++- extension.js | 11 +- locale/draw-on-your-screen.pot | 18 +- prefs.js | 3 + schemas/gschemas.compiled | Bin 3256 -> 3492 bytes ...extensions.draw-on-your-screen.gschema.xml | 15 + stylesheet.css | 24 ++ 7 files changed, 363 insertions(+), 19 deletions(-) diff --git a/draw.js b/draw.js index 85e3603..e44414c 100644 --- a/draw.js +++ b/draw.js @@ -48,6 +48,7 @@ const _ = imports.gettext.domain(Extension.metadata["gettext-domain"]).gettext; const GS_VERSION = Config.PACKAGE_VERSION; const DEFAULT_FILE_NAME = 'DrawOnYourScreen'; +const DATA_SUB_DIR = 'drawOnYourScreen' const FILL_ICON_PATH = Extension.dir.get_child('icons').get_child('fill-symbolic.svg').get_path(); const STROKE_ICON_PATH = Extension.dir.get_child('icons').get_child('stroke-symbolic.svg').get_path(); @@ -70,6 +71,40 @@ function getDateString() { return `${date.format("%F")} ${date.format("%X")}`; } +function getJsonFiles() { + let directory = Gio.File.new_for_path(GLib.build_filenamev([GLib.get_user_data_dir(), DATA_SUB_DIR])); + if (!directory.query_exists(null)) + return []; + + let jsonFiles = []; + let enumerator; + try { + enumerator = directory.enumerate_children('standard::name,standard::display-name,standard::content-type,time::modified', Gio.FileQueryInfoFlags.NONE, null); + } catch(e) { + return []; + } + + let i = 0; + let fileInfo = enumerator.next_file(null); + while (fileInfo) { + if (fileInfo.get_content_type().indexOf('json') != -1 && fileInfo.get_name() != `${DEFAULT_FILE_NAME}.json`) { + let file = enumerator.get_child(fileInfo); + jsonFiles.push({ name: fileInfo.get_name().slice(0, -5), + displayName: fileInfo.get_display_name().slice(0, -5), + modificationDateTime: fileInfo.get_modification_date_time(), + delete: () => file.delete(null) }); + } + fileInfo = enumerator.next_file(null); + } + enumerator.close(null); + + jsonFiles.sort((a, b) => { + return a.modificationDateTime.difference(b.modificationDateTime); + }); + + return jsonFiles; +} + // DrawingArea is the widget in which we draw, thanks to Cairo. // It creates and manages a DrawingElement for each "brushstroke". // It handles pointer/mouse/(touch?) events and some keyboard events. @@ -79,7 +114,7 @@ var DrawingArea = new Lang.Class({ Signals: { 'show-osd': { param_types: [GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_DOUBLE] }, 'stop-drawing': {} }, - _init: function(params, monitor, helper, loadJson) { + _init: function(params, monitor, helper, loadPersistent) { this.parent({ style_class: 'draw-on-your-screen', name: params && params.name ? params.name : ""}); this.connect('repaint', this._repaint.bind(this)); @@ -99,8 +134,8 @@ var DrawingArea = new Lang.Class({ this.fill = false; this.colors = [Clutter.Color.new(0, 0, 0, 255)]; - if (loadJson) - this._loadJson(); + if (loadPersistent) + this._loadPersistent(); }, get menu() { @@ -591,7 +626,7 @@ var DrawingArea = new Lang.Class({ this._menu.close(); this.get_parent().set_background_color(null); if (save) - this.saveAsJson(); + this.savePersistent(); }, saveAsSvg: function() { @@ -632,10 +667,18 @@ var DrawingArea = new Lang.Class({ } }, - saveAsJson: function() { - let filename = `${DEFAULT_FILE_NAME}.json`; - let dir = GLib.get_user_data_dir(); - let path = GLib.build_filenamev([dir, filename]); + _saveAsJson: function(name, notify) { + // stop drawing or writing + if (this.currentElement && this.currentElement.shape == Shapes.TEXT && this.currentElement.state == TextState.WRITING) { + this._stopWriting(); + } else if (this.currentElement && this.currentElement.shape != Shapes.TEXT) { + this._stopDrawing(); + } + + let dir = GLib.build_filenamev([GLib.get_user_data_dir(), DATA_SUB_DIR]); + if (!GLib.file_test(dir, GLib.FileTest.EXISTS)) + GLib.mkdir_with_parents(dir, 0o700); + let path = GLib.build_filenamev([dir, `${name}.json`]); let oldContents; if (GLib.file_test(path, GLib.FileTest.EXISTS)) { @@ -652,14 +695,30 @@ var DrawingArea = new Lang.Class({ // 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) + if (contents != oldContents) { GLib.file_set_contents(path, contents); + if (notify) + this.emit('show-osd', 'document-save-symbolic', name, -1); + if (name != DEFAULT_FILE_NAME) + this.jsonName = name; + } }, - _loadJson: function() { - let filename = `${DEFAULT_FILE_NAME}.json`; + saveAsJsonWithName: function(name) { + this._saveAsJson(name); + }, + + saveAsJson: function() { + this._saveAsJson(getDateString(), true); + }, + + savePersistent: function() { + this._saveAsJson(DEFAULT_FILE_NAME); + }, + + _loadJson: function(name, notify) { let dir = GLib.get_user_data_dir(); - let path = GLib.build_filenamev([dir, filename]); + let path = GLib.build_filenamev([dir, DATA_SUB_DIR, `${name}.json`]); if (!GLib.file_test(path, GLib.FileTest.EXISTS)) return; @@ -669,6 +728,43 @@ var DrawingArea = new Lang.Class({ if (contents instanceof Uint8Array) contents = imports.byteArray.toString(contents); this.elements.push(...JSON.parse(contents).map(object => new DrawingElement(object))); + + if (notify) + this.emit('show-osd', 'document-open-symbolic', name, -1); + if (name != DEFAULT_FILE_NAME) + this.jsonName = name; + }, + + _loadPersistent: function() { + this._loadJson(DEFAULT_FILE_NAME); + }, + + loadJson: function(name, notify) { + this.elements = []; + this.currentElement = null; + this._stopCursorTimeout(); + this._loadJson(name, notify); + this._redisplay(); + }, + + loadNextJson: function() { + let names = getJsonFiles().map(file => file.name); + + if (!names.length) + return; + + let nextName = names[this.jsonName && names.indexOf(this.jsonName) != names.length - 1 ? names.indexOf(this.jsonName) + 1 : 0]; + this.loadJson(nextName, true); + }, + + loadPreviousJson: function() { + let names = getJsonFiles().map(file => file.name); + + if (!names.length) + return; + + let previousName = names[this.jsonName && names.indexOf(this.jsonName) > 0 ? names.indexOf(this.jsonName) - 1 : names.length - 1]; + this.loadJson(previousName, true); }, disable: function() { @@ -1144,8 +1240,12 @@ var DrawingMenu = new Lang.Class({ this._addSwitchItemWithCallback(this.menu, _("Square drawing area"), this.area.isSquareArea, this.area.toggleSquareArea.bind(this.area)); this._addSeparator(this.menu); - this.menu.addAction(_("Save drawing as a SVG file"), this.area.saveAsSvg.bind(this.area), 'document-save-symbolic'); - this.menu.addAction(_("Open stylesheet.css"), manager.openStylesheetFile.bind(manager), 'document-open-symbolic'); + this._addDrawingNameItem(this.menu); + this._addOpenDrawingSubMenuItem(this.menu); + this._addSaveDrawingSubMenuItem(this.menu); + + this.menu.addAction(_("Save drawing as a SVG file"), this.area.saveAsSvg.bind(this.area), 'image-x-generic-symbolic'); + this.menu.addAction(_("Open stylesheet.css"), manager.openStylesheetFile.bind(manager), 'document-page-setup-symbolic'); this.menu.addAction(_("Show help"), this.area.toggleHelp.bind(this.area), 'preferences-desktop-keyboard-shortcuts-symbolic'); this.updateSectionVisibility(); @@ -1277,6 +1377,105 @@ var DrawingMenu = new Lang.Class({ menu.addMenuItem(item); }, + _addDrawingNameItem: function(menu) { + this.drawingNameMenuItem = new PopupMenu.PopupMenuItem('', { reactive: false, activate: false }); + this.drawingNameMenuItem.setSensitive(false); + menu.addMenuItem(this.drawingNameMenuItem); + this._updateDrawingNameMenuItem(); + }, + + _updateDrawingNameMenuItem: function() { + getActor(this.drawingNameMenuItem).visible = this.area.jsonName ? true : false; + if (this.area.jsonName) { + this.drawingNameMenuItem.label.set_text(`${this.area.jsonName}`); + this.drawingNameMenuItem.label.get_clutter_text().set_use_markup(true); + } + }, + + _addOpenDrawingSubMenuItem: function(menu) { + let item = new PopupMenu.PopupSubMenuMenuItem(_("Open drawing"), true); + this.openDrawingSubMenuItem = item; + this.openDrawingSubMenu = item.menu; + item.icon.set_icon_name('document-open-symbolic'); + + item.menu.itemActivated = () => { + item.menu.close(); + }; + + Mainloop.timeout_add(0, () => { + this._populateOpenDrawingSubMenu(); + return GLib.SOURCE_REMOVE; + }); + menu.addMenuItem(item); + }, + + _populateOpenDrawingSubMenu: function() { + this.openDrawingSubMenu.removeAll(); + let jsonFiles = getJsonFiles(); + jsonFiles.forEach(file => { + let item = this.openDrawingSubMenu.addAction(`${file.displayName}`, () => { + this.area.loadJson(file.name); + this._updateDrawingNameMenuItem(); + this._updateSaveDrawingSubMenuItemSensitivity(); + }); + item.label.get_clutter_text().set_use_markup(true); + + let expander = new St.Bin({ + style_class: 'popup-menu-item-expander', + x_expand: true, + }); + getActor(item).add_child(expander); + + let deleteButton = new St.Button({ style_class: 'draw-on-your-screen-menu-delete-button', + child: new St.Icon({ icon_name: 'edit-delete-symbolic', + style_class: 'popup-menu-icon', + x_align: Clutter.ActorAlign.END }) }); + getActor(item).add_child(deleteButton); + + deleteButton.connect('clicked', () => { + file.delete(); + this._populateOpenDrawingSubMenu(); + }); + }); + + this.openDrawingSubMenuItem.setSensitive(!this.openDrawingSubMenu.isEmpty()); + }, + + _addSaveDrawingSubMenuItem: function(menu) { + let item = new PopupMenu.PopupSubMenuMenuItem(_("Save drawing"), true); + this.saveDrawingSubMenuItem = item; + this._updateSaveDrawingSubMenuItemSensitivity(); + this.saveDrawingSubMenu = item.menu; + item.icon.set_icon_name('document-save-symbolic'); + + item.menu.itemActivated = () => { + item.menu.close(); + }; + + Mainloop.timeout_add(0, () => { + this._populateSaveDrawingSubMenu(); + return GLib.SOURCE_REMOVE; + }); + menu.addMenuItem(item); + }, + + _updateSaveDrawingSubMenuItemSensitivity: function() { + this.saveDrawingSubMenuItem.setSensitive(this.area.elements.length > 0); + }, + + _populateSaveDrawingSubMenu: function() { + this.saveEntry = new DrawingMenuEntry({ initialTextGetter: getDateString, + entryActivateCallback: (text) => { + this.area.saveAsJsonWithName(text); + this.saveDrawingSubMenu.toggle(); + this._updateDrawingNameMenuItem(); + this._populateOpenDrawingSubMenu(); + }, + invalidStrings: [DEFAULT_FILE_NAME, '/'], + primaryIconName: 'insert-text' }); + this.saveDrawingSubMenu.addMenuItem(this.saveEntry.item); + }, + _addSeparator: function(menu) { let separatorItem = new PopupMenu.PopupSeparatorMenuItem(' '); getActor(separatorItem).add_style_class_name('draw-on-your-screen-menu-separator-item'); @@ -1284,3 +1483,87 @@ var DrawingMenu = new Lang.Class({ } }); +// based on searchItem.js, https://github.com/leonardo-bartoli/gnome-shell-extension-Recents +var DrawingMenuEntry = new Lang.Class({ + Name: 'DrawOnYourScreenDrawingMenuEntry', + + _init: function (params) { + this.params = params; + this.item = new PopupMenu.PopupBaseMenuItem({ style_class: 'draw-on-your-screen-menu-entry-item', + activate: false, + reactive: true, + can_focus: false }); + + this.itemActor = GS_VERSION < '3.33.0' ? this.item.actor : this.item; + + this.entry = new St.Entry({ + style_class: 'search-entry draw-on-your-screen-menu-entry', + track_hover: true, + reactive: true, + can_focus: true + }); + + this.entry.set_primary_icon(new St.Icon({ style_class: 'search-entry-icon', + icon_name: this.params.primaryIconName })); + + this.entry.clutter_text.connect('text-changed', this._onTextChanged.bind(this)); + this.entry.clutter_text.connect('activate', this._onTextActivated.bind(this)); + + this.clearIcon = new St.Icon({ + style_class: 'search-entry-icon', + icon_name: 'edit-clear-symbolic' + }); + this.entry.connect('secondary-icon-clicked', this._reset.bind(this)); + + getActor(this.item).add(this.entry, { expand: true }); + getActor(this.item).connect('notify::mapped', (actor) => { + if (actor.mapped) { + this.entry.set_text(this.params.initialTextGetter()); + this.entry.clutter_text.grab_key_focus(); + } + }); + }, + + _setError: function(hasError) { + if (hasError) + this.entry.add_style_class_name('draw-on-your-screen-menu-entry-error'); + else + this.entry.remove_style_class_name('draw-on-your-screen-menu-entry-error'); + }, + + _reset: function() { + this.entry.text = ''; + this.entry.clutter_text.set_cursor_visible(true); + this.entry.clutter_text.set_selection(0, 0); + this._setError(false); + }, + + _onTextActivated: function(clutterText) { + let text = clutterText.get_text(); + if (text.length == 0) + return; + if (this._getIsInvalid()) + return; + this._reset(); + this.params.entryActivateCallback(text); + }, + + _onTextChanged: function(clutterText) { + let text = clutterText.get_text(); + this.entry.set_secondary_icon(text.length ? this.clearIcon : null); + + if (text.length) + this._setError(this._getIsInvalid()); + }, + + _getIsInvalid: function() { + for (let i = 0; i < this.params.invalidStrings.length; i++) { + if (this.entry.text.indexOf(this.params.invalidStrings[i]) != -1) + return true; + } + + return false; + } +}); + + diff --git a/extension.js b/extension.js index 635c99a..7e83e57 100644 --- a/extension.js +++ b/extension.js @@ -113,7 +113,7 @@ var AreaManager = new Lang.Class({ onPersistentSettingChanged: function() { if (this.settings.get_boolean('persistent-drawing')) - this.areas[Main.layoutManager.primaryIndex].saveAsJson(); + this.areas[Main.layoutManager.primaryIndex].savePersistent(); }, updateIndicator: function() { @@ -136,8 +136,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 load = i == Main.layoutManager.primaryIndex && this.settings.get_boolean('persistent-drawing'); - let area = new Draw.DrawingArea({ name: 'drawOnYourSreenArea' + i }, monitor, helper, load); + let loadPersistent = i == Main.layoutManager.primaryIndex && this.settings.get_boolean('persistent-drawing'); + let area = new Draw.DrawingArea({ name: 'drawOnYourSreenArea' + i }, monitor, helper, loadPersistent); container.add_child(area); container.add_child(helper); @@ -161,6 +161,9 @@ var AreaManager = new Lang.Class({ 'delete-last-element': this.activeArea.deleteLastElement.bind(this.activeArea), 'smooth-last-element': this.activeArea.smoothLastElement.bind(this.activeArea), 'save-as-svg': this.activeArea.saveAsSvg.bind(this.activeArea), + 'save-as-json': this.activeArea.saveAsJson.bind(this.activeArea), + 'open-previous-json': this.activeArea.loadPreviousJson.bind(this.activeArea), + 'open-next-json': this.activeArea.loadNextJson.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,7 +226,7 @@ var AreaManager = new Lang.Class({ for (let i = 0; i < this.areas.length; i++) this.areas[i].erase(); if (this.settings.get_boolean('persistent-drawing')) - this.areas[Main.layoutManager.primaryIndex].saveAsJson(); + this.areas[Main.layoutManager.primaryIndex].savePersistent(); }, togglePanelAndDockOpacity: function() { diff --git a/locale/draw-on-your-screen.pot b/locale/draw-on-your-screen.pot index e579156..d19a5a8 100644 --- a/locale/draw-on-your-screen.pot +++ b/locale/draw-on-your-screen.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Draw On Your Screen VERSION\n" "Report-Msgid-Bugs-To: https://framagit.org/abakkk/DrawOnYourScreen/issues\n" -"POT-Creation-Date: 2019-03-04 16:40+0100\n" +"POT-Creation-Date: 2020-01-03 08:00+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -108,6 +108,12 @@ msgstr "" msgid "Color" msgstr "" +msgid "Open drawing" +msgstr "" + +msgid "Save drawing" +msgstr "" + #: prefs.js msgid "Preferences" @@ -196,6 +202,16 @@ msgstr "" msgid "Square drawing area" msgstr "" +msgid "Open previous drawing" +msgstr "" + +msgid "Open next drawing" +msgstr "" + +# already in draw.js +#msgid "Save drawing" +#msgstr "" + msgid "Save drawing as a SVG file" msgstr "" diff --git a/prefs.js b/prefs.js index 2488cf3..6ec03a4 100644 --- a/prefs.js +++ b/prefs.js @@ -68,6 +68,9 @@ var INTERNAL_KEYBINDINGS = { 'toggle-background': "Add a drawing background", 'toggle-square-area': "Square drawing area", '-separator-5': '', + 'open-previous-json': "Open previous drawing", + 'open-next-json': "Open next drawing", + 'save-as-json': "Save drawing", 'save-as-svg': "Save drawing as a SVG file", 'open-stylesheet': "Open stylesheet.css", 'toggle-help': "Show help" diff --git a/schemas/gschemas.compiled b/schemas/gschemas.compiled index 329554d6b23e75f72fdb56ab41f68bcf99307d8f..563aa40844035c1a4d1fb15785f43c11b6d3142f 100644 GIT binary patch literal 3492 zcmZ`+U2GIp6dsf+e}(cR7N`pN!xorbN+}dmt0+=HOo{~4_#mC#xw|{O5kN^>h8lvSvLrh5eq!=}U#2Ac9crdYvLHxeiJ3G5&-Q?r@dgjc% z=bn4+xkJaZhHDv)uc==>xT~mRw<+5s@Z`%wEo456Yn!!U@R=G-tGP?lZsPY|EezT= zZ3O%gAl*zn!?H&2h5e9MH3>qlI?rnXvB%zXkOE)7(HiHT{o+KL_@0ZTN+D z>Upq_fqw^%eQ~3Xc53=F*)_n?lS?J-)YD7)d>-uvSX{VkA zdl%ROM!L_YX{VcB@Yle}r;qNXoq96-$G}&ChQAwJ+NqiUac~`q%-+81 zQQD~&z`hFH0X#nN=NRqOwXk=A2Y?@sEeY~Q&AbhRj{w)s#9yR8HT{o+&jC-Uaj0n@ z178P5U)VRDXNFk}(m~ z6*c$$68LA}?Q`2taUANouwMt)Oow6N_cv&#=6=V_|zQ#F>p6fcx2~E`crcs z2f(ia9m=1Y{)fSz0h^Vbn)VCetH2gzr>1=zT#p04RoSU&kAXJ>qiJhC=cVSly1}~v zf6v8@v{N&lVek>)`LE8~v{Un3oC2Q*{>m*5_K}+VI0pU|sJra`OMhzS2a{{Hz@i23 z2X#fwx~c~^0&m{D@+tkPIZi8h3vj_d@CohIL7ZS8IPvYldfKTO&oG#M))Tf!`MQgL z3@2j?-OCzz0Z07WI$bMgxP$F3rid9{qc1abNlVAq(?-s+2P^&3m411{5w>nPrf$kq zuij^QR?@O9zxYxC-{;R(O=T&m}4 z(;SIltL;}_`KegAsFab9*4>OY&uoB??7~Y8u(2IekK>3{*!{5APaRh=N@63CF*}yWO5x5VS4@?5kLbQhf zv@jl*;4bDJk1Hp*Ps^6yBP}Ode^0pnoRof6n8>v&d$Ad)D_58j@AFs6d)tnzmG;|* zup;iFXY`?xyi(y!^z)RT<=k3UdQQ6PctzuP8X2)`XC4a;hA$q;l(ePWR1pX2uqk@0 zNt?N#qN*(0u8iAI>lCixiRk#WZLt0JwjBi=t#*NoPn>jhFiP3_G4JYV-qqo}@w^e7 zlLS7{62S*rBKSZ{L?390Dj#SGbRAW}!5W)O`NKTT(LBxJJk^fp|L1X|>~~Oh6Bo6n zay@IJdDfKXDfSnBPnyE(^<`cqf_32qwW8aG=j+%Yc8gNn0?oy)>^D)b!n|eqHml^j zrAoeAqWD_E_*Bw-Hodar8hQF*U6)nR+RAmWjl9=R7&q9Ab%>?3F6_s;=&yCv{97mZ zw?_W0)%@2_@LwPKuMhppubF-k^ztA>rMUXlI+bJ6NcCo1S#XM%Ml@owG9UQAgO$fY z2y<5&PgIU)8Xnt!G!71mB~A1f7L|$Q`l6x`g6QxK6+A(!q#L5SrH>4S@u&vk_3<)` n=JC|?;BL#iqR*0rsLe!v+eF$|byTg#l-7m)+hB%q7lZr{MBgWG literal 3256 zcmZu!U2GIp7#)ymp@8LA3RMe=Y{A*hQVOl96|_P{Ng#+pAE2{4cXx-*&MY&t{R0V6 z5;2MqeUKQ5H73FX2{i$t#z=iJ#Ds(=gy;h#nrNb=4?dU}#B*lv&d+u?IXNe1zq$9j z-@SA1oo%mZj-gqeB7e)kdn-CIQ+hMNvu=%blKEd!=~s?}2O1QmVTq#L!|%(vFqD^+ z3*fH++sP;MmR%G{w;)V2DMmbDxrS}IN!`(gRohZW?Xsh~Sw{$q&nk&0eNvSBz{LGP zBQOVO0@%fTU;(fQSRBDpXyPHDMPfPl;RqguCfb0Nz$%Hyz{KNquo~VPpdDB%u?}3t z_`szcO5oRGfik3wpeAnv%JQG?(x;ve{}lKf@#BeQ^r;uap9EhAj%;uJl|D87DR2`C z@a)K6*XUEvgTD;i1$=Pt_C@;CP4N4{uL94>cxuKMz{i1)zTGv!c^ zlRou>@UMVx0)4U_YPRz`xbXo+d0zU|em>wXV5{`0>Gy*Rz~H|ft!$rqA^fA@lfX6^ zPtEvo@FdVLeQNsGz*B&C=xQI^p=O;Mu`pVIsq63TqEF2_C&1mnygysNqfgCo^@Dc+ zFUa<(+5Q0dD6n1n)b!s6PXG<+FXpfv>ZS0nfN#==$#qZ7b^iJr{=h>fNui(E`M**r}ozacm`gCw?12YgFbZ|;uGL* z;QWr$hv`$#g1;HO7g*8qsqa(M9{?W&-cw(@%6Mwl=P39j@bSBc?$D=Z{%65o1Cu#p zDSc}C*TA=d)8|*&^r^WHr@%AuvK~1$@d&%?NHM{4n6^xyY@drpPKET1z!f5Z#nyZvFXDHXGoGVmJ!OgikW4jeo3@jV zwwn&KO)K+TD#6;2P&HR|hw}09xN zyqsPaqi|3-M`-@=!bq!5-W%h2Zw#Y1R@;r1c~eauo5J`_)p(glM#~Q79lLDll{CW0 zOng1E##yZt{y$jF)1NS*tFGtRgILyyOnWq$uA1?oj$L6ZUDbS|k961M-yOzx*Tg$` zsWgi(jC`qr`FCV~Xp46Up7T!tJm1>^-f30?JnMNk;C+Gjh7|ygTwrgq1W>(qG(+>q;N1kq8=T8ibfHI4c+(|UWQTC|Zq+QnoVcCZguc5~i#b>R+rHgdqc8kTNkHP3dUv+MiQw{4k9 zJdZskEVfGWrtrk{ZByyP^m_u!l2P&{^Kc2D_P%)WI{9_?r-!48%%36Sgri|ORgbCI zIVI#dl`LtVUlcr_!iPZ0{}4#|9|EcHLm*Y>Lm-6{Q*Kc?!!#rPYqEboD@FMq=~4Bg 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 9864222..58fa1ad 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 @@ -206,6 +206,21 @@ Save drawing as a svg file Save drawing as a svg file + + ["<Primary><Shift>s"] + Save drawing as a json file + Save drawing as a json file + + + ["<Primary>Left"] + Open previous json file + Open previous json file + + + ["<Primary>Right"] + Open next json file + Open next json file + ["<Primary>F1"] toggle help diff --git a/stylesheet.css b/stylesheet.css index 3e96dd6..6437e87 100644 --- a/stylesheet.css +++ b/stylesheet.css @@ -115,5 +115,29 @@ min-width: 3em; text-align: right; } + +.draw-on-your-screen-menu-entry-item { + padding-right: 1.15em; /* default 1.75em */ + spacing: 0; /* default 12px */ +} + +.draw-on-your-screen-menu-entry { + border: none; + border-radius: 3px; + padding: 0.35em 0.57em; + width: 10em; +} + +.draw-on-your-screen-menu-entry-error { + color: #f57900; /* upstream warning_color */ +} + +.draw-on-your-screen-menu-entry:focus { + padding: 0.35em 0.57em; +} + +.draw-on-your-screen-menu-delete-button:hover { + color: #f57900; +}