Changeset 7996


Ignore:
Timestamp:
Mar 2, 2009, 11:31:01 PM (13 years ago)
Author:
charles
Message:

(gtk trunk) #628: Show thumbnails next to torrents

Location:
trunk/gtk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/Makefile.am

    r7087 r7996  
    4343    dialogs.h \
    4444    hig.h \
     45    icons.h \
    4546    file-list.h \
    4647    lock.h \
     
    7677    file-list.c \
    7778    hig.c \
     79    icons.c \
    7880    main.c \
    7981    makemeta-ui.c \
  • trunk/gtk/file-list.c

    r7464 r7996  
    3535#include "file-list.h"
    3636#include "hig.h"
     37#include "icons.h"
    3738
    3839enum
     
    5051enum
    5152{
    52     FC_STOCK,
     53    FC_ICON,
    5354    FC_LABEL,
    5455    FC_PROG,
     
    104105
    105106static void
    106 parsepath( const tr_torrent * tor,
    107            GtkTreeStore *     store,
    108            GtkTreeIter *      ret,
    109            const char *       path,
    110            tr_file_index_t    index,
    111            uint64_t           size )
     107parsepath( GtkWidget         * w,
     108           const tr_torrent  * tor,
     109           GtkTreeStore      * store,
     110           GtkTreeIter       * ret,
     111           const char        * path,
     112           tr_file_index_t     index,
     113           uint64_t            size )
    112114{
    113115    GtkTreeModel * model;
    114     GtkTreeIter *  parent, start, iter;
    115     char *         file, * lower, * mykey;
    116     const char *   stock;
     116    GtkTreeIter  * parent, start, iter;
     117    char         * file, * lower, * mykey;
    117118    int            priority = 0;
    118119    gboolean       enabled = TRUE;
    119120    gboolean       is_file;
    120 
     121    GdkPixbuf    * icon;
     122    const char   * mime_type;
     123   
    121124    model  = GTK_TREE_MODEL( store );
    122125    parent = NULL;
     
    125128    {
    126129        char * dir = g_path_get_dirname( path );
    127         parsepath( tor, store, &start, dir, index, size );
     130        parsepath( w, tor, store, &start, dir, index, size );
    128131        parent = &start;
    129132        g_free( dir );
     
    146149    if( ( is_file = !ret ) )
    147150    {
    148         stock = GTK_STOCK_FILE;
    149151        priority = tr_torrentGetFilePriority( tor, index );
    150152        enabled  = tr_torrentGetFileDL( tor, index );
     153        mime_type = get_mime_type_from_filename( file );
    151154    }
    152155    else
    153156    {
    154         stock = GTK_STOCK_DIRECTORY;
    155157        size  = 0;
    156     }
     158        mime_type = DIRECTORY_MIME_TYPE;
     159    }
     160
     161    icon = get_mime_type_icon( mime_type, GTK_ICON_SIZE_MENU, w );
    157162
    158163#if 0
    159164    gtk_tree_store_set( store, &iter, FC_INDEX, index,
    160                         FC_LABEL, file,
    161                         FC_KEY, mykey,
    162                         FC_STOCK, stock,
    163                         FC_PRIORITY, priority,
    164                         FC_ENABLED, enabled,
    165                         FC_IS_FILE, is_file,
    166                         FC_SIZE, size,
    167                         FC_HAVE, 0,
    168                         -1 );
     165                                      FC_LABEL, file,
     166                                      FC_KEY, mykey,
     167                                      FC_ICON, icon,
     168                                      FC_PRIORITY, priority,
     169                                      FC_ENABLED, enabled,
     170                                      FC_IS_FILE, is_file,
     171                                      FC_SIZE, size,
     172                                      FC_HAVE, 0,
     173                                      -1 );
    169174#else
    170175    gtk_tree_store_set( store, &iter, FC_INDEX, index, -1 );
    171176    gtk_tree_store_set( store, &iter, FC_LABEL, file, -1 );
    172177    gtk_tree_store_set( store, &iter, FC_KEY, mykey, -1 );
    173     gtk_tree_store_set( store, &iter, FC_STOCK, stock, -1 );
     178    gtk_tree_store_set( store, &iter, FC_ICON, icon, -1 );
    174179    gtk_tree_store_set( store, &iter, FC_PRIORITY, priority, -1 );
    175180    gtk_tree_store_set( store, &iter, FC_ENABLED, enabled, -1 );
     
    178183    gtk_tree_store_set( store, &iter, FC_HAVE, 0, -1 );
    179184#endif
     185
     186    if( icon != NULL )
     187        g_object_unref( icon );
    180188
    181189done:
     
    448456    /* instantiate the model */
    449457    store = gtk_tree_store_new ( N_FILE_COLS,
    450                                  G_TYPE_STRING,    /* stock */
     458                                 GDK_TYPE_PIXBUF,  /* icon */
    451459                                 G_TYPE_STRING,    /* label */
    452460                                 G_TYPE_INT,       /* prog [0..100] */
     
    479487                g_path_is_absolute( path ) ? g_path_skip_root( path ) :
    480488                path;
    481             parsepath( tor, store, NULL, base, i, inf->files[i].length );
     489            parsepath( w, tor, store, NULL, base, i, inf->files[i].length );
    482490        }
    483491
     
    795803    rend = gtk_cell_renderer_pixbuf_new( );
    796804    gtk_tree_view_column_pack_start( col, rend, FALSE );
    797     gtk_tree_view_column_add_attribute( col, rend, "stock-id", FC_STOCK );
     805    gtk_tree_view_column_add_attribute( col, rend, "pixbuf", FC_ICON );
    798806    /* add text renderer */
    799807    rend = gtk_cell_renderer_text_new( );
  • trunk/gtk/torrent-cell-renderer.c

    r7982 r7996  
    1616#include <libtransmission/transmission.h>
    1717#include "hig.h"
     18#include "icons.h"
    1819#include "torrent-cell-renderer.h"
    1920#include "tr-torrent.h"
     
    3031
    3132#define DEFAULT_BAR_HEIGHT 12
     33#define SMALL_SCALE 0.9
     34#define MINIMAL_ICON_SIZE GTK_ICON_SIZE_MENU
     35#define FULL_ICON_SIZE GTK_ICON_SIZE_DND
    3236
    3337/***
     
    262266struct TorrentCellRendererPrivate
    263267{
    264     tr_torrent *       tor;
    265     GtkCellRenderer *  text_renderer;
    266     GtkCellRenderer *  text_renderer_err;
    267     GtkCellRenderer *  progress_renderer;
     268    tr_torrent       * tor;
     269    GtkCellRenderer  * text_renderer;
     270    GtkCellRenderer  * text_renderer_err;
     271    GtkCellRenderer  * progress_renderer;
     272    GtkCellRenderer  * icon_renderer;
    268273    int                bar_height;
    269274    gboolean           minimal;
    270275};
    271276
    272 static void
    273 torrent_cell_renderer_get_size( GtkCellRenderer * cell,
    274                                 GtkWidget *       widget,
    275                                 GdkRectangle *    cell_area,
    276                                 gint *            x_offset,
    277                                 gint *            y_offset,
    278                                 gint *            width,
    279                                 gint *            height )
     277/***
     278****
     279***/
     280
     281static GdkPixbuf*
     282get_icon( const tr_torrent * tor, GtkIconSize icon_size, GtkWidget * for_widget )
     283{
     284    const char * mime_type;
     285    const tr_info * info = tr_torrentInfo( tor );
     286
     287    /* a very basic cache, but hits about 80% of the time... */
     288    static GdkPixbuf   * prev_icon = NULL;
     289    static GtkWidget   * prev_widget = NULL;
     290    static const char  * prev_mime_type = NULL;
     291    static GtkIconSize   prev_size = 0;
     292
     293    if( info->fileCount > 1 )
     294        mime_type = DIRECTORY_MIME_TYPE;
     295    else
     296        mime_type = get_mime_type_from_filename( info->files[0].name );
     297
     298    if( ( for_widget == prev_widget ) && ( prev_size == icon_size ) && !strcmp( prev_mime_type, mime_type ) )
     299        return prev_icon;
     300
     301    prev_mime_type = mime_type;
     302    prev_size = icon_size;
     303    prev_widget = for_widget;
     304    prev_icon = get_mime_type_icon( mime_type, icon_size, for_widget );
     305    return prev_icon;
     306}
     307
     308static GtkCellRenderer*
     309get_text_renderer( const tr_stat * st, TorrentCellRenderer * r )
     310{
     311    return st->error ? r->priv->text_renderer_err : r->priv->text_renderer;
     312}
     313
     314/***
     315****
     316***/
     317
     318static void
     319get_size_minimal( TorrentCellRenderer * cell,
     320                  GtkWidget           * widget,
     321                  gint                * width,
     322                  gint                * height )
     323{
     324    int w, h;
     325    GdkRectangle icon_area;
     326    GdkRectangle name_area;
     327    GdkRectangle stat_area;
     328    const char * name;
     329    char * status;
     330    GdkPixbuf * icon;
     331    GtkCellRenderer * text_renderer;
     332
     333    struct TorrentCellRendererPrivate * p = cell->priv;
     334    const tr_torrent * tor = p->tor;
     335    const tr_stat * st = tr_torrentStatCached( (tr_torrent*)tor );
     336
     337    icon = get_icon( tor, MINIMAL_ICON_SIZE, widget );
     338    name = tr_torrentInfo( tor )->name;
     339    status = getShortStatusString( st );
     340
     341    /* get the idealized cell dimensions */
     342    g_object_set( p->icon_renderer, "pixbuf", icon, NULL );
     343    gtk_cell_renderer_get_size( p->icon_renderer, widget, NULL, NULL, NULL, &w, &h );
     344    icon_area.width = w;
     345    icon_area.height = h;
     346    text_renderer = get_text_renderer( st, cell );
     347    g_object_set( text_renderer, "text", name, "ellipsize", PANGO_ELLIPSIZE_NONE,  "scale", 1.0, NULL );
     348    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
     349    name_area.width = w;
     350    name_area.height = h;
     351    g_object_set( text_renderer, "text", status, "scale", SMALL_SCALE, NULL );
     352    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
     353    stat_area.width = w;
     354    stat_area.height = h;
     355   
     356    /**
     357    *** LAYOUT
     358    **/
     359
     360    if( width != NULL )
     361        *width = cell->parent.xpad * 2 + icon_area.width + GUI_PAD + name_area.width + GUI_PAD + stat_area.width;
     362    if( height != NULL )
     363        *height = cell->parent.ypad * 2 + name_area.height + p->bar_height;
     364
     365    /* cleanup */
     366    g_free( status );
     367}
     368
     369#define MAX3(a,b,c) MAX(a,MAX(b,c))
     370
     371static void
     372get_size_full( TorrentCellRenderer * cell,
     373               GtkWidget           * widget,
     374               gint                * width,
     375               gint                * height )
     376{
     377    int w, h;
     378    GdkRectangle icon_area;
     379    GdkRectangle name_area;
     380    GdkRectangle stat_area;
     381    GdkRectangle prog_area;
     382    const char * name;
     383    char * status;
     384    char * progress;
     385    GdkPixbuf * icon;
     386    GtkCellRenderer * text_renderer;
     387
     388    struct TorrentCellRendererPrivate * p = cell->priv;
     389    const tr_torrent * tor = p->tor;
     390    const tr_stat * st = tr_torrentStatCached( (tr_torrent*)tor );
     391    const tr_info * inf = tr_torrentInfo( tor );
     392
     393    icon = get_icon( tor, FULL_ICON_SIZE, widget );
     394    name = inf->name;
     395    status = getStatusString( st );
     396    progress = getProgressString( tor, inf, st );
     397
     398    /* get the idealized cell dimensions */
     399    g_object_set( p->icon_renderer, "pixbuf", icon, NULL );
     400    gtk_cell_renderer_get_size( p->icon_renderer, widget, NULL, NULL, NULL, &w, &h );
     401    icon_area.width = w;
     402    icon_area.height = h;
     403    text_renderer = get_text_renderer( st, cell );
     404    g_object_set( text_renderer, "text", name, "weight", PANGO_WEIGHT_BOLD, "scale", 1.0, "ellipsize", PANGO_ELLIPSIZE_NONE, NULL );
     405    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
     406    name_area.width = w;
     407    name_area.height = h;
     408    g_object_set( text_renderer, "text", progress, "weight", PANGO_WEIGHT_NORMAL, "scale", SMALL_SCALE, NULL );
     409    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
     410    prog_area.width = w;
     411    prog_area.height = h;
     412    g_object_set( text_renderer, "text", status, NULL );
     413    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
     414    stat_area.width = w;
     415    stat_area.height = h;
     416   
     417    /**
     418    *** LAYOUT
     419    **/
     420
     421    if( width != NULL )
     422        *width = cell->parent.xpad * 2 + icon_area.width + GUI_PAD + MAX3( name_area.width, prog_area.width, stat_area.width );
     423    if( height != NULL )
     424        *height = cell->parent.ypad * 2 + name_area.height + prog_area.height + GUI_PAD_SMALL + p->bar_height + GUI_PAD_SMALL + stat_area.height;
     425
     426    /* cleanup */
     427    g_free( status );
     428    g_free( progress );
     429}
     430
     431
     432static void
     433torrent_cell_renderer_get_size( GtkCellRenderer  * cell,
     434                                GtkWidget        * widget,
     435                                GdkRectangle     * cell_area,
     436                                gint             * x_offset,
     437                                gint             * y_offset,
     438                                gint             * width,
     439                                gint             * height )
    280440{
    281441    TorrentCellRenderer * self = TORRENT_CELL_RENDERER( cell );
     
    283443    if( self && self->priv->tor )
    284444    {
    285         const tr_torrent *                  tor = self->priv->tor;
    286         const tr_info *                     info = tr_torrentInfo( tor );
    287         const char *                        name = info->name;
    288         const tr_stat *                     torStat =
    289             tr_torrentStatCached( (tr_torrent*)tor );
    290         char *                              str;
    291         int                                 w = 0, h = 0;
    292445        struct TorrentCellRendererPrivate * p = self->priv;
    293         GtkCellRenderer *                   text_renderer =
    294             torStat->error != 0
    295             ? p->
    296             text_renderer_err
    297             : p->
    298             text_renderer;
    299 
    300         g_object_set( text_renderer, "ellipsize", PANGO_ELLIPSIZE_NONE,
    301                       NULL );
    302 
    303         /* above the progressbar */
     446        int w, h;
     447
    304448        if( p->minimal )
    305         {
    306             int    w1, w2, h1, h2;
    307             char * shortStatus = getShortStatusString( torStat );
    308             g_object_set( text_renderer, "text", name, NULL );
    309             gtk_cell_renderer_get_size( text_renderer,
    310                                         widget, NULL, NULL, NULL, &w1, &h1 );
    311             str = g_markup_printf_escaped( "<small>%s</small>", shortStatus );
    312             g_object_set( text_renderer, "markup", str, NULL );
    313             gtk_cell_renderer_get_size( text_renderer,
    314                                         widget, NULL, NULL, NULL, &w2, &h2 );
    315             h += MAX( h1, h2 );
    316             w = MAX( w, w1 + GUI_PAD_BIG + w2 );
    317             g_free( str );
    318             g_free( shortStatus );
    319         }
     449            get_size_minimal( TORRENT_CELL_RENDERER( cell ), widget, &w, &h );
    320450        else
    321         {
    322             int    w1, h1;
    323             char * progressString = getProgressString( tor, info, torStat );
    324             str = g_markup_printf_escaped( "<b>%s</b>\n<small>%s</small>",
    325                                            name, progressString );
    326             g_object_set( text_renderer, "markup", str, NULL );
    327             gtk_cell_renderer_get_size( text_renderer,
    328                                         widget, NULL, NULL, NULL, &w1, &h1 );
    329             h += h1;
    330             w = MAX( w, w1 );
    331             g_free( str );
    332             g_free( progressString );
    333         }
    334 
    335         /* below the progressbar */
    336         if( !p->minimal )
    337         {
    338             int    w1, h1;
    339             char * statusString = getStatusString( torStat );
    340             str = g_markup_printf_escaped( "<small>%s</small>",
    341                                            statusString );
    342             g_object_set( text_renderer, "markup", str, NULL );
    343             gtk_cell_renderer_get_size( text_renderer,
    344                                         widget, NULL, NULL, NULL, &w1, &h1 );
    345             h += h1;
    346             w = MAX( w, w1 );
    347             g_free( str );
    348             g_free( statusString );
    349         }
    350 
    351         h += p->bar_height;
    352 
    353         if( cell_area )
    354         {
     451            get_size_full( TORRENT_CELL_RENDERER( cell ), widget, &w, &h );
     452
     453        if( width )
     454            *width = w;
     455
     456        if( height )
     457            *height = h;
     458
     459        if( cell_area ) {
    355460            if( x_offset ) *x_offset = 0;
    356             if( y_offset )
    357             {
    358                 *y_offset = 0.5 *
    359                             ( cell_area->height - ( h + ( 2 * cell->ypad ) ) );
     461            if( y_offset ) {
     462                *y_offset = 0.5 * ( cell_area->height - ( h + ( 2 * cell->ypad ) ) );
    360463                *y_offset = MAX( *y_offset, 0 );
    361464            }
    362465        }
    363 
    364         *width = w + cell->xpad * 2;
    365         *height = h + cell->ypad * 2;
    366     }
    367 }
    368 
    369 static void
    370 torrent_cell_renderer_render(
    371     GtkCellRenderer *                  cell,
    372     GdkDrawable *                      window,
    373     GtkWidget *                        widget,
    374     GdkRectangle *
    375                                        background_area,
    376     GdkRectangle         * cell_area   UNUSED,
    377     GdkRectangle         * expose_area UNUSED,
    378     GtkCellRendererState               flags )
     466    }
     467}
     468
     469static void
     470render_minimal( TorrentCellRenderer   * cell,
     471                GdkDrawable           * window,
     472                GtkWidget             * widget,
     473                GdkRectangle          * background_area,
     474                GdkRectangle          * cell_area UNUSED,
     475                GdkRectangle          * expose_area UNUSED,
     476                GtkCellRendererState    flags )
     477{
     478    int w, h;
     479    GdkRectangle icon_area;
     480    GdkRectangle name_area;
     481    GdkRectangle stat_area;
     482    GdkRectangle prog_area;
     483    GdkRectangle fill_area;
     484    const char * name;
     485    char * status;
     486    GdkPixbuf * icon;
     487    GtkCellRenderer * text_renderer;
     488
     489    struct TorrentCellRendererPrivate * p = cell->priv;
     490    const tr_torrent * tor = p->tor;
     491    const tr_stat * st = tr_torrentStatCached( (tr_torrent*)tor );
     492    const gboolean active = st->activity != TR_STATUS_STOPPED;
     493    const double percentDone = MAX( 0.0, st->percentDone );
     494
     495    icon = get_icon( tor, MINIMAL_ICON_SIZE, widget );
     496    name = tr_torrentInfo( tor )->name;
     497    status = getShortStatusString( st );
     498
     499    /* get the cell dimensions */
     500    g_object_set( p->icon_renderer, "pixbuf", icon, NULL );
     501    gtk_cell_renderer_get_size( p->icon_renderer, widget, NULL, NULL, NULL, &w, &h );
     502    icon_area.width = w;
     503    icon_area.height = h;
     504    text_renderer = get_text_renderer( st, cell );
     505    g_object_set( text_renderer, "text", name, "ellipsize", PANGO_ELLIPSIZE_NONE, "scale", 1.0, NULL );
     506    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
     507    name_area.width = w;
     508    name_area.height = h;
     509    g_object_set( text_renderer, "text", status, "scale", SMALL_SCALE, NULL );
     510    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
     511    stat_area.width = w;
     512    stat_area.height = h;
     513
     514    /**
     515    *** LAYOUT
     516    **/
     517
     518    fill_area = *background_area;
     519    fill_area.x += cell->parent.xpad;
     520    fill_area.y += cell->parent.ypad;
     521    fill_area.width -= cell->parent.xpad * 2;
     522    fill_area.height -= cell->parent.ypad * 2;
     523
     524    /* icon */
     525    icon_area.x = fill_area.x;
     526    icon_area.y = fill_area.y + ( fill_area.height - icon_area.height ) / 2;
     527
     528    /* short status (right justified) */
     529    stat_area.x = fill_area.x + fill_area.width - stat_area.width;
     530    stat_area.y = fill_area.y + ( name_area.height - stat_area.height ) / 2;
     531
     532    /* name */
     533    name_area.x = icon_area.x + icon_area.width + GUI_PAD;
     534    name_area.y = fill_area.y;
     535    name_area.width = stat_area.x - GUI_PAD - name_area.x;
     536
     537    /* progressbar */
     538    prog_area.x = name_area.x;
     539    prog_area.y = name_area.y + name_area.height;
     540    prog_area.width = name_area.width + GUI_PAD + stat_area.width;
     541    prog_area.height = p->bar_height;
     542
     543    /**
     544    *** RENDER
     545    **/
     546   
     547    g_object_set( p->icon_renderer, "pixbuf", icon, "sensitive", active, NULL );
     548    gtk_cell_renderer_render( p->icon_renderer, window, widget, &icon_area, &icon_area, &icon_area, flags );
     549    g_object_set( text_renderer, "text", status, "scale", SMALL_SCALE, "sensitive", active, "ellipsize", PANGO_ELLIPSIZE_END, NULL );
     550    gtk_cell_renderer_render( text_renderer, window, widget, &stat_area, &stat_area, &stat_area, flags );
     551    g_object_set( text_renderer, "text", name, "scale", 1.0, NULL );
     552    gtk_cell_renderer_render( text_renderer, window, widget, &name_area, &name_area, &name_area, flags );
     553    g_object_set( p->progress_renderer, "value", (int)(percentDone*100.0), "text", "", "sensitive", active, NULL );
     554    gtk_cell_renderer_render( p->progress_renderer, window, widget, &prog_area, &prog_area, &prog_area, flags );
     555
     556    /* cleanup */
     557    g_free( status );
     558}
     559
     560static void
     561render_full( TorrentCellRenderer   * cell,
     562             GdkDrawable           * window,
     563             GtkWidget             * widget,
     564             GdkRectangle          * background_area,
     565             GdkRectangle          * cell_area UNUSED,
     566             GdkRectangle          * expose_area UNUSED,
     567             GtkCellRendererState    flags )
     568{
     569    int w, h;
     570    GdkRectangle fill_area;
     571    GdkRectangle icon_area;
     572    GdkRectangle name_area;
     573    GdkRectangle stat_area;
     574    GdkRectangle prog_area;
     575    GdkRectangle prct_area;
     576    const char * name;
     577    char * status;
     578    char * progress;
     579    GdkPixbuf * icon;
     580    GtkCellRenderer * text_renderer;
     581
     582    struct TorrentCellRendererPrivate * p = cell->priv;
     583    const tr_torrent * tor = p->tor;
     584    const tr_stat * st = tr_torrentStatCached( (tr_torrent*)tor );
     585    const tr_info * inf = tr_torrentInfo( tor );
     586    const gboolean active = st->activity != TR_STATUS_STOPPED;
     587    const double percentDone = MAX( 0.0, st->percentDone );
     588
     589    icon = get_icon( tor, FULL_ICON_SIZE, widget );
     590    name = inf->name;
     591    status = getStatusString( st );
     592    progress = getProgressString( tor, inf, st );
     593
     594    /* get the idealized cell dimensions */
     595    g_object_set( p->icon_renderer, "pixbuf", icon, NULL );
     596    gtk_cell_renderer_get_size( p->icon_renderer, widget, NULL, NULL, NULL, &w, &h );
     597    icon_area.width = w;
     598    icon_area.height = h;
     599    text_renderer = get_text_renderer( st, cell );
     600    g_object_set( text_renderer, "text", name, "weight", PANGO_WEIGHT_BOLD, "ellipsize", PANGO_ELLIPSIZE_NONE, "scale", 1.0, NULL );
     601    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
     602    name_area.width = w;
     603    name_area.height = h;
     604    g_object_set( text_renderer, "text", progress, "weight", PANGO_WEIGHT_NORMAL, "scale", SMALL_SCALE, NULL );
     605    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
     606    prog_area.width = w;
     607    prog_area.height = h;
     608    g_object_set( text_renderer, "text", status, NULL );
     609    gtk_cell_renderer_get_size( text_renderer, widget, NULL, NULL, NULL, &w, &h );
     610    stat_area.width = w;
     611    stat_area.height = h;
     612   
     613    /**
     614    *** LAYOUT
     615    **/
     616
     617    fill_area = *background_area;
     618    fill_area.x += cell->parent.xpad;
     619    fill_area.y += cell->parent.ypad;
     620    fill_area.width -= cell->parent.xpad * 2;
     621    fill_area.height -= cell->parent.ypad * 2;
     622
     623    /* icon */
     624    icon_area.x = fill_area.x;
     625    icon_area.y = fill_area.y + ( fill_area.height - icon_area.height ) / 2;
     626
     627    /* name */
     628    name_area.x = icon_area.x + icon_area.width + GUI_PAD;
     629    name_area.y = fill_area.y;
     630    name_area.width = fill_area.width - GUI_PAD - icon_area.width - GUI_PAD_SMALL;
     631
     632    /* prog */
     633    prog_area.x = name_area.x;
     634    prog_area.y = name_area.y + name_area.height;
     635    prog_area.width = name_area.width;
     636
     637    /* progressbar */
     638    prct_area.x = prog_area.x;
     639    prct_area.y = prog_area.y + prog_area.height + GUI_PAD_SMALL;
     640    prct_area.width = prog_area.width;
     641    prct_area.height = p->bar_height;
     642
     643    /* status */
     644    stat_area.x = prct_area.x;
     645    stat_area.y = prct_area.y + prct_area.height + GUI_PAD_SMALL;
     646    stat_area.width = prct_area.width;
     647
     648    /**
     649    *** RENDER
     650    **/
     651   
     652    g_object_set( p->icon_renderer, "pixbuf", icon, "sensitive", active, NULL );
     653    gtk_cell_renderer_render( p->icon_renderer, window, widget, &icon_area, &icon_area, &icon_area, flags );
     654    g_object_set( text_renderer, "text", name, "scale", 1.0, "sensitive", active, "ellipsize", PANGO_ELLIPSIZE_END, "weight", PANGO_WEIGHT_BOLD, NULL );
     655    gtk_cell_renderer_render( text_renderer, window, widget, &name_area, &name_area, &name_area, flags );
     656    g_object_set( text_renderer, "text", progress, "scale", SMALL_SCALE, "weight", PANGO_WEIGHT_NORMAL, NULL );
     657    gtk_cell_renderer_render( text_renderer, window, widget, &prog_area, &prog_area, &prog_area, flags );
     658    g_object_set( p->progress_renderer, "value", (int)(percentDone*100.0), "text", "", "sensitive", active, NULL );
     659    gtk_cell_renderer_render( p->progress_renderer, window, widget, &prct_area, &prct_area, &prct_area, flags );
     660    g_object_set( text_renderer, "text", status, NULL );
     661    gtk_cell_renderer_render( text_renderer, window, widget, &stat_area, &stat_area, &stat_area, flags );
     662
     663    /* cleanup */
     664    g_free( status );
     665    g_free( progress );
     666}
     667
     668static void
     669torrent_cell_renderer_render( GtkCellRenderer       * cell,
     670                              GdkDrawable           * window,
     671                              GtkWidget             * widget,
     672                              GdkRectangle          * background_area,
     673                              GdkRectangle          * cell_area,
     674                              GdkRectangle          * expose_area,
     675                              GtkCellRendererState    flags )
    379676{
    380677    TorrentCellRenderer * self = TORRENT_CELL_RENDERER( cell );
     
    387684    if( self && self->priv->tor )
    388685    {
    389         const tr_torrent *                  tor = self->priv->tor;
    390         const tr_info *                     info = tr_torrentInfo( tor );
    391         const char *                        name = info->name;
    392         const tr_stat *                     torStat =
    393             tr_torrentStatCached( (tr_torrent*)tor );
    394         GdkRectangle                        my_bg;
    395         GdkRectangle                        my_cell;
    396         GdkRectangle                        my_expose;
    397         int                                 w, h;
    398686        struct TorrentCellRendererPrivate * p = self->priv;
    399         GtkCellRenderer * text_renderer = torStat->error != 0
    400                                         ? p->text_renderer_err
    401                                         : p->text_renderer;
    402         const gboolean isActive = torStat->activity != TR_STATUS_STOPPED;
    403 
    404         my_bg = *background_area;
    405         my_bg.x += cell->xpad;
    406         my_bg.y += cell->ypad;
    407         my_bg.width -= cell->xpad * 2;
    408         my_cell = my_expose = my_bg;
    409 
    410         g_object_set( text_renderer, "sensitive", isActive, NULL );
    411         g_object_set( p->progress_renderer, "sensitive", isActive, NULL );
    412 
    413         /* above the progressbar */
    414         if( !p->minimal )
    415         {
    416             char * progressString = getProgressString( tor, info, torStat );
    417             char * str = g_markup_printf_escaped(
    418                 "<b>%s</b>\n<small>%s</small>",
    419                 name, progressString );
    420             g_object_set( text_renderer, "markup", str,
    421                           "ellipsize", PANGO_ELLIPSIZE_NONE,
    422                           NULL );
    423             gtk_cell_renderer_get_size( text_renderer,
    424                                         widget, NULL, NULL, NULL, &w, &h );
    425             my_bg.height     =
    426                 my_cell.height   =
    427                     my_expose.height = h;
    428             g_object_set( text_renderer, "ellipsize", PANGO_ELLIPSIZE_END,
    429                           NULL );
    430             gtk_cell_renderer_render( text_renderer,
    431                                       window, widget,
    432                                       &my_bg, &my_cell, &my_expose, flags );
    433             my_bg.y += h;
    434             my_cell.y += h;
    435             my_expose.y += h;
    436 
    437             g_free( str );
    438             g_free( progressString );
    439         }
     687        if( p->minimal )
     688            render_minimal( self, window, widget, background_area, cell_area, expose_area, flags );
    440689        else
    441         {
    442             char *       statusStr = getShortStatusString( torStat );
    443             char *       str = g_markup_printf_escaped( "<small>%s</small>",
    444                                                         statusStr );
    445             int          w1, w2, h1, h2, tmp_h;
    446             GdkRectangle tmp_bg, tmp_cell, tmp_expose;
    447 
    448             /* get the dimensions for the name */
    449             g_object_set( text_renderer, "text", name,
    450                           "ellipsize", PANGO_ELLIPSIZE_NONE,
    451                           NULL );
    452             gtk_cell_renderer_get_size( text_renderer,
    453                                         widget, NULL, NULL, NULL, &w1, &h1 );
    454 
    455             /* get the dimensions for the short status string */
    456             g_object_set( text_renderer, "markup", str,
    457                           "ellipsize", PANGO_ELLIPSIZE_NONE,
    458                           NULL );
    459             gtk_cell_renderer_get_size( text_renderer,
    460                                         widget, NULL, NULL, NULL, &w2, &h2 );
    461 
    462             tmp_h = MAX( h1, h2 );
    463 
    464             /* short status */
    465             tmp_bg.x = my_bg.width - w2;
    466             tmp_bg.y = my_bg.y + ( h2 - h1 ) / 2;
    467             tmp_bg.width = w2;
    468             tmp_bg.height = tmp_h;
    469             tmp_expose = tmp_cell = tmp_bg;
    470             g_object_set( text_renderer, "markup", str,
    471                           "ellipsize", PANGO_ELLIPSIZE_END,
    472                           NULL );
    473             gtk_cell_renderer_render( text_renderer,
    474                                       window, widget,
    475                                       &tmp_bg, &tmp_cell, &tmp_expose,
    476                                       flags );
    477 
    478             /* name */
    479             tmp_bg.x = my_bg.x;
    480             tmp_bg.width = my_bg.width - w2 - GUI_PAD_BIG;
    481             tmp_expose = tmp_cell = tmp_bg;
    482             g_object_set( text_renderer, "text", name,
    483                           "ellipsize", PANGO_ELLIPSIZE_END,
    484                           NULL );
    485             gtk_cell_renderer_render( text_renderer,
    486                                       window, widget,
    487                                       &tmp_bg, &tmp_cell, &tmp_expose,
    488                                       flags );
    489 
    490             my_bg.y = tmp_bg.y + tmp_bg.height;
    491             my_cell.y = tmp_cell.y + tmp_cell.height;
    492             my_expose.y = tmp_expose.y + tmp_cell.height;
    493 
    494             g_free( str );
    495             g_free( statusStr );
    496         }
    497 
    498         /* the progressbar */
    499         my_cell.height = p->bar_height;
    500         if( 1 )
    501         {
    502             const double percent = MAX( 0.0, torStat->percentDone );
    503             g_object_set( p->progress_renderer, "value",
    504                           (int)( percent * 100.0 ),
    505                           "text", "",
    506                           NULL );
    507             gtk_cell_renderer_render( p->progress_renderer,
    508                                       window, widget,
    509                                       &my_cell, &my_cell, &my_cell, flags );
    510         }
    511         my_bg.y     += my_cell.height;
    512         my_cell.y   += my_cell.height;
    513         my_expose.y += my_cell.height;
    514 
    515         /* below progressbar */
    516         if( !p->minimal )
    517         {
    518             char * statusString = getStatusString( torStat );
    519             char * str = g_markup_printf_escaped( "<small>%s</small>",
    520                                                   statusString );
    521             g_object_set( text_renderer, "markup", str,
    522                           "ellipsize", PANGO_ELLIPSIZE_END,
    523                           NULL );
    524             gtk_cell_renderer_get_size( text_renderer,
    525                                         widget, NULL, NULL, NULL, &w, &h );
    526             my_bg.height      =
    527                 my_cell.height    =
    528                     my_expose.height  = h;
    529             gtk_cell_renderer_render( text_renderer,
    530                                       window, widget,
    531                                       &my_bg, &my_cell, &my_expose, flags );
    532 
    533             g_free( str );
    534             g_free( statusString );
    535         }
     690            render_full( self, window, widget, background_area, cell_area, expose_area, flags );
    536691    }
    537692
     
    606761        g_object_unref( G_OBJECT( r->priv->text_renderer_err ) );
    607762        g_object_unref( G_OBJECT( r->priv->progress_renderer ) );
     763        g_object_unref( G_OBJECT( r->priv->icon_renderer ) );
    608764        r->priv = NULL;
    609765    }
     
    665821    p->tor = NULL;
    666822    p->text_renderer = gtk_cell_renderer_text_new( );
     823    g_object_set( p->text_renderer, "xpad", 0, "ypad", 0, NULL );
    667824    p->text_renderer_err = gtk_cell_renderer_text_new(  );
     825    g_object_set( p->text_renderer_err, "xpad", 0, "ypad", 0, NULL );
    668826    p->progress_renderer = gtk_cell_renderer_progress_new(  );
     827    p->icon_renderer = gtk_cell_renderer_pixbuf_new(  );
    669828    g_object_set( p->text_renderer_err, "foreground", "red", NULL );
    670829    tr_object_ref_sink( p->text_renderer );
    671830    tr_object_ref_sink( p->text_renderer_err );
    672831    tr_object_ref_sink( p->progress_renderer );
     832    tr_object_ref_sink( p->icon_renderer );
    673833
    674834    p->bar_height = DEFAULT_BAR_HEIGHT;
Note: See TracChangeset for help on using the changeset viewer.