# Copyright (c) 2016 Ruby-GNOME2 Project Team
# This program is licenced under the same licence as Ruby-GNOME2.
#
=begin
= List Box
GtkListBox allows lists with complicated layouts, using
regular widgets supporting sorting and filtering.
=end
class ListboxDemo
def initialize(main_window)
@window = Gtk::Window.new(:toplevel)
@window.screen = main_window.screen
@window.title = "List Box"
@window.set_default_size(400, 600)
vbox = Gtk::Box.new(:vertical, 12)
@window.add(vbox)
label = Gtk::Label.new("Messages from Gtk+ and friends")
vbox.pack_start(label, :expand => false, :fill => false, :padding => 0)
scrolled = Gtk::ScrolledWindow.new
scrolled.set_policy(:never, :automatic)
vbox.pack_start(scrolled, :expand => true, :fill => true, :padding => 0)
listbox = Gtk::ListBox.new
scrolled.add(listbox)
listbox.set_sort_func do |a, b|
a.sort(b)
end
listbox.activate_on_single_click = false
listbox.signal_connect("row-activated", &:row_activated)
vbox.show_all
data = Gio::Resources.lookup_data("/listbox/messages.txt", 0)
data.to_s.each_line do |line|
message = Message.new(line)
row = GtkMessageRow.new(message)
row.show
listbox.add(row)
end
end
def run
if !@window.visible?
@window.show_all
else
@window.destroy
end
@window
end
end
class Message
attr_reader :id, :sender_name, :sender_nick, :message, :time, :reply_to,
:resent_by
attr_accessor :n_favorites, :n_reshares
def initialize(str)
strv = str.split("|")
parse(strv)
end
private
def parse(array_of_strings)
@id = array_of_strings[0].to_i
@sender_name = array_of_strings[1]
@sender_nick = array_of_strings[2]
@message = array_of_strings[3]
@time = array_of_strings[4].to_i
@reply_to = array_of_strings[5] || nil
@resent_by = array_of_strings[6] || nil
@n_favorites = array_of_strings[7] ? array_of_strings[7].to_i : nil
@n_reshares = array_of_strings[8] ? array_of_strings[8].to_i : nil
end
end
class GtkMessageRow < Gtk::ListBoxRow
type_register
class << self
def init
set_template(:resource => "/listbox/listbox.ui")
bind_template_child("content_label")
bind_template_child("source_name")
bind_template_child("source_nick")
bind_template_child("short_time_label")
bind_template_child("detailed_time_label")
bind_template_child("extra_buttons_box")
bind_template_child("details_revealer")
bind_template_child("avatar_image")
bind_template_child("resent_box")
bind_template_child("resent_by_button")
bind_template_child("n_reshares_label")
bind_template_child("n_favorites_label")
bind_template_child("expand_button")
set_connect_func do |name|
method(name)
end
end
private
def favorite_clicked(button)
row = button.parent
row = row.parent while row.class != GtkMessageRow
row.message.n_favorites += 1
row.message_row_update
end
def expand_clicked(button)
row = button.parent
row = row.parent while row.class != GtkMessageRow
row.row_expand
end
def reshare_clicked(button)
row = button.parent
row = row.parent while row.class != GtkMessageRow
row.message.n_reshares += 1
row.message_row_update
end
end
attr_reader :message
def initialize(message)
super()
@message = message
@avatar_pixbuf_other = GdkPixbuf::Pixbuf.new(:resource => "/listbox/apple-red.png",
:width => 32, :height => 32,
:preserve_aspect_ratio => false)
message_row_update
extra_buttons_box.hide
extra_buttons_box.visible = false
extra_buttons_box.unset_state_flags([:prelight, :selected])
set_state_flags(Gtk::StateFlags::NORMAL, false)
signal_connect "state-flags-changed" do |widget, _previous_flags|
flags = widget.state_flags
is_prelight_or_selected = flags & (Gtk::StateFlags::PRELIGHT |
Gtk::StateFlags::SELECTED)
if is_prelight_or_selected.nonzero?
widget.extra_buttons_box.visible = true
else
widget.extra_buttons_box.visible = false
end
end
end
def message_row_update
source_name.text = @message.sender_name
source_nick.text = @message.sender_nick
content_label.text = @message.message
short_time_label.text = Time.at(@message.time).utc.strftime("%e %b %y")
detailed_time_label.text = Time.at(@message.time).utc.strftime("%Y - %e %b %Y")
n_favorites_label.visible = !@message.n_favorites.zero?
n_favorites_label.markup = "#{@message.n_favorites}\nFavorites"
n_reshares_label.visible = !@message.n_reshares.zero?
n_reshares_label.markup = "#{@message.n_reshares}\nReshares"
resent_box.visible = !@message.resent_by.nil?
resent_by_button.label = @message.resent_by if @message.resent_by
if @message.sender_nick == "@GTKtoolkit"
avatar_image.set_from_icon_name("gtk3-demo", Gtk::IconSize::DND)
else
avatar_image.from_pixbuf = @avatar_pixbuf_other
end
end
def sort(b)
@message.time - b.message.time
end
def row_expand
expand = !details_revealer.reveal_child?
details_revealer.reveal_child = expand
expand ? expand_button.label = "Hide" : expand_button.label = "Expand"
end
end