Module: GladeGUI
- Included in:
- VR::Alert, VR::Col::BlobCol, VR::Col::CalendarCol, VR::Col::ImageCol, VR::FileTreeView, VR::ObjectInspector::ObjectInspectorGUI
- Defined in:
- lib/GladeGUI.rb
Overview
GladeGUI connects your class to a glade form. It will load a .glade file into memory, enabling your ruby programs to have a GUI interface.
GladeGUI works by adding an instance variable named “builder” to your class. The “builder” variable is an instance of Gtk::Builder It holds references to all your windows and widgets.
Include the GladeGUI interface
To use the GladeGUI interface, include this line in your code:
class MyClass
include GladeGUI
end
GladeGUI will load a corresponding glade file for this class. It knows which glade file to load by using a naming convention:
/folder/MyClass.rb
Will load this glade file:
/folder/glade/MyClass.glade
The class, the class file name and the glade file name must match. You should always name your class, script, and glade file the same name (case sensitive).
builder
variable holds all your widgets
So when you “load” your class's glade file where is it loaded?
GladeGUI adds an instance variable, builder to your class. It loads all the
windows and widgets from your glade file into @builder. So, you use
@builder
to manipulate everything in you class's GUI.
@builder
is set when you call the show_glade() method, as this
code shows:
class MyClass
include GladeGUI
def initialize()
puts @builder.to_s # => nil
end
def before_show()
puts @builder.to_s # => Gtk::Builder
end
end
After show_glade() is called, you can access any of your form's windows or widgets using the @builder variable:
@builder["window1"].title = "This is the title that appears at the top."
Here's another example: Suppose you have a glade form with a Gtk::Entry box on it named “email.” You could set the text that appears in the Gtk::Entry by setting the Gtk::Entry#text property:
@builder["email"].text = "harvey@harveyserver.com"
Now the email adddess is set with a new value:
Auto fill your glade form
You can streamline the process of setting-up your forms by auto-filling the widgets from instance variables with the same name.
When assigning names to widgets in glade, give them names that correspond to your instance variables. For example, if you want to edit an email address on the glade form, create an instance variable named @email in your class. Then, in glade, you add a Gtk::Entry widget to your form and set its name to “email”. The advantage of this is that GladeGUI will populate the “email” widget in glade using the @email variable. so you don’t need to include the above line of code. (see set_glade_variables() method.)
Instance Attribute Summary collapse
-
#builder ⇒ Gtk::Builder
The builder that holds references to everything in the glade form.
Instance Method Summary collapse
-
#buttonCancel__clicked(*a) ⇒ Object
Convenience method so you can just make a button named “buttonCancel” and it will work.
-
#extract_key(widget) ⇒ String
retrieves the key inside a glade control name.
- #get_glade_active_record(obj) ⇒ Object
-
#get_glade_all(obj = self) ⇒ Object
This method is the most useful method to retreive values from a glade form.
-
#get_glade_variables(obj = self) ⇒ Object
Populates your instance variables from the glade form.
-
#load_glade ⇒ Object
This will Load the glade form according to the naming convention: MyClass.rb => MyClass.glade.
-
#parse_signals ⇒ Object
Connects gtk's signals to your methods according to the naming convention widget__signal.
-
#set_drag_drop(hash) ⇒ Object
drag_to() will make it so you can drag-n-drop the source_widget onto the target widget.
-
#set_glade_active_record(obj = self) ⇒ Object
Populates the glade form from the fields of an ActiveRecord object.
-
#set_glade_all(obj = self) ⇒ Object
This method is the most useful method to populate a glade form.
-
#set_glade_hash(hash) ⇒ Object
Matches names in glade form to keys in a Hash.
-
#set_glade_variables(obj = self) ⇒ Object
Populates the glade form from the instance variables of the class.
-
#show_glade(parent = nil) ⇒ Object
The method you call to show the glade form.
- #try_to_select_text_in_combobox(cb, text) ⇒ Object
-
#window1__destroy(*args) ⇒ Object
Called when window is destroyed when you execute: @builder.destroy It manages the Gtk.main loop for all the windows.
- #window1__key_press_event(view, evt) ⇒ Object
Instance Attribute Details
#builder ⇒ Gtk::Builder
Returns The builder that holds references to everything in the glade form.
87 88 89 |
# File 'lib/GladeGUI.rb', line 87 def builder @builder end |
Instance Method Details
#buttonCancel__clicked(*a) ⇒ Object
Convenience method so you can just make a button named “buttonCancel” and it will work. This method isn't called in code, its triggered by a user clicking a button named “buttonCancel”.
402 403 404 |
# File 'lib/GladeGUI.rb', line 402 def (*a) @builder[:window1].destroy end |
#extract_key(widget) ⇒ String
retrieves the key inside a glade control name. Useful when handling events where the control name is returned, and you need to match it to an actual hash.
419 420 421 |
# File 'lib/GladeGUI.rb', line 419 def extract_key() .builder_name[/\[.+?\]/] end |
#get_glade_active_record(obj) ⇒ Object
446 447 448 449 450 451 452 |
# File 'lib/GladeGUI.rb', line 446 def get_glade_active_record(obj) return if not defined? obj.attributes obj.attributes.each_pair do |key, val| new_val = get_control_value(key, obj) obj.send("#{key}=", new_val) unless new_val.nil? end end |
#get_glade_all(obj = self) ⇒ Object
This method is the most useful method to retreive values from a glade form. It will
populate from active_record fields and instance variables. It will simply
call both of these methods:
get_glade_active_record()
get_glade_variables()
So, to retreive all the values of a form back into your ActiveRecord object and instance variables, simply call the set_glade_all() method instead.
209 210 211 212 |
# File 'lib/GladeGUI.rb', line 209 def get_glade_all(obj = self) get_glade_active_record(obj) get_glade_variables(obj) end |
#get_glade_variables(obj = self) ⇒ Object
Populates your instance variables from the glade form. This works for Gtk:Button, Gtk::Entry, Gtk::Label and Gtk::Checkbutton. So instead of having to assign instance variable:
You can write one line of code:
The optional parameter is seldom used because you usually want the glade form to populate from the calling class. If you passed another object, the form would populate from it.
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/GladeGUI.rb', line 317 def get_glade_variables(obj = self) obj.instance_variables.each do |var_name| next if var_name == :@builder or var_name == :@top_level_window var = obj.instance_variable_get(var_name) var_name = var_name.to_s.gsub("@", "") #fix for ruby 1.9 giving symbols if var.is_a? Hash var.each_pair do |key, val| if glade_value = get_control_value("#{var_name}[#{key.to_s}]", obj) var[key] = glade_value end end obj.instance_variable_set("@"+ var_name, var) elsif var.is_a? Array var.each_index do |i| if glade_value = get_control_value("#{var_name}[#{i.to_s}]", obj) var[i] = glade_value end end obj.instance_variable_set("@"+ var_name, var) else glade_value = get_control_value(var_name, obj) obj.instance_variable_set("@"+ var_name, glade_value) unless glade_value.nil? end end end |
#load_glade ⇒ Object
This will Load the glade form according to the naming convention:
MyClass.rb => MyClass.glade.
It will create a Gtk::Builder object from your glade file. The Gtk::Builder object is stored in the instance variable, @builder. You can get a reference to any of the widgets on the glade form by using the @builder object:
Normally, you should give your widgets names of instance variables: i.e. @email so they can be autoloaded when the glade form is shown using the #show_glade method. For example, the value of the @email vaiable would be loaded into a Gtk:Entry named “email” in your glade form. It saves you from having to do this:
130 131 132 133 134 135 136 |
# File 'lib/GladeGUI.rb', line 130 def load_glade() caller__FILE__ = my_class_file_path() file_name = File.join(File.split(caller__FILE__)[0] , "glade", class_name(self) + ".glade") @builder = Gtk::Builder.new @builder << file_name @builder.connect_signals{ |handle| method(handle) } end |
#parse_signals ⇒ Object
Connects gtk's signals to your methods according to the naming convention widget__signal. For example,
when you place a button called "button1" in your glade form, and declare a method called
"button1__clicked", they aren't connected to each other. Clicking on the button does nothing
and the method never gets called. After running parse_signals(), the "clicked" signal is
connected to the method named "button1__clicked" so when the user clicks the button, the method is called.
Remember that it will enforce the naming convention: name__signal (two underscores).
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/GladeGUI.rb', line 154 def parse_signals() meths = self.class.instance_methods() meths.each do |meth| meth = meth.to_s #bug fix ruby 1.9 gives stmbol glade_name, signal_name = *(meth.split("__")) next if (signal_name.to_s == "" or glade_name.to_s == "") #covers nil if @builder @builder.objects.each do |obj| next unless obj.respond_to?(:builder_name) if obj.builder_name == glade_name or obj.builder_name =~ /^(?:#{class_name(self)}\.|)#{glade_name}\[[a-zA-Z\d_-]+\]$/ #arrays obj.signal_connect(signal_name) { |*args| method(meth.to_sym).call(*args) } end end end obj = glade_name == "self" ? self : self.instance_variable_get("@" + glade_name) obj ||= eval(glade_name) if respond_to?(glade_name) and method(glade_name.to_sym).arity == 0 # no arguments! if obj.respond_to?("signal_connect") obj.signal_connect(signal_name) { |*args| method(meth.to_sym).call(*args) } end end end |
#set_drag_drop(hash) ⇒ Object
drag_to() will make it so you can drag-n-drop the source_widget onto the target widget.
You may pass a reference to a widget object, or a String that gives the name of the
widget on your glade form. So, it functions the same as this statement:
widget_source.drag_to(widget_target)
It also functions the same as this statement:
@builder["widget_source"].drag_to(@builder["widget_target"])
100 101 102 103 104 105 106 107 |
# File 'lib/GladeGUI.rb', line 100 def set_drag_drop(hash) hash.each do |key,val| src = key.is_a?(Gtk::Widget) ? key : @builder[key] target = @builder[val] src.extend(VR::Draggable) unless src.is_a?(VR::Draggable) src.(target) end end |
#set_glade_active_record(obj = self) ⇒ Object
Populates the glade form from the fields of an ActiveRecord object. So instead of having to assign each widget a value: You can write one line of code: The optional parameter is seldom used because you usually want the glade form to populate from the calling class. If you passed another object, the form would populate from it.
441 442 443 444 |
# File 'lib/GladeGUI.rb', line 441 def set_glade_active_record(obj = self) return if not defined? obj.attributes obj.attributes.each_pair { |key, val| fill_control(class_name(obj) + "." + key, val) } end |
#set_glade_all(obj = self) ⇒ Object
This method is the most useful method to populate a glade form. It will
populate from active_record fields and instance variables. It will simply
call both of these methods:
set_glade_active_record()
set_glade_variables()
So, to set all the values of a form, simply call the set_glade_all() method instead.
196 197 198 199 |
# File 'lib/GladeGUI.rb', line 196 def set_glade_all(obj = self) set_glade_active_record(obj) set_glade_variables(obj) end |
#set_glade_hash(hash) ⇒ Object
Matches names in glade form to keys in a Hash.
218 219 220 221 |
# File 'lib/GladeGUI.rb', line 218 def set_glade_hash(hash) return unless hash.is_a?(Hash) hash.each { |key,val| fill_control( key.to_s, val.to_s) } end |
#set_glade_variables(obj = self) ⇒ Object
Populates the glade form from the instance variables of the class. So instead of having to assign each widget a value:
@builder["name"].text = @name
@builder["address"].text = @address
@builder["email"].text = @eamil
@builder["phone"].text = @phone
you can write one line of code:
set_glade_variables()
The optional parameter is seldom used because you usually want the glade form to populate from the calling class. If you passed another object, the form would populate from it.
obj - type Object
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/GladeGUI.rb', line 241 def set_glade_variables(obj = self) obj.instance_variables.each do |name| name = name.to_s #ruby 1.9 passes symbol! v = obj.instance_variable_get(name) name = name.gsub('@', '') if v.is_a?(Array) v.each_index do |i| fill_control("#{name}[#{i.to_s}]", v[i] ) end elsif v.is_a?(Hash) v.each_pair do |key, val| fill_control("#{name}[#{key.to_s}]", val) end else fill_control(name, v) end end end |
#show_glade(parent = nil) ⇒ Object
The method you call to show the glade form.
It loads the glade form, sets all the form's widgets to your instance variables, connects all your methods to their signals, and starts Gtk.main loop if necessary.
381 382 383 384 385 386 387 388 389 390 391 392 |
# File 'lib/GladeGUI.rb', line 381 def show_glade(parent = nil) load_glade() if parent then @builder[:window1].transient_for = parent.builder[:window1] end before_show() if respond_to? :before_show parse_signals() set_glade_all() @builder[:window1].show #show_all can't hide widgets in before_show @top_level_window = Gtk.main_level == 0 ? true : false Gtk.main if @top_level_window or @builder[:window1].modal? # need new Gtk.main for blocking! end |
#try_to_select_text_in_combobox(cb, text) ⇒ Object
284 285 286 287 288 289 290 291 292 293 |
# File 'lib/GladeGUI.rb', line 284 def try_to_select_text_in_combobox(cb, text) i = 0 cb.model.each do |model, path, iter| if iter[0] == text cb.active = i return end i = i + 1 end end |
#window1__destroy(*args) ⇒ Object
Called when window is destroyed when you execute:
@builder[:window1].destroy
It manages the Gtk.main loop for
all the windows.
396 397 398 |
# File 'lib/GladeGUI.rb', line 396 def window1__destroy(*args) Gtk.main_quit if @top_level_window or @builder["window1"].modal? end |
#window1__key_press_event(view, evt) ⇒ Object
406 407 408 409 |
# File 'lib/GladeGUI.rb', line 406 def window1__key_press_event(view, evt) return unless evt.keyval == Gdk::Keyval::KEY_F8 oinspect end |