hotcocoa 0.5

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.
Files changed (84) hide show
  1. data/History.txt +4 -0
  2. data/bin/hotcocoa +31 -0
  3. data/lib/hotcocoa/application_builder.rb +320 -0
  4. data/lib/hotcocoa/attributed_string.rb +143 -0
  5. data/lib/hotcocoa/behaviors.rb +7 -0
  6. data/lib/hotcocoa/data_sources/combo_box_data_source.rb +44 -0
  7. data/lib/hotcocoa/data_sources/table_data_source.rb +18 -0
  8. data/lib/hotcocoa/delegate_builder.rb +85 -0
  9. data/lib/hotcocoa/graphics/canvas.rb +836 -0
  10. data/lib/hotcocoa/graphics/color.rb +781 -0
  11. data/lib/hotcocoa/graphics/elements/particle.rb +75 -0
  12. data/lib/hotcocoa/graphics/elements/rope.rb +99 -0
  13. data/lib/hotcocoa/graphics/elements/sandpainter.rb +71 -0
  14. data/lib/hotcocoa/graphics/gradient.rb +63 -0
  15. data/lib/hotcocoa/graphics/image.rb +488 -0
  16. data/lib/hotcocoa/graphics/path.rb +325 -0
  17. data/lib/hotcocoa/graphics/pdf.rb +71 -0
  18. data/lib/hotcocoa/graphics.rb +161 -0
  19. data/lib/hotcocoa/kernel_ext.rb +14 -0
  20. data/lib/hotcocoa/kvo_accessors.rb +48 -0
  21. data/lib/hotcocoa/layout_view.rb +448 -0
  22. data/lib/hotcocoa/mapper.rb +227 -0
  23. data/lib/hotcocoa/mapping_methods.rb +40 -0
  24. data/lib/hotcocoa/mappings/alert.rb +25 -0
  25. data/lib/hotcocoa/mappings/application.rb +112 -0
  26. data/lib/hotcocoa/mappings/array_controller.rb +87 -0
  27. data/lib/hotcocoa/mappings/box.rb +39 -0
  28. data/lib/hotcocoa/mappings/button.rb +92 -0
  29. data/lib/hotcocoa/mappings/collection_view.rb +44 -0
  30. data/lib/hotcocoa/mappings/color.rb +28 -0
  31. data/lib/hotcocoa/mappings/column.rb +21 -0
  32. data/lib/hotcocoa/mappings/combo_box.rb +24 -0
  33. data/lib/hotcocoa/mappings/control.rb +33 -0
  34. data/lib/hotcocoa/mappings/font.rb +44 -0
  35. data/lib/hotcocoa/mappings/gradient.rb +15 -0
  36. data/lib/hotcocoa/mappings/image.rb +15 -0
  37. data/lib/hotcocoa/mappings/image_view.rb +43 -0
  38. data/lib/hotcocoa/mappings/label.rb +25 -0
  39. data/lib/hotcocoa/mappings/layout_view.rb +9 -0
  40. data/lib/hotcocoa/mappings/menu.rb +71 -0
  41. data/lib/hotcocoa/mappings/menu_item.rb +47 -0
  42. data/lib/hotcocoa/mappings/movie.rb +13 -0
  43. data/lib/hotcocoa/mappings/movie_view.rb +27 -0
  44. data/lib/hotcocoa/mappings/notification.rb +17 -0
  45. data/lib/hotcocoa/mappings/popup.rb +110 -0
  46. data/lib/hotcocoa/mappings/progress_indicator.rb +68 -0
  47. data/lib/hotcocoa/mappings/scroll_view.rb +29 -0
  48. data/lib/hotcocoa/mappings/search_field.rb +9 -0
  49. data/lib/hotcocoa/mappings/secure_text_field.rb +17 -0
  50. data/lib/hotcocoa/mappings/segmented_control.rb +97 -0
  51. data/lib/hotcocoa/mappings/slider.rb +25 -0
  52. data/lib/hotcocoa/mappings/sort_descriptor.rb +13 -0
  53. data/lib/hotcocoa/mappings/sound.rb +9 -0
  54. data/lib/hotcocoa/mappings/speech_synthesizer.rb +25 -0
  55. data/lib/hotcocoa/mappings/split_view.rb +21 -0
  56. data/lib/hotcocoa/mappings/status_bar.rb +7 -0
  57. data/lib/hotcocoa/mappings/status_item.rb +9 -0
  58. data/lib/hotcocoa/mappings/table_view.rb +110 -0
  59. data/lib/hotcocoa/mappings/text_field.rb +41 -0
  60. data/lib/hotcocoa/mappings/text_view.rb +13 -0
  61. data/lib/hotcocoa/mappings/timer.rb +25 -0
  62. data/lib/hotcocoa/mappings/toolbar.rb +97 -0
  63. data/lib/hotcocoa/mappings/toolbar_item.rb +36 -0
  64. data/lib/hotcocoa/mappings/view.rb +67 -0
  65. data/lib/hotcocoa/mappings/web_view.rb +22 -0
  66. data/lib/hotcocoa/mappings/window.rb +118 -0
  67. data/lib/hotcocoa/mappings/xml_parser.rb +41 -0
  68. data/lib/hotcocoa/mappings.rb +109 -0
  69. data/lib/hotcocoa/mvc.rb +175 -0
  70. data/lib/hotcocoa/notification_listener.rb +62 -0
  71. data/lib/hotcocoa/object_ext.rb +22 -0
  72. data/lib/hotcocoa/plist.rb +45 -0
  73. data/lib/hotcocoa/standard_rake_tasks.rb +17 -0
  74. data/lib/hotcocoa/template.rb +27 -0
  75. data/lib/hotcocoa/virtual_file_system.rb +172 -0
  76. data/lib/hotcocoa.rb +26 -0
  77. data/template/Rakefile +5 -0
  78. data/template/config/build.yml +8 -0
  79. data/template/lib/application.rb +45 -0
  80. data/template/lib/menu.rb +32 -0
  81. data/template/resources/HotCocoa.icns +0 -0
  82. data/test/test_helper.rb +3 -0
  83. data/test/test_hotcocoa.rb +11 -0
  84. metadata +137 -0
@@ -0,0 +1,109 @@
1
+ module HotCocoa
2
+ module Mappings
3
+
4
+ def self.reload
5
+ Dir.glob(File.join(File.dirname(__FILE__), "mappings", "*.rb")).each do |mapping|
6
+ require mapping
7
+ end
8
+ end
9
+
10
+ DefaultEmptyRect = [0,0,0,0]
11
+
12
+ module TargetActionConvenience
13
+ def on_action=(behavior)
14
+ if target && (
15
+ target.instance_variable_get("@action_behavior") ||
16
+ target.instance_variable_get("@double_action_behavior"))
17
+ object.instance_variable_set("@action_behavior", behavior)
18
+ object = target
19
+ else
20
+ object = Object.new
21
+ object.instance_variable_set("@action_behavior", behavior)
22
+ setTarget(object)
23
+ end
24
+ def object.perform_action(sender)
25
+ @action_behavior.call(sender)
26
+ end
27
+ setAction("perform_action:")
28
+ end
29
+
30
+ def on_action(&behavior)
31
+ self.on_action = behavior
32
+ self
33
+ end
34
+ end
35
+
36
+ # TODO: Needs docs for all possible invocations and examples!
37
+ def self.map(options, &block)
38
+ framework = options.delete(:framework)
39
+ mapped_name = options.keys.first
40
+ mapped_value = options.values.first
41
+ args = [mapped_name, mapped_value]
42
+
43
+ if mapped_value.kind_of?(Class)
44
+ add_mapping(*args, &block)
45
+ else
46
+ if framework.nil? || loaded_framework?(framework)
47
+ add_constant_mapping(*args, &block)
48
+ else
49
+ on_framework(framework) do
50
+ add_constant_mapping(*args, &block)
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ # Registers +mapped_name+ as a Mapper#builder_method for the given
57
+ # +mapped_value+. The +block+ is used as the Mapper#builder_method's body.
58
+ def self.add_mapping(mapped_name, mapped_value, &block)
59
+ m = Mapper.map_instances_of(mapped_value, mapped_name, &block)
60
+ mappings[m.builder_method] = m
61
+ end
62
+
63
+ # Registers +mapped_name+ as a Mapper#builder_method for the given
64
+ # +constant+ string which will be looked up. The +block+ is used as the
65
+ # Mapper#builder_method's body.
66
+ def self.add_constant_mapping(mapped_name, constant, &block)
67
+ add_mapping(mapped_name, Object.full_const_get(constant), &block)
68
+ end
69
+
70
+ # Returns the Hash of mappings.
71
+ def self.mappings
72
+ @mappings ||= {}
73
+ end
74
+
75
+ # Registers a callback for after the specified framework has been loaded.
76
+ def self.on_framework(name, &block)
77
+ (frameworks[name.to_s] ||= []) << block
78
+ end
79
+
80
+ # Returns the Hash of mapped frameworks.
81
+ def self.frameworks
82
+ @frameworks ||= {}
83
+ end
84
+
85
+ # Returns the Set of loaded frameworks.
86
+ def self.loaded_frameworks
87
+ @loaded_frameworks ||= Set.new
88
+ end
89
+
90
+ # Registers a given framework as being loaded.
91
+ def self.framework_loaded
92
+ frameworks.keys.each do |key|
93
+ if loaded_framework?(key)
94
+ frameworks[key].each do |mapper|
95
+ mapper.call
96
+ end
97
+ frameworks.delete(key)
98
+ end
99
+ end
100
+ end
101
+
102
+ # Returns whether or not the framework has been loaded yet.
103
+ def self.loaded_framework?(name)
104
+ NSBundle.allFrameworks.map {|bundle| bundle.bundlePath.split("/").last}.select {|framework| framework.split(".")[1] == 'framework'}.map {|framework| framework.split(".")[0]}.include?(name.to_s)
105
+ end
106
+
107
+ end
108
+
109
+ end
@@ -0,0 +1,175 @@
1
+ require 'hotcocoa'
2
+
3
+ class HotCocoaApplication
4
+ attr_accessor :shared_application, :application_controller, :controllers
5
+
6
+ include HotCocoa
7
+
8
+ def self.instance=(instance)
9
+ @instance = instance
10
+ end
11
+
12
+ def self.instance
13
+ @instance
14
+ end
15
+
16
+ def initialize(application_file)
17
+ HotCocoaApplication.instance = self
18
+ @controllers = {}
19
+ load_controllers_and_views(directory_of(application_file))
20
+ @shared_application = application(ApplicationView.options[:application])
21
+ @shared_application.load_application_menu
22
+ @application_controller = controller(:application_controller)
23
+ shared_application.delegate_to(application_controller)
24
+ end
25
+
26
+ def start
27
+ @shared_application.run
28
+ end
29
+
30
+ def controller(controller_name)
31
+ controller_name_string = controller_name.to_s
32
+ controller_class = Object.const_get(controller_name_string !~ /_/ && controller_name_string =~ /[A-Z]+.*/ ? controller_name_string : controller_name_string.split('_').map{|e| e.capitalize}.join)
33
+ @controllers[controller_name] || create_controller_instance(controller_name, controller_class)
34
+ end
35
+
36
+ private
37
+
38
+ def create_controller_instance(controller_name, controller_class)
39
+ controller_instance = controller_class.new(self)
40
+ @controllers[controller_name] = controller_instance
41
+ controller_instance.application_window
42
+ controller_instance
43
+ end
44
+
45
+ def directory_of(application_file)
46
+ File.dirname(File.expand_path(application_file))
47
+ end
48
+
49
+ def load_controllers_and_views(directory)
50
+ Dir.glob(File.join(directory, 'controllers', '**', '*.rb')).each do |controller_file|
51
+ load(controller_file)
52
+ end
53
+ Dir.glob(File.join(directory, 'views', '**', '*.rb')).each do |view_file|
54
+ load(view_file)
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ class HotCocoaController
61
+
62
+ def self.view_instances
63
+ @view_instances ||= {}
64
+ end
65
+
66
+ attr_reader :application
67
+
68
+ def initialize(application)
69
+ @application = application
70
+ end
71
+
72
+ def application_window
73
+ @application.application_controller.application_window
74
+ end
75
+
76
+ end
77
+
78
+ class HotCocoaApplicationController < HotCocoaController
79
+
80
+ def initialize(application)
81
+ super(application)
82
+ end
83
+
84
+ def application_window
85
+ @application_window ||= ApplicationWindow.new(self).application_window
86
+ end
87
+
88
+ end
89
+
90
+ class HotCocoaWindow
91
+
92
+ attr_reader :application_controller, :application_window
93
+
94
+ def initialize(application_controller)
95
+ @application_controller = application_controller
96
+ render
97
+ end
98
+
99
+ def render
100
+ @application_window = HotCocoa.window(ApplicationView.options[:window])
101
+ @application_window.delegate_to(application_controller)
102
+ @application_window.view << application_controller.application_view
103
+ end
104
+
105
+ end
106
+
107
+ class HotCocoaView < HotCocoa::LayoutView
108
+
109
+ DefaultLayoutOptions = {:expand => [:width, :height]}
110
+
111
+ module ClassMethods
112
+ def controller(name=nil)
113
+ if name
114
+ @name = name
115
+ else
116
+ @name || :application_controller
117
+ end
118
+ end
119
+ def options(options=nil)
120
+ if options
121
+ @options = options
122
+ else
123
+ @options
124
+ end
125
+ end
126
+ end
127
+
128
+ def self.inherited(klass)
129
+ klass.extend(ClassMethods)
130
+ klass.send(:include, HotCocoa::Behaviors)
131
+ class_name = klass.name.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("-", "_").downcase
132
+ HotCocoaController.class_eval %{
133
+ def #{class_name}
134
+ unless HotCocoaController.view_instances[:#{class_name}]
135
+ HotCocoaController.view_instances[:#{class_name}] = #{klass.name}.alloc.initWithFrame([0,0,0,0])
136
+ HotCocoaController.view_instances[:#{class_name}].setup_view
137
+ end
138
+ HotCocoaController.view_instances[:#{class_name}]
139
+ end
140
+ }, __FILE__, __LINE__
141
+ end
142
+
143
+ attr_reader :controller
144
+
145
+ def setup_view
146
+ unless @controller
147
+ @controller = class_controller
148
+ self.layout = layout_options
149
+ render
150
+ end
151
+ end
152
+
153
+ private
154
+
155
+ def class_controller
156
+ HotCocoaApplication.instance.controller(self.class.controller)
157
+ end
158
+
159
+ def layout_options
160
+ options = if self.class.options && self.class.options[:layout]
161
+ self.class.options[:layout]
162
+ else
163
+ DefaultLayoutOptions
164
+ end
165
+ end
166
+
167
+ end
168
+
169
+ class ApplicationWindow < HotCocoaWindow
170
+
171
+ end
172
+
173
+ class Application < HotCocoaApplication
174
+
175
+ end
@@ -0,0 +1,62 @@
1
+ module HotCocoa
2
+
3
+ class NotificationListener
4
+
5
+ DistributedBehaviors = {
6
+ :drop => NSNotificationSuspensionBehaviorDrop,
7
+ :coalesce => NSNotificationSuspensionBehaviorCoalesce,
8
+ :hold => NSNotificationSuspensionBehaviorHold,
9
+ :deliver_immediately => NSNotificationSuspensionBehaviorDeliverImmediately
10
+ }
11
+
12
+ attr_reader :callback, :name, :sender, :suspension_behavior
13
+
14
+ def self.registered_listeners
15
+ @registered_listeners ||= []
16
+ end
17
+
18
+ def initialize(options={}, &block)
19
+ @callback = block
20
+ @distributed = (options[:distributed] == true)
21
+ @suspension_behavior = DistributedBehaviors[options[:when_suspended] || :coalesce]
22
+ @name = options[:named]
23
+ @sender = options[:sent_by]
24
+ NotificationListener.registered_listeners << self
25
+ observe
26
+ end
27
+
28
+ def distributed?
29
+ @distributed
30
+ end
31
+
32
+ def receive(notification)
33
+ callback.call(notification)
34
+ end
35
+
36
+ def stop_notifications(options={})
37
+ if options.has_key?(:named) || options.has_key?(:sent_by)
38
+ notification_center.removeObserver(self, name:options[:named], object:options[:sender])
39
+ else
40
+ notification_center.removeObserver(self)
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def observe
47
+ if distributed?
48
+ notification_center.addObserver self, selector:'receive:', name:name, object:sender, suspensionBehavior:suspension_behavior
49
+ else
50
+ notification_center.addObserver self, selector:'receive:', name:name, object:sender
51
+ end
52
+ end
53
+
54
+ def notification_center
55
+ @notification_center ||= (distributed? ? NSDistributedNotificationCenter.defaultCenter : NSNotificationCenter.defaultCenter)
56
+ end
57
+ end
58
+
59
+ def on_notification(options={}, &block)
60
+ NotificationListener.new(options, &block)
61
+ end
62
+ end
@@ -0,0 +1,22 @@
1
+ # Object.full_const_get was taken from the ‘extlib’ project:
2
+ # http://github.com/sam/extlib which is released under a MIT License and
3
+ # copyrighted by Sam Smoot (2008).
4
+
5
+ class Object
6
+
7
+ # @param name<String> The name of the constant to get, e.g. "Merb::Router".
8
+ #
9
+ # @return <Object> The constant corresponding to the name.
10
+ def full_const_get(name)
11
+ list = name.split("::")
12
+ list.shift if list.first.empty?
13
+ obj = self
14
+ list.each do |x|
15
+ # This is required because const_get tries to look for constants in the
16
+ # ancestor chain, but we only want constants that are HERE
17
+ obj = obj.const_defined?(x) ? obj.const_get(x) : obj.const_missing(x)
18
+ end
19
+ obj
20
+ end
21
+
22
+ end
@@ -0,0 +1,45 @@
1
+ module HotCocoa
2
+ def read_plist(data, mutability=:all)
3
+ mutability = case mutability
4
+ when :none
5
+ NSPropertyListImmutable
6
+ when :containers_only
7
+ NSPropertyListMutableContainers
8
+ when :all
9
+ NSPropertyListMutableContainersAndLeaves
10
+ else
11
+ raise ArgumentError, "invalid mutability `#{mutability}'"
12
+ end
13
+ if data.is_a?(String)
14
+ data = data.dataUsingEncoding(NSUTF8StringEncoding)
15
+ if data.nil?
16
+ raise ArgumentError, "cannot convert string `#{data}' to data"
17
+ end
18
+ end
19
+ # TODO retrieve error description and raise it if there is an error.
20
+ NSPropertyListSerialization.propertyListFromData(data,
21
+ mutabilityOption:mutability,
22
+ format:nil,
23
+ errorDescription:nil)
24
+ end
25
+ end
26
+
27
+ class Object
28
+ def to_plist(format=:xml)
29
+ format = case format
30
+ when :xml
31
+ NSPropertyListXMLFormat_v1_0
32
+ when :binary
33
+ NSPropertyListBinaryFormat_v1_0
34
+ when :open_step
35
+ NSPropertyListOpenStepFormat
36
+ else
37
+ raise ArgumentError, "invalid format `#{format}'"
38
+ end
39
+ # TODO retrieve error description and raise it if there is an error.
40
+ data = NSPropertyListSerialization.dataFromPropertyList(self,
41
+ format:format,
42
+ errorDescription:nil)
43
+ NSMutableString.alloc.initWithData(data, encoding:NSUTF8StringEncoding)
44
+ end
45
+ end
@@ -0,0 +1,17 @@
1
+ AppConfig = HotCocoa::ApplicationBuilder::Configuration.new("config/build.yml")
2
+
3
+ task :deploy => [:clean] do
4
+ HotCocoa::ApplicationBuilder.build(AppConfig, :deploy => true)
5
+ end
6
+
7
+ task :build do
8
+ HotCocoa::ApplicationBuilder.build(AppConfig)
9
+ end
10
+
11
+ task :run => [:build] do
12
+ `"./#{AppConfig.name}.app/Contents/MacOS/#{AppConfig.name.gsub(/ /, '')}"`
13
+ end
14
+
15
+ task :clean do
16
+ `/bin/rm -rf "#{AppConfig.name}.app"`
17
+ end
@@ -0,0 +1,27 @@
1
+ require 'fileutils'
2
+ require 'rbconfig'
3
+
4
+ module HotCocoa
5
+ class Template
6
+
7
+ def self.source_directory
8
+ File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
9
+ end
10
+
11
+ def self.copy_to(directory, app_name)
12
+ FileUtils.mkdir_p(directory)
13
+ Dir.glob(File.join(source_directory, "template", "**/*")).each do |file|
14
+ short_name = file[(source_directory.length+10)..-1]
15
+ if File.directory?(file)
16
+ FileUtils.mkdir_p File.join(directory, short_name)
17
+ else
18
+ File.open(File.join(directory, short_name), "w") do |out|
19
+ input = File.read(file)
20
+ input.gsub!(/__APPLICATION_NAME__/, app_name)
21
+ out.write input
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,172 @@
1
+ class VirtualFileSystem
2
+
3
+ def self.code_to_load(main_file, password = "\320\302\354\024\215\360P\235\2244\261\214\276:'\274%\270<\350t\212\003\340\t'\004\345\334\256\315\277")
4
+ <<-VFS
5
+ module DatabaseRuntime
6
+
7
+ class VirtualFilesystem
8
+
9
+ attr_reader :password, :encryption_method
10
+
11
+ def initialize(password, encryption_method="aes256")
12
+ @password = password
13
+ @encryption_method = encryption_method
14
+ end
15
+
16
+ def open_database(main_database)
17
+ @main_database = main_database
18
+ begin
19
+ @db = Marshal.load(File.open(main_database, "rb") {|f| f.read})
20
+ rescue
21
+ puts $!
22
+ puts $!.backtrace.join("\\n")
23
+ end
24
+ end
25
+
26
+ def read_file_and_key(filename)
27
+ data, key = read_file_using_path(filename)
28
+ if data.nil? && filename[0,1] != "/"
29
+ $:.each do |loadpath|
30
+ data, key = read_file_using_path(filename, expand_path(loadpath))
31
+ break if data
32
+ end
33
+ end
34
+ [data, key]
35
+ end
36
+
37
+ def read_file_using_path(filename, pathname="/")
38
+ path = expand_path(File.join(pathname, filename))
39
+ rb_ext = false
40
+ if has_key?(path)
41
+ key = filename
42
+ elsif self.has_key?(path+".rb")
43
+ key = filename+".rb"
44
+ rb_ext = true
45
+ end
46
+ if key
47
+ result = rb_ext ? self[path+".rb"] : self[path]
48
+ if result
49
+ result.gsub!(/__FILE__/, "'\#{path + (rb_ext ? ".rb" : '')}'")
50
+ return result, key
51
+ end
52
+ end
53
+ nil
54
+ end
55
+
56
+ def has_key?(key)
57
+ @db.has_key?(key)
58
+ end
59
+
60
+ def delete(key)
61
+ end
62
+
63
+ def [](key)
64
+ read(@db, key)
65
+ end
66
+
67
+ def close
68
+ end
69
+
70
+ def keys
71
+ @db.keys
72
+ end
73
+
74
+ def []=(key, value)
75
+ end
76
+
77
+ def normalize(filename)
78
+ f = filename.split(File::Separator)
79
+ f.delete(".")
80
+ while f.include?("..")
81
+ f[f.index("..")-1,2] = []
82
+ end
83
+ f.join(File::Separator)
84
+ end
85
+
86
+ private
87
+
88
+ def expand_path(filename, dirstring=nil)
89
+ filename = File.join(dirstring, filename) if dirstring
90
+ f = filename.split(File::Separator)
91
+ f.delete(".")
92
+ f.delete("")
93
+ while f.include?("..")
94
+ f[f.index("..")-1,2] = []
95
+ end
96
+ "/"+f.join(File::Separator)
97
+ end
98
+
99
+
100
+ def read(db, key)
101
+ if db.has_key?(key)
102
+ #decrypt = OpenSSL::Cipher::Cipher.new(encryption_method)
103
+ #decrypt.decrypt
104
+ #decrypt.key = password
105
+ #data = decrypt.update(db[key])
106
+ #data << decrypt.final
107
+ #::Zlib::Inflate.inflate(data)
108
+ db[key]
109
+ else
110
+ nil
111
+ end
112
+ end
113
+
114
+ end
115
+
116
+ end
117
+
118
+ $ROOT_BINDING = binding
119
+
120
+ module Kernel
121
+
122
+ def virtual_filesystems(options)
123
+ vfs = DatabaseRuntime::VirtualFilesystem.new(options["password"])
124
+ vfs.open_database(options["database"])
125
+ Kernel.const_set("VIRTUAL_FILESYSTEM", vfs)
126
+ vfs
127
+ end
128
+
129
+ alias_method :original_require, :require
130
+
131
+ def require(path)
132
+ path = VIRTUAL_FILESYSTEM.normalize(path)
133
+ path_loaded = $".include?(path) || $".include?(path+".rb") || $".include?(path+".so")
134
+ unless path_loaded
135
+ data, key = VIRTUAL_FILESYSTEM.read_file_and_key(path)
136
+ if data
137
+ $" << key
138
+ eval(data, $ROOT_BINDING, key, 0)
139
+ return true
140
+ else
141
+ original_require(path)
142
+ end
143
+ else
144
+ return false
145
+ end
146
+ end
147
+
148
+ alias_method :original_load, :load
149
+
150
+ def load(path)
151
+ path = VIRTUAL_FILESYSTEM.normalize(path)
152
+ data, key = VIRTUAL_FILESYSTEM.read_file_and_key(path)
153
+ if data
154
+ eval(data, $ROOT_BINDING, key, 0)
155
+ return true
156
+ else
157
+ begin
158
+ original_load(path)
159
+ rescue LoadError => e
160
+ raise e
161
+ end
162
+ end
163
+ end
164
+
165
+ end
166
+
167
+ virtual_filesystems("database"=>File.join(NSBundle.mainBundle.resourcePath.fileSystemRepresentation, 'vfs.db'), "password"=>#{password.inspect})
168
+ $:.unshift "/lib"
169
+ load '#{main_file}'
170
+ VFS
171
+ end
172
+ end
data/lib/hotcocoa.rb ADDED
@@ -0,0 +1,26 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ framework 'Cocoa'
5
+
6
+ module Hotcocoa
7
+ VERSION = '0.0.1'
8
+ Views = {}
9
+ end
10
+
11
+ require 'hotcocoa/object_ext'
12
+ require 'hotcocoa/kernel_ext'
13
+ require 'hotcocoa/mappings'
14
+ require 'hotcocoa/behaviors'
15
+ require 'hotcocoa/mapping_methods'
16
+ require 'hotcocoa/mapper'
17
+ require 'hotcocoa/layout_view'
18
+ require 'hotcocoa/delegate_builder'
19
+ require 'hotcocoa/notification_listener'
20
+ require 'hotcocoa/data_sources/table_data_source'
21
+ require 'hotcocoa/data_sources/combo_box_data_source'
22
+ require 'hotcocoa/plist'
23
+ require 'hotcocoa/kvo_accessors'
24
+ require 'hotcocoa/attributed_string'
25
+
26
+ HotCocoa::Mappings.reload
data/template/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'hotcocoa/application_builder'
3
+ require 'hotcocoa/standard_rake_tasks'
4
+
5
+ task :default => [:run]
@@ -0,0 +1,8 @@
1
+ name: __APPLICATION_NAME__
2
+ load: lib/application.rb
3
+ version: "1.0"
4
+ icon: resources/HotCocoa.icns
5
+ resources:
6
+ - resources/**/*.*
7
+ sources:
8
+ - lib/**/*.rb