Skip to content
This repository was archived by the owner on Nov 25, 2020. It is now read-only.

keyboard: add KeyboardMap and KeyboardListener #40

Merged
merged 2 commits into from
Jun 5, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions src/core/keyboard/listener.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
module.exports = class KDKeyboardListener

constructor: ->
@maps = {}
@isListening = no

makeUpdater = (fn) -> ->
{ isListening } = this
@reset() if isListening
retVal = fn.apply this, arguments
@listen() if isListening
return retVal

addComboMap: makeUpdater (comboMap, priority) ->
m = @maps[priority ? comboMap.priority ? 0] ?= []
m.push comboMap
return this

removeComboMap: makeUpdater (comboMap) ->
for own priority, ms of @maps
@maps[priority] = ms.filter (m) -> m isnt comboMap
return this

listen: ->
return this if @isActive()

KDKeyboardListener.currentListener?.reset()

seen = {}
@combos (combo, options = { global: yes }, listener) ->
return if seen[combo]
seen[combo] = yes
method = if options.global then 'bindGlobal' else 'bind'
Mousetrap[method] combo, listener

KDKeyboardListener.currentListener = this
@isListening = yes
return this

reset: ->
return this unless @isActive()

Mousetrap.reset()
@isListening = no
KDKeyboardListener.currentListener = null
return this

getCombos: ->
Object.keys @maps
# prioritize by key:
.sort (a, b) -> b - a # descending priority
# map back to value:
.map (k) => @maps[k]
# flatten:
.reduce (a, b) ->
a.concat b
, []

combos: (fn) ->
@getCombos().forEach (m) -> m.eachCombo fn
return this

isActive: ->
@isListening and this is KDKeyboardListener.currentListener

@current = ->
return @currentListener if @currentListener?

@currentListener = new this
@currentListener.listen()
return @currentListener
23 changes: 23 additions & 0 deletions src/core/keyboard/map.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = class KDKeyboardMap

constructor: (options) ->
@combos = {}

{ combos, @priority } = options if options?

if combos?
@addCombo combo, null, listener for own combo, listener of combos

addCombo: (combo, options, listener) ->
[listener, options] = [options, listener] unless listener?
@combos[combo] = { listener, options }
return this

removeCombo: (combo) ->
@combos[combo] = null
return this

eachCombo: (fn, thisArg) ->
for own combo, { options, listener } of @combos
fn.call thisArg, combo, options, listener
return
14 changes: 5 additions & 9 deletions src/core/windowcontroller.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -200,17 +200,13 @@ module.exports = class KDWindowController extends KDController
return if Object.keys(combos).length > 0 then combos else no

registerKeyCombos:(view)->

if combos = @viewHasKeyCombos view
view.setClass "mousetrap"
@currentCombos = superizeCombos combos
for own combo, cb of @currentCombos
Mousetrap.bind combo, cb, 'keydown'
combos = @viewHasKeyCombos view
if combos?
@comboMap = new KDKeyboardMap { combos }
KDKeyboardListener.current().addComboMap @comboMap

unregisterKeyCombos:->

@currentCombos = {}
Mousetrap.reset()
KDKeyboardListener.current().removeComboMap @comboMap
@keyView.unsetClass "mousetrap" if @keyView

setKeyView:(keyView)->
Expand Down