Commit 036f3818 authored by Philip Withnall's avatar Philip Withnall Committed by Philip Withnall

Move the cell renderer used in the YouTube plugin out to a C-based GObject

2007-10-22  Philip Withnall  <pwithnall@svn.gnome.org>

	* bindings/python/Makefile.am:
	* bindings/python/totem.defs:
	* bindings/python/totem.override:
	* src/Makefile.am:
	* src/plugins/youtube/youtube.py:
	* src/plugins/youtube/youtube.ui:
	* src/totem-cell-renderer-video.c: 
(totem_cell_renderer_video_new),
	(totem_cell_renderer_video_class_init),
	(totem_cell_renderer_video_init),
	(totem_cell_renderer_video_dispose),
	(totem_cell_renderer_video_set_property),
	(totem_cell_renderer_video_get_property), (get_size),
	(totem_cell_renderer_video_get_size),
	(totem_cell_renderer_video_render):
	* src/totem-cell-renderer-video.h: Move the cell renderer used 
in
	the YouTube plugin out to a C-based GObject and clean it up a 
bit.
	Add the new object to the Python bindings, and make the YouTube
	plugin use it. Additional cleanup to the YouTube plugin and the
	Python bindings.


svn path=/trunk/; revision=4805
parent 7259003a
2007-10-22 Philip Withnall <pwithnall@svn.gnome.org>
* bindings/python/Makefile.am:
* bindings/python/totem.defs:
* bindings/python/totem.override:
* src/Makefile.am:
* src/plugins/youtube/youtube.py:
* src/plugins/youtube/youtube.ui:
* src/totem-cell-renderer-video.c: (totem_cell_renderer_video_new),
(totem_cell_renderer_video_class_init),
(totem_cell_renderer_video_init),
(totem_cell_renderer_video_dispose),
(totem_cell_renderer_video_set_property),
(totem_cell_renderer_video_get_property), (get_size),
(totem_cell_renderer_video_get_size),
(totem_cell_renderer_video_render):
* src/totem-cell-renderer-video.h: Move the cell renderer used in
the YouTube plugin out to a C-based GObject and clean it up a bit.
Add the new object to the Python bindings, and make the YouTube
plugin use it. Additional cleanup to the YouTube plugin and the
Python bindings.
2007-10-22 Philip Withnall <pwithnall@svn.gnome.org>
* src/plugins/youtube/youtube.py: Fix popping from an empty list
......
......@@ -33,6 +33,7 @@ totem.c: totem.defs totem.override
BINDING_HEADERS_SRCDIR_IN = \
src/totem.h \
src/totem-cell-renderer-video.h \
src/plugins/totem-plugin.h \
$(NULL)
......
......@@ -15,6 +15,13 @@
(gtype-id "TOTEM_TYPE_OBJECT")
)
(define-object CellRendererVideo
(in-module "Totem")
(parent "GtkCellRenderer")
(c-name "TotemCellRendererVideo")
(gtype-id "TOTEM_TYPE_CELL_RENDERER_VIDEO")
)
;; Enumerations and flags ...
(define-enum DiscMediaType
......@@ -85,11 +92,6 @@
(return-type "GQuark")
)
(define-function totem_plugin_get_type
(c-name "totem_plugin_get_type")
(return-type "GType")
)
(define-method activate
(of-object "TotemPlugin")
(c-name "totem_plugin_activate")
......@@ -145,11 +147,6 @@
;; From totem.h
(define-function totem_object_get_type
(c-name "totem_object_get_type")
(return-type "GType")
)
(define-method plugins_init
(of-object "TotemObject")
(c-name "totem_object_plugins_init")
......@@ -438,3 +435,15 @@
)
;; From ../../src/totem-cell-renderer-video.h
(define-function totem_cell_renderer_video_new
(is-constructor-of "TotemCellRendererVideo")
(c-name "totem_cell_renderer_video_new")
(return-type "TotemCellRendererVideo*")
(properties
'("title" (argname "title") (optional))
'("thumbnail-url" (argname "thumbnail-url") (optional))
)
)
......@@ -9,6 +9,7 @@ headers
#include "override_common.h"
#include "totem.h"
#include "totem-cell-renderer-video.h"
#include "plparse/totem-disc.h"
#include "plugins/totem-plugin.h"
......@@ -33,6 +34,7 @@ import gtk.Widget as PyGtkWidget_Type
import gtk.Window as PyGtkWindow_Type
import gtk.gdk.Pixbuf as PyGdkPixbuf_Type
import gtk.ComboBox as PyGtkComboBox_Type
import gtk.CellRenderer as PyGtkCellRenderer_Type
%%
ignore-glob
*_get_type
......
2007-10-22 Philip Withnall <pwithnall@svn.gnome.org>
* POTFILES.in: Add the TotemCellRendererVideo files
to the list and fix a previous entry in the ChangeLog.
2007-10-22 Jorge Gonzalez <jorgegonz@svn.gnome.org>
* es.po: Updated Spanish translation.
......@@ -38,11 +43,9 @@
* he.po: Updated Hebrew translation.
2007-10-08 Philip Withnall <philip@KWA-PHILIP-LINUX>
2007-10-08 Philip Withnall <pwithnall@svn.gnome.org>
reviewed by: <delete if not using a buddy>
* POTFILES.in:
* POTFILES.in: Add the YouTube files to the list.
2007-10-08 Danishka Navin <danishka@gmail.com>
......
......@@ -10,6 +10,7 @@ data/totem.desktop.in.in.in
data/totem.schemas.in
[type: gettext/glade]data/uri.ui
lib/totem-scrsaver.c
src/totem-cell-renderer-video.c
src/totem-fullscreen.c
src/totem-interface.c
src/totem-menu.c
......
......@@ -104,7 +104,9 @@ totem_SOURCES = \
totem-uri.c totem-uri.h \
ev-sidebar.c ev-sidebar.h \
totem-subtitle-encoding.c \
totem-subtitle-encoding.h
totem-subtitle-encoding.h \
totem-cell-renderer-video.c \
totem-cell-renderer-video.h
totem_CPPFLAGS = \
-I$(srcdir)/plparse \
......
......@@ -4,7 +4,6 @@ import gdata.service
import urllib
import httplib
import atom
import pango
import threading
import re
from os import unlink
......@@ -17,73 +16,6 @@ class DownloadThread (threading.Thread):
def run (self):
self.youtube.entry = self.youtube.service.Get (self.url).entry
class CellRendererVideo (gtk.GenericCellRenderer):
__gtype_name__ = "CellRendererVideo"
__gproperties__ = {
"youtube-id": (gobject.TYPE_STRING, "YouTube ID", "The unique YouTube ID of this video.", "", gobject.PARAM_READWRITE),
"title": (gobject.TYPE_STRING, "Video title", "The video's title.", "", gobject.PARAM_READWRITE)
}
def __init__ (self, totem):
gtk.GenericCellRenderer.__init__ (self)
self.renderer = gtk.CellRendererPixbuf ()
self.youtube_id = None
self.title = None
self.cached_pixbufs = {}
self.totem = totem
self.set_property ("mode", gtk.CELL_RENDERER_MODE_ACTIVATABLE)
def do_set_property (self, pspec, value):
if pspec.name == "youtube-id":
if not self.cached_pixbufs.has_key (value):
"""Save the thumbnail to a temporary location"""
try:
filename, headers = urllib.urlretrieve ("http://img.youtube.com/vi/" + value + "/1.jpg")
except IOError:
print "Could not load thumbnail for video " + value
self.cached_pixbufs[value] = gtk.gdk.pixbuf_new_from_file (filename)
"""Don't leak the temporary file"""
unlink (filename)
if self.youtube_id != value:
"""Use the cached pixbuf"""
self.renderer.set_property ("pixbuf", self.cached_pixbufs[value])
self.youtube_id = value
elif pspec.name == "title":
self.title = value
else:
raise AttributeError, "unknown property %s" % pspec.name
def do_get_property (self, pspec):
if pspec.name == "youtube-id":
return self.youtube_id
elif pspec.name == "title":
return self.title
else:
raise AttributeError, "unknown property %s" % pspec.name
def on_get_size (self, widget, cell_area):
return (0, 0, 130, 120)
def on_render (self, window, widget, background_area, cell_area, expose_area, flags):
layout = widget.create_pango_layout (self.title)
desc = pango.FontDescription ("Sans bold 10")
layout.set_font_description (desc)
layout.set_ellipsize (pango.ELLIPSIZE_END)
layout.set_width (cell_area[2] * pango.SCALE)
gc = window.new_gc ()
window.draw_layout (gc, cell_area[0] + 2, cell_area[1] + 2, layout)
cell_area[1] += 10
return self.renderer.render (window, widget, background_area, cell_area, expose_area, flags)
def on_activate (self, event, widget, path, background_area, cell_area, flags):
self.renderer.activate (event, widget, path, background_area, cell_area, flags)
return False
def clear (self):
"""Don't leak pixbufs"""
self.cached_pixbufs.clear ()
gobject.type_register (CellRendererVideo)
class YouTube (totem.Plugin):
def __init__ (self):
totem.Plugin.__init__(self)
......@@ -96,8 +28,8 @@ class YouTube (totem.Plugin):
self.results = 0
self.entry = None
self.button_down = False
def activate (self, totem):
self.builder = self.load_interface ("youtube.ui", True, totem.get_main_window (), self)
def activate (self, totem_object):
self.builder = self.load_interface ("youtube.ui", True, totem_object.get_main_window (), self)
self.search_entry = self.builder.get_object ("yt_search_entry")
self.search_entry.connect ("activate", self.on_search_entry_activated)
......@@ -106,10 +38,10 @@ class YouTube (totem.Plugin):
self.status_label = self.builder.get_object ("yt_status_label")
"""This is created here rather than in the UI file, because UI files parsed in C and GObjects created in Python don't mix."""
self.renderer = CellRendererVideo (totem)
self.renderer = totem.CellRendererVideo ()
self.treeview = self.builder.get_object ("yt_treeview")
self.treeview.connect ("row-activated", self.on_row_activated)
self.treeview.insert_column_with_attributes (0, _("Videos"), self.renderer, youtube_id=0, title=1)
self.treeview.insert_column_with_attributes (0, _("Videos"), self.renderer, thumbnail=0, title=1)
self.vadjust = self.treeview.get_vadjustment ()
self.vadjust.connect ("value-changed", self.on_value_changed)
......@@ -117,22 +49,22 @@ class YouTube (totem.Plugin):
vscroll.connect ("button-press-event", self.on_button_press_event)
vscroll.connect ("button-release-event", self.on_button_release_event)
self.liststore = gtk.ListStore (gobject.TYPE_STRING, gobject.TYPE_STRING)
self.liststore = gtk.ListStore (gobject.TYPE_OBJECT, gobject.TYPE_STRING, gobject.TYPE_STRING)
self.treeview.set_model (self.liststore)
vbox = self.builder.get_object ("yt_vbox")
vbox.show_all ()
totem.add_sidebar_page ("youtube", _("YouTube"), vbox)
totem_object.add_sidebar_page ("youtube", _("YouTube"), vbox)
"""Set up the service"""
self.service = gdata.service.GDataService (None, None, "HOSTED_OR_GOOGLE", None, None, "gdata.youtube.com")
self.totem = totem
self.totem = totem_object
def deactivate (self, totem):
totem.remove_sidebar_page ("youtube")
def on_row_activated (self, treeview, path, column):
model, iter = treeview.get_selection ().get_selected ()
youtube_id = model.get_value (iter, 0)
youtube_id = model.get_value (iter, 2)
"""Play the video"""
conn = httplib.HTTPConnection ("www.youtube.com")
......@@ -145,7 +77,6 @@ class YouTube (totem.Plugin):
url = "http://www.youtube.com/v/" + urllib.quote (youtube_id)
conn.close ()
print url
if self.debug:
print "Playing: " + url
else:
......@@ -172,7 +103,6 @@ class YouTube (totem.Plugin):
self.get_results ("/feeds/videos?vq=" + urllib.quote_plus (self.query) + "&max-results=" + str (self.max_results) + "&orderby=relevance&start-index=" + str (self.start_index), _("Search Results:"), False)
else:
self.get_results ("/feeds/videos/" + urllib.quote_plus (self.query) + "/related?max-results=" + str (self.max_results) + "&start-index=" + str (self.start_index), _("Related Videos:"), False)
self.start_index += self.max_results
def convert_url_to_id (self, url):
return url.rpartition ("/")[2]
def populate_list_from_results (self, status_text):
......@@ -183,7 +113,31 @@ class YouTube (totem.Plugin):
"""Only do one result at a time, as the thumbnail has to be downloaded"""
entry = self.entry.pop (0)
self.results += 1
self.liststore.append ([self.convert_url_to_id (entry.id.text), entry.title.text])
self.start_index += 1
"""Find the thumbnail tag"""
for _element in entry.extension_elements:
if _element.tag == "group":
break
"""Download the thumbnail and store it in a temporary location so we can get a pixbuf from it"""
thumbnail_url = _element.FindChildren ("thumbnail")[0].attributes['url']
try:
filename, headers = urllib.urlretrieve (thumbnail_url)
except IOError:
print "Could not load thumbnail " + thumbnail_url + " for video."
return True
try:
pixbuf = gtk.gdk.pixbuf_new_from_file (filename)
except gobject.GError:
print "Could not load thumbnail " + filename + " for video. It has been left in place for investigation."
return True
"""Don't leak the temporary file"""
unlink (filename)
self.liststore.append ([pixbuf, entry.title.text, self.convert_url_to_id (entry.id.text)])
self.treeview.window.process_updates (True)
"""Have we finished?"""
......@@ -197,7 +151,7 @@ class YouTube (totem.Plugin):
search_terms = self.search_entry.get_text ()
if self.debug:
print "Searching: " + search_terms
print "Searching for \"" + search_terms + "\""
self.search_mode = True
self.query = search_terms
......@@ -208,7 +162,6 @@ class YouTube (totem.Plugin):
self.search_button.clicked ()
def get_results (self, url, status_text, clear = True):
if clear:
self.renderer.clear ()
self.liststore.clear ()
self.status_label.set_text (_("Loading..."))
......@@ -217,5 +170,8 @@ class YouTube (totem.Plugin):
self.status_label.window.process_updates (True)
self.treeview.window.process_updates (True)
if self.debug:
print "Getting results from URL \"" + url + "\""
DownloadThread (self, url).start ()
gobject.idle_add (self.populate_list_from_results, status_text)
......@@ -73,7 +73,7 @@
<child>
<object class="GtkTreeView" id="yt_treeview">
<property name="headers-visible">False</property>
<property name="fixed-height-mode">True</property>
<property name="fixed-height-mode">False</property>
<child>
<!--<object class="GtkTreeViewColumn" id="yt_treeview_column">
<property name="title">Videos</property>
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2001-2007 Philip Withnall <philip@tecnocode.co.uk>
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Totem project hereby grant permission for non-gpl compatible GStreamer
* plugins to be used and distributed together with GStreamer and Totem. This
* permission are above and beyond the permissions granted by the GPL license
* Totem is covered by.
*
* Monday 7th February 2005: Christian Schaller: Add exception clause.
* See license_change file for details.
*
*/
#include "config.h"
#include <glib.h>
#include <glib/gi18n.h>
#include "totem.h"
#include "totem-cell-renderer-video.h"
#include "totem-private.h"
struct _TotemCellRendererVideoPrivate {
gboolean dispose_has_run;
gchar *title;
GdkPixbuf *thumbnail;
};
#define TOTEM_CELL_RENDERER_VIDEO_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TOTEM_TYPE_CELL_RENDERER_VIDEO, TotemCellRendererVideoPrivate))
enum {
PROP_THUMBNAIL = 1,
PROP_TITLE
};
static void totem_cell_renderer_video_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
static void totem_cell_renderer_video_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static void totem_cell_renderer_video_dispose (GObject *object);
static void totem_cell_renderer_video_get_size (GtkCellRenderer *cell, GtkWidget *widget, GdkRectangle *cell_area, gint *x_offset, gint *y_offset, gint *width, gint *height);
static void totem_cell_renderer_video_render (GtkCellRenderer *cell, GdkDrawable *window, GtkWidget *widget, GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags);
G_DEFINE_TYPE (TotemCellRendererVideo, totem_cell_renderer_video, GTK_TYPE_CELL_RENDERER)
TotemCellRendererVideo *
totem_cell_renderer_video_new (void)
{
return g_object_new (TOTEM_TYPE_CELL_RENDERER_VIDEO, NULL);
}
static void
totem_cell_renderer_video_class_init (TotemCellRendererVideoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkCellRendererClass *renderer_class = GTK_CELL_RENDERER_CLASS (klass);
g_type_class_add_private (klass, sizeof (TotemCellRendererVideoPrivate));
object_class->set_property = totem_cell_renderer_video_set_property;
object_class->get_property = totem_cell_renderer_video_get_property;
object_class->dispose = totem_cell_renderer_video_dispose;
renderer_class->get_size = totem_cell_renderer_video_get_size;
renderer_class->render = totem_cell_renderer_video_render;
/*renderer_class->activate = totem_cell_renderer_video_activate;*/
g_object_class_install_property (object_class, PROP_THUMBNAIL,
g_param_spec_object ("thumbnail", NULL, NULL,
GDK_TYPE_PIXBUF, G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_TITLE,
g_param_spec_string ("title", NULL, NULL,
_("Unknown video"), G_PARAM_READWRITE));
}
static void
totem_cell_renderer_video_init (TotemCellRendererVideo *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TOTEM_TYPE_CELL_RENDERER_VIDEO, TotemCellRendererVideoPrivate);
self->priv->dispose_has_run = FALSE;
self->priv->title = NULL;
self->priv->thumbnail = NULL;
/* Make sure we're in the right mode */
g_object_set ((gpointer) self, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
}
static void
totem_cell_renderer_video_dispose (GObject *object)
{
TotemCellRendererVideo *self = TOTEM_CELL_RENDERER_VIDEO (object);
/* Make sure we only run once */
if (self->priv->dispose_has_run)
return;
self->priv->dispose_has_run = TRUE;
g_free (self->priv->title);
if (self->priv->thumbnail != NULL)
g_object_unref (self->priv->thumbnail);
/* Chain up to the parent class */
G_OBJECT_CLASS (totem_cell_renderer_video_parent_class)->dispose (object);
}
static void
totem_cell_renderer_video_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
TotemCellRendererVideo *self = TOTEM_CELL_RENDERER_VIDEO (object);
switch (property_id)
{
case PROP_THUMBNAIL:
if (self->priv->thumbnail != NULL)
g_object_unref (self->priv->thumbnail);
self->priv->thumbnail = (GdkPixbuf*) g_value_dup_object (value);
break;
case PROP_TITLE:
g_free (self->priv->title);
self->priv->title = g_strdup (g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
totem_cell_renderer_video_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
TotemCellRendererVideo *self = TOTEM_CELL_RENDERER_VIDEO (object);
switch (property_id)
{
case PROP_THUMBNAIL:
g_value_set_object (value, G_OBJECT (self->priv->thumbnail));
break;
case PROP_TITLE:
g_value_set_string (value, self->priv->title);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
get_size (GtkCellRenderer *cell,
GtkWidget *widget,
GdkRectangle *cell_area,
GdkRectangle *draw_area,
GdkRectangle *title_area,
GdkRectangle *thumbnail_area)
{
TotemCellRendererVideoPrivate *priv = TOTEM_CELL_RENDERER_VIDEO_GET_PRIVATE (cell);
guint pixbuf_width = 0;
guint pixbuf_height = 0;
guint calc_width;
guint calc_height;
PangoContext *context;
PangoFontMetrics *metrics;
PangoFontDescription *font_desc;
guint title_height;
/* Calculate thumbnail dimensions */
if (priv->thumbnail != NULL) {
pixbuf_width = gdk_pixbuf_get_width (priv->thumbnail);
pixbuf_height = gdk_pixbuf_get_height (priv->thumbnail);
}
/* Calculate title dimensions */
font_desc = pango_font_description_copy_static (widget->style->font_desc);
pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
context = gtk_widget_get_pango_context (widget);
metrics = pango_context_get_metrics (context,
font_desc,
pango_context_get_language (context));
title_height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
pango_font_metrics_get_descent (metrics));
pango_font_metrics_unref (metrics);
pango_font_description_free (font_desc);
/* Calculate the final size */
calc_width = cell->xpad * 2 + pixbuf_width;
calc_height = cell->ypad * 3 + pixbuf_height + title_height;
if (draw_area) {
if (cell_area && pixbuf_width > 0 && pixbuf_height + title_height + cell->ypad > 0) {
draw_area->x = (((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ?
(1.0 - cell->xalign) : cell->xalign) *
(cell_area->width - calc_width));
draw_area->x = MAX (draw_area->x, 0);
draw_area->y = (cell->yalign * (cell_area->height - calc_height));
draw_area->y = MAX (draw_area->y, 0);
} else {
draw_area->x = 0;
draw_area->y = 0;
}
draw_area->width = calc_width;
draw_area->height = calc_height;
if (title_area) {
title_area->x = draw_area->x;
title_area->y = draw_area->y;
title_area->width = calc_width;
title_area->height = title_height;
}
if (thumbnail_area) {
thumbnail_area->x = draw_area->x;
thumbnail_area->y = draw_area->y + title_height + cell->ypad;
thumbnail_area->width = calc_width;
thumbnail_area->height = pixbuf_height;
}
}
}
static void
totem_cell_renderer_video_get_size (GtkCellRenderer *cell,
GtkWidget *widget,
GdkRectangle *cell_area,
gint *x_offset,
gint *y_offset,
gint *width,
gint *height)
{
GdkRectangle draw_area;
get_size (cell, widget, cell_area, &draw_area, NULL, NULL);
if (x_offset)
*x_offset = draw_area.x;
if (y_offset)
*y_offset = draw_area.y;
if (width)
*width = draw_area.width;
if (height)
*height = draw_area.height;
}
static void
totem_cell_renderer_video_render (GtkCellRenderer *cell,
GdkDrawable *window,
GtkWidget *widget,
GdkRectangle *background_area,
GdkRectangle *cell_area,
GdkRectangle *expose_area,
GtkCellRendererState flags)
{
TotemCellRendererVideoPrivate *priv = TOTEM_CELL_RENDERER_VIDEO_GET_PRIVATE (cell);
GdkPixbuf *pixbuf;
GdkRectangle draw_rect;
GdkRectangle draw_area;
GdkRectangle title_area;
GdkRectangle thumbnail_area;
cairo_t *cr;
PangoLayout *layout;
PangoFontDescription *desc;
GtkStateType state;
get_size (cell, widget, cell_area, &draw_area, &title_area, &thumbnail_area);
draw_area.x += cell_area->x + cell->xpad;
draw_area.y += cell_area->y + cell->ypad;
draw_area.width -= cell->xpad * 2;
draw_area.height -= cell->ypad * 2;
if (!gdk_rectangle_intersect (cell_area, &draw_area, &draw_rect) ||
!gdk_rectangle_intersect (expose_area, &draw_rect, &draw_rect))
return;
/* Sort out the thumbnail */
pixbuf = priv->thumbnail;
if (cell->is_expander || !pixbuf)
return;
/* Sort out the title */
if (!cell->sensitive) {
state = GTK_STATE_INSENSITIVE;
} else if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED) {
if (GTK_WIDGET_HAS_FOCUS (widget))
state = GTK_STATE_SELECTED;
else
state = GTK_STATE_ACTIVE;
} else if ((flags & GTK_CELL_RENDERER_PRELIT) == GTK_CELL_RENDERER_PRELIT &&
GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT) {
state = GTK_STATE_PRELIGHT;
} else {
if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE)
state = GTK_STATE_INSENSITIVE;
else
state = GTK_STATE_NORMAL;
}
cr = gdk_cairo_create (window);
/* Draw the title */
layout = gtk_widget_create_pango_layout (widget, priv->title);
desc = pango_font_description_copy_static (widget->style->font_desc);
pango_font_description_set_weight (desc, PANGO_WEIGHT_BOLD);
pango_layout_set_font_description (layout, desc);
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
pango_layout_set_width (layout, (cell_area->width - title_area.x - 2 * cell->xpad) * PANGO_SCALE);
gtk_paint_layout (widget->style,
window,
state,
TRUE,
expose_area,
widget,
"cellrenderervideotitle",
cell_area->x + title_area.x + cell->xpad,
cell_area->y + title_area.y + cell->ypad,
layout);
pango_font_description_free (desc);
g_object_unref (layout);
/* Draw the thumbnail */
gdk_cairo_set_source_pixbuf (cr, pixbuf, cell_area->x + thumbnail_area.x + cell->xpad, cell_area->y + thumbnail_area.y + cell->ypad);
gdk_cairo_rectangle (cr, &draw_rect);
cairo_fill (cr);
cairo_destroy (cr);
}
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2001-2007 Philip Withnall <philip@tecnocode.co.uk>
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Totem project hereby grant permission for non-gpl compatible GStreamer
* plugins to be used and distributed together with GStreamer and Totem. This
* permission are above and beyond the permissions granted by the GPL license
* Totem is covered by.
*
* Monday 7th February 2005: Christian Schaller: Add exception clause.
* See license_change file for details.
*
*/
#include <gtk/gtk.h>
#include <glib.h>