gtk3 3.0.9-x64-mingw32 → 3.1.0-x64-mingw32

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