Merge branch 'dev' into 'master'

v6.4

See merge request abakkk/DrawOnYourScreen!15
This commit is contained in:
abakkk 2020-09-19 00:34:29 +02:00
commit 34eb8e930b
7 changed files with 100 additions and 92 deletions

92
area.js
View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -21,13 +21,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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) });
}
}
});

View File

@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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 <span alpha=\"50%\">(while moving)</span>"

35
menu.js
View File

@ -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() {

View File

@ -83,7 +83,7 @@ const getOthers = function() {
[_("Extend circle to ellipse"), getKeyLabel('<Primary>')],
[_("Curve line"), getKeyLabel('<Primary>')],
[_("Smooth free drawing outline"), getKeyLabel('<Primary>')],
[_("Unlock image ratio"), getKeyLabel('<Primary>')],
[_("Do not preserve image ratio"), getKeyLabel('<Primary>')],
[_("Rotate <span alpha=\"50%\">(while moving)</span>"), getKeyLabel('<Primary>')],
[_("Stretch <span alpha=\"50%\">(while resizing)</span>"), getKeyLabel('<Primary>')],
[_("Inverse <span alpha=\"50%\">(while mirroring)</span>"), getKeyLabel('<Primary>')],