Browse Source

Added highlighting boxes around selection. Shift click for multi selection. Single click for single selection. Need to work on context menus next

master
Drew Short 10 years ago
parent
commit
a81ad158e0
  1. 60
      gui/src/main/scala/com/sothr/imagetools/ui/component/ImageTile.scala
  2. 5
      gui/src/main/scala/com/sothr/imagetools/ui/component/ImageTileFactory.scala
  3. 46
      gui/src/main/scala/com/sothr/imagetools/ui/component/ImageTilePane.scala
  4. 8
      gui/src/main/scala/com/sothr/imagetools/ui/controller/AppController.scala

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

@ -2,8 +2,8 @@ package com.sothr.imagetools.ui.component
import java.io.FileInputStream
import javafx.event.EventHandler
import javafx.geometry.Pos
import javafx.scene.control.{Tooltip, Label}
import javafx.geometry.{Orientation, Insets, Pos}
import javafx.scene.control.{Separator, Tooltip, Label}
import javafx.scene.image.{ImageView}
import javafx.scene.input.MouseEvent
import javafx.scene.layout.VBox
@ -16,32 +16,53 @@ import resource._
*
* Created by drew on 8/22/14.
*/
class ImageTile(thumbnailWidth: Integer, image: com.sothr.imagetools.engine.image.Image) extends VBox with Logging {
val imageData: com.sothr.imagetools.engine.image.Image = image
val preferedTileSize = (thumbnailWidth + 32).toDouble
class ImageTile(thumbnailWidth: Integer,
image: com.sothr.imagetools.engine.image.Image,
imageTilePane: ImageTilePane) extends VBox with Logging {
val thisTile = this
val imageData = image
val preferedTileWidth = (thumbnailWidth + 8).toDouble
val preferedTileHeight = (thumbnailWidth + 32).toDouble
//set tile size
this.setPrefSize(preferedTileSize, preferedTileSize)
this.setMinSize(preferedTileSize, preferedTileSize)
this.setMaxSize(preferedTileSize, preferedTileSize)
this.setPrefSize(preferedTileWidth, preferedTileHeight)
this.setMinSize(preferedTileWidth, preferedTileHeight)
this.setMaxSize(preferedTileWidth, preferedTileHeight)
this.setAlignment(Pos.TOP_CENTER)
//set padding on the tiles
//this.setPadding(new Insets(10.0d,0.0d,10.0d,0.0d))
this.setAlignment(Pos.CENTER)
this.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler[MouseEvent] {
override def handle(event: MouseEvent): Unit = {
if (event.isPrimaryButtonDown) {
//double click
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))
} else {
if (event.isShiftDown) {
//multiple selection
imageTilePane.addImageSelected(thisTile)
}
else {
if (event.isPrimaryButtonDown) {
imageTilePane.imageSelected(thisTile)
//double click
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))
} else {
}
} else if (event.isSecondaryButtonDown) {
//right click context menu
}
} else if (event.isSecondaryButtonDown) {
//right click context menu
}
}
})
//Separator
val separator = new Separator()
separator.setOrientation(Orientation.HORIZONTAL)
separator.setMaxHeight(5.0d)
separator.setVisible(false)
this.getChildren.add(separator)
// Image
val genImageView = new ImageView()
debug(s"Getting thumbnail from: ${image.getThumbnailPath}")
@ -63,6 +84,9 @@ class ImageTile(thumbnailWidth: Integer, image: com.sothr.imagetools.engine.imag
val imageLabel = new Label()
imageLabel.setText(s"${image.getHeight}x${image.getWidth}")
imageLabel.setWrapText(true)
imageLabel.setMaxHeight(32d)
imageLabel.setMaxWidth(preferedTileWidth-2)
imageLabel.setAlignment(Pos.BOTTOM_CENTER)
//Tooltip
val tooltip = new Tooltip()

5
gui/src/main/scala/com/sothr/imagetools/ui/component/ImageTileFactory.scala

@ -1,6 +1,7 @@
package com.sothr.imagetools.ui.component
import javafx.geometry.Insets
import javafx.scene.layout.TilePane
import com.sothr.imagetools.engine.util.PropertiesService
import grizzled.slf4j.Logging
@ -12,9 +13,9 @@ import grizzled.slf4j.Logging
*/
object ImageTileFactory extends Logging {
def get(image: com.sothr.imagetools.engine.image.Image): ImageTile = {
def get(image: com.sothr.imagetools.engine.image.Image, pane: TilePane): ImageTile = {
val thumbnailWidth = PropertiesService.get("app.thumbnail.size","128").toInt
val imageTile = new ImageTile(thumbnailWidth, image)
val imageTile = new ImageTile(thumbnailWidth, image, pane.asInstanceOf[ImageTilePane])
//set padding
imageTile.setPadding(new Insets(2, 2, 2, 2))

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

@ -3,7 +3,8 @@ package com.sothr.imagetools.ui.component
import java.util
import javafx.collections.{ModifiableObservableListBase, ObservableList}
import javafx.scene.control.MultipleSelectionModel
import javafx.scene.layout.TilePane
import javafx.scene.layout._
import javafx.scene.paint.{Color, Paint}
/**
* Custom Tile Pane with a multi selection model
@ -12,6 +13,14 @@ import javafx.scene.layout.TilePane
*/
class ImageTilePane extends TilePane {
val selectionModel = new ImageTilePaneSelectionModel(this)
def imageSelected(imageTile: ImageTile) = {
this.selectionModel.clearAndSelect(this.getChildren.indexOf(imageTile))
}
def addImageSelected(imageTile: ImageTile) = {
this.selectionModel.select(this.getChildren.indexOf(imageTile))
}
}
/**
@ -36,32 +45,43 @@ class ImageTilePaneSelectionModel[ImageTile](parentTilePane: ImageTilePane) exte
}
override def selectIndices(index: Int, indices: Int*): Unit = {
clearSelectionFormatting
this.selectedIndexes.clear()
setSelectionFormatting(index)
this.selectedIndexes.add(index)
for (i <- indices) {
setSelectionFormatting(i)
this.selectedIndexes.add(i)
}
}
override def selectAll(): Unit = {
clearSelectionFormatting
this.selectedIndexes.clear()
for (index <- 0 until this.parentTilePane.getChildren.size()) {
setSelectionFormatting(index)
this.selectedIndexes.add(index)
}
}
override def selectFirst(): Unit = {
clearSelectionFormatting
this.selectedIndexes.clear()
setSelectionFormatting(0)
this.selectedIndexes.add(0)
}
override def selectLast(): Unit = {
clearSelectionFormatting
this.selectedIndexes.clear()
setSelectionFormatting(this.parentTilePane.getChildren.size()-1)
this.selectedIndexes.add(this.parentTilePane.getChildren.size()-1)
}
override def clearAndSelect(index: Int): Unit = {
clearSelectionFormatting
this.selectedIndexes.clear()
setSelectionFormatting(index)
this.selectedIndexes.add(index)
}
@ -70,6 +90,7 @@ class ImageTilePaneSelectionModel[ImageTile](parentTilePane: ImageTilePane) exte
}
override def clearSelection(): Unit = {
clearSelectionFormatting
this.selectedIndexes.clear()
}
@ -90,13 +111,15 @@ class ImageTilePaneSelectionModel[ImageTile](parentTilePane: ImageTilePane) exte
}
override def select(index: Int): Unit = {
this.selectedIndexes.clear()
setSelectionFormatting(index)
this.selectedIndexes.add(index)
}
override def select(obj: ImageTile): Unit = {
if (this.parentTilePane.getChildren.contains(obj)) {
clearSelectionFormatting
this.selectedIndexes.clear()
setSelectionFormatting(obj)
this.selectedIndexes.add(this.parentTilePane.getChildren.indexOf(obj))
}
}
@ -108,6 +131,25 @@ class ImageTilePaneSelectionModel[ImageTile](parentTilePane: ImageTilePane) exte
override def isSelected(index: Int): Boolean = {
this.selectedIndexes.contains(index)
}
private def clearSelectionFormatting = {
val iterator = this.parentTilePane.getChildren.iterator()
while (iterator.hasNext) {
//remove the selection styling
val imageTile: VBox = iterator.next().asInstanceOf[VBox]
imageTile.setBorder(Border.EMPTY)
}
}
private def setSelectionFormatting(index: Int): Unit = {
setSelectionFormatting(this.parentTilePane.getChildren.get(index).asInstanceOf[ImageTile])
}
private def setSelectionFormatting(imageTile: ImageTile): Unit = {
val borderStroke = new BorderStroke(Color.BLUE, BorderStrokeStyle.SOLID, CornerRadii.EMPTY,BorderStroke.THIN)
imageTile.asInstanceOf[VBox].setBorder(new Border(borderStroke))
}
}
class ArrayObservableList[E] extends ModifiableObservableListBase[E] {

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

@ -100,8 +100,8 @@ class AppController extends Logging {
newImageTilePane.setMaxWidth(this.imageTilePane.getMaxWidth)
newImageTilePane.setPrefColumns(this.imageTilePane.getPrefColumns)
newImageTilePane.setPrefRows(this.imageTilePane.getPrefRows)
newImageTilePane.setPrefTileHeight(this.imageTilePane.getPrefTileHeight)
newImageTilePane.setPrefTileWidth(this.imageTilePane.getPrefTileWidth)
//newImageTilePane.setPrefTileHeight(this.imageTilePane.getPrefTileHeight)
//newImageTilePane.setPrefTileWidth(this.imageTilePane.getPrefTileWidth)
newImageTilePane.setTileAlignment(this.imageTilePane.getTileAlignment)
this.scrollPane.setContent(newImageTilePane)
this.imageTilePane = newImageTilePane
@ -219,7 +219,7 @@ class AppController extends Logging {
for (similarImage <- similarImages) {
debug(s"Adding similar images ${similarImage.rootImage.toString} to app")
tempImages += similarImage.rootImage
imageTilePane.getChildren.add(ImageTileFactory.get(similarImage.rootImage))
imageTilePane.getChildren.add(ImageTileFactory.get(similarImage.rootImage, imageTilePane))
similarImage.similarImages.foreach(image => tempImages += image)
}
setPagesContent(tempImages.toList)
@ -259,7 +259,7 @@ class AppController extends Logging {
override def run() {
for (image <- images) {
debug(s"Adding image ${image.toString} to app")
imageTilePane.getChildren.add(ImageTileFactory.get(image))
imageTilePane.getChildren.add(ImageTileFactory.get(image, imageTilePane))
}
}
})

Loading…
Cancel
Save