visualruby 3.6.13 → 3.6.14
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 +4 -4
- data/.vr_settings.yaml +7 -29
- data/examples/01_phantom/.vr_settings.yaml +3 -4
- data/examples/01_phantom/README.txt +50 -0
- data/examples/01_phantom/phantom.rb +1 -1
- data/examples/01_phantom/src/glade/Phantom.glade +0 -1
- data/examples/02_hello/.vr_settings.yaml +3 -4
- data/examples/02_hello/README.txt +50 -0
- data/examples/03_builder_variable/README.txt +36 -0
- data/examples/04_before_show/README.txt +27 -0
- data/examples/05_menus/README.txt +38 -0
- data/examples/06_alert_box/README.txt +71 -0
- data/examples/06_alert_box/alertdemo.rb +3 -5
- data/examples/07_event_handlers/README.txt +81 -0
- data/examples/08_interrupt_exit/README.txt +40 -0
- data/examples/09_get_glade_variables/README.txt +72 -0
- data/examples/10_all_widgets/README.txt +35 -0
- data/examples/20_calculator/README.txt +17 -0
- data/examples/36_dialog_box/.vr_settings.yaml +17 -0
- data/examples/36_dialog_box/README.txt +30 -0
- data/examples/49_settings_file/.vr_settings.yaml +2 -2
- data/examples/49_settings_file/README.txt +33 -0
- data/examples/70_better_views/README.txt +64 -0
- data/examples/71_prettify_view/README.txt +105 -0
- data/examples/75_treeview/.vr_settings.yaml +2 -2
- data/examples/75_treeview/README.txt +25 -0
- data/examples/92_standalone_exe/README.txt +43 -0
- data/img/ui.png +0 -0
- data/lib/GladeGUI.rb +1 -1
- data/src/editor/VR_Document.rb +2 -0
- data/src/editor/VR_Tabs.rb +2 -1
- data/src/main/VR_ENV_GLOBAL.rb +1 -1
- data/src/main/VR_Main.rb +1 -1
- data/src/version.rb +1 -1
- metadata +24 -6
- data/examples/dialog_box/.vr_settings.yaml +0 -16
- /data/examples/{dialog_box → 36_dialog_box}/dialog_box.rb +0 -0
- /data/examples/{dialog_box → 36_dialog_box}/src/ChooserDialog.rb +0 -0
- /data/examples/{dialog_box → 36_dialog_box}/src/glade/ChooserDialog.glade +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5d5411c3ce7feb323c2c280124c42bc0d8ba62aae637d3c33d96c454f77faa9b
|
|
4
|
+
data.tar.gz: f4b39a1d930ce297bd0e0b1c4733eb5b0a7573f51db92d6b8fc11dfa34c82a3d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 10eea170af1150d7ae64cde819c96620276fa21c0997a7a7a0478597e0c8241e8a5ef508826a0421480a142feb134194b6bf70522e7039a13eecf719b7afc442
|
|
7
|
+
data.tar.gz: 370a04d6b8a79c658a5a6098b3b129f864862ba238cb9c4a39556aec7095e7809b9d6a348e2601904bc4a1c612a36d25007c721239348812b39f66482110fab1
|
data/.vr_settings.yaml
CHANGED
|
@@ -3,43 +3,21 @@ vr_yaml_file: "/home/eric/vrp/vr3/.vr_settings.yaml"
|
|
|
3
3
|
width: 1854
|
|
4
4
|
height: 1003
|
|
5
5
|
panel_pos: 353
|
|
6
|
-
notebook_panel_position:
|
|
6
|
+
notebook_panel_position: 734
|
|
7
7
|
run_command_line: vr
|
|
8
8
|
open_files:
|
|
9
9
|
- "/home/eric/vrp/vr3/lib/GladeGUI.rb"
|
|
10
10
|
- "/home/eric/vrp/vr3/src/main/VR_Main.rb"
|
|
11
|
-
- "/home/eric/vrp/vr3/vr"
|
|
12
|
-
- "/home/eric/vrp/vr3/src/editor/VR_Document.rb"
|
|
13
|
-
- "/home/eric/vrp/vr3/src/main/VR_Tools.rb"
|
|
14
|
-
- "/home/eric/vrp/vr3/src/main/OpenProject.rb"
|
|
15
|
-
- "/home/eric/vrp/vr3/src/version.rb"
|
|
16
|
-
- "/home/eric/vrp/vr3/lib/Alert.rb"
|
|
17
|
-
- "/home/eric/vrp/vr3/lib/vrlib.rb"
|
|
18
|
-
- "/home/eric/vrp/vr3/lib/AlertDialog.rb"
|
|
19
|
-
- "/home/eric/vrp/vr3/src/main/NewProjectGUI.rb"
|
|
20
11
|
- "/home/eric/vrp/vr3/src/editor/VR_Tabs.rb"
|
|
21
|
-
- "/home/eric/vrp/vr3/
|
|
22
|
-
- "/home/eric/vrp/vr3/examples/
|
|
23
|
-
- "/home/eric/vrp/vr3/
|
|
24
|
-
- "/home/eric/vrp/vr3/
|
|
25
|
-
- "/home/eric/vrp/vr3/examples/78_listview/listview.rb"
|
|
26
|
-
- "/home/eric/vrp/vr3/examples/78_listview_objects/listviewobjects.rb"
|
|
27
|
-
- "/home/eric/vrp/vr3/examples/95_active_record/active_record.rb"
|
|
28
|
-
- "/home/eric/vrp/vr3/examples/97_active_record2/main.rb"
|
|
12
|
+
- "/home/eric/vrp/vr3/src/main/VR_File_Tree.rb"
|
|
13
|
+
- "/home/eric/vrp/vr3/examples/78_listview/src/SongListViewGUI.rb"
|
|
14
|
+
- "/home/eric/vrp/vr3/lib/treeview/FileTreeView.rb"
|
|
15
|
+
- "/home/eric/vrp/vr3/vr"
|
|
29
16
|
- "/home/eric/vrp/vr3/vr.gemspec"
|
|
30
17
|
open_folders:
|
|
31
18
|
- "/home/eric/vrp/vr3"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- "/home/eric/vrp/vr3/site"
|
|
35
|
-
- "/home/eric/vrp/vr3/skeleton"
|
|
36
|
-
- "/home/eric/vrp/vr3/skeleton/document"
|
|
37
|
-
- "/home/eric/vrp/vr3/src"
|
|
38
|
-
- "/home/eric/vrp/vr3/src/editor"
|
|
39
|
-
- "/home/eric/vrp/vr3/src/main"
|
|
40
|
-
- "/home/eric/vrp/vr3/src/main/glade"
|
|
41
|
-
current_file: "/home/eric/vrp/vr3/src/version.rb"
|
|
42
|
-
current_line: 1
|
|
19
|
+
current_file: "/home/eric/vrp/vr3/src/editor/VR_Tabs.rb"
|
|
20
|
+
current_line: 24
|
|
43
21
|
rdoc_command_line: rdoc -x README
|
|
44
22
|
builder: !ruby/object:Gtk::Builder {}
|
|
45
23
|
top_level_window: false
|
|
@@ -3,10 +3,9 @@ vr_yaml_file: "/home/eric/vrp/vr3/examples/01_phantom/.vr_settings.yaml"
|
|
|
3
3
|
width: 1854
|
|
4
4
|
height: 1003
|
|
5
5
|
panel_pos: 360
|
|
6
|
-
notebook_panel_position:
|
|
6
|
+
notebook_panel_position: 630
|
|
7
7
|
run_command_line: phantom.rb
|
|
8
8
|
open_files:
|
|
9
|
-
- "/home/eric/vrp/vr3/src/main/NewProjectGUI.rb"
|
|
10
9
|
- "/home/eric/vrp/vr3/examples/01_phantom/README.txt"
|
|
11
10
|
- "/home/eric/vrp/vr3/examples/01_phantom/phantom.rb"
|
|
12
11
|
- "/home/eric/vrp/vr3/examples/01_phantom/src/Phantom.rb"
|
|
@@ -14,8 +13,8 @@ open_folders:
|
|
|
14
13
|
- "/home/eric/vrp/vr3/examples/01_phantom"
|
|
15
14
|
- "/home/eric/vrp/vr3/examples/01_phantom/src"
|
|
16
15
|
- "/home/eric/vrp/vr3/examples/01_phantom/src/glade"
|
|
17
|
-
current_file: "/home/eric/vrp/vr3/examples/01_phantom/
|
|
18
|
-
current_line:
|
|
16
|
+
current_file: "/home/eric/vrp/vr3/examples/01_phantom/phantom.rb"
|
|
17
|
+
current_line: 3
|
|
19
18
|
rdoc_command_line: rdoc -x README
|
|
20
19
|
builder: !ruby/object:Gtk::Builder {}
|
|
21
20
|
top_level_window: false
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
|
|
2
|
+
To start, click the "Run" button, and the program will appear.
|
|
3
|
+
|
|
4
|
+
Clicking the run button, simply runs this command:
|
|
5
|
+
|
|
6
|
+
ruby phantom.rb
|
|
7
|
+
|
|
8
|
+
You can see and edit the "Run" command in menu: Tools > Project Settings
|
|
9
|
+
|
|
10
|
+
Try right-clicking on the files on the left to see options.
|
|
11
|
+
|
|
12
|
+
Next, try editing a glade file by clicking on the glade folder,
|
|
13
|
+
and double clicking on Phantom.glade. If this does't work,
|
|
14
|
+
you need to install the Glade Interface Designer. Glade needs to be installed
|
|
15
|
+
such that it runs from the command prompt using the command, "glade"
|
|
16
|
+
|
|
17
|
+
These lines of code are what makes the program work:
|
|
18
|
+
|
|
19
|
+
require 'vrlib'
|
|
20
|
+
|
|
21
|
+
and
|
|
22
|
+
|
|
23
|
+
include GladeGUI
|
|
24
|
+
|
|
25
|
+
The GladeGUI module is in vrlib.rb, and it contains the vital methods
|
|
26
|
+
to transform a class into a GUI program.
|
|
27
|
+
|
|
28
|
+
One important method in GladeGUI is the #show_glade() method. It reads the
|
|
29
|
+
glade file, and shows it on the screen.
|
|
30
|
+
|
|
31
|
+
So this line of code:
|
|
32
|
+
|
|
33
|
+
Phantom.new.show_glade()
|
|
34
|
+
|
|
35
|
+
Creates an instance of the Phantom class, then loads Phantom.glade, then
|
|
36
|
+
finds a window with ID "window1" in the glade file, and show it onscreen.
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
Summary:
|
|
40
|
+
1) Always require "vrlib" in your programs.
|
|
41
|
+
2) Then, include GladeGUI to any class that has a GUI.
|
|
42
|
+
3) Visualruby will automatically find the glade files in the glade folder.
|
|
43
|
+
4) It will load the glade file, find ID "window1", and show it.
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
Click the "Run" button to see this in action. Then click the "Open Project" button
|
|
47
|
+
to move on to example 2 ....
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
<object class="GtkWindow" id="window1">
|
|
6
6
|
<property name="width-request">400</property>
|
|
7
7
|
<property name="can-focus">False</property>
|
|
8
|
-
<property name="window-position">center</property>
|
|
9
8
|
<child>
|
|
10
9
|
<object class="GtkBox" id="box1">
|
|
11
10
|
<property name="visible">True</property>
|
|
@@ -8,15 +8,14 @@ run_command_line: hello.rb
|
|
|
8
8
|
open_files:
|
|
9
9
|
- "/home/eric/vrp/vr3/examples/02_hello/README.txt"
|
|
10
10
|
- "/home/eric/vrp/vr3/examples/02_hello/hello.rb"
|
|
11
|
-
- "/home/eric/vrp/vr3/examples/02_hello/src/HelloGUI.rb"
|
|
12
11
|
open_folders:
|
|
13
12
|
- "/home/eric/vrp/vr3/examples/02_hello"
|
|
14
13
|
- "/home/eric/vrp/vr3/examples/02_hello/src"
|
|
15
14
|
- "/home/eric/vrp/vr3/examples/02_hello/src/glade"
|
|
16
|
-
current_file: "/home/eric/vrp/vr3/examples/02_hello/
|
|
17
|
-
current_line:
|
|
18
|
-
builder: !ruby/object:Gtk::Builder {}
|
|
15
|
+
current_file: "/home/eric/vrp/vr3/examples/02_hello/hello.rb"
|
|
16
|
+
current_line: 9
|
|
19
17
|
rdoc_command_line: rdoc -x README
|
|
18
|
+
builder: !ruby/object:Gtk::Builder {}
|
|
20
19
|
top_level_window: false
|
|
21
20
|
browser: firefox
|
|
22
21
|
backup_path: "/home/eric"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
|
|
2
|
+
This "hello world" script is simple, but there are some important lessons
|
|
3
|
+
to be learned from it.
|
|
4
|
+
|
|
5
|
+
As before, the HelloGUI.rb class has a corresponding glade file, HelloGUI.glade, to add a GUI.
|
|
6
|
+
It maps like this:
|
|
7
|
+
|
|
8
|
+
HelloGUI.rb ==> glade/HelloGUI.glade
|
|
9
|
+
|
|
10
|
+
If you doubleclick on HelloGUI.glade, the file will open, and you can see
|
|
11
|
+
the button with ID: "ui_hello_btn"
|
|
12
|
+
|
|
13
|
+
This ID follows a naming convention:
|
|
14
|
+
|
|
15
|
+
ui = user interface
|
|
16
|
+
hello = identifier
|
|
17
|
+
btn = a button
|
|
18
|
+
|
|
19
|
+
This naming convention isn't required, but it helps distinguish a variable that
|
|
20
|
+
refers to a widget from one of your variables.
|
|
21
|
+
|
|
22
|
+
The main program creates an instance of the HelloGUI class and shows it:
|
|
23
|
+
|
|
24
|
+
HelloGUI.new().show_glade()
|
|
25
|
+
|
|
26
|
+
The following method uses this ID, such that it runs when the button is clicked:
|
|
27
|
+
|
|
28
|
+
From HelloGUI.rb:
|
|
29
|
+
|
|
30
|
+
def ui_hello_btn__clicked(*args)
|
|
31
|
+
alert("Hello World")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
The name of this method is definately not an accident. It follows a naming convention:
|
|
36
|
+
|
|
37
|
+
<GladeID>__<event> # two underscores between ID and event!
|
|
38
|
+
|
|
39
|
+
So the method, ui_hello_btn__clicked(*args) runs when the button with glade ID "ui_hello_btn"
|
|
40
|
+
encounters a "clicked" event. To make this work, you only need to create a unique glade ID and
|
|
41
|
+
name your method correctly. It will call the method based on its name.
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
SUMMARY:
|
|
45
|
+
1) Give the widgets on the form unique glade IDs, then refer to them by their ID.
|
|
46
|
+
2) Store your glade files in the subdirectory /glade. Mapping: MyClass.rb => glade/MyClass.glade
|
|
47
|
+
3) Visualruby will call event handlers by the naming convention: <GladeID>__<event> (see next examples)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
|
|
2
|
+
This example shows how a instance variable named @builder is
|
|
3
|
+
automatically created when the show_glade() method is called.
|
|
4
|
+
It runs this code:
|
|
5
|
+
|
|
6
|
+
@builder = Gtk::Builder.new(file: "glade/BuilderDemo.glade")
|
|
7
|
+
|
|
8
|
+
which loads the glade file into the @builder variable. This is done
|
|
9
|
+
behind the scenes in GladeGUI, so the @builder variable will magically
|
|
10
|
+
apper in your script.
|
|
11
|
+
|
|
12
|
+
The @builder variable holds references to all the widgets (and windows etc).
|
|
13
|
+
You can access any widget using its glade ID:
|
|
14
|
+
|
|
15
|
+
widget = @builder[:ui_widget_btn]
|
|
16
|
+
|
|
17
|
+
You can get and set properties:
|
|
18
|
+
|
|
19
|
+
my_button = @builder[:ui_widget_btn] # retreives reference to button
|
|
20
|
+
puts my_button.label # using GtkLabel's "label" property.
|
|
21
|
+
my_button.label = "Click Me" # Changes button's text to "Click Me"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
However, the @builder variable isn't created until show_glade() is called
|
|
25
|
+
so it isn't useable in the initialize() method. But you can use it in a method,
|
|
26
|
+
before_show(). This is a method that's automatically called before
|
|
27
|
+
the window is shown.
|
|
28
|
+
|
|
29
|
+
SUMMARY:
|
|
30
|
+
1) The @builder variable is created when you call show_glade()
|
|
31
|
+
2) Every item in the glade form can be retreived with its glade ID
|
|
32
|
+
3) @builder is an instance variable so visible to subclasses etc.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
The before_show() method
|
|
3
|
+
|
|
4
|
+
When you create a form, you'll often want to initialize it with data.
|
|
5
|
+
|
|
6
|
+
However, the initialize() method can't be used to set-up your form because the @builder
|
|
7
|
+
variable hasn't been created yet. In the initialize() method, @builder = nil!
|
|
8
|
+
So you must use the before_show() method because it runs after initialize() and
|
|
9
|
+
before the show() method.
|
|
10
|
+
|
|
11
|
+
The before_show() method is automatically called just before a form is shown
|
|
12
|
+
on the screen. It gives you an opportunity to set-up your form with data, just before
|
|
13
|
+
being shown. It is optional, but if you write a before_show() method, it will
|
|
14
|
+
automatically be called when you call the show_glade() method.
|
|
15
|
+
There is no need to explicitly call it.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
Typically in the before_show() method, you populate your form:
|
|
19
|
+
|
|
20
|
+
def before_show()
|
|
21
|
+
@view = VR::ListView.new(...)
|
|
22
|
+
@builder["scrolledwindow1"].add_child(@view) # add custom listview to scrolledwindow1
|
|
23
|
+
@builder["button1"].label = get_customer_name()
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
Anything can be done because you have the @builder variable which references everything
|
|
27
|
+
on the form.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
Menus
|
|
3
|
+
|
|
4
|
+
You can easily make menus and toolbars in glade without any lines of code. You
|
|
5
|
+
just insert a menu into your form using glade, and give each menu item a unique name, then
|
|
6
|
+
create a method to run when the user selects the menu item.
|
|
7
|
+
|
|
8
|
+
You can see the menus for this example program by double-clicking the Menus.glade file. Then
|
|
9
|
+
right-click on the MenuBar in the tree and select "Edit."
|
|
10
|
+
You'll see that theres a menu and a toolbar with the following menu items:
|
|
11
|
+
|
|
12
|
+
ui_open_menu
|
|
13
|
+
ui_save_menu
|
|
14
|
+
ui_quit_menu
|
|
15
|
+
|
|
16
|
+
ui_zoom_tool
|
|
17
|
+
ui_home_tool
|
|
18
|
+
etc.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
When you select a menu item, an event named "activate" is fired, so you can write
|
|
22
|
+
a method to handle this event:
|
|
23
|
+
|
|
24
|
+
def ui_open_menu__activate(*args)
|
|
25
|
+
alert("Open clicked...")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
Likewise, the toolbar items are buttons so they have a "clicked" event:
|
|
29
|
+
|
|
30
|
+
def ui_zoom_tool__clicked(*args)
|
|
31
|
+
alert("Zooming in...")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
You can build the whole thing in glade, then just write event handlers with the
|
|
35
|
+
naming convention:
|
|
36
|
+
|
|
37
|
+
<GladeID>__<event> # two underscores!
|
|
38
|
+
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
|
|
2
|
+
Alert Box Examples
|
|
3
|
+
|
|
4
|
+
The alert() method can be used anywhere in your script.
|
|
5
|
+
It is a simple pop-up window that gives the user a message
|
|
6
|
+
with optional input.
|
|
7
|
+
|
|
8
|
+
The most basic example is popping up a message on the screen:
|
|
9
|
+
|
|
10
|
+
alert("Hello World")
|
|
11
|
+
|
|
12
|
+
But it can do much more using optional parameters.
|
|
13
|
+
|
|
14
|
+
You can add a headline or title:
|
|
15
|
+
|
|
16
|
+
alert("Nice to see you", headline: "Hello World")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
It has the option to have additional buttons:
|
|
20
|
+
|
|
21
|
+
button_yes: (returns data or true)
|
|
22
|
+
button_no: (returns false)
|
|
23
|
+
button_cancel: (returns nil)
|
|
24
|
+
|
|
25
|
+
So you can program it to do anything with those options:
|
|
26
|
+
|
|
27
|
+
answer = alert("Hello", button_yes: "Hi", button_cancel: "Goodbye")
|
|
28
|
+
|
|
29
|
+
This will show an alert pop-up with a button saying "Hi" and "Goodbye"
|
|
30
|
+
And it will return a value for the button clicked.
|
|
31
|
+
You can write code to respond to clicking these buttons.
|
|
32
|
+
|
|
33
|
+
You have several options to get users to input data using the :data option:
|
|
34
|
+
|
|
35
|
+
answer = alert("Enter your name:", data: "Name goes here...")
|
|
36
|
+
|
|
37
|
+
This will return a string for the name. There are a few ways to ask for data
|
|
38
|
+
in alert(). It depends on the type of data you send it. In the last example,
|
|
39
|
+
we sent it a String, and it shows a Gtk::Entry to edit the string. You can also
|
|
40
|
+
pass it an array or a hash:
|
|
41
|
+
|
|
42
|
+
String ==> Entry box
|
|
43
|
+
Array ==> Drop Down chooser menu
|
|
44
|
+
Hash ==> Multiple Entry Boxes
|
|
45
|
+
|
|
46
|
+
Press the Run button to see them in action.
|
|
47
|
+
|
|
48
|
+
Most of the time, you'll just use a simple "ok" and "cancel" button, but you have
|
|
49
|
+
the option to add a :no_button to do any other task:
|
|
50
|
+
|
|
51
|
+
answer = alert("Enter name/password:", data: { name: "", password: ""}, button_no: "Forgot Password")
|
|
52
|
+
|
|
53
|
+
Now there is a third button to do something else if they forgot their password.
|
|
54
|
+
|
|
55
|
+
Here are all the options:
|
|
56
|
+
|
|
57
|
+
:buton_yes = label for button that returns true (default: "Ok", "Save" when input_text is set))
|
|
58
|
+
:button_no = label for button that returns false (default "Cancel" when input text is set)
|
|
59
|
+
:button_cancel = label for button that returns nil
|
|
60
|
+
:data = data for user to edit. (String, Hash, or Array)
|
|
61
|
+
:width = with of window (used to make longer messages with wrapping look good.)
|
|
62
|
+
:title = title of the window (appears in bar at top) Default = :headline
|
|
63
|
+
:headline = large text that appears at the top.
|
|
64
|
+
:parent = reference to parent window. Alert box will always be on top of this parent. Usually=self!
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
2
|
+
require_relative "./../../lib/vrlib"
|
|
3
3
|
|
|
4
4
|
require_relative "src/AlertBoxDemo.rb"
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
main = Gtk::Application.new()
|
|
6
|
+
main = Gtk::Application.new("org.visualruby.main")
|
|
9
7
|
main.signal_connect "activate" do |app|
|
|
10
|
-
AlertBoxDemo.new.show_glade()
|
|
8
|
+
app = AlertBoxDemo.new.show_glade()
|
|
11
9
|
end
|
|
12
10
|
main.run
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
|
|
2
|
+
This demonstrates how visualruby handles events.
|
|
3
|
+
|
|
4
|
+
An example of an event is when a user clicks a button.
|
|
5
|
+
The button itself is an instance of Gtk::Button, and it has an event
|
|
6
|
+
associated with it called "clicked". When the user clicks the
|
|
7
|
+
buttion, the "clicked" event occurs, calling a method to take some action.
|
|
8
|
+
|
|
9
|
+
The code would look like this if you did everything without the benefit of
|
|
10
|
+
visualruby or glade:
|
|
11
|
+
|
|
12
|
+
@button = Gtk::Button.new(label: "Say hello")
|
|
13
|
+
@button.signal_connect "clicked" do |_widget|
|
|
14
|
+
puts "Hello World!!"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
You are free to write code like this. However, its much easier and faster in visualruby.
|
|
18
|
+
|
|
19
|
+
With visualruby, you can create your button in glade exacly how you like it, then
|
|
20
|
+
give it a name like: ui_hello_but. Then you can write a method for
|
|
21
|
+
the ui_hello_but by simply using this naming convention:
|
|
22
|
+
|
|
23
|
+
def ui_hello_but__clicked(*args) # two underscores!
|
|
24
|
+
puts "Hello World!!"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
Visualruby will automatically find this method, and execute the code based
|
|
28
|
+
on the method's naming convention.
|
|
29
|
+
|
|
30
|
+
It takes the form:
|
|
31
|
+
|
|
32
|
+
object__event_name(*args) # *args just captures arguments, often ignored
|
|
33
|
+
|
|
34
|
+
When you run your program, visualruby will look at all the names of methods,
|
|
35
|
+
and if it sees a name that has 2 underscores, it will look for an
|
|
36
|
+
object and an event to match it to. In our example, it would find the method,
|
|
37
|
+
#ui_hello_but__clicked, and see that ui_hello_but is a button on the glade
|
|
38
|
+
form, and the button has a matching "clicked" event. So it would run this code
|
|
39
|
+
when the user clicks the button.
|
|
40
|
+
|
|
41
|
+
Visualruby would run this code under the hood:
|
|
42
|
+
|
|
43
|
+
@builder["ui_hello_but"].signal_connect "clicked" do |*args|
|
|
44
|
+
ui_hello_but__clicked(*args)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
So you don't need to hard code everything, just use the naming convention.
|
|
48
|
+
|
|
49
|
+
There are three different forms the method name can take:
|
|
50
|
+
|
|
51
|
+
1) the one described above
|
|
52
|
+
|
|
53
|
+
2) It will call event handlers based on an instance variable name:
|
|
54
|
+
|
|
55
|
+
@var = @builder["ui_hello_but"] # var is instance of Gtk::Button
|
|
56
|
+
def var__clicked(*args)
|
|
57
|
+
puts "Hello World"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
3) If your class is a subclass of a Gtk::Button:
|
|
61
|
+
|
|
62
|
+
class MyClass
|
|
63
|
+
...
|
|
64
|
+
@button = MyButton.new(label: "Hello") # necessary step!
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
class MyButton < Gtk::Button
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
def self__clicked(*args)
|
|
71
|
+
puts "Hello World"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
Note: it is necessary to have an instance variable that refers to
|
|
77
|
+
your button in order for visualruby to find the self__xxxxx methods.
|
|
78
|
+
If you just insert it into a form, there will be no reference to it.
|
|
79
|
+
|
|
80
|
+
Using this method, you can write your own custom subclass of Gtk::TextView
|
|
81
|
+
and use it whereever you want.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
Closing Windows
|
|
3
|
+
|
|
4
|
+
Visualruby has some helpful features to handle closing windows.
|
|
5
|
+
|
|
6
|
+
First, you can make a "cancel button" on any form by simply giving
|
|
7
|
+
it the glade name:
|
|
8
|
+
|
|
9
|
+
cancelButton
|
|
10
|
+
|
|
11
|
+
Any button with that name will be recognized, and its window will be closed automatically
|
|
12
|
+
when you press it. This is nice because you don't need to clutter your code with
|
|
13
|
+
a method named "cancelButton__clicked()" on every form.
|
|
14
|
+
|
|
15
|
+
However, sometimes it's desirable to interrupt the window closing process
|
|
16
|
+
to avoid data loss. Sometimes, you want the program to confirm that
|
|
17
|
+
the user wants to discard the data on the form. Usually, asking, "Are you sure you want to close?"
|
|
18
|
+
|
|
19
|
+
There's a GTK event named "delete_event" that is fired before the window is destroyed.
|
|
20
|
+
You can write this method to run before the window is destroyed:
|
|
21
|
+
|
|
22
|
+
def window1__delete_event(*a)
|
|
23
|
+
answer = alert("Do you really want to leave?", button_yes: "Yes!", button_no: "No")
|
|
24
|
+
if answer == true
|
|
25
|
+
return false # will close window
|
|
26
|
+
else
|
|
27
|
+
return true # abort and stay here
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
Remember, that ALL windows have the name "window1"
|
|
32
|
+
|
|
33
|
+
If this method returns false, the window closes. If it returns true, it leaves the window
|
|
34
|
+
open. You can try it for yourself by hitting the "run" button now.
|
|
35
|
+
|
|
36
|
+
So the "destroy" method will kill the window without asking, but all the "close" requests will
|
|
37
|
+
be interrupted, and run the window1__delete_event() method.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
|
|
2
|
+
Using get_glade_variables and set_glade_variables
|
|
3
|
+
|
|
4
|
+
Visualruby uses @builder variable to hold references
|
|
5
|
+
to all the GUI components on the glade form. It's created by GladeGUI.
|
|
6
|
+
So you can retreive the instance of a widget by using its glade name:
|
|
7
|
+
|
|
8
|
+
@builder["ui_customer_ent"].text = "Harry"
|
|
9
|
+
|
|
10
|
+
This would likely be a Gtk::Entry for a customer's name that now shows "Harry".
|
|
11
|
+
|
|
12
|
+
However, usually there will be many fields on the form that need to be filled beyond
|
|
13
|
+
customer (e.g. address, phone, email etc.) To initialize your form, you would need
|
|
14
|
+
to populate the fields like this:
|
|
15
|
+
|
|
16
|
+
def before_show()
|
|
17
|
+
@builder["ui_customer_ent"].text = "Harry"
|
|
18
|
+
@builder["ui_customer_id_ent"].text = "4356444"
|
|
19
|
+
@builder["ui_customer_address_ent"].text = "3424 Main St"
|
|
20
|
+
# etc.
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
Then those values would show on the screen.
|
|
24
|
+
|
|
25
|
+
However, visualruby will do this for you automatically using a method named
|
|
26
|
+
set_glade_variables. To use it you just need to create instance variables
|
|
27
|
+
with the same names as your widgets in glade:
|
|
28
|
+
|
|
29
|
+
def initialize
|
|
30
|
+
@ui_customer_ent" = "Harry"
|
|
31
|
+
@ui_customer_id_ent = "4356444"
|
|
32
|
+
@ui_customer_address_ent = "3424 Main St"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
Then, when the #show_glade method is called, it will automatically call #set_glade_variables
|
|
36
|
+
to do this:
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@builder["ui_customer_ent"].text = @ui_customer_ent
|
|
40
|
+
@builder["ui_customer_id_ent"].text = @ui_customer_id_ent
|
|
41
|
+
@builder["ui_customer_address_ent"].text = @ui_customer_address_ent
|
|
42
|
+
# etc.
|
|
43
|
+
|
|
44
|
+
It's a shortcut to match the names of the instance variables to the glade names
|
|
45
|
+
and fill in the values on the form.
|
|
46
|
+
|
|
47
|
+
You can also do the reverse, and read the form values back into the variables
|
|
48
|
+
using method, #get_glade_variables.
|
|
49
|
+
|
|
50
|
+
This saves even more typing and errors. You can replace this:
|
|
51
|
+
|
|
52
|
+
@ui_customer_ent = @builder["ui_customer_ent"].text
|
|
53
|
+
@ui_customer_id_ent = @builder["ui_customer_id_ent"].text
|
|
54
|
+
@ui_customer_id_address = @builder["ui_customer_address_ent"].text
|
|
55
|
+
|
|
56
|
+
with this:
|
|
57
|
+
|
|
58
|
+
get_glade_variables
|
|
59
|
+
|
|
60
|
+
Now you can save to a database etc.
|
|
61
|
+
|
|
62
|
+
So the general procedure is to create a list of instance variables in the #initialize method,
|
|
63
|
+
then visualruby will update the form with the values. When done, retreive the values
|
|
64
|
+
using #get_glade_variables.
|
|
65
|
+
|
|
66
|
+
An added benefit is that it creates a nice list of the fields on the
|
|
67
|
+
form so you don't need to look them up in glade.
|
|
68
|
+
|
|
69
|
+
This process can be done with many widgets including buttons, images, calendar dates, entries
|
|
70
|
+
etc. You can see this in the next example.
|
|
71
|
+
|
|
72
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
This example shows a shortcut to assigning initial properties
|
|
3
|
+
to widgets in your glade form. This method can be used in the
|
|
4
|
+
initialize() method because it only assigns values to variables
|
|
5
|
+
that are later loaded into widgets when show_glade() is called.
|
|
6
|
+
|
|
7
|
+
So this works:
|
|
8
|
+
|
|
9
|
+
def initialize()
|
|
10
|
+
@ui_splash_img = "src/splash.png"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
In ititialize() @ui_splash_img is a String. But, when show_glade()
|
|
14
|
+
is called, it will be loaded into the glade form.
|
|
15
|
+
The glade form contains an ID named ui_splash_img (a Gtk::Image)
|
|
16
|
+
This is how GladeGUI loads the string into the Gtk::Image:
|
|
17
|
+
|
|
18
|
+
GladeGUI:
|
|
19
|
+
|
|
20
|
+
if @builder["ui_splash_img"].is_a Gtk::Image
|
|
21
|
+
@builder["ui_splash_image"].file = @ui_splash_img
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
So its finding where a variable name matches a glade ID and populating
|
|
25
|
+
the widget with the appropriate data.
|
|
26
|
+
|
|
27
|
+
There is a method named set_glade_variables() in GladeGUI that does
|
|
28
|
+
this translating. And there is a another method named get_glade_variables()
|
|
29
|
+
that retreives the widget variables back into the instance variables.
|
|
30
|
+
See the example named "get_glade_variables" for more.
|
|
31
|
+
|
|
32
|
+
Note: you must add an "adjustment" object to the spinbutton in glade
|
|
33
|
+
to make it work.
|
|
34
|
+
|
|
35
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
This example shows how you can make an array of glade widgets
|
|
3
|
+
that corresponds to an array in ruby, and you can use
|
|
4
|
+
the get_glade_variables and set_glade_variables to
|
|
5
|
+
update between the form and variables.
|
|
6
|
+
|
|
7
|
+
In the glade form, there are buttons named:
|
|
8
|
+
|
|
9
|
+
button[0]
|
|
10
|
+
button[1]
|
|
11
|
+
button[2]
|
|
12
|
+
etc.
|
|
13
|
+
|
|
14
|
+
In ruby there is a corresponding array with the labels for the buttons.
|
|
15
|
+
When show_glade() is run, it automatically runs set_glade_variables(), loading
|
|
16
|
+
the ruby array onto the buttons. Then the calculator uses the labels to do the
|
|
17
|
+
calculations.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
--- !ruby/object:VR_ENV
|
|
2
|
+
vr_yaml_file: "/home/eric/vrp/vr3/examples/36_dialog_box/.vr_settings.yaml"
|
|
3
|
+
width: 1854
|
|
4
|
+
height: 1003
|
|
5
|
+
panel_pos: 360
|
|
6
|
+
notebook_panel_position: 606
|
|
7
|
+
run_command_line: dialog_box.rb
|
|
8
|
+
open_files:
|
|
9
|
+
- "/home/eric/vrp/vr3/examples/36_dialog_box/README.txt"
|
|
10
|
+
- "/home/eric/vrp/vr3/examples/36_dialog_box/dialog_box.rb"
|
|
11
|
+
- "/home/eric/vrp/vr3/examples/36_dialog_box/src/ChooserDialog.rb"
|
|
12
|
+
open_folders:
|
|
13
|
+
- "/home/eric/vrp/vr3/examples/36_dialog_box"
|
|
14
|
+
- "/home/eric/vrp/vr3/examples/36_dialog_box/src"
|
|
15
|
+
- "/home/eric/vrp/vr3/examples/36_dialog_box/src/glade"
|
|
16
|
+
current_file: "/home/eric/vrp/vr3/examples/36_dialog_box/README.txt"
|
|
17
|
+
current_line: 30
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
DIALOG BOXES
|
|
3
|
+
|
|
4
|
+
Dialog boxes offer the ability to present questions to the user and wait
|
|
5
|
+
for the answer. They are simply a Gtk::Window that has a run() method that
|
|
6
|
+
blocks the main event loop, and waits for a response.
|
|
7
|
+
|
|
8
|
+
The alert() method in visualruby uses a dialog box because it needs to wait for
|
|
9
|
+
the user input before proceeding. (see alert_box example)
|
|
10
|
+
|
|
11
|
+
In fact, the vast majority of the time, you won't need to write your own dialog
|
|
12
|
+
box becuase you can just use the alert() method.
|
|
13
|
+
|
|
14
|
+
This example, shows a situation where you're asing for a boolean input, so it
|
|
15
|
+
isn't supported by the alert() method. So, here you can just create a custom
|
|
16
|
+
dialog box with a boolean input.
|
|
17
|
+
|
|
18
|
+
These dialog boxes can be as extensive as you like.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
The run() method returns a Gtk::ResponseType object. It has several preset return values.
|
|
22
|
+
You can see a list of them here:
|
|
23
|
+
|
|
24
|
+
https://docs.gtk.org/gtk3/enum.ResponseType.html
|
|
25
|
+
|
|
26
|
+
You need to set the "Response ID" of each button to tell it which value to return.
|
|
27
|
+
Here, there is a "OK" button with a response id = OK. That means that when you click it,
|
|
28
|
+
the run() method returns GTK::ResponseType::OK
|
|
29
|
+
|
|
30
|
+
|
|
@@ -12,6 +12,6 @@ open_files:
|
|
|
12
12
|
open_folders:
|
|
13
13
|
- "/home/eric/vrp/vr3/examples/49_settings_file"
|
|
14
14
|
- "/home/eric/vrp/vr3/examples/49_settings_file/src"
|
|
15
|
-
current_file: "/home/eric/vrp/vr3/examples/49_settings_file/
|
|
16
|
-
current_line:
|
|
15
|
+
current_file: "/home/eric/vrp/vr3/examples/49_settings_file/save_settings.rb"
|
|
16
|
+
current_line: 12
|
|
17
17
|
rdoc_command_line: rdoc -x README
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
|
|
2
|
+
SAVING A CLASS TO A YAML FILE
|
|
3
|
+
|
|
4
|
+
Visualruby has 2 methods that allow you to save any instance of a class to a yaml
|
|
5
|
+
file, then retreive it from disk later:
|
|
6
|
+
|
|
7
|
+
var = VR::load_yaml(MyClass, "/path/to/file/class_instance.yaml", *args)
|
|
8
|
+
|
|
9
|
+
and
|
|
10
|
+
|
|
11
|
+
VR::save_yaml(var) # or VR::save_yaml(self) from inside class
|
|
12
|
+
|
|
13
|
+
The first time you use VR::load_yaml(), it will create an instance of MyClass
|
|
14
|
+
with a variable, @vr_yaml_file that records the complete file
|
|
15
|
+
path used for saving and retreiving it.
|
|
16
|
+
|
|
17
|
+
When you call VR::load_yaml(), it will try to load the file from disk, but if the file
|
|
18
|
+
isn't there, it will create an instance of MyClass that can be saved later.
|
|
19
|
+
|
|
20
|
+
VR::save_yaml() will write the image of the file to that path.
|
|
21
|
+
|
|
22
|
+
The "*args" parameter holds all the arguments you wish to pass to the constructor.
|
|
23
|
+
So this happens under the hood:
|
|
24
|
+
|
|
25
|
+
me = MyClass.new(*args)
|
|
26
|
+
|
|
27
|
+
To create a savable class, you just need to
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
|
|
2
|
+
While Gtk offers a Gtk::TreeView and Gtk::ListView class, they are
|
|
3
|
+
very difficult to use. Visualruby has created subclasses of Gtk::TreeView
|
|
4
|
+
and Gtk::ListView that are much easier to use. The TreeView and ListView classes are
|
|
5
|
+
almost the same class so all the methods and properties here can be applied to
|
|
6
|
+
both ListViews and TreeViews. This example is for a VR::ListView, but everything applies to
|
|
7
|
+
VR::TreeView too.
|
|
8
|
+
|
|
9
|
+
The VR::ListView constructor has the benefit of applying names to all the columns:
|
|
10
|
+
|
|
11
|
+
@view = VR::ListView( name: String, age: Integer )
|
|
12
|
+
|
|
13
|
+
The VR::ListView class will keep a hash of column names that can be retreived
|
|
14
|
+
using the id() method:
|
|
15
|
+
|
|
16
|
+
@age = id(:age) # ==> 1
|
|
17
|
+
|
|
18
|
+
This is much easier than Gtk's classes which use numbers to identify columns.
|
|
19
|
+
|
|
20
|
+
Since VR::ListView is a subclass of Gtk::ListView, you can still use all the properties
|
|
21
|
+
from Gtk::ListView including the ".model" property that holds all the data.
|
|
22
|
+
The ".model" property is like a complete table (or spreadsheet) of data with columns and rows.
|
|
23
|
+
When you access the ".model", you need to use the id() method so you pass a column number:
|
|
24
|
+
|
|
25
|
+
row = model.first # this is model from Gtk::ListView
|
|
26
|
+
x = row[id(:age)] # ==> that row's age
|
|
27
|
+
|
|
28
|
+
In this example, it calls the Gtk::ListView's #append method to add rows:
|
|
29
|
+
|
|
30
|
+
row = model.append
|
|
31
|
+
row[id(:name)] = "Helen" # same as row[0] = "Helen"
|
|
32
|
+
etc.
|
|
33
|
+
|
|
34
|
+
Again, the id() method is converting the column symbol, ":name" to the correct integer
|
|
35
|
+
for the column, so you can identify columns by their symbol.
|
|
36
|
+
|
|
37
|
+
Summary:
|
|
38
|
+
1) using VR::ListView and VR::Treeveiw allows naming of columns
|
|
39
|
+
2) You can still use Gtk::Listview's methods and properties because it's their superclass
|
|
40
|
+
|
|
41
|
+
This example creates the most basic VR::ListView, but it can do a lot more including
|
|
42
|
+
changing columns' and cells' appearance, changing the header, sorting etc.
|
|
43
|
+
Click "Open Project" to go to the next example...
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
There is a list of color names here:
|
|
49
|
+
|
|
50
|
+
https://drafts.csswg.org/css-color/#named-colors
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
|
|
2
|
+
The last example showed how easy it is to create a VR::ListView but it needed
|
|
3
|
+
to look a little better.
|
|
4
|
+
|
|
5
|
+
In this example, we will fix these items:
|
|
6
|
+
|
|
7
|
+
1) The columns are squished together on the left side.
|
|
8
|
+
2) The width is too wide
|
|
9
|
+
3) The "Balance" numbers and header needs to right-justify, so it forms a column.
|
|
10
|
+
4) The "Balance" numbers should have 2 decimal places.
|
|
11
|
+
5) Negatave balances shold be in red.
|
|
12
|
+
|
|
13
|
+
First, we fix the attributes of the columns, and later we'll fix the individual cells.
|
|
14
|
+
To change attributes for whole columns, the col_attr() and col_[attribute_name] methods
|
|
15
|
+
are used:
|
|
16
|
+
|
|
17
|
+
col_width(name: 160, balance: 120)
|
|
18
|
+
col_attr(:balance, alignment: 1, xalign: 1)
|
|
19
|
+
|
|
20
|
+
This will solve issues 1, 2 and 3. This is a simple example, but the col_attr() method
|
|
21
|
+
can do much more:
|
|
22
|
+
|
|
23
|
+
col_attr(width: 200) # changes width of ALL columns to 200
|
|
24
|
+
col_attr(:balance, :name, background: "pink", foreground: "gray")
|
|
25
|
+
|
|
26
|
+
It can handle any number of columns and attributes. Also, it works on the column and
|
|
27
|
+
renderer's attributes so you can change renderer's attributes too. Likewise the
|
|
28
|
+
col_[attribute_name] method is useful to change one attribute for many columns:
|
|
29
|
+
|
|
30
|
+
col_width(200) # changes all widths to 200 (same as above)
|
|
31
|
+
col_foreground( "gray", :balance, :name)
|
|
32
|
+
|
|
33
|
+
The col_[attribute_name] method works for any attribute. So, col_xalign() and col_background() both work.
|
|
34
|
+
These methods are very similar: they both just set attributes for columns and renderers.
|
|
35
|
+
But the col_attr sets multiple attributes for columns, whereas the col_[attribute_name]
|
|
36
|
+
sets a single attribute for multiple columns. You can use either one. You can't go wrong.
|
|
37
|
+
|
|
38
|
+
Individual Cells
|
|
39
|
+
|
|
40
|
+
To make the negative balances appear in red, and truncate the numbers to 2 decimal places,
|
|
41
|
+
we need to operate on each individual cell. Gtk::TreeView has a method called,
|
|
42
|
+
set_cell_data_func() that accepts a code block to be executed on each cell, and the result
|
|
43
|
+
gets painted on the screen. This is a complicated method to use. VR::ListView added a
|
|
44
|
+
shortcut method named each_cell_method() that just passes a method to Gtk's set_cell_data_func()
|
|
45
|
+
but is much easier to use:
|
|
46
|
+
|
|
47
|
+
def initialize()
|
|
48
|
+
...
|
|
49
|
+
each_cell_method(:balance, method(:make_negatives_red))
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def make_negatives_red(col, rend, model, iter)
|
|
53
|
+
col_id = id(rend.model_sym)
|
|
54
|
+
balance = iter[col_id]
|
|
55
|
+
if balance < 0
|
|
56
|
+
rend.text = "(%.2f)" % balance.abs
|
|
57
|
+
rend.foreground = "darkred"
|
|
58
|
+
rend.weight = 700
|
|
59
|
+
else
|
|
60
|
+
rend.text = "%.2f" % balance
|
|
61
|
+
rend.foreground = "black"
|
|
62
|
+
rend.weight = 400
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
The each_cell_method() line is telling it to call the make_negatives_red() method on each cell
|
|
67
|
+
in the :balance column. The result will be displayed on the screen.
|
|
68
|
+
|
|
69
|
+
The make_negatives_red method must accept four parameters, (col, rend, model, iter) because
|
|
70
|
+
the Gtk::TreeView will be passing it those 4 parameters. This is Gtk's business. It will
|
|
71
|
+
always pass those parameters, so you must write your method to accept them.
|
|
72
|
+
|
|
73
|
+
There's a wrinkle to this story: Because this is a VR::ListView (not Gtk), the make_negatives_red() method
|
|
74
|
+
will be passed a VR::TreeViewColumn, VR::CellRendererText and a VR::Iter instead of their Gtk
|
|
75
|
+
equivalents.
|
|
76
|
+
|
|
77
|
+
That allows us to do this:
|
|
78
|
+
|
|
79
|
+
col_id = id(rend.model_sym)
|
|
80
|
+
balance = iter[col_id]
|
|
81
|
+
|
|
82
|
+
So using VR::ListView, you can look up the symbol of the column. Then use the id() method to
|
|
83
|
+
retreive the column number used by Gtk. This illustrates the benefits of VR::ListView.
|
|
84
|
+
|
|
85
|
+
Also, because the make_negatives_red() function looks up the column number for itself, it can
|
|
86
|
+
be reused on any column:
|
|
87
|
+
|
|
88
|
+
each_cell_method( :degree_angle, method(:make_negatives_red))
|
|
89
|
+
each_cell_method( :weight_diff, method(:make_negatives_red))
|
|
90
|
+
each_cell_method( :spin_rate, method(:make_negatives_red))
|
|
91
|
+
|
|
92
|
+
This would work on all those number columns.
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
There is a list of color names here:
|
|
96
|
+
|
|
97
|
+
https://drafts.csswg.org/css-color/#named-colors
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
@@ -4,14 +4,14 @@ width: 1854
|
|
|
4
4
|
height: 1003
|
|
5
5
|
panel_pos: 491
|
|
6
6
|
notebook_panel_position: 687
|
|
7
|
-
run_command_line:
|
|
7
|
+
run_command_line: familytree.rb
|
|
8
8
|
open_files:
|
|
9
9
|
- "/home/eric/vrp/vr3/examples/75_treeview/familytree.rb"
|
|
10
10
|
open_folders:
|
|
11
11
|
- "/home/eric/vrp/vr3/examples/75_treeview"
|
|
12
12
|
current_file: "/home/eric/vrp/vr3/examples/75_treeview/familytree.rb"
|
|
13
13
|
current_line: 10
|
|
14
|
-
rdoc_command_line: rdoc -x README
|
|
15
14
|
builder: !ruby/object:Gtk::Builder {}
|
|
15
|
+
rdoc_command_line: rdoc -x README
|
|
16
16
|
top_level_window: false
|
|
17
17
|
settings_file_version: 1
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
Press the "Run" button and see what happens.
|
|
2
|
+
|
|
3
|
+
This example shows the best way to insert a Gtk::TreeView object into your forms.
|
|
4
|
+
If you double click on the FamilyTree.glade file, you will see that there is no Gtk::TreeView
|
|
5
|
+
in the form. Instead, there is an empty Gtk::ScrolledWindow named "scrolledwindow1."
|
|
6
|
+
|
|
7
|
+
This scrolledwindow1 is a blank canvas where we can insert our TreeView.
|
|
8
|
+
|
|
9
|
+
Glade had a Gtk::TreeView widget that you can insert in glade, but it is very problematic
|
|
10
|
+
to work with because it is stuck in a glade form. A much better approach is to create
|
|
11
|
+
a custom Gtk::TreeView and insert it into the form like this:
|
|
12
|
+
|
|
13
|
+
@builder["scrolledwindow1"].add_child(@my_tree)
|
|
14
|
+
|
|
15
|
+
This example uses VR_TreeView from the vrlib library. It is a subclass of Gtk::TreeView but adds
|
|
16
|
+
a lot of functionality and ease of use.
|
|
17
|
+
|
|
18
|
+
Its beyond our scope to describe all the complexities of Gtk::TreeView here, but a major
|
|
19
|
+
advantage to using VR::TreeView is that you can use symbols for the field names:
|
|
20
|
+
|
|
21
|
+
@tree = VR::TreeView.new(name: String, age: Integer)
|
|
22
|
+
|
|
23
|
+
Then identifly the fields by :name and :age instead of a column number as Gtk::TreeView uses.
|
|
24
|
+
|
|
25
|
+
There will be more on TreeViews and ListViews in the following examples.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
|
|
2
|
+
CREATING A STANDALONE EXE
|
|
3
|
+
|
|
4
|
+
This project will create a standalone executable file using rubygems.
|
|
5
|
+
The program will run independently from visualruby, but it depends
|
|
6
|
+
on vrlib.rb, therefore it depends on the visualruby gem.
|
|
7
|
+
|
|
8
|
+
Here are the steps needed to create the executable file, my_program:
|
|
9
|
+
|
|
10
|
+
1) Right-click my_program and make it the main program (bold).
|
|
11
|
+
|
|
12
|
+
2) Create the .gemspec file by going to:
|
|
13
|
+
|
|
14
|
+
Tools > Create Gemspec File
|
|
15
|
+
|
|
16
|
+
This will add a .gemspec file to the project. It will set the executable file
|
|
17
|
+
to be the main program, my_program. You can click on it to look at it.
|
|
18
|
+
|
|
19
|
+
3) Right click on the my_program.gemspec file and Build the gem. It will then appear
|
|
20
|
+
in the project.
|
|
21
|
+
|
|
22
|
+
4) Right-click on the .gem file and select:
|
|
23
|
+
|
|
24
|
+
Install Gem
|
|
25
|
+
|
|
26
|
+
This will install it locally on your computer.
|
|
27
|
+
|
|
28
|
+
You can now run my_program at the command line. At the command prompt enter:
|
|
29
|
+
|
|
30
|
+
my_program
|
|
31
|
+
|
|
32
|
+
When you do this process, visualruby is just executing the gem commands. So
|
|
33
|
+
if you experience and difficulty, just run the commands manually to see what's
|
|
34
|
+
going on:
|
|
35
|
+
|
|
36
|
+
gem install my_program-0.0.1.gem --local
|
|
37
|
+
|
|
38
|
+
etc.
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
data/img/ui.png
ADDED
|
Binary file
|
data/lib/GladeGUI.rb
CHANGED
data/src/editor/VR_Document.rb
CHANGED
|
@@ -21,6 +21,8 @@ class VR_Document < GtkSource::View
|
|
|
21
21
|
buffer.language = GtkSource::LanguageManager.new.get_language("html")
|
|
22
22
|
elsif [".yaml", ".yml"].include?(File.extname(full_path_file))
|
|
23
23
|
buffer.language = GtkSource::LanguageManager.new.get_language("yaml")
|
|
24
|
+
elsif [".ui", ".glade"].include?(File.extname(full_path_file))
|
|
25
|
+
buffer.language = GtkSource::LanguageManager.new.get_language("xml")
|
|
24
26
|
else
|
|
25
27
|
guess_lang = GtkSource::LanguageManager.new.guess_language(File.basename(full_path_file))
|
|
26
28
|
buffer.language = guess_lang
|
data/src/editor/VR_Tabs.rb
CHANGED
|
@@ -20,7 +20,8 @@ class VR_Tabs < Gtk::Notebook
|
|
|
20
20
|
title: "Save File As...",
|
|
21
21
|
parent: @main.builder[:window1],
|
|
22
22
|
action: :save,
|
|
23
|
-
buttons: [["_Cancel", :cancel], ["_Save", :accept]])
|
|
23
|
+
buttons: [["_Cancel", :cancel], ["_Save", :accept]])
|
|
24
|
+
dialog.resize(500, 800)
|
|
24
25
|
dialog.current_folder = File.dirname(@docs[page].full_path_file)
|
|
25
26
|
dialog.current_name = VR_Document.get_class_title(@docs[page].buffer.text)
|
|
26
27
|
resp = dialog.run
|
data/src/main/VR_ENV_GLOBAL.rb
CHANGED
|
@@ -16,7 +16,7 @@ class VR_ENV_GLOBAL
|
|
|
16
16
|
@glade_path ||= "glade"
|
|
17
17
|
@projects_home ||= File.join(ENV["HOME"], "visualruby")
|
|
18
18
|
@projects_home_open_folders ||= [@projects_home]
|
|
19
|
-
@default_project ||= File.join(ENV["HOME"], "visualruby", "examples", "
|
|
19
|
+
@default_project ||= File.join(ENV["HOME"], "visualruby", "examples", "01_phantom")
|
|
20
20
|
@home_project ||= @default_project
|
|
21
21
|
end
|
|
22
22
|
|
data/src/main/VR_Main.rb
CHANGED
|
@@ -13,7 +13,7 @@ class VR_Main
|
|
|
13
13
|
def before_show
|
|
14
14
|
|
|
15
15
|
# there must be a visualruby directory:
|
|
16
|
-
required_project = File.join(ENV["HOME"],"","visualruby", "examples", "
|
|
16
|
+
required_project = File.join(ENV["HOME"],"","visualruby", "examples", "01_phantom")
|
|
17
17
|
menuInstallExamples__activate if not VR_Tools.vr_project?(required_project)
|
|
18
18
|
|
|
19
19
|
# load global settings (requires /home/visuaruby folder exists
|
data/src/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: visualruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.6.
|
|
4
|
+
version: 3.6.14
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eric Cunningham
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir:
|
|
10
10
|
- "."
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2024-12-
|
|
12
|
+
date: 2024-12-17 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: gtk3
|
|
@@ -60,49 +60,60 @@ files:
|
|
|
60
60
|
- "./docs/img/main.png"
|
|
61
61
|
- "./docs/img/ruby_prompt.png"
|
|
62
62
|
- "./examples/01_phantom/.vr_settings.yaml"
|
|
63
|
+
- "./examples/01_phantom/README.txt"
|
|
63
64
|
- "./examples/01_phantom/phantom.rb"
|
|
64
65
|
- "./examples/01_phantom/src/Phantom.rb"
|
|
65
66
|
- "./examples/01_phantom/src/glade/Phantom.glade"
|
|
66
67
|
- "./examples/02_hello/.vr_settings.yaml"
|
|
68
|
+
- "./examples/02_hello/README.txt"
|
|
67
69
|
- "./examples/02_hello/hello.rb"
|
|
68
70
|
- "./examples/02_hello/src/HelloGUI.rb"
|
|
69
71
|
- "./examples/02_hello/src/glade/HelloGUI.glade"
|
|
70
72
|
- "./examples/03_builder_variable/.vr_settings.yaml"
|
|
73
|
+
- "./examples/03_builder_variable/README.txt"
|
|
71
74
|
- "./examples/03_builder_variable/builder.rb"
|
|
72
75
|
- "./examples/03_builder_variable/src/BuilderDemo.rb"
|
|
73
76
|
- "./examples/03_builder_variable/src/glade/BuilderDemo.glade"
|
|
74
77
|
- "./examples/04_before_show/.vr_settings.yaml"
|
|
78
|
+
- "./examples/04_before_show/README.txt"
|
|
75
79
|
- "./examples/04_before_show/before_show.rb"
|
|
76
80
|
- "./examples/04_before_show/src/BeforeShow.rb"
|
|
77
81
|
- "./examples/04_before_show/src/MyClass.rb"
|
|
78
82
|
- "./examples/04_before_show/src/glade/BeforeShow.glade"
|
|
79
83
|
- "./examples/05_menus/.vr_settings.yaml"
|
|
84
|
+
- "./examples/05_menus/README.txt"
|
|
80
85
|
- "./examples/05_menus/menus.rb"
|
|
81
86
|
- "./examples/05_menus/src/Menus.rb"
|
|
82
87
|
- "./examples/05_menus/src/glade/Menus.glade"
|
|
83
88
|
- "./examples/06_alert_box/.vr_settings.yaml"
|
|
89
|
+
- "./examples/06_alert_box/README.txt"
|
|
84
90
|
- "./examples/06_alert_box/alertdemo.rb"
|
|
85
91
|
- "./examples/06_alert_box/src/AlertBoxDemo.rb"
|
|
86
92
|
- "./examples/06_alert_box/src/glade/AlertBoxDemo.glade"
|
|
87
93
|
- "./examples/07_event_handlers/.vr_settings.yaml"
|
|
94
|
+
- "./examples/07_event_handlers/README.txt"
|
|
88
95
|
- "./examples/07_event_handlers/event_handlers.rb"
|
|
89
96
|
- "./examples/07_event_handlers/src/Event_Handlers.rb"
|
|
90
97
|
- "./examples/07_event_handlers/src/MyTextView.rb"
|
|
91
98
|
- "./examples/07_event_handlers/src/glade/Event_Handlers.glade"
|
|
92
99
|
- "./examples/08_interrupt_exit/.vr_settings.yaml"
|
|
100
|
+
- "./examples/08_interrupt_exit/README.txt"
|
|
93
101
|
- "./examples/08_interrupt_exit/interrupt_exit.rb"
|
|
94
102
|
- "./examples/08_interrupt_exit/src/InterruptExit.rb"
|
|
95
103
|
- "./examples/08_interrupt_exit/src/glade/InterruptExit.glade"
|
|
96
104
|
- "./examples/09_get_glade_variables/.vr_settings.yaml"
|
|
105
|
+
- "./examples/09_get_glade_variables/README.txt"
|
|
97
106
|
- "./examples/09_get_glade_variables/get_glade_variables.rb"
|
|
98
107
|
- "./examples/09_get_glade_variables/src/DataObjectGUI.rb"
|
|
99
108
|
- "./examples/09_get_glade_variables/src/glade/DataObjectGUI.glade"
|
|
100
109
|
- "./examples/10_all_widgets/.vr_settings.yaml"
|
|
110
|
+
- "./examples/10_all_widgets/README.txt"
|
|
101
111
|
- "./examples/10_all_widgets/all_widgets.rb"
|
|
102
112
|
- "./examples/10_all_widgets/src/AllWidgets.rb"
|
|
103
113
|
- "./examples/10_all_widgets/src/glade/AllWidgets.glade"
|
|
104
114
|
- "./examples/10_all_widgets/src/splash.png"
|
|
105
115
|
- "./examples/20_calculator/.vr_settings.yaml"
|
|
116
|
+
- "./examples/20_calculator/README.txt"
|
|
106
117
|
- "./examples/20_calculator/calculator.rb"
|
|
107
118
|
- "./examples/20_calculator/src/CalculatorGUI.rb"
|
|
108
119
|
- "./examples/20_calculator/src/glade/CalculatorGUI.glade"
|
|
@@ -116,16 +127,24 @@ files:
|
|
|
116
127
|
- "./examples/35_child_window/src/glade/ModalWindow.glade"
|
|
117
128
|
- "./examples/35_child_window/src/glade/ModelessWindow.glade"
|
|
118
129
|
- "./examples/35_child_window/src/glade/MyChildClass.glade"
|
|
130
|
+
- "./examples/36_dialog_box/.vr_settings.yaml"
|
|
131
|
+
- "./examples/36_dialog_box/README.txt"
|
|
132
|
+
- "./examples/36_dialog_box/dialog_box.rb"
|
|
133
|
+
- "./examples/36_dialog_box/src/ChooserDialog.rb"
|
|
134
|
+
- "./examples/36_dialog_box/src/glade/ChooserDialog.glade"
|
|
119
135
|
- "./examples/49_settings_file/.vr_settings.yaml"
|
|
136
|
+
- "./examples/49_settings_file/README.txt"
|
|
120
137
|
- "./examples/49_settings_file/save_settings.rb"
|
|
121
138
|
- "./examples/49_settings_file/settings.yaml"
|
|
122
139
|
- "./examples/49_settings_file/src/SavableSettings.rb"
|
|
123
140
|
- "./examples/49_settings_file/src/glade/SavableSettings.glade"
|
|
124
141
|
- "./examples/70_better_views/.vr_settings.yaml"
|
|
142
|
+
- "./examples/70_better_views/README.txt"
|
|
125
143
|
- "./examples/70_better_views/better_views.rb"
|
|
126
144
|
- "./examples/70_better_views/src/BetterView.rb"
|
|
127
145
|
- "./examples/70_better_views/src/glade/BetterView.glade"
|
|
128
146
|
- "./examples/71_prettify_view/.vr_settings.yaml"
|
|
147
|
+
- "./examples/71_prettify_view/README.txt"
|
|
129
148
|
- "./examples/71_prettify_view/prettify_view.rb"
|
|
130
149
|
- "./examples/71_prettify_view/src/PrettyView.rb"
|
|
131
150
|
- "./examples/71_prettify_view/src/glade/PrettyView.glade"
|
|
@@ -136,6 +155,7 @@ files:
|
|
|
136
155
|
- "./examples/72_object_views/src/CustomerClass.rb"
|
|
137
156
|
- "./examples/72_object_views/src/glade/BalanceListView.glade"
|
|
138
157
|
- "./examples/75_treeview/.vr_settings.yaml"
|
|
158
|
+
- "./examples/75_treeview/README.txt"
|
|
139
159
|
- "./examples/75_treeview/familytree.rb"
|
|
140
160
|
- "./examples/75_treeview/src/FamilyTree.rb"
|
|
141
161
|
- "./examples/75_treeview/src/glade/FamilyTree.glade"
|
|
@@ -184,6 +204,7 @@ files:
|
|
|
184
204
|
- "./examples/80_golf_handicap/src/glade/Handicap.glade"
|
|
185
205
|
- "./examples/80_golf_handicap/src/glade/Score.glade"
|
|
186
206
|
- "./examples/92_standalone_exe/.vr_settings.yaml"
|
|
207
|
+
- "./examples/92_standalone_exe/README.txt"
|
|
187
208
|
- "./examples/92_standalone_exe/src/MyClass.rb"
|
|
188
209
|
- "./examples/92_standalone_exe/src/glade/MyClass.glade"
|
|
189
210
|
- "./examples/95_active_record/.vr_settings.yaml"
|
|
@@ -204,10 +225,6 @@ files:
|
|
|
204
225
|
- "./examples/97_active_record2/bin/glade/Paycheck.glade"
|
|
205
226
|
- "./examples/97_active_record2/db/development.sqlite3"
|
|
206
227
|
- "./examples/97_active_record2/main.rb"
|
|
207
|
-
- "./examples/dialog_box/.vr_settings.yaml"
|
|
208
|
-
- "./examples/dialog_box/dialog_box.rb"
|
|
209
|
-
- "./examples/dialog_box/src/ChooserDialog.rb"
|
|
210
|
-
- "./examples/dialog_box/src/glade/ChooserDialog.glade"
|
|
211
228
|
- "./img/close.png"
|
|
212
229
|
- "./img/folder.png"
|
|
213
230
|
- "./img/glade.png"
|
|
@@ -217,6 +234,7 @@ files:
|
|
|
217
234
|
- "./img/rb.png"
|
|
218
235
|
- "./img/ruby.png"
|
|
219
236
|
- "./img/splash.png"
|
|
237
|
+
- "./img/ui.png"
|
|
220
238
|
- "./img/unknown.png"
|
|
221
239
|
- "./lib/Alert.rb"
|
|
222
240
|
- "./lib/AlertDialog.rb"
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
--- !ruby/object:VR_ENV
|
|
2
|
-
vr_yaml_file: "/home/eric/vrp/vr3/examples/dialog_box/.vr_settings.yaml"
|
|
3
|
-
width: 1854
|
|
4
|
-
height: 1003
|
|
5
|
-
panel_pos: 360
|
|
6
|
-
notebook_panel_position: 506
|
|
7
|
-
run_command_line: dialog_box.rb
|
|
8
|
-
open_files:
|
|
9
|
-
- "/home/eric/vrp/vr3/examples/dialog_box/dialog_box.rb"
|
|
10
|
-
- "/home/eric/vrp/vr3/examples/dialog_box/src/ChooserDialog.rb"
|
|
11
|
-
open_folders:
|
|
12
|
-
- "/home/eric/vrp/vr3/examples/dialog_box"
|
|
13
|
-
- "/home/eric/vrp/vr3/examples/dialog_box/src"
|
|
14
|
-
- "/home/eric/vrp/vr3/examples/dialog_box/src/glade"
|
|
15
|
-
current_file: "/home/eric/vrp/vr3/examples/dialog_box/src/ChooserDialog.rb"
|
|
16
|
-
current_line: 15
|
|
File without changes
|
|
File without changes
|
|
File without changes
|