|
|
- // Copyright (c) 2015 Walter Bender
- //
- // This program is free software; you can redistribute it and/or
- // modify it under the terms of the The GNU Affero General Public
- // License as published by the Free Software Foundation; either
- // version 3 of the License, or (at your option) any later version.
- //
- // You should have received a copy of the GNU Affero General Public
- // License along with this library; if not, write to the Free Software
- // Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA
- //
-
- // FIXME: Use busy cursor
-
- // A viewer for Turtle Blocks plugins
- function PluginsViewer(canvas, stage, refreshCanvas, close, load) {
- this.canvas = canvas;
- this.stage = stage;
- this.refreshCanvas = refreshCanvas;
- this.closeViewer = close;
- this.loadPlugin = load;
- this.dict = {};
- this.pluginFiles = [];
- this.container = null;
- this.prev = null;
- this.next = null;
- this.page = 0; // 4x4 image matrix per page
- this.server = true;
-
- this.setServer = function(server) {
- this.server = server;
- }
-
- this.hide = function() {
- if (this.container !== null) {
- this.container.visible = false;
- this.refreshCanvas();
- }
- }
-
- this.show = function(scale) {
- this.scale = scale;
- this.page = 0;
- if (this.server) {
- try {
- var rawData = httpGet();
- var obj = JSON.parse(rawData);
- // console.log('json parse: ' + obj);
- // Look for svg
- for (var file in obj) {
- if (fileExt(obj[file]) === 'svg') {
- var name = fileBasename(obj[file]);
- if (this.pluginFiles.indexOf(name) === -1) {
- this.pluginFiles.push(name);
- }
- }
- }
- // and corresponding .json files
- for (var file in this.pluginFiles) {
- var tbfile = this.pluginFiles[file] + '.json';
- if (!tbfile in obj) {
- this.pluginFiles.remove(this.pluginFiles[file]);
- }
- }
- } catch (e) {
- console.log(e);
- return false;
- }
- } else {
- // FIXME: grab files from a local server?
- this.pluginFiles = SAMPLEPLUGINS;
- }
- console.log('found these projects: ' + this.pluginFiles.sort());
-
- if (this.container === null) {
- this.container = new createjs.Container();
- this.stage.addChild(this.container);
- this.container.x = Math.floor(((this.canvas.width / scale) - 650) / 2);
- this.container.y = 27;
-
- function processBackground(viewer, name, bitmap, extras) {
- viewer.container.addChild(bitmap);
-
- function processPrev(viewer, name, bitmap, extras) {
- viewer.prev = bitmap;
- viewer.container.addChild(viewer.prev);
- viewer.prev.x = 270;
- viewer.prev.y = 535;
-
- function processNext(viewer, name, bitmap, scale) {
- viewer.next = bitmap;
- viewer.container.addChild(viewer.next);
- viewer.next.x = 325;
- viewer.next.y = 535;
- viewer.container.visible = true;
- viewer.refreshCanvas();
- viewer.completeInit();
- loadThumbnailContainerHandler(viewer);
- return true;
- }
- makeViewerBitmap(viewer, NEXTBUTTON, 'viewer', processNext, null);
- }
- makeViewerBitmap(viewer, PREVBUTTON, 'viewer', processPrev, null);
- }
- makeViewerBitmap(this, BACKGROUND, 'viewer', processBackground, null);
- } else {
- this.container.visible = true;
- this.refreshCanvas();
- this.completeInit();
- return true;
- }
- }
-
- this.downloadImage = function(p, prepareNextImage) {
- var header = 'data:image/svg+xml;utf8,';
- var name = this.pluginFiles[p] + '.svg';
- // console.log('getting ' + name + ' from samples');
- if (this.server) {
- var data = header + httpGet(name);
- } else {
- var data = header + SAMPLESSVG[name];
- }
- var image = new Image();
- var viewer = this;
-
- image.onload = function() {
- bitmap = new createjs.Bitmap(data);
- bitmap.scaleX = 0.5;
- bitmap.scaleY = 0.5;
- viewer.container.addChild(bitmap);
- lastChild = last(viewer.container.children);
- viewer.container.swapChildren(bitmap, lastChild);
-
- viewer.dict[viewer.pluginFiles[p]] = bitmap;
- x = 5 + (p % 4) * 160;
- y = 55 + Math.floor((p % 16) / 4) * 120;
- viewer.dict[viewer.pluginFiles[p]].x = x;
- viewer.dict[viewer.pluginFiles[p]].y = y;
- viewer.dict[viewer.pluginFiles[p]].visible = true;
- viewer.refreshCanvas();
- if (prepareNextImage !== null) {
- prepareNextImage(viewer, p + 1);
- }
- }
- image.src = data;
- }
-
- this.completeInit = function() {
- var p = 0;
- this.prepareNextImage(this, p);
- }
-
- this.prepareNextImage = function(viewer, p) {
- // TODO: this.pluginFiles.sort()
- // Only download the images on the first page.
- if (p < viewer.pluginFiles.length && p < (viewer.page * 16 + 16)) {
- if (viewer.pluginFiles[p] in viewer.dict) {
- x = 5 + (p % 4) * 160;
- y = 55 + Math.floor((p % 16) / 4) * 120;
- viewer.dict[viewer.pluginFiles[p]].x = x;
- viewer.dict[viewer.pluginFiles[p]].y = y;
- viewer.dict[viewer.pluginFiles[p]].visible = true;
- viewer.prepareNextImage(viewer, p + 1)
- } else {
- viewer.downloadImage(p, viewer.prepareNextImage);
- }
- } else {
- if (viewer.page === 0) {
- viewer.prev.visible = false;
- }
- if ((viewer.page + 1) * 16 < viewer.pluginFiles.length) {
- viewer.next.visible = true;
- }
- viewer.refreshCanvas();
- }
- }
- }
-
-
- function hideCurrentPage(viewer) {
- var min = viewer.page * 16;
- var max = Math.min(viewer.pluginFiles.length, (viewer.page + 1) * 16);
- // Hide the current page.
- for (var p = min; p < max; p++) {
- viewer.dict[viewer.pluginFiles[p]].visible = false;
- }
- // Go back to previous page.
- viewer.page -= 1;
- if (viewer.page === 0) {
- viewer.prev.visible = false;
- }
- if ((viewer.page + 1) * 16 < viewer.pluginFiles.length) {
- viewer.next.visible = true;
- }
- // Show the current page.
- var min = viewer.page * 16;
- var max = Math.min(viewer.pluginFiles.length, (viewer.page + 1) * 16);
- for (var p = min; p < max; p++) {
- viewer.dict[viewer.pluginFiles[p]].visible = true;
- }
- viewer.refreshCanvas();
- }
-
-
- function showNextPage(viewer) {
- var min = viewer.page * 16;
- var max = Math.min(viewer.pluginFiles.length, (viewer.page + 1) * 16);
- // Hide the current page.
- for (var p = min; p < max; p++) {
- viewer.dict[viewer.pluginFiles[p]].visible = false;
- }
- // Advance to next page.
- viewer.page += 1;
- viewer.prev.visible = true;
- if ((viewer.page + 1) * 16 + 1 > viewer.pluginFiles.length) {
- viewer.next.visible = false;
- }
- viewer.prepareNextImage(viewer, max);
- viewer.refreshCanvas();
- }
-
-
- function viewerClicked(viewer, event) {
- var x = (event.stageX / viewer.scale) - viewer.container.x;
- var y = (event.stageY / viewer.scale) - viewer.container.y;
- if (x > 600 && y < 55) {
- viewer.hide();
- viewer.closeViewer();
- } else if (y > 535) {
- if (viewer.prev.visible && x < 325) {
- hideCurrentPage(viewer);
- } else if (viewer.next.visible && x > 325) {
- showNextPage(viewer)
- }
- } else {
- // Select a plugin.
- var col = Math.floor((x - 5) / 160);
- var row = Math.floor((y - 55) / 120);
- var p = row * 4 + col + 16 * viewer.page;
- if (p < viewer.pluginFiles.length) {
- viewer.hide();
- viewer.closeViewer();
- viewer.loadPlugin(viewer.pluginFiles[p] + '.json');
- }
- }
- }
-
-
- function loadThumbnailContainerHandler(viewer) {
- var hitArea = new createjs.Shape();
- var w = 650;
- var h = 590;
- var startX, startY, endX, endY;
- hitArea.graphics.beginFill('#FFF').drawRect(0, 0, w, h);
- hitArea.x = 0;
- hitArea.y = 0;
- viewer.container.hitArea = hitArea;
-
- var locked = false;
-
- viewer.container.on('click', function(event) {
- // We need a lock to "debouce" the click.
- if (locked) {
- console.log('debouncing click');
- return;
- }
- locked = true;
- setTimeout(function() {
- locked = false;
- }, 500);
- viewerClicked(viewer, event)
- });
-
- viewer.container.on('mousedown', function(event) {
- startX = event.stageX;
- startY = event.stageY;
- locked = true;
- });
-
- viewer.container.on('pressup', function(event) {
- endX = event.stageX;
- endY = event.stageY;
- if (endY > startY + 30 || endX > startX + 30) {
- // Down or right
- if (viewer.next.visible) {
- showNextPage(viewer);
- }
- }
- else if(endY < startY - 30 || endX < startX - 30) {
- // Up or left
- if (viewer.prev.visible) {
- hideCurrentPage(viewer);
- }
- }
- else {
- locked = false;
- viewerClicked(viewer, event)
- }
- });
- }
-
-
- function makeViewerBitmap(viewer, data, name, callback, extras) {
- // Async creation of bitmap from SVG data
- // Works with Chrome, Safari, Firefox (untested on IE)
- var img = new Image();
- img.onload = function() {
- bitmap = new createjs.Bitmap(img);
- callback(viewer, name, bitmap, extras);
- }
- img.src = 'data:image/svg+xml;base64,' + window.btoa(
- unescape(encodeURIComponent(data)));
- }
|