/
menu.coffee
78 lines (59 loc) · 2.35 KB
/
menu.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
resources = require 'resources'
UIBase = require 'ui/base'
UIMenuSeparator = class $.model.UIMenuSeparator extends UIBase
constructor: -> super $('<li class="ui-menuSeparator">')
UIMenuItem = class $.model.UIMenuItem extends UIBase
constructor: (options, @action) ->
super options.template ? 'views/ui/menu/item', options
$(@rootElement).bind 'click', (event) =>
this.action?(event)
$(event.target).closest('.ui-menu').model().hide()
exports = class $.model.UIMenu extends UIBase
@property 'title', '.ui-menuHeader'
constructor: (title, options, buildMenu) ->
if not buildMenu? and typeof options is 'function'
[options, buildMenu] = [{}, options]
else if not options?
options = {}
super 'views/ui/menu', $.extend({title}, options)
if buildMenu?
buildMenu
defaults: (options) =>
$.extend @defaults, options
item: =>
this.addItem arguments...
separator: =>
this.addSeparator arguments...
Object.defineProperty @prototype, 'items',
get: -> this.find('.ui-menuItem, .ui-menuSeparator').models()
load: (options) ->
@defaults = $.extend {}, options.defaults
addItem: (label, options, action) ->
if not action? and typeof options is 'function'
[options, action] = [{}, options]
options = $.extend {label}, @defaults, options
this.find('.ui-menuContent').append \
new UIMenuItem(options, action).rootElement
addSeparator: ->
this.find('.ui-menuContent').append new UIMenuSeparator().rootElement
show: (targetPos = {}) ->
el = $(@rootElement)
el.appendTo('body') unless @rootElement.parentElement?
cssPos = {}
height = el.outerHeight()
width = el.outerWidth()
if targetPos.at?
# position relative to another element
{left: x, top: y} = $(targetPos.at).offset()
x += targetPos.x if targetPos.x?
y += targetPos.y if targetPos.y?
else
# position absolutely
{x, y} = targetPos
if x + width <= window.innerWidth
then [cssPos.left, cssPos.right] = [x, '']
else [cssPos.right, cssPos.left ] = [window.innerWidth - x, '']
if y + height <= window.innerHeight
then [cssPos.top, cssPos.bottom] = [y, '']
else [cssPos.bottom, cssPos.top ] = [window.innerHeight - y, '']
el.css(cssPos).cssFadeIn()