group menu items at the bottom

In addition, 'Save as a SVG file' -> "Export to a SVG file'.
This commit is contained in:
abakkk 2020-09-16 22:12:54 +02:00
parent f9e25fa8f6
commit 072adde856
8 changed files with 124 additions and 81 deletions

View File

@ -1139,7 +1139,7 @@ var DrawingArea = new Lang.Class({
return [getGiconSvgContent, getImageSvgContent]; return [getGiconSvgContent, getImageSvgContent];
}, },
saveAsSvg: function() { exportToSvg: function() {
// stop drawing or writing // stop drawing or writing
if (this.currentElement && this.currentElement.shape == Shapes.TEXT && this.isWriting) { if (this.currentElement && this.currentElement.shape == Shapes.TEXT && this.isWriting) {
this._stopWriting(); this._stopWriting();
@ -1204,8 +1204,8 @@ var DrawingArea = new Lang.Class({
this._saveAsJson(Files.Jsons.getNamed(name), false, callback); this._saveAsJson(Files.Jsons.getNamed(name), false, callback);
}, },
saveAsJson: function() { saveAsJson: function(notify, callback) {
this._saveAsJson(Files.Jsons.getDated(), true); this._saveAsJson(Files.Jsons.getDated(), notify, callback);
}, },
savePersistent: function() { savePersistent: function() {

View File

@ -200,8 +200,8 @@ const AreaManager = new Lang.Class({
// available when writing // available when writing
this.internalKeybindings2 = { this.internalKeybindings2 = {
'save-as-svg': this.activeArea.saveAsSvg.bind(this.activeArea), 'export-to-svg': this.activeArea.exportToSvg.bind(this.activeArea),
'save-as-json': this.activeArea.saveAsJson.bind(this.activeArea), 'save-as-json': this.activeArea.saveAsJson.bind(this.activeArea, true, null),
'open-previous-json': this.activeArea.loadPreviousJson.bind(this.activeArea), 'open-previous-json': this.activeArea.loadPreviousJson.bind(this.activeArea),
'open-next-json': this.activeArea.loadNextJson.bind(this.activeArea), 'open-next-json': this.activeArea.loadNextJson.bind(this.activeArea),
'toggle-background': this.activeArea.toggleBackground.bind(this.activeArea), 'toggle-background': this.activeArea.toggleBackground.bind(this.activeArea),

View File

@ -10,7 +10,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Draw On Your Screen\n" "Project-Id-Version: Draw On Your Screen\n"
"Report-Msgid-Bugs-To: https://framagit.org/abakkk/DrawOnYourScreen/issues\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" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -272,13 +272,19 @@ msgstr ""
msgid "Smooth" msgid "Smooth"
msgstr "" msgstr ""
msgid "Open drawing"
msgstr ""
msgid "Save drawing as…"
msgstr ""
msgid "Palette" msgid "Palette"
msgstr "" msgstr ""
msgid "Color" msgid "Color"
msgstr "" msgstr ""
msgid "Open drawing" msgid "Type a name"
msgstr "" msgstr ""
#. Translators: "Preferences" page in preferences #. Translators: "Preferences" page in preferences
@ -535,6 +541,9 @@ msgstr ""
msgid "Erase last brushstroke" msgid "Erase last brushstroke"
msgstr "" msgstr ""
msgid "Export drawing to a SVG file"
msgstr ""
msgid "Increment line width" msgid "Increment line width"
msgstr "" msgstr ""
@ -559,9 +568,6 @@ msgstr ""
msgid "Save drawing" msgid "Save drawing"
msgstr "" msgstr ""
msgid "Save drawing as a SVG file"
msgstr ""
msgid "Select color 1" msgid "Select color 1"
msgstr "" msgstr ""

127
menu.js
View File

@ -30,6 +30,7 @@ const St = imports.gi.St;
const BoxPointer = imports.ui.boxpointer; const BoxPointer = imports.ui.boxpointer;
const Config = imports.misc.config; const Config = imports.misc.config;
const Dash = imports.ui.dash;
const Main = imports.ui.main; const Main = imports.ui.main;
const PopupMenu = imports.ui.popupMenu; const PopupMenu = imports.ui.popupMenu;
const Slider = imports.ui.slider; const Slider = imports.ui.slider;
@ -221,12 +222,17 @@ var DrawingMenu = new Lang.Class({
_redisplay: function() { _redisplay: function() {
this.menu.removeAll(); this.menu.removeAll();
this.actionButtons = [];
let groupItem = new PopupMenu.PopupBaseMenuItem({ reactive: false, can_focus: false, style_class: 'draw-on-your-screen-menu-group-item' }); 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')); this.undoButton = new ActionButton(_("Undo"), 'edit-undo-symbolic', this.area.undo.bind(this.area), this._updateActionSensitivity.bind(this));
getActor(groupItem).add_child(this._createActionButton(_("Redo"), this.area.redo.bind(this.area), 'edit-redo-symbolic')); this.redoButton = new ActionButton(_("Redo"), 'edit-redo-symbolic', this.area.redo.bind(this.area), this._updateActionSensitivity.bind(this));
getActor(groupItem).add_child(this._createActionButton(_("Erase"), this.area.deleteLastElement.bind(this.area), 'edit-clear-all-symbolic')); this.eraseButton = new ActionButton(_("Erase"), 'edit-clear-all-symbolic', this.area.deleteLastElement.bind(this.area), this._updateActionSensitivity.bind(this));
getActor(groupItem).add_child(this._createActionButton(_("Smooth"), this.area.smoothLastElement.bind(this.area), Files.Icons.SMOOTH)); 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.menu.addMenuItem(groupItem);
this._addSeparator(this.menu, true); this._addSeparator(this.menu, true);
@ -275,40 +281,33 @@ var DrawingMenu = new Lang.Class({
this._addSeparator(this.menu); this._addSeparator(this.menu);
this._addDrawingNameItem(this.menu); this._addDrawingNameItem(this.menu);
this._addOpenDrawingSubMenuItem(this.menu, 'document-open-symbolic'); this._addOpenDrawingSubMenuItem(this.menu, _("Open drawing"), 'document-open-symbolic');
this._addSaveDrawingSubMenuItem(this.menu, 'document-save-as-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); groupItem = new PopupMenu.PopupBaseMenuItem({ reactive: false, can_focus: false, style_class: 'draw-on-your-screen-menu-group-item' });
this.menu.addAction(getSummary('open-preferences'), areaManager.openPreferences.bind(areaManager), 'document-page-setup-symbolic'); this.saveButton = new ActionButton(getSummary('save-as-json'), 'document-save-symbolic', this.area.saveAsJson.bind(this.area, false, this._onDrawingSaved.bind(this)), null);
this.menu.addAction(getSummary('toggle-help'), () => { this.close(); this.area.toggleHelp(); }, 'preferences-desktop-keyboard-shortcuts-symbolic'); 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._updateActionSensitivity();
this._updateSectionVisibility(); 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() { _updateActionSensitivity: function() {
let [undoButton, redoButton, eraseButton, smoothButton] = this.actionButtons; this.undoButton.child.reactive = this.area.elements.length > 0;
undoButton.reactive = this.area.elements.length > 0; this.redoButton.child.reactive = this.area.undoneElements.length > 0;
redoButton.reactive = this.area.undoneElements.length > 0; this.eraseButton.child.reactive = this.area.elements.length > 0;
eraseButton.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;
smoothButton.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() { _updateSectionVisibility: function() {
@ -577,8 +576,8 @@ var DrawingMenu = new Lang.Class({
} }
}, },
_addOpenDrawingSubMenuItem: function(menu, icon) { _addOpenDrawingSubMenuItem: function(menu, label, icon) {
let item = new PopupMenu.PopupSubMenuMenuItem(_("Open drawing"), true); let item = new PopupMenu.PopupSubMenuMenuItem(label, true);
this.openDrawingSubMenuItem = item; this.openDrawingSubMenuItem = item;
this.openDrawingSubMenu = item.menu; this.openDrawingSubMenu = item.menu;
item.setSensitive(Boolean(Files.Jsons.getSorted().length)); item.setSensitive(Boolean(Files.Jsons.getSorted().length));
@ -605,7 +604,7 @@ var DrawingMenu = new Lang.Class({
let subItem = this.openDrawingSubMenu.addAction(`<i>${String(json)}</i>`, () => { let subItem = this.openDrawingSubMenu.addAction(`<i>${String(json)}</i>`, () => {
this.area.loadJson(json); this.area.loadJson(json);
this._updateDrawingNameMenuItem(); this._updateDrawingNameMenuItem();
this._updateSaveDrawingSubMenuItemSensitivity(); this._updateActionSensitivity();
}, json.gicon); }, json.gicon);
subItem.label.get_clutter_text().set_use_markup(true); subItem.label.get_clutter_text().set_use_markup(true);
@ -617,7 +616,7 @@ var DrawingMenu = new Lang.Class({
}); });
getActor(subItem).add_child(expander); 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', child: new St.Icon({ icon_name: 'insert-image-symbolic',
style_class: 'popup-menu-icon' }) }); style_class: 'popup-menu-icon' }) });
getActor(subItem).add_child(insertButton); getActor(subItem).add_child(insertButton);
@ -630,7 +629,7 @@ var DrawingMenu = new Lang.Class({
this._updateSectionVisibility(); 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', child: new St.Icon({ icon_name: 'edit-delete-symbolic',
style_class: 'popup-menu-icon' }) }); style_class: 'popup-menu-icon' }) });
getActor(subItem).add_child(deleteButton); getActor(subItem).add_child(deleteButton);
@ -645,10 +644,9 @@ var DrawingMenu = new Lang.Class({
this.openDrawingSubMenuItem.setSensitive(!this.openDrawingSubMenu.isEmpty()); this.openDrawingSubMenuItem.setSensitive(!this.openDrawingSubMenu.isEmpty());
}, },
_addSaveDrawingSubMenuItem: function(menu, icon) { _addSaveDrawingSubMenuItem: function(menu, label, icon) {
let item = new PopupMenu.PopupSubMenuMenuItem(getSummary('save-as-json'), true); let item = new PopupMenu.PopupSubMenuMenuItem(label, true);
this.saveDrawingSubMenuItem = item; this.saveDrawingSubMenuItem = item;
this._updateSaveDrawingSubMenuItemSensitivity();
this.saveDrawingSubMenu = item.menu; this.saveDrawingSubMenu = item.menu;
item.icon.set_icon_name(icon); item.icon.set_icon_name(icon);
@ -674,7 +672,8 @@ var DrawingMenu = new Lang.Class({
_populateSaveDrawingSubMenu: function() { _populateSaveDrawingSubMenu: function() {
this.saveDrawingSubMenu.removeAll(); this.saveDrawingSubMenu.removeAll();
let saveEntry = new DrawingMenuEntry({ initialTextGetter: Files.getDateString, let saveEntry = new Entry({ initialTextGetter: () => this.area.currentJson ? this.area.currentJson.name : "",
hint_text: _("Type a name"),
entryActivateCallback: (text) => { entryActivateCallback: (text) => {
this.area.saveAsJsonWithName(text, this._onDrawingSaved.bind(this)); this.area.saveAsJsonWithName(text, this._onDrawingSaved.bind(this));
this.saveDrawingSubMenu.toggle(); this.saveDrawingSubMenu.toggle();
@ -712,8 +711,51 @@ const updateSubMenuAdjustment = function(itemActor) {
adjustment.set_value(newScrollValue); 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 // 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', Name: 'DrawOnYourScreenDrawingMenuEntry',
_init: function(params) { _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.itemActor = GS_VERSION < '3.33.0' ? this.item.actor : this.item;
this.entry = new St.Entry({ this.entry = new St.Entry({
hint_text: params.hint_text || "",
style_class: 'search-entry draw-on-your-screen-menu-entry', style_class: 'search-entry draw-on-your-screen-menu-entry',
track_hover: true, track_hover: true,
reactive: true, reactive: true,

Binary file not shown.

View File

@ -131,6 +131,10 @@
<default>["Delete"]</default> <default>["Delete"]</default>
<summary>Erase last brushstroke</summary> <summary>Erase last brushstroke</summary>
</key> </key>
<key type="as" name="export-to-svg">
<default>["&lt;Primary&gt;&lt;Alt&gt;s"]</default>
<summary>Export drawing to a SVG file</summary>
</key>
<key type="as" name="increment-line-width"> <key type="as" name="increment-line-width">
<default><![CDATA[['<Primary>KP_Add','<Primary><Shift>plus']]]></default> <default><![CDATA[['<Primary>KP_Add','<Primary><Shift>plus']]]></default>
<summary>Increment line width</summary> <summary>Increment line width</summary>
@ -163,10 +167,6 @@
<default>["&lt;Primary&gt;s"]</default> <default>["&lt;Primary&gt;s"]</default>
<summary>Save drawing</summary> <summary>Save drawing</summary>
</key> </key>
<key type="as" name="save-as-svg">
<default>["&lt;Primary&gt;&lt;Alt&gt;s"]</default>
<summary>Save drawing as a SVG file</summary>
</key>
<key type="as" name="select-color1"> <key type="as" name="select-color1">
<default><![CDATA[['<Primary>KP_1','<Primary>1']]]></default> <default><![CDATA[['<Primary>KP_1','<Primary>1']]]></default>
<summary>Select color 1</summary> <summary>Select color 1</summary>

View File

@ -52,7 +52,7 @@ var INTERNAL_KEYBINDINGS = [
['switch-font-family', 'switch-font-family-reverse', 'switch-font-weight', 'switch-font-style', 'switch-text-alignment'], ['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'], ['switch-image-file', 'switch-image-file-reverse', 'paste-image-files'],
['toggle-panel-and-dock-visibility', 'toggle-background', 'toggle-grid', 'toggle-square-area'], ['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') { if (GS_VERSION < '3.36') {

View File

@ -76,23 +76,20 @@
margin-top: 0; margin-top: 0;
} }
/* system-menu-action: from GS 3.34- */ .draw-on-your-screen-menu-destructive-button:hover {
.draw-on-your-screen-menu .system-menu-action { color: #e01b24; /* upstream destructive color, light: #e01b24, dark: #b2161d */
}
/* override .button upstream style class */
.draw-on-your-screen-menu-action-button {
min-height: 0;
min-width: 0; min-width: 0;
border: none;
border-radius: 32px; border-radius: 32px;
padding: 12px; padding: 12px;
margin: 0;
} }
.draw-on-your-screen-menu .system-menu-action:hover, .draw-on-your-screen-menu-action-button > StIcon {
.draw-on-your-screen-menu .system-menu-action:focus { icon-size: 1em;
border: none;
padding: 12px;
}
.draw-on-your-screen-menu .system-menu-action > StIcon {
icon-size: 16px;
} }
.draw-on-your-screen-menu-slider-label { .draw-on-your-screen-menu-slider-label {
@ -120,16 +117,13 @@
padding: 0.35em 0.57em; 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; min-height: 1px;
padding: 2px 4px; /* default 3px 24px */ padding: 2px 4px; /* default 3px 24px */
} }
.draw-on-your-screen-menu-delete-button:hover { .draw-on-your-screen-menu-inline-button .popup-menu-icon {
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 {
icon-size: 0.85em; /* default 1.09 */ icon-size: 0.85em; /* default 1.09 */
} }