Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

gtask-cell-renderer-basic.c

Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include <stdio.h>
00003 #include <libart_lgpl/libart.h>
00004 #include <eel/eel.h>
00005 
00006 #include <gtask-ui/gtask-cell-renderer-basic.h>
00007 
00008 #include "gtask-internals.h"
00009 #include "gtask-ui-util.h"
00010 
00012 /* @{ */
00013 
00017 #define PADDING 6
00018 
00019 enum {
00020   PROP_0,
00021   C_PROP_PROGRESS,
00022   C_PROP_TITLE,
00023   C_PROP_STATUS_MESSAGE,
00024   C_PROP_ACTIVITY_STATE,
00025   C_PROP_TIME_LEFT,
00026   C_PROP_PREVIEW,
00027   C_PROP_PREVIEW_IS_THUMB,
00028   C_PROP_THUMBNAIL_FRAME
00029 }; 
00030 
00031 typedef struct _GTaskBasicInfo {
00032     PangoLayout *title_prefix;
00033     PangoLayout *title;
00034     int          title_width;
00035     int          title_height;
00036 
00037     PangoLayout *status_prefix;
00038     PangoLayout *status;
00039     int          status_width;
00040     int          status_height;
00041 
00042     PangoLayout *time_prefix;
00043     PangoLayout *time;
00044     int          time_width;
00045     int          time_height;
00046 
00047     PangoLayout *actions_layout;
00048     int          actions_width;
00049     int          actions_height;
00050 
00051     GdkPixbuf   *preview;
00052     int          preview_width;
00053     int          preview_height;
00054 
00055     int         center_x;
00056     int         right_x;
00057 
00058     int         max_title_width;
00059     int         text_spacer_width;
00060     int         text_spacer_height;
00061 } GTaskBasicInfo;
00062 
00063 static gpointer parent_class;
00064 
00065 /* forward declarations */
00066 static GTaskBasicInfo *
00067 gtask_cell_renderer_basic_get_sizing_info( GTaskCellRendererBasic *cell,
00068                                            GtkWidget *widget,
00069                                            guint x,
00070                                            guint y );
00071 static void
00072 gtask_cell_renderer_basic_fill_text_info( GTaskCellRendererBasic *cell,
00073                                           GTaskBasicInfo *info,
00074                                           GtkWidget *widget,
00075                                           gint center_size );
00076 
00077 static void
00078 gtask_basic_info_free( GTaskBasicInfo *info );
00079 
00080 static void
00081 gtask_cell_renderer_basic_init( GTaskCellRendererBasic *cell );
00082 
00083 static void
00084 gtask_cell_renderer_basic_class_init( GTaskCellRendererBasicClass *klass );
00085 
00086 static void
00087 gtask_cell_renderer_basic_finalize( GObject *object );
00088 
00089 static void
00090 gtask_cell_renderer_basic_get_property( GObject    *object,
00091                                         guint       param_id,
00092                                         GValue     *value,
00093                                         GParamSpec *pspec );
00094 
00095 static void
00096 gtask_cell_renderer_basic_set_property( GObject      *object,
00097                                         guint         param_id,
00098                                         const GValue *value,
00099                                         GParamSpec   *pspec );
00100 
00101 static void
00102 gtask_cell_renderer_basic_get_size( GtkCellRenderer *cell,
00103                                     GtkWidget       *widget,
00104                                     GdkRectangle    *cell_area,
00105                                     gint            *x_offset,
00106                                     gint            *y_offset,
00107                                     gint            *width,
00108                                     gint            *height );
00109 
00110 static void
00111 gtask_cell_renderer_basic_render( GtkCellRenderer *cell,
00112                                   GdkWindow       *window,
00113                                   GtkWidget       *widget,
00114                                   GdkRectangle    *background_area,
00115                                   GdkRectangle    *cell_area,
00116                                   GdkRectangle    *expose_area,
00117                                   guint            flags );
00118 
00119 GtkType gtask_cell_renderer_basic_get_type( ) {
00120         static GtkType type = 0;
00121 
00122         if( !type ) {
00123                 static const GTypeInfo info = {
00124                         sizeof( GTaskCellRendererBasicClass ),
00125                         NULL,           /* base_init */
00126                         NULL,           /* base_finalize */
00127                         (GClassInitFunc) gtask_cell_renderer_basic_class_init,
00128                         NULL,           /* class_finalize */
00129                         NULL,           /* class_data */
00130                         sizeof( GTaskCellRendererBasic ),
00131                         0,          /* n_preallocs */
00132                         (GInstanceInitFunc) gtask_cell_renderer_basic_init,
00133                 };
00134 
00135                 type = g_type_register_static( GTK_TYPE_CELL_RENDERER,
00136                                        "GTaskCellRendererBasic",
00137                                        &info,
00138                                        0);
00139         }
00140 
00141         return type;
00142 }
00143 
00144 static void
00145 gtask_cell_renderer_basic_init( GTaskCellRendererBasic *cell ) {
00146     GTaskCellRendererBasicPrivate *private;
00147     gchar                         *uri;
00148 
00149     private = g_new0( GTaskCellRendererBasicPrivate, 1 );
00150 
00151     private->progress = 0.0;
00152     private->title = NULL;
00153     private->status_msg = NULL;
00154     private->activity_state = GTASK_ACTIVITY_STATE_INACTIVE;
00155     private->time_left = GTASK_TIME_LEFT_UNKNOWN;
00156 
00157     cell->private = private;
00158 
00164     uri = g_build_filename( DATADIR,
00165                             "pixmaps",
00166                             "default-thumbnail-frame.png",
00167                             NULL );
00168 
00169     private->thumbnail_frame = gdk_pixbuf_new_from_file( uri, NULL );
00170 
00171     g_free( uri );
00172 }
00173 
00174 static void
00175 gtask_cell_renderer_basic_class_init( GTaskCellRendererBasicClass *klass ) {
00176         GObjectClass         *object_class = G_OBJECT_CLASS( klass );
00177         GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS( klass );
00178 
00179         parent_class = g_type_class_peek_parent( klass );
00180   
00181         object_class->finalize = gtask_cell_renderer_basic_finalize;
00182   
00183         object_class->get_property = gtask_cell_renderer_basic_get_property;
00184         object_class->set_property = gtask_cell_renderer_basic_set_property;
00185 
00186         cell_class->get_size = gtask_cell_renderer_basic_get_size;
00187         cell_class->render = gtask_cell_renderer_basic_render;
00188   
00189         g_object_class_install_property( object_class,
00190                                      C_PROP_PROGRESS,
00191                                      g_param_spec_float( "progress",
00192                                                          "Progress",
00193                                                          "Value of the progress bar.",
00194                                                          0.0, 1.0, 0.0,
00195                                                          G_PARAM_READWRITE ) );
00196         g_object_class_install_property( object_class,
00197                                      C_PROP_TITLE,
00198                                      g_param_spec_string( "title",
00199                                                           "Title",
00200                                                           "Title of the task.",
00201                                                           "",
00202                                                           G_PARAM_READWRITE ) );
00203 
00204         g_object_class_install_property( object_class,
00205                                      C_PROP_STATUS_MESSAGE,
00206                                      g_param_spec_string( "status-message",
00207                                                           "Status Message",
00208                                                           "Status message of the task.",
00209                                                           "",
00210                                                           G_PARAM_READWRITE ) );
00211 
00212         g_object_class_install_property( object_class,
00213                                      C_PROP_ACTIVITY_STATE,
00214                                      g_param_spec_enum( "activity-state",
00215                                                         "Task Activity State",
00216                                                         "The activity state of the task.",
00217                                                         GTASK_ACTIVITY_STATE_TYPE,
00218                                                         GTASK_ACTIVITY_STATE_INACTIVE,
00219                                                         G_PARAM_READWRITE ) );
00220 
00221         g_object_class_install_property( object_class,
00222                                      C_PROP_PREVIEW,
00223                                      g_param_spec_object( "preview",
00224                                                           "Preview",
00225                                                           "A thumbnail of the resultant file or something indicative of the task",
00226                                                           GDK_TYPE_PIXBUF,
00227                                                           G_PARAM_READWRITE ) );
00228         g_object_class_install_property( object_class,
00229                                      C_PROP_PREVIEW_IS_THUMB,
00230                                      g_param_spec_boolean( "preview-is-thumb",
00231                                                           "Preview is a Thumbnail",
00232                                                           "Whether or not the preview is a thumbnail (ie should we draw a frame around it or not",
00233                                                           TRUE,
00234                                                           G_PARAM_READWRITE ) );
00235         g_object_class_install_property( object_class,
00236                                      C_PROP_THUMBNAIL_FRAME,
00237                                      g_param_spec_object( "thumbnail-frame",
00238                                                           "Thumbnail Frame",
00239                                                           "The frame to place around all generated thumbnails",
00240                                                           GDK_TYPE_PIXBUF,
00241                                                           G_PARAM_READWRITE ) );
00242         g_object_class_install_property( object_class,
00243                                      C_PROP_TIME_LEFT,
00244                                      g_param_spec_long( "time-left",
00245                                                         "Time Left",
00246                                                         "The remaining time in seconds until the task is expected to be finished. If the time left is unknown use GTASK_TIME_LEFT_UNKNOWN (-1)",
00247                                                         -1,
00248                                                         G_MAXLONG,
00249                                                         GTASK_TIME_LEFT_UNKNOWN,
00250                                                         G_PARAM_READWRITE ) );
00251 }
00252 
00253 static void
00254 gtask_cell_renderer_basic_get_property( GObject    *object,
00255                                         guint       param_id,
00256                                         GValue     *value,
00257                                         GParamSpec *pspec )
00258 {
00259         GTaskCellRendererBasic        *cell = GTASK_CELL_RENDERER_BASIC( object );
00260     GTaskCellRendererBasicPrivate *private = cell->private;
00261 
00262         switch( param_id ) {
00263                 case C_PROP_PROGRESS:
00264                         g_value_set_float( value, private->progress );
00265                         break;
00266         case C_PROP_TITLE:
00267             g_value_set_string( value, private->title );
00268             break;
00269         case C_PROP_STATUS_MESSAGE:
00270             g_value_set_string( value, private->status_msg );
00271             break;
00272         case C_PROP_ACTIVITY_STATE:
00273             g_value_set_int( value, private->activity_state );
00274             break;
00276         case C_PROP_PREVIEW:
00277             g_value_set_object( value, private->preview );
00278             break;
00279         case C_PROP_PREVIEW_IS_THUMB:
00280             g_value_set_boolean( value, private->preview_is_thumb );
00281             break;
00282         case C_PROP_TIME_LEFT:
00283             g_value_set_long( value, private->time_left );
00284             break;
00285                 default:
00286                         G_OBJECT_WARN_INVALID_PROPERTY_ID( object, param_id, pspec );
00287         }
00288 }
00289 
00290 static void
00291 gtask_cell_renderer_basic_set_property( GObject       *object,
00292                                         guint         param_id,
00293                                         const GValue *value,
00294                                         GParamSpec   *pspec )
00295 {
00296         GTaskCellRendererBasic        *cell = GTASK_CELL_RENDERER_BASIC( object );
00297     GTaskCellRendererBasicPrivate *private = cell->private;
00298 
00299         switch( param_id ) {
00300                 case C_PROP_PROGRESS:
00301                         private->progress = g_value_get_float( value );
00302                 g_object_notify( object, "progress" );
00303                         break;
00304         case C_PROP_TITLE:
00305             if( private->title )
00306                 g_free( private->title );
00307 
00308             private->title = g_strdup( g_value_get_string( value ) );
00309             g_object_notify( object, "title" );
00310             break;
00311         case C_PROP_STATUS_MESSAGE:
00312             if( private->status_msg )
00313                 g_free( private->status_msg );
00314 
00315             private->status_msg = g_strdup( g_value_get_string( value ) );
00316             g_object_notify( object, "status-message" );
00317             break;
00318         case C_PROP_ACTIVITY_STATE:
00319             private->activity_state = g_value_get_enum( value );
00320             g_object_notify( object, "activity-state" );
00321             break;
00322         case C_PROP_PREVIEW:
00323             private->preview = g_value_get_object( value );
00324             g_object_notify( object, "preview" );
00325             break;
00326         case C_PROP_PREVIEW_IS_THUMB:
00327             private->preview_is_thumb = g_value_get_boolean( value );
00328             g_object_notify( object, "preview-is-thumb" );
00329             break;
00330         case C_PROP_TIME_LEFT:
00331             private->time_left = g_value_get_long( value );
00332             g_object_notify( object, "time-left" );
00333             break;
00334                 default:
00335                         G_OBJECT_WARN_INVALID_PROPERTY_ID( object, param_id, pspec );
00336         }
00337 }
00338 
00339 #define ELLIPSIS "..."
00340 
00341 /* the following is a variation on the ellipsizing-label from eel,
00342  * I basically just added support for marking up portions of the string */
00343 
00344 /* the following modified from eel-pango-extensions.c */
00345 static int
00346 measure_string_width (const char  *string, PangoLayout *layout) {
00347     int width;
00348 
00349     pango_layout_set_markup (layout, string, -1);
00350     pango_layout_get_pixel_size (layout, &width, NULL);
00351 
00352     return width;
00353 }
00354 
00355 static void
00356 compute_character_widths( const char    *format_string,
00357                           const char    *string,
00358                           PangoLayout   *layout,
00359                           int           *char_len_return,
00360                           int          **widths_return,
00361                           int          **cuts_return )
00362 {
00363     int *widths;
00364     int *offsets;
00365     int *cuts;
00366     int char_len;
00367     int byte_len;
00368     const char *p;
00369     int i;
00370     PangoLayoutIter *iter;
00371     PangoLogAttr *attrs;
00372 
00373 #define BEGINS_UTF8_CHAR(x) (((x) & 0xc0) != 0x80)
00374 
00375     char_len = g_utf8_strlen( string, -1 );
00376     byte_len = strlen( string );
00377 
00378     widths = g_new (int, char_len);
00379     offsets = g_new (int, byte_len);
00380 
00381     /* Create a translation table from byte index to char offset */
00382     p = string;
00383     i = 0;
00384     while (*p) {
00385         int byte_index = p - string;
00386 
00387         if (BEGINS_UTF8_CHAR (*p)) {
00388             offsets[byte_index] = i;
00389             ++i;
00390         } else {
00391             offsets[byte_index] = G_MAXINT; /* segv if we try to use this */
00392         }
00393 
00394         ++p;
00395     }
00396 
00397     /* Now fill in the widths array */
00398     pango_layout_set_markup (layout, format_string, -1);
00399    iter = pango_layout_get_iter (layout);
00400 
00401     do {
00402         PangoRectangle extents;
00403         int byte_index;
00404 
00405         byte_index = pango_layout_iter_get_index (iter);
00406 
00407         if (byte_index < byte_len) {
00408             pango_layout_iter_get_char_extents (iter, &extents);
00409 
00410             g_assert (BEGINS_UTF8_CHAR (string[byte_index]));
00411             g_assert (offsets[byte_index] < char_len);
00412 
00413             widths[offsets[byte_index]] = PANGO_PIXELS (extents.width);
00414         }
00415 
00416     } while (pango_layout_iter_next_char (iter));
00417 
00418     pango_layout_iter_free (iter);
00419 
00420     g_free (offsets);
00421 
00422     *widths_return = widths;
00423 
00424     /* Now compute character offsets that are legitimate places to
00425      * chop the string
00426      */
00427     attrs = g_new (PangoLogAttr, char_len + 1);
00428 
00429     pango_get_log_attrs (string, byte_len, -1,
00430                  pango_context_get_language (
00431                      pango_layout_get_context (layout)),
00432                  attrs,
00433                  char_len + 1);
00434 
00435     cuts = g_new (int, char_len);
00436     i = 0;
00437     while (i < char_len) {
00438         cuts[i] = attrs[i].is_cursor_position;
00439 
00440         ++i;
00441     }
00442 
00443     g_free (attrs);
00444     *cuts_return = cuts;
00445 
00446     *char_len_return = char_len;
00447 }
00448 
00449 static char *
00450 eel_string_ellipsize_end (const char *format_string,
00451                           const char *string,
00452                           PangoLayout *layout,
00453                           int width)
00454 {
00455     int resulting_width;
00456     int *cuts;
00457     int *widths;
00458     int char_len;
00459     const char *p;
00460     int truncate_offset;
00461     char *result;
00462 
00463     /* See explanatory comments in ellipsize_start */
00464 
00465     if ( !string || *string == '\0')
00466         return g_strdup ("");
00467 
00468     resulting_width = measure_string_width (format_string, layout);
00469 
00470     if (resulting_width <= width) {
00471         return g_strdup (string);
00472     }
00473 
00474     width -= measure_string_width (ELLIPSIS, layout);
00475 
00476     if (width < 0) {
00477         return g_strdup ("");
00478     }
00479 
00480     compute_character_widths (format_string, string, layout, &char_len, &widths, &cuts);
00481 
00482         for (truncate_offset = char_len - 1; truncate_offset > 0; truncate_offset--) {
00483             resulting_width -= widths[truncate_offset];
00484             if (resulting_width <= width &&
00485             cuts[truncate_offset]) {
00486             break;
00487             }
00488         }
00489 
00490     g_free (cuts);
00491     g_free (widths);
00492 
00493     p = g_utf8_offset_to_pointer (string, truncate_offset);
00494 
00495     result = g_malloc ((p - string) + strlen (ELLIPSIS) + 1);
00496     memcpy (result, string, (p - string));
00497     strcpy (result + (p - string), ELLIPSIS);
00498 
00499     return result;
00500 }
00501 /* end of functions borrowed and modified from eel-pango-extensions.c */
00502 
00503 /* have optional prefix layout, always request that plus 10 blank
00504  * spaces of space
00505  *
00506  * then run string through a slightly modified eel-pango foo
00507  * to chop off what needs to go
00508  */
00509 
00510 static GTaskBasicInfo *
00511 gtask_cell_renderer_basic_get_sizing_info( GTaskCellRendererBasic *cell,
00512                                            GtkWidget *widget,
00513                                            guint x,
00514                                            guint y )
00515 {
00516     GTaskCellRendererBasicPrivate *private = cell->private;
00517     GTaskBasicInfo                *info    = g_new0( GTaskBasicInfo, 1 );
00518     PangoLayout                   *spacer_layout;
00519 
00520     info->title_width = 0;
00521     info->title_height = 0;
00522 
00523     spacer_layout = gtk_widget_create_pango_layout( widget, NULL );
00524 
00525     pango_layout_set_markup( spacer_layout, 
00526                              "<span size=\"medium\">          </span>",
00527                              -1 );
00528     pango_layout_get_pixel_size( spacer_layout,
00529                                  &(info->text_spacer_width),
00530                                  &(info->text_spacer_height) );
00531 
00532     info->status_prefix = gtk_widget_create_pango_layout( widget, NULL );
00533     pango_layout_set_markup( info->status_prefix,
00534                              "<span size=\"small\">    <b>Info:</b> </span>",
00535                              -1 );
00536 
00537     pango_layout_get_pixel_size( info->status_prefix,
00538                                  &(info->status_width),
00539                                  &(info->status_height) );
00540 
00541     info->time_prefix = gtk_widget_create_pango_layout( widget, NULL );
00542     pango_layout_set_markup( info->time_prefix,
00543                             "<span size=\"small\">    <b>Time Left:</b> </span>",
00544                             -1 );
00545 
00546     pango_layout_get_pixel_size( info->time_prefix,
00547                                  &(info->time_width),
00548                                  &(info->time_height) );
00549 
00550     info->actions_layout = gtk_widget_create_pango_layout( widget, NULL );
00551     pango_layout_set_markup( info->actions_layout,
00552                              "<span size=\"small\"><b>Actions:</b></span>",
00553                              -1 );
00554 
00555     pango_layout_get_pixel_size( info->actions_layout,
00556                                  &(info->actions_width),
00557                                  &(info->actions_height) );
00558 
00559     info->preview_height = info->text_spacer_height + info->status_height + info->time_height;
00560     info->preview_width = info->preview_height;
00561 
00562     if( private->preview )
00563         info->preview = private->preview;
00564 
00565     info->center_x = x + PADDING + info->preview_width + 12;
00566     info->right_x = info->center_x + MAX( info->title_width,
00567                                           MAX( info->status_width, 
00568                                                info->time_width ) ) + 12;
00569 
00570 
00571     info->max_title_width = MAX( info->status_width, info->time_width );
00572 
00573     return info;
00574 }
00575 
00576 void
00577 gtask_cell_renderer_basic_fill_text_info( GTaskCellRendererBasic *cell,
00578                                           GTaskBasicInfo *info,
00579                                           GtkWidget *widget,
00580                                           gint center_width )
00581 {
00582     GTaskCellRendererBasicPrivate *private = cell->private;
00583     PangoLayout                   *layout;
00584     GString                       *markup  = g_string_new( NULL );
00585     GString                       *tmp = g_string_new( NULL );
00586     char                          *text;
00587 
00588     /* title */
00589     info->title = layout = gtk_widget_create_pango_layout( widget, NULL );
00590 
00591     g_string_printf( markup, "<span size=\"medium\"><b>%s</b></span>",
00592                      private->title );
00593 
00594     text = eel_string_ellipsize_end( markup->str, private->title, layout, center_width );
00595 
00596     g_string_printf( markup, "<span size=\"medium\"><b>%s</b></span>",
00597                      text );
00598 
00599     pango_layout_set_markup( layout, markup->str, -1 );
00600 
00601     g_free( text );
00602 
00603     /* info */
00604     info->status = layout = gtk_widget_create_pango_layout( widget, NULL );
00605 
00609     g_string_printf( markup, "<span size=\"small\">%s</span>",
00610                      private->status_msg );
00611 
00612     text = eel_string_ellipsize_end( markup->str, private->status_msg, layout, center_width - info->status_width );
00613 
00614     g_string_printf( markup, "<span size=\"small\">%s</span>",
00615                      text );
00616 
00617     pango_layout_set_markup( layout, markup->str, -1 );
00618 
00619     g_free( text );
00620 
00621     /* time left */
00622     info->time = layout = gtk_widget_create_pango_layout( widget, NULL );
00623 
00624     if( private->activity_state == GTASK_ACTIVITY_STATE_COMPLETED ) {
00625         g_string_assign( markup, "<span size=\"small\">None</span>" );
00626         g_string_assign( tmp, "None" );
00627     } else if( private->time_left < 0 ) {
00628         g_string_assign( markup, "<span size=\"small\">Unknown</span>" );
00629         g_string_assign( tmp, "Unknown" );
00630     } else {
00631         g_string_printf( markup, "<span size=\"small\">%ld seconds</span>", private->time_left );
00632         g_string_printf( tmp, "%ld seconds", private->time_left );
00633     }
00634 
00635     text = eel_string_ellipsize_end( markup->str, tmp->str, layout, center_width - info->time_width );
00636 
00637     g_string_printf( markup, "<span size=\"small\">%s</span>", tmp->str );
00638 
00639     pango_layout_set_markup( layout, markup->str, -1 );
00640 
00641     g_free( text );
00642 
00643     g_string_free( markup, TRUE );
00644     g_string_free( tmp, TRUE );
00645 }
00646 
00647 static void
00648 gtask_basic_info_free( GTaskBasicInfo *info ) {
00649     if( info->title )
00650         g_object_unref( info->title );
00651 
00652     if( info->status_prefix )
00653         g_object_unref( info->status_prefix );
00654 
00655     if( info->status )
00656         g_object_unref( info->status );
00657 
00658     if( info->time_prefix )
00659         g_object_unref( info->time_prefix );
00660 
00661     if( info->time )
00662         g_object_unref( info->time );
00663 
00664     if( info->actions_layout )
00665         g_object_unref( info->actions_layout );
00666 
00667 //    gdk_pixbuf_unref( info->preview );
00668 
00669     g_free( info );
00670 }
00671 
00672 static void
00673 gtask_cell_renderer_basic_get_size( GtkCellRenderer *cell,
00674                                     GtkWidget       *widget,
00675                                     GdkRectangle    *cell_area,
00676                                     gint            *x_offset,
00677                                     gint            *y_offset,
00678                                     gint            *width,
00679                                     gint            *height)
00680 {
00681     GTaskCellRendererBasic *cell_basic = GTASK_CELL_RENDERER_BASIC( cell );
00682     GTaskBasicInfo *info = gtask_cell_renderer_basic_get_sizing_info( cell_basic, widget, 0, 0 );
00683 
00684     g_debug( "IN: gtask_cell_renderer_basic_get_size" );
00685 
00686         if( width ) {
00687         *width = PADDING + info->preview_width + 8 +
00688                  info->max_title_width + info->text_spacer_width + 8 +
00689                  MAX( 100,
00690                       MAX( info->actions_width,
00691                           4 * 8 + 3 * info->time_height ) ) +
00692                  PADDING;
00693     }
00694         if( height ) {
00695                 *height = PADDING +
00696                   MAX( info->preview_height,
00697                        info->text_spacer_height + 4 + info->status_height +
00698                        info->time_height ) +
00699                   PADDING;
00700     }
00701 
00702     gtask_basic_info_free( info );
00703 
00704     g_debug( "LEAVING: gtask_cell_renderer_basic_get_size" );
00705 }
00706 
00707 GtkCellRenderer*
00708 gtask_cell_renderer_basic_new( void ) {
00709         return GTK_CELL_RENDERER( g_object_new( GTASK_CELL_RENDERER_BASIC_TYPE, NULL ) );
00710 }
00711 
00712 static void
00713 gtask_cell_renderer_basic_render( GtkCellRenderer *cell,
00714                                   GdkWindow       *window,
00715                                   GtkWidget       *widget,
00716                                   GdkRectangle    *background_area,
00717                                   GdkRectangle    *cell_area,
00718                                   GdkRectangle    *expose_area,
00719                                   guint            flags)
00720 {
00721         GTaskCellRendererBasic *cell_basic = GTASK_CELL_RENDERER_BASIC( cell );
00722         GTaskCellRendererBasicPrivate *private = cell_basic->private;
00723     GTaskBasicInfo         *info = gtask_cell_renderer_basic_get_sizing_info( cell_basic, widget, cell_area->x, cell_area->y );
00724 
00725     
00726     guint x = cell_area->x;
00727     guint y = cell_area->y;
00728 
00729         GdkGC *gc;
00730 
00731     GtkStateType   gtk_state;
00732 
00733     GTaskActivityState activity_state = cell_basic->private->activity_state;
00734 
00735     g_debug( "IN: gtask_cell_renderer_basic_render" );
00736 
00738     gtask_cell_renderer_basic_fill_text_info( cell_basic,
00739                                               info,
00740                                               widget,
00741                                               cell_area->width - info->preview_width - 100 - 16 - 2 * PADDING );
00742 
00743     if( activity_state == GTASK_ACTIVITY_STATE_INACTIVE )
00744         gtk_state = GTK_STATE_INSENSITIVE;
00745     else {
00746         switch( flags ) {
00747             case GTK_CELL_RENDERER_SELECTED:
00748                 gtk_state = GTK_STATE_SELECTED;
00749                 break;
00750             default:
00751                 gtk_state = GTK_STATE_NORMAL;
00752                 break;
00753         }
00754     }
00755 
00756     gc = gdk_gc_new( window );
00757 
00758     if( info->preview ) {
00764         guint p_x, p_y;
00765         guint width, height;
00766         guint max_size = info->text_spacer_height + info->status_height + info->time_height;
00767 
00768         GdkPixbuf *scaled = eel_gdk_pixbuf_scale_down_to_fit( info->preview,
00769                                                               max_size,
00770                                                               max_size );
00771         GdkPixbuf *final;
00772 
00773         if( private->thumbnail_frame && private->preview_is_thumb ) {
00774             final = eel_embed_image_in_frame( scaled,
00775                                               private->thumbnail_frame,
00776                                               3, 3, 6, 6 );
00777 
00778             g_object_unref( (GObject *) scaled );
00779         } else {
00780             final = scaled;
00781         }
00782 
00783         width = gdk_pixbuf_get_width( final );
00784         height = gdk_pixbuf_get_height( final );
00785 
00786         /* place icons in the middle of the "box" */
00787         p_x = x + ( max_size - width ) / 2;
00788         p_y = y +( max_size - height ) / 2;
00789 
00790         if( private->activity_state == GTASK_ACTIVITY_STATE_INACTIVE ) {
00791             /* grey out the resulting image */
00792             gdk_pixbuf_saturate_and_pixelate( final, final, 1.0, TRUE );
00793         }
00794 
00795         gdk_pixbuf_render_to_drawable( final, window, gc, 0, 0,
00796                                        p_x + PADDING, p_y + PADDING, -1, -1,
00797                                        GDK_RGB_DITHER_NONE, -1, -1 );
00798 
00799         g_object_unref( (GObject *) final );
00800 
00801 
00803     }
00804 
00805         gtk_paint_layout( widget->style, window,
00806                       gtk_state,
00807                       FALSE,
00808                       cell_area,
00809                       widget,
00810                       "title",
00811                       info->center_x,
00812                       y + PADDING + 2,
00813                       info->title );
00814 
00815         gtk_paint_layout( widget->style, window,
00816                         gtk_state,
00817                         FALSE,
00818                         cell_area,
00819                         widget,
00820                         "status-message-label",
00821                         info->center_x,
00822                         y + PADDING + info->text_spacer_height + 4,
00823                         info->status_prefix );
00824 
00825         gtk_paint_layout( widget->style, window,
00826                         gtk_state,
00827                         FALSE,
00828                         cell_area,
00829                         widget,
00830                         "status-message",
00831                         info->center_x + info->status_width,
00832                         y + PADDING + info->text_spacer_height + 4,
00833                         info->status );
00834 
00835         gtk_paint_layout( widget->style, window,
00836                         gtk_state,
00837                         FALSE,
00838                         cell_area,
00839                         widget,
00840                         "time-remaining-label",
00841                         info->center_x,
00842                         y + PADDING + info->text_spacer_height + 4 + info->status_height,
00843                         info->time_prefix );
00844 
00845         gtk_paint_layout( widget->style, window,
00846                         gtk_state,
00847                         FALSE,
00848                         cell_area,
00849                         widget,
00850                         "time-remaining",
00851                         info->center_x + info->time_width,
00852                         y + PADDING + info->text_spacer_height + 4 + info->status_height,
00853                         info->time );
00854 
00858     gtask_ui_draw_progressbar( widget, window, cell_area,
00859                                cell_basic->private->progress, activity_state,
00860                                cell_area->x + cell_area->width - 100 - PADDING, y + PADDING,
00861                                100, info->text_spacer_height + 4 );
00862 
00863         gtk_paint_layout( widget->style, window,
00864                         gtk_state,
00865                         FALSE,
00866                         cell_area,
00867                         widget,
00868                         "actions",
00869                         cell_area->x + cell_area->width - 100 - PADDING,
00870                         y + PADDING + info->text_spacer_height + 4,
00871                         info->actions_layout );
00872 
00873     gtask_basic_info_free( info );
00874 
00875     g_debug( "LEAVING: gtask_cell_renderer_basic_render" );
00876 }
00877 
00878 static void
00879 gtask_cell_renderer_basic_finalize( GObject *object ) {
00880         GTaskCellRendererBasic *cell = GTASK_CELL_RENDERER_BASIC( object );
00881 
00882         g_free( cell->private );
00883   
00884         if( G_OBJECT_CLASS (parent_class)->finalize )
00885         G_OBJECT_CLASS (parent_class)->finalize( object );
00886 }
00887 
00888 /* @} */

Generated on Mon Feb 2 21:33:25 2004 for libgtask-ui by doxygen 1.3.4