mynu 0.2.5 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGES CHANGED
@@ -1 +1,14 @@
1
- None yet!
1
+ v 0.3.0
2
+ ====
3
+ * Changed how blocks are passed and received
4
+ * Slight changes the API
5
+ * New example scripts
6
+ * Added a bunch of commands, see `examples/` directory for details
7
+ * Added `open` command
8
+ * Added `link` command
9
+ * Added `terminal` command (best used with one terminal window and/or visor)
10
+ * Added `menu` command
11
+
12
+ v 0.2.5
13
+ ====
14
+ * Initial release
data/README.md CHANGED
@@ -6,50 +6,42 @@ A simple DSL to create a systembar menu with macruby in OSX
6
6
  ![](http://i.imgur.com/yQBEE.png)
7
7
 
8
8
  1. `gem install mynu`
9
- 2. `macruby examples/hello-mynu.rb`
10
-
11
-
12
- An example of abusing `open [-a]`
13
-
14
- `macruby examples/workflow.rb`
15
-
16
-
17
- Or if your feeling bohemian:
18
-
19
- `macruby examples/queen.rb`
9
+ 2. `macruby examples/dsl.rb`
20
10
 
11
+ Usage example:
12
+ `macruby examples/dsl.rb`
21
13
 
22
14
  require 'rubygems'
23
15
  require 'mynu'
24
16
 
25
17
  mynu = Mynu.new
26
18
 
27
- mynu.item "Hello World!" do |menu|
19
+ mynu.menu "Hello World!" do |menu|
28
20
  puts "Inside menu setup!"
29
21
  menu.title = "Good Bye World!"
30
- menu.item "Option 1" do |sub_menu|
31
- sub_menu.execute do
22
+ menu.item "Option 1" do |item|
23
+ item.execute do
32
24
  puts "Execution block"
33
- sub_menu.title = "Dynamically changed!"
25
+ item.title = "Dynamically changed!"
34
26
  end
35
27
  end
36
- menu.item "Option 2" do |sub_menu|
37
- sub_menu.item "Option 2a" do
28
+ menu.menu "Option 2" do |menu|
29
+ menu.item "Option 2a" do
38
30
  puts "Option 2a clicked!"
39
31
  end
40
- sub_menu.item "Option 2b" do
32
+ menu.item "Option 2b" do
41
33
  puts "Option 2b clicked!"
42
34
  end
43
- sub_menu.execute do
44
- puts "Execution block and items"
45
- sub_menu.title = "Dynamically changed!"
35
+ menu.execute do
36
+ puts "Menu item clicked!"
37
+ menu.title = "Dynamically changed!"
46
38
  end
47
39
  end
48
- capture_menu_item = menu.item "Disabled" do |sub_menu|
49
- sub_menu.disabled
40
+ capture_menu_item = menu.item "Disabled" do |item|
41
+ item.disabled
50
42
  end
51
- menu.item "Enable `Disabled`" do |sub_menu|
52
- sub_menu.execute do
43
+ menu.item "Enable `Disabled`" do |item|
44
+ item.execute do
53
45
  capture_menu_item.enabled
54
46
  capture_menu_item.execute do
55
47
  capture_menu_item.title = "Disabled (Again)!"
@@ -67,65 +59,74 @@ Or if your feeling bohemian:
67
59
 
68
60
  ====
69
61
 
70
- require 'rubygems'
71
- require 'mynu'
62
+ A workflow example:
63
+ `macruby examples/workflow.rb`
72
64
 
73
65
  mynu = Mynu.new
74
66
 
75
- mynu.item "Applications" do |applications|
76
- applications.item "Terminal" do
77
- # TODO: AppleScript a tab, this does nothing if terminal is open
78
- `open -a /Applications/Utilities/Terminal.app`
79
- end
67
+ mynu.menu "Applications" do |applications|
68
+ applications.app "TextEdit", "/Applications/Utilities/Terminal.app"
80
69
  end
81
70
 
82
- mynu.item "Project" do |project|
83
- project.item "Live" do
84
- `open http://example.com`
85
- end
86
- project.item "Staging" do
87
- `open http://user:pass@staging.example.com`
88
- end
89
- project.item "Development" do
90
- `open http://example.dev`
91
- end
92
- project.item "Repos" do |repos|
93
- repos.item "Example" do
94
- `open ~/example`
95
- end
96
- repos.item "Resources" do
97
- `open ~/example-resources`
98
- end
71
+ mynu.menu "Project" do |project|
72
+ project.link "Live", "http://example.com"
73
+ project.link "Staging", "http://user:pass@staging.example.com"
74
+ project.link "Development", "http://example.dev"
75
+ project.menu "Repos" do |repos|
76
+ repos.open "Example", "~/example"
77
+ repos.open "Resources", "~/example-resources"
99
78
  end
100
79
  end
101
80
 
102
- mynu.items << NSMenuItem.separatorItem
81
+ mynu.separator
103
82
 
104
- mynu.item "Development" do |development|
105
- development.item "Rails" do |development_mynu|
106
- development_mynu.item "Github" do
107
- `open http://github.com/rails/rails`
108
- end
109
- development_mynu.item "Repo" do
110
- `open ~/workspace/rails`
111
- end
83
+ mynu.menu "Development" do |development|
84
+ development.menu "Rails" do |rails|
85
+ rails.link "Github", "http://github.com/rails/rails"
86
+ rails.open "Repo", "~/workspace/rails"
112
87
  end
113
88
  end
114
89
 
115
- mynu.items << NSMenuItem.separatorItem
90
+ mynu.separator
91
+ mynu.open "Downloads", "~/Downloads"
92
+ mynu.separator
93
+ mynu.open "Desktop", "~/Desktop"
94
+ mynu.separator
95
+
96
+ mynu.run
116
97
 
117
- mynu.item "Downloads" do
118
- `open ~/Downloads`
119
- end
120
98
 
121
- mynu.items << NSMenuItem.separatorItem
99
+ A terminal example (best used with Visor and one terminal window!):
100
+ `macruby examples/terminal.rb`
122
101
 
123
- desktop = mynu.item "Desktop" do
124
- `open ~/Desktop`
102
+ require 'rubygems'
103
+ require 'mynu'
104
+
105
+ mynu = Mynu.new
106
+
107
+ #############################################################
108
+ # Warning!
109
+ #
110
+ # This makes the assumation you use Visor and only manage
111
+ # one terminal window. Otherwise tabs will only be created
112
+ # in your first/primary terminal window.
113
+ #
114
+ # You can get Visor at: http://visor.binaryage.com/
115
+ #
116
+ #############################################################
117
+
118
+ # Normal usage will return to the frontmost app at execution
119
+ mynu.terminal "Echo & Disable Item", "echo hello" do
120
+ disabled
125
121
  end
126
122
 
127
- mynu.items << NSMenuItem.separatorItem
123
+ mynu.terminal "Echo & Exit", "echo hello", :exit => true do
124
+ disabled
125
+ end
128
126
 
127
+ mynu.terminal "Keeps focus on Terminal Tab", "echo hello", :focus => true do
128
+ disabled
129
+ end
129
130
 
130
131
  mynu.run
131
132
 
@@ -133,11 +134,10 @@ Or if your feeling bohemian:
133
134
 
134
135
  Todo
135
136
  =====
136
- * Lots
137
- * Reloading
138
- * Crash Handling
137
+ * Improved API (done!)
138
+ * Reloading?
139
+ * Crash Handling?
139
140
  * FileMenuItem
140
- * Improved API
141
- * Simple Dialogs?
141
+ * Simple Dialogs
142
142
 
143
143
  # Copyright (C) 2011 by Robert Lowe <rob[!]iblargz.com> - MIT
@@ -12,37 +12,41 @@ class Mynu
12
12
  autoload :Menu, 'mynu/menu' # wrapping NSMenu
13
13
  autoload :Dsl, 'mynu/dsl' # dsl modules
14
14
 
15
- include Dsl::Block
15
+ autoload :Support, 'mynu/support'
16
16
 
17
- attr_accessor :app # the sharedApplication
18
- attr_accessor :status_item # the new bar icon
19
- attr_accessor :menu # menu container
20
- attr_accessor :items # root items
17
+ attr_accessor :__app # the sharedApplication
18
+ attr_accessor :__status_item # the new bar icon
19
+ attr_accessor :__menu # menu container
20
+
21
+ include Dsl::Block # menu, app, open, terminal on items
22
+ alias_method :link, :open
23
+
24
+ attr_accessor :items
21
25
 
22
26
  # Prepare the application
23
27
  def initialize(icon = nil, menu_title = 'Mynu')
24
- @app = NSApplication.sharedApplication
28
+ @__app = NSApplication.sharedApplication
25
29
 
26
30
  icon = File.join(File.dirname(__FILE__), '..', 'lib') + '/mynu/assets/logo.png' if icon.nil?
27
31
 
28
- @status_item = status_bar.statusItemWithLength(NSVariableStatusItemLength)
29
- @status_item.setImage NSImage.new.initWithContentsOfFile(icon)
32
+ @__status_item = status_bar.statusItemWithLength(NSVariableStatusItemLength)
33
+ @__status_item.setImage NSImage.new.initWithContentsOfFile(icon)
34
+
35
+ @__menu = Menu.new
36
+ @__menu.initWithTitle menu_title
37
+ @__menu.setAutoenablesItems false
30
38
 
31
- @menu = Menu.new
32
- @menu.initWithTitle menu_title
33
- @menu.setAutoenablesItems false
34
-
35
39
  @items = []
36
40
  end
37
41
 
38
42
  def run
39
- @status_item.setMenu loadMenu
40
- @app.run
43
+ @__status_item.setMenu loadMenu
44
+ @__app.run
41
45
  end
42
46
 
43
47
  def quit(sender)
44
48
  puts "Quitting :: Mynu"
45
- @app.terminate(self)
49
+ @__app.terminate(self)
46
50
  end
47
51
 
48
52
  protected
@@ -53,16 +57,16 @@ protected
53
57
 
54
58
  def loadMenu
55
59
  @items.each do |item|
56
- @menu.addItem item
60
+ @__menu.addItem item
57
61
  end
58
62
 
59
63
  quit = Menu::MenuItem.new
60
64
  quit.title = 'Quit'
61
65
  quit.action = 'quit:'
62
66
  quit.target = self
63
- @menu.addItem quit
67
+ @__menu.addItem quit
64
68
 
65
- @menu
69
+ @__menu
66
70
  end
67
71
 
68
72
  end
@@ -2,4 +2,10 @@ class Mynu
2
2
  module Dsl
3
3
  autoload :Block, 'mynu/dsl/block'
4
4
  end
5
+
6
+ class Receivable < Proc
7
+ def call(sender)
8
+ super(sender)
9
+ end
10
+ end
5
11
  end
@@ -1,16 +1,96 @@
1
1
  class Mynu
2
2
  module Dsl
3
3
  module Block
4
+ def separator
5
+ @items << NSMenuItem.separatorItem
6
+ end
7
+
8
+ def app(title, app, &block)
9
+ block = Proc.new {} unless block_given?
10
+ add_item(
11
+ title,
12
+ item_block(block) { `open -a #{app}` }
13
+ )
14
+ end
15
+
16
+ def open(title, path, &block)
17
+ block = Proc.new {} unless block_given?
18
+ add_item(
19
+ title,
20
+ item_block(block) { `open #{path}` }
21
+ )
22
+ end
23
+
24
+ def terminal(title, command, options={}, &block)
25
+ block = Proc.new {} unless block_given?
26
+ add_item(
27
+ title,
28
+ item_block(block) {
29
+ terminal = Mynu::Support::Terminal.new
30
+ terminal.create_tab(command, options)
31
+ }
32
+ )
33
+ end
34
+
4
35
  def item(title, &block)
5
- if block_given?
6
- item = Menu::BlockMenuItem.new(title, block)
7
- @items << item
8
- item
9
- else
10
- raise
11
- end
36
+ block = Proc.new {} unless block_given?
37
+ add_item(
38
+ title,
39
+ item_block(block) { }
40
+ )
12
41
  end
42
+
43
+ def menu(title, &block)
44
+ raise "Block must be provided for a menu" unless block_given?
45
+ add_item(
46
+ title,
47
+ item_block(Proc.new {}) {}
48
+ ) {
49
+ case block.arity
50
+ when 0
51
+ self.instance_eval(&block)
52
+ when 1
53
+ block.call(self)
54
+ else
55
+ raise
56
+ end
57
+
58
+ if self.items.length > 0
59
+ menu = Menu.new
60
+ menu.setAutoenablesItems false
61
+
62
+ self.setSubmenu menu
63
+
64
+ self.items.each do |item|
65
+ menu.addItem item
66
+ end
67
+ end
68
+ }
69
+ end
70
+
71
+ def add_item(title, runtime_block, &block)
72
+ item = Menu::BlockMenuItem.new(title, runtime_block)
73
+ item.instance_eval(&block) if block_given?
74
+ @items << item
75
+ item
76
+ end
77
+
78
+ def item_block(original_block, &block)
79
+ Receivable.new { |sender|
80
+ block.call(sender) if block
81
+ case original_block.arity
82
+ when 0
83
+ sender.instance_eval(&original_block)
84
+ when 1
85
+ original_block.call(sender)
86
+ else
87
+ raise
88
+ end
89
+ }
90
+ end
91
+
13
92
  end
14
93
  end
15
94
  end
16
95
 
96
+
@@ -2,40 +2,22 @@ class Mynu
2
2
  module Menu
3
3
  class BlockMenuItem < MenuItem
4
4
  include Dsl::Block
5
-
6
- def execute(&block)
7
- self.action = 'call:'
8
- self.target = block
9
- end
5
+ alias_method :link, :open
10
6
 
11
7
  def initialize(title, block)
12
- super # thanks for asking
8
+ super
13
9
 
14
10
  self.title = title
15
11
 
16
- case block.arity
17
- when 0
18
- # regular item
19
- self.action = 'call:'
20
- self.target = block
21
- when 1
22
- block.call(self)
23
-
24
- if @items.length > 0
25
- menu = Menu.new
26
- menu.setAutoenablesItems false
27
-
28
- self.setSubmenu menu
12
+ self.action = 'call:'
13
+ self.target = block
14
+ end
29
15
 
30
- @items.each do |item|
31
- menu.addItem item
32
- end
33
- end
34
- else
35
- raise
36
- end
16
+ def execute(&block)
17
+ self.action = 'call:'
18
+ self.target = item_block(block){}
37
19
  end
38
-
20
+
39
21
  def disabled
40
22
  self.setEnabled(false)
41
23
  self.isEnabled
@@ -0,0 +1,9 @@
1
+ framework 'Foundation'
2
+ framework 'ScriptingBridge'
3
+
4
+ class Mynu
5
+ module Support
6
+ autoload :System, 'mynu/support/system'
7
+ autoload :Terminal, 'mynu/support/terminal'
8
+ end
9
+ end
@@ -0,0 +1,484 @@
1
+ <?xml version='1.0'?>
2
+ <!DOCTYPE signatures SYSTEM "file://localhost/System/Library/DTDs/BridgeSupport.dtd">
3
+ <signatures version='0.9'>
4
+ <enum name='SystemEventsAppeBlue' value='1651275109'/>
5
+ <enum name='SystemEventsAppeGraphite' value='1735550580'/>
6
+ <enum name='SystemEventsDhacAskWhatToDo' value='1684562291'/>
7
+ <enum name='SystemEventsDhacIgnore' value='1684564327'/>
8
+ <enum name='SystemEventsDhacOpenApplication' value='1684562288'/>
9
+ <enum name='SystemEventsDhacRunAScript' value='1684566643'/>
10
+ <enum name='SystemEventsDpefGenie' value='1734700649'/>
11
+ <enum name='SystemEventsDpefScale' value='1935892844'/>
12
+ <enum name='SystemEventsDplsBottom' value='1651471476'/>
13
+ <enum name='SystemEventsDplsLeft' value='1818584692'/>
14
+ <enum name='SystemEventsDplsRight' value='1919510376'/>
15
+ <enum name='SystemEventsEMdsCommandDown' value='1264807268'/>
16
+ <enum name='SystemEventsEMdsControlDown' value='1264809068'/>
17
+ <enum name='SystemEventsEMdsOptionDown' value='1265594484'/>
18
+ <enum name='SystemEventsEMdsShiftDown' value='1265854068'/>
19
+ <enum name='SystemEventsEMkyCommand' value='1698917732'/>
20
+ <enum name='SystemEventsEMkyControl' value='1698918004'/>
21
+ <enum name='SystemEventsEMkyOption' value='1699704948'/>
22
+ <enum name='SystemEventsEMkyShift' value='1699964532'/>
23
+ <enum name='SystemEventsEdfmApplePhotoFormat' value='1684435048'/>
24
+ <enum name='SystemEventsEdfmAppleShareFormat' value='1684431219'/>
25
+ <enum name='SystemEventsEdfmAudioFormat' value='1684431221'/>
26
+ <enum name='SystemEventsEdfmHighSierraFormat' value='1684433011'/>
27
+ <enum name='SystemEventsEdfmISO9660Format' value='1684420918'/>
28
+ <enum name='SystemEventsEdfmMSDOSFormat' value='1684434291'/>
29
+ <enum name='SystemEventsEdfmMacOSExtendedFormat' value='1684432939'/>
30
+ <enum name='SystemEventsEdfmMacOSFormat' value='1684432998'/>
31
+ <enum name='SystemEventsEdfmNFSFormat' value='1684434534'/>
32
+ <enum name='SystemEventsEdfmProDOSFormat' value='1684435058'/>
33
+ <enum name='SystemEventsEdfmQuickTakeFormat' value='1684435316'/>
34
+ <enum name='SystemEventsEdfmUDFFormat' value='1684436324'/>
35
+ <enum name='SystemEventsEdfmUFSFormat' value='1684436326'/>
36
+ <enum name='SystemEventsEdfmUnknownFormat' value='1684415524'/>
37
+ <enum name='SystemEventsEdfmWebDAVFormat' value='1684436836'/>
38
+ <enum name='SystemEventsEnumDetailed' value='1819763828'/>
39
+ <enum name='SystemEventsEnumStandard' value='1819767668'/>
40
+ <enum name='SystemEventsEpacAllWindows' value='1634495607'/>
41
+ <enum name='SystemEventsEpacApplicationWindows' value='1634758775'/>
42
+ <enum name='SystemEventsEpacDashboard' value='1684108136'/>
43
+ <enum name='SystemEventsEpacDisableScreenSaver' value='1684632419'/>
44
+ <enum name='SystemEventsEpacNone' value='1852796517'/>
45
+ <enum name='SystemEventsEpacShowDesktop' value='1684370283'/>
46
+ <enum name='SystemEventsEpacShowSpaces' value='1936745331'/>
47
+ <enum name='SystemEventsEpacSleepDisplay' value='1684632435'/>
48
+ <enum name='SystemEventsEpacStartScreenSaver' value='1937006962'/>
49
+ <enum name='SystemEventsEpfkF1' value='1177643897'/>
50
+ <enum name='SystemEventsEpfkF10' value='1177628779'/>
51
+ <enum name='SystemEventsEpfkF11' value='1177629035'/>
52
+ <enum name='SystemEventsEpfkF12' value='1177629291'/>
53
+ <enum name='SystemEventsEpfkF13' value='1177629547'/>
54
+ <enum name='SystemEventsEpfkF14' value='1177629803'/>
55
+ <enum name='SystemEventsEpfkF15' value='1177630059'/>
56
+ <enum name='SystemEventsEpfkF16' value='1177630315'/>
57
+ <enum name='SystemEventsEpfkF17' value='1177630571'/>
58
+ <enum name='SystemEventsEpfkF18' value='1177630827'/>
59
+ <enum name='SystemEventsEpfkF19' value='1177631083'/>
60
+ <enum name='SystemEventsEpfkF2' value='1177709433'/>
61
+ <enum name='SystemEventsEpfkF3' value='1177774969'/>
62
+ <enum name='SystemEventsEpfkF4' value='1177840505'/>
63
+ <enum name='SystemEventsEpfkF5' value='1177906041'/>
64
+ <enum name='SystemEventsEpfkF6' value='1177971577'/>
65
+ <enum name='SystemEventsEpfkF7' value='1178037113'/>
66
+ <enum name='SystemEventsEpfkF8' value='1178102649'/>
67
+ <enum name='SystemEventsEpfkF9' value='1178168185'/>
68
+ <enum name='SystemEventsEpfkLeftCommand' value='1281584484'/>
69
+ <enum name='SystemEventsEpfkLeftControl' value='1281586284'/>
70
+ <enum name='SystemEventsEpfkLeftOption' value='1282371700'/>
71
+ <enum name='SystemEventsEpfkLeftShift' value='1282631796'/>
72
+ <enum name='SystemEventsEpfkNone' value='1852796517'/>
73
+ <enum name='SystemEventsEpfkRightCommand' value='1382247780'/>
74
+ <enum name='SystemEventsEpfkRightControl' value='1382249580'/>
75
+ <enum name='SystemEventsEpfkRightOption' value='1383034996'/>
76
+ <enum name='SystemEventsEpfkRightShift' value='1383295092'/>
77
+ <enum name='SystemEventsEpfkSecondaryFunctionKey' value='1397123961'/>
78
+ <enum name='SystemEventsEpmdCommand' value='1668113517'/>
79
+ <enum name='SystemEventsEpmdControl' value='1668574317'/>
80
+ <enum name='SystemEventsEpmdNone' value='1852796517'/>
81
+ <enum name='SystemEventsEpmdOption' value='1869640813'/>
82
+ <enum name='SystemEventsEpmdShift' value='1936225389'/>
83
+ <enum name='SystemEventsFtssAutomatic' value='1635087469'/>
84
+ <enum name='SystemEventsFtssLight' value='1818850405'/>
85
+ <enum name='SystemEventsFtssMedium' value='1835361385'/>
86
+ <enum name='SystemEventsFtssStandard' value='1937010276'/>
87
+ <enum name='SystemEventsFtssStrong' value='1937011303'/>
88
+ <enum name='SystemEventsHicoBlue' value='1651275109'/>
89
+ <enum name='SystemEventsHicoGold' value='1735355492'/>
90
+ <enum name='SystemEventsHicoGraphite' value='1735550580'/>
91
+ <enum name='SystemEventsHicoGreen' value='1735550318'/>
92
+ <enum name='SystemEventsHicoOrange' value='1869770343'/>
93
+ <enum name='SystemEventsHicoPurple' value='1886548076'/>
94
+ <enum name='SystemEventsHicoRed' value='1919247392'/>
95
+ <enum name='SystemEventsHicoSilver' value='1936488050'/>
96
+ <enum name='SystemEventsMvszCurrent' value='1668641652'/>
97
+ <enum name='SystemEventsMvszDouble' value='1685026146'/>
98
+ <enum name='SystemEventsMvszHalf' value='1751215206'/>
99
+ <enum name='SystemEventsMvszNormal' value='1852797549'/>
100
+ <enum name='SystemEventsMvszScreen' value='1718187123'/>
101
+ <enum name='SystemEventsPrmdNormal' value='1852797549'/>
102
+ <enum name='SystemEventsPrmdSlideShow' value='1886221171'/>
103
+ <enum name='SystemEventsSavoAsk' value='1634954016'/>
104
+ <enum name='SystemEventsSavoNo' value='1852776480'/>
105
+ <enum name='SystemEventsSavoYes' value='2036691744'/>
106
+ <enum name='SystemEventsSclbJumpToHere' value='1953458290'/>
107
+ <enum name='SystemEventsSclbJumpToNextPage' value='1853386855'/>
108
+ <enum name='SystemEventsSclpTogether' value='1952937064'/>
109
+ <enum name='SystemEventsSclpTogetherAtTopAndBottom' value='1952937058'/>
110
+ <enum name='SystemEventsSclpTopAndBottom' value='1953522292'/>
111
+ <class name='SystemEventsAlias'>
112
+ <method selector='printPrintDialog:withProperties:'>
113
+ <arg type='B' index='0'/>
114
+ </method>
115
+ <method selector='setStationery:'>
116
+ <arg type='B' index='0'/>
117
+ </method>
118
+ <method selector='stationery'>
119
+ <retval type='B'/>
120
+ </method>
121
+ </class>
122
+ <class name='SystemEventsAppearancePreferencesObject'>
123
+ <method selector='doubleClickMinimizes'>
124
+ <retval type='B'/>
125
+ </method>
126
+ <method selector='fontSmoothing'>
127
+ <retval type='B'/>
128
+ </method>
129
+ <method selector='setDoubleClickMinimizes:'>
130
+ <arg type='B' index='0'/>
131
+ </method>
132
+ <method selector='setFontSmoothing:'>
133
+ <arg type='B' index='0'/>
134
+ </method>
135
+ <method selector='setSmoothScrolling:'>
136
+ <arg type='B' index='0'/>
137
+ </method>
138
+ <method selector='smoothScrolling'>
139
+ <retval type='B'/>
140
+ </method>
141
+ </class>
142
+ <class name='SystemEventsApplication'>
143
+ <method selector='UIElementsEnabled'>
144
+ <retval type='B'/>
145
+ </method>
146
+ <method selector='folderActionsEnabled'>
147
+ <retval type='B'/>
148
+ </method>
149
+ <method selector='frontmost'>
150
+ <retval type='B'/>
151
+ </method>
152
+ <method selector='scriptMenuEnabled'>
153
+ <retval type='B'/>
154
+ </method>
155
+ <method selector='setFolderActionsEnabled:'>
156
+ <arg type='B' index='0'/>
157
+ </method>
158
+ <method selector='setUIElementsEnabled:'>
159
+ <arg type='B' index='0'/>
160
+ </method>
161
+ </class>
162
+ <class name='SystemEventsAttribute'>
163
+ <method selector='settable'>
164
+ <retval type='B'/>
165
+ </method>
166
+ </class>
167
+ <class name='SystemEventsConfiguration'>
168
+ <method selector='connected'>
169
+ <retval type='B'/>
170
+ </method>
171
+ </class>
172
+ <class name='SystemEventsDesktop'>
173
+ <method selector='randomOrder'>
174
+ <retval type='B'/>
175
+ </method>
176
+ <method selector='setRandomOrder:'>
177
+ <arg type='B' index='0'/>
178
+ </method>
179
+ <method selector='setTranslucentMenuBar:'>
180
+ <arg type='B' index='0'/>
181
+ </method>
182
+ <method selector='translucentMenuBar'>
183
+ <retval type='B'/>
184
+ </method>
185
+ </class>
186
+ <class name='SystemEventsDisk'>
187
+ <method selector='ejectable'>
188
+ <retval type='B'/>
189
+ </method>
190
+ <method selector='ignorePrivileges'>
191
+ <retval type='B'/>
192
+ </method>
193
+ <method selector='localVolume'>
194
+ <retval type='B'/>
195
+ </method>
196
+ <method selector='setIgnorePrivileges:'>
197
+ <arg type='B' index='0'/>
198
+ </method>
199
+ <method selector='startup'>
200
+ <retval type='B'/>
201
+ </method>
202
+ </class>
203
+ <class name='SystemEventsDiskItem'>
204
+ <method selector='busyStatus'>
205
+ <retval type='B'/>
206
+ </method>
207
+ <method selector='packageFolder'>
208
+ <retval type='B'/>
209
+ </method>
210
+ <method selector='setVisible:'>
211
+ <arg type='B' index='0'/>
212
+ </method>
213
+ <method selector='visible'>
214
+ <retval type='B'/>
215
+ </method>
216
+ </class>
217
+ <class name='SystemEventsDockPreferencesObject'>
218
+ <method selector='animate'>
219
+ <retval type='B'/>
220
+ </method>
221
+ <method selector='autohide'>
222
+ <retval type='B'/>
223
+ </method>
224
+ <method selector='magnification'>
225
+ <retval type='B'/>
226
+ </method>
227
+ <method selector='setAnimate:'>
228
+ <arg type='B' index='0'/>
229
+ </method>
230
+ <method selector='setAutohide:'>
231
+ <arg type='B' index='0'/>
232
+ </method>
233
+ <method selector='setMagnification:'>
234
+ <arg type='B' index='0'/>
235
+ </method>
236
+ </class>
237
+ <class name='SystemEventsDocument'>
238
+ <method selector='modified'>
239
+ <retval type='B'/>
240
+ </method>
241
+ </class>
242
+ <class name='SystemEventsFile'>
243
+ <method selector='setStationery:'>
244
+ <arg type='B' index='0'/>
245
+ </method>
246
+ <method selector='stationery'>
247
+ <retval type='B'/>
248
+ </method>
249
+ </class>
250
+ <class name='SystemEventsFolderAction'>
251
+ <method selector='enabled'>
252
+ <retval type='B'/>
253
+ </method>
254
+ <method selector='setEnabled:'>
255
+ <arg type='B' index='0'/>
256
+ </method>
257
+ </class>
258
+ <class name='SystemEventsInterface'>
259
+ <method selector='automatic'>
260
+ <retval type='B'/>
261
+ </method>
262
+ <method selector='setAutomatic:'>
263
+ <arg type='B' index='0'/>
264
+ </method>
265
+ </class>
266
+ <class name='SystemEventsItem'>
267
+ <method selector='exists'>
268
+ <retval type='B'/>
269
+ </method>
270
+ </class>
271
+ <class name='SystemEventsLoginItem'>
272
+ <method selector='hidden'>
273
+ <retval type='B'/>
274
+ </method>
275
+ <method selector='setHidden:'>
276
+ <arg type='B' index='0'/>
277
+ </method>
278
+ </class>
279
+ <class name='SystemEventsPrintSettings'>
280
+ <method selector='collating'>
281
+ <retval type='B'/>
282
+ </method>
283
+ <method selector='exists'>
284
+ <retval type='B'/>
285
+ </method>
286
+ <method selector='setCollating:'>
287
+ <arg type='B' index='0'/>
288
+ </method>
289
+ </class>
290
+ <class name='SystemEventsProcess'>
291
+ <method selector='Classic'>
292
+ <retval type='B'/>
293
+ </method>
294
+ <method selector='acceptsHighLevelEvents'>
295
+ <retval type='B'/>
296
+ </method>
297
+ <method selector='acceptsRemoteEvents'>
298
+ <retval type='B'/>
299
+ </method>
300
+ <method selector='backgroundOnly'>
301
+ <retval type='B'/>
302
+ </method>
303
+ <method selector='frontmost'>
304
+ <retval type='B'/>
305
+ </method>
306
+ <method selector='hasScriptingTerminology'>
307
+ <retval type='B'/>
308
+ </method>
309
+ <method selector='setFrontmost:'>
310
+ <arg type='B' index='0'/>
311
+ </method>
312
+ <method selector='setVisible:'>
313
+ <arg type='B' index='0'/>
314
+ </method>
315
+ <method selector='visible'>
316
+ <retval type='B'/>
317
+ </method>
318
+ </class>
319
+ <class name='SystemEventsQuickTimeData'>
320
+ <method selector='autoPlay'>
321
+ <retval type='B'/>
322
+ </method>
323
+ <method selector='autoPresent'>
324
+ <retval type='B'/>
325
+ </method>
326
+ <method selector='autoQuitWhenDone'>
327
+ <retval type='B'/>
328
+ </method>
329
+ <method selector='looping'>
330
+ <retval type='B'/>
331
+ </method>
332
+ <method selector='storedStream'>
333
+ <retval type='B'/>
334
+ </method>
335
+ </class>
336
+ <class name='SystemEventsScreenSaverPreferencesObject'>
337
+ <method selector='mainScreenOnly'>
338
+ <retval type='B'/>
339
+ </method>
340
+ <method selector='running'>
341
+ <retval type='B'/>
342
+ </method>
343
+ <method selector='setMainScreenOnly:'>
344
+ <arg type='B' index='0'/>
345
+ </method>
346
+ <method selector='setShowClock:'>
347
+ <arg type='B' index='0'/>
348
+ </method>
349
+ <method selector='showClock'>
350
+ <retval type='B'/>
351
+ </method>
352
+ </class>
353
+ <class name='SystemEventsScript'>
354
+ <method selector='enabled'>
355
+ <retval type='B'/>
356
+ </method>
357
+ <method selector='setEnabled:'>
358
+ <arg type='B' index='0'/>
359
+ </method>
360
+ </class>
361
+ <class name='SystemEventsSecurityPreferencesObject'>
362
+ <method selector='automaticLogin'>
363
+ <retval type='B'/>
364
+ </method>
365
+ <method selector='logOutWhenInactive'>
366
+ <retval type='B'/>
367
+ </method>
368
+ <method selector='requirePasswordToUnlock'>
369
+ <retval type='B'/>
370
+ </method>
371
+ <method selector='requirePasswordToWake'>
372
+ <retval type='B'/>
373
+ </method>
374
+ <method selector='secureVirtualMemory'>
375
+ <retval type='B'/>
376
+ </method>
377
+ <method selector='setAutomaticLogin:'>
378
+ <arg type='B' index='0'/>
379
+ </method>
380
+ <method selector='setLogOutWhenInactive:'>
381
+ <arg type='B' index='0'/>
382
+ </method>
383
+ <method selector='setRequirePasswordToUnlock:'>
384
+ <arg type='B' index='0'/>
385
+ </method>
386
+ <method selector='setRequirePasswordToWake:'>
387
+ <arg type='B' index='0'/>
388
+ </method>
389
+ <method selector='setSecureVirtualMemory:'>
390
+ <arg type='B' index='0'/>
391
+ </method>
392
+ </class>
393
+ <class name='SystemEventsService'>
394
+ <method selector='active'>
395
+ <retval type='B'/>
396
+ </method>
397
+ </class>
398
+ <class name='SystemEventsSpacesPreferencesObject'>
399
+ <method selector='setSpacesEnabled:'>
400
+ <arg type='B' index='0'/>
401
+ </method>
402
+ <method selector='spacesEnabled'>
403
+ <retval type='B'/>
404
+ </method>
405
+ </class>
406
+ <class name='SystemEventsTrack'>
407
+ <method selector='audioCharacteristic'>
408
+ <retval type='B'/>
409
+ </method>
410
+ <method selector='enabled'>
411
+ <retval type='B'/>
412
+ </method>
413
+ <method selector='highQuality'>
414
+ <retval type='B'/>
415
+ </method>
416
+ <method selector='setEnabled:'>
417
+ <arg type='B' index='0'/>
418
+ </method>
419
+ <method selector='setHighQuality:'>
420
+ <arg type='B' index='0'/>
421
+ </method>
422
+ <method selector='visualCharacteristic'>
423
+ <retval type='B'/>
424
+ </method>
425
+ </class>
426
+ <class name='SystemEventsUIElement'>
427
+ <method selector='enabled'>
428
+ <retval type='B'/>
429
+ </method>
430
+ <method selector='focused'>
431
+ <retval type='B'/>
432
+ </method>
433
+ <method selector='selected'>
434
+ <retval type='B'/>
435
+ </method>
436
+ <method selector='setFocused:'>
437
+ <arg type='B' index='0'/>
438
+ </method>
439
+ <method selector='setSelected:'>
440
+ <arg type='B' index='0'/>
441
+ </method>
442
+ </class>
443
+ <class name='SystemEventsWindow'>
444
+ <method selector='closeable'>
445
+ <retval type='B'/>
446
+ </method>
447
+ <method selector='floating'>
448
+ <retval type='B'/>
449
+ </method>
450
+ <method selector='miniaturizable'>
451
+ <retval type='B'/>
452
+ </method>
453
+ <method selector='miniaturized'>
454
+ <retval type='B'/>
455
+ </method>
456
+ <method selector='modal'>
457
+ <retval type='B'/>
458
+ </method>
459
+ <method selector='resizable'>
460
+ <retval type='B'/>
461
+ </method>
462
+ <method selector='setMiniaturized:'>
463
+ <arg type='B' index='0'/>
464
+ </method>
465
+ <method selector='setVisible:'>
466
+ <arg type='B' index='0'/>
467
+ </method>
468
+ <method selector='setZoomed:'>
469
+ <arg type='B' index='0'/>
470
+ </method>
471
+ <method selector='titled'>
472
+ <retval type='B'/>
473
+ </method>
474
+ <method selector='visible'>
475
+ <retval type='B'/>
476
+ </method>
477
+ <method selector='zoomable'>
478
+ <retval type='B'/>
479
+ </method>
480
+ <method selector='zoomed'>
481
+ <retval type='B'/>
482
+ </method>
483
+ </class>
484
+ </signatures>
@@ -0,0 +1,158 @@
1
+ <?xml version='1.0'?>
2
+ <!DOCTYPE signatures SYSTEM "file://localhost/System/Library/DTDs/BridgeSupport.dtd">
3
+ <signatures version='0.9'>
4
+ <enum name='TerminalPrintingErrorHandlingDetailed' value='1819763828'/>
5
+ <enum name='TerminalPrintingErrorHandlingStandard' value='1819767668'/>
6
+ <enum name='TerminalSaveOptionsAsk' value='1634954016'/>
7
+ <enum name='TerminalSaveOptionsNo' value='1852776480'/>
8
+ <enum name='TerminalSaveOptionsYes' value='2036691744'/>
9
+ <class name='TerminalApplication'>
10
+ <method selector='frontmost'>
11
+ <retval type='B'/>
12
+ </method>
13
+ <method selector='print:withProperties:printDialog:'>
14
+ <arg type='B' index='2'/>
15
+ </method>
16
+ </class>
17
+ <class name='TerminalSettingsSet'>
18
+ <method selector='exists'>
19
+ <retval type='B'/>
20
+ </method>
21
+ <method selector='fontAntialiasing'>
22
+ <retval type='B'/>
23
+ </method>
24
+ <method selector='printWithProperties:printDialog:'>
25
+ <arg type='B' index='1'/>
26
+ </method>
27
+ <method selector='setFontAntialiasing:'>
28
+ <arg type='B' index='0'/>
29
+ </method>
30
+ <method selector='setTitleDisplaysCustomTitle:'>
31
+ <arg type='B' index='0'/>
32
+ </method>
33
+ <method selector='setTitleDisplaysDeviceName:'>
34
+ <arg type='B' index='0'/>
35
+ </method>
36
+ <method selector='setTitleDisplaysSettingsName:'>
37
+ <arg type='B' index='0'/>
38
+ </method>
39
+ <method selector='setTitleDisplaysShellPath:'>
40
+ <arg type='B' index='0'/>
41
+ </method>
42
+ <method selector='setTitleDisplaysWindowSize:'>
43
+ <arg type='B' index='0'/>
44
+ </method>
45
+ <method selector='titleDisplaysCustomTitle'>
46
+ <retval type='B'/>
47
+ </method>
48
+ <method selector='titleDisplaysDeviceName'>
49
+ <retval type='B'/>
50
+ </method>
51
+ <method selector='titleDisplaysSettingsName'>
52
+ <retval type='B'/>
53
+ </method>
54
+ <method selector='titleDisplaysShellPath'>
55
+ <retval type='B'/>
56
+ </method>
57
+ <method selector='titleDisplaysWindowSize'>
58
+ <retval type='B'/>
59
+ </method>
60
+ </class>
61
+ <class name='TerminalTab'>
62
+ <method selector='busy'>
63
+ <retval type='B'/>
64
+ </method>
65
+ <method selector='exists'>
66
+ <retval type='B'/>
67
+ </method>
68
+ <method selector='fontAntialiasing'>
69
+ <retval type='B'/>
70
+ </method>
71
+ <method selector='printWithProperties:printDialog:'>
72
+ <arg type='B' index='1'/>
73
+ </method>
74
+ <method selector='selected'>
75
+ <retval type='B'/>
76
+ </method>
77
+ <method selector='setFontAntialiasing:'>
78
+ <arg type='B' index='0'/>
79
+ </method>
80
+ <method selector='setSelected:'>
81
+ <arg type='B' index='0'/>
82
+ </method>
83
+ <method selector='setTitleDisplaysCustomTitle:'>
84
+ <arg type='B' index='0'/>
85
+ </method>
86
+ <method selector='setTitleDisplaysDeviceName:'>
87
+ <arg type='B' index='0'/>
88
+ </method>
89
+ <method selector='setTitleDisplaysFileName:'>
90
+ <arg type='B' index='0'/>
91
+ </method>
92
+ <method selector='setTitleDisplaysShellPath:'>
93
+ <arg type='B' index='0'/>
94
+ </method>
95
+ <method selector='setTitleDisplaysWindowSize:'>
96
+ <arg type='B' index='0'/>
97
+ </method>
98
+ <method selector='titleDisplaysCustomTitle'>
99
+ <retval type='B'/>
100
+ </method>
101
+ <method selector='titleDisplaysDeviceName'>
102
+ <retval type='B'/>
103
+ </method>
104
+ <method selector='titleDisplaysFileName'>
105
+ <retval type='B'/>
106
+ </method>
107
+ <method selector='titleDisplaysShellPath'>
108
+ <retval type='B'/>
109
+ </method>
110
+ <method selector='titleDisplaysWindowSize'>
111
+ <retval type='B'/>
112
+ </method>
113
+ </class>
114
+ <class name='TerminalWindow'>
115
+ <method selector='closeable'>
116
+ <retval type='B'/>
117
+ </method>
118
+ <method selector='exists'>
119
+ <retval type='B'/>
120
+ </method>
121
+ <method selector='frontmost'>
122
+ <retval type='B'/>
123
+ </method>
124
+ <method selector='miniaturizable'>
125
+ <retval type='B'/>
126
+ </method>
127
+ <method selector='miniaturized'>
128
+ <retval type='B'/>
129
+ </method>
130
+ <method selector='printWithProperties:printDialog:'>
131
+ <arg type='B' index='1'/>
132
+ </method>
133
+ <method selector='resizable'>
134
+ <retval type='B'/>
135
+ </method>
136
+ <method selector='setFrontmost:'>
137
+ <arg type='B' index='0'/>
138
+ </method>
139
+ <method selector='setMiniaturized:'>
140
+ <arg type='B' index='0'/>
141
+ </method>
142
+ <method selector='setVisible:'>
143
+ <arg type='B' index='0'/>
144
+ </method>
145
+ <method selector='setZoomed:'>
146
+ <arg type='B' index='0'/>
147
+ </method>
148
+ <method selector='visible'>
149
+ <retval type='B'/>
150
+ </method>
151
+ <method selector='zoomable'>
152
+ <retval type='B'/>
153
+ </method>
154
+ <method selector='zoomed'>
155
+ <retval type='B'/>
156
+ </method>
157
+ </class>
158
+ </signatures>
@@ -0,0 +1,28 @@
1
+ load_bridge_support_file File.dirname(__FILE__) + '/bridgesupport/SystemEvents.bridgesupport'
2
+
3
+ class Mynu
4
+ module Support
5
+ class System
6
+ attr_accessor :system
7
+
8
+ CommandDown = SystemEventsEMdsCommandDown
9
+ ControlDown = SystemEventsEMdsControlDown
10
+ OptionDown = SystemEventsEMdsOptionDown
11
+ ShiftDown = SystemEventsEMdsShiftDown
12
+
13
+ def initialize
14
+ self.system = SBApplication.applicationWithBundleIdentifier("com.apple.SystemEvents")
15
+ end
16
+
17
+ # wrapping a native selector
18
+ def keystroke(keys, using=0)
19
+ @system.send(:"keystroke:using:", keys, using)
20
+ end
21
+
22
+ def method_missing(method, *args)
23
+ args.empty? ? @system.send(method) : @system.send(method, args)
24
+ end
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,76 @@
1
+ load_bridge_support_file File.dirname(__FILE__) + '/bridgesupport/Terminal.bridgesupport'
2
+
3
+ class Mynu
4
+ module Support
5
+ class Terminal
6
+ attr_accessor :system
7
+ attr_accessor :terminal
8
+
9
+ def initialize
10
+ self.system = Mynu::Support::System.new
11
+ self.terminal = SBApplication.applicationWithBundleIdentifier("com.apple.Terminal")
12
+ end
13
+
14
+ def method_missing(method, *args)
15
+ args.empty? ? @terminal.send(method) : @terminal.send(method, args)
16
+ end
17
+
18
+ def wait_for_terminal_tab(terminal_tab)
19
+ while(terminal_tab.busy)
20
+ sleep 0.25
21
+ end
22
+ end
23
+
24
+ # For terminal.app I use an SIMBL plugin called Visor, this intergates tab support for your primary (first) window
25
+ # If someone wants to write support for multiple windows, it would help the project a lot!
26
+ def create_tab(command, options = {})
27
+ options = {
28
+ :exit => false,
29
+ :focus => false
30
+ }.merge(options)
31
+
32
+ current_process = nil
33
+ terminal_process = nil
34
+
35
+ terminals = self.windows.first.tabs.map do |terminal_tab|
36
+ terminal_tab
37
+ end
38
+
39
+ system.processes.each do |process|
40
+ current_process = process if process.frontmost
41
+ end
42
+ system.processes.each do |process|
43
+ terminal_process = process if process.shortName == "Terminal"
44
+ end
45
+
46
+ terminal_process.setFrontmost true
47
+ system.keystroke "t", Mynu::Support::System::CommandDown
48
+ system.keystroke "#{command}\r" if command.length > 0
49
+
50
+ current_terminals = self.windows.first.tabs.map do |terminal_tab|
51
+ terminal_tab
52
+ end
53
+
54
+ new_terminal_tab = nil
55
+ current_terminals.each do |terminal_tab|
56
+ new_terminal_tab = terminal_tab unless terminals.include?(terminal_tab)
57
+ end
58
+
59
+ # exit the new tab
60
+ if options[:exit]
61
+ # broken:
62
+ # new_terminal_tab.send(:"closeSaving:savingIn:", TerminalSaveOptionsNo, nil)
63
+ wait_for_terminal_tab(new_terminal_tab)
64
+ system.keystroke("exit\r")
65
+ wait_for_terminal_tab(new_terminal_tab)
66
+ system.keystroke "w", Mynu::Support::System::CommandDown
67
+ end
68
+
69
+ current_process.setFrontmost true unless options[:focus]
70
+
71
+ new_terminal_tab
72
+ end
73
+ end
74
+ end
75
+ end
76
+
@@ -1,8 +1,8 @@
1
1
  class Mynu
2
2
  module Version
3
3
  MAJOR = 0
4
- MINOR = 2
5
- PATCH = 5
4
+ MINOR = 3
5
+ PATCH = 0
6
6
  BUILD = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
@@ -24,6 +24,11 @@ Gem::Specification.new do |s|
24
24
  "mynu.gemspec",
25
25
  "lib/mynu.rb",
26
26
  "lib/mynu/assets/logo.png",
27
+ "lib/mynu/support.rb",
28
+ "lib/mynu/support/system.rb",
29
+ "lib/mynu/support/terminal.rb",
30
+ "lib/mynu/support/bridgesupport/Terminal.bridgesupport",
31
+ "lib/mynu/support/bridgesupport/SystemEvents.bridgesupport",
27
32
  "lib/mynu/menu.rb",
28
33
  "lib/mynu/menu/menu_item.rb",
29
34
  "lib/mynu/menu/block_menu_item.rb",
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: mynu
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.5
5
+ version: 0.3.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Rob Lowe
@@ -61,6 +61,11 @@ files:
61
61
  - mynu.gemspec
62
62
  - lib/mynu.rb
63
63
  - lib/mynu/assets/logo.png
64
+ - lib/mynu/support.rb
65
+ - lib/mynu/support/system.rb
66
+ - lib/mynu/support/terminal.rb
67
+ - lib/mynu/support/bridgesupport/Terminal.bridgesupport
68
+ - lib/mynu/support/bridgesupport/SystemEvents.bridgesupport
64
69
  - lib/mynu/menu.rb
65
70
  - lib/mynu/menu/menu_item.rb
66
71
  - lib/mynu/menu/block_menu_item.rb