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