X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fhomebank;a=blobdiff_plain;f=src%2Fgtk-chart.c;fp=src%2Fgtk-chart.c;h=d01d097d40bb22a2603814ec3fc48cc13aa5703b;hp=3c9b9149a1939c99ae02c363ebc5a7e580f3208f;hb=996fa4ab9f6b836001f8ad0eecbfd3821687fea7;hpb=27f6e3b112df235c8e9afc9911b1f6bce208a001 diff --git a/src/gtk-chart.c b/src/gtk-chart.c index 3c9b914..d01d097 100644 --- a/src/gtk-chart.c +++ b/src/gtk-chart.c @@ -1,5 +1,5 @@ /* HomeBank -- Free, easy, personal accounting for everyone. - * Copyright (C) 1995-2014 Maxime DOYEN + * Copyright (C) 1995-2016 Maxime DOYEN * * This file is part of HomeBank. * @@ -19,16 +19,12 @@ #include #include - #include #include "homebank.h" #include "gtk-chart-colors.h" #include "gtk-chart.h" - -#define HELPDRAW 0 - #define MYDEBUG 0 #if MYDEBUG @@ -38,25 +34,26 @@ #endif +#define HELPDRAW 0 +#define DYNAMICS 1 + + static void gtk_chart_class_intern_init (gpointer); -static void gtk_chart_class_init (GtkChartClass *klass); -static void gtk_chart_init (GtkChart *chart); -static void gtk_chart_destroy (GtkObject *chart); +static void gtk_chart_class_init (GtkChartClass *klass); +static void gtk_chart_init (GtkChart *chart); +static void gtk_chart_dispose (GObject * object); +static void gtk_chart_finalize (GObject * object); -static gboolean -drawarea_configure_event (GtkWidget *widget, - GdkEventConfigure *event, - gpointer user_data); -static void drawarea_sizeallocate_callback(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data); +static gboolean drawarea_configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer user_data); static void drawarea_realize_callback(GtkWidget *widget, gpointer user_data); -static gboolean drawarea_draw_callback( GtkWidget *widget, GdkEventExpose *event, gpointer user_data); +static gboolean drawarea_draw_callback(GtkWidget *widget, cairo_t *wcr, gpointer user_data); static gboolean drawarea_motionnotifyevent_callback(GtkWidget *widget, GdkEventMotion *event, gpointer user_data); static gboolean drawarea_querytooltip_callback(GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data); static gboolean drawarea_full_redraw(GtkWidget *widget, gpointer user_data); static void chart_calculation(GtkChart *chart); -static void chart_clear(GtkChart *chart, gboolean store); +static void chart_clear(GtkChart *chart); static void colchart_first_changed( GtkAdjustment *adj, gpointer user_data); static void colchart_compute_range(GtkChart *chart); @@ -65,12 +62,13 @@ static void colchart_scrollbar_setvalues(GtkChart *chart); static void piechart_calculation(GtkChart *chart); -static GdkPixbuf *create_color_pixbuf (GdkColor *col); +static GdkPixbuf *create_color_pixbuf (struct rgbcol *color); static GtkWidget *legend_list_new(GtkChart *chart); -static GtkHBoxClass *gtk_chart_parent_class = NULL; +static GtkBoxClass *gtk_chart_parent_class = NULL; +static const double dashed3[] = {3.0}; GType gtk_chart_get_type () @@ -93,7 +91,7 @@ static GType chart_type = 0; NULL }; - chart_type = g_type_register_static (GTK_TYPE_HBOX, "GtkChart", + chart_type = g_type_register_static (GTK_TYPE_BOX, "GtkChart", &chart_info, 0); } @@ -110,36 +108,39 @@ gtk_chart_class_intern_init (gpointer klass) static void gtk_chart_class_init (GtkChartClass * klass) { -//GObjectClass *gobject_class; -GtkObjectClass *object_class; -//GtkWidgetClass *widget_class; - - //gobject_class = (GObjectClass*) klass; - object_class = (GtkObjectClass*) klass; - //widget_class = (GtkWidgetClass*) klass; +GObjectClass *gobject_class; - gtk_chart_parent_class = g_type_class_peek_parent (klass); + DB( g_print("\n[gtkchart] class init\n") ); - DB( g_print("\n[gtkchart] class_init\n") ); - - object_class->destroy = gtk_chart_destroy; + gobject_class = G_OBJECT_CLASS (klass); + //gobject_class->get_property = gtk_chart_get_property; + //gobject_class->set_property = gtk_chart_set_property; + gobject_class->dispose = gtk_chart_dispose; + gobject_class->finalize = gtk_chart_finalize; } + static void gtk_chart_init (GtkChart * chart) { -GtkWidget *widget, *vbox, *frame; +GtkWidget *widget, *vbox; GtkWidget *scrollwin, *treeview; + DB( g_print("\n[gtkchart] init\n") ); + + chart->surface = NULL; chart->nb_items = 0; chart->items = NULL; chart->title = NULL; + + chart->pfd = NULL; chart->abs = FALSE; chart->dual = FALSE; chart->barw = GTK_CHART_BARW; - + chart->show_mono = FALSE; + //chart->drawmode = CHART_DRAW_FULL; chart->active = -1; chart->lastactive = -1; @@ -152,24 +153,29 @@ GtkWidget *scrollwin, *treeview; gtk_box_set_homogeneous(GTK_BOX(widget), FALSE); - vbox = gtk_vbox_new (FALSE, 0); + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start (GTK_BOX (widget), vbox, TRUE, TRUE, 0); /* drawing area */ - frame = gtk_frame_new(NULL); - gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0); - gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); + scrollwin = gtk_frame_new(NULL); + gtk_frame_set_shadow_type (GTK_FRAME(scrollwin), GTK_SHADOW_ETCHED_IN); + gtk_box_pack_start (GTK_BOX (vbox), scrollwin, TRUE, TRUE, 0); + + //scrollwin = gtk_scrolled_window_new(NULL,NULL); + //gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN); + //gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_NEVER, GTK_POLICY_NEVER); + //gtk_box_pack_start (GTK_BOX (vbox), scrollwin, TRUE, TRUE, 0); chart->drawarea = gtk_drawing_area_new(); //gtk_widget_set_double_buffered (GTK_WIDGET(widget), FALSE); - gtk_container_add( GTK_CONTAINER(frame), chart->drawarea ); - gtk_widget_set_size_request(chart->drawarea, 150, 150 ); + gtk_container_add( GTK_CONTAINER(scrollwin), chart->drawarea ); + gtk_widget_set_size_request(chart->drawarea, 100, 100 ); gtk_widget_set_has_tooltip(chart->drawarea, TRUE); gtk_widget_show(chart->drawarea); #if MYDEBUG == 1 - GtkStyle *style; + /*GtkStyle *style; PangoFontDescription *font_desc; g_print("draw_area font\n"); @@ -179,15 +185,14 @@ GtkWidget *scrollwin, *treeview; g_print("family: %s\n", pango_font_description_get_family(font_desc) ); g_print("size: %d (%d)\n", pango_font_description_get_size (font_desc), pango_font_description_get_size (font_desc )/PANGO_SCALE ); - + */ #endif /* scrollbar */ chart->adjustment = GTK_ADJUSTMENT(gtk_adjustment_new (0.0, 0.0, 1.0, 1.0, 1.0, 1.0)); - chart->scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (chart->adjustment)); + chart->scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (chart->adjustment)); gtk_box_pack_start (GTK_BOX (vbox), chart->scrollbar, FALSE, TRUE, 0); - /* legend treeview */ scrollwin = gtk_scrolled_window_new(NULL,NULL); chart->scrollwin = scrollwin; @@ -208,14 +213,14 @@ GtkWidget *scrollwin, *treeview; //GDK_BUTTON_RELEASE_MASK ); - g_signal_connect( G_OBJECT(chart->drawarea),"configure-event", G_CALLBACK (drawarea_configure_event), chart); - g_signal_connect( G_OBJECT(chart->drawarea), "size-allocate", G_CALLBACK(drawarea_sizeallocate_callback), chart ) ; + g_signal_connect( G_OBJECT(chart->drawarea), "configure-event", G_CALLBACK (drawarea_configure_event), chart); g_signal_connect( G_OBJECT(chart->drawarea), "realize", G_CALLBACK(drawarea_realize_callback), chart ) ; - g_signal_connect( G_OBJECT(chart->drawarea), "expose-event", G_CALLBACK(drawarea_draw_callback), chart ) ; + g_signal_connect( G_OBJECT(chart->drawarea), "draw", G_CALLBACK(drawarea_draw_callback), chart ) ; +#if DYNAMICS == 1 g_signal_connect( G_OBJECT(chart->drawarea), "query-tooltip", G_CALLBACK(drawarea_querytooltip_callback), chart ); g_signal_connect( G_OBJECT(chart->drawarea), "motion-notify-event", G_CALLBACK(drawarea_motionnotifyevent_callback), chart ); - - g_signal_connect (G_OBJECT(chart->adjustment), "value_changed", G_CALLBACK (colchart_first_changed), chart); +#endif + g_signal_connect (G_OBJECT(chart->adjustment), "value-changed", G_CALLBACK (colchart_first_changed), chart); //g_signal_connect( G_OBJECT(chart->drawarea), "map-event", G_CALLBACK(chart_map), chart ) ; //g_signal_connect( G_OBJECT(chart->drawarea), "button-press-event", G_CALLBACK(chart_button_press), chart ); @@ -230,6 +235,7 @@ gtk_chart_new (gint type) { GtkChart *chart; + DB( g_print("\n======================================================\n") ); DB( g_print("\n[gtkchart] new\n") ); chart = g_object_new (GTK_TYPE_CHART, NULL); @@ -240,27 +246,57 @@ GtkChart *chart; static void -gtk_chart_destroy (GtkObject * object) +gtk_chart_dispose (GObject *gobject) { -GtkChart *chart; +//GtkChart *chart = GTK_CHART (object); + + DB( g_print("\n[gtkchart] dispose\n") ); + + /* In dispose(), you are supposed to free all types referenced from this + * object which might themselves hold a reference to self. Generally, + * the most simple solution is to unref all members on which you own a + * reference. + */ + + /* dispose() might be called multiple times, so we must guard against + * calling g_object_unref() on an invalid GObject by setting the member + * NULL; g_clear_object() does this for us, atomically. + */ + //g_clear_object (&self->priv->an_object); + + /* Always chain up to the parent class; there is no need to check if + * the parent class implements the dispose() virtual function: it is + * always guaranteed to do so + */ + G_OBJECT_CLASS (gtk_chart_parent_class)->dispose (gobject); +} + + - DB( g_print("\n[gtkchart] destroy\n") ); - g_return_if_fail (GTK_IS_CHART (object)); +static void +gtk_chart_finalize (GObject * object) +{ +GtkChart *chart = GTK_CHART (object); - chart = GTK_CHART (object); + DB( g_print("\n[gtkchart] finalize\n") ); - chart_clear(chart, FALSE); + chart_clear(chart); + if(chart->pfd) + { + pango_font_description_free (chart->pfd); + chart->pfd = NULL; + } + if (chart->surface) { cairo_surface_destroy (chart->surface); chart->surface = NULL; } - GTK_OBJECT_CLASS (gtk_chart_parent_class)->destroy (object); -} - + G_OBJECT_CLASS (gtk_chart_parent_class)->finalize (object); +} /* @@ -268,21 +304,7 @@ GtkChart *chart; */ static gchar *chart_print_int(GtkChart *chart, gint value) { - - //mystrfmon(chart->buffer, CHART_BUFFER_LENGTH-1, (gdouble)value, chart->minor); - mystrfmon_int(chart->buffer1, CHART_BUFFER_LENGTH-1, (gdouble)value, chart->minor); - - /* - if(chart->minor) - { - value *= chart->minor_rate; - strfmon(chart->buffer, CHART_BUFFER_LENGTH-1, "%!.0n ", (gdouble)value); - strcat(chart->buffer, chart->minor_symbol); - } - else - strfmon(chart->buffer, CHART_BUFFER_LENGTH-1, "%.0n", (gdouble)value); - */ - + hb_strfmon_int(chart->buffer1, CHART_BUFFER_LENGTH-1, (gdouble)value, chart->kcur, chart->minor); return chart->buffer1; } @@ -291,20 +313,7 @@ static gchar *chart_print_int(GtkChart *chart, gint value) */ static gchar *chart_print_double(GtkChart *chart, gchar *buffer, gdouble value) { - - mystrfmon(buffer, CHART_BUFFER_LENGTH-1, value, chart->minor); - - /* - if(chart->minor) - { - value *= chart->minor_rate; - strfmon(chart->buffer, CHART_BUFFER_LENGTH-1, "%!n ", (gdouble)value); - strcat(chart->buffer, chart->minor_symbol); - } - else - strfmon(chart->buffer, CHART_BUFFER_LENGTH-1, "%n", (gdouble)value); - */ - + hb_strfmon(buffer, CHART_BUFFER_LENGTH-1, value, chart->kcur, chart->minor); return buffer; } @@ -312,7 +321,7 @@ static gchar *chart_print_double(GtkChart *chart, gchar *buffer, gdouble value) /* ** clear any allocated memory */ -static void chart_clear(GtkChart *chart, gboolean store) +static void chart_clear(GtkChart *chart) { gint i; @@ -325,6 +334,12 @@ gint i; chart->title = NULL; } + if(chart->subtitle != NULL) + { + g_free(chart->subtitle); + chart->subtitle = NULL; + } + if(chart->items != NULL) { for(i=0;inb_items;i++) @@ -337,11 +352,6 @@ gint i; chart->items = NULL; } - if(store == TRUE) - { - gtk_list_store_clear (GTK_LIST_STORE(chart->legend)); - } - chart->nb_items = 0; chart->total = 0; @@ -365,11 +375,14 @@ gint i; gboolean valid; GtkTreeIter iter, l_iter; gint color; -GdkColor colour; - DB( g_print("\n[gtkchart] setup with model\n") ); + DB( g_print("\n[chart] setup with model\n") ); - chart_clear(chart, TRUE); + chart_clear(chart); + + if( GTK_IS_LIST_STORE(chart->legend) ) + gtk_list_store_clear (GTK_LIST_STORE(chart->legend)); + chart->nb_items = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list_store), NULL); chart->items = g_array_sized_new(FALSE, FALSE, sizeof(ChartItem), chart->nb_items); @@ -387,6 +400,7 @@ GdkColor colour; gchar *label; gdouble value1, value2; ChartItem item; + GdkPixbuf *pixbuf; /* column 0: pos (gint) */ /* column 1: key (gint) */ @@ -424,25 +438,28 @@ GdkColor colour; item.serie2 = value2; g_array_append_vals(chart->items, &item, 1); - /* populate our legend list */ + /* ensure rawmin rawmax not equal */ + if(chart->rawmin == chart->rawmax) + { + chart->rawmin = 0; + chart->rawmax = 100; + } - color = i % chart->nb_cols; + /* populate our legend list */ + color = i % chart->color_scheme.nb_cols; //color = id % chart->nb_cols; //DB( g_print ("Row %d: (%s, %2.f) color %d\n", id, title, value, color) ); - colour.red = COLTO16(chart->colors[color].r); - colour.green = COLTO16(chart->colors[color].g); - colour.blue = COLTO16(chart->colors[color].b); + pixbuf = create_color_pixbuf (&chart->color_scheme.colors[color]); gtk_list_store_append (GTK_LIST_STORE(chart->legend), &l_iter); gtk_list_store_set (GTK_LIST_STORE(chart->legend), &l_iter, - LST_LEGEND_COLOR, create_color_pixbuf (&colour), + LST_LEGEND_COLOR, pixbuf, LST_LEGEND_TITLE, label, LST_LEGEND_AMOUNT, value1, -1); - /* pie chart total sum */ chart->total += ABS(value1); @@ -490,6 +507,31 @@ GdkColor colour; } +static void chart_set_font_size(GtkChart *chart, gint font_size) +{ +gint size = 10; + + //DB( g_print("\n[chart] set font size\n") ); + + switch(font_size) + { + case CHART_FONT_SIZE_TITLE: + size = chart->pfd_size + 3; + break; + case CHART_FONT_SIZE_SUBTITLE: + size = chart->pfd_size + 1; + break; + case CHART_FONT_SIZE_NORMAL: + size = chart->pfd_size - 1; + break; + } + + //DB( g_print(" size=%d\n", size) ); + + pango_font_description_set_size(chart->pfd, size * PANGO_SCALE); + +} + /* ** recompute according to type @@ -506,7 +548,6 @@ static void chart_recompute(GtkChart *chart) case CHART_TYPE_LINE: case CHART_TYPE_COL: colchart_compute_range(chart); - colchart_calculation(chart); gtk_adjustment_set_value(chart->adjustment, 0); colchart_scrollbar_setvalues(chart); @@ -517,7 +558,6 @@ static void chart_recompute(GtkChart *chart) gtk_widget_hide(chart->scrollbar); break; } - } @@ -554,7 +594,7 @@ static void colchart_compute_range(GtkChart *chart) { double lobound=chart->rawmin, hibound=chart->rawmax; - DB( g_print("\n[gtkchart] bar compute range\n") ); + DB( g_print("\n[column] compute range\n") ); /* comptute max ticks */ chart->range = chart->rawmax - chart->rawmin; @@ -582,10 +622,11 @@ GtkWidget *drawarea = chart->drawarea; GdkWindow *gdkwindow; cairo_surface_t *surf = NULL; cairo_t *cr; -cairo_text_extents_t te; -cairo_font_extents_t fe; +int tw, th; GtkAllocation allocation; +PangoLayout *layout; gchar *valstr; +gint i; DB( g_print("\n[gtkchart] calculation\n") ); @@ -609,40 +650,73 @@ gchar *valstr; else cr = gdk_cairo_create (gdkwindow); + /* Create a PangoLayout, set the font and text */ + layout = pango_cairo_create_layout (cr); + + // compute title chart->title_zh = 0; if(chart->title != NULL) { - cairo_set_font_size(cr, CHART_FONT_SIZE_TITLE); - cairo_font_extents(cr, &fe); - chart->title_zh = fe.height; + chart_set_font_size(chart, CHART_FONT_SIZE_TITLE); + pango_layout_set_font_description (layout, chart->pfd); + + pango_layout_set_text (layout, chart->title, -1); + pango_layout_get_size (layout, &tw, &th); + chart->title_zh = (th / PANGO_SCALE); + DB( g_print(" - title: %s w=%d h=%d\n", chart->title, tw, th) ); } // compute subtitle chart->subtitle_zh = 0; if(chart->subtitle != NULL) { - cairo_set_font_size(cr, CHART_FONT_SIZE_PERIOD); - cairo_font_extents(cr, &fe); - chart->subtitle_zh = fe.height; + chart_set_font_size(chart, CHART_FONT_SIZE_SUBTITLE); + pango_layout_set_font_description (layout, chart->pfd); + + pango_layout_set_text (layout, chart->subtitle, -1); + pango_layout_get_size (layout, &tw, &th); + chart->subtitle_zh = (th / PANGO_SCALE); + DB( g_print(" - title: %s w=%d h=%d\n", chart->subtitle, tw, th) ); } chart->subtitle_y = chart->t + chart->title_zh; - cairo_set_font_size(cr, CHART_FONT_SIZE_NORMAL); + // todo: compute maxwidth of item labels + double label_w = 0; + for(i=0;inb_items;i++) + { + ChartItem *item = &g_array_index(chart->items, ChartItem, i); + + // category width + pango_layout_set_text (layout, item->label, -1); + pango_layout_get_size (layout, &tw, &th); + label_w = MAX(label_w, (tw / PANGO_SCALE)); + } + + chart->label_w = label_w + CHART_SPACING; + + DB( g_print(" - label_w:%g\n", chart->label_w) ); + + + // compute other text + chart_set_font_size(chart, CHART_FONT_SIZE_NORMAL); + pango_layout_set_font_description (layout, chart->pfd); // compute amount scale valstr = chart_print_int(chart, (gint)chart->min); - cairo_text_extents(cr, valstr, &te); - chart->scale_w = te.width; + pango_layout_set_text (layout, valstr, -1); + pango_layout_get_size (layout, &tw, &th); + chart->scale_w = (tw / PANGO_SCALE); + valstr = chart_print_int(chart, (gint)chart->max); - cairo_text_extents(cr, valstr, &te); - chart->scale_w = MAX(chart->scale_w, te.width); + pango_layout_set_text (layout, valstr, -1); + pango_layout_get_size (layout, &tw, &th); + chart->scale_w = MAX(chart->scale_w, (tw / PANGO_SCALE)); DB( g_print(" - scale: %g,%g %g,%g\n", chart->l, 0.0, chart->scale_w, 0.0) ); // compute font height - cairo_font_extents(cr, &fe); - chart->font_h = fe.height; + chart->font_h = (th / PANGO_SCALE); // compute graph region switch(chart->type) @@ -671,6 +745,8 @@ gchar *valstr; if(chart->type != CHART_TYPE_PIE && chart->show_xval) chart->graph_height -= (chart->font_h + CHART_SPACING); + g_object_unref (layout); + cairo_destroy(cr); cairo_surface_destroy(surf); @@ -681,12 +757,11 @@ static void colchart_calculation(GtkChart *chart) { gint blkw; - DB( g_print("\n[gtkchart] bar calculation\n") ); + DB( g_print("\n[column] calculation\n") ); //if expand : we compute available space - //chart->barw = MAX(32, (chart->graph_width)/chart->nb_items); - //chart->barw = 32; // usr setted or defaut to BARW + //blkw = floor(MAX(8, (chart->graph_width)/chart->nb_items)); // if fixed blkw = chart->barw + 3; @@ -698,10 +773,25 @@ gint blkw; chart->visible = MIN(chart->visible, chart->nb_items); chart->ox = chart->l; - chart->oy = floor(chart->graph_y + (chart->max/chart->range) * chart->graph_height); + chart->oy = chart->b; + if(chart->range > 0) + chart->oy = floor(chart->graph_y + (chart->max/chart->range) * chart->graph_height); DB( g_print(" + ox=%f oy=%f\n", chart->ox, chart->oy) ); + /* todo: hack on every xval */ + if(chart->label_w > 0) + { + blkw = floor(MIN(chart->nb_items*chart->blkw, chart->graph_width) / chart->label_w); + if(blkw > 0 ) + blkw = chart->visible / blkw; + + chart->every_xval = MAX(1,blkw); + } + //chart->every_xval = chart->visible - floor(chart->graph_width / chart->label_w); + + DB( g_print("vis=%d, width=%g, lbl_w=%g :: %d\n", chart->visible, chart->graph_width, chart->label_w, blkw) ); + } @@ -715,10 +805,10 @@ double x, y; gdouble curxval; gint i, first; - DB( g_print("\n(gtkline) draw scale\n") ); + DB( g_print("\n[column] draw scale\n") ); cairo_t *cr; -//static const double dashed3[] = {2.0}; + //gdkwindow = gtk_widget_get_window(widget); //cr = gdk_cairo_create (gdkwindow); @@ -738,15 +828,18 @@ cairo_t *cr; y = chart->oy; first = gtk_adjustment_get_value(GTK_ADJUSTMENT(chart->adjustment)); + cairo_set_dash(cr, dashed3, 1, 0); for(i=first; i<(first+chart->visible) ;i++) { if( !(i % chart->every_xval) ) { //cairo_user_set_rgbcol(cr, &global_colors[GREY1]); - cairo_user_set_rgbacol(cr, &global_colors[THTEXT], 0.05); + cairo_user_set_rgbacol(cr, &global_colors[THTEXT], 0.1); + + //cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); //blue cairo_move_to(cr, x, chart->graph_y); - cairo_line_to(cr, x, chart->b); + cairo_line_to(cr, x, chart->b - chart->font_h); cairo_stroke(cr); } @@ -757,6 +850,7 @@ cairo_t *cr; /* horizontal lines */ curxval = chart->max; + cairo_set_dash(cr, 0, 0, 0); for(i=0;i<=chart->div;i++) { @@ -802,11 +896,12 @@ double x, y; gdouble curxval; gchar *valstr; gint i, first; +cairo_t *cr; +PangoLayout *layout; +int tw, th; - DB( g_print("----------------------\n(gtkline) draw scale text\n") ); -cairo_t *cr; -cairo_text_extents_t te; + DB( g_print("\n([column] draw scale text\n") ); //GdkWindow *gdkwindow; //gdkwindow = gtk_widget_get_window(widget); @@ -814,7 +909,9 @@ cairo_text_extents_t te; //cr = gdk_cairo_create (gdkwindow); //cr = gdk_cairo_create (widget->window); cr = cairo_create (chart->surface); - + + layout = pango_cairo_create_layout (cr); + cairo_set_line_width(cr, 1); /* clip */ @@ -823,6 +920,11 @@ cairo_text_extents_t te; //cairo_set_operator(cr, CAIRO_OPERATOR_SATURATE); + chart_set_font_size(chart, CHART_FONT_SIZE_NORMAL); + pango_layout_set_font_description (layout, chart->pfd); + + + /* draw x-legend (items) */ if(chart->show_xval) { @@ -837,14 +939,15 @@ cairo_text_extents_t te; if( !(i % chart->every_xval) ) { valstr = item->label; - cairo_text_extents(cr, valstr, &te); + pango_layout_set_text (layout, valstr, -1); + pango_layout_get_size (layout, &tw, &th); - DB( g_print("%s w=%f h=%f\n", valstr, te.width, te.height) ); + DB( g_print("%s w=%d h=%d\n", valstr, tw, th) ); cairo_user_set_rgbacol(cr, &global_colors[THTEXT], 0.78); - //cairo_move_to(cr, x - (te.width/2), y - te.y_bearing); - cairo_move_to(cr, x, y - te.y_bearing); - cairo_show_text(cr, valstr); + cairo_move_to(cr, x - ((tw / PANGO_SCALE)/2), y); + //cairo_move_to(cr, x, y); + pango_cairo_show_layout (cr, layout); /*cairo_user_set_rgbcol(cr, &global_colors[TEXT]); cairo_move_to(cr, x, y); @@ -868,20 +971,23 @@ cairo_text_extents_t te; if( curxval != 0.0 ) { valstr = chart_print_int(chart, (gint)curxval); - cairo_text_extents(cr, valstr, &te); + pango_layout_set_text (layout, valstr, -1); + pango_layout_get_size (layout, &tw, &th); //DB( g_print("'%s', %f %f %f %f %f %f\n", valstr, te.x_bearing, te.y_bearing, te.width, te.height, te.x_advance, te.y_advance) ); // draw texts - cairo_move_to(cr, chart->graph_x - te.x_bearing - te.width - 2, y + (( te.height)/2)); + cairo_move_to(cr, chart->graph_x - (tw / PANGO_SCALE) - 2, y - ((th / PANGO_SCALE)*0.8) ); cairo_user_set_rgbacol (cr, &global_colors[THTEXT], 0.78); - cairo_show_text(cr, valstr); - + pango_cairo_show_layout (cr, layout); + } curxval -= chart->unit; } + g_object_unref (layout); + cairo_destroy(cr); } @@ -895,7 +1001,7 @@ cairo_t *cr; double x, x2, y2, h; gint i, first; - DB( g_print("\n[gtkchart] bar draw bars\n") ); + DB( g_print("\n[column] draw bars\n") ); x = chart->graph_x; first = (gint)gtk_adjustment_get_value(GTK_ADJUSTMENT(chart->adjustment)); @@ -911,7 +1017,6 @@ gint i, first; { cairo_move_to(cr, x2, chart->graph_y); cairo_line_to(cr, x2, chart->graph_x + chart->graph_height); - x2 += chart->blkw; } cairo_stroke(cr); @@ -925,9 +1030,12 @@ gint i, first; //if(!chart->datas1[i]) goto nextbar; - color = i % chart->nb_cols; + if(!chart->show_mono) + color = i % chart->color_scheme.nb_cols; + else + color = chart->color_scheme.cs_green; - cairo_user_set_rgbcol_over(cr, &chart->colors[color], i == chart->active); + cairo_user_set_rgbcol_over(cr, &chart->color_scheme.colors[color], i == chart->active); if(item->serie1) { @@ -935,11 +1043,16 @@ gint i, first; h = floor((item->serie1 / chart->range) * chart->graph_height); y2 = chart->oy - h; if(item->serie1 < 0.0) + { y2 += 1; - + if(chart->show_mono) + { + color = chart->color_scheme.cs_red; + cairo_user_set_rgbcol_over(cr, &chart->color_scheme.colors[color], i == chart->active); + } + } //DB( g_print(" + i=%d :: y2=%f h=%f (%f / %f) * %f\n", i, y2, h, chart->datas1[i], chart->range, chart->graph_height ) ); - cairo_rectangle(cr, x2+2, y2, barw, h); cairo_fill(cr); @@ -998,7 +1111,7 @@ static void colchart_first_changed( GtkAdjustment *adj, gpointer user_data) GtkChart *chart = GTK_CHART(user_data); //gint first; - DB( g_print("\n[gtkchart] bar first changed\n") ); + DB( g_print("\n[column] first changed\n") ); //first = gtk_adjustment_get_value(GTK_ADJUSTMENT(adj)); @@ -1027,7 +1140,7 @@ gint first; g_return_if_fail (GTK_IS_ADJUSTMENT (adj)); - DB( g_print("\n[gtkchart] sb_set_values\n") ); + DB( g_print("\n[column] sb_set_values\n") ); first = gtk_adjustment_get_value(GTK_ADJUSTMENT(adj)); @@ -1065,7 +1178,7 @@ static void linechart_draw_plot(cairo_t *cr, double x, double y, double r, GtkCh cairo_stroke_preserve(cr); //cairo_set_source_rgb(cr, COLTOCAIRO(0), COLTOCAIRO(119), COLTOCAIRO(204)); - cairo_user_set_rgbcol(cr, &chart->colors[chart->cs_blue]); + cairo_user_set_rgbcol(cr, &chart->color_scheme.colors[chart->color_scheme.cs_blue]); cairo_fill(cr); } @@ -1078,7 +1191,7 @@ double x, y, x2, y2, firstx, lastx, linew; gint first, i; - DB( g_print("\n(gtkline) line draw lines\n") ); + DB( g_print("\n[line] draw lines\n") ); x = chart->graph_x; y = chart->oy; @@ -1100,9 +1213,10 @@ gint first, i; { cairo_move_to(cr, x2, chart->graph_y); cairo_line_to(cr, x2, chart->graph_x + chart->graph_height); - cairo_stroke(cr); x2 += chart->blkw; } + cairo_stroke(cr); + #endif //todo: it should be possible to draw line & plot together using surface and composite fill, or sub path ?? @@ -1142,14 +1256,14 @@ gint first, i; x += chart->blkw; } - cairo_user_set_rgbcol(cr, &chart->colors[chart->cs_blue]); + cairo_user_set_rgbcol(cr, &chart->color_scheme.colors[chart->color_scheme.cs_blue]); cairo_stroke_preserve(cr); cairo_line_to(cr, lastx, y); cairo_line_to(cr, firstx, y); cairo_close_path(cr); - cairo_user_set_rgbacol(cr, &chart->colors[chart->cs_blue], 0.15); + cairo_user_set_rgbacol(cr, &chart->color_scheme.colors[chart->color_scheme.cs_blue], AREA_ALPHA); cairo_fill(cr); x = chart->graph_x; @@ -1168,17 +1282,30 @@ gint first, i; } /* overdrawn */ + + DB( g_print(" min=%.2f range=%.2f\n", chart->min, chart->range) ); + + if( chart->show_over ) { if(chart->minimum != 0 && chart->minimum >= chart->min) { - y = chart->oy - (chart->minimum/chart->range) * chart->graph_height; - cairo_set_source_rgba(cr, COLTOCAIRO(255), COLTOCAIRO(0), COLTOCAIRO(0), .15); + y = 0.5 + chart->oy + (ABS(chart->minimum)/chart->range) * chart->graph_height; + y2 = (ABS(chart->min)/chart->range) * chart->graph_height - (y - chart->oy) + 1; + cairo_set_source_rgba(cr, COLTOCAIRO(255), COLTOCAIRO(0), COLTOCAIRO(0), AREA_ALPHA / 2); - DB( g_print(" draw over: %f, %f, %f, %f\n", chart->l, y, chart->w, chart->b - y) ); + DB( g_print(" draw over: x%f, y%f, w%f, h%f\n", chart->l, y, chart->w, y2) ); - cairo_rectangle(cr, chart->graph_x, y, chart->graph_width, chart->b - y); + cairo_rectangle(cr, chart->graph_x, y, chart->graph_width, y2 ); cairo_fill(cr); + + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, COLTOCAIRO(255), COLTOCAIRO(0), COLTOCAIRO(0)); + + cairo_set_dash (cr, dashed3, 1, 0); + cairo_move_to(cr, chart->graph_x, y); + cairo_line_to (cr, chart->graph_x + chart->graph_width, y); + cairo_stroke(cr); } } @@ -1199,9 +1326,11 @@ GtkChart *chart = GTK_CHART(user_data); gint retval; gint first, index, px; + DB( g_print("\n[line] get active\n") ); + retval = -1; - if( x <= chart->r && x >= chart->l ) + if( x <= chart->r && x >= chart->graph_x && y >= chart->graph_y && y <= chart->b ) { px = (x - chart->graph_x); //py = (y - chart->oy); @@ -1225,6 +1354,9 @@ GtkWidget *drawarea = chart->drawarea; GtkAllocation allocation; gint w, h; + DB( g_print("\n[pie] calculation\n") ); + + w = chart->graph_width; h = chart->graph_height; @@ -1246,6 +1378,8 @@ cairo_t *cr; if(chart->nb_items <= 0) return; + DB( g_print("\n[pie] draw slices\n") ); + //cairo drawing @@ -1291,8 +1425,8 @@ cairo_t *cr; //g_print("color : %f %f %f\n", COLTOCAIRO(colors[i].r), COLTOCAIRO(colors[i].g), COLTOCAIRO(colors[i].b)); - color = i % chart->nb_cols; - cairo_user_set_rgbcol_over(cr, &chart->colors[color], i == chart->active); + color = i % chart->color_scheme.nb_cols; + cairo_user_set_rgbcol_over(cr, &chart->color_scheme.colors[color], i == chart->active); cairo_fill(cr); } @@ -1336,21 +1470,21 @@ cairo_t *cr; #if CHART_PIE_DONUT == 1 a1 = 0; a2 = 2 * M_PI; - radius = (gint)((chart->rayon/3) * (1 / PHI)); + + //original + //radius = (gint)((chart->rayon/3) * (1 / PHI)); + //5.1 + //radius = (gint)((chart->rayon/2) * 2 / 3); + //ynab + radius = (gint)(chart->rayon/2) * 0.5; cairo_arc(cr, cx, cy, radius, a1, a2); cairo_user_set_rgbcol(cr, &global_colors[THBASE]); cairo_fill(cr); - - - #endif - - cairo_destroy(cr); - } @@ -1361,6 +1495,8 @@ gint retval, px, py; gint index; double h; + DB( g_print("\n[pie] get active\n") ); + px = x - chart->ox; py = y - chart->oy; h = sqrt( pow(px,2) + pow(py,2) ); @@ -1401,54 +1537,25 @@ double h; static gboolean drawarea_full_redraw(GtkWidget *widget, gpointer user_data) { GtkChart *chart = GTK_CHART(user_data); -cairo_text_extents_t te; -cairo_font_extents_t fe; cairo_t *cr; +PangoLayout *layout; +int tw, th; DB( g_print("\n[gtkchart] drawarea full redraw\n") ); - - cr = cairo_create (chart->surface); -#if MYDEBUG == 1 -cairo_font_face_t *ff; -cairo_scaled_font_t *sf; - - ff = cairo_get_font_face(cr); - sf = cairo_get_scaled_font(cr); - - g_print("cairo ff = '%s'\n", cairo_toy_font_face_get_family(ff) ); - - ff = cairo_scaled_font_get_font_face(sf); - g_print("cairo sf = '%s'\n", cairo_toy_font_face_get_family(ff) ); - - - //cairo_set_font_face(cr, ff); - - - -#endif - - - - /* fillin the back in white */ //cairo_user_set_rgbcol(cr, &global_colors[WHITE]); cairo_user_set_rgbcol(cr, &global_colors[THBASE]); cairo_paint(cr); - /* taken from scrolled window - gtk_paint_shadow (widget->style, widget->window, - GTK_STATE_NORMAL, scrolled_window->shadow_type, - area, widget, "scrolled_window", - widget->allocation.x + relative_allocation.x, - widget->allocation.y + relative_allocation.y, - relative_allocation.width, - relative_allocation.height); - */ - + if(chart->nb_items == 0) + { + cairo_destroy(cr); + return FALSE; + } /*debug help draws */ #if HELPDRAW == 1 @@ -1462,32 +1569,33 @@ cairo_scaled_font_t *sf; cairo_stroke(cr); #endif - // draw title - cairo_set_font_size(cr, CHART_FONT_SIZE_TITLE); - cairo_font_extents(cr, &fe); - cairo_text_extents(cr, chart->title, &te); - -#if HELPDRAW == 1 - double dashlength; - cairo_set_source_rgb(cr, 0.0, 0.0, 1.0); //blue - dashlength = 3; - cairo_set_dash (cr, &dashlength, 1, 0); - cairo_move_to(cr, chart->l, chart->t); - cairo_rectangle(cr, chart->l + te.x_bearing, chart->t, te.width, fe.height); - cairo_stroke(cr); -#endif - - //center title - //cairo_move_to(cr, chart->l + (chart->w/2) - ((te.width - te.x_bearing) / 2), chart->t - te.y_bearing); - cairo_move_to(cr, chart->l, chart->t - te.y_bearing); - //cairo_user_set_rgbcol(cr, &global_colors[BLACK]); - cairo_user_set_rgbcol(cr, &global_colors[THTEXT]); - cairo_show_text(cr, chart->title); - - cairo_destroy(cr); - if(chart->nb_items == 0) - return FALSE; + // draw title + if(chart->title) + { + layout = pango_cairo_create_layout (cr); + + chart_set_font_size(chart, CHART_FONT_SIZE_TITLE); + pango_layout_set_font_description (layout, chart->pfd); + pango_layout_set_text (layout, chart->title, -1); + pango_layout_get_size (layout, &tw, &th); + + cairo_user_set_rgbcol(cr, &global_colors[THTEXT]); + cairo_move_to(cr, chart->l, chart->t); + pango_cairo_show_layout (cr, layout); + + #if HELPDRAW == 1 + double dashlength; + cairo_set_source_rgb(cr, 0.0, 0.0, 1.0); //blue + dashlength = 3; + cairo_set_dash (cr, &dashlength, 1, 0); + cairo_move_to(cr, chart->l, chart->t); + cairo_rectangle(cr, chart->l, chart->t, (tw / PANGO_SCALE), (th / PANGO_SCALE)); + cairo_stroke(cr); + #endif + + g_object_unref (layout); + } switch(chart->type) { @@ -1506,10 +1614,13 @@ cairo_scaled_font_t *sf; break; } + cairo_destroy(cr); + return TRUE; } + static gboolean drawarea_configure_event (GtkWidget *widget, GdkEventConfigure *event, @@ -1517,16 +1628,18 @@ drawarea_configure_event (GtkWidget *widget, { GtkChart *chart = GTK_CHART(user_data); GtkAllocation allocation; -GtkStyle *style; -GdkColor *color; +GtkStyleContext *context; +PangoFontDescription *desc; +gboolean colfound; +GdkRGBA color; DB( g_print("\n[gtkchart] drawarea configure \n") ); + gtk_widget_get_allocation (widget, &allocation); + DB( g_print("w=%d h=%d\n", allocation.width, allocation.height) ); - gtk_widget_get_allocation (widget, &allocation); - chart_recompute(chart); if (chart->surface) cairo_surface_destroy (chart->surface); @@ -1536,53 +1649,63 @@ GdkColor *color; allocation.width, allocation.height); + context = gtk_widget_get_style_context (widget); - // get theme color - style = gtk_widget_get_style (widget); - //style = gtk_widget_get_style (chart->treeview); - //style = gtk_widget_get_default_style(); + chart_color_global_default(); - //get text color - color = &style->text[GTK_STATE_NORMAL]; - struct rgbcol *tcol = &global_colors[THTEXT]; - tcol->r = color->red; - tcol->g = color->green; - tcol->b = color->blue; - DB( g_print(" - theme text col: %x %x %x\n", tcol->r, tcol->g, tcol->b) ); - - // get base color - color = &style->base[GTK_STATE_NORMAL]; - tcol = &global_colors[THBASE]; - tcol->r = color->red; - tcol->g = color->green; - tcol->b = color->blue; - DB( g_print(" - theme base col: %x %x %x\n", tcol->r, tcol->g, tcol->b) ); + // get base color + colfound = gtk_style_context_lookup_color(context, "theme_base_color", &color); + if(!colfound) + colfound = gtk_style_context_lookup_color(context, "base_color", &color); - - drawarea_full_redraw(widget, user_data); + if( colfound ) + { + struct rgbcol *tcol = &global_colors[THBASE]; + tcol->r = color.red * 255; + tcol->g = color.green * 255; + tcol->b = color.blue * 255; + DB( g_print(" - theme base col: %x %x %x\n", tcol->r, tcol->g, tcol->b) ); + } - - /* We've handled the configure event, no need for further processing. */ - return TRUE; -} + //get text color + colfound = gtk_style_context_lookup_color(context, "theme_fg_color", &color); + if(!colfound) + gtk_style_context_lookup_color(context, "fg_color", &color); + if( colfound ) + { + struct rgbcol *tcol = &global_colors[THTEXT]; + tcol->r = color.red * 255; + tcol->g = color.green * 255; + tcol->b = color.blue * 255; + DB( g_print(" - theme text (bg) col: %x %x %x\n", tcol->r, tcol->g, tcol->b) ); + } -static void drawarea_sizeallocate_callback(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data) -{ -GtkChart *chart = GTK_CHART(user_data); - - DB( g_print("\n[gtkchart] drawarea sizeallocate\n") ); - DB( g_print("w=%d h=%d\n", allocation->width, allocation->height) ); - //g_print("\n[gtkchart] drawarea sizeallocate\n") ; - //g_print("w=%d h=%d\n", allocation->width, allocation->height) ; + /* get and copy the font */ + gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL, "font", &desc, NULL); + if(chart->pfd) + { + pango_font_description_free (chart->pfd); + chart->pfd = NULL; + } + chart->pfd = pango_font_description_copy(desc); + chart->pfd_size = pango_font_description_get_size (desc) / PANGO_SCALE; + //chart->barw = (6 + chart->pfd_size) * PHI; + DB( g_print("family: %s\n", pango_font_description_get_family(chart->pfd) ) ); + DB( g_print("size : %d (%d)\n", chart->pfd_size, chart->pfd_size/PANGO_SCALE ) ); + DB( g_print("isabs : %d\n", pango_font_description_get_size_is_absolute (chart->pfd) ) ); + if( gtk_widget_get_realized(widget)) { - chart_recompute(chart); + chart_recompute(chart); + drawarea_full_redraw(widget, chart); } - + + /* We've handled the configure event, no need for further processing. */ + return TRUE; } @@ -1597,28 +1720,18 @@ static void drawarea_realize_callback(GtkWidget *widget, gpointer user_data) } - -static gboolean drawarea_draw_callback( GtkWidget *widget, GdkEventExpose *event, gpointer user_data) +static gboolean drawarea_draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) { GtkChart *chart = GTK_CHART(user_data); -cairo_t *cr; - DB( g_print("\n[gtkchart] drawarea expose\n") ); - - DB( g_print(" type=%d regionempty=%d\n", event->type, cairo_region_is_empty(event->region)) ); + if( !gtk_widget_get_realized(widget) || chart->surface == NULL ) + return FALSE; - - - cr = gdk_cairo_create (gtk_widget_get_window (widget)); + DB( g_print("\n[gtkchart] drawarea draw callback\n") ); cairo_set_source_surface (cr, chart->surface, 0, 0); - //gdk_cairo_rectangle (cr, &event->area); cairo_paint (cr); - /* here draw only line, bar, slices */ - if(chart->nb_items == 0) - return FALSE; - switch(chart->type) { case CHART_TYPE_COL: @@ -1632,10 +1745,6 @@ cairo_t *cr; break; } - - - cairo_destroy (cr); - return FALSE; } @@ -1646,6 +1755,9 @@ GtkChart *chart = GTK_CHART(user_data); gchar *strval, *strval2, *buffer; gboolean retval = FALSE; + if(chart->surface == NULL) + return FALSE; + DB( g_print("\n[gtkchart] drawarea querytooltip\n") ); DB( g_print(" x=%d, y=%d kbm=%d\n", x, y, keyboard_mode) ); @@ -1661,17 +1773,17 @@ gboolean retval = FALSE; strval = chart_print_double(chart, chart->buffer1, item->serie1); if( !chart->dual ) { - + //#1420495 don't use g_markup_printf_escaped if( chart->type == CHART_TYPE_PIE ) - buffer = g_markup_printf_escaped("%s\n%s\n%.2f%%", item->label, strval, item->rate); + buffer = g_strdup_printf("%s\n%s\n%.2f%%", item->label, strval, item->rate); else - buffer = g_markup_printf_escaped("%s\n%s", item->label, strval); + buffer = g_strdup_printf("%s\n%s", item->label, strval); } else { strval2 = chart_print_double(chart, chart->buffer2, item->serie2); - buffer = g_markup_printf_escaped("%s\n+%s\n%s", item->label, strval2, strval); + buffer = g_strdup_printf("%s\n+%s\n%s", item->label, strval2, strval); } gtk_tooltip_set_text(tooltip, buffer); @@ -1692,7 +1804,7 @@ GtkChart *chart = GTK_CHART(user_data); gboolean retval = TRUE; gint x, y; - if(chart->nb_items == 0) + if(chart->surface == NULL || chart->nb_items == 0) return FALSE; DB( g_print("\n[gtkchart] drawarea motion\n") ); @@ -1704,8 +1816,8 @@ gint x, y; { DB( g_print(" is hint\n") ); - //gdk_window_get_device_position(event->window, event->device, &x, &y, NULL); - gdk_window_get_pointer(event->window, &x, &y, NULL); + gdk_window_get_device_position(event->window, event->device, &x, &y, NULL); + //gdk_window_get_pointer(event->window, &x, &y, NULL); //return FALSE; } @@ -1727,11 +1839,59 @@ gint x, y; if(chart->lastactive != chart->active) { - DB( g_print(" rollover redraw :: active=%d\n", chart->active) ); - //chart->drawmode = CHART_DRAW_OVERCHANGE; - //gtk_widget_queue_draw_area(widget, chart->graph_x, chart->graph_y, chart->graph_width, chart->graph_height); + GdkRectangle update_rect; + gint first; + + DB( g_print(" motion rollover redraw :: active=%d\n", chart->active) ); + + first = (gint)gtk_adjustment_get_value(GTK_ADJUSTMENT(chart->adjustment)); + + /* pie : always invalidate all graph area */ + if( chart->type == CHART_TYPE_PIE ) + { + update_rect.x = chart->graph_x; + update_rect.y = chart->graph_y; + update_rect.width = chart->graph_width; + update_rect.height = chart->graph_height; + + /* Now invalidate the affected region of the drawing area. */ + gdk_window_invalidate_rect (gtk_widget_get_window (widget), + &update_rect, + FALSE); + } + + if(chart->lastactive != -1) + { + /* column/line : invalidate rollover */ + if( chart->type != CHART_TYPE_PIE ) + { + update_rect.x = chart->graph_x + (chart->lastactive - first) * chart->blkw; + update_rect.y = chart->graph_y - 6; + update_rect.width = chart->blkw; + update_rect.height = chart->graph_height + 12; + } + + /* Now invalidate the affected region of the drawing area. */ + gdk_window_invalidate_rect (gtk_widget_get_window (widget), + &update_rect, + FALSE); + } - gtk_widget_queue_draw( widget ); + /* column/line : invalidate current item */ + if(chart->type != CHART_TYPE_PIE) + { + update_rect.x = chart->graph_x + (chart->active - first) * chart->blkw; + update_rect.y = chart->graph_y - 6; + update_rect.width = chart->blkw; + update_rect.height = chart->graph_height + 12; + + /* Now invalidate the affected region of the drawing area. */ + gdk_window_invalidate_rect (gtk_widget_get_window (widget), + &update_rect, + FALSE); + } + + //gtk_widget_queue_draw( widget ); //retval = FALSE; } @@ -1750,16 +1910,21 @@ gint x, y; void gtk_chart_queue_redraw(GtkChart *chart) { - chart_recompute(chart); - drawarea_full_redraw(chart->drawarea, chart); - gtk_widget_queue_draw( chart->drawarea ); + DB( g_print("\n[gtkchart] queue redraw\n") ); + + if( gtk_widget_get_realized(chart->drawarea) ) + { + chart_recompute(chart); + drawarea_full_redraw(chart->drawarea, chart); + gtk_widget_queue_draw( chart->drawarea ); + } } /* ** change the model and/or column */ -void gtk_chart_set_datas(GtkChart *chart, GtkTreeModel *model, guint column, gchar *title) +void gtk_chart_set_datas(GtkChart *chart, GtkTreeModel *model, guint column, gchar *title, gchar *subtitle) { g_return_if_fail (GTK_IS_CHART (chart)); @@ -1768,21 +1933,24 @@ void gtk_chart_set_datas(GtkChart *chart, GtkTreeModel *model, guint column, gch chart_setup_with_model(chart, model, column, column); if(title != NULL) chart->title = g_strdup(title); - - + if(subtitle != NULL) + chart->subtitle = g_strdup(subtitle); gtk_chart_queue_redraw(chart); } else { - chart_clear(chart, TRUE); + chart_clear(chart); + if( GTK_IS_LIST_STORE(chart->legend) ) + gtk_list_store_clear (GTK_LIST_STORE(chart->legend)); + } } /* ** change the model and/or column */ -void gtk_chart_set_dualdatas(GtkChart *chart, GtkTreeModel *model, guint column1, guint column2, gchar *title) +void gtk_chart_set_dualdatas(GtkChart *chart, GtkTreeModel *model, guint column1, guint column2, gchar *title, gchar *subtitle) { g_return_if_fail (GTK_IS_CHART (chart)); @@ -1791,14 +1959,16 @@ void gtk_chart_set_dualdatas(GtkChart *chart, GtkTreeModel *model, guint column1 chart_setup_with_model(chart, model, column1, column2 ); if(title != NULL) chart->title = g_strdup(title); - - - + if(subtitle != NULL) + chart->subtitle = g_strdup(subtitle); + gtk_chart_queue_redraw(chart); } else { - chart_clear(chart, TRUE); + chart_clear(chart); + if( GTK_IS_LIST_STORE(chart->legend) ) + gtk_list_store_clear (GTK_LIST_STORE(chart->legend)); } } @@ -1821,44 +1991,9 @@ void gtk_chart_set_type(GtkChart * chart, gint type) /* = = = = = = = = = = parameters = = = = = = = = = = */ -void gtk_chart_set_color_scheme(GtkChart * chart, gint colorscheme) +void gtk_chart_set_color_scheme(GtkChart * chart, gint index) { - chart->cs_blue = 0; - - switch(colorscheme) - { - default: - case CHART_COLMAP_HOMEBANK: - chart->colors = homebank_colors; - chart->nb_cols = homebank_nbcolors; - break; - case CHART_COLMAP_MSMONEY: - chart->colors = money_colors; - chart->nb_cols = money_nbcolors; - chart->cs_blue = 1; - break; - case CHART_COLMAP_SAP: - chart->colors = sap_colors; - chart->nb_cols = sap_nbcolors; - break; - case CHART_COLMAP_QUICKEN: - chart->colors = quicken_colors; - chart->nb_cols = quicken_nbcolors; - chart->cs_blue = 3; - break; - case CHART_COLMAP_OFFICE2010: - chart->colors = office2010_colors; - chart->nb_cols = office2010_nbcolors; - break; - case CHART_COLMAP_OFFICE2013: - chart->colors = office2013_colors; - chart->nb_cols = office2013_nbcolors; - break; - case CHART_COLMAP_ANALYTICS: - chart->colors = analytics_colors; - chart->nb_cols = analytics_nbcolors; - break; - } + colorscheme_init(&chart->color_scheme, index); } @@ -1882,14 +2017,14 @@ void gtk_chart_set_absolute(GtkChart * chart, gboolean abs) chart->abs = abs; } -/* + void gtk_chart_set_currency(GtkChart * chart, guint32 kcur) { g_return_if_fail (GTK_IS_CHART (chart)); chart->kcur = kcur; } -*/ + /* ** set the overdrawn minimum @@ -1931,6 +2066,19 @@ void gtk_chart_set_barw(GtkChart * chart, gdouble barw) gtk_chart_queue_redraw(chart); } +/* +** set the show mono (colors) +*/ +void gtk_chart_set_showmono(GtkChart * chart, gboolean mono) +{ + g_return_if_fail (GTK_IS_CHART (chart)); + + chart->show_mono = mono; + + if(chart->type != CHART_TYPE_PIE) + gtk_chart_queue_redraw(chart); +} + /* = = = = = = = = = = visibility = = = = = = = = = = */ @@ -1997,60 +2145,39 @@ void gtk_chart_show_minor(GtkChart * chart, gboolean minor) gtk_chart_queue_redraw(chart); gtk_tree_view_columns_autosize (GTK_TREE_VIEW(chart->treeview)); + gtk_widget_queue_draw (chart->treeview); } - - /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* legend list */ -static GdkPixbuf * -//create_color_pixbuf (const char *color) -create_color_pixbuf (GdkColor *col) -{ - GdkPixbuf *pixbuf; - //GdkColor col = color; - - int x; - int num; - guchar *p; +#define LEG_SQUARE_SIZE 12 -/* - if (!gdk_color_parse (color, &col)) - return NULL; - */ - -#define squaredim 12 - - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, - FALSE, 8, //bits - squaredim, squaredim); //width,height - - //rowstride = gdk_pixbuf_get_rowstride (pixbuf); - p = gdk_pixbuf_get_pixels (pixbuf); +static GdkPixbuf *create_color_pixbuf (struct rgbcol *color) +{ +GdkPixbuf *pixbuf; +guint32 pixel; - num = gdk_pixbuf_get_width (pixbuf) * - gdk_pixbuf_get_height (pixbuf); + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, LEG_SQUARE_SIZE, LEG_SQUARE_SIZE); - for (x = 0; x < num; x++) { + pixel = 0xFF; + pixel |= (color->r << 24); + pixel |= (color->g << 16); + pixel |= (color->b << 8); - p[0] = col->red; - p[1] = col->green; - p[2] = col->blue; + /*g_print("%08x\n", (0xFF & col->red) << 24 ); + g_print("%08x\n", (0xFF & col->green) << 16 ); + g_print("%08x\n", (0xFF & col->blue) << 8 ); + g_print("%x %x %x => %08x\n", col->red, col->green, col->blue, pixel);*/ - /* - p[0] = col->red / 65535 * 255; - p[1] = col->green / 65535 * 255; - p[2] = col->blue / 65535 * 255; - */ - p += 3; - } + gdk_pixbuf_fill(pixbuf, pixel); - return pixbuf; + return pixbuf; } + static void legend_list_cell_data_function(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, @@ -2088,9 +2215,7 @@ gdouble amount; LST_LEGEND_AMOUNT, &amount, -1); - //hb_strfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, value, kcur); - //todo: manage GLOBALS->minor eq - mystrfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, amount, chart->minor); + hb_strfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, amount, chart->kcur, chart->minor); g_object_set(renderer, "text", buf, @@ -2151,10 +2276,22 @@ GtkTreeViewColumn *column; #endif // change the font size to a smaller one - PangoFontDescription *font = pango_font_description_new(); + /*PangoFontDescription *font = pango_font_description_new(); pango_font_description_set_size (font, 8 * PANGO_SCALE); gtk_widget_modify_font(GTK_WIDGET(view), font); - pango_font_description_free( font ); + pango_font_description_free( font );*/ + GtkStyleContext *context; + PangoFontDescription *desc, *nfd; + gint nfsize; + + context = gtk_widget_get_style_context (chart->drawarea); + gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL, "font", &desc, NULL); + nfd = pango_font_description_copy(desc); + nfsize = pango_font_description_get_size (desc) / PANGO_SCALE; + pango_font_description_set_size(nfd, MAX(8, nfsize-2) * PANGO_SCALE); + gtk_widget_override_font(GTK_WIDGET(view), nfd); + pango_font_description_free (nfd); + // column 1 column = gtk_tree_view_column_new();