2019-03-05 08:36:59 -03:00
|
|
|
/* jslint esversion: 6 */
|
2020-09-07 13:56:48 -03:00
|
|
|
/* exported DisplayStrings, DrawingMenu */
|
2019-03-05 08:36:59 -03:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Copyright 2019 Abakkk
|
|
|
|
|
*
|
2019-12-28 09:25:41 -03:00
|
|
|
* This file is part of DrawOnYourScreen, a drawing extension for GNOME Shell.
|
2019-03-05 08:36:59 -03:00
|
|
|
* https://framagit.org/abakkk/DrawOnYourScreen
|
|
|
|
|
*
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
const Clutter = imports.gi.Clutter;
|
|
|
|
|
const GLib = imports.gi.GLib;
|
2019-03-26 18:28:24 -03:00
|
|
|
const GObject = imports.gi.GObject;
|
2019-03-05 08:36:59 -03:00
|
|
|
const Gtk = imports.gi.Gtk;
|
|
|
|
|
const Lang = imports.lang;
|
|
|
|
|
const St = imports.gi.St;
|
2019-03-26 18:28:24 -03:00
|
|
|
|
|
|
|
|
const BoxPointer = imports.ui.boxpointer;
|
2019-10-11 04:22:37 -03:00
|
|
|
const Config = imports.misc.config;
|
2019-03-26 18:28:24 -03:00
|
|
|
const Main = imports.ui.main;
|
|
|
|
|
const PopupMenu = imports.ui.popupMenu;
|
|
|
|
|
const Slider = imports.ui.slider;
|
2019-03-05 08:36:59 -03:00
|
|
|
|
|
|
|
|
const ExtensionUtils = imports.misc.extensionUtils;
|
2020-01-05 11:44:51 -03:00
|
|
|
const Me = ExtensionUtils.getCurrentExtension();
|
2020-08-04 21:00:20 -03:00
|
|
|
const Files = Me.imports.files;
|
2020-01-06 11:29:01 -03:00
|
|
|
const _ = imports.gettext.domain(Me.metadata['gettext-domain']).gettext;
|
2020-09-08 15:11:57 -03:00
|
|
|
const pgettext = imports.gettext.domain(Me.metadata['gettext-domain']).pgettext;
|
2019-03-05 08:36:59 -03:00
|
|
|
|
2019-10-11 04:22:37 -03:00
|
|
|
const GS_VERSION = Config.PACKAGE_VERSION;
|
2020-08-05 18:30:25 -03:00
|
|
|
// 150 labels with font-family style take ~15Mo
|
|
|
|
|
const FONT_FAMILY_STYLE = true;
|
2020-08-31 06:05:33 -03:00
|
|
|
// use 'login-dialog-message-warning' class in order to get GS theme warning color (default: #f57900)
|
|
|
|
|
const WARNING_COLOR_STYLE_CLASS_NAME = 'login-dialog-message-warning';
|
2020-08-05 18:30:25 -03:00
|
|
|
|
2020-03-02 12:32:50 -03:00
|
|
|
const getActor = function(object) {
|
2020-01-01 21:38:57 -03:00
|
|
|
return GS_VERSION < '3.33.0' ? object.actor : object;
|
2020-03-02 12:32:50 -03:00
|
|
|
};
|
2020-01-01 21:38:57 -03:00
|
|
|
|
2020-09-01 08:43:30 -03:00
|
|
|
const getSummary = function(settingKey) {
|
|
|
|
|
return Me.internalShortcutSettings.settings_schema.get_key(settingKey).get_summary();
|
|
|
|
|
};
|
|
|
|
|
|
2020-09-07 13:56:48 -03:00
|
|
|
// Used by both menu and osd notifications.
|
|
|
|
|
var DisplayStrings = {
|
|
|
|
|
getDashedLine: function(dashed) {
|
2020-09-08 15:11:57 -03:00
|
|
|
return dashed ? _("Dashed line") :
|
|
|
|
|
// Translators: as the alternative to "Dashed line"
|
|
|
|
|
_("Full line");
|
2020-09-07 13:56:48 -03:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getFill: function(fill) {
|
2020-09-08 15:11:57 -03:00
|
|
|
return fill ? _("Fill") :
|
|
|
|
|
// Translators: as the alternative to "Fill"
|
|
|
|
|
_("Outline");
|
2020-09-07 13:56:48 -03:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
get FillRule() {
|
|
|
|
|
if (!this._fillRules)
|
2020-09-08 15:11:57 -03:00
|
|
|
// Translators: fill-rule SVG attribute
|
2020-09-07 13:56:48 -03:00
|
|
|
this._fillRules = { 0: _("Nonzero"), 1: _("Evenodd") };
|
|
|
|
|
return this._fillRules;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getFontFamily: function(family) {
|
|
|
|
|
if (!this._fontGenericFamilies)
|
2020-09-08 15:11:57 -03:00
|
|
|
// Translators: generic font-family SVG attribute
|
|
|
|
|
this._fontGenericFamilies = { 'Sans-Serif': pgettext("font-family", "Sans-Serif"), 'Serif': pgettext("font-family", "Serif"),
|
|
|
|
|
'Monospace': pgettext("font-family", "Monospace"), 'Cursive': pgettext("font-family", "Cursive"),
|
|
|
|
|
'Fantasy': pgettext("font-family", "Fantasy") };
|
2020-09-07 13:56:48 -03:00
|
|
|
return this._fontGenericFamilies[family] || family;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
get FontStyle() {
|
|
|
|
|
if (!this._fontStyles)
|
2020-09-08 15:11:57 -03:00
|
|
|
// Translators: font-style SVG attribute
|
|
|
|
|
this._fontStyles = { 0: pgettext("font-style", "Normal"), 1: pgettext("font-style", "Oblique"), 2: pgettext("font-style", "Italic") };
|
2020-09-07 13:56:48 -03:00
|
|
|
return this._fontStyles;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
FontStyleMarkup: { 0: 'normal', 1: 'oblique', 2: 'italic' },
|
|
|
|
|
|
|
|
|
|
get FontWeight() {
|
|
|
|
|
if (!this._fontWeights)
|
2020-09-08 15:11:57 -03:00
|
|
|
// Translators: font-weight SVG attribute
|
|
|
|
|
this._fontWeights = { 100: pgettext("font-weight", "Thin"), 200: pgettext("font-weight", "Ultra Light"), 300: pgettext("font-weight", "Light"),
|
|
|
|
|
350: pgettext("font-weight", "Semi Light"), 380: pgettext("font-weight", "Book"), 400: pgettext("font-weight", "Normal"),
|
|
|
|
|
500: pgettext("font-weight", "Medium"), 600: pgettext("font-weight", "Semi Bold"), 700: pgettext("font-weight", "Bold"),
|
|
|
|
|
800: pgettext("font-weight", "Ultra Bold"), 900: pgettext("font-weight", "Heavy"), 1000: pgettext("font-weight", "Ultra Heavy") };
|
2020-09-07 13:56:48 -03:00
|
|
|
return this._fontWeights;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
get LineCap() {
|
|
|
|
|
if (!this._lineCaps)
|
2020-09-08 15:11:57 -03:00
|
|
|
// Translators: stroke-linecap SVG attribute
|
|
|
|
|
this._lineCaps = { 0: pgettext("stroke-linecap", "Butt"), 1: pgettext("stroke-linecap", "Round"), 2: pgettext("stroke-linecap", "Square") };
|
2020-09-07 13:56:48 -03:00
|
|
|
return this._lineCaps;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
get LineJoin() {
|
|
|
|
|
if (!this._lineJoins)
|
2020-09-08 15:11:57 -03:00
|
|
|
// Translators: stroke-linejoin SVG attribute
|
|
|
|
|
this._lineJoins = { 0: pgettext("stroke-linejoin", "Miter"), 1: pgettext("stroke-linejoin", "Round"), 2: pgettext("stroke-linejoin", "Bevel") };
|
2020-09-07 13:56:48 -03:00
|
|
|
return this._lineJoins;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getPixels(value) {
|
2020-09-08 15:11:57 -03:00
|
|
|
// Translators: value in pixel unit (e.g. "5 px")
|
|
|
|
|
return _("%f px").format(value);
|
2020-09-07 13:56:48 -03:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getTextAlignment: function(rightAligned) {
|
2020-09-08 15:11:57 -03:00
|
|
|
// Translators: text alignment
|
2020-09-07 13:56:48 -03:00
|
|
|
return rightAligned ? _("Right aligned") : _("Left aligned");
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
get Tool() {
|
|
|
|
|
if (!this._tools)
|
2020-09-08 15:11:57 -03:00
|
|
|
this._tools = { 0: pgettext("drawing-tool", "Free drawing"), 1: pgettext("drawing-tool", "Line"), 2: pgettext("drawing-tool", "Ellipse"),
|
|
|
|
|
3: pgettext("drawing-tool", "Rectangle"), 4: pgettext("drawing-tool", "Text"), 5: pgettext("drawing-tool", "Polygon"),
|
|
|
|
|
6: pgettext("drawing-tool", "Polyline"), 7: pgettext("drawing-tool", "Image"),
|
|
|
|
|
100: pgettext("drawing-tool", "Move"), 101: pgettext("drawing-tool", "Resize"), 102: pgettext("drawing-tool", "Mirror") };
|
2020-09-07 13:56:48 -03:00
|
|
|
return this._tools;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-07-03 17:51:23 -03:00
|
|
|
var DrawingMenu = new Lang.Class({
|
2019-03-26 18:28:24 -03:00
|
|
|
Name: 'DrawOnYourScreenDrawingMenu',
|
|
|
|
|
|
2020-09-07 13:56:48 -03:00
|
|
|
_init: function(area, monitor, drawingTools) {
|
2019-03-26 18:28:24 -03:00
|
|
|
this.area = area;
|
2020-09-07 13:56:48 -03:00
|
|
|
this.drawingTools = drawingTools;
|
|
|
|
|
|
2019-03-26 18:28:24 -03:00
|
|
|
let side = Clutter.get_default_text_direction() == Clutter.TextDirection.RTL ? St.Side.RIGHT : St.Side.LEFT;
|
|
|
|
|
this.menu = new PopupMenu.PopupMenu(Main.layoutManager.dummyCursor, 0.25, side);
|
2019-10-11 04:22:37 -03:00
|
|
|
this.menuManager = new PopupMenu.PopupMenuManager(GS_VERSION < '3.33.0' ? { actor: this.area } : this.area);
|
2019-03-26 18:28:24 -03:00
|
|
|
this.menuManager.addMenu(this.menu);
|
|
|
|
|
|
|
|
|
|
Main.layoutManager.uiGroup.add_actor(this.menu.actor);
|
|
|
|
|
this.menu.actor.add_style_class_name('background-menu draw-on-your-screen-menu');
|
2019-12-29 11:26:20 -03:00
|
|
|
this.menu.actor.set_style('max-height:' + monitor.height + 'px;');
|
2019-03-26 18:28:24 -03:00
|
|
|
this.menu.actor.hide();
|
2020-06-05 17:45:11 -03:00
|
|
|
this.hasSeparators = monitor.height >= 750;
|
2019-03-26 18:28:24 -03:00
|
|
|
|
|
|
|
|
// do not close the menu on item activated
|
|
|
|
|
this.menu.itemActivated = () => {};
|
|
|
|
|
this.menu.connect('open-state-changed', this._onMenuOpenStateChanged.bind(this));
|
2019-03-29 12:35:18 -03:00
|
|
|
|
2020-01-05 08:36:42 -03:00
|
|
|
// Case where the menu is closed (escape key) while the save entry clutter_text is active:
|
|
|
|
|
// St.Entry clutter_text set the DEFAULT cursor on leave event with a delay and
|
|
|
|
|
// overrides the cursor set by area.updatePointerCursor().
|
|
|
|
|
// In order to update drawing cursor on menu closed, we need to leave the saveEntry before closing menu.
|
|
|
|
|
// Since escape key press event can't be captured easily, the job is done in the menu close function.
|
|
|
|
|
let menuCloseFunc = this.menu.close;
|
|
|
|
|
this.menu.close = (animate) => {
|
2020-02-09 12:43:21 -03:00
|
|
|
if (this.saveDrawingSubMenu && this.saveDrawingSubMenu.isOpen)
|
2020-01-05 08:36:42 -03:00
|
|
|
this.saveDrawingSubMenu.close();
|
|
|
|
|
menuCloseFunc.bind(this.menu)(animate);
|
|
|
|
|
};
|
2019-03-26 18:28:24 -03:00
|
|
|
},
|
|
|
|
|
|
2019-03-27 10:23:34 -03:00
|
|
|
disable: function() {
|
2020-09-07 13:56:48 -03:00
|
|
|
delete this.area;
|
|
|
|
|
delete this.drawingTools;
|
2019-03-27 10:23:34 -03:00
|
|
|
this.menuManager.removeMenu(this.menu);
|
|
|
|
|
Main.layoutManager.uiGroup.remove_actor(this.menu.actor);
|
2020-06-22 09:38:42 -03:00
|
|
|
this.menu.destroy();
|
2019-03-27 10:23:34 -03:00
|
|
|
},
|
|
|
|
|
|
2019-03-26 18:28:24 -03:00
|
|
|
_onMenuOpenStateChanged: function(menu, open) {
|
2019-11-27 02:04:37 -03:00
|
|
|
if (open) {
|
|
|
|
|
this.area.setPointerCursor('DEFAULT');
|
|
|
|
|
} else {
|
|
|
|
|
this.area.updatePointerCursor();
|
2019-03-26 18:28:24 -03:00
|
|
|
// actionMode has changed, set previous actionMode in order to keep internal shortcuts working
|
2020-06-25 06:41:15 -03:00
|
|
|
this.area.updateActionMode();
|
2020-01-05 08:36:42 -03:00
|
|
|
this.area.grab_key_focus();
|
2019-11-27 02:04:37 -03:00
|
|
|
}
|
2019-03-26 18:28:24 -03:00
|
|
|
},
|
|
|
|
|
|
2019-03-27 10:23:34 -03:00
|
|
|
popup: function() {
|
|
|
|
|
if (this.menu.isOpen) {
|
|
|
|
|
this.close();
|
|
|
|
|
} else {
|
|
|
|
|
this.open();
|
|
|
|
|
this.menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2019-03-26 18:28:24 -03:00
|
|
|
open: function(x, y) {
|
2019-03-27 10:23:34 -03:00
|
|
|
if (this.menu.isOpen)
|
|
|
|
|
return;
|
|
|
|
|
if (x === undefined || y === undefined)
|
|
|
|
|
[x, y] = [this.area.monitor.x + this.area.monitor.width / 2, this.area.monitor.y + this.area.monitor.height / 2];
|
2019-03-26 18:28:24 -03:00
|
|
|
this._redisplay();
|
|
|
|
|
Main.layoutManager.setDummyCursorGeometry(x, y, 0, 0);
|
|
|
|
|
let monitor = this.area.monitor;
|
|
|
|
|
this.menu._arrowAlignment = (y - monitor.y) / monitor.height;
|
|
|
|
|
this.menu.open(BoxPointer.PopupAnimation.NONE);
|
|
|
|
|
this.menuManager.ignoreRelease();
|
|
|
|
|
},
|
|
|
|
|
|
2019-03-27 10:23:34 -03:00
|
|
|
close: function() {
|
|
|
|
|
if (this.menu.isOpen)
|
|
|
|
|
this.menu.close();
|
|
|
|
|
},
|
|
|
|
|
|
2019-03-26 18:28:24 -03:00
|
|
|
_redisplay: function() {
|
|
|
|
|
this.menu.removeAll();
|
|
|
|
|
|
2020-07-13 07:53:01 -03:00
|
|
|
this.actionButtons = [];
|
2020-09-01 08:43:30 -03:00
|
|
|
let groupItem = new PopupMenu.PopupBaseMenuItem({ reactive: false, can_focus: false, style_class: 'draw-on-your-screen-menu-group-item' });
|
2020-08-07 19:27:41 -03:00
|
|
|
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'));
|
2020-09-10 10:19:17 -03:00
|
|
|
getActor(groupItem).add_child(this._createActionButton(_("Smooth"), this.area.smoothLastElement.bind(this.area), Files.Icons.SMOOTH));
|
2020-07-11 15:41:04 -03:00
|
|
|
this.menu.addMenuItem(groupItem);
|
|
|
|
|
this._addSeparator(this.menu, true);
|
2019-03-26 18:28:24 -03:00
|
|
|
|
2020-09-14 17:44:20 -03:00
|
|
|
this.toolItem = this._addToolSubMenuItem(this.menu, this._updateSectionVisibility.bind(this));
|
2020-09-11 20:25:37 -03:00
|
|
|
this.paletteItem = this._addPaletteSubMenuItem(this.menu, Files.Icons.PALETTE);
|
|
|
|
|
this.colorItem = this._addColorSubMenuItem(this.menu, Files.Icons.COLOR);
|
2020-09-10 10:19:17 -03:00
|
|
|
this.fillItem = this._addSwitchItem(this.menu, DisplayStrings.getFill(true), Files.Icons.STROKE, Files.Icons.FILL, this.area, 'fill', this._updateSectionVisibility.bind(this));
|
2020-06-08 15:50:23 -03:00
|
|
|
this.fillSection = new PopupMenu.PopupMenuSection();
|
2020-06-27 08:40:34 -03:00
|
|
|
this.fillSection.itemActivated = () => {};
|
2020-09-10 10:19:17 -03:00
|
|
|
this.fillRuleItem = this._addSwitchItem(this.fillSection, DisplayStrings.FillRule[1], Files.Icons.FILLRULE_NONZERO, Files.Icons.FILLRULE_EVENODD, this.area, 'currentEvenodd');
|
2020-06-08 15:50:23 -03:00
|
|
|
this.menu.addMenuItem(this.fillSection);
|
2019-03-27 18:11:51 -03:00
|
|
|
this._addSeparator(this.menu);
|
2019-03-26 18:28:24 -03:00
|
|
|
|
2019-03-27 18:11:51 -03:00
|
|
|
let lineSection = new PopupMenu.PopupMenuSection();
|
|
|
|
|
this._addSliderItem(lineSection, this.area, 'currentLineWidth');
|
2020-09-10 10:19:17 -03:00
|
|
|
this._addSubMenuItem(lineSection, Files.Icons.LINEJOIN, DisplayStrings.LineJoin, this.area, 'currentLineJoin');
|
|
|
|
|
this._addSubMenuItem(lineSection, Files.Icons.LINECAP, DisplayStrings.LineCap, this.area, 'currentLineCap');
|
|
|
|
|
this._addSwitchItem(lineSection, DisplayStrings.getDashedLine(true), Files.Icons.FULL_LINE, Files.Icons.DASHED_LINE, this.area, 'dashedLine');
|
2019-03-27 18:11:51 -03:00
|
|
|
this._addSeparator(lineSection);
|
|
|
|
|
this.menu.addMenuItem(lineSection);
|
2019-03-28 11:26:10 -03:00
|
|
|
lineSection.itemActivated = () => {};
|
2019-03-27 18:11:51 -03:00
|
|
|
this.lineSection = lineSection;
|
2019-03-26 18:28:24 -03:00
|
|
|
|
2019-03-27 18:11:51 -03:00
|
|
|
let fontSection = new PopupMenu.PopupMenuSection();
|
2020-09-11 20:25:37 -03:00
|
|
|
this._addFontFamilySubMenuItem(fontSection, Files.Icons.FONT_FAMILY);
|
|
|
|
|
this._addSubMenuItem(fontSection, Files.Icons.FONT_WEIGHT, DisplayStrings.FontWeight, this.area, 'currentFontWeight');
|
|
|
|
|
this._addSubMenuItem(fontSection, Files.Icons.FONT_STYLE, DisplayStrings.FontStyle, this.area, 'currentFontStyle');
|
|
|
|
|
this._addSwitchItem(fontSection, DisplayStrings.getTextAlignment(true), Files.Icons.LEFT_ALIGNED, Files.Icons.RIGHT_ALIGNED, this.area, 'currentTextRightAligned');
|
2019-03-27 18:11:51 -03:00
|
|
|
this._addSeparator(fontSection);
|
|
|
|
|
this.menu.addMenuItem(fontSection);
|
2020-06-27 10:10:01 -03:00
|
|
|
fontSection.itemActivated = () => {};
|
2019-03-27 18:11:51 -03:00
|
|
|
this.fontSection = fontSection;
|
2019-03-26 18:28:24 -03:00
|
|
|
|
2020-07-30 06:13:23 -03:00
|
|
|
let imageSection = new PopupMenu.PopupMenuSection();
|
2020-09-14 17:44:20 -03:00
|
|
|
this.imageItem = this._addImageSubMenuItem(imageSection);
|
2020-07-30 06:13:23 -03:00
|
|
|
this._addSeparator(imageSection);
|
|
|
|
|
this.menu.addMenuItem(imageSection);
|
|
|
|
|
imageSection.itemActivated = () => {};
|
|
|
|
|
this.imageSection = imageSection;
|
|
|
|
|
|
2020-08-31 08:05:41 -03:00
|
|
|
let areaManager = Me.stateObj.areaManager;
|
2020-09-01 08:43:30 -03:00
|
|
|
this._addSimpleSwitchItem(this.menu, getSummary('toggle-panel-and-dock-visibility'), !!areaManager.hiddenList, areaManager.togglePanelAndDockOpacity.bind(areaManager));
|
|
|
|
|
this._addSimpleSwitchItem(this.menu, getSummary('toggle-background'), this.area.hasBackground, this.area.toggleBackground.bind(this.area));
|
|
|
|
|
this._addSimpleSwitchItem(this.menu, getSummary('toggle-grid'), this.area.hasGrid, this.area.toggleGrid.bind(this.area));
|
|
|
|
|
this._addSimpleSwitchItem(this.menu, getSummary('toggle-square-area'), this.area.isSquareArea, this.area.toggleSquareArea.bind(this.area));
|
2019-03-27 18:11:51 -03:00
|
|
|
this._addSeparator(this.menu);
|
2019-03-26 18:28:24 -03:00
|
|
|
|
2020-01-03 20:16:20 -03:00
|
|
|
this._addDrawingNameItem(this.menu);
|
2020-09-11 20:25:37 -03:00
|
|
|
this._addOpenDrawingSubMenuItem(this.menu, Files.Icons.OPEN);
|
|
|
|
|
this._addSaveDrawingSubMenuItem(this.menu, Files.Icons.SAVE);
|
2020-01-03 20:16:20 -03:00
|
|
|
|
2020-09-01 08:43:30 -03:00
|
|
|
this.menu.addAction(getSummary('save-as-svg'), this.area.saveAsSvg.bind(this.area), 'image-x-generic-symbolic');
|
|
|
|
|
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');
|
2019-03-27 18:11:51 -03:00
|
|
|
|
2020-07-13 07:53:01 -03:00
|
|
|
this._updateActionSensitivity();
|
2020-06-08 15:50:23 -03:00
|
|
|
this._updateSectionVisibility();
|
2019-03-27 18:11:51 -03:00
|
|
|
},
|
|
|
|
|
|
2020-07-11 15:41:04 -03:00
|
|
|
// from system.js (GS 3.34-)
|
|
|
|
|
_createActionButton: function(accessibleName, callback, icon) {
|
2020-07-13 07:53:01 -03:00
|
|
|
let button = new St.Button({ track_hover: true,
|
2020-07-11 15:41:04 -03:00
|
|
|
x_align: Clutter.ActorAlign.CENTER,
|
|
|
|
|
accessible_name: accessibleName,
|
2020-07-13 07:53:01 -03:00
|
|
|
// use 'popup-menu' and 'popup-menu-item' style classes to provide theme colors
|
|
|
|
|
style_class: 'system-menu-action popup-menu-item popup-menu' });
|
2020-07-11 15:41:04 -03:00
|
|
|
button.child = new St.Icon(typeof icon == 'string' ? { icon_name: icon } : { gicon: icon });
|
2020-07-13 07:53:01 -03:00
|
|
|
button.connect('clicked', () => {
|
|
|
|
|
callback();
|
|
|
|
|
this._updateActionSensitivity();
|
|
|
|
|
});
|
|
|
|
|
button.bind_property('reactive', button, 'can_focus', GObject.BindingFlags.DEFAULT);
|
|
|
|
|
this.actionButtons.push(button);
|
2020-07-11 15:41:04 -03:00
|
|
|
return new St.Bin({ child: button, x_expand: true });
|
|
|
|
|
},
|
|
|
|
|
|
2020-07-13 07:53:01 -03:00
|
|
|
_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;
|
2020-09-07 13:56:48 -03:00
|
|
|
smoothButton.reactive = this.area.elements.length > 0 && this.area.elements[this.area.elements.length - 1].shape == this.drawingTools.NONE;
|
2020-07-13 07:53:01 -03:00
|
|
|
},
|
|
|
|
|
|
2020-06-08 15:50:23 -03:00
|
|
|
_updateSectionVisibility: function() {
|
2020-09-07 13:56:48 -03:00
|
|
|
let [isText, isImage] = [this.area.currentTool == this.drawingTools.TEXT, this.area.currentTool == this.drawingTools.IMAGE];
|
2020-07-30 06:13:23 -03:00
|
|
|
this.lineSection.actor.visible = !isText && !isImage;
|
|
|
|
|
this.fontSection.actor.visible = isText;
|
|
|
|
|
this.imageSection.actor.visible = isImage;
|
|
|
|
|
this.colorItem.setSensitive(!isImage);
|
2020-08-31 04:43:00 -03:00
|
|
|
this.paletteItem.setSensitive(!isImage);
|
2020-07-30 06:13:23 -03:00
|
|
|
this.fillItem.setSensitive(!isText && !isImage);
|
|
|
|
|
this.fillSection.setSensitive(!isText && !isImage);
|
2020-06-08 15:50:23 -03:00
|
|
|
|
|
|
|
|
if (this.area.fill)
|
|
|
|
|
this.fillSection.actor.show();
|
|
|
|
|
else
|
|
|
|
|
this.fillSection.actor.hide();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
_addSwitchItem: function(menu, label, iconFalse, iconTrue, target, targetProperty, onToggled) {
|
2019-03-26 18:28:24 -03:00
|
|
|
let item = new PopupMenu.PopupSwitchMenuItem(label, target[targetProperty]);
|
|
|
|
|
|
2019-03-29 18:57:22 -03:00
|
|
|
item.icon = new St.Icon({ style_class: 'popup-menu-icon' });
|
2020-01-01 21:38:57 -03:00
|
|
|
getActor(item).insert_child_at_index(item.icon, 1);
|
2020-06-27 10:10:01 -03:00
|
|
|
let icon = target[targetProperty] ? iconTrue : iconFalse;
|
2020-09-11 20:25:37 -03:00
|
|
|
if (icon)
|
2020-06-27 10:10:01 -03:00
|
|
|
item.icon.set_gicon(icon);
|
2019-03-26 18:28:24 -03:00
|
|
|
|
|
|
|
|
item.connect('toggled', (item, state) => {
|
|
|
|
|
target[targetProperty] = state;
|
2020-06-27 10:10:01 -03:00
|
|
|
let icon = target[targetProperty] ? iconTrue : iconFalse;
|
2020-09-11 20:25:37 -03:00
|
|
|
if (icon)
|
2020-06-27 10:10:01 -03:00
|
|
|
item.icon.set_gicon(icon);
|
2020-06-08 15:50:23 -03:00
|
|
|
if (onToggled)
|
|
|
|
|
onToggled();
|
2019-03-26 18:28:24 -03:00
|
|
|
});
|
2019-03-27 18:11:51 -03:00
|
|
|
menu.addMenuItem(item);
|
2019-03-29 12:35:18 -03:00
|
|
|
return item;
|
2019-03-26 18:28:24 -03:00
|
|
|
},
|
|
|
|
|
|
2020-06-08 15:50:23 -03:00
|
|
|
_addSimpleSwitchItem: function(menu, label, active, onToggled) {
|
2019-03-26 18:28:24 -03:00
|
|
|
let item = new PopupMenu.PopupSwitchMenuItem(label, active);
|
|
|
|
|
item.connect('toggled', onToggled);
|
2019-03-27 18:11:51 -03:00
|
|
|
menu.addMenuItem(item);
|
2019-03-26 18:28:24 -03:00
|
|
|
},
|
|
|
|
|
|
2019-03-27 18:11:51 -03:00
|
|
|
_addSliderItem: function(menu, target, targetProperty) {
|
2019-03-26 18:28:24 -03:00
|
|
|
let item = new PopupMenu.PopupBaseMenuItem({ activate: false });
|
2020-09-07 13:56:48 -03:00
|
|
|
let label = new St.Label({ text: DisplayStrings.getPixels(target[targetProperty]), style_class: 'draw-on-your-screen-menu-slider-label' });
|
2019-03-26 18:28:24 -03:00
|
|
|
let slider = new Slider.Slider(target[targetProperty] / 50);
|
|
|
|
|
|
2019-10-11 04:22:37 -03:00
|
|
|
if (GS_VERSION < '3.33.0') {
|
|
|
|
|
slider.connect('value-changed', (slider, value, property) => {
|
2019-10-11 08:26:08 -03:00
|
|
|
target[targetProperty] = Math.max(Math.round(value * 50), 0);
|
2020-09-07 13:56:48 -03:00
|
|
|
label.set_text(DisplayStrings.getPixels(target[targetProperty]));
|
2019-10-11 08:26:08 -03:00
|
|
|
if (target[targetProperty] === 0)
|
2020-08-31 06:05:33 -03:00
|
|
|
label.add_style_class_name(WARNING_COLOR_STYLE_CLASS_NAME);
|
2019-10-11 08:26:08 -03:00
|
|
|
else
|
2020-08-31 06:05:33 -03:00
|
|
|
label.remove_style_class_name(WARNING_COLOR_STYLE_CLASS_NAME);
|
2019-10-11 04:22:37 -03:00
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
slider.connect('notify::value', () => {
|
2019-10-11 08:26:08 -03:00
|
|
|
target[targetProperty] = Math.max(Math.round(slider.value * 50), 0);
|
2020-09-07 13:56:48 -03:00
|
|
|
label.set_text(DisplayStrings.getPixels(target[targetProperty]));
|
2019-10-11 08:26:08 -03:00
|
|
|
if (target[targetProperty] === 0)
|
2020-08-31 06:05:33 -03:00
|
|
|
label.add_style_class_name(WARNING_COLOR_STYLE_CLASS_NAME);
|
2019-10-11 08:26:08 -03:00
|
|
|
else
|
2020-08-31 06:05:33 -03:00
|
|
|
label.remove_style_class_name(WARNING_COLOR_STYLE_CLASS_NAME);
|
2019-10-11 04:22:37 -03:00
|
|
|
});
|
|
|
|
|
}
|
2019-03-26 18:28:24 -03:00
|
|
|
|
2020-03-10 20:09:21 -03:00
|
|
|
getActor(slider).x_expand = true;
|
|
|
|
|
getActor(item).add_child(getActor(slider));
|
|
|
|
|
getActor(item).add_child(label);
|
|
|
|
|
if (slider.onKeyPressEvent)
|
|
|
|
|
getActor(item).connect('key-press-event', slider.onKeyPressEvent.bind(slider));
|
2019-03-27 18:11:51 -03:00
|
|
|
menu.addMenuItem(item);
|
2019-03-26 18:28:24 -03:00
|
|
|
},
|
|
|
|
|
|
2020-09-11 20:25:37 -03:00
|
|
|
_addSubMenuItem: function(menu, icon, obj, target, targetProperty) {
|
2020-09-07 13:56:48 -03:00
|
|
|
let item = new PopupMenu.PopupSubMenuMenuItem(String(obj[target[targetProperty]]), icon ? true : false);
|
2019-03-26 18:28:24 -03:00
|
|
|
|
2020-09-11 20:25:37 -03:00
|
|
|
item.icon.set_gicon(icon);
|
2020-09-10 23:06:21 -03:00
|
|
|
item.menu.itemActivated = item.menu.close;
|
2019-03-26 18:28:24 -03:00
|
|
|
|
2020-06-22 07:16:17 -03:00
|
|
|
GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
|
2020-09-10 23:06:21 -03:00
|
|
|
Object.keys(obj).forEach(key => {
|
2020-09-11 20:25:37 -03:00
|
|
|
let text = targetProperty == 'currentFontWeight' ? `<span font_weight="${key}">${obj[key]}</span>` :
|
|
|
|
|
targetProperty == 'currentFontStyle' ? `<span font_style="${DisplayStrings.FontStyleMarkup[key]}">${obj[key]}</span>` :
|
|
|
|
|
String(obj[key]);
|
2019-03-29 18:31:13 -03:00
|
|
|
|
|
|
|
|
let subItem = item.menu.addAction(text, () => {
|
2020-09-10 23:06:21 -03:00
|
|
|
item.label.set_text(String(obj[key]));
|
|
|
|
|
target[targetProperty] = Number(key);
|
2019-03-26 18:28:24 -03:00
|
|
|
});
|
2019-03-29 18:31:13 -03:00
|
|
|
|
|
|
|
|
subItem.label.get_clutter_text().set_use_markup(true);
|
2020-08-06 17:10:12 -03:00
|
|
|
getActor(subItem).connect('key-focus-in', updateSubMenuAdjustment);
|
2020-09-11 20:25:37 -03:00
|
|
|
});
|
|
|
|
|
return GLib.SOURCE_REMOVE;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
menu.addMenuItem(item);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
_addToolSubMenuItem: function(menu, callback) {
|
2020-09-14 17:44:20 -03:00
|
|
|
let item = new PopupMenu.PopupSubMenuMenuItem('', true);
|
|
|
|
|
item.update = () => {
|
|
|
|
|
item.label.set_text(DisplayStrings.Tool[this.area.currentTool]);
|
|
|
|
|
let toolName = this.drawingTools.getNameOf(this.area.currentTool);
|
|
|
|
|
item.icon.set_gicon(Files.Icons[`TOOL_${toolName}`]);
|
|
|
|
|
};
|
|
|
|
|
item.update();
|
2020-09-11 20:25:37 -03:00
|
|
|
|
|
|
|
|
item.menu.itemActivated = item.menu.close;
|
|
|
|
|
|
|
|
|
|
GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
|
|
|
|
|
Object.keys(DisplayStrings.Tool).forEach(key => {
|
|
|
|
|
let text = DisplayStrings.Tool[key];
|
|
|
|
|
let toolName = this.drawingTools.getNameOf(key);
|
|
|
|
|
let subItemIcon = Files.Icons[`TOOL_${toolName}`];
|
|
|
|
|
let subItem = item.menu.addAction(text, () => {
|
|
|
|
|
this.area.currentTool = Number(key);
|
2020-09-14 17:44:20 -03:00
|
|
|
item.update();
|
2020-09-11 20:25:37 -03:00
|
|
|
callback();
|
|
|
|
|
}, subItemIcon);
|
|
|
|
|
|
|
|
|
|
subItem.label.get_clutter_text().set_use_markup(true);
|
|
|
|
|
getActor(subItem).connect('key-focus-in', updateSubMenuAdjustment);
|
2020-06-07 13:57:11 -03:00
|
|
|
|
2020-06-13 08:53:52 -03:00
|
|
|
// change the display order of tools
|
2020-09-11 20:25:37 -03:00
|
|
|
if (key == this.drawingTools.POLYGON)
|
|
|
|
|
item.menu.moveMenuItem(subItem, Number(this.drawingTools.TEXT));
|
|
|
|
|
else if (key == this.drawingTools.POLYLINE)
|
|
|
|
|
item.menu.moveMenuItem(subItem, Number(this.drawingTools.TEXT) + 1);
|
2020-09-10 23:06:21 -03:00
|
|
|
});
|
2019-03-26 18:28:24 -03:00
|
|
|
return GLib.SOURCE_REMOVE;
|
|
|
|
|
});
|
2020-09-10 23:06:21 -03:00
|
|
|
|
2019-03-27 18:11:51 -03:00
|
|
|
menu.addMenuItem(item);
|
2020-09-14 17:44:20 -03:00
|
|
|
return item;
|
2019-03-26 18:28:24 -03:00
|
|
|
},
|
|
|
|
|
|
2020-09-11 20:25:37 -03:00
|
|
|
_addPaletteSubMenuItem: function(menu, icon) {
|
2020-08-31 04:43:00 -03:00
|
|
|
let text = _(this.area.currentPalette[0] || "Palette");
|
|
|
|
|
let item = new PopupMenu.PopupSubMenuMenuItem(text, true);
|
2020-09-11 20:25:37 -03:00
|
|
|
item.icon.set_gicon(icon);
|
2020-08-31 04:43:00 -03:00
|
|
|
|
2020-09-10 23:06:21 -03:00
|
|
|
item.menu.itemActivated = item.menu.close;
|
2020-08-31 04:43:00 -03:00
|
|
|
|
|
|
|
|
GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
|
|
|
|
|
this.area.palettes.forEach(palette => {
|
|
|
|
|
let [name, colors] = palette;
|
|
|
|
|
if (!colors[0])
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
let subItem = item.menu.addAction(_(name || "Palette"), () => {
|
|
|
|
|
item.label.set_text(_(name || "Palette"));
|
|
|
|
|
this.area.currentPalette = palette;
|
|
|
|
|
this._populateColorSubMenu();
|
|
|
|
|
});
|
|
|
|
|
getActor(subItem).connect('key-focus-in', updateSubMenuAdjustment);
|
|
|
|
|
});
|
|
|
|
|
return GLib.SOURCE_REMOVE;
|
|
|
|
|
});
|
2020-09-10 23:06:21 -03:00
|
|
|
|
2020-08-31 04:43:00 -03:00
|
|
|
menu.addMenuItem(item);
|
|
|
|
|
return item;
|
|
|
|
|
},
|
|
|
|
|
|
2020-09-11 20:25:37 -03:00
|
|
|
_addColorSubMenuItem: function(menu, icon) {
|
2019-03-26 18:28:24 -03:00
|
|
|
let item = new PopupMenu.PopupSubMenuMenuItem(_("Color"), true);
|
2020-08-31 04:43:00 -03:00
|
|
|
this.colorSubMenu = item.menu;
|
2020-09-11 20:25:37 -03:00
|
|
|
item.icon.set_gicon(icon);
|
2019-03-26 18:28:24 -03:00
|
|
|
item.icon.set_style(`color:${this.area.currentColor.to_string().slice(0, 7)};`);
|
|
|
|
|
|
2020-09-10 23:06:21 -03:00
|
|
|
item.menu.itemActivated = item.menu.close;
|
2019-03-26 18:28:24 -03:00
|
|
|
|
2020-08-31 04:43:00 -03:00
|
|
|
this._populateColorSubMenu();
|
|
|
|
|
menu.addMenuItem(item);
|
|
|
|
|
return item;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
_populateColorSubMenu: function() {
|
|
|
|
|
this.colorSubMenu.removeAll();
|
2020-06-22 07:16:17 -03:00
|
|
|
GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
|
2020-08-31 04:43:00 -03:00
|
|
|
this.area.colors.forEach(color => {
|
2020-09-14 19:29:02 -03:00
|
|
|
let text = String(color);
|
2020-08-31 04:43:00 -03:00
|
|
|
let subItem = this.colorSubMenu.addAction(text, () => {
|
|
|
|
|
this.area.currentColor = color;
|
|
|
|
|
this.colorItem.icon.set_style(`color:${color.to_string().slice(0, 7)};`);
|
2019-03-26 18:28:24 -03:00
|
|
|
});
|
2020-06-01 14:28:06 -03:00
|
|
|
// Foreground color markup is not displayed since 3.36, use style instead but the transparency is lost.
|
2020-08-31 04:43:00 -03:00
|
|
|
subItem.label.set_style(`color:${color.to_string().slice(0, 7)};`);
|
|
|
|
|
getActor(subItem).connect('key-focus-in', updateSubMenuAdjustment);
|
|
|
|
|
});
|
2019-03-26 18:28:24 -03:00
|
|
|
return GLib.SOURCE_REMOVE;
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2020-08-05 18:30:25 -03:00
|
|
|
_addFontFamilySubMenuItem: function(menu, icon) {
|
2020-09-07 13:56:48 -03:00
|
|
|
let item = new PopupMenu.PopupSubMenuMenuItem(DisplayStrings.getFontFamily(this.area.currentFontFamily), true);
|
2020-09-11 20:25:37 -03:00
|
|
|
item.icon.set_gicon(icon);
|
2020-08-05 18:30:25 -03:00
|
|
|
|
2020-09-10 23:06:21 -03:00
|
|
|
item.menu.itemActivated = item.menu.close;
|
2020-08-05 18:30:25 -03:00
|
|
|
|
|
|
|
|
item.menu.openOld = item.menu.open;
|
|
|
|
|
item.menu.open = (animate) => {
|
|
|
|
|
if (!item.menu.isOpen && item.menu.isEmpty()) {
|
|
|
|
|
this.area.fontFamilies.forEach(family => {
|
2020-09-07 13:56:48 -03:00
|
|
|
let subItem = item.menu.addAction(DisplayStrings.getFontFamily(family), () => {
|
|
|
|
|
item.label.set_text(DisplayStrings.getFontFamily(family));
|
2020-08-05 18:30:25 -03:00
|
|
|
this.area.currentFontFamily = family;
|
|
|
|
|
});
|
|
|
|
|
if (FONT_FAMILY_STYLE)
|
|
|
|
|
subItem.label.set_style(`font-family:${family}`);
|
2020-08-06 17:10:12 -03:00
|
|
|
getActor(subItem).connect('key-focus-in', updateSubMenuAdjustment);
|
2020-08-05 18:30:25 -03:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
item.menu.openOld();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
menu.addMenuItem(item);
|
|
|
|
|
},
|
|
|
|
|
|
2020-09-10 23:06:21 -03:00
|
|
|
_addImageSubMenuItem: function(menu, images) {
|
2020-09-14 17:44:20 -03:00
|
|
|
let item = new PopupMenu.PopupSubMenuMenuItem('', true);
|
|
|
|
|
item.update = () => {
|
|
|
|
|
item.label.set_text(this.area.currentImage.toString());
|
|
|
|
|
item.icon.set_gicon(this.area.currentImage.gicon);
|
|
|
|
|
};
|
|
|
|
|
item.update();
|
2020-09-10 23:06:21 -03:00
|
|
|
|
|
|
|
|
item.menu.itemActivated = item.menu.close;
|
|
|
|
|
|
|
|
|
|
item.menu.openOld = item.menu.open;
|
|
|
|
|
item.menu.open = (animate) => {
|
|
|
|
|
if (!item.menu.isOpen && item.menu.isEmpty()) {
|
2020-09-12 14:54:10 -03:00
|
|
|
Files.Images.getSorted().forEach(image => {
|
2020-09-10 23:06:21 -03:00
|
|
|
let subItem = item.menu.addAction(image.toString(), () => {
|
|
|
|
|
this.area.currentImage = image;
|
2020-09-14 17:44:20 -03:00
|
|
|
item.update();
|
2020-09-10 23:06:21 -03:00
|
|
|
}, image.thumbnailGicon || undefined);
|
|
|
|
|
getActor(subItem).connect('key-focus-in', updateSubMenuAdjustment);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
item.menu.openOld();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
menu.addMenuItem(item);
|
2020-09-14 17:44:20 -03:00
|
|
|
return item;
|
2020-09-10 23:06:21 -03:00
|
|
|
},
|
|
|
|
|
|
2020-01-03 20:16:20 -03:00
|
|
|
_addDrawingNameItem: function(menu) {
|
|
|
|
|
this.drawingNameMenuItem = new PopupMenu.PopupMenuItem('', { reactive: false, activate: false });
|
|
|
|
|
this.drawingNameMenuItem.setSensitive(false);
|
|
|
|
|
menu.addMenuItem(this.drawingNameMenuItem);
|
|
|
|
|
this._updateDrawingNameMenuItem();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
_updateDrawingNameMenuItem: function() {
|
2020-09-13 18:50:09 -03:00
|
|
|
getActor(this.drawingNameMenuItem).visible = this.area.currentJson ? true : false;
|
|
|
|
|
if (this.area.currentJson) {
|
2020-01-04 08:50:43 -03:00
|
|
|
let prefix = this.area.drawingContentsHasChanged ? "* " : "";
|
2020-09-13 18:50:09 -03:00
|
|
|
this.drawingNameMenuItem.label.set_text(`<i>${prefix}${this.area.currentJson.name}</i>`);
|
2020-01-03 20:16:20 -03:00
|
|
|
this.drawingNameMenuItem.label.get_clutter_text().set_use_markup(true);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2020-09-11 20:25:37 -03:00
|
|
|
_addOpenDrawingSubMenuItem: function(menu, icon) {
|
2020-01-03 20:16:20 -03:00
|
|
|
let item = new PopupMenu.PopupSubMenuMenuItem(_("Open drawing"), true);
|
|
|
|
|
this.openDrawingSubMenuItem = item;
|
|
|
|
|
this.openDrawingSubMenu = item.menu;
|
2020-09-13 18:50:09 -03:00
|
|
|
item.setSensitive(Boolean(Files.Jsons.getSorted().length));
|
2020-09-11 20:25:37 -03:00
|
|
|
item.icon.set_gicon(icon);
|
2020-01-03 20:16:20 -03:00
|
|
|
|
2020-09-10 23:06:21 -03:00
|
|
|
item.menu.itemActivated = item.menu.close;
|
2020-01-03 20:16:20 -03:00
|
|
|
|
2020-06-22 09:38:42 -03:00
|
|
|
item.menu.openOld = item.menu.open;
|
|
|
|
|
item.menu.open = (animate) => {
|
|
|
|
|
if (!item.menu.isOpen)
|
|
|
|
|
this._populateOpenDrawingSubMenu();
|
|
|
|
|
item.menu.openOld();
|
2020-06-25 06:41:15 -03:00
|
|
|
};
|
2020-06-22 09:38:42 -03:00
|
|
|
|
2020-01-03 20:16:20 -03:00
|
|
|
menu.addMenuItem(item);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
_populateOpenDrawingSubMenu: function() {
|
|
|
|
|
this.openDrawingSubMenu.removeAll();
|
2020-09-13 20:32:37 -03:00
|
|
|
Files.Jsons.getSorted().forEach(json => {
|
2020-09-16 03:52:36 -03:00
|
|
|
if (!json.gicon)
|
|
|
|
|
json.addSvgContents(...this.area.getSvgContentsForJson(json));
|
2020-09-13 20:32:37 -03:00
|
|
|
|
2020-08-06 17:10:12 -03:00
|
|
|
let subItem = this.openDrawingSubMenu.addAction(`<i>${String(json)}</i>`, () => {
|
2020-09-13 18:50:09 -03:00
|
|
|
this.area.loadJson(json);
|
2020-01-03 20:16:20 -03:00
|
|
|
this._updateDrawingNameMenuItem();
|
|
|
|
|
this._updateSaveDrawingSubMenuItemSensitivity();
|
2020-09-13 20:32:37 -03:00
|
|
|
}, json.gicon);
|
|
|
|
|
|
2020-08-06 17:10:12 -03:00
|
|
|
subItem.label.get_clutter_text().set_use_markup(true);
|
|
|
|
|
getActor(subItem).connect('key-focus-in', updateSubMenuAdjustment);
|
2020-01-03 20:16:20 -03:00
|
|
|
|
|
|
|
|
let expander = new St.Bin({
|
|
|
|
|
style_class: 'popup-menu-item-expander',
|
|
|
|
|
x_expand: true,
|
|
|
|
|
});
|
2020-08-06 17:10:12 -03:00
|
|
|
getActor(subItem).add_child(expander);
|
2020-01-03 20:16:20 -03:00
|
|
|
|
2020-09-14 17:44:20 -03:00
|
|
|
let insertButton = new St.Button({ style_class: 'button draw-on-your-screen-menu-insert-button',
|
|
|
|
|
child: new St.Icon({ icon_name: 'insert-image-symbolic',
|
|
|
|
|
style_class: 'popup-menu-icon' }) });
|
|
|
|
|
getActor(subItem).add_child(insertButton);
|
|
|
|
|
|
|
|
|
|
insertButton.connect('clicked', () => {
|
|
|
|
|
this.area.currentImage = json.image;
|
|
|
|
|
this.imageItem.update();
|
|
|
|
|
this.area.currentTool = this.drawingTools.IMAGE;
|
|
|
|
|
this.toolItem.update();
|
|
|
|
|
this._updateSectionVisibility();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let deleteButton = new St.Button({ style_class: 'button draw-on-your-screen-menu-delete-button',
|
2020-01-03 20:16:20 -03:00
|
|
|
child: new St.Icon({ icon_name: 'edit-delete-symbolic',
|
2020-09-14 17:44:20 -03:00
|
|
|
style_class: 'popup-menu-icon' }) });
|
2020-08-06 17:10:12 -03:00
|
|
|
getActor(subItem).add_child(deleteButton);
|
2020-01-03 20:16:20 -03:00
|
|
|
|
|
|
|
|
deleteButton.connect('clicked', () => {
|
2020-08-04 21:00:20 -03:00
|
|
|
json.delete();
|
2020-08-06 17:10:12 -03:00
|
|
|
subItem.destroy();
|
2020-08-04 21:49:52 -03:00
|
|
|
this.openDrawingSubMenuItem.setSensitive(!this.openDrawingSubMenu.isEmpty());
|
2020-01-03 20:16:20 -03:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.openDrawingSubMenuItem.setSensitive(!this.openDrawingSubMenu.isEmpty());
|
|
|
|
|
},
|
|
|
|
|
|
2020-09-11 20:25:37 -03:00
|
|
|
_addSaveDrawingSubMenuItem: function(menu, icon) {
|
2020-09-01 08:43:30 -03:00
|
|
|
let item = new PopupMenu.PopupSubMenuMenuItem(getSummary('save-as-json'), true);
|
2020-01-03 20:16:20 -03:00
|
|
|
this.saveDrawingSubMenuItem = item;
|
|
|
|
|
this._updateSaveDrawingSubMenuItemSensitivity();
|
|
|
|
|
this.saveDrawingSubMenu = item.menu;
|
2020-09-11 20:25:37 -03:00
|
|
|
item.icon.set_gicon(icon);
|
2020-01-03 20:16:20 -03:00
|
|
|
|
2020-09-10 23:06:21 -03:00
|
|
|
item.menu.itemActivated = item.menu.close;
|
2020-01-03 20:16:20 -03:00
|
|
|
|
2020-06-22 09:38:42 -03:00
|
|
|
item.menu.openOld = item.menu.open;
|
|
|
|
|
item.menu.open = (animate) => {
|
|
|
|
|
if (!item.menu.isOpen)
|
|
|
|
|
this._populateSaveDrawingSubMenu();
|
|
|
|
|
item.menu.openOld();
|
2020-06-25 06:41:15 -03:00
|
|
|
};
|
2020-01-03 20:16:20 -03:00
|
|
|
menu.addMenuItem(item);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
_updateSaveDrawingSubMenuItemSensitivity: function() {
|
|
|
|
|
this.saveDrawingSubMenuItem.setSensitive(this.area.elements.length > 0);
|
|
|
|
|
},
|
|
|
|
|
|
2020-08-04 21:49:52 -03:00
|
|
|
_onDrawingSaved() {
|
|
|
|
|
this._updateDrawingNameMenuItem();
|
|
|
|
|
this.openDrawingSubMenuItem.setSensitive(true);
|
|
|
|
|
},
|
|
|
|
|
|
2020-01-03 20:16:20 -03:00
|
|
|
_populateSaveDrawingSubMenu: function() {
|
2020-06-22 09:38:42 -03:00
|
|
|
this.saveDrawingSubMenu.removeAll();
|
2020-08-04 21:00:20 -03:00
|
|
|
let saveEntry = new DrawingMenuEntry({ initialTextGetter: Files.getDateString,
|
2020-01-03 20:16:20 -03:00
|
|
|
entryActivateCallback: (text) => {
|
2020-08-04 21:49:52 -03:00
|
|
|
this.area.saveAsJsonWithName(text, this._onDrawingSaved.bind(this));
|
2020-01-03 20:16:20 -03:00
|
|
|
this.saveDrawingSubMenu.toggle();
|
|
|
|
|
},
|
2020-01-10 08:32:28 -03:00
|
|
|
invalidStrings: [Me.metadata['persistent-file-name'], '/'],
|
2020-01-03 20:16:20 -03:00
|
|
|
primaryIconName: 'insert-text' });
|
2020-06-22 09:38:42 -03:00
|
|
|
this.saveDrawingSubMenu.addMenuItem(saveEntry.item);
|
2020-01-03 20:16:20 -03:00
|
|
|
},
|
|
|
|
|
|
2020-07-11 15:41:04 -03:00
|
|
|
_addSeparator: function(menu, thin) {
|
2020-06-05 17:45:11 -03:00
|
|
|
if (this.hasSeparators) {
|
|
|
|
|
let separatorItem = new PopupMenu.PopupSeparatorMenuItem(' ');
|
|
|
|
|
getActor(separatorItem).add_style_class_name('draw-on-your-screen-menu-separator-item');
|
2020-07-11 15:41:04 -03:00
|
|
|
if (thin)
|
|
|
|
|
getActor(separatorItem).add_style_class_name('draw-on-your-screen-menu-thin-separator-item');
|
2020-06-05 17:45:11 -03:00
|
|
|
menu.addMenuItem(separatorItem);
|
|
|
|
|
}
|
2019-03-26 18:28:24 -03:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2020-08-06 17:10:12 -03:00
|
|
|
// based on ApplicationsButton.scrollToButton , https://gitlab.gnome.org/GNOME/gnome-shell-extensions/blob/master/extensions/apps-menu/extension.js
|
|
|
|
|
const updateSubMenuAdjustment = function(itemActor) {
|
|
|
|
|
let scrollView = itemActor.get_parent().get_parent();
|
|
|
|
|
let adjustment = scrollView.get_vscroll_bar().get_adjustment();
|
|
|
|
|
let scrollViewAlloc = scrollView.get_allocation_box();
|
|
|
|
|
let currentScrollValue = adjustment.get_value();
|
|
|
|
|
let height = scrollViewAlloc.y2 - scrollViewAlloc.y1;
|
|
|
|
|
let itemActorAlloc = itemActor.get_allocation_box();
|
|
|
|
|
let newScrollValue = currentScrollValue;
|
|
|
|
|
if (currentScrollValue > itemActorAlloc.y1 - 10)
|
|
|
|
|
newScrollValue = itemActorAlloc.y1 - 10;
|
|
|
|
|
if (height + currentScrollValue < itemActorAlloc.y2 + 10)
|
|
|
|
|
newScrollValue = itemActorAlloc.y2 - height + 10;
|
|
|
|
|
if (newScrollValue != currentScrollValue)
|
|
|
|
|
adjustment.set_value(newScrollValue);
|
|
|
|
|
};
|
|
|
|
|
|
2020-01-03 20:16:20 -03:00
|
|
|
// based on searchItem.js, https://github.com/leonardo-bartoli/gnome-shell-extension-Recents
|
2020-03-02 12:32:50 -03:00
|
|
|
const DrawingMenuEntry = new Lang.Class({
|
2020-01-03 20:16:20 -03:00
|
|
|
Name: 'DrawOnYourScreenDrawingMenuEntry',
|
|
|
|
|
|
2020-03-02 12:32:50 -03:00
|
|
|
_init: function(params) {
|
2020-01-03 20:16:20 -03:00
|
|
|
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,
|
2020-03-10 20:09:21 -03:00
|
|
|
can_focus: true,
|
|
|
|
|
x_expand: true
|
2020-01-03 20:16:20 -03:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
|
2020-03-10 20:09:21 -03:00
|
|
|
getActor(this.item).add_child(this.entry);
|
2020-01-03 20:16:20 -03:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|