[editor] support level pack edit

This commit is contained in:
2019-09-09 17:56:08 +03:00
parent 4fa5cf84fa
commit 77ddd78d84
25 changed files with 1125 additions and 467 deletions

View File

@@ -1,11 +1,8 @@
const gulp = require('gulp'); const gulp = require('gulp');
const zip = require('gulp-zip');
const foreach = require('gulp-foreach');
const gulpClean = require('gulp-clean'); const gulpClean = require('gulp-clean');
const Config = require('./config.json'); const Config = require('./config.json');
const packageInfo = require('./package.json'); const packageInfo = require('./package.json');
const {System, Sdk, Haxe, Project} = require('gulp-haxetool'); const {System, Sdk, Haxe, Project} = require('gulp-haxetool');
const path = require('path');
const dateformat = require('dateformat'); const dateformat = require('dateformat');
const argv = require('yargs').argv; const argv = require('yargs').argv;
const publish = require('./tasks/gulp-publish'); const publish = require('./tasks/gulp-publish');
@@ -26,19 +23,6 @@ exports.generate = function generate() {
}); });
}; };
exports.levels = function levels() {
return gulp.src("./src/common/level/*").pipe(foreach(function (stream, file) {
const type = file.path.substr(file.path.lastIndexOf(path.sep) + 1);
gulp.src("./src/common/level/" + type + "/*").pipe(foreach(function (stream, file) {
const name = file.path.substr(file.path.lastIndexOf(path.sep) + 1);
gulp.src("./src/common/level/" + type + "/" + name + "/*")
.pipe(zip(`${type}_${name}.zip`))
.pipe(gulp.dest("./target/levels"));
}));
return stream;
}));
};
/** /**
* base config * base config
*/ */
@@ -59,7 +43,6 @@ const config = new Project.Config({
], ],
assets: [ assets: [
'src/common/resources', 'src/common/resources',
'target/levels'
], ],
flags: [ flags: [
//'proto_debug', //'proto_debug',
@@ -168,7 +151,6 @@ module.exports.publish = publish(packageInfo.name, packageInfo.version, Config.P
*/ */
const defaultSeries = [ const defaultSeries = [
exports.clean, exports.clean,
exports.levels,
exports.generate, exports.generate,
module.exports['client:flash:build'], module.exports['client:flash:build'],
module.exports['client:flash:html'], module.exports['client:flash:html'],

1063
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -7,9 +7,7 @@
"gulp": "^4.0.0", "gulp": "^4.0.0",
"gulp-add": "0.0.2", "gulp-add": "0.0.2",
"gulp-clean": "^0.4.0", "gulp-clean": "^0.4.0",
"gulp-foreach": "^0.1.0",
"gulp-haxetool": "0.1.0", "gulp-haxetool": "0.1.0",
"gulp-zip": "^5.0.0",
"yargs": "^13.2.4" "yargs": "^13.2.4"
}, },
"haxeDependencies": { "haxeDependencies": {

View File

@@ -1,6 +1,7 @@
package ru.m.tankz.bundle; package ru.m.tankz.bundle;
import openfl.Assets; import openfl.Assets;
import openfl.utils.AssetType;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.Type; import ru.m.tankz.Type;
import ru.m.tankz.util.LevelUtil; import ru.m.tankz.util.LevelUtil;
@@ -12,7 +13,7 @@ class LevelBundle implements ILevelBundle {
public function new() {} public function new() {}
private function resolve(id:PackId):LevelPack { private function resolve(id:PackId):LevelPack {
var bytes = Assets.getBytes('levels/${id}.zip'); var bytes = Assets.getBytes('resources/level/${id}.zip');
return { return {
id: id, id: id,
data: LevelUtil.unpack(bytes).map(function(level) { data: LevelUtil.unpack(bytes).map(function(level) {
@@ -28,4 +29,14 @@ class LevelBundle implements ILevelBundle {
} }
return _cache.get(id); return _cache.get(id);
} }
public function list():Array<PackId> {
var result = [];
for (path in Assets.list(AssetType.BINARY)) {
if (StringTools.startsWith(path, "resources/level")) {
result.push(PackId.fromString(path.split("/").pop().split(".").shift()));
}
}
return result;
}
} }

View File

@@ -33,7 +33,7 @@ class LocalGame extends GameRunner {
} }
} }
if (humansTeams.length == 1 && result.winner == humansTeams[0]) { if (humansTeams.length == 1 && result.winner == humansTeams[0]) {
var progress = gameStorage.get(new PackId(result.state.type)); var progress = gameStorage.get(result.level.packId);
progress.completeLevel(result.level.id, result.state.presetId); progress.completeLevel(result.level.id, result.state.presetId);
gameStorage.set(progress); gameStorage.set(progress);
} }

View File

@@ -12,6 +12,8 @@ import ru.m.tankz.game.GameState;
import ru.m.tankz.storage.GameStorage; import ru.m.tankz.storage.GameStorage;
import ru.m.tankz.Type.PackId; import ru.m.tankz.Type.PackId;
using ru.m.tankz.view.ViewUtil;
@:template class LevelFrame extends FrameView<PackId> { @:template class LevelFrame extends FrameView<PackId> {
public static inline var ID = "level"; public static inline var ID = "level";
@@ -35,7 +37,7 @@ import ru.m.tankz.Type.PackId;
} }
override public function onShow(data:PackId):Void { override public function onShow(data:PackId):Void {
header.text = data.type; header.text = data.toPackLabel();
pack = levelBundle.get(data); pack = levelBundle.get(data);
levels.data = pack.data; levels.data = pack.data;
} }

View File

@@ -1,9 +1,11 @@
package ru.m.tankz.view; package ru.m.tankz.view;
import haxework.view.data.DataView;
import haxework.view.form.ButtonView; import haxework.view.form.ButtonView;
import haxework.view.form.LabelView; import haxework.view.form.LabelView;
import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameSwitcher;
import haxework.view.frame.FrameView; import haxework.view.frame.FrameView;
import ru.m.tankz.bundle.ILevelBundle;
import ru.m.tankz.game.GameInit; import ru.m.tankz.game.GameInit;
import ru.m.tankz.game.GameState; import ru.m.tankz.game.GameState;
import ru.m.tankz.network.NetworkManager; import ru.m.tankz.network.NetworkManager;
@@ -12,15 +14,19 @@ import ru.m.tankz.view.network.RoomFrame;
import ru.m.tankz.view.network.RoomListFrame; import ru.m.tankz.view.network.RoomListFrame;
import ru.m.tankz.view.popup.LoginPopup; import ru.m.tankz.view.popup.LoginPopup;
using ru.m.tankz.view.ViewUtil;
@:template class MenuFrame extends FrameView<Dynamic> { @:template class MenuFrame extends FrameView<Dynamic> {
public static var ID(default, never):String = "menu"; public static var ID(default, never):String = "menu";
@:provide var gameInit:GameInit; @:provide static var gameInit:GameInit;
@:provide var switcher:FrameSwitcher; @:provide static var switcher:FrameSwitcher;
@:provide var network:NetworkManager; @:provide static var network:NetworkManager;
@:provide var appUpdater:Updater; @:provide static var appUpdater:Updater;
@:provide static var levelBundle:ILevelBundle;
@:view var packs:DataView<PackId, ButtonView>;
@:view var username:LabelView; @:view var username:LabelView;
@:view("login") var loginButton:ButtonView; @:view("login") var loginButton:ButtonView;
@:view("logout") var logoutButton:ButtonView; @:view("logout") var logoutButton:ButtonView;
@@ -40,6 +46,9 @@ import ru.m.tankz.view.popup.LoginPopup;
updateButton.text = 'Update ${appUpdater.bundle.version}'; updateButton.text = 'Update ${appUpdater.bundle.version}';
} }
}); });
var list = levelBundle.list();
list.sort(function(a:PackId, b:PackId) return a.toPackLabel() > b.toPackLabel() ? 1 : -1);
packs.data = list;
} }
override public function onHide():Void { override public function onHide():Void {
@@ -47,9 +56,16 @@ import ru.m.tankz.view.popup.LoginPopup;
network.stateSignal.disconnect(onConnectionState); network.stateSignal.disconnect(onConnectionState);
} }
private function startGame(type:GameType):Void { private function packButtonFactory(index:Int, packId:PackId):ButtonView {
gameInit = LOCAL({state: new GameState(type), level: null}); var result = new ButtonView();
switcher.change(LevelFrame.ID, new PackId(type)); result.style = "button.menu";
result.text = packId.toPackLabel();
return result;
}
private function startGame(packId:PackId):Void {
gameInit = LOCAL({state: new GameState(packId.type), level: null});
switcher.change(LevelFrame.ID, packId);
} }
private function startNetwork():Void { private function startNetwork():Void {

View File

@@ -1,79 +1,74 @@
--- ---
views: views:
- $type: haxework.view.group.VGroupView - $type: haxework.view.group.VGroupView
style: container style: container
overflow.y: scroll overflow.y: scroll
views: views:
- $type: haxework.view.group.VGroupView - $type: haxework.view.group.VGroupView
layout.margin: 10 layout.margin: 10
layout.hAlign: center layout.hAlign: center
views: views:
- $type: haxework.view.form.LabelView - $type: haxework.view.form.LabelView
text: Tank'z text: Tank'z
style: font style: font
font.size: 100 font.size: 100
geometry.margin.bottom: 30 geometry.margin.bottom: 30
- $type: haxework.view.form.ButtonView - id: packs
style: button.menu $type: haxework.view.data.DataView
+onPress: ~startGame('classic') layout:
text: Classic $type: haxework.view.layout.VerticalLayout
- $type: haxework.view.form.ButtonView margin: 10
style: button.menu factory: ~packButtonFactory
+onPress: ~startGame('dota') +onDataSelect: ~startGame
text: DotA
- $type: haxework.view.form.ButtonView
style: button.menu
+onPress: ~startGame('death')
text: DeathMatch
- $type: haxework.view.SpriteView
style: line
geometry.width: 250
geometry.margin: [0, 10]
visible: false
- $type: haxework.view.form.ButtonView
style: button.menu
+onPress: ~switcher.change('record')
text: Records
visible: false
- id: network
$type: haxework.view.form.ButtonView
style: button.menu
+onPress: ~startNetwork()
text: Network
visible: false
- $type: haxework.view.form.LabelView
geometry.hAlign: right
geometry.vAlign: top
geometry.position: absolute
geometry.margin: [0, 20, 20, 0]
style: text.box
text: $r:text:version
- $type: haxework.view.group.HGroupView
style: panel
layout.margin: 10
views:
- id: settings
$type: haxework.view.form.ButtonView
style: button.settings
+onPress: ~switcher.change('settings')
- $type: haxework.view.SpriteView - $type: haxework.view.SpriteView
geometry.width: 50% style: line
- id: username geometry.width: 250
$type: haxework.view.form.LabelView geometry.margin: [0, 10]
style: text
- id: login
$type: haxework.view.form.ButtonView
style: button.login
+onPress: ~login()
- id: logout
$type: haxework.view.form.ButtonView
style: button.logout
+onPress: ~logout()
visible: false visible: false
- $type: haxework.view.SpriteView - $type: haxework.view.form.ButtonView
geometry.width: 50% style: button.menu
- id: update +onPress: ~switcher.change('record')
$type: haxework.view.form.ButtonView text: Records
style: button.active
+onPress: ~appUpdate()
visible: false visible: false
- id: network
$type: haxework.view.form.ButtonView
style: button.menu
+onPress: ~startNetwork()
text: Network
visible: false
- $type: haxework.view.form.LabelView
geometry.hAlign: right
geometry.vAlign: top
geometry.position: absolute
geometry.margin: [0, 20, 20, 0]
style: text.box
text: $r:text:version
- $type: haxework.view.group.HGroupView
style: panel
layout.margin: 10
views:
- id: settings
$type: haxework.view.form.ButtonView
style: button.settings
+onPress: ~switcher.change('settings')
- $type: haxework.view.SpriteView
geometry.width: 50%
- id: username
$type: haxework.view.form.LabelView
style: text
- id: login
$type: haxework.view.form.ButtonView
style: button.login
+onPress: ~login()
- id: logout
$type: haxework.view.form.ButtonView
style: button.logout
+onPress: ~logout()
visible: false
- $type: haxework.view.SpriteView
geometry.width: 50%
- id: update
$type: haxework.view.form.ButtonView
style: button.active
+onPress: ~appUpdate()
visible: false

View File

@@ -1,5 +1,6 @@
package ru.m.tankz.view; package ru.m.tankz.view;
import ru.m.tankz.Type.PackId;
import openfl.Assets; import openfl.Assets;
import ru.m.control.DeviceAction; import ru.m.control.DeviceAction;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
@@ -40,6 +41,10 @@ class ViewUtil {
return result.join(oneline ? " " : "\n"); return result.join(oneline ? " " : "\n");
} }
public static function toPackLabel(packId:PackId):String {
return packId.name != PackId.DEFAULT ? '${packId.type} #${packId.name}' : packId.type;
}
public static function toActionLabel(action:TankAction):String { public static function toActionLabel(action:TankAction):String {
return switch (action) { return switch (action) {
case MOVE(d): 'MOVE_$d'; case MOVE(d): 'MOVE_$d';

View File

@@ -80,6 +80,10 @@ abstract PackId(Array<Dynamic>) {
return new PackId(value[0], value[1]); return new PackId(value[0], value[1]);
} }
@:from static public function fromString(value:String):PackId {
return fromArray(value.split("_"));
}
@:to public inline function toString():String { @:to public inline function toString():String {
return '${type}_${name}'; return '${type}_${name}';
} }

View File

@@ -5,4 +5,5 @@ import ru.m.tankz.Type;
interface ILevelBundle { interface ILevelBundle {
public function get(id:PackId):LevelPack; public function get(id:PackId):LevelPack;
public function list():Array<PackId>;
} }

View File

@@ -1,5 +1,9 @@
package ru.m.tankz.util; package ru.m.tankz.util;
import haxe.zip.Tools;
import haxe.io.BytesOutput;
import haxe.zip.Writer;
import flash.utils.ByteArray;
import haxe.io.Bytes; import haxe.io.Bytes;
import haxe.io.BytesInput; import haxe.io.BytesInput;
import haxe.zip.Entry; import haxe.zip.Entry;
@@ -87,8 +91,32 @@ class LevelUtil {
return level; return level;
} }
private static function compress(level:LevelConfig):Entry {
var content = LevelUtil.dumps(null, level);
var bytes = Bytes.ofString(content);
var crc = haxe.crypto.Crc32.make(bytes);
var result:Entry = {
fileName: '${formatLevel(level.id)}.txt',
fileSize: bytes.length,
fileTime : Date.now(),
compressed : false,
dataSize : bytes.length,
data : bytes,
crc32 : crc,
};
Tools.compress(result, 9);
return result;
}
public static function unpack(bytes:Bytes):Array<LevelConfig> { public static function unpack(bytes:Bytes):Array<LevelConfig> {
var files = Reader.readZip(new BytesInput(bytes)); var files = Reader.readZip(new BytesInput(bytes));
return Lambda.array(files.map(extract)); return Lambda.array(files.map(extract));
} }
public static function pack(data:Array<LevelConfig>):Bytes {
var output = new BytesOutput();
var writer = new Writer(output);
writer.write(Lambda.list(data.map(compress)));
return output.getBytes();
}
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -19,6 +19,7 @@ class Editor {
@:provide static var resources:IResources; @:provide static var resources:IResources;
@:provide static var theme:ITheme; @:provide static var theme:ITheme;
@:provide static var switcher:FrameSwitcher; @:provide static var switcher:FrameSwitcher;
@:provide static var storage:EditorStorage;
public static function main() { public static function main() {
L.push(new haxework.log.TraceLogger()); L.push(new haxework.log.TraceLogger());
@@ -39,6 +40,7 @@ class Editor {
Provider.setFactory(IConfigBundle, ConfigBundle); Provider.setFactory(IConfigBundle, ConfigBundle);
Provider.setFactory(ILevelBundle, LevelBundle); Provider.setFactory(ILevelBundle, LevelBundle);
storage = new EditorStorage();
var view = new EditorView(); var view = new EditorView();
Root.bind(view); Root.bind(view);

View File

@@ -0,0 +1,22 @@
package ru.m.tankz.editor;
import haxe.DynamicAccess;
import haxework.storage.SharedObjectStorage;
import ru.m.tankz.Type;
class EditorStorage extends SharedObjectStorage {
private static inline var VERSION = 2;
public function new() {
super('editor_${VERSION}');
}
public function packList():Array<PackId> {
var result = [];
var data:DynamicAccess<String> = so.data;
for (id in data.keys()) {
result.push(PackId.fromString(id));
}
return result;
}
}

View File

@@ -1,19 +1,18 @@
package ru.m.tankz.editor; package ru.m.tankz.editor;
import promhx.Deferred;
import flash.events.ProgressEvent;
import flash.events.IOErrorEvent;
import flash.events.Event; import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.net.FileReference; import flash.net.FileReference;
import haxe.io.Bytes;
import promhx.Deferred;
import promhx.Promise; import promhx.Promise;
typedef FileContent = { typedef FileContent = {
var name:String; var name:String;
var content:String; var content:Bytes;
} }
class FileUtil { class FileUtil {
public static function browse():Promise<FileContent> { public static function browse():Promise<FileContent> {
@@ -30,10 +29,9 @@ class FileUtil {
}); });
file.addEventListener(Event.COMPLETE, function(event:Event) { file.addEventListener(Event.COMPLETE, function(event:Event) {
var f:FileReference = cast event.target; var f:FileReference = cast event.target;
var data = f.data.readUTFBytes(f.data.length);
d.resolve({ d.resolve({
name: f.name, name: f.name,
content: data content: Bytes.ofData(f.data),
}); });
}); });
file.browse(); file.browse();
@@ -42,7 +40,6 @@ class FileUtil {
public static function save(content:FileContent):Void { public static function save(content:FileContent):Void {
var file = new FileReference(); var file = new FileReference();
file.save(content.content, content.name); file.save(content.content.getData(), content.name);
} }
} }

View File

@@ -1,19 +1,18 @@
package ru.m.tankz.editor.view; package ru.m.tankz.editor.view;
import haxework.view.list.LabelListItem; import ru.m.tankz.util.LevelUtil;
import haxework.view.data.DataView; import haxework.view.data.DataView;
import haxework.view.form.InputView; import haxework.view.form.InputView;
import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameSwitcher;
import haxework.view.frame.FrameView; import haxework.view.frame.FrameView;
import haxework.view.list.LabelListItem;
import haxework.view.list.ListView; import haxework.view.list.ListView;
import ru.m.tankz.bundle.IConfigBundle; import ru.m.tankz.bundle.IConfigBundle;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.editor.FileUtil;
import ru.m.tankz.editor.view.map.BrickView; import ru.m.tankz.editor.view.map.BrickView;
import ru.m.tankz.editor.view.map.MapEditView; import ru.m.tankz.editor.view.map.MapEditView;
import ru.m.tankz.editor.view.map.SpawnPointView; import ru.m.tankz.editor.view.map.SpawnPointView;
import ru.m.tankz.Type; import ru.m.tankz.Type;
import ru.m.tankz.util.LevelUtil;
using ru.m.tankz.view.ViewUtil; using ru.m.tankz.view.ViewUtil;
@@ -24,6 +23,7 @@ using ru.m.tankz.view.ViewUtil;
public var level(default, set):LevelConfig; public var level(default, set):LevelConfig;
private var fileName:String; private var fileName:String;
private var pack:LevelPack;
@:view var levels:ListView<LevelConfig>; @:view var levels:ListView<LevelConfig>;
@:view var levelName:InputView; @:view var levelName:InputView;
@@ -36,6 +36,7 @@ using ru.m.tankz.view.ViewUtil;
@:provide var configBundle:IConfigBundle; @:provide var configBundle:IConfigBundle;
@:provide var config:Config; @:provide var config:Config;
@:provide static var switcher:FrameSwitcher; @:provide static var switcher:FrameSwitcher;
@:provide static var storage:EditorStorage;
public function new() { public function new() {
super(ID); super(ID);
@@ -43,8 +44,12 @@ using ru.m.tankz.view.ViewUtil;
override public function onShow(data:LevelPack):Void { override public function onShow(data:LevelPack):Void {
super.onShow(data); super.onShow(data);
type = data.id.type; pack = data;
levels.data = data.data; type = pack.id.type;
levels.data = pack.data;
if (pack.data.length > 0) {
level = pack.data[0];
}
} }
private function set_type(value:GameType):GameType { private function set_type(value:GameType):GameType {
@@ -104,20 +109,14 @@ using ru.m.tankz.view.ViewUtil;
updateSelected(null, point); updateSelected(null, point);
} }
private function open():Void {
FileUtil.browse().then(function(content:FileContent) {
fileName = content.name;
level = LevelUtil.loads(content.content);
});
}
private function save():Void { private function save():Void {
var data = mapView.data; var data = mapView.data;
data.id = level.id;
data.packId = pack.id;
data.name = levelName.text; data.name = levelName.text;
FileUtil.save({ pack.data[data.id] = data;
name: fileName, levels.data = pack.data;
content: LevelUtil.dumps(config, data), storage.write(pack.id, pack);
});
} }
private function applySize():Void { private function applySize():Void {
@@ -129,4 +128,23 @@ using ru.m.tankz.view.ViewUtil;
heightInput.text = Std.string(config.map.grid.height); heightInput.text = Std.string(config.map.grid.height);
mapView.gridSize = null; mapView.gridSize = null;
} }
private function addLevel():Void {
var level = LevelUtil.empty(config.map.grid, 0);
level.id = pack.data.length;
level.packId = pack.id;
pack.data.push(level);
levels.data = pack.data;
this.level = level;
}
private function removeLevel():Void {
if (level != null) {
pack.data.remove(level);
levels.data = pack.data;
if (pack.data.length > 0) {
this.level = pack.data[0];
}
}
}
} }

View File

@@ -3,14 +3,20 @@ views:
- $type: haxework.view.group.HGroupView - $type: haxework.view.group.HGroupView
geometry.stretch: true geometry.stretch: true
views: views:
- id: levels - $type: haxework.view.group.VGroupView
$type: haxework.view.list.VListView
geometry.width: 200
geometry.height: 100% geometry.height: 100%
factory: ~levelViewFactory views:
+onItemSelect: ~onLevelSelect - id: levels
scroll: $type: haxework.view.list.VListView
$type: haxework.view.list.VScrollBarView geometry.width: 200
geometry.height: 100%
factory: ~levelViewFactory
+onItemSelect: ~onLevelSelect
scroll:
$type: haxework.view.list.VScrollBarView
- $type: haxework.view.form.ButtonView
text: +
+onPress: ~addLevel()
- $type: haxework.view.group.VGroupView - $type: haxework.view.group.VGroupView
geometry.stretch: true geometry.stretch: true
views: views:
@@ -69,22 +75,20 @@ views:
overflow.x: crop overflow.x: crop
overflow.y: crop overflow.y: crop
views: views:
- $type: ru.m.tankz.view.game.GameViewContainer - $type: ru.m.tankz.view.game.GameViewContainer
views: views:
- id: mapView - id: mapView
$type: ru.m.tankz.editor.view.map.MapEditView $type: ru.m.tankz.editor.view.map.MapEditView
- $type: haxework.view.group.HGroupView - $type: haxework.view.group.HGroupView
style: panel style: panel
layout.margin: 10 layout.margin: 10
views: views:
- $type: haxework.view.SpriteView - $type: haxework.view.SpriteView
geometry.width: 100% geometry.width: 100%
- id: openButton - $type: haxework.view.form.ButtonView
$type: haxework.view.form.ButtonView text: Remove
text: Open +onPress: ~removeLevel()
+onPress: ~open() - $type: haxework.view.form.ButtonView
- id: saveButton
$type: haxework.view.form.ButtonView
text: Save text: Save
+onPress: ~save() +onPress: ~save()
- $type: haxework.view.form.ButtonView - $type: haxework.view.form.ButtonView

View File

@@ -1,20 +1,22 @@
package ru.m.tankz.editor.view; package ru.m.tankz.editor.view;
import haxework.view.data.DataView; import haxework.view.data.DataView;
import haxework.view.form.ButtonView;
import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameSwitcher;
import haxework.view.frame.FrameView; import haxework.view.frame.FrameView;
import ru.m.tankz.bundle.ILevelBundle; import ru.m.tankz.bundle.ILevelBundle;
import ru.m.tankz.config.Config; import ru.m.tankz.config.Config;
import ru.m.tankz.editor.FileUtil;
import ru.m.tankz.Type; import ru.m.tankz.Type;
import ru.m.tankz.util.LevelUtil;
@:template class PackListFrame extends FrameView<Dynamic> { @:template class PackListFrame extends FrameView<Dynamic> {
public static inline var ID = "pack_list"; public static inline var ID = "pack_list";
@:view("packs") var packView:DataView<LevelPack, ButtonView>; @:view("packs") var packView:DataView<PackId, PackView>;
@:provide static var levelBundle:ILevelBundle; @:provide static var levelBundle:ILevelBundle;
@:provide static var switcher:FrameSwitcher; @:provide static var switcher:FrameSwitcher;
@:provide static var storage:EditorStorage;
public function new() { public function new() {
super(ID); super(ID);
@@ -22,20 +24,49 @@ import ru.m.tankz.Type;
override public function onShow(data:Dynamic):Void { override public function onShow(data:Dynamic):Void {
super.onShow(data); super.onShow(data);
packView.data = [ packView.data = storage.packList();
levelBundle.get(new PackId("classic")),
levelBundle.get(new PackId("dota")),
levelBundle.get(new PackId("death")),
];
} }
private function packViewFactory(index:Int, value:LevelPack):ButtonView { private function onPackAction(value:PackId, action:String):Void {
var result = new ButtonView(); switch action {
result.text = value.id; case "export":
return result; var pack:LevelPack = storage.read(value);
FileUtil.save({
name: '${value}.zip',
content: LevelUtil.pack(pack.data),
});
case "edit":
switcher.change(PackFrame.ID, storage.read(value));
case "delete":
storage.delete(value);
packView.data = storage.packList();
case _:
}
} }
private function onPackSelect(value:LevelPack):Void { private function create():Void {
switcher.change(PackFrame.ID, value); var levelPack:LevelPack = {
id: new PackId("classic", "modern"),
data: [],
}
storage.write(levelPack.id, levelPack);
packView.data.push(levelPack.id);
packView.data = packView.data;
}
private function open():Void {
FileUtil.browse().then(function(file:FileContent) {
var packId = PackId.fromArray(file.name.split("/").pop().split(".").shift().split("_"));
var levelPack:LevelPack = {
id: packId,
data: LevelUtil.unpack(file.content).map(function(level) {
level.packId = packId;
return level;
}),
};
storage.write(levelPack.id, levelPack);
packView.data.push(levelPack.id);
packView.data = packView.data;
});
} }
} }

View File

@@ -1,17 +1,22 @@
--- ---
views: views:
- id: packs - $type: haxework.view.group.VGroupView
$type: haxework.view.data.DataView style: container
geometry.width: 100% layout.margin: 10
geometry.height: 100% views:
geometry.padding: 30 - $type: haxework.view.form.ButtonView
overflow.y: scroll text: New
layout: +onPress: ~create()
$type: haxework.view.layout.TailLayout - id: packs
rowSize: 10 $type: haxework.view.data.DataView
margin: 5 layout:
factory: ~packViewFactory $type: haxework.view.layout.VerticalLayout
+onDataSelect: ~onPackSelect margin: 5
factory: ~ru.m.tankz.editor.view.PackView.factory
+onDataAction: ~onPackAction
- $type: haxework.view.form.ButtonView
text: Open
+onPress: ~open()
- $type: haxework.view.group.HGroupView - $type: haxework.view.group.HGroupView
style: panel style: panel
layout.margin: 10 layout.margin: 10

View File

@@ -0,0 +1,50 @@
package ru.m.tankz.editor.view;
import haxework.signal.Signal;
import haxework.view.data.DataView;
import haxework.view.form.ButtonView;
import haxework.view.group.HGroupView;
import haxework.view.list.ListView;
import ru.m.tankz.Type;
using ru.m.tankz.view.ViewUtil;
@:template class PackView extends HGroupView implements IListItemView<PackId> {
public var item_index(default, default):Int;
public var data(default, set):PackId;
private var actionSignal(get, null):Signal2<PackId, String>;
@:view var label:ButtonView;
private function set_data(value:PackId):PackId {
data = value;
label.text = data.toPackLabel();
return data;
}
private function get_actionSignal():Signal2<PackId, String> {
var dataView:DataView<PackId, PackView> = cast parent;
return dataView.onDataAction;
}
private function export():Void {
actionSignal.emit(data, "export");
}
private function edit():Void {
actionSignal.emit(data, "edit");
}
private function delete():Void {
actionSignal.emit(data, "delete");
}
public static function factory(index:Int, value:PackId):PackView {
var result = new PackView();
result.item_index = index;
result.data = value;
return result;
}
}

View File

@@ -0,0 +1,14 @@
---
layout.margin: 5
views:
- $type: haxework.view.form.ButtonView
style: button.prev
+onPress: ~export()
- id: label
$type: haxework.view.form.ButtonView
geometry.width: 250
+onPress: ~edit()
- $type: haxework.view.form.ButtonView
style: button.close
+onPress: ~delete()