rugui 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog CHANGED
@@ -1,3 +1,12 @@
1
+ 1.3.1
2
+ - Added a DSL to detect when observable properties were changed.
3
+ - Silencing logs when running in test environment unless a level is defined in test environment configuration file.
4
+ - Added refresh method to be used when testing GUI parts (views) of applications.
5
+ - Conventionally named views are now registered automatically (i.e., for a controller named MyController, a view named MyView will be registered automatically)
6
+ - Added a new style registering of controllers, views and models, with option for registering main models (models which are already registered in the main controller)
7
+ - Connecting signals for widget types only if the widget isn't destroyed
8
+ - Fixed a bug which happened when copying properties from a observable when the destination observable property value was nil
9
+
1
10
  1.3.0
2
11
  - Added support to upload RuGUI to rubyforge.
3
12
  - Updated README docs with new instructions for installation.
@@ -9,8 +9,8 @@ begin
9
9
  gemspec.authors = ["Vicente Mundim", "Felipe Mesquita", "Claudio Escudero"]
10
10
  gemspec.add_dependency(%q<activesupport>, [">= 2.1.1"])
11
11
  gemspec.add_dependency(%q<rubigen>, [">= 1.5.1"])
12
- gemspec.version = "1.3.0"
13
- gemspec.date = %q{2009-04-01}
12
+ gemspec.version = "1.3.1"
13
+ gemspec.date = %q{2009-06-16}
14
14
  gemspec.rubyforge_project = "rugui"
15
15
  gemspec.executables = ['rugui']
16
16
  gemspec.files = FileList["bin/*", "lib/**/*", "rugui_generators/**/*", "script/*", "spec/**/*", "Changelog", "LICENSE", "Rakefile", "README"].to_a
@@ -6,14 +6,17 @@ module RuGUI
6
6
  include RuGUI::PropertyObserver
7
7
  include RuGUI::LogSupport
8
8
  include RuGUI::SignalSupport
9
+ include RuGUI::EntityRegistrationSupport
9
10
 
10
11
  attr_accessor :models
12
+ attr_accessor :main_models
11
13
  attr_accessor :views
12
14
  attr_accessor :controllers
13
15
  attr_accessor :parent_controller
14
16
 
15
17
  def initialize(parent_controller = nil)
16
18
  @models = {}
19
+ @main_models = {}
17
20
  @views = {}
18
21
  @controllers = {}
19
22
 
@@ -23,9 +26,18 @@ module RuGUI
23
26
  @parent_controller = parent_controller
24
27
  end
25
28
 
29
+ register_all :model
26
30
  setup_models
31
+
32
+ register_default_view if should_register_default_view?
33
+ register_all :view
27
34
  setup_views
35
+
36
+ register_all :controller
28
37
  setup_controllers
38
+
39
+ register_all :main_model
40
+ setup_main_models
29
41
  end
30
42
 
31
43
  # This is included here so that the initialize method is properly updated.
@@ -43,13 +55,19 @@ module RuGUI
43
55
  # a new instance of the model class will be created.
44
56
  #
45
57
  def register_model(model, name = nil)
46
- model = create_instance(model) if model.is_a?(String) or model.is_a?(Symbol)
47
- name ||= model.class.to_s.underscore
48
- model.register_observer(self, name)
49
- @models[name.to_sym] = model
50
- create_model_attribute_reader(name)
58
+ register(:model, model, name)
59
+ end
51
60
 
52
- model.post_registration(self)
61
+ #
62
+ # Registers a main model for this controller.
63
+ #
64
+ # Only model names (as string or symbol) should be passed. Optionally a
65
+ # different name may be given. If the main controller doesn't have a model
66
+ # registered or if this is the main controller a NoMethodError exception
67
+ # will be raised.
68
+ #
69
+ def register_main_model(model_name, name = nil)
70
+ register(:main_model, model_name, name)
53
71
  end
54
72
 
55
73
  #
@@ -59,13 +77,7 @@ module RuGUI
59
77
  # instance of the view class will be created.
60
78
  #
61
79
  def register_view(view, name = nil)
62
- view = create_instance(view) if view.is_a?(String) or view.is_a?(Symbol)
63
- name ||= view.class.to_s.underscore
64
- view.register_controller(self)
65
- @views[name.to_sym] = view
66
- create_view_attribute_reader(name)
67
-
68
- view.post_registration(self)
80
+ register(:view, view, name)
69
81
  end
70
82
 
71
83
  #
@@ -75,13 +87,7 @@ module RuGUI
75
87
  # a new instance of the controller class will be created.
76
88
  #
77
89
  def register_controller(controller, name = nil)
78
- controller = create_instance(controller, self) if controller.is_a?(String) or controller.is_a?(Symbol)
79
- name ||= controller.class.to_s.underscore
80
- controller.parent_controller = self
81
- @controllers[name.to_sym] = controller
82
- create_controller_attribute_reader(name)
83
-
84
- controller.post_registration
90
+ register(:controller, controller, name)
85
91
  end
86
92
 
87
93
  #
@@ -102,54 +108,97 @@ module RuGUI
102
108
  @main_controller ||= find_main_controller
103
109
  end
104
110
 
111
+ class << self
112
+ def models(*names)
113
+ register(:model, *names)
114
+ end
115
+
116
+ def main_models(*names)
117
+ register(:main_model, *names)
118
+ end
119
+
120
+ def views(*names)
121
+ register(:view, *names)
122
+ end
123
+
124
+ def controllers(*names)
125
+ register(:controller, *names)
126
+ end
127
+ end
128
+
105
129
  protected
106
130
  #
107
- # Subclasses should reimplement this to register models.
131
+ # Subclasses should reimplement this to register or initialize models.
108
132
  #
109
133
  def setup_models
110
134
  end
111
135
 
112
136
  #
113
- # Subclasses should reimplement this to register views.
137
+ # Subclasses should reimplement this to register or initialize main models.
138
+ #
139
+ def setup_main_models
140
+ end
141
+
142
+ #
143
+ # Subclasses should reimplement this to register or initialize views.
114
144
  #
115
145
  def setup_views
116
146
  end
117
147
 
118
148
  #
119
- # Subclasses should reimplement this to register controllers.
149
+ # Subclasses should reimplement this to register or initialize controllers.
120
150
  #
121
151
  def setup_controllers
122
152
  end
123
153
 
124
154
  private
125
- def create_instance(klass_name, *args)
126
- klass_name.to_s.camelize.constantize.new(*args)
155
+ def after_register_model(model, name)
156
+ model.register_observer(self, name)
157
+ model.post_registration(self)
158
+ end
159
+
160
+ def after_register_main_model(model, name)
161
+ after_register_model(model, name)
127
162
  end
128
163
 
129
- # Creates an attribute reader for the model.
130
- def create_model_attribute_reader(name)
131
- create_attribute_reader(:models, name)
164
+ def after_register_view(view, name)
165
+ view.register_controller(self)
166
+ view.post_registration(self)
132
167
  end
133
168
 
134
- # Creates an attribute reader for the view.
135
- def create_view_attribute_reader(name)
136
- create_attribute_reader(:views, name)
169
+ def after_register_controller(controller, name)
170
+ controller.parent_controller = self
171
+ controller.post_registration
137
172
  end
138
173
 
139
- # Creates an attribute reader for the controller.
140
- def create_controller_attribute_reader(name)
141
- create_attribute_reader(:controllers, name)
174
+ def create_instance_arguments_for_controller
175
+ [self]
142
176
  end
143
177
 
144
- # Creates an attribute reader for the some entity.
145
- def create_attribute_reader(entity, name)
146
- self.class.class_eval <<-class_eval
147
- def #{name}
148
- @#{entity}[:#{name}]
149
- end
150
- class_eval
178
+ def get_instance_for_main_model(name)
179
+ main_controller.send(name) # should raise an error if main_controller doesn't have that main model.
151
180
  end
152
-
181
+
182
+ def register_default_view
183
+ default_view_name.camelize.constantize # Check if we can constantize view name, if this fails a NameError exception is thrown.
184
+ register_view default_view_name
185
+ rescue NameError
186
+ # No default view for this controller, nothing to do.
187
+ end
188
+
189
+ def default_view_name
190
+ "#{controller_name}_view"
191
+ end
192
+
193
+ def controller_name
194
+ match = self.class.name.underscore.match(/([\w_]*)_controller/)
195
+ match ? match[1] : self.class.name
196
+ end
197
+
198
+ def should_register_default_view?
199
+ RuGUI.configuration.automatically_register_conventionally_named_views
200
+ end
201
+
153
202
  # Navigates through the controllers hierarchy trying to find the main
154
203
  # controller (i.e., a class that extends RuGUI::BaseMainController).
155
204
  def find_main_controller
@@ -182,6 +231,16 @@ module RuGUI
182
231
  self.framework_adapter.run
183
232
  end
184
233
 
234
+ #
235
+ # Refreshes the GUI application, running just one event loop.
236
+ #
237
+ # This method is mostly useful when writing tests. It shouldn't be used
238
+ # in normal applications.
239
+ #
240
+ def refresh
241
+ self.framework_adapter.refresh
242
+ end
243
+
185
244
  #
186
245
  # Exits from the application.
187
246
  #
@@ -2,7 +2,7 @@ module RuGUI
2
2
  class BaseModel < BaseObject
3
3
  include RuGUI::ObservablePropertySupport
4
4
  include RuGUI::LogSupport
5
-
5
+
6
6
  def initialize(observable_properties_values = {})
7
7
  initialize_observable_property_support(observable_properties_values)
8
8
  end
@@ -36,7 +36,7 @@ module RuGUI
36
36
  attr_accessor :controllers
37
37
  attr_reader :widgets
38
38
  attr_reader :unnamed_widgets
39
-
39
+
40
40
  class_inheritable_accessor :configured_builder_file
41
41
  class_inheritable_accessor :configured_builder_file_usage
42
42
  class_inheritable_accessor :configured_builder_file_extension
@@ -67,7 +67,7 @@ module RuGUI
67
67
  # Reimplement this method to create widgets by hand.
68
68
  def setup_widgets
69
69
  end
70
-
70
+
71
71
  # Reimplement this method to setup view helpers.
72
72
  def setup_view_helpers
73
73
  end
@@ -41,6 +41,9 @@ module RuGUI
41
41
  # The timeout for queued calls. Useful when performing long tasks.
42
42
  attr_accessor :queue_timeout
43
43
 
44
+ # Automatically register conventionally named views. Defaults to true.
45
+ attr_accessor :automatically_register_conventionally_named_views
46
+
44
47
  # A hash of application specific configurations.
45
48
  attr_accessor :application
46
49
 
@@ -61,6 +64,7 @@ module RuGUI
61
64
  self.builder_files_paths = default_builder_files_paths
62
65
  self.styles_paths = default_styles_paths
63
66
  self.queue_timeout = default_queue_timeout
67
+ self.automatically_register_conventionally_named_views = default_automatically_register_conventionally_named_views
64
68
  self.gems = default_gems
65
69
  self.logger = {}
66
70
  self.application = {}
@@ -129,6 +133,10 @@ module RuGUI
129
133
  50
130
134
  end
131
135
 
136
+ def default_automatically_register_conventionally_named_views
137
+ true
138
+ end
139
+
132
140
  def default_gems
133
141
  []
134
142
  end
@@ -0,0 +1,94 @@
1
+ module RuGUI
2
+ module EntityRegistrationSupport
3
+ module ClassMethods
4
+ def register(entity, *names)
5
+ names.each do |name|
6
+ register_entity entity, name
7
+ end
8
+ end
9
+
10
+ private
11
+ def register_entity(entity, name)
12
+ self.entity_registrations[entity] ||= []
13
+ self.entity_registrations[entity] << name
14
+ end
15
+ end
16
+
17
+ def self.included(base)
18
+ base.class_inheritable_accessor :entity_registrations
19
+ base.entity_registrations = {}
20
+ base.extend(ClassMethods)
21
+ end
22
+
23
+ protected
24
+ def register_all(entity)
25
+ if self.entity_registrations.has_key?(entity)
26
+ self.entity_registrations[entity].each do |name|
27
+ register(entity, name)
28
+ end
29
+ end
30
+ end
31
+
32
+ def register(entity, object_or_name, name = nil)
33
+ name = register_name_for(object_or_name, name)
34
+ if should_register?(name)
35
+ object = create_or_get_instance_for(entity, object_or_name)
36
+ setup_instance(entity, name, object)
37
+ call_after_register_for(entity, object, name)
38
+ object
39
+ end
40
+ end
41
+
42
+ private
43
+ def register_name_for(object_or_name, name)
44
+ if object_or_name.is_a?(String) or object_or_name.is_a?(Symbol)
45
+ name || object_or_name.to_s.underscore
46
+ else
47
+ name || object_or_name.class.to_s.underscore
48
+ end
49
+ end
50
+
51
+ def should_register?(name)
52
+ not respond_to?(name) or send(name).nil?
53
+ end
54
+
55
+ def create_or_get_instance_for(entity, object_or_name)
56
+ if object_or_name.is_a?(String) or object_or_name.is_a?(Symbol)
57
+ args = create_instance_arguments_for(entity) || []
58
+ get_instance_for(entity, object_or_name) or create_instance(object_or_name, *args)
59
+ else
60
+ object_or_name
61
+ end
62
+ end
63
+
64
+ def create_instance_arguments_for(entity)
65
+ send("create_instance_arguments_for_#{entity}") if respond_to?("create_instance_arguments_for_#{entity}", true)
66
+ end
67
+
68
+ def get_instance_for(entity, name)
69
+ send("get_instance_for_#{entity}", name) if respond_to?("get_instance_for_#{entity}", true)
70
+ end
71
+
72
+ def create_instance(klass_name, *args)
73
+ klass_name.to_s.camelize.constantize.new(*args)
74
+ end
75
+
76
+ def setup_instance(entity, name, object)
77
+ send("#{entity}s")[name.to_sym] = object
78
+ create_attribute_reader(entity, name)
79
+ end
80
+
81
+ def call_after_register_for(entity, object, name)
82
+ send("after_register_#{entity}", object, name) if respond_to?("after_register_#{entity}", true)
83
+ end
84
+
85
+ # Creates an attribute reader for the some entity.
86
+ def create_attribute_reader(type, name)
87
+ self.class.class_eval <<-class_eval
88
+ def #{name}
89
+ @#{type}s[:#{name}]
90
+ end
91
+ class_eval
92
+ end
93
+ end
94
+ end
@@ -85,6 +85,10 @@ module RuGUI
85
85
  Gtk.main
86
86
  end
87
87
 
88
+ def refresh
89
+ Gtk.main_iteration_do(false) while Gtk.events_pending?
90
+ end
91
+
88
92
  def quit
89
93
  Gtk.main_quit
90
94
  end
@@ -188,7 +192,7 @@ module RuGUI
188
192
  widgets.concat(@unnamed_widgets.select { |widget| widget.kind_of?(widget_type) }) unless @unnamed_widgets.empty?
189
193
 
190
194
  widgets.each do |widget|
191
- widget.signal_connect(signal, &block)
195
+ widget.signal_connect(signal, &block) unless widget.destroyed?
192
196
  end
193
197
  end
194
198
 
@@ -27,6 +27,11 @@ module RuGUI
27
27
  Qt.application.exec
28
28
  end
29
29
 
30
+ def refresh
31
+ # TODO: Vicente Mundim - 03/06/2009 - Implement this method for Qt.
32
+ raise NotImplementedError.new("Sorry, refresh is not implemented for Qt yet!")
33
+ end
34
+
30
35
  def quit
31
36
  Qt.application.exit
32
37
  end
@@ -22,6 +22,13 @@ module RuGUI
22
22
  def run
23
23
  end
24
24
 
25
+ # Refreshes the GUI application, running just one event loop.
26
+ #
27
+ # This method is mostly useful when writing tests. It shouldn't be used
28
+ # in normal applications.
29
+ def refresh
30
+ end
31
+
25
32
  # Exits the application, freeing any resources used by the framework.
26
33
  def quit
27
34
  end
@@ -89,10 +89,12 @@ module RuGUI
89
89
  #
90
90
  def defined_level
91
91
  level = RuGUI.configuration.logger[:level]
92
- unless level
93
- level = DEFAULT_LEVEL
94
- else
92
+ if level
95
93
  level = LEVELS[level]
94
+ elsif ENV["RUGUI_ENV"] == 'test'
95
+ level = LEVELS[:fatal] # log nothing at all
96
+ else
97
+ level = DEFAULT_LEVEL
96
98
  end
97
99
  level
98
100
  end
@@ -95,7 +95,10 @@ module RuGUI
95
95
  if other_observable.respond_to?(property)
96
96
  other_property_value = other_observable.send(property)
97
97
  if other_property_value.class.include?(ObservablePropertySupport)
98
- send(property).copy_observable_properties_from(other_property_value) if deep
98
+ if deep
99
+ send("#{property}=", other_property_value.class.new) if send(property).nil? # Creates an instance of the same class
100
+ send(property).copy_observable_properties_from(other_property_value)
101
+ end
99
102
  else
100
103
  send("#{property}=", other_property_value)
101
104
  end
@@ -0,0 +1,119 @@
1
+ module RuGUI
2
+ module PropertyChangedSupport
3
+ module ClassMethods
4
+ # Invoked when a property was changed.
5
+ #
6
+ # Example:
7
+ # <tt>
8
+ # when_property_changed :name do |observable, new_value, old_value|
9
+ # puts "Hey! The property 'name' of the #{observable.class.name} was changed from #{old_value} to #{new_value}."
10
+ # end
11
+ # </tt>
12
+ #
13
+ # Or you can inform the observable:
14
+ # <tt>
15
+ # when_property_changed :name, :observable => :rabbit do |observable, new_value, old_value|
16
+ # puts "Hey! The property 'name' of the 'rabbit' was changed from #{old_value} to #{new_value}."
17
+ # end
18
+ # </tt>
19
+ #
20
+ # If you can inform a method to be called:
21
+ # <tt>
22
+ # when_property_changed :name, :puts_anything
23
+ #
24
+ # def puts_anything(observable, new_value, old_value)
25
+ # puts "Hey! The property 'name' of the #{observable.class.name} was changed from #{old_value} to #{new_value}."
26
+ # end
27
+ # </tt>
28
+ #
29
+ # Or you can inform the observable and a method to be called.
30
+ # <tt>
31
+ # when_property_changed :name, :observable => :rabbit, :call => :puts_anything
32
+ #
33
+ # def puts_anything(observable, new_value, old_value)
34
+ # puts "Hey! The property 'name' of the 'rabbit' was changed from #{old_value} to #{new_value}."
35
+ # end
36
+ # </tt>
37
+ # </tt>
38
+ #
39
+ def when_property_changed(property, method_or_options = {}, &block)
40
+ property_changed_block = RuGUI::PropertyChangedSupport::PropertyChangedBlock.new
41
+ property_changed_block.property = property
42
+ property_changed_block.set_options(method_or_options)
43
+ property_changed_block.block = block if block_given?
44
+ self.property_changed_blocks << property_changed_block
45
+ end
46
+ end
47
+
48
+ def self.included(base)
49
+ base.class_inheritable_accessor :property_changed_blocks
50
+ base.property_changed_blocks = []
51
+ base.extend(ClassMethods)
52
+ end
53
+
54
+ class PropertyChangedBlock
55
+ attr_accessor :property
56
+ attr_accessor :options
57
+ attr_accessor :block
58
+ attr_accessor :observer
59
+
60
+ # Call the block configurated for the property changed if a block exists for the one.
61
+ def call_property_changed_block_if_exists(observer, observable, property, new_value, old_value)
62
+ self.observer = observer
63
+ call_property_changed_block(observable, new_value, old_value) if block_exists?(observable, property, new_value, old_value)
64
+ end
65
+
66
+ # Set the options given the args.
67
+ def set_options(method_or_options)
68
+ case method_or_options
69
+ when String, Symbol
70
+ self.options = { :call => prepared(method_or_options) }
71
+ when Hash
72
+ self.options = method_or_options
73
+ end
74
+ end
75
+
76
+ protected
77
+ # Check if a block exists for the property changed
78
+ def block_exists?(observable, property, new_value, old_value)
79
+ if self.options.has_key?(:observable)
80
+ return same_observable_and_property?(observable, property)
81
+ else
82
+ return same_property?(property)
83
+ end
84
+ end
85
+
86
+ # Call the block configurated for the property changed.
87
+ def call_property_changed_block(observable, new_value, old_value)
88
+ return if not self.options.has_key?(:call) and self.block.blank?
89
+ if self.options.has_key?(:call)
90
+ method = self.options[:call]
91
+ self.observer.send(method, observable, new_value, old_value) if self.observer.respond_to?(method)
92
+ else
93
+ self.block.call(observable, new_value, old_value) unless self.block.blank?
94
+ end
95
+ end
96
+
97
+ private
98
+ def same_property?(property)
99
+ prepared(self.property) == prepared(property)
100
+ end
101
+
102
+ def same_observable?(observable)
103
+ prepared(self.options[:observable]) == prepared(observable.class.name)
104
+ end
105
+
106
+ def same_observable_and_property?(observable, property)
107
+ same_observable?(observable) and same_property?(property)
108
+ end
109
+
110
+ def prepared(param)
111
+ param.to_s.downcase.underscore
112
+ end
113
+
114
+ def logger
115
+ @logger ||= RuGUILogger.logger
116
+ end
117
+ end
118
+ end
119
+ end
@@ -1,13 +1,13 @@
1
1
  module RuGUI
2
2
  # Adds observer functionality for any class which has support for observable
3
3
  # properties.
4
- #
4
+ #
5
5
  # The observer class should implement a method name
6
6
  # 'property_property_name_changed', where 'property_name' is
7
7
  # the name of the observable property, that will be called whenever that
8
8
  # property value has changed. If it does not declare a method with this
9
9
  # name, it will be silently ignored.
10
- #
10
+ #
11
11
  # The method signature is:
12
12
  #
13
13
  # property_foo_changed(model, new_value, old_value)
@@ -33,15 +33,22 @@ module RuGUI
33
33
  module PropertyObserver
34
34
  include RuGUI::FrameworkAdapters::FrameworkAdapterSupport
35
35
 
36
+ def self.included(base)
37
+ base.send(:include, RuGUI::PropertyChangedSupport)
38
+ end
39
+
36
40
  def property_updated(observable, property, new_value, old_value)
37
41
  queue_method_call_if_exists("property_#{property}_changed", observable, new_value, old_value)
38
42
  queue_method_call_if_exists("property_#{observable.class.name.underscore}_#{property}_changed", observable, new_value, old_value)
43
+ self.property_changed_blocks.each do |property_changed_block|
44
+ property_changed_block.call_property_changed_block_if_exists(self, observable, property, new_value, old_value)
45
+ end
39
46
  end
40
-
47
+
41
48
  def named_observable_property_updated(observable_name, observable, property, new_value, old_value)
42
49
  queue_method_call_if_exists("property_#{observable_name}_#{property}_changed", observable, new_value, old_value) unless named_observable_collides_with_class_name?(observable_name, observable)
43
50
  end
44
-
51
+
45
52
  private
46
53
  def queue_method_call_if_exists(method_name, *args)
47
54
  if respond_to?(method_name)
@@ -50,7 +57,7 @@ module RuGUI
50
57
  end
51
58
  end
52
59
  end
53
-
60
+
54
61
  def named_observable_collides_with_class_name?(observable_name, observable)
55
62
  observable_name == observable.class.name.underscore
56
63
  end
data/lib/rugui/version.rb CHANGED
@@ -2,7 +2,7 @@ module RuGUI
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 1
4
4
  MINOR = 3
5
- TINY = 0
5
+ TINY = 1
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
data/lib/rugui.rb CHANGED
@@ -27,11 +27,13 @@ require 'rugui/log_support'
27
27
  require 'rugui/plugin/loader'
28
28
  require 'rugui/framework_adapters/framework_adapter_support'
29
29
  require 'rugui/base_object'
30
+ require 'rugui/property_changed_support'
30
31
  require 'rugui/observable_property_support'
31
32
  require 'rugui/property_observer'
32
33
  require 'rugui/initialize_hooks'
33
34
  require 'rugui/signal_support'
35
+ require 'rugui/entity_registration_support'
34
36
  require 'rugui/base_controller'
35
37
  require 'rugui/base_model'
36
38
  require 'rugui/base_view_helper'
37
- require 'rugui/base_view'
39
+ require 'rugui/base_view'
@@ -15,6 +15,14 @@ describe RuGUI::BaseController do
15
15
  @controller.my_view.should be_an_instance_of(MyView)
16
16
  @controller.views[:my_view].should == @controller.my_view
17
17
  end
18
+
19
+ describe "with conventionally named controllers and views" do
20
+ it "should automatically register a conventionally named view if it exists" do
21
+ @conventionally_named_controller = ConventionallyNamedController.new
22
+ @conventionally_named_controller.respond_to?(:conventionally_named_view).should be_true
23
+ @conventionally_named_controller.conventionally_named_view.should be_an_instance_of(ConventionallyNamedView)
24
+ end
25
+ end
18
26
  end
19
27
 
20
28
  describe "with model registering" do
@@ -38,6 +46,83 @@ describe RuGUI::BaseController do
38
46
  end
39
47
  end
40
48
 
49
+ describe "with new style registering" do
50
+ before :all do
51
+ RuGUI.configuration.automatically_register_conventionally_named_views = false
52
+ end
53
+
54
+ after :all do
55
+ RuGUI.configuration.automatically_register_conventionally_named_views = true
56
+ end
57
+
58
+ describe "of views" do
59
+ before :each do
60
+ NewStyleController.views :new_style_view
61
+ @controller = NewStyleController.new
62
+ end
63
+
64
+ it "should have the new_style_view registered when instantiated" do
65
+ @controller.views[:new_style_view].should be_an_instance_of(NewStyleView)
66
+ @controller.new_style_view.should be_an_instance_of(NewStyleView)
67
+ @controller.views[:new_style_view].should == @controller.new_style_view
68
+ end
69
+ end
70
+
71
+ describe "of models" do
72
+ before :each do
73
+ NewStyleController.models :new_style_model
74
+ @controller = NewStyleController.new
75
+ end
76
+
77
+ it "should have the new_style_model registered when instantiated" do
78
+ @controller.models[:new_style_model].should be_an_instance_of(NewStyleModel)
79
+ @controller.new_style_model.should be_an_instance_of(NewStyleModel)
80
+ @controller.models[:new_style_model].should == @controller.new_style_model
81
+ end
82
+ end
83
+
84
+ describe "of main models" do
85
+ before :each do
86
+ NewStyleController.main_models :new_style_model
87
+
88
+ @main_controller = RuGUI::BaseMainController.new
89
+ @main_controller.register_model :new_style_model
90
+ @main_controller.register_controller :new_style_controller
91
+
92
+ @controller = @main_controller.new_style_controller
93
+ end
94
+
95
+ it "should have the new_style_model registered when instantiated" do
96
+ @controller.main_models[:new_style_model].should be_an_instance_of(NewStyleModel)
97
+ @controller.new_style_model.should be_an_instance_of(NewStyleModel)
98
+ @controller.main_models[:new_style_model].should == @controller.new_style_model
99
+ end
100
+
101
+ it "should use the same instance that was registered in the main controller" do
102
+ @controller.new_style_model.object_id.should == @main_controller.new_style_model.object_id # object ids should be equals here
103
+ end
104
+
105
+ it "should raise an error if we register a main model which aren't register in the main controller" do
106
+ lambda {
107
+ @controller.register_main_model(:some_inexistent_model)
108
+ }.should raise_error(NoMethodError)
109
+ end
110
+ end
111
+
112
+ describe "of controllers" do
113
+ before :each do
114
+ NewStyleController.controllers :new_style_child_controller
115
+ @controller = NewStyleController.new
116
+ end
117
+
118
+ it "should have the new_style_child_controller registered when instantiated" do
119
+ @controller.controllers[:new_style_child_controller].should be_an_instance_of(NewStyleChildController)
120
+ @controller.new_style_child_controller.should be_an_instance_of(NewStyleChildController)
121
+ @controller.controllers[:new_style_child_controller].should == @controller.new_style_child_controller
122
+ end
123
+ end
124
+ end
125
+
41
126
  describe "with initialization hooks" do
42
127
  it "should call before initialize and after initialize methods" do
43
128
  controller = MyController.new
@@ -210,6 +210,12 @@ describe RuGUI::ObservablePropertySupport do
210
210
  @parent.my_own_observable_property.should == @another_parent.my_own_observable_property
211
211
  @parent.child_observable_property.should_not == @another_parent.child_observable_property
212
212
  end
213
+
214
+ it "should create an instance of the same class and copy observable properties to it if destination object has a nil observable property while source object doesn't" do
215
+ @parent.child_observable_property = nil
216
+ @parent.copy_observable_properties_from(@another_parent)
217
+ @parent.child_observable_property.should == @another_parent.child_observable_property
218
+ end
213
219
  end
214
220
 
215
221
  describe "with observable properties mapped for an instance" do
@@ -7,10 +7,6 @@ class MyController < RuGUI::BaseController
7
7
 
8
8
  attr_accessor :message
9
9
 
10
- def setup_views
11
- register_view :my_view
12
- end
13
-
14
10
  def setup_models
15
11
  register_model :my_model
16
12
  register_model :my_model, :my_other_model_instance
@@ -26,4 +22,13 @@ class MyController < RuGUI::BaseController
26
22
  end
27
23
 
28
24
  class MyChildController < RuGUI::BaseController
29
- end
25
+ end
26
+
27
+ class ConventionallyNamedController < RuGUI::BaseController
28
+ end
29
+
30
+ class NewStyleController < RuGUI::BaseController
31
+ end
32
+
33
+ class NewStyleChildController < RuGUI::BaseController
34
+ end
@@ -7,3 +7,6 @@ class MyModel < RuGUI::BaseModel
7
7
 
8
8
  observable_property :my_property
9
9
  end
10
+
11
+ class NewStyleModel < RuGUI::BaseModel
12
+ end
@@ -69,4 +69,10 @@ class MyOtherView < RuGUI::BaseView
69
69
  end
70
70
 
71
71
  class NoBuilderView < RuGUI::BaseView
72
+ end
73
+
74
+ class ConventionallyNamedView < RuGUI::BaseView
75
+ end
76
+
77
+ class NewStyleView < RuGUI::BaseView
72
78
  end
@@ -3,7 +3,7 @@
3
3
  <!--Generated with glade3 3.4.5 on Thu Aug 28 14:02:01 2008 -->
4
4
  <glade-interface>
5
5
  <widget class="GtkWindow" id="top_window">
6
- <property name="visible">True</property>
6
+ <property name="visible">False</property>
7
7
  <signal name="delete_event" handler="on_top_window_delete_event"/>
8
8
  <child>
9
9
  <widget class="GtkHBox" id="horizontal_container">
@@ -3,7 +3,7 @@
3
3
  <!--Generated with glade3 3.4.5 on Thu Aug 28 14:02:07 2008 -->
4
4
  <glade-interface>
5
5
  <widget class="GtkWindow" id="top_window">
6
- <property name="visible">True</property>
6
+ <property name="visible">False</property>
7
7
  <signal name="delete_event" handler="on_top_window_delete_event"/>
8
8
  <child>
9
9
  <widget class="GtkVBox" id="vertical_container">
data/spec/spec.opts CHANGED
@@ -2,3 +2,4 @@
2
2
  --format progress
3
3
  --loadby mtime
4
4
  --reverse
5
+ --debugger
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rugui
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vicente Mundim
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2009-04-24 00:00:00 -03:00
14
+ date: 2009-07-08 00:00:00 -03:00
15
15
  default_executable: rugui
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
@@ -61,6 +61,7 @@ files:
61
61
  - lib/rugui/base_view.rb
62
62
  - lib/rugui/base_view_helper.rb
63
63
  - lib/rugui/configuration.rb
64
+ - lib/rugui/entity_registration_support.rb
64
65
  - lib/rugui/framework_adapters/GTK.rb
65
66
  - lib/rugui/framework_adapters/Qt4.rb
66
67
  - lib/rugui/framework_adapters/base_framework_adapter.rb
@@ -73,6 +74,7 @@ files:
73
74
  - lib/rugui/observable_property_proxy.rb
74
75
  - lib/rugui/observable_property_support.rb
75
76
  - lib/rugui/plugin/loader.rb
77
+ - lib/rugui/property_changed_support.rb
76
78
  - lib/rugui/property_observer.rb
77
79
  - lib/rugui/signal_support.rb
78
80
  - lib/rugui/tasks/gems_application.rake