mirror of
https://github.com/processing/processing4.git
synced 2026-02-02 13:21:07 +01:00
Merge pull request #962 from Stefterv/gradle-beta-indicator
Processing Beta Indicator
This commit is contained in:
11
app/ant/processing/app/ui/WelcomeToBeta.java
Normal file
11
app/ant/processing/app/ui/WelcomeToBeta.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package processing.app.ui;
|
||||
|
||||
|
||||
// Stub class for backwards compatibility with the ant-build system
|
||||
// This class is not used in the Gradle build system
|
||||
// The actual implementation is in src/.../Schema.kt
|
||||
public class WelcomeToBeta {
|
||||
public static void showWelcomeToBeta(){
|
||||
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ import java.io.FileOutputStream
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
|
||||
// TODO: Update to 2.10.20 and add hot-reloading: https://github.com/JetBrains/compose-hot-reload
|
||||
|
||||
plugins{
|
||||
id("java")
|
||||
kotlin("jvm") version libs.versions.kotlin
|
||||
@@ -32,6 +34,9 @@ sourceSets{
|
||||
kotlin{
|
||||
srcDirs("src")
|
||||
}
|
||||
resources{
|
||||
srcDirs("resources", listOf("languages", "fonts", "theme").map { "../build/shared/lib/$it" })
|
||||
}
|
||||
}
|
||||
test{
|
||||
kotlin{
|
||||
@@ -108,6 +113,8 @@ dependencies {
|
||||
|
||||
implementation(libs.compottie)
|
||||
implementation(libs.kaml)
|
||||
implementation(libs.markdown)
|
||||
implementation(libs.markdownJVM)
|
||||
|
||||
testImplementation(kotlin("test"))
|
||||
testImplementation(libs.mockitoKotlin)
|
||||
|
||||
5
app/src/main/resources/bird.svg
Normal file
5
app/src/main/resources/bird.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg width="900" height="900" viewBox="0 0 900 900" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M456.735 552.393L155.9 151.279" stroke="#A44D28" stroke-width="150.418"/>
|
||||
<path d="M757.575 452.113C456.738 552.391 456.738 752.948 155.903 652.67" stroke="#FF7D45" stroke-width="150.418"/>
|
||||
<path d="M556.832 552.392L456.555 51" stroke="#FFBEA2" stroke-width="150.418"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 386 B |
309
app/src/main/resources/defaults.txt
Normal file
309
app/src/main/resources/defaults.txt
Normal file
@@ -0,0 +1,309 @@
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
|
||||
# DO NOT MAKE CHANGES TO THIS FILE!!!
|
||||
|
||||
# These are the default preferences. If you want to modify
|
||||
# them directly, use the per-user local version of the file:
|
||||
|
||||
# Users -> [username] -> AppData -> Roaming ->
|
||||
# Processing -> preferences.txt (on Windows 10)
|
||||
|
||||
# ~/Library -> Processing -> preferences.txt (on macOS)
|
||||
|
||||
# ~/.config/processing -> preferences.txt (on Linux)
|
||||
|
||||
# The exact location of your preferences file can be found at
|
||||
# the bottom of the Preferences window inside Processing.
|
||||
|
||||
# Because AppData and Application Data may be considered
|
||||
# hidden or system folders on Windows, you'll have to ensure
|
||||
# that they're visible in order to get at preferences.txt
|
||||
|
||||
# You'll have problems running Processing if you incorrectly
|
||||
# modify lines in this file. It will probably not start at all.
|
||||
|
||||
# AGAIN, DO NOT ALTER THIS FILE! I'M ONLY YELLING BECAUSE I LOVE YOU!
|
||||
|
||||
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
|
||||
# If you don't want users to have their sketchbook default to
|
||||
# "My Documents/Processing" on Windows and "Documents/Processing" on OS X,
|
||||
# set this to another path that will be used by default.
|
||||
# Note that this path must exist already otherwise it won't see
|
||||
# the sketchbook folder, and will instead assume the sketchbook
|
||||
# has gone missing, and that it should instead use the default.
|
||||
# In 4.0, the location has changed.
|
||||
#sketchbook.path.four=
|
||||
|
||||
# Whether or not to show the Welcome screen for 4.0
|
||||
# (It's always available under Help → Welcome)
|
||||
welcome.four.show = true
|
||||
welcome.four.seen = false
|
||||
|
||||
# Set 'true' for the default behavior before 4.0, where the
|
||||
# main tab must have the same name as the sketch folder
|
||||
editor.sync_folder_and_filename = true
|
||||
|
||||
# By default, contributions are moved to backup folders when
|
||||
# they are removed or replaced. The backups can be found at
|
||||
# sketchbook/libraries/old, sketchbook/tools/old, and sketchbook/modes/old
|
||||
|
||||
# true to backup contributions when "Remove" button is pressed
|
||||
contribution.backup.on_remove = true
|
||||
# true to backup contributions when installing a newer version
|
||||
contribution.backup.on_install = true
|
||||
|
||||
recent.count = 10
|
||||
|
||||
# Default to the native (AWT) file selector where possible
|
||||
chooser.files.native = true
|
||||
# We were shutting this off on macOS because it broke Copy/Paste:
|
||||
# https://github.com/processing/processing/issues/1035
|
||||
# But removing again for 4.0 alpha 5, because the JFileChooser is awful,
|
||||
# and worse on Big Sur, so a bigger problem than the Copy/Paste issue.
|
||||
# https://github.com/processing/processing4/issues/77
|
||||
#chooser.files.native.macos = false
|
||||
|
||||
# set to 'lab' to interpolate theme gradients using L*a*b* color space
|
||||
theme.gradient.method = rgb
|
||||
|
||||
|
||||
# by default, check the processing server for any updates
|
||||
# (please avoid disabling, this also helps us know basic numbers
|
||||
# on how many people are using Processing)
|
||||
update.check = true
|
||||
|
||||
# on windows, automatically associate .pde files with processing.exe
|
||||
platform.auto_file_type_associations = true
|
||||
|
||||
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
|
||||
# default size for the main window
|
||||
editor.window.width.default = 700
|
||||
editor.window.height.default = 600
|
||||
|
||||
editor.window.width.min = 400
|
||||
editor.window.height.min = 500
|
||||
# tested as approx 440 on OS X
|
||||
editor.window.height.min.macos = 450
|
||||
# tested to be 515 on Windows XP, this leaves some room
|
||||
editor.window.height.min.windows = 530
|
||||
# tested with Raspberry Pi display
|
||||
editor.window.height.min.linux = 480
|
||||
|
||||
# scaling for the interface (to handle Windows and Linux HiDPI displays)
|
||||
editor.zoom = 100%
|
||||
# automatically set based on system dpi (only helps on Windows)
|
||||
editor.zoom.auto = true
|
||||
|
||||
# Use the default monospace font included in lib/fonts.
|
||||
# (As of Processing 4 alpha 5, that's Source Code Pro)
|
||||
editor.font.family = processing.mono
|
||||
editor.font.size = 12
|
||||
|
||||
# To reset everyone's default, replaced editor.antialias with editor.smooth
|
||||
# for 2.1. Fonts are unusably gross on OS X (and Linux) w/o smoothing and
|
||||
# the Oracle JVM, and many longtime users have anti-aliasing turned off.
|
||||
editor.smooth = true
|
||||
|
||||
# blink the caret by default
|
||||
editor.caret.blink = true
|
||||
# change to true to use a block (instead of a bar)
|
||||
editor.caret.block = false
|
||||
|
||||
# enable ctrl-ins, shift-ins, shift-delete for cut/copy/paste
|
||||
# on windows and linux, but disable on the mac
|
||||
editor.keys.alternative_cut_copy_paste = true
|
||||
editor.keys.alternative_cut_copy_paste.macos = false
|
||||
|
||||
# true if shift-backspace sends the delete character,
|
||||
# false if shift-backspace just means backspace
|
||||
editor.keys.shift_backspace_is_delete = false
|
||||
|
||||
# home and end keys should only travel to the start/end of the current line
|
||||
editor.keys.home_and_end_travel_far = false
|
||||
# home and end keys move to the first/last non-whitespace character,
|
||||
# and move to the actual start/end when pressed a second time.
|
||||
# Only works if editor.keys.home_and_end_travel_far is false.
|
||||
editor.keys.home_and_end_travel_smart = true
|
||||
# The OS X HI Guidelines say that home/end are relative to the document,
|
||||
# but that drives some people nuts. This pref enables/disables it.
|
||||
editor.keys.home_and_end_travel_far.macos = true
|
||||
|
||||
# Enable/disable support for complex scripts. Used for Japanese and others,
|
||||
# but disable when not needed, otherwise basic Western European chars break.
|
||||
editor.input_method_support = false
|
||||
|
||||
# convert tabs to spaces? how many spaces?
|
||||
editor.tabs.expand = true
|
||||
editor.tabs.size = 2
|
||||
|
||||
# Set to true to automatically close [ { ( " and '
|
||||
editor.completion.auto_close = false
|
||||
|
||||
# automatically indent each line
|
||||
editor.indent = true
|
||||
|
||||
# Whether to check files to see if they've been modified externally
|
||||
editor.watcher = true
|
||||
# Set true to enable debugging, since this is quirky on others' machines
|
||||
editor.watcher.debug = false
|
||||
# The window of time (in milliseconds) in which a change won't be counted
|
||||
editor.watcher.window = 1500
|
||||
|
||||
# Format and search engine to use for online queries
|
||||
search.format = https://google.com/search?q=%s
|
||||
|
||||
# font choice and size for the console
|
||||
console.font.size = 12
|
||||
|
||||
# number of lines to show by default
|
||||
console.lines = 4
|
||||
|
||||
# Number of blank lines to advance/clear console.
|
||||
# Note that those lines are also printed in the terminal when
|
||||
# Processing is executed there.
|
||||
# Setting to 0 stops this behavior.
|
||||
console.head_padding = 10
|
||||
|
||||
# Set to false to disable automatically clearing the console
|
||||
# each time 'run' is hit
|
||||
# If one sets it to false, one may also want to set 'console.head_padding'
|
||||
# to a positive number to separate outputs from different runs.
|
||||
console.auto_clear = true
|
||||
|
||||
# number of days of history to keep around before cleaning
|
||||
# setting to 0 will never clean files
|
||||
console.temp.days = 7
|
||||
|
||||
# set the maximum number of lines remembered by the console
|
||||
# the default is 500, lengthen at your own peril
|
||||
console.scrollback.lines = 500
|
||||
console.scrollback.chars = 40000
|
||||
|
||||
# Any additional Java options when running.
|
||||
# If you change this and can't run things, it's your own durn fault.
|
||||
run.options =
|
||||
|
||||
# settings for the -XmsNNNm and -XmxNNNm command line option
|
||||
run.options.memory = false
|
||||
run.options.memory.initial = 64
|
||||
run.options.memory.maximum = 512
|
||||
|
||||
# Index of the display to use for running sketches (starts at 1).
|
||||
# Kept this 1-indexed because older vesions of Processing were setting
|
||||
# the preference even before it was being used.
|
||||
# -1 means the default display, 0 means all displays
|
||||
run.display = -1
|
||||
|
||||
# set internally because it comes from the system
|
||||
#run.window.bgcolor=
|
||||
|
||||
# set to false to open a new untitled window when closing the last window
|
||||
# (otherwise, the environment will quit)
|
||||
# default to the relative norm for the different platforms,
|
||||
# but the setting can be changed in the prefs dialog anyway
|
||||
#sketchbook.closing_last_window_quits = true
|
||||
#sketchbook.closing_last_window_quits.macos = false
|
||||
|
||||
editor.untitled.prefix=sketch_
|
||||
# The old (pre-1.0, back for 2.0) style for default sketch name.
|
||||
# If you change this, be careful that this will work with your language
|
||||
# settings. For instance, MMMdd won't work on Korean-language systems
|
||||
# because it'll insert non-ASCII characters and break the environment.
|
||||
# https://github.com/processing/processing/issues/322
|
||||
editor.untitled.suffix=yyMMdd
|
||||
|
||||
# replace underscores in .pde file names with spaces
|
||||
sketch.name.replace_underscore = true
|
||||
|
||||
# what to use for generating sketch names (change in the prefs window)
|
||||
#sketch.name.approach =
|
||||
|
||||
# number of days of build history and other temp files to keep around
|
||||
# these are kept around for debugging purposes, and in case code is lost
|
||||
temp.days = 7
|
||||
|
||||
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
|
||||
# whether or not to export as full screen (present) mode
|
||||
export.application.fullscreen = false
|
||||
|
||||
# whether to show the stop button when exporting to application
|
||||
export.application.stop = true
|
||||
|
||||
# embed Java by default for lower likelihood of problems
|
||||
export.application.embed_java = true
|
||||
|
||||
# set to false to no longer delete application folders before export
|
||||
# (removed from the Preferences windows in 4.0 beta 9)
|
||||
export.delete_target_folder = true
|
||||
|
||||
# may be useful when attempting to debug the preprocessor
|
||||
preproc.save_build_files=false
|
||||
|
||||
# allows various preprocessor features to be toggled
|
||||
# in case they are causing problems
|
||||
|
||||
# preprocessor: pde.g
|
||||
preproc.color_datatype = true
|
||||
preproc.web_colors = true
|
||||
preproc.enhanced_casting = true
|
||||
|
||||
# preprocessor: PdeEmitter.java
|
||||
preproc.substitute_floats = true
|
||||
|
||||
# PdePreproc.java
|
||||
# writes out the parse tree as parseTree.xml, which can be usefully
|
||||
# viewed in (at least) Mozilla or IE. useful when debugging the preprocessor.
|
||||
preproc.output_parse_tree = false
|
||||
|
||||
# set to the program to be used for opening HTML files, folders, etc.
|
||||
#launcher.linux = xdg-open
|
||||
|
||||
# FULL SCREEN (PRESENT MODE)
|
||||
run.present.bgcolor = #666666
|
||||
run.present.stop.color = #cccccc
|
||||
|
||||
# PROXIES
|
||||
# Set a proxy server for folks that require it. This will allow the update
|
||||
# checker and the contrib manager to run properly in those environments.
|
||||
# This changed from proxy.host and proxy.port to proxy.http.host and
|
||||
# proxy.http.port in 3.0a8. In addition, https and socks were added.
|
||||
proxy.http.host=
|
||||
proxy.http.port=
|
||||
proxy.https.host=
|
||||
proxy.https.port=
|
||||
proxy.socks.host=
|
||||
proxy.socks.port=
|
||||
# Example of usage (replace 'http' with 'https' or 'socks' as needed)
|
||||
#proxy.http.host=proxy.example.com
|
||||
#proxy.http.port=8080
|
||||
# Whether to use the system proxy by default
|
||||
proxy.system=true
|
||||
|
||||
# PDE X
|
||||
pdex.errorCheckEnabled = true
|
||||
pdex.warningsEnabled = true
|
||||
pdex.writeErrorLogs = false
|
||||
|
||||
pdex.autoSave.autoSaveEnabled = false
|
||||
pdex.autoSaveInterval = 5
|
||||
pdex.autoSave.promptDisplay = true
|
||||
pdex.autoSave.autoSaveByDefault = true
|
||||
|
||||
# Enable auto-completion when hitting ctrl-space
|
||||
pdex.completion = false
|
||||
# Setting this true will show completions whenever available, not just after ctrl-space
|
||||
pdex.completion.trigger = false
|
||||
# Suggest libraries to import when a class is undefined/unavailable
|
||||
pdex.suggest.imports = true
|
||||
# Set to false to disable ctrl/cmd-click jump to definition
|
||||
pdex.inspectMode.hotkey = true
|
||||
5
app/src/main/resources/logo.svg
Normal file
5
app/src/main/resources/logo.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
||||
|
After Width: | Height: | Size: 329 B |
@@ -1,11 +1,10 @@
|
||||
package processing.app.contrib.ui
|
||||
package processing.app
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import processing.app.Base
|
||||
import processing.app.Platform
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.nio.file.*
|
||||
import java.util.Properties
|
||||
|
||||
@@ -13,10 +12,13 @@ import java.util.Properties
|
||||
const val PREFERENCES_FILE_NAME = "preferences.txt"
|
||||
const val DEFAULTS_FILE_NAME = "defaults.txt"
|
||||
|
||||
fun PlatformStart(){
|
||||
Platform.inst ?: Platform.init()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun loadPreferences(): Properties{
|
||||
Platform.init()
|
||||
PlatformStart()
|
||||
|
||||
val settingsFolder = Platform.getSettingsFolder()
|
||||
val preferencesFile = settingsFolder.resolve(PREFERENCES_FILE_NAME)
|
||||
@@ -24,20 +26,12 @@ fun loadPreferences(): Properties{
|
||||
if(!preferencesFile.exists()){
|
||||
preferencesFile.createNewFile()
|
||||
}
|
||||
val watched = watchFile(preferencesFile)
|
||||
watchFile(preferencesFile)
|
||||
|
||||
val preferences by remember {
|
||||
mutableStateOf(Properties())
|
||||
return Properties().apply {
|
||||
load(ClassLoader.getSystemResourceAsStream(DEFAULTS_FILE_NAME) ?: InputStream.nullInputStream())
|
||||
load(preferencesFile.inputStream())
|
||||
}
|
||||
|
||||
LaunchedEffect(watched){
|
||||
val defaults = Base::class.java.getResourceAsStream("/lib/${DEFAULTS_FILE_NAME}") ?: return@LaunchedEffect
|
||||
|
||||
preferences.load(defaults)
|
||||
preferences.load(preferencesFile.inputStream())
|
||||
}
|
||||
|
||||
return preferences
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -68,4 +62,12 @@ fun watchFile(file: File): Any? {
|
||||
}
|
||||
}
|
||||
return event
|
||||
}
|
||||
val LocalPreferences = compositionLocalOf<Properties> { error("No preferences provided") }
|
||||
@Composable
|
||||
fun PreferencesProvider(content: @Composable () -> Unit){
|
||||
val preferences = loadPreferences()
|
||||
CompositionLocalProvider(LocalPreferences provides preferences){
|
||||
content()
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import java.util.Random;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import processing.app.ui.WelcomeToBeta;
|
||||
import processing.core.PApplet;
|
||||
|
||||
|
||||
@@ -116,7 +117,7 @@ public class UpdateCheck {
|
||||
long now = System.currentTimeMillis();
|
||||
if (lastString != null) {
|
||||
long when = Long.parseLong(lastString);
|
||||
if (now - when < ONE_DAY) {
|
||||
if (now - when < ONE_DAY && !Base.DEBUG) {
|
||||
// don't annoy the shit outta people
|
||||
return;
|
||||
}
|
||||
@@ -134,6 +135,9 @@ public class UpdateCheck {
|
||||
// offerToUpdateContributions = !promptToVisitDownloadPage();
|
||||
promptToVisitDownloadPage();
|
||||
}
|
||||
if(latest < Base.getRevision()){
|
||||
WelcomeToBeta.showWelcomeToBeta();
|
||||
}
|
||||
|
||||
/*
|
||||
if (offerToUpdateContributions) {
|
||||
|
||||
@@ -12,8 +12,6 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.awt.ComposePanel
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.key.Key
|
||||
import androidx.compose.ui.input.key.key
|
||||
import androidx.compose.ui.input.pointer.PointerIcon
|
||||
import androidx.compose.ui.input.pointer.pointerHoverIcon
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
@@ -25,6 +23,7 @@ import com.charleskorn.kaml.Yaml
|
||||
import com.charleskorn.kaml.YamlConfiguration
|
||||
import kotlinx.serialization.Serializable
|
||||
import processing.app.Platform
|
||||
import processing.app.loadPreferences
|
||||
import java.net.URL
|
||||
import java.util.*
|
||||
import javax.swing.JFrame
|
||||
@@ -33,16 +32,7 @@ import kotlin.io.path.*
|
||||
|
||||
|
||||
fun main() = application {
|
||||
val active = remember { mutableStateOf(true) }
|
||||
if(!active.value){
|
||||
Window(onCloseRequest = ::exitApplication) {
|
||||
|
||||
}
|
||||
return@application
|
||||
}
|
||||
Window(
|
||||
onCloseRequest = { active.value = false },
|
||||
) {
|
||||
Window(onCloseRequest = ::exitApplication) {
|
||||
contributionsManager()
|
||||
}
|
||||
}
|
||||
|
||||
211
app/src/processing/app/ui/WelcomeToBeta.kt
Normal file
211
app/src/processing/app/ui/WelcomeToBeta.kt
Normal file
@@ -0,0 +1,211 @@
|
||||
package processing.app.ui
|
||||
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.MaterialTheme.colors
|
||||
import androidx.compose.material.MaterialTheme.typography
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.awt.ComposePanel
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.pointer.PointerEventType
|
||||
import androidx.compose.ui.input.pointer.PointerIcon
|
||||
import androidx.compose.ui.input.pointer.onPointerEvent
|
||||
import androidx.compose.ui.input.pointer.pointerHoverIcon
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.WindowPosition
|
||||
import androidx.compose.ui.window.application
|
||||
import androidx.compose.ui.window.rememberWindowState
|
||||
import com.formdev.flatlaf.util.SystemInfo
|
||||
import com.mikepenz.markdown.compose.Markdown
|
||||
import com.mikepenz.markdown.m2.markdownColor
|
||||
import com.mikepenz.markdown.m2.markdownTypography
|
||||
import com.mikepenz.markdown.model.MarkdownColors
|
||||
import com.mikepenz.markdown.model.MarkdownTypography
|
||||
import processing.app.Base.getRevision
|
||||
import processing.app.Base.getVersionName
|
||||
import processing.app.ui.theme.LocalLocale
|
||||
import processing.app.ui.theme.LocalTheme
|
||||
import processing.app.ui.theme.Locale
|
||||
import processing.app.ui.theme.ProcessingTheme
|
||||
import java.awt.Cursor
|
||||
import java.awt.Dimension
|
||||
import java.awt.event.KeyAdapter
|
||||
import java.awt.event.KeyEvent
|
||||
import java.io.InputStream
|
||||
import java.util.Properties
|
||||
import javax.swing.JFrame
|
||||
import javax.swing.SwingUtilities
|
||||
|
||||
|
||||
class WelcomeToBeta {
|
||||
companion object{
|
||||
val windowSize = Dimension(400, 200)
|
||||
val windowTitle = Locale()["beta.window.title"]
|
||||
|
||||
@JvmStatic
|
||||
fun showWelcomeToBeta() {
|
||||
val mac = SystemInfo.isMacFullWindowContentSupported
|
||||
SwingUtilities.invokeLater {
|
||||
JFrame(windowTitle).apply {
|
||||
val close = { dispose() }
|
||||
rootPane.putClientProperty("apple.awt.transparentTitleBar", mac)
|
||||
rootPane.putClientProperty("apple.awt.fullWindowContent", mac)
|
||||
defaultCloseOperation = JFrame.DISPOSE_ON_CLOSE
|
||||
contentPane.add(ComposePanel().apply {
|
||||
size = windowSize
|
||||
setContent {
|
||||
ProcessingTheme {
|
||||
Box(modifier = Modifier.padding(top = if (mac) 22.dp else 0.dp)) {
|
||||
welcomeToBeta(close)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
pack()
|
||||
background = java.awt.Color.white
|
||||
setLocationRelativeTo(null)
|
||||
addKeyListener(object : KeyAdapter() {
|
||||
override fun keyPressed(e: KeyEvent) {
|
||||
if (e.keyCode == KeyEvent.VK_ESCAPE) close()
|
||||
}
|
||||
})
|
||||
isResizable = false
|
||||
isVisible = true
|
||||
requestFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun welcomeToBeta(close: () -> Unit = {}) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(20.dp, 10.dp)
|
||||
.size(windowSize.width.dp, windowSize.height.dp),
|
||||
horizontalArrangement = Arrangement
|
||||
.spacedBy(20.dp)
|
||||
){
|
||||
val locale = LocalLocale.current
|
||||
Image(
|
||||
painter = painterResource("bird.svg"),
|
||||
contentDescription = locale["beta.logo"],
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterVertically)
|
||||
.size(100.dp, 100.dp)
|
||||
.offset(0.dp, (-25).dp)
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxHeight(),
|
||||
verticalArrangement = Arrangement
|
||||
.spacedBy(
|
||||
10.dp,
|
||||
alignment = Alignment.CenterVertically
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = locale["beta.title"],
|
||||
style = typography.subtitle1,
|
||||
)
|
||||
val text = locale["beta.message"]
|
||||
.replace('$' + "version", getVersionName())
|
||||
.replace('$' + "revision", getRevision().toString())
|
||||
Markdown(
|
||||
text,
|
||||
colors = markdownColor(),
|
||||
typography = markdownTypography(text = typography.body1, link = typography.body1.copy(color = colors.primary)),
|
||||
modifier = Modifier.background(Color.Transparent).padding(bottom = 10.dp)
|
||||
)
|
||||
Row {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
PDEButton(onClick = {
|
||||
close()
|
||||
}) {
|
||||
Text(
|
||||
text = locale["beta.button"],
|
||||
color = colors.onPrimary
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
@Composable
|
||||
fun PDEButton(onClick: () -> Unit, content: @Composable BoxScope.() -> Unit) {
|
||||
val theme = LocalTheme.current
|
||||
|
||||
var hover by remember { mutableStateOf(false) }
|
||||
var clicked by remember { mutableStateOf(false) }
|
||||
val offset by animateFloatAsState(if (hover) -5f else 5f)
|
||||
val color by animateColorAsState(if(clicked) colors.primaryVariant else colors.primary)
|
||||
|
||||
Box(modifier = Modifier.padding(end = 5.dp, top = 5.dp)) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.offset((-offset).dp, (offset).dp)
|
||||
.background(theme.getColor("toolbar.button.pressed.field"))
|
||||
.matchParentSize()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.onPointerEvent(PointerEventType.Press) {
|
||||
clicked = true
|
||||
}
|
||||
.onPointerEvent(PointerEventType.Release) {
|
||||
clicked = false
|
||||
onClick()
|
||||
}
|
||||
.onPointerEvent(PointerEventType.Enter) {
|
||||
hover = true
|
||||
}
|
||||
.onPointerEvent(PointerEventType.Exit) {
|
||||
hover = false
|
||||
}
|
||||
.pointerHoverIcon(PointerIcon(Cursor(Cursor.HAND_CURSOR)))
|
||||
.background(color)
|
||||
.padding(10.dp)
|
||||
.sizeIn(minWidth = 100.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
application {
|
||||
val windowState = rememberWindowState(
|
||||
size = DpSize.Unspecified,
|
||||
position = WindowPosition(Alignment.Center)
|
||||
)
|
||||
|
||||
Window(onCloseRequest = ::exitApplication, state = windowState, title = windowTitle) {
|
||||
ProcessingTheme {
|
||||
Surface(color = colors.background) {
|
||||
welcomeToBeta {
|
||||
exitApplication()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
45
app/src/processing/app/ui/theme/Locale.kt
Normal file
45
app/src/processing/app/ui/theme/Locale.kt
Normal file
@@ -0,0 +1,45 @@
|
||||
package processing.app.ui.theme
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import processing.app.LocalPreferences
|
||||
import processing.app.Messages
|
||||
import processing.app.Platform
|
||||
import processing.app.PlatformStart
|
||||
import processing.app.watchFile
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.util.*
|
||||
|
||||
class Locale(language: String = "") : Properties() {
|
||||
init {
|
||||
val locale = java.util.Locale.getDefault()
|
||||
load(ClassLoader.getSystemResourceAsStream("PDE.properties"))
|
||||
load(ClassLoader.getSystemResourceAsStream("PDE_${locale.language}.properties") ?: InputStream.nullInputStream())
|
||||
load(ClassLoader.getSystemResourceAsStream("PDE_${locale.toLanguageTag()}.properties") ?: InputStream.nullInputStream())
|
||||
load(ClassLoader.getSystemResourceAsStream("PDE_${language}.properties") ?: InputStream.nullInputStream())
|
||||
}
|
||||
|
||||
@Deprecated("Use get instead", ReplaceWith("get(key)"))
|
||||
override fun getProperty(key: String?, default: String): String {
|
||||
val value = super.getProperty(key, default)
|
||||
if(value == default) Messages.log("Missing translation for $key")
|
||||
return value
|
||||
}
|
||||
operator fun get(key: String): String = getProperty(key, key)
|
||||
}
|
||||
val LocalLocale = compositionLocalOf { Locale() }
|
||||
@Composable
|
||||
fun LocaleProvider(content: @Composable () -> Unit) {
|
||||
PlatformStart()
|
||||
|
||||
val settingsFolder = Platform.getSettingsFolder()
|
||||
val languageFile = File(settingsFolder, "language.txt")
|
||||
watchFile(languageFile)
|
||||
|
||||
val locale = Locale(languageFile.readText().substring(0, 2))
|
||||
CompositionLocalProvider(LocalLocale provides locale) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
75
app/src/processing/app/ui/theme/Theme.kt
Normal file
75
app/src/processing/app/ui/theme/Theme.kt
Normal file
@@ -0,0 +1,75 @@
|
||||
package processing.app.ui.theme
|
||||
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material.Colors
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import processing.app.LocalPreferences
|
||||
import processing.app.PreferencesProvider
|
||||
import java.io.InputStream
|
||||
import java.util.Properties
|
||||
|
||||
|
||||
class Theme(themeFile: String? = "") : Properties() {
|
||||
init {
|
||||
load(ClassLoader.getSystemResourceAsStream("theme.txt"))
|
||||
load(ClassLoader.getSystemResourceAsStream(themeFile) ?: InputStream.nullInputStream())
|
||||
}
|
||||
fun getColor(key: String): Color {
|
||||
return Color(getProperty(key).toColorInt())
|
||||
}
|
||||
}
|
||||
|
||||
val LocalTheme = compositionLocalOf<Theme> { error("No theme provided") }
|
||||
|
||||
@Composable
|
||||
fun ProcessingTheme(
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
content: @Composable() () -> Unit
|
||||
) {
|
||||
PreferencesProvider {
|
||||
val preferences = LocalPreferences.current
|
||||
val theme = Theme(preferences.getProperty("theme"))
|
||||
val colors = Colors(
|
||||
primary = theme.getColor("editor.gradient.top"),
|
||||
primaryVariant = theme.getColor("toolbar.button.pressed.field"),
|
||||
secondary = theme.getColor("editor.gradient.bottom"),
|
||||
secondaryVariant = theme.getColor("editor.scrollbar.thumb.pressed.color"),
|
||||
background = theme.getColor("editor.bgcolor"),
|
||||
surface = theme.getColor("editor.bgcolor"),
|
||||
error = theme.getColor("status.error.bgcolor"),
|
||||
onPrimary = theme.getColor("toolbar.button.enabled.field"),
|
||||
onSecondary = theme.getColor("toolbar.button.enabled.field"),
|
||||
onBackground = theme.getColor("editor.fgcolor"),
|
||||
onSurface = theme.getColor("editor.fgcolor"),
|
||||
onError = theme.getColor("status.error.fgcolor"),
|
||||
isLight = theme.getProperty("laf.mode").equals("light")
|
||||
)
|
||||
|
||||
CompositionLocalProvider(LocalTheme provides theme) {
|
||||
LocaleProvider {
|
||||
MaterialTheme(
|
||||
colors = colors,
|
||||
typography = Typography,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun String.toColorInt(): Int {
|
||||
if (this[0] == '#') {
|
||||
var color = substring(1).toLong(16)
|
||||
if (length == 7) {
|
||||
color = color or 0x00000000ff000000L
|
||||
} else if (length != 9) {
|
||||
throw IllegalArgumentException("Unknown color")
|
||||
}
|
||||
return color.toInt()
|
||||
}
|
||||
throw IllegalArgumentException("Unknown color")
|
||||
}
|
||||
38
app/src/processing/app/ui/theme/Typography.kt
Normal file
38
app/src/processing/app/ui/theme/Typography.kt
Normal file
@@ -0,0 +1,38 @@
|
||||
package processing.app.ui.theme
|
||||
|
||||
import androidx.compose.material.MaterialTheme.typography
|
||||
import androidx.compose.material.Typography
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.platform.Font
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
val processingFont = FontFamily(
|
||||
Font(
|
||||
resource = "ProcessingSans-Regular.ttf",
|
||||
weight = FontWeight.Normal,
|
||||
style = FontStyle.Normal
|
||||
),
|
||||
Font(
|
||||
resource = "ProcessingSans-Bold.ttf",
|
||||
weight = FontWeight.Bold,
|
||||
style = FontStyle.Normal
|
||||
)
|
||||
)
|
||||
|
||||
val Typography = Typography(
|
||||
body1 = TextStyle(
|
||||
fontFamily = processingFont,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 13.sp,
|
||||
lineHeight = 16.sp
|
||||
),
|
||||
subtitle1 = TextStyle(
|
||||
fontFamily = processingFont,
|
||||
fontWeight = FontWeight.Bold,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 20.sp
|
||||
)
|
||||
)
|
||||
@@ -613,7 +613,6 @@ update_check = Update
|
||||
update_check.updates_available.core = A new version of Processing is available,\nwould you like to visit the Processing download page?
|
||||
update_check.updates_available.contributions = There are updates available for some of the installed contributions,\nwould you like to open the the Contribution Manager now?
|
||||
|
||||
|
||||
# ---------------------------------------
|
||||
# Color Chooser
|
||||
|
||||
|
||||
@@ -315,6 +315,13 @@ update_check = Update
|
||||
update_check.updates_available.core = Een nieuwe versie van Processing is beschikbaar,\nwilt u de Processing download pagina bezoeken?
|
||||
update_check.updates_available.contributions = Er zijn updates beschikbaar voor sommige van de door u geïnstalleerde bijdragen,\nwilt u nu de Bijdragen Manager openen?
|
||||
|
||||
# ---------------------------------------
|
||||
# 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!
|
||||
|
||||
|
||||
# ---------------------------------------
|
||||
# Color Chooser
|
||||
|
||||
@@ -25,6 +25,8 @@ netbeansSwing = { module = "org.netbeans.api:org-netbeans-swing-outline", versio
|
||||
ant = { module = "org.apache.ant:ant", version = "1.10.14" }
|
||||
lsp4j = { module = "org.eclipse.lsp4j:org.eclipse.lsp4j", version = "0.22.0" }
|
||||
jsoup = { module = "org.jsoup:jsoup", version = "1.17.2" }
|
||||
markdown = { module = "com.mikepenz:multiplatform-markdown-renderer-m2", version = "0.31.0" }
|
||||
markdownJVM = { module = "com.mikepenz:multiplatform-markdown-renderer-jvm", version = "0.31.0" }
|
||||
|
||||
[plugins]
|
||||
jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" }
|
||||
|
||||
Reference in New Issue
Block a user