visualruby 1.0.19 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
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