gtk3 3.0.9 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/gtk3/rb-gtk3-private.h +1 -0
- data/ext/gtk3/rb-gtk3-spin-button.c +85 -0
- data/ext/gtk3/rb-gtk3.c +3 -0
- data/lib/gtk3/deprecated.rb +0 -8
- data/lib/gtk3/loader.rb +1 -7
- data/lib/gtk3/tree-model.rb +2 -0
- data/sample/gtk-demo/TODO +10 -10
- data/sample/gtk-demo/assistant.rb +44 -39
- data/sample/gtk-demo/builder.rb +71 -50
- data/sample/gtk-demo/button_box.rb +39 -28
- data/sample/gtk-demo/clipboard.rb +139 -46
- data/sample/gtk-demo/colorsel.rb +50 -36
- data/sample/gtk-demo/css_accordion.rb +18 -17
- data/sample/gtk-demo/css_basics.rb +60 -47
- data/sample/gtk-demo/css_multiplebgs.rb +92 -71
- data/sample/gtk-demo/css_pixbufs.rb +61 -48
- data/sample/gtk-demo/css_shadows.rb +63 -50
- data/sample/gtk-demo/cursors.rb +95 -64
- data/sample/gtk-demo/dialog.rb +95 -78
- data/sample/gtk-demo/drawingarea.rb +138 -171
- data/sample/gtk-demo/editable_cells.rb +169 -130
- data/sample/gtk-demo/entry_buffer.rb +15 -13
- data/sample/gtk-demo/entry_completion.rb +22 -17
- data/sample/gtk-demo/expander.rb +39 -31
- data/sample/gtk-demo/filtermodel.rb +67 -63
- data/sample/gtk-demo/font_features.rb +91 -60
- data/sample/gtk-demo/glarea.rb +277 -0
- data/sample/gtk-demo/headerbar.rb +17 -15
- data/sample/gtk-demo/hypertext.rb +146 -167
- data/sample/gtk-demo/iconview.rb +132 -91
- data/sample/gtk-demo/iconview_edit.rb +49 -38
- data/sample/gtk-demo/infobar.rb +81 -62
- data/sample/gtk-demo/links.rb +35 -30
- data/sample/gtk-demo/list_store.rb +169 -114
- data/sample/gtk-demo/listbox.rb +183 -0
- data/sample/gtk-demo/main.rb +32 -21
- data/sample/gtk-demo/markup.rb +65 -52
- data/sample/gtk-demo/menus.rb +57 -58
- data/sample/gtk-demo/modelbutton.rb +11 -9
- data/sample/gtk-demo/modelbutton.ui +3 -0
- data/sample/gtk-demo/overlay.rb +39 -32
- data/sample/gtk-demo/overlay2.rb +68 -54
- data/sample/gtk-demo/panes.rb +56 -68
- data/sample/gtk-demo/pickers.rb +46 -45
- data/sample/gtk-demo/pixbufs.rb +27 -25
- data/sample/gtk-demo/popover.rb +70 -63
- data/sample/gtk-demo/printing.rb +94 -69
- data/sample/gtk-demo/revealer.rb +46 -38
- data/sample/gtk-demo/rotated_text.rb +75 -54
- data/sample/gtk-demo/scale.rb +10 -8
- data/sample/gtk-demo/search_entry.rb +195 -0
- data/sample/gtk-demo/search_entry2.rb +71 -59
- data/sample/gtk-demo/sidebar.rb +20 -19
- data/sample/gtk-demo/sizegroup.rb +36 -35
- data/sample/gtk-demo/spinbutton.rb +128 -0
- data/sample/gtk-demo/spinner.rb +55 -40
- data/sample/gtk-demo/stack.rb +11 -8
- data/sample/gtk-demo/textmask.rb +14 -13
- data/sample/gtk-demo/textscroll.rb +16 -12
- data/sample/gtk-demo/theming_style_classes.rb +14 -12
- data/sample/gtk-demo/transparent.rb +17 -13
- data/sample/misc/treemodelfilter.rb +1 -1
- metadata +21 -16
@@ -1,205 +1,172 @@
|
|
1
|
-
# Copyright (c)
|
1
|
+
# Copyright (c) 2016 Ruby-GNOME2 Project Team
|
2
2
|
# This program is licenced under the same licence as Ruby-GNOME2.
|
3
3
|
#
|
4
|
-
# $Id: drawingarea.rb,v 1.5 2005/02/12 23:02:43 kzys Exp $
|
5
4
|
=begin
|
6
|
-
=
|
5
|
+
= Drawing Area
|
7
6
|
|
8
|
-
|
9
|
-
of various kinds.
|
7
|
+
GtkDrawingArea is a blank area where you can draw custom displays
|
8
|
+
of various kinds.
|
10
9
|
|
11
|
-
This demo has two drawing areas. The checkerboard area shows
|
12
|
-
how you can just draw something; all you have to do is write
|
13
|
-
a signal handler for expose_event, as shown here.
|
10
|
+
This demo has two drawing areas. The checkerboard area shows
|
11
|
+
how you can just draw something; all you have to do is write
|
12
|
+
a signal handler for expose_event, as shown here.
|
14
13
|
|
15
|
-
The
|
16
|
-
events such as button presses and mouse motion. Click the mouse
|
17
|
-
and drag in the scribble area to draw squiggles. Resize the window
|
18
|
-
to clear the area.
|
14
|
+
The "scribble" area is a bit more advanced, and shows how to handle
|
15
|
+
events such as button presses and mouse motion. Click the mouse
|
16
|
+
and drag in the scribble area to draw squiggles. Resize the window
|
17
|
+
to clear the area.
|
19
18
|
=end
|
19
|
+
class DrawingareaDemo
|
20
|
+
def initialize(main_window)
|
21
|
+
@window = Gtk::Window.new(:toplevel)
|
22
|
+
@window.screen = main_window.screen
|
23
|
+
@window.title = "Drawing Area"
|
24
|
+
@window.border_width = 8
|
25
|
+
|
26
|
+
initialize_vbox
|
27
|
+
create_the_checkerboard_area
|
28
|
+
create_the_scribble_area
|
29
|
+
end
|
20
30
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
self.border_width = 8
|
31
|
+
def run
|
32
|
+
if !@window.visible?
|
33
|
+
@window.show_all
|
34
|
+
else
|
35
|
+
@window.destroy
|
36
|
+
end
|
37
|
+
@window
|
38
|
+
end
|
31
39
|
|
32
|
-
|
33
|
-
vbox.border_width = 8
|
34
|
-
add(vbox)
|
40
|
+
private
|
35
41
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
42
|
+
def initialize_vbox
|
43
|
+
@vbox = Gtk::Box.new(:vertical, 8)
|
44
|
+
@vbox.border_width = 8
|
45
|
+
@window.add(@vbox)
|
46
|
+
end
|
40
47
|
|
41
|
-
|
42
|
-
|
43
|
-
|
48
|
+
def create_da_in_frame(text)
|
49
|
+
label = Gtk::Label.new
|
50
|
+
label.set_markup(text, :use_underline => true)
|
51
|
+
@vbox.pack_start(label, :expand => false, :fill => false, :padding => 0)
|
44
52
|
|
45
|
-
|
46
|
-
|
47
|
-
|
53
|
+
frame = Gtk::Frame.new
|
54
|
+
frame.shadow_type = :in
|
55
|
+
@vbox.pack_start(frame, :expand => true, :fill => true, :padding => 0)
|
48
56
|
|
49
|
-
|
57
|
+
da = Gtk::DrawingArea.new
|
58
|
+
da.set_size_request(100, 100)
|
59
|
+
frame.add(da)
|
60
|
+
da
|
61
|
+
end
|
50
62
|
|
51
|
-
|
52
|
-
|
63
|
+
def checkerboard_draw(da, cr)
|
64
|
+
check_size = 10
|
65
|
+
spacing = 2
|
66
|
+
# At the start of a draw handler, a clip region has been set on
|
67
|
+
# the Cairo context, and the contents have been cleared to the
|
68
|
+
# widget's background color. The docs for
|
69
|
+
# gdk_window_begin_paint_region() give more details on how this
|
70
|
+
# works.
|
71
|
+
ycount = 0
|
72
|
+
xcount = 0
|
73
|
+
i = spacing
|
74
|
+
while i < da.allocated_width
|
75
|
+
j = spacing
|
76
|
+
ycount = xcount % 2 # start with even/odd depending on row
|
77
|
+
while j < da.allocated_height
|
78
|
+
if ycount % 2
|
79
|
+
cr.set_source_rgb(0.45777, 0, 0.45777)
|
80
|
+
else
|
81
|
+
cr.set_source_rgb(1, 1, 1)
|
82
|
+
end
|
83
|
+
# if we are outside the clip, this will do nothing
|
84
|
+
cr.rectangle(i, j, check_size, check_size)
|
85
|
+
cr.fill
|
86
|
+
j += check_size + spacing
|
87
|
+
++ycount
|
53
88
|
end
|
89
|
+
i += check_size + spacing
|
90
|
+
++xcount
|
91
|
+
end
|
92
|
+
end
|
54
93
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
frame.shadow_type = :in
|
62
|
-
vbox.pack_start(frame, :expand => true, :fill => true, :padding => 0)
|
94
|
+
def create_the_checkerboard_area
|
95
|
+
da = create_da_in_frame("<u>Checkerboard pattern</u>")
|
96
|
+
da.signal_connect "draw" do |widget, cr|
|
97
|
+
checkerboard_draw(widget, cr)
|
98
|
+
end
|
99
|
+
end
|
63
100
|
|
64
|
-
|
65
|
-
|
66
|
-
|
101
|
+
def scribble_configure_event(da)
|
102
|
+
@surface.destroy if @surface
|
103
|
+
|
104
|
+
@surface = da.window.create_similar_surface(Cairo::CONTENT_COLOR,
|
105
|
+
da.allocated_width,
|
106
|
+
da.allocated_height)
|
107
|
+
# initialize the surface to white
|
108
|
+
cr = Cairo::Context.new(@surface)
|
109
|
+
cr.set_source_rgb(1, 1, 1)
|
110
|
+
cr.paint
|
111
|
+
cr.destroy
|
112
|
+
# we have handled the configure event, no need to further processing
|
113
|
+
true
|
114
|
+
end
|
67
115
|
|
68
|
-
|
116
|
+
def scribble_draw(cr)
|
117
|
+
# Redraw the screen from the surface
|
118
|
+
cr.set_source(@surface, 0, 0)
|
119
|
+
cr.paint
|
120
|
+
false
|
121
|
+
end
|
69
122
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
123
|
+
def draw_brush(widget, x, y)
|
124
|
+
cr = Cairo::Context.new(@surface)
|
125
|
+
cr.rectangle(x - 3, y - 3, 6, 6)
|
126
|
+
cr.fill
|
127
|
+
cr.destroy
|
128
|
+
widget.queue_draw_area(x - 3, y - 3, 6, 6)
|
129
|
+
end
|
77
130
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
scribble_button_press_event(*args)
|
84
|
-
end
|
131
|
+
def scribble_button_press_event(da, event)
|
132
|
+
return false unless @surface
|
133
|
+
draw_brush(da, event.x, event.y) if event.button == Gdk::BUTTON_PRIMARY
|
134
|
+
true
|
135
|
+
end
|
85
136
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
Gdk::Event::POINTER_MOTION_HINT_MASK)
|
137
|
+
def scribble_motion_notify_event(da, event)
|
138
|
+
return false unless @surface
|
139
|
+
_window, x, y, state = event.window.get_device_position(event.device)
|
140
|
+
if (state & Gdk::EventMask::BUTTON_PRESS_MASK.to_i).nonzero?
|
141
|
+
draw_brush(da, x, y)
|
92
142
|
end
|
143
|
+
true
|
144
|
+
end
|
93
145
|
|
94
|
-
|
95
|
-
|
96
|
-
allocation = widget.allocation
|
97
|
-
surface = widget.window.create_similar_surface(:color,
|
98
|
-
allocation.width,
|
99
|
-
allocation.height)
|
100
|
-
@cairo_context = Cairo::Context.new(surface)
|
101
|
-
@cairo_context.set_source_rgb(1, 1, 1)
|
102
|
-
@cairo_context.paint
|
103
|
-
|
104
|
-
# We've handled the configure event, no need for further processing.
|
105
|
-
return true
|
106
|
-
end
|
146
|
+
def create_the_scribble_area
|
147
|
+
da = create_da_in_frame("<u>Scribble area</u>")
|
107
148
|
|
108
|
-
|
109
|
-
|
110
|
-
def checkerboard_draw(da, cairo_context)
|
111
|
-
# At the start of a draw handler, a clip region of event.area
|
112
|
-
# is set on the window, and event.area has been cleared to the
|
113
|
-
# widget's background color. The docs for
|
114
|
-
# gdk_window_begin_paint_region give more details on how this
|
115
|
-
# works.
|
116
|
-
|
117
|
-
xcount = 0
|
118
|
-
width = da.allocated_width
|
119
|
-
height = da.allocated_height
|
120
|
-
SPACING.step(da.allocation.width, CHECK_SIZE + SPACING) do |i|
|
121
|
-
ycount = xcount % 2; # start with even/odd depending on row
|
122
|
-
SPACING.step(da.allocation.height, CHECK_SIZE + SPACING) do |j|
|
123
|
-
if ycount % 2 == 1
|
124
|
-
cairo_context.set_source_rgb(0.45777, 0, 0.45777)
|
125
|
-
else
|
126
|
-
cairo_context.set_source_rgb(1, 1, 1)
|
127
|
-
end
|
128
|
-
|
129
|
-
# If we're outside the clip, this will do nothing.
|
130
|
-
cairo_context.fill do
|
131
|
-
cairo_context.rectangle(i, j, CHECK_SIZE, CHECK_SIZE)
|
132
|
-
end
|
133
|
-
ycount += 1
|
134
|
-
end
|
135
|
-
xcount += 1
|
136
|
-
end
|
137
|
-
# return true because we've handled this event, so no
|
138
|
-
# further processing is required.
|
139
|
-
#
|
140
|
-
return true
|
149
|
+
da.signal_connect "draw" do |_widget, cr|
|
150
|
+
scribble_draw(cr)
|
141
151
|
end
|
142
152
|
|
143
|
-
|
144
|
-
|
145
|
-
event.set_source(@cairo_context.target)
|
146
|
-
event.paint
|
147
|
-
return false
|
153
|
+
da.signal_connect "configure-event" do |widget|
|
154
|
+
scribble_configure_event(widget)
|
148
155
|
end
|
149
156
|
|
150
|
-
|
151
|
-
|
152
|
-
update_rect = Gdk::Rectangle.new(x - 3, y - 3, 6, 6)
|
153
|
-
|
154
|
-
# Paint to the surface, where we store our state
|
155
|
-
@cairo_context.fill do
|
156
|
-
@cairo_context.set_source_rgb(0, 0, 0)
|
157
|
-
@cairo_context.rectangle(update_rect.x,
|
158
|
-
update_rect.y,
|
159
|
-
update_rect.width,
|
160
|
-
update_rect.height)
|
161
|
-
end
|
162
|
-
|
163
|
-
# Now invalidate the affected region of the drawing area.
|
164
|
-
widget.window.invalidate(update_rect, false)
|
157
|
+
da.signal_connect "motion-notify-event" do |widget, event|
|
158
|
+
scribble_motion_notify_event(widget, event)
|
165
159
|
end
|
166
160
|
|
167
|
-
|
168
|
-
|
169
|
-
return false unless @cairo_context
|
170
|
-
|
171
|
-
if event.button == 1
|
172
|
-
draw_brush(widget, event.x, event.y)
|
173
|
-
end
|
174
|
-
|
175
|
-
# We've handled the event, stop processing
|
176
|
-
return true
|
161
|
+
da.signal_connect "button-press-event" do |widget, event|
|
162
|
+
scribble_button_press_event(widget, event)
|
177
163
|
end
|
178
164
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
# a single motion event. The reason is that we specified
|
186
|
-
# Gdk::POINTER_MOTION_HINT_MASK to Gtk::Widget#set_events.
|
187
|
-
# If we hadn't specified that, we could just use event.x, event.y
|
188
|
-
# as the pointer location. But we'd also get deluged in events.
|
189
|
-
# By requesting the next event as we handle the current one,
|
190
|
-
# we avoid getting a huge number of events faster than we
|
191
|
-
# can cope.
|
192
|
-
|
193
|
-
# NOTE: Gdk::EventMotion#window will be restored from Ruby/GDK3 2.1.1.
|
194
|
-
# win, x, y, state = event.window.get_device_position(event.device)
|
195
|
-
win, x, y, state = widget.window.get_device_position(event.device)
|
196
|
-
|
197
|
-
if (state & :button1_mask) != 0
|
198
|
-
draw_brush(widget, x, y)
|
199
|
-
end
|
200
|
-
|
201
|
-
# We've handled it, stop processing
|
202
|
-
return true
|
203
|
-
end
|
165
|
+
# da.events |= (Gdk::EventMask::LEAVE_NOTIFY_MASK |
|
166
|
+
# Gdk::EventMask::BUTTON_PRESS_MASK |
|
167
|
+
# Gdk::EventMask::POINTER_MOTION_MASK |
|
168
|
+
# Gdk::EventMask::POINTER_MOTION_HINT_MASK)
|
169
|
+
da.add_events([:leave_notify_mask, :button_press_mask,
|
170
|
+
:pointer_motion_mask, :pointer_motion_hint_mask])
|
204
171
|
end
|
205
172
|
end
|
@@ -1,173 +1,212 @@
|
|
1
|
-
# Copyright (c)
|
1
|
+
# Copyright (c) 2016 Ruby-GNOME2 Project Team
|
2
2
|
# This program is licenced under the same licence as Ruby-GNOME2.
|
3
3
|
#
|
4
|
-
# $Id: editable_cells.rb,v 1.7 2005/02/06 18:25:13 kzys Exp $
|
5
4
|
=begin
|
6
|
-
=
|
5
|
+
= Tree View/Editable Cells
|
7
6
|
|
8
|
-
This demo demonstrates the use of editable cells in a
|
9
|
-
you're new to the
|
10
|
-
the
|
11
|
-
|
12
|
-
|
7
|
+
This demo demonstrates the use of editable cells in a GtkTreeView. If
|
8
|
+
you're new to the GtkTreeView widgets and associates, look into
|
9
|
+
the GtkListStore example first. It also shows how to use the
|
10
|
+
GtkCellRenderer::editing-started signal to do custom setup of the
|
11
|
+
editable widget.
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
The cell renderers used in this demo are GtkCellRendererText,
|
14
|
+
GtkCellRendererCombo and GtkCellRendererProgress.
|
15
|
+
=end
|
16
|
+
class EditableCellsDemo
|
17
|
+
Item = Struct.new("Item", :number, :product, :yummy)
|
18
|
+
COL_ITEM_NUM, COL_ITEM_PROD, COL_ITEM_YUMMY = *(0..3).to_a
|
19
|
+
COL_NUM_TEXT = 0
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
def initialize(main_window)
|
22
|
+
@window = Gtk::Window.new(:toplevel)
|
23
|
+
@window.screen = main_window.screen
|
24
|
+
@window.title = "Editable Cells"
|
25
|
+
@window.border_width = 5
|
22
26
|
|
23
|
-
|
24
|
-
|
27
|
+
vbox = Gtk::Box.new(:vertical, 5)
|
28
|
+
@window.add(vbox)
|
29
|
+
label = Gtk::Label.new("Shopping list (you can edit the cells)")
|
30
|
+
vbox.pack_start(label, :expand => false, :fill => true, :padding => 0)
|
25
31
|
|
26
|
-
|
27
|
-
|
32
|
+
sw = Gtk::ScrolledWindow.new
|
33
|
+
sw.shadow_type = :etched_in
|
34
|
+
sw.set_policy(:automatic, :automatic)
|
35
|
+
vbox.pack_start(sw, :expand => true, :fill => true, :padding => 0)
|
28
36
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
vbox.pack_start(sw, :expand => true, :fill => true, :padding => 0)
|
37
|
+
# create models
|
38
|
+
create_items_model
|
39
|
+
create_numbers_model
|
33
40
|
|
34
|
-
|
35
|
-
|
41
|
+
# create tree view
|
42
|
+
@treeview = Gtk::TreeView.new(@items_model)
|
43
|
+
@treeview.selection.mode = :single
|
36
44
|
|
37
|
-
|
38
|
-
treeview = Gtk::TreeView.new(model)
|
39
|
-
treeview.rules_hint = true
|
40
|
-
treeview.selection.mode = Gtk::SELECTION_SINGLE
|
45
|
+
add_columns
|
41
46
|
|
42
|
-
|
47
|
+
sw.add(@treeview)
|
43
48
|
|
44
|
-
|
49
|
+
# Some buttons
|
50
|
+
hbox = Gtk::Box.new(:horizontal, 4)
|
51
|
+
hbox.homogeneous = true
|
52
|
+
vbox.pack_start(hbox, :expand => false, :fill => false, :padding => 0)
|
45
53
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
vbox.pack_start(hbox, :expand => false, :fill => false, :padding => 0)
|
54
|
+
button = Gtk::Button.new(:label => "Add item")
|
55
|
+
button.signal_connect("clicked") { add_item }
|
56
|
+
hbox.pack_start(button, :expand => true, :fill => true, :padding => 0)
|
50
57
|
|
51
|
-
|
52
|
-
|
53
|
-
add_item(model)
|
54
|
-
end
|
55
|
-
hbox.pack_start(button, :expand => true, :fill => true, :padding => 0)
|
58
|
+
button = Gtk::Button.new(:label => "Remove item")
|
59
|
+
button.signal_connect("clicked") { remove_item }
|
56
60
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
hbox.pack_start(button, :expand => true, :fill => true, :padding => 0)
|
61
|
+
hbox.pack_start(button, :expand => true, :fill => true, :padding => 0)
|
62
|
+
@window.set_default_size(320, 200)
|
63
|
+
end
|
62
64
|
|
63
|
-
|
65
|
+
def run
|
66
|
+
if !@window.visible?
|
67
|
+
@window.show_all
|
68
|
+
else
|
69
|
+
@window.destroy
|
64
70
|
end
|
71
|
+
@window
|
72
|
+
end
|
65
73
|
|
66
|
-
|
67
|
-
|
68
|
-
|
74
|
+
private
|
75
|
+
|
76
|
+
def add_item
|
77
|
+
return if @items.nil?
|
78
|
+
item = Item.new(0, "Description here", 50)
|
79
|
+
@items << item
|
80
|
+
|
81
|
+
# Insert a row below the current one
|
82
|
+
path = @treeview.cursor[0]
|
83
|
+
iter = if path
|
84
|
+
current = @items_model.get_iter(path)
|
85
|
+
@items_model.insert_after(current)
|
86
|
+
else
|
87
|
+
@items_model.insert(-1)
|
88
|
+
end
|
89
|
+
|
90
|
+
# set the data for the new row
|
91
|
+
item.each_with_index do |value, index|
|
92
|
+
iter[index] = value
|
93
|
+
end
|
69
94
|
|
70
|
-
|
95
|
+
# Move focus to the new row
|
96
|
+
path = @items_model.get_path(iter)
|
97
|
+
column = @treeview.get_column(0)
|
98
|
+
@treeview.set_cursor(path, column, false)
|
99
|
+
end
|
71
100
|
|
72
|
-
|
73
|
-
|
101
|
+
def remove_item
|
102
|
+
selection = @treeview.selection
|
103
|
+
iter = selection.selected
|
104
|
+
if iter
|
105
|
+
path = @items_model.get_path(iter)
|
106
|
+
i = path.indices[0]
|
107
|
+
@items_model.remove(iter)
|
108
|
+
@items.delete_at(i)
|
109
|
+
end
|
110
|
+
end
|
74
111
|
|
75
|
-
|
76
|
-
|
77
|
-
|
112
|
+
def add_items
|
113
|
+
@items << Item.new(3, "bottles of coke", 20)
|
114
|
+
@items << Item.new(5, "packages of noodles", 50)
|
115
|
+
@items << Item.new(2, "packages of chocolate chip cookies", 90)
|
116
|
+
@items << Item.new(1, "can vanilla ice cream", 60)
|
117
|
+
@items << Item.new(6, "eggs", 10)
|
118
|
+
end
|
78
119
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
120
|
+
def create_items_model
|
121
|
+
@items = []
|
122
|
+
add_items
|
123
|
+
|
124
|
+
# Create list store
|
125
|
+
@items_model = Gtk::ListStore.new(Integer, String, Integer, TrueClass)
|
126
|
+
@items.each do |item|
|
127
|
+
iter = @items_model.append
|
128
|
+
iter[COL_ITEM_NUM] = item.number
|
129
|
+
iter[COL_ITEM_PROD] = item.product
|
130
|
+
iter[COL_ITEM_YUMMY] = item.yummy
|
84
131
|
end
|
132
|
+
end
|
85
133
|
|
86
|
-
|
87
|
-
|
88
|
-
|
134
|
+
def create_numbers_model
|
135
|
+
@numbers_model = Gtk::ListStore.new(String, Integer)
|
136
|
+
(1..10).each do |n|
|
137
|
+
iter = @numbers_model.append
|
138
|
+
iter[COL_NUM_TEXT] = n.to_s
|
139
|
+
end
|
140
|
+
end
|
89
141
|
|
90
|
-
|
91
|
-
|
142
|
+
def add_columns
|
143
|
+
add_number_column
|
144
|
+
add_product_column
|
145
|
+
add_yummy_column
|
146
|
+
end
|
92
147
|
|
93
|
-
|
94
|
-
|
148
|
+
def add_number_column
|
149
|
+
renderer = Gtk::CellRendererCombo.new
|
150
|
+
renderer.model = @numbers_model
|
151
|
+
renderer.text_column = COL_NUM_TEXT
|
152
|
+
renderer.has_entry = false
|
153
|
+
renderer.editable = true
|
95
154
|
|
96
|
-
|
97
|
-
|
155
|
+
renderer.signal_connect "edited" do |cell, path, new_text|
|
156
|
+
cell_edited(cell, path, new_text)
|
157
|
+
end
|
98
158
|
|
99
|
-
|
100
|
-
|
159
|
+
renderer.signal_connect "editing-started" do |_cell, editable, path|
|
160
|
+
editable.set_row_separator_func do |model, iter|
|
161
|
+
path = model.get_path(iter)
|
162
|
+
idx = path.indices[0]
|
163
|
+
idx == 5
|
164
|
+
end
|
101
165
|
end
|
102
166
|
|
103
|
-
def
|
104
|
-
|
167
|
+
def renderer.column
|
168
|
+
COL_ITEM_NUM
|
169
|
+
end
|
105
170
|
|
106
|
-
|
107
|
-
|
108
|
-
renderer.signal_connect('edited') do |*args|
|
109
|
-
cell_edited(*args.push(model))
|
110
|
-
end
|
111
|
-
treeview.insert_column(-1, 'Number', renderer,
|
112
|
-
{
|
113
|
-
:text => COLUMN_NUMBER,
|
114
|
-
:editable => COLUMN_EDITABLE,
|
115
|
-
})
|
116
|
-
def renderer.column
|
117
|
-
COLUMN_NUMBER
|
118
|
-
end
|
171
|
+
@treeview.insert_column(-1, "Number", renderer, :text => COL_ITEM_NUM)
|
172
|
+
end
|
119
173
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
def renderer.column
|
126
|
-
COLUMN_PRODUCT
|
127
|
-
end
|
128
|
-
treeview.insert_column(-1, 'Product', renderer,
|
129
|
-
{
|
130
|
-
:text => COLUMN_PRODUCT,
|
131
|
-
:editable => COLUMN_EDITABLE,
|
132
|
-
})
|
174
|
+
def add_product_column
|
175
|
+
renderer = Gtk::CellRendererText.new
|
176
|
+
renderer.editable = true
|
177
|
+
renderer.signal_connect "edited" do |cell, path, new_text|
|
178
|
+
cell_edited(cell, path, new_text)
|
133
179
|
end
|
134
180
|
|
135
|
-
def
|
136
|
-
|
137
|
-
|
138
|
-
column = cell.column
|
139
|
-
|
140
|
-
iter = model.get_iter(path)
|
141
|
-
case column
|
142
|
-
when COLUMN_NUMBER
|
143
|
-
i = iter.path.indices[0]
|
144
|
-
@articles[i].number = new_text.to_i
|
145
|
-
iter.set_value(column, @articles[i].number)
|
146
|
-
when COLUMN_PRODUCT
|
147
|
-
i = iter.path.indices[0]
|
148
|
-
@articles[i].product = new_text
|
149
|
-
iter.set_value(column, @articles[i].product)
|
150
|
-
end
|
181
|
+
def renderer.column
|
182
|
+
COL_ITEM_PROD
|
151
183
|
end
|
152
184
|
|
153
|
-
|
154
|
-
|
155
|
-
@articles.concat([foo])
|
185
|
+
@treeview.insert_column(-1, "Product", renderer, :text => COL_ITEM_PROD)
|
186
|
+
end
|
156
187
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
188
|
+
def add_yummy_column
|
189
|
+
renderer = Gtk::CellRendererProgress.new
|
190
|
+
def renderer.column
|
191
|
+
COL_ITEM_YUMMY
|
161
192
|
end
|
193
|
+
@treeview.insert_column(-1, "Yummy", renderer, :value => COL_ITEM_YUMMY)
|
194
|
+
end
|
162
195
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
196
|
+
def cell_edited(cell, path_string, new_text)
|
197
|
+
path = Gtk::TreePath.new(path_string)
|
198
|
+
column = cell.column
|
199
|
+
iter = @items_model.get_iter(path)
|
200
|
+
|
201
|
+
case column
|
202
|
+
when COL_ITEM_NUM
|
203
|
+
i = path.indices[0]
|
204
|
+
@items[i].number = new_text.to_i
|
205
|
+
iter.set_value(column, @items[i].number)
|
206
|
+
when COL_ITEM_PROD
|
207
|
+
i = path.indices[0]
|
208
|
+
@items[i].product = new_text
|
209
|
+
iter.set_value(column, @items[i].product)
|
171
210
|
end
|
172
211
|
end
|
173
212
|
end
|