Merge branch 'processing:main' into gradle-preprocessor

This commit is contained in:
Stef Tervelde
2025-03-07 15:06:27 +01:00
committed by GitHub
29 changed files with 480 additions and 211 deletions
+37
View File
@@ -1428,6 +1428,43 @@
"contributions": [
"doc"
]
},
{
"login": "xinemata",
"name": "Xin Xin",
"avatar_url": "https://avatars.githubusercontent.com/u/9159424?v=4",
"profile": "https://github.com/xinemata",
"contributions": [
"eventOrganizing",
"ideas"
]
},
{
"login": "tracerstar",
"name": "Benjamin Fox",
"avatar_url": "https://avatars.githubusercontent.com/u/234190?v=4",
"profile": "http://benjaminfoxstudios.com",
"contributions": [
"code"
]
},
{
"login": "e1dem",
"name": "e1dem",
"avatar_url": "https://avatars.githubusercontent.com/u/32488297?v=4",
"profile": "https://github.com/e1dem",
"contributions": [
"code"
]
},
{
"login": "inteqam",
"name": "Aditya Chaudhary",
"avatar_url": "https://avatars.githubusercontent.com/u/104833943?v=4",
"profile": "https://github.com/inteqam",
"contributions": [
"code"
]
}
],
"repoType": "github",
+2 -2
View File
@@ -1,4 +1,4 @@
name: Pull Requests
name: Pull Requests with Gradle
on:
pull_request:
paths-ignore:
@@ -17,7 +17,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: [self-hosted, linux, ARM64]
- os: ubuntu-24.04-arm
os_prefix: linux
arch: aarch64
- os: ubuntu-latest
+1 -1
View File
@@ -55,7 +55,7 @@ jobs:
- name: Build Release
run: ant -noinput -buildfile build/build.xml ${{ matrix.os_prefix }}-dist -Dversion="${{ github.sha }}" -Dplatform=${{ matrix.os_prefix }}
- name: Add artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
id: upload
with:
name: processing-pr${{ github.event.pull_request.number }}-${{github.sha}}-${{ matrix.os_prefix }}-${{ matrix.arch }}-ant
+113
View File
@@ -0,0 +1,113 @@
name: Releases
on:
release:
types: [published]
jobs:
version:
runs-on: ubuntu-latest
outputs:
build_number: ${{ steps.tag_info.outputs.build_number }}
version: ${{ steps.tag_info.outputs.version }}
steps:
- name: Extract version and build number
id: tag_info
shell: bash
run: |
TAG_NAME="${GITHUB_REF#refs/tags/}"
BUILD_NUMBER=$(echo "$TAG_NAME" | cut -d'-' -f2)
VERSION=$(echo "$TAG_NAME" | cut -d'-' -f3)
# Set outputs for use in later jobs or steps
echo "build_number=$BUILD_NUMBER" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
publish:
name: Publish Processing Core to Maven Central
runs-on: ubuntu-latest
needs: version
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Build with Gradle
run: ./gradlew publish
env:
MAVEN_CENTRAL_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
MAVEN_CENTRAL_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_IN_MEMORY_KEY }}
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_IN_MEMORY_KEY_PASSWORD }}
ORG_GRADLE_PROJECT_version: ${{ needs.version.outputs.version }}
ORG_GRADLE_PROJECT_group: ${{ vars.PROCESSING_GROUP }}
build:
name: Publish Release for ${{ matrix.os_prefix }} (${{ matrix.arch }})
runs-on: ${{ matrix.os }}
needs: version
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, linux, ARM]
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: 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: Install Certificates for Code Signing
# if: ${{ matrix.os_prefix == 'macos' }}
# uses: apple-actions/import-codesign-certs@v3
# with:
# p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
# p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
- name: Build with Gradle
run: ./gradlew packageDistributionForCurrentOS
env:
ORG_GRADLE_PROJECT_version: ${{ needs.version.outputs.version }}
ORG_GRADLE_PROJECT_group: ${{ vars.PROCESSING_GROUP }}
- name: Upload binaries to release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: |
./app/build/compose/binaries/main/dmg/Processing-*.dmg
./app/build/compose/binaries/main/dmg/INSTRUCTIONS_FOR_TESTING.txt
./app/build/compose/binaries/main/msi/Processing-*.msi
./app/build/compose/binaries/main/deb/processing*.deb
file_glob: true
+7
View File
@@ -38,6 +38,7 @@ For a quick start:
1. Fork and clone the repository
1. Open it in IntelliJ IDEA
1. Wait for Gradle to sync
1. Next to the run Button, select the `Processing` Configuration
1. Hit Run
For more information and detailed instructions, follow our [How to Build Processing](BUILD.md) guide.
@@ -281,6 +282,12 @@ Add yourself to the contributors list [here](https://github.com/processing/proce
<td align="center" valign="top" width="16.66%"><a href="http://d.hatena.ne.jp/junology/"><img src="https://avatars.githubusercontent.com/u/1933073?v=4?s=120" width="120px;" alt="Junology"/><br /><sub><b>Junology</b></sub></a><br /><a href="https://github.com/processing/processing4/commits?author=Junology" title="Code">💻</a></td>
<td align="center" valign="top" width="16.66%"><a href="https://github.com/twisst"><img src="https://avatars.githubusercontent.com/u/2244463?v=4?s=120" width="120px;" alt="Jaap Meijers"/><br /><sub><b>Jaap Meijers</b></sub></a><br /><a href="https://github.com/processing/processing4/commits?author=twisst" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="16.66%"><a href="https://github.com/xinemata"><img src="https://avatars.githubusercontent.com/u/9159424?v=4?s=120" width="120px;" alt="Xin Xin"/><br /><sub><b>Xin Xin</b></sub></a><br /><a href="#eventOrganizing-xinemata" title="Event Organizing">📋</a> <a href="#ideas-xinemata" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="16.66%"><a href="http://benjaminfoxstudios.com"><img src="https://avatars.githubusercontent.com/u/234190?v=4?s=120" width="120px;" alt="Benjamin Fox"/><br /><sub><b>Benjamin Fox</b></sub></a><br /><a href="https://github.com/processing/processing4/commits?author=tracerstar" title="Code">💻</a></td>
<td align="center" valign="top" width="16.66%"><a href="https://github.com/e1dem"><img src="https://avatars.githubusercontent.com/u/32488297?v=4?s=120" width="120px;" alt="e1dem"/><br /><sub><b>e1dem</b></sub></a><br /><a href="https://github.com/processing/processing4/commits?author=e1dem" title="Code">💻</a></td>
<td align="center" valign="top" width="16.66%"><a href="https://github.com/inteqam"><img src="https://avatars.githubusercontent.com/u/104833943?v=4?s=120" width="120px;" alt="Aditya Chaudhary"/><br /><sub><b>Aditya Chaudhary</b></sub></a><br /><a href="https://github.com/processing/processing4/commits?author=inteqam" title="Code">💻</a></td>
</tr>
</tbody>
</table>
+108 -175
View File
@@ -13,14 +13,7 @@ plugins{
}
group = rootProject.group
tasks.withType<JavaExec> {
systemProperty("processing.version", version)
systemProperty("processing.revision", "1300")
systemProperty("processing.contributions.source", "https://contributions-preview.processing.org/contribs.txt")
systemProperty("processing.download.page", "https://processing.org/download/")
systemProperty("processing.download.latest", "https://processing.org/download/latest.txt")
}
version = rootProject.version
repositories{
mavenCentral()
@@ -43,17 +36,25 @@ compose.desktop {
application {
mainClass = "processing.app.ui.Start"
jvmArgs(*listOf(
Pair("processing.version", version),
Pair("processing.revision", "1300"),
Pair("processing.contributions.source", "https://contributions-preview.processing.org/contribs.txt"),
Pair("processing.download.page", "https://processing.org/download/"),
Pair("processing.download.latest", "https://processing.org/download/latest.txt"),
Pair("processing.tutorials", "https://processing.org/tutorials/"),
).map { "-D${it.first}=${it.second}" }.toTypedArray())
nativeDistributions{
modules("jdk.jdi", "java.compiler")
modules("jdk.jdi", "java.compiler", "jdk.accessibility")
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "Processing"
packageVersion = rootProject.version.toString()
macOS{
bundleID = "org.processing.app"
iconFile = project.file("../build/macos/processing.icns")
infoPlist{
extraKeysRawXml = plistStrings
extraKeysRawXml = layout.projectDirectory.file("info.plist").asFile.readText()
}
entitlementsFile.set(project.file("entitlements.plist"))
runtimeEntitlementsFile.set(project.file("entitlements.plist"))
@@ -69,9 +70,12 @@ compose.desktop {
iconFile = project.file("../build/linux/processing.png")
// Fix fonts on some Linux distributions
jvmArgs("-Dawt.useSystemAAFontSettings=on")
}
appResourcesRootDir.set(layout.buildDirectory.dir("resources-bundled"))
fileAssociation("pde", "Processing Source Code", "application/x-processing")
fileAssociation("pyde", "Processing Python Source Code", "application/x-processing")
fileAssociation("pdez", "Processing Sketch Bundle", "application/x-processing")
fileAssociation("pdex", "Processing Contribution Bundle", "application/x-processing")
}
}
}
}
@@ -97,34 +101,38 @@ dependencies {
implementation(libs.kaml)
}
tasks.compileJava{
options.encoding = "UTF-8"
}
// LEGACY TASKS
// Most of these are shims to be compatible with the old build system
// They should be removed in the future, as we work towards making things more Gradle-native
tasks.register<Copy>("copyCore"){
val project = project(":core")
dependsOn(project.tasks.jar)
from(project.layout.buildDirectory.dir("libs"))
from(project.configurations.runtimeClasspath)
into(layout.buildDirectory.dir("resources-bundled/common/core/library"))
val composeResources = { subPath: String -> layout.buildDirectory.dir("resources-bundled/common/$subPath") }
compose.desktop.application.nativeDistributions.appResourcesRootDir.set(composeResources("../"))
tasks.register<Copy>("includeCore"){
val core = project(":core")
dependsOn(core.tasks.jar)
from(core.layout.buildDirectory.dir("libs"))
from(core.configurations.runtimeClasspath)
into(composeResources("core/library"))
}
tasks.register<Copy>("copyJava"){
val project = project(":java")
dependsOn(project.tasks.jar)
from(project.layout.buildDirectory.dir("libs"))
from(project.configurations.runtimeClasspath)
into(layout.buildDirectory.dir("resources-bundled/common/modes/java/mode"))
tasks.register<Copy>("includeJavaMode") {
val java = project(":java")
dependsOn(java.tasks.jar)
from(java.layout.buildDirectory.dir("libs"))
from(java.configurations.runtimeClasspath)
into(composeResources("modes/java/mode"))
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
tasks.register<Download>("downloadJDK") {
val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem()
val arch: String = System.getProperty("os.arch").let { originalArch ->
when (originalArch) {
"amd64" -> "x64"
"x86_64" -> "x64"
else -> originalArch
}
tasks.register<Download>("includeJdk") {
val os = DefaultNativePlatform.getCurrentOperatingSystem()
val arch = when (System.getProperty("os.arch")) {
"amd64", "x86_64" -> "x64"
else -> System.getProperty("os.arch")
}
val platform = when {
os.isWindows -> "windows"
os.isMacOsX -> "mac"
@@ -142,73 +150,65 @@ tasks.register<Download>("downloadJDK") {
"hotspot/normal/eclipse?project=jdk")
val extension = if (os.isWindows) "zip" else "tar.gz"
dest(layout.buildDirectory.file("jdk-$platform-$arch.$extension"))
val jdk = layout.buildDirectory.file("tmp/jdk-$platform-$arch.$extension")
dest(jdk)
overwrite(false)
}
tasks.register<Copy>("unzipJDK") {
val dl = tasks.findByPath("downloadJDK") as Download
dependsOn(dl)
val os = DefaultNativePlatform.getCurrentOperatingSystem()
val archive = if (os.isWindows) {
zipTree(dl.dest)
} else {
tarTree(dl.dest)
}
from(archive){ eachFile{ permissions{ unix("755") } } }
into(layout.buildDirectory.dir("resources-bundled/common"))
}
tasks.register<Copy>("copyShared"){
from("../build/shared/")
into(layout.buildDirectory.dir("resources-bundled/common"))
}
tasks.register<Download>("downloadProcessingExamples") {
src("https://github.com/processing/processing-examples/archive/refs/heads/main.zip")
dest(layout.buildDirectory.file("tmp/processing-examples.zip"))
overwrite(false)
}
tasks.register<Copy>("unzipExamples") {
val dl = tasks.findByPath("downloadProcessingExamples") as Download
dependsOn(dl)
from(zipTree(dl.dest)){ // remove top level directory
exclude("processing-examples-main/README.md")
exclude("processing-examples-main/.github/**")
eachFile { relativePath = RelativePath(true, *relativePath.segments.drop(1).toTypedArray()) }
includeEmptyDirs = false
}
into(layout.buildDirectory.dir("resources-bundled/common/modes/java/examples"))
}
tasks.register<Download>("downloadProcessingWebsiteExamples") {
src("https://github.com/processing/processing-website/archive/refs/heads/main.zip")
dest(layout.buildDirectory.file("tmp/processing-website.zip"))
overwrite(false)
}
tasks.register<Copy>("unzipWebsiteExamples") {
val dl = tasks.findByPath("downloadProcessingWebsiteExamples") as Download
dependsOn(dl)
dependsOn("unzipExamples")
print(dl.dest)
from(zipTree(dl.dest)){
include("processing-website-main/content/examples/**")
eachFile { relativePath = RelativePath(true, *relativePath.segments.drop(3).toTypedArray()) }
includeEmptyDirs = false
exclude {
it.name.contains(".es.") || it.name == "liveSketch.js"
doLast {
copy {
val archive = if (os.isWindows) { zipTree(jdk) } else { tarTree(jdk) }
from(archive){ eachFile{ permissions{ unix("755") } } }
into(composeResources(""))
}
}
into(layout.buildDirectory.dir("resources-bundled/common/modes/java/examples"))
}
tasks.register<Copy>("copyJavaMode"){
dependsOn("unzipExamples","unzipWebsiteExamples")
dependsOn(project(":java").tasks.named("extraResources"))
from(project(":java").layout.buildDirectory.dir("resources-bundled"))
into(layout.buildDirectory.dir("resources-bundled"))
tasks.register<Copy>("includeSharedAssets"){
from("../build/shared/")
into(composeResources(""))
}
tasks.register<Download>("includeProcessingExamples") {
val examples = layout.buildDirectory.file("tmp/processing-examples.zip")
src("https://github.com/processing/processing-examples/archive/refs/heads/main.zip")
dest(examples)
overwrite(false)
doLast{
copy{
from(zipTree(examples)){ // remove top level directory
exclude("processing-examples-main/README.md")
exclude("processing-examples-main/.github/**")
eachFile { relativePath = RelativePath(true, *relativePath.segments.drop(1).toTypedArray()) }
includeEmptyDirs = false
}
into(composeResources("/modes/java/examples"))
}
}
}
tasks.register<Download>("includeProcessingWebsiteExamples") {
val examples = layout.buildDirectory.file("tmp/processing-website.zip")
src("https://github.com/processing/processing-website/archive/refs/heads/main.zip")
dest(examples)
overwrite(false)
doLast{
copy{
from(zipTree(examples)){
include("processing-website-main/content/examples/**")
eachFile { relativePath = RelativePath(true, *relativePath.segments.drop(3).toTypedArray()) }
includeEmptyDirs = false
exclude { it.name.contains(".es.") || it.name == "liveSketch.js" }
}
into(composeResources("modes/java/examples"))
}
}
}
tasks.register<Copy>("includeJavaModeResources") {
val java = project(":java")
dependsOn(java.tasks.named("extraResources"))
from(java.layout.buildDirectory.dir("resources-bundled"))
into(composeResources("../"))
}
tasks.register<Copy>("renameWindres") {
dependsOn("copyJavaMode", "copyShared", "unzipJDK")
val dir = layout.buildDirectory.dir("resources-bundled/common/modes/java/application/launch4j/bin/")
val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem()
dependsOn("includeSharedAssets","includeJavaModeResources")
val dir = composeResources("modes/java/application/launch4j/bin/")
val os = DefaultNativePlatform.getCurrentOperatingSystem()
val platform = when {
os.isWindows -> "windows"
os.isMacOsX -> "macos"
@@ -222,7 +222,18 @@ tasks.register<Copy>("renameWindres") {
into(dir)
}
afterEvaluate {
tasks.findByName("prepareAppResources")?.dependsOn("unzipJDK","copyShared", "copyCore", "copyJava", "unzipExamples","renameWindres", "copyJavaMode")
tasks.named("prepareAppResources").configure {
dependsOn(
"includeCore",
"includeJavaMode",
"includeJdk",
"includeSharedAssets",
"includeProcessingExamples",
"includeProcessingWebsiteExamples",
"includeJavaModeResources",
"renameWindres"
)
}
tasks.register("setExecutablePermissions") {
description = "Sets executable permissions on binaries in Processing.app resources"
group = "compose desktop"
@@ -243,82 +254,4 @@ afterEvaluate {
}
}
tasks.findByName("createDistributable")?.finalizedBy("setExecutablePermissions")
}
val plistStrings: String
get() = """
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>org.processing.app</string>
<key>CFBundleURLSchemes</key>
<array>
<string>pde</string>
</array>
</dict>
</array>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>pde</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
<key>CFBundleTypeIconFile</key>
<string>macos/pde.icns</string>
<key>CFBundleTypeName</key>
<string>Processing Source Code</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>pyde</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
<key>CFBundleTypeIconFile</key>
<string>macos/pde.icns</string>
<key>CFBundleTypeName</key>
<string>Processing Python Source Code</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>pdez</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
<key>CFBundleTypeIconFile</key>
<string>macos/pdez.icns</string>
<key>CFBundleTypeName</key>
<string>Processing Sketch Bundle</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>pdex</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
<key>CFBundleTypeIconFile</key>
<string>macos/pdex.icns</string>
<key>CFBundleTypeName</key>
<string>Processing Contribution Bundle</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
</array>
<key>NSCameraUsageDescription</key>
<string>The sketch you're running needs access to your video camera.</string>
<key>NSMicrophoneUsageDescription</key>
<string>The sketch you're running needs access to your microphone.</string>
"""
}
+74
View File
@@ -0,0 +1,74 @@
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>org.processing.app</string>
<key>CFBundleURLSchemes</key>
<array>
<string>pde</string>
</array>
</dict>
</array>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>pde</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
<key>CFBundleTypeIconFile</key>
<string>macos/pde.icns</string>
<key>CFBundleTypeName</key>
<string>Processing Source Code</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>pyde</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
<key>CFBundleTypeIconFile</key>
<string>macos/pde.icns</string>
<key>CFBundleTypeName</key>
<string>Processing Python Source Code</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>pdez</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
<key>CFBundleTypeIconFile</key>
<string>macos/pdez.icns</string>
<key>CFBundleTypeName</key>
<string>Processing Sketch Bundle</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>pdex</string>
</array>
<key>LSTypeIsPackage</key>
<false/>
<key>CFBundleTypeIconFile</key>
<string>macos/pdex.icns</string>
<key>CFBundleTypeName</key>
<string>Processing Contribution Bundle</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
</array>
<key>NSCameraUsageDescription</key>
<string>The sketch you're running needs access to your video camera.</string>
<key>NSMicrophoneUsageDescription</key>
<string>The sketch you're running needs access to your microphone.</string>
+4 -4
View File
@@ -1366,10 +1366,10 @@ public class Base {
* @param schemeUri the full URI, including pde://
*/
public Editor handleScheme(String schemeUri) {
var result = Schema.handleSchema(schemeUri, this);
if (result != null) {
return result;
}
// var result = Schema.handleSchema(schemeUri, this);
// if (result != null) {
// return result;
// }
String location = schemeUri.substring(6);
if (location.length() > 0) {
+18 -3
View File
@@ -659,11 +659,25 @@ public class Sketch {
return;
}
if(currentIndex == 0){
Object[] options = { Language.text("menu.sketch.show_sketch_folder"), Language.text("prompt.cancel") };
int result = JOptionPane.showOptionDialog(editor,
Language.interpolate("warn.delete.sketch_last", getName()),
Language.text("warn.delete"),
JOptionPane.YES_NO_OPTION,
JOptionPane.ERROR_MESSAGE,
null,
options,
options[1]);
if (result == JOptionPane.YES_OPTION) {
Platform.openFolder(folder);
}
return;
}
// confirm deletion with user, yes/no
Object[] options = { Language.text("prompt.ok"), Language.text("prompt.cancel") };
String prompt = (currentIndex == 0) ?
Language.interpolate("warn.delete.sketch_folder", getName()) :
Language.interpolate("warn.delete.sketch_file", current.getPrettyName());
String prompt = Language.interpolate("warn.delete.sketch_file", current.getPrettyName());
int result = JOptionPane.showOptionDialog(editor,
prompt,
Language.text("warn.delete"),
@@ -672,6 +686,7 @@ public class Sketch {
null,
options,
options[0]);
// TODO: Remove the code to remove the entire sketch folder
if (result == JOptionPane.YES_OPTION) {
if (currentIndex == 0) { // delete the entire sketch
// need to unset all the modified flags, otherwise tries
+3 -2
View File
@@ -9,8 +9,9 @@ First, [download the IntelliJ IDEA Community Edition](https://www.jetbrains.com/
1. Clone the Processing4 repository to your machine locally
1. Open the cloned repository in IntelliJ IDEA CE
1. Click `Install Required Plugins` on the bottom right or in the notification tray
1. In the main menu, go to File > Project Structure > Project Settings > Project.
1. In the SDK Dropdown option, select a JDK version 17 or Download the jdk
1. Open the `Project Structure` window (`Ctrl+Alt+Shift+S` on Windows/Linux or `⌘;` on macOS)
2. Go to `Project Settings > Project`
1. In the SDK Dropdown option, select a JDK version 17 or `Download a JDK`
1. Select your platform (Windows, MacOS or Linux) in the top right of the window
1. Click the green Run Icon next to it
1. Logs can be found in the `messages` or `run` pane on the bottom left of the window
@@ -600,6 +600,7 @@ contrib.import.errors.link = Error: The library %s has a strange looking downloa
warn.delete = Delete
warn.delete.sketch_folder = Are you sure you want to delete this sketch?\nThis will remove the entire “%s” folder.
warn.delete.sketch_last = To keep your files safe, deleting the whole sketch folder is not supported in Processing. \nPlease open the sketch folder in your file explorer to delete it.
warn.delete.sketch_file = Are you sure you want to delete “%s”?
warn.cannot_change_mode.title = Cannot change mode
warn.cannot_change_mode.body = Cannot change mode,\nbecause “%s” mode is not compatible with current mode.
@@ -407,6 +407,7 @@ editor.status.error.syntax = Syntaxfehler - %s
warn.delete = Löschen
warn.delete.sketch = Den Sketch endgültig löschen?
warn.delete.sketch_last = Um deine Dateien sicher zu halten, wird das Löschen des gesamten Sketch-Ordners in Processing nicht unterstützt. \nBitte öffne den Sketch-Ordner in deinem Datei-Explorer, um ihn zu löschen.
warn.delete.file = Die Datei "%s" entgültig löschen?
@@ -478,6 +478,7 @@ contrib.import.errors.link = Error: The library %s has a strange looking downloa
warn.delete = Διαγραφή
warn.delete.sketch = Είσαι σίγουρος ότι θέλεις να διαγραφεί το Σχέδιο;
warn.delete.sketch_last = Για να διατηρήσετε τα αρχεία σας ασφαλή, η διαγραφή ολόκληρου του φακέλου Σχεδίου δεν υποστηρίζεται στο Processing.\nΠαρακαλούμε ανοίξτε το φάκελο Σχεδίου στον εξερευνητή αρχείων για να το διαγράψετε.
warn.delete.file = Είσαι σίγουρος ότι θέλεις να διαγράψεις το "%s";
@@ -599,6 +599,7 @@ contrib.import.errors.link = Error: el enlace de descarga de la biblioteca «%s
warn.delete = Eliminar
warn.delete.sketch_folder = ¿Seguro que quieres eliminar el sketch?\nEsto suprimirá la carpeta «%s» y todo su contenido.
warn.delete.sketch_last = Para mantener tus archivos seguros, no se admite eliminar toda la carpeta del sketch en Processing.\nAbre la carpeta del sketch en tu explorador de archivos para eliminarla.
warn.delete.sketch_file = ¿Seguro que quieres eliminar el archivo «%s»?
warn.cannot_change_mode.title = Error cambio de modo
warn.cannot_change_mode.body = No se puede cambiar al modo «%s»\nporque no es compatible con el modo actual.
+3 -1
View File
@@ -487,7 +487,9 @@ contrib.import.errors.link = Erreur : Le lien de téléchargement de la biblioth
# Warnings
warn.delete = Supprimer
warn.delete.sketch = Êtes-vous sûr(e) de vouloir supprimer ce sketch?
warn.delete.sketch = Êtes-vous sûr(e) de vouloir supprimer ce sketch? \nLe dossier “%s” sera entièrement effacé.
# warn.delete.sketch_last = To keep your files safe, deleting the whole sketch folder isn?t supported in Processing. \nPlease open the sketch folder in your file explorer to delete it.
warn.delete.sketch_last = Pour protéger vos fichiers, la suppression du dossier de sketch entier n'est pas prise en charge dans Processing. \nVeuillez ouvrir le dossier de sketch dans votre explorateur de fichiers pour le supprimer.
warn.delete.file = Êtes-vous sûr(e) de vouloir supprimer «%s»?
warn.cannot_change_mode.title = Impossible de changer le mode
warn.cannot_change_mode.body = Impossible de changer de mode, \ncar le mode "%s" n'est pas compatible avec le mode actuel.
@@ -533,6 +533,7 @@ contrib.import.errors.link = Errore: la libreria %s ha uno strano link di downlo
warn.delete = Elimina
warn.delete.sketch = Sei sicuro di voler eliminare questo sketch?
warn.delete.sketch_last = Per mantenere i tuoi file al sicuro, l'eliminazione dell'intera cartella dello sketch non è supportata in Processing. \nPer favore apri la cartella dello sketch nel tuo esplora file per eliminarla.
warn.delete.file = Sei sicuro di voler eliminare "%s"?
warn.cannot_change_mode.title = Impossibile cambiare modalità
warn.cannot_change_mode.body = Impossibile cambiare modalità,\npoichè la modalità "%s" non è compatibile con quella corrente.
@@ -537,6 +537,7 @@ contrib.import.errors.link = Error: The library %s has a strange looking downloa
warn.delete = 削除
warn.delete.sketch = このスケッチを削除してもよろしいですか?
warn.delete.sketch_last = ファイルの安全を保つため、Processing ではプロジェクトフォルダーの削除はサポートされていません。\nファイルエクスプローラーでプロジェクトフォルダーを開き、削除してください。
warn.delete.file = "%s"を削除してもよろしいですか?
warn.cannot_change_mode.title = モード変更失敗
warn.cannot_change_mode.body = 互換性がないため、"%s"モードに切り替えられません。
@@ -308,6 +308,7 @@ editor.status.error.syntax = 구문 오류 - %s
warn.delete = 삭제
warn.delete.sketch = 정말 해당 스케치를 삭제하시겠습니까?
warn.delete.sketch_last = 파일의 안전을 위해 Processing에서는 프로젝트 폴더 삭제를 지원하지 않습니다. \n파일 탐색기에서 프로젝트 폴더를 열어 삭제해 주세요.
warn.delete.file = 정말 "%s"를 삭제하시겠습니까?
@@ -305,6 +305,7 @@ contrib.unsupported_operating_system = Uw besturingssyteem wordt schijnbaar niet
warn.delete = Verwijderen
warn.delete.sketch = Weet u zeker dat u deze schets wil verwijderen?
warn.delete.sketch_last = Om je bestanden veilig te houden, wordt het verwijderen van de gehele schets niet ondersteund in Processing. \nOpen de schets map in je bestandsverkenner om deze te verwijderen.
warn.delete.file = Weet u zeker dat u "%s" wil verwijderen?
@@ -253,3 +253,13 @@ contrib.progress.starting = A iniciar
contrib.progress.downloading = A descarregar
contrib.download_error = Ocorreu um erro ao descarregar a contribuição.
contrib.unsupported_operating_system = O seu sistema operativo não parece ser suportado. Deve visitar a biblioteca %s para mais informação.
# ---------------------------------------
# Warnings
warn.delete = Apagar
warn.delete.sketch_folder = Tem a certeza de que deseja apagar este sketch?\nIsto irá remover a pasta inteira “%s”.
warn.delete.sketch_last = Para manter os seus ficheiros seguros, apagar a pasta inteira do sketch não é suportado no Processing.\nPor favor, abra a pasta do sketch no seu explorador de ficheiros para a apagar.
warn.delete.sketch_file = Tem a certeza de que deseja apagar “%s”?
warn.cannot_change_mode.title = Não é possível mudar de modo
warn.cannot_change_mode.body = Não é possível mudar de modo,\nporque o modo “%s” não é compatível com o modo atual.
@@ -547,6 +547,7 @@ contrib.import.errors.link = Ошибка: у библиотеки %s стран
warn.delete = Удалить
warn.delete.sketch = Вы уверены, что хотите удалить эскиз?
warn.delete.sketch_last = Чтобы сохранить ваши файлы в безопасности, удаление всей папки с наброском не поддерживается в Processing.\nПожалуйста, откройте папку с наброском в проводнике, чтобы удалить её.
warn.delete.file = Вы уверены, что хотите удалить "%s"?
warn.cannot_change_mode.title = Нельзя сменить режим
warn.cannot_change_mode.body = Не получается изменить режим,\nтак как "%s" не совместим с текущим режимом.
@@ -232,3 +232,13 @@ editor.status.error.syntax = Hata - %s
contrib.category = Kategori:
contrib.filter_your_search = Aramayı Filtrele...
# ---------------------------------------
# Warnings
warn.delete = Sil
warn.delete.sketch_folder = Bu sketch'i silmek istediğinizden emin misiniz?\nBu işlem “%s” klasörünün tamamını silecektir.
warn.delete.sketch_last = Dosyalarınızı güvende tutmak için, tüm sketch klasörünü silmek Processing'de desteklenmemektedir.\nLütfen bu klasörü silmek için dosya gezgininizi kullanın.
warn.delete.sketch_file = “%s” dosyasını silmek istediğinizden emin misiniz?
warn.cannot_change_mode.title = Mod değiştirilemiyor
warn.cannot_change_mode.body = Mod değiştirilemiyor,\nçünkü “%s” modu mevcut modla uyumlu değil.
+3 -1
View File
@@ -594,6 +594,7 @@ contrib.import.errors.link = Помилка: У бібліотеки %s неді
warn.delete = Видалення
warn.delete.sketch = Ви впевнені, що хочете видалити цей ескіз?
warn.delete.sketch_last = Щоб зберегти ваші файли в безпеці, видалення всієї папки ескізу не підтримується в Processing.\nБудь ласка, відкрийте папку ескізу у вашому файловому менеджері, щоб видалити її.
warn.delete.file = Ви впевнені, що хочете видалити "%s"?
warn.cannot_change_mode.title = Зміна режиму неможлива
warn.cannot_change_mode.body = Зміна режиму неможлива,\nоскільки режим "%s" несумісний з поточним режимом.
@@ -649,4 +650,5 @@ movie_maker.progress.creating_output_file = Створюю вихідний фа
movie_maker.progress.initializing = Ініціалізація...
movie_maker.progress.processing = Обробляю %s.
movie_maker.progress.handling_frame = Конвертую кадр %s з %s...
movie_maker.progress.handling_frame = Конвертую кадр %s з %s...
@@ -307,5 +307,10 @@ contrib.unsupported_operating_system = 你当前的操作系统似乎不被支
# Warnings
warn.delete = 删除
warn.delete.sketch = 你确定要删除该速写本?
warn.delete.file = 你确定删除 "%s"?
warn.delete.sketch = 你确定要删除该速写本吗?
warn.delete.sketch_folder = 你确定删除该速写本吗?\n这将删除整个 “%s” 文件夹。
warn.delete.sketch_last = 为了确保您的文件安全,Processing 不支持删除整个速写本文件夹。\n请在文件管理器中打开速写本文件夹进行删除。
warn.delete.file = 你确定要删除 "%s" 吗?
warn.delete.sketch_file = 你确定要删除 “%s” 吗?
warn.cannot_change_mode.title = 无法切换模式
warn.cannot_change_mode.body = 无法切换模式,\n因为 “%s” 模式与当前模式不兼容。
@@ -577,9 +577,10 @@ contrib.import.errors.link = 錯誤Error: 這個library %s 的下載網址有問
warn.delete = 刪除Delete...
warn.delete.sketch = 確定要刪除程式嗎?
warn.delete.file = 確定要刪除檔案 "%s" 嗎?
warn.cannot_change_mode.title = Cannot change mode
warn.cannot_change_mode.body = Cannot change mode,\nbecause "%s" mode is not compatible with current mode.
warn.delete.sketch_file = 您確定要刪除「%s」嗎?
warn.delete.sketch_last = 為了保護您的檔案安全,Processing 不支援刪除整個程式素描本資料夾。\n請在檔案總管中開啟該資料夾進行刪除。
warn.cannot_change_mode.title = 無法切換模式
warn.cannot_change_mode.body = 無法切換模式,\n因為「%s」模式與當前模式不相容。
# ---------------------------------------
# Update Check
+14 -4
View File
@@ -2335,18 +2335,28 @@ public class PShape implements PConstants {
}
/**
* The <b>getVertexCount()</b> method returns the number of vertices that
* make up a <b>PShape</b>. In the above example, the value 4 is returned by the
* The <b>getVertexCount()</b> method returns the number of vertices (with an option to count children by passing true as boolean parameter to method call) that
* make up a <b>PShape</b>. By default, it does not count child vertices for GROUP shapes. To include child vertices, pass <b>true</b> as a boolean parameter. In the above example, the value 4 is returned by the
* <b>getVertexCount()</b> method because 4 vertices are defined in
* <b>setup()</b>.
*
* @webref pshape:method
* @webBrief Returns the total number of vertices as an int
* @webBrief Returns the total number of vertices as an int with an option to count children Vertex for GROUP Shapes
* @see PShape#getVertex(int)
* @see PShape#setVertex(int, float, float)
*/
public int getVertexCount(boolean includeChildren) {
if(!includeChildren && family == GROUP){
PGraphics.showWarning(NO_VERTICES_ERROR);
}
else if (family == PRIMITIVE) {
PGraphics.showWarning(NO_VERTICES_ERROR);
}
return vertexCount;
}
public int getVertexCount() {
if (family == GROUP || family == PRIMITIVE) {
if(family == GROUP || family == PRIMITIVE){
PGraphics.showWarning(NO_VERTICES_ERROR);
}
return vertexCount;
+23 -8
View File
@@ -1632,20 +1632,34 @@ public class PShapeOpenGL extends PShape {
// Setters/getters of individual vertices
//for taking the default value as false , so user don't have to explicitly enter false
// if user don't want to include children vertex count
@Override
public int getVertexCount() {
if (family == GROUP) return 0; // Group shapes don't have vertices
else {
return getVertexCount(false); // Calls the main method with default false
}
@Override
public int getVertexCount(boolean includeChildren) {
int count = 0;
// If the shape is a group, recursively count the vertices of its children
if (family == GROUP) {
if(!includeChildren){
return 0;
}
// Iterate through all the child shapes and count their vertices
for (int i = 0; i < getChildCount(); i++) {
count += getChild(i).getVertexCount(true); // Recursive call to get the vertex count of child shapes
}
} else {
if (root.tessUpdate) {
if (root.tessKind == TRIANGLES) {
return lastPolyVertex - firstPolyVertex + 1;
count += lastPolyVertex - firstPolyVertex + 1;
} else if (root.tessKind == LINES) {
return lastLineVertex - firstLineVertex + 1;
count += lastLineVertex - firstLineVertex + 1;
} else if (root.tessKind == POINTS) {
return lastPointVertex - firstPointVertex + 1;
count += lastPointVertex - firstPointVertex + 1;
} else {
return 0;
count += 0; // Handle other cases
}
} else {
if (family == PRIMITIVE || family == PATH) {
@@ -1653,9 +1667,10 @@ public class PShapeOpenGL extends PShape {
// tessellation
updateTessellation();
}
return inGeo.vertexCount;
count += inGeo.vertexCount;
}
}
return count;
}
@@ -194,14 +194,29 @@ public class ErrorChecker {
static private JavaProblem convertIProblem(IProblem iproblem, PreprocSketch ps) {
SketchInterval in = ps.mapJavaToSketch(iproblem);
if (in != SketchInterval.BEFORE_START) {
String badCode = ps.getPdeCode(in);
int line = ps.tabOffsetToTabLine(in.tabIndex, in.startTabOffset);
JavaProblem p = JavaProblem.fromIProblem(iproblem, in.tabIndex, line, badCode);
String originalFileName = new String(iproblem.getOriginatingFileName());
boolean isJavaTab = ps.isJavaTab(originalFileName);
// Java tabs' content isn't stored in a sketch's combined source code file,
// so they are processed differently
if (!isJavaTab) {
SketchInterval in = ps.mapJavaToSketch(iproblem);
if (in != SketchInterval.BEFORE_START) {
String badCode = ps.getPdeCode(in);
int line = ps.tabOffsetToTabLine(in.tabIndex, in.startTabOffset);
JavaProblem p = JavaProblem.fromIProblem(iproblem, in.tabIndex, line, badCode);
p.setPDEOffsets(0, -1);
return p;
}
} else {
int tabIndex = ps.getJavaTabIndex(originalFileName);
int line = iproblem.getSourceLineNumber() - 1;
JavaProblem p = JavaProblem.fromIProblem(iproblem, tabIndex, line, "");
p.setPDEOffsets(0, -1);
return p;
}
return null;
}
@@ -73,6 +73,16 @@ public class PreprocSketch {
}
public boolean isJavaTab(String fileName) {
return javaFileMapping.containsKey(fileName);
}
public int getJavaTabIndex(String fileName) {
return javaFileMapping.get(fileName);
}
public SketchInterval mapJavaToSketch(IProblem iproblem) {
String originalFile = new String(iproblem.getOriginatingFileName());
boolean isJavaTab = javaFileMapping.containsKey(originalFile);