menu-motion 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 934a02195b3c68b51b5bcfdf5f0907d7d3717995
4
- data.tar.gz: 5f6f318336f94e483f9cc58d2d7c17f1e42583f6
3
+ metadata.gz: 728776dec6261eb85e60dbb1d452dd1605257f62
4
+ data.tar.gz: 233be399ec008b1eb71af6146684568fc335f521
5
5
  SHA512:
6
- metadata.gz: 833c111856c289a0c5b3d977640e3d65cb92b9d02daeb6385164349b79d03582b3925b3ad1ca19888579d38039db043bd2715b6bdeefc21d46449555e5630555
7
- data.tar.gz: 815b050b4d22bbbda7601e30417897d897e75a268dd1235b03f6cde46ad4e1a773f0bfe47b5cc0088851d926fb9ee9c1d036f964c45e0fcd93b6293f2dc58adf
6
+ metadata.gz: 7f27f0192f9ef7bb1f1c2592873fa5bda6e949410b40bcc2f3d093b79bbeae54b34ce42e69c8a5a0cfe6d29e01bf7893b787e506d5d616cf00bb50d02be529ba
7
+ data.tar.gz: e57a001a46dc0fc2271f7f1b44fa541e0a247a0de2db09caf75d5891c192c2ba7ac9d37299fcd0108611a8738224dc00554b1ba444fcfd60d1ba0275f3b0b5be
data/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # MenuMotion
2
2
 
3
- MenuMotion is a RubyMotion wrapper inspired by Formotion for creating OS X status bar menus with a syntax that should feel familiar if you've used Formotion.
3
+ [![Build Status](https://travis-ci.org/codelation/menu-motion.svg)](https://travis-ci.org/codelation/menu-motion)
4
+ [![Code Climate](https://codeclimate.com/github/codelation/menu-motion.png)](https://codeclimate.com/github/codelation/menu-motion)
5
+
6
+ MenuMotion is a [RubyMotion](http://www.rubymotion.com) wrapper inspired by [Formotion](https://github.com/clayallsopp/formotion) for creating OS X status bar menus with a syntax that should feel familiar if you've used Formotion.
4
7
 
5
8
  ## Installation
6
9
 
@@ -67,12 +70,10 @@ menu = MenuMotion::Menu.new({
67
70
  }, {
68
71
  rows: [{
69
72
  title: "About MenuMotion",
70
- target: self,
71
- action: "about"
73
+ action: "orderFrontStandardAboutPanel:"
72
74
  }, {
73
75
  title: "Quit",
74
- target: self,
75
- action: "quit"
76
+ action: "terminate:"
76
77
  }]
77
78
  }]
78
79
  })
@@ -137,23 +138,69 @@ def action_with_sender(sender)
137
138
  end
138
139
  ```
139
140
 
141
+ ### Keyboard Shortcuts
142
+
143
+ Keyboard shortcuts can be assigned to menu items with a simple string.
144
+ The string can include multiple modifier keys, followed by the final key to be assigned (`{modifier+}{modifier+}{key}`):
145
+
146
+ ```ruby
147
+ menu = MenuMotion::Menu.new({
148
+ rows: [{
149
+ title: "Item 1",
150
+ shortcut: "command+1"
151
+ }, {
152
+ title: "Item 2",
153
+ shortcut: "control+shift+2"
154
+ }]
155
+ })
156
+ ```
157
+
158
+ #### Modifier Key Options
159
+
160
+ - **`shift`**
161
+ - **`control`**, `ctl`, `ctrl`
162
+ - **`option`**, `opt`, `alt`, `alternate`
163
+ - **`command`**, `cmd`
164
+
165
+ ### Validation
166
+
167
+ MenuMotion implements the [NSMenuValidation](https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/Protocols/NSMenuValidation_Protocol/Reference/Reference.html) protocol. Pass a proc to a menu item on `validate`:
168
+
169
+ ```ruby
170
+ menu = MenuMotion::Menu.new({
171
+ rows: [{
172
+ title: "Menu item",
173
+ tag: :main_item
174
+ rows: [{
175
+ title: "Submenu item 1",
176
+ tag: :submenu_item1,
177
+ target: self,
178
+ action: "do_something:",
179
+ validate: ->(menu_item) {
180
+ true # or false
181
+ }
182
+ }]
183
+ }]
184
+ })
185
+ ```
186
+
140
187
  ### Updating Menu Items
141
188
 
142
- Assign keys to menu items that will need to be updated.
189
+ Assign tags to menu items that will need to be updated.
143
190
 
144
191
  ```ruby
145
192
  menu = MenuMotion::Menu.new({
146
193
  rows: [{
147
194
  title: "Menu item",
148
- key: :main_item
195
+ tag: :main_item
149
196
  rows: [{
150
197
  title: "Submenu item 1",
151
- key: :submenu_item1,
198
+ tag: :submenu_item1,
152
199
  target: self,
153
200
  action: "do_something:"
154
201
  }, {
155
202
  title: "Submenu item 2",
156
- key: :submenu_item2,
203
+ tag: :submenu_item2,
157
204
  target: self,
158
205
  action: "do_something:"
159
206
  }]
@@ -161,13 +208,13 @@ menu = MenuMotion::Menu.new({
161
208
  })
162
209
 
163
210
  # Let's update the first item's title:
164
- menu.update(:main_item, {
211
+ menu.update_item_with_tag(:main_item, {
165
212
  title: "Hello World"
166
213
  })
167
214
 
168
215
  # And give the first submenu item a submenu.
169
216
  # The target and action will not be used if a submenu is defined.
170
- menu.update(:submenu_item1, {
217
+ menu.update_item_with_tag(:submenu_item1, {
171
218
  rows: [{
172
219
  title: "Click me",
173
220
  target: self,
@@ -176,6 +223,11 @@ menu.update(:submenu_item1, {
176
223
  })
177
224
  ```
178
225
 
226
+ ## TODO
227
+
228
+ - Menu Item Icons
229
+ - Keyboard Shortcuts
230
+
179
231
  ## Contributing
180
232
 
181
233
  1. Fork it
@@ -2,34 +2,25 @@ module MenuMotion
2
2
 
3
3
  class Menu < NSMenu
4
4
 
5
- attr_accessor :menu_items
6
- attr_accessor :root_menu
5
+ attr_accessor :menu_items, :root_menu
7
6
 
8
7
  def add_rows_to_menu(menu, rows)
9
8
  rows.each do |row|
10
- menu_item = NSMenuItem.alloc.initWithTitle(row[:title], action: row[:action], keyEquivalent:"")
11
- menu_item.target = row[:target]
12
-
13
- # Add sections and/or rows to a submenu
14
- if row[:sections]
15
- submenu = MenuMotion::Menu.new({
16
- sections: row[:sections]
17
- }, self.root_menu || self)
18
- menu_item.setSubmenu(submenu)
19
- elsif row[:rows]
20
- submenu = MenuMotion::Menu.new({
21
- rows: row[:rows]
22
- }, self.root_menu || self)
23
- menu_item.setSubmenu(submenu)
24
- end
9
+ row[:root_menu] = WeakRef.new(self.root_menu || self)
10
+ menu_item = MenuMotion::MenuItem.new(row)
11
+ menu_item.target = self
12
+ menu_item.action = "perform_action:"
13
+
14
+ if tag = row[:tag]
15
+ tag = tag.to_sym
16
+ menu_item.tag = tag
25
17
 
26
- if row[:key]
27
18
  if self.root_menu
28
19
  self.root_menu.menu_items ||= {}
29
- self.root_menu.menu_items[row[:key].to_sym] = WeakRef.new(menu_item)
20
+ self.root_menu.menu_items[tag] = WeakRef.new(menu_item)
30
21
  else
31
22
  self.menu_items ||= {}
32
- self.menu_items[row[:key].to_sym] = WeakRef.new(menu_item)
23
+ self.menu_items[tag] = WeakRef.new(menu_item)
33
24
  end
34
25
  end
35
26
 
@@ -59,7 +50,11 @@ module MenuMotion
59
50
  end
60
51
 
61
52
  def initialize(params = {}, root_menu = nil)
62
- super()
53
+ if params[:title]
54
+ initWithTitle(params[:title])
55
+ else
56
+ super()
57
+ end
63
58
 
64
59
  self.root_menu = root_menu
65
60
  self.build_menu_from_params(self, params)
@@ -67,22 +62,24 @@ module MenuMotion
67
62
  self
68
63
  end
69
64
 
70
- def item_with_key(key)
65
+ def item_with_tag(tag)
71
66
  @menu_items ||= {}
72
- @menu_items[key.to_sym]
67
+ @menu_items[tag.to_sym]
73
68
  end
74
69
 
75
- def update(key, params)
76
- menu_item = self.item_with_key(key)
70
+ def perform_action(menu_item)
71
+ menu_item.perform_action
72
+ end
77
73
 
78
- menu_item.title = params[:title] if params[:title]
79
- menu_item.target = params[:target] if params[:target]
80
- menu_item.action = params[:action] if params[:action]
74
+ def update_item_with_tag(tag, params)
75
+ menu_item = self.item_with_tag(tag)
76
+ menu_item.update(params)
77
+ end
81
78
 
82
- self
79
+ def validateMenuItem(menu_item)
80
+ menu_item.valid?
83
81
  end
84
82
 
85
83
  end
86
84
 
87
85
  end
88
-
@@ -0,0 +1,106 @@
1
+ module MenuMotion
2
+
3
+ class MenuItem < NSMenuItem
4
+
5
+ attr_accessor :item_action, :item_target,
6
+ :root_menu, :tag, :validate
7
+
8
+ def initialize(params = {})
9
+ super()
10
+ update(params)
11
+ self
12
+ end
13
+
14
+ def perform_action
15
+ if self.valid? && self.valid_target_and_action?
16
+ if self.item_action.to_s.end_with?(":")
17
+ self.item_target.performSelector(self.item_action, withObject: self)
18
+ else
19
+ self.item_target.performSelector(self.item_action)
20
+ end
21
+ end
22
+ end
23
+
24
+ def update(params)
25
+ self.item_action = params[:action] if params.has_key?(:action)
26
+ self.item_target = params[:target] if params.has_key?(:target)
27
+ self.root_menu = params[:root_menu] if params.has_key?(:root_menu)
28
+ self.title = params[:title] if params.has_key?(:title)
29
+ self.validate = params[:validate] if params.has_key?(:validate)
30
+
31
+ # Set NSApp as the default target if no other target is given
32
+ if self.item_action && self.item_target.nil?
33
+ self.item_target = NSApp
34
+ end
35
+
36
+ # Setup submenu and keyboard shortcut
37
+ set_submenu_from_params(params)
38
+ set_keyboard_shortcut(params[:shortcut]) if params.has_key?(:shortcut)
39
+
40
+ self
41
+ end
42
+
43
+ def valid?
44
+ if self.submenu || self.valid_target_and_action?
45
+ if self.validate.nil?
46
+ true
47
+ else
48
+ self.validate.call(self)
49
+ end
50
+ else
51
+ false
52
+ end
53
+ end
54
+
55
+ def valid_target_and_action?
56
+ self.item_target && self.item_action && self.item_target.respond_to?(self.item_action.gsub(":", ""))
57
+ end
58
+
59
+ private
60
+
61
+ def set_keyboard_shortcut(shortcut)
62
+ if shortcut
63
+ keys = shortcut.gsub("-", "+").split("+")
64
+ key = keys.pop
65
+ modifier_mask = 0
66
+ modifier_keys = keys
67
+
68
+ modifier_keys.each do |modifier_key|
69
+ case modifier_key
70
+ when "alt", "alternate", "opt", "option"
71
+ modifier_mask |= NSAlternateKeyMask
72
+ when "cmd", "command"
73
+ modifier_mask |= NSCommandKeyMask
74
+ when "ctl", "ctrl", "control"
75
+ modifier_mask |= NSControlKeyMask
76
+ when "shift"
77
+ modifier_mask |= NSShiftKeyMask
78
+ end
79
+ end
80
+
81
+ self.setKeyEquivalent(key)
82
+ self.setKeyEquivalentModifierMask(modifier_mask)
83
+ else
84
+ self.setKeyEquivalent(nil)
85
+ self.setKeyEquivalentModifierMask(nil)
86
+ end
87
+ end
88
+
89
+ def set_submenu_from_params(params)
90
+ if params[:sections]
91
+ submenu = MenuMotion::Menu.new({
92
+ sections: params[:sections]
93
+ }, self.root_menu)
94
+ self.setSubmenu(submenu)
95
+ elsif params[:rows]
96
+ submenu = MenuMotion::Menu.new({
97
+ rows: params[:rows]
98
+ }, self.root_menu)
99
+ self.setSubmenu(submenu)
100
+ end
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+
@@ -1,3 +1,3 @@
1
1
  module MenuMotion
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: menu-motion
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Pattison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-18 00:00:00.000000000 Z
11
+ date: 2014-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -35,6 +35,7 @@ files:
35
35
  - README.md
36
36
  - lib/menu_motion.rb
37
37
  - lib/menu_motion/menu.rb
38
+ - lib/menu_motion/menu_item.rb
38
39
  - lib/menu_motion/version.rb
39
40
  homepage: https://github.com/codelation/menu-motion
40
41
  licenses: