[Editor] Improve graphic asset import dialogs

This commit is contained in:
2022-08-30 01:04:42 +02:00
parent 981eb9ef31
commit 297b2d0d9d
11 changed files with 168 additions and 28 deletions

View File

@@ -14,9 +14,15 @@ class AnimationAssetData {
val fileProperty = SimpleObjectProperty<File>() val fileProperty = SimpleObjectProperty<File>()
var file by fileProperty var file by fileProperty
val rowsProperty = SimpleIntegerProperty() val rowsProperty = SimpleIntegerProperty(1)
var rows by rowsProperty var rows by rowsProperty
val columnsProperty = SimpleIntegerProperty() val columnsProperty = SimpleIntegerProperty(1)
var columns by columnsProperty var columns by columnsProperty
val tileSetWidthProperty = SimpleIntegerProperty(1)
var tileWidth by tileSetWidthProperty
val tileSetHeightProperty = SimpleIntegerProperty(1)
var tileHeight by tileSetHeightProperty
} }

View File

@@ -2,6 +2,7 @@ package com.bartlomiejpluta.base.editor.animation.view.importing
import com.bartlomiejpluta.base.editor.animation.asset.AnimationAssetData import com.bartlomiejpluta.base.editor.animation.asset.AnimationAssetData
import com.bartlomiejpluta.base.editor.animation.viewmodel.AnimationAssetDataVM import com.bartlomiejpluta.base.editor.animation.viewmodel.AnimationAssetDataVM
import com.bartlomiejpluta.base.editor.asset.component.GraphicAssetViewCanvas
import com.bartlomiejpluta.base.editor.util.fx.TextFieldUtil import com.bartlomiejpluta.base.editor.util.fx.TextFieldUtil
import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleObjectProperty
import javafx.scene.Cursor import javafx.scene.Cursor
@@ -15,6 +16,8 @@ class ImportAnimationFragment : Fragment("Import Animation") {
private var onCompleteConsumer: ((AnimationAssetData) -> Unit)? = null private var onCompleteConsumer: ((AnimationAssetData) -> Unit)? = null
private val canvas = GraphicAssetViewCanvas(dataVM.rowsProperty, dataVM.columnsProperty, dataVM.fileProperty)
init { init {
dataVM.fileProperty.addListener { _, _, file -> dataVM.fileProperty.addListener { _, _, file ->
when (file) { when (file) {
@@ -22,6 +25,29 @@ class ImportAnimationFragment : Fragment("Import Animation") {
else -> file.inputStream().use { imagePreview.value = Image(it) } else -> file.inputStream().use { imagePreview.value = Image(it) }
} }
} }
dataVM.tileSetWidthProperty.addListener { _, _, width ->
dataVM.columns = (imagePreview.value?.width?.toInt() ?: 1) / width.toInt()
}
dataVM.tileSetHeightProperty.addListener { _, _, height ->
dataVM.rows = (imagePreview.value?.height?.toInt() ?: 1) / height.toInt()
}
dataVM.columnsProperty.addListener { _, _, columns ->
dataVM.tileSetWidth = (imagePreview.value?.width?.toInt() ?: 1) / columns.toInt()
}
dataVM.rowsProperty.addListener { _, _, rows ->
dataVM.tileSetHeight = (imagePreview.value?.height?.toInt() ?: 1) / rows.toInt()
}
imagePreview.addListener { _, _, image ->
dataVM.columns = 1
dataVM.rows = 1
dataVM.tileSetWidth = image?.width?.toInt() ?: 0
dataVM.tileSetHeight = image?.height?.toInt() ?: 0
}
} }
fun onComplete(consumer: (AnimationAssetData) -> Unit) { fun onComplete(consumer: (AnimationAssetData) -> Unit) {
@@ -37,7 +63,7 @@ class ImportAnimationFragment : Fragment("Import Animation") {
scrollpane { scrollpane {
prefWidth = 300.0 prefWidth = 300.0
prefHeightProperty().bind(this@form.heightProperty()) prefHeightProperty().bind(this@form.heightProperty())
imageview(imagePreview) this += canvas
tooltip = tooltip("Click to choose Animation file") tooltip = tooltip("Click to choose Animation file")
cursor = Cursor.HAND cursor = Cursor.HAND
@@ -69,6 +95,7 @@ class ImportAnimationFragment : Fragment("Import Animation") {
} }
field("Animation Rows") { field("Animation Rows") {
enableWhen(imagePreview.isNotNull)
spinner(min = 1, max = Integer.MAX_VALUE, property = dataVM.rowsProperty, editable = true) { spinner(min = 1, max = Integer.MAX_VALUE, property = dataVM.rowsProperty, editable = true) {
required() required()
editor.textFormatter = TextFieldUtil.integerFormatter(dataVM.rows) editor.textFormatter = TextFieldUtil.integerFormatter(dataVM.rows)
@@ -76,11 +103,28 @@ class ImportAnimationFragment : Fragment("Import Animation") {
} }
field("Animation Columns") { field("Animation Columns") {
enableWhen(imagePreview.isNotNull)
spinner(min = 1, max = Integer.MAX_VALUE, property = dataVM.columnsProperty, editable = true) { spinner(min = 1, max = Integer.MAX_VALUE, property = dataVM.columnsProperty, editable = true) {
required() required()
editor.textFormatter = TextFieldUtil.integerFormatter(dataVM.columns) editor.textFormatter = TextFieldUtil.integerFormatter(dataVM.columns)
} }
} }
field("Animation tile width") {
enableWhen(imagePreview.isNotNull)
spinner(min = 1, max = Integer.MAX_VALUE, property = dataVM.tileSetWidthProperty, editable = true) {
required()
editor.textFormatter = TextFieldUtil.integerFormatter(dataVM.rows)
}
}
field("Animation tile height") {
enableWhen(imagePreview.isNotNull)
spinner(min = 1, max = Integer.MAX_VALUE, property = dataVM.tileSetHeightProperty, editable = true) {
required()
editor.textFormatter = TextFieldUtil.integerFormatter(dataVM.columns)
}
}
} }
} }
} }

View File

@@ -17,4 +17,10 @@ class AnimationAssetDataVM : ItemViewModel<AnimationAssetData>(AnimationAssetDat
val columnsProperty = bind(AnimationAssetData::columnsProperty) val columnsProperty = bind(AnimationAssetData::columnsProperty)
var columns by columnsProperty var columns by columnsProperty
val tileSetWidthProperty = bind(AnimationAssetData::tileSetWidthProperty)
var tileSetWidth by tileSetWidthProperty
val tileSetHeightProperty = bind(AnimationAssetData::tileSetHeightProperty)
var tileSetHeight by tileSetHeightProperty
} }

View File

@@ -2,41 +2,57 @@ package com.bartlomiejpluta.base.editor.asset.component
import com.bartlomiejpluta.base.editor.asset.model.GraphicAsset import com.bartlomiejpluta.base.editor.asset.model.GraphicAsset
import com.bartlomiejpluta.base.editor.asset.viewmodel.GraphicAssetVM import com.bartlomiejpluta.base.editor.asset.viewmodel.GraphicAssetVM
import javafx.beans.property.IntegerProperty
import javafx.beans.property.Property
import javafx.scene.canvas.Canvas import javafx.scene.canvas.Canvas
import javafx.scene.image.Image import javafx.scene.image.Image
import javafx.scene.image.WritableImage import javafx.scene.image.WritableImage
import javafx.scene.paint.Color import javafx.scene.paint.Color
import javafx.scene.text.TextAlignment import javafx.scene.text.TextAlignment
import tornadofx.getValue import tornadofx.getValue
import java.io.File
class GraphicAssetViewCanvas(asset: GraphicAssetVM) : Canvas() { class GraphicAssetViewCanvas(val rowsProperty: IntegerProperty, val columnsProperty: IntegerProperty, val fileProperty: Property<File>) : Canvas() {
private var image: Image? = null private var image: Image? = null
val rows by asset.rowsProperty val rows by rowsProperty
val columns by asset.columnsProperty val columns by columnsProperty
var chunkWidth: Int = 1// = //(image.width / columns).toInt() var chunkWidth: Int = 1
private set private set
var chunkHeight: Int = 1// = (image.height / rows).toInt() var chunkHeight: Int = 1
private set private set
var singleChunk = rows == 1 && columns == 1 var singleChunk = rows == 1 && columns == 1
private set private set
init { init {
asset.itemProperty.addListener { _, _, item -> updateAsset(item) } rowsProperty.addListener { _, _, _ -> updateAsset() }
updateAsset(asset.item) columnsProperty.addListener { _, _, _ -> updateAsset() }
fileProperty.addListener { _, _, _ -> updateAsset() }
updateAsset()
} }
private fun updateAsset(asset: GraphicAsset?) { constructor(asset: GraphicAssetVM) : this(asset.rowsProperty, asset.columnsProperty, asset.fileProperty)
asset?.let {
image = Image(it.file.inputStream()) private fun updateAsset() {
width = image!!.width + OFFSET_X val file = fileProperty.value
height = image!!.height + OFFSET_Y
if (file != null) {
image = Image(fileProperty.value.inputStream())
width = image!!.width + OFFSET_X * 2
height = image!!.height + OFFSET_Y * 2
chunkWidth = (image!!.width / columns).toInt() chunkWidth = (image!!.width / columns).toInt()
chunkHeight = (image!!.height / rows).toInt() chunkHeight = (image!!.height / rows).toInt()
singleChunk = rows == 1 && columns == 1 singleChunk = rows == 1 && columns == 1
} else {
image = null
width = 0.0
height = 0.0
chunkWidth = 0
chunkHeight = 0
singleChunk = true
} }
render() render()

View File

@@ -21,10 +21,6 @@ class SelectGraphicAssetView<T : GraphicAsset> : View() {
private var assetsListView: ListView<T> by singleAssign() private var assetsListView: ListView<T> by singleAssign()
private val image = createObjectBinding({
asset.value?.file?.inputStream()?.use { Image(it) } ?: PLACEHOLDER_IMAGE
}, asset)
init { init {
asset.addListener { _, _, item -> vm.item = item } asset.addListener { _, _, item -> vm.item = item }
} }

View File

@@ -1,5 +1,7 @@
package com.bartlomiejpluta.base.editor.autotile.view.importing package com.bartlomiejpluta.base.editor.autotile.view.importing
import com.bartlomiejpluta.base.editor.asset.component.GraphicAssetViewCanvas
import com.bartlomiejpluta.base.editor.asset.viewmodel.GraphicAssetVM
import com.bartlomiejpluta.base.editor.autotile.asset.AutoTileAssetData import com.bartlomiejpluta.base.editor.autotile.asset.AutoTileAssetData
import com.bartlomiejpluta.base.editor.autotile.viewmodel.AutoTileAssetDataVM import com.bartlomiejpluta.base.editor.autotile.viewmodel.AutoTileAssetDataVM
import com.bartlomiejpluta.base.editor.util.fx.TextFieldUtil import com.bartlomiejpluta.base.editor.util.fx.TextFieldUtil
@@ -15,6 +17,8 @@ class ImportAutoTileFragment : Fragment("Import Auto Tile") {
private var onCompleteConsumer: ((AutoTileAssetData) -> Unit)? = null private var onCompleteConsumer: ((AutoTileAssetData) -> Unit)? = null
private val canvas = GraphicAssetViewCanvas(dataVM.rowsProperty, dataVM.columnsProperty, dataVM.fileProperty)
init { init {
dataVM.fileProperty.addListener { _, _, file -> dataVM.fileProperty.addListener { _, _, file ->
when (file) { when (file) {
@@ -39,9 +43,11 @@ class ImportAutoTileFragment : Fragment("Import Auto Tile") {
dataVM.tileSetHeight = (imagePreview.value?.height?.toInt() ?: 1) / rows.toInt() dataVM.tileSetHeight = (imagePreview.value?.height?.toInt() ?: 1) / rows.toInt()
} }
imagePreview.addListener { _, _, _ -> imagePreview.addListener { _, _, image ->
dataVM.columns = 1 dataVM.columns = 1
dataVM.rows = 1 dataVM.rows = 1
dataVM.tileSetWidth = image?.width?.toInt() ?: 0
dataVM.tileSetHeight = image?.height?.toInt() ?: 0
} }
} }
@@ -58,7 +64,7 @@ class ImportAutoTileFragment : Fragment("Import Auto Tile") {
scrollpane { scrollpane {
prefWidth = 300.0 prefWidth = 300.0
prefHeightProperty().bind(this@form.heightProperty()) prefHeightProperty().bind(this@form.heightProperty())
imageview(imagePreview) this += canvas
tooltip = tooltip("Click to choose Auto Tile file") tooltip = tooltip("Click to choose Auto Tile file")
cursor = Cursor.HAND cursor = Cursor.HAND

View File

@@ -14,9 +14,15 @@ class CharacterSetAssetData {
val fileProperty = SimpleObjectProperty<File>() val fileProperty = SimpleObjectProperty<File>()
var file by fileProperty var file by fileProperty
val rowsProperty = SimpleIntegerProperty() val rowsProperty = SimpleIntegerProperty(1)
var rows by rowsProperty var rows by rowsProperty
val columnsProperty = SimpleIntegerProperty() val columnsProperty = SimpleIntegerProperty(1)
var columns by columnsProperty var columns by columnsProperty
val tileSetWidthProperty = SimpleIntegerProperty(1)
var tileWidth by tileSetWidthProperty
val tileSetHeightProperty = SimpleIntegerProperty(1)
var tileHeight by tileSetHeightProperty
} }

View File

@@ -1,5 +1,6 @@
package com.bartlomiejpluta.base.editor.characterset.view.importing package com.bartlomiejpluta.base.editor.characterset.view.importing
import com.bartlomiejpluta.base.editor.asset.component.GraphicAssetViewCanvas
import com.bartlomiejpluta.base.editor.characterset.asset.CharacterSetAssetData import com.bartlomiejpluta.base.editor.characterset.asset.CharacterSetAssetData
import com.bartlomiejpluta.base.editor.characterset.viewmodel.CharacterSetAssetDataVM import com.bartlomiejpluta.base.editor.characterset.viewmodel.CharacterSetAssetDataVM
import com.bartlomiejpluta.base.editor.util.fx.TextFieldUtil import com.bartlomiejpluta.base.editor.util.fx.TextFieldUtil
@@ -15,6 +16,8 @@ class ImportCharacterSetFragment : Fragment("Import Character Set") {
private var onCompleteConsumer: ((CharacterSetAssetData) -> Unit)? = null private var onCompleteConsumer: ((CharacterSetAssetData) -> Unit)? = null
private val canvas = GraphicAssetViewCanvas(dataVM.rowsProperty, dataVM.columnsProperty, dataVM.fileProperty)
init { init {
dataVM.fileProperty.addListener { _, _, file -> dataVM.fileProperty.addListener { _, _, file ->
when (file) { when (file) {
@@ -22,6 +25,29 @@ class ImportCharacterSetFragment : Fragment("Import Character Set") {
else -> file.inputStream().use { imagePreview.value = Image(it) } else -> file.inputStream().use { imagePreview.value = Image(it) }
} }
} }
dataVM.tileSetWidthProperty.addListener { _, _, width ->
dataVM.columns = (imagePreview.value?.width?.toInt() ?: 1) / width.toInt()
}
dataVM.tileSetHeightProperty.addListener { _, _, height ->
dataVM.rows = (imagePreview.value?.height?.toInt() ?: 1) / height.toInt()
}
dataVM.columnsProperty.addListener { _, _, columns ->
dataVM.tileSetWidth = (imagePreview.value?.width?.toInt() ?: 1) / columns.toInt()
}
dataVM.rowsProperty.addListener { _, _, rows ->
dataVM.tileSetHeight = (imagePreview.value?.height?.toInt() ?: 1) / rows.toInt()
}
imagePreview.addListener { _, _, image ->
dataVM.columns = 1
dataVM.rows = 1
dataVM.tileSetWidth = image?.width?.toInt() ?: 0
dataVM.tileSetHeight = image?.height?.toInt() ?: 0
}
} }
fun onComplete(consumer: (CharacterSetAssetData) -> Unit) { fun onComplete(consumer: (CharacterSetAssetData) -> Unit) {
@@ -37,7 +63,7 @@ class ImportCharacterSetFragment : Fragment("Import Character Set") {
scrollpane { scrollpane {
prefWidth = 300.0 prefWidth = 300.0
prefHeightProperty().bind(this@form.heightProperty()) prefHeightProperty().bind(this@form.heightProperty())
imageview(imagePreview) this += canvas
tooltip = tooltip("Click to choose Character Set file") tooltip = tooltip("Click to choose Character Set file")
cursor = Cursor.HAND cursor = Cursor.HAND
@@ -69,6 +95,7 @@ class ImportCharacterSetFragment : Fragment("Import Character Set") {
} }
field("Character Set Rows") { field("Character Set Rows") {
enableWhen(imagePreview.isNotNull)
spinner(min = 1, max = Integer.MAX_VALUE, property = dataVM.rowsProperty, editable = true) { spinner(min = 1, max = Integer.MAX_VALUE, property = dataVM.rowsProperty, editable = true) {
required() required()
editor.textFormatter = TextFieldUtil.integerFormatter(dataVM.rows) editor.textFormatter = TextFieldUtil.integerFormatter(dataVM.rows)
@@ -76,11 +103,28 @@ class ImportCharacterSetFragment : Fragment("Import Character Set") {
} }
field("Character Set Columns") { field("Character Set Columns") {
enableWhen(imagePreview.isNotNull)
spinner(min = 1, max = Integer.MAX_VALUE, property = dataVM.columnsProperty, editable = true) { spinner(min = 1, max = Integer.MAX_VALUE, property = dataVM.columnsProperty, editable = true) {
required() required()
editor.textFormatter = TextFieldUtil.integerFormatter(dataVM.columns) editor.textFormatter = TextFieldUtil.integerFormatter(dataVM.columns)
} }
} }
field("Character tile width") {
enableWhen(imagePreview.isNotNull)
spinner(min = 1, max = Integer.MAX_VALUE, property = dataVM.tileSetWidthProperty, editable = true) {
required()
editor.textFormatter = TextFieldUtil.integerFormatter(dataVM.rows)
}
}
field("Character tile height") {
enableWhen(imagePreview.isNotNull)
spinner(min = 1, max = Integer.MAX_VALUE, property = dataVM.tileSetHeightProperty, editable = true) {
required()
editor.textFormatter = TextFieldUtil.integerFormatter(dataVM.columns)
}
}
} }
} }
} }

View File

@@ -17,4 +17,10 @@ class CharacterSetAssetDataVM : ItemViewModel<CharacterSetAssetData>(CharacterSe
val columnsProperty = bind(CharacterSetAssetData::columnsProperty) val columnsProperty = bind(CharacterSetAssetData::columnsProperty)
var columns by columnsProperty var columns by columnsProperty
val tileSetWidthProperty = bind(CharacterSetAssetData::tileSetWidthProperty)
var tileSetWidth by tileSetWidthProperty
val tileSetHeightProperty = bind(CharacterSetAssetData::tileSetHeightProperty)
var tileSetHeight by tileSetHeightProperty
} }

View File

@@ -1,5 +1,6 @@
package com.bartlomiejpluta.base.editor.iconset.view.importing package com.bartlomiejpluta.base.editor.iconset.view.importing
import com.bartlomiejpluta.base.editor.asset.component.GraphicAssetViewCanvas
import com.bartlomiejpluta.base.editor.iconset.asset.IconSetAssetData import com.bartlomiejpluta.base.editor.iconset.asset.IconSetAssetData
import com.bartlomiejpluta.base.editor.iconset.viewmodel.IconSetAssetDataVM import com.bartlomiejpluta.base.editor.iconset.viewmodel.IconSetAssetDataVM
import com.bartlomiejpluta.base.editor.util.fx.TextFieldUtil import com.bartlomiejpluta.base.editor.util.fx.TextFieldUtil
@@ -15,6 +16,8 @@ class ImportIconSetFragment : Fragment("Import Icon Set") {
private var onCompleteConsumer: ((IconSetAssetData) -> Unit)? = null private var onCompleteConsumer: ((IconSetAssetData) -> Unit)? = null
private val canvas = GraphicAssetViewCanvas(dataVM.rowsProperty, dataVM.columnsProperty, dataVM.fileProperty)
init { init {
dataVM.fileProperty.addListener { _, _, file -> dataVM.fileProperty.addListener { _, _, file ->
when (file) { when (file) {
@@ -39,9 +42,11 @@ class ImportIconSetFragment : Fragment("Import Icon Set") {
dataVM.iconHeight = (imagePreview.value?.height?.toInt() ?: 1) / rows.toInt() dataVM.iconHeight = (imagePreview.value?.height?.toInt() ?: 1) / rows.toInt()
} }
imagePreview.addListener { _, _, _ -> imagePreview.addListener { _, _, image ->
dataVM.columns = 1 dataVM.columns = 1
dataVM.rows = 1 dataVM.rows = 1
dataVM.iconWidth = image?.width?.toInt() ?: 0
dataVM.iconHeight = image?.height?.toInt() ?: 0
} }
} }
@@ -58,7 +63,7 @@ class ImportIconSetFragment : Fragment("Import Icon Set") {
scrollpane { scrollpane {
prefWidth = 300.0 prefWidth = 300.0
prefHeightProperty().bind(this@form.heightProperty()) prefHeightProperty().bind(this@form.heightProperty())
imageview(imagePreview) this += canvas
tooltip = tooltip("Click to choose Icon Set file") tooltip = tooltip("Click to choose Icon Set file")
cursor = Cursor.HAND cursor = Cursor.HAND

View File

@@ -1,5 +1,6 @@
package com.bartlomiejpluta.base.editor.tileset.view.importing package com.bartlomiejpluta.base.editor.tileset.view.importing
import com.bartlomiejpluta.base.editor.asset.component.GraphicAssetViewCanvas
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAssetData import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAssetData
import com.bartlomiejpluta.base.editor.tileset.viewmodel.TileSetAssetDataVM import com.bartlomiejpluta.base.editor.tileset.viewmodel.TileSetAssetDataVM
import com.bartlomiejpluta.base.editor.util.fx.TextFieldUtil import com.bartlomiejpluta.base.editor.util.fx.TextFieldUtil
@@ -15,6 +16,8 @@ class ImportTileSetFragment : Fragment("Import Tile Set") {
private var onCompleteConsumer: ((TileSetAssetData) -> Unit)? = null private var onCompleteConsumer: ((TileSetAssetData) -> Unit)? = null
private val canvas = GraphicAssetViewCanvas(dataVM.rowsProperty, dataVM.columnsProperty, dataVM.fileProperty)
init { init {
dataVM.fileProperty.addListener { _, _, file -> dataVM.fileProperty.addListener { _, _, file ->
when (file) { when (file) {
@@ -39,9 +42,11 @@ class ImportTileSetFragment : Fragment("Import Tile Set") {
dataVM.tileHeight = (imagePreview.value?.height?.toInt() ?: 1) / rows.toInt() dataVM.tileHeight = (imagePreview.value?.height?.toInt() ?: 1) / rows.toInt()
} }
imagePreview.addListener { _, _, _ -> imagePreview.addListener { _, _, image ->
dataVM.columns = 1 dataVM.columns = 1
dataVM.rows = 1 dataVM.rows = 1
dataVM.tileWidth = image?.width?.toInt() ?: 0
dataVM.tileHeight = image?.height?.toInt() ?: 0
} }
} }
@@ -58,7 +63,7 @@ class ImportTileSetFragment : Fragment("Import Tile Set") {
scrollpane { scrollpane {
prefWidth = 300.0 prefWidth = 300.0
prefHeightProperty().bind(this@form.heightProperty()) prefHeightProperty().bind(this@form.heightProperty())
imageview(imagePreview) this += canvas
tooltip = tooltip("Click to choose Tile Set file") tooltip = tooltip("Click to choose Tile Set file")
cursor = Cursor.HAND cursor = Cursor.HAND