Skip to content

Commit 2624608

Browse files
committed
Show file name in windows title, show star when modifies, intercept window close request.
1 parent 3ea1380 commit 2624608

File tree

15 files changed

+249
-271
lines changed

15 files changed

+249
-271
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ ijp-scala-console
33

44
Simple user interface for executing Scala scripts. Can be run stand-alone or embedded in a desktop application.
55

6-
Currently, it is primarily developed to be run as an [ImageJ](http://rsb.info.nih.gov/ij/) plugin.
6+
Currently, it is primarily developed to be run as an [ImageJ](http://rsb.info.nih.gov/ij/) plugin. It can also run as a stand-alone application, see [ScalaConsoleApp](scala-console/src/main/scala/net/sf/ij_plugins/scala/console/ScalaConsoleApp.scala)
77

8-
![Screenshot](http://ij-plugins.sourceforge.net/plugins/scala/Screenshot-ScalaConsole.png)
8+
![Screenshot](docs/images/Scala-Console-2_screenshot.png)
99

1010
Binaries can be downloaded from the [releases] page. Some additional info is at the old [IJ Plugins](http://ij-plugins.sourceforge.net/plugins/scala/index.html) project site.
1111

149 KB
Loading
Lines changed: 37 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,37 @@
1-
/////////////////////////////////////////////////////////////////////////////
2-
// .__ __ .__ .__ //
3-
// |__| |__| ______ | | __ __ ____ |__| ____ ______ //
4-
// | | | | ______ \____ \| | | | \/ ___\| |/ \ / ___/ //
5-
// | | | | /_____/ | |_> > |_| | / /_/ > | | \\___ \ //
6-
// |__/\__| | | __/|____/____/\___ /|__|___| /____ > //
7-
// \______| |__| /_____/ \/ \/ //
8-
// //
9-
/////////////////////////////////////////////////////////////////////////////
10-
11-
12-
import ij.IJ._
13-
import ij.ImagePlus
14-
import ij.WindowManager._
15-
import scala.math._
16-
17-
18-
// get the current image
19-
val imp = getCurrentImage
20-
21-
// check that it's a valid image and if so start processing it!
22-
if (imp == null) {
23-
noImage()
24-
} else {
25-
val ip = imp.getProcessor.crop().convertToByte(false)
26-
27-
// add random noise to its pixels
28-
val width = ip.getWidth
29-
val height = ip.getHeight
30-
for (x <- 0 until width) {
31-
showProgress(x, width)
32-
for (y <- 0 until height) {
33-
val noise = round(random * 255 - 128).toInt
34-
ip.putPixel(x, y, ip.getPixel(x, y) + noise)
35-
}
36-
}
37-
showProgress(width, width)
38-
39-
// show it in a new image
40-
ip.resetMinAndMax()
41-
new ImagePlus("Noisy", ip).show()
42-
}
43-
1+
//
2+
// Add noise to the current image in ImageJ
3+
//
4+
5+
import ij.IJ._
6+
import ij.ImagePlus
7+
import ij.WindowManager._
8+
9+
import scala.math._
10+
11+
12+
// get the current image
13+
val imp = getCurrentImage
14+
15+
// check that it's a valid image and if so start processing it!
16+
if (imp == null) {
17+
noImage()
18+
} else {
19+
val ip = imp.getProcessor.crop().convertToByte(false)
20+
21+
// add random noise to its pixels
22+
val width = ip.getWidth
23+
val height = ip.getHeight
24+
for (x <- 0 until width) {
25+
showProgress(x, width)
26+
for (y <- 0 until height) {
27+
val noise = round(random * 255 - 128).toInt
28+
ip.putPixel(x, y, ip.getPixel(x, y) + noise)
29+
}
30+
}
31+
showProgress(width, width)
32+
33+
// show it in a new image
34+
ip.resetMinAndMax()
35+
new ImagePlus("Noisy", ip).show()
36+
}
37+

scala-console/examples/batchProcessImages.scala

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,12 @@
1-
/*
2-
* ImageJ Plugins
3-
* Copyright (C) 2002-2016 Jarek Sacha
4-
* Author's email: jpsacha at gmail dot com
5-
*
6-
* This library is free software; you can redistribute it and/or
7-
* modify it under the terms of the GNU Lesser General Public
8-
* License as published by the Free Software Foundation; either
9-
* version 2.1 of the License, or (at your option) any later version.
10-
*
11-
* This library is distributed in the hope that it will be useful,
12-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14-
* Lesser General Public License for more details.
15-
*
16-
* You should have received a copy of the GNU Lesser General Public
17-
* License along with this library; if not, write to the Free Software
18-
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19-
*
20-
* Latest release available at https://github.com/ij-plugins
21-
*/
1+
//
2+
// Batch process images in ImageJ applying a median filter.
3+
//
224

235
import java.io.File
246

257
import ij.{IJ, ImagePlus}
268

27-
//
28-
// Batch process images applying a median filter.
29-
//
9+
3010
batchProcess(
3111
filter = {
3212
imp =>

scala-console/examples/printWave.scala

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,12 @@
1-
/*
2-
* ImageJ Plugins
3-
* Copyright (C) 2002-2016 Jarek Sacha
4-
* Author's email: jpsacha at gmail dot com
5-
*
6-
* This library is free software; you can redistribute it and/or
7-
* modify it under the terms of the GNU Lesser General Public
8-
* License as published by the Free Software Foundation; either
9-
* version 2.1 of the License, or (at your option) any later version.
10-
*
11-
* This library is distributed in the hope that it will be useful,
12-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14-
* Lesser General Public License for more details.
15-
*
16-
* You should have received a copy of the GNU Lesser General Public
17-
* License along with this library; if not, write to the Free Software
18-
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19-
*
20-
* Latest release available at https://github.com/ij-plugins
21-
*
22-
*/
23-
241
import scala.math._
252

26-
/*
27-
* Print a wave to the standard output
28-
*/
3+
//
4+
// Print a wave to the standard output
5+
//
296
val scale = 2
307
for (x <- Range.Double(-Pi / 2, 3.5 * Pi, Pi / 5)) {
318
// Prepare empty line
32-
val line = Array.fill(scale * 2 + 1) {
33-
" "
34-
}
9+
val line = Array.fill(scale * 2 + 1)(" ")
3510
// Create marker at location `y`
3611
val y = round((sin(x) + 1) * scale).toInt
3712
line(y) = "*"

scala-console/examples/processCurrentImage.scala

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,6 @@
1-
/*
2-
* ImageJ Plugins
3-
* Copyright (C) 2002-2016 Jarek Sacha
4-
* Author's email: jpsacha at gmail dot com
5-
*
6-
* This library is free software; you can redistribute it and/or
7-
* modify it under the terms of the GNU Lesser General Public
8-
* License as published by the Free Software Foundation; either
9-
* version 2.1 of the License, or (at your option) any later version.
10-
*
11-
* This library is distributed in the hope that it will be useful,
12-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14-
* Lesser General Public License for more details.
15-
*
16-
* You should have received a copy of the GNU Lesser General Public
17-
* License along with this library; if not, write to the Free Software
18-
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19-
*
20-
* Latest release available at https://github.com/ij-plugins
21-
*/
1+
//
2+
// Apply some processing to the current image in ImageJ
3+
//
224

235
import ij.IJ
246

scala-console/src/main/scala/net/sf/ij_plugins/scala/console/ScalaConsoleApp.scala

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ import org.scalafx.extras._
2828
import scalafx.Includes._
2929
import scalafx.application.JFXApp
3030
import scalafx.application.JFXApp.PrimaryStage
31+
import scalafx.beans.binding.Bindings
3132
import scalafx.scene.image.Image
3233
import scalafx.scene.{Node, Scene}
34+
import scalafx.stage.WindowEvent
3335

3436
/**
3537
* Stand-alone Scala Console application.
@@ -44,14 +46,39 @@ object ScalaConsoleApp extends JFXApp {
4446
names.map { n => new Image(s"$path$n").delegate }
4547
}
4648

49+
val scalaConsolePane = new ScalaConsolePane()
50+
4751
stage = new PrimaryStage {
4852
scene = new Scene(640, 480) {
49-
title = "Scala Console"
50-
root = new ScalaConsolePane().view
53+
root = scalaConsolePane.view
5154
}
5255
icons ++= iconImages
53-
}
5456

57+
// Intercept window close request
58+
onCloseRequest = (event: WindowEvent) => {
59+
if (scalaConsolePane.model.onExit()) {
60+
// Exiting, allow default FX close handler
61+
} else {
62+
// Do not exit, mark close request event as done
63+
event.consume()
64+
}
65+
}
66+
67+
// Display open file name in the title
68+
title <== Bindings.createStringBinding(
69+
() => {
70+
val t = scalaConsolePane.model.editor.sourceFile.value match {
71+
case Some(f) => "Scala Console: " + f.getName
72+
case None => "Scala Console"
73+
}
74+
75+
// Add `*` when content is modified
76+
t + (if (scalaConsolePane.model.editor.needsSaving.value) "*" else "")
77+
},
78+
scalaConsolePane.model.editor.sourceFile,
79+
scalaConsolePane.model.editor.needsSaving
80+
)
81+
}
5582

5683
def setupUncaughtExceptionHandling(title: String): Unit = {
5784
Thread.setDefaultUncaughtExceptionHandler(

scala-console/src/main/scala/net/sf/ij_plugins/scala/console/ScalaConsolePaneModel.scala

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import org.scalafx.extras.onFX
3232
import scala.collection.mutable
3333
import scala.tools.nsc.interpreter.Results
3434
import scalafx.application.Platform
35-
import scalafx.beans.property.{ReadOnlyBooleanWrapper, StringProperty}
35+
import scalafx.beans.property.{ReadOnlyBooleanProperty, ReadOnlyBooleanWrapper, StringProperty}
3636

3737
/**
3838
* UI model for the Scala Console main pane.
@@ -44,7 +44,7 @@ class ScalaConsolePaneModel extends Model {
4444
val outputArea = new OutputArea()
4545

4646
private val _isReady = new ReadOnlyBooleanWrapper(this, "isReady", true)
47-
val isReady = _isReady.readOnlyProperty
47+
val isReady: ReadOnlyBooleanProperty = _isReady.readOnlyProperty
4848

4949
private val scalaInterpreter = new ScalaInterpreter()
5050

@@ -96,9 +96,21 @@ class ScalaConsolePaneModel extends Model {
9696
scalaInterpreter.run(code)
9797
}
9898

99-
def onExit(): Unit = {
100-
// TODO: Check if content needs to be saved
101-
Platform.exit()
99+
/**
100+
* Exit application if no saving is needed or saving is done.
101+
* Do not exit if user cancelled saving request.
102+
*
103+
* @return `true` when exited (application may terminate before returning).
104+
* `false` if exit was canceled.
105+
*/
106+
def onExit(): Boolean = {
107+
// Check if content needs to be saved
108+
if (editor.prepareToClose()) {
109+
Platform.exit()
110+
true
111+
} else {
112+
false
113+
}
102114
}
103115

104116
}

scala-console/src/main/scala/net/sf/ij_plugins/scala/console/ScalaConsolePaneView.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class ScalaConsolePaneView(private val fileMenu: Menu,
8181
}
8282

8383
// Create editor menu items
84-
val fileMenuItems = model.editor.fileActions.
84+
private val fileMenuItems = model.editor.fileActions.
8585
map { a =>
8686
new MenuItem {
8787
text = a.name

scala-console/src/main/scala/net/sf/ij_plugins/scala/console/editor/Editor.scala

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
/*
2-
* ImageJ Plugins
3-
* Copyright (C) 2002-2016 Jarek Sacha
4-
* Author's email: jpsacha at gmail dot com
2+
* ImageJ Plugins
3+
* Copyright (C) 2002-2016 Jarek Sacha
4+
* Author's email: jpsacha at gmail dot com
55
*
6-
* This library is free software; you can redistribute it and/or
7-
* modify it under the terms of the GNU Lesser General Public
8-
* License as published by the Free Software Foundation; either
9-
* version 2.1 of the License, or (at your option) any later version.
6+
* This library is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 2.1 of the License, or (at your option) any later version.
1010
*
11-
* This library is distributed in the hope that it will be useful,
12-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14-
* Lesser General Public License for more details.
11+
* This library is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
1515
*
16-
* You should have received a copy of the GNU Lesser General Public
17-
* License along with this library; if not, write to the Free Software
18-
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16+
* You should have received a copy of the GNU Lesser General Public
17+
* License along with this library; if not, write to the Free Software
18+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19+
*
20+
* Latest release available at https://github.com/ij-plugins
1921
*
20-
* Latest release available at https://github.com/ij-plugins
2122
*/
2223

2324
package net.sf.ij_plugins.scala.console.editor
@@ -27,6 +28,8 @@ import java.io.File
2728
import net.sf.ij_plugins.scala.console.editor.Editor.EditorEvent
2829

2930
import scala.collection.mutable
31+
import scalafx.beans.binding.BooleanBinding
32+
import scalafx.beans.property.ReadOnlyObjectProperty
3033
import scalafx.scene.Node
3134

3235
object Editor {
@@ -84,7 +87,14 @@ class Editor extends mutable.Publisher[EditorEvent] {
8487
/**
8588
* Full editor content.
8689
*/
87-
def text = _model.text
90+
def text: String = _model.text.value
91+
92+
/**
93+
* Source file from editor content was saved to read from.
94+
*/
95+
val sourceFile: ReadOnlyObjectProperty[Option[File]] = _model.sourceFile
96+
97+
val needsSaving: BooleanBinding = _model.needsSaving
8898

8999
/**
90100
* Actions for file menu.
@@ -93,8 +103,10 @@ class Editor extends mutable.Publisher[EditorEvent] {
93103

94104
/**
95105
* Perform operations needed to safely close the editor, save files, etc.
106+
*
107+
* Return 'true' if can be closed.
96108
*/
97-
def prepareToClose(): Unit = {
109+
def prepareToClose(): Boolean = {
98110
_controller.prepareToClose()
99111
}
100112

0 commit comments

Comments
 (0)