# -*- ruby -*-
#
# Copyright (C) 2007 kksou
# Copyright (C) 2008,2009 Cathal Mc Ginley
# Modifications Copyright (C) 2011 Matijs van Zuijlen
#
# Alexandria is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Alexandria is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with Alexandria; see the file COPYING. If not,
# write to the Free Software Foundation, Inc., 51 Franklin Street,
# Fifth Floor, Boston, MA 02110-1301 USA.
# Please retain the following note:
#
# Based upon Recipe 168 - "How to display tooltips in GtkTreeView - Part 3"
# from the "php-gtk2 Cookbook" website, by kksou.
# http://www.kksou.com/php-gtk2/articles/display-tooltips-in-GtkTreeView---Part-3---no-hardcoding-of-header-height.php
#
# Ported to ruby-gtk2 (and modified for IconView) by Cathal Mc Ginley
require 'cgi'
class IconViewTooltips
include Alexandria::Logging
def initialize(view)
@tooltip_window = Gtk::Window.new(Gtk::Window::POPUP)
@tooltip_window.name = 'gtk-tooltips'
@tooltip_window.resizable = false
@tooltip_window.border_width = 4
@tooltip_window.app_paintable = true
@tooltip_window.signal_connect('expose_event') { |window, event|
on_expose(window, event) }
@tooltip_window.signal_connect('leave_notify_event') { |vw, event|
on_leave(vw, event) }
@label = Gtk::Label.new('')
@label.wrap = true
@label.set_alignment(0.5, 0.5)
@label.use_markup = true
@label.show
@tooltip_window.add(@label)
set_view(view)
end
def set_view(view)
view.signal_connect('motion_notify_event') { |vw, event|
on_motion(vw, event) }
view.signal_connect('leave_notify_event') { |vw, event|
on_leave(vw, event) }
end
def on_expose(window, _event)
# this paints a nice outline around the label
size = window.size_request
window.style.paint_flat_box(window.window,
Gtk::STATE_NORMAL,
Gtk::SHADOW_OUT,
nil,
@tooltip_window,
'tooltip',
0, 0, size[0], size[1])
# must return nil so the label contents get drawn correctly
nil
end
def label_for_book(title, authors, publisher, year)
# This is much too complex... but it works for now!
html = ''
if title.size > 0
html += "#{CGI.escapeHTML(title)}"
if authors.size > 0
html += "\n"
end
end
if authors.size > 0
html += "#{CGI.escapeHTML(authors)}"
end
if (title.size > 0) or (authors.size > 0)
html += "\n"
end
html += ''
if publisher and publisher.size > 0
html += "#{CGI.escapeHTML(publisher)}"
end
if year and year.size > 0
if publisher and publisher.size > 0
html += ' '
end
html += "(#{year})"
end
html + ''
end
def on_motion(view, event)
tree_path = view.get_path(event.x, event.y)
# TODO translate path a few times, for sorting & filtering...
# hmmm, actually seems to work. Report a bug if you can spot a failure
if tree_path
iter = view.model.get_iter(tree_path)
if @latest_iter.nil?
@latest_iter = iter
@tooltip_timeout_id = Gtk.timeout_add(250) do
if @latest_iter == iter
title = iter[2] # HACK hardcoded, should use column names...
authors = iter[4]
publisher = iter[6]
year = iter[7]
@label.markup = label_for_book(title, authors, publisher, year)
## "#{title}\n#{authors}\n#{publisher} (#{year})"
size = @tooltip_window.size_request
@tooltip_window.move(event.x_root - size[0],
event.y_root + 12)
@tooltip_window.show
# don't run again
false
else
@tooltip_timeout_id = nil
end
end
elsif @latest_iter != iter
hide_tooltip
end
else
hide_tooltip
end
end
def hide_tooltip
unless @tooltip_window.nil?
@tooltip_window.hide
if @tooltip_timeout_id
Gtk.timeout_remove(@tooltip_timeout_id)
@tooltip_timeout_id = nil
end
@latest_iter = nil
end
end
def on_leave(_view, _event)
@tooltip_window.hide
end
end