ironnails 0.0.1

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 (60) hide show
  1. data/Rakefile +21 -0
  2. data/VERSION +1 -0
  3. data/init.rb +1 -0
  4. data/ironnails.gemspec +96 -0
  5. data/lib/iron_nails.rb +1 -0
  6. data/lib/ironnails/bin/IronNails.Library.dll +0 -0
  7. data/lib/ironnails/bin/IronRuby.Libraries.Yaml.dll +0 -0
  8. data/lib/ironnails/bin/IronRuby.Libraries.dll +0 -0
  9. data/lib/ironnails/bin/IronRuby.dll +0 -0
  10. data/lib/ironnails/bin/Microsoft.Dynamic.dll +0 -0
  11. data/lib/ironnails/bin/Microsoft.Scripting.Core.dll +0 -0
  12. data/lib/ironnails/bin/Microsoft.Scripting.ExtensionAttribute.dll +0 -0
  13. data/lib/ironnails/bin/Microsoft.Scripting.dll +0 -0
  14. data/lib/ironnails/config/configuration.rb +141 -0
  15. data/lib/ironnails/config/initializer.rb +144 -0
  16. data/lib/ironnails/controller/base.rb +135 -0
  17. data/lib/ironnails/controller/view_operations.rb +101 -0
  18. data/lib/ironnails/controller.rb +2 -0
  19. data/lib/ironnails/core_ext/array.rb +15 -0
  20. data/lib/ironnails/core_ext/class/attribute_accessors.rb +57 -0
  21. data/lib/ironnails/core_ext/class.rb +8 -0
  22. data/lib/ironnails/core_ext/fixnum.rb +22 -0
  23. data/lib/ironnails/core_ext/hash.rb +32 -0
  24. data/lib/ironnails/core_ext/kernel.rb +26 -0
  25. data/lib/ironnails/core_ext/string.rb +58 -0
  26. data/lib/ironnails/core_ext/symbol.rb +78 -0
  27. data/lib/ironnails/core_ext/system/net/web_request.rb +110 -0
  28. data/lib/ironnails/core_ext/system/security/secure_string.rb +18 -0
  29. data/lib/ironnails/core_ext/system/windows/markup/xaml_reader.rb +6 -0
  30. data/lib/ironnails/core_ext/system/windows/ui_element.rb +17 -0
  31. data/lib/ironnails/core_ext/time.rb +28 -0
  32. data/lib/ironnails/core_ext.rb +12 -0
  33. data/lib/ironnails/errors.rb +19 -0
  34. data/lib/ironnails/iron_xml.rb +83 -0
  35. data/lib/ironnails/logger.rb +4 -0
  36. data/lib/ironnails/logging/buffered_logger.rb +137 -0
  37. data/lib/ironnails/logging/class_logger.rb +29 -0
  38. data/lib/ironnails/models/base.rb +16 -0
  39. data/lib/ironnails/models/bindable_collection.rb +15 -0
  40. data/lib/ironnails/models/model_mixin.rb +69 -0
  41. data/lib/ironnails/models.rb +3 -0
  42. data/lib/ironnails/nails_engine.rb +398 -0
  43. data/lib/ironnails/observable.rb +117 -0
  44. data/lib/ironnails/security/secure_string.rb +61 -0
  45. data/lib/ironnails/version.rb +11 -0
  46. data/lib/ironnails/view/collections.rb +117 -0
  47. data/lib/ironnails/view/commands/add_sub_view_command.rb +33 -0
  48. data/lib/ironnails/view/commands/behavior_command.rb +29 -0
  49. data/lib/ironnails/view/commands/command.rb +208 -0
  50. data/lib/ironnails/view/commands/event_command.rb +32 -0
  51. data/lib/ironnails/view/commands/timed_command.rb +40 -0
  52. data/lib/ironnails/view/commands.rb +5 -0
  53. data/lib/ironnails/view/view.rb +190 -0
  54. data/lib/ironnails/view/view_model.rb +45 -0
  55. data/lib/ironnails/view/xaml_proxy.rb +226 -0
  56. data/lib/ironnails/view.rb +5 -0
  57. data/lib/ironnails/wpf.rb +113 -0
  58. data/lib/ironnails/wpf_application.rb +30 -0
  59. data/lib/ironnails.rb +68 -0
  60. metadata +133 -0
@@ -0,0 +1,137 @@
1
+ # Inspired by the Buffered Logger from Ezra (Merb)
2
+ # Taken from active_support
3
+ module IronNails
4
+
5
+ module Logging
6
+
7
+
8
+ class BufferedLogger
9
+ module Severity
10
+ DEBUG = 0
11
+ INFO = 1
12
+ WARN = 2
13
+ ERROR = 3
14
+ FATAL = 4
15
+ UNKNOWN = 5
16
+ end
17
+ include Severity
18
+
19
+ MAX_BUFFER_SIZE = 1000
20
+
21
+ # Set to false to disable the silencer
22
+ cattr_accessor :silencer
23
+ self.silencer = true
24
+
25
+ # Silences the logger for the duration of the block.
26
+ def silence(temporary_level = ERROR)
27
+ if silencer
28
+ begin
29
+ old_logger_level, self.level = level, temporary_level
30
+ yield self
31
+ ensure
32
+ self.level = old_logger_level
33
+ end
34
+ else
35
+ yield self
36
+ end
37
+ end
38
+
39
+ attr_accessor :level
40
+ attr_reader :auto_flushing
41
+ attr_reader :buffer
42
+
43
+ def initialize(log, level = DEBUG)
44
+ @level = level
45
+ @buffer = []
46
+ @auto_flushing = 1
47
+ @no_block = false
48
+
49
+ if log.respond_to?(:write)
50
+ @log = log
51
+ elsif File.exist?(log)
52
+ @log = File.open(log, (File::WRONLY | File::APPEND))
53
+ @log.sync = true
54
+ else
55
+ FileUtils.mkdir_p(File.dirname(log))
56
+ @log = File.open(log, (File::WRONLY | File::APPEND | File::CREAT))
57
+ @log.sync = true
58
+ @log.write("# Logfile created on %s" % [Time.now.to_s])
59
+ end
60
+ end
61
+
62
+ def set_non_blocking_io
63
+ if !RUBY_PLATFORM.match(/java|mswin/) && !(@log == STDOUT) && @log.respond_to?(:write_nonblock)
64
+ @no_block = true
65
+ end
66
+ end
67
+
68
+ def add(severity, message = nil, progname = nil, &block)
69
+ from_framework = progname == IRONNAILS_FRAMEWORKNAME
70
+ fw_logging = defined?(IronNails::Logging::FRAMEWORK_LOGGING) && IronNails::Logging::FRAMEWORK_LOGGING
71
+ return if @level > severity || (from_framework && !fw_logging )
72
+ message = (message || (block && block.call) || progname).to_s
73
+ puts message if defined?(IronNails::Logging::CONSOLE_LOGGING) && IronNails::Logging::CONSOLE_LOGGING
74
+ # If a newline is necessary then create a new message ending with a newline.
75
+ # Ensures that the original message is not mutated.
76
+ message = "IRONNAILS: #{Severity.constants[severity]}: #{message}" if from_framework
77
+ message = "[#{Time.now.strftime("%d/%m/%Y %H:%M:%S.#{Time.now.usec}")}] #{message}\n" unless message[-1] == ?\n
78
+ buffer << message
79
+ auto_flush
80
+ message
81
+ end
82
+
83
+ for severity in Severity.constants
84
+ class_eval <<-EOT, __FILE__, __LINE__
85
+ def #{severity.downcase}(message = nil, progname = nil, &block)
86
+ add(#{severity}, message, progname, &block)
87
+ end
88
+
89
+ def #{severity.downcase}?
90
+ #{severity} >= @level
91
+ end
92
+ EOT
93
+ end
94
+
95
+ # Set the auto-flush period. Set to true to flush after every log message,
96
+ # to an integer to flush every N messages, or to false, nil, or zero to
97
+ # never auto-flush. If you turn auto-flushing off, be sure to regularly
98
+ # flush the log yourself -- it will eat up memory until you do.
99
+ def auto_flushing=(period)
100
+ @auto_flushing =
101
+ case period
102
+ when true;
103
+ 1
104
+ when false, nil, 0;
105
+ MAX_BUFFER_SIZE
106
+ when Integer;
107
+ period
108
+ else
109
+ raise ArgumentError, "Unrecognized auto_flushing period: #{period.inspect}"
110
+ end
111
+ end
112
+
113
+ def flush
114
+ unless buffer.empty?
115
+ if @no_block
116
+ @log.write_nonblock(buffer.slice!(0..-1).join)
117
+ else
118
+ @log.write(buffer.slice!(0..-1).join)
119
+ end
120
+ end
121
+ end
122
+
123
+ def close
124
+ flush
125
+ @log.close if @log.respond_to?(:close)
126
+ @log = nil
127
+ end
128
+
129
+ protected
130
+ def auto_flush
131
+ flush if buffer.size >= @auto_flushing
132
+ end
133
+ end
134
+
135
+ end
136
+
137
+ end
@@ -0,0 +1,29 @@
1
+ module IronNails
2
+
3
+ module Logging
4
+
5
+ module ClassLogger
6
+
7
+ # provides access for the logger we are using
8
+ # you can override this logger as long as it responds to
9
+ # the methods: debug, info, warn, error, fatal
10
+ def logger
11
+ IRONNAILS_DEFAULT_LOGGER
12
+ end
13
+
14
+ # Ensures that a message is logged when the execution of
15
+ # the specified block throws an error. It will then re-raise the error.
16
+ def log_on_error
17
+ begin
18
+ yield if block_given?
19
+ rescue Exception => e
20
+ logger.error "IronNails Error: #{e}"
21
+ raise e
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,16 @@
1
+ module IronNails
2
+
3
+ module Models
4
+
5
+
6
+
7
+
8
+ class Base
9
+
10
+ include IronNails::Models::ModelMixin
11
+
12
+ end
13
+
14
+ end
15
+
16
+ end
@@ -0,0 +1,15 @@
1
+ module IronNails
2
+
3
+ module Models
4
+
5
+ class BindableCollection < System::Collections::ObjectModel::ObservableCollection.of(System::Object)
6
+
7
+ def initialize(*list)
8
+ list.map { |item| self.add item }
9
+ end
10
+
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,69 @@
1
+ module IronNails
2
+
3
+ module Models
4
+
5
+ module ModelMixin
6
+
7
+ include IronNails::Logging::ClassLogger
8
+
9
+ end
10
+
11
+ module Databinding
12
+
13
+ module ClassMethods
14
+
15
+ # defines a write-only attribute on an object
16
+ # this would map to a property setter in different languages
17
+ def attr_writer(*names)
18
+ names.each do |nm|
19
+ mn = nm
20
+ self.send :define_method, "#{nm}=".to_sym do |arg|
21
+ __vr__ = instance_variable_get :"@#{mn}"
22
+ return __vr__ if __vr__ == arg
23
+ instance_variable_set :"@#{mn}", arg
24
+ raise_property_changed mn
25
+ end
26
+ end
27
+ end
28
+
29
+ # defines a read/write attribute on an object.
30
+ # this would map to a property with a getter and a setter in different langauages
31
+ def attr_accessor(*names)
32
+ attr_reader *names
33
+ attr_writer *names
34
+ end
35
+
36
+
37
+ end
38
+
39
+ # extend the class with the class methods defined in this module
40
+ def self.included(base)
41
+ base.send :include, System::ComponentModel::INotifyPropertyChanged unless base.ancestors.include? System::ComponentModel::INotifyPropertyChanged
42
+ base.extend ClassMethods
43
+ end
44
+
45
+ def add_PropertyChanged(handler=nil)
46
+ @__handlers__ ||= []
47
+ @__handlers__ << handler
48
+ end
49
+
50
+ def remove_PropertyChanged(handler=nil)
51
+ @__handlers__ ||= []
52
+ @__handlers__.delete handler
53
+ end
54
+
55
+ private
56
+ def raise_property_changed(name)
57
+ return unless @__handlers__
58
+ @__handlers__.each do |ev|
59
+ ev.invoke self, System::ComponentModel::PropertyChangedEventArgs.new(name) if ev.respond_to? :invoke
60
+ ev.call self, System::ComponentModel::PropertyChangedEventArgs.new(name) if ev.respond_to? :call
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,3 @@
1
+ require File.dirname(__FILE__) + '/models/model_mixin'
2
+ require File.dirname(__FILE__) + '/models/bindable_collection'
3
+ require File.dirname(__FILE__) + '/models/base'
@@ -0,0 +1,398 @@
1
+ require File.dirname(__FILE__) + "/view/collections"
2
+ require File.dirname(__FILE__) + "/view/view_model"
3
+ require File.dirname(__FILE__) + "/view/xaml_proxy"
4
+ require File.dirname(__FILE__) + "/observable"
5
+
6
+ module IronNails
7
+
8
+ module Core
9
+
10
+ module ViewOperations
11
+
12
+ def init_view_operations
13
+ end
14
+
15
+ def build_view(options)
16
+ logger.debug "View to load: #{options[:name]}", IRONNAILS_FRAMEWORKNAME
17
+ vw = IronNails::View::View.new(options)
18
+ #vw.add_observer(:loaded) { |sender| set_data_context_for(sender) }
19
+ vw
20
+ end
21
+
22
+ def register_child_view(options)
23
+ vw = registry.view_for options[:controller]
24
+ vw.add_child(options)
25
+ end
26
+
27
+ def register_view_for(controller)
28
+ vw = build_view(:name => controller.view_name.to_sym, :controller => controller.controller_name)
29
+ vw.add_observer(:configuring) { |sender| configure_view(sender) }
30
+ registry.register_view_for controller, vw
31
+ end
32
+
33
+ def on_view(controller, name = nil, &b)
34
+ find_view(controller, name).on_proxy(&b) #unless vw.nil?
35
+ end
36
+
37
+ def from_view(controller, name, target, method)
38
+ find_view(controller, name).get_property(target, method)
39
+ end
40
+
41
+ def to_update_ui_after(controller, options, &b)
42
+ # if options.is_a? Hash
43
+ # klass = options[:class]||BindableCollection
44
+ # request = options[:request]
45
+ # else
46
+ # klass = BindableCollection
47
+ # request = options
48
+ # end
49
+ # cb = System::Threading::WaitCallback.new do
50
+ # begin
51
+ # registry.view_for(controller).dispatcher.begin_invoke(DispatcherPriority.normal, Action.of(klass).new(&b), request.call)
52
+ # rescue WebException => e
53
+ # MessageBox.Show("There was a problem logging in to Twitter. #{e.message}");
54
+ # rescue RequestLimitException => e
55
+ # MessageBox.Show(e.message)
56
+ # rescue SecurityException => e
57
+ # MessageBox.Show("Incorrect username or password. Please try again");
58
+ # end
59
+ # end
60
+ # System::Threading::ThreadPool.queue_user_work_item cb
61
+ cb = nil
62
+ cb = options[:callback] unless options[:callback].nil?
63
+ options[:callback] = lambda do |vw|
64
+ b.call
65
+ refresh_view(vw)
66
+ end
67
+ find_view(controller, name).to_update_ui_after(options, &b)
68
+ end
69
+
70
+ def on_ui_thread(controller, options=nil, &b)
71
+ if options.is_a? Hash
72
+ data = options[:data]
73
+ klass = options[:class] || data.class
74
+ else
75
+ unless options.nil?
76
+ klass = options.class
77
+ data = options
78
+ end
79
+ end
80
+ b.call
81
+ #registry.view_for(controller).dispatcher.begin_invoke(DispatcherPriority.normal, options.nil? ? Action.new(&b) : Action.of(klass).new(&b), data)
82
+ end
83
+
84
+ alias_method :on_ui_thread_with, :on_ui_thread
85
+
86
+ def play_storyboard(controller, name, storyboard)
87
+ logger.debug "finding controller #{controller.controller_name} and view #{name} to play #{storyboard}"
88
+ vw = find_view(controller, name)
89
+ find_view(controller, name).play_storyboard(storyboard)
90
+ end
91
+
92
+ def stop_storyboard(controller, view_name, storyboard)
93
+ find_view(controller, name).stop_storyboard(storyboard)
94
+ end
95
+
96
+ def find_view(controller, name)
97
+ registry.view_for(controller).find(name)
98
+ end
99
+ end
100
+
101
+ module ViewModelObjectOperations
102
+
103
+ # gets or sets the models that wil be used in the view to bind to
104
+ attr_accessor :model_queue
105
+
106
+ def init_object_operations
107
+ @model_queue = ModelCollection.new
108
+ end
109
+
110
+ # flags the view model as in need of wiring up and
111
+ # sets the model collection
112
+ def model_queue=(value)
113
+ unless model_queue == value
114
+ @configured = false
115
+ @model_queue = value
116
+ end
117
+ end
118
+
119
+ # adds a new model to the queue for synchronisation to the view
120
+ def add_model_to_queue_on(model)
121
+ if model.respond_to?(:has_model?)
122
+ model.each do |m|
123
+ enqueue_model(m)
124
+ end
125
+ elsif model.is_a?(Hash)
126
+ enqueue_model(model)
127
+ end
128
+ end
129
+
130
+ alias_method :add_models_to_queue_on, :add_model_to_queue_on
131
+
132
+ private
133
+
134
+ def enqueue_model(model)
135
+ key = model.keys[0]
136
+ unless model_queue.has_model?(model) && model_queue[key] == model[key]
137
+ model_queue.add_model model
138
+ @configured = false
139
+ end
140
+ end
141
+
142
+ end
143
+
144
+ module ViewModelCommandOperations
145
+
146
+ # gets or sets the command_queue to respond to user actions in the view.
147
+ attr_accessor :command_queue
148
+
149
+ def init_command_operations
150
+ @command_queue = CommandCollection.new
151
+ end
152
+
153
+ # flags the view model as in need of wiring up and
154
+ # sets the command collection
155
+ def command_queue=(value)
156
+ unless command_queue == value
157
+ @configured = false
158
+ @command_queue = value
159
+ end
160
+ end
161
+
162
+ # adds a command or a command collection to the queue
163
+ def add_command_to_queue(cmd)
164
+
165
+ if cmd.respond_to?(:has_command?)
166
+ cmd.each do |c|
167
+ enqueue_command(c)
168
+ end
169
+ elsif cmd.respond_to?(:execute) && cmd.respond_to?(:refresh_view) # define some sort of contract
170
+ enqueue_command(cmd)
171
+ end
172
+ end
173
+
174
+ alias_method :add_commands_to_queue, :add_command_to_queue
175
+
176
+ private
177
+
178
+ def enqueue_command(cmd)
179
+ if !command_queue.has_command?(cmd) || cmd.changed?
180
+ cmd.add_observer(:refreshing_view) do |sender|
181
+ refresh_view(registry.view_for(sender.controller))
182
+ end
183
+ command_queue << cmd
184
+ @configured = false
185
+ end
186
+ end
187
+
188
+ end
189
+
190
+ module ViewModelOperations
191
+
192
+ # gets the view model instance to manipulate with this builder
193
+ attr_accessor :view_models
194
+
195
+ include ViewModelObjectOperations
196
+ include ViewModelCommandOperations
197
+
198
+ def init_viewmodel_operations
199
+ init_object_operations
200
+ init_command_operations
201
+ @view_models = {}
202
+ end
203
+
204
+ def register_viewmodel_for(controller)
205
+ vm_class_name = controller.view_model_name.camelize
206
+ Object.const_set vm_class_name, Class.new unless Object.const_defined? vm_class_name
207
+
208
+ # TODO: There is an issue with namespacing and CLR classes, they aren't registered as constants with
209
+ # IronRuby. This makes it hard to namespace viewmodels. If the namespace is included everything
210
+ # should work as normally. Will revisit this later to properly fix it.
211
+ vm_name = controller.view_model_name
212
+ klass = Object.const_get vm_class_name
213
+ klass.send :include, IronNails::Models::Databinding
214
+ klass.send :include, IronNails::View::ViewModelMixin
215
+ key = vm_name.to_sym
216
+ view_models[key] = klass.new if view_models[key].nil?
217
+ registry.register_viewmodel_for controller, view_models[key]
218
+ view_models[key]
219
+ end
220
+
221
+ end
222
+
223
+ class ComponentRegistryItem
224
+
225
+ attr_accessor :viewmodel
226
+
227
+ attr_accessor :view
228
+
229
+ def initialize(options={})
230
+ @view = options[:view]
231
+ @viewmodel = options[:viewmodel]
232
+ end
233
+
234
+ end
235
+
236
+ class ComponentRegistry
237
+
238
+ attr_accessor :components
239
+
240
+ def initialize
241
+ @components = {}
242
+ end
243
+
244
+ def register(controller)
245
+ components[controller.controller_name] = ComponentRegistryItem.new
246
+ end
247
+
248
+ def register_view_for(controller, view)
249
+ find_controller(controller).view = view
250
+ end
251
+
252
+ def register_viewmodel_for(controller, model)
253
+ find_controller(controller).viewmodel = model
254
+ end
255
+
256
+ def find_controller(controller)
257
+ con_name = controller.respond_to?(:controller_name) ? controller.controller_name : controller.to_sym
258
+ components[con_name]
259
+ end
260
+
261
+ def viewmodel_for(controller)
262
+ find_controller(controller).viewmodel
263
+ end
264
+
265
+ def view_for(controller)
266
+ find_controller(controller).view
267
+ end
268
+ end
269
+
270
+ # This could be viewed as the life support for the Nails framework
271
+ # It serves as the glue between the different components.
272
+ # One of its main functions is to manage communication between the controller,
273
+ # view model and view.
274
+ class NailsEngine
275
+
276
+ include IronNails::Logging::ClassLogger
277
+ include ControllerObservable
278
+ include ViewOperations
279
+ include ViewModelOperations
280
+
281
+ # Stores the registered components and does lookup on them
282
+ attr_accessor :registry
283
+
284
+ def set_viewmodel_for(controller, key, value)
285
+ model = registry.viewmodel_for controller
286
+ model.set_model key, value
287
+ end
288
+
289
+ # configures the properties for the view model
290
+ def configure_models(model)
291
+ model_queue.each do |o|
292
+ o.each do |k, v|
293
+ model.add_model k, v
294
+ end unless o.nil?
295
+ end
296
+ end
297
+
298
+ # processes the command queue.
299
+ def configure_events(model, view)
300
+ command_queue.each do |cmd|
301
+ case
302
+ when cmd.is_a?(EventCommand)
303
+ view.add_command(cmd)
304
+ when cmd.is_a?(TimedCommand)
305
+ view.add_timer(cmd)
306
+ view.proxy.start_timer(cmd)
307
+ when cmd.is_a?(BehaviorCommand)
308
+ model.add_command cmd
309
+ end unless cmd.attached?
310
+ end
311
+ end
312
+
313
+ # configures the view
314
+ def configure_view(view)
315
+ model = registry.viewmodel_for view.controller
316
+ configure_models(model)
317
+ configure_events(model, view)
318
+ view.data_context = model unless view.has_datacontext? && !view.sets_datacontext?
319
+ @configured = true
320
+ end
321
+
322
+ # refreshes the data for the view.
323
+ def refresh_view(view)
324
+ notify_observers :refreshing_view, view.controller, self, view
325
+ view.configure
326
+ view.proxy.refresh
327
+ @configured = true
328
+ end
329
+
330
+ # synchronises the data in the viewmodel with the controller
331
+ def synchronise_with_controller
332
+ notify_observers :reading_input, self, view
333
+ end
334
+
335
+ def add_command_to_view(commands)
336
+ add_commands_to_queue commands
337
+ end
338
+
339
+ def synchronise_to_controller(controller)
340
+ objects = controller.instance_variable_get "@objects"
341
+ #model = registry.viewmodel_for controller #.objects.collect { |kvp| kvp.key.to_s.underscore.to_sym }
342
+ vw = registry.view_for controller
343
+ model = vw.proxy.data_context
344
+ objects.each do |k, v|
345
+ if model.respond_to?(k.to_sym)
346
+ val = model.send k.to_sym
347
+ objects[k] = val
348
+ controller.instance_variable_set "@#{k}", val
349
+ end
350
+ end
351
+ view_properties = controller.instance_variable_get "@view_properties"
352
+ view_properties.each do |k, v|
353
+ val = from_view controller, (v[:view]||controller.view_name), v[:element], v[:property]
354
+ instance_variable_set "@#{k}", val
355
+ end
356
+ end
357
+
358
+ # returns whether this view needs configuration or not
359
+ def configured?
360
+ !!@configured
361
+ end
362
+
363
+ def initialize
364
+ @configured, @registry = false, ComponentRegistry.new
365
+ init_viewmodel_operations
366
+ init_view_operations
367
+ end
368
+
369
+ def register_controller(controller)
370
+ logger.debug "registering controller #{controller.controller_name}", IRONNAILS_FRAMEWORKNAME
371
+ registry.register(controller)
372
+ register_viewmodel_for controller
373
+ register_view_for controller
374
+ controller.nails_engine = self
375
+ logger.debug "controller #{controller.controller_name} registered", IRONNAILS_FRAMEWORKNAME
376
+ end
377
+
378
+ def show_initial_window(controller)
379
+ logger.debug "setting up controller", IRONNAILS_FRAMEWORKNAME
380
+ #controller.setup_for_showing_view
381
+ registry.view_for(controller).load
382
+ controller.default_action if controller.respond_to? :default_action
383
+ controller.setup_for_showing_view
384
+ yield registry.view_for(controller).instance if block_given?
385
+ end
386
+
387
+ def initialize_with(command_definitions, models)
388
+ add_commands_to_queue command_definitions
389
+ add_models_to_queue_on models
390
+ logger.debug "Added commands to queue on view manager.", IRONNAILS_FRAMEWORKNAME
391
+ logger.debug "Added models to queue on view manager.", IRONNAILS_FRAMEWORKNAME
392
+ end
393
+
394
+ end
395
+
396
+ end
397
+
398
+ end