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