Skip to content

Commit

Permalink
Merge pull request #4 from bpxl-labs/feature/overrides
Browse files Browse the repository at this point in the history
Feature/overrides
  • Loading branch information
iconmaster authored Jul 31, 2017
2 parents 66ecbfd + a19627d commit e9244ea
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 40 deletions.
77 changes: 43 additions & 34 deletions FocusEngine.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ exports.unfocusStyle =
exports.initialize = (focusableArray) ->
exports.focusable = focusableArray
for layer in exports.focusable
if layer.overrides == undefined
layer.overrides =
up: null
down: null
left: null
right: null
layer.focus = false
styleLayer(layer)

Expand Down Expand Up @@ -181,40 +187,43 @@ exports.changeFocus = Utils.throttle 0.1, (direction) ->
# if we've lost all focus, reset
if exports.focus == null or exports.focus == undefined
exports.placeFocus(exports.initialFocus)
focusMidX = exports.focus.screenFrame.x + exports.focus.screenFrame.width/2
focusMidY = exports.focus.screenFrame.y + exports.focus.screenFrame.height/2
if direction == "up"
for layer in exports.focusable
layerMidY = layer.screenFrame.y + layer.screenFrame.height/2
if layerMidY < focusMidY and checkVisible(layer) == true
tempArray.push(layer)
else if direction == "down"
for layer in exports.focusable
layerMidY = layer.screenFrame.y + layer.screenFrame.height/2
if layerMidY > focusMidY and checkVisible(layer) == true
tempArray.push(layer)
else if direction == "left"
for layer in exports.focusable
layerMidX = layer.screenFrame.x + layer.screenFrame.width/2
if layerMidX < focusMidX and checkVisible(layer) == true
tempArray.push(layer)
else if direction == "right"
for layer in exports.focusable
layerMidX = layer.screenFrame.x + layer.screenFrame.width/2
if layerMidX > focusMidX and checkVisible(layer) == true
tempArray.push(layer)
else if direction == "select"
exports.focus.emit "selected"
if tempArray.length == 0
return
targetLayer = tempArray[0]
shortestDistance = measureDistance(targetLayer, direction)
for layer in tempArray
distance = measureDistance(layer, direction)
if distance < shortestDistance
targetLayer = layer
shortestDistance = distance
exports.placeFocus(targetLayer)
if exports.focus.overrides?[direction] != undefined and exports.focus.overrides?[direction] != null # override
exports.placeFocus(exports.focus.overrides[direction])
else
focusMidX = exports.focus.screenFrame.x + exports.focus.screenFrame.width/2
focusMidY = exports.focus.screenFrame.y + exports.focus.screenFrame.height/2
if direction == "up"
for layer in exports.focusable
layerMidY = layer.screenFrame.y + layer.screenFrame.height/2
if layerMidY < focusMidY and checkVisible(layer) == true
tempArray.push(layer)
else if direction == "down"
for layer in exports.focusable
layerMidY = layer.screenFrame.y + layer.screenFrame.height/2
if layerMidY > focusMidY and checkVisible(layer) == true
tempArray.push(layer)
else if direction == "left"
for layer in exports.focusable
layerMidX = layer.screenFrame.x + layer.screenFrame.width/2
if layerMidX < focusMidX and checkVisible(layer) == true
tempArray.push(layer)
else if direction == "right"
for layer in exports.focusable
layerMidX = layer.screenFrame.x + layer.screenFrame.width/2
if layerMidX > focusMidX and checkVisible(layer) == true
tempArray.push(layer)
else if direction == "select"
exports.focus.emit "selected"
if tempArray.length == 0
return
targetLayer = tempArray[0]
shortestDistance = measureDistance(targetLayer, direction)
for layer in tempArray
distance = measureDistance(layer, direction)
if distance < shortestDistance
targetLayer = layer
shortestDistance = distance
exports.placeFocus(targetLayer)

measureDistance = (target, direction) ->
focusTopCenter =
Expand Down
35 changes: 29 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,6 @@ myRemote = new RemoteLayer
swipeRightAction: -> fe.changeFocus("right")
```

#### Enable debug mode to log focus changes
```coffeescript
fe.debug = true
```

#### Check the currently focused layer
```coffeescript
print fe.focus
Expand All @@ -131,9 +126,37 @@ print fe.focus
print layerA.focus
```

#### Overriding focus logic
Sometimes you will want to change focus in a way that doesn't make exact geometric sense. For example, when switching from a large header row to a smaller secondary row, you may prefer the first cell in the secondary row receive focus. Or, you may want to provide a way for focus to "loop around" at a row's end. These kinds of functions are possible through _overrides._

Set a layer's overrides using the `overrides` object:
```coffeescript
layerA.overrides =
up: <layer>
down: <layer>
left: <layer>
right: <layer>
```

It is not necessary to set all four overrides; but only for those directions which require custom behavior. Now, shifting focus from `layerA` will always land on the direction-specified target -- no matter what FocusEngine thinks should happen.

> Obviously, you can create very unexpected behaviors this way. Use with care!
If a layer has custom overrides, or has been initialized with FocusEngine, you may check any of its current overrides:
```coffeescript
print layerA.overrides?.up
```

The `?` permits the check to fail gracefully on layers which have no overrides.

#### Enable debug mode to log focus changes
```coffeescript
fe.debug = true
```

#### Known issues

Attempting to perform a `placeFocus()` call as FocusEngine is changing its own focus will fail. (The call is discarded.) If you need to override FocusEngine's logic, Use a slight delay to ensure the call is respected.
Attempting to perform a `placeFocus()` call as FocusEngine is changing its own focus will fail. (The call is discarded.) If you need to override FocusEngine's logic, use the `overrides` feature or add a slight delay to ensure the call is respected.

```coffeescript
layerA.on "unfocus", ->
Expand Down

0 comments on commit e9244ea

Please sign in to comment.