vr-corelib 0.0.36
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.
- checksums.yaml +7 -0
- data/Demo.rb +41 -0
- data/doc/images/add.png +0 -0
- data/doc/images/brick.png +0 -0
- data/doc/images/brick_link.png +0 -0
- data/doc/images/bug.png +0 -0
- data/doc/images/bullet_black.png +0 -0
- data/doc/images/bullet_toggle_minus.png +0 -0
- data/doc/images/bullet_toggle_plus.png +0 -0
- data/doc/images/date.png +0 -0
- data/doc/images/delete.png +0 -0
- data/doc/images/find.png +0 -0
- data/doc/images/macFFBgHack.png +0 -0
- data/doc/images/package.png +0 -0
- data/doc/images/page_green.png +0 -0
- data/doc/images/page_white_text.png +0 -0
- data/doc/images/page_white_width.png +0 -0
- data/doc/images/plugin.png +0 -0
- data/doc/images/ruby.png +0 -0
- data/doc/images/tag_blue.png +0 -0
- data/doc/images/tag_green.png +0 -0
- data/doc/images/transparent.png +0 -0
- data/doc/images/wrench.png +0 -0
- data/doc/images/wrench_orange.png +0 -0
- data/doc/images/zoom.png +0 -0
- data/glade/Demo.glade +52 -0
- data/img/image-x-generic.png +0 -0
- data/lib/Dialog.rb +157 -0
- data/lib/GladeGUI.rb +358 -0
- data/lib/IconHash.rb +22 -0
- data/lib/SimpleComboBoxEntry.rb +14 -0
- data/lib/Thread.rb +59 -0
- data/lib/Widget.rb +37 -0
- data/lib/treeview/FileTreeView.rb +91 -0
- data/lib/treeview/IterMethods.rb +82 -0
- data/lib/treeview/ListView.rb +90 -0
- data/lib/treeview/ModelRow.rb +31 -0
- data/lib/treeview/TreeIter.rb +33 -0
- data/lib/treeview/TreeView.rb +43 -0
- data/lib/treeview/ViewCommon.rb +351 -0
- data/lib/treeview/columns/CalendarCol.rb +88 -0
- data/lib/treeview/columns/CellRendererCombo.rb +66 -0
- data/lib/treeview/columns/CellRendererDate.rb +45 -0
- data/lib/treeview/columns/CellRendererObject.rb +57 -0
- data/lib/treeview/columns/CellRendererPhone.rb +45 -0
- data/lib/treeview/columns/CellRendererPixbuf.rb +16 -0
- data/lib/treeview/columns/CellRendererProgress.rb +17 -0
- data/lib/treeview/columns/CellRendererSpin.rb +37 -0
- data/lib/treeview/columns/CellRendererText.rb +38 -0
- data/lib/treeview/columns/CellRendererToggle.rb +47 -0
- data/lib/treeview/columns/ComboCol.rb +43 -0
- data/lib/treeview/columns/CurrencyCol.rb +23 -0
- data/lib/treeview/columns/DateCol.rb +20 -0
- data/lib/treeview/columns/ImageCol.rb +30 -0
- data/lib/treeview/columns/ProgressCol.rb +27 -0
- data/lib/treeview/columns/SpinCol.rb +11 -0
- data/lib/treeview/columns/TextCol.rb +64 -0
- data/lib/treeview/columns/TreeViewColumn.rb +108 -0
- data/lib/treeview/columns/glade/CalendarCol.glade +133 -0
- data/lib/treeview/columns/glade/ImageCol.glade +16 -0
- data/lib/treeview/columns/glade/TextCol.glade +77 -0
- data/main.rb +3 -0
- data/vr-corelib.rb +7 -0
- data/vrlib.rb +7 -0
- metadata +138 -0
data/lib/IconHash.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module VR
|
2
|
+
|
3
|
+
class IconHash < Hash # :nodoc:
|
4
|
+
|
5
|
+
def initialize(path,width=nil,height=nil)
|
6
|
+
Dir.glob(path + "/*.png").each do |f|
|
7
|
+
ext = File.basename(f, ".png")
|
8
|
+
if width.nil?
|
9
|
+
self[ext] = Gdk::Pixbuf.new(f)
|
10
|
+
else
|
11
|
+
self[ext] = Gdk::Pixbuf.new(f,width,height)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_icon(file_name)
|
17
|
+
ext = File.extname(file_name).gsub(".", "")
|
18
|
+
self.has_key?(ext) ? self[ext] : self["unknown"]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/lib/Thread.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
module VR
|
2
|
+
class Thread
|
3
|
+
def self.new(*args,&block)
|
4
|
+
::Thread.new(*args,&block)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.init
|
8
|
+
@@mutex = Mutex.new
|
9
|
+
@@pending_calls = []
|
10
|
+
@@running = true
|
11
|
+
GLib::Timeout.add(100) do
|
12
|
+
@@mutex.synchronize do
|
13
|
+
@@pending_calls.each do |closuer|
|
14
|
+
closuer.call
|
15
|
+
end
|
16
|
+
@@pending_calls = []
|
17
|
+
end
|
18
|
+
@@running
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.destroy
|
23
|
+
@@running = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.protect(&block)
|
27
|
+
if ::Thread.current == ::Thread.main
|
28
|
+
block.call
|
29
|
+
else
|
30
|
+
@@mutex.synchronize do
|
31
|
+
@@pending_calls << block
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.protect_call(obj,sym,*args)
|
37
|
+
if ::Thread.current == ::Thread.main
|
38
|
+
obj.__send__(sym,*args)
|
39
|
+
else
|
40
|
+
@@mutex.synchronize do
|
41
|
+
@@pending_calls << Proc.new do
|
42
|
+
obj.__send__(sym,*args)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.flush
|
49
|
+
if @@mutex.try_lock
|
50
|
+
@@pending_calls.each do |closuer|
|
51
|
+
closuer.call
|
52
|
+
end
|
53
|
+
|
54
|
+
@@pending_calls = []
|
55
|
+
@@mutex.unlock
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/Widget.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Gtk
|
2
|
+
|
3
|
+
class Widget
|
4
|
+
|
5
|
+
attr_accessor :dragged_widget
|
6
|
+
|
7
|
+
def drag_array(element = nil)
|
8
|
+
@dnd ||= []
|
9
|
+
@dnd.push(element) if not element.nil?
|
10
|
+
return @dnd
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def drag_to(target_widget = self, button = Gdk::Window::BUTTON1_MASK)
|
15
|
+
|
16
|
+
@target_widgets ||= []
|
17
|
+
@target_widgets.push(target_widget)
|
18
|
+
|
19
|
+
target = Gtk::Drag::TARGET_SAME_APP #useless
|
20
|
+
action = Gdk::DragContext::ACTION_MOVE #useless
|
21
|
+
dest = Gtk::Drag::DEST_DEFAULT_ALL #useless
|
22
|
+
|
23
|
+
Gtk::Drag.source_set(self, button, [ [self.object_id.to_s, target, 0] ], action)
|
24
|
+
ar = target_widget.drag_array([ self.object_id.to_s, target, 0])
|
25
|
+
Gtk::Drag.dest_set(target_widget, dest , ar , action)
|
26
|
+
if not @done
|
27
|
+
@done = true
|
28
|
+
self.signal_connect("drag_begin") do |widget, context|
|
29
|
+
@target_widgets.each { |widg| widg.dragged_widget = self }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
|
2
|
+
module VR
|
3
|
+
|
4
|
+
class FileTreeView < TreeView # :nodoc:
|
5
|
+
|
6
|
+
unless defined? FILETREEVIEW_GTYPE
|
7
|
+
FILETREEVIEW_GTYPE = self.name.split(":").collect {|x| x.empty? ? nil : x}.compact.join("_")
|
8
|
+
type_register(FILETREEVIEW_GTYPE)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(icon_path = nil, width = nil, height = nil) #, &block)
|
12
|
+
super(:file => {:pix => Gdk::Pixbuf, :file_name => String}, :path => String, :modified_date => VR::DateCol, :sort_on => String)
|
13
|
+
col_visible( :path => false, :modified_date => false, :sort_on => false)
|
14
|
+
self.headers_visible = false
|
15
|
+
model.set_sort_column_id(id(:sort_on))
|
16
|
+
@icons = File.directory?(icon_path.to_s) ? VR::IconHash.new(icon_path,width,height) : nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_open_folders()
|
20
|
+
expanded = []
|
21
|
+
map_expanded_rows {|view, path| expanded << model.get_iter(path)[id(:path)] }
|
22
|
+
return expanded
|
23
|
+
end
|
24
|
+
|
25
|
+
def open_folders(folder_paths)
|
26
|
+
collapse_all
|
27
|
+
model.each do |model, path, iter|
|
28
|
+
if folder_paths.include?(iter[id(:path)])
|
29
|
+
expand_row(path, false)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def refresh(root = Dir.pwd, glob = File.join(root, "**","*"))
|
35
|
+
@root_dir = root
|
36
|
+
expanded_folders = get_open_folders()
|
37
|
+
self.model.clear
|
38
|
+
add_file(root, nil)
|
39
|
+
Dir.glob(glob).each do |fn|
|
40
|
+
insert(fn)
|
41
|
+
end
|
42
|
+
open_folders(expanded_folders)
|
43
|
+
self.expand_row(self.model.iter_first.path, false)
|
44
|
+
end
|
45
|
+
|
46
|
+
def insert(fn) #fn is absolute path
|
47
|
+
fn.gsub!("\\", "/")
|
48
|
+
return if not File.exists?(fn) or get_iter_from_path(fn) or not fn.match(/^#{model.iter_first[id(:path)]}/)
|
49
|
+
if not parent_iter = get_iter_from_path(File.dirname(fn))
|
50
|
+
parent_iter = insert(File.dirname(fn))
|
51
|
+
end
|
52
|
+
return add_file(fn, parent_iter)
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_iter_from_path(fn)
|
56
|
+
model.each do | model, path, iter|
|
57
|
+
if iter[id(:path)] == fn
|
58
|
+
return iter
|
59
|
+
end
|
60
|
+
end
|
61
|
+
return false
|
62
|
+
end
|
63
|
+
|
64
|
+
def add_file(fn, parent)
|
65
|
+
fn.gsub!("\\", "/")
|
66
|
+
child = model.append(parent)
|
67
|
+
if @root_dir == fn && @icons.get_icon("x.project")
|
68
|
+
child[id(:pix)] = @icons.get_icon("x.project")
|
69
|
+
else
|
70
|
+
child[id(:pix)] = @icons.get_icon(File.directory?(fn) ? "x.folder" : fn)
|
71
|
+
end
|
72
|
+
child[id(:file_name)] = File.basename(fn)
|
73
|
+
child[id(:path)] = fn
|
74
|
+
child[id(:sort_on)] = (File.directory?(fn) ? "0" : "1") + child[id(:file_name)]
|
75
|
+
return child
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
def folder?(iter) iter[id(:sort_on)][0,1] == "0" end
|
80
|
+
def file_name(iter) iter ? iter[id(:path)] : nil end
|
81
|
+
def get_selected_file_name()
|
82
|
+
selection.selected ? selection.selected[id(:file_name)] : nil
|
83
|
+
end
|
84
|
+
def get_selected_path() (selection.selected ? selection.selected[id(:path)] : nil) end
|
85
|
+
def delete_selected() self.model.remove(selection.selected) if selection.selected end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
|
@@ -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,90 @@
|
|
1
|
+
module VR
|
2
|
+
|
3
|
+
|
4
|
+
class ListView < Gtk::TreeView
|
5
|
+
|
6
|
+
unless defined? LISTVIEW_GTYPE
|
7
|
+
LISTVIEW_GTYPE = self.name.split(":").collect {|x| x.empty? ? nil : x}.compact.join("_")
|
8
|
+
type_register(LISTVIEW_GTYPE)
|
9
|
+
end
|
10
|
+
|
11
|
+
include ViewCommon
|
12
|
+
|
13
|
+
#The new() constructor takes a Hash that defines the columns as its only argument. The Hash defines
|
14
|
+
#symbols as the keys to give an ID to each column. The Hash also defines the type (class) of the column.
|
15
|
+
#A simple constructor looks like this:
|
16
|
+
#
|
17
|
+
# @view = VR::ListView.new(:name => String, :date => DateTime)
|
18
|
+
#
|
19
|
+
#You can create columns with any type of data including your own classes, and classes subclassed
|
20
|
+
#from ActiveRecordBase. The common types that are included by default are:
|
21
|
+
#
|
22
|
+
#- String - Displays and edits as a String.
|
23
|
+
#- Integer - Displays number, edits like a String.
|
24
|
+
#- FixNum - ditto
|
25
|
+
#- Integer - ditto
|
26
|
+
#- Float - ditto
|
27
|
+
#- DateTime - Displays in a default date format(editable), edits like a String
|
28
|
+
#- TrueClass - Displays as a GtkCheckButton, click checkbox to edit
|
29
|
+
#- GdkPixbuf - Just an Image, uneditable
|
30
|
+
#- VR::CalendarCol - Displays in a default date format(editable), calendar window to edit.
|
31
|
+
#- VR::SpinCol - Displays as a number with default number of digits, edits like a GtkSpinButton
|
32
|
+
#- VR::ComboCol - Displays String, edits like a GtkComboBoxEntry
|
33
|
+
#- VR::ProgressCol - Displays a GtkProgressBar, uneditable
|
34
|
+
#- VR::TextCol - For long strings. Displays first 20 characters in view, edits with simple text editor.
|
35
|
+
#
|
36
|
+
#You can also add your own user-defined column types. See: {Adding Your Own Objects to ListView}[link:/site/ListView%20Tutorial.html#objects].
|
37
|
+
#
|
38
|
+
|
39
|
+
def initialize(cls)
|
40
|
+
super()
|
41
|
+
hash = flatten_hash(cls)
|
42
|
+
vals = hash.values
|
43
|
+
self.model = Gtk::ListStore.new(*vals)
|
44
|
+
load_columns(cls)
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_active_record_rows(ar) # :nodoc:
|
48
|
+
ar.each do |obj|
|
49
|
+
row = add_row()
|
50
|
+
matches = obj.attributes.keys & @column_keys #intersection
|
51
|
+
matches.each { |field| row[field] = obj.attributes[field] }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def []( row ) # :nodoc:
|
56
|
+
model.get_iter(Gtk::TreePath.new("#{row}"))
|
57
|
+
end
|
58
|
+
|
59
|
+
def []( row, col ) # :nodoc:
|
60
|
+
model.get_iter(Gtk::TreePath.new("#{row}"))[col]
|
61
|
+
end
|
62
|
+
|
63
|
+
#This method will select a given row number. The row will be hilighted, and the
|
64
|
+
#GtkSelection object will point to that row. It uses the GtkTreeView#set_cursor
|
65
|
+
#method to move the cursor to the specified row.
|
66
|
+
#
|
67
|
+
#- row_number: Integer (FixNum)
|
68
|
+
#
|
69
|
+
|
70
|
+
def select_row(row_number = 0)
|
71
|
+
set_cursor(Gtk::TreePath.new(row_number), nil, false)
|
72
|
+
end
|
73
|
+
|
74
|
+
#This will add a row to the data model, and fill-in the values from a Hash.
|
75
|
+
#This example would add a row to the model and set the name and email fields:
|
76
|
+
#
|
77
|
+
# @view.add_row(:name => "Chester", :email => "chester@chester.com")
|
78
|
+
#
|
79
|
+
#
|
80
|
+
#- hash: A ruby Hash object with pairs of column ISs (symbols) and values.
|
81
|
+
|
82
|
+
def add_row(hash = {})
|
83
|
+
row = vr_row(model.append)
|
84
|
+
hash.each_pair { |key, val| row[key] = val }
|
85
|
+
return row
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#module VR
|
2
|
+
#
|
3
|
+
# class VR::TreeIter < Gtk::TreeIter
|
4
|
+
#
|
5
|
+
# def initialize(iter, keys)
|
6
|
+
# self = iter
|
7
|
+
# @keys = keys
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# def [](id)
|
11
|
+
# super[id_to_int(id)]
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# def []=(id,val)
|
15
|
+
# i = id_to_int(id)
|
16
|
+
# super[i] = val
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# def id_to_int(id)
|
20
|
+
# return (id.is_a? Fixnum or id.is_a? Integer) ? id : @keys.index(id)
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# def load_object(obj)
|
24
|
+
# @keys.each do |k|
|
25
|
+
# super[id_to_int(k)] = obj.send(k) if obj.respond_to(k.to_s)
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
#end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#module VR
|
2
|
+
#
|
3
|
+
# class TreeIter < Gtk::TreeIter
|
4
|
+
#
|
5
|
+
# attr_accessor :keys
|
6
|
+
#
|
7
|
+
# def initialize(iter, keys)
|
8
|
+
# @keys = keys
|
9
|
+
# super()
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def [](id)
|
13
|
+
# super[id_to_int(id)]
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# def []=(id,val)
|
17
|
+
# i = id_to_int(id)
|
18
|
+
# super[i] = val
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# def id_to_int(id)
|
22
|
+
# return (id.is_a? Fixnum or id.is_a? Integer) ? id : @keys.index(id)
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# def load_object(obj)
|
26
|
+
# @keys.each do |k|
|
27
|
+
# super[id_to_int(k)] = obj.send(k) if obj.respond_to(k.to_s)
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
#end
|