Can now save and load animations

This commit is contained in:
dalyjame 2019-07-01 12:50:01 -04:00
parent e9284e2158
commit adef7235f1
3 changed files with 95 additions and 19 deletions

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?> <?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.ListView?> <?import javafx.scene.control.ListView?>
<?import javafx.scene.control.ScrollPane?> <?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.image.ImageView?> <?import javafx.scene.image.ImageView?>
@ -43,5 +44,6 @@
<TilePane fx:id="tiles" hgap="5.0" vgap="5.0" /> <TilePane fx:id="tiles" hgap="5.0" vgap="5.0" />
</content> </content>
</ScrollPane> </ScrollPane>
<ComboBox fx:id="fileChooser" prefWidth="150.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
</children> </children>
</GridPane> </GridPane>

View File

@ -18,37 +18,87 @@ import scalafx.scene.input.MouseEvent
import scalafx.scene.paint.Color import scalafx.scene.paint.Color
import scalafx.scene.layout._ import scalafx.scene.layout._
import scalafx.util.Duration import scalafx.util.Duration
import scalafx.util.StringConverter
import fmon.draw._ import fmon.draw._
import fmon.util.YamlHelper
class ObsAnimation(name_ : String) { class ObsAnimation(name_ : String) {
val name = new StringProperty(this, "name", name_) val name = new StringProperty(this, "name", name_)
val frames = new ObservableBuffer[FrameToken]() val frames = new ObservableBuffer[Frame]()
def toToken = {
val filename = frames(0).file.getName
val indices = frames.map(_.index)
AnimationToken(filename, indices)
}
override def toString = name() override def toString = name()
} }
case class FrameToken(img: StillImg) { class Frame(val img: StillImg, val file: File, val index: Int) {
def toToken = ImageToken(file.getName, index)
override def toString = s"${file.getName} ${index}"
}
case class AnimationToken(val filename: String, val indices: Seq[Int]) {
def toFrames(dir: File) = {
val file = new File(s"${dir.getPath}/$filename")
val palette = Palette.square(new FileInputStream(file), 5)
val images = palette.images
indices.map(i => new Frame(images(i), file, i))
}
}
case class ImageToken(val filename: String, val index: Int) {
def toFrame(dir: File) = {
val file = new File(s"${dir.getPath}/$filename")
val pal = Palette.square(new FileInputStream(file), 5).images(5)
}
override def toString = s"${filename} ${index}"
} }
class AnimationBuilder extends Savable { class AnimationBuilder extends Savable {
@FXML var animationList: jfxsc.ListView[ObsAnimation] = _ @FXML var animationList: jfxsc.ListView[ObsAnimation] = _
@FXML var frameList: jfxsc.ListView[FrameToken] = _ @FXML var frameList: jfxsc.ListView[Frame] = _
@FXML var viewpane: javafx.scene.image.ImageView = _ @FXML var viewpane: javafx.scene.image.ImageView = _
@FXML var tiles: javafx.scene.layout.TilePane = _ @FXML var tiles: javafx.scene.layout.TilePane = _
@FXML var fileChooser: jfxsc.ComboBox[File] = _
val animations = ObservableBuffer[ObsAnimation]() val animations = ObservableBuffer[ObsAnimation]()
val imgFiles = ObservableBuffer[File]()
val palette = new Palette(new FileInputStream(raw"C:\Users\dalyj\Documents\Design\Images\TimmahLexusX reduced\Reduced Animations\Fireball.png"), 5, 3) val imgdir = raw"C:\Users\dalyj\Documents\Design\Images\TimmahLexusX reduced\Reduced Animations"
@FXML @FXML
def initialize(): Unit = { def initialize(): Unit = {
fileChooser.items = imgFiles
fileChooser.selectionModel().selectedIndex.onChange(selectImageFile)
fileChooser.converter = new StringConverter[File] {
override def toString(f: File) = f.getName
override def fromString(s: String) = new File(s)
}
val dir = new File(imgdir)
imgFiles ++= dir.listFiles()
animationList.items = animations animationList.items = animations
animationList.selectionModel().selectedIndex.onChange(selectionChange) animationList.selectionModel().selectedIndex.onChange(selectionChange)
frameList.selectionModel().selectedIndex.onChange(selectFrame) frameList.selectionModel().selectedIndex.onChange(selectFrame)
//for (x <- 0 until palette.numAcross; y <- 0 until palette.numDown) { //for (x <- 0 until palette.numAcross; y <- 0 until palette.numDown) {
//addAnimation()
animationList.selectionModel().selectFirst()
fileChooser.selectionModel().selectFirst()
}
def currFile = fileChooser.selectionModel().getSelectedItem
def palette = Palette.square(new FileInputStream(currFile), 5)
def selectImageFile(): Unit = {
val images = palette.images val images = palette.images
val children = images.map(img => { val children = images.zipWithIndex.map{case (img, i) => {
val imgView = new ImageView() { val imgView = new ImageView() {
scaleX = 0.5 scaleX = 0.5
scaleY = 0.5 scaleY = 0.5
@ -57,29 +107,32 @@ class AnimationBuilder extends Savable {
} }
imgView.handleEvent(MouseEvent.Any) { imgView.handleEvent(MouseEvent.Any) {
e: MouseEvent => if (e.clickCount == 2 && e.eventType == MouseEvent.MouseClicked) { e: MouseEvent => if (e.clickCount == 2 && e.eventType == MouseEvent.MouseClicked) {
addFrame(img) addFrame(img, i)
} }
} }
imgView.delegate imgView.delegate
}) }}
tiles.children.clear()
tiles.children ++= children tiles.children ++= children
tiles.prefTileWidth = 96 // TODO : I think this has to do with how the image is scaled tiles.prefTileWidth = 96 // TODO : I think this has to do with how the image is scaled
tiles.prefTileHeight = 96 tiles.prefTileHeight = 96
addAnimation()
animationList.selectionModel().selectFirst()
} }
def addAnimation(): Unit = { def addAnimation(): Unit = {
animations += new ObsAnimation("Animation") addAnimation("Animation")
}
def addAnimation(name: String): Unit = {
animations += new ObsAnimation(name)
animationList.selectionModel().selectLast() animationList.selectionModel().selectLast()
} }
def quickBuildAnimation(): Unit = { def quickBuildAnimation(): Unit = {
animations += new ObsAnimation("Animation") val filename = currFile.getName
val name = filename.split('.')(0)
animations += new ObsAnimation(name)
animationList.selectionModel().selectLast() animationList.selectionModel().selectLast()
palette.images.foreach(addFrame(_)) palette.images.zipWithIndex.foreach{case (img, i) => addFrame(img, i)}
} }
def selectionChange(): Unit = { def selectionChange(): Unit = {
@ -99,9 +152,8 @@ class AnimationBuilder extends Savable {
//selected.frames += new FrameToken //selected.frames += new FrameToken
} }
def addFrame(img: StillImg): Unit = { def addFrame(img: StillImg, index: Int): Unit = {
println("Image") selected.frames += new Frame(img, currFile, index)
selected.frames += new FrameToken(img)
} }
def removeFrame(): Unit = { def removeFrame(): Unit = {
@ -114,11 +166,17 @@ class AnimationBuilder extends Savable {
} }
override def saveTo(file: File): Unit = { override def saveTo(file: File): Unit = {
val aniMap = animations.map(a => (a.name(), a.toToken)).toMap
YamlHelper.writeMap(new FileOutputStream(file), aniMap)
} }
override def openFrom(file: File): Unit = { override def openFrom(file: File): Unit = {
val aniMap = YamlHelper.extractMap[AnimationToken](new FileInputStream(file))
aniMap.foreach{case (name, token) => {
addAnimation(name)
val frames = token.toFrames(new File(imgdir))
animationList.selectionModel().getSelectedItem.frames ++= frames
}}
} }
private def selected: ObsAnimation = { private def selected: ObsAnimation = {

View File

@ -48,3 +48,19 @@ class Palette(val image: Image, val numAcross: Int, val numDown: Int) {
} }
} }
} }
object Palette {
def square(stream: InputStream, numAcross: Int) = {
val img = new Image(stream)
val size = img.width() / numAcross
val numDown = img.height() / size
new Palette(img, numAcross, numDown.toInt)
}
def bySize(stream: InputStream, width: Double, height: Double) = {
val img = new Image(stream)
val numAcross = img.width() / width
val numDown = img.height() / height
new Palette(img, numAcross.toInt, numDown.toInt)
}
}