mynu 0.2.5 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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