Merge branch 'dev' into 'master'
v6.4 See merge request abakkk/DrawOnYourScreen!15
This commit is contained in:
commit
34eb8e930b
92
area.js
92
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
11
files.js
11
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();
|
||||
|
|
|
|||
38
helper.js
38
helper.js
|
|
@ -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) });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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
35
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() {
|
||||
|
|
|
|||
|
|
@ -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>')],
|
||||
|
|
|
|||
Loading…
Reference in New Issue