Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/src/processing/app/ui/Editor.java
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,7 @@ public void buildDevelopMenu(){
var updateTrigger = new JMenuItem(Language.text("menu.develop.check_for_updates"));
updateTrigger.addActionListener(e -> {
Preferences.unset("update.last");
Preferences.setInteger("update.beta_welcome", 0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<3

new UpdateCheck(base);
});
developMenu.add(updateTrigger);
Expand Down
57 changes: 13 additions & 44 deletions app/src/processing/app/ui/WelcomeToBeta.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ import processing.app.Base.getRevision
import processing.app.Base.getVersionName
import processing.app.ui.theme.LocalLocale
import processing.app.ui.theme.Locale
import processing.app.ui.theme.PDETheme
import processing.app.ui.theme.PDEComposeWindow
import processing.app.ui.theme.PDESwingWindow
import processing.app.ui.theme.ProcessingTheme
import java.awt.Cursor
import java.awt.Dimension
import java.awt.event.KeyAdapter
Expand All @@ -53,46 +55,20 @@ import javax.swing.SwingUtilities

class WelcomeToBeta {
companion object{
val windowSize = Dimension(400, 250)
val windowTitle = Locale()["beta.window.title"]

@JvmStatic
fun showWelcomeToBeta() {
val mac = SystemInfo.isMacFullWindowContentSupported
SwingUtilities.invokeLater {
JFrame(windowTitle).apply {
val close = {
Preferences.set("update.beta_welcome", getRevision().toString())
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 {
PDETheme(darkTheme = false) {
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()
val close = {
Preferences.set("update.beta_welcome", getRevision().toString())
}

PDESwingWindow("beta.window.title", onClose = close) {
welcomeToBeta(close)
}
}
}

val windowSize = Dimension(400, 200)
@Composable
fun welcomeToBeta(close: () -> Unit = {}) {
Row(
Expand Down Expand Up @@ -151,16 +127,9 @@ class WelcomeToBeta {
@JvmStatic
fun main(args: Array<String>) {
application {
val windowState = rememberWindowState(
size = windowSize.let { DpSize(it.width.dp, it.height.dp) },
position = WindowPosition(Alignment.Center)
)

Window(onCloseRequest = ::exitApplication, state = windowState, title = windowTitle) {
PDETheme(darkTheme = false) {
welcomeToBeta {
exitApplication()
}
PDEComposeWindow(titleKey = "beta.window.title", onClose = ::exitApplication){
welcomeToBeta {
exitApplication()
}
}
}
Expand Down
143 changes: 143 additions & 0 deletions app/src/processing/app/ui/theme/Window.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package processing.app.ui.theme

import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.awt.ComposePanel
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowPosition
import androidx.compose.ui.window.rememberWindowState
import com.formdev.flatlaf.util.SystemInfo

import java.awt.event.KeyAdapter
import java.awt.event.KeyEvent
import javax.swing.JFrame

val LocalWindow = compositionLocalOf<JFrame> { error("No Window Set") }

/**
* A utility class to create a new Window with Compose content in a Swing application.
* It sets up the window with some default properties and allows for custom content.
* Use this when creating a Compose based window from Swing.
*
* Usage example:
* ```
* SwingUtilities.invokeLater {
* PDESwingWindow("menu.help.welcome", fullWindowContent = true) {
*
* }
* }
* ```
*
* @param titleKey The key for the window title, which will be localized.
* @param fullWindowContent If true, the content will extend into the title bar area on macOS.
* @param content The composable content to be displayed in the window.
*/
class PDESwingWindow(titleKey: String = "", fullWindowContent: Boolean = false, onClose: () -> Unit = {}, content: @Composable BoxScope.() -> Unit): JFrame(){
init{
val window = this
defaultCloseOperation = DISPOSE_ON_CLOSE
ComposePanel().apply {
setContent {
PDEWindowContent(window, titleKey, fullWindowContent, content)
}
window.add(this)
}
background = java.awt.Color.white
setLocationRelativeTo(null)
addKeyListener(object : KeyAdapter() {
override fun keyPressed(e: KeyEvent) {
if (e.keyCode != KeyEvent.VK_ESCAPE) return

window.dispose()
onClose()
}
})
isResizable = false
isVisible = true
requestFocus()
}
}

/**
* Internal Composable function to set up the window content with theming and localization.
* It also handles macOS specific properties for full window content.
*
* @param window The JFrame instance to be configured.
* @param titleKey The key for the window title, which will be localized.
* @param fullWindowContent If true, the content will extend into the title bar area on macOS.
* @param content The composable content to be displayed in the window.
*/
@Composable
private fun PDEWindowContent(window: JFrame, titleKey: String, fullWindowContent: Boolean = false, content: @Composable BoxScope.() -> Unit){
val mac = SystemInfo.isMacOS && SystemInfo.isMacFullWindowContentSupported
remember {
window.rootPane.putClientProperty("apple.awt.fullWindowContent", mac && fullWindowContent)
window.rootPane.putClientProperty("apple.awt.transparentTitleBar", mac && fullWindowContent)
}

CompositionLocalProvider(LocalWindow provides window) {
ProcessingTheme {
val locale = LocalLocale.current
window.title = locale[titleKey]
LaunchedEffect(locale) {
window.pack()
window.setLocationRelativeTo(null)
}

Box(modifier = Modifier.padding(top = if (mac && !fullWindowContent) 22.dp else 0.dp),content = content)
}
}
}

/**
* A Composable function to create and display a new window with the specified content.
* This function sets up the window state and handles the close request.
* Use this when creating a Compose based window from another Compose context.
*
* Usage example:
* ```
* PDEComposeWindow("window.title", fullWindowContent = true, onClose = { /* handle close */ }) {
* // Your window content here
* Text("Hello, World!")
* }
* ```
*
* This will create a new window with the title localized from "window.title" key,
* with content extending into the title bar area on macOS, and a custom close handler.
*
* Fully standalone example:
* ```
* application {
* PDEComposeWindow("window.title", fullWindowContent = true, onClose = ::exitApplication) {
* // Your window content here
* }
* }
* ```
*
* @param titleKey The key for the window title, which will be localized.
* @param fullWindowContent If true, the content will extend into the title bar area on
* macOS.
* @param onClose A lambda function to be called when the window is requested to close.
* @param content The composable content to be displayed in the window.
*
*
*
*/
@Composable
fun PDEComposeWindow(titleKey: String, fullWindowContent: Boolean = false, onClose: () -> Unit = {}, content: @Composable BoxScope.() -> Unit){
val windowState = rememberWindowState(
size = DpSize.Unspecified,
position = WindowPosition(Alignment.Center)
)
Window(onCloseRequest = onClose, state = windowState, title = "") {
PDEWindowContent(window, titleKey, fullWindowContent, content)
}
}