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
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,
00126 NULL,
00127 (GClassInitFunc) gtask_cell_renderer_basic_class_init,
00128 NULL,
00129 NULL,
00130 sizeof( GTaskCellRendererBasic ),
00131 0,
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
00342
00343
00344
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
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;
00392 }
00393
00394 ++p;
00395 }
00396
00397
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
00425
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
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
00502
00503
00504
00505
00506
00507
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
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
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
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
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
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
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