agt 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +65 -0
- data/app/assets/javascripts/agt/geom/range.coffee +26 -0
- data/app/assets/javascripts/agt/geom/rectangle.coffee +11 -4
- data/app/assets/javascripts/agt/i18n/i18n.coffee +53 -0
- data/app/assets/javascripts/agt/mixins/emitter.coffee +42 -0
- data/app/assets/javascripts/agt/mixins/subscriber.coffee +69 -0
- data/app/assets/javascripts/agt/net/router.coffee +6 -2
- data/app/assets/javascripts/agt/scenes/camera.coffee +85 -0
- data/app/assets/javascripts/agt/signal.coffee +2 -0
- data/app/assets/javascripts/agt/sprites/renderer.coffee +8 -0
- data/app/assets/javascripts/agt/widgets/widgets/form.coffee +28 -0
- data/app/assets/javascripts/agt/widgets/widgets.coffee +14 -14
- data/lib/agt/version.rb +1 -1
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 907efa700bf068d2d6143df8bd544ccb06bbb7e1
|
4
|
+
data.tar.gz: 1379aee9576449ae0096a86819aec4abcd3233ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dfa83250404df0ab969df7aad87e044802ce05a025f1572aca7972071c085aaaa279c43bf80cb30a3b5c95817d6881e40c1d7611eebfc852e0b11b9eee2ae226
|
7
|
+
data.tar.gz: 021341fda32e429e14dc4b378868bee6d5c2a8ec2f556b9239d1674ea396c517a417a3321a1ddcaef5e7701135700b07d288e396decab1304f3681f1fcbe215c
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
<a name="v0.0.3"></a>
|
2
|
+
# v0.0.3 (2014-08-28)
|
3
|
+
|
4
|
+
## :sparkles: Features
|
5
|
+
|
6
|
+
- Add center method on Camera ([1be71190](https://github.com/abe33/agt.git/commit/1be71190ed757bd44e768d11b694fbc88d55a282))
|
7
|
+
- Add zooming ability on Camera ([bb6f2557](https://github.com/abe33/agt.git/commit/bb6f2557b51793a49d66c95428ef3b99a258453b))
|
8
|
+
- Add Range methods ([9b745644](https://github.com/abe33/agt.git/commit/9b74564445451a7aaaf7d994f60291d9be0dc648))
|
9
|
+
- Add batch update method on camera ([0cbce1c7](https://github.com/abe33/agt.git/commit/0cbce1c7bf1ed05e3ff91df5144584fd34982ae6))
|
10
|
+
- Add a Subscriber mixin for events listening objects ([a6c7dedc](https://github.com/abe33/agt.git/commit/a6c7dedcfb13696768a9b28f36afe6434db0a7fb))
|
11
|
+
- Add an Emitter mixin for events dispatching ([04273aa7](https://github.com/abe33/agt.git/commit/04273aa7f89ed5fb7c1da33662fb8196d77545fa))
|
12
|
+
- Add a `changed` signal to the Camera class ([abb01665](https://github.com/abe33/agt.git/commit/abb0166543af9c66771b797b5cc7af0e10e61fc5))
|
13
|
+
- Add I18n class ([b8a68e7e](https://github.com/abe33/agt.git/commit/b8a68e7ef7d828f3d188e72454a03d5335af30bb))
|
14
|
+
- Add draft of a form widget ([97a04b27](https://github.com/abe33/agt.git/commit/97a04b27a83843281592589ac42f9e5b76667e74))
|
15
|
+
- Add a camera class ([f5a354f2](https://github.com/abe33/agt.git/commit/f5a354f2891f5c05209afbbd59b4ee40800e49da))
|
16
|
+
- Add a dummy renderer class ([4892e0de](https://github.com/abe33/agt.git/commit/4892e0de46e76dc1d69c15b457c87707ed2d4fd2))
|
17
|
+
- Add a process helper based on spawn instead of exec ([90c5c37b](https://github.com/abe33/agt.git/commit/90c5c37ba02e0226afc08884e18692a86f7a0533))
|
18
|
+
- Add a basic Range class ([d2911a99](https://github.com/abe33/agt.git/commit/d2911a99563a772023012e742739460786509ceb))
|
19
|
+
- Add a first demo file with a specific task to compile assets ([04f86f25](https://github.com/abe33/agt.git/commit/04f86f257cb93574eb6796d06b0fad57d7015343))
|
20
|
+
|
21
|
+
<a name="v0.0.2"></a>
|
22
|
+
# v0.0.2 (2014-08-20)
|
23
|
+
|
24
|
+
## :bug: Bug Fixes
|
25
|
+
|
26
|
+
- Fix invalid affectation of namespace function ([07765a32](https://github.com/abe33/agt.git/commit/07765a3252f343e3d26a2c921a69c1b7b7767391))
|
27
|
+
|
28
|
+
<a name="v0.0.1"></a>
|
29
|
+
# v0.0.1 (2014-08-20)
|
30
|
+
|
31
|
+
## :sparkles: Features
|
32
|
+
|
33
|
+
- Add gemification tasks to prepare, build and publish a gem ([5410fa41](https://github.com/abe33/agt.git/commit/5410fa411ef3ab702c0df3b11a7fc8a082acaaed))
|
34
|
+
- Add gemify task stub ([27d1a97b](https://github.com/abe33/agt.git/commit/27d1a97b81934db93fc35b14134828577dd780b1))
|
35
|
+
- Add sprite and animation classes ([1aa9040e](https://github.com/abe33/agt.git/commit/1aa9040ee77931008362a30bd23ef8bd5ad3209a))
|
36
|
+
- Add a namespace helper ([79bc9fe8](https://github.com/abe33/agt.git/commit/79bc9fe8e85b1b861f54fa7fa3da1acecfc6fb18)) <br>It initializes the namespaces and ensure that namespaces
|
37
|
+
exists, reducing the amount of namespaces created in the index.
|
38
|
+
- Add past tense inflections ([8071b818](https://github.com/abe33/agt.git/commit/8071b8189932d17ec8bd4bb97e0ec580db1c9954))
|
39
|
+
- Add string inflections with plural/singular support ([bf5ca15c](https://github.com/abe33/agt.git/commit/bf5ca15cf1e2ff5cd4b84a278c24500606ff1766))
|
40
|
+
- Add StateMachine mixin ([14298101](https://github.com/abe33/agt.git/commit/142981016649677cbf91876d54e5e7782249ae99))
|
41
|
+
- Add tests for widgets activation ([d5929ef8](https://github.com/abe33/agt.git/commit/d5929ef86d4466b76900bc2233e34597dbb4f2e4))
|
42
|
+
- Add live reload script in spec runner ([4bce009e](https://github.com/abe33/agt.git/commit/4bce009e3547050266443d4bd294c304fd6db589))
|
43
|
+
- Add an after each hook to reset the widgets and avoid pollution ([e1193a6b](https://github.com/abe33/agt.git/commit/e1193a6b5b4045ab3541079e5ad310826ebced92))
|
44
|
+
- Add a fixture helper for browser specs ([0ad6664c](https://github.com/abe33/agt.git/commit/0ad6664c870f1644bf8aa9066556f0feaf76ddf1))
|
45
|
+
- Add a default widget instance when calling block ([3fb300f2](https://github.com/abe33/agt.git/commit/3fb300f2ae93e65f21764dd59f9e780434bcbbde)) <br>This widget instance is both activable and disposable.
|
46
|
+
This will allow several things:
|
47
|
+
- The block can freely defines hook for activable/disposable methods
|
48
|
+
- Being sure that we have an instance stored in the hash that match the
|
49
|
+
widget interface we doesn’t have to test everything when calling a
|
50
|
+
method on it.
|
51
|
+
- The block have a real object to store data in.
|
52
|
+
- Add watcher for package.json to trigger npm install on changes ([98e711f2](https://github.com/abe33/agt.git/commit/98e711f269199f14d0ccf42e708740fc9895d720))
|
53
|
+
- Implement a new build allowing to access individual classes ([5f48cbc7](https://github.com/abe33/agt.git/commit/5f48cbc7ac7ce188743ce47019d6ba568a02e18d)) <br>The previous generated `lib` now appears in `build`, the `lib`
|
54
|
+
directory now host the compiled files on a 1-1 basis.
|
55
|
+
- Add some basic widgets ([d55bc7cd](https://github.com/abe33/agt.git/commit/d55bc7cd6139aa3e85fd92b375599137e43bb77d))
|
56
|
+
- Implement splats for activation/deactivation/release methods ([fe162b09](https://github.com/abe33/agt.git/commit/fe162b09b353f86ce9ff05593074e37083ad053b))
|
57
|
+
- Add widgets classes and include it in build ([fe58b3a1](https://github.com/abe33/agt.git/commit/fe58b3a1c036a0de24635004ca2dedcbd7e71110))
|
58
|
+
- Add LICENSE file ([c798b147](https://github.com/abe33/agt.git/commit/c798b147ac6e6f19b59e0d359c6a643522ae49eb))
|
59
|
+
- Add Promise and Router classes ([6852bee8](https://github.com/abe33/agt.git/commit/6852bee8310e4c809c532cc7769361bc6e481cd4))
|
60
|
+
- Add more example generator functions ([55fe65c1](https://github.com/abe33/agt.git/commit/55fe65c189f2ef0d15edbde2d3607253438192ed))
|
61
|
+
- Add demos compilation and minimap markers ([0c26e501](https://github.com/abe33/agt.git/commit/0c26e501b1272568923883c93b12d038dfe87ce4))
|
62
|
+
|
63
|
+
## :bug: Bug Fixes
|
64
|
+
|
65
|
+
- Fix route when history API isn't available ([3b1861df](https://github.com/abe33/agt.git/commit/3b1861df019279b564decc09e337e225ca1fbed7))
|
@@ -0,0 +1,26 @@
|
|
1
|
+
namespace('agt.geom')
|
2
|
+
|
3
|
+
class agt.geom.Range
|
4
|
+
properties = ['min','max']
|
5
|
+
|
6
|
+
@include agt.mixins.Cloneable()
|
7
|
+
@include agt.mixins.Equatable(properties...)
|
8
|
+
@include agt.mixins.Formattable(['Range'].concat(properties)...)
|
9
|
+
@include agt.mixins.Sourcable(['agt.geom.Range'].concat(properties)...)
|
10
|
+
@include agt.mixins.Parameterizable('rangeFrom', {
|
11
|
+
min: -Infinity
|
12
|
+
max: Infinity
|
13
|
+
})
|
14
|
+
|
15
|
+
constructor: (min=-Infinity, max=Infinity) ->
|
16
|
+
{@min, @max} = @rangeFrom(min, max)
|
17
|
+
|
18
|
+
surround: (value) -> @min <= value <= @max
|
19
|
+
|
20
|
+
middle: -> @min + (@max - @min) / 2
|
21
|
+
|
22
|
+
overlap: (range) -> @max > range.min and range.max > @min
|
23
|
+
|
24
|
+
inside: (range) -> @max > range.max and @min < range.min
|
25
|
+
|
26
|
+
size: -> @max - @min
|
@@ -161,8 +161,12 @@ class agt.geom.Rectangle
|
|
161
161
|
# <script>drawGeometryEdge(exampleKey, 'topLeft', 'topEdge')</script>
|
162
162
|
#
|
163
163
|
# Returns a [Point]{agt.geom.Point}.
|
164
|
-
topEdge: ->
|
165
|
-
|
164
|
+
topEdge: ->
|
165
|
+
if @rotation is 0
|
166
|
+
new agt.geom.Point @width, 0
|
167
|
+
else
|
168
|
+
new agt.geom.Point @width * Math.cos(@rotation),
|
169
|
+
@width * Math.sin(@rotation)
|
166
170
|
|
167
171
|
# Returns the rectangle's left edge vector.
|
168
172
|
#
|
@@ -170,8 +174,11 @@ class agt.geom.Rectangle
|
|
170
174
|
#
|
171
175
|
# Returns a [Point]{agt.geom.Point}.
|
172
176
|
leftEdge: ->
|
173
|
-
|
174
|
-
|
177
|
+
if @rotation is 0
|
178
|
+
new agt.geom.Point 0, @height
|
179
|
+
else
|
180
|
+
new agt.geom.Point @height * Math.cos(@rotation + Math.PI / 2),
|
181
|
+
@height * Math.sin(@rotation + Math.PI / 2)
|
175
182
|
|
176
183
|
# Returns the rectangle's bottom edge vector.
|
177
184
|
#
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Public
|
2
|
+
class window.I18n
|
3
|
+
### Public ###
|
4
|
+
|
5
|
+
constructor: (@locales={}, @defaultLanguage='en') ->
|
6
|
+
@languages = (k for k of @locales).sort()
|
7
|
+
|
8
|
+
# Returns a string from the locales.
|
9
|
+
# That function can be called either with or without a language:
|
10
|
+
#
|
11
|
+
# i18n.get (path.to.string')
|
12
|
+
# i18n.get ('fr', 'path.to.string')
|
13
|
+
#
|
14
|
+
# If the path lead to a dead end, the function return the last element
|
15
|
+
# in the path as a capitalized sentence.
|
16
|
+
#
|
17
|
+
# i18n.get (path.that.do_not_exist) # Do Not Exist
|
18
|
+
get: (language, path) ->
|
19
|
+
[language, path] = [@defaultLanguage, language] unless path?
|
20
|
+
lang = @locales[language]
|
21
|
+
|
22
|
+
throw new Error "Language #{language} not found" unless lang?
|
23
|
+
els = path.split('.')
|
24
|
+
(lang = lang[v]; break unless lang?) for v in els
|
25
|
+
|
26
|
+
unless lang?
|
27
|
+
lang = els[-1..][0].replace(/[-_]/g, ' ')
|
28
|
+
.replace(/(^|\s)(\w)/g, (m,sp,s) ->
|
29
|
+
"#{sp}#{s.toUpperCase()}")
|
30
|
+
|
31
|
+
lang
|
32
|
+
|
33
|
+
# Returns a helper function bound to the current instance that allow
|
34
|
+
# to retrieve localized string from the `I18n` instance as well as doing
|
35
|
+
# token substitution in the returned string.
|
36
|
+
#
|
37
|
+
# ```coffee
|
38
|
+
# _ = i18n.getHelper()
|
39
|
+
# _('path.to.string')
|
40
|
+
# _('path.to.string_with_token', token: 'token substitute')
|
41
|
+
# ```
|
42
|
+
getHelper: -> (path, tokens={}) =>
|
43
|
+
@get(path).replace /\#\{([^\}]+)\}/g, (token, key) ->
|
44
|
+
return token unless tokens[key]?
|
45
|
+
tokens[key]
|
46
|
+
|
47
|
+
if window? and document?
|
48
|
+
document.addEventListener 'load', f = ->
|
49
|
+
instance = new I18n locales, $('html').attr('lang') or 'en'
|
50
|
+
window.t = instance.getHelper()
|
51
|
+
document.removeEventListener 'load', f
|
52
|
+
|
53
|
+
String::t = -> window.t(this)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
namespace('agt.mixins')
|
2
|
+
|
3
|
+
class agt.mixins.Emitter
|
4
|
+
|
5
|
+
dispatch: (event, data) ->
|
6
|
+
@listeners?[event]?.forEach (listener) -> listener(data)
|
7
|
+
|
8
|
+
on: (event, options={}, listener) ->
|
9
|
+
[listener, options] = [options, {}] if typeof options is 'function'
|
10
|
+
@listeners ?= {}
|
11
|
+
@listeners[event] ?= []
|
12
|
+
|
13
|
+
@listeners[event].push(listener) unless listener in @listeners[event]
|
14
|
+
off: => @off(event, options, listener)
|
15
|
+
|
16
|
+
once: (event, options={}, listener) ->
|
17
|
+
[listener, options] = [options, {}] if typeof options is 'function'
|
18
|
+
|
19
|
+
subscription = @on event, options, (data) =>
|
20
|
+
listener(data)
|
21
|
+
subscription.off()
|
22
|
+
|
23
|
+
off: (event, options={}, listener) ->
|
24
|
+
[listener, options] = [options, {}] if typeof options is 'function'
|
25
|
+
|
26
|
+
if event?
|
27
|
+
if listener?
|
28
|
+
if @listeners?[event]? and listener in @listeners[event]
|
29
|
+
@listeners[event].splice(@listeners[event].indexOf(listener))
|
30
|
+
else
|
31
|
+
@listeners[event] = []
|
32
|
+
else
|
33
|
+
@listeners = {}
|
34
|
+
|
35
|
+
hasListeners: (event) ->
|
36
|
+
if event?
|
37
|
+
@listeners?[event].length > 0
|
38
|
+
else
|
39
|
+
if @listeners?
|
40
|
+
Object.keys(@listeners).some (event) => @hasListeners(event)
|
41
|
+
else
|
42
|
+
false
|
@@ -0,0 +1,69 @@
|
|
1
|
+
namespace('agt.mixins')
|
2
|
+
|
3
|
+
class agt.mixins.Subscriber
|
4
|
+
subscribe: (emitter, event, options={}, listener) ->
|
5
|
+
[listener, options] = [options, {}] if typeof options is 'function'
|
6
|
+
|
7
|
+
@subscripions ?= {}
|
8
|
+
@subscripions[event] ?= []
|
9
|
+
|
10
|
+
subscription = emitter.on(event, options, listener)
|
11
|
+
subscription.emitter = emitter
|
12
|
+
subscription.listener = listener
|
13
|
+
subscription.event = event
|
14
|
+
|
15
|
+
@subscripions[event].push(subscription)
|
16
|
+
subscription
|
17
|
+
|
18
|
+
unsubscribe: (emitter, event, options={}, listener) ->
|
19
|
+
[listener, options] = [options, {}] if typeof options is 'function'
|
20
|
+
|
21
|
+
if emitter?
|
22
|
+
if event?
|
23
|
+
if listener?
|
24
|
+
@filterSubscriptions event, (subscription) =>
|
25
|
+
match = subscription.listener is listener and
|
26
|
+
subscription.emitter is emitter
|
27
|
+
subscription.off() if match
|
28
|
+
not match
|
29
|
+
|
30
|
+
else
|
31
|
+
@filterSubscriptions event, (subscription) =>
|
32
|
+
match = subscription.emitter is emitter
|
33
|
+
subscription.off() if match
|
34
|
+
not match
|
35
|
+
|
36
|
+
else
|
37
|
+
@filterSubscriptions (subscription) =>
|
38
|
+
match = subscription.emitter is emitter
|
39
|
+
subscription.off() if match
|
40
|
+
not match
|
41
|
+
|
42
|
+
else
|
43
|
+
@filterSubscriptions (subscription) =>
|
44
|
+
subscription.off()
|
45
|
+
true
|
46
|
+
|
47
|
+
|
48
|
+
filterSubscriptions: (event, block) ->
|
49
|
+
[block, event] = [event, null] if typeof event is 'function'
|
50
|
+
|
51
|
+
if event? and @subscripions[event]?
|
52
|
+
newSubscriptions = []
|
53
|
+
|
54
|
+
for subscription in @subscripions[event]
|
55
|
+
unless block(subscription)
|
56
|
+
newSubscriptions.push(subscription)
|
57
|
+
|
58
|
+
@subscripions[event] = newSubscriptions
|
59
|
+
|
60
|
+
else unless event?
|
61
|
+
newSubscriptions = {}
|
62
|
+
|
63
|
+
for event, subscripions of @subscripions
|
64
|
+
for subscription in subscripions
|
65
|
+
unless block(subscription)
|
66
|
+
newSubscriptions[event] ?= []
|
67
|
+
newSubscriptions[event].push(subscription)
|
68
|
+
|
69
|
+
@subscripions = newSubscriptions
|
@@ -104,14 +104,15 @@ class agt.net.Router
|
|
104
104
|
|
105
105
|
handler = @findRoute(path)
|
106
106
|
|
107
|
-
@beforeFilters.forEach (filter) => filter(path, this)
|
108
107
|
|
109
108
|
if handler?
|
110
109
|
handler(path)
|
111
110
|
else
|
111
|
+
@beforeFilters.forEach (filter) => filter({path}, this)
|
112
112
|
@notFoundHandle?({path})
|
113
|
+
@afterFilters.forEach (filter) => filter({path}, this)
|
114
|
+
|
113
115
|
|
114
|
-
@afterFilters.forEach (filter) => filter(path, this)
|
115
116
|
|
116
117
|
document.dispatchEvent agt.domEvent('route:changed', {path}) if document?
|
117
118
|
|
@@ -150,6 +151,7 @@ class agt.net.Router
|
|
150
151
|
pathRe.push part
|
151
152
|
|
152
153
|
re = new RegExp('^/' + pathRe.join('/') + '$')
|
154
|
+
self = this
|
153
155
|
|
154
156
|
{
|
155
157
|
options
|
@@ -161,5 +163,7 @@ class agt.net.Router
|
|
161
163
|
for pname,i in pathParams
|
162
164
|
params[pname] = decodeURI(res[i+1])
|
163
165
|
|
166
|
+
self.beforeFilters.forEach (filter) => filter(params, self)
|
164
167
|
handle(params)
|
168
|
+
self.afterFilters.forEach (filter) => filter(params, self)
|
165
169
|
}
|
@@ -0,0 +1,85 @@
|
|
1
|
+
namespace('agt.scenes')
|
2
|
+
|
3
|
+
{Rectangle, Range} = agt.geom
|
4
|
+
|
5
|
+
class agt.scenes.Camera
|
6
|
+
@include agt.mixins.Emitter
|
7
|
+
|
8
|
+
constructor: (@screen=new Rectangle(0, 0,
|
9
|
+
window.innerWidth, window.innerHeight),
|
10
|
+
@_zoom=1,
|
11
|
+
@zoomRange=new Range(-Infinity, Infinity),
|
12
|
+
@silent=false) ->
|
13
|
+
@_width = @screen.width
|
14
|
+
@_height = @screen.height
|
15
|
+
|
16
|
+
|
17
|
+
@accessor 'x',
|
18
|
+
get: -> @screen.center().x
|
19
|
+
set: (value) ->
|
20
|
+
return if value is @x
|
21
|
+
@screen.setCenter(value, @y)
|
22
|
+
@fireCameraChange()
|
23
|
+
|
24
|
+
@accessor 'y',
|
25
|
+
get: -> @screen.center().y
|
26
|
+
set: (value) ->
|
27
|
+
return if value is @y
|
28
|
+
@screen.setCenter(@x, value)
|
29
|
+
@fireCameraChange()
|
30
|
+
|
31
|
+
@accessor 'width',
|
32
|
+
get: -> @_width
|
33
|
+
set: (value) ->
|
34
|
+
return if value is @_width
|
35
|
+
@_width = value
|
36
|
+
@updateZoom()
|
37
|
+
|
38
|
+
@accessor 'height',
|
39
|
+
get: -> @_height
|
40
|
+
set: (value) ->
|
41
|
+
return if value is @_height
|
42
|
+
@_height = value
|
43
|
+
@updateZoom()
|
44
|
+
|
45
|
+
@accessor 'rotation',
|
46
|
+
get: -> @screen.rotation
|
47
|
+
set: (value) ->
|
48
|
+
@screen.rotateAroundCenter(rotation - @screen.rotation)
|
49
|
+
@fireCameraChange()
|
50
|
+
|
51
|
+
@accessor 'zoom',
|
52
|
+
get: -> @_zoom
|
53
|
+
set: (value) ->
|
54
|
+
if @zoomRange.surround(value)
|
55
|
+
@_zoom = value
|
56
|
+
@updateZoom()
|
57
|
+
|
58
|
+
center: (x,y) ->
|
59
|
+
{x,y} = agt.geom.Point.pointFrom(x,y)
|
60
|
+
|
61
|
+
x = @x unless x?
|
62
|
+
y = @y unless y?
|
63
|
+
|
64
|
+
if x isnt @x or y isnt @y
|
65
|
+
@screen.setCenter(x, y)
|
66
|
+
@fireCameraChange()
|
67
|
+
|
68
|
+
update: (props={}) ->
|
69
|
+
@inBatch = true
|
70
|
+
changed = false
|
71
|
+
for key, value of props
|
72
|
+
@[key] = value
|
73
|
+
changed ||= true
|
74
|
+
|
75
|
+
@dispatch('changed', this) if changed
|
76
|
+
@inBatch = false
|
77
|
+
|
78
|
+
updateZoom: ->
|
79
|
+
center = @screen.center()
|
80
|
+
@screen.width = @_width * @_zoom
|
81
|
+
@screen.height = @_height * @_zoom
|
82
|
+
@screen.setCenter(center)
|
83
|
+
@fireCameraChange()
|
84
|
+
|
85
|
+
fireCameraChange: -> @dispatch('changed', this) unless @inBatch
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
agt.widgets.define 'form', (form, options={}) ->
|
3
|
+
formAction = form.getAttribute('data-action')
|
4
|
+
|
5
|
+
unless options[formAction]?
|
6
|
+
throw new Error "Can't find action for `#{formAction}`"
|
7
|
+
|
8
|
+
queryFields = '''
|
9
|
+
input:not([type=submit]):not([type=reset]),
|
10
|
+
textarea,
|
11
|
+
select
|
12
|
+
'''
|
13
|
+
queryActions = 'input[type=submit], input[type=reset], button, a'
|
14
|
+
|
15
|
+
fields = document.querySelectorAll(queryFields)
|
16
|
+
actions = document.querySelectorAll(queryActions)
|
17
|
+
|
18
|
+
Array::forEaxch.call fields, (field) ->
|
19
|
+
# TODO create a field object for each input
|
20
|
+
|
21
|
+
Array::forEach.call actions, (trigger) ->
|
22
|
+
action = trigger.getAttribute('type') ? trigger.getAttribute('value')
|
23
|
+
|
24
|
+
trigger.addEventListener 'click', (e) ->
|
25
|
+
e.preventDefault()
|
26
|
+
e.stopPropagation()
|
27
|
+
|
28
|
+
options[formAction](form, action)
|
@@ -13,7 +13,7 @@ __subscriptions__ = {}
|
|
13
13
|
|
14
14
|
# The `widgets` function is both the main module and the function
|
15
15
|
# used to register the widgets to apply on a page.
|
16
|
-
|
16
|
+
agt.widgets = (name, selector, options={}, block) ->
|
17
17
|
unless __widgets__[name]?
|
18
18
|
throw new Error "Unable to find widget '#{name}'"
|
19
19
|
|
@@ -118,9 +118,9 @@ widgets = agt.widgets = (name, selector, options={}, block) ->
|
|
118
118
|
switch event
|
119
119
|
when 'init' then handler()
|
120
120
|
when 'load', 'resize'
|
121
|
-
widgets.subscribe name, window, event, handler
|
121
|
+
agt.widgets.subscribe name, window, event, handler
|
122
122
|
else
|
123
|
-
widgets.subscribe name, document, event, handler
|
123
|
+
agt.widgets.subscribe name, document, event, handler
|
124
124
|
|
125
125
|
# The `widgets.define` is used to create a new widget usable through the
|
126
126
|
# `widgets` method. Basically, a widget is defined using a `name`, and a
|
@@ -133,10 +133,10 @@ widgets = agt.widgets = (name, selector, options={}, block) ->
|
|
133
133
|
#
|
134
134
|
# The `options` object will contains all the options passed to the `widgets`
|
135
135
|
# method except the `on`, `if`, `unless` and `media` ones.
|
136
|
-
widgets.define = (name, block) -> __widgets__[name] = block
|
136
|
+
agt.widgets.define = (name, block) -> __widgets__[name] = block
|
137
137
|
|
138
138
|
# A shorthand method to register a jQuery widget.
|
139
|
-
widgets.$define = (name, baseOptions={}, block) ->
|
139
|
+
agt.widgets.$define = (name, baseOptions={}, block) ->
|
140
140
|
[baseOptions, block] = [{}, baseOptions] if typeof baseOptions is 'function'
|
141
141
|
throw new Error "#{name} jquery widget isn't defined" unless $.fn[name]
|
142
142
|
__widgets__[name] = (element, options={}) ->
|
@@ -144,22 +144,22 @@ widgets.$define = (name, baseOptions={}, block) ->
|
|
144
144
|
res = $(element)[name](options)
|
145
145
|
block?(res, options)
|
146
146
|
|
147
|
-
widgets.delete = (name) ->
|
147
|
+
agt.widgets.delete = (name) ->
|
148
148
|
__subscriptions__[name]?.forEach (subscription) -> subscription.off()
|
149
|
-
widgets.release(name)
|
149
|
+
agt.widgets.release(name)
|
150
150
|
delete __widgets__[name]
|
151
151
|
|
152
|
-
widgets.reset = (names...) ->
|
152
|
+
agt.widgets.reset = (names...) ->
|
153
153
|
names = Object.keys(__instances__) if names.length is 0
|
154
|
-
widgets.delete(name) for name in names
|
154
|
+
agt.widgets.delete(name) for name in names
|
155
155
|
|
156
|
-
widgets.widgetsFor = (element, widget) ->
|
156
|
+
agt.widgets.widgetsFor = (element, widget) ->
|
157
157
|
if widget?
|
158
158
|
__instances__[widget].get(element)
|
159
159
|
else
|
160
160
|
instances.get(element) for instances in __instances__ when instances.hasKey(element)
|
161
161
|
|
162
|
-
widgets.subscribe = (name, to, evt, handler) ->
|
162
|
+
agt.widgets.subscribe = (name, to, evt, handler) ->
|
163
163
|
__subscriptions__[name] ||= []
|
164
164
|
to.addEventListener(evt, handler)
|
165
165
|
subscription = off: -> to.removeEventListener(evt, handler)
|
@@ -170,19 +170,19 @@ widgets.subscribe = (name, to, evt, handler) ->
|
|
170
170
|
# of the given `name` from the page.
|
171
171
|
# It's the widget responsibility to clean up its dependencies during
|
172
172
|
# the `dispose` call.
|
173
|
-
widgets.release = (names...) ->
|
173
|
+
agt.widgets.release = (names...) ->
|
174
174
|
names = Object.keys(__instances__) if names.length is 0
|
175
175
|
for name in names
|
176
176
|
__instances__[name].each (value) -> value.dispose()
|
177
177
|
|
178
178
|
# Activates all the widgets instances of type `name`.
|
179
|
-
widgets.activate = (names...) ->
|
179
|
+
agt.widgets.activate = (names...) ->
|
180
180
|
names = Object.keys(__instances__) if names.length is 0
|
181
181
|
for name in names
|
182
182
|
__instances__[name].each (value) -> value.activate()
|
183
183
|
|
184
184
|
# Deactivates all the widgets instances of type `name`.
|
185
|
-
widgets.deactivate = (names...) ->
|
185
|
+
agt.widgets.deactivate = (names...) ->
|
186
186
|
names = Object.keys(__instances__) if names.length is 0
|
187
187
|
for name in names
|
188
188
|
__instances__[name].each (value) -> value.deactivate()
|
data/lib/agt/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: agt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cédric Néhémie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -67,10 +67,12 @@ files:
|
|
67
67
|
- app/assets/javascripts/agt/geom/polygon.coffee
|
68
68
|
- app/assets/javascripts/agt/geom/quad_bezier.coffee
|
69
69
|
- app/assets/javascripts/agt/geom/quint_bezier.coffee
|
70
|
+
- app/assets/javascripts/agt/geom/range.coffee
|
70
71
|
- app/assets/javascripts/agt/geom/rectangle.coffee
|
71
72
|
- app/assets/javascripts/agt/geom/spiral.coffee
|
72
73
|
- app/assets/javascripts/agt/geom/transformation_proxy.coffee
|
73
74
|
- app/assets/javascripts/agt/geom/triangle.coffee
|
75
|
+
- app/assets/javascripts/agt/i18n/i18n.coffee
|
74
76
|
- app/assets/javascripts/agt/impulse.coffee
|
75
77
|
- app/assets/javascripts/agt/index.coffee
|
76
78
|
- app/assets/javascripts/agt/inflector/inflection.coffee
|
@@ -84,6 +86,7 @@ files:
|
|
84
86
|
- app/assets/javascripts/agt/mixins/cloneable.coffee
|
85
87
|
- app/assets/javascripts/agt/mixins/delegation.coffee
|
86
88
|
- app/assets/javascripts/agt/mixins/disposable.coffee
|
89
|
+
- app/assets/javascripts/agt/mixins/emitter.coffee
|
87
90
|
- app/assets/javascripts/agt/mixins/equatable.coffee
|
88
91
|
- app/assets/javascripts/agt/mixins/formattable.coffee
|
89
92
|
- app/assets/javascripts/agt/mixins/globalizable.coffee
|
@@ -95,6 +98,7 @@ files:
|
|
95
98
|
- app/assets/javascripts/agt/mixins/poolable.coffee
|
96
99
|
- app/assets/javascripts/agt/mixins/sourcable.coffee
|
97
100
|
- app/assets/javascripts/agt/mixins/state_machine.coffee
|
101
|
+
- app/assets/javascripts/agt/mixins/subscriber.coffee
|
98
102
|
- app/assets/javascripts/agt/net/router.coffee
|
99
103
|
- app/assets/javascripts/agt/object.coffee
|
100
104
|
- app/assets/javascripts/agt/particles/actions/base_action.coffee
|
@@ -137,13 +141,17 @@ files:
|
|
137
141
|
- app/assets/javascripts/agt/random/seeds/mersenne_twister.coffee
|
138
142
|
- app/assets/javascripts/agt/random/seeds/no_random.coffee
|
139
143
|
- app/assets/javascripts/agt/random/seeds/paul_houle.coffee
|
144
|
+
- app/assets/javascripts/agt/scenes/camera.coffee
|
140
145
|
- app/assets/javascripts/agt/signal.coffee
|
141
146
|
- app/assets/javascripts/agt/sprites/animation.coffee
|
147
|
+
- app/assets/javascripts/agt/sprites/renderer.coffee
|
142
148
|
- app/assets/javascripts/agt/sprites/sprite.coffee
|
143
149
|
- app/assets/javascripts/agt/widgets/hash.coffee
|
144
150
|
- app/assets/javascripts/agt/widgets/widgets/checked_input.coffee
|
145
151
|
- app/assets/javascripts/agt/widgets/widgets/focus_bubbling.coffee
|
152
|
+
- app/assets/javascripts/agt/widgets/widgets/form.coffee
|
146
153
|
- app/assets/javascripts/agt/widgets/widgets.coffee
|
154
|
+
- CHANGELOG.md
|
147
155
|
- LICENSE.md
|
148
156
|
- README.md
|
149
157
|
homepage: https://github.com/abe33/agt.git
|