add persistence feature
This commit is contained in:
parent
0c17e2cfbe
commit
2b25958d8c
74
draw.js
74
draw.js
|
|
@ -52,7 +52,7 @@ var DrawingArea = new Lang.Class({
|
|||
Name: 'DrawOnYourScreenDrawingArea',
|
||||
Extends: St.DrawingArea,
|
||||
|
||||
_init: function(params, monitor, helper) {
|
||||
_init: function(params, monitor, helper, loadJson) {
|
||||
this.parent({ style_class: 'draw-on-your-screen', name: params && params.name ? params.name : ""});
|
||||
|
||||
// 'style-changed' is emitted when 'this' is added to an actor
|
||||
|
|
@ -74,6 +74,9 @@ var DrawingArea = new Lang.Class({
|
|||
this.textHasCursor = false;
|
||||
this.dashedLine = false;
|
||||
this.colors = [Clutter.Color.new(0, 0, 0, 255)];
|
||||
|
||||
if (loadJson)
|
||||
this._loadJson();
|
||||
},
|
||||
|
||||
_redisplay: function() {
|
||||
|
|
@ -225,12 +228,12 @@ var DrawingArea = new Lang.Class({
|
|||
this.smoothedStroke = this.settings.get_boolean('smoothed-stroke');
|
||||
|
||||
this.currentElement = new DrawingElement ({
|
||||
color: this.currentColor,
|
||||
shape: this.currentShape == Shapes.TEXT ? Shapes.RECTANGLE : this.currentShape,
|
||||
color: this.currentColor.to_string(),
|
||||
line: { lineWidth: this.currentLineWidth, lineJoin: this.currentLineJoin, lineCap: this.currentLineCap },
|
||||
dash: { array: this.dashedLine ? this.dashArray : [0, 0] , offset: this.dashedLine ? this.dashOffset : 0 },
|
||||
fill: fill,
|
||||
eraser: eraser,
|
||||
shape: this.currentShape == Shapes.TEXT ? Shapes.RECTANGLE : this.currentShape,
|
||||
transform: { active: false, center: [0, 0], angle: 0, startAngle: 0, ratio: 1 },
|
||||
text: '',
|
||||
font: { family: (this.currentFontFamilyId == 0 ? this.fontFamily : FontFamilyNames[this.currentFontFamilyId]), weight: this.currentFontWeight, style: this.currentFontStyle },
|
||||
|
|
@ -390,7 +393,7 @@ var DrawingArea = new Lang.Class({
|
|||
selectColor: function(index) {
|
||||
this.currentColor = this.colors[index];
|
||||
if (this.currentElement) {
|
||||
this.currentElement.color = this.currentColor;
|
||||
this.currentElement.color = this.currentColor.to_string();
|
||||
this._redisplay();
|
||||
}
|
||||
this.emitter.emit('show-osd', this.currentColor.to_string(), null);
|
||||
|
|
@ -469,7 +472,7 @@ var DrawingArea = new Lang.Class({
|
|||
this.get_parent().set_background_color(this.hasBackground ? this.activeBackgroundColor : null);
|
||||
},
|
||||
|
||||
leaveDrawingMode: function() {
|
||||
leaveDrawingMode: function(save) {
|
||||
if (this.keyPressedHandler) {
|
||||
this.disconnect(this.keyPressedHandler);
|
||||
this.keyPressedHandler = null;
|
||||
|
|
@ -499,9 +502,11 @@ var DrawingArea = new Lang.Class({
|
|||
this.dashedLine = false;
|
||||
this._redisplay();
|
||||
this.get_parent().set_background_color(null);
|
||||
if (save)
|
||||
this._saveAsJson();
|
||||
},
|
||||
|
||||
save: function() {
|
||||
saveAsSvg: function() {
|
||||
// stop drawing or writing
|
||||
if (this.currentElement && this.currentElement.shape == Shapes.TEXT) {
|
||||
this._stopWriting();
|
||||
|
|
@ -535,6 +540,41 @@ var DrawingArea = new Lang.Class({
|
|||
}
|
||||
},
|
||||
|
||||
_saveAsJson: function() {
|
||||
let filename = `DrawOnYourScreen.json`;
|
||||
let dir = GLib.get_user_data_dir();
|
||||
let path = GLib.build_filenamev([dir, filename]);
|
||||
|
||||
let oldContents;
|
||||
if (GLib.file_test(path, GLib.FileTest.EXISTS)) {
|
||||
oldContents = GLib.file_get_contents(path)[1];
|
||||
if (oldContents instanceof Uint8Array)
|
||||
oldContents = imports.byteArray.toString(oldContents);
|
||||
}
|
||||
|
||||
// do not use "content = JSON.stringify(this.elements, null, 2);", neither "content = JSON.stringify(this.elements);"
|
||||
// because of compromise between disk usage and human readability
|
||||
let contents = `[\n ` + new Array(...this.elements.map(element => JSON.stringify(element))).join(`,\n\n `) + `\n]`;
|
||||
|
||||
if (contents != oldContents)
|
||||
GLib.file_set_contents(path, contents);
|
||||
},
|
||||
|
||||
_loadJson: function() {
|
||||
let filename = `DrawOnYourScreen.json`;
|
||||
let dir = GLib.get_user_data_dir();
|
||||
let path = GLib.build_filenamev([dir, filename]);
|
||||
|
||||
if (!GLib.file_test(path, GLib.FileTest.EXISTS))
|
||||
return;
|
||||
let [success, contents] = GLib.file_get_contents(path);
|
||||
if (!success)
|
||||
return;
|
||||
if (contents instanceof Uint8Array)
|
||||
contents = imports.byteArray.toString(contents);
|
||||
this.elements.push(...JSON.parse(contents).map(object => new DrawingElement(object)));
|
||||
},
|
||||
|
||||
disable: function() {
|
||||
this.erase();
|
||||
}
|
||||
|
|
@ -560,6 +600,22 @@ var DrawingElement = new Lang.Class({
|
|||
this[key] = params[key];
|
||||
},
|
||||
|
||||
// toJSON is called by JSON.stringify
|
||||
toJSON: function() {
|
||||
return {
|
||||
shape: this.shape,
|
||||
color: this.color,
|
||||
line: this.line,
|
||||
dash: this.dash,
|
||||
fill: this.fill,
|
||||
eraser: this.eraser,
|
||||
transform: this.transform,
|
||||
text: this.text,
|
||||
font: this.font,
|
||||
points: this.points.map((point) => [Math.round(point[0]*100)/100, Math.round(point[1]*100)/100])
|
||||
};
|
||||
},
|
||||
|
||||
buildCairo: function(cr, showTextCursor) {
|
||||
cr.setLineCap(this.line.lineCap);
|
||||
cr.setLineJoin(this.line.lineJoin);
|
||||
|
|
@ -575,7 +631,9 @@ var DrawingElement = new Lang.Class({
|
|||
else
|
||||
cr.setOperator(Cairo.Operator.OVER);
|
||||
|
||||
Clutter.cairo_set_source_color(cr, this.color);
|
||||
let [success, color] = Clutter.Color.from_string(this.color);
|
||||
if (success)
|
||||
Clutter.cairo_set_source_color(cr, color);
|
||||
|
||||
let [points, shape, trans] = [this.points, this.shape, this.transform];
|
||||
|
||||
|
|
@ -614,7 +672,7 @@ var DrawingElement = new Lang.Class({
|
|||
buildSVG: function(bgColor) {
|
||||
let row = "\n ";
|
||||
let points = this.points.map((point) => [Math.round(point[0]*100)/100, Math.round(point[1]*100)/100]);
|
||||
let color = this.eraser ? bgColor : this.color.to_string();
|
||||
let color = this.eraser ? bgColor : this.color;
|
||||
let isStraightLine = this.shape == Shapes.LINE && (points.length < 3 || points[2] == points[1] || points[2] == points[0]);
|
||||
let fill = this.fill && !isStraightLine;
|
||||
let attributes = `fill="${fill ? color : 'transparent'}" ` +
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ var AreaManager = new Lang.Class({
|
|||
let monitor = this.monitors[i];
|
||||
let container = new St.Widget({ name: 'drawOnYourSreenContainer' + i });
|
||||
let helper = new Draw.DrawingHelper({ name: 'drawOnYourSreenHelper' + i }, monitor);
|
||||
let area = new Draw.DrawingArea({ name: 'drawOnYourSreenArea' + i }, monitor, helper);
|
||||
let load = i == Main.layoutManager.primaryIndex && this.settings.get_boolean('persistent-drawing');
|
||||
let area = new Draw.DrawingArea({ name: 'drawOnYourSreenArea' + i }, monitor, helper, load);
|
||||
container.add_child(area);
|
||||
container.add_child(helper);
|
||||
|
||||
|
|
@ -122,7 +123,7 @@ var AreaManager = new Lang.Class({
|
|||
'redo': this.activeArea.redo.bind(this.activeArea),
|
||||
'delete-last-element': this.activeArea.deleteLastElement.bind(this.activeArea),
|
||||
'smooth-last-element': this.activeArea.smoothLastElement.bind(this.activeArea),
|
||||
'save-as-svg': this.activeArea.save.bind(this.activeArea),
|
||||
'save-as-svg': this.activeArea.saveAsSvg.bind(this.activeArea),
|
||||
'toggle-background': this.activeArea.toggleBackground.bind(this.activeArea),
|
||||
'toggle-square-area': this.activeArea.toggleSquareArea.bind(this.activeArea),
|
||||
'increment-line-width': () => this.activeArea.incrementLineWidth(1),
|
||||
|
|
@ -223,6 +224,7 @@ var AreaManager = new Lang.Class({
|
|||
if (this.activeArea) {
|
||||
let activeIndex = this.areas.indexOf(this.activeArea);
|
||||
let activeContainer = this.activeArea.get_parent();
|
||||
let save = activeIndex == Main.layoutManager.primaryIndex && this.settings.get_boolean('persistent-drawing');
|
||||
|
||||
if (this.hiddenList)
|
||||
this.togglePanelAndDockOpacity();
|
||||
|
|
@ -230,7 +232,7 @@ var AreaManager = new Lang.Class({
|
|||
Main.popModal(this.activeArea);
|
||||
this.removeInternalKeybindings();
|
||||
this.activeArea.reactive = false;
|
||||
this.activeArea.leaveDrawingMode();
|
||||
this.activeArea.leaveDrawingMode(save);
|
||||
this.activeArea = null;
|
||||
|
||||
activeContainer.get_parent().remove_actor(activeContainer);
|
||||
|
|
|
|||
|
|
@ -223,6 +223,12 @@ msgstr ""
|
|||
msgid "Draw On Your Screen becomes Draw On Your Desktop"
|
||||
msgstr ""
|
||||
|
||||
msgid "Persistent"
|
||||
msgstr ""
|
||||
|
||||
msgid "Persistent drawing through restart"
|
||||
msgstr ""
|
||||
|
||||
msgid "Internal"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
14
prefs.js
14
prefs.js
|
|
@ -139,6 +139,20 @@ const PrefsPage = new GObject.Class({
|
|||
desktopBox.pack_start(desktopLabelBox, true, true, 4);
|
||||
desktopBox.pack_start(desktopSwitch, false, false, 4);
|
||||
listBox.add(desktopBox);
|
||||
|
||||
let persistentBox = new Gtk.Box({ margin: MARGIN });
|
||||
let persistentLabelBox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
|
||||
let persistentLabel1 = new Gtk.Label({label: _("Persistent")});
|
||||
let persistentLabel2 = new Gtk.Label({ use_markup: true, halign: 1, label: "<small>" + _("Persistent drawing through restart") + "</small>" });
|
||||
persistentLabel1.set_halign(1);
|
||||
persistentLabel2.get_style_context().add_class("dim-label");
|
||||
persistentLabelBox.pack_start(persistentLabel1, true, true, 0);
|
||||
persistentLabelBox.pack_start(persistentLabel2, true, true, 0);
|
||||
let persistentSwitch = new Gtk.Switch({valign: 3});
|
||||
this.settings.bind("persistent-drawing", persistentSwitch, "active", 0);
|
||||
persistentBox.pack_start(persistentLabelBox, true, true, 4);
|
||||
persistentBox.pack_start(persistentSwitch, false, false, 4);
|
||||
listBox.add(persistentBox);
|
||||
this.addSeparator(listBox);
|
||||
|
||||
let internalTitleBox = new Gtk.Box({ margin: MARGIN });
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -11,6 +11,11 @@
|
|||
<summary>move drawing on desktop</summary>
|
||||
<description>move drawing on desktop</description>
|
||||
</key>
|
||||
<key type="b" name="persistent-drawing">
|
||||
<default>false</default>
|
||||
<summary>persistent drawing</summary>
|
||||
<description>persistent drawing</description>
|
||||
</key>
|
||||
<key type="as" name="toggle-drawing">
|
||||
<default>["<Alt><Super>d"]</default>
|
||||
<summary>toggle drawing</summary>
|
||||
|
|
|
|||
Loading…
Reference in New Issue