From 6f074e4799d73c91ebe0429c79bb2a690ca71dd9 Mon Sep 17 00:00:00 2001 From: Manuel Menezes de Sequeira Date: Sun, 9 Mar 2014 21:57:07 +0000 Subject: Add localization support for 'Brush size' string. --- paint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paint.js b/paint.js index 1929f95..7f1504d 100644 --- a/paint.js +++ b/paint.js @@ -371,7 +371,7 @@ PaintEditorMorph.prototype.populatePropertiesMenu = function () { c.add(pc.colorpicker); //c.add(pc.primaryColorButton); c.add(pc.primaryColorViewer); - c.add(new TextMorph("Brush size")); + c.add(new TextMorph(localize("Brush size"))); c.add(alpen); c.add(pc.constrain); }; -- cgit v1.3.1 From 1f0e4f7480e47fd2f0552547b174ff9d938435ee Mon Sep 17 00:00:00 2001 From: Manuel Menezes de Sequeira Date: Sun, 9 Mar 2014 21:59:32 +0000 Subject: Add localization support for SymbolMorph menu items. --- byob.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/byob.js b/byob.js index 4b581e1..5946fd5 100644 --- a/byob.js +++ b/byob.js @@ -2579,7 +2579,7 @@ InputSlotDialogMorph.prototype.symbolMenu = function () { myself = this; SymbolMorph.prototype.names.forEach(function (symbol) { symbols.push([ - [new SymbolMorph(symbol, myself.fontSize, symbolColor), symbol], + [new SymbolMorph(symbol, myself.fontSize, symbolColor), localize(symbol)], '$' + symbol ]); }); -- cgit v1.3.1 From d115aa58d7afca248eac8b44181c6f13c3531747 Mon Sep 17 00:00:00 2001 From: Manuel Menezes de Sequeira Date: Sun, 9 Mar 2014 22:00:55 +0000 Subject: Improve translation of several strings and add several new translations. --- lang-pt.js | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 117 insertions(+), 5 deletions(-) diff --git a/lang-pt.js b/lang-pt.js index 36ae99d..c5e33b0 100755 --- a/lang-pt.js +++ b/lang-pt.js @@ -1093,15 +1093,15 @@ SnapTranslator.dict.pt = { // detecção de colisões 'mouse-pointer': - 'ponteiro do rato', + 'o ponteiro do rato', 'edge': - 'borda', + 'a borda', 'pen trails': 'traços da caneta', // trajes 'Turtle': - 'seta', + 'tartaruga', 'Empty': 'vazio', @@ -1225,7 +1225,7 @@ SnapTranslator.dict.pt = { 'whitespace': 'espaços em branco', 'line': - 'avanços de linha', + 'linha', 'tab': 'tabuladores', 'cr': @@ -1385,5 +1385,117 @@ SnapTranslator.dict.pt = { 'comment pic...': 'fotografia do comentário…', 'open a new window\nwith a picture of this comment': - 'Abrir uma nova janela com\numa fotografia deste comentário.' + 'Abrir uma nova janela com\numa fotografia deste comentário.', + 'undo': + 'desfazer', + 'Brush size': + 'Espessura do pincel', + 'Constrain proportions of shapes?\n(you can also hold shift)': + 'Preservar proporções das formas?\n(também pode pressionar shift)', + 'Eraser tool': + 'Borracha', + 'Paintbrush tool\n(free draw)': + 'Pincel\n(desenho livre)', + 'Line tool\n(shift: vertical/horizontal)': + 'Segmento de recta\n(shift: vertical/horizontal)', + 'Stroked Rectangle\n(shift: square)': + 'Rectângulo\n(shift: quadrado)', + 'Filled Rectangle\n(shift: square)': + 'Rectângulo preenchido\n(shift: quadrado)', + 'Stroked Ellipse\n(shift: circle)': + 'Elipse\n(shift: circunferência)', + 'Filled Ellipse\n(shift: circle)': + 'Elipse preenchida\n(shift: círculo)', + 'Fill a region': + 'Balde de tinta', + 'Set the rotation center': + 'Estabelecer centro de rotação', + 'Pipette tool\n(pick a color anywhere)': + 'Pipeta\n(recolher uma cor em qualquer lado)', + 'Paint Editor': + 'Editor de Pintura', + 'square': + 'quadrado', + 'pointRight': + 'triângulo para a direita', + 'gears': + 'roda dentada', + 'file': + 'arquivo', + 'fullScreen': + 'ecrã inteiro', + 'normalScreen': + 'ecrã normal', + 'smallStage': + 'palco pequeno', + 'normalStage': + 'palco normal', + 'turtle': + 'tartaruga', + 'stage': + 'palco', + 'turtleOutline': + 'contorno de tartaruga', + 'pause': + 'pausa', + 'flag': + 'bandeira', + 'octagon': + 'octógono', + 'cloud': + 'nuvem', + 'cloudOutline': + 'contorno de nuvem', + 'cloudGradient': + 'nuvem com gradiente', + 'turnRight': + 'girar à direita', + 'turnLeft': + 'girar à esquerda', + 'storage': + 'armazenagem', + 'poster': + 'póster', + 'flash': + 'relâmpago', + 'brush': + 'pincel', + 'rectangle': + 'rectângulo', + 'rectangleSolid': + 'rectângulo preenchido', + 'circle': + 'circunferência', + 'circleSolid': + 'círculo', + 'crosshairs': + 'mira', + 'paintbucket': + 'balde de tinta', + 'eraser': + 'borracha', + 'pipette': + 'pipeta', + 'speechBubble': + 'balão de fala', + 'speechBubbleOutline': + 'contorno de balão de fala', + 'arrowUp': + 'seta para cima', + 'arrowUpOutline': + 'contorno de seta para cima', + 'arrowLeft': + 'seta para a esquerda', + 'arrowLeftOutline': + 'contorno de seta para a esquerda', + 'arrowDown': + 'seta para baixo', + 'arrowDownOutline': + 'contorno de seta para baixo', + 'arrowRight': + 'seta para a direita', + 'arrowRightOutline': + 'contorno de seta para a direita', + 'robot': + 'robot' }; -- cgit v1.3.1 From 0282a0f448bc03477879f1db08c8fc69828c706f Mon Sep 17 00:00:00 2001 From: Dmithiy Date: Tue, 18 Mar 2014 15:12:39 +0600 Subject: Add some translate --- lang-ru.js | 68 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/lang-ru.js b/lang-ru.js index 45a0870..4834f7c 100644 --- a/lang-ru.js +++ b/lang-ru.js @@ -186,15 +186,15 @@ SnapTranslator.dict.ru = { // GUI // control bar: 'untitled': - 'неозаглавленный', + 'Безымянный', 'development mode': - 'разрабатываемая версия', + 'Разрабатываемая версия', // categories: 'Motion': 'Движение', 'Looks': - 'Изображение', + 'Внешность', 'Sound': 'Звук', 'Pen': @@ -202,7 +202,7 @@ SnapTranslator.dict.ru = { 'Control': 'Управление', 'Sensing': - 'Состояние', + 'Сенсоры', 'Operators': 'Операторы', 'Variables': @@ -220,13 +220,13 @@ SnapTranslator.dict.ru = { 'Scripts': 'Скрипты', 'Costumes': - 'Маски', + 'Костюмы', 'Sounds': - 'Звучания', + 'Звуки', // names: 'Sprite': - 'Образ', + 'Спрайт', 'Stage': 'Сцена', @@ -236,17 +236,17 @@ SnapTranslator.dict.ru = { 'can rotate': 'вращаемый', 'only face left/right': - 'вращаемый только слева направо', + 'вращаемый только на лево и направо', // new sprite button: 'add a new sprite': - 'Добавить новый Образ', + 'Добавить новый спрайт', // tab help 'costumes tab help': - 'импорт изображение с другого веб-сайта\nили со своего компьютера скопировав его сюда', + 'импортируйте изображение с другого веб-сайта\nили со своего компьютера скопировав его сюда', 'import a sound from your computer\nby dragging it into here': - 'импорт звук со своего компьютера\nскопировав его сюда', + 'импортируйте звук со своего компьютера\nскопировав его сюда', // primitive blocks: @@ -282,7 +282,7 @@ SnapTranslator.dict.ru = { // motion: 'Stage selected:\nno motion primitives': - 'Сцена-клавиша нажата:\nДвижение-примитивы отключены', + 'Выбрана сцена:\nнет блоков движения', 'move %n steps': 'передвинуть на %n шагов', @@ -291,7 +291,7 @@ SnapTranslator.dict.ru = { 'turn %counterclockwise %n degrees': 'повернуть %counterclockwise на %n градусов', 'point in direction %dir': - 'указывать в направл. %dir', + 'указывать в направлении %dir', 'point towards %dst': 'указывать на %dst', 'go to x: %n y: %n': @@ -319,17 +319,17 @@ SnapTranslator.dict.ru = { // looks: 'switch to costume %cst': - 'измен. маску на %cst', + 'изменить костюм на %cst', 'next costume': - 'следующая маска', + 'следующий костюм', 'costume #': - 'маска #', + 'костюм №', 'say %s for %n secs': - 'произн. %s в теч. %n сек.', + 'говорить %s в течение %n сек', 'say %s': - 'произнести %s', + 'говорить %s', 'think %s for %n secs': - 'думать %s в теч. %n сек.', + 'думать %s в течение %n сек', 'think %s': 'думать %s', 'Hello!': @@ -337,25 +337,25 @@ SnapTranslator.dict.ru = { 'Hmm...': 'Хмм...', 'change %eff effect by %n': - 'измен. %eff эфф. на %n', + 'изменить эффект %eff на %n', 'set %eff effect to %n': - 'устан. %eff эфф. %n', + 'установить эффект %eff в %n', 'clear graphic effects': - 'аннулировать графич. эфф-ты', + 'убрать эффекты', 'change size by %n': 'изменить размер на %n', 'set size to %n %': - 'установить размер %n %', + 'установить размер в %n', 'size': 'размер', 'show': - 'показывать', + 'показаться', 'hide': - 'прятать', + 'спрятаться', 'go to front': - 'переместить вперед', + 'переместиться на слой вперед', 'go back %n layers': - 'перемест. на %n уровня назад', + 'переместиться на %n слоёв назад', 'development mode \ndebugging primitives:': 'Разрабатываемая версия \nотладка примитивов:', @@ -913,7 +913,7 @@ SnapTranslator.dict.ru = { // About Snap 'About Snap': - 'Snap! Реквизиты', + 'О Snap!', 'Back...': 'Bозврат...', 'License...': @@ -957,7 +957,7 @@ SnapTranslator.dict.ru = { // coments 'add comment here...': - 'добавить комментарий сюда...', + 'добавьте комментарий сюда...', // drow downs // directions @@ -974,17 +974,17 @@ SnapTranslator.dict.ru = { 'mouse-pointer': 'курсор мышки', 'edge': - 'грань', + 'край', 'pen trails': 'линии пера', // costumes 'Turtle': - 'Горлица', + 'Черепашка', // graphical effects 'ghost': - 'прозрачн.', + 'прозрачность', // keys 'space': @@ -1117,4 +1117,8 @@ SnapTranslator.dict.ru = { 'последний', 'any': 'любой' + 'now connected': + 'вы вошли в систему' + 'undo': + 'отменить' }; -- cgit v1.3.1 From ca9445c245d6c36f9a53ff3afeef47ff6920b59b Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 31 Mar 2014 12:01:03 +0200 Subject: experimental “wardrobe” and “jukebox” reporters in dev mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tentative preparations for first-class costumes and sounds --- history.txt | 4 ++++ objects.js | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index 2096b08..4c4201e 100755 --- a/history.txt +++ b/history.txt @@ -2103,3 +2103,7 @@ ______ * Widgets: new “promptVector” dialog box feature * GUI: Use new vector prompter for stage dimensions * German translation update + +140331 +------ +* Objects: experimental “wardrobe” and “jukebox” reporters in dev mode diff --git a/objects.js b/objects.js index 46a951f..37daa69 100644 --- a/objects.js +++ b/objects.js @@ -124,7 +124,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2014-February-11'; +modules.objects = '2014-March-31'; var SpriteMorph; var StageMorph; @@ -389,6 +389,12 @@ SpriteMorph.prototype.initBlocks = function () { }, // Looks - Debugging primitives for development mode + reportCostumes: { + type: 'reporter', + category: 'looks', + spec: 'wardrobe' + }, + alert: { type: 'command', category: 'looks', @@ -446,6 +452,13 @@ SpriteMorph.prototype.initBlocks = function () { spec: 'tempo' }, + // Sound - Debugging primitives for development mode + reportSounds: { + type: 'reporter', + category: 'sound', + spec: 'jukebox' + }, + // Pen clear: { type: 'command', @@ -1620,6 +1633,8 @@ SpriteMorph.prototype.blockTemplates = function (category) { txt.setColor(this.paletteTextColor); blocks.push(txt); blocks.push('-'); + blocks.push(block('reportCostumes')); + blocks.push('-'); blocks.push(block('log')); blocks.push(block('alert')); } @@ -1641,6 +1656,20 @@ SpriteMorph.prototype.blockTemplates = function (category) { blocks.push(watcherToggle('getTempo')); blocks.push(block('getTempo')); + // for debugging: /////////////// + + if (this.world().isDevMode) { + blocks.push('-'); + txt = new TextMorph(localize( + 'development mode \ndebugging primitives:' + )); + txt.fontSize = 9; + txt.setColor(this.paletteTextColor); + blocks.push(txt); + blocks.push('-'); + blocks.push(block('reportSounds')); + } + } else if (cat === 'pen') { blocks.push(block('clear')); @@ -2292,6 +2321,10 @@ SpriteMorph.prototype.doSwitchToCostume = function (id) { this.wearCostume(costume); }; +SpriteMorph.prototype.reportCostumes = function () { + return this.costumes; +}; + // SpriteMorph sound management SpriteMorph.prototype.addSound = function (audio, name) { @@ -2317,6 +2350,10 @@ SpriteMorph.prototype.playSound = function (name) { } }; +SpriteMorph.prototype.reportSounds = function () { + return this.sounds; +}; + // SpriteMorph user menu SpriteMorph.prototype.userMenu = function () { @@ -4353,6 +4390,8 @@ StageMorph.prototype.blockTemplates = function (category) { txt.setColor(this.paletteTextColor); blocks.push(txt); blocks.push('-'); + blocks.push(block('reportCostumes')); + blocks.push('-'); blocks.push(block('log')); blocks.push(block('alert')); } @@ -4374,6 +4413,20 @@ StageMorph.prototype.blockTemplates = function (category) { blocks.push(watcherToggle('getTempo')); blocks.push(block('getTempo')); + // for debugging: /////////////// + + if (this.world().isDevMode) { + blocks.push('-'); + txt = new TextMorph(localize( + 'development mode \ndebugging primitives:' + )); + txt.fontSize = 9; + txt.setColor(this.paletteTextColor); + blocks.push(txt); + blocks.push('-'); + blocks.push(block('reportSounds')); + } + } else if (cat === 'pen') { blocks.push(block('clear')); @@ -4832,6 +4885,9 @@ StageMorph.prototype.doWearPreviousCostume StageMorph.prototype.doSwitchToCostume = SpriteMorph.prototype.doSwitchToCostume; +StageMorph.prototype.reportCostumes + = SpriteMorph.prototype.reportCostumes; + // StageMorph graphic effects StageMorph.prototype.setEffect @@ -4873,6 +4929,9 @@ StageMorph.prototype.resumeAllActiveSounds = function () { }); }; +StageMorph.prototype.reportSounds + = SpriteMorph.prototype.reportSounds; + // StageMorph non-variable watchers StageMorph.prototype.toggleWatcher -- cgit v1.3.1 From 6fd93533ecb01c27589bfe569d8e22013a77f65c Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 31 Mar 2014 13:09:31 +0200 Subject: display costume thumbnails in speech/thought/value bubbles and watcher cells --- blocks.js | 8 +++++++- history.txt | 1 + objects.js | 12 ++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/blocks.js b/blocks.js index 480545d..f0ddd93 100644 --- a/blocks.js +++ b/blocks.js @@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/ // Global stuff //////////////////////////////////////////////////////// -modules.blocks = '2014-February-11'; +modules.blocks = '2014-March-31'; var SyntaxElementMorph; @@ -1635,6 +1635,12 @@ SyntaxElementMorph.prototype.showBubble = function (value) { morphToShow.silentSetWidth(img.width); morphToShow.silentSetHeight(img.height); morphToShow.image = img; + } else if (value instanceof Costume) { + img = value.thumbnail(new Point(40, 40)); + morphToShow = new Morph(); + morphToShow.silentSetWidth(img.width); + morphToShow.silentSetHeight(img.height); + morphToShow.image = img; } else if (value instanceof Context) { img = value.image(); morphToShow = new Morph(); diff --git a/history.txt b/history.txt index 4c4201e..1399ba6 100755 --- a/history.txt +++ b/history.txt @@ -2107,3 +2107,4 @@ ______ 140331 ------ * Objects: experimental “wardrobe” and “jukebox” reporters in dev mode +* Blocks, Objects: display costume thumbnails in speech/thought/value bubbles and watcher cells diff --git a/objects.js b/objects.js index 37daa69..a6d2c9a 100644 --- a/objects.js +++ b/objects.js @@ -5058,6 +5058,12 @@ SpriteBubbleMorph.prototype.dataAsMorph = function (data) { contents.silentSetWidth(img.width); contents.silentSetHeight(img.height); contents.image = img; + } else if (data instanceof Costume) { + img = data.thumbnail(new Point(40, 40)); + contents = new Morph(); + contents.silentSetWidth(img.width); + contents.silentSetHeight(img.height); + contents.image = img; } else if (data instanceof HTMLCanvasElement) { contents = new Morph(); contents.silentSetWidth(data.width); @@ -5900,6 +5906,12 @@ CellMorph.prototype.drawNew = function () { this.contentsMorph.silentSetWidth(img.width); this.contentsMorph.silentSetHeight(img.height); this.contentsMorph.image = img; + } else if (this.contents instanceof Costume) { + img = this.contents.thumbnail(new Point(40, 40)); + this.contentsMorph = new Morph(); + this.contentsMorph.silentSetWidth(img.width); + this.contentsMorph.silentSetHeight(img.height); + this.contentsMorph.image = img; } else if (this.contents instanceof List) { if (this.isCircular()) { this.contentsMorph = new TextMorph( -- cgit v1.3.1 From ce3340e623fd0f03ecb15de5ec54eda8113c7c67 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 31 Mar 2014 13:19:39 +0200 Subject: let “switch to costume” block accept actual costume objects (in addition to names and numbers) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- history.txt | 1 + objects.js | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/history.txt b/history.txt index 1399ba6..2c0362b 100755 --- a/history.txt +++ b/history.txt @@ -2108,3 +2108,4 @@ ______ ------ * Objects: experimental “wardrobe” and “jukebox” reporters in dev mode * Blocks, Objects: display costume thumbnails in speech/thought/value bubbles and watcher cells +* Objects: let “switch to costume” block accept actual costume objects (in addition to names and numbers) diff --git a/objects.js b/objects.js index a6d2c9a..cc02ebe 100644 --- a/objects.js +++ b/objects.js @@ -2291,6 +2291,11 @@ SpriteMorph.prototype.doWearPreviousCostume = function () { }; SpriteMorph.prototype.doSwitchToCostume = function (id) { + if (id instanceof Costume) { // allow first-class costumes + this.wearCostume(id); + return; + } + var num, arr = this.costumes.asArray(), costume; -- cgit v1.3.1 From 442265ba5f38aba57d8aea19c8c36ccfc6e39a26 Mon Sep 17 00:00:00 2001 From: Nathaniel Titterton Date: Thu, 17 Apr 2014 12:21:31 -0700 Subject: give error message when attempting to import (into a variable) with a non-text file; don't read every file in multifile import --- objects.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/objects.js b/objects.js index cc02ebe..fcb8796 100644 --- a/objects.js +++ b/objects.js @@ -6466,11 +6466,11 @@ WatcherMorph.prototype.userMenu = function () { document.body.removeChild(inp); ide.filePicker = null; if (inp.files.length > 0) { - for (i = 0; i < inp.files.length; i += 1) { - file = inp.files[i]; - if (file.type.indexOf("text") === 0) { - readText(file); - } + file = inp.files[inp.files.length - 1]; + if (file.type.indexOf("text") === 0) { + readText(file); + } else { + ide.inform("Unable to import", "Snap! can only import \"text\" files.\n You selected a file of type \"" + file.type + "\"."); } } }, -- cgit v1.3.1 From 7d717817748f2f659803ecc9e3b8c9632e14a59d Mon Sep 17 00:00:00 2001 From: "Jouni K. Seppänen" Date: Fri, 18 Apr 2014 13:33:05 +0300 Subject: Finnish translation --- lang-fi.js | 1280 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ locale.js | 14 +- 2 files changed, 1293 insertions(+), 1 deletion(-) create mode 100644 lang-fi.js diff --git a/lang-fi.js b/lang-fi.js new file mode 100644 index 0000000..bb70a9f --- /dev/null +++ b/lang-fi.js @@ -0,0 +1,1280 @@ +/* + + lang-fi.js + + Finnish translation for SNAP! + + written by Jouni K. Seppänen + + Copyright (C) 2014 by Jens Mönig + + This file is part of Snap!. + + Snap! is free software: you can redistribute it and/or modify + it under the terms of 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + + + Note to Translators: + -------------------- + At this stage of development, Snap! can be translated to any LTR language + maintaining the current order of inputs (formal parameters in blocks). + + Translating Snap! is easy: + + + 1. Download + + Download the sources and extract them into a local folder on your + computer: + + + + Use the German translation file (named 'lang-de.js') as template for your + own translations. Start with editing the original file, because that way + you will be able to immediately check the results in your browsers while + you're working on your translation (keep the local copy of snap.html open + in your web browser, and refresh it as you progress with your + translation). + + + 2. Edit + + Edit the translation file with a regular text editor, or with your + favorite JavaScript editor. + + In the first non-commented line (the one right below this + note) replace "de" with the two-letter ISO 639-1 code for your language, + e.g. + + fr - French => SnapTranslator.dict.fr = { + it - Italian => SnapTranslator.dict.it = { + pl - Polish => SnapTranslator.dict.pl = { + pt - Portuguese => SnapTranslator.dict.pt = { + es - Spanish => SnapTranslator.dict.es = { + el - Greek => => SnapTranslator.dict.el = { + + etc. (see ) + + + 3. Translate + + Then work through the dictionary, replacing the German strings against + your translations. The dictionary is a straight-forward JavaScript ad-hoc + object, for review purposes it should be formatted as follows: + + { + 'English string': + 'Translation string', + 'last key': + } 'last value' + + and you only edit the indented value strings. Note that each key-value + pair needs to be delimited by a comma, but that there shouldn't be a comma + after the last pair (again, just overwrite the template file and you'll be + fine). + + If something doesn't work, or if you're unsure about the formalities you + should check your file with + + + + This will inform you about any missed commas etc. + + + 4. Accented characters + + Depending on which text editor and which file encoding you use you can + directly enter special characters (e.g. Umlaut, accented characters) on + your keyboard. However, I've noticed that some browsers may not display + special characters correctly, even if other browsers do. So it's best to + check your results in several browsers. If you want to be on the safe + side, it's even better to escape these characters using Unicode. + + see: + + + 5. Block specs: + + At this time your translation of block specs will only work + correctly, if the order of formal parameters and their types + are unchanged. Placeholders for inputs (formal parameters) are + indicated by a preceding % prefix and followed by a type + abbreviation. + + For example: + + 'say %s for %n secs' + + can currently not be changed into + + 'say %n secs long %s' + + and still work as intended. + + Similarly + + 'point towards %dst' + + cannot be changed into + + 'point towards %cst' + + without breaking its functionality. + + + 6. Submit + + When you're done, rename the edited file by replacing the "de" part of the + filename with the two-letter ISO 639-1 code for your language, e.g. + + fr - French => lang-fr.js + it - Italian => lang-it.js + pl - Polish => lang-pl.js + pt - Portuguese => lang-pt.js + es - Spanish => lang-es.js + el - Greek => => lang-el.js + + and send it to me for inclusion in the official Snap! distribution. + Once your translation has been included, Your name will the shown in the + "Translators" tab in the "About Snap!" dialog box, and you will be able to + directly launch a translated version of Snap! in your browser by appending + + lang:xx + + to the URL, xx representing your translations two-letter code. + + + 7. Known issues + + In some browsers accents or ornaments located in typographic ascenders + above the cap height are currently (partially) cut-off. + + Enjoy! + -Jens +*/ + +/*global SnapTranslator*/ + +SnapTranslator.dict.fi = { + +/* + Special characters: (see ) + + Ä, ä \u00c4, \u00e4 + Ö, ö \u00d6, \u00f6 + → \u2192 + \u200B zero-width space, useful to escape % at the beginning of words +*/ + + // translations meta information + 'language_name': + 'suomi', // the name as it should appear in the language menu + 'language_translator': + 'Jouni K. Sepp\u00e4nen', // your name for the Translators tab + 'translator_e-mail': + 'jks@iki.fi', // optional + 'last_changed': + '2014-04-18', // this, too, will appear in the Translators tab + + // GUI + // control bar: + 'untitled': + 'nimet\u00f6n', + 'development mode': + 'kehitysmoodi', + + // categories: + 'Motion': + 'Liike', + 'Looks': + 'Ulkon\u00e4k\u00f6', + 'Sound': + '\u00c4\u00e4ni', + 'Pen': + 'Kyn\u00e4', + 'Control': + 'Ohjaus', + 'Sensing': + 'Tuntoaisti', + 'Operators': + 'Laskenta', + 'Variables': + 'Muuttujat', + 'Lists': + 'Listat', + 'Other': + 'Muut', + + // editor: + 'draggable': + 'hiirell\u00e4 liikuteltava', + + // tabs: + 'Scripts': + 'Skriptit', + 'Costumes': + 'Asut', + 'Sounds': + '\u00c4\u00e4net', + + // names: + 'Sprite': + 'Hahmo', + 'Stage': + 'Esiintymislava', + + // rotation styles: + 'don\'t rotate': + 'ei py\u00f6ri', + 'can rotate': + 'py\u00f6rii vapaasti', + 'only face left/right': + 'k\u00e4\u00e4ntyy vain vasemmalle ja oikealle', + + // new sprite button: + 'add a new sprite': + 'lis\u00e4\u00e4 uusi hahmo', + + // tab help + 'costumes tab help': + 'Tuo kuva verkosta tai koneeltasi\n' + + 'siirt\u00e4m\u00e4ll\u00e4 se hiirell\u00e4 t\u00e4h\u00e4n', + 'import a sound from your computer\nby dragging it into here': + 'Tuo \u00e4\u00e4ni koneeltasi\n' + + 'siirt\u00e4m\u00e4ll\u00e4 se hiirell\u00e4 t\u00e4h\u00e4n', + + // primitive blocks: + + /* + Attention Translators: + ---------------------- + At this time your translation of block specs will only work + correctly, if the order of formal parameters and their types + are unchanged. Placeholders for inputs (formal parameters) are + indicated by a preceding % prefix and followed by a type + abbreviation. + + For example: + + 'say %s for %n secs' + + can currently not be changed into + + 'say %n secs long %s' + + and still work as intended. + + Similarly + + 'point towards %dst' + + cannot be changed into + + 'point towards %cst' + + without breaking its functionality. + */ + + // motion: + 'Stage selected:\nno motion primitives': + 'Esiintymislava valittuna\nei liikekomentoja', + + 'move %n steps': + 'liiku %n askelta', + 'turn %clockwise %n degrees': + 'k\u00e4\u00e4nny %clockwise %n astetta', + 'turn %counterclockwise %n degrees': + 'k\u00e4\u00e4nny %counterclockwise %n astetta', + 'point in direction %dir': + 'osoita suuntaan %dir', + 'point towards %dst': + 'osoita hahmoa %dst kohti', + 'go to x: %n y: %n': + 'mene paikkaan x: %n y: %n', + 'go to %dst': + 'mene hahmon %dst luo', + 'glide %n secs to x: %n y: %n': + 'liu\'u %n s \u2192 x: %n y: %n', + 'change x by %n': + 'muuta x:\u00e4\u00e4 %n askelta', + 'set x to %n': + 'aseta x:ksi %n', + 'change y by %n': + 'muuta y:t\u00e4 %n askelta', + 'set y to %n': + 'aseta y:ksi %n', + 'if on edge, bounce': + 'kimpoa reunasta', + 'x position': + 'x-paikka', + 'y position': + 'y-paikka', + 'direction': + 'suunta', + + // looks: + 'switch to costume %cst': + 'vaihda asuun %cst', + 'next costume': + 'seuraava asu', + 'costume #': + 'asun nro', + 'say %s for %n secs': + 'sano %s %n sekunnin ajan', + 'say %s': + 'sano %s', + 'think %s for %n secs': + 'ajattele %s %n sekunnin ajan', + 'think %s': + 'ajattele %s', + 'Hello!': + 'Hei!', + 'Hmm...': + 'Hmm...', + 'change %eff effect by %n': + 'muuta efekti\u00e4 %eff %n yksikk\u00f6\u00e4', + 'set %eff effect to %n': + 'aseta efektin %eff m\u00e4\u00e4r\u00e4ksi %n', + 'clear graphic effects': + 'poista efektit', + 'change size by %n': + // using a zero-width space to hide % at word beginning + 'muuta kokoa %n \u200B%-yksikk\u00f6\u00e4', + 'set size to %n %': + 'aseta kooksi %n %', + 'size': + 'koko', + 'show': + 'n\u00e4yt\u00e4', + 'hide': + 'piilota', + 'go to front': + 'tule etualalle', + 'go back %n layers': + 'siirry %n kerrosta taakse', + + 'development mode \ndebugging primitives:': + 'Kehitysmoodin \ndebuggauskomennot:', + 'console log %mult%s': + 'kirjoita konsoliin: %mult%s', + 'alert %mult%s': + 'ponnahdusikkuna: %mult%s', + + // sound: + 'play sound %snd': + 'soita \u00e4\u00e4ni %snd', + 'play sound %snd until done': + 'soita \u00e4\u00e4ni %snd kokonaan', + 'stop all sounds': + 'pys\u00e4yt\u00e4 kaikki \u00e4\u00e4net', + 'rest for %n beats': + 'tauko %n iskua', + 'play note %n for %n beats': + 'nuotti %n %n iskua', + 'change tempo by %n': + 'vaihda tempoa %n iskulla/min', + 'set tempo to %n bpm': + 'aseta tempoksi %n iskua/min', + 'tempo': + 'tempo', + + // pen: + 'clear': + 'tyhjenn\u00e4', + 'pen down': + 'kyn\u00e4 alas', + 'pen up': + 'kyn\u00e4 yl\u00f6s', + 'set pen color to %clr': + 'aseta kyn\u00e4n v\u00e4riksi %clr', + 'change pen color by %n': + 'vaihda kyn\u00e4n v\u00e4ri\u00e4 m\u00e4\u00e4r\u00e4ll\u00e4 %n', + 'set pen color to %n': + 'aseta kyn\u00e4n v\u00e4riksi %n', + 'change pen shade by %n': + // using a zero-width space to hide % at word beginning + 'muuta kirkkautta %n \u200b%-yks.', + 'set pen shade to %n': + 'aseta kirkkaudeksi %n %', + 'change pen size by %n': + 'muuta paksuutta m\u00e4\u00e4r\u00e4ll\u00e4 %n', + 'set pen size to %n': + 'aseta kyn\u00e4n paksuudeksi %n', + 'stamp': + 'leimaa', + + // control: + 'when %greenflag clicked': + 'kun klikataan %greenflag', + 'when %keyHat key pressed': + 'kun painetaan %keyHat', + 'when I am clicked': + 'kun minua klikataan', + 'when I receive %msgHat': + 'kun vastaanotan sanoman %msgHat', + 'broadcast %msg': + 'l\u00e4het\u00e4 sanoma %msg', + 'broadcast %msg and wait': + 'l\u00e4het\u00e4 sanoma %msg ja odota', + 'Message name': + 'Sanoma', + 'message': + 'sanoma', + 'any message': + 'mik\u00e4 tahansa', + 'wait %n secs': + 'odota %n sekuntia', + 'wait until %b': + 'odota kunnes %b', + 'forever %c': + 'ikuisesti %c', + 'repeat %n %c': + 'toista %n kertaa %c', + 'repeat until %b %c': + 'toista kunnes %b %c', + 'if %b %c': + 'jos %b %c', + 'if %b %c else %c': + 'jos %b %c muuten %c', + 'report %s': + 'vastaa %s', + 'stop %stopChoices': + 'pys\u00e4yt\u00e4 %stopChoices', + 'all': + 'kaikki', + 'this script': + 't\u00e4m\u00e4 skripti', + 'this block': + 't\u00e4m\u00e4 palikka', + 'stop %stopOthersChoices': + 'pys\u00e4yt\u00e4 %stopOthersChoices', + 'all but this script': + 'kaikki paitsi t\u00e4m\u00e4 skripti', + 'other scripts in sprite': + 'hahmon muut skriptit', + 'pause all %pause': + 'keskeyt\u00e4 kaikki %pause', + 'run %cmdRing %inputs': + 'suorita %cmdRing %inputs', + 'launch %cmdRing %inputs': + 'k\u00e4ynnist\u00e4 %cmdRing %inputs', + 'call %repRing %inputs': + 'kutsu %repRing %inputs', + 'run %cmdRing w/continuation': + 'suorita %cmdRing kontinuaatiolla', + 'call %cmdRing w/continuation': + 'kutsu %cmdRing kontinuaatiolla', + 'warp %c': + 'supernopeasti %c', + 'when I start as a clone': + 'Kun aloitan kloonina', + 'create a clone of %cln': + 'kloonaa %cln', + 'myself': + 'minut', + 'delete this clone': + 'poista t\u00e4m\u00e4 klooni', + + // sensing: + 'touching %col ?': + 'koskettaa hahmoa %col ?', + 'touching %clr ?': + 'koskettaa v\u00e4ri\u00e4 %clr ?', + 'color %clr is touching %clr ?': + 'v\u00e4ri %clr koskettaa v\u00e4ri\u00e4 %clr ?', + 'ask %s and wait': + 'kysy %s ja odota', + 'what\'s your name?': + 'Mik\u00e4 sinun nimesi on?', + 'answer': + 'vastaus', + 'mouse x': + 'hiiren x-paikka', + 'mouse y': + 'hiiren y-paikka', + 'mouse down?': + 'hiiren n\u00e4pp\u00e4in painettuna?', + 'key %key pressed?': + 'n\u00e4pp\u00e4in %key painettuna?', + 'distance to %dst': + 'et\u00e4isyys hahmoon %dst', + 'reset timer': + 'nollaa ajastin', + 'timer': + 'ajastin', + '%att of %spr': + '%att hahmolla %spr', + 'http:// %s': + 'http:// %s', + 'turbo mode?': + 'turbonopeus?', + 'set turbo mode to %b': + 'kytke turbonopeus p\u00e4\u00e4lle jos %b', + + 'filtered for %clr': + 'suodatettuna v\u00e4ri %clr', + 'stack size': + 'pinon koko', + 'frames': + 'ruutuja', + + // operators: + '%n mod %n': + 'jakoj\u00e4\u00e4nn\u00f6s laskusta %n / %n', + 'round %n': + 'py\u00f6rist\u00e4 %n', + '%fun of %n': + '%fun %n', + 'pick random %n to %n': + 'arvo satunnaisluku %n .. %n', + '%b and %b': + '%b ja %b', + '%b or %b': + '%b tai %b', + 'not %b': + 'ei %b', + 'true': + 'tosi', + 'false': + 'ep\u00e4tosi', + 'join %words': + 'yhdist\u00e4 %words', + 'split %s by %delim': + 'pilko %s %delim kohdalta', + 'hello': + 'Hei', + 'world': + 'maailma', + 'letter %n of %s': + 'kirjain nro %n tekstist\u00e4 %s', + 'length of %s': + 'tekstin %s pituus', + 'unicode of %s': + 'merkin %s Unicode-arvo', + 'unicode %n as letter': + 'Unicode-arvoa %n vastaava merkki', + 'is %s a %typ ?': + 'onko %s %typ ?', + 'is %s identical to %s ?': + 'onko %s sama kuin %s ?', + + 'type of %s': + '%s:n tyyppi', + + // variables: + 'Make a variable': + 'Uusi muuttuja', + 'Variable name': + 'Muuttujan nimi', + 'Script variable name': + 'Skriptimuuttujan nimi', + 'Delete a variable': + 'poista muuttuja', + + 'set %var to %s': + 'aseta muuttujan %var arvoksi %s', + 'change %var by %n': + 'muuta muuttujaa %var m\u00e4\u00e4r\u00e4ll\u00e4 %n', + 'show variable %var': + 'n\u00e4yt\u00e4 muuttuja %var', + 'hide variable %var': + 'piilota muuttuja %var', + 'script variables %scriptVars': + 'skriptimuuttujat %scriptVars', + + // lists: + 'list %exp': + 'lista %exp', + '%s in front of %l': + '%s listan %l aluksi', + 'item %idx of %l': + 'alkio kohdassa %idx listassa %l', + 'all but first of %l': + 'kaikki paitsi ensimm\u00e4inen alkio listasta %l', + 'length of %l': + 'listan %l pituus', + '%l contains %s': + 'lista %l sis\u00e4lt\u00e4\u00e4 %s', + 'thing': + 'alkio', + 'add %s to %l': + 'lis\u00e4\u00e4 %s listaan %l', + 'delete %ida of %l': + 'poista %ida listasta %l', + 'insert %s at %idx of %l': + 'lis\u00e4\u00e4 %s kohtaan %idx listassa %l', + 'replace item %idx of %l with %s': + 'vaihda kohtaan %idx listassa %l alkio %s', + + // other + 'Make a block': + 'Uusi palikka', + + // menus + // snap menu + 'About...': + 'Tietoa Snapista...', + 'Reference manual': + 'K\u00e4ytt\u00f6ohje', + 'Snap! website': + 'Snapin kotisivu', + 'Download source': + 'Lataa l\u00e4hdekoodi', + 'Switch back to user mode': + 'Palaa k\u00e4ytt\u00e4j\u00e4moodiin', + 'disable deep-Morphic\ncontext menus\nand show user-friendly ones': + 'poista Morphic-valikot k\u00e4yt\u00f6st\u00e4\n' + + 'ja n\u00e4yt\u00e4 helpot valikot', + 'Switch to dev mode': + 'vaihda kehitysmoodiin', + 'enable Morphic\ncontext menus\nand inspectors,\nnot user-friendly!': + 'n\u00e4yt\u00e4 Morphic-toiminnot,\n' + + 'ei kovin helppok\u00e4ytt\u00f6isi\u00e4', + + // project menu + 'Project notes...': + 'Projektimerkint\u00f6j\u00e4...', + 'New': + 'Uusi', + 'Open...': + 'Avaa...', + 'Save': + 'Tallenna', + 'Save As...': + 'Tallenna nimell\u00e4...', + 'Import...': + 'Tuo...', + 'file menu import hint': + 'lataa viety projekti,\npalikkakirjasto, asu\ntai \u00e4\u00e4ni', + 'Export project as plain text...': + 'Vie projekti tekstin\u00e4...', + 'Export project...': + 'Vie projekti...', + 'show project data as XML\nin a new browser window': + 'n\u00e4yt\u00e4 projekti XML-muodossa\nuudessa selainikkunassa', + 'Export blocks...': + 'Vie palikoita...', + 'show global custom block definitions as XML\nin a new browser window': + 'n\u00e4yt\u00e4 yhteiset palikkam\u00e4\u00e4rittelyt\n' + + 'XML-muodossa uudessa selainikkunassa', + 'Import tools': + 'Tuo ty\u00f6kaluja', + 'load the official library of\npowerful blocks': + 'lataa virallinen tehopalikoiden kirjasto', + 'Libraries...': + 'Kirjastot...', + 'Import library': + 'Tuo kirjasto', + + // cloud menu + 'Login...': + 'Kirjaudu...', + 'Signup...': + 'Luo k\u00e4ytt\u00e4j\u00e4tili...', + + // settings menu + 'Language...': + 'Kieli...', + 'Zoom blocks...': + 'Suurenna palikoita...', + 'Stage size...': + 'Esiintymislavan koko...', + 'Stage size': + 'Esiintymislavan koko', + 'Stage width': + 'Esiintymislavan leveys', + 'Stage height': + 'Esiintymislavan korkeus', + 'Default': + 'Tavallinen', + 'Blurred shadows': + 'Sumeat varjot', + 'uncheck to use solid drop\nshadows and highlights': + 'poistamalla saat kiinte\u00e4t varjot\nja korostukset', + 'check to use blurred drop\nshadows and highlights': + 'asettamalla saat sumeat varjot\nja korostukset', + 'Zebra coloring': + 'Seeprav\u00e4ritys', + 'check to enable alternating\ncolors for nested blocks': + 'asettamalla saat vaihtuvat v\u00e4rit\nsis\u00e4kk\u00e4isille palikoille', + 'uncheck to disable alternating\ncolors for nested block': + 'poistamalla saat samat v\u00e4rit\nsis\u00e4kk\u00e4isille palikoille', + 'Dynamic input labels': + 'Vaihtuvat sy\u00f6tetunnukset', + 'uncheck to disable dynamic\nlabels for variadic inputs': + 'poistamalla est\u00e4t vaihtuvien\nsy\u00f6tteiden vaihtuvat tunnukset', + 'check to enable dynamic\nlabels for variadic inputs': + 'asettamalla saat vaihtuville\nsy\u00f6tteille vaihtuvat tunnukset', + 'Prefer empty slot drops': + 'Suosi asettamista tyhjiin aukkoihin', + 'settings menu prefer empty slots hint': + 'asettamalla saat asetettavat\npalikat osumaan tyhjiin aukkoihin', + 'uncheck to allow dropped\nreporters to kick out others': + 'poistamalla sallit asetettujen\npalikoiden pois potkimisen', + 'Long form input dialog': + 'Yksityiskohtainen sy\u00f6tevalinta', + 'Plain prototype labels': + 'Yksinkertaiset palikkatunnisteet', + 'uncheck to always show (+) symbols\nin block prototype labels': + 'poistamalla saat (+)-merkit\nn\u00e4kym\u00e4\u00e4n aina\n' + + 'palikan muokkauksessa', + 'check to hide (+) symbols\nin block prototype labels': + 'asettamalla piilotat (+)-merkit\npalikan muokkauksessa', + 'check to always show slot\ntypes in the input dialog': + 'asettamalla n\u00e4et aina\ntietotyyppivalinnat\n' + + 'palikan sy\u00f6tteit\u00e4 lis\u00e4tess\u00e4', + 'uncheck to use the input\ndialog in short form': + 'poistamalla teet palikan\nsy\u00f6tteiden lis\u00e4\u00e4misikkunasta\n' + + 'yksinkertaisen', + 'Virtual keyboard': + 'Virtuaalin\u00e4pp\u00e4imist\u00f6', + 'uncheck to disable\nvirtual keyboard support\nfor mobile devices': + 'poistamalla est\u00e4t mobiililaitteiden\n' + + 'virtuaalin\u00e4pp\u00e4imist\u00f6n k\u00e4yt\u00f6n', + 'check to enable\nvirtual keyboard support\nfor mobile devices': + 'asettamalla sallit mobiililaitteiden\n' + + 'virtuaalin\u00e4pp\u00e4imist\u00f6n k\u00e4yt\u00f6n', + 'Input sliders': + 'Liukus\u00e4\u00e4timet', + 'uncheck to disable\ninput sliders for\nentry fields': + 'poistamalla piilotat\nliukus\u00e4\u00e4timet sy\u00f6tekentist\u00e4\n', + 'check to enable\ninput sliders for\nentry fields': + 'asettamalla saat\nsy\u00f6tekenttiin liukus\u00e4\u00e4timet', + 'Clicking sound': + 'Klikkaus\u00e4\u00e4ni', + 'uncheck to turn\nblock clicking\nsound off': + 'poistamalla hiljenn\u00e4t\npalikoiden klikkaus\u00e4\u00e4nen', + 'check to turn\nblock clicking\nsound on': + 'asettamalla kytket p\u00e4\u00e4lle\npalikoiden klikkaus\u00e4\u00e4nen', + 'Animations': + 'Animaatiot', + 'uncheck to disable\nIDE animations': + 'poistamalla piilotat\nk\u00e4ytt\u00f6liittym\u00e4n animaatiot', + 'Turbo mode': + 'Turbonopeus', + 'check to prioritize\nscript execution': + 'asettamalla nostat\nskriptien prioriteettia', + 'uncheck to run scripts\nat normal speed': + 'poistamalla ajat\nskriptit normaalinopeudella', + 'check to enable\nIDE animations': + 'asettamalla kytket p\u00e4\u00e4lle\n' + + 'k\u00e4ytt\u00f6liittym\u00e4n animaatiot', + 'Thread safe scripts': + 'S\u00e4ieturvalliset skriptit', + 'uncheck to allow\nscript reentrance': + 'poistamalla sallit skriptin\nk\u00e4ynnistymisen vaikka se on ajossa', + 'check to disallow\nscript reentrance': + 'asettamalla est\u00e4t skriptin\nk\u00e4ynnistymisen jos se on jo ajossa', + 'Prefer smooth animations': + 'Pyri sulaviin animaatioihin', + 'uncheck for greater speed\nat variable frame rates': + 'poistamalla saat lis\u00e4\u00e4 nopeutta\n' + + 'mutta p\u00e4ivitystaajuus vaihtelee', + 'check for smooth, predictable\nanimations across computers': + 'asettamalla saat sulavat\nanimaatiot eri tietokoneilla', + 'Flat line ends': + 'Tasaiset viivanp\u00e4\u00e4t', + 'check for flat ends of lines': + 'asettamalla saat viivan p\u00e4ist\u00e4 suorat', + 'uncheck for round ends of lines': + 'poistamalla saat viivan p\u00e4ist\u00e4 py\u00f6ristetyt', + + // inputs + 'with inputs': + 'sy\u00f6tteill\u00e4', + 'input names:': + 'sy\u00f6tteet:', + 'Input Names:': + 'Sy\u00f6tteet:', + 'input list:': + 'sy\u00f6telista:', + + // context menus: + 'help': + 'apua', + + // palette: + 'hide primitives': + 'piilota peruspalikat', + 'show primitives': + 'n\u00e4yt\u00e4 peruspalikat', + + // blocks: + 'help...': + 'apua...', + 'relabel...': + 'nime\u00e4 uudestaan...', + 'duplicate': + 'kopioi', + 'make a copy\nand pick it up': + 'ota kopio mukaan', + 'only duplicate this block': + 'kopioi vain t\u00e4m\u00e4 palikka', + 'delete': + 'poista', + 'script pic...': + 'kuva skriptist\u00e4...', + 'open a new window\nwith a picture of this script': + 'avaa kuva t\u00e4st\u00e4 skriptist\u00e4\nuudessa selainikkunassa', + 'ringify': + 'ympyr\u00f6i', + 'unringify': + 'poista ympyr\u00f6inti', + + // custom blocks: + 'delete block definition...': + 'poista palikkam\u00e4\u00e4rittely', + 'edit...': + 'muokkaa...', + + // sprites: + 'edit': + 'muokkaa', + 'detach from': + 'irrota', + 'detach all parts': + 'irrota kaikki osat', + 'export...': + 'Vie...', + + // stage: + 'show all': + 'N\u00e4yt\u00e4 kaikki', + 'pic...': + 'Vie kuva...', + 'open a new window\nwith a picture of the stage': + 'Avaa esiintymislavan kuva\nuuteen selainikkunaan', + + // scripting area + 'clean up': + 'siivoa', + 'arrange scripts\nvertically': + 'j\u00e4rjest\u00e4 pystysuorasti', + 'add comment': + 'lis\u00e4\u00e4 kommentti', + 'undrop': + 'peruuta asetus', + 'undo the last\nblock drop\nin this pane': + 'peruuta viimeisin\npalikan asetus', + 'scripts pic...': + 'kuva skripteist\u00e4...', + 'open a new window\nwith a picture of all scripts': + 'avaa kuva\nkaikista skripteist\u00e4\nuudessa selainikkunassa', + 'make a block...': + 'tee uusi palikka...', + + // costumes + 'rename': + 'nime\u00e4 uudestaan', + 'export': + 'vie', + 'rename costume': + 'nime\u00e4 asu uudestaan', + + // sounds + 'Play sound': + 'Soita \u00e4\u00e4ni', + 'Stop sound': + 'Pys\u00e4yt\u00e4 \u00e4\u00e4ni', + 'Stop': + 'Pys\u00e4yt\u00e4', + 'Play': + 'Soita', + 'rename sound': + 'nime\u00e4 \u00e4\u00e4ni uudestaan', + + // dialogs + // buttons + 'OK': + 'OK', + 'Ok': + 'OK', + 'Cancel': + 'Peruuta', + 'Yes': + 'Kyll\u00e4', + 'No': + 'Ei', + + // help + 'Help': + 'Apua', + + // zoom blocks + 'Zoom blocks': + 'Suurenna palikoita', + 'build': + 'rakenna', + 'your own': + 'omia', + 'blocks': + 'palikoita', + 'normal (1x)': + 'normaali (1x)', + 'demo (1.2x)': + 'demo (1.2x)', + 'presentation (1.4x)': + 'esitys (1.4x)', + 'big (2x)': + 'iso (2x)', + 'huge (4x)': + 'valtava (4x)', + 'giant (8x)': + 'j\u00e4ttim\u00e4inen (8x)', + 'monstrous (10x)': + 'hirvi\u00f6m\u00e4inen (10x)', + + // Project Manager + 'Untitled': + 'Nimet\u00f6n', + 'Open Project': + 'Avaa projekti', + '(empty)': + '(tyhj\u00e4)', + 'Saved!': + 'Tallennettu!', + 'Delete Project': + 'Poista projekti', + 'Are you sure you want to delete': + 'Poistetaanko varmasti?', + 'rename...': + 'nime\u00e4 uusiksi...', + + // costume editor + 'Costume Editor': + 'Asun muokkaus', + 'click or drag crosshairs to move the rotation center': + 'siirr\u00e4 kiertokeskusta klikkaamalla\n' + + 'tai pit\u00e4m\u00e4ll\u00e4 hiirt\u00e4 ' + + 'painettuna ja liikuttamalla', + + // project notes + 'Project Notes': + 'Projektin muistiinpanot', + + // new project + 'New Project': + 'Uusi projekti', + 'Replace the current project with a new one?': + 'Korvataanko nykyinen projekti uudella?', + + // save project + 'Save Project As...': + 'Tallenna projekti nimell\u00e4...', + + // export blocks + 'Export blocks': + 'Vie palikoita', + 'Import blocks': + 'Tuo palikoita', + 'this project doesn\'t have any\ncustom global blocks yet': + 'projektilla ei ole viel\u00e4\nyht\u00e4\u00e4n yhteist\u00e4\n' + + 'muokattua palikkaa', + 'select': + 'valitse', + 'none': + 'ei mit\u00e4\u00e4n', + + // variable dialog + 'for all sprites': + 'kaikille hahmoille', + 'for this sprite only': + 'vain t\u00e4lle hahmolle', + + // block dialog + 'Change block': + 'Muuta palikkaa', + 'Command': + 'Komento', + 'Reporter': + 'Funktio', + 'Predicate': + 'Predikaatti', + + // block editor + 'Block Editor': + 'Palikan muokkaus', + 'Apply': + 'Tee muutokset', + + // block deletion dialog + 'Delete Custom Block': + 'Poista palikka', + 'block deletion dialog text': + 'Poistetaanko t\u00e4m\u00e4 palikka\n ja kaikki sen esiintym\u00e4t?', + + + // input dialog + 'Create input name': + 'Nime\u00e4 sy\u00f6te', + 'Edit input name': + 'Muokkaa sy\u00f6tteen nime\u00e4', + 'Edit label fragment': + 'Muokkaa otsikkoa', + 'Title text': + 'Otsikko', + 'Input name': + 'Sy\u00f6te', + 'Delete': + 'Poista', + 'Object': + 'Objekti', + 'Number': + 'Luku', + 'Text': + 'Teksti', + 'List': + 'Lista', + 'Any type': + 'Mik\u00e4 vain', + 'Boolean (T/F)': + 'Totuusarvo', + 'Command\n(inline)': + 'Komento', + 'Command\n(C-shape)': + 'Komento\n(C-muoto)', + 'Any\n(unevaluated)': + 'Mik\u00e4 vain\n(sitaatti)', + 'Boolean\n(unevaluated)': + 'Totuusarvo\n(sitaatti)', + 'Single input.': + 'Yksi sy\u00f6te.', + 'Default Value:': + 'Oletusarvo:', + 'Multiple inputs (value is list of inputs)': + 'Useita sy\u00f6tteit\u00e4 (listana)', + 'Upvar - make internal variable visible to caller': + 'Paljasta sis\u00e4inen muuttuja ulkopuolelle', + + // About Snap + 'About Snap': + 'Tietoa Snapista', + 'Back...': + 'Takaisin...', + 'License...': + 'Tekij\u00e4noikeudet...', + 'Modules...': + 'Osat...', + 'Credits...': + 'Kiitokset...', + 'Translators...': + 'K\u00e4\u00e4nt\u00e4j\u00e4t...', + 'License': + 'Tekij\u00e4noikeudet', + 'current module versions:': + 'Osien versiot:', + 'Contributors': + 'Osallistujat', + 'Translations': + 'K\u00e4\u00e4nn\u00f6kset', + + // variable watchers + 'normal': + 'tavallinen', + 'large': + 'suuri', + 'slider': + 'liukus\u00e4\u00e4din', + 'slider min...': + 'minimiarvo...', + 'slider max...': + 'maksimiarvo...', + 'import...': + 'tuo...', + 'Slider minimum value': + 'Liukus\u00e4\u00e4timen minimiarvo', + 'Slider maximum value': + 'Liukus\u00e4\u00e4timen maksimiarvo', + + // list watchers + 'length: ': + 'pituus: ', + + // coments + 'add comment here...': + 'Kirjoita kommentti t\u00e4h\u00e4n...', + + // drow downs + // directions + '(90) right': + '(90) oikealle', + '(-90) left': + '(-90) vasemmalle', + '(0) up': + '(0) yl\u00f6s', + '(180) down': + '(180) alas', + + // collision detection + 'mouse-pointer': + 'hiiren osoitin', + 'edge': + 'reuna', + 'pen trails': + 'kyn\u00e4n j\u00e4lki', + + // costumes + 'Turtle': + 'Osoitin', + 'Empty': + 'Tyhj\u00e4', + + // graphical effects + 'ghost': + 'l\u00e4pin\u00e4kyvyys', + + // keys + 'space': + 'v\u00e4lily\u00f6nti', + 'up arrow': + 'nuoli yl\u00f6s', + 'down arrow': + 'nuoli alas', + 'right arrow': + 'nuoli oikealle', + 'left arrow': + 'nuoli vasemmalle', + 'a': + 'a', + 'b': + 'b', + 'c': + 'c', + 'd': + 'd', + 'e': + 'e', + 'f': + 'f', + 'g': + 'g', + 'h': + 'h', + 'i': + 'i', + 'j': + 'j', + 'k': + 'k', + 'l': + 'l', + 'm': + 'm', + 'n': + 'n', + 'o': + 'o', + 'p': + 'p', + 'q': + 'q', + 'r': + 'r', + 's': + 's', + 't': + 't', + 'u': + 'u', + 'v': + 'v', + 'w': + 'w', + 'x': + 'x', + 'y': + 'y', + 'z': + 'z', + '0': + '0', + '1': + '1', + '2': + '2', + '3': + '3', + '4': + '4', + '5': + '5', + '6': + '6', + '7': + '7', + '8': + '8', + '9': + '9', + + // messages + 'new...': + 'uusi...', + + // math functions + 'abs': + 'itseisarvo', + 'floor': + 'py\u00f6ristys alas', + 'sqrt': + 'neli\u00f6juuri', + 'sin': + 'sin', + 'cos': + 'cos', + 'tan': + 'tan', + 'asin': + 'asin', + 'acos': + 'acos', + 'atan': + 'atan', + 'ln': + 'ln', + 'e^': + 'e^', + + // delimiters + 'whitespace': + 'tyhjien v\u00e4lien', + 'line': + 'rivinvaihtojen (lf)', + 'tab': + 'sarkaimien (tab)', + 'cr': + 'vaununpalautusten (cr)', + + // data types + 'number': + 'luku', + 'text': + 'teksti', + 'Boolean': + 'totuusarvo', + 'list': + 'lista', + 'command': + 'komentopalikka', + 'reporter': + 'funktiopalikka', + 'predicate': + 'predikaatti', + + // list indices + 'last': + 'viimeinen', + 'any': + 'mik\u00e4 tahansa' +}; diff --git a/locale.js b/locale.js index c4e8f6f..d71a9c6 100644 --- a/locale.js +++ b/locale.js @@ -368,4 +368,16 @@ SnapTranslator.dict.ca = { 'tibabenfortlapalanca@gmail.com', 'last_changed': '2013-11-26' -}; \ No newline at end of file +}; + +SnapTranslator.dict.fi = { + // meta information + 'language_name': + 'suomi', + 'language_translator': + 'Jouni K. Sepp\u00e4nen', + 'translator_e-mail': + 'jks@iki.fi', + 'last_changed': + '2014-04-18' +}; -- cgit v1.3.1 From 9dad5314df266acb7418c96caa6fa77cb9bdcdbe Mon Sep 17 00:00:00 2001 From: Michael Ball Date: Tue, 22 Apr 2014 17:05:14 -0700 Subject: fix set turbo mode block --- threads.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/threads.js b/threads.js index 77632d0..ef83b46 100644 --- a/threads.js +++ b/threads.js @@ -1482,10 +1482,10 @@ Process.prototype.doSetFastTracking = function (bool) { if (this.homeContext.receiver) { ide = this.homeContext.receiver.parentThatIsA(IDE_Morph); if (ide) { - if (ide.stage.isFastTracked) { - ide.stopFastTracking(); - } else { + if (bool === true) { ide.startFastTracking(); + } else { + ide.stopFastTracking(); } } } -- cgit v1.3.1 From d2c47608441bb4a9b221ad11581e964248c3f967 Mon Sep 17 00:00:00 2001 From: blob8108 Date: Sat, 26 Apr 2014 01:10:57 +0100 Subject: Add charset to variable export --- objects.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/objects.js b/objects.js index 41b511d..9c5087a 100644 --- a/objects.js +++ b/objects.js @@ -6339,7 +6339,7 @@ WatcherMorph.prototype.userMenu = function () { 'export...', function () { window.open( - 'data:text/plain,' + + 'data:text/plain;charset=utf-8,' + encodeURIComponent(this.currentValue.toString()) ); } -- cgit v1.3.1 From 826eb102c88ca4722a44fe1cc150ba16a30ef9a6 Mon Sep 17 00:00:00 2001 From: Michael Ball Date: Sun, 27 Apr 2014 12:46:57 -0700 Subject: style fix for bool --- threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/threads.js b/threads.js index ef83b46..ca6bcd2 100644 --- a/threads.js +++ b/threads.js @@ -1482,7 +1482,7 @@ Process.prototype.doSetFastTracking = function (bool) { if (this.homeContext.receiver) { ide = this.homeContext.receiver.parentThatIsA(IDE_Morph); if (ide) { - if (bool === true) { + if (bool) { ide.startFastTracking(); } else { ide.stopFastTracking(); -- cgit v1.3.1 From 7a9f83295a68f27489a265c06c814fd2701a4df1 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 30 Apr 2014 07:31:11 +0200 Subject: Brazilian Portuguese translation contributed by Aldo von Wangenheim. Thanks! --- lang-pt_BR.js | 1389 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ locale.js | 15 +- 2 files changed, 1403 insertions(+), 1 deletion(-) create mode 100755 lang-pt_BR.js diff --git a/lang-pt_BR.js b/lang-pt_BR.js new file mode 100755 index 0000000..f277c45 --- /dev/null +++ b/lang-pt_BR.js @@ -0,0 +1,1389 @@ +/* + + lang-pt_BR.js + + Brazilian Portuguese translation for SNAP! + + translated by Aldo von Wangenheim + + Copyright (C) 2014 by Aldo von Wangenheim + + This file is part of Snap!. + + Snap! is free software: you can redistribute it and/or modify + it under the terms of 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + + + Note to Translators: + -------------------- + At this stage of development, Snap! can be translated to any LTR language + maintaining the current order of inputs (formal parameters in blocks). + + Translating Snap! is easy: + + + 1. Download + + Download the sources and extract them into a local folder on your + computer: + + + + Use the German translation file (named 'lang-de.js') as template for your + own translations. Start with editing the original file, because that way + you will be able to immediately check the results in your browsers while + you're working on your translation (keep the local copy of snap.html open + in your web browser, and refresh it as you progress with your + translation). + + + 2. Edit + + Edit the translation file with a regular text editor, or with your + favorite JavaScript editor. + + In the first non-commented line (the one right below this + note) replace "de" with the two-letter ISO 639-1 code for your language, + e.g. + + fr - French => SnapTranslator.dict.fr = { + it - Italian => SnapTranslator.dict.it = { + pl - Polish => SnapTranslator.dict.pl = { + pt - Portuguese => SnapTranslator.dict.pt = { + es - Spanish => SnapTranslator.dict.es = { + el - Greek => => SnapTranslator.dict.el = { + + etc. (see ) + + + 3. Translate + + Then work through the dictionary, replacing the German strings against + your translations. The dictionary is a straight-forward JavaScript ad-hoc + object, for review purposes it should be formatted as follows: + + { + 'English string': + 'Translation string', + 'last key': + } 'last value' + + and you only edit the indented value strings. Note that each key-value + pair needs to be delimited by a comma, but that there shouldn't be a comma + after the last pair (again, just overwrite the template file and you'll be + fine). + + If something doesn't work, or if you're unsure about the formalities you + should check your file with + + + + This will inform you about any missed commas etc. + + + 4. Accented characters + + Depending on which text editor and which file encoding you use you can + directly enter special characters (e.g. Umlaut, accented characters) on + your keyboard. However, I've noticed that some browsers may not display + special characters correctly, even if other browsers do. So it's best to + check your results in several browsers. If you want to be on the safe + side, it's even better to escape these characters using Unicode. + + see: + + + 5. Block specs: + + At this time your translation of block specs will only work + correctly, if the order of formal parameters and their types + are unchanged. Placeholders for inputs (formal parameters) are + indicated by a preceding % prefix and followed by a type + abbreviation. + + For example: + + 'say %s for %n secs' + + can currently not be changed into + + 'say %n secs long %s' + + and still work as intended. + + Similarly + + 'point towards %dst' + + cannot be changed into + + 'point towards %cst' + + without breaking its functionality. + + + 6. Submit + + When you're done, rename the edited file by replacing the "de" part of the + filename with the two-letter ISO 639-1 code for your language, e.g. + + fr - French => lang-fr.js + it - Italian => lang-it.js + pl - Polish => lang-pl.js + pt - Portuguese => lang-pt.js + es - Spanish => lang-es.js + el - Greek => => lang-el.js + + and send it to me for inclusion in the official Snap! distribution. + Once your translation has been included, Your name will the shown in the + "Translators" tab in the "About Snap!" dialog box, and you will be able to + directly launch a translated version of Snap! in your browser by appending + + lang:xx + + to the URL, xx representing your translations two-letter code. + + + 7. Known issues + + In some browsers accents or ornaments located in typographic ascenders + above the cap height are currently (partially) cut-off. + + Enjoy! + -Jens +*/ + +/*global SnapTranslator*/ + +SnapTranslator.dict.pt_BR = { + +/* + Special characters: (see ) + + Ä, ä \u00c4, \u00e4 + Ö, ö \u00d6, \u00f6 + Ü, ü \u00dc, \u00fc + ß \u00df +*/ + + // meta informação sobre a tradução + 'language_name': + 'Português do Brasil', + 'language_translator': + 'Aldo von Wangenheim', + 'translator_e-mail': + 'awangenh@inf.ufsc.br', + 'last_changed': + '2014-04-20', + + // GUI + // control bar: + 'untitled': + 'Sem título', + 'development mode': + 'modo de desenvolvimento', + + // categorias: + 'Motion': + 'Movimento', + 'Looks': + 'Aparência', + 'Sound': + 'Som', + 'Pen': + 'Caneta', + 'Control': + 'Controle', + 'Sensing': + 'Sensores', + 'Operators': + 'Operadores', + 'Variables': + 'Variáveis', + 'Lists': + 'Listas', + 'Other': + 'Outros', + + // editor: + 'draggable': + 'arrastável', + + // separadores: + 'Scripts': + 'Roteiros', + 'Costumes': + 'Fantasias', + 'Sounds': + 'Sons', + + // nomes: + 'Sprite': + 'Ator', + 'Stage': + 'Palco', + + // estilos de rotação: + 'don\'t rotate': + 'não rode', + 'can rotate': + 'rode', + 'only face left/right': + 'olhe apenas para a esquerda ou para a direita', + + // botão de criação de novo actor: + 'add a new sprite': + 'adicionar um novo ator', + + // ajuda nos tabuladores + 'costumes tab help': + 'Importa uma imagem de uma página Web ou de um\n' + + 'arquivo no teu computador arrastando-a para aqui', + 'import a sound from your computer\nby dragging it into here': + 'Importe um som de seu computador\narrastando-o para cá', + + // blocos primitivos: + + /* + Attention Translators: + ---------------------- + At this time your translation of block specs will only work + correctly, if the order of formal parameters and their types + are unchanged. Placeholders for inputs (formal parameters) are + indicated by a preceding % prefix and followed by a type + abbreviation. + + For example: + + 'say %s for %n secs' + + can currently not be changed into + + 'say %n secs long %s' + + and still work as intended. + + Similarly + + 'point towards %dst' + + cannot be changed into + + 'point towards %cst' + + without breaking its functionality. + */ + + // Movimento: + 'Stage selected:\nno motion primitives': + 'Palco selecionado:\nsem primitivas de movimento', + + + 'move %n steps': + 'mova %n passos', + 'turn %clockwise %n degrees': + 'gire %clockwise %n graus', + 'turn %counterclockwise %n degrees': + 'gire %counterclockwise %n graus', + 'point in direction %dir': + 'aponte para a direção %dir graus', + 'point towards %dst': + 'aponte para %dst', + 'go to x: %n y: %n': + 'vá para x: %n , y: %n ', + 'go to %dst': + 'vá para %dst', + 'glide %n secs to x: %n y: %n': + 'deslize por %n segundos ate x: %n , y: %n ', + 'change x by %n': + 'adicione %n a x', + 'set x to %n': + 'mude x para %n', + 'change y by %n': + 'adicione %n a y', + 'set y to %n': + 'mude y para %n', + 'if on edge, bounce': + 'se tocar na borda, volte', + 'x position': + 'coordenada x da posição', + 'y position': + 'coordenada y da posição', + 'direction': + 'direção', + + // Aparência: + 'switch to costume %cst': + 'mude para a fantasia %cst', + 'next costume': + 'próxima fantasia', + 'costume #': + 'n° da fantasia', + 'say %s for %n secs': + 'diga %s por %n segundos', + 'say %s': + 'diga %s', + 'think %s for %n secs': + 'pense %s por %n segundos', + 'think %s': + 'pense %s', + 'Hello!': + 'Olá!', + 'Hmm...': + 'Hmm…', + 'change %eff effect by %n': + 'adicione ao efeito %eff %n', + 'set %eff effect to %n': + 'mude o efeito %eff para %n', + 'clear graphic effects': + 'apague os efeitos gráficos', + 'change size by %n': + 'adicione %n ao seu tamanho', + 'set size to %n %': + 'mude o tamanho para %n %', + 'size': + 'tamanho', + 'show': + 'mostrar', + 'hide': + 'esconder', + 'go to front': + 'vá para a frente', + 'go back %n layers': + 'vá %n camadas para trás', + + 'development mode \ndebugging primitives:': + 'primitivas de depuração \ndo modo de desenvolvimento:', + 'console log %mult%s': + 'registre %mult%s no console', + 'alert %mult%s': + 'mostre janela de alerta com %mult%s', + + // Som: + 'play sound %snd': + 'toque o som %snd', + 'play sound %snd until done': + 'toque o som %snd até o fim', + 'stop all sounds': + 'pare todos os sons', + 'rest for %n beats': + 'silêncio por %n tempos', + 'play note %n for %n beats': + 'toque a nota %n durante %n tempos', + 'change tempo by %n': + 'adicione %n tempos ao andamento', + 'set tempo to %n bpm': + 'altere o andamento para %n tempos', + 'tempo': + 'andamento', + + // Caneta: + 'clear': + 'apague tudo', + 'pen down': + 'use a caneta', + 'pen up': + 'levante a caneta', + 'set pen color to %clr': + 'mude a cor da caneta para %clr', + 'change pen color by %n': + 'adicione %n à cor da caneta', + 'set pen color to %n': + 'mude a cor da caneta para %n', + 'change pen shade by %n': + 'adicione %n à intensidade da caneta', + 'set pen shade to %n': + 'mude a intensidade da caneta para %n', + 'change pen size by %n': + 'adicione %n à espessura da caneta', + 'set pen size to %n': + 'mude a espessura da caneta para %n', + 'stamp': + 'carimbe', + + // Eventos e Controle: + 'when %greenflag clicked': + 'quando clicar em %greenflag', + 'when %keyHat key pressed': + 'quando a tecla %keyHat for pressionada', + 'when I am clicked': + 'quando este ator for clicado', + 'when I receive %msgHat': + 'quando receber %msgHat', + 'broadcast %msg': + 'envie %msg a todos', + 'broadcast %msg and wait': + 'envie %msg a todos e espere', + 'Message name': + 'nome da mensagem', + 'message': + 'mensagem', + 'any message': + 'qualquer mensagem', + 'wait %n secs': + 'espere %n segundos', + 'wait until %b': + 'espere até que %b', + 'forever %c': + 'sempre %c', + 'repeat %n %c': + 'repita %n vezes %c', + 'repeat until %b %c': + 'repita até que %b %c', + 'if %b %c': + 'se %b então %c', + 'if %b %c else %c': + 'se %b então %c senão %c', + 'report %s': + 'reporte %s', + 'stop %stopChoices': + 'pare %stopChoices', + 'all': + 'tudo', + 'this script': + 'este roteiro', + 'this block': + 'este bloco', + 'stop %stopOthersChoices': + 'pare %stopOthersChoices', + 'all but this script': + 'todos os roteiros exceto este', + 'other scripts in sprite': + 'outros roteiros deste ator', + 'pause all %pause': + 'pause tudo %pause', + 'run %cmdRing %inputs': + 'execute %cmdRing %inputs', + 'launch %cmdRing %inputs': + 'inicie execução de %cmdRing %inputs', + 'call %repRing %inputs': + 'chame %repRing %inputs', + 'run %cmdRing w/continuation': + 'execute %cmdRing com continuação', + 'call %cmdRing w/continuation': + 'chame %cmdRing com continuação', + 'warp %c': + 'execute atomicamente %c', + 'when I start as a clone': + 'quando este ator começar como clone', + 'create a clone of %cln': + 'crie clone de %cln', + 'myself': + 'este ator', + 'delete this clone': + 'apague este clone', + + // Sensores: + 'touching %col ?': + 'tocando em %col', + 'touching %clr ?': + 'tocando na cor %clr', + 'color %clr is touching %clr ?': + 'a cor %clr está tocando na cor %clr', + 'ask %s and wait': + 'pergunte %s e espere a resposta', + 'what\'s your name?': + 'qual o seu nome?', + 'answer': + 'resposta', + 'mouse x': + 'posição x do mouse', + 'mouse y': + 'posição y do mouse', + 'mouse down?': + 'mouse pressionado?', + 'key %key pressed?': + 'tecla %key pressionada?', + 'distance to %dst': + 'distância até %dst', + 'reset timer': + 'zere o cronómetro', + 'timer': + 'valor do cronómetro', + '%att of %spr': + '%att de %spr', + 'http:// %s': + 'página http:// %s', + 'turbo mode?': + 'modo turbo?', + 'set turbo mode to %b': + 'mude o modo turbo para %b', + + 'filtered for %clr': + 'filtrado por %clr', + 'stack size': + 'altura da pilha', + 'frames': + 'quadros', + + // Operadores: + '%n mod %n': + 'resto de %n por %n', + 'round %n': + 'arredondamento de %n', + '%fun of %n': + '%fun de %n', + 'pick random %n to %n': + 'escolha um valor ao acaso entre %n e %n', + '%b and %b': + '%b e %b', + '%b or %b': + '%b ou %b', + 'not %b': + 'não %b', + 'true': + 'verdadeiro', + 'false': + 'falso', + 'join %words': + 'junte %words', + 'split %s by %delim': + 'separe %s por %delim', + 'hello': + 'Olá', + 'world': + 'mundo', + 'letter %n of %s': + 'o caractere %n de %s', + 'length of %s': + 'o comprimento de %s', + 'unicode of %s': + 'o código Unicode do caractere %s', + 'unicode %n as letter': + 'o caractere cujo código Unicode é %n', + 'is %s a %typ ?': + '%s é um/uma %typ', + 'is %s identical to %s ?': + '%s é idêntico a %s', + + 'type of %s': + 'o tipo de %s', + + // Variáveis: + 'Make a variable': + 'Criar uma variável', + 'Variable name': + 'Nome da variável', + 'Script variable name': + 'Nome da variável de Roteiro', + 'Delete a variable': + 'Remova uma variável', + + 'set %var to %s': + 'mude %var para %s', + 'change %var by %n': + 'adicione a %var o valor %n', + 'show variable %var': + 'mostre variável %var', + 'hide variable %var': + 'esconda variável %var', + 'script variables %scriptVars': + 'crie as variáveis de roteiro %scriptVars', + + // listas: + 'list %exp': + 'uma lista com %exp', + '%s in front of %l': + '%s inicia %l', + 'item %idx of %l': + '%idx de %l', + 'all but first of %l': + 'todos elementos de %l menos o primeiro', + 'length of %l': + 'tamanho de %l', + '%l contains %s': + '%l contém %s', + 'thing': + 'valor', + 'add %s to %l': + 'adicione %s a %l', + 'delete %ida of %l': + 'apague %ida de %l', + 'insert %s at %idx of %l': + 'insira %s na posição %idx em %l', + 'replace item %idx of %l with %s': + 'substitua o item %idx de %l por %s', + + // Outros + 'Make a block': + 'Criar um bloco', + + // Menus + // Snap menu + 'About...': + 'Sobre Snap!…', + 'Reference manual': + 'Manual de Referência', + 'Snap! website': + 'Site do Snap!', + 'Download source': + 'Baixar código fonte', + 'Switch back to user mode': + 'Volte ao modo de usuário', + 'disable deep-Morphic\ncontext menus\nand show user-friendly ones': + 'Desative menus de contexto\nprofundos do Morphic e\nmostrar menus amigáveis.', + 'Switch to dev mode': + 'Mude para modo de desenvolvimento', + 'enable Morphic\ncontext menus\nand inspectors,\nnot user-friendly!': + 'Ativar menus de contexto\ne inspectores não\namigáveis do Morphic!', + + // Menu de projeto + 'Project notes...': + 'Notas deste projeto…', + 'New': + 'Criar um novo projeto', + 'Open...': + 'Abrir um projeto…', + 'Save': + 'Salvar', + 'Save As...': + 'Salvar como…', + 'Import...': + 'Importar…', + 'file menu import hint': + 'Importar para este projecto\num projeto exportado,\n' + + 'uma biblioteca de blocos,\n' + + 'um traje ou um som.', + 'Export project as plain text...': + 'Exportar este projeto em modo texto…', + 'Export project...': + 'Exportar este projeto…', + 'show project data as XML\nin a new browser window': + 'Mostrar os dados no\nformato XML numa nova janela do navegador.', + 'Export blocks...': + 'Exportar blocos…', + 'show global custom block definitions as XML\nin a new browser window': + 'Mostrar as definições globais de blocos\npersonalizados no formato\nXML numa nova janela do navegador.', + 'Import tools': + 'Importar ferramentas oficiais', + 'load the official library of\npowerful blocks': + 'Importar a biblioteca\n oficial de blocos.', + 'Libraries...': + 'Bibliotecas...', + 'Import library': + 'Importar biblioteca', + + // Menu da nuvem + 'Login...': + 'Entrar na sua conta…', + 'Signup...': + 'Registar uma nova conta…', + + // menu de preferências + 'Language...': + 'Língua…', + 'Zoom blocks...': + 'Zoom dos blocos…', + 'Blurred shadows': + 'Sombras borradas', + 'uncheck to use solid drop\nshadows and highlights': + 'Desmarque para usar sombras\ne realces nítidos.', + 'check to use blurred drop\nshadows and highlights': + 'Marque para usar sombras\ne realces borrados.', + 'Zebra coloring': + 'Coloração em zebra', + 'check to enable alternating\ncolors for nested blocks': + 'Marque para alternar\nas cores de blocos aninhados.', + 'uncheck to disable alternating\ncolors for nested block': + 'Desmarque para deixar de alternar\nas cores de blocos aninhados.', + 'Dynamic input labels': + 'Nomes de entrada dinâmicos', + 'uncheck to disable dynamic\nlabels for variadic inputs': + 'Desmarque para desativar nomes\ndinâmicos nas variáveis de entrada.', + 'check to enable dynamic\nlabels for variadic inputs': + 'Marque para ativar nomes\ndinâmicos nas variáveis de entrada.', + 'Prefer empty slot drops': + 'Procure encaixar blocos de valor (repórteres) em campos vazios ao soltar', + 'settings menu prefer empty slots hint': + 'Marque para focar em campos vazios\nquando estiver arrastando e ' + + 'soltando blocos de valor (repórteres).', + 'uncheck to allow dropped\nreporters to kick out others': + 'Desmarque para permitir que blocos\nrepórteres soltos em um campo ' + + 'desalojem outros.', + 'Long form input dialog': + 'Forma longa da caixa de diálogo dos parâmetros', + 'Plain prototype labels': + 'Use texto simples para protótipos', + 'uncheck to always show (+) symbols\nin block prototype labels': + 'Desmarque para mostrar sempre os símbolos (+)\nno texto dos protótipos dos blocos', + 'check to hide (+) symbols\nin block prototype labels': + 'Marque para esconder os símbolos (+)\nno texto dos protótipos dos blocos', + 'check to always show slot\ntypes in the input dialog': + 'Marque para sempre mostrar\no tipo dos campos na caixa\nde diálogo dos parâmetros.', + 'uncheck to use the input\ndialog in short form': + 'Desmarque para usar texto abreviado\nda caixa de diálogo dos parâmetros.', + 'Virtual keyboard': + 'Teclado virtual', + 'uncheck to disable\nvirtual keyboard support\nfor mobile devices': + 'Desmarque para desativar o\nsuporte ao teclado virtual\npara dispositivos ' + + 'móveis.', + 'check to enable\nvirtual keyboard support\nfor mobile devices': + 'Marque para ativar o\nsuporte ao teclado virtual\npara dispositivos ' + + 'móveis.', + 'Input sliders': + 'Sliders nos campos de entrada', + 'uncheck to disable\ninput sliders for\nentry fields': + 'Desmarque para desativar\nsliders nos campos de entrada dos blocos.', + 'check to enable\ninput sliders for\nentry fields': + 'Marque para ativar\nsliders nos campos de entrada dos blocos.', + 'Clicking sound': + 'Som de cliques', + 'uncheck to turn\nblock clicking\nsound off': + 'Desmarque para desativar o som\nproduzido ao clicar nos blocos.', + 'check to turn\nblock clicking\nsound on': + 'Marque para ativar o som\nproduzido ao clicar nos blocos.', + 'Animations': + 'Animações', + 'uncheck to disable\nIDE animations': + 'Desmarque para desativar\nas animações da interface de usuário.', + 'Turbo mode.': + 'Modo turbo', + 'check to prioritize\nscript execution': + 'Marque para priorizar\na execução de roteiros.', + 'uncheck to run scripts\nat normal speed': + 'Desmarque para executar os roteiros\nna velocidade normal.', + 'check to enable\nIDE animations': + 'Marque para ativar\nas animações da interface de usuário.', + 'Thread safe scripts': + 'Roteiros seguros face a threads', + 'uncheck to allow\nscript reentrance': + 'Desmarque para permitir\nreentrância nos roteiros.', + 'check to disallow\nscript reentrance': + 'Marque para não permitir\nreentrância nos roteiros.', + 'Prefer smooth animations': + 'Prefira animações suaves', + 'uncheck for greater speed\nat variable frame rates': + 'Desmarque para aumentar a velocidade\npermitindo ritmos variáveis das tramas nas animações.', + 'check for smooth, predictable\nanimations across computers': + 'Marque para obter animações mais suaves\ne previsíveis de computador para computador.', + + // Entradas + 'with inputs': + 'com argumentos', + 'input names:': + 'com parâmetros', + 'Input Names:': + 'Parâmetros:', + 'input list:': + 'lista de entradas', + + // menus de contexto: + 'help': + 'ajuda', + + // palette: + 'hide primitives': + 'esconda blocos primitivos', + 'show primitives': + 'mostre blocos primitivos', + + // blocos: + 'help...': + 'ajuda…', + 'relabel...': + 'renomear…', + 'duplicate': + 'duplicar', + 'make a copy\nand pick it up': + 'Faça uma cópia do\nbloco e pegue-a.', + 'only duplicate this block': + 'Duplique apenas este bloco.', + 'delete': + 'apague', + 'script pic...': + 'fotografia do roteiro', + 'open a new window\nwith a picture of this script': + 'Abra uma nova janela com\numa fotografia deste roteiro.', + 'ringify': + 'adicione anel', + 'unringify': + 'apague anel', + + // blocos personalizados: + 'delete block definition...': + 'remova definição do bloco…', + 'edit...': + 'editar…', + + // Atores: + 'edit': + 'editar', + 'detach from': + 'desencaixe de', + 'detach all parts': + 'desencaixe todas as partes', + 'export...': + 'exportar…', + + // palco: + 'show all': + 'mostre todos os atores', + 'pic...': + 'fotografia…', + 'open a new window\nwith a picture of the stage': + 'Abrir uma nova janela com\numa fotografia do palco.', + + // área de Roteiros: + 'clean up': + 'limpar', + 'arrange scripts\nvertically': + 'Organize roteiros\nverticalmente.', + 'add comment': + 'adicione um comentário', + 'undrop': + 'desfaça posicionamento', + 'undo the last\nblock drop\nin this pane': + 'Desfazer o último posicionamento de um bloco\nneste painel.', + 'scripts pic...': + 'fotografe os roteiros…', + 'open a new window\nwith a picture of all scripts': + 'Abra uma nova janela com\numa fotografia de todos os roteiros.', + 'make a block...': + 'crie um bloco…', + + // Fantasias: + 'rename': + 'renomear', + 'export': + 'exportar', + 'rename costume': + 'Qual o novo nome da fantasia?', + + // Sons + 'Play sound': + 'Toque som.', + 'Stop sound': + 'Pare som.', + 'Stop': + 'Parar', + 'Play': + 'Tocar', + 'rename sound': + 'Qual o novo nome do som?', + + // Caixas de diálogo + // botões + 'OK': + 'OK', + 'Ok': + 'OK', + 'Cancel': + 'Cancela', + 'Yes': + 'Sim', + 'No': + 'Não', + + // ajuda + 'Help': + 'Ajuda', + + // ampliação de blocos + 'Zoom blocks': + 'Zoom dos blocos', + 'build': + 'construa', + 'your own': + 'os seus próprios', + 'blocks': + 'blocos', + 'normal (1x)': + 'normal (1x)', + 'demo (1.2x)': + 'demonstração (1.2x)', + 'presentation (1.4x)': + 'apresentação (1.4x)', + 'big (2x)': + 'grande (2x)', + 'huge (4x)': + 'enorme (4x)', + 'giant (8x)': + 'gigante (8x)', + 'monstrous (10x)': + 'monstruoso (10x)', + + // Gestor de Projetos + 'Untitled': + 'Sem título', + 'Open Project': + 'Abrir Projeto', + '(empty)': + '(vazio)', + 'Saved!': + 'Salvo!', + 'Delete Project': + 'Apague Projeto', + 'Are you sure you want to delete': + 'Tem certeza que deseja apagar?', + 'rename...': + 'alterar o nome…', + + // Editor de fantasias + 'Costume Editor': + 'Editor de Fantasias', + 'click or drag crosshairs to move the rotation center': + 'Clique ou arraste a mira para mudar o centro de rotação.', + + // Anotaes de projeto + 'Project Notes': + 'Notas do Projeto', + + // Novo projeto + 'New Project': + 'Novo Projeto', + 'Replace the current project with a new one?': + 'Substituir este projeto por um novo projeto?', + + // guardar projecto + 'Save Project As...': + 'Salvar Projeto Como…', + + // exportar blocos + 'Export blocks': + 'Exportar blocos', + 'Import blocks': + 'Importar blocos', + 'this project doesn\'t have any\ncustom global blocks yet': + 'Este projeto ainda não possui\nnenhum bloco global personalizado.', + 'select': + 'selecionar', + 'none': + 'nenhum', + + // Caixa de diálogo de variáveis + 'for all sprites': + 'para todos os atores', + 'for this sprite only': + 'apenas para este ator', + + // caixa de diálogo de blocos + 'Change block': + 'Altere o tipo do bloco', + 'Command': + 'Comando', + 'Reporter': + 'Repórter', + 'Predicate': + 'Predicado', + + // editor de blocos + 'Block Editor': + 'Editor de Blocos', + 'Apply': + 'Aplicar', + + // caixa de diálogo de remoção de bloco + 'Delete Custom Block': + 'Remova Bloco Personalizado', + 'block deletion dialog text': + 'Quer mesmo remover este bloco e ' + + 'todas as suas aplicações?', + + // Caixa de diálogo de parâmetros + 'Create input name': + 'Criar parâmetro', + 'Edit input name': + 'Editar parâmetro', + 'Edit label fragment': + 'Editar rótulo', + 'Title text': + 'Nome', + 'Input name': + 'Parâmetro', + 'Delete': + 'Remover', + 'Object': + 'Objeto', + 'Number': + 'Número', + 'Text': + 'Texto', + 'List': + 'Lista', + 'Any type': + 'Qualquer tipo', + 'Boolean (T/F)': + 'Booleano (V/F)', + 'Command\n(inline)': + 'Comando\n(em linha)', + 'Command\n(C-shape)': + 'Comando\n(bloco de repetição)', + 'Any\n(unevaluated)': + 'Repórter\n(forma especial)', + 'Boolean\n(unevaluated)': + 'Predicado\n(forma especial)', + 'Single input.': + 'Parâmetro único.', + 'Default Value:': + 'Valor em caso de omissão:', + 'Multiple inputs (value is list of inputs)': + 'Múltiplos argumentos (o valor do parâmetro é a lista dos argumentos).', + 'Upvar - make internal variable visible to caller': + 'Tornar o parâmetro visível ao invocador.', + + // Acerca do Snap + 'About Snap': + 'Sobre o Snap!', + 'Back...': + 'Para trás…', + 'License...': + 'Licença…', + 'Modules...': + 'Módulos…', + 'Credits...': + 'Créditos…', + 'Translators...': + 'Tradutores…', + 'License': + 'Licença', + 'current module versions:': + 'versões actuais dos módulos', + 'Contributors': + 'Contribuidores', + 'Translations': + 'Traduções', + + // observadores de variáveis + 'normal': + 'normal', + 'large': + 'grande', + 'slider': + 'slider', + 'slider min...': + 'mínimo do slider…', + 'slider max...': + 'máximo do slider…', + 'import...': + 'importar…', + 'Slider minimum value': + 'Valor mínimo do potenciómetro deslizante', + 'Slider maximum value': + 'Valor máximo do potenciómetro deslizante', + + // observadores de listas + 'length: ': + 'tamanho: ', + + // comentários + 'add comment here...': + 'coloque aqui um comentário…', + + // drop downs + // direcções + '(90) right': + '90° (direita)', + '(-90) left': + '-90° (esquerda)', + '(0) up': + '0° (acima)', + '(180) down': + '180° (abaixo)', + + // detecção de colisões + 'mouse-pointer': + 'ponteiro do mouse', + 'edge': + 'borda', + 'pen trails': + 'traços da caneta', + + // trajes + 'Turtle': + 'seta', + 'Empty': + 'vazio', + + // efeitos gráficos + 'ghost': + 'fantasma', + + // teclas + 'space': + 'espaço', + 'up arrow': + 'seta para cima', + 'down arrow': + 'seta para baixo', + 'right arrow': + 'seta para a direita', + 'left arrow': + 'seta para a esquerda', + 'a': + 'a', + 'b': + 'b', + 'c': + 'c', + 'd': + 'd', + 'e': + 'e', + 'f': + 'f', + 'g': + 'g', + 'h': + 'h', + 'i': + 'i', + 'j': + 'j', + 'k': + 'k', + 'l': + 'l', + 'm': + 'm', + 'n': + 'n', + 'o': + 'o', + 'p': + 'p', + 'q': + 'q', + 'r': + 'r', + 's': + 's', + 't': + 't', + 'u': + 'u', + 'v': + 'v', + 'w': + 'w', + 'x': + 'x', + 'y': + 'y', + 'z': + 'z', + '0': + '0', + '1': + '1', + '2': + '2', + '3': + '3', + '4': + '4', + '5': + '5', + '6': + '6', + '7': + '7', + '8': + '8', + '9': + '9', + + // messagens + 'new...': + 'Nova…', + + // funções matemáticas + 'abs': + 'valor absoluto', + 'floor': + 'arredondamento para baixo', + 'sqrt': + 'raiz quadrada', + 'sin': + 'seno', + 'cos': + 'cosseno', + 'tan': + 'tangente', + 'asin': + 'arco-seno', + 'acos': + 'arco-cosseno', + 'atan': + 'arco-tangente', + 'ln': + 'logaritmo natural', + 'e^': + 'exponencial', + + // delimitadores + 'whitespace': + 'espaços em branco', + 'line': + 'avanços de linha', + 'tab': + 'tabuladores', + 'cr': + 'retornos', + + // tipos de dados + 'number': + 'número', + 'text': + 'texto', + 'Boolean': + 'booleano', + 'list': + 'lista', + 'command': + 'comando', + 'reporter': + 'repórter', + 'predicate': + 'predicado', + + // índices de listas + 'last': + 'último item', + 'any': + 'um item ao acaso', + + // em falta no ficheiro lang-de.js + 'costume name': + 'nome da fantasia', + 'Open': + 'Abrir', + 'Share': + 'Compartilhar', + 'Cloud': + 'Nuvem', + 'Browser': + 'Navegador', + 'Sign up': + 'Registrar nova conta', + 'Sign in': + 'Entrar', + 'now connected.': + 'entrou.', + 'disconnected.': + 'saiu.', + 'Reset password': + 'Recuperar senha', + 'Reset Password...': + 'Recuperar a sua senha...', + 'User name:': + 'Nome de usuário:', + 'Password:': + 'Senha:', + 'Birth date:': + 'Data de nascimento:', + 'January': + 'Janeiro', + 'February': + 'Fevereiro', + 'March': + 'Março', + 'April': + 'Abril', + 'May': + 'Maio', + 'June': + 'Junho', + 'July': + 'Julho', + 'August': + 'Agosto', + 'September': + 'Setembro', + 'October': + 'Outubro', + 'November': + 'Novembro', + 'December': + 'Dezembro', + 'year:': + 'ano:', + ' or before': + ' ou antes', + 'E-mail address:': + 'Endereço de email:', + 'E-mail address of parent or guardian:': + 'Endereço de encarregado de educação:', + 'Terms of Service...': + 'Termos do Serviço…', + 'Privacy...': + 'Privacidade…', + 'I have read and agree\nto the Terms of Service': + 'Li e declaro concordar\ncom os Termos do Serviço', + 'stay signed in on this computer\nuntil logging out': + 'manter-me autenticado neste\ncomputador até que saia', + 'please fill out\nthis field': + 'Por favor preencha\neste campo.', + 'User name must be four\ncharacters or longer': + 'O nome de usuário tem de ter\npelo menos quatro caracteres.', + 'please provide a valid\nemail address': + 'Por favor indique um endereço\nde email válido.', + 'password must be six\ncharacters or longer': + 'A senha tem de ter\npelo menos seis caracteres.', + 'passwords do\nnot match': + 'As senhas\nnão correspondem.', + 'please agree to\nthe TOS': + 'Por favor concorde com\nos Termos do Serviço.', + 'Examples': + 'Exemplos', + 'You are not logged in': + 'Ainda não se autenticou', + 'Updating\nproject list...': + 'Atualizando a\nlista de projetos…', + 'Opening project...': + 'Abrindo o projeto…', + 'Fetching project from the cloud...': + 'Obtendo o projeto da nuvem…', + 'Saving project to the cloud...': + 'Salvando o projeto na nuvem…', + 'Sprite Nesting': + 'Atores aninhados', + 'uncheck to disable\nsprite composition': + 'Desmarque para desativar\na composição de atores.', + 'Codification support': + 'Suportar produção de código', + 'check for block\nto text mapping features': + 'Assinalar para funcionalidades\nde mapeamento entre blocos e texto.', + 'Save to disk': + 'Salvar no disco', + 'experimental - store this project\nin your downloads folder': + 'Experimental - Salvar este projeto\nna sua pasta de downloads.', + 'saved.': + 'salvo.', + 'options...': + 'opções…', + 'read-only': + 'apenas leitura', + 'Input Slot Options': + 'Opções de Campos de Entrada', + 'Enter one option per line.Optionally use "=" as key/value delimiter\ne.g.\n the answer=42': + 'Entre com uma opção por linha. Opcionalmente, use "=" como separador\nentre chave e valor, e.g.\n a resposta=42', + 'paint a new sprite': + 'Desenhar um novo ator.', + 'Paint a new costume': + 'Desenhar uma nova fantasia.', + 'add a new Turtle sprite': + 'Adicionar um novo ator.', + 'Flat design': + 'Visual plano', + 'check for alternative\nGUI design': + 'Marque para um design alternativo\nda interface gráfica de usuário.', + 'Rasterize SVGs': + 'Transformar desenhos vetorias (SVG) em mapas de bits', + 'check to rasterize\nSVGs on import': + 'Marque para transformar os arquivos vetoriais SVG\nem mapas de bits durante a importação.', + 'comment pic...': + 'fotografia do comentário…', + 'open a new window\nwith a picture of this comment': + 'Abrir uma nova janela com\numa fotografia deste comentário.' +}; diff --git a/locale.js b/locale.js index d71a9c6..c6924e9 100644 --- a/locale.js +++ b/locale.js @@ -42,7 +42,7 @@ /*global modules, contains*/ -modules.locale = '2014-February-13'; +modules.locale = '2014-April-30'; // Global stuff @@ -381,3 +381,16 @@ SnapTranslator.dict.fi = { 'last_changed': '2014-04-18' }; + +SnapTranslator.dict.pt_BR = { + // meta information + 'language_name': + 'Português do Brasil', + 'language_translator': + 'Aldo von Wangenheim', + 'translator_e-mail': + 'awangenh@inf.ufsc.br', + 'last_changed': + '2014-04-20' +}; + -- cgit v1.3.1 From 51e17d2ce9368c3546b7e27809dfbd187cefb246 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 30 Apr 2014 12:18:06 +0200 Subject: enable storage of first-class costumes --- history.txt | 6 ++++++ objects.js | 2 +- store.js | 14 ++++++++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/history.txt b/history.txt index 2c0362b..69b48bc 100755 --- a/history.txt +++ b/history.txt @@ -2109,3 +2109,9 @@ ______ * Objects: experimental “wardrobe” and “jukebox” reporters in dev mode * Blocks, Objects: display costume thumbnails in speech/thought/value bubbles and watcher cells * Objects: let “switch to costume” block accept actual costume objects (in addition to names and numbers) + +140430 +------ +* new Finnish translation, yay! Thanks, Jouni! +* new Brazilian Portuguese translation, yay! Thanks, Aldo! +* enable storage and retrieval of first-class costumes in both file formats diff --git a/objects.js b/objects.js index 1c4e61e..b506195 100644 --- a/objects.js +++ b/objects.js @@ -124,7 +124,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2014-March-31'; +modules.objects = '2014-April-30'; var SpriteMorph; var StageMorph; diff --git a/store.js b/store.js index b3f5d95..d69667a 100644 --- a/store.js +++ b/store.js @@ -61,7 +61,7 @@ SyntaxElementMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.store = '2014-February-13'; +modules.store = '2014-April-30'; // XML_Serializer /////////////////////////////////////////////////////// @@ -457,8 +457,6 @@ SnapSerializer.prototype.loadProjectModel = function (xmlNode) { } }); - this.objects = {}; - /* Global Variables */ if (model.globalVariables) { @@ -468,6 +466,8 @@ SnapSerializer.prototype.loadProjectModel = function (xmlNode) { ); } + this.objects = {}; + /* Watchers */ model.sprites.childrenNamed('watcher').forEach(function (model) { @@ -521,7 +521,7 @@ SnapSerializer.prototype.loadProjectModel = function (xmlNode) { )) ); project.stage.add(watcher); - watcher.update(); + watcher.onNextStep = function () {this.currentValue = null; }; // set watcher's contentsMorph's extent if it is showing a list and // its monitor dimensions are given @@ -1302,6 +1302,12 @@ SnapSerializer.prototype.openProject = function (project, ide) { ide.createCorral(); ide.selectSprite(sprite); ide.fixLayout(); + + // force watchers to update + //project.stage.watchers().forEach(function (watcher) { + // watcher.onNextStep = function () {this.currentValue = null;}; + //}) + ide.world().keyboardReceiver = project.stage; }; -- cgit v1.3.1 From ebb4b9301055ba94f53328f18a2c26657c66972f Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 30 Apr 2014 12:30:19 +0200 Subject: integrate localisation changes --- byob.js | 7 +++++-- paint.js | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/byob.js b/byob.js index 5946fd5..9e0c067 100644 --- a/byob.js +++ b/byob.js @@ -106,7 +106,7 @@ SymbolMorph, isNil*/ // Global stuff //////////////////////////////////////////////////////// -modules.byob = '2014-January-10'; +modules.byob = '2014-April-30'; // Declarations @@ -2579,7 +2579,10 @@ InputSlotDialogMorph.prototype.symbolMenu = function () { myself = this; SymbolMorph.prototype.names.forEach(function (symbol) { symbols.push([ - [new SymbolMorph(symbol, myself.fontSize, symbolColor), localize(symbol)], + [ + new SymbolMorph(symbol, myself.fontSize, symbolColor), + localize(symbol) + ], '$' + symbol ]); }); diff --git a/paint.js b/paint.js index fd53122..44c988b 100644 --- a/paint.js +++ b/paint.js @@ -52,6 +52,7 @@ September 16 - flood fill freeze fix (Kartik) Jan 08 - mouse leave dragging fix (Kartik) Feb 11 - dynamically adjust to stage dimensions (Jens) + Apr 30 - localizations (Manuel) */ @@ -65,7 +66,7 @@ // Global stuff //////////////////////////////////////////////////////// -modules.paint = '2014-February-11'; +modules.paint = '2014-April-30'; // Declarations -- cgit v1.3.1 From 5ab8b7e56357fd38fbc9d43a03033cb569de4a1c Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 30 Apr 2014 12:52:54 +0200 Subject: checkpoint --- blocks.js | 2 +- history.txt | 5 +++++ threads.js | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/blocks.js b/blocks.js index f0ddd93..8e868f8 100644 --- a/blocks.js +++ b/blocks.js @@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/ // Global stuff //////////////////////////////////////////////////////// -modules.blocks = '2014-March-31'; +modules.blocks = '2014-April-30'; var SyntaxElementMorph; diff --git a/history.txt b/history.txt index 69b48bc..5fb2b40 100755 --- a/history.txt +++ b/history.txt @@ -2114,4 +2114,9 @@ ______ ------ * new Finnish translation, yay! Thanks, Jouni! * new Brazilian Portuguese translation, yay! Thanks, Aldo! +* Russian translation update +* Portuguese translation update +* additional localisations, thanks, Manuel! +* text-encoding fix for exporting variable contents, thanks, Blob! +* set turbo mode block fix, thanks, Michael and Nathan! * enable storage and retrieval of first-class costumes in both file formats diff --git a/threads.js b/threads.js index ca6bcd2..2d954a8 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-Feb-10'; +modules.threads = '2014-April-30'; var ThreadManager; var Process; -- cgit v1.3.1 From a469f44afcf2c9b30c93f96d197f8e9862829933 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 30 Apr 2014 14:41:51 +0200 Subject: partial fix for #407 the label still is wrong --- byob.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/byob.js b/byob.js index 9e0c067..e47f7c5 100644 --- a/byob.js +++ b/byob.js @@ -167,6 +167,9 @@ CustomBlockDefinition.prototype.templateInstance = function () { var block; block = this.blockInstance(); block.refreshDefaults(); + if (!block.zebraContrast) { + block.forceNormalColoring(); // label still is wrong + } block.isDraggable = false; block.isTemplate = true; return block; -- cgit v1.3.1 From 7edecf8255860cd2498bd8e9e72bec5e29992489 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 2 May 2014 08:40:17 +0200 Subject: integrate #394 --- history.txt | 4 ++++ objects.js | 27 +++++++++++++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/history.txt b/history.txt index 5fb2b40..bcf8e5c 100755 --- a/history.txt +++ b/history.txt @@ -2120,3 +2120,7 @@ ______ * text-encoding fix for exporting variable contents, thanks, Blob! * set turbo mode block fix, thanks, Michael and Nathan! * enable storage and retrieval of first-class costumes in both file formats + +140502 +------ +* error message when trying to import a non-text file into a variable, thanks, Nate! diff --git a/objects.js b/objects.js index 21d5156..d1e99ff 100644 --- a/objects.js +++ b/objects.js @@ -124,7 +124,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2014-April-30'; +modules.objects = '2014-May-02'; var SpriteMorph; var StageMorph; @@ -6450,7 +6450,17 @@ WatcherMorph.prototype.userMenu = function () { inp.addEventListener( "change", function () { - var file, i; + var file; + + function txtOnlyMsg(ftype) { + ide.inform( + 'Unable to import', + 'Snap! can only import "text" files.\n' + + 'You selected a file of type "' + + ftype + + '".' + ); + } function readText(aFile) { var frd = new FileReader(); @@ -6460,18 +6470,19 @@ WatcherMorph.prototype.userMenu = function () { e.target.result ); }; - frd.readAsText(aFile); + + if (aFile.type.indexOf("text") === 0) { + frd.readAsText(aFile); + } else { + txtOnlyMsg(aFile.type); + } } document.body.removeChild(inp); ide.filePicker = null; if (inp.files.length > 0) { file = inp.files[inp.files.length - 1]; - if (file.type.indexOf("text") === 0) { - readText(file); - } else { - ide.inform("Unable to import", "Snap! can only import \"text\" files.\n You selected a file of type \"" + file.type + "\"."); - } + readText(file); } }, false -- cgit v1.3.1 From f6561867d24f18b5ae803385f1475fce973fd548 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 2 May 2014 10:55:03 +0200 Subject: fixed #407 (custom-block coloring w/ zebra off) --- byob.js | 11 ++++++----- history.txt | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/byob.js b/byob.js index e47f7c5..6a10110 100644 --- a/byob.js +++ b/byob.js @@ -106,7 +106,7 @@ SymbolMorph, isNil*/ // Global stuff //////////////////////////////////////////////////////// -modules.byob = '2014-April-30'; +modules.byob = '2014-May-02'; // Declarations @@ -167,9 +167,6 @@ CustomBlockDefinition.prototype.templateInstance = function () { var block; block = this.blockInstance(); block.refreshDefaults(); - if (!block.zebraContrast) { - block.forceNormalColoring(); // label still is wrong - } block.isDraggable = false; block.isTemplate = true; return block; @@ -375,8 +372,12 @@ CustomCommandBlockMorph.prototype.refresh = function () { this.setCategory(def.category); if (this.blockSpec !== newSpec) { oldInputs = this.inputs(); + if (!this.zebraContrast) { + this.forceNormalColoring(); + } else { + this.fixBlockColor(); + } this.setSpec(newSpec); - this.fixBlockColor(); this.fixLabelColor(); this.restoreInputs(oldInputs); } else { // update all input slots' drop-downs diff --git a/history.txt b/history.txt index bcf8e5c..af54766 100755 --- a/history.txt +++ b/history.txt @@ -2124,3 +2124,4 @@ ______ 140502 ------ * error message when trying to import a non-text file into a variable, thanks, Nate! +* fixed #407 (custom-block coloring w/ zebra off) -- cgit v1.3.1 From f9989ad7cfa5e27b4784d8cd464fdc7cbe289942 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 2 May 2014 11:08:30 +0200 Subject: checkpoint - release --- blocks.js | 2 +- lang-ru.js | 3 ++- locale.js | 2 +- paint.js | 2 +- store.js | 2 +- threads.js | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/blocks.js b/blocks.js index 8e868f8..69ae610 100644 --- a/blocks.js +++ b/blocks.js @@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/ // Global stuff //////////////////////////////////////////////////////// -modules.blocks = '2014-April-30'; +modules.blocks = '2014-May-02'; var SyntaxElementMorph; diff --git a/lang-ru.js b/lang-ru.js index 4834f7c..f113f2c 100644 --- a/lang-ru.js +++ b/lang-ru.js @@ -168,7 +168,8 @@ SnapTranslator.dict.ru = { Special characters: (see ) €, Š \u00c4, \u00e4 -…, š \u00d6, \u00f6 + +, š \u00d6, \u00f6 †, Ÿ \u00dc, \u00fc § \u00df */ diff --git a/locale.js b/locale.js index c6924e9..d981960 100644 --- a/locale.js +++ b/locale.js @@ -42,7 +42,7 @@ /*global modules, contains*/ -modules.locale = '2014-April-30'; +modules.locale = '2014-May-02'; // Global stuff diff --git a/paint.js b/paint.js index 44c988b..ee40b23 100644 --- a/paint.js +++ b/paint.js @@ -66,7 +66,7 @@ // Global stuff //////////////////////////////////////////////////////// -modules.paint = '2014-April-30'; +modules.paint = '2014-May-02'; // Declarations diff --git a/store.js b/store.js index d69667a..e143245 100644 --- a/store.js +++ b/store.js @@ -61,7 +61,7 @@ SyntaxElementMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.store = '2014-April-30'; +modules.store = '2014-May-02'; // XML_Serializer /////////////////////////////////////////////////////// diff --git a/threads.js b/threads.js index 2d954a8..b82a8c5 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-April-30'; +modules.threads = '2014-May-02'; var ThreadManager; var Process; -- cgit v1.3.1 From a53c189e4b379a262bc424be263c19290be18e6d Mon Sep 17 00:00:00 2001 From: jmoenig Date: Tue, 20 May 2014 09:26:44 +0200 Subject: Morphic: Prevent default action for ctrl-/cmd-key events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … and allow using these for Snap! without having Chrome trigger its own actions for them --- history.txt | 4 ++++ morphic.js | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index af54766..faf992d 100755 --- a/history.txt +++ b/history.txt @@ -2125,3 +2125,7 @@ ______ ------ * error message when trying to import a non-text file into a variable, thanks, Nate! * fixed #407 (custom-block coloring w/ zebra off) + +140520 +------ +* Morphic: Prevent default action for ctrl-/cmd-key events diff --git a/morphic.js b/morphic.js index b55b180..48e29bb 100644 --- a/morphic.js +++ b/morphic.js @@ -1035,7 +1035,7 @@ /*global window, HTMLCanvasElement, getMinimumFontHeight, FileReader, Audio, FileList, getBlurredShadowSupport*/ -var morphicVersion = '2014-February-03'; +var morphicVersion = '2014-April-20'; var modules = {}; // keep track of additional loaded modules var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug @@ -10268,6 +10268,9 @@ WorldMorph.prototype.initEventListeners = function () { } event.preventDefault(); } + if (event.ctrlKey || event.metaKey) { + event.preventDefault(); + } }, false ); -- cgit v1.3.1 From 669d93a62967d88b4c4dd33b919737a386bf958a Mon Sep 17 00:00:00 2001 From: jmoenig Date: Tue, 20 May 2014 09:29:19 +0200 Subject: Snap.html: Focus the world canvas on startup so Snap reacts to keyboard events right away (without having to click on the IDE first) --- history.txt | 3 ++- snap.html | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index faf992d..960daf1 100755 --- a/history.txt +++ b/history.txt @@ -2128,4 +2128,5 @@ ______ 140520 ------ -* Morphic: Prevent default action for ctrl-/cmd-key events +* Morphic: Prevent default action for ctrl-/cmd-key event +* Snap.html: Focus the world canvas on startup, so Snap reacts to keyboard events right away diff --git a/snap.html b/snap.html index 66604c5..904aba8 100755 --- a/snap.html +++ b/snap.html @@ -22,6 +22,7 @@ var world; window.onload = function () { world = new WorldMorph(document.getElementById('world')); + world.worldCanvas.focus(); new IDE_Morph().openIn(world); setInterval(loop, 1); }; -- cgit v1.3.1 From 295de115a387d24ded700146203c07ba7c522d16 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Tue, 20 May 2014 09:34:37 +0200 Subject: Threads: new Variable data structure for refactoring upvar references, not yet used anywhere --- history.txt | 1 + threads.js | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index 960daf1..c49f5f8 100755 --- a/history.txt +++ b/history.txt @@ -2130,3 +2130,4 @@ ______ ------ * Morphic: Prevent default action for ctrl-/cmd-key event * Snap.html: Focus the world canvas on startup, so Snap reacts to keyboard events right away +* Threads: new Variable data structure, for refactoring upvar references, not yet used anywhere diff --git a/threads.js b/threads.js index b82a8c5..21147a3 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-May-02'; +modules.threads = '2014-May-20'; var ThreadManager; var Process; @@ -3110,6 +3110,20 @@ VariableFrame.prototype.allNames = function () { return answer; }; +// Variable ///////////////////////////////////////////////////////////////// + +function Variable(value) { + this.value = value; +} + +Variable.prototype.toString = function () { + return 'a Variable [' + this.value + ']'; +}; + +Variable.prototype.copy = function () { + return new Variable(this.value); +}; + // UpvarReference /////////////////////////////////////////////////////////// // ... quasi-inherits some features from VariableFrame -- cgit v1.3.1 From a1b9d3e3964fd363cdb169c9de9287b54e736637 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Tue, 20 May 2014 09:43:31 +0200 Subject: Search Blocks feature, keyboard shortcuts Thanks, Kyle, for designing and architecting the search blocks feature!! --- gui.js | 49 +++++++++------ history.txt | 2 + objects.js | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 232 insertions(+), 21 deletions(-) diff --git a/gui.js b/gui.js index 0f4f2eb..4de6b3d 100644 --- a/gui.js +++ b/gui.js @@ -68,7 +68,7 @@ sb, CommentMorph, CommandBlockMorph, BlockLabelPlaceHolderMorph, Audio*/ // Global stuff //////////////////////////////////////////////////////// -modules.gui = '2014-February-13'; +modules.gui = '2014-May-20'; // Declarations @@ -848,7 +848,7 @@ IDE_Morph.prototype.createCategories = function () { this.add(this.categories); }; -IDE_Morph.prototype.createPalette = function () { +IDE_Morph.prototype.createPalette = function (forSearching) { // assumes that the logo pane has already been created // needs the categories pane for layout var myself = this; @@ -857,7 +857,15 @@ IDE_Morph.prototype.createPalette = function () { this.palette.destroy(); } - this.palette = this.currentSprite.palette(this.currentCategory); + if (forSearching) { + this.palette = new ScrollFrameMorph( + null, + null, + this.currentSprite.sliderColor + ); + } else { + this.palette = this.currentSprite.palette(this.currentCategory); + } this.palette.isDraggable = false; this.palette.acceptsDrops = true; this.palette.contents.acceptsDrops = false; @@ -882,6 +890,7 @@ IDE_Morph.prototype.createPalette = function () { this.add(this.palette); this.palette.scrollX(this.palette.padding); this.palette.scrollY(this.palette.padding); + return this.palette; }; IDE_Morph.prototype.createStage = function () { @@ -2273,23 +2282,7 @@ IDE_Morph.prototype.projectMenu = function () { } ); menu.addItem('Open...', 'openProjectsBrowser'); - menu.addItem( - 'Save', - function () { - if (myself.source === 'examples') { - myself.source = 'local'; // cannot save to examples - } - if (myself.projectName) { - if (myself.source === 'local') { // as well as 'examples' - myself.saveProject(myself.projectName); - } else { // 'cloud' - myself.saveProjectToCloud(myself.projectName); - } - } else { - myself.saveProjectsBrowser(); - } - } - ); + menu.addItem('Save', "save"); if (shiftClicked) { menu.addItem( 'Save to disk', @@ -2720,6 +2713,22 @@ IDE_Morph.prototype.newProject = function () { this.fixLayout(); }; +IDE_Morph.prototype.save = function () { + if (this.source === 'examples') { + this.source = 'local'; // cannot save to examples + } + if (this.projectName) { + if (this.source === 'local') { // as well as 'examples' + this.saveProject(this.projectName); + } else { // 'cloud' + this.saveProjectToCloud(this.projectName); + } + } else { + this.saveProjectsBrowser(); + } +}; + + IDE_Morph.prototype.saveProject = function (name) { var myself = this; this.nextSteps([ diff --git a/history.txt b/history.txt index c49f5f8..126c11c 100755 --- a/history.txt +++ b/history.txt @@ -2131,3 +2131,5 @@ ______ * Morphic: Prevent default action for ctrl-/cmd-key event * Snap.html: Focus the world canvas on startup, so Snap reacts to keyboard events right away * Threads: new Variable data structure, for refactoring upvar references, not yet used anywhere +* Objects, GUI: Search Blocks, feature. Thanks, Kyle, for architecting and designing this!!! +* Objects, GUI: Keyboard-shortcuts for opening (cmd-o), saving (cmd-s) projects and for finding blocks (cmd-f) diff --git a/objects.js b/objects.js index d1e99ff..66ceb97 100644 --- a/objects.js +++ b/objects.js @@ -124,7 +124,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2014-May-02'; +modules.objects = '2014-May-20'; var SpriteMorph; var StageMorph; @@ -203,90 +203,106 @@ SpriteMorph.prototype.initBlocks = function () { // Motion forward: { + only: SpriteMorph, type: 'command', category: 'motion', spec: 'move %n steps', defaults: [10] }, turn: { + only: SpriteMorph, type: 'command', category: 'motion', spec: 'turn %clockwise %n degrees', defaults: [15] }, turnLeft: { + only: SpriteMorph, type: 'command', category: 'motion', spec: 'turn %counterclockwise %n degrees', defaults: [15] }, setHeading: { + only: SpriteMorph, type: 'command', category: 'motion', spec: 'point in direction %dir' }, doFaceTowards: { + only: SpriteMorph, type: 'command', category: 'motion', spec: 'point towards %dst' }, gotoXY: { + only: SpriteMorph, type: 'command', category: 'motion', spec: 'go to x: %n y: %n', defaults: [0, 0] }, doGotoObject: { + only: SpriteMorph, type: 'command', category: 'motion', spec: 'go to %dst' }, doGlide: { + only: SpriteMorph, type: 'command', category: 'motion', spec: 'glide %n secs to x: %n y: %n', defaults: [1, 0, 0] }, changeXPosition: { + only: SpriteMorph, type: 'command', category: 'motion', spec: 'change x by %n', defaults: [10] }, setXPosition: { + only: SpriteMorph, type: 'command', category: 'motion', spec: 'set x to %n', defaults: [0] }, changeYPosition: { + only: SpriteMorph, type: 'command', category: 'motion', spec: 'change y by %n', defaults: [10] }, setYPosition: { + only: SpriteMorph, type: 'command', category: 'motion', spec: 'set y to %n', defaults: [0] }, bounceOffEdge: { + only: SpriteMorph, type: 'command', category: 'motion', spec: 'if on edge, bounce' }, xPosition: { + only: SpriteMorph, type: 'reporter', category: 'motion', spec: 'x position' }, yPosition: { + only: SpriteMorph, type: 'reporter', category: 'motion', spec: 'y position' }, direction: { + only: SpriteMorph, type: 'reporter', category: 'motion', spec: 'direction' @@ -309,24 +325,28 @@ SpriteMorph.prototype.initBlocks = function () { spec: 'costume #' }, doSayFor: { + only: SpriteMorph, type: 'command', category: 'looks', spec: 'say %s for %n secs', defaults: [localize('Hello!'), 2] }, bubble: { + only: SpriteMorph, type: 'command', category: 'looks', spec: 'say %s', defaults: [localize('Hello!')] }, doThinkFor: { + only: SpriteMorph, type: 'command', category: 'looks', spec: 'think %s for %n secs', defaults: [localize('Hmm...'), 2] }, doThink: { + only: SpriteMorph, type: 'command', category: 'looks', spec: 'think %s', @@ -350,38 +370,45 @@ SpriteMorph.prototype.initBlocks = function () { spec: 'clear graphic effects' }, changeScale: { + only: SpriteMorph, type: 'command', category: 'looks', spec: 'change size by %n', defaults: [10] }, setScale: { + only: SpriteMorph, type: 'command', category: 'looks', spec: 'set size to %n %', defaults: [100] }, getScale: { + only: SpriteMorph, type: 'reporter', category: 'looks', spec: 'size' }, show: { + only: SpriteMorph, type: 'command', category: 'looks', spec: 'show' }, hide: { + only: SpriteMorph, type: 'command', category: 'looks', spec: 'hide' }, comeToFront: { + only: SpriteMorph, type: 'command', category: 'looks', spec: 'go to front' }, goBack: { + only: SpriteMorph, type: 'command', category: 'looks', spec: 'go back %n layers', @@ -390,17 +417,20 @@ SpriteMorph.prototype.initBlocks = function () { // Looks - Debugging primitives for development mode reportCostumes: { + dev: true, type: 'reporter', category: 'looks', spec: 'wardrobe' }, alert: { + dev: true, type: 'command', category: 'looks', spec: 'alert %mult%s' }, log: { + dev: true, type: 'command', category: 'looks', spec: 'console log %mult%s' @@ -454,6 +484,7 @@ SpriteMorph.prototype.initBlocks = function () { // Sound - Debugging primitives for development mode reportSounds: { + dev: true, type: 'reporter', category: 'sound', spec: 'jukebox' @@ -466,57 +497,67 @@ SpriteMorph.prototype.initBlocks = function () { spec: 'clear' }, down: { + only: SpriteMorph, type: 'command', category: 'pen', spec: 'pen down' }, up: { + only: SpriteMorph, type: 'command', category: 'pen', spec: 'pen up' }, setColor: { + only: SpriteMorph, type: 'command', category: 'pen', spec: 'set pen color to %clr' }, changeHue: { + only: SpriteMorph, type: 'command', category: 'pen', spec: 'change pen color by %n', defaults: [10] }, setHue: { + only: SpriteMorph, type: 'command', category: 'pen', spec: 'set pen color to %n', defaults: [0] }, changeBrightness: { + only: SpriteMorph, type: 'command', category: 'pen', spec: 'change pen shade by %n', defaults: [10] }, setBrightness: { + only: SpriteMorph, type: 'command', category: 'pen', spec: 'set pen shade to %n', defaults: [100] }, changeSize: { + only: SpriteMorph, type: 'command', category: 'pen', spec: 'change pen size by %n', defaults: [1] }, setSize: { + only: SpriteMorph, type: 'command', category: 'pen', spec: 'set pen size to %n', defaults: [1] }, doStamp: { + only: SpriteMorph, type: 'command', category: 'pen', spec: 'stamp' @@ -710,31 +751,37 @@ SpriteMorph.prototype.initBlocks = function () { // Sensing reportTouchingObject: { + only: SpriteMorph, type: 'predicate', category: 'sensing', spec: 'touching %col ?' }, reportTouchingColor: { + only: SpriteMorph, type: 'predicate', category: 'sensing', spec: 'touching %clr ?' }, reportColorIsTouchingColor: { + only: SpriteMorph, type: 'predicate', category: 'sensing', spec: 'color %clr is touching %clr ?' }, colorFiltered: { + dev: true, type: 'reporter', category: 'sensing', spec: 'filtered for %clr' }, reportStackSize: { + dev: true, type: 'reporter', category: 'sensing', spec: 'stack size' }, reportFrameCount: { + dev: true, type: 'reporter', category: 'sensing', spec: 'frames' @@ -746,6 +793,7 @@ SpriteMorph.prototype.initBlocks = function () { defaults: [localize('what\'s your name?')] }, reportLastAnswer: { // retained for legacy compatibility + dev: true, type: 'reporter', category: 'sensing', spec: 'answer' @@ -786,6 +834,7 @@ SpriteMorph.prototype.initBlocks = function () { spec: 'reset timer' }, reportTimer: { // retained for legacy compatibility + dev: true, type: 'reporter', category: 'sensing', spec: 'timer' @@ -969,12 +1018,14 @@ SpriteMorph.prototype.initBlocks = function () { defaults: [localize('hello') + ' ' + localize('world'), " "] }, reportTypeOf: { // only in dev mode for debugging + dev: true, type: 'reporter', category: 'operators', spec: 'type of %s', defaults: [5] }, reportTextFunction: { // only in dev mode - experimental + dev: true, type: 'reporter', category: 'operators', spec: '%txtfun of %s', @@ -1083,6 +1134,7 @@ SpriteMorph.prototype.initBlocks = function () { // MAP - experimental reportMap: { + dev: true, type: 'reporter', category: 'lists', spec: 'map %repRing over %l' @@ -2068,6 +2120,7 @@ SpriteMorph.prototype.freshPalette = function (category) { }); } + menu.addItem('find blocks...', function () {myself.searchBlocks(); }); if (canHidePrimitives()) { menu.addItem( 'hide primitives', @@ -2199,6 +2252,139 @@ SpriteMorph.prototype.freshPalette = function (category) { return palette; }; +// SpriteMorph blocks searching + +SpriteMorph.prototype.blocksMatching = function (searchString, strictly) { + // answer an array of block templates whose spec contains + // the given search string, ordered by descending relevance + var blocks = [], + blocksDict, + myself = this, + search = searchString.toLowerCase(), + stage = this.parentThatIsA(StageMorph); + + function labelOf(aBlockSpec) { + var words = (BlockMorph.prototype.parseSpec(aBlockSpec)), + filtered = words.filter( + function (each) {return (each.indexOf('%') !== 0); } + ); + return filtered.join(' '); + } + + function fillDigits(anInt, totalDigits, fillChar) { + var ans = String(anInt); + while (ans.length < totalDigits) {ans = fillChar + ans; } + return ans; + } + + function relevance(aBlockLabel, aSearchString) { + var lbl = ' ' + aBlockLabel, + idx = lbl.indexOf(aSearchString), + atWord; + if (idx === -1) {return -1; } + atWord = (lbl.charAt(idx - 1) === ' '); + if (strictly && !atWord) {return -1; } + return (atWord ? '1' : '2') + fillDigits(idx, 4, '0'); + } + + function primitive(selector) { + var newBlock = SpriteMorph.prototype.blockForSelector(selector, true); + newBlock.isTemplate = true; + return newBlock; + } + + // custom blocks + [this.customBlocks, stage.globalBlocks].forEach(function (blocksList) { + blocksList.forEach(function (definition) { + var spec = localize(definition.blockSpec()).toLowerCase(), + rel = relevance(labelOf(spec), search); + if (rel !== -1) { + blocks.push([definition.templateInstance(), rel + '1']); + } + }); + }); + // primitives + blocksDict = SpriteMorph.prototype.blocks; + Object.keys(blocksDict).forEach(function (selector) { + if (!StageMorph.prototype.hiddenPrimitives[selector]) { + var block = blocksDict[selector], + spec = localize(block.spec).toLowerCase(), + rel = relevance(labelOf(spec), search); + if ( + (rel !== -1) && + (!block.dev) && + (!block.only || (block.only === myself.constructor)) + ) { + blocks.push([primitive(selector), rel + '2']); + } + } + }); + blocks.sort(function (x, y) {return x[1] < y[1] ? -1 : 1; }); + return blocks.map(function (each) {return each[0]; }); +}; + +SpriteMorph.prototype.searchBlocks = function () { + var myself = this, + unit = SyntaxElementMorph.prototype.fontSize, + ide = this.parentThatIsA(IDE_Morph), + oldSearch = '', + searchBar = new InputFieldMorph(''), + searchPane = ide.createPalette('forSearch'); + + function show(blocks) { + var oldFlag = Morph.prototype.trackChanges, + x = searchPane.contents.left() + 5, + y = (searchBar.bottom() + unit); + Morph.prototype.trackChanges = false; + searchPane.contents.children = [searchPane.contents.children[0]]; + blocks.forEach(function (block) { + block.setPosition(new Point(x, y)); + searchPane.addContents(block); + y += block.height(); + y += unit * 0.3; + }); + Morph.prototype.trackChanges = oldFlag; + searchPane.changed(); + } + + searchPane.owner = this; + searchPane.padding = unit / 2; + searchPane.color = myself.paletteColor; + searchPane.contents.color = myself.paletteColor; + searchPane.growth = new Point(0, MorphicPreferences.scrollBarSize); + searchPane.addContents(searchBar); + searchBar.drawNew(); + searchBar.setWidth(ide.logo.width() - 20); + searchBar.contrast = 90; + searchBar.setPosition( + searchPane.contents.topLeft().add(new Point(10, 10)) + ); + searchBar.drawNew(); + + searchPane.accept = function () { + var search = searchBar.getValue(); + if (search.length > 0) { + show(myself.blocksMatching(search)); + } + }; + + searchPane.reactToKeystroke = function () { + var search = searchBar.getValue(); + if (search !== oldSearch) { + oldSearch = search; + show(myself.blocksMatching(search, search.length < 2)); + } + }; + + searchBar.cancel = function () { + ide.refreshPalette(); + ide.palette.adjustScrollBars(); + }; + + ide.fixLayout('refreshPalette'); + searchBar.edit(); +}; + // SpriteMorph variable management SpriteMorph.prototype.addVariable = function (name, isGlobal) { @@ -4210,6 +4396,9 @@ StageMorph.prototype.processKeyEvent = function (event, action) { break; default: keyName = String.fromCharCode(event.keyCode || event.charCode); + if (event.ctrlKey || event.metaKey) { + keyName = 'ctrl ' + keyName; + } } action.call(this, keyName); }; @@ -4224,6 +4413,15 @@ StageMorph.prototype.fireKeyEvent = function (key) { if (evt === 'ctrl enter') { return this.fireGreenFlagEvent(); } + if (evt === 'ctrl f') { + return this.parentThatIsA(IDE_Morph).currentSprite.searchBlocks(); + } + if (evt === 'ctrl o') { + return this.parentThatIsA(IDE_Morph).openProjectsBrowser(); + } + if (evt === 'ctrl s') { + return this.parentThatIsA(IDE_Morph).save(); + } if (evt === 'esc') { return this.fireStopAllEvent(); } @@ -4847,6 +5045,8 @@ StageMorph.prototype.paletteColor = SpriteMorph.prototype.paletteColor; StageMorph.prototype.setName = SpriteMorph.prototype.setName; StageMorph.prototype.palette = SpriteMorph.prototype.palette; StageMorph.prototype.freshPalette = SpriteMorph.prototype.freshPalette; +StageMorph.prototype.blocksMatching = SpriteMorph.prototype.blocksMatching; +StageMorph.prototype.searchBlocks = SpriteMorph.prototype.searchBlocks; StageMorph.prototype.showingWatcher = SpriteMorph.prototype.showingWatcher; StageMorph.prototype.addVariable = SpriteMorph.prototype.addVariable; StageMorph.prototype.deleteVariable = SpriteMorph.prototype.deleteVariable; -- cgit v1.3.1 From 089d1500b41f00611603de936a65093d0dbb15ec Mon Sep 17 00:00:00 2001 From: jmoenig Date: Tue, 20 May 2014 10:55:14 +0200 Subject: prepare release correct last-changed-date --- morphic.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/morphic.js b/morphic.js index 48e29bb..7d1f53d 100644 --- a/morphic.js +++ b/morphic.js @@ -1035,7 +1035,7 @@ /*global window, HTMLCanvasElement, getMinimumFontHeight, FileReader, Audio, FileList, getBlurredShadowSupport*/ -var morphicVersion = '2014-April-20'; +var morphicVersion = '2014-May-20'; var modules = {}; // keep track of additional loaded modules var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug -- cgit v1.3.1 From 6926f7085bb2d1e3df02a6eb0547e40c5d47ef3f Mon Sep 17 00:00:00 2001 From: Manuel Menezes de Sequeira Date: Tue, 20 May 2014 13:23:24 +0100 Subject: Add localization to connection error message. --- cloud.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cloud.js b/cloud.js index 17fc76b..0dd7780 100644 --- a/cloud.js +++ b/cloud.js @@ -107,7 +107,7 @@ Cloud.prototype.signup = function ( errorCall.call( null, myself.url + 'SignUp', - 'could not connect to:' + localize('could not connect to:') ); } } @@ -164,7 +164,7 @@ Cloud.prototype.getPublicProject = function ( errorCall.call( null, myself.url + 'Public', - 'could not connect to:' + localize('could not connect to:') ); } } @@ -217,7 +217,7 @@ Cloud.prototype.resetPassword = function ( errorCall.call( null, myself.url + 'ResetPW', - 'could not connect to:' + localize('could not connect to:') ); } } @@ -264,7 +264,7 @@ Cloud.prototype.connect = function ( errorCall.call( null, myself.url, - 'could not connect to:' + localize('could not connect to:') ); } } @@ -533,7 +533,7 @@ Cloud.prototype.callService = function ( errorCall.call( this, request.responseText, - 'Service: ' + serviceName + localize('Service:') + ' ' + localize(serviceName) ); return; } -- cgit v1.3.1 From 43bfc95c1bda3912263475c4e49e9b4a4591c6de Mon Sep 17 00:00:00 2001 From: Manuel Menezes de Sequeira Date: Tue, 20 May 2014 13:26:08 +0100 Subject: Add new Portuguese localizations for stage size, flat line ends, dates sensor block, and Snap\!Cloud stuff. --- lang-pt.js | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/lang-pt.js b/lang-pt.js index c5e33b0..ffc8bf1 100755 --- a/lang-pt.js +++ b/lang-pt.js @@ -685,6 +685,16 @@ SnapTranslator.dict.pt = { 'Língua…', 'Zoom blocks...': 'Ampliação dos blocos…', + 'Stage size...': + 'Tamanho do palco…', + 'Stage size': + 'Tamanho do palco', + 'Stage width': + 'Largura do palco', + 'Stage height': + 'Altura do palco', + 'Default': + 'Normal', 'Blurred shadows': 'Sombras desfocadas', 'uncheck to use solid drop\nshadows and highlights': @@ -767,6 +777,12 @@ SnapTranslator.dict.pt = { 'Desassinalar para aumentar a velocidade\npermitindo ritmos variáveis das tramas.', 'check for smooth, predictable\nanimations across computers': 'Assinalar para obter animações mais suaves\ne previsíveis de computador para computador.', + 'Flat line ends': + 'Extremos das linhas planos', + 'check for flat ends of lines': + 'Assinalar para que os extremos das linhas\ndesenhadas pela caneta sejam planos.', + 'uncheck for round ends of lines': + 'Desassinalar para que os extremos das linhas\ndesenhadas pela caneta sejam redondos.', // entradas 'with inputs': @@ -1254,20 +1270,62 @@ SnapTranslator.dict.pt = { 'um item ao acaso', // em falta no ficheiro lang-de.js + 'current %dates': + '%dates corrente', + 'year': + 'ano', + 'month': + 'mês', + 'date': + 'dia', + 'day of week': + 'dia da semana', + 'hour': + 'hora', + 'minute': + 'minuto', + 'second': + 'segundo', + 'time in milliseconds': + 'tempo (em milisegundos)', + 'find blocks...': + 'procurar blocos…', 'costume name': 'o nome do traje', 'Open': 'Abrir', 'Share': 'Partilhar', + 'Snap!Cloud': + 'Snap!Nuvem', 'Cloud': 'Nuvem', + 'could not connect to:': + 'Não foi possível ligar a:', + 'Service:': + 'Serviço:', + 'login': + 'autenticação', + 'ERROR: INVALID PASSWORD': + 'ERRO: PALAVRA-PASSE INVÁLIDA', 'Browser': 'Navegador', 'Sign up': 'Registar nova conta', + 'Signup': + 'Registo de nova conta', 'Sign in': 'Entrar', + 'Logout': + 'Sair', + 'Change Password...': + 'Alterar palavra-passe…', + 'Change Password': + 'Alterar palavra-passe', + 'Account created.': + 'Conta criada.', + 'An e-mail with your password\nhas been sent to the address provided': + 'Foi enviada uma mensagem para\no endereço disponibilizado\ncontendo a sua palavra-passe.', 'now connected.': 'entrou.', 'disconnected.': @@ -1280,6 +1338,12 @@ SnapTranslator.dict.pt = { 'Nome de utilizador:', 'Password:': 'Palavra-passe:', + 'Old password:': + 'Palavra-passe actual:', + 'New password:': + 'Nova palavra-passe:', + 'Repeat new password:': + 'Repita a nova palavra-passe:', 'Birth date:': 'Data de nascimento:', 'January': -- cgit v1.3.1 From 8125861f8062727cc7a3abb2e3a140279a10b862 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 26 May 2014 09:40:55 +0200 Subject: Fixed #445 (minor search + zoom issues) --- history.txt | 4 ++++ objects.js | 6 ++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/history.txt b/history.txt index 126c11c..ecfdff4 100755 --- a/history.txt +++ b/history.txt @@ -2133,3 +2133,7 @@ ______ * Threads: new Variable data structure, for refactoring upvar references, not yet used anywhere * Objects, GUI: Search Blocks, feature. Thanks, Kyle, for architecting and designing this!!! * Objects, GUI: Keyboard-shortcuts for opening (cmd-o), saving (cmd-s) projects and for finding blocks (cmd-f) + +140526 +------ +* Objects: Fixed #445 (minor search + zoom issues) diff --git a/objects.js b/objects.js index 66ceb97..5f91606 100644 --- a/objects.js +++ b/objects.js @@ -124,7 +124,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2014-May-20'; +modules.objects = '2014-May-26'; var SpriteMorph; var StageMorph; @@ -2348,13 +2348,11 @@ SpriteMorph.prototype.searchBlocks = function () { } searchPane.owner = this; - searchPane.padding = unit / 2; searchPane.color = myself.paletteColor; searchPane.contents.color = myself.paletteColor; - searchPane.growth = new Point(0, MorphicPreferences.scrollBarSize); searchPane.addContents(searchBar); searchBar.drawNew(); - searchBar.setWidth(ide.logo.width() - 20); + searchBar.setWidth(ide.logo.width() - 30); searchBar.contrast = 90; searchBar.setPosition( searchPane.contents.topLeft().add(new Point(10, 10)) -- cgit v1.3.1 From 24f7a37a56e4c44d6dd339f227507871867f1436 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 26 May 2014 09:57:21 +0200 Subject: Localization additions and Portuguese translation update, thanks, Manuel! --- cloud.js | 5 +++-- history.txt | 1 + lang-pt.js | 2 +- locale.js | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cloud.js b/cloud.js index 0dd7780..54189d8 100644 --- a/cloud.js +++ b/cloud.js @@ -27,9 +27,10 @@ // Global settings ///////////////////////////////////////////////////// -/*global modules, IDE_Morph, SnapSerializer, hex_sha512, alert, nop*/ +/*global modules, IDE_Morph, SnapSerializer, hex_sha512, alert, nop, +localize*/ -modules.cloud = '2014-January-09'; +modules.cloud = '2014-May-26'; // Global stuff diff --git a/history.txt b/history.txt index ecfdff4..8155285 100755 --- a/history.txt +++ b/history.txt @@ -2137,3 +2137,4 @@ ______ 140526 ------ * Objects: Fixed #445 (minor search + zoom issues) +* Localization additions and Portuguese translation update, thanks, Manuel! diff --git a/lang-pt.js b/lang-pt.js index ffc8bf1..226abf5 100755 --- a/lang-pt.js +++ b/lang-pt.js @@ -185,7 +185,7 @@ SnapTranslator.dict.pt = { 'translator_e-mail': 'mmsequeira@gmail.com', 'last_changed': - '2014-01-12', + '2014-05-26', // GUI // control bar: diff --git a/locale.js b/locale.js index d981960..c10aa64 100644 --- a/locale.js +++ b/locale.js @@ -42,7 +42,7 @@ /*global modules, contains*/ -modules.locale = '2014-May-02'; +modules.locale = '2014-May-26'; // Global stuff @@ -209,7 +209,7 @@ SnapTranslator.dict.pt = { 'translator_e-mail': 'mmsequeira@gmail.com', 'last_changed': - '2014-01-12' + '2014-05-26' }; SnapTranslator.dict.cs = { -- cgit v1.3.1 From 6a4b4afbe98fa99623a81a89e2f6505ff5704d38 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Mon, 26 May 2014 10:46:00 +0200 Subject: Show last-changed-timestamp of cloud projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit display a tool-tip “bubble” in the “Open-Project” dialog next to the preview field --- gui.js | 16 ++++++++++++++-- history.txt | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/gui.js b/gui.js index 4de6b3d..981696a 100644 --- a/gui.js +++ b/gui.js @@ -64,11 +64,12 @@ standardSettings, Sound, BlockMorph, ToggleMorph, InputSlotDialogMorph, ScriptsMorph, isNil, SymbolMorph, BlockExportDialogMorph, BlockImportDialogMorph, SnapTranslator, localize, List, InputSlotMorph, SnapCloud, Uint8Array, HandleMorph, SVG_Costume, fontHeight, hex_sha512, -sb, CommentMorph, CommandBlockMorph, BlockLabelPlaceHolderMorph, Audio*/ +sb, CommentMorph, CommandBlockMorph, BlockLabelPlaceHolderMorph, Audio, +SpeechBubbleMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.gui = '2014-May-20'; +modules.gui = '2014-May-26'; // Declarations @@ -4533,6 +4534,17 @@ ProjectDialogMorph.prototype.installCloudProjectList = function (pl) { myself.preview.texture = item.Thumbnail || null; myself.preview.cachedTexture = null; myself.preview.drawNew(); + (new SpeechBubbleMorph(new TextMorph( + localize('last changed') + '\n' + item.Updated, + null, + null, + null, + null, + 'center' + ))).popUp( + myself.world(), + myself.preview.rightCenter().add(new Point(2, 0)) + ); } if (item.Public === 'true') { myself.shareButton.hide(); diff --git a/history.txt b/history.txt index 8155285..bd4d9fe 100755 --- a/history.txt +++ b/history.txt @@ -2138,3 +2138,4 @@ ______ ------ * Objects: Fixed #445 (minor search + zoom issues) * Localization additions and Portuguese translation update, thanks, Manuel! +* GUI, cloud: Show last-changed-timestamp when opening cloud projects -- cgit v1.3.1 From e1b97b98df9219865d08566bb10309603a9b12fe Mon Sep 17 00:00:00 2001 From: yuan Date: Tue, 27 May 2014 00:57:19 -0700 Subject: added graphics effects that work for all redraws; incorporated most recent updates to Snap! --- blocks.js | 16 +++----- objects.js | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 138 insertions(+), 14 deletions(-) diff --git a/blocks.js b/blocks.js index 69ae610..da5e929 100644 --- a/blocks.js +++ b/blocks.js @@ -913,16 +913,12 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { part = new InputSlotMorph( null, false, - { - /* - color : 'color', - fisheye : 'fisheye', - whirl : 'whirl', - pixelate : 'pixelate', - mosaic : 'mosaic', - brightness : 'brightness', - */ - ghost : ['ghost'] + { brightness : ['brightness'], + ghost : ['ghost'], + negative : ['negative'], + comic: ['comic'], + duplicate: ['duplicate'], + confetti: ['confetti'], }, true ); diff --git a/objects.js b/objects.js index 5f91606..b1e2892 100644 --- a/objects.js +++ b/objects.js @@ -1297,6 +1297,19 @@ SpriteMorph.prototype.init = function (globals) { this.isDraggable = true; this.isDown = false; + this.graphicsValues = { 'color': 0, //dictionary of all the orignal values + 'fisheye': 0, + 'whirl': 0, + 'pixelate': 0, + 'mosaic': 0, + 'brightness': 0, + 'negative': 0, + 'comic': 0, + 'duplicate': 0, + 'confetti': 0 + }; + this.graphicsChanged = false; + this.heading = 90; this.changed(); this.drawNew(); @@ -1421,6 +1434,9 @@ SpriteMorph.prototype.drawNew = function () { ctx.rotate(radians(facing - 90)); ctx.drawImage(pic.contents, 0, 0); + // apply graphics effects to image + this.image = this.applyGraphicsEffects(this.image); + // adjust my position to the rotation this.setCenter(currentCenter, true); // just me @@ -1443,6 +1459,7 @@ SpriteMorph.prototype.drawNew = function () { this.setCenter(currentCenter, true); // just me SpriteMorph.uber.drawNew.call(this, facing); this.rotationOffset = this.extent().divideBy(2); + this.image = this.applyGraphicsEffects(this.image); if (isLoadingCostume) { // retry until costume is done loading cst = this.costume; handle = setInterval( @@ -2833,12 +2850,118 @@ SpriteMorph.prototype.changeScale = function (delta) { // SpriteMorph graphic effects +SpriteMorph.prototype.applyGraphicsEffects = function (canvas) { +// For every effect: apply transform of that effect(canvas, stored value) +// The future: write more effects here + + function transform_negative(p, value) { + if (value !== 0) { + for (i = 0; i < p.length; i = i + 4) { + var rcom = 255 - p[i + 0] + var gcom = 255 - p[i + 1] + var bcom = 255 - p[i + 2] + + if (p[i + 0] < rcom) { //check if current number less than the complement. if so, then + p[i + 0] = p[i + 0] + value + } else if (p[i + 0] > rcom) { + p[i + 0] = p[i + 0] - value //or else decrease towards it + } + if (p[i + 1] < gcom) { + p[i + 1] = p[i + 1] + value + } else if (p[i + 1] > gcom) { + p[i + 1] = p[i + 1] - value + } + if (p[i + 2] < bcom) { + p[i + 2] = p[i + 2] + value + } else if (p[i + 2] > bcom) { + p[i + 2] = p[i + 2] - value + }; + }; + }; + return p; + }; + + function transform_brightness(p, value) { + if (value !== 0) { + for (i = 0; i < p.length; i += 4) { + p[i+0] = p[i+0] + value; //255 = 100% of this color. 255 everything = white. + p[i+1] = p[i+1] + value; //if value is negative, add more value to p. if value is positive, subtract value from p + p[i+2] = p[i+2] + value; + p[i+3] = p[i+3]; + }; + }; + return p; + }; + + function transform_comic(p, value) { + if (value !== 0) { + for (i = 0; i < p.length; i += 4) { + var frequency = value; + p[i + 0] = p[i + 0] + Math.sin(i * frequency) * 127 + 128 + p[i + 1] = p[i + 1] + Math.sin(i * frequency) * 127 + 128 + p[i + 2] = p[i + 2] + Math.sin(i * frequency) * 127 + 128 + p[i + 3] = p[i + 3]; + }; + }; + return p; + }; + + function transform_duplicate(p, value) { + if (value !== 0) { + for (i = 0; i < p.length; i += 4) { + p[i + 0] = p[i * value + 0] + p[i + 1] = p[i * value + 1] + p[i + 2] = p[i * value + 2] + p[i + 3] = p[i * value + 3]; + }; + }; + return p; + }; + + function transform_confetti(p, value) { + if (value !== 0) { + for (i = 0; i < p.length; i++) { + p[i] = Math.sin(value * p[i]) * 127 + p[i] + }; + }; + return p; + }; + + if (this.graphicsChanged) { + ctx = canvas.getContext("2d"); + imagedata = ctx.getImageData(0, 0, canvas.width, canvas.height); + pixels = imagedata.data; + + // for each effect, do a transform. at any given time, a sprite should wear all 7 effects + /*pixels = transform_whirl(pixels, this.graphicsValues['whirl']);*/ + pixels = transform_negative(pixels, this.graphicsValues['negative']); + pixels = transform_brightness(pixels, this.graphicsValues['brightness']); + pixels = transform_comic(pixels, this.graphicsValues['comic']); + /*pixels = transform_pixelate(pixels, this.graphicsValues['pixelate']);*/ + pixels = transform_duplicate(pixels, this.graphicsValues['duplicate']); + /*pixels = transform_color(pixels, this.graphicsValues['color']);*/ + /*pixels = transform_fisheye(pixels, this.graphicsValues['fisheye']);*/ + pixels = transform_confetti(pixels, this.graphicsValues['confetti']); + + //the last object will have all the transformations done on it + newimagedata = ctx.createImageData(imagedata); //make new imgdata object + newimagedata.data.set(pixels); //add transformed pixels + ctx.putImageData(newimagedata, 0, 0); + }; + + return canvas; //for each effect, apply the transformation on the image we receive +}; + SpriteMorph.prototype.setEffect = function (effect, value) { var eff = effect instanceof Array ? effect[0] : null; if (eff === 'ghost') { this.alpha = 1 - Math.min(Math.max(+value || 0, 0), 100) / 100; - this.changed(); - } + } else { + this.graphicsValues[eff] = value; + }; + this.graphicsChanged = true; + this.drawNew(); + this.changed(); }; SpriteMorph.prototype.getGhostEffect = function () { @@ -2848,11 +2971,16 @@ SpriteMorph.prototype.getGhostEffect = function () { SpriteMorph.prototype.changeEffect = function (effect, value) { var eff = effect instanceof Array ? effect[0] : null; if (eff === 'ghost') { - this.setEffect(effect, this.getGhostEffect() + (+value || 0)); - } + this.setEffect(effect, this.getGhostEffect() + (+value || 0)); //special for ghost because its value is the alpha value + } else { + this.setEffect(effect, this.graphicsValues[eff] + value); + }; }; SpriteMorph.prototype.clearEffects = function () { + for (var effect in this.graphicsValues) { + this.setEffect([effect], 0); + }; this.setEffect(['ghost'], 0); }; -- cgit v1.3.1 From ab218322f3227a40e38b891be84b58ad49c82d74 Mon Sep 17 00:00:00 2001 From: yuan Date: Wed, 28 May 2014 02:38:04 -0700 Subject: changed graphicsChanged boolean to a function --- objects.js | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/objects.js b/objects.js index b1e2892..c0e7357 100644 --- a/objects.js +++ b/objects.js @@ -1292,23 +1292,22 @@ SpriteMorph.prototype.init = function (globals) { this.idx = 0; // not to be serialized (!) - used for de-serialization this.wasWarped = false; // not to be serialized, used for fast-tracking - SpriteMorph.uber.init.call(this); - - this.isDraggable = true; - this.isDown = false; - - this.graphicsValues = { 'color': 0, //dictionary of all the orignal values + this.graphicsValues = { 'negative': 0, //dictionary of all the orignal values 'fisheye': 0, 'whirl': 0, 'pixelate': 0, 'mosaic': 0, 'brightness': 0, - 'negative': 0, + 'color': 0, 'comic': 0, 'duplicate': 0, 'confetti': 0 }; - this.graphicsChanged = false; + + SpriteMorph.uber.init.call(this); + + this.isDraggable = true; + this.isDown = false; this.heading = 90; this.changed(); @@ -2848,7 +2847,16 @@ SpriteMorph.prototype.changeScale = function (delta) { this.setScale(this.getScale() + (+delta || 0)); }; -// SpriteMorph graphic effects +//spritemorph graphics effects + +SpriteMorph.prototype.graphicsChanged = function () { + var myself = this; + return Object.keys(this.graphicsValues).some( + function(any) { + return myself.graphicsValues[any] < 0 || myself.graphicsValues[any] > 0; + } + ); +}; SpriteMorph.prototype.applyGraphicsEffects = function (canvas) { // For every effect: apply transform of that effect(canvas, stored value) @@ -2927,7 +2935,7 @@ SpriteMorph.prototype.applyGraphicsEffects = function (canvas) { return p; }; - if (this.graphicsChanged) { + if (this.graphicsChanged()) { //operates image pixel manipulation if graphicschanged = true. ctx = canvas.getContext("2d"); imagedata = ctx.getImageData(0, 0, canvas.width, canvas.height); pixels = imagedata.data; @@ -2957,9 +2965,8 @@ SpriteMorph.prototype.setEffect = function (effect, value) { if (eff === 'ghost') { this.alpha = 1 - Math.min(Math.max(+value || 0, 0), 100) / 100; } else { - this.graphicsValues[eff] = value; + this.graphicsValues[eff] = value; //changes the value of the dictionary }; - this.graphicsChanged = true; this.drawNew(); this.changed(); }; @@ -4134,6 +4141,18 @@ StageMorph.prototype.init = function (globals) { this.trailsCanvas = null; this.isThreadSafe = false; + this.graphicsValues = { 'negative': 0, //dictionary of all the orignal values + 'fisheye': 0, + 'whirl': 0, + 'pixelate': 0, + 'mosaic': 0, + 'brightness': 0, + 'color': 0, + 'comic': 0, + 'duplicate': 0, + 'confetti': 0 + }; + StageMorph.uber.init.call(this); this.acceptsDrops = false; @@ -4189,8 +4208,8 @@ StageMorph.prototype.setScale = function (number) { StageMorph.prototype.drawNew = function () { var ctx; - StageMorph.uber.drawNew.call(this); - if (this.costume) { + StageMorph.uber.drawNew.call(this); //call drawNew from framemorph + if (this.costume) { //if it's wearing a costume ctx = this.image.getContext('2d'); ctx.scale(this.scale, this.scale); ctx.drawImage( -- cgit v1.3.1 From 94ad721bfe5f63e6545abf96ca6349977c6b06fd Mon Sep 17 00:00:00 2001 From: yuan Date: Wed, 28 May 2014 23:17:04 -0700 Subject: good to go for stagemorph --- objects.js | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/objects.js b/objects.js index c0e7357..5eb481c 100644 --- a/objects.js +++ b/objects.js @@ -1431,7 +1431,7 @@ SpriteMorph.prototype.drawNew = function () { ctx.scale(this.scale * stageScale, this.scale * stageScale); ctx.translate(shift.x, shift.y); ctx.rotate(radians(facing - 90)); - ctx.drawImage(pic.contents, 0, 0); + ctx.drawImage(pic.contents, 0, 0); // apply graphics effects to image this.image = this.applyGraphicsEffects(this.image); @@ -2978,7 +2978,7 @@ SpriteMorph.prototype.getGhostEffect = function () { SpriteMorph.prototype.changeEffect = function (effect, value) { var eff = effect instanceof Array ? effect[0] : null; if (eff === 'ghost') { - this.setEffect(effect, this.getGhostEffect() + (+value || 0)); //special for ghost because its value is the alpha value + this.setEffect(effect, this.getGhostEffect() + (+value || 0)); //special for ghost because of alpha value } else { this.setEffect(effect, this.graphicsValues[eff] + value); }; @@ -4141,7 +4141,7 @@ StageMorph.prototype.init = function (globals) { this.trailsCanvas = null; this.isThreadSafe = false; - this.graphicsValues = { 'negative': 0, //dictionary of all the orignal values + this.graphicsValues = { 'negative': 0, //dictionary of all the original values 'fisheye': 0, 'whirl': 0, 'pixelate': 0, @@ -4208,15 +4208,16 @@ StageMorph.prototype.setScale = function (number) { StageMorph.prototype.drawNew = function () { var ctx; - StageMorph.uber.drawNew.call(this); //call drawNew from framemorph - if (this.costume) { //if it's wearing a costume + StageMorph.uber.drawNew.call(this); + if (this.costume) { //if wearing a costume ctx = this.image.getContext('2d'); ctx.scale(this.scale, this.scale); - ctx.drawImage( - this.costume.contents, - (this.width() / this.scale - this.costume.width()) / 2, - (this.height() / this.scale - this.costume.height()) / 2 + ctx.drawImage( //drawimage on this new 2d canvas with these inputs: image, x and y + this.costume.contents, //this is the image + (this.width() / this.scale - this.costume.width()) / 2, //width = canvas wdith - costume width/2 + (this.height() / this.scale - this.costume.height()) / 2 //this is the y ); + this.image = this.applyGraphicsEffects(this.image) //apply graphics effects to this image. } }; @@ -5240,6 +5241,12 @@ StageMorph.prototype.reportCostumes // StageMorph graphic effects +StageMorph.prototype.graphicsChanged + = SpriteMorph.prototype.graphicsChanged; + +StageMorph.prototype.applyGraphicsEffects + = SpriteMorph.prototype.applyGraphicsEffects; + StageMorph.prototype.setEffect = SpriteMorph.prototype.setEffect; -- cgit v1.3.1 From 8971d29adc0fbcb75b60dd58c3043c8eb2e150a1 Mon Sep 17 00:00:00 2001 From: yuan Date: Wed, 28 May 2014 23:45:43 -0700 Subject: cleaned up my comments --- objects.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/objects.js b/objects.js index 5eb481c..7d6ce14 100644 --- a/objects.js +++ b/objects.js @@ -2847,7 +2847,7 @@ SpriteMorph.prototype.changeScale = function (delta) { this.setScale(this.getScale() + (+delta || 0)); }; -//spritemorph graphics effects +// Spritemorph graphics effects SpriteMorph.prototype.graphicsChanged = function () { var myself = this; @@ -4209,13 +4209,13 @@ StageMorph.prototype.setScale = function (number) { StageMorph.prototype.drawNew = function () { var ctx; StageMorph.uber.drawNew.call(this); - if (this.costume) { //if wearing a costume + if (this.costume) { ctx = this.image.getContext('2d'); ctx.scale(this.scale, this.scale); - ctx.drawImage( //drawimage on this new 2d canvas with these inputs: image, x and y - this.costume.contents, //this is the image - (this.width() / this.scale - this.costume.width()) / 2, //width = canvas wdith - costume width/2 - (this.height() / this.scale - this.costume.height()) / 2 //this is the y + ctx.drawImage( + this.costume.contents, + (this.width() / this.scale - this.costume.width()) / 2, + (this.height() / this.scale - this.costume.height()) / 2 ); this.image = this.applyGraphicsEffects(this.image) //apply graphics effects to this image. } -- cgit v1.3.1 From e7f9ff5dcbac3459c9ab111aea3e4096467d5ea5 Mon Sep 17 00:00:00 2001 From: yuan Date: Mon, 2 Jun 2014 00:07:00 -0700 Subject: JSLinted --- blocks.js | 4 +- objects.js | 183 ++++++++++++++++++++++++++++++++----------------------------- 2 files changed, 97 insertions(+), 90 deletions(-) diff --git a/blocks.js b/blocks.js index da5e929..65ab90b 100644 --- a/blocks.js +++ b/blocks.js @@ -918,8 +918,8 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { negative : ['negative'], comic: ['comic'], duplicate: ['duplicate'], - confetti: ['confetti'], - }, + confetti: ['confetti'] + }, true ); part.setContents(['ghost']); diff --git a/objects.js b/objects.js index 7d6ce14..81ce072 100644 --- a/objects.js +++ b/objects.js @@ -1292,11 +1292,11 @@ SpriteMorph.prototype.init = function (globals) { this.idx = 0; // not to be serialized (!) - used for de-serialization this.wasWarped = false; // not to be serialized, used for fast-tracking - this.graphicsValues = { 'negative': 0, //dictionary of all the orignal values - 'fisheye': 0, - 'whirl': 0, - 'pixelate': 0, - 'mosaic': 0, + this.graphicsValues = { 'negative': 0, + 'fisheye': 0, + 'whirl': 0, + 'pixelate': 0, + 'mosaic': 0, 'brightness': 0, 'color': 0, 'comic': 0, @@ -1431,7 +1431,7 @@ SpriteMorph.prototype.drawNew = function () { ctx.scale(this.scale * stageScale, this.scale * stageScale); ctx.translate(shift.x, shift.y); ctx.rotate(radians(facing - 90)); - ctx.drawImage(pic.contents, 0, 0); + ctx.drawImage(pic.contents, 0, 0); // apply graphics effects to image this.image = this.applyGraphicsEffects(this.image); @@ -2847,13 +2847,14 @@ SpriteMorph.prototype.changeScale = function (delta) { this.setScale(this.getScale() + (+delta || 0)); }; -// Spritemorph graphics effects +// Spritemorph graphic effects SpriteMorph.prototype.graphicsChanged = function () { var myself = this; return Object.keys(this.graphicsValues).some( - function(any) { - return myself.graphicsValues[any] < 0 || myself.graphicsValues[any] > 0; + function (any) { + return myself.graphicsValues[any] < 0 || + myself.graphicsValues[any] > 0; } ); }; @@ -2861,103 +2862,106 @@ SpriteMorph.prototype.graphicsChanged = function () { SpriteMorph.prototype.applyGraphicsEffects = function (canvas) { // For every effect: apply transform of that effect(canvas, stored value) // The future: write more effects here + var ctx, imagedata, pixels, newimagedata; function transform_negative(p, value) { + var i, rcom, gcom, bcom; if (value !== 0) { - for (i = 0; i < p.length; i = i + 4) { - var rcom = 255 - p[i + 0] - var gcom = 255 - p[i + 1] - var bcom = 255 - p[i + 2] - - if (p[i + 0] < rcom) { //check if current number less than the complement. if so, then - p[i + 0] = p[i + 0] + value - } else if (p[i + 0] > rcom) { - p[i + 0] = p[i + 0] - value //or else decrease towards it + for (i = 0; i < p.length; i += 4) { + rcom = 255 - p[i]; + gcom = 255 - p[i + 1]; + bcom = 255 - p[i + 2]; + + if (p[i] < rcom) { //compare to the complement + p[i] += value; + } else if (p[i] > rcom) { + p[i] -= value; } if (p[i + 1] < gcom) { - p[i + 1] = p[i + 1] + value + p[i + 1] += value; } else if (p[i + 1] > gcom) { - p[i + 1] = p[i + 1] - value + p[i + 1] -= value; } if (p[i + 2] < bcom) { - p[i + 2] = p[i + 2] + value + p[i + 2] += value; } else if (p[i + 2] > bcom) { - p[i + 2] = p[i + 2] - value - }; - }; - }; + p[i + 2] -= value; + } + } + } return p; - }; + } function transform_brightness(p, value) { + var i; if (value !== 0) { for (i = 0; i < p.length; i += 4) { - p[i+0] = p[i+0] + value; //255 = 100% of this color. 255 everything = white. - p[i+1] = p[i+1] + value; //if value is negative, add more value to p. if value is positive, subtract value from p - p[i+2] = p[i+2] + value; - p[i+3] = p[i+3]; - }; - }; + p[i] += value; //255 = 100% of this color + p[i + 1] += value; + p[i + 2] += value; + } + } return p; - }; + } function transform_comic(p, value) { + var i; if (value !== 0) { for (i = 0; i < p.length; i += 4) { - var frequency = value; - p[i + 0] = p[i + 0] + Math.sin(i * frequency) * 127 + 128 - p[i + 1] = p[i + 1] + Math.sin(i * frequency) * 127 + 128 - p[i + 2] = p[i + 2] + Math.sin(i * frequency) * 127 + 128 - p[i + 3] = p[i + 3]; - }; - }; - return p; - }; + p[i] += Math.sin(i * value) * 127 + 128; + p[i + 1] += Math.sin(i * value) * 127 + 128; + p[i + 2] += Math.sin(i * value) * 127 + 128; + } + } + return p; + } function transform_duplicate(p, value) { + var i; if (value !== 0) { for (i = 0; i < p.length; i += 4) { - p[i + 0] = p[i * value + 0] - p[i + 1] = p[i * value + 1] - p[i + 2] = p[i * value + 2] + p[i] = p[i * value]; + p[i + 1] = p[i * value + 1]; + p[i + 2] = p[i * value + 2]; p[i + 3] = p[i * value + 3]; - }; - }; + } + } return p; - }; + } function transform_confetti(p, value) { + var i; if (value !== 0) { - for (i = 0; i < p.length; i++) { - p[i] = Math.sin(value * p[i]) * 127 + p[i] - }; - }; + for (i = 0; i < p.length; i += 1) { + p[i] = Math.sin(value * p[i]) * 127 + p[i]; + } + } return p; - }; + } - if (this.graphicsChanged()) { //operates image pixel manipulation if graphicschanged = true. - ctx = canvas.getContext("2d"); + if (this.graphicsChanged()) { + ctx = canvas.getContext("2d"); imagedata = ctx.getImageData(0, 0, canvas.width, canvas.height); pixels = imagedata.data; - // for each effect, do a transform. at any given time, a sprite should wear all 7 effects - /*pixels = transform_whirl(pixels, this.graphicsValues['whirl']);*/ - pixels = transform_negative(pixels, this.graphicsValues['negative']); - pixels = transform_brightness(pixels, this.graphicsValues['brightness']); - pixels = transform_comic(pixels, this.graphicsValues['comic']); - /*pixels = transform_pixelate(pixels, this.graphicsValues['pixelate']);*/ - pixels = transform_duplicate(pixels, this.graphicsValues['duplicate']); - /*pixels = transform_color(pixels, this.graphicsValues['color']);*/ - /*pixels = transform_fisheye(pixels, this.graphicsValues['fisheye']);*/ - pixels = transform_confetti(pixels, this.graphicsValues['confetti']); - + //A sprite should wear all 7 effects at once + /*pixels = transform_whirl(pixels, this.graphicsValues.whirl);*/ + pixels = transform_negative(pixels, this.graphicsValues.negative); + pixels = transform_brightness(pixels, this.graphicsValues.brightness); + pixels = transform_comic(pixels, this.graphicsValues.comic); + /*pixels = transform_pixelate(pixels, this.graphicsValues.pixelate);*/ + pixels = transform_duplicate(pixels, this.graphicsValues.duplicate); + /*pixels = transform_color(pixels, this.graphicsValues.color);*/ + /*pixels = transform_fisheye(pixels, this.graphicsValues.fisheye);*/ + pixels = transform_confetti(pixels, this.graphicsValues.confetti); + //the last object will have all the transformations done on it - newimagedata = ctx.createImageData(imagedata); //make new imgdata object - newimagedata.data.set(pixels); //add transformed pixels + newimagedata = ctx.createImageData(imagedata); //make imgdata object + newimagedata.data.set(pixels); //add transformed pixels ctx.putImageData(newimagedata, 0, 0); - }; + } - return canvas; //for each effect, apply the transformation on the image we receive + return canvas; }; SpriteMorph.prototype.setEffect = function (effect, value) { @@ -2965,8 +2969,8 @@ SpriteMorph.prototype.setEffect = function (effect, value) { if (eff === 'ghost') { this.alpha = 1 - Math.min(Math.max(+value || 0, 0), 100) / 100; } else { - this.graphicsValues[eff] = value; //changes the value of the dictionary - }; + this.graphicsValues[eff] = value; + } this.drawNew(); this.changed(); }; @@ -2978,16 +2982,19 @@ SpriteMorph.prototype.getGhostEffect = function () { SpriteMorph.prototype.changeEffect = function (effect, value) { var eff = effect instanceof Array ? effect[0] : null; if (eff === 'ghost') { - this.setEffect(effect, this.getGhostEffect() + (+value || 0)); //special for ghost because of alpha value + this.setEffect(effect, this.getGhostEffect() + (+value || 0)); } else { this.setEffect(effect, this.graphicsValues[eff] + value); - }; + } }; SpriteMorph.prototype.clearEffects = function () { - for (var effect in this.graphicsValues) { - this.setEffect([effect], 0); - }; + var effect; + for (effect in this.graphicsValues) { + if (this.graphicsValues.hasOwnProperty(effect)) { + this.setEffect([effect], 0); + } + } this.setEffect(['ghost'], 0); }; @@ -4141,17 +4148,17 @@ StageMorph.prototype.init = function (globals) { this.trailsCanvas = null; this.isThreadSafe = false; - this.graphicsValues = { 'negative': 0, //dictionary of all the original values - 'fisheye': 0, - 'whirl': 0, - 'pixelate': 0, - 'mosaic': 0, + this.graphicsValues = { 'negative': 0, + 'fisheye': 0, + 'whirl': 0, + 'pixelate': 0, + 'mosaic': 0, 'brightness': 0, 'color': 0, 'comic': 0, 'duplicate': 0, 'confetti': 0 - }; + }; StageMorph.uber.init.call(this); @@ -4209,15 +4216,15 @@ StageMorph.prototype.setScale = function (number) { StageMorph.prototype.drawNew = function () { var ctx; StageMorph.uber.drawNew.call(this); - if (this.costume) { + if (this.costume) { ctx = this.image.getContext('2d'); ctx.scale(this.scale, this.scale); - ctx.drawImage( - this.costume.contents, + ctx.drawImage( + this.costume.contents, (this.width() / this.scale - this.costume.width()) / 2, - (this.height() / this.scale - this.costume.height()) / 2 + (this.height() / this.scale - this.costume.height()) / 2 ); - this.image = this.applyGraphicsEffects(this.image) //apply graphics effects to this image. + this.image = this.applyGraphicsEffects(this.image); } }; -- cgit v1.3.1 From 64a1636736e5b535996deddfddf9d0318e1f56e2 Mon Sep 17 00:00:00 2001 From: Nathan Dinsmore Date: Mon, 2 Jun 2014 15:20:33 -0400 Subject: Fixed loading blank inputs --- store.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/store.js b/store.js index e143245..e448f74 100644 --- a/store.js +++ b/store.js @@ -1032,7 +1032,7 @@ SnapSerializer.prototype.loadInput = function (model, input, block) { input.setColor(this.loadColor(model.contents)); } else { val = this.loadValue(model); - if (val) { + if (val !== undefined && val !== null && input.setContents) { input.setContents(this.loadValue(model)); } } -- cgit v1.3.1 From ee695213cfe947f0dc69de9c640879da96582ddd Mon Sep 17 00:00:00 2001 From: Nathan Dinsmore Date: Mon, 2 Jun 2014 15:55:28 -0400 Subject: Fixed ctrl/cmd+shift+s saving the project in place --- objects.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/objects.js b/objects.js index 5f91606..f48b13a 100644 --- a/objects.js +++ b/objects.js @@ -4395,7 +4395,7 @@ StageMorph.prototype.processKeyEvent = function (event, action) { default: keyName = String.fromCharCode(event.keyCode || event.charCode); if (event.ctrlKey || event.metaKey) { - keyName = 'ctrl ' + keyName; + keyName = 'ctrl ' + (event.shiftKey ? 'shift ' : '') + keyName; } } action.call(this, keyName); @@ -4420,6 +4420,9 @@ StageMorph.prototype.fireKeyEvent = function (key) { if (evt === 'ctrl s') { return this.parentThatIsA(IDE_Morph).save(); } + if (evt === 'ctrl shift s') { + return this.parentThatIsA(IDE_Morph).saveProjectsBrowser(); + } if (evt === 'esc') { return this.fireStopAllEvent(); } -- cgit v1.3.1 From 2710f5b30777d356382763d0b4d30f3472e5b951 Mon Sep 17 00:00:00 2001 From: Nathan Dinsmore Date: Mon, 2 Jun 2014 15:53:12 -0400 Subject: Fixed the equals block when one list is linked and the other is not --- lists.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lists.js b/lists.js index 3166bf1..13ec880 100644 --- a/lists.js +++ b/lists.js @@ -305,7 +305,7 @@ List.prototype.equalTo = function (other) { if (this.length() !== other.length()) { return false; } - for (i = 0; i < this.length(); i += 1) { + for (i = 1; i <= this.length(); i += 1) { if (!snapEquals(this.at(i), other.at(i))) { return false; } -- cgit v1.3.1 From 6d9ce7b61c61ff737133dd3490c6caf854793f04 Mon Sep 17 00:00:00 2001 From: Hardmath123 Date: Tue, 3 Jun 2014 15:28:07 -0700 Subject: Added scaling and flipping --- paint.js | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/paint.js b/paint.js index ee40b23..12f4f82 100644 --- a/paint.js +++ b/paint.js @@ -3,12 +3,12 @@ a paint editor for Snap! inspired by the Scratch paint editor. - + written by Kartik Chandra Copyright (C) 2014 by Kartik Chandra - + This file is part of Snap!. - + Snap! is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of @@ -133,6 +133,10 @@ PaintEditorMorph.prototype.buildContents = function () { this.buildToolbox(); this.controls.add(this.toolbox); + this.scaleBox = new AlignmentMorph('row', this.padding); + this.buildScaleBox(); + this.controls.add(this.scaleBox); + this.propertiesControls = { colorpicker: null, penSizeSlider: null, @@ -218,6 +222,27 @@ PaintEditorMorph.prototype.buildEdits = function () { this.edits.fixLayout(); }; +PaintEditorMorph.prototype.buildScaleBox = function () { + var paper = this.paper; + this.scaleBox.add(this.pushButton( + "grow", + function () {paper.scale(0.05, 0.05); } + )); + this.scaleBox.add(this.pushButton( + "shrink", + function () {paper.scale(-0.05, -0.05); } + )); + this.scaleBox.add(this.pushButton( + "flipX", + function () {paper.scale(-2, 0); } + )); + this.scaleBox.add(this.pushButton( + "flipY", + function () {paper.scale(0, -2); } + )); + this.scaleBox.fixLayout(); +}; + PaintEditorMorph.prototype.openIn = function (world, oldim, oldrc, callback) { // Open the editor in a world with an optional image to edit this.oldim = oldim; @@ -558,6 +583,19 @@ PaintCanvasMorph.prototype.init = function (shift) { this.buildContents(); }; +PaintCanvasMorph.prototype.scale = function(x, y) { + this.mask = newCanvas(this.extent()); + var c = newCanvas(this.extent()); + c.getContext("2d").save(); + c.getContext("2d").translate(this.rotationCenter.x, this.rotationCenter.y); + c.getContext("2d").scale(1 + x, 1 + y); + c.getContext("2d").drawImage(this.paper, -this.rotationCenter.x, -this.rotationCenter.y); + c.getContext("2d").restore(); + this.paper = c; + this.drawNew(); + this.changed(); +}; + PaintCanvasMorph.prototype.cacheUndo = function () { var cachecan = newCanvas(this.extent()); this.merge(this.paper, cachecan); -- cgit v1.3.1 From f5fca5418765f1783e056de82072351d144adb50 Mon Sep 17 00:00:00 2001 From: Hardmath123 Date: Tue, 3 Jun 2014 15:32:41 -0700 Subject: Docs, symbols --- paint.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/paint.js b/paint.js index 12f4f82..d4d2954 100644 --- a/paint.js +++ b/paint.js @@ -53,6 +53,7 @@ Jan 08 - mouse leave dragging fix (Kartik) Feb 11 - dynamically adjust to stage dimensions (Jens) Apr 30 - localizations (Manuel) + June 3 - transformations (Kartik) */ @@ -66,7 +67,7 @@ // Global stuff //////////////////////////////////////////////////////// -modules.paint = '2014-May-02'; +modules.paint = '2014-June-3'; // Declarations @@ -233,11 +234,11 @@ PaintEditorMorph.prototype.buildScaleBox = function () { function () {paper.scale(-0.05, -0.05); } )); this.scaleBox.add(this.pushButton( - "flipX", + "flip ↔", function () {paper.scale(-2, 0); } )); this.scaleBox.add(this.pushButton( - "flipY", + "flip ↕", function () {paper.scale(0, -2); } )); this.scaleBox.fixLayout(); -- cgit v1.3.1 From ef3997cccf833aebd3d5d3fbecfdc2c13dab9631 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 4 Jun 2014 12:39:28 +0200 Subject: Blocks: refactor “script pics” feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- blocks.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/blocks.js b/blocks.js index 69ae610..3e8aa60 100644 --- a/blocks.js +++ b/blocks.js @@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/ // Global stuff //////////////////////////////////////////////////////// -modules.blocks = '2014-May-02'; +modules.blocks = '2014-June-04'; var SyntaxElementMorph; @@ -4957,6 +4957,14 @@ ScriptsMorph.prototype.cleanUp = function () { }; ScriptsMorph.prototype.exportScriptsPicture = function () { + var pic = this.scriptsPicture(); + if (pic) { + window.open(pic.toDataURL()); + } +}; + +ScriptsMorph.prototype.scriptsPicture = function () { + // private - answer a canvas containing the pictures of all scripts var boundingBox, pic, ctx; if (this.children.length === 0) {return; } boundingBox = this.children[0].fullBounds(); @@ -4977,7 +4985,7 @@ ScriptsMorph.prototype.exportScriptsPicture = function () { ); } }); - window.open(pic.toDataURL()); + return pic; }; ScriptsMorph.prototype.addComment = function () { -- cgit v1.3.1 From 50203901eaac7f4ed277bb8ab981037dcc28687f Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 4 Jun 2014 12:40:03 +0200 Subject: BYOB: new scriptsPicture() method for custom block definitions --- byob.js | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/byob.js b/byob.js index 6a10110..0f79acf 100644 --- a/byob.js +++ b/byob.js @@ -106,7 +106,7 @@ SymbolMorph, isNil*/ // Global stuff //////////////////////////////////////////////////////// -modules.byob = '2014-May-02'; +modules.byob = '2014-Jun-04'; // Declarations @@ -336,6 +336,43 @@ CustomBlockDefinition.prototype.parseSpec = function (spec) { return parts; }; +// CustomBlockDefinition picturing + +CustomBlockDefinition.prototype.scriptsPicture = function () { + var scripts, proto, block, comment; + + scripts = new ScriptsMorph(); + scripts.cleanUpMargin = 10; + proto = new PrototypeHatBlockMorph(this); + proto.setPosition(scripts.position().add(10)); + if (this.comment !== null) { + comment = this.comment.fullCopy(); + proto.comment = comment; + comment.block = proto; + } + if (this.body !== null) { + proto.nextBlock(this.body.expression.fullCopy()); + } + scripts.add(proto); + proto.fixBlockColor(null, true); + this.scripts.forEach(function (element) { + block = element.fullCopy(); + block.setPosition(scripts.position().add(element.position())); + scripts.add(block); + if (block instanceof BlockMorph) { + block.allComments().forEach(function (comment) { + comment.align(block); + }); + } + }); + proto.allComments().forEach(function (comment) { + comment.align(proto); + }); + proto.children[0].fixLayout(); + scripts.fixMultiArgs(); + return scripts.scriptsPicture(); +}; + // CustomCommandBlockMorph ///////////////////////////////////////////// // CustomCommandBlockMorph inherits from CommandBlockMorph: -- cgit v1.3.1 From bae41fde2870706b200aa9ec2b0e00ca5ceb59d9 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 4 Jun 2014 12:40:44 +0200 Subject: GUI: new (hidden) feature: “Export all scripts as pic” MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (including custom block refs) --- gui.js | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- history.txt | 6 ++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/gui.js b/gui.js index 981696a..67510cf 100644 --- a/gui.js +++ b/gui.js @@ -69,7 +69,7 @@ SpeechBubbleMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.gui = '2014-May-26'; +modules.gui = '2014-Jun-04'; // Declarations @@ -2350,6 +2350,15 @@ IDE_Morph.prototype.projectMenu = function () { 'show global custom block definitions as XML\nin a new browser window' ); + if (shiftClicked) { + menu.addItem( + 'Export all scripts as pic...', + function () {myself.exportScriptsPicture(); }, + 'show a picture of all scripts\nand block definitions', + new Color(100, 0, 0) + ); + } + menu.addLine(); menu.addItem( 'Import tools', @@ -2847,6 +2856,56 @@ IDE_Morph.prototype.exportSprite = function (sprite) { + ''); }; +IDE_Morph.prototype.exportScriptsPicture = function () { + var pics = [], + pic, + padding = 20, + w = 0, + h = 0, + y = 0, + ctx; + + // collect all script pics + this.sprites.asArray().forEach(function (sprite) { + pics.push(sprite.image); + pics.push(sprite.scripts.scriptsPicture()); + sprite.customBlocks.forEach(function (def) { + pics.push(def.scriptsPicture()); + }); + }); + pics.push(this.stage.image); + pics.push(this.stage.scripts.scriptsPicture()); + this.stage.customBlocks.forEach(function (def) { + pics.push(def.scriptsPicture()); + }); + + // collect global block pics + this.stage.globalBlocks.forEach(function (def) { + pics.push(def.scriptsPicture()); + }); + + pics = pics.filter(function (each) {return !isNil(each); }); + + // determine dimensions of composite + pics.forEach(function (each) { + w = Math.max(w, each.width); + h += (each.height); + h += padding; + }); + h -= padding; + pic = newCanvas(new Point(w, h)); + ctx = pic.getContext('2d'); + + // draw all parts + pics.forEach(function (each) { + ctx.drawImage(each, 0, y); + y += padding; + y += each.height; + }); + + window.open(pic.toDataURL()); +}; + IDE_Morph.prototype.openProjectString = function (str) { var msg, myself = this; diff --git a/history.txt b/history.txt index bd4d9fe..a72aa2c 100755 --- a/history.txt +++ b/history.txt @@ -2139,3 +2139,9 @@ ______ * Objects: Fixed #445 (minor search + zoom issues) * Localization additions and Portuguese translation update, thanks, Manuel! * GUI, cloud: Show last-changed-timestamp when opening cloud projects + +140604 +------ +* Blocks: refactor “script pics” feature +* BYOB: new scriptsPicture() method for custom block definitions +* GUI: new (hidden) feature: “Export all scripts as pic” (including custom block refs) -- cgit v1.3.1 From ac39877b9c7f2cfadfca581fc98fe3b6a3c434fb Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 4 Jun 2014 13:48:43 +0200 Subject: German translation update, tweaks --- gui.js | 1 + history.txt | 3 +++ lang-de.js | 10 +++++++++- lists.js | 2 +- locale.js | 4 ++-- objects.js | 3 ++- store.js | 4 ++-- 7 files changed, 20 insertions(+), 7 deletions(-) diff --git a/gui.js b/gui.js index 67510cf..d12453b 100644 --- a/gui.js +++ b/gui.js @@ -2535,6 +2535,7 @@ IDE_Morph.prototype.aboutSnap = function () { + '\n\nNathan Dinsmore: Saving/Loading, Snap-Logo Design, ' + 'countless bugfixes' + '\nKartik Chandra: Paint Editor' + + '\nYuan Yuan: Graphic Effects' + '\nIan Reynolds: UI Design, Event Bindings, ' + 'Sound primitives' + '\nIvan Motyashov: Initial Squeak Porting' diff --git a/history.txt b/history.txt index a72aa2c..a6b3276 100755 --- a/history.txt +++ b/history.txt @@ -2145,3 +2145,6 @@ ______ * Blocks: refactor “script pics” feature * BYOB: new scriptsPicture() method for custom block definitions * GUI: new (hidden) feature: “Export all scripts as pic” (including custom block refs) +* Graphic effects!!! Yay, thanks, Yuan! +* Bug fixes from Nathan, yay, thank, Nathan!! +* German translation update diff --git a/lang-de.js b/lang-de.js index 9ce0c50..0a62da0 100644 --- a/lang-de.js +++ b/lang-de.js @@ -185,7 +185,7 @@ SnapTranslator.dict.de = { 'translator_e-mail': 'jens@moenig.org', // optional 'last_changed': - '2014-02-13', // this, too, will appear in the Translators tab + '2014-06-04', // this, too, will appear in the Translators tab // GUI // control bar: @@ -1122,8 +1122,16 @@ SnapTranslator.dict.de = { 'Leer', // graphical effects + 'brightness': + 'Helligeit', 'ghost': 'Durchsichtigkeit', + 'negative': + 'Farbumkehr', + 'comic': + 'Moire', + 'confetti': + 'Farbverschiebung', // keys 'space': diff --git a/lists.js b/lists.js index 13ec880..ea553b0 100644 --- a/lists.js +++ b/lists.js @@ -61,7 +61,7 @@ PushButtonMorph, SyntaxElementMorph, Color, Point, WatcherMorph, StringMorph, SpriteMorph, ScrollFrameMorph, CellMorph, ArrowMorph, MenuMorph, snapEquals, Morph, isNil, localize, MorphicPreferences*/ -modules.lists = '2014-January-09'; +modules.lists = '2014-Jun-04'; var List; var ListWatcherMorph; diff --git a/locale.js b/locale.js index c10aa64..614b38c 100644 --- a/locale.js +++ b/locale.js @@ -42,7 +42,7 @@ /*global modules, contains*/ -modules.locale = '2014-May-26'; +modules.locale = '2014-Jun-04'; // Global stuff @@ -149,7 +149,7 @@ SnapTranslator.dict.de = { 'translator_e-mail': 'jens@moenig.org', 'last_changed': - '2014-02-13' + '2014-06-04' }; SnapTranslator.dict.it = { diff --git a/objects.js b/objects.js index cc4371b..dc02051 100644 --- a/objects.js +++ b/objects.js @@ -61,6 +61,7 @@ sound handling Achal Dave contributed research and prototyping for creating music using the Web Audio API + Yuan Yuan contributed graphic effects for costumes */ @@ -124,7 +125,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2014-May-26'; +modules.objects = '2014-Jun-04'; var SpriteMorph; var StageMorph; diff --git a/store.js b/store.js index e448f74..11e2757 100644 --- a/store.js +++ b/store.js @@ -61,7 +61,7 @@ SyntaxElementMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.store = '2014-May-02'; +modules.store = '2014-Jun-04'; // XML_Serializer /////////////////////////////////////////////////////// @@ -1032,7 +1032,7 @@ SnapSerializer.prototype.loadInput = function (model, input, block) { input.setColor(this.loadColor(model.contents)); } else { val = this.loadValue(model); - if (val !== undefined && val !== null && input.setContents) { + if (!isNil(val) && input.setContents) { input.setContents(this.loadValue(model)); } } -- cgit v1.3.1 From ef140b093ebb61d37235ce7f4baf5fd4c0baf01d Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 4 Jun 2014 14:16:57 +0200 Subject: Paint Editor transform integration - little tweaks Thanks, Kartik!! --- history.txt | 3 ++- paint.js | 22 +++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/history.txt b/history.txt index a6b3276..72a34a6 100755 --- a/history.txt +++ b/history.txt @@ -2146,5 +2146,6 @@ ______ * BYOB: new scriptsPicture() method for custom block definitions * GUI: new (hidden) feature: “Export all scripts as pic” (including custom block refs) * Graphic effects!!! Yay, thanks, Yuan! -* Bug fixes from Nathan, yay, thank, Nathan!! +* Bug fixes from Nathan, yay, thanks, Nathan!! * German translation update +* Paint Editor transforms, yay, thanks, Kartik!! diff --git a/paint.js b/paint.js index d4d2954..7105b72 100644 --- a/paint.js +++ b/paint.js @@ -54,6 +54,7 @@ Feb 11 - dynamically adjust to stage dimensions (Jens) Apr 30 - localizations (Manuel) June 3 - transformations (Kartik) + June 4 - tweaks (Jens) */ @@ -67,7 +68,7 @@ // Global stuff //////////////////////////////////////////////////////// -modules.paint = '2014-June-3'; +modules.paint = '2014-June-4'; // Declarations @@ -112,10 +113,10 @@ PaintEditorMorph.prototype.buildContents = function () { this.paper.setExtent(StageMorph.prototype.dimensions); this.addBody(new AlignmentMorph('row', this.padding)); - this.controls = new AlignmentMorph('column', this.padding); + this.controls = new AlignmentMorph('column', this.padding / 2); this.controls.alignment = 'left'; - this.edits = new AlignmentMorph('row', this.padding); + this.edits = new AlignmentMorph('row', this.padding / 2); this.buildEdits(); this.controls.add(this.edits); @@ -134,7 +135,7 @@ PaintEditorMorph.prototype.buildContents = function () { this.buildToolbox(); this.controls.add(this.toolbox); - this.scaleBox = new AlignmentMorph('row', this.padding); + this.scaleBox = new AlignmentMorph('row', this.padding / 2); this.buildScaleBox(); this.controls.add(this.scaleBox); @@ -584,13 +585,20 @@ PaintCanvasMorph.prototype.init = function (shift) { this.buildContents(); }; -PaintCanvasMorph.prototype.scale = function(x, y) { +PaintCanvasMorph.prototype.scale = function (x, y) { this.mask = newCanvas(this.extent()); var c = newCanvas(this.extent()); c.getContext("2d").save(); - c.getContext("2d").translate(this.rotationCenter.x, this.rotationCenter.y); + c.getContext("2d").translate( + this.rotationCenter.x, + this.rotationCenter.y + ); c.getContext("2d").scale(1 + x, 1 + y); - c.getContext("2d").drawImage(this.paper, -this.rotationCenter.x, -this.rotationCenter.y); + c.getContext("2d").drawImage( + this.paper, + -this.rotationCenter.x, + -this.rotationCenter.y + ); c.getContext("2d").restore(); this.paper = c; this.drawNew(); -- cgit v1.3.1 From c09c4c2b306a36a8471480d07cbb7645bbdc6a66 Mon Sep 17 00:00:00 2001 From: Manuel Menezes de Sequeira Date: Wed, 4 Jun 2014 15:41:13 +0100 Subject: Add Portuguese translation of graphic effects, costume transformations, and exporting of scripts as pic. --- lang-pt.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lang-pt.js b/lang-pt.js index 226abf5..d28c290 100755 --- a/lang-pt.js +++ b/lang-pt.js @@ -1122,8 +1122,16 @@ SnapTranslator.dict.pt = { 'vazio', // efeitos gráficos + 'brightness': + 'brilho', 'ghost': 'fantasma', + 'negative': + 'negativo', + 'comic': + 'ondeado', + 'confetti': + 'cor', // teclas 'space': @@ -1270,6 +1278,18 @@ SnapTranslator.dict.pt = { 'um item ao acaso', // em falta no ficheiro lang-de.js + 'grow': + 'aumentar', + 'shrink': + 'reduzir', + 'flip ↔': + 'inverter ↔', + 'flip ↕': + 'inverter ↕', + 'Export all scripts as pic...': + 'Exportar todos os guiões como fotografia…', + 'show a picture of all scripts\nand block definitions': + 'Mostra uma imagem com todos\nos guiões e definições de blocos', 'current %dates': '%dates corrente', 'year': -- cgit v1.3.1 From f80235ee43f21db5a4036ce0cdbea65cc821899b Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 5 Jun 2014 17:13:27 +0200 Subject: stop replacing the empty string with the number zero in watchers fixed #473 --- history.txt | 4 ++++ objects.js | 10 ++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/history.txt b/history.txt index 72a34a6..44160ca 100755 --- a/history.txt +++ b/history.txt @@ -2149,3 +2149,7 @@ ______ * Bug fixes from Nathan, yay, thanks, Nathan!! * German translation update * Paint Editor transforms, yay, thanks, Kartik!! + +140605 +------ +* Objects: stop replacing the empty string with the number zero in watchers diff --git a/objects.js b/objects.js index dc02051..e3f1674 100644 --- a/objects.js +++ b/objects.js @@ -125,7 +125,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2014-Jun-04'; +modules.objects = '2014-Jun-05'; var SpriteMorph; var StageMorph; @@ -6591,9 +6591,11 @@ WatcherMorph.prototype.update = function () { } else { newValue = this.target[this.getter](); } - num = +newValue; - if (typeof newValue !== 'boolean' && !isNaN(num)) { - newValue = Math.round(newValue * 1000000000) / 1000000000; + if (newValue !== '' && !isNil(newValue)) { + num = +newValue; + if (typeof newValue !== 'boolean' && !isNaN(num)) { + newValue = Math.round(newValue * 1000000000) / 1000000000; + } } if (newValue !== this.currentValue) { this.changed(); -- cgit v1.3.1 From 9f690fbfa393c2bc73ac4a8a479ae089161a7556 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 5 Jun 2014 17:16:27 +0200 Subject: initialize new variables with zero (instead of null) --- history.txt | 1 + threads.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/history.txt b/history.txt index 44160ca..53e6087 100755 --- a/history.txt +++ b/history.txt @@ -2153,3 +2153,4 @@ ______ 140605 ------ * Objects: stop replacing the empty string with the number zero in watchers +* Threads: initialize new variables with zero (instead of null) diff --git a/threads.js b/threads.js index 21147a3..d489441 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2014-May-20'; +modules.threads = '2014-Jun-05'; var ThreadManager; var Process; @@ -3054,7 +3054,7 @@ VariableFrame.prototype.getVar = function (name, upvars) { VariableFrame.prototype.addVar = function (name, value) { this.vars[name] = (value === 0 ? 0 : value === false ? false - : value === '' ? '' : value || null); + : value === '' ? '' : value || 0); }; VariableFrame.prototype.deleteVar = function (name) { -- cgit v1.3.1 From ccdce5da74cbc0b8bd1f60c8981894bc1f0e164b Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 5 Jun 2014 17:42:36 +0200 Subject: fixed #465 --- history.txt | 1 + objects.js | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/history.txt b/history.txt index 53e6087..da0aebf 100755 --- a/history.txt +++ b/history.txt @@ -2154,3 +2154,4 @@ ______ ------ * Objects: stop replacing the empty string with the number zero in watchers * Threads: initialize new variables with zero (instead of null) +* Objects: fixed #465 diff --git a/objects.js b/objects.js index e3f1674..41f3e4a 100644 --- a/objects.js +++ b/objects.js @@ -3204,11 +3204,12 @@ SpriteMorph.prototype.forward = function (steps) { SpriteMorph.prototype.setHeading = function (degrees) { var x = this.xPosition(), y = this.yPosition(), - turn = degrees - this.heading; + dir = (+degrees || 90), + turn = dir - this.heading; // apply to myself this.changed(); - SpriteMorph.uber.setHeading.call(this, degrees); + SpriteMorph.uber.setHeading.call(this, dir); this.silentGotoXY(x, y, true); // just me this.positionTalkBubble(); -- cgit v1.3.1 From d7f30820b5d0363b89af5201643188545dd3e815 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 5 Jun 2014 17:56:19 +0200 Subject: fixed #457 --- history.txt | 1 + objects.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index da0aebf..fd4acc8 100755 --- a/history.txt +++ b/history.txt @@ -2155,3 +2155,4 @@ ______ * Objects: stop replacing the empty string with the number zero in watchers * Threads: initialize new variables with zero (instead of null) * Objects: fixed #465 +* Threads: fixed #457 diff --git a/objects.js b/objects.js index 41f3e4a..5de468b 100644 --- a/objects.js +++ b/objects.js @@ -4144,7 +4144,7 @@ StageMorph.prototype.init = function (globals) { this.keysPressed = {}; // for handling keyboard events, do not persist this.blocksCache = {}; // not to be serialized (!) this.paletteCache = {}; // not to be serialized (!) - this.lastAnswer = null; // last user input, do not persist + this.lastAnswer = ''; // last user input, do not persist this.activeSounds = []; // do not persist this.trailsCanvas = null; -- cgit v1.3.1 From fdfd74f79e5bfc6388397bdcc258e4672964f675 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Thu, 5 Jun 2014 22:29:16 +0200 Subject: fixes a but in setHeading() thanks, Brian! --- objects.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/objects.js b/objects.js index 5de468b..897f14d 100644 --- a/objects.js +++ b/objects.js @@ -3204,7 +3204,7 @@ SpriteMorph.prototype.forward = function (steps) { SpriteMorph.prototype.setHeading = function (degrees) { var x = this.xPosition(), y = this.yPosition(), - dir = (+degrees || 90), + dir = (+degrees || 0), turn = dir - this.heading; // apply to myself -- cgit v1.3.1 From 4e2ce9a4ee2ffb5e22423290fd3ae34045e339fb Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 6 Jun 2014 09:07:42 +0200 Subject: gracefully hide & show the stage, fixed #281 --- history.txt | 6 +++++- objects.js | 19 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/history.txt b/history.txt index fd4acc8..3f52e14 100755 --- a/history.txt +++ b/history.txt @@ -2155,4 +2155,8 @@ ______ * Objects: stop replacing the empty string with the number zero in watchers * Threads: initialize new variables with zero (instead of null) * Objects: fixed #465 -* Threads: fixed #457 +* Objects: fixed #457 + +140605 +------ +* Objects: gracefully hide & show the stage, fixed #281 diff --git a/objects.js b/objects.js index 897f14d..88ee351 100644 --- a/objects.js +++ b/objects.js @@ -125,7 +125,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2014-Jun-05'; +modules.objects = '2014-Jun-06'; var SpriteMorph; var StageMorph; @@ -5191,6 +5191,23 @@ StageMorph.prototype.thumbnail = function (extentPoint, excludedSprite) { return trg; }; +// StageMorph hiding and showing: + +/* + override the inherited behavior to recursively hide/show all + children. +*/ + +StageMorph.prototype.hide = function () { + this.isVisible = false; + this.changed(); +}; + +StageMorph.prototype.show = function () { + this.isVisible = true; + this.changed(); +}; + // StageMorph cloning overrice StageMorph.prototype.createClone = nop; -- cgit v1.3.1 From 76f6ad4c235f96dab4c67f2bae8b1bd9a8f20c7b Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 6 Jun 2014 09:15:16 +0200 Subject: add hide and show blocks for the stage --- history.txt | 1 + objects.js | 3 +++ 2 files changed, 4 insertions(+) diff --git a/history.txt b/history.txt index 3f52e14..cabc941 100755 --- a/history.txt +++ b/history.txt @@ -2160,3 +2160,4 @@ ______ 140605 ------ * Objects: gracefully hide & show the stage, fixed #281 +* Objects: add hide and show blocks to the stage’s “looks” category diff --git a/objects.js b/objects.js index 88ee351..607df14 100644 --- a/objects.js +++ b/objects.js @@ -4739,6 +4739,9 @@ StageMorph.prototype.blockTemplates = function (category) { blocks.push(block('changeEffect')); blocks.push(block('setEffect')); blocks.push(block('clearEffects')); + blocks.push('-'); + blocks.push(block('show')); + blocks.push(block('hide')); // for debugging: /////////////// -- cgit v1.3.1 From 3f04b5b474d5b189182b90246280d25c4e858693 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 6 Jun 2014 10:34:15 +0200 Subject: more relabelling options for SAY and THINK variants --- history.txt | 1 + objects.js | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/history.txt b/history.txt index cabc941..127e01b 100755 --- a/history.txt +++ b/history.txt @@ -2161,3 +2161,4 @@ ______ ------ * Objects: gracefully hide & show the stage, fixed #281 * Objects: add hide and show blocks to the stage’s “looks” category +* Objects: added more relabelling options to SAY and THINK variants diff --git a/objects.js b/objects.js index 607df14..1d027c2 100644 --- a/objects.js +++ b/objects.js @@ -1199,10 +1199,10 @@ SpriteMorph.prototype.blockAlternatives = { yPosition: ['xPosition'], // looks: - doSayFor: ['doThinkFor'], - doThinkFor: ['doSayFor'], - bubble: ['doThink'], - doThink: ['bubble'], + doSayFor: ['doThinkFor', 'bubble', 'doThink'], + doThinkFor: ['doSayFor', 'doThink', 'bubble'], + bubble: ['doThink', 'doSayFor', 'doThinkFor'], + doThink: ['bubble', 'doSayFor', 'doThinkFor'], show: ['hide'], hide: ['show'], changeEffect: ['setEffect'], -- cgit v1.3.1 From 9bbe9b2e0af9afd5d94d65d0f7399126c235384b Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 6 Jun 2014 11:45:41 +0200 Subject: enable relabelling blocks with C-Slots --- blocks.js | 12 ++++++++++-- history.txt | 1 + objects.js | 4 ++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/blocks.js b/blocks.js index b2955e9..4890fa1 100644 --- a/blocks.js +++ b/blocks.js @@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/ // Global stuff //////////////////////////////////////////////////////// -modules.blocks = '2014-June-04'; +modules.blocks = '2014-June-06'; var SyntaxElementMorph; @@ -2295,6 +2295,7 @@ BlockMorph.prototype.restoreInputs = function (oldInputs) { // try to restore my previous inputs when my spec has been changed var i = 0, old, + nb, myself = this; this.inputs().forEach(function (inp) { @@ -2305,7 +2306,14 @@ BlockMorph.prototype.restoreInputs = function (oldInputs) { // original - turns empty numberslots to 0: // inp.setContents(old.evaluate()); // "fix" may be wrong b/c constants - inp.setContents(old.contents().text); + if (old.contents) { + inp.setContents(old.contents().text); + } + } else if (old instanceof CSlotMorph && inp instanceof CSlotMorph) { + nb = old.nestedBlock(); + if (nb) { + inp.nestedBlock(nb.fullCopy()); + } } i += 1; }); diff --git a/history.txt b/history.txt index 127e01b..9a1ec59 100755 --- a/history.txt +++ b/history.txt @@ -2162,3 +2162,4 @@ ______ * Objects: gracefully hide & show the stage, fixed #281 * Objects: add hide and show blocks to the stage’s “looks” category * Objects: added more relabelling options to SAY and THINK variants +* Blocks, objects: enable relabelling blocks with C-Slots diff --git a/objects.js b/objects.js index 1d027c2..5aac197 100644 --- a/objects.js +++ b/objects.js @@ -1233,6 +1233,10 @@ SpriteMorph.prototype.blockAlternatives = { receiveClick: ['receiveGo'], doBroadcast: ['doBroadcastAndWait'], doBroadcastAndWait: ['doBroadcast'], + doIf: ['doIfElse', 'doUntil'], + doIfElse: ['doIf', 'doUntil'], + doRepeat: ['doUntil'], + doUntil: ['doRepeat', 'doIf'], // sensing: getLastAnswer: ['getTimer'], -- cgit v1.3.1 From dcd7fb92546d6e9d9b4bd7eeb7d15417cdba3d50 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 6 Jun 2014 11:56:47 +0200 Subject: enable relabelling blocks across categories --- blocks.js | 1 + history.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/blocks.js b/blocks.js index 4890fa1..d5730b6 100644 --- a/blocks.js +++ b/blocks.js @@ -2268,6 +2268,7 @@ BlockMorph.prototype.relabel = function (alternativeSelectors) { menu.addItem( block, function () { + myself.setCategory(SpriteMorph.prototype.blocks[sel].category); myself.setSelector(sel); } ); diff --git a/history.txt b/history.txt index 9a1ec59..72268f6 100755 --- a/history.txt +++ b/history.txt @@ -2163,3 +2163,4 @@ ______ * Objects: add hide and show blocks to the stage’s “looks” category * Objects: added more relabelling options to SAY and THINK variants * Blocks, objects: enable relabelling blocks with C-Slots +* Blocks: enable relabelling blocks across categories -- cgit v1.3.1 From 7f1b542e73ce6cc80aa6c154152e96b336d18c00 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 6 Jun 2014 11:58:17 +0200 Subject: more relabelling options for SAY, THINK, ASK --- history.txt | 1 + objects.js | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/history.txt b/history.txt index 72268f6..97b487e 100755 --- a/history.txt +++ b/history.txt @@ -2164,3 +2164,4 @@ ______ * Objects: added more relabelling options to SAY and THINK variants * Blocks, objects: enable relabelling blocks with C-Slots * Blocks: enable relabelling blocks across categories +* Objects: more relabelling options for SAY, THINK, ASK diff --git a/objects.js b/objects.js index 5aac197..89bc815 100644 --- a/objects.js +++ b/objects.js @@ -1199,10 +1199,10 @@ SpriteMorph.prototype.blockAlternatives = { yPosition: ['xPosition'], // looks: - doSayFor: ['doThinkFor', 'bubble', 'doThink'], - doThinkFor: ['doSayFor', 'doThink', 'bubble'], - bubble: ['doThink', 'doSayFor', 'doThinkFor'], - doThink: ['bubble', 'doSayFor', 'doThinkFor'], + doSayFor: ['doThinkFor', 'bubble', 'doThink', 'doAsk'], + doThinkFor: ['doSayFor', 'doThink', 'bubble', 'doAsk'], + bubble: ['doThink', 'doAsk', 'doSayFor', 'doThinkFor'], + doThink: ['bubble', 'doAsk', 'doSayFor', 'doThinkFor'], show: ['hide'], hide: ['show'], changeEffect: ['setEffect'], @@ -1239,6 +1239,7 @@ SpriteMorph.prototype.blockAlternatives = { doUntil: ['doRepeat', 'doIf'], // sensing: + doAsk: ['bubble', 'doThink', 'doSayFor', 'doThinkFor'], getLastAnswer: ['getTimer'], getTimer: ['getLastAnswer'], reportMouseX: ['reportMouseY'], -- cgit v1.3.1 From 0b80976c9c2fc688663c521f4eb9a583b36949c4 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 6 Jun 2014 12:12:19 +0200 Subject: tweaks --- blocks.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/blocks.js b/blocks.js index d5730b6..4d14351 100644 --- a/blocks.js +++ b/blocks.js @@ -2268,7 +2268,6 @@ BlockMorph.prototype.relabel = function (alternativeSelectors) { menu.addItem( block, function () { - myself.setCategory(SpriteMorph.prototype.blocks[sel].category); myself.setSelector(sel); } ); @@ -2284,7 +2283,7 @@ BlockMorph.prototype.setSelector = function (aSelector) { var oldInputs = this.inputs(), info; info = SpriteMorph.prototype.blocks[aSelector]; - this.category = info.category; + this.setCategory(info.category); this.selector = aSelector; this.setSpec(localize(info.spec)); this.restoreInputs(oldInputs); -- cgit v1.3.1 From a5eace927aae19f8141eb525a72b18b757f57261 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 6 Jun 2014 13:04:46 +0200 Subject: show zebra-coloring when previewing cross-category relabels --- blocks.js | 1 + 1 file changed, 1 insertion(+) diff --git a/blocks.js b/blocks.js index 4d14351..af5542f 100644 --- a/blocks.js +++ b/blocks.js @@ -2264,6 +2264,7 @@ BlockMorph.prototype.relabel = function (alternativeSelectors) { alternativeSelectors.forEach(function (sel) { var block = SpriteMorph.prototype.blockForSelector(sel); block.restoreInputs(oldInputs); + block.fixBlockColor(null, true); block.addShadow(new Point(3, 3)); menu.addItem( block, -- cgit v1.3.1 From 7f8d5a3d1eacdc78f61da8e82ac481bbbb825938 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 6 Jun 2014 13:57:45 +0200 Subject: relabelling custom blocks (experimental) --- blocks.js | 9 +++++++++ byob.js | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- history.txt | 1 + 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/blocks.js b/blocks.js index af5542f..159d1a2 100644 --- a/blocks.js +++ b/blocks.js @@ -2009,6 +2009,7 @@ BlockMorph.prototype.userMenu = function () { var menu = new MenuMorph(this), world = this.world(), myself = this, + alternatives, blck; menu.addItem( @@ -2066,6 +2067,14 @@ BlockMorph.prototype.userMenu = function () { ); } ); + } else if (this.definition && this.alternatives) { // custom block + alternatives = this.alternatives(); + if (alternatives.length > 0) { + menu.addItem( + 'relabel...', + function () {myself.relabel(alternatives); } + ); + } } menu.addItem( diff --git a/byob.js b/byob.js index 0f79acf..a17f976 100644 --- a/byob.js +++ b/byob.js @@ -106,7 +106,7 @@ SymbolMorph, isNil*/ // Global stuff //////////////////////////////////////////////////////// -modules.byob = '2014-Jun-04'; +modules.byob = '2014-Jun-06'; // Declarations @@ -745,6 +745,7 @@ CustomCommandBlockMorph.prototype.userMenu = function () { } else { menu.addLine(); } + // menu.addItem("export definition...", 'exportBlockDefinition'); menu.addItem("delete block definition...", 'deleteBlockDefinition'); } @@ -846,6 +847,44 @@ CustomCommandBlockMorph.prototype.popUpbubbleHelp = function ( ).popUp(this.world(), this.rightCenter().add(new Point(-8, 0))); }; +// CustomCommandBlockMorph relabelling + +CustomCommandBlockMorph.prototype.relabel = function (alternatives) { + var menu = new MenuMorph(this), + oldInputs = this.inputs().map( + function (each) {return each.fullCopy(); } + ), + myself = this; + alternatives.forEach(function (def) { + var block = def.blockInstance(); + block.restoreInputs(oldInputs); + block.fixBlockColor(null, true); + block.addShadow(new Point(3, 3)); + menu.addItem( + block, + function () { + myself.definition = def; + myself.refresh(); + } + ); + }); + menu.popup(this.world(), this.bottomLeft().subtract(new Point( + 8, + this instanceof CommandBlockMorph ? this.corner : 0 + ))); +}; + +CustomCommandBlockMorph.prototype.alternatives = function () { + var rcvr = this.receiver(), + stage = rcvr.parentThatIsA(StageMorph), + allDefs = rcvr.customBlocks.concat(stage.globalBlocks), + myself = this; + return allDefs.filter(function (each) { + return each !== myself.definition && + each.type === myself.definition.type; + }); +}; + // CustomReporterBlockMorph //////////////////////////////////////////// // CustomReporterBlockMorph inherits from ReporterBlockMorph: @@ -961,6 +1000,14 @@ CustomReporterBlockMorph.prototype.bubbleHelp CustomReporterBlockMorph.prototype.popUpbubbleHelp = CustomCommandBlockMorph.prototype.popUpbubbleHelp; +// CustomReporterBlockMorph relabelling + +CustomReporterBlockMorph.prototype.relabel + = CustomCommandBlockMorph.prototype.relabel; + +CustomReporterBlockMorph.prototype.alternatives + = CustomCommandBlockMorph.prototype.alternatives; + // JaggedBlockMorph //////////////////////////////////////////////////// /* diff --git a/history.txt b/history.txt index 97b487e..02fc2a0 100755 --- a/history.txt +++ b/history.txt @@ -2165,3 +2165,4 @@ ______ * Blocks, objects: enable relabelling blocks with C-Slots * Blocks: enable relabelling blocks across categories * Objects: more relabelling options for SAY, THINK, ASK +* BYOB, Blocks: relabelling custom blocks (experimental) -- cgit v1.3.1