rugui 1.3.0 → 1.3.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.
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