NAT flixel playground multiple playground views
This commit is contained in:
@@ -184,6 +184,10 @@ class CompilerTools {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO it's possible that moving .haxelib here would solve
|
||||||
|
// the problem Yvon found, but it's also possible that code
|
||||||
|
// would fail to compile if haxelib dependencies aren't
|
||||||
|
// where they're expected at arbitrary times during compilation
|
||||||
move("package.json", "package.json.temp");
|
move("package.json", "package.json.temp");
|
||||||
move("package-lock.json", "package-lock.json.temp");
|
move("package-lock.json", "package-lock.json.temp");
|
||||||
move("node_modules", "node_modules.temp");
|
move("node_modules", "node_modules.temp");
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package nat;
|
|||||||
import sys.FileSystem;
|
import sys.FileSystem;
|
||||||
import kiss.Prelude;
|
import kiss.Prelude;
|
||||||
import sys.io.File;
|
import sys.io.File;
|
||||||
import tink.Json;
|
|
||||||
import uuid.Uuid;
|
import uuid.Uuid;
|
||||||
|
import haxe.DynamicAccess;
|
||||||
|
|
||||||
using haxe.io.Path;
|
using haxe.io.Path;
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,27 @@
|
|||||||
(FileSystem.createDirectory entryDir)
|
(FileSystem.createDirectory entryDir)
|
||||||
(FileSystem.createDirectory componentDir)
|
(FileSystem.createDirectory componentDir)
|
||||||
(FileSystem.createDirectory filesDir)
|
(FileSystem.createDirectory filesDir)
|
||||||
|
|
||||||
(let [entryFiles (FileSystem.readDirectory entryDir)]
|
(let [entryFiles (FileSystem.readDirectory entryDir)]
|
||||||
(for file entryFiles
|
(for file entryFiles
|
||||||
=>(file.withoutExtension)
|
=>(file.withoutExtension)
|
||||||
(the Entry (Json.parse (File.getContent (joinPath archiveDir "entries" file)))))))])
|
(the Entry (tink.Json.parse (File.getContent (joinPath archiveDir "entries" file)))))))
|
||||||
|
:DynamicAccess<Dynamic> playgrounds
|
||||||
|
(let [playgroundsFile (joinPath archiveDir "playgrounds.json")]
|
||||||
|
(unless (FileSystem.exists playgroundsFile)
|
||||||
|
(File.saveContent playgroundsFile
|
||||||
|
#"{
|
||||||
|
"default": "Playground-MAIN",
|
||||||
|
"Playground-MAIN": {
|
||||||
|
"catsMatch": "true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#))
|
||||||
|
(haxe.Json.parse (File.getContent playgroundsFile)))])
|
||||||
|
|
||||||
|
(method changePlaygrounds [:Dynamic->Void change]
|
||||||
|
(change playgrounds)
|
||||||
|
(File.saveContent (joinPath archiveDir "playgrounds.json") (haxe.Json.stringify playgrounds "\t")))
|
||||||
|
|
||||||
(method addSystem [:System system]
|
(method addSystem [:System system]
|
||||||
// Assign entries to the Systems that care about them
|
// Assign entries to the Systems that care about them
|
||||||
@@ -47,7 +64,7 @@
|
|||||||
(method _saveEntry [:Entry e]
|
(method _saveEntry [:Entry e]
|
||||||
(File.saveContent
|
(File.saveContent
|
||||||
(joinPath archiveDir "entries" (e.id.withExtension "json"))
|
(joinPath archiveDir "entries" (e.id.withExtension "json"))
|
||||||
(Json.stringify e)))
|
(tink.Json.stringify e)))
|
||||||
|
|
||||||
(method fullString [:Entry e]
|
(method fullString [:Entry e]
|
||||||
(haxe.Json.stringify e null "\t"))
|
(haxe.Json.stringify e null "\t"))
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package nat;
|
|||||||
import kiss.Prelude;
|
import kiss.Prelude;
|
||||||
import kiss.List;
|
import kiss.List;
|
||||||
import haxe.Constraints;
|
import haxe.Constraints;
|
||||||
|
import haxe.DynamicAccess;
|
||||||
import uuid.Uuid;
|
import uuid.Uuid;
|
||||||
import nat.systems.*;
|
import nat.systems.*;
|
||||||
|
|
||||||
@@ -22,6 +23,8 @@ enum CommandArgType {
|
|||||||
Entries(min:Null<Int>, max:Null<Int>);
|
Entries(min:Null<Int>, max:Null<Int>);
|
||||||
// TODO Tag -- make sure a tag input is a valid haxe variable name for tagsMatch compatibility
|
// TODO Tag -- make sure a tag input is a valid haxe variable name for tagsMatch compatibility
|
||||||
// TODO VarTag
|
// TODO VarTag
|
||||||
|
|
||||||
|
// TODO playground name -- choose from archive.playgrounds
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef CommandArg = {
|
typedef CommandArg = {
|
||||||
|
|||||||
@@ -146,6 +146,8 @@
|
|||||||
(method getSelectedEntries []
|
(method getSelectedEntries []
|
||||||
(_selectedEntries.copy))
|
(_selectedEntries.copy))
|
||||||
|
|
||||||
|
(prop &mut :PlaygroundSystem playgroundSystem null)
|
||||||
|
|
||||||
(defNew [&prop :Archive archive
|
(defNew [&prop :Archive archive
|
||||||
&prop :ArchiveUI ui]
|
&prop :ArchiveUI ui]
|
||||||
[&mut :Array<Entry> _selectedEntries []
|
[&mut :Array<Entry> _selectedEntries []
|
||||||
@@ -163,14 +165,14 @@
|
|||||||
(archive.addSystem (new KeyShortcutSystem this))
|
(archive.addSystem (new KeyShortcutSystem this))
|
||||||
(archive.addSystem (new DLSystem))
|
(archive.addSystem (new DLSystem))
|
||||||
(whenLet [ps (ui.playgroundSystem)]
|
(whenLet [ps (ui.playgroundSystem)]
|
||||||
|
(set playgroundSystem ps)
|
||||||
(archive.addSystem ps)
|
(archive.addSystem ps)
|
||||||
// TODO allow saving a different default playground
|
(ps.switchPlaygroundKey (dictGet archive.playgrounds "default")))
|
||||||
(ps.switchPlaygroundKey "Playground-MAIN"))
|
|
||||||
|
|
||||||
// Just for testing:
|
// Just for testing:
|
||||||
// (archive.addSystem (new AttachmentSystem ["jpg" "jpeg" "png"] ->[archive e files] ~files))
|
// (archive.addSystem (new AttachmentSystem ["jpg" "jpeg" "png"] ->[archive e files] ~files))
|
||||||
|
|
||||||
(archive.processSystems)
|
(archive.processSystems ui)
|
||||||
|
|
||||||
(defCommand Help []
|
(defCommand Help []
|
||||||
(ui.displayMessage
|
(ui.displayMessage
|
||||||
@@ -261,4 +263,12 @@
|
|||||||
(withWritableComponents archive e [scaleComponent Scale]
|
(withWritableComponents archive e [scaleComponent Scale]
|
||||||
(set scaleComponent scale))
|
(set scaleComponent scale))
|
||||||
(addComponent archive e Scale scale)))
|
(addComponent archive e Scale scale)))
|
||||||
entries))
|
entries)
|
||||||
|
|
||||||
|
(defCommand CreatePlayground [name (Text null) catsMatchExp (Text null)]
|
||||||
|
(archive.changePlaygrounds ->:Void [:DynamicAccess<Dynamic> p]
|
||||||
|
(dictSet p name (object catsMatch catsMatchExp))))
|
||||||
|
|
||||||
|
(defCommand SwitchPlayground [name (Text null)]
|
||||||
|
(archive.changePlaygrounds ->:Void [:DynamicAccess<Dynamic> p] (dictSet p "default" name))
|
||||||
|
(when playgroundSystem (playgroundSystem.switchPlaygroundKey name))))
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
// Changes to the object returned by (readComponent) will not be saved! Use (withWritableComponents) for making changes
|
// Changes to the object returned by (readComponent) will not be saved! Use (withWritableComponents) for making changes
|
||||||
(defMacro readComponent [e componentType]
|
(defMacro readComponent [e componentType]
|
||||||
`(let [componentData (dictGet (the Map<String,String> .components ,e) ,(symbolName componentType))]
|
`(let [componentData (dictGet (the Map<String,String> .components ,e) ,(symbolName componentType))]
|
||||||
(log null (+ "reading " componentData " as " ,(symbolName componentType) " for " .id ,e))
|
// (log null (+ "reading " componentData " as " ,(symbolName componentType) " for " .id ,e))
|
||||||
(the nat.components ,componentType
|
(the nat.components ,componentType
|
||||||
// TODO add to the documentation a hint that macros should use fully qualified type paths so macro caller classes don't need to import everything
|
// TODO add to the documentation a hint that macros should use fully qualified type paths so macro caller classes don't need to import everything
|
||||||
(tink.Json.parse componentData))))
|
(tink.Json.parse componentData))))
|
||||||
|
|||||||
@@ -16,5 +16,3 @@
|
|||||||
(when (entries.exists e.id)
|
(when (entries.exists e.id)
|
||||||
(entries.remove e.id)
|
(entries.remove e.id)
|
||||||
(when onRemoveEntry (onRemoveEntry archive e)))))
|
(when onRemoveEntry (onRemoveEntry archive e)))))
|
||||||
|
|
||||||
// TODO systems may need access to an ArchiveController
|
|
||||||
|
|||||||
@@ -16,9 +16,10 @@
|
|||||||
(addComponent archive e Positions (new Map)))
|
(addComponent archive e Positions (new Map)))
|
||||||
(withWritableComponents archive e [positions Positions]
|
(withWritableComponents archive e [positions Positions]
|
||||||
(when !(positions.exists _playgroundKey)
|
(when !(positions.exists _playgroundKey)
|
||||||
// TODO do a playground check before giving a default position.
|
(if (catsMatch e .catsMatch (dictGet archive.playgrounds _playgroundKey))
|
||||||
(dictSet positions _playgroundKey (defaultPosition e))))
|
(dictSet positions _playgroundKey (defaultPosition e))
|
||||||
(let [pos (dictGet (readComponent e Positions) _playgroundKey)]
|
(return null))))
|
||||||
|
(whenLet [pos (dictGet (readComponent e Positions) _playgroundKey)]
|
||||||
(processor archive e pos ui))
|
(processor archive e pos ui))
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@
|
|||||||
(set _playgroundKey key)
|
(set _playgroundKey key)
|
||||||
(process ui.controller.archive ui))
|
(process ui.controller.archive ui))
|
||||||
|
|
||||||
(method clear [])
|
(method :Void clear [])
|
||||||
|
|
||||||
(method &override :Void process [:Archive archive &opt :ArchiveUI ui]
|
(method &override :Void process [:Archive archive &opt :ArchiveUI ui]
|
||||||
(when _playgroundKey (super.process archive ui)))
|
(when _playgroundKey (super.process archive ui)))
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import kiss.Prelude;
|
|||||||
import kiss.List;
|
import kiss.List;
|
||||||
import flash.display.BitmapData;
|
import flash.display.BitmapData;
|
||||||
import flixel.addons.display.FlxExtendedSprite;
|
import flixel.addons.display.FlxExtendedSprite;
|
||||||
|
import flixel.text.FlxText;
|
||||||
import nat.Entry;
|
import nat.Entry;
|
||||||
import nat.Archive;
|
import nat.Archive;
|
||||||
import nat.ArchiveController;
|
import nat.ArchiveController;
|
||||||
|
|||||||
@@ -7,24 +7,24 @@
|
|||||||
&prop :Entry e
|
&prop :Entry e
|
||||||
&prop :ArchiveController controller]
|
&prop :ArchiveController controller]
|
||||||
[&mut :Bool selected false]
|
[&mut :Bool selected false]
|
||||||
|
(super position.x position.y)
|
||||||
(let [images (readComponent e Images)]
|
(if (hasComponent e Images)
|
||||||
(super position.x position.y)
|
(let [images (readComponent e Images)]
|
||||||
(.onComplete (BitmapData.loadFromFile (joinPath archive.archiveDir "files" (nth images.imageFiles images.pinnedImageIndex)))
|
(.onComplete (BitmapData.loadFromFile (joinPath archive.archiveDir "files" (nth images.imageFiles images.pinnedImageIndex)))
|
||||||
->bitmapData {
|
->bitmapData {
|
||||||
(loadGraphic bitmapData)
|
(loadGraphic bitmapData)
|
||||||
(updateColor)
|
}))
|
||||||
(when (hasComponent e Scale)
|
(set pixels .pixels (new FlxText 0 0 0 (readComponent e Name) 16)))
|
||||||
(let [:Float scale (readComponent e Scale)]
|
(updateColor)
|
||||||
(this.scale.set scale scale)
|
(when (hasComponent e Scale)
|
||||||
(updateHitbox)))
|
(let [:Float scale (readComponent e Scale)]
|
||||||
(enableMouseClicks false)
|
(this.scale.set scale scale)
|
||||||
(enableMouseDrag)
|
(updateHitbox)))
|
||||||
}))
|
(enableMouseClicks false)
|
||||||
|
(enableMouseDrag)
|
||||||
(set mouseStartDragCallback
|
(set mouseStartDragCallback
|
||||||
->[self _dx _dy]
|
->[self _dx _dy]
|
||||||
(doFor sprite ~(system.getSelectedSprites)
|
(doFor sprite (system.getSelectedSprites)
|
||||||
(unless (= sprite.e.id this.e.id)
|
(unless (= sprite.e.id this.e.id)
|
||||||
(sprite.fixToSprite this))))
|
(sprite.fixToSprite this))))
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package;
|
|
||||||
|
|
||||||
import kiss.Prelude;
|
|
||||||
import kiss.List;
|
|
||||||
import nat.Entry;
|
|
||||||
import nat.System;
|
|
||||||
import nat.BoolExpInterp;
|
|
||||||
import nat.ArchiveController;
|
|
||||||
import nat.components.Positions;
|
|
||||||
import flixel.FlxG;
|
|
||||||
|
|
||||||
@:build(kiss.Kiss.build())
|
|
||||||
class EntrySpriteDepthSystem extends System {}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
(loadFrom "nat-archive-tool" "src/nat/Lib.kiss")
|
|
||||||
|
|
||||||
(method z [:Entry e]
|
|
||||||
.z (dictGet (readComponent e Positions) (spriteSystem.getPlaygroundKey)))
|
|
||||||
|
|
||||||
(method :Array<EntrySprite> collectOverlapping [:EntrySprite s &opt :Array<EntrySprite> overlapping]
|
|
||||||
(unless overlapping (set overlapping []))
|
|
||||||
(overlapping.push s)
|
|
||||||
(FlxG.overlap s state.entryGroup
|
|
||||||
->[_ s2]
|
|
||||||
(unless (contains overlapping s2)
|
|
||||||
(collectOverlapping s2 overlapping)))
|
|
||||||
overlapping)
|
|
||||||
|
|
||||||
(defNew [&prop :PlayState state
|
|
||||||
&prop :EntrySpriteSystem spriteSystem]
|
|
||||||
(super
|
|
||||||
->[archive e]
|
|
||||||
?(and
|
|
||||||
(spriteSystem.sprites.exists e.id)
|
|
||||||
!(= 0 (z e)))
|
|
||||||
->[archive e &opt ui]
|
|
||||||
(let [:Array<EntrySprite> inOrder
|
|
||||||
(sortBy
|
|
||||||
(collectOverlapping (dictGet spriteSystem.sprites e.id))
|
|
||||||
->s (- (z s.e)))]
|
|
||||||
// Looping twice avoids having to splice() the group
|
|
||||||
(doFor s inOrder
|
|
||||||
// This will leave null holes
|
|
||||||
(state.entryGroup.remove s))
|
|
||||||
(doFor s inOrder
|
|
||||||
// this will fill the null holes in the right order
|
|
||||||
(state.entryGroup.add s)))))
|
|
||||||
@@ -6,8 +6,13 @@ import nat.System;
|
|||||||
import nat.BoolExpInterp;
|
import nat.BoolExpInterp;
|
||||||
import nat.ArchiveController;
|
import nat.ArchiveController;
|
||||||
import nat.ArchiveUI;
|
import nat.ArchiveUI;
|
||||||
|
import nat.Archive;
|
||||||
|
import nat.Entry;
|
||||||
|
import nat.components.Position;
|
||||||
|
using kiss_flixel.CameraTools;
|
||||||
import nat.components.Positions;
|
import nat.components.Positions;
|
||||||
import nat.systems.PlaygroundSystem;
|
import nat.systems.PlaygroundSystem;
|
||||||
|
import flixel.util.FlxSort;
|
||||||
|
|
||||||
@:build(kiss.Kiss.build())
|
@:build(kiss.Kiss.build())
|
||||||
class EntrySpriteSystem extends PlaygroundSystem {}
|
class EntrySpriteSystem extends PlaygroundSystem {}
|
||||||
|
|||||||
@@ -6,12 +6,12 @@
|
|||||||
// just make the FlxText every time at runtime -- so PinNextImage won't be needed
|
// just make the FlxText every time at runtime -- so PinNextImage won't be needed
|
||||||
// when the media tag is added
|
// when the media tag is added
|
||||||
|
|
||||||
(defNew [:PlayState playState
|
(defNew [&prop :PlayState playState
|
||||||
&prop :ArchiveController controller]
|
&prop :ArchiveController controller]
|
||||||
(super
|
(super
|
||||||
playState
|
playState
|
||||||
->[archive e]
|
->[archive e]
|
||||||
?(hasComponent e Images)
|
?(hasComponent e Name)
|
||||||
->[archive e pos &opt ui]
|
->[archive e pos &opt ui]
|
||||||
(unless (sprites.exists e.id)
|
(unless (sprites.exists e.id)
|
||||||
(let [sprite (new EntrySprite this _playgroundKey pos archive e controller)]
|
(let [sprite (new EntrySprite this _playgroundKey pos archive e controller)]
|
||||||
@@ -27,7 +27,27 @@
|
|||||||
(controller.DeSelectEntry e)
|
(controller.DeSelectEntry e)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// TODO override process to z-sort all sprites after making them
|
(method &override :Void clear []
|
||||||
|
(sprites.clear)
|
||||||
|
(playState.entryGroup.kill)
|
||||||
|
(playState.entryGroup.clear)
|
||||||
|
(playState.entryGroup.revive)
|
||||||
|
(controller.SelectEntries []))
|
||||||
|
|
||||||
|
(method z [:Entry e]
|
||||||
|
.z (dictGet (readComponent e Positions) _playgroundKey))
|
||||||
|
|
||||||
|
// override process to z-sort all sprites after making them
|
||||||
|
(method &override :Void process [:Archive archive &opt :ArchiveUI ui]
|
||||||
|
(super.process archive ui)
|
||||||
|
(FlxG.camera.calculateScrollBounds playState.entryGroup PlayState.SCROLL_BOUND_MARGIN)
|
||||||
|
(playState.entryGroup.sort ->[o s1 s2] (FlxSort.byValues o (z s1.e) (z s2.e))))
|
||||||
|
|
||||||
(method getSelectedSprites []
|
(method getSelectedSprites []
|
||||||
(filter (for e (controller.getSelectedEntries) (dictGet sprites e.id))))
|
(filter (for e (controller.getSelectedEntries) (dictGet sprites e.id))))
|
||||||
|
|
||||||
|
(prop defaultSpacing 100)
|
||||||
|
(prop &mut defaultX 0)
|
||||||
|
(method &override :Position defaultPosition [_]
|
||||||
|
(+= defaultX defaultSpacing)
|
||||||
|
(object x defaultX y 0.0 z 0.0))
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
(method :PlaygroundSystem playgroundSystem []
|
(method :PlaygroundSystem playgroundSystem []
|
||||||
(set spriteSystem (new EntrySpriteSystem this controller)))
|
(set spriteSystem (new EntrySpriteSystem this controller)))
|
||||||
|
|
||||||
|
(prop :KeyShortcutHandler<Entry> shortcutHandler (new FlxKeyShortcutHandler<Entry>))
|
||||||
(method &override :Void create []
|
(method &override :Void create []
|
||||||
(super.create)
|
(super.create)
|
||||||
|
|
||||||
@@ -28,7 +29,6 @@
|
|||||||
archive
|
archive
|
||||||
this)))
|
this)))
|
||||||
|
|
||||||
(prop :KeyShortcutHandler<Entry> shortcutHandler (new FlxKeyShortcutHandler<Entry>))
|
|
||||||
|
|
||||||
(prop &mut :FlxGroup uiGroup (new FlxGroup))
|
(prop &mut :FlxGroup uiGroup (new FlxGroup))
|
||||||
(add uiGroup)
|
(add uiGroup)
|
||||||
@@ -95,14 +95,6 @@
|
|||||||
(when !(= overlaps (controller.isSelected entrySprite.e))
|
(when !(= overlaps (controller.isSelected entrySprite.e))
|
||||||
(controller.ToggleSelectEntry entrySprite.e))))))))
|
(controller.ToggleSelectEntry entrySprite.e))))))))
|
||||||
|
|
||||||
// make text-only sprites for entries that have no images:
|
|
||||||
(archive.addSystem (new TextSpriteSystem))
|
|
||||||
|
|
||||||
(prop &mut :EntrySpriteDepthSystem spriteDepthSystem)
|
|
||||||
(set spriteDepthSystem (new EntrySpriteDepthSystem this spriteSystem))
|
|
||||||
(archive.addSystem spriteDepthSystem)
|
|
||||||
|
|
||||||
(archive.processSystems this)
|
|
||||||
(FlxG.camera.calculateScrollBounds entryGroup SCROLL_BOUND_MARGIN))
|
(FlxG.camera.calculateScrollBounds entryGroup SCROLL_BOUND_MARGIN))
|
||||||
|
|
||||||
(defAlias &ident sh (cast shortcutHandler FlxKeyShortcutHandler<Dynamic>))
|
(defAlias &ident sh (cast shortcutHandler FlxKeyShortcutHandler<Dynamic>))
|
||||||
@@ -112,10 +104,16 @@
|
|||||||
(when sh.currentMap
|
(when sh.currentMap
|
||||||
(sh.update))
|
(sh.update))
|
||||||
|
|
||||||
(spriteDepthSystem.process archive)
|
|
||||||
|
|
||||||
(when FlxG.keys.justPressed.ESCAPE
|
(when FlxG.keys.justPressed.ESCAPE
|
||||||
(Sys.exit 0))
|
(if (and textInput textInput.hasFocus)
|
||||||
|
{
|
||||||
|
(set textInput.callback null)
|
||||||
|
(hideUI textInput)
|
||||||
|
// This part is hacky...
|
||||||
|
(set lastUI textInputLabel)
|
||||||
|
(hideUI textInputLabel)
|
||||||
|
}
|
||||||
|
(Sys.exit 0)))
|
||||||
|
|
||||||
// Press ENTER to type a command to run
|
// Press ENTER to type a command to run
|
||||||
(when (and !textInput FlxG.keys.justPressed.ENTER)
|
(when (and !textInput FlxG.keys.justPressed.ENTER)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
?(and !(hasComponent e Images) (hasComponent e Name))
|
?(and !(hasComponent e Images) (hasComponent e Name))
|
||||||
->[archive e &opt ui]
|
->[archive e &opt ui]
|
||||||
{
|
{
|
||||||
|
// TODO refactor this to kiss-flixel SpriteTools as #if sys savePNG
|
||||||
(let [name (readComponent e Name)
|
(let [name (readComponent e Name)
|
||||||
sprite (new FlxText 0 0 0 name 16)
|
sprite (new FlxText 0 0 0 name 16)
|
||||||
bitmapData sprite.pixels
|
bitmapData sprite.pixels
|
||||||
|
|||||||
Reference in New Issue
Block a user