From 1f9ff5ae53069f6f23c0b187d11ea6c889554043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ben=20B=C3=BClent=20Ba=C5=9Faran=2C=20PhD?= Date: Mon, 20 Mar 2023 13:30:53 -0400 Subject: [PATCH 01/23] Revert "merge from master" --- .scalafmt.conf | 58 +- installer.i4j/kojo.install4j | 2 +- installer/licenses/Kojo-license.txt | 2 +- installer/licenses/Kojoi-license.txt | 2 +- .../net/kogics/kojo/lite/Bundle.properties | 3 - .../net/kogics/kojo/lite/Bundle_fr.properties | 20 - .../net/kogics/kojo/lite/Bundle_it.properties | 20 - .../net/kogics/kojo/lite/Bundle_sv.properties | 20 - .../samples/animated-square-creation.kojo | 65 -- .../resources/samples/fireworks-canvas.kojo | 148 ----- src/main/resources/samples/fireworks.kojo | 155 ----- src/main/resources/samples/hunted-fp.kojo | 6 +- .../net/kogics/kojo/action/actions.scala | 15 +- .../net/kogics/kojo/animation/package.scala | 144 ++-- .../kojo/appexport/WebAppExporter.scala | 14 +- .../net/kogics/kojo/codex/CodexSession.scala | 25 +- .../scala/net/kogics/kojo/codex/Talker.scala | 13 +- .../kogics/kojo/codingmode/SwitchMode.scala | 1 + .../kojo/core/CodeCompletionSupport.scala | 26 +- .../kojo/core/CodeExecutionSupport.scala | 2 +- .../net/kogics/kojo/core/InputAware.scala | 2 +- .../scala/net/kogics/kojo/core/KojoCtx.scala | 6 +- .../scala/net/kogics/kojo/core/Picture.scala | 25 +- .../net/kogics/kojo/core/Rich2DPath.scala | 11 +- .../scala/net/kogics/kojo/core/SCanvas.scala | 6 +- .../net/kogics/kojo/core/SpriteListener.scala | 12 +- .../kogics/kojo/core/TSCanvasFeatures.scala | 2 +- .../scala/net/kogics/kojo/core/Turtle.scala | 5 +- .../net/kogics/kojo/core/TurtleMover.scala | 8 +- .../net/kogics/kojo/core/codeRunner.scala | 8 +- .../scala/net/kogics/kojo/core/history.scala | 15 +- .../scala/net/kogics/kojo/core/music.scala | 13 +- .../scala/net/kogics/kojo/core/shapes.scala | 11 +- .../scala/net/kogics/kojo/core/unitlen.scala | 1 + .../kogics/kojo/core/vertexShapeSupport.scala | 50 +- .../scala/net/kogics/kojo/doodle/Angle.scala | 13 +- .../scala/net/kogics/kojo/doodle/Color.scala | 140 ++-- .../net/kogics/kojo/doodle/ColorMap.scala | 2 +- .../net/kogics/kojo/doodle/CommonColors.scala | 296 ++++----- .../net/kogics/kojo/doodle/Normalized.scala | 3 +- .../net/kogics/kojo/doodle/UnsignedByte.scala | 2 +- .../scala/net/kogics/kojo/figure/Figure.scala | 20 +- .../net/kogics/kojo/gaming/package.scala | 97 +-- .../kogics/kojo/history/CommandHistory.scala | 5 +- .../kogics/kojo/history/HistoryPanel.scala | 60 +- .../net/kogics/kojo/history/historydb.scala | 40 +- .../net/kogics/kojo/kgeom/PolyLine.scala | 12 +- .../scala/net/kogics/kojo/kmath/Kmath.scala | 3 +- .../net/kogics/kojo/kmath/rational.scala | 4 +- .../kojo/lexer/ScalariformTokenMaker.scala | 61 +- .../scala/net/kogics/kojo/lite/AppMenu.scala | 14 +- .../scala/net/kogics/kojo/lite/AppMode.scala | 2 +- .../kogics/kojo/lite/ArithAerobicsPane.scala | 13 +- .../net/kogics/kojo/lite/BreakpointPane.scala | 3 +- .../scala/net/kogics/kojo/lite/Builtins.scala | 386 +++-------- .../net/kogics/kojo/lite/CanvasDraw.scala | 4 +- .../kojo/lite/CodeExecutionSupport.scala | 167 +++-- .../net/kogics/kojo/lite/CoreBuiltins.scala | 56 +- .../net/kogics/kojo/lite/DesktopMain.scala | 2 +- .../kogics/kojo/lite/DrawingCanvasAPI.scala | 18 +- .../kogics/kojo/lite/EditorFileSupport.scala | 14 +- .../scala/net/kogics/kojo/lite/JoyStick.scala | 24 +- .../kojo/lite/KojoCompletionProvider.scala | 85 +-- .../scala/net/kogics/kojo/lite/KojoCtx.scala | 23 +- .../kojo/lite/KojoScratchpadRunner.scala | 10 +- .../kogics/kojo/lite/LangMenuFactory.scala | 45 +- .../net/kogics/kojo/lite/MacTweaks.scala | 14 +- .../scala/net/kogics/kojo/lite/Main.scala | 26 +- .../kojo/lite/MultiInstanceHandler.scala | 10 +- .../kogics/kojo/lite/NewKojoInstance.scala | 10 +- .../net/kogics/kojo/lite/NoOpSCanvas.scala | 13 +- .../net/kogics/kojo/lite/OutputPane.scala | 74 +-- .../net/kogics/kojo/lite/PictureDraw.scala | 5 +- .../kojo/lite/RmiLocalhostSocketFactory.scala | 2 +- .../kogics/kojo/lite/RmiMultiInstance.scala | 10 +- .../net/kogics/kojo/lite/ScriptEditor.scala | 277 ++++---- .../net/kogics/kojo/lite/ScriptLoader.scala | 30 +- .../net/kogics/kojo/lite/SettingsWindow.scala | 37 +- .../net/kogics/kojo/lite/SplashScreen.scala | 3 +- .../net/kogics/kojo/lite/StatusBar.scala | 3 +- .../scala/net/kogics/kojo/lite/StubMain.scala | 19 +- .../scala/net/kogics/kojo/lite/Theme.scala | 9 +- .../scala/net/kogics/kojo/lite/TopCs.scala | 17 +- .../scala/net/kogics/kojo/lite/Versions.scala | 4 +- .../net/kogics/kojo/lite/action/actions.scala | 33 +- .../kojo/lite/canvas/SpriteCanvas.scala | 94 ++- .../net/kogics/kojo/lite/i18n/LangInit.scala | 3 +- .../net/kogics/kojo/lite/i18n/deInit.scala | 394 ++++++----- .../net/kogics/kojo/lite/i18n/esInit.scala | 30 +- .../net/kogics/kojo/lite/i18n/hrInit.scala | 40 +- .../net/kogics/kojo/lite/i18n/itInit.scala | 125 ++-- .../net/kogics/kojo/lite/i18n/nlInit.scala | 60 +- .../net/kogics/kojo/lite/i18n/plInit.scala | 128 ++-- .../net/kogics/kojo/lite/i18n/ruInit.scala | 38 +- .../net/kogics/kojo/lite/i18n/svInit.scala | 93 ++- .../net/kogics/kojo/lite/i18n/tr/aralik.scala | 11 +- .../net/kogics/kojo/lite/i18n/tr/arayuz.scala | 67 +- .../net/kogics/kojo/lite/i18n/tr/belki.scala | 1 + .../kojo/lite/i18n/tr/bolumselislev.scala | 4 +- .../net/kogics/kojo/lite/i18n/tr/buan.scala | 14 +- .../kojo/lite/i18n/tr/cinidunyasi.scala | 4 +- .../net/kogics/kojo/lite/i18n/tr/data.scala | 623 +++++++++--------- .../net/kogics/kojo/lite/i18n/tr/dict.scala | 22 +- .../net/kogics/kojo/lite/i18n/tr/dizi.scala | 7 +- .../net/kogics/kojo/lite/i18n/tr/dizim.scala | 39 +- .../net/kogics/kojo/lite/i18n/tr/dizin.scala | 4 +- .../net/kogics/kojo/lite/i18n/tr/eslem.scala | 14 +- .../net/kogics/kojo/lite/i18n/tr/geo.scala | 5 +- .../net/kogics/kojo/lite/i18n/tr/help.scala | 11 +- .../net/kogics/kojo/lite/i18n/tr/kume.scala | 2 +- .../net/kogics/kojo/lite/i18n/tr/kuyruk.scala | 8 +- .../kogics/kojo/lite/i18n/tr/matematik.scala | 11 +- .../kojo/lite/i18n/tr/miskindizin.scala | 2 +- .../kogics/kojo/lite/i18n/tr/package.scala | 55 +- .../net/kogics/kojo/lite/i18n/tr/renk.scala | 48 +- .../net/kogics/kojo/lite/i18n/tr/resim.scala | 94 +-- .../net/kogics/kojo/lite/i18n/tr/sayi.scala | 26 +- .../net/kogics/kojo/lite/i18n/tr/yazi.scala | 4 +- .../net/kogics/kojo/lite/i18n/tr/yoney.scala | 4 +- .../kogics/kojo/lite/i18n/tr/yoney2b.scala | 5 +- .../net/kogics/kojo/lite/i18n/trInit.scala | 235 +++---- .../kojo/lite/topc/ArithAerobicsHolder.scala | 10 +- .../kogics/kojo/lite/topc/BaseHolder.scala | 10 +- .../kojo/lite/topc/DrawingCanvasHolder.scala | 6 +- .../kogics/kojo/lite/topc/HistoryHolder.scala | 12 +- .../kojo/lite/topc/OutputWindowHolder.scala | 4 +- .../kojo/lite/topc/ScriptEditorHolder.scala | 6 +- .../kojo/lite/topc/StoryTellerHolder.scala | 5 +- .../kogics/kojo/lite/topc/TraceHolder.scala | 5 +- .../kogics/kojo/lite/trace/MethodEvent.scala | 27 +- .../kojo/lite/trace/TraceListener.scala | 10 +- .../net/kogics/kojo/lite/trace/Tracing.scala | 214 ++---- .../kojo/lite/trace/TracingBuiltins.scala | 16 +- .../kogics/kojo/lite/trace/TracingGUI.scala | 60 +- .../ColorMakerManipulatorHexRgb.scala | 22 +- .../livecoding/ColorMakerManipulatorHsv.scala | 22 +- .../ColorMakerManipulatorKnownHsl.scala | 30 +- .../kojo/livecoding/ColorManipulator.scala | 19 +- .../kojo/livecoding/FloatManipulator.scala | 14 +- .../kojo/livecoding/IntManipulator.scala | 11 +- .../kojo/livecoding/NumberManipulator.scala | 29 +- .../kogics/kojo/livecoding/manipulators.scala | 3 +- .../net/kogics/kojo/music/FuguePlayer.scala | 35 +- .../net/kogics/kojo/music/Instrument.scala | 520 --------------- .../net/kogics/kojo/music/Mp3Player.scala | 53 +- .../scala/net/kogics/kojo/music/Music.scala | 2 +- .../kojo/music/RealtimeNotePlayer.scala | 87 --- .../net/kogics/kojo/picture/PicCache.scala | 2 +- .../net/kogics/kojo/picture/cartooning.scala | 48 +- .../net/kogics/kojo/picture/effects.scala | 6 +- .../net/kogics/kojo/picture/package.scala | 42 +- .../net/kogics/kojo/picture/picimage.scala | 57 +- .../scala/net/kogics/kojo/picture/pics.scala | 58 +- .../net/kogics/kojo/picture/picshapes.scala | 158 ++--- .../net/kogics/kojo/picture/transforms.scala | 12 +- .../net/kogics/kojo/staging/CapJoin.scala | 7 - .../net/kogics/kojo/staging/ColorName.scala | 297 +++++---- .../net/kogics/kojo/staging/KColor.scala | 6 +- .../net/kogics/kojo/staging/KeyCodes.scala | 111 ++-- .../net/kogics/kojo/staging/Sprite.scala | 9 +- .../net/kogics/kojo/staging/SvgPath.scala | 272 ++++---- .../scala/net/kogics/kojo/staging/color.scala | 18 +- .../kogics/kojo/staging/complexshapes.scala | 37 +- .../net/kogics/kojo/staging/inputs.scala | 37 +- .../net/kogics/kojo/staging/screen.scala | 13 +- .../kogics/kojo/staging/simpleshapes.scala | 199 +++--- .../net/kogics/kojo/staging/staging.scala | 433 ++++++------ .../net/kogics/kojo/staging/svgshapes.scala | 61 +- .../net/kogics/kojo/story/LinkListener.scala | 15 +- .../net/kogics/kojo/story/StoryTeller.scala | 31 +- .../net/kogics/kojo/story/handlers.scala | 3 +- .../net/kogics/kojo/story/htmlEditorKit.scala | 44 +- .../scala/net/kogics/kojo/story/story.scala | 42 +- .../net/kogics/kojo/syntax/Builtins.scala | 6 +- .../net/kogics/kojo/syntax/package.scala | 4 +- .../scala/net/kogics/kojo/tiles/package.scala | 13 +- .../net/kogics/kojo/turtle/LoTurtle.scala | 26 +- .../scala/net/kogics/kojo/turtle/Turtle.scala | 50 +- .../net/kogics/kojo/turtle/TurtleHelper.scala | 24 +- .../kogics/kojo/turtle/TurtleWorldAPI.scala | 34 +- .../kogics/kojo/util/AsyncQueuedRunner.scala | 1 + .../net/kogics/kojo/util/Constants.scala | 2 +- .../net/kogics/kojo/util/PuzzleLoader.scala | 6 +- .../kogics/kojo/util/ScalatestHelper.scala | 1 + .../kogics/kojo/util/TerminalAnsiCodes.scala | 4 +- .../net/kogics/kojo/util/Throttler.scala | 10 +- .../scala/net/kogics/kojo/util/Unzipper.scala | 12 +- .../scala/net/kogics/kojo/util/Utils.scala | 197 +++--- .../scala/net/kogics/kojo/util/Vector2D.scala | 2 +- .../net/kogics/kojo/util/typeclasses.scala | 32 +- .../scala/net/kogics/kojo/util/ziptools.scala | 6 +- .../kogics/kojo/widget/swingwrappers.scala | 7 +- .../kojo/xscala/CodeCompletionUtils.scala | 33 +- .../kogics/kojo/xscala/CodeTemplates.scala | 4 +- .../kojo/xscala/CompilerAndRunner.scala | 272 ++++---- .../scala/net/kogics/kojo/xscala/Help.scala | 493 +++++++------- .../kogics/kojo/xscala/RepeatCommands.scala | 19 +- .../kogics/kojo/xscala/ScalaCodeRunner2.scala | 101 ++- .../kogics/kojo/xscala/kojoInterpreter.scala | 5 +- .../kogics/kojo/xscala/outputHandlers.scala | 28 +- 200 files changed, 4027 insertions(+), 6076 deletions(-) delete mode 100644 src/main/resources/samples/animated-square-creation.kojo delete mode 100644 src/main/resources/samples/fireworks-canvas.kojo delete mode 100644 src/main/resources/samples/fireworks.kojo delete mode 100644 src/main/scala/net/kogics/kojo/music/Instrument.scala delete mode 100644 src/main/scala/net/kogics/kojo/music/RealtimeNotePlayer.scala diff --git a/.scalafmt.conf b/.scalafmt.conf index 5086294f1..834f2d20f 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,57 +1 @@ -# Based on https://github.com/playframework/playframework/blob/main/.scalafmt.conf - -# Version https://scalameta.org/scalafmt/docs/configuration.html#version -version = 3.7.1 -# Dialect https://scalameta.org/scalafmt/docs/configuration.html#scala-dialects -runner.dialect = scala213 - -# Top-level preset https://scalameta.org/scalafmt/docs/configuration.html#top-level-presets -preset = default - -# Common https://scalameta.org/scalafmt/docs/configuration.html#most-popular -maxColumn = 120 -assumeStandardLibraryStripMargin = true - -# Alignment https://scalameta.org/scalafmt/docs/configuration.html#alignment -align { - preset = some - allowOverflow = true -} - -# Newlines https://scalameta.org/scalafmt/docs/configuration.html#newlines -newlines { - alwaysBeforeElseAfterCurlyIf = true - alwaysBeforeMultilineDef = false - implicitParamListModifierPrefer = before - beforeCurlyLambdaParams = multilineWithCaseOnly - inInterpolation = "avoid" -} - -# Spaces https://scalameta.org/scalafmt/docs/configuration.html#spaces -spaces { - inImportCurlyBraces = true # more idiomatic to include whitepsace in import x.{ yyy => zzz } -} - -# Project https://scalameta.org/scalafmt/docs/configuration.html#project -# project { -# git = true -# excludePaths = ["glob:**/core/play/src/main/scala/play/core/hidden/ObjectMappings.scala"] -# } - -# Rewrite Rules https://scalameta.org/scalafmt/docs/configuration.html#rewrite-rules -rewrite { - rules = [ - AvoidInfix, # https://scalameta.org/scalafmt/docs/configuration.html#avoidinfix - RedundantParens, # https://scalameta.org/scalafmt/docs/configuration.html#redundantparens - SortModifiers, # https://scalameta.org/scalafmt/docs/configuration.html#sortmodifiers - PreferCurlyFors, # https://scalameta.org/scalafmt/docs/configuration.html#prefercurlyfors - Imports, # https://scalameta.org/scalafmt/docs/configuration.html#imports - ] - sortModifiers.order = ["private", "protected", "final", "sealed", "abstract", "implicit", "override", "lazy"] - imports { - expand = true - sort = original - groups = [["java(x)?\\..*"], ["scala\\..*"], ["sbt\\..*"]] - } - trailingCommas.style = keep # https://scalameta.org/scalafmt/docs/configuration.html#trailing-commas -} +version = 2.7.5 \ No newline at end of file diff --git a/installer.i4j/kojo.install4j b/installer.i4j/kojo.install4j index 1ee96aa2d..dd0997533 100644 --- a/installer.i4j/kojo.install4j +++ b/installer.i4j/kojo.install4j @@ -9,7 +9,7 @@ - + diff --git a/installer/licenses/Kojo-license.txt b/installer/licenses/Kojo-license.txt index 34735ca5b..dc09cb6bc 100644 --- a/installer/licenses/Kojo-license.txt +++ b/installer/licenses/Kojo-license.txt @@ -1,5 +1,5 @@ -Copyright (C) 2009-2023 Lalit Pant as per contributions. +Copyright (C) 2009-2022 Lalit Pant as per contributions. Copyright (C) Project contributors as per contributions. Contributors retain copyright to their own contributions, diff --git a/installer/licenses/Kojoi-license.txt b/installer/licenses/Kojoi-license.txt index c3c8a9f70..40791f289 100644 --- a/installer/licenses/Kojoi-license.txt +++ b/installer/licenses/Kojoi-license.txt @@ -1,5 +1,5 @@ -Copyright (C) 2009-2023 Lalit Pant as per contributions. Copyright (C) Project contributors as per contributions. Contributors retain copyright to their own contributions, and contribute their work to this project under the license specified below. Kojo is licensed under The GNU General Public License, Version 3. The full text of the license is available at: http://www.gnu.org/licenses/gpl.html, and is also reproduced below for quick reference. +Copyright (C) 2009-2022 Lalit Pant as per contributions. Copyright (C) Project contributors as per contributions. Contributors retain copyright to their own contributions, and contribute their work to this project under the license specified below. Kojo is licensed under The GNU General Public License, Version 3. The full text of the license is available at: http://www.gnu.org/licenses/gpl.html, and is also reproduced below for quick reference. Kojo makes use of third-party software. A list of this software is available in the 'Help -> About' menu item in Kojo. diff --git a/src/main/resources/net/kogics/kojo/lite/Bundle.properties b/src/main/resources/net/kogics/kojo/lite/Bundle.properties index e6ab4b5db..638d042c0 100644 --- a/src/main/resources/net/kogics/kojo/lite/Bundle.properties +++ b/src/main/resources/net/kogics/kojo/lite/Bundle.properties @@ -62,9 +62,6 @@ S_TangramSkier=Tangram Skier S_LunarLander=Lunar Lander S_PulsatingLamp=Pulsating Lamp S_PulsatingLamp2=Pulsating Lamp 2 -S_DynamicSquare=Dynamic Square -S_Fireworks=Fireworks -S_Fireworks2=Fireworks 2 S_CrazySquare=Crazy Square S_Hunted=Hunted S_Pong=Pong diff --git a/src/main/resources/net/kogics/kojo/lite/Bundle_fr.properties b/src/main/resources/net/kogics/kojo/lite/Bundle_fr.properties index 807c0d38e..9cf4576b1 100644 --- a/src/main/resources/net/kogics/kojo/lite/Bundle_fr.properties +++ b/src/main/resources/net/kogics/kojo/lite/Bundle_fr.properties @@ -280,23 +280,3 @@ S_TicTacToe=Tic Tac Toe S_Othello=Othello S_HypnoticSquares=Carrs hypnotiques S_Radiance=Radiance - -S_PulsatingLamp=Lampe Pulse -S_PulsatingLamp2=Lampe Pulse 2 -S_DesertTree=Arbre du dsert -S_StoryTellerIntroP1=Excutez une histoire en chargeant/crivant votre script d'histoire dans l'diteur de script , puis en cliquant sur le bouton Excuter . -S_StoryTellerIntroP2=Vous pouvez contrler une histoire en cours d'excution via les boutons qui apparaissent au bas de ce volet. -S_StoryTellerIntroP3=Bonne histoire raconter ! -S_Anagrams=Anagrammes -S_UnitCircle=Cercle unitaire et vagues -S_DynamicSquare=Carr dynamique -S_Fireworks=Feux d'artifice -S_Fireworks2=Feux d'artifice 2 - -S_File_Format=Format de fichier -S_Landscape=Paysage -S_Portrait=Portrait -S_Dimension_Height=Hauteur -S_Dimension_Width=Largeur -S_WorksheetPragma=feuille de travail -S_IncludePragma=inclure diff --git a/src/main/resources/net/kogics/kojo/lite/Bundle_it.properties b/src/main/resources/net/kogics/kojo/lite/Bundle_it.properties index 4b3360b32..9d15b70cd 100644 --- a/src/main/resources/net/kogics/kojo/lite/Bundle_it.properties +++ b/src/main/resources/net/kogics/kojo/lite/Bundle_it.properties @@ -292,23 +292,3 @@ S_Radiance=Bagliore S_CubicDisarray=Disordine cubico S_CrazySquare=Quadrati pazzi S_DragonCurve=Curva del drago - -S_PulsatingLamp=Lampada pulsante -S_PulsatingLamp2=Lampada pulsante 2 -S_DesertTree=Albero del deserto -S_StoryTellerIntroP1=Esegui una storia caricando o scrivendo il codice all'interno dell'"Editor del codice" e quindi facendo clic sul pulsante "Esegui". -S_StoryTellerIntroP2=Puoi controllare una storia in corso tramite i pulsanti visualizzati nella parte inferiore di questo riquadro. -S_StoryTellerIntroP3=Buona narrazione! -S_Anagrams=Anagrammi -S_UnitCircle=Unit Circle and Waves -S_DynamicSquare=Quadrato dinamico -S_Fireworks=Fuochi d'artificio -S_Fireworks2=Fuochi d'artificio 2 - -S_File_Format=Formato del file -S_Landscape=Paesaggio -S_Portrait=Ritratto -S_Dimension_Height=Altezza -S_Dimension_Width=Larghezza -S_WorksheetPragma=foglio di lavoro -S_IncludePragma=includi diff --git a/src/main/resources/net/kogics/kojo/lite/Bundle_sv.properties b/src/main/resources/net/kogics/kojo/lite/Bundle_sv.properties index cc47003ed..1d5160ee0 100644 --- a/src/main/resources/net/kogics/kojo/lite/Bundle_sv.properties +++ b/src/main/resources/net/kogics/kojo/lite/Bundle_sv.properties @@ -280,23 +280,3 @@ S_TicTacToe=Tic Tac Toe S_Othello=Othello S_HypnoticSquares=Hypnotiska kvadrater S_Radiance=Strlglans - -S_PulsatingLamp=Pulserande lampa -S_PulsatingLamp2=Pulserande lampa 2 -S_DesertTree=kentrd -S_StoryTellerIntroP1=Kr en berttelse genom att ladda/skriva program i Skripteditorn och klicka sedan p den grna Kr-knappen. -S_StoryTellerIntroP2=Du kan styra en pgende berttelse via knapparna som framkommer i denna ruta. -S_StoryTellerIntroP3=Ha s kul! -S_Anagrams=Anagram -S_UnitCircle=Enhetscirkel och vgor -S_DynamicSquare=Dynamisk kvadrat -S_Fireworks=Fyrverkeri -S_Fireworks2=Fyrverkeri 2 - -S_File_Format=Filformat -S_Landscape=Liggande -S_Portrait=Stende -S_Dimension_Height=Hjd -S_Dimension_Width=Bredd -S_WorksheetPragma=kalkylblad -S_IncludePragma=inkludera diff --git a/src/main/resources/samples/animated-square-creation.kojo b/src/main/resources/samples/animated-square-creation.kojo deleted file mode 100644 index 5d016120f..000000000 --- a/src/main/resources/samples/animated-square-creation.kojo +++ /dev/null @@ -1,65 +0,0 @@ -cleari() -setBackgroundH(ColorMaker.hsl(210, 1.00, 0.1), ColorMaker.hsl(210, 1.00, 0.15)) - -val sqSize = 200 -val diag = math.sqrt(2 * sqSize * sqSize) -val duration = 5 // seconds -val bg = cm.linearGradient(0, 0, ColorMaker.hsl(18, 1.00, 0.50), sqSize / 2, sqSize / 2, cm.gold) -val bg2 = cm.linearGradient(0, 0, cm.gold, sqSize / 2, sqSize / 2, ColorMaker.hsl(18, 1.00, 0.50)) - -def t(sz: Double) = Picture.fromPath { p => - p.moveTo(0, 0) - p.lineTo(0, sz) - p.lineTo(sz, 0) - p.closePath() -} - -def t1 = t(sqSize) -def t2 = t(diag / 2) - -def xProp(s: Seq[Double]) = s(0) -def yProp(s: Seq[Double]) = s(1) -def rProp(s: Seq[Double]) = s(2) - -def maket1(s: Seq[Double]) = - t1.withRotation(rProp(s)).withTranslation(xProp(s), yProp(s)) - .withTranslation(-sqSize / 2, -sqSize / 2) // to center - .withFillColor(bg) - .withPenColor(darkGray) - -def maket2(s: Seq[Double]) = - t2.withRotation(rProp(s)).withTranslation(xProp(s), yProp(s)) - .withTranslation(-sqSize / 2, -sqSize / 2) // to center - .withFillColor(bg2) - .withPenColor(darkGray) - -val anim1 = Transition( - duration, - Seq(-200, -200, 360), - Seq(0, 0, 0), - easing.Linear, - maket1, - false -) - -val anim2 = Transition( - duration, - Seq(-200, 200, -360), - Seq(sqSize / 2, sqSize / 2, 45), - easing.QuadInOut, - maket2, - false -) - -val anim3 = Transition( - duration, - Seq(200, 200, -360), - Seq(sqSize / 2, sqSize / 2, -45), - easing.QuadInOut, - maket2, - false -) - -val anim = animPar(anim1, anim2, anim3) - -run(anim) diff --git a/src/main/resources/samples/fireworks-canvas.kojo b/src/main/resources/samples/fireworks-canvas.kojo deleted file mode 100644 index 7853c063a..000000000 --- a/src/main/resources/samples/fireworks-canvas.kojo +++ /dev/null @@ -1,148 +0,0 @@ -cleari() -originBottomLeft() - -setNoteInstrument(Instrument.ACOUSTIC_BASS) -playNote(50, 150) -playNote(45, 200) - -val cb = canvasBounds -val gravity = Vector2D(0, -0.1) - -class Particle(x0: Double, y0: Double, hu: Double, seed: Boolean) { - var location = Vector2D(x0, y0) - private var velocity = - if (seed) Vector2D(0, random(5, 12)) - else randomExplosionVector - private var acceleration = Vector2D(0, 0) - private var lifespan = 255.0 - private var exploded = false - - private val pic = Picture.circle(0.5) - - def randomExplosionVector: Vector2D = { - val rv1 = Vector2D(randomNormalDouble, randomNormalDouble) - val r1 = randomDouble(2, 4) - rv1 * r1 - } - - def applyForce(force: Vector2D) { - acceleration += force - } - - def shouldExplode: Boolean = !exploded && lifespan <= 0 - - def checkExplode() { - if (seed && velocity.y < 0) { - lifespan = 0 - } - } - - def isDead: Boolean = { - if (seed) exploded else lifespan <= 0 - } - - def explode() { - // note, duration, volume - playNote(15, 30, 127) - exploded = true - } - - def step() { - velocity += acceleration - location += velocity - if (!seed) { - lifespan -= 5 - velocity *= 0.95 - } - acceleration *= 0 - checkExplode() - } - - def view(canvas: CanvasDraw) { - canvas.stroke(cm.hsla(hu, 1, 0.5, lifespan / 255)) - if (seed) { - canvas.strokeWeight(4) - } - else { - canvas.strokeWeight(2) - } - canvas.point(location.x, location.y) - } -} - -class Firework() { - private val hu = random(360) - private val firework = new Particle(random(cwidth), 0, hu, true) - private val particles = ArrayBuffer.empty[Particle] - - def done: Boolean = { - if (firework.isDead & particles.isEmpty) true else false - } - - def step() { - particles.filterInPlace(p => !p.isDead) - - if (!firework.isDead) { - firework.applyForce(gravity) - firework.step() - - if (firework.shouldExplode) { - repeat(100) { - particles.append( - new Particle(firework.location.x, firework.location.y, hu, false) - ) - } - firework.explode() - } - } - - repeatFor(particles) { p => - p.applyForce(gravity) - p.step() - } - } - - def view(canvas: CanvasDraw) { - firework.view(canvas) - repeatFor(particles) { p => - p.view(canvas) - } - } - - def dead: Boolean = { - if (particles.isEmpty) true else false - } -} - -val fireworks = ArrayBuffer.empty[Firework] - -def updateState() { - fireworks.filterInPlace(f => !f.done) - if (randomDouble(1) < 0.08) { - fireworks.append(new Firework()) - } - repeatFor(fireworks) { f => - f.step() - } -} - -def viewState(canvas: CanvasDraw) { - canvas.fill(0, 0, 0, 30) - canvas.noStroke() - canvas.rect(0, 0, cwidth, cheight) - // canvas.background(black) - repeatFor(fireworks) { f => - f.view(canvas) - } -} - -animateWithCanvasDraw { canvas => - updateState() - viewState(canvas) -} - -// Inspired by -// https://github.com/CodingTrain/Coding-Challenges/tree/main/027_FireWorks/Processing/CC_027_FireWorks_2D - -// For more details, check out: -// https://github.com/litan/kojo-examples/tree/main/fireworks diff --git a/src/main/resources/samples/fireworks.kojo b/src/main/resources/samples/fireworks.kojo deleted file mode 100644 index bf55b1044..000000000 --- a/src/main/resources/samples/fireworks.kojo +++ /dev/null @@ -1,155 +0,0 @@ -cleari() -originBottomLeft() -setBackground(black) - -setNoteInstrument(Instrument.ACOUSTIC_BASS) -playNote(50, 150) -playNote(45, 200) - -val cb = canvasBounds -val gravity = Vector2D(0, -0.1) - -class Particle(x0: Double, y0: Double, hu: Double, seed: Boolean) { - var location = Vector2D(x0, y0) - private var velocity = - if (seed) Vector2D(0, random(5, 12)) - else randomExplosionVector - private var acceleration = Vector2D(0, 0) - private var lifespan = 255.0 - private var exploded = false - - private val pic = Picture.circle(1) - - def randomExplosionVector: Vector2D = { - val rv1 = Vector2D(randomNormalDouble, randomNormalDouble) - val r1 = randomDouble(2, 4) - rv1 * r1 - } - - def applyForce(force: Vector2D) { - acceleration += force - } - - def shouldExplode: Boolean = !exploded && lifespan <= 0 - - def checkExplode() { - if (seed && velocity.y < 0) { - lifespan = 0 - } - } - - def isDead: Boolean = { - if (seed) exploded else lifespan <= 0 - } - - def explode() { - // note, duration, volume - playNote(15, 30, 127) - exploded = true - } - - def step() { - velocity += acceleration - location += velocity - if (!seed) { - lifespan -= 5 - velocity *= 0.95 - } - acceleration *= 0 - checkExplode() - } - - def view() { - if (isDead) { - pic.erase() - } - else if (pic.isDrawn) { - val clr = cm.hsla(hu, 1, 0.5, lifespan / 255) - pic.setPenColor(clr) - pic.setFillColor(clr) - if (seed) { - pic.setPenThickness(3) - } - else { - pic.setPenThickness(2) - } - pic.setPosition(location.x, location.y) - } - else { - pic.draw() - } - } -} - -class Firework() { - private val hu = random(360) - private val firework = new Particle(random(cwidth), 0, hu, true) - private val particles = ArrayBuffer.empty[Particle] - - def done: Boolean = { - if (firework.isDead & particles.isEmpty) true else false - } - - def step() { - particles.filterInPlace(p => !p.isDead) - - if (!firework.isDead) { - firework.applyForce(gravity) - firework.step() - - if (firework.shouldExplode) { - repeat(100) { - particles.append( - new Particle(firework.location.x, firework.location.y, hu, false) - ) - } - firework.explode() - } - } - - repeatFor(particles) { p => - p.applyForce(gravity) - p.step() - } - } - - def view() { - firework.view() - repeatFor(particles) { p => - p.view() - } - } - - def dead: Boolean = { - if (particles.isEmpty) true else false - } -} - -val fireworks = ArrayBuffer.empty[Firework] - -def updateState() { - fireworks.filterInPlace(f => !f.done) - if (randomDouble(1) < 0.08) { - fireworks.append(new Firework()) - } - repeatFor(fireworks) { f => - f.step() - } -} - -def viewState() { - repeatFor(fireworks) { f => - f.view() - } -} - -animate { - updateState() - viewState() -} - -// Inspired by -// https://github.com/CodingTrain/Coding-Challenges/tree/main/027_FireWorks/Processing/CC_027_FireWorks_2D - -// For more details, check out: -// https://github.com/litan/kojo-examples/tree/main/fireworks diff --git a/src/main/resources/samples/hunted-fp.kojo b/src/main/resources/samples/hunted-fp.kojo index a26c242c2..fbced3079 100644 --- a/src/main/resources/samples/hunted-fp.kojo +++ b/src/main/resources/samples/hunted-fp.kojo @@ -68,7 +68,7 @@ def update(m: Model, msg: Msg): Model = msg match { val p = m.player val gameOver = cd.collidesWithEdge(p.x, p.y, p.w, p.h) || - newm.hunters.exists { h => + m.hunters.exists { h => cd.collidesWith(p.x, p.y, p.w, p.h, h.x, h.y, h.w, h.h) } newm.copy(gameOver = gameOver) @@ -97,11 +97,11 @@ def view(m: Model): Picture = { picStack(viewPics) } -val tickSub = Subscriptions.onAnimationFrame { +val tickSub: Sub[Msg] = Subscriptions.onAnimationFrame { Tick } -val keyDownSub = Subscriptions.onKeyDown { keyCode => +val keyDownSub: Sub[Msg] = Subscriptions.onKeyDown { keyCode => keyCode match { case Kc.VK_LEFT => MoveLeft case Kc.VK_RIGHT => MoveRight diff --git a/src/main/scala/net/kogics/kojo/action/actions.scala b/src/main/scala/net/kogics/kojo/action/actions.scala index 137b6d868..4be742d5d 100644 --- a/src/main/scala/net/kogics/kojo/action/actions.scala +++ b/src/main/scala/net/kogics/kojo/action/actions.scala @@ -16,21 +16,22 @@ package net.kogics.kojo package action -import java.awt.event.ActionEvent import java.awt.Color +import java.awt.event.ActionEvent + import javax.swing.AbstractAction import javax.swing.Action import javax.swing.JColorChooser -import core.CodeExecutionSupport import net.kogics.kojo.lite.EditorFileSupport import net.kogics.kojo.util.Utils +import core.CodeExecutionSupport + class ChooseColor(execSupport: CodeExecutionSupport) extends AbstractAction(Utils.loadString("S_ChooseColor")) { val ctx = execSupport.kojoCtx def actionPerformed(e: ActionEvent): Unit = { - val sColor = - JColorChooser.showDialog(execSupport.kojoCtx.frame, util.Utils.stripDots(e.getActionCommand), ctx.lastColor) + val sColor = JColorChooser.showDialog(execSupport.kojoCtx.frame, util.Utils.stripDots(e.getActionCommand), ctx.lastColor) if (sColor != null) { val cprint = execSupport.showOutput(_: String, _: Color) cprint("\u2500" * 3 + "\n", sColor) @@ -43,7 +44,7 @@ class ChooseColor(execSupport: CodeExecutionSupport) extends AbstractAction(Util "Color(%d, %d, %d)".format(sColor.getRed, sColor.getGreen, sColor.getBlue) } println(color) - println("Example usage: setPenColor(%s)".format(color)) + println("Example usage: setPenColor(%s)" format (color)) cprint("\u2500" * 3 + "\n", sColor) ctx.lastColor = sColor } @@ -61,7 +62,7 @@ object CloseFile { } class CloseFile(fileSupport: EditorFileSupport) - extends AbstractAction(Utils.loadString("S_Close"), Utils.loadIcon("/images/extra/close.gif")) { + extends AbstractAction(Utils.loadString("S_Close"), Utils.loadIcon("/images/extra/close.gif")) { setEnabled(false) CloseFile.action = this @@ -76,7 +77,7 @@ class CloseFile(fileSupport: EditorFileSupport) } class NewFile(fileSupport: EditorFileSupport) - extends AbstractAction(Utils.loadString("S_New"), Utils.loadIcon("/images/extra/new.gif")) { + extends AbstractAction(Utils.loadString("S_New"), Utils.loadIcon("/images/extra/new.gif")) { val saveAs = new SaveAs(fileSupport) diff --git a/src/main/scala/net/kogics/kojo/animation/package.scala b/src/main/scala/net/kogics/kojo/animation/package.scala index eb4f244d0..9bde0a81b 100644 --- a/src/main/scala/net/kogics/kojo/animation/package.scala +++ b/src/main/scala/net/kogics/kojo/animation/package.scala @@ -14,8 +14,7 @@ */ package net.kogics.kojo -import net.kogics.kojo.core.Picture -import net.kogics.kojo.core.SCanvas +import net.kogics.kojo.core.{Picture, SCanvas} import net.kogics.kojo.kmath.KEasing import net.kogics.kojo.util.Utils @@ -50,41 +49,40 @@ package object animation { object Animation { def apply( - duration: Double, - initState: Seq[Double], - finalState: Seq[Double], - easer: KEasing, - picMaker: Seq[Double] => Picture, - hideOnDone: Boolean - ): Animation = Transition(duration, initState, finalState, easer, picMaker, hideOnDone) + duration: Double, + initState: Seq[Double], + finalState: Seq[Double], + easer: KEasing, + picMaker: Seq[Double] => Picture, + hideOnDone: Boolean + ): Animation = Transition(duration, initState, finalState, easer, picMaker, hideOnDone) def apply( - duration: Double, - keyFrames: KeyFrames, - easers: Seq[KEasing], - picMaker: Seq[Double] => Picture, - hideOnDone: Boolean - ): Animation = Timeline(duration, keyFrames, easers, picMaker, hideOnDone) + duration: Double, + keyFrames: KeyFrames, + easers: Seq[KEasing], + picMaker: Seq[Double] => Picture, + hideOnDone: Boolean + ): Animation = Timeline(duration, keyFrames, easers, picMaker, hideOnDone) } private[animation] object AnimationUtils { def transitions( - duration: Double, - keyFrames: KeyFrames, - easers: Seq[KEasing], - picMaker: Seq[Double] => Picture, - hideOnDone: Boolean - ): Iterator[Transition] = { + duration: Double, + keyFrames: KeyFrames, + easers: Seq[KEasing], + picMaker: Seq[Double] => Picture, + hideOnDone: Boolean + ): Iterator[Transition] = { require( keyFrames.frames.length - 1 == easers.length, s"Incorrect number of easings for keyframes - required = ${keyFrames.frames.length - 1}, actual = ${easers.length}" ) - keyFrames.frames.sliding(2).zip(easers).map { - case (Seq(as1, as2), easer) => - val tduration = (as2._1 - as1._1) / 100 * duration - val initState = as1._2 - val finalState = as2._2 - Transition(tduration, initState, finalState, easer, picMaker, hideOnDone) + keyFrames.frames.sliding(2).zip(easers).map { case (Seq(as1, as2), easer) => + val tduration = (as2._1 - as1._1) / 100 * duration + val initState = as1._2 + val finalState = as2._2 + Transition(tduration, initState, finalState, easer, picMaker, hideOnDone) } } @@ -93,21 +91,20 @@ package object animation { require(frames.length > 1, "KeyFrames should have at least two frames") require(frames.head._1 == 0, "KeyFrames should start at 0%") require(frames.last._1 == 100, "KeyFrames should end at 100%") - frames.sliding(2).foreach { - case (Seq(as1, as2)) => - require(as2._1 > as1._1, "Keyframe start times should be in increasing order") + frames.sliding(2).foreach { case (Seq(as1, as2)) => + require(as2._1 > as1._1, "Keyframe start times should be in increasing order") } } } case class Transition( - duration: Double, // in seconds - initState: Seq[Double], - finalState: Seq[Double], - easer: KEasing, - picMaker: Seq[Double] => Picture, - hideOnDone: Boolean - ) extends Animation { + duration: Double, // in seconds + initState: Seq[Double], + finalState: Seq[Double], + easer: KEasing, + picMaker: Seq[Double] => Picture, + hideOnDone: Boolean + ) extends Animation { def runner = new TransitionRunner(this) @@ -121,7 +118,6 @@ package object animation { val stateSize = initState.size val durationMillis = duration * 1000 - var currState: Seq[Double] = _ var currPic: Picture = _ private def nextState(s: Seq[Double], elapsedTimeMillis: Double): Seq[Double] = { @@ -140,34 +136,30 @@ package object animation { import java.util.concurrent.Future val startMillis = System.currentTimeMillis - var firstTime = true + val initPic = picMaker(initState) + + Utils.runInSwingThreadNonBatched { + initPic.draw() + currPic = initPic + onStart() + } lazy val anim: Future[PActivity] = - canvas.animate { - if (firstTime) { - val initPic = picMaker(initState) - initPic.draw() - currState = initState - currPic = initPic - onStart() - firstTime = false - } - else { - val elapsedTimeMillis = - (System.currentTimeMillis - startMillis).toDouble - val ns = nextState(currState, elapsedTimeMillis) - val pic2 = picMaker(ns) - currPic.erase() - pic2.draw() - - currState = ns - currPic = pic2 - - if (elapsedTimeMillis >= durationMillis) { - onDone() - canvas.stopAnimationActivity(anim) - } + canvas.animateWithState((initPic, initState)) { case (pic, s) => + val elapsedTimeMillis = + (System.currentTimeMillis - startMillis).toDouble + val ns = nextState(s, elapsedTimeMillis) + + pic.erase() + val pic2 = picMaker(ns) + pic2.draw() + currPic = pic2 + + if (ns == finalState && elapsedTimeMillis >= durationMillis) { + onDone() + canvas.stopAnimationActivity(anim) } + (pic2, ns) } anim } @@ -180,13 +172,13 @@ package object animation { } case class Timeline( - duration: Double, - keyFrames: KeyFrames, - easers: Seq[KEasing], - picMaker: Seq[Double] => Picture, - hideOnDone: Boolean, - isReversed: Boolean = false - ) extends Animation { + duration: Double, + keyFrames: KeyFrames, + easers: Seq[KEasing], + picMaker: Seq[Double] => Picture, + hideOnDone: Boolean, + isReversed: Boolean = false + ) extends Animation { AnimationUtils.checkKeyFrames(keyFrames) def runner = new TimelineRunner(this) @@ -344,16 +336,16 @@ package object animation { } def animSeq(as: Seq[Animation]): Animation = as match { - case Seq() => throw new RuntimeException("To sequence animations, we need one animation at least!") - case Seq(a) => a + case Seq() => throw new RuntimeException("To sequence animations, we need one animation at least!") + case Seq(a) => a case Seq(a1, a2) => SeqAnimation(a1, a2) - case h +: tail => SeqAnimation(h, animSeq(tail)) + case h +: tail => SeqAnimation(h, animSeq(tail)) } def animPar(as: Seq[Animation]): Animation = as match { - case Seq() => throw new RuntimeException("To `par` animations, we need one animation at least!") - case Seq(a) => a + case Seq() => throw new RuntimeException("To `par` animations, we need one animation at least!") + case Seq(a) => a case Seq(a1, a2) => ParAnimation(a1, a2) - case h +: tail => ParAnimation(h, animPar(tail)) + case h +: tail => ParAnimation(h, animPar(tail)) } } diff --git a/src/main/scala/net/kogics/kojo/appexport/WebAppExporter.scala b/src/main/scala/net/kogics/kojo/appexport/WebAppExporter.scala index 17e9a22e7..631b5d42e 100644 --- a/src/main/scala/net/kogics/kojo/appexport/WebAppExporter.scala +++ b/src/main/scala/net/kogics/kojo/appexport/WebAppExporter.scala @@ -1,16 +1,15 @@ package net.kogics.kojo.appexport import java.io._ -import java.net.HttpURLConnection -import java.net.URL +import java.net.{HttpURLConnection, URL} import java.nio.charset.StandardCharsets import java.util.zip.GZIPInputStream -import scala.util.parsing.json._ -import scala.util.Using - import net.kogics.kojo.util.Unzipper +import scala.util.Using +import scala.util.parsing.json._ + object WebAppExporter { def run(script: String): Unit = { println("Web-compiling via iKojo...") @@ -71,8 +70,7 @@ $script } println("Script compilation done.") - @annotation.nowarn - def parseJson(json: String) = JSON.parseFull(json) + @annotation.nowarn def parseJson(json: String) = JSON.parseFull(json) println("Parsing response...") val parsed = parseJson(content.toString) @@ -86,7 +84,7 @@ $script val exportDir = s"$home/kojo-export" val displayExportDir = new File(exportDir).getCanonicalPath println(s"Downloading and extracting Web-App template to $displayExportDir...") - val templateUrl = new URL("https://docs.kogics.net/assets/files/webapp.zip") + val templateUrl = new URL("https://github.com/litan/kojo/blob/master/src/main/resources/export/webapp.zip?raw=true") Unzipper.unzipUrl(templateUrl, exportDir) println("Template downloading and extracting done.") diff --git a/src/main/scala/net/kogics/kojo/codex/CodexSession.scala b/src/main/scala/net/kogics/kojo/codex/CodexSession.scala index 0dc0e9f3f..bfb07a894 100644 --- a/src/main/scala/net/kogics/kojo/codex/CodexSession.scala +++ b/src/main/scala/net/kogics/kojo/codex/CodexSession.scala @@ -14,34 +14,28 @@ */ package net.kogics.kojo.codex -import java.io.File -import java.net.URI - -import org.apache.hc.client5.http.classic.methods.HttpGet -import org.apache.hc.client5.http.classic.methods.HttpPost +import org.apache.hc.client5.http.classic.methods.{HttpGet, HttpPost} import org.apache.hc.client5.http.cookie.BasicCookieStore -import org.apache.hc.client5.http.entity.mime.FileBody -import org.apache.hc.client5.http.entity.mime.HttpMultipartMode -import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder -import org.apache.hc.client5.http.entity.mime.StringBody +import org.apache.hc.client5.http.entity.mime.{FileBody, HttpMultipartMode, MultipartEntityBuilder, StringBody} import org.apache.hc.client5.http.impl.classic.HttpClients +import org.apache.hc.core5.http.ContentType import org.apache.hc.core5.http.io.entity.EntityUtils import org.apache.hc.core5.http.io.support.ClassicRequestBuilder -import org.apache.hc.core5.http.ContentType + +import java.io.File +import java.net.URI class UploadTooBigException(msg: String) extends RuntimeException(msg) class CodexSession(server: String) { val cookieStore = new BasicCookieStore() - val client = HttpClients - .custom() + val client = HttpClients.custom() .setDefaultCookieStore(cookieStore) .disableRedirectHandling() .build() def login(email: String, password: String): Unit = { - val login = ClassicRequestBuilder - .post() + val login = ClassicRequestBuilder.post() .setUri(new URI(s"$server/login")) .addParameter("email", email) .addParameter("password", password) @@ -67,8 +61,7 @@ class CodexSession(server: String) { val codeBody = new StringBody(code, ContentType.MULTIPART_FORM_DATA); val fileBody = new FileBody(image, ContentType.IMAGE_PNG) - val mpEntity = MultipartEntityBuilder - .create() + val mpEntity = MultipartEntityBuilder.create() .setMode(HttpMultipartMode.LEGACY) .addPart("title", titleBody) .addPart("category", catBody) diff --git a/src/main/scala/net/kogics/kojo/codex/Talker.scala b/src/main/scala/net/kogics/kojo/codex/Talker.scala index 88d6aa6eb..ad4674cd4 100644 --- a/src/main/scala/net/kogics/kojo/codex/Talker.scala +++ b/src/main/scala/net/kogics/kojo/codex/Talker.scala @@ -31,7 +31,7 @@ object Talker { } class Talker(email: String, password: String, listener: TalkListener) { - + @volatile var _cancel = false def fireEvent(msg: String): Unit = { @@ -79,7 +79,7 @@ class Talker(email: String, password: String, listener: TalkListener) { if (Talker.Competition == category && (catData == null || catData.trim == "")) { fireProblem("Please provide a Competition Number (above) before uploading your sketch.") } - + val session = new CodexSession(Talker.server) fireEvent(Utils.loadString(classOf[Talker], "Talker.login", Talker.server)) @@ -89,7 +89,7 @@ class Talker(email: String, password: String, listener: TalkListener) { } catch { case ex: RuntimeException => fireProblem(Utils.loadString(classOf[Talker], "Talker.login.error")) - case t: Throwable => fireProblem(t.getMessage) + case t: Throwable => fireProblem(t.getMessage) } checkCancel() @@ -104,12 +104,13 @@ class Talker(email: String, password: String, listener: TalkListener) { fireFinish(true) } catch { - case _: UploadTooBigException => - fireProblem("The drawing is too big to upload. Try reducing your canvas size.") + case _: UploadTooBigException => fireProblem("The drawing is too big to upload. Try reducing your canvas size.") case _: RuntimeException => fireProblem(Utils.loadString(classOf[Talker], "Talker.upload.error")) - case t: Throwable => fireProblem(t.getMessage) + case t: Throwable => fireProblem(t.getMessage) } + + } catch { case t: Throwable => diff --git a/src/main/scala/net/kogics/kojo/codingmode/SwitchMode.scala b/src/main/scala/net/kogics/kojo/codingmode/SwitchMode.scala index b00495c19..186228073 100644 --- a/src/main/scala/net/kogics/kojo/codingmode/SwitchMode.scala +++ b/src/main/scala/net/kogics/kojo/codingmode/SwitchMode.scala @@ -17,6 +17,7 @@ package net.kogics.kojo package codingmode import java.awt.event.ActionEvent + import javax.swing.AbstractAction import javax.swing.JCheckBoxMenuItem diff --git a/src/main/scala/net/kogics/kojo/core/CodeCompletionSupport.scala b/src/main/scala/net/kogics/kojo/core/CodeCompletionSupport.scala index be23f9a30..c5238cc1d 100644 --- a/src/main/scala/net/kogics/kojo/core/CodeCompletionSupport.scala +++ b/src/main/scala/net/kogics/kojo/core/CodeCompletionSupport.scala @@ -22,17 +22,17 @@ object MemberKind extends Enumeration { } case class CompletionInfo( - kind: MemberKind.Value, - name0: String, - signature: String, - owner: String, - prio: Int, - isJava: Boolean, - paramNames: List[List[String]], // parameter names (excluding any implicit parameter sections) - paramTypes: List[List[String]], // parameter types matching parameter names (excluding implicit parameter sections) - returnType: String, - fullyQualifiedName: String // for Class, Trait, Type, Objects: the fully qualified name -) { + kind: MemberKind.Value, + name0: String, + signature: String, + owner: String, + prio: Int, + isJava: Boolean, + paramNames: List[List[String]], // parameter names (excluding any implicit parameter sections) + paramTypes: List[List[String]], // parameter types matching parameter names (excluding implicit parameter sections) + returnType: String, + fullyQualifiedName: String // for Class, Trait, Type, Objects: the fully qualified name + ) { val name = name0.trim def params: String = { @@ -63,7 +63,7 @@ case class CompletionInfo( else { val contextInfo = for { names <- paramNames - } yield for { name <- names } yield "${%s}".format(name) + } yield for { name <- names } yield "${%s}" format (name) contextInfo.map(_.mkString("(", ", ", ")")).mkString("") } @@ -77,7 +77,7 @@ case class CompletionInfo( case Var => s"$name$params: $returnType" case _ => s"$name: $owner" } - if (ret.endsWith(": ")) ret.substring(0, ret.length - 2) else ret + if (ret endsWith ": ") ret.substring(0, ret.length - 2) else ret } } diff --git a/src/main/scala/net/kogics/kojo/core/CodeExecutionSupport.scala b/src/main/scala/net/kogics/kojo/core/CodeExecutionSupport.scala index fc219c2f1..6e656898b 100644 --- a/src/main/scala/net/kogics/kojo/core/CodeExecutionSupport.scala +++ b/src/main/scala/net/kogics/kojo/core/CodeExecutionSupport.scala @@ -11,4 +11,4 @@ trait CodeExecutionSupport { def showOutput(outText: String, color: Color): Unit def commandHistory: CommandHistory def loadCodeFromHistory(historyIdx: Int): Unit -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/core/InputAware.scala b/src/main/scala/net/kogics/kojo/core/InputAware.scala index 28ae93150..2a99e9c6f 100644 --- a/src/main/scala/net/kogics/kojo/core/InputAware.scala +++ b/src/main/scala/net/kogics/kojo/core/InputAware.scala @@ -116,7 +116,7 @@ trait InputAware { } pnode.addInputEventListener(h) } - + // import java.awt.event.KeyEvent // def onKeyPress(fn: Int => Unit) = Utils.runInSwingThread { // val eh = new PBasicInputEventHandler { diff --git a/src/main/scala/net/kogics/kojo/core/KojoCtx.scala b/src/main/scala/net/kogics/kojo/core/KojoCtx.scala index 2bac49e2c..91e568a79 100644 --- a/src/main/scala/net/kogics/kojo/core/KojoCtx.scala +++ b/src/main/scala/net/kogics/kojo/core/KojoCtx.scala @@ -15,14 +15,16 @@ package net.kogics.kojo.core -import java.awt.geom.Point2D import java.awt.Color +import java.awt.geom.Point2D + import javax.swing.Action import javax.swing.JCheckBoxMenuItem import javax.swing.JFrame -import javax.swing.JMenu import bibliothek.gui.dock.common.DefaultSingleCDockable +import javax.swing.JMenu + import net.kogics.kojo.doodle trait KojoCtx { diff --git a/src/main/scala/net/kogics/kojo/core/Picture.scala b/src/main/scala/net/kogics/kojo/core/Picture.scala index bbe3f586d..4617f7802 100644 --- a/src/main/scala/net/kogics/kojo/core/Picture.scala +++ b/src/main/scala/net/kogics/kojo/core/Picture.scala @@ -1,20 +1,20 @@ package net.kogics.kojo package core -import java.awt.geom.AffineTransform -import java.awt.image.BufferedImage -import java.awt.image.BufferedImageOp import java.awt.Paint import java.awt.Shape - +import java.awt.geom.AffineTransform +import java.awt.image.{BufferedImage, BufferedImageOp} import com.vividsolutions.jts.geom.Geometry -import edu.umd.cs.piccolo.util.PBounds -import edu.umd.cs.piccolo.PNode + import net.kogics.kojo.kgeom.PolyLine -import net.kogics.kojo.picture.ImageOp import net.kogics.kojo.util.Utils import net.kogics.kojo.util.Vector2D +import edu.umd.cs.piccolo.PNode +import edu.umd.cs.piccolo.util.PBounds +import net.kogics.kojo.picture.ImageOp + trait Picture extends InputAware { def canvas: SCanvas def pnode = tnode @@ -28,7 +28,7 @@ trait Picture extends InputAware { def scaleAboutPoint(factor: Double, x: Double, y: Double): Unit def scaleAboutPoint(factorX: Double, factorY: Double, x: Double, y: Double): Unit def scale(xFactor: Double, yFactor: Double): Unit - def shear(shearX: Double, shearY: Double): Unit + def shear(shearX:Double, shearY:Double):Unit def translate(x: Double, y: Double): Unit def translate(v: Vector2D): Unit = translate(v.x, v.y): Unit def transv(v: Vector2D) = translate(v.x, v.y): Unit @@ -179,7 +179,7 @@ trait Picture extends InputAware { animateToPosition(pos0.x + dx, pos0.y + dy, inMillis)(onEnd) } - def withRotation(angle: Double): Picture = thatsRotated(angle) + def withRotation(angle: Double): Picture = thatsRotated(angle) def withRotationAround(angle: Double, x: Double, y: Double): Picture = thatsRotatedAround(angle, x, y) def withTranslation(x: Double, y: Double): Picture = thatsTranslated(x, y) def withScaling(factor: Double): Picture = thatsScaled(factor) @@ -187,7 +187,7 @@ trait Picture extends InputAware { def withScalingAround(factor: Double, x: Double, y: Double): Picture = thatsScaledAround(factor, x, y) def withScalingAround(factorX: Double, factorY: Double, x: Double, y: Double): Picture = thatsScaledAround(factorX, factorY, x, y) - def withShear(shearX: Double, shearY: Double): Picture = thatsSheared(shearX, shearY) + def withShear(shearX:Double, shearY:Double): Picture = thatsSheared(shearX, shearY) def withFillColor(color: Paint): Picture = thatsFilledWith(color) def withPenColor(color: Paint): Picture = thatsStrokeColored(color) def withPenThickness(t: Double): Picture = thatsStrokeSized(t) @@ -200,7 +200,7 @@ trait Picture extends InputAware { def thatsScaled(factorX: Double, factorY: Double): Picture def thatsScaledAround(factor: Double, x: Double, y: Double): Picture def thatsScaledAround(factorX: Double, factorY: Double, x: Double, y: Double): Picture - def thatsSheared(shearX: Double, shearY: Double): Picture + def thatsSheared(shearX:Double, shearY:Double):Picture def thatsFilledWith(color: Paint): Picture def thatsStrokeColored(color: Paint): Picture def thatsStrokeSized(t: Double): Picture @@ -212,10 +212,9 @@ trait Picture extends InputAware { def withFading(distance: Int): Picture def withBlurring(radius: Int): Picture def withAxes: Picture - def withLocalBounds: Picture + def withBounds: Picture def withOpacity(opacity: Double): Picture def withPosition(x: Double, y: Double): Picture def withZIndex(idx: Int): Picture def withClipping(clipShape: Shape): Picture - def withPenCapJoin(capJoin: (Int, Int)): Picture } diff --git a/src/main/scala/net/kogics/kojo/core/Rich2DPath.scala b/src/main/scala/net/kogics/kojo/core/Rich2DPath.scala index 387208490..e56ed4cb1 100644 --- a/src/main/scala/net/kogics/kojo/core/Rich2DPath.scala +++ b/src/main/scala/net/kogics/kojo/core/Rich2DPath.scala @@ -15,8 +15,7 @@ package net.kogics.kojo.core -import java.awt.geom.Arc2D -import java.awt.geom.GeneralPath +import java.awt.geom.{Arc2D, GeneralPath} class Rich2DPath(p: GeneralPath) { def arc(endPointX: Double, endPointY: Double, angleOfArc: Double): Unit = { @@ -48,9 +47,9 @@ class Rich2DPath(p: GeneralPath) { ) val t: Double = Math.abs(arcAngle) match { - case value if value == 0.0 => lengthOfDirectionVector + case value if value == 0.0 => lengthOfDirectionVector case value if Math.abs(value) == 180.0 => 0.0 - case _ => lengthOfDirectionVector / Math.tan(Math.toRadians(arcAngle) / 2.0) + case _ => lengthOfDirectionVector / Math.tan(Math.toRadians(arcAngle) / 2.0) } val centerPoint = ( @@ -63,18 +62,20 @@ class Rich2DPath(p: GeneralPath) { centerPoint._2 - startPoint._2, ) + val radius = Math.hypot(pointToFindRadius._1, pointToFindRadius._2) val arcStartX = centerPoint._1 - radius val arcStartY = centerPoint._2 - radius + val width: Double = 2.0 * radius val (x0, y0) = centerPoint val (x1, y1) = startPoint val (x2, y2) = endPoint - val startAngle: Double = -180 / Math.PI * Math.atan2(y1 - y0, x1 - x0) + val startAngle: Double = (-180 / Math.PI * Math.atan2(y1 - y0, x1 - x0)) val arc = new Arc2D.Double(arcStartX, arcStartY, width, width, startAngle, arcAngle, Arc2D.OPEN) p.append(arc, true) diff --git a/src/main/scala/net/kogics/kojo/core/SCanvas.scala b/src/main/scala/net/kogics/kojo/core/SCanvas.scala index 1942e1257..60fbe8e61 100644 --- a/src/main/scala/net/kogics/kojo/core/SCanvas.scala +++ b/src/main/scala/net/kogics/kojo/core/SCanvas.scala @@ -18,15 +18,15 @@ package net.kogics.kojo.core import java.awt.Paint import java.util.concurrent.Future -import edu.umd.cs.piccolo.activities.PActivity -import edu.umd.cs.piccolo.util.PBounds import edu.umd.cs.piccolo.PCamera import edu.umd.cs.piccolo.PCanvas import edu.umd.cs.piccolo.PLayer +import edu.umd.cs.piccolo.activities.PActivity +import edu.umd.cs.piccolo.util.PBounds trait SCanvas extends TSCanvasFeatures { // stuff gets added here (instead of in the base class) if any of the following conditions hold: - // 1) there's a name clash with TurtleWorld + // 1) there's a name clash with TurtleWorld // 2) the builtin method name is different from the canvas method name // 3) there is no builtin method corresponding to the canvas method def turtle0: Turtle diff --git a/src/main/scala/net/kogics/kojo/core/SpriteListener.scala b/src/main/scala/net/kogics/kojo/core/SpriteListener.scala index 5056d89b2..cddff69c6 100644 --- a/src/main/scala/net/kogics/kojo/core/SpriteListener.scala +++ b/src/main/scala/net/kogics/kojo/core/SpriteListener.scala @@ -16,13 +16,14 @@ package net.kogics.kojo.core trait SpriteListener { - - /** Tell Listener that Sprite has pending commands in its queue - */ + /** + * Tell Listener that Sprite has pending commands in its queue + */ def hasPendingCommands(): Unit - /** Tell Listener that Sprite has no more pending commands. - */ + /** + * Tell Listener that Sprite has no more pending commands. + */ def pendingCommandsDone(): Unit } @@ -41,3 +42,4 @@ class DelegatingSpriteListener extends SpriteListener { def hasPendingCommands() = realListener.hasPendingCommands() def pendingCommandsDone() = realListener.pendingCommandsDone() } + diff --git a/src/main/scala/net/kogics/kojo/core/TSCanvasFeatures.scala b/src/main/scala/net/kogics/kojo/core/TSCanvasFeatures.scala index 808ae278c..cee5a1ab5 100644 --- a/src/main/scala/net/kogics/kojo/core/TSCanvasFeatures.scala +++ b/src/main/scala/net/kogics/kojo/core/TSCanvasFeatures.scala @@ -30,7 +30,7 @@ trait TSCanvasFeatures { def showAxes(): Unit def hideAxes(): Unit def axesOn() = showAxes() - def axesOff() = hideAxes() + def axesOff()= hideAxes() def showGrid(): Unit def hideGrid(): Unit def gridOn() = showGrid() diff --git a/src/main/scala/net/kogics/kojo/core/Turtle.scala b/src/main/scala/net/kogics/kojo/core/Turtle.scala index f72bdb0f9..159b72e16 100644 --- a/src/main/scala/net/kogics/kojo/core/Turtle.scala +++ b/src/main/scala/net/kogics/kojo/core/Turtle.scala @@ -19,17 +19,18 @@ import java.awt.Stroke import scala.collection.mutable.ArrayBuffer -import edu.umd.cs.piccolo.PLayer import net.kogics.kojo.kgeom.PolyLine import net.kogics.kojo.util.Utils +import edu.umd.cs.piccolo.PLayer + trait Turtle extends TurtleMover { def clear(): Unit def remove(): Unit def act(fn: Turtle => Unit) = Utils.runAsyncMonitored(fn(this)) def react(fn: Turtle => Unit): Unit def distanceTo(other: Turtle): Double - def towards(t: Turtle): Unit = { val pos = t.position; towards(pos.x, pos.y) } + def towards(t: Turtle): Unit = { val pos = t.position; towards(pos.x, pos.y)} // stuff for the pictures module def tlayer: PLayer private[kojo] def penPaths: ArrayBuffer[PolyLine] diff --git a/src/main/scala/net/kogics/kojo/core/TurtleMover.scala b/src/main/scala/net/kogics/kojo/core/TurtleMover.scala index 98e1b8152..7b2613751 100644 --- a/src/main/scala/net/kogics/kojo/core/TurtleMover.scala +++ b/src/main/scala/net/kogics/kojo/core/TurtleMover.scala @@ -14,12 +14,8 @@ */ package net.kogics.kojo.core -import java.awt.geom.GeneralPath -import java.awt.geom.PathIterator -import java.awt.geom.Point2D -import java.awt.Font -import java.awt.Image -import java.awt.Paint +import java.awt.geom.{GeneralPath, PathIterator, Point2D} +import java.awt.{Font, Image, Paint} case class Style(penColor: Paint, penThickness: Double, fillColor: Paint, font: Font, down: Boolean) trait Speed diff --git a/src/main/scala/net/kogics/kojo/core/codeRunner.scala b/src/main/scala/net/kogics/kojo/core/codeRunner.scala index f5e6c81f4..36bc6e16b 100644 --- a/src/main/scala/net/kogics/kojo/core/codeRunner.scala +++ b/src/main/scala/net/kogics/kojo/core/codeRunner.scala @@ -30,12 +30,7 @@ trait CodeRunner { def compileRunCode(code: String): Unit def varCompletions(prefix: Option[String]): (List[String], Int) def keywordCompletions(prefix: Option[String]): (List[String], Int) - def memberCompletions( - code: String, - caretOffset: Int, - objid: String, - prefix: Option[String] - ): (List[CompletionInfo], Int) + def memberCompletions(code: String, caretOffset: Int, objid: String, prefix: Option[String]): (List[CompletionInfo], Int) def typeAt(code: String, caretOffset: Int): String def activateTw(): Unit def activateVn(): Unit @@ -49,6 +44,7 @@ object Interpreter { val IR = Results } + trait Interpreter { import Interpreter._ def bind(name: String, boundType: String, value: Any): IR.Result diff --git a/src/main/scala/net/kogics/kojo/core/history.scala b/src/main/scala/net/kogics/kojo/core/history.scala index 8cfa978b3..0c4124853 100644 --- a/src/main/scala/net/kogics/kojo/core/history.scala +++ b/src/main/scala/net/kogics/kojo/core/history.scala @@ -3,19 +3,18 @@ package net.kogics.kojo.core import java.util.Date case class HistoryItem( - script: String, - file: String = "", - var id: Long = 0, - var starred: Boolean = false, - var tags: String = "", - at: Date = new Date -) + script: String, + file: String = "", + var id: Long = 0, + var starred: Boolean = false, + var tags: String = "", + at: Date = new Date) trait HistoryListener { def itemAdded: Unit def selectionChanged(n: Int): Unit def ensureVisible(n: Int): Unit - def historyReady(): Unit + def historyReady(): Unit } trait HistorySaver { diff --git a/src/main/scala/net/kogics/kojo/core/music.scala b/src/main/scala/net/kogics/kojo/core/music.scala index 2200f0a44..bc5e64809 100644 --- a/src/main/scala/net/kogics/kojo/core/music.scala +++ b/src/main/scala/net/kogics/kojo/core/music.scala @@ -15,7 +15,7 @@ package net.kogics.kojo.core -import org.jfugue.{ Rhythm => JFRhythm, _ } +import org.jfugue.{Rhythm => JFRhythm, _} trait Voice { def pattern(n: Int): Pattern @@ -42,18 +42,17 @@ case class Rhythm(instrument: String, duration: String, beat: String) extends Vo } def beatChar(b: String): Char = { - b.find { c => c != '.' }.get + b.find {c => c != '.'}.get } } -case class Score(voices: Voice*) extends Voice { +case class Score(voices: Voice *) extends Voice { def pattern(n: Int): Pattern = { val score = new Pattern() var idx = 0 val rhy = new JFRhythm() var rLayer = 1 - voices.foreach { voice => - voice match { + voices.foreach { voice => voice match { case Melody(i, m) => val p = new Pattern("V%d I[%s] %s".format(idx, i, m)) score.add(p, n) @@ -64,9 +63,9 @@ case class Score(voices: Voice*) extends Voice { rhy.addSubstitution('.', "R%s".format(d)) rLayer += 1 } - idx += 1 + idx += 1 } score.add(rhy.getPattern, n) score } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/core/shapes.scala b/src/main/scala/net/kogics/kojo/core/shapes.scala index ef1511f63..4c0bbc3e6 100644 --- a/src/main/scala/net/kogics/kojo/core/shapes.scala +++ b/src/main/scala/net/kogics/kojo/core/shapes.scala @@ -47,7 +47,7 @@ class Point(val x: Double, val y: Double) { override def hashCode: Int = 41 * (41 + x.hashCode) + y.hashCode override def equals(other: Any) = other match { case that: Point => - (that.canEqual(this)) && (this.x == that.x) && (this.y == that.y) + (that canEqual this) && (this.x == that.x) && (this.y == that.y) case _ => false } @@ -56,7 +56,7 @@ class Point(val x: Double, val y: Double) { class Line(val p1: Point, val p2: Point) //class LineSegment(p1: Point, p2: Point) extends Line(p1, p2) class Ellipse(val center: Point, val w: Double, val h: Double) -class Circle(center: Point, val radius: Double) extends Ellipse(center, 2 * radius, 2 * radius) +class Circle(center: Point, val radius: Double) extends Ellipse(center, 2*radius, 2*radius) class Arc(val onEll: Ellipse, val start: Double, val extent: Double) class Angle(val size: Double) class Text(val content: String) @@ -67,10 +67,9 @@ class Rectangle(val bLeft: Point, val tRight: Point) { override def toString = "Rectangle(%.2f , %.2f , %.2f , %.2f)".format(bLeft.x, bLeft.y, tRight.x, tRight.y) } class RoundRectangle( - override val bLeft: Point, - override val tRight: Point, - rx: Double, - ry: Double + override val bLeft: Point, + override val tRight: Point, + rx: Double, ry: Double ) extends Rectangle(bLeft, tRight) // class Square(bLeft: Point, tRight: Point) extends Rectangle(bLeft, tRight diff --git a/src/main/scala/net/kogics/kojo/core/unitlen.scala b/src/main/scala/net/kogics/kojo/core/unitlen.scala index d1ddf9e80..1f33bf603 100644 --- a/src/main/scala/net/kogics/kojo/core/unitlen.scala +++ b/src/main/scala/net/kogics/kojo/core/unitlen.scala @@ -4,3 +4,4 @@ abstract class UnitLen case object Pixel extends UnitLen case object Cm extends UnitLen case object Inch extends UnitLen + diff --git a/src/main/scala/net/kogics/kojo/core/vertexShapeSupport.scala b/src/main/scala/net/kogics/kojo/core/vertexShapeSupport.scala index f4825f179..88fcece63 100644 --- a/src/main/scala/net/kogics/kojo/core/vertexShapeSupport.scala +++ b/src/main/scala/net/kogics/kojo/core/vertexShapeSupport.scala @@ -2,35 +2,18 @@ package net.kogics.kojo.core import java.awt.geom.GeneralPath +import processing.core.PMatrix3D + import scala.collection.mutable.ArrayBuffer import scala.language.implicitConversions -import processing.core.PMatrix3D - object VertexShapeSupport { val curveTightness = 0f val bezierBasisMatrix = new PMatrix3D(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0) val s = curveTightness val curveBasisMatrix = new PMatrix3D - curveBasisMatrix.set( - (s - 1) / 2f, - (s + 3) / 2f, - (-3 - s) / 2f, - (1 - s) / 2f, - 1 - s, - (-5 - s) / 2f, - s + 2, - (s - 1) / 2f, - (s - 1) / 2f, - 0, - (1 - s) / 2f, - 0, - 0, - 1, - 0, - 0 - ) + curveBasisMatrix.set((s - 1) / 2f, (s + 3) / 2f, (-3 - s) / 2f, (1 - s) / 2f, 1 - s, (-5 - s) / 2f, s + 2, (s - 1) / 2f, (s - 1) / 2f, 0, (1 - s) / 2f, 0, 0, 1, 0, 0) val bezierBasisInverse = bezierBasisMatrix.get bezierBasisInverse.invert @@ -48,8 +31,7 @@ trait VertexShapeSupport { private case class Vertex(x: Double, y: Double) extends ShapeVertex private case class CurveVertex(x: Double, y: Double) extends ShapeVertex private case class QuadVertex(x1: Double, y1: Double, x2: Double, y2: Double) extends ShapeVertex - private case class BezierVertex(x1: Double, y1: Double, x2: Double, y2: Double, x3: Double, y3: Double) - extends ShapeVertex + private case class BezierVertex(x1: Double, y1: Double, x2: Double, y2: Double, x3: Double, y3: Double) extends ShapeVertex private var shapeVertices: collection.mutable.ArrayBuffer[ShapeVertex] = _ private var curveCoordX: Array[Float] = _ @@ -111,17 +93,7 @@ trait VertexShapeSupport { curveVertex(p.x, p.y) } - private def curveVertexSegment( - gpath: GeneralPath, - x1: Float, - y1: Float, - x2: Float, - y2: Float, - x3: Float, - y3: Float, - x4: Float, - y4: Float - ): Unit = { + private def curveVertexSegment(gpath: GeneralPath, x1: Float, y1: Float, x2: Float, y2: Float, x3: Float, y3: Float, x4: Float, y4: Float): Unit = { import VertexShapeSupport.curveToBezierMatrix curveInit @@ -169,14 +141,10 @@ trait VertexShapeSupport { if (cvlen > 3) { curveVertexSegment( tempPath, - curveVertices(cvlen - 4).x.toFloat, - curveVertices(cvlen - 4).y.toFloat, - curveVertices(cvlen - 3).x.toFloat, - curveVertices(cvlen - 3).y.toFloat, - curveVertices(cvlen - 2).x.toFloat, - curveVertices(cvlen - 2).y.toFloat, - curveVertices(cvlen - 1).x.toFloat, - curveVertices(cvlen - 1).y.toFloat + curveVertices(cvlen - 4).x.toFloat, curveVertices(cvlen - 4).y.toFloat, + curveVertices(cvlen - 3).x.toFloat, curveVertices(cvlen - 3).y.toFloat, + curveVertices(cvlen - 2).x.toFloat, curveVertices(cvlen - 2).y.toFloat, + curveVertices(cvlen - 1).x.toFloat, curveVertices(cvlen - 1).y.toFloat ) } case QuadVertex(x1, y1, x2, y2) => diff --git a/src/main/scala/net/kogics/kojo/doodle/Angle.scala b/src/main/scala/net/kogics/kojo/doodle/Angle.scala index 9caa576c6..57be89397 100644 --- a/src/main/scala/net/kogics/kojo/doodle/Angle.scala +++ b/src/main/scala/net/kogics/kojo/doodle/Angle.scala @@ -1,7 +1,8 @@ // Borrowed from: https://github.com/underscoreio/doodle package net.kogics.kojo.doodle -/** An angle in radians +/** + * An angle in radians */ final class Angle(val toRadians: Double) { def +(that: Angle): Angle = @@ -60,7 +61,7 @@ final class Angle(val toRadians: Double) { new Angle(toRadians) override def equals(that: Any): Boolean = - that.isInstanceOf[Angle] && that.asInstanceOf[Angle].toRadians == this.toRadians + (that.isInstanceOf[Angle] && that.asInstanceOf[Angle].toRadians == this.toRadians) override def hashCode: Int = this.toRadians.hashCode @@ -68,8 +69,8 @@ final class Angle(val toRadians: Double) { object Angle { val TwoPi = math.Pi * 2 - val zero = Angle(0.0) - val one = Angle(TwoPi) + val zero = Angle(0.0) + val one = Angle(TwoPi) def degrees(deg: Double): Angle = Angle(deg * TwoPi / 360.0) @@ -77,7 +78,9 @@ object Angle { def radians(rad: Double): Angle = Angle(rad) - /** A turn represents angle as a proportion of a full turn around a circle, with a full turn being 1.0 + /** + * A turn represents angle as a proportion of a full turn around a + * circle, with a full turn being 1.0 */ def turns(t: Double): Angle = Angle(t * TwoPi) diff --git a/src/main/scala/net/kogics/kojo/doodle/Color.scala b/src/main/scala/net/kogics/kojo/doodle/Color.scala index 87f6b59f1..410ec9ae7 100644 --- a/src/main/scala/net/kogics/kojo/doodle/Color.scala +++ b/src/main/scala/net/kogics/kojo/doodle/Color.scala @@ -1,21 +1,22 @@ // Borrowed from: https://github.com/underscoreio/doodle package net.kogics.kojo.doodle -import java.awt.{ Color => AwtColor } -import java.awt.geom.Rectangle2D import java.awt.GradientPaint import java.awt.LinearGradientPaint import java.awt.MultipleGradientPaint import java.awt.RadialGradientPaint import java.awt.TexturePaint +import java.awt.geom.Rectangle2D +import java.awt.{Color => AwtColor} import scala.collection.mutable.ArrayBuffer +import org.hsluv.HUSLColorConverter + import net.kogics.kojo.syntax.angle._ import net.kogics.kojo.syntax.normalized._ import net.kogics.kojo.syntax.uByte._ import net.kogics.kojo.util.Utils -import org.hsluv.HUSLColorConverter sealed abstract class Color extends Product with Serializable { @@ -47,19 +48,19 @@ sealed abstract class Color extends Product with Serializable { // Color manipulation ------------------------------------ - /** Copies this color, changing the hue to the given value */ + /** Copies this color, changing the hue to the given value*/ def hue(angle: Double): Color = this.toHSLA.copy(h = angle.degrees) - /** Copies this color, changing the saturation to the given value */ + /** Copies this color, changing the saturation to the given value*/ def saturation(s: Double): Color = this.toHSLA.copy(s = s.normalized) - /** Copies this color, changing the lightness to the given value */ + /** Copies this color, changing the lightness to the given value*/ def lightness(l: Double): Color = this.toHSLA.copy(l = l.normalized) - /** Copies this color, changing the alpha to the given value */ + /** Copies this color, changing the alpha to the given value*/ def alpha(a: Double): Color = this.toHSLA.copy(a = a.normalized) @@ -75,33 +76,41 @@ sealed abstract class Color extends Product with Serializable { original.copy(h = original.h + Angle.turns(turnFactor)) } - /** Saturate the color by the given amount. This is an absolute amount, not an amount relative to the Color's current - * saturation. Saturation is clipped at Normalized.MaxValue - */ + /** + * Saturate the color by the given amount. This is an absolute + * amount, not an amount relative to the Color's current + * saturation. Saturation is clipped at Normalized.MaxValue + */ def saturate(saturation: Double) = { val original = this.toHSLA original.copy(s = Normalized.clip(original.s + saturation.normalized)) } - /** Desaturate the color by the given amount. This is an absolute amount, not an amount relative to the Color's - * current saturation. Saturation is clipped at Normalized.MaxValue - */ + /** + * Desaturate the color by the given amount. This is an absolute + * amount, not an amount relative to the Color's current + * saturation. Saturation is clipped at Normalized.MaxValue + */ def desaturate(desaturation: Double) = { val original = this.toHSLA original.copy(s = Normalized.clip(original.s - desaturation.normalized)) } - /** Lighten the color by the given amount. This is an absolute amount, not an amount relative to the Color's current - * lightness. Lightness is clipped at Normalized.MaxValue - */ + /** + * Lighten the color by the given amount. This is an absolute + * amount, not an amount relative to the Color's current + * lightness. Lightness is clipped at Normalized.MaxValue + */ def lighten(lightness: Double) = { val original = this.toHSLA original.copy(l = Normalized.clip(original.l + lightness.normalized)) } - /** Darken the color by the given amount. This is an absolute amount, not an amount relative to the Color's current - * lightness. Lightness is clipped at Normalized.MaxValue - */ + /** + * Darken the color by the given amount. This is an absolute + * amount, not an amount relative to the Color's current + * lightness. Lightness is clipped at Normalized.MaxValue + */ def darken(darkness: Double) = { val original = this.toHSLA original.copy(l = Normalized.clip(original.l - darkness.normalized)) @@ -119,33 +128,41 @@ sealed abstract class Color extends Product with Serializable { original.copy(a = Normalized.clip(original.a - opacity.normalized)) } - /** Saturate the color by the given *relative* amount. For example, calling `aColor.saturateBy(0.1.normalized` - * increases the saturation by 10% of the current saturation. - */ + /** + * Saturate the color by the given *relative* amount. For example, calling + * `aColor.saturateBy(0.1.normalized` increases the saturation by 10% of the + * current saturation. + */ def saturateBy(saturation: Double) = { val original = this.toHSLA original.copy(s = Normalized.clip(original.s.get * (1 + saturation))) } - /** Desaturate the color by the given *relative* amount. For example, calling `aColor.desaturateBy(0.1.normalized` - * decreases the saturation by 10% of the current saturation. - */ + /** + * Desaturate the color by the given *relative* amount. For example, calling + * `aColor.desaturateBy(0.1.normalized` decreases the saturation by 10% of the + * current saturation. + */ def desaturateBy(desaturation: Double) = { val original = this.toHSLA original.copy(s = Normalized.clip(original.s.get * (1 - desaturation))) } - /** Lighten the color by the given *relative* amount. For example, calling `aColor.lightenBy(0.1.normalized` increases - * the lightness by 10% of the current lightness. - */ + /** + * Lighten the color by the given *relative* amount. For example, calling + * `aColor.lightenBy(0.1.normalized` increases the lightness by 10% of the + * current lightness. + */ def lightenBy(lightness: Double) = { val original = this.toHSLA original.copy(l = Normalized.clip(original.l.get * (1 + lightness))) } - /** Darken the color by the given *relative* amount. For example, calling `aColor.darkenBy(0.1.normalized` decreases - * the lightness by 10% of the current lightness. - */ + /** + * Darken the color by the given *relative* amount. For example, calling + * `aColor.darkenBy(0.1.normalized` decreases the lightness by 10% of the + * current lightness. + */ def darkenBy(darkness: Double) = { val original = this.toHSLA original.copy(l = Normalized.clip(original.l.get * (1 - darkness))) @@ -170,9 +187,9 @@ sealed abstract class Color extends Product with Serializable { (this.toRGBA, that.toRGBA) match { case (RGBA(r1, g1, b1, a1), RGBA(r2, g2, b2, a2)) => Math.abs(r1 - r2) < 2 && - Math.abs(g1 - g2) < 2 && - Math.abs(b1 - b2) < 2 && - Math.abs(a1 - a2) < 0.1 + Math.abs(g1 - g2) < 2 && + Math.abs(b1 - b2) < 2 && + Math.abs(a1 - a2) < 0.1 } def toCanvas: String = @@ -206,13 +223,13 @@ sealed abstract class Color extends Product with Serializable { val rNormalized = r.toNormalized val gNormalized = g.toNormalized val bNormalized = b.toNormalized - val cMax = rNormalized.max(gNormalized).max(bNormalized) - val cMin = rNormalized.min(gNormalized).min(bNormalized) + val cMax = rNormalized max gNormalized max bNormalized + val cMin = rNormalized min gNormalized min bNormalized val delta = cMax - cMin val unnormalizedHue = if (cMax == rNormalized) - 60 * ((gNormalized - bNormalized) / delta) + 60 * (((gNormalized - bNormalized) / delta)) else if (cMax == gNormalized) 60 * (((bNormalized - rNormalized) / delta) + 2) else @@ -283,37 +300,16 @@ object Color extends CommonColors { rgba(red, green, blue, 255) def hsla(hueAngle: Double, saturationFraction: Double, lightnessFraction: Double, opacityFraction: Double): Color = - HSLA( - Angle.degrees(hueAngle), - saturationFraction.normalized, - lightnessFraction.normalized, - opacityFraction.normalized - ) + HSLA(Angle.degrees(hueAngle), saturationFraction.normalized, lightnessFraction.normalized, opacityFraction.normalized) def hsl(hueAngle: Double, saturationFraction: Double, lightnessFraction: Double): Color = hsla(hueAngle, saturationFraction, lightnessFraction, 1.0) - def linearGradient( - x1: Double, - y1: Double, - c1: AwtColor, - x2: Double, - y2: Double, - c2: AwtColor, - cyclic: Boolean = false - ): GradientPaint = + def linearGradient(x1: Double, y1: Double, c1: AwtColor, x2: Double, y2: Double, c2: AwtColor, cyclic: Boolean = false): GradientPaint = new GradientPaint(x1.toFloat, y1.toFloat, c1, x2.toFloat, y2.toFloat, c2, cyclic) - def radialMultipleGradient( - x: Double, - y: Double, - radius: Double, - distribution: collection.Seq[Double], - colors: collection.Seq[AwtColor], - cyclic: Boolean = false - ) = { - val cycleMode = - if (cyclic) MultipleGradientPaint.CycleMethod.REFLECT else MultipleGradientPaint.CycleMethod.NO_CYCLE + def radialMultipleGradient(x: Double, y: Double, radius: Double, distribution: collection.Seq[Double], colors: collection.Seq[AwtColor], cyclic: Boolean = false) = { + val cycleMode = if (cyclic) MultipleGradientPaint.CycleMethod.REFLECT else MultipleGradientPaint.CycleMethod.NO_CYCLE val floatD = ArrayBuffer.empty[Float]; distribution.foreach { n => floatD.append(n.toFloat) } new RadialGradientPaint(x.toFloat, y.toFloat, radius.toFloat, floatD.toArray, colors.toArray, cycleMode) } @@ -321,17 +317,8 @@ object Color extends CommonColors { def radialGradient(cx: Double, cy: Double, c1: AwtColor, radius: Double, c2: AwtColor, cyclic: Boolean = false) = radialMultipleGradient(cx, cy, radius, Seq(0, 1), Seq(c1, c2), cyclic) - def linearMultipleGradient( - x1: Double, - y1: Double, - x2: Double, - y2: Double, - distribution: collection.Seq[Double], - colors: collection.Seq[AwtColor], - cyclic: Boolean = false - ) = { - val cycleMode = - if (cyclic) MultipleGradientPaint.CycleMethod.REFLECT else MultipleGradientPaint.CycleMethod.NO_CYCLE + def linearMultipleGradient(x1: Double, y1: Double, x2: Double, y2: Double, distribution: collection.Seq[Double], colors: collection.Seq[AwtColor], cyclic: Boolean = false) = { + val cycleMode = if (cyclic) MultipleGradientPaint.CycleMethod.REFLECT else MultipleGradientPaint.CycleMethod.NO_CYCLE val floatD = ArrayBuffer.empty[Float]; distribution.foreach { n => floatD.append(n.toFloat) } new LinearGradientPaint(x1.toFloat, y1.toFloat, x2.toFloat, y2.toFloat, floatD.toArray, colors.toArray, cycleMode) } @@ -348,12 +335,7 @@ object Color extends CommonColors { val rgbs = HUSLColorConverter.hsluvToRgb(Array(hueAngle, saturationFraction * 100, lightnessFraction * 100)) rgb((rgbs(0) * 255).toInt, (rgbs(1) * 255).toInt, (rgbs(2) * 255).toInt) } - def hsluva( - hueAngle: Double, - saturationFraction: Double, - lightnessFraction: Double, - opacityFraction: Double - ): Color = { + def hsluva(hueAngle: Double, saturationFraction: Double, lightnessFraction: Double, opacityFraction: Double): Color = { val rgbs = HUSLColorConverter.hsluvToRgb(Array(hueAngle, saturationFraction * 100, lightnessFraction * 100)) rgba((rgbs(0) * 255).toInt, (rgbs(1) * 255).toInt, (rgbs(2) * 255).toInt, (opacityFraction * 255).toInt) } diff --git a/src/main/scala/net/kogics/kojo/doodle/ColorMap.scala b/src/main/scala/net/kogics/kojo/doodle/ColorMap.scala index 1bed5ed6c..b4b3ee4f0 100644 --- a/src/main/scala/net/kogics/kojo/doodle/ColorMap.scala +++ b/src/main/scala/net/kogics/kojo/doodle/ColorMap.scala @@ -152,4 +152,4 @@ object ColorMap { "yellow" -> Color.yellow, "yellowGreen" -> Color.yellowGreen ) -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/doodle/CommonColors.scala b/src/main/scala/net/kogics/kojo/doodle/CommonColors.scala index ca50bb823..f19237112 100644 --- a/src/main/scala/net/kogics/kojo/doodle/CommonColors.scala +++ b/src/main/scala/net/kogics/kojo/doodle/CommonColors.scala @@ -4,153 +4,153 @@ package net.kogics.kojo.doodle import net.kogics.kojo.syntax.uByte._ trait CommonColors { - val aliceBlue = Color.rgb(0xf0.uByte, 0xf8.uByte, 0xff.uByte) - val antiqueWhite = Color.rgb(0xfa.uByte, 0xeb.uByte, 0xd7.uByte) - val aqua = Color.rgb(0x00.uByte, 0xff.uByte, 0xff.uByte) - val aquamarine = Color.rgb(0x7f.uByte, 0xff.uByte, 0xd4.uByte) - val azure = Color.rgb(0xf0.uByte, 0xff.uByte, 0xff.uByte) - val beige = Color.rgb(0xf5.uByte, 0xf5.uByte, 0xdc.uByte) - val bisque = Color.rgb(0xff.uByte, 0xe4.uByte, 0xc4.uByte) - val black = Color.rgb(0x00.uByte, 0x00.uByte, 0x00.uByte) - val blanchedAlmond = Color.rgb(0xff.uByte, 0xeb.uByte, 0xcd.uByte) - val blue = Color.rgb(0x00.uByte, 0x00.uByte, 0xff.uByte) - val blueViolet = Color.rgb(0x8a.uByte, 0x2b.uByte, 0xe2.uByte) - val brown = Color.rgb(0xa5.uByte, 0x2a.uByte, 0x2a.uByte) - val burlyWood = Color.rgb(0xde.uByte, 0xb8.uByte, 0x87.uByte) - val cadetBlue = Color.rgb(0x5f.uByte, 0x9e.uByte, 0xa0.uByte) - val chartReuse = Color.rgb(0x7f.uByte, 0xff.uByte, 0x00.uByte) - val chocolate = Color.rgb(0xd2.uByte, 0x69.uByte, 0x1e.uByte) - val coral = Color.rgb(0xff.uByte, 0x7f.uByte, 0x50.uByte) - val cornflowerBlue = Color.rgb(0x64.uByte, 0x95.uByte, 0xed.uByte) - val cornSilk = Color.rgb(0xff.uByte, 0xf8.uByte, 0xdc.uByte) - val crimson = Color.rgb(0xdc.uByte, 0x14.uByte, 0x3c.uByte) - val cyan = Color.rgb(0x00.uByte, 0xff.uByte, 0xff.uByte) - val darkBlue = Color.rgb(0x00.uByte, 0x00.uByte, 0x8b.uByte) - val darkCyan = Color.rgb(0x00.uByte, 0x8b.uByte, 0x8b.uByte) - val darkGoldenrod = Color.rgb(0xb8.uByte, 0x86.uByte, 0x0b.uByte) - val darkGray = Color.rgb(0xa9.uByte, 0xa9.uByte, 0xa9.uByte) - val darkGrey = Color.rgb(0xa9.uByte, 0xa9.uByte, 0xa9.uByte) - val darkGrayClassic = Color.rgb(0x40.uByte, 0x40.uByte, 0x40.uByte) - val darkGreyClassic = Color.rgb(0x40.uByte, 0x40.uByte, 0x40.uByte) - val darkGreen = Color.rgb(0x00.uByte, 0x64.uByte, 0x00.uByte) - val darkKhaki = Color.rgb(0xbd.uByte, 0xb7.uByte, 0x6b.uByte) - val darkMagenta = Color.rgb(0x8b.uByte, 0x00.uByte, 0x8b.uByte) - val darkOliveGreen = Color.rgb(0x55.uByte, 0x6b.uByte, 0x2f.uByte) - val darkOrange = Color.rgb(0xff.uByte, 0x8c.uByte, 0x00.uByte) - val darkOrchid = Color.rgb(0x99.uByte, 0x32.uByte, 0xcc.uByte) - val darkRed = Color.rgb(0x8b.uByte, 0x00.uByte, 0x00.uByte) - val darkSalmon = Color.rgb(0xe9.uByte, 0x96.uByte, 0x7a.uByte) - val darkSeaGreen = Color.rgb(0x8f.uByte, 0xbc.uByte, 0x8f.uByte) - val darkSlateBlue = Color.rgb(0x48.uByte, 0x3d.uByte, 0x8b.uByte) - val darkSlateGray = Color.rgb(0x2f.uByte, 0x4f.uByte, 0x4f.uByte) - val darkSlateGrey = Color.rgb(0x2f.uByte, 0x4f.uByte, 0x4f.uByte) - val darkTurquoise = Color.rgb(0x00.uByte, 0xce.uByte, 0xd1.uByte) - val darkViolet = Color.rgb(0x94.uByte, 0x00.uByte, 0xd3.uByte) - val deepPink = Color.rgb(0xff.uByte, 0x14.uByte, 0x93.uByte) - val deepSkyBlue = Color.rgb(0x00.uByte, 0xbf.uByte, 0xff.uByte) - val dimGray = Color.rgb(0x69.uByte, 0x69.uByte, 0x69.uByte) - val dimGrey = Color.rgb(0x69.uByte, 0x69.uByte, 0x69.uByte) - val dodgerBlue = Color.rgb(0x1e.uByte, 0x90.uByte, 0xff.uByte) - val fireBrick = Color.rgb(0xb2.uByte, 0x22.uByte, 0x22.uByte) - val floralWhite = Color.rgb(0xff.uByte, 0xfa.uByte, 0xf0.uByte) - val forestGreen = Color.rgb(0x22.uByte, 0x8b.uByte, 0x22.uByte) - val fuchsia = Color.rgb(0xff.uByte, 0x00.uByte, 0xff.uByte) - val gainsboro = Color.rgb(0xdc.uByte, 0xdc.uByte, 0xdc.uByte) - val ghostWhite = Color.rgb(0xf8.uByte, 0xf8.uByte, 0xff.uByte) - val gold = Color.rgb(0xff.uByte, 0xd7.uByte, 0x00.uByte) - val goldenrod = Color.rgb(0xda.uByte, 0xa5.uByte, 0x20.uByte) - val gray = Color.rgb(0x80.uByte, 0x80.uByte, 0x80.uByte) - val grey = Color.rgb(0x80.uByte, 0x80.uByte, 0x80.uByte) - val green = Color.rgb(0x00.uByte, 0x80.uByte, 0x00.uByte) - val greenYellow = Color.rgb(0xad.uByte, 0xff.uByte, 0x2f.uByte) - val honeydew = Color.rgb(0xf0.uByte, 0xff.uByte, 0xf0.uByte) - val hotpink = Color.rgb(0xff.uByte, 0x69.uByte, 0xb4.uByte) - val indianRed = Color.rgb(0xcd.uByte, 0x5c.uByte, 0x5c.uByte) - val indigo = Color.rgb(0x4b.uByte, 0x00.uByte, 0x82.uByte) - val ivory = Color.rgb(0xff.uByte, 0xff.uByte, 0xf0.uByte) - val khaki = Color.rgb(0xf0.uByte, 0xe6.uByte, 0x8c.uByte) - val lavender = Color.rgb(0xe6.uByte, 0xe6.uByte, 0xfa.uByte) - val lavenderBlush = Color.rgb(0xff.uByte, 0xf0.uByte, 0xf5.uByte) - val lawngreen = Color.rgb(0x7c.uByte, 0xfc.uByte, 0x00.uByte) - val lemonChiffon = Color.rgb(0xff.uByte, 0xfa.uByte, 0xcd.uByte) - val lightBlue = Color.rgb(0xad.uByte, 0xd8.uByte, 0xe6.uByte) - val lightCoral = Color.rgb(0xf0.uByte, 0x80.uByte, 0x80.uByte) - val lightCyan = Color.rgb(0xe0.uByte, 0xff.uByte, 0xff.uByte) + val aliceBlue = Color.rgb(0xf0.uByte, 0xf8.uByte, 0xff.uByte) + val antiqueWhite = Color.rgb(0xfa.uByte, 0xeb.uByte, 0xd7.uByte) + val aqua = Color.rgb(0x00.uByte, 0xff.uByte, 0xff.uByte) + val aquamarine = Color.rgb(0x7f.uByte, 0xff.uByte, 0xd4.uByte) + val azure = Color.rgb(0xf0.uByte, 0xff.uByte, 0xff.uByte) + val beige = Color.rgb(0xf5.uByte, 0xf5.uByte, 0xdc.uByte) + val bisque = Color.rgb(0xff.uByte, 0xe4.uByte, 0xc4.uByte) + val black = Color.rgb(0x00.uByte, 0x00.uByte, 0x00.uByte) + val blanchedAlmond = Color.rgb(0xff.uByte, 0xeb.uByte, 0xcd.uByte) + val blue = Color.rgb(0x00.uByte, 0x00.uByte, 0xff.uByte) + val blueViolet = Color.rgb(0x8a.uByte, 0x2b.uByte, 0xe2.uByte) + val brown = Color.rgb(0xa5.uByte, 0x2a.uByte, 0x2a.uByte) + val burlyWood = Color.rgb(0xde.uByte, 0xb8.uByte, 0x87.uByte) + val cadetBlue = Color.rgb(0x5f.uByte, 0x9e.uByte, 0xa0.uByte) + val chartReuse = Color.rgb(0x7f.uByte, 0xff.uByte, 0x00.uByte) + val chocolate = Color.rgb(0xd2.uByte, 0x69.uByte, 0x1e.uByte) + val coral = Color.rgb(0xff.uByte, 0x7f.uByte, 0x50.uByte) + val cornflowerBlue = Color.rgb(0x64.uByte, 0x95.uByte, 0xed.uByte) + val cornSilk = Color.rgb(0xff.uByte, 0xf8.uByte, 0xdc.uByte) + val crimson = Color.rgb(0xdc.uByte, 0x14.uByte, 0x3c.uByte) + val cyan = Color.rgb(0x00.uByte, 0xff.uByte, 0xff.uByte) + val darkBlue = Color.rgb(0x00.uByte, 0x00.uByte, 0x8b.uByte) + val darkCyan = Color.rgb(0x00.uByte, 0x8b.uByte, 0x8b.uByte) + val darkGoldenrod = Color.rgb(0xb8.uByte, 0x86.uByte, 0x0b.uByte) + val darkGray = Color.rgb(0xa9.uByte, 0xa9.uByte, 0xa9.uByte) + val darkGrey = Color.rgb(0xa9.uByte, 0xa9.uByte, 0xa9.uByte) + val darkGrayClassic = Color.rgb(0x40.uByte, 0x40.uByte, 0x40.uByte) + val darkGreyClassic = Color.rgb(0x40.uByte, 0x40.uByte, 0x40.uByte) + val darkGreen = Color.rgb(0x00.uByte, 0x64.uByte, 0x00.uByte) + val darkKhaki = Color.rgb(0xbd.uByte, 0xb7.uByte, 0x6b.uByte) + val darkMagenta = Color.rgb(0x8b.uByte, 0x00.uByte, 0x8b.uByte) + val darkOliveGreen = Color.rgb(0x55.uByte, 0x6b.uByte, 0x2f.uByte) + val darkOrange = Color.rgb(0xff.uByte, 0x8c.uByte, 0x00.uByte) + val darkOrchid = Color.rgb(0x99.uByte, 0x32.uByte, 0xcc.uByte) + val darkRed = Color.rgb(0x8b.uByte, 0x00.uByte, 0x00.uByte) + val darkSalmon = Color.rgb(0xe9.uByte, 0x96.uByte, 0x7a.uByte) + val darkSeaGreen = Color.rgb(0x8f.uByte, 0xbc.uByte, 0x8f.uByte) + val darkSlateBlue = Color.rgb(0x48.uByte, 0x3d.uByte, 0x8b.uByte) + val darkSlateGray = Color.rgb(0x2f.uByte, 0x4f.uByte, 0x4f.uByte) + val darkSlateGrey = Color.rgb(0x2f.uByte, 0x4f.uByte, 0x4f.uByte) + val darkTurquoise = Color.rgb(0x00.uByte, 0xce.uByte, 0xd1.uByte) + val darkViolet = Color.rgb(0x94.uByte, 0x00.uByte, 0xd3.uByte) + val deepPink = Color.rgb(0xff.uByte, 0x14.uByte, 0x93.uByte) + val deepSkyBlue = Color.rgb(0x00.uByte, 0xbf.uByte, 0xff.uByte) + val dimGray = Color.rgb(0x69.uByte, 0x69.uByte, 0x69.uByte) + val dimGrey = Color.rgb(0x69.uByte, 0x69.uByte, 0x69.uByte) + val dodgerBlue = Color.rgb(0x1e.uByte, 0x90.uByte, 0xff.uByte) + val fireBrick = Color.rgb(0xb2.uByte, 0x22.uByte, 0x22.uByte) + val floralWhite = Color.rgb(0xff.uByte, 0xfa.uByte, 0xf0.uByte) + val forestGreen = Color.rgb(0x22.uByte, 0x8b.uByte, 0x22.uByte) + val fuchsia = Color.rgb(0xff.uByte, 0x00.uByte, 0xff.uByte) + val gainsboro = Color.rgb(0xdc.uByte, 0xdc.uByte, 0xdc.uByte) + val ghostWhite = Color.rgb(0xf8.uByte, 0xf8.uByte, 0xff.uByte) + val gold = Color.rgb(0xff.uByte, 0xd7.uByte, 0x00.uByte) + val goldenrod = Color.rgb(0xda.uByte, 0xa5.uByte, 0x20.uByte) + val gray = Color.rgb(0x80.uByte, 0x80.uByte, 0x80.uByte) + val grey = Color.rgb(0x80.uByte, 0x80.uByte, 0x80.uByte) + val green = Color.rgb(0x00.uByte, 0x80.uByte, 0x00.uByte) + val greenYellow = Color.rgb(0xad.uByte, 0xff.uByte, 0x2f.uByte) + val honeydew = Color.rgb(0xf0.uByte, 0xff.uByte, 0xf0.uByte) + val hotpink = Color.rgb(0xff.uByte, 0x69.uByte, 0xb4.uByte) + val indianRed = Color.rgb(0xcd.uByte, 0x5c.uByte, 0x5c.uByte) + val indigo = Color.rgb(0x4b.uByte, 0x00.uByte, 0x82.uByte) + val ivory = Color.rgb(0xff.uByte, 0xff.uByte, 0xf0.uByte) + val khaki = Color.rgb(0xf0.uByte, 0xe6.uByte, 0x8c.uByte) + val lavender = Color.rgb(0xe6.uByte, 0xe6.uByte, 0xfa.uByte) + val lavenderBlush = Color.rgb(0xff.uByte, 0xf0.uByte, 0xf5.uByte) + val lawngreen = Color.rgb(0x7c.uByte, 0xfc.uByte, 0x00.uByte) + val lemonChiffon = Color.rgb(0xff.uByte, 0xfa.uByte, 0xcd.uByte) + val lightBlue = Color.rgb(0xad.uByte, 0xd8.uByte, 0xe6.uByte) + val lightCoral = Color.rgb(0xf0.uByte, 0x80.uByte, 0x80.uByte) + val lightCyan = Color.rgb(0xe0.uByte, 0xff.uByte, 0xff.uByte) val lightGoldenrodYellow = Color.rgb(0xfa.uByte, 0xfa.uByte, 0xd2.uByte) - val lightGray = Color.rgb(0xd3.uByte, 0xd3.uByte, 0xd3.uByte) - val lightGrey = Color.rgb(0xd3.uByte, 0xd3.uByte, 0xd3.uByte) - val lightGreen = Color.rgb(0x90.uByte, 0xee.uByte, 0x90.uByte) - val lightPink = Color.rgb(0xff.uByte, 0xb6.uByte, 0xc1.uByte) - val lightSalmon = Color.rgb(0xff.uByte, 0xa0.uByte, 0x7a.uByte) - val lightSeaGreen = Color.rgb(0x20.uByte, 0xb2.uByte, 0xaa.uByte) - val lightSkyBlue = Color.rgb(0x87.uByte, 0xce.uByte, 0xfa.uByte) - val lightSlateGray = Color.rgb(0x77.uByte, 0x88.uByte, 0x99.uByte) - val lightSlateGrey = Color.rgb(0x77.uByte, 0x88.uByte, 0x99.uByte) - val lightSteelBlue = Color.rgb(0xb0.uByte, 0xc4.uByte, 0xde.uByte) - val lightYellow = Color.rgb(0xff.uByte, 0xff.uByte, 0xe0.uByte) - val lime = Color.rgb(0x00.uByte, 0xff.uByte, 0x00.uByte) - val limeGreen = Color.rgb(0x32.uByte, 0xcd.uByte, 0x32.uByte) - val linen = Color.rgb(0xfa.uByte, 0xf0.uByte, 0xe6.uByte) - val magenta = Color.rgb(0xff.uByte, 0x00.uByte, 0xff.uByte) - val maroon = Color.rgb(0x80.uByte, 0x00.uByte, 0x00.uByte) - val mediumAquamarine = Color.rgb(0x66.uByte, 0xcd.uByte, 0xaa.uByte) - val mediumBlue = Color.rgb(0x00.uByte, 0x00.uByte, 0xcd.uByte) - val mediumOrchid = Color.rgb(0xba.uByte, 0x55.uByte, 0xd3.uByte) - val mediumPurple = Color.rgb(0x93.uByte, 0x70.uByte, 0xd8.uByte) - val mediumSeaGreen = Color.rgb(0x3c.uByte, 0xb3.uByte, 0x71.uByte) - val mediumSlateBlue = Color.rgb(0x7b.uByte, 0x68.uByte, 0xee.uByte) - val mediumSpringGreen = Color.rgb(0x00.uByte, 0xfa.uByte, 0x9a.uByte) - val mediumTurquoise = Color.rgb(0x48.uByte, 0xd1.uByte, 0xcc.uByte) - val mediumVioletRed = Color.rgb(0xc7.uByte, 0x15.uByte, 0x85.uByte) - val midnightBlue = Color.rgb(0x19.uByte, 0x19.uByte, 0x70.uByte) - val mintCream = Color.rgb(0xf5.uByte, 0xff.uByte, 0xfa.uByte) - val mistyRose = Color.rgb(0xff.uByte, 0xe4.uByte, 0xe1.uByte) - val moccasin = Color.rgb(0xff.uByte, 0xe4.uByte, 0xb5.uByte) - val navajoWhite = Color.rgb(0xff.uByte, 0xde.uByte, 0xad.uByte) - val navy = Color.rgb(0x00.uByte, 0x00.uByte, 0x80.uByte) - val oldLace = Color.rgb(0xfd.uByte, 0xf5.uByte, 0xe6.uByte) - val olive = Color.rgb(0x80.uByte, 0x80.uByte, 0x00.uByte) - val oliveDrab = Color.rgb(0x6b.uByte, 0x8e.uByte, 0x23.uByte) - val orange = Color.rgb(0xff.uByte, 0xa5.uByte, 0x00.uByte) - val orangeRed = Color.rgb(0xff.uByte, 0x45.uByte, 0x00.uByte) - val orchid = Color.rgb(0xda.uByte, 0x70.uByte, 0xd6.uByte) - val paleGoldenrod = Color.rgb(0xee.uByte, 0xe8.uByte, 0xaa.uByte) - val paleGreen = Color.rgb(0x98.uByte, 0xfb.uByte, 0x98.uByte) - val paleTurquoise = Color.rgb(0xaf.uByte, 0xee.uByte, 0xee.uByte) - val paleVioletRed = Color.rgb(0xd8.uByte, 0x70.uByte, 0x93.uByte) - val papayaWhip = Color.rgb(0xff.uByte, 0xef.uByte, 0xd5.uByte) - val peachPuff = Color.rgb(0xff.uByte, 0xda.uByte, 0xb9.uByte) - val peru = Color.rgb(0xcd.uByte, 0x85.uByte, 0x3f.uByte) - val pink = Color.rgb(0xff.uByte, 0xc0.uByte, 0xcb.uByte) - val plum = Color.rgb(0xdd.uByte, 0xa0.uByte, 0xdd.uByte) - val powderBlue = Color.rgb(0xb0.uByte, 0xe0.uByte, 0xe6.uByte) - val purple = Color.rgb(0x80.uByte, 0x00.uByte, 0x80.uByte) - val red = Color.rgb(0xff.uByte, 0x00.uByte, 0x00.uByte) - val rosyBrown = Color.rgb(0xbc.uByte, 0x8f.uByte, 0x8f.uByte) - val royalBlue = Color.rgb(0x41.uByte, 0x69.uByte, 0xe1.uByte) - val saddleBrown = Color.rgb(0x8b.uByte, 0x45.uByte, 0x13.uByte) - val salmon = Color.rgb(0xfa.uByte, 0x80.uByte, 0x72.uByte) - val sandyBrown = Color.rgb(0xf4.uByte, 0xa4.uByte, 0x60.uByte) - val seaGreen = Color.rgb(0x2e.uByte, 0x8b.uByte, 0x57.uByte) - val seaShell = Color.rgb(0xff.uByte, 0xf5.uByte, 0xee.uByte) - val sienna = Color.rgb(0xa0.uByte, 0x52.uByte, 0x2d.uByte) - val silver = Color.rgb(0xc0.uByte, 0xc0.uByte, 0xc0.uByte) - val skyBlue = Color.rgb(0x87.uByte, 0xce.uByte, 0xeb.uByte) - val slateBlue = Color.rgb(0x6a.uByte, 0x5a.uByte, 0xcd.uByte) - val slateGray = Color.rgb(0x70.uByte, 0x80.uByte, 0x90.uByte) - val slateGrey = Color.rgb(0x70.uByte, 0x80.uByte, 0x90.uByte) - val snow = Color.rgb(0xff.uByte, 0xfa.uByte, 0xfa.uByte) - val springGreen = Color.rgb(0x00.uByte, 0xff.uByte, 0x7f.uByte) - val steelBlue = Color.rgb(0x46.uByte, 0x82.uByte, 0xb4.uByte) - val tan = Color.rgb(0xd2.uByte, 0xb4.uByte, 0x8c.uByte) - val teal = Color.rgb(0x00.uByte, 0x80.uByte, 0x80.uByte) - val thistle = Color.rgb(0xd8.uByte, 0xbf.uByte, 0xd8.uByte) - val tomato = Color.rgb(0xff.uByte, 0x63.uByte, 0x47.uByte) - val turquoise = Color.rgb(0x40.uByte, 0xe0.uByte, 0xd0.uByte) - val violet = Color.rgb(0xee.uByte, 0x82.uByte, 0xee.uByte) - val wheat = Color.rgb(0xf5.uByte, 0xde.uByte, 0xb3.uByte) - val white = Color.rgb(0xff.uByte, 0xff.uByte, 0xff.uByte) - val whiteSmoke = Color.rgb(0xf5.uByte, 0xf5.uByte, 0xf5.uByte) - val yellow = Color.rgb(0xff.uByte, 0xff.uByte, 0x00.uByte) - val yellowGreen = Color.rgb(0x9a.uByte, 0xcd.uByte, 0x33.uByte) + val lightGray = Color.rgb(0xd3.uByte, 0xd3.uByte, 0xd3.uByte) + val lightGrey = Color.rgb(0xd3.uByte, 0xd3.uByte, 0xd3.uByte) + val lightGreen = Color.rgb(0x90.uByte, 0xee.uByte, 0x90.uByte) + val lightPink = Color.rgb(0xff.uByte, 0xb6.uByte, 0xc1.uByte) + val lightSalmon = Color.rgb(0xff.uByte, 0xa0.uByte, 0x7a.uByte) + val lightSeaGreen = Color.rgb(0x20.uByte, 0xb2.uByte, 0xaa.uByte) + val lightSkyBlue = Color.rgb(0x87.uByte, 0xce.uByte, 0xfa.uByte) + val lightSlateGray = Color.rgb(0x77.uByte, 0x88.uByte, 0x99.uByte) + val lightSlateGrey = Color.rgb(0x77.uByte, 0x88.uByte, 0x99.uByte) + val lightSteelBlue = Color.rgb(0xb0.uByte, 0xc4.uByte, 0xde.uByte) + val lightYellow = Color.rgb(0xff.uByte, 0xff.uByte, 0xe0.uByte) + val lime = Color.rgb(0x00.uByte, 0xff.uByte, 0x00.uByte) + val limeGreen = Color.rgb(0x32.uByte, 0xcd.uByte, 0x32.uByte) + val linen = Color.rgb(0xfa.uByte, 0xf0.uByte, 0xe6.uByte) + val magenta = Color.rgb(0xff.uByte, 0x00.uByte, 0xff.uByte) + val maroon = Color.rgb(0x80.uByte, 0x00.uByte, 0x00.uByte) + val mediumAquamarine = Color.rgb(0x66.uByte, 0xcd.uByte, 0xaa.uByte) + val mediumBlue = Color.rgb(0x00.uByte, 0x00.uByte, 0xcd.uByte) + val mediumOrchid = Color.rgb(0xba.uByte, 0x55.uByte, 0xd3.uByte) + val mediumPurple = Color.rgb(0x93.uByte, 0x70.uByte, 0xd8.uByte) + val mediumSeaGreen = Color.rgb(0x3c.uByte, 0xb3.uByte, 0x71.uByte) + val mediumSlateBlue = Color.rgb(0x7b.uByte, 0x68.uByte, 0xee.uByte) + val mediumSpringGreen = Color.rgb(0x00.uByte, 0xfa.uByte, 0x9a.uByte) + val mediumTurquoise = Color.rgb(0x48.uByte, 0xd1.uByte, 0xcc.uByte) + val mediumVioletRed = Color.rgb(0xc7.uByte, 0x15.uByte, 0x85.uByte) + val midnightBlue = Color.rgb(0x19.uByte, 0x19.uByte, 0x70.uByte) + val mintCream = Color.rgb(0xf5.uByte, 0xff.uByte, 0xfa.uByte) + val mistyRose = Color.rgb(0xff.uByte, 0xe4.uByte, 0xe1.uByte) + val moccasin = Color.rgb(0xff.uByte, 0xe4.uByte, 0xb5.uByte) + val navajoWhite = Color.rgb(0xff.uByte, 0xde.uByte, 0xad.uByte) + val navy = Color.rgb(0x00.uByte, 0x00.uByte, 0x80.uByte) + val oldLace = Color.rgb(0xfd.uByte, 0xf5.uByte, 0xe6.uByte) + val olive = Color.rgb(0x80.uByte, 0x80.uByte, 0x00.uByte) + val oliveDrab = Color.rgb(0x6b.uByte, 0x8e.uByte, 0x23.uByte) + val orange = Color.rgb(0xff.uByte, 0xa5.uByte, 0x00.uByte) + val orangeRed = Color.rgb(0xff.uByte, 0x45.uByte, 0x00.uByte) + val orchid = Color.rgb(0xda.uByte, 0x70.uByte, 0xd6.uByte) + val paleGoldenrod = Color.rgb(0xee.uByte, 0xe8.uByte, 0xaa.uByte) + val paleGreen = Color.rgb(0x98.uByte, 0xfb.uByte, 0x98.uByte) + val paleTurquoise = Color.rgb(0xaf.uByte, 0xee.uByte, 0xee.uByte) + val paleVioletRed = Color.rgb(0xd8.uByte, 0x70.uByte, 0x93.uByte) + val papayaWhip = Color.rgb(0xff.uByte, 0xef.uByte, 0xd5.uByte) + val peachPuff = Color.rgb(0xff.uByte, 0xda.uByte, 0xb9.uByte) + val peru = Color.rgb(0xcd.uByte, 0x85.uByte, 0x3f.uByte) + val pink = Color.rgb(0xff.uByte, 0xc0.uByte, 0xcb.uByte) + val plum = Color.rgb(0xdd.uByte, 0xa0.uByte, 0xdd.uByte) + val powderBlue = Color.rgb(0xb0.uByte, 0xe0.uByte, 0xe6.uByte) + val purple = Color.rgb(0x80.uByte, 0x00.uByte, 0x80.uByte) + val red = Color.rgb(0xff.uByte, 0x00.uByte, 0x00.uByte) + val rosyBrown = Color.rgb(0xbc.uByte, 0x8f.uByte, 0x8f.uByte) + val royalBlue = Color.rgb(0x41.uByte, 0x69.uByte, 0xe1.uByte) + val saddleBrown = Color.rgb(0x8b.uByte, 0x45.uByte, 0x13.uByte) + val salmon = Color.rgb(0xfa.uByte, 0x80.uByte, 0x72.uByte) + val sandyBrown = Color.rgb(0xf4.uByte, 0xa4.uByte, 0x60.uByte) + val seaGreen = Color.rgb(0x2e.uByte, 0x8b.uByte, 0x57.uByte) + val seaShell = Color.rgb(0xff.uByte, 0xf5.uByte, 0xee.uByte) + val sienna = Color.rgb(0xa0.uByte, 0x52.uByte, 0x2d.uByte) + val silver = Color.rgb(0xc0.uByte, 0xc0.uByte, 0xc0.uByte) + val skyBlue = Color.rgb(0x87.uByte, 0xce.uByte, 0xeb.uByte) + val slateBlue = Color.rgb(0x6a.uByte, 0x5a.uByte, 0xcd.uByte) + val slateGray = Color.rgb(0x70.uByte, 0x80.uByte, 0x90.uByte) + val slateGrey = Color.rgb(0x70.uByte, 0x80.uByte, 0x90.uByte) + val snow = Color.rgb(0xff.uByte, 0xfa.uByte, 0xfa.uByte) + val springGreen = Color.rgb(0x00.uByte, 0xff.uByte, 0x7f.uByte) + val steelBlue = Color.rgb(0x46.uByte, 0x82.uByte, 0xb4.uByte) + val tan = Color.rgb(0xd2.uByte, 0xb4.uByte, 0x8c.uByte) + val teal = Color.rgb(0x00.uByte, 0x80.uByte, 0x80.uByte) + val thistle = Color.rgb(0xd8.uByte, 0xbf.uByte, 0xd8.uByte) + val tomato = Color.rgb(0xff.uByte, 0x63.uByte, 0x47.uByte) + val turquoise = Color.rgb(0x40.uByte, 0xe0.uByte, 0xd0.uByte) + val violet = Color.rgb(0xee.uByte, 0x82.uByte, 0xee.uByte) + val wheat = Color.rgb(0xf5.uByte, 0xde.uByte, 0xb3.uByte) + val white = Color.rgb(0xff.uByte, 0xff.uByte, 0xff.uByte) + val whiteSmoke = Color.rgb(0xf5.uByte, 0xf5.uByte, 0xf5.uByte) + val yellow = Color.rgb(0xff.uByte, 0xff.uByte, 0x00.uByte) + val yellowGreen = Color.rgb(0x9a.uByte, 0xcd.uByte, 0x33.uByte) } diff --git a/src/main/scala/net/kogics/kojo/doodle/Normalized.scala b/src/main/scala/net/kogics/kojo/doodle/Normalized.scala index e63a32bf2..1766fb419 100644 --- a/src/main/scala/net/kogics/kojo/doodle/Normalized.scala +++ b/src/main/scala/net/kogics/kojo/doodle/Normalized.scala @@ -3,7 +3,8 @@ package net.kogics.kojo.doodle import scala.annotation.tailrec -/** A value in the range [0, 1] +/** + * A value in the range [0, 1] */ final case class Normalized(get: Double) extends AnyVal { def +(that: Normalized): Double = diff --git a/src/main/scala/net/kogics/kojo/doodle/UnsignedByte.scala b/src/main/scala/net/kogics/kojo/doodle/UnsignedByte.scala index b8524009b..d3aecc57f 100644 --- a/src/main/scala/net/kogics/kojo/doodle/UnsignedByte.scala +++ b/src/main/scala/net/kogics/kojo/doodle/UnsignedByte.scala @@ -9,7 +9,7 @@ final case class UnsignedByte(value: Byte) extends AnyVal { this.value - that.value def get: Int = - value + 128 + (value + 128) def toNormalized: Normalized = Normalized.clip(get.toDouble / UnsignedByte.MaxValue.get.toDouble) diff --git a/src/main/scala/net/kogics/kojo/figure/Figure.scala b/src/main/scala/net/kogics/kojo/figure/Figure.scala index d4dd43054..bfd911ee1 100644 --- a/src/main/scala/net/kogics/kojo/figure/Figure.scala +++ b/src/main/scala/net/kogics/kojo/figure/Figure.scala @@ -16,18 +16,15 @@ package net.kogics.kojo package figure -import java.awt.{ List => _, Point => _, _ } -import java.util.concurrent.Future -import java.util.logging.Level -import java.util.logging.Logger - -import core._ import edu.umd.cs.piccolo._ +import edu.umd.cs.piccolo.nodes._ import edu.umd.cs.piccolo.activities.PActivity import edu.umd.cs.piccolo.activities.PActivity.PActivityDelegate -import edu.umd.cs.piccolo.nodes._ -import net.kogics.kojo.util.FutureResult +import java.awt.{Point => _, List => _, _} import net.kogics.kojo.util.Utils +import core._ +import java.util.concurrent.Future +import net.kogics.kojo.util.FutureResult object Figure { def apply(canvas: SCanvas, initX: Double = 0d, initY: Double = 0): Figure = { @@ -42,7 +39,6 @@ class Figure private (canvas: SCanvas, initX: Double, initY: Double) { private val bgLayer = new PLayer private val fgLayer = new PLayer private var currLayer = bgLayer - val Log = Logger.getLogger("FigureAnimator") // if fgLayer is bigger than bgLayer, (re)painting does not happen very cleanly // needs a better fix than the one below @@ -200,10 +196,9 @@ class Figure private (canvas: SCanvas, initX: Double, initY: Double) { } catch { case t: Throwable => - terminate(PActivity.TERMINATE_AND_FINISH) - figAnimations = figAnimations.filter { _ != this } println("Problem: " + t.toString()) - Log.log(Level.WARNING, "GUI Thread Problem", t) + terminate(PActivity.TERMINATE_AND_FINISH) + figAnimations = figAnimations filter { _ != this } } finally { // repaint() @@ -265,3 +260,4 @@ class Figure private (canvas: SCanvas, initX: Double, initY: Double) { stopFn = Some(() => fn) } } + diff --git a/src/main/scala/net/kogics/kojo/gaming/package.scala b/src/main/scala/net/kogics/kojo/gaming/package.scala index a1bc00807..923b28762 100644 --- a/src/main/scala/net/kogics/kojo/gaming/package.scala +++ b/src/main/scala/net/kogics/kojo/gaming/package.scala @@ -15,10 +15,7 @@ */ package net.kogics.kojo -import net.kogics.kojo.core.Picture -import net.kogics.kojo.core.Point -import net.kogics.kojo.core.SCanvas -import net.kogics.kojo.util.Utils +import net.kogics.kojo.core.{Picture, Point, SCanvas} package object gaming { trait GameMsgSink[Msg] { @@ -27,7 +24,7 @@ package object gaming { def triggerUpdate(msg: Msg): Unit } - trait Sub[+Msg] + trait Sub[Msg] trait NonTimerSub[Msg] extends Sub[Msg] { def activate(gameMsgSink: GameMsgSink[Msg]): Unit @@ -69,10 +66,9 @@ package object gaming { case class OnMouseClick[Msg](mapper: Point => Msg)(implicit canvas: SCanvas) extends NonTimerSub[Msg] { def activate(gameMsgSink: GameMsgSink[Msg]): Unit = { - canvas.onMouseClick { - case (x, y) => - val msg = mapper(Point(x, y)) - gameMsgSink.triggerUpdate(msg) + canvas.onMouseClick { case (x, y) => + val msg = mapper(Point(x, y)) + gameMsgSink.triggerUpdate(msg) } } @@ -91,23 +87,18 @@ package object gaming { def onMouseClick[Msg](mapper: Point => Msg)(implicit cavas: SCanvas): Sub[Msg] = OnMouseClick(mapper) } - trait CmdQ[+Msg] { - def run(): Msg - } - class Game[Model, Msg]( - init: => Model, - update: (Model, Msg) => Model, - view: Model => Picture, - subscriptions: Model => Seq[Sub[Msg]] - )(implicit canvas: SCanvas) - extends GameMsgSink[Msg] { + init: => Model, + update: (Model, Msg) => Model, + view: Model => Picture, + subscriptions: Model => Seq[Sub[Msg]] + )(implicit canvas: SCanvas) extends GameMsgSink[Msg] { private var currModel: Model = _ private var currSubs: Seq[Sub[Msg]] = _ private var currView: Picture = _ private var firstTime = true - private var gameTimer = canvas.timer(20) { + var gameTimer = canvas.timer(20) { if (firstTime) { firstTime = false currModel = init @@ -119,71 +110,53 @@ package object gaming { else { fireTimerSubs() updateView() - checkForStop() } } - private def timerSubs: Seq[TimerSub[Msg]] = - currSubs.filter(_.isInstanceOf[TimerSub[Msg]]).asInstanceOf[Seq[TimerSub[Msg]]] + def timerSubs: Seq[TimerSub[Msg]] = currSubs.filter(_.isInstanceOf[TimerSub[Msg]]).asInstanceOf[Seq[TimerSub[Msg]]] - private def nonTimerSubs: Seq[NonTimerSub[Msg]] = - currSubs.filter(_.isInstanceOf[NonTimerSub[Msg]]).asInstanceOf[Seq[NonTimerSub[Msg]]] + def nonTimerSubs: Seq[NonTimerSub[Msg]] = currSubs.filter(_.isInstanceOf[NonTimerSub[Msg]]).asInstanceOf[Seq[NonTimerSub[Msg]]] - private def updateView(): Unit = { + def updateView(): Unit = { val oldView = currView currView = view(currModel) oldView.erase() currView.draw() } - private def updateModelAndSubs(msg: Msg): Unit = { + def updateModelAndSubs(msg: Msg): Unit = { currModel = update(currModel, msg) val oldSubs = currSubs currSubs = subscriptions(currModel) handleSubChanges(oldSubs, currSubs) } - private def handleSubChanges(oldSubs: Seq[Sub[Msg]], newSubs: Seq[Sub[Msg]]): Unit = { - if (newSubs != oldSubs) { - lazy val newSubsSet = Set(newSubs: _*) - oldSubs.foreach { - case oldNtSub: NonTimerSub[Msg] => - if (!newSubsSet.contains(oldNtSub)) { - oldNtSub.deactivate() - } - case _ => - } - - lazy val oldSubsSet = Set(oldSubs: _*) - newSubs.foreach { - case newNtSub: NonTimerSub[Msg] => - if (!oldSubsSet.contains(newNtSub)) { - newNtSub.activate(this) - } - case _ => + def handleSubChanges(oldSubs: Seq[Sub[Msg]], newSubs: Seq[Sub[Msg]]): Unit = { + if (newSubs.length != oldSubs.length) { + val newSubsSet = Set(newSubs: _*) + oldSubs.foreach { sub => + sub match { + case ntSub: NonTimerSub[Msg] => + if (!newSubsSet.contains(ntSub)) { + ntSub.deactivate() + } + case _ => + } } } } - private def checkForStop(): Unit = { + def checkForStop(): Unit = { if (currSubs.isEmpty) { canvas.stopAnimationActivity(gameTimer) } } - private def fireTimerSubs(): Unit = { + def fireTimerSubs(): Unit = { timerSubs.foreach { sub => sub.fire(this) } - } - - def runCommandQuery(cmdQ: CmdQ[Msg]): Unit = { - Utils.runAsync { - val msg = cmdQ.run() - Utils.runInSwingThreadNonBatched { - triggerUpdate(msg) - } - } + checkForStop() } def triggerIncrementalUpdate(msg: Msg): Unit = { @@ -217,15 +190,9 @@ package object gaming { } def collidesWith( - x1: Double, - y1: Double, - w1: Double, - h1: Double, - x2: Double, - y2: Double, - w2: Double, - h2: Double - ): Boolean = { + x1: Double, y1: Double, w1: Double, h1: Double, + x2: Double, y2: Double, w2: Double, h2: Double + ): Boolean = { import java.awt.geom.Rectangle2D val r1 = new Rectangle2D.Double(x1, y1, w1, h1) val r2 = new Rectangle2D.Double(x2, y2, w2, h2) diff --git a/src/main/scala/net/kogics/kojo/history/CommandHistory.scala b/src/main/scala/net/kogics/kojo/history/CommandHistory.scala index f02dd96cf..e79b17b87 100644 --- a/src/main/scala/net/kogics/kojo/history/CommandHistory.scala +++ b/src/main/scala/net/kogics/kojo/history/CommandHistory.scala @@ -16,7 +16,6 @@ package net.kogics.kojo package history import scala.collection.mutable - import net.kogics.kojo.core.HistoryItem import net.kogics.kojo.core.HistoryListener import net.kogics.kojo.core.HistorySaver @@ -115,7 +114,7 @@ class CommandHistory private[kojo] (historySaver: HistorySaver) extends core.Com def apply(idx: Int) = history(idx) def ensureVisible(idx: Int): Unit = { - listener.foreach { _.ensureVisible(idx) } + listener foreach { _ ensureVisible (idx) } } def ensureLastEntryVisible(): Unit = { @@ -161,7 +160,7 @@ class CommandHistory private[kojo] (historySaver: HistorySaver) extends core.Com allHistory.foreach { hi => internalAdd(hi) } - listener.foreach { _.historyReady() } + listener foreach { _.historyReady() } } } diff --git a/src/main/scala/net/kogics/kojo/history/HistoryPanel.scala b/src/main/scala/net/kogics/kojo/history/HistoryPanel.scala index aa284f114..51652a373 100644 --- a/src/main/scala/net/kogics/kojo/history/HistoryPanel.scala +++ b/src/main/scala/net/kogics/kojo/history/HistoryPanel.scala @@ -1,19 +1,13 @@ package net.kogics.kojo.history +import java.awt.BorderLayout +import java.awt.Color import java.awt.event.ActionEvent import java.awt.event.ActionListener import java.awt.event.KeyAdapter import java.awt.event.KeyEvent -import java.awt.BorderLayout -import java.awt.Color import java.text.DateFormat -import javax.swing.border.BevelBorder -import javax.swing.border.CompoundBorder -import javax.swing.border.EmptyBorder -import javax.swing.event.ListSelectionEvent -import javax.swing.event.ListSelectionListener -import javax.swing.table.AbstractTableModel -import javax.swing.table.DefaultTableCellRenderer + import javax.swing.BorderFactory import javax.swing.DefaultCellEditor import javax.swing.JButton @@ -24,11 +18,19 @@ import javax.swing.JTable import javax.swing.JTextField import javax.swing.ListSelectionModel import javax.swing.SwingConstants +import javax.swing.border.BevelBorder +import javax.swing.border.CompoundBorder +import javax.swing.border.EmptyBorder +import javax.swing.event.ListSelectionEvent +import javax.swing.event.ListSelectionListener +import javax.swing.table.AbstractTableModel +import javax.swing.table.DefaultTableCellRenderer import net.kogics.kojo.core.CodeExecutionSupport import net.kogics.kojo.core.HistoryListener import net.kogics.kojo.lite.Theme import net.kogics.kojo.util.Utils + import sun.swing.table.DefaultTableCellHeaderRenderer class HistoryPanel(execSupport: CodeExecutionSupport) extends JPanel { hpanel => @@ -101,32 +103,20 @@ class HistoryPanel(execSupport: CodeExecutionSupport) extends JPanel { hpanel => table.setRowHeight(table.getRowHeight + 8) table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION) table.setRowSelectionInterval(cmdh.size, cmdh.size) - table.getTableHeader.getDefaultRenderer - .asInstanceOf[DefaultTableCellHeaderRenderer] - .setHorizontalAlignment(SwingConstants.CENTER) - table.setDefaultRenderer( - classOf[AnyRef], - new DefaultTableCellRenderer { - override def getTableCellRendererComponent( - table: JTable, - value: Object, - isSelected: Boolean, - hasFocus: Boolean, - row: Int, - column: Int - ) = { - val component = - super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column).asInstanceOf[JComponent] - - val outsideBorder = BorderFactory.createLineBorder(new Color(240, 240, 240)) - val insideBorder = new EmptyBorder(0, 3, 0, 2) - val border = new CompoundBorder(outsideBorder, insideBorder) - - component.setBorder(border) - component - } + table.getTableHeader.getDefaultRenderer.asInstanceOf[DefaultTableCellHeaderRenderer].setHorizontalAlignment(SwingConstants.CENTER) + table.setDefaultRenderer(classOf[AnyRef], new DefaultTableCellRenderer { + override def getTableCellRendererComponent(table: JTable, value: Object, isSelected: Boolean, + hasFocus: Boolean, row: Int, column: Int) = { + val component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column).asInstanceOf[JComponent] + + val outsideBorder = BorderFactory.createLineBorder(new Color(240, 240, 240)) + val insideBorder = new EmptyBorder(0, 3, 0, 2) + val border = new CompoundBorder(outsideBorder, insideBorder) + + component.setBorder(border) + component } - ) + }) table.getSelectionModel.addListSelectionListener(new ListSelectionListener { override def valueChanged(event: ListSelectionEvent): Unit = { if (!event.getValueIsAdjusting) { @@ -229,4 +219,4 @@ class HistoryPanel(execSupport: CodeExecutionSupport) extends JPanel { hpanel => } }) scrollToEnd() -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/history/historydb.scala b/src/main/scala/net/kogics/kojo/history/historydb.scala index ec56891ea..c016b5cb2 100644 --- a/src/main/scala/net/kogics/kojo/history/historydb.scala +++ b/src/main/scala/net/kogics/kojo/history/historydb.scala @@ -25,15 +25,14 @@ import scala.collection.mutable.ListBuffer import net.kogics.kojo.core.HistoryItem import net.kogics.kojo.core.HistorySaver -// code to simplify jdbc queries from: +// code to simplify jdbc queries from: // http://zcox.wordpress.com/2009/08/17/simple-jdbc-queries-in-scala/ object Control { import language.reflectiveCalls def using[Closeable <: { def close(): Unit }, B](closeable: Closeable)(getB: Closeable => B): B = try { getB(closeable) - } - finally { + } finally { closeable.close() } @@ -47,7 +46,7 @@ object Control { /** Executes the SQL and processes the result set using the specified function. */ def query[B](connection: Connection, sql: String)(process: ResultSet => B): B = - // using (connection) { connection => + // using (connection) { connection => using(connection.createStatement) { statement => using(statement.executeQuery(sql)) { results => process(results) @@ -71,8 +70,7 @@ class DBHistorySaver extends HistorySaver { conn.setAutoCommit(true) createTableIfNeeded() - val saveStatement = - conn.prepareStatement("INSERT INTO HISTORY(SCRIPT, FILE, STARRED, TAGS, AT) VALUES(?, ?, ?, ?, ?)") + val saveStatement = conn.prepareStatement("INSERT INTO HISTORY(SCRIPT, FILE, STARRED, TAGS, AT) VALUES(?, ?, ?, ?, ?)") val idCall = conn.prepareCall("{? = CALL IDENTITY()}") idCall.registerOutParameter(1, Types.BIGINT); val updateStars = conn.prepareStatement("UPDATE HISTORY SET STARRED = ? WHERE ID = ?") @@ -104,30 +102,13 @@ class DBHistorySaver extends HistorySaver { def readAll = { queryEach(conn, "SELECT * FROM HISTORY ORDER BY AT DESC LIMIT 1000") { rs => - HistoryItem( - rs.getString("SCRIPT"), - rs.getString("FILE"), - rs.getLong("ID"), - rs.getBoolean("STARRED"), - rs.getString("TAGS"), - rs.getTimestamp("AT") - ) + HistoryItem(rs.getString("SCRIPT"), rs.getString("FILE"), rs.getLong("ID"), rs.getBoolean("STARRED"), rs.getString("TAGS"), rs.getTimestamp("AT")) } } def readSome(filter: String) = { - queryEach( - conn, - s"SELECT * FROM HISTORY WHERE SCRIPT LIKE '%$filter%' OR FILE LIKE '%$filter%' OR TAGS LIKE '%$filter%' ORDER BY AT DESC LIMIT 1000" - ) { rs => - HistoryItem( - rs.getString("SCRIPT"), - rs.getString("FILE"), - rs.getLong("ID"), - rs.getBoolean("STARRED"), - rs.getString("TAGS"), - rs.getTimestamp("AT") - ) + queryEach(conn, s"SELECT * FROM HISTORY WHERE SCRIPT LIKE '%$filter%' OR FILE LIKE '%$filter%' OR TAGS LIKE '%$filter%' ORDER BY AT DESC LIMIT 1000") { rs => + HistoryItem(rs.getString("SCRIPT"), rs.getString("FILE"), rs.getLong("ID"), rs.getBoolean("STARRED"), rs.getString("TAGS"), rs.getTimestamp("AT")) } } @@ -145,17 +126,18 @@ class DBHistorySaver extends HistorySaver { h.id = idCall.getLong(1) h } - + def updateStar(hi: HistoryItem): Unit = { updateStars.setBoolean(1, hi.starred) updateStars.setLong(2, hi.id) updateStars.executeUpdate() } - + def updateTags(hi: HistoryItem): Unit = { updateTags.setString(1, hi.tags) updateTags.setLong(2, hi.id) updateTags.executeUpdate() } - + } + diff --git a/src/main/scala/net/kogics/kojo/kgeom/PolyLine.scala b/src/main/scala/net/kogics/kojo/kgeom/PolyLine.scala index 78a5cf628..2d15a7ad3 100644 --- a/src/main/scala/net/kogics/kojo/kgeom/PolyLine.scala +++ b/src/main/scala/net/kogics/kojo/kgeom/PolyLine.scala @@ -17,11 +17,11 @@ package net.kogics.kojo.kgeom import java.awt._ import java.awt.geom._ -import scala.collection._ - import edu.umd.cs.piccolo._ import edu.umd.cs.piccolo.util._ +import scala.collection._ + object PolyLine { def apply(points: Seq[Point2D.Double]) = { val result = new PolyLine() @@ -43,7 +43,7 @@ class PolyLine extends PNode { def addPoint(x: Double, y: Double): Unit = addPoint(new Point2D.Double(x, y)) def lineTo(x: Double, y: Double) = addPoint(new Point2D.Double(x, y)) def removeLastPoint(): Unit = { - points.remove(points.size - 1) + points.remove(points.size-1) buildGeneralPath() } @@ -76,7 +76,7 @@ class PolyLine extends PNode { } polyLinePath.lineTo(p.x, p.y) - + updateBounds() } @@ -114,7 +114,7 @@ class PolyLine extends PNode { // val b = stroke.createStrokedShape(polyLinePath).getBounds2D() val b = polyLinePath.getBounds2D() val w = stroke.getLineWidth - super.setBounds(b.getX() - w / 2.0, b.getY() - w / 2.0, b.getWidth() + w, b.getHeight() + w) + super.setBounds(b.getX()-w/2.0, b.getY()-w/2.0, b.getWidth()+w, b.getHeight()+w) repaint() } @@ -140,7 +140,7 @@ class PolyLine extends PNode { println("Cannot set bounds") false } - + def map(fn: Point2D.Double => Point2D.Double) = { val result = PolyLine(points.map(fn)) result.setPaint(getPaint) diff --git a/src/main/scala/net/kogics/kojo/kmath/Kmath.scala b/src/main/scala/net/kogics/kojo/kmath/Kmath.scala index a3c06cdb9..ca0aa8448 100644 --- a/src/main/scala/net/kogics/kojo/kmath/Kmath.scala +++ b/src/main/scala/net/kogics/kojo/kmath/Kmath.scala @@ -2,10 +2,9 @@ package net.kogics.kojo package kmath import scala.language.implicitConversions - -import net.kogics.kojo.core.Point import org.apache.commons.math3.stat.StatUtils import org.apache.commons.math3.util.ArithmeticUtils +import net.kogics.kojo.core.Point object Kmath { implicit def seqToArrD(seq: Seq[Double]): Array[Double] = seq.toArray diff --git a/src/main/scala/net/kogics/kojo/kmath/rational.scala b/src/main/scala/net/kogics/kojo/kmath/rational.scala index f69aa4bad..8fe32c3ab 100644 --- a/src/main/scala/net/kogics/kojo/kmath/rational.scala +++ b/src/main/scala/net/kogics/kojo/kmath/rational.scala @@ -12,7 +12,7 @@ trait Rationals { implicit def itor(n: Int) = Rational(new BigFraction(n)) implicit def ltor(n: Long) = Rational(new BigFraction(n)) implicit def dtor(n: Double) = { - val ret = Rational(new BigFraction(n, 1e-9, Int.MaxValue)) + val ret = Rational(new BigFraction(n, 1E-9, Int.MaxValue)) if (n != 0 && ret == 0) Rational(new BigFraction(n)) else ret } implicit def ftor(n: Float) = Rational(new BigFraction(n)) @@ -68,3 +68,5 @@ trait Rationals { } } } + + diff --git a/src/main/scala/net/kogics/kojo/lexer/ScalariformTokenMaker.scala b/src/main/scala/net/kogics/kojo/lexer/ScalariformTokenMaker.scala index b477f608c..bcf1428e9 100644 --- a/src/main/scala/net/kogics/kojo/lexer/ScalariformTokenMaker.scala +++ b/src/main/scala/net/kogics/kojo/lexer/ScalariformTokenMaker.scala @@ -25,11 +25,12 @@ import org.fife.ui.rsyntaxtextarea.AbstractTokenMaker import org.fife.ui.rsyntaxtextarea.Token import org.fife.ui.rsyntaxtextarea.TokenMap import org.fife.ui.rsyntaxtextarea.TokenTypes -import scalariform.lexer.{ Token => SfToken } + +import scalariform.ScalaVersions import scalariform.lexer.ScalaLexer import scalariform.lexer.TokenType import scalariform.lexer.Tokens -import scalariform.ScalaVersions +import scalariform.lexer.{Token => SfToken} class ScalariformTokenMaker extends AbstractTokenMaker { @@ -75,7 +76,7 @@ class ScalariformTokenMaker extends AbstractTokenMaker { override def getTokenList(segment: Segment, initialTokenType: Int, docOffset: Int): Token = { def addRstaToken(t: SfToken): Unit = { - debug(" %s".format(t)) + debug(" %s" format t) // offset of token within its segment = offset in doc - offset of segment within doc val segStartOffset = t.offset - (docOffset - segment.offset) val segEndOffset = segStartOffset + t.length - 1 @@ -83,13 +84,8 @@ class ScalariformTokenMaker extends AbstractTokenMaker { addToken(segment.array, segStartOffset, segEndOffset, convertTokenType(t.tokenType), docStartOffset) } - debug( - "\n---\nGetting tokens for Line. Doc Offset: %d, Seg Offset: %d, Length: %d".format( - docOffset, - segment.offset, - segment.length - ) - ) + debug("\n---\nGetting tokens for Line. Doc Offset: %d, Seg Offset: %d, Length: %d". + format(docOffset, segment.offset, segment.length)) debug("Line Text:" + segment.toString) resetTokenList() @@ -209,9 +205,10 @@ class ScalariformTokenMaker extends AbstractTokenMaker { val flen = upper - lower val docFragment = doc.getText(lower, flen) val newActive = rawTokenise(docFragment).map { t => t.copy(offset = t.offset + lower) } - docTokens = preInactive.slice(0, preInactive.length - dropped) ++ - newActive.slice(0, newActive.length - 1) ++ - newPostInactive.slice(udropped, newPostInactive.length) + docTokens = + preInactive.slice(0, preInactive.length - dropped) ++ + newActive.slice(0, newActive.length - 1) ++ + newPostInactive.slice(udropped, newPostInactive.length) showTiming(t0, "Incr") } } @@ -245,23 +242,23 @@ class ScalariformTokenMaker extends AbstractTokenMaker { } else { sfType match { - case Tokens.WS => TokenTypes.WHITESPACE - case Tokens.CHARACTER_LITERAL => TokenTypes.LITERAL_CHAR - case Tokens.INTEGER_LITERAL => TokenTypes.LITERAL_NUMBER_DECIMAL_INT - case Tokens.FLOATING_POINT_LITERAL => TokenTypes.LITERAL_NUMBER_FLOAT - case Tokens.STRING_LITERAL => TokenTypes.LITERAL_STRING_DOUBLE_QUOTE - case Tokens.STRING_PART => TokenTypes.LITERAL_STRING_DOUBLE_QUOTE - case Tokens.SYMBOL_LITERAL => TokenTypes.LITERAL_STRING_DOUBLE_QUOTE - case Tokens.TRUE => TokenTypes.LITERAL_BOOLEAN - case Tokens.FALSE => TokenTypes.LITERAL_BOOLEAN - case Tokens.NULL => TokenTypes.LITERAL_CHAR - case Tokens.EOF => TokenTypes.WHITESPACE - case Tokens.LBRACE => TokenTypes.SEPARATOR - case Tokens.RBRACE => TokenTypes.SEPARATOR - case Tokens.LBRACKET => TokenTypes.SEPARATOR - case Tokens.RBRACKET => TokenTypes.SEPARATOR - case Tokens.LPAREN => TokenTypes.SEPARATOR - case Tokens.RPAREN => TokenTypes.SEPARATOR + case Tokens.WS => TokenTypes.WHITESPACE + case Tokens.CHARACTER_LITERAL => TokenTypes.LITERAL_CHAR + case Tokens.INTEGER_LITERAL => TokenTypes.LITERAL_NUMBER_DECIMAL_INT + case Tokens.FLOATING_POINT_LITERAL => TokenTypes.LITERAL_NUMBER_FLOAT + case Tokens.STRING_LITERAL => TokenTypes.LITERAL_STRING_DOUBLE_QUOTE + case Tokens.STRING_PART => TokenTypes.LITERAL_STRING_DOUBLE_QUOTE + case Tokens.SYMBOL_LITERAL => TokenTypes.LITERAL_STRING_DOUBLE_QUOTE + case Tokens.TRUE => TokenTypes.LITERAL_BOOLEAN + case Tokens.FALSE => TokenTypes.LITERAL_BOOLEAN + case Tokens.NULL => TokenTypes.LITERAL_CHAR + case Tokens.EOF => TokenTypes.WHITESPACE + case Tokens.LBRACE => TokenTypes.SEPARATOR + case Tokens.RBRACE => TokenTypes.SEPARATOR + case Tokens.LBRACKET => TokenTypes.SEPARATOR + case Tokens.RBRACKET => TokenTypes.SEPARATOR + case Tokens.LPAREN => TokenTypes.SEPARATOR + case Tokens.RPAREN => TokenTypes.SEPARATOR case Tokens.XML_START_OPEN => TokenTypes.MARKUP_TAG_DELIMITER case Tokens.XML_EMPTY_CLOSE => TokenTypes.MARKUP_TAG_DELIMITER @@ -277,7 +274,7 @@ class ScalariformTokenMaker extends AbstractTokenMaker { case Tokens.XML_UNPARSED => TokenTypes.MARKUP_CDATA case Tokens.XML_PROCESSING_INSTRUCTION => TokenTypes.MARKUP_PROCESSING_INSTRUCTION - case _ => TokenTypes.IDENTIFIER + case _ => TokenTypes.IDENTIFIER } } } @@ -298,4 +295,4 @@ class ScalariformTokenMaker extends AbstractTokenMaker { debugOn = if (System.getProperty("kojo.lexer.debug") == "true") true else false timingOn = if (System.getProperty("kojo.lexer.timing") == "true") true else false } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/AppMenu.scala b/src/main/scala/net/kogics/kojo/lite/AppMenu.scala index fa5c6a88e..b37f9c4e9 100644 --- a/src/main/scala/net/kogics/kojo/lite/AppMenu.scala +++ b/src/main/scala/net/kogics/kojo/lite/AppMenu.scala @@ -14,16 +14,14 @@ */ package net.kogics.kojo.lite +import java.awt.{Component, Dimension, Insets} import java.awt.event.ActionEvent import java.awt.event.ActionListener -import java.awt.Component -import java.awt.Dimension -import java.awt.Insets + import javax.swing._ import javax.swing.event.PopupMenuEvent import javax.swing.event.PopupMenuListener import javax.swing.text.html.HTMLEditorKit - import net.kogics.kojo.action.CloseFile import net.kogics.kojo.action.LoadFrom import net.kogics.kojo.action.NewFile @@ -150,7 +148,7 @@ trait AppMenu { val item = new JMenuItem(label) item.addActionListener(new ActionListener { def actionPerformed(ev: ActionEvent): Unit = { - // loadAndRunResource(root + file) + //loadAndRunResource(root + file) loadAndRunLocalizedResource(root, file) } }) @@ -257,9 +255,6 @@ trait AppMenu { animGameMenu.add(menuItemFor("S_LunarLander", "lunar-lander.kojo")) animGameMenu.add(menuItemFor("S_PulsatingLamp", "lamp-animation.kojo")) animGameMenu.add(menuItemFor("S_PulsatingLamp2", "lamp-animation2.kojo")) - animGameMenu.add(menuItemFor("S_DynamicSquare", "animated-square-creation.kojo")) - animGameMenu.add(menuItemFor("S_Fireworks", "fireworks-canvas.kojo")) - animGameMenu.add(menuItemFor("S_Fireworks2", "fireworks.kojo")) animGameMenu.add(menuItemFor("S_TangramSkier", "tangram-skier.kojo")) animGameMenu.add(menuItemFor("S_Pong", "pong.kojo")) animGameMenu.add(menuItemFor("S_MemoryCards", "memory-cards.kojo")) @@ -327,7 +322,6 @@ trait AppMenu { showcaseMenu.add(menuItemFor("S_Mandel", "mandelbrot.kojo")) showcaseMenu.add(menuItemFor("S_Mondrian", "genart-mondrian.kojo")) showcaseMenu.add(menuItemFor("S_Delaunay", "genart-delaunay.kojo")) - showcaseMenu.add(menuItemFor("S_Fireworks", "fireworks-canvas.kojo")) showcaseMenu.add(menuItemFor("S_Collidium", "collidium.kojo")) showcaseMenu.add(menuItemFor("S_CarRide", "car-ride.kojo")) showcaseMenu.add(menuItemForInstalledFile("S_Platformer", "examples/tiledgame/game.kojo")) @@ -460,7 +454,7 @@ trait AppMenu { Version: ${Versions.KojoVersion} ${Versions.KojoRevision}
Build date: ${Versions.KojoBuildDate}
Java version: ${Versions.JavaVersion}. Scala version: ${Versions.ScalaVersion}

- Copyright © 2009-2023 Lalit Pant (pant.lalit@gmail.com) as per contributions.
+ Copyright © 2009-2022 Lalit Pant (pant.lalit@gmail.com) as per contributions.
Copyright © Project contributors as per contributions.

Please visit http://www.kogics.net/kojo for more information about Kojo.

Kojo Contributors:
    diff --git a/src/main/scala/net/kogics/kojo/lite/AppMode.scala b/src/main/scala/net/kogics/kojo/lite/AppMode.scala index d23a054a0..d60acc9d3 100644 --- a/src/main/scala/net/kogics/kojo/lite/AppMode.scala +++ b/src/main/scala/net/kogics/kojo/lite/AppMode.scala @@ -16,9 +16,9 @@ package net.kogics.kojo.lite import net.kogics.kojo.core.CodeRunner import net.kogics.kojo.core.CodingMode +import net.kogics.kojo.core.VanillaMode import net.kogics.kojo.core.RunContext import net.kogics.kojo.core.TwMode -import net.kogics.kojo.core.VanillaMode import net.kogics.kojo.xscala import net.kogics.kojo.xscala.KojoInterpreter import net.kogics.kojo.xscala.ScalaCodeRunner2 diff --git a/src/main/scala/net/kogics/kojo/lite/ArithAerobicsPane.scala b/src/main/scala/net/kogics/kojo/lite/ArithAerobicsPane.scala index 0869be3e8..6ca4971c7 100644 --- a/src/main/scala/net/kogics/kojo/lite/ArithAerobicsPane.scala +++ b/src/main/scala/net/kogics/kojo/lite/ArithAerobicsPane.scala @@ -1,18 +1,19 @@ package net.kogics.kojo.lite import java.awt.Color -import javax.swing.event.ChangeEvent + import javax.swing.JFrame import javax.swing.JLabel import javax.swing.JTabbedPane import javax.swing.SwingConstants +import javax.swing.event.ChangeEvent import net.kogics.kojo.util.Utils -import net.kogics.rithica.addition.{ TopContainer => Adder } -import net.kogics.rithica.division.{ TopContainer => Divider } -import net.kogics.rithica.multiplication.{ TopContainer => Multiplier } -import net.kogics.rithica.subtraction.{ TopContainer => Subtractor } -import net.kogics.rithica.ui.{ TopContainer => ArithContainer } +import net.kogics.rithica.addition.{TopContainer => Adder} +import net.kogics.rithica.division.{TopContainer => Divider} +import net.kogics.rithica.multiplication.{TopContainer => Multiplier} +import net.kogics.rithica.subtraction.{TopContainer => Subtractor} +import net.kogics.rithica.ui.{TopContainer => ArithContainer} class ArithAerobicsPane(frame: JFrame, kojoCtx: KojoCtx) extends JTabbedPane { diff --git a/src/main/scala/net/kogics/kojo/lite/BreakpointPane.scala b/src/main/scala/net/kogics/kojo/lite/BreakpointPane.scala index 3856eb565..69eb7761d 100644 --- a/src/main/scala/net/kogics/kojo/lite/BreakpointPane.scala +++ b/src/main/scala/net/kogics/kojo/lite/BreakpointPane.scala @@ -1,13 +1,14 @@ package net.kogics.kojo.lite import java.awt.Component -import javax.swing.border.EmptyBorder + import javax.swing.JButton import javax.swing.JDialog import javax.swing.JFrame import javax.swing.JLabel import javax.swing.JScrollPane import javax.swing.ScrollPaneConstants +import javax.swing.border.EmptyBorder import net.kogics.kojo.core import net.kogics.kojo.util.Utils diff --git a/src/main/scala/net/kogics/kojo/lite/Builtins.scala b/src/main/scala/net/kogics/kojo/lite/Builtins.scala index a09a261de..967be3710 100644 --- a/src/main/scala/net/kogics/kojo/lite/Builtins.scala +++ b/src/main/scala/net/kogics/kojo/lite/Builtins.scala @@ -16,50 +16,39 @@ package net.kogics.kojo package lite -import java.awt.geom.Ellipse2D import java.awt.geom.GeneralPath -import java.awt.geom.Rectangle2D -import java.awt.image.BufferedImage -import java.awt.image.BufferedImageOp -import java.awt.Graphics2D -import java.awt.Paint -import java.awt.Toolkit +import java.awt.geom.{Ellipse2D, Rectangle2D} +import java.awt.image.{BufferedImage, BufferedImageOp} +import java.awt.{Paint, Toolkit} import java.net.URL -import javax.swing.JComponent - -import scala.language.implicitConversions - import com.jhlabs.image.AbstractBufferedImageOp import com.jhlabs.image.LightFilter.Light -import net.kogics.kojo.core.Rich2DPath -import net.kogics.kojo.core.VertexShape -import net.kogics.kojo.core.Voice + +import javax.swing.JComponent +import net.kogics.kojo.core.{Rich2DPath, VertexShape, Voice} import net.kogics.kojo.kmath.KEasing -import net.kogics.kojo.music.RealtimeNotePlayer import net.kogics.kojo.turtle.TurtleWorldAPI -import net.kogics.kojo.util.Throttler -import net.kogics.kojo.util.UserCommand -import net.kogics.kojo.util.Utils -import net.kogics.kojo.xscala.CodeCompletionUtils -import net.kogics.kojo.xscala.Help -import net.kogics.kojo.xscala.RepeatCommands - -// a static instance is needed for the compiler prefix code +import net.kogics.kojo.util.{Throttler, UserCommand, Utils} +import net.kogics.kojo.xscala.{CodeCompletionUtils, Help, RepeatCommands} + +import scala.language.implicitConversions +import scala.swing.Graphics2D + +// a static instance is needed for the compiler prefix code object Builtins { @volatile var instance: Builtins = _ } class Builtins( - val TSCanvas: DrawingCanvasAPI, - val Tw: TurtleWorldAPI, - val Staging: staging.API, - storyTeller: story.StoryTeller, - mp3player: music.KMp3, - fuguePlayer: music.FuguePlayer, - val kojoCtx: core.KojoCtx, - scalaCodeRunner: core.CodeRunner -) extends CoreBuiltins - with RepeatCommands { builtins => + val TSCanvas: DrawingCanvasAPI, + val Tw: TurtleWorldAPI, + val Staging: staging.API, + storyTeller: story.StoryTeller, + mp3player: music.KMp3, + fuguePlayer: music.FuguePlayer, + val kojoCtx: core.KojoCtx, + scalaCodeRunner: core.CodeRunner +) extends CoreBuiltins with RepeatCommands { builtins => Builtins.instance = this val tCanvas = TSCanvas.tCanvas @@ -70,17 +59,11 @@ class Builtins( UserCommand.addCompletion("repeat", "(${n}) {\n ${cursor}\n}") UserCommand.addSynopsis("repeat(n) {} - Repeats the commands within braces n number of times.") UserCommand.addCompletion("repeati", "(${n}) { i => \n ${cursor}\n}") - UserCommand.addSynopsis( - "repeati(n) {} - Repeats the commands within braces n number of times. The current repeat index is available within the braces." - ) + UserCommand.addSynopsis("repeati(n) {} - Repeats the commands within braces n number of times. The current repeat index is available within the braces.") UserCommand.addCompletion("repeatWhile", "(${condition}) {\n ${cursor}\n}") - UserCommand.addSynopsis( - "repeatWhile(cond) {} - Repeats the commands within braces while the given condition is true." - ) + UserCommand.addSynopsis("repeatWhile(cond) {} - Repeats the commands within braces while the given condition is true.") UserCommand.addCompletion("repeatUntil", "(${condition}) {\n ${cursor}\n}") - UserCommand.addSynopsis( - "repeatUntil(cond) {} - Repeats the commands within braces until the given condition is true." - ) + UserCommand.addSynopsis("repeatUntil(cond) {} - Repeats the commands within braces until the given condition is true.") def showScriptInOutput() = kojoCtx.showScriptInOutput() UserCommand("showScriptInOutput", Nil, "Enables the display of scripts in the output window when they run.") @@ -89,11 +72,7 @@ class Builtins( UserCommand("hideScriptInOutput", Nil, "Stops the display of scripts in the output window.") def showVerboseOutput() = kojoCtx.showVerboseOutput() - UserCommand( - "showVerboseOutput", - Nil, - "Enables the display of output from the Scala interpreter. By default, output from the interpreter is shown only for single line scripts." - ) + UserCommand("showVerboseOutput", Nil, "Enables the display of output from the Scala interpreter. By default, output from the interpreter is shown only for single line scripts.") def hideVerboseOutput() = kojoCtx.hideVerboseOutput() UserCommand("hideVerboseOutput", Nil, "Stops the display of output from the Scala interpreter.") @@ -107,21 +86,17 @@ class Builtins( def print(obj: Any): Unit = { // Runs on Actor pool (interpreter) thread - kojoCtx.kprintln("%s".format(obj)) + kojoCtx.kprintln("%s" format (obj)) Throttler.throttleHard() } UserCommand.addCompletion("print", List("obj")) - def println(obj: Any): Unit = print("%s\n".format(obj)) + def println(obj: Any): Unit = print("%s\n" format (obj)) UserCommand.addCompletion("println", List("obj")) UserCommand.addSynopsis("println(obj) or print(obj) - Displays the given object as a string in the output window.") def readln(prompt: String): String = kojoCtx.readInput(prompt) - UserCommand( - "readln", - List("promptString"), - "Displays the given prompt in the output window and reads a line that the user enters." - ) + UserCommand("readln", List("promptString"), "Displays the given prompt in the output window and reads a line that the user enters.") def onRunStart(): Unit = { BreakpointPane.onRunStart() @@ -138,35 +113,15 @@ class Builtins( } def readInt(prompt: String): Int = readln(prompt).toInt - UserCommand( - "readInt", - List("promptString"), - "Displays the given prompt in the output window and reads an Integer value that the user enters." - ) + UserCommand("readInt", List("promptString"), "Displays the given prompt in the output window and reads an Integer value that the user enters.") def readDouble(prompt: String): Double = readln(prompt).toDouble - UserCommand( - "readDouble", - List("promptString"), - "Displays the given prompt in the output window and reads a Double-precision Real value that the user enters." - ) - - UserCommand( - "random", - List("lowerBound", "upperBound"), - "Returns a random Integer between 0 (inclusive) and upperBound (exclusive)." - ) - UserCommand( - "randomDouble", - List("lowerBound", "upperBound"), - "Returns a random Double-precision Real between 0 (inclusive) and upperBound (exclusive)." - ) - - UserCommand( - "color", - List("red", "green", "blue"), - "Creates a new color based on the specified red, green, and blue levels." - ) + UserCommand("readDouble", List("promptString"), "Displays the given prompt in the output window and reads a Double-precision Real value that the user enters.") + + UserCommand("random", List("lowerBound", "upperBound"), "Returns a random Integer between 0 (inclusive) and upperBound (exclusive).") + UserCommand("randomDouble", List("lowerBound", "upperBound"), "Returns a random Double-precision Real between 0 (inclusive) and upperBound (exclusive).") + + UserCommand("color", List("red", "green", "blue"), "Creates a new color based on the specified red, green, and blue levels.") def setAstStopPhase(phase: String): Unit = kojoCtx.setAstStopPhase(phase) def astStopPhase = kojoCtx.astStopPhase @@ -196,24 +151,13 @@ class Builtins( UserCommand("stPlayStory", List("story"), "Play the given story.") def stFormula(latex: String, size: Int = 18, cssColor: String = null) = -
    - { - if (cssColor != null) { - - } - else { - - } - } +
    + { if (cssColor != null) { } else { } }
    - UserCommand( - "stFormula", - List("latex"), - "Converts the supplied latex string into html that can be displayed in the Story Teller Window." - ) + UserCommand("stFormula", List("latex"), "Converts the supplied latex string into html that can be displayed in the Story Teller Window.") def stPlayMp3(mp3File: String): Unit = { storyTeller.playMp3(mp3File) @@ -229,18 +173,12 @@ class Builtins( storyTeller.addButton(label)(fn) } UserCommand.addCompletion("stAddButton", " (${label}) {\n ${cursor}\n}") - UserCommand.addSynopsis( - "stAddButton(label) {code} - Adds a button with the given label to the Story Teller Window, and runs the supplied code when the button is clicked." - ) + UserCommand.addSynopsis("stAddButton(label) {code} - Adds a button with the given label to the Story Teller Window, and runs the supplied code when the button is clicked.") def stAddField(label: String, default: Any): Unit = { storyTeller.addField(label, default) } - UserCommand( - "stAddField", - List("label", "default"), - "Adds an input field with the supplied label and default value to the Story Teller Window." - ) + UserCommand("stAddField", List("label", "default"), "Adds an input field with the supplied label and default value to the Story Teller Window.") implicit val StringRead = util.Read.StringRead implicit val DoubleRead = util.Read.DoubleRead @@ -316,68 +254,20 @@ Here's a partial list of the available commands: def playMusicUntilDone(voice: Voice, n: Int = 1): Unit = { fuguePlayer.playMusicUntilDone(voice, n) } - UserCommand( - "playMusicUntilDone", - List("score"), - "Plays the specified melody, rhythm, or score, and waits till the music finishes." - ) + UserCommand("playMusicUntilDone", List("score"), "Plays the specified melody, rhythm, or score, and waits till the music finishes.") def playMusicLoop(voice: Voice): Unit = { fuguePlayer.playMusicLoop(voice) } - UserCommand( - "playMusicLoop", - List("score"), - "Plays the specified melody, rhythm, or score in the background - in a loop." - ) - - val Instrument = music.Instrument - @volatile private var rtnp: Option[RealtimeNotePlayer] = None - - private def checkNotePlayer(): Unit = { - if (rtnp.isEmpty) { - rtnp = Some(new RealtimeNotePlayer()) - } - } + UserCommand("playMusicLoop", List("score"), "Plays the specified melody, rhythm, or score in the background - in a loop.") - def playNote(pitch: Int, durationMillis: Int, volume: Int = 80): Unit = { - checkNotePlayer() - rtnp.get.playNote(pitch, durationMillis, volume) - } - - def setNoteInstrument(instrumentCode: Int): Unit = { - checkNotePlayer() - rtnp.get.setInstrument(instrumentCode) - } - - def stopNotePlayer(): Unit = { - rtnp.foreach(_.stop()) - } - - def resetNotePlayer(): Unit = { - rtnp.foreach(_.close()) - rtnp = None - } - - UserCommand( - "textExtent", - List("text", "fontSize"), - "Determines the size/extent of the given text fragment for the given font size." - ) + UserCommand("textExtent", List("text", "fontSize"), "Determines the size/extent of the given text fragment for the given font size.") def runInBackground(code: => Unit) = Utils.runAsyncMonitored(code) - UserCommand.addSynopsis( - "runInBackground", - List("code"), - "Runs the given code in the background, concurrently with other code that follows right after this command." - ) + UserCommand.addSynopsis("runInBackground", List("code"), "Runs the given code in the background, concurrently with other code that follows right after this command.") def runInGuiThread(code: => Unit) = Utils.runInSwingThread(code) - UserCommand.addSynopsis( - "runInGuiThread", - List("code"), - "Runs the given code in the the GUI Thread, concurrently with other code that follows right after this command." - ) + UserCommand.addSynopsis("runInGuiThread", List("code"), "Runs the given code in the the GUI Thread, concurrently with other code that follows right after this command.") def runInDrawingThread(code: => Unit) = Utils.runInSwingThread(code) def evalInDrawingThread[T](fn: => T) = Utils.runInSwingThreadAndWait(fn) @@ -414,10 +304,7 @@ Here's a partial list of the available commands: } def reimportDefaults() = reimportBuiltins() - import story.HandlerHolder - import story.IntHandlerHolder - import story.StringHandlerHolder - import story.VoidHandlerHolder + import story.{HandlerHolder, IntHandlerHolder, StringHandlerHolder, VoidHandlerHolder} implicit def toIhm(handler: Int => Unit): HandlerHolder[Int] = new IntHandlerHolder(handler) implicit def toShm(handler: String => Unit): HandlerHolder[String] = new StringHandlerHolder(handler) implicit def toVhm(handler: () => Unit): HandlerHolder[Unit] = new VoidHandlerHolder(handler) @@ -522,12 +409,10 @@ Here's a partial list of the available commands: def zIndex(idx: Int) = postDrawTransform { pic => pic.setZIndex(idx) } def clip(clipShape: java.awt.Shape) = picture.Clippedc(clipShape) - // some core picture transformations as regular functions - for educative use - def withRotation(pic: Picture, angle: Double) = pic.withRotation(angle) - def withTranslation(pic: Picture, x: Double, y: Double) = pic.withTranslation(x, y) - def withScaling(pic: Picture, factor: Double) = pic.withScaling(factor) - def withFillColor(pic: Picture, color: Color) = pic.withFillColor(color) - def withPenColor(pic: Picture, color: Color) = pic.withPenColor(color) + def rotated(pic: Picture, angle: Double) = pic.thatsRotated(angle) + def translated(pic: Picture, x: Double, y: Double) = pic.thatsTranslated(x, y) + def scaled(pic: Picture, factor: Double) = pic.thatsScaled(factor) + def filled(pic: Picture, color: Color) = pic.thatsFilledWith(color) implicit val _picCanvas = tCanvas def pict(painter: Painter) = picture.Pic(painter) @@ -560,7 +445,6 @@ Here's a partial list of the available commands: def stopAnimations() = kojoCtx.stopActivity() def stopAnimation() = kojoCtx.stopActivity() def isKeyPressed(key: Int) = staging.Inputs.isKeyPressed(key) - def pressedKeys: collection.Set[Int] = staging.Inputs.pressedKeys def activateCanvas() = kojoCtx.activateDrawingCanvas() def activateEditor() = kojoCtx.activateScriptEditor() @@ -753,18 +637,14 @@ Here's a partial list of the available commands: def fromTurtle(fn: Turtle => Unit) = PictureT(fn) def fromCanvas(width: Double, height: Double)(fn: Graphics2D => Unit) = picture.fromJava2d(width, height, fn) - private[lite] def fromCanvasDynamic(width: Double, height: Double, scaleOutFactor: Double)(fn: Graphics2D => Unit)( - stopCheck: => Boolean - ) = + private[lite] def fromCanvasDynamic(width: Double, height: Double, scaleOutFactor: Double) + (fn: Graphics2D => Unit)(stopCheck: => Boolean) = picture.fromJava2dDynamic(width, height, scaleOutFactor, fn, stopCheck) - def fromSketch( - sketch: { - def setup(cd: CanvasDraw): Unit - def drawLoop(cd: CanvasDraw): Unit - }, - scaleOutFactor: Double = 1 - ): Picture = { + def fromSketch(sketch: { + def setup(cd: CanvasDraw): Unit + def drawLoop(cd: CanvasDraw): Unit + }, scaleOutFactor: Double = 1): Picture = { val sr = new SketchRunner(sketch, scaleOutFactor) sr.pic } @@ -772,8 +652,7 @@ Here's a partial list of the available commands: def circle(radius: Double) = picture.circle(radius) // def circle(x: Double, y: Double, r: Double) = picture.offset(x, y) -> picture.circle(r) def ellipse(xRadius: Double, yRadius: Double) = picture.ellipse(xRadius, yRadius) - def ellipseInRect(width: Double, height: Double) = - picture.trans(width / 2, height / 2) -> picture.ellipse(width / 2, height / 2) + def ellipseInRect(width: Double, height: Double) = picture.trans(width / 2, height / 2) -> picture.ellipse(width / 2, height / 2) // def ellipse(x: Double, y: Double, rx: Double, ry: Double) = picture.offset(x, y) -> picture.ellipse(rx, ry) def arc(radius: Double, angle: Double) = picture.arc(radius, angle) def point = picture.trans(0, -0.01 / 2) -> line(0, 0.01) @@ -875,13 +754,10 @@ Here's a partial list of the available commands: placeAndDraw(pic, 0, 0) } - def fromSketch( - sketch: { - def setup(cd: CanvasDraw): Unit - def drawLoop(cd: CanvasDraw): Unit - }, - scaleOutFactor: Double = 1 - ): Picture = { + def fromSketch(sketch: { + def setup(cd: CanvasDraw): Unit + def drawLoop(cd: CanvasDraw): Unit + }, scaleOutFactor: Double = 1): Picture = { val pic = Picture.fromSketch(sketch, scaleOutFactor) placeAndDraw(pic, 0, 0) } @@ -889,30 +765,14 @@ Here's a partial list of the available commands: val pm = PictureMaker type Animation = animation.Animation - def Transition( - durationSeconds: Double, - fromState: Seq[Double], - toState: Seq[Double], - easer: KEasing, - picMaker: Seq[Double] => Picture, - hideOnDone: Boolean - ): Animation = + def Transition(durationSeconds: Double, fromState: Seq[Double], toState: Seq[Double], easer: KEasing, + picMaker: Seq[Double] => Picture, hideOnDone: Boolean): Animation = animation.Animation(durationSeconds, fromState, toState, easer, picMaker, hideOnDone) - def Timeline( - duration: Double, - keyFrames: animation.KeyFrames, - easer: KEasing, - picMaker: Seq[Double] => Picture, - hideOnDone: Boolean - ): Animation = + def Timeline(duration: Double, keyFrames: animation.KeyFrames, easer: KEasing, + picMaker: Seq[Double] => Picture, hideOnDone: Boolean): Animation = animation.Animation(duration, keyFrames, Seq.fill(keyFrames.frames.length - 1)(easer), picMaker, hideOnDone) - def Timeline( - duration: Double, - keyFrames: animation.KeyFrames, - easers: Seq[KEasing], - picMaker: Seq[Double] => Picture, - hideOnDone: Boolean - ): Animation = + def Timeline(duration: Double, keyFrames: animation.KeyFrames, easers: Seq[KEasing], + picMaker: Seq[Double] => Picture, hideOnDone: Boolean): Animation = animation.Animation(duration, keyFrames, easers, picMaker, hideOnDone) implicit def iis2dds(is: (Int, Seq[Int])): (Double, Seq[Double]) = is match { case (i, si) => (i.toDouble, si.map(_.toDouble)) @@ -920,7 +780,7 @@ Here's a partial list of the available commands: implicit def ids2dds(is: (Int, Seq[Double])): (Double, Seq[Double]) = is match { case (i, sd) => (i.toDouble, sd) } - def KeyFrames(frames: (Double, Seq[Double])*) = animation.KeyFrames(frames) + def KeyFrames(frames: (Double, Seq[Double])*)= animation.KeyFrames(frames) def animSeq(as: Animation*): Animation = animSeq(as) def animSeq(as: collection.Seq[Animation]): Animation = animation.animSeq(as.toSeq) def animPar(as: Animation*): Animation = animPar(as) @@ -964,7 +824,7 @@ Here's a partial list of the available commands: } } - def makeCenteredMessage(message: String, color: Color = black, fontSize: Int = 15): Picture = { + private def makeCenteredMessage(message: String, color: Color = black, fontSize: Int = 15): Picture = { val cb = canvasBounds val te = textExtent(message, fontSize) penColor(color) * @@ -987,24 +847,12 @@ Here's a partial list of the available commands: gameTimeRunning = false } - def showGameTimeCountdown( - limitSecs: Int, - endMsg: => String, - color: Color = black, - fontSize: Int = 15, - dx: Double = 10, - dy: Double = 50 - ) = showGameTime(limitSecs, endMsg, color, fontSize, dx, dy, true) - - def showGameTime( - limitSecs: Int, - endMsg: => String, - color: Color = black, - fontSize: Int = 15, - dx: Double = 10, - dy: Double = 50, - countDown: Boolean = false - ): Unit = { + def showGameTimeCountdown(limitSecs: Int, endMsg: => String, color: Color = black, fontSize: Int = 15, + dx: Double = 10, dy: Double = 50) = showGameTime(limitSecs, endMsg, color, fontSize, dx, dy, true) + + + def showGameTime(limitSecs: Int, endMsg: => String, color: Color = black, fontSize: Int = 15, + dx: Double = 10, dy: Double = 50, countDown: Boolean = false): Unit = { if (gameTimeRunning) { return } @@ -1052,7 +900,6 @@ Here's a partial list of the available commands: cwidth = cb.width.toInt cheight = cb.height.toInt clearGameTime() - currGame = null } def size(width: Int, height: Int): Unit = { @@ -1105,13 +952,10 @@ Here's a partial list of the available commands: type CanvasDraw = net.kogics.kojo.lite.CanvasDraw import scala.language.reflectiveCalls - class SketchRunner private[lite] ( - sketch: { - def setup(cd: CanvasDraw): Unit - def drawLoop(cd: CanvasDraw): Unit - }, - scaleFactor: Double = 1 - ) { + class SketchRunner private[lite](sketch: { + def setup(cd: CanvasDraw): Unit + def drawLoop(cd: CanvasDraw): Unit + }, scaleFactor: Double = 1) { @volatile var inited = false @volatile var initStarted = false // to support breakpoints in setup @volatile var cd: CanvasDraw = null @@ -1137,22 +981,19 @@ Here's a partial list of the available commands: } } - def canvasSketch( - sketch: { - def setup(cd: CanvasDraw): Unit - def drawLoop(cd: CanvasDraw): Unit - }, - scaleOutFactor: Double = 1 - ): Unit = { + def canvasSketch(sketch: { + def setup(cd: CanvasDraw): Unit + def drawLoop(cd: CanvasDraw): Unit + }, scaleOutFactor: Double = 1): Unit = { val sr = new SketchRunner(sketch, scaleOutFactor) sr.draw() } type PictureDraw = net.kogics.kojo.lite.PictureDraw def pictureSketch(sketch: { - def setup(cd: PictureDraw): Unit - def drawLoop(cd: PictureDraw): Unit - }): Unit = { + def setup(cd: PictureDraw): Unit + def drawLoop(cd: PictureDraw): Unit + }): Unit = { setup(sketch.setup(PictureDraw)) drawLoop(sketch.drawLoop(PictureDraw)) @@ -1185,49 +1026,26 @@ Here's a partial list of the available commands: import java.util.concurrent.Future val initPic = stateView(initState) initPic.draw() - lazy val anim: Future[PActivity] = tCanvas.animateWithState((initState, initPic)) { - case (state, pic) => - val newState = nextState(state) - val pic2 = stateView(state) - pic.erase() - pic2.draw() - if (newState == state) { - tCanvas.stopAnimationActivity(anim) - } - (newState, pic2) - } - anim - } - - def animateWithSetupCanvasDraw(setupCanvas: CanvasDraw => Unit)(drawFrame: CanvasDraw => Unit): Unit = { - class Sketch { - def setup(canvas: CanvasDraw): Unit = { - setupCanvas(canvas) - } - - def drawLoop(canvas: CanvasDraw): Unit = { - drawFrame(canvas) + lazy val anim: Future[PActivity] = tCanvas.animateWithState((initState, initPic)) { case (state, pic) => + pic.erase() + val pic2 = stateView(state) + pic2.draw() + val newState = nextState(state) + if (newState == state) { + tCanvas.stopAnimationActivity(anim) } + (newState, pic2) } - - val sketch = new Sketch - val pic = Picture.fromSketch(sketch, 1) - draw(pic) + anim } - def animateWithCanvasDraw(drawFrame: CanvasDraw => Unit): Unit = { - animateWithSetupCanvasDraw { canvas => }(drawFrame) - } + def runAnimation[S](init: S, update: S => S, view: S => Picture): Unit = + animateWithRedraw(init, update, view) type Sub[M] = gaming.Sub[M] - type CmdQ[M] = gaming.CmdQ[M] val Subscriptions = gaming.Subscriptions - lazy val CollisionDetector = new gaming.CollisionDetector() - @volatile private var currGame: Option[gaming.Game[_, _]] = None def runGame[S, M](init: S, update: (S, M) => S, view: S => Picture, subscriptions: S => Seq[Sub[M]]): Unit = { - currGame = Some(new gaming.Game(init, update, view, subscriptions)) + new gaming.Game(init, update, view, subscriptions) } - - def runCommandQuery[M](cmdQ: CmdQ[M]): Unit = currGame.get.asInstanceOf[gaming.Game[_, M]].runCommandQuery(cmdQ) } diff --git a/src/main/scala/net/kogics/kojo/lite/CanvasDraw.scala b/src/main/scala/net/kogics/kojo/lite/CanvasDraw.scala index bd26af28b..2286f4026 100644 --- a/src/main/scala/net/kogics/kojo/lite/CanvasDraw.scala +++ b/src/main/scala/net/kogics/kojo/lite/CanvasDraw.scala @@ -1,9 +1,9 @@ package net.kogics.kojo.lite -import java.awt.geom.GeneralPath - import net.kogics.kojo.core.VertexShapeSupport +import java.awt.geom.GeneralPath + class CanvasDraw(g2d: java.awt.Graphics2D, width: Double, height: Double, val b: Builtins) extends VertexShapeSupport { import b._ diff --git a/src/main/scala/net/kogics/kojo/lite/CodeExecutionSupport.scala b/src/main/scala/net/kogics/kojo/lite/CodeExecutionSupport.scala index c5122ab02..85f2d96d2 100644 --- a/src/main/scala/net/kogics/kojo/lite/CodeExecutionSupport.scala +++ b/src/main/scala/net/kogics/kojo/lite/CodeExecutionSupport.scala @@ -15,25 +15,26 @@ package net.kogics.kojo package lite -import java.awt.event.ActionEvent -import java.awt.event.ActionListener import java.awt.Color import java.awt.Cursor +import java.awt.event.ActionEvent +import java.awt.event.ActionListener import java.io.OutputStream import java.io.PrintStream import java.io.Writer import java.util.logging.Logger + +import javax.swing.JButton +import javax.swing.JTextArea import javax.swing.event.DocumentEvent import javax.swing.event.DocumentListener import javax.swing.text.Utilities -import javax.swing.JButton -import javax.swing.JTextArea import net.kogics.kojo.core.CodingMode +import net.kogics.kojo.core.VanillaMode import net.kogics.kojo.core.Interpreter import net.kogics.kojo.core.RunContext import net.kogics.kojo.core.TwMode -import net.kogics.kojo.core.VanillaMode import net.kogics.kojo.history.CommandHistory import net.kogics.kojo.lite.canvas.SpriteCanvas import net.kogics.kojo.lite.i18n.LangInit @@ -42,22 +43,25 @@ import net.kogics.kojo.livecoding.InteractiveManipulator import net.kogics.kojo.livecoding.ManipulationContext import net.kogics.kojo.turtle.TurtleWorldAPI import net.kogics.kojo.util.FutureResult + import util.Utils object CodeExecutionSupport { - /** Contains the goal a user wants to reach, and the action he has to take for this. */ + /**Contains the goal a user wants to reach, and the action he has to take for this.*/ private case class Line(goal: String, action: Option[String]) - /** The End-of-Line String used to separate lines of the welcome message */ + /**The End-of-Line String used to separate lines of the welcome message*/ val EOL = "\n" - val goalActionSeparator = "→" // instead of -> in order to save one position. Christoph 2017-02-24 - - /** Composes a welcome message from the head and a tabulated arrangement of the instructions. Each instruction should - * have the format "goal -> action". The instructions are splitted at the first occurrence of "->" and then - * tabulated. The "->" are replaced by the unicode arrow \u2192 "→" in order to save one character position. In the - * end all "→" are one below another when using a monospace font. - */ + val goalActionSeparator = "→" //instead of -> in order to save one position. Christoph 2017-02-24 + + /** + * Composes a welcome message from the head and a tabulated arrangement of the instructions. + * Each instruction should have the format "goal -> action". + * The instructions are splitted at the first occurrence of "->" and then tabulated. + * The "->" are replaced by the unicode arrow \u2192 "→" in order to save one character position. + * In the end all "→" are one below another when using a monospace font. + */ def makeTabulatedWelcomeMessage(head: String, instructions: List[String]): String = { require(head != null, "head != null") require(instructions != null, "instructions != null") @@ -69,20 +73,20 @@ object CodeExecutionSupport { val maxGoalLine = (Line("", None) :: instructionsTrimmed).maxBy(line => line.goal.length) val maxGoalLen = maxGoalLine.goal.length val sb = new StringBuilder(head) - sb.append(EOL) + sb append EOL for (instr <- instructionsTrimmed) { - sb.append("* ") - sb.append(instr.goal) + sb append "* " + sb append instr.goal instr.action match { case Some(a) => - sb.append(" " * (maxGoalLen - instr.goal.length)) - sb.append(" ") - sb.append(goalActionSeparator) - sb.append(" ") - sb.append(a) - case None => // Nothing to append + sb append " " * (maxGoalLen - instr.goal.length) + sb append " " + sb append goalActionSeparator + sb append " " + sb append a + case None => //Nothing to append } - sb.append(EOL) + sb append EOL } sb.toString } @@ -90,21 +94,19 @@ object CodeExecutionSupport { } class CodeExecutionSupport( - TSCanvas: DrawingCanvasAPI, - Tw: TurtleWorldAPI, - Staging: staging.API, - storyTeller: story.StoryTeller, - mp3player: music.KMp3, - fuguePlayer: music.FuguePlayer, - tCanvas: SpriteCanvas, - scriptEditor0: => ScriptEditor, - val kojoCtx: core.KojoCtx -) extends core.CodeExecutionSupport - with core.CodeCompletionSupport - with ManipulationContext { + TSCanvas: DrawingCanvasAPI, + Tw: TurtleWorldAPI, + Staging: staging.API, + storyTeller: story.StoryTeller, + mp3player: music.KMp3, + fuguePlayer: music.FuguePlayer, + tCanvas: SpriteCanvas, + scriptEditor0: => ScriptEditor, + val kojoCtx: core.KojoCtx +) extends core.CodeExecutionSupport with core.CodeCompletionSupport with ManipulationContext { // the script editor that gets passed in is not yet inited (the last remaining circular dependency!) // we access it via a lazy val - // and then import the stuff inside it, + // and then import the stuff inside it, // which we could not do if we used a regular var that was inited in phase 2 lazy val scriptEditor = scriptEditor0 import scriptEditor._ @@ -241,7 +243,7 @@ class CodeExecutionSupport( showOutput(Utils.loadString("S_OutputScratchpadHistoryNotSave") + "\n", Color.red) } else { - val head = Utils.loadString("S_OutputWelcome").format(Versions.KojoVersion) + val head = Utils.loadString("S_OutputWelcome") format Versions.KojoVersion val instructions = List( Utils.loadString("S_OutputVisualPalette"), Utils.loadString("S_OutputHelp"), @@ -569,46 +571,30 @@ class CodeExecutionSupport( def enableClearButton() = if (!clearButton.isEnabled) clearButton.setEnabled(true) - @volatile var inputBeingRead = false - - def removeInputPanel(): Unit = { - inputBeingRead = false - outputPane.removeInputPanel() - } - def readInput(prompt: String): String = { if (Utils.inSwingThread) { throw new RuntimeException("Input can't be read from the GUI thread") } else { - if (!inputBeingRead) { - inputBeingRead = true - val input = new FutureResult[String] - Utils.runInSwingThread { - val inputField = outputPane.createReadInputPanel(prompt) - kojoCtx.activateOutputPane() - Utils.schedule(0.1) { - inputField.requestFocusInWindow(); - kojoCtx.scrollOutputToEnd() - } - Utils.schedule(0.9) { - inputField.requestFocusInWindow() - } - inputField.addActionListener(new ActionListener { - def actionPerformed(e: ActionEvent): Unit = { - // println("%s: %s" format (prompt, inputField.getText)) - input.set(inputField.getText) - outputPane.removeInputPanel() - } - }) + val input = new FutureResult[String] + Utils.runInSwingThread { + val inputField = outputPane.createReadInputPanel(prompt) + kojoCtx.activateOutputPane() + Utils.schedule(0.1) { + inputField.requestFocusInWindow(); kojoCtx.scrollOutputToEnd() } - val ret = input.get - inputBeingRead = false - ret - } - else { - throw new RuntimeException("Input reads cannot overlap") + Utils.schedule(0.9) { + inputField.requestFocusInWindow() + } + inputField.addActionListener(new ActionListener { + def actionPerformed(e: ActionEvent): Unit = { + // println("%s: %s" format (prompt, inputField.getText)) + input.set(inputField.getText) + outputPane.removeInputPanel() + } + }) } + input.get } } @@ -639,7 +625,7 @@ class CodeExecutionSupport( else { stopInterpreter() stopActivity() - removeInputPanel() + outputPane.removeInputPanel() } } @@ -654,7 +640,6 @@ class CodeExecutionSupport( fuguePlayer.stopBgMusic() mp3player.stopMp3() mp3player.stopMp3Loop() - builtins.stopNotePlayer() } def invalidCode(code: String): Boolean = { @@ -834,22 +819,20 @@ class CodeExecutionSupport( // impure function! def extendSelection(code2run: CodeToRun) = { - code2run.selection - .map { - case (selStart, selEnd) => - val selStartLine = codePane.getLineOfOffset(selStart) - val selEndLine = codePane.getLineOfOffset(selEnd) - val selStartLineStart = codePane.getLineStartOffset(selStartLine) - val selStartLineEnd = getVisibleLineEndOffset(selStartLine) - val selEndLineStart = codePane.getLineStartOffset(selEndLine) - val selEndLineEnd = getVisibleLineEndOffset(selEndLine) - val newSelStart = if (selStartLineEnd == selStart) selStart else selStartLineStart - val newSelEnd = if (selEndLineStart == selEnd) selEnd else selEndLineEnd - codePane.setSelectionStart(newSelStart) - codePane.setSelectionEnd(newSelEnd) - CodeToRun(codePane.getSelectedText, Some(newSelStart, newSelEnd)) - } - .getOrElse(code2run) + code2run.selection.map { + case (selStart, selEnd) => + val selStartLine = codePane.getLineOfOffset(selStart) + val selEndLine = codePane.getLineOfOffset(selEnd) + val selStartLineStart = codePane.getLineStartOffset(selStartLine) + val selStartLineEnd = getVisibleLineEndOffset(selStartLine) + val selEndLineStart = codePane.getLineStartOffset(selEndLine) + val selEndLineEnd = getVisibleLineEndOffset(selEndLine) + val newSelStart = if (selStartLineEnd == selStart) selStart else selStartLineStart + val newSelEnd = if (selEndLineStart == selEnd) selEnd else selEndLineEnd + codePane.setSelectionStart(newSelStart) + codePane.setSelectionEnd(newSelEnd) + CodeToRun(codePane.getSelectedText, Some(newSelStart, newSelEnd)) + } getOrElse code2run } // Impure function! @@ -939,8 +922,7 @@ class CodeExecutionSupport( val codeAndOffset = completionCodeAndOffset(caretOffset) codeRunner.memberCompletions(codeAndOffset._1, codeAndOffset._2, objid, prefix) } - def objidAndPrefix(caretOffset: Int): (Option[String], Option[String]) = - xscala.CodeCompletionUtils.findIdentifier(codeFragment(caretOffset)) + def objidAndPrefix(caretOffset: Int): (Option[String], Option[String]) = xscala.CodeCompletionUtils.findIdentifier(codeFragment(caretOffset)) def typeAt(caretOffset: Int) = { val codeAndOffset = completionCodeAndOffset(caretOffset) codeRunner.typeAt(codeAndOffset._1, codeAndOffset._2) @@ -1012,7 +994,8 @@ class CodeExecutionSupport( // codePane.requestFocusInWindow } - def codeRunError() = {} + def codeRunError() = { + } def codeRun(code: String): Unit = { val tcode = code.trim() diff --git a/src/main/scala/net/kogics/kojo/lite/CoreBuiltins.scala b/src/main/scala/net/kogics/kojo/lite/CoreBuiltins.scala index bd516842e..e08abc5eb 100644 --- a/src/main/scala/net/kogics/kojo/lite/CoreBuiltins.scala +++ b/src/main/scala/net/kogics/kojo/lite/CoreBuiltins.scala @@ -1,25 +1,26 @@ package net.kogics.kojo package lite -import java.awt.{ Color => JColor } -import java.awt.{ Font => JFont } -import java.awt.image.BufferedImage import java.awt.GraphicsEnvironment import java.awt.Paint +import java.awt.image.BufferedImage +import java.awt.{Color => JColor} +import java.awt.{Font => JFont} import java.net.URL import java.util.concurrent.CountDownLatch import scala.language.implicitConversions -import io.github.jdiemke.triangulation.Triangle2D import net.kogics.kojo.core.Rectangle import net.kogics.kojo.core.TSCanvasFeatures import net.kogics.kojo.kmath.Rationals -import net.kogics.kojo.picture.PicCache import net.kogics.kojo.turtle.LoTurtle import net.kogics.kojo.util.PerlinNoiseImproved import net.kogics.kojo.util.PerlinNoiseProcessing import net.kogics.kojo.util.Utils +import net.kogics.kojo.picture.PicCache + +import io.github.jdiemke.triangulation.Triangle2D trait CoreBuiltins extends Rationals { def TSCanvas: TSCanvasFeatures @@ -63,7 +64,7 @@ trait CoreBuiltins extends Rationals { val cm = doodle.Color implicit def rc2c(rc: doodle.Color): Color = rc.toAwt implicit def c2rc(c: Color): doodle.Color = Utils.awtColorToDoodleColor(c) - implicit def rcSeq2cSeq(rcs: collection.Seq[doodle.Color]): collection.Seq[Color] = rcs.map(rc2c) + implicit def rcSeq2cSeq(rcs: collection.Seq[doodle.Color]): collection.Seq[Color] = rcs map rc2c // val Color = staging.KColor val noColor = C.noColor @@ -111,18 +112,15 @@ trait CoreBuiltins extends Rationals { def setRandomSeed(seed: Long): Unit = { Random.setSeed(seed) } def random(upperBound: Int) = Random.nextInt(upperBound) def random(lowerBound: Int, upperBound: Int): Int = { - if (lowerBound >= upperBound) lowerBound - else + if (lowerBound >= upperBound) lowerBound else lowerBound + random(upperBound - lowerBound) } def randomDouble(upperBound: Double): Double = { - if ((upperBound == 0) || (upperBound != upperBound)) 0 - else + if ((upperBound == 0) || (upperBound != upperBound)) 0 else Random.nextDouble * upperBound } def randomDouble(lowerBound: Double, upperBound: Double): Double = { - if (lowerBound >= upperBound) lowerBound - else + if (lowerBound >= upperBound) lowerBound else lowerBound + randomDouble(upperBound - lowerBound) } @@ -132,9 +130,8 @@ trait CoreBuiltins extends Rationals { def randomInt = Random.nextInt def randomLong = Random.nextLong def randomFrom[T](seq: collection.Seq[T]) = seq(random(seq.length)) - def randomFrom[T](seq: collection.Seq[T], weights: Seq[Int]): T = randomFrom(seq, weights.map(_.toDouble)) - def randomFrom[T](seq: collection.Seq[T], weights: collection.mutable.Seq[Int]): T = - randomFrom(seq, weights.map(_.toDouble)) + def randomFrom[T](seq: collection.Seq[T], weights: Seq[Int]): T = randomFrom(seq, weights map (_.toDouble)) + def randomFrom[T](seq: collection.Seq[T], weights: collection.mutable.Seq[Int]): T = randomFrom(seq, weights map (_.toDouble)) def randomFrom[T](seq: collection.Seq[T], weights: collection.Seq[Double]): T = { val sum = weights.sum val probabilities = if (Utils.doublesEqual(sum, 1.0, 1e-3)) { @@ -175,7 +172,7 @@ trait CoreBuiltins extends Rationals { import io.github.jdiemke.triangulation.DelaunayTriangulator import io.github.jdiemke.triangulation.Vector2D - val triangulator = new DelaunayTriangulator(points.map { p => new Vector2D(p.x, p.y) }.asJava) + val triangulator = new DelaunayTriangulator((points map { p => new Vector2D(p.x, p.y) }).asJava) triangulator.triangulate() val tr = triangulator.getTriangles tr.asScala @@ -188,29 +185,12 @@ trait CoreBuiltins extends Rationals { def Color(rgbHex: Int, hasAlpha: Boolean = false) = new Color(rgbHex, hasAlpha) def ColorG(x1: Double, y1: Double, c1: Color, x2: Double, y2: Double, c2: Color, cyclic: Boolean = false) = cm.linearGradient(x1, y1, c1, x2, y2, c2, cyclic) - def ColorRadialG( - x: Double, - y: Double, - radius: Double, - distribution: collection.Seq[Double], - colors: collection.Seq[Color], - cyclic: Boolean = false - ) = + def ColorRadialG(x: Double, y: Double, radius: Double, distribution: collection.Seq[Double], colors: collection.Seq[Color], cyclic: Boolean = false) = cm.radialMultipleGradient(x, y, radius, distribution, colors, cyclic) - def ColorLinearG( - x1: Double, - y1: Double, - x2: Double, - y2: Double, - distribution: collection.Seq[Double], - colors: collection.Seq[Color], - cyclic: Boolean = false - ) = + def ColorLinearG(x1: Double, y1: Double, x2: Double, y2: Double, distribution: collection.Seq[Double], colors: collection.Seq[Color], cyclic: Boolean = false) = cm.linearMultipleGradient(x1, y1, x2, y2, distribution, colors, cyclic) - def ColorHSB(h: Double, s: Double, b: Double) = - java.awt.Color.getHSBColor((h / 360).toFloat, (s / 100).toFloat, (b / 100).toFloat) - def pause(seconds: Double) = pauseMillis((seconds * 1000).toLong) - def pauseMillis(milliSeconds: Long) = Thread.sleep(milliSeconds) + def ColorHSB(h: Double, s: Double, b: Double) = java.awt.Color.getHSBColor((h / 360).toFloat, (s / 100).toFloat, (b / 100).toFloat) + def pause(secs: Double) = Thread.sleep((secs * 1000).toLong) def clearOutput(): Unit def readln(prompt: String): String @@ -251,7 +231,7 @@ trait CoreBuiltins extends Rationals { def scale(xf: Double, yf: Double) = picture.scale(xf, yf) def scalep(f: Double, x: Double, y: Double) = picture.scalep(f, x, y) def draw(pictures: Picture*): Unit = draw(pictures) - protected[lite] def checkForLargeDrawing(): Unit = { + protected [lite] def checkForLargeDrawing(): Unit = { if (PicCache.size > 60000) { println("There are too many pics in your drawing, and trying to draw them might freeze Kojo.") println("If you still want to go ahead with this, use the pic.draw() method.") diff --git a/src/main/scala/net/kogics/kojo/lite/DesktopMain.scala b/src/main/scala/net/kogics/kojo/lite/DesktopMain.scala index 2e7a47d48..544a5e6cd 100644 --- a/src/main/scala/net/kogics/kojo/lite/DesktopMain.scala +++ b/src/main/scala/net/kogics/kojo/lite/DesktopMain.scala @@ -21,4 +21,4 @@ object DesktopMain extends StubMain with RmiMultiInstance { val cp = System.getProperty("java.class.path").split(File.pathSeparatorChar).toList createCp(cp) } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/DrawingCanvasAPI.scala b/src/main/scala/net/kogics/kojo/lite/DrawingCanvasAPI.scala index 981b51e0a..aea0d219a 100644 --- a/src/main/scala/net/kogics/kojo/lite/DrawingCanvasAPI.scala +++ b/src/main/scala/net/kogics/kojo/lite/DrawingCanvasAPI.scala @@ -5,13 +5,14 @@ import java.awt.Color import java.awt.Paint import java.util.concurrent.Future -import edu.umd.cs.piccolo.activities.PActivity import net.kogics.kojo.core.SCanvas import net.kogics.kojo.core.TSCanvasFeatures import net.kogics.kojo.core.Turtle import net.kogics.kojo.core.UnitLen import net.kogics.kojo.util.UserCommand +import edu.umd.cs.piccolo.activities.PActivity + // Turtle and Staging Canvas class DrawingCanvasAPI(val tCanvas: SCanvas) extends TSCanvasFeatures { def turtle0 = tCanvas.turtle0 @@ -25,7 +26,7 @@ class DrawingCanvasAPI(val tCanvas: SCanvas) extends TSCanvasFeatures { def zoom(factor: Double, cx: Double, cy: Double) = tCanvas.zoom(factor, cx, cy) UserCommand("zoom", List("factor"), "Zooms in by the given factor, leaving the center point unchanged.") UserCommand.addSynopsisSeparator() - + def scroll(x: Double, y: Double) = tCanvas.scroll(x, y) def viewRotate(a: Double): Unit = tCanvas.viewRotate(a) @@ -43,16 +44,15 @@ class DrawingCanvasAPI(val tCanvas: SCanvas) extends TSCanvasFeatures { def hideAxes() = tCanvas.hideAxes() UserCommand("axesOff", Nil, "Hides the X and Y axes.") - def showProtractor() = tCanvas.showProtractor(-tCanvas.cbounds.getWidth / 2, -tCanvas.cbounds.getHeight / 2) + def showProtractor() = tCanvas.showProtractor(-tCanvas.cbounds.getWidth/2, -tCanvas.cbounds.getHeight/2) def showProtractor(x: Double, y: Double) = tCanvas.showProtractor(x, y) def hideProtractor() = tCanvas.hideProtractor() - def showScale() = tCanvas.showScale(-tCanvas.cbounds.getWidth / 2, tCanvas.cbounds.getHeight / 2) + def showScale() = tCanvas.showScale(-tCanvas.cbounds.getWidth/2, tCanvas.cbounds.getHeight/2) def showScale(x: Double, y: Double) = tCanvas.showScale(x, y) def hideScale() = tCanvas.hideScale() - + def newTurtle(): Turtle = newTurtle(0, 0) - def newTurtle(x: Double = 0, y: Double = 0, costume: String = "/images/turtle32.png") = - tCanvas.newTurtle(x, y, costume) + def newTurtle(x: Double = 0, y: Double = 0, costume: String = "/images/turtle32.png") = tCanvas.newTurtle(x, y, costume) def exportImage(filePrefix: String) = tCanvas.exportImage(filePrefix) def exportImage(filePrefix: String, width: Int, height: Int) = tCanvas.exportImage(filePrefix, width, height) @@ -89,8 +89,8 @@ class DrawingCanvasAPI(val tCanvas: SCanvas) extends TSCanvasFeatures { def timerWithState[S](rate: Long, init: S)(code: S => S): Future[PActivity] = tCanvas.timerWithState(rate, init)(code) def animate(code: => Unit) = tCanvas.animate(code) - def animateWithState[S](initState: S)(nextState: S => S): Future[PActivity] = - tCanvas.animateWithState(initState)(nextState) + def animateWithState[S](init: S)(code: S => S): Future[PActivity] = + tCanvas.animateWithState(init)(code) // def animateWithState[S](init: S, nextState: S => S)(code: S => Unit): Future[PActivity] = { // tCanvas.animateWithState(init) { s => // code(s) diff --git a/src/main/scala/net/kogics/kojo/lite/EditorFileSupport.scala b/src/main/scala/net/kogics/kojo/lite/EditorFileSupport.scala index d98d9bcf5..29501eeed 100644 --- a/src/main/scala/net/kogics/kojo/lite/EditorFileSupport.scala +++ b/src/main/scala/net/kogics/kojo/lite/EditorFileSupport.scala @@ -1,10 +1,9 @@ package net.kogics.kojo.lite -import java.io.File import javax.swing.JOptionPane - -import net.kogics.kojo.util.RichFile +import java.io.File import net.kogics.kojo.util.Utils +import net.kogics.kojo.util.RichFile trait EditorFileSupport { self: ScriptEditor => var openedFile: Option[File] = None @@ -43,8 +42,7 @@ trait EditorFileSupport { self: ScriptEditor => if (fileChanged) { val doSave = JOptionPane.showConfirmDialog( kojoCtx.frame, - Utils.loadString("S_FileChanged").format(openedFile.get.getName, openedFile.get.getName) - ) + Utils.loadString("S_FileChanged").format(openedFile.get.getName, openedFile.get.getName)) if (doSave == JOptionPane.CANCEL_OPTION || doSave == JOptionPane.CLOSED_OPTION) { throw new RuntimeException("Cancel File Close") } @@ -88,7 +86,9 @@ trait EditorFileSupport { self: ScriptEditor => def saveAs(file: java.io.File): Unit = { if (file.exists) { - val doSave = JOptionPane.showConfirmDialog(kojoCtx.frame, Utils.loadString("S_FileExists").format(file.getName)) + val doSave = JOptionPane.showConfirmDialog( + kojoCtx.frame, + Utils.loadString("S_FileExists") format (file.getName)) if (doSave == JOptionPane.CANCEL_OPTION || doSave == JOptionPane.CLOSED_OPTION) { throw new RuntimeException("Cancel File SaveAs") } @@ -127,4 +127,4 @@ trait EditorFileSupport { self: ScriptEditor => } } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/JoyStick.scala b/src/main/scala/net/kogics/kojo/lite/JoyStick.scala index 8cff6a5e3..a1ae7d809 100644 --- a/src/main/scala/net/kogics/kojo/lite/JoyStick.scala +++ b/src/main/scala/net/kogics/kojo/lite/JoyStick.scala @@ -56,32 +56,18 @@ class JoyStick(radius: Double)(builtins: Builtins) { def currentVector = currentVec - def movePlayerHelper( - player: Picture, - scaleVelocity: Double = 1, - directionConstraint: net.kogics.kojo.util.Vector2D = null - ) = { - val vel = - if (directionConstraint == null) - currentVector * scaleVelocity - else currentVector.project(directionConstraint) * scaleVelocity + def movePlayerHelper(player: Picture, scaleVelocity: Double = 1, directionConstraint: net.kogics.kojo.util.Vector2D = null) = { + val vel = if (directionConstraint == null) + currentVector * scaleVelocity else currentVector.project(directionConstraint) * scaleVelocity player.offset(vel) vel } - def movePlayer( - player: Picture, - scaleVelocity: Double = 1, - directionConstraint: net.kogics.kojo.util.Vector2D = null - ): Unit = { + def movePlayer(player: Picture, scaleVelocity: Double = 1, directionConstraint: net.kogics.kojo.util.Vector2D = null): Unit = { movePlayerHelper(player, scaleVelocity, directionConstraint) } - def movePlayerWithinStage( - player: Picture, - scaleVelocity: Double = 1, - directionConstraint: net.kogics.kojo.util.Vector2D = null - ): Unit = { + def movePlayerWithinStage(player: Picture, scaleVelocity: Double = 1, directionConstraint: net.kogics.kojo.util.Vector2D = null): Unit = { import builtins.TSCanvas._ val vel = movePlayerHelper(player, scaleVelocity, directionConstraint) diff --git a/src/main/scala/net/kogics/kojo/lite/KojoCompletionProvider.scala b/src/main/scala/net/kogics/kojo/lite/KojoCompletionProvider.scala index 4be41cbd2..c77261be7 100644 --- a/src/main/scala/net/kogics/kojo/lite/KojoCompletionProvider.scala +++ b/src/main/scala/net/kogics/kojo/lite/KojoCompletionProvider.scala @@ -2,21 +2,16 @@ package net.kogics.kojo package lite import java.awt.Point -import java.util.logging.Logger import java.util.List -import javax.swing.text.JTextComponent - -import scala.collection.mutable +import java.util.logging.Logger +import javax.swing.text.JTextComponent import net.kogics.kojo.core.CompletionInfo import net.kogics.kojo.util.Utils -import net.kogics.kojo.xscala.CodeCompletionUtils -import net.kogics.kojo.xscala.CodeTemplates -import net.kogics.kojo.xscala.Help -import org.fife.ui.autocomplete.Completion -import org.fife.ui.autocomplete.CompletionCellRenderer -import org.fife.ui.autocomplete.CompletionProviderBase -import org.fife.ui.autocomplete.TemplateCompletion +import net.kogics.kojo.xscala.{CodeCompletionUtils, CodeTemplates, Help} +import org.fife.ui.autocomplete.{Completion, CompletionCellRenderer, CompletionProviderBase, TemplateCompletion} + +import scala.collection.mutable class KojoCompletionProvider(execSupport: CodeExecutionSupport) extends CompletionProviderBase { val Log = Logger.getLogger(getClass.getName) @@ -32,19 +27,13 @@ class KojoCompletionProvider(execSupport: CodeExecutionSupport) extends Completi setAutoActivationRules(false, null) def rtsaTemplate(t: String) = { - val res = if (t.contains("${")) t else "%s${cursor}".format(t) + val res = if (t.contains("${")) t else "%s${cursor}" format (t) res } def proposal(offset: Int, completion: String, kind: Int, template: String) = { - new TemplateCompletion( - this, - completion, - completion, - rtsaTemplate(if (template == null) completion else template), - null, - Help(completion) - ) { + new TemplateCompletion(this, completion, completion, rtsaTemplate(if (template == null) completion else template), + null, Help(completion)) { setRelevance(kind) override def getIcon = kindIcon(kind) } @@ -102,8 +91,7 @@ class KojoCompletionProvider(execSupport: CodeExecutionSupport) extends Completi if (knownCompletion) { var template = methodTemplate(qualifiedName) if (template == "") None - else if (template != null) Some(template) - else { + else if (template != null) Some(template) else { if (specialOwner) { template = methodTemplate(completion.name) if (template != null) Some(template) else None @@ -124,8 +112,7 @@ class KojoCompletionProvider(execSupport: CodeExecutionSupport) extends Completi def knownHelp: Option[String] = { if (knownCompletion) { var help = Help(qualifiedName) - if (help != null) Some(help) - else { + if (help != null) Some(help) else { if (specialOwner) { help = Help(completion.name) if (help != null) Some(help) else None @@ -165,11 +152,7 @@ class KojoCompletionProvider(execSupport: CodeExecutionSupport) extends Completi CodeCompletionUtils.methodTemplate(completion) } - def addTemplateProposals( - proposals: collection.mutable.ArrayBuffer[Completion], - prefix: String, - caretOffset: Int - ): Unit = { + def addTemplateProposals(proposals: collection.mutable.ArrayBuffer[Completion], prefix: String, caretOffset: Int): Unit = { CodeTemplates.templates.filter { kv => kv._1.startsWith(prefix) }.foreach { kv => val name = kv._1; val value = kv._2 proposals.append( @@ -193,7 +176,9 @@ class KojoCompletionProvider(execSupport: CodeExecutionSupport) extends Completi val (varCompletions, voffset) = execSupport.varCompletions(prefix) varCompletions.foreach { completion => if (!completion.contains("$")) { - proposals.append(proposal(caretOffset - voffset, completion, VARIABLE, methodTemplate(completion))) + proposals.append(proposal(caretOffset - voffset, completion, + VARIABLE, + methodTemplate(completion))) } } @@ -204,16 +189,15 @@ class KojoCompletionProvider(execSupport: CodeExecutionSupport) extends Completi } catch { case t: Throwable => - /*Log.warning*/ - println(s"Completion Problem for: ${completion.name} -- ${t.getMessage()}") + /*Log.warning*/ println(s"Completion Problem for: ${completion.name} -- ${t.getMessage()}") } } val (keywordCompletions, koffset) = execSupport.keywordCompletions(prefix) keywordCompletions.foreach { completion => - proposals.append( - proposal(caretOffset - koffset, completion, KEYWORD, CodeCompletionUtils.keywordTemplate(completion)) - ) + proposals.append(proposal(caretOffset - koffset, completion, + KEYWORD, + CodeCompletionUtils.keywordTemplate(completion))) } addTemplateProposals(proposals, prefix.getOrElse(""), caretOffset) @@ -227,8 +211,7 @@ class KojoCompletionProvider(execSupport: CodeExecutionSupport) extends Completi } catch { case t: Throwable => - /*Log.warning*/ - println("Completion Problem 2: " + t.getMessage()) + /*Log.warning*/ println("Completion Problem 2: " + t.getMessage()) } execSupport.kojoCtx.hideAppWaitCursor() val proposals2 = new java.util.ArrayList[Completion] @@ -266,7 +249,7 @@ class KojoCompletionProvider(execSupport: CodeExecutionSupport) extends Completi // there is a previous proposal // does it have help? if (hasHelp(c)) { - // don't add current proposal + // don't add current proposal } else { // no help @@ -300,16 +283,8 @@ class KojoCompletionProvider(execSupport: CodeExecutionSupport) extends Completi if (execSupport.startingUp) { val proposals = new java.util.ArrayList[Completion] val completion = "Please try again soon..." - proposals.add( - new TemplateCompletion( - this, - completion, - completion, - "${cursor}", - null, - "Kojo is starting up, and the Code Completion Engine is not available yet." - ) - ) + proposals.add(new TemplateCompletion(this, completion, completion, "${cursor}", null, + "Kojo is starting up, and the Code Completion Engine is not available yet.")) proposals } else if (execSupport.isRunningEnabled) { @@ -318,20 +293,12 @@ class KojoCompletionProvider(execSupport: CodeExecutionSupport) extends Completi else { val proposals = new java.util.ArrayList[Completion] val completion = "Please try again soon..." - proposals.add( - new TemplateCompletion( - this, - completion, - completion, - "${cursor}", - null, - "The Code Completion Engine is currently blocked (probably because a script is running)." - ) - ) + proposals.add(new TemplateCompletion(this, completion, completion, "${cursor}", null, + "The Code Completion Engine is currently blocked (probably because a script is running).")) proposals } } override def getParameterizedCompletions(comp: JTextComponent) = throw new UnsupportedOperationException override def getCompletionsAt(comp: JTextComponent, pt: Point) = throw new UnsupportedOperationException -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/KojoCtx.scala b/src/main/scala/net/kogics/kojo/lite/KojoCtx.scala index 65d25657b..cb86ab319 100644 --- a/src/main/scala/net/kogics/kojo/lite/KojoCtx.scala +++ b/src/main/scala/net/kogics/kojo/lite/KojoCtx.scala @@ -16,27 +16,23 @@ package net.kogics.kojo package lite -import java.awt.geom.Point2D import java.awt.Color import java.awt.Cursor import java.awt.Dimension import java.awt.Font import java.awt.Toolkit +import java.awt.geom.Point2D import java.io.File import java.io.FileInputStream -import java.util.prefs.Preferences import java.util.Properties -import javax.swing.plaf.FontUIResource +import java.util.prefs.Preferences + import javax.swing.JCheckBoxMenuItem import javax.swing.JFrame import javax.swing.JMenu import javax.swing.UIManager +import javax.swing.plaf.FontUIResource -import bibliothek.gui.dock.common.mode.ExtendedMode -import bibliothek.gui.dock.common.CControl -import bibliothek.gui.dock.common.CGrid -import bibliothek.gui.dock.common.CLocation -import bibliothek.gui.dock.common.DefaultSingleCDockable import net.kogics.kojo.action.CloseFile import net.kogics.kojo.core.DelegatingSpriteListener import net.kogics.kojo.core.Picture @@ -49,6 +45,12 @@ import net.kogics.kojo.lite.i18n.LangInit import net.kogics.kojo.story.StoryTeller import net.kogics.kojo.util.Utils +import bibliothek.gui.dock.common.CControl +import bibliothek.gui.dock.common.CGrid +import bibliothek.gui.dock.common.CLocation +import bibliothek.gui.dock.common.DefaultSingleCDockable +import bibliothek.gui.dock.common.mode.ExtendedMode + class KojoCtx(val subKojo: Boolean) extends core.KojoCtx { val prefs = Preferences.userRoot().node("Kojolite-Prefs") @@ -328,8 +330,7 @@ class KojoCtx(val subKojo: Boolean) extends core.KojoCtx { prefs.put("lastLoadStoreDir", lastLoadStoreDir) } - @volatile var _lastColor = - new Color(Integer.parseInt(prefs.get("lastColor", Integer.toString(Color.red.getRGB()))), true) + @volatile var _lastColor = new Color(Integer.parseInt(prefs.get("lastColor", Integer.toString(Color.red.getRGB()))), true) def lastColor: Color = _lastColor def lastColor_=(c: Color): Unit = { _lastColor = c @@ -462,4 +463,4 @@ class KojoCtx(val subKojo: Boolean) extends core.KojoCtx { def insertOutputError(text: String): Unit = { topcs.owh.outputPane.showError(text) } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/KojoScratchpadRunner.scala b/src/main/scala/net/kogics/kojo/lite/KojoScratchpadRunner.scala index c1599ec3d..37c67b019 100644 --- a/src/main/scala/net/kogics/kojo/lite/KojoScratchpadRunner.scala +++ b/src/main/scala/net/kogics/kojo/lite/KojoScratchpadRunner.scala @@ -1,9 +1,7 @@ package net.kogics.kojo.lite import java.io.File - -import scala.sys.process.Process -import scala.sys.process.ProcessLogger +import scala.sys.process.{Process, ProcessLogger} object KojoScratchpadRunner { def newScratchPad(): Unit = { @@ -25,9 +23,11 @@ object KojoScratchpadRunner { ) val processLogger = new ProcessLogger { - override def out(s: => String): Unit = {} + override def out(s: => String): Unit = { + } - override def err(s: => String): Unit = {} + override def err(s: => String): Unit = { + } override def buffer[T](f: => T): T = ??? } diff --git a/src/main/scala/net/kogics/kojo/lite/LangMenuFactory.scala b/src/main/scala/net/kogics/kojo/lite/LangMenuFactory.scala index f5cb82f60..1c8855335 100644 --- a/src/main/scala/net/kogics/kojo/lite/LangMenuFactory.scala +++ b/src/main/scala/net/kogics/kojo/lite/LangMenuFactory.scala @@ -15,23 +15,17 @@ */ package net.kogics.kojo.lite -import java.awt.event.ActionEvent -import java.awt.event.ActionListener -import javax.swing.ImageIcon -import javax.swing.JCheckBoxMenuItem -import javax.swing.JMenu -import javax.swing.JOptionPane - +import javax.swing.{JMenu, JOptionPane, JCheckBoxMenuItem, ImageIcon} import net.kogics.kojo.core +import java.awt.event.{ActionEvent, ActionListener} import net.kogics.kojo.util.Utils -/** Creates the Language menu. - * - * @author - * Eric Zoerner eric.zoerner@gmail.com - * @author - * Christoph Knabe http://public.beuth-hochschule.de/~knabe/ - */ +/** + * Creates the Language menu. + * + * @author Eric Zoerner eric.zoerner@gmail.com + * @author Christoph Knabe http://public.beuth-hochschule.de/~knabe/ + */ object LangMenuFactory { val supportedLanguages = List("en", "sv", "fr", "pl", "nl", "eo", /*"hi", */ "de", "ru", "it", "hr", "tr", "es") @@ -42,17 +36,16 @@ object LangMenuFactory { override def actionPerformed(e: ActionEvent): Unit = { val lang = e.getActionCommand kojoCtx.userLanguage = lang - langMenus.foreach { mi => - if (mi.getActionCommand != lang) { - mi.setSelected(false) - } + langMenus foreach { + mi => + if (mi.getActionCommand != lang) { + mi.setSelected(false) + } } - JOptionPane.showMessageDialog( - kojoCtx.frame, - Utils.loadString("S_LangChanged").format(e.getSource.asInstanceOf[JCheckBoxMenuItem].getText), - Utils.loadString("S_LangChange"), - JOptionPane.INFORMATION_MESSAGE - ) + JOptionPane.showMessageDialog(kojoCtx.frame, + Utils.loadString("S_LangChanged").format(e.getSource.asInstanceOf[JCheckBoxMenuItem].getText), + Utils.loadString("S_LangChange"), + JOptionPane.INFORMATION_MESSAGE) } } @@ -75,11 +68,11 @@ object LangMenuFactory { Utils.loadIcon("/images/generic-flag.png") // langIcon(kojoCtx.userLanguage) ) - supportedLanguages.foreach { lang => langMenu.add(langMenuItem(lang)) } + supportedLanguages.foreach {lang => langMenu.add(langMenuItem(lang))} langMenu } - private val langNames = Map( + private val langNames = Map ( "en" -> "English", "sv" -> "Svenska (Swedish)", "fr" -> "Français (French)", diff --git a/src/main/scala/net/kogics/kojo/lite/MacTweaks.scala b/src/main/scala/net/kogics/kojo/lite/MacTweaks.scala index c525aeff2..0f2f19110 100644 --- a/src/main/scala/net/kogics/kojo/lite/MacTweaks.scala +++ b/src/main/scala/net/kogics/kojo/lite/MacTweaks.scala @@ -15,24 +15,18 @@ package net.kogics.kojo.lite import javax.swing.JFrame - import net.kogics.kojo.util.Utils class MacTweaks { def tweak(frame: JFrame): Unit = { - import com.apple.eawt.{ AboutHandler, Application }; import com.apple.eawt.AppEvent.AboutEvent; - import javax.swing.JOptionPane + import com.apple.eawt.{ AboutHandler, Application }; import com.apple.eawt.AppEvent.AboutEvent; import javax.swing.JOptionPane val app = Application.getApplication app.setDockIconImage(Utils.loadImage("/images/kojo48.png")) app.setAboutHandler(new AboutHandler { def handleAbout(e: AboutEvent): Unit = { - JOptionPane.showMessageDialog( - frame, - "The Kojo Learning Environment\nSee 'Help -> About' for more information", - "", - JOptionPane.PLAIN_MESSAGE - ) + JOptionPane.showMessageDialog(frame, "The Kojo Learning Environment\nSee 'Help -> About' for more information", + "", JOptionPane.PLAIN_MESSAGE) } }) } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/Main.scala b/src/main/scala/net/kogics/kojo/lite/Main.scala index 7c839a561..f4273386a 100644 --- a/src/main/scala/net/kogics/kojo/lite/Main.scala +++ b/src/main/scala/net/kogics/kojo/lite/Main.scala @@ -15,25 +15,26 @@ package net.kogics.kojo package lite -import java.awt.event.WindowAdapter -import java.awt.event.WindowEvent import java.awt.BorderLayout import java.awt.Font import java.awt.Frame import java.awt.Toolkit +import java.awt.event.WindowAdapter +import java.awt.event.WindowEvent import java.io.File import java.util.logging.FileHandler import java.util.logging.Level import java.util.logging.Logger import java.util.logging.SimpleFormatter + import javax.swing.JFrame import javax.swing.UIManager import javax.swing.WindowConstants import scala.jdk.CollectionConverters._ -import bibliothek.gui.dock.common.theme.ThemeMap -import bibliothek.gui.dock.common.CControl +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea + import net.kogics.kojo.history.HistoryPanel import net.kogics.kojo.lite.canvas.SpriteCanvas import net.kogics.kojo.lite.topc.ArithAerobicsHolder @@ -47,7 +48,9 @@ import net.kogics.kojo.music.KMp3 import net.kogics.kojo.story.StoryTeller import net.kogics.kojo.turtle.TurtleWorldAPI import net.kogics.kojo.util.Utils -import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea + +import bibliothek.gui.dock.common.CControl +import bibliothek.gui.dock.common.theme.ThemeMap object Main extends AppMenu with ScriptLoader { main => @volatile var codePane: RSyntaxTextArea = _ @@ -61,12 +64,9 @@ object Main extends AppMenu with ScriptLoader { main => val sysProps = System.getProperties.asScala.toBuffer System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tc, %3$s] %4$s: %5$s%6$s%n") - // app name needs to be set right in the beginning (this applies to Mac; is ignored elsewhere) + // app name needs to be set right in the beginning (this applies to Mac; is ignored elsewhere) System.setProperty("apple.awt.application.name", "Kojo") - kojoCtx = - new KojoCtx( - args.length == 1 && args(0) == "subKojo" - ) // context needs to be created right up front to set user language + kojoCtx = new KojoCtx(args.length == 1 && args(0) == "subKojo") // context needs to be created right up front to set user language if (Utils.isMac) { try { new MacTweaks().tweak(frame) @@ -184,9 +184,9 @@ object Main extends AppMenu with ScriptLoader { main => Log.info(s"Kojo version: ${Versions.KojoMajorVersion}, ${Versions.KojoVersion}") Log.info(s"Java version: ${Versions.JavaVersion}. Scala version: ${Versions.ScalaVersion}") val sortedSysProps = sysProps.sorted.foldLeft(new StringBuilder) { - case (sb, kv) => - sb.append(s"\n${kv._1} = ${kv._2}") - } + case (sb, kv) => + sb append s"\n${kv._1} = ${kv._2}" + } Log.info(s"System Properties:$sortedSysProps\n\n") } diff --git a/src/main/scala/net/kogics/kojo/lite/MultiInstanceHandler.scala b/src/main/scala/net/kogics/kojo/lite/MultiInstanceHandler.scala index 705f7aa06..aab7cc525 100644 --- a/src/main/scala/net/kogics/kojo/lite/MultiInstanceHandler.scala +++ b/src/main/scala/net/kogics/kojo/lite/MultiInstanceHandler.scala @@ -14,10 +14,10 @@ */ package net.kogics.kojo.lite -import java.rmi.registry.LocateRegistry -import java.rmi.server.UnicastRemoteObject import java.rmi.Remote import java.rmi.RemoteException +import java.rmi.registry.LocateRegistry +import java.rmi.server.UnicastRemoteObject import net.kogics.kojo.util.Utils @@ -28,8 +28,8 @@ trait MultiInstanceHandler extends Remote { object MultiInstanceManager { // make mih static so that it does not get garbage collected - // we're trying to prevent the sporadic lack of activation of the first instance of Kojo from an nth instance - // and the accompanying 'Problem - no such object in table' message that shows up in the Java Console + // we're trying to prevent the sporadic lack of activation of the first instance of Kojo from an nth instance + // and the accompanying 'Problem - no such object in table' message that shows up in the Java Console val mih = new MultiInstanceHandlerImpl() def run(): Unit = { try { @@ -54,4 +54,4 @@ class MultiInstanceHandlerImpl extends MultiInstanceHandler { } } } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/NewKojoInstance.scala b/src/main/scala/net/kogics/kojo/lite/NewKojoInstance.scala index 5bf466acc..2fcc85e71 100644 --- a/src/main/scala/net/kogics/kojo/lite/NewKojoInstance.scala +++ b/src/main/scala/net/kogics/kojo/lite/NewKojoInstance.scala @@ -3,9 +3,9 @@ package net.kogics.kojo.lite import java.io.File object NewKojoInstance extends StubMain { - lazy val classpath = { - val cp = System.getProperty("java.class.path").split(File.pathSeparatorChar).toList - createCp(cp) + lazy val classpath = { + val cp = System.getProperty("java.class.path").split(File.pathSeparatorChar).toList + createCp(cp) } def firstInstance = true @@ -13,5 +13,5 @@ object NewKojoInstance extends StubMain { def firstMainDone(): Unit = {} def nthMain(args: Array[String]) = throw new UnsupportedOperationException override def log(msg: String): Unit = {} - override def done(): Unit = {} -} + override def done(): Unit = { } +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/NoOpSCanvas.scala b/src/main/scala/net/kogics/kojo/lite/NoOpSCanvas.scala index f5c405aa4..37692767b 100644 --- a/src/main/scala/net/kogics/kojo/lite/NoOpSCanvas.scala +++ b/src/main/scala/net/kogics/kojo/lite/NoOpSCanvas.scala @@ -5,16 +5,17 @@ import java.awt.Color import java.awt.Paint import java.util.concurrent.Future -import edu.umd.cs.piccolo.activities.PActivity -import edu.umd.cs.piccolo.util.PBounds -import edu.umd.cs.piccolo.PCamera -import edu.umd.cs.piccolo.PCanvas -import edu.umd.cs.piccolo.PLayer import net.kogics.kojo.core.Picture import net.kogics.kojo.core.SCanvas import net.kogics.kojo.core.Turtle import net.kogics.kojo.core.UnitLen +import edu.umd.cs.piccolo.PCamera +import edu.umd.cs.piccolo.PCanvas +import edu.umd.cs.piccolo.PLayer +import edu.umd.cs.piccolo.activities.PActivity +import edu.umd.cs.piccolo.util.PBounds + class NoOpSCanvas extends SCanvas { def clear(): Unit = {} def clearStepDrawing(): Unit = {} @@ -82,3 +83,5 @@ class NoOpSCanvas extends SCanvas { def resetPanAndZoom(): Unit = {} def disablePanAndZoom(): Unit = {} } + + diff --git a/src/main/scala/net/kogics/kojo/lite/OutputPane.scala b/src/main/scala/net/kogics/kojo/lite/OutputPane.scala index e3d4fe04e..7cdee6437 100644 --- a/src/main/scala/net/kogics/kojo/lite/OutputPane.scala +++ b/src/main/scala/net/kogics/kojo/lite/OutputPane.scala @@ -1,5 +1,12 @@ package net.kogics.kojo.lite +import java.awt.BorderLayout +import java.awt.CardLayout +import java.awt.Color +import java.awt.Component +import java.awt.Font +import java.awt.Insets +import java.awt.Toolkit import java.awt.event.ActionEvent import java.awt.event.ActionListener import java.awt.event.FocusAdapter @@ -8,20 +15,7 @@ import java.awt.event.InputEvent import java.awt.event.KeyEvent import java.awt.event.MouseAdapter import java.awt.event.MouseWheelEvent -import java.awt.BorderLayout -import java.awt.CardLayout -import java.awt.Color -import java.awt.Component -import java.awt.Font -import java.awt.Insets -import java.awt.Toolkit -import javax.swing.event.HyperlinkEvent -import javax.swing.event.HyperlinkListener -import javax.swing.event.PopupMenuEvent -import javax.swing.event.PopupMenuListener -import javax.swing.text.DefaultEditorKit -import javax.swing.text.StyleConstants -import javax.swing.text.StyleContext + import javax.swing.AbstractAction import javax.swing.BorderFactory import javax.swing.BoxLayout @@ -36,6 +30,13 @@ import javax.swing.JTextField import javax.swing.JTextPane import javax.swing.KeyStroke import javax.swing.UIDefaults +import javax.swing.event.HyperlinkEvent +import javax.swing.event.HyperlinkListener +import javax.swing.event.PopupMenuEvent +import javax.swing.event.PopupMenuListener +import javax.swing.text.DefaultEditorKit +import javax.swing.text.StyleConstants +import javax.swing.text.StyleContext import net.kogics.kojo.util.NoOpPainter import net.kogics.kojo.util.TerminalAnsiCodes @@ -144,8 +145,7 @@ class OutputPane(execSupport: CodeExecutionSupport) extends JPanel { val am = outputWindow.getActionMap val controlNumPlus = KeyStroke.getKeyStroke(KeyEvent.VK_ADD, InputEvent.CTRL_MASK) val controlPlus = KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, InputEvent.CTRL_MASK) - val controlShiftPlus = - KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK) + val controlShiftPlus = KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK) inputMap.put(controlNumPlus, "increase-font-size") inputMap.put(controlPlus, "increase-font-size") inputMap.put(controlShiftPlus, "increase-font-size") @@ -160,9 +160,8 @@ class OutputPane(execSupport: CodeExecutionSupport) extends JPanel { } val decrFontSizeItem = new JMenuItem(decreaseFontSizeAction) val controlNumMinus = KeyStroke.getKeyStroke(KeyEvent.VK_SUBTRACT, InputEvent.CTRL_MASK) - val controlMinus = KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_MASK) - val controlShiftMinus = - KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK) + val controlMinus = KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_MASK) + val controlShiftMinus = KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK) inputMap.put(controlNumMinus, "decrease-font-size") inputMap.put(controlMinus, "decrease-font-size") inputMap.put(controlShiftMinus, "decrease-font-size") @@ -170,10 +169,7 @@ class OutputPane(execSupport: CodeExecutionSupport) extends JPanel { decrFontSizeItem.setAccelerator(controlMinus) add(decrFontSizeItem) - inputMap.put( - KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit.getMenuShortcutKeyMask), - DefaultEditorKit.copyAction - ); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit.getMenuShortcutKeyMask), DefaultEditorKit.copyAction); errorWindow.addFocusListener(new FocusAdapter { override def focusGained(e: FocusEvent): Unit = { @@ -199,7 +195,7 @@ class OutputPane(execSupport: CodeExecutionSupport) extends JPanel { action.actionPerformed(null) } else { - outoutSp.getMouseWheelListeners.foreach { _.mouseWheelMoved(e) } + outoutSp.getMouseWheelListeners foreach { _.mouseWheelMoved(e) } } } } @@ -247,7 +243,7 @@ class OutputPane(execSupport: CodeExecutionSupport) extends JPanel { def appendOutput(s: String, color: Color): Unit = { if (TerminalAnsiCodes.isColoredString(s)) { - TerminalAnsiCodes.parse(s).foreach { cstr => + TerminalAnsiCodes.parse(s) foreach { cstr => appendOutput(cstr._1, cstr._2) } } @@ -279,11 +275,11 @@ class OutputPane(execSupport: CodeExecutionSupport) extends JPanel { def errorLocation =
    - { - val key = if (errCount == 1) "S_OutputLocateError" else "S_OutputLocateFirstError" - if (errCount >= 1) { {Utils.loadString(key)} } - else { {Utils.loadString("S_OutputCheckScriptButton")} } - } + { + val key = if (errCount == 1) "S_OutputLocateError" else "S_OutputLocateFirstError" + if (errCount >= 1) { { Utils.loadString(key) } + } else { { Utils.loadString("S_OutputCheckScriptButton") } } + }
    val fontSize = @@ -293,15 +289,15 @@ class OutputPane(execSupport: CodeExecutionSupport) extends JPanel { "large" val bg = Theme.currentTheme.errorPaneBg val errMsg = - +
    - {Utils.loadString("S_OutputScriptProblem")} + { Utils.loadString("S_OutputScriptProblem") }
    - {errorLocation} -
    -
    {errText}
    + { errorLocation } +
    +
    { errText }
    - {if (errCount > 2) errorLocation} + { if (errCount > 2) errorLocation } errorWindow.setText(errMsg.toString) @@ -372,7 +368,7 @@ class OutputPane(execSupport: CodeExecutionSupport) extends JPanel { // outoutPanel.remove(readInputPanel) readInputPanel = new JPanel() readInputPanel.setLayout(new BoxLayout(readInputPanel, BoxLayout.Y_AXIS)) - val label = new JLabel(" %s".format(prompt)) + val label = new JLabel(" %s" format (prompt)) label.setAlignmentX(Component.LEFT_ALIGNMENT) val lfont = label.getFont() label.setFont(new Font(lfont.getName, Font.BOLD, lfont.getSize + 2)) @@ -398,7 +394,7 @@ class OutputPane(execSupport: CodeExecutionSupport) extends JPanel { // works after nimbus painter hack outputWindow.setBackground(color) - // problem with code below: + // problem with code below: // works only for previous text // does not fill out the whole background // val background = new SimpleAttributeSet() @@ -435,4 +431,4 @@ class OutputPane(execSupport: CodeExecutionSupport) extends JPanel { val vsb = outoutSp.getVerticalScrollBar vsb.setValue(vsb.getMaximum) } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/PictureDraw.scala b/src/main/scala/net/kogics/kojo/lite/PictureDraw.scala index dc40f96fe..c91321b48 100644 --- a/src/main/scala/net/kogics/kojo/lite/PictureDraw.scala +++ b/src/main/scala/net/kogics/kojo/lite/PictureDraw.scala @@ -14,9 +14,8 @@ */ package net.kogics.kojo.lite -import java.awt.geom.AffineTransform - import net.kogics.kojo.util.Utils +import java.awt.geom.AffineTransform class PictureDraw(val b: Builtins) { import b._ @@ -136,7 +135,7 @@ class PictureDraw(val b: Builtins) { def arc(cx: Double, cy: Double, width: Double, height: Double, start: Double, extent: Double) = { // not quite the full deal - returnPic(cx, cy, Picture.arc(width / 2, -extent.toDegrees)) + returnPic(cx, cy, Picture.arc(width/2, -extent.toDegrees)) } def line(x1: Double, y1: Double, x2: Double, y2: Double) = { diff --git a/src/main/scala/net/kogics/kojo/lite/RmiLocalhostSocketFactory.scala b/src/main/scala/net/kogics/kojo/lite/RmiLocalhostSocketFactory.scala index 1052d9179..871ec1bf7 100644 --- a/src/main/scala/net/kogics/kojo/lite/RmiLocalhostSocketFactory.scala +++ b/src/main/scala/net/kogics/kojo/lite/RmiLocalhostSocketFactory.scala @@ -17,4 +17,4 @@ class RmiLocalhostSocketFactory extends RMIClientSocketFactory with RMIServerSoc new Socket(Utils.localHost, port) } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/RmiMultiInstance.scala b/src/main/scala/net/kogics/kojo/lite/RmiMultiInstance.scala index 7fea02e27..b7e1f120e 100644 --- a/src/main/scala/net/kogics/kojo/lite/RmiMultiInstance.scala +++ b/src/main/scala/net/kogics/kojo/lite/RmiMultiInstance.scala @@ -14,10 +14,10 @@ */ package net.kogics.kojo.lite +import java.rmi.RemoteException import java.rmi.registry.LocateRegistry import java.rmi.registry.Registry import java.rmi.server.UnicastRemoteObject -import java.rmi.RemoteException import net.kogics.kojo.util.Utils @@ -61,12 +61,10 @@ trait RmiMultiInstance { } def nthMain(args: Array[String]): Unit = Utils.safeProcess { - registry.foreach { r => + registry foreach { r => val mih = r.lookup(Utils.RmiHandlerName).asInstanceOf[MultiInstanceHandler] - println( - s"[INFO] Connecting (via RMI) with args: ${args.mkString("[", ", ", "]")} to already running Kojo instance" - ) + println(s"[INFO] Connecting (via RMI) with args: ${args.mkString("[", ", ", "]")} to already running Kojo instance") mih.newInstance(args) } } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala b/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala index 0dfef09b0..77b98d7b8 100644 --- a/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala +++ b/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala @@ -1,5 +1,11 @@ package net.kogics.kojo.lite +import java.awt.BorderLayout +import java.awt.Dimension +import java.awt.Event +import java.awt.Font +import java.awt.Point +import java.awt.Toolkit import java.awt.event.ActionEvent import java.awt.event.ActionListener import java.awt.event.FocusAdapter @@ -10,19 +16,7 @@ import java.awt.event.KeyEvent import java.awt.event.MouseAdapter import java.awt.event.MouseEvent import java.awt.event.MouseWheelEvent -import java.awt.BorderLayout -import java.awt.Dimension -import java.awt.Event -import java.awt.Font -import java.awt.Point -import java.awt.Toolkit -import javax.swing.event.CaretEvent -import javax.swing.event.CaretListener -import javax.swing.event.DocumentEvent -import javax.swing.event.DocumentListener -import javax.swing.event.PopupMenuEvent -import javax.swing.event.PopupMenuListener -import javax.swing.text.Utilities + import javax.swing.AbstractAction import javax.swing.Action import javax.swing.JButton @@ -35,22 +29,19 @@ import javax.swing.JPanel import javax.swing.JPopupMenu import javax.swing.JToolBar import javax.swing.KeyStroke +import javax.swing.event.CaretEvent +import javax.swing.event.CaretListener +import javax.swing.event.DocumentEvent +import javax.swing.event.DocumentListener +import javax.swing.event.PopupMenuEvent +import javax.swing.event.PopupMenuListener +import javax.swing.text.Utilities -import net.kogics.kojo.action.ChooseColor -import net.kogics.kojo.codingmode.SwitchMode -import net.kogics.kojo.core.TwMode -import net.kogics.kojo.core.VanillaMode -import net.kogics.kojo.livecoding.IpmProvider -import net.kogics.kojo.util.Utils -import net.kogics.kojo.xscala.CodeTemplates +import org.fife.rsta.ui.CollapsibleSectionPanel import org.fife.rsta.ui.search.ReplaceToolBar import org.fife.rsta.ui.search.SearchEvent import org.fife.rsta.ui.search.SearchListener -import org.fife.rsta.ui.CollapsibleSectionPanel import org.fife.ui.autocomplete.AutoCompletion -import org.fife.ui.rsyntaxtextarea.folding.CurlyFoldParser -import org.fife.ui.rsyntaxtextarea.folding.FoldParserManager -import org.fife.ui.rsyntaxtextarea.templates.StaticCodeTemplate import org.fife.ui.rsyntaxtextarea.AbstractTokenMakerFactory import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaEditorKit @@ -58,12 +49,24 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaEditorKit.DecreaseFontSizeActi import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaEditorKit.IncreaseFontSizeAction import org.fife.ui.rsyntaxtextarea.SyntaxConstants import org.fife.ui.rsyntaxtextarea.TokenMakerFactory +import org.fife.ui.rsyntaxtextarea.folding.CurlyFoldParser +import org.fife.ui.rsyntaxtextarea.folding.FoldParserManager +import org.fife.ui.rsyntaxtextarea.templates.StaticCodeTemplate import org.fife.ui.rtextarea.IconGroup import org.fife.ui.rtextarea.RTextArea import org.fife.ui.rtextarea.RTextScrollPane import org.fife.ui.rtextarea.SearchEngine -import scalariform.formatter.preferences._ + +import net.kogics.kojo.action.ChooseColor +import net.kogics.kojo.codingmode.SwitchMode +import net.kogics.kojo.core.TwMode +import net.kogics.kojo.core.VanillaMode +import net.kogics.kojo.livecoding.IpmProvider +import net.kogics.kojo.util.Utils +import net.kogics.kojo.xscala.CodeTemplates + import scalariform.formatter.ScalaFormatter +import scalariform.formatter.preferences._ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends JPanel with EditorFileSupport { @@ -72,19 +75,8 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends val codePane2 = new RSyntaxTextArea(5, 80) val codePanes = List(codePane, codePane2) val statusStrip = new StatusStrip() - val ( - toolbar, - runButton, - runWorksheetButton, - traceButton, - compileButton, - stopButton, - hNextButton, - hPrevButton, - clearSButton, - clearButton, - cexButton - ) = makeToolbar() + val (toolbar, runButton, runWorksheetButton, traceButton, compileButton, stopButton, hNextButton, hPrevButton, + clearSButton, clearButton, cexButton) = makeToolbar() val SYNTAX_STYLE_SCALA2 = "text/scala2" val tFactory = TokenMakerFactory.getDefaultInstance.asInstanceOf[AbstractTokenMakerFactory] @@ -231,12 +223,10 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends val caretLine = codePane.getCaretLineNumber val posInLine = codePane.getCaretOffsetFromLineStart try { - codePane.setText( - ScalaFormatter.format( - codePane.getText, - formatPrefs - ) - ) + codePane.setText(ScalaFormatter.format( + codePane.getText, + formatPrefs + )) try { val lineStart = codePane.getLineStartOffset(caretLine) val lineEnd = codePane.getLineEndOffset(caretLine) @@ -267,93 +257,92 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends popup.add(formatItem, idx) idx += 1 - val findReplaceAction = - new AbstractAction(Utils.loadString("S_FindReplace"), Utils.loadIcon("/images/extra/find.gif")) { - - // lazy val dialog: ReplaceDialog = new ReplaceDialog(frame, listener) { - // setTitle(Utils.loadString("S_FindReplace")) - // override def setVisible(visible: Boolean) { - // val searchContext = getSearchContext - // if (!visible) { - // // dialog closing; get rid of marks, if any - // val oldMarkAll = searchContext.getMarkAll - // searchContext.setMarkAll(false) - // val oldDot = codePane.getCaret.getDot - // SearchEngine.find(codePane, searchContext) - // codePane.getCaret.setDot(oldDot) - // searchContext.setMarkAll(oldMarkAll) - // } - // super.setVisible(visible) - // } - // } - - lazy val listener = new SearchListener { - def getSelectedText = codePane.getSelectedText - - def searchEvent(ev: SearchEvent): Unit = { - val searchContext = toolbar.getSearchContext - def find(): Unit = { - var found = SearchEngine.find(codePane, searchContext) + val findReplaceAction = new AbstractAction(Utils.loadString("S_FindReplace"), Utils.loadIcon("/images/extra/find.gif")) { + + // lazy val dialog: ReplaceDialog = new ReplaceDialog(frame, listener) { + // setTitle(Utils.loadString("S_FindReplace")) + // override def setVisible(visible: Boolean) { + // val searchContext = getSearchContext + // if (!visible) { + // // dialog closing; get rid of marks, if any + // val oldMarkAll = searchContext.getMarkAll + // searchContext.setMarkAll(false) + // val oldDot = codePane.getCaret.getDot + // SearchEngine.find(codePane, searchContext) + // codePane.getCaret.setDot(oldDot) + // searchContext.setMarkAll(oldMarkAll) + // } + // super.setVisible(visible) + // } + // } + + lazy val listener = new SearchListener { + def getSelectedText = codePane.getSelectedText + + def searchEvent(ev: SearchEvent): Unit = { + val searchContext = toolbar.getSearchContext + def find(): Unit = { + var found = SearchEngine.find(codePane, searchContext) + if (found.getCount == 0) { + val oldDot = codePane.getCaret.getDot + codePane.getCaret.setDot(0) + found = SearchEngine.find(codePane, searchContext) if (found.getCount == 0) { - val oldDot = codePane.getCaret.getDot - codePane.getCaret.setDot(0) - found = SearchEngine.find(codePane, searchContext) - if (found.getCount == 0) { - codePane.getCaret.setDot(oldDot) - } + codePane.getCaret.setDot(oldDot) } } + } - ev.getType match { - case SearchEvent.Type.MARK_ALL => - SearchEngine.markAll(codePane, searchContext) - case SearchEvent.Type.FIND => + ev.getType match { + case SearchEvent.Type.MARK_ALL => + SearchEngine.markAll(codePane, searchContext) + case SearchEvent.Type.FIND => + find() + case SearchEvent.Type.REPLACE => + val result = SearchEngine.replace(codePane, searchContext) + val nextFindRange = result.getMatchRange + if (nextFindRange.getEndOffset == nextFindRange.getStartOffset) { + // nothing found; try from beginning of document find() - case SearchEvent.Type.REPLACE => - val result = SearchEngine.replace(codePane, searchContext) - val nextFindRange = result.getMatchRange - if (nextFindRange.getEndOffset == nextFindRange.getStartOffset) { - // nothing found; try from beginning of document - find() - } - case SearchEvent.Type.REPLACE_ALL => - SearchEngine.replaceAll(codePane, searchContext); - case _ => - } + } + case SearchEvent.Type.REPLACE_ALL => + SearchEngine.replaceAll(codePane, searchContext); + case _ => } } + } - lazy val toolbar: ReplaceToolBar = new ReplaceToolBar(listener) { - override def addNotify() = { - val searchContext = getSearchContext - searchContext.setMarkAll(false) - val sel = codePane.getSelectedText - if (sel != null) { - searchContext.setSearchFor(sel) - searchContext.setReplaceWith("") - } - super.addNotify() + lazy val toolbar: ReplaceToolBar = new ReplaceToolBar(listener) { + override def addNotify() = { + val searchContext = getSearchContext + searchContext.setMarkAll(false) + val sel = codePane.getSelectedText + if (sel != null) { + searchContext.setSearchFor(sel) + searchContext.setReplaceWith("") } + super.addNotify() + } - override def removeNotify(): Unit = { - val searchContext = getSearchContext - // toolbar closing; get rid of marks, if any - searchContext.setMarkAll(false) - SearchEngine.markAll(codePane, searchContext) - super.removeNotify() - } + override def removeNotify(): Unit = { + val searchContext = getSearchContext + // toolbar closing; get rid of marks, if any + searchContext.setMarkAll(false) + SearchEngine.markAll(codePane, searchContext) + super.removeNotify() } + } - var toolbarAdded = false - def actionPerformed(ev: ActionEvent): Unit = { - // dialog.setVisible(true) - if (!toolbarAdded) { - csp.addBottomComponent(toolbar) - toolbarAdded = true - } - csp.showBottomComponent(toolbar) + var toolbarAdded = false + def actionPerformed(ev: ActionEvent): Unit = { + // dialog.setVisible(true) + if (!toolbarAdded) { + csp.addBottomComponent(toolbar) + toolbarAdded = true } + csp.showBottomComponent(toolbar) } + } val findReplaceItem = new JMenuItem(findReplaceAction) val cf = KeyStroke.getKeyStroke("control F") inputMap.put(cf, "find-replace") @@ -438,8 +427,7 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends increaseFontItem.setText(Utils.loadString("S_IncreaseFontSize")) val controlNumPlus = KeyStroke.getKeyStroke(KeyEvent.VK_ADD, InputEvent.CTRL_MASK) val controlPlus = KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, InputEvent.CTRL_MASK) - val controlShiftPlus = - KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK) + val controlShiftPlus = KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK) inputMap.put(controlNumPlus, "increase-font-size") inputMap.put(controlPlus, "increase-font-size") inputMap.put(controlShiftPlus, "increase-font-size") @@ -459,8 +447,7 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends decreaseFontItem.setText(Utils.loadString("S_DecreaseFontSize")) val controlNumMinus = KeyStroke.getKeyStroke(KeyEvent.VK_SUBTRACT, InputEvent.CTRL_MASK) val controlMinus = KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_MASK) - val controlShiftMinus = - KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK) + val controlShiftMinus = KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK) inputMap.put(controlNumMinus, "decrease-font-size") inputMap.put(controlMinus, "decrease-font-size") inputMap.put(controlShiftMinus, "decrease-font-size") @@ -665,7 +652,8 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends } } - def makeNavigationButton(imageFile: String, actionCommand: String, toolTipText: String): JButton = { + def makeNavigationButton(imageFile: String, actionCommand: String, + toolTipText: String): JButton = { val button = new JButton() button.setActionCommand(actionCommand) button.setToolTipText(toolTipText) @@ -696,24 +684,15 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends import Theme.currentTheme.stopPng val runButton = makeNavigationButton(s"/images/$imageFolder/$runPng", RunScript, Utils.loadString("S_RunScript")) - val runWorksheetButton = - makeNavigationButton(s"/images/$imageFolder/$runwPng", RunWorksheet, Utils.loadString("S_RunWorksheet")) - val traceButton = - makeNavigationButton(s"/images/$imageFolder/$runtPng", TraceScript, Utils.loadString("S_TraceScript")) - val compileButton = - makeNavigationButton(s"/images/$imageFolder/$checkPng", CompileScript, Utils.loadString("S_CheckScript")) - val stopButton = - makeNavigationButton(s"/images/$imageFolder/$stopPng", StopScript, Utils.loadString("S_StopScript")) - val hNextButton = - makeNavigationButton(s"/images/$imageFolder/history-next.png", HistoryNext, Utils.loadString("S_HistNext")) - val hPrevButton = - makeNavigationButton(s"/images/$imageFolder/history-prev.png", HistoryPrev, Utils.loadString("S_HistPrev")) - val clearSButton = - makeNavigationButton(s"/images/$imageFolder/$clearSePng", ClearEditor, Utils.loadString("S_ClearEditorT")) - val clearButton = - makeNavigationButton(s"/images/$imageFolder/$clearOwPng", ClearOutput, Utils.loadString("S_ClearOutput")) - val cexButton = - makeNavigationButton(s"/images/$imageFolder/upload.png", UploadCommand, Utils.loadString("S_Upload")) + val runWorksheetButton = makeNavigationButton(s"/images/$imageFolder/$runwPng", RunWorksheet, Utils.loadString("S_RunWorksheet")) + val traceButton = makeNavigationButton(s"/images/$imageFolder/$runtPng", TraceScript, Utils.loadString("S_TraceScript")) + val compileButton = makeNavigationButton(s"/images/$imageFolder/$checkPng", CompileScript, Utils.loadString("S_CheckScript")) + val stopButton = makeNavigationButton(s"/images/$imageFolder/$stopPng", StopScript, Utils.loadString("S_StopScript")) + val hNextButton = makeNavigationButton(s"/images/$imageFolder/history-next.png", HistoryNext, Utils.loadString("S_HistNext")) + val hPrevButton = makeNavigationButton(s"/images/$imageFolder/history-prev.png", HistoryPrev, Utils.loadString("S_HistPrev")) + val clearSButton = makeNavigationButton(s"/images/$imageFolder/$clearSePng", ClearEditor, Utils.loadString("S_ClearEditorT")) + val clearButton = makeNavigationButton(s"/images/$imageFolder/$clearOwPng", ClearOutput, Utils.loadString("S_ClearOutput")) + val cexButton = makeNavigationButton(s"/images/$imageFolder/upload.png", UploadCommand, Utils.loadString("S_Upload")) toolbar.add(runButton) toolbar.add(runWorksheetButton) @@ -739,19 +718,7 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends clearButton.setEnabled(false) toolbar.add(clearButton) - ( - toolbar, - runButton, - runWorksheetButton, - traceButton, - compileButton, - stopButton, - hNextButton, - hPrevButton, - clearSButton, - clearButton, - cexButton - ) + (toolbar, runButton, runWorksheetButton, traceButton, compileButton, stopButton, hNextButton, hPrevButton, clearSButton, clearButton, cexButton) } def addCodePaneListeners(): Unit = { @@ -836,7 +803,7 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends action.actionPerformed(null) } else { - sp.getMouseWheelListeners.foreach { _.mouseWheelMoved(e) } + sp.getMouseWheelListeners foreach { _.mouseWheelMoved(e) } } } } @@ -954,4 +921,4 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends } } } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/ScriptLoader.scala b/src/main/scala/net/kogics/kojo/lite/ScriptLoader.scala index 90273f020..ba6824d39 100644 --- a/src/main/scala/net/kogics/kojo/lite/ScriptLoader.scala +++ b/src/main/scala/net/kogics/kojo/lite/ScriptLoader.scala @@ -5,7 +5,7 @@ import net.kogics.kojo.util.Utils trait ScriptLoader { self: Main.type => def _loadUrl(url: String)(postfn: => Unit = {}): Unit = { Theme.currentTheme.loadDefaultPerspective(kojoCtx) - codePane.setText("// Loading code from URL: %s ...\n".format(url)) + codePane.setText("// Loading code from URL: %s ...\n" format (url)) Utils.runAsyncMonitored { try { val code = Utils.readUrl(url) @@ -16,7 +16,7 @@ trait ScriptLoader { self: Main.type => } } catch { - case t: Throwable => codePane.append("// Problem loading code: %s".format(t.getMessage)) + case t: Throwable => codePane.append("// Problem loading code: %s" format (t.getMessage)) } } } @@ -24,14 +24,8 @@ trait ScriptLoader { self: Main.type => def loadUrl(url: String) = _loadUrl(url) {} def loadAndRunUrl(url: String, onStartup: Boolean = false) = _loadUrl(url) { - if ( - !url.startsWith("http://www.kogics.net/public/kojolite/samples/") && codePane.getText.toLowerCase.contains("file") - ) { - codePane.insert( - "// Loaded code from URL: %s\n// ** Not running it automatically ** because it references files.\n// Look carefully at the code before running it.\n\n" - .format(url), - 0 - ) + if (!url.startsWith("http://www.kogics.net/public/kojolite/samples/") && codePane.getText.toLowerCase.contains("file")) { + codePane.insert("// Loaded code from URL: %s\n// ** Not running it automatically ** because it references files.\n// Look carefully at the code before running it.\n\n" format (url), 0) codePane.setCaretPosition(0) } else { @@ -42,7 +36,7 @@ trait ScriptLoader { self: Main.type => } } - @deprecated("Replaced by loadAndRunLocalizedResource(root,file)", since = "2016-04-03") + @deprecated("Replaced by loadAndRunLocalizedResource(root,file)", since="2016-04-03") def loadAndRunResource(res: String) = { try { codePane.setText("") @@ -52,12 +46,12 @@ trait ScriptLoader { self: Main.type => execSupport.compileRunCode() } catch { - case t: Throwable => codePane.append("// Problem loading/running code: %s".format(t.getMessage)) + case t: Throwable => codePane.append("// Problem loading/running code: %s" format (t.getMessage)) } scriptEditorHolder.activate() } - - // @since 2016-04-03 + + //@since 2016-04-03 def loadAndRunLocalizedResource(root: String, file: String) = { try { codePane.setText("") @@ -68,7 +62,7 @@ trait ScriptLoader { self: Main.type => } catch { case ex: IllegalArgumentException => codePane.append(s"// Problem loading code from ${ex.getMessage}") - case t: Throwable => codePane.append("// Problem loading/running code: %s".format(t.getMessage)) + case t: Throwable => codePane.append("// Problem loading/running code: %s" format (t.getMessage)) } scriptEditorHolder.activate() } @@ -80,7 +74,7 @@ trait ScriptLoader { self: Main.type => execSupport.compileRunCode(code) } catch { - case t: Throwable => println("// Problem loading/running code: %s".format(t.getMessage)) + case t: Throwable => println("// Problem loading/running code: %s" format (t.getMessage)) } scriptEditorHolder.activate() } @@ -94,9 +88,9 @@ trait ScriptLoader { self: Main.type => execSupport.compileRunCode() } catch { - case t: Throwable => codePane.append("// Problem loading/running code: %s".format(t.getMessage)) + case t: Throwable => codePane.append("// Problem loading/running code: %s" format (t.getMessage)) } scriptEditorHolder.activate() } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/SettingsWindow.scala b/src/main/scala/net/kogics/kojo/lite/SettingsWindow.scala index 8aac6613b..f4e1a89b1 100644 --- a/src/main/scala/net/kogics/kojo/lite/SettingsWindow.scala +++ b/src/main/scala/net/kogics/kojo/lite/SettingsWindow.scala @@ -18,6 +18,7 @@ import java.awt.event.ActionEvent import java.awt.event.ActionListener import java.awt.event.KeyAdapter import java.awt.event.KeyEvent + import javax.swing.JButton import javax.swing.JDialog import javax.swing.JFrame @@ -95,15 +96,9 @@ class SettingsWindow(owner: JFrame) extends JDialog(owner) { val r6 = RowPanel(filler(7), Label(Utils.loadString("S_ImageExport"))) val r7 = RowPanel( filler(10), - Label(Utils.loadString("S_DPI")), - dpiTf, - filler(3), - Label(Utils.loadString("S_Dimension")), - dimensionDd, - filler(3), - Label(Utils.loadString("S_Inches")), - inchesDd, - filler(3) + Label(Utils.loadString("S_DPI")), dpiTf, filler(3), + Label(Utils.loadString("S_Dimension")), dimensionDd, filler(3), + Label(Utils.loadString("S_Inches")), inchesDd, filler(3) ) def changeModality(modal: Boolean): Unit = { @@ -192,20 +187,18 @@ class SettingsWindow(owner: JFrame) extends JDialog(owner) { } } } - val newDpi = - if (newInches.trim == "") "" - else { - val v = dpiTf.value - try { - assert(v.toInt > 0) - v - } - catch { - case throwable: Throwable => - newInches = "" - "" - } + val newDpi = if (newInches.trim == "") "" else { + val v = dpiTf.value + try { + assert(v.toInt > 0) + v } + catch { + case throwable: Throwable => + newInches = "" + "" + } + } val newDimension = dimensionDd.value val m = Map( "theme" -> newTheme, diff --git a/src/main/scala/net/kogics/kojo/lite/SplashScreen.scala b/src/main/scala/net/kogics/kojo/lite/SplashScreen.scala index bccf0c5c5..081fb2620 100644 --- a/src/main/scala/net/kogics/kojo/lite/SplashScreen.scala +++ b/src/main/scala/net/kogics/kojo/lite/SplashScreen.scala @@ -4,14 +4,13 @@ package lite import java.awt.event.ActionEvent import java.awt.event.ActionListener import java.awt.Color -import java.awt.Cursor import javax.swing.JLabel import javax.swing.JPanel import javax.swing.JProgressBar import javax.swing.JWindow import javax.swing.Timer - import util.Utils +import java.awt.Cursor class SplashScreen extends JWindow { diff --git a/src/main/scala/net/kogics/kojo/lite/StatusBar.scala b/src/main/scala/net/kogics/kojo/lite/StatusBar.scala index 55a72a632..a11d3e134 100644 --- a/src/main/scala/net/kogics/kojo/lite/StatusBar.scala +++ b/src/main/scala/net/kogics/kojo/lite/StatusBar.scala @@ -3,6 +3,7 @@ package net.kogics.kojo.lite import java.awt.BorderLayout import java.awt.Color import java.awt.Font + import javax.swing.BorderFactory import javax.swing.JLabel import javax.swing.JPanel @@ -26,4 +27,4 @@ class StatusBar extends JPanel { def showCaretPos(line: Int, col: Int): Unit = { lineCol.setText(s"${" " * 12}$line | $col${" " * 12}") } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/StubMain.scala b/src/main/scala/net/kogics/kojo/lite/StubMain.scala index 23c87273e..3f20b5841 100644 --- a/src/main/scala/net/kogics/kojo/lite/StubMain.scala +++ b/src/main/scala/net/kogics/kojo/lite/StubMain.scala @@ -15,6 +15,7 @@ package net.kogics.kojo.lite import java.io.File + import javax.swing.JOptionPane import scala.collection.mutable.ArrayBuffer @@ -96,8 +97,7 @@ trait StubMain { } def maybeMarlin = { if (System.getProperty("java.vendor", "").toLowerCase.contains("jetbrains")) - "-Dsun.java2d.renderer=sun.java2d.marlin.MarlinRenderingEngine" - else "" + "-Dsun.java2d.renderer=sun.java2d.marlin.MarlinRenderingEngine" else "" } def cmsGC = @@ -132,10 +132,8 @@ trait StubMain { val pythonVer = Utils.appProperty("python.version").getOrElse("3.8") Utils.appProperty("python.home") match { case Some(phome) => - libraryPath.append( - File.pathSeparator + s"$phome/lib" + - File.pathSeparatorChar + s"$phome/lib/python$pythonVer/site-packages/jep" - ) + libraryPath.append(File.pathSeparator + s"$phome/lib" + + File.pathSeparatorChar + s"$phome/lib/python$pythonVer/site-packages/jep") case None => } libraryPath.toString @@ -164,18 +162,17 @@ trait StubMain { val command = Seq( javaExec, - "-cp", - classpath, + "-cp", classpath, s"-Djava.library.path=$libPath" ) ++ cmdArgs.split(' ') log(s"Java VM args: $cmdArgs") - Process(command, None, extraEnv: _*) ! + Process(command, None, extraEnv: _*)! } def createCp(xs: List[String]): String = { val ourCp = new StringBuilder - // Bad stuff on the classpath can clobber the launch of the Real Kojo + // Bad stuff on the classpath can clobber the launch of the Real Kojo // val oldCp = System.getenv("CLASSPATH") // if (oldCp != null) { // ourCp.append(oldCp) @@ -208,4 +205,4 @@ trait StubMain { ourCp.append(xs.mkString(File.pathSeparator)) ourCp.toString } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/Theme.scala b/src/main/scala/net/kogics/kojo/lite/Theme.scala index 1c5fd17a5..a3b749952 100644 --- a/src/main/scala/net/kogics/kojo/lite/Theme.scala +++ b/src/main/scala/net/kogics/kojo/lite/Theme.scala @@ -16,11 +16,12 @@ package net.kogics.kojo.lite import java.awt.Color -import com.formdev.flatlaf.FlatDarkLaf -import com.formdev.flatlaf.FlatLightLaf +import org.fife.ui.rsyntaxtextarea.{Theme => RTheme} + +import com.formdev.flatlaf.{FlatDarkLaf, FlatLightLaf} + import net.kogics.kojo.core import net.kogics.kojo.util.Utils -import org.fife.ui.rsyntaxtextarea.{ Theme => RTheme } trait Theme { def outputPaneFg: Color @@ -76,7 +77,7 @@ class DarkTheme extends Theme { val outputPaneBg = new Color(0x2d2d2d) val errorPaneFg = "#F42E2E" val errorPaneBg = "#2d2d2d" - val errorColor = new Color(0xf42e2e) + val errorColor = new Color(0xF42E2E) val successColor = new Color(0x06cc06) val neutralColor = defaultBg val tracingBg = defaultBg diff --git a/src/main/scala/net/kogics/kojo/lite/TopCs.scala b/src/main/scala/net/kogics/kojo/lite/TopCs.scala index e3405a675..c611b0fe0 100644 --- a/src/main/scala/net/kogics/kojo/lite/TopCs.scala +++ b/src/main/scala/net/kogics/kojo/lite/TopCs.scala @@ -1,17 +1,16 @@ package net.kogics.kojo.lite -import net.kogics.kojo.lite.topc.ArithAerobicsHolder import net.kogics.kojo.lite.topc.DrawingCanvasHolder -import net.kogics.kojo.lite.topc.HistoryHolder import net.kogics.kojo.lite.topc.OutputWindowHolder import net.kogics.kojo.lite.topc.ScriptEditorHolder import net.kogics.kojo.lite.topc.StoryTellerHolder +import net.kogics.kojo.lite.topc.HistoryHolder +import net.kogics.kojo.lite.topc.ArithAerobicsHolder case class TopCs( - dch: DrawingCanvasHolder, - owh: OutputWindowHolder, - seh: ScriptEditorHolder, - sth: StoryTellerHolder, - hih: HistoryHolder, - aah: ArithAerobicsHolder -) + dch: DrawingCanvasHolder, + owh: OutputWindowHolder, + seh: ScriptEditorHolder, + sth: StoryTellerHolder, + hih: HistoryHolder, + aah: ArithAerobicsHolder) \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/Versions.scala b/src/main/scala/net/kogics/kojo/lite/Versions.scala index abc6d0b4e..de59a30f4 100644 --- a/src/main/scala/net/kogics/kojo/lite/Versions.scala +++ b/src/main/scala/net/kogics/kojo/lite/Versions.scala @@ -3,8 +3,8 @@ package net.kogics.kojo.lite object Versions { val KojoMajorVersion = "2.9" val KojoVersion = "2.9.24" - val KojoRevision = "r27" - val KojoBuildDate = "15 February 2023" + val KojoRevision = "r11" + val KojoBuildDate = "24 November 2022" val JavaVersion = { val jrv = System.getProperty("java.runtime.version") val arch = System.getProperty("os.arch") diff --git a/src/main/scala/net/kogics/kojo/lite/action/actions.scala b/src/main/scala/net/kogics/kojo/lite/action/actions.scala index 6bf17b091..1c953ea1f 100644 --- a/src/main/scala/net/kogics/kojo/lite/action/actions.scala +++ b/src/main/scala/net/kogics/kojo/lite/action/actions.scala @@ -15,20 +15,19 @@ package net.kogics.kojo.lite.action +import java.awt.GraphicsEnvironment import java.awt.event.ActionEvent import java.awt.event.KeyAdapter import java.awt.event.KeyEvent -import java.awt.GraphicsEnvironment -import javax.swing.AbstractAction import javax.swing.JCheckBoxMenuItem -import javax.swing.JComponent +import javax.swing.AbstractAction import javax.swing.JFrame - +import javax.swing.JComponent import net.kogics.kojo.core.KojoCtx +import net.kogics.kojo.lite.EditorFileSupport import net.kogics.kojo.lite.topc.BaseHolder import net.kogics.kojo.lite.topc.DrawingCanvasHolder import net.kogics.kojo.lite.topc.OutputWindowHolder -import net.kogics.kojo.lite.EditorFileSupport import net.kogics.kojo.util.Utils import FullScreenSupport.sdev @@ -55,7 +54,7 @@ object FullScreenSupport { } class FullScreenBaseAction(key: String, fsComp: => JComponent, fsCompHolder: => BaseHolder) - extends AbstractAction(key) { + extends AbstractAction(key) { import FullScreenSupport._ var frame: JFrame = _ var fullScreen = false @@ -92,7 +91,7 @@ class FullScreenBaseAction(key: String, fsComp: => JComponent, fsCompHolder: => } // can also be called from the interp thread via the API - def actionPerformed(e: ActionEvent) = Utils.runInSwingThreadAndWait { + def actionPerformed(e: ActionEvent) = Utils.runInSwingThreadAndWait { if (!isFullScreen) { if (!FullScreenSupport.isFullScreenOn) { enterFullScreen() @@ -115,11 +114,11 @@ object FullScreenCanvasAction { } class FullScreenCanvasAction(dch: => DrawingCanvasHolder, kojoCtx: KojoCtx) - extends FullScreenBaseAction( - Utils.loadString("S_FullScreenCanvas"), - dch.dc, - dch - ) { + extends FullScreenBaseAction( + Utils.loadString("S_FullScreenCanvas"), + dch.dc, + dch + ) { override def enterFullScreen(): Unit = { dch.dc.setFocusable(true) // make canvas work with frame.getMostRecentFocusOwner() super.enterFullScreen() @@ -138,11 +137,11 @@ object FullScreenOutputAction { } class FullScreenOutputAction(owh: => OutputWindowHolder) - extends FullScreenBaseAction( - Utils.loadString("S_FullScreenOutput"), - owh.outputPane, - owh - ) { + extends FullScreenBaseAction( + Utils.loadString("S_FullScreenOutput"), + owh.outputPane, + owh + ) { override def enterFullScreen(): Unit = { super.enterFullScreen() } diff --git a/src/main/scala/net/kogics/kojo/lite/canvas/SpriteCanvas.scala b/src/main/scala/net/kogics/kojo/lite/canvas/SpriteCanvas.scala index d132acf7b..43877c99d 100644 --- a/src/main/scala/net/kogics/kojo/lite/canvas/SpriteCanvas.scala +++ b/src/main/scala/net/kogics/kojo/lite/canvas/SpriteCanvas.scala @@ -16,38 +16,21 @@ package net.kogics.kojo package lite package canvas -import java.awt.event.ActionEvent -import java.awt.event.ActionListener -import java.awt.event.ComponentAdapter -import java.awt.event.ComponentEvent -import java.awt.event.InputEvent -import java.awt.event.MouseEvent -import java.awt.geom.Point2D import java.awt.Color import java.awt.Dimension import java.awt.GradientPaint import java.awt.Paint +import java.awt.event.{ActionEvent, ActionListener, ComponentAdapter, ComponentEvent, InputEvent, MouseEvent} +import java.awt.geom.Point2D import java.util.concurrent.Future import java.util.logging.Logger -import javax.swing.event.PopupMenuEvent -import javax.swing.event.PopupMenuListener + import javax.swing.JCheckBoxMenuItem import javax.swing.JMenuItem import javax.swing.JPopupMenu +import javax.swing.event.PopupMenuEvent +import javax.swing.event.PopupMenuListener -import edu.umd.cs.piccolo.activities.PActivity -import edu.umd.cs.piccolo.event.PBasicInputEventHandler -import edu.umd.cs.piccolo.event.PInputEvent -import edu.umd.cs.piccolo.event.PInputEventFilter -import edu.umd.cs.piccolo.event.PInputEventListener -import edu.umd.cs.piccolo.event.PPanEventHandler -import edu.umd.cs.piccolo.event.PZoomEventHandler -import edu.umd.cs.piccolo.nodes.PPath -import edu.umd.cs.piccolo.nodes.PText -import edu.umd.cs.piccolo.util.PPaintContext -import edu.umd.cs.piccolo.PCanvas -import edu.umd.cs.piccolo.PNode -import edu.umd.cs.piccolox.pswing.PSwingCanvas import net.kogics.kojo.core.Cm import net.kogics.kojo.core.Inch import net.kogics.kojo.core.Pixel @@ -60,6 +43,20 @@ import net.kogics.kojo.turtle.Turtle import net.kogics.kojo.util.FileChooser import net.kogics.kojo.util.Utils +import edu.umd.cs.piccolo.PCanvas +import edu.umd.cs.piccolo.PNode +import edu.umd.cs.piccolo.activities.PActivity +import edu.umd.cs.piccolo.event.PBasicInputEventHandler +import edu.umd.cs.piccolo.event.PInputEvent +import edu.umd.cs.piccolo.event.PInputEventFilter +import edu.umd.cs.piccolo.event.PInputEventListener +import edu.umd.cs.piccolo.event.PPanEventHandler +import edu.umd.cs.piccolo.event.PZoomEventHandler +import edu.umd.cs.piccolo.nodes.PPath +import edu.umd.cs.piccolo.nodes.PText +import edu.umd.cs.piccolo.util.PPaintContext +import edu.umd.cs.piccolox.pswing.PSwingCanvas + class SpriteCanvas(val kojoCtx: core.KojoCtx) extends PSwingCanvas with SCanvas { val origLayer = getLayer() @@ -215,7 +212,7 @@ class SpriteCanvas(val kojoCtx: core.KojoCtx) extends PSwingCanvas with SCanvas override def mouseWheelRotated(e: PInputEvent): Unit = { // If wheelRotation is 10, zoomFactor is 0, which causes an exception in zoomBy - // If wheelRotation is > 10, zoomFactor is < 0. The fix is to limit + // If wheelRotation is > 10, zoomFactor is < 0. The fix is to limit // wheelRotation to 9. if (getZoomEventHandler != null) { val wheelRotation = math.min(e.getWheelRotation, 9) @@ -351,8 +348,8 @@ class SpriteCanvas(val kojoCtx: core.KojoCtx) extends PSwingCanvas with SCanvas val labelPrec = if (scale % seedDelta == 0) math.log10(scale).round else prec - val labelText = "%%.%df".format(labelPrec) - val deltaFinder = "%%.%df".format(if (prec == 0) prec else prec - 1) + val labelText = "%%.%df" format (labelPrec) + val deltaFinder = "%%.%df" format (if (prec == 0) prec else prec - 1) val delta = { val d = seedDelta @@ -428,10 +425,10 @@ class SpriteCanvas(val kojoCtx: core.KojoCtx) extends PSwingCanvas with SCanvas axes.addChild(tick) if (!Utils.doublesEqual(ycoord, 0, 1 / math.pow(10, prec + 1))) { - val label = new PText(labelText.format(ycoord)) + val label = new PText(labelText format (ycoord)) label.setOffset(pt2.getX.toFloat, pt2.getY.toFloat) if (isInteger(label.getText)) { - label.setText("%.0f".format(ycoord)) + label.setText("%.0f" format (ycoord)) label.setTextPaint(TickIntegerLabelColor) } else { @@ -466,10 +463,10 @@ class SpriteCanvas(val kojoCtx: core.KojoCtx) extends PSwingCanvas with SCanvas axes.addChild(label) } else { - val label = new PText(labelText.format(xcoord)) + val label = new PText(labelText format (xcoord)) label.setOffset(pt2.getX.toFloat, pt2.getY.toFloat) if (isInteger(label.getText)) { - label.setText("%.0f".format(xcoord)) + label.setText("%.0f" format (xcoord)) label.setTextPaint(TickIntegerLabelColor) } else { @@ -505,13 +502,11 @@ class SpriteCanvas(val kojoCtx: core.KojoCtx) extends PSwingCanvas with SCanvas def zoomBy(factor: Double, mousePos: Point2D): Unit = { require(factor != 0, "Zoom factor can't be 0.") val czoom = currZoom - if ( - (czoom < 1.0e-30 && factor < 1) || - (czoom > 1.0e30 && factor > 1) - ) { - // restrict current zoom to practically usable range, with plenty to spare - canvas items - // disappear after a zoom of approximately 1.0E(+-)10. - // without restriction, the current zoom eventually becomes NaN or Infinity + if ((czoom < 1.0E-30 && factor < 1) || + (czoom > 1.0E30 && factor > 1)) { + // restrict current zoom to practically usable range, with plenty to spare - canvas items + // disappear after a zoom of approximately 1.0E(+-)10. + // without restriction, the current zoom eventually becomes NaN or Infinity return } @@ -644,9 +639,9 @@ class SpriteCanvas(val kojoCtx: core.KojoCtx) extends PSwingCanvas with SCanvas } private def clearHelper(): Unit = { - // can't stop animation because it kills animations that run from within + // can't stop animation because it kills animations that run from within // code blocks inside stories - // kojoCtx.stopAnimation() + // kojoCtx.stopAnimation() gridOff() axesOff() Utils.runInSwingThreadAndWait { @@ -771,7 +766,7 @@ class SpriteCanvas(val kojoCtx: core.KojoCtx) extends PSwingCanvas with SCanvas requestFocusInWindow() getRoot.getDefaultInputManager.setKeyboardFocus(globalEl) } - // try to make this play well with + // try to make this play well with // (a) a slow system or a fast system // (b) a toggle call at the beginning of a script or an activate call at the end Utils.schedule(0) { grabFocus() } @@ -794,7 +789,7 @@ class SpriteCanvas(val kojoCtx: core.KojoCtx) extends PSwingCanvas with SCanvas c match { case color: Color if color.getAlpha == 255 => // full screen windows get messed up with transparent color backgrounds - // so set window background only if color is fully opaque + // so set window background only if color is fully opaque setBackgroundWrapper(color) case _ => val bounds = cbounds @@ -821,15 +816,15 @@ class SpriteCanvas(val kojoCtx: core.KojoCtx) extends PSwingCanvas with SCanvas } def timer(rate: Long)(fn: => Unit): Future[PActivity] = figure0.refresh(rate, 0)(fn) - def timerWithState[S](rate: Long, initState: S)(nextState: S => S): Future[PActivity] = { - var state = initState + def timerWithState[S](rate: Long, init: S)(code: S => S): Future[PActivity] = { + var state = init timer(rate) { - state = nextState(state) + state = code(state) } } def animate(fn: => Unit): Future[PActivity] = timer(1000 / kojoCtx.fps)(fn) - def animateWithState[S](initState: S)(nextState: S => S): Future[PActivity] = - timerWithState(1000 / kojoCtx.fps, initState)(nextState) + def animateWithState[S](init: S)(code: S => S): Future[PActivity] = + timerWithState(1000 / kojoCtx.fps, init)(code) def animateActivity(a: PActivity) = getRoot.addActivity(a) def stopAnimation() = figure0.stopRefresh() @@ -853,7 +848,8 @@ class SpriteCanvas(val kojoCtx: core.KojoCtx) extends PSwingCanvas with SCanvas } import core.Picture - val noPic = picture.Pic { t => } + val noPic = picture.Pic { t => + } @volatile var stage: Picture = _ @volatile var stageLeft: Picture = _ @volatile var stageTop: Picture = _ @@ -906,13 +902,13 @@ class SpriteCanvas(val kojoCtx: core.KojoCtx) extends PSwingCanvas with SCanvas stage.draw() } - protected override def sendInputEventToInputManager(event: InputEvent, typ: Int): Unit = { + override protected def sendInputEventToInputManager(event: InputEvent, typ: Int): Unit = { try { super.sendInputEventToInputManager(event, typ) } catch { case _: RuntimeException => - // Ignore events that Piccolo is unable to handle + // Ignore events that Piccolo is unable to handle } } @@ -1033,7 +1029,7 @@ class SpriteCanvas(val kojoCtx: core.KojoCtx) extends PSwingCanvas with SCanvas addSeparator() - add("%s".format(Utils.loadString("S_MouseActions"))) + add("%s" format (Utils.loadString("S_MouseActions"))) addPopupMenuListener(new PopupMenuListener { def popupMenuWillBecomeVisible(e: PopupMenuEvent): Unit = { axesItem.setState(_showAxes) diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/LangInit.scala b/src/main/scala/net/kogics/kojo/lite/i18n/LangInit.scala index 7d6cd9260..1236749ea 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/LangInit.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/LangInit.scala @@ -3,9 +3,10 @@ package net.kogics.kojo.lite.i18n import java.awt.Font import java.awt.GraphicsEnvironment import java.util.prefs.Preferences -import javax.swing.plaf.FontUIResource + import javax.swing.JMenu import javax.swing.UIManager +import javax.swing.plaf.FontUIResource import net.kogics.kojo.lite.CoreBuiltins diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/deInit.scala b/src/main/scala/net/kogics/kojo/lite/i18n/deInit.scala index 132e7df1e..8a6924a6d 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/deInit.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/deInit.scala @@ -1,7 +1,7 @@ /* - * Copyright (C) 2013 + * Copyright (C) 2013 * Bjorn Regnell , - * Lalit Pant + * Lalit Pant * Christoph Knabe http://public.beuth-hochschule.de/~knabe/ * * The contents of this file are subject to the GNU General Public License @@ -20,244 +20,239 @@ package net.kogics.kojo.lite.i18n -import net.kogics.kojo.lite.Builtins import net.kogics.kojo.lite.CoreBuiltins +import net.kogics.kojo.lite.Builtins import net.kogics.kojo.xscala.RepeatCommands object GermanAPI { - import java.awt.Color - import net.kogics.kojo.core.Turtle - var builtins: net.kogics.kojo.lite.CoreBuiltins = _ // unstable reference to module - + import java.awt.Color + var builtins: net.kogics.kojo.lite.CoreBuiltins = _ //unstable reference to module + trait GermanTurtle { def englishTurtle: Turtle - // sudda() + //sudda() def leeren() = englishTurtle.clear() - // synlig() + //synlig() def sichtbar() = englishTurtle.visible() - // osynlig() + //osynlig() def unsichtbar() = englishTurtle.invisible() - // fram(steg) + //fram(steg) def vor(schritte: Double) = englishTurtle.forward(schritte) - // fram() + //fram() def vor() = englishTurtle.forward(25) - // Not in swedish API + //Not in swedish API def rück(schritte: Double) = englishTurtle.back(schritte) def rück() = englishTurtle.back(25) - // höger(vinkel) + //höger(vinkel) def rechts(grad: Double) = englishTurtle.right(grad) - // höger() + //höger() def rechts() = englishTurtle.right(90) - // vänster(vinkel) + //vänster(vinkel) def links(grad: Double) = englishTurtle.left(grad) - // vänster() + //vänster() def links() = englishTurtle.left(90) - // hoppaTill(x, y) + //hoppaTill(x, y) def springen(x: Double, y: Double) = englishTurtle.jumpTo(x, y) - // hoppa(steg) + //hoppa(steg) def springen(schritte: Double) = { - englishTurtle.saveStyle() // to preserve pen state - englishTurtle.hop(schritte) // hop changes state to penDown after hop + englishTurtle.saveStyle() //to preserve pen state + englishTurtle.hop(schritte) //hop changes state to penDown after hop englishTurtle.restoreStyle() } - // hoppa() + //hoppa() def springen(): Unit = springen(25) - // gåTill(x,y) + //gåTill(x,y) def gehen(x: Double, y: Double) = englishTurtle.moveTo(x, y) - // hem() + //hem() def heim() = englishTurtle.home() - // mot(x,y) + //mot(x,y) def schauen(x: Double, y: Double) = englishTurtle.towards(x, y) - // sättVinkel(vinkel) + //sättVinkel(vinkel) def winkel(grad: Double) = englishTurtle.setHeading(grad) - // vinkel + //vinkel def winkel = englishTurtle.heading - // öster() + //öster() def ost() = englishTurtle.setHeading(0) - // väster() + //väster() def west() = englishTurtle.setHeading(180) - // norr() + //norr() def nord() = englishTurtle.setHeading(90) - // söder() + //söder() def süd() = englishTurtle.setHeading(-90) - // sakta(n) + //sakta(n) def langsam(verzögerung: Long) = englishTurtle.setAnimationDelay(verzögerung) - // skriv(t) + //skriv(t) def schreiben(text: Any) = englishTurtle.write(text) - // textstorlek(s) + //textstorlek(s) def schriftgröße(größe: Int) = englishTurtle.setPenFontSize(größe) - // båge(radie, vinkel) + //båge(radie, vinkel) def bogen(radius: Double, winkel: Double) = englishTurtle.arc(radius, math.round(winkel).toInt) - // cirkel(radie) + //cirkel(radie) def kreis(radius: Double) = englishTurtle.circle(radius) - // läge + //läge def ort = englishTurtle.position - // pennaNer() + //pennaNer() def stiftRunter() = englishTurtle.penDown() - // pennaUpp() + //pennaUpp() def stiftRauf() = englishTurtle.penUp() - // pennanÄrNere + //pennanÄrNere def stiftUnten = englishTurtle.style.down def stiftOben = !englishTurtle.style.down - // färg(c) + //färg(c) def stiftfarbe(farbe: java.awt.Color) = englishTurtle.setPenColor(farbe) - // fyll(c) + //fyll(c) def füllfarbe(farbe: java.awt.Color) = englishTurtle.setFillColor(farbe) - // bredd(n) + //bredd(n) def stiftbreite(breite: Double) = englishTurtle.setPenThickness(breite) - // sparaStil() + //sparaStil() def stilSpeichern() = englishTurtle.saveStyle() - // laddaStil() + //laddaStil() def stilHolen() = englishTurtle.restoreStyle() - // sparaLägeRiktning() + //sparaLägeRiktning() def lageSpeichern() = englishTurtle.savePosHe() - // laddaLägeRiktning() + //laddaLägeRiktning() def lageHolen() = englishTurtle.restorePosHe() - // siktePå() + //siktePå() def kreuzAn() = englishTurtle.beamsOn() - // sikteAv() + //sikteAv() def kreuzAus() = englishTurtle.beamsOff() - // kostym(filNamn) + //kostym(filNamn) def kostüm(dateiname: String) = englishTurtle.setCostume(dateiname) - // kostymer(filNamn) + //kostymer(filNamn) def kostüme(dateinamen: String*) = englishTurtle.setCostumes(dateinamen: _*) - // nästaKostym() + //nästaKostym() def kostümWechseln() = englishTurtle.nextCostume() } - // Padda + //Padda class Kröte(override val englishTurtle: Turtle) extends GermanTurtle { - def this(startX: Double, startY: Double, kostümDateiname: String) = - this(builtins.TSCanvas.newTurtle(startX, startY, kostümDateiname)) + def this(startX: Double, startY: Double, kostümDateiname: String) = this(builtins.TSCanvas.newTurtle(startX, startY, kostümDateiname)) def this(startX: Double, startY: Double) = this(startX, startY, "/images/turtle32.png") - def this() = this(0, 0) + def this() = this(0,0) } - // Padda0 - class Kröte0(t0: => Turtle) extends GermanTurtle { // by-name construction as turtle0 is volatile } + //Padda0 + class Kröte0(t0: => Turtle) extends GermanTurtle { //by-name construction as turtle0 is volatile } override def englishTurtle: Turtle = t0 } - // padda + //padda object kröte extends Kröte0(builtins.TSCanvas.turtle0) - // sudda() + //sudda() def leeren() = builtins.TSCanvas.clear() - // suddaUtdata() + //suddaUtdata() def ausgabeLeeren() = builtins.clearOutput() - // blå + //blå lazy val blau = builtins.blue - // röd + //röd lazy val rot = builtins.red - // gul + //gul lazy val gelb = builtins.yellow - // grön - lazy val grün = builtins.green + //grön + lazy val grün = builtins.green lazy val lila = builtins.purple lazy val rosa = builtins.pink - // brun - lazy val braun = builtins.brown - // svart + //brun + lazy val braun = builtins.brown + //svart lazy val schwarz = builtins.black - // Not in swedish API + //Not in swedish API lazy val grau = builtins.gray - // vit + //vit lazy val weiß = builtins.white - // genomskinlig + //genomskinlig lazy val durchsichtig = builtins.noColor - // bakgrund(färg) + //bakgrund(färg) def grundfarbe(farbe: Color) = builtins.setBackground(farbe) - // bakgrund2(färg1, färg2) + //bakgrund2(färg1, färg2) def grundfarbeUO(farbeUnten: Color, farbeOben: Color) = builtins.TSCanvas.setBackgroundV(farbeUnten, farbeOben) def grundfarbeLR(farbeLinks: Color, farbeRechts: Color) = builtins.TSCanvas.setBackgroundH(farbeLinks, farbeRechts) - object KcGer { // Key codes for German keys as in Unicode + object KcGer { //Key codes for German keys as in Unicode lazy val VK_Ä = 196 lazy val VK_Ö = 214 lazy val VK_Ü = 220 lazy val VK_ß = 223 } - - // Loops in German: - // upprepa(n) + + //Loops in German: + //upprepa(n) def schleife(anzahl: Int)(block: => Unit): Unit = { - RepeatCommands.repeatFor(1 to anzahl) { i => block } + RepeatCommands.repeatFor(1 to anzahl){i => block} } - // sålänge(villkor: => Boolean)(block: => Unit) + //sålänge(villkor: => Boolean)(block: => Unit) def schleifeSolange(bedingung: => Boolean)(block: => Unit): Unit = { - RepeatCommands.repeatWhile(bedingung) { block } + RepeatCommands.repeatWhile(bedingung){block} } - // Not in swedish API + //Not in swedish API def schleifeBis(bedingung: => Boolean)(block: => Unit): Unit = { - RepeatCommands.repeatUntil(bedingung) { block } + RepeatCommands.repeatUntil(bedingung){block} } - // I mean too limited by fixing the start value. Christoph: - // def räkneslinga(n: Int)(block: Int => Unit) { + //I mean too limited by fixing the start value. Christoph: + //def räkneslinga(n: Int)(block: Int => Unit) { // for (i <- 1 to n) block(i) - // } - def schleifeBereich(start: Int, ende: Int)(verarbeiten: Int => Unit): Unit = { - RepeatCommands.repeatFor(start to ende) { verarbeiten } + //} + def schleifeBereich(start: Int, ende: Int)(verarbeiten: Int => Unit): Unit ={ + RepeatCommands.repeatFor(start to ende){verarbeiten} } - // The new Kojo loops from RepeatCommands regularly call the Throttler to enable interruption of busy loops. - // New in Kojo with name repeatFor at 2015-02-23, thus not yet in swedish API: - // Allows: - // schleifeFür(1 to 5){} - // schleifeFür(0 until 5)[} - // schleifeFür(Seq(red, green, blue)){} - def schleifeFür[T](elemente: Iterable[T])(verarbeiten: T => Unit): Unit = { - RepeatCommands.repeatFor(elemente) { verarbeiten } + //The new Kojo loops from RepeatCommands regularly call the Throttler to enable interruption of busy loops. + //New in Kojo with name repeatFor at 2015-02-23, thus not yet in swedish API: + //Allows: + //schleifeFür(1 to 5){} + //schleifeFür(0 until 5)[} + //schleifeFür(Seq(red, green, blue)){} + def schleifeFür[T](elemente: Iterable[T])(verarbeiten: T => Unit): Unit ={ + RepeatCommands.repeatFor(elemente){verarbeiten} } - - // simple IO - // indata(ledtext) - def einlesen(aufforderung: String): String = builtins.readln(aufforderung) - - // utdata(data) - def ausgeben(daten: Any) = println(daten) // Transferred here from sv.tw.kojo. Seems to work in german API. + + //simple IO + //indata(ledtext) + def einlesen(aufforderung: String): String = builtins.readln(aufforderung) + + //utdata(data) + def ausgeben(daten: Any) = println(daten) //Transferred here from sv.tw.kojo. Seems to work in german API. def ausgeben() = println() - - // math functions - // avrunda(tal, antalDecimaler) + + //math functions + //avrunda(tal, antalDecimaler) def runden(zahl: Number, nachkommastellen: Int = 0): Double = { val faktor = math.pow(10, nachkommastellen).toDouble math.round(zahl.doubleValue * faktor).toLong / faktor } - // slumptal(n) + //slumptal(n) def zufall(wenigerAls: Int) = builtins.random(wenigerAls) def zufallBruch(wenigerAls: Int) = builtins.randomDouble(wenigerAls) - - // some type aliases in Swedish - // Heltal + + //some type aliases in Swedish + //Heltal type Ganzzahl = Int - // Decimaltal + //Decimaltal type Bruchzahl = Double - // Sträng + //Sträng type Text = String - - // For speed test: - // systemtid - def systemzeit = BigDecimal(System.nanoTime) / BigDecimal("1000000000") // sekunder - - // räknaTill - @annotation.nowarn - def zählzeitStoppen(bisZahl: BigInt): Unit = { + + //For speed test: + //systemtid + def systemzeit = BigDecimal(System.nanoTime) / BigDecimal("1000000000") //sekunder + + //räknaTill + @annotation.nowarn def zählzeitStoppen(bisZahl: BigInt): Unit = { var c: BigInt = 1 print("*** Zählen von 1 bis ... ") val startZeit = systemzeit - while (c < bisZahl) { c = c + 1 } // braucht Zeit, wenn bisZahl groß ist + while (c < bisZahl) { c = c + 1 } //braucht Zeit, wenn bisZahl groß ist val stoppZeit = systemzeit println(s"$bisZahl *** FERTIG!") val dauer = stoppZeit - startZeit print("Das dauerte ") if (dauer < 0.1) - println( - (dauer * 1000).round(new java.math.MathContext(2)) + - " Millisekunden." - ) + println((dauer * 1000).round(new java.math.MathContext(2)) + + " Millisekunden.") else println((dauer * 10).toLong / 10.0 + " Sekunden.") } - + } object DeInit { def init(builtins: CoreBuiltins): Unit = { - // initialize unstable value + //initialize unstable value GermanAPI.builtins = builtins builtins match { case b: Builtins => @@ -267,12 +262,12 @@ object DeInit { } b.setEditorTabSize(2) - // code completion + //code completion b.addCodeTemplates( "de", codeTemplates ) - // help texts + //help texts b.addHelpContent( "de", helpContent @@ -281,8 +276,8 @@ object DeInit { case _ => } } - - val codeTemplates = Map[String, String]( + + val codeTemplates = Map[String,String]( "englishTurtle" -> "englishTurtle", "vor" -> "vor(${schritte})", "rück" -> "rück(${schritte})", @@ -291,14 +286,14 @@ object DeInit { "springen" -> "springen(${schritte})", "springen" -> "springen(${x},${y})", "gehen" -> "gehen(${x},${y})", - "heim" -> "heim()", + "heim" -> "heim()", "schauen" -> "schauen(${x},${y})", "winkel" -> "winkel(${grad})", - "ost" -> "ost()", - "west" -> "west()", - "nord" -> "nord()", + "ost" -> "ost()", + "west" -> "west()", + "nord" -> "nord()", "söder" -> "süd()", - "langsam" -> "langsam(${verzögerung})", + "langsam" -> "langsam(${verzögerung})", "schreiben" -> "schreiben(${text})", "schriftgröße" -> "schriftgröße(${größe})", "bogen" -> "bogen(${radius},${winkel})", @@ -314,7 +309,7 @@ object DeInit { "füllfarbe" -> "füllfarbe(${füllfarbe})", "stiftbreite" -> "stiftbreite(${breite})", "stilSpeichern" -> "stilSpeichern()", - "stilHolen" -> "stilHolen()", + "stilHolen" -> "stilHolen()", "lageSpeichern" -> "lageSpeichern()", "lageHolen" -> "lageHolen()", "kreuzAn" -> "kreuzAn()", @@ -341,8 +336,8 @@ object DeInit { "kostümWechseln" -> "kostümWechseln()" ) - val helpContent = Map[String, String]( - "englishTurtle" -> + val helpContent = Map[String,String]( + "englishTurtle" ->
    englishTurtle

    Liefert die englische Schildkröte als Objekt des Typs Turtle. @@ -372,8 +367,8 @@ rechts(45) //Die Schildkröte dreht sich um 45 Grad nach rechts. Englisch: forward
    .toString, - "rück" -> -
    + "rück" -> +
    rück(schritte)

    Bewegt die Schildkröte die angegebene Anzahl von Schritten rückwärts. Ihre Kopfrichtung (winkel) wird dabei nicht geändert.

    @@ -391,7 +386,7 @@ vor(100) Englisch: back
    .toString, - "links" -> + "links" ->
    links(grad)

    Dreht die Schildkröte um die angegebene Gradzahl nach links. Ohne (grad) wird sie um 90 Grad gedreht.
    @@ -402,7 +397,7 @@ links() //Dreht die Schildkröte um 90 Grad nach links. Englisch: left
    .toString, - "rechts" -> + "rechts" ->
    rechts(grad)

    Dreht die Schildkröte um die angegebene Gradzahl nach rechts. Ohne (grad) wird sie um 90 Grad gedreht.
    @@ -413,7 +408,7 @@ rechts() //Dreht die Schildkröte um 90 Grad nach rechts. Englisch: right
    .toString, - "springen" -> + "springen" ->
    springen(x, y)
    Die Schildkröte springt zum Ort (x,y) ohne zu zeichnen und ohne ihren Winkel (Kopfrichtung) zu ändern.
    Englisch: jumpTo @@ -422,14 +417,14 @@ rechts() //Dreht die Schildkröte um 90 Grad nach rechts. springen()
    Die Schildkröte springt in Kopfrichtung 25 Schritte ohne zu zeichnen.
    Englisch: hop
    .toString, - "gehen" -> + "gehen" ->
    gehen(x, y)

    Die Schildkröte dreht sich zum Ort (x,y) und geht dorthin.
    Wenn der Stift unten ist, zeichnet sie dabei eine gerade Linie.
    Englisch: moveTo
    .toString, - "heim" -> + "heim" ->
    heim()

    Die Schildkröte bewegt sich zeichnend zum Ursprung und zeigt danach in Richtung Norden.
    @@ -447,12 +442,12 @@ heim() Englisch: home
    .toString, - "schauen" -> + "schauen" ->
    schauen(x, y)

    Dreht die Schildkröte so, dass sie zum Ort (x,y) schaut.
    Endlisch: towards
    .toString, - "winkel" -> + "winkel" ->
    winkel(grad)

    Dreht die Schildkröte so, dass ihre Kopfrichtung den angegebenen Winkel zur positiven x-Achse hat. 90=Nord, 180=West, 270=Süd.
    Englisch: setHeading @@ -460,24 +455,24 @@ heim() winkel

    Liefert den Winkel der Kopfrichtung der Schildkröte zur positiven x-Achse hat. 0=Ost, 90=Nord, 180=West, 270=Süd.
    Englisch: heading
    .toString, - "ost" -> + "ost" ->
    ost()

    Dreht die Schildkröte in Richtung Osten (rechte Seite).
    Englisch: setHeading(0)
    .toString, - "nord" -> + "nord" ->
    nord()

    Dreht die Schildkröte in Richtung Norden (oben).
    Englisch: setHeading(90)
    .toString, - "west" -> + "west" ->
    west()

    Dreht die Schildkröte in Richtung Westen (linke Seite).
    Englisch: setHeading(180)
    .toString, - "süd" -> + "süd" ->
    süd()

    Dreht die Schildkröte in Richtung Süden (unten).
    Englisch: setHeading(270)
    .toString, - "langsam" -> + "langsam" ->
    langsam(verzögerung)

    Legt die Langsamkeit der Schildkröte fest. Die angegebene verzögerung ist die Dauer (in Millisekunden), die die Schildkröte braucht, um hundert Schritte zurückzulegen.
    @@ -500,41 +495,41 @@ forward(100) Englisch: setAnimationDelay
    .toString, - "schreiben" -> + "schreiben" ->
    schreiben(text)

    Die Schildkröte schreibt rechts von sich den text in den Zeichenbereich.
    Ein Text muss in Anführungszeichen eingeschlossen werden. Beispiel: schreiben("Hallo")
    Englisch: write
    .toString, - "schriftgröße" -> + "schriftgröße" ->
    schriftgröße(größe)
    Legt die Schriftgröße fürs Textschreiben fest.
    Englisch: setPenFontSize
    .toString, - "bogen" -> + "bogen" ->
    bogen(radius, winkel)

    Zeichnet einen Kreisbogen mit dem radius und winkel. Positive Winkel bewegen die Schildkröte gegen, negative mit dem Uhrzeigersinn.
    Englisch: arc
    .toString, - "kreis" -> + "kreis" ->
    kreis(radius)

    Zeichnet einen kompletten Kreis mit dem radius gegen den Uhrzeigersinn.
    Englisch: circle
    .toString, - "sichtbar" -> + "sichtbar" ->
    sichtbar()

    Macht die Schildkröte sichtbar.
    Englisch: visible
    .toString, - "unsichtbar" -> + "unsichtbar" ->
    unsichtbar()

    Macht die Schildkröte unsichtbar. Sie kann wieder sichtbar gemacht werden mit dem Befehl sichtbar().
    Englisch: invisible
    .toString, - "ort" -> + "ort" ->
    ort

    Liefert den aktuellen Ort der Schildkröte als Punktwert Point(x,y). @@ -551,29 +546,29 @@ hoppaTill(x, y) //Springt zum neuen Ort mit der geänderten x-Koordinate. Englisch: position
    .toString, - "stiftRunter" -> + "stiftRunter" ->
    stiftRunter()
    Senkt den Stift der Schildkröte, so dass sie bei folgenden Bewegungen zeichnet.
    Englisch: penDown
    .toString, - "stiftRauf" -> + "stiftRauf" ->
    stiftRauf()
    Hebt den Stift der Schildkröte an, so dass sie bei folgenden Bewegungen nicht zeichnet.
    Englisch: penUp
    .toString, - "stiftUnten" -> + "stiftUnten" ->
    stiftUnten

    Zeigt an, ob der Stift der Schildkröte unten ist. Liefert true, wenn der Stift unten ist bzw. false, wenn er oben ist.
    Englisch: style.down
    .toString, - "stiftOben" -> + "stiftOben" ->
    stiftOben

    Zeigt an, ob der Stift der Schildkröte oben ist. Liefert true, wenn der Stift oben ist bzw. false, wenn er unten ist.
    Englisch: !style.down
    .toString, - "stiftfarbe" -> + "stiftfarbe" ->
    stiftfarbe(farbe)

    Stellt die Farbe des Schildkrötenstifts auf die angegebene farbe ein. @@ -591,8 +586,8 @@ vor(200) Englisch: setPenColor
    .toString, - "füllfarbe" -> -
    + "füllfarbe" -> +
    füllfarbe(farbe)
    Legt die Füllfarbe für die ab jetzt gezeichnete Figur fest auf farbe.
    Du kannst diese vorgemischten Farben verwenden:
    blau, rot, gelb, grün, lila, rosa, braun, schwarz, grau, weiß, durchsichtig.
    Du kannst eigene Farben mit Color mischen. Siehe bei stiftfarbe. @@ -608,7 +603,7 @@ kreis(100) //Die Schidkröte zeichnet einen roten Kreis, dessen Fläche d Englisch: setFillColor
    .toString, - "stiftbreite" -> + "stiftbreite" ->
    stiftbreite(breite)
    Legt die Breite des Stifts fest, mit dem die Schildkröte zeichnet.

    @@ -624,8 +619,9 @@ stiftbreite(15) vor(100) Englisch: setPenThickness -
    .toString, - "stilSpeichern" -> +
    .toString + , + "stilSpeichern" ->
    stilSpeichern()
    Speichert den jetzigen Zeichenstil der Schildkröte, sodass er später mit stilHolen() einfach wiederhergestellt werden kann.
    @@ -668,7 +664,7 @@ vor(100) Englisch: saveStyle
    .toString, - "stilHolen" -> + "stilHolen" ->
    stilHolen()

    Stellt den Zeichenstil wieder her, der mit dem letzten Aufruf von stilSpeichern() gespeichert wurde. @@ -712,7 +708,7 @@ vor(100) Englisch: restoreStyle
    .toString, - "lageSpeichern" -> + "lageSpeichern" ->
    lageSpeichern()

    Speichert, wo und wie die Schildkröte zur Zeit liegt (Ort und Winkel), @@ -738,7 +734,7 @@ lageHolen() Englisch: savePosHe
    .toString, - "lageHolen" -> + "lageHolen" ->
    lageHolen()

    Stellt die Lage (Ort und Winkel) der Schildkröte wieder her, die mit dem letzten Aufruf von lageSpeichern() gespeichert wurde. @@ -763,36 +759,36 @@ lageHolen() Englisch: restorePosHe
    .toString, - "kreuzAn" -> + "kreuzAn" ->
    kreuzAn()

    Zeigt die exakte Richtung der Schildkröte durch ein Kreuz an.
    Englisch: beamsOn
    .toString, - "kreuzAus" -> + "kreuzAus" ->
    kreuzAus()

    Schaltet das Richtungskreuz der Schildkröte aus.
    Englisch: beamsOff
    .toString, - "leeren" -> + "leeren" ->
    leeren()

    Löscht alles im Zeichenbereich und setzt die Schildkröte in Heim-Lage (x=0, y=0 und winkel=90). Wenn man diese Methode bei einer speziellen Schildkröte anwendet wie meineKröte.leeren(), wird nur das von dieser Schildkröte Gezeichnete gelöscht.
    Englisch: clear
    .toString, - "ausgabeLeeren" -> + "ausgabeLeeren" ->
    ausgabeLeeren()

    Löscht den ganzen Inhalt des Ausgabebereichs.
    Englisch: clearOutput
    .toString, - "grundfarbe" -> + "grundfarbe" ->
    grundfarbe(farbe)

    Legt die Hintergrundfarbe für den Zeichenbereich fest auf farbe.
    Du kannst diese vorgemischten Farben verwenden:
    blau, rot, gelb, grün, lila, rosa, braun, schwarz, grau, weiß, durchsichtig.
    Du kannst eigene Farben mit Color mischen. Siehe bei stiftfarbe.
    Englisch: setBackground
    .toString, - "grundfarbeUO" -> + "grundfarbeUO" ->
    grundfarbeUO(farbeUnten, farbeOben)

    Legt einen Hintergrund-Farbverlauf fest mit farbeUnten unten und farbeOben oben. @@ -800,7 +796,7 @@ lageHolen()
    Du kannst eigene Farben mit Color mischen. Siehe bei stiftfarbe.
    Englisch: setBackgroundV
    .toString, - "grundfarbeLR" -> + "grundfarbeLR" ->
    grundfarbeLR(farbeLinks, farbeRechts)

    Legt einen Hintergrund-Farbverlauf fest mit farbeLinks links und farbeRechts rechts. @@ -808,7 +804,7 @@ lageHolen()
    Du kannst eigene Farben mit Color mischen. Siehe bei stiftfarbe.
    Englisch: setBackgroundH
    .toString, - "schleife" -> + "schleife" ->
    schleife(anzahl) {{ anweisungen }}

    Wiederholt den Block von anweisungen in geschweiften Klammern. @@ -822,7 +818,7 @@ schleife(4) {{ Dieses Beispiel zeichnet ein Quadrat.
    Englisch: repeat
    .toString, - "schleifeSolange" -> + "schleifeSolange" ->
    schleifeSolange(bedingung) {{ anweisungen }}

    Wiederholt den Block von {{anweisungen}} in geschweiften Klammern. @@ -830,14 +826,14 @@ schleife(4) {{
    Beispiel:

     var i = 0
    -schleifeSolange(i{"<"}10) {{ 
    +schleifeSolange(i{ "<" }10) {{ 
           ausgeben(i)
           i = i + 1
     }}
             
    Dieses Beispiel gibt die Ganzzahlen von 0 bis 9 aus.
    Englisch: repeatWhile
    .toString, - "schleifeBis" -> + "schleifeBis" ->
    schleifeBis(bedingung) {{ anweisungen }}

    Wiederholt den Block von anweisungen in geschweiften Klammern. @@ -852,7 +848,7 @@ schleifeBis(i {">"} 5){{ Dieses Beispiel gibt die Ganzzahlen von 1 bis 5 aus.
    Englisch: repeatUntil
    .toString, - "schleifeBereich" -> + "schleifeBereich" ->
    schleifeBereich(start,ende) {{ i => anweisungen }}

    Wiederholt die Folge von anweisungen. @@ -868,8 +864,8 @@ schleifeBereich(1,10){{ Dieses Beispiel gibt die ersten 10 Quadratzahlen aus.
    Englisch: repeatFor(start to ende)
    .toString, - "schleifeFür" -> -
    + "schleifeFür" -> +
    schleifeFür(elemente){{ e => anweisungen}}

    Wiederholt die Folge von anweisungen. Sie wird für jedes der elemente einmal ausgeführt. @@ -896,7 +892,7 @@ schleifeFür (Seq(blau, grün, gelb, rot)) {{ e => Dieses Beispiel zeichnet ein Quadrat, dessen Seiten blau, grün, gelb und rot sind.
    Englisch: repeatFor
    .toString, - "ausgeben" -> + "ausgeben" ->
    ausgeben(daten)

    Gibt die daten als Text in den Ausgabebereich aus. Ein Text (Zeichenkette) muss in Anführungszeichen "..." eingeschlossen sein. @@ -905,7 +901,7 @@ schleifeFür (Seq(blau, grün, gelb, rot)) {{ e => Beispiel: ausgeben("Hallo").
    Englisch: println
    .toString, - "einlesen" -> + "einlesen" ->
    einlesen(aufforderung)

    Zeigt die angegebene aufforderung im Ausgabebereich an und liest eine Zeile, die der Benutzer eingibt. @@ -917,7 +913,7 @@ ausgeben("Hallo, " + x + "!") Englisch: readln
    .toString, - "runden" -> + "runden" ->
    runden(zahl, nachkommastellen)

    Rundet die übergebene zahl mit einer Genauigkeit der angegebenen Anzahl nachkommastellen.
    @@ -930,7 +926,7 @@ ausgeben(z2) Englisch: math.round
    .toString, - "systemzeit" -> + "systemzeit" ->
    systemzeit
    Liefert die Systemzeit in Sekunden als Bruchzahl. Du kannst die Systemzeit verwenden, um zu messen, wie lange etwas dauert.
    @@ -947,7 +943,7 @@ val s = stopp - start ausgeben(s"Du hattest $s Sekunden Geduld.")
    .toString, - "zählzeitStoppen" -> + "zählzeitStoppen" ->
    zählzeitStoppen(bisZahl)

    Zählt von 1 bis bisZahl und stoppt die dafür benötigte Zeit. @@ -958,8 +954,8 @@ ausgeben(s"Du hattest $s Sekunden Geduld.") zählzeitStoppen(5000)
    .toString, - // zufall(wenigerAls: Int) - "zufall" -> + //zufall(wenigerAls: Int) + "zufall" ->
    zufall(wenigerAls)

    Liefert eine zufällige Ganzzahl zwischen 0 (einschließlich) und wenigerAls (ausschließlich).
    @@ -971,7 +967,7 @@ schleife(10){{ Gibt 10 zufällige Ganzzahlen im Bereich 1...20 aus.
    Englisch: random
    .toString, - "zufallBruch(wenigerAls)" -> + "zufallBruch(wenigerAls)" ->
    zufallBruch(wenigerAls)

    Liefert eine zufällige Bruchzahl zwischen 0 (einschließlich) und wenigerAls (ausschließlich).
    @@ -984,7 +980,7 @@ schleife(4){{ Gibt 4 zufällige Bruchzahlen im Bereich 0.0 bis 9.999999999999999 aus, zum Beispiel 7.944168334647333 1.5762542354581088 3.078541034787967 0.7535865933723174
    Englisch: randomDouble
    .toString, - "kostüm" -> + "kostüm" ->
    kostüm(dateiname)
    Nimmt das Bild in der angegebenen Datei als Kostüm, d.h. für das Aussehen der Schildkröte.
    Beispiel:
      
    @@ -998,18 +994,18 @@ auto.vor(100)
             
    Englisch: setCostume
    .toString, - "kostüme" -> + "kostüme" ->
    kostüme(dateiname1, dateiname2, ...)
    Nimmt die Bilder in den Dateien als mögliche Kostüme, d.h. für das Aussehen der Schildkröte und legt das erste Bild als jetziges Kostüm fest. Man kann die Kostüme durchlaufen mit Aufruf von kostümWechseln().
    Englisch: setCostumes
    .toString, - "kostümWechseln" -> + "kostümWechseln" ->
    kostümWechseln()

    Ändert das Schildkrötenkostüm zu dem nächsten in der Reihe der Kostüme, die durch kostüme(...) festgelegt wurden.
    Englisch: nextCostume
    .toString ) -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/esInit.scala b/src/main/scala/net/kogics/kojo/lite/i18n/esInit.scala index eb8c44439..1a38f6b71 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/esInit.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/esInit.scala @@ -20,15 +20,14 @@ package net.kogics.kojo.lite.i18n -import net.kogics.kojo.lite.Builtins import net.kogics.kojo.lite.CoreBuiltins +import net.kogics.kojo.lite.Builtins import net.kogics.kojo.xscala.RepeatCommands object SpanishAPI { - import java.awt.Color - import net.kogics.kojo.core.Turtle - var builtins: net.kogics.kojo.lite.CoreBuiltins = _ // unstable reference to module + import java.awt.Color + var builtins: net.kogics.kojo.lite.CoreBuiltins = _ //unstable reference to module trait SpanishTurtle { def englishTurtle: Turtle @@ -44,8 +43,8 @@ object SpanishAPI { def saltoA(x: Double, y: Double) = englishTurtle.jumpTo(x, y) def moverA(x: Double, y: Double) = englishTurtle.moveTo(x, y) def salto(n: Double) = { - englishTurtle.saveStyle() // to preserve pen state - englishTurtle.hop(n) // hop change state to penDown after hop + englishTurtle.saveStyle() //to preserve pen state + englishTurtle.hop(n) //hop change state to penDown after hop englishTurtle.restoreStyle() } def salto(): Unit = salto(25) @@ -80,12 +79,11 @@ object SpanishAPI { def siguienteDisfraz() = englishTurtle.nextCostume() } class Tortuga(override val englishTurtle: Turtle) extends SpanishTurtle { - def this(startX: Double, startY: Double, costumeFileName: String) = - this(builtins.TSCanvas.newTurtle(startX, startY, costumeFileName)) + def this(startX: Double, startY: Double, costumeFileName: String) = this(builtins.TSCanvas.newTurtle(startX, startY, costumeFileName)) def this(startX: Double, startY: Double) = this(startX, startY, "/images/turtle32.png") def this() = this(0, 0) } - class Tortuga0(t0: => Turtle) extends SpanishTurtle { // by-name construction as turtle0 is volatile } + class Tortuga0(t0: => Turtle) extends SpanishTurtle { //by-name construction as turtle0 is volatile } override def englishTurtle: Turtle = t0 } object tortuga extends Tortuga0(builtins.TSCanvas.turtle0) @@ -110,7 +108,7 @@ object SpanishAPI { // lazy val VK_Ö = 214 // } - // loops + //loops def repetir(n: Int)(block: => Unit): Unit = { RepeatCommands.repeat(n) { block } } @@ -127,13 +125,13 @@ object SpanishAPI { RepeatCommands.repeatFor(secuencia) { block } } - // simple IO + //simple IO def leerln(prompt: String = "") = builtins.readln(prompt) - def imprimirln(data: Any) = println(data) // Transferred here from sv.tw.kojo. + def imprimirln(data: Any) = println(data) //Transferred here from sv.tw.kojo. def imprimirln() = println() - // math functions + //math functions def redondear(numero: Number, digito: Int = 0): Double = { val faktor = math.pow(10, digito).toDouble math.round(numero.doubleValue * faktor).toLong / faktor @@ -144,7 +142,7 @@ object SpanishAPI { object SpanishInit { def init(builtins: CoreBuiltins): Unit = { - // initialize unstable value + //initialize unstable value SpanishAPI.builtins = builtins builtins match { case b: Builtins => @@ -155,12 +153,12 @@ object SpanishInit { // b.setEditorTabSize(2) - // code completion + //code completion b.addCodeTemplates( "es", codeTemplates ) - // help texts + //help texts b.addHelpContent( "es", helpContent diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/hrInit.scala b/src/main/scala/net/kogics/kojo/lite/i18n/hrInit.scala index a7980e5ce..de026bdbc 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/hrInit.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/hrInit.scala @@ -1,7 +1,7 @@ /* - * Copyright (C) 2013 + * Copyright (C) 2013 * Bjorn Regnell , - * Lalit Pant + * Lalit Pant * * The contents of this file are subject to the GNU General Public License * Version 3 (the "License"); you may not use this file @@ -19,15 +19,14 @@ package net.kogics.kojo.lite.i18n -import net.kogics.kojo.lite.Builtins import net.kogics.kojo.lite.CoreBuiltins +import net.kogics.kojo.lite.Builtins import net.kogics.kojo.xscala.RepeatCommands object CroatianAPI { - import java.awt.Color - import net.kogics.kojo.core.Turtle - var builtins: net.kogics.kojo.lite.CoreBuiltins = _ // unstable reference to module + import java.awt.Color + var builtins: net.kogics.kojo.lite.CoreBuiltins = _ //unstable reference to module trait CroatianTurtle { def englishTurtle: Turtle @@ -43,8 +42,8 @@ object CroatianAPI { def skočiNa(x: Double, y: Double) = englishTurtle.jumpTo(x, y) def idiNa(x: Double, y: Double) = englishTurtle.moveTo(x, y) def skoči(n: Double) = { - englishTurtle.saveStyle() // to preserve pen state - englishTurtle.hop(n) // hop change state to penDown after hop + englishTurtle.saveStyle() //to preserve pen state + englishTurtle.hop(n) //hop change state to penDown after hop englishTurtle.restoreStyle() } def skoči(): Unit = skoči(25) @@ -79,12 +78,11 @@ object CroatianAPI { def sljedećiKostim() = englishTurtle.nextCostume() } class Kornjača(override val englishTurtle: Turtle) extends CroatianTurtle { - def this(startX: Double, startY: Double, costumeFileName: String) = - this(builtins.TSCanvas.newTurtle(startX, startY, costumeFileName)) + def this(startX: Double, startY: Double, costumeFileName: String) = this(builtins.TSCanvas.newTurtle(startX, startY, costumeFileName)) def this(startX: Double, startY: Double) = this(startX, startY, "/images/turtle32.png") def this() = this(0, 0) } - class Kornjača0(t0: => Turtle) extends CroatianTurtle { // by-name construction as turtle0 is volatile } + class Kornjača0(t0: => Turtle) extends CroatianTurtle { //by-name construction as turtle0 is volatile } override def englishTurtle: Turtle = t0 } object kornjača extends Kornjača0(builtins.TSCanvas.turtle0) @@ -109,7 +107,7 @@ object CroatianAPI { // lazy val VK_Ö = 214 // } - // loops + //loops def ponovi(n: Int)(block: => Unit): Unit = { RepeatCommands.repeat(n) { block } } @@ -126,13 +124,13 @@ object CroatianAPI { RepeatCommands.repeatFor(slijed) { block } } - // simple IO + //simple IO def čitajln(upit: String = "") = builtins.readln(upit) - def pišiln(data: Any) = println(data) // Transferred here from sv.tw.kojo. + def pišiln(data: Any) = println(data) //Transferred here from sv.tw.kojo. def pišiln() = println() - // math functions + //math functions def zaokruži(broj: Number, znamenka: Int = 0): Double = { val faktor = math.pow(10, znamenka).toDouble math.round(broj.doubleValue * faktor).toLong / faktor @@ -140,7 +138,7 @@ object CroatianAPI { def slučajan(gornjaGranica: Int) = builtins.random(gornjaGranica) def slučajanDupli(gornjaGranica: Int) = builtins.randomDouble(gornjaGranica) - // some type aliases in Swedish + //some type aliases in Swedish type Broj = Int type Dvostruki = Double type Niz = String @@ -148,7 +146,7 @@ object CroatianAPI { object hrInit { def init(builtins: CoreBuiltins): Unit = { - // initialize unstable value + //initialize unstable value CroatianAPI.builtins = builtins builtins match { case b: Builtins => @@ -156,15 +154,15 @@ object hrInit { if (b.isScratchPad) { println("Povijest neće biti snimljena kada zatvorite Kojo podlogu za natuknice.") } - + // b.setEditorTabSize(2) - // code completion + //code completion b.addCodeTemplates( "hr", codeTemplates ) - // help texts + //help texts b.addHelpContent( "hr", helpContent @@ -261,7 +259,7 @@ object hrInit { "zrakeUgašene" ->
    zrakeUgašene() - Skriva kornjačine zrake koje su bile uključene sa zrakeUpaljene().
    .toString, "obriši" ->
    obriši() - Briše kornjačino platno i postavlja ju u sredinu.
    .toString, "obrišiIzlaz" ->
    obrišiIzlaz() - Briše izlazni prozor.
    .toString, - "postaviPozadinu" ->
    postaviPozadinu(boja) - Postavlja pozadinu platna u određenu boju. Možete koristiti predefinirane boje za bojanje pozadine, ili možete stvoriti nove boje koristeći Boja, BojaHSB, i BojaG funkcije.
    .toString, + "postaviPozadinu" ->
    postaviPozadinu(boja) - Postavlja pozadinu platna u određenu boju. Možete koristiti predefinirane boje za bojanje pozadine, ili možete stvoriti nove boje koristeći Boja, BojaHSB, i BojaG funkcije.
    .toString, "postaviPozadinuV" ->
    postaviPozadinuV(boja1, boja2) - Postavlja pozadinu platna u okomit obojani gradijent definiran s dvije boje.
    .toString, "ponovi" ->
    ponovi(n){{ }} - Ponavlja određeni skup komandi (unutar vitičastih zagrada) n puta.
    .toString, "ponovii" ->
    ponovii(n) {{i => }} - Ponavlja određeni skup komandi (unutar vitičastih zagrada) n puta. Trenutna veličina iteratora dostupna je kao i unutar vitičastih zagrada.
    .toString, diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/itInit.scala b/src/main/scala/net/kogics/kojo/lite/i18n/itInit.scala index dfc538169..ac4b3e1ef 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/itInit.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/itInit.scala @@ -20,15 +20,15 @@ package net.kogics.kojo.lite.i18n -import java.awt.geom.Point2D import java.awt.Font -import java.awt.Image import java.awt.Paint +import java.awt.geom.Point2D +import java.awt.Image -import net.kogics.kojo.core.Voice -import net.kogics.kojo.lite.Builtins import net.kogics.kojo.lite.CoreBuiltins +import net.kogics.kojo.lite.Builtins import net.kogics.kojo.xscala.RepeatCommands +import net.kogics.kojo.core.Voice object ItalianDirectionCases { @@ -55,34 +55,34 @@ object ItalianSpeedCases { case object Velocissima extends Velocità } + object ItalianCustomStatements { import scala.language.implicitConversions - class IfClauseExpression[T1, T2](fn1: => T1, fn2: => T2) { + class IfClauseExpression[T1, T2](fn1: => T1, fn2: => T2){ lazy val pred = fn1 lazy val compl = fn2 } - implicit class TernaryAssocExpression(cond: => Boolean) { + implicit class TernaryAssocExpression(cond: => Boolean){ def ??[T](thenFn: => T) = new IfClauseExpression(cond, thenFn) } - implicit class TernaryElseClauseExpression[T](falseFn: => T) { + implicit class TernaryElseClauseExpression[T](falseFn: => T){ def ::(clause: IfClauseExpression[Boolean, T]) = - if (clause.pred) clause.compl else falseFn + if(clause.pred) clause.compl else falseFn } def isNotEmpty[T](value: T): Boolean = { Option(value) match { case None => false - case Some(v) => - v match { - case false => false - case 0 => false - case s: String if s.isEmpty => false - case _ => true - } + case Some(v) => v match { + case false => false + case 0 => false + case s: String if s.isEmpty => false + case _ => true + } } } @@ -94,13 +94,14 @@ object ItalianCustomStatements { implicit class OrOperator[T](thatFn: => T) { def oppure[A >: T](thisFn: A) = { - if (isNotEmpty(thatFn)) thatFn else thisFn + if(isNotEmpty(thatFn)) thatFn else thisFn } } - class IfThenClauseExpression[T](cond: => Boolean, thenFn: => T) extends IfClauseExpression(cond, thenFn) { + class IfThenClauseExpression[T](cond: => Boolean, thenFn: => T) + extends IfClauseExpression(cond, thenFn) { def altrimenti[T](elseFn: => T) = { - if (cond) thenFn else elseFn + if(cond) thenFn else elseFn } } @@ -115,14 +116,13 @@ object ItalianCustomStatements { } object ItalianAPI { - import java.awt.Color - - import net.kogics.kojo.core.Turtle - import net.kogics.kojo.util.Utils import ItalianDirectionCases._ import ItalianSpeedCases._ + import net.kogics.kojo.core.Turtle + import java.awt.Color + import net.kogics.kojo.util.Utils - var builtins: net.kogics.kojo.lite.CoreBuiltins = _ // unstable reference to module + var builtins: net.kogics.kojo.lite.CoreBuiltins = _ //unstable reference to module import ItalianCustomStatements._ @@ -143,8 +143,8 @@ object ItalianAPI { def muoviVerso(x: Double, y: Double) = englishTurtle.moveTo(x, y) def cambiaPosizione(x: Double, y: Double) = englishTurtle.changePosition(x, y) def salta(n: Double) = { - englishTurtle.saveStyle() // to preserve pen state - englishTurtle.hop(n) // hop change state to penDown after hop + englishTurtle.saveStyle() //to preserve pen state + englishTurtle.hop(n) //hop change state to penDown after hop englishTurtle.restoreStyle() } def salta(): Unit = salta(25) @@ -159,10 +159,10 @@ object ItalianAPI { def valoreRitardo = englishTurtle.animationDelay def ritardo(n: Long) = englishTurtle.setAnimationDelay(n) def velocità(v: Velocità) = v match { - case Lentissima => englishTurtle.setAnimationDelay(2000) - case Lenta => englishTurtle.setAnimationDelay(1000) - case Media => englishTurtle.setAnimationDelay(100) - case Veloce => englishTurtle.setAnimationDelay(10) + case Lentissima => englishTurtle.setAnimationDelay(2000) + case Lenta => englishTurtle.setAnimationDelay(1000) + case Media => englishTurtle.setAnimationDelay(100) + case Veloce => englishTurtle.setAnimationDelay(10) case Velocissima => englishTurtle.setAnimationDelay(0) } def lentezza(v: Long) = englishTurtle.setAnimationDelay(v) @@ -217,14 +217,11 @@ object ItalianAPI { } def quadrato(passi: Double = 100, direzione: Direzione = Destra): Unit = { - square( - passi, - direzione match { - case Destra => Right - case Sinistra => Left + square(passi, direzione match { + case Destra => Right + case Sinistra => Left - } - ) + }) } def triangle(steps: Double, direction: Direction): Unit = { @@ -242,7 +239,7 @@ object ItalianAPI { def polygon(side: Double, sides: Int) = { val a = 180 / (sides.toDouble / 2) - if (sides % 2 >= 0) englishTurtle.left(90 - a) + if(sides % 2 >= 0) englishTurtle.left(90 - a) RepeatCommands.repeat(sides) { englishTurtle.forward(side) englishTurtle.right(a) @@ -252,21 +249,17 @@ object ItalianAPI { def poligono(lato: Double, lati: Int) = polygon(lato, lati) def triangolo(lato: Double, direzione: Direzione = Destra) = { - triangle( - lato, - direzione match { - case Destra => Right - case Sinistra => Left + triangle(lato, direzione match { + case Destra => Right + case Sinistra => Left - } - ) + }) } } class Tartaruga(override val englishTurtle: Turtle) extends ItalianTurtle { - def this(startX: Double, startY: Double, costumeFileName: String) = - this(builtins.TSCanvas.newTurtle(startX, startY, costumeFileName)) + def this(startX: Double, startY: Double, costumeFileName: String) = this(builtins.TSCanvas.newTurtle(startX, startY, costumeFileName)) def this(startX: Double, startY: Double) = this(startX, startY, "/images/turtle32.png") def this() = this(0, 0) @@ -280,10 +273,9 @@ object ItalianAPI { } def nuovaTartaruga(): Tartaruga = new Tartaruga(0, 0) - def nuovaTartaruga(x: Double = 0, y: Double = 0, costume: String = "/images/turtle32.png") = - new Tartaruga(x, y, costume) + def nuovaTartaruga(x: Double = 0, y: Double = 0, costume: String = "/images/turtle32.png") = new Tartaruga(x, y, costume) - class Tartaruga0(t0: => Turtle) extends ItalianTurtle { // by-name construction as turtle0 is volatile } + class Tartaruga0(t0: => Turtle) extends ItalianTurtle { //by-name construction as turtle0 is volatile } override def englishTurtle: Turtle = t0 } @@ -304,7 +296,7 @@ object ItalianAPI { def sfondo(c: Color) = builtins.setBackground(c) def gradiente(c1: Color, c2: Color) = builtins.TSCanvas.setBackgroundV(c1, c2) - // loops + //loops def ripeti(n: Int)(block: => Unit): Unit = { RepeatCommands.repeat(n) { block } } @@ -321,13 +313,13 @@ object ItalianAPI { RepeatCommands.repeatFor(sequenza) { block } } - // simple IO + //simple IO def leggiLinea(pronto: String = "") = builtins.readln(pronto) - def scriviLinea(data: Any) = println(data) // Transferred here from sv.tw.kojo. + def scriviLinea(data: Any) = println(data) //Transferred here from sv.tw.kojo. def scriviLinea() = println() - // math functions + //math functions def arrotonda(numero: Number, cifre: Int = 0): Double = { val faktor = math.pow(10, cifre).toDouble math.round(numero.doubleValue * faktor).toLong / faktor @@ -335,36 +327,35 @@ object ItalianAPI { def numeroCasuale(limitiSuperiori: Int) = builtins.random(limitiSuperiori) def numeroDecimaleCasuale(limitiSuperiori: Int) = builtins.randomDouble(limitiSuperiori) - // some type aliases in Swedish + //some type aliases in Swedish type Intero = Int type Decimale = Double type Stringa = String - // speedTest - def systemtid = BigDecimal(System.nanoTime) / BigDecimal("1000000000") // sekunder + //speedTest + def systemtid = BigDecimal(System.nanoTime) / BigDecimal("1000000000") //sekunder - @annotation.nowarn - def conta(n: BigInt): Unit = { + @annotation.nowarn def conta(n: BigInt): Unit = { var c: BigInt = 1 print("*** conta da 1 fino a ... ") val startTid = systemtid - while (c < n) { c = c + 1 } // tar tid om n är stort + while (c < n) { c = c + 1 } //tar tid om n är stort val stoppTid = systemtid println("" + n + " *** PRONTO!") val tid = stoppTid - startTid print("Ci sono voluti ") if (tid < 0.1) - println( - (tid * 1000).round(new java.math.MathContext(2)) + - " millisecondi." - ) + println((tid * 1000).round(new java.math.MathContext(2)) + + " millisecondi.") else println((tid * 10).toLong / 10.0 + " secondi.") } } + + object ItInit { def init(builtins: CoreBuiltins): Unit = { - // initialize unstable value + //initialize unstable value ItalianAPI.builtins = builtins builtins match { case b: Builtins => @@ -373,12 +364,12 @@ object ItInit { println("Lo storico non sarà salvato nel Blocco Note di Kojo alla chiusura.") } b.setEditorTabSize(2) - // code completion + //code completion b.addCodeTemplates( "it", codeTemplates ) - // help texts + //help texts b.addHelpContent( "it", helpContent @@ -920,4 +911,4 @@ object ItInit {
    """ ) -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/nlInit.scala b/src/main/scala/net/kogics/kojo/lite/i18n/nlInit.scala index dc7ecfdc3..fb672b4e3 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/nlInit.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/nlInit.scala @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 + * Copyright (C) 2013 * Lalit Pant , * Eric Zoerner * Jacco Huysmans @@ -20,15 +20,14 @@ package net.kogics.kojo.lite.i18n -import net.kogics.kojo.lite.Builtins import net.kogics.kojo.lite.CoreBuiltins +import net.kogics.kojo.lite.Builtins import net.kogics.kojo.xscala.RepeatCommands object DutchAPI { - import java.awt.Color - import net.kogics.kojo.core.Turtle - var builtins: net.kogics.kojo.lite.CoreBuiltins = _ // unstable reference to module + import java.awt.Color + var builtins: net.kogics.kojo.lite.CoreBuiltins = _ //unstable reference to module trait DutchTurtle { def engels: Turtle @@ -44,13 +43,13 @@ object DutchAPI { def springNaar(x: Double, y: Double) = engels.jumpTo(x, y) def gaNaar(x: Double, y: Double) = engels.moveTo(x, y) def spring(n: Double) = { - engels.saveStyle() // to preserve pen state - engels.hop(n) // hop change state to penDown after hop + engels.saveStyle() //to preserve pen state + engels.hop(n) //hop change state to penDown after hop engels.restoreStyle() } def spring(): Unit = { - engels.saveStyle() // to preserve pen state - engels.hop() // hop change state to penDown after hop + engels.saveStyle() //to preserve pen state + engels.hop() //hop change state to penDown after hop engels.restoreStyle() } def start() = engels.home() @@ -87,9 +86,9 @@ object DutchAPI { def this(startX: Double, startY: Double, kostuumBestandsNaam: String) = this(builtins.TSCanvas.newTurtle(startX, startY, kostuumBestandsNaam)) def this(startX: Double, startY: Double) = this(startX, startY, "/images/turtle32.png") - def this() = this(0, 0) + def this() = this(0,0) } - class Schildpad0(t0: => Turtle) extends DutchTurtle { // by-name construction as turtle0 is volatile } + class Schildpad0(t0: => Turtle) extends DutchTurtle { //by-name construction as turtle0 is volatile } override def engels: Turtle = t0 } object schildpad extends Schildpad0(builtins.TSCanvas.turtle0) @@ -109,11 +108,11 @@ object DutchAPI { def achterGrond(kleur: Color) = builtins.setBackground(kleur) def achterGrondV(kleur1: Color, kleur2: Color) = builtins.TSCanvas.setBackgroundV(kleur1, kleur2) - // loops in Dutch + //loops in Dutch def herhaal(n: Int)(bloc: => Unit): Unit = { RepeatCommands.repeat(n)(bloc) } - def herhaalTel(n: Int)(bloc: Int => Unit): Unit = { + def herhaalTel (n: Int)(bloc: Int => Unit): Unit = { RepeatCommands.repeati(n)(bloc) } @@ -121,10 +120,10 @@ object DutchAPI { RepeatCommands.repeatWhile(conditie)(bloc) } - // simple IO - def input(leidTekst: String = "") = builtins.readln(leidTekst) + //simple IO + def input(leidTekst: String = "") = builtins.readln(leidTekst) - // math functions + //math functions def rondAf(getal: Number, aantalDecimalen: Int = 0): Double = { val factor = math.pow(10, aantalDecimalen) math.round(getal.doubleValue * factor) / factor @@ -133,54 +132,51 @@ object DutchAPI { def willekeurigDecimaal(n: Int) = builtins.randomDouble(n) def kleur(r: Int, g: Int, b: Int) = builtins.Color(r, g, b) - // some type aliases in Dutch + //some type aliases in Dutch type GeheelGetal = Int type Decimaal = Double type Tekst = String - // speedTest - def systeemTijd() = BigDecimal(System.nanoTime()) / BigDecimal("1000000000") // seconds + //speedTest + def systeemTijd() = BigDecimal(System.nanoTime()) / BigDecimal("1000000000") //seconds - @annotation.nowarn - def telTot(n: BigInt): Unit = { + @annotation.nowarn def telTot(n: BigInt): Unit = { var c: BigInt = 1 print("*** Tel van 1 tot ... ") val startTime = systeemTijd() while (c < n) { c = c + 1 - } // takes time if n is large + } //takes time if n is large val stopTime = systeemTijd() println("" + n + " *** KLAAR!") val time = stopTime - startTime print("Het duurde ") if (time < 0.1) - println( - (time * 1000).round(new java.math.MathContext(2)) + - " millseconden." - ) + println((time * 1000).round(new java.math.MathContext(2)) + + " millseconden.") else println((time * 10).toLong / 10.0 + " seconden.") } } object NlInit { def init(builtins: CoreBuiltins): Unit = { - // initialize unstable value + //initialize unstable value net.kogics.kojo.lite.i18n.DutchAPI.builtins = builtins builtins match { case b: Builtins => println("Welkom in Kojo met Nederlandse schildpad!") if (b.isScratchPad) { - // History for work you do in the Scratchpad will not be saved. + //History for work you do in the Scratchpad will not be saved. println("De geschiedenis wordt niet opgeslagen bij het sluiten van Kojo kladblok.") } b.setEditorTabSize(2) - // code completion + //code completion b.addCodeTemplates( "nl", codeTemplates ) - // help texts + //help texts b.addHelpContent( "nl", helpContent @@ -362,7 +358,7 @@ object NlInit { "zolangAls" ->
    zolangAls(voorwaarde) {{ opdrachten }} - herhaal opdrachten zolang als voorwaarde waar is.
    Voorbeeld:

    var i = 0
    -        zolangAls(i{"<"}10) {{
    +        zolangAls(i{ "<" }10) {{
             output(i)
             i = i + 1
             }}
    @@ -419,4 +415,4 @@ object NlInit {
           aardbei.vooruit(100)
         

    .toString ) -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/plInit.scala b/src/main/scala/net/kogics/kojo/lite/i18n/plInit.scala index 47d0ae0a6..966776e89 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/plInit.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/plInit.scala @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 + * Copyright (C) 2013 * Bjorn Regnell , * Lalit Pant , * Mikołaj Sochacki @@ -20,45 +20,44 @@ package net.kogics.kojo.lite.i18n -import net.kogics.kojo.lite.Builtins import net.kogics.kojo.lite.CoreBuiltins +import net.kogics.kojo.lite.Builtins object PolishAPI { - import java.awt.Color - import net.kogics.kojo.core.Turtle - var builtins: net.kogics.kojo.lite.CoreBuiltins = _ // unstable reference to module - + import java.awt.Color + var builtins: net.kogics.kojo.lite.CoreBuiltins = _ //unstable reference to module + trait PolishTurtle { def englishTurtle: Turtle - def czyść() = englishTurtle.clear() - def pokaż() = englishTurtle.visible() - def ukryj() = englishTurtle.invisible() - def naprzód(kroki: Double) = englishTurtle.forward(kroki) - def naprzód() = englishTurtle.forward(25) + def czyść() = englishTurtle.clear() + def pokaż() = englishTurtle.visible() + def ukryj() = englishTurtle.invisible() + def naprzód(kroki: Double) = englishTurtle.forward(kroki) + def naprzód() = englishTurtle.forward(25) def tył() = englishTurtle.back() - def tył(kroki: Double) = englishTurtle.back(kroki) - def prawo(kąt: Double) = englishTurtle.right(kąt) - def prawo() = englishTurtle.right(90) - def lewo(kąt: Double) = englishTurtle.left(kąt) - def lewo() = englishTurtle.left(90) - def skoczDo(x: Double, y: Double) = englishTurtle.jumpTo(x, y) - def idźDo(x: Double, y: Double) = englishTurtle.moveTo(x, y) + def tył(kroki:Double) = englishTurtle.back(kroki) + def prawo(kąt: Double) = englishTurtle.right(kąt) + def prawo() = englishTurtle.right(90) + def lewo(kąt: Double) = englishTurtle.left(kąt) + def lewo() = englishTurtle.left(90) + def skoczDo(x: Double, y: Double) = englishTurtle.jumpTo(x, y) + def idźDo(x: Double, y: Double) = englishTurtle.moveTo(x, y) def skocz(kroki: Double) = { - englishTurtle.saveStyle() - englishTurtle.hop(kroki) + englishTurtle.saveStyle() + englishTurtle.hop(kroki) englishTurtle.restoreStyle() } def skocz(): Unit = skocz(25) - def dom() = englishTurtle.home() - def kierunek(x: Double, y: Double) = englishTurtle.towards(x, y) - def ustawKąt(kąt: Double) = englishTurtle.setHeading(kąt) - def kąt = englishTurtle.heading - def wschód() = englishTurtle.setHeading(0) + def dom() = englishTurtle.home() + def kierunek(x: Double, y: Double) = englishTurtle.towards(x, y) + def ustawKąt(kąt: Double) = englishTurtle.setHeading(kąt) + def kąt = englishTurtle.heading + def wschód() = englishTurtle.setHeading(0) def zachód() = englishTurtle.setHeading(180) - def północ() = englishTurtle.setHeading(90) + def północ() = englishTurtle.setHeading(90) def południe() = englishTurtle.setHeading(-90) - def spowolnij(n: Long) = englishTurtle.setAnimationDelay(n) + def spowolnij(n: Long) = englishTurtle.setAnimationDelay(n) def pisz(t: Any) = englishTurtle.write(t) def rozmiarCzcionki(s: Int) = englishTurtle.setPenFontSize(s) def łuk(promień: Double, kąt: Double) = englishTurtle.arc(promień, math.round(kąt).toInt) @@ -68,9 +67,10 @@ object PolishAPI { def podnieśPisak() = englishTurtle.penUp() def czyśćStylPisaka = englishTurtle.style.down def kolor(c: java.awt.Color) = englishTurtle.setPenColor(c) - def kolorLosowy = builtins.Color(builtins.random(256), builtins.random(256), builtins.random(256)) - def utwórzKolor(czerwony: Int, zielony: Int, niebieski: Int) = - builtins.Color(czerwony, zielony, niebieski) + def kolorLosowy = builtins.Color(builtins.random(256), + builtins.random(256), builtins.random(256)) + def utwórzKolor(czerwony:Int, zielony:Int, niebieski:Int) = + builtins.Color(czerwony, zielony, niebieski) def wypełnienie(c: java.awt.Color) = englishTurtle.setFillColor(c) def grubość(n: Double) = englishTurtle.setPenThickness(n) def zapiszStyl() = englishTurtle.saveStyle() @@ -84,25 +84,25 @@ object PolishAPI { def następnyKostium() = englishTurtle.nextCostume() } class Żółw(override val englishTurtle: Turtle) extends PolishTurtle { - def this(startX: Double, startY: Double, nazwaPlikuKostiumu: String) = - this(builtins.TSCanvas.newTurtle(startX, startY, nazwaPlikuKostiumu)) + def this(startX: Double, startY: Double, nazwaPlikuKostiumu: String) = + this(builtins.TSCanvas.newTurtle(startX, startY, nazwaPlikuKostiumu)) def this(startX: Double, startY: Double) = this(startX, startY, "/images/turtle32.png") - def this() = this(0, 0) + def this() = this(0,0) } - class Żółw0(t0: => Turtle) extends PolishTurtle { // by-name construction as turtle0 is volatile } + class Żółw0(t0: => Turtle) extends PolishTurtle { //by-name construction as turtle0 is volatile } override def englishTurtle: Turtle = t0 } object żółw extends Żółw0(builtins.TSCanvas.turtle0) def czyść() = builtins.TSCanvas.clear() def czyśćWyjście() = builtins.clearOutput() - lazy val niebieski = builtins.blue // bla - lazy val czerwony = builtins.red - lazy val żółty = builtins.yellow - lazy val zielony = builtins.green + lazy val niebieski = builtins.blue //bla + lazy val czerwony = builtins.red + lazy val żółty = builtins.yellow + lazy val zielony = builtins.green lazy val fioletowy = builtins.purple - lazy val różowy = builtins.pink - lazy val brązowy = builtins.brown - lazy val czarny = builtins.black + lazy val różowy = builtins.pink + lazy val brązowy = builtins.brown + lazy val czarny = builtins.black lazy val biały = builtins.white lazy val przezroczysty = builtins.noColor lazy val szary = builtins.gray @@ -110,8 +110,8 @@ object PolishAPI { def tło(kolor: Color) = builtins.setBackground(kolor) def tłoGradientPion(kolor1: Color, kolor2: Color) = builtins.TSCanvas.setBackgroundV(kolor1, kolor2) def tłoGradientPoz(kolor1: Color, kolor2: Color) = builtins.TSCanvas.setBackgroundH(kolor1, kolor2) - object KcPL { // Key codes Polish - lazy val VK_Ą = 260 + object KcPL { //Key codes Polish + lazy val VK_Ą = 260 lazy val VK_Ę = 280 lazy val VK_Ó = 211 lazy val VK_Ś = 346 @@ -121,7 +121,7 @@ object PolishAPI { lazy val VK_Ć = 262 lazy val VK_Ń = 323 } - + def powtarzaj(n: Int)(blok: => Unit): Unit = { for (i <- 1 to n) blok } @@ -131,45 +131,45 @@ object PolishAPI { def dopóki(warunek: => Boolean)(blok: => Unit): Unit = { while (warunek) blok } - - // simple IO - def wejście(tekst: String = "") = builtins.readln(tekst) - - // math functions + + //simple IO + def wejście(tekst: String = "") = builtins.readln(tekst) + + //math functions def zaokrągl(liczba: Number, miejscPoPrzecinku: Int = 0): Double = { val faktor = math.pow(10, miejscPoPrzecinku).toDouble math.round(liczba.doubleValue * faktor).toLong / faktor } def liczbaLosowa(n: Int) = builtins.random(n) def liczbaLosowaRzeczywista(n: Int) = builtins.randomDouble(n) - - // some type aliases in Polish + + //some type aliases in Polish type Całkowita = Int type Rzeczywista = Double type Napis = String - - // speedTest - def czasSystemowy = System.nanoTime / 1000000000L // sekunder + + //speedTest + def czasSystemowy = System.nanoTime / 1000000000L //sekunder } object PlInit { def init(builtins: CoreBuiltins): Unit = { - // initialize unstable value + //initialize unstable value net.kogics.kojo.lite.i18n.PolishAPI.builtins = builtins builtins match { case b: Builtins => println("Witamy w Kojo w polskiej wersji!") if (b.isScratchPad) { - println("Jesteś w brudnopisie, historia zmian nie zostanie zapisana po jego zamknięciu") + println("Jesteś w brudnopisie, historia zmian nie zostanie zapisana po jego zamknięciu") } b.setEditorTabSize(2) - // code completion + //code completion b.addCodeTemplates( "pl", codeTemplates ) - // help texts + //help texts b.addHelpContent( "pl", helpContent @@ -178,7 +178,7 @@ object PlInit { case _ => } } - + val codeTemplates = Map( "naprzód" -> "naprzód(${kroki})", "tył" -> "tył(${kroki})", @@ -296,9 +296,9 @@ naprzód(200) lub za pomocą ustawKolor(cz,n,z)
    .toString, - "kolorLosowy" ->
    kolorLosowy()
    losuje kolor
    .toString, - "utwórzKolor" ->
    utwórzKolor(czerwony:Int, zielony:Int, niebieski:Int)
    tworzy kolor ze zmiesznia podanych kolorów
    .toString, - "wypełnienie" ->
    wypełnienie(kolor)
    Ustawia kolor wypełnienia. Aby wypełnić musimy wykonać figurę zamkniętą
    .toString, +"kolorLosowy" ->
    kolorLosowy()
    losuje kolor
    .toString, +"utwórzKolor" ->
    utwórzKolor(czerwony:Int, zielony:Int, niebieski:Int)
    tworzy kolor ze zmiesznia podanych kolorów
    .toString, +"wypełnienie" ->
    wypełnienie(kolor)
    Ustawia kolor wypełnienia. Aby wypełnić musimy wykonać figurę zamkniętą
    .toString, "grubość" ->
    grubość(grubość)
    Ustawia grubość pisaka
    .toString, "zapiszStyl" ->
    zapiszStyl()
    Zapamiętuje styl (kolor, grubość pędzla, wypełnienie kolorem)
    >Odczyt stylu odbywa się za pomocą przywróćStyl
    .toString, "przywróćStyl" ->
    przywróćStyl()
    Służy do odczytu zapamiętanego stylu funkcją przwróćStyl
    .toString, @@ -311,7 +311,7 @@ lub za pomocą ustawKolor(cz,n,z) "czyśćWyjście" ->
    czyśćWyjście()
    czyści okno wyjścia (komunikatów)
    .toString, "tło" ->
    tło(kolorTła)
    ustawia kolor tła, zdefiniowane kolory:
    niebieski, czerwony, żółty, zielony, fioletowy, różowy, brązowy, czarny, biały, przezroczysty.
    Możemy też użyć obiektu Color
    .toString, "tłoGradientPion" ->
    tłoGradientPion(kolor1,kolor2)
    ustawia gradient zmieniający się w pionie od koloru kolor1 aż do koloru kolor2
    Dostępe zdefiniowane kolory:
    niebieski, czerwony, żółty, zielony, fioletowy, różowy, brązowy, czarny, pomarańczowy, szary, biały, przezroczysty.
    Można też użyć obiektu Color
    .toString, - "tłoGradientPoz" ->
    tłoGradientPion(kolor1,kolor2)
    ustawia gradient zmieniający się w poziomie od koloru kolor1 aż do koloru kolor2
    Dostępe zdefiniowane kolory:
    niebieski, czerwony, żółty, zielony, fioletowy, różowy, brązowy, czarny, biały, pomarańczowy, szary, przezroczysty.
    Można też użyć obiektu Color
    .toString, +"tłoGradientPoz" ->
    tłoGradientPion(kolor1,kolor2)
    ustawia gradient zmieniający się w poziomie od koloru kolor1 aż do koloru kolor2
    Dostępe zdefiniowane kolory:
    niebieski, czerwony, żółty, zielony, fioletowy, różowy, brązowy, czarny, biały, pomarańczowy, szary, przezroczysty.
    Można też użyć obiektu Color
    .toString, "powtarzaj" ->
    powtarzaj(ilość) {{ polecenia }} - powtarza polecenia w nawiasie zadaną ilość razy.
    Przykład:

    @@ -332,7 +332,7 @@ powtarzajZLicznikem(10) {{ i =>
         "dopóki" -> 
    dopóki(warunek) {{ polecenia }} - powtarza polecenia dopóki warunek logiczny warunek jest prawdziwy
    Przykład:

    var i = 0
    -dopóki(i{"<"}10) {{ 
    +dopóki(i{ "<" }10) {{ 
           drukuj(i)
           i = i + 1
     }}
    diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/ruInit.scala b/src/main/scala/net/kogics/kojo/lite/i18n/ruInit.scala
    index 9228a9d88..5dd949d53 100644
    --- a/src/main/scala/net/kogics/kojo/lite/i18n/ruInit.scala
    +++ b/src/main/scala/net/kogics/kojo/lite/i18n/ruInit.scala
    @@ -1,7 +1,7 @@
     /*
    - * Copyright (C) 2013
    + * Copyright (C) 2013 
      *   Bjorn Regnell ,
    - *   Lalit Pant 
    + *   Lalit Pant  
      *
      * The contents of this file are subject to the GNU General Public License
      * Version 3 (the "License"); you may not use this file
    @@ -19,15 +19,14 @@
     
     package net.kogics.kojo.lite.i18n
     
    -import net.kogics.kojo.lite.Builtins
     import net.kogics.kojo.lite.CoreBuiltins
    +import net.kogics.kojo.lite.Builtins
     import net.kogics.kojo.xscala.RepeatCommands
     
     object RussianAPI {
    -  import java.awt.Color
    -
       import net.kogics.kojo.core.Turtle
    -  var builtins: net.kogics.kojo.lite.CoreBuiltins = _ // unstable reference to module
    +  import java.awt.Color
    +  var builtins: net.kogics.kojo.lite.CoreBuiltins = _ //unstable reference to module
     
       trait RussianTurtle {
         def englishTurtle: Turtle
    @@ -43,8 +42,8 @@ object RussianAPI {
         def перепрыгни(x: Double, y: Double) = englishTurtle.jumpTo(x, y)
         def иди(x: Double, y: Double) = englishTurtle.moveTo(x, y)
         def прыгни(n: Double) = {
    -      englishTurtle.saveStyle() // to preserve pen state
    -      englishTurtle.hop(n) // hop change state to penDown after hop
    +      englishTurtle.saveStyle() //to preserve pen state
    +      englishTurtle.hop(n) //hop change state to penDown after hop
           englishTurtle.restoreStyle()
         }
         def прыгни(): Unit = прыгни(25)
    @@ -79,12 +78,11 @@ object RussianAPI {
         def следующий_костюм() = englishTurtle.nextCostume()
       }
       class Черепашка(override val englishTurtle: Turtle) extends RussianTurtle {
    -    def this(startX: Double, startY: Double, costumeFileName: String) =
    -      this(builtins.TSCanvas.newTurtle(startX, startY, costumeFileName))
    +    def this(startX: Double, startY: Double, costumeFileName: String) = this(builtins.TSCanvas.newTurtle(startX, startY, costumeFileName))
         def this(startX: Double, startY: Double) = this(startX, startY, "/images/turtle32.png")
         def this() = this(0, 0)
       }
    -  class Черепашка0(t0: => Turtle) extends RussianTurtle { // by-name construction as turtle0 is volatile }
    +  class Черепашка0(t0: => Turtle) extends RussianTurtle { //by-name construction as turtle0 is volatile }
         override def englishTurtle: Turtle = t0
       }
       object черепашка extends Черепашка0(builtins.TSCanvas.turtle0)
    @@ -109,7 +107,7 @@ object RussianAPI {
       //    lazy val VK_Ö = 214
       //  }
     
    -  // loops
    +  //loops 
       def повтори(n: Int)(block: => Unit): Unit = {
         RepeatCommands.repeat(n) { block }
       }
    @@ -126,13 +124,13 @@ object RussianAPI {
         RepeatCommands.repeatFor(последовательность) { block }
       }
     
    -  // simple IO
    +  //simple IO
       def прочти(подсказка: String = "") = builtins.readln(подсказка)
     
    -  def напиши(data: Any) = println(data) // Transferred here from sv.tw.kojo.
    +  def напиши(data: Any) = println(data) //Transferred here from sv.tw.kojo.
       def напиши() = println()
     
    -  // math functions
    +  //math functions
       def округли(число: Number, разряд: Int = 0): Double = {
         val faktor = math.pow(10, разряд).toDouble
         math.round(число.doubleValue * faktor).toLong / faktor
    @@ -140,7 +138,7 @@ object RussianAPI {
       def случайное(верхняя_граница: Int) = builtins.random(верхняя_граница)
       def случайное_двойное(верхняя_граница: Int) = builtins.randomDouble(верхняя_граница)
     
    -  // some type aliases in Swedish
    +  //some type aliases in Swedish
       type целое = Int
       type двойное = Double
       type строка = String
    @@ -148,7 +146,7 @@ object RussianAPI {
     
     object RussianInit {
       def init(builtins: CoreBuiltins): Unit = {
    -    // initialize unstable value
    +    //initialize unstable value
         RussianAPI.builtins = builtins
         builtins match {
           case b: Builtins =>
    @@ -156,15 +154,15 @@ object RussianInit {
             if (b.isScratchPad) {
               println("История не будет сохранена при закрытии блокнота Kojo.")
             }
    -
    +        
     //        b.setEditorTabSize(2)
     
    -        // code completion
    +        //code completion
             b.addCodeTemplates(
               "ru",
               codeTemplates
             )
    -        // help texts
    +        //help texts
             b.addHelpContent(
               "ru",
               helpContent
    diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/svInit.scala b/src/main/scala/net/kogics/kojo/lite/i18n/svInit.scala
    index e5540ed5a..aa7cc3747 100644
    --- a/src/main/scala/net/kogics/kojo/lite/i18n/svInit.scala
    +++ b/src/main/scala/net/kogics/kojo/lite/i18n/svInit.scala
    @@ -1,7 +1,7 @@
     /*
    - * Copyright (C) 2013
    + * Copyright (C) 2013 
      *   Bjorn Regnell ,
    - *   Lalit Pant 
    + *   Lalit Pant  
      *
      * The contents of this file are subject to the GNU General Public License
      * Version 3 (the "License"); you may not use this file
    @@ -19,16 +19,15 @@
     
     package net.kogics.kojo.lite.i18n
     
    -import net.kogics.kojo.lite.Builtins
     import net.kogics.kojo.lite.CoreBuiltins
    +import net.kogics.kojo.lite.Builtins
     import net.kogics.kojo.xscala.RepeatCommands
     
     object SwedishAPI {
    -  import java.awt.Color
    -
       import net.kogics.kojo.core.Turtle
    -  var builtins: net.kogics.kojo.lite.CoreBuiltins = _ // unstable reference to module
    -
    +  import java.awt.Color
    +  var builtins: net.kogics.kojo.lite.CoreBuiltins = _  //unstable reference to module
    +  
       trait SwedishTurtle {
         def englishTurtle: Turtle
         def sudda() = englishTurtle.clear()
    @@ -43,8 +42,8 @@ object SwedishAPI {
         def hoppaTill(x: Double, y: Double) = englishTurtle.jumpTo(x, y)
         def gåTill(x: Double, y: Double) = englishTurtle.moveTo(x, y)
         def hoppa(steg: Double) = {
    -      englishTurtle.saveStyle() // to preserve pen state
    -      englishTurtle.hop(steg) // hop change state to penDown after hop
    +      englishTurtle.saveStyle() //to preserve pen state
    +      englishTurtle.hop(steg) //hop change state to penDown after hop
           englishTurtle.restoreStyle()
         }
         def hoppa(): Unit = hoppa(25)
    @@ -79,38 +78,37 @@ object SwedishAPI {
         def nästaKostym() = englishTurtle.nextCostume()
       }
       class Padda(override val englishTurtle: Turtle) extends SwedishTurtle {
    -    def this(startX: Double, startY: Double, kostymFilNamn: String) =
    -      this(builtins.TSCanvas.newTurtle(startX, startY, kostymFilNamn))
    +    def this(startX: Double, startY: Double, kostymFilNamn: String) = this(builtins.TSCanvas.newTurtle(startX, startY, kostymFilNamn))
         def this(startX: Double, startY: Double) = this(startX, startY, "/images/turtle32.png")
    -    def this() = this(0, 0)
    +    def this() = this(0,0)
       }
    -  class Padda0(t0: => Turtle) extends SwedishTurtle { // by-name construction as turtle0 is volatile }
    +  class Padda0(t0: => Turtle) extends SwedishTurtle { //by-name construction as turtle0 is volatile }
         override def englishTurtle: Turtle = t0
       }
       object padda extends Padda0(builtins.TSCanvas.turtle0)
       def sudda() = builtins.TSCanvas.clear()
       def suddaUtdata() = builtins.clearOutput()
    -  lazy val blå = builtins.blue
    -  lazy val röd = builtins.red
    -  lazy val gul = builtins.yellow
    -  lazy val grön = builtins.green
    +  lazy val blå = builtins.blue 
    +  lazy val röd = builtins.red 
    +  lazy val gul = builtins.yellow 
    +  lazy val grön = builtins.green 
       lazy val lila = builtins.purple
    -  lazy val rosa = builtins.pink
    -  lazy val brun = builtins.brown
    -  lazy val svart = builtins.black
    +  lazy val rosa = builtins.pink 
    +  lazy val brun = builtins.brown 
    +  lazy val svart = builtins.black 
       lazy val vit = builtins.white
       lazy val genomskinlig = builtins.noColor
       def bakgrund(färg: Color) = builtins.setBackground(färg)
       def bakgrund2(färg1: Color, färg2: Color) = builtins.TSCanvas.setBackgroundV(färg1, färg2)
    -  object KcSwe { // Key codes for Swedish keys
    +  object KcSwe { //Key codes for Swedish keys
         lazy val VK_Å = 197
         lazy val VK_Ä = 196
         lazy val VK_Ö = 214
       }
    -
    -  // loops in Swedish
    +  
    +  //loops in Swedish
       def upprepa(n: Int)(block: => Unit): Unit = {
    -    RepeatCommands.repeat(n) { block }
    +    RepeatCommands.repeat(n){ block }
       }
     
       def räkneslinga(n: Int)(block: Int => Unit): Unit = {
    @@ -118,51 +116,48 @@ object SwedishAPI {
       }
     
       def sålänge(villkor: => Boolean)(block: => Unit): Unit = {
    -    RepeatCommands.repeatWhile(villkor) { block }
    -  }
    -
    -  // simple IO
    -  def indata(ledtext: String = "") = builtins.readln(ledtext)
    +    RepeatCommands.repeatWhile (villkor) { block }
    +  }  
     
    -  // math functions
    +  //simple IO
    +  def indata(ledtext: String = "") =  builtins.readln(ledtext)
    +  
    +  //math functions
       def avrunda(tal: Number, antalDecimaler: Int = 0): Double = {
         val faktor = math.pow(10, antalDecimaler).toDouble
         math.round(tal.doubleValue * faktor).toLong / faktor
       }
       def slumptal(n: Int) = builtins.random(n)
       def slumptalMedDecimaler(n: Int) = builtins.randomDouble(n)
    -
    -  // some type aliases in Swedish
    +  
    +  //some type aliases in Swedish
       type Heltal = Int
       type Decimaltal = Double
       type Sträng = String
    +  
    +  //speedTest
    +  def systemtid = BigDecimal(System.nanoTime) / BigDecimal("1000000000") //sekunder
     
    -  // speedTest
    -  def systemtid = BigDecimal(System.nanoTime) / BigDecimal("1000000000") // sekunder
    -
    -  @annotation.nowarn
    -  def räknaTill(n: BigInt): Unit = {
    +  @annotation.nowarn def räknaTill(n: BigInt): Unit = {
         var c: BigInt = 1
         print("*** Räknar från 1 till ... ")
         val startTid = systemtid
    -    while (c < n) { c = c + 1 } // tar tid om n är stort
    +    while (c < n) { c = c + 1 } //tar tid om n är stort
         val stoppTid = systemtid
         println("" + n + " *** KLAR!")
         val tid = stoppTid - startTid
         print("Det tog ")
         if (tid < 0.1)
    -      println(
    -        (tid * 1000).round(new java.math.MathContext(2)) +
    -          " millisekunder."
    -      )
    +      println((tid * 1000).round(new java.math.MathContext(2)) +
    +        " millisekunder.")
         else println((tid * 10).toLong / 10.0 + " sekunder.")
       }
    -
    +  
     }
     
     object SvInit {
       def init(builtins: CoreBuiltins): Unit = {
    -    // initialize unstable value
    +    //initialize unstable value
         net.kogics.kojo.lite.i18n.SwedishAPI.builtins = builtins
         builtins match {
           case b: Builtins =>
    @@ -172,12 +167,12 @@ object SvInit {
             }
             b.setEditorTabSize(2)
     
    -        // code completion
    +        //code completion
             b.addCodeTemplates(
               "sv",
               codeTemplates
             )
    -        // help texts
    +        //help texts
             b.addHelpContent(
               "sv",
               helpContent
    @@ -186,7 +181,7 @@ object SvInit {
           case _ =>
         }
       }
    -
    +  
       val codeTemplates = Map(
         "fram" -> "fram(${steg})",
         "höger" -> "höger(${vinkel})",
    @@ -351,7 +346,7 @@ räkneslinga(10) {{ i =>
         "sålänge" -> 
    sålänge(villkor) {{ satser }} - upprepar satser så länge villkor är sant.
    Exempel:

    var i = 0
    -sålänge(i{"<"}10) {{ 
    +sålänge(i{ "<" }10) {{ 
           utdata(i)
           i = i + 1
     }}
    @@ -399,4 +394,4 @@ val gubbe = new Padda(100,100,"gubbe.jpg") //ny padda skapas på plats (100, 100
     gubbe.fram(100) 
     

    .toString ) -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/aralik.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/aralik.scala index 5f6a50095..1ded8350e 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/aralik.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/aralik.scala @@ -28,12 +28,11 @@ case class Aralık(ilki: Sayı, sonuncu: Sayı, adım: Sayı = 1) { def yazı() = toString() def herÖgeİçin(komutlar: (Sayı) => Birim) = r.foreach(komutlar) override def toString() = { - val yazı = - if (r.size <= 10) r.mkString("(", ", ", ")") - else { - val (başı, sonu) = (r.take(5), r.drop(r.size - 5)) - başı.mkString("(", ", ", " ...") + sonu.mkString(" ", ", ", ")") - } + val yazı = if (r.size <= 10) r.mkString("(", ", ", ")") + else { + val (başı, sonu) = (r.take(5), r.drop(r.size - 5)) + başı.mkString("(", ", ", " ...") + sonu.mkString(" ", ", ", ")") + } s"Aralık$yazı" } def map[B](f: Sayı => B) = r.map(f) diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/arayuz.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/arayuz.scala index a7a32d3c5..eb0700899 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/arayuz.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/arayuz.scala @@ -18,16 +18,14 @@ package net.kogics.kojo.lite.i18n.tr // translating user interface widgets -import java.awt.{ event => e } -import java.awt.Color -import java.awt.Font -import javax.{ swing => s } -import javax.swing.{ BorderFactory => bf } -import javax.swing.{ SwingConstants => sc } -import javax.swing.border.Border - -import net.kogics.kojo.{ widget => w } +import net.kogics.kojo.{widget => w} import net.kogics.kojo.util.Read +import javax.{swing => s} +import javax.swing.{SwingConstants => sc} +import javax.swing.{BorderFactory => bf} +import javax.swing.border.Border +import java.awt.{Font, Color} +import java.awt.{event => e} object arayuz { @@ -158,8 +156,7 @@ object arayuz { def apply[T](ilkSeçenekler: T*)(implicit okur: Read[T]) = new Salındıraç(ilkSeçenekler: _*)(okur) } - class Kaydıraç(enUfak: Sayı, enİri: Sayı, ilkDeğer: Sayı, boşluk: Sayı) - extends w.Slider(enUfak, enİri, ilkDeğer, boşluk) { + class Kaydıraç(enUfak: Sayı, enİri: Sayı, ilkDeğer: Sayı, boşluk: Sayı) extends w.Slider(enUfak, enİri, ilkDeğer, boşluk) { def değeri = value def artalanıKur(renk: Renk) = setBackground(renk) def önalanıKur(renk: Renk) = setForeground(renk) @@ -173,48 +170,12 @@ object arayuz { object değişmez { // https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingConstants.html - val ( - merkez, - taban, - tavan, - sol, - sağ, - doğu, - batı, - kuzey, - güney, - kuzeydoğu, - kuzeybatı, - güneydoğu, - güneybatı, - yatay, - dikey, - önceki, - sonraki, - önder, - izler - ) = - ( - sc.CENTER, - sc.BOTTOM, - sc.TOP, - sc.LEFT, - sc.RIGHT, - sc.EAST, - sc.WEST, - sc.NORTH, - sc.SOUTH, - sc.NORTH_EAST, - sc.NORTH_WEST, - sc.SOUTH_EAST, - sc.SOUTH_WEST, - sc.HORIZONTAL, - sc.VERTICAL, - sc.PREVIOUS, - sc.NEXT, - sc.LEADING, - sc.TRAILING - ) + val (merkez, taban, tavan, sol, sağ, + doğu, batı, kuzey, güney, kuzeydoğu, kuzeybatı, güneydoğu, güneybatı, + yatay, dikey, önceki, sonraki, önder, izler) = + (sc.CENTER, sc.BOTTOM, sc.TOP, sc.LEFT, sc.RIGHT, + sc.EAST, sc.WEST, sc.NORTH, sc.SOUTH, sc.NORTH_EAST, sc.NORTH_WEST, sc.SOUTH_EAST, sc.SOUTH_WEST, + sc.HORIZONTAL, sc.VERTICAL, sc.PREVIOUS, sc.NEXT, sc.LEADING, sc.TRAILING) } object çerçeveci { diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/belki.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/belki.scala index 3d45bffc9..8fe37473a 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/belki.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/belki.scala @@ -58,3 +58,4 @@ trait OptionMethodsInTurkish { // todo: more to come } } + diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/bolumselislev.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/bolumselislev.scala index dfd449fbe..e039166a5 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/bolumselislev.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/bolumselislev.scala @@ -17,9 +17,9 @@ package net.kogics.kojo.lite.i18n.tr trait PartialFunctionMethodsInTurkish { - type Bölümselİşlev[D, R] = PartialFunction[D, R] + type Bölümselİşlev[D,R] = PartialFunction[D,R] // todo: implicit class doesn't work when f's type uses the alias above - implicit class PartialFunctionMethodsInTurkish[D, R](f: PartialFunction[D, R]) { + implicit class PartialFunctionMethodsInTurkish[D,R](f: PartialFunction[D,R]) { def tanımlıMı(d: D) = f.isDefinedAt(d) } } diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/buan.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/buan.scala index 14c9ac70e..5eb48398a 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/buan.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/buan.scala @@ -16,9 +16,7 @@ */ package net.kogics.kojo.lite.i18n.tr -import java.util.Calendar -import java.util.Date -import java.util.TimeZone +import java.util.{Calendar, Date, TimeZone} trait CalendarAndTimeUtilsInTurkish { type Takvim = Calendar @@ -31,15 +29,15 @@ trait CalendarAndTimeUtilsInTurkish { def saat(buan: Takvim): Sayı = buan.get(Calendar.HOUR_OF_DAY) def dakika(buan: Takvim): Sayı = buan.get(Calendar.MINUTE) def saniye(buan: Takvim): Sayı = buan.get(Calendar.SECOND) - // more to come + //more to come } case class BuAn() { val buan = Takvim.buAn val saniye = Takvim.saniye(buan) val dakika = Takvim.dakika(buan) - val saat = Takvim.saat(buan) + val saat = Takvim.saat(buan) def yazıya = Takvim.tarih(buan).toString - // more to come + //more to come } // from ../../CoreBuiltins.scala @@ -48,7 +46,7 @@ trait CalendarAndTimeUtilsInTurkish { // from ../svInit.scala def buAn2: Uzun = System.nanoTime - def buSaniye2: İriKesir = BigDecimal(System.nanoTime) / BigDecimal("1000000000") // seconds + def buSaniye2: İriKesir = BigDecimal(System.nanoTime) / BigDecimal("1000000000") //seconds @annotation.nowarn def sayıyaKadarSay(n: İriSayı, sessiz: İkil = yanlış): Kesir = { def buSaniye1 = BigDecimal(buSaniye) @@ -58,7 +56,7 @@ trait CalendarAndTimeUtilsInTurkish { } val startTid = buSaniye2 // or buSaniye1 while (c < n) { - c = c + 1 // this is one of the simplest operations :-) + c = c + 1 // this is one of the simplest operations :-) } val stoppTid = buSaniye2 // buSaniye1 val tid = stoppTid - startTid diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/cinidunyasi.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/cinidunyasi.scala index aca5c8fb6..3b5f2c1ca 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/cinidunyasi.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/cinidunyasi.scala @@ -16,9 +16,9 @@ */ package net.kogics.kojo.lite.i18n.tr -import net.kogics.kojo.core.SCanvas // ../../../tiles/package.scala import net.kogics.kojo.tiles +import net.kogics.kojo.core.SCanvas // used in Demo Platformer (Mağara Oyunu in Turkish): // ../../../../../../../../../installer/examples/tiledgame/game_tr.kojo.installed @@ -35,7 +35,7 @@ class ÇiniDünyası(dosya: Yazı)(implicit canvas: SCanvas) { val tw = new tiles.TileWorld(dosya) def çinidenKojoya(xy: ÇiniXY): Nokta = tw.tileToKojo(xy) def kojodanÇiniye(x: Kesir, y: Kesir): ÇiniXY = tw.kojoToTile(x, y) - + def yukarıdaÇiniVarMı(resim: Resim, düzey: Sayı): İkil = tw.hasTileAbove(resim.p, düzey) def soldaÇiniVarMı(resim: Resim, düzey: Sayı): İkil = tw.hasTileAtLeft(resim.p, düzey) def sağdaÇiniVarMı(resim: Resim, düzey: Sayı): İkil = tw.hasTileAtRight(resim.p, düzey) diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/data.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/data.scala index e575111a6..d18724cc2 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/data.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/data.scala @@ -26,313 +26,322 @@ case object Method extends Ne case class Name(tr: String, en: String, ne: Ne) object Data { - def nType(tr: String, en: String) = Name(tr, en, Type) - def nVal(tr: String, en: String) = Name(tr, en, Val) - def nDef(tr: String, en: String) = Name(tr, en, Def) - def nMet(tr: String, en: String) = Name(tr, en, Method) - val data = List( - // type defs, (case) classes - nType("Nesne", "Object"), - nType("Birim", "Unit"), - nType("Her", "Any"), - nType("HerDeğer", "AnyVal"), - nType("HerGönder", "AnyRef"), - nType("Yok", "Null"), - nType("Hiç", "Nothing"), - nType("Renk", "Color"), - nType("Boya", "Paint"), - nType("Hız", "Speed"), - nType("Nokta", "Point"), - nType("Dikdörtgen", "Rectangle"), - nType("Üçgen", "Triangle2D"), - nType("İkil", "Boolean"), - nType("Seçim", "Boolean"), - nType("Lokma", "Byte"), - nType("Kısa", "Short"), - nType("Sayı", "Int"), - nType("Uzun", "Long"), - nType("İriSayı", "BigInt"), - nType("UfakKesir", "Float"), - nType("Kesir", "Double"), - nType("İriKesir", "BigDecimal"), - nType("Harf", "Char"), - nType("Yazı", "String"), - nType("EsnekYazı", "collection.mutable.StringBuilder"), - nType("Belki", "Option"), - nType("Biri", "Some"), - nType("Dizi", "collection.Seq"), - nType("Dizim", "Array"), - nType("EsnekDizim", "collection.mutable.ArrayBuffer"), - nType("Dizin", "List"), - nType("MiskinDizin", "LazyList"), - nType("Yöney", "Vector"), - nType("Küme", "Set"), - nType("Sayılar", "Vector[Sayı]"), - nType("UzunlukBirimi", "UnitLen"), - nType("GeoYol", "java.awt.geom.GeneralPath"), - nType("GeoNokta", "VertexShape"), - nType("Grafik2B", "scala.swing.Graphics2D"), - nType("İmge", "Image"), - nType("Bellekteİmge", "BufferedImage"), - nType("Bellekteİmgeİşlemi", "java.awt.image.BufferedImageOp"), - nType("İşlev1", "Function1"), - nType("İşlev2", "Function2"), - nType("İşlev3", "Function3"), - nType("Bölümselİşlev", "PartialFunction"), - // class defs - nType("Mp3Çalar", "net.kogics.kojo.music.KMp3"), - nType("Aralık", "Range"), - nType("ÇiniDünyası", "net.kogics.kojo.tiles.TileWorld"), - nType("ÇiniXY", "net.kogics.kojo.tiles.TileXY"), - nType("BirSayfaKostüm", "net.kogics.kojo.tiles.SpriteSheet"), - nType("Yöney2B", "Vector2D"), - nType("Resim", "Picture"), - nType("İmge", "Image"), - // defs - nDef("varMı", "isDefined"), - nDef("yokMu", "isEmpty"), - nDef("belirt", "assert"), - nDef("gerekli", "require"), - nDef("yeniMp3Çalar", "newMp3Player"), - nDef("sil", "clear"), - nDef("silVeSakla", "cleari"), - nDef("çizimiSil", "clearStepDrawing"), - nDef("çıktıyıSil", "clearOutput"), - nDef("silVeÇizimBiriminiKur", "clearWithUL"), - // val defs, objects, packages - nVal("yok", "null"), - nVal("doğru", "true"), - nVal("yanlış", "false"), - nVal("yavaş", "slow"), - nVal("orta", "medium"), - nVal("hızlı", "fast"), - nVal("çokHızlı", "superFast"), - nVal("noktaSayısı", "Pixel"), - nVal("santim", "Cm"), - nVal("inç", "Inch"), - nVal("Boş", "collection.immutable.Nil"), - nVal("Hiçbiri", "None"), - nVal("mavi", "blue"), - nVal("kırmızı", "red"), - nVal("sarı", "yellow"), - nVal("yeşil", "green"), - nVal("mor", "purple"), - nVal("pembe", "pink"), - nVal("kahverengi", "brown"), - nVal("siyah", "black"), - nVal("beyaz", "white"), - nVal("renksiz", "noColor"), - nVal("gri", "gray"), - nVal("koyuGri", "darkGray"), - nVal("açıkGri", "lightGray"), - nVal("turuncu", "orange"), - nVal("morumsu", "magenta"), - nVal("camgöbeği", "cyan"), - // cm - nVal("renkler", "ColorMaker"), - // Key Codes - nVal("tuşlar", "Kc"), - nDef("Renk", "Color"), - nDef("artalanıKur", "setBackground"), - nDef("artalanıKurDik", "setBackgroundV"), - nDef("artalanıKurYatay", "setBackgroundH"), - nDef("buAn", "epochTimeMillis"), - nDef("buSaniye", "epochTime"), - nDef("yinele", "repeat"), - nDef("yineleDizinli", "repeati"), - nDef("yineleDoğruysa", "repeatWhile"), - nDef("yineleOlanaKadar", "repeatUntil"), - nDef("yineleKere", "repeatFor"), - nDef("yineleİçin", "repeatFor"), - nDef("yineleİlktenSonra", "repeatFor"), - nDef("satıroku", "readln"), - nDef("satıryaz", "println"), - nDef("yaz", "print"), - nVal("matematik", "math"), - nDef("piSayısı", "Pi"), - nDef("eSayısı", "E"), - nDef("gücü", "pow"), - nDef("kuvveti", "pow"), - nDef("karesi", "pow"), - nDef("karekökü", "sqrt"), - nDef("onlukTabandaLogu", "log10"), - nDef("doğalLogu", "log"), - nDef("logaritması", "log"), - nDef("sinüs", "sin"), - nDef("kosinüs", "cos"), - nDef("tanjant", "tan"), - nDef("sinüsünAçısı", "asin"), - nDef("kosinüsünAçısı", "acos"), - nDef("tanjantınAçısı", "atan"), - nDef("eüssü", "exp"), - nDef("radyana", "toRadians"), - nDef("dereceye", "toDegrees"), - nDef("taban", "floor"), - nDef("tavan", "ceil"), - nDef("yakını", "rint"), - nDef("işareti", "sign"), - nDef("sayıya", "toInt"), - nDef("logTabanlı", "log"), - nDef("rastgele", "random"), - nDef("yuvarla", "round"), - nDef("mutlakDeğer", "abs"), - nDef("yakın", "round"), - nDef("enUfağı", "min"), - nDef("enİrisi", "max"), - nDef("rastgele", "random"), - nDef("rastgeleSayı", "randomInt"), - nDef("rastgeleUzun", "randomLong"), - nDef("rastgeleKesir", "randomDouble"), - nDef("rastgeleÇanEğrisinden", "randomNormalDouble"), - nDef("rastgeleNormalKesir", "randomNormalDouble"), - nDef("rastgeleDoğalKesir", "randomNormalDouble"), - nDef("rastgeleTohumunuKur", "initRandomGenerator"), - nDef("rastgeleİkil", "randomBoolean"), - nDef("rastgeleSeçim", "randomBoolean"), - nDef("rastgeleRenk", "randomColor"), - nDef("rastgeleŞeffafRenk", "randomTransparentColor"), - nDef("rastgeleDiziden", "randomFrom"), - nDef("rastgeleKarıştır", "util.Random.shuffle"), - nDef("evDizini", "homeDir"), - nDef("buDizin", "currentDir"), - nDef("kurulumDizini", "installDir"), - nDef("yazıyüzleri", "availableFontNames"), - nDef("yazıyüzü", "Font"), - nDef("yazıÇerçevesi", "textExtent"), - nDef("kaplumbağa0", "turtle0"), - nDef("yeniKaplumbağa", "newTurtle"), - nDef("buradaDur", ""), - nDef("burdaDur", ""), - nDef("sayıOku", ""), - nDef("kesirOku", ""), - nDef("resimİndir", ""), - nDef("müzikİndir", ""), - nDef("müzikMp3üÇal", ""), - nDef("sesMp3üÇal", ""), - nDef("müzikMp3üÇalDöngülü", ""), - nDef("Mp3ÇalıyorMu", ""), - nDef("Mp3üDurdur", ""), - nDef("Mp3DöngüsünüDurdur", ""), - nDef("müzikMp3üÇalıyorMu", ""), - nDef("müzikÇalıyorMu", ""), - nDef("müzikMp3üKapat", ""), - nDef("müzikMp3DöngüsünüKapat", ""), - nDef("müziğiDurdur", ""), - nDef("müziğiKapat", ""), - nDef("kojoVarsayılanBakışaçısınıKur", ""), - nDef("kojoVarsayılanİkinciBakışaçısınıKur", ""), - nDef("kojoYazılımcıkBakışaçısınıKur", ""), - nDef("kojoÇalışmaSayfalıBakışaçısınıKur", ""), - nDef("kojoÖyküBakışaçısınıKur", ""), - nDef("kojoGeçmişBakışaçısınıKur", ""), - nDef("kojoÇıktılıÖyküBakışaçısınıKur", ""), - nDef("tümEkranÇıktı", ""), - nDef("tümEkranTuval", ""), - nDef("tümEkran", ""), - nDef("tuvalAlanı", "canvasBounds"), - nDef("eni", ""), - nDef("boyu", ""), - nDef("en", ""), - nDef("boy", ""), - nDef("yatayMerkezKonumu", ""), - nDef("dikeyMerkezKonumu", ""), - nDef("ekranTazelemeHızınıKur", ""), - nDef("ekranTazelemeHızınıGöster", ""), - nDef("yaklaş", ""), - nDef("yaklaşXY", ""), - nDef("yaklaşmayıSil", ""), - nDef("yaklaşmayaİzinVerme", ""), - nDef("tuvaliKaydır", ""), - nDef("tuvaliDöndür", ""), - nDef("tuşaBasılıMı", ""), - nDef("tuşaBasınca", ""), - nDef("tuşuBırakınca", ""), - nDef("fareyeTıklıyınca", ""), - nDef("fareyiSürükleyince", ""), - nDef("fareKımıldayınca", ""), - nDef("gridiGöster", ""), - nDef("gridiGizle", ""), - nDef("eksenleriGöster", ""), - nDef("eksenleriGizle", ""), - nDef("açıÖlçeriGöster", ""), - nDef("açıÖlçeriGöster", ""), - nDef("cetveliGöster", ""), - nDef("çizimiKaydet", ""), - nDef("çizimiKaydetBoy", ""), - nDef("çizimiKaydetEn", ""), - nDef("çizimiPulBoyundaKaydet", ""), - nDef("artalandaOynat", ""), - nDef("fareKonumu", ""), - nDef("yorumla", ""), - nDef("yineleSayaçla", ""), - nDef("canlandır", ""), - nDef("durdur", ""), - nDef("canlandırmaBaşlayınca", ""), - nDef("canlandırmaBitince", ""), - nDef("tuvaliEtkinleştir", ""), - nDef("yazılımcıkDüzenleyicisiniEtkinleştir", ""), - nDef("çıktıArtalanınıKur", ""), - nDef("çıktıYazıRenginiKur", ""), - nDef("çıktıYazıYüzüBoyunuKur", ""), - nDef("tuvalBoyutOranınınKur", ""), - nDef("tuvalBoyutlarınıKur", ""), - nDef("süreTut", ""), - nDef("oyunSüresiniGöster", ""), - nDef("sırayaSok", ""), - nDef("döndür", "rot"), - nDef("döndürMerkezli", ""), - nDef("filtre", ""), - nDef("gürültü", ""), - nDef("örgü", ""), - nDef("büyütXY", ""), - nDef("saydamlık", ""), - nDef("ton", ""), - nDef("parlaklık", ""), - nDef("aydınlık", ""), - nDef("yansıtY", ""), - nDef("yansıtX", ""), - nDef("eksenler", ""), - nDef("boyaRengi", ""), - nDef("kalemRengi", ""), - nDef("kalemBoyu", ""), - nDef("çizimÖncesiİşlev", ""), - nDef("çizimSonrasıİşlev", ""), - nDef("çevir", ""), - nDef("yansıt", ""), - nDef("soluk", ""), - nDef("bulanık", ""), - nDef("noktaIşık", ""), - nDef("sahneIşığı", ""), - nDef("götür", ""), - nDef("kaydır", ""), - nDef("büyüt", ""), - nDef("ışıklar", ""), - nDef("birEfekt", ""), - nDef("NoktaIşık", ""), - nDef("SahneIşığı", ""), - nDef("çiz", ""), - nDef("çizVeSakla", ""), - nDef("çizMerkezde", ""), - nDef("çizSahne", ""), - nDef("çizMerkezdeYazı", ""), - nDef("merkezeTaşı", ""), - nDef("sahneKenarındanYansıtma", ""), - nDef("engeldeYansıtma", ""), - nDef("imge", ""), - nDef("imgeNoktası", ""), - nDef("imgeNoktasınıKur", ""), - nDef("arayüz", ""), - nDef("zamanTut", "timeit"), - nDef("DokumaBoya", "TexturePaint"), - nDef("boş", "empty"), - nDef("doldur", "tabulate"), - nDef("sayalım", "from"), - nDef("sayıMı", "isDigit"), - nDef("harfMi", "isLetter"), - nDef("yazıya", "toString"), - ) + def nType(tr: String, en: String) = Name(tr, en, Type) + def nVal(tr: String, en: String) = Name(tr, en, Val) + def nDef(tr: String, en: String) = Name(tr, en, Def) + def nMet(tr: String, en: String) = Name(tr, en, Method) + val data = List( + // type defs, (case) classes + nType("Nesne", "Object"), + nType("Birim", "Unit"), + nType("Her", "Any"), + nType("HerDeğer", "AnyVal"), + nType("HerGönder", "AnyRef"), + nType("Yok", "Null"), + nType("Hiç", "Nothing"), + nType("Renk", "Color"), + nType("Boya", "Paint"), + nType("Hız", "Speed"), + nType("Nokta", "Point"), + nType("Dikdörtgen", "Rectangle"), + nType("Üçgen", "Triangle2D"), + nType("İkil", "Boolean"), + nType("Seçim", "Boolean"), + nType("Lokma", "Byte"), + nType("Kısa", "Short"), + nType("Sayı", "Int"), + nType("Uzun", "Long"), + nType("İriSayı", "BigInt"), + nType("UfakKesir", "Float"), + nType("Kesir", "Double"), + nType("İriKesir", "BigDecimal"), + nType("Harf", "Char"), + nType("Yazı", "String"), + nType("EsnekYazı", "collection.mutable.StringBuilder"), + nType("Belki", "Option"), + nType("Biri", "Some"), + nType("Dizi", "collection.Seq"), + nType("Dizim", "Array"), + nType("EsnekDizim", "collection.mutable.ArrayBuffer"), + nType("Dizin", "List"), + nType("MiskinDizin", "LazyList"), + nType("Yöney", "Vector"), + nType("Küme", "Set"), + nType("Sayılar", "Vector[Sayı]"), + nType("UzunlukBirimi", "UnitLen"), + nType("GeoYol", "java.awt.geom.GeneralPath"), + nType("GeoNokta", "VertexShape"), + nType("Grafik2B", "scala.swing.Graphics2D"), + nType("İmge", "Image"), + nType("Bellekteİmge", "BufferedImage"), + nType("Bellekteİmgeİşlemi", "java.awt.image.BufferedImageOp"), + nType("İşlev1", "Function1"), + nType("İşlev2", "Function2"), + nType("İşlev3", "Function3"), + nType("Bölümselİşlev", "PartialFunction"), + // class defs + nType("Mp3Çalar", "net.kogics.kojo.music.KMp3"), + nType("Aralık", "Range"), + nType("ÇiniDünyası", "net.kogics.kojo.tiles.TileWorld"), + nType("ÇiniXY", "net.kogics.kojo.tiles.TileXY"), + nType("BirSayfaKostüm", "net.kogics.kojo.tiles.SpriteSheet"), + nType("Yöney2B", "Vector2D"), + nType("Resim", "Picture"), + nType("İmge", "Image"), + // defs + nDef("varMı", "isDefined"), + nDef("yokMu", "isEmpty"), + nDef("belirt", "assert"), + nDef("gerekli", "require"), + nDef("yeniMp3Çalar", "newMp3Player"), + nDef("sil", "clear"), + nDef("silVeSakla", "cleari"), + nDef("çizimiSil", "clearStepDrawing"), + nDef("çıktıyıSil", "clearOutput"), + nDef("silVeÇizimBiriminiKur", "clearWithUL"), + // val defs, objects, packages + nVal("yok", "null"), + nVal("doğru", "true"), + nVal("yanlış", "false"), + nVal("yavaş", "slow"), + nVal("orta", "medium"), + nVal("hızlı", "fast"), + nVal("çokHızlı", "superFast"), + nVal("noktaSayısı", "Pixel"), + nVal("santim", "Cm"), + nVal("inç", "Inch"), + nVal("Boş", "collection.immutable.Nil"), + nVal("Hiçbiri", "None"), - /* + nVal("mavi", "blue"), + nVal("kırmızı", "red"), + nVal("sarı", "yellow"), + nVal("yeşil", "green"), + nVal("mor", "purple"), + nVal("pembe", "pink"), + nVal("kahverengi", "brown"), + nVal("siyah", "black"), + nVal("beyaz", "white"), + nVal("renksiz", "noColor"), + nVal("gri", "gray"), + nVal("koyuGri", "darkGray"), + nVal("açıkGri", "lightGray"), + nVal("turuncu", "orange"), + nVal("morumsu", "magenta"), + nVal("camgöbeği", "cyan"), + // cm + nVal("renkler", "ColorMaker"), + // Key Codes + nVal("tuşlar", "Kc"), + + nDef("Renk", "Color"), + nDef("artalanıKur", "setBackground"), + nDef("artalanıKurDik", "setBackgroundV"), + nDef("artalanıKurYatay", "setBackgroundH"), + + nDef("buAn", "epochTimeMillis"), + nDef("buSaniye", "epochTime"), + + nDef("yinele", "repeat"), + nDef("yineleDizinli", "repeati"), + nDef("yineleDoğruysa", "repeatWhile"), + nDef("yineleOlanaKadar", "repeatUntil"), + nDef("yineleKere", "repeatFor"), + nDef("yineleİçin", "repeatFor"), + nDef("yineleİlktenSonra", "repeatFor"), + + nDef("satıroku", "readln"), + nDef("satıryaz", "println"), + nDef("yaz", "print"), + + nVal("matematik", "math"), + nDef("piSayısı", "Pi"), + nDef("eSayısı", "E"), + nDef("gücü", "pow"), + nDef("kuvveti", "pow"), + nDef("karesi", "pow"), + nDef("karekökü", "sqrt"), + nDef("onlukTabandaLogu", "log10"), + nDef("doğalLogu", "log"), + nDef("logaritması", "log"), + nDef("sinüs", "sin"), + nDef("kosinüs", "cos"), + nDef("tanjant", "tan"), + nDef("sinüsünAçısı", "asin"), + nDef("kosinüsünAçısı", "acos"), + nDef("tanjantınAçısı", "atan"), + + nDef("eüssü", "exp"), + nDef("radyana", "toRadians"), + nDef("dereceye", "toDegrees"), + nDef("taban", "floor"), + nDef("tavan", "ceil"), + nDef("yakını", "rint"), + nDef("işareti", "sign"), + nDef("sayıya", "toInt"), + nDef("logTabanlı", "log"), + + nDef("rastgele", "random"), + nDef("yuvarla", "round"), + nDef("mutlakDeğer", "abs"), + nDef("yakın", "round"), + nDef("enUfağı", "min"), + nDef("enİrisi", "max"), + nDef("rastgele", "random"), + nDef("rastgeleSayı", "randomInt"), + nDef("rastgeleUzun", "randomLong"), + nDef("rastgeleKesir", "randomDouble"), + nDef("rastgeleÇanEğrisinden", "randomNormalDouble"), + nDef("rastgeleNormalKesir", "randomNormalDouble"), + nDef("rastgeleDoğalKesir", "randomNormalDouble"), + nDef("rastgeleTohumunuKur", "initRandomGenerator"), + nDef("rastgeleİkil", "randomBoolean"), + nDef("rastgeleSeçim", "randomBoolean"), + nDef("rastgeleRenk", "randomColor"), + nDef("rastgeleŞeffafRenk", "randomTransparentColor"), + nDef("rastgeleDiziden", "randomFrom"), + nDef("rastgeleKarıştır", "util.Random.shuffle"), + + nDef("evDizini", "homeDir"), + nDef("buDizin", "currentDir"), + nDef("kurulumDizini", "installDir"), + nDef("yazıyüzleri", "availableFontNames"), + nDef("yazıyüzü", "Font"), + nDef("yazıÇerçevesi", "textExtent"), + nDef("kaplumbağa0", "turtle0"), + nDef("yeniKaplumbağa", "newTurtle"), + nDef("buradaDur", ""), + nDef("burdaDur", ""), + nDef("sayıOku", ""), + nDef("kesirOku", ""), + nDef("resimİndir", ""), + nDef("müzikİndir", ""), + nDef("müzikMp3üÇal", ""), + nDef("sesMp3üÇal", ""), + nDef("müzikMp3üÇalDöngülü", ""), + nDef("Mp3ÇalıyorMu", ""), + nDef("Mp3üDurdur", ""), + nDef("Mp3DöngüsünüDurdur", ""), + nDef("müzikMp3üÇalıyorMu", ""), + nDef("müzikÇalıyorMu", ""), + nDef("müzikMp3üKapat", ""), + nDef("müzikMp3DöngüsünüKapat", ""), + nDef("müziğiDurdur", ""), + nDef("müziğiKapat", ""), + nDef("kojoVarsayılanBakışaçısınıKur", ""), + nDef("kojoVarsayılanİkinciBakışaçısınıKur", ""), + nDef("kojoYazılımcıkBakışaçısınıKur", ""), + nDef("kojoÇalışmaSayfalıBakışaçısınıKur", ""), + nDef("kojoÖyküBakışaçısınıKur", ""), + nDef("kojoGeçmişBakışaçısınıKur", ""), + nDef("kojoÇıktılıÖyküBakışaçısınıKur", ""), + nDef("tümEkranÇıktı", ""), + nDef("tümEkranTuval", ""), + nDef("tümEkran", ""), + nDef("tuvalAlanı", "canvasBounds"), + nDef("eni", ""), + nDef("boyu", ""), + nDef("en", ""), + nDef("boy", ""), + nDef("yatayMerkezKonumu", ""), + nDef("dikeyMerkezKonumu", ""), + nDef("ekranTazelemeHızınıKur", ""), + nDef("ekranTazelemeHızınıGöster", ""), + nDef("yaklaş", ""), + nDef("yaklaşXY", ""), + nDef("yaklaşmayıSil", ""), + nDef("yaklaşmayaİzinVerme", ""), + nDef("tuvaliKaydır", ""), + nDef("tuvaliDöndür", ""), + nDef("tuşaBasılıMı", ""), + nDef("tuşaBasınca", ""), + nDef("tuşuBırakınca", ""), + nDef("fareyeTıklıyınca", ""), + nDef("fareyiSürükleyince", ""), + nDef("fareKımıldayınca", ""), + nDef("gridiGöster", ""), + nDef("gridiGizle", ""), + nDef("eksenleriGöster", ""), + nDef("eksenleriGizle", ""), + nDef("açıÖlçeriGöster", ""), + nDef("açıÖlçeriGöster", ""), + nDef("cetveliGöster", ""), + nDef("çizimiKaydet", ""), + nDef("çizimiKaydetBoy", ""), + nDef("çizimiKaydetEn", ""), + nDef("çizimiPulBoyundaKaydet", ""), + nDef("artalandaOynat", ""), + nDef("fareKonumu", ""), + nDef("yorumla", ""), + nDef("yineleSayaçla", ""), + nDef("canlandır", ""), + nDef("durdur", ""), + nDef("canlandırmaBaşlayınca", ""), + nDef("canlandırmaBitince", ""), + nDef("tuvaliEtkinleştir", ""), + nDef("yazılımcıkDüzenleyicisiniEtkinleştir", ""), + nDef("çıktıArtalanınıKur", ""), + nDef("çıktıYazıRenginiKur", ""), + nDef("çıktıYazıYüzüBoyunuKur", ""), + nDef("tuvalBoyutOranınınKur", ""), + nDef("tuvalBoyutlarınıKur", ""), + nDef("süreTut", ""), + nDef("oyunSüresiniGöster", ""), + nDef("sırayaSok", ""), + nDef("döndür", "rot"), + nDef("döndürMerkezli", ""), + nDef("filtre", ""), + nDef("gürültü", ""), + nDef("örgü", ""), + nDef("büyütXY", ""), + nDef("saydamlık", ""), + nDef("ton", ""), + nDef("parlaklık", ""), + nDef("aydınlık", ""), + nDef("yansıtY", ""), + nDef("yansıtX", ""), + nDef("eksenler", ""), + nDef("boyaRengi", ""), + nDef("kalemRengi", ""), + nDef("kalemBoyu", ""), + nDef("çizimÖncesiİşlev", ""), + nDef("çizimSonrasıİşlev", ""), + nDef("çevir", ""), + nDef("yansıt", ""), + nDef("soluk", ""), + nDef("bulanık", ""), + nDef("noktaIşık", ""), + nDef("sahneIşığı", ""), + nDef("götür", ""), + nDef("kaydır", ""), + nDef("büyüt", ""), + nDef("ışıklar", ""), + nDef("birEfekt", ""), + nDef("NoktaIşık", ""), + nDef("SahneIşığı", ""), + nDef("çiz", ""), + nDef("çizVeSakla", ""), + nDef("çizMerkezde", ""), + nDef("çizSahne", ""), + nDef("çizMerkezdeYazı", ""), + nDef("merkezeTaşı", ""), + nDef("sahneKenarındanYansıtma", ""), + nDef("engeldeYansıtma", ""), + nDef("imge", ""), + nDef("imgeNoktası", ""), + nDef("imgeNoktasınıKur", ""), + nDef("arayüz", ""), + nDef("zamanTut", "timeit"), + nDef("DokumaBoya", "TexturePaint"), + nDef("boş", "empty"), + nDef("doldur", "tabulate"), + nDef("sayalım", "from"), + nDef("sayıMı", "isDigit"), + nDef("harfMi", "isLetter"), + nDef("yazıya", "toString"), + ) + +/* def dump = { // https://docs.scala-lang.org/overviews/reflection/overview.html import scala.reflect.runtime.{ universe => ru } @@ -357,7 +366,7 @@ object Data { satıryaz(s"${hepsi.size} tane Türkçe ad var:") hepsi.foreach(satıryaz) } - */ +*/ } // Data.dump diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/dict.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/dict.scala index 9bb9732c9..daa2d285d 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/dict.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/dict.scala @@ -51,8 +51,8 @@ object dict { "map" -> "işle", "flatMap" -> "düzİşle", // "ABC".flatMap(_.toLower.toString * 3) "sorted" -> "sıralı", - "sortBy" -> "sırala", // def sortBy[B](f: A => B)(implicit ord: Ordering[B]): C - "sortWith" -> "sırayaSok", // def sortWith(lt: (A, A) => Boolean): C + "sortBy" -> "sırala", // def sortBy[B](f: A => B)(implicit ord: Ordering[B]): C + "sortWith" -> "sırayaSok", // def sortWith(lt: (A, A) => Boolean): C "reduce" -> "indirge", "fold" -> "katla", "foldLeft" -> "soldanKatla", @@ -75,7 +75,7 @@ object dict { "foreach" -> "herbiriİçin", "compareTo" -> "kıyasla", "compareToIgnoreCase" -> "kıyaslaKüçükHarfBüyükHarfAyrımıYapmadan", - "eq" -> "aynıMı", // AnyRef + "eq" -> "aynıMı", // AnyRef "equals" -> "eşitMi", "equalsIgnoreCase" -> "eşitMiKüçükHarfBüyükHarfAyrımıYapmadan", "startsWith" -> "başındaMı", @@ -102,8 +102,8 @@ object dict { "zip" -> "ikile", "zipWithIndex" -> "ikileSırayla", "spin" -> "çevir", - "rgb" -> "kym", // kırmızı yeşil mavi - "rgba" -> "kyms", // saydamlık + "rgb" -> "kym", // kırmızı yeşil mavi + "rgba" -> "kyms", // saydamlık "linearGradient" -> "doğrusalDeğişim", "linearMultipleGradient" -> "doğrusalÇokluDeğişim", "radialGradient" -> "merkezdenDışarıDoğruDeğişim", @@ -209,7 +209,7 @@ object dict { "false" -> "yanlış", "final" -> "son", "finally" -> "sonunda", - "for" -> "için", // yerine içinYinele + "for" -> "için", // yerine içinYinele "forSome" -> "bazı", // eskitilmiş ve dilden çıkarılmış "given" -> "verilen", "if" -> "eğer", @@ -294,9 +294,9 @@ object dict { ) val type2en = Map() - val def2en = Map() - val val2en = Map() - val method2en = Map( + val def2en = Map () + val val2en = Map () + val method2en = Map ( "Yöney.boş" -> "Vector.empty", "Küme.boş" -> "Set.empty", "Dizi.doldur" -> "Seq.tabulate", @@ -333,10 +333,10 @@ object dict { "ay.çerçeveci.çizgiKenar" -> "javax.swing.BorderFactory.createLineBorder", "ay.çerçeveci.boşKenar" -> "javax.swing.BorderFactory.createEmptyBorder", ) - val altkumeler = Map( + val altkumeler = Map ( "ay" -> List("olay", "değişmez", "çerçeveci") ) - val packageName2en = Map( + val packageName2en = Map ( "ay" -> List("java.awt", "javax.swing"), ) // todo: ./cinidunyasi.scala diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/dizi.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/dizi.scala index d0af3c837..e2efb3eaf 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/dizi.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/dizi.scala @@ -27,8 +27,7 @@ trait SeqMethodsInTurkish { def doldur[B](n1: Sayı)(f: Sayı => B) = Seq.tabulate(n1)(f) def doldur[B](n1: Sayı, n2: Sayı)(f: (Sayı, Sayı) => B) = Seq.tabulate(n1, n2)(f) def doldur[B](n1: Sayı, n2: Sayı, n3: Sayı)(f: (Sayı, Sayı, Sayı) => B) = Seq.tabulate(n1, n2, n3)(f) - def doldur[B](n1: Sayı, n2: Sayı, n3: Sayı, n4: Sayı)(f: (Sayı, Sayı, Sayı, Sayı) => B) = - Seq.tabulate(n1, n2, n3, n4)(f) + def doldur[B](n1: Sayı, n2: Sayı, n3: Sayı, n4: Sayı)(f: (Sayı, Sayı, Sayı, Sayı) => B) = Seq.tabulate(n1, n2, n3, n4)(f) def doldur[B](n1: Sayı, n2: Sayı, n3: Sayı, n4: Sayı, n5: Sayı)(f: (Sayı, Sayı, Sayı, Sayı, Sayı) => B) = Seq.tabulate(n1, n2, n3, n4, n5)(f) } @@ -62,7 +61,7 @@ trait SeqMethodsInTurkish { def soldanKatla[T2](z: T2)(işlev: (T2, T) => T2): T2 = d.foldLeft(z)(işlev) def sağdanKatla[T2](z: T2)(işlev: (T, T2) => T2): T2 = d.foldRight(z)(işlev) // https://github.com/scala/scala/blob/v2.12.7/src/library/scala/collection/TraversableOnce.scala#L1 - def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) + def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) def çarp[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.product(num) // foldLeft(num.one)(num.times) def yinelemesiz = d.distinct def yinelemesizİşlevle[T2](işlev: T => T2): Col = d.distinctBy(işlev) @@ -135,7 +134,7 @@ trait SeqMethodsInTurkish { def soldanKatla[T2](z: T2)(işlev: (T2, T) => T2): T2 = d.foldLeft(z)(işlev) def sağdanKatla[T2](z: T2)(işlev: (T, T2) => T2): T2 = d.foldRight(z)(işlev) // https://github.com/scala/scala/blob/v2.12.7/src/library/scala/collection/TraversableOnce.scala#L1 - def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) + def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) def çarp[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.product(num) // foldLeft(num.one)(num.times) def yinelemesiz = d.distinct def yinelemesizİşlevle[T2](işlev: T => T2): Col = d.distinctBy(işlev) diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/dizim.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/dizim.scala index 0e0ac4913..de6e0cdd4 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/dizim.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/dizim.scala @@ -16,9 +16,8 @@ */ package net.kogics.kojo.lite.i18n.tr -import scala.reflect.ClassTag - import collection.mutable.ArrayBuffer +import scala.reflect.ClassTag // todo: this has only the bare essentials for Array and ArrayBuffer. Add more to the interface.. object EsnekDizim { @@ -28,7 +27,7 @@ object EsnekDizim { class EsnekDizim[T](val a: ArrayBuffer[T]) { def apply(yer: Sayı) = a(yer) def sayı = a.size - def ekle(eleman: T) = { a.append(eleman); this } + def ekle(eleman: T) = {a.append(eleman); this} def +=(eleman: T) = ekle(eleman) def çıkar(yer: Sayı) = a.remove(yer) def sil() = a.clear() @@ -38,27 +37,26 @@ class EsnekDizim[T](val a: ArrayBuffer[T]) { } object Dizim { - def boş[T: ClassTag](b1: Sayı) = new Dizim(Array.ofDim[T](b1)) - def boş[T: ClassTag](b1: Sayı, b2: Sayı) = new Dizim(Array.ofDim[T](b1, b2)) - def boş[T: ClassTag](b1: Sayı, b2: Sayı, b3: Sayı) = new Dizim(Array.ofDim[T](b1, b2, b3)) + def boş[T:ClassTag](b1: Sayı) = new Dizim(Array.ofDim[T](b1)) + def boş[T:ClassTag](b1: Sayı, b2: Sayı) = new Dizim(Array.ofDim[T](b1, b2)) + def boş[T:ClassTag](b1: Sayı, b2: Sayı, b3: Sayı) = new Dizim(Array.ofDim[T](b1, b2, b3)) - def doldur[T: ClassTag](b1: Sayı)(e: => T) = new Dizim(Array.fill[T](b1)(e)) - def doldur[T: ClassTag](b1: Sayı, b2: Sayı)(e: => T) = new Dizim(Array.fill[T](b1, b2)(e)) - def doldur[T: ClassTag](b1: Sayı, b2: Sayı, b3: Sayı)(e: => T) = new Dizim(Array.fill[T](b1, b2, b3)(e)) + def doldur[T:ClassTag](b1: Sayı)(e: => T) = new Dizim(Array.fill[T](b1)(e)) + def doldur[T:ClassTag](b1: Sayı, b2: Sayı)(e: => T) = new Dizim(Array.fill[T](b1, b2)(e)) + def doldur[T:ClassTag](b1: Sayı, b2: Sayı, b3: Sayı)(e: => T) = new Dizim(Array.fill[T](b1, b2, b3)(e)) } class Dizim[T](val a: Array[T]) { def diziye = a.toSeq def yazıya = toString override def toString = String.valueOf(a) def apply(b1: Sayı) = a(b1) - @annotation.nowarn - def boyut: Sayı = { // just an exercise -- not really needed + @annotation.nowarn def boyut: Sayı = { // just an exercise -- not really needed var b = 1 var p = a // scala style pointer var recurse = true while (recurse) p(0) match { case x: Array[T] => b += 1; p = x - case _ => recurse = false + case _ => recurse = false } b } @@ -88,7 +86,7 @@ trait ArrayMethodsInTurkish { // Builds a new array by applying a function to all elements of this array. def işle[A](işlev: T => A)(implicit ct: ClassTag[A]): Dizik[A] = d.map(işlev)(ct) def işleYerinde(işlev: (T) => T): Dizik[T] = d.mapInPlace(işlev) - def düzİşle[A: ClassTag](işlev: T => Dizik[A]): Dizik[A] = d.flatMap(işlev) + def düzİşle[A:ClassTag](işlev: T => Dizik[A]): Dizik[A] = d.flatMap(işlev) def sıralı(implicit ord: Ordering[T]): Col = d.sorted(ord) def sırala[A](i: T => A)(implicit ord: Ordering[A]): Col = d.sortBy(i) def sırayaSok(önce: (T, T) => İkil): Col = d.sortWith(önce) @@ -96,7 +94,7 @@ trait ArrayMethodsInTurkish { def soldanKatla[T2](z: T2)(işlev: (T2, T) => T2): T2 = d.foldLeft(z)(işlev) def sağdanKatla[T2](z: T2)(işlev: (T, T2) => T2): T2 = d.foldRight(z)(işlev) // https://github.com/scala/scala/blob/v2.12.7/src/library/scala/collection/TraversableOnce.scala#L1 - def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) + def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) def çarp[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.product(num) // foldLeft(num.one)(num.times) def yinelemesiz = d.distinct def yinelemesizİşlevle[T2](işlev: T => T2): Col = d.distinctBy(işlev) @@ -104,13 +102,13 @@ trait ArrayMethodsInTurkish { def yazıYap(ara: Yazı): Yazı = d.mkString(ara) def yazıYap(başı: Yazı, ara: Yazı, sonu: Yazı): Yazı = d.mkString(başı, ara, sonu) def tersi = d.reverse - def değiştir[S >: T: ClassTag](yeri: Sayı, değeri: S): Dizik[S] = d.updated(yeri, değeri) + def değiştir[S >: T:ClassTag](yeri: Sayı, değeri: S): Dizik[S] = d.updated(yeri, değeri) def değiştirYerinde(yeri: Sayı, değeri: T): Birim = d.update(yeri, değeri) def herbiriİçin[S](işlev: T => S): Birim = d.foreach(işlev) def varMı(deneme: T => İkil): İkil = d.exists(deneme) def hepsiDoğruMu(deneme: T => İkil): İkil = d.forall(deneme) def hepsiİçinDoğruMu(deneme: T => İkil): İkil = d.forall(deneme) - // def içeriyorMu[S >: T](öge: S): İkil = d.contains(öge) + //def içeriyorMu[S >: T](öge: S): İkil = d.contains(öge) def içeriyorMu(öge: T): İkil = d.contains(öge) def içeriyorMuDilim(dilim: Col): İkil = d.containsSlice(dilim) def al(n: Sayı): Col = d.take(n) @@ -119,10 +117,10 @@ trait ArrayMethodsInTurkish { def düşür(n: Sayı): Col = d.drop(n) def düşürDoğruKaldıkça(deneme: T => İkil): Col = d.dropWhile(deneme) def düşürSağdan(n: Sayı): Col = d.dropRight(n) - // def sırası[S >: T](öge: S): Sayı = d.indexOf(öge) - // def sırası[S >: T](öge: S, başlamaNoktası: Sayı): Sayı = d.indexOf(öge, başlamaNoktası) - // def sırasıSondan[S >: T](öge: S): Sayı = d.lastIndexOf(öge) - // def sırasıSondan[S >: T](öge: S, sonNokta: Sayı): Sayı = d.lastIndexOf(öge, sonNokta) + //def sırası[S >: T](öge: S): Sayı = d.indexOf(öge) + //def sırası[S >: T](öge: S, başlamaNoktası: Sayı): Sayı = d.indexOf(öge, başlamaNoktası) + //def sırasıSondan[S >: T](öge: S): Sayı = d.lastIndexOf(öge) + //def sırasıSondan[S >: T](öge: S, sonNokta: Sayı): Sayı = d.lastIndexOf(öge, sonNokta) def sırası(öge: T): Sayı = d.indexOf(öge) def sırası(öge: T, başlamaNoktası: Sayı): Sayı = d.indexOf(öge, başlamaNoktası) def sırasıSondan(öge: T): Sayı = d.lastIndexOf(öge) @@ -151,3 +149,4 @@ trait ArrayMethodsInTurkish { } } + diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/dizin.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/dizin.scala index d80c39b77..aa33bfbfe 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/dizin.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/dizin.scala @@ -21,7 +21,7 @@ trait ListMethodsInTurkish { object Dizin { def apply[A](elems: A*): List[A] = List.from(elems) - def unapplySeq[A](list: List[A]) = List.unapplySeq(list) + def unapplySeq[A](list: List[A]) = List.unapplySeq(list) } // extends AbstractSeq and gets the translations from Seq in dizi.scala. @@ -47,7 +47,7 @@ trait ListMethodsInTurkish { def soldanKatla[T2](z: T2)(işlev: (T2, T) => T2): T2 = d.foldLeft(z)(işlev) def sağdanKatla[T2](z: T2)(işlev: (T, T2) => T2): T2 = d.foldRight(z)(işlev) // https://github.com/scala/scala/blob/v2.12.7/src/library/scala/collection/TraversableOnce.scala#L1 - def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) + def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) def çarp[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.product(num) // foldLeft(num.one)(num.times) def yinelemesiz = d.distinct def yinelemesizİşlevle[T2](işlev: T => T2): Col = d.distinctBy(işlev) diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/eslem.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/eslem.scala index fc01fda90..1cccd37df 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/eslem.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/eslem.scala @@ -16,21 +16,21 @@ */ package net.kogics.kojo.lite.i18n.tr -import collection.mutable.Map +import collection.mutable.{Map} // todo: add more to the interface object Eşlem { - def boş[A, D] = new Eşlem[A, D](Map.empty[A, D]) - def apply[A, D](elems: (A, D)*) = new Eşlem[A, D](Map.from(elems)) - def değişmezden[A, D](m: collection.immutable.Map[A, D]) = new Eşlem[A, D](Map.from(m.iterator)) + def boş[A,D] = new Eşlem[A,D](Map.empty[A,D]) + def apply[A,D](elems: (A,D)*) = new Eşlem[A,D](Map.from(elems)) + def değişmezden[A,D](m: collection.immutable.Map[A,D]) = new Eşlem[A,D](Map.from(m.iterator)) } -case class Eşlem[A, D](val m: Map[A, D]) { +case class Eşlem[A,D](val m: Map[A,D]) { type Pair = (A, D) // todo: duplicated most of the api in Eşlek type Belki[T] = Option[T] def eşli(a: A) = m.contains(a) def eşEkle(ikili: Pair) = m += ikili - def +=(ikili: Pair) = this.eşEkle(ikili) + def +=(ikili: Pair) = this eşEkle ikili def -=(birinci: A) = m -= birinci def herbiriİçin(komutlar: ((A, D)) => Birim) = m.foreach(komutlar) def herÖgeİçin(komutlar: ((A, D)) => Birim) = m.foreach(komutlar) @@ -67,7 +67,7 @@ case class Eşlem[A, D](val m: Map[A, D]) { def soldanKatla[B](z: B)(işlev: (B, Pair) => B): B = m.foldLeft(z)(işlev) def sağdanKatla[B](z: B)(işlev: (Pair, B) => B): B = m.foldRight(z)(işlev) - def topla[T >: Pair](implicit num: scala.math.Numeric[T]) = m.sum(num) + def topla[T >: Pair](implicit num: scala.math.Numeric[T]) = m.sum(num) def çarp[T >: Pair](implicit num: scala.math.Numeric[T]) = m.product(num) def yazıYap: Yazı = m.mkString diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/geo.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/geo.scala index f90b5a6c6..01727ddf6 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/geo.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/geo.scala @@ -19,7 +19,7 @@ package net.kogics.kojo.lite.i18n.tr trait GeoMethodsInTurkish { implicit class RectYöntemleri(d: Dikdörtgen) { def boyu = d.height - def eni = d.width + def eni = d.width // todo: more to come } @@ -44,8 +44,7 @@ trait GeoMethodsInTurkish { def bitir() = gn.endShape() def nokta(x: Kesir, y: Kesir) = gn.vertex(x, y) def ikinciDereceNokta(mx: Kesir, my: Kesir, x2: Kesir, y2: Kesir) = gn.quadraticVertex(mx, my, x2, y2) - def bezierNoktası(mx1: Kesir, my1: Kesir, mx2: Kesir, my2: Kesir, x2: Kesir, y2: Kesir) = - gn.bezierVertex(mx1, my1, mx2, my2, x2, y2) + def bezierNoktası(mx1: Kesir, my1: Kesir, mx2: Kesir, my2: Kesir, x2: Kesir, y2: Kesir) = gn.bezierVertex(mx1, my1, mx2, my2, x2, y2) def eğriNoktası(x: Kesir, y: Kesir) = gn.curveVertex(x, y) def açısalNokta(boyu: Kesir, açısı: Kesir) = gn.vertexRt(boyu, açısı) def açısalEğriNoktası(boyu: Kesir, açısı: Kesir) = gn.curveVertexRt(boyu, açısı) diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/help.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/help.scala index 801e4ba69..470b8f4e6 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/help.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/help.scala @@ -18,7 +18,7 @@ package net.kogics.kojo.lite.i18n.tr object help { val templates = Map( - "englishTurtle" -> "englishTurtle", + "englishTurtle" -> "englishTurtle", "yeniKaplumbağa" -> "yeniKaplumbağa(${x},${y},${kılık})", "a_kalıp" -> "a_kalıp()", "ileri" -> "ileri(${adım})", @@ -87,7 +87,7 @@ object help { ) val content = Map( - "englishTurtle" -> + "englishTurtle" ->
    englishTurtle

    Bu komut sadece İngilizce komutları bilen bir kaplumbağacık verir. Bu kaplumbağanın türü @@ -105,6 +105,7 @@ repeat(4){{

    yeniKaplumbağa komutuna da bir bakıver.
    .toString, + "yeniKaplumbağa" ->
    yeniKaplumbağa(x, y, kılık) - Bu komut x,y noktasında yeni bir kaplumbağa oluşturur ve verilmişse ona bır kılık giydirir. Kılık verilmemişse kaplumbağa olarak çizer. Onun için de adı yeniKaplumbağa! @@ -116,6 +117,7 @@ araba.ilerle(0,0) araba.kuzey()
    Bu örnek bir araba oluşturur, (100, 200) noktasından (0, 0) noktasına hızlıca giderek mavi bir doğru parçası, yani bir çizgi çizer.
    .toString, + "a_kalıp" ->
    komut(g1, g2) - Açıklama ...
    @@ -126,6 +128,7 @@ val x = komut x.metod
    Bu örnek ... açıklama ...
    .toString, + "ileri" ->
    ileri(adımSayısı) - Bu komut kaplumbağaya verilen sayı kadar adım atırarak baktığı doğrultuda ilerletir. Adım sayısı verilmemişse 25 adım atar.
    .toString, "geri" -> "geri(${adımSayısı}) - ileri komutunun tersi", "sol" ->
    @@ -220,6 +223,7 @@ x.metod satıryaz(toplam)
    .toString, + "eksenler" ->
    eksenler -> resim - Verilen resmin yerel eksenlerini çizerek yeni bir resim oluşturur. @@ -242,13 +246,16 @@ x.metod Bu örnekte bir dikdörtgen çiziyor, onu (-100, -50) noktasına taşıyor, 45 derece döndürüyor ve içini maviye boyuyoruz. Bir de bu çizimin kendi eksenlerini yani yerel eksenlerini çiziyoruz. En sondaki eksenleriGöster komutuyla da genel ya da mutlak eksenleri gösteriyoruz.
    .toString, + "eksenleriGöster" ->
    eksenleriGöster - Çizim tuvalinde yatay (X) ve dikey (Y) eksenlerini çizer.
    .toString, + "eksenleriGizle" ->
    eksenleriGizle - Çizim tuvalindeki yatay (X) ve dikey (Y) eksenlerini siler.
    .toString, + ) } diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/kume.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/kume.scala index b44817e03..ebc4a6f88 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/kume.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/kume.scala @@ -39,7 +39,7 @@ trait SetMethodsInTurkish { def soldanKatla[T2](z: T2)(işlev: (T2, T) => T2): T2 = d.foldLeft(z)(işlev) def sağdanKatla[T2](z: T2)(işlev: (T, T2) => T2): T2 = d.foldRight(z)(işlev) // https://github.com/scala/scala/blob/v2.12.7/src/library/scala/collection/TraversableOnce.scala#L1 - def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) + def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) def çarp[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.product(num) // foldLeft(num.one)(num.times) def yazıYap: Yazı = d.mkString def yazıYap(ara: Yazı): Yazı = d.mkString(ara) diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/kuyruk.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/kuyruk.scala index f3f6cfec1..b3c30067c 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/kuyruk.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/kuyruk.scala @@ -16,9 +16,7 @@ */ package net.kogics.kojo.lite.i18n.tr -import collection.mutable.PriorityQueue -import collection.mutable.Queue -import collection.mutable.Stack +import collection.mutable.{Stack, Queue, PriorityQueue} object Yığın { def boş[T] = new Yığın[T]() @@ -83,7 +81,7 @@ trait QueueMethodsInTurkish { def soldanKatla[T2](z: T2)(işlev: (T2, T) => T2): T2 = d.foldLeft(z)(işlev) def sağdanKatla[T2](z: T2)(işlev: (T, T2) => T2): T2 = d.foldRight(z)(işlev) // https://github.com/scala/scala/blob/v2.12.7/src/library/scala/collection/TraversableOnce.scala#L1 - def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) + def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) def çarp[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.product(num) // foldLeft(num.one)(num.times) def yazıYap: Yazı = d.mkString def yazıYap(ara: Yazı): Yazı = d.mkString(ara) @@ -156,7 +154,7 @@ trait QueueMethodsInTurkish { def soldanKatla[T2](z: T2)(işlev: (T2, T) => T2): T2 = d.foldLeft(z)(işlev) def sağdanKatla[T2](z: T2)(işlev: (T, T2) => T2): T2 = d.foldRight(z)(işlev) // https://github.com/scala/scala/blob/v2.12.7/src/library/scala/collection/TraversableOnce.scala#L1 - def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) + def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) def çarp[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.product(num) // foldLeft(num.one)(num.times) def yazıYap: Yazı = d.mkString def yazıYap(ara: Yazı): Yazı = d.mkString(ara) diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/matematik.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/matematik.scala index 3978bc599..50d5d76f3 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/matematik.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/matematik.scala @@ -16,12 +16,12 @@ */ package net.kogics.kojo.lite.i18n.tr -import scala.{ Array => Dizik } import scala.language.implicitConversions - -import net.kogics.kojo.core.{ Point => Nokta } import org.apache.commons.math3.stat.StatUtils import org.apache.commons.math3.util.ArithmeticUtils +import net.kogics.kojo.core.{Point => Nokta} + +import scala.{Array => Dizik} // translating math library trait MathMethodsInTurkish { @@ -78,8 +78,7 @@ trait MathMethodsInTurkish { def enUfakOrtakKat(s1: Uzun, s2: Uzun) = ArithmeticUtils.lcm(s1, s2) def enİriOrtakPayda(s1: Uzun, s2: Uzun) = ArithmeticUtils.gcd(s1, s2) - def uzaklık(x1: Kesir, y1: Kesir, x2: Kesir, y2: Kesir): Kesir = - math.sqrt(math.pow(y2 - y1, 2) + math.pow(x2 - x1, 2)) + def uzaklık(x1: Kesir, y1: Kesir, x2: Kesir, y2: Kesir): Kesir = math.sqrt(math.pow(y2 - y1, 2) + math.pow(x2 - x1, 2)) def uzaklık(n1: Nokta, n2: Nokta): Kesir = uzaklık(n1.x, n1.y, n2.x, n2.y) def açı(x1: Kesir, y1: Kesir, x2: Kesir, y2: Kesir): Kesir = math.atan2(y2 - y1, x2 - x1).toDegrees def açı(n1: Nokta, n2: Nokta): Kesir = açı(n1.x, n1.y, n2.x, n2.y) @@ -87,6 +86,6 @@ trait MathMethodsInTurkish { def ortalama(sayılar: Dizik[Kesir]) = StatUtils.mean(sayılar) def değişim(sayılar: Dizik[Kesir]) = StatUtils.variance(sayılar) def değişim(sayılar: Dizik[Kesir], ortalama: Kesir) = StatUtils.variance(sayılar, ortalama) - + // todo: more to come } diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/miskindizin.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/miskindizin.scala index 73e420b32..4f17991e0 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/miskindizin.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/miskindizin.scala @@ -41,7 +41,7 @@ trait LazyListMethodsInTurkish { def soldanKatla[T2](z: T2)(işlev: (T2, T) => T2): T2 = d.foldLeft(z)(işlev) def sağdanKatla[T2](z: T2)(işlev: (T, T2) => T2): T2 = d.foldRight(z)(işlev) // https://github.com/scala/scala/blob/v2.12.7/src/library/scala/collection/TraversableOnce.scala#L1 - def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) + def topla[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.sum(num) // foldLeft(num.zero)(num.plus) def çarp[T2 >: T](implicit num: scala.math.Numeric[T2]) = d.product(num) // foldLeft(num.one)(num.times) def yinelemesiz = d.distinct def yinelemesizİşlevle[T2](işlev: T => T2): Col = d.distinctBy(işlev) diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/package.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/package.scala index 796f12e12..8da3146fe 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/package.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/package.scala @@ -17,45 +17,30 @@ package net.kogics.kojo.lite.i18n +import net.kogics.kojo.core.{Turtle, UnitLen, Pixel, Cm, Inch, VertexShape, Rectangle} +import java.awt.{Color, Paint} import java.awt.image.BufferedImage -import java.awt.Color -import java.awt.Paint - +import net.kogics.kojo.core.{Speed, Slow, Medium, Fast, SuperFast, Point} import io.github.jdiemke.triangulation.Triangle2D -import net.kogics.kojo.core.Cm -import net.kogics.kojo.core.Fast -import net.kogics.kojo.core.Inch -import net.kogics.kojo.core.Medium -import net.kogics.kojo.core.Pixel -import net.kogics.kojo.core.Point -import net.kogics.kojo.core.Rectangle -import net.kogics.kojo.core.Slow -import net.kogics.kojo.core.Speed -import net.kogics.kojo.core.SuperFast -import net.kogics.kojo.core.Turtle -import net.kogics.kojo.core.UnitLen -import net.kogics.kojo.core.VertexShape -import net.kogics.kojo.lite.Builtins -import net.kogics.kojo.lite.CoreBuiltins +import net.kogics.kojo.lite.{CoreBuiltins, Builtins} package object tr { - var builtins: CoreBuiltins = _ // unstable reference to module + var builtins: CoreBuiltins = _ //unstable reference to module lazy val richBuiltins = builtins.asInstanceOf[Builtins] // some type aliases in Turkish -- Ctrl-t to return type info will also be in turkish type Nesne = Object type Birim = Unit - type Her = Any - type HerDeğer = AnyVal - type HerGönder = AnyRef // Gönderge, gönderme todo... - type Yok = Null - val yok: Yok = null - type Hiç = Nothing + type Her = Any + type HerDeğer = AnyVal + type HerGönder = AnyRef // Gönderge, gönderme todo... + type Yok = Null + type Hiç = Nothing type Boya = Paint type Renk = Color - type Hız = Speed + type Hız = Speed type Nokta = Point type Dikdörtgen = Rectangle type Üçgen = Triangle2D @@ -66,10 +51,10 @@ package object tr { // no type for Bit. But if there were, how about Parçacık? // duplicated from sayi.scala as they are used in other traits - type Lokma = Byte - type Kısa = Short - type Sayı = Int - type Uzun = Long + type Lokma = Byte + type Kısa = Short + type Sayı = Int + type Uzun = Long type İriSayı = BigInt type UfakKesir = Float type Kesir = Double @@ -102,9 +87,9 @@ package object tr { type Bellekteİmge = BufferedImage type Bellekteİmgeİşlemi = java.awt.image.BufferedImageOp - type İşlev1[D, R] = Function1[D, R] - type İşlev2[D1, D2, R] = Function2[D1, D2, R] - type İşlev3[D1, D2, D3, R] = Function3[D1, D2, D3, R] + type İşlev1[D,R] = Function1[D,R] + type İşlev2[D1,D2,R] = Function2[D1,D2,R] + type İşlev3[D1,D2,D3,R] = Function3[D1,D2,D3,R] type Yazı = String @@ -113,9 +98,9 @@ package object tr { def sesMp3üÇal(mp3dosyası: Yazı) = p.playMp3Sound(mp3dosyası) def çal(mp3dosyası: Yazı) = p.playMp3(mp3dosyası) def durdur() = p.stopMp3() - + def önyükle(mp3dosyası: Yazı) = p.preloadMp3(mp3dosyası) - + def döngülüÇal(mp3dosyası: Yazı) = p.playMp3Loop(mp3dosyası) def döngüyüDurdur() = p.stopMp3Loop() } diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/renk.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/renk.scala index 4e5590ea7..2da837fef 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/renk.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/renk.scala @@ -16,10 +16,10 @@ */ package net.kogics.kojo.lite.i18n.tr -import net.kogics.kojo.doodle.{ Color => DColor } +import net.kogics.kojo.doodle.{Color => DColor} trait ColorMethodsInTurkish { - import java.awt.{ Color => AColor } + import java.awt.{Color => AColor} type Renk = AColor implicit class ColorYöntemleri(r: Renk) { @@ -35,8 +35,7 @@ trait ColorMethodsInTurkish { } object Renk { - def apply(kırmızı: Sayı, yeşil: Sayı, mavi: Sayı, saydam: Sayı = 255): Renk = - new AColor(kırmızı, yeşil, mavi, saydam) + def apply(kırmızı: Sayı, yeşil: Sayı, mavi: Sayı, saydam: Sayı = 255): Renk = new AColor(kırmızı, yeşil, mavi, saydam) def apply(rgbHex: Sayı): Renk = new AColor(rgbHex, yanlış) def apply(rgbHex: Sayı, alfaDahilMi: İkil): Renk = new AColor(rgbHex, alfaDahilMi) @@ -47,51 +46,20 @@ trait ColorMethodsInTurkish { DColor.rgba(kırmızı, yeşil, mavi, saydamlık) } def ada(arıRenk: Kesir, doygunluk: Kesir, açıklık: Kesir) = DColor.hsla(arıRenk, doygunluk, açıklık, 1.0) - def adas(arıRenk: Kesir, doygunluk: Kesir, açıklık: Kesir, saydamlık: Kesir) = - DColor.hsla(arıRenk, doygunluk, açıklık, saydamlık) - def doğrusalDeğişim( - x1: Kesir, - y1: Kesir, - renk1: Renk, - x2: Kesir, - y2: Kesir, - renk2: Renk, - dalgalıDevam: İkil = yanlış - ) = { + def adas(arıRenk: Kesir, doygunluk: Kesir, açıklık: Kesir, saydamlık: Kesir) = DColor.hsla(arıRenk, doygunluk, açıklık, saydamlık) + def doğrusalDeğişim(x1: Kesir, y1: Kesir, renk1: Renk, x2: Kesir, y2: Kesir, renk2: Renk, dalgalıDevam: İkil = yanlış) = { DColor.linearGradient(x1, y1, renk1, x2, y2, renk2, dalgalıDevam) } // (x1: Double, y1: Double, x2: Double, y2: Double, distribution: collection.Seq[Double], colors: collection.Seq[AwtColor], cyclic: Boolean = false) - def doğrusalÇokluDeğişim( - x1: Kesir, - y1: Kesir, - x2: Kesir, - y2: Kesir, - dağılım: Dizi[Kesir], - renkler: Dizi[Renk], - dalgalıDevam: İkil = yanlış - ) = { + def doğrusalÇokluDeğişim(x1: Kesir, y1: Kesir, x2: Kesir, y2: Kesir, dağılım: Dizi[Kesir], renkler: Dizi[Renk], dalgalıDevam: İkil = yanlış) = { DColor.linearMultipleGradient(x1, y1, x2, y2, dağılım, renkler, dalgalıDevam) } // (cx: Double, cy: Double, c1: java.awt.Color, radius: Double, c2: java.awt.Color, cyclic: Boolean): - def merkezdenDışarıDoğruDeğişim( - merkezX: Kesir, - merkezY: Kesir, - renk1: Renk, - yarıçap: Kesir, - renk2: Renk, - dalgalıDevam: İkil - ) = { + def merkezdenDışarıDoğruDeğişim(merkezX: Kesir, merkezY: Kesir, renk1: Renk, yarıçap: Kesir, renk2: Renk, dalgalıDevam: İkil) = { DColor.radialGradient(merkezX, merkezY, renk1, yarıçap, renk2, dalgalıDevam) } // (x: Double, y: Double, radius: Double, distribution: collection.Seq[Double], colors: collection.Seq[AwtColor], cyclic: Boolean = false) - def merkezdenDışarıDoğruÇokluDeğişim( - merkezX: Kesir, - merkezY: Kesir, - yarıçap: Kesir, - dağılım: Dizi[Kesir], - renkler: Dizi[Renk], - dalgalıDevam: İkil = yanlış - ) = { + def merkezdenDışarıDoğruÇokluDeğişim(merkezX: Kesir, merkezY: Kesir, yarıçap: Kesir, dağılım: Dizi[Kesir], renkler: Dizi[Renk], dalgalıDevam: İkil = yanlış) = { DColor.radialMultipleGradient(merkezX, merkezY, yarıçap, dağılım, renkler, dalgalıDevam) } diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/resim.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/resim.scala index 39069c44d..00f745044 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/resim.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/resim.scala @@ -18,13 +18,12 @@ package net.kogics.kojo.lite.i18n.tr +import net.kogics.kojo.picture import java.awt.Paint +import net.kogics.kojo.lite.{CoreBuiltins, Builtins} import net.kogics.kojo.core.Turtle import net.kogics.kojo.lite.i18n.TurkishAPI.Kaplumbağa -import net.kogics.kojo.lite.Builtins -import net.kogics.kojo.lite.CoreBuiltins -import net.kogics.kojo.picture // this is to hold names to go to top level of TurkishAPI (and kojo editor) object res { @@ -49,26 +48,22 @@ object res { def eksenler = AxesOnc def boyaRengi(r: Boya) = Fillc(r) def kalemRengi(r: Boya) = Strokec(r) - def kalemBoyu(b: Kesir) = StrokeWidthc(b) // penThickness setPenThickness + def kalemBoyu(b: Kesir) = StrokeWidthc(b) // penThickness setPenThickness def çizimÖncesiİşlev(iv: Resim => Birim) = PreDrawTransformc(iv) def çizimSonrasıİşlev(iv: Resim => Birim) = PostDrawTransformc(iv) def çevir(sayı: Sayı) = Spinc(sayı) def yansıt(sayı: Sayı) = Reflectc(sayı) def soluk(n: Sayı) = Fadec(n) def bulanık(n: Sayı) = Blurc(n) - def noktaIşık(x: Kesir, y: Kesir, yön: Kesir, yükseklik: Kesir, uzaklık: Kesir) = - PointLightc(x, y, yön, yükseklik, uzaklık) - def sahneIşığı(x: Kesir, y: Kesir, yön: Kesir, yükseklik: Kesir, uzaklık: Kesir) = - SpotLightc(x, y, yön, yükseklik, uzaklık) + def noktaIşık(x: Kesir, y: Kesir, yön: Kesir, yükseklik: Kesir, uzaklık: Kesir) = PointLightc(x, y, yön, yükseklik, uzaklık) + def sahneIşığı(x: Kesir, y: Kesir, yön: Kesir, yükseklik: Kesir, uzaklık: Kesir) = SpotLightc(x, y, yön, yükseklik, uzaklık) def ışıklar(ışıklar: com.jhlabs.image.LightFilter.Light*) = Lightsc(ışıklar: _*) def birEfekt(isim: Symbol, özellikler: Tuple2[Symbol, Any]*) = SomeEffectc(isim, özellikler: _*) def filtre(filtre: java.awt.image.BufferedImageOp) = ApplyFilterc(filtre) def gürültü(miktar: Sayı, yoğunluk: Kesir) = Noisec(miktar, yoğunluk) def örgü(xBoyu: Kesir, xAra: Kesir, yBoyu: Kesir, yAra: Kesir) = Weavec(xBoyu, xAra, yBoyu, yAra) - def NoktaIşık(x: Kesir, y: Kesir, yön: Kesir, yükseklik: Kesir, uzaklık: Kesir) = - picture.PointLight(x, y, yön, yükseklik, uzaklık) - def SahneIşığı(x: Kesir, y: Kesir, yön: Kesir, yükseklik: Kesir, uzaklık: Kesir) = - picture.SpotLight(x, y, yön, yükseklik, uzaklık) + def NoktaIşık(x: Kesir, y: Kesir, yön: Kesir, yükseklik: Kesir, uzaklık: Kesir) = picture.PointLight(x, y, yön, yükseklik, uzaklık) + def SahneIşığı(x: Kesir, y: Kesir, yön: Kesir, yükseklik: Kesir, uzaklık: Kesir) = picture.SpotLight(x, y, yön, yükseklik, uzaklık) // ../../../core/Picture.scala def çiz(r: Resim) = Resim.çiz(r) @@ -98,7 +93,7 @@ object res { // ../../../picture/transforms.scala abstract class ComposableTransformer extends Function1[Resim, Resim] { outer => def apply(r: Resim): Resim - def ->(r: Resim) = apply(r) + def -> (r: Resim) = apply(r) def *(digeri: ComposableTransformer) = new ComposableTransformer { def apply(r: Resim): Resim = outer.apply(digeri.apply(r)) } @@ -111,40 +106,22 @@ object res { } } - case class Rotc(angle: Double) extends ComposableTransformer { - def apply(r: Resim) = new Resim(picture.Rot(angle)(r.p)) - } - case class Rotpc(angle: Double, x: Double, y: Double) extends ComposableTransformer { - def apply(r: Resim) = new Resim(picture.Rotp(angle, x, y)(r.p)) - } - case class Scalec(factor: Double) extends ComposableTransformer { - def apply(r: Resim) = new Resim(picture.Scale(factor)(r.p)) - } - case class ScaleXYc(x: Double, y: Double) extends ComposableTransformer { - def apply(r: Resim) = new Resim(picture.ScaleXY(x, y)(r.p)) - } + case class Rotc(angle: Double) extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.Rot(angle)(r.p)) } + case class Rotpc(angle: Double, x: Double, y: Double) extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.Rotp(angle, x, y)(r.p)) } + case class Scalec(factor: Double) extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.Scale(factor)(r.p)) } + case class ScaleXYc(x: Double, y: Double) extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.ScaleXY(x, y)(r.p)) } case class Opacc(f: Double) extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.Opac(f)(r.p)) } case class Huec(f: Double) extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.Hue(f)(r.p)) } case class Satc(f: Double) extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.Sat(f)(r.p)) } case class Britc(f: Double) extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.Brit(f)(r.p)) } - case class Transc(x: Double, y: Double) extends ComposableTransformer { - def apply(r: Resim) = new Resim(picture.Trans(x, y)(r.p)) - } - case class Offsetc(x: Double, y: Double) extends ComposableTransformer { - def apply(r: Resim) = new Resim(picture.Offset(x, y)(r.p)) - } + case class Transc(x: Double, y: Double) extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.Trans(x, y)(r.p)) } + case class Offsetc(x: Double, y: Double) extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.Offset(x, y)(r.p)) } case object FlipYc extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.FlipY(r.p)) } case object FlipXc extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.FlipX(r.p)) } case object AxesOnc extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.AxesOn(r.p)) } - case class Fillc(color: Paint) extends ComposableTransformer { - def apply(r: Resim) = new Resim(picture.Fill(color)(r.p)) - } - case class Strokec(color: Paint) extends ComposableTransformer { - def apply(r: Resim) = new Resim(picture.Stroke(color)(r.p)) - } - case class StrokeWidthc(w: Double) extends ComposableTransformer { - def apply(r: Resim) = new Resim(picture.StrokeWidth(w)(r.p)) - } + case class Fillc(color: Paint) extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.Fill(color)(r.p)) } + case class Strokec(color: Paint) extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.Stroke(color)(r.p)) } + case class StrokeWidthc(w: Double) extends ComposableTransformer { def apply(r: Resim) = new Resim(picture.StrokeWidth(w)(r.p)) } case class PreDrawTransformc(fn: Resim => Birim) extends ComposableTransformer { def apply(r: Resim) = { val f2 = new Function1[richBuiltins.Picture, Unit] { @@ -171,12 +148,10 @@ object res { case class Blurc(n: Int) extends ComposableImageEffect { def apply(r: Resim) = new Resim(picture.Blur(n)(epic(r))) } - case class PointLightc(x: Double, y: Double, direction: Double, elevation: Double, distance: Double) - extends ComposableImageEffect { + case class PointLightc(x: Double, y: Double, direction: Double, elevation: Double, distance: Double) extends ComposableImageEffect { def apply(r: Resim) = new Resim(picture.PointLightEffect(x, y, direction, elevation, distance)(epic(r))) } - case class SpotLightc(x: Double, y: Double, direction: Double, elevation: Double, distance: Double) - extends ComposableImageEffect { + case class SpotLightc(x: Double, y: Double, direction: Double, elevation: Double, distance: Double) extends ComposableImageEffect { def apply(r: Resim) = new Resim(picture.SpotLightEffect(x, y, direction, elevation, distance)(epic(r))) } case class Lightsc(lights: com.jhlabs.image.LightFilter.Light*) extends ComposableImageEffect { @@ -237,9 +212,9 @@ class Resim(val p: richBuiltins.Picture) { def çarptıMı = çarpıştı _ def çarpıştı(başkaResim: Resim): İkil = p.intersects(başkaResim.p) def çarpışmalar(başkaları: Set[Resim]): Set[Resim] = - başkaları.filter { this çarpıştı _ } + başkaları.filter {this çarpıştı _} def çarpışma(başkaları: Seq[Resim]): Option[Resim] = - başkaları.find { this çarpıştı _ } + başkaları.find {this çarpıştı _} def kesişim(başkaResim: Resim): com.vividsolutions.jts.geom.Geometry = p.intersection(başkaResim.p) def içinde(başkaResim: Resim) = p.contains(başkaResim.p) @@ -261,10 +236,10 @@ class Resim(val p: richBuiltins.Picture) { def dönüşüm = p.transform def kalemRenginiKur = p.setPenColor _ def kalemKalınlığınıKur(kalınlık: Sayı) = p.setPenThickness(kalınlık) - def kalemBoyunuKur(kalınlık: Sayı) = p.setPenThickness(kalınlık) + def kalemBoyunuKur(kalınlık: Sayı) = p.setPenThickness(kalınlık) def kalemiKapa() = p.setNoPen() - // def setPenCapJoin(capJoin: (Int, Int)): Unit = setPenCapJoin(capJoin._1, capJoin._2) - // def setPenCapJoin(cap: Int, join: Int): Unit + //def setPenCapJoin(capJoin: (Int, Int)): Unit = setPenCapJoin(capJoin._1, capJoin._2) + //def setPenCapJoin(cap: Int, join: Int): Unit def boyamaRenginiKur(renk: Boya) = p.setFillColor(renk) def saydamlık = p.opacity def saydamlığıKur(s: Kesir) = p.setOpacity(s) @@ -282,7 +257,7 @@ class Resim(val p: richBuiltins.Picture) { // ../../../picture/pics.scala def boşluk(uzunluk: Kesir): Resim = p match { case rd: picture.BasePicList => new Resim(rd.withGap(uzunluk)) - case _ => this + case _ => this } def imge = p.toImage def girdiyiAktar(r: Resim) = p.forwardInputTo(r.p) @@ -324,15 +299,13 @@ object Resim { def yatay(boy: Kesir) = new Resim(richBuiltins.Picture.hline(boy)) def dikey(boy: Kesir) = new Resim(richBuiltins.Picture.vline(boy)) def dikdörtgen(en: Kesir, boy: Kesir) = new Resim(richBuiltins.Picture.rect(boy, en)) // they are swapped! - // ../../../Picture/package.scala + // ../../../Picture/package.scala def satır(r: => Resim, kaçTane: Sayı) = new Resim(picture.row(r.p, kaçTane)) def sütun(r: => Resim, kaçTane: Sayı) = new Resim(picture.col(r.p, kaçTane)) - def yazı(içerik: Her, yazıBoyu: Sayı = 15) = new Resim(richBuiltins.Picture.text(içerik, yazıBoyu)) + def yazı(içerik: Her, yazıBoyu: Sayı=15) = new Resim(richBuiltins.Picture.text(içerik, yazıBoyu)) def yazı(içerik: Her, yazıyüzü: Yazıyüzü) = new Resim(richBuiltins.Picture.text(içerik, yazıyüzü)) def yazı(içerik: Her, yazıyüzü: Yazıyüzü, renk: Renk) = new Resim(richBuiltins.Picture.textu(içerik, yazıyüzü, renk)) - def yazıRenkli(içerik: Her, yazıBoyu: Sayı, renk: Renk) = new Resim( - richBuiltins.Picture.textu(içerik, yazıBoyu, renk) - ) + def yazıRenkli(içerik: Her, yazıBoyu: Sayı, renk: Renk) = new Resim(richBuiltins.Picture.textu(içerik, yazıBoyu, renk)) def imge(dosyaAdı: Yazı) = new Resim(richBuiltins.Picture.image(dosyaAdı)) def imge(dosyaAdı: Yazı, zarf: Resim) = new Resim(richBuiltins.Picture.image(dosyaAdı, zarf.p)) def imge(url: java.net.URL) = new Resim(richBuiltins.Picture.image(url)) @@ -344,7 +317,7 @@ object Resim { // Resim.arayüz(Label("Merhaba")) // Resim.arayüz(Button("Merhaba")(println("Selam!"))) def arayüz(parça: javax.swing.JComponent) = new Resim(richBuiltins.Picture.widget(parça)) - def yatayBoşluk(en: Kesir) = new Resim(richBuiltins.Picture.hgap(en)) + def yatayBoşluk(en: Kesir) = new Resim(richBuiltins.Picture.hgap(en)) def dikeyBoşluk(boy: Kesir) = new Resim(richBuiltins.Picture.vgap(boy)) def yoldan(işlev: GeoYol => Birim) = new Resim(richBuiltins.Picture.fromPath(işlev)) def noktadan(işlev: GeoNokta => Birim) = new Resim(richBuiltins.Picture.fromVertexShape(işlev)) @@ -352,17 +325,14 @@ object Resim { val f = new Function1[Turtle, Unit] { def apply(t: Turtle): Unit = işlev(new Kaplumbağa(t)) } new Resim(richBuiltins.Picture.fromTurtle(f)) } - def tuvalden(en: Kesir, boy: Kesir)(işlev: Grafik2B => Birim) = new Resim( - richBuiltins.Picture.fromCanvas(en, boy)(işlev) - ) - def karalamadan() = - ??? // ../../Builtins.scala ~/src/kojo/git/kojo/src/main/scala/net/kogics/kojo/lite/Builtins.scala + def tuvalden(en: Kesir, boy: Kesir)(işlev: Grafik2B => Birim) = new Resim(richBuiltins.Picture.fromCanvas(en, boy)(işlev)) + def karalamadan() = ??? // ../../Builtins.scala ~/src/kojo/git/kojo/src/main/scala/net/kogics/kojo/lite/Builtins.scala def eksenleriGöster(r: Resim) = richBuiltins.Picture.showAxes(r.p) def eksenleriGöster(resimler: Resim*) = richBuiltins.Picture.showAxes(resimler.map(_.p): _*) def sınırlarıGöster(r: Resim) = richBuiltins.Picture.showBounds(r.p) def sınırlarıGöster(resimler: Resim*) = richBuiltins.Picture.showBounds(resimler.map(_.p): _*) - def tuval = tuvalSınırları // stageBorder + def tuval = tuvalSınırları // stageBorder def tuvalinSınırları = tuvalSınırları def tuvalSınırları = new Resim(richBuiltins.tCanvas.stage) def tuvalinSolu = new Resim(richBuiltins.tCanvas.stageLeft) diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/sayi.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/sayi.scala index ecb36e42d..fcd54da40 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/sayi.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/sayi.scala @@ -21,10 +21,10 @@ trait NumMethodsInTurkish { // We have Byte/Short/Int/Long which all default to Int and BigInt // val n = 1 // Sayma sayıları - type Lokma = Byte - type Kısa = Short - type Sayı = Int - type Uzun = Long + type Lokma = Byte + type Kısa = Short + type Sayı = Int + type Uzun = Long type İriSayı = BigInt // We have Float/Double which default to Double and BigDecimal // val x = 1.0 @@ -36,7 +36,7 @@ trait NumMethodsInTurkish { val İriSayı = BigInt val İriKesir = BigDecimal - type Sayılar = Vector[Sayı] // Used in Conway's game of life code in the tutorial + type Sayılar = Vector[Sayı] // Used in Conway's game of life code in the tutorial object Sayılar { def apply(elemanlar: Sayı*): Sayılar = Vector.from(elemanlar) def unapplySeq(ss: Sayılar) = Vector.unapplySeq(ss) @@ -56,8 +56,8 @@ trait NumMethodsInTurkish { def yazıya = a.toString def kesire = a.toDouble def mutlakDeğer = a.abs - def enİrisi(b: S) = a.max(b) - def enUfağı(b: S) = a.min(b) + def enİrisi(b: S) = a max b + def enUfağı(b: S) = a min b } implicit class BigDecimalMethods(a: İriKesir) { @@ -65,8 +65,8 @@ trait NumMethodsInTurkish { def yazıya = a.toString def kesire = a.toDouble def mutlakDeğer = a.abs - def enİrisi(b: S) = a.max(b) - def enUfağı(b: S) = a.min(b) + def enİrisi(b: S) = a max b + def enUfağı(b: S) = a min b def iriSayıya = a.toBigInt def ölçek = a.scale @@ -80,8 +80,8 @@ trait NumMethodsInTurkish { def yazıya = a.toString def kesire = a.toDouble def mutlakDeğer = a.abs - def enİrisi(b: Sayı) = a.max(b) - def enUfağı(b: Sayı) = a.min(b) + def enİrisi(b: Sayı) = a max b + def enUfağı(b: Sayı) = a min b } implicit class KesirYöntemleri(a: Kesir) { @@ -90,8 +90,8 @@ trait NumMethodsInTurkish { def dereceye = a.toDegrees def radyana = a.toRadians def mutlakDeğer = a.abs - def enİrisi(b: Kesir) = a.max(b) - def enUfağı(b: Kesir) = a.min(b) + def enİrisi(b: Kesir) = a max b + def enUfağı(b: Kesir) = a min b def taban = a.floor def tavan = a.ceil def yakın = a.round diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/yazi.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/yazi.scala index 13b79157f..d815ee7c7 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/yazi.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/yazi.scala @@ -18,7 +18,7 @@ package net.kogics.kojo.lite.i18n.tr trait StringMethodsInTurkish { type Yazı = String - type EsnekYazı = collection.mutable.StringBuilder + type EsnekYazı=collection.mutable.StringBuilder object Yazı { type Harf = Char @@ -57,7 +57,7 @@ trait StringMethodsInTurkish { def soldanKatla[T2](z: T2)(işlev: (T2, Harf) => T2): T2 = y.foldLeft(z)(işlev) def sağdanKatla[T2](z: T2)(işlev: (Harf, T2) => T2): T2 = y.foldRight(z)(işlev) // https://github.com/scala/scala/blob/v2.12.7/src/library/scala/collection/TraversableOnce.scala#L1 - def topla[T2 >: Harf](implicit num: scala.math.Numeric[T2]) = y.sum(num) // foldLeft(num.zero)(num.plus) + def topla[T2 >: Harf](implicit num: scala.math.Numeric[T2]) = y.sum(num) // foldLeft(num.zero)(num.plus) def çarp[T2 >: Harf](implicit num: scala.math.Numeric[T2]) = y.product(num) // foldLeft(num.one)(num.times) def yinelemesiz = y.distinct def yinelemesizİşlevle[T2](işlev: Harf => T2): Yazı = y.distinctBy(işlev) diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/yoney.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/yoney.scala index 96de3f1dc..72b468315 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/yoney.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/yoney.scala @@ -24,7 +24,7 @@ trait VectorMethodsInTurkish { def apply[T](elemanlar: T*) = Vector.from(elemanlar) def unapplySeq[T](yler: Vector[T]) = Vector.unapplySeq(yler) def boş[T] = Vector.empty[T] - def doldur[T: ClassTag](b1: Sayı)(e: => T) = Vector.fill[T](b1)(e) + def doldur[T:ClassTag](b1: Sayı)(e: => T) = Vector.fill[T](b1)(e) } implicit class YöneyYöntemleri[A](y: Yöney[A]) { @@ -47,7 +47,7 @@ trait VectorMethodsInTurkish { def soldanKatla[B](z: B)(işlev: (B, A) => B): B = y.foldLeft(z)(işlev) def sağdanKatla[B](z: B)(işlev: (A, B) => B): B = y.foldRight(z)(işlev) // https://github.com/scala/scala/blob/v2.12.7/src/library/scala/collection/TraversableOnce.scala#L1 - def topla[B >: A](implicit num: scala.math.Numeric[B]) = y.sum(num) // foldLeft(num.zero)(num.plus) + def topla[B >: A](implicit num: scala.math.Numeric[B]) = y.sum(num) // foldLeft(num.zero)(num.plus) def çarp[B >: A](implicit num: scala.math.Numeric[B]) = y.product(num) // foldLeft(num.one)(num.times) def yinelemesiz = y.distinct def yinelemesizİşlevle[B](işlev: A => B): Yöney[A] = y.distinctBy(işlev) diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/yoney2b.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/yoney2b.scala index c6c2ba9f6..1d8fcdf93 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/yoney2b.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/yoney2b.scala @@ -16,8 +16,7 @@ */ package net.kogics.kojo.lite.i18n.tr -import net.kogics.kojo.lite.Builtins -import net.kogics.kojo.lite.CoreBuiltins +import net.kogics.kojo.lite.{Builtins, CoreBuiltins} // ../../util/Vector2D.scala case class Yöney2B(x: Kesir, y: Kesir) { @@ -48,7 +47,7 @@ case class Yöney2B(x: Kesir, y: Kesir) { override def toString = "Yöney2B(%.2f, %.2f)".format(x, y) override def equals(y2: Any) = y2 match { case y3: Yöney2B => v.equals(y3.v) - case _ => yanlış + case _ => yanlış } } object Yöney2B { diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/trInit.scala b/src/main/scala/net/kogics/kojo/lite/i18n/trInit.scala index 33cffe3d1..055f62da6 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/trInit.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/trInit.scala @@ -20,93 +20,74 @@ package net.kogics.kojo.lite.i18n -import java.awt.Color -import java.util.concurrent.Future // todo - -import edu.umd.cs.piccolo.activities.PActivity // todo +import net.kogics.kojo.lite.{CoreBuiltins, Builtins} +import net.kogics.kojo.xscala.RepeatCommands import net.kogics.kojo.core.Turtle +import java.awt.Color +import java.util.concurrent.Future // todo +import edu.umd.cs.piccolo.activities.PActivity // todo import net.kogics.kojo.kmath.KEasing -import net.kogics.kojo.lite.Builtins -import net.kogics.kojo.lite.CoreBuiltins -import net.kogics.kojo.xscala.RepeatCommands // Keep in alphabetical order -object TurkishAPI - extends tr.ArrayMethodsInTurkish - with tr.CalendarAndTimeUtilsInTurkish - with tr.CharMethodsInTurkish - with tr.ColorMethodsInTurkish - with tr.CoreTypeMethodsInTurkish - with tr.FutureMethodsInTurkish - with tr.GeoMethodsInTurkish - with tr.LazyListMethodsInTurkish - with tr.ListMethodsInTurkish - with tr.MapMethodsInTurkish - with tr.MathMethodsInTurkish - with tr.NumMethodsInTurkish - with tr.OptionMethodsInTurkish - with tr.PartialFunctionMethodsInTurkish - with tr.QueueMethodsInTurkish - with tr.RangeMethodsInTurkish - with tr.SeqMethodsInTurkish - with tr.SetMethodsInTurkish - with tr.StringMethodsInTurkish - with tr.arayuz.SwingWidgetMethodsInTurkish - with tr.VectorMethodsInTurkish { - - var builtins: CoreBuiltins = _ // unstable reference to module +object TurkishAPI extends tr.ArrayMethodsInTurkish with tr.CalendarAndTimeUtilsInTurkish with tr.CharMethodsInTurkish with + tr.ColorMethodsInTurkish with tr.CoreTypeMethodsInTurkish with tr.FutureMethodsInTurkish with tr.GeoMethodsInTurkish with + tr.LazyListMethodsInTurkish with tr.ListMethodsInTurkish with tr.MapMethodsInTurkish with + tr.MathMethodsInTurkish with tr.NumMethodsInTurkish with tr.OptionMethodsInTurkish with + tr.PartialFunctionMethodsInTurkish with tr.QueueMethodsInTurkish with tr.RangeMethodsInTurkish with + tr.SeqMethodsInTurkish with tr.SetMethodsInTurkish with tr.StringMethodsInTurkish with + tr.arayuz.SwingWidgetMethodsInTurkish with tr.VectorMethodsInTurkish { + + var builtins: CoreBuiltins = _ //unstable reference to module lazy val richBuiltins = builtins.asInstanceOf[Builtins] import net.kogics.kojo.lite.i18n.tr // todo: better here than at the top scope? // Imports are intransitive (not visibly transitive). So, we "export" the ones that should be on the interface // todo: metaprog on these? - type Nesne = tr.Nesne - type Birim = tr.Birim - type Her = tr.Her - type HerDeğer = tr.HerDeğer - type HerGönder = tr.HerGönder - type Yok = tr.Yok - val yok: Yok = tr.yok - type Hiç = tr.Hiç - type Boya = tr.Boya - type Hız = tr.Hız - type Nokta = tr.Nokta - type Dikdörtgen = tr.Dikdörtgen - type Üçgen = tr.Üçgen - type İkil = tr.İkil - type Seçim = tr.Seçim + type Nesne=tr.Nesne + type Birim=tr.Birim + type Her=tr.Her + type HerDeğer=tr.HerDeğer + type HerGönder=tr.HerGönder + type Yok=tr.Yok + type Hiç=tr.Hiç + type Boya=tr.Boya + type Hız=tr.Hız + type Nokta=tr.Nokta + type Dikdörtgen=tr.Dikdörtgen + type Üçgen=tr.Üçgen + type İkil=tr.İkil + type Seçim=tr.Seçim type KuralDışı = Exception type ÇalışmaSırasıKuralDışı = RuntimeException - type Diz[T] = tr.Diz[T] + type Diz[T]=tr.Diz[T] type Dizi[B] = tr.Dizi[B] type Dizin[A] = tr.Dizin[A] - type Dizim[T] = tr.Dizim[T] - type EsnekDizim[T] = tr.EsnekDizim[T] + type Dizim[T]=tr.Dizim[T] + type EsnekDizim[T]=tr.EsnekDizim[T] val Dizim = tr.Dizim val EsnekDizim = tr.EsnekDizim - type UzunlukBirimi = tr.UzunlukBirimi + type UzunlukBirimi=tr.UzunlukBirimi - type GeoYol = tr.GeoYol - type GeoNokta = tr.GeoNokta - type Grafik2B = tr.Grafik2B + type GeoYol=tr.GeoYol + type GeoNokta=tr.GeoNokta + type Grafik2B=tr.Grafik2B type Aralık = tr.Aralık val Aralık = tr.Aralık type Yığın[T] = tr.Yığın[T] val Yığın = tr.Yığın - type Eşlem[A, D] = tr.Eşlem[A, D] + type Eşlem[A,D] = tr.Eşlem[A,D] val Eşlem = tr.Eşlem // use tuples, case classes or other structure types when more args seem to be needed - type İşlev1[D, R] = tr.İşlev1[D, R] - type İşlev2[D1, D2, R] = tr.İşlev2[D1, D2, R] - type İşlev3[D1, D2, D3, R] = tr.İşlev3[D1, D2, D3, R] + type İşlev1[D,R] = tr.İşlev1[D,R] + type İşlev2[D1,D2,R] = tr.İşlev2[D1,D2,R] + type İşlev3[D1,D2,D3,R] = tr.İşlev3[D1,D2,D3,R] - val (doğru, yanlış, yavaş, orta, hızlı, çokHızlı, noktaSayısı, santim, inç) = - (tr.doğru, tr.yanlış, tr.yavaş, tr.orta, tr.hızlı, tr.çokHızlı, tr.noktaSayısı, tr.santim, tr.inç) + val (yavaş, orta, hızlı, çokHızlı, noktaSayısı, santim, inç) = (tr.yavaş, tr.orta, tr.hızlı, tr.çokHızlı, tr.noktaSayısı, tr.santim, tr.inç) val Nokta = tr.Nokta @@ -123,9 +104,9 @@ object TurkishAPI trait TurkishTurtle { def englishTurtle: Turtle - def sil(): Birim = englishTurtle.clear() // bbx: does this do anything? See sil def below.. - def göster = görünür _ - def gizle = görünmez _ + def sil(): Birim = englishTurtle.clear() // bbx: does this do anything? See sil def below.. + def göster = görünür() + def gizle = görünmez() def görünür() = englishTurtle.visible() def görünmez() = englishTurtle.invisible() def ileri(adım: Kesir) = englishTurtle.forward(adım) @@ -141,8 +122,8 @@ object TurkishAPI def atla(x: Kesir, y: Kesir) = englishTurtle.jumpTo(x, y) def ilerle(x: Kesir, y: Kesir) = englishTurtle.moveTo(x, y) def zıpla(n: Kesir) = { - englishTurtle.saveStyle() // to preserve pen state - englishTurtle.hop(n) // hop change state to penDown after hop + englishTurtle.saveStyle() //to preserve pen state + englishTurtle.hop(n) //hop change state to penDown after hop englishTurtle.restoreStyle() } def zıpla(): Birim = zıpla(25) @@ -199,8 +180,7 @@ object TurkishAPI } class Kaplumbağa(override val englishTurtle: Turtle) extends TurkishTurtle { - def this(startX: Kesir, startY: Kesir, costumeFileName: Yazı) = - this(builtins.TSCanvas.newTurtle(startX, startY, costumeFileName)) + def this(startX: Kesir, startY: Kesir, costumeFileName: Yazı) = this(builtins.TSCanvas.newTurtle(startX, startY, costumeFileName)) def this(startX: Kesir, startY: Kesir) = this(startX, startY, "/images/turtle32.png") def this() = this(0, 0) def uzaklık(öbürü: Kaplumbağa) = englishTurtle.distanceTo(öbürü.englishTurtle) @@ -217,7 +197,7 @@ object TurkishAPI englishTurtle.react(f) } } - class Kaplumbağa0(t0: => Turtle) extends TurkishTurtle { // by-name construction as turtle0 is volatile } + class Kaplumbağa0(t0: => Turtle) extends TurkishTurtle { //by-name construction as turtle0 is volatile } override def englishTurtle: Turtle = t0 } object kaplumbağa extends Kaplumbağa0(builtins.TSCanvas.turtle0) @@ -245,12 +225,12 @@ object TurkishAPI // TODO: other Color* constructors -- and Help Content // ../CoreBuiltins.scala - lazy val renkler = builtins.cm // ColorMaker + lazy val renkler = builtins.cm // ColorMaker lazy val tuşlar = builtins.Kc // Key Codes def artalanıKur(r: Renk) = builtins.setBackground(r) def artalanıKur(b: Boya) = builtins.setBackground(b) - def artalanıKurDik(r1: Renk, r2: Renk) = builtins.TSCanvas.setBackgroundV(r1, r2) + def artalanıKurDik (r1: Renk, r2: Renk) = builtins.TSCanvas.setBackgroundV(r1, r2) def artalanıKurYatay(r1: Renk, r2: Renk) = builtins.TSCanvas.setBackgroundH(r1, r2) // object KcSwe { //Key codes for Swedish keys @@ -259,7 +239,7 @@ object TurkishAPI // lazy val VK_Ö = 214 // } - // loops + //loops def yinele(n: Sayı)(diziKomut: => Birim): Birim = { RepeatCommands.repeat(n) { diziKomut } } @@ -287,9 +267,9 @@ object TurkishAPI RepeatCommands.repeatFor(ilki to sonu) { diziKomut } } - // simple IO + //simple IO def satıroku(istem: Yazı = "") = builtins.readln(istem) - def satıryaz(data: Her) = println(data) // Transferred here from sv.tw.kojo. + def satıryaz(data: Her) = println(data) //Transferred here from sv.tw.kojo. def satıryaz() = println() def yaz(data: Her) = print(data) @@ -312,8 +292,7 @@ object TurkishAPI def rastgeleDiziden[T](dizi: Dizi[T]) = builtins.randomFrom(dizi) def rastgeleDiziden[T](dizi: Dizi[T], ağırlıklar: Dizi[Kesir]) = builtins.randomFrom(dizi, ağırlıklar) // def diziKarıştır[T](xs: Dizi[T]): Dizi[T] = util.Random.shuffle(xs) - def rastgeleKarıştır[T, C](xs: IterableOnce[T])(implicit bf: collection.BuildFrom[xs.type, T, C]): C = - util.Random.shuffle(xs) + def rastgeleKarıştır[T, C](xs: IterableOnce[T])(implicit bf: collection.BuildFrom[xs.type, T, C]): C = util.Random.shuffle(xs) def durakla(saniye: Kesir) = builtins.pause(saniye) @@ -326,8 +305,7 @@ object TurkishAPI def yazıyüzleri = builtins.availableFontNames def yazıyüzü(adı: Yazı, boyu: Sayı): Yazıyüzü = builtins.Font(adı, boyu) def yazıyüzü(adı: Yazı, boyu: Sayı, biçem: Sayı): Yazıyüzü = builtins.Font(adı, biçem, boyu) - def yazıÇerçevesi(yazı: Yazı, yazıBoyu: Sayı, yazıyüzüAdı: Yazı = yok): Dikdörtgen = - builtins.textExtent(yazı, yazıBoyu, yazıyüzüAdı) + def yazıÇerçevesi(yazı: Yazı, yazıBoyu: Sayı, yazıyüzüAdı: Yazı = yok): Dikdörtgen = builtins.textExtent(yazı, yazıBoyu, yazıyüzüAdı) val kaplumbağa0 = kaplumbağa def yeniKaplumbağa(x: Kesir, y: Kesir) = new Kaplumbağa(x, y) @@ -372,7 +350,7 @@ object TurkishAPI def eni = en def boyu = boy def en: Kesir = ta.width - def boy: Kesir = ta.height + def boy:Kesir = ta.height def x: Kesir = ta.x def y: Kesir = ta.y def X = ta.x + ta.width @@ -421,11 +399,11 @@ object TurkishAPI def gridiGizle() = richBuiltins.tCanvas.gridOff() def eksenleriGöster() = richBuiltins.tCanvas.axesOn() def eksenleriGizle() = richBuiltins.tCanvas.axesOff() - def açıÖlçeriGöster(): richBuiltins.Picture = açıÖlçeriGöster(-tuvalAlanı.en / 2, -tuvalAlanı.boy / 2) + def açıÖlçeriGöster():richBuiltins.Picture = açıÖlçeriGöster(-tuvalAlanı.en/2, -tuvalAlanı.boy/2) def açıÖlçeriGöster(x: Kesir, y: Kesir): richBuiltins.Picture = richBuiltins.tCanvas.showProtractor(x, y) def açıÖlçeriGizle() = richBuiltins.tCanvas.hideProtractor() - def cetveliGöster(): richBuiltins.Picture = cetveliGöster(-tuvalAlanı.en / 2, tuvalAlanı.boy / 2) - def cetveliGöster(x: Kesir, y: Kesir): richBuiltins.Picture = richBuiltins.tCanvas.showScale(x, y) + def cetveliGöster():richBuiltins.Picture = cetveliGöster(-tuvalAlanı.en/2, tuvalAlanı.boy/2) + def cetveliGöster(x: Kesir, y: Kesir):richBuiltins.Picture = richBuiltins.tCanvas.showScale(x, y) def çizimiKaydet(dosyaAdı: Yazı) = richBuiltins.tCanvas.exportImage(dosyaAdı) def çizimiKaydet(dosyaAdı: Yazı, en: Sayı, boy: Sayı) = richBuiltins.tCanvas.exportImage(dosyaAdı, en, boy) @@ -434,14 +412,8 @@ object TurkishAPI def çizimiPulBoyundaKaydet(dosyaAdı: Yazı, boy: Sayı) = richBuiltins.tCanvas.exportThumbnail(dosyaAdı, boy) // todo: help doc - def Geçiş( - süreSaniyeOlarak: Kesir, - ilkEvre: Dizi[Kesir], - sonEvre: Dizi[Kesir], - kolaylaştırma: KEasing, - resimci: Dizi[Kesir] => Resim, - bitinceGizle: İkil - ) = { + def Geçiş(süreSaniyeOlarak: Kesir, ilkEvre: Dizi[Kesir], sonEvre: Dizi[Kesir], kolaylaştırma: KEasing, + resimci: Dizi[Kesir] => Resim, bitinceGizle: İkil) = { val resimci2 = new Function1[Dizi[Kesir], richBuiltins.Picture] { def apply(d: Dizi[Kesir]) = resimci(d).p } richBuiltins.Transition(süreSaniyeOlarak, ilkEvre, sonEvre, kolaylaştırma, resimci2, bitinceGizle) } @@ -451,16 +423,14 @@ object TurkishAPI // todo: more to come } def canlandırmaDizisi(canlandırmalar: richBuiltins.Animation*) = richBuiltins.animSeq(canlandırmalar) - def canlandırmaDizisi(canlandırmalar: collection.Seq[richBuiltins.Animation]) = - richBuiltins.animSeq(canlandırmalar.toSeq) + def canlandırmaDizisi(canlandırmalar: collection.Seq[richBuiltins.Animation]) = richBuiltins.animSeq(canlandırmalar.toSeq) def oynat(canlandırma: richBuiltins.Animation) = richBuiltins.run(canlandırma) def artalandaOynat(kod: => Unit) = richBuiltins.runInBackground(kod) def fareKonumu = richBuiltins.mousePosition def yorumla(komutDizisi: Yazı) = richBuiltins.interpret(komutDizisi) def yineleSayaçla(miliSaniye: Uzun)(işlev: => Birim) = richBuiltins.tCanvas.timer(miliSaniye)(işlev) def canlandır(işlev: => Birim) = richBuiltins.tCanvas.animate(işlev) - def canlandırEvreyle[Evre](ilkEvre: Evre)(işlev: Evre => Evre): Future[PActivity] = - richBuiltins.tCanvas.animateWithState(ilkEvre)(işlev) + def canlandırEvreyle[Evre](ilkEvre: Evre)(işlev: Evre => Evre): Future[PActivity] = richBuiltins.tCanvas.animateWithState(ilkEvre)(işlev) def canlandırmayıDurdur(etkinlik: Future[PActivity]) = richBuiltins.tCanvas.stopAnimationActivity(etkinlik) def canlandırYenidenÇizerek[Evre](ilkEvre: Evre, sonrakiEvre: Evre => Evre, işlev: Evre => Resim): Birim = { val işlev2 = new Function1[Evre, richBuiltins.Picture] { def apply(e: Evre) = işlev(e).p } @@ -485,23 +455,9 @@ object TurkishAPI println("Komudun çalışması $delta%.3f saniye sürdü.") } - def oyunSüresiniGöster( - süreSaniyeOlarak: Sayı, - mesaj: Yazı, - renk: Renk = siyah, - yazıBoyu: Sayı = 15, - kx: Kesir = 10, - ky: Kesir = 50 - ) = + def oyunSüresiniGöster(süreSaniyeOlarak: Sayı, mesaj: Yazı, renk: Renk = siyah, yazıBoyu: Sayı = 15, kx: Kesir = 10, ky: Kesir = 50) = richBuiltins.showGameTime(süreSaniyeOlarak, mesaj, renk, yazıBoyu, kx, ky) - def oyunSüresiniGeriyeSayarakGöster( - süreSaniyeOlarak: Sayı, - mesaj: Yazı, - renk: Renk = siyah, - yazıBoyu: Sayı = 15, - kx: Kesir = 10, - ky: Kesir = 50 - ) = richBuiltins.showGameTimeCountdown(süreSaniyeOlarak, mesaj, renk, yazıBoyu, kx, ky) + def oyunSüresiniGeriyeSayarakGöster(süreSaniyeOlarak: Sayı, mesaj: Yazı, renk: Renk = siyah, yazıBoyu: Sayı = 15, kx: Kesir = 10, ky: Kesir = 50) = richBuiltins.showGameTimeCountdown(süreSaniyeOlarak, mesaj, renk, yazıBoyu, kx, ky) def sırayaSok(kaçSaniyeSonra: Kesir)(komut: => Birim) = richBuiltins.schedule(kaçSaniyeSonra)(komut) def sırayaSok(n: Sayı, kaçSaniyeSonra: Kesir)(komut: => Birim) = richBuiltins.scheduleN(n, kaçSaniyeSonra)(komut) @@ -514,50 +470,9 @@ object TurkishAPI val Yöney2B = tr.Yöney2B val Resim = tr.Resim - import tr.{ res => r } - val (döndür, döndürMerkezli, filtre, gürültü, örgü) = - (r.döndür _, r.döndürMerkezli _, r.filtre _, r.gürültü _, r.örgü _) - val ( - büyütXY, - saydamlık, - ton, - parlaklık, - aydınlık, - yansıtY, - yansıtX, - eksenler, - boyaRengi, - kalemRengi, - kalemBoyu, - çizimÖncesiİşlev, - çizimSonrasıİşlev, - çevir, - yansıt, - soluk, - bulanık, - noktaIşık, - sahneIşığı - ) = ( - r.büyütXY _, - r.saydamlık _, - r.ton _, - r.parlaklık _, - r.aydınlık _, - r.yansıtY, - r.yansıtX, - r.eksenler, - r.boyaRengi _, - r.kalemRengi _, - r.kalemBoyu _, - r.çizimÖncesiİşlev _, - r.çizimSonrasıİşlev _, - r.çevir _, - r.yansıt _, - r.soluk _, - r.bulanık _, - r.noktaIşık _, - r.sahneIşığı _ - ) + import tr.{res => r} + val (döndür, döndürMerkezli, filtre, gürültü, örgü) = (r.döndür _, r.döndürMerkezli _, r.filtre _, r.gürültü _, r.örgü _) + val (büyütXY, saydamlık, ton, parlaklık, aydınlık, yansıtY, yansıtX, eksenler, boyaRengi, kalemRengi, kalemBoyu, çizimÖncesiİşlev, çizimSonrasıİşlev, çevir, yansıt, soluk, bulanık, noktaIşık, sahneIşığı) = (r.büyütXY _, r.saydamlık _, r.ton _, r.parlaklık _, r.aydınlık _, r.yansıtY, r.yansıtX, r.eksenler, r.boyaRengi _, r.kalemRengi _, r.kalemBoyu _, r.çizimÖncesiİşlev _, r.çizimSonrasıİşlev _, r.çevir _, r.yansıt _, r.soluk _, r.bulanık _, r.noktaIşık _, r.sahneIşığı _) def götür(n: Nokta) = r.götür(n) def götür(x: Kesir, y: Kesir) = r.götür(x, y) def götür(yy: Yöney2B) = r.götür(yy) @@ -568,16 +483,13 @@ object TurkishAPI def büyüt(xOranı: Kesir, yOranı: Kesir) = r.büyüt(xOranı, yOranı) def ışıklar(ışıklar: com.jhlabs.image.LightFilter.Light*) = r.ışıklar(ışıklar: _*) def birEfekt(isim: Symbol, özellikler: Tuple2[Symbol, Any]*) = r.birEfekt(isim, özellikler: _*) - def NoktaIşık(x: Kesir, y: Kesir, yön: Kesir, yükseklik: Kesir, uzaklık: Kesir) = - r.NoktaIşık(x, y, yön, yükseklik, uzaklık) - def SahneIşığı(x: Kesir, y: Kesir, yön: Kesir, yükseklik: Kesir, uzaklık: Kesir) = - r.SahneIşığı(x, y, yön, yükseklik, uzaklık) + def NoktaIşık(x: Kesir, y: Kesir, yön: Kesir, yükseklik: Kesir, uzaklık: Kesir) = r.NoktaIşık(x, y, yön, yükseklik, uzaklık) + def SahneIşığı(x: Kesir, y: Kesir, yön: Kesir, yükseklik: Kesir, uzaklık: Kesir) = r.SahneIşığı(x, y, yön, yükseklik, uzaklık) def çiz(r2: Resim) = r.çiz(r2) def çiz(rler: Resim*) = r.çiz(rler: _*) def çiz(rler: collection.Seq[Resim]) = r.çiz(rler) def çizVeSakla(resimler: Resim*) = richBuiltins.drawAndHide(resimler.map(_.p): _*) - val (çizMerkezde, çizSahne, çizMerkezdeYazı, merkezeTaşı) = - (r.çizMerkezde _, r.çizSahne _, r.çizMerkezdeYazı _, r.merkezeTaşı _) + val (çizMerkezde, çizSahne, çizMerkezdeYazı, merkezeTaşı) = (r.çizMerkezde _, r.çizSahne _, r.çizMerkezdeYazı _, r.merkezeTaşı _) val (sahneKenarındanYansıtma, engeldenYansıtma) = (r.sahneKenarındanYansıtma _, r.engeldenYansıtma _) def imge(boy: Sayı, en: Sayı) = r.imge(boy, en) @@ -612,7 +524,7 @@ object TurkishAPI object TurkishInit { def init(builtins: CoreBuiltins): Unit = { - // initialize unstable values: + //initialize unstable values: TurkishAPI.builtins = builtins tr.builtins = builtins builtins match { @@ -624,12 +536,12 @@ object TurkishInit { // b.setEditorTabSize(2) - // code completion + //code completion b.addCodeTemplates( "tr", codeTemplates ) - // help texts + //help texts b.addHelpContent( "tr", helpContent @@ -643,3 +555,4 @@ object TurkishInit { val codeTemplates = help.templates val helpContent = help.content } + diff --git a/src/main/scala/net/kogics/kojo/lite/topc/ArithAerobicsHolder.scala b/src/main/scala/net/kogics/kojo/lite/topc/ArithAerobicsHolder.scala index 2fcc8edf5..beb34ae56 100644 --- a/src/main/scala/net/kogics/kojo/lite/topc/ArithAerobicsHolder.scala +++ b/src/main/scala/net/kogics/kojo/lite/topc/ArithAerobicsHolder.scala @@ -1,21 +1,21 @@ package net.kogics.kojo.lite.topc import javax.swing.JPanel - +import net.kogics.kojo.util.Utils import bibliothek.gui.dock.common.event.CFocusListener import bibliothek.gui.dock.common.intern.CDockable import net.kogics.kojo.lite.ArithAerobicsPane -import net.kogics.kojo.util.Utils class ArithAerobicsHolder(ae: ArithAerobicsPane) - extends BaseHolder("AE", Utils.loadString("CTL_ArithAerobicsTopComponent"), ae) { + extends BaseHolder("AE", Utils.loadString("CTL_ArithAerobicsTopComponent"), ae) { this.addFocusListener(new CFocusListener { override def focusGained(dockable: CDockable): Unit = { ae.activated() } - override def focusLost(dockable: CDockable): Unit = {} + override def focusLost(dockable: CDockable): Unit = { + } }) -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/topc/BaseHolder.scala b/src/main/scala/net/kogics/kojo/lite/topc/BaseHolder.scala index 1a249abfb..7ac5315d8 100644 --- a/src/main/scala/net/kogics/kojo/lite/topc/BaseHolder.scala +++ b/src/main/scala/net/kogics/kojo/lite/topc/BaseHolder.scala @@ -1,16 +1,14 @@ package net.kogics.kojo.lite.topc -import java.awt.Color import javax.swing.JComponent - +import bibliothek.gui.dock.common.DefaultSingleCDockable +import java.awt.Color import bibliothek.gui.dock.common.mode.ExtendedMode import bibliothek.gui.dock.common.CLocation -import bibliothek.gui.dock.common.DefaultSingleCDockable -class BaseHolder(id: String, title: String, component: JComponent) - extends DefaultSingleCDockable(id, title, component) { +class BaseHolder(id: String, title: String, component: JComponent) extends DefaultSingleCDockable(id, title, component) { if (component != null) { component.setBackground(Color.white) } setDefaultLocation(ExtendedMode.MINIMIZED, CLocation.base.minimalWest) -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/topc/DrawingCanvasHolder.scala b/src/main/scala/net/kogics/kojo/lite/topc/DrawingCanvasHolder.scala index c8f8492f1..7fabc26de 100644 --- a/src/main/scala/net/kogics/kojo/lite/topc/DrawingCanvasHolder.scala +++ b/src/main/scala/net/kogics/kojo/lite/topc/DrawingCanvasHolder.scala @@ -1,12 +1,12 @@ package net.kogics.kojo.lite.topc import net.kogics.kojo.core.KojoCtx -import net.kogics.kojo.lite.canvas.SpriteCanvas import net.kogics.kojo.lite.Theme +import net.kogics.kojo.lite.canvas.SpriteCanvas import net.kogics.kojo.util.Utils class DrawingCanvasHolder(val dc: SpriteCanvas, ctx: KojoCtx) - extends BaseHolder("DC", Utils.loadString("CTL_SCanvasTopComponent"), dc) { + extends BaseHolder("DC", Utils.loadString("CTL_SCanvasTopComponent"), dc) { dc.setBackground(Theme.currentTheme.canvasBg) def activate(): Unit = { toFront() @@ -17,4 +17,4 @@ class DrawingCanvasHolder(val dc: SpriteCanvas, ctx: KojoCtx) def activateCanvas(): Unit = { dc.activate() } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/topc/HistoryHolder.scala b/src/main/scala/net/kogics/kojo/lite/topc/HistoryHolder.scala index 320ef31b4..f3d058658 100644 --- a/src/main/scala/net/kogics/kojo/lite/topc/HistoryHolder.scala +++ b/src/main/scala/net/kogics/kojo/lite/topc/HistoryHolder.scala @@ -1,24 +1,26 @@ package net.kogics.kojo.lite.topc -import bibliothek.gui.dock.common.event.CDockableStateListener -import bibliothek.gui.dock.common.event.CFocusListener +import bibliothek.gui.dock.common.event.{CDockableStateListener, CFocusListener} import bibliothek.gui.dock.common.intern.CDockable import bibliothek.gui.dock.common.mode.ExtendedMode import net.kogics.kojo.history.HistoryPanel import net.kogics.kojo.util.Utils -class HistoryHolder(val hw: HistoryPanel) extends BaseHolder("HW", Utils.loadString("CTL_HistoryTopComponent"), hw) { +class HistoryHolder(val hw: HistoryPanel) + extends BaseHolder("HW", Utils.loadString("CTL_HistoryTopComponent"), hw) { addFocusListener(new CFocusListener { override def focusGained(dockable: CDockable): Unit = { hw.searchField.requestFocusInWindow() } - override def focusLost(dockable: CDockable): Unit = {} + override def focusLost(dockable: CDockable): Unit = { + } }) addCDockableStateListener(new CDockableStateListener { - def visibilityChanged(cDockable: CDockable): Unit = {} + def visibilityChanged(cDockable: CDockable): Unit = { + } def extendedModeChanged(cDockable: CDockable, extendedMode: ExtendedMode): Unit = { if (extendedMode == ExtendedMode.MINIMIZED) { diff --git a/src/main/scala/net/kogics/kojo/lite/topc/OutputWindowHolder.scala b/src/main/scala/net/kogics/kojo/lite/topc/OutputWindowHolder.scala index 49b85f040..7518754c3 100644 --- a/src/main/scala/net/kogics/kojo/lite/topc/OutputWindowHolder.scala +++ b/src/main/scala/net/kogics/kojo/lite/topc/OutputWindowHolder.scala @@ -4,7 +4,7 @@ import net.kogics.kojo.lite.OutputPane import net.kogics.kojo.util.Utils class OutputWindowHolder(val outputPane: OutputPane) - extends BaseHolder("OW", Utils.loadString("CTL_OutputTopComponent"), outputPane) { + extends BaseHolder("OW", Utils.loadString("CTL_OutputTopComponent"), outputPane) { def scrollToEnd() = outputPane.scrollToEnd() -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/topc/ScriptEditorHolder.scala b/src/main/scala/net/kogics/kojo/lite/topc/ScriptEditorHolder.scala index 3d567a4c2..f3f933c4d 100644 --- a/src/main/scala/net/kogics/kojo/lite/topc/ScriptEditorHolder.scala +++ b/src/main/scala/net/kogics/kojo/lite/topc/ScriptEditorHolder.scala @@ -4,10 +4,10 @@ import net.kogics.kojo.lite.ScriptEditor import net.kogics.kojo.util.Utils class ScriptEditorHolder(val se: ScriptEditor) - extends BaseHolder("SE", Utils.loadString("CTL_CodeEditorTopComponent"), se) { + extends BaseHolder("SE", Utils.loadString("CTL_CodeEditorTopComponent"), se) { val title = getTitleText val scratch = Utils.loadString("S_Scratch") - + setNoFileTitle() def activate(): Unit = { @@ -39,4 +39,4 @@ class ScriptEditorHolder(val se: ScriptEditor) setTitleText(title) } } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/topc/StoryTellerHolder.scala b/src/main/scala/net/kogics/kojo/lite/topc/StoryTellerHolder.scala index a2d1031a3..c84c3ffd2 100644 --- a/src/main/scala/net/kogics/kojo/lite/topc/StoryTellerHolder.scala +++ b/src/main/scala/net/kogics/kojo/lite/topc/StoryTellerHolder.scala @@ -1,10 +1,9 @@ package net.kogics.kojo.lite.topc -import java.awt.Color import javax.swing.JComponent - import bibliothek.gui.dock.common.DefaultSingleCDockable +import java.awt.Color import net.kogics.kojo.util.Utils class StoryTellerHolder(val st: JComponent) - extends BaseHolder("ST", Utils.loadString("CTL_StoryTellerTopComponent"), st) + extends BaseHolder("ST", Utils.loadString("CTL_StoryTellerTopComponent"), st) \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/topc/TraceHolder.scala b/src/main/scala/net/kogics/kojo/lite/topc/TraceHolder.scala index 99e0d01d3..d7413c167 100644 --- a/src/main/scala/net/kogics/kojo/lite/topc/TraceHolder.scala +++ b/src/main/scala/net/kogics/kojo/lite/topc/TraceHolder.scala @@ -15,8 +15,9 @@ package net.kogics.kojo.lite.topc import javax.swing.JPanel - import net.kogics.kojo.util.Utils class TraceHolder(val tracePanel: JPanel) - extends BaseHolder("TR", Utils.loadString("CTL_TraceTopComponent"), tracePanel) {} + extends BaseHolder("TR", Utils.loadString("CTL_TraceTopComponent"), tracePanel) { + +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/trace/MethodEvent.scala b/src/main/scala/net/kogics/kojo/lite/trace/MethodEvent.scala index d026a4d32..60d1a00e8 100644 --- a/src/main/scala/net/kogics/kojo/lite/trace/MethodEvent.scala +++ b/src/main/scala/net/kogics/kojo/lite/trace/MethodEvent.scala @@ -15,14 +15,14 @@ */ package net.kogics.kojo.lite.trace +import com.sun.jdi.LocalVariable +import com.sun.jdi.StackFrame import java.awt.geom.Point2D -import javax.swing.JComponent +import net.kogics.kojo.core.Picture import scala.collection.mutable.ArrayBuffer +import javax.swing.JComponent -import com.sun.jdi.LocalVariable -import com.sun.jdi.StackFrame -import net.kogics.kojo.core.Picture import net.kogics.kojo.lite.Theme class MethodEvent { @@ -64,21 +64,13 @@ class MethodEvent { def entry(level: Int) = { if (rawName.endsWith("_$eq")) -
    {"\u00b7 " * level} ASSIGN { - methodName - } {assignArg}
    .toString +
    { "\u00b7 " * level } ASSIGN { methodName } { assignArg }
    .toString else -
    { - "\u00b7 " * level - } CALL {methodName} { - pargs - }
    .toString +
    { "\u00b7 " * level } CALL { methodName } { pargs }
    .toString } def exit(level: Int) = { -
    {"\u00b7 " * level} RETURN { - methodName - } = {pret}
    .toString +
    { "\u00b7 " * level } RETURN { methodName } = { pret }
    .toString } override def toString() = { @@ -100,7 +92,7 @@ Caller Source Line: $callerLine def setParent(p: Option[MethodEvent]): Unit = { parent = p - parent.foreach { _.addChild(this) } + parent foreach { _.addChild(this) } } private def addChild(c: MethodEvent): Unit = { subcalls = subcalls :+ c } @@ -116,8 +108,7 @@ Caller Source Line: $callerLine case x +: xs => if (!x.uiElems.isEmpty) true - else if (visibleSubCall(x.subcalls)) true - else visibleSubCall(xs) + else if (visibleSubCall(x.subcalls)) true else visibleSubCall(xs) } visibleSubCall(subcalls) } diff --git a/src/main/scala/net/kogics/kojo/lite/trace/TraceListener.scala b/src/main/scala/net/kogics/kojo/lite/trace/TraceListener.scala index f3578cf7f..2a49d141a 100644 --- a/src/main/scala/net/kogics/kojo/lite/trace/TraceListener.scala +++ b/src/main/scala/net/kogics/kojo/lite/trace/TraceListener.scala @@ -1,8 +1,8 @@ package net.kogics.kojo.lite.trace trait TraceListener { - def onStart(): Unit - def onMethodEnter(me: MethodEvent): Unit - def onMethodExit(me: MethodEvent): Unit - def onEnd(): Unit -} + def onStart(): Unit + def onMethodEnter(me: MethodEvent): Unit + def onMethodExit(me: MethodEvent): Unit + def onEnd(): Unit +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/trace/Tracing.scala b/src/main/scala/net/kogics/kojo/lite/trace/Tracing.scala index 1b1dd838e..06b92486b 100644 --- a/src/main/scala/net/kogics/kojo/lite/trace/Tracing.scala +++ b/src/main/scala/net/kogics/kojo/lite/trace/Tracing.scala @@ -17,35 +17,24 @@ package net.kogics.kojo package lite package trace -import java.awt.geom.AffineTransform -import java.awt.geom.Point2D import java.awt.Color import java.awt.Font +import java.awt.geom.AffineTransform +import java.awt.geom.Point2D import java.io.File +import scala.jdk.CollectionConverters._ import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.HashMap -import scala.jdk.CollectionConverters._ import scala.reflect.internal.util.BatchSourceFile import scala.reflect.internal.util.Position -import scala.tools.nsc.reporters.Reporter import scala.tools.nsc.Global import scala.tools.nsc.Settings +import scala.tools.nsc.reporters.Reporter import scala.util.control.Breaks.break import scala.util.control.Breaks.breakable import scala.util.matching.Regex -import com.sun.jdi.connect.LaunchingConnector -import com.sun.jdi.event.BreakpointEvent -import com.sun.jdi.event.ClassPrepareEvent -import com.sun.jdi.event.ExceptionEvent -import com.sun.jdi.event.MethodEntryEvent -import com.sun.jdi.event.MethodExitEvent -import com.sun.jdi.event.ThreadStartEvent -import com.sun.jdi.event.VMDeathEvent -import com.sun.jdi.event.VMDisconnectEvent -import com.sun.jdi.event.VMStartEvent -import com.sun.jdi.request.EventRequest import com.sun.jdi.AbsentInformationException import com.sun.jdi.ArrayReference import com.sun.jdi.Bootstrap @@ -60,6 +49,18 @@ import com.sun.jdi.StringReference import com.sun.jdi.ThreadReference import com.sun.jdi.Value import com.sun.jdi.VirtualMachine +import com.sun.jdi.connect.LaunchingConnector +import com.sun.jdi.event.BreakpointEvent +import com.sun.jdi.event.ClassPrepareEvent +import com.sun.jdi.event.ExceptionEvent +import com.sun.jdi.event.MethodEntryEvent +import com.sun.jdi.event.MethodExitEvent +import com.sun.jdi.event.ThreadStartEvent +import com.sun.jdi.event.VMDeathEvent +import com.sun.jdi.event.VMDisconnectEvent +import com.sun.jdi.event.VMStartEvent +import com.sun.jdi.request.EventRequest + import net.kogics.kojo.core.Picture import net.kogics.kojo.core.RunContext import net.kogics.kojo.core.Turtle @@ -143,8 +144,7 @@ def main(args: Array[String]) { def stop(): Unit = { traceListener.onEnd() if (vmRunning) { - try { currThread.virtualMachine.exit(1) } - catch { case t: Throwable => } + try { currThread.virtualMachine.exit(1) } catch { case t: Throwable => } } } @@ -178,8 +178,7 @@ def main(args: Array[String]) { def launchVM() = { val conns = Bootstrap.virtualMachineManager.allConnectors - val connector = - conns.asScala.find(_.name.equals("com.sun.jdi.RawCommandLineLaunch")).get.asInstanceOf[LaunchingConnector] + val connector = conns.asScala.find(_.name.equals("com.sun.jdi.RawCommandLineLaunch")).get.asInstanceOf[LaunchingConnector] // set connector arguments val connArgs = connector.defaultArguments() @@ -189,13 +188,10 @@ def main(args: Array[String]) { val port = 8001 + builtins.random(1000) - val cmdLine = - if (System.getProperty("os.name").contains("Windows")) - s"""-Xrunjdwp:transport=dt_shmem,address=127.0.0.1:$port,suspend=y -classpath "$tmpdir${File.pathSeparator}${System - .getProperty("java.class.path")}" -client -Xms32m -Xmx768m Wrapper""" - else - s"""-Xrunjdwp:transport=dt_socket,address=127.0.0.1:$port,suspend=y -classpath "$tmpdir${File.pathSeparator}${System - .getProperty("java.class.path")}" -client -Xms32m -Xmx768m Wrapper""" + val cmdLine = if (System.getProperty("os.name").contains("Windows")) + s"""-Xrunjdwp:transport=dt_shmem,address=127.0.0.1:$port,suspend=y -classpath "$tmpdir${File.pathSeparator}${System.getProperty("java.class.path")}" -client -Xms32m -Xmx768m Wrapper""" + else + s"""-Xrunjdwp:transport=dt_socket,address=127.0.0.1:$port,suspend=y -classpath "$tmpdir${File.pathSeparator}${System.getProperty("java.class.path")}" -client -Xms32m -Xmx768m Wrapper""" val javaHome = System.getProperty("java.home") val javaExec = @@ -225,7 +221,7 @@ def main(args: Array[String]) { vm.allThreads.asScala.find(_.name == name).getOrElse(null) def trace(code: String) = { - notSupported.find { code.contains(_) } match { + notSupported find { code.contains(_) } match { case Some(w) => println(s"Tracing is not supported for scripts that use $w") case None => Utils.runAsync { realTrace(code) } } @@ -235,9 +231,7 @@ def main(args: Array[String]) { try { traceListener.onStart() verboseTrace = if (System.getProperty("kojo.trace.verbose") == "true") true else false - traceLevel = - try { System.getProperty("kojo.trace.level", "1").toInt } - catch { case t: Throwable => 1 } + traceLevel = try { System.getProperty("kojo.trace.level", "1").toInt } catch { case t: Throwable => 1 } turtles.clear() pictures.clear() evtReqs = Vector[EventRequest]() @@ -247,7 +241,7 @@ def main(args: Array[String]) { val success = compile(code) if (!success) { - pictureKeywords.find { code.contains(_) } match { + pictureKeywords find { code.contains(_) } match { case Some(_) => val msg = """Picture tracing is only supported for scripts that use - Picture, PictureT, @@ -268,17 +262,7 @@ that is not supported under Tracing. val vm = launchVM() println("Tracing started...") - val excludes = Array( - "java.*", - "javax.*", - "jdk.internal.*", - "sun.*", - "com.sun.*", - "com.apple.*", - "edu.umd.cs.piccolo.*", - "net.kogics.kojo.util.*", - "org.apache.commons.math.*" - ) + val excludes = Array("java.*", "javax.*", "jdk.internal.*", "sun.*", "com.sun.*", "com.apple.*", "edu.umd.cs.piccolo.*", "net.kogics.kojo.util.*", "org.apache.commons.math.*") val evtQueue = vm.eventQueue @@ -419,11 +403,9 @@ that is not supported under Tracing. return "null" } - if ( - frameVal.isInstanceOf[ObjectReference] && + if (frameVal.isInstanceOf[ObjectReference] && !frameVal.isInstanceOf[StringReference] && - !frameVal.isInstanceOf[ArrayReference] - ) { + !frameVal.isInstanceOf[ArrayReference]) { val objRef = frameVal.asInstanceOf[ObjectReference] val mthd = objRef.referenceType.methodsByName("toString").asScala.find(_.argumentTypes.size == 0).get @@ -476,8 +458,8 @@ that is not supported under Tracing. !name.startsWith("box") && !name.startsWith("unbox") && !name.startsWith("wrap"))) && - (callerLineNum > 0 && - callerLineNum <= codeLines.size) + (callerLineNum > 0 && + callerLineNum <= codeLines.size) } def handleMethodEntry(methodEnterEvt: MethodEntryEvent): Unit = { @@ -504,33 +486,21 @@ that is not supported under Tracing. val methodObjectType = if (methodObject != null) methodObject.referenceType.name else "" val methodName = desugar(methodEnterEvt.method.name, methodObjectType) - val srcName = - try { methodEnterEvt.location.sourceName } - catch { case e: Throwable => "N/A" } - val callerSrcName = - try { currThread.frame(1).location.sourceName } - catch { case _: Throwable => "N/A" } + val srcName = try { methodEnterEvt.location.sourceName } catch { case e: Throwable => "N/A" } + val callerSrcName = try { currThread.frame(1).location.sourceName } catch { case _: Throwable => "N/A" } val lOffset = if (srcName == "scripteditor") lineNumOffset else 0 val clOffset = if (callerSrcName == "scripteditor") lineNumOffset else 0 val lineNum = methodEnterEvt.location.lineNumber - lOffset - val callerLineNum = - try { currThread.frame(1).location.lineNumber - clOffset } - catch { case _: Throwable => -1 } - val callerLine = - if (callerSrcName == "scripteditor") - try { codeLines(callerLineNum - 1) } - catch { case _: Throwable => "N/A" } - else - "" - val srcLine = - if (srcName == "scripteditor") - try { codeLines(lineNum - 1) } - catch { case _: Throwable => "N/A" } - else - "" - val localArgs = - try { methodEnterEvt.method.arguments.asScala.toList } - catch { case e: AbsentInformationException => List[LocalVariable]() } + val callerLineNum = try { currThread.frame(1).location.lineNumber - clOffset } catch { case _: Throwable => -1 } + val callerLine = if (callerSrcName == "scripteditor") + try { codeLines(callerLineNum - 1) } catch { case _: Throwable => "N/A" } + else + "" + val srcLine = if (srcName == "scripteditor") + try { codeLines(lineNum - 1) } catch { case _: Throwable => "N/A" } + else + "" + val localArgs = try { methodEnterEvt.method.arguments.asScala.toList } catch { case e: AbsentInformationException => List[LocalVariable]() } val isCommand = methodEnterEvt.method.returnTypeName == "void" def isTurtleCommand = isCommand && methodObjectType.contains("TracingTurtle") @@ -573,11 +543,9 @@ that is not supported under Tracing. // } newEvt.picture = currPicture - if ( - (callerSrcName == "scripteditor" && - (callerLine.contains(methodName) || traceLevelEntry(methodName, callerLineNum))) || - isPictureDraw - ) { + if ((callerSrcName == "scripteditor" && + (callerLine.contains(methodName) || traceLevelEntry(methodName, callerLineNum))) || + isPictureDraw) { newEvt.args = methodArgs(targetToString) newEvt.targetObject = targetToString(methodObject) traceListener.onMethodEnter(newEvt) @@ -597,19 +565,10 @@ that is not supported under Tracing. val methodObjectType = if (methodObject != null) methodObject.referenceType.name else "" val methodName = desugar(methodExitEvt.method.name, methodObjectType) - val localArgs = - try { methodExitEvt.method.arguments.asScala.toList } - catch { case e: AbsentInformationException => List[LocalVariable]() } + val localArgs = try { methodExitEvt.method.arguments.asScala.toList } catch { case e: AbsentInformationException => List[LocalVariable]() } val retVal = methodExitEvt.returnValue - handleMethodReturn( - methodName, - methodExitEvt.method.declaringType.name, - methodExitEvt.method.signature, - stkfrm, - localArgs, - retVal - ) + handleMethodReturn(methodName, methodExitEvt.method.declaringType.name, methodExitEvt.method.signature, stkfrm, localArgs, retVal) val mthdEvent = getCurrentMethodEvent mthdEvent.foreach { ce => @@ -618,11 +577,9 @@ that is not supported under Tracing. val retValStr = localToString(retVal) ce.exitLineNum = lineNum - if ( - ce.callerSourceName == "scripteditor" && + if (ce.callerSourceName == "scripteditor" && (ce.callerLine.contains(methodName) || traceLevelEntry(methodName, ce.callerLineNum)) && - (ce.returnType != "void" || ce.hasVisibleSubcall) - ) { + (ce.returnType != "void" || ce.hasVisibleSubcall)) { ce.returnVal = targetToString(retVal) traceListener.onMethodExit(ce) handleOutputUiEvent(ce, false) @@ -637,14 +594,7 @@ that is not supported under Tracing. var currPicture: Option[Picture] = None - def runPictureMethod( - name: String, - signature: String, - methodObject: ObjectReference, - methodObjectType: String, - stkfrm: StackFrame, - localArgs: List[LocalVariable] - ): Unit = { + def runPictureMethod(name: String, signature: String, methodObject: ObjectReference, methodObjectType: String, stkfrm: StackFrame, localArgs: List[LocalVariable]): Unit = { if (currPicture.isDefined) { return } @@ -661,10 +611,9 @@ that is not supported under Tracing. pictures(caller).rotate(angle) case "scale" if signature.endsWith("CorePicOps;") => val fx = stkfrm.getValue(localArgs(0)).toString.toDouble - val fy = - if (localArgs.length == 2) - stkfrm.getValue(localArgs(1)).toString.toDouble - else fx + val fy = if (localArgs.length == 2) + stkfrm.getValue(localArgs(1)).toString.toDouble + else fx pictures(caller).scale(fx, fy) case m @ _ => // println(s"**TODO** - Unimplemented Picture method - $m") @@ -709,11 +658,7 @@ that is not supported under Tracing. case "gridOff" => TSCanvas.gridOff() case "zoom" => - val (x, y, z) = ( - stkfrm.getValue(localArgs(0)).toString.toDouble, - stkfrm.getValue(localArgs(1)).toString.toDouble, - stkfrm.getValue(localArgs(0)).toString.toDouble - ) + val (x, y, z) = (stkfrm.getValue(localArgs(0)).toString.toDouble, stkfrm.getValue(localArgs(1)).toString.toDouble, stkfrm.getValue(localArgs(0)).toString.toDouble) TSCanvas.zoom(x, y, z) case "setBackgroundH" => val c1 = colorValue(stkfrm.getValue(localArgs(0))) @@ -730,11 +675,10 @@ that is not supported under Tracing. def runTurtleCommand(name: String, stkfrm: StackFrame, localArgs: List[LocalVariable], me: MethodEvent): Unit = { val caller = stkfrm.thisObject.uniqueID - val turtle = - if (currPicture.isDefined) - currPicture.get.asInstanceOf[Pic].t - else - turtles.getOrElse(caller, builtins.TSCanvas.turtle0) + val turtle = if (currPicture.isDefined) + currPicture.get.asInstanceOf[Pic].t + else + turtles.getOrElse(caller, builtins.TSCanvas.turtle0) val createdTurtle = turtles.contains(caller) def traceForward(me2: MethodEvent, step: Double): Unit = { @@ -832,8 +776,7 @@ that is not supported under Tracing. } case "jumpTo" => if (localArgs.length == 2) { - val (x, y) = - (stkfrm.getValue(localArgs(0)).toString.toDouble, stkfrm.getValue(localArgs(1)).toString.toDouble) + val (x, y) = (stkfrm.getValue(localArgs(0)).toString.toDouble, stkfrm.getValue(localArgs(1)).toString.toDouble) turtle.jumpTo(x, y) } case "setCostume" => @@ -853,10 +796,8 @@ that is not supported under Tracing. while (!done) { evtReqs.foreach(_.disable) try { - val headValue = - arg.invokeMethod(currThread, head, new java.util.ArrayList, ObjectReference.INVOKE_SINGLE_THREADED) - val tailValue = - arg.invokeMethod(currThread, tail, new java.util.ArrayList, ObjectReference.INVOKE_SINGLE_THREADED) + val headValue = arg.invokeMethod(currThread, head, new java.util.ArrayList, ObjectReference.INVOKE_SINGLE_THREADED) + val tailValue = arg.invokeMethod(currThread, tail, new java.util.ArrayList, ObjectReference.INVOKE_SINGLE_THREADED) val costume = headValue.asInstanceOf[StringReference].value arg = tailValue.asInstanceOf[ObjectReference] costumes = costumes :+ costume @@ -943,23 +884,12 @@ that is not supported under Tracing. lpics.toList } - def handleMethodReturn( - name: String, - declaringType: String, - signature: String, - stkfrm: StackFrame, - localArgs: List[LocalVariable], - retVal: Value - ): Unit = { + def handleMethodReturn(name: String, declaringType: String, signature: String, stkfrm: StackFrame, localArgs: List[LocalVariable], retVal: Value): Unit = { name match { case "newTurtle" => import builtins.TSCanvas if (localArgs.length == 3) { - val (x, y, costume) = ( - stkfrm.getValue(localArgs(0)).toString.toDouble, - stkfrm.getValue(localArgs(1)).toString.toDouble, - stringValue(stkfrm.getValue(localArgs(2))) - ) + val (x, y, costume) = (stkfrm.getValue(localArgs(0)).toString.toDouble, stkfrm.getValue(localArgs(1)).toString.toDouble, stringValue(stkfrm.getValue(localArgs(2)))) val newTurtle = TSCanvas.newTurtle(x, y, costume) val ref = retVal.asInstanceOf[ObjectReference].uniqueID turtles(ref) = newTurtle @@ -1041,18 +971,15 @@ that is not supported under Tracing. evtReqs.foreach(_.disable) val nameMthd = fontVal.referenceType.methodsByName("getFontName").get(0) - val nameValue = - fontVal.invokeMethod(currThread, nameMthd, new java.util.ArrayList, ObjectReference.INVOKE_SINGLE_THREADED) + val nameValue = fontVal.invokeMethod(currThread, nameMthd, new java.util.ArrayList, ObjectReference.INVOKE_SINGLE_THREADED) val name = nameValue.asInstanceOf[StringReference].value val styleMthd = fontVal.referenceType.methodsByName("getStyle").get(0) - val styleValue = - fontVal.invokeMethod(currThread, styleMthd, new java.util.ArrayList, ObjectReference.INVOKE_SINGLE_THREADED) + val styleValue = fontVal.invokeMethod(currThread, styleMthd, new java.util.ArrayList, ObjectReference.INVOKE_SINGLE_THREADED) val style = styleValue.asInstanceOf[IntegerValue].value val sizeMthd = fontVal.referenceType.methodsByName("getSize").get(0) - val sizeValue = - fontVal.invokeMethod(currThread, sizeMthd, new java.util.ArrayList, ObjectReference.INVOKE_SINGLE_THREADED) + val sizeValue = fontVal.invokeMethod(currThread, sizeMthd, new java.util.ArrayList, ObjectReference.INVOKE_SINGLE_THREADED) val size = sizeValue.asInstanceOf[IntegerValue].value evtReqs.foreach(_.enable) @@ -1064,12 +991,11 @@ that is not supported under Tracing. val str = targetToString(colorVal) val pattern = new Regex("\\d{1,3}") var rgb = Vector[Int]() - pattern.findAllIn(str).foreach(c => rgb = rgb :+ c.toInt) + (pattern findAllIn str).foreach(c => rgb = rgb :+ c.toInt) evtReqs.foreach(_.disable) val alphaMthd = colorVal.referenceType.methodsByName("getAlpha").get(0) - val alphaValue = - colorVal.invokeMethod(currThread, alphaMthd, new java.util.ArrayList, ObjectReference.INVOKE_SINGLE_THREADED) + val alphaValue = colorVal.invokeMethod(currThread, alphaMthd, new java.util.ArrayList, ObjectReference.INVOKE_SINGLE_THREADED) val alpha = alphaValue.asInstanceOf[IntegerValue].value evtReqs.foreach(_.enable) @@ -1085,7 +1011,7 @@ that is not supported under Tracing. val thrdStartVal = evtReqMgr.createThreadStartRequest thrdStartVal.setSuspendPolicy(EventRequest.SUSPEND_ALL) - // thrdStartVal.addThreadFilter(mainThread) + //thrdStartVal.addThreadFilter(mainThread) thrdStartVal.enable() evtReqs = evtReqs :+ thrdStartVal } @@ -1133,4 +1059,4 @@ that is not supported under Tracing. request.setSuspendPolicy(EventRequest.SUSPEND_ALL) request.enable() } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/trace/TracingBuiltins.scala b/src/main/scala/net/kogics/kojo/lite/trace/TracingBuiltins.scala index 2408117bf..9ef42f843 100644 --- a/src/main/scala/net/kogics/kojo/lite/trace/TracingBuiltins.scala +++ b/src/main/scala/net/kogics/kojo/lite/trace/TracingBuiltins.scala @@ -6,15 +6,16 @@ import java.awt.Paint import scala.tools.nsc.interpreter.IMain -import edu.umd.cs.piccolo.activities.PActivity -import edu.umd.cs.piccolo.PCamera -import edu.umd.cs.piccolo.PLayer import net.kogics.kojo.core.SCanvas import net.kogics.kojo.lite.CoreBuiltins import net.kogics.kojo.lite.NoOpSCanvas import net.kogics.kojo.util.Utils import net.kogics.kojo.xscala.RepeatCommands +import edu.umd.cs.piccolo.PCamera +import edu.umd.cs.piccolo.PLayer +import edu.umd.cs.piccolo.activities.PActivity + object TracingBuiltins extends CoreBuiltins with RepeatCommands { val TSCanvas = new TracingTSCanvas @@ -63,7 +64,8 @@ object TracingBuiltins extends CoreBuiltins with RepeatCommands { def setOutputTextColor(color: Color) = {} def setOutputTextFontSize(size: Int) = {} - def playMp3Loop(mp3File: String): Unit = {} + def playMp3Loop(mp3File: String): Unit = { + } def setBackground(c: Paint): Unit = {} def stopActivity() = {} @@ -82,7 +84,7 @@ object TracingBuiltins extends CoreBuiltins with RepeatCommands { def isTracing = true def kojoInterp = new TracingInterp // get reqT to work with tracing def print(obj: Any): Unit = {} - def println(obj: Any): Unit = print("%s\n".format(obj)) + def println(obj: Any): Unit = print("%s\n" format (obj)) def TexturePaint(file: String, x: Double, y: Double) = Color(247, 247, 247) @@ -106,7 +108,7 @@ object TracingBuiltins extends CoreBuiltins with RepeatCommands { } class TracingTurtle(canvas: SCanvas, costume: String, x: Double, y: Double) - extends turtle.Turtle(canvas, costume, x, y) { + extends turtle.Turtle(canvas, costume, x, y) { override def act(fn: Turtle => Unit): Unit = { fn(this) @@ -153,4 +155,4 @@ object TracingBuiltins extends CoreBuiltins with RepeatCommands { override lazy val pictures: PLayer = new PLayer def cleari(): Unit = {} } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/lite/trace/TracingGUI.scala b/src/main/scala/net/kogics/kojo/lite/trace/TracingGUI.scala index bdd9da5ac..25c9abcc8 100644 --- a/src/main/scala/net/kogics/kojo/lite/trace/TracingGUI.scala +++ b/src/main/scala/net/kogics/kojo/lite/trace/TracingGUI.scala @@ -17,11 +17,12 @@ package net.kogics.kojo package lite package trace +import java.awt.Color +import java.awt.GradientPaint import java.awt.event.MouseAdapter import java.awt.event.MouseEvent import java.awt.geom.Point2D -import java.awt.Color -import java.awt.GradientPaint + import javax.swing.Box import javax.swing.BoxLayout import javax.swing.JButton @@ -34,15 +35,16 @@ import javax.swing.SwingConstants import scala.collection.mutable.ArrayBuffer -import bibliothek.gui.dock.common.event.CDockableStateListener -import bibliothek.gui.dock.common.intern.CDockable -import bibliothek.gui.dock.common.mode.ExtendedMode import net.kogics.kojo.core.Picture -import net.kogics.kojo.lite.topc.TraceHolder import net.kogics.kojo.lite.ScriptEditor +import net.kogics.kojo.lite.topc.TraceHolder import net.kogics.kojo.picture.GPics import net.kogics.kojo.util.Utils +import bibliothek.gui.dock.common.event.CDockableStateListener +import bibliothek.gui.dock.common.intern.CDockable +import bibliothek.gui.dock.common.mode.ExtendedMode + class TracingGUI(scriptEditor: ScriptEditor, kojoCtx: core.KojoCtx) { val events: JPanel = new JPanel events.setLayout(new BoxLayout(events, BoxLayout.Y_AXIS)) @@ -100,8 +102,7 @@ class TracingGUI(scriptEditor: ScriptEditor, kojoCtx: core.KojoCtx) { } private def addEvent(me: MethodEvent): Unit = { - @annotation.nowarn - def meSubLines(me: MethodEvent): Seq[(Point2D.Double, Point2D.Double)] = { + @annotation.nowarn def meSubLines(me: MethodEvent): Seq[(Point2D.Double, Point2D.Double)] = { def nodeSeq = me.turtlePoints match { case Some(tp) => Vector(tp) case None => Vector() @@ -109,13 +110,12 @@ class TracingGUI(scriptEditor: ScriptEditor, kojoCtx: core.KojoCtx) { me.subcalls match { case Seq() => nodeSeq - case x +: xs => nodeSeq ++ meSubLines(x) ++ (xs.flatMap(meSubLines)) + case x +: xs => nodeSeq ++ meSubLines(x) ++ (xs flatMap meSubLines) } } - @annotation.nowarn - def meSubTurns(me: MethodEvent): Seq[(Point2D.Double, Double, Double)] = { + @annotation.nowarn def meSubTurns(me: MethodEvent): Seq[(Point2D.Double, Double, Double)] = { def nodeSeq = me.turtleTurn match { case Some(tt) => Vector(tt) case None => Vector() @@ -123,7 +123,7 @@ class TracingGUI(scriptEditor: ScriptEditor, kojoCtx: core.KojoCtx) { me.subcalls match { case Seq() => nodeSeq - case x +: xs => nodeSeq ++ meSubTurns(x) ++ (xs.flatMap(meSubTurns)) + case x +: xs => nodeSeq ++ meSubTurns(x) ++ (xs flatMap meSubTurns) } } @@ -160,21 +160,21 @@ class TracingGUI(scriptEditor: ScriptEditor, kojoCtx: core.KojoCtx) { scriptEditor.markTraceLine(-1) } - currMarker.foreach { _.erase() } - currPicsMarker.foreach { p => p.setPenColor(Color.red); p.setPenThickness(2) } + currMarker foreach { _.erase() } + currPicsMarker foreach { p => p.setPenColor(Color.red); p.setPenThickness(2) } kojoCtx.repaintCanvas() currMarker = None currPicsMarker = mePictures(me) if (currPicsMarker.size > 0) { - currPicsMarker.foreach { p => p.setPenColor(markingClr); p.setPenThickness(6) } + currPicsMarker foreach { p => p.setPenColor(markingClr); p.setPenThickness(6) } } else { val subLines = meSubLines(me) if (subLines.size > 0) { if (subLines.size < 375) { val picCol = new ArrayBuffer[Picture] - subLines.foreach { ll => + subLines foreach { ll => val pic1 = picture.stroke(Color.black) * picture.strokeWidth(10) -> kojoCtx.picLine(ll._1, ll._2) val pic2 = picture.stroke(Color.yellow) * picture.strokeWidth(4) -> kojoCtx.picLine(ll._1, ll._2) val marker = GPics(pic1, pic2) @@ -196,7 +196,7 @@ class TracingGUI(scriptEditor: ScriptEditor, kojoCtx: core.KojoCtx) { else if (p.y > maxy) maxy = p.y } - subLines.foreach { ll => + subLines foreach { ll => val p1 = ll._1; val p2 = ll._2 processBounds(p1) processBounds(p2) @@ -218,26 +218,10 @@ class TracingGUI(scriptEditor: ScriptEditor, kojoCtx: core.KojoCtx) { val subTurns = meSubTurns(me) def turnPic(turn: (Point2D.Double, Double, Double)) = { val pos = turn._1; val oldTheta = turn._2; val newTheta = turn._3 - val arm11 = picture.stroke(Color.black) * picture.strokeWidth(10) * picture.rotp( - Utils.rad2degrees(oldTheta), - pos.x, - pos.y - ) -> kojoCtx.picLine(pos, new Point2D.Double(pos.x + 25, pos.y)) - val arm12 = picture.stroke(Color.yellow) * picture.strokeWidth(4) * picture.rotp( - Utils.rad2degrees(oldTheta), - pos.x, - pos.y - ) -> kojoCtx.picLine(pos, new Point2D.Double(pos.x + 25, pos.y)) - val arm21 = picture.stroke(Color.yellow) * picture.strokeWidth(10) * picture.rotp( - Utils.rad2degrees(newTheta), - pos.x, - pos.y - ) -> kojoCtx.picLine(pos, new Point2D.Double(pos.x + 25, pos.y)) - val arm22 = picture.stroke(Color.black) * picture.strokeWidth(4) * picture.rotp( - Utils.rad2degrees(newTheta), - pos.x, - pos.y - ) -> kojoCtx.picLine(pos, new Point2D.Double(pos.x + 25, pos.y)) + val arm11 = picture.stroke(Color.black) * picture.strokeWidth(10) * picture.rotp(Utils.rad2degrees(oldTheta), pos.x, pos.y) -> kojoCtx.picLine(pos, new Point2D.Double(pos.x + 25, pos.y)) + val arm12 = picture.stroke(Color.yellow) * picture.strokeWidth(4) * picture.rotp(Utils.rad2degrees(oldTheta), pos.x, pos.y) -> kojoCtx.picLine(pos, new Point2D.Double(pos.x + 25, pos.y)) + val arm21 = picture.stroke(Color.yellow) * picture.strokeWidth(10) * picture.rotp(Utils.rad2degrees(newTheta), pos.x, pos.y) -> kojoCtx.picLine(pos, new Point2D.Double(pos.x + 25, pos.y)) + val arm22 = picture.stroke(Color.black) * picture.strokeWidth(4) * picture.rotp(Utils.rad2degrees(newTheta), pos.x, pos.y) -> kojoCtx.picLine(pos, new Point2D.Double(pos.x + 25, pos.y)) picture.strokeWidth(5) -> GPics(arm11, arm12, arm21, arm22) } if (subTurns.size > 0) { @@ -265,4 +249,4 @@ class TracingGUI(scriptEditor: ScriptEditor, kojoCtx: core.KojoCtx) { events.revalidate() } } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/livecoding/ColorMakerManipulatorHexRgb.scala b/src/main/scala/net/kogics/kojo/livecoding/ColorMakerManipulatorHexRgb.scala index 03f751106..b6fcc4fc1 100644 --- a/src/main/scala/net/kogics/kojo/livecoding/ColorMakerManipulatorHexRgb.scala +++ b/src/main/scala/net/kogics/kojo/livecoding/ColorMakerManipulatorHexRgb.scala @@ -1,14 +1,11 @@ package net.kogics.kojo.livecoding -import java.awt.event.ActionEvent import java.awt.BorderLayout import java.awt.Color import java.awt.Point +import java.awt.event.ActionEvent import java.util.regex.Pattern -import javax.swing.event.ChangeEvent -import javax.swing.event.ChangeListener -import javax.swing.text.JTextComponent -import javax.swing.text.Utilities + import javax.swing.AbstractAction import javax.swing.BorderFactory import javax.swing.JColorChooser @@ -18,6 +15,10 @@ import javax.swing.JPanel import javax.swing.KeyStroke import javax.swing.PopupFactory import javax.swing.SwingUtilities +import javax.swing.event.ChangeEvent +import javax.swing.event.ChangeListener +import javax.swing.text.JTextComponent +import javax.swing.text.Utilities import net.kogics.kojo.util.Utils @@ -71,7 +72,7 @@ class ColorMakerManipulatorHexRgb(ctx: ManipulationContext) extends InteractiveM val lineOffset = offset - lineStart if (start <= lineOffset && lineOffset <= end) { target = m.group - val rgba = Seq(3, 4, 5, 7).map { e => + val rgba = Seq(3, 4, 5, 7) map { e => val ret = m.group(e) if (ret != null) ret.toInt else 255 } @@ -157,12 +158,7 @@ class ColorMakerManipulatorHexRgb(ctx: ManipulationContext) extends InteractiveM "ColorMaker.rgb(%d, %d, %d)".format(newColor.getRed, newColor.getGreen, newColor.getBlue) } else { - "ColorMaker.rgba(%d, %d, %d, %d)".format( - newColor.getRed, - newColor.getGreen, - newColor.getBlue, - newColor.getAlpha - ) + "ColorMaker.rgba(%d, %d, %d, %d)".format(newColor.getRed, newColor.getGreen, newColor.getBlue, newColor.getAlpha) } doc.insertString(targetStart, target, null); inSliderChange = false @@ -198,4 +194,4 @@ class ColorMakerManipulatorHexRgb(ctx: ManipulationContext) extends InteractiveM ctx.removeManipulator(this) } } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/livecoding/ColorMakerManipulatorHsv.scala b/src/main/scala/net/kogics/kojo/livecoding/ColorMakerManipulatorHsv.scala index 657799696..39db25214 100644 --- a/src/main/scala/net/kogics/kojo/livecoding/ColorMakerManipulatorHsv.scala +++ b/src/main/scala/net/kogics/kojo/livecoding/ColorMakerManipulatorHsv.scala @@ -1,15 +1,12 @@ package net.kogics.kojo.livecoding -import java.awt.{ Color => JColor } -import java.awt.event.ActionEvent import java.awt.BorderLayout import java.awt.Point -import java.util.regex.Pattern +import java.awt.event.ActionEvent +import java.awt.{Color => JColor} import java.util.Locale -import javax.swing.event.ChangeEvent -import javax.swing.event.ChangeListener -import javax.swing.text.JTextComponent -import javax.swing.text.Utilities +import java.util.regex.Pattern + import javax.swing.AbstractAction import javax.swing.BorderFactory import javax.swing.JColorChooser @@ -19,6 +16,10 @@ import javax.swing.JPanel import javax.swing.KeyStroke import javax.swing.PopupFactory import javax.swing.SwingUtilities +import javax.swing.event.ChangeEvent +import javax.swing.event.ChangeListener +import javax.swing.text.JTextComponent +import javax.swing.text.Utilities import net.kogics.kojo.doodle.Color import net.kogics.kojo.util.JUtils @@ -34,8 +35,7 @@ class ColorMakerManipulatorHsv(ctx: ManipulationContext) extends InteractiveMani def isAbsent = colorPopup == null def isPresent = !isAbsent - lazy val ColorPattern2 = - Pattern.compile("""(ColorMaker|cm)\.hsb(a)?\((\d+),\s*(\d+\.?\d?\d?),\s*(\d+\.?\d?\d?)(,\s*(\d+\.?\d?\d?))?\)""") + lazy val ColorPattern2 = Pattern.compile("""(ColorMaker|cm)\.hsb(a)?\((\d+),\s*(\d+\.?\d?\d?),\s*(\d+\.?\d?\d?)(,\s*(\d+\.?\d?\d?))?\)""") def matcher2(possibleColorLine: String) = ColorPattern2.matcher(possibleColorLine) def findColorFunction(pane: JTextComponent, offset: Int): Boolean = { @@ -50,7 +50,7 @@ class ColorMakerManipulatorHsv(ctx: ManipulationContext) extends InteractiveMani val lineOffset = offset - lineStart if (start <= lineOffset && lineOffset <= end) { target = m.group - val hsva = Seq(3, 4, 5, 7).map { e => + val hsva = Seq(3, 4, 5, 7) map { e => val ret = m.group(e) e match { case 3 => ret.toInt @@ -179,4 +179,4 @@ class ColorMakerManipulatorHsv(ctx: ManipulationContext) extends InteractiveMani ctx.removeManipulator(this) } } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/livecoding/ColorMakerManipulatorKnownHsl.scala b/src/main/scala/net/kogics/kojo/livecoding/ColorMakerManipulatorKnownHsl.scala index 8097a2f25..7caa72701 100644 --- a/src/main/scala/net/kogics/kojo/livecoding/ColorMakerManipulatorKnownHsl.scala +++ b/src/main/scala/net/kogics/kojo/livecoding/ColorMakerManipulatorKnownHsl.scala @@ -1,15 +1,12 @@ package net.kogics.kojo package livecoding -import java.awt.{ Color => JColor } -import java.awt.event.ActionEvent import java.awt.BorderLayout import java.awt.Point +import java.awt.event.ActionEvent +import java.awt.{Color => JColor} import java.util.regex.Pattern -import javax.swing.event.ChangeEvent -import javax.swing.event.ChangeListener -import javax.swing.text.JTextComponent -import javax.swing.text.Utilities + import javax.swing.AbstractAction import javax.swing.BorderFactory import javax.swing.JColorChooser @@ -19,6 +16,10 @@ import javax.swing.JPanel import javax.swing.KeyStroke import javax.swing.PopupFactory import javax.swing.SwingUtilities +import javax.swing.event.ChangeEvent +import javax.swing.event.ChangeListener +import javax.swing.text.JTextComponent +import javax.swing.text.Utilities import net.kogics.kojo.doodle.Color import net.kogics.kojo.util.Utils @@ -33,10 +34,9 @@ class ColorMakerManipulatorKnownHsl(ctx: ManipulationContext) extends Interactiv def isAbsent = colorPopup == null def isPresent = !isAbsent - lazy val ColorPattern = Pattern.compile("""(ColorMaker|cm)\.(%s)""".format(ctx.knownColors2.mkString("|"))) + lazy val ColorPattern = Pattern.compile("""(ColorMaker|cm)\.(%s)""" format (ctx.knownColors2.mkString("|"))) def matcher(possibleColor: String) = ColorPattern.matcher(possibleColor) - lazy val ColorPattern2 = - Pattern.compile("""(ColorMaker|cm)\.hsl(a)?\((\d+),\s*(\d+\.?\d?\d?),\s*(\d+\.?\d?\d?)(,\s*(\d+\.?\d?\d?))?\)""") + lazy val ColorPattern2 = Pattern.compile("""(ColorMaker|cm)\.hsl(a)?\((\d+),\s*(\d+\.?\d?\d?),\s*(\d+\.?\d?\d?)(,\s*(\d+\.?\d?\d?))?\)""") def matcher2(possibleColorLine: String) = ColorPattern2.matcher(possibleColorLine) def findColorFunction(pane: JTextComponent, offset: Int): Boolean = { @@ -51,7 +51,7 @@ class ColorMakerManipulatorKnownHsl(ctx: ManipulationContext) extends Interactiv val lineOffset = offset - lineStart if (start <= lineOffset && lineOffset <= end) { target = m.group - val hsla = Seq(3, 4, 5, 7).map { e => + val hsla = Seq(3, 4, 5, 7) map { e => val ret = m.group(e) e match { case 3 => ret.toInt @@ -157,13 +157,7 @@ class ColorMakerManipulatorKnownHsl(ctx: ManipulationContext) extends Interactiv Utils.strFormat("ColorMaker.hsl(%d, %.2f, %.2f)", hueAngle, ndc.saturation.get, ndc.lightness.get) } else { - Utils.strFormat( - "ColorMaker.hsla(%d, %.2f, %.2f, %.2f)", - hueAngle, - ndc.saturation.get, - ndc.lightness.get, - ndc.alpha.get - ) + Utils.strFormat("ColorMaker.hsla(%d, %.2f, %.2f, %.2f)", hueAngle, ndc.saturation.get, ndc.lightness.get, ndc.alpha.get) } doc.insertString(targetStart, target, null); inSliderChange = false @@ -199,4 +193,4 @@ class ColorMakerManipulatorKnownHsl(ctx: ManipulationContext) extends Interactiv ctx.removeManipulator(this) } } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/livecoding/ColorManipulator.scala b/src/main/scala/net/kogics/kojo/livecoding/ColorManipulator.scala index 13ad072a9..9a952821a 100644 --- a/src/main/scala/net/kogics/kojo/livecoding/ColorManipulator.scala +++ b/src/main/scala/net/kogics/kojo/livecoding/ColorManipulator.scala @@ -1,27 +1,28 @@ package net.kogics.kojo.livecoding -import java.awt.event.ActionEvent import java.awt.BorderLayout import java.awt.Color import java.awt.Point +import java.awt.event.ActionEvent import java.util.regex.Pattern -import javax.swing.event.ChangeEvent -import javax.swing.event.ChangeListener -import javax.swing.text.JTextComponent -import javax.swing.text.Utilities + import javax.swing.AbstractAction import javax.swing.BorderFactory import javax.swing.JButton import javax.swing.JColorChooser import javax.swing.JComponent -import javax.swing.JDialog import javax.swing.JPanel import javax.swing.KeyStroke import javax.swing.Popup import javax.swing.PopupFactory import javax.swing.SwingUtilities +import javax.swing.event.ChangeEvent +import javax.swing.event.ChangeListener +import javax.swing.text.JTextComponent +import javax.swing.text.Utilities import net.kogics.kojo.util.Utils +import javax.swing.JDialog class ColorManipulator(ctx: ManipulationContext) extends InteractiveManipulator { var target = "" @@ -33,7 +34,7 @@ class ColorManipulator(ctx: ManipulationContext) extends InteractiveManipulator def isAbsent = colorPopup == null def isPresent = !isAbsent - lazy val ColorPattern = Pattern.compile("""(C\.)?(%s)""".format(ctx.knownColors.mkString("|"))) + lazy val ColorPattern = Pattern.compile("""(C\.)?(%s)""" format (ctx.knownColors.mkString("|"))) def matcher(possibleColor: String) = ColorPattern.matcher(possibleColor) lazy val ColorPattern2 = Pattern.compile("""Color\((\d+),\s*(\d+),\s*(\d+)(,\s*(\d+))?\)""") def matcher2(possibleColorLine: String) = ColorPattern2.matcher(possibleColorLine) @@ -50,7 +51,7 @@ class ColorManipulator(ctx: ManipulationContext) extends InteractiveManipulator val lineOffset = offset - lineStart if (start <= lineOffset && lineOffset <= end) { target = m.group - val rgba = Seq(1, 2, 3, 5).map { e => + val rgba = Seq(1, 2, 3, 5) map { e => val ret = m.group(e) if (ret != null) ret.toInt else 255 } @@ -178,4 +179,4 @@ class ColorManipulator(ctx: ManipulationContext) extends InteractiveManipulator ctx.removeManipulator(this) } } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/livecoding/FloatManipulator.scala b/src/main/scala/net/kogics/kojo/livecoding/FloatManipulator.scala index cdfda4056..59b46f2dd 100644 --- a/src/main/scala/net/kogics/kojo/livecoding/FloatManipulator.scala +++ b/src/main/scala/net/kogics/kojo/livecoding/FloatManipulator.scala @@ -15,6 +15,7 @@ package net.kogics.kojo.livecoding import java.util.regex.Pattern + import javax.swing.event.ChangeEvent import javax.swing.event.ChangeListener import javax.swing.text.JTextComponent @@ -22,13 +23,12 @@ import javax.swing.JLabel import javax.swing.JSlider import javax.swing.JTextField import javax.swing.JToggleButton - import net.kogics.kojo.util.Utils class FloatManipulator(ctx: ManipulationContext) extends NumberManipulator(ctx) { // support a max of 12 digits after decimal point - // formatting precision does not seem to work after 16 digits, so there has to be an upper limit - val FloatPattern = Pattern.compile("""\d+\.\d?\d?\d?\d?\d?\d?\d?\d?\d?\d?\d?\d?""") + // formatting precision does not seem to work after 16 digits, so there has to be an upper limit + val FloatPattern = Pattern.compile("""\d+\.\d?\d?\d?\d?\d?\d?\d?\d?\d?\d?\d?\d?""") def matcher(possibleNumber: String) = FloatPattern.matcher(possibleNumber) @@ -42,7 +42,7 @@ class FloatManipulator(ctx: ManipulationContext) extends NumberManipulator(ctx) def activate(pane: JTextComponent, offset: Int, target0: String, targetStart: Int) = Utils.safeProcess { - def digitsAfterPoint(n: String) = { + def digitsAfterPoint(n: String) = { val pointLoc = n.indexOf('.') val digits = n.length - 1 - pointLoc if (digits < 2) 2 else digits @@ -80,8 +80,8 @@ class FloatManipulator(ctx: ManipulationContext) extends NumberManipulator(ctx) slider.setMaximum(18) slider.setValue(9) slider.setMajorTickSpacing(1) - leftLabel.setText(uiDouble(formatter.format(slider2num(slider.getMinimum)))) - rightLabel.setText(uiDouble(formatter.format(slider2num(slider.getMaximum)))) + leftLabel.setText(uiDouble(formatter format slider2num(slider.getMinimum))) + rightLabel.setText(uiDouble(formatter format slider2num(slider.getMaximum))) } slider.setValue(9) slider.setPaintTicks(true) @@ -95,7 +95,7 @@ class FloatManipulator(ctx: ManipulationContext) extends NumberManipulator(ctx) inSliderChange = true doc.remove(targetStart, target.length()) ntarget = slider2num(newnum) - target = uiDouble(formatter.format(ntarget)) + target = uiDouble(formatter format ntarget) doc.insertString(targetStart, target, null); inSliderChange = false diff --git a/src/main/scala/net/kogics/kojo/livecoding/IntManipulator.scala b/src/main/scala/net/kogics/kojo/livecoding/IntManipulator.scala index 61e0ef689..320e0f176 100644 --- a/src/main/scala/net/kogics/kojo/livecoding/IntManipulator.scala +++ b/src/main/scala/net/kogics/kojo/livecoding/IntManipulator.scala @@ -15,17 +15,16 @@ package net.kogics.kojo.livecoding import java.util.regex.Pattern -import javax.swing.event.ChangeEvent -import javax.swing.event.ChangeListener -import javax.swing.text.Document -import javax.swing.text.JTextComponent -import javax.swing.text.Utilities import javax.swing.JLabel import javax.swing.JSlider import javax.swing.JTextField import javax.swing.JToggleButton - +import javax.swing.event.ChangeEvent +import javax.swing.event.ChangeListener +import javax.swing.text.Document import net.kogics.kojo.util.Utils +import javax.swing.text.Utilities +import javax.swing.text.JTextComponent class IntManipulator(ctx: ManipulationContext) extends NumberManipulator(ctx) { val IntPattern = Pattern.compile("\\d*") diff --git a/src/main/scala/net/kogics/kojo/livecoding/NumberManipulator.scala b/src/main/scala/net/kogics/kojo/livecoding/NumberManipulator.scala index ddc37d5d5..70e81b1b3 100644 --- a/src/main/scala/net/kogics/kojo/livecoding/NumberManipulator.scala +++ b/src/main/scala/net/kogics/kojo/livecoding/NumberManipulator.scala @@ -16,14 +16,11 @@ package net.kogics.kojo package livecoding -import java.awt.event.ActionEvent -import java.awt.event.ActionListener +import util.Utils import java.awt.Color import java.awt.Point -import java.awt.Window -import java.util.regex.Matcher -import javax.swing.text.JTextComponent -import javax.swing.text.Utilities +import java.awt.event.ActionEvent +import java.awt.event.ActionListener import javax.swing.AbstractAction import javax.swing.BorderFactory import javax.swing.JButton @@ -38,8 +35,10 @@ import javax.swing.KeyStroke import javax.swing.Popup import javax.swing.PopupFactory import javax.swing.SwingUtilities - -import util.Utils +import javax.swing.text.JTextComponent +import javax.swing.text.Utilities +import java.awt.Window +import java.util.regex.Matcher abstract class NumberManipulator(ctx: ManipulationContext) extends InteractiveManipulator { var target = "" @@ -102,14 +101,12 @@ abstract class NumberManipulator(ctx: ManipulationContext) extends InteractiveMa } } - def showPopup( - offset: Int, - leftLabel: JLabel, - slider0: JSlider, - rightLabel: JLabel, - zoomListener: JToggleButton => Unit, - stepListener: Option[(JTextField, JToggleButton) => Unit] - ): Unit = { + def showPopup(offset: Int, + leftLabel: JLabel, + slider0: JSlider, + rightLabel: JLabel, + zoomListener: JToggleButton => Unit, + stepListener: Option[(JTextField, JToggleButton) => Unit]): Unit = { slider = slider0 val factory = PopupFactory.getSharedInstance(); val rect = ctx.codePane.modelToView(offset) diff --git a/src/main/scala/net/kogics/kojo/livecoding/manipulators.scala b/src/main/scala/net/kogics/kojo/livecoding/manipulators.scala index 2e760cc27..b4e0b6c30 100644 --- a/src/main/scala/net/kogics/kojo/livecoding/manipulators.scala +++ b/src/main/scala/net/kogics/kojo/livecoding/manipulators.scala @@ -15,8 +15,9 @@ package net.kogics.kojo.livecoding import java.awt.Color -import javax.swing.text.JTextComponent + import javax.swing.JFrame +import javax.swing.text.JTextComponent import net.kogics.kojo.doodle diff --git a/src/main/scala/net/kogics/kojo/music/FuguePlayer.scala b/src/main/scala/net/kogics/kojo/music/FuguePlayer.scala index de7a1db23..14a277463 100644 --- a/src/main/scala/net/kogics/kojo/music/FuguePlayer.scala +++ b/src/main/scala/net/kogics/kojo/music/FuguePlayer.scala @@ -16,20 +16,19 @@ package net.kogics.kojo package music -import java.util.concurrent.locks.ReentrantLock -import java.util.concurrent.TimeUnit -import java.util.logging._ -import javax.swing.Timer - -import net.kogics.kojo.core.KojoCtx -import org.jfugue.{ Rhythm => JFRhythm, _ } import util.Utils import util.Utils.withLock import Utils.giveupLock +import org.jfugue.{Rhythm => JFRhythm, _} +import java.util.logging._ +import java.util.concurrent.TimeUnit +import java.util.concurrent.locks.ReentrantLock +import javax.swing.Timer +import net.kogics.kojo.core.KojoCtx class FuguePlayer(kojoCtx: KojoCtx) { val Log = Logger.getLogger(getClass.getName) - private lazy val listener = kojoCtx.activityListener + lazy private val listener = kojoCtx.activityListener private var currMusic: Option[Music] = None private var currBgMusic: Option[Music] = None val playLock = new ReentrantLock @@ -61,22 +60,22 @@ class FuguePlayer(kojoCtx: KojoCtx) { } } } - + private def stopAndCreate(voice: core.Voice, n: Int): Unit = { if (n > 10) { throw new IllegalArgumentException("Score repeat count cannot be more than 10") } - - stopMusic() + + stopMusic() currMusic = Some(Music(voice, n)) } - + def isMusicPlaying: Boolean = { withLock(playLock) { currMusic.isDefined } } - + def playMusic(voice: core.Voice, n: Int = 1): Unit = { def done(): Unit = { stopFg = false @@ -100,7 +99,7 @@ class FuguePlayer(kojoCtx: KojoCtx) { } } } - startPumpingEvents() + startPumpingEvents() } } @@ -124,7 +123,7 @@ class FuguePlayer(kojoCtx: KojoCtx) { done.await() } } - + def playMusicLoop(voice: core.Voice): Unit = { def playLoop0(): Unit = { @@ -153,7 +152,7 @@ class FuguePlayer(kojoCtx: KojoCtx) { currBgMusic = Some(Music(voice, 5)) playLoop0() startPumpingEvents() - } + } } def stopMusic(): Unit = { @@ -161,7 +160,7 @@ class FuguePlayer(kojoCtx: KojoCtx) { if (currMusic.isDefined) { stopFg = true currMusic.get.stop() - while (stopFg) { + while(stopFg) { val signalled = stopped.await(20, TimeUnit.MILLISECONDS) if (!signalled) { try { @@ -181,7 +180,7 @@ class FuguePlayer(kojoCtx: KojoCtx) { if (currBgMusic.isDefined) { stopBg = true currBgMusic.get.stop() - while (stopBg) { + while(stopBg) { val signalled = stopped.await(20, TimeUnit.MILLISECONDS) if (!signalled) { try { diff --git a/src/main/scala/net/kogics/kojo/music/Instrument.scala b/src/main/scala/net/kogics/kojo/music/Instrument.scala deleted file mode 100644 index ef0f2fb43..000000000 --- a/src/main/scala/net/kogics/kojo/music/Instrument.scala +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright (C) 2022 Lalit Pant - * - * The contents of this file are subject to the GNU General Public License - * Version 3 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.gnu.org/copyleft/gpl.html - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - */ -package net.kogics.kojo.music - -object Instrument { - - // constants from jmusic (https://explodingart.com/jmusic/index.html) - - val PIANO = 0 - - val ACOUSTIC_GRAND = 0 - - val BRIGHT_ACOUSTIC = 1 - - val ELECTRIC_GRAND = 2 - - val HONKYTONK = 3 - - val HONKYTONK_PIANO = 3 - - val EPIANO = 4 - - val ELECTRIC_PIANO = 4 - - val ELPIANO = 4 - - val RHODES = 4 - - val EPIANO2 = 5 - - val DX_EPIANO = 5 - - val HARPSICHORD = 6 - - val CLAV = 7 - - val CLAVINET = 7 - - val CELESTE = 8 - - val CELESTA = 8 - - val GLOCKENSPIEL = 9 - - val GLOCK = 9 - - val MUSIC_BOX = 10 - - val VIBRAPHONE = 11 - - val VIBES = 11 - - val MARIMBA = 12 - - val XYLOPHONE = 13 - - val TUBULAR_BELL = 14 - - val TUBULAR_BELLS = 14 - - val ORGAN = 16 - - val ELECTRIC_ORGAN = 16 - - val ORGAN2 = 17 - - val JAZZ_ORGAN = 17 - - val ORGAN3 = 18 - - val HAMMOND_ORGAN = 17 - - val CHURCH_ORGAN = 19 - - val PIPE_ORGAN = 19 - - val REED_ORGAN = 20 - - val ACCORDION = 21 - - val PIANO_ACCORDION = 21 - - val CONCERTINA = 21 - - val HARMONICA = 22 - - val BANDNEON = 23 - - val NYLON_GUITAR = 24 - - val NGUITAR = 24 - - val GUITAR = 24 - - val ACOUSTIC_GUITAR = 24 - - val AC_GUITAR = 24 - - val STEEL_GUITAR = 25 - - val SGUITAR = 25 - - val JAZZ_GUITAR = 26 - - val JGUITAR = 26 - - val CLEAN_GUITAR = 27 - - val CGUITAR = 27 - - val ELECTRIC_GUITAR = 27 - - val EL_GUITAR = 27 - - val MUTED_GUITAR = 28 - - val MGUITAR = 28 - - val OVERDRIVE_GUITAR = 29 - - val OGUITAR = 29 - - val DISTORTED_GUITAR = 30 - - val DGUITAR = 30 - - val DIST_GUITAR = 30 - - val GUITAR_HARMONICS = 31 - - val GT_HARMONICS = 31 - - val HARMONICS = 31 - - val ACOUSTIC_BASS = 32 - - val ABASS = 32 - - val FINGERED_BASS = 33 - - val BASS = 33 - - val FBASS = 33 - - val ELECTRIC_BASS = 33 - - val EL_BASS = 33 - - val EBASS = 33 - - val PICKED_BASS = 34 - - val PBASS = 34 - - val FRETLESS_BASS = 35 - - val FRETLESS = 35 - - val SLAP_BASS = 36 - - val SBASS = 36 - - val SLAP = 36 - - val SLAP_BASS_1 = 36 - - val SLAP_BASS_2 = 37 - - val SYNTH_BASS = 38 - - val SYNTH_BASS_1 = 38 - - val SYNTH_BASS_2 = 39 - - val VIOLIN = 40 - - val VIOLA = 41 - - val CELLO = 42 - - val VIOLIN_CELLO = 42 - - val CONTRABASS = 43 - - val CONTRA_BASS = 43 - - val DOUBLE_BASS = 43 - - val TREMOLO_STRINGS = 44 - - val TREMOLO = 44 - - val PIZZICATO_STRINGS = 45 - - val PIZZ = 45 - - val PITZ = 45 - - val PSTRINGS = 45 - - val HARP = 46 - - val TIMPANI = 47 - - val TIMP = 47 - - val STRINGS = 48 - - val STR = 48 - - val STRING_ENSEMBLE_1 = 48 - - val STRING_ENSEMBLE_2 = 49 - - val SYNTH_STRINGS = 50 - - val SYNTH_STRINGS_1 = 50 - - val SLOW_STRINGS = 51 - - val SYNTH_STRINGS_2 = 51 - - val AAH = 52 - - val AHHS = 52 - - val CHOIR = 52 - - val OOH = 53 - - val OOHS = 53 - - val VOICE = 53 - - val SYNVOX = 54 - - val VOX = 54 - - val ORCHESTRA_HIT = 55 - - val TRUMPET = 56 - - val TROMBONE = 57 - - val TUBA = 58 - - val MUTED_TRUMPET = 59 - - val FRENCH_HORN = 60 - - val HORN = 60 - - val BRASS = 61 - - val SYNTH_BRASS = 62 - - val SYNTH_BRASS_1 = 62 - - val SYNTH_BRASS_2 = 63 - - val SOPRANO_SAX = 64 - - val SOPRANO = 64 - - val SOPRANO_SAXOPHONE = 64 - - val SOP = 64 - - val ALTO_SAX = 65 - - val ALTO = 65 - - val ALTO_SAXOPHONE = 65 - - val TENOR_SAX = 66 - - val TENOR = 66 - - val TENOR_SAXOPHONE = 66 - - val SAX = 66 - - val SAXOPHONE = 66 - - val BARITONE_SAX = 67 - - val BARI = 67 - - val BARI_SAX = 67 - - val BARITONE = 67 - - val BARITONE_SAXOPHONE = 67 - - val OBOE = 68 - - val ENGLISH_HORN = 69 - - val BASSOON = 70 - - val CLARINET = 71 - - val CLAR = 71 - - val PICCOLO = 72 - - val PIC = 72 - - val PICC = 72 - - val FLUTE = 73 - - val RECORDER = 74 - - val PAN_FLUTE = 75 - - val PANFLUTE = 75 - - val BOTTLE_BLOW = 76 - - val BOTTLE = 76 - - val SHAKUHACHI = 77 - - val WHISTLE = 78 - - val OCARINA = 79 - - val GMSQUARE_WAVE = 80 - - val SQUARE = 80 - - val GMSAW_WAVE = 81 - - val SAW = 81 - - val SAWTOOTH = 81 - - val SYNTH_CALLIOPE = 82 - - val CALLOPE = 82 - - val SYN_CALLIOPE = 82 - - val CHIFFER_LEAD = 83 - - val CHIFFER = 83 - - val CHARANG = 84 - - val SOLO_VOX = 85 - - val FANTASIA = 88 - - val WARM_PAD = 89 - - val PAD = 89 - - val POLYSYNTH = 90 - - val POLY_SYNTH = 90 - - val SPACE_VOICE = 91 - - val BOWED_GLASS = 92 - - val METAL_PAD = 93 - - val HALO_PAD = 94 - - val HALO = 94 - - val SWEEP_PAD = 95 - - val SWEEP = 95 - - val ICE_RAIN = 96 - - val ICERAIN = 96 - - val SOUNDTRACK = 97 - - val CRYSTAL = 98 - - val ATMOSPHERE = 99 - - val BRIGHTNESS = 100 - - val GOBLIN = 101 - - val ECHO_DROPS = 102 - - val DROPS = 102 - - val ECHOS = 102 - - val ECHO = 102 - - val ECHO_DROP = 102 - - val STAR_THEME = 103 - - val SITAR = 104 - - val BANJO = 105 - - val SHAMISEN = 106 - - val KOTO = 107 - - val KALIMBA = 108 - - val THUMB_PIANO = 108 - - val BAGPIPES = 109 - - val BAG_PIPES = 109 - - val BAGPIPE = 109 - - val PIPES = 109 - - val FIDDLE = 110 - - val SHANNAI = 111 - - val TINKLE_BELL = 112 - - val BELL = 112 - - val BELLS = 112 - - val AGOGO = 113 - - val STEEL_DRUMS = 114 - - val STEELDRUMS = 114 - - val STEELDRUM = 114 - - val STEEL_DRUM = 114 - - val WOODBLOCK = 115 - - val WOODBLOCKS = 115 - - val TAIKO = 116 - - val DRUM = 116 - - val TOM = 119 - - val TOMS = 119 - - val TOM_TOM = 119 - - val TOM_TOMS = 119 - - val SYNTH_DRUM = 118 - - val SYNTH_DRUMS = 118 - - val REVERSE_CYMBAL = 119 - - val CYMBAL = 119 - - val FRETNOISE = 120 - - val FRET_NOISE = 120 - - val FRET = 120 - - val FRETS = 120 - - val BREATHNOISE = 121 - - val BREATH = 121 - - val SEASHORE = 122 - - val SEA = 122 - - val RAIN = 122 - - val THUNDER = 122 - - val WIND = 122 - - val STREAM = 122 - - val SFX = 122 - - val SOUNDEFFECTS = 122 - - val SOUNDFX = 122 - - val BIRD = 123 - - val TELEPHONE = 124 - - val PHONE = 124 - - val HELICOPTER = 125 - - val APPLAUSE = 126 - - val GUNSHOT = 127 -} diff --git a/src/main/scala/net/kogics/kojo/music/Mp3Player.scala b/src/main/scala/net/kogics/kojo/music/Mp3Player.scala index 4130b7f7a..b07236fc4 100644 --- a/src/main/scala/net/kogics/kojo/music/Mp3Player.scala +++ b/src/main/scala/net/kogics/kojo/music/Mp3Player.scala @@ -19,17 +19,14 @@ package music import java.io._ import java.net.URL import java.util.concurrent.locks.ReentrantLock -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.TimeUnit -import javax.swing.Timer +import java.util.concurrent.{ConcurrentHashMap, TimeUnit} +import javax.swing.Timer import javazoom.jl.player.Player import net.kogics.kojo.core.KojoCtx import net.kogics.kojo.lite.LoadProgress -import net.kogics.kojo.util.AsyncQueuedRunner -import net.kogics.kojo.util.Utils -import net.kogics.kojo.util.Utils.giveupLock -import net.kogics.kojo.util.Utils.withLock +import net.kogics.kojo.util.Utils.{giveupLock, withLock} +import net.kogics.kojo.util.{AsyncQueuedRunner, Utils} object Mp3Player { val streamCache = new ConcurrentHashMap[String, Array[Byte]]() @@ -40,7 +37,7 @@ trait Mp3Player { val pumpEvents: Boolean val kojoCtx: KojoCtx def showError(msg: String): Unit - private lazy val listener = kojoCtx.activityListener + lazy private val listener = kojoCtx.activityListener @volatile private var mp3Player: Option[Player] = None @volatile private var bgmp3Player: Option[Player] = None @@ -97,36 +94,35 @@ trait Mp3Player { new ByteArrayInputStream(byteArray) } else { - val byteArrayIs = - try { - if (fname.startsWith("http")) { - val is = new URL(fname).openConnection().getInputStream + val byteArrayIs = try { + if (fname.startsWith("http")) { + val is = new URL(fname).openConnection().getInputStream + val ba = inputStreamToByteArray(is) + updateCacheAndObtainInputStream(ba) + } + else { + val is = getClass.getResourceAsStream(fname) + if (is != null) { val ba = inputStreamToByteArray(is) updateCacheAndObtainInputStream(ba) } else { - val is = getClass.getResourceAsStream(fname) - if (is != null) { + val mp3File = Utils.absolutePath(fname) + val f = new File(mp3File) + if (f.exists) { + val is = new FileInputStream(f) val ba = inputStreamToByteArray(is) updateCacheAndObtainInputStream(ba) } else { - val mp3File = Utils.absolutePath(fname) - val f = new File(mp3File) - if (f.exists) { - val is = new FileInputStream(f) - val ba = inputStreamToByteArray(is) - updateCacheAndObtainInputStream(ba) - } - else { - null - } + null } } } - catch { - case t: Throwable => null - } + } + catch { + case t: Throwable => null + } byteArrayIs } } @@ -137,7 +133,7 @@ trait Mp3Player { fn(is) } else { - showError("MP3 file does not exist - %s".format(fname)) + showError("MP3 file does not exist - %s" format (fname)) } } @@ -311,3 +307,4 @@ class KMp3(val kojoCtx: KojoCtx) extends Mp3Player { val pumpEvents = true def showError(msg: String) = println(msg) } + diff --git a/src/main/scala/net/kogics/kojo/music/Music.scala b/src/main/scala/net/kogics/kojo/music/Music.scala index ad77d2c46..879e4f3fe 100644 --- a/src/main/scala/net/kogics/kojo/music/Music.scala +++ b/src/main/scala/net/kogics/kojo/music/Music.scala @@ -16,7 +16,7 @@ package net.kogics.kojo package music -import org.jfugue.{ Rhythm => JFRhythm, _ } +import org.jfugue.{Rhythm => JFRhythm, _} import util.Utils object Music { diff --git a/src/main/scala/net/kogics/kojo/music/RealtimeNotePlayer.scala b/src/main/scala/net/kogics/kojo/music/RealtimeNotePlayer.scala deleted file mode 100644 index be27592c6..000000000 --- a/src/main/scala/net/kogics/kojo/music/RealtimeNotePlayer.scala +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2023 Lalit Pant - * - * The contents of this file are subject to the GNU General Public License - * Version 3 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.gnu.org/copyleft/gpl.html - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - */ -package net.kogics.kojo.music - -import javax.sound.midi.MidiEvent -import javax.sound.midi.MidiSystem -import javax.sound.midi.Sequence -import javax.sound.midi.ShortMessage - -class RealtimeNotePlayer { - println("Initializing Midi Sequencer...") - private val sequencer = MidiSystem.getSequencer() - private val ticksPerQuarterNote = 1 - private val sequence = new Sequence(Sequence.PPQ, ticksPerQuarterNote) - private var track = sequence.createTrack() - private var trackTicks = 0L - private val channel = 0 - - sequencer.open() - sequencer.setSequence(sequence) - Thread.sleep(2500) // give Midi Synth a chance to warm up, as in alda - println("Done") - setInstrument(Instrument.PIANO) - - def setInstrument(instrumentCode: Int): Unit = { - require(instrumentCode >= 0 && instrumentCode <= 127, "Instrument Code should be between 0 and 127") - val insMsg = new ShortMessage(ShortMessage.PROGRAM_CHANGE, channel, instrumentCode, 0) - val insEvent = new MidiEvent(insMsg, trackTicks) - track.add(insEvent) - } - - def playNote(pitch: Int, durationMillis: Int, volume: Int): Unit = { - require(pitch >= 0 && pitch <= 127, "Note pitch should be between 0 and 127") - require(volume >= 0 && volume <= 127, "Note volume should be between 0 and 127") - - val durationTicks = durationMillis // our ticks are in units of millis - val endBuffer0 = (0.1 * durationTicks).toInt - val endBuffer = if (endBuffer0 > 0) endBuffer0 else 1 - - val noteOnMsg = new ShortMessage(ShortMessage.NOTE_ON, channel, pitch, volume) - val noteOnEvent = new MidiEvent(noteOnMsg, trackTicks) - track.add(noteOnEvent) - trackTicks += durationTicks - - val noteOffMsg = new ShortMessage(ShortMessage.NOTE_OFF, channel, pitch, volume) - val noteOffEvent = new MidiEvent(noteOffMsg, trackTicks - endBuffer) - track.add(noteOffEvent) - - if (!sequencer.isRunning) { - // tempo in increments of 1ms - sequencer.setTempoInMPQ(1000f) - sequencer.start() - } - else { - // let the running sequencer play this note after the previous ones are done - } - } - - def stop(): Unit = { - if (sequencer.isRunning) { - sequencer.stop() - sequence.deleteTrack(track) - track = sequence.createTrack() - sequencer.setSequence(sequence) - trackTicks = 0L - sequencer.setTickPosition(0) - } - } - - def close(): Unit = { - sequencer.stop() - sequence.deleteTrack(track) - sequencer.close() - } -} diff --git a/src/main/scala/net/kogics/kojo/picture/PicCache.scala b/src/main/scala/net/kogics/kojo/picture/PicCache.scala index 4e63e19dd..85b7b9c31 100644 --- a/src/main/scala/net/kogics/kojo/picture/PicCache.scala +++ b/src/main/scala/net/kogics/kojo/picture/PicCache.scala @@ -43,6 +43,6 @@ object PicCache { } def freshPics(ps: collection.Seq[Picture]): collection.Seq[Picture] = { - ps.map(freshPic) + ps map freshPic } } diff --git a/src/main/scala/net/kogics/kojo/picture/cartooning.scala b/src/main/scala/net/kogics/kojo/picture/cartooning.scala index 5b48e6464..c07d432e7 100644 --- a/src/main/scala/net/kogics/kojo/picture/cartooning.scala +++ b/src/main/scala/net/kogics/kojo/picture/cartooning.scala @@ -17,18 +17,16 @@ package net.kogics.kojo package picture import java.awt.Font -import java.util.concurrent.CountDownLatch - import scala.collection.immutable.Queue - import net.kogics.kojo.core.Picture import net.kogics.kojo.core.Point -import net.kogics.kojo.core.SCanvas import net.kogics.kojo.kgeom.PolyLine import net.kogics.kojo.util.Utils import util.Utils import Cartooning._ import Cartooning2._ +import java.util.concurrent.CountDownLatch +import net.kogics.kojo.core.SCanvas object Cartooning { import language.implicitConversions @@ -63,7 +61,7 @@ object Cartooning2 { math.abs(a - b) < accuracy } - // *** some utility functions related to PolyLines: + //*** some utility functions related to PolyLines: def isZero(pl: PolyLine) = (pl.size == 0) || (pl.size == 1) && (pl.points(0) == Point2D(0, 0)) @@ -76,7 +74,7 @@ object Cartooning2 { def extendPolyLineTo(pl: PolyLine, s: Int): PolyLine = { val n = s - pl.size if (n <= 0 || pl.size < 2) return pl - val pointBuffer = pl.points.toBuffer // copy; to not mutate pl + val pointBuffer = pl.points.toBuffer //copy; to not mutate pl var added = 0 var i = 0 while (added < n) { @@ -101,7 +99,7 @@ object Cartooning2 { } result } - def cleanUpMidPoints(pl: PolyLine): PolyLine = { // not used yet + def cleanUpMidPoints(pl: PolyLine): PolyLine = { //not used yet val pts = pl.points.toBuffer var i = 0 while (i < pts.size - 2) { @@ -122,7 +120,7 @@ case class RichListDD(listDD: ListDD) { listDD match { case p :: ps => jumpTo(p._1, p._2) - ps.foreach { p => moveTo(p._1, p._2) } + ps foreach { p => moveTo(p._1, p._2) } case _ => } } @@ -136,11 +134,11 @@ case class RichPicture(pic: Picture) { pic.morph(skel.morpher) } def printPicture(): Unit = { - // as there is no elaborate toString on Pictures in Kojo - // and we can't return a string as morph runs unsynched in another thread + //as there is no elaborate toString on Pictures in Kojo + //and we can't return a string as morph runs unsynched in another thread println("Picture(") pic.morph { polyLines => - polyLines.map { pl => + polyLines map { pl => println(" " + plToString(pl)) pl } @@ -150,7 +148,7 @@ case class RichPicture(pic: Picture) { } } -case class Skeleton(points: Array[Point2D]) { // was MorphTarget +case class Skeleton(points: Array[Point2D]) { //was MorphTarget def size = points.size def extendTo(s: Int): Skeleton = { val n = s - size @@ -195,20 +193,21 @@ case class Skeleton(points: Array[Point2D]) { // was MorphTarget result } def stepwiseMorpher(step: Double): Seq[PolyLine] => Seq[PolyLine] = { - // this is the actual morph function to be passed to pic.morph(mt.stepwiseMorpher(1)) + //this is the actual morph function to be passed to pic.morph(mt.stepwiseMorpher(1)) (pls: Seq[PolyLine]) => { - pls.map(pl => { + pls map (pl => { if (!isZero(pl) && !isMorphedTo(pl, step)) approachTarget(pl, step) else pl - }) + } + ) } } def morpher: Seq[PolyLine] => Seq[PolyLine] = { - // a morph function to be passed to pic.morph(mySkeleton.morpher) + //a morph function to be passed to pic.morph(mySkeleton.morpher) (pls: Seq[PolyLine]) => { - pls.map(pl => { + pls map (pl => { if (!isZero(pl)) { val (mte, ple) = extendShortest(pl) for (i <- 0 until ple.size) { @@ -221,7 +220,8 @@ case class Skeleton(points: Array[Point2D]) { // was MorphTarget result } else pl - }) + } + ) } } def toPicture(implicit canvas: SCanvas) = Pic { t => @@ -237,7 +237,7 @@ case class Skeleton(points: Array[Point2D]) { // was MorphTarget object Skeleton { import language.postfixOps def apply(pts: (Double, Double)*): Skeleton = - new Skeleton(pts.map { + new Skeleton(pts map { case (x, y) => Point2D(x, y) } toArray) def apply(pl: PolyLine) = new Skeleton(pl.points.toArray) @@ -265,7 +265,7 @@ class Animator(canvas: SCanvas) { def schedule(w: AnimationStep): Unit = { addToAgenda(w) } - + def stop() = canvas.stopAnimation() // TODO: canvas.figure0.stopAnimation(animation) def currTime = System.currentTimeMillis() @@ -389,12 +389,10 @@ trait SpeakBalloon { self: AnimClip => val fillColor = fill _ val penColor = stroke _ import staging.KColor._ - wi.pic.map { _.erase() } + wi.pic map { _.erase() } wi.timeStamp = System.currentTimeMillis - wi.pic = Some( - fillColor(white) * penColor(black) -> - speakPicture(lines: _*) - ) + wi.pic = Some(fillColor(white) * penColor(black) -> + speakPicture(lines: _*)) wi.pic.foreach(_.draw()) } diff --git a/src/main/scala/net/kogics/kojo/picture/effects.scala b/src/main/scala/net/kogics/kojo/picture/effects.scala index 0d69500de..9a8c1fe39 100644 --- a/src/main/scala/net/kogics/kojo/picture/effects.scala +++ b/src/main/scala/net/kogics/kojo/picture/effects.scala @@ -31,13 +31,13 @@ case class Spin(n: Int)(pic: Picture) extends Effect { val lb = new collection.mutable.ListBuffer[Picture] lb += freshPic(pic) var angle = 360.0 / n - for (i <- 1 to n - 1) { + for (i <- 1 to n-1) { lb += rot(angle) -> pic.copy angle += 360.0 / n } GPics(lb.toList) } - + def copy = Spin(n)(pic.copy) } @@ -46,7 +46,7 @@ case class Reflect(n: Int)(pic: Picture) extends Effect { def reflectedP = { HPics(freshPic(pic), trans(n, 0)(FlipY(pic.copy))) } - + def copy = Reflect(n)(pic.copy) } diff --git a/src/main/scala/net/kogics/kojo/picture/package.scala b/src/main/scala/net/kogics/kojo/picture/package.scala index a187ec701..e4ce9a82b 100644 --- a/src/main/scala/net/kogics/kojo/picture/package.scala +++ b/src/main/scala/net/kogics/kojo/picture/package.scala @@ -14,32 +14,27 @@ */ package net.kogics.kojo +import java.awt.{Color, Font, Image, Paint} import java.awt.event.KeyEvent import java.awt.geom.GeneralPath import java.awt.image.BufferedImageOp -import java.awt.Color -import java.awt.Font -import java.awt.Image -import java.awt.Paint import java.net.URL import java.util.Random import javax.swing.JComponent - import scala.swing.Graphics2D - import com.jhlabs.image.LightFilter import com.jhlabs.image.LightFilter.Light import com.vividsolutions.jts.geom.Coordinate import com.vividsolutions.jts.geom.GeometryFactory import com.vividsolutions.jts.geom.PrecisionModel -import core.Picture import net.kogics.kojo.core.Cm import net.kogics.kojo.core.Inch import net.kogics.kojo.core.Pixel import net.kogics.kojo.core.SCanvas -import net.kogics.kojo.picture.PicCache.freshPic import net.kogics.kojo.util.Utils import net.kogics.kojo.util.Vector2D +import core.Picture +import net.kogics.kojo.picture.PicCache.freshPic package object picture { type Painter = core.Painter @@ -61,7 +56,7 @@ package object picture { val flipY = FlipYc val axesOn = AxesOnc - private[picture] def picLocalBounds(pic: Picture): Unit = Utils.runInSwingThread { + private[picture] def picBounds(pic: Picture): Unit = Utils.runInSwingThread { import edu.umd.cs.piccolo.nodes.PPath val tnode = pic.tnode val b = tnode.getUnionOfChildrenBounds(null) @@ -73,7 +68,7 @@ package object picture { } def bounds = PostDrawTransformc { pic => - picLocalBounds(pic) + picBounds(pic) } def fill(color: Paint) = Fillc(color) def stroke(color: Paint) = Strokec(color) @@ -148,8 +143,7 @@ package object picture { write(s) } - def text(s0: Any, fontSize: Int, color: Color)(implicit canvas: SCanvas): TextPic = - new TextPic(s0.toString, fontSize, color) + def text(s0: Any, fontSize: Int, color: Color)(implicit canvas: SCanvas): TextPic = new TextPic(s0.toString, fontSize, color) def text(s0: Any, font: Font, color: Color)(implicit canvas: SCanvas): TextPic = { val ret = text(s0, 15, color) ret.setPenFont(font) @@ -179,9 +173,7 @@ package object picture { def fromJava2d(w: Double, h: Double, fn: Graphics2D => Unit)(implicit canvas: SCanvas) = new Java2DPic(w, h, fn) - def fromJava2dDynamic(w: Double, h: Double, scaleOutFactor: Double, fn: Graphics2D => Unit, stopCheck: => Boolean)( - implicit canvas: SCanvas - ) = + def fromJava2dDynamic(w: Double, h: Double, scaleOutFactor: Double, fn: Graphics2D => Unit, stopCheck: => Boolean)(implicit canvas: SCanvas) = new Java2DPic(w * scaleOutFactor, h * scaleOutFactor, fn) { override def draw(): Unit = { super.draw() @@ -415,17 +407,15 @@ package object picture { // returns points on the obstacle that contain the given collision coordinate def obstacleCollPoints(c: Coordinate): Option[Array[Coordinate]] = { obstacle.picGeom.getCoordinates.sliding(2).find { cs => - val xcheck = - if (cs(0).x > cs(1).x) - cs(0).x >= c.x && c.x >= cs(1).x - else - cs(0).x <= c.x && c.x <= cs(1).x - - val ycheck = - if (cs(0).y > cs(1).y) - cs(0).y >= c.y && c.y >= cs(1).y - else - cs(0).y <= c.y && c.y <= cs(1).y + val xcheck = if (cs(0).x > cs(1).x) + cs(0).x >= c.x && c.x >= cs(1).x + else + cs(0).x <= c.x && c.x <= cs(1).x + + val ycheck = if (cs(0).y > cs(1).y) + cs(0).y >= c.y && c.y >= cs(1).y + else + cs(0).y <= c.y && c.y <= cs(1).y xcheck && ycheck } } diff --git a/src/main/scala/net/kogics/kojo/picture/picimage.scala b/src/main/scala/net/kogics/kojo/picture/picimage.scala index 959a6afb5..4b91a8dcc 100644 --- a/src/main/scala/net/kogics/kojo/picture/picimage.scala +++ b/src/main/scala/net/kogics/kojo/picture/picimage.scala @@ -15,12 +15,12 @@ package net.kogics.kojo.picture -import java.awt.image.BufferedImage -import java.awt.image.BufferedImageOp import java.awt.AlphaComposite import java.awt.Color import java.awt.GradientPaint import java.awt.RenderingHints +import java.awt.image.BufferedImage +import java.awt.image.BufferedImageOp import scala.collection.mutable.ArrayBuffer @@ -30,14 +30,16 @@ import com.jhlabs.image.LightFilter.Light import com.jhlabs.image.NoiseFilter import com.jhlabs.image.WeaveFilter import com.vividsolutions.jts.geom.Coordinate -import edu.umd.cs.piccolo.nodes.PImage -import edu.umd.cs.piccolo.util.PPaintContext -import edu.umd.cs.piccolo.PNode + import net.kogics.kojo.core.Picture import net.kogics.kojo.core.SCanvas import net.kogics.kojo.picture.PicCache.freshPic import net.kogics.kojo.util.Utils +import edu.umd.cs.piccolo.PNode +import edu.umd.cs.piccolo.nodes.PImage +import edu.umd.cs.piccolo.util.PPaintContext + trait ImageOp { def filter(img: BufferedImage): BufferedImage } @@ -51,9 +53,7 @@ class FadeImageOp(n: Int) extends ImageOp { // draw initial image into new image g2.drawImage(img, 0, 0, null) g2.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN)) - g2.setPaint( - new GradientPaint(0, 0, new Color(0.0f, 0.0f, 0.0f, 1.0f), 0, n.toFloat, new Color(0.0f, 0.0f, 0.0f, 0.0f)) - ) + g2.setPaint(new GradientPaint(0, 0, new Color(0.0f, 0.0f, 0.0f, 1.0f), 0, n.toFloat, new Color(0.0f, 0.0f, 0.0f, 0.0f))) g2.fillRect(0, 0, width.toInt, n); g2.setPaint(new Color(0.0f, 0.0f, 0.0f, 0.0f)) g2.fillRect(0, n, width.toInt, height - n); @@ -95,7 +95,7 @@ class LightsImageOp(lights: Light*) extends ImageOp { def filter(img: BufferedImage): BufferedImage = { val fltr = new LightFilter fltr.removeLight(fltr.getLights().get(0).asInstanceOf[Light]) - lights.foreach { fltr.addLight } + lights foreach { fltr.addLight } fltr.filter(img, null) } } @@ -163,14 +163,8 @@ trait EffectablePicture extends Picture { def applyFilter(filter: BufferedImageOp): Unit } -class EffectableImagePic(pic: Picture)(implicit val canvas: SCanvas) - extends Picture - with CorePicOps - with CorePicOps2 - with TNodeCacher - with RedrawStopper - with NonVectorPicOps - with EffectablePicture { +class EffectableImagePic(pic: Picture)(implicit val canvas: SCanvas) extends Picture with CorePicOps with CorePicOps2 + with TNodeCacher with RedrawStopper with NonVectorPicOps with EffectablePicture { @volatile var effects = Vector.empty[ImageOp] def makeTnode: edu.umd.cs.piccolo.PNode = Utils.runInSwingThreadAndPause { @@ -285,28 +279,22 @@ case class Blur(n: Int)(pic: EffectablePicture) extends EffectableTransformer(pi override def toString() = s"Blur($n) (Id: ${System.identityHashCode(this)}) -> ${tpic.toString}" } -case class PointLightEffect(x: Double, y: Double, direction: Double, elevation: Double, distance: Double)( - pic: EffectablePicture -) extends EffectableTransformer(pic) { +case class PointLightEffect(x: Double, y: Double, direction: Double, elevation: Double, distance: Double)(pic: EffectablePicture) extends EffectableTransformer(pic) { def draw(): Unit = { tpic.pointLight(x, y, direction, elevation, distance) tpic.draw() } def copy = PointLightEffect(x, y, direction, elevation, distance)(pic.copy.asInstanceOf[EffectablePicture]) - override def toString() = - s"PointLightEffect($x, $y, $direction, $elevation, $distance) (Id: ${System.identityHashCode(this)}) -> ${tpic.toString}" + override def toString() = s"PointLightEffect($x, $y, $direction, $elevation, $distance) (Id: ${System.identityHashCode(this)}) -> ${tpic.toString}" } -case class SpotLightEffect(x: Double, y: Double, direction: Double, elevation: Double, distance: Double)( - pic: EffectablePicture -) extends EffectableTransformer(pic) { +case class SpotLightEffect(x: Double, y: Double, direction: Double, elevation: Double, distance: Double)(pic: EffectablePicture) extends EffectableTransformer(pic) { def draw(): Unit = { tpic.spotLight(x, y, direction, elevation, distance) tpic.draw() } def copy = SpotLightEffect(x, y, direction, elevation, distance)(pic.copy.asInstanceOf[EffectablePicture]) - override def toString() = - s"SpotLightEffect($x, $y, $direction, $elevation, $distance) (Id: ${System.identityHashCode(this)}) -> ${tpic.toString}" + override def toString() = s"SpotLightEffect($x, $y, $direction, $elevation, $distance) (Id: ${System.identityHashCode(this)}) -> ${tpic.toString}" } case class Lights(nlights: Light*)(pic: EffectablePicture) extends EffectableTransformer(pic) { @@ -327,19 +315,16 @@ case class Noise(amount: Int, density: Double)(pic: EffectablePicture) extends E override def toString() = s"Noise($amount, $density) (Id: ${System.identityHashCode(this)}) -> ${tpic.toString}" } -case class Weave(xWidth: Double, xGap: Double, yWidth: Double, yGap: Double)(pic: EffectablePicture) - extends EffectableTransformer(pic) { +case class Weave(xWidth: Double, xGap: Double, yWidth: Double, yGap: Double)(pic: EffectablePicture) extends EffectableTransformer(pic) { def draw(): Unit = { tpic.weave(xWidth, xGap, yWidth, yGap) tpic.draw() } def copy = Weave(xWidth, xGap, yWidth, yGap)(pic.copy.asInstanceOf[EffectablePicture]) - override def toString() = - s"Weave($xWidth, $xGap, $yWidth, $yGap) (Id: ${System.identityHashCode(this)}) -> ${tpic.toString}" + override def toString() = s"Weave($xWidth, $xGap, $yWidth, $yGap) (Id: ${System.identityHashCode(this)}) -> ${tpic.toString}" } -case class SomeEffect(name: Symbol, props: Tuple2[Symbol, Any]*)(pic: EffectablePicture) - extends EffectableTransformer(pic) { +case class SomeEffect(name: Symbol, props: Tuple2[Symbol, Any]*)(pic: EffectablePicture) extends EffectableTransformer(pic) { def draw(): Unit = { tpic.effect(name, props: _*) tpic.draw() @@ -367,13 +352,11 @@ case class Blurc(n: Int) extends ComposableImageEffect { def apply(p: Picture) = Blur(n)(epic(p)) } -case class PointLightc(x: Double, y: Double, direction: Double, elevation: Double, distance: Double) - extends ComposableImageEffect { +case class PointLightc(x: Double, y: Double, direction: Double, elevation: Double, distance: Double) extends ComposableImageEffect { def apply(p: Picture) = PointLightEffect(x, y, direction, elevation, distance)(epic(p)) } -case class SpotLightc(x: Double, y: Double, direction: Double, elevation: Double, distance: Double) - extends ComposableImageEffect { +case class SpotLightc(x: Double, y: Double, direction: Double, elevation: Double, distance: Double) extends ComposableImageEffect { def apply(p: Picture) = SpotLightEffect(x, y, direction, elevation, distance)(epic(p)) } diff --git a/src/main/scala/net/kogics/kojo/picture/pics.scala b/src/main/scala/net/kogics/kojo/picture/pics.scala index 2142d2e98..5ef92f563 100644 --- a/src/main/scala/net/kogics/kojo/picture/pics.scala +++ b/src/main/scala/net/kogics/kojo/picture/pics.scala @@ -16,35 +16,32 @@ package net.kogics.kojo package picture -import java.awt.geom.AffineTransform -import java.awt.image.BufferedImage -import java.awt.image.BufferedImageOp +import com.jhlabs.image.AbstractBufferedImageOp + import java.awt.BasicStroke import java.awt.Color import java.awt.Paint import java.awt.Shape +import java.awt.geom.AffineTransform +import java.awt.image.{BufferedImage, BufferedImageOp} import java.util.concurrent.Future - import scala.collection.mutable.ArrayBuffer - -import com.jhlabs.image.AbstractBufferedImageOp -import com.vividsolutions.jts.geom.util.AffineTransformation import com.vividsolutions.jts.geom.Coordinate import com.vividsolutions.jts.geom.Geometry import com.vividsolutions.jts.geom.TopologyException -import edu.umd.cs.piccolo.activities.PActivity -import edu.umd.cs.piccolo.nodes.PPath -import edu.umd.cs.piccolo.nodes.PText -import edu.umd.cs.piccolo.PNode +import com.vividsolutions.jts.geom.util.AffineTransformation import net.kogics.kojo.core.Cm import net.kogics.kojo.core.Inch import net.kogics.kojo.core.Picture import net.kogics.kojo.core.Pixel import net.kogics.kojo.core.SCanvas import net.kogics.kojo.kgeom.PolyLine -import net.kogics.kojo.kmath.{ Kmath => Math } import net.kogics.kojo.picture.PicCache.freshPics +import net.kogics.kojo.kmath.{Kmath => Math} import net.kogics.kojo.util.Utils +import edu.umd.cs.piccolo.PNode +import edu.umd.cs.piccolo.activities.PActivity +import edu.umd.cs.piccolo.nodes.{PPath, PText} trait GeomPolygon { self: Picture => lazy val geomPoly = { @@ -57,9 +54,7 @@ trait GeomPolygon { self: Picture => } trait UnsupportedOps { - def notSupported(name: String, reason: String) = throw new UnsupportedOperationException( - s"$name - operation not available $reason:\n${toString}" - ) + def notSupported(name: String, reason: String) = throw new UnsupportedOperationException(s"$name - operation not available $reason:\n${toString}") } trait CorePicOps extends GeomPolygon with UnsupportedOps { self: Picture with RedrawStopper => @@ -80,7 +75,7 @@ trait CorePicOps extends GeomPolygon with UnsupportedOps { self: Picture with Re def draw(): Unit = { realDraw() - // Need to do the following if we ever have turtle commands that modify the turtle's layer transform + // Need to do the following if we ever have turtle commands that modify the turtle's layer transform // Utils.runInSwingThread { // pgTransform = t2t(tnode.getTransformReference(true)) // } @@ -143,7 +138,7 @@ trait CorePicOps extends GeomPolygon with UnsupportedOps { self: Picture with Re transformBy(AffineTransform.getScaleInstance(safeScaleFactor(xFactor), safeScaleFactor(yFactor))) } - def shear(shearX: Double, shearY: Double): Unit = { + def shear(shearX:Double, shearY:Double):Unit = { transformBy(AffineTransform.getShearInstance(shearX, shearY)) } @@ -438,7 +433,7 @@ trait CorePicOps2 extends GeomPolygon { self: Picture => PreDrawTransform { pic => pic.scaleAboutPoint(factor, x, y) }(this) def thatsScaledAround(factorX: Double, factorY: Double, x: Double, y: Double): Picture = PreDrawTransform { pic => pic.scaleAboutPoint(factorX, factorY, x, y) }(this) - def thatsSheared(shearX: Double, shearY: Double): Picture = + def thatsSheared(shearX:Double, shearY:Double):Picture = PreDrawTransform { pic => pic.shear(shearX, shearY) }(this) def thatsFilledWith(color: Paint): Picture = PostDrawTransform { pic => pic.setFillColor(color) }(this) def thatsStrokeColored(color: Paint): Picture = PostDrawTransform { pic => pic.setPenColor(color) }(this) @@ -452,16 +447,15 @@ trait CorePicOps2 extends GeomPolygon { self: Picture => withEffect(filter2) } def withFlippedX: Picture = FlipY(this) - def withFlippedY: Picture = FlipX(this) - def withFading(distance: Int): Picture = Fade(distance)(epic(this)) + def withFlippedY: Picture = FlipX(this) + def withFading(distance: Int): Picture = Fade(distance)(epic(this)) def withBlurring(radius: Int): Picture = Blur(radius)(epic(this)) def withAxes: Picture = PostDrawTransform { pic => pic.axesOn() }(this) - def withLocalBounds: Picture = PostDrawTransform { pic => picLocalBounds(pic) }(this) + def withBounds: Picture = PostDrawTransform { pic => picBounds(pic) }(this) def withOpacity(opacity: Double): Picture = PostDrawTransform { pic => pic.setOpacity(opacity) }(this) def withPosition(x: Double, y: Double): Picture = PostDrawTransform { pic => pic.setPosition(x, y) }(this) def withZIndex(zIndex: Int): Picture = PostDrawTransform { pic => pic.setZIndex(zIndex) }(this) def withClipping(clipShape: Shape): Picture = new ClipPic(this, clipShape)(canvas) - def withPenCapJoin(capJoin: (Int, Int)): Picture = PostDrawTransform { pic => pic.setPenCapJoin(capJoin) }(this) } trait RedrawStopper extends Picture { @@ -495,15 +489,9 @@ object Pic { def apply(painter: Painter)(implicit canvas: SCanvas) = new Pic(painter) } -class Pic(painter: Painter)(implicit val canvas: SCanvas) - extends Picture - with CorePicOps - with CorePicOps2 - with TNodeCacher - with RedrawStopper { +class Pic(painter: Painter)(implicit val canvas: SCanvas) extends Picture with CorePicOps with CorePicOps2 with TNodeCacher with RedrawStopper { @volatile var _t: canvas.TurtleLike = _ - val ErrMsg = - "Unable to create picture turtle. This could be because you have a draw() call after an animate{ } or morph{ } call" + val ErrMsg = "Unable to create picture turtle. This could be because you have a draw() call after an animate{ } or morph{ } call" def t = { if (_t == null) Utils.runInSwingThreadAndWait(10000, ErrMsg) { @@ -586,7 +574,7 @@ class Pic(painter: Painter)(implicit val canvas: SCanvas) while (iter.hasNext) { iter.next match { case text: PText => text.setTextPaint(color) - case _ => + case _ => } } } @@ -668,11 +656,7 @@ class Pic0(painter: Painter)(implicit canvas0: SCanvas) extends Pic(painter) { } abstract class BasePicList(val pics: List[Picture]) - extends Picture - with CorePicOps - with CorePicOps2 - with TNodeCacher - with RedrawStopper { + extends Picture with CorePicOps with CorePicOps2 with TNodeCacher with RedrawStopper { if (pics.isEmpty) { throw new IllegalArgumentException("A Picture List needs to have at least one Picture.") } @@ -753,7 +737,7 @@ abstract class BasePicList(val pics: List[Picture]) protected def initGeom() = { var pg = pics(0).picGeom pics.tail.foreach { pic => - pg = pg.union(pic.picGeom) + pg = pg union pic.picGeom } pg } diff --git a/src/main/scala/net/kogics/kojo/picture/picshapes.scala b/src/main/scala/net/kogics/kojo/picture/picshapes.scala index d4b9d64b9..abe266cfd 100644 --- a/src/main/scala/net/kogics/kojo/picture/picshapes.scala +++ b/src/main/scala/net/kogics/kojo/picture/picshapes.scala @@ -15,31 +15,48 @@ package net.kogics.kojo.picture -import java.awt._ -import java.awt.geom._ +import java.awt.BasicStroke +import java.awt.Color +import java.awt.Component +import java.awt.Font +import java.awt.GraphicsEnvironment +import java.awt.Image +import java.awt.RenderingHints +import java.awt.Shape +import java.awt.Transparency +import java.awt.geom.Arc2D +import java.awt.geom.GeneralPath +import java.awt.geom.PathIterator +import java.awt.geom.Point2D +import java.awt.geom.Rectangle2D import java.net.URL -import javax.swing.event.PopupMenuEvent -import javax.swing.event.PopupMenuListener + import javax.swing.JComboBox import javax.swing.JComponent import javax.swing.JPanel +import javax.swing.event.PopupMenuEvent +import javax.swing.event.PopupMenuListener import scala.collection.mutable.ArrayBuffer +import scala.swing.Graphics2D import com.vividsolutions.jts.geom.Coordinate import com.vividsolutions.jts.geom.Geometry -import edu.umd.cs.piccolo.nodes.PImage -import edu.umd.cs.piccolo.nodes.PPath -import edu.umd.cs.piccolo.util.PPaintContext -import edu.umd.cs.piccolo.PNode -import edu.umd.cs.piccolox.nodes.PClip -import edu.umd.cs.piccolox.pswing.PSwing + import net.kogics.kojo.core.Picture import net.kogics.kojo.core.SCanvas import net.kogics.kojo.staging.CapJoinConstants._ import net.kogics.kojo.util.Constants import net.kogics.kojo.util.Utils +import edu.umd.cs.piccolo.PNode +import edu.umd.cs.piccolo.nodes.PImage +import edu.umd.cs.piccolo.nodes.PPath +import edu.umd.cs.piccolo.nodes.PText +import edu.umd.cs.piccolo.util.PPaintContext +import edu.umd.cs.piccolox.nodes.PClip +import edu.umd.cs.piccolox.pswing.PSwing + trait PicShapeOps { self: Picture with CorePicOps => def realDraw() = Utils.runInSwingThread { tnode.setVisible(true) @@ -119,11 +136,9 @@ trait PicShapeOps { self: Picture with CorePicOps => (Cap, Join) } - def morph(fn: Seq[net.kogics.kojo.kgeom.PolyLine] => Seq[net.kogics.kojo.kgeom.PolyLine]) = - notSupported("morph", "for non-turtle picture") + def morph(fn: Seq[net.kogics.kojo.kgeom.PolyLine] => Seq[net.kogics.kojo.kgeom.PolyLine]) = notSupported("morph", "for non-turtle picture") def dumpInfo(): Unit = {} - def foreachPolyLine(fn: net.kogics.kojo.kgeom.PolyLine => Unit) = - notSupported("foreachPolyLine", "for non-turtle picture") + def foreachPolyLine(fn: net.kogics.kojo.kgeom.PolyLine => Unit) = notSupported("foreachPolyLine", "for non-turtle picture") } trait NonVectorPicOps { self: Picture with CorePicOps => @@ -151,20 +166,13 @@ trait NonVectorPicOps { self: Picture with CorePicOps => def initGeom(): Geometry = notSupported("initGeometry", "for non-vector picture") - def morph(fn: Seq[net.kogics.kojo.kgeom.PolyLine] => Seq[net.kogics.kojo.kgeom.PolyLine]) = - notSupported("morph", "for non-vector picture") + def morph(fn: Seq[net.kogics.kojo.kgeom.PolyLine] => Seq[net.kogics.kojo.kgeom.PolyLine]) = notSupported("morph", "for non-vector picture") def dumpInfo(): Unit = {} - def foreachPolyLine(fn: net.kogics.kojo.kgeom.PolyLine => Unit) = - notSupported("foreachPolyLine", "for non-vector picture") + def foreachPolyLine(fn: net.kogics.kojo.kgeom.PolyLine => Unit) = notSupported("foreachPolyLine", "for non-vector picture") } -class CirclePic(r: Double)(implicit val canvas: SCanvas) - extends Picture - with CorePicOps - with CorePicOps2 - with TNodeCacher - with RedrawStopper - with PicShapeOps { +class CirclePic(r: Double)(implicit val canvas: SCanvas) extends Picture with CorePicOps with CorePicOps2 + with TNodeCacher with RedrawStopper with PicShapeOps { def initGeom(): com.vividsolutions.jts.geom.Geometry = { def x(t: Double) = r * math.cos(t.toRadians) def y(t: Double) = r * math.sin(t.toRadians) @@ -187,13 +195,8 @@ class CirclePic(r: Double)(implicit val canvas: SCanvas) def copy: net.kogics.kojo.core.Picture = new CirclePic(r) } -class EllipsePic(rx: Double, ry: Double)(implicit val canvas: SCanvas) - extends Picture - with CorePicOps - with CorePicOps2 - with TNodeCacher - with RedrawStopper - with PicShapeOps { +class EllipsePic(rx: Double, ry: Double)(implicit val canvas: SCanvas) extends Picture with CorePicOps with CorePicOps2 + with TNodeCacher with RedrawStopper with PicShapeOps { def initGeom(): com.vividsolutions.jts.geom.Geometry = { def x(t: Double) = rx * math.cos(t.toRadians) def y(t: Double) = ry * math.sin(t.toRadians) @@ -218,13 +221,8 @@ class EllipsePic(rx: Double, ry: Double)(implicit val canvas: SCanvas) def copy: net.kogics.kojo.core.Picture = new EllipsePic(rx, ry) } -class ArcPic(r: Double, angle: Double)(implicit val canvas: SCanvas) - extends Picture - with CorePicOps - with CorePicOps2 - with TNodeCacher - with RedrawStopper - with PicShapeOps { +class ArcPic(r: Double, angle: Double)(implicit val canvas: SCanvas) extends Picture with CorePicOps with CorePicOps2 + with TNodeCacher with RedrawStopper with PicShapeOps { def initGeom(): com.vividsolutions.jts.geom.Geometry = { def x(t: Double) = r * math.cos(t.toRadians) def y(t: Double) = r * math.sin(t.toRadians) @@ -252,13 +250,8 @@ class ArcPic(r: Double, angle: Double)(implicit val canvas: SCanvas) def copy: net.kogics.kojo.core.Picture = new ArcPic(r, angle) } -class RectanglePic(w: Double, h: Double)(implicit val canvas: SCanvas) - extends Picture - with CorePicOps - with CorePicOps2 - with TNodeCacher - with RedrawStopper - with PicShapeOps { +class RectanglePic(w: Double, h: Double)(implicit val canvas: SCanvas) extends Picture with CorePicOps with CorePicOps2 + with TNodeCacher with RedrawStopper with PicShapeOps { def initGeom(): com.vividsolutions.jts.geom.Geometry = { val cab = new ArrayBuffer[Coordinate] cab += newCoordinate(0, 0) @@ -282,13 +275,8 @@ class RectanglePic(w: Double, h: Double)(implicit val canvas: SCanvas) def copy: net.kogics.kojo.core.Picture = new RectanglePic(w, h) } -class LinePic(x: Double, y: Double)(implicit val canvas: SCanvas) - extends Picture - with CorePicOps - with CorePicOps2 - with TNodeCacher - with RedrawStopper - with PicShapeOps { +class LinePic(x: Double, y: Double)(implicit val canvas: SCanvas) extends Picture with CorePicOps with CorePicOps2 + with TNodeCacher with RedrawStopper with PicShapeOps { def initGeom(): com.vividsolutions.jts.geom.Geometry = { val cab = new ArrayBuffer[Coordinate] cab += newCoordinate(0, 0) @@ -309,13 +297,8 @@ class LinePic(x: Double, y: Double)(implicit val canvas: SCanvas) def copy: net.kogics.kojo.core.Picture = new LinePic(x, y) } -class PathPic(pathMaker: => GeneralPath)(implicit val canvas: SCanvas) - extends Picture - with CorePicOps - with CorePicOps2 - with TNodeCacher - with RedrawStopper - with PicShapeOps { +class PathPic(pathMaker: => GeneralPath)(implicit val canvas: SCanvas) extends Picture with CorePicOps with CorePicOps2 + with TNodeCacher with RedrawStopper with PicShapeOps { lazy val path = pathMaker def initGeom(): com.vividsolutions.jts.geom.Geometry = { val cab = new ArrayBuffer[Coordinate] @@ -357,13 +340,8 @@ class PathPic(pathMaker: => GeneralPath)(implicit val canvas: SCanvas) } // a picture that lets you use the full Java2D API for drawing via a Graphics2D -class Java2DPic(w: Double, h: Double, fn: Graphics2D => Unit)(implicit val canvas: SCanvas) - extends Picture - with CorePicOps - with CorePicOps2 - with TNodeCacher - with RedrawStopper - with NonVectorPicOps { +class Java2DPic(w: Double, h: Double, fn: Graphics2D => Unit)(implicit val canvas: SCanvas) extends Picture with CorePicOps with CorePicOps2 + with TNodeCacher with RedrawStopper with NonVectorPicOps { override def initGeom(): com.vividsolutions.jts.geom.Geometry = { val cab = new ArrayBuffer[Coordinate] cab += newCoordinate(0, 0) @@ -375,8 +353,7 @@ class Java2DPic(w: Double, h: Double, fn: Graphics2D => Unit)(implicit val canva } lazy val (imageWithDrawing, imageG2D) = { - val graphicsConfiguration = - GraphicsEnvironment.getLocalGraphicsEnvironment.getDefaultScreenDevice.getDefaultConfiguration + val graphicsConfiguration = GraphicsEnvironment.getLocalGraphicsEnvironment.getDefaultScreenDevice.getDefaultConfiguration val buffImg = graphicsConfiguration.createCompatibleImage(w.toInt, h.toInt, Transparency.TRANSLUCENT) val gbi = buffImg.createGraphics new PPaintContext(gbi).setRenderQuality(PPaintContext.HIGH_QUALITY_RENDERING) @@ -415,13 +392,8 @@ class Java2DPic(w: Double, h: Double, fn: Graphics2D => Unit)(implicit val canva def copy: net.kogics.kojo.core.Picture = new Java2DPic(w, h, fn) } -class ImagePic(img: Image, envelope: Option[Picture])(implicit val canvas: SCanvas) - extends Picture - with CorePicOps - with CorePicOps2 - with TNodeCacher - with RedrawStopper - with NonVectorPicOps { +class ImagePic(img: Image, envelope: Option[Picture])(implicit val canvas: SCanvas) extends Picture with CorePicOps with CorePicOps2 + with TNodeCacher with RedrawStopper with NonVectorPicOps { def makeTnode: edu.umd.cs.piccolo.PNode = Utils.runInSwingThreadAndPause { val inode = new PImage(img) { @@ -476,22 +448,17 @@ class ImagePic(img: Image, envelope: Option[Picture])(implicit val canvas: SCanv } class FileImagePic(file: String, envelope: Option[Picture])(implicit canvas: SCanvas) - extends ImagePic(Utils.loadImage(file), envelope) { + extends ImagePic(Utils.loadImage(file), envelope) { override def copy: net.kogics.kojo.core.Picture = new FileImagePic(file, envelope) } class UrlImagePic(url: URL, envelope: Option[Picture])(implicit canvas: SCanvas) - extends ImagePic(Utils.loadUrlImageC(url), envelope) { + extends ImagePic(Utils.loadUrlImageC(url), envelope) { override def copy: net.kogics.kojo.core.Picture = new UrlImagePic(url, envelope) } -class SwingPic(swingComponent: JComponent)(implicit val canvas: SCanvas) - extends Picture - with CorePicOps - with CorePicOps2 - with TNodeCacher - with RedrawStopper - with NonVectorPicOps { +class SwingPic(swingComponent: JComponent)(implicit val canvas: SCanvas) extends Picture with CorePicOps with CorePicOps2 + with TNodeCacher with RedrawStopper with NonVectorPicOps { def pswingHook(ps: PSwing): Unit = {} @@ -513,7 +480,7 @@ class SwingPic(swingComponent: JComponent)(implicit val canvas: SCanvas) def handleComponent(comp: Component): Unit = { comp match { case combo: JComboBox[_] => handleCombo(combo.asInstanceOf[JComboBox[AnyRef]]) - case jp: JPanel => jp.getComponents.foreach { handleComponent } + case jp: JPanel => jp.getComponents foreach { handleComponent } case _ => } } @@ -553,13 +520,8 @@ class SwingPic(swingComponent: JComponent)(implicit val canvas: SCanvas) override def toString() = s"SwingPic (Id: ${System.identityHashCode(this)})" } -class TextPic(text: String, size: Int, color: Color)(implicit val canvas: SCanvas) - extends Picture - with CorePicOps - with CorePicOps2 - with TNodeCacher - with RedrawStopper - with PicShapeOps { +class TextPic(text: String, size: Int, color: Color)(implicit val canvas: SCanvas) extends Picture with CorePicOps with CorePicOps2 + with TNodeCacher with RedrawStopper with PicShapeOps { def initGeom(): Geometry = notSupported("initGeometry", "for text picture") val ptext = Utils.textNode(text, 0, 0, canvas.camScale, size) @@ -601,13 +563,8 @@ class TextPic(text: String, size: Int, color: Color)(implicit val canvas: SCanva override def toString() = s"TextPic (Id: ${System.identityHashCode(this)})" } -class ClipPic(pic: Picture, clipShape: Shape)(implicit val canvas: SCanvas) - extends Picture - with CorePicOps - with CorePicOps2 - with TNodeCacher - with RedrawStopper - with PicShapeOps { +class ClipPic(pic: Picture, clipShape: Shape)(implicit val canvas: SCanvas) extends Picture with CorePicOps with CorePicOps2 + with TNodeCacher with RedrawStopper with PicShapeOps { def initGeom(): com.vividsolutions.jts.geom.Geometry = { throw new RuntimeException("Clip pic does not yet support geometry") } @@ -631,3 +588,4 @@ class ClipPic(pic: Picture, clipShape: Shape)(implicit val canvas: SCanvas) def copy: net.kogics.kojo.core.Picture = new ClipPic(pic.copy, clipShape) } + diff --git a/src/main/scala/net/kogics/kojo/picture/transforms.scala b/src/main/scala/net/kogics/kojo/picture/transforms.scala index 1bfdfb013..ef55a1041 100644 --- a/src/main/scala/net/kogics/kojo/picture/transforms.scala +++ b/src/main/scala/net/kogics/kojo/picture/transforms.scala @@ -16,14 +16,15 @@ package net.kogics.kojo package picture -import java.awt.geom.AffineTransform import java.awt.Paint import java.awt.Shape +import java.awt.geom.AffineTransform import net.kogics.kojo.core.Picture import net.kogics.kojo.kgeom.PolyLine -import net.kogics.kojo.picture.PicCache.freshPic + import util.Utils +import net.kogics.kojo.picture.PicCache.freshPic trait Transformer extends Picture with CorePicOps2 { val tpic: Picture @@ -34,10 +35,9 @@ trait Transformer extends Picture with CorePicOps2 { def rotateAboutPoint(angle: Double, x: Double, y: Double) = tpic.rotateAboutPoint(angle, x, y) def scale(factor: Double) = tpic.scale(factor) def scaleAboutPoint(factor: Double, x: Double, y: Double) = tpic.scaleAboutPoint(factor, x, y) - def scaleAboutPoint(factorX: Double, factorY: Double, x: Double, y: Double) = - tpic.scaleAboutPoint(factorX, factorY, x, y) + def scaleAboutPoint(factorX: Double, factorY: Double, x: Double, y: Double) = tpic.scaleAboutPoint(factorX, factorY, x, y) def scale(xFactor: Double, yFactor: Double) = tpic.scale(xFactor, yFactor) - def shear(shearX: Double, shearY: Double): Unit = tpic.shear(shearX, shearY) + def shear(shearX:Double, shearY:Double):Unit = tpic.shear(shearX, shearY) def opacityMod(f: Double) = tpic.opacityMod(f) def hueMod(f: Double) = tpic.hueMod(f) def satMod(f: Double) = tpic.satMod(f) @@ -267,7 +267,7 @@ case class PostDrawTransform(fn: Picture => Unit)(pic: Picture) extends Transfor abstract class ComposableTransformer extends Function1[Picture, Picture] { outer => def apply(p: Picture): Picture - def ->(p: Picture) = apply(p) + def -> (p: Picture) = apply(p) def *(other: ComposableTransformer) = new ComposableTransformer { def apply(p: Picture): Picture = { outer.apply(other.apply(p)) diff --git a/src/main/scala/net/kogics/kojo/staging/CapJoin.scala b/src/main/scala/net/kogics/kojo/staging/CapJoin.scala index 97a18b7d0..376d0f949 100644 --- a/src/main/scala/net/kogics/kojo/staging/CapJoin.scala +++ b/src/main/scala/net/kogics/kojo/staging/CapJoin.scala @@ -10,17 +10,10 @@ class CapJoin { val CAP_ROUND = BasicStroke.CAP_ROUND val CAP_SQUARE = BasicStroke.CAP_SQUARE - // Note - CAPs are for "unclosed" lines - // Joins come into play where lines connect - // good combos val BUTT_BEVEL = (CAP_BUTT, JOIN_BEVEL) val ROUND_ROUND = (CAP_ROUND, JOIN_ROUND) val SQUARE_MITER = (CAP_SQUARE, JOIN_MITER) - - val ROUNDED_CORNERS = ROUND_ROUND - val SHARP_CORNERS = SQUARE_MITER - val SLOPING_CORNERS = BUTT_BEVEL } object CapJoinConstants { diff --git a/src/main/scala/net/kogics/kojo/staging/ColorName.scala b/src/main/scala/net/kogics/kojo/staging/ColorName.scala index 53e8c48ca..e37443f39 100644 --- a/src/main/scala/net/kogics/kojo/staging/ColorName.scala +++ b/src/main/scala/net/kogics/kojo/staging/ColorName.scala @@ -19,153 +19,152 @@ package staging object ColorName { def unapply(name: String) = ColorNames.get(name) - val ColorNames = Map[String, java.awt.Color]( - "aliceblue" -> new java.awt.Color(240, 248, 255), - "antiquewhite" -> new java.awt.Color(250, 235, 215), - "aqua" -> new java.awt.Color(0, 255, 255), - "aquamarine" -> new java.awt.Color(127, 255, 212), - "azure" -> new java.awt.Color(240, 255, 255), - "beige" -> new java.awt.Color(245, 245, 220), - "bisque" -> new java.awt.Color(255, 228, 196), - "black" -> new java.awt.Color(0, 0, 0), - "blanchedalmond" -> new java.awt.Color(255, 235, 205), - "blue" -> new java.awt.Color(0, 0, 255), - "blueviolet" -> new java.awt.Color(138, 43, 226), - "brown" -> new java.awt.Color(165, 42, 42), - "burlywood" -> new java.awt.Color(222, 184, 135), - "cadetblue" -> new java.awt.Color(95, 158, 160), - "chartreuse" -> new java.awt.Color(127, 255, 0), - "chocolate" -> new java.awt.Color(210, 105, 30), - "coral" -> new java.awt.Color(255, 127, 80), - "cornflowerblue" -> new java.awt.Color(100, 149, 237), - "cornsilk" -> new java.awt.Color(255, 248, 220), - "crimson" -> new java.awt.Color(220, 20, 60), - "cyan" -> new java.awt.Color(0, 255, 255), - "darkblue" -> new java.awt.Color(0, 0, 139), - "darkcyan" -> new java.awt.Color(0, 139, 139), - "darkgoldenrod" -> new java.awt.Color(184, 134, 11), - "darkgray" -> new java.awt.Color(169, 169, 169), - "darkgreen" -> new java.awt.Color(0, 100, 0), - "darkgrey" -> new java.awt.Color(169, 169, 169), - "darkkhaki" -> new java.awt.Color(189, 183, 107), - "darkmagenta" -> new java.awt.Color(139, 0, 139), - "darkolivegreen" -> new java.awt.Color(85, 107, 47), - "darkorange" -> new java.awt.Color(255, 140, 0), - "darkorchid" -> new java.awt.Color(153, 50, 204), - "darkred" -> new java.awt.Color(139, 0, 0), - "darksalmon" -> new java.awt.Color(233, 150, 122), - "darkseagreen" -> new java.awt.Color(143, 188, 143), - "darkslateblue" -> new java.awt.Color(72, 61, 139), - "darkslategray" -> new java.awt.Color(47, 79, 79), - "darkslategrey" -> new java.awt.Color(47, 79, 79), - "darkturquoise" -> new java.awt.Color(0, 206, 209), - "darkviolet" -> new java.awt.Color(148, 0, 211), - "deeppink" -> new java.awt.Color(255, 20, 147), - "deepskyblue" -> new java.awt.Color(0, 191, 255), - "dimgray" -> new java.awt.Color(105, 105, 105), - "dimgrey" -> new java.awt.Color(105, 105, 105), - "dodgerblue" -> new java.awt.Color(30, 144, 255), - "firebrick" -> new java.awt.Color(178, 34, 34), - "floralwhite" -> new java.awt.Color(255, 250, 240), - "forestgreen" -> new java.awt.Color(34, 139, 34), - "fuchsia" -> new java.awt.Color(255, 0, 255), - "gainsboro" -> new java.awt.Color(220, 220, 220), - "ghostwhite" -> new java.awt.Color(248, 248, 255), - "gold" -> new java.awt.Color(255, 215, 0), - "goldenrod" -> new java.awt.Color(218, 165, 32), - "gray" -> new java.awt.Color(128, 128, 128), - "grey" -> new java.awt.Color(128, 128, 128), - "green" -> new java.awt.Color(0, 128, 0), - "greenyellow" -> new java.awt.Color(173, 255, 47), - "honeydew" -> new java.awt.Color(240, 255, 240), - "hotpink" -> new java.awt.Color(255, 105, 180), - "indianred" -> new java.awt.Color(205, 92, 92), - "indigo" -> new java.awt.Color(75, 0, 130), - "ivory" -> new java.awt.Color(255, 255, 240), - "khaki" -> new java.awt.Color(240, 230, 140), - "lavender" -> new java.awt.Color(230, 230, 250), - "lavenderblush" -> new java.awt.Color(255, 240, 245), - "lawngreen" -> new java.awt.Color(124, 252, 0), - "lemonchiffon" -> new java.awt.Color(255, 250, 205), - "lightblue" -> new java.awt.Color(173, 216, 230), - "lightcoral" -> new java.awt.Color(240, 128, 128), - "lightcyan" -> new java.awt.Color(224, 255, 255), - "lightgoldenrodyellow" -> new java.awt.Color(250, 250, 210), - "lightgray" -> new java.awt.Color(211, 211, 211), - "lightgreen" -> new java.awt.Color(144, 238, 144), - "lightgrey" -> new java.awt.Color(211, 211, 211), - "lightpink" -> new java.awt.Color(255, 182, 193), - "lightsalmon" -> new java.awt.Color(255, 160, 122), - "lightseagreen" -> new java.awt.Color(32, 178, 170), - "lightskyblue" -> new java.awt.Color(135, 206, 250), - "lightslategray" -> new java.awt.Color(119, 136, 153), - "lightslategrey" -> new java.awt.Color(119, 136, 153), - "lightsteelblue" -> new java.awt.Color(176, 196, 222), - "lightyellow" -> new java.awt.Color(255, 255, 224), - "lime" -> new java.awt.Color(0, 255, 0), - "limegreen" -> new java.awt.Color(50, 205, 50), - "linen" -> new java.awt.Color(250, 240, 230), - "magenta" -> new java.awt.Color(255, 0, 255), - "maroon" -> new java.awt.Color(128, 0, 0), - "mediumaquamarine" -> new java.awt.Color(102, 205, 170), - "mediumblue" -> new java.awt.Color(0, 0, 205), - "mediumorchid" -> new java.awt.Color(186, 85, 211), - "mediumpurple" -> new java.awt.Color(147, 112, 219), - "mediumseagreen" -> new java.awt.Color(60, 179, 113), - "mediumslateblue" -> new java.awt.Color(123, 104, 238), - "mediumspringgreen" -> new java.awt.Color(0, 250, 154), - "mediumturquoise" -> new java.awt.Color(72, 209, 204), - "mediumvioletred" -> new java.awt.Color(199, 21, 133), - "midnightblue" -> new java.awt.Color(25, 25, 112), - "mintcream" -> new java.awt.Color(245, 255, 250), - "mistyrose" -> new java.awt.Color(255, 228, 225), - "moccasin" -> new java.awt.Color(255, 228, 181), - "navajowhite" -> new java.awt.Color(255, 222, 173), - "navy" -> new java.awt.Color(0, 0, 128), - "oldlace" -> new java.awt.Color(253, 245, 230), - "olive" -> new java.awt.Color(128, 128, 0), - "olivedrab" -> new java.awt.Color(107, 142, 35), - "orange" -> new java.awt.Color(255, 165, 0), - "orangered" -> new java.awt.Color(255, 69, 0), - "orchid" -> new java.awt.Color(218, 112, 214), - "palegoldenrod" -> new java.awt.Color(238, 232, 170), - "palegreen" -> new java.awt.Color(152, 251, 152), - "paleturquoise" -> new java.awt.Color(175, 238, 238), - "palevioletred" -> new java.awt.Color(219, 112, 147), - "papayawhip" -> new java.awt.Color(255, 239, 213), - "peachpuff" -> new java.awt.Color(255, 218, 185), - "peru" -> new java.awt.Color(205, 133, 63), - "pink" -> new java.awt.Color(255, 192, 203), - "plum" -> new java.awt.Color(221, 160, 221), - "powderblue" -> new java.awt.Color(176, 224, 230), - "purple" -> new java.awt.Color(128, 0, 128), - "red" -> new java.awt.Color(255, 0, 0), - "rosybrown" -> new java.awt.Color(188, 143, 143), - "royalblue" -> new java.awt.Color(65, 105, 225), - "saddlebrown" -> new java.awt.Color(139, 69, 19), - "salmon" -> new java.awt.Color(250, 128, 114), - "sandybrown" -> new java.awt.Color(244, 164, 96), - "seagreen" -> new java.awt.Color(46, 139, 87), - "seashell" -> new java.awt.Color(255, 245, 238), - "sienna" -> new java.awt.Color(160, 82, 45), - "silver" -> new java.awt.Color(192, 192, 192), - "skyblue" -> new java.awt.Color(135, 206, 235), - "slateblue" -> new java.awt.Color(106, 90, 205), - "slategray" -> new java.awt.Color(112, 128, 144), - "slategrey" -> new java.awt.Color(112, 128, 144), - "snow" -> new java.awt.Color(255, 250, 250), - "springgreen" -> new java.awt.Color(0, 255, 127), - "steelblue" -> new java.awt.Color(70, 130, 180), - "tan" -> new java.awt.Color(210, 180, 140), - "teal" -> new java.awt.Color(0, 128, 128), - "thistle" -> new java.awt.Color(216, 191, 216), - "tomato" -> new java.awt.Color(255, 99, 71), - "turquoise" -> new java.awt.Color(64, 224, 208), - "violet" -> new java.awt.Color(238, 130, 238), - "wheat" -> new java.awt.Color(245, 222, 179), - "white" -> new java.awt.Color(255, 255, 255), - "whitesmoke" -> new java.awt.Color(245, 245, 245), - "yellow" -> new java.awt.Color(255, 255, 0), - "yellowgreen" -> new java.awt.Color(154, 205, 50) - ) +val ColorNames = Map[String, java.awt.Color]( + "aliceblue" -> new java.awt.Color(240, 248, 255), + "antiquewhite" -> new java.awt.Color(250, 235, 215), + "aqua" -> new java.awt.Color( 0, 255, 255), + "aquamarine" -> new java.awt.Color(127, 255, 212), + "azure" -> new java.awt.Color(240, 255, 255), + "beige" -> new java.awt.Color(245, 245, 220), + "bisque" -> new java.awt.Color(255, 228, 196), + "black" -> new java.awt.Color( 0, 0, 0), + "blanchedalmond" -> new java.awt.Color(255, 235, 205), + "blue" -> new java.awt.Color( 0, 0, 255), + "blueviolet" -> new java.awt.Color(138, 43, 226), + "brown" -> new java.awt.Color(165, 42, 42), + "burlywood" -> new java.awt.Color(222, 184, 135), + "cadetblue" -> new java.awt.Color( 95, 158, 160), + "chartreuse" -> new java.awt.Color(127, 255, 0), + "chocolate" -> new java.awt.Color(210, 105, 30), + "coral" -> new java.awt.Color(255, 127, 80), + "cornflowerblue" -> new java.awt.Color(100, 149, 237), + "cornsilk" -> new java.awt.Color(255, 248, 220), + "crimson" -> new java.awt.Color(220, 20, 60), + "cyan" -> new java.awt.Color( 0, 255, 255), + "darkblue" -> new java.awt.Color( 0, 0, 139), + "darkcyan" -> new java.awt.Color( 0, 139, 139), + "darkgoldenrod" -> new java.awt.Color(184, 134, 11), + "darkgray" -> new java.awt.Color(169, 169, 169), + "darkgreen" -> new java.awt.Color( 0, 100, 0), + "darkgrey" -> new java.awt.Color(169, 169, 169), + "darkkhaki" -> new java.awt.Color(189, 183, 107), + "darkmagenta" -> new java.awt.Color(139, 0, 139), + "darkolivegreen" -> new java.awt.Color( 85, 107, 47), + "darkorange" -> new java.awt.Color(255, 140, 0), + "darkorchid" -> new java.awt.Color(153, 50, 204), + "darkred" -> new java.awt.Color(139, 0, 0), + "darksalmon" -> new java.awt.Color(233, 150, 122), + "darkseagreen" -> new java.awt.Color(143, 188, 143), + "darkslateblue" -> new java.awt.Color( 72, 61, 139), + "darkslategray" -> new java.awt.Color( 47, 79, 79), + "darkslategrey" -> new java.awt.Color( 47, 79, 79), + "darkturquoise" -> new java.awt.Color( 0, 206, 209), + "darkviolet" -> new java.awt.Color(148, 0, 211), + "deeppink" -> new java.awt.Color(255, 20, 147), + "deepskyblue" -> new java.awt.Color( 0, 191, 255), + "dimgray" -> new java.awt.Color(105, 105, 105), + "dimgrey" -> new java.awt.Color(105, 105, 105), + "dodgerblue" -> new java.awt.Color( 30, 144, 255), + "firebrick" -> new java.awt.Color(178, 34, 34), + "floralwhite" -> new java.awt.Color(255, 250, 240), + "forestgreen" -> new java.awt.Color( 34, 139, 34), + "fuchsia" -> new java.awt.Color(255, 0, 255), + "gainsboro" -> new java.awt.Color(220, 220, 220), + "ghostwhite" -> new java.awt.Color(248, 248, 255), + "gold" -> new java.awt.Color(255, 215, 0), + "goldenrod" -> new java.awt.Color(218, 165, 32), + "gray" -> new java.awt.Color(128, 128, 128), + "grey" -> new java.awt.Color(128, 128, 128), + "green" -> new java.awt.Color( 0, 128, 0), + "greenyellow" -> new java.awt.Color(173, 255, 47), + "honeydew" -> new java.awt.Color(240, 255, 240), + "hotpink" -> new java.awt.Color(255, 105, 180), + "indianred" -> new java.awt.Color(205, 92, 92), + "indigo" -> new java.awt.Color( 75, 0, 130), + "ivory" -> new java.awt.Color(255, 255, 240), + "khaki" -> new java.awt.Color(240, 230, 140), + "lavender" -> new java.awt.Color(230, 230, 250), + "lavenderblush" -> new java.awt.Color(255, 240, 245), + "lawngreen" -> new java.awt.Color(124, 252, 0), + "lemonchiffon" -> new java.awt.Color(255, 250, 205), + "lightblue" -> new java.awt.Color(173, 216, 230), + "lightcoral" -> new java.awt.Color(240, 128, 128), + "lightcyan" -> new java.awt.Color(224, 255, 255), + "lightgoldenrodyellow" -> new java.awt.Color(250, 250, 210), + "lightgray" -> new java.awt.Color(211, 211, 211), + "lightgreen" -> new java.awt.Color(144, 238, 144), + "lightgrey" -> new java.awt.Color(211, 211, 211), + "lightpink" -> new java.awt.Color(255, 182, 193), + "lightsalmon" -> new java.awt.Color(255, 160, 122), + "lightseagreen" -> new java.awt.Color( 32, 178, 170), + "lightskyblue" -> new java.awt.Color(135, 206, 250), + "lightslategray" -> new java.awt.Color(119, 136, 153), + "lightslategrey" -> new java.awt.Color(119, 136, 153), + "lightsteelblue" -> new java.awt.Color(176, 196, 222), + "lightyellow" -> new java.awt.Color(255, 255, 224), + "lime" -> new java.awt.Color( 0, 255, 0), + "limegreen" -> new java.awt.Color( 50, 205, 50), + "linen" -> new java.awt.Color(250, 240, 230), + "magenta" -> new java.awt.Color(255, 0, 255), + "maroon" -> new java.awt.Color(128, 0, 0), + "mediumaquamarine" -> new java.awt.Color(102, 205, 170), + "mediumblue" -> new java.awt.Color( 0, 0, 205), + "mediumorchid" -> new java.awt.Color(186, 85, 211), + "mediumpurple" -> new java.awt.Color(147, 112, 219), + "mediumseagreen" -> new java.awt.Color( 60, 179, 113), + "mediumslateblue" -> new java.awt.Color(123, 104, 238), + "mediumspringgreen" -> new java.awt.Color( 0, 250, 154), + "mediumturquoise" -> new java.awt.Color( 72, 209, 204), + "mediumvioletred" -> new java.awt.Color(199, 21, 133), + "midnightblue" -> new java.awt.Color( 25, 25, 112), + "mintcream" -> new java.awt.Color(245, 255, 250), + "mistyrose" -> new java.awt.Color(255, 228, 225), + "moccasin" -> new java.awt.Color(255, 228, 181), + "navajowhite" -> new java.awt.Color(255, 222, 173), + "navy" -> new java.awt.Color( 0, 0, 128), + "oldlace" -> new java.awt.Color(253, 245, 230), + "olive" -> new java.awt.Color(128, 128, 0), + "olivedrab" -> new java.awt.Color(107, 142, 35), + "orange" -> new java.awt.Color(255, 165, 0), + "orangered" -> new java.awt.Color(255, 69, 0), + "orchid" -> new java.awt.Color(218, 112, 214), + "palegoldenrod" -> new java.awt.Color(238, 232, 170), + "palegreen" -> new java.awt.Color(152, 251, 152), + "paleturquoise" -> new java.awt.Color(175, 238, 238), + "palevioletred" -> new java.awt.Color(219, 112, 147), + "papayawhip" -> new java.awt.Color(255, 239, 213), + "peachpuff" -> new java.awt.Color(255, 218, 185), + "peru" -> new java.awt.Color(205, 133, 63), + "pink" -> new java.awt.Color(255, 192, 203), + "plum" -> new java.awt.Color(221, 160, 221), + "powderblue" -> new java.awt.Color(176, 224, 230), + "purple" -> new java.awt.Color(128, 0, 128), + "red" -> new java.awt.Color(255, 0, 0), + "rosybrown" -> new java.awt.Color(188, 143, 143), + "royalblue" -> new java.awt.Color( 65, 105, 225), + "saddlebrown" -> new java.awt.Color(139, 69, 19), + "salmon" -> new java.awt.Color(250, 128, 114), + "sandybrown" -> new java.awt.Color(244, 164, 96), + "seagreen" -> new java.awt.Color( 46, 139, 87), + "seashell" -> new java.awt.Color(255, 245, 238), + "sienna" -> new java.awt.Color(160, 82, 45), + "silver" -> new java.awt.Color(192, 192, 192), + "skyblue" -> new java.awt.Color(135, 206, 235), + "slateblue" -> new java.awt.Color(106, 90, 205), + "slategray" -> new java.awt.Color(112, 128, 144), + "slategrey" -> new java.awt.Color(112, 128, 144), + "snow" -> new java.awt.Color(255, 250, 250), + "springgreen" -> new java.awt.Color( 0, 255, 127), + "steelblue" -> new java.awt.Color( 70, 130, 180), + "tan" -> new java.awt.Color(210, 180, 140), + "teal" -> new java.awt.Color( 0, 128, 128), + "thistle" -> new java.awt.Color(216, 191, 216), + "tomato" -> new java.awt.Color(255, 99, 71), + "turquoise" -> new java.awt.Color( 64, 224, 208), + "violet" -> new java.awt.Color(238, 130, 238), + "wheat" -> new java.awt.Color(245, 222, 179), + "white" -> new java.awt.Color(255, 255, 255), + "whitesmoke" -> new java.awt.Color(245, 245, 245), + "yellow" -> new java.awt.Color(255, 255, 0), + "yellowgreen" -> new java.awt.Color(154, 205, 50)) } diff --git a/src/main/scala/net/kogics/kojo/staging/KColor.scala b/src/main/scala/net/kogics/kojo/staging/KColor.scala index d70208818..9090f07ce 100644 --- a/src/main/scala/net/kogics/kojo/staging/KColor.scala +++ b/src/main/scala/net/kogics/kojo/staging/KColor.scala @@ -17,8 +17,8 @@ package net.kogics.kojo.staging import java.awt.Color -// if I make this a trait to mix into Builtins, the color completions -// inside the C builtin do not show up nicely +// if I make this a trait to mix into Builtins, the color completions +// inside the C builtin do not show up nicely // because the colors get into C via inheritence, and show up lower down // in the list of completions object KColor { @@ -57,6 +57,6 @@ object KColor { "cyan" -> cyan, "noColor" -> noColor ) - + lazy val knownColors = knownColorsMap.keySet.toList } diff --git a/src/main/scala/net/kogics/kojo/staging/KeyCodes.scala b/src/main/scala/net/kogics/kojo/staging/KeyCodes.scala index fc93f70b4..e5c44f714 100644 --- a/src/main/scala/net/kogics/kojo/staging/KeyCodes.scala +++ b/src/main/scala/net/kogics/kojo/staging/KeyCodes.scala @@ -15,68 +15,64 @@ package net.kogics.kojo.staging -/** Copied from java.awt.event.KeyEvent - */ +/** + * Copied from java.awt.event.KeyEvent + */ class KeyCodes { val VK_ENTER = '\n'; val VK_BACK_SPACE = '\b'; val VK_TAB = '\t'; val VK_CANCEL = 0x03; - val VK_CLEAR = 0x0c; + val VK_CLEAR = 0x0C; val VK_SHIFT = 0x10; val VK_CONTROL = 0x11; val VK_ALT = 0x12; val VK_PAUSE = 0x13; val VK_CAPS_LOCK = 0x14; - val VK_ESCAPE = 0x1b; + val VK_ESCAPE = 0x1B; val VK_SPACE = 0x20; val VK_PAGE_UP = 0x21; val VK_PAGE_DOWN = 0x22; val VK_END = 0x23; val VK_HOME = 0x24; - - /** Constant for the non-numpad left arrow key. - * @see - * #VK_KP_LEFT - */ + /** + * Constant for the non-numpad left arrow key. + * @see #VK_KP_LEFT + */ val VK_LEFT = 0x25; - - /** Constant for the non-numpad up arrow key. - * @see - * #VK_KP_UP - */ + /** + * Constant for the non-numpad up arrow key. + * @see #VK_KP_UP + */ val VK_UP = 0x26; - - /** Constant for the non-numpad right arrow key. - * @see - * #VK_KP_RIGHT - */ + /** + * Constant for the non-numpad right arrow key. + * @see #VK_KP_RIGHT + */ val VK_RIGHT = 0x27; - - /** Constant for the non-numpad down arrow key. - * @see - * #VK_KP_DOWN - */ + /** + * Constant for the non-numpad down arrow key. + * @see #VK_KP_DOWN + */ val VK_DOWN = 0x28; - - /** Constant for the comma key, "," - */ - val VK_COMMA = 0x2c; - - /** Constant for the minus key, "-" - * @since 1.2 - */ - val VK_MINUS = 0x2d; - - /** Constant for the period key, "." - */ - val VK_PERIOD = 0x2e; - - /** Constant for the forward slash key, "/" - */ - val VK_SLASH = 0x2f; - + /** + * Constant for the comma key, "," + */ + val VK_COMMA = 0x2C; + /** + * Constant for the minus key, "-" + * @since 1.2 + */ + val VK_MINUS = 0x2D; + /** + * Constant for the period key, "." + */ + val VK_PERIOD = 0x2E; + /** + * Constant for the forward slash key, "/" + */ + val VK_SLASH = 0x2F; /** VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */ val VK_0 = 0x30; val VK_1 = 0x31; @@ -88,15 +84,14 @@ class KeyCodes { val VK_7 = 0x37; val VK_8 = 0x38; val VK_9 = 0x39; - - /** Constant for the semicolon key, ";" - */ - val VK_SEMICOLON = 0x3b; - - /** Constant for the equals key, "=" - */ - val VK_EQUALS = 0x3d; - + /** + * Constant for the semicolon key, ";" + */ + val VK_SEMICOLON = 0x3B; + /** + * Constant for the equals key, "=" + */ + val VK_EQUALS = 0x3D; /** VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */ val VK_A = 0x41; val VK_B = 0x42; @@ -107,12 +102,12 @@ class KeyCodes { val VK_G = 0x47; val VK_H = 0x48; val VK_I = 0x49; - val VK_J = 0x4a; - val VK_K = 0x4b; - val VK_L = 0x4c; - val VK_M = 0x4d; - val VK_N = 0x4e; - val VK_O = 0x4f; + val VK_J = 0x4A; + val VK_K = 0x4B; + val VK_L = 0x4C; + val VK_M = 0x4D; + val VK_N = 0x4E; + val VK_O = 0x4F; val VK_P = 0x50; val VK_Q = 0x51; val VK_R = 0x52; @@ -123,5 +118,5 @@ class KeyCodes { val VK_W = 0x57; val VK_X = 0x58; val VK_Y = 0x59; - val VK_Z = 0x5a; + val VK_Z = 0x5A; } diff --git a/src/main/scala/net/kogics/kojo/staging/Sprite.scala b/src/main/scala/net/kogics/kojo/staging/Sprite.scala index 7632912ad..05ae9dc41 100644 --- a/src/main/scala/net/kogics/kojo/staging/Sprite.scala +++ b/src/main/scala/net/kogics/kojo/staging/Sprite.scala @@ -16,10 +16,11 @@ package net.kogics.kojo package staging +import util.Utils +import core._ + import edu.umd.cs.piccolo._ import edu.umd.cs.piccolo.nodes._ -import net.kogics.kojo.core._ -import net.kogics.kojo.util.Utils object Sprite { def apply(p1: Point, fname: String) = { @@ -42,9 +43,9 @@ class Sprite(val origin: Point, fname: String) extends BaseShape { val width = image.getWidth val height = image.getHeight - + image.getTransformReference(true).setToScale(1, -1) - image.setOffset(-width / 2, height / 2) + image.setOffset(-width/2, height/2) imageHolder.addChild(image) imageHolder.setOffset(origin.x, origin.y) diff --git a/src/main/scala/net/kogics/kojo/staging/SvgPath.scala b/src/main/scala/net/kogics/kojo/staging/SvgPath.scala index 3f6c6b43a..6726fb915 100644 --- a/src/main/scala/net/kogics/kojo/staging/SvgPath.scala +++ b/src/main/scala/net/kogics/kojo/staging/SvgPath.scala @@ -16,9 +16,15 @@ package net.kogics.kojo package staging +import util.Utils +import edu.umd.cs.piccolo._ import edu.umd.cs.piccolo.nodes._ -import net.kogics.kojo.core._ -import net.kogics.kojo.util.Utils +import edu.umd.cs.piccolo.util._ +import edu.umd.cs.piccolo.event._ + +import javax.swing._ + +import core._ class SvgPath(val path: PPath) extends StrokedShape { val origin = Point(path.getX, path.getY) @@ -29,7 +35,7 @@ object SvgPath { var pPath: PPath = _ // case class Point(x: Float, y: Float) - + type CurvePointGroup = (Point, Point, Point) type QuadPointGroup = (Point, Point) @@ -45,8 +51,7 @@ object SvgPath { var t2: Point = _ var t: Point = _ - def adjust(p: Point): Point = p match { - case Point(x, y) => + def adjust(p: Point): Point = p match { case Point(x, y) => adjust(x.toFloat, y.toFloat) } def adjust(x: Float, y: Float): Point @@ -62,6 +67,7 @@ object SvgPath { def complementY(x: Float) = Point(x, currentPoint.y) } + trait RelativeCoords extends Coords { def adjust(x: Float, y: Float) = Point(currentPoint.x + x, currentPoint.y + y) @@ -72,91 +78,100 @@ object SvgPath { Point(currentPoint.x + x, currentPoint.y) } - sealed abstract class SVGCmd { def apply(): Unit } + abstract sealed class SVGCmd { def apply (): Unit } trait MoveTo extends Coords { val pts: List[Point] def foreach(fn: Point => Unit): Unit = { - pts.tail.map(adjust(_)).foreach(fn) + pts.tail map (adjust(_)) foreach fn currentPoint = adjust(pts.last) } - def apply() = { - if (pts.nonEmpty) adjust(pts.head) match { - case Point(x, y) => + def apply () = { + if (pts.nonEmpty) adjust(pts.head) match { case Point(x, y) => pPath.moveTo(x.toFloat, y.toFloat) currentPoint = adjust(pts.head) } - this.foreach { - case Point(x, y) => + this foreach { case Point(x, y) => pPath.lineTo(x.toFloat, y.toFloat) } } } - case class MoveToAbs(pts: List[Point]) extends SVGCmd with MoveTo with AbsoluteCoords + case class MoveToAbs(pts: List[Point]) extends SVGCmd + with MoveTo + with AbsoluteCoords - case class MoveToRel(pts: List[Point]) extends SVGCmd with MoveTo with RelativeCoords + case class MoveToRel(pts: List[Point]) extends SVGCmd + with MoveTo + with RelativeCoords trait LineTo extends Coords { val pts: List[Point] def foreach(fn: Point => Unit): Unit = { - pts.map(adjust).foreach(fn) + pts map adjust foreach fn currentPoint = pts.last } - def apply() = this.foreach { - case (Point(x, y)) => + def apply () = this foreach { case(Point(x, y)) => pPath.lineTo(x.toFloat, y.toFloat) } } - case class LineToAbs(pts: List[Point]) extends SVGCmd with LineTo with AbsoluteCoords + case class LineToAbs(pts: List[Point]) extends SVGCmd + with LineTo + with AbsoluteCoords - case class LineToRel(pts: List[Point]) extends SVGCmd with LineTo with RelativeCoords + case class LineToRel(pts: List[Point]) extends SVGCmd + with LineTo + with RelativeCoords trait HorizontalLine extends Coords { val xs: List[Float] def foreach(fn: Point => Unit): Unit = { - xs.foreach { - case x0: Float => + xs foreach { case x0: Float => t = complementY(x0) fn(t) } currentPoint = t } - def apply() = this.foreach { - case (Point(x, y)) => + def apply () = this foreach { case(Point(x, y)) => pPath.lineTo(x.toFloat, y.toFloat) } } - case class HLineToAbs(xs: List[Float]) extends SVGCmd with HorizontalLine with AbsoluteCoords + case class HLineToAbs(xs: List[Float]) extends SVGCmd + with HorizontalLine + with AbsoluteCoords - case class HLineToRel(xs: List[Float]) extends SVGCmd with HorizontalLine with RelativeCoords + case class HLineToRel(xs: List[Float]) extends SVGCmd + with HorizontalLine + with RelativeCoords trait VerticalLine extends Coords { val ys: List[Float] def foreach(fn: Point => Unit): Unit = { - ys.foreach { - case y0: Float => + ys foreach { case y0: Float => t = complementX(y0) fn(t) } currentPoint = t } - def apply() = this.foreach { - case (Point(x, y)) => + def apply () = this foreach { case(Point(x, y)) => pPath.lineTo(x.toFloat, y.toFloat) } } - case class VLineToAbs(ys: List[Float]) extends SVGCmd with VerticalLine with AbsoluteCoords + case class VLineToAbs(ys: List[Float]) extends SVGCmd + with VerticalLine + with AbsoluteCoords - case class VLineToRel(ys: List[Float]) extends SVGCmd with VerticalLine with RelativeCoords + case class VLineToRel(ys: List[Float]) extends SVGCmd + with VerticalLine + with RelativeCoords trait Curve extends Coords { val cs: List[CurvePointGroup] def foreach(fn: CurvePointGroup => Unit): Unit = { - cs.foreach { + cs foreach { case (p1, p2, p) => t1 = adjust(p1) t2 = adjust(p2) @@ -166,20 +181,23 @@ object SvgPath { currentControlPoint = t2 currentPoint = t } - def apply() = this.foreach { - case (Point(x1, y1), Point(x2, y2), Point(x3, y3)) => + def apply () = this foreach { case(Point(x1, y1), Point(x2, y2), Point(x3, y3)) => pPath.curveTo(x1.toFloat, y1.toFloat, x2.toFloat, y2.toFloat, x3.toFloat, y3.toFloat) } } - case class CurveToAbs(cs: List[CurvePointGroup]) extends SVGCmd with Curve with AbsoluteCoords + case class CurveToAbs(cs: List[CurvePointGroup]) extends SVGCmd + with Curve + with AbsoluteCoords - case class CurveToRel(cs: List[CurvePointGroup]) extends SVGCmd with Curve with RelativeCoords + case class CurveToRel(cs: List[CurvePointGroup]) extends SVGCmd + with Curve + with RelativeCoords trait SmoothCurve extends Coords { val cs: List[(Point, Point)] def foreach(fn: CurvePointGroup => Unit): Unit = { - cs.foreach { + cs foreach { case (p2, p) => t1 = reflectedControlPoint t2 = adjust(p2) @@ -189,20 +207,23 @@ object SvgPath { currentControlPoint = t2 currentPoint = t } - def apply() = this.foreach { - case (Point(x1, y1), Point(x2, y2), Point(x3, y3)) => + def apply () = this foreach { case(Point(x1, y1), Point(x2, y2), Point(x3, y3)) => pPath.curveTo(x1.toFloat, y1.toFloat, x2.toFloat, y2.toFloat, x3.toFloat, y3.toFloat) } } - case class SmoothCurveToAbs(cs: List[(Point, Point)]) extends SVGCmd with SmoothCurve with AbsoluteCoords + case class SmoothCurveToAbs(cs: List[(Point, Point)]) extends SVGCmd + with SmoothCurve + with AbsoluteCoords - case class SmoothCurveToRel(cs: List[(Point, Point)]) extends SVGCmd with SmoothCurve with RelativeCoords + case class SmoothCurveToRel(cs: List[(Point, Point)]) extends SVGCmd + with SmoothCurve + with RelativeCoords trait QuadBezier extends Coords { val cs: List[QuadPointGroup] def foreach(fn: QuadPointGroup => Unit): Unit = { - cs.foreach { + cs foreach { case (p1: Point, p: Point) => t1 = adjust(p1) t = adjust(p) @@ -211,18 +232,21 @@ object SvgPath { currentControlPoint = t1 currentPoint = t } - def apply() = this.foreach { - case (Point(x1, y1), Point(x2, y2)) => + def apply () = this foreach { case(Point(x1, y1), Point(x2, y2)) => pPath.quadTo(x1.toFloat, y1.toFloat, x2.toFloat, y2.toFloat) } } - case class QuadBezierAbs(cs: List[QuadPointGroup]) extends SVGCmd with QuadBezier with AbsoluteCoords - case class QuadBezierRel(cs: List[QuadPointGroup]) extends SVGCmd with QuadBezier with RelativeCoords + case class QuadBezierAbs(cs: List[QuadPointGroup]) extends SVGCmd + with QuadBezier + with AbsoluteCoords + case class QuadBezierRel(cs: List[QuadPointGroup]) extends SVGCmd + with QuadBezier + with RelativeCoords trait SmoothQuadBezier extends Coords { val cs: List[Point] def foreach(fn: QuadPointGroup => Unit): Unit = { - cs.foreach { + cs foreach { case p => t1 = reflectedControlPoint t = adjust(p) @@ -231,117 +255,121 @@ object SvgPath { currentControlPoint = t1 currentPoint = t } - def apply() = this.foreach { - case (Point(x1, y1), Point(x2, y2)) => + def apply () = this foreach { case(Point(x1, y1), Point(x2, y2)) => pPath.quadTo(x1.toFloat, y1.toFloat, x2.toFloat, y2.toFloat) } } - case class SmoothQuadBezierAbs(cs: List[Point]) extends SVGCmd with SmoothQuadBezier with AbsoluteCoords + case class SmoothQuadBezierAbs(cs: List[Point]) extends SVGCmd + with SmoothQuadBezier + with AbsoluteCoords - case class SmoothQuadBezierRel(cs: List[Point]) extends SVGCmd with SmoothQuadBezier with RelativeCoords + case class SmoothQuadBezierRel(cs: List[Point]) extends SVGCmd + with SmoothQuadBezier + with RelativeCoords - case class EllipticalArcAbs(as: List[_]) extends SVGCmd with AbsoluteCoords { - def apply() = {} + case class EllipticalArcAbs(as: List[_]) extends SVGCmd + with AbsoluteCoords { + def apply () = {} } - case class EllipticalArcRel(as: List[_]) extends SVGCmd with RelativeCoords { - def apply() = {} + case class EllipticalArcRel(as: List[_]) extends SVGCmd + with RelativeCoords { + def apply () = {} } case class Close() extends SVGCmd { - def apply() = pPath.closePath + def apply () = pPath.closePath } import scala.util.parsing.combinator._ class SVGPathParser extends JavaTokenParsers { - def drawto: Parser[Any] = - lineto | closepath | hlineto | vlineto | curveto | sCurveto | qBezierto | sqBezierto | elliptArc - def svgpath: Parser[Any] = rep(pathcommand) - def pathcommand: Parser[Any] = moveto ~ rep(drawto) ^^ { - case a ~ b => (a, b) + def drawto: Parser[Any] = lineto | closepath | hlineto | vlineto | curveto | sCurveto | qBezierto | sqBezierto | elliptArc + def svgpath: Parser[Any] = rep(pathcommand) + def pathcommand: Parser[Any] = moveto~rep(drawto) ^^ { + case a~b => (a, b) } - def closepath: Parser[SVGCmd] = ("Z" | "z") ^^ { + def closepath: Parser[SVGCmd] = ("Z" | "z") ^^ { case _ => Close() } - def moveto: Parser[SVGCmd] = ("M" | "m") ~ repsep(coordPair, oc) ^^ { - case "M" ~ b => MoveToAbs(b) - case "m" ~ b => MoveToRel(b) - case _ => throw new RuntimeException("Parse error") - } - def lineto: Parser[SVGCmd] = ("L" | "l") ~ repsep(coordPair, oc) ^^ { - case "L" ~ b => LineToAbs(b) - case "l" ~ b => LineToRel(b) - case _ => throw new RuntimeException("Parse error") - } - def hlineto: Parser[SVGCmd] = ("H" | "h") ~ repsep(number, oc) ^^ { - case "H" ~ b => HLineToAbs(b) - case "h" ~ b => HLineToRel(b) - case _ => throw new RuntimeException("Parse error") - } - def vlineto: Parser[SVGCmd] = ("V" | "v") ~ repsep(number, oc) ^^ { - case "V" ~ b => VLineToAbs(b) - case "v" ~ b => VLineToRel(b) - case _ => throw new RuntimeException("Parse error") - } - def curveto: Parser[SVGCmd] = ("C" | "c") ~ repsep(coordPairTri, oc) ^^ { - case "C" ~ b => CurveToAbs(b) - case "c" ~ b => CurveToRel(b) - case _ => throw new RuntimeException("Parse error") - } - def sCurveto: Parser[SVGCmd] = ("S" | "s") ~ repsep(coordPairDbl, oc) ^^ { - case "S" ~ b => SmoothCurveToAbs(b) - case "s" ~ b => SmoothCurveToRel(b) - case _ => throw new RuntimeException("Parse error") - } - def qBezierto: Parser[SVGCmd] = ("Q" | "q") ~ repsep(coordPairDbl, oc) ^^ { - case "Q" ~ b => QuadBezierAbs(b) - case "q" ~ b => QuadBezierRel(b) - case _ => throw new RuntimeException("Parse error") - } - def sqBezierto: Parser[SVGCmd] = ("T" | "t") ~ repsep(coordPair, oc) ^^ { - case "T" ~ b => SmoothQuadBezierAbs(b) - case "t" ~ b => SmoothQuadBezierRel(b) - case _ => throw new RuntimeException("Parse error") - } - def elliptArc: Parser[Any] = ("A" | "a") ~ repsep(arcArg, oc) ^^ { - case "A" ~ b => EllipticalArcAbs(b) - case "a" ~ b => EllipticalArcRel(b) - case _ => throw new RuntimeException("Parse error") - } - def coordPair: Parser[Point] = number ~ oc ~ number ^^ { - case a ~ c ~ b => Point(a.asInstanceOf[Float], b.asInstanceOf[Float]) + def moveto: Parser[SVGCmd] = ("M" | "m")~repsep(coordPair, oc) ^^ { + case "M"~b => MoveToAbs(b) + case "m"~b => MoveToRel(b) + case _ => throw new RuntimeException("Parse error") + } + def lineto: Parser[SVGCmd] = ("L" | "l")~repsep(coordPair, oc) ^^ { + case "L"~b => LineToAbs(b) + case "l"~b => LineToRel(b) + case _ => throw new RuntimeException("Parse error") + } + def hlineto: Parser[SVGCmd] = ("H" | "h")~repsep(number, oc) ^^ { + case "H"~b => HLineToAbs(b) + case "h"~b => HLineToRel(b) + case _ => throw new RuntimeException("Parse error") + } + def vlineto: Parser[SVGCmd] = ("V" | "v")~repsep(number, oc) ^^ { + case "V"~b => VLineToAbs(b) + case "v"~b => VLineToRel(b) + case _ => throw new RuntimeException("Parse error") + } + def curveto: Parser[SVGCmd] = ("C" | "c")~repsep(coordPairTri, oc) ^^ { + case "C"~b => CurveToAbs(b) + case "c"~b => CurveToRel(b) + case _ => throw new RuntimeException("Parse error") + } + def sCurveto: Parser[SVGCmd] = ("S" | "s")~repsep(coordPairDbl, oc) ^^ { + case "S"~b => SmoothCurveToAbs(b) + case "s"~b => SmoothCurveToRel(b) + case _ => throw new RuntimeException("Parse error") + } + def qBezierto: Parser[SVGCmd] = ("Q" | "q")~repsep(coordPairDbl, oc) ^^ { + case "Q"~b => QuadBezierAbs(b) + case "q"~b => QuadBezierRel(b) + case _ => throw new RuntimeException("Parse error") + } + def sqBezierto: Parser[SVGCmd] = ("T" | "t")~repsep(coordPair, oc) ^^ { + case "T"~b => SmoothQuadBezierAbs(b) + case "t"~b => SmoothQuadBezierRel(b) + case _ => throw new RuntimeException("Parse error") + } + def elliptArc: Parser[Any] = ("A" | "a")~repsep(arcArg, oc) ^^ { + case "A"~b => EllipticalArcAbs(b) + case "a"~b => EllipticalArcRel(b) + case _ => throw new RuntimeException("Parse error") + } + def coordPair: Parser[Point] = number~oc~number ^^ { + case a~c~b => Point(a.asInstanceOf[Float], b.asInstanceOf[Float]) } def coordPairDbl: Parser[QuadPointGroup] = - coordPair ~ oc ~ coordPair ^^ { - case a ~ c ~ b => (a, b) + coordPair~oc~coordPair ^^ { + case a~c~b => (a, b) } def coordPairTri: Parser[CurvePointGroup] = - coordPair ~ oc ~ coordPair ~ oc ~ coordPair ^^ { - case a ~ d ~ b ~ e ~ c => (a, b, c) + coordPair~oc~coordPair~oc~coordPair ^^ { + case a~d~b~e~c => (a, b, c) } - def arcArg: Parser[Any] = - number ~ oc ~ number ~ oc ~ number ~ oc ~ flag ~ oc ~ flag ~ oc ~ coordPair ^^ { - case n1 ~ a ~ n2 ~ b ~ n3 ~ c ~ f1 ~ d ~ f2 ~ e ~ cp => (n1, n2, n3, f1, f2, cp) + def arcArg: Parser[Any] = + number~oc~number~oc~number~oc~flag~oc~flag~oc~coordPair ^^ { + case n1~a~n2~b~n3~c~f1~d~f2~e~cp => (n1, n2, n3, f1, f2, cp) } - def flag: Parser[Int] = ("0" | "1") ^^ (_.toInt) - def oc: Parser[Any] = opt(",") - def number: Parser[Float] = floatingPointNumber ^^ (_.toFloat) + def flag: Parser[Int] = ("0" | "1") ^^ (_.toInt) + def oc: Parser[Any] = opt(",") + def number: Parser[Float] = floatingPointNumber ^^ (_.toFloat) } object ParseExpr extends SVGPathParser { - def apply(d: String) = parseAll(svgpath, d) + def apply (d: String) = parseAll(svgpath, d) } def apply(d: String) = { pPath = new PPath - + try { ParseExpr(d).get match { case List((move: SVGCmd, drawcmds)) => move() - drawcmds.asInstanceOf[List[SVGCmd]].foreach(_()) + drawcmds.asInstanceOf[List[SVGCmd]] foreach (_()) case Nil => } } diff --git a/src/main/scala/net/kogics/kojo/staging/color.scala b/src/main/scala/net/kogics/kojo/staging/color.scala index 086a400d0..4cc892951 100644 --- a/src/main/scala/net/kogics/kojo/staging/color.scala +++ b/src/main/scala/net/kogics/kojo/staging/color.scala @@ -16,15 +16,19 @@ package net.kogics.kojo package staging -import net.kogics.kojo.kmath.{ Kmath => Math } -import net.kogics.kojo.staging.Impl.API +import kmath.{Kmath => Math} + +import javax.swing._ + +import core._ +import Impl.API object ColorMaker { - def apply(mode: GRAY) = new GrayColorMaker(mode) + def apply(mode: GRAY) = new GrayColorMaker(mode) def apply(mode: GRAYA) = new GrayAlphaColorMaker(mode) - def apply(mode: RGB) = new RgbColorMaker(mode) - def apply(mode: RGBA) = new RgbAlphaColorMaker(mode) - def apply(mode: HSB) = new HsbColorMaker(mode) + def apply(mode: RGB) = new RgbColorMaker(mode) + def apply(mode: RGBA) = new RgbAlphaColorMaker(mode) + def apply(mode: HSB) = new HsbColorMaker(mode) def color(s: String) = s match { case ColorName(cc) => cc @@ -100,7 +104,7 @@ class HsbColorMaker(mode: HSB) extends ColorMaker { } } -class RichColor(val c: java.awt.Color) { +class RichColor (val c: java.awt.Color) { type Color = java.awt.Color def alpha = c.getAlpha def red = c.getRed diff --git a/src/main/scala/net/kogics/kojo/staging/complexshapes.scala b/src/main/scala/net/kogics/kojo/staging/complexshapes.scala index feb270898..7cb4a8806 100644 --- a/src/main/scala/net/kogics/kojo/staging/complexshapes.scala +++ b/src/main/scala/net/kogics/kojo/staging/complexshapes.scala @@ -16,14 +16,20 @@ package net.kogics.kojo package staging +import util.Utils +import edu.umd.cs.piccolo._ import edu.umd.cs.piccolo.nodes._ -import net.kogics.kojo.core._ -import net.kogics.kojo.util.Utils +import edu.umd.cs.piccolo.util._ +import edu.umd.cs.piccolo.event._ + +import javax.swing._ + +import core._ class Polyline(val points: Seq[Point]) extends PolyShape with StrokedShape { - val path = PPath.createPolyline(points.map { - case Point(x, y) => new java.awt.geom.Point2D.Double(x, y) - }.toArray) + val path = PPath.createPolyline((points map { + case Point(x, y) => new java.awt.geom.Point2D.Double(x, y) + }).toArray) override def toString = "Staging.Polyline(" + points + ")" } @@ -36,9 +42,9 @@ object Polyline { } class Polygon(val points: Seq[Point]) extends PolyShape with StrokedShape { - val path = PPath.createPolyline(points.map { - case Point(x, y) => new java.awt.geom.Point2D.Double(x, y) - }.toArray) + val path = PPath.createPolyline((points map { + case Point(x, y) => new java.awt.geom.Point2D.Double(x, y) + }).toArray) path.closePath override def toString = "Staging.Polygon(" + points + ")" @@ -55,7 +61,7 @@ class LinesShape(val points: Seq[Point]) extends PolyShape with StrokedShape { val path = new PPath def init = { - points.grouped(2).foreach { + points grouped(2) foreach { case Nil => case Seq(Point(x1, y1), Point(x2, y2)) => path.moveTo(x1.toFloat, y1.toFloat) @@ -80,7 +86,7 @@ class TrianglesShape(val points: Seq[Point]) extends PolyShape with StrokedShape val path = new PPath def init = { - points.grouped(3).foreach { + points grouped(3) foreach { case Nil => case Seq(Point(x0, y0), Point(x1, y1), Point(x2, y2)) => path.moveTo(x0.toFloat, y0.toFloat) @@ -107,7 +113,7 @@ class TriangleStripShape(val points: Seq[Point]) extends PolyShape with StrokedS val path = new PPath def init = { - points.sliding(3).foreach { + points sliding(3) foreach { case Nil => case Seq(Point(x0, y0), Point(x1, y1), Point(x2, y2)) => path.moveTo(x0.toFloat, y0.toFloat) @@ -134,7 +140,7 @@ class QuadsShape(val points: Seq[Point]) extends PolyShape with StrokedShape { val path = new PPath def init = { - points.grouped(4).foreach { + points grouped(4) foreach { case Nil => case Seq(Point(x0, y0), Point(x1, y1), Point(x2, y2), Point(x3, y3)) => path.moveTo(x0.toFloat, y0.toFloat) @@ -190,7 +196,7 @@ class HexShape(val points: Seq[Point]) extends PolyShape with StrokedShape { val path = new PPath def init = { - points.grouped(6).foreach { + points grouped(6) foreach { case Nil => case Seq(Point(x0, y0), Point(x1, y1), Point(x2, y2), Point(x3, y3), Point(x4, y4), Point(x5, y5)) => path.moveTo(x0.toFloat, y0.toFloat) @@ -216,11 +222,12 @@ object HexShape { } } -class TriangleFanShape(override val origin: Point, val points: Seq[Point]) extends PolyShape with StrokedShape { +class TriangleFanShape(override val origin: Point, val points: Seq[Point]) extends PolyShape + with StrokedShape { val path = new PPath def init = { - points.grouped(2).foreach { + points grouped(2) foreach { case Nil => case Seq(Point(x1, y1), Point(x2, y2)) => path.moveTo(origin.x.toFloat, origin.y.toFloat) diff --git a/src/main/scala/net/kogics/kojo/staging/inputs.scala b/src/main/scala/net/kogics/kojo/staging/inputs.scala index ef1aaeb1e..90ed122ae 100644 --- a/src/main/scala/net/kogics/kojo/staging/inputs.scala +++ b/src/main/scala/net/kogics/kojo/staging/inputs.scala @@ -16,15 +16,15 @@ package net.kogics.kojo package staging +import Impl.API import core.Point import edu.umd.cs.piccolo.event.PBasicInputEventHandler import edu.umd.cs.piccolo.event.PInputEvent import util.Utils -import Impl.API object Inputs { import edu.umd.cs.piccolo.event._ - // import java.awt.event.InputEvent + //import java.awt.event.InputEvent @volatile var mousePos: Point = API.O @@ -87,64 +87,67 @@ object Inputs { Utils.runInSwingThread { val iel = new PBasicInputEventHandler { // This method is invoked when a node gains the keyboard focus. - override def keyboardFocusGained(e: PInputEvent): Unit = {} + override def keyboardFocusGained(e: PInputEvent): Unit = { + } // This method is invoked when a node loses the keyboard focus. - override def keyboardFocusLost(e: PInputEvent): Unit = {} + override def keyboardFocusLost(e: PInputEvent): Unit = { + } // Will get called whenever a key has been pressed down. override def keyPressed(e: PInputEvent): Unit = { val evtCode = Utils.getKeyCode(e) if (heldReleasedKeys contains evtCode) { // system generated release - eat it up - heldReleasedKeys.remove(evtCode) + heldReleasedKeys remove evtCode // but call key press handlers anyway - keyPressedHandler.foreach { _.apply(e) } + keyPressedHandler.foreach { _ apply e } } else { pressedKeys.add(evtCode) - keyPressedHandler.foreach { _.apply(e) } + keyPressedHandler.foreach { _ apply e } } } // Will get called whenever a key has been released. override def keyReleased(e: PInputEvent): Unit = { val evtCode = Utils.getKeyCode(e) - heldReleasedKeys.add(evtCode) + heldReleasedKeys add evtCode Utils.schedule(0.002) { if (heldReleasedKeys contains evtCode) { // actual key release - pressedKeys.remove(evtCode) - heldReleasedKeys.remove(evtCode) - keyReleasedHandler.foreach { _.apply(e) } + pressedKeys remove evtCode + heldReleasedKeys remove evtCode + keyReleasedHandler.foreach { _ apply e } } } } // Will be called at the end of a full keystroke (down then up). - override def keyTyped(e: PInputEvent): Unit = {} + override def keyTyped(e: PInputEvent): Unit = { + } // Will be called at the end of a full click (mouse pressed followed by mouse released). override def mouseClicked(e: PInputEvent): Unit = { super.mouseClicked(e) val p = e.getPosition mousePos = Point(p.getX, p.getY) mouseBtn = e.getButton - mouseClickHandler.foreach { _.apply(e) } + mouseClickHandler.foreach { _ apply e } } // Will be called when a drag is occurring. override def mouseDragged(e: PInputEvent): Unit = { super.mouseDragged(e) val p = e.getPosition mousePos = Point(p.getX, p.getY) - mouseDragHandler.foreach { _.apply(e) } + mouseDragHandler.foreach { _ apply e } } // Will be invoked when the mouse enters a specified region. override def mouseEntered(e: PInputEvent): Unit = { super.mouseEntered(e) - // e.pushCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)) + //e.pushCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)) val p = e.getPosition mousePos = Point(p.getX, p.getY) } // Will be invoked when the mouse leaves a specified region. override def mouseExited(e: PInputEvent): Unit = { super.mouseExited(e) - // e.popCursor + //e.popCursor val p = e.getPosition mousePos = Point(p.getX, p.getY) // mousePressedFlag = false @@ -154,7 +157,7 @@ object Inputs { super.mouseMoved(e) val p = e.getPosition mousePos = Point(p.getX, p.getY) - mouseMoveHandler.foreach { _.apply(e) } + mouseMoveHandler.foreach { _ apply e } } // Will be called when a mouse button is pressed down. override def mousePressed(e: PInputEvent): Unit = { diff --git a/src/main/scala/net/kogics/kojo/staging/screen.scala b/src/main/scala/net/kogics/kojo/staging/screen.scala index 84351f501..a54d33a17 100644 --- a/src/main/scala/net/kogics/kojo/staging/screen.scala +++ b/src/main/scala/net/kogics/kojo/staging/screen.scala @@ -16,13 +16,16 @@ package net.kogics.kojo package staging -import javax.swing._ - -import core._ import edu.umd.cs.piccolo._ -import edu.umd.cs.piccolo.event._ import edu.umd.cs.piccolo.nodes._ import edu.umd.cs.piccolo.util._ +import edu.umd.cs.piccolo.event._ + +//import net.kogics.kojo.util.Utils + +import javax.swing._ + +import core._ object Screen { val rect = Bounds(0, 0, 0, 0) @@ -30,7 +33,7 @@ object Screen { def size(width: Int, height: Int) = { // TODO 560 is a value that works on my system, should be less ad-hoc val factor = 560 - val xfactor = factor / (if (width < 0) -height.abs else height.abs) // sic! + val xfactor = factor / (if (width < 0) -(height.abs) else height.abs) // sic! val yfactor = factor / height Impl.canvas.zoomXY(xfactor, yfactor, width / 2, height / 2) rect.setRect(0, 0, width.abs, height.abs) diff --git a/src/main/scala/net/kogics/kojo/staging/simpleshapes.scala b/src/main/scala/net/kogics/kojo/staging/simpleshapes.scala index f1d5a19df..b54f46ec6 100644 --- a/src/main/scala/net/kogics/kojo/staging/simpleshapes.scala +++ b/src/main/scala/net/kogics/kojo/staging/simpleshapes.scala @@ -17,24 +17,25 @@ package net.kogics.kojo package staging -import javax.swing._ - -import core._ import edu.umd.cs.piccolo._ -import edu.umd.cs.piccolo.event._ import edu.umd.cs.piccolo.nodes._ import edu.umd.cs.piccolo.util._ -import language.postfixOps -import math._ +import edu.umd.cs.piccolo.event._ + import net.kogics.kojo.util.Utils + +import javax.swing._ + +import core._ +import math._ import Impl.API +import language.postfixOps + class Dot(val origin: Point) extends StrokedShape { val path = PPath.createLine( - origin.x.toFloat, - origin.y.toFloat, - origin.x.toFloat, - origin.y.toFloat + origin.x.toFloat, origin.y.toFloat, + origin.x.toFloat, origin.y.toFloat ) override def toString = "Staging.Dot(" + origin + ")" @@ -85,21 +86,17 @@ object Rectangle { } class RoundRectangle( - val origin: Point, - val endpoint: Point, - val curvature: Point -) extends SimpleShape - with Rounded { + val origin: Point, + val endpoint: Point, + val curvature: Point +) extends SimpleShape with Rounded { // precondition endpoint > origin require(width > 0 && height > 0, "A RoundRectangles's width and height should be more than 0.") val path = PPath.createRoundRectangle( - origin.x.toFloat, - origin.y.toFloat, - width.toFloat, - height.toFloat, - curvature.x.toFloat, - curvature.y.toFloat + origin.x.toFloat, origin.y.toFloat, + width.toFloat, height.toFloat, + curvature.x.toFloat, curvature.y.toFloat ) override def toString = @@ -115,10 +112,8 @@ object RoundRectangle { class Ellipse(val origin: Point, val endpoint: Point) extends Elliptical { val path = PPath.createEllipse( - (origin.x - radiusX).toFloat, - (origin.y - radiusY).toFloat, - width.toFloat, - height.toFloat + (origin.x - radiusX).toFloat, (origin.y - radiusY).toFloat, + width.toFloat, height.toFloat ) override def toString = "Staging.Ellipse(" + origin + "," + endpoint + ")" @@ -132,24 +127,15 @@ object Ellipse { } class Arc( - val origin: Point, - val endpoint: Point, - val start: Double, - val extent: Double, - val kind: Int + val origin: Point, val endpoint: Point, + val start: Double, val extent: Double, + val kind: Int ) extends Elliptical { val path = new PPath - path.setPathTo( - new java.awt.geom.Arc2D.Double( - origin.x - radiusX, - origin.y - radiusY, - width, - height, - -start, - -extent, - kind - ) - ) + path.setPathTo(new java.awt.geom.Arc2D.Double( + (origin.x - radiusX), (origin.y - radiusY), width, height, + -start, -extent, kind + )) override def toString = "Staging.Arc(" + origin + "," + endpoint + start + "," + extent + ")" } @@ -161,72 +147,72 @@ object Arc { } } -class Cross(val origin: Point, val endpoint: Point, val crossWidth: Double, val ratio: Double, val greek: Boolean) - extends SimpleShape - with CrossShape { +class Cross(val origin: Point, + val endpoint: Point, + val crossWidth: Double, + val ratio: Double, + val greek: Boolean) extends SimpleShape with CrossShape { val pts = crossDims(width, height, crossWidth, ratio, greek).points() - val path = PPath.createPolyline(pts.map { - case Point(x, y) => - new java.awt.geom.Point2D.Double(x + origin.x, y + origin.y) - }.toArray) + val path = PPath.createPolyline((pts map { case Point(x, y) => + new java.awt.geom.Point2D.Double(x + origin.x, y + origin.y) + }).toArray) path.closePath override def toString = "Staging.Cross(" + - origin + "," + endpoint + "," + crossWidth + "," + - ratio + "," + greek + "," + ")" + origin + "," + endpoint + "," + crossWidth + "," + + ratio + "," + greek + "," + ")" } object Cross { - def apply(origin: Point, endpoint: Point, crossWidth: Double, ratio: Double, greek: Boolean) = { + def apply(origin: Point, endpoint: Point, crossWidth: Double, ratio: Double, greek: Boolean) = + { val shape = new Cross(origin, endpoint, crossWidth, ratio, greek) Impl.figure0.addPnode(shape.node) shape } } -class CrossOutline( - val origin: Point, - val endpoint: Point, - val crossWidth: Double, - val ratio: Double, - val greek: Boolean -) extends SimpleShape - with CrossShape { +class CrossOutline(val origin: Point, + val endpoint: Point, + val crossWidth: Double, + val ratio: Double, + val greek: Boolean) extends SimpleShape with CrossShape { val pts = crossDims(width, height, crossWidth, ratio, greek).outlinePoints() - val path = PPath.createPolyline(pts.map { - case Point(x, y) => - new java.awt.geom.Point2D.Double(x + origin.x, y + origin.y) - }.toArray) + val path = PPath.createPolyline((pts map { case Point(x, y) => + new java.awt.geom.Point2D.Double(x + origin.x, y + origin.y) + }).toArray) path.closePath override def toString = "Staging.CrossOutline(" + - origin + "," + endpoint + "," + crossWidth + "," + - ratio + "," + greek + "," + ")" + origin + "," + endpoint + "," + crossWidth + "," + + ratio + "," + greek + "," + ")" } object CrossOutline { - def apply(origin: Point, endpoint: Point, crossWidth: Double, ratio: Double, greek: Boolean) = { + def apply(origin: Point, endpoint: Point, crossWidth: Double, ratio: Double, greek: Boolean) = + { val shape = new CrossOutline(origin, endpoint, crossWidth, ratio, greek) Impl.figure0.addPnode(shape.node) shape } } -class Saltire(val origin: Point, val endpoint: Point, val crossWidth: Double) extends SimpleShape { +class Saltire(val origin: Point, + val endpoint: Point, + val crossWidth: Double) extends SimpleShape { val points = Saltire.saltirePoints(width, height, crossWidth) - val path = PPath.createPolyline(points.map { - case Point(x, y) => - new java.awt.geom.Point2D.Double(x + origin.x, y + origin.y) - }.toArray) + val path = PPath.createPolyline((points map { case Point(x, y) => + new java.awt.geom.Point2D.Double(x + origin.x, y + origin.y) + }).toArray) path.closePath override def toString = "Staging.Saltire(" + origin + "," + endpoint + "," + crossWidth + ")" } object Saltire { def saltirePoints(len: Double, wid: Double, cw: Double) = { - val hl = len / 2 - val hw = wid / 2 + val hl = len / 2 + val hw = wid / 2 val hcw = cw / 2 - val my = cw * 0.36 - val mx = cw * 0.83 + val my = cw * 0.36 + val mx = cw * 0.83 List( // 0-1 3-4 // f \ / 5 @@ -237,22 +223,22 @@ object Saltire { // / A \ // d / \ 7 // c-b 9-8 - Point(0, wid), - Point(0 + hcw, wid), - Point(hl, hw + my), + Point(0, wid), + Point(0 + hcw, wid), + Point(hl, hw + my), Point(len - hcw, wid), - Point(len, wid), - Point(len, wid - hcw), - Point(hl + mx, hw), - Point(len, hcw), - Point(len, 0), + Point(len, wid), + Point(len, wid - hcw), + Point(hl + mx, hw), + Point(len, hcw), + Point(len, 0), Point(len - hcw, 0), - Point(hl, hw - my), - Point(hcw, 0), - Point(0, 0), - Point(0, hcw), - Point(hl - mx, hw), - Point(0, wid - hcw) + Point(hl, hw - my), + Point(hcw, 0), + Point(0, 0), + Point(0, hcw), + Point(hl - mx, hw), + Point(0, wid - hcw) ) } @@ -263,43 +249,44 @@ object Saltire { } } -@annotation.nowarn -class SaltireOutline(val origin: Point, val endpoint: Point, val crossWidth: Double) extends SimpleShape { +@annotation.nowarn class SaltireOutline(val origin: Point, + val endpoint: Point, + val crossWidth: Double) extends SimpleShape { val path = new PPath // TODO scale outset to crossWidth val points = Saltire.saltirePoints(width, height, crossWidth) - (points.map(origin + _).grouped(4) zipWithIndex).foreach { + (points map (origin + _) grouped(4) zipWithIndex) foreach { case (Seq(_, Point(x0, y0), Point(x1, y1), Point(x2, y2)), 0) => path.moveTo(x0.toFloat - 1, y0.toFloat) path.lineTo(x0.toFloat + 2, y0.toFloat) - path.lineTo(x1.toFloat, y1.toFloat + 1) + path.lineTo(x1.toFloat, y1.toFloat + 1) path.lineTo(x2.toFloat - 2, y2.toFloat) path.lineTo(x2.toFloat + 1, y2.toFloat) - path.lineTo(x1.toFloat, y1.toFloat - 1) + path.lineTo(x1.toFloat, y1.toFloat - 1) path.closePath case (Seq(_, Point(x0, y0), Point(x1, y1), Point(x2, y2)), 1) => - path.moveTo(x0.toFloat, y0.toFloat + 2) - path.lineTo(x0.toFloat, y0.toFloat - 1) + path.moveTo(x0.toFloat, y0.toFloat + 2) + path.lineTo(x0.toFloat, y0.toFloat - 1) path.lineTo(x1.toFloat + 4, y1.toFloat) - path.lineTo(x2.toFloat, y2.toFloat + 1) - path.lineTo(x2.toFloat, y2.toFloat - 2) + path.lineTo(x2.toFloat, y2.toFloat + 1) + path.lineTo(x2.toFloat, y2.toFloat - 2) path.lineTo(x1.toFloat - 1, y1.toFloat) path.closePath case (Seq(_, Point(x0, y0), Point(x1, y1), Point(x2, y2)), 2) => path.moveTo(x0.toFloat + 1, y0.toFloat) path.lineTo(x0.toFloat - 2, y0.toFloat) - path.lineTo(x1.toFloat, y1.toFloat - 1) + path.lineTo(x1.toFloat, y1.toFloat - 1) path.lineTo(x2.toFloat + 2, y2.toFloat) path.lineTo(x2.toFloat - 1, y2.toFloat) - path.lineTo(x1.toFloat, y1.toFloat + 1) + path.lineTo(x1.toFloat, y1.toFloat + 1) path.closePath case (Seq(_, Point(x0, y0), Point(x1, y1), Point(x2, y2)), 3) => - path.moveTo(x0.toFloat, y0.toFloat - 2) - path.lineTo(x0.toFloat, y0.toFloat + 1) + path.moveTo(x0.toFloat, y0.toFloat - 2) + path.lineTo(x0.toFloat, y0.toFloat + 1) path.lineTo(x1.toFloat - 4, y1.toFloat) - path.lineTo(x2.toFloat, y2.toFloat - 1) - path.lineTo(x2.toFloat, y2.toFloat + 2) + path.lineTo(x2.toFloat, y2.toFloat - 1) + path.lineTo(x2.toFloat, y2.toFloat + 2) path.lineTo(x1.toFloat + 1, y1.toFloat) path.closePath } @@ -334,7 +321,7 @@ class Vector(val origin: Point, val endpoint: Point, val length: Double) extends val angle = if (origin.x < endpoint.x) { math.asin((endpoint.y - origin.y) / vlength) } - else { math.Pi - math.asin((endpoint.y - origin.y) / vlength) } + else { math.Pi - math.asin((endpoint.y - origin.y) / vlength) } node.rotateAboutPoint(angle, origin.x, origin.y) @@ -351,7 +338,7 @@ object Vector { object Star { def apply(origin: Point, inner: Double, outer: Double, points: Int) = Utils.runInSwingThreadAndWait { val a = math.Pi / points // the angle between outer and inner point - val pts = Seq.tabulate(2 * points) { i => + val pts = Seq.tabulate(2 * points){ i => val aa = math.Pi / 2 + a * i if (i % 2 == 0) { origin + Point(outer * cos(aa), outer * sin(aa)) } else { origin + Point(inner * cos(aa), inner * sin(aa)) } diff --git a/src/main/scala/net/kogics/kojo/staging/staging.scala b/src/main/scala/net/kogics/kojo/staging/staging.scala index 68cde57e2..6b86d3f53 100644 --- a/src/main/scala/net/kogics/kojo/staging/staging.scala +++ b/src/main/scala/net/kogics/kojo/staging/staging.scala @@ -17,128 +17,132 @@ package net.kogics.kojo package staging +import util.Utils +import kmath.{Kmath => Math} +import core.InputAware +import core.Point import java.awt.BasicStroke -import java.awt.Paint -import java.util.concurrent.Future - -import scala.language.implicitConversions -import scala.language.postfixOps - -import edu.umd.cs.piccolo.activities.PActivity +import edu.umd.cs.piccolo.PNode import edu.umd.cs.piccolo.nodes.PPath import edu.umd.cs.piccolo.util.PBounds -import edu.umd.cs.piccolo.PNode -import net.kogics.kojo.core.InputAware -import net.kogics.kojo.core.Point -import net.kogics.kojo.core.Turtle +import edu.umd.cs.piccolo.event._ +import java.awt.Color +import java.awt.Paint import net.kogics.kojo.core.UnitLen +import net.kogics.kojo.core.InputAware +import lite.canvas.SpriteCanvas +import java.util.concurrent.Future +import edu.umd.cs.piccolo.activities.PActivity import net.kogics.kojo.figure.Figure -import net.kogics.kojo.kmath.{ Kmath => Math } -import net.kogics.kojo.lite.canvas.SpriteCanvas -import net.kogics.kojo.util.Utils +import net.kogics.kojo.core.Turtle + +import language.implicitConversions +import language.postfixOps object Impl { @volatile var canvas: SpriteCanvas = _ @volatile var turtle0: Turtle = _ @volatile var figure0: Figure = _ - @volatile var API: API = _ + @volatile var API: API = _ } -/** Staging API - * - * This object contains the API for using Staging within Kojo scripts. - * - * DISCLAIMER - * - * Parts of this interface is written to approximately conform to the Processing API as described in the reference at - * . The implementation code is the work of Peter Lewerin - * () and is not in any way derived from the Processing source. - */ +/** + * Staging API + * + * This object contains the API for using Staging within Kojo scripts. + * + * DISCLAIMER + * + * Parts of this interface is written to approximately conform to the + * Processing API as described in the reference at + * . + * The implementation code is the work of Peter Lewerin + * () and is not in any way derived from the + * Processing source. + */ class API(canvas: SpriteCanvas) { Impl.API = this Impl.canvas = canvas Impl.turtle0 = canvas.turtle0 Impl.figure0 = canvas.figure0 - // W#summary Developer home-page for the Staging Module - // W - // W=Introduction= - // W - // WThe Staging Module is currently being developed by Peter Lewerin. - // WThe original impetus came from a desire to run Processing-style code in Kojo. - // W - // WAt this point, the shape hierarchy is the most complete part, but - // Wutilities for color definition, time keeping etc are being added. - // W - // W=Examples= - // W - // W * StagingHelloKojoExample - // W * StagingArrayExample - // W * StagingArrayTwoDeeExample - // W * StagingClockExample - // W * StagingColorWheelExample - // W * StagingCreatingColorsExample - // W * StagingDifferenceOfTwoSquaresExample - // W * StagingEasingExample - // W * StagingHueSaturationBrightnessExample - // W * StagingSineOfAnAngleExample - // W - // W=Overview= - // W - // W==Points== - // W - // WStaging uses {{{net.kogics.kojo.core.Point}}} for coordinates. - // W - - // T PointTest begins + //W#summary Developer home-page for the Staging Module + //W + //W=Introduction= + //W + //WThe Staging Module is currently being developed by Peter Lewerin. + //WThe original impetus came from a desire to run Processing-style code in Kojo. + //W + //WAt this point, the shape hierarchy is the most complete part, but + //Wutilities for color definition, time keeping etc are being added. + //W + //W=Examples= + //W + //W * StagingHelloKojoExample + //W * StagingArrayExample + //W * StagingArrayTwoDeeExample + //W * StagingClockExample + //W * StagingColorWheelExample + //W * StagingCreatingColorsExample + //W * StagingDifferenceOfTwoSquaresExample + //W * StagingEasingExample + //W * StagingHueSaturationBrightnessExample + //W * StagingSineOfAnAngleExample + //W + //W=Overview= + //W + //W==Points== + //W + //WStaging uses {{{net.kogics.kojo.core.Point}}} for coordinates. + //W + + //T PointTest begins def point(x: Double, y: Double) = Point(x, y) implicit def tupleDDToPoint(tuple: (Double, Double)) = Point(tuple._1, tuple._2) implicit def tupleDIToPoint(tuple: (Double, Int)) = Point(tuple._1, tuple._2) implicit def tupleIDToPoint(tuple: (Int, Double)) = Point(tuple._1, tuple._2) implicit def tupleIIToPoint(tuple: (Int, Int)) = Point(tuple._1, tuple._2) - // implicit def baseShapeToPoint(b: BaseShape) = b.origin - // implicit def awtPointToPoint(p: java.awt.geom.Point2D) = Point(p.getX, p.getY) - // implicit def awtDimToPoint(d: java.awt.geom.Dimension2D) = Point(d.getWidth, d.getHeight) + //implicit def baseShapeToPoint(b: BaseShape) = b.origin + //implicit def awtPointToPoint(p: java.awt.geom.Point2D) = Point(p.getX, p.getY) + //implicit def awtDimToPoint(d: java.awt.geom.Dimension2D) = Point(d.getWidth, d.getHeight) - /** The point of origin, located at a corner of the user screen if `screenSize` has been called, or the middle of the - * screen otherwise. - */ + /** The point of origin, located at a corner of the user screen if + * `screenSize` has been called, or the middle of the screen otherwise. */ val O = Point(0, 0) - // T PointTest ends - - // W - // W==User Screen== - // W - // WThe zoom level and axis orientations can be set using `screenSize`. - // W - // T ScreenMethodsTest begins + //T PointTest ends + + //W + //W==User Screen== + //W + //WThe zoom level and axis orientations can be set using `screenSize`. + //W + //T ScreenMethodsTest begins def screenWidth = Screen.rect.getWidth.toInt def screenHeight = Screen.rect.getHeight.toInt def screenSize(width: Int, height: Int) = Screen.size(width, height) - /** The middle point of the user screen, or (0, 0) if `screenSize` hasn't been called. - */ + /** The middle point of the user screen, or (0, 0) if `screenSize` hasn't + * been called. */ def screenMid = Screen.rect.getCenter2D - /** The extreme point of the user screen (i.e. the opposite corner from the point of origin), or (0, 0) if - * `screenSize` hasn't been called. - */ + /** The extreme point of the user screen (i.e. the opposite corner from + * the point of origin), or (0, 0) if `screenSize` hasn't been called. */ def screenExt = Screen.rect.getExt /** Fills the user screen with the specified color. */ def background(bc: Paint) = { withStyle(bc, null, 1) { rectangle(O, screenExt) } } - // T ScreenMethodsTest ends + //T ScreenMethodsTest ends - // W - // W==Simple shapes and text== - // W - // WGiven `Point`s or _x_ and _y_ coordinate values, simple shapes like dots, - // Wlines, rectangles, ellipses, and elliptic arcs can be drawn. Texts can - // Walso be placed in this way. - // W - // T SimpleShapesTest begins + //W + //W==Simple shapes and text== + //W + //WGiven `Point`s or _x_ and _y_ coordinate values, simple shapes like dots, + //Wlines, rectangles, ellipses, and elliptic arcs can be drawn. Texts can + //Walso be placed in this way. + //W + //T SimpleShapesTest begins def dot(x: Double, y: Double): Dot = Dot(Point(x, y)) def dot(p: Point): Dot = Dot(p) @@ -164,20 +168,15 @@ class API(canvas: SpriteCanvas) { Rectangle(p, Point(p.x + s, p.y + s)) def roundRectangle( - x: Double, - y: Double, - w: Double, - h: Double, - rx: Double, - ry: Double + x: Double, y: Double, + w: Double, h: Double, + rx: Double, ry: Double ) = RoundRectangle(Point(x, y), Point(x + w, y + h), Point(rx, ry)) def roundRectangle( - p: Point, - w: Double, - h: Double, - rx: Double, - ry: Double + p: Point, + w: Double, h: Double, + rx: Double, ry: Double ) = RoundRectangle(p, Point(p.x + w, p.y + h), Point(rx, ry)) def roundRectangle(p1: Point, p2: Point, rx: Double, ry: Double) = @@ -237,15 +236,15 @@ class API(canvas: SpriteCanvas) { CrossOutline(p1, p2, cw, r, greek) def saltire(p1: Point, p2: Point, s: Double) = Saltire(p1, p2, s) def saltireOutline(p1: Point, p2: Point, s: Double) = SaltireOutline(p1, p2, s) - // T SimpleShapesTest ends - - // W - // W==Complex Shapes== - // W - // WGiven a sequence of `Point`s, a number of complex shapes can be drawn, - // Wincluding basic polylines and polygons, and patterns of polylines/polygons. - // W - // T ComplexShapesTest begins + //T SimpleShapesTest ends + + //W + //W==Complex Shapes== + //W + //WGiven a sequence of `Point`s, a number of complex shapes can be drawn, + //Wincluding basic polylines and polygons, and patterns of polylines/polygons. + //W + //T ComplexShapesTest begins def polyline(pts: Seq[Point]) = Polyline(pts) def polygon(pts: Seq[Point]): Polygon = Polygon(pts) @@ -259,35 +258,35 @@ class API(canvas: SpriteCanvas) { def quadsShape(pts: Seq[Point]) = QuadsShape(pts) def quadStripShape(pts: Seq[Point]) = QuadStripShape(pts) def triangleFanShape(p0: Point, pts: Seq[Point]) = TriangleFanShape(p0, pts) - // T ComplexShapesTest ends - - // W - // W==SVG Shapes== - // W - // WGiven an SVG element, the corresponding shape can be drawn. - // W - // T SvgShapesTest begins + //T ComplexShapesTest ends + + //W + //W==SVG Shapes== + //W + //WGiven an SVG element, the corresponding shape can be drawn. + //W + //T SvgShapesTest begins def svgShape(node: scala.xml.Node) = SvgShape(node) - // T SvgShapesTest ends - + //T SvgShapesTest ends + def sprite(x: Double, y: Double, fname: String) = Sprite(point(x, y), fname) def path(x: Double, y: Double) = Path(point(x, y)) def group(shapes: List[Shape]) = Composite(shapes) - def group(shapes: Shape*) = Composite(shapes) - - // W - // W==Color== - // W - // WColor values can be created with the method `color`, or using a - // W_color-maker_. The methods `fill`, `noFill`, - // W`stroke`, and `noStroke` set the colors used to draw the insides and edges - // Wof figures. The method `strokeWidth` doesn't actually affect color but is - // Wtypically used together with the color setting methods. The method - // W`withStyle` allows the user to set fill color, stroke color, and stroke - // Wwidth temporarily. - // W - // W - // T ColorTest begins + def group(shapes: Shape *) = Composite(shapes) + + //W + //W==Color== + //W + //WColor values can be created with the method `color`, or using a + //W_color-maker_. The methods `fill`, `noFill`, + //W`stroke`, and `noStroke` set the colors used to draw the insides and edges + //Wof figures. The method `strokeWidth` doesn't actually affect color but is + //Wtypically used together with the color setting methods. The method + //W`withStyle` allows the user to set fill color, stroke color, and stroke + //Wwidth temporarily. + //W + //W + //T ColorTest begins def grayColors(grayMax: Int) = ColorMaker(GRAY(grayMax)) def grayColorsWithAlpha(grayMax: Int, alphaMax: Int) = @@ -308,40 +307,40 @@ class API(canvas: SpriteCanvas) { def setPenColor(color: Paint) = stroke(color) def setFillColor(color: Paint) = fill(color) def setPenThickness(w: Double) = strokeWidth(w) - + def withStyle(fc: Paint, sc: Paint, sw: Double)(body: => Unit) = Style(fc, sc, sw)(body) - implicit def ColorToRichColor(c: java.awt.Color) = RichColor(c) + implicit def ColorToRichColor (c: java.awt.Color) = RichColor(c) def lerpColor(from: RichColor, to: RichColor, amt: Double) = RichColor.lerpColor(from, to, amt) - // T ColorTest ends + //T ColorTest ends Inputs.init() - // W - // W==Timekeeping== - // W - // WA number of methods report the current time. - // W - // T TimekeepingTest begins + //W + //W==Timekeeping== + //W + //WA number of methods report the current time. + //W + //T TimekeepingTest begins def millis = System.currentTimeMillis() - def time = System.currentTimeMillis() / 1000.0 + def time = System.currentTimeMillis()/1000.0 import java.util.Calendar def second = Calendar.getInstance().get(Calendar.SECOND) def minute = Calendar.getInstance().get(Calendar.MINUTE) - def hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY) - def day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH) - def month = Calendar.getInstance().get(Calendar.MONTH) + 1 - def year = Calendar.getInstance().get(Calendar.YEAR) - // T UtilsTest ends - - // W - // W==Math== - // W - // WA number of methods perform number processing tasks. - // W - // T MathTest begins + def hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY) + def day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + def month = Calendar.getInstance().get(Calendar.MONTH) + 1 + def year = Calendar.getInstance().get(Calendar.YEAR) + //T UtilsTest ends + + //W + //W==Math== + //W + //WA number of methods perform number processing tasks. + //W + //T MathTest begins def constrain(value: Double, min: Double, max: Double) = Math.constrain(value, min, max) @@ -365,15 +364,15 @@ class API(canvas: SpriteCanvas) { def mag(x: Double, y: Double) = dist(0, 0, x, y) def mag(p: Point) = dist(0, 0, p.x, p.y) - // W - // W==Trigonometry== - // W - // WA number of methods perform trigonometry tasks. - // W + //W + //W==Trigonometry== + //W + //WA number of methods perform trigonometry tasks. + //W val PI = math.Pi - val TWO_PI = 2 * PI - val HALF_PI = PI / 2 - val QUARTER_PI = PI / 4 + val TWO_PI = 2*PI + val HALF_PI = PI/2 + val QUARTER_PI = PI/4 def sin(a: Double) = math.sin(a) def cos(a: Double) = math.cos(a) def tan(a: Double) = math.tan(a) @@ -382,15 +381,15 @@ class API(canvas: SpriteCanvas) { def atan(a: Double) = math.atan(a) def radians(deg: Double) = deg.toRadians def degrees(rad: Double) = rad.toDegrees - // T MathTest ends + //T MathTest ends - // W + //W - // W==Control== - // W - // WThere are methods for execution control and mouse feedback. - // W - // T ControlTest begins + //W==Control== + //W + //WThere are methods for execution control and mouse feedback. + //W + //T ControlTest begins def loop(fn: => Unit) = Impl.figure0.refresh(fn) def animate(fn: => Unit) = loop(fn) def stop() = Impl.figure0.stopRefresh() @@ -422,12 +421,8 @@ class API(canvas: SpriteCanvas) { require(pts1.size == pts2.size, "The polygons don't match up.") var g0 = polygon(pts1) - for { - i <- 0 to n - amt = i / n.toFloat - } { - val pts = pts1.zip(pts2).map { - case (p1, p2) => + for (i <- 0 to n ; amt = i / n.toFloat) { + val pts = (pts1 zip pts2) map { case(p1, p2) => point(lerp(p1.x, p2.x, amt), lerp(p1.y, p2.y, amt)) } g0.hide() @@ -437,15 +432,15 @@ class API(canvas: SpriteCanvas) { } } } - // T ControlTest ends + //T ControlTest ends // expose some types in the API type Shape = staging.Shape type StrokedShape = staging.StrokedShape - // W - // W=Usage= - // W + //W + //W=Usage= + //W } // end of API abstract class ColorModes @@ -457,7 +452,7 @@ case class GRAY(v: Int) extends ColorModes case class GRAYA(v: Int, a: Int) extends ColorModes //T ShapeMethodsTest begins -trait Shape extends InputAware { +trait Shape extends InputAware { def pnode = node def node: PNode var sizeFactor = 1.0 @@ -492,11 +487,11 @@ trait Shape extends InputAware { def setFillColor(color: Paint) = fill(color) def rotate(amount: Double) = turn(amount) - + def rotateTo(angle: Double) = { turn(angle - _theta.toDegrees) } - + def scale(amount: Double) = { Utils.runInSwingThread { node.scale(amount) @@ -507,11 +502,11 @@ trait Shape extends InputAware { def scaleTo(size: Double) = { scale(size / sizeFactor) } - + def translate(p: Point): Unit = { translate(p.x, p.y) } - + def offset(p: Point): Unit = { offset(p.x, p.y) } @@ -545,7 +540,7 @@ trait Shape extends InputAware { node.repaint() } } - + def heading = Utils.runInSwingThreadAndWait { _theta.toDegrees } @@ -564,6 +559,7 @@ trait Rounded { def radiusY = curvature.y } + trait BaseShape extends Shape with core.RichTurtleCommands { val origin: Point import turtle.TurtleHelper._ @@ -577,12 +573,12 @@ trait BaseShape extends Shape with core.RichTurtleCommands { node.repaint() } } - + def position = Utils.runInSwingThreadAndWait { val o = node.getOffset Point(o.getX + origin.x, o.getY + origin.y) - } - + } + def forward(n: Double): Unit = { Utils.runInSwingThread { val pos = position @@ -590,7 +586,7 @@ trait BaseShape extends Shape with core.RichTurtleCommands { setPosition(xy._1, xy._2) } } - + def towards(x: Double, y: Double): Unit = { Utils.runInSwingThread { val pos = position @@ -681,16 +677,17 @@ object Text { } } + trait PolyShape extends BaseShape { val points: Seq[Point] val origin = points(0) - // def toPolygon: Polygon = Polygon(points) - // def toPolyline: Polyline = Polyline(points) + //def toPolygon: Polygon = Polygon(points) + //def toPolyline: Polyline = Polyline(points) } trait CrossShape { - val xdims = Array.fill(8) { 0.0 } - val ydims = Array.fill(8) { 0.0 } + val xdims = Array.fill(8){0.0} + val ydims = Array.fill(8){0.0} def crossDims(len: Double, wid: Double, cw: Double, r: Double = 1, greek: Boolean = false) = { require(wid / 2 > cw) require(len / 2 > cw) @@ -715,50 +712,29 @@ trait CrossShape { this } def points() = List( - Point(xdims(0), ydims(5)), - Point(xdims(2), ydims(5)), - Point(xdims(2), ydims(7)), - Point(xdims(5), ydims(7)), - Point(xdims(5), ydims(5)), - Point(xdims(7), ydims(5)), - Point(xdims(7), ydims(2)), - Point(xdims(5), ydims(2)), - Point(xdims(5), ydims(0)), - Point(xdims(2), ydims(0)), - Point(xdims(2), ydims(2)), - Point(xdims(0), ydims(2)) + Point(xdims(0), ydims(5)), Point(xdims(2), ydims(5)), + Point(xdims(2), ydims(7)), Point(xdims(5), ydims(7)), + Point(xdims(5), ydims(5)), Point(xdims(7), ydims(5)), + Point(xdims(7), ydims(2)), Point(xdims(5), ydims(2)), + Point(xdims(5), ydims(0)), Point(xdims(2), ydims(0)), + Point(xdims(2), ydims(2)), Point(xdims(0), ydims(2)) ) def outlinePoints() = List( - Point(xdims(0), ydims(6)), - Point(xdims(1), ydims(6)), - Point(xdims(1), ydims(7)), - Point(xdims(3), ydims(7)), - Point(xdims(3), ydims(4)), - Point(xdims(0), ydims(4)), - Point(xdims(6), ydims(7)), - Point(xdims(6), ydims(6)), - Point(xdims(7), ydims(6)), - Point(xdims(7), ydims(4)), - Point(xdims(4), ydims(4)), - Point(xdims(4), ydims(7)), - Point(xdims(7), ydims(1)), - Point(xdims(6), ydims(1)), - Point(xdims(6), ydims(0)), - Point(xdims(4), ydims(0)), - Point(xdims(4), ydims(3)), - Point(xdims(7), ydims(3)), - Point(xdims(1), ydims(0)), - Point(xdims(1), ydims(1)), - Point(xdims(0), ydims(1)), - Point(xdims(0), ydims(3)), - Point(xdims(3), ydims(3)), - Point(xdims(3), ydims(0)) + Point(xdims(0), ydims(6)), Point(xdims(1), ydims(6)), Point(xdims(1), ydims(7)), + Point(xdims(3), ydims(7)), Point(xdims(3), ydims(4)), Point(xdims(0), ydims(4)), + Point(xdims(6), ydims(7)), Point(xdims(6), ydims(6)), Point(xdims(7), ydims(6)), + Point(xdims(7), ydims(4)), Point(xdims(4), ydims(4)), Point(xdims(4), ydims(7)), + Point(xdims(7), ydims(1)), Point(xdims(6), ydims(1)), Point(xdims(6), ydims(0)), + Point(xdims(4), ydims(0)), Point(xdims(4), ydims(3)), Point(xdims(7), ydims(3)), + Point(xdims(1), ydims(0)), Point(xdims(1), ydims(1)), Point(xdims(0), ydims(1)), + Point(xdims(0), ydims(3)), Point(xdims(3), ydims(3)), Point(xdims(3), ydims(0)) ) } + class Composite(val shapes: Seq[Shape]) extends Shape { val node = new PNode - shapes.foreach { shape => + shapes foreach { shape => node.addChild(shape.node) } @@ -779,7 +755,7 @@ object Style { def save: Unit = { Utils.runInSwingThread { - savedStyles.push(Tuple3(f.fillColor, f.lineColor, f.lineStroke)) + savedStyles push Tuple3(f.fillColor, f.lineColor, f.lineStroke) } } @@ -806,6 +782,7 @@ object Style { } } + class Bounds(x1: Double, y1: Double, x2: Double, y2: Double) { val bounds = new PBounds(x1, y1, x2 - x1, y2 - y1) diff --git a/src/main/scala/net/kogics/kojo/staging/svgshapes.scala b/src/main/scala/net/kogics/kojo/staging/svgshapes.scala index bb47f89cb..5cad87e13 100644 --- a/src/main/scala/net/kogics/kojo/staging/svgshapes.scala +++ b/src/main/scala/net/kogics/kojo/staging/svgshapes.scala @@ -16,42 +16,46 @@ package net.kogics.kojo package staging -import javax.swing._ - -import core._ import edu.umd.cs.piccolo._ -import edu.umd.cs.piccolo.event._ import edu.umd.cs.piccolo.nodes._ import edu.umd.cs.piccolo.util._ +import edu.umd.cs.piccolo.event._ + +//import net.kogics.kojo.util.Utils + +import javax.swing._ + +import core._ + import language.postfixOps object SvgShape { import Impl.API - - def getAttr(ns: scala.xml.Node, s: String): Option[String] = { + + def getAttr (ns: scala.xml.Node, s: String): Option[String] = { ns \ ("@" + s) text match { case "" => None case z => Some(z) } } - private def matchXY(ns: scala.xml.Node, xn: String = "x", yn: String = "y") = { - val x = getAttr(ns, xn).getOrElse("0").toDouble - val y = getAttr(ns, yn).getOrElse("0").toDouble + private def matchXY (ns: scala.xml.Node, xn: String = "x", yn: String = "y") = { + val x = (getAttr(ns, xn) getOrElse "0").toDouble + val y = (getAttr(ns, yn) getOrElse "0").toDouble Point(x, y) } - private def matchWH(ns: scala.xml.Node) = { - val w = getAttr(ns, "width").getOrElse("0").toDouble - val h = getAttr(ns, "height").getOrElse("0").toDouble + private def matchWH (ns: scala.xml.Node) = { + val w = (getAttr(ns, "width") getOrElse "0").toDouble + val h = (getAttr(ns, "height") getOrElse "0").toDouble require(w >= 0, "Bad width for XML element " + ns) require(h >= 0, "Bad height for XML element " + ns) (w, h) } - private def matchRXY(ns: scala.xml.Node) = { - val x = getAttr(ns, "rx").getOrElse("0").toDouble - val y = getAttr(ns, "ry").getOrElse("0").toDouble + private def matchRXY (ns: scala.xml.Node) = { + val x = (getAttr(ns, "rx") getOrElse "0").toDouble + val y = (getAttr(ns, "ry") getOrElse "0").toDouble require(x >= 0, "Bad rx for XML element " + ns) require(y >= 0, "Bad ry for XML element " + ns) val rx = if (x != 0) x else y @@ -65,11 +69,11 @@ object SvgShape { private def matchStrokeWidth(ns: scala.xml.Node) = getAttr(ns, "stroke-width") - private def matchPoints(ns: scala.xml.Node): Seq[Point] = { + private def matchPoints (ns: scala.xml.Node): Seq[Point] = { val pointsStr = ns \ "@points" text val splitter = "(:?,\\s*|\\s+)".r - val pointsItr = splitter.split(pointsStr).map(_.toDouble).grouped(2) - pointsItr.map { a => Point(a(0), a(1)) }.toList + val pointsItr = (splitter split pointsStr) map (_.toDouble) grouped(2) + (pointsItr map { a => Point(a(0), a(1)) }).toList } import staging.Style @@ -79,11 +83,11 @@ object SvgShape { val sw_? = matchStrokeWidth(ns) Style.save - fc_?.foreach { fc => API.fill(ColorMaker.color(fc)) } + fc_? foreach { fc => API.fill(ColorMaker.color(fc)) } - sc_?.foreach { sc => API.stroke(ColorMaker.color(sc)) } + sc_? foreach { sc => API.stroke(ColorMaker.color(sc)) } - sw_?.foreach { sw => API.strokeWidth(sw.toDouble) } + sw_? foreach { sw => API.strokeWidth(sw.toDouble) } } private def matchRect(ns: scala.xml.Node) = { @@ -95,8 +99,7 @@ object SvgShape { val res = if (p2.x != 0.0 || p2.y != 0.0) { RoundRectangle(p0, p1, p2) - } - else { + } else { Rectangle(p0, p1) } Style.restore @@ -105,7 +108,7 @@ object SvgShape { private def matchCircle(ns: scala.xml.Node) = { val p0 = matchXY(ns, "cx", "cy") - val r = getAttr(ns, "r").getOrElse("0").toDouble + val r = (getAttr(ns, "r") getOrElse "0").toDouble val p1 = p0 + Point(r, r) setStyle(ns) val res = Ellipse(p0, p1) @@ -132,7 +135,7 @@ object SvgShape { } private def matchText(ns: scala.xml.Node) = { - // TODO hmm not working + //TODO hmm not working val p1 = matchXY(ns) // should also support dx/dy, rotate, textLength, lengthAdjust // and font attributes (as far as piccolo/awt can support them) @@ -179,12 +182,12 @@ object SvgShape { res case => matchPath(node) - case {shapes @ _*} => + case { shapes @ _* } => new Shape { val node = null } - // for (s <- shapes) yield SvgShape(s) - case {shapes @ _*} => + //for (s <- shapes) yield SvgShape(s) + case { shapes @ _* } => new Shape { val node = null } - // for (s <- shapes) yield SvgShape(s) + //for (s <- shapes) yield SvgShape(s) case _ => // unknown element, ignore new Shape { val node = null } } diff --git a/src/main/scala/net/kogics/kojo/story/LinkListener.scala b/src/main/scala/net/kogics/kojo/story/LinkListener.scala index a1d20da52..0bcc10e35 100644 --- a/src/main/scala/net/kogics/kojo/story/LinkListener.scala +++ b/src/main/scala/net/kogics/kojo/story/LinkListener.scala @@ -19,7 +19,6 @@ import java.awt.Desktop import java.net.URL import javax.swing._ import javax.swing.event._ - import net.kogics.kojo.util.Utils class LinkListener(st: StoryTeller) extends HyperlinkListener { @@ -30,18 +29,18 @@ class LinkListener(st: StoryTeller) extends HyperlinkListener { def localpageLocation(url: String): (Int, Int) = { url match { case linkRegex(page, para) => - (page.toInt, if (para == "") 1 else para.toInt) + (page.toInt, if (para=="") 1 else para.toInt) case linkPnameRegex(pageName, para) => val pageNum = st.pageNumber(pageName) if (pageNum.isDefined) - (pageNum.get, if (para == "") 1 else para.toInt) + (pageNum.get, if (para=="") 1 else para.toInt) else throw new IllegalArgumentException() case _ => throw new IllegalArgumentException() } } - + // extract handler and data from runhandler url. def handlerData(url: String): (String, String) = { url.trim match { @@ -51,7 +50,7 @@ class LinkListener(st: StoryTeller) extends HyperlinkListener { throw new IllegalArgumentException() } } - + // satisfy url click def gotoUrl(url: URL) = Utils.runInSwingThread { if (url.getProtocol == "http") { @@ -67,7 +66,7 @@ class LinkListener(st: StoryTeller) extends HyperlinkListener { st.showStatusError("Problem handling Url - %s: %s".format(url.toString, t.getMessage)) } } - else if (url.getHost.toLowerCase == "runhandler") { + else if (url.getHost.toLowerCase == "runhandler") { try { val d = handlerData(url.toString) st.handleLink(d._1, d._2) @@ -81,7 +80,7 @@ class LinkListener(st: StoryTeller) extends HyperlinkListener { } else { try { - Desktop.getDesktop().browse(url.toURI) + Desktop.getDesktop().browse(url.toURI) } catch { case t: Throwable => @@ -129,7 +128,7 @@ class LinkListener(st: StoryTeller) extends HyperlinkListener { } // for tests - private[story] def setStory(story: Story): Unit = { + private [story] def setStory(story: Story): Unit = { st.currStory = Some(story) } } diff --git a/src/main/scala/net/kogics/kojo/story/StoryTeller.scala b/src/main/scala/net/kogics/kojo/story/StoryTeller.scala index 5a70b370b..a2142b418 100644 --- a/src/main/scala/net/kogics/kojo/story/StoryTeller.scala +++ b/src/main/scala/net/kogics/kojo/story/StoryTeller.scala @@ -16,17 +16,17 @@ package net.kogics.kojo package story -import java.awt.event.ActionEvent -import java.awt.event.ActionListener -import java.awt.event.ComponentAdapter -import java.awt.event.ComponentEvent import java.awt.BorderLayout import java.awt.Color import java.awt.Cursor import java.awt.Dimension import java.awt.Font +import java.awt.event.ActionEvent +import java.awt.event.ActionListener +import java.awt.event.ComponentAdapter +import java.awt.event.ComponentEvent import java.util.logging.Logger -import javax.swing.text.html.HTMLDocument + import javax.swing.BorderFactory import javax.swing.BoxLayout import javax.swing.JButton @@ -36,6 +36,7 @@ import javax.swing.JLabel import javax.swing.JPanel import javax.swing.JScrollPane import javax.swing.JTextField +import javax.swing.text.html.HTMLDocument import net.kogics.kojo.lite.Theme import net.kogics.kojo.util.Read @@ -56,10 +57,10 @@ class StoryTeller(val kojoCtx: core.KojoCtx) extends JPanel with music.Mp3Player val pageFields = new collection.mutable.HashMap[String, JTextField]() val defaultMsg =
    - {for (idx <- 1 to 6) yield {
    }} -

    {xml.XML.loadString(Utils.loadString("S_StoryTellerIntroP1"))}

    -

    {Utils.loadString("S_StoryTellerIntroP2")}

    -

    {Utils.loadString("S_StoryTellerIntroP3")}

    + { for (idx <- 1 to 6) yield {
    } } +

    { xml.XML.loadString(Utils.loadString("S_StoryTellerIntroP1")) }

    +

    { Utils.loadString("S_StoryTellerIntroP2") }

    +

    { Utils.loadString("S_StoryTellerIntroP3") }

    // setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)) @@ -297,7 +298,7 @@ class StoryTeller(val kojoCtx: core.KojoCtx) extends JPanel with music.Mp3Player private def done() = { // call in gui thread - currStory.foreach { _.stop() } + currStory foreach { _.stop() } currStory = None clearHelper() stopMp3Loop() @@ -377,8 +378,8 @@ class StoryTeller(val kojoCtx: core.KojoCtx) extends JPanel with music.Mp3Player } } else { - showStatusError("Field with label - %s is not defined".format(label)) - throw new IllegalArgumentException("Field with label - %s is not defined".format(label)) + showStatusError("Field with label - %s is not defined" format (label)) + throw new IllegalArgumentException("Field with label - %s is not defined" format (label)) } } @@ -445,7 +446,7 @@ class StoryTeller(val kojoCtx: core.KojoCtx) extends JPanel with music.Mp3Player statusBar.setText(msg) } if (output) { - outputFn("[Storyteller] %s\n".format(msg)) + outputFn("[Storyteller] %s\n" format (msg)) } } @@ -454,7 +455,7 @@ class StoryTeller(val kojoCtx: core.KojoCtx) extends JPanel with music.Mp3Player statusBar.setForeground(Color.red) statusBar.setText(msg) } - outputFn("[Storyteller] %s\n".format(msg)) + outputFn("[Storyteller] %s\n" format (msg)) } def playStory(story: Story) = Utils.runInSwingThread { @@ -496,7 +497,7 @@ class StoryTeller(val kojoCtx: core.KojoCtx) extends JPanel with music.Mp3Player story.handleLinkEnter(name, data) } def handleLinkExit(name: String, data: String): Unit = { - if (currStory.isDefined) { // work around link exits showing up after story ends + if (currStory.isDefined) { // work around link exits showing up after story ends story.handleLinkExit(name, data) } } diff --git a/src/main/scala/net/kogics/kojo/story/handlers.scala b/src/main/scala/net/kogics/kojo/story/handlers.scala index c5f6eb43a..c8c88edc4 100644 --- a/src/main/scala/net/kogics/kojo/story/handlers.scala +++ b/src/main/scala/net/kogics/kojo/story/handlers.scala @@ -22,7 +22,7 @@ import util.Read._ trait HandlerHolder[+T] { def handle(data: String): Unit } - + class IntHandlerHolder(handler: Int => Unit) extends HandlerHolder[Int] { def handle(data: String): Unit = { handler(convertArg(data)) @@ -41,3 +41,4 @@ class VoidHandlerHolder(handler: () => Unit) extends HandlerHolder[Unit] { handler() } } + diff --git a/src/main/scala/net/kogics/kojo/story/htmlEditorKit.scala b/src/main/scala/net/kogics/kojo/story/htmlEditorKit.scala index ecd385f31..6242ecfa0 100644 --- a/src/main/scala/net/kogics/kojo/story/htmlEditorKit.scala +++ b/src/main/scala/net/kogics/kojo/story/htmlEditorKit.scala @@ -21,19 +21,20 @@ import java.awt.Graphics import java.awt.Insets import java.awt.Rectangle import java.awt.Shape -import javax.swing.text.html.CSS -import javax.swing.text.html.HTML -import javax.swing.text.html.HTMLEditorKit -import javax.swing.text.Element -import javax.swing.text.Position -import javax.swing.text.StyleConstants -import javax.swing.text.View -import javax.swing.JLabel import org.scilab.forge.jlatexmath.ParseException import org.scilab.forge.jlatexmath.TeXConstants import org.scilab.forge.jlatexmath.TeXFormula +import javax.swing.JLabel +import javax.swing.text.Element +import javax.swing.text.Position +import javax.swing.text.StyleConstants +import javax.swing.text.View +import javax.swing.text.html.CSS +import javax.swing.text.html.HTML +import javax.swing.text.html.HTMLEditorKit + object CustomHtmlEditorKit { val latexPrefix = "latex://" util.Utils.runAsync { @@ -50,18 +51,18 @@ class CustomHtmlEditorKit private extends HTMLEditorKit { } class CustomHtmlFactory extends HTMLEditorKit.HTMLFactory { - + override def create(elem: Element) = { def hasLatexAttr(e: Element) = e.getAttributes().getAttribute(HTML.Attribute.SRC) match { - case src: String if src.startsWith(CustomHtmlEditorKit.latexPrefix) => true - case _ => false + case src: String if (src.startsWith(CustomHtmlEditorKit.latexPrefix)) => true + case _ => false } val o = elem.getAttributes().getAttribute(StyleConstants.NameAttribute) val src = elem.getAttributes().getAttribute(HTML.Attribute.SRC) o match { - case kind: HTML.Tag if kind == HTML.Tag.IMG && hasLatexAttr(elem) => new LatexView(elem) - case _ => super.create(elem) + case kind: HTML.Tag if(kind == HTML.Tag.IMG && hasLatexAttr(elem)) => new LatexView(elem) + case _ => super.create(elem) } } } @@ -88,15 +89,14 @@ class LatexView(elem: Element) extends View(elem) { } } - val formula = - try { - new TeXFormula(latex) - } - catch { - case pe: ParseException => - output("Incorrect formula - %s.\nProblem: %s".format(latex, pe.getMessage)) - new TeXFormula("\\text{Incorrect Formula. See output for details}") - } + val formula = try { + new TeXFormula(latex) + } + catch { + case pe: ParseException => + output("Incorrect formula - %s.\nProblem: %s".format(latex, pe.getMessage)) + new TeXFormula("\\text{Incorrect Formula. See output for details}") + } val icon = formula.createTeXIcon(TeXConstants.STYLE_DISPLAY, size) icon.setInsets(new Insets(2, 2, 2, 2)) val jl = new JLabel(); diff --git a/src/main/scala/net/kogics/kojo/story/story.scala b/src/main/scala/net/kogics/kojo/story/story.scala index 642f11a95..4877c0aef 100644 --- a/src/main/scala/net/kogics/kojo/story/story.scala +++ b/src/main/scala/net/kogics/kojo/story/story.scala @@ -66,13 +66,13 @@ class IncrPage(val name: String, style: String, body: List[Para]) extends Viewab private def viewParas(n: Int) = { - {body.take(n).map { para => para.body }} + {body.take(n).map {para => para.body}} } - + private def runCode(n: Int): Unit = { Utils.runAsyncMonitored { - body(n - 1).code + body(n-1).code } } @@ -145,9 +145,9 @@ case class Story(pages: Viewable*) extends Viewable { } def hasView(pg: Int, para: Int) = { - if (pg > 0 && pg <= pages.size && para > 0 && para <= pages(pg - 1).numViews) + if (pg > 0 && pg <= pages.size && para > 0 && para <= pages(pg-1).numViews) true - else + else false } @@ -157,7 +157,7 @@ case class Story(pages: Viewable*) extends Viewable { val targetPage = pg - 1 if (currPage < targetPage) { while (currPage != targetPage) { - while (pages(currPage).hasNextView) { + while(pages(currPage).hasNextView) { pages(currPage).forward() } currPage += 1 @@ -166,9 +166,9 @@ case class Story(pages: Viewable*) extends Viewable { forward() } } - else if (currPage > targetPage) { + else if(currPage > targetPage) { while (currPage != targetPage) { - while (pages(currPage).hasPrevView) { + while(pages(currPage).hasPrevView) { pages(currPage).back() } currPage -= 1 @@ -179,7 +179,7 @@ case class Story(pages: Viewable*) extends Viewable { } else { // currPage == targetPage - while (pages(currPage).hasPrevView) { + while(pages(currPage).hasPrevView) { pages(currPage).back() } for (idx <- 1 until para) { @@ -188,11 +188,11 @@ case class Story(pages: Viewable*) extends Viewable { } } - def location = (currPage + 1, pages(currPage).currView) + def location = (currPage+1, pages(currPage).currView) def pageNumber(name: String): Option[Int] = { - val idx = pages.indexWhere { e => name == e.name } - if (idx == -1) None else Some(idx + 1) + val idx = pages.indexWhere {e => name == e.name} + if (idx == -1) None else Some(idx+1) } def numViews = throw new UnsupportedOperationException @@ -201,14 +201,14 @@ case class Story(pages: Viewable*) extends Viewable { def scrollToEnd = pages(currPage).scrollToEnd val noOpHandler = new StringHandlerHolder({ e => }) - val handlers = collection.mutable.Map[String, HandlerHolder[Any]]().withDefaultValue(noOpHandler) - val linkEnterHandlers = collection.mutable.Map[String, HandlerHolder[Any]]().withDefaultValue(noOpHandler) - val linkExitHandlers = collection.mutable.Map[String, HandlerHolder[Any]]().withDefaultValue(noOpHandler) + val handlers = collection.mutable.Map[String, HandlerHolder[Any]]() withDefaultValue(noOpHandler) + val linkEnterHandlers = collection.mutable.Map[String, HandlerHolder[Any]]() withDefaultValue(noOpHandler) + val linkExitHandlers = collection.mutable.Map[String, HandlerHolder[Any]]() withDefaultValue(noOpHandler) def addLinkHandler[T](name: String)(hm: HandlerHolder[T]) = Utils.runInSwingThread { handlers(name) = hm } - + def handleLink(name: String, data: String): Unit = { handlers(name).handle(data) } @@ -216,7 +216,7 @@ case class Story(pages: Viewable*) extends Viewable { def addLinkEnterHandler[T](name: String)(hm: HandlerHolder[T]) = Utils.runInSwingThread { linkEnterHandlers(name) = hm } - + def handleLinkEnter(name: String, data: String): Unit = { linkEnterHandlers(name).handle(data) } @@ -224,18 +224,18 @@ case class Story(pages: Viewable*) extends Viewable { def addLinkExitHandler[T](name: String)(hm: HandlerHolder[T]) = Utils.runInSwingThread { linkExitHandlers(name) = hm } - + def handleLinkExit(name: String, data: String): Unit = { linkExitHandlers(name).handle(data) } - + @volatile var stopFn: Option[() => Unit] = None def onStop(fn: => Unit): Unit = { stopFn = Some(() => fn) } - + def stop(): Unit = { stopFn.foreach(_.apply()) } - + } diff --git a/src/main/scala/net/kogics/kojo/syntax/Builtins.scala b/src/main/scala/net/kogics/kojo/syntax/Builtins.scala index d9d55da3a..3b48cfb69 100644 --- a/src/main/scala/net/kogics/kojo/syntax/Builtins.scala +++ b/src/main/scala/net/kogics/kojo/syntax/Builtins.scala @@ -1,11 +1,9 @@ package net.kogics.kojo.syntax -import angle._ -import net.kogics.kojo.doodle.Angle -import net.kogics.kojo.doodle.Normalized -import net.kogics.kojo.doodle.UnsignedByte +import net.kogics.kojo.doodle.{ Angle, Normalized, UnsignedByte } import normalized._ import uByte._ +import angle._ object Builtins { val Color = net.kogics.kojo.doodle.Color diff --git a/src/main/scala/net/kogics/kojo/syntax/package.scala b/src/main/scala/net/kogics/kojo/syntax/package.scala index 154d7bb02..67a0ae32f 100644 --- a/src/main/scala/net/kogics/kojo/syntax/package.scala +++ b/src/main/scala/net/kogics/kojo/syntax/package.scala @@ -2,7 +2,7 @@ package net.kogics.kojo package object syntax { - object angle extends AngleSyntax + object angle extends AngleSyntax object normalized extends NormalizedSyntax - object uByte extends UnsignedByteSyntax + object uByte extends UnsignedByteSyntax } diff --git a/src/main/scala/net/kogics/kojo/tiles/package.scala b/src/main/scala/net/kogics/kojo/tiles/package.scala index 794ac11a0..20b1f8765 100644 --- a/src/main/scala/net/kogics/kojo/tiles/package.scala +++ b/src/main/scala/net/kogics/kojo/tiles/package.scala @@ -18,13 +18,9 @@ import java.awt.image.BufferedImage import java.io.File import java.net.URL -import net.kogics.kojo.core.Picture -import net.kogics.kojo.core.Point -import net.kogics.kojo.core.SCanvas +import net.kogics.kojo.core.{Picture, Point, SCanvas} import net.kogics.kojo.util.Utils -import org.mapeditor.core.{ Tile => MapTile } -import org.mapeditor.core.MapLayer -import org.mapeditor.core.TileLayer +import org.mapeditor.core.{MapLayer, TileLayer, Tile => MapTile} package object tiles { @@ -62,7 +58,7 @@ package object tiles { case class Layer(index: Int, world: TileWorld)(implicit canvas: SCanvas) { val mapLayer = world.layerAt(index) match { case tl: TileLayer => tl - case _ @l => println(s"Ignoring non-tile layer: $l"); null + case _@ l => println(s"Ignoring non-tile layer: $l"); null } val tiles = Array.ofDim[Tile](world.height, world.width) @@ -255,7 +251,8 @@ package object tiles { currentLevel.layers(layerIdx).removeTileAt(txy) } - def step(): Unit = {} + def step(): Unit = { + } // Draw level, player, overlay def draw(): Unit = { diff --git a/src/main/scala/net/kogics/kojo/turtle/LoTurtle.scala b/src/main/scala/net/kogics/kojo/turtle/LoTurtle.scala index 1f7eb9b9a..9ac85370b 100644 --- a/src/main/scala/net/kogics/kojo/turtle/LoTurtle.scala +++ b/src/main/scala/net/kogics/kojo/turtle/LoTurtle.scala @@ -15,13 +15,11 @@ package net.kogics.kojo package turtle -import java.awt.Color - -import scala.language.dynamics -import scala.language.postfixOps - import net.kogics.kojo.kmath.Kmath +import java.awt.Color +import scala.language.{dynamics, postfixOps} + class LoTurtle(val t: core.Turtle) extends Dynamic { lazy val cmdsu = collection.mutable.HashMap.empty[Symbol, Unit => LoTurtle] lazy val cmdsd = collection.mutable.HashMap.empty[Symbol, Any => LoTurtle] @@ -46,7 +44,7 @@ class LoTurtle(val t: core.Turtle) extends Dynamic { def pc(c: Any) = { t.setPenColor(c.asInstanceOf[Color]); this } def fc(c: Any) = { t.setFillColor(c.asInstanceOf[Color]); this } def pt(n: Any) = { t.setPenThickness(n.asInstanceOf[Int]); this } - def jb(x: Any, y: Any) = { this.hp(x).rt(90).hp(y).lt(90); this } + def jb(x: Any, y: Any) = { this hp x rt 90 hp y lt 90; this } def jt(x: Any, y: Any) = { t.setPosition(toD(x), toD(y)); this } def bon() = { t.beamsOn(); this } def boff() = { t.beamsOff(); this } @@ -82,19 +80,17 @@ class LoTurtle(val t: core.Turtle) extends Dynamic { def applyDynamic(name: String)(args: Any*): LoTurtle = { try { args.size match { - case 0 => cmdsu(Symbol(name)).apply(()) + case 0 => cmdsu(Symbol(name)).apply(()) case 1 if args(0).toString == "()" => cmdsu(Symbol(name)).apply(()) - case 1 => cmdsd(Symbol(name))(args(0)) - case 2 => cmdsdd(Symbol(name))(args(0), args(1)) - case 3 => cmdsddd(Symbol(name))(args(0), args(1), args(2)) - case _ => this + case 1 => cmdsd(Symbol(name))(args(0)) + case 2 => cmdsdd(Symbol(name))(args(0), args(1)) + case 3 => cmdsddd(Symbol(name))(args(0), args(1), args(2)) + case _ => this } } catch { case t: NoSuchElementException => - throw new RuntimeException( - s"Invalid command $name with ${args.length} input(s). Check command name and input(s)." - ) + throw new RuntimeException(s"Invalid command $name with ${args.length} input(s). Check command name and input(s).") } } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/turtle/Turtle.scala b/src/main/scala/net/kogics/kojo/turtle/Turtle.scala index f8d11c80a..3d6ecb160 100644 --- a/src/main/scala/net/kogics/kojo/turtle/Turtle.scala +++ b/src/main/scala/net/kogics/kojo/turtle/Turtle.scala @@ -15,27 +15,21 @@ package net.kogics.kojo package turtle -import java.awt.geom.AffineTransform -import java.awt.geom.Point2D import java.awt.BasicStroke import java.awt.Color import java.awt.Font import java.awt.Image import java.awt.Paint import java.awt.Stroke +import java.awt.geom.AffineTransform +import java.awt.geom.Point2D import java.util.concurrent.CountDownLatch import scala.collection.mutable import com.vividsolutions.jts.geom.Coordinate import com.vividsolutions.jts.geom.GeometryFactory -import edu.umd.cs.piccolo.activities.PActivity -import edu.umd.cs.piccolo.activities.PActivity.PActivityDelegate -import edu.umd.cs.piccolo.nodes.PImage -import edu.umd.cs.piccolo.nodes.PPath -import edu.umd.cs.piccolo.nodes.PText -import edu.umd.cs.piccolo.PLayer -import edu.umd.cs.piccolo.PNode + import net.kogics.kojo.core.Point import net.kogics.kojo.core.SCanvas import net.kogics.kojo.core.Style @@ -48,14 +42,16 @@ import net.kogics.kojo.turtle.TurtleHelper.thetaAfterTurn import net.kogics.kojo.turtle.TurtleHelper.thetaTowards import net.kogics.kojo.util.Utils -class Turtle( - canvas: SCanvas, - costumeFile: String, - initX: Double, - initY: Double, - hidden: Boolean = false, - bottomLayer: Boolean = false -) extends core.Turtle { +import edu.umd.cs.piccolo.PLayer +import edu.umd.cs.piccolo.PNode +import edu.umd.cs.piccolo.activities.PActivity +import edu.umd.cs.piccolo.activities.PActivity.PActivityDelegate +import edu.umd.cs.piccolo.nodes.PImage +import edu.umd.cs.piccolo.nodes.PPath +import edu.umd.cs.piccolo.nodes.PText + +class Turtle(canvas: SCanvas, costumeFile: String, initX: Double, + initY: Double, hidden: Boolean = false, bottomLayer: Boolean = false) extends core.Turtle { // private val Log = Logger.getLogger(getClass.getName) // Log.info("Turtle being created in thread: " + Thread.currentThread.getName) @@ -305,13 +301,13 @@ class Turtle( } } - // called for non-default turtles + // called for non-default turtles def remove() = Utils.runInSwingThread { camera.removeLayer(layer) /*; camera.getRoot().removeChild(layer) */ // this causes a very rare exeception for a subsequent endMove triggered by an earlier stop // so schedule memory reclamation for later - // we're reclaiming memory by clearing turtle fields because there's a reference to turtles - // from the Piccolo animation timer, which makes them leak + // we're reclaiming memory by clearing turtle fields because there's a reference to turtles + // from the Piccolo animation timer, which makes them leak // you can test all of this with VisualVM! Utils.schedule(60) { pen.clear() @@ -374,7 +370,7 @@ class Turtle( throw new IllegalArgumentException("Negative delay not allowed") } // set it right here, as opposed to in the swing thread - // because all users of _animation delay use it within the calling thread + // because all users of _animation delay use it within the calling thread // users are forward, arc, and moveTo _animationDelay = d } @@ -620,7 +616,7 @@ class Turtle( def setCostumes(costumeFiles: Vector[String]) = { require(costumeFiles.length > 1, "You need to specify at least two costumes") Utils.runInSwingThread { - costumes = Some(costumeFiles.map(Utils.loadImageC)) + costumes = Some(costumeFiles map Utils.loadImageC) setCostumeHelper(costumes.get(0)) currCostume = 0 } @@ -637,7 +633,7 @@ class Turtle( def nextCostume() = { Utils.runInSwingThread { - costumes.foreach { cseq => + costumes foreach { cseq => currCostume = if (currCostume == cseq.length - 1) 0 else currCostume + 1 setCostumeHelper(cseq(currCostume)) } @@ -698,7 +694,7 @@ class Turtle( def dumpState(): Unit = { Utils.runInSwingThread { val cIter = layer.getChildrenReference.iterator - println("Turtle Layer (%d children):\n".format(layer.getChildrenReference.size)) + println("Turtle Layer (%d children):\n" format (layer.getChildrenReference.size)) while (cIter.hasNext) { val node = cIter.next.asInstanceOf[PNode] println(stringRep(node)) @@ -708,9 +704,9 @@ class Turtle( private def stringRep(node: PNode): String = node match { case l: PolyLine => - new StringBuilder().append(" Polyline:\n").append(" Points: %s\n".format(l.points)).toString + new StringBuilder().append(" Polyline:\n").append(" Points: %s\n" format l.points).toString case n: PNode => - new StringBuilder().append(" PNode:\n").append(" Children: %s\n".format(n.getChildrenReference)).toString + new StringBuilder().append(" PNode:\n").append(" Children: %s\n" format n.getChildrenReference).toString } abstract class AbstractPen extends Pen { @@ -878,4 +874,4 @@ class Turtle( ptext.repaint() } } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/turtle/TurtleHelper.scala b/src/main/scala/net/kogics/kojo/turtle/TurtleHelper.scala index 5b1d68f9c..f8bc0c7bb 100644 --- a/src/main/scala/net/kogics/kojo/turtle/TurtleHelper.scala +++ b/src/main/scala/net/kogics/kojo/turtle/TurtleHelper.scala @@ -19,7 +19,7 @@ package turtle import util.Utils object TurtleHelper { - + def posAfterForward(x: Double, y: Double, theta: Double, n: Double): (Double, Double) = { val delX = math.cos(theta) * n val delY = math.sin(theta) * n @@ -30,34 +30,34 @@ object TurtleHelper { val (x0, y0) = (px, py) val delX = x - x0 val delY = y - y0 - if (Utils.doublesEqual(delX, 0, 0.001)) { - if (Utils.doublesEqual(delY, 0, 0.001)) oldTheta - else if (delY > 0) math.Pi / 2 - else 3 * math.Pi / 2 + if (Utils.doublesEqual(delX,0,0.001)) { + if (Utils.doublesEqual(delY,0,0.001)) oldTheta + else if (delY > 0) math.Pi/2 + else 3*math.Pi/2 } - else if (Utils.doublesEqual(delY, 0, 0.001)) { + else if (Utils.doublesEqual(delY,0,0.001)) { if (delX > 0) 0 else math.Pi } else { - var nt2 = math.atan(delY / delX) + var nt2 = math.atan(delY/delX) if (delX < 0 && delY > 0) nt2 += math.Pi else if (delX < 0 && delY < 0) nt2 += math.Pi - else if (delX > 0 && delY < 0) nt2 += 2 * math.Pi + else if (delX > 0 && delY < 0) nt2 += 2* math.Pi nt2 } } def thetaAfterTurn(angle: Double, oldTheta: Double) = { var newTheta = oldTheta + Utils.deg2radians(angle) - if (newTheta < 0) newTheta = newTheta % (2 * math.Pi) + 2 * math.Pi - else if (newTheta > 2 * math.Pi) newTheta = newTheta % (2 * math.Pi) + if (newTheta < 0) newTheta = newTheta % (2*math.Pi) + 2*math.Pi + else if (newTheta > 2*math.Pi) newTheta = newTheta % (2*math.Pi) newTheta } def distance(x0: Double, y0: Double, x: Double, y: Double): Double = { - val delX = x - x0 - val delY = y - y0 + val delX = x-x0 + val delY = y-y0 math.sqrt(delX * delX + delY * delY) } } diff --git a/src/main/scala/net/kogics/kojo/turtle/TurtleWorldAPI.scala b/src/main/scala/net/kogics/kojo/turtle/TurtleWorldAPI.scala index 0b7d3fe3f..9374d7472 100644 --- a/src/main/scala/net/kogics/kojo/turtle/TurtleWorldAPI.scala +++ b/src/main/scala/net/kogics/kojo/turtle/TurtleWorldAPI.scala @@ -27,11 +27,7 @@ class TurtleWorldAPI(turtle0: => core.Turtle) extends TurtleMover { def jumpTo(x: Double, y: Double) = turtle0.jumpTo(x, y) UserCommand.addCompletion("jumpTo", List("x", "y")) - UserCommand( - "setPosition", - List("x", "y"), - "Sends the turtle to the point (x, y) without drawing a line. The turtle's heading is not changed." - ) + UserCommand("setPosition", List("x", "y"), "Sends the turtle to the point (x, y) without drawing a line. The turtle's heading is not changed.") def position: Point = turtle0.position UserCommand.addSynopsis("position - Queries the turtle's position.") @@ -41,11 +37,7 @@ class TurtleWorldAPI(turtle0: => core.Turtle) extends TurtleMover { UserCommand("moveTo", List("x", "y"), "Turns the turtle towards (x, y) and moves the turtle to that point. ") def turn(angle: Double) = turtle0.turn(angle) - UserCommand( - "turn", - List("angle"), - "Turns the turtle through a specified angle. Angles are positive for counter-clockwise turns." - ) + UserCommand("turn", List("angle"), "Turns the turtle through a specified angle. Angles are positive for counter-clockwise turns.") UserCommand("right", Nil, "Turns the turtle 90 degrees right (clockwise).") UserCommand("right", List("angle"), "Turns the turtle angle degrees right (clockwise).") @@ -56,16 +48,10 @@ class TurtleWorldAPI(turtle0: => core.Turtle) extends TurtleMover { def towards(x: Double, y: Double) = turtle0.towards(x, y) UserCommand("towards", List("x", "y"), "Turns the turtle towards the point (x, y).") - UserCommand( - "setHeading", - List("angle"), - "Sets the turtle's heading to angle (0 is towards the right side of the screen ('east'), 90 is up ('north'))." - ) + UserCommand("setHeading", List("angle"), "Sets the turtle's heading to angle (0 is towards the right side of the screen ('east'), 90 is up ('north')).") def heading: Double = turtle0.heading - UserCommand.addSynopsis( - "heading - Queries the turtle's heading (0 is towards the right side of the screen ('east'), 90 is up ('north'))." - ) + UserCommand.addSynopsis("heading - Queries the turtle's heading (0 is towards the right side of the screen ('east'), 90 is up ('north')).") UserCommand.addSynopsisSeparator() def penDown() = turtle0.penDown() @@ -122,11 +108,7 @@ class TurtleWorldAPI(turtle0: => core.Turtle) extends TurtleMover { UserCommand("write", List("obj"), "Makes the turtle write the specified object as a string at its current location.") def setAnimationDelay(d: Long) = turtle0.setAnimationDelay(d) - UserCommand( - "setAnimationDelay", - List("delay"), - "Sets the turtle's speed. The specified delay is the amount of time (in milliseconds) taken by the turtle to move through a distance of one hundred steps." - ) + UserCommand("setAnimationDelay", List("delay"), "Sets the turtle's speed. The specified delay is the amount of time (in milliseconds) taken by the turtle to move through a distance of one hundred steps.") def animationDelay = turtle0.animationDelay UserCommand.addSynopsis("animationDelay - Queries the turtle's delay setting.") @@ -142,11 +124,7 @@ class TurtleWorldAPI(turtle0: => core.Turtle) extends TurtleMover { def setCostumeImage(image: Image) = turtle0.setCostumeImage(image) def setCostume(costumeFile: String) = turtle0.setCostume(costumeFile) - UserCommand( - "setCostume", - List("costumeFile"), - "Changes the costume (i.e. image) associated with the turtle to the image in the specified file." - ) + UserCommand("setCostume", List("costumeFile"), "Changes the costume (i.e. image) associated with the turtle to the image in the specified file.") def setCostumes(costumeFiles: Vector[String]) = turtle0.setCostumes(costumeFiles) def setCostumeImages(images: Vector[Image]) = turtle0.setCostumeImages(images) diff --git a/src/main/scala/net/kogics/kojo/util/AsyncQueuedRunner.scala b/src/main/scala/net/kogics/kojo/util/AsyncQueuedRunner.scala index f6a6a81f9..76de71569 100644 --- a/src/main/scala/net/kogics/kojo/util/AsyncQueuedRunner.scala +++ b/src/main/scala/net/kogics/kojo/util/AsyncQueuedRunner.scala @@ -23,3 +23,4 @@ trait AsyncQueuedRunner { } } } + diff --git a/src/main/scala/net/kogics/kojo/util/Constants.scala b/src/main/scala/net/kogics/kojo/util/Constants.scala index dfb67397a..f2c1db090 100644 --- a/src/main/scala/net/kogics/kojo/util/Constants.scala +++ b/src/main/scala/net/kogics/kojo/util/Constants.scala @@ -2,4 +2,4 @@ package net.kogics.kojo.util object Constants { val DropDownCanvasPadding = " " * 5 -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/util/PuzzleLoader.scala b/src/main/scala/net/kogics/kojo/util/PuzzleLoader.scala index 9a931b16f..f325da10a 100644 --- a/src/main/scala/net/kogics/kojo/util/PuzzleLoader.scala +++ b/src/main/scala/net/kogics/kojo/util/PuzzleLoader.scala @@ -14,13 +14,11 @@ */ package net.kogics.kojo.util +import java.util.jar._ import java.io._ import java.io.File -import java.util.jar._ -import java.util.ArrayList -import java.util.HashMap - import net.kogics.kojo.util._ +import java.util.{HashMap, ArrayList} object PuzzleLoader { diff --git a/src/main/scala/net/kogics/kojo/util/ScalatestHelper.scala b/src/main/scala/net/kogics/kojo/util/ScalatestHelper.scala index 9c5e22ee8..446a65191 100644 --- a/src/main/scala/net/kogics/kojo/util/ScalatestHelper.scala +++ b/src/main/scala/net/kogics/kojo/util/ScalatestHelper.scala @@ -22,3 +22,4 @@ object ScalatestHelper { suite.execute() } } + diff --git a/src/main/scala/net/kogics/kojo/util/TerminalAnsiCodes.scala b/src/main/scala/net/kogics/kojo/util/TerminalAnsiCodes.scala index f487a4aea..f185acf54 100644 --- a/src/main/scala/net/kogics/kojo/util/TerminalAnsiCodes.scala +++ b/src/main/scala/net/kogics/kojo/util/TerminalAnsiCodes.scala @@ -28,7 +28,7 @@ object TerminalAnsiCodes { def parse(s: String): collection.Seq[(String, Color)] = { val strs = s.split(s"$ESC\\[") - strs.filter { _.length > 0 }.map { ss => + strs filter { _.length > 0 } map { ss => val mindex = ss.indexOf('m') val clr = ss.substring(0, mindex) match { case "0" => NormalColor @@ -39,4 +39,4 @@ object TerminalAnsiCodes { (ss.substring(mindex + 1, ss.length), clr) } } -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/util/Throttler.scala b/src/main/scala/net/kogics/kojo/util/Throttler.scala index 439d57728..1c815b0b1 100644 --- a/src/main/scala/net/kogics/kojo/util/Throttler.scala +++ b/src/main/scala/net/kogics/kojo/util/Throttler.scala @@ -16,7 +16,7 @@ package net.kogics.kojo.util object Throttler { val systemThrottler = new Throttler(100, 0) - val hardSystemThrottler = new Throttler(100, 10) + val hardSystemThrottler = new Throttler(100, 10) def throttle() = systemThrottler.throttle() def throttleHard() = hardSystemThrottler.throttle() } @@ -26,9 +26,11 @@ class Throttler(after: Int, sleepTime: Int) { override def initialValue = 0 } - /** Slow things down if stuff is happening too quickly Meant to slow down runaway computation inside the interpreter, - * so that the user can interrupt the runaway thread - */ + /** + * Slow things down if stuff is happening too quickly + * Meant to slow down runaway computation inside the interpreter, so that the + * user can interrupt the runaway thread + */ def throttle(): Unit = { val nc = numCalls.get + 1 if (nc > after) { diff --git a/src/main/scala/net/kogics/kojo/util/Unzipper.scala b/src/main/scala/net/kogics/kojo/util/Unzipper.scala index 1a499e792..a06312314 100644 --- a/src/main/scala/net/kogics/kojo/util/Unzipper.scala +++ b/src/main/scala/net/kogics/kojo/util/Unzipper.scala @@ -1,14 +1,8 @@ package net.kogics.kojo.util -import java.io.BufferedOutputStream -import java.io.File -import java.io.FileInputStream -import java.io.FileOutputStream -import java.io.InputStream -import java.net.HttpURLConnection -import java.net.URL -import java.util.zip.ZipEntry -import java.util.zip.ZipInputStream +import java.io.{BufferedOutputStream, File, FileInputStream, FileOutputStream, InputStream} +import java.net.{HttpURLConnection, URL} +import java.util.zip.{ZipEntry, ZipInputStream} import scala.reflect.io.Directory diff --git a/src/main/scala/net/kogics/kojo/util/Utils.scala b/src/main/scala/net/kogics/kojo/util/Utils.scala index 2b444a0a4..70f416e9a 100644 --- a/src/main/scala/net/kogics/kojo/util/Utils.scala +++ b/src/main/scala/net/kogics/kojo/util/Utils.scala @@ -15,15 +15,15 @@ package net.kogics.kojo package util -import java.awt.event.ActionEvent -import java.awt.event.ActionListener -import java.awt.event.KeyEvent -import java.awt.image.BufferedImage import java.awt.Color import java.awt.EventQueue import java.awt.Font import java.awt.Image import java.awt.Toolkit +import java.awt.event.ActionEvent +import java.awt.event.ActionListener +import java.awt.event.KeyEvent +import java.awt.image.BufferedImage import java.io.BufferedInputStream import java.io.BufferedReader import java.io.File @@ -36,36 +36,38 @@ import java.io.PrintWriter import java.io.StringWriter import java.net.InetAddress import java.net.URL -import java.util.concurrent.locks.Lock -import java.util.concurrent.locks.ReentrantLock +import java.util.LinkedList +import java.util.Locale +import java.util.Properties +import java.util.ResourceBundle import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit +import java.util.concurrent.locks.Lock +import java.util.concurrent.locks.ReentrantLock import java.util.logging.Level import java.util.logging.Logger -import java.util.LinkedList -import java.util.Locale -import java.util.Properties -import java.util.ResourceBundle + import javax.imageio.ImageIO -import javax.swing.text.JTextComponent import javax.swing.ImageIcon import javax.swing.JComponent import javax.swing.JDialog import javax.swing.KeyStroke import javax.swing.Timer +import javax.swing.text.JTextComponent import scala.collection.mutable import scala.collection.mutable.HashMap -import akka.actor.ActorSystem -import edu.umd.cs.piccolo.event.PInputEvent import net.kogics.kojo.core.CodingMode +import net.kogics.kojo.core.VanillaMode import net.kogics.kojo.core.KojoCtx import net.kogics.kojo.core.TwMode -import net.kogics.kojo.core.VanillaMode import net.kogics.kojo.util.RichFile.enrichFile +import akka.actor.ActorSystem +import edu.umd.cs.piccolo.event.PInputEvent + object Utils { lazy val Log = Logger.getLogger("Utils") lazy val imageCache = new HashMap[String, BufferedImage] @@ -132,17 +134,15 @@ object Utils { readStream(getClass.getResourceAsStream(res)) } - /** Returns the content of the given file in the local variant selected by Locale.getDefault(). At first tries to find - * a resource of the given file name in the subdirectory LL of the given root directory, if the current default - * Locale has language LL selected. If this resource is not found, then tries to find the given file directly in the - * named root directory. - * @param root - * directory path inside the classpath. Should begin and end in '/', as "/samples". - * @param file - * file name with extension in the given root directory, as "tree0.kojo". - * @throws IllegalArgumentException - * the named file is found neither in the local variant for the default Locale, nor in the base variant. - */ + /** + * Returns the content of the given file in the local variant selected by Locale.getDefault(). + * At first tries to find a resource of the given file name in the subdirectory LL of the given root directory, + * if the current default Locale has language LL selected. + * If this resource is not found, then tries to find the given file directly in the named root directory. + * @param root directory path inside the classpath. Should begin and end in '/', as "/samples". + * @param file file name with extension in the given root directory, as "tree0.kojo". + * @throws IllegalArgumentException the named file is found neither in the local variant for the default Locale, nor in the base variant. + */ def loadLocalizedResource(root: String, file: String): String = { val locale = Locale.getDefault val langCode = locale.getLanguage @@ -218,16 +218,9 @@ object Utils { def inSwingThread = EventQueue.isDispatchThread def runAsync(fn: => Unit): Unit = { - import scala.util.control.NonFatal new Thread(new Runnable { def run: Unit = { - try { - fn - } - catch { - case NonFatal(e) => - Log.log(Level.WARNING, "Problem on async runner thread", e) - } + fn } }).start } @@ -386,8 +379,7 @@ object Utils { } } - def runInSwingThreadAndPause[T](fn: => T): T = - runInSwingThreadAndWait(GuiTimeout, "Potential Deadlock. Bailing out!")(fn) + def runInSwingThreadAndPause[T](fn: => T): T = runInSwingThreadAndWait(GuiTimeout, "Potential Deadlock. Bailing out!")(fn) def runInSwingThreadAndWait[T](timeout: Long, msg: String)(fn: => T): T = { if (inSwingThread) { @@ -419,46 +411,37 @@ object Utils { } def schedule(secs: Double)(f: => Unit): Timer = { - lazy val t: Timer = new Timer( - (secs * 1000).toInt, - new ActionListener { - def actionPerformed(e: ActionEvent): Unit = { - t.stop - f - } + lazy val t: Timer = new Timer((secs * 1000).toInt, new ActionListener { + def actionPerformed(e: ActionEvent): Unit = { + t.stop + f } - ) + }) t.start t } def scheduleRec(secs: Double)(f: => Unit): Timer = { - val t: Timer = new Timer( - (secs * 1000).toInt, - new ActionListener { - def actionPerformed(e: ActionEvent): Unit = { - f - } + val t: Timer = new Timer((secs * 1000).toInt, new ActionListener { + def actionPerformed(e: ActionEvent): Unit = { + f } - ) + }) t.start t } def scheduleRecN(n: Int, secs: Double)(f: => Unit): Timer = { @volatile var count = 0 - lazy val t: Timer = new Timer( - (secs * 1000).toInt, - new ActionListener { - def actionPerformed(e: ActionEvent): Unit = { - count += 1 - if (count == n) { - t.stop() - } - f + lazy val t: Timer = new Timer((secs * 1000).toInt, new ActionListener { + def actionPerformed(e: ActionEvent): Unit = { + count += 1 + if (count == n) { + t.stop() } + f } - ) + }) t.start t } @@ -552,20 +535,19 @@ object Utils { if (keyWithStrings) s"[$key]" else "" } - /** Returns the localized String for the given key. - * @throws NullPointerException - * if key is null - * @throws MissingResourceException - * if no object for the given key can be found - */ + /** + * Returns the localized String for the given key. + * @throws NullPointerException if key is null + * @throws MissingResourceException if no object for the given key can be found + */ def loadString(key: String) = { - messages.getString(key).concat(stringSuffix(key)) + messages.getString(key) concat stringSuffix(key) } def loadString(klass: Class[_], key: String) = { - messages.getString(key).concat(stringSuffix(key)) + messages.getString(key) concat stringSuffix(key) } def loadString(klass: Class[_], key: String, args: AnyRef*) = { - messages.getString(key).format(args: _*).concat(stringSuffix(key)) + (messages.getString(key) format (args: _*)) concat stringSuffix(key) } // Loads the actual string in the bundle without the debug key suffix @@ -576,14 +558,11 @@ object Utils { def filesInDir(dir: String, ext: String): List[String] = { val osDir = new File(dir) if (osDir.exists && osDir.isDirectory) { - osDir - .list(new FilenameFilter { - override def accept(dir: File, name: String) = { - name.endsWith("." + ext) - } - }) - .toList - .sorted + osDir.list(new FilenameFilter { + override def accept(dir: File, name: String) = { + name.endsWith("." + ext) + } + }).toList.sorted } else { Nil @@ -593,13 +572,11 @@ object Utils { def numFilesInDir(dir: String, ext: String): Int = { val osDir = new File(dir) if (osDir.exists && osDir.isDirectory) { - osDir - .list(new FilenameFilter { - override def accept(dir: File, name: String) = { - name.endsWith("." + ext) - } - }) - .length + osDir.list(new FilenameFilter { + override def accept(dir: File, name: String) = { + name.endsWith("." + ext) + } + }).length } else { 0 @@ -609,15 +586,11 @@ object Utils { def dirsInDir(dir: String): List[String] = { val osDir = new File(dir) if (osDir.exists && osDir.isDirectory) { - osDir - .list(new FilenameFilter { - override def accept(dir: File, name: String) = { - dir.isDirectory - } - }) - .sorted - .map { subDir => dir + File.separatorChar + subDir } - .toList + osDir.list(new FilenameFilter { + override def accept(dir: File, name: String) = { + dir.isDirectory + } + }).sorted.map { subDir => dir + File.separatorChar + subDir }.toList } else { Nil @@ -634,7 +607,7 @@ object Utils { lazy val extensionsDir = userDir + File.separatorChar + ".kojo/extension" - /** Locates where the log directory should be, creates it if necessary, and returns its File object. */ + /**Locates where the log directory should be, creates it if necessary, and returns its File object.*/ def locateLogDir(): File = { val logDir = new File(s"$userDir/.kojo/lite/log/") if (!logDir.exists()) { @@ -661,19 +634,16 @@ object Utils { def initkCode(mode: CodingMode): Option[String] = initCodeCache.getOrElseUpdate( mode, - (codeFromScripts(modeFilter(initScripts, mode), initScriptDir) |+| langInit(mode)).map(stripCR) + (codeFromScripts(modeFilter(initScripts, mode), initScriptDir) |+| langInit(mode)) map stripCR ) def codeFromScripts(scripts: List[String], scriptDir: String): Option[String] = scripts match { case Nil => None - case files => - Some( - files - .map { file => - "// File: %s\n%s\n".format(file, readStream(new FileInputStream(scriptDir + File.separatorChar + file))) - } - .mkString("\n") - ) + case files => Some( + files.map { file => + "// File: %s\n%s\n".format(file, readStream(new FileInputStream(scriptDir + File.separatorChar + file))) + }.mkString("\n") + ) } def initCode(mode: CodingMode): Option[String] = { @@ -695,14 +665,7 @@ object Utils { tnode } - def textNode( - text: String, - x: Double, - y: Double, - camScale: Double, - fontSize: Int, - fontName0: Option[String] = None - ): PText = { + def textNode(text: String, x: Double, y: Double, camScale: Double, fontSize: Int, fontName0: Option[String] = None): PText = { val tnode = textNode(text, x, y, camScale) val fontName = fontName0 match { case Some(name) => name @@ -802,7 +765,7 @@ object Utils { def stripDots(s: String): String = s.filterNot { _ == '.' } lazy val (needsSanitizing, decimalSep) = { - val tester = "%.1f".format(0.0) + val tester = "%.1f" format (0.0) (tester != "0.0", tester(1).toString) } @@ -857,7 +820,7 @@ object Utils { included.add(fileName) val fileContent = readFileContent val codeToInclude = s"// #begin-include: $fileName\n$fileContent\n// #end-include: $fileName\n" - val (result, _, _) = _preProcessInclude(codeToInclude) // non-tail-recursive call + val (result, _, _) = _preProcessInclude(codeToInclude) //non-tail-recursive call result } } @@ -997,17 +960,15 @@ object Utils { def closeOnEsc(dlg: JDialog): Unit = { dlg.getRootPane.registerKeyboardAction( - _ => dlg.setVisible(false), - KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + _ => dlg.setVisible(false), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW ) } lazy val javaMajorVersion = { val version = System.getProperty("java.specification.version").split('.') - val major = - if (version(0) == "1") version(1) // 1.8 is 8 - else version(0) // later versions are 9, 10, etc + val major = if (version(0) == "1") version(1) // 1.8 is 8 + else version(0) // later versions are 9, 10, etc major.toInt } diff --git a/src/main/scala/net/kogics/kojo/util/Vector2D.scala b/src/main/scala/net/kogics/kojo/util/Vector2D.scala index 0c08a5aa1..a22148fe6 100644 --- a/src/main/scala/net/kogics/kojo/util/Vector2D.scala +++ b/src/main/scala/net/kogics/kojo/util/Vector2D.scala @@ -61,7 +61,7 @@ case class Vector2D(x: Double, y: Double) { override def toString = "Vector2D(%.2f , %.2f)".format(x, y) override def equals(other: Any) = other match { case v: Vector2D => - Utils.doublesEqual(x, v.x, 1e-6) && Utils.doublesEqual(y, v.y, 1e-6) + Utils.doublesEqual(x, v.x, 1e-6) && Utils.doublesEqual(y, v.y, 1e-6) case _ => false } } diff --git a/src/main/scala/net/kogics/kojo/util/typeclasses.scala b/src/main/scala/net/kogics/kojo/util/typeclasses.scala index ba2e8f3ad..145571ee8 100644 --- a/src/main/scala/net/kogics/kojo/util/typeclasses.scala +++ b/src/main/scala/net/kogics/kojo/util/typeclasses.scala @@ -18,7 +18,9 @@ import language.implicitConversions // Ideas and a good bit of code borrowed from Scalaz: https://github.com/scalaz/scalaz // Can't afford to bundle all of Scalaz within Kojo just yet (because of size constraints) -object Typeclasses extends Semigroups with Identitys with Function2s { +object Typeclasses extends Semigroups + with Identitys + with Function2s { def some[A](a: A): Option[A] = Some(a) def none[A] = None } @@ -38,18 +40,16 @@ object Semigroup { implicit def StringSemigroup: Semigroup[String] = semigroup(_ + _) implicit def IntSemigroup: Semigroup[Int] = semigroup(_ + _) implicit def ListSemigroup[A]: Semigroup[List[A]] = semigroup(_ ++ _) - implicit def OptionSemigroup[A: Semigroup]: Semigroup[Option[A]] = semigroup((a, b) => { - (a, b) match { - case (Some(va), Some(vb)) => Some(va |+| vb) - case (Some(va), None) => Some(va) - case (None, Some(vb)) => Some(vb) - case (None, None) => None - } - }) + implicit def OptionSemigroup[A : Semigroup]: Semigroup[Option[A]] = semigroup((a, b) => { (a,b) match { + case (Some(va), Some(vb)) => Some(va |+| vb) + case (Some(va), None) => Some(va) + case (None, Some(vb)) => Some(vb) + case (None, None) => None + }}) - implicit def MapSemigroup[K, V](implicit ss: Semigroup[V]): Semigroup[Map[K, V]] = semigroup { (m1, m2) => - { - // semigroups are not commutative, so order may matter. + implicit def MapSemigroup[K, V](implicit ss: Semigroup[V]): Semigroup[Map[K, V]] = semigroup { + (m1, m2) => { + // semigroups are not commutative, so order may matter. val (from, to, semigroup) = { if (m1.size > m2.size) (m2, m1, ss.append(_: V, _: V)) else (m1, m2, (ss.append(_: V, _: V)).flip) @@ -62,7 +62,7 @@ object Semigroup { } } -trait Identity[A] { +trait Identity[A] { def value: A def |+|(a: => A)(implicit s: Semigroup[A]): A = s.append(value, a) } @@ -74,7 +74,7 @@ trait Identitys { val unital = mkIdentity(()) } -object Identity { +object Identity { def apply[A](a: => A): Identity[A] = new Identity[A] { lazy val value = a } @@ -83,7 +83,7 @@ object Identity { sealed trait Function2W[T1, T2, R] { val k: (T1, T2) => R - def flip: (T2, T1) => R = (v2: T2, v1: T1) => k(v1, v2) + def flip : (T2, T1) => R = (v2: T2, v1: T1) => k(v1, v2) } trait Function2s { @@ -91,4 +91,4 @@ trait Function2s { val k = f } implicit def Function2From[T1, T2, R](f: Function2W[T1, T2, R]): (T1, T2) => R = f.k -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/util/ziptools.scala b/src/main/scala/net/kogics/kojo/util/ziptools.scala index 78b7a8e92..cb2f5f765 100644 --- a/src/main/scala/net/kogics/kojo/util/ziptools.scala +++ b/src/main/scala/net/kogics/kojo/util/ziptools.scala @@ -1,8 +1,8 @@ // This was built to strip the signatures from the Kojo jars under Webstart // That solved the slow Tracing problem under Webstart // Since then, a better solution has been discovered to solve the slow Tracing problem under Webstart -// Now, this stuff depends on commons-compress, which we don't want to include for the Webstart App because it is not needed any more -// So we comment out this code, to avoid having it in a production environment without its commons-compress dependency being available +// Now, this stuff depends on commons-compress, which we don't want to include for the Webstart App because it is not needed any more +// So we comment out this code, to avoid having it in a production environment without its commons-compress dependency being available ///* // * Copyright (C) 2013 Lalit Pant @@ -106,4 +106,4 @@ // srcZip.close() // destZip.close() // } -//} +//} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/widget/swingwrappers.scala b/src/main/scala/net/kogics/kojo/widget/swingwrappers.scala index 5fc4b0697..d0b1d2eff 100644 --- a/src/main/scala/net/kogics/kojo/widget/swingwrappers.scala +++ b/src/main/scala/net/kogics/kojo/widget/swingwrappers.scala @@ -1,11 +1,12 @@ package net.kogics.kojo.widget +import java.awt.Color +import java.awt.FlowLayout import java.awt.event.ActionEvent import java.awt.event.ActionListener import java.awt.event.HierarchyEvent import java.awt.event.HierarchyListener -import java.awt.Color -import java.awt.FlowLayout + import javax.swing.Box import javax.swing.BoxLayout import javax.swing.DefaultComboBoxModel @@ -160,4 +161,4 @@ case class Slider(min: Int, max: Int, curr: Int, spacing: Int) extends JSlider { setPaintLabels(true) setSnapToTicks(true) def value = getValue -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/xscala/CodeCompletionUtils.scala b/src/main/scala/net/kogics/kojo/xscala/CodeCompletionUtils.scala index a8831e9d4..7520fe986 100644 --- a/src/main/scala/net/kogics/kojo/xscala/CodeCompletionUtils.scala +++ b/src/main/scala/net/kogics/kojo/xscala/CodeCompletionUtils.scala @@ -58,8 +58,7 @@ object CodeCompletionUtils { "var", "while", "with", - "yield" - ) + "yield") val KeywordTemplates = Map( "for" -> "for (i <- 1 to ${n}) {\n ${cursor}\n}", @@ -224,8 +223,8 @@ object CodeCompletionUtils { "breakpoint" -> "breakpoint(${msg})", "beginShape" -> "beginShape()", "endShape" -> "endShape()" - ) - +) + val TwMethodTemplates = Map( "turnNorth" -> "turnNorth()", "turnSouth" -> "turnSouth()", @@ -242,7 +241,7 @@ object CodeCompletionUtils { "morph" -> "morph { polyLines =>\n ${cursor}\n}", "PolyLine" -> "PolyLine(List(Point2D(${x1}, ${y1}), Point2D(${x2}, ${y2})))", "dot" -> "dot(${diameter})", - + // Picture Completions "InputAware.onMousePress" -> "onMousePress { (x, y) =>\n ${cursor}\n}", "InputAware.onMouseRelease" -> "onMouseRelease { (x, y) =>\n ${cursor}\n}", @@ -278,30 +277,30 @@ object CodeCompletionUtils { def addTemplates(lang: String, templates: Map[String, String]): Unit = { // import util.Typeclasses._ // langTemplates += (lang -> (langTemplates.getOrElse(lang, Map()) |+| templates)) - langTemplates += (lang -> (langTemplates.getOrElse(lang, Map()) ++ templates)) + langTemplates += (lang -> (langTemplates.getOrElse(lang, Map()) ++ templates)) } - + def clearLangTemplates(): Unit = { langTemplates.clear() } - + def langMethodTemplate(name: String, lang: String): Option[String] = { langTemplates.get(lang) match { case Some(ts) => ts.get(name) - case None => None + case None => None } } - + def methodTemplate(completion: String): String = { BuiltinsMethodTemplates.getOrElse( completion, ExtraMethodTemplates.getOrElse( - completion, + completion, langMethodTemplate(completion, System.getProperty("user.language")).getOrElse(null) ) ) } - + def keywordTemplate(completion: String) = { KeywordTemplates.getOrElse(completion, null) } @@ -311,13 +310,13 @@ object CodeCompletionUtils { val InternalVarsRe = java.util.regex.Pattern.compile("""res\d+|\p{Punct}.*""") val InternalMethodsRe = java.util.regex.Pattern.compile("""_.*|.*\$.*""") - def notIdChar(c: Char): Boolean = NotIdChars.contains(c) + def notIdChar(c: Char): Boolean = NotIdChars.contains(c) def findLastIdentifier(rstr: String): Option[String] = { val str = " " + rstr var remaining = str.length - while (remaining > 0) { - if (notIdChar(str(remaining - 1))) return Some(str.substring(remaining)) + while(remaining > 0) { + if (notIdChar(str(remaining-1))) return Some(str.substring(remaining)) remaining -= 1 } None @@ -327,13 +326,13 @@ object CodeCompletionUtils { if (str.length == 0) return (None, None) if (str.endsWith(".")) { - (findLastIdentifier(str.substring(0, str.length - 1)), None) + (findLastIdentifier(str.substring(0, str.length-1)), None) } else { val lastDot = str.lastIndexOf('.') if (lastDot == -1) (None, findLastIdentifier(str)) else { - val tPrefix = str.substring(lastDot + 1) + val tPrefix = str.substring(lastDot+1) if (tPrefix == findLastIdentifier(tPrefix).get) (findLastIdentifier(str.substring(0, lastDot)), Some(tPrefix)) else diff --git a/src/main/scala/net/kogics/kojo/xscala/CodeTemplates.scala b/src/main/scala/net/kogics/kojo/xscala/CodeTemplates.scala index c80f89bd9..6a8b1b327 100644 --- a/src/main/scala/net/kogics/kojo/xscala/CodeTemplates.scala +++ b/src/main/scala/net/kogics/kojo/xscala/CodeTemplates.scala @@ -180,8 +180,8 @@ draw(pic) ) def apply(name: String) = templates(name) - def asString(name: String) = + def asString(name: String) = xml.Utility.escape(templates(name).replace("${cursor}", "|").replace("$", "")).replace("\n", "
    ") def beforeCursor(name: String) = templates(name).split("""\$\{cursor\}""")(0) def afterCursor(name: String) = templates(name).split("""\$\{cursor\}""")(1) -} +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala b/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala index 8ba5e7a03..eeccf7195 100644 --- a/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala +++ b/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala @@ -20,17 +20,17 @@ import java.net.URL import scala.collection.mutable.ListBuffer import scala.language.postfixOps +import scala.reflect.internal.Flags import scala.reflect.internal.util.AbstractFileClassLoader import scala.reflect.internal.util.BatchSourceFile import scala.reflect.internal.util.OffsetPosition import scala.reflect.internal.util.Position import scala.reflect.internal.util.ScalaClassLoader.URLClassLoader -import scala.reflect.internal.Flags +import scala.tools.nsc.Global +import scala.tools.nsc.Settings import scala.tools.nsc.interactive import scala.tools.nsc.io.VirtualDirectory import scala.tools.nsc.reporters.Reporter -import scala.tools.nsc.Global -import scala.tools.nsc.Settings import scala.tools.util.PathResolver import net.kogics.kojo.core.CompletionInfo @@ -55,19 +55,19 @@ trait CompilerListener { // This class borrows code and ideas from scala.tools.nsc.Interpreter class CompilerAndRunner( - makeSettings: () => Settings, - initCode: => Option[String], - listener: CompilerListener, - runContext: RunContext + makeSettings: () => Settings, + initCode: => Option[String], + listener: CompilerListener, + runContext: RunContext ) extends StoppableCodeRunner { import language.postfixOps var counter = 0 - // The Counter above is used to define/create a new wrapper object for every run. The calling of the entry() - // .method within this object results in the initialization of the object, which causes the user submitted + // The Counter above is used to define/create a new wrapper object for every run. The calling of the entry() + //.method within this object results in the initialization of the object, which causes the user submitted // code to run. // If we don't increment the counter, the user code will not run (an object is initialized only once) - // If this approach turns out to be too memory intensive, I'm sure there are other ways of running user + // If this approach turns out to be too memory intensive, I'm sure there are other ways of running user // submitted code.' val prefixHeader = "object Wrapper" val prefix0 = runContext.compilerPrefix @@ -104,21 +104,20 @@ class CompilerAndRunner( val compilerClasspath: List[URL] = new PathResolver(settings).resultAsURLs.toList var classLoader = makeClassLoader - // needed to prevent pcompiler from making the interp's classloader as + // needed to prevent pcompiler from making the interp's classloader as // its context loader (which causes a mem leak) - // we could make pcompiler lazy, but then the first completion takes a big hit + // we could make pcompiler lazy, but then the first completion takes a big hit private def makeClassLoader = { val parent = new URLClassLoader(compilerClasspath, getClass.getClassLoader()) new AbstractFileClassLoader(virtualDirectory, parent) } - private def loadByName(s: String): Class[_] = classLoader.loadClass(s) + private def loadByName(s: String): Class[_] = (classLoader loadClass s) val reporter = new Reporter { override def info0(position: Position, msg: String, severity: Severity, force: Boolean): Unit = { // severity.count += 1 - lazy val line = - position.line - prefixLines - 1 // we added an extra line after the prefix in the code template. Take it off + lazy val line = position.line - prefixLines - 1 // we added an extra line after the prefix in the code template. Take it off lazy val offset = position.start - offsetDelta - 1 // we added an extra newline char after the prefix severity match { case ERROR if position.isDefined => @@ -154,23 +153,21 @@ class CompilerAndRunner( } def compile(code0: String, stopPhase: List[String] = List("cleanup")) = { - compilerCode(code0) - .map { code => - if (compiler.settings.stopAfter.value != stopPhase) { - // There seems to be a bug in the PhasesSetting contains method - // which makes the compiler not see the new stopAfter value - // So we make a new Settings - compiler.currentSettings = makeSettings2() - compiler.settings.stopAfter.value = stopPhase - } - - val run = new compiler.Run - reporter.reset() - run.compileSources(List(new BatchSourceFile("scripteditor", code))) - // println(s"[Debug] Script checking done till phase: ${compiler.globalPhase.prev}") - if (reporter.hasErrors) IR.Error else IR.Success + compilerCode(code0) map { code => + if (compiler.settings.stopAfter.value != stopPhase) { + // There seems to be a bug in the PhasesSetting contains method + // which makes the compiler not see the new stopAfter value + // So we make a new Settings + compiler.currentSettings = makeSettings2() + compiler.settings.stopAfter.value = stopPhase } - .getOrElse(IR.Error) + + val run = new compiler.Run + reporter.reset() + run.compileSources(List(new BatchSourceFile("scripteditor", code))) + // println(s"[Debug] Script checking done till phase: ${compiler.globalPhase.prev}") + if (reporter.hasErrors) IR.Error else IR.Success + } getOrElse (IR.Error) } def compileAndRun(code0: String) = { @@ -188,7 +185,7 @@ class CompilerAndRunner( try { classLoader = makeClassLoader classLoader.asContext { - val loadedResultObject = loadByName("Wrapper%d".format(counter)) + val loadedResultObject = loadByName("Wrapper%d" format (counter)) loadedResultObject.getMethod("entry").invoke(loadedResultObject) IR.Success } @@ -220,26 +217,24 @@ class CompilerAndRunner( } def parse(code0: String, browseAst: Boolean) = { - compilerCode(code0) - .map { code => - compiler.currentSettings = makeSettings2() - compiler.settings.stopAfter.value = stopPhase() - if (browseAst) { - compiler.settings.browse.value = stopPhase() - } - val run = new compiler.Run - reporter.reset() - run.compileSources(List(new BatchSourceFile("scripteditor", code))) + compilerCode(code0) map { code => + compiler.currentSettings = makeSettings2() + compiler.settings.stopAfter.value = stopPhase() + if (browseAst) { + compiler.settings.browse.value = stopPhase() + } + val run = new compiler.Run + reporter.reset() + run.compileSources(List(new BatchSourceFile("scripteditor", code))) - if (reporter.hasErrors) { - IR.Error - } - else { - compiler.printAllUnits() - IR.Success - } + if (reporter.hasErrors) { + IR.Error + } + else { + compiler.printAllUnits() + IR.Success } - .getOrElse(IR.Error) + } getOrElse (IR.Error) } // phase after which you want to stop @@ -249,21 +244,21 @@ class CompilerAndRunner( } val preporter = new Reporter { - override def info0(position: Position, msg: String, severity: Severity, force: Boolean): Unit = {} + override def info0(position: Position, msg: String, severity: Severity, force: Boolean): Unit = { + } } class KGlobal(s: Settings, r: Reporter) extends interactive.Global(s, r) { def mkCompletionProposal(sym: Symbol, tpe: Type, inherited: Boolean, viaView: Symbol): CompletionInfo = { // code borrowed from Scala Eclipse Plugin, after my own hacks in this area failed with 2.10.1 - val kind = - if (sym.isSourceMethod && !sym.hasFlag(Flags.ACCESSOR | Flags.PARAMACCESSOR)) Def - else if (sym.hasPackageFlag) Package - else if (sym.isClass) Class - else if (sym.isTrait) Trait - else if (sym.isPackageObject) PackageObject - else if (sym.isModule) Object - else if (sym.isType) Type - else Val + val kind = if (sym.isSourceMethod && !sym.hasFlag(Flags.ACCESSOR | Flags.PARAMACCESSOR)) Def + else if (sym.hasPackageFlag) Package + else if (sym.isClass) Class + else if (sym.isTrait) Trait + else if (sym.isPackageObject) PackageObject + else if (sym.isModule) Object + else if (sym.isType) Type + else Val val name = sym.decodedName val returnType = @@ -275,8 +270,8 @@ class CompilerAndRunner( if (sym.isMethod) { "%s: %s".format( name + - (if (!sym.typeParams.isEmpty) sym.typeParams.map { _.name }.mkString("[", ",", "]") else "") + - tpe.paramss.map(_.map(_.tpe.toString).mkString("(", ", ", ")")).mkString, + (if (!sym.typeParams.isEmpty) sym.typeParams.map { _.name }.mkString("[", ",", "]") else "") + + tpe.paramss.map(_.map(_.tpe.toString).mkString("(", ", ", ")")).mkString, returnType ) } @@ -294,11 +289,9 @@ class CompilerAndRunner( if (sym.hasPackageFlag) relevance += 30 // theoretically we'd need an 'ask' around this code, but given that // Any and AnyRef are definitely loaded, we call directly to definitions. - if ( - sym.owner == definitions.AnyClass + if (sym.owner == definitions.AnyClass || sym.owner == definitions.AnyRefClass - || sym.owner == definitions.ObjectClass - ) { + || sym.owner == definitions.ObjectClass) { relevance += 40 } val pfx = prefix @@ -336,41 +329,39 @@ class CompilerAndRunner( def typeAt(code0: String, offset: Int): String = { import interactive._ - compilerCode(code0) - .map { code => - classLoader.asContext { - val source = new BatchSourceFile("scripteditor", code) - val pos = new OffsetPosition(source, offset + offsetDelta + 1) - - var r1 = new Response[Unit] - pcompiler.askReload(List(source), r1) - - var resp = new Response[pcompiler.Tree] - pcompiler.askTypeAt(pos, resp) - - val respget = resp.get - val response: pcompiler.Response[String] = pcompiler.askForResponse { () => - respget match { - case Left(x) => - x match { - case t: pcompiler.ValOrDefDef => t.tpt.toString - case t: pcompiler.TypeDef => t.name.toString - case t: pcompiler.ClassDef => t.name.toString - case _ => x.tpe.toString - } + compilerCode(code0) map { code => + classLoader.asContext { + val source = new BatchSourceFile("scripteditor", code) + val pos = new OffsetPosition(source, offset + offsetDelta + 1) + + var r1 = new Response[Unit] + pcompiler.askReload(List(source), r1) + + var resp = new Response[pcompiler.Tree] + pcompiler.askTypeAt(pos, resp) + + val respget = resp.get + val response: pcompiler.Response[String] = pcompiler.askForResponse { () => + respget match { + case Left(x) => + x match { + case t: pcompiler.ValOrDefDef => t.tpt.toString + case t: pcompiler.TypeDef => t.name.toString + case t: pcompiler.ClassDef => t.name.toString + case _ => x.tpe.toString + } - case Right(y) => - // println("Right:" + y) - "" - } - } - response.get match { - case Left(s) => s - case Right(_) => "" + case Right(y) => + // println("Right:" + y) + "" } } + response.get match { + case Left(s) => s + case Right(_) => "" + } } - .getOrElse("") + } getOrElse ("") } import core.CompletionInfo @@ -382,64 +373,61 @@ class CompilerAndRunner( val queryOffset = if (selection) offset - 1 else offset completionQuery(augmentedCode, queryOffset, selection) match { - case Nil => if (selection) completionQuery(code, queryOffset, selection) else Nil - case _ @ret => ret + case Nil => if (selection) completionQuery(code, queryOffset, selection) else Nil + case _@ret => ret } } private def completionQuery(code0: String, offset: Int, selection: Boolean): List[CompletionInfo] = { import interactive._ - compilerCode(code0) - .map { code => - classLoader.asContext { - val source = new BatchSourceFile("scripteditor", code) - val pos = new OffsetPosition(source, offset + offsetDelta + 1) + compilerCode(code0) map { code => + classLoader.asContext { + val source = new BatchSourceFile("scripteditor", code) + val pos = new OffsetPosition(source, offset + offsetDelta + 1) - val r1 = new Response[Unit] - pcompiler.askReload(List(source), r1) + val r1 = new Response[Unit] + pcompiler.askReload(List(source), r1) - val resp = new Response[List[pcompiler.Member]] - if (selection) { - pcompiler.askTypeCompletion(pos, resp) - } - else { - pcompiler.askScopeCompletion(pos, resp) - } + val resp = new Response[List[pcompiler.Member]] + if (selection) { + pcompiler.askTypeCompletion(pos, resp) + } + else { + pcompiler.askScopeCompletion(pos, resp) + } - val completionTimeout = 3000 - resp.get(completionTimeout) match { - case Some(Left(completions)) => - val response: pcompiler.Response[List[CompletionInfo]] = pcompiler.askForResponse { () => - val elb = new ListBuffer[CompletionInfo] - completions.foreach { completion => - try { - completion match { - case pcompiler.TypeMember(sym, tpe, true, inherited, viaView, aliasInfo) - if !sym.isConstructor /*&& nameMatches(sym)*/ => - elb += pcompiler.mkCompletionProposal(sym, tpe, inherited, viaView) - case pcompiler.ScopeMember(sym, tpe, true, _, aliasInfo) if !sym.isConstructor /*&& nameMatches(sym)*/ => - elb += pcompiler.mkCompletionProposal(sym, tpe, false, pcompiler.NoSymbol) - case _ => - } - } - catch { - case t: Throwable => - println("Completion Problem 0: " + t.getMessage()) - // ignore, and move on to the next one + val completionTimeout = 3000 + resp.get(completionTimeout) match { + case Some(Left(completions)) => + val response: pcompiler.Response[List[CompletionInfo]] = pcompiler.askForResponse { () => + val elb = new ListBuffer[CompletionInfo] + completions.foreach { completion => + try { + completion match { + case pcompiler.TypeMember(sym, tpe, true, inherited, viaView, aliasInfo) if !sym.isConstructor /*&& nameMatches(sym)*/ => + elb += pcompiler.mkCompletionProposal(sym, tpe, inherited, viaView) + case pcompiler.ScopeMember(sym, tpe, true, _, aliasInfo) if !sym.isConstructor /*&& nameMatches(sym)*/ => + elb += pcompiler.mkCompletionProposal(sym, tpe, false, pcompiler.NoSymbol) + case _ => } } - elb.toList - } - response.get match { - case Left(l) => l - case Right(_) => Nil + catch { + case t: Throwable => + println("Completion Problem 0: " + t.getMessage()) + // ignore, and move on to the next one + } } - case Some(Right(_)) => Nil - case None => Nil - } + elb.toList + } + response.get match { + case Left(l) => l + case Right(_) => Nil + } + case Some(Right(_)) => Nil + case None => Nil } } - .getOrElse(Nil) + } getOrElse (Nil) } } diff --git a/src/main/scala/net/kogics/kojo/xscala/Help.scala b/src/main/scala/net/kogics/kojo/xscala/Help.scala index 2a6275d44..e11ac0d7c 100644 --- a/src/main/scala/net/kogics/kojo/xscala/Help.scala +++ b/src/main/scala/net/kogics/kojo/xscala/Help.scala @@ -23,7 +23,7 @@ import language.implicitConversions object Help { implicit def elem2str(e: xml.Elem) = e.toString - def summaryFooter = + def summaryFooter =
    Some Background
    The act of programming is based on three crucial ideas: @@ -42,31 +42,33 @@ object Help {
  • Condition - value comparison functions. These are needed for the if-else flow element
- - val exportImageHelpTemplate = - "Saves the contents of the drawing canvas as an image%s, in a file located in the temporary directory on your machine. The name of the file starts with filePrefix. Kojo prints out the full path of the exported image file in the output pane so that you can easily locate the file." + + val exportImageHelpTemplate = "Saves the contents of the drawing canvas as an image%s, in a file located in the temporary directory on your machine. The name of the file starts with filePrefix. Kojo prints out the full path of the exported image file in the output pane so that you can easily locate the file." val CommonContent = Map[String, String]( "TurtlePalette" -> -
+
This Pane contains commands for controlling the Turtle. These are in-built or primitive commands.

- {summaryFooter} -
, + { summaryFooter } +
+ , "PicturePalette" -> -
+
This Pane contains functions for constructing Pictures and a command to draw Pictures. These are in-built or primitive functions and commands.

- {summaryFooter} -
, + { summaryFooter } +
+ , "Picture TransformsPalette" -> -
+
This Pane contains functions for transforming Pictures. These are in-built or primitive functions.

- {summaryFooter} -
, + { summaryFooter } +
+ , "FlowPalette" -> -
+
This Pane contains mechanisms for combining/composing commands and functions. Why is it named Flow? Because the way in which commands or functions are combined in your program determines the runtime flow of your program (this is also called the process generated by your program).
@@ -74,23 +76,26 @@ object Help { Note - the recursion items at the bottom of this pane also conceptually belong to the Abstraction category.

- {summaryFooter} -
, + { summaryFooter } +
+ , "AbstractionPalette" -> -
+
This Pane contains mechanisms for giving your combinations of primitives and other abstractions a name. Once you name a combination, you can re-use it in your programs. This makes your programs easier to read, understand, and modify.

- {summaryFooter} -
, + { summaryFooter } +
+ , "ConditionPalette" -> -
+
This Pane contains functions for comparing values. These are needed for the if-else flow element.

- {summaryFooter} -
, - "repeat" -> -
+ { summaryFooter } +
+ , + "repeat" -> +
repeat(n){{ }} - Repeats the specified block of commands (within braces) n number of times.

Example:

@@ -103,9 +108,10 @@ object Help { right() }} -
, - "repeatFor" -> -
+
+ , + "repeatFor" -> +
repeatFor(seq){{ }} - Repeats the specified block of commands (within braces) for each element in the given sequence.

Example:

@@ -126,12 +132,13 @@ object Help { right() }} -
, +
+ , "repeati" ->
repeati(n) {{i => }} - Repeats the specified block of commands (within braces) n number of times. The current repeat index is available as i within the braces.
.toString, "repeatWhile" ->
repeatWhile(cond) {{ }} - Repeats the specified block of commands (within braces) while the given condition is true.
.toString, "repeatUntil" ->
repeatUntil(cond) {{ }} - Repeats the specified block of commands (within braces) until the given condition is true.
.toString, - "zoom" -> - """zoom(factor) - Zooms in by the given factor, leaving the center point unchanged.
+ "zoom" -> + """zoom(factor) - Zooms in by the given factor, leaving the center point unchanged.

zoom(factor, cx, cy) - Zooms in by the given factor, and positions (cx, cy) at the center of the turtle canvas. """, @@ -190,15 +197,15 @@ object Help { "canvasBounds" -> "canvasBounds - Returns the bounds of the canvas: the x and y coordinates of its bottom left point, and its width and height.", "dot" -> "dot(diameter) - Makes a dot with the given diameter.", "TexturePaint" -> "TexturePaint(fileName, x, y) - Creates a paint from the texture image in the given file. The bottom left of the image is anchored at (x, y). This paint can be used to set the pen and fill colors of shapes.", - "exportImage" -> "exportImage(filePrefix) - ".concat(exportImageHelpTemplate.format("")), - "exportImageH" -> "exportImageH(filePrefix, h) - ".concat(exportImageHelpTemplate.format(" with the given height")), - "exportImageW" -> "exportImageW(filePrefix, w) - ".concat(exportImageHelpTemplate.format(" with the given width")), - "east" ->
east() - Turns the turtle east.
.toString, + "exportImage" -> "exportImage(filePrefix) - ".concat(exportImageHelpTemplate format ""), + "exportImageH" -> "exportImageH(filePrefix, h) - ".concat(exportImageHelpTemplate format " with the given height"), + "exportImageW" -> "exportImageW(filePrefix, w) - ".concat(exportImageHelpTemplate format " with the given width"), + "east" ->
east() - Turns the turtle east.
.toString, "west" ->
west() - Turns the turtle west.
.toString, "north" ->
north() - Turns the turtle north.
.toString, "south" ->
south() - Turns the turtle south.
.toString, "ColorLinearG" -> -
+
ColorLinearG(x1, y1, x2, y2, distribution, colors, cyclic) - creates a linear color gradient. (x1, y1) is the start point of the gradient and (x2, y2) is the end point. The distribution of colors between these points is specified by the given distribution and colors. If cyclic is true, the gradient is reflected @@ -223,7 +230,7 @@ sq(100)
, "ColorRadialG" -> -
+
ColorRadialG(x, y, radius, distribution, colors, cyclic) - creates a circular color gradient. (x, y) is the start point of the gradient. The gradient extends radially in a circle with the given radius. The distribution of colors within this circle is specified by the given distribution and colors. @@ -247,8 +254,8 @@ setPosition(100, 100) sq(100)
, - "map" -> -
+ "map" -> +
sequence.map {{ function }} - maps (or transforms) the sequence into another sequence based on the supplied transformation function.

@@ -259,8 +266,8 @@ sq(100) }} //> res6: Seq[Int] = List(2, 4, 6)
, - "filter" -> -
+ "filter" -> +
sequence.filter {{ condition }} - filters the sequence based on the supplied condition.

Example:

@@ -270,8 +277,8 @@ sq(100) }} //> res1: Seq[Int] = List(1, 3, 5)
, - "foreach" -> -
+ "foreach" -> +
sequence.foreach {{ command }} - runs the given command for each element of the sequence.

Example:

@@ -284,8 +291,8 @@ sq(100) ) val TwContent = Map[String, String]( - "forward" -> -
+ "forward" -> +
forward(numSteps) - Moves the turtle forward by the given number of steps.

Example:

@@ -297,9 +304,10 @@ sq(100) // move forward by 200 steps forward(200) -
, - "hop" -> -
+
+ , + "hop" -> +
hop(numSteps) - Moves the turtle forward by the given number of steps with the pen up, so that no line is drawn. The pen is put down after the hop.

@@ -313,9 +321,10 @@ sq(100) forward(10) }} -
, - "back" -> -
+
+ , + "back" -> +
back(numSteps) - Moves the turtle back by the given number of steps.

Example:

@@ -327,9 +336,10 @@ sq(100) // move back by 200 steps back(200) -
, - "home" -> -
+
+ , + "home" -> +
home() - Moves the turtle to its original location at the center of the screen, and makes it point north.

Example:

@@ -343,9 +353,10 @@ sq(100) // now take it back home home() -
, - "setPosition" -> -
+
+ , + "setPosition" -> +
setPosition(x, y) - Places the turtle at the point (x, y) without drawing a line. The turtle's heading is not changed.

Examples:

@@ -354,9 +365,10 @@ sq(100) setPosition(80, 150) -
, - "position" -> -
+
+ , + "position" -> +
position - Returns the turtle's current position.

Example:

@@ -370,18 +382,20 @@ sq(100) // now report its position print(position) // Point(50.00, 100.00) -
, +
+ , "style" -> "style - Tells you the turtle's current style. See the help for saveStyle() for more information on styles.", "moveTo" ->
moveTo(x, y) - Turns the turtle towards (x, y) and moves the turtle to that point.
.toString, - "turn" -> -
+ "turn" -> +
turn(angle) - Turns the turtle through the specified angle.
Positive angles are in the anti-clockwise direction. Negative angles are in the clockwise direction.

Note: It's easier to use left(angle) or right(angle) to turn the turtle. -
, - "right" -> -
+
+ , + "right" -> +
right() - Turns the turtle 90 degrees right (clockwise).
right(angle) - Turns the turtle right (clockwise) through the given angle in degrees.
right(angle, radius) - Turns the turtle right (clockwise) through the given angle in degrees, around the given turning radius.
@@ -395,9 +409,10 @@ sq(100) // turn right by 30 degrees right(30) -
, - "left" -> -
+
+ , + "left" -> +
left() - Turns the turtle 90 degrees left (anti-clockwise).
left(angle) - Turns the turtle left (anti-clockwise) through the given angle in degrees.
left(angle, radius) - Turns the turtle left (anti-clockwise) through the given angle in degrees, around the given turning radius.
@@ -411,12 +426,13 @@ sq(100) // turn left by 30 degrees left(30) -
, +
+ , "towards" ->
towards(x, y) - Turns the turtle towards the point (x, y).
.toString, "setHeading" ->
setHeading(angle) - Sets the turtle's heading to the given angle (0 is towards the right side of the screen (east), 90 is up (north)).
.toString, "heading" ->
heading - Queries the turtle's heading (0 is towards the right side of the screen (east), 90 is up (north)).
.toString, - "penDown" -> -
+ "penDown" -> +
penDown() - Puts the turtle's pen down, so that it draws lines as the turtle moves.
The turtle's pen is down by default.

@@ -436,9 +452,10 @@ sq(100) // as it moves forward forward(100) -
, - "penUp" -> -
+
+ , + "penUp" -> +
penUp() - Pulls the turtle's pen up, so that it does not draw lines as the turtle moves.

Example:
@@ -457,9 +474,10 @@ sq(100) // as it moves forward forward(100) -
, - "setPenColor" -> -
+
+ , + "setPenColor" -> +
setPenColor(color) - Specifies the color of the pen that the turtle draws with.

Example:
@@ -474,9 +492,10 @@ sq(100) // makes a green line forward(100) -
, - "setFillColor" -> -
+
+ , + "setFillColor" -> +
setFillColor(color) - Specifies the fill color of the figures drawn by the turtle.

Example:
@@ -491,9 +510,10 @@ sq(100) // make a circle filled with green circle(50) -
, - "setPenThickness" -> -
+
+ , + "setPenThickness" -> +
setPenThickness(thickness) - Specifies the width of the pen that the turtle draws with.

Example:
@@ -508,9 +528,10 @@ sq(100) // make a line that is 15 units thick forward(100) -
, - "setPenFontSize" -> -
+
+ , + "setPenFontSize" -> +
setPenFontSize(n) - Specifies the font size of the pen that the turtle writes with.

Example:
@@ -525,9 +546,10 @@ sq(100) // write with a font size of 20 write("Hi There") -
, - "setPenFont" -> -
+
+ , + "setPenFont" -> +
setPenFont(font) - Specifies the font of the pen that the turtle writes with.

Example:
@@ -542,9 +564,10 @@ sq(100) // write with Calibri font write("Hi There") -
, - "savePosHe" -> -
+
+ , + "savePosHe" -> +
savePosHe() - Saves the turtle's current position and heading, so that they can easily be restored later with a restorePosHe().

@@ -565,9 +588,10 @@ sq(100) // exactly where it started out from restorePosHe() -
, - "restorePosHe" -> -
+
+ , + "restorePosHe" -> +
restorePosHe() - Restores the turtle's current position and heading based on an earlier savePosHe().

@@ -588,9 +612,10 @@ sq(100) // exactly where it started out from restorePosHe() -
, - "saveStyle" -> -
+
+ , + "saveStyle" -> +
saveStyle() - Saves the turtle's current style, so that it can easily be restored later with a restoreStyle().

@@ -630,9 +655,10 @@ sq(100) // green line forward(100) -

, - "restoreStyle" -> -
+
+ , + "restoreStyle" -> +
restoreStyle() - Restores the turtle's style based on an earlier saveStyle().
@@ -673,14 +699,15 @@ sq(100) // green line forward(100) -
, +
+ , "beamsOn" ->
beamsOn() - Shows crossbeams centered on the turtle - to help with thinking about the turtle's heading/orientation.
.toString, "beamsOff" ->
beamsOff() - Hides the turtle crossbeams that are turned on by a beamsOn().
.toString, "invisible" ->
invisible() - Makes the turtle invisible. Use the visible() command to make it visible again.
.toString, "visible" ->
visible() - Makes the turtle visible after it was made invisible with the invisible() command.
.toString, "write" ->
write(obj) - Makes the turtle write, at its current location, the specified object as a string.
.toString, - "setAnimationDelay" -> -
+ "setAnimationDelay" -> +
setAnimationDelay(delay) - Sets the turtle's speed. The specified delay is the amount of time (in milliseconds) taken by the turtle to move through a distance of one hundred steps.
The default delay is 1000 milliseconds (or 1 second).
@@ -700,7 +727,8 @@ sq(100) // drawing the line takes 1/10 seconds forward(100) -
, +
+ , "setSpeed" ->
setSpeed(speed) - sets the turtle's speed to the given speed. Possible values are slow, medium, fast, and superFast.
, "setSlowness" ->
setSlowness(delay) - sets the inverse of the turtle's speed based on the given delay. This behaves in exactly the same way as setAnimationDelay.
, "animationDelay" ->
animationDelay - Queries the turtle's delay setting.
, @@ -710,7 +738,7 @@ sq(100) "clearOutput" ->
clearOutput() - Clears the output window.
.toString, "clearWithUL" -> "clearWithUL(unit) - Clears the turtle canvas, sets the given unit length (Pixel, Cm, or Inch), and brings the turtle to the center of the canvas.", "arc" -> -
+
arc(radius, angle) - Gets the turtle to make an arc with the given radius and angle.
Positive angles make the turtle go left (anti-clockwise). Negative angles make the turtle go right (clockwise)
@@ -732,7 +760,7 @@ sq(100)
, "arc2" -> -
+
arc2(radius, angle) - Gets the turtle to make an arc with the given radius and angle.
Positive angles result in an anti-clockwise arc. Negative angles result in a clockwise arc.
@@ -755,7 +783,7 @@ sq(100)
, "circle" -> -
+
circle(radius) - Gets the turtle to make a circle with the given radius.
A circle(50) command is equivalent to an arc(50, 360) command.
@@ -766,7 +794,8 @@ sq(100) clear() circle(50) -
, +
+ , "image" -> """image(height, width) - Creates an image with the given height and width. This image is blank to begin with. You can set the individual pixels in the image by using the setImagePixel() command.""", "setImagePixel" -> "setImagePixel(img, x, y, color) - Sets the pixel at the given (x, y) location in the given image to the given color.", @@ -788,8 +817,8 @@ The code that you provide to react runs about thirty times per second, in the UI "distanceTo" -> "distanceTo(otherTurtle) - Calculates the distance (in the current units) between this turtle and the given turtle", "perimeter" -> "perimeter - calculates the perimeter (in the current units) of the figure made by this turtle", "area" -> "area - calculates the area (in the current units-squared) enclosed by the figure made by this turtle", - "==" -> -
+ "==" -> +
a == b - Evaluates to true if a and b are equal, false otherwise.

Example:
@@ -811,9 +840,10 @@ The code that you provide to react runs about thirty times per second, in the UI def isZero(n: Int) = n == 0 -
, - "!=" -> -
+
+ , + "!=" -> +
a != b - Evaluates to true if a and b are not equal, false otherwise.

Example:
@@ -835,9 +865,10 @@ The code that you provide to react runs about thirty times per second, in the UI def isNotZero(n: Int) = n != 0 -
, - ">" -> -
+
+ , + ">" -> +
a > b - Evaluates to true if a is greater than b, false otherwise.

Example:
@@ -859,9 +890,10 @@ The code that you provide to react runs about thirty times per second, in the UI def max(a: Int, b: Int) = if (a > b) a else b max(5, 10) // 10 -
, - "<" -> -
+
+ , + "<" -> +
a < b - Evaluates to true if a is less than b, false otherwise.

Example:
@@ -883,9 +915,10 @@ The code that you provide to react runs about thirty times per second, in the UI def min(a: Int, b: Int) = if (a < b) a else b min(5, 10) // 5 -
, - ">=" -> -
+
+ , + ">=" -> +
a >= b - Evaluates to true if a is greater than or equal to b, false otherwise.

Example:
@@ -907,9 +940,10 @@ The code that you provide to react runs about thirty times per second, in the UI def max(a: Int, b: Int) = if (a >= b) a else b max(5, 10) // 10 -
, - "<=" -> -
+
+ , + "<=" -> +
a <= b - Evaluates to true if a is less than or equal b, false otherwise.

Example:
@@ -931,9 +965,10 @@ The code that you provide to react runs about thirty times per second, in the UI def min(a: Int, b: Int) = if (a <= b) a else b min(5, 10) // 5 -
, +
+ , "for" -> -
+
Usage #1 [with commands]:
for(i <- 1 to n) {{ commands }} - Repeats a block of commands (within braces) n number of times, making the repeat counter available within the block defined by the braces.
@@ -955,9 +990,10 @@ The code that you provide to react runs about thirty times per second, in the UI
           for (i <- 1 to 4) yield (2 * i)
       
-
, +
+ , "def" -> -
+
def - Gives a name to a block of commands (within braces) or an expression. This lets you define a new command or function.

@@ -988,9 +1024,10 @@ The code that you provide to react runs about thirty times per second, in the UI // another call to the sum function print(sum(20, 7)) -
, - "recursion" -> -
+
+ , + "recursion" -> +
Recursion allows you to define a command or function in terms of itself.

Usage #1 [to define a command]:
@@ -1012,9 +1049,10 @@ The code that you provide to react runs about thirty times per second, in the UI def factorial(n: Int): Int = if (n == 0) 1 else n * factorial(n-1) -
, +
+ , "if" -> -
+
if or if-else - Let's you choose the instruction to execute based on a condition. The instruction can be a command, in which case if-else works as a command. Or the instruction can be an expression, in which case if-else works as an expression.
@@ -1041,9 +1079,10 @@ The code that you provide to react runs about thirty times per second, in the UI clearOutput() println(big) -
, +
+ , "val" -> -
+
val - Gives a name to an expression, letting you create a named value. This makes your programs easier to modify and easier to understand.

@@ -1058,10 +1097,11 @@ The code that you provide to react runs about thirty times per second, in the UI right() }} -
, +
+ , "pict" -> "pict { t => } is obsolete. Use the PictureT (preferred) or Picture function instead.", - "Picture" -> -
+ "Picture" -> +
Picture {{ drawingCode }} - Makes a picture out of the given turtle drawing code.
The picture needs to be drawn for it to become visible in the turtle canvas.

@@ -1078,9 +1118,10 @@ The code that you provide to react runs about thirty times per second, in the UI // draw the picture draw(p) -
, - "PictureT" -> -
+
+ , + "PictureT" -> +
PictureT {{ t => drawingCode }} - Makes a picture out of the given turtle drawing code, which needs to draw using the supplied turtle t.
The picture needs to be drawn for it to become visible in the turtle canvas.
@@ -1099,9 +1140,10 @@ The code that you provide to react runs about thirty times per second, in the UI // draw the picture draw(p) -
, +
+ , "Picture.line" -> -
+
Picture.line(width, height) - Creates a picture of a line with the given extent in the x and y directions.

Example:
@@ -1124,7 +1166,7 @@ The code that you provide to react runs about thirty times per second, in the UI
, "Picture.vline" -> -
+
Picture.vline(length) - Creates a picture of a vertical line with the given length.

Example:
@@ -1135,7 +1177,7 @@ The code that you provide to react runs about thirty times per second, in the UI
, "Picture.rect" -> -
+
Picture.rect(height, width) - Creates a picture of a rectangle with the given height and width.

Example:
@@ -1158,7 +1200,7 @@ The code that you provide to react runs about thirty times per second, in the UI
, "Picture.circle" -> -
+
Picture.circle(radius) - Creates a picture of a circle with the given radius.

Example:
@@ -1169,7 +1211,7 @@ The code that you provide to react runs about thirty times per second, in the UI
, "Picture.ellipse" -> -
+
Picture.ellipse(rx, ry) - Creates a picture of an elipse with the given x radius and y radius.

Example:
@@ -1192,7 +1234,7 @@ The code that you provide to react runs about thirty times per second, in the UI
, "Picture.text" -> -
+
Picture.text(content, size) - Creates a picture out of the given text with the given font-size.
Picture.text(content, font) - Creates a picture out of the given text with the given font.

@@ -1205,7 +1247,7 @@ The code that you provide to react runs about thirty times per second, in the UI
, "Picture.image" -> -
+
Picture.image(fileName) - Creates a picture out of an image from the file with the given name.
Picture.image(image) - Creates a picture out of the given image. The image can be created with the image(height, width) function.

@@ -1217,7 +1259,7 @@ The code that you provide to react runs about thirty times per second, in the UI
, "Picture.widget" -> -
+
Picture.widget(component) - Creates a picture out of the given widget.

Example:
@@ -1227,8 +1269,8 @@ The code that you provide to react runs about thirty times per second, in the UI draw(Picture.widget(Label("Hi there")))
, - "draw" -> -
+ "draw" -> +
draw(picture[s]) - Draws the given (one or more) picture(s).

Example:
@@ -1238,8 +1280,8 @@ The code that you provide to react runs about thirty times per second, in the UI draw(Picture.hline(50), Picture.vline(50))
, - "HPics" -> -
+ "HPics" -> +
HPics(pictures)
Creates a horizontal row of the supplied pictures. Is equivalent to picRow(pictures)
HPics is a container for pictures that lays out its child pictures horizontally.
@@ -1263,9 +1305,10 @@ The code that you provide to react runs about thirty times per second, in the UI ) draw(pic) -
, - "picRow" -> -
+
+ , + "picRow" -> +
picRow(pictures)
Creates a horizontal row of the supplied pictures. Is equivalent to HPics(pictures)

@@ -1288,9 +1331,10 @@ The code that you provide to react runs about thirty times per second, in the UI ) draw(pic) -
, - "VPics" -> -
+
+ , + "VPics" -> +
VPics(pictures)
Creates a vertical column of the supplied pictures. Is equivalent to picCol(pictures)
VPics is a container for pictures that lays out its child pictures vertically.
@@ -1314,9 +1358,10 @@ The code that you provide to react runs about thirty times per second, in the UI ) draw(pic) -
, - "picCol" -> -
+
+ , + "picCol" -> +
picCol(pictures)
Creates a vertical column of the supplied pictures. Is equivalent to VPics(pictures)

@@ -1339,9 +1384,10 @@ The code that you provide to react runs about thirty times per second, in the UI ) draw(pic) -
, - "GPics" -> -
+
+ , + "GPics" -> +
GPics(pictures)
Creates a stack of the supplied pictures. Is equivalent to picStack(pictures)
GPics is a container for pictures that lays out its child pictures one on top of the other.
@@ -1365,9 +1411,10 @@ The code that you provide to react runs about thirty times per second, in the UI ) draw(pic) -
, - "picStack" -> -
+
+ , + "picStack" -> +
picStack(pictures)
Creates a stack of the supplied pictures. Is equivalent to GPics(pictures)

@@ -1390,9 +1437,10 @@ The code that you provide to react runs about thirty times per second, in the UI ) draw(pic) -
, - "rot" -> -
+
+ , + "rot" -> +
rot(angle) -> picture
Creates a new picture by rotating the given picture by the given angle.

@@ -1411,9 +1459,10 @@ The code that you provide to react runs about thirty times per second, in the UI val pic = rot(30) -> p draw(pic) -
, - "trans" -> -
+
+ , + "trans" -> +
trans(x, y) -> picture
Creates a new picture by translating the given picture by the given x and y values.

@@ -1433,8 +1482,8 @@ The code that you provide to react runs about thirty times per second, in the UI draw(pic)
, - "offset" -> -
+ "offset" -> +
offset(x, y) -> picture
Creates a new picture by offsetting the given picture by the given x and y values, with respect to the global (canvas) coordinate system.
@@ -1456,8 +1505,8 @@ The code that you provide to react runs about thirty times per second, in the UI draw(pic)
, - "scale" -> -
+ "scale" -> +
scale(factor) -> picture
scale(xf, yf) -> picture
Creates a new picture by scaling the given picture by the given scaling factor(s).
@@ -1478,8 +1527,8 @@ The code that you provide to react runs about thirty times per second, in the UI draw(pic)
, - "fillColor" -> -
+ "fillColor" -> +
fillColor(color) -> picture
Creates a new picture by filling the given picture with the given color.

@@ -1499,8 +1548,8 @@ The code that you provide to react runs about thirty times per second, in the UI draw(pic)
, - "penColor" -> -
+ "penColor" -> +
penColor(color) -> picture
Creates a new picture by setting the pen color for the given picture to the given color.

@@ -1520,8 +1569,8 @@ The code that you provide to react runs about thirty times per second, in the UI draw(pic)
, - "penWidth" -> -
+ "penWidth" -> +
penWidth(thickness) -> picture
Creates a new picture by setting the pen width for the given picture to the given thickness.

@@ -1541,8 +1590,8 @@ The code that you provide to react runs about thirty times per second, in the UI draw(pic)
, - "hue" -> -
+ "hue" -> +
hue(factor) -> picture
Creates a new picture by changing the hue of the given picture's fill color by the given factor.
The factor needs to be between -1 and 1.
@@ -1564,8 +1613,8 @@ The code that you provide to react runs about thirty times per second, in the UI draw(pic)
, - "sat" -> -
+ "sat" -> +
sat(factor) -> picture
Creates a new picture by changing the saturation of the given picture's fill color by the given factor.
The factor needs to be between -1 and 1.
@@ -1586,8 +1635,8 @@ The code that you provide to react runs about thirty times per second, in the UI draw(pic)
, - "brit" -> -
+ "brit" -> +
brit(factor) -> picture
Creates a new picture by changing the brightness of the given picture's fill color by the given factor.
The factor needs to be between -1 and 1.
@@ -1608,8 +1657,8 @@ The code that you provide to react runs about thirty times per second, in the UI draw(pic)
, - "opac" -> -
+ "opac" -> +
opac(factor) -> picture
Creates a new picture by changing the opacity of the given picture by the given factor.

@@ -1629,8 +1678,8 @@ The code that you provide to react runs about thirty times per second, in the UI draw(pic)
, - "hueMod" -> -
+ "hueMod" -> +
hueMod(color, factor)
A function that computes and returns a new color made by changing the hue of the given color by the given factor.
@@ -1662,8 +1711,8 @@ repeat(5) {{ }}
, - "satMod" -> -
+ "satMod" -> +
satMod(color, factor)
A function that computes and returns a new color made by changing the saturation of the given color by the given factor.
@@ -1694,8 +1743,8 @@ repeat(5) {{ }}
, - "britMod" -> -
+ "britMod" -> +
britMod(color, factor)
A function that computes and returns a new color made by changing the brightness of the given color by the given factor.
@@ -1726,8 +1775,8 @@ repeat(5) {{ }}
, - "axes" -> -
+ "axes" -> +
axes -> picture
Creates a new picture by turning on the local axes for the given picture (to help during picture construction).

@@ -1747,8 +1796,8 @@ repeat(5) {{ draw(pic)
, - "flipY" -> -
+ "flipY" -> +
flipY -> picture
flipAroundY -> picture
Flips the given picture around the local Y axis.
@@ -1770,8 +1819,8 @@ repeat(5) {{ draw(pic)
, - "flipX" -> -
+ "flipX" -> +
flipX -> picture
flipAroundX -> picture
Flips the given picture around the local X axis.
@@ -1793,8 +1842,8 @@ repeat(5) {{ draw(pic)
, - "flip" -> -
+ "flip" -> +
flip -> picture
The same thing as flipY.
Flips the given picture around the local Y axis.
@@ -1816,8 +1865,8 @@ repeat(5) {{ draw(pic)
, - "animate" -> -
+ "animate" -> +
animate {{ code }}

Calls the given code block repeatedly (at the default refresh rate of 50 times per second) within an animation loop. The refresh rate can be modified with the setRefreshRate(fps) command, @@ -1838,7 +1887,7 @@ repeat(5) {{ the current state.
, "schedule" -> -
+
schedule(seconds) {{ code }}

Schedules the given code block to be called (in the animation/GUI thread) after the specified number of seconds. @@ -1878,11 +1927,11 @@ repeat(5) {{ "Kmath.lerp" -> "mathx.lerp(start, stop, amt) - interpolates between start and stop by the given amount.", "Kmath.map" -> "mathx.map(value, start1, stop1, start2, stop2) - maps the given value from the range (start1, stop1) to the range(start2, stop2)." ) - + val VnContent = Map[String, String]() - + @volatile var modeSpecificContent: Map[String, String] = TwContent - + def activateTw(): Unit = { modeSpecificContent = TwContent clearLangContent() @@ -1897,25 +1946,25 @@ repeat(5) {{ def addContent(lang: String, content: Map[String, String]): Unit = { // import util.Typeclasses._ // langContent += (lang -> (langContent.getOrElse(lang, Map()) |+| content)) - langContent += (lang -> (langContent.getOrElse(lang, Map()) ++ content)) + langContent += (lang -> (langContent.getOrElse(lang, Map()) ++ content)) } - + def clearLangContent(): Unit = { langContent.clear() } - + def langHelp(name: String, lang: String): Option[String] = { langContent.get(lang) match { case Some(content) => content.get(name) - case None => None + case None => None } } - + def apply(topic: String): String = { CommonContent.getOrElse( - topic, + topic, modeSpecificContent.getOrElse( - topic, + topic, langHelp(topic, System.getProperty("user.language")).getOrElse(null) ) ) diff --git a/src/main/scala/net/kogics/kojo/xscala/RepeatCommands.scala b/src/main/scala/net/kogics/kojo/xscala/RepeatCommands.scala index 17f6decef..a0e3bab59 100644 --- a/src/main/scala/net/kogics/kojo/xscala/RepeatCommands.scala +++ b/src/main/scala/net/kogics/kojo/xscala/RepeatCommands.scala @@ -16,46 +16,47 @@ package net.kogics.kojo package xscala +import net.kogics.kojo.util.UserCommand import net.kogics.kojo.util.Throttler object RepeatCommands extends RepeatCommands trait RepeatCommands { - def repeat(n: Int)(fn: => Unit): Unit = { + def repeat(n: Int) (fn: => Unit): Unit = { var i = 0 - while (i < n) { + while(i < n) { fn i += 1 } } - def repeati(n: Int)(fn: Int => Unit): Unit = { + def repeati(n: Int) (fn: Int => Unit): Unit = { var i = 0 - while (i < n) { - fn(i + 1) + while(i < n) { + fn(i+1) i += 1 } } - def repeatWhile(cond: => Boolean)(fn: => Unit): Unit = { + def repeatWhile(cond: => Boolean) (fn: => Unit): Unit = { while (cond) { fn Throttler.throttle() } } - def repeatUntil(cond: => Boolean)(fn: => Unit): Unit = { + def repeatUntil(cond: => Boolean) (fn: => Unit): Unit = { while (!cond) { fn Throttler.throttle() } } - + def repeatFor[T](seq: Iterable[T])(fn: T => Unit): Unit = { val iter = seq.iterator while (iter.hasNext) { fn(iter.next()) Throttler.throttle() } - } + } } diff --git a/src/main/scala/net/kogics/kojo/xscala/ScalaCodeRunner2.scala b/src/main/scala/net/kogics/kojo/xscala/ScalaCodeRunner2.scala index cb905b598..cbc2f3ce1 100644 --- a/src/main/scala/net/kogics/kojo/xscala/ScalaCodeRunner2.scala +++ b/src/main/scala/net/kogics/kojo/xscala/ScalaCodeRunner2.scala @@ -21,26 +21,27 @@ import java.util.logging.Level import java.util.logging.Logger import scala.collection.mutable.ListBuffer -import scala.concurrent.duration._ import scala.concurrent.Await +import scala.concurrent.duration._ -import akka.actor.Actor -import akka.actor.Props -import akka.pattern.ask -import akka.util.Timeout import net.kogics.kojo.core import net.kogics.kojo.core.CodeRunner import net.kogics.kojo.core.CodingMode import net.kogics.kojo.core.CompletionInfo +import net.kogics.kojo.core.VanillaMode import net.kogics.kojo.core.Interpreter.IR import net.kogics.kojo.core.Interpreter.Settings import net.kogics.kojo.core.RunContext import net.kogics.kojo.core.TwMode -import net.kogics.kojo.core.VanillaMode import net.kogics.kojo.util.Typeclasses.mkIdentity import net.kogics.kojo.util.Typeclasses.some import net.kogics.kojo.util.Utils +import akka.actor.Actor +import akka.actor.Props +import akka.pattern.ask +import akka.util.Timeout + class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) extends CodeRunner { val Log = Logger.getLogger("ScalaCodeRunner") val outputHandler = new InterpOutputHandler(runContext) @@ -141,33 +142,27 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) def askCodeRunner(m: Any): Any = { implicit val timeout = Timeout(MaxResponseTime) - val fresult = codeRunner.ask(m) + val fresult = codeRunner ask m Await.result(fresult, timeout.duration) } def varCompletions(prefix: Option[String]): (List[String], Int) = { - val resp = this.askCodeRunner(VarCompletionRequest(prefix)).asInstanceOf[CompletionResponse] + val resp = (this askCodeRunner VarCompletionRequest(prefix)).asInstanceOf[CompletionResponse] resp.data } def keywordCompletions(prefix: Option[String]): (List[String], Int) = { - val resp = this.askCodeRunner(KeywordCompletionRequest(prefix)).asInstanceOf[CompletionResponse] + val resp = (this askCodeRunner KeywordCompletionRequest(prefix)).asInstanceOf[CompletionResponse] resp.data } - def memberCompletions( - code: String, - caretOffset: Int, - objid: String, - prefix: Option[String] - ): (List[CompletionInfo], Int) = { - val resp = - this.askCodeRunner(MemberCompletionRequest(code, caretOffset, objid, prefix)).asInstanceOf[CompletionResponse2] + def memberCompletions(code: String, caretOffset: Int, objid: String, prefix: Option[String]): (List[CompletionInfo], Int) = { + val resp = (this askCodeRunner MemberCompletionRequest(code, caretOffset, objid, prefix)).asInstanceOf[CompletionResponse2] resp.data } def typeAt(code: String, caretOffset: Int): String = { - this.askCodeRunner(TypeAtRequest(code, caretOffset)).asInstanceOf[String] + (this askCodeRunner TypeAtRequest(code, caretOffset)).asInstanceOf[String] } def activateTw(): Unit = { @@ -185,8 +180,7 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) def interruptionInProgress = interruptTimer.isDefined - @annotation.nowarn - def interruptInterpreter(): Unit = synchronized { + @annotation.nowarn def interruptInterpreter(): Unit = synchronized { // Runs on swing thread if (interruptionInProgress) { Log.info("Interruption of Interpreter Requested") @@ -386,12 +380,12 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) case CompileCode(code) => try { - Log.info("CodeRunner actor compiling code:\n---\n%s\n---\n".format(code)) + Log.info("CodeRunner actor compiling code:\n---\n%s\n---\n" format (code)) InterruptionManager.onInterpreterStart(compilerAndRunner) runContext.onCompileStart() val ret = compile(code) - Log.info("CodeRunner actor done compiling code. Return value %s".format(ret.toString)) + Log.info("CodeRunner actor done compiling code. Return value %s" format (ret.toString)) if (ret == IR.Success) { runContext.onCompileSuccess() @@ -412,20 +406,19 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) case CompileRunCode(code) => try { - Log.info("CodeRunner actor compiling/running code:\n---\n%s\n---\n".format(code)) + Log.info("CodeRunner actor compiling/running code:\n---\n%s\n---\n" format (code)) InterruptionManager.onInterpreterStart(compilerAndRunner) runContext.onInterpreterStart(code) val ret = compileAndRun(code) - Log.info("CodeRunner actor done compiling/running code. Return value %s".format(ret.toString)) + Log.info("CodeRunner actor done compiling/running code. Return value %s" format (ret.toString)) if (ret == IR.Success) { runContext.onRunSuccess() } else { Utils.clearGuiBatchQ() - if (InterruptionManager.interruptionInProgress) - runContext.onRunSuccess() // user cancelled running code; no errors + if (InterruptionManager.interruptionInProgress) runContext.onRunSuccess() // user cancelled running code; no errors else runContext.onRunError() } } @@ -449,12 +442,12 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) case ParseCode(code, browseAst) => try { - Log.info("CodeRunner actor parsing code:\n---\n%s\n---\n".format(code)) + Log.info("CodeRunner actor parsing code:\n---\n%s\n---\n" format (code)) InterruptionManager.onInterpreterStart(compilerAndRunner) runContext.onCompileStart() val ret = compilerAndRunner.parse(code, browseAst) - Log.info("CodeRunner actor done parsing code. Return value %s".format(ret.toString)) + Log.info("CodeRunner actor done parsing code. Return value %s" format (ret.toString)) if (ret == IR.Success) { runContext.onCompileSuccess() @@ -499,12 +492,12 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) def runCode(code: String, asWorksheet: Boolean): Unit = { try { - Log.info("CodeRunner actor running code:\n---\n%s\n---\n".format(code)) + Log.info("CodeRunner actor running code:\n---\n%s\n---\n" format (code)) InterruptionManager.onInterpreterStart(interp) runContext.onInterpreterStart(code) val ret = interpret(code, asWorksheet) - Log.info("CodeRunner actor done running code. Return value %s".format(ret.toString)) + Log.info("CodeRunner actor done running code. Return value %s" format (ret.toString)) if (ret == IR.Incomplete) showIncompleteCodeMsg(code) @@ -513,8 +506,7 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) } else { Utils.clearGuiBatchQ() - if (InterruptionManager.interruptionInProgress) - runContext.onRunSuccess() // user cancelled running code; no errors + if (InterruptionManager.interruptionInProgress) runContext.onRunSuccess() // user cancelled running code; no errors else runContext.onRunError() } } @@ -551,8 +543,7 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) } def loadCompiler(): Unit = { - compilerAndRunner = - new CompilerAndRunner(makeSettings, compilerInitCode, new CompilerOutputHandler(runContext), runContext) + compilerAndRunner = new CompilerAndRunner(makeSettings, compilerInitCode, new CompilerOutputHandler(runContext), runContext) actorState.compilerAndRunner = compilerAndRunner } @@ -568,16 +559,13 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) } if (Utils.installInitScripts.size > 0) { - kprintln( - Utils.installInitScripts - .mkString("\n---\nLoading Init Scripts (from install initk):\n * ", "\n * ", "\n---\n") - ) + kprintln(Utils.installInitScripts.mkString("\n---\nLoading Init Scripts (from install initk):\n * ", "\n * ", "\n---\n")) } } def loadInitScripts(mode: CodingMode): Unit = { Utils.initCode(mode).foreach { code => - // println("\nRunning initk code...") + //println("\nRunning initk code...") println() print(Utils.loadString("S_OutputInitkRunning")) println("...") @@ -607,19 +595,17 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) outputHandler.clearWorksheetError(); interpretWorksheetLines(lines.tail) case IR.Error => if (InterruptionManager.interruptionInProgress) { outputHandler.flushWorksheetError(); IR.Error } - else - tail match { - case Nil => - outputHandler.flushWorksheetError(); IR.Error - case (code2, lnum2) :: tail2 => interpretWorksheetLines((s"$code\n$code2", lnum) :: tail2, true) - } + else tail match { + case Nil => + outputHandler.flushWorksheetError(); IR.Error + case (code2, lnum2) :: tail2 => interpretWorksheetLines((s"$code\n$code2", lnum) :: tail2, true) + } case IR.Incomplete => if (inError) { outputHandler.flushWorksheetError(); IR.Error } - else - tail match { - case Nil => IR.Incomplete - case (code2, lnum2) :: tail2 => interpretWorksheetLines((s"$code\n$code2", lnum2) :: tail2) - } + else tail match { + case Nil => IR.Incomplete + case (code2, lnum2) :: tail2 => interpretWorksheetLines((s"$code\n$code2", lnum2) :: tail2) + } } } @@ -634,7 +620,7 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) case l if l.startsWith("*/") => inMultiLineComment = false; true case l if l.startsWith("*") && inMultiLineComment => true - case _ => false + case _ => false } } val lines = code.split("\n").toList.zipWithIndex.filter { case (line, _) => !shouldIgnoreLine(line) } @@ -675,8 +661,8 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) def showIncompleteCodeMsg(code: String): Unit = { val msg = """ - |error: Incomplete code fragment - |You probably have a missing brace/bracket somewhere in your script + |error: Incomplete code fragment + |You probably have a missing brace/bracket somewhere in your script """.stripMargin runContext.reportError(msg) } @@ -714,12 +700,7 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) (c2s, pfx.length) } - def memberCompletions( - code0: String, - caretOffset: Int, - objid: String, - prefix: Option[String] - ): (List[CompletionInfo], Int) = { + def memberCompletions(code0: String, caretOffset: Int, objid: String, prefix: Option[String]): (List[CompletionInfo], Int) = { val pfx = prefix.getOrElse("") val offset = caretOffset - pfx.length val code = @@ -731,7 +712,7 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) case Nil => val ics = completions(objid).filter { ignoreCaseStartsWith(_, pfx) } (ics.map { CompletionInfo(core.MemberKind.Var, _, "", "", 0, false, Nil, Nil, "", "") }, pfx.length) - case _ @ccs => + case _@ ccs => (ccs.filter { ci => ignoreCaseStartsWith(ci.name, pfx) }, pfx.length) } } diff --git a/src/main/scala/net/kogics/kojo/xscala/kojoInterpreter.scala b/src/main/scala/net/kogics/kojo/xscala/kojoInterpreter.scala index 26b4cfb96..0930403a9 100644 --- a/src/main/scala/net/kogics/kojo/xscala/kojoInterpreter.scala +++ b/src/main/scala/net/kogics/kojo/xscala/kojoInterpreter.scala @@ -24,7 +24,7 @@ import net.kogics.kojo.core.Interpreter class KojoInterpreter(settings: Interpreter.Settings, out: PrintWriter) extends StoppableCodeRunner with Interpreter { val interp = new IMain(settings, None, settings, new ReplReporterImpl(settings, out)) { - protected override def parentClassLoader = classOf[KojoInterpreter].getClassLoader + override protected def parentClassLoader = classOf[KojoInterpreter].getClassLoader } // interp.setContextClassLoader() @@ -34,8 +34,7 @@ class KojoInterpreter(settings: Interpreter.Settings, out: PrintWriter) extends interp.interpret(code) } } - @annotation.nowarn - def completions(id: String): List[String] = { + @annotation.nowarn def completions(id: String): List[String] = { interp.presentationCompile(id.length + 1, s"$id.") match { case Right(value) => value.candidates(0)._2 diff --git a/src/main/scala/net/kogics/kojo/xscala/outputHandlers.scala b/src/main/scala/net/kogics/kojo/xscala/outputHandlers.scala index 01fcf446a..2d24c65ea 100644 --- a/src/main/scala/net/kogics/kojo/xscala/outputHandlers.scala +++ b/src/main/scala/net/kogics/kojo/xscala/outputHandlers.scala @@ -42,14 +42,14 @@ class InterpOutputHandler(ctx: RunContext) { def showInterpOutput(lineFragment: String): Unit = { if (!interpOutputSuppressed) reportInterpOutput(lineFragment) } - + private def reportWorksheetOutput(output: String, line: Int): Unit = { - if (output.trim == "") return + if (output.trim == "") return - val wline = line - includedLines - if (wline >= 0) { - ctx.reportWorksheetOutput(output, wline) - } + val wline = line - includedLines + if (wline >= 0) { + ctx.reportWorksheetOutput(output, wline) + } } private def reportExceptionOutput(output0: String): Unit = { @@ -62,7 +62,7 @@ class InterpOutputHandler(ctx: RunContext) { else { output0 } - worksheetLineNum.foreach { reportWorksheetOutput(output, _) } + worksheetLineNum foreach { reportWorksheetOutput(output, _) } ctx.reportException(output) } @@ -82,14 +82,14 @@ class InterpOutputHandler(ctx: RunContext) { } } else { - worksheetLineNum.foreach { reportWorksheetOutput(output, _) } + worksheetLineNum foreach { reportWorksheetOutput(output, _) } ctx.reportOutput(output) } } def flushWorksheetError(): Unit = { - firstWorksheetError.foreach { msg => - worksheetLineNum.foreach { reportWorksheetOutput(msg.linesIterator.next(), _) } + firstWorksheetError foreach { msg => + worksheetLineNum foreach { reportWorksheetOutput(msg.linesIterator.next(), _) } ctx.reportError(msg) } firstWorksheetError = None @@ -131,14 +131,14 @@ class CompilerOutputHandler(ctx: RunContext) extends CompilerListener { } def warning(msg: String, line: Int, column: Int): Unit = { - println("Warning: %s\n".format(msg)) + println("Warning: %s\n" format (msg)) } def info(msg: String, line: Int, column: Int): Unit = { - println("Info: %s\n".format(msg)) + println("Info: %s\n" format (msg)) } def message(msg: String): Unit = { - println("%s\n".format(msg)) + println("%s\n" format (msg)) } -} +} \ No newline at end of file From 9a31893eb1870018f66eebaecf584670cd163e93 Mon Sep 17 00:00:00 2001 From: Ben Bulent Basaran Date: Mon, 31 Jul 2023 12:59:25 -0400 Subject: [PATCH 02/23] merge to sync --- .../net/kogics/kojo/lite/Bundle_tr.properties | 1 + .../scala/net/kogics/kojo/lite/Builtins.scala | 379 +++++++++++++----- .../kojo/xscala/CompilerAndRunner.scala | 11 +- 3 files changed, 285 insertions(+), 106 deletions(-) diff --git a/src/main/resources/net/kogics/kojo/lite/Bundle_tr.properties b/src/main/resources/net/kogics/kojo/lite/Bundle_tr.properties index d07da7f18..12b18e9d1 100644 --- a/src/main/resources/net/kogics/kojo/lite/Bundle_tr.properties +++ b/src/main/resources/net/kogics/kojo/lite/Bundle_tr.properties @@ -320,3 +320,4 @@ S_StoryTellerIntroP3=Çalıştıktan sonra sayfanın altında çıkan düğmeler S_WorksheetPragma=çalışmasayfası S_IncludePragma=yükle +S_ExecPragma=işlet diff --git a/src/main/scala/net/kogics/kojo/lite/Builtins.scala b/src/main/scala/net/kogics/kojo/lite/Builtins.scala index 9fe0ba08c..0600e2372 100644 --- a/src/main/scala/net/kogics/kojo/lite/Builtins.scala +++ b/src/main/scala/net/kogics/kojo/lite/Builtins.scala @@ -16,39 +16,50 @@ package net.kogics.kojo package lite +import java.awt.geom.Ellipse2D import java.awt.geom.GeneralPath -import java.awt.geom.{Ellipse2D, Rectangle2D} -import java.awt.image.{BufferedImage, BufferedImageOp} -import java.awt.{Paint, Toolkit} +import java.awt.geom.Rectangle2D +import java.awt.image.BufferedImage +import java.awt.image.BufferedImageOp +import java.awt.Graphics2D +import java.awt.Paint +import java.awt.Toolkit import java.net.URL -import com.jhlabs.image.AbstractBufferedImageOp -import com.jhlabs.image.LightFilter.Light - import javax.swing.JComponent -import net.kogics.kojo.core.{Rich2DPath, VertexShape, Voice} -import net.kogics.kojo.kmath.KEasing -import net.kogics.kojo.turtle.TurtleWorldAPI -import net.kogics.kojo.util.{Throttler, UserCommand, Utils} -import net.kogics.kojo.xscala.{CodeCompletionUtils, Help, RepeatCommands} import scala.language.implicitConversions -import scala.swing.Graphics2D -// a static instance is needed for the compiler prefix code +import com.jhlabs.image.AbstractBufferedImageOp +import com.jhlabs.image.LightFilter.Light +import net.kogics.kojo.core.Rich2DPath +import net.kogics.kojo.core.VertexShape +import net.kogics.kojo.core.Voice +import net.kogics.kojo.kmath.KEasing +import net.kogics.kojo.music.RealtimeNotePlayer +import net.kogics.kojo.turtle.TurtleWorldAPI +import net.kogics.kojo.util.Throttler +import net.kogics.kojo.util.UserCommand +import net.kogics.kojo.util.Utils +import net.kogics.kojo.xscala.CodeCompletionUtils +import net.kogics.kojo.xscala.Help +import net.kogics.kojo.xscala.RepeatCommands + +// a static instance is needed for the compiler prefix code object Builtins { @volatile var instance: Builtins = _ } class Builtins( - val TSCanvas: DrawingCanvasAPI, - val Tw: TurtleWorldAPI, - val Staging: staging.API, - storyTeller: story.StoryTeller, - mp3player: music.KMp3, - fuguePlayer: music.FuguePlayer, - val kojoCtx: core.KojoCtx, - scalaCodeRunner: core.CodeRunner -) extends CoreBuiltins with RepeatCommands { builtins => + val TSCanvas: DrawingCanvasAPI, + val Tw: TurtleWorldAPI, + val Staging: staging.API, + storyTeller: story.StoryTeller, + mp3player: music.KMp3, + fuguePlayer: music.FuguePlayer, + val kojoCtx: core.KojoCtx, + scalaCodeRunner: core.CodeRunner +) extends CoreBuiltins + with RepeatCommands { builtins => Builtins.instance = this val tCanvas = TSCanvas.tCanvas @@ -59,11 +70,17 @@ class Builtins( UserCommand.addCompletion("repeat", "(${n}) {\n ${cursor}\n}") UserCommand.addSynopsis("repeat(n) {} - Repeats the commands within braces n number of times.") UserCommand.addCompletion("repeati", "(${n}) { i => \n ${cursor}\n}") - UserCommand.addSynopsis("repeati(n) {} - Repeats the commands within braces n number of times. The current repeat index is available within the braces.") + UserCommand.addSynopsis( + "repeati(n) {} - Repeats the commands within braces n number of times. The current repeat index is available within the braces." + ) UserCommand.addCompletion("repeatWhile", "(${condition}) {\n ${cursor}\n}") - UserCommand.addSynopsis("repeatWhile(cond) {} - Repeats the commands within braces while the given condition is true.") + UserCommand.addSynopsis( + "repeatWhile(cond) {} - Repeats the commands within braces while the given condition is true." + ) UserCommand.addCompletion("repeatUntil", "(${condition}) {\n ${cursor}\n}") - UserCommand.addSynopsis("repeatUntil(cond) {} - Repeats the commands within braces until the given condition is true.") + UserCommand.addSynopsis( + "repeatUntil(cond) {} - Repeats the commands within braces until the given condition is true." + ) def showScriptInOutput() = kojoCtx.showScriptInOutput() UserCommand("showScriptInOutput", Nil, "Enables the display of scripts in the output window when they run.") @@ -72,7 +89,11 @@ class Builtins( UserCommand("hideScriptInOutput", Nil, "Stops the display of scripts in the output window.") def showVerboseOutput() = kojoCtx.showVerboseOutput() - UserCommand("showVerboseOutput", Nil, "Enables the display of output from the Scala interpreter. By default, output from the interpreter is shown only for single line scripts.") + UserCommand( + "showVerboseOutput", + Nil, + "Enables the display of output from the Scala interpreter. By default, output from the interpreter is shown only for single line scripts." + ) def hideVerboseOutput() = kojoCtx.hideVerboseOutput() UserCommand("hideVerboseOutput", Nil, "Stops the display of output from the Scala interpreter.") @@ -86,17 +107,21 @@ class Builtins( def print(obj: Any): Unit = { // Runs on Actor pool (interpreter) thread - kojoCtx.kprintln("%s" format (obj)) + kojoCtx.kprintln("%s".format(obj)) Throttler.throttleHard() } UserCommand.addCompletion("print", List("obj")) - def println(obj: Any): Unit = print("%s\n" format (obj)) + def println(obj: Any): Unit = print("%s\n".format(obj)) UserCommand.addCompletion("println", List("obj")) UserCommand.addSynopsis("println(obj) or print(obj) - Displays the given object as a string in the output window.") def readln(prompt: String): String = kojoCtx.readInput(prompt) - UserCommand("readln", List("promptString"), "Displays the given prompt in the output window and reads a line that the user enters.") + UserCommand( + "readln", + List("promptString"), + "Displays the given prompt in the output window and reads a line that the user enters." + ) def onRunStart(): Unit = { BreakpointPane.onRunStart() @@ -113,15 +138,35 @@ class Builtins( } def readInt(prompt: String): Int = readln(prompt).toInt - UserCommand("readInt", List("promptString"), "Displays the given prompt in the output window and reads an Integer value that the user enters.") + UserCommand( + "readInt", + List("promptString"), + "Displays the given prompt in the output window and reads an Integer value that the user enters." + ) def readDouble(prompt: String): Double = readln(prompt).toDouble - UserCommand("readDouble", List("promptString"), "Displays the given prompt in the output window and reads a Double-precision Real value that the user enters.") - - UserCommand("random", List("lowerBound", "upperBound"), "Returns a random Integer between 0 (inclusive) and upperBound (exclusive).") - UserCommand("randomDouble", List("lowerBound", "upperBound"), "Returns a random Double-precision Real between 0 (inclusive) and upperBound (exclusive).") - - UserCommand("color", List("red", "green", "blue"), "Creates a new color based on the specified red, green, and blue levels.") + UserCommand( + "readDouble", + List("promptString"), + "Displays the given prompt in the output window and reads a Double-precision Real value that the user enters." + ) + + UserCommand( + "random", + List("lowerBound", "upperBound"), + "Returns a random Integer between 0 (inclusive) and upperBound (exclusive)." + ) + UserCommand( + "randomDouble", + List("lowerBound", "upperBound"), + "Returns a random Double-precision Real between 0 (inclusive) and upperBound (exclusive)." + ) + + UserCommand( + "color", + List("red", "green", "blue"), + "Creates a new color based on the specified red, green, and blue levels." + ) def setAstStopPhase(phase: String): Unit = kojoCtx.setAstStopPhase(phase) def astStopPhase = kojoCtx.astStopPhase @@ -151,13 +196,24 @@ class Builtins( UserCommand("stPlayStory", List("story"), "Play the given story.") def stFormula(latex: String, size: Int = 18, cssColor: String = null) = -
- { if (cssColor != null) { } else { } } +
+ { + if (cssColor != null) { + + } + else { + + } + }
- UserCommand("stFormula", List("latex"), "Converts the supplied latex string into html that can be displayed in the Story Teller Window.") + UserCommand( + "stFormula", + List("latex"), + "Converts the supplied latex string into html that can be displayed in the Story Teller Window." + ) def stPlayMp3(mp3File: String): Unit = { storyTeller.playMp3(mp3File) @@ -173,12 +229,18 @@ class Builtins( storyTeller.addButton(label)(fn) } UserCommand.addCompletion("stAddButton", " (${label}) {\n ${cursor}\n}") - UserCommand.addSynopsis("stAddButton(label) {code} - Adds a button with the given label to the Story Teller Window, and runs the supplied code when the button is clicked.") + UserCommand.addSynopsis( + "stAddButton(label) {code} - Adds a button with the given label to the Story Teller Window, and runs the supplied code when the button is clicked." + ) def stAddField(label: String, default: Any): Unit = { storyTeller.addField(label, default) } - UserCommand("stAddField", List("label", "default"), "Adds an input field with the supplied label and default value to the Story Teller Window.") + UserCommand( + "stAddField", + List("label", "default"), + "Adds an input field with the supplied label and default value to the Story Teller Window." + ) implicit val StringRead = util.Read.StringRead implicit val DoubleRead = util.Read.DoubleRead @@ -254,20 +316,68 @@ Here's a partial list of the available commands: def playMusicUntilDone(voice: Voice, n: Int = 1): Unit = { fuguePlayer.playMusicUntilDone(voice, n) } - UserCommand("playMusicUntilDone", List("score"), "Plays the specified melody, rhythm, or score, and waits till the music finishes.") + UserCommand( + "playMusicUntilDone", + List("score"), + "Plays the specified melody, rhythm, or score, and waits till the music finishes." + ) def playMusicLoop(voice: Voice): Unit = { fuguePlayer.playMusicLoop(voice) } - UserCommand("playMusicLoop", List("score"), "Plays the specified melody, rhythm, or score in the background - in a loop.") + UserCommand( + "playMusicLoop", + List("score"), + "Plays the specified melody, rhythm, or score in the background - in a loop." + ) + + val Instrument = music.Instrument + @volatile private var rtnp: Option[RealtimeNotePlayer] = None + + private def checkNotePlayer(): Unit = { + if (rtnp.isEmpty) { + rtnp = Some(new RealtimeNotePlayer()) + } + } + + def playNote(pitch: Int, durationMillis: Int, volume: Int = 80): Unit = { + checkNotePlayer() + rtnp.get.playNote(pitch, durationMillis, volume) + } + + def setNoteInstrument(instrumentCode: Int): Unit = { + checkNotePlayer() + rtnp.get.setInstrument(instrumentCode) + } + + def stopNotePlayer(): Unit = { + rtnp.foreach(_.stop()) + } - UserCommand("textExtent", List("text", "fontSize"), "Determines the size/extent of the given text fragment for the given font size.") + def resetNotePlayer(): Unit = { + rtnp.foreach(_.close()) + rtnp = None + } + + UserCommand( + "textExtent", + List("text", "fontSize"), + "Determines the size/extent of the given text fragment for the given font size." + ) def runInBackground(code: => Unit) = Utils.runAsyncMonitored(code) - UserCommand.addSynopsis("runInBackground", List("code"), "Runs the given code in the background, concurrently with other code that follows right after this command.") + UserCommand.addSynopsis( + "runInBackground", + List("code"), + "Runs the given code in the background, concurrently with other code that follows right after this command." + ) def runInGuiThread(code: => Unit) = Utils.runInSwingThread(code) - UserCommand.addSynopsis("runInGuiThread", List("code"), "Runs the given code in the the GUI Thread, concurrently with other code that follows right after this command.") + UserCommand.addSynopsis( + "runInGuiThread", + List("code"), + "Runs the given code in the the GUI Thread, concurrently with other code that follows right after this command." + ) def runInDrawingThread(code: => Unit) = Utils.runInSwingThread(code) def evalInDrawingThread[T](fn: => T) = Utils.runInSwingThreadAndWait(fn) @@ -304,7 +414,10 @@ Here's a partial list of the available commands: } def reimportDefaults() = reimportBuiltins() - import story.{HandlerHolder, IntHandlerHolder, StringHandlerHolder, VoidHandlerHolder} + import story.HandlerHolder + import story.IntHandlerHolder + import story.StringHandlerHolder + import story.VoidHandlerHolder implicit def toIhm(handler: Int => Unit): HandlerHolder[Int] = new IntHandlerHolder(handler) implicit def toShm(handler: String => Unit): HandlerHolder[String] = new StringHandlerHolder(handler) implicit def toVhm(handler: () => Unit): HandlerHolder[Unit] = new VoidHandlerHolder(handler) @@ -409,10 +522,12 @@ Here's a partial list of the available commands: def zIndex(idx: Int) = postDrawTransform { pic => pic.setZIndex(idx) } def clip(clipShape: java.awt.Shape) = picture.Clippedc(clipShape) - def rotated(pic: Picture, angle: Double) = pic.thatsRotated(angle) - def translated(pic: Picture, x: Double, y: Double) = pic.thatsTranslated(x, y) - def scaled(pic: Picture, factor: Double) = pic.thatsScaled(factor) - def filled(pic: Picture, color: Color) = pic.thatsFilledWith(color) + // some core picture transformations as regular functions - for educative use + def withRotation(pic: Picture, angle: Double) = pic.withRotation(angle) + def withTranslation(pic: Picture, x: Double, y: Double) = pic.withTranslation(x, y) + def withScaling(pic: Picture, factor: Double) = pic.withScaling(factor) + def withFillColor(pic: Picture, color: Color) = pic.withFillColor(color) + def withPenColor(pic: Picture, color: Color) = pic.withPenColor(color) implicit val _picCanvas = tCanvas def pict(painter: Painter) = picture.Pic(painter) @@ -445,6 +560,7 @@ Here's a partial list of the available commands: def stopAnimations() = kojoCtx.stopActivity() def stopAnimation() = kojoCtx.stopActivity() def isKeyPressed(key: Int) = staging.Inputs.isKeyPressed(key) + def pressedKeys: collection.Set[Int] = staging.Inputs.pressedKeys def activateCanvas() = kojoCtx.activateDrawingCanvas() def activateEditor() = kojoCtx.activateScriptEditor() @@ -637,14 +753,18 @@ Here's a partial list of the available commands: def fromTurtle(fn: Turtle => Unit) = PictureT(fn) def fromCanvas(width: Double, height: Double)(fn: Graphics2D => Unit) = picture.fromJava2d(width, height, fn) - private[lite] def fromCanvasDynamic(width: Double, height: Double, scaleOutFactor: Double) - (fn: Graphics2D => Unit)(stopCheck: => Boolean) = + private[lite] def fromCanvasDynamic(width: Double, height: Double, scaleOutFactor: Double)(fn: Graphics2D => Unit)( + stopCheck: => Boolean + ) = picture.fromJava2dDynamic(width, height, scaleOutFactor, fn, stopCheck) - def fromSketch(sketch: { - def setup(cd: CanvasDraw): Unit - def drawLoop(cd: CanvasDraw): Unit - }, scaleOutFactor: Double = 1): Picture = { + def fromSketch( + sketch: { + def setup(cd: CanvasDraw): Unit + def drawLoop(cd: CanvasDraw): Unit + }, + scaleOutFactor: Double = 1 + ): Picture = { val sr = new SketchRunner(sketch, scaleOutFactor) sr.pic } @@ -652,7 +772,8 @@ Here's a partial list of the available commands: def circle(radius: Double) = picture.circle(radius) // def circle(x: Double, y: Double, r: Double) = picture.offset(x, y) -> picture.circle(r) def ellipse(xRadius: Double, yRadius: Double) = picture.ellipse(xRadius, yRadius) - def ellipseInRect(width: Double, height: Double) = picture.trans(width / 2, height / 2) -> picture.ellipse(width / 2, height / 2) + def ellipseInRect(width: Double, height: Double) = + picture.trans(width / 2, height / 2) -> picture.ellipse(width / 2, height / 2) // def ellipse(x: Double, y: Double, rx: Double, ry: Double) = picture.offset(x, y) -> picture.ellipse(rx, ry) def arc(radius: Double, angle: Double) = picture.arc(radius, angle) def point = picture.trans(0, -0.01 / 2) -> line(0, 0.01) @@ -754,10 +875,13 @@ Here's a partial list of the available commands: placeAndDraw(pic, 0, 0) } - def fromSketch(sketch: { - def setup(cd: CanvasDraw): Unit - def drawLoop(cd: CanvasDraw): Unit - }, scaleOutFactor: Double = 1): Picture = { + def fromSketch( + sketch: { + def setup(cd: CanvasDraw): Unit + def drawLoop(cd: CanvasDraw): Unit + }, + scaleOutFactor: Double = 1 + ): Picture = { val pic = Picture.fromSketch(sketch, scaleOutFactor) placeAndDraw(pic, 0, 0) } @@ -765,14 +889,30 @@ Here's a partial list of the available commands: val pm = PictureMaker type Animation = animation.Animation - def Transition(durationSeconds: Double, fromState: Seq[Double], toState: Seq[Double], easer: KEasing, - picMaker: Seq[Double] => Picture, hideOnDone: Boolean): Animation = + def Transition( + durationSeconds: Double, + fromState: Seq[Double], + toState: Seq[Double], + easer: KEasing, + picMaker: Seq[Double] => Picture, + hideOnDone: Boolean + ): Animation = animation.Animation(durationSeconds, fromState, toState, easer, picMaker, hideOnDone) - def Timeline(duration: Double, keyFrames: animation.KeyFrames, easer: KEasing, - picMaker: Seq[Double] => Picture, hideOnDone: Boolean): Animation = + def Timeline( + duration: Double, + keyFrames: animation.KeyFrames, + easer: KEasing, + picMaker: Seq[Double] => Picture, + hideOnDone: Boolean + ): Animation = animation.Animation(duration, keyFrames, Seq.fill(keyFrames.frames.length - 1)(easer), picMaker, hideOnDone) - def Timeline(duration: Double, keyFrames: animation.KeyFrames, easers: Seq[KEasing], - picMaker: Seq[Double] => Picture, hideOnDone: Boolean): Animation = + def Timeline( + duration: Double, + keyFrames: animation.KeyFrames, + easers: Seq[KEasing], + picMaker: Seq[Double] => Picture, + hideOnDone: Boolean + ): Animation = animation.Animation(duration, keyFrames, easers, picMaker, hideOnDone) implicit def iis2dds(is: (Int, Seq[Int])): (Double, Seq[Double]) = is match { case (i, si) => (i.toDouble, si.map(_.toDouble)) @@ -780,7 +920,7 @@ Here's a partial list of the available commands: implicit def ids2dds(is: (Int, Seq[Double])): (Double, Seq[Double]) = is match { case (i, sd) => (i.toDouble, sd) } - def KeyFrames(frames: (Double, Seq[Double])*)= animation.KeyFrames(frames) + def KeyFrames(frames: (Double, Seq[Double])*) = animation.KeyFrames(frames) def animSeq(as: Animation*): Animation = animSeq(as) def animSeq(as: collection.Seq[Animation]): Animation = animation.animSeq(as.toSeq) def animPar(as: Animation*): Animation = animPar(as) @@ -824,7 +964,7 @@ Here's a partial list of the available commands: } } - private def makeCenteredMessage(message: String, color: Color = black, fontSize: Int = 15): Picture = { + def makeCenteredMessage(message: String, color: Color = black, fontSize: Int = 15): Picture = { val cb = canvasBounds val te = textExtent(message, fontSize) penColor(color) * @@ -847,12 +987,24 @@ Here's a partial list of the available commands: gameTimeRunning = false } - def showGameTimeCountdown(limitSecs: Int, endMsg: => String, color: Color = black, fontSize: Int = 15, - dx: Double = 10, dy: Double = 50) = showGameTime(limitSecs, endMsg, color, fontSize, dx, dy, true) - - - def showGameTime(limitSecs: Int, endMsg: => String, color: Color = black, fontSize: Int = 15, - dx: Double = 10, dy: Double = 50, countDown: Boolean = false): Unit = { + def showGameTimeCountdown( + limitSecs: Int, + endMsg: => String, + color: Color = black, + fontSize: Int = 15, + dx: Double = 10, + dy: Double = 50 + ) = showGameTime(limitSecs, endMsg, color, fontSize, dx, dy, true) + + def showGameTime( + limitSecs: Int, + endMsg: => String, + color: Color = black, + fontSize: Int = 15, + dx: Double = 10, + dy: Double = 50, + countDown: Boolean = false + ): Unit = { if (gameTimeRunning) { return } @@ -900,6 +1052,7 @@ Here's a partial list of the available commands: cwidth = cb.width.toInt cheight = cb.height.toInt clearGameTime() + currGame = null } def size(width: Int, height: Int): Unit = { @@ -952,10 +1105,13 @@ Here's a partial list of the available commands: type CanvasDraw = net.kogics.kojo.lite.CanvasDraw import scala.language.reflectiveCalls - class SketchRunner private[lite](sketch: { - def setup(cd: CanvasDraw): Unit - def drawLoop(cd: CanvasDraw): Unit - }, scaleFactor: Double = 1) { + class SketchRunner private[lite] ( + sketch: { + def setup(cd: CanvasDraw): Unit + def drawLoop(cd: CanvasDraw): Unit + }, + scaleFactor: Double = 1 + ) { @volatile var inited = false @volatile var initStarted = false // to support breakpoints in setup @volatile var cd: CanvasDraw = null @@ -981,19 +1137,22 @@ Here's a partial list of the available commands: } } - def canvasSketch(sketch: { - def setup(cd: CanvasDraw): Unit - def drawLoop(cd: CanvasDraw): Unit - }, scaleOutFactor: Double = 1): Unit = { + def canvasSketch( + sketch: { + def setup(cd: CanvasDraw): Unit + def drawLoop(cd: CanvasDraw): Unit + }, + scaleOutFactor: Double = 1 + ): Unit = { val sr = new SketchRunner(sketch, scaleOutFactor) sr.draw() } type PictureDraw = net.kogics.kojo.lite.PictureDraw def pictureSketch(sketch: { - def setup(cd: PictureDraw): Unit - def drawLoop(cd: PictureDraw): Unit - }): Unit = { + def setup(cd: PictureDraw): Unit + def drawLoop(cd: PictureDraw): Unit + }): Unit = { setup(sketch.setup(PictureDraw)) drawLoop(sketch.drawLoop(PictureDraw)) @@ -1026,21 +1185,39 @@ Here's a partial list of the available commands: import java.util.concurrent.Future val initPic = stateView(initState) initPic.draw() - lazy val anim: Future[PActivity] = tCanvas.animateWithState((initState, initPic)) { case (state, pic) => - pic.erase() - val pic2 = stateView(state) - pic2.draw() - val newState = nextState(state) - if (newState == state) { - tCanvas.stopAnimationActivity(anim) - } - (newState, pic2) + lazy val anim: Future[PActivity] = tCanvas.animateWithState((initState, initPic)) { + case (state, pic) => + val newState = nextState(state) + val pic2 = stateView(state) + pic.erase() + pic2.draw() + if (newState == state) { + tCanvas.stopAnimationActivity(anim) + } + (newState, pic2) } anim } - def runAnimation[S](init: S, update: S => S, view: S => Picture): Unit = - animateWithRedraw(init, update, view) + def animateWithSetupCanvasDraw(setupCanvas: CanvasDraw => Unit)(drawFrame: CanvasDraw => Unit): Unit = { + class Sketch { + def setup(canvas: CanvasDraw): Unit = { + setupCanvas(canvas) + } + + def drawLoop(canvas: CanvasDraw): Unit = { + drawFrame(canvas) + } + } + + val sketch = new Sketch + val pic = Picture.fromSketch(sketch, 1) + draw(pic) + } + + def animateWithCanvasDraw(drawFrame: CanvasDraw => Unit): Unit = { + animateWithSetupCanvasDraw { canvas => }(drawFrame) + } type Sub[M] = fpgaming.Sub[M] type CmdQ[M] = fpgaming.CmdQ[M] diff --git a/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala b/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala index 22198cac8..f246d84c0 100644 --- a/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala +++ b/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala @@ -27,6 +27,8 @@ import scala.reflect.internal.util.BatchSourceFile import scala.reflect.internal.util.OffsetPosition import scala.reflect.internal.util.Position import scala.reflect.internal.util.ScalaClassLoader.URLClassLoader +import scala.tools.nsc.Global +import scala.tools.nsc.Settings import scala.reflect.internal.Flags import scala.sys.process.Process import scala.sys.process.ProcessLogger @@ -261,14 +263,13 @@ class CompilerAndRunner( SRSwitcher.restoreRunSettings() } if (runReporter.hasErrors) IR.Error else IR.Success - } + } getOrElse (IR.Error) val run = new compiler.Run reporter.reset() run.compileSources(List(new BatchSourceFile("scripteditor", code))) // println(s"[Debug] Script checking done till phase: ${compiler.globalPhase.prev}") - if (reporter.hasErrors) IR.Error else IR.Success - } getOrElse (IR.Error) + if (reporter.hasErrors) IR.Error else IR.Success } def compileForExecing(code0: String): Results.Result = { @@ -387,7 +388,8 @@ class CompilerAndRunner( compiler.printAllUnits() IR.Success } - } + } getOrElse (IR.Error) + val run = new compiler.Run reporter.reset() run.compileSources(List(new BatchSourceFile("scripteditor", code))) @@ -399,7 +401,6 @@ class CompilerAndRunner( compiler.printAllUnits() IR.Success } - } getOrElse (IR.Error) } // phase after which you want to stop From da68c83c2214ce6c579dbd46e96e4c30d1e46f89 Mon Sep 17 00:00:00 2001 From: Ben Bulent Basaran Date: Mon, 31 Jul 2023 13:48:06 -0400 Subject: [PATCH 03/23] fix merge errors and add improvement to the turkish scala tutorial code for wall tennis --- .../samples/animated-square-creation.kojo | 65 +++ .../samples/tr/kojo-kilavuz/duvar-tenisi.kojo | 37 ++ .../net/kogics/kojo/fpgaming/package.scala | 97 ++-- .../net/kogics/kojo/music/Instrument.scala | 520 ++++++++++++++++++ .../kojo/music/RealtimeNotePlayer.scala | 87 +++ .../kojo/xscala/CompilerAndRunner.scala | 206 ++++--- 6 files changed, 871 insertions(+), 141 deletions(-) create mode 100644 src/main/resources/samples/animated-square-creation.kojo create mode 100644 src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi.kojo create mode 100644 src/main/scala/net/kogics/kojo/music/Instrument.scala create mode 100644 src/main/scala/net/kogics/kojo/music/RealtimeNotePlayer.scala diff --git a/src/main/resources/samples/animated-square-creation.kojo b/src/main/resources/samples/animated-square-creation.kojo new file mode 100644 index 000000000..9e5741ddb --- /dev/null +++ b/src/main/resources/samples/animated-square-creation.kojo @@ -0,0 +1,65 @@ +cleari() +setBackgroundH(ColorMaker.hsl(210, 1.00, 0.1), ColorMaker.hsl(210, 1.00, 0.15)) + +val sqSize = 200 +val diag = math.sqrt(2 * sqSize * sqSize) +val duration = 5 // seconds +val bg = cm.linearGradient(0, 0, ColorMaker.hsl(18, 1.00, 0.50), sqSize / 2, sqSize / 2, cm.gold) +val bg2 = cm.linearGradient(0, 0, cm.gold, sqSize / 2, sqSize / 2, ColorMaker.hsl(18, 1.00, 0.50)) + +def t(sz: Double) = Picture.fromPath { p => + p.moveTo(0, 0) + p.lineTo(0, sz) + p.lineTo(sz, 0) + p.closePath() +} + +def t1 = t(sqSize) +def t2 = t(diag / 2) + +def xProp(s: Seq[Double]) = s(0) +def yProp(s: Seq[Double]) = s(1) +def rProp(s: Seq[Double]) = s(2) + +def maket1(s: Seq[Double]) = + t1.withRotation(rProp(s)).withTranslation(xProp(s), yProp(s)) + .withTranslation(-sqSize / 2, -sqSize / 2) // to center + .withFillColor(bg) + .withPenColor(darkGray) + +def maket2(s: Seq[Double]) = + t2.withRotation(rProp(s)).withTranslation(xProp(s), yProp(s)) + .withTranslation(-sqSize / 2, -sqSize / 2) // to center + .withFillColor(bg2) + .withPenColor(darkGray) + +val anim1 = Transition( + duration, + Seq(-200, -200, 360), + Seq(0, 0, 0), + easing.Linear, + maket1, + false +) + +val anim2 = Transition( + duration, + Seq(-200, 200, -360), + Seq(sqSize / 2, sqSize / 2, 45), + easing.QuadInOut, + maket2, + false +) + +val anim3 = Transition( + duration, + Seq(200, 200, -360), + Seq(sqSize / 2, sqSize / 2, -45), + easing.QuadInOut, + maket2, + false +) + +val anim = animPar(anim1, anim2, anim3) + +run(anim) \ No newline at end of file diff --git a/src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi.kojo b/src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi.kojo new file mode 100644 index 000000000..4607fa48e --- /dev/null +++ b/src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi.kojo @@ -0,0 +1,37 @@ +silVeSakla() +çiz(götür(-200, -100) -> Resim.düz(0, 200)) // Üç duvar çizelim. Bu dik ön duvar +çiz(götür(-200, -100) -> Resim.düz(400, 0)) // Bu alt duvar +çiz(götür(-200, 100) -> Resim.düz(400, 0)) // Bu da üst duvar +dez rb = 80 // raketin boyu +dez raket = kalemRengi(mavi) -> Resim.düz(0, rb) +dez top = kalemRengi(mavi) -> Resim.daire(5) +dez skor = kalemRengi(siyah) * götür(-50, 150) -> Resim.yazı("Raketi fareyle yönet") +çiz(raket, top, skor) +den x = 0.0; den y = 0 // topun konumu +den dy = 8; den dx = -8.0 // topun hızı: d delta yani değişim ya da derivative yani türev demek +den rx = 0.0; den ry = 0.0 // raketin konumu +den ıska = 0 // top kaç kere kaçtı, saymak için +den vuruş = 0 // kaç kere raketle vurduğumuzu da sayalım +raket.kondur(fareKonumu) // raketi fareyle kontrol ediyoruz +canlandır { + rx = fareKonumu.x; ry = fareKonumu.y + rx = eğer (rx > -150) rx yoksa -150 // ama çok yaklaşmasın duvara! + rx = eğer (rx < 200) rx yoksa 200 // ve çok uzaklaşmasın + ry = eğer (-100 < ry) ry yoksa -100 // çok aşağıya ve çok yukarıya da gitmesin + ry = eğer (ry < 100 - rb) ry yoksa 100 - rb + raket.kondur(rx, ry) + top.kondur(x, y) // topun yerini değiştirelim + // top rakete çarpıyor mu? + dx = eğer ((dx > 0) && (mutlakDeğer(rx - x) < 10) && + (y > ry) && (y < ry + rb)) {vuruş += 1; -1.1*dx} yoksa dx + // topun konumunu güncelleyelim, duvarlara bakalım + dx = eğer (x + dx < -200) -dx yoksa dx // ön duvardan sekti mi? + dy = eğer ((y + dy < -100) || (y + dy > 100)) -dy yoksa dy // üst ve alt duvarlardan sekti mi? + eğer (x + dx > 200) { x = -200; dx = 8; ıska += 1 } // ıskaladı + x += dx; y += dy // topun gideceği noktayı hesaplayalım + eğer (ıska > 0 || vuruş > 0) { // skoru güncelleyelim + dez mesaj = eğer (vuruş == 0) "Fareyi tuvale getir!" yoksa s"$vuruş kere vurdun" + skor.güncelle(s"$mesaj\n$ıska kere ıskaladın") + } +} +oyunSüresiniGeriyeSayarakGöster(60, "Süre bitti", yeşil) // oyun 60 saniye sürsün \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/fpgaming/package.scala b/src/main/scala/net/kogics/kojo/fpgaming/package.scala index 4941509f0..2952d6a5b 100644 --- a/src/main/scala/net/kogics/kojo/fpgaming/package.scala +++ b/src/main/scala/net/kogics/kojo/fpgaming/package.scala @@ -15,7 +15,10 @@ */ package net.kogics.kojo -import net.kogics.kojo.core.{Picture, Point, SCanvas} +import net.kogics.kojo.core.Picture +import net.kogics.kojo.core.Point +import net.kogics.kojo.core.SCanvas +import net.kogics.kojo.util.Utils package object fpgaming { trait GameMsgSink[Msg] { @@ -24,7 +27,7 @@ package object fpgaming { def triggerUpdate(msg: Msg): Unit } - trait Sub[Msg] + trait Sub[+Msg] trait NonTimerSub[Msg] extends Sub[Msg] { def activate(gameMsgSink: GameMsgSink[Msg]): Unit @@ -66,9 +69,10 @@ package object fpgaming { case class OnMouseClick[Msg](mapper: Point => Msg)(implicit canvas: SCanvas) extends NonTimerSub[Msg] { def activate(gameMsgSink: GameMsgSink[Msg]): Unit = { - canvas.onMouseClick { case (x, y) => - val msg = mapper(Point(x, y)) - gameMsgSink.triggerUpdate(msg) + canvas.onMouseClick { + case (x, y) => + val msg = mapper(Point(x, y)) + gameMsgSink.triggerUpdate(msg) } } @@ -87,18 +91,23 @@ package object fpgaming { def onMouseClick[Msg](mapper: Point => Msg)(implicit cavas: SCanvas): Sub[Msg] = OnMouseClick(mapper) } + trait CmdQ[+Msg] { + def run(): Msg + } + class Game[Model, Msg]( - init: => Model, - update: (Model, Msg) => Model, - view: Model => Picture, - subscriptions: Model => Seq[Sub[Msg]] - )(implicit canvas: SCanvas) extends GameMsgSink[Msg] { + init: => Model, + update: (Model, Msg) => Model, + view: Model => Picture, + subscriptions: Model => Seq[Sub[Msg]] + )(implicit canvas: SCanvas) + extends GameMsgSink[Msg] { private var currModel: Model = _ private var currSubs: Seq[Sub[Msg]] = _ private var currView: Picture = _ private var firstTime = true - var gameTimer = canvas.timer(20) { + private var gameTimer = canvas.timer(20) { if (firstTime) { firstTime = false currModel = init @@ -110,53 +119,71 @@ package object fpgaming { else { fireTimerSubs() updateView() + checkForStop() } } - def timerSubs: Seq[TimerSub[Msg]] = currSubs.filter(_.isInstanceOf[TimerSub[Msg]]).asInstanceOf[Seq[TimerSub[Msg]]] + private def timerSubs: Seq[TimerSub[Msg]] = + currSubs.filter(_.isInstanceOf[TimerSub[Msg]]).asInstanceOf[Seq[TimerSub[Msg]]] - def nonTimerSubs: Seq[NonTimerSub[Msg]] = currSubs.filter(_.isInstanceOf[NonTimerSub[Msg]]).asInstanceOf[Seq[NonTimerSub[Msg]]] + private def nonTimerSubs: Seq[NonTimerSub[Msg]] = + currSubs.filter(_.isInstanceOf[NonTimerSub[Msg]]).asInstanceOf[Seq[NonTimerSub[Msg]]] - def updateView(): Unit = { + private def updateView(): Unit = { val oldView = currView currView = view(currModel) oldView.erase() currView.draw() } - def updateModelAndSubs(msg: Msg): Unit = { + private def updateModelAndSubs(msg: Msg): Unit = { currModel = update(currModel, msg) val oldSubs = currSubs currSubs = subscriptions(currModel) handleSubChanges(oldSubs, currSubs) } - def handleSubChanges(oldSubs: Seq[Sub[Msg]], newSubs: Seq[Sub[Msg]]): Unit = { - if (newSubs.length != oldSubs.length) { - val newSubsSet = Set(newSubs: _*) - oldSubs.foreach { sub => - sub match { - case ntSub: NonTimerSub[Msg] => - if (!newSubsSet.contains(ntSub)) { - ntSub.deactivate() - } - case _ => - } + private def handleSubChanges(oldSubs: Seq[Sub[Msg]], newSubs: Seq[Sub[Msg]]): Unit = { + if (newSubs != oldSubs) { + lazy val newSubsSet = Set(newSubs: _*) + oldSubs.foreach { + case oldNtSub: NonTimerSub[Msg] => + if (!newSubsSet.contains(oldNtSub)) { + oldNtSub.deactivate() + } + case _ => + } + + lazy val oldSubsSet = Set(oldSubs: _*) + newSubs.foreach { + case newNtSub: NonTimerSub[Msg] => + if (!oldSubsSet.contains(newNtSub)) { + newNtSub.activate(this) + } + case _ => } } } - def checkForStop(): Unit = { + private def checkForStop(): Unit = { if (currSubs.isEmpty) { canvas.stopAnimationActivity(gameTimer) } } - def fireTimerSubs(): Unit = { + private def fireTimerSubs(): Unit = { timerSubs.foreach { sub => sub.fire(this) } - checkForStop() + } + + def runCommandQuery(cmdQ: CmdQ[Msg]): Unit = { + Utils.runAsync { + val msg = cmdQ.run() + Utils.runInSwingThreadNonBatched { + triggerUpdate(msg) + } + } } def triggerIncrementalUpdate(msg: Msg): Unit = { @@ -190,9 +217,15 @@ package object fpgaming { } def collidesWith( - x1: Double, y1: Double, w1: Double, h1: Double, - x2: Double, y2: Double, w2: Double, h2: Double - ): Boolean = { + x1: Double, + y1: Double, + w1: Double, + h1: Double, + x2: Double, + y2: Double, + w2: Double, + h2: Double + ): Boolean = { import java.awt.geom.Rectangle2D val r1 = new Rectangle2D.Double(x1, y1, w1, h1) val r2 = new Rectangle2D.Double(x2, y2, w2, h2) diff --git a/src/main/scala/net/kogics/kojo/music/Instrument.scala b/src/main/scala/net/kogics/kojo/music/Instrument.scala new file mode 100644 index 000000000..a6a03ef77 --- /dev/null +++ b/src/main/scala/net/kogics/kojo/music/Instrument.scala @@ -0,0 +1,520 @@ +/* + * Copyright (C) 2022 Lalit Pant + * + * The contents of this file are subject to the GNU General Public License + * Version 3 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.gnu.org/copyleft/gpl.html + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + */ +package net.kogics.kojo.music + +object Instrument { + + // constants from jmusic (https://explodingart.com/jmusic/index.html) + + val PIANO = 0 + + val ACOUSTIC_GRAND = 0 + + val BRIGHT_ACOUSTIC = 1 + + val ELECTRIC_GRAND = 2 + + val HONKYTONK = 3 + + val HONKYTONK_PIANO = 3 + + val EPIANO = 4 + + val ELECTRIC_PIANO = 4 + + val ELPIANO = 4 + + val RHODES = 4 + + val EPIANO2 = 5 + + val DX_EPIANO = 5 + + val HARPSICHORD = 6 + + val CLAV = 7 + + val CLAVINET = 7 + + val CELESTE = 8 + + val CELESTA = 8 + + val GLOCKENSPIEL = 9 + + val GLOCK = 9 + + val MUSIC_BOX = 10 + + val VIBRAPHONE = 11 + + val VIBES = 11 + + val MARIMBA = 12 + + val XYLOPHONE = 13 + + val TUBULAR_BELL = 14 + + val TUBULAR_BELLS = 14 + + val ORGAN = 16 + + val ELECTRIC_ORGAN = 16 + + val ORGAN2 = 17 + + val JAZZ_ORGAN = 17 + + val ORGAN3 = 18 + + val HAMMOND_ORGAN = 17 + + val CHURCH_ORGAN = 19 + + val PIPE_ORGAN = 19 + + val REED_ORGAN = 20 + + val ACCORDION = 21 + + val PIANO_ACCORDION = 21 + + val CONCERTINA = 21 + + val HARMONICA = 22 + + val BANDNEON = 23 + + val NYLON_GUITAR = 24 + + val NGUITAR = 24 + + val GUITAR = 24 + + val ACOUSTIC_GUITAR = 24 + + val AC_GUITAR = 24 + + val STEEL_GUITAR = 25 + + val SGUITAR = 25 + + val JAZZ_GUITAR = 26 + + val JGUITAR = 26 + + val CLEAN_GUITAR = 27 + + val CGUITAR = 27 + + val ELECTRIC_GUITAR = 27 + + val EL_GUITAR = 27 + + val MUTED_GUITAR = 28 + + val MGUITAR = 28 + + val OVERDRIVE_GUITAR = 29 + + val OGUITAR = 29 + + val DISTORTED_GUITAR = 30 + + val DGUITAR = 30 + + val DIST_GUITAR = 30 + + val GUITAR_HARMONICS = 31 + + val GT_HARMONICS = 31 + + val HARMONICS = 31 + + val ACOUSTIC_BASS = 32 + + val ABASS = 32 + + val FINGERED_BASS = 33 + + val BASS = 33 + + val FBASS = 33 + + val ELECTRIC_BASS = 33 + + val EL_BASS = 33 + + val EBASS = 33 + + val PICKED_BASS = 34 + + val PBASS = 34 + + val FRETLESS_BASS = 35 + + val FRETLESS = 35 + + val SLAP_BASS = 36 + + val SBASS = 36 + + val SLAP = 36 + + val SLAP_BASS_1 = 36 + + val SLAP_BASS_2 = 37 + + val SYNTH_BASS = 38 + + val SYNTH_BASS_1 = 38 + + val SYNTH_BASS_2 = 39 + + val VIOLIN = 40 + + val VIOLA = 41 + + val CELLO = 42 + + val VIOLIN_CELLO = 42 + + val CONTRABASS = 43 + + val CONTRA_BASS = 43 + + val DOUBLE_BASS = 43 + + val TREMOLO_STRINGS = 44 + + val TREMOLO = 44 + + val PIZZICATO_STRINGS = 45 + + val PIZZ = 45 + + val PITZ = 45 + + val PSTRINGS = 45 + + val HARP = 46 + + val TIMPANI = 47 + + val TIMP = 47 + + val STRINGS = 48 + + val STR = 48 + + val STRING_ENSEMBLE_1 = 48 + + val STRING_ENSEMBLE_2 = 49 + + val SYNTH_STRINGS = 50 + + val SYNTH_STRINGS_1 = 50 + + val SLOW_STRINGS = 51 + + val SYNTH_STRINGS_2 = 51 + + val AAH = 52 + + val AHHS = 52 + + val CHOIR = 52 + + val OOH = 53 + + val OOHS = 53 + + val VOICE = 53 + + val SYNVOX = 54 + + val VOX = 54 + + val ORCHESTRA_HIT = 55 + + val TRUMPET = 56 + + val TROMBONE = 57 + + val TUBA = 58 + + val MUTED_TRUMPET = 59 + + val FRENCH_HORN = 60 + + val HORN = 60 + + val BRASS = 61 + + val SYNTH_BRASS = 62 + + val SYNTH_BRASS_1 = 62 + + val SYNTH_BRASS_2 = 63 + + val SOPRANO_SAX = 64 + + val SOPRANO = 64 + + val SOPRANO_SAXOPHONE = 64 + + val SOP = 64 + + val ALTO_SAX = 65 + + val ALTO = 65 + + val ALTO_SAXOPHONE = 65 + + val TENOR_SAX = 66 + + val TENOR = 66 + + val TENOR_SAXOPHONE = 66 + + val SAX = 66 + + val SAXOPHONE = 66 + + val BARITONE_SAX = 67 + + val BARI = 67 + + val BARI_SAX = 67 + + val BARITONE = 67 + + val BARITONE_SAXOPHONE = 67 + + val OBOE = 68 + + val ENGLISH_HORN = 69 + + val BASSOON = 70 + + val CLARINET = 71 + + val CLAR = 71 + + val PICCOLO = 72 + + val PIC = 72 + + val PICC = 72 + + val FLUTE = 73 + + val RECORDER = 74 + + val PAN_FLUTE = 75 + + val PANFLUTE = 75 + + val BOTTLE_BLOW = 76 + + val BOTTLE = 76 + + val SHAKUHACHI = 77 + + val WHISTLE = 78 + + val OCARINA = 79 + + val GMSQUARE_WAVE = 80 + + val SQUARE = 80 + + val GMSAW_WAVE = 81 + + val SAW = 81 + + val SAWTOOTH = 81 + + val SYNTH_CALLIOPE = 82 + + val CALLOPE = 82 + + val SYN_CALLIOPE = 82 + + val CHIFFER_LEAD = 83 + + val CHIFFER = 83 + + val CHARANG = 84 + + val SOLO_VOX = 85 + + val FANTASIA = 88 + + val WARM_PAD = 89 + + val PAD = 89 + + val POLYSYNTH = 90 + + val POLY_SYNTH = 90 + + val SPACE_VOICE = 91 + + val BOWED_GLASS = 92 + + val METAL_PAD = 93 + + val HALO_PAD = 94 + + val HALO = 94 + + val SWEEP_PAD = 95 + + val SWEEP = 95 + + val ICE_RAIN = 96 + + val ICERAIN = 96 + + val SOUNDTRACK = 97 + + val CRYSTAL = 98 + + val ATMOSPHERE = 99 + + val BRIGHTNESS = 100 + + val GOBLIN = 101 + + val ECHO_DROPS = 102 + + val DROPS = 102 + + val ECHOS = 102 + + val ECHO = 102 + + val ECHO_DROP = 102 + + val STAR_THEME = 103 + + val SITAR = 104 + + val BANJO = 105 + + val SHAMISEN = 106 + + val KOTO = 107 + + val KALIMBA = 108 + + val THUMB_PIANO = 108 + + val BAGPIPES = 109 + + val BAG_PIPES = 109 + + val BAGPIPE = 109 + + val PIPES = 109 + + val FIDDLE = 110 + + val SHANNAI = 111 + + val TINKLE_BELL = 112 + + val BELL = 112 + + val BELLS = 112 + + val AGOGO = 113 + + val STEEL_DRUMS = 114 + + val STEELDRUMS = 114 + + val STEELDRUM = 114 + + val STEEL_DRUM = 114 + + val WOODBLOCK = 115 + + val WOODBLOCKS = 115 + + val TAIKO = 116 + + val DRUM = 116 + + val TOM = 119 + + val TOMS = 119 + + val TOM_TOM = 119 + + val TOM_TOMS = 119 + + val SYNTH_DRUM = 118 + + val SYNTH_DRUMS = 118 + + val REVERSE_CYMBAL = 119 + + val CYMBAL = 119 + + val FRETNOISE = 120 + + val FRET_NOISE = 120 + + val FRET = 120 + + val FRETS = 120 + + val BREATHNOISE = 121 + + val BREATH = 121 + + val SEASHORE = 122 + + val SEA = 122 + + val RAIN = 122 + + val THUNDER = 122 + + val WIND = 122 + + val STREAM = 122 + + val SFX = 122 + + val SOUNDEFFECTS = 122 + + val SOUNDFX = 122 + + val BIRD = 123 + + val TELEPHONE = 124 + + val PHONE = 124 + + val HELICOPTER = 125 + + val APPLAUSE = 126 + + val GUNSHOT = 127 +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/music/RealtimeNotePlayer.scala b/src/main/scala/net/kogics/kojo/music/RealtimeNotePlayer.scala new file mode 100644 index 000000000..d7fc9af2d --- /dev/null +++ b/src/main/scala/net/kogics/kojo/music/RealtimeNotePlayer.scala @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2023 Lalit Pant + * + * The contents of this file are subject to the GNU General Public License + * Version 3 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.gnu.org/copyleft/gpl.html + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + */ +package net.kogics.kojo.music + +import javax.sound.midi.MidiEvent +import javax.sound.midi.MidiSystem +import javax.sound.midi.Sequence +import javax.sound.midi.ShortMessage + +class RealtimeNotePlayer { + println("Initializing Midi Sequencer...") + private val sequencer = MidiSystem.getSequencer() + private val ticksPerQuarterNote = 1 + private val sequence = new Sequence(Sequence.PPQ, ticksPerQuarterNote) + private var track = sequence.createTrack() + private var trackTicks = 0L + private val channel = 0 + + sequencer.open() + sequencer.setSequence(sequence) + Thread.sleep(2500) // give Midi Synth a chance to warm up, as in alda + println("Done") + setInstrument(Instrument.PIANO) + + def setInstrument(instrumentCode: Int): Unit = { + require(instrumentCode >= 0 && instrumentCode <= 127, "Instrument Code should be between 0 and 127") + val insMsg = new ShortMessage(ShortMessage.PROGRAM_CHANGE, channel, instrumentCode, 0) + val insEvent = new MidiEvent(insMsg, trackTicks) + track.add(insEvent) + } + + def playNote(pitch: Int, durationMillis: Int, volume: Int): Unit = { + require(pitch >= 0 && pitch <= 127, "Note pitch should be between 0 and 127") + require(volume >= 0 && volume <= 127, "Note volume should be between 0 and 127") + + val durationTicks = durationMillis // our ticks are in units of millis + val endBuffer0 = (0.1 * durationTicks).toInt + val endBuffer = if (endBuffer0 > 0) endBuffer0 else 1 + + val noteOnMsg = new ShortMessage(ShortMessage.NOTE_ON, channel, pitch, volume) + val noteOnEvent = new MidiEvent(noteOnMsg, trackTicks) + track.add(noteOnEvent) + trackTicks += durationTicks + + val noteOffMsg = new ShortMessage(ShortMessage.NOTE_OFF, channel, pitch, volume) + val noteOffEvent = new MidiEvent(noteOffMsg, trackTicks - endBuffer) + track.add(noteOffEvent) + + if (!sequencer.isRunning) { + // tempo in increments of 1ms + sequencer.setTempoInMPQ(1000f) + sequencer.start() + } + else { + // let the running sequencer play this note after the previous ones are done + } + } + + def stop(): Unit = { + if (sequencer.isRunning) { + sequencer.stop() + sequence.deleteTrack(track) + track = sequence.createTrack() + sequencer.setSequence(sequence) + trackTicks = 0L + sequencer.setTickPosition(0) + } + } + + def close(): Unit = { + sequencer.stop() + sequence.deleteTrack(track) + sequencer.close() + } +} \ No newline at end of file diff --git a/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala b/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala index f246d84c0..36eef6ff7 100644 --- a/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala +++ b/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala @@ -21,14 +21,11 @@ import java.net.URL import scala.collection.mutable.ListBuffer import scala.language.postfixOps -import scala.reflect.internal.Flags import scala.reflect.internal.util.AbstractFileClassLoader import scala.reflect.internal.util.BatchSourceFile import scala.reflect.internal.util.OffsetPosition import scala.reflect.internal.util.Position import scala.reflect.internal.util.ScalaClassLoader.URLClassLoader -import scala.tools.nsc.Global -import scala.tools.nsc.Settings import scala.reflect.internal.Flags import scala.sys.process.Process import scala.sys.process.ProcessLogger @@ -36,6 +33,8 @@ import scala.tools.nsc.interactive import scala.tools.nsc.interpreter.Results import scala.tools.nsc.io.VirtualDirectory import scala.tools.nsc.reporters.Reporter +import scala.tools.nsc.Global +import scala.tools.nsc.Settings import scala.tools.util.PathResolver import net.kogics.kojo.core.CompletionInfo @@ -60,19 +59,19 @@ trait CompilerListener { // This class borrows code and ideas from scala.tools.nsc.Interpreter class CompilerAndRunner( - makeSettings: () => Settings, - initCode: => Option[String], - listener: CompilerListener, - runContext: RunContext + makeSettings: () => Settings, + initCode: => Option[String], + listener: CompilerListener, + runContext: RunContext ) extends StoppableCodeRunner { import language.postfixOps var counter = 0 - // The Counter above is used to define/create a new wrapper object for every run. The calling of the entry() - //.method within this object results in the initialization of the object, which causes the user submitted + // The Counter above is used to define/create a new wrapper object for every run. The calling of the entry() + // .method within this object results in the initialization of the object, which causes the user submitted // code to run. // If we don't increment the counter, the user code will not run (an object is initialized only once) - // If this approach turns out to be too memory intensive, I'm sure there are other ways of running user + // If this approach turns out to be too memory intensive, I'm sure there are other ways of running user // submitted code.' val prefixHeader = "object Wrapper" val prefix0 = runContext.compilerPrefix @@ -125,15 +124,15 @@ class CompilerAndRunner( val compilerClasspath: List[URL] = new PathResolver(runSettings).resultAsURLs.toList var classLoader = makeClassLoader - // needed to prevent pcompiler from making the interp's classloader as + // needed to prevent pcompiler from making the interp's classloader as // its context loader (which causes a mem leak) - // we could make pcompiler lazy, but then the first completion takes a big hit + // we could make pcompiler lazy, but then the first completion takes a big hit private def makeClassLoader = { val parent = new URLClassLoader(compilerClasspath, getClass.getClassLoader()) new AbstractFileClassLoader(virtualDirectory, parent) } - private def loadByName(s: String): Class[_] = (classLoader loadClass s) + private def loadByName(s: String): Class[_] = classLoader.loadClass(s) trait KojoReporter extends Reporter { def lineMod: Int @@ -263,13 +262,8 @@ class CompilerAndRunner( SRSwitcher.restoreRunSettings() } if (runReporter.hasErrors) IR.Error else IR.Success - } getOrElse (IR.Error) - - val run = new compiler.Run - reporter.reset() - run.compileSources(List(new BatchSourceFile("scripteditor", code))) - // println(s"[Debug] Script checking done till phase: ${compiler.globalPhase.prev}") - if (reporter.hasErrors) IR.Error else IR.Success + } + .getOrElse(IR.Error) } def compileForExecing(code0: String): Results.Result = { @@ -300,7 +294,7 @@ class CompilerAndRunner( try { classLoader = makeClassLoader classLoader.asContext { - val loadedResultObject = loadByName("Wrapper%d" format (counter)) + val loadedResultObject = loadByName("Wrapper%d".format(counter)) loadedResultObject.getMethod("entry").invoke(loadedResultObject) IR.Success } @@ -388,19 +382,8 @@ class CompilerAndRunner( compiler.printAllUnits() IR.Success } - } getOrElse (IR.Error) - - val run = new compiler.Run - reporter.reset() - run.compileSources(List(new BatchSourceFile("scripteditor", code))) - - if (reporter.hasErrors) { - IR.Error - } - else { - compiler.printAllUnits() - IR.Success } + .getOrElse(IR.Error) } // phase after which you want to stop @@ -410,21 +393,21 @@ class CompilerAndRunner( } val preporter = new Reporter { - override def info0(position: Position, msg: String, severity: Severity, force: Boolean): Unit = { - } + override def info0(position: Position, msg: String, severity: Severity, force: Boolean): Unit = {} } class KGlobal(s: Settings, r: Reporter) extends interactive.Global(s, r) { def mkCompletionProposal(sym: Symbol, tpe: Type, inherited: Boolean, viaView: Symbol): CompletionInfo = { // code borrowed from Scala Eclipse Plugin, after my own hacks in this area failed with 2.10.1 - val kind = if (sym.isSourceMethod && !sym.hasFlag(Flags.ACCESSOR | Flags.PARAMACCESSOR)) Def - else if (sym.hasPackageFlag) Package - else if (sym.isClass) Class - else if (sym.isTrait) Trait - else if (sym.isPackageObject) PackageObject - else if (sym.isModule) Object - else if (sym.isType) Type - else Val + val kind = + if (sym.isSourceMethod && !sym.hasFlag(Flags.ACCESSOR | Flags.PARAMACCESSOR)) Def + else if (sym.hasPackageFlag) Package + else if (sym.isClass) Class + else if (sym.isTrait) Trait + else if (sym.isPackageObject) PackageObject + else if (sym.isModule) Object + else if (sym.isType) Type + else Val val name = sym.decodedName val returnType = @@ -436,8 +419,8 @@ class CompilerAndRunner( if (sym.isMethod) { "%s: %s".format( name + - (if (!sym.typeParams.isEmpty) sym.typeParams.map { _.name }.mkString("[", ",", "]") else "") + - tpe.paramss.map(_.map(_.tpe.toString).mkString("(", ", ", ")")).mkString, + (if (!sym.typeParams.isEmpty) sym.typeParams.map { _.name }.mkString("[", ",", "]") else "") + + tpe.paramss.map(_.map(_.tpe.toString).mkString("(", ", ", ")")).mkString, returnType ) } @@ -455,9 +438,11 @@ class CompilerAndRunner( if (sym.hasPackageFlag) relevance += 30 // theoretically we'd need an 'ask' around this code, but given that // Any and AnyRef are definitely loaded, we call directly to definitions. - if (sym.owner == definitions.AnyClass + if ( + sym.owner == definitions.AnyClass || sym.owner == definitions.AnyRefClass - || sym.owner == definitions.ObjectClass) { + || sym.owner == definitions.ObjectClass + ) { relevance += 40 } val pfx = prefix @@ -501,34 +486,35 @@ class CompilerAndRunner( val source = new BatchSourceFile("scripteditor", code) val pos = new OffsetPosition(source, offset + offsetDelta + 1) - var r1 = new Response[Unit] - pcompiler.askReload(List(source), r1) - - var resp = new Response[pcompiler.Tree] - pcompiler.askTypeAt(pos, resp) - - val respget = resp.get - val response: pcompiler.Response[String] = pcompiler.askForResponse { () => - respget match { - case Left(x) => - x match { - case t: pcompiler.ValOrDefDef => t.tpt.toString - case t: pcompiler.TypeDef => t.name.toString - case t: pcompiler.ClassDef => t.name.toString - case _ => x.tpe.toString - } + var r1 = new Response[Unit] + pcompiler.askReload(List(source), r1) + + var resp = new Response[pcompiler.Tree] + pcompiler.askTypeAt(pos, resp) + + val respget = resp.get + val response: pcompiler.Response[String] = pcompiler.askForResponse { () => + respget match { + case Left(x) => + x match { + case t: pcompiler.ValOrDefDef => t.tpt.toString + case t: pcompiler.TypeDef => t.name.toString + case t: pcompiler.ClassDef => t.name.toString + case _ => x.tpe.toString + } - case Right(y) => - // println("Right:" + y) - "" + case Right(y) => + // println("Right:" + y) + "" + } + } + response.get match { + case Left(s) => s + case Right(_) => "" } - } - response.get match { - case Left(s) => s - case Right(_) => "" } } - } getOrElse ("") + .getOrElse("") } import core.CompletionInfo @@ -540,8 +526,8 @@ class CompilerAndRunner( val queryOffset = if (selection) offset - 1 else offset completionQuery(augmentedCode, queryOffset, selection) match { - case Nil => if (selection) completionQuery(code, queryOffset, selection) else Nil - case _@ret => ret + case Nil => if (selection) completionQuery(code, queryOffset, selection) else Nil + case _ @ret => ret } } @@ -554,49 +540,51 @@ class CompilerAndRunner( val source = new BatchSourceFile("scripteditor", code) val pos = new OffsetPosition(source, offset + offsetDelta + 1) - val r1 = new Response[Unit] - pcompiler.askReload(List(source), r1) + val r1 = new Response[Unit] + pcompiler.askReload(List(source), r1) - val resp = new Response[List[pcompiler.Member]] - if (selection) { - pcompiler.askTypeCompletion(pos, resp) - } - else { - pcompiler.askScopeCompletion(pos, resp) - } + val resp = new Response[List[pcompiler.Member]] + if (selection) { + pcompiler.askTypeCompletion(pos, resp) + } + else { + pcompiler.askScopeCompletion(pos, resp) + } - val completionTimeout = 3000 - resp.get(completionTimeout) match { - case Some(Left(completions)) => - val response: pcompiler.Response[List[CompletionInfo]] = pcompiler.askForResponse { () => - val elb = new ListBuffer[CompletionInfo] - completions.foreach { completion => - try { - completion match { - case pcompiler.TypeMember(sym, tpe, true, inherited, viaView, aliasInfo) if !sym.isConstructor /*&& nameMatches(sym)*/ => - elb += pcompiler.mkCompletionProposal(sym, tpe, inherited, viaView) - case pcompiler.ScopeMember(sym, tpe, true, _, aliasInfo) if !sym.isConstructor /*&& nameMatches(sym)*/ => - elb += pcompiler.mkCompletionProposal(sym, tpe, false, pcompiler.NoSymbol) - case _ => + val completionTimeout = 3000 + resp.get(completionTimeout) match { + case Some(Left(completions)) => + val response: pcompiler.Response[List[CompletionInfo]] = pcompiler.askForResponse { () => + val elb = new ListBuffer[CompletionInfo] + completions.foreach { completion => + try { + completion match { + case pcompiler.TypeMember(sym, tpe, true, inherited, viaView, aliasInfo) // scala 2.13.x + if !sym.isConstructor /*&& nameMatches(sym)*/ => + elb += pcompiler.mkCompletionProposal(sym, tpe, inherited, viaView) + case pcompiler.ScopeMember(sym, tpe, true, _, aliasInfo) if !sym.isConstructor /*&& nameMatches(sym)*/ => // scala 2.13.x + elb += pcompiler.mkCompletionProposal(sym, tpe, false, pcompiler.NoSymbol) + case _ => + } + } + catch { + case t: Throwable => + println("Completion Problem 0: " + t.getMessage()) + // ignore, and move on to the next one } } - catch { - case t: Throwable => - println("Completion Problem 0: " + t.getMessage()) - // ignore, and move on to the next one - } + elb.toList } - elb.toList - } - response.get match { - case Left(l) => l - case Right(_) => Nil - } - case Some(Right(_)) => Nil - case None => Nil + response.get match { + case Left(l) => l + case Right(_) => Nil + } + case Some(Right(_)) => Nil + case None => Nil + } } } - } getOrElse (Nil) + .getOrElse(Nil) } val processLogger = new ProcessLogger { From 763f33239a431fe1b000eae27a785eafd923c1ee Mon Sep 17 00:00:00 2001 From: Ben Bulent Basaran Date: Mon, 31 Jul 2023 14:04:29 -0400 Subject: [PATCH 04/23] install4j files use hardcoded paths. so we keep two: kojo for Lalit, original koco for Bulent for Turkish keywords --- ...up_before_manual_tweaks => koco.install4j} | 41 +- installer.i4j/kojo.install4j | 35 +- installer.i4j/kojo.install4j_lalit | 634 ------------------ 3 files changed, 51 insertions(+), 659 deletions(-) rename installer.i4j/{kojo.install4j.backup_before_manual_tweaks => koco.install4j} (93%) delete mode 100644 installer.i4j/kojo.install4j_lalit diff --git a/installer.i4j/kojo.install4j.backup_before_manual_tweaks b/installer.i4j/koco.install4j similarity index 93% rename from installer.i4j/kojo.install4j.backup_before_manual_tweaks rename to installer.i4j/koco.install4j index 53b95ebb2..a4d45370c 100644 --- a/installer.i4j/kojo.install4j.backup_before_manual_tweaks +++ b/installer.i4j/koco.install4j @@ -1,7 +1,7 @@ - + - + @@ -9,7 +9,7 @@ - + @@ -52,7 +52,6 @@ - @@ -67,8 +66,36 @@ + + + + /Users/ben/src/kojo/git/kojo/installer/icons/kojo16.png + + + + + /Users/ben/src/kojo/git/kojo/installer/icons/kojo32.png + + + + + /Users/ben/src/kojo/git/kojo/installer/icons/kojo48.png + + + + + /Users/ben/src/kojo/git/kojo/installer/icons/kojo64.png + + + + + /Users/ben/src/kojo/git/kojo/installer/icons/kojo128.png + + + + @@ -593,7 +620,7 @@ return console.askYesNo(message, true); - + @@ -601,9 +628,11 @@ return console.askYesNo(message, true); - + + + diff --git a/installer.i4j/kojo.install4j b/installer.i4j/kojo.install4j index f5c106650..f8170744e 100644 --- a/installer.i4j/kojo.install4j +++ b/installer.i4j/kojo.install4j @@ -1,10 +1,7 @@ - - - - - + + @@ -41,7 +38,7 @@ - + @@ -54,11 +51,11 @@ - - - - - + + + + + @@ -69,32 +66,33 @@ - /Users/ben/src/kojo/git/kojo/installer/icons/kojo16.png + /home/lalit/work/kojo/installer/icons/kojo16.png - /Users/ben/src/kojo/git/kojo/installer/icons/kojo32.png + /home/lalit/work/kojo/installer/icons/kojo32.png - /Users/ben/src/kojo/git/kojo/installer/icons/kojo48.png + /home/lalit/work/kojo/installer/icons/kojo48.png - /Users/ben/src/kojo/git/kojo/installer/icons/kojo64.png + /home/lalit/work/kojo/installer/icons/kojo64.png - /Users/ben/src/kojo/git/kojo/installer/icons/kojo128.png + /home/lalit/work/kojo/installer/icons/kojo128.png + @@ -165,7 +163,7 @@ return console.askOkCancel(message, true); en - /Users/ben/src/kojo/git/kojo/installerbuild/licenses/Kojoi-license.txt + /home/lalit/work/kojo/installerbuild/licenses/Kojoi-license.txt @@ -278,7 +276,7 @@ return console.askOkCancel(message, true); ${installer:sys.installationDir}/bin/kojo - Koco Learning Environment + Kojo Learning Environment context.getBooleanVariable("createDesktopLinkAction") @@ -633,5 +631,4 @@ return console.askYesNo(message, true); - diff --git a/installer.i4j/kojo.install4j_lalit b/installer.i4j/kojo.install4j_lalit deleted file mode 100644 index 898fafc04..000000000 --- a/installer.i4j/kojo.install4j_lalit +++ /dev/null @@ -1,634 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /home/lalit/work/kojo/installer/icons/kojo16.png - - - - - /home/lalit/work/kojo/installer/icons/kojo32.png - - - - - /home/lalit/work/kojo/installer/icons/kojo48.png - - - - - /home/lalit/work/kojo/installer/icons/kojo64.png - - - - - /home/lalit/work/kojo/installer/icons/kojo128.png - - - - - - - - - - - - - - - - - - - - - - - - - - - sys.installationDir - - - context.getBooleanVariable("sys.confirmedUpdateInstallation") - - - - - - ${form:welcomeMessage} - - !context.isConsole() - - - - - - String message = context.getMessage("ConsoleWelcomeLabel", context.getApplicationName()); -return console.askOkCancel(message, true); - - - - - - - - updateCheck - - - - - ${i18n:ClickNext} - - - - - - - - - ${i18n:LicenseLabel3} - - - - - - - - en - - /home/lalit/work/kojo/installerbuild/licenses/Kojoi-license.txt - - - - - - - - textSource - displayedText - displayedTextFile - variableName - acceptInitiallySelected - readAllRequired - - - - - - !context.getBooleanVariable("sys.confirmedUpdateInstallation") - - - - - sys.installationDir - - - context.getVariable("sys.responseFile") == null - - - - - - ${i18n:SelectDirLabel(${compiler:sys.fullName})} - - - - - - - - suggestAppDir - validateApplicationId - existingDirWarning - checkWritable - manualEntryAllowed - checkFreeSpace - showRequiredDiskSpace - showFreeDiskSpace - allowSpacesOnUnix - validationScript - standardValidation - - - - - - - - - ${i18n:SelectComponentsLabel2} - - !context.isConsole() - - - - - - - selectionChangedScript - - - - - - - - - ${form:confirmationMessage} - - !context.isConsole() - - - - ${i18n:CreateDesktopIcon} - - createDesktopLinkAction - - - - - - - - - - - - - Development - Kojo - Uninstall ${compiler:sys.fullName} - - !context.getBooleanVariable("sys.programGroupDisabled") - - - - - - - ${installer:sys.installationDir}/bin/kojo - - - Kojo Learning Environment - - context.getBooleanVariable("createDesktopLinkAction") - - - - - - ${i18n:WizardPreparing} - - - - - - - - - 239 - - context.getBooleanVariable("executeLauncherAction") && (!context.isUnattended()) - - - - - - ${form:finishedMessage} - - - - - ${i18n:RunEntryExec("${compiler:sys.fullName}")} - - executeLauncherAction - - - - - - - - - ${i18n:UninstallerMenuEntry(${compiler:sys.fullName})} - - - - - - - - - - - - - - - - ${form:welcomeMessage} - - !context.isConsole() - - - - - - String message = context.getMessage("ConfirmUninstall", context.getApplicationName()); -return console.askYesNo(message, true); - - - - - - - - - - - - - - - ${i18n:UninstallerPreparing} - - - - - - - - - - ${form:successMessage} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From f9b7f9e839430eb8a511383672079986cc4b10bb Mon Sep 17 00:00:00 2001 From: Ben Bulent Basaran Date: Thu, 3 Aug 2023 10:53:54 -0400 Subject: [PATCH 05/23] prog lesson in turkish using duvar-tenisi sample from the scala tutorial --- .../samples/tr/kojo-kilavuz/duvar-tenisi.kojo | 6 +-- .../tr/kojo-kilavuz/duvar-tenisi0.kojo | 32 +++++++++++++++ .../tr/kojo-kilavuz/duvar-tenisi2.kojo | 39 +++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi0.kojo create mode 100644 src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi2.kojo diff --git a/src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi.kojo b/src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi.kojo index 4607fa48e..71bc8dce7 100644 --- a/src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi.kojo +++ b/src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi.kojo @@ -1,7 +1,7 @@ silVeSakla() -çiz(götür(-200, -100) -> Resim.düz(0, 200)) // Üç duvar çizelim. Bu dik ön duvar -çiz(götür(-200, -100) -> Resim.düz(400, 0)) // Bu alt duvar -çiz(götür(-200, 100) -> Resim.düz(400, 0)) // Bu da üst duvar +çiz(götür(-200, -100) -> Resim.dikey(200)) // Üç duvar çizelim. Bu dik ön duvar +çiz(götür(-200, -100) -> Resim.yatay(400)) // Bu alt duvar +çiz(götür(-200, 100) -> Resim.yatay(400)) // Bu da üst duvar dez rb = 80 // raketin boyu dez raket = kalemRengi(mavi) -> Resim.düz(0, rb) dez top = kalemRengi(mavi) -> Resim.daire(5) diff --git a/src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi0.kojo b/src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi0.kojo new file mode 100644 index 000000000..5565fc7d5 --- /dev/null +++ b/src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi0.kojo @@ -0,0 +1,32 @@ +silVeSakla() +çiz(götür(-200, -100) -> Resim.dikey(200)) // Üç duvar çizelim. Bu dik ön duvar +çiz(götür(-200, -100) -> Resim.yatay(400)) // Bu alt duvar +çiz(götür(-200, 100) -> Resim.yatay(400)) // Bu da üst duvar +dez rb = 80 // raketin boyu +dez raket = kalemRengi(mavi) -> Resim.düz(0, rb) +dez top = kalemRengi(mavi) -> Resim.daire(5) +dez skor = kalemRengi(siyah) * götür(-50, 150) -> Resim.yazı("Raketi fareyle yönet") +çiz(raket, top, skor) +den x = 0.0; den y = 0 // topun konumu +den dy = 8; den dx = -8.0 // topun hızı: d delta yani değişim ya da derivative yani türev demek +den rx = 0.0; den ry = 0.0 // raketin konumu +den ıska = 0 // top kaç kere kaçtı, saymak için +den vuruş = 0 // kaç kere raketle vurduğumuzu da sayalım +canlandır { + raket.kondur(fareKonumu) // raketi fareyle kontrol ediyoruz + top.kondur(x, y) // topun yerini değiştirelim + // top rakete çarpıyor mu? + rx = fareKonumu.x; ry = fareKonumu.y + dx = eğer ((dx > 0) && (mutlakDeğer(rx - x) < 10) && + (y > ry) && (y < ry + rb)) {vuruş += 1; -1.1*dx} yoksa dx + // topun konumunu güncelleyelim, duvarlara bakalım + dx = eğer (x + dx < -200) -dx yoksa dx // ön duvardan sekti mi? + dy = eğer ((y + dy < -100) || (y + dy > 100)) -dy yoksa dy // üst ve alt duvarlardan sekti mi? + eğer (x + dx > 200) { x = -200; dx = 8; ıska += 1 } // ıskaladı + x += dx; y += dy // topun gideceği noktayı hesaplayalım + eğer (ıska > 0 || vuruş > 0) { // skoru güncelleyelim + dez mesaj = eğer (vuruş == 0) "Fareyi tuvale getir!" yoksa s"$vuruş kere vurdun" + skor.güncelle(s"$mesaj\n$ıska kere ıskaladın") + } +} +oyunSüresiniGeriyeSayarakGöster(60, "Süre bitti", yeşil) // oyun 60 saniye sürsün diff --git a/src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi2.kojo b/src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi2.kojo new file mode 100644 index 000000000..0269fcfb1 --- /dev/null +++ b/src/main/resources/samples/tr/kojo-kilavuz/duvar-tenisi2.kojo @@ -0,0 +1,39 @@ +silVeSakla() +nesne duvar { dez (x, yAlt, yÜst) = (-200, -100, 100) } // karşı duvarın koordinatları +dez uzunluk = 400 // yan duvarların uzunluğu +çiz(götür(duvar.x, duvar.yAlt) -> Resim.dikey(duvar.yÜst - duvar.yAlt)) // Bu karşı duvar +çiz(götür(duvar.x, duvar.yAlt) -> Resim.yatay(uzunluk)) // Bu alt duvar +çiz(götür(duvar.x, duvar.yÜst) -> Resim.yatay(uzunluk)) // Bu da üst duvar +dez rb = 80 // raketin boyu +dez raket = kalemRengi(mavi) -> Resim.düz(0, rb) +dez top = kalemRengi(mavi) -> Resim.daire(5) +dez skor = kalemRengi(siyah) * götür(-50, duvar.yÜst + 50) -> Resim.yazı("Raketi fareyle yönet") +çiz(raket, top, skor) +den x = 0.0; den y = 0 // topun konumu +den dy = 8; den dx = -8.0 // topun hızı: d delta yani değişim ya da derivative yani türev demek +den rx = 0.0; den ry = 0.0 // raketin konumu +den ıska = 0 // top kaç kere kaçtı, saymak için +den vuruş = 0 // kaç kere raketle vurduğumuzu da sayalım +raket.kondur(fareKonumu) // raketi fareyle kontrol ediyoruz +canlandır { + rx = fareKonumu.x; ry = fareKonumu.y + rx = eğer (rx > duvar.x + 50) rx yoksa duvar.x + 50 // ama çok yaklaşmasın duvara! + rx = eğer (rx < duvar.x + uzunluk) rx yoksa duvar.x + uzunluk // ve çok uzaklaşmasın + ry = eğer (duvar.yAlt < ry) ry yoksa duvar.yAlt // çok aşağıya ve çok yukarıya da gitmesin + ry = eğer (ry < duvar.yÜst - rb) ry yoksa duvar.yÜst - rb + raket.kondur(rx, ry) + top.kondur(x, y) // topun yerini belirleyelim ya da değiştirelim + // top rakete çarpıyor mu? + dx = eğer ((dx > 0) && (mutlakDeğer(rx - x) < 10) && + (y > ry) && (y < ry + rb)) {vuruş += 1; -1.1*dx} yoksa dx + // topun konumunu güncelleyelim, duvarlara bakalım + dx = eğer (x + dx < duvar.x) -dx yoksa dx // ön duvardan sekti mi? + dy = eğer ((y + dy < duvar.yAlt) || (y + dy > duvar.yÜst)) -dy yoksa dy // üst ve alt duvarlardan sekti mi? + eğer (x + dx > duvar.x + uzunluk) { x = duvar.x; dx = 8; ıska += 1 } // ıskaladı + x += dx; y += dy // topun gideceği noktayı hesaplayalım + eğer (ıska > 0 || vuruş > 0) { // skoru güncelleyelim + dez mesaj = eğer (vuruş == 0) "Fareyi tuvale getir!" yoksa s"$vuruş kere vurdun" + skor.güncelle(s"$mesaj\n$ıska kere ıskaladın") + } +} +oyunSüresiniGeriyeSayarakGöster(60, "Süre bitti", yeşil) // oyun 60 saniye sürsün \ No newline at end of file From fecbb199e98db570f0feb9de9da97f66487c4685 Mon Sep 17 00:00:00 2001 From: Ben Bulent Basaran Date: Sun, 13 Aug 2023 13:12:10 -0400 Subject: [PATCH 06/23] Update release name: 2.9.25-tr-2023-08-a (done in August) --- installer.i4j/koco.install4j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer.i4j/koco.install4j b/installer.i4j/koco.install4j index a4d45370c..5892b6e8a 100644 --- a/installer.i4j/koco.install4j +++ b/installer.i4j/koco.install4j @@ -1,7 +1,7 @@ - + From 4fa3a64edc002382882f50730b2650d9ea92bef9 Mon Sep 17 00:00:00 2001 From: Lalit Pant Date: Tue, 12 Aug 2025 13:58:47 +0530 Subject: [PATCH 07/23] Initial support for running on Java 21. --- build.sbt | 2 +- installer.i4j/kojo.install4j | 7 ++----- installer/jarlist.txt | 6 +++--- src/main/scala/net/kogics/kojo/lite/StubMain.scala | 4 ++-- src/main/scala/net/kogics/kojo/lite/Versions.scala | 4 ++-- .../scala/net/kogics/kojo/xscala/CompilerAndRunner.scala | 9 +++------ 6 files changed, 13 insertions(+), 19 deletions(-) diff --git a/build.sbt b/build.sbt index c04bbe975..75b960e9a 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,4 @@ -lazy val scalaVer = "2.13.6" +lazy val scalaVer = "2.13.16" name := "Kojo" version := "2.9" scalaVersion := scalaVer diff --git a/installer.i4j/kojo.install4j b/installer.i4j/kojo.install4j index b3ffa223c..bf5180983 100644 --- a/installer.i4j/kojo.install4j +++ b/installer.i4j/kojo.install4j @@ -1,12 +1,12 @@ - + - + @@ -626,9 +626,6 @@ return console.askYesNo(message, true); - - - diff --git a/installer/jarlist.txt b/installer/jarlist.txt index 2fa45d7af..6afc8a987 100644 --- a/installer/jarlist.txt +++ b/installer/jarlist.txt @@ -15,7 +15,7 @@ ../dist/jssc.jar ../dist/flatlaf-3.4.jar -> flatlaf.jar ../dist/libtiled.jar -../dist/scala-reflect-2.13.6.jar -> scala-reflect.jar +../dist/scala-reflect-2.13.16.jar -> scala-reflect.jar ../dist/akka-actor_2.13-2.6.16.jar -> akka-actors.jar ../dist/scala-swing_2.13-2.1.1.jar -> scala-swing.jar ../dist/scala-xml_2.13-1.2.0.jar -> scala-xml.jar @@ -26,8 +26,8 @@ ../dist/h2-1.3.168.jar -> h2.jar ../dist/scalatest_2.13-3.0.8.jar -> scalatest.jar ../dist/scalactic_2.13-3.0.8.jar -> scalactic.jar -../dist/scala-library-2.13.6.jar -> scala-library.jar -../dist/scala-compiler-2.13.6.jar -> scala-compiler.jar +../dist/scala-library-2.13.16.jar -> scala-library.jar +../dist/scala-compiler-2.13.16.jar -> scala-compiler.jar ../dist/config-1.4.0.jar -> config.jar ../dist/scala-java8-compat_2.13-1.0.0.jar -> scala-java8-compat.jar ../dist/activation-1.1.jar -> activation.jar diff --git a/src/main/scala/net/kogics/kojo/lite/StubMain.scala b/src/main/scala/net/kogics/kojo/lite/StubMain.scala index 23c87273e..72cddd5fb 100644 --- a/src/main/scala/net/kogics/kojo/lite/StubMain.scala +++ b/src/main/scala/net/kogics/kojo/lite/StubMain.scala @@ -112,14 +112,14 @@ trait StubMain { } def noScaling = - "-Dsun.java2d.uiScale.enabled=false" + "-Dsun.java2d.uiScale=1.0" val javaVersionSpecificArgs = { if (Utils.isJava8) { s"$maybeMarlin $cmsGC".trim } else { - s"$reflectiveAccess $noScaling" + s"$reflectiveAccess" } } diff --git a/src/main/scala/net/kogics/kojo/lite/Versions.scala b/src/main/scala/net/kogics/kojo/lite/Versions.scala index 952fe59a6..552a0ce32 100644 --- a/src/main/scala/net/kogics/kojo/lite/Versions.scala +++ b/src/main/scala/net/kogics/kojo/lite/Versions.scala @@ -2,8 +2,8 @@ package net.kogics.kojo.lite object Versions { val KojoMajorVersion = "2.9" - val KojoVersion = "2.9.32" - val KojoRevision = "r3" + val KojoVersion = "2.9.33" + val KojoRevision = "r1" val KojoBuildDate = "12 August 2025" val JavaVersion = { val jrv = System.getProperty("java.runtime.version") diff --git a/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala b/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala index d2238af63..0e9181db0 100644 --- a/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala +++ b/src/main/scala/net/kogics/kojo/xscala/CompilerAndRunner.scala @@ -565,10 +565,10 @@ class CompilerAndRunner( completions.foreach { completion => try { completion match { - case pcompiler.TypeMember(sym, tpe, true, inherited, viaView) + case pcompiler.TypeMember(sym, tpe, true, inherited, viaView, _) if !sym.isConstructor /*&& nameMatches(sym)*/ => elb += pcompiler.mkCompletionProposal(sym, tpe, inherited, viaView) - case pcompiler.ScopeMember(sym, tpe, true, _) if !sym.isConstructor /*&& nameMatches(sym)*/ => + case pcompiler.ScopeMember(sym, tpe, true, _, _) if !sym.isConstructor /*&& nameMatches(sym)*/ => elb += pcompiler.mkCompletionProposal(sym, tpe, false, pcompiler.NoSymbol) case _ => } @@ -649,14 +649,11 @@ class CompilerAndRunner( "--add-opens java.base/java.lang=ALL-UNNAMED" } - def noScaling = - "-Dsun.java2d.uiScale.enabled=false" - val javaVersionSpecificArgs = { if (isJava8) cmsGC else - s"$reflectiveAccess $noScaling" + s"$reflectiveAccess" } val cmdArgs = s"-client -Xms128m -Xmx$maxMem -Xss1m $javaVersionSpecificArgs ${extraArgs}Launcher" From e994292bc6c79d033d63de0b3b09cce6e5e0198c Mon Sep 17 00:00:00 2001 From: Lalit Pant Date: Tue, 12 Aug 2025 19:26:33 +0530 Subject: [PATCH 08/23] Some experiments. --- installer.i4j/kojo.install4j | 4 ++-- src/main/scala/net/kogics/kojo/lite/StubMain.scala | 7 +++++-- src/main/scala/net/kogics/kojo/lite/Versions.scala | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/installer.i4j/kojo.install4j b/installer.i4j/kojo.install4j index bf5180983..627e2473e 100644 --- a/installer.i4j/kojo.install4j +++ b/installer.i4j/kojo.install4j @@ -1,7 +1,7 @@ - + @@ -626,6 +626,6 @@ return console.askYesNo(message, true); - + diff --git a/src/main/scala/net/kogics/kojo/lite/StubMain.scala b/src/main/scala/net/kogics/kojo/lite/StubMain.scala index 72cddd5fb..cd8eca1a0 100644 --- a/src/main/scala/net/kogics/kojo/lite/StubMain.scala +++ b/src/main/scala/net/kogics/kojo/lite/StubMain.scala @@ -112,14 +112,17 @@ trait StubMain { } def noScaling = - "-Dsun.java2d.uiScale=1.0" + "-Dsun.java2d.uiScale.enabled=false" val javaVersionSpecificArgs = { if (Utils.isJava8) { s"$maybeMarlin $cmsGC".trim } else { - s"$reflectiveAccess" + if (Utils.isWin) + s"$reflectiveAccess" + else + s"$reflectiveAccess $noScaling" } } diff --git a/src/main/scala/net/kogics/kojo/lite/Versions.scala b/src/main/scala/net/kogics/kojo/lite/Versions.scala index 552a0ce32..f1133652a 100644 --- a/src/main/scala/net/kogics/kojo/lite/Versions.scala +++ b/src/main/scala/net/kogics/kojo/lite/Versions.scala @@ -3,7 +3,7 @@ package net.kogics.kojo.lite object Versions { val KojoMajorVersion = "2.9" val KojoVersion = "2.9.33" - val KojoRevision = "r1" + val KojoRevision = "r2" val KojoBuildDate = "12 August 2025" val JavaVersion = { val jrv = System.getProperty("java.runtime.version") From 41f6ac1fe0da6f3185876bd78a515895e5195f32 Mon Sep 17 00:00:00 2001 From: Lalit Pant Date: Wed, 13 Aug 2025 10:05:53 +0530 Subject: [PATCH 09/23] Warm up compiler after it initializes. The first run for users gets faster, and this takes care of a potential issue with the compiler (post 2.13.6) -- if the first compile results in a compiler error, the compiler gets messed up after that. --- src/main/scala/net/kogics/kojo/xscala/ScalaCodeRunner2.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/scala/net/kogics/kojo/xscala/ScalaCodeRunner2.scala b/src/main/scala/net/kogics/kojo/xscala/ScalaCodeRunner2.scala index a818482a9..297874dc0 100644 --- a/src/main/scala/net/kogics/kojo/xscala/ScalaCodeRunner2.scala +++ b/src/main/scala/net/kogics/kojo/xscala/ScalaCodeRunner2.scala @@ -598,6 +598,8 @@ class ScalaCodeRunner2(val runContext: RunContext, val defaultMode: CodingMode) compilerAndRunner = new CompilerAndRunner(makeSettings, compilerInitCode, new CompilerOutputHandler(runContext), runContext) actorState.compilerAndRunner = compilerAndRunner + // warm up the compiler + compile("9") } def initInterp(): Unit = { From b7e233277191179d1ab416b0e573c775d0117b85 Mon Sep 17 00:00:00 2001 From: Lalit Pant Date: Thu, 14 Aug 2025 18:38:23 +0530 Subject: [PATCH 10/23] Revert "Some experiments." This reverts commit e994292bc6c79d033d63de0b3b09cce6e5e0198c. --- src/main/scala/net/kogics/kojo/lite/StubMain.scala | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/scala/net/kogics/kojo/lite/StubMain.scala b/src/main/scala/net/kogics/kojo/lite/StubMain.scala index cd8eca1a0..72cddd5fb 100644 --- a/src/main/scala/net/kogics/kojo/lite/StubMain.scala +++ b/src/main/scala/net/kogics/kojo/lite/StubMain.scala @@ -112,17 +112,14 @@ trait StubMain { } def noScaling = - "-Dsun.java2d.uiScale.enabled=false" + "-Dsun.java2d.uiScale=1.0" val javaVersionSpecificArgs = { if (Utils.isJava8) { s"$maybeMarlin $cmsGC".trim } else { - if (Utils.isWin) - s"$reflectiveAccess" - else - s"$reflectiveAccess $noScaling" + s"$reflectiveAccess" } } From b4de7497e22a0d52b5902fda2ae0527169af69a0 Mon Sep 17 00:00:00 2001 From: Lalit Pant Date: Thu, 14 Aug 2025 18:41:01 +0530 Subject: [PATCH 11/23] Bump up revision number. --- src/main/scala/net/kogics/kojo/lite/Versions.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/net/kogics/kojo/lite/Versions.scala b/src/main/scala/net/kogics/kojo/lite/Versions.scala index f1133652a..0f7032ea6 100644 --- a/src/main/scala/net/kogics/kojo/lite/Versions.scala +++ b/src/main/scala/net/kogics/kojo/lite/Versions.scala @@ -3,8 +3,8 @@ package net.kogics.kojo.lite object Versions { val KojoMajorVersion = "2.9" val KojoVersion = "2.9.33" - val KojoRevision = "r2" - val KojoBuildDate = "12 August 2025" + val KojoRevision = "r3" + val KojoBuildDate = "14 August 2025" val JavaVersion = { val jrv = System.getProperty("java.runtime.version") val arch = System.getProperty("os.arch") From 40e348b91f01d9f373b1d9e236085aff237fbbd4 Mon Sep 17 00:00:00 2001 From: Lalit Pant Date: Thu, 14 Aug 2025 18:46:54 +0530 Subject: [PATCH 12/23] Tweak installer. --- installer.i4j/kojo.install4j | 3 +++ 1 file changed, 3 insertions(+) diff --git a/installer.i4j/kojo.install4j b/installer.i4j/kojo.install4j index 627e2473e..97fa69e6a 100644 --- a/installer.i4j/kojo.install4j +++ b/installer.i4j/kojo.install4j @@ -626,6 +626,9 @@ return console.askYesNo(message, true); + + + From 003eb7ec110efdfaeda5dee383f6da2ec56f1e33 Mon Sep 17 00:00:00 2001 From: Ben Bulent Basaran Date: Wed, 8 Oct 2025 12:29:45 -0400 Subject: [PATCH 13/23] fix merge problems --- .scalafmt.conf | 58 ++++++- .../net/kogics/kojo/lite/Bundle.properties | 3 + .../resources/samples/fireworks-canvas.kojo | 148 +++++++++++++++++ src/main/resources/samples/fireworks.kojo | 155 ++++++++++++++++++ .../scala/net/kogics/kojo/lite/AppMenu.scala | 12 +- 5 files changed, 372 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/samples/fireworks-canvas.kojo create mode 100644 src/main/resources/samples/fireworks.kojo diff --git a/.scalafmt.conf b/.scalafmt.conf index 834f2d20f..5086294f1 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1 +1,57 @@ -version = 2.7.5 \ No newline at end of file +# Based on https://github.com/playframework/playframework/blob/main/.scalafmt.conf + +# Version https://scalameta.org/scalafmt/docs/configuration.html#version +version = 3.7.1 +# Dialect https://scalameta.org/scalafmt/docs/configuration.html#scala-dialects +runner.dialect = scala213 + +# Top-level preset https://scalameta.org/scalafmt/docs/configuration.html#top-level-presets +preset = default + +# Common https://scalameta.org/scalafmt/docs/configuration.html#most-popular +maxColumn = 120 +assumeStandardLibraryStripMargin = true + +# Alignment https://scalameta.org/scalafmt/docs/configuration.html#alignment +align { + preset = some + allowOverflow = true +} + +# Newlines https://scalameta.org/scalafmt/docs/configuration.html#newlines +newlines { + alwaysBeforeElseAfterCurlyIf = true + alwaysBeforeMultilineDef = false + implicitParamListModifierPrefer = before + beforeCurlyLambdaParams = multilineWithCaseOnly + inInterpolation = "avoid" +} + +# Spaces https://scalameta.org/scalafmt/docs/configuration.html#spaces +spaces { + inImportCurlyBraces = true # more idiomatic to include whitepsace in import x.{ yyy => zzz } +} + +# Project https://scalameta.org/scalafmt/docs/configuration.html#project +# project { +# git = true +# excludePaths = ["glob:**/core/play/src/main/scala/play/core/hidden/ObjectMappings.scala"] +# } + +# Rewrite Rules https://scalameta.org/scalafmt/docs/configuration.html#rewrite-rules +rewrite { + rules = [ + AvoidInfix, # https://scalameta.org/scalafmt/docs/configuration.html#avoidinfix + RedundantParens, # https://scalameta.org/scalafmt/docs/configuration.html#redundantparens + SortModifiers, # https://scalameta.org/scalafmt/docs/configuration.html#sortmodifiers + PreferCurlyFors, # https://scalameta.org/scalafmt/docs/configuration.html#prefercurlyfors + Imports, # https://scalameta.org/scalafmt/docs/configuration.html#imports + ] + sortModifiers.order = ["private", "protected", "final", "sealed", "abstract", "implicit", "override", "lazy"] + imports { + expand = true + sort = original + groups = [["java(x)?\\..*"], ["scala\\..*"], ["sbt\\..*"]] + } + trailingCommas.style = keep # https://scalameta.org/scalafmt/docs/configuration.html#trailing-commas +} diff --git a/src/main/resources/net/kogics/kojo/lite/Bundle.properties b/src/main/resources/net/kogics/kojo/lite/Bundle.properties index 6065f213c..9549cdc7f 100644 --- a/src/main/resources/net/kogics/kojo/lite/Bundle.properties +++ b/src/main/resources/net/kogics/kojo/lite/Bundle.properties @@ -62,6 +62,9 @@ S_TangramSkier=Tangram Skier S_LunarLander=Lunar Lander S_PulsatingLamp=Pulsating Lamp S_PulsatingLamp2=Pulsating Lamp 2 +S_DynamicSquare=Dynamic Square +S_Fireworks=Fireworks +S_Fireworks2=Fireworks 2 S_CrazySquare=Crazy Square S_Hunted=Hunted S_Pong=Pong diff --git a/src/main/resources/samples/fireworks-canvas.kojo b/src/main/resources/samples/fireworks-canvas.kojo new file mode 100644 index 000000000..7853c063a --- /dev/null +++ b/src/main/resources/samples/fireworks-canvas.kojo @@ -0,0 +1,148 @@ +cleari() +originBottomLeft() + +setNoteInstrument(Instrument.ACOUSTIC_BASS) +playNote(50, 150) +playNote(45, 200) + +val cb = canvasBounds +val gravity = Vector2D(0, -0.1) + +class Particle(x0: Double, y0: Double, hu: Double, seed: Boolean) { + var location = Vector2D(x0, y0) + private var velocity = + if (seed) Vector2D(0, random(5, 12)) + else randomExplosionVector + private var acceleration = Vector2D(0, 0) + private var lifespan = 255.0 + private var exploded = false + + private val pic = Picture.circle(0.5) + + def randomExplosionVector: Vector2D = { + val rv1 = Vector2D(randomNormalDouble, randomNormalDouble) + val r1 = randomDouble(2, 4) + rv1 * r1 + } + + def applyForce(force: Vector2D) { + acceleration += force + } + + def shouldExplode: Boolean = !exploded && lifespan <= 0 + + def checkExplode() { + if (seed && velocity.y < 0) { + lifespan = 0 + } + } + + def isDead: Boolean = { + if (seed) exploded else lifespan <= 0 + } + + def explode() { + // note, duration, volume + playNote(15, 30, 127) + exploded = true + } + + def step() { + velocity += acceleration + location += velocity + if (!seed) { + lifespan -= 5 + velocity *= 0.95 + } + acceleration *= 0 + checkExplode() + } + + def view(canvas: CanvasDraw) { + canvas.stroke(cm.hsla(hu, 1, 0.5, lifespan / 255)) + if (seed) { + canvas.strokeWeight(4) + } + else { + canvas.strokeWeight(2) + } + canvas.point(location.x, location.y) + } +} + +class Firework() { + private val hu = random(360) + private val firework = new Particle(random(cwidth), 0, hu, true) + private val particles = ArrayBuffer.empty[Particle] + + def done: Boolean = { + if (firework.isDead & particles.isEmpty) true else false + } + + def step() { + particles.filterInPlace(p => !p.isDead) + + if (!firework.isDead) { + firework.applyForce(gravity) + firework.step() + + if (firework.shouldExplode) { + repeat(100) { + particles.append( + new Particle(firework.location.x, firework.location.y, hu, false) + ) + } + firework.explode() + } + } + + repeatFor(particles) { p => + p.applyForce(gravity) + p.step() + } + } + + def view(canvas: CanvasDraw) { + firework.view(canvas) + repeatFor(particles) { p => + p.view(canvas) + } + } + + def dead: Boolean = { + if (particles.isEmpty) true else false + } +} + +val fireworks = ArrayBuffer.empty[Firework] + +def updateState() { + fireworks.filterInPlace(f => !f.done) + if (randomDouble(1) < 0.08) { + fireworks.append(new Firework()) + } + repeatFor(fireworks) { f => + f.step() + } +} + +def viewState(canvas: CanvasDraw) { + canvas.fill(0, 0, 0, 30) + canvas.noStroke() + canvas.rect(0, 0, cwidth, cheight) + // canvas.background(black) + repeatFor(fireworks) { f => + f.view(canvas) + } +} + +animateWithCanvasDraw { canvas => + updateState() + viewState(canvas) +} + +// Inspired by +// https://github.com/CodingTrain/Coding-Challenges/tree/main/027_FireWorks/Processing/CC_027_FireWorks_2D + +// For more details, check out: +// https://github.com/litan/kojo-examples/tree/main/fireworks diff --git a/src/main/resources/samples/fireworks.kojo b/src/main/resources/samples/fireworks.kojo new file mode 100644 index 000000000..bf55b1044 --- /dev/null +++ b/src/main/resources/samples/fireworks.kojo @@ -0,0 +1,155 @@ +cleari() +originBottomLeft() +setBackground(black) + +setNoteInstrument(Instrument.ACOUSTIC_BASS) +playNote(50, 150) +playNote(45, 200) + +val cb = canvasBounds +val gravity = Vector2D(0, -0.1) + +class Particle(x0: Double, y0: Double, hu: Double, seed: Boolean) { + var location = Vector2D(x0, y0) + private var velocity = + if (seed) Vector2D(0, random(5, 12)) + else randomExplosionVector + private var acceleration = Vector2D(0, 0) + private var lifespan = 255.0 + private var exploded = false + + private val pic = Picture.circle(1) + + def randomExplosionVector: Vector2D = { + val rv1 = Vector2D(randomNormalDouble, randomNormalDouble) + val r1 = randomDouble(2, 4) + rv1 * r1 + } + + def applyForce(force: Vector2D) { + acceleration += force + } + + def shouldExplode: Boolean = !exploded && lifespan <= 0 + + def checkExplode() { + if (seed && velocity.y < 0) { + lifespan = 0 + } + } + + def isDead: Boolean = { + if (seed) exploded else lifespan <= 0 + } + + def explode() { + // note, duration, volume + playNote(15, 30, 127) + exploded = true + } + + def step() { + velocity += acceleration + location += velocity + if (!seed) { + lifespan -= 5 + velocity *= 0.95 + } + acceleration *= 0 + checkExplode() + } + + def view() { + if (isDead) { + pic.erase() + } + else if (pic.isDrawn) { + val clr = cm.hsla(hu, 1, 0.5, lifespan / 255) + pic.setPenColor(clr) + pic.setFillColor(clr) + if (seed) { + pic.setPenThickness(3) + } + else { + pic.setPenThickness(2) + } + pic.setPosition(location.x, location.y) + } + else { + pic.draw() + } + } +} + +class Firework() { + private val hu = random(360) + private val firework = new Particle(random(cwidth), 0, hu, true) + private val particles = ArrayBuffer.empty[Particle] + + def done: Boolean = { + if (firework.isDead & particles.isEmpty) true else false + } + + def step() { + particles.filterInPlace(p => !p.isDead) + + if (!firework.isDead) { + firework.applyForce(gravity) + firework.step() + + if (firework.shouldExplode) { + repeat(100) { + particles.append( + new Particle(firework.location.x, firework.location.y, hu, false) + ) + } + firework.explode() + } + } + + repeatFor(particles) { p => + p.applyForce(gravity) + p.step() + } + } + + def view() { + firework.view() + repeatFor(particles) { p => + p.view() + } + } + + def dead: Boolean = { + if (particles.isEmpty) true else false + } +} + +val fireworks = ArrayBuffer.empty[Firework] + +def updateState() { + fireworks.filterInPlace(f => !f.done) + if (randomDouble(1) < 0.08) { + fireworks.append(new Firework()) + } + repeatFor(fireworks) { f => + f.step() + } +} + +def viewState() { + repeatFor(fireworks) { f => + f.view() + } +} + +animate { + updateState() + viewState() +} + +// Inspired by +// https://github.com/CodingTrain/Coding-Challenges/tree/main/027_FireWorks/Processing/CC_027_FireWorks_2D + +// For more details, check out: +// https://github.com/litan/kojo-examples/tree/main/fireworks diff --git a/src/main/scala/net/kogics/kojo/lite/AppMenu.scala b/src/main/scala/net/kogics/kojo/lite/AppMenu.scala index 55ea8a328..dab6d8a4c 100644 --- a/src/main/scala/net/kogics/kojo/lite/AppMenu.scala +++ b/src/main/scala/net/kogics/kojo/lite/AppMenu.scala @@ -14,14 +14,16 @@ */ package net.kogics.kojo.lite -import java.awt.{Component, Dimension, Insets} import java.awt.event.ActionEvent import java.awt.event.ActionListener - +import java.awt.Component +import java.awt.Dimension +import java.awt.Insets import javax.swing._ import javax.swing.event.PopupMenuEvent import javax.swing.event.PopupMenuListener import javax.swing.text.html.HTMLEditorKit + import net.kogics.kojo.action.CloseFile import net.kogics.kojo.action.LoadFrom import net.kogics.kojo.action.NewFile @@ -148,7 +150,7 @@ trait AppMenu { val item = new JMenuItem(label) item.addActionListener(new ActionListener { def actionPerformed(ev: ActionEvent): Unit = { - //loadAndRunResource(root + file) + // loadAndRunResource(root + file) loadAndRunLocalizedResource(root, file) } }) @@ -255,6 +257,9 @@ trait AppMenu { animGameMenu.add(menuItemFor("S_LunarLander", "lunar-lander.kojo")) animGameMenu.add(menuItemFor("S_PulsatingLamp", "lamp-animation.kojo")) animGameMenu.add(menuItemFor("S_PulsatingLamp2", "lamp-animation2.kojo")) + animGameMenu.add(menuItemFor("S_DynamicSquare", "animated-square-creation.kojo")) + animGameMenu.add(menuItemFor("S_Fireworks", "fireworks-canvas.kojo")) + animGameMenu.add(menuItemFor("S_Fireworks2", "fireworks.kojo")) animGameMenu.add(menuItemFor("S_TangramSkier", "tangram-skier.kojo")) animGameMenu.add(menuItemFor("S_Pong", "pong.kojo")) animGameMenu.add(menuItemFor("S_MemoryCards", "memory-cards.kojo")) @@ -322,6 +327,7 @@ trait AppMenu { showcaseMenu.add(menuItemFor("S_Mandel", "mandelbrot.kojo")) showcaseMenu.add(menuItemFor("S_Mondrian", "genart-mondrian.kojo")) showcaseMenu.add(menuItemFor("S_Delaunay", "genart-delaunay.kojo")) + showcaseMenu.add(menuItemFor("S_Fireworks", "fireworks-canvas.kojo")) showcaseMenu.add(menuItemFor("S_Collidium", "collidium.kojo")) showcaseMenu.add(menuItemFor("S_CarRide", "car-ride.kojo")) showcaseMenu.add(menuItemForInstalledFile("S_Platformer", "examples/tiledgame/game.kojo")) From 2a9ddd243421652d9db0b0f336aaa73f20772447 Mon Sep 17 00:00:00 2001 From: Ben Bulent Basaran Date: Sat, 11 Oct 2025 17:03:30 -0400 Subject: [PATCH 14/23] minor updates to samples in turkish --- src/main/resources/samples/tr/fireworks-canvas.kojo | 2 +- src/main/resources/samples/tr/fireworks.kojo | 2 +- src/main/resources/samples/tr/mandelbrot.kojo | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/samples/tr/fireworks-canvas.kojo b/src/main/resources/samples/tr/fireworks-canvas.kojo index c9468aad4..97ce747f5 100644 --- a/src/main/resources/samples/tr/fireworks-canvas.kojo +++ b/src/main/resources/samples/tr/fireworks-canvas.kojo @@ -120,5 +120,5 @@ canlandırTuvalÇizimle { tuval => // Esin kaynağı: // https://github.com/CodingTrain/Coding-Challenges/tree/main/027_FireWorks/Processing/CC_027_FireWorks_2D -// Ayrıntılı detay için: +// Ayrıntılı bilgiler: // https://github.com/litan/kojo-examples/tree/main/fireworks diff --git a/src/main/resources/samples/tr/fireworks.kojo b/src/main/resources/samples/tr/fireworks.kojo index 65c4d269a..3dd05d30f 100644 --- a/src/main/resources/samples/tr/fireworks.kojo +++ b/src/main/resources/samples/tr/fireworks.kojo @@ -127,5 +127,5 @@ canlandır { // Esin kaynağı: // https://github.com/CodingTrain/Coding-Challenges/tree/main/027_FireWorks/Processing/CC_027_FireWorks_2D -// Ayrıntılı detay için: +// Ayrıntılı bilgiler: // https://github.com/litan/kojo-examples/tree/main/fireworks diff --git a/src/main/resources/samples/tr/mandelbrot.kojo b/src/main/resources/samples/tr/mandelbrot.kojo index 0d21f38a0..fb4b27323 100644 --- a/src/main/resources/samples/tr/mandelbrot.kojo +++ b/src/main/resources/samples/tr/mandelbrot.kojo @@ -36,8 +36,8 @@ /* çizim çok yavaşsa, örneğin beş on saniyeden çok sürüyorsa * buradaki değişmez değerleri küçültmeyi dene */ -dez kenar = 400 // kümemizin resmi k x k büyüklüğünde bir kare -dez yinelemeSınırı = 2000 // bu da resmin çözünürlüğünü artırıyor +dez kenar = 500 // kümemizin resmi k x k büyüklüğünde bir kare +dez yinelemeSınırı = 3000 // bu da resmin çözünürlüğünü artırıyor //tümEkran() /* From ae2eab0730bbe9e5b74770b5933c3915b1ab5cc1 Mon Sep 17 00:00:00 2001 From: Lalit Pant Date: Sun, 30 Nov 2025 14:50:08 +0530 Subject: [PATCH 15/23] Work related to better support for hi-res monitors. --- build.sbt | 2 +- installer.i4j/kojo.install4j | 4 ++-- installer/jarlist.txt | 6 +++--- src/main/scala/net/kogics/kojo/lite/AppMenu.scala | 3 ++- src/main/scala/net/kogics/kojo/lite/Main.scala | 13 +++---------- .../scala/net/kogics/kojo/lite/OutputPane.scala | 6 +----- .../scala/net/kogics/kojo/lite/ScriptEditor.scala | 5 +++++ src/main/scala/net/kogics/kojo/lite/StubMain.scala | 6 ++++++ src/main/scala/net/kogics/kojo/lite/Versions.scala | 4 ++-- 9 files changed, 25 insertions(+), 24 deletions(-) diff --git a/build.sbt b/build.sbt index 75b960e9a..572bf6a6b 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,4 @@ -lazy val scalaVer = "2.13.16" +lazy val scalaVer = "2.13.18" name := "Kojo" version := "2.9" scalaVersion := scalaVer diff --git a/installer.i4j/kojo.install4j b/installer.i4j/kojo.install4j index 97fa69e6a..b06cb82ae 100644 --- a/installer.i4j/kojo.install4j +++ b/installer.i4j/kojo.install4j @@ -1,12 +1,12 @@ - + - + diff --git a/installer/jarlist.txt b/installer/jarlist.txt index 6afc8a987..0fcb93d42 100644 --- a/installer/jarlist.txt +++ b/installer/jarlist.txt @@ -15,7 +15,7 @@ ../dist/jssc.jar ../dist/flatlaf-3.4.jar -> flatlaf.jar ../dist/libtiled.jar -../dist/scala-reflect-2.13.16.jar -> scala-reflect.jar +../dist/scala-reflect-2.13.18.jar -> scala-reflect.jar ../dist/akka-actor_2.13-2.6.16.jar -> akka-actors.jar ../dist/scala-swing_2.13-2.1.1.jar -> scala-swing.jar ../dist/scala-xml_2.13-1.2.0.jar -> scala-xml.jar @@ -26,8 +26,8 @@ ../dist/h2-1.3.168.jar -> h2.jar ../dist/scalatest_2.13-3.0.8.jar -> scalatest.jar ../dist/scalactic_2.13-3.0.8.jar -> scalactic.jar -../dist/scala-library-2.13.16.jar -> scala-library.jar -../dist/scala-compiler-2.13.16.jar -> scala-compiler.jar +../dist/scala-library-2.13.18.jar -> scala-library.jar +../dist/scala-compiler-2.13.18.jar -> scala-compiler.jar ../dist/config-1.4.0.jar -> config.jar ../dist/scala-java8-compat_2.13-1.0.0.jar -> scala-java8-compat.jar ../dist/activation-1.1.jar -> activation.jar diff --git a/src/main/scala/net/kogics/kojo/lite/AppMenu.scala b/src/main/scala/net/kogics/kojo/lite/AppMenu.scala index dab6d8a4c..d34f34f81 100644 --- a/src/main/scala/net/kogics/kojo/lite/AppMenu.scala +++ b/src/main/scala/net/kogics/kojo/lite/AppMenu.scala @@ -455,8 +455,9 @@ trait AppMenu { val aboutText = new JEditorPane aboutText.setEditorKit(new HTMLEditorKit) aboutText.setEditable(false) + val fsz = aboutText.getFont.getSize aboutText.setText(s""" -
+
Kojo ${Versions.KojoMajorVersion}
Version: ${Versions.KojoVersion} ${Versions.KojoRevision}
Build date: ${Versions.KojoBuildDate}
diff --git a/src/main/scala/net/kogics/kojo/lite/Main.scala b/src/main/scala/net/kogics/kojo/lite/Main.scala index 7c839a561..c72fbdeb5 100644 --- a/src/main/scala/net/kogics/kojo/lite/Main.scala +++ b/src/main/scala/net/kogics/kojo/lite/Main.scala @@ -63,10 +63,9 @@ object Main extends AppMenu with ScriptLoader { main => System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tc, %3$s] %4$s: %5$s%6$s%n") // app name needs to be set right in the beginning (this applies to Mac; is ignored elsewhere) System.setProperty("apple.awt.application.name", "Kojo") - kojoCtx = - new KojoCtx( - args.length == 1 && args(0) == "subKojo" - ) // context needs to be created right up front to set user language + kojoCtx = new KojoCtx( + args.length == 1 && args(0) == "subKojo" + ) // context needs to be created right up front to set user language if (Utils.isMac) { try { new MacTweaks().tweak(frame) @@ -87,7 +86,6 @@ object Main extends AppMenu with ScriptLoader { main => } Utils.schedule(0.3) { - updateDefaultFonts(12 + kojoCtx.screenDpiFontDelta) Theme.currentTheme.loadLookAndFeel() kojoCtx.lookAndFeelReady() @@ -226,9 +224,4 @@ object Main extends AppMenu with ScriptLoader { main => def runMultiInstancehandler(): Unit = { MultiInstanceManager.run() } - - private def updateDefaultFonts(size: Int): Unit = { - // not needed with FlatLAF - } - } diff --git a/src/main/scala/net/kogics/kojo/lite/OutputPane.scala b/src/main/scala/net/kogics/kojo/lite/OutputPane.scala index f06cdf3c2..bb48413b8 100644 --- a/src/main/scala/net/kogics/kojo/lite/OutputPane.scala +++ b/src/main/scala/net/kogics/kojo/lite/OutputPane.scala @@ -287,11 +287,7 @@ class OutputPane(execSupport: CodeExecutionSupport) extends JPanel { }
- val fontSize = - if (kojoCtx.screenDpiFontDelta > 0) - "large" - else - "large" + val fontSize = "large" val bg = Theme.currentTheme.errorPaneBg val errMsg = diff --git a/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala b/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala index 0dfef09b0..be90546e8 100644 --- a/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala +++ b/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala @@ -103,6 +103,11 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends codePanes.foreach(_.setCodeFoldingEnabled(true)) codePanes.foreach(Theme.currentTheme.loadEditorTheme.apply(_)) + codePanes.foreach { cp => + val oldf = cp.getFont + val f = oldf.deriveFont(getFont.getSize.toFloat) + cp.setFont(f) + } val inputMap = codePane.getInputMap val inputMap2 = codePane2.getInputMap diff --git a/src/main/scala/net/kogics/kojo/lite/StubMain.scala b/src/main/scala/net/kogics/kojo/lite/StubMain.scala index 72cddd5fb..392a0147a 100644 --- a/src/main/scala/net/kogics/kojo/lite/StubMain.scala +++ b/src/main/scala/net/kogics/kojo/lite/StubMain.scala @@ -155,10 +155,16 @@ trait StubMain { } } + val jvmDevOpts = Utils.appProperty("jvm.dev.opts") match { + case Some(opts) => opts.concat(" ") + case None => "" + } + val cmdArgs = s"-client -Xms128m -Xmx$maxMem " + "-Xss1m " + s"$javaVersionSpecificArgs " + extraArgs + + jvmDevOpts + s"net.kogics.kojo.lite.Main ${kojoArgs.mkString(" ")}" val command = diff --git a/src/main/scala/net/kogics/kojo/lite/Versions.scala b/src/main/scala/net/kogics/kojo/lite/Versions.scala index 0f7032ea6..4b2fe98ab 100644 --- a/src/main/scala/net/kogics/kojo/lite/Versions.scala +++ b/src/main/scala/net/kogics/kojo/lite/Versions.scala @@ -3,8 +3,8 @@ package net.kogics.kojo.lite object Versions { val KojoMajorVersion = "2.9" val KojoVersion = "2.9.33" - val KojoRevision = "r3" - val KojoBuildDate = "14 August 2025" + val KojoRevision = "r5" + val KojoBuildDate = "30 Nov 2025" val JavaVersion = { val jrv = System.getProperty("java.runtime.version") val arch = System.getProperty("os.arch") From 26ae7912f62a30c466592b18a13c1af2f0087624 Mon Sep 17 00:00:00 2001 From: Lalit Pant Date: Sun, 30 Nov 2025 15:14:11 +0530 Subject: [PATCH 16/23] Don't bump up Script Editor font size by extra amount, just let the system bump it up. --- src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala | 2 +- src/main/scala/net/kogics/kojo/lite/Versions.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala b/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala index be90546e8..c374cf435 100644 --- a/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala +++ b/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala @@ -126,7 +126,7 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends } } Utils.safeProcessSilent { - for (i <- 1 to 3 + kojoCtx.screenDpiFontDelta) { increaseFontSizeAction.actionPerformed(null) } + for (i <- 1 to kojoCtx.screenDpiFontDelta) { increaseFontSizeAction.actionPerformed(null) } } RSyntaxTextArea.setTemplatesEnabled(true) diff --git a/src/main/scala/net/kogics/kojo/lite/Versions.scala b/src/main/scala/net/kogics/kojo/lite/Versions.scala index 4b2fe98ab..aeca83537 100644 --- a/src/main/scala/net/kogics/kojo/lite/Versions.scala +++ b/src/main/scala/net/kogics/kojo/lite/Versions.scala @@ -3,7 +3,7 @@ package net.kogics.kojo.lite object Versions { val KojoMajorVersion = "2.9" val KojoVersion = "2.9.33" - val KojoRevision = "r5" + val KojoRevision = "r6" val KojoBuildDate = "30 Nov 2025" val JavaVersion = { val jrv = System.getProperty("java.runtime.version") From bd405871ddae8fc4f3ab8864cd9c07c12344e2ea Mon Sep 17 00:00:00 2001 From: Lalit Pant Date: Mon, 1 Dec 2025 15:19:43 +0530 Subject: [PATCH 17/23] Allow FlatLAF to scale toolbar icons. --- .../net/kogics/kojo/lite/ScriptEditor.scala | 8 ++++-- .../scala/net/kogics/kojo/lite/Versions.scala | 4 +-- .../scala/net/kogics/kojo/util/Utils.scala | 25 +++++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala b/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala index c374cf435..ffab574b8 100644 --- a/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala +++ b/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala @@ -1,5 +1,7 @@ package net.kogics.kojo.lite +import com.formdev.flatlaf.util.UIScale + import java.awt.event.ActionEvent import java.awt.event.ActionListener import java.awt.event.FocusAdapter @@ -675,7 +677,7 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends button.setActionCommand(actionCommand) button.setToolTipText(toolTipText) button.addActionListener(actionListener) - button.setIcon(Utils.loadIcon(imageFile)) + Utils.setupScaledButtonIcon(button, imageFile) // button.setMnemonic(KeyEvent.VK_ENTER) button.setBorderPainted(false) button @@ -690,7 +692,9 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends case n if n < 6 => 24 case _ => 36 } - toolbar.setPreferredSize(new Dimension(0, imageFolder + imageFolder / 6)) + val scale = UIScale.getUserScaleFactor + val tsz = ((imageFolder + imageFolder / 6) * scale).toInt + toolbar.setPreferredSize(new Dimension(0, tsz)) import Theme.currentTheme.checkPng import Theme.currentTheme.clearOwPng diff --git a/src/main/scala/net/kogics/kojo/lite/Versions.scala b/src/main/scala/net/kogics/kojo/lite/Versions.scala index aeca83537..93a03a5c2 100644 --- a/src/main/scala/net/kogics/kojo/lite/Versions.scala +++ b/src/main/scala/net/kogics/kojo/lite/Versions.scala @@ -3,8 +3,8 @@ package net.kogics.kojo.lite object Versions { val KojoMajorVersion = "2.9" val KojoVersion = "2.9.33" - val KojoRevision = "r6" - val KojoBuildDate = "30 Nov 2025" + val KojoRevision = "r7" + val KojoBuildDate = "1 Dec 2025" val JavaVersion = { val jrv = System.getProperty("java.runtime.version") val arch = System.getProperty("os.arch") diff --git a/src/main/scala/net/kogics/kojo/util/Utils.scala b/src/main/scala/net/kogics/kojo/util/Utils.scala index c2891ac17..414a857c9 100644 --- a/src/main/scala/net/kogics/kojo/util/Utils.scala +++ b/src/main/scala/net/kogics/kojo/util/Utils.scala @@ -50,15 +50,18 @@ import java.util.ResourceBundle import javax.imageio.ImageIO import javax.swing.text.JTextComponent import javax.swing.ImageIcon +import javax.swing.JButton import javax.swing.JComponent import javax.swing.JDialog import javax.swing.KeyStroke import javax.swing.Timer +import javax.swing.UIManager import scala.collection.mutable import scala.collection.mutable.HashMap import akka.actor.ActorSystem +import com.formdev.flatlaf.util.ScaledImageIcon import edu.umd.cs.piccolo.event.PInputEvent import net.kogics.kojo.core.CodingMode import net.kogics.kojo.core.KojoCtx @@ -128,6 +131,28 @@ object Utils { iconCache.getOrElseUpdate(fname, loadIcon(fname)) } + def setupScaledButtonIcon(button: JButton, imagePath: String): Unit = { + // 1. Base icon (your old non-scaled one) + val baseIcon = loadIcon(imagePath) + + // 2. Scaled icon for normal state + val scaledIcon = new ScaledImageIcon(baseIcon) + button.setIcon(scaledIcon) + + // 3. Ask LAF to create a disabled version *from the base ImageIcon* + val disabled = UIManager.getLookAndFeel.getDisabledIcon(button, baseIcon) + + // 4. If we got one, wrap it too + if (disabled != null) { + val disabledScaled = + disabled match { + case img: ImageIcon => new ScaledImageIcon(img) + case other => other // fallback – in case LAF returns a non-ImageIcon + } + button.setDisabledIcon(disabledScaled) + } + } + def loadResource(res: String): String = { readStream(getClass.getResourceAsStream(res)) } From 9bc5f952bc35399239366ac259e83c148a759a42 Mon Sep 17 00:00:00 2001 From: Lalit Pant Date: Wed, 3 Dec 2025 14:08:42 +0530 Subject: [PATCH 18/23] UI scaling refinements. --- .../scala/net/kogics/kojo/lite/ScriptEditor.scala | 2 +- src/main/scala/net/kogics/kojo/lite/StubMain.scala | 12 +++++++++++- src/main/scala/net/kogics/kojo/lite/Versions.scala | 4 ++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala b/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala index ffab574b8..dcb871497 100644 --- a/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala +++ b/src/main/scala/net/kogics/kojo/lite/ScriptEditor.scala @@ -128,7 +128,7 @@ class ScriptEditor(val execSupport: CodeExecutionSupport, frame: JFrame) extends } } Utils.safeProcessSilent { - for (i <- 1 to kojoCtx.screenDpiFontDelta) { increaseFontSizeAction.actionPerformed(null) } + for (i <- 1 to 2) { increaseFontSizeAction.actionPerformed(null) } } RSyntaxTextArea.setTemplatesEnabled(true) diff --git a/src/main/scala/net/kogics/kojo/lite/StubMain.scala b/src/main/scala/net/kogics/kojo/lite/StubMain.scala index 392a0147a..710050146 100644 --- a/src/main/scala/net/kogics/kojo/lite/StubMain.scala +++ b/src/main/scala/net/kogics/kojo/lite/StubMain.scala @@ -157,7 +157,17 @@ trait StubMain { val jvmDevOpts = Utils.appProperty("jvm.dev.opts") match { case Some(opts) => opts.concat(" ") - case None => "" + case None => + var ret = "" + if (Utils.isWin) { + import com.formdev.flatlaf.util.UIScale + val gc = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment.getDefaultScreenDevice.getDefaultConfiguration + val systemScaleFactor = UIScale.getSystemScaleFactor(gc) + if (systemScaleFactor > 1 && systemScaleFactor < 2) { + ret = s"-Dsun.java2d.uiScale=1 -Dflatlaf.uiScale=$systemScaleFactor " + } + } + ret } val cmdArgs = s"-client -Xms128m -Xmx$maxMem " + diff --git a/src/main/scala/net/kogics/kojo/lite/Versions.scala b/src/main/scala/net/kogics/kojo/lite/Versions.scala index 93a03a5c2..2b3efb5b2 100644 --- a/src/main/scala/net/kogics/kojo/lite/Versions.scala +++ b/src/main/scala/net/kogics/kojo/lite/Versions.scala @@ -3,8 +3,8 @@ package net.kogics.kojo.lite object Versions { val KojoMajorVersion = "2.9" val KojoVersion = "2.9.33" - val KojoRevision = "r7" - val KojoBuildDate = "1 Dec 2025" + val KojoRevision = "r8" + val KojoBuildDate = "3 Dec 2025" val JavaVersion = { val jrv = System.getProperty("java.runtime.version") val arch = System.getProperty("os.arch") From 8273f2cbb60dbc34f645587a05e08ea253f6192d Mon Sep 17 00:00:00 2001 From: Lalit Pant Date: Fri, 5 Dec 2025 01:26:40 +0530 Subject: [PATCH 19/23] Tweaks --- src/main/scala/net/kogics/kojo/lite/KojoCtx.scala | 4 ++-- src/main/scala/net/kogics/kojo/lite/StubMain.scala | 2 +- src/main/scala/net/kogics/kojo/lite/Versions.scala | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/scala/net/kogics/kojo/lite/KojoCtx.scala b/src/main/scala/net/kogics/kojo/lite/KojoCtx.scala index 64dab95fb..a0ee8291a 100644 --- a/src/main/scala/net/kogics/kojo/lite/KojoCtx.scala +++ b/src/main/scala/net/kogics/kojo/lite/KojoCtx.scala @@ -81,8 +81,8 @@ class KojoCtx(val subKojo: Boolean) extends core.KojoCtx { case n if n <= 1920 => 2 case n if n <= 2560 => 4 case n if n <= 2880 => 6 - case n if n <= 3840 => 6 - case _ => 6 + case n if n <= 3840 => 8 + case _ => 8 } val delta = Utils.appProperty("font.increase") match { case Some(d) => d.toInt + delta1 diff --git a/src/main/scala/net/kogics/kojo/lite/StubMain.scala b/src/main/scala/net/kogics/kojo/lite/StubMain.scala index 710050146..f79169615 100644 --- a/src/main/scala/net/kogics/kojo/lite/StubMain.scala +++ b/src/main/scala/net/kogics/kojo/lite/StubMain.scala @@ -163,7 +163,7 @@ trait StubMain { import com.formdev.flatlaf.util.UIScale val gc = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment.getDefaultScreenDevice.getDefaultConfiguration val systemScaleFactor = UIScale.getSystemScaleFactor(gc) - if (systemScaleFactor > 1 && systemScaleFactor < 2) { + if (systemScaleFactor > 1.0 && systemScaleFactor < 1.7) { ret = s"-Dsun.java2d.uiScale=1 -Dflatlaf.uiScale=$systemScaleFactor " } } diff --git a/src/main/scala/net/kogics/kojo/lite/Versions.scala b/src/main/scala/net/kogics/kojo/lite/Versions.scala index 2b3efb5b2..278dd6369 100644 --- a/src/main/scala/net/kogics/kojo/lite/Versions.scala +++ b/src/main/scala/net/kogics/kojo/lite/Versions.scala @@ -3,8 +3,8 @@ package net.kogics.kojo.lite object Versions { val KojoMajorVersion = "2.9" val KojoVersion = "2.9.33" - val KojoRevision = "r8" - val KojoBuildDate = "3 Dec 2025" + val KojoRevision = "r9" + val KojoBuildDate = "4 Dec 2025" val JavaVersion = { val jrv = System.getProperty("java.runtime.version") val arch = System.getProperty("os.arch") From 6322398902bcdbb810a8e91487792780ebd3c905 Mon Sep 17 00:00:00 2001 From: Lalit Pant Date: Fri, 2 Jan 2026 09:26:35 +0530 Subject: [PATCH 20/23] Fix "$ in method name" triggered issue after Scala upgrade, for the case where code-completion is triggered without any prefix text. --- .../kojo/lite/KojoCompletionProvider.scala | 32 ++++++++++++++--- .../scala/net/kogics/kojo/lite/Versions.scala | 6 ++-- .../lite/KojoCompletionProviderTest.scala | 36 +++++++++++++++++++ 3 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 src/test/scala/net/kogics/kojo/lite/KojoCompletionProviderTest.scala diff --git a/src/main/scala/net/kogics/kojo/lite/KojoCompletionProvider.scala b/src/main/scala/net/kogics/kojo/lite/KojoCompletionProvider.scala index 4be41cbd2..64cd20a5e 100644 --- a/src/main/scala/net/kogics/kojo/lite/KojoCompletionProvider.scala +++ b/src/main/scala/net/kogics/kojo/lite/KojoCompletionProvider.scala @@ -31,9 +31,31 @@ class KojoCompletionProvider(execSupport: CodeExecutionSupport) extends Completi setListCellRenderer(new CompletionCellRenderer) // needed for icons to show up setAutoActivationRules(false, null) - def rtsaTemplate(t: String) = { - val res = if (t.contains("${")) t else "%s${cursor}".format(t) - res + def rstaTemplate(t: String): String = { + if (t == null) return null + + val sb = new StringBuilder(t.length) + var sawInterpolation = false + + var i = 0 + while (i < t.length) { + val ch = t.charAt(i) + if (ch == '$') { + val nextIsBrace = (i + 1 < t.length) && t.charAt(i + 1) == '{' + if (nextIsBrace) { + sawInterpolation = true + sb.append('$') // keep '$' as-is for "${...}" + } else { + sb.append("$$") // escape plain '$' + } + } else { + sb.append(ch) + } + i += 1 + } + + val escaped = sb.toString + if (sawInterpolation) escaped else escaped + "${cursor}" } def proposal(offset: Int, completion: String, kind: Int, template: String) = { @@ -41,7 +63,7 @@ class KojoCompletionProvider(execSupport: CodeExecutionSupport) extends Completi this, completion, completion, - rtsaTemplate(if (template == null) completion else template), + rstaTemplate(if (template == null) completion else template), null, Help(completion) ) { @@ -143,7 +165,7 @@ class KojoCompletionProvider(execSupport: CodeExecutionSupport) extends Completi def help = knownHelp.getOrElse(completion.fullCompletion) - new TemplateCompletion(this, display, display, rtsaTemplate(template), null, help) { + new TemplateCompletion(this, display, display, rstaTemplate(template), null, help) { setRelevance(-completion.prio) override def getIcon = kindIcon(kind) } diff --git a/src/main/scala/net/kogics/kojo/lite/Versions.scala b/src/main/scala/net/kogics/kojo/lite/Versions.scala index 278dd6369..4c8ce46cd 100644 --- a/src/main/scala/net/kogics/kojo/lite/Versions.scala +++ b/src/main/scala/net/kogics/kojo/lite/Versions.scala @@ -2,9 +2,9 @@ package net.kogics.kojo.lite object Versions { val KojoMajorVersion = "2.9" - val KojoVersion = "2.9.33" - val KojoRevision = "r9" - val KojoBuildDate = "4 Dec 2025" + val KojoVersion = "2.9.34" + val KojoRevision = "r1" + val KojoBuildDate = "2 Jan 2025" val JavaVersion = { val jrv = System.getProperty("java.runtime.version") val arch = System.getProperty("os.arch") diff --git a/src/test/scala/net/kogics/kojo/lite/KojoCompletionProviderTest.scala b/src/test/scala/net/kogics/kojo/lite/KojoCompletionProviderTest.scala new file mode 100644 index 000000000..e825bd0e3 --- /dev/null +++ b/src/test/scala/net/kogics/kojo/lite/KojoCompletionProviderTest.scala @@ -0,0 +1,36 @@ +package net.kogics.kojo.lite + +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner +import org.scalatest.{FunSuite, Matchers} + +@RunWith(classOf[JUnitRunner]) +class KojoCompletionProviderTest extends FunSuite with Matchers { + + // Option B: shared instance for the whole suite + private lazy val provider = new KojoCompletionProvider(null) + + test("rstaTemplate escapes $ not followed by { and appends ${cursor} when no interpolation is present") { + provider.rstaTemplate("$conforms") shouldBe "$$conforms${cursor}" + } + + test("rstaTemplate does not append ${cursor} when an interpolation ${...} is already present") { + provider.rstaTemplate("forward(${n})") shouldBe "forward(${n})" + } + + test("rstaTemplate escapes plain $ but preserves $ that starts a ${...} interpolation") { + provider.rstaTemplate("$forward(${n})") shouldBe "$$forward(${n})" + } + + test("rstaTemplate escapes plain $ but preserves $ that starts a ${...} interpolation, #2") { + provider.rstaTemplate("for$ard(${n})") shouldBe "for$$ard(${n})" + } + + test("rstaTemplate doubles a trailing $ and appends ${cursor} when no interpolation is present") { + provider.rstaTemplate("$") shouldBe "$$${cursor}" + } + + test("rstaTemplate leaves non-$ strings unchanged except for appending ${cursor}") { + provider.rstaTemplate("clear") shouldBe "clear${cursor}" + } +} From afd53a3c77a3d8ee2221dc2fa2dfa3f5fde6a16f Mon Sep 17 00:00:00 2001 From: Lalit Pant Date: Fri, 2 Jan 2026 17:09:01 +0530 Subject: [PATCH 21/23] Reduce compiler warning that show up after Scala upgrade. --- src/main/scala/net/kogics/kojo/kmath/rational.scala | 8 ++++---- src/main/scala/net/kogics/kojo/lite/Builtins.scala | 12 +++++++----- .../net/kogics/kojo/lite/CodeExecutionSupport.scala | 4 ++-- src/main/scala/net/kogics/kojo/lite/Versions.scala | 2 +- .../net/kogics/kojo/lite/canvas/SpriteCanvas.scala | 2 +- .../net/kogics/kojo/lite/trace/TracingBuiltins.scala | 2 +- src/main/scala/net/kogics/kojo/picture/package.scala | 2 +- src/main/scala/net/kogics/kojo/staging/staging.scala | 10 +++++----- src/main/scala/net/kogics/kojo/util/RichFile.scala | 2 +- .../scala/net/kogics/kojo/util/ScalatestHelper.scala | 4 ++-- src/main/scala/net/kogics/kojo/xscala/Help.scala | 2 +- .../net/kogics/kojo/picture/ArcDoubleAngleTest.scala | 2 +- .../net/kogics/kojo/picture/PictureBounceTest.scala | 2 +- .../kogics/kojo/picture/PictureClosenessTest.scala | 2 +- .../kogics/kojo/picture/PictureCollisionTest.scala | 2 +- .../kogics/kojo/picture/PictureEqualsHashTest.scala | 2 +- .../scala/net/kogics/kojo/picture/PictureTest.scala | 2 +- 17 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/main/scala/net/kogics/kojo/kmath/rational.scala b/src/main/scala/net/kogics/kojo/kmath/rational.scala index f69aa4bad..a5512919f 100644 --- a/src/main/scala/net/kogics/kojo/kmath/rational.scala +++ b/src/main/scala/net/kogics/kojo/kmath/rational.scala @@ -9,13 +9,13 @@ import org.apache.commons.math3.fraction.BigFraction import org.apache.commons.math3.fraction.BigFractionFormat trait Rationals { - implicit def itor(n: Int) = Rational(new BigFraction(n)) - implicit def ltor(n: Long) = Rational(new BigFraction(n)) - implicit def dtor(n: Double) = { + implicit def itor(n: Int): Rational = Rational(new BigFraction(n)) + implicit def ltor(n: Long): Rational = Rational(new BigFraction(n)) + implicit def dtor(n: Double): Rational = { val ret = Rational(new BigFraction(n, 1e-9, Int.MaxValue)) if (n != 0 && ret == 0) Rational(new BigFraction(n)) else ret } - implicit def ftor(n: Float) = Rational(new BigFraction(n)) + implicit def ftor(n: Float): Rational = Rational(new BigFraction(n)) implicit class RationalMaker(val sc: StringContext) { val bff = new BigFractionFormat diff --git a/src/main/scala/net/kogics/kojo/lite/Builtins.scala b/src/main/scala/net/kogics/kojo/lite/Builtins.scala index 282205091..bcf6cf7a4 100644 --- a/src/main/scala/net/kogics/kojo/lite/Builtins.scala +++ b/src/main/scala/net/kogics/kojo/lite/Builtins.scala @@ -32,6 +32,7 @@ import scala.language.implicitConversions import com.jhlabs.image.AbstractBufferedImageOp import com.jhlabs.image.LightFilter.Light import net.kogics.kojo.core.Rich2DPath +import net.kogics.kojo.core.SCanvas import net.kogics.kojo.core.VertexShape import net.kogics.kojo.core.Voice import net.kogics.kojo.kmath.KEasing @@ -242,10 +243,10 @@ class Builtins( "Adds an input field with the supplied label and default value to the Story Teller Window." ) - implicit val StringRead = util.Read.StringRead - implicit val DoubleRead = util.Read.DoubleRead - implicit val IntRead = util.Read.IntRead import util.Read + implicit val StringRead: Read.StringRead.type = Read.StringRead + implicit val DoubleRead: Read.DoubleRead.type = Read.DoubleRead + implicit val IntRead: Read.IntRead.type = Read.IntRead def stFieldValue[T](label: String, default: T)(implicit reader: Read[T]): T = { storyTeller.fieldValue(label, default) @@ -529,7 +530,7 @@ Here's a partial list of the available commands: def withFillColor(pic: Picture, color: Color) = pic.withFillColor(color) def withPenColor(pic: Picture, color: Color) = pic.withPenColor(color) - implicit val _picCanvas = tCanvas + implicit val _picCanvas: SCanvas = tCanvas def pict(painter: Painter) = picture.Pic(painter) def PictureT(painter: Painter) = picture.Pic(painter) def Picture(fn: => Unit) = picture.Pic0 { t => @@ -1124,7 +1125,7 @@ Here's a partial list of the available commands: def rangeTo(start: Double, end: Double, step: Double) = Range.BigDecimal.inclusive(start, end, step) def rangeTill(start: Double, end: Double, step: Double) = Range.BigDecimal(start, end, step) - implicit def bd2double(bd: BigDecimal) = bd.doubleValue + implicit def bd2double(bd: BigDecimal): Double = bd.doubleValue type CanvasDraw = net.kogics.kojo.lite.CanvasDraw import scala.language.reflectiveCalls @@ -1207,6 +1208,7 @@ Here's a partial list of the available commands: def animateWithRedraw[S](initState: S, nextState: S => S, stateView: S => Picture): Unit = { import edu.umd.cs.piccolo.activities.PActivity + import java.util.concurrent.Future val initPic = stateView(initState) initPic.draw() diff --git a/src/main/scala/net/kogics/kojo/lite/CodeExecutionSupport.scala b/src/main/scala/net/kogics/kojo/lite/CodeExecutionSupport.scala index dd11bb1a5..af068c197 100644 --- a/src/main/scala/net/kogics/kojo/lite/CodeExecutionSupport.scala +++ b/src/main/scala/net/kogics/kojo/lite/CodeExecutionSupport.scala @@ -541,11 +541,11 @@ class CodeExecutionSupport( def setActivityListener(): Unit = { kojoCtx.setActivityListener(new core.AbstractSpriteListener { def interpreterDone = runButton.isEnabled - override def hasPendingCommands: Unit = { + override def hasPendingCommands(): Unit = { pendingCommands = true stopButton.setEnabled(true) } - override def pendingCommandsDone: Unit = { + override def pendingCommandsDone(): Unit = { pendingCommands = false if (interpreterDone && Utils.noMonitoredThreads) stopButton.setEnabled(false) } diff --git a/src/main/scala/net/kogics/kojo/lite/Versions.scala b/src/main/scala/net/kogics/kojo/lite/Versions.scala index 4c8ce46cd..b5bb2cd35 100644 --- a/src/main/scala/net/kogics/kojo/lite/Versions.scala +++ b/src/main/scala/net/kogics/kojo/lite/Versions.scala @@ -3,7 +3,7 @@ package net.kogics.kojo.lite object Versions { val KojoMajorVersion = "2.9" val KojoVersion = "2.9.34" - val KojoRevision = "r1" + val KojoRevision = "r2" val KojoBuildDate = "2 Jan 2025" val JavaVersion = { val jrv = System.getProperty("java.runtime.version") diff --git a/src/main/scala/net/kogics/kojo/lite/canvas/SpriteCanvas.scala b/src/main/scala/net/kogics/kojo/lite/canvas/SpriteCanvas.scala index bdbf24a6e..5386e7eb5 100644 --- a/src/main/scala/net/kogics/kojo/lite/canvas/SpriteCanvas.scala +++ b/src/main/scala/net/kogics/kojo/lite/canvas/SpriteCanvas.scala @@ -126,7 +126,7 @@ class SpriteCanvas(val kojoCtx: core.KojoCtx) extends PSwingCanvas with SCanvas @volatile var turtle = newTurtle() val pictures = origLayer // getCamera.addLayer(getCamera.getLayerCount - 1, pictures) - implicit val picCanvas = this + implicit val picCanvas: SpriteCanvas = this def turtle0 = turtle val figure0 = figure diff --git a/src/main/scala/net/kogics/kojo/lite/trace/TracingBuiltins.scala b/src/main/scala/net/kogics/kojo/lite/trace/TracingBuiltins.scala index 2408117bf..2975b12ee 100644 --- a/src/main/scala/net/kogics/kojo/lite/trace/TracingBuiltins.scala +++ b/src/main/scala/net/kogics/kojo/lite/trace/TracingBuiltins.scala @@ -86,7 +86,7 @@ object TracingBuiltins extends CoreBuiltins with RepeatCommands { def TexturePaint(file: String, x: Double, y: Double) = Color(247, 247, 247) - implicit val picCanvas = TSCanvas + implicit val picCanvas: TracingTSCanvas = TSCanvas def Picture(fn: => Unit) = new picture.Pic(t => fn) def PictureT(fn: Turtle => Unit) = new picture.Pic(fn) def picStack(pics: Picture*) = new GPics(pics.toList) diff --git a/src/main/scala/net/kogics/kojo/picture/package.scala b/src/main/scala/net/kogics/kojo/picture/package.scala index e43dd31a1..611f93699 100644 --- a/src/main/scala/net/kogics/kojo/picture/package.scala +++ b/src/main/scala/net/kogics/kojo/picture/package.scala @@ -189,7 +189,7 @@ package object picture { new Java2DPic(w * scaleOutFactor, h * scaleOutFactor, fn) { override def draw(): Unit = { super.draw() - scale(1 / scaleOutFactor) + this.scale(1 / scaleOutFactor) canvas.animate { update() if (stopCheck) { diff --git a/src/main/scala/net/kogics/kojo/staging/staging.scala b/src/main/scala/net/kogics/kojo/staging/staging.scala index 68cde57e2..6e984a014 100644 --- a/src/main/scala/net/kogics/kojo/staging/staging.scala +++ b/src/main/scala/net/kogics/kojo/staging/staging.scala @@ -92,10 +92,10 @@ class API(canvas: SpriteCanvas) { // T PointTest begins def point(x: Double, y: Double) = Point(x, y) - implicit def tupleDDToPoint(tuple: (Double, Double)) = Point(tuple._1, tuple._2) - implicit def tupleDIToPoint(tuple: (Double, Int)) = Point(tuple._1, tuple._2) - implicit def tupleIDToPoint(tuple: (Int, Double)) = Point(tuple._1, tuple._2) - implicit def tupleIIToPoint(tuple: (Int, Int)) = Point(tuple._1, tuple._2) + implicit def tupleDDToPoint(tuple: (Double, Double)): Point = Point(tuple._1, tuple._2) + implicit def tupleDIToPoint(tuple: (Double, Int)): Point = Point(tuple._1, tuple._2) + implicit def tupleIDToPoint(tuple: (Int, Double)): Point = Point(tuple._1, tuple._2) + implicit def tupleIIToPoint(tuple: (Int, Int)): Point = Point(tuple._1, tuple._2) // implicit def baseShapeToPoint(b: BaseShape) = b.origin // implicit def awtPointToPoint(p: java.awt.geom.Point2D) = Point(p.getX, p.getY) // implicit def awtDimToPoint(d: java.awt.geom.Dimension2D) = Point(d.getWidth, d.getHeight) @@ -311,7 +311,7 @@ class API(canvas: SpriteCanvas) { def withStyle(fc: Paint, sc: Paint, sw: Double)(body: => Unit) = Style(fc, sc, sw)(body) - implicit def ColorToRichColor(c: java.awt.Color) = RichColor(c) + implicit def ColorToRichColor(c: java.awt.Color): RichColor = RichColor(c) def lerpColor(from: RichColor, to: RichColor, amt: Double) = RichColor.lerpColor(from, to, amt) // T ColorTest ends diff --git a/src/main/scala/net/kogics/kojo/util/RichFile.scala b/src/main/scala/net/kogics/kojo/util/RichFile.scala index f3b730f45..40a48cfde 100644 --- a/src/main/scala/net/kogics/kojo/util/RichFile.scala +++ b/src/main/scala/net/kogics/kojo/util/RichFile.scala @@ -18,7 +18,7 @@ import java.io._ object RichFile { import language.implicitConversions - implicit def enrichFile(f: File) = new RichFile(f) + implicit def enrichFile(f: File): RichFile = new RichFile(f) } class RichFile(f: File) { diff --git a/src/main/scala/net/kogics/kojo/util/ScalatestHelper.scala b/src/main/scala/net/kogics/kojo/util/ScalatestHelper.scala index 9c5e22ee8..50989433e 100644 --- a/src/main/scala/net/kogics/kojo/util/ScalatestHelper.scala +++ b/src/main/scala/net/kogics/kojo/util/ScalatestHelper.scala @@ -6,8 +6,8 @@ object ScalatestHelper { class TestRun extends FunSuite { override def suiteName = "test-run" - def register(name: String)(fn: => Unit) = test(name)(fn) - def registerIgnored(name: String)(fn: => Unit) = ignore(name)(fn) + def register(name: String)(fn: => Unit) = this.test(name)(fn) + def registerIgnored(name: String)(fn: => Unit) = this.ignore(name)(fn) } def test(name: String)(fn: => Unit): Unit = { diff --git a/src/main/scala/net/kogics/kojo/xscala/Help.scala b/src/main/scala/net/kogics/kojo/xscala/Help.scala index a16563de6..a01687645 100644 --- a/src/main/scala/net/kogics/kojo/xscala/Help.scala +++ b/src/main/scala/net/kogics/kojo/xscala/Help.scala @@ -22,7 +22,7 @@ import language.implicitConversions object Help { - implicit def elem2str(e: xml.Elem) = e.toString + implicit def elem2str(e: xml.Elem): String = e.toString def summaryFooter =
Some Background
diff --git a/src/test/scala/net/kogics/kojo/picture/ArcDoubleAngleTest.scala b/src/test/scala/net/kogics/kojo/picture/ArcDoubleAngleTest.scala index f21eb1127..8442f9bf4 100644 --- a/src/test/scala/net/kogics/kojo/picture/ArcDoubleAngleTest.scala +++ b/src/test/scala/net/kogics/kojo/picture/ArcDoubleAngleTest.scala @@ -11,7 +11,7 @@ import org.scalatest.junit.JUnitRunner @RunWith(classOf[JUnitRunner]) class ArcDoubleAngleTest extends FunSuite with Matchers { val kojoCtx = new NoOpKojoCtx - implicit val spriteCanvas = new SpriteCanvas(kojoCtx) + implicit val spriteCanvas: SpriteCanvas = new SpriteCanvas(kojoCtx) test("touching") { val arc1 = arc(100, 45.6) diff --git a/src/test/scala/net/kogics/kojo/picture/PictureBounceTest.scala b/src/test/scala/net/kogics/kojo/picture/PictureBounceTest.scala index 705fdc0aa..66c2ea4e6 100644 --- a/src/test/scala/net/kogics/kojo/picture/PictureBounceTest.scala +++ b/src/test/scala/net/kogics/kojo/picture/PictureBounceTest.scala @@ -13,7 +13,7 @@ import net.kogics.kojo.util.Vector2D class PictureBounceTest extends FunSuite with Matchers { val rg = new java.util.Random val kojoCtx = new NoOpKojoCtx - implicit val spriteCanvas = new SpriteCanvas(kojoCtx) + implicit val spriteCanvas: SpriteCanvas = new SpriteCanvas(kojoCtx) def picline(x1: Double, y1: Double, x2: Double, y2: Double) = Pic { t => import t._ jumpTo(x1, y1) diff --git a/src/test/scala/net/kogics/kojo/picture/PictureClosenessTest.scala b/src/test/scala/net/kogics/kojo/picture/PictureClosenessTest.scala index 82c91bf78..7b2786315 100644 --- a/src/test/scala/net/kogics/kojo/picture/PictureClosenessTest.scala +++ b/src/test/scala/net/kogics/kojo/picture/PictureClosenessTest.scala @@ -28,7 +28,7 @@ import org.scalatestplus.junit.JUnitRunner class PictureClosenessTest extends FunSuite with Matchers with RepeatCommands { val kojoCtx = new NoOpKojoCtx - implicit val spriteCanvas = new SpriteCanvas(kojoCtx) + implicit val spriteCanvas: SpriteCanvas = new SpriteCanvas(kojoCtx) object Picture { def rectangle(width: Double, height: Double) = picture.rect2(width, height) diff --git a/src/test/scala/net/kogics/kojo/picture/PictureCollisionTest.scala b/src/test/scala/net/kogics/kojo/picture/PictureCollisionTest.scala index 0556cba3f..605012d4e 100644 --- a/src/test/scala/net/kogics/kojo/picture/PictureCollisionTest.scala +++ b/src/test/scala/net/kogics/kojo/picture/PictureCollisionTest.scala @@ -28,7 +28,7 @@ import net.kogics.kojo.lite.canvas.SpriteCanvas class PictureCollisionTest extends FunSuite with Matchers with xscala.RepeatCommands { val kojoCtx = new NoOpKojoCtx - implicit val spriteCanvas = new SpriteCanvas(kojoCtx) + implicit val spriteCanvas: SpriteCanvas = new SpriteCanvas(kojoCtx) val psize = 50.0 val delta = 0.01 diff --git a/src/test/scala/net/kogics/kojo/picture/PictureEqualsHashTest.scala b/src/test/scala/net/kogics/kojo/picture/PictureEqualsHashTest.scala index 2a781eb65..f2d8784c5 100644 --- a/src/test/scala/net/kogics/kojo/picture/PictureEqualsHashTest.scala +++ b/src/test/scala/net/kogics/kojo/picture/PictureEqualsHashTest.scala @@ -28,7 +28,7 @@ import net.kogics.kojo.lite.canvas.SpriteCanvas class PictureEqualsHashTest extends FunSuite with Matchers with xscala.RepeatCommands { val kojoCtx = new NoOpKojoCtx - implicit val spriteCanvas = new SpriteCanvas(kojoCtx) + implicit val spriteCanvas: SpriteCanvas = new SpriteCanvas(kojoCtx) case class Box1(p: Painter) extends Pic(p) { override def copy: Box1 = new Box1(p) diff --git a/src/test/scala/net/kogics/kojo/picture/PictureTest.scala b/src/test/scala/net/kogics/kojo/picture/PictureTest.scala index 494995163..0f0c0a2b3 100644 --- a/src/test/scala/net/kogics/kojo/picture/PictureTest.scala +++ b/src/test/scala/net/kogics/kojo/picture/PictureTest.scala @@ -32,7 +32,7 @@ import util.Utils.doublesEqual class PictureTest extends FunSuite with Matchers with xscala.RepeatCommands { val kojoCtx = new NoOpKojoCtx - implicit val spriteCanvas = new SpriteCanvas(kojoCtx) + implicit val spriteCanvas: SpriteCanvas = new SpriteCanvas(kojoCtx) val Staging = new staging.API(spriteCanvas) // required for the animation test val psize = 50 From cd29d3ec103c82e670a550955fcd0e3d6a929da7 Mon Sep 17 00:00:00 2001 From: Lalit Pant Date: Fri, 2 Jan 2026 17:24:42 +0530 Subject: [PATCH 22/23] Bump up Kojo version to 2.9.34 --- installer.i4j/kojo.install4j | 2 +- src/main/scala/net/kogics/kojo/lite/Versions.scala | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/installer.i4j/kojo.install4j b/installer.i4j/kojo.install4j index b06cb82ae..dfd03f342 100644 --- a/installer.i4j/kojo.install4j +++ b/installer.i4j/kojo.install4j @@ -1,7 +1,7 @@ - + diff --git a/src/main/scala/net/kogics/kojo/lite/Versions.scala b/src/main/scala/net/kogics/kojo/lite/Versions.scala index b5bb2cd35..652ce0a45 100644 --- a/src/main/scala/net/kogics/kojo/lite/Versions.scala +++ b/src/main/scala/net/kogics/kojo/lite/Versions.scala @@ -3,8 +3,8 @@ package net.kogics.kojo.lite object Versions { val KojoMajorVersion = "2.9" val KojoVersion = "2.9.34" - val KojoRevision = "r2" - val KojoBuildDate = "2 Jan 2025" + val KojoRevision = "r3" + val KojoBuildDate = "2 Jan 2026" val JavaVersion = { val jrv = System.getProperty("java.runtime.version") val arch = System.getProperty("os.arch") From 2dcab9f7e7588b9f6b22be5fcc3eb42558b6ce13 Mon Sep 17 00:00:00 2001 From: Ben Bulent Basaran Date: Wed, 1 Apr 2026 14:26:53 -0400 Subject: [PATCH 23/23] new turkish release --- installer.i4j/koco.install4j | 4 ++-- src/main/scala/net/kogics/kojo/lite/i18n/tr/dict.scala | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/installer.i4j/koco.install4j b/installer.i4j/koco.install4j index 72e55f666..827d84a63 100644 --- a/installer.i4j/koco.install4j +++ b/installer.i4j/koco.install4j @@ -1,7 +1,7 @@ - + @@ -9,7 +9,7 @@ - + diff --git a/src/main/scala/net/kogics/kojo/lite/i18n/tr/dict.scala b/src/main/scala/net/kogics/kojo/lite/i18n/tr/dict.scala index 4e3bfa614..f91dc9295 100644 --- a/src/main/scala/net/kogics/kojo/lite/i18n/tr/dict.scala +++ b/src/main/scala/net/kogics/kojo/lite/i18n/tr/dict.scala @@ -16,8 +16,8 @@ */ /* Koco version tag for timestamping purposes: - val KojoRevision = "r2-tr-1" - val KojoBuildDate = "28 Haziran 2025" + val KojoRevision = "r3-tr-1" + val KojoBuildDate = "31 Mart 2026" Ref Kojo version: ../../Versions.scala I do not check in to Version.scala. Makes it hard to sync by fork with Lalit's base.