bowline 0.5.3 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.txt +62 -62
- data/Rakefile +10 -0
- data/TODO +3 -1
- data/VERSION +1 -1
- data/assets/bowline.js +118 -3
- data/bowline.gemspec +6 -6
- data/examples/example.js +2 -15
- data/examples/tweet.rb +35 -0
- data/examples/tweets_binder.rb +6 -0
- data/examples/twitter.html +6 -8
- data/examples/users.rb +8 -14
- data/lib/bowline/binders.rb +130 -42
- data/lib/bowline/dependencies/lib/dependencies.rb +2 -1
- data/lib/bowline/dependencies/lib/ext/rubygems.rb +4 -4
- data/lib/bowline/desktop.rb +11 -2
- data/lib/bowline/desktop/app.rb +7 -3
- data/lib/bowline/desktop/bridge.rb +8 -9
- data/lib/bowline/desktop/clipboard.rb +11 -2
- data/lib/bowline/desktop/dialog.rb +19 -0
- data/lib/bowline/desktop/dock.rb +14 -3
- data/lib/bowline/desktop/host.rb +13 -4
- data/lib/bowline/desktop/js.rb +2 -2
- data/lib/bowline/desktop/misc.rb +7 -3
- data/lib/bowline/desktop/network.rb +1 -1
- data/lib/bowline/desktop/proxy.rb +28 -30
- data/lib/bowline/desktop/sound.rb +3 -2
- data/lib/bowline/desktop/window.rb +147 -21
- data/lib/bowline/desktop/window_manager.rb +53 -5
- data/lib/bowline/desktop/window_methods.rb +2 -2
- data/lib/bowline/ext/object.rb +1 -1
- data/lib/bowline/generators.rb +1 -1
- data/lib/bowline/generators/binder.rb +1 -1
- data/lib/bowline/helpers.rb +1 -1
- data/lib/bowline/initializer.rb +37 -4
- data/lib/bowline/library.rb +11 -0
- data/lib/bowline/local_model.rb +45 -19
- data/lib/bowline/logging.rb +1 -1
- data/lib/bowline/platform.rb +8 -6
- data/lib/bowline/tasks/app.rake +4 -3
- data/lib/bowline/version.rb +1 -1
- data/lib/bowline/watcher.rb +18 -8
- data/templates/binder.rb +1 -1
- data/vendor/pathname.rb +0 -4
- metadata +6 -6
- data/examples/account.rb +0 -31
- data/examples/tweets.rb +0 -28
@@ -1,5 +1,24 @@
|
|
1
1
|
module Bowline
|
2
2
|
module Desktop
|
3
|
+
# This class provides a useful abstraction on the Window class.
|
4
|
+
# It's the usual way of interfacing with your application's windows,
|
5
|
+
# and all of Bowline's windows normally inherit from it.
|
6
|
+
#
|
7
|
+
# You'll need to call the setup method, before calling using this class.
|
8
|
+
# If the window is deallocated (i.e. closed), you'll need to call it again.
|
9
|
+
# It's worth not calling the setup method before you need it, since it'll
|
10
|
+
# increase the amount of CPU your application uses.
|
11
|
+
#
|
12
|
+
# By default, windows are hidden. You'll need to show your custom windows explicitly
|
13
|
+
# before any user interaction using the show method. You can still load HTML/JavaScript
|
14
|
+
# while the window is hidden.
|
15
|
+
#
|
16
|
+
# If you don't want to show the window until it's properly loaded, you can use this pattern:
|
17
|
+
# MyWindow.on_load { MyWindow.show }
|
18
|
+
# MyWindow.file = :test
|
19
|
+
#
|
20
|
+
# Any undefined methods are delegated to the Window class.
|
21
|
+
# See that class for the full windowing API.
|
3
22
|
class WindowManager
|
4
23
|
extend Bridge::ClassMethods
|
5
24
|
js_expose
|
@@ -8,21 +27,24 @@ module Bowline
|
|
8
27
|
watch :on_load
|
9
28
|
|
10
29
|
class << self
|
30
|
+
# An array of all the application's windows
|
11
31
|
def windows
|
12
|
-
subclasses.map(&:constantize)
|
32
|
+
Bowline::Desktop::WindowManager.subclasses.map(&:constantize)
|
13
33
|
end
|
14
34
|
|
35
|
+
# An array of all the application's windows that are currently shown
|
15
36
|
def shown_windows
|
16
37
|
windows.select(&:shown?)
|
17
38
|
end
|
18
39
|
|
40
|
+
# An array of all the application's allocated windows
|
19
41
|
def allocated_windows
|
20
42
|
windows.select(&:allocated?)
|
21
43
|
end
|
22
44
|
|
23
45
|
# Methods for subclasses:
|
24
46
|
|
25
|
-
def window
|
47
|
+
def window #:nodoc:
|
26
48
|
@window
|
27
49
|
end
|
28
50
|
|
@@ -30,6 +52,9 @@ module Bowline
|
|
30
52
|
!!@window
|
31
53
|
end
|
32
54
|
|
55
|
+
# Call this method to allocate a new window.
|
56
|
+
# You'll need to do this before using it,
|
57
|
+
# or after it has been closed.
|
33
58
|
def setup
|
34
59
|
return unless Desktop.enabled?
|
35
60
|
return if @window && !@window.dealocated?
|
@@ -39,19 +64,42 @@ module Bowline
|
|
39
64
|
@window = Window.new
|
40
65
|
end
|
41
66
|
end
|
42
|
-
|
67
|
+
|
68
|
+
# Evaluate JavaScript in this window. Pass
|
69
|
+
# a block to capture the result.
|
70
|
+
# Example:
|
71
|
+
# eval("Bowline.msgs") {|res| puts res }
|
43
72
|
def eval(*args, &block)
|
44
73
|
JS.eval(window, *args, &block)
|
45
74
|
end
|
46
75
|
|
76
|
+
# Window Proxy instance. Use this to evaluate JavaScript
|
77
|
+
# in this window, but in an object orientated way.
|
78
|
+
# Example:
|
79
|
+
# page.yourFunc.call
|
80
|
+
#
|
81
|
+
# See Bowline::Desktop::Proxy for full usage.
|
47
82
|
def page
|
48
|
-
Proxy.new(
|
83
|
+
Proxy.new(self)
|
84
|
+
end
|
85
|
+
|
86
|
+
def bowline
|
87
|
+
page.Bowline
|
49
88
|
end
|
50
89
|
|
90
|
+
# Returns true if the both the HTML and JavaScript in
|
91
|
+
# this window have loaded. Use the on_load event to know
|
92
|
+
# when this window has loaded.
|
51
93
|
def loaded?
|
52
94
|
@loaded
|
53
95
|
end
|
54
96
|
|
97
|
+
##
|
98
|
+
# :singleton-method: on_load(method = nil, &block)
|
99
|
+
# A Watcher event method that gets called when this window loads.
|
100
|
+
# Example:
|
101
|
+
# on_load { puts "Window loaded!" }
|
102
|
+
|
55
103
|
def loaded! # :nodoc:
|
56
104
|
@loaded = true
|
57
105
|
watcher.call(:on_load)
|
@@ -59,7 +107,7 @@ module Bowline
|
|
59
107
|
end
|
60
108
|
|
61
109
|
# Delegate most methods to Window
|
62
|
-
def method_missing(sym, *args)
|
110
|
+
def method_missing(sym, *args) #:nodoc:
|
63
111
|
if window && window.respond_to?(sym)
|
64
112
|
return window.send(sym, *args)
|
65
113
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Bowline
|
2
2
|
module Desktop
|
3
|
-
module WindowMethods
|
3
|
+
module WindowMethods #:nodoc:
|
4
4
|
def center(direction = nil)
|
5
5
|
direction =
|
6
6
|
case direction
|
@@ -63,7 +63,7 @@ module Bowline
|
|
63
63
|
# The methods won't exist on window
|
64
64
|
# if Bowline::Desktop isn't enabled
|
65
65
|
def method_missing(sym, *args)
|
66
|
-
Bowline::Desktop.enabled? ?
|
66
|
+
Bowline::Desktop.enabled? ? super : nil
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
data/lib/bowline/ext/object.rb
CHANGED
data/lib/bowline/generators.rb
CHANGED
data/lib/bowline/helpers.rb
CHANGED
data/lib/bowline/initializer.rb
CHANGED
@@ -7,7 +7,7 @@ module Bowline
|
|
7
7
|
@@configuration
|
8
8
|
end
|
9
9
|
|
10
|
-
def configuration=(configuration)
|
10
|
+
def configuration=(configuration) #:nodoc:
|
11
11
|
@@configuration = configuration
|
12
12
|
end
|
13
13
|
|
@@ -15,10 +15,12 @@ module Bowline
|
|
15
15
|
@initialized || false
|
16
16
|
end
|
17
17
|
|
18
|
-
def initialized=(initialized)
|
18
|
+
def initialized=(initialized) #:nodoc:
|
19
19
|
@initialized ||= initialized
|
20
20
|
end
|
21
21
|
|
22
|
+
# The default Bowline logger.
|
23
|
+
# Also see the Bowline::Logging class.
|
22
24
|
def logger
|
23
25
|
if defined?(BOWLINE_LOGGER)
|
24
26
|
BOWLINE_LOGGER
|
@@ -27,12 +29,13 @@ module Bowline
|
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
32
|
+
# The application's root
|
30
33
|
def root
|
31
34
|
Pathname.new(APP_ROOT) if defined?(APP_ROOT)
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
35
|
-
class Initializer
|
38
|
+
class Initializer #:nodoc:
|
36
39
|
# The Configuration instance used by this Initializer instance.
|
37
40
|
attr_reader :configuration
|
38
41
|
|
@@ -58,6 +61,7 @@ module Bowline
|
|
58
61
|
@loaded_plugins = []
|
59
62
|
end
|
60
63
|
|
64
|
+
# Add all of Ruby's stdlib to the load path
|
61
65
|
def initialize_ruby
|
62
66
|
return unless Bowline::Desktop.enabled?
|
63
67
|
ruby_path = Bowline::Library.local_rubylib_path
|
@@ -65,6 +69,10 @@ module Bowline
|
|
65
69
|
ruby_path = Bowline::Library.rubylib_path
|
66
70
|
return unless File.directory?(ruby_path)
|
67
71
|
end
|
72
|
+
# Remove old stdlib load paths
|
73
|
+
$:.delete_if {|path| path =~ /^\/usr\// }
|
74
|
+
|
75
|
+
# Add new stdlib load paths
|
68
76
|
version = Library::RUBY_LIB_VERSION
|
69
77
|
platform = Library::RUBY_ARCHLIB_PLATFORM
|
70
78
|
$: << File.join(ruby_path, version) # RUBY_LIB
|
@@ -75,9 +83,10 @@ module Bowline
|
|
75
83
|
$: << File.join(ruby_path, "vendor_ruby") # RUBY_VENDOR_LIB
|
76
84
|
$: << File.join(ruby_path, "vendor_ruby", version) # RUBY_VENDOR_LIB2
|
77
85
|
$: << File.join(ruby_path, "vendor_ruby", version, platform) # RUBY_VENDOR_ARCHLIB
|
86
|
+
|
87
|
+
# These two need to be required to fully setup internationalization
|
78
88
|
require File.join(*%w[enc encdb])
|
79
89
|
require File.join(*%w[enc trans transdb])
|
80
|
-
$:.uniq!
|
81
90
|
end
|
82
91
|
|
83
92
|
def require_frameworks
|
@@ -119,6 +128,7 @@ module Bowline
|
|
119
128
|
$LOAD_PATH.uniq!
|
120
129
|
end
|
121
130
|
|
131
|
+
# Initializes ActiveRecord databases
|
122
132
|
def initialize_database
|
123
133
|
if defined?(ActiveRecord)
|
124
134
|
ActiveRecord::Base.establish_connection(configuration.database_configuration)
|
@@ -268,6 +278,8 @@ module Bowline
|
|
268
278
|
silence_warnings { Object.const_set "APP_NAME", configuration.name }
|
269
279
|
end
|
270
280
|
|
281
|
+
# Creates a class called AppConfig from configuration
|
282
|
+
# variables found in config/application.yml
|
271
283
|
def load_app_config
|
272
284
|
app_config = configuration.app_config
|
273
285
|
return unless app_config
|
@@ -446,13 +458,34 @@ module Bowline
|
|
446
458
|
|
447
459
|
attr_accessor :initializer_glob
|
448
460
|
|
461
|
+
# Set the path that MainWindow will load
|
462
|
+
# when the application starts.
|
449
463
|
attr_accessor :index_path
|
450
464
|
|
465
|
+
# Set the application's name.
|
466
|
+
# This is required.
|
451
467
|
attr_accessor :name
|
468
|
+
|
469
|
+
# Set the application's globally unique id.
|
470
|
+
# This is required.
|
471
|
+
# Example:
|
472
|
+
# config.id = "com.maccman.bowline"
|
452
473
|
attr_accessor :id
|
474
|
+
|
475
|
+
# Set the application's version.
|
476
|
+
# Example:
|
477
|
+
# config.version = "0.1.2"
|
453
478
|
attr_accessor :version
|
479
|
+
|
454
480
|
attr_accessor :description
|
455
481
|
attr_accessor :url
|
482
|
+
|
483
|
+
# Set the application's icon.
|
484
|
+
# Point this variable to the icons path.
|
485
|
+
#
|
486
|
+
# If this isn't specified, Bowline's default one will be used.
|
487
|
+
#
|
488
|
+
# Supported icon files are PNGs and JPGs, preferably 512px x 512px.
|
456
489
|
attr_accessor :icon
|
457
490
|
|
458
491
|
attr_accessor :publisher
|
data/lib/bowline/library.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
module Bowline
|
2
|
+
# Provides paths to Bowline's required libraries.
|
2
3
|
module Library
|
3
4
|
RUBY_LIB_VERSION = "1.9.1"
|
4
5
|
RUBY_ARCHLIB_PLATFORM = "i386-darwin9.8.0"
|
@@ -6,6 +7,8 @@ module Bowline
|
|
6
7
|
DESKTOP_URL = "#{PROJECT_URL}/bowline-desktop"
|
7
8
|
RUBYLIB_URL = "#{PROJECT_URL}/rubylib.zip"
|
8
9
|
|
10
|
+
# Path to a folder stored under the users
|
11
|
+
# home directory containing the downloaded libraries.
|
9
12
|
def path
|
10
13
|
File.expand_path(
|
11
14
|
File.join(home_path, ".bowline")
|
@@ -13,11 +16,13 @@ module Bowline
|
|
13
16
|
end
|
14
17
|
module_function :path
|
15
18
|
|
19
|
+
# Path to the bowline-desktop binary
|
16
20
|
def desktop_path
|
17
21
|
File.join(path, "bowline-desktop")
|
18
22
|
end
|
19
23
|
module_function :desktop_path
|
20
24
|
|
25
|
+
# Path to Ruby's stdlib
|
21
26
|
def rubylib_path
|
22
27
|
File.join(path, "rubylib")
|
23
28
|
end
|
@@ -33,6 +38,12 @@ module Bowline
|
|
33
38
|
end
|
34
39
|
module_function :local_rubylib_path
|
35
40
|
|
41
|
+
def local_build_path
|
42
|
+
File.join(APP_ROOT, "build")
|
43
|
+
end
|
44
|
+
module_function :local_build_path
|
45
|
+
|
46
|
+
# Returns true if all required libraries exist.
|
36
47
|
def ready?
|
37
48
|
File.exist?(desktop_path) &&
|
38
49
|
File.directory?(rubylib_path) &&
|
data/lib/bowline/local_model.rb
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
module Bowline
|
2
|
+
# The LocalModel class mirrors ActiveRecord's api, and is used for
|
3
|
+
# models you want to hold in memory.
|
4
|
+
#
|
5
|
+
# You can also use this class in conjunction with Bowline's binders.
|
6
|
+
#
|
7
|
+
# All normal ActiveRecord callbacks are supported, such as before_save and after_save.
|
8
|
+
#
|
9
|
+
# Associations are not currently supported.
|
2
10
|
class LocalModel
|
3
11
|
extend Watcher::Base
|
4
12
|
|
@@ -6,47 +14,60 @@ module Bowline
|
|
6
14
|
:before_create, :after_create,
|
7
15
|
:before_update, :after_update,
|
8
16
|
:before_destroy, :after_destroy
|
9
|
-
|
10
|
-
@@records = []
|
11
|
-
|
17
|
+
|
12
18
|
class << self
|
19
|
+
def records
|
20
|
+
@records ||= []
|
21
|
+
end
|
22
|
+
|
23
|
+
# Populate the model with the array argument.
|
24
|
+
# This doesn't replace the model's existing records.
|
25
|
+
# Create callbacks are still executed.
|
13
26
|
def populate(array)
|
14
27
|
array.each {|r| create(r) }
|
15
28
|
end
|
16
|
-
|
29
|
+
|
30
|
+
# Find record by ID, or raise.
|
17
31
|
def find(id)
|
18
|
-
|
32
|
+
records.find {|r| r.id == id } || raise('Unknown Record')
|
19
33
|
end
|
20
34
|
alias :[] :find
|
21
35
|
|
22
36
|
def first
|
23
|
-
|
37
|
+
records[0]
|
24
38
|
end
|
25
39
|
|
26
40
|
def last
|
27
|
-
|
41
|
+
records[-1]
|
28
42
|
end
|
29
43
|
|
30
44
|
def count
|
31
|
-
|
45
|
+
records.length
|
32
46
|
end
|
33
47
|
|
34
48
|
def all
|
35
|
-
|
49
|
+
records
|
36
50
|
end
|
37
|
-
|
51
|
+
|
38
52
|
def destroy(id)
|
39
53
|
find(id).destroy
|
40
54
|
end
|
41
55
|
|
56
|
+
# Removes all records and executes
|
57
|
+
# destory callbacks.
|
42
58
|
def destroy_all
|
43
|
-
|
59
|
+
records.dup.each {|r| r.destroy }
|
44
60
|
end
|
45
61
|
|
62
|
+
# Removes all records without executing
|
63
|
+
# destroy callbacks.
|
46
64
|
def delete_all
|
47
|
-
|
65
|
+
records.clear
|
48
66
|
end
|
49
|
-
|
67
|
+
|
68
|
+
# Create a new record.
|
69
|
+
# Example:
|
70
|
+
# create(:name => "foo", :id => 1)
|
50
71
|
def create(atts = {})
|
51
72
|
rec = self.new(atts)
|
52
73
|
rec.save && rec
|
@@ -54,7 +75,11 @@ module Bowline
|
|
54
75
|
end
|
55
76
|
|
56
77
|
attr_reader :attributes
|
57
|
-
|
78
|
+
|
79
|
+
# Initialize the record with an optional
|
80
|
+
# hash of attributes. If a :id attribute
|
81
|
+
# isn't passed, the instance's object id
|
82
|
+
# is used instead.
|
58
83
|
def initialize(atts = {})
|
59
84
|
@attributes = {}.with_indifferent_access
|
60
85
|
@attributes.replace(atts)
|
@@ -66,7 +91,8 @@ module Bowline
|
|
66
91
|
def id
|
67
92
|
@attributes[:id]
|
68
93
|
end
|
69
|
-
|
94
|
+
|
95
|
+
# Update record with a hash of new attributes.
|
70
96
|
def update(atts)
|
71
97
|
run_callbacks(:before_save)
|
72
98
|
run_callbacks(:before_update)
|
@@ -75,12 +101,12 @@ module Bowline
|
|
75
101
|
run_callbacks(:after_update)
|
76
102
|
true
|
77
103
|
end
|
78
|
-
|
104
|
+
|
79
105
|
def save
|
80
106
|
run_callbacks(:before_save)
|
81
107
|
if @new_record
|
82
108
|
run_callbacks(:before_create)
|
83
|
-
|
109
|
+
self.class.records << self
|
84
110
|
run_callbacks(:after_create)
|
85
111
|
@new_record = false
|
86
112
|
end
|
@@ -90,7 +116,7 @@ module Bowline
|
|
90
116
|
|
91
117
|
def destroy
|
92
118
|
run_callbacks(:before_destroy)
|
93
|
-
|
119
|
+
self.class.records.delete(self)
|
94
120
|
run_callbacks(:after_destroy)
|
95
121
|
true
|
96
122
|
end
|
@@ -110,7 +136,7 @@ module Bowline
|
|
110
136
|
|
111
137
|
private
|
112
138
|
def run_callbacks(callback)
|
113
|
-
self.class.watcher.call(callback)
|
139
|
+
self.class.watcher.call(callback, self)
|
114
140
|
end
|
115
141
|
end
|
116
142
|
end
|