From 85084b8279a9562ad627aebeb36937b6ace43fa8 Mon Sep 17 00:00:00 2001 From: jdescottes Date: Mon, 10 Feb 2014 01:00:16 +0100 Subject: [PATCH 1/8] Added localstorage save + read --- css/settings.css | 40 +++++- index.html | 5 +- js/app.js | 6 +- js/controller/settings/SaveController.js | 63 ++++++++-- js/controller/settings/SettingsController.js | 4 + js/service/LocalStorageService.js | 121 +++++++++---------- js/utils/serialization/Deserializer.js | 5 +- piskel-script-list.js | 1 + templates/settings.html | 7 ++ templates/settings/save.html | 5 +- 10 files changed, 169 insertions(+), 88 deletions(-) diff --git a/css/settings.css b/css/settings.css index 41bf99c..829a727 100644 --- a/css/settings.css +++ b/css/settings.css @@ -56,6 +56,13 @@ position: relative; } +.tool-icon.local-storage-icon { + background-image: url(../img/local-storage-icon.png); + background-position: 10px 12px; + background-size: 30px; + position: relative; +} + .tool-icon.import-icon { background-image: url(../img/import-icon.png); background-position: 10px 5px; @@ -247,12 +254,10 @@ } #save-status { - margin-left: 10px; + margin-top: 10px; } .status { height: 1.5rem; - - word-break : break-all; vertical-align: middle; font-weight: normal; text-shadow: none; @@ -264,4 +269,33 @@ [name*=checkbox] { vertical-align: middle; +} + +.local-piskels-list { + width: 100%; +} + +.local-piskel-item { + height: 3em; +} + +.local-piskel-name { + width: 40%; +} + +.local-piskel-save-date { + font-weight : normal; +} + +.local-piskels-list a { + text-decoration: none; +} +.local-piskels-list a:hover { + text-decoration: underline; +} +.local-piskel-load-link { + color : gold; +} +.local-piskel-delete-link { + color : red; } \ No newline at end of file diff --git a/index.html b/index.html index 08bbd11..05d758b 100644 --- a/index.html +++ b/index.html @@ -9,8 +9,8 @@ -
+
diff --git a/js/app.js b/js/app.js index 3f37fcc..a217981 100644 --- a/js/app.js +++ b/js/app.js @@ -103,8 +103,6 @@ "content" : "Loading animation with id : [" + framesheetId + "]" }]); this.loadFramesheetFromService(framesheetId); - } else { - this.localStorageService.displayRestoreNotification(); } }, @@ -118,6 +116,10 @@ } }, + isLoggedIn : function () { + return pskl.appEnginePiskelData_ && pskl.appEnginePiskelData_.isLoggedIn; + }, + initTooltips_ : function () { $('body').tooltip({ selector: '[rel=tooltip]' diff --git a/js/controller/settings/SaveController.js b/js/controller/settings/SaveController.js index 0b10eeb..57d9c57 100644 --- a/js/controller/settings/SaveController.js +++ b/js/controller/settings/SaveController.js @@ -13,7 +13,12 @@ this.nameInput = $('#save-name'); this.descriptionInput = $('#save-description'); this.isPublicCheckbox = $('input[name=save-public-checkbox]'); - this.saveButton = $('#save-button'); + this.saveCloudButton = $('#save-cloud-button'); + this.saveLocalButton = $('#save-local-button'); + + // Only available in app-engine mode ... + this.piskelName = $('.piskel-name').get(0); + this.status = $('#save-status'); var descriptor = this.piskelController.piskel.getDescriptor(); @@ -22,21 +27,22 @@ this.isPublicCheckbox.prop('checked', descriptor.isPublic); - if (!pskl.app.isAppEngineVersion) { - this.nameInput.attr('disabled', 'disabled'); - this.descriptionInput.attr('disabled', 'disabled'); - this.isPublicCheckbox.attr('disabled', 'disabled'); + if (!pskl.app.isLoggedIn()) { + this.saveCloudButton.attr('disabled', 'disabled'); + this.status.html('You are not logged in. Only Local Save is available.'); + } else { + this.saveForm.submit(this.onSaveFormSubmit_.bind(this)); } - this.saveForm.submit(this.onSaveFormSubmit_.bind(this)); + this.saveLocalButton.click(this.onSaveLocalClick_.bind(this)); }; ns.SaveController.prototype.onSaveFormSubmit_ = function (evt) { evt.preventDefault(); evt.stopPropagation(); - var name = this.nameInput.val(); - var description = this.descriptionInput.val(); + var name = this.getName(); + var description = this.getDescription(); var isPublic = !!this.isPublicCheckbox.prop('checked'); var descriptor = new pskl.model.piskel.Descriptor(name, description, isPublic); @@ -50,10 +56,40 @@ }); }; + ns.SaveController.prototype.onSaveLocalClick_ = function (evt) { + var localStorageService = pskl.app.localStorageService; + var isOk = true; + var name = this.getName(); + var description = this.getDescription(); + if (localStorageService.getPiskel(name)) { + isOk = window.confirm('There is already a piskel saved as ' + name + '. Override ?'); + } + + if (isOk) { + this.beforeSaving_(); + localStorageService.save(name, description, pskl.app.piskelController.serialize()); + window.setTimeout(function () { + this.onSaveSuccess_(); + this.afterSaving_(); + }.bind(this), 1000); + } + }; + + ns.SaveController.prototype.getName = function () { + return this.nameInput.val(); + }; + + ns.SaveController.prototype.getDescription = function () { + return this.descriptionInput.val(); + }; + ns.SaveController.prototype.beforeSaving_ = function () { - this.saveButton.attr('disabled', true); + this.saveCloudButton.attr('disabled', true); this.status.html('Saving ...'); - $('.piskel-name').get(0).classList.add('piskel-name-saving'); + + if (this.piskelName) { + this.piskelName.classList.add('piskel-name-saving'); + } }; ns.SaveController.prototype.onSaveSuccess_ = function () { @@ -66,9 +102,12 @@ }; ns.SaveController.prototype.afterSaving_ = function () { - this.saveButton.attr('disabled', false); + this.saveCloudButton.attr('disabled', false); this.status.html(''); - $('.piskel-name').get(0).classList.remove('piskel-name-saving'); + + if (this.piskelName) { + this.piskelName.classList.remove('piskel-name-saving'); + } window.setTimeout($.publish.bind($, Events.HIDE_NOTIFICATION), 2000); }; diff --git a/js/controller/settings/SettingsController.js b/js/controller/settings/SettingsController.js index bc1f031..de4a0bd 100644 --- a/js/controller/settings/SettingsController.js +++ b/js/controller/settings/SettingsController.js @@ -18,6 +18,10 @@ template : 'templates/settings/import.html', controller : ns.ImportController }, + 'localstorage' : { + template : 'templates/settings/localstorage.html', + controller : ns.LocalStorageController + }, 'save' : { template : 'templates/settings/save.html', controller : ns.SaveController diff --git a/js/service/LocalStorageService.js b/js/service/LocalStorageService.js index c68cee3..62a174a 100644 --- a/js/service/LocalStorageService.js +++ b/js/service/LocalStorageService.js @@ -7,83 +7,74 @@ throw "Bad LocalStorageService initialization: "; } this.piskelController = piskelController; - this.localStorageThrottler_ = null; }; - /** - * @public - */ - ns.LocalStorageService.prototype.init = function(piskelController) { - $.subscribe(Events.LOCALSTORAGE_REQUEST, $.proxy(this.persistToLocalStorageRequest_, this)); + ns.LocalStorageService.prototype.init = function() {}; + +// localStorage.setItem('piskel_bkp', pskl.app.piskelController.serialize()) + + ns.LocalStorageService.prototype.save = function(name, description, piskel) { + this.removeFromKeys_(name); + this.addToKeys_(name, description, Date.now()); + window.localStorage.setItem('piskel.' + name, piskel); }; - /** - * @private - */ - ns.LocalStorageService.prototype.persistToLocalStorageRequest_ = function () { - // Persist to localStorage when drawing. We throttle localStorage accesses - // for high frequency drawing (eg mousemove). - if(this.localStorageThrottler_ !== null) { - window.clearTimeout(this.localStorageThrottler_); - } - this.localStorageThrottler_ = window.setTimeout($.proxy(function() { - this.persistToLocalStorage_(); - this.localStorageThrottler_ = null; - }, this), 1000); - }; + ns.LocalStorageService.prototype.load = function(name) { + var piskelString = this.getPiskel(name); + var key = this.getKey_(name); - /** - * @private - */ - ns.LocalStorageService.prototype.persistToLocalStorage_ = function() { - console.log('[LocalStorage service]: Snapshot stored'); - window.localStorage.snapShot = this.piskelController.serialize(); - }; - - /** - * @private - */ - ns.LocalStorageService.prototype.restoreFromLocalStorage_ = function() { - var framesheet = JSON.parse(window.localStorage.snapShot); - - pskl.utils.serialization.Deserializer.deserialize(framesheet, function (piskel) { + pskl.utils.serialization.Deserializer.deserialize(JSON.parse(piskelString), function (piskel) { + piskel.setDescriptor(new pskl.model.piskel.Descriptor(name, key.description, true)); pskl.app.piskelController.setPiskel(piskel); }); }; - /** - * @private - */ - ns.LocalStorageService.prototype.cleanLocalStorage_ = function() { - console.log('[LocalStorage service]: Snapshot removed'); - delete window.localStorage.snapShot; + ns.LocalStorageService.prototype.remove = function(name) { + this.removeFromKeys_(name); + window.localStorage.removeItem('piskel.' + name); }; - /** - * @public - */ - ns.LocalStorageService.prototype.displayRestoreNotification = function() { - if(window.localStorage && window.localStorage.snapShot) { - var reloadLink = "reload"; - var discardLink = "discard"; - var content = "Non saved version found. " + reloadLink + " or " + discardLink; + ns.LocalStorageService.prototype.saveKeys_ = function(keys) { + window.localStorage.setItem('piskel.keys', JSON.stringify(keys)); + }; - $.publish(Events.SHOW_NOTIFICATION, [{ - "content": content, - "behavior": $.proxy(function(rootNode) { - rootNode = $(rootNode); - rootNode.click($.proxy(function(evt) { - var target = $(evt.target); - if(target.hasClass("localstorage-restore")) { - this.restoreFromLocalStorage_(); - } - else if (target.hasClass("localstorage-discard")) { - this.cleanLocalStorage_(); - } - $.publish(Events.HIDE_NOTIFICATION); - }, this)); - }, this) - }]); + ns.LocalStorageService.prototype.removeFromKeys_ = function(name) { + var keys = this.getKeys(); + var otherKeys = keys.filter(function (key) { + return key.name !== name; + }); + + this.saveKeys_(otherKeys); + }; + + ns.LocalStorageService.prototype.getKey_ = function(name) { + var matches = this.getKeys().filter(function (key) { + return key.name === name; + }); + if (matches.length > 0) { + return matches[0]; + } else { + return null; } }; + + ns.LocalStorageService.prototype.addToKeys_ = function(name, description, date) { + var keys = this.getKeys(); + keys.push({ + name : name, + description : description, + date : date + }); + this.saveKeys_(keys); + }; + + ns.LocalStorageService.prototype.getPiskel = function(name) { + return window.localStorage.getItem('piskel.' + name); + }; + + ns.LocalStorageService.prototype.getKeys = function(name) { + var keysString = window.localStorage.getItem('piskel.keys'); + return JSON.parse(keysString) || []; + }; + })(); \ No newline at end of file diff --git a/js/utils/serialization/Deserializer.js b/js/utils/serialization/Deserializer.js index 799b1f0..5c35322 100644 --- a/js/utils/serialization/Deserializer.js +++ b/js/utils/serialization/Deserializer.js @@ -20,11 +20,12 @@ deserializer.deserialize(); }; - ns.Deserializer.prototype.deserialize = function () { + ns.Deserializer.prototype.deserialize = function (name) { var data = this.data_; var piskelData = data.piskel; + name = name || 'Deserialized piskel'; - var descriptor = new pskl.model.piskel.Descriptor('Deserialized piskel', ''); + var descriptor = new pskl.model.piskel.Descriptor(name, ''); this.piskel_ = new pskl.model.Piskel(piskelData.width, piskelData.height, descriptor); this.layersToLoad_ = piskelData.layers.length; diff --git a/piskel-script-list.js b/piskel-script-list.js index 27286ea..0e92ebb 100644 --- a/piskel-script-list.js +++ b/piskel-script-list.js @@ -72,6 +72,7 @@ exports.scripts = [ "js/controller/settings/ApplicationSettingsController.js", "js/controller/settings/ResizeController.js", "js/controller/settings/GifExportController.js", + "js/controller/settings/LocalStorageController.js", "js/controller/settings/SaveController.js", "js/controller/settings/ImportController.js", // Settings controller diff --git a/templates/settings.html b/templates/settings.html index 80ac056..bb12a43 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -27,6 +27,13 @@ rel="tooltip" data-placement="left"> +
+
+
- - + + +
\ No newline at end of file From bd0adda73f6851ef0613d3c49fb12d9cecef33b4 Mon Sep 17 00:00:00 2001 From: jdescottes Date: Tue, 11 Feb 2014 22:04:44 +0100 Subject: [PATCH 2/8] Various bug fixes - Added missing files from previous commit - Fixed move cursor that would remain after using a Selection tool - Switched to mousedown for Tool Selection to avoid missed clicks --- img/local-storage-icon.png | Bin 0 -> 1308 bytes js/controller/ToolController.js | 3 +- .../settings/LocalStorageController.js | 70 ++++++++++++++++++ js/drawingtools/Move.js | 4 +- js/drawingtools/selectiontools/BaseSelect.js | 2 +- templates/settings/localstorage.html | 18 +++++ 6 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 img/local-storage-icon.png create mode 100644 js/controller/settings/LocalStorageController.js create mode 100644 templates/settings/localstorage.html diff --git a/img/local-storage-icon.png b/img/local-storage-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d9b757e71ec3f63780eb22004e05e4273b441ec1 GIT binary patch literal 1308 zcmV+%1>^dOP)w2&Iy*JbKg<)p8URV8jKYms9ud42WEX$1HIxNLPTz~=f@(3QSxs6H1z^EW6<7wQ} z<@W!=x!BX?cKepW(ce$%z8EkI5A>kjzGWcGvTN{G4`WC!8N(p%?r{vWaDR_u=o<#I zEc*r*_Bf8@l2HaRzt=$sF1fGQLG%Ly*|>Rc57{laWN(k-=qZD(KhiZ$mBy03atO&K zedQ2>OBy|v^qWIyxJ&v`5ZHh(dL2Xrd+-^)#6O)>)USd}Rt{hVR<>I~5~Lnp#chcG zZu@OepDHZEz3tqX98w?qF$V`@Zb}ZRkC|8yd(-hX1QN@y*wyPGYT~Te8@esX2-f36 zd_DTJyUQ{3HQf^AFjnC){M4m3CnenwWE~#FjxMw{>8X2Ae;7+7F-lXHLo#8J@VT1m zpR&{;$PrE6kqqSR{#2md*I33PE00yeqb>g8G}n8migCy%O)`Tt8b_YEQe8 zt@&Hn?%mhvm-W4TF$m8pCNawKny|{z@fWswg0j?Im1phIKRW5MG9mZanNxO|uwa&G z%`Rc@{a-qB$UE}IfT0fRZ5r#1ia}?B3>REK5qES@Z_`*a_MdhI*@ukGE_VpDKn4ZeJ#Ww2-51^9K!|Ir{k`;m>NyX z?usDDwh77)2-Dp>ZpLYmK{b^TCG)gFd^$n-Mj;{0V<;}BM)QV}kADy13B?KDaKZIC zxIQ|p=2EJ=A_($>@I=#ib_k1!c`Vi+Z-JN${3$r36h~)SD{(9S7*m#Vk80Q;j3K2M z7?*~ej;nDwo|Qk{U4YL!2(W2ffe*@lc)TEGct*otR2ji`AsH-9?0(2JDffusm{TRK zh!x}}oDthdgQ;DRv{X`_kA&6TC}ISejT>ScXfV<4AWo3Q(!-l&IgA(Ex$!^e!Wti+ SDG+1;0000 k2.date) {return -1;} + return 0; + }); + + keys.forEach((function (key) { + var date = new Date(key.date); + var formattedDate = pskl.utils.Template.replace("{{Y}}/{{M}}/{{D}} {{H}}:{{m}}", { + Y : date.getFullYear(), + M : pad(date.getMonth() + 1), + D : pad(date.getDate()), + H : pad(date.getHours()), + m : pad(date.getMinutes()) + }); + html += pskl.utils.Template.replace(this.localStorageItemTemplate_, {name : key.name, date : formattedDate}); + }).bind(this)); + + var tableBody_ = this.piskelsList.get(0).tBodies[0]; + tableBody_.innerHTML = html; + }; + +})(); \ No newline at end of file diff --git a/js/drawingtools/Move.js b/js/drawingtools/Move.js index 1635e0c..0ff4985 100644 --- a/js/drawingtools/Move.js +++ b/js/drawingtools/Move.js @@ -7,7 +7,7 @@ var ns = $.namespace("pskl.drawingtools"); ns.Move = function() { - this.toolId = "tool-move"; + this.toolId = ns.Move.TOOL_ID; this.helpText = "Move tool"; // Stroke's first point coordinates (set in applyToolAt) @@ -15,6 +15,8 @@ this.startRow = null; }; + ns.Move.TOOL_ID = "tool-move"; + pskl.utils.inherit(ns.Move, ns.BaseTool); /** diff --git a/js/drawingtools/selectiontools/BaseSelect.js b/js/drawingtools/selectiontools/BaseSelect.js index b5ca0da..b6cb3b0 100644 --- a/js/drawingtools/selectiontools/BaseSelect.js +++ b/js/drawingtools/selectiontools/BaseSelect.js @@ -7,7 +7,7 @@ var ns = $.namespace("pskl.drawingtools"); ns.BaseSelect = function() { - this.secondaryToolId = "tool-move"; + this.secondaryToolId = pskl.drawingtools.Move.TOOL_ID; this.BodyRoot = $('body'); // Select's first point coordinates (set in applyToolAt) diff --git a/templates/settings/localstorage.html b/templates/settings/localstorage.html new file mode 100644 index 0000000..524cb15 --- /dev/null +++ b/templates/settings/localstorage.html @@ -0,0 +1,18 @@ +
+
+ Browse Local Piskels +
+
+ + +
+
+ +
\ No newline at end of file From aae994b3d580a66d86451bea7ab8efd5d711f110 Mon Sep 17 00:00:00 2001 From: jdescottes Date: Tue, 11 Feb 2014 23:42:38 +0100 Subject: [PATCH 3/8] Feature : Saved status and warning msg Added saved status (*) next to title when a Piskel is updated. Upon saving, the * disappears. If the workspace contains an unsaved piskel when leaving the application a message will be displayed to the user, using onbeforeunload. This logic should also be used everywhere we display a confirm message before a navigation. --- js/Events.js | 2 + js/app.js | 3 ++ js/controller/settings/SaveController.js | 1 + js/service/SavedStatusService.js | 63 ++++++++++++++++++++++++ piskel-script-list.js | 1 + 5 files changed, 70 insertions(+) create mode 100644 js/service/SavedStatusService.js diff --git a/js/Events.js b/js/Events.js index aebb030..b7b4523 100644 --- a/js/Events.js +++ b/js/Events.js @@ -29,6 +29,8 @@ var Events = { */ PISKEL_RESET: "PISKEL_RESET", + PISKEL_SAVED: "PISKEL_SAVED", + FRAME_SIZE_CHANGED : "FRAME_SIZE_CHANGED", SELECTION_CREATED: "SELECTION_CREATED", diff --git a/js/app.js b/js/app.js index a217981..c8a9352 100644 --- a/js/app.js +++ b/js/app.js @@ -75,6 +75,9 @@ this.cheatsheetService = new pskl.service.keyboard.CheatsheetService(); this.cheatsheetService.init(); + this.savedStatusService = new pskl.service.SavedStatusService(this.piskelController); + this.savedStatusService.init(); + if (this.isAppEngineVersion) { this.storageService = new pskl.service.AppEngineStorageService(this.piskelController); } else { diff --git a/js/controller/settings/SaveController.js b/js/controller/settings/SaveController.js index 57d9c57..01c7a6f 100644 --- a/js/controller/settings/SaveController.js +++ b/js/controller/settings/SaveController.js @@ -95,6 +95,7 @@ ns.SaveController.prototype.onSaveSuccess_ = function () { $.publish(Events.CLOSE_SETTINGS_DRAWER); $.publish(Events.SHOW_NOTIFICATION, [{"content": "Successfully saved !"}]); + $.publish(Events.PISKEL_SAVED); }; ns.SaveController.prototype.onSaveError_ = function (status) { diff --git a/js/service/SavedStatusService.js b/js/service/SavedStatusService.js new file mode 100644 index 0000000..2a0024f --- /dev/null +++ b/js/service/SavedStatusService.js @@ -0,0 +1,63 @@ +(function () { + var ns = $.namespace('pskl.service'); + + ns.SavedStatusService = function (piskelController) { + this.piskelController_ = piskelController; + }; + + ns.SavedStatusService.prototype.init = function () { + $.subscribe(Events.TOOL_RELEASED, this.onToolReleased.bind(this)); + $.subscribe(Events.PISKEL_RESET, this.onPiskelReset.bind(this)); + + $.subscribe(Events.PISKEL_SAVED, this.onPiskelSaved.bind(this)); + + window.addEventListener("beforeunload", this.onBeforeUnload.bind(this)); + }; + + ns.SavedStatusService.prototype.onPiskelReset = function () { + var piskel = this.piskelController_.piskel; + // A first PISKEL_RESET is triggered during the load of a new Piskel, it should be ignored + // putting a firstResetDone flag as a nasty workaround for this + if (piskel.firstResetDone_) { + this.updateDirtyStatus(true); + } else { + piskel.firstResetDone_ = true; + } + }; + + ns.SavedStatusService.prototype.onToolReleased = function () { + this.updateDirtyStatus(true); + }; + + ns.SavedStatusService.prototype.onPiskelSaved = function () { + this.updateDirtyStatus(false); + }; + + ns.SavedStatusService.prototype.updateDirtyStatus = function (status) { + var piskel = this.piskelController_.piskel; + if (piskel.isDirty_ !== status) { + piskel.isDirty_ = status; + this.updatePiskelName(); + } + }; + + ns.SavedStatusService.prototype.updatePiskelName = function () { + var piskel = this.piskelController_.piskel; + var name = piskel.getDescriptor().name; + if (piskel.isDirty_) { + $('.piskel-name').html(name + ' *'); + } else { + $('.piskel-name').html(name); + } + }; + + ns.SavedStatusService.prototype.onBeforeUnload = function (evt) { + var piskel = this.piskelController_.piskel; + if (piskel.isDirty_) { + var confirmationMessage = "Your Piskel seem to have unsaved changes"; + + (evt || window.event).returnValue = confirmationMessage; + return confirmationMessage; + } + }; +})(); \ No newline at end of file diff --git a/piskel-script-list.js b/piskel-script-list.js index 0e92ebb..65247a7 100644 --- a/piskel-script-list.js +++ b/piskel-script-list.js @@ -83,6 +83,7 @@ exports.scripts = [ "js/service/GithubStorageService.js", "js/service/AppEngineStorageService.js", "js/service/HistoryService.js", + "js/service/SavedStatusService.js", "js/service/keyboard/ShortcutService.js", "js/service/keyboard/KeycodeTranslator.js", "js/service/keyboard/CheatsheetService.js", From 5d4ba0b79f322a07ef05250291e0a88217c84c7e Mon Sep 17 00:00:00 2001 From: jdescottes Date: Wed, 12 Feb 2014 00:08:52 +0100 Subject: [PATCH 4/8] Added comment --- js/service/SavedStatusService.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/service/SavedStatusService.js b/js/service/SavedStatusService.js index 2a0024f..e2445ef 100644 --- a/js/service/SavedStatusService.js +++ b/js/service/SavedStatusService.js @@ -36,6 +36,7 @@ ns.SavedStatusService.prototype.updateDirtyStatus = function (status) { var piskel = this.piskelController_.piskel; if (piskel.isDirty_ !== status) { + // Redraw piskel name only if dirty status actually changed piskel.isDirty_ = status; this.updatePiskelName(); } From 0f817ddf58a2c9dcc7b15279316a76c78b899511 Mon Sep 17 00:00:00 2001 From: jdescottes Date: Wed, 12 Feb 2014 00:14:24 +0100 Subject: [PATCH 5/8] Increased timeout config for Remote build --- Gruntfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index 2201f43..01ea242 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -65,7 +65,7 @@ module.exports = function(grunt) { } }, ghost : { - 'default' : getGhostConfig(3000), + 'default' : getGhostConfig(5000), local : getGhostConfig(50) }, concat : { From 2f1e13ca200c852010b7c1e699150da827ce6597 Mon Sep 17 00:00:00 2001 From: jdescottes Date: Sun, 16 Feb 2014 22:37:09 +0100 Subject: [PATCH 6/8] Added private rule to gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 1bdbebc..41c1dea 100644 --- a/.gitignore +++ b/.gitignore @@ -15,5 +15,8 @@ npm-debug.log # builds build +# marked as private +*.private.* + # Closure compiler generated JS binary. closure_compiled_binary.js \ No newline at end of file From b51620634e65510ba491568cb27843c0a19b2761 Mon Sep 17 00:00:00 2001 From: jdescottes Date: Thu, 20 Feb 2014 18:26:35 +0100 Subject: [PATCH 7/8] UI : update display of palette tool icons --- css/tools.css | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/css/tools.css b/css/tools.css index 28242a3..2e009bf 100644 --- a/css/tools.css +++ b/css/tools.css @@ -136,6 +136,20 @@ cursor: url(../img/icons/dropper.png) 0 15, pointer; } +.tool-color-picker { + position:relative; +} + +.tool-color-picker:nth-child(1) { + z-index : 100; +} + +.tool-color-picker:nth-child(2) { + z-index : 90; + margin-top: 20px; + margin-left:-20px; +} + .tool-color-picker input { width: 16px; height: 16px; @@ -155,6 +169,7 @@ .palette-wrapper { margin-top: 10px; + margin-left: 10px; } .palette-color[data-color=TRANSPARENT] { From cac1fa8ed51f8e2cbf68a2417d125eff24c53e1b Mon Sep 17 00:00:00 2001 From: jdescottes Date: Mon, 3 Mar 2014 22:50:08 +0100 Subject: [PATCH 8/8] UX : Primary/Secondary colors usability - Added swap colors icon - Created SVG icon, source is in resources (Inkscape) --- css/spectrum/spectrum-overrides.css | 7 +- css/tools.css | 16 +++++ img/tools/swap-arrow-square-small-grey.png | Bin 0 -> 973 bytes js/controller/PaletteController.js | 2 + resources/swap-arrow-small.png | Bin 0 -> 574 bytes resources/swap-arrow-square-small-grey.png | Bin 0 -> 973 bytes resources/swap-arrow-square-small.png | Bin 0 -> 816 bytes resources/swap-arrow-square.svg | 80 +++++++++++++++++++++ resources/swap-arrow.svg | 80 +++++++++++++++++++++ templates/drawing-tools.html | 20 +++++- 10 files changed, 202 insertions(+), 3 deletions(-) create mode 100644 img/tools/swap-arrow-square-small-grey.png create mode 100644 resources/swap-arrow-small.png create mode 100644 resources/swap-arrow-square-small-grey.png create mode 100644 resources/swap-arrow-square-small.png create mode 100644 resources/swap-arrow-square.svg create mode 100644 resources/swap-arrow.svg diff --git a/css/spectrum/spectrum-overrides.css b/css/spectrum/spectrum-overrides.css index 1bd874e..2b214de 100644 --- a/css/spectrum/spectrum-overrides.css +++ b/css/spectrum/spectrum-overrides.css @@ -25,13 +25,18 @@ /* Remove the padding on the input container */ .sp-replacer { - padding: 3px; + padding: 4px; height: 100%; border-width: 0; box-sizing: border-box; -moz-box-sizing:border-box; background-color: #444; } + +.sp-replacer:hover { + background-color: #888; +} + /* Hide the triangle */ .sp-dd { display: none; diff --git a/css/tools.css b/css/tools.css index 2e009bf..bda3cde 100644 --- a/css/tools.css +++ b/css/tools.css @@ -136,6 +136,22 @@ cursor: url(../img/icons/dropper.png) 0 15, pointer; } +.swap-colors-icon { + background-image: url(../img/tools/swap-arrow-square-small-grey.png); + position: relative; + top: 50px; + left: 6px; + height: 18px; + width: 18px; + background-size: 18px; + opacity : 0.3; + cursor : pointer; +} + +.swap-colors-icon:hover { + opacity : 1; +} + .tool-color-picker { position:relative; } diff --git a/img/tools/swap-arrow-square-small-grey.png b/img/tools/swap-arrow-square-small-grey.png new file mode 100644 index 0000000000000000000000000000000000000000..ce91d2401d4b4efd985e00e65d9e1becf4563ff5 GIT binary patch literal 973 zcmV;;12X)HP)CmK~z|U#g|`*6=fL4pXWPgt=&|1_q(gO7JRz za$}Jd{1a#p1QB+rGZ zJts)M1z@aNtqv|F5PN%jzX!0X{ao(q>KdDvn0R?ffWk052w;0G{Cum`8f!Ef>+=TU zOb@B*#{dp>sGk7vj)+{%9Y|H*Bl)YD6*@MM_W-N_<0JAdwP*NG1ZA+17kM~Ty!7+AbBh$b)Z(OJ(m+tI*^(Dl#(hJi^csp@uUNZ$SnY8 zlX7OZKMcd&S%<0WYpUAum8Sx=2k*syfB0E_W_DOr-_HU>vJ1eE-un;d1QZ0pbu&BK zq4$XQep?nO0FLCS_kK@iAOIlwIe=Cf6iI$luh;iw1`?4f$t?gL zrj!&(e$s3IZIvNsb@8)`Gj;{cXFbyH_GqZ^W=rBZ26CZIOdt0aF0 zFz>@7$!2W+5C7|-xPl=&*=<1Y|UI7J2X2kz55}MRb|j8j_#2OQON2MPvkRgXad6 zq%aI$H?s@Tvzh%iJw5$)xmS->P)vrFQ7c~wSXc#n ztAL_~5DP$kw2Fn;+E{3zC~9FP1})QwTNo@P5I19S=d$BvU177c2M%23GWY*H zcg~!d5MxwF2w@rfa4W{Rtz^U)CHNI=qKj9UtlyQ$8ajtgf^MgLgPCGr9Kc!zjVZhM ziW4QkyKobq@EMoTPOGqrm)Ku=joVny96v0%#;r`i7M^CB&V~>sinyf*PVqRog&CY5 z3pmF3K~>FlTpbHI#gpuLA%w6{gxqI;P2q=Lk*#5GvEs^vbZ{>ln#FQ)$H{dI&okG* zaB}1=^B?e8RU570UvRWIIKdY)a8xyzQ^mmvzS@9)$Hj4gC$Q3h|HO5)ih&b6;J&|4 zuZXv}Pz;<2xQ(p_{I{yr9vd)k1$%}Dr;p6zV*_5F->pF M07*qoM6N<$f|tGaX#fBK literal 0 HcmV?d00001 diff --git a/resources/swap-arrow-square-small-grey.png b/resources/swap-arrow-square-small-grey.png new file mode 100644 index 0000000000000000000000000000000000000000..ce91d2401d4b4efd985e00e65d9e1becf4563ff5 GIT binary patch literal 973 zcmV;;12X)HP)CmK~z|U#g|`*6=fL4pXWPgt=&|1_q(gO7JRz za$}Jd{1a#p1QB+rGZ zJts)M1z@aNtqv|F5PN%jzX!0X{ao(q>KdDvn0R?ffWk052w;0G{Cum`8f!Ef>+=TU zOb@B*#{dp>sGk7vj)+{%9Y|H*Bl)YD6*@MM_W-N_<0JAdwP*NG1ZA+17kM~Ty!7+AbBh$b)Z(OJ(m+tI*^(Dl#(hJi^csp@uUNZ$SnY8 zlX7OZKMcd&S%<0WYpUAum8Sx=2k*syfB0E_W_DOr-_HU>vJ1eE-un;d1QZ0pbu&BK zq4$XQep?nO0FLCS_kK@iAOIlwIe=Cf6iI$luh;iw1`?4f$t?gL zrj!&(e$s3IZIvNsb@8)`Gj;{cXFbyH_GqZ^W=rBZ26CZIOdt0aF0 zFz>@7$!2W+5C7|-xPl=&*=<1Y|UI7J2X2kz55}MRb|j8j_#2OQON2MPvkRgXad6 zq%aI$H?s@Tvzh%iJw5$)xmFpW*)kU=4HF)e|5-#Jv(+k~i={SAp0Tcbp)WQW@f0O8tHdd%6O| ztC-5*LP4fS@(zYO3d9ST$eG4wfHllxU#EZ(zQ=AXrlv5$Al6wOv$&m^?#DPDLYU8~ zUt5$6?QaDmc%~Z{N0NCXl*FZiI`RfG@7al1;;;+qUiOiF?rDlcoq+Gj&H!%)pK&9i9gC8!j^j7+ncH{Iiv0aMUX z#ka*)fO8nE92g_}uwQ*YdB2V6y^Fn-tidL*uiz+t##KCO0DOo~E4hl>1iyq~oUr_A zCBZG?30%af5W=rzMb7{SWrM)t + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/resources/swap-arrow.svg b/resources/swap-arrow.svg new file mode 100644 index 0000000..00ecd7f --- /dev/null +++ b/resources/swap-arrow.svg @@ -0,0 +1,80 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/templates/drawing-tools.html b/templates/drawing-tools.html index 6f93ab4..47ac6c8 100644 --- a/templates/drawing-tools.html +++ b/templates/drawing-tools.html @@ -3,12 +3,28 @@
    -
    +
    -
    +
    +