Browse Source

Working on selection in the ImageTilePane.

Added a deselect while holding control
Added some logic for opening files on different OS's
Added some OS specific variables and logging
master
Drew Short 10 years ago
parent
commit
10439606db
  1. 1
      engine/src/main/java/com/sothr/imagetools/engine/AppConfig.java
  2. 5
      engine/src/main/scala/com/sothr/imagetools/engine/util/PropertiesService.scala
  3. 5
      gui/src/main/resources/fxml/mainapp/MainApp.fxml
  4. 10
      gui/src/main/scala/com/sothr/imagetools/ui/component/ImageTile.scala
  5. 29
      gui/src/main/scala/com/sothr/imagetools/ui/component/ImageTilePane.scala
  6. 33
      gui/src/main/scala/com/sothr/imagetools/ui/controller/AppController.scala
  7. 21
      gui/src/main/scala/com/sothr/imagetools/ui/util/FileUtil.scala

1
engine/src/main/java/com/sothr/imagetools/engine/AppConfig.java

@ -94,6 +94,7 @@ public class AppConfig {
String message = fromFile ? "From File" : "From Defaults";
logger.info(String.format("Configured Logger %s", message));
logger.info(String.format("Detected Version: %s of Image Tools", PropertiesService.getVersion().toString()));
logger.info(String.format("Running on %s, %s, %s",PropertiesService.OS(), PropertiesService.OS_VERSION(),PropertiesService.OS_ARCH()));
}
//Only configure logging from the default file once

5
engine/src/main/scala/com/sothr/imagetools/engine/util/PropertiesService.scala

@ -38,6 +38,11 @@ object PropertiesService extends Logging {
var pHashWeight = 0.0f
var usePhash = false
//OS information
val OS = System.getProperty("os.name", "UNKNOWN")
val OS_VERSION = System.getProperty("os.version", "UNKNOWN")
val OS_ARCH = System.getProperty("os.arch", "UNKNOWN")
/*
* Load the properties file from the specified location
*/

5
gui/src/main/resources/fxml/mainapp/MainApp.fxml

@ -2,6 +2,7 @@
<!--suppress ALL -->
<?import javafx.scene.effect.*?>
<?import java.lang.*?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
@ -128,9 +129,9 @@
<Insets />
</VBox.margin>
</ScrollPane>
<Pagination fx:id="paginator" disable="true" maxHeight="40.0" maxPageIndicatorCount="9" maxWidth="1.7976931348623157E308" minHeight="40.0" pageCount="1" prefHeight="40.0">
<Pagination fx:id="paginator" disable="true" maxHeight="40.0" maxPageIndicatorCount="20" maxWidth="1.7976931348623157E308" minHeight="40.0" pageCount="1" prefHeight="40.0">
<opaqueInsets>
<Insets />
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</opaqueInsets></Pagination>
</children>
</VBox>

10
gui/src/main/scala/com/sothr/imagetools/ui/component/ImageTile.scala

@ -1,6 +1,7 @@
package com.sothr.imagetools.ui.component
import java.io.FileInputStream
import java.awt.Desktop
import java.io.{File, FileInputStream}
import javafx.event.{EventType, EventHandler}
import javafx.geometry.{Orientation, Insets, Pos}
import javafx.scene.control.{Separator, Tooltip, Label}
@ -8,6 +9,7 @@ import javafx.scene.image.{ImageView}
import javafx.scene.input.{PickResult, ContextMenuEvent, MouseEvent}
import javafx.scene.layout.VBox
import com.sothr.imagetools.ui.util.FileUtil
import grizzled.slf4j.Logging
import resource._
@ -37,6 +39,9 @@ class ImageTile(thumbnailWidth: Integer,
if (event.isShiftDown) {
//multiple selection
imageTilePane.addImageSelected(thisTile)
//remove individual images with control
} else if (event.isControlDown) {
imageTilePane.removeImageSelected(thisTile)
}
else {
if (event.isPrimaryButtonDown) {
@ -45,13 +50,14 @@ class ImageTile(thumbnailWidth: Integer,
if (event.getClickCount == 2) {
// Look into http://stackoverflow.com/questions/228477/how-do-i-programmatically-determine-operating-system-in-java
// for proper multi-platform opening support
//Desktop.getDesktop.open(new File(image.getImagePath))
FileUtil.openInEditor(new File(image.getImagePath))
} else {
}
} else if (event.isSecondaryButtonDown) {
//right click context menu
debug("Requesting Context Menu")
imageTilePane.addImageSelected(thisTile)
val contextMenuEvent = new ContextMenuEvent(
thisTile,
thisTile,

29
gui/src/main/scala/com/sothr/imagetools/ui/component/ImageTilePane.scala

@ -88,6 +88,15 @@ class ImageTilePane extends TilePane with Logging {
def addImageSelected(imageTile: ImageTile) = {
this.selectionModel.select(this.getChildren.indexOf(imageTile))
}
def removeImageSelected(imageTile: ImageTile) = {
this.selectionModel.clearSelection(this.getChildren.indexOf(imageTile))
}
def clearSelection() = {
this.selectionModel.clearSelection()
}
}
/**
@ -153,7 +162,11 @@ class ImageTilePaneSelectionModel[ImageTile](parentTilePane: ImageTilePane) exte
}
override def clearSelection(index: Int): Unit = {
this.selectedIndexes.remove(index)
val i = this.selectedIndexes.indexOf(index)
if (i >= 0) {
clearSelectionFormatting(index)
this.selectedIndexes.remove(i)
}
}
override def clearSelection(): Unit = {
@ -178,8 +191,11 @@ class ImageTilePaneSelectionModel[ImageTile](parentTilePane: ImageTilePane) exte
}
override def select(index: Int): Unit = {
setSelectionFormatting(index)
this.selectedIndexes.add(index)
//can only select once
if (! this.selectedIndexes.contains(index)) {
setSelectionFormatting(index)
this.selectedIndexes.add(index)
}
}
override def select(obj: ImageTile): Unit = {
@ -199,6 +215,11 @@ class ImageTilePaneSelectionModel[ImageTile](parentTilePane: ImageTilePane) exte
this.selectedIndexes.contains(index)
}
private def clearSelectionFormatting(index: Int) = {
val tile = this.parentTilePane.getChildren.get(index).asInstanceOf[VBox]
tile.setBorder(Border.EMPTY)
}
private def clearSelectionFormatting() = {
val iterator = this.parentTilePane.getChildren.iterator()
while (iterator.hasNext) {
@ -212,7 +233,7 @@ class ImageTilePaneSelectionModel[ImageTile](parentTilePane: ImageTilePane) exte
setSelectionFormatting(this.parentTilePane.getChildren.get(index).asInstanceOf[ImageTile])
}
private def setSelectionFormatting(imageTile: ImageTile): Unit = {
private def setSelectionFormatting(imageTile: ImageTile) = {
val borderStroke = new BorderStroke(Color.BLUE, BorderStrokeStyle.SOLID, CornerRadii.EMPTY,BorderStroke.THIN)
imageTile.asInstanceOf[VBox].setBorder(new Border(borderStroke))
}

33
gui/src/main/scala/com/sothr/imagetools/ui/controller/AppController.scala

@ -80,6 +80,9 @@ class AppController extends Logging {
PropertiesService.set("app.ui.thumbsPerPage", "100")
}
//setup the paginator
//font size doesn't increase the size of the buttons
//paginator.setStyle("-fx-font-size:13;")
// configure the page factory
paginator.setPageFactory(new Callback[Integer, Node]() {
override def call(pageIndex: Integer): Node = {
@ -188,7 +191,8 @@ class AppController extends Logging {
resetPaginator()
getImageTilePane.getChildren.setAll(new java.util.ArrayList[Node]())
val f: Future[List[Image]] = Future {
engine.getImagesForDirectory(currentDirectory, recursive = doRecursiveProcessing.isSelected)
val images = engine.getImagesForDirectory(currentDirectory, recursive = doRecursiveProcessing.isSelected)
images.sortWith((x,y) => x.imagePath < y.imagePath)
}
f onComplete {
@ -212,22 +216,23 @@ class AppController extends Logging {
resetPaginator()
imageTilePane.getChildren.setAll(new java.util.ArrayList[Node]())
val f: Future[List[SimilarImages]] = Future {
engine.getSimilarImagesForDirectory(currentDirectory, recursive = doRecursiveProcessing.isSelected)
val f: Future[List[Image]] = Future {
val similarImages = engine.getSimilarImagesForDirectory(currentDirectory, recursive = doRecursiveProcessing.isSelected)
val tempImages = new mutable.MutableList[Image]()
for (similarImage <- similarImages) {
debug(s"Adding similar images ${similarImage.rootImage.toString} to app")
tempImages += similarImage.rootImage
similarImage.similarImages.foreach(image => tempImages += image)
}
tempImages.toList.sortWith((x,y) => x.imagePath < y.imagePath)
}
f onComplete {
case Success(similarImages) =>
info(s"Displaying ${similarImages.length} similar images")
case Success(images) =>
info(s"Displaying ${images.length} similar images")
Platform.runLater(new Runnable() {
override def run() {
val tempImages = new mutable.MutableList[Image]()
for (similarImage <- similarImages) {
debug(s"Adding similar images ${similarImage.rootImage.toString} to app")
tempImages += similarImage.rootImage
similarImage.similarImages.foreach(image => tempImages += image)
}
setPagesContent(tempImages.toList)
setPagesContent(images)
showPage(0)
}
})
@ -246,7 +251,7 @@ class AppController extends Logging {
}
def setPagesContent(images: List[Image]) = {
this.currentImages = images.sortWith((x,y) => x.imagePath < y.imagePath)
this.currentImages = images
//set the appropriate size for the pagination
val itemsPerPage = PropertiesService.get("app.ui.thumbsPerPage", "100").toInt
val pageNum = Math.ceil(this.currentImages.size.toFloat / itemsPerPage).toInt
@ -258,6 +263,8 @@ class AppController extends Logging {
val itemsPerPage = PropertiesService.get("app.ui.thumbsPerPage", "100").toInt
val startIndex = pageIndex * itemsPerPage
val endIndex = if ((startIndex + itemsPerPage) > this.currentImages.size) this.currentImages.length else startIndex + itemsPerPage
//clear any selections
getImageTilePane.asInstanceOf[ImageTilePane].clearSelection()
//clear and populate the scrollpane
getImageTilePane.getChildren.setAll(new java.util.ArrayList[Node]())
val images = this.currentImages.slice(startIndex, endIndex)

21
gui/src/main/scala/com/sothr/imagetools/ui/util/FileUtil.scala

@ -0,0 +1,21 @@
package com.sothr.imagetools.ui.util
import java.awt.Desktop
import java.io.File
import com.sothr.imagetools.engine.util.PropertiesService
import grizzled.slf4j.Logging
/**
* Created by Drew Short on 8/31/2014.
*/
object FileUtil extends Logging {
def openInEditor(file: File) = {
PropertiesService.OS.toLowerCase match {
// Open file on windows
case os if os.startsWith("windows") => Desktop.getDesktop.open(file)
case default => error(s"Do not know how to open editor for OS: ${PropertiesService.OS}, ${PropertiesService.OS_VERSION}, ${PropertiesService.OS_ARCH}")
}
}
}
Loading…
Cancel
Save