diff --git a/area.js b/area.js
index d28a846..dadec04 100644
--- a/area.js
+++ b/area.js
@@ -367,7 +367,8 @@ var DrawingArea = new Lang.Class({
} else if (button == 2) {
this.switchFill();
} else if (button == 3) {
- this._stopDrawing();
+ this._stopAll();
+
this.menu.open(x, y);
return Clutter.EVENT_STOP;
}
@@ -376,7 +377,8 @@ var DrawingArea = new Lang.Class({
},
_onKeyboardPopupMenu: function() {
- this._stopDrawing();
+ this._stopAll();
+
if (this.helper.visible)
this.toggleHelp();
this.menu.popup();
@@ -701,6 +703,7 @@ var DrawingArea = new Lang.Class({
},
_startWriting: function() {
+ let [stageX, stageY] = this.get_transformed_position();
let [x, y] = [this.currentElement.x, this.currentElement.y];
this.currentElement.text = '';
this.currentElement.cursorPosition = 0;
@@ -711,16 +714,22 @@ var DrawingArea = new Lang.Class({
this.textHasCursor = true;
this._redisplay();
- this.textEntry = new St.Entry({ visible: false, x, y });
- this.get_parent().add_child(this.textEntry);
+ // Do not hide and do not set opacity to 0 because ibusCandidatePopup need a mapped text entry to init correctly its position.
+ this.textEntry = new St.Entry({ opacity: 1, x: stageX + x, y: stageY + y });
+ this.get_parent().insert_child_below(this.textEntry, this);
this.textEntry.grab_key_focus();
this.updateActionMode();
this.updatePointerCursor();
- let ibusCandidatePopup = Main.layoutManager.uiGroup.get_children().filter(child =>
- child.has_style_class_name && child.has_style_class_name('candidate-popup-boxpointer'))[0] || null;
+ let ibusCandidatePopup = Main.layoutManager.uiGroup.get_children().find(child =>
+ child.has_style_class_name && child.has_style_class_name('candidate-popup-boxpointer'));
if (ibusCandidatePopup) {
- this.ibusHandler = ibusCandidatePopup.connect('notify::visible', popup => popup.visible && (this.textEntry.visible = true));
+ this.ibusHandler = ibusCandidatePopup.connect('notify::visible', () => {
+ if (ibusCandidatePopup.visible) {
+ this.get_parent().set_child_above_sibling(this.textEntry, this);
+ this.textEntry.opacity = 255;
+ }
+ });
this.textEntry.connect('destroy', () => ibusCandidatePopup.disconnect(this.ibusHandler));
}
@@ -832,6 +841,21 @@ var DrawingArea = new Lang.Class({
});
},
+ // A priori there is nothing to stop, except transformations, if there is no current element.
+ // 'force' argument is passed when leaving drawing mode to ensure all is clean, as a workaround for possible bugs.
+ _stopAll: function(force) {
+ if (this.grabbedElement)
+ this._stopTransforming();
+
+ if (!this.currentElement && !force)
+ return;
+
+ if (this.isWriting)
+ this._stopWriting();
+
+ this._stopDrawing();
+ },
+
erase: function() {
this.deleteLastElement();
this.elements = [];
@@ -840,21 +864,8 @@ var DrawingArea = new Lang.Class({
},
deleteLastElement: function() {
- if (this.currentElement) {
- if (this.motionHandler) {
- this.disconnect(this.motionHandler);
- this.motionHandler = null;
- }
- if (this.buttonReleasedHandler) {
- this.disconnect(this.buttonReleasedHandler);
- this.buttonReleasedHandler = null;
- }
- if (this.isWriting)
- this._stopWriting();
- this.currentElement = null;
- } else {
- this.elements.pop();
- }
+ this._stopAll();
+ this.elements.pop();
this._redisplay();
},
@@ -1085,25 +1096,16 @@ var DrawingArea = new Lang.Class({
this.disconnect(this.keyboardPopupMenuHandler);
this.keyboardPopupMenuHandler = null;
}
- if (this.motionHandler) {
- this.disconnect(this.motionHandler);
- this.motionHandler = null;
- }
- if (this.buttonReleasedHandler) {
- this.disconnect(this.buttonReleasedHandler);
- this.buttonReleasedHandler = null;
- }
if (this.scrollHandler) {
this.disconnect(this.scrollHandler);
this.scrollHandler = null;
}
- this.currentElement = null;
- this._stopTextCursorTimeout();
+ this._stopAll(true);
+
if (erase)
this.erase();
- else
- this._redisplay();
+
this.closeMenu();
this.get_parent().set_background_color(null);
Files.Images.reset();
@@ -1143,12 +1145,7 @@ var DrawingArea = new Lang.Class({
},
exportToSvg: function() {
- // stop drawing or writing
- if (this.currentElement && this.currentElement.shape == Shapes.TEXT && this.isWriting) {
- this._stopWriting();
- } else if (this.currentElement && this.currentElement.shape != Shapes.TEXT) {
- this._stopDrawing();
- }
+ this._stopAll();
let prefixes = 'xmlns="http://www.w3.org/2000/svg"';
if (this.elements.some(element => element.shape == Shapes.IMAGE))
@@ -1181,12 +1178,7 @@ var DrawingArea = new Lang.Class({
},
_saveAsJson: function(json, notify, callback) {
- // stop drawing or writing
- if (this.currentElement && this.currentElement.shape == Shapes.TEXT && this.isWriting) {
- this._stopWriting();
- } else if (this.currentElement && this.currentElement.shape != Shapes.TEXT) {
- this._stopDrawing();
- }
+ this._stopAll();
// do not use "content = JSON.stringify(this.elements, null, 2);", neither "content = JSON.stringify(this.elements);"
// do compromise between disk usage and human readability
@@ -1225,12 +1217,8 @@ var DrawingArea = new Lang.Class({
},
_loadJson: function(json, notify) {
- // stop drawing or writing
- if (this.currentElement && this.currentElement.shape == Shapes.TEXT && this.isWriting) {
- this._stopWriting();
- } else if (this.currentElement && this.currentElement.shape != Shapes.TEXT) {
- this._stopDrawing();
- }
+ this._stopAll();
+
this.elements = [];
this.currentElement = null;
diff --git a/elements.js b/elements.js
index b89800d..82338dd 100644
--- a/elements.js
+++ b/elements.js
@@ -670,9 +670,9 @@ const TextElement = new Lang.Class({
layout.set_font_description(this.font);
layout.set_text(this.text, -1);
this.textWidth = layout.get_pixel_size()[0];
- cr.moveTo(this.x, this.y - layout.get_baseline() / Pango.SCALE);
+ cr.moveTo(this.x, this.y);
layout.set_text(this.text, -1);
- PangoCairo.show_layout(cr, layout);
+ PangoCairo.show_layout_line(cr, layout.get_line(0));
if (params.showTextCursor) {
let cursorPosition = this.cursorPosition == -1 ? this.text.length : this.cursorPosition;
diff --git a/files.js b/files.js
index 22a31bc..c91b404 100644
--- a/files.js
+++ b/files.js
@@ -318,11 +318,12 @@ var Images = {
},
addImagesFromClipboard: function(callback) {
- Clipboard.get_text(CLIPBOARD_TYPE, (clipBoard, text) => {
+ Clipboard.get_text(CLIPBOARD_TYPE, (clipboard, text) => {
if (!text)
return;
-
- let lines = text.split('\n');
+
+ // Since 3.38 there is a line terminator character, that has to be removed with .trim().
+ let lines = text.split('\n').map(line => line.trim());
if (lines[0] == 'x-special/nautilus-clipboard')
lines = lines.slice(2);
@@ -443,7 +444,9 @@ var Jsons = {
return;
let directory = Gio.File.new_for_path(GLib.build_filenamev([GLib.get_user_data_dir(), Me.metadata['data-dir']]));
- this._monitor = directory.monitor(Gio.FileMonitorFlags.NONE, null);
+ // It is important to specify that the file to monitor is a directory because maybe the directory does not exist yet
+ // and remove events would not be monitored.
+ this._monitor = directory.monitor_directory(Gio.FileMonitorFlags.NONE, null);
this._monitorHandler = this._monitor.connect('changed', (monitor, file) => {
if (file.get_basename() != `${Me.metadata['persistent-file-name']}.json` && file.get_basename().indexOf('.goutputstream'))
this.reset();
diff --git a/helper.js b/helper.js
index 444ff93..fdeeb10 100644
--- a/helper.js
+++ b/helper.js
@@ -21,13 +21,13 @@
* along with this program. If not, see .
*/
+const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const St = imports.gi.St;
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils;
-const Tweener = imports.ui.tweener;
const Me = ExtensionUtils.getCurrentExtension();
const Convenience = ExtensionUtils.getSettings ? ExtensionUtils : Me.imports.convenience;
@@ -35,6 +35,7 @@ const Shortcuts = Me.imports.shortcuts;
const _ = imports.gettext.domain(Me.metadata['gettext-domain']).gettext;
const GS_VERSION = Config.PACKAGE_VERSION;
+const Tweener = GS_VERSION < '3.33.0' ? imports.ui.tweener : null;
const HELPER_ANIMATION_TIME = 0.25;
const MEDIA_KEYS_SCHEMA = 'org.gnome.settings-daemon.plugins.media-keys';
@@ -175,20 +176,33 @@ var DrawingHelper = new Lang.Class({
else
this.vscrollbar_policy = Gtk.PolicyType.NEVER;
- Tweener.removeTweens(this);
- Tweener.addTween(this, { opacity: 255,
- time: HELPER_ANIMATION_TIME,
- transition: 'easeOutQuad',
- onComplete: null });
+ if (Tweener) {
+ Tweener.removeTweens(this);
+ Tweener.addTween(this, { opacity: 255,
+ time: HELPER_ANIMATION_TIME,
+ transition: 'easeOutQuad' });
+ } else {
+ this.remove_all_transitions();
+ this.ease({ opacity: 255,
+ duration: HELPER_ANIMATION_TIME * 1000,
+ transition: Clutter.AnimationMode.EASE_OUT_QUAD });
+ }
},
hideHelp: function() {
- Tweener.removeTweens(this);
- Tweener.addTween(this, { opacity: 0,
- time: HELPER_ANIMATION_TIME,
- transition: 'easeOutQuad',
- onComplete: this.hide.bind(this) });
-
+ if (Tweener) {
+ Tweener.removeTweens(this);
+ Tweener.addTween(this, { opacity: 0,
+ time: HELPER_ANIMATION_TIME,
+ transition: 'easeOutQuad',
+ onComplete: this.hide.bind(this) });
+ } else {
+ this.remove_all_transitions();
+ this.ease({ opacity: 0,
+ duration: HELPER_ANIMATION_TIME * 1000,
+ transition: Clutter.AnimationMode.EASE_OUT_QUAD,
+ onComplete: this.hide.bind(this) });
+ }
}
});
diff --git a/locale/draw-on-your-screen.pot b/locale/draw-on-your-screen.pot
index e94b500..3b2aa41 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-17 22:27+0200\n"
+"POT-Creation-Date: 2020-09-18 11:37+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -284,6 +284,12 @@ msgstr ""
msgid "Color"
msgstr ""
+msgid "Add to images"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
msgid "Type a name"
msgstr ""
@@ -417,7 +423,7 @@ msgstr ""
msgid "Smooth free drawing outline"
msgstr ""
-msgid "Unlock image ratio"
+msgid "Do not preserve image ratio"
msgstr ""
msgid "Rotate (while moving)"
diff --git a/menu.js b/menu.js
index 86a6032..53364bf 100644
--- a/menu.js
+++ b/menu.js
@@ -616,29 +616,24 @@ var DrawingMenu = new Lang.Class({
});
getActor(subItem).add_child(expander);
- 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);
-
- insertButton.connect('clicked', () => {
+ let insertCallback = () => {
this.area.currentImage = json.image;
this.imageItem.update();
this.area.currentTool = this.drawingTools.IMAGE;
this.toolItem.update();
this._updateSectionVisibility();
- });
+ };
+ let insertButton = new ActionButton(_("Add to images"), 'insert-image-symbolic', insertCallback, null, true);
+ getActor(subItem).add_child(insertButton);
- 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);
-
- deleteButton.connect('clicked', () => {
+ let deleteCallback = () => {
json.delete();
subItem.destroy();
this.openDrawingSubMenuItem.setSensitive(!this.openDrawingSubMenu.isEmpty());
- });
+ };
+ let deleteButton = new ActionButton(_("Delete"), 'edit-delete-symbolic', deleteCallback, null, true);
+ deleteButton.child.add_style_class_name('draw-on-your-screen-menu-destructive-button');
+ getActor(subItem).add_child(deleteButton);
});
this.openDrawingSubMenuItem.setSensitive(!this.openDrawingSubMenu.isEmpty());
@@ -722,16 +717,18 @@ const ActionButton = new Lang.Class({
hideLabel: Dash.DashItemContainer.prototype.hideLabel,
_syncLabel: Dash.Dash.prototype._syncLabel,
- _init: function(name, icon, callback, callbackAfter) {
+ _init: function(name, icon, callback, callbackAfter, inline) {
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' });
+ style_class: `button draw-on-your-screen-menu-${inline ? 'inline' : 'action'}-button` });
+
button.child = new St.Icon(typeof icon == 'string' ? { icon_name: icon } : { gicon: icon });
+ if (inline)
+ button.child.add_style_class_name('popup-menu-icon');
+
button.connect('clicked', () => {
callback();
if (callbackAfter)
@@ -740,7 +737,7 @@ const ActionButton = new Lang.Class({
button.bind_property('reactive', button, 'can_focus', GObject.BindingFlags.DEFAULT);
button.connect('notify::hover', () => this._syncLabel(this));
- this.parent({ child: button, x_expand: true });
+ this.parent({ child: button, x_expand: inline ? false : true });
},
get label() {
diff --git a/shortcuts.js b/shortcuts.js
index 488485a..df753d4 100644
--- a/shortcuts.js
+++ b/shortcuts.js
@@ -83,7 +83,7 @@ const getOthers = function() {
[_("Extend circle to ellipse"), getKeyLabel('')],
[_("Curve line"), getKeyLabel('')],
[_("Smooth free drawing outline"), getKeyLabel('')],
- [_("Unlock image ratio"), getKeyLabel('')],
+ [_("Do not preserve image ratio"), getKeyLabel('')],
[_("Rotate (while moving)"), getKeyLabel('')],
[_("Stretch (while resizing)"), getKeyLabel('')],
[_("Inverse (while mirroring)"), getKeyLabel('')],