[update] :-)
This commit is contained in:
@@ -4,11 +4,13 @@ import haxework.color.Color;
|
||||
import haxework.view.geometry.Box;
|
||||
import haxework.view.geometry.SizeValue;
|
||||
import haxework.view.theme.Theme;
|
||||
import openfl.Assets;
|
||||
import ru.m.skin.ButtonSVGSkin;
|
||||
|
||||
class PuzzlezTheme extends Theme {
|
||||
|
||||
public function new() {
|
||||
super({name: "Georgia"}, {light: "gray"}, {base: 22});
|
||||
super({embed: true}, {light: "gray"}, {base: 22});
|
||||
data.get("frame").data.set("geometry.padding", Box.fromFloat(8));
|
||||
register(new Style("view", [
|
||||
"skin.background.color" => colors.light,
|
||||
@@ -20,5 +22,24 @@ class PuzzlezTheme extends Theme {
|
||||
register(new Style("text.error", [
|
||||
"font.color" => Color.fromString("red"),
|
||||
], "text"));
|
||||
registerButton("close", "times-circle-solid.svg", false, 0xcc5500);
|
||||
}
|
||||
|
||||
private function registerButton(name:String, resource:String, solid:Bool = false, color:Color = null):Void {
|
||||
if (color == null) {
|
||||
color = colors.light;
|
||||
}
|
||||
var size = 42;
|
||||
var smallSize = 32;
|
||||
register(new Style('button.$name', [
|
||||
"geometry.width" => SizeValue.fromInt(size),
|
||||
"geometry.height" => SizeValue.fromInt(size),
|
||||
"skin" => function() return new ButtonSVGSkin(Assets.getText('resources/image/icon/$resource'), color, solid),
|
||||
]));
|
||||
register(new Style('button.$name.small', [
|
||||
"geometry.width" => SizeValue.fromInt(smallSize),
|
||||
"geometry.height" => SizeValue.fromInt(smallSize),
|
||||
"skin" => function() return new ButtonSVGSkin(Assets.getText('resources/image/icon/$resource'), color, solid),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package ru.m.puzzlez.source;
|
||||
import flash.display.BitmapData;
|
||||
import flash.net.SharedObject;
|
||||
import haxe.crypto.Md5;
|
||||
import haxe.DynamicAccess;
|
||||
import haxe.io.Bytes;
|
||||
import promhx.Promise;
|
||||
import ru.m.puzzlez.core.Id;
|
||||
@@ -50,7 +51,8 @@ class FileSource implements IImageSource<Dynamic> {
|
||||
var fileData = SharedObject.getLocal(id);
|
||||
fileData.clear();
|
||||
fileData.flush();
|
||||
Reflect.deleteField(listData.data, id);
|
||||
var access:DynamicAccess<String> = listData.data;
|
||||
access.remove(id);
|
||||
listData.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package ru.m.puzzlez.source;
|
||||
package ru.m.puzzlez.storage;
|
||||
|
||||
import haxework.storage.SharedObjectStorage;
|
||||
import ru.m.puzzlez.core.GameState;
|
||||
@@ -7,7 +7,7 @@ import ru.m.puzzlez.core.GameEvent;
|
||||
import ru.m.puzzlez.core.GameState;
|
||||
import ru.m.puzzlez.core.IGame;
|
||||
import ru.m.puzzlez.render.IRender;
|
||||
import ru.m.puzzlez.source.GameStorage;
|
||||
import ru.m.puzzlez.storage.GameStorage;
|
||||
|
||||
@:template class GameFrame extends FrameView<GameState> {
|
||||
public static var ID = "game";
|
||||
|
||||
@@ -3,15 +3,16 @@ package ru.m.puzzlez.view;
|
||||
import haxework.view.data.DataView;
|
||||
import haxework.view.frame.FrameSwitcher;
|
||||
import haxework.view.frame.FrameView;
|
||||
import ru.m.puzzlez.core.GameState;
|
||||
import ru.m.puzzlez.source.GameStorage;
|
||||
import haxework.view.popup.ConfirmView;
|
||||
import ru.m.puzzlez.core.Id.ImageId;
|
||||
import ru.m.puzzlez.storage.GameStorage;
|
||||
import ru.m.puzzlez.view.PuzzleImageView;
|
||||
|
||||
@:template class GameListFrame extends FrameView<Dynamic> {
|
||||
|
||||
public static var ID(default, never) = "game_list";
|
||||
|
||||
@:view var images:ActionDataView<GameState, PuzzleImageView, Action>;
|
||||
@:view var images:ActionDataView<ImageId, PuzzleImageView, Action>;
|
||||
|
||||
@:provide var switcher:FrameSwitcher;
|
||||
@:provide var storage:GameStorage;
|
||||
@@ -21,18 +22,22 @@ import ru.m.puzzlez.view.PuzzleImageView;
|
||||
}
|
||||
|
||||
override public function onShow(data:Dynamic):Void {
|
||||
images.data = storage.list();
|
||||
images.data = storage.listIds();
|
||||
}
|
||||
|
||||
private function start(state:GameState):Void {
|
||||
switcher.change(GameFrame.ID, state);
|
||||
private function start(id:ImageId):Void {
|
||||
switcher.change(GameFrame.ID, storage.read(id));
|
||||
}
|
||||
|
||||
private function onAction(state:GameState, action:Action):Void {
|
||||
private function onAction(id:ImageId, action:Action):Void {
|
||||
switch action {
|
||||
case CLOSE:
|
||||
storage.delete(state.preset.imageId);
|
||||
images.data = storage.list();
|
||||
case REMOVE:
|
||||
ConfirmView.confirm("Delete?").then(function(result) {
|
||||
if (result) {
|
||||
storage.delete(id);
|
||||
images.data = storage.listIds();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ views:
|
||||
margin: 5
|
||||
vAlign: middle
|
||||
geometry.stretch: true
|
||||
factory: ~ru.m.puzzlez.view.PuzzleImageView.stateFactory
|
||||
factory: ~ru.m.puzzlez.view.PuzzleImageView.factory
|
||||
+onDataSelect: ~start
|
||||
+onDataAction: ~onAction
|
||||
geometry.margin: 5
|
||||
|
||||
@@ -4,17 +4,21 @@ import haxework.view.data.DataView;
|
||||
import haxework.view.form.ButtonView;
|
||||
import haxework.view.frame.FrameSwitcher;
|
||||
import haxework.view.frame.FrameView;
|
||||
import haxework.view.popup.ConfirmView;
|
||||
import ru.m.puzzlez.core.Id;
|
||||
import ru.m.puzzlez.FileUtil;
|
||||
import ru.m.puzzlez.source.FileSource;
|
||||
import ru.m.puzzlez.storage.GameStorage;
|
||||
import ru.m.puzzlez.storage.ImageStorage;
|
||||
import ru.m.puzzlez.view.PuzzleImageView;
|
||||
|
||||
@:template class ImageListFrame extends FrameView<ImageListSource<Dynamic>> {
|
||||
public static var ID = "image_list";
|
||||
|
||||
@:view var images:DataView<ImageId, PuzzleImageView>;
|
||||
@:view var images:ActionDataView<ImageId, PuzzleImageView, Action>;
|
||||
@:view var select:ButtonView;
|
||||
@:provide var imageStorage:ImageStorage;
|
||||
@:provide var gameStorage:GameStorage;
|
||||
@:provide var switcher:FrameSwitcher;
|
||||
|
||||
private var source:ImageListSource<Dynamic>;
|
||||
@@ -47,8 +51,28 @@ import ru.m.puzzlez.storage.ImageStorage;
|
||||
});
|
||||
}
|
||||
|
||||
private function start(image:ImageId):Void {
|
||||
switcher.change(PresetFrame.ID, image);
|
||||
private function onAction(imageId:ImageId, action:Action):Void {
|
||||
switch action {
|
||||
case REMOVE:
|
||||
var fileSource:FileSource = Std.instance(source.source, FileSource);
|
||||
if (fileSource != null) {
|
||||
ConfirmView.confirm("Delete?").then(function(result) {
|
||||
if (result) {
|
||||
fileSource.remove(imageId);
|
||||
loading.promise = fileSource.getList().then(function(result) images.data = result);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function start(imageId:ImageId):Void {
|
||||
var state = gameStorage.read(imageId);
|
||||
if (state != null) {
|
||||
switcher.change(GameFrame.ID, state);
|
||||
} else {
|
||||
switcher.change(PresetFrame.ID, imageId);
|
||||
}
|
||||
}
|
||||
|
||||
private function back():Void {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
style: frame
|
||||
views:
|
||||
- id: images
|
||||
$type: haxework.view.data.DataView
|
||||
$type: haxework.view.data.ActionDataView
|
||||
layout:
|
||||
$type: haxework.view.layout.TailLayout
|
||||
margin: 5
|
||||
@@ -10,6 +10,7 @@ views:
|
||||
geometry.stretch: true
|
||||
factory: ~ru.m.puzzlez.view.PuzzleImageView.factory
|
||||
+onDataSelect: ~start
|
||||
+onDataAction: ~onAction
|
||||
geometry.margin: 5
|
||||
overflow.y: scroll
|
||||
- id: select
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package ru.m.puzzlez.view;
|
||||
|
||||
import haxework.view.data.DataView.ActionDataView;
|
||||
import haxework.view.data.DataView;
|
||||
import haxework.view.form.ButtonView;
|
||||
import haxework.view.form.LabelView;
|
||||
import haxework.view.group.GroupView;
|
||||
import haxework.view.ImageView;
|
||||
import ru.m.puzzlez.core.GameState;
|
||||
import ru.m.puzzlez.core.GameUtil;
|
||||
import ru.m.puzzlez.core.Id;
|
||||
import ru.m.puzzlez.storage.GameStorage;
|
||||
import ru.m.puzzlez.storage.ImageStorage;
|
||||
|
||||
enum Action {
|
||||
CLOSE;
|
||||
REMOVE;
|
||||
}
|
||||
|
||||
@:template class PuzzleImageView extends GroupView {
|
||||
@@ -37,7 +38,9 @@ enum Action {
|
||||
|
||||
@:view("image") var imageView:ImageView;
|
||||
@:view("label") var labelView:LabelView;
|
||||
@:provide var imageStorage:ImageStorage;
|
||||
@:view("remove") var removeButton:ButtonView;
|
||||
@:provide static var imageStorage:ImageStorage;
|
||||
@:provide static var gameStorage:GameStorage;
|
||||
private var loading:LoadingWrapper;
|
||||
|
||||
public function new() {
|
||||
@@ -45,25 +48,22 @@ enum Action {
|
||||
loading = new LoadingWrapper(this);
|
||||
}
|
||||
|
||||
private function close():Void {
|
||||
private function emit(action:Action):Void {
|
||||
var dataView:ActionDataView<Dynamic, PuzzleImageView, Action> = Std.instance(parent, ActionDataView);
|
||||
if (dataView != null) {
|
||||
var index = dataView.dataViews.indexOf(this);
|
||||
dataView.onDataAction.emit(dataView.data[index], CLOSE);
|
||||
dataView.onDataAction.emit(dataView.data[index], action);
|
||||
}
|
||||
}
|
||||
|
||||
public static function factory(index:Int, imageId:ImageId):PuzzleImageView {
|
||||
var result = new PuzzleImageView();
|
||||
result.imageId = imageId;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static function stateFactory(index:Int, state:GameState):PuzzleImageView {
|
||||
var result = new PuzzleImageView();
|
||||
result.imageId = state.preset.imageId;
|
||||
var progress = GameUtil.calcProgress(state);
|
||||
result.text = '${progress.complete}/${progress.total}';
|
||||
var state = gameStorage.read(imageId);
|
||||
if (state != null) {
|
||||
var progress = GameUtil.calcProgress(state);
|
||||
result.text = '${progress.complete}/${progress.total}';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ views:
|
||||
fillType: COVER
|
||||
- id: label
|
||||
$type: haxework.view.form.LabelView
|
||||
- id: close
|
||||
- id: remove
|
||||
$type: haxework.view.form.ButtonView
|
||||
propagation: false
|
||||
geometry.hAlign: right
|
||||
text: X
|
||||
+onPress: ~close()
|
||||
style: button.close.small
|
||||
+onPress: ~emit(Action.REMOVE)
|
||||
|
||||
56
src/haxe/ru/m/skin/ButtonSVGSkin.hx
Normal file
56
src/haxe/ru/m/skin/ButtonSVGSkin.hx
Normal file
@@ -0,0 +1,56 @@
|
||||
package ru.m.skin;
|
||||
|
||||
import format.SVG;
|
||||
import haxework.color.Color;
|
||||
import haxework.view.form.ButtonView;
|
||||
import haxework.view.skin.ISkin;
|
||||
|
||||
using StringTools;
|
||||
using haxework.color.ColorUtil;
|
||||
|
||||
@:style class ButtonSVGSkin implements ISkin<ButtonView> {
|
||||
|
||||
@:style(null) public var svg:String;
|
||||
@:style(0) public var color:Null<Color>;
|
||||
@:style(false) public var solid:Null<Bool>;
|
||||
|
||||
private var svgs:Map<ButtonState, SVG>;
|
||||
|
||||
public function new(?svg:String, ?color:Color, ?solid:Bool) {
|
||||
this.svg = svg;
|
||||
this.color = color;
|
||||
this.solid = solid;
|
||||
init(solid);
|
||||
}
|
||||
|
||||
private inline function buildSVG(color:Color):SVG {
|
||||
return new SVG(svg.replace("currentColor", '#${color}'));
|
||||
}
|
||||
|
||||
private function init(solid:Bool):Void {
|
||||
var color = color;
|
||||
if (solid) {
|
||||
color = color.multiply(1.5);
|
||||
}
|
||||
svgs = new Map();
|
||||
svgs.set(UP, buildSVG(color));
|
||||
svgs.set(DOWN, buildSVG(color.diff(-24)));
|
||||
svgs.set(OVER, buildSVG(color.diff(24)));
|
||||
svgs.set(DISABLED, buildSVG(color.grey()));
|
||||
}
|
||||
|
||||
public function draw(view:ButtonView):Void {
|
||||
var svg = svgs.get(view.state);
|
||||
var graphics = view.content.graphics;
|
||||
graphics.beginFill(0, 0);
|
||||
graphics.drawRect(0, 0, view.width, view.height);
|
||||
graphics.beginFill(color);
|
||||
if (!solid) {
|
||||
graphics.lineStyle(2, color.multiply(1.5));
|
||||
}
|
||||
// ToDo: padding
|
||||
svg.render(graphics, 0, 0, Std.int(view.width * 0.8), Std.int(view.height * 0.8));
|
||||
graphics.lineStyle();
|
||||
graphics.endFill();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user