agt 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|