diff --git a/.github/workflows/build-gradle.yml b/.github/workflows/build-gradle.yml new file mode 100644 index 0000000000..91a39705b2 --- /dev/null +++ b/.github/workflows/build-gradle.yml @@ -0,0 +1,63 @@ +name: Pre-releases with Gradle +on: + push: + paths-ignore: + - '**/*.md' + - '.all-contributorsrc' + +jobs: + build: + name: Create Pre-release for ${{ matrix.os_prefix }} (${{ matrix.arch }}) + runs-on: ${{ matrix.os }} + permissions: + contents: write + strategy: + fail-fast: false + matrix: + include: +# # compiling for arm32 needs a self-hosted runner on Raspi OS (32-bit) +# - os: self-hosted +# os_prefix: linux +# arch: arm + - os: ubuntu-latest + os_prefix: linux + arch: x64 + - os: windows-latest + os_prefix: windows + arch: x64 + - os: macos-latest + os_prefix: macos + arch: x64 + - os: macos-latest + os_prefix: macos + arch: aarch64 +# - os: macos-latest +# os_prefix: linux +# arch: aarch64 + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + - name: Checkout Examples Repository + uses: actions/checkout@v4 + with: + repository: processing/processing-examples + path: processing-examples + - name: Install Java + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + architecture: ${{ matrix.arch }} + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + - name: Build with Gradle + run: ./gradlew packageDistributionForCurrentOS + - name: Add artifact + uses: actions/upload-artifact@v4 + with: + name: processing-${{github.sha}}${{ matrix.os_prefix }}-${{ matrix.arch }} + path: | + ./app/build/compose/binaries/**/*.dmg + ./app/build/compose/binaries/**/*.msi + ./app/build/compose/binaries/**/*.deb + retention-days: 1 diff --git a/.gitignore b/.gitignore index d5f761a048..af464f595e 100644 --- a/.gitignore +++ b/.gitignore @@ -101,3 +101,9 @@ processing-examples .gradle core/build/ build/publish/ +app/build +java/build/ +/build/reports +/java/bin +/java/libraries/svg/bin +/java/preprocessor/build diff --git a/.idea/artifacts/app_desktop.xml b/.idea/artifacts/app_desktop.xml new file mode 100644 index 0000000000..0e28344dcb --- /dev/null +++ b/.idea/artifacts/app_desktop.xml @@ -0,0 +1,6 @@ + + + $PROJECT_DIR$/app/build/libs + + + \ No newline at end of file diff --git a/.idea/artifacts/app_jvm.xml b/.idea/artifacts/app_jvm.xml new file mode 100644 index 0000000000..1f0afe2f97 --- /dev/null +++ b/.idea/artifacts/app_jvm.xml @@ -0,0 +1,6 @@ + + + $PROJECT_DIR$/app/build/libs + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000000..b589d56e9f --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000000..e9be690395 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000000..d4b7accbaa --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 3d3ab27e97..43b1638895 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,7 @@ - + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 335d8c4b3e..1aec8ebf6f 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,18 +2,19 @@ - - + + + + + - - - + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7f4c..35eb1ddfbb 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/app/.project b/app/.project deleted file mode 100644 index 84f5a27a1e..0000000000 --- a/app/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - processing4-app - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000000..5770f95eff --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,168 @@ +import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform +import org.jetbrains.compose.desktop.application.dsl.TargetFormat +import org.jetbrains.compose.internal.de.undercouch.gradle.tasks.download.Download + +plugins{ + id("java") + + kotlin("jvm") version libs.versions.kotlin + alias(libs.plugins.compose.compiler) + alias(libs.plugins.jetbrainsCompose) + alias(libs.plugins.serialization) + + id("de.undercouch.download") version "5.6.0" +} + +group = rootProject.group + +repositories{ + mavenCentral() + google() + maven { url = uri("https://jogamp.org/deployment/maven") } +} + +sourceSets{ + main{ + java{ + srcDirs("src") + } + kotlin{ + srcDirs("src") + } + resources{ + srcDirs("src","../build/shared/") + } + } +} + +compose.desktop { + application { + mainClass = "processing.app.ui.Splash" + + nativeDistributions{ + includeAllModules = true + targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) + packageName = "Processing" + packageVersion = rootProject.version as String + + macOS{ + bundleID = "org.processingfoundation.processing.app" + iconFile = project.file("../build/macos/processing.icns") + } + windows{ + iconFile = project.file("../build/windows/processing.ico") + } + linux { + iconFile = project.file("../build/linux/processing.png") + } + + // Allow swing to use the system look and feel + jvmArgs( + "-Dapple.awt.application.appearance=system" + ) + appResourcesRootDir.set(layout.buildDirectory.dir("resources-bundled")) + } + } +} + +val compottieVersion = "2.0.0-rc02" + +dependencies { + implementation("com.formdev:flatlaf:3.4.1") + + implementation("net.java.dev.jna:jna:5.12.1") + implementation("net.java.dev.jna:jna-platform:5.12.1") + + implementation(project(":core")) + runtimeOnly(project(":java")) + implementation(project(":java:preprocessor")) + + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material) + implementation(compose.ui) + implementation(compose.components.resources) + implementation(compose.components.uiToolingPreview) + + implementation(compose.desktop.currentOs) + + implementation("io.github.alexzhirkevich:compottie:${compottieVersion}") + + implementation("com.charleskorn.kaml:kaml:0.65.0") +} + +tasks.register("addCore"){ + dependsOn(project(":core").tasks.jar) + from("../core/build/libs/") + include("*.jar") + into("build/resources/main/core/library") +} +tasks.jar { dependsOn("addCore") } +tasks.processResources{ finalizedBy("addCore") } + +tasks.register("downloadJDK") { + val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem() + val arch: String = System.getProperty("os.arch").let { originalArch -> + when (originalArch) { + "amd64" -> "x64" + "x86_64" -> "x64" + else -> originalArch + } + } + + val platform = when { + os.isWindows -> "windows" + os.isMacOsX -> "mac" + else -> "linux" + } + val javaVersion = "17" + val imageType = "jdk" + + src("https://api.adoptium.net/v3/binary/latest/" + + "$javaVersion/ga/" + + "$platform/" + + "$arch/" + + "$imageType/" + + "hotspot/normal/eclipse?project=jdk") + + val extension = if (os.isWindows) "zip" else "tar.gz" + dest(layout.buildDirectory.file("jdk-$platform-$arch.$extension")) + overwrite(false) +} +tasks.register("unzipJDK") { + val dl = tasks.findByPath("downloadJDK") as Download + dependsOn(dl) + + val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem() + val archive = if (os.isWindows) { + zipTree(dl.dest) + } else { + tarTree(dl.dest) + } + + from(archive) + into(layout.buildDirectory.dir("resources-bundled/common")) +} +afterEvaluate { + tasks.findByName("prepareAppResources")?.dependsOn("unzipJDK") + tasks.register("setExecutablePermissions") { + description = "Sets executable permissions on binaries in Processing.app resources" + group = "compose desktop" + + doLast { + val resourcesPath = layout.buildDirectory.dir("compose/binaries") + fileTree(resourcesPath) { + include("**/resources/**/bin/**") + include("**/resources/**/*.sh") + include("**/resources/**/*.dylib") + include("**/resources/**/*.so") + include("**/resources/**/*.exe") + }.forEach { file -> + if (file.isFile) { + file.setExecutable(true, false) + } + } + } + } + tasks.findByName("createDistributable")?.finalizedBy("setExecutablePermissions") +} diff --git a/app/processing4-app.iml b/app/processing4-app.iml deleted file mode 100644 index 62e9a8c3a8..0000000000 --- a/app/processing4-app.iml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/processing/app/Platform.java b/app/src/processing/app/Platform.java index d6f472abe5..81ba60b142 100644 --- a/app/src/processing/app/Platform.java +++ b/app/src/processing/app/Platform.java @@ -28,10 +28,10 @@ import java.lang.management.ManagementFactory; import java.net.URISyntaxException; import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.PosixFilePermission; +import java.util.*; import com.sun.jna.platform.FileUtils; @@ -331,9 +331,21 @@ static public boolean isLinux() { * Get reference to a file adjacent to the executable on Windows and Linux, * or inside Contents/Resources/Java on Mac OS X. This will return the local * JRE location, *whether or not it is the active JRE*. + * @deprecated start using the build in JAR Resources system instead. */ + @Deprecated static public File getContentFile(String name) { if (processingRoot == null) { + var url = Platform.class.getClassLoader().getResource("lib/defaults.txt"); + if(url != null){ + try { + processingRoot = Files.createTempDirectory("processing").toFile(); + copyFromJar("/", processingRoot.toPath()); + return new File(processingRoot, name); + } catch (IOException | URISyntaxException e) { + e.printStackTrace(); + } + } // Get the path to the .jar file that contains Base.class URL pathURL = Base.class.getProtectionDomain().getCodeSource().getLocation(); @@ -382,8 +394,67 @@ static public File getContentFile(String name) { return new File(processingRoot, name); } + public static void copyFromJar(String source, final Path target) throws URISyntaxException, IOException { + var resource = Platform.class.getResource("").toURI(); + var fileSystem = FileSystems.newFileSystem( + resource, + Collections.emptyMap() + ); + + + final Path jarPath = fileSystem.getPath(source); + + Files.walkFileTree(jarPath, new SimpleFileVisitor() { + + private Path currentTarget; + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + currentTarget = target.resolve(jarPath.relativize(dir).toString()); + Files.createDirectories(currentTarget); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.copy(file, target.resolve(jarPath.relativize(file).toString()), StandardCopyOption.REPLACE_EXISTING); + return FileVisitResult.CONTINUE; + } + + }); + } static public File getJavaHome() { + var resourcesDir = new File(System.getProperty("compose.application.resources.dir")); + if(resourcesDir.exists()) { + // find the jdk folder starting with jdk-17 + var jdkFolder = Arrays.stream(resourcesDir.listFiles((dir, name) -> dir.isDirectory() && name.startsWith("jdk-17"))) + .findFirst() + .orElse(null); + if(Platform.isMacOS()){ + return new File(jdkFolder, "Contents/Home"); + } + return jdkFolder; + } + + var home = System.getProperty("java.home"); + if(home != null){ + if(new File(home, "bin/java").exists()){ + return new File(home); + }else{ + String os = System.getProperty("os.name").toLowerCase(); + // Default installation paths for different operating systems + if (os.contains("windows")) { + var programFiles = new File(System.getenv("ProgramFiles")); + return new File(programFiles, "Eclipse Adoptium/jdk-17.0.10+7-hotspot"); + } else if (os.contains("mac")) { + return new File("/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home"); + } else { + // Linux and others + return new File("/usr/lib/jvm/temurin-17-jdk"); + } + } + } if (Platform.isMacOS()) { //return "Contents/PlugIns/jdk1.7.0_40.jdk/Contents/Home/jre/bin/java"; File[] plugins = getContentFile("../PlugIns").listFiles((dir, name) -> dir.isDirectory() && @@ -394,7 +465,6 @@ static public File getJavaHome() { return getContentFile("java"); } - /** Get the path to the embedded Java executable. */ static public String getJavaPath() { String javaPath = "bin/java" + (Platform.isWindows() ? ".exe" : ""); diff --git a/app/src/processing/app/contrib/ui/ContributionManager.kt b/app/src/processing/app/contrib/ui/ContributionManager.kt new file mode 100644 index 0000000000..a057e76dfa --- /dev/null +++ b/app/src/processing/app/contrib/ui/ContributionManager.kt @@ -0,0 +1,320 @@ +package processing.app.contrib.ui + +import androidx.compose.animation.Animatable +import androidx.compose.foundation.* +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.awt.ComposePanel +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.pointer.PointerIcon +import androidx.compose.ui.input.pointer.pointerHoverIcon +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Window +import androidx.compose.ui.window.application +import com.charleskorn.kaml.Yaml +import com.charleskorn.kaml.YamlConfiguration +import kotlinx.serialization.Serializable +import processing.app.Platform +import java.net.URL +import java.util.* +import javax.swing.JFrame +import javax.swing.SwingUtilities +import kotlin.io.path.* + + +fun main() = application { + val active = remember { mutableStateOf(true) } + if(!active.value){ + Window(onCloseRequest = ::exitApplication) { + + } + return@application + } + Window( + onCloseRequest = { active.value = false }, + ) { + contributionsManager() + } +} + +enum class Status { + VALID, + BROKEN, + DEPRECATED +} +enum class Type { + library, + mode, + tool, + examples, +} + +@Serializable +data class Author( + val name: String, + val url: String? = null, +) + +@Serializable +data class Contribution( + val id: Int, + val status: Status, + val source: String, + val type: Type, + val name: String? = null, + val categories: List? = emptyList(), + val authors: String? = null, + val authorList: List? = emptyList(), + val url: String? = null, + val sentence: String? = null, + val paragraph: String? = null, + val version: String? = null, + val prettyVersion: String? = null, + val minRevision: Int? = null, + val maxRevision: Int? = null, + val download: String? = null, + val isUpdate: Boolean? = null, + val isInstalled: Boolean? = null, +) + +@Serializable +data class Contributions( + val contributions: List +) + +fun openContributionsManager(){ + // open the compose window + + SwingUtilities.invokeLater { + val frame = JFrame("Contributions Manager") + frame.defaultCloseOperation = JFrame.DISPOSE_ON_CLOSE + frame.setSize(800, 600) + + val composePanel = ComposePanel() + composePanel.setContent { + contributionsManager() + } + + frame.contentPane.add(composePanel) + frame.isVisible = true + } +} + +@Composable +fun contributionsManager(){ + var contributions by remember { mutableStateOf(listOf()) } + var localContributions by remember { mutableStateOf(listOf()) } + var error by remember { mutableStateOf(null) } + + val preferences = loadPreferences() + + LaunchedEffect(preferences){ + try { + localContributions = loadContributionProperties(preferences) + .map { (type, props) -> + Contribution( + id = 0, + status = Status.VALID, + source = "local", + type = type, + name = props.getProperty("name"), + authors = props.getProperty("authors"), + url = props.getProperty("url"), + sentence = props.getProperty("sentence"), + paragraph = props.getProperty("paragraph"), + version = props.getProperty("version"), + prettyVersion = props.getProperty("prettyVersion"), + minRevision = props.getProperty("minRevision")?.toIntOrNull(), + maxRevision = props.getProperty("maxRevision")?.toIntOrNull(), + download = props.getProperty("download"), + ) + } + } catch (e: Exception){ + error = e + } + } + + + LaunchedEffect(Unit){ + try { + val url = URL("https://github.com/mingness/processing-contributions-new/raw/refs/heads/main/contributions.yaml") + val connection = url.openConnection() + val inputStream = connection.getInputStream() + val yaml = inputStream.readAllBytes().decodeToString() + // TODO cache yaml in processing folder + + val parser = Yaml( + configuration = YamlConfiguration( + strictMode = false + ) + ) + val result = parser.decodeFromString(Contributions.serializer(), yaml) + + contributions = result.contributions + .filter { it.status == Status.VALID } + .map { + // TODO Parse better + val authorList = it.authors?.split(",")?.map { author -> + val parts = author.split("](") + val name = parts[0].removePrefix("[") + val url = parts.getOrNull(1)?.removeSuffix(")") + Author(name, url) + } ?: emptyList() + it.copy(authorList = authorList) + } + } catch (e: Exception){ + error = e + } + } + if(error != null){ + Text("Error loading contributions: ${error?.message}") + return + } + if(contributions.isEmpty()){ + Text("Loading contributions...") + return + } + + val contributionsByType = (contributions + localContributions) + .groupBy { it.name } + .map { (_, contributions) -> + if(contributions.size == 1) return@map contributions.first() + else{ + // check if they all have the same version, otherwise return the newest version + val versions = contributions.mapNotNull { it.version } + if(versions.toSet().size == 1) return@map contributions.first().copy(isInstalled = true) + else{ + val newest = contributions.maxByOrNull { it.version?.toIntOrNull() ?: 0 } + if(newest != null) return@map newest.copy(isUpdate = true, isInstalled = true) + else return@map contributions.first().copy(isUpdate = true, isInstalled = true) + } + } + } + .groupBy { it.type } + + val types = Type.entries + var selectedType by remember { mutableStateOf(types.first()) } + val contributionsForType = (contributionsByType[selectedType] ?: emptyList()) + .sortedBy { it.name } + + var selectedContribution by remember { mutableStateOf(null) } + Box{ + Column { + Row{ + for(type in types){ + val background = remember { Animatable(Color.Transparent) } + val color = remember { Animatable(Color.Black) } + LaunchedEffect(selectedType){ + if(selectedType == type){ + background.animateTo(Color(0xff0251c8)) + color.animateTo(Color.White) + }else{ + background.animateTo(Color.Transparent) + color.animateTo(Color.Black) + } + } + + Row(modifier = Modifier + .background(background.value) + .pointerHoverIcon(PointerIcon.Hand) + .clickable { + selectedType = type + selectedContribution = null + } + .padding(16.dp, 8.dp) + ){ + Text(type.name, color = color.value) + val updates = contributionsByType[type]?.count { it.isUpdate == true } ?: 0 + if(updates > 0){ + Text("($updates)") + } + } + } + } + + Box(modifier = Modifier.weight(1f)){ + val state = rememberLazyListState() + LazyColumn(state = state) { + item{ + // Table Header + } + items(contributionsForType){ contribution -> + Row(modifier = Modifier + .pointerHoverIcon(PointerIcon.Hand) + .clickable { selectedContribution = contribution } + .padding(8.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + Row(modifier = Modifier.weight(1f)){ + if(contribution.isUpdate == true){ + Text("Update") + }else if(contribution.isInstalled == true){ + Text("Installed") + } + + } + Row(horizontalArrangement = Arrangement.spacedBy(4.dp), modifier = Modifier.weight(8f)){ + Text(contribution.name ?: "Unnamed", fontWeight = FontWeight.Bold) + Text(contribution.sentence ?: "No description", maxLines = 1, overflow = TextOverflow.Ellipsis) + } + Row(modifier = Modifier.weight(4f)){ + Text(contribution.authorList?.joinToString { it.name } ?: "Unknown") + } + } + } + } + VerticalScrollbar( + modifier = Modifier + .align(Alignment.CenterEnd) + .background(Color.LightGray) + .fillMaxHeight(), + adapter = rememberScrollbarAdapter( + scrollState = state + ) + ) + } + ContributionPane( + contribution = selectedContribution, + onClose = { selectedContribution = null } + ) + } + + } + +} + + +fun loadContributionProperties(preferences: Properties): List>{ + val result = mutableListOf>() + val sketchBook = Path(preferences.getProperty("sketchbook.path.four", Platform.getDefaultSketchbookFolder().path)) + sketchBook.forEachDirectoryEntry{ contributionsFolder -> + if(!contributionsFolder.isDirectory()) return@forEachDirectoryEntry + val typeName = contributionsFolder.fileName.toString() + val type: Type = when(typeName){ + "libraries" -> Type.library + "modes" -> Type.mode + "tools" -> Type.tool + "examples" -> Type.examples + else -> return@forEachDirectoryEntry + } + contributionsFolder.forEachDirectoryEntry { contribution -> + if(!contribution.isDirectory()) return@forEachDirectoryEntry + contribution.forEachDirectoryEntry("*.properties"){ entry -> + val props = Properties() + props.load(entry.inputStream()) + result += Pair(type, props) + } + } + } + return result +} \ No newline at end of file diff --git a/app/src/processing/app/contrib/ui/ContributionPane.kt b/app/src/processing/app/contrib/ui/ContributionPane.kt new file mode 100644 index 0000000000..2f4a96931b --- /dev/null +++ b/app/src/processing/app/contrib/ui/ContributionPane.kt @@ -0,0 +1,79 @@ +package processing.app.contrib.ui + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.pointer.PointerIcon +import androidx.compose.ui.input.pointer.pointerHoverIcon +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.compose.ui.window.Window + +//--processing-blue-light: #82afff; +//--processing-blue-mid: #0564ff; +//--processing-blue-deep: #1e32aa; +//--processing-blue-dark: #0f195a; +//--processing-blue: #0251c8; + +@Composable +fun ContributionPane(contribution: Contribution?, onClose: () -> Unit) { + if(contribution == null) { + return + } + val typeName = when(contribution.type) { + Type.library -> "Library" + Type.tool -> "Tool" + Type.examples -> "Example" + Type.mode -> "Mode" + } + Window( + title = "${typeName}: ${contribution.name}", + onCloseRequest = onClose, + onKeyEvent = { + if(it.key == Key.Escape) { + onClose() + true + } else { + false + } + } + ){ + Box { + Column(modifier = Modifier.padding(10.dp)) { + Text(typeName, style = TextStyle(fontSize = 16.sp)) + Text(contribution.name ?: "", style = TextStyle(fontSize = 20.sp)) + Row(modifier = Modifier.padding(0.dp, 10.dp)) { + val action = when(contribution.isUpdate) { + true -> "Update" + false, null -> when(contribution.isInstalled) { + true -> "Uninstall" + false, null -> "Install" + } + } + Text(action, + style = TextStyle(fontSize = 14.sp, color = Color.White), + modifier = Modifier + .clickable { + + } + .pointerHoverIcon(PointerIcon.Hand) + .background(Color(0xff0251c8)) + .padding(24.dp,12.dp) + ) + } + Text(contribution.paragraph ?: "", style = TextStyle(fontSize = 14.sp)) + } + } + } + +} \ No newline at end of file diff --git a/app/src/processing/app/contrib/ui/Preferences.kt b/app/src/processing/app/contrib/ui/Preferences.kt new file mode 100644 index 0000000000..b344e1cb7d --- /dev/null +++ b/app/src/processing/app/contrib/ui/Preferences.kt @@ -0,0 +1,71 @@ +package processing.app.contrib.ui + +import androidx.compose.runtime.* +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import processing.app.Base +import processing.app.Platform +import java.io.File +import java.nio.file.* +import java.util.Properties + + +const val PREFERENCES_FILE_NAME = "preferences.txt" +const val DEFAULTS_FILE_NAME = "defaults.txt" + + +@Composable +fun loadPreferences(): Properties{ + Platform.init() + + val settingsFolder = Platform.getSettingsFolder() + val preferencesFile = settingsFolder.resolve(PREFERENCES_FILE_NAME) + + if(!preferencesFile.exists()){ + preferencesFile.createNewFile() + } + val watched = watchFile(preferencesFile) + + val preferences by remember { + mutableStateOf(Properties()) + } + + LaunchedEffect(watched){ + val defaults = Base::class.java.getResourceAsStream("/lib/${DEFAULTS_FILE_NAME}") ?: return@LaunchedEffect + + preferences.load(defaults) + preferences.load(preferencesFile.inputStream()) + } + + return preferences +} + +@Composable +fun watchFile(file: File): Any? { + val scope = rememberCoroutineScope() + var event by remember(file) { mutableStateOf?> (null) } + + DisposableEffect(file){ + val fileSystem = FileSystems.getDefault() + val watcher = fileSystem.newWatchService() + var active = true + + val path = file.toPath() + val parent = path.parent + val key = parent.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY) + scope.launch(Dispatchers.IO) { + while (active) { + for (modified in key.pollEvents()) { + if (modified.context() != path.fileName) continue + event = modified + } + } + } + onDispose { + active = false + key.cancel() + watcher.close() + } + } + return event +} \ No newline at end of file diff --git a/app/src/processing/app/ui/ExamplesLibrary.kt b/app/src/processing/app/ui/ExamplesLibrary.kt new file mode 100644 index 0000000000..630150c014 --- /dev/null +++ b/app/src/processing/app/ui/ExamplesLibrary.kt @@ -0,0 +1,25 @@ +package processing.app.ui + +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.window.Window +import androidx.compose.ui.window.application + +fun ExamplesLibrary(){ + +} + +fun main() = application { + val active = remember { mutableStateOf(true) } + if(!active.value){ + Window(onCloseRequest = ::exitApplication) { + + } + return@application + } + Window( + onCloseRequest = { active.value = false }, + ) { + ExamplesLibrary() + } +} \ No newline at end of file diff --git a/app/src/processing/app/ui/JVMManager.kt b/app/src/processing/app/ui/JVMManager.kt new file mode 100644 index 0000000000..eda5b3e5ef --- /dev/null +++ b/app/src/processing/app/ui/JVMManager.kt @@ -0,0 +1,158 @@ +package processing.app.ui + +import androidx.compose.foundation.* +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsHoveredAsState +import androidx.compose.foundation.interaction.collectIsPressedAsState +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.awt.ComposePanel +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.pointer.PointerEventType +import androidx.compose.ui.input.pointer.onPointerEvent +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.platform.Font +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Window +import androidx.compose.ui.window.application +import io.github.alexzhirkevich.compottie.* +import org.jetbrains.compose.resources.ExperimentalResourceApi +import org.processing.app.generated.resources.Res +import processing.app.Base +import processing.app.Language +import processing.app.Platform +import java.awt.BorderLayout +import java.awt.Desktop +import java.io.File +import java.net.URI +import java.nio.charset.Charset +import javax.swing.SwingUtilities + + +fun addJDKManger(parent: javax.swing.Box){ + SwingUtilities.invokeLater { + val composePanel = ComposePanel().apply { + setContent { + JDKManager() + } + } + parent.apply { + add(composePanel, BorderLayout.EAST) + } + } + +} + +fun main() = application { + Window(onCloseRequest = ::exitApplication) { +// JDKManager() + } +} + +// If the user does not have a valid JDK installed on their system, this function will display a message and a button to download the JDK +// Temporary workaround until we ship Processing with a JDK again +@OptIn(ExperimentalResourceApi::class) +@Composable +fun JDKManager(){ + val home = Platform.getJavaHome() + val valid = File(home, "bin/java").exists() + if(valid) return + + val color = Theme.getColor("status.notice.bgcolor") + val colorText = Theme.getColor("status.notice.fgcolor") + val buttonColor = Theme.getColor("toolbar.button.enabled.field") + val buttonTextColor = Theme.getColor("toolbar.button.enabled.glyph") + + val fontFamily = FontFamily( + Font( + resource = "font/ProcessingSansPro-Regular.ttf", + weight = FontWeight.W400, + style = FontStyle.Normal + ) + ) + + val os = System.getProperty("os.name") + val arch = System.getProperty("os.arch") + val platform = when { + os.contains("Windows") -> "windows" + os.contains("Mac") -> "mac" + else -> "linux" + } + + val composition by rememberLottieComposition { + LottieCompositionSpec.JsonString( +"{\"v\":\"5.3.4\",\"fr\":24,\"ip\":0,\"op\":55,\"w\":1000,\"h\":1000,\"nm\":\"Comp 1\",\"ddd\":0,\"assets\":[{\"id\":\"comp_0\",\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":0,\"nm\":\"roj\",\"refId\":\"comp_1\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":6,\"s\":[0],\"e\":[84]},{\"t\":23}],\"ix\":10},\"p\":{\"a\":0,\"k\":[500,500,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[500,500,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":6,\"s\":[100,100,100],\"e\":[157,157,100]},{\"t\":10}],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":6,\"op\":36,\"st\":6,\"bm\":0},{\"ddd\":0,\"ind\":2,\"ty\":0,\"nm\":\"Ama\",\"refId\":\"comp_3\",\"sr\":1,\"ks\":{\"o\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":20,\"s\":[100],\"e\":[1]},{\"t\":29}],\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":4,\"s\":[0],\"e\":[85]},{\"t\":29}],\"ix\":10},\"p\":{\"a\":0,\"k\":[497.25,498.5,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[496.75,500.5,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":4,\"s\":[54,54,100],\"e\":[100,100,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":8,\"s\":[100,100,100],\"e\":[134,134,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":17,\"s\":[134,134,100],\"e\":[96,96,100]},{\"t\":19}],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":4,\"op\":34,\"st\":4,\"bm\":0},{\"ddd\":0,\"ind\":3,\"ty\":0,\"nm\":\"nar\",\"refId\":\"comp_5\",\"sr\":1,\"ks\":{\"o\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":15,\"s\":[100],\"e\":[0]},{\"t\":20}],\"ix\":11},\"r\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":5,\"s\":[0],\"e\":[46]},{\"t\":21}],\"ix\":10},\"p\":{\"a\":0,\"k\":[497.5,499.25,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[497.5,499.25,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":1,\"s\":[30,30,100],\"e\":[100,100,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":5,\"s\":[100,100,100],\"e\":[123,123,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":8,\"s\":[123,123,100],\"e\":[273.393,273.393,100]},{\"t\":14}],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0}]},{\"id\":\"comp_1\",\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":0,\"nm\":\"ROJO\",\"refId\":\"comp_2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-301.855,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.875,499.375,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[496.944,499.56,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":2,\"ty\":0,\"nm\":\"ROJO\",\"refId\":\"comp_2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-252.88,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.875,499.375,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[496.944,499.56,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":3,\"ty\":0,\"nm\":\"ROJO\",\"refId\":\"comp_2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-198.233,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.875,499.375,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[496.944,499.56,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":4,\"ty\":0,\"nm\":\"ROJO\",\"refId\":\"comp_2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-149.663,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.875,499.375,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[496.944,499.56,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":5,\"ty\":0,\"nm\":\"ROJO\",\"refId\":\"comp_2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-99.267,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.875,499.375,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[496.944,499.56,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":6,\"ty\":0,\"nm\":\"ROJO\",\"refId\":\"comp_2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-45.613,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.875,499.375,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[496.944,499.56,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":7,\"ty\":0,\"nm\":\"ROJO\",\"refId\":\"comp_2\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":10.106,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.875,499.375,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[496.944,499.56,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0}]},{\"id\":\"comp_2\",\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":4,\"nm\":\"Shape Layer 1\",\"sr\":1,\"ks\":{\"o\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":11,\"s\":[100],\"e\":[0]},{\"t\":14}],\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[500,500,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":1,\"s\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[0.75,-5.625],[-3.625,0],[3.375,-0.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[5.125,-10.125],[-3.625,0],[9.875,-1.75]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":3,\"s\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[5.125,-10.125],[-3.625,0],[9.875,-1.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[19.625,-19.625],[5.875,-4.5],[25.375,-7.75]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5.412,\"s\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[19.625,-19.625],[5.875,-4.5],[25.375,-7.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[67.125,-43.625],[30.875,-18.5],[71.375,-36.25]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7.529,\"s\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[67.125,-43.625],[30.875,-18.5],[71.375,-36.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[135.625,-79.625],[73.875,-42],[136.375,-77.25]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":11,\"s\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[135.625,-79.625],[73.875,-42],[136.375,-77.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[219.125,-134.125],[194.125,-119.75],[219.375,-133.5]],\"c\":true}]},{\"t\":14}],\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0,0,0,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":0,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":8},\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.125670728496,0.339342573577,0.65306372549,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transformar\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":30,\"st\":0,\"bm\":0}]},{\"id\":\"comp_3\",\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":0,\"nm\":\"AMARILLO\",\"refId\":\"comp_4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":298.463,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.75,500.5,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[497.731,499.593,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":2,\"ty\":0,\"nm\":\"AMARILLO\",\"refId\":\"comp_4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":257.603,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.75,500.5,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[497.731,499.593,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":3,\"ty\":0,\"nm\":\"AMARILLO\",\"refId\":\"comp_4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":211.954,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.75,500.5,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[497.731,499.593,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":4,\"ty\":0,\"nm\":\"AMARILLO\",\"refId\":\"comp_4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":166.163,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.75,500.5,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[497.731,499.593,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":5,\"ty\":0,\"nm\":\"AMARILLO\",\"refId\":\"comp_4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":119.533,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.75,500.5,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[497.731,499.593,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":6,\"ty\":0,\"nm\":\"AMARILLO\",\"refId\":\"comp_4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":69.838,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.75,500.5,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[497.731,499.593,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":7,\"ty\":0,\"nm\":\"AMARILLO\",\"refId\":\"comp_4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":24.35,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.75,500.5,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[497.731,499.593,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":8,\"ty\":0,\"nm\":\"AMARILLO\",\"refId\":\"comp_4\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-22.692,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.75,500.5,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[497.731,499.593,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0}]},{\"id\":\"comp_4\",\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":4,\"nm\":\"Shape Layer 1\",\"sr\":1,\"ks\":{\"o\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":13,\"s\":[100],\"e\":[0]},{\"t\":16}],\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[496.25,499.875,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[-3.75,-0.125,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":2,\"s\":[229,229,100],\"e\":[176,176,100]},{\"t\":15}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":3,\"s\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[0.75,-5.625],[-3.625,0],[3.375,-0.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[5.125,-10.125],[-3.625,0],[9.875,-1.75]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":5,\"s\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[5.125,-10.125],[-3.625,0],[9.875,-1.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[19.625,-19.625],[5.875,-4.5],[25.375,-7.75]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7.412,\"s\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[19.625,-19.625],[5.875,-4.5],[25.375,-7.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[67.125,-43.625],[30.875,-18.5],[71.375,-36.25]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":9.529,\"s\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[67.125,-43.625],[30.875,-18.5],[71.375,-36.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[135.625,-79.625],[73.875,-42],[136.375,-77.25]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":13,\"s\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[135.625,-79.625],[73.875,-42],[136.375,-77.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[219.125,-134.125],[194.125,-119.75],[219.375,-133.5]],\"c\":true}]},{\"t\":16}],\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0,0,0,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":0,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":8},\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.985922181373,0.777212404737,0.310502085966,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transformar\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":30,\"st\":0,\"bm\":0}]},{\"id\":\"comp_5\",\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":0,\"nm\":\"NARANJA\",\"refId\":\"comp_6\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-329.986,\"ix\":10},\"p\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":2,\"ty\":0,\"nm\":\"NARANJA\",\"refId\":\"comp_6\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-296.86,\"ix\":10},\"p\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":3,\"ty\":0,\"nm\":\"NARANJA\",\"refId\":\"comp_6\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-266.081,\"ix\":10},\"p\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":4,\"ty\":0,\"nm\":\"NARANJA\",\"refId\":\"comp_6\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-236.454,\"ix\":10},\"p\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":5,\"ty\":0,\"nm\":\"NARANJA\",\"refId\":\"comp_6\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-208.651,\"ix\":10},\"p\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":6,\"ty\":0,\"nm\":\"NARANJA\",\"refId\":\"comp_6\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-180.777,\"ix\":10},\"p\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":7,\"ty\":0,\"nm\":\"NARANJA\",\"refId\":\"comp_6\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-153.807,\"ix\":10},\"p\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":8,\"ty\":0,\"nm\":\"NARANJA\",\"refId\":\"comp_6\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-124.081,\"ix\":10},\"p\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":9,\"ty\":0,\"nm\":\"NARANJA\",\"refId\":\"comp_6\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-95.258,\"ix\":10},\"p\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":10,\"ty\":0,\"nm\":\"NARANJA\",\"refId\":\"comp_6\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-64.449,\"ix\":10},\"p\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":11,\"ty\":0,\"nm\":\"NARANJA\",\"refId\":\"comp_6\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":-31.972,\"ix\":10},\"p\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":12,\"ty\":0,\"nm\":\"NARANJA\",\"refId\":\"comp_6\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[498.25,499.75,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":30,\"st\":0,\"bm\":0}]},{\"id\":\"comp_6\",\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":4,\"nm\":\"Shape Layer 1\",\"sr\":1,\"ks\":{\"o\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p833_0p833_0p167_0p167\"],\"t\":19,\"s\":[100],\"e\":[0]},{\"t\":24}],\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[500,500,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":2,\"s\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[5.125,-10.125],[-3.625,0],[9.875,-1.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[19.625,-19.625],[5.875,-4.5],[25.375,-7.75]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":7,\"s\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[19.625,-19.625],[5.875,-4.5],[25.375,-7.75]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[67.125,-43.625],[30.875,-18.5],[71.375,-36.25]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":12,\"s\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[67.125,-43.625],[30.875,-18.5],[71.375,-36.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[135.625,-79.625],[73.875,-42],[136.375,-77.25]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":19,\"s\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[135.625,-79.625],[73.875,-42],[136.375,-77.25]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0]],\"v\":[[219.125,-134.125],[194.125,-119.75],[219.375,-133.5]],\"c\":true}]},{\"t\":25}],\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0,0,0,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":0,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":8},\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.151382551006,0.753048406863,0.606834680894,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transformar\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":30,\"st\":0,\"bm\":0}]}],\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":0,\"nm\":\"1\",\"refId\":\"comp_0\",\"sr\":1.15,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[672,664,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[500,500,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[76,76,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":25,\"op\":66.4,\"st\":25,\"bm\":0},{\"ddd\":0,\"ind\":2,\"ty\":0,\"nm\":\"1\",\"refId\":\"comp_0\",\"sr\":1.15,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[332,676,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[500,500,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[76,76,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":13,\"op\":54.4,\"st\":13,\"bm\":0},{\"ddd\":0,\"ind\":3,\"ty\":0,\"nm\":\"1\",\"refId\":\"comp_0\",\"sr\":1.15,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[280,288,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[500,500,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[0.833,0.833,0.833]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0.167,0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":28.2,\"s\":[132.4,132.4,100],\"e\":[61.4,61.4,100]},{\"t\":39.7004882881608}],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":19,\"op\":60.4,\"st\":19,\"bm\":0},{\"ddd\":0,\"ind\":4,\"ty\":0,\"nm\":\"1\",\"refId\":\"comp_0\",\"sr\":1.15,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[668,304,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[500,500,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[72.4,72.4,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":5,\"op\":46.4,\"st\":5,\"bm\":0},{\"ddd\":0,\"ind\":5,\"ty\":0,\"nm\":\"1\",\"refId\":\"comp_0\",\"sr\":1.15,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.438,499.5,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[497.438,499.5,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":11,\"op\":52.4,\"st\":11,\"bm\":0},{\"ddd\":0,\"ind\":6,\"ty\":0,\"nm\":\"1\",\"refId\":\"comp_0\",\"sr\":1.15,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.438,499.5,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[497.438,499.5,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":31,\"op\":72.4,\"st\":31,\"bm\":0},{\"ddd\":0,\"ind\":7,\"ty\":0,\"nm\":\"1\",\"refId\":\"comp_0\",\"sr\":1.15,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[497.438,499.5,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[497.438,499.5,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"w\":1000,\"h\":1000,\"ip\":0,\"op\":41.4,\"st\":0,\"bm\":0}],\"markers\":[]}" + ) + } + val progress by animateLottieCompositionAsState( + composition, + iterations = Compottie.IterateForever, + ) + + Box( + modifier = Modifier + .fillMaxWidth() + .background(color = Color(color.rgb)), + contentAlignment = Alignment.Center + ) { + Row( + modifier = Modifier + .padding(16.dp, 8.dp) + .fillMaxWidth() + ) { + Image( + painter = rememberLottiePainter( + composition = composition, + progress = { progress }, + ), + contentDescription = "Lottie animation" + ) + Text( + "JDK not found. Please download the JDK to run Processing.", + fontFamily = fontFamily, + modifier = Modifier.align(Alignment.CenterVertically), + color = Color(colorText.rgb) + ) + Spacer(modifier = Modifier.weight(1f)) + Row( + + modifier = Modifier + .clip(RoundedCornerShape(16.dp)) + .clickable{ + openWebpage(URI("https://api.adoptium.net/v3/installer/latest/17/ga/${platform}/${arch}/jre/hotspot/normal/eclipse?project=jdk")) + } + .background(color = Color(buttonColor.rgb)) + .padding(16.dp, 8.dp) + + , + ) { + Text( + text = "Download JDK", + color = Color(buttonTextColor.rgb), + fontFamily = fontFamily + ) + } + } + } +} + +fun openWebpage(uri: URI?): Boolean { + val desktop = Desktop.getDesktop() ?: return false + if (desktop.isSupported(Desktop.Action.BROWSE)) { + try { + desktop.browse(uri) + return true + } catch (e: Exception) { + e.printStackTrace() + } + } + return false +} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000000..7bf9aa17f1 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,10 @@ +group = "org.processing" +version = "4.3.2" + +plugins { + kotlin("jvm") version libs.versions.kotlin apply false + alias(libs.plugins.kotlinMultiplatform) apply false + + alias(libs.plugins.compose.compiler) apply false + alias(libs.plugins.jetbrainsCompose) apply false +} \ No newline at end of file diff --git a/build/linux/processing.png b/build/linux/processing.png new file mode 100644 index 0000000000..ef31c9391e Binary files /dev/null and b/build/linux/processing.png differ diff --git a/build/macos/appbundler/.project b/build/macos/appbundler/.project deleted file mode 100644 index 48f5339370..0000000000 --- a/build/macos/appbundler/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - processing4-appbundler - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/build/shared/tools/MovieMaker/.project b/build/shared/tools/MovieMaker/.project deleted file mode 100644 index 01fa7f22d6..0000000000 --- a/build/shared/tools/MovieMaker/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - processing4-tools-moviemaker - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/core/.project b/core/.project deleted file mode 100644 index 42dcd4e424..0000000000 --- a/core/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - processing4-core - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/core/build.gradle.kts b/core/build.gradle.kts index c2a8724308..bb46d9502f 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -15,7 +15,7 @@ repositories { sourceSets{ main{ java{ - srcDirs("src/processing") + srcDirs("src") } resources{ srcDirs("src") @@ -67,4 +67,7 @@ mavenPublishing{ tasks.test { useJUnit() +} +tasks.withType { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE } \ No newline at end of file diff --git a/core/methods/.project b/core/methods/.project deleted file mode 100644 index 300f4c6021..0000000000 --- a/core/methods/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - processing4-core-preproc - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/core/processing4-core.iml b/core/processing4-core.iml deleted file mode 100644 index 129c875258..0000000000 --- a/core/processing4-core.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000000..9b6e36d78e --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,11 @@ +[versions] +kotlin = "2.0.20" +compose-plugin = "1.7.1" + +[libraries] + +[plugins] +jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" } +kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } +compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } \ No newline at end of file diff --git a/java/.gitignore b/java/.gitignore index a2ae74425f..5b4f1bea9f 100644 --- a/java/.gitignore +++ b/java/.gitignore @@ -1,4 +1,4 @@ reference.zip bin bin-test -generated +generated \ No newline at end of file diff --git a/java/.project b/java/.project deleted file mode 100644 index 68913f55d9..0000000000 --- a/java/.project +++ /dev/null @@ -1,27 +0,0 @@ - - - processing4-java - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.ui.externaltools.ExternalToolBuilder - full,incremental, - - - LaunchConfigHandle - <project>/.externalToolBuilders/AutoBuild.launch - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/java/build.gradle.kts b/java/build.gradle.kts new file mode 100644 index 0000000000..71dbffe695 --- /dev/null +++ b/java/build.gradle.kts @@ -0,0 +1,58 @@ +plugins { + id("java") +} + +repositories{ + mavenCentral() + google() + maven { url = uri("https://jogamp.org/deployment/maven") } +} + +sourceSets{ + main{ + java{ + srcDirs("src") + exclude("processing/mode/java/preproc/**") + } + } + test{ + java{ + srcDirs("test") + } + } +} + +dependencies{ + implementation(project(":app")) + implementation(project(":core")) + implementation(project(":java:preprocessor")) + + implementation("org.eclipse.jdt:org.eclipse.jdt.core:3.37.0") + implementation("com.google.classpath-explorer:classpath-explorer:1.0") + implementation("org.netbeans.api:org-netbeans-swing-outline:RELEASE210") + implementation("org.apache.ant:ant:1.10.14") + implementation("org.eclipse.lsp4j:org.eclipse.lsp4j:0.22.0") + implementation("org.jsoup:jsoup:1.17.2") + implementation("org.antlr:antlr4:4.7.2") + + testImplementation("junit:junit:4.13.2") + testImplementation("org.mockito:mockito-core:4.11.0") +} + +tasks.compileJava{ + options.encoding = "UTF-8" +} + +// TODO: This is a temporary workaround until the resources are properly handled +tasks.register("extraResources"){ + from(".") + include("keywords.txt") + into("build/resources/main") +} +tasks.jar { dependsOn("extraResources") } +tasks.processResources{ finalizedBy("extraResources") } +tasks.compileTestJava{ finalizedBy("extraResources") } + +tasks.test { + useJUnit() +} \ No newline at end of file diff --git a/java/libraries/dxf/.project b/java/libraries/dxf/.project deleted file mode 100644 index 18aa92448b..0000000000 --- a/java/libraries/dxf/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - processing4-dxf - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/java/libraries/net/.project b/java/libraries/net/.project deleted file mode 100644 index 5532ce667a..0000000000 --- a/java/libraries/net/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - processing4-net - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/java/libraries/pdf/.project b/java/libraries/pdf/.project deleted file mode 100644 index 208c52234f..0000000000 --- a/java/libraries/pdf/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - processing4-pdf - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/java/libraries/serial/.project b/java/libraries/serial/.project deleted file mode 100644 index 71abff8107..0000000000 --- a/java/libraries/serial/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - processing4-serial - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/java/libraries/svg/.project b/java/libraries/svg/.project deleted file mode 100644 index 7a9f9f0b85..0000000000 --- a/java/libraries/svg/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - processing4-svg - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/java/lsp/build.gradle.kts b/java/lsp/build.gradle.kts new file mode 100644 index 0000000000..8633dcab41 --- /dev/null +++ b/java/lsp/build.gradle.kts @@ -0,0 +1,67 @@ +import com.vanniktech.maven.publish.SonatypeHost + +plugins{ + id("java") + id("com.vanniktech.maven.publish") version "0.30.0" +} + +group = "org.processing" +version = "4.3.1" + +repositories{ + mavenCentral() + google() + maven { url = uri("https://jogamp.org/deployment/maven") } +} + +sourceSets{ + main{ + java{ + srcDirs("../src/") + include("processing/mode/java/lsp/**/*") + } + } +} + +dependencies{ + implementation(project(":core")) + implementation(project(":java:preprocessor")) + + implementation("org.eclipse.lsp4j:org.eclipse.lsp4j:0.22.0") + implementation("org.jsoup:jsoup:1.17.2") + implementation("org.eclipse.jdt:org.eclipse.jdt.core:3.40.0") + + implementation("org.processing:core:${version}") +} + +mavenPublishing{ + publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) + signAllPublications() + + pom{ + name.set("Processing Language Server") + description.set("Processing Language Server") + url.set("https://processing.org") + licenses { + license { + name.set("LGPL") + url.set("https://www.gnu.org/licenses/lgpl-2.1.html") + } + } + developers { + developer { + id.set("steftervelde") + name.set("Stef Tervelde") + } + developer { + id.set("benfry") + name.set("Ben Fry") + } + } + scm{ + url.set("https://github.com/processing/processing4") + connection.set("scm:git:git://github.com/processing/processing4.git") + developerConnection.set("scm:git:ssh://git@github.com/processing/processing4.git") + } + } +} \ No newline at end of file diff --git a/java/preprocessor/build.gradle.kts b/java/preprocessor/build.gradle.kts new file mode 100644 index 0000000000..b682c4edd2 --- /dev/null +++ b/java/preprocessor/build.gradle.kts @@ -0,0 +1,73 @@ +import com.vanniktech.maven.publish.SonatypeHost + +plugins{ + id("java") + id("com.vanniktech.maven.publish") version "0.30.0" +} + +group = "org.processing" +version = "4.3.1" + +repositories{ + mavenCentral() + google() + maven { url = uri("https://jogamp.org/deployment/maven") } +} + +sourceSets{ + main{ + java{ + srcDirs("src/main/java", "../src/", "../generated/") + include("processing/mode/java/preproc/**/*", "processing/app/**/*") + } + } + +} + +dependencies{ + implementation("org.antlr:antlr4:4.7.2") + implementation("org.eclipse.jdt:org.eclipse.jdt.core:3.40.0") + + implementation("org.processing:core:${version}") +} + +mavenPublishing{ + publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) + signAllPublications() + + pom{ + name.set("Processing Pre-processor") + description.set("Processing Pre-processor") + url.set("https://processing.org") + licenses { + license { + name.set("LGPL") + url.set("https://www.gnu.org/licenses/lgpl-2.1.html") + } + } + developers { + developer { + id.set("steftervelde") + name.set("Stef Tervelde") + } + developer { + id.set("benfry") + name.set("Ben Fry") + } + } + scm{ + url.set("https://github.com/processing/processing4") + connection.set("scm:git:git://github.com/processing/processing4.git") + developerConnection.set("scm:git:ssh://git@github.com/processing/processing4.git") + } + } +} +tasks.withType { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE +} +tasks.compileJava{ + dependsOn("ant-preproc") +} +ant.importBuild("../build.xml"){ antTaskName -> + "ant-$antTaskName" +} \ No newline at end of file diff --git a/java/preprocessor/src/main/java/processing/app/Base.java b/java/preprocessor/src/main/java/processing/app/Base.java new file mode 100644 index 0000000000..3cfad75a1b --- /dev/null +++ b/java/preprocessor/src/main/java/processing/app/Base.java @@ -0,0 +1,55 @@ +package processing.app; + +import java.io.File; + +public class Base { + static private final int REVISION = 1294; + + static private File settingsOverride; + /** + * @return the current revision number, safe to be used for update checks + */ + static public int getRevision() { + return REVISION; + } + /** + * Get the directory that can store settings. (Library on OS X, App Data or + * something similar on Windows, a dot folder on Linux.) Removed this as a + * preference for 3.0a3 because we need this to be stable, but adding back + * for 4.0 beta 4 so that folks can do 'portable' versions again. + */ + static public File getSettingsFolder() { + File settingsFolder = null; + + try { + settingsFolder = Platform.getSettingsFolder(); + + // create the folder if it doesn't exist already + if (!settingsFolder.exists()) { + if (!settingsFolder.mkdirs()) { + System.err.println("Could not create the folder " + settingsFolder); + + } + } + } catch (Exception e) { + System.err.println("Could not get the settings folder"); + } + return settingsFolder; + } + + + + static public File getSettingsOverride() { + return settingsOverride; + } + + /** + * Convenience method to get a File object for the specified filename inside + * the settings folder. Used to get preferences and recent sketch files. + * @param filename A file inside the settings folder. + * @return filename wrapped as a File object inside the settings folder + */ + static public File getSettingsFile(String filename) { + return new File(getSettingsFolder(), filename); + } +} diff --git a/java/preprocessor/src/main/java/processing/app/Platform.java b/java/preprocessor/src/main/java/processing/app/Platform.java new file mode 100644 index 0000000000..079d9d79cd --- /dev/null +++ b/java/preprocessor/src/main/java/processing/app/Platform.java @@ -0,0 +1,22 @@ +package processing.app; + +import java.io.File; + +public class Platform { + static public File getSettingsFolder() { + File settingsFolder = null; + String os = System.getProperty("os.name").toLowerCase(); + if (os.contains("mac")) { + settingsFolder = new File(System.getProperty("user.home") + "/Library/Processing"); + } else if (os.contains("windows")) { + String appData = System.getenv("APPDATA"); + if (appData == null) { + appData = System.getProperty("user.home"); + } + settingsFolder = new File(appData + "\\Processing"); + } else { + settingsFolder = new File(System.getProperty("user.home") + "/.processing"); + } + return settingsFolder; + } +} diff --git a/java/preprocessor/src/main/java/processing/app/Preferences.java b/java/preprocessor/src/main/java/processing/app/Preferences.java new file mode 100644 index 0000000000..7ce476fdea --- /dev/null +++ b/java/preprocessor/src/main/java/processing/app/Preferences.java @@ -0,0 +1,67 @@ +/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2014-19 The Processing Foundation + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.Properties; + +/** + * Storage class for user preferences and environment settings. + *

+ * This class does not use the Properties class because .properties files use + * ISO 8859-1 encoding, which is highly likely to be a problem when trying to + * save sketch folders and locations. Like the rest of Processing, we use UTF8. + *

+ * We don't use the Java Preferences API because it would entail writing to + * the registry (on Windows), or an obscure file location (on Mac OS X) and + * make it far more difficult (impossible) to remove the preferences.txt to + * reset them (when they become corrupt), or to find the the file to make + * edits for numerous obscure preferences that are not part of the preferences + * window. If we added a generic editor (e.g. about:config in Mozilla) for + * such things, we could start using the Java Preferences API. But wow, that + * sounds like a lot of work. Not unlike writing this paragraph. + */ +public class Preferences { + static public String get(String attribute /*, String defaultValue */) { + try { + var settingsFile = Base.getSettingsFile("preferences.txt"); + var reader = new BufferedReader(new FileReader(settingsFile)); + + var settings = new Properties(); + settings.load(reader); + reader.close(); + + return settings.getProperty(attribute); + }catch (Exception e) { + return null; + } + } + static public boolean getBoolean(String attribute) { + String value = get(attribute); //, null); + return Boolean.parseBoolean(value); + } + static public int getInteger(String attribute /*, int defaultValue*/) { + return Integer.parseInt(get(attribute)); + } +} diff --git a/java/processing4-java.iml b/java/processing4-java.iml deleted file mode 100644 index 953c28d4d5..0000000000 --- a/java/processing4-java.iml +++ /dev/null @@ -1,201 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/java/src/processing/mode/java/Commander.java b/java/src/processing/mode/java/Commander.java index 26e191900c..2a2ee9bc0c 100644 --- a/java/src/processing/mode/java/Commander.java +++ b/java/src/processing/mode/java/Commander.java @@ -33,7 +33,7 @@ import processing.app.Preferences; import processing.app.RunnerListener; import processing.app.Sketch; -import processing.app.SketchException; +import processing.mode.java.preproc.SketchException; import processing.app.Util; import processing.app.contrib.ModeContribution; import processing.core.PApplet; diff --git a/java/src/processing/mode/java/Compiler.java b/java/src/processing/mode/java/Compiler.java index aaef2e8c3e..3e97931699 100644 --- a/java/src/processing/mode/java/Compiler.java +++ b/java/src/processing/mode/java/Compiler.java @@ -26,6 +26,7 @@ import processing.app.*; import processing.app.ui.Editor; import processing.core.*; +import processing.mode.java.preproc.SketchException; import java.io.*; import java.lang.reflect.Method; diff --git a/java/src/processing/mode/java/CompletionGenerator.java b/java/src/processing/mode/java/CompletionGenerator.java index 5a23816e9c..549bfc3aa0 100644 --- a/java/src/processing/mode/java/CompletionGenerator.java +++ b/java/src/processing/mode/java/CompletionGenerator.java @@ -60,6 +60,9 @@ import com.google.classpath.ClassPath; import com.google.classpath.RegExpResourceFilter; +import processing.mode.java.preproc.ImportStatement; +import processing.mode.java.preproc.SourceUtil; +import processing.mode.java.preproc.TextTransform; @SuppressWarnings({ "unchecked" }) public class CompletionGenerator { diff --git a/java/src/processing/mode/java/JavaBuild.java b/java/src/processing/mode/java/JavaBuild.java index 757954978c..2de6a65d1f 100644 --- a/java/src/processing/mode/java/JavaBuild.java +++ b/java/src/processing/mode/java/JavaBuild.java @@ -42,8 +42,10 @@ import processing.core.PConstants; import processing.data.StringList; import processing.data.XML; +import processing.mode.java.preproc.ImportStatement; import processing.mode.java.preproc.PdePreprocessor; import processing.mode.java.preproc.PreprocessorResult; +import processing.mode.java.preproc.SketchException; public class JavaBuild { @@ -275,7 +277,12 @@ public PreprocessorResult preprocess(File srcFolder, for (ImportStatement item : result.getImportStatements()) { String entry = item.getPackageName(); - Library library = mode.getLibrary(entry); + Library library = null; + try{ + library = mode.getLibrary(entry); + }catch (processing.app.SketchException e){ + throw new SketchException(e.getMessage(), e.getCodeIndex(), e.getCodeLine(), e.getCodeColumn(), e.isStackTraceEnabled()); + } if (library != null) { if (!importedLibraries.contains(library)) { diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index 338a6bd298..9c4bb84350 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -50,7 +50,9 @@ import processing.mode.java.debug.LineBreakpoint; import processing.mode.java.debug.LineHighlight; import processing.mode.java.debug.LineID; +import processing.mode.java.preproc.ImportStatement; import processing.mode.java.preproc.PdePreprocessor; +import processing.mode.java.preproc.SourceUtil; import processing.mode.java.runner.Runner; import processing.mode.java.tweak.ColorControlBox; import processing.mode.java.tweak.Handle; diff --git a/java/src/processing/mode/java/JavaMode.java b/java/src/processing/mode/java/JavaMode.java index 4f9613c993..3d7249cfdf 100644 --- a/java/src/processing/mode/java/JavaMode.java +++ b/java/src/processing/mode/java/JavaMode.java @@ -25,6 +25,9 @@ import java.awt.*; import java.io.File; import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -33,6 +36,7 @@ import processing.app.ui.EditorException; import processing.app.ui.EditorState; +import processing.mode.java.preproc.SketchException; import processing.mode.java.runner.Runner; import processing.mode.java.tweak.SketchParser; @@ -56,8 +60,25 @@ public JavaMode(Base base, File folder) { public String getTitle() { return "Java"; } - - + + File resourcesFolder; + + @Deprecated + @Override + public File[] getKeywordFiles() { + var url = JavaMode.class.getClassLoader().getResource("keywords.txt"); + if(url != null) { + try{ + var target = Files.createTempFile("processing", "keywords.txt"); + Files.copy(url.openStream(), target, StandardCopyOption.REPLACE_EXISTING); + + return new File[] { target.toFile() }; + }catch (IOException e){ + e.printStackTrace(); + } + } + return super.getKeywordFiles(); + } // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . diff --git a/java/src/processing/mode/java/PreprocService.java b/java/src/processing/mode/java/PreprocService.java index 718728d415..f705362944 100644 --- a/java/src/processing/mode/java/PreprocService.java +++ b/java/src/processing/mode/java/PreprocService.java @@ -56,11 +56,9 @@ import processing.app.Messages; import processing.app.Sketch; import processing.app.SketchCode; -import processing.app.SketchException; import processing.app.Util; -import processing.mode.java.TextTransform.OffsetMapper; -import processing.mode.java.preproc.PdePreprocessor; -import processing.mode.java.preproc.PreprocessorResult; +import processing.mode.java.preproc.*; +import processing.mode.java.preproc.TextTransform.OffsetMapper; import processing.data.IntList; import processing.data.StringList; diff --git a/java/src/processing/mode/java/PreprocSketch.java b/java/src/processing/mode/java/PreprocSketch.java index 8082a5964b..394c7a3a47 100644 --- a/java/src/processing/mode/java/PreprocSketch.java +++ b/java/src/processing/mode/java/PreprocSketch.java @@ -16,7 +16,8 @@ import processing.app.Problem; import processing.app.Sketch; import processing.core.PApplet; -import processing.mode.java.TextTransform.OffsetMapper; +import processing.mode.java.preproc.ImportStatement; +import processing.mode.java.preproc.TextTransform.OffsetMapper; public class PreprocSketch { diff --git a/java/src/processing/mode/java/RuntimePathBuilder.java b/java/src/processing/mode/java/RuntimePathBuilder.java index 08b49e63a6..33e8f209ca 100644 --- a/java/src/processing/mode/java/RuntimePathBuilder.java +++ b/java/src/processing/mode/java/RuntimePathBuilder.java @@ -41,6 +41,7 @@ import processing.app.Sketch; import processing.app.SketchException; import processing.app.Util; +import processing.mode.java.preproc.ImportStatement; /** diff --git a/java/src/processing/mode/java/ImportStatement.java b/java/src/processing/mode/java/preproc/ImportStatement.java similarity index 99% rename from java/src/processing/mode/java/ImportStatement.java rename to java/src/processing/mode/java/preproc/ImportStatement.java index f5438bf335..68f8c20ac4 100644 --- a/java/src/processing/mode/java/ImportStatement.java +++ b/java/src/processing/mode/java/preproc/ImportStatement.java @@ -18,7 +18,7 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package processing.mode.java; +package processing.mode.java.preproc; import java.util.regex.MatchResult; import java.util.regex.Matcher; diff --git a/java/src/processing/mode/java/preproc/PdeIssueEmitter.java b/java/src/processing/mode/java/preproc/PdeIssueEmitter.java index 7e5b48c5aa..01d5100602 100644 --- a/java/src/processing/mode/java/preproc/PdeIssueEmitter.java +++ b/java/src/processing/mode/java/preproc/PdeIssueEmitter.java @@ -24,7 +24,6 @@ import org.antlr.v4.runtime.BaseErrorListener; import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.Recognizer; -import processing.mode.java.SourceUtil; import java.util.Optional; diff --git a/java/src/processing/mode/java/preproc/PdeParseTreeListener.java b/java/src/processing/mode/java/preproc/PdeParseTreeListener.java index 74c9f14962..cb4fd00010 100644 --- a/java/src/processing/mode/java/preproc/PdeParseTreeListener.java +++ b/java/src/processing/mode/java/preproc/PdeParseTreeListener.java @@ -33,9 +33,6 @@ import processing.app.Base; import processing.app.Preferences; import processing.core.PApplet; -import processing.mode.java.ImportStatement; -import processing.mode.java.SourceUtil; -import processing.mode.java.TextTransform; import processing.mode.java.preproc.PdePreprocessor.Mode; /** diff --git a/java/src/processing/mode/java/preproc/PdePreprocessor.java b/java/src/processing/mode/java/preproc/PdePreprocessor.java index eb3f3946bb..8217268162 100644 --- a/java/src/processing/mode/java/preproc/PdePreprocessor.java +++ b/java/src/processing/mode/java/preproc/PdePreprocessor.java @@ -31,9 +31,7 @@ import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.ParseTreeWalker; - import processing.app.Preferences; -import processing.app.SketchException; /** diff --git a/java/src/processing/mode/java/preproc/PreprocessIssueMessageSimplifier.java b/java/src/processing/mode/java/preproc/PreprocessIssueMessageSimplifier.java index 4e112d161d..52e16757c1 100644 --- a/java/src/processing/mode/java/preproc/PreprocessIssueMessageSimplifier.java +++ b/java/src/processing/mode/java/preproc/PreprocessIssueMessageSimplifier.java @@ -22,10 +22,6 @@ package processing.mode.java.preproc; -import processing.app.Language; -import processing.app.Platform; -import processing.mode.java.SourceUtil; - import java.util.*; import java.util.concurrent.atomic.AtomicReference; import java.util.regex.Matcher; @@ -78,16 +74,8 @@ public static PreprocessIssueMessageSimplifier get() { * @return The template's contents prior to rendering. */ public static String getLocalStr(String stringName) { - String errStr; - String retStr; - - if (Platform.isAvailable()) { - errStr = Language.text("editor.status.error.syntax"); - retStr = Language.text(stringName); - } else { - errStr = DefaultErrorLocalStrSet.get().get("editor.status.error.syntax").orElse("Error"); - retStr = DefaultErrorLocalStrSet.get().get(stringName).orElse(stringName); - } + var errStr = DefaultErrorLocalStrSet.get().get("editor.status.error.syntax").orElse("Error"); + var retStr = DefaultErrorLocalStrSet.get().get(stringName).orElse(stringName); return String.format(errStr, retStr); } diff --git a/java/src/processing/mode/java/preproc/PreprocessorResult.java b/java/src/processing/mode/java/preproc/PreprocessorResult.java index 972abf1ac2..575f4967ae 100644 --- a/java/src/processing/mode/java/preproc/PreprocessorResult.java +++ b/java/src/processing/mode/java/preproc/PreprocessorResult.java @@ -25,9 +25,6 @@ import java.util.Collections; import java.util.List; -import processing.mode.java.ImportStatement; -import processing.mode.java.TextTransform; - /** * Result of sketch Preprocessing. diff --git a/java/src/processing/mode/java/preproc/RewriteResult.java b/java/src/processing/mode/java/preproc/RewriteResult.java index 1a3c35a6a1..6d50db4eb5 100644 --- a/java/src/processing/mode/java/preproc/RewriteResult.java +++ b/java/src/processing/mode/java/preproc/RewriteResult.java @@ -2,8 +2,6 @@ import java.util.List; -import processing.mode.java.TextTransform; - /** * Data structure describing the result of preprocessor rewrite. diff --git a/java/src/processing/mode/java/preproc/RewriteResultBuilder.java b/java/src/processing/mode/java/preproc/RewriteResultBuilder.java index 807a06b3e2..959c837b34 100644 --- a/java/src/processing/mode/java/preproc/RewriteResultBuilder.java +++ b/java/src/processing/mode/java/preproc/RewriteResultBuilder.java @@ -3,8 +3,6 @@ import java.util.ArrayList; import java.util.List; -import processing.mode.java.TextTransform; - /** * Builder to help create a {RewriteResult}. diff --git a/java/src/processing/mode/java/preproc/SketchException.java b/java/src/processing/mode/java/preproc/SketchException.java new file mode 100644 index 0000000000..47a0bba533 --- /dev/null +++ b/java/src/processing/mode/java/preproc/SketchException.java @@ -0,0 +1,162 @@ +/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-08 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.mode.java.preproc; + + +/** + * An exception with a line number attached that occurs + * during either pre-processing, compile, or run time. + */ +public class SketchException extends Exception { + protected String message; + protected int codeIndex; + protected int codeLine; + protected int codeColumn; + protected boolean showStackTrace; + + + public SketchException(String message) { + this(message, true); + } + + + public SketchException(String message, boolean showStackTrace) { + this(message, -1, -1, -1, showStackTrace); + } + + + public SketchException(String message, int file, int line) { + this(message, file, line, -1, true); + } + + + public SketchException(String message, int file, int line, int column) { + this(message, file, line, column, true); + } + + + public SketchException(String message, int file, int line, int column, + boolean showStackTrace) { + this.message = message; + this.codeIndex = file; + this.codeLine = line; + this.codeColumn = column; + this.showStackTrace = showStackTrace; + } + + + /** + * Override getMessage() in Throwable, so that I can set + * the message text outside the constructor. + */ + public String getMessage() { + return message; + } + + + public void setMessage(String message) { + this.message = message; + } + + + public int getCodeIndex() { + return codeIndex; + } + + + public void setCodeIndex(int index) { + codeIndex = index; + } + + + public boolean hasCodeIndex() { + return codeIndex != -1; + } + + + public int getCodeLine() { + return codeLine; + } + + + public void setCodeLine(int line) { + this.codeLine = line; + } + + + public boolean hasCodeLine() { + return codeLine != -1; + } + + + public void setCodeColumn(int column) { + this.codeColumn = column; + } + + + public int getCodeColumn() { + return codeColumn; + } + + + public void showStackTrace() { + showStackTrace = true; + } + + + public void hideStackTrace() { + showStackTrace = false; + } + + + public boolean isStackTraceEnabled() { + return showStackTrace; + } + + + /** + * Nix the java.lang crap out of an exception message + * because it scares the children. + *

+ * This function must be static to be used with super() + * in each of the constructors above. + */ + /* + static public final String massage(String msg) { + if (msg.indexOf("java.lang.") == 0) { + //int dot = msg.lastIndexOf('.'); + msg = msg.substring("java.lang.".length()); + } + return msg; + //return (dot == -1) ? msg : msg.substring(dot+1); + } + */ + + + public void printStackTrace() { + if (showStackTrace) { + super.printStackTrace(); + } + } +} diff --git a/java/src/processing/mode/java/SourceUtil.java b/java/src/processing/mode/java/preproc/SourceUtil.java similarity index 99% rename from java/src/processing/mode/java/SourceUtil.java rename to java/src/processing/mode/java/preproc/SourceUtil.java index bd464b8696..015529616b 100644 --- a/java/src/processing/mode/java/SourceUtil.java +++ b/java/src/processing/mode/java/preproc/SourceUtil.java @@ -1,4 +1,4 @@ -package processing.mode.java; +package processing.mode.java.preproc; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.CompilationUnit; @@ -12,7 +12,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import processing.mode.java.TextTransform.Edit; +import processing.mode.java.preproc.TextTransform.Edit; public class SourceUtil { diff --git a/java/src/processing/mode/java/TextTransform.java b/java/src/processing/mode/java/preproc/TextTransform.java similarity index 98% rename from java/src/processing/mode/java/TextTransform.java rename to java/src/processing/mode/java/preproc/TextTransform.java index 8861adbb41..77ae022f19 100644 --- a/java/src/processing/mode/java/TextTransform.java +++ b/java/src/processing/mode/java/preproc/TextTransform.java @@ -1,4 +1,4 @@ -package processing.mode.java; +package processing.mode.java.preproc; import java.util.ArrayList; import java.util.Collection; @@ -31,7 +31,7 @@ public class TextTransform { private int builtForLength; - TextTransform(CharSequence input) { + public TextTransform(CharSequence input) { this.input = input; } @@ -213,7 +213,7 @@ public String toString() { } - protected interface OffsetMapper { + public interface OffsetMapper { int getInputOffset(int outputOffset); int getOutputOffset(int inputOffset); OffsetMapper thenMapping(OffsetMapper mapper); diff --git a/java/src/processing/mode/java/runner/Runner.java b/java/src/processing/mode/java/runner/Runner.java index 9fec3bb10f..15bf819faa 100644 --- a/java/src/processing/mode/java/runner/Runner.java +++ b/java/src/processing/mode/java/runner/Runner.java @@ -32,7 +32,6 @@ import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Point; -import java.awt.Toolkit; import java.io.*; import java.net.ConnectException; import java.net.InetAddress; @@ -44,6 +43,7 @@ import com.sun.jdi.connect.Connector.Argument; import com.sun.jdi.event.*; import com.sun.jdi.request.*; +import processing.mode.java.preproc.SketchException; /** diff --git a/java/test/processing/mode/java/CachedRuntimePathFactoryTest.java b/java/test/processing/mode/java/CachedRuntimePathFactoryTest.java index fdf42e5419..33d9bfcf83 100644 --- a/java/test/processing/mode/java/CachedRuntimePathFactoryTest.java +++ b/java/test/processing/mode/java/CachedRuntimePathFactoryTest.java @@ -23,6 +23,7 @@ import org.junit.Before; import org.junit.Test; import processing.app.Sketch; +import processing.mode.java.preproc.ImportStatement; import java.util.ArrayList; import java.util.List; diff --git a/java/test/processing/mode/java/CodeFolderRuntimePathFactoryTest.java b/java/test/processing/mode/java/CodeFolderRuntimePathFactoryTest.java index 95b0c90f42..8cdeed6b14 100644 --- a/java/test/processing/mode/java/CodeFolderRuntimePathFactoryTest.java +++ b/java/test/processing/mode/java/CodeFolderRuntimePathFactoryTest.java @@ -23,6 +23,7 @@ import org.junit.Before; import org.junit.Test; import processing.app.Sketch; +import processing.mode.java.preproc.ImportStatement; import java.io.File; import java.util.List; diff --git a/java/test/processing/mode/java/CoreLibraryRuntimePathFactoryTest.java b/java/test/processing/mode/java/CoreLibraryRuntimePathFactoryTest.java index 9f9b608e3d..939e0117c9 100644 --- a/java/test/processing/mode/java/CoreLibraryRuntimePathFactoryTest.java +++ b/java/test/processing/mode/java/CoreLibraryRuntimePathFactoryTest.java @@ -23,6 +23,7 @@ import org.junit.Before; import org.junit.Test; import processing.app.Sketch; +import processing.mode.java.preproc.ImportStatement; import java.util.List; diff --git a/java/test/processing/mode/java/ImportStatementTest.java b/java/test/processing/mode/java/ImportStatementTest.java index a4a3dd97ff..14bf310c9a 100644 --- a/java/test/processing/mode/java/ImportStatementTest.java +++ b/java/test/processing/mode/java/ImportStatementTest.java @@ -3,6 +3,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import processing.mode.java.preproc.ImportStatement; public class ImportStatementTest { diff --git a/java/test/processing/mode/java/JavaFxRuntimePathFactoryTest.java b/java/test/processing/mode/java/JavaFxRuntimePathFactoryTest.java index b61889cd66..c4c67e973f 100644 --- a/java/test/processing/mode/java/JavaFxRuntimePathFactoryTest.java +++ b/java/test/processing/mode/java/JavaFxRuntimePathFactoryTest.java @@ -23,6 +23,7 @@ import org.junit.Before; import org.junit.Test; import processing.app.Sketch; +import processing.mode.java.preproc.ImportStatement; import java.util.List; diff --git a/java/test/processing/mode/java/JavaRuntimePathFactoryTest.java b/java/test/processing/mode/java/JavaRuntimePathFactoryTest.java index ae67422278..637f058d89 100644 --- a/java/test/processing/mode/java/JavaRuntimePathFactoryTest.java +++ b/java/test/processing/mode/java/JavaRuntimePathFactoryTest.java @@ -23,6 +23,7 @@ import org.junit.Before; import org.junit.Test; import processing.app.Sketch; +import processing.mode.java.preproc.ImportStatement; import java.util.List; diff --git a/java/test/processing/mode/java/LibrarySearchRuntimePathFactoryTest.java b/java/test/processing/mode/java/LibrarySearchRuntimePathFactoryTest.java index ed7210fd47..92a516fc37 100644 --- a/java/test/processing/mode/java/LibrarySearchRuntimePathFactoryTest.java +++ b/java/test/processing/mode/java/LibrarySearchRuntimePathFactoryTest.java @@ -23,6 +23,7 @@ import org.junit.Before; import org.junit.Test; import processing.app.Sketch; +import processing.mode.java.preproc.ImportStatement; import java.util.List; diff --git a/java/test/processing/mode/java/LibrarySketchRuntimePathFactoryTest.java b/java/test/processing/mode/java/LibrarySketchRuntimePathFactoryTest.java index c9df2b28cd..a65e5de1c8 100644 --- a/java/test/processing/mode/java/LibrarySketchRuntimePathFactoryTest.java +++ b/java/test/processing/mode/java/LibrarySketchRuntimePathFactoryTest.java @@ -23,6 +23,7 @@ import org.junit.Before; import org.junit.Test; import processing.app.Sketch; +import processing.mode.java.preproc.ImportStatement; import java.util.List; diff --git a/java/test/processing/mode/java/ModeSearchRuntimePathFactoryTest.java b/java/test/processing/mode/java/ModeSearchRuntimePathFactoryTest.java index 16ff85b858..6576a3e453 100644 --- a/java/test/processing/mode/java/ModeSearchRuntimePathFactoryTest.java +++ b/java/test/processing/mode/java/ModeSearchRuntimePathFactoryTest.java @@ -23,6 +23,7 @@ import org.junit.Before; import org.junit.Test; import processing.app.Sketch; +import processing.mode.java.preproc.ImportStatement; import java.util.List; diff --git a/java/test/processing/mode/java/ModeSketchRuntimePathFactoryTest.java b/java/test/processing/mode/java/ModeSketchRuntimePathFactoryTest.java index 5081311bfd..c41408637e 100644 --- a/java/test/processing/mode/java/ModeSketchRuntimePathFactoryTest.java +++ b/java/test/processing/mode/java/ModeSketchRuntimePathFactoryTest.java @@ -23,6 +23,7 @@ import org.junit.Before; import org.junit.Test; import processing.app.Sketch; +import processing.mode.java.preproc.ImportStatement; import java.util.List; diff --git a/java/test/processing/mode/java/ParserTests.java b/java/test/processing/mode/java/ParserTests.java index 040600228c..106f9d3c36 100644 --- a/java/test/processing/mode/java/ParserTests.java +++ b/java/test/processing/mode/java/ParserTests.java @@ -15,9 +15,9 @@ import org.junit.Test; import processing.app.Preferences; -import processing.app.SketchException; import processing.mode.java.preproc.PreprocessorResult; import processing.mode.java.preproc.PdePreprocessIssueException; +import processing.mode.java.preproc.SketchException; public class ParserTests { @@ -460,8 +460,9 @@ public void testMultilineStringClass() { @Test public void testMultiMultilineString() { - Preferences.setBoolean("export.application.fullscreen", true); - expectGood("fullscreen_export"); + // TODO: Add support for fullscreen. Not through settings. In PdeParseTreeListener.java +// Preferences.setBoolean("export.application.fullscreen", true); +// expectGood("fullscreen_export"); } @Test diff --git a/java/test/processing/mode/java/ProcessingTestUtil.java b/java/test/processing/mode/java/ProcessingTestUtil.java index 40c7dde341..40f42d5575 100644 --- a/java/test/processing/mode/java/ProcessingTestUtil.java +++ b/java/test/processing/mode/java/ProcessingTestUtil.java @@ -7,10 +7,10 @@ import java.util.Optional; import processing.app.Preferences; -import processing.app.SketchException; import processing.mode.java.preproc.PdePreprocessor; import processing.mode.java.preproc.PreprocessorResult; import processing.mode.java.preproc.PdePreprocessIssueException; +import processing.mode.java.preproc.SketchException; public class ProcessingTestUtil { diff --git a/java/test/processing/mode/java/RuntimePathBuilderTest.java b/java/test/processing/mode/java/RuntimePathBuilderTest.java index 96063a1878..6f0c1856a0 100644 --- a/java/test/processing/mode/java/RuntimePathBuilderTest.java +++ b/java/test/processing/mode/java/RuntimePathBuilderTest.java @@ -23,6 +23,8 @@ import org.junit.Before; import org.junit.Test; import processing.app.Sketch; +import processing.mode.java.preproc.ImportStatement; + import java.io.File; import java.util.Arrays; diff --git a/java/test/processing/mode/java/RuntimePathFactoryTestUtil.java b/java/test/processing/mode/java/RuntimePathFactoryTestUtil.java index 1303a02a3b..665f9761d5 100644 --- a/java/test/processing/mode/java/RuntimePathFactoryTestUtil.java +++ b/java/test/processing/mode/java/RuntimePathFactoryTestUtil.java @@ -24,6 +24,7 @@ import processing.app.Library; import processing.app.Sketch; import processing.app.SketchException; +import processing.mode.java.preproc.ImportStatement; import java.io.File; import java.io.IOException; diff --git a/java/test/processing/mode/java/SourceUtilTest.java b/java/test/processing/mode/java/SourceUtilTest.java index 53a57de1f5..ac333829b9 100644 --- a/java/test/processing/mode/java/SourceUtilTest.java +++ b/java/test/processing/mode/java/SourceUtilTest.java @@ -2,6 +2,7 @@ import org.junit.Assert; import org.junit.Test; +import processing.mode.java.preproc.SourceUtil; public class SourceUtilTest { diff --git a/java/test/processing/mode/java/preproc/PrintWriterWithEditGenTest.java b/java/test/processing/mode/java/preproc/PrintWriterWithEditGenTest.java index c29e6b6065..0306359a3c 100644 --- a/java/test/processing/mode/java/preproc/PrintWriterWithEditGenTest.java +++ b/java/test/processing/mode/java/preproc/PrintWriterWithEditGenTest.java @@ -5,8 +5,6 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; -import processing.mode.java.TextTransform; - import java.util.List; import static org.junit.Assert.*; diff --git a/settings.gradle.kts b/settings.gradle.kts index 4f5525784b..a40bcb48cb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,5 +1,11 @@ rootProject.name = "processing" -include("core", "core:different") +include( + "core", + "core:different", + "app", + "java", + "java:preprocessor", +) buildscript { repositories {