Merge branch 'dev-context-menu' into 'master'
Dev context menu See merge request abakkk/DrawOnYourScreen!1
This commit is contained in:
commit
a89e1d9d70
264
draw.js
264
draw.js
|
|
@ -22,21 +22,35 @@
|
||||||
|
|
||||||
const Cairo = imports.cairo;
|
const Cairo = imports.cairo;
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const GdkPixbuf = imports.gi.GdkPixbuf;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
|
const GObject = imports.gi.GObject;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const BoxPointer = imports.ui.boxpointer;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
|
const Slider = imports.ui.slider;
|
||||||
const Screenshot = imports.ui.screenshot;
|
const Screenshot = imports.ui.screenshot;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||||||
const Extension = ExtensionUtils.getCurrentExtension();
|
const Extension = ExtensionUtils.getCurrentExtension();
|
||||||
const Convenience = Extension.imports.convenience;
|
const Convenience = Extension.imports.convenience;
|
||||||
|
const ExtensionJs = Extension.imports.extension;
|
||||||
const Prefs = Extension.imports.prefs;
|
const Prefs = Extension.imports.prefs;
|
||||||
const _ = imports.gettext.domain(Extension.metadata["gettext-domain"]).gettext;
|
const _ = imports.gettext.domain(Extension.metadata["gettext-domain"]).gettext;
|
||||||
|
|
||||||
|
const FILL_ICON_PATH = Extension.dir.get_child('icons').get_child('fill-symbolic.svg').get_path();
|
||||||
|
const LINEJOIN_ICON_PATH = Extension.dir.get_child('icons').get_child('linejoin-symbolic.svg').get_path();
|
||||||
|
const LINECAP_ICON_PATH = Extension.dir.get_child('icons').get_child('linecap-symbolic.svg').get_path();
|
||||||
|
const DASHED_LINE_ICON_PATH = Extension.dir.get_child('icons').get_child('dashed-line-symbolic.svg').get_path();
|
||||||
|
|
||||||
var Shapes = { NONE: 0, LINE: 1, ELLIPSE: 2, RECTANGLE: 3, TEXT: 4 };
|
var Shapes = { NONE: 0, LINE: 1, ELLIPSE: 2, RECTANGLE: 3, TEXT: 4 };
|
||||||
var ShapeNames = { 0: "Free drawing", 1: "Line", 2: "Ellipse", 3: "Rectangle", 4: "Text" };
|
var ShapeNames = { 0: "Free drawing", 1: "Line", 2: "Ellipse", 3: "Rectangle", 4: "Text" };
|
||||||
var LineCapNames = { 0: 'Butt', 1: 'Round', 2: 'Square' };
|
var LineCapNames = { 0: 'Butt', 1: 'Round', 2: 'Square' };
|
||||||
|
|
@ -60,6 +74,7 @@ var DrawingArea = new Lang.Class({
|
||||||
this.settings = Convenience.getSettings();
|
this.settings = Convenience.getSettings();
|
||||||
this.emitter = new DrawingAreaEmitter();
|
this.emitter = new DrawingAreaEmitter();
|
||||||
this.monitor = monitor;
|
this.monitor = monitor;
|
||||||
|
this.menu = new DrawingMenu(this);
|
||||||
this.helper = helper;
|
this.helper = helper;
|
||||||
|
|
||||||
this.elements = [];
|
this.elements = [];
|
||||||
|
|
@ -70,6 +85,7 @@ var DrawingArea = new Lang.Class({
|
||||||
this.hasBackground = false;
|
this.hasBackground = false;
|
||||||
this.textHasCursor = false;
|
this.textHasCursor = false;
|
||||||
this.dashedLine = false;
|
this.dashedLine = false;
|
||||||
|
this.fill = false;
|
||||||
this.colors = [Clutter.Color.new(0, 0, 0, 255)];
|
this.colors = [Clutter.Color.new(0, 0, 0, 255)];
|
||||||
|
|
||||||
if (loadJson)
|
if (loadJson)
|
||||||
|
|
@ -154,18 +170,27 @@ var DrawingArea = new Lang.Class({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (button == 1) {
|
if (button == 1) {
|
||||||
this._startDrawing(x, y, false, shiftPressed);
|
this._startDrawing(x, y, shiftPressed);
|
||||||
return Clutter.EVENT_STOP;
|
return Clutter.EVENT_STOP;
|
||||||
} else if (button == 2) {
|
} else if (button == 2) {
|
||||||
this.toggleShape();
|
this.toggleShape();
|
||||||
} else if (button == 3) {
|
} else if (button == 3) {
|
||||||
this._startDrawing(x, y, true, shiftPressed);
|
this._stopDrawing();
|
||||||
|
this.menu.open(x, y);
|
||||||
return Clutter.EVENT_STOP;
|
return Clutter.EVENT_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Clutter.EVENT_PROPAGATE;
|
return Clutter.EVENT_PROPAGATE;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onKeyboardPopupMenu: function() {
|
||||||
|
this._stopDrawing();
|
||||||
|
if (this.helper.visible)
|
||||||
|
this.helper.hideHelp();
|
||||||
|
this.menu.popup();
|
||||||
|
return Clutter.EVENT_STOP;
|
||||||
|
},
|
||||||
|
|
||||||
_onKeyPressed: function(actor, event) {
|
_onKeyPressed: function(actor, event) {
|
||||||
if (event.get_key_symbol() == Clutter.Escape) {
|
if (event.get_key_symbol() == Clutter.Escape) {
|
||||||
this.emitter.emit('stop-drawing');
|
this.emitter.emit('stop-drawing');
|
||||||
|
|
@ -213,7 +238,7 @@ var DrawingArea = new Lang.Class({
|
||||||
return Clutter.EVENT_STOP;
|
return Clutter.EVENT_STOP;
|
||||||
},
|
},
|
||||||
|
|
||||||
_startDrawing: function(stageX, stageY, fill, eraser) {
|
_startDrawing: function(stageX, stageY, eraser) {
|
||||||
let [success, startX, startY] = this.transform_stage_point(stageX, stageY);
|
let [success, startX, startY] = this.transform_stage_point(stageX, stageY);
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
|
|
@ -230,7 +255,7 @@ var DrawingArea = new Lang.Class({
|
||||||
color: this.currentColor.to_string(),
|
color: this.currentColor.to_string(),
|
||||||
line: { lineWidth: this.currentLineWidth, lineJoin: this.currentLineJoin, lineCap: this.currentLineCap },
|
line: { lineWidth: this.currentLineWidth, lineJoin: this.currentLineJoin, lineCap: this.currentLineCap },
|
||||||
dash: { array: this.dashedLine ? this.dashArray : [0, 0] , offset: this.dashedLine ? this.dashOffset : 0 },
|
dash: { array: this.dashedLine ? this.dashArray : [0, 0] , offset: this.dashedLine ? this.dashOffset : 0 },
|
||||||
fill: fill,
|
fill: this.fill,
|
||||||
eraser: eraser,
|
eraser: eraser,
|
||||||
transform: { active: false, center: [0, 0], angle: 0, startAngle: 0, ratio: 1 },
|
transform: { active: false, center: [0, 0], angle: 0, startAngle: 0, ratio: 1 },
|
||||||
text: '',
|
text: '',
|
||||||
|
|
@ -406,6 +431,11 @@ var DrawingArea = new Lang.Class({
|
||||||
this.selectShape((this.currentShape == Object.keys(Shapes).length - 1) ? 0 : this.currentShape + 1);
|
this.selectShape((this.currentShape == Object.keys(Shapes).length - 1) ? 0 : this.currentShape + 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
toggleFill: function() {
|
||||||
|
this.fill = !this.fill;
|
||||||
|
this.emitter.emit('show-osd', this.fill ? _("Fill") : _("Stroke"), null);
|
||||||
|
},
|
||||||
|
|
||||||
toggleDash: function() {
|
toggleDash: function() {
|
||||||
this.dashedLine = !this.dashedLine;
|
this.dashedLine = !this.dashedLine;
|
||||||
this.emitter.emit('show-osd', this.dashedLine ? _("Dashed line") : _("Full line"), null);
|
this.emitter.emit('show-osd', this.dashedLine ? _("Dashed line") : _("Full line"), null);
|
||||||
|
|
@ -464,6 +494,7 @@ var DrawingArea = new Lang.Class({
|
||||||
enterDrawingMode: function() {
|
enterDrawingMode: function() {
|
||||||
this.keyPressedHandler = this.connect('key-press-event', this._onKeyPressed.bind(this));
|
this.keyPressedHandler = this.connect('key-press-event', this._onKeyPressed.bind(this));
|
||||||
this.buttonPressedHandler = this.connect('button-press-event', this._onButtonPressed.bind(this));
|
this.buttonPressedHandler = this.connect('button-press-event', this._onButtonPressed.bind(this));
|
||||||
|
this._onKeyboardPopupMenuHandler = this.connect('popup-menu', this._onKeyboardPopupMenu.bind(this));
|
||||||
this.scrollHandler = this.connect('scroll-event', this._onScroll.bind(this));
|
this.scrollHandler = this.connect('scroll-event', this._onScroll.bind(this));
|
||||||
this.selectShape(Shapes.NONE);
|
this.selectShape(Shapes.NONE);
|
||||||
this.get_parent().set_background_color(this.hasBackground ? this.activeBackgroundColor : null);
|
this.get_parent().set_background_color(this.hasBackground ? this.activeBackgroundColor : null);
|
||||||
|
|
@ -479,6 +510,10 @@ var DrawingArea = new Lang.Class({
|
||||||
this.disconnect(this.buttonPressedHandler);
|
this.disconnect(this.buttonPressedHandler);
|
||||||
this.buttonPressedHandler = null;
|
this.buttonPressedHandler = null;
|
||||||
}
|
}
|
||||||
|
if (this._onKeyboardPopupMenuHandler) {
|
||||||
|
this.disconnect(this._onKeyboardPopupMenuHandler);
|
||||||
|
this._onKeyboardPopupMenuHandler = null;
|
||||||
|
}
|
||||||
if (this.motionHandler) {
|
if (this.motionHandler) {
|
||||||
this.disconnect(this.motionHandler);
|
this.disconnect(this.motionHandler);
|
||||||
this.motionHandler = null;
|
this.motionHandler = null;
|
||||||
|
|
@ -498,7 +533,9 @@ var DrawingArea = new Lang.Class({
|
||||||
this.currentElement = null;
|
this.currentElement = null;
|
||||||
this._stopCursorTimeout();
|
this._stopCursorTimeout();
|
||||||
this.dashedLine = false;
|
this.dashedLine = false;
|
||||||
|
this.fill = false;
|
||||||
this._redisplay();
|
this._redisplay();
|
||||||
|
this.menu.close();
|
||||||
this.get_parent().set_background_color(null);
|
this.get_parent().set_background_color(null);
|
||||||
if (save)
|
if (save)
|
||||||
this.saveAsJson();
|
this.saveAsJson();
|
||||||
|
|
@ -584,6 +621,7 @@ var DrawingArea = new Lang.Class({
|
||||||
|
|
||||||
disable: function() {
|
disable: function() {
|
||||||
this.erase();
|
this.erase();
|
||||||
|
this.menu.disable();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -941,3 +979,221 @@ var DrawingHelper = new Lang.Class({
|
||||||
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var DrawingMenu = new Lang.Class({
|
||||||
|
Name: 'DrawOnYourScreenDrawingMenu',
|
||||||
|
|
||||||
|
_init: function(area) {
|
||||||
|
this.area = area;
|
||||||
|
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);
|
||||||
|
this.menuManager = new PopupMenu.PopupMenuManager({ actor: this.area });
|
||||||
|
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');
|
||||||
|
this.menu.actor.hide();
|
||||||
|
|
||||||
|
// do not close the menu on item activated
|
||||||
|
this.menu.itemActivated = () => {};
|
||||||
|
this.menu.connect('open-state-changed', this._onMenuOpenStateChanged.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
disable: function() {
|
||||||
|
this.menuManager.removeMenu(this.menu);
|
||||||
|
Main.layoutManager.uiGroup.remove_actor(this.menu.actor);
|
||||||
|
this.menu.actor.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onMenuOpenStateChanged: function(menu, open) {
|
||||||
|
if (!open)
|
||||||
|
// actionMode has changed, set previous actionMode in order to keep internal shortcuts working
|
||||||
|
Main.actionMode = ExtensionJs.DRAWING_ACTION_MODE | Shell.ActionMode.NORMAL;
|
||||||
|
},
|
||||||
|
|
||||||
|
popup: function() {
|
||||||
|
if (this.menu.isOpen) {
|
||||||
|
this.close();
|
||||||
|
} else {
|
||||||
|
this.open();
|
||||||
|
this.menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
open: function(x, y) {
|
||||||
|
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];
|
||||||
|
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();
|
||||||
|
},
|
||||||
|
|
||||||
|
close: function() {
|
||||||
|
if (this.menu.isOpen)
|
||||||
|
this.menu.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
_redisplay: function() {
|
||||||
|
this.menu.removeAll();
|
||||||
|
|
||||||
|
this.menu.addAction(_("Undo"), this.area.undo.bind(this.area), 'edit-undo-symbolic');
|
||||||
|
this.menu.addAction(_("Redo"), this.area.redo.bind(this.area), 'edit-redo-symbolic');
|
||||||
|
this.menu.addAction(_("Erase"), this.area.deleteLastElement.bind(this.area), 'edit-clear-all-symbolic');
|
||||||
|
this.menu.addAction(_("Smooth"), this.area.smoothLastElement.bind(this.area), 'format-text-strikethrough-symbolic');
|
||||||
|
this._addSeparator(this.menu);
|
||||||
|
|
||||||
|
this._addSubMenuItem(this.menu, null, ShapeNames, this.area, 'currentShape', this.updateSectionVisibility.bind(this));
|
||||||
|
this._addColorSubMenuItem(this.menu);
|
||||||
|
let fillIcon = GdkPixbuf.Pixbuf.new_from_file_at_size(FILL_ICON_PATH, 24, 24);
|
||||||
|
this._addSwitchItem(this.menu, _("Fill"), fillIcon, this.area, 'fill', this.updateSectionVisibility.bind(this));
|
||||||
|
this._addSeparator(this.menu);
|
||||||
|
|
||||||
|
let lineSection = new PopupMenu.PopupMenuSection();
|
||||||
|
this._addSliderItem(lineSection, this.area, 'currentLineWidth');
|
||||||
|
let linejoinIcon = GdkPixbuf.Pixbuf.new_from_file_at_size(LINEJOIN_ICON_PATH, 24, 24);
|
||||||
|
this._addSubMenuItem(lineSection, linejoinIcon, LineJoinNames, this.area, 'currentLineJoin');
|
||||||
|
let linecapIcon = GdkPixbuf.Pixbuf.new_from_file_at_size(LINECAP_ICON_PATH, 24, 24);
|
||||||
|
this._addSubMenuItem(lineSection, linecapIcon, LineCapNames, this.area, 'currentLineCap');
|
||||||
|
let dashedLineIcon = GdkPixbuf.Pixbuf.new_from_file_at_size(DASHED_LINE_ICON_PATH, 24, 24);
|
||||||
|
this._addSwitchItem(lineSection, _("Dashed"), dashedLineIcon, this.area, 'dashedLine');
|
||||||
|
this._addSeparator(lineSection);
|
||||||
|
this.menu.addMenuItem(lineSection);
|
||||||
|
this.lineSection = lineSection;
|
||||||
|
|
||||||
|
let fontSection = new PopupMenu.PopupMenuSection();
|
||||||
|
let FontFamilyNamesCopy = Object.create(FontFamilyNames);
|
||||||
|
FontFamilyNamesCopy[0] = this.area.fontFamily;
|
||||||
|
this._addSubMenuItem(fontSection, 'font-x-generic-symbolic', FontFamilyNamesCopy, this.area, 'currentFontFamilyId');
|
||||||
|
this._addSubMenuItem(fontSection, 'format-text-bold-symbolic', FontWeightNames, this.area, 'currentFontWeight');
|
||||||
|
this._addSubMenuItem(fontSection, 'format-text-italic-symbolic', FontStyleNames, this.area, 'currentFontStyle');
|
||||||
|
this._addSeparator(fontSection);
|
||||||
|
this.menu.addMenuItem(fontSection);
|
||||||
|
this.fontSection = fontSection;
|
||||||
|
|
||||||
|
let manager = ExtensionJs.manager;
|
||||||
|
this._addSwitchItemWithCallback(this.menu, _("Hide panel and dock"), manager.hiddenList ? true : false, manager.togglePanelAndDockOpacity.bind(manager));
|
||||||
|
this._addSwitchItemWithCallback(this.menu, _("Add a drawing background"), this.area.hasBackground, this.area.toggleBackground.bind(this.area));
|
||||||
|
this._addSwitchItemWithCallback(this.menu, _("Square drawing area"), this.area.isSquareArea, this.area.toggleSquareArea.bind(this.area));
|
||||||
|
this._addSeparator(this.menu);
|
||||||
|
|
||||||
|
this.menu.addAction(_("Save drawing as a SVG file"), this.area.saveAsSvg.bind(this.area), 'document-save-symbolic');
|
||||||
|
this.menu.addAction(_("Open stylesheet.css"), manager.openStylesheetFile.bind(manager), 'document-open-symbolic');
|
||||||
|
this.menu.addAction(_("Show help"), this.area.toggleHelp.bind(this.area), 'preferences-desktop-keyboard-shortcuts-symbolic');
|
||||||
|
|
||||||
|
this.updateSectionVisibility();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateSectionVisibility: function() {
|
||||||
|
if (this.area.fill || this.area.currentShape == Shapes.TEXT)
|
||||||
|
this.lineSection.actor.hide();
|
||||||
|
else
|
||||||
|
this.lineSection.actor.show();
|
||||||
|
|
||||||
|
if (this.area.currentShape != Shapes.TEXT)
|
||||||
|
this.fontSection.actor.hide();
|
||||||
|
else
|
||||||
|
this.fontSection.actor.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
_addSwitchItem: function(menu, label, icon, target, targetProperty, callback) {
|
||||||
|
let item = new PopupMenu.PopupSwitchMenuItem(label, target[targetProperty]);
|
||||||
|
|
||||||
|
if (icon) {
|
||||||
|
item.icon = new St.Icon({ style_class: 'popup-menu-icon' });
|
||||||
|
item.actor.insert_child_at_index(item.icon, 1);
|
||||||
|
if (icon instanceof GObject.Object && GObject.type_is_a(icon, GdkPixbuf.Pixbuf))
|
||||||
|
item.icon.set_gicon(icon);
|
||||||
|
else
|
||||||
|
item.icon.set_icon_name(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
item.connect('toggled', (item, state) => {
|
||||||
|
target[targetProperty] = state;
|
||||||
|
if (callback)
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
menu.addMenuItem(item);
|
||||||
|
},
|
||||||
|
|
||||||
|
_addSwitchItemWithCallback: function(menu, label, active, onToggled) {
|
||||||
|
let item = new PopupMenu.PopupSwitchMenuItem(label, active);
|
||||||
|
item.connect('toggled', onToggled);
|
||||||
|
menu.addMenuItem(item);
|
||||||
|
},
|
||||||
|
|
||||||
|
_addSliderItem: function(menu, target, targetProperty) {
|
||||||
|
let item = new PopupMenu.PopupBaseMenuItem({ activate: false });
|
||||||
|
let label = new St.Label({ text: target[targetProperty] + " px", style_class: 'draw-on-your-screen-menu-slider-label' });
|
||||||
|
let slider = new Slider.Slider(target[targetProperty] / 50);
|
||||||
|
|
||||||
|
slider.connect('value-changed', (slider, value, property) => {
|
||||||
|
target[targetProperty] = Math.max(Math.round(value * 50), 1);
|
||||||
|
label.set_text(target[targetProperty] + " px");
|
||||||
|
});
|
||||||
|
|
||||||
|
item.actor.add(slider.actor, { expand: true });
|
||||||
|
item.actor.add(label);
|
||||||
|
item.actor.connect('key-press-event', slider.onKeyPressEvent.bind(slider));
|
||||||
|
menu.addMenuItem(item);
|
||||||
|
},
|
||||||
|
|
||||||
|
_addSubMenuItem: function(menu, icon, obj, target, targetProperty, callback) {
|
||||||
|
let item = new PopupMenu.PopupSubMenuMenuItem(_(obj[target[targetProperty]]), icon ? true : false);
|
||||||
|
if (icon && icon instanceof GObject.Object && GObject.type_is_a(icon, GdkPixbuf.Pixbuf))
|
||||||
|
item.icon.set_gicon(icon);
|
||||||
|
else if (icon)
|
||||||
|
item.icon.set_icon_name(icon);
|
||||||
|
|
||||||
|
item.menu.itemActivated = () => {
|
||||||
|
item.menu.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
Mainloop.timeout_add(0, () => {
|
||||||
|
for (let i in obj) {
|
||||||
|
item.menu.addAction(_(obj[i]), () => {
|
||||||
|
item.label.set_text(_(obj[i]));
|
||||||
|
target[targetProperty] = i;
|
||||||
|
if (callback)
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return GLib.SOURCE_REMOVE;
|
||||||
|
});
|
||||||
|
menu.addMenuItem(item);
|
||||||
|
},
|
||||||
|
|
||||||
|
_addColorSubMenuItem: function(menu) {
|
||||||
|
let item = new PopupMenu.PopupSubMenuMenuItem(_("Color"), true);
|
||||||
|
item.icon.set_icon_name('document-edit-symbolic');
|
||||||
|
item.icon.set_style(`color:${this.area.currentColor.to_string().slice(0, 7)};`);
|
||||||
|
|
||||||
|
item.menu.itemActivated = () => {
|
||||||
|
item.menu.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
Mainloop.timeout_add(0, () => {
|
||||||
|
for (let i = 1; i < this.area.colors.length; i++) {
|
||||||
|
let text = `<span foreground="${this.area.colors[i].to_string()}">${this.area.colors[i].to_string()}</span>`;
|
||||||
|
let colorItem = item.menu.addAction(text, () => {
|
||||||
|
this.area.currentColor = this.area.colors[i];
|
||||||
|
item.icon.set_style(`color:${this.area.currentColor.to_string().slice(0, 7)};`);
|
||||||
|
});
|
||||||
|
colorItem.label.get_clutter_text().set_use_markup(true);
|
||||||
|
}
|
||||||
|
return GLib.SOURCE_REMOVE;
|
||||||
|
});
|
||||||
|
menu.addMenuItem(item);
|
||||||
|
},
|
||||||
|
|
||||||
|
_addSeparator: function(menu) {
|
||||||
|
let separator = new PopupMenu.PopupSeparatorMenuItem(' ');
|
||||||
|
separator.actor.add_style_class_name('draw-on-your-screen-menu-separator');
|
||||||
|
menu.addMenuItem(separator);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
||||||
12
extension.js
12
extension.js
|
|
@ -32,6 +32,9 @@ const Convenience = Extension.imports.convenience;
|
||||||
const Draw = Extension.imports.draw;
|
const Draw = Extension.imports.draw;
|
||||||
const _ = imports.gettext.domain(Extension.metadata["gettext-domain"]).gettext;
|
const _ = imports.gettext.domain(Extension.metadata["gettext-domain"]).gettext;
|
||||||
|
|
||||||
|
// DRAWING_ACTION_MODE is a custom Shell.ActionMode
|
||||||
|
var DRAWING_ACTION_MODE = Math.pow(2,14);
|
||||||
|
|
||||||
let manager;
|
let manager;
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
|
@ -147,6 +150,7 @@ var AreaManager = new Lang.Class({
|
||||||
'toggle-linejoin': this.activeArea.toggleLineJoin.bind(this.activeArea),
|
'toggle-linejoin': this.activeArea.toggleLineJoin.bind(this.activeArea),
|
||||||
'toggle-linecap': this.activeArea.toggleLineCap.bind(this.activeArea),
|
'toggle-linecap': this.activeArea.toggleLineCap.bind(this.activeArea),
|
||||||
'toggle-dash' : this.activeArea.toggleDash.bind(this.activeArea),
|
'toggle-dash' : this.activeArea.toggleDash.bind(this.activeArea),
|
||||||
|
'toggle-fill' : this.activeArea.toggleFill.bind(this.activeArea),
|
||||||
'select-none-shape': () => this.activeArea.selectShape(Draw.Shapes.NONE),
|
'select-none-shape': () => this.activeArea.selectShape(Draw.Shapes.NONE),
|
||||||
'select-line-shape': () => this.activeArea.selectShape(Draw.Shapes.LINE),
|
'select-line-shape': () => this.activeArea.selectShape(Draw.Shapes.LINE),
|
||||||
'select-ellipse-shape': () => this.activeArea.selectShape(Draw.Shapes.ELLIPSE),
|
'select-ellipse-shape': () => this.activeArea.selectShape(Draw.Shapes.ELLIPSE),
|
||||||
|
|
@ -164,7 +168,7 @@ var AreaManager = new Lang.Class({
|
||||||
Main.wm.addKeybinding(key,
|
Main.wm.addKeybinding(key,
|
||||||
this.settings,
|
this.settings,
|
||||||
Meta.KeyBindingFlags.NONE,
|
Meta.KeyBindingFlags.NONE,
|
||||||
256,
|
DRAWING_ACTION_MODE,
|
||||||
this.internalKeybindings[key]);
|
this.internalKeybindings[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,7 +176,7 @@ var AreaManager = new Lang.Class({
|
||||||
Main.wm.addKeybinding('select-color' + i,
|
Main.wm.addKeybinding('select-color' + i,
|
||||||
this.settings,
|
this.settings,
|
||||||
Meta.KeyBindingFlags.NONE,
|
Meta.KeyBindingFlags.NONE,
|
||||||
256,
|
DRAWING_ACTION_MODE,
|
||||||
() => this.activeArea.selectColor(i));
|
() => this.activeArea.selectColor(i));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -270,8 +274,8 @@ var AreaManager = new Lang.Class({
|
||||||
activeContainer.get_parent().remove_actor(activeContainer);
|
activeContainer.get_parent().remove_actor(activeContainer);
|
||||||
Main.uiGroup.add_child(activeContainer);
|
Main.uiGroup.add_child(activeContainer);
|
||||||
|
|
||||||
// 256 is a custom Shell.ActionMode
|
// add Shell.ActionMode.NORMAL to keep system keybindings enabled (e.g. Alt + F2 ...)
|
||||||
if (!Main.pushModal(this.areas[currentIndex], { actionMode: 256 | 1 }))
|
if (!Main.pushModal(this.areas[currentIndex], { actionMode: DRAWING_ACTION_MODE | Shell.ActionMode.NORMAL }))
|
||||||
return;
|
return;
|
||||||
this.activeArea = this.areas[currentIndex];
|
this.activeArea = this.areas[currentIndex];
|
||||||
this.addInternalKeybindings();
|
this.addInternalKeybindings();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg viewBox="0 0 576 576" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill="transparent" stroke="#eeeeec" stroke-width="110" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="25 150.5" stroke-dashoffset="0" d="M100 288 L 476 288"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 255 B |
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg viewBox="0 0 576 576" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<ellipse fill="#eeeeec" stroke="transparent" cx="288" cy="288" rx="260" ry="180"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 155 B |
|
|
@ -0,0 +1,4 @@
|
||||||
|
<svg viewBox="0 0 576 576" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill="transparent" stroke="#eeeeec" stroke-width="250" stroke-linecap="butt" stroke-linejoin="round" d="M50 288 L 350 288"/>
|
||||||
|
<path fill="transparent" stroke="#eeeeec" stroke-width="250" stroke-linecap="round" stroke-linejoin="round" d="M300 288 L 400 288"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 338 B |
|
|
@ -0,0 +1,4 @@
|
||||||
|
<svg viewBox="0 0 576 576" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill="transparent" stroke="#eeeeec" stroke-width="110" stroke-linecap="round" stroke-linejoin="round" d="M288 90 L 55 512"/>
|
||||||
|
<path fill="transparent" stroke="#eeeeec" stroke-width="110" stroke-linecap="round" stroke-linejoin="round" d="M288 90 L 514 512"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 337 B |
|
|
@ -43,6 +43,12 @@ msgstr ""
|
||||||
msgid "Text"
|
msgid "Text"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Fill"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Stroke"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Dashed line"
|
msgid "Dashed line"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -69,6 +75,21 @@ msgstr ""
|
||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Redo"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Erase"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Smooth"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Dashed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: prefs.js
|
#: prefs.js
|
||||||
|
|
||||||
# GLOBAL_KEYBINDINGS
|
# GLOBAL_KEYBINDINGS
|
||||||
|
|
@ -93,6 +114,24 @@ msgstr ""
|
||||||
msgid "Smooth last brushstroke"
|
msgid "Smooth last brushstroke"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Select line"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Select ellipse"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Select rectangle"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Select text"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Unselect shape (free drawing)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Select fill/stroke"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Increment line width"
|
msgid "Increment line width"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -115,21 +154,6 @@ msgstr ""
|
||||||
#msgid "Dashed line"
|
#msgid "Dashed line"
|
||||||
#msgstr ""
|
#msgstr ""
|
||||||
|
|
||||||
msgid "Select line"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Select ellipse"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Select rectangle"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Select text"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Unselect shape (free drawing)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Change font family (generic name)"
|
msgid "Change font family (generic name)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
||||||
13
prefs.js
13
prefs.js
|
|
@ -43,6 +43,13 @@ var INTERNAL_KEYBINDINGS = {
|
||||||
'delete-last-element' : "Erase last brushstroke",
|
'delete-last-element' : "Erase last brushstroke",
|
||||||
'smooth-last-element': "Smooth last brushstroke",
|
'smooth-last-element': "Smooth last brushstroke",
|
||||||
'-separator-1': '',
|
'-separator-1': '',
|
||||||
|
'select-line-shape': "Select line",
|
||||||
|
'select-ellipse-shape': "Select ellipse",
|
||||||
|
'select-rectangle-shape': "Select rectangle",
|
||||||
|
'select-text-shape': "Select text",
|
||||||
|
'select-none-shape': "Unselect shape (free drawing)",
|
||||||
|
'toggle-fill': "Select fill/stroke",
|
||||||
|
'-separator-2': '',
|
||||||
'increment-line-width': "Increment line width",
|
'increment-line-width': "Increment line width",
|
||||||
'decrement-line-width': "Decrement line width",
|
'decrement-line-width': "Decrement line width",
|
||||||
'increment-line-width-more': "Increment line width even more",
|
'increment-line-width-more': "Increment line width even more",
|
||||||
|
|
@ -50,12 +57,6 @@ var INTERNAL_KEYBINDINGS = {
|
||||||
'toggle-linejoin': "Change linejoin",
|
'toggle-linejoin': "Change linejoin",
|
||||||
'toggle-linecap': "Change linecap",
|
'toggle-linecap': "Change linecap",
|
||||||
'toggle-dash': "Dashed line",
|
'toggle-dash': "Dashed line",
|
||||||
'-separator-2': '',
|
|
||||||
'select-line-shape': "Select line",
|
|
||||||
'select-ellipse-shape': "Select ellipse",
|
|
||||||
'select-rectangle-shape': "Select rectangle",
|
|
||||||
'select-text-shape': "Select text",
|
|
||||||
'select-none-shape': "Unselect shape (free drawing)",
|
|
||||||
'-separator-3': '',
|
'-separator-3': '',
|
||||||
'toggle-font-family': "Change font family (generic name)",
|
'toggle-font-family': "Change font family (generic name)",
|
||||||
'toggle-font-weight': "Change font weight",
|
'toggle-font-weight': "Change font weight",
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -117,10 +117,15 @@
|
||||||
<description>toggle linecap</description>
|
<description>toggle linecap</description>
|
||||||
</key>
|
</key>
|
||||||
<key type="as" name="toggle-dash">
|
<key type="as" name="toggle-dash">
|
||||||
<default>["<Primary>a"]</default>
|
<default>["<Primary>period"]</default>
|
||||||
<summary>toggle dash</summary>
|
<summary>toggle dash</summary>
|
||||||
<description>toggle dash</description>
|
<description>toggle dash</description>
|
||||||
</key>
|
</key>
|
||||||
|
<key type="as" name="toggle-fill">
|
||||||
|
<default>["<Primary>a"]</default>
|
||||||
|
<summary>toggle fill</summary>
|
||||||
|
<description>toggle fill</description>
|
||||||
|
</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 color1</summary>
|
<summary>select color1</summary>
|
||||||
|
|
|
||||||
|
|
@ -77,4 +77,24 @@
|
||||||
min-height: 0.6em;
|
min-height: 0.6em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* context menu */
|
||||||
|
|
||||||
|
.draw-on-your-screen-menu {
|
||||||
|
font-size: 0.98em; /* default: 1em */
|
||||||
|
}
|
||||||
|
|
||||||
|
.draw-on-your-screen-menu .popup-menu-item {
|
||||||
|
padding-top: .37em; /* default: .4em */
|
||||||
|
padding-bottom: .37em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.draw-on-your-screen-menu-separator StLabel {
|
||||||
|
font-size: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.draw-on-your-screen-menu-slider-label {
|
||||||
|
min-width: 3em;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue