[refactoring] add GameListFrame

This commit is contained in:
2020-09-26 16:20:38 +03:00
parent 5e22d45d01
commit e6a11efe64
16 changed files with 139 additions and 123 deletions

View File

@@ -8,7 +8,6 @@ import ru.m.puzzlez.render.part.IPartBuilder;
import ru.m.puzzlez.settings.Settings;
import ru.m.puzzlez.source.AssetImageSource;
import ru.m.puzzlez.source.FileImageSource;
import ru.m.puzzlez.source.GameImageSource;
import ru.m.puzzlez.source.PixabayImageSource;
import ru.m.puzzlez.storage.GameStorage;
import ru.m.puzzlez.view.PuzzlezAppView;
@@ -27,7 +26,6 @@ class PuzzlezApp {
sourceBundle.register(new AssetImageSource());
sourceBundle.register(new FileImageSource());
sourceBundle.register(new PixabayImageSource());
sourceBundle.register(new GameImageSource());
L.push(new TraceLogger());
updater = new Updater(Const.instance.VERSION, "https://shmyga.ru/repo/puzzlez/packages.json");
var app = new App();

View File

@@ -1,24 +0,0 @@
package ru.m.puzzlez.source;
import ru.m.puzzlez.proto.game.ImageId;
import promhx.Promise;
import ru.m.data.DataSource;
import ru.m.puzzlez.image.ImageSource;
import ru.m.puzzlez.storage.GameStorage;
class GameImageSource implements ImageSource {
public var id(default, never):String = "game";
@:provide private var storage:GameStorage;
public function new() {
}
public function getPage(page:Page):Promise<DataPage<ImageId>> {
return storage.getIndexPage(page);
}
public function load(id:String):Promise<ImageValue> {
throw "Unsupported";
}
}

View File

@@ -0,0 +1,46 @@
package ru.m.puzzlez.view;
import hw.view.frame.FrameSwitcher;
import ru.m.puzzlez.view.common.GameStateView;
import ru.m.view.DataList;
import hw.view.form.LabelView;
import ru.m.puzzlez.proto.game.GameState;
import ru.m.data.DataSource;
import ru.m.data.DataSource.Filter;
import hw.view.frame.FrameView;
typedef GameListConfig = {
var title:String;
var source:DataSource<GameState>;
@:optional var filter:Filter;
}
@:template class GameListFrame extends FrameView<GameListConfig> {
public static var ID(default, never) = "game_list";
@:view var header:LabelView;
@:view var games:DataList<GameState, GameStateView>;
@:provide var switcher:FrameSwitcher;
public function new() {
super(ID);
}
override public function onShow(data:GameListConfig):Void {
games.reset();
if (data != null) {
header.text = data.title;
games.page.filter = data.filter;
games.source = data.source;
games.refresh();
}
}
public function start(state:GameState):Void {
switcher.change(GameFrame.ID, state);
}
private function back():Void {
switcher.change(StartFrame.ID);
}
}

View File

@@ -0,0 +1,17 @@
---
style: frame
views:
- id: header
$type: hw.view.form.LabelView
style: label.header
- id: games
$type: ru.m.view.DataList
geometry.stretch: true
list.factory: ~ru.m.puzzlez.view.common.GameStateView.factory
+list.onDataSelect: ~start
- $type: hw.view.form.ButtonView
text: Back
geometry.position: absolute
geometry.hAlign: right
geometry.vAlign: top
+onPress: ~back()

View File

@@ -2,7 +2,6 @@ package ru.m.puzzlez.view;
import ru.m.puzzlez.view.common.ImageIdView;
import ru.m.view.DataList;
import ru.m.puzzlez.storage.GameStorage;
import hw.view.form.LabelView;
import hw.view.frame.FrameSwitcher;
import hw.view.frame.FrameView;
@@ -10,26 +9,25 @@ import ru.m.data.DataSource;
import ru.m.puzzlez.image.ImageSourceBundle;
import ru.m.puzzlez.proto.game.ImageId;
typedef ImageSourceConfig = {
typedef ImageListConfig = {
var title:String;
var sourceId:String;
@:optional var filter:Filter;
}
@:template class ImageSourceFrame extends FrameView<ImageSourceConfig> {
public static var ID = "source";
@:template class ImageListFrame extends FrameView<ImageListConfig> {
public static var ID = "image_list";
@:view var header:LabelView;
@:view var images:DataList<ImageId, ImageIdView>;
@:provide var switcher:FrameSwitcher;
@:provide var sourceBundle:ImageSourceBundle;
@:provide var gameStorage:GameStorage;
public function new() {
super(ID);
}
override public function onShow(data:ImageSourceConfig):Void {
override public function onShow(data:ImageListConfig):Void {
images.reset();
if (data != null) {
header.text = data.title;
@@ -40,13 +38,7 @@ typedef ImageSourceConfig = {
}
private function start(imageId:ImageId):Void {
gameStorage.get(imageId).then(state -> {
if (state != null) {
switcher.change(GameFrame.ID, state);
} else {
switcher.change(PresetFrame.ID, imageId);
}
});
switcher.change(PresetFrame.ID, imageId);
}
private function back():Void {

View File

@@ -61,6 +61,6 @@ import ru.m.puzzlez.view.common.PresetView;
}
private function back():Void {
switcher.change(ImageSourceFrame.ID);
switcher.change(ImageListFrame.ID);
}
}

View File

@@ -6,8 +6,9 @@ views:
style: dark
factory:
_start_: {$class: ru.m.puzzlez.view.StartFrame}
_source_: {$class: ru.m.puzzlez.view.ImageSourceFrame}
_image_list_: {$class: ru.m.puzzlez.view.ImageListFrame}
_preset_: {$class: ru.m.puzzlez.view.PresetFrame}
_game_list_: {$class: ru.m.puzzlez.view.GameListFrame}
_game_: {$class: ru.m.puzzlez.view.GameFrame}
- $type: hw.view.group.HGroupView
geometry.position: absolute

View File

@@ -9,13 +9,14 @@ import ru.m.puzzlez.FileUtil;
import ru.m.puzzlez.proto.game.GameStatus;
import ru.m.puzzlez.storage.FileStorage;
import ru.m.puzzlez.storage.GameStorage;
import ru.m.puzzlez.view.ImageSourceFrame;
import ru.m.puzzlez.view.ImageListFrame;
import ru.m.puzzlez.view.GameListFrame;
import ru.m.update.Updater;
@:template class StartFrame extends FrameView<Dynamic> {
public static var ID = "start";
@:view var sources:DataView<ImageSourceConfig, ButtonView>;
@:view var sources:DataView<ImageListConfig, ButtonView>;
@:view var startedButton:ButtonView;
@:view var completedButton:ButtonView;
@:view var updateButton:ButtonView;
@@ -25,13 +26,13 @@ import ru.m.update.Updater;
@:provide var fileStorage:FileStorage;
@:provide var gameStorage:GameStorage;
private var fileSource:ImageSourceConfig = {title: "Files", sourceId: "file"};
private var startedSource:ImageSourceConfig = {title: "Started", sourceId: "game", filter: ["status" => GameStatus.STARTED]};
private var completedSource:ImageSourceConfig = {title: "Completed", sourceId: "game", filter: ["status" => GameStatus.COMPLETE]};
private var fileSource:ImageListConfig = {title: "Files", sourceId: "file"};
private var startedGames:GameListConfig = {title: "Started", source: gameStorage, filter: ["status" => GameStatus.STARTED]};
private var completedGames:GameListConfig = {title: "Completed", source: gameStorage, filter: ["status" => GameStatus.COMPLETE]};
public function new() {
super(ID);
var data:Array<ImageSourceConfig> = [];
var data:Array<ImageListConfig> = [];
data.push({title: "Assets", sourceId: "asset"});
data.push(fileSource);
for (type in AbstractEnumTools.getValues(PixabayCategory)) {
@@ -40,7 +41,7 @@ import ru.m.update.Updater;
sources.data = data;
}
private function sourceViewFactory(index:Int, source:ImageSourceConfig):ButtonView {
private function sourceViewFactory(index:Int, source:ImageListConfig):ButtonView {
var result = new ButtonView();
result.text = source.title;
return result;
@@ -52,8 +53,12 @@ import ru.m.update.Updater;
.then(_ -> showSource(fileSource));
}
public function showSource(source:ImageSourceConfig):Void {
switcher.change(ImageSourceFrame.ID, source);
public function showSource(config:ImageListConfig):Void {
switcher.change(ImageListFrame.ID, config);
}
public function showGames(config:GameListConfig):Void {
switcher.change(GameListFrame.ID, config);
}
override public function onShow(data:Dynamic):Void {
@@ -67,10 +72,10 @@ import ru.m.update.Updater;
}
private function refresh():Void {
gameStorage.getIndexPage({index:0, count:0, filter:startedSource.filter}).then(response -> {
gameStorage.getIndexPage({index:0, count:0, filter:startedGames.filter}).then(response -> {
startedButton.text = response.total > 0 ? 'Started (${response.total})' : 'Started';
});
gameStorage.getIndexPage({index:0, count:0, filter:completedSource.filter}).then(response -> {
gameStorage.getIndexPage({index:0, count:0, filter:completedGames.filter}).then(response -> {
completedButton.text = response.total > 0 ? 'Completed (${response.total})' : 'Completed';
});
}

View File

@@ -34,11 +34,11 @@ views:
- id: startedButton
$type: hw.view.form.ButtonView
text: Started
+onPress: ~showSource(startedSource)
+onPress: ~showGames(startedGames)
- id: completedButton
$type: hw.view.form.ButtonView
text: Completed
+onPress: ~showSource(completedSource)
+onPress: ~showGames(completedGames)
- $type: hw.view.form.ButtonView
text: Upload
geometry.margin.left: 30

View File

@@ -0,0 +1,34 @@
package ru.m.puzzlez.view.common;
import hw.view.theme.StyleId;
import hw.view.form.LabelView;
import hw.view.group.GroupView;
import ru.m.puzzlez.image.GameUtil;
import ru.m.puzzlez.proto.game.GameState;
@:template class GameStateView extends GroupView {
public var state(default, set):GameState;
private function set_state(value:GameState):GameState {
state = value;
image.imageId = state.preset.image;
var progress = GameUtil.calcProgress(state);
label.text = '${progress.complete}/${progress.total}';
return state;
}
@:view var image:ImageIdView;
@:view var label:LabelView;
public function new(?state:GameState, ?style: StyleId) {
super();
this.style = style;
if (state != null) {
this.state = state;
}
}
public static function factory(index:Int, value:GameState):GameStateView {
return new GameStateView(value, "view");
}
}

View File

@@ -0,0 +1,8 @@
---
views:
- id: image
$type: ru.m.puzzlez.view.common.ImageIdView
geometry.width: 100%
geometry.height: 100%
- id: label
$type: hw.view.form.LabelView

View File

@@ -1,79 +1,34 @@
package ru.m.puzzlez.view.common;
import ru.m.view.LoadingWrapper;
import ru.m.puzzlez.image.GameUtil;
import hw.view.popup.ConfirmView;
import hw.signal.Signal;
import hw.view.form.LabelView;
import hw.view.form.ButtonView;
import hw.view.theme.StyleId;
import hw.view.group.GroupView;
import hw.view.ImageView;
import ru.m.puzzlez.image.ImageData;
import ru.m.puzzlez.proto.game.ImageId;
import ru.m.puzzlez.storage.FileStorage;
import ru.m.puzzlez.storage.GameStorage;
import ru.m.view.LoadingWrapper;
@:template class ImageIdView extends GroupView {
public var imageId(default, set):ImageId;
private function set_imageId(value:ImageId):ImageId {
imageId = value;
labelView.text = "";
cleanButton.visible = false;
removeButton.visible = false;
loading.promise = ImageData.fromImageId(imageId).resolve().then(data -> this.imageView.image = data);
gameStorage.get(imageId).then(state -> {
if (state != null) {
var progress = GameUtil.calcProgress(state);
labelView.text = '${progress.complete}/${progress.total}';
cleanButton.visible = true;
}
});
if (imageId.source == "file") {
fileStorage.get(imageId.id).then(value -> {
if (value != null) {
removeButton.visible = true;
}
});
}
return imageId;
}
@:view("image") var imageView:ImageView;
private var loading:LoadingWrapper;
@:view("label") var labelView:LabelView;
@:view("remove") var removeButton:ButtonView;
@:view("clean") var cleanButton:ButtonView;
@:provide private var fileStorage:FileStorage;
@:provide private var gameStorage:GameStorage;
public var onChange(default, null):Signal<Bool> = new Signal();
public function new(imageId:ImageId = null) {
public function new(?imageId:ImageId, ?style: StyleId) {
super();
this.style = style;
loading = new LoadingWrapper(this);
if (imageId != null) {
this.imageId = imageId;
}
}
private function removeImage():Void {
ConfirmView.confirm("Remove image?").then(result -> {
if (result) {
fileStorage.delete(imageId.id).then(_ -> onChange.emit(true));
}
});
}
private function cleanGame():Void {
ConfirmView.confirm("Remove game?").then(result -> {
if (result) {
gameStorage.delete(imageId).then(_ -> onChange.emit(true));
}
});
}
public static function factory(index:Int, value:ImageId):ImageIdView {
return new ImageIdView(value);
return new ImageIdView(value, "view");
}
}

View File

@@ -1,22 +1,7 @@
---
style: view
views:
- id: image
$type: hw.view.ImageView
geometry.stretch: true
stretch: false
fillType: COVER
- id: label
$type: hw.view.form.LabelView
- id: remove
$type: hw.view.form.ButtonView
visible: false
propagation: false
style: icon.control.small.close.red
+onPress: ~removeImage()
- id: clean
$type: hw.view.form.ButtonView
visible: false
propagation: false
style: icon.control.small.close.orange
+onPress: ~cleanGame()

View File

@@ -26,8 +26,6 @@ import ru.m.view.LoadingWrapper;
public function new() {
super();
trace("list", list);
trace("paginator", paginator);
loading = new LoadingWrapper(list);
page = {index: 0, count: 6, order: [{field: "date", reverse: true}]};
}