[Editor] Enable full support for map labels
From now on, the editor is capable to put map labels in the canavs as well as generate the map labels in output map serialized file.
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
package com.bartlomiejpluta.base.api.map.layer.object;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.Value;
|
||||||
|
|
||||||
|
@Value
|
||||||
|
@Builder
|
||||||
|
public class MapPin {
|
||||||
|
String map;
|
||||||
|
int layer;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
}
|
||||||
@@ -2,13 +2,17 @@ package com.bartlomiejpluta.base.editor.code.build.generator
|
|||||||
|
|
||||||
import com.bartlomiejpluta.base.editor.asset.model.Asset
|
import com.bartlomiejpluta.base.editor.asset.model.Asset
|
||||||
import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset
|
import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset
|
||||||
|
import com.bartlomiejpluta.base.editor.map.model.layer.ObjectLayer
|
||||||
import com.bartlomiejpluta.base.editor.map.serial.MapDeserializer
|
import com.bartlomiejpluta.base.editor.map.serial.MapDeserializer
|
||||||
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
||||||
import com.bartlomiejpluta.base.editor.project.model.Project
|
import com.bartlomiejpluta.base.editor.project.model.Project
|
||||||
import com.squareup.javapoet.*
|
import com.squareup.javapoet.*
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
|
import java.time.Instant
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import javax.annotation.processing.Generated
|
||||||
import javax.lang.model.element.Modifier
|
import javax.lang.model.element.Modifier
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@@ -46,10 +50,17 @@ class AssetMapCodeGenerator : CodeGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateAssetClass(name: String, assets: List<Asset>): TypeSpec {
|
private fun generateAssetClass(name: String, assets: List<Asset>): TypeSpec {
|
||||||
|
val generatedAnnotation = AnnotationSpec.builder(Generated::class.java).addMember("value", "\$S", GENERATOR_NAME)
|
||||||
|
.addMember("date", "\$S", DateTimeFormatter.ISO_INSTANT.format(Instant.now()))
|
||||||
|
.addMember("comments", "\$S", "Utility class for $name assets")
|
||||||
|
.build()
|
||||||
|
|
||||||
val className = ClassName.get("A", name)
|
val className = ClassName.get("A", name)
|
||||||
|
|
||||||
return TypeSpec
|
return TypeSpec
|
||||||
.classBuilder(className)
|
.classBuilder(className)
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
||||||
|
.addAnnotation(generatedAnnotation)
|
||||||
.addField(
|
.addField(
|
||||||
FieldSpec.builder(
|
FieldSpec.builder(
|
||||||
ParameterizedTypeName.get(
|
ParameterizedTypeName.get(
|
||||||
@@ -69,13 +80,13 @@ class AssetMapCodeGenerator : CodeGenerator {
|
|||||||
}
|
}
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.addField(String::class.java, "uid", Modifier.PUBLIC, Modifier.FINAL)
|
.addField(String::class.java, "$", Modifier.PUBLIC, Modifier.FINAL)
|
||||||
.addMethod(
|
.addMethod(
|
||||||
MethodSpec
|
MethodSpec
|
||||||
.constructorBuilder()
|
.constructorBuilder()
|
||||||
.addModifiers(Modifier.PRIVATE)
|
.addModifiers(Modifier.PRIVATE)
|
||||||
.addParameter(TypeName.get(String::class.java), "uid")
|
.addParameter(TypeName.get(String::class.java), "uid")
|
||||||
.addStatement("this.uid = uid")
|
.addStatement("this.\$\$ = uid")
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.addMethod(
|
.addMethod(
|
||||||
@@ -101,15 +112,22 @@ class AssetMapCodeGenerator : CodeGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateMapAssetClass(name: String, assets: List<GameMapAsset>): TypeSpec {
|
private fun generateMapAssetClass(name: String, assets: List<GameMapAsset>): TypeSpec {
|
||||||
|
val generatedAnnotation = AnnotationSpec.builder(Generated::class.java).addMember("value", "\$S", GENERATOR_NAME)
|
||||||
|
.addMember("date", "\$S", DateTimeFormatter.ISO_INSTANT.format(Instant.now()))
|
||||||
|
.addMember("comments", "\$S", "Utility class for $name assets")
|
||||||
|
.build()
|
||||||
|
|
||||||
val className = ClassName.get("A", name)
|
val className = ClassName.get("A", name)
|
||||||
val mapLayers = assets
|
val mapLayers = assets
|
||||||
.map { asset -> asset to mapDeserializer.deserialize(asset.file.inputStream()) }
|
.map { asset -> asset to mapDeserializer.deserialize(asset.file.inputStream()) }
|
||||||
.associate { (asset, map) -> asset to map.layers }
|
.associate { (asset, map) -> asset to map.layers }
|
||||||
|
|
||||||
val abstractAssetClassName = ClassName.get("", "GameMapAsset")
|
val abstractAssetClassName = ClassName.get("", "GameMapAsset")
|
||||||
|
val abstractLayerClassName = ClassName.get("", "GameMapAssetLayer")
|
||||||
|
|
||||||
return TypeSpec
|
return TypeSpec
|
||||||
.classBuilder(className)
|
.classBuilder(className)
|
||||||
|
.addAnnotation(generatedAnnotation)
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
||||||
.addField(
|
.addField(
|
||||||
FieldSpec.builder(
|
FieldSpec.builder(
|
||||||
@@ -122,67 +140,33 @@ class AssetMapCodeGenerator : CodeGenerator {
|
|||||||
.initializer("new \$T<>()", java.util.HashMap::class.java)
|
.initializer("new \$T<>()", java.util.HashMap::class.java)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.addField(
|
|
||||||
FieldSpec.builder(
|
|
||||||
ParameterizedTypeName.get(
|
|
||||||
ClassName.get(java.util.Map::class.java),
|
|
||||||
ClassName.get(String::class.java),
|
|
||||||
ClassName.get(Integer::class.java)
|
|
||||||
), "_layers", Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL
|
|
||||||
)
|
|
||||||
.initializer("new \$T<>()", java.util.HashMap::class.java)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.addStaticBlock(CodeBlock.builder()
|
.addStaticBlock(CodeBlock.builder()
|
||||||
.apply {
|
.apply {
|
||||||
assets.forEach {
|
assets.forEach {
|
||||||
addStatement("_maps.put(\"${it.name}\", ${getAssetName(it)})")
|
addStatement("_maps.put(\"${it.name}\", ${getAssetName(it)})")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.apply {
|
|
||||||
mapLayers.forEach { asset, layers ->
|
|
||||||
layers.forEach { layer ->
|
|
||||||
addStatement(
|
|
||||||
"_layers.put(\"${asset.name}::${layer.name}\", ${getAssetName(asset)}.layers.${
|
|
||||||
getAssetName(
|
|
||||||
layer.name
|
|
||||||
)
|
|
||||||
})"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.addMethod(
|
.addMethod(
|
||||||
MethodSpec
|
MethodSpec
|
||||||
.methodBuilder("get")
|
.methodBuilder("byName")
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC)
|
.addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC)
|
||||||
.returns(abstractAssetClassName)
|
.returns(abstractAssetClassName)
|
||||||
.addParameter(TypeName.get(String::class.java), "name")
|
.addParameter(TypeName.get(String::class.java), "name")
|
||||||
.addStatement("return _maps.get(name)")
|
.addStatement("return _maps.get(name)")
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.addMethod(
|
|
||||||
MethodSpec
|
|
||||||
.methodBuilder("getLayer")
|
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC)
|
|
||||||
.returns(ClassName.get(Integer::class.java))
|
|
||||||
.addParameter(TypeName.get(String::class.java), "mapName")
|
|
||||||
.addParameter(TypeName.get(String::class.java), "layerName")
|
|
||||||
.addStatement("return _layers.get(mapName + \"::\" + layerName)")
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.addType(
|
.addType(
|
||||||
TypeSpec.classBuilder(abstractAssetClassName)
|
TypeSpec.classBuilder(abstractAssetClassName)
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.ABSTRACT)
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.ABSTRACT)
|
||||||
.addField(String::class.java, "uid", Modifier.PUBLIC, Modifier.FINAL)
|
.addField(String::class.java, "$", Modifier.PUBLIC, Modifier.FINAL)
|
||||||
.addField(
|
.addField(
|
||||||
FieldSpec.builder(
|
FieldSpec.builder(
|
||||||
ParameterizedTypeName.get(
|
ParameterizedTypeName.get(
|
||||||
ClassName.get(java.util.Map::class.java),
|
ClassName.get(java.util.Map::class.java),
|
||||||
ClassName.get(String::class.java),
|
ClassName.get(String::class.java),
|
||||||
ClassName.get(Integer::class.java)
|
abstractLayerClassName
|
||||||
), "_layers", Modifier.PROTECTED, Modifier.FINAL
|
), "_layers", Modifier.PROTECTED, Modifier.FINAL
|
||||||
)
|
)
|
||||||
.initializer("new \$T<>()", java.util.HashMap::class.java)
|
.initializer("new \$T<>()", java.util.HashMap::class.java)
|
||||||
@@ -191,23 +175,52 @@ class AssetMapCodeGenerator : CodeGenerator {
|
|||||||
.addMethod(
|
.addMethod(
|
||||||
MethodSpec.constructorBuilder()
|
MethodSpec.constructorBuilder()
|
||||||
.addParameter(ClassName.get(String::class.java), "uid")
|
.addParameter(ClassName.get(String::class.java), "uid")
|
||||||
.addStatement("this.uid = uid")
|
.addStatement("this.\$\$ = uid")
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.addMethod(
|
.addMethod(
|
||||||
MethodSpec.methodBuilder("get")
|
MethodSpec.methodBuilder("layer")
|
||||||
.addModifiers(Modifier.PUBLIC)
|
.addModifiers(Modifier.PUBLIC)
|
||||||
.addParameter(ClassName.get(String::class.java), "name")
|
.addParameter(ClassName.get(String::class.java), "name")
|
||||||
.returns(ClassName.get(Integer::class.java))
|
.returns(abstractLayerClassName)
|
||||||
.addStatement("return this._layers.get(name)")
|
.addStatement("return this._layers.get(name)")
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
|
).addType(
|
||||||
|
TypeSpec.classBuilder(abstractLayerClassName)
|
||||||
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.ABSTRACT)
|
||||||
|
.addField(TypeName.INT, "$", Modifier.PUBLIC, Modifier.FINAL)
|
||||||
|
.addField(
|
||||||
|
FieldSpec.builder(
|
||||||
|
ParameterizedTypeName.get(
|
||||||
|
ClassName.get(java.util.Map::class.java),
|
||||||
|
ClassName.get(String::class.java),
|
||||||
|
MAP_PIN_TYPE
|
||||||
|
), "_labels", Modifier.PROTECTED, Modifier.FINAL
|
||||||
|
)
|
||||||
|
.initializer("new \$T<>()", java.util.HashMap::class.java)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.addMethod(
|
||||||
|
MethodSpec.constructorBuilder()
|
||||||
|
.addParameter(TypeName.INT, "index")
|
||||||
|
.addStatement("this.\$\$ = index")
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.addMethod(
|
||||||
|
MethodSpec.methodBuilder("label")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addParameter(ClassName.get(String::class.java), "label")
|
||||||
|
.returns(MAP_PIN_TYPE)
|
||||||
|
.addStatement("return this._labels.get(label)")
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
)
|
)
|
||||||
.apply {
|
.apply {
|
||||||
mapLayers.forEach { (asset, layers) ->
|
mapLayers.forEach { (asset, layers) ->
|
||||||
val assetClassName = ClassName.get("", "GameMapAsset_${getCapitalizedAssetName(asset)}")
|
val assetClassName = ClassName.get("", getCapitalizedAssetName(asset))
|
||||||
val layersClassName = ClassName.get("", "GameMapAsset_Layers_${getCapitalizedAssetName(asset)}")
|
|
||||||
|
|
||||||
addField(
|
addField(
|
||||||
FieldSpec
|
FieldSpec
|
||||||
@@ -220,36 +233,62 @@ class AssetMapCodeGenerator : CodeGenerator {
|
|||||||
TypeSpec.classBuilder(assetClassName)
|
TypeSpec.classBuilder(assetClassName)
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
||||||
.superclass(abstractAssetClassName)
|
.superclass(abstractAssetClassName)
|
||||||
.addField(
|
|
||||||
FieldSpec.builder(layersClassName, "layers", Modifier.PUBLIC, Modifier.FINAL)
|
|
||||||
.initializer("new \$T()", layersClassName)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.addMethod(
|
.addMethod(
|
||||||
MethodSpec.constructorBuilder()
|
MethodSpec.constructorBuilder()
|
||||||
.addStatement("super(\"${asset.uid}\")")
|
.addStatement("super(\"${asset.uid}\")")
|
||||||
.apply {
|
.apply {
|
||||||
layers.forEach { layer ->
|
layers.forEach { layer ->
|
||||||
addStatement("this._layers.put(\"${layer.name}\", layers.${getAssetName(layer.name)})")
|
addStatement("this._layers.put(\"${layer.name}\", this.${getAssetName(layer.name)})")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.build()
|
|
||||||
)
|
|
||||||
addType(
|
|
||||||
TypeSpec.classBuilder(layersClassName)
|
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
|
||||||
.apply {
|
.apply {
|
||||||
layers.forEachIndexed { index, layer ->
|
layers.forEachIndexed { index, layer ->
|
||||||
|
val layerClass = ClassName.get("", getCapitalizedAssetName(layer.name))
|
||||||
|
val type = TypeSpec.classBuilder(layerClass)
|
||||||
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
||||||
|
.superclass(abstractLayerClassName)
|
||||||
|
.addMethod(
|
||||||
|
MethodSpec
|
||||||
|
.constructorBuilder()
|
||||||
|
.addStatement("super($index)")
|
||||||
|
.apply {
|
||||||
|
if (layer is ObjectLayer) {
|
||||||
|
layer.labels.forEach { label ->
|
||||||
|
addStatement("this._labels.put(\"${label.label}\", this.${getAssetName(label.label)})")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
//.addField(FieldSpec.builder(TypeName.INT, "$", Modifier.PUBLIC, Modifier.FINAL).initializer(index.toString()).build())
|
||||||
|
.apply {
|
||||||
|
if (layer is ObjectLayer) {
|
||||||
|
layer.labels.forEach { label ->
|
||||||
|
addField(FieldSpec.builder(MAP_PIN_TYPE, getAssetName(label.label), Modifier.FINAL, Modifier.PUBLIC)
|
||||||
|
.initializer("\$T.builder()" +
|
||||||
|
".map(\"${asset.uid}\")" +
|
||||||
|
".layer(${index})" +
|
||||||
|
".x(${label.x})" +
|
||||||
|
".y(${label.y})" +
|
||||||
|
".build()", MAP_PIN_TYPE)
|
||||||
|
.build())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.build()
|
||||||
|
|
||||||
|
addType(type)
|
||||||
|
|
||||||
addField(
|
addField(
|
||||||
FieldSpec.builder(
|
FieldSpec.builder(
|
||||||
TypeName.INT,
|
layerClass,
|
||||||
getAssetName(layer.name),
|
getAssetName(layer.name),
|
||||||
Modifier.PUBLIC,
|
Modifier.PUBLIC,
|
||||||
Modifier.FINAL
|
Modifier.FINAL
|
||||||
)
|
)
|
||||||
.initializer(index.toString())
|
.initializer("new \$T()", layerClass)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -272,4 +311,9 @@ class AssetMapCodeGenerator : CodeGenerator {
|
|||||||
private fun getCapitalizedAssetName(name: String) = name
|
private fun getCapitalizedAssetName(name: String) = name
|
||||||
.split("\\s+".toRegex())
|
.split("\\s+".toRegex())
|
||||||
.joinToString("") { part -> part.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } }
|
.joinToString("") { part -> part.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } }
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val MAP_PIN_TYPE = ClassName.get("com.bartlomiejpluta.base.api.map.layer.object", "MapPin")
|
||||||
|
val GENERATOR_NAME = AssetMapCodeGenerator::class.java.canonicalName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -381,12 +381,11 @@ class DataAccessObjectCodeGenerator : CodeGenerator {
|
|||||||
.addStatement("var list = new \$T<\$T>()", LinkedList::class.java, model)
|
.addStatement("var list = new \$T<\$T>()", LinkedList::class.java, model)
|
||||||
.beginControlFlow("\$T.INSTANCE.getContext().withDatabase(db ->", CONTEXT_HOLDER)
|
.beginControlFlow("\$T.INSTANCE.getContext().withDatabase(db ->", CONTEXT_HOLDER)
|
||||||
.addStatement(
|
.addStatement(
|
||||||
"var filter = filters.stream().map(f -> String.format(\"`%s` %s ?\", f.column.column, f.op.getOp())).collect(\$T.joining(\" AND \"))",
|
"var filter = filters.isEmpty() ? \"\" : \" WHERE \" + filters.stream().map(f -> String.format(\"`%s` %s ?\", f.column.column, f.op.getOp())).collect(\$T.joining(\" AND \"))", COLLECTORS_CLASS
|
||||||
COLLECTORS_CLASS
|
|
||||||
)
|
)
|
||||||
.addStatement("var order = ordering.isEmpty() ? \"\" : \" ORDER BY \" + ordering.stream().collect(\$T.joining(\", \"))", COLLECTORS_CLASS)
|
.addStatement("var order = ordering.isEmpty() ? \"\" : \" ORDER BY \" + ordering.stream().collect(\$T.joining(\", \"))", COLLECTORS_CLASS)
|
||||||
.apply {
|
.apply {
|
||||||
val sql = "SELECT * FROM `${table.name}` WHERE "
|
val sql = "SELECT * FROM `${table.name}` "
|
||||||
addStatement("var statement = db.prepareStatement(\"$sql\" + filter + order)")
|
addStatement("var statement = db.prepareStatement(\"$sql\" + filter + order)")
|
||||||
}
|
}
|
||||||
.addStatement("var i = 1")
|
.addStatement("var i = 1")
|
||||||
@@ -407,6 +406,39 @@ class DataAccessObjectCodeGenerator : CodeGenerator {
|
|||||||
.addStatement("return list")
|
.addStatement("return list")
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
|
.addMethod(
|
||||||
|
MethodSpec.methodBuilder("first")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.returns(model)
|
||||||
|
.addStatement("var list = new \$T<\$T>()", LinkedList::class.java, model)
|
||||||
|
.beginControlFlow("return \$T.INSTANCE.getContext().withDatabase(db ->", CONTEXT_HOLDER)
|
||||||
|
.addStatement(
|
||||||
|
"var filter = filters.isEmpty() ? \"\" : \" WHERE \" + filters.stream().map(f -> String.format(\"`%s` %s ?\", f.column.column, f.op.getOp())).collect(\$T.joining(\" AND \"))",
|
||||||
|
COLLECTORS_CLASS
|
||||||
|
)
|
||||||
|
.addStatement("var order = ordering.isEmpty() ? \"\" : \" ORDER BY \" + ordering.stream().collect(\$T.joining(\", \"))", COLLECTORS_CLASS)
|
||||||
|
.apply {
|
||||||
|
val sql = "SELECT * FROM `${table.name}` "
|
||||||
|
addStatement("var statement = db.prepareStatement(\"$sql\" + filter + order + \" FETCH FIRST ROW ONLY\")")
|
||||||
|
}
|
||||||
|
.addStatement("var i = 1")
|
||||||
|
.beginControlFlow("for (var f : filters)")
|
||||||
|
.addStatement("statement.setObject(i++, f.value)")
|
||||||
|
.endControlFlow()
|
||||||
|
.addStatement("var result = statement.executeQuery()")
|
||||||
|
.beginControlFlow("if(result.next())")
|
||||||
|
.addStatement("var model = ${model.simpleName()}.builder()")
|
||||||
|
.apply {
|
||||||
|
table.columns.forEach { column ->
|
||||||
|
addStatement("model.${snakeToCamelCase(column.name)}(result.${dbToGetMethod(column)}(\"${column.name}\"))")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.addStatement("return model.build()")
|
||||||
|
.endControlFlow()
|
||||||
|
.addStatement("return null")
|
||||||
|
.endControlFlow(")")
|
||||||
|
.build()
|
||||||
|
)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
|
|||||||
@@ -37,9 +37,11 @@ class MapObjectsCodeGenerator : CodeGenerator {
|
|||||||
private fun generateMapObjects(asset: GameMapAsset, map: GameMap, project: Project) {
|
private fun generateMapObjects(asset: GameMapAsset, map: GameMap, project: Project) {
|
||||||
val runner = className(project.runner)
|
val runner = className(project.runner)
|
||||||
|
|
||||||
map.layers
|
map.layers.forEachIndexed { index, layer ->
|
||||||
.mapNotNull { it as? ObjectLayer }
|
if (layer is ObjectLayer) {
|
||||||
.forEach { generateLayerClass(project.buildGeneratedCodeDirectory, asset, map, it, runner) }
|
generateLayerClass(project.buildGeneratedCodeDirectory, asset, map, layer, index, runner)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateLayerClass(
|
private fun generateLayerClass(
|
||||||
@@ -47,6 +49,7 @@ class MapObjectsCodeGenerator : CodeGenerator {
|
|||||||
asset: GameMapAsset,
|
asset: GameMapAsset,
|
||||||
map: GameMap,
|
map: GameMap,
|
||||||
layer: ObjectLayer,
|
layer: ObjectLayer,
|
||||||
|
layerIndex: Int,
|
||||||
runner: ClassName
|
runner: ClassName
|
||||||
) {
|
) {
|
||||||
val packageName = "com.bartlomiejpluta.base.generated.map"
|
val packageName = "com.bartlomiejpluta.base.generated.map"
|
||||||
@@ -77,6 +80,7 @@ class MapObjectsCodeGenerator : CodeGenerator {
|
|||||||
.addParameter(EngineObjectLayer::class.java, "layer", Modifier.FINAL)
|
.addParameter(EngineObjectLayer::class.java, "layer", Modifier.FINAL)
|
||||||
.addParameter(TypeName.INT, "x", Modifier.FINAL)
|
.addParameter(TypeName.INT, "x", Modifier.FINAL)
|
||||||
.addParameter(TypeName.INT, "y", Modifier.FINAL)
|
.addParameter(TypeName.INT, "y", Modifier.FINAL)
|
||||||
|
.addParameter(MAP_PIN_TYPE, "here", Modifier.FINAL)
|
||||||
.addCode(it.code)
|
.addCode(it.code)
|
||||||
.build()
|
.build()
|
||||||
.let(generatedClass::addMethod)
|
.let(generatedClass::addMethod)
|
||||||
@@ -93,7 +97,7 @@ class MapObjectsCodeGenerator : CodeGenerator {
|
|||||||
.addStatement("var customHandler = (\$T) handler", handler)
|
.addStatement("var customHandler = (\$T) handler", handler)
|
||||||
|
|
||||||
layer.objects.forEach {
|
layer.objects.forEach {
|
||||||
runMethod.addStatement("_${it.x}x${it.y}(context, customRunner, customHandler, map, layer, ${it.x}, ${it.y})")
|
runMethod.addStatement("_${it.x}x${it.y}(context, customRunner, customHandler, map, layer, ${it.x}, ${it.y}, \$T.builder().map(\"${map.uid}\").layer($layerIndex).x(${it.x}).y(${it.y}).build())", MAP_PIN_TYPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
generatedClass
|
generatedClass
|
||||||
@@ -132,5 +136,6 @@ class MapObjectsCodeGenerator : CodeGenerator {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val GENERATOR_NAME = MapObjectsCodeGenerator::class.java.canonicalName
|
private val GENERATOR_NAME = MapObjectsCodeGenerator::class.java.canonicalName
|
||||||
|
val MAP_PIN_TYPE = ClassName.get("com.bartlomiejpluta.base.api.map.layer.object", "MapPin")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.bartlomiejpluta.base.editor.common.view
|
||||||
|
|
||||||
|
import javafx.beans.property.SimpleStringProperty
|
||||||
|
import tornadofx.*
|
||||||
|
|
||||||
|
class StringInputFragment : Fragment("Enter value") {
|
||||||
|
val valueProperty = SimpleStringProperty()
|
||||||
|
var value by valueProperty
|
||||||
|
|
||||||
|
private var onCompleteConsumer: ((String) -> Unit)? = null
|
||||||
|
|
||||||
|
fun onComplete(consumer: (String) -> Unit) {
|
||||||
|
this.onCompleteConsumer = consumer
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override val root = borderpane {
|
||||||
|
center = textfield(valueProperty) {
|
||||||
|
whenDocked { requestFocus() }
|
||||||
|
}
|
||||||
|
|
||||||
|
bottom = buttonbar {
|
||||||
|
button("Apply") {
|
||||||
|
action {
|
||||||
|
onCompleteConsumer?.let { it(value) }
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button("Cancel") {
|
||||||
|
action {
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.bartlomiejpluta.base.editor.common.viewmodel
|
||||||
|
|
||||||
|
import tornadofx.*
|
||||||
|
|
||||||
|
class StringVM(value: String = "") : ViewModel() {
|
||||||
|
val valueProperty = value.toProperty()
|
||||||
|
val value by valueProperty
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
package com.bartlomiejpluta.base.editor.map.canvas
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.editor.common.view.StringInputFragment
|
||||||
|
import com.bartlomiejpluta.base.editor.common.viewmodel.StringVM
|
||||||
|
import com.bartlomiejpluta.base.editor.map.model.brush.BrushMode
|
||||||
|
import com.bartlomiejpluta.base.editor.map.model.layer.ObjectLayer
|
||||||
|
import com.bartlomiejpluta.base.editor.map.model.obj.MapLabel
|
||||||
|
import com.bartlomiejpluta.base.editor.map.viewmodel.BrushVM
|
||||||
|
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
|
||||||
|
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
|
||||||
|
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
||||||
|
import com.bartlomiejpluta.base.editor.render.input.MapMouseEvent
|
||||||
|
import javafx.collections.ObservableList
|
||||||
|
import javafx.scene.input.MouseButton
|
||||||
|
import tornadofx.Scope
|
||||||
|
import tornadofx.find
|
||||||
|
import tornadofx.setInScope
|
||||||
|
|
||||||
|
class LabelPaintingTrace(
|
||||||
|
private val projectContext: ProjectContext,
|
||||||
|
private val map: GameMapVM,
|
||||||
|
override val commandName: String
|
||||||
|
) : PaintingTrace {
|
||||||
|
private lateinit var labels: ObservableList<MapLabel>
|
||||||
|
private lateinit var event: MapMouseEvent
|
||||||
|
|
||||||
|
private var newLabel: MapLabel? = null
|
||||||
|
private var formerLabel: MapLabel? = null
|
||||||
|
private var x = 0
|
||||||
|
private var y = 0
|
||||||
|
|
||||||
|
override var executed = false
|
||||||
|
private set
|
||||||
|
|
||||||
|
override fun beginTrace(editorStateVM: EditorStateVM, brushVM: BrushVM, mouseEvent: MapMouseEvent) {
|
||||||
|
x = editorStateVM.cursorColumn
|
||||||
|
y = editorStateVM.cursorRow
|
||||||
|
|
||||||
|
if (y >= map.rows || x >= map.columns || y < 0 || x < 0 || editorStateVM.selectedLayerIndex < 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
labels = (editorStateVM.selectedLayer as ObjectLayer).labels
|
||||||
|
formerLabel = labels.firstOrNull { it.x == x && it.y == y }
|
||||||
|
|
||||||
|
event = mouseEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createOrUpdateLabel() {
|
||||||
|
showCodeDialog(formerLabel?.label ?: "")?.let {
|
||||||
|
newLabel = MapLabel(x, y, it)
|
||||||
|
labels.remove(formerLabel)
|
||||||
|
labels.add(newLabel)
|
||||||
|
executed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showCodeDialog(initialContent: String): String? {
|
||||||
|
val scope = Scope()
|
||||||
|
val vm = StringVM(initialContent)
|
||||||
|
setInScope(vm, scope)
|
||||||
|
|
||||||
|
var content: String? = null
|
||||||
|
|
||||||
|
find<StringInputFragment>(scope).apply {
|
||||||
|
title = "Set label"
|
||||||
|
|
||||||
|
onComplete {
|
||||||
|
content = it
|
||||||
|
}
|
||||||
|
|
||||||
|
openModal(block = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun moveLabel(newX: Int, newY: Int) {
|
||||||
|
if (newY >= map.rows || newX >= map.columns || newY < 0 || newX < 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
formerLabel?.let {
|
||||||
|
newLabel = MapLabel(newX, newY, it.label)
|
||||||
|
labels.remove(formerLabel)
|
||||||
|
labels.add(newLabel)
|
||||||
|
executed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun removeLabel() {
|
||||||
|
labels.remove(formerLabel)
|
||||||
|
executed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun proceedTrace(editorStateVM: EditorStateVM, brushVM: BrushVM, mouseEvent: MapMouseEvent) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun commitTrace(editorStateVM: EditorStateVM, brushVM: BrushVM, mouseEvent: MapMouseEvent) {
|
||||||
|
val newX = editorStateVM.cursorColumn
|
||||||
|
val newY = editorStateVM.cursorRow
|
||||||
|
val dx = newX - x
|
||||||
|
val dy = newY - y
|
||||||
|
|
||||||
|
// Moving
|
||||||
|
if (brushVM.mode == BrushMode.PAINTING_MODE && (dx != 0 || dy != 0)) {
|
||||||
|
moveLabel(newX, newY)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creating new or updating existing one or removing
|
||||||
|
if (event.event.clickCount > 1 && brushVM.mode == BrushMode.PAINTING_MODE) {
|
||||||
|
when (event.button) {
|
||||||
|
MouseButton.PRIMARY -> createOrUpdateLabel()
|
||||||
|
MouseButton.SECONDARY -> removeLabel()
|
||||||
|
else -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removing
|
||||||
|
if (brushVM.mode == BrushMode.ERASING_MODE) {
|
||||||
|
removeLabel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun undo() {
|
||||||
|
labels.remove(newLabel)
|
||||||
|
formerLabel?.let(labels::add)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun redo() {
|
||||||
|
labels.remove(formerLabel)
|
||||||
|
newLabel?.let(labels::add)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val supportedButtons = arrayOf(MouseButton.PRIMARY, MouseButton.SECONDARY)
|
||||||
|
}
|
||||||
@@ -6,9 +6,12 @@ import com.bartlomiejpluta.base.editor.map.model.layer.*
|
|||||||
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
|
import com.bartlomiejpluta.base.editor.map.viewmodel.EditorStateVM
|
||||||
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
|
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
|
||||||
import com.bartlomiejpluta.base.editor.render.model.Renderable
|
import com.bartlomiejpluta.base.editor.render.model.Renderable
|
||||||
|
import javafx.geometry.VPos
|
||||||
import javafx.scene.canvas.GraphicsContext
|
import javafx.scene.canvas.GraphicsContext
|
||||||
import javafx.scene.image.WritableImage
|
import javafx.scene.image.WritableImage
|
||||||
import javafx.scene.paint.Color
|
import javafx.scene.paint.Color
|
||||||
|
import javafx.scene.text.Font
|
||||||
|
import javafx.scene.text.TextAlignment
|
||||||
|
|
||||||
|
|
||||||
class MapCanvas(val map: GameMapVM, private val editorStateVM: EditorStateVM, private val painter: MapPainter) :
|
class MapCanvas(val map: GameMapVM, private val editorStateVM: EditorStateVM, private val painter: MapPainter) :
|
||||||
@@ -157,6 +160,7 @@ class MapCanvas(val map: GameMapVM, private val editorStateVM: EditorStateVM, pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderObjects(gc, objectLayer)
|
renderObjects(gc, objectLayer)
|
||||||
|
renderLabels(gc, objectLayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderObjectPassageMap(gc: GraphicsContext, objectLayer: ObjectLayer) {
|
private fun renderObjectPassageMap(gc: GraphicsContext, objectLayer: ObjectLayer) {
|
||||||
@@ -196,6 +200,60 @@ class MapCanvas(val map: GameMapVM, private val editorStateVM: EditorStateVM, pr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun renderLabels(gc: GraphicsContext, objectLayer: ObjectLayer) {
|
||||||
|
val alpha = gc.globalAlpha
|
||||||
|
val fill = gc.fill
|
||||||
|
val width = gc.lineWidth
|
||||||
|
val align = gc.textAlign
|
||||||
|
val baseLine = gc.textBaseline
|
||||||
|
val font = gc.font
|
||||||
|
|
||||||
|
// gc.font = LABEL_FONT
|
||||||
|
|
||||||
|
for (mapLabel in objectLayer.labels) {
|
||||||
|
|
||||||
|
// gc.globalAlpha = OBJECT_FILL_ALPHA
|
||||||
|
// gc.fill = OBJECT_COLOR
|
||||||
|
//
|
||||||
|
// gc.fillRect(
|
||||||
|
// mapObject.x * tileWidth + OBJECT_MARGIN,
|
||||||
|
// mapObject.y * tileHeight + OBJECT_MARGIN,
|
||||||
|
// tileWidth - 2 * OBJECT_MARGIN,
|
||||||
|
// tileHeight - 2 * OBJECT_MARGIN
|
||||||
|
// )
|
||||||
|
|
||||||
|
gc.globalAlpha = 1.0
|
||||||
|
gc.stroke = LABEL_COLOR
|
||||||
|
gc.fill = LABEL_COLOR
|
||||||
|
gc.lineWidth = LABEL_FONT_WIDTH
|
||||||
|
|
||||||
|
gc.textAlign = TextAlignment.CENTER
|
||||||
|
gc.textBaseline = VPos.CENTER
|
||||||
|
|
||||||
|
gc.fillText(
|
||||||
|
"${mapLabel.label[0]}.${mapLabel.label[mapLabel.label.lastIndex]}",
|
||||||
|
mapLabel.x * tileWidth + tileWidth / 2,
|
||||||
|
mapLabel.y * tileHeight + tileHeight / 2
|
||||||
|
)
|
||||||
|
|
||||||
|
gc.lineWidth = LABEL_WIDTH
|
||||||
|
|
||||||
|
gc.strokeRect(
|
||||||
|
mapLabel.x * tileWidth + LABEL_MARGIN + LABEL_WIDTH/2,
|
||||||
|
mapLabel.y * tileHeight + LABEL_MARGIN + LABEL_WIDTH/2,
|
||||||
|
tileWidth - 2 * LABEL_MARGIN - LABEL_WIDTH/2,
|
||||||
|
tileHeight - 2 * LABEL_MARGIN - LABEL_WIDTH/2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
gc.globalAlpha = alpha
|
||||||
|
gc.fill = fill
|
||||||
|
gc.lineWidth = width
|
||||||
|
gc.textAlign = align
|
||||||
|
gc.textBaseline = baseLine
|
||||||
|
gc.font = font
|
||||||
|
}
|
||||||
|
|
||||||
private fun renderColorLayer(gc: GraphicsContext, colorLayer: ColorLayer) {
|
private fun renderColorLayer(gc: GraphicsContext, colorLayer: ColorLayer) {
|
||||||
val alpha = gc.globalAlpha
|
val alpha = gc.globalAlpha
|
||||||
val color = gc.fill
|
val color = gc.fill
|
||||||
@@ -238,7 +296,11 @@ class MapCanvas(val map: GameMapVM, private val editorStateVM: EditorStateVM, pr
|
|||||||
private val BACKGROUND_COLOR2 = Color.color(0.8, 0.8, 0.8, 1.0)
|
private val BACKGROUND_COLOR2 = Color.color(0.8, 0.8, 0.8, 1.0)
|
||||||
|
|
||||||
private val OBJECT_COLOR = Color.WHITE
|
private val OBJECT_COLOR = Color.WHITE
|
||||||
|
private val LABEL_COLOR = Color.CYAN
|
||||||
|
private val LABEL_WIDTH = 2.0
|
||||||
|
private val LABEL_FONT_WIDTH = 4.0
|
||||||
private const val OBJECT_FILL_ALPHA = 0.3
|
private const val OBJECT_FILL_ALPHA = 0.3
|
||||||
private const val OBJECT_MARGIN = 4
|
private const val OBJECT_MARGIN = 4
|
||||||
|
private const val LABEL_MARGIN = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,6 +72,7 @@ class MapPainter(
|
|||||||
is AutoTileLayer -> AutoTilePaintingTrace(mapVM, "Paint trace")
|
is AutoTileLayer -> AutoTilePaintingTrace(mapVM, "Paint trace")
|
||||||
is ObjectLayer -> when (brushVM.tool) {
|
is ObjectLayer -> when (brushVM.tool) {
|
||||||
BrushTool.DEFAULT -> ObjectPaintingTrace(projectContext, mapVM, "Update object")
|
BrushTool.DEFAULT -> ObjectPaintingTrace(projectContext, mapVM, "Update object")
|
||||||
|
BrushTool.LABEL -> LabelPaintingTrace(projectContext, mapVM, "Update label")
|
||||||
else -> PassageAbilityPaintingTrace(mapVM, "Toggle passage")
|
else -> PassageAbilityPaintingTrace(mapVM, "Toggle passage")
|
||||||
}
|
}
|
||||||
is ImageLayer -> ImagePositionPaintingTrace(mapVM, "Move Image Layer")
|
is ImageLayer -> ImagePositionPaintingTrace(mapVM, "Move Image Layer")
|
||||||
|
|||||||
@@ -84,10 +84,12 @@ class ObjectPaintingTrace(
|
|||||||
get() = """
|
get() = """
|
||||||
/*
|
/*
|
||||||
* Following final parameters are available to use:
|
* Following final parameters are available to use:
|
||||||
* x: int - the x coordinate of tile the object has been created on
|
* here: MapPin - the composite object containing current map UID,
|
||||||
* y: int - the y coordinate of tile the object has been created on
|
* layer's index and x,y coordinates of the current tile
|
||||||
* layer: ObjectLayer - current object layer
|
* x: int - the x coordinate of the current tile
|
||||||
* map: GameMap - current map
|
* y: int - the y coordinate of the current tile
|
||||||
|
* layer: ObjectLayer - current object layer's index
|
||||||
|
* map: GameMap - current map
|
||||||
* handler: ${className(map.handler)} - current map handler
|
* handler: ${className(map.handler)} - current map handler
|
||||||
* runner: ${className(projectContext.project?.runner)} - the game runner of the project
|
* runner: ${className(projectContext.project?.runner)} - the game runner of the project
|
||||||
* context: Context - the game context
|
* context: Context - the game context
|
||||||
|
|||||||
@@ -4,5 +4,6 @@ enum class BrushTool {
|
|||||||
DEFAULT,
|
DEFAULT,
|
||||||
|
|
||||||
// Object Layer
|
// Object Layer
|
||||||
PASSAGE
|
PASSAGE,
|
||||||
|
LABEL
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.bartlomiejpluta.base.editor.map.model.layer
|
package com.bartlomiejpluta.base.editor.map.model.layer
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.editor.map.model.enumeration.PassageAbility
|
import com.bartlomiejpluta.base.editor.map.model.enumeration.PassageAbility
|
||||||
|
import com.bartlomiejpluta.base.editor.map.model.obj.MapLabel
|
||||||
import com.bartlomiejpluta.base.editor.map.model.obj.MapObject
|
import com.bartlomiejpluta.base.editor.map.model.obj.MapObject
|
||||||
import javafx.beans.property.SimpleStringProperty
|
import javafx.beans.property.SimpleStringProperty
|
||||||
import tornadofx.asObservable
|
import tornadofx.asObservable
|
||||||
@@ -14,13 +15,16 @@ class ObjectLayer(
|
|||||||
columns: Int,
|
columns: Int,
|
||||||
objects: List<MapObject> = mutableListOf(),
|
objects: List<MapObject> = mutableListOf(),
|
||||||
javaImports: String = "",
|
javaImports: String = "",
|
||||||
passageMap: Array<Array<PassageAbility>> = Array(rows) { Array(columns) { PassageAbility.ALLOW } }
|
passageMap: Array<Array<PassageAbility>> = Array(rows) { Array(columns) { PassageAbility.ALLOW } },
|
||||||
|
labels: List<MapLabel> = mutableListOf()
|
||||||
) : Layer {
|
) : Layer {
|
||||||
var passageMap = passageMap
|
var passageMap = passageMap
|
||||||
private set
|
private set
|
||||||
|
|
||||||
val objects = objects.asObservable()
|
val objects = objects.asObservable()
|
||||||
|
|
||||||
|
val labels = labels.asObservable()
|
||||||
|
|
||||||
override val nameProperty = SimpleStringProperty(name)
|
override val nameProperty = SimpleStringProperty(name)
|
||||||
|
|
||||||
val javaImportsProperty = javaImports.toProperty()
|
val javaImportsProperty = javaImports.toProperty()
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.bartlomiejpluta.base.editor.map.model.obj
|
||||||
|
|
||||||
|
import tornadofx.getValue
|
||||||
|
import tornadofx.setValue
|
||||||
|
import tornadofx.toProperty
|
||||||
|
|
||||||
|
class MapLabel(x: Int, y: Int, label: String) {
|
||||||
|
val xProperty = x.toProperty()
|
||||||
|
var x by xProperty
|
||||||
|
|
||||||
|
val yProperty = y.toProperty()
|
||||||
|
var y by yProperty
|
||||||
|
|
||||||
|
val labelProperty = label.toProperty()
|
||||||
|
var label by labelProperty
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import com.bartlomiejpluta.base.editor.map.model.enumeration.ImageLayerMode
|
|||||||
import com.bartlomiejpluta.base.editor.map.model.enumeration.PassageAbility
|
import com.bartlomiejpluta.base.editor.map.model.enumeration.PassageAbility
|
||||||
import com.bartlomiejpluta.base.editor.map.model.layer.*
|
import com.bartlomiejpluta.base.editor.map.model.layer.*
|
||||||
import com.bartlomiejpluta.base.editor.map.model.map.GameMap
|
import com.bartlomiejpluta.base.editor.map.model.map.GameMap
|
||||||
|
import com.bartlomiejpluta.base.editor.map.model.obj.MapLabel
|
||||||
import com.bartlomiejpluta.base.editor.map.model.obj.MapObject
|
import com.bartlomiejpluta.base.editor.map.model.obj.MapObject
|
||||||
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
|
||||||
import com.bartlomiejpluta.base.editor.tileset.model.Tile
|
import com.bartlomiejpluta.base.editor.tileset.model.Tile
|
||||||
@@ -121,7 +122,11 @@ class ProtobufMapDeserializer : MapDeserializer {
|
|||||||
MapObject(it.x, it.y, it.code)
|
MapObject(it.x, it.y, it.code)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ObjectLayer(proto.name, rows, columns, objects, proto.objectLayer.javaImports, passageMap)
|
val labels = proto.objectLayer.labelsList.map {
|
||||||
|
MapLabel(it.x, it.y, it.label)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ObjectLayer(proto.name, rows, columns, objects, proto.objectLayer.javaImports, passageMap, labels)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeColorLayer(proto: GameMapProto.Layer): Layer {
|
private fun deserializeColorLayer(proto: GameMapProto.Layer): Layer {
|
||||||
|
|||||||
@@ -60,6 +60,15 @@ class ProtobufMapSerializer : MapSerializer {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.also { proto ->
|
||||||
|
layer.labels.map {
|
||||||
|
proto.addLabels(GameMapProto.MapLabel.newBuilder().apply {
|
||||||
|
x = it.x
|
||||||
|
y = it.y
|
||||||
|
label = it.label
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
.setJavaImports(layer.javaImports)
|
.setJavaImports(layer.javaImports)
|
||||||
.build()
|
.build()
|
||||||
.let { GameMapProto.Layer.newBuilder().setName(layer.name).setObjectLayer(it).build() }
|
.let { GameMapProto.Layer.newBuilder().setName(layer.name).setObjectLayer(it).build() }
|
||||||
|
|||||||
@@ -165,5 +165,16 @@ class MapToolbarView : View() {
|
|||||||
brushVM.commit()
|
brushVM.commit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
togglebutton(value = BrushTool.LABEL, group = objectLayerTool) {
|
||||||
|
graphic = FontIcon("fa-star")
|
||||||
|
|
||||||
|
visibleWhen(isObjectLayerSelected)
|
||||||
|
|
||||||
|
action {
|
||||||
|
brushVM.tool = BrushTool.LABEL
|
||||||
|
brushVM.commit()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user