diff --git a/build.gradle.kts b/build.gradle.kts index b0ab7430..c30cd305 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,15 +4,13 @@ import java.net.URL import sciview.* plugins { - val ktVersion = "1.8.20" - val dokkaVersion = "1.8.20" - java - kotlin("jvm") version ktVersion - kotlin("kapt") version ktVersion + // Kotlin/Dokka versions are managed in gradle.properties + kotlin("jvm") + kotlin("kapt") sciview.publish sciview.sign - id("org.jetbrains.dokka") version dokkaVersion + id("org.jetbrains.dokka") jacoco `maven-publish` `java-library` @@ -25,43 +23,48 @@ java { } repositories { + if(project.properties["useMavenLocal"] == "true") { + logger.warn("Using local Maven repository as source") + mavenLocal() + } mavenCentral() maven("https://maven.scijava.org/content/groups/public") } dependencies { - val ktVersion = "1.8.20" - implementation(platform("org.scijava:pom-scijava:31.1.0")) + val scijavaParentPomVersion = project.properties["scijavaParentPOMVersion"] + val ktVersion = project.properties["kotlinVersion"] + implementation(platform("org.scijava:pom-scijava:$scijavaParentPomVersion")) // Graphics dependencies - annotationProcessor("org.scijava:scijava-common:2.90.0") - kapt("org.scijava:scijava-common:2.90.0") { // MANUAL version increment + // Attention! Manual version increment necessary here! + val scijavaCommonVersion = "2.94.1" + annotationProcessor("org.scijava:scijava-common:$scijavaCommonVersion") + kapt("org.scijava:scijava-common:$scijavaCommonVersion") { exclude("org.lwjgl") } - val sceneryVersion = "0.8.0" + val sceneryVersion = "0.9.0" api("graphics.scenery:scenery:$sceneryVersion") { version { strictly(sceneryVersion) } exclude("org.biojava.thirdparty", "forester") exclude("null", "unspecified") } - implementation("com.fasterxml.jackson.core:jackson-databind:2.13.4.2") - implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.4") - implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.4") - implementation("org.msgpack:jackson-dataformat-msgpack:0.9.3") implementation("net.java.dev.jna:jna-platform:5.11.0") - implementation("net.clearvolume:cleargl") implementation("org.janelia.saalfeldlab:n5") implementation("org.janelia.saalfeldlab:n5-imglib2") implementation("org.apache.logging.log4j:log4j-api:2.20.0") implementation("org.apache.logging.log4j:log4j-1.2-api:2.20.0") - implementation("com.formdev:flatlaf:2.6") + implementation("com.formdev:flatlaf") // SciJava dependencies + implementation("org.yaml:snakeyaml") { + version { strictly("1.33") } + } implementation("org.scijava:scijava-common") implementation("org.scijava:ui-behaviour") implementation("org.scijava:script-editor") @@ -151,6 +154,7 @@ tasks { } withType().configureEach { + val scijavaParentPomVersion = project.properties["scijavaParentPOMVersion"] val matcher = Regex("""generatePomFileFor(\w+)Publication""").matchEntire(name) val publicationName = matcher?.let { it.groupValues[1] } @@ -161,7 +165,7 @@ tasks { val parent = asNode().appendNode("parent") parent.appendNode("groupId", "org.scijava") parent.appendNode("artifactId", "pom-scijava") - parent.appendNode("version", "31.1.0") + parent.appendNode("version", "$scijavaParentPomVersion") parent.appendNode("relativePath") val repositories = asNode().appendNode("repositories") @@ -435,5 +439,7 @@ artifacts { archives(dokkaHtmlJar) } + + java.withSourcesJar() diff --git a/gradle.properties b/gradle.properties index bedcd1be..b762473c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,3 +2,6 @@ org.gradle.jvmargs=-XX:MaxMetaspaceSize=2g org.gradle.caching=true jvmTarget=11 #useLocalScenery=true +kotlinVersion=1.8.22 +dokkaVersion=1.8.20 +scijavaParentPOMVersion=35.1.1 diff --git a/settings.gradle.kts b/settings.gradle.kts index 1bab6a17..48e3d4a5 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,15 +1,21 @@ - pluginManagement { + val kotlinVersion: String by settings + val dokkaVersion: String by settings + + plugins { + kotlin("jvm") version kotlinVersion + kotlin("kapt") version kotlinVersion + id("org.jetbrains.dokka") version dokkaVersion + + id("com.github.johnrengelman.shadow") version "8.1.1" + } + repositories { gradlePluginPortal() maven("https://raw.githubusercontent.com/kotlin-graphics/mary/master") } } -//plugins { -// id("sciJava.catalogs") version "30.0.0+66" -//} - rootProject.name = "sciview" gradle.rootProject { diff --git a/src/main/java/sc/iview/commands/demo/animation/SceneRiggingDemo.java b/src/main/java/sc/iview/commands/demo/animation/SceneRiggingDemo.java index 853a17e1..bfc506f9 100644 --- a/src/main/java/sc/iview/commands/demo/animation/SceneRiggingDemo.java +++ b/src/main/java/sc/iview/commands/demo/animation/SceneRiggingDemo.java @@ -113,7 +113,7 @@ public void run() { sciView.centerOnNode( sciView.getActiveNode() ); for( PointLight light : sciView.getLights() ) { - Icosphere s = new Icosphere(1f, 1); + Icosphere s = new Icosphere(1f, 1, false); s.getMaterial().setDiffuse(light.getEmissionColor()); s.getMaterial().setAmbient(light.getEmissionColor()); s.getMaterial().setSpecular(light.getEmissionColor()); diff --git a/src/main/java/sc/iview/commands/edit/add/AddOrientationCompass.java b/src/main/java/sc/iview/commands/edit/add/AddOrientationCompass.java index da8de582..ebbefe0f 100644 --- a/src/main/java/sc/iview/commands/edit/add/AddOrientationCompass.java +++ b/src/main/java/sc/iview/commands/edit/add/AddOrientationCompass.java @@ -86,7 +86,7 @@ private Node makeAxis( float axisLength, float angleX, float angleY, float angle return null; }); - Icosphere axisCap = new Icosphere(AXESBARRADIUS, 2); + Icosphere axisCap = new Icosphere(AXESBARRADIUS, 2, false); axisCap.ifSpatial(spatial -> { spatial.setPosition(new Vector3f(0, axisLength, 0)); return null; diff --git a/src/main/java/sc/iview/io/N5IO.java b/src/main/java/sc/iview/io/N5IO.java index e7f44569..1c8407c2 100644 --- a/src/main/java/sc/iview/io/N5IO.java +++ b/src/main/java/sc/iview/io/N5IO.java @@ -29,6 +29,7 @@ package sc.iview.io; import bdv.util.AxisOrder; +import bvv.core.VolumeViewerOptions; import graphics.scenery.Group; import graphics.scenery.Node; import graphics.scenery.primitives.PointCloud; @@ -46,7 +47,6 @@ import sc.iview.SciView; import sc.iview.SciViewService; import sc.iview.process.MeshConverter; -import tpietzsch.example2.VolumeViewerOptions; import java.io.File; import java.io.IOException; diff --git a/src/main/java/sc/iview/ui/REPLPane.java b/src/main/java/sc/iview/ui/REPLPane.java index 76376259..ae617426 100644 --- a/src/main/java/sc/iview/ui/REPLPane.java +++ b/src/main/java/sc/iview/ui/REPLPane.java @@ -75,7 +75,7 @@ public REPLPane(final Context context) { final JScrollPane outputScroll = new JScrollPane(output); outputScroll.setPreferredSize(new Dimension(440, 400)); - repl = new ScriptREPL(context, output.getOutputStream()); + repl = new ScriptREPL(context, "Python (Jython)", output.getOutputStream()); repl.initialize(); final Writer writer = output.getOutputWriter(); @@ -89,7 +89,7 @@ public REPLPane(final Context context) { //prompt = new REPLEditor(repl, vars, output); prompt = new REPLEditor(repl, null, output); context.inject(prompt); - prompt.setREPLLanguage("Python"); + final JScrollPane promptScroll = new JScrollPane(prompt); final JPanel bottomPane = new JPanel(); diff --git a/src/main/kotlin/sc/iview/SciView.kt b/src/main/kotlin/sc/iview/SciView.kt index 3c404ebf..19cd7102 100644 --- a/src/main/kotlin/sc/iview/SciView.kt +++ b/src/main/kotlin/sc/iview/SciView.kt @@ -37,11 +37,11 @@ import bdv.util.RandomAccessibleIntervalSource4D import bdv.util.volatiles.VolatileView import bdv.viewer.Source import bdv.viewer.SourceAndConverter +import bvv.core.VolumeViewerOptions import dev.dirs.ProjectDirectories import graphics.scenery.* import graphics.scenery.Scene.RaycastResult import graphics.scenery.backends.Renderer -import graphics.scenery.backends.opengl.OpenGLRenderer import graphics.scenery.backends.vulkan.VulkanRenderer import graphics.scenery.controls.InputHandler import graphics.scenery.controls.OpenVRHMD @@ -110,7 +110,6 @@ import sc.iview.ui.CustomPropertyUI import sc.iview.ui.MainWindow import sc.iview.ui.SwingMainWindow import sc.iview.ui.TaskManager -import tpietzsch.example2.VolumeViewerOptions import java.awt.event.WindowListener import java.io.IOException import java.net.URL @@ -388,10 +387,9 @@ class SciView : SceneryBase, CalibratedRealInterval { versionString = versionString.substring(0, 5) val launcherVersion = Version(versionString) val nonWorkingVersion = Version("4.0.5") - if (launcherVersion.compareTo(nonWorkingVersion) <= 0 + if (launcherVersion <= nonWorkingVersion && !java.lang.Boolean.parseBoolean(System.getProperty("sciview.DisableLauncherVersionCheck", "false"))) { - logger.info("imagej-launcher version smaller or equal to non-working version ($versionString vs. 4.0.5), disabling Vulkan as rendering backend. Disable check by setting 'scenery.DisableLauncherVersionCheck' system property to 'true'.") - System.setProperty("scenery.Renderer", "OpenGLRenderer") + throw IllegalStateException("imagej-launcher version is outdated, please update your Fiji installation.") } else { logger.info("imagej-launcher version bigger that non-working version ($versionString vs. 4.0.5), all good.") } diff --git a/src/main/kotlin/sc/iview/commands/edit/Properties.kt b/src/main/kotlin/sc/iview/commands/edit/Properties.kt index 8c68403f..af46ac50 100644 --- a/src/main/kotlin/sc/iview/commands/edit/Properties.kt +++ b/src/main/kotlin/sc/iview/commands/edit/Properties.kt @@ -491,6 +491,8 @@ class Properties : InteractiveCommand() { if (node is Line){ edgeWidth = node.edgeWidth.toInt() + } else { + maybeRemoveInput("edgeWidth", java.lang.Integer::class.java) } name = node.name diff --git a/src/main/kotlin/sc/iview/ui/SwingGroupingInputHarvester.kt b/src/main/kotlin/sc/iview/ui/SwingGroupingInputHarvester.kt index 2bd7f3ee..94b2672f 100644 --- a/src/main/kotlin/sc/iview/ui/SwingGroupingInputHarvester.kt +++ b/src/main/kotlin/sc/iview/ui/SwingGroupingInputHarvester.kt @@ -95,7 +95,7 @@ class SwingGroupingInputHarvester : SwingInputHarvester() { if(panel.component.isVisible) { label.text = "▼ ${group.key}" } else { - label.text = "▶ ${group.key}" + label.text = """ ${group.key}""" } inputPanel.component.revalidate() } diff --git a/src/main/kotlin/sc/iview/ui/SwingMainWindow.kt b/src/main/kotlin/sc/iview/ui/SwingMainWindow.kt index 1404b555..2faf5037 100644 --- a/src/main/kotlin/sc/iview/ui/SwingMainWindow.kt +++ b/src/main/kotlin/sc/iview/ui/SwingMainWindow.kt @@ -46,6 +46,7 @@ import java.awt.event.* import java.util.* import javax.script.ScriptException import javax.swing.* +import kotlin.concurrent.thread import kotlin.math.roundToInt /** @@ -58,228 +59,239 @@ class SwingMainWindow(val sciview: SciView) : MainWindow { private val logger by lazyLogger() private var previousSidebarPosition = 0 - var sceneryJPanel: SceneryJPanel + lateinit var sceneryJPanel: SceneryJPanel private set - var mainSplitPane: JSplitPane + lateinit var mainSplitPane: JSplitPane protected set - var inspector: JSplitPane + lateinit var inspector: JSplitPane protected set - var interpreterPane: REPLPane + lateinit var interpreterPane: REPLPane protected set - var nodePropertyEditor: SwingNodePropertyEditor + lateinit var nodePropertyEditor: SwingNodePropertyEditor protected set - var frame: JFrame + lateinit var frame: JFrame protected set var sidebarOpen = false protected set - private var splashLabel: SplashLabel + private lateinit var splashLabel: SplashLabel private var defaultSidebarAction: (() -> Any)? = null init { - FlatLightLaf.setup() - try { - UIManager.setLookAndFeel(FlatLightLaf()) - } catch (ex: Exception) { - System.err.println("Failed to initialize Flat Light LaF, falling back to Swing default.") - } + val initializer = Runnable { + FlatLightLaf.setup() + try { + UIManager.setLookAndFeel(FlatLightLaf()) + } catch (ex: Exception) { + System.err.println("Failed to initialize Flat Light LaF, falling back to Swing default.") + } - var x: Int - var y: Int - try { - val screenSize = Toolkit.getDefaultToolkit().screenSize - x = screenSize.width / 2 - sciview.windowWidth / 2 - y = screenSize.height / 2 - sciview.windowHeight / 2 - } catch (e: HeadlessException) { - x = 10 - y = 10 - } + var x: Int + var y: Int + try { + val screenSize = Toolkit.getDefaultToolkit().screenSize + x = screenSize.width / 2 - sciview.windowWidth / 2 + y = screenSize.height / 2 - sciview.windowHeight / 2 + } catch (e: HeadlessException) { + x = 10 + y = 10 + } - frame = JFrame("sciview") - frame.layout = BorderLayout(0, 0) - frame.setSize(sciview.windowWidth, sciview.windowHeight) - frame.setLocation(x, y) - - splashLabel = SplashLabel() - val glassPane = frame.glassPane as JPanel - glassPane.isVisible = true - glassPane.layout = BorderLayout() - glassPane.isOpaque = false - glassPane.add(splashLabel, BorderLayout.CENTER) - glassPane.requestFocusInWindow() - glassPane.revalidate() - - frame.defaultCloseOperation = JFrame.DISPOSE_ON_CLOSE - nodePropertyEditor = SwingNodePropertyEditor(sciview) - - sceneryJPanel = SceneryJPanel() - JPopupMenu.setDefaultLightWeightPopupEnabled(false) - val swingMenuBar = JMenuBar() - val menus = sciview.scijavaContext?.getService(MenuService::class.java) ?: throw IllegalStateException("MenuService not available") - SwingJMenuBarCreator().createMenus(menus.getMenu("SciView"), swingMenuBar) - - val bar = ProgressPie() - bar.value = 0.0 - bar.minimumSize = Dimension(30, 30) - bar.maximumSize = Dimension(30, 30) - bar.preferredSize = Dimension(30, 30) - val progressLabel = JLabel("") - progressLabel.horizontalAlignment = SwingConstants.RIGHT - swingMenuBar.add(Box.createHorizontalGlue()) - swingMenuBar.add(progressLabel) - swingMenuBar.add(bar) - frame.jMenuBar = swingMenuBar - - sciview.taskManager.update = { current -> - if(current != null) { - progressLabel.text = "${current.source}: ${current.status} " - bar.value = current.completion.toDouble() - } else { - progressLabel.text = "" - bar.value = 0.0 + frame = JFrame("sciview") + frame.layout = BorderLayout(0, 0) + frame.setSize(sciview.windowWidth, sciview.windowHeight) + frame.setLocation(x, y) + + splashLabel = SplashLabel() + val glassPane = frame.glassPane as JPanel + glassPane.isVisible = true + glassPane.layout = BorderLayout() + glassPane.isOpaque = false + glassPane.add(splashLabel, BorderLayout.CENTER) + glassPane.requestFocusInWindow() + glassPane.revalidate() + + frame.defaultCloseOperation = JFrame.DISPOSE_ON_CLOSE + nodePropertyEditor = SwingNodePropertyEditor(sciview) + + sceneryJPanel = SceneryJPanel() + JPopupMenu.setDefaultLightWeightPopupEnabled(false) + val swingMenuBar = JMenuBar() + val menus = sciview.scijavaContext?.getService(MenuService::class.java) + ?: throw IllegalStateException("MenuService not available") + SwingJMenuBarCreator().createMenus(menus.getMenu("SciView"), swingMenuBar) + + val bar = ProgressPie() + bar.value = 0.0 + bar.minimumSize = Dimension(30, 30) + bar.maximumSize = Dimension(30, 30) + bar.preferredSize = Dimension(30, 30) + val progressLabel = JLabel("") + progressLabel.horizontalAlignment = SwingConstants.RIGHT + swingMenuBar.add(Box.createHorizontalGlue()) + swingMenuBar.add(progressLabel) + swingMenuBar.add(bar) + frame.jMenuBar = swingMenuBar + + sciview.taskManager.update = { current -> + if (current != null) { + progressLabel.text = "${current.source}: ${current.status} " + bar.value = current.completion.toDouble() + } else { + progressLabel.text = "" + bar.value = 0.0 + } + + bar.repaint() + } + sceneryJPanel.isVisible = true + nodePropertyEditor.component // Initialize node property panel + + val inspectorTree = nodePropertyEditor.tree + inspectorTree.toggleClickCount = 0 // This disables expanding menus on double click + val inspectorProperties = nodePropertyEditor.props + + val container = JPanel(CardLayout()) + + var propsPane = JScrollPane(inspectorProperties) + var treePane = JScrollPane(inspectorTree) + propsPane.verticalScrollBar.unitIncrement = 16 + treePane.verticalScrollBar.unitIncrement = 16 + inspector = JSplitPane(JSplitPane.VERTICAL_SPLIT, // + treePane, + propsPane) + inspector.dividerLocation = sciview.windowHeight / 3 + inspector.isContinuousLayout = true + inspector.border = BorderFactory.createEmptyBorder() + inspector.dividerSize = 4 + inspector.name = "Inspector" + container.add(inspector, "Inspector") + + // We need to get the surface scale here before initialising scenery's renderer, as + // the information is needed already at initialisation time. + val dt = frame.graphicsConfiguration.defaultTransform + val surfaceScale = Vector2f(dt.scaleX.toFloat(), dt.scaleY.toFloat()) + sciview.getScenerySettings().set("Renderer.SurfaceScale", surfaceScale) + interpreterPane = REPLPane(sciview.scijavaContext) + interpreterPane.component.border = BorderFactory.createEmptyBorder() + interpreterPane.component.name = "REPL" + container.add(interpreterPane.component, "REPL") + thread { + initializeInterpreter() } + mainSplitPane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT, + sceneryJPanel, + container + ) + mainSplitPane.dividerLocation = frame.width + mainSplitPane.border = BorderFactory.createEmptyBorder() + mainSplitPane.dividerSize = 4 + mainSplitPane.resizeWeight = 1.0 + mainSplitPane.rightComponent = null - bar.repaint() - } - sceneryJPanel.isVisible = true - nodePropertyEditor.component // Initialize node property panel - - val inspectorTree = nodePropertyEditor.tree - inspectorTree.toggleClickCount = 0 // This disables expanding menus on double click - val inspectorProperties = nodePropertyEditor.props - - val container = JPanel(CardLayout()) - - var propsPane = JScrollPane(inspectorProperties) - var treePane = JScrollPane(inspectorTree) - propsPane.verticalScrollBar.unitIncrement = 16 - treePane.verticalScrollBar.unitIncrement = 16 - inspector = JSplitPane(JSplitPane.VERTICAL_SPLIT, // - treePane, - propsPane) - inspector.dividerLocation = sciview.windowHeight / 3 - inspector.isContinuousLayout = true - inspector.border = BorderFactory.createEmptyBorder() - inspector.dividerSize = 1 - inspector.name = "Inspector" - container.add(inspector, "Inspector") - - // We need to get the surface scale here before initialising scenery's renderer, as - // the information is needed already at initialisation time. - val dt = frame.graphicsConfiguration.defaultTransform - val surfaceScale = Vector2f(dt.scaleX.toFloat(), dt.scaleY.toFloat()) - sciview.getScenerySettings().set("Renderer.SurfaceScale", surfaceScale) - interpreterPane = REPLPane(sciview.scijavaContext) - interpreterPane.component.border = BorderFactory.createEmptyBorder() - interpreterPane.component.name = "REPL" - container.add(interpreterPane.component, "REPL") - initializeInterpreter() - mainSplitPane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT, - sceneryJPanel, - container - ) - mainSplitPane.dividerLocation = frame.width - mainSplitPane.border = BorderFactory.createEmptyBorder() - mainSplitPane.dividerSize = 1 - mainSplitPane.resizeWeight = 0.5 - mainSplitPane.rightComponent = null - - val toolbar = JToolBar() - toolbar.orientation = SwingConstants.VERTICAL - - val inspectorIcon = Utils.getScaledImageIcon(SciView::class.java.getResource("toolbox.png"), 16, 16) - val inspectorButton = JToggleButton() - inspectorButton.toolTipText = "Inspector" - - val inspectorAction = object: AbstractAction("Inspector", inspectorIcon) { - override fun actionPerformed(e: ActionEvent) { - container.toggleSidebarComponent(inspector, toolbar, inspectorButton, e) + val toolbar = JToolBar() + toolbar.orientation = SwingConstants.VERTICAL + + val inspectorIcon = Utils.getScaledImageIcon(SciView::class.java.getResource("toolbox.png"), 16, 16) + val inspectorButton = JToggleButton() + inspectorButton.toolTipText = "Inspector" + + val inspectorAction = object : AbstractAction("Inspector", inspectorIcon) { + override fun actionPerformed(e: ActionEvent) { + container.toggleSidebarComponent(inspector, toolbar, inspectorButton, e) + } } - } - defaultSidebarAction = { container.toggleSidebarComponent(inspector, toolbar, inspectorButton, null) } + defaultSidebarAction = { container.toggleSidebarComponent(inspector, toolbar, inspectorButton, null) } - inspectorButton.action = inspectorAction - inspectorButton.icon = inspectorIcon - inspectorButton.hideActionText = true + inspectorButton.action = inspectorAction + inspectorButton.icon = inspectorIcon + inspectorButton.hideActionText = true - val replIcon = Utils.getScaledImageIcon(SciView::class.java.getResource("terminal.png"), 16, 16) - val replButton = JToggleButton() - replButton.toolTipText = "Script Interpreter" + val replIcon = Utils.getScaledImageIcon(SciView::class.java.getResource("terminal.png"), 16, 16) + val replButton = JToggleButton() + replButton.toolTipText = "Script Interpreter" - val replAction = object: AbstractAction("REPL", replIcon) { - override fun actionPerformed(e: ActionEvent) { - container.toggleSidebarComponent(interpreterPane.component, toolbar, replButton, e) + val replAction = object : AbstractAction("REPL", replIcon) { + override fun actionPerformed(e: ActionEvent) { + container.toggleSidebarComponent(interpreterPane.component, toolbar, replButton, e) + } } - } - replButton.action = replAction - replButton.icon = replIcon - replButton.hideActionText = true - - toolbar.add(inspectorButton) - toolbar.add(replButton) - - //frame.add(mainSplitPane, BorderLayout.CENTER); - frame.add(mainSplitPane, BorderLayout.CENTER) - frame.add(toolbar, BorderLayout.EAST) - frame.defaultCloseOperation = JFrame.DO_NOTHING_ON_CLOSE - frame.addWindowListener(object : WindowAdapter() { - override fun windowClosing(e: WindowEvent) { - logger.debug("Closing SciView window.") - close() - sciview.scijavaContext?.service(SciViewService::class.java)?.close(sciview) - sciview.isClosed = true - } - }) - - frame.isVisible = true - glassPane.repaint() - - sciview.sceneryPanel[0] = sceneryJPanel - val renderer = Renderer.createRenderer( - sciview.hub, - sciview.applicationName, - sciview.currentScene, - sciview.windowWidth, - sciview.windowHeight, - sciview.sceneryPanel[0] - ) - - sciview.setRenderer(renderer) - sciview.hub.add(SceneryElement.Renderer, renderer) - sciview.reset() - - SwingUtilities.invokeLater { - try { - while (!sciview.getSceneryRenderer()!!.firstImageReady) { - logger.debug("Waiting for renderer initialisation") - Thread.sleep(300) + replButton.action = replAction + replButton.icon = replIcon + replButton.hideActionText = true + + toolbar.add(inspectorButton) + toolbar.add(replButton) + + //frame.add(mainSplitPane, BorderLayout.CENTER); + frame.add(mainSplitPane, BorderLayout.CENTER) + frame.add(toolbar, BorderLayout.EAST) + frame.defaultCloseOperation = JFrame.DO_NOTHING_ON_CLOSE + frame.addWindowListener(object : WindowAdapter() { + override fun windowClosing(e: WindowEvent) { + logger.debug("Closing SciView window.") + close() + sciview.scijavaContext?.service(SciViewService::class.java)?.close(sciview) + sciview.isClosed = true } - Thread.sleep(200) - } catch (e: InterruptedException) { - logger.error("Renderer construction interrupted.") - } - nodePropertyEditor.rebuildTree() - logger.info("Done initializing SciView") + }) + + frame.isVisible = true + glassPane.repaint() + + sciview.sceneryPanel[0] = sceneryJPanel + val renderer = Renderer.createRenderer( + sciview.hub, + sciview.applicationName, + sciview.currentScene, + sciview.windowWidth, + sciview.windowHeight, + sciview.sceneryPanel[0] + ) + + sciview.setRenderer(renderer) + sciview.hub.add(SceneryElement.Renderer, renderer) + sciview.reset() + + SwingUtilities.invokeLater { + try { + while (!sciview.getSceneryRenderer()!!.firstImageReady) { + logger.debug("Waiting for renderer initialisation") + Thread.sleep(300) + } + Thread.sleep(200) + } catch (e: InterruptedException) { + logger.error("Renderer construction interrupted.") + } + nodePropertyEditor.rebuildTree() + logger.info("Done initializing SciView") - // subscribe to Node{Added, Removed, Changed} events, happens automatically + // subscribe to Node{Added, Removed, Changed} events, happens automatically // eventService!!.subscribe(this) - sceneryJPanel.isVisible = true + sceneryJPanel.isVisible = true - // install hook to keep inspector updated on external changes (scripting, etc) - sciview.currentScene.onNodePropertiesChanged["updateInspector"] = { node: Node -> - if (node === nodePropertyEditor.currentNode) { - nodePropertyEditor.updateProperties(node) + // install hook to keep inspector updated on external changes (scripting, etc) + sciview.currentScene.onNodePropertiesChanged["updateInspector"] = { node: Node -> + if (node === nodePropertyEditor.currentNode) { + nodePropertyEditor.updateProperties(node) + } } - } - // Enable push rendering by default - renderer.pushMode = true - sciview.camera!!.setPosition(1.65, 1) - glassPane.isVisible = false + // Enable push rendering by default + renderer.pushMode = true + sciview.camera!!.setPosition(1.65, 1) + glassPane.isVisible = false + + sceneryJPanel.minimumSize = Dimension(256, 256) + } + } - sceneryJPanel.minimumSize = Dimension(256, 256) + if(SwingUtilities.isEventDispatchThread()) { + initializer.run() + } else { + SwingUtilities.invokeAndWait(initializer) } } diff --git a/src/main/kotlin/sc/iview/ui/SwingNodePropertyEditor.kt b/src/main/kotlin/sc/iview/ui/SwingNodePropertyEditor.kt index 83f517e4..b9f05517 100644 --- a/src/main/kotlin/sc/iview/ui/SwingNodePropertyEditor.kt +++ b/src/main/kotlin/sc/iview/ui/SwingNodePropertyEditor.kt @@ -32,6 +32,8 @@ import com.intellij.ui.components.JBPanel import graphics.scenery.Camera import graphics.scenery.Node import graphics.scenery.Scene +import graphics.scenery.volumes.TransferFunctionEditor +import graphics.scenery.volumes.Volume import net.miginfocom.swing.MigLayout import org.joml.Quaternionf import org.joml.Vector3f @@ -334,12 +336,21 @@ class SwingNodePropertyEditor(private val sciView: SciView) : UIComponent { material.setAmbient( new Vector3f( 1.0f, 0.0f, 0.0f ) ); material.setDiffuse( new Vector3f( 1.0f, 0.0f, 0.0f ) );