gtk3 3.0.9-x86-mingw32 → 3.1.0-x86-mingw32

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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/ext/gtk3/rb-gtk3-private.h +1 -0
  3. data/ext/gtk3/rb-gtk3-spin-button.c +85 -0
  4. data/ext/gtk3/rb-gtk3.c +3 -0
  5. data/lib/2.2/gtk3.so +0 -0
  6. data/lib/2.3/gtk3.so +0 -0
  7. data/lib/gtk3/deprecated.rb +0 -8
  8. data/lib/gtk3/loader.rb +1 -7
  9. data/lib/gtk3/tree-model.rb +2 -0
  10. data/sample/gtk-demo/TODO +10 -10
  11. data/sample/gtk-demo/assistant.rb +44 -39
  12. data/sample/gtk-demo/builder.rb +71 -50
  13. data/sample/gtk-demo/button_box.rb +39 -28
  14. data/sample/gtk-demo/clipboard.rb +139 -46
  15. data/sample/gtk-demo/colorsel.rb +50 -36
  16. data/sample/gtk-demo/css_accordion.rb +18 -17
  17. data/sample/gtk-demo/css_basics.rb +60 -47
  18. data/sample/gtk-demo/css_multiplebgs.rb +92 -71
  19. data/sample/gtk-demo/css_pixbufs.rb +61 -48
  20. data/sample/gtk-demo/css_shadows.rb +63 -50
  21. data/sample/gtk-demo/cursors.rb +95 -64
  22. data/sample/gtk-demo/dialog.rb +95 -78
  23. data/sample/gtk-demo/drawingarea.rb +138 -171
  24. data/sample/gtk-demo/editable_cells.rb +169 -130
  25. data/sample/gtk-demo/entry_buffer.rb +15 -13
  26. data/sample/gtk-demo/entry_completion.rb +22 -17
  27. data/sample/gtk-demo/expander.rb +39 -31
  28. data/sample/gtk-demo/filtermodel.rb +67 -63
  29. data/sample/gtk-demo/font_features.rb +91 -60
  30. data/sample/gtk-demo/glarea.rb +277 -0
  31. data/sample/gtk-demo/headerbar.rb +17 -15
  32. data/sample/gtk-demo/hypertext.rb +146 -167
  33. data/sample/gtk-demo/iconview.rb +132 -91
  34. data/sample/gtk-demo/iconview_edit.rb +49 -38
  35. data/sample/gtk-demo/infobar.rb +81 -62
  36. data/sample/gtk-demo/links.rb +35 -30
  37. data/sample/gtk-demo/list_store.rb +169 -114
  38. data/sample/gtk-demo/listbox.rb +183 -0
  39. data/sample/gtk-demo/main.rb +32 -21
  40. data/sample/gtk-demo/markup.rb +65 -52
  41. data/sample/gtk-demo/menus.rb +57 -58
  42. data/sample/gtk-demo/modelbutton.rb +11 -9
  43. data/sample/gtk-demo/modelbutton.ui +3 -0
  44. data/sample/gtk-demo/overlay.rb +39 -32
  45. data/sample/gtk-demo/overlay2.rb +68 -54
  46. data/sample/gtk-demo/panes.rb +56 -68
  47. data/sample/gtk-demo/pickers.rb +46 -45
  48. data/sample/gtk-demo/pixbufs.rb +27 -25
  49. data/sample/gtk-demo/popover.rb +70 -63
  50. data/sample/gtk-demo/printing.rb +94 -69
  51. data/sample/gtk-demo/revealer.rb +46 -38
  52. data/sample/gtk-demo/rotated_text.rb +75 -54
  53. data/sample/gtk-demo/scale.rb +10 -8
  54. data/sample/gtk-demo/search_entry.rb +195 -0
  55. data/sample/gtk-demo/search_entry2.rb +71 -59
  56. data/sample/gtk-demo/sidebar.rb +20 -19
  57. data/sample/gtk-demo/sizegroup.rb +36 -35
  58. data/sample/gtk-demo/spinbutton.rb +128 -0
  59. data/sample/gtk-demo/spinner.rb +55 -40
  60. data/sample/gtk-demo/stack.rb +11 -8
  61. data/sample/gtk-demo/textmask.rb +14 -13
  62. data/sample/gtk-demo/textscroll.rb +16 -12
  63. data/sample/gtk-demo/theming_style_classes.rb +14 -12
  64. data/sample/gtk-demo/transparent.rb +17 -13
  65. data/sample/misc/treemodelfilter.rb +1 -1
  66. metadata +24 -19
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2015 Ruby-GNOME2 Project Team
1
+ # Copyright (c) 2015-2016 Ruby-GNOME2 Project Team
2
2
  # This program is licenced under the same licence as Ruby-GNOME2.
3
3
  #
4
4
  =begin
@@ -8,12 +8,12 @@ GtkLabel can show hyperlinks. The default action is to call
8
8
  gtk_show_uri() on their URI, but it is possible to override
9
9
  this with a custom handler.
10
10
  =end
11
- module LinksDemo
12
- def self.run_demo(main_window)
13
- window = Gtk::Window.new(:toplevel)
14
- window.screen = main_window.screen
15
- window.set_title("Links")
16
- window.set_border_width(12)
11
+ class LinksDemo
12
+ def initialize(main_window)
13
+ @window = Gtk::Window.new(:toplevel)
14
+ @window.screen = main_window.screen
15
+ @window.title = "Links"
16
+ @window.border_width = 12
17
17
 
18
18
  label = Gtk::Label.new(<<-MESSAGE)
19
19
  Some <a href="http://en.wikipedia.org/wiki/Text"
@@ -27,40 +27,45 @@ searching on <a href="http://www.google.com/">
27
27
  <span color="#00933B">l</span><span color="#F90101">e</span>
28
28
  </a>.
29
29
  MESSAGE
30
- label.set_use_markup(true)
30
+ label.use_markup = true
31
31
 
32
- label.signal_connect "activate-link" do |_widget, uri|
32
+ label.signal_connect "activate-link" do |widget, uri|
33
33
  if uri == "keynav"
34
- parent = label.toplevel
35
- dialog = Gtk::MessageDialog.new(:parent => parent,
36
- :flags => :destroy_with_parent,
37
- :type => :info,
38
- :buttons => :ok,
39
- :message => <<-MESSAGE)
40
- The term <i>keynav</i> is a shorthand for
41
- keyboard navigation and refers to the process of using
42
- a program (exclusively) via keyboard input.
43
- MESSAGE
44
- dialog.set_use_markup(true)
45
- dialog.set_modal(true)
46
- dialog.present
47
- dialog.signal_connect "response" do
48
- dialog.destroy
49
- end
34
+ generate_dialog(widget)
50
35
  true
51
36
  else
52
37
  false
53
38
  end
54
39
  end
55
40
 
56
- window.add(label)
41
+ @window.add(label)
57
42
  label.show
43
+ end
58
44
 
59
- if !window.visible?
60
- window.show_all
45
+ def run
46
+ if !@window.visible?
47
+ @window.show_all
61
48
  else
62
- window.destroy
49
+ @window.destroy
63
50
  end
64
- window
51
+ @window
52
+ end
53
+
54
+ private
55
+
56
+ def generate_dialog(widget)
57
+ dialog = Gtk::MessageDialog.new(:parent => widget.toplevel,
58
+ :flags => :destroy_with_parent,
59
+ :type => :info,
60
+ :buttons => :ok,
61
+ :message => <<-MESSAGE)
62
+ The term <i>keynav</i> is a shorthand for
63
+ keyboard navigation and refers to the process of using
64
+ a program (exclusively) via keyboard input.
65
+ MESSAGE
66
+ dialog.use_markup = true
67
+ dialog.modal = true
68
+ dialog.present
69
+ dialog.signal_connect("response", &:destroy)
65
70
  end
66
71
  end
@@ -1,138 +1,193 @@
1
- # Copyright (c) 2003-2005 Ruby-GNOME2 Project Team
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: list_store.rb,v 1.5 2005/02/06 18:25:13 kzys Exp $
5
4
  =begin
6
- = Tree View/List Store
5
+ = Tree View/List Store
7
6
 
8
- The Gtk::ListStore is used to store data in list form, to be used
9
- later on by a Gtk::TreeView to display it. This demo builds a
10
- simple Gtk::ListStore and displays it. See the Stock Browser
11
- demo for a more advanced example.
12
- =end
13
- require 'common'
14
-
15
- module Demo
16
- class ListStore < BasicWindow
17
- Bug = Struct.new('Bug', :fixed, :number, :severity, :description)
18
- COLUMN_FIXED, COLUMN_NUMBER, COLUMN_SEVERITY, COLUMN_DESCRIPTION,
19
- NUM_COLUMNS = *(0..5).to_a
20
- DATA = [
21
- [ false, 60482, 'Normal', 'scrollable notebooks and hidden tabs' ],
22
- [ false, 60620, 'Critical', 'gdk_window_clear_area (gdkwindow-win32.c) is not thread-safe' ],
23
- [ false, 50214, 'Major', 'Xft support does not clean up correctly' ],
24
- [ true, 52877, 'Major', 'GtkFileSelection needs a refresh method. ' ],
25
- [ false, 56070, 'Normal', "Can't click button after setting in sensitive" ],
26
- [ true, 56355, 'Normal', 'GtkLabel - Not all changes propagate correctly' ],
27
- [ false, 50055, 'Normal', 'Rework width/height computations for TreeView' ],
28
- [ false, 58278, 'Normal', "gtk_dialog_set_response_sensitive doesn't work" ],
29
- [ false, 55767, 'Normal', 'Getters for all setters' ],
30
- [ false, 56925, 'Normal', 'Gtkcalender size' ],
31
- [ false, 56221, 'Normal', 'Selectable label needs right-click copy menu' ],
32
- [ true, 50939, 'Normal', 'Add shift clicking to GtkTextView' ],
33
- [ false, 6112, 'Enhancement','netscape-like collapsable toolbars' ],
34
- [ false, 1, 'Normal', 'First bug :=)' ],
35
- ].collect do |ary|
36
- Bug.new(*ary)
37
- end
38
- def initialize
39
- super('GtkListStore demo')
40
- self.border_width = 8
7
+ The GtkListStore is used to store data in list form, to be used
8
+ later on by a GtkTreeView to display it. This demo builds a
9
+ simple GtkListStore and displays it.
41
10
 
42
- vbox = Gtk::VBox.new(false, 8)
43
- add(vbox)
11
+ =end
12
+ class ListStoreDemo
13
+ Bug = Struct.new("Bug", :fixed, :number, :severity, :description)
14
+ COLUMN_FIXED, COLUMN_NUMBER, COLUMN_SEVERITY, COLUMN_DESCRIPTION,
15
+ COLUMN_PULSE, COLUMN_ICON, COLUMN_ACTIVE, COLUMN_SENSITIVE, NUM_COLUMNS =
16
+ *(0..8).to_a
17
+ DATA = [
18
+ [false, 60_482, "Normal", "scrollable notebooks and hidden tabs" ],
19
+ [false, 60_620, "Critical", "gdk_window_clear_area (gdkwindow-win32.c) is not thread-safe" ],
20
+ [false, 50_214, "Major", "Xft support does not clean up correctly" ],
21
+ [true, 52_877, "Major", "GtkFileSelection needs a refresh method. " ],
22
+ [false, 56_070, "Normal", "Can't click button after setting in sensitive" ],
23
+ [true, 56_355, "Normal", "GtkLabel - Not all changes propagate correctly" ],
24
+ [false, 50_055, "Normal", "Rework width/height computations for TreeView" ],
25
+ [false, 58_278, "Normal", "gtk_dialog_set_response_sensitive doesn't work" ],
26
+ [false, 55_767, "Normal", "Getters for all setters" ],
27
+ [false, 56_925, "Normal", "Gtkcalender size" ],
28
+ [false, 56_221, "Normal", "Selectable label needs right-click copy menu" ],
29
+ [true, 50_939, "Normal", "Add shift clicking to GtkTextView" ],
30
+ [false, 6_112, "Enhancement","netscape-like collapsable toolbars" ],
31
+ [false, 1, "Normal", "First bug :=)" ],
32
+ ].collect do |ary|
33
+ Bug.new(*ary)
34
+ end
44
35
 
45
- label = Gtk::Label.new('This is the bug list (note: not based on real data, it would be nice to have a nice ODBC interface to bugzilla or so, though).')
46
- vbox.pack_start(label, :expand => false, :fill => false, :padding => 0)
36
+ def initialize(main_window)
37
+ @window = Gtk::Window.new(:toplevel)
38
+ @window.screen = main_window.screen
39
+ @window.title = "List Store"
40
+ @window.border_width = 8
41
+ @timeout = 0
42
+ @window.signal_connect "delete-event" do
43
+ @model = nil
44
+ GLib::Source.remove(@timeout) unless @timeout.zero?
45
+ @timeout = 0
46
+ false
47
+ end
48
+ vbox = Gtk::Box.new(:vertical, 8)
49
+ @window.add(vbox)
50
+
51
+ label = Gtk::Label.new(<<-EOF)
52
+ This is the bug list (note: not based on real data, it would be nice to
53
+ have a nice ODBC interface to bugzilla or so, though).
54
+ EOF
55
+ vbox.pack_start(label, :expand => false, :fill => false, :padding => 0)
56
+ sw = Gtk::ScrolledWindow.new(nil, nil)
57
+ sw.shadow_type = :etched_in
58
+ sw.set_policy(:never, :automatic)
59
+ vbox.pack_start(sw, :expand => true, :fill => true, :padding => 0)
60
+
61
+ # create tree model
62
+ create_model
63
+
64
+ # create tree view
65
+ treeview = Gtk::TreeView.new(@model)
66
+ treeview.search_column = COLUMN_DESCRIPTION
67
+ sw.add(treeview)
68
+
69
+ # add columns to the tree view
70
+ add_columns(treeview)
71
+
72
+ # finish and show
73
+ @window.set_default_size(280, 250)
74
+ end
47
75
 
48
- sw = Gtk::ScrolledWindow.new(nil, nil)
49
- sw.shadow_type = Gtk::SHADOW_ETCHED_IN
50
- sw.set_policy(Gtk::POLICY_NEVER, :automatic)
51
- vbox.pack_start(sw, :expand => true, :fill => true, :padding => 0)
76
+ def run
77
+ if !@window.visible?
78
+ @window.show_all
79
+ add_spinner
52
80
 
53
- # create tree model
54
- model = create_model
81
+ else
82
+ @window.destroy
83
+ GLib::Source.remove(@tiemout) unless @timeout.zero?
84
+ @timeout = 0
85
+ end
86
+ @window
87
+ end
55
88
 
56
- # create tree view
57
- treeview = Gtk::TreeView.new(model)
58
- treeview.rules_hint = true
59
- treeview.search_column = COLUMN_DESCRIPTION
89
+ private
60
90
 
61
- sw.add(treeview)
91
+ def create_model
92
+ # create list store
93
+ @model = Gtk::ListStore.new(TrueClass, Integer, String, String, Integer,
94
+ String, TrueClass, TrueClass)
62
95
 
63
- # add columns to the tree view
64
- add_columns(treeview)
96
+ # add data to the list store
97
+ DATA.each_with_index do |bug, i|
98
+ icon_name = ""
99
+ icon_name = "battery-caution-charging-symbolic" if i == 1 || i == 3
100
+ sensitive = i == 3 ? false : true
65
101
 
66
- set_default_size(280, 250)
102
+ iter = @model.append
103
+ iter.set_values([bug.fixed, bug.number, bug.severity, bug.description,
104
+ 0, icon_name, false, sensitive])
67
105
  end
106
+ end
68
107
 
69
- def create_model
70
- # create list store
71
- store = Gtk::ListStore.new(TrueClass, Integer, String, String)
108
+ def add_columns(treeview)
109
+ # column for fixed toggles
110
+ renderer = Gtk::CellRendererToggle.new
111
+ renderer.signal_connect("toggled") { |_cell, path| fixed_toggled(path) }
112
+ column = Gtk::TreeViewColumn.new("Fixed?",
113
+ renderer,
114
+ "active" => COLUMN_FIXED)
115
+
116
+ # set this column to a fixed sizing (of 50 pixels)
117
+ column.sizing = :fixed
118
+ column.fixed_width = 50
119
+ treeview.append_column(column)
120
+
121
+ # column for bug numbers
122
+ renderer = Gtk::CellRendererText.new
123
+ column = Gtk::TreeViewColumn.new("Bug number",
124
+ renderer,
125
+ "text" => COLUMN_NUMBER)
126
+ column.sort_column_id = COLUMN_NUMBER
127
+ treeview.append_column(column)
128
+
129
+ # column for severities
130
+ renderer = Gtk::CellRendererText.new
131
+ column = Gtk::TreeViewColumn.new("Severity",
132
+ renderer,
133
+ "text" => COLUMN_SEVERITY)
134
+ column.sort_column_id = COLUMN_SEVERITY
135
+ treeview.append_column(column)
136
+
137
+ # column for description
138
+ renderer = Gtk::CellRendererText.new
139
+ column = Gtk::TreeViewColumn.new("Description",
140
+ renderer,
141
+ "text" => COLUMN_DESCRIPTION)
142
+ column.sort_column_id = COLUMN_DESCRIPTION
143
+ treeview.append_column(column)
144
+
145
+ # column for spinner
146
+ renderer = Gtk::CellRendererSpinner.new
147
+ column = Gtk::TreeViewColumn.new("Spinning",
148
+ renderer,
149
+ "pulse" => COLUMN_PULSE,
150
+ "active" => COLUMN_ACTIVE)
151
+ column.sort_column_id = COLUMN_PULSE
152
+ treeview.append_column(column)
153
+
154
+ # column for symbolic icon
155
+ renderer = Gtk::CellRendererPixbuf.new
156
+ column = Gtk::TreeViewColumn.new("Symbolic icon",
157
+ renderer,
158
+ "icon-name" => COLUMN_ICON,
159
+ "sensitive" => COLUMN_SENSITIVE)
160
+ column.sort_column_id = COLUMN_ICON
161
+ treeview.append_column(column)
162
+ end
72
163
 
73
- # add data to the list store
74
- DATA.each do |bug|
75
- iter = store.append
76
- bug.each_with_index do |value, index|
77
- iter[index] = value
78
- end
79
- end
80
- return store
81
- end
164
+ def fixed_toggled(path_str)
165
+ path = Gtk::TreePath.new(path_str)
82
166
 
83
- def add_columns(treeview)
84
- # column for fixed toggles
85
- renderer = Gtk::CellRendererToggle.new
86
- renderer.signal_connect('toggled') do |cell, path|
87
- fixed_toggled(treeview.model, path)
88
- end
167
+ # get toggled iter
168
+ iter = @model.get_iter(path)
169
+ fixed = iter[COLUMN_FIXED]
89
170
 
90
- column = Gtk::TreeViewColumn.new('Fixed?',
91
- renderer,
92
- 'active' => COLUMN_FIXED)
93
-
94
- # set this column to a fixed sizing (of 50 pixels)
95
- column.sizing = Gtk::TreeViewColumn::FIXED
96
- column.fixed_width = 50
97
- treeview.append_column(column)
98
-
99
- # column for bug numbers
100
- renderer = Gtk::CellRendererText.new
101
- column = Gtk::TreeViewColumn.new('Bug number',
102
- renderer,
103
- 'text' => COLUMN_NUMBER)
104
- column.set_sort_column_id(COLUMN_NUMBER)
105
- treeview.append_column(column)
106
-
107
- # column for severities
108
- renderer = Gtk::CellRendererText.new
109
- column = Gtk::TreeViewColumn.new('Severity',
110
- renderer,
111
- 'text' => COLUMN_SEVERITY)
112
- column.set_sort_column_id(COLUMN_SEVERITY)
113
- treeview.append_column(column)
114
-
115
- # column for description
116
- renderer = Gtk::CellRendererText.new
117
- column = Gtk::TreeViewColumn.new('Description',
118
- renderer,
119
- 'text' => COLUMN_DESCRIPTION)
120
- column.set_sort_column_id(COLUMN_DESCRIPTION)
121
- treeview.append_column(column)
122
- end
171
+ # do something with the value
172
+ fixed ^= 1
123
173
 
124
- def fixed_toggled(model, path_str)
125
- path = Gtk::TreePath.new(path_str)
174
+ # set new value
175
+ iter[COLUMN_FIXED] = fixed
176
+ end
126
177
 
127
- # get toggled iter
128
- iter = model.get_iter(path)
129
- fixed =iter[COLUMN_FIXED]
178
+ def add_spinner
179
+ if @timeout.zero?
180
+ @timeout = GLib::Timeout.add(80) do
181
+ GLib::Source.remove(@timeout) unless @model
182
+ iter = @model.iter_first
183
+ pulse = iter[COLUMN_PULSE]
130
184
 
131
- # do something with the value
132
- fixed ^= 1
185
+ pulse = pulse == GLib::MAXUINT ? 0 : pulse + 1
186
+ iter[COLUMN_PULSE] = pulse
187
+ iter[COLUMN_ACTIVE] = true
133
188
 
134
- # set new value
135
- iter[COLUMN_FIXED] = fixed
189
+ true
190
+ end
136
191
  end
137
192
  end
138
193
  end
@@ -0,0 +1,183 @@
1
+ # Copyright (c) 2016 Ruby-GNOME2 Project Team
2
+ # This program is licenced under the same licence as Ruby-GNOME2.
3
+ #
4
+ =begin
5
+ = List Box
6
+
7
+ GtkListBox allows lists with complicated layouts, using
8
+ regular widgets supporting sorting and filtering.
9
+
10
+ =end
11
+ class ListboxDemo
12
+ def initialize(main_window)
13
+ @window = Gtk::Window.new(:toplevel)
14
+ @window.screen = main_window.screen
15
+ @window.title = "List Box"
16
+ @window.set_default_size(400, 600)
17
+
18
+ vbox = Gtk::Box.new(:vertical, 12)
19
+ @window.add(vbox)
20
+ label = Gtk::Label.new("Messages from Gtk+ and friends")
21
+ vbox.pack_start(label, :expand => false, :fill => false, :padding => 0)
22
+ scrolled = Gtk::ScrolledWindow.new
23
+ scrolled.set_policy(:never, :automatic)
24
+ vbox.pack_start(scrolled, :expand => true, :fill => true, :padding => 0)
25
+
26
+ listbox = Gtk::ListBox.new
27
+ scrolled.add(listbox)
28
+
29
+ listbox.set_sort_func do |a, b|
30
+ a.sort(b)
31
+ end
32
+ listbox.activate_on_single_click = false
33
+ listbox.signal_connect("row-activated", &:row_activated)
34
+ vbox.show_all
35
+
36
+ data = Gio::Resources.lookup_data("/listbox/messages.txt", 0)
37
+ data.each_line do |line|
38
+ message = Message.new(line)
39
+ row = GtkMessageRow.new(message)
40
+ row.show
41
+ listbox.add(row)
42
+ end
43
+ end
44
+
45
+ def run
46
+ if !@window.visible?
47
+ @window.show_all
48
+ else
49
+ @window.destroy
50
+ end
51
+ @window
52
+ end
53
+ end
54
+
55
+ class Message
56
+ attr_reader :id, :sender_name, :sender_nick, :message, :time, :reply_to,
57
+ :resent_by
58
+ attr_accessor :n_favorites, :n_reshares
59
+
60
+ def initialize(str)
61
+ strv = str.split("|")
62
+ parse(strv)
63
+ end
64
+
65
+ private
66
+
67
+ def parse(array_of_strings)
68
+ @id = array_of_strings[0].to_i
69
+ @sender_name = array_of_strings[1]
70
+ @sender_nick = array_of_strings[2]
71
+ @message = array_of_strings[3]
72
+ @time = array_of_strings[4].to_i
73
+ @reply_to = array_of_strings[5] || nil
74
+ @resent_by = array_of_strings[6] || nil
75
+ @n_favorites = array_of_strings[7] ? array_of_strings[7].to_i : nil
76
+ @n_reshares = array_of_strings[8] ? array_of_strings[8].to_i : nil
77
+ end
78
+ end
79
+
80
+ class GtkMessageRow < Gtk::ListBoxRow
81
+
82
+ type_register
83
+ class << self
84
+ def init
85
+ set_template(:resource => "/listbox/listbox.ui")
86
+ bind_template_child("content_label")
87
+ bind_template_child("source_name")
88
+ bind_template_child("source_nick")
89
+ bind_template_child("short_time_label")
90
+ bind_template_child("detailed_time_label")
91
+ bind_template_child("extra_buttons_box")
92
+ bind_template_child("details_revealer")
93
+ bind_template_child("avatar_image")
94
+ bind_template_child("resent_box")
95
+ bind_template_child("resent_by_button")
96
+ bind_template_child("n_reshares_label")
97
+ bind_template_child("n_favorites_label")
98
+ bind_template_child("expand_button")
99
+
100
+ set_connect_func do |name|
101
+ method(name)
102
+ end
103
+ end
104
+
105
+ private
106
+
107
+ def favorite_clicked(button)
108
+ row = button.parent
109
+ row = row.parent while row.class != GtkMessageRow
110
+ row.message.n_favorites += 1
111
+ row.message_row_update
112
+ end
113
+
114
+ def expand_clicked(button)
115
+ row = button.parent
116
+ row = row.parent while row.class != GtkMessageRow
117
+ row.row_expand
118
+ end
119
+
120
+ def reshare_clicked(button)
121
+ row = button.parent
122
+ row = row.parent while row.class != GtkMessageRow
123
+ row.message.n_reshares += 1
124
+ row.message_row_update
125
+ end
126
+ end
127
+
128
+ attr_reader :message
129
+
130
+ def initialize(message)
131
+ super()
132
+ @message = message
133
+ @avatar_pixbuf_other = GdkPixbuf::Pixbuf.new(:resource => "/listbox/apple-red.png",
134
+ :width => 32, :height => 32,
135
+ :preserve_aspect_ratio => false)
136
+ message_row_update
137
+ extra_buttons_box.hide
138
+ extra_buttons_box.visible = false
139
+ extra_buttons_box.unset_state_flags([:prelight, :selected])
140
+ set_state_flags(Gtk::StateFlags::NORMAL, false)
141
+
142
+ signal_connect "state-flags-changed" do |widget, _previous_flags|
143
+ flags = widget.state_flags
144
+
145
+ is_prelight_or_selected = flags & (Gtk::StateFlags::PRELIGHT |
146
+ Gtk::StateFlags::SELECTED)
147
+ if is_prelight_or_selected.nonzero?
148
+ widget.extra_buttons_box.visible = true
149
+ else
150
+ widget.extra_buttons_box.visible = false
151
+ end
152
+ end
153
+ end
154
+
155
+ def message_row_update
156
+ source_name.text = @message.sender_name
157
+ source_nick.text = @message.sender_nick
158
+ content_label.text = @message.message
159
+ short_time_label.text = Time.at(@message.time).utc.strftime("%e %b %y")
160
+ detailed_time_label.text = Time.at(@message.time).utc.strftime("%Y - %e %b %Y")
161
+ n_favorites_label.visible = @message.n_favorites.nonzero?
162
+ n_favorites_label.markup = "<b>#{@message.n_favorites}</b>\nFavorites"
163
+ n_reshares_label.visible = @message.n_reshares.nonzero?
164
+ n_reshares_label.markup = "<b>#{@message.n_reshares}</b>\nReshares"
165
+ resent_box.visible = !@message.resent_by.nil?
166
+ resent_by_button.label = @message.resent_by if @message.resent_by
167
+ if @message.sender_nick == "@GTKtoolkit"
168
+ avatar_image.set_from_icon_name("gtk3-demo", Gtk::IconSize::DND)
169
+ else
170
+ avatar_image.from_pixbuf = @avatar_pixbuf_other
171
+ end
172
+ end
173
+
174
+ def sort(b)
175
+ @message.time - b.message.time
176
+ end
177
+
178
+ def row_expand
179
+ expand = !details_revealer.reveal_child?
180
+ details_revealer.reveal_child = expand
181
+ expand ? expand_button.label = "Hide" : expand_button.label = "Expand"
182
+ end
183
+ end