Make EventPalette a SelectList subclass

This commit is contained in:
Nathan Sobo
2012-10-04 09:32:30 -10:00
parent eced862902
commit 66c997f75d
3 changed files with 30 additions and 119 deletions

View File

@@ -19,68 +19,27 @@ describe "EventPalette", ->
describe "when event-palette:show is triggered on the root view", ->
it "shows a list of all valid events for the previously focused element, then focuses the mini-editor and selects the first event", ->
for [event, description] in rootView.getActiveEditor().events()
expect(palette.eventList.find("td:contains(#{event})")).toExist()
expect(palette.list.find(".event:contains(#{event})")).toExist()
expect(palette.miniEditor.isFocused).toBeTruthy()
expect(palette.find('.event:first')).toHaveClass 'selected'
describe "when event-palette:cancel is triggered on the event palette", ->
describe "when the event palette is cancelled", ->
it "focuses the root view and detaches the event palette", ->
expect(palette.hasParent()).toBeTruthy()
palette.trigger('event-palette:cancel')
palette.cancel()
expect(palette.hasParent()).toBeFalsy()
expect(rootView.getActiveEditor().isFocused).toBeTruthy()
describe "when 'move-up' and 'move-down' events are triggered on the mini editor", ->
it "selects the next and previous event, if there is one, and scrolls the list to it", ->
palette.miniEditor.trigger 'move-up'
expect(palette.find('.event:eq(0)')).toHaveClass 'selected'
palette.miniEditor.trigger 'move-down'
expect(palette.find('.event:eq(0)')).not.toHaveClass 'selected'
expect(palette.find('.event:eq(1)')).toHaveClass 'selected'
palette.miniEditor.trigger 'move-down'
expect(palette.find('.event:eq(1)')).not.toHaveClass 'selected'
expect(palette.find('.event:eq(2)')).toHaveClass 'selected'
palette.miniEditor.trigger 'move-up'
expect(palette.find('.event:eq(2)')).not.toHaveClass 'selected'
expect(palette.find('.event:eq(1)')).toHaveClass 'selected'
_.times palette.find('.event').length, ->
palette.miniEditor.trigger 'move-down'
expect(palette.eventList.scrollTop() + palette.eventList.height()).toBe palette.eventList.prop('scrollHeight')
describe "event triggering", ->
eventHandler = null
beforeEach ->
describe "when an event selection is confirmed", ->
it "detaches the palette, then focuses the previously focused element and emits the selected event on it", ->
eventHandler = jasmine.createSpy 'eventHandler'
activeEditor = rootView.getActiveEditor()
[eventName, description] = palette.array[4]
activeEditor.preempt eventName, eventHandler
describe "when event-palette:select is triggered on the palette", ->
it "emits the selected event on the last focused element, then detaches the palette", ->
_.times 3, -> palette.miniEditor.trigger 'move-down'
rootView.getActiveEditor().preempt palette.getSelectedEventName(), eventHandler
palette.trigger 'event-palette:select'
expect(eventHandler).toHaveBeenCalled()
expect(rootView.getActiveEditor().isFocused).toBeTruthy()
expect(palette.hasParent()).toBeFalsy()
describe "when an item is clicked", ->
it "selects item and triggers its event", ->
element = palette.eventList.find('.event:eq(3)')
element.mousedown()
expect(element).toHaveClass 'selected'
rootView.getActiveEditor().preempt palette.getSelectedEventName(), eventHandler
element.mouseup()
expect(eventHandler).toHaveBeenCalled()
rootView.getActiveEditor().preempt palette.getSelectedEventName(), eventHandler
element.click()
palette.confirmed(palette.array[4])
expect(activeEditor.isFocused).toBeTruthy()
expect(eventHandler).toHaveBeenCalled()
expect(palette.hasParent()).toBeFalsy()

View File

@@ -1,34 +1,35 @@
{View, $$} = require 'space-pen'
SelectList = require 'select-list'
Editor = require 'editor'
$ = require 'jquery'
module.exports =
class EventPalette extends View
class EventPalette extends SelectList
@activate: (rootView) ->
requireStylesheet 'event-palette/event-palette.css'
@instance = new EventPalette(rootView)
rootView.on 'event-palette:show', => @instance.attach()
@content: ->
@div class: 'event-palette', =>
@div class: 'select-list', outlet: 'eventList'
@subview 'miniEditor', new Editor(mini: true)
@viewClass: ->
"#{super} event-palette"
filterKey: 0 # filter on the event name for now
initialize: (@rootView) ->
@on 'move-up', => @selectPrevious()
@on 'move-down', => @selectNext()
@on 'event-palette:cancel', => @detach()
@on 'event-palette:select', => @triggerSelectedEvent()
@on 'mousedown', '.event', (e) => @selectItem($(e.target).closest('.event'))
@on 'mouseup', '.event', => @triggerSelectedEvent()
super
attach: ->
@previouslyFocusedElement = $(':focus')
@populateEventList()
@eventList.find('.event:first').addClass('selected')
@setArray(@previouslyFocusedElement.events())
@appendTo(@rootView)
@miniEditor.focus()
itemForElement: ([eventName, description]) ->
$$ ->
@li class: 'event', =>
@div eventName, class: 'event-name'
@div description, class: 'event-description'
populateEventList: ->
events = @previouslyFocusedElement.events()
table = $$ ->
@@ -40,39 +41,10 @@ class EventPalette extends View
@eventList.html(table)
selectPrevious: ->
@selectItem(@getSelectedItem().prev())
confirmed: ([eventName, description]) ->
@cancel()
@previouslyFocusedElement.trigger(eventName)
selectNext: ->
@selectItem(@getSelectedItem().next())
selectItem: (item) ->
return unless item.length
@eventList.find('.selected').removeClass('selected')
item.addClass('selected')
@scrollToItem(item)
scrollToItem: (item) ->
scrollTop = @eventList.prop('scrollTop')
desiredTop = item.position().top + scrollTop
desiredBottom = desiredTop + item.height()
if desiredTop < scrollTop
@eventList.scrollTop(desiredTop)
else if desiredBottom > @eventList.scrollBottom()
@eventList.scrollBottom(desiredBottom)
getSelectedItem: ->
@eventList.find('.selected')
getSelectedEventName: ->
@getSelectedItem().find('.event-name').text()
triggerSelectedEvent: ->
cancelled: ->
@previouslyFocusedElement.focus()
@previouslyFocusedElement.trigger(@getSelectedEventName())
@detach()
detach: ->
@rootView.focus() if @miniEditor.isFocused
super

View File

@@ -1,21 +1 @@
.event-palette {
position: absolute;
width: 100%;
bottom: 0;
}
.event-palette .select-list {
background-color: black;
position: relative;
max-height: 300px;
color: white;
overflow-y: auto;
}
.event-palette .select-list table {
width: 100%;
}
.event-palette .select-list .selected {
background-color: green;
}