]> Dogcows Code - chaz/homebank/blobdiff - src/gtk-chart.c
import homebank-5.1.2
[chaz/homebank] / src / gtk-chart.c
index 3c9b9149a1939c99ae02c363ebc5a7e580f3208f..d01d097d40bb22a2603814ec3fc48cc13aa5703b 100644 (file)
@@ -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.
  *
 
 #include <math.h>
 #include <string.h>
-
 #include <gtk/gtk.h>
 
 #include "homebank.h"
 #include "gtk-chart-colors.h"
 #include "gtk-chart.h"
 
-
-#define HELPDRAW 0
-
 #define MYDEBUG 0
 
 #if MYDEBUG
 #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;i<chart->nb_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;i<chart->nb_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();
This page took 0.057511 seconds and 4 git commands to generate.