diff --git a/dependencies/android/AndroidManifest.xml b/dependencies/android/AndroidManifest.xml
new file mode 100644
index 0000000..fd7579b
--- /dev/null
+++ b/dependencies/android/AndroidManifest.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/dependencies/android/build.xml b/dependencies/android/build.xml
new file mode 100644
index 0000000..b046d16
--- /dev/null
+++ b/dependencies/android/build.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dependencies/android/project.properties b/dependencies/android/project.properties
new file mode 100644
index 0000000..816ab69
--- /dev/null
+++ b/dependencies/android/project.properties
@@ -0,0 +1,3 @@
+android.library=true
+android.library.reference.1=../extension-api
+target=android-::ANDROID_TARGET_SDK_VERSION::
diff --git a/dependencies/android/src/ru/m/android/FileUtil.java b/dependencies/android/src/ru/m/android/FileUtil.java
new file mode 100644
index 0000000..b503a44
--- /dev/null
+++ b/dependencies/android/src/ru/m/android/FileUtil.java
@@ -0,0 +1,57 @@
+package ru.m.android;
+
+import android.app.Activity;
+import android.content.res.AssetManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.net.Uri;
+import android.util.Log;
+import org.haxe.extension.Extension;
+import org.haxe.lime.HaxeObject;
+import java.io.InputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public class FileUtil extends Extension {
+ private static HaxeObject callback;
+
+ public static void browse(HaxeObject callback) {
+ FileUtil.callback = callback;
+ Intent intent = new Intent()
+ .setType("*/*")
+ .setAction(Intent.ACTION_GET_CONTENT);
+ Extension.mainActivity.startActivityForResult(Intent.createChooser(intent, "Select a file"), 123);
+ }
+
+ @Override
+ public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == 123 && resultCode == Activity.RESULT_OK) {
+ Uri uri = data.getData(); //The uri with the location of the file
+ try {
+ InputStream is = Extension.mainActivity.getContentResolver().openInputStream(uri);
+ byte[] result = getBytes(is);
+ callback.call("execute", new Object[]{result});
+ } catch (IOException exception) {
+ Log.e("FileUtil", "", exception);
+ }
+ return true;
+ } else {
+ return super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+
+ public static byte[] getBytes(InputStream inputStream) throws IOException {
+ ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
+ int bufferSize = 1024;
+ byte[] buffer = new byte[bufferSize];
+
+ int len = 0;
+ while ((len = inputStream.read(buffer)) != -1) {
+ byteBuffer.write(buffer, 0, len);
+ }
+ return byteBuffer.toByteArray();
+ }
+}
diff --git a/gulpfile.js b/gulpfile.js
index fa1dbc4..21bef73 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -36,6 +36,11 @@ const config = new Project.Config({
],
});
+/*
+
+
+ */
+
const app = new Project(
Project.BuildSystem.OPENFL,
[
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..c0a8ac7
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,3 @@
+include ':android'
+
+
diff --git a/src/haxe/ru/m/puzzlez/FileUtil.hx b/src/haxe/ru/m/puzzlez/FileUtil.hx
new file mode 100644
index 0000000..83242a7
--- /dev/null
+++ b/src/haxe/ru/m/puzzlez/FileUtil.hx
@@ -0,0 +1,73 @@
+package ru.m.puzzlez;
+
+import flash.events.Event;
+import flash.events.IOErrorEvent;
+import flash.events.ProgressEvent;
+import flash.net.FileReference;
+import haxe.io.Bytes;
+import haxe.io.BytesData;
+import promhx.Deferred;
+import promhx.Promise;
+
+typedef FileContent = {
+ var name:String;
+ var content:Bytes;
+}
+
+class Callback {
+ private var callback:T -> Void;
+
+ public function new(callback: T -> Void) {
+ this.callback = callback;
+ }
+
+ public function execute(result:T):Void {
+ this.callback(result);
+ }
+}
+
+class FileUtil {
+ #if android
+ private static var fileUtilBrowse = lime.system.JNI.createStaticMethod(
+ "ru.m.android.FileUtil",
+ "browse",
+ "(Lorg/haxe/lime/HaxeObject;)V"
+ );
+ #end
+
+ public static function browse():Promise {
+ var d = new Deferred();
+ var file = new FileReference();
+ file.addEventListener(Event.SELECT, function(event:Event) {
+ cast(event.target, FileReference).load();
+ });
+ file.addEventListener(IOErrorEvent.IO_ERROR, function(event:IOErrorEvent) {
+ d.throwError(event);
+ });
+ file.addEventListener(ProgressEvent.PROGRESS, function(event:ProgressEvent) {
+ //trace('progress', '${event}');
+ });
+ file.addEventListener(Event.COMPLETE, function(event:Event) {
+ var f:FileReference = cast event.target;
+ d.resolve({
+ name: f.name,
+ content: Bytes.ofData(f.data),
+ });
+ });
+ file.browse();
+ #if android
+ fileUtilBrowse(new Callback(function(result:BytesData):Void {
+ d.resolve({
+ name: "",
+ content: Bytes.ofData(result),
+ });
+ }));
+ #end
+ return d.promise();
+ }
+
+ public static function save(content:FileContent):Void {
+ var file = new FileReference();
+ file.save(content.content.getData(), content.name);
+ }
+}
diff --git a/src/haxe/ru/m/puzzlez/ImageUtil.hx b/src/haxe/ru/m/puzzlez/ImageUtil.hx
new file mode 100644
index 0000000..cf473ac
--- /dev/null
+++ b/src/haxe/ru/m/puzzlez/ImageUtil.hx
@@ -0,0 +1,23 @@
+package ru.m.puzzlez;
+
+import flash.display.Bitmap;
+import flash.display.BitmapData;
+import flash.display.Loader;
+import flash.display.LoaderInfo;
+import flash.events.Event;
+import haxe.io.Bytes;
+import promhx.Deferred;
+import promhx.Promise;
+
+class ImageUtil {
+
+ public static function bytesToImage(bytes:Bytes):Promise {
+ var def = new Deferred();
+ var loader = new Loader();
+ loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(event:Event) {
+ def.resolve(cast(cast(event.target, LoaderInfo).content, Bitmap).bitmapData);
+ });
+ loader.loadBytes(bytes);
+ return def.promise();
+ }
+}
diff --git a/src/haxe/ru/m/puzzlez/core/GamePreset.hx b/src/haxe/ru/m/puzzlez/core/GamePreset.hx
index 759e269..869b5ec 100644
--- a/src/haxe/ru/m/puzzlez/core/GamePreset.hx
+++ b/src/haxe/ru/m/puzzlez/core/GamePreset.hx
@@ -1,9 +1,10 @@
package ru.m.puzzlez.core;
import flash.geom.Rectangle;
+import ru.m.puzzlez.core.Id;
typedef GamePreset = {
- var image:ImageSource;
+ var image:ImageId;
var grid:Grid;
var tableRect:Rectangle;
var imageRect:Rectangle;
diff --git a/src/haxe/ru/m/puzzlez/core/GameUtil.hx b/src/haxe/ru/m/puzzlez/core/GameUtil.hx
index 09a3bbe..237b0b7 100644
--- a/src/haxe/ru/m/puzzlez/core/GameUtil.hx
+++ b/src/haxe/ru/m/puzzlez/core/GameUtil.hx
@@ -1,5 +1,6 @@
package ru.m.puzzlez.core;
+import ru.m.puzzlez.core.Id.ImageId;
import flash.geom.Point;
import flash.geom.Rectangle;
import ru.m.puzzlez.core.Part;
@@ -62,7 +63,7 @@ class BoundsMap {
class GameUtil {
- public static function buildPreset(image:ImageSource):GamePreset {
+ public static function buildPreset(image:ImageId):GamePreset {
var size = 8;
var offsetX = 500;
var offsetY = 200;
diff --git a/src/haxe/ru/m/puzzlez/core/Id.hx b/src/haxe/ru/m/puzzlez/core/Id.hx
new file mode 100644
index 0000000..441a3c2
--- /dev/null
+++ b/src/haxe/ru/m/puzzlez/core/Id.hx
@@ -0,0 +1,24 @@
+package ru.m.puzzlez.core;
+
+typedef SourceId = String;
+
+abstract ImageId({source:SourceId, id:String}) {
+ public var source(get, never):SourceId;
+ private inline function get_source():SourceId return this.source;
+
+ public var id(get, never):String;
+ private inline function get_id():String return this.id;
+
+ public function new(source:SourceId, id:String) {
+ this = {source: source, id: id};
+ }
+
+ @:from public static function fromString(value:String):ImageId {
+ var args = value.split("_");
+ return new ImageId(args[0], args[1]);
+ }
+
+ @:to public function toString():String {
+ return '${this.source}_${this.id}';
+ }
+}
diff --git a/src/haxe/ru/m/puzzlez/core/ImageSource.hx b/src/haxe/ru/m/puzzlez/core/ImageSource.hx
deleted file mode 100644
index 98be924..0000000
--- a/src/haxe/ru/m/puzzlez/core/ImageSource.hx
+++ /dev/null
@@ -1,6 +0,0 @@
-package ru.m.puzzlez.core;
-
-enum ImageSource {
- ASSET(name:String);
- URL(url:String, ?preview:String);
-}
diff --git a/src/haxe/ru/m/puzzlez/storage/AssetSource.hx b/src/haxe/ru/m/puzzlez/storage/AssetSource.hx
new file mode 100644
index 0000000..4b09f4b
--- /dev/null
+++ b/src/haxe/ru/m/puzzlez/storage/AssetSource.hx
@@ -0,0 +1,33 @@
+package ru.m.puzzlez.storage;
+
+import flash.display.BitmapData;
+import openfl.Assets;
+import openfl.utils.AssetType;
+import promhx.Promise;
+import ru.m.puzzlez.core.Id;
+
+class AssetSource implements IImageSource {
+ public static var ID:SourceId = "asset";
+
+ public var id(default, never):SourceId = ID;
+
+ private var data:Promise>;
+
+ public function new() {
+ }
+
+ private function resolveData():Array {
+ return [for (name in Assets.list(AssetType.IMAGE).filter(function(name:String) return name.substr(0, 15) == "resources/image")) new ImageId(id, name)];
+ }
+
+ public function getList(?type:Dynamic):Promise> {
+ if (data == null) {
+ data = Promise.promise(resolveData());
+ }
+ return data;
+ }
+
+ public function loadImage(id:ImageId, preview:Bool = false):Promise {
+ return Promise.promise(Assets.getBitmapData(id.id));
+ }
+}
diff --git a/src/haxe/ru/m/puzzlez/storage/AssetStorage.hx b/src/haxe/ru/m/puzzlez/storage/AssetStorage.hx
deleted file mode 100644
index ae4fb83..0000000
--- a/src/haxe/ru/m/puzzlez/storage/AssetStorage.hx
+++ /dev/null
@@ -1,21 +0,0 @@
-package ru.m.puzzlez.storage;
-
-import openfl.Assets;
-import openfl.utils.AssetType;
-import promhx.Promise;
-import ru.m.puzzlez.core.ImageSource;
-
-@:provide class AssetStorage implements ISourceStorage {
-
- var data:Promise>;
-
- public function new() {
- }
-
- public function resolve(?type:Dynamic):Promise> {
- if (data == null) {
- data = Promise.promise([for (name in Assets.list(AssetType.IMAGE).filter(function(name:String) return name.substr(0, 15) == "resources/image")) ASSET(name)]);
- }
- return data;
- }
-}
diff --git a/src/haxe/ru/m/puzzlez/storage/FileSource.hx b/src/haxe/ru/m/puzzlez/storage/FileSource.hx
new file mode 100644
index 0000000..df7ef94
--- /dev/null
+++ b/src/haxe/ru/m/puzzlez/storage/FileSource.hx
@@ -0,0 +1,48 @@
+package ru.m.puzzlez.storage;
+
+import flash.display.BitmapData;
+import flash.net.SharedObject;
+import haxe.crypto.Md5;
+import haxe.io.Bytes;
+import promhx.Promise;
+import ru.m.puzzlez.core.Id;
+
+class FileSource implements IImageSource {
+ public static var ID:SourceId = "file";
+
+ public var id(default, never):SourceId = ID;
+
+ private var listData:SharedObject;
+
+ public function new() {
+ listData = SharedObject.getLocal('${id}_list');
+ }
+
+ public function getList(?type:Dynamic):Promise> {
+ return Promise.promise([for (name in Reflect.fields(listData.data)) new ImageId(id, name)]);
+ }
+
+ public function loadImage(id:ImageId, preview:Bool = false):Promise {
+ var fileData = SharedObject.getLocal(id);
+ return ImageUtil.bytesToImage(Bytes.ofHex(Reflect.field(fileData.data, "image")));
+ }
+
+ public function append(data:Bytes):ImageId {
+ var name = Md5.make(data).toHex();
+ var imageId = new ImageId(id, name);
+ var fileData = SharedObject.getLocal(imageId);
+ fileData.setProperty("image", data.toHex());
+ fileData.flush();
+ listData.setProperty(name, true);
+ listData.flush();
+ return imageId;
+ }
+
+ public function remove(id:ImageId):Void {
+ var fileData = SharedObject.getLocal(id);
+ fileData.clear();
+ fileData.flush();
+ Reflect.deleteField(listData.data, id);
+ listData.flush();
+ }
+}
diff --git a/src/haxe/ru/m/puzzlez/storage/IImageSource.hx b/src/haxe/ru/m/puzzlez/storage/IImageSource.hx
new file mode 100644
index 0000000..4c6a7f0
--- /dev/null
+++ b/src/haxe/ru/m/puzzlez/storage/IImageSource.hx
@@ -0,0 +1,11 @@
+package ru.m.puzzlez.storage;
+
+import flash.display.BitmapData;
+import promhx.Promise;
+import ru.m.puzzlez.core.Id;
+
+interface IImageSource {
+ public var id(default, never):SourceId;
+ public function getList(?type:T):Promise>;
+ public function loadImage(id:ImageId, preview:Bool = false):Promise;
+}
diff --git a/src/haxe/ru/m/puzzlez/storage/ISourceStorage.hx b/src/haxe/ru/m/puzzlez/storage/ISourceStorage.hx
deleted file mode 100644
index 61e72af..0000000
--- a/src/haxe/ru/m/puzzlez/storage/ISourceStorage.hx
+++ /dev/null
@@ -1,8 +0,0 @@
-package ru.m.puzzlez.storage;
-
-import promhx.Promise;
-import ru.m.puzzlez.core.ImageSource;
-
-interface ISourceStorage {
- public function resolve(?type:T):Promise>;
-}
diff --git a/src/haxe/ru/m/puzzlez/storage/ImageStorage.hx b/src/haxe/ru/m/puzzlez/storage/ImageStorage.hx
index 913102f..5583d87 100644
--- a/src/haxe/ru/m/puzzlez/storage/ImageStorage.hx
+++ b/src/haxe/ru/m/puzzlez/storage/ImageStorage.hx
@@ -7,23 +7,40 @@ import flash.display.LoaderInfo;
import flash.display.PNGEncoderOptions;
import flash.events.Event;
import flash.geom.Rectangle;
+import flash.net.SharedObject;
import flash.utils.ByteArray;
-import haxework.net.ImageLoader;
-import haxework.storage.SharedObjectStorage;
-import openfl.utils.Assets;
import promhx.Deferred;
import promhx.Promise;
-import ru.m.puzzlez.core.ImageSource;
+import Reflect;
+import ru.m.puzzlez.core.Id;
-@:provide class ImageStorage extends SharedObjectStorage {
+@:provide class ImageStorage {
+
+ public var sources(default, null):Map>;
private var cache:Map>;
- private var enabled:Bool;
public function new() {
- super("image_1");
+ sources = new Map();
cache = new Map();
- enabled = false;
+ register(new AssetSource());
+ register(new FileSource());
+ register(new PixabaySource());
+ }
+
+ public function register(source:IImageSource):Void {
+ sources.set(source.id, source);
+ }
+
+ public function read(id:ImageId):BitmapData {
+ var so = SharedObject.getLocal(id);
+ return Reflect.field(so.data, "");
+ }
+
+ public function write(id:ImageId, data:BitmapData):Void {
+ var so = SharedObject.getLocal(id);
+ so.setProperty("", data);
+ so.flush();
}
public static function serialize(image:BitmapData):ByteArray {
@@ -42,24 +59,12 @@ import ru.m.puzzlez.core.ImageSource;
return def.promise();
}
- public function resolve(source:ImageSource, preview:Bool = false):Promise {
- var key = '${source}_${preview}';
+ public function resolve(id:ImageId, preview:Bool = false):Promise {
+ var key = '${id}_${preview}';
if (cache.exists(key)) {
return cache.get(key);
}
- var result:Promise = enabled && exists(key) ?
- unserialize(Reflect.field(so.data, key)) :
- (switch source {
- case ASSET(name):
- Promise.promise(Assets.getBitmapData(name));
- case URL(url, previewUrl):
- new ImageLoader().GET(preview && previewUrl != null ? previewUrl : url);
- }).then(function(image) {
- if (enabled) {
- so.setProperty(key, serialize(image));
- }
- return image;
- });
+ var result = sources.get(id.source).loadImage(id, preview);
cache.set(key, result);
return result;
}
diff --git a/src/haxe/ru/m/puzzlez/storage/PixabaySource.hx b/src/haxe/ru/m/puzzlez/storage/PixabaySource.hx
new file mode 100644
index 0000000..15ee880
--- /dev/null
+++ b/src/haxe/ru/m/puzzlez/storage/PixabaySource.hx
@@ -0,0 +1,94 @@
+package ru.m.puzzlez.storage;
+
+import flash.display.BitmapData;
+import haxework.net.ImageLoader;
+import haxework.net.JsonLoader;
+import promhx.Promise;
+import ru.m.puzzlez.core.Id;
+
+typedef PixabayImage = {
+ var id:Int;
+ var largeImageURL:String;
+ var webformatURL:String;
+ var previewURL:String;
+}
+
+typedef PixabayResponse = {
+ var hits:Array;
+}
+
+@:enum abstract PixabayCategory(String) from String to String {
+ var FASHION = "fashion";
+ var NATURE = "nature";
+ var BACKGROUNDS = "backgrounds";
+ var SCIENCE = "science";
+ var EDUCATION = "education";
+ var PEOPLE = "people";
+ var FEELINGS = "feelings";
+ var RELIGION = "religion";
+ var HEALTH = "health";
+ var PLACES = "places";
+ var ANIMALS = "animals";
+ var INDUSTRY = "industry";
+ var FOOD = "food";
+ var COMPUTER = "computer";
+ var SPORTS = "sports";
+ var TRANSPORTATION = "transportation";
+ var TRAVEL = "travel";
+ var BUILDINGS = "buildings";
+ var BUSINESS = "business";
+ var MUSIC = "music";
+}
+
+@:enum abstract PixabayImageType(String) from String to String {
+ var ALL = "all";
+ var PHOTO = "photo";
+ var ILLUSTRATION = "illustration";
+ var VECTOR = "vector";
+}
+
+class PixabaySource implements IImageSource {
+ public static var ID:SourceId = "pixabay";
+
+ public var id(default, never):SourceId = ID;
+
+ private var baseUrl:String = "https://pixabay.com/api/";
+ private var key:String = "14915210-5eae157281211e0ad28bc8def";
+
+ private var cache:Map>;
+
+ public function new() {
+ cache = new Map();
+ }
+
+ public function getList(?type:PixabayCategory):Promise> {
+ return new JsonLoader()
+ .GET('${baseUrl}?key=${key}&category=${type}&image_type=${PixabayImageType.PHOTO}')
+ .then(function(response:PixabayResponse) {
+ var result = [];
+ for (item in response.hits) {
+ var imageId = new ImageId(id, Std.string(item.id));
+ cache.set(imageId, Promise.promise(item));
+ result.push(imageId);
+ }
+ return [for (item in response.hits) new ImageId(id, Std.string(item.id))];
+ });
+ }
+
+ private function getImage(id:ImageId):Promise {
+ if (!cache.exists(id)) {
+ cache.set(id, new JsonLoader()
+ .GET('${baseUrl}?key=${key}&id=${id.id}')
+ .then(function(response:PixabayResponse) {
+ return response.hits[0];
+ }));
+ }
+ return cache.get(id);
+ }
+
+ public function loadImage(id:ImageId, preview:Bool = false):Promise {
+ return getImage(id).pipe(function(data:PixabayImage) {
+ return new ImageLoader().GET(preview ? data.previewURL : data.largeImageURL);
+ });
+ }
+}
diff --git a/src/haxe/ru/m/puzzlez/storage/PixabayStorage.hx b/src/haxe/ru/m/puzzlez/storage/PixabayStorage.hx
deleted file mode 100644
index 9bcd55e..0000000
--- a/src/haxe/ru/m/puzzlez/storage/PixabayStorage.hx
+++ /dev/null
@@ -1,66 +0,0 @@
-package ru.m.puzzlez.storage;
-
-import haxework.net.JsonLoader;
-import haxework.storage.SharedObjectStorage;
-import promhx.Promise;
-import ru.m.puzzlez.core.ImageSource;
-
-typedef PixabayImage = {
- var id:Int;
- var largeImageURL:String;
- var webformatURL:String;
- var previewURL:String;
-}
-
-typedef PixabayResponse = {
- var hits:Array;
-}
-
-@:enum abstract PixabayCategory(String) from String to String {
- var FASHION = "fashion";
- var NATURE = "nature";
- var BACKGROUNDS = "backgrounds";
- var SCIENCE = "science";
- var EDUCATION = "education";
- var PEOPLE = "people";
- var FEELINGS = "feelings";
- var RELIGION = "religion";
- var HEALTH = "health";
- var PLACES = "places";
- var ANIMALS = "animals";
- var INDUSTRY = "industry";
- var FOOD = "food";
- var COMPUTER = "computer";
- var SPORTS = "sports";
- var TRANSPORTATION = "transportation";
- var TRAVEL = "travel";
- var BUILDINGS = "buildings";
- var BUSINESS = "business";
- var MUSIC = "music";
-}
-
-@:provide class PixabayStorage extends SharedObjectStorage implements ISourceStorage {
-
- private var key:String;
- private var enabled:Bool;
-
- public function new() {
- super("pixabay_1");
- key = "14915210-5eae157281211e0ad28bc8def";
- enabled = false;
- }
-
- public function resolve(?type:PixabayCategory):Promise> {
- return enabled && exists(type) ?
- Promise.promise(read(type)) :
- new JsonLoader()
- .GET('https://pixabay.com/api/?key=${key}&category=${type}')
- .then(function(result:PixabayResponse) {
- var result = [for (item in result.hits) URL(item.largeImageURL, item.previewURL)];
- if (enabled) {
- write(type, result);
- }
- return result;
- });
- }
-}
diff --git a/src/haxe/ru/m/puzzlez/view/GameFrame.hx b/src/haxe/ru/m/puzzlez/view/GameFrame.hx
index e9745d1..c107368 100644
--- a/src/haxe/ru/m/puzzlez/view/GameFrame.hx
+++ b/src/haxe/ru/m/puzzlez/view/GameFrame.hx
@@ -4,11 +4,11 @@ import haxework.view.frame.FrameSwitcher;
import haxework.view.frame.FrameView;
import ru.m.puzzlez.core.Game;
import ru.m.puzzlez.core.GameUtil;
+import ru.m.puzzlez.core.Id;
import ru.m.puzzlez.core.IGame;
-import ru.m.puzzlez.core.ImageSource;
import ru.m.puzzlez.render.IRender;
-@:template class GameFrame extends FrameView {
+@:template class GameFrame extends FrameView {
public static var ID = "game";
@:view private var render:IRender;
@@ -19,7 +19,7 @@ import ru.m.puzzlez.render.IRender;
super(ID);
}
- override public function onShow(image:ImageSource):Void {
+ override public function onShow(image:ImageId):Void {
onHide();
game = new Game(GameUtil.buildPreset(image));
game.signal.connect(render.onGameEvent);
diff --git a/src/haxe/ru/m/puzzlez/view/ImageListSource.hx b/src/haxe/ru/m/puzzlez/view/ImageListSource.hx
new file mode 100644
index 0000000..4c7a6ff
--- /dev/null
+++ b/src/haxe/ru/m/puzzlez/view/ImageListSource.hx
@@ -0,0 +1,8 @@
+package ru.m.puzzlez.view;
+
+import ru.m.puzzlez.storage.IImageSource;
+
+typedef ImageListSource = {
+ var source:IImageSource;
+ @:optional var type:T;
+}
diff --git a/src/haxe/ru/m/puzzlez/view/ImagesFrame.hx b/src/haxe/ru/m/puzzlez/view/ImagesFrame.hx
index 502d971..8db45bc 100644
--- a/src/haxe/ru/m/puzzlez/view/ImagesFrame.hx
+++ b/src/haxe/ru/m/puzzlez/view/ImagesFrame.hx
@@ -1,28 +1,37 @@
package ru.m.puzzlez.view;
import haxework.view.data.DataView;
+import haxework.view.form.ButtonView;
import haxework.view.frame.FrameSwitcher;
import haxework.view.frame.FrameView;
import haxework.view.ImageView;
import haxework.view.utils.DrawUtil;
import openfl.Assets;
-import ru.m.puzzlez.core.ImageSource;
+import ru.m.puzzlez.core.Id;
+import ru.m.puzzlez.FileUtil;
+import ru.m.puzzlez.storage.FileSource;
import ru.m.puzzlez.storage.ImageStorage;
-@:template class ImagesFrame extends FrameView> {
+@:template class ImagesFrame extends FrameView> {
public static var ID = "images";
- @:view var images:DataView;
+ @:view var images:DataView;
+ @:view var select:ButtonView;
@:provide var imageStorage:ImageStorage;
@:provide var switcher:FrameSwitcher;
+ private var source:ImageListSource;
+
public function new() {
super(ID);
}
- override public function onShow(data:Array):Void {
+ override public function onShow(data:ImageListSource):Void {
if (data != null) {
- images.data = data;
+ source = data;
+ select.visible = source.source.id == FileSource.ID;
+ images.data = [];
+ data.source.getList(data.type).then(function(result) images.data = result);
}
}
@@ -30,7 +39,7 @@ import ru.m.puzzlez.storage.ImageStorage;
//images.data = [];
}
- private function imageViewFactory(index:Int, image:ImageSource):ImageView {
+ private function imageViewFactory(index:Int, image:ImageId):ImageView {
var result = new ImageView();
result.style = "view";
result.stretch = false;
@@ -41,7 +50,16 @@ import ru.m.puzzlez.storage.ImageStorage;
return result;
}
- private function start(image:ImageSource):Void {
+ private function selectFile():Void {
+ FileUtil.browse().then(function(data:FileContent) {
+ var fileSource:FileSource = cast source.source;
+ var imageId = fileSource.append(data.content);
+ images.data.push(imageId);
+ images.data = images.data;
+ });
+ }
+
+ private function start(image:ImageId):Void {
switcher.change(GameFrame.ID, image);
}
diff --git a/src/haxe/ru/m/puzzlez/view/ImagesFrame.yaml b/src/haxe/ru/m/puzzlez/view/ImagesFrame.yaml
index 3a43d75..dfad8a4 100644
--- a/src/haxe/ru/m/puzzlez/view/ImagesFrame.yaml
+++ b/src/haxe/ru/m/puzzlez/view/ImagesFrame.yaml
@@ -12,6 +12,11 @@ views:
+onDataSelect: ~start
geometry.margin: 5
overflow.y: scroll
+ - id: select
+ $type: haxework.view.form.ButtonView
+ text: Select...
+ +onPress: ~selectFile()
+ visible: false
- $type: haxework.view.form.ButtonView
text: Back
geometry.position: absolute
diff --git a/src/haxe/ru/m/puzzlez/view/StartFrame.hx b/src/haxe/ru/m/puzzlez/view/StartFrame.hx
index 2ebbce6..7b71469 100644
--- a/src/haxe/ru/m/puzzlez/view/StartFrame.hx
+++ b/src/haxe/ru/m/puzzlez/view/StartFrame.hx
@@ -4,45 +4,36 @@ import haxework.view.data.DataView;
import haxework.view.form.ButtonView;
import haxework.view.frame.FrameSwitcher;
import haxework.view.frame.FrameView;
-import ru.m.puzzlez.core.ImageSource;
-import ru.m.puzzlez.storage.AssetStorage;
-import ru.m.puzzlez.storage.ISourceStorage;
-import ru.m.puzzlez.storage.PixabayStorage;
-
-typedef Source = {
- var storage:ISourceStorage;
- @:optional var type:T;
-}
+import ru.m.puzzlez.storage.AssetSource;
+import ru.m.puzzlez.storage.FileSource;
+import ru.m.puzzlez.storage.ImageStorage;
+import ru.m.puzzlez.storage.PixabaySource;
@:template class StartFrame extends FrameView {
public static var ID = "start";
- @:view var sources:DataView, ButtonView>;
- @:provide var assetStorage:AssetStorage;
- @:provide var pixabayStorage:PixabayStorage;
+ @:view var sources:DataView, ButtonView>;
+ @:provide var storage:ImageStorage;
@:provide var switcher:FrameSwitcher;
public function new() {
super(ID);
- var data:Array> = [];
- data.push({storage: assetStorage});
+ var data:Array> = [];
+ data.push({source: storage.sources.get(AssetSource.ID), type: "asset"});
+ data.push({source: storage.sources.get(FileSource.ID), type: "file"});
for (type in AbstractEnumTools.getValues(PixabayCategory)) {
- data.push({storage: pixabayStorage, type: type});
+ data.push({source: storage.sources.get(PixabaySource.ID), type: type});
}
sources.data = data;
}
- private function sourceViewFactory(index:Int, source:Source):ButtonView {
+ private function sourceViewFactory(index:Int, source:ImageListSource):ButtonView {
var result = new ButtonView();
result.text = Std.string(source.type != null ? source.type : "custom");
return result;
}
- private function load(source:Source):Void {
- source.storage.resolve(source.type).then(onLoaded);
- }
-
- private function onLoaded(result:Array):Void {
- switcher.change(ImagesFrame.ID, result);
+ private function load(source:ImageListSource):Void {
+ switcher.change(ImagesFrame.ID, source);
}
}
diff --git a/work.md b/work.md
new file mode 100644
index 0000000..9c8bac4
--- /dev/null
+++ b/work.md
@@ -0,0 +1,6 @@
+* win event
+* save game state
+* load user images
+* background settings
+* grid settings
+* parts groups