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

View File

@ -18,37 +18,87 @@ import scalafx.scene.input.MouseEvent
import scalafx.scene.paint.Color
import scalafx.scene.layout._
import scalafx.util.Duration
import scalafx.util.StringConverter
import fmon.draw._
import fmon.util.YamlHelper
class ObsAnimation(name_ : String) {
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()
}
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 {
@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 tiles: javafx.scene.layout.TilePane = _
@FXML var fileChooser: jfxsc.ComboBox[File] = _
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
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.selectionModel().selectedIndex.onChange(selectionChange)
frameList.selectionModel().selectedIndex.onChange(selectFrame)
//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 children = images.map(img => {
val children = images.zipWithIndex.map{case (img, i) => {
val imgView = new ImageView() {
scaleX = 0.5
scaleY = 0.5
@ -57,29 +107,32 @@ class AnimationBuilder extends Savable {
}
imgView.handleEvent(MouseEvent.Any) {
e: MouseEvent => if (e.clickCount == 2 && e.eventType == MouseEvent.MouseClicked) {
addFrame(img)
addFrame(img, i)
}
}
imgView.delegate
})
}}
tiles.children.clear()
tiles.children ++= children
tiles.prefTileWidth = 96 // TODO : I think this has to do with how the image is scaled
tiles.prefTileHeight = 96
addAnimation()
animationList.selectionModel().selectFirst()
}
def addAnimation(): Unit = {
animations += new ObsAnimation("Animation")
addAnimation("Animation")
}
def addAnimation(name: String): Unit = {
animations += new ObsAnimation(name)
animationList.selectionModel().selectLast()
}
def quickBuildAnimation(): Unit = {
animations += new ObsAnimation("Animation")
val filename = currFile.getName
val name = filename.split('.')(0)
animations += new ObsAnimation(name)
animationList.selectionModel().selectLast()
palette.images.foreach(addFrame(_))
palette.images.zipWithIndex.foreach{case (img, i) => addFrame(img, i)}
}
def selectionChange(): Unit = {
@ -99,9 +152,8 @@ class AnimationBuilder extends Savable {
//selected.frames += new FrameToken
}
def addFrame(img: StillImg): Unit = {
println("Image")
selected.frames += new FrameToken(img)
def addFrame(img: StillImg, index: Int): Unit = {
selected.frames += new Frame(img, currFile, index)
}
def removeFrame(): Unit = {
@ -114,11 +166,17 @@ class AnimationBuilder extends Savable {
}
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 = {
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 = {

View File

@ -47,4 +47,20 @@ class Palette(val image: Image, val numAcross: Int, val numDown: Int) {
this(x, y)
}
}
}
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)
}
}