visualruby 1.0.19 → 3.0.2

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.
Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/Splash.rb +40 -0
  3. data/bin/editor/VR_Document.rb +81 -74
  4. data/bin/editor/VR_TabSearch.rb +5 -7
  5. data/bin/editor/VR_Tabs.rb +57 -36
  6. data/bin/editor/VR_TextShell.rb +12 -34
  7. data/bin/editor/VR_TextViewCommon.rb +9 -28
  8. data/bin/main/NewProjectGUI.rb +14 -13
  9. data/bin/main/OpenProject.rb +69 -0
  10. data/bin/main/ProjectChooserView.rb +3 -2
  11. data/bin/main/ProjectTree.rb +25 -0
  12. data/bin/main/RubygemsAPI.rb +15 -11
  13. data/bin/main/VR_ENV.rb +38 -60
  14. data/bin/main/VR_ENV_GLOBAL.rb +45 -44
  15. data/bin/main/VR_File_Tree.rb +29 -21
  16. data/bin/main/VR_Local_Gem_Tree.rb +4 -19
  17. data/bin/main/VR_Main.rb +128 -144
  18. data/bin/main/VR_Remote_Gem_Tree.rb +6 -19
  19. data/bin/main/glade/NewProjectGUI.glade +94 -98
  20. data/bin/main/glade/OpenProject.glade +259 -0
  21. data/bin/main/glade/RubygemsAPI.glade +98 -62
  22. data/bin/main/glade/VR_ENV.glade +46 -55
  23. data/bin/main/glade/VR_ENV_GLOBAL.glade +251 -180
  24. data/bin/main/glade/VR_File_Tree.glade +25 -16
  25. data/bin/main/glade/VR_Local_Gem_Tree.glade +16 -8
  26. data/bin/main/glade/VR_Main.glade +410 -449
  27. data/bin/main/glade/VR_Remote_Gem_Tree.glade +33 -31
  28. data/bin/tools/VR_Tools.rb +60 -46
  29. data/{visualruby_examples → examples}/active_record/active_record.rb +16 -10
  30. data/{visualruby_examples → examples}/active_record/bin/ChoosePerson.rb +7 -0
  31. data/examples/active_record/bin/Person.rb +21 -0
  32. data/examples/active_record/bin/glade/ChoosePerson.glade +89 -0
  33. data/examples/active_record/bin/glade/Person.glade +197 -0
  34. data/{visualruby_examples → examples}/active_record/db/development.sqlite3 +0 -0
  35. data/{visualruby_examples → examples}/active_record2/bin/CompanyGUI.rb +7 -7
  36. data/{visualruby_examples → examples}/active_record2/bin/Employee.rb +0 -0
  37. data/{visualruby_examples → examples}/active_record2/bin/Employer.rb +0 -0
  38. data/{visualruby_examples → examples}/active_record2/bin/Paycheck.rb +0 -0
  39. data/examples/active_record2/bin/glade/CompanyGUI.glade +149 -0
  40. data/examples/active_record2/bin/glade/Employee.glade +126 -0
  41. data/{visualruby_examples → examples}/active_record2/bin/glade/Employer.glade +0 -0
  42. data/{visualruby_examples → examples}/active_record2/bin/glade/Paycheck.glade +0 -0
  43. data/{visualruby_examples → examples}/active_record2/db/development.sqlite3 +0 -0
  44. data/{visualruby_examples → examples}/active_record2/main.rb +15 -9
  45. data/examples/alert_box/bin/AlertBoxDemo.rb +80 -0
  46. data/examples/alert_box/bin/glade/AlertBoxDemo.glade +234 -0
  47. data/examples/alert_box/main.rb +12 -0
  48. data/{visualruby_examples → examples}/all_widgets/bin/AllWidgets.rb +18 -10
  49. data/{visualruby_examples → examples}/all_widgets/bin/glade/AllWidgets.glade +52 -16
  50. data/{visualruby_examples → examples}/all_widgets/bin/splash.png +0 -0
  51. data/examples/all_widgets/main.rb +12 -0
  52. data/{visualruby_examples → examples}/calculator/bin/Calculator.rb +23 -22
  53. data/{visualruby_examples → examples}/calculator/bin/glade/Calculator.glade +81 -51
  54. data/examples/calculator/main.rb +13 -0
  55. data/examples/child_window/bin/ChildWindowDemo.rb +52 -0
  56. data/examples/child_window/bin/ModalWindow.rb +9 -0
  57. data/examples/child_window/bin/ModelessWindow.rb +9 -0
  58. data/examples/child_window/bin/MyChildClass.rb +21 -0
  59. data/examples/child_window/bin/glade/ChildWindowDemo.glade +87 -0
  60. data/examples/child_window/bin/glade/ModalWindow.glade +61 -0
  61. data/examples/child_window/bin/glade/ModelessWindow.glade +61 -0
  62. data/{visualruby_examples → examples}/child_window/bin/glade/MyChildClass.glade +14 -12
  63. data/examples/child_window/main.rb +12 -0
  64. data/{visualruby_examples → examples}/drag_drop/bin/DragDropDemo.rb +9 -10
  65. data/examples/drag_drop/bin/glade/DragDropDemo.glade +161 -0
  66. data/{visualruby_examples → examples}/drag_drop/img/folder.png +0 -0
  67. data/{visualruby_examples → examples}/drag_drop/img/glade.png +0 -0
  68. data/{visualruby_examples → examples}/drag_drop/img/gtk-edit.png +0 -0
  69. data/{visualruby_examples → examples}/drag_drop/img/obj.png +0 -0
  70. data/{visualruby_examples → examples}/drag_drop/img/png.png +0 -0
  71. data/{visualruby_examples → examples}/drag_drop/img/rb.png +0 -0
  72. data/{visualruby_examples → examples}/drag_drop/img/ruby.png +0 -0
  73. data/{visualruby_examples → examples}/drag_drop/img/unknown.png +0 -0
  74. data/examples/drag_drop/main.rb +11 -0
  75. data/examples/filetreeview/bin/ProjectTree.rb +32 -0
  76. data/examples/filetreeview/bin/ProjectTreeGUI.rb +28 -0
  77. data/examples/filetreeview/bin/glade/ProjectTreeGUI.glade +156 -0
  78. data/examples/filetreeview/main.rb +13 -0
  79. data/{visualruby_examples → examples}/listview/bin/SongListView.rb +24 -20
  80. data/{visualruby_examples → examples}/listview/bin/SongListViewGUI.rb +12 -11
  81. data/{visualruby_examples → examples}/listview/bin/audio-x-generic.png +0 -0
  82. data/examples/listview/bin/glade/SongListViewGUI.glade +195 -0
  83. data/examples/listview/main.rb +10 -0
  84. data/examples/listview_objects/bin/DataObject.rb +53 -0
  85. data/{visualruby_examples → examples}/listview_objects/bin/ListViewObjects.rb +7 -4
  86. data/examples/listview_objects/bin/ListViewObjectsGUI.rb +26 -0
  87. data/examples/listview_objects/bin/glade/DataObject.glade +196 -0
  88. data/examples/listview_objects/bin/glade/ListViewObjectsGUI.glade +87 -0
  89. data/examples/listview_objects/main.rb +12 -0
  90. data/examples/settings_file/bin/MainApp.rb +38 -0
  91. data/examples/settings_file/bin/SavableSettings.rb +39 -0
  92. data/examples/settings_file/bin/glade/MainApp.glade +87 -0
  93. data/examples/settings_file/bin/glade/SavableSettings.glade +162 -0
  94. data/examples/settings_file/main.rb +14 -0
  95. data/examples/settings_file/settings.yaml +15 -0
  96. data/examples/simple_ruby_gui/bin/DataObjectGUI.rb +21 -0
  97. data/examples/simple_ruby_gui/bin/glade/DataObjectGUI.glade +195 -0
  98. data/examples/simple_ruby_gui/main.rb +16 -0
  99. data/{visualruby_examples → examples}/treeview/bin/MyClass.rb +1 -5
  100. data/examples/treeview/bin/glade/MyClass.glade +24 -0
  101. data/examples/treeview/main.rb +13 -0
  102. data/skeleton/document/New.glade +3 -4
  103. data/skeleton/document/NewWindow.rb +1 -1
  104. data/skeleton/project/bin/MyClass.rb +2 -2
  105. data/skeleton/project/bin/glade/MyClass.glade +12 -26
  106. data/skeleton/project/main.rb +4 -8
  107. data/vr +41 -37
  108. data/vrlib/lib/Alert.rb +67 -0
  109. data/vrlib/lib/DragDrop.rb +90 -0
  110. data/vrlib/lib/GladeGUI.rb +433 -0
  111. data/vrlib/lib/IconHash.rb +18 -0
  112. data/vrlib/lib/SavableClass.rb +56 -0
  113. data/vrlib/lib/SimpleComboBoxEntry.rb +8 -0
  114. data/vrlib/lib/glade/Alert.glade +119 -0
  115. data/vrlib/lib/treeview/FileTreeView.rb +113 -0
  116. data/vrlib/lib/treeview/IterMethods.rb +82 -0
  117. data/vrlib/lib/treeview/ListView.rb +85 -0
  118. data/vrlib/lib/treeview/TreeView.rb +43 -0
  119. data/vrlib/lib/treeview/ViewCommon.rb +370 -0
  120. data/vrlib/lib/treeview/columns/CalendarCol.rb +89 -0
  121. data/vrlib/lib/treeview/columns/CellRendererCombo.rb +66 -0
  122. data/vrlib/lib/treeview/columns/CellRendererDate.rb +45 -0
  123. data/vrlib/lib/treeview/columns/CellRendererObject.rb +57 -0
  124. data/vrlib/lib/treeview/columns/CellRendererPhone.rb +45 -0
  125. data/vrlib/lib/treeview/columns/CellRendererPixbuf.rb +16 -0
  126. data/vrlib/lib/treeview/columns/CellRendererProgress.rb +17 -0
  127. data/vrlib/lib/treeview/columns/CellRendererSpin.rb +37 -0
  128. data/vrlib/lib/treeview/columns/CellRendererText.rb +38 -0
  129. data/vrlib/lib/treeview/columns/CellRendererToggle.rb +47 -0
  130. data/vrlib/lib/treeview/columns/ComboCol.rb +43 -0
  131. data/vrlib/lib/treeview/columns/CurrencyCol.rb +23 -0
  132. data/vrlib/lib/treeview/columns/DateCol.rb +20 -0
  133. data/vrlib/lib/treeview/columns/ImageCol.rb +27 -0
  134. data/vrlib/lib/treeview/columns/ProgressCol.rb +27 -0
  135. data/vrlib/lib/treeview/columns/SpinCol.rb +11 -0
  136. data/vrlib/lib/treeview/columns/TextCol.rb +65 -0
  137. data/vrlib/lib/treeview/columns/TreeViewColumn.rb +93 -0
  138. data/{bin/main/glade/ProjectChooserGUI.glade → vrlib/lib/treeview/columns/glade/CalendarCol.glade} +71 -63
  139. data/{bin/main/glade/Splash.glade → vrlib/lib/treeview/columns/glade/ImageCol.glade} +5 -6
  140. data/vrlib/lib/treeview/columns/glade/TextCol.glade +82 -0
  141. data/vrlib/rdoc_replace.yaml +77 -0
  142. data/vrlib/vrlib.rb +7 -0
  143. metadata +163 -136
  144. data/bin/editor/glade/VR_Document.glade +0 -160
  145. data/bin/main/ProjectChooserGUI.rb +0 -41
  146. data/bin/main/Splash.rb +0 -22
  147. data/visualruby_examples/active_record/.vr_settings.yaml +0 -47
  148. data/visualruby_examples/active_record/bin/Person.rb +0 -13
  149. data/visualruby_examples/active_record/bin/glade/ChoosePerson.glade +0 -61
  150. data/visualruby_examples/active_record/bin/glade/Person.glade +0 -148
  151. data/visualruby_examples/active_record2/.vr_settings.yaml +0 -16
  152. data/visualruby_examples/active_record2/bin/glade/CompanyGUI.glade +0 -167
  153. data/visualruby_examples/active_record2/bin/glade/Employee.glade +0 -123
  154. data/visualruby_examples/all_widgets/.vr_settings.yaml +0 -13
  155. data/visualruby_examples/all_widgets/main.rb +0 -14
  156. data/visualruby_examples/calculator/.vr_settings.yaml +0 -11
  157. data/visualruby_examples/calculator/main.rb +0 -13
  158. data/visualruby_examples/child_window/.vr_settings.yaml +0 -16
  159. data/visualruby_examples/child_window/bin/ChildWindowDemo.rb +0 -39
  160. data/visualruby_examples/child_window/bin/MyChildClass.rb +0 -40
  161. data/visualruby_examples/child_window/bin/glade/ChildWindowDemo.glade +0 -101
  162. data/visualruby_examples/child_window/main.rb +0 -13
  163. data/visualruby_examples/drag_drop/.vr_settings.yaml +0 -12
  164. data/visualruby_examples/drag_drop/bin/glade/DragDropDemo.glade +0 -143
  165. data/visualruby_examples/drag_drop/main.rb +0 -14
  166. data/visualruby_examples/listview/.vr_settings.yaml +0 -12
  167. data/visualruby_examples/listview/bin/glade/SongListViewGUI.glade +0 -220
  168. data/visualruby_examples/listview/main.rb +0 -19
  169. data/visualruby_examples/listview_objects/.vr_settings.yaml +0 -16
  170. data/visualruby_examples/listview_objects/bin/DataObject.rb +0 -32
  171. data/visualruby_examples/listview_objects/bin/DataObjectGUI.rb +0 -41
  172. data/visualruby_examples/listview_objects/bin/ListViewObjectsGUI.rb +0 -18
  173. data/visualruby_examples/listview_objects/bin/glade/DataObject.glade +0 -198
  174. data/visualruby_examples/listview_objects/bin/glade/ListViewObjectsGUI.glade +0 -102
  175. data/visualruby_examples/listview_objects/main.rb +0 -13
  176. data/visualruby_examples/simple_ruby_gui/.vr_settings.yaml +0 -16
  177. data/visualruby_examples/simple_ruby_gui/bin/DataObjectGUI.rb +0 -20
  178. data/visualruby_examples/simple_ruby_gui/bin/glade/DataObjectGUI.glade +0 -163
  179. data/visualruby_examples/simple_ruby_gui/main.rb +0 -16
  180. data/visualruby_examples/treeview/.vr_settings.yaml +0 -12
  181. data/visualruby_examples/treeview/bin/glade/MyClass.glade +0 -48
  182. 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