[add] frames views
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "puzzlez",
|
"name": "puzzlez",
|
||||||
"version": "0.0.4",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"dateformat": "^3.0.3",
|
"dateformat": "^3.0.3",
|
||||||
|
|||||||
38
src/haxe/ru/m/AbstractEnumTools.hx
Normal file
38
src/haxe/ru/m/AbstractEnumTools.hx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package ru.m;
|
||||||
|
|
||||||
|
#if macro
|
||||||
|
import haxe.macro.Context;
|
||||||
|
import haxe.macro.Expr;
|
||||||
|
using haxe.macro.Tools;
|
||||||
|
#end
|
||||||
|
|
||||||
|
class AbstractEnumTools {
|
||||||
|
public static macro function getValues(typePath:Expr):Expr {
|
||||||
|
// Get the type from a given expression converted to string.
|
||||||
|
// This will work for identifiers and field access which is what we need,
|
||||||
|
// it will also consider local imports. If expression is not a valid type path or type is not found,
|
||||||
|
// compiler will give a error here.
|
||||||
|
var type = Context.getType(typePath.toString());
|
||||||
|
|
||||||
|
// Switch on the type and check if it's an abstract with @:enum metadata
|
||||||
|
switch (type.follow()) {
|
||||||
|
case TAbstract(_.get() => ab, _) if (ab.meta.has(":enum")):
|
||||||
|
// @:enum abstract values are actually static fields of the abstract implementation class,
|
||||||
|
// marked with @:enum and @:impl metadata. We generate an array of expressions that access those fields.
|
||||||
|
// Note that this is a bit of implementation detail, so it can change in future Haxe versions, but it's been
|
||||||
|
// stable so far.
|
||||||
|
var valueExprs = [];
|
||||||
|
for (field in ab.impl.get().statics.get()) {
|
||||||
|
if (field.meta.has(":enum") && field.meta.has(":impl")) {
|
||||||
|
var fieldName = field.name;
|
||||||
|
valueExprs.push(macro $typePath.$fieldName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Return collected expressions as an array declaration.
|
||||||
|
return macro $a{valueExprs};
|
||||||
|
default:
|
||||||
|
// The given type is not an abstract, or doesn't have @:enum metadata, show a nice error message.
|
||||||
|
throw new Error(type.toString() + " should be @:enum abstract", typePath.pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/haxe/ru/m/puzzlez/Const.hx
Executable file
20
src/haxe/ru/m/puzzlez/Const.hx
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
package ru.m.puzzlez;
|
||||||
|
|
||||||
|
import flash.Lib;
|
||||||
|
import flash.system.Capabilities;
|
||||||
|
|
||||||
|
class Const {
|
||||||
|
public static var FPS:Int;
|
||||||
|
public static var BUILD:String;
|
||||||
|
public static var VERSION:String;
|
||||||
|
public static var NAME:String;
|
||||||
|
public static var DEBUG:Bool;
|
||||||
|
|
||||||
|
public static function init():Void {
|
||||||
|
FPS = Std.parseInt(Lib.current.stage.application.meta.get("fps"));
|
||||||
|
BUILD = CompilationOption.get("build");
|
||||||
|
VERSION = Lib.current.stage.application.meta.get("version");
|
||||||
|
NAME = Lib.current.stage.application.meta.get("name");
|
||||||
|
DEBUG = Capabilities.isDebugger;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,9 @@ class PuzzlezApp extends App {
|
|||||||
LinuxIcon.apply();
|
LinuxIcon.apply();
|
||||||
#end
|
#end
|
||||||
var app = new PuzzlezApp(new PuzzlezTheme());
|
var app = new PuzzlezApp(new PuzzlezTheme());
|
||||||
app.start(new PuzzlezAppView());
|
var view = new PuzzlezAppView();
|
||||||
|
app.start(view);
|
||||||
|
view.launch();
|
||||||
L.d("Puzzlez", "started");
|
L.d("Puzzlez", "started");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ package ru.m.puzzlez.core;
|
|||||||
|
|
||||||
enum ImageSource {
|
enum ImageSource {
|
||||||
ASSET(name:String);
|
ASSET(name:String);
|
||||||
URL(url:String);
|
URL(url:String, ?preview:String);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,16 @@ class ProgressView extends LabelView {
|
|||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
text = 'Loading 0/0';
|
text = 'Loading...';
|
||||||
update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setProgress(current:Int, total:Int):Void {
|
public function setProgress(current:Int, total:Int):Void {
|
||||||
text = 'Loading ${current}/${total}';
|
text = 'Loading ${current}/${total}';
|
||||||
|
}
|
||||||
|
|
||||||
|
override private function set_text(value:String):String {
|
||||||
|
var result = super.set_text(value);
|
||||||
update();
|
update();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ class Render extends SpriteView implements IRender {
|
|||||||
table.graphics.drawRect(state.preset.imageRect.x, state.preset.imageRect.y, state.preset.imageRect.width, state.preset.imageRect.height);
|
table.graphics.drawRect(state.preset.imageRect.x, state.preset.imageRect.y, state.preset.imageRect.width, state.preset.imageRect.height);
|
||||||
table.graphics.endFill();
|
table.graphics.endFill();
|
||||||
table.graphics.lineStyle();
|
table.graphics.lineStyle();
|
||||||
progress.setProgress(0, state.parts.length);
|
progress.text = "Loading image";
|
||||||
content.addChild(progress.content);
|
content.addChild(progress.content);
|
||||||
imageStorage.resolve(state.preset.image).then(onImageResolved);
|
imageStorage.resolve(state.preset.image).then(onImageResolved);
|
||||||
toUpdate();
|
toUpdate();
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ import openfl.utils.AssetType;
|
|||||||
import promhx.Promise;
|
import promhx.Promise;
|
||||||
import ru.m.puzzlez.core.ImageSource;
|
import ru.m.puzzlez.core.ImageSource;
|
||||||
|
|
||||||
@:provide class AssetStorage implements ISourceStorage {
|
@:provide class AssetStorage implements ISourceStorage<Dynamic> {
|
||||||
|
|
||||||
var data:Promise<Array<ImageSource>>;
|
var data:Promise<Array<ImageSource>>;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function resolve(?type:String):Promise<Array<ImageSource>> {
|
public function resolve(?type:Dynamic):Promise<Array<ImageSource>> {
|
||||||
if (data == null) {
|
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)]);
|
data = Promise.promise([for (name in Assets.list(AssetType.IMAGE).filter(function(name:String) return name.substr(0, 15) == "resources/image")) ASSET(name)]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package ru.m.puzzlez.storage;
|
package ru.m.puzzlez.storage;
|
||||||
|
|
||||||
import ru.m.puzzlez.core.ImageSource;
|
|
||||||
import promhx.Promise;
|
import promhx.Promise;
|
||||||
|
import ru.m.puzzlez.core.ImageSource;
|
||||||
|
|
||||||
interface ISourceStorage {
|
interface ISourceStorage<T> {
|
||||||
public function resolve(?type:String):Promise<Array<ImageSource>>;
|
public function resolve(?type:T):Promise<Array<ImageSource>>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import ru.m.puzzlez.core.ImageSource;
|
|||||||
|
|
||||||
@:provide class ImageStorage extends SharedObjectStorage {
|
@:provide class ImageStorage extends SharedObjectStorage {
|
||||||
|
|
||||||
private var cache:Map<ImageSource, Promise<BitmapData>>;
|
private var cache:Map<String, Promise<BitmapData>>;
|
||||||
private var enabled:Bool;
|
private var enabled:Bool;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
@@ -42,25 +42,25 @@ import ru.m.puzzlez.core.ImageSource;
|
|||||||
return def.promise();
|
return def.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function resolve(source:ImageSource):Promise<BitmapData> {
|
public function resolve(source:ImageSource, preview:Bool = false):Promise<BitmapData> {
|
||||||
if (cache.exists(source)) {
|
var key = '${source}_${preview}';
|
||||||
return cache.get(source);
|
if (cache.exists(key)) {
|
||||||
|
return cache.get(key);
|
||||||
}
|
}
|
||||||
var key = Std.string(source);
|
|
||||||
var result:Promise<BitmapData> = enabled && exists(key) ?
|
var result:Promise<BitmapData> = enabled && exists(key) ?
|
||||||
unserialize(Reflect.field(so.data, key)) :
|
unserialize(Reflect.field(so.data, key)) :
|
||||||
(switch source {
|
(switch source {
|
||||||
case ASSET(name):
|
case ASSET(name):
|
||||||
Promise.promise(Assets.getBitmapData(name));
|
Promise.promise(Assets.getBitmapData(name));
|
||||||
case URL(url):
|
case URL(url, previewUrl):
|
||||||
new ImageLoader().GET(url);
|
new ImageLoader().GET(preview && previewUrl != null ? previewUrl : url);
|
||||||
}).then(function(image) {
|
}).then(function(image) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
so.setProperty(key, serialize(image));
|
so.setProperty(key, serialize(image));
|
||||||
}
|
}
|
||||||
return image;
|
return image;
|
||||||
});
|
});
|
||||||
cache.set(source, result);
|
cache.set(key, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,35 +5,41 @@ import haxework.storage.SharedObjectStorage;
|
|||||||
import promhx.Promise;
|
import promhx.Promise;
|
||||||
import ru.m.puzzlez.core.ImageSource;
|
import ru.m.puzzlez.core.ImageSource;
|
||||||
|
|
||||||
|
typedef PixabayImage = {
|
||||||
|
var id:Int;
|
||||||
|
var largeImageURL:String;
|
||||||
|
var webformatURL:String;
|
||||||
|
var previewURL:String;
|
||||||
|
}
|
||||||
|
|
||||||
typedef PixabayResponse = {
|
typedef PixabayResponse = {
|
||||||
hits:Array<{
|
var hits:Array<PixabayImage>;
|
||||||
largeImageURL:String,
|
|
||||||
}>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PixabayCategory {
|
@:enum abstract PixabayCategory(String) from String to String {
|
||||||
FASHION;
|
var FASHION = "fashion";
|
||||||
NATURE;
|
var NATURE = "nature";
|
||||||
BACKGROUNDS;
|
var BACKGROUNDS = "backgrounds";
|
||||||
SCIENCE;
|
var SCIENCE = "science";
|
||||||
EDUCATION;
|
var EDUCATION = "education";
|
||||||
PEOPLE;
|
var PEOPLE = "people";
|
||||||
FEELINGS;
|
var FEELINGS = "feelings";
|
||||||
RELIGION;
|
var RELIGION = "religion";
|
||||||
HEALTH;
|
var HEALTH = "health";
|
||||||
PLACES;
|
var PLACES = "places";
|
||||||
ANIMALS;
|
var ANIMALS = "animals";
|
||||||
INDUSTRY;
|
var INDUSTRY = "industry";
|
||||||
FOOD;
|
var FOOD = "food";
|
||||||
COMPUTER;
|
var COMPUTER = "computer";
|
||||||
SPORTS;
|
var SPORTS = "sports";
|
||||||
TRANSPORTATION;
|
var TRANSPORTATION = "transportation";
|
||||||
TRAVEL; BUILDINGS;
|
var TRAVEL = "travel";
|
||||||
BUSINESS;
|
var BUILDINGS = "buildings";
|
||||||
MUSIC;
|
var BUSINESS = "business";
|
||||||
|
var MUSIC = "music";
|
||||||
}
|
}
|
||||||
|
|
||||||
@:provide class PixabayStorage extends SharedObjectStorage implements ISourceStorage {
|
@:provide class PixabayStorage extends SharedObjectStorage implements ISourceStorage<PixabayCategory> {
|
||||||
|
|
||||||
private var key:String;
|
private var key:String;
|
||||||
private var enabled:Bool;
|
private var enabled:Bool;
|
||||||
@@ -44,13 +50,13 @@ enum PixabayCategory {
|
|||||||
enabled = false;
|
enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function resolve(?type:String):Promise<Array<ImageSource>> {
|
public function resolve(?type:PixabayCategory):Promise<Array<ImageSource>> {
|
||||||
return enabled && exists(type) ?
|
return enabled && exists(type) ?
|
||||||
Promise.promise(read(type)) :
|
Promise.promise(read(type)) :
|
||||||
new JsonLoader<PixabayResponse>()
|
new JsonLoader<PixabayResponse>()
|
||||||
.GET('https://pixabay.com/api/?key=${key}&q=${type}')
|
.GET('https://pixabay.com/api/?key=${key}&category=${type}')
|
||||||
.then(function(result:PixabayResponse) {
|
.then(function(result:PixabayResponse) {
|
||||||
var result = [for (item in result.hits) URL(item.largeImageURL)];
|
var result = [for (item in result.hits) URL(item.largeImageURL, item.previewURL)];
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
write(type, result);
|
write(type, result);
|
||||||
}
|
}
|
||||||
|
|||||||
42
src/haxe/ru/m/puzzlez/view/GameFrame.hx
Normal file
42
src/haxe/ru/m/puzzlez/view/GameFrame.hx
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package ru.m.puzzlez.view;
|
||||||
|
|
||||||
|
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.IGame;
|
||||||
|
import ru.m.puzzlez.core.ImageSource;
|
||||||
|
import ru.m.puzzlez.render.IRender;
|
||||||
|
|
||||||
|
@:template class GameFrame extends FrameView<ImageSource> {
|
||||||
|
public static var ID = "game";
|
||||||
|
|
||||||
|
@:view private var render:IRender;
|
||||||
|
private var game:IGame;
|
||||||
|
@:provide var switcher:FrameSwitcher;
|
||||||
|
|
||||||
|
public function new() {
|
||||||
|
super(ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function onShow(image:ImageSource):Void {
|
||||||
|
onHide();
|
||||||
|
game = new Game(GameUtil.buildPreset(image));
|
||||||
|
game.signal.connect(render.onGameEvent);
|
||||||
|
render.signal.connect(game.signal.emit);
|
||||||
|
game.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function onHide():Void {
|
||||||
|
if (game != null) {
|
||||||
|
render.signal.disconnect(game.signal.emit);
|
||||||
|
game.stop();
|
||||||
|
game.dispose();
|
||||||
|
game = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function back():Void {
|
||||||
|
switcher.change(ImagesFrame.ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/haxe/ru/m/puzzlez/view/GameFrame.yaml
Normal file
17
src/haxe/ru/m/puzzlez/view/GameFrame.yaml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
style: frame
|
||||||
|
geometry.width: 100%
|
||||||
|
geometry.height: 100%
|
||||||
|
overflow.x: crop
|
||||||
|
overflow.y: crop
|
||||||
|
views:
|
||||||
|
- id: render
|
||||||
|
$type: ru.m.puzzlez.render.Render
|
||||||
|
geometry.width: 100%
|
||||||
|
geometry.height: 100%
|
||||||
|
- $type: haxework.view.form.ButtonView
|
||||||
|
text: Back
|
||||||
|
geometry.position: absolute
|
||||||
|
geometry.hAlign: right
|
||||||
|
geometry.vAlign: top
|
||||||
|
+onPress: ~back()
|
||||||
51
src/haxe/ru/m/puzzlez/view/ImagesFrame.hx
Normal file
51
src/haxe/ru/m/puzzlez/view/ImagesFrame.hx
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package ru.m.puzzlez.view;
|
||||||
|
|
||||||
|
import haxework.view.data.DataView;
|
||||||
|
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.storage.ImageStorage;
|
||||||
|
|
||||||
|
@:template class ImagesFrame extends FrameView<Array<ImageSource>> {
|
||||||
|
public static var ID = "images";
|
||||||
|
|
||||||
|
@:view var images:DataView<ImageSource, ImageView>;
|
||||||
|
@:provide var imageStorage:ImageStorage;
|
||||||
|
@:provide var switcher:FrameSwitcher;
|
||||||
|
|
||||||
|
public function new() {
|
||||||
|
super(ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function onShow(data:Array<ImageSource>):Void {
|
||||||
|
if (data != null) {
|
||||||
|
images.data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function onHide():Void {
|
||||||
|
//images.data = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function imageViewFactory(index:Int, image:ImageSource):ImageView {
|
||||||
|
var result = new ImageView();
|
||||||
|
result.style = "view";
|
||||||
|
result.stretch = false;
|
||||||
|
result.fillType = FillType.COVER;
|
||||||
|
result.setSize(192, 128);
|
||||||
|
result.image = Assets.getBitmapData("resources/icon.png");
|
||||||
|
imageStorage.resolve(image, true).then(function(image) result.image = image);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function start(image:ImageSource):Void {
|
||||||
|
switcher.change(GameFrame.ID, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function back():Void {
|
||||||
|
switcher.change(StartFrame.ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/haxe/ru/m/puzzlez/view/ImagesFrame.yaml
Normal file
20
src/haxe/ru/m/puzzlez/view/ImagesFrame.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
style: frame
|
||||||
|
views:
|
||||||
|
- id: images
|
||||||
|
$type: haxework.view.data.DataView
|
||||||
|
layout:
|
||||||
|
$type: haxework.view.layout.TailLayout
|
||||||
|
margin: 5
|
||||||
|
vAlign: middle
|
||||||
|
geometry.stretch: true
|
||||||
|
factory: ~imageViewFactory
|
||||||
|
+onDataSelect: ~start
|
||||||
|
geometry.margin: 5
|
||||||
|
overflow.y: scroll
|
||||||
|
- $type: haxework.view.form.ButtonView
|
||||||
|
text: Back
|
||||||
|
geometry.position: absolute
|
||||||
|
geometry.hAlign: right
|
||||||
|
geometry.vAlign: top
|
||||||
|
+onPress: ~back()
|
||||||
@@ -1,66 +1,33 @@
|
|||||||
package ru.m.puzzlez.view;
|
package ru.m.puzzlez.view;
|
||||||
|
|
||||||
import haxework.view.data.DataView;
|
import flash.events.KeyboardEvent;
|
||||||
import haxework.view.form.ButtonView;
|
import flash.ui.Keyboard;
|
||||||
|
import haxework.resources.IResources;
|
||||||
|
import haxework.view.frame.FrameSwitcher;
|
||||||
import haxework.view.group.VGroupView;
|
import haxework.view.group.VGroupView;
|
||||||
import haxework.view.ImageView;
|
|
||||||
import haxework.view.utils.DrawUtil;
|
|
||||||
import openfl.utils.Assets;
|
|
||||||
import ru.m.puzzlez.core.Game;
|
|
||||||
import ru.m.puzzlez.core.GameUtil;
|
|
||||||
import ru.m.puzzlez.core.IGame;
|
|
||||||
import ru.m.puzzlez.core.ImageSource;
|
|
||||||
import ru.m.puzzlez.render.IRender;
|
|
||||||
import ru.m.puzzlez.storage.AssetStorage;
|
|
||||||
import ru.m.puzzlez.storage.ImageStorage;
|
|
||||||
import ru.m.puzzlez.storage.PixabayStorage;
|
|
||||||
|
|
||||||
@:template class PuzzlezAppView extends VGroupView {
|
@:template class PuzzlezAppView extends VGroupView {
|
||||||
|
|
||||||
@:view private var images:DataView<ImageSource, ImageView>;
|
@:view("switcher") var switcherView:FrameSwitcher;
|
||||||
@:view private var render:IRender;
|
@:provide var switcher:FrameSwitcher;
|
||||||
private var game:IGame;
|
@:provide var resources:IResources;
|
||||||
|
|
||||||
@:provide var imageStorage:ImageStorage;
|
|
||||||
@:provide var assetStorage:AssetStorage;
|
|
||||||
@:provide var pixabayStorage:PixabayStorage;
|
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
assetStorage.resolve().then(function(data) images.data = data);
|
Const.init();
|
||||||
|
resources.text.put("version", Const.VERSION);
|
||||||
|
resources.text.put("name", Const.NAME);
|
||||||
|
switcher = switcherView;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function imageViewFactory(index:Int, image:ImageSource):ImageView {
|
public function launch():Void {
|
||||||
var result = new ImageView();
|
content.stage.stageFocusRect = false;
|
||||||
result.style = "view";
|
switcher.change(StartFrame.ID);
|
||||||
result.stretch = false;
|
stage.addEventListener(KeyboardEvent.KEY_DOWN, function(event:KeyboardEvent) {
|
||||||
result.fillType = FillType.COVER;
|
switch event.keyCode {
|
||||||
result.setSize(192, 128);
|
case Keyboard.ESCAPE:
|
||||||
result.image = Assets.getBitmapData("resources/icon.png");
|
switcher.change(StartFrame.ID);
|
||||||
imageStorage.resolve(image).then(function(image) result.image = image);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function moreImages(view:ButtonView):Void {
|
|
||||||
view.visible = false;
|
|
||||||
view.toUpdateParent();
|
|
||||||
pixabayStorage.resolve("nature").then(function(data) images.data = images.data.concat(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function start(image:ImageSource):Void {
|
|
||||||
stop();
|
|
||||||
game = new Game(GameUtil.buildPreset(image));
|
|
||||||
game.signal.connect(render.onGameEvent);
|
|
||||||
render.signal.connect(game.signal.emit);
|
|
||||||
game.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stop():Void {
|
|
||||||
if (game != null) {
|
|
||||||
render.signal.disconnect(game.signal.emit);
|
|
||||||
game.stop();
|
|
||||||
game.dispose();
|
|
||||||
game = null;
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,10 @@
|
|||||||
style: background
|
---
|
||||||
layout.hAlign: center
|
|
||||||
layout.vAlign: middle
|
|
||||||
views:
|
views:
|
||||||
- $type: haxework.view.group.HGroupView
|
- $type: haxework.view.frame.FrameSwitcher
|
||||||
|
id: switcher
|
||||||
geometry.stretch: true
|
geometry.stretch: true
|
||||||
geometry.margin: 5
|
style: dark
|
||||||
views:
|
factory:
|
||||||
- $type: haxework.view.group.VGroupView
|
_start_: {$class: ru.m.puzzlez.view.StartFrame}
|
||||||
geometry.height: 100%
|
_images_: {$class: ru.m.puzzlez.view.ImagesFrame}
|
||||||
layout.hAlign: center
|
_game_: {$class: ru.m.puzzlez.view.GameFrame}
|
||||||
views:
|
|
||||||
- $type: haxework.view.form.LabelView
|
|
||||||
text: Puzzle'z
|
|
||||||
font.size: 42
|
|
||||||
- $type: haxework.view.form.ButtonView
|
|
||||||
text: Shuffle
|
|
||||||
+onPress: ~game.shuffle()
|
|
||||||
- id: images
|
|
||||||
$type: haxework.view.data.DataView
|
|
||||||
layout:
|
|
||||||
$type: haxework.view.layout.VerticalLayout
|
|
||||||
margin: 5
|
|
||||||
geometry.height: 100%
|
|
||||||
factory: ~imageViewFactory
|
|
||||||
+onDataSelect: ~start
|
|
||||||
geometry.margin: 5
|
|
||||||
overflow.y: scroll
|
|
||||||
- $type: haxework.view.form.ButtonView
|
|
||||||
text: More
|
|
||||||
+onPress: ~moreImages
|
|
||||||
- $type: haxework.view.group.GroupView
|
|
||||||
style: frame
|
|
||||||
geometry.width: 100%
|
|
||||||
geometry.height: 100%
|
|
||||||
overflow.x: crop
|
|
||||||
overflow.y: crop
|
|
||||||
views:
|
|
||||||
- id: render
|
|
||||||
$type: ru.m.puzzlez.render.Render
|
|
||||||
geometry.width: 100%
|
|
||||||
geometry.height: 100%
|
|
||||||
|
|||||||
48
src/haxe/ru/m/puzzlez/view/StartFrame.hx
Normal file
48
src/haxe/ru/m/puzzlez/view/StartFrame.hx
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
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 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<T> = {
|
||||||
|
var storage:ISourceStorage<T>;
|
||||||
|
@:optional var type:T;
|
||||||
|
}
|
||||||
|
|
||||||
|
@:template class StartFrame extends FrameView<Dynamic> {
|
||||||
|
public static var ID = "start";
|
||||||
|
|
||||||
|
@:view var sources:DataView<Source<Dynamic>, ButtonView>;
|
||||||
|
@:provide var assetStorage:AssetStorage;
|
||||||
|
@:provide var pixabayStorage:PixabayStorage;
|
||||||
|
@:provide var switcher:FrameSwitcher;
|
||||||
|
|
||||||
|
public function new() {
|
||||||
|
super(ID);
|
||||||
|
var data:Array<Source<Dynamic>> = [];
|
||||||
|
data.push({storage: assetStorage});
|
||||||
|
for (type in AbstractEnumTools.getValues(PixabayCategory)) {
|
||||||
|
data.push({storage: pixabayStorage, type: type});
|
||||||
|
}
|
||||||
|
sources.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function sourceViewFactory(index:Int, source:Source<Dynamic>):ButtonView {
|
||||||
|
var result = new ButtonView();
|
||||||
|
result.text = Std.string(source.type != null ? source.type : "custom");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function load(source:Source<Dynamic>):Void {
|
||||||
|
source.storage.resolve(source.type).then(onLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onLoaded(result:Array<ImageSource>):Void {
|
||||||
|
switcher.change(ImagesFrame.ID, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/haxe/ru/m/puzzlez/view/StartFrame.yaml
Normal file
19
src/haxe/ru/m/puzzlez/view/StartFrame.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
style: frame
|
||||||
|
views:
|
||||||
|
- $type: haxework.view.form.LabelView
|
||||||
|
text: $r:text:name
|
||||||
|
geometry.margin.top: 15
|
||||||
|
geometry.hAlign: center
|
||||||
|
font.size: 40
|
||||||
|
- id: sources
|
||||||
|
$type: haxework.view.data.DataView
|
||||||
|
layout:
|
||||||
|
$type: haxework.view.layout.TailLayout
|
||||||
|
margin: 10
|
||||||
|
vAlign: middle
|
||||||
|
geometry.stretch: true
|
||||||
|
factory: ~sourceViewFactory
|
||||||
|
+onDataSelect: ~load
|
||||||
|
geometry.margin: 5
|
||||||
|
overflow.y: scroll
|
||||||
Reference in New Issue
Block a user