Class: RuGUI::BaseView

Inherits:
BaseObject show all
Includes:
InitializeHooks, LogSupport, PropertyObserver, SignalSupport
Defined in:
lib/rugui/base_view.rb,
lib/rugui/framework_adapters/GTK.rb,
lib/rugui/framework_adapters/Qt4.rb

Overview

A base class for views.

To use this class create a subclass and reimplement #setup_widgets, if you want to create your interface by hand. If you want to use a builder file just call #use_builder and, optionally, call #builder_file passing the filename to use.

Each adapter may implement additional features, extending this class, look for it in adapter classes.

The view may have ViewHelpers, which works as ‘models’ for views, i.e., they have observable properties that can be observed by the view. A default helper, named as {view_name}Helper is registered if it exists. For example, for a view named MyView, the default view helper should be named MyViewHelper. This helper can be accessed as a helper attribute. Other helpers may be registered if needed.

Example (using GTK framework adapter):

class MyGladeView < RuGUI::BaseView
  builder_file 'my_file.glade' # this is optional, if the glade file was called my_glade_view.glade this wouldn't be needed.
  root :top_window
  use_builder
end

class MyHandView < RuGUI::BaseView
  def setup_widgets
    # do your hand-made code here...
  end
end

Direct Known Subclasses

ApplicationView

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from InitializeHooks

included, #initialize_with_hooks, update_initialize_method

Methods included from SignalSupport

#autoconnect_declared_signals, included

Methods included from PropertyObserver

included, #named_observable_property_updated, #property_updated

Methods included from FrameworkAdapters::FrameworkAdapterSupport

#framework_adapter_for, included, #load_framework_adapter

Methods included from LogSupport

included, #logger

Methods inherited from BaseObject

#inspect

Constructor Details

#initializeBaseView

Returns a new instance of BaseView.



46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rugui/base_view.rb', line 46

def initialize
  @controllers = {}
  @helpers = {}
  @unnamed_widgets = []
  @widgets = {}

  register_default_helper
  setup_view_helpers
  build_from_builder_file if use_builder?
  setup_widgets
  autoconnect_signals(self)
end

Instance Attribute Details

#controllersObject

Returns the value of attribute controllers.



36
37
38
# File 'lib/rugui/base_view.rb', line 36

def controllers
  @controllers
end

#gladeObject

Returns the value of attribute glade.



188
189
190
# File 'lib/rugui/framework_adapters/GTK.rb', line 188

def glade
  @glade
end

#unnamed_widgetsObject (readonly)

Returns the value of attribute unnamed_widgets.



38
39
40
# File 'lib/rugui/base_view.rb', line 38

def unnamed_widgets
  @unnamed_widgets
end

#widgetsObject (readonly)

Returns the value of attribute widgets.



37
38
39
# File 'lib/rugui/base_view.rb', line 37

def widgets
  @widgets
end

Class Method Details

.builder_file(file) ⇒ Object

Sets the builder file to use when creating this view.



179
180
181
# File 'lib/rugui/base_view.rb', line 179

def builder_file(file)
  self.configured_builder_file = file
end

.framework_adapter_classObject



196
197
198
# File 'lib/rugui/base_view.rb', line 196

def framework_adapter_class
  class_adapter_for('BaseView')
end

.root(root_widget_name) ⇒ Object

Sets the name of the root widget for this view.

This is specially useful when more than one view uses the same glade file, but each one uses a diferent widget tree inside that glade file.

Other use for this is when building a reusable widget, composed of the contents of a glade file. One could create a window, place a vertical box, and then place elements inside this vertical box. Later, this glade file is used to insert the contents of the vertical box inside another vertical box in other glade file.



174
175
176
# File 'lib/rugui/base_view.rb', line 174

def root(root_widget_name)
  self.configured_root = root_widget_name
end

.use_builder(display_root = true) ⇒ Object

Tells whether we should use a builder file when creating this view.

By default the root widget will be displayed, but you can pass false to this method to prevent it for being displayed.



187
188
189
190
191
192
193
194
# File 'lib/rugui/base_view.rb', line 187

def use_builder(display_root = true)
  self.configured_builder_file_usage = true
  self.configured_display_root = display_root

  self.configured_builder_file_extension = self.framework_adapter_class.builder_file_extension
  default_builder_file_path = RuGUI.root.join('app', 'resources', "#{self.configured_builder_file_extension}")
  RuGUI.configuration.builder_files_paths << default_builder_file_path unless RuGUI.configuration.builder_files_paths.include?(default_builder_file_path)
end

.use_gladeObject

Call this method at class level if the view should be built from a glade file.



233
234
235
236
# File 'lib/rugui/framework_adapters/GTK.rb', line 233

def use_glade
  self.logger.warn('DEPRECATED - Call use_builder class method instead in your view.')
  use_builder
end

Instance Method Details

#add_signal_handler_for_widget_type(widget_type, signal, &block) ⇒ Object

Adds a signal handler for all widgets of the given type.



191
192
193
194
195
196
197
198
199
# File 'lib/rugui/framework_adapters/GTK.rb', line 191

def add_signal_handler_for_widget_type(widget_type, signal, &block)
  widgets = []
  widgets.concat(@widgets.values.select { |widget| widget.kind_of?(widget_type) }) unless @widgets.empty?
  widgets.concat(@unnamed_widgets.select { |widget| widget.kind_of?(widget_type) }) unless @unnamed_widgets.empty?

  widgets.each do |widget|
    widget.signal_connect(signal, &block) unless widget.destroyed?
  end
end

#add_widget_to_container(widget, container_widget_or_name) ⇒ Object

Adds the given widget to a container widget.



76
77
78
# File 'lib/rugui/base_view.rb', line 76

def add_widget_to_container(widget, container_widget_or_name)
  self.framework_adapter.add_widget_to_container(widget, from_widget_or_name(container_widget_or_name))
end

#build_from_builder_fileObject

Framework adapters should implement this if they support builder files.



146
147
148
149
150
151
152
# File 'lib/rugui/base_view.rb', line 146

def build_from_builder_file
  filename = get_builder_file
  raise BuilderFileNotFoundError, "Could not find builder file for view #{self.class.name}. UI file paths: #{RuGUI.configuration.builder_files_paths.join(', ')}." if filename.nil?

  self.framework_adapter.build_widgets_from(filename)
  self.framework_adapter.register_widgets
end

#builder_fileObject

Returns the builder file.



131
132
133
# File 'lib/rugui/base_view.rb', line 131

def builder_file
  self.configured_builder_file
end

#builder_file_extensionObject

Returns the builder file extension.



136
137
138
# File 'lib/rugui/base_view.rb', line 136

def builder_file_extension
  self.configured_builder_file_extension
end

#change_widget_style(widget_or_name, widget_path_style) ⇒ Object

Changes the widget style to use the given widget style.

This widget style should be declared in a gtkrc file, by specifying a style using a widget path, such as:

widget "main_window" style "main_window_style"
widget "main_window_other" style "main_window_other_style"

In this example, if you called this method like this:

change_widget_style(:main_window, 'main_window_other')
change_widget_style(self.main_window, 'main_window_other')     # or, passing the widget instance directly

The widget style would be set to “main_window_other_style”.

NOTE: Unfortunately, gtk doesn’t offer an API to get declared styles, so you must set a style to a widget. Since the widget name set in the style definition doesn’t need to point to an existing widget we can use this to simplify the widget styling here.



220
221
222
223
224
225
226
227
228
# File 'lib/rugui/framework_adapters/GTK.rb', line 220

def change_widget_style(widget_or_name, widget_path_style)
  if widget_or_name.is_a?(Gtk::Widget)
    widget = widget_or_name
  else
    widget = @glade[widget_or_name.to_s]
  end
  style = Gtk::RC.get_style_by_paths(Gtk::Settings.default, widget_path_style.to_s, nil, nil)
  widget.style = style
end

#connect(sender, signal, slot, receiver = nil) ⇒ Object

An utility method to connect Qt signals between two Qt::Object.

If receiver is given, it will be used instead of the view itself.



166
167
168
169
170
171
172
173
174
# File 'lib/rugui/framework_adapters/Qt4.rb', line 166

def connect(sender, signal, slot, receiver = nil)
  sender = from_widget_or_name(sender)
  receiver = receiver.nil? ? self : from_widget_or_name(receiver)
  if receiver.is_a?(Qt::Object)
    Qt::Object.connect(sender, SIGNAL(signal), receiver, SLOT(slot))
  elsif receiver.is_a?(RuGUI::BaseObject)
    sender.connect(SIGNAL(signal)) { |*args| receiver.send(slot, *args) if receiver.respond_to?(slot) }
  end
end

#display_root?Boolean

Returns:

  • (Boolean)


159
160
161
# File 'lib/rugui/base_view.rb', line 159

def display_root?
  !!self.configured_display_root
end

#framework_adapterObject

Returns the framework_adapter for this class.



63
64
65
# File 'lib/rugui/base_view.rb', line 63

def framework_adapter
  framework_adapter_for('BaseView')
end

#include_view(container_widget_name, view) ⇒ Object

Includes a view root widget inside the given container widget.



86
87
88
89
# File 'lib/rugui/base_view.rb', line 86

def include_view(container_widget_name, view)
  raise RootWidgetNotSetForIncludedView, "You must set a root for views to be included." if view.root_widget.nil?
  add_widget_to_container(view.root_widget, container_widget_name)
end

#post_registration(controller) ⇒ Object

Called after the view is registered in a controller.



122
123
# File 'lib/rugui/base_view.rb', line 122

def post_registration(controller)
end

#register_controller(controller, name = nil) ⇒ Object

Registers a controller as receiver of signals from the view widgets.



103
104
105
106
107
# File 'lib/rugui/base_view.rb', line 103

def register_controller(controller, name = nil)
  name ||= controller.class.to_s.underscore
  autoconnect_signals(controller)
  @controllers[name.to_sym] = controller
end

#register_helper(helper, name = nil) ⇒ Object

Registers a view helper for the view.



110
111
112
113
114
115
116
117
118
119
# File 'lib/rugui/base_view.rb', line 110

def register_helper(helper, name = nil)
  helper = create_instance_if_possible(helper) if helper.is_a?(String) or helper.is_a?(Symbol)
  unless helper.nil?()
    name ||= helper.class.to_s.underscore
    helper.register_observer(self, name)
    @helpers[name.to_sym] = helper
    create_attribute_reader(:helpers, name)
    helper.post_registration(self)
  end
end

#remove_all_children(container_widget) ⇒ Object

Removes all children from the given container widget



98
99
100
# File 'lib/rugui/base_view.rb', line 98

def remove_all_children(container_widget)
  self.framework_adapter.remove_all_children(container_widget)
end

#remove_view(container_widget_name, view) ⇒ Object

Removes a view root widget from the given container widget.



92
93
94
95
# File 'lib/rugui/base_view.rb', line 92

def remove_view(container_widget_name, view)
  raise RootWidgetNotSetForIncludedView, "You must set a root for views to be removed." if view.root_widget.nil?
  remove_widget_from_container(view.root_widget, container_widget_name)
end

#remove_widget_from_container(widget, container_widget_or_name) ⇒ Object

Adds the given widget to a container widget.



81
82
83
# File 'lib/rugui/base_view.rb', line 81

def remove_widget_from_container(widget, container_widget_or_name)
  self.framework_adapter.remove_widget_from_container(widget, from_widget_or_name(container_widget_or_name))
end

#rootObject

Returns the name of the root widget for this view.



155
156
157
# File 'lib/rugui/base_view.rb', line 155

def root
  self.configured_root.to_s unless self.configured_root.nil?
end

#root_widgetObject

Returns the root widget if one is set.



126
127
128
# File 'lib/rugui/base_view.rb', line 126

def root_widget
  send(root.to_sym) if not root.nil?
end

#setup_view_helpersObject

Reimplement this method to setup view helpers.



72
73
# File 'lib/rugui/base_view.rb', line 72

def setup_view_helpers
end

#setup_widgetsObject

Reimplement this method to create widgets by hand.



68
69
# File 'lib/rugui/base_view.rb', line 68

def setup_widgets
end

#use_builder?Boolean

Returns true if builder file is being used for this view.

Returns:

  • (Boolean)


141
142
143
# File 'lib/rugui/base_view.rb', line 141

def use_builder?
  self.configured_builder_file_usage
end