From 072adde856b6628b756f116b5f0972ea52a5ac6c Mon Sep 17 00:00:00 2001 From: abakkk Date: Wed, 16 Sep 2020 22:12:54 +0200 Subject: [PATCH] group menu items at the bottom In addition, 'Save as a SVG file' -> "Export to a SVG file'. --- area.js | 6 +- extension.js | 4 +- locale/draw-on-your-screen.pot | 16 +- menu.js | 139 ++++++++++++------ schemas/gschemas.compiled | Bin 7384 -> 7376 bytes ...extensions.draw-on-your-screen.gschema.xml | 8 +- shortcuts.js | 2 +- stylesheet.css | 30 ++-- 8 files changed, 124 insertions(+), 81 deletions(-) diff --git a/area.js b/area.js index 0556a75..61dc879 100644 --- a/area.js +++ b/area.js @@ -1139,7 +1139,7 @@ var DrawingArea = new Lang.Class({ return [getGiconSvgContent, getImageSvgContent]; }, - saveAsSvg: function() { + exportToSvg: function() { // stop drawing or writing if (this.currentElement && this.currentElement.shape == Shapes.TEXT && this.isWriting) { this._stopWriting(); @@ -1204,8 +1204,8 @@ var DrawingArea = new Lang.Class({ this._saveAsJson(Files.Jsons.getNamed(name), false, callback); }, - saveAsJson: function() { - this._saveAsJson(Files.Jsons.getDated(), true); + saveAsJson: function(notify, callback) { + this._saveAsJson(Files.Jsons.getDated(), notify, callback); }, savePersistent: function() { diff --git a/extension.js b/extension.js index ca34b88..c7d9b42 100644 --- a/extension.js +++ b/extension.js @@ -200,8 +200,8 @@ const AreaManager = new Lang.Class({ // available when writing this.internalKeybindings2 = { - 'save-as-svg': this.activeArea.saveAsSvg.bind(this.activeArea), - 'save-as-json': this.activeArea.saveAsJson.bind(this.activeArea), + 'export-to-svg': this.activeArea.exportToSvg.bind(this.activeArea), + 'save-as-json': this.activeArea.saveAsJson.bind(this.activeArea, true, null), '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), diff --git a/locale/draw-on-your-screen.pot b/locale/draw-on-your-screen.pot index e4f93a3..231ace4 100644 --- a/locale/draw-on-your-screen.pot +++ b/locale/draw-on-your-screen.pot @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: Draw On Your Screen\n" "Report-Msgid-Bugs-To: https://framagit.org/abakkk/DrawOnYourScreen/issues\n" -"POT-Creation-Date: 2020-09-11 03:43+0200\n" +"POT-Creation-Date: 2020-09-16 21:11+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -272,13 +272,19 @@ msgstr "" msgid "Smooth" msgstr "" +msgid "Open drawing" +msgstr "" + +msgid "Save drawing as…" +msgstr "" + msgid "Palette" msgstr "" msgid "Color" msgstr "" -msgid "Open drawing" +msgid "Type a name" msgstr "" #. Translators: "Preferences" page in preferences @@ -535,6 +541,9 @@ msgstr "" msgid "Erase last brushstroke" msgstr "" +msgid "Export drawing to a SVG file" +msgstr "" + msgid "Increment line width" msgstr "" @@ -559,9 +568,6 @@ msgstr "" msgid "Save drawing" msgstr "" -msgid "Save drawing as a SVG file" -msgstr "" - msgid "Select color 1" msgstr "" diff --git a/menu.js b/menu.js index 2e4f536..86a6032 100644 --- a/menu.js +++ b/menu.js @@ -30,6 +30,7 @@ const St = imports.gi.St; const BoxPointer = imports.ui.boxpointer; const Config = imports.misc.config; +const Dash = imports.ui.dash; const Main = imports.ui.main; const PopupMenu = imports.ui.popupMenu; const Slider = imports.ui.slider; @@ -221,12 +222,17 @@ var DrawingMenu = new Lang.Class({ _redisplay: function() { this.menu.removeAll(); - this.actionButtons = []; let groupItem = new PopupMenu.PopupBaseMenuItem({ reactive: false, can_focus: false, style_class: 'draw-on-your-screen-menu-group-item' }); - getActor(groupItem).add_child(this._createActionButton(_("Undo"), this.area.undo.bind(this.area), 'edit-undo-symbolic')); - getActor(groupItem).add_child(this._createActionButton(_("Redo"), this.area.redo.bind(this.area), 'edit-redo-symbolic')); - getActor(groupItem).add_child(this._createActionButton(_("Erase"), this.area.deleteLastElement.bind(this.area), 'edit-clear-all-symbolic')); - getActor(groupItem).add_child(this._createActionButton(_("Smooth"), this.area.smoothLastElement.bind(this.area), Files.Icons.SMOOTH)); + this.undoButton = new ActionButton(_("Undo"), 'edit-undo-symbolic', this.area.undo.bind(this.area), this._updateActionSensitivity.bind(this)); + this.redoButton = new ActionButton(_("Redo"), 'edit-redo-symbolic', this.area.redo.bind(this.area), this._updateActionSensitivity.bind(this)); + this.eraseButton = new ActionButton(_("Erase"), 'edit-clear-all-symbolic', this.area.deleteLastElement.bind(this.area), this._updateActionSensitivity.bind(this)); + this.smoothButton = new ActionButton(_("Smooth"), Files.Icons.SMOOTH, this.area.smoothLastElement.bind(this.area), this._updateActionSensitivity.bind(this)); + this.eraseButton.child.add_style_class_name('draw-on-your-screen-menu-destructive-button'); + this.smoothButton.child.add_style_class_name('draw-on-your-screen-menu-destructive-button'); + getActor(groupItem).add_child(this.undoButton); + getActor(groupItem).add_child(this.redoButton); + getActor(groupItem).add_child(this.eraseButton); + getActor(groupItem).add_child(this.smoothButton); this.menu.addMenuItem(groupItem); this._addSeparator(this.menu, true); @@ -275,40 +281,33 @@ var DrawingMenu = new Lang.Class({ this._addSeparator(this.menu); this._addDrawingNameItem(this.menu); - this._addOpenDrawingSubMenuItem(this.menu, 'document-open-symbolic'); - this._addSaveDrawingSubMenuItem(this.menu, 'document-save-as-symbolic'); + this._addOpenDrawingSubMenuItem(this.menu, _("Open drawing"), 'document-open-symbolic'); + this._addSaveDrawingSubMenuItem(this.menu, _("Save drawing as…"), 'document-save-as-symbolic'); + this._addSeparator(this.menu); - this.menu.addAction(getSummary('save-as-svg'), this.area.saveAsSvg.bind(this.area), Files.Icons.DOCUMENT_EXPORT); - this.menu.addAction(getSummary('open-preferences'), areaManager.openPreferences.bind(areaManager), 'document-page-setup-symbolic'); - this.menu.addAction(getSummary('toggle-help'), () => { this.close(); this.area.toggleHelp(); }, 'preferences-desktop-keyboard-shortcuts-symbolic'); + groupItem = new PopupMenu.PopupBaseMenuItem({ reactive: false, can_focus: false, style_class: 'draw-on-your-screen-menu-group-item' }); + this.saveButton = new ActionButton(getSummary('save-as-json'), 'document-save-symbolic', this.area.saveAsJson.bind(this.area, false, this._onDrawingSaved.bind(this)), null); + this.svgButton = new ActionButton(getSummary('export-to-svg'), Files.Icons.DOCUMENT_EXPORT, this.area.exportToSvg.bind(this.area), null); + this.prefsButton = new ActionButton(getSummary('open-preferences'), 'document-page-setup-symbolic', areaManager.openPreferences.bind(areaManager), null); + this.helpButton = new ActionButton(getSummary('toggle-help'), 'preferences-desktop-keyboard-shortcuts-symbolic', () => { this.close(); this.area.toggleHelp(); }, null); + getActor(groupItem).add_child(this.saveButton); + getActor(groupItem).add_child(this.svgButton); + getActor(groupItem).add_child(this.prefsButton); + getActor(groupItem).add_child(this.helpButton); + this.menu.addMenuItem(groupItem); this._updateActionSensitivity(); this._updateSectionVisibility(); }, - // from system.js (GS 3.34-) - _createActionButton: function(accessibleName, callback, icon) { - let button = new St.Button({ track_hover: true, - x_align: Clutter.ActorAlign.CENTER, - accessible_name: accessibleName, - // use 'popup-menu' and 'popup-menu-item' style classes to provide theme colors - style_class: 'system-menu-action popup-menu-item popup-menu' }); - button.child = new St.Icon(typeof icon == 'string' ? { icon_name: icon } : { gicon: icon }); - button.connect('clicked', () => { - callback(); - this._updateActionSensitivity(); - }); - button.bind_property('reactive', button, 'can_focus', GObject.BindingFlags.DEFAULT); - this.actionButtons.push(button); - return new St.Bin({ child: button, x_expand: true }); - }, - _updateActionSensitivity: function() { - let [undoButton, redoButton, eraseButton, smoothButton] = this.actionButtons; - undoButton.reactive = this.area.elements.length > 0; - redoButton.reactive = this.area.undoneElements.length > 0; - eraseButton.reactive = this.area.elements.length > 0; - smoothButton.reactive = this.area.elements.length > 0 && this.area.elements[this.area.elements.length - 1].shape == this.drawingTools.NONE; + this.undoButton.child.reactive = this.area.elements.length > 0; + this.redoButton.child.reactive = this.area.undoneElements.length > 0; + this.eraseButton.child.reactive = this.area.elements.length > 0; + this.smoothButton.child.reactive = this.area.elements.length > 0 && this.area.elements[this.area.elements.length - 1].shape == this.drawingTools.NONE; + this.saveButton.child.reactive = this.area.elements.length > 0; + this.svgButton.child.reactive = this.area.elements.length > 0; + this.saveDrawingSubMenuItem.setSensitive(this.area.elements.length > 0); }, _updateSectionVisibility: function() { @@ -577,8 +576,8 @@ var DrawingMenu = new Lang.Class({ } }, - _addOpenDrawingSubMenuItem: function(menu, icon) { - let item = new PopupMenu.PopupSubMenuMenuItem(_("Open drawing"), true); + _addOpenDrawingSubMenuItem: function(menu, label, icon) { + let item = new PopupMenu.PopupSubMenuMenuItem(label, true); this.openDrawingSubMenuItem = item; this.openDrawingSubMenu = item.menu; item.setSensitive(Boolean(Files.Jsons.getSorted().length)); @@ -605,7 +604,7 @@ var DrawingMenu = new Lang.Class({ let subItem = this.openDrawingSubMenu.addAction(`${String(json)}`, () => { this.area.loadJson(json); this._updateDrawingNameMenuItem(); - this._updateSaveDrawingSubMenuItemSensitivity(); + this._updateActionSensitivity(); }, json.gicon); subItem.label.get_clutter_text().set_use_markup(true); @@ -617,7 +616,7 @@ var DrawingMenu = new Lang.Class({ }); getActor(subItem).add_child(expander); - let insertButton = new St.Button({ style_class: 'button draw-on-your-screen-menu-insert-button', + let insertButton = new St.Button({ style_class: 'button draw-on-your-screen-menu-inline-button', child: new St.Icon({ icon_name: 'insert-image-symbolic', style_class: 'popup-menu-icon' }) }); getActor(subItem).add_child(insertButton); @@ -630,7 +629,7 @@ var DrawingMenu = new Lang.Class({ this._updateSectionVisibility(); }); - let deleteButton = new St.Button({ style_class: 'button draw-on-your-screen-menu-delete-button', + let deleteButton = new St.Button({ style_class: 'button draw-on-your-screen-menu-inline-button draw-on-your-screen-menu-destructive-button', child: new St.Icon({ icon_name: 'edit-delete-symbolic', style_class: 'popup-menu-icon' }) }); getActor(subItem).add_child(deleteButton); @@ -645,10 +644,9 @@ var DrawingMenu = new Lang.Class({ this.openDrawingSubMenuItem.setSensitive(!this.openDrawingSubMenu.isEmpty()); }, - _addSaveDrawingSubMenuItem: function(menu, icon) { - let item = new PopupMenu.PopupSubMenuMenuItem(getSummary('save-as-json'), true); + _addSaveDrawingSubMenuItem: function(menu, label, icon) { + let item = new PopupMenu.PopupSubMenuMenuItem(label, true); this.saveDrawingSubMenuItem = item; - this._updateSaveDrawingSubMenuItemSensitivity(); this.saveDrawingSubMenu = item.menu; item.icon.set_icon_name(icon); @@ -674,13 +672,14 @@ var DrawingMenu = new Lang.Class({ _populateSaveDrawingSubMenu: function() { this.saveDrawingSubMenu.removeAll(); - let saveEntry = new DrawingMenuEntry({ initialTextGetter: Files.getDateString, - entryActivateCallback: (text) => { - this.area.saveAsJsonWithName(text, this._onDrawingSaved.bind(this)); - this.saveDrawingSubMenu.toggle(); - }, - invalidStrings: [Me.metadata['persistent-file-name'], '/'], - primaryIconName: 'insert-text' }); + let saveEntry = new Entry({ initialTextGetter: () => this.area.currentJson ? this.area.currentJson.name : "", + hint_text: _("Type a name"), + entryActivateCallback: (text) => { + this.area.saveAsJsonWithName(text, this._onDrawingSaved.bind(this)); + this.saveDrawingSubMenu.toggle(); + }, + invalidStrings: [Me.metadata['persistent-file-name'], '/'], + primaryIconName: 'insert-text' }); this.saveDrawingSubMenu.addMenuItem(saveEntry.item); }, @@ -712,8 +711,51 @@ const updateSubMenuAdjustment = function(itemActor) { adjustment.set_value(newScrollValue); }; +// An action button that uses upstream dash item tooltips. +const ActionButton = new Lang.Class({ + Name: 'DrawOnYourScreenDrawingMenuActionButton', + Extends: St.Bin, + _labelShowing: false, + _resetHoverTimeoutId: 0, + _showLabelTimeoutId: 0, + showLabel: Dash.DashItemContainer.prototype.showLabel, + hideLabel: Dash.DashItemContainer.prototype.hideLabel, + _syncLabel: Dash.Dash.prototype._syncLabel, + + _init: function(name, icon, callback, callbackAfter) { + this._labelText = name; + + let button = new St.Button({ track_hover: true, + x_align: Clutter.ActorAlign.CENTER, + accessible_name: name, + // use 'popup-menu' and 'popup-menu-item' style classes to provide theme colors + //style_class: 'system-menu-action popup-menu-item popup-menu' }); + style_class: 'button draw-on-your-screen-menu-action-button' }); + button.child = new St.Icon(typeof icon == 'string' ? { icon_name: icon } : { gicon: icon }); + button.connect('clicked', () => { + callback(); + if (callbackAfter) + callbackAfter(); + }); + button.bind_property('reactive', button, 'can_focus', GObject.BindingFlags.DEFAULT); + button.connect('notify::hover', () => this._syncLabel(this)); + + this.parent({ child: button, x_expand: true }); + }, + + get label() { + if (!this._label) { + this._label = new St.Label({ style_class: 'dash-label' }); + Main.layoutManager.uiGroup.add_actor(this._label); + this.connect('destroy', () => this._label.destroy()); + } + + return this._label; + } +}); + // based on searchItem.js, https://github.com/leonardo-bartoli/gnome-shell-extension-Recents -const DrawingMenuEntry = new Lang.Class({ +const Entry = new Lang.Class({ Name: 'DrawOnYourScreenDrawingMenuEntry', _init: function(params) { @@ -726,6 +768,7 @@ const DrawingMenuEntry = new Lang.Class({ this.itemActor = GS_VERSION < '3.33.0' ? this.item.actor : this.item; this.entry = new St.Entry({ + hint_text: params.hint_text || "", style_class: 'search-entry draw-on-your-screen-menu-entry', track_hover: true, reactive: true, diff --git a/schemas/gschemas.compiled b/schemas/gschemas.compiled index 9271c1aa9324aa634c237e58b1de25474f22fd4f..53d5dbc4d661ccc3f82e74be45e90f97d3df8a5e 100644 GIT binary patch delta 1528 zcmaKsZ)j6j7{=eU)_-Z5HmOZ+ykIN0*gE1YwVN4QQ?1&T39VMBGB&ds(_l0;xvg<( zqo8d51MvvTOW`Uj)msg6^fUifFPco;kM&1V90lEVRyP4BFkoQ4{Kx@b4 zR_63}Q}2e zgQT#+Dy$0h)ZM>mD2MYyo1xY^XZzno&fCsIpMdiA`L7MN&#KxyB2}CnS`RMW>&hA` zV^y~!VgEkpA>f=jY#8d1RUJjbH<^WwgYO@n^BU@n(^J?-bG)x6y@2G(vLV;_1hGzC2cTCG0x z>@)03i`>S=Myo*2LLT}j_-NgCpRf@w!kW zW@|h>$ETpfz)T;0RM>dD;7YU5aqxG?y_IZ4??gTU{SCBPjp*5E8d|Q4ta|1i<#>Ab zse?9yc56I6$9F>eL5G#s@`8n9&=HU~&*a#Mp8M%GbV4<`y44MrCzp5Ku{DNM{qcn9 zH{<@~U_@k1XCk^UlsMG9rX^-JC-I!>Ldp8%!Km5W=iePl_MuzuY~__=)#df5uy`UGt{9RnrFdM zIG&#KRD-spVijBySOM_)N{I?-ZrcJipe@_VGqe~~1MDkl1UT4m0EsjJZqk*Y7SsWr zw>+EixriB$L}FooBoW>H-~C3^UC(0mOtW98bm#28vLe;42Z~pVs9N1nnr^oR)Jc8Y EzfGtk;{X5v delta 1568 zcmaKsVQ5=b7=};UPOE8_Hr?7J2Dg@8Y?aK7t+Ul`Yqe@u94u^uBBBdzOzYBhCRtpa zTRRw7Q9*ZvO=zK2kTKL&f>LGD?OzoJl_>;7*+73dEY?4EFtt8!dZ+&kJiPCHzk9!P z?#a1lp|#LD(_Yb0YK*zVXOmf|~C(_Ed!(aky#;7*l0(W-l6tZ-3tRvU2%K z@?+?0aAxKDr^@BMQ#9It$M{ z6#YWE{Ce_*>O;m{=i=n)nQ;~5Lln$9W9s3?;qX=E@*21W-3_l!-Cs~Hzmfb1dI~zb z$2*nFYlYrIKY*q4sTIebSX&!Xm9ZIs*G4vZsZpo`-59u zCechPYmBLbp2oR%9P9Hx=yB{0|7!nF$n|>j=#NmjyZn}82i>Zt)|eWNjyA#Bi?JEU zPPo+rB*i60hrz#myuq;n?c9^<*zO7qq5-Y-xfqSLHOzVA-%7> zR-+w_!O8B(Ps-)B4*lo_c=Xuff^vBu`7Bz1K+Vx>%H_2!mQYW~m^G}$3P1b^<)=&; zVF6OH=XMnzz-uXQqU*!PJmwA{uK^m-E|{2Jov6Gf+Jn9TM|T{URv&o{Jc_;zoo*j_ z^_dJa{v|FRcMI|=ETBuUeb8FN6|^hjvT*I+<3asOlQ%r;Lq-ho7G6(PhLQOfiAa^yc*p^gAq2go68p`gm%HU zU#q8z6T++iK{N;5?){D~^uQQ;9_F*J=kH>483V#m)umnvXC< zBFYq!iRkkKsYGVA!+$MuYza+?ydHGCmfFQ&t*-&61GgMXtS_{|*@|n1O~6-QJf3-P z;{pBHujXzW3*FbIgSZSf0-Mup15QV?2DSh@+-!zAXapVFI^g-{jQu9GA^%&bzQleW V_Ig_Eo=AhOinNxtQaTaY_YV-vD6jwk 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 b90abe1..9568ed4 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 @@ -131,6 +131,10 @@ ["Delete"] Erase last brushstroke + + ["<Primary><Alt>s"] + Export drawing to a SVG file + KP_Add','plus']]]> Increment line width @@ -163,10 +167,6 @@ ["<Primary>s"] Save drawing - - ["<Primary><Alt>s"] - Save drawing as a SVG file - KP_1','1']]]> Select color 1 diff --git a/shortcuts.js b/shortcuts.js index 5a04a67..ac66815 100644 --- a/shortcuts.js +++ b/shortcuts.js @@ -52,7 +52,7 @@ var INTERNAL_KEYBINDINGS = [ ['switch-font-family', 'switch-font-family-reverse', 'switch-font-weight', 'switch-font-style', 'switch-text-alignment'], ['switch-image-file', 'switch-image-file-reverse', 'paste-image-files'], ['toggle-panel-and-dock-visibility', 'toggle-background', 'toggle-grid', 'toggle-square-area'], - ['open-next-json', 'open-previous-json', 'save-as-json', 'save-as-svg', 'open-preferences', 'toggle-help'], + ['open-next-json', 'open-previous-json', 'save-as-json', 'export-to-svg', 'open-preferences', 'toggle-help'], ]; if (GS_VERSION < '3.36') { diff --git a/stylesheet.css b/stylesheet.css index 0170137..768f8ca 100644 --- a/stylesheet.css +++ b/stylesheet.css @@ -76,23 +76,20 @@ margin-top: 0; } -/* system-menu-action: from GS 3.34- */ -.draw-on-your-screen-menu .system-menu-action { - min-width: 0; - border: none; - border-radius: 32px; - padding: 12px; - margin: 0; +.draw-on-your-screen-menu-destructive-button:hover { + color: #e01b24; /* upstream destructive color, light: #e01b24, dark: #b2161d */ } -.draw-on-your-screen-menu .system-menu-action:hover, -.draw-on-your-screen-menu .system-menu-action:focus { - border: none; +/* override .button upstream style class */ +.draw-on-your-screen-menu-action-button { + min-height: 0; + min-width: 0; + border-radius: 32px; padding: 12px; } -.draw-on-your-screen-menu .system-menu-action > StIcon { - icon-size: 16px; +.draw-on-your-screen-menu-action-button > StIcon { + icon-size: 1em; } .draw-on-your-screen-menu-slider-label { @@ -120,16 +117,13 @@ padding: 0.35em 0.57em; } -.draw-on-your-screen-menu-delete-button, .draw-on-your-screen-menu-insert-button { +/* override .button upstream style class */ +.draw-on-your-screen-menu-inline-button { min-height: 1px; padding: 2px 4px; /* default 3px 24px */ } -.draw-on-your-screen-menu-delete-button:hover { - color: #e01b24; /* upstream destructive color, light: #e01b24, dark: #b2161d */ -} - -.draw-on-your-screen-menu-delete-button .popup-menu-icon, .draw-on-your-screen-menu-insert-button .popup-menu-icon { +.draw-on-your-screen-menu-inline-button .popup-menu-icon { icon-size: 0.85em; /* default 1.09 */ }