visualruby 1.0.19 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Splash.rb +40 -0
- data/bin/editor/VR_Document.rb +81 -74
- data/bin/editor/VR_TabSearch.rb +5 -7
- data/bin/editor/VR_Tabs.rb +57 -36
- data/bin/editor/VR_TextShell.rb +12 -34
- data/bin/editor/VR_TextViewCommon.rb +9 -28
- data/bin/main/NewProjectGUI.rb +14 -13
- data/bin/main/OpenProject.rb +69 -0
- data/bin/main/ProjectChooserView.rb +3 -2
- data/bin/main/ProjectTree.rb +25 -0
- data/bin/main/RubygemsAPI.rb +15 -11
- data/bin/main/VR_ENV.rb +38 -60
- data/bin/main/VR_ENV_GLOBAL.rb +45 -44
- data/bin/main/VR_File_Tree.rb +29 -21
- data/bin/main/VR_Local_Gem_Tree.rb +4 -19
- data/bin/main/VR_Main.rb +128 -144
- data/bin/main/VR_Remote_Gem_Tree.rb +6 -19
- data/bin/main/glade/NewProjectGUI.glade +94 -98
- data/bin/main/glade/OpenProject.glade +259 -0
- data/bin/main/glade/RubygemsAPI.glade +98 -62
- data/bin/main/glade/VR_ENV.glade +46 -55
- data/bin/main/glade/VR_ENV_GLOBAL.glade +251 -180
- data/bin/main/glade/VR_File_Tree.glade +25 -16
- data/bin/main/glade/VR_Local_Gem_Tree.glade +16 -8
- data/bin/main/glade/VR_Main.glade +410 -449
- data/bin/main/glade/VR_Remote_Gem_Tree.glade +33 -31
- data/bin/tools/VR_Tools.rb +60 -46
- data/{visualruby_examples → examples}/active_record/active_record.rb +16 -10
- data/{visualruby_examples → examples}/active_record/bin/ChoosePerson.rb +7 -0
- data/examples/active_record/bin/Person.rb +21 -0
- data/examples/active_record/bin/glade/ChoosePerson.glade +89 -0
- data/examples/active_record/bin/glade/Person.glade +197 -0
- data/{visualruby_examples → examples}/active_record/db/development.sqlite3 +0 -0
- data/{visualruby_examples → examples}/active_record2/bin/CompanyGUI.rb +7 -7
- data/{visualruby_examples → examples}/active_record2/bin/Employee.rb +0 -0
- data/{visualruby_examples → examples}/active_record2/bin/Employer.rb +0 -0
- data/{visualruby_examples → examples}/active_record2/bin/Paycheck.rb +0 -0
- data/examples/active_record2/bin/glade/CompanyGUI.glade +149 -0
- data/examples/active_record2/bin/glade/Employee.glade +126 -0
- data/{visualruby_examples → examples}/active_record2/bin/glade/Employer.glade +0 -0
- data/{visualruby_examples → examples}/active_record2/bin/glade/Paycheck.glade +0 -0
- data/{visualruby_examples → examples}/active_record2/db/development.sqlite3 +0 -0
- data/{visualruby_examples → examples}/active_record2/main.rb +15 -9
- data/examples/alert_box/bin/AlertBoxDemo.rb +80 -0
- data/examples/alert_box/bin/glade/AlertBoxDemo.glade +234 -0
- data/examples/alert_box/main.rb +12 -0
- data/{visualruby_examples → examples}/all_widgets/bin/AllWidgets.rb +18 -10
- data/{visualruby_examples → examples}/all_widgets/bin/glade/AllWidgets.glade +52 -16
- data/{visualruby_examples → examples}/all_widgets/bin/splash.png +0 -0
- data/examples/all_widgets/main.rb +12 -0
- data/{visualruby_examples → examples}/calculator/bin/Calculator.rb +23 -22
- data/{visualruby_examples → examples}/calculator/bin/glade/Calculator.glade +81 -51
- data/examples/calculator/main.rb +13 -0
- data/examples/child_window/bin/ChildWindowDemo.rb +52 -0
- data/examples/child_window/bin/ModalWindow.rb +9 -0
- data/examples/child_window/bin/ModelessWindow.rb +9 -0
- data/examples/child_window/bin/MyChildClass.rb +21 -0
- data/examples/child_window/bin/glade/ChildWindowDemo.glade +87 -0
- data/examples/child_window/bin/glade/ModalWindow.glade +61 -0
- data/examples/child_window/bin/glade/ModelessWindow.glade +61 -0
- data/{visualruby_examples → examples}/child_window/bin/glade/MyChildClass.glade +14 -12
- data/examples/child_window/main.rb +12 -0
- data/{visualruby_examples → examples}/drag_drop/bin/DragDropDemo.rb +9 -10
- data/examples/drag_drop/bin/glade/DragDropDemo.glade +161 -0
- data/{visualruby_examples → examples}/drag_drop/img/folder.png +0 -0
- data/{visualruby_examples → examples}/drag_drop/img/glade.png +0 -0
- data/{visualruby_examples → examples}/drag_drop/img/gtk-edit.png +0 -0
- data/{visualruby_examples → examples}/drag_drop/img/obj.png +0 -0
- data/{visualruby_examples → examples}/drag_drop/img/png.png +0 -0
- data/{visualruby_examples → examples}/drag_drop/img/rb.png +0 -0
- data/{visualruby_examples → examples}/drag_drop/img/ruby.png +0 -0
- data/{visualruby_examples → examples}/drag_drop/img/unknown.png +0 -0
- data/examples/drag_drop/main.rb +11 -0
- data/examples/filetreeview/bin/ProjectTree.rb +32 -0
- data/examples/filetreeview/bin/ProjectTreeGUI.rb +28 -0
- data/examples/filetreeview/bin/glade/ProjectTreeGUI.glade +156 -0
- data/examples/filetreeview/main.rb +13 -0
- data/{visualruby_examples → examples}/listview/bin/SongListView.rb +24 -20
- data/{visualruby_examples → examples}/listview/bin/SongListViewGUI.rb +12 -11
- data/{visualruby_examples → examples}/listview/bin/audio-x-generic.png +0 -0
- data/examples/listview/bin/glade/SongListViewGUI.glade +195 -0
- data/examples/listview/main.rb +10 -0
- data/examples/listview_objects/bin/DataObject.rb +53 -0
- data/{visualruby_examples → examples}/listview_objects/bin/ListViewObjects.rb +7 -4
- data/examples/listview_objects/bin/ListViewObjectsGUI.rb +26 -0
- data/examples/listview_objects/bin/glade/DataObject.glade +196 -0
- data/examples/listview_objects/bin/glade/ListViewObjectsGUI.glade +87 -0
- data/examples/listview_objects/main.rb +12 -0
- data/examples/settings_file/bin/MainApp.rb +38 -0
- data/examples/settings_file/bin/SavableSettings.rb +39 -0
- data/examples/settings_file/bin/glade/MainApp.glade +87 -0
- data/examples/settings_file/bin/glade/SavableSettings.glade +162 -0
- data/examples/settings_file/main.rb +14 -0
- data/examples/settings_file/settings.yaml +15 -0
- data/examples/simple_ruby_gui/bin/DataObjectGUI.rb +21 -0
- data/examples/simple_ruby_gui/bin/glade/DataObjectGUI.glade +195 -0
- data/examples/simple_ruby_gui/main.rb +16 -0
- data/{visualruby_examples → examples}/treeview/bin/MyClass.rb +1 -5
- data/examples/treeview/bin/glade/MyClass.glade +24 -0
- data/examples/treeview/main.rb +13 -0
- data/skeleton/document/New.glade +3 -4
- data/skeleton/document/NewWindow.rb +1 -1
- data/skeleton/project/bin/MyClass.rb +2 -2
- data/skeleton/project/bin/glade/MyClass.glade +12 -26
- data/skeleton/project/main.rb +4 -8
- data/vr +41 -37
- data/vrlib/lib/Alert.rb +67 -0
- data/vrlib/lib/DragDrop.rb +90 -0
- data/vrlib/lib/GladeGUI.rb +433 -0
- data/vrlib/lib/IconHash.rb +18 -0
- data/vrlib/lib/SavableClass.rb +56 -0
- data/vrlib/lib/SimpleComboBoxEntry.rb +8 -0
- data/vrlib/lib/glade/Alert.glade +119 -0
- data/vrlib/lib/treeview/FileTreeView.rb +113 -0
- data/vrlib/lib/treeview/IterMethods.rb +82 -0
- data/vrlib/lib/treeview/ListView.rb +85 -0
- data/vrlib/lib/treeview/TreeView.rb +43 -0
- data/vrlib/lib/treeview/ViewCommon.rb +370 -0
- data/vrlib/lib/treeview/columns/CalendarCol.rb +89 -0
- data/vrlib/lib/treeview/columns/CellRendererCombo.rb +66 -0
- data/vrlib/lib/treeview/columns/CellRendererDate.rb +45 -0
- data/vrlib/lib/treeview/columns/CellRendererObject.rb +57 -0
- data/vrlib/lib/treeview/columns/CellRendererPhone.rb +45 -0
- data/vrlib/lib/treeview/columns/CellRendererPixbuf.rb +16 -0
- data/vrlib/lib/treeview/columns/CellRendererProgress.rb +17 -0
- data/vrlib/lib/treeview/columns/CellRendererSpin.rb +37 -0
- data/vrlib/lib/treeview/columns/CellRendererText.rb +38 -0
- data/vrlib/lib/treeview/columns/CellRendererToggle.rb +47 -0
- data/vrlib/lib/treeview/columns/ComboCol.rb +43 -0
- data/vrlib/lib/treeview/columns/CurrencyCol.rb +23 -0
- data/vrlib/lib/treeview/columns/DateCol.rb +20 -0
- data/vrlib/lib/treeview/columns/ImageCol.rb +27 -0
- data/vrlib/lib/treeview/columns/ProgressCol.rb +27 -0
- data/vrlib/lib/treeview/columns/SpinCol.rb +11 -0
- data/vrlib/lib/treeview/columns/TextCol.rb +65 -0
- data/vrlib/lib/treeview/columns/TreeViewColumn.rb +93 -0
- data/{bin/main/glade/ProjectChooserGUI.glade → vrlib/lib/treeview/columns/glade/CalendarCol.glade} +71 -63
- data/{bin/main/glade/Splash.glade → vrlib/lib/treeview/columns/glade/ImageCol.glade} +5 -6
- data/vrlib/lib/treeview/columns/glade/TextCol.glade +82 -0
- data/vrlib/rdoc_replace.yaml +77 -0
- data/vrlib/vrlib.rb +7 -0
- metadata +163 -136
- data/bin/editor/glade/VR_Document.glade +0 -160
- data/bin/main/ProjectChooserGUI.rb +0 -41
- data/bin/main/Splash.rb +0 -22
- data/visualruby_examples/active_record/.vr_settings.yaml +0 -47
- data/visualruby_examples/active_record/bin/Person.rb +0 -13
- data/visualruby_examples/active_record/bin/glade/ChoosePerson.glade +0 -61
- data/visualruby_examples/active_record/bin/glade/Person.glade +0 -148
- data/visualruby_examples/active_record2/.vr_settings.yaml +0 -16
- data/visualruby_examples/active_record2/bin/glade/CompanyGUI.glade +0 -167
- data/visualruby_examples/active_record2/bin/glade/Employee.glade +0 -123
- data/visualruby_examples/all_widgets/.vr_settings.yaml +0 -13
- data/visualruby_examples/all_widgets/main.rb +0 -14
- data/visualruby_examples/calculator/.vr_settings.yaml +0 -11
- data/visualruby_examples/calculator/main.rb +0 -13
- data/visualruby_examples/child_window/.vr_settings.yaml +0 -16
- data/visualruby_examples/child_window/bin/ChildWindowDemo.rb +0 -39
- data/visualruby_examples/child_window/bin/MyChildClass.rb +0 -40
- data/visualruby_examples/child_window/bin/glade/ChildWindowDemo.glade +0 -101
- data/visualruby_examples/child_window/main.rb +0 -13
- data/visualruby_examples/drag_drop/.vr_settings.yaml +0 -12
- data/visualruby_examples/drag_drop/bin/glade/DragDropDemo.glade +0 -143
- data/visualruby_examples/drag_drop/main.rb +0 -14
- data/visualruby_examples/listview/.vr_settings.yaml +0 -12
- data/visualruby_examples/listview/bin/glade/SongListViewGUI.glade +0 -220
- data/visualruby_examples/listview/main.rb +0 -19
- data/visualruby_examples/listview_objects/.vr_settings.yaml +0 -16
- data/visualruby_examples/listview_objects/bin/DataObject.rb +0 -32
- data/visualruby_examples/listview_objects/bin/DataObjectGUI.rb +0 -41
- data/visualruby_examples/listview_objects/bin/ListViewObjectsGUI.rb +0 -18
- data/visualruby_examples/listview_objects/bin/glade/DataObject.glade +0 -198
- data/visualruby_examples/listview_objects/bin/glade/ListViewObjectsGUI.glade +0 -102
- data/visualruby_examples/listview_objects/main.rb +0 -13
- data/visualruby_examples/simple_ruby_gui/.vr_settings.yaml +0 -16
- data/visualruby_examples/simple_ruby_gui/bin/DataObjectGUI.rb +0 -20
- data/visualruby_examples/simple_ruby_gui/bin/glade/DataObjectGUI.glade +0 -163
- data/visualruby_examples/simple_ruby_gui/main.rb +0 -16
- data/visualruby_examples/treeview/.vr_settings.yaml +0 -12
- data/visualruby_examples/treeview/bin/glade/MyClass.glade +0 -48
- data/visualruby_examples/treeview/main.rb +0 -14
@@ -0,0 +1,113 @@
|
|
1
|
+
|
2
|
+
module VR
|
3
|
+
|
4
|
+
class FileTreeView < VR::TreeView # :nodoc:
|
5
|
+
|
6
|
+
include GladeGUI
|
7
|
+
|
8
|
+
attr_accessor :root, :glob, :test_block
|
9
|
+
|
10
|
+
def initialize(root = Dir.pwd, icon_path = nil, glob = "*")
|
11
|
+
@root = root
|
12
|
+
@glob = glob
|
13
|
+
super(:file => {:pix => Gdk::Pixbuf, :file_name => String}, :empty => TrueClass, :path => String, :modified_date => VR::DateCol, :sort_on => String)
|
14
|
+
col_visible( :path => false, :modified_date => false, :sort_on => false, :empty => false)
|
15
|
+
self.headers_visible = false
|
16
|
+
@icons = File.directory?(icon_path) ? VR::IconHash.new(icon_path) : nil
|
17
|
+
parse_signals()
|
18
|
+
model.set_sort_column_id(id(:sort_on), :ascending )
|
19
|
+
self.set_enable_search(false)
|
20
|
+
refresh
|
21
|
+
self.visible = true # necessary!
|
22
|
+
end
|
23
|
+
|
24
|
+
# flags: :root => root path, :open_folders => array of paths to open
|
25
|
+
def refresh(flags={})
|
26
|
+
@root = flags[:root] if flags[:root]
|
27
|
+
open_folders = flags[:open_folders] ? flags[:open_folders] : get_open_folders()
|
28
|
+
model.clear
|
29
|
+
@root_iter = add_file(@root, nil)
|
30
|
+
fill_folder(@root_iter)
|
31
|
+
expand_row(@root_iter.path, false)
|
32
|
+
open_folders(open_folders)
|
33
|
+
end
|
34
|
+
|
35
|
+
def fill_folder(parent_iter)
|
36
|
+
model.remove(parent_iter.first_child) #remove dummy record
|
37
|
+
files = Dir.glob(File.join(parent_iter[id(:path)],@glob))
|
38
|
+
files = files.select &@test_block if @test_block
|
39
|
+
files.each do |fn|
|
40
|
+
add_file(fn, parent_iter)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self__row_expanded(view, iter, path)
|
45
|
+
iter = model.get_iter(path) #bug fix
|
46
|
+
fill_folder(iter) if iter[id(:empty)]
|
47
|
+
expand_row(iter.path, false)
|
48
|
+
end
|
49
|
+
|
50
|
+
def expand_or_collapse_folder()
|
51
|
+
return unless row = selected_rows.first
|
52
|
+
if row_expanded?(row.path)
|
53
|
+
collapse_row(row.path)
|
54
|
+
else
|
55
|
+
self__row_expanded(self, row, row.path)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_open_folders()
|
60
|
+
expanded = []
|
61
|
+
map_expanded_rows {|view, path| expanded << model.get_iter(path)[id(:path)] }
|
62
|
+
return expanded
|
63
|
+
end
|
64
|
+
|
65
|
+
def open_folders(folder_paths)
|
66
|
+
model.each do |model, path, iter|
|
67
|
+
if folder_paths.include?(iter[id(:path)])
|
68
|
+
expand_row(path, false)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_file(filename, parent = @root_iter)
|
74
|
+
my_path = File.dirname(filename)
|
75
|
+
model.each do |model, path, iter|
|
76
|
+
return if iter[id(:path)] == filename # duplicate
|
77
|
+
parent = iter if iter[id(:path)] == my_path
|
78
|
+
end
|
79
|
+
fn = filename.gsub("\\", "/")
|
80
|
+
parent[id(:empty)] = false unless parent.nil?
|
81
|
+
child = add_row(parent)
|
82
|
+
child[:pix] = @icons.get_icon(File.directory?(fn) ? "x.folder" : fn) if @icons
|
83
|
+
child[:file_name] = File.basename(fn)
|
84
|
+
child[:path] = fn
|
85
|
+
if File.directory?(fn)
|
86
|
+
child[:sort_on] = "0" + child[:file_name]
|
87
|
+
child[:empty] = true
|
88
|
+
add_row(child) # dummy record so expander appears
|
89
|
+
else
|
90
|
+
child[id(:sort_on)] = "1" + child[id(:file_name)]
|
91
|
+
end
|
92
|
+
return child
|
93
|
+
end
|
94
|
+
|
95
|
+
def set_show_expanders(expand)
|
96
|
+
self.show_expanders = expand
|
97
|
+
self.level_indentation = expand ? 0 : 12
|
98
|
+
end
|
99
|
+
|
100
|
+
def folder?(iter)
|
101
|
+
iter[id(:sort_on)][0,1] == "0"
|
102
|
+
end
|
103
|
+
|
104
|
+
def get_selected_path() (selection.selected ? selection.selected[id(:path)] : nil) end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
|
@@ -0,0 +1,82 @@
|
|
1
|
+
|
2
|
+
module VR
|
3
|
+
|
4
|
+
# The IterMethods module extends the GtkTreeIter class so it can work with
|
5
|
+
# visualruby's colum ID symbols as well as Gtk's column numbers.
|
6
|
+
#
|
7
|
+
|
8
|
+
module IterMethods
|
9
|
+
|
10
|
+
attr_accessor :column_keys
|
11
|
+
@column_keys = nil
|
12
|
+
|
13
|
+
# The [] method returns the value from the specified column in the iter:
|
14
|
+
#
|
15
|
+
# val = iter[:name]
|
16
|
+
#
|
17
|
+
# - col_id -- Either a visualruby column ID symbol, as above, or an integer.
|
18
|
+
#
|
19
|
+
|
20
|
+
def [](col_id)
|
21
|
+
get_value(id(col_id))
|
22
|
+
end
|
23
|
+
|
24
|
+
def []=(col_id,val)
|
25
|
+
i = id(col_id)
|
26
|
+
set_value(i, val)
|
27
|
+
end
|
28
|
+
|
29
|
+
# The id() method translates visualruby's colum ID symbols into integers that
|
30
|
+
# GtkTreeIter can use:
|
31
|
+
#
|
32
|
+
# iter = model.append
|
33
|
+
# iter[id(:name)] = "Henry"
|
34
|
+
#
|
35
|
+
# Normally, its best to use VR's "rows" instead. They will already use the column ID symbols.
|
36
|
+
#
|
37
|
+
def id(col_id) # :nodoc:
|
38
|
+
return (col_id.is_a? Fixnum) ? col_id : @column_keys.index(col_id)
|
39
|
+
end
|
40
|
+
|
41
|
+
# This will load the values of any object into the iter. It will look at all the
|
42
|
+
# instance variables, methods, and ActiveRecord fields and match them to
|
43
|
+
# columns in a VR::ListView or VR::TreeView. For example, if your object
|
44
|
+
# has an instance variable, @name, this will fill in a column with the symbol :name.
|
45
|
+
#
|
46
|
+
# class MyClass
|
47
|
+
# @name = "Henry"
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# @view = VR::ListView.new(:name => String)
|
51
|
+
# my = MyClass.new
|
52
|
+
# row = @view.add_row()
|
53
|
+
# row.load_object(my) # assigns "Henry" to first cell
|
54
|
+
#
|
55
|
+
#
|
56
|
+
# -obj--any ruby object or object subclassed from ActiveRecord::Base.
|
57
|
+
#
|
58
|
+
def load_object(obj)
|
59
|
+
class_sym = obj.class.name.to_sym
|
60
|
+
self[class_sym] = obj if @column_keys.include?(class_sym)
|
61
|
+
@column_keys.each do |k|
|
62
|
+
begin
|
63
|
+
self[k] = obj.send(k) if obj.respond_to?(k.to_s)
|
64
|
+
rescue
|
65
|
+
end
|
66
|
+
end
|
67
|
+
keys = @column_keys.inject([]) { |ar, e| ar << e.to_s }
|
68
|
+
matches = obj.attributes.keys & keys if obj.attributes.is_a? Hash
|
69
|
+
matches.each do |field|
|
70
|
+
begin
|
71
|
+
self[field.to_sym] = obj.attributes[field]
|
72
|
+
rescue
|
73
|
+
end
|
74
|
+
end
|
75
|
+
obj.instance_variables.each do |name|
|
76
|
+
self[name] = instance_variable_get(name) if @column_keys.include?(name)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module VR
|
2
|
+
|
3
|
+
|
4
|
+
class ListView < Gtk::TreeView
|
5
|
+
|
6
|
+
include ViewCommon
|
7
|
+
|
8
|
+
#The new() constructor takes a Hash that defines the columns as its only argument. The Hash defines
|
9
|
+
#symbols as the keys to give an ID to each column. The Hash also defines the type (class) of the column.
|
10
|
+
#A simple constructor looks like this:
|
11
|
+
#
|
12
|
+
# @view = VR::ListView.new(:name => String, :date => DateTime)
|
13
|
+
#
|
14
|
+
#You can create columns with any type of data including your own classes, and classes subclassed
|
15
|
+
#from ActiveRecordBase. The common types that are included by default are:
|
16
|
+
#
|
17
|
+
#- String - Displays and edits as a String.
|
18
|
+
#- Integer - Displays number, edits like a String.
|
19
|
+
#- FixNum - ditto
|
20
|
+
#- Integer - ditto
|
21
|
+
#- Float - ditto
|
22
|
+
#- DateTime - Displays in a default date format(editable), edits like a String
|
23
|
+
#- TrueClass - Displays as a GtkCheckButton, click checkbox to edit
|
24
|
+
#- GdkPixbuf - Just an Image, uneditable
|
25
|
+
#- VR::CalendarCol - Displays in a default date format(editable), calendar window to edit.
|
26
|
+
#- VR::SpinCol - Displays as a number with default number of digits, edits like a GtkSpinButton
|
27
|
+
#- VR::ComboCol - Displays String, edits like a GtkComboBoxEntry
|
28
|
+
#- VR::ProgressCol - Displays a GtkProgressBar, uneditable
|
29
|
+
#- VR::TextCol - For long strings. Displays first 20 characters in view, edits with simple text editor.
|
30
|
+
#
|
31
|
+
#You can also add your own user-defined column types. See: {Adding Your Own Objects to ListView}[link:/site/ListView%20Tutorial.html#objects].
|
32
|
+
#
|
33
|
+
|
34
|
+
def initialize(cls)
|
35
|
+
super()
|
36
|
+
hash = flatten_hash(cls)
|
37
|
+
vals = hash.values
|
38
|
+
self.model = Gtk::ListStore.new(*vals)
|
39
|
+
load_columns(cls)
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_active_record_rows(ar) # :nodoc:
|
43
|
+
ar.each do |obj|
|
44
|
+
row = add_row()
|
45
|
+
matches = obj.attributes.keys & @column_keys #intersection
|
46
|
+
matches.each { |field| row[field] = obj.attributes[field] }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def []( row ) # :nodoc:
|
51
|
+
model.get_iter(Gtk::TreePath.new("#{row}"))
|
52
|
+
end
|
53
|
+
|
54
|
+
def []( row, col ) # :nodoc:
|
55
|
+
model.get_iter(Gtk::TreePath.new("#{row}"))[col]
|
56
|
+
end
|
57
|
+
|
58
|
+
# This method will select a given row number. The row will be hilighted, and the
|
59
|
+
# GtkSelection object will point to that row. It uses the GtkTreeView#set_cursor
|
60
|
+
# method to move the cursor to the specified row.
|
61
|
+
#
|
62
|
+
#- row_number: Integer (FixNum)
|
63
|
+
#
|
64
|
+
|
65
|
+
def select_row(row_number = 0)
|
66
|
+
set_cursor(Gtk::TreePath.new(row_number), nil, false)
|
67
|
+
end
|
68
|
+
|
69
|
+
#This will add a row to the data model, and fill-in the values from a Hash.
|
70
|
+
#This example would add a row to the model and set the name and email fields:
|
71
|
+
#
|
72
|
+
# @view.add_row(:name => "Chester", :email => "chester@chester.com")
|
73
|
+
#
|
74
|
+
#
|
75
|
+
#- hash: A ruby Hash object with pairs of column ISs (symbols) and values.
|
76
|
+
|
77
|
+
def add_row(hash = {})
|
78
|
+
row = vr_row(model.append)
|
79
|
+
hash.each_pair { |key, val| row[key] = val }
|
80
|
+
return row
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
module VR
|
3
|
+
#
|
4
|
+
# TreeView is almost identical to VR::ListView. The only difference
|
5
|
+
# is how rows are added, and that they use a different model class.
|
6
|
+
# See VR::ListView for in-depth docs. Also, see Gtk::TreeView for more.
|
7
|
+
#
|
8
|
+
# Also, most of the useful methods for VR::TreeView are found in VR::ViewCommon.
|
9
|
+
# All the methods in VR::ViewCommon work on VR::TreeViews and VR::ListViews.
|
10
|
+
#
|
11
|
+
class TreeView < Gtk::TreeView
|
12
|
+
|
13
|
+
include ViewCommon
|
14
|
+
|
15
|
+
# See VR::ListView constructor. (exactly the same)
|
16
|
+
|
17
|
+
def initialize(cols)
|
18
|
+
super()
|
19
|
+
self.model = Gtk::TreeStore.new(*flatten_hash(cols).values)
|
20
|
+
load_columns(cols)
|
21
|
+
end
|
22
|
+
#
|
23
|
+
# Adds row to the model. This will return a "row" type iter that responds
|
24
|
+
# to column IDs (symbols). You need to provide a parent row (iter).
|
25
|
+
# See GtkTreeView#append for more.
|
26
|
+
#
|
27
|
+
# The iter is a GtkTreeIter object for the parent or nil for the root of the tree. The hash argument is a Hash of values to add:
|
28
|
+
#
|
29
|
+
# @view.add_row(iter, :name => "Chester", :email => "chester@chesterizer.com")
|
30
|
+
#
|
31
|
+
#
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
def add_row(parent, hash = {})
|
36
|
+
row = vr_row(model.append(parent))
|
37
|
+
hash.each_pair { |key, val| row[key] = val }
|
38
|
+
return row
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,370 @@
|
|
1
|
+
module VR
|
2
|
+
|
3
|
+
# This module holds all the methods that both VR::ListView
|
4
|
+
# and VR::TreeView use. All the methods listed here can be called from a
|
5
|
+
# VR::ListView or a VR::TreeView.
|
6
|
+
#
|
7
|
+
# ==The col_<propery>, ren_<property>, col_attr, and ren_attr methods
|
8
|
+
#
|
9
|
+
# All of these methods do the same thing: set the properties of your VR::ListView.
|
10
|
+
#
|
11
|
+
# The way to configure a VR::ListView or VR::TreeView is to set the properties
|
12
|
+
# of its columns (and renderers). For example,
|
13
|
+
# setting the "title" property of a column will set the title that appears at the top.
|
14
|
+
#
|
15
|
+
# The normal Gtk approach to setting properties of a GtkTreeViewColumn, (or renderer) is to set
|
16
|
+
# them individually:
|
17
|
+
#
|
18
|
+
# col = Gtk::TreeViewColumn.new()
|
19
|
+
# col.title = "My Title"
|
20
|
+
#
|
21
|
+
# This is slow, and tedious. However, you can completely configure any VR::ListView or
|
22
|
+
# VR::TreeView object with only a few lines of code using the above methods. They can set many properties on many columns
|
23
|
+
# at once.
|
24
|
+
#
|
25
|
+
# The first thing to understand is that there are several ways to set properties. In fact all
|
26
|
+
# of these lines of code do the exact same thing:
|
27
|
+
#
|
28
|
+
# column(:name).title = "Person's Name"
|
29
|
+
# col_title(:name => "Person's Name")
|
30
|
+
# ren_title(:name => "Person's Name")
|
31
|
+
# col_attr(:name, :title => "Person's Name")
|
32
|
+
# ren_attr(:name, :title => "Person's Name")
|
33
|
+
#
|
34
|
+
# All the above lines of code simply set the title of the :name column. So why
|
35
|
+
# is one method better than another? Answer: because you can set multiple
|
36
|
+
# properties on multiple columns with one line of code. For example, you can set all the titles
|
37
|
+
# with this line:
|
38
|
+
#
|
39
|
+
# col_titles(:name => "Name", :email => "Address", :phone => "Phone Number")
|
40
|
+
#
|
41
|
+
# The col_<property> method is very good at setting <b>multiple columns</b>.
|
42
|
+
#
|
43
|
+
# Likewise, the VR::ListView#col_attr method is good at setting the same property on multiple columns:
|
44
|
+
#
|
45
|
+
# col_attr(:name, :email, :phone, :width => 200, :weight => 700) #bold
|
46
|
+
#
|
47
|
+
# Either way, you can set everything with one line of code. Also, if you want to set
|
48
|
+
# a propery for all the columns, simply omit any column IDs:
|
49
|
+
#
|
50
|
+
# col_width(200)
|
51
|
+
# ren_background("yellow")
|
52
|
+
# col_attr(:font => "Sans")
|
53
|
+
# ren_attr(:visible => true)
|
54
|
+
#
|
55
|
+
# There are many, many possibilities of properties you can set using these methods.
|
56
|
+
# You need to know the name of the property that you want to set from consulting
|
57
|
+
# the docs for GtkTreeViewColumn and the docs for the column's renderer type (listed on the left of this webpage)
|
58
|
+
#
|
59
|
+
# Any of the properties of these classes can be set using the above methods.
|
60
|
+
#
|
61
|
+
# If you consult, GtkCellRendererText for example, you'll see that it has a "background" property.
|
62
|
+
# Therefore you can use ren_background() to set the color of the background of that column.
|
63
|
+
#
|
64
|
+
# Method names like "col_title" are just one possibility of methods you can use.
|
65
|
+
# You could call any of these as well:
|
66
|
+
#
|
67
|
+
# col_width
|
68
|
+
# col_xalign # (0.00 to 1.00, 1 = right justify)
|
69
|
+
# col_weight # (100 to 900)
|
70
|
+
# col_background
|
71
|
+
# col_foreground
|
72
|
+
# col_font
|
73
|
+
# col_markup
|
74
|
+
# col_size
|
75
|
+
# col_spacing
|
76
|
+
#
|
77
|
+
# You'll notice that some of the methods listed above don't look valid. For example,
|
78
|
+
# col_background doesn't seem to make sense because the GtkTreeViewColumn doesn't
|
79
|
+
# have a <b>background</b> property. The <b>background</b> property belongs to the
|
80
|
+
# renderer, GtkCellRendererText. But, the col_<attribute> method is programmed
|
81
|
+
# to try to set the property on the column first, and if the column object doesn't
|
82
|
+
# support the propery, it will look in the renderer. If the renderer doesn't support it,
|
83
|
+
# it DOES NOTHING.
|
84
|
+
#
|
85
|
+
# Likewise, the ren_<property> method will look first in the renderer for the property, then
|
86
|
+
# the column. The only difference between the ren_<property> and col_<propery> methods
|
87
|
+
# is that the ren_<property> looks in the renderer object first. These two methods
|
88
|
+
# are almost interchangable. In fact, I always just use the col_<propery> method
|
89
|
+
# because it looks better. The only time I have a problem is when the column and the renderer
|
90
|
+
# have the same property (i.e. "visible" and "xalign"). Then, I simply substitute the ren_<property> method.
|
91
|
+
#
|
92
|
+
# ==Summary
|
93
|
+
#
|
94
|
+
# - To set the <b>same attribute value</b> on multiple columns use col_attr() or ren_attr()
|
95
|
+
# - To set <b>different attribute values</b> on multiple columns, use col_<property> or ren_<property>
|
96
|
+
# - The ren_<property> and col_<property> methods are almost interchangable.
|
97
|
+
# - The ren_attr() and col_attr() methods are almost interchangable.
|
98
|
+
# - To set the properties of <b>all</b> the columns, omit any column iDs
|
99
|
+
# - Consult the documentation for GtkTreeViewColumn to learn about properties to set.
|
100
|
+
# - Consult the Gtk docs for the renderer by locating the type on the left of this webpage.
|
101
|
+
#
|
102
|
+
# Some examples are:
|
103
|
+
# ren_background(:name => "yellow", :email => black) #renderer for :name bg = yellow
|
104
|
+
# col_editable(false) #makes all columns un-editable
|
105
|
+
# col_width(:name => 300, email => 200)
|
106
|
+
# ren_xalign(:email => 1) # right justify email
|
107
|
+
# ren_attr(:name, :email, :font => "Courier")
|
108
|
+
# ren_attr(:font => "Sans") # all columns now Sans font
|
109
|
+
# col_attr(:name, :email, :visible => true)
|
110
|
+
#
|
111
|
+
|
112
|
+
module ViewCommon
|
113
|
+
|
114
|
+
attr_accessor :vr_renderer, :vr_column
|
115
|
+
|
116
|
+
def load_columns(cols) # :nodoc:
|
117
|
+
@vr_renderer = {}
|
118
|
+
@vr_column = {}
|
119
|
+
model_col = 0
|
120
|
+
cols.each_pair do | sym, type|
|
121
|
+
col = VR::TreeViewColumn.new(self, model_col, sym, type)
|
122
|
+
model_col = model_col + (type.class == Hash ? type.size : 1)
|
123
|
+
self.append_column(col)
|
124
|
+
end
|
125
|
+
turn_on_comboboxes()
|
126
|
+
@column_keys = flatten_hash(cols).keys
|
127
|
+
end
|
128
|
+
|
129
|
+
def method_missing(meth, *args) # :nodoc:
|
130
|
+
unless m = /^(ren_|col_)(.+)$/.match(meth.to_s)
|
131
|
+
super
|
132
|
+
return
|
133
|
+
end
|
134
|
+
if args.first.is_a? Hash
|
135
|
+
args.first.each_pair { |key, val| method(m[1] + "attr").call(key, m[2] => val) }
|
136
|
+
else
|
137
|
+
method(m[1] + "attr").call(m[2] => args.first)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Sets properties on renderers (and columns) See VR::ViewCommon#col_attr for more.
|
142
|
+
|
143
|
+
def ren_attr(*args)
|
144
|
+
cols = args.select { |arg| !arg.is_a? Hash }
|
145
|
+
return unless hash = args.detect { |arg| arg.is_a? Hash }
|
146
|
+
cols = @column_keys if cols.empty?
|
147
|
+
cols.each do |c|
|
148
|
+
hash.each_pair do | key, val |
|
149
|
+
if renderer(c).respond_to?(key.to_s + "=")
|
150
|
+
renderer(c).send(key.to_s + '=', val)
|
151
|
+
elsif column(c).respond_to?(key.to_s + "=")
|
152
|
+
column(c).send(key.to_s + '=', val)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Sets properties on many columns at once. It can be called with many columns and many attributes.
|
159
|
+
# Also, if you don't specify any columns, it will set the properties on all of them. There are
|
160
|
+
# many ways to call this method, here are a few:
|
161
|
+
#
|
162
|
+
# @view.col_attr(:name, :date, :background => "yellow", foreground => "black")
|
163
|
+
# @view.col_attr(:background => "yellow", foreground => "black") #sets all columns
|
164
|
+
# @view.col_attr(:name, :date, :editable => true) # both editable now
|
165
|
+
# @view.col_attr(:editable => false) # turns off editing to all columns
|
166
|
+
#
|
167
|
+
# Also, if the column VR::TreeViewColumn object doesn't support the property, it will try to
|
168
|
+
# set the property on the renderer instead. In the above example, the col_attr() method tries to
|
169
|
+
# set teh "<b>background</b>" property of a VR:TreeViewColumn. However, that object doesn't
|
170
|
+
# support the "background" property, but the renderer for the column, VR::CellRendererText does.
|
171
|
+
# So it sets the renderer's property instead. So, in this example this line of code would do exactly the same
|
172
|
+
# thing:
|
173
|
+
#
|
174
|
+
# @view.ren_attr(:name, :date, :background => "yellow", foreground => "black")
|
175
|
+
#
|
176
|
+
# In the vast majority of cases, VR::ViewCommon#col_attr and VR::ViewCommon#ren_attr are interchangable.
|
177
|
+
|
178
|
+
|
179
|
+
def col_attr(*args)
|
180
|
+
cols = args.select { |arg| !arg.is_a? Hash }
|
181
|
+
return unless hash = args.detect { |arg| arg.is_a? Hash }
|
182
|
+
cols = @column_keys if cols.empty?
|
183
|
+
cols.each do |c|
|
184
|
+
hash.each_pair do | key, val |
|
185
|
+
if column(c).respond_to?(key.to_s + "=")
|
186
|
+
column(c).send(key.to_s + '=', val)
|
187
|
+
elsif renderer(c).respond_to?(key.to_s + "=")
|
188
|
+
renderer(c).send(key.to_s + '=', val)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
# Returns an array of rows that are selected in the VR::TreeView or VR::ListView.
|
196
|
+
# If nothing is selected, it returns an empty array. If you've configured your
|
197
|
+
# listview to accept multiple selections, it will return all of them. In single
|
198
|
+
# selection mode, it will return an array with one row. These rows are
|
199
|
+
# able to respond to column IDs. They are the same types of rows as returned by
|
200
|
+
# VR::ViewCommon#vr_row.
|
201
|
+
|
202
|
+
def selected_rows()
|
203
|
+
rows = []
|
204
|
+
selection.each do |model, path, iter|
|
205
|
+
rows << vr_row(iter)
|
206
|
+
end
|
207
|
+
rows
|
208
|
+
end
|
209
|
+
|
210
|
+
def delete_selected()
|
211
|
+
refs = []
|
212
|
+
selection.each do |mod, path, iter|
|
213
|
+
refs << Gtk::TreeRowReference.new(mod, path)
|
214
|
+
end
|
215
|
+
refs.each do |ref|
|
216
|
+
model.remove(model.get_iter(ref.path))
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def turn_on_comboboxes() # :nodoc:
|
221
|
+
# detect if comboboxes are present:
|
222
|
+
found = false
|
223
|
+
self.each_renderer do |r|
|
224
|
+
if r.is_a? VR::CellRendererCombo
|
225
|
+
found = true
|
226
|
+
break
|
227
|
+
end
|
228
|
+
end
|
229
|
+
return unless found
|
230
|
+
self.signal_connect("cursor_changed") do |view|
|
231
|
+
next unless iter = view.selection.selected
|
232
|
+
view.each_renderer do |r|
|
233
|
+
r.set_model( iter[r.model_col] ) if r.is_a? VR::CellRendererCombo
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def flatten_hash(hash) # :nodoc:
|
239
|
+
h = {}
|
240
|
+
hash.each do | k, v |
|
241
|
+
if v.class == Hash
|
242
|
+
v.each_pair { |key, val| h[key] = val }
|
243
|
+
else
|
244
|
+
h[k] = v
|
245
|
+
end
|
246
|
+
end
|
247
|
+
return h
|
248
|
+
end
|
249
|
+
|
250
|
+
# Enumerates each row in the model and returns an instance of GtkTreeIter.
|
251
|
+
# However, the iters returned have been converted into a "row" using VR::ViewCommon#vr_row
|
252
|
+
# so they will respond to colum IDs (symbols). Like this:
|
253
|
+
#
|
254
|
+
# @view.each_row { |row| puts row[:name] } # works!
|
255
|
+
#
|
256
|
+
|
257
|
+
def each_row
|
258
|
+
self.model.each { |mod, pth, itr| yield vr_row(itr) }
|
259
|
+
end
|
260
|
+
|
261
|
+
# Converts a normal GtkTreeIter to use VR's column IDs. You can use it like this:
|
262
|
+
#
|
263
|
+
# row = @view.vr_row(iter) # iter is a Gtk::TreeIter
|
264
|
+
# row[:name] = "Chester" # works!
|
265
|
+
|
266
|
+
|
267
|
+
def vr_row(iter)
|
268
|
+
unless iter.respond_to?(:id)
|
269
|
+
iter.extend(VR::IterMethods)
|
270
|
+
iter.column_keys = @column_keys
|
271
|
+
end
|
272
|
+
return iter
|
273
|
+
end
|
274
|
+
|
275
|
+
def get_iter(path)
|
276
|
+
vr_row(model.get_iter(path))
|
277
|
+
end
|
278
|
+
|
279
|
+
|
280
|
+
# Returns a VR::TreeViewColumn object for the column. You can pass this method either
|
281
|
+
# a column ID (symbol) or the column number. Since, VR::TreeViewColumn is a subclass
|
282
|
+
# of Gtk::TreeViewColumn, you should consult Gtk::TreeViewColumn's documentation to
|
283
|
+
# see all the properties you can set on this object:
|
284
|
+
#
|
285
|
+
# @view.column(:name).title = "Person's Name"
|
286
|
+
# @view.column(:ok).visible = false
|
287
|
+
# @view.column(:name).class.name # => VR:TreeViewColumn
|
288
|
+
#
|
289
|
+
# Even though the above statements are valid, its usually easier to use the col_<property>
|
290
|
+
# methods instead. See VR::ViewCommon for more.
|
291
|
+
|
292
|
+
|
293
|
+
def column(id)
|
294
|
+
@vr_column[id]
|
295
|
+
end
|
296
|
+
|
297
|
+
def each_renderer
|
298
|
+
self.columns.each do |c|
|
299
|
+
c.cells.each do |r|
|
300
|
+
yield r
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
#Returns the renderer for a given column ID.
|
306
|
+
#
|
307
|
+
#In VR::ListView#new (and VR::TreeView#new) method, a data model (VR::ListStore or VR::TreeStore) is automatically contstructed.
|
308
|
+
#Then the class will automatically assign a renderer to show it on the screen. These renderers
|
309
|
+
#simply convert a piece of data to something visual on the screen. For example, a column in the model
|
310
|
+
#might contain a value "true," but the renderer converts it to a GtkCheckButton which shows a check-mark.
|
311
|
+
#The VR::ListView class will
|
312
|
+
#automatically assign renderers to each column based on its type:
|
313
|
+
#
|
314
|
+
#String, Fixnum, Integer, Float => VR::CellRendererText
|
315
|
+
#TrueClass => VR::CellRendererToggle
|
316
|
+
#GdkPixbuf => VR::CellRendererPixbuf
|
317
|
+
#DateTime => VR::CellRendererDate
|
318
|
+
#VR::CalendarCol, VR::TextCol => VR::CellRendererObject
|
319
|
+
#VR::SpinCol => VR::CellRendererSpin
|
320
|
+
#VR::ProgressCol => VR::CellRendererProgress
|
321
|
+
#VR::ComboCol => VR::CellRendererCombo
|
322
|
+
#
|
323
|
+
#The renderer() method will return one of these renderers:
|
324
|
+
#
|
325
|
+
# ren = @view.renderer(:ok)
|
326
|
+
# puts ren.class.name # VR::CellRendererToggle (:ok column is a TrueClass)
|
327
|
+
# puts @view.renderer(:name).class.name # => VR::CellRendererText
|
328
|
+
#
|
329
|
+
#All the types of renderers are subclasses of Gtk renderers. For example, VR::CellRendererText
|
330
|
+
#is a subclass of Gtk::CellRendererText. So, you can use these objects just as you would use a
|
331
|
+
#normal Gtk renderer:
|
332
|
+
#
|
333
|
+
# @view.renderer(:name).width = 100
|
334
|
+
#
|
335
|
+
#This is perfectly valid even though there are better ways of setting these properties in visualruby.
|
336
|
+
|
337
|
+
def renderer(sym)
|
338
|
+
@vr_renderer[sym]
|
339
|
+
end
|
340
|
+
|
341
|
+
# def renderer(id)
|
342
|
+
# each_renderer do |r|
|
343
|
+
# return r if r.model_col == id(id)
|
344
|
+
# end
|
345
|
+
# return nil
|
346
|
+
# end
|
347
|
+
|
348
|
+
# Returns the number of the given column ID. This is very useful when you're
|
349
|
+
# working with Gtk's methods because they require column numbers (not Column IDs)
|
350
|
+
# This method converts the column ID symbols from the VR::ListView#new constructor
|
351
|
+
# to Integers:
|
352
|
+
#
|
353
|
+
# @view = VR::ListView.new(:name => String, :date => VR::CalendarCol)
|
354
|
+
#
|
355
|
+
# Later in code...
|
356
|
+
#
|
357
|
+
# iter = get_iter(path)
|
358
|
+
# col_num = id(:date) # 1
|
359
|
+
# iter[col_num]
|
360
|
+
#
|
361
|
+
# You won't need to use this when adding rows with VR::ListView#add_row, and
|
362
|
+
# you also have the option of converting the whole iter to use column IDs (symbols)
|
363
|
+
# using VR::ViewCommon#vr_row.
|
364
|
+
|
365
|
+
def id(id)
|
366
|
+
return (id.is_a? Fixnum or id.is_a? Integer) ? id : @column_keys.index(id)
|
367
|
+
end
|
368
|
+
|
369
|
+
end
|
370
|
+
end
|