Merge branch 'processing:main' into gradle-welcome-screen
@@ -1465,6 +1465,34 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Rishab87",
|
||||
"name": "Rishab Kumar Jha",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/138858208?v=4",
|
||||
"profile": "https://github.com/Rishab87",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "yehiarasheed",
|
||||
"name": "Yehia Rasheed",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/157399068?v=4",
|
||||
"profile": "https://github.com/yehiarasheed",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "babaissarkar",
|
||||
"name": "Subhraman Sarkar",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/8469888?v=4",
|
||||
"profile": "https://github.com/babaissarkar",
|
||||
"contributions": [
|
||||
"code",
|
||||
"a11y"
|
||||
]
|
||||
}
|
||||
],
|
||||
"repoType": "github",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Pre-releases
|
||||
name: Branch Builds (Legacy)
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Pull Requests
|
||||
name: Pull Requests (Legacy)
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
|
||||
@@ -134,7 +134,7 @@ jobs:
|
||||
- name: Install Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '17'
|
||||
java-version: '17.0.8'
|
||||
distribution: 'temurin'
|
||||
architecture: ${{ matrix.arch }}
|
||||
- name: Setup Gradle
|
||||
@@ -153,6 +153,22 @@ jobs:
|
||||
ORG_GRADLE_PROJECT_compose.desktop.mac.notarization.password: ${{ secrets.PROCESSING_APP_PASSWORD }}
|
||||
ORG_GRADLE_PROJECT_compose.desktop.mac.notarization.teamID: ${{ secrets.PROCESSING_TEAM_ID }}
|
||||
ORG_GRADLE_PROJECT_snapname: ${{ vars.SNAP_NAME }}
|
||||
|
||||
- name: Sign files with Trusted Signing
|
||||
if: runner.os == 'Windows'
|
||||
uses: azure/trusted-signing-action@v0
|
||||
with:
|
||||
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||
endpoint: https://eus.codesigning.azure.net/
|
||||
trusted-signing-account-name: ${{ secrets.AZURE_SIGNING_ACCOUNT_NAME }}
|
||||
certificate-profile-name: ${{ secrets.AZURE_CERTIFICATE_PROFILE_NAME }}
|
||||
files-folder: app/build/compose/binaries/main/msi
|
||||
files-folder-filter: msi
|
||||
file-digest: SHA256
|
||||
timestamp-rfc3161: http://timestamp.acs.microsoft.com
|
||||
timestamp-digest: SHA256
|
||||
|
||||
- name: Upload portables to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
@@ -174,18 +190,4 @@ jobs:
|
||||
env:
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.PROCESSING_SNAPCRAFT_TOKEN }}
|
||||
|
||||
- name: Sign files with Trusted Signing
|
||||
if: runner.os == 'Windows'
|
||||
uses: azure/trusted-signing-action@v0
|
||||
with:
|
||||
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||
endpoint: https://eus.codesigning.azure.net/
|
||||
trusted-signing-account-name: vscx-codesigning
|
||||
certificate-profile-name: vscx-certificate-profile
|
||||
files-folder: app/build/compose/binaries/main/msi
|
||||
files-folder-filter: msi
|
||||
file-digest: SHA256
|
||||
timestamp-rfc3161: http://timestamp.acs.microsoft.com
|
||||
timestamp-digest: SHA256
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Releases
|
||||
name: Releases (Legacy)
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
@@ -113,3 +113,5 @@ java/build/
|
||||
|
||||
.build/
|
||||
/app/windows/obj
|
||||
/java/gradle/build
|
||||
/java/gradle/example/.processing
|
||||
|
||||
@@ -1,5 +1,40 @@
|
||||
<svg width="800" height="800" viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M400 500C700 500 700 100 400 100" stroke="#0468FF" stroke-width="150"/>
|
||||
<path d="M400 200L100 600" stroke="#1F34AB" stroke-width="150"/>
|
||||
<path d="M100 300L200 500" stroke="#85AEFF" stroke-width="150"/>
|
||||
<svg width="824" height="825" viewBox="0 0 824 825" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_2066_295)">
|
||||
<g clip-path="url(#clip1_2066_295)">
|
||||
<rect y="0.82666" width="824" height="824" rx="412" fill="url(#paint0_linear_2066_295)"/>
|
||||
<g filter="url(#filter0_dd_2066_295)">
|
||||
<path d="M442.935 523.359C678.119 523.359 678.119 209.453 442.935 209.453" stroke="white" stroke-width="117.1"/>
|
||||
<path d="M432.083 318.783L211.328 628.892" stroke="#9FCFFF" stroke-width="117.738"/>
|
||||
<path d="M205.021 349.27L280.708 535.86" stroke="#1C48B5" stroke-width="117.044"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_dd_2066_295" x="10.7905" y="10.9026" width="815.083" height="800.13" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="4" dy="4"/>
|
||||
<feGaussianBlur stdDeviation="72"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_2066_295"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="11"/>
|
||||
<feGaussianBlur stdDeviation="5"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
|
||||
<feBlend mode="normal" in2="effect1_dropShadow_2066_295" result="effect2_dropShadow_2066_295"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_2066_295" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_2066_295" x1="178.174" y1="61.0872" x2="636.323" y2="764.108" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#60B0FF"/>
|
||||
<stop offset="1" stop-color="#308EFF"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_2066_295">
|
||||
<rect width="824" height="824" fill="white" transform="translate(0 0.82666)"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip1_2066_295">
|
||||
<rect width="824" height="824" fill="white" transform="translate(0 0.82666)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 324 B After Width: | Height: | Size: 2.1 KiB |
@@ -25,36 +25,37 @@ Instructions for other editors are welcome and feel free to contribute the docum
|
||||
|
||||
|
||||
## Architecture
|
||||
Processing is made of three distinct parts, the `Core`, `Java` and the `App`. The `Core` currently stands alone and `Java` and `App` depend on it. `Java` and `App` are currently interdependent but we are working on decoupling those two.
|
||||
Processing consists of three main components: `Core`, `Java`, and `App`. The `Core` is independent, while `Java` and `App` depend on it. Currently, `Java` and `App` are interdependent, but efforts are underway to decouple them.
|
||||
|
||||
`Core`: The part of the code that gets bundled with your sketches, so the functionality like `ellipse(25,25,50,50);` The inner workings of that function can be found here.
|
||||
- **Core**: The essential code included with your sketches that provides Processing’s basic functions. When you use functions like `ellipse(25,25,50,50)` or `background(255)`, their underlying code is part of `Core`.
|
||||
|
||||
`Java`: This is the pipeline that will take your `.pde` file and compile and run it. The PDE understands different _modes_ with `Java` being the primary one.
|
||||
- **Java**: The part of Processing that compiles and runs `.pde` files. It supports different *modes* which implement support for different languages or versions of Processing. The default mode is `Java`.
|
||||
|
||||
- **App**: This is the Processing Development Environment (PDE), the visual part of the editor that you see and work within when you use Processing.
|
||||
|
||||
`App`: This is the PDE, the visual part of the editor that you see and work within when you use Processing.
|
||||
|
||||
### Examples
|
||||
|
||||
- You want to fix a bug with one of the argument of a function that you use in a sketch. The `Core` is probably where you would find the implementation of the function that you would like to modify.
|
||||
- A feature/bug of the PDE editor has been driving you nuts, and you can no longer stand it. You would probably find your bug in the `App` section of this project.
|
||||
- You've written a large sketch and Processing has become slow to compile, a place to improve this code can probably be found in the `Java` section.
|
||||
- A bug of the PDE editor has been keeping you up at night, you would likely find the relevant code in the `App` section of this project.
|
||||
- If you've written a large sketch and Processing has become slow to compile and run it, a place to improve this code can most likely be found in the `Java` section.
|
||||
|
||||
## User interface
|
||||
Traditionally Processing has been written in Java swing and Flatlaf (and some html & css). Since 2025 we have switched to include Jetpack Compose, for a variety of reasons but mostly for it's inter-compatibility. There were ideas to switch to a React based editor, but this approach allows us to slowly replace Java swing components to Jetpack Compose, Ship of Theseus style.
|
||||
Historically, Processing's UI has been written in Java Swing and Flatlaf (and some html & css). Since 2025 we have switched to include Jetpack Compose, mostly for it's backwards-compatibility with Swing. This approach allows us to gradually replace Java Swing components with Jetpack Compose ones, instead of doing a complete overhaul of the editor.
|
||||
|
||||
## Build system
|
||||
|
||||
We use `Gradle` as the build system for Processing. This used to be `Ant` but we have switched to be more in line with modern standards and to hopefully switch the internal build system in the `Java` mode to `Gradle` as well, unifying both systems for simplicity.
|
||||
We use `Gradle` as the build system for Processing. Until 2025, Processing used `Ant` but we have switched to `Gradle` to be more in line with modern standards. We plan to migrate the internal build system of the `Java` mode to `Gradle` as well, unifying both systems for simplicity.
|
||||
|
||||
## Kotlin vs Java
|
||||
Since introducing the Gradle build system we also support Kotlin within the repository. Refactors from Java to Kotlin are not really necessary at this stage, but all new functionality should be written in Kotlin.
|
||||
With the introduction of the Gradle build system we now support Kotlin within the repository. Refactors from Java to Kotlin are not necessary at this stage, but all new functionality should be written in Kotlin.
|
||||
|
||||
Any classes that end in `..Kt.Java` are there for backwards compatibility with the `Ant` build system and can be removed when that is no longer necessary.
|
||||
Any classes that end up being written in Kotlin have their equivalent Java class under `app/ant/` source directory.
|
||||
|
||||
### Running Processing
|
||||
|
||||
The main task to run or debug the PDE is `app:run` this run the application with `compose desktop`
|
||||
The main task to run or debug the PDE is `run`. That means you just need to run `./gradlew run` (Linux) or `./gradlew.bat run` (Windows) to build and run Processing.
|
||||
|
||||
If your main concern is with the `Core` you don't need to start the whole PDE to test your changes. In IntelliJ IDEA you can select any of the sketches in `core/examples/src/.../` to run by click on the green arrow next to their main functions. This will just compile core and the example sketch. Feel free to also new examples for your newly added functionality.
|
||||
If your main concern is with the `Core` you don't need to build and start the whole PDE to test your changes. In IntelliJ IDEA you can select any of the sketches in `core/examples/src/.../` to run by click on the green arrow next to their main functions. This will just compile core and the example sketch. Feel free to create additional examples for your new functionality.
|
||||
|
||||
## Other editors
|
||||
|
||||
@@ -1,6 +1,106 @@
|
||||
## Welcome to Processing!
|
||||
# Contributing to Processing on GitHub
|
||||
|
||||
Thanks for your interest in contributing to Processing! Processing is a collaborative project with contributions from many volunteers. Our community is always looking for contributors and appreciates involvement in all forms. We acknowledge that not everyone has the capacity, time, or financial means to participate actively or in the same ways. We want to expand the meaning of the word “contributor.” Whether you're an experienced developer or just starting out, we value your involvement. Your unique perspectives, skills, and experiences enrich our community, and we encourage you to get involved in a way that works for you. It includes documentation, teaching, writing code, making art, writing, design, activism, organizing, curating, or anything else you might imagine. The [p5.js contribute page](https://p5js.org/contribute/) gives a great overview of different ways to get involved and contribute.
|
||||
Welcome to the contributor guidelines!
|
||||
|
||||
This document is for new contributors looking to contribute code to Processing, contributors refreshing their memory on some technical steps, or anyone interested in working on Processing’s codebase. We believe that anyone can be a contributor. You don’t need to be an expert. We also know that not everyone has the same time, energy, or resources to spend on Processing. That’s okay. We’re glad you’re here!
|
||||
|
||||
> [!TIP]
|
||||
> For questions about your own sketches, or broader conversations about coding in Processing, our [online forum](https://discourse.processing.org/) is a fantastic resource (make sure to read the [forum guidelines](https://discourse.processing.org/t/welcome-to-the-processing-foundation-discourse/8) before posting). You can also visit the [Processing Community Discord](https://discord.gg/8pFwMVATh8).
|
||||
|
||||
## About GitHub
|
||||
Processing’s codebase is hosted on [GitHub](https://github.com/processing). GitHub is a website where people can collaborate on code. It’s widely used for open source projects and makes it easier to keep track of changes, report issues with the software, and contribute improvements to the code.
|
||||
|
||||
If you're new to GitHub, a good place to start is [this tutorial](https://github.com/firstcontributions/first-contributions/blob/main/docs/gui-tool-tutorials/github-desktop-tutorial.md) guide, which walks you through the basics of contributing to a project using GitHub Desktop. For more information, we recommend [Git and GitHub for Poets](https://www.youtube.com/playlist?list=PLRqwX-V7Uu6ZF9C0YMKuns9sLDzK6zoiV), a beginner-friendly video series by Dan Shiffman.
|
||||
|
||||
## About issues
|
||||
|
||||
Most activity on Processing’s GitHub happens in _issues_. Issues are GitHub posts which can contain bug reports, feature requests, or broader discussions about the development of Processing. It’s a great place to begin contributing.
|
||||
|
||||
To file a new issue, visit the [Issues](https://github.com/processing/processing4/issues) tab on the repository and click `New issue` then select the most appropriate template and follow the included instructions. These templates help maintainers understand and respond to issues faster.
|
||||
|
||||
## Working on the Processing codebase
|
||||
|
||||
### Prerequisites
|
||||
|
||||
To contribute to Processing, we recommend using [GitHub Desktop](https://github.com/apps/desktop) and [IntelliJ IDEA (Community Edition)](https://www.jetbrains.com/idea/download/), as that’s the toolchain we’re best able to support. If you’re comfortable using Git on the command line or prefer a different editor, that’s totally fine too! Use what works best for you. Some familiarity with the [command line](https://developer.mozilla.org/en-US/docs/Learn_web_development/Getting_started/Environment_setup/Command_line) can help, but it’s not required.
|
||||
|
||||
You'll need to set up a local development environment—see our [build instructions](https://github.com/processing/processing4/blob/main/BUILD.md) to get started.
|
||||
|
||||
### Making your first contribution
|
||||
|
||||
Most issues marked [help wanted](https://github.com/processing/processing4/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) or [good first issue](https://github.com/processing/processing4/issues?q=is%3Aissue%20is%3Aopen%20label%3A%22good%20first%20issue%22%20) are a good place to start.
|
||||
|
||||
Before beginning work on a code contribution, please make sure that:
|
||||
|
||||
- The issue has been discussed and a proposed solution has been approved.
|
||||
- You have been **assigned** to the issue.
|
||||
|
||||
If an implementation has been agreed upon but no one has volunteered to take it on, feel free to comment and offer to help. A maintainer can then assign the issue to you.
|
||||
|
||||
Please do **not** open a pull request for an issue that is already assigned to someone else. We follow a “first assigned, first served” approach to avoid duplicated work. If you open a PR for an issue that someone else is already working on, your PR will be closed.
|
||||
|
||||
If an issue has been inactive for a long time, you’re welcome to check in politely by commenting to see if the assignee still plans to work on it or would be open to someone else taking over.
|
||||
|
||||
There’s no hard deadline for completing contributions. We understand that people often contribute on a volunteer basis and timelines may vary. That said, if you run into trouble or have questions at any point, don’t hesitate to ask for help in the issue thread. Maintainers and other community members are here to support you.
|
||||
|
||||
### Follow the style guidelines
|
||||
Keep the [style guidelines](https://github.com/processing/processing/wiki/Style-Guidelines) in mind when making changes to the code. If you don’t, someone else will have to reformat your code so that it fits everything else (or we’ll have to reject your changes if it’ll take us too long to clean things up).
|
||||
|
||||
### Test locally
|
||||
Before you contribute your changes, it's essential that you make sure that Processing still builds, runs, and functions on your machine. Here again, the [build instructions](https://github.com/processing/processing4/blob/main/BUILD.md) are your best friend. Pay special attention to any features that may be affected by your changes. Does everything still work as before? Great!
|
||||
|
||||
## Submit a pull request (PR)
|
||||
|
||||
Once your changes are ready:
|
||||
|
||||
1. Push your branch to your fork
|
||||
2. Open a pull request from your branch into `main` on the official repository
|
||||
3. Fill out the pull request information:
|
||||
|
||||
- **Title**: clear and descriptive
|
||||
- **Resolves**: add `Resolves #[issue-number]` if applicable
|
||||
- **Changes**: explain what you changed and why
|
||||
- **Tests**: mention if you added tests or validated your changes
|
||||
- **Checklist**: ensure tests pass and the branch is up-to-date
|
||||
|
||||
Maintainers usually review pull requests within one to two weeks. If changes are requested, follow up by pushing additional commits. The PR will automatically update.
|
||||
|
||||
If there hasn’t been any activity after two weeks, feel free to gently follow up. We kindly ask that you don’t request a review or tag maintainers before that time. Thanks for your patience!
|
||||
|
||||
Before opening a pull request, please make sure to discuss the related issue and get assigned to it first. This helps us stay aligned and avoid unnecessary work. Thank you!
|
||||
|
||||
## New Features
|
||||
|
||||
In most cases, the best way to contribute a new feature is to create a library. The [Processing Library Template](https://github.com/processing/processing-library-template) is a great way to get started. For more instructions, see the [library template documenation](https://processing.github.io/processing-library-template/).
|
||||
|
||||
Nearly all new features are first introduced as a Library or a Mode, or even as an example. The current [OpenGL renderer](http://glgraphics.sourceforge.net/) and Video library began as separate projects by Andrés Colubri, who needed a more performant, more sophisticated version of what we had in Processing for work that he was creating. The original `loadShape()` implementation came from the “Candy” library by Michael Chang (“mflux“). Similarly, Tweak Mode began as a [separate project](http://galsasson.com/tweakmode/) by Gal Sasson before being incorporated. PDE X was a Google Summer of code [project](https://github.com/processing/processing-experimental) by Manindra Moharana that updated the PDE to include basic refactoring and better error checking.
|
||||
|
||||
Developing features separately from the main software has several benefits:
|
||||
|
||||
* It’s easier for the contributor to develop the software without it needing to work for tens or hundreds of thousands of Processing users.
|
||||
* It provides a way to get feedback on that code independently of everything else, and the ability to iterate on it rapidly.
|
||||
* This feedback process also helps gauge the level of interest for the community, and how it should be prioritized for the software.
|
||||
* We can delay the process of “normalizing” the features so that they’re consistent with the rest of Processing (function naming, structure, etc).
|
||||
|
||||
A major consideration for any new feature is the level of maintenance that it might require in the future. If the original maintainer loses interest over time (which is normal) and the feature breaks (which happens more often than we'd like), it sits on the issues list unfixed, which isn’t good for anyone.
|
||||
|
||||
Processing is a massive project that has existed for more than 20 years. Part of its longevity comes from the effort that’s gone into keeping things as simple as we can, and in particular, making a lot of difficult decisions about *what to leave out*. Adding a new feature always has to be weighed against the potential confusion of one more thing—whether it’s a menu item, a dialog box, a function that needs to be added to the reference, etc. Adding a new graphics function means making it work across all the renderers that we ship (Java2D, OpenGL, JavaFX, PDF, etc) and across platforms (macOS, Windows, Linux). Does the feature help enough people that it's worth making the reference longer? Or the additional burden of maintaining that feature? It's no fun to say “no,” especially to people volunteering their time, but we often have to.
|
||||
|
||||
## Editor
|
||||
|
||||
The current Editor component is based on the ancient [JEditSyntax](http://syntax.jedit.org/) package and has held up long past its expiration date. [Exhaustive work](https://github.com/processing/processing4/blob/master/app/src/processing/app/syntax/README.md) has been done to look at replacing the component with something more modern, like `RSyntaxArea`, but that approach was considered too risky.
|
||||
|
||||
With Processing 4.4.0, we’ve started transitioning the Processing UI from Swing to Jetpack Compose Multiplatform, allowing us to replace Swing components gradually, without a full rewrite. Any work on updating the PDE and adding new features should focus on this migration. Replacing JEditSyntax will likely be the last step in the process. In the meantime, the editor does what it needs to do, for the intended audience. Features like code-folding, refactoring, or symbol navigation are currently out of scope.
|
||||
|
||||
For users who want editor features beyond what the PDE offers, we’re working to make Processing easier to use in other environments. [Migrating the Processing CLI to Gradle](https://github.com/orgs/processing/projects/32/views/2?filterQuery=CLI&pane=issue&itemId=81026317) and [better Language Server support](https://github.com/orgs/processing/projects/32/views/2?filterQuery=LSP&pane=issue&itemId=90809690) will help make that possible. This should reduce the pressure to add these features to the PDE itself, allowing it to stay focused on being a minimal, beginner-friendly coding sketchbook. If you'd like to help, [let us know](https://github.com/processing/processing4/issues/883)!
|
||||
|
||||
## Refactoring
|
||||
|
||||
Refactoring is fun! There’s always more cleaning to do. It’s also often not very helpful.
|
||||
|
||||
Broadly speaking, the code is built the way it is for a reason. There are so many things that can be improved, but those improvements need to come from an understanding of what’s been built so far. Changes that include refactoring are typically only accepted from contributors who have an established record of working on the code. With a better understanding of the software, the refactoring decisions come from a better, more useful place.
|
||||
|
||||
## Contributor Recognition
|
||||
|
||||
The Processing project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification, recognizing all types of contributions, not just code. We use the @all-contributors bot to handle adding people to the README.md file. You can ask the @all-contributors bot to add you in an issue or PR comment like so:
|
||||
|
||||
@@ -10,70 +110,15 @@ The Processing project follows the [all-contributors](https://github.com/kentcdo
|
||||
|
||||
We usually add contributors automatically after merging a PR, but feel free to request addition yourself by commenting on [this issue](https://github.com/processing/processing4-carbon-aug-19/issues/839).
|
||||
|
||||
## Found a Bug?
|
||||
## Other Ways to Contribute
|
||||
|
||||
First, please visit our [troubleshooting](https://github.com/processing/processing/wiki/Troubleshooting) page for common issues—you might find the answer there!
|
||||
We're always grateful for your help fixing bugs and implementing new features BUT You don’t have to write code to contribute to Processing! Here are just a few other ways to get involved:
|
||||
|
||||
For coding questions or help getting started, our [online forum](https://discourse.processing.org/) is a fantastic resource. Make sure to read the [forum guidelines](https://discourse.processing.org/t/welcome-to-the-processing-foundation-discourse/8) before posting.
|
||||
|
||||
If your issue remains unresolved after exploring these options, we'd appreciate it if you could [file a bug report](https://github.com/processing/processing4/issues). Your feedback is crucial as it helps us address issues we might not be aware of yet.
|
||||
|
||||
## Making Your First Contribution
|
||||
|
||||
* **Help Wanted** – Most [issues marked help wanted](https://github.com/processing/processing4/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) are a good place to start. Issues are marked with this tag when:
|
||||
|
||||
* They are isolated enough that someone can jump into it without significant reworking of other code.
|
||||
* Ben knows that it’s unlikely that he’ll have time to work on them.
|
||||
|
||||
* **The Old Repository** – There are also many “help wanted” [issues in the 3.x repository](https://github.com/processing/processing4/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22). Some of these are very old, so if you're interested in one of these, check in about the priority before putting in too much work!
|
||||
|
||||
* **JavaFX** – There are several [active issues](https://github.com/processing/processing4-javafx/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) for the JavaFX renderer as well.
|
||||
|
||||
* **The `todo.txt` File** – This is *not* a good place to start. It’s Ben’s rambling to-do list, and dates back to the very start of the project over twenty years ago. It shouldn’t be used as a guideline for work to be done, because there are lots of things there that are no longer relevant. Consider it the dusty attic of what’s inside his head. If you see something of interest there, open an issue to see if it’s still a priority, or how it should be approached. But really, there are *so many open issues*, which represent actual problems identified by community members, and they are by far the best place to start.
|
||||
|
||||
* **Style Guidelines** – Keep the [style guidelines](https://github.com/processing/processing/wiki/Style-Guidelines) in mind when submitting pull requests. If you don’t, someone else will have to reformat your code so that it fits everything else (or we’ll have to reject it if it’ll take us too long to clean it up).
|
||||
|
||||
* **Larger Projects** – If you’re looking for a larger project, check out the [Project List](https://github.com/processing/processing/wiki/Project-List#processing) for other ideas.
|
||||
|
||||
|
||||
## New Features
|
||||
|
||||
Nearly all new features are first introduced as a Library or a Mode, or even as an example. The current [OpenGL renderer](http://glgraphics.sourceforge.net/) and Video library began as separate projects by Andrés Colubri, who needed a more performant, more sophisticated version of what we had in Processing for work that he was creating. The original `loadShape()` implementation came from the “Candy” library by Michael Chang (“mflux“).
|
||||
|
||||
Similarly, Tweak Mode began as a [separate project](http://galsasson.com/tweakmode/) by Gal Sasson before being incorporated. PDE X was a Google Summer of code [project](https://github.com/processing/processing-experimental) by Manindra Moharana that updated the PDE to include basic refactoring and better error checking.
|
||||
|
||||
Developing features separately from the main software has several benefits:
|
||||
|
||||
* It’s easier for the contributor to develop the software without it needing to work for tens or hundreds of thousands of Processing users.
|
||||
* It provides a way to get feedback on that code independently of everything else, and the ability to iterate on it rapidly.
|
||||
* This feedback process also helps gauge the level of interest for the community, and how it should be prioritized for the software.
|
||||
* We can delay the process of “normalizing” the features so that they’re consistent with the rest of Processing (function naming, structure, etc).
|
||||
|
||||
A major consideration for any new feature is the level of maintenance that it might require in the future. If the original maintainer loses interest over time (which is normal), any ongoing work usually falls to Ben, or it sits on the issues list unfixed, which isn’t good for the community, or for Ben, who has plenty of issues of his own—whether Processing or otherwise.
|
||||
|
||||
Processing is a massive project that has existed for more than 20 years. Part of its longevity comes from the effort that’s gone into keeping things as simple as we can, and in particular, making a lot of difficult decisions about *what to leave out*. Adding a new feature always has to be weighed against the potential confusion of one more thing—whether it’s a menu item, a dialog box, a function that needs to be added to the reference, etc. Adding a new graphics function means making it work across all the renderers that we ship (Java2D, OpenGL, JavaFX, PDF, etc) and across platforms (macOS, Windows, Linux). Does the feature help enough people that it's worth making the reference longer? Or the additional burden of maintaining that feature? It's no fun to say “no,” especially to people volunteering their time, but we often have to.
|
||||
|
||||
|
||||
## Editor
|
||||
|
||||
The current Editor, based on the ancient [JEditSyntax](http://syntax.jedit.org/) package has held up long past its expiration date. [Exhaustive work](https://github.com/processing/processing4/blob/master/app/src/processing/app/syntax/README.md) has been done to look at replacing the component with something more modern, like `RSyntaxArea`, but it’s simply not feasible without breaking a massive amount of code, and likely introducing a lot of regressions in the process. All for… code folding? An incrementally better experience? But with potential for major setbacks in low-level code? It’s simply not a path that makes sense.
|
||||
|
||||
With that in mind, any work on updating the editor and adding new features should be focused on further [adapting the preprocessor and compiler](https://github.com/processing/processing4/issues/117) to be wrapped using the [Language Server Protocol](https://en.wikipedia.org/wiki/Language_Server_Protocol), so that we can link to other existing editors (Visual Studio Code and many others). It should be possible to create a Java-only, headless implementation that wraps the current source in this repository and can communicate via LSP.
|
||||
|
||||
The initial work was completed in Processing 4.1, and now needs more testing and implementation of Language Server clients such as [this one](https://github.com/kgtkr/processing-language-server-vscode).
|
||||
|
||||
We can start building a new PDE that’s as simple to use as the current application, based on something like [Theia](https://theia-ide.org/), a new editor platform that uses LSP as its basis.
|
||||
|
||||
With that in mind, nearly all editor enhancement requests will be redirected to this aim. The current editor does what we want it to, for the intended audience, and improving it requires a better foundation as a starting point.
|
||||
|
||||
|
||||
## Refactoring
|
||||
|
||||
Refactoring is fun! There’s always more cleaning to do. It’s also often not very helpful.
|
||||
|
||||
Broadly speaking, the code is built the way it is for a reason. There are so many things that can be improved, but those improvements need to come from an understanding of what’s been built so far. Changes that include refactoring are typically only accepted from contributors who have an established record of working on the code. With a better understanding of the software, the refactoring decisions come from a better, more useful place.
|
||||
|
||||
|
||||
## Other Details
|
||||
|
||||
This document was hastily thrown together in an attempt to improve the bug reporting and development/contribution process. It doesn’t yet include detail about our intent with the project, the community behind it, our values, and an explanation of how the code itself is designed.
|
||||
- **Translation** – Help localize the software and documentation in your language. Many of us made our first contribution this way.
|
||||
- **Testing** – Try out new releases (especially the betas) and [report bugs](https://github.com/processing/processing4/issues/new/choose).
|
||||
- **Documentation** – Improve tutorials, reference pages, or even this guide!
|
||||
- **Design** – Contribute UI design ideas or help improve user experience.
|
||||
- **Community Support** – Answer questions on the [forum](https://discourse.processing.org/).
|
||||
- **Education** – Create learning resources, curriculums, organize workshops, or share your teaching experiences.
|
||||
- **Art and Projects** – Share what you’re making with Processing and use the #BuiltWithProcessing hashtag 💙
|
||||
- **Outreach and Advocacy** – Help others discover and get excited about the project.
|
||||
|
||||
@@ -287,6 +287,11 @@ Add yourself to the contributors list [here](https://github.com/processing/proce
|
||||
<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>
|
||||
<td align="center" valign="top" width="16.66%"><a href="https://github.com/Rishab87"><img src="https://avatars.githubusercontent.com/u/138858208?v=4?s=120" width="120px;" alt="Rishab Kumar Jha"/><br /><sub><b>Rishab Kumar Jha</b></sub></a><br /><a href="https://github.com/processing/processing4/commits?author=Rishab87" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="16.66%"><a href="https://github.com/yehiarasheed"><img src="https://avatars.githubusercontent.com/u/157399068?v=4?s=120" width="120px;" alt="Yehia Rasheed"/><br /><sub><b>Yehia Rasheed</b></sub></a><br /><a href="https://github.com/processing/processing4/commits?author=yehiarasheed" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="16.66%"><a href="https://github.com/babaissarkar"><img src="https://avatars.githubusercontent.com/u/8469888?v=4?s=120" width="120px;" alt="Subhraman Sarkar"/><br /><sub><b>Subhraman Sarkar</b></sub></a><br /><a href="https://github.com/processing/processing4/commits?author=babaissarkar" title="Code">💻</a> <a href="#a11y-babaissarkar" title="Accessibility">️️️️♿️</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# Processing URI Schema Definition
|
||||
|
||||
The Processing URI schema defines a custom protocol for launching and interacting with the Processing Development Environment (PDE) via specially formatted `pde://` links. These links can be used to open sketches, create new ones, load hosted or base64-encoded files, and set preferences, all through a simple URI-based interface.
|
||||
|
||||
This feature is primarily intended for integration with web platforms, tutorials, documentation, or third-party tools that want to streamline the experience of launching sketches in Processing from a web page.
|
||||
|
||||
Because these links can be generated dynamically, they support a range of interactive use cases. For example, an online editor could generate a unique link for each sketch, or a forum could create links based on user-submitted code snippets.
|
||||
|
||||
>[!WARNING]
|
||||
> Be cautious when opening `pde://` links from unknown sources. Always review the contents of a sketch before running it, especially if it was shared by someone you don’t know. To protect your system, Processing runs downloaded sketches in a temporary folder, but you should still treat untrusted code with care.
|
||||
|
||||
## Local File Schema
|
||||
```
|
||||
pde:///path/to/sketch.pde
|
||||
@@ -60,4 +69,4 @@ Sets and saves multiple preferences in a single operation.
|
||||
- URL-based operations automatically prepend https:// if no scheme is provided
|
||||
- All URLs and query parameters are decoded using UTF-8
|
||||
- File downloads occur asynchronously in a separate thread
|
||||
- Base64 and remote sketches are saved to temporary folders
|
||||
- Base64 and remote sketches are saved to temporary folders
|
||||
|
||||
@@ -53,7 +53,7 @@ compose.desktop {
|
||||
jvmArgs(*listOf(
|
||||
Pair("processing.version", rootProject.version),
|
||||
Pair("processing.revision", findProperty("revision") ?: Int.MAX_VALUE),
|
||||
Pair("processing.contributions.source", "https://download.processing.org/contribs.txt"),
|
||||
Pair("processing.contributions.source", "https://contributions.processing.org/contribs"),
|
||||
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/"),
|
||||
@@ -73,6 +73,7 @@ compose.desktop {
|
||||
entitlementsFile.set(file("macos/entitlements.plist"))
|
||||
runtimeEntitlementsFile.set(file("macos/entitlements.plist"))
|
||||
appStore = true
|
||||
jvmArgs("-Dsun.java2d.metal=true")
|
||||
}
|
||||
windows{
|
||||
iconFile = rootProject.file("build/windows/processing.ico")
|
||||
@@ -243,6 +244,7 @@ tasks.register("generateSnapConfiguration"){
|
||||
- x11
|
||||
- network
|
||||
- opengl
|
||||
- home
|
||||
|
||||
parts:
|
||||
processing:
|
||||
@@ -358,6 +360,7 @@ tasks.register<Download>("includeJdk") {
|
||||
into(composeResources(""))
|
||||
}
|
||||
}
|
||||
finalizedBy("prepareAppResources")
|
||||
}
|
||||
tasks.register<Copy>("includeSharedAssets"){
|
||||
from("../build/shared/")
|
||||
@@ -515,7 +518,6 @@ afterEvaluate {
|
||||
dependsOn(
|
||||
"includeCore",
|
||||
"includeJavaMode",
|
||||
"includeJdk",
|
||||
"includeSharedAssets",
|
||||
"includeProcessingExamples",
|
||||
"includeProcessingWebsiteExamples",
|
||||
@@ -543,7 +545,7 @@ afterEvaluate {
|
||||
}
|
||||
}
|
||||
tasks.named("createDistributable").configure {
|
||||
dependsOn("signResources")
|
||||
dependsOn("signResources", "includeJdk")
|
||||
finalizedBy("setExecutablePermissions")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 185 KiB |
@@ -0,0 +1,23 @@
|
||||
# The default is 8, which creates tiny nubby scroll bars
|
||||
ScrollBar.width = 16
|
||||
|
||||
TitlePane.inactiveForeground = #000000
|
||||
|
||||
|
||||
# Better matched for macOS dark mode (but using everywhere)
|
||||
# https://github.com/JFormDesigner/FlatLaf/issues/497
|
||||
|
||||
[dark]@background = #1e1e1e
|
||||
[dark]@foreground = #e0e0e0
|
||||
[dark]@accentColor = #107aff
|
||||
[dark]@accentFocusColor = #176896
|
||||
|
||||
[dark]Component.arrowType = chevron
|
||||
|
||||
[dark]CheckBox.icon.style = filled
|
||||
[dark]CheckBox.icon[filled].selectedBorderColor = @accentColor
|
||||
[dark]CheckBox.icon[filled].selectedBackground = @accentColor
|
||||
[dark]CheckBox.icon[filled].checkmarkColor = @foreground
|
||||
|
||||
[dark]RadioButton.icon.style = filled
|
||||
[dark]RadioButton.icon[filled].centerDiameter = 6
|
||||
@@ -1,5 +1,9 @@
|
||||
package processing.app
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import processing.app.ui.Editor
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
@@ -13,6 +17,8 @@ import java.util.*
|
||||
class Schema {
|
||||
companion object{
|
||||
private var base: Base? = null
|
||||
val jobs = mutableListOf<Job>()
|
||||
|
||||
@JvmStatic
|
||||
fun handleSchema(input: String, base: Base): Editor?{
|
||||
this.base = base
|
||||
@@ -72,10 +78,9 @@ class Schema {
|
||||
}
|
||||
private fun handleSketchOptions(uri: URI, sketchFolder: File){
|
||||
val options = uri.query?.split("&")
|
||||
?.map { it.split("=") }
|
||||
?.map { it.split("=", limit = 2) }
|
||||
?.associate {
|
||||
URLDecoder.decode(it[0], StandardCharsets.UTF_8) to
|
||||
URLDecoder.decode(it[1], StandardCharsets.UTF_8)
|
||||
it[0] to it[1]
|
||||
}
|
||||
?: emptyMap()
|
||||
options["data"]?.let{ data ->
|
||||
@@ -93,8 +98,9 @@ class Schema {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private val scope = CoroutineScope(Dispatchers.Default)
|
||||
private fun downloadFiles(uri: URI, urlList: String, targetFolder: File, extension: String = ""){
|
||||
Thread{
|
||||
targetFolder.mkdirs()
|
||||
|
||||
val base = uri.path.split("/")
|
||||
@@ -129,15 +135,20 @@ class Schema {
|
||||
URL("https://$content").path.isNotBlank() -> "https://$content"
|
||||
else -> "https://$base/$content"
|
||||
})
|
||||
url.openStream().use { input ->
|
||||
target.outputStream().use { output ->
|
||||
input.copyTo(output)
|
||||
val download = scope.launch{
|
||||
url.openStream().use { input ->
|
||||
target.outputStream().use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
}
|
||||
jobs.add(download)
|
||||
download.invokeOnCompletion {
|
||||
jobs.remove(download)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,15 +31,19 @@ import processing.app.Messages;
|
||||
import processing.app.Preferences;
|
||||
import processing.core.PApplet;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
|
||||
public class LinuxPlatform extends DefaultPlatform {
|
||||
// Switched to use ~ as the home directory for compatibility with snap
|
||||
String homeDir = "~";
|
||||
String homeDir;
|
||||
|
||||
|
||||
public void initBase(Base base) {
|
||||
super.initBase(base);
|
||||
|
||||
JFrame.setDefaultLookAndFeelDecorated(true);
|
||||
System.setProperty("flatlaf.menuBarEmbedded", "true");
|
||||
|
||||
// Set X11 WM_CLASS property which is used as the application
|
||||
// name by Gnome 3 and other window managers.
|
||||
// https://github.com/processing/processing/issues/2534
|
||||
@@ -107,6 +111,10 @@ public class LinuxPlatform extends DefaultPlatform {
|
||||
configHome = null; // don't use non-existent folder
|
||||
}
|
||||
}
|
||||
String snapUserCommon = System.getenv("SNAP_USER_COMMON");
|
||||
if (snapUserCommon != null && !snapUserCommon.isBlank()) {
|
||||
configHome = new File(snapUserCommon);
|
||||
}
|
||||
// If not set properly, use the default
|
||||
if (configHome == null) {
|
||||
configHome = new File(getHomeDir(), ".config");
|
||||
|
||||
@@ -399,6 +399,7 @@ public class JEditTextArea extends JComponent
|
||||
public void updateScrollBars() {
|
||||
if (vertical != null && visibleLines != 0) {
|
||||
vertical.setValues(firstLine,visibleLines,0,getLineCount());
|
||||
vertical.setVisible(visibleLines < getLineCount());
|
||||
vertical.setUnitIncrement(2);
|
||||
vertical.setBlockIncrement(visibleLines);
|
||||
}
|
||||
@@ -424,6 +425,7 @@ public class JEditTextArea extends JComponent
|
||||
// https://github.com/processing/processing/issues/319
|
||||
// https://github.com/processing/processing/issues/355
|
||||
//setValues(int newValue, int newExtent, int newMin, int newMax)
|
||||
horizontal.setVisible(painterWidth < width);
|
||||
if (horizontalOffset < 0) {
|
||||
horizontal.setValues(-horizontalOffset, painterWidth, -leftHandGutter, width);
|
||||
} else {
|
||||
|
||||
@@ -208,7 +208,7 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
Box box = Box.createVerticalBox();
|
||||
Box upper = Box.createVerticalBox();
|
||||
|
||||
if(SystemInfo.isMacFullWindowContentSupported) {
|
||||
if(Platform.isMacOS() && SystemInfo.isMacFullWindowContentSupported) {
|
||||
getRootPane().putClientProperty( "apple.awt.fullWindowContent", true );
|
||||
getRootPane().putClientProperty( "apple.awt.transparentTitleBar", true );
|
||||
|
||||
@@ -349,6 +349,30 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
|
||||
// Enable window resizing (which allows for full screen button)
|
||||
setResizable(true);
|
||||
|
||||
{
|
||||
// Move Lines Keyboard Shortcut (Alt + Arrow Up/Down)
|
||||
KeyStroke moveUpKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.ALT_DOWN_MASK);
|
||||
final String MOVE_UP_ACTION_KEY = "moveLinesUp";
|
||||
textarea.getInputMap(JComponent.WHEN_FOCUSED).put(moveUpKeyStroke, MOVE_UP_ACTION_KEY);
|
||||
textarea.getActionMap().put(MOVE_UP_ACTION_KEY, new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
handleMoveLines(true);
|
||||
}
|
||||
});
|
||||
|
||||
KeyStroke moveDownKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.ALT_DOWN_MASK);
|
||||
final String MOVE_DOWN_ACTION_KEY = "moveLinesDown";
|
||||
textarea.getInputMap(JComponent.WHEN_FOCUSED).put(moveDownKeyStroke, MOVE_DOWN_ACTION_KEY);
|
||||
textarea.getActionMap().put(MOVE_DOWN_ACTION_KEY, new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
handleMoveLines(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -595,12 +619,10 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
toolTipWarningColor = Theme.get("errors.selection.warning.bgcolor");
|
||||
toolTipErrorColor = Theme.get("errors.selection.error.bgcolor");
|
||||
|
||||
if(Platform.isWindows()) {
|
||||
UIManager.put("RootPane.background", color);
|
||||
UIManager.put("TitlePane.embeddedForeground", Theme.getColor("editor.fgcolor"));
|
||||
getRootPane().updateUI();
|
||||
UIManager.put("RootPane.background", null);
|
||||
}
|
||||
UIManager.put("RootPane.background", color);
|
||||
UIManager.put("TitlePane.embeddedForeground", Theme.getColor("editor.fgcolor"));
|
||||
getRootPane().updateUI();
|
||||
UIManager.put("RootPane.background", null);
|
||||
|
||||
JPopupMenu popup = modePopup.getPopupMenu();
|
||||
// Cannot use instanceof because com.formdev.flatlaf.ui.FlatPopupMenuBorder
|
||||
@@ -791,6 +813,18 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
item.addActionListener(e -> handleIndentOutdent(false));
|
||||
menu.add(item);
|
||||
|
||||
item = Toolkit.newJMenuItemExt("menu.edit.increase_font");
|
||||
item.addActionListener(e -> {
|
||||
modifyFontSize(true);
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
item = Toolkit.newJMenuItemExt("menu.edit.decrease_font");
|
||||
item.addActionListener(e -> {
|
||||
modifyFontSize(false);
|
||||
});
|
||||
menu.add(item);
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
item = Toolkit.newJMenuItem(Language.text("menu.edit.find"), 'F');
|
||||
@@ -848,6 +882,16 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
return menu;
|
||||
}
|
||||
|
||||
protected void modifyFontSize(boolean increase){
|
||||
var fontSize = Preferences.getInteger("editor.font.size");
|
||||
fontSize += increase ? 1 : -1;
|
||||
fontSize = Math.max(5, Math.min(72, fontSize));
|
||||
Preferences.setInteger("editor.font.size", fontSize);
|
||||
for (Editor editor : base.getEditors()) {
|
||||
editor.applyPreferences();
|
||||
}
|
||||
Preferences.save();
|
||||
}
|
||||
|
||||
abstract public JMenu buildSketchMenu();
|
||||
|
||||
@@ -1919,6 +1963,110 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
sketch.setModified(true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Moves the selected lines up or down in the text editor.
|
||||
*
|
||||
* <p>If {@code moveUp} is true, the selected lines are moved up. If false, they move down.</p>
|
||||
* <p>This method ensures proper selection updates and handles edge cases like moving
|
||||
* the first or last line.</p>
|
||||
* <p>This operation is undo/redoable, allowing the user to revert the action using
|
||||
* {@code Ctrl/Cmd + Z} (Undo). Redo functionality is available through the
|
||||
* keybinding {@code Ctrl/Cmd + Z} on Windows/Linux and {@code Shift + Cmd + Z} on macOS.</p>
|
||||
*
|
||||
* @param moveUp {@code true} to move the selection up, {@code false} to move it down.
|
||||
*/
|
||||
public void handleMoveLines(boolean moveUp) {
|
||||
startCompoundEdit();
|
||||
boolean isSelected = false;
|
||||
|
||||
if (textarea.isSelectionActive())
|
||||
isSelected = true;
|
||||
|
||||
int caretPos = textarea.getCaretPosition();
|
||||
int currentLine = textarea.getCaretLine();
|
||||
int lineStart = textarea.getLineStartOffset(currentLine);
|
||||
int column = caretPos - lineStart;
|
||||
|
||||
int startLine = textarea.getSelectionStartLine();
|
||||
int stopLine = textarea.getSelectionStopLine();
|
||||
|
||||
// Adjust selection if the last line isn't fully selected
|
||||
if (startLine != stopLine &&
|
||||
textarea.getSelectionStop() == textarea.getLineStartOffset(stopLine)) {
|
||||
stopLine--;
|
||||
}
|
||||
|
||||
int replacedLine = moveUp ? startLine - 1 : stopLine + 1;
|
||||
if (replacedLine < 0 || replacedLine >= textarea.getLineCount()) {
|
||||
stopCompoundEdit();
|
||||
return;
|
||||
}
|
||||
|
||||
final String source = textarea.getText(); // Get full text from textarea
|
||||
|
||||
int replaceStart = textarea.getLineStartOffset(replacedLine);
|
||||
int replaceEnd = textarea.getLineStopOffset(replacedLine);
|
||||
if (replaceEnd > source.length()) {
|
||||
replaceEnd = source.length();
|
||||
}
|
||||
|
||||
int selectionStart = textarea.getLineStartOffset(startLine);
|
||||
int selectionEnd = textarea.getLineStopOffset(stopLine);
|
||||
if (selectionEnd > source.length()) {
|
||||
selectionEnd = source.length();
|
||||
}
|
||||
|
||||
String replacedText = source.substring(replaceStart, replaceEnd);
|
||||
String selectedText = source.substring(selectionStart, selectionEnd);
|
||||
|
||||
if (replacedLine == textarea.getLineCount() - 1) {
|
||||
replacedText += "\n";
|
||||
selectedText = selectedText.substring(0, Math.max(0, selectedText.length() - 1));
|
||||
} else if (stopLine == textarea.getLineCount() - 1) {
|
||||
selectedText += "\n";
|
||||
replacedText = replacedText.substring(0, Math.max(0, replacedText.length() - 1));
|
||||
}
|
||||
|
||||
int newSelectionStart, newSelectionEnd;
|
||||
if (moveUp) {
|
||||
textarea.select(selectionStart, selectionEnd);
|
||||
textarea.setSelectedText(replacedText); // Use setSelectedText()
|
||||
|
||||
textarea.select(replaceStart, replaceEnd);
|
||||
textarea.setSelectedText(selectedText);
|
||||
|
||||
newSelectionStart = textarea.getLineStartOffset(startLine - 1);
|
||||
newSelectionEnd = textarea.getLineStopOffset(stopLine - 1);
|
||||
} else {
|
||||
textarea.select(replaceStart, replaceEnd);
|
||||
textarea.setSelectedText(selectedText);
|
||||
|
||||
textarea.select(selectionStart, selectionEnd);
|
||||
textarea.setSelectedText(replacedText);
|
||||
|
||||
newSelectionStart = textarea.getLineStartOffset(startLine + 1);
|
||||
newSelectionEnd = stopLine + 1 < textarea.getLineCount()
|
||||
? Math.min(textarea.getLineStopOffset(stopLine + 1), source.length())
|
||||
: textarea.getLineStopOffset(stopLine); // Prevent out-of-bounds
|
||||
}
|
||||
stopCompoundEdit();
|
||||
|
||||
if (isSelected)
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
textarea.select(newSelectionStart, newSelectionEnd-1);
|
||||
});
|
||||
else if (replacedLine >= 0 && replacedLine < textarea.getLineCount()) {
|
||||
int replacedLineStart = textarea.getLineStartOffset(replacedLine);
|
||||
int replacedLineEnd = textarea.getLineStopOffset(replacedLine);
|
||||
|
||||
// Ensure caret stays within bounds of the new line
|
||||
int newCaretPos = Math.min(replacedLineStart + column, replacedLineEnd - 1);
|
||||
|
||||
SwingUtilities.invokeLater(() -> textarea.setCaretPosition(newCaretPos));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static public boolean checkParen(char[] array, int index, int stop) {
|
||||
while (index < stop) {
|
||||
@@ -2128,7 +2276,7 @@ public abstract class Editor extends JFrame implements RunnerListener {
|
||||
* something like "sketch_070752a - Processing 0126"
|
||||
*/
|
||||
public void updateTitle() {
|
||||
setTitle(sketch.getName() + " | Processing " + Base.getVersionName());
|
||||
setTitle(sketch.getName());
|
||||
|
||||
if (!sketch.isUntitled()) {
|
||||
// Set current file for macOS so that cmd-click in title bar works.
|
||||
|
||||
@@ -30,6 +30,8 @@ import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.font.FontRenderContext;
|
||||
@@ -39,6 +41,7 @@ import java.util.List;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import processing.app.Base;
|
||||
import processing.app.Mode;
|
||||
import processing.app.Sketch;
|
||||
import processing.app.contrib.ContributionManager;
|
||||
@@ -83,10 +86,14 @@ public class EditorFooter extends Box {
|
||||
Image gradient;
|
||||
Color bgColor;
|
||||
|
||||
Box tabBar;
|
||||
|
||||
JPanel cardPanel;
|
||||
CardLayout cardLayout;
|
||||
Controller controller;
|
||||
|
||||
JLabel version;
|
||||
|
||||
int updateCount;
|
||||
|
||||
|
||||
@@ -98,8 +105,33 @@ public class EditorFooter extends Box {
|
||||
cardPanel = new JPanel(cardLayout);
|
||||
add(cardPanel);
|
||||
|
||||
tabBar = new Box(BoxLayout.X_AXIS);
|
||||
|
||||
controller = new Controller();
|
||||
add(controller);
|
||||
tabBar.add(controller);
|
||||
|
||||
version = new JLabel(Base.getVersionName());
|
||||
version.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, Editor.RIGHT_GUTTER));
|
||||
version.addMouseListener(new MouseAdapter() {
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if(e.getClickCount() == 5){
|
||||
Base.DEBUG = !Base.DEBUG;
|
||||
}
|
||||
var debugInformation = String.join("\n",
|
||||
"Version: " + Base.getVersionName(),
|
||||
"Revision: " + Base.getRevision(),
|
||||
"OS: " + System.getProperty("os.name") + " " + System.getProperty("os.version") + " " + System.getProperty("os.arch"),
|
||||
"Java: " + System.getProperty("java.version") + " " + System.getProperty("java.vendor")
|
||||
);
|
||||
var stringSelection = new StringSelection(debugInformation);
|
||||
var clipboard = java.awt.Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
clipboard.setContents(stringSelection, null);
|
||||
}
|
||||
});
|
||||
|
||||
tabBar.add(version);
|
||||
|
||||
add(tabBar);
|
||||
|
||||
updateTheme();
|
||||
}
|
||||
@@ -175,6 +207,15 @@ public class EditorFooter extends Box {
|
||||
|
||||
// replace colors for the "updates" indicator
|
||||
controller.updateTheme();
|
||||
|
||||
tabBar.setOpaque(true);
|
||||
tabBar.setBackground(bgColor);
|
||||
|
||||
var updatesTextColor = Theme.getColor("footer.updates.text.color");
|
||||
var withAlpha = new Color(updatesTextColor.getRed(), updatesTextColor.getGreen(), updatesTextColor.getBlue(), 128);
|
||||
|
||||
version.setForeground(withAlpha);
|
||||
version.setFont(font);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.swing.Box;
|
||||
@@ -57,6 +59,7 @@ import processing.app.Mode;
|
||||
import processing.app.Platform;
|
||||
import processing.app.Preferences;
|
||||
import processing.app.SketchReference;
|
||||
import processing.app.contrib.Contribution;
|
||||
import processing.app.contrib.ContributionManager;
|
||||
import processing.app.contrib.ContributionType;
|
||||
import processing.app.contrib.ExamplesContribution;
|
||||
@@ -313,9 +316,11 @@ public class ExamplesFrame extends JFrame {
|
||||
}
|
||||
|
||||
// Get examples for third party libraries
|
||||
DefaultMutableTreeNode contributedLibExamples = new
|
||||
DefaultMutableTreeNode(Language.text("examples.libraries"));
|
||||
for (Library lib : mode.contribLibraries) {
|
||||
DefaultMutableTreeNode contributedLibExamples = new DefaultMutableTreeNode(Language.text("examples.libraries"));
|
||||
var sortedContribLibs = new ArrayList<>(mode.contribLibraries);
|
||||
// Sort the libraries by actual name (not the name of the folder)
|
||||
sortedContribLibs.sort(Comparator.comparing(Contribution::getName));
|
||||
for (Library lib : sortedContribLibs) {
|
||||
if (lib.hasExamples()) {
|
||||
DefaultMutableTreeNode libNode =
|
||||
new DefaultMutableTreeNode(lib.getName());
|
||||
|
||||
@@ -12,15 +12,12 @@ import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.toComposeImageBitmap
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.*
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import processing.app.Base
|
||||
import processing.app.Platform
|
||||
import javax.imageio.ImageIO
|
||||
|
||||
/**
|
||||
* Show a splash screen window. A rewrite of Splash.java
|
||||
@@ -29,8 +26,6 @@ class Start {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
val splash = Platform.getContentFile("lib/about-processing.png")
|
||||
val image = ImageIO.read(splash).toComposeImageBitmap()
|
||||
val duration = 200
|
||||
val timeMargin = 50
|
||||
|
||||
@@ -44,7 +39,8 @@ class Start {
|
||||
resizable = false,
|
||||
state = rememberWindowState(
|
||||
position = WindowPosition(Alignment.Center),
|
||||
size = DpSize(image.width.dp / 2 , image.height.dp / 2)
|
||||
width = 578.dp,
|
||||
height = 665.dp
|
||||
)
|
||||
) {
|
||||
var visible by remember { mutableStateOf(false) }
|
||||
@@ -81,7 +77,7 @@ class Start {
|
||||
)
|
||||
) {
|
||||
Image(
|
||||
bitmap = image,
|
||||
painter = painterResource("about-processing.svg"),
|
||||
contentDescription = "About",
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package processing.app
|
||||
|
||||
import kotlinx.coroutines.joinAll
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.ValueSource
|
||||
import org.mockito.ArgumentCaptor
|
||||
@@ -35,6 +37,22 @@ class SchemaTest {
|
||||
verify(base).handleNew()
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun testCustomBase64Sketch(){
|
||||
Schema.handleSchema("pde://sketch/base64/LyoqCiAqIEFycmF5IE9iamVjdHMuIAogKiAKICogRGVtb25zdHJhdGVzIHRoZSBzeW50YXggZm9yIGNyZWF0aW5nIGFuIGFycmF5IG9mIGN1c3RvbSBvYmplY3RzLiAKICovCgppbnQgdW5pdCA9IDQwOwppbnQgY291bnQ7Ck1vZHVsZVtdIG1vZHM7Cgp2b2lkIHNldHVwKCkgewogIHNpemUoNjQwLCAzNjApOwogIG5vU3Ryb2tlKCk7CiAgaW50IHdpZGVDb3VudCA9IHdpZHRoIC8gdW5pdDsKICBpbnQgaGlnaENvdW50ID0gaGVpZ2h0IC8gdW5pdDsKICBjb3VudCA9IHdpZGVDb3VudCAqIGhpZ2hDb3VudDsKICBtb2RzID0gbmV3IE1vZHVsZVtjb3VudF07CgogIGludCBpbmRleCA9IDA7CiAgZm9yIChpbnQgeSA9IDA7IHkgPCBoaWdoQ291bnQ7IHkrKykgewogICAgZm9yIChpbnQgeCA9IDA7IHggPCB3aWRlQ291bnQ7IHgrKykgewogICAgICBtb2RzW2luZGV4KytdID0gbmV3IE1vZHVsZSh4KnVuaXQsIHkqdW5pdCwgdW5pdC8yLCB1bml0LzIsIHJhbmRvbSgwLjA1LCAwLjgpLCB1bml0KTsKICAgIH0KICB9Cn0KCnZvaWQgZHJhdygpIHsKICBiYWNrZ3JvdW5kKDApOwogIGZvciAoTW9kdWxlIG1vZCA6IG1vZHMpIHsKICAgIG1vZC51cGRhdGUoKTsKICAgIG1vZC5kaXNwbGF5KCk7CiAgfQp9?pde=Module:Y2xhc3MgTW9kdWxlIHsKICBpbnQgeE9mZnNldDsKICBpbnQgeU9mZnNldDsKICBmbG9hdCB4LCB5OwogIGludCB1bml0OwogIGludCB4RGlyZWN0aW9uID0gMTsKICBpbnQgeURpcmVjdGlvbiA9IDE7CiAgZmxvYXQgc3BlZWQ7IAogIAogIC8vIENvbnRydWN0b3IKICBNb2R1bGUoaW50IHhPZmZzZXRUZW1wLCBpbnQgeU9mZnNldFRlbXAsIGludCB4VGVtcCwgaW50IHlUZW1wLCBmbG9hdCBzcGVlZFRlbXAsIGludCB0ZW1wVW5pdCkgewogICAgeE9mZnNldCA9IHhPZmZzZXRUZW1wOwogICAgeU9mZnNldCA9IHlPZmZzZXRUZW1wOwogICAgeCA9IHhUZW1wOwogICAgeSA9IHlUZW1wOwogICAgc3BlZWQgPSBzcGVlZFRlbXA7CiAgICB1bml0ID0gdGVtcFVuaXQ7CiAgfQogIAogIC8vIEN1c3RvbSBtZXRob2QgZm9yIHVwZGF0aW5nIHRoZSB2YXJpYWJsZXMKICB2b2lkIHVwZGF0ZSgpIHsKICAgIHggPSB4ICsgKHNwZWVkICogeERpcmVjdGlvbik7CiAgICBpZiAoeCA+PSB1bml0IHx8IHggPD0gMCkgewogICAgICB4RGlyZWN0aW9uICo9IC0xOwogICAgICB4ID0geCArICgxICogeERpcmVjdGlvbik7CiAgICAgIHkgPSB5ICsgKDEgKiB5RGlyZWN0aW9uKTsKICAgIH0KICAgIGlmICh5ID49IHVuaXQgfHwgeSA8PSAwKSB7CiAgICAgIHlEaXJlY3Rpb24gKj0gLTE7CiAgICAgIHkgPSB5ICsgKDEgKiB5RGlyZWN0aW9uKTsKICAgIH0KICB9CiAgCiAgLy8gQ3VzdG9tIG1ldGhvZCBmb3IgZHJhd2luZyB0aGUgb2JqZWN0CiAgdm9pZCBkaXNwbGF5KCkgewogICAgZmlsbCgyNTUpOwogICAgZWxsaXBzZSh4T2Zmc2V0ICsgeCwgeU9mZnNldCArIHksIDYsIDYpOwogIH0KfQAA", base)
|
||||
val captor = ArgumentCaptor.forClass(String::class.java)
|
||||
|
||||
verify(base).handleOpenUntitled(captor.capture())
|
||||
|
||||
val file = File(captor.value)
|
||||
assert(file.exists())
|
||||
|
||||
val extra = file.parentFile.resolve("Module.pde")
|
||||
assert(extra.exists())
|
||||
file.parentFile.deleteRecursively()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalEncodingApi::class)
|
||||
@Test
|
||||
fun testBase64SketchAndExtraFiles() {
|
||||
@@ -49,8 +67,8 @@ class SchemaTest {
|
||||
|
||||
val base64 = Base64.encode(sketch.toByteArray())
|
||||
Schema.handleSchema("pde://sketch/base64/$base64?pde=AnotherFile:$base64", base)
|
||||
val captor = ArgumentCaptor.forClass(String::class.java)
|
||||
|
||||
val captor = ArgumentCaptor.forClass(String::class.java)
|
||||
verify(base).handleOpenUntitled(captor.capture())
|
||||
|
||||
val file = File(captor.value)
|
||||
@@ -66,6 +84,7 @@ class SchemaTest {
|
||||
@Test
|
||||
fun testURLSketch() {
|
||||
Schema.handleSchema("pde://sketch/url/github.com/processing/processing-examples/raw/refs/heads/main/Basics/Arrays/Array/Array.pde", base)
|
||||
waitForSchemeJobsToComplete()
|
||||
|
||||
val captor = ArgumentCaptor.forClass(String::class.java)
|
||||
verify(base).handleOpenUntitled(captor.capture())
|
||||
@@ -88,6 +107,7 @@ class SchemaTest {
|
||||
])
|
||||
fun testURLSketchWithFile(file: String){
|
||||
Schema.handleSchema("pde://sketch/url/github.com/processing/processing-examples/raw/refs/heads/main/Basics/Arrays/ArrayObjects/ArrayObjects.pde?pde=$file", base)
|
||||
waitForSchemeJobsToComplete()
|
||||
|
||||
val captor = ArgumentCaptor.forClass(String::class.java)
|
||||
verify(base).handleOpenUntitled(captor.capture())
|
||||
@@ -110,4 +130,10 @@ class SchemaTest {
|
||||
Preferences.save()
|
||||
}
|
||||
}
|
||||
|
||||
fun waitForSchemeJobsToComplete(){
|
||||
runBlocking {
|
||||
joinAll(*Schema.jobs.toTypedArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,19 @@
|
||||
<svg width="825" height="825" viewBox="0 0 825 825" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_2067_354)">
|
||||
<mask id="mask0_2067_354" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="825" height="825">
|
||||
<rect x="0.5" y="0.82666" width="824" height="824" rx="50" fill="#1369C9"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_2067_354)">
|
||||
<rect x="0.5" y="0.82666" width="824" height="824" rx="50" fill="#1369C9"/>
|
||||
<rect x="0.5" y="-19.1733" width="824" height="824" rx="50" fill="#489EFF"/>
|
||||
<path d="M447.435 527.359C682.619 527.359 682.619 213.453 447.435 213.453" stroke="white" stroke-width="117.1"/>
|
||||
<path d="M436.583 322.783L215.828 632.892" stroke="#9FCFFF" stroke-width="117.738"/>
|
||||
<path d="M209.521 353.27L285.208 539.86" stroke="#1C48B5" stroke-width="117.044"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_2067_354">
|
||||
<rect width="824" height="824" fill="white" transform="translate(0.5 0.82666)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 958 B |
|
Before Width: | Height: | Size: 710 KiB |
@@ -59,6 +59,14 @@ menu.edit.decrease_indent = ← Decrease Indent
|
||||
menu.edit.decrease_indent.keystroke.macos = meta pressed OPEN_BRACKET
|
||||
menu.edit.decrease_indent.keystroke.windows = ctrl pressed OPEN_BRACKET
|
||||
menu.edit.decrease_indent.keystroke.linux = ctrl pressed OPEN_BRACKET
|
||||
menu.edit.increase_font = Increase Font Size
|
||||
menu.edit.increase_font.keystroke.macos = meta pressed EQUALS
|
||||
menu.edit.increase_font.keystroke.windows = ctrl pressed EQUALS
|
||||
menu.edit.increase_font.keystroke.linux = ctrl pressed EQUALS
|
||||
menu.edit.decrease_font = Decrease Font Size
|
||||
menu.edit.decrease_font.keystroke.macos = meta pressed MINUS
|
||||
menu.edit.decrease_font.keystroke.windows = ctrl pressed MINUS
|
||||
menu.edit.decrease_font.keystroke.linux = ctrl pressed MINUS
|
||||
menu.edit.find = Find...
|
||||
menu.edit.find_next = Find Next
|
||||
menu.edit.find_previous = Find Previous
|
||||
@@ -631,6 +639,13 @@ beta.title = Welcome to the Processing Beta
|
||||
beta.message = Thank you for trying out the new version of Processing. We're very grateful!\n\nPlease report any bugs on the forums.
|
||||
beta.button = Got it!
|
||||
|
||||
# ---------------------------------------
|
||||
# Beta
|
||||
beta.window.title = Welcome to Beta
|
||||
beta.title = Thanks for testing this Processing Beta!
|
||||
beta.message = This preview release lets us gather feedback and fix issues before the final version. **Some features may not work as expected.** If you encounter problems, [please post on the forum](https://discourse.processing.org) or [open a GitHub issue](https://github.com/processing/processing4/issues).
|
||||
beta.button = Ok
|
||||
|
||||
# ---------------------------------------
|
||||
# Color Chooser
|
||||
|
||||
|
||||
@@ -318,10 +318,9 @@ update_check.updates_available.contributions = Er zijn updates beschikbaar voor
|
||||
# ---------------------------------------
|
||||
# Beta
|
||||
beta.window.title = Welkom bij Beta
|
||||
beta.title = Welkom bij de Processing Beta
|
||||
beta.message = Bedankt dat je de nieuwe versie van Processing uitprobeert. We zijn je zeer dankbaar!\n\nMeld eventuele bugs alsjeblieft op de forums.
|
||||
beta.button = Okee!
|
||||
|
||||
beta.title = Dankuwel voor het testen van deze Processing Beta!
|
||||
beta.message = Deze preview release laat ons feedback verzamelen en problemen oplossen. **Sommige functies werken mogelijk niet zoals verwacht.** Als u problemen ondervindt, [post dan op het forum](https://discourse.processing.org) of [open een GitHub issue](https://github.com/processing/processing4/issues).
|
||||
beta.button = Ok
|
||||
|
||||
# ---------------------------------------
|
||||
# Color Chooser
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #0066C5
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #C0FFFF
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #374E81
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #834548
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #FFEBEC
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #0087A9
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #49D0A7
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #1A0300
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #9C9824
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #431D29
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #FFF2FF
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #544587
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #47502C
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #FBFFD7
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #3D4B37
|
||||
|
||||
@@ -161,16 +161,16 @@ editor.scrollbar.color = #978FAC
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #540000
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 90
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 60
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #CA0022
|
||||
editor.gutter.highlight.color = #F7637B
|
||||
|
||||
# squiggly line underneath errors in the editor
|
||||
editor.error.underline.color = #000000
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #9D0038
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #FFE8FF
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #8F4965
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #F07D44
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #3E0000
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #D9964A
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #E9E9E9
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #00003B
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #809AE3
|
||||
|
||||
@@ -161,16 +161,16 @@ editor.scrollbar.color = #FF6E38
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #000049
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #4F4CA9
|
||||
editor.gutter.highlight.color = #9090ED
|
||||
|
||||
# squiggly line underneath errors in the editor
|
||||
editor.error.underline.color = #000000
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #FF8F2F
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #470000
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 90
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 50
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #CF226A
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #697982
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #EFFFFF
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #7C5295
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #4E535A
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #FAFFFF
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #535558
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #00593B
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #B7FFEA
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #347A00
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #A55134
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #FFFDFB
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #888280
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #008A50
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.color = #71FFD5
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #CBFFEF
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 90
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 60
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #8F9090
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #092D38
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #E1FFFF
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #30505D
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #4A4E59
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #FAFEFF
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #686C78
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #00926F
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #001E00
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #007757
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #B9BDC4
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #000009
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #92969D
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #BD8A68
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #270000
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #9C6D4C
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #402563
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #FFEFFF
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #654788
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #7A896D
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #000700
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #606F54
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #6C7076
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #000009
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #565A60
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #973542
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.color = #FFDFE5
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #FFEFF2
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 90
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #B9545E
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #CC383C
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.color = #460000
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #fbb5b5
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 100
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 70
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #B11928
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #5E93BF
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.color = #00072B
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #000833
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #3E76A0
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #313E38
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #F2FFFA
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #515F58
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #869F36
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #000D00
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #678015
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #EFBA4E
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #2D0000
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #C29225
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #06545D
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #C9FFFF
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 40
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #32747C
|
||||
|
||||
@@ -161,13 +161,13 @@ editor.scrollbar.color = #DE5C25
|
||||
|
||||
## PdeTextAreaPainter - extras added to the editor ##
|
||||
|
||||
editor.gutter.text.font = processing.mono,plain,12
|
||||
editor.gutter.text.font = processing.mono,bold,16
|
||||
editor.gutter.text.color = #440000
|
||||
|
||||
# transparency (0..100) for line numbers in gutter
|
||||
editor.gutter.text.active.alpha = 70
|
||||
editor.gutter.text.active.alpha = 80
|
||||
# transparency for lines not currently in use
|
||||
editor.gutter.text.inactive.alpha = 30
|
||||
editor.gutter.text.inactive.alpha = 50
|
||||
|
||||
# bgcolor for the current (highlighted) line
|
||||
editor.gutter.highlight.color = #BC4007
|
||||
|
||||
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 615 KiB |
@@ -0,0 +1,40 @@
|
||||
<svg width="824" height="825" viewBox="0 0 824 825" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_2066_295)">
|
||||
<g clip-path="url(#clip1_2066_295)">
|
||||
<rect y="0.82666" width="824" height="824" rx="412" fill="url(#paint0_linear_2066_295)"/>
|
||||
<g filter="url(#filter0_dd_2066_295)">
|
||||
<path d="M442.935 523.359C678.119 523.359 678.119 209.453 442.935 209.453" stroke="white" stroke-width="117.1"/>
|
||||
<path d="M432.083 318.783L211.328 628.892" stroke="#9FCFFF" stroke-width="117.738"/>
|
||||
<path d="M205.021 349.27L280.708 535.86" stroke="#1C48B5" stroke-width="117.044"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_dd_2066_295" x="10.7905" y="10.9026" width="815.083" height="800.13" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="4" dy="4"/>
|
||||
<feGaussianBlur stdDeviation="72"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_2066_295"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="11"/>
|
||||
<feGaussianBlur stdDeviation="5"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
|
||||
<feBlend mode="normal" in2="effect1_dropShadow_2066_295" result="effect2_dropShadow_2066_295"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_2066_295" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_2066_295" x1="178.174" y1="61.0872" x2="636.323" y2="764.108" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#60B0FF"/>
|
||||
<stop offset="1" stop-color="#308EFF"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_2066_295">
|
||||
<rect width="824" height="824" fill="white" transform="translate(0 0.82666)"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip1_2066_295">
|
||||
<rect width="824" height="824" fill="white" transform="translate(0 0.82666)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -2635,8 +2635,11 @@ public class PApplet implements PConstants {
|
||||
keyPressed = true;
|
||||
keyPressed(keyEvent);
|
||||
}
|
||||
case KeyEvent.RELEASE -> {
|
||||
pressedKeys.remove(((long) keyCode << Character.SIZE) | key);
|
||||
case KeyEvent.RELEASE -> {
|
||||
pressedKeys.removeIf(hash -> {
|
||||
int pressedKeyCode = (int)(hash >> Character.SIZE);
|
||||
return pressedKeyCode == keyCode;
|
||||
});
|
||||
keyPressed = !pressedKeys.isEmpty();
|
||||
keyReleased(keyEvent);
|
||||
}
|
||||
@@ -2842,6 +2845,7 @@ public class PApplet implements PConstants {
|
||||
public void focusLost() {
|
||||
// TODO: if user overrides this without calling super it's not gonna work
|
||||
pressedKeys.clear();
|
||||
keyPressed = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1057,6 +1057,9 @@ public class PImage implements PConstants, Cloneable {
|
||||
* [toxi 050728]
|
||||
*/
|
||||
protected void buildBlurKernel(float r) {
|
||||
float maxRadius = Math.min(width, height) / 2.0f;
|
||||
float maxR = maxRadius / 3.5f;
|
||||
r = Math.min(r, maxR);
|
||||
int radius = (int) (r * 3.5f);
|
||||
if (radius < 1) radius = 1;
|
||||
if (radius > 248) radius = 248;
|
||||
@@ -1083,6 +1086,9 @@ public class PImage implements PConstants, Cloneable {
|
||||
}
|
||||
}
|
||||
|
||||
private int safeDivide(int numerator, int denominator) {
|
||||
return denominator == 0 ? numerator : numerator / denominator;
|
||||
}
|
||||
|
||||
protected void blurAlpha(float r) {
|
||||
int sum, cb;
|
||||
@@ -1115,7 +1121,7 @@ public class PImage implements PConstants, Cloneable {
|
||||
read++;
|
||||
}
|
||||
ri = yi + x;
|
||||
b2[ri] = cb / sum;
|
||||
b2[ri] = safeDivide(cb, sum);
|
||||
}
|
||||
yi += pixelWidth;
|
||||
}
|
||||
@@ -1146,7 +1152,7 @@ public class PImage implements PConstants, Cloneable {
|
||||
ri++;
|
||||
read += pixelWidth;
|
||||
}
|
||||
pixels[x+yi] = (cb/sum);
|
||||
pixels[x+yi] = safeDivide(cb, sum);
|
||||
}
|
||||
yi += pixelWidth;
|
||||
ymi += pixelWidth;
|
||||
@@ -1191,9 +1197,9 @@ public class PImage implements PConstants, Cloneable {
|
||||
read++;
|
||||
}
|
||||
ri = yi + x;
|
||||
r2[ri] = cr / sum;
|
||||
g2[ri] = cg / sum;
|
||||
b2[ri] = cb / sum;
|
||||
r2[ri] = safeDivide(cr, sum);
|
||||
g2[ri] = safeDivide(cg, sum);
|
||||
b2[ri] = safeDivide(cb, sum);
|
||||
}
|
||||
yi += pixelWidth;
|
||||
}
|
||||
@@ -1228,7 +1234,7 @@ public class PImage implements PConstants, Cloneable {
|
||||
ri++;
|
||||
read += pixelWidth;
|
||||
}
|
||||
pixels[x+yi] = 0xff000000 | (cr/sum)<<16 | (cg/sum)<<8 | (cb/sum);
|
||||
pixels[x+yi] = 0xff000000 | (safeDivide(cr, sum))<<16 | (safeDivide(cg, sum))<<8 | (safeDivide(cb, sum));
|
||||
}
|
||||
yi += pixelWidth;
|
||||
ymi += pixelWidth;
|
||||
@@ -1276,10 +1282,10 @@ public class PImage implements PConstants, Cloneable {
|
||||
read++;
|
||||
}
|
||||
ri = yi + x;
|
||||
a2[ri] = ca / sum;
|
||||
r2[ri] = cr / sum;
|
||||
g2[ri] = cg / sum;
|
||||
b2[ri] = cb / sum;
|
||||
a2[ri] = safeDivide(ca, sum);
|
||||
r2[ri] = safeDivide(cr, sum);
|
||||
g2[ri] = safeDivide(cg, sum);
|
||||
b2[ri] = safeDivide(cb, sum);
|
||||
}
|
||||
yi += pixelWidth;
|
||||
}
|
||||
@@ -1315,7 +1321,7 @@ public class PImage implements PConstants, Cloneable {
|
||||
ri++;
|
||||
read += pixelWidth;
|
||||
}
|
||||
pixels[x+yi] = (ca/sum)<<24 | (cr/sum)<<16 | (cg/sum)<<8 | (cb/sum);
|
||||
pixels[x+yi] = (safeDivide(ca, sum))<<24 | (safeDivide(cr, sum))<<16 | (safeDivide(cg, sum))<<8 | (safeDivide(cb, sum));
|
||||
}
|
||||
yi += pixelWidth;
|
||||
ymi += pixelWidth;
|
||||
|
||||
@@ -4481,7 +4481,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
// The minus sign is needed to invert the Y axis.
|
||||
projection.set(x, 0, 0, tx,
|
||||
0, -y, 0, ty,
|
||||
0, -y, 0, -ty,
|
||||
0, 0, z, tz,
|
||||
0, 0, 0, 1);
|
||||
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
package processing.core;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import processing.event.KeyEvent;
|
||||
|
||||
public class PAppletKeyEventTest {
|
||||
|
||||
private static final int SHIFT_MASK = 1;
|
||||
private static final int CTRL_MASK = 2;
|
||||
private static final int ALT_MASK = 4;
|
||||
|
||||
private PApplet applet;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
applet = new PApplet();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleKeyPressAndRelease() {
|
||||
KeyEvent pressEvent = new KeyEvent(null, 0L, KeyEvent.PRESS, 0, 'a', 65, false);
|
||||
applet.handleKeyEvent(pressEvent);
|
||||
Assert.assertEquals(1, applet.pressedKeys.size());
|
||||
|
||||
KeyEvent releaseEvent = new KeyEvent(null, 0L, KeyEvent.RELEASE, 0, 'a', 65, false);
|
||||
applet.handleKeyEvent(releaseEvent);
|
||||
Assert.assertEquals(0, applet.pressedKeys.size());
|
||||
Assert.assertFalse(applet.keyPressed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShiftAndLetterSequence() {
|
||||
KeyEvent pressA = new KeyEvent(null, 0L, KeyEvent.PRESS, 0, 'a', 65, false);
|
||||
applet.handleKeyEvent(pressA);
|
||||
|
||||
KeyEvent pressShift = new KeyEvent(null, 0L, KeyEvent.PRESS, SHIFT_MASK, 'A', 16, false);
|
||||
applet.handleKeyEvent(pressShift);
|
||||
|
||||
KeyEvent releaseA = new KeyEvent(null, 0L, KeyEvent.RELEASE, SHIFT_MASK, 'A', 65, false);
|
||||
applet.handleKeyEvent(releaseA);
|
||||
|
||||
KeyEvent releaseShift = new KeyEvent(null, 0L, KeyEvent.RELEASE, 0, 'A', 16, false);
|
||||
applet.handleKeyEvent(releaseShift);
|
||||
|
||||
Assert.assertFalse("keyPressed should be false after all keys released", applet.keyPressed);
|
||||
Assert.assertTrue("pressedKeys should be empty", applet.pressedKeys.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testControlAndLetterSequence() {
|
||||
KeyEvent pressCtrl = new KeyEvent(null, 0L, KeyEvent.PRESS, CTRL_MASK, '\0', 17, false);
|
||||
applet.handleKeyEvent(pressCtrl);
|
||||
|
||||
KeyEvent pressC = new KeyEvent(null, 0L, KeyEvent.PRESS, CTRL_MASK, (char)3, 67, false);
|
||||
applet.handleKeyEvent(pressC);
|
||||
|
||||
KeyEvent releaseC = new KeyEvent(null, 0L, KeyEvent.RELEASE, CTRL_MASK, 'c', 67, false);
|
||||
applet.handleKeyEvent(releaseC);
|
||||
|
||||
KeyEvent releaseCtrl = new KeyEvent(null, 0L, KeyEvent.RELEASE, 0, '\0', 17, false);
|
||||
applet.handleKeyEvent(releaseCtrl);
|
||||
|
||||
Assert.assertFalse("keyPressed should be false after all keys released", applet.keyPressed);
|
||||
Assert.assertTrue("pressedKeys should be empty", applet.pressedKeys.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAltAndLetterSequence() {
|
||||
KeyEvent pressV = new KeyEvent(null, 0L, KeyEvent.PRESS, 0, 'v', 86, false);
|
||||
applet.handleKeyEvent(pressV);
|
||||
|
||||
KeyEvent pressAlt = new KeyEvent(null, 0L, KeyEvent.PRESS, ALT_MASK, 'v', 18, false);
|
||||
applet.handleKeyEvent(pressAlt);
|
||||
|
||||
KeyEvent releaseV = new KeyEvent(null, 0L, KeyEvent.RELEASE, ALT_MASK, 'v', 86, false);
|
||||
applet.handleKeyEvent(releaseV);
|
||||
|
||||
KeyEvent releaseAlt = new KeyEvent(null, 0L, KeyEvent.RELEASE, 0, 'v', 18, false);
|
||||
applet.handleKeyEvent(releaseAlt);
|
||||
|
||||
Assert.assertFalse("keyPressed should be false after all keys released", applet.keyPressed);
|
||||
Assert.assertTrue("pressedKeys should be empty", applet.pressedKeys.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyRepeat() {
|
||||
applet.keyRepeatEnabled = false;
|
||||
|
||||
KeyEvent pressR = new KeyEvent(null, 0L, KeyEvent.PRESS, 0, 'r', 82, false);
|
||||
applet.handleKeyEvent(pressR);
|
||||
|
||||
KeyEvent repeatR = new KeyEvent(null, 0L, KeyEvent.PRESS, 0, 'r', 82, true);
|
||||
applet.handleKeyEvent(repeatR);
|
||||
|
||||
Assert.assertTrue("keyPressed should be true after key press", applet.keyPressed);
|
||||
Assert.assertEquals("pressedKeys should have 1 entry", 1, applet.pressedKeys.size());
|
||||
|
||||
KeyEvent releaseR = new KeyEvent(null, 0L, KeyEvent.RELEASE, 0, 'r', 82, false);
|
||||
applet.handleKeyEvent(releaseR);
|
||||
|
||||
Assert.assertFalse("keyPressed should be false after key release", applet.keyPressed);
|
||||
Assert.assertEquals("pressedKeys should be empty", true, applet.pressedKeys.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyRepeatEnabled() {
|
||||
applet.keyRepeatEnabled = true;
|
||||
|
||||
KeyEvent pressT = new KeyEvent(null, 0L, KeyEvent.PRESS, 0, 't', 84, false);
|
||||
applet.handleKeyEvent(pressT);
|
||||
|
||||
KeyEvent repeatT = new KeyEvent(null, 0L, KeyEvent.PRESS, 0, 't', 84, true);
|
||||
applet.handleKeyEvent(repeatT);
|
||||
|
||||
Assert.assertTrue("keyPressed should be true with key repeat enabled", applet.keyPressed);
|
||||
Assert.assertEquals("pressedKeys should have 1 entry", 1, applet.pressedKeys.size());
|
||||
|
||||
KeyEvent releaseT = new KeyEvent(null, 0L, KeyEvent.RELEASE, 0, 't', 84, false);
|
||||
applet.handleKeyEvent(releaseT);
|
||||
|
||||
Assert.assertFalse("keyPressed should be false after key release", applet.keyPressed);
|
||||
Assert.assertEquals("pressedKeys should be empty", true, applet.pressedKeys.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyFocusLost() {
|
||||
KeyEvent pressF = new KeyEvent(null, 0L, KeyEvent.PRESS, 0, 'f', 70, false);
|
||||
applet.handleKeyEvent(pressF);
|
||||
|
||||
Assert.assertTrue("keyPressed should be true after key press", applet.keyPressed);
|
||||
Assert.assertEquals("pressedKeys should have 1 entry", 1, applet.pressedKeys.size());
|
||||
|
||||
applet.focusLost();
|
||||
|
||||
Assert.assertFalse("keyPressed should be false after focus lost", applet.keyPressed);
|
||||
Assert.assertEquals("pressedKeys should be empty after focus lost", true, applet.pressedKeys.isEmpty());
|
||||
}
|
||||
}
|
||||