diff options
| author | Maria <matveeva.maria@gmail.com> | 2013-12-12 16:57:08 +0100 | 
|---|---|---|
| committer | Maria <matveeva.maria@gmail.com> | 2013-12-12 16:57:08 +0100 | 
| commit | 0b5805af5d67e6e4768072fe18712cc28dc100ee (patch) | |
| tree | 030cc3ea75b66934409c7befad44b3fc3bf50572 | |
| parent | d3c7d98dd866835a9039e38d75cf83be0c2b7d94 (diff) | |
| download | libuca-0b5805af5d67e6e4768072fe18712cc28dc100ee.tar.gz libuca-0b5805af5d67e6e4768072fe18712cc28dc100ee.tar.bz2 libuca-0b5805af5d67e6e4768072fe18712cc28dc100ee.tar.xz libuca-0b5805af5d67e6e4768072fe18712cc28dc100ee.zip | |
Add region of interest.
| -rw-r--r-- | bin/gui/control.c | 230 | ||||
| -rw-r--r-- | bin/gui/control.glade | 179 | 
2 files changed, 343 insertions, 66 deletions
| diff --git a/bin/gui/control.c b/bin/gui/control.c index af5cfe3..2a7d74f 100644 --- a/bin/gui/control.c +++ b/bin/gui/control.c @@ -38,6 +38,7 @@ typedef struct {      UcaCamera   *camera;      GtkWidget   *main_window;      GdkPixbuf   *pixbuf; +    GdkPixbuf   *subpixbuf;      GtkWidget   *image;      GtkWidget   *start_button;      GtkWidget   *stop_button; @@ -55,6 +56,10 @@ typedef struct {      GtkLabel    *x_label;      GtkLabel    *y_label;      GtkLabel    *val_label; +    GtkLabel    *roix_label; +    GtkLabel    *roiy_label; +    GtkLabel    *roiw_label; +    GtkLabel    *roih_label;      GtkDialog       *download_dialog;      GtkProgressBar  *download_progressbar; @@ -62,6 +67,10 @@ typedef struct {      GtkAdjustment   *count;      GtkAdjustment   *hadjustment;      GtkAdjustment   *vadjustment; +    GtkAdjustment   *x_adjustment; +    GtkAdjustment   *y_adjustment; +    GtkAdjustment   *width_adjustment; +    GtkAdjustment   *height_adjustment;      GtkWidget       *histogram_view;      GtkToggleButton *histogram_button; @@ -73,6 +82,7 @@ typedef struct {      gint         display_width, display_height;      gint         colormap;      gdouble      zoom_factor; +    gdouble      zoom_before;      State        state;      guint        n_recorded;      gboolean     data_in_camram; @@ -81,11 +91,18 @@ typedef struct {      gint         width, height;      gint         pixel_size;      gint         ev_x, ev_y; +    gint         display_x, display_y; +    gint         tmp_fromx, tmp_fromy; +    gint         from_x, from_y; +    gint         to_x, to_y; +    gint         adj_width, adj_height;  } ThreadData;  static UcaPluginManager *plugin_manager;  static gsize mem_size = 2048;  +static void update_pixbuf (ThreadData *data); +  static void  up_and_down_scale (ThreadData *data, gpointer buffer)  { @@ -112,10 +129,18 @@ up_and_down_scale (ThreadData *data, gpointer buffer)      do_log = gtk_toggle_button_get_active (data->log_button);      if (data->state == RUNNING) { -        start_wval = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->hadjustment)); -        start_hval = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->vadjustment)); -        page_width += start_wval; -        page_height += start_hval; +        if ((data->adj_width > 0) && (data->adj_height > 0)) { +            start_wval = data->from_x; +            start_hval = data->from_y; +            page_width = data->to_x; +            page_height = data->to_y; +        } +        else { +            start_wval = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->hadjustment)); +            start_hval = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->vadjustment)); +            page_width += start_wval; +            page_height += start_hval; +        }      }      else {          start_wval = 0; @@ -336,10 +361,36 @@ on_motion_notify (GtkWidget *event_box, GdkEventMotion *event, ThreadData *data)          data->ev_x = event->x - startx;          gint starty = (page_height - data->display_height) / 2;          data->ev_y = event->y - starty; + +        if ((data->adj_width > 0) && (data->adj_height > 0)) { +            data->display_x = event->x - ((page_width - data->adj_width) / 2) + data->from_x; +            data->display_y = event->y - ((page_height - data->adj_height) / 2) + data->from_y; +        } +        else { +            data->display_x = data->ev_x; +            data->display_y = data->ev_y; +        }      }        else { -         data->ev_x = event->x; -         data->ev_y = event->y; +        data->ev_x = event->x; +        data->ev_y = event->y; + +        if ((data->adj_width > 0) && (data->adj_height > 0)) { + +            if (data->adj_width >= page_width) +                data->display_x = event->x + data->from_x; +            else +                data->display_x = event->x - ((page_width - data->adj_width) / 2) + data->from_x; + +            if (data->adj_height >= page_height) +                data->display_y = event->y + data->from_y; +            else +                data->display_y = event->y - ((page_height - data->adj_height) / 2) + data->from_y; +        } +        else { +            data->display_x = data->ev_x; +            data->display_y = data->ev_y; +        }      }      if ((data->state != RUNNING) || ((data->ev_x >= 0 && data->ev_y >= 0) && (data->ev_y <= data->display_height && data->ev_x <= data->display_width))) {  @@ -347,7 +398,7 @@ on_motion_notify (GtkWidget *event_box, GdkEventMotion *event, ThreadData *data)          GString *string;           buffer = uca_ring_buffer_get_current_pointer (data->buffer);          string = g_string_new_len (NULL, 32); -        gint i = (data->ev_y / data->zoom_factor) * data->width + data->ev_x / data->zoom_factor; +        gint i = (data->display_y / data->zoom_factor) * data->width + data->display_x / data->zoom_factor;          if (data->pixel_size == 1) {              guint8 *input = (guint8 *) buffer; @@ -362,11 +413,78 @@ on_motion_notify (GtkWidget *event_box, GdkEventMotion *event, ThreadData *data)              gtk_label_set_text (data->val_label, string->str);          } -        g_string_printf (string, "x = %i", data->ev_x); +        g_string_printf (string, "x = %i", data->display_x);          gtk_label_set_text (data->x_label, string->str); -        g_string_printf (string, "y = %i", data->ev_y); +        g_string_printf (string, "y = %i", data->display_y);          gtk_label_set_text (data->y_label, string->str); +    }    +} + +static void +on_button_press (GtkWidget *event_box, GdkEventMotion *event, ThreadData *data) +{ +    if (data->ev_x < 0) +        data->ev_x = 0; +    if (data->ev_x > data->display_width) +        data->ev_x = data->display_width; +    if (data->ev_y < 0) +        data->ev_y = 0; +    if (data->ev_y > data->display_height) +        data->ev_y = data->display_height; + +    if ((data->ev_x >= 0 && data->ev_y >= 0) && (data->ev_y <= data->display_height && data->ev_x <= data->display_width)) { +        gtk_adjustment_set_upper (GTK_ADJUSTMENT (data->x_adjustment), data->display_width); +        gtk_adjustment_set_upper (GTK_ADJUSTMENT (data->y_adjustment), data->display_height); +        gtk_adjustment_set_value (GTK_ADJUSTMENT (data->x_adjustment), data->ev_x); +        gtk_adjustment_set_value (GTK_ADJUSTMENT (data->y_adjustment), data->ev_y); +        data->tmp_fromx = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->x_adjustment)); +        data->tmp_fromy = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->y_adjustment)); +    } +    data->zoom_before = data->zoom_factor; +} + +static void +on_button_release (GtkWidget *event_box, GdkEventMotion *event, ThreadData *data) +{ +    if (data->ev_x < 0) +        data->ev_x = 0; +    if (data->ev_x > data->display_width) +        data->ev_x = data->display_width; +    if (data->ev_y < 0) +        data->ev_y = 0; +    if (data->ev_y > data->display_height) +        data->ev_y = data->display_height; + +    if ((data->ev_x >= 0 && data->ev_y >= 0) && (data->ev_y <= data->display_height && data->ev_x <= data->display_width)) { +        gtk_adjustment_set_upper (GTK_ADJUSTMENT (data->width_adjustment), data->display_width); +        gtk_adjustment_set_upper (GTK_ADJUSTMENT (data->height_adjustment), data->display_height); +        gtk_adjustment_set_value (GTK_ADJUSTMENT (data->width_adjustment), data->ev_x); +        gtk_adjustment_set_value (GTK_ADJUSTMENT (data->height_adjustment), data->ev_y); +        gint tmp_tox = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->width_adjustment)); +        gint tmp_toy = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->height_adjustment)); +   +        if (data->tmp_fromx > tmp_tox) { +            data->from_x = tmp_tox; +            data->to_x = data->tmp_fromx; +        } +        else { +            data->from_x = data->tmp_fromx; +            data->to_x = tmp_tox; +        } +        if (data->tmp_fromy > tmp_toy) { +            data->from_y = tmp_toy; +            data->to_y = data->tmp_fromy; +        } +        else { +            data->from_y = data->tmp_fromy; +            data->to_y = tmp_toy; +        } + +        data->adj_width = data->to_x - data->from_x; +        data->adj_height = data->to_y - data->from_y; + +        update_pixbuf (data);           }  } @@ -380,7 +498,15 @@ update_pixbuf (ThreadData *data)      guint max;      gdk_flush (); -    gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), data->pixbuf); + +    if (data->adj_width > 0 && data->adj_height > 0) { +        data->subpixbuf = gdk_pixbuf_new_subpixbuf (data->pixbuf, data->from_x, data->from_y, data->adj_width, data->adj_height); +        gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), data->subpixbuf); +    } +    else { +        gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), data->pixbuf); +    } +      gtk_widget_queue_draw_area (data->image, 0, 0, data->display_width, data->display_height);      egg_histogram_view_update (EGG_HISTOGRAM_VIEW (data->histogram_view), @@ -401,6 +527,18 @@ update_pixbuf (ThreadData *data)      g_string_printf (string, "max = %i", max);      gtk_label_set_text (data->max_label, string->str); +    g_string_printf (string, "x = %i", data->from_x); +    gtk_label_set_text (data->roix_label, string->str); + +    g_string_printf (string, "y = %i", data->from_y); +    gtk_label_set_text (data->roiy_label, string->str); + +    g_string_printf (string, "width = %i", data->adj_width); +    gtk_label_set_text (data->roiw_label, string->str); + +    g_string_printf (string, "height = %i", data->adj_height); +    gtk_label_set_text (data->roih_label, string->str); +      g_string_free (string, TRUE);      if (gtk_toggle_button_get_active (data->histogram_button)) @@ -413,6 +551,29 @@ update_pixbuf_dimensions (ThreadData *data)      if (data->pixbuf != NULL)          g_object_unref (data->pixbuf); +    if (data->adj_width > 0 && data->adj_height > 0) { +        gdouble zoom = data->zoom_factor / data->zoom_before; + +        data->from_x = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->x_adjustment)) * zoom; +        data->from_y = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->y_adjustment)) * zoom; +        data->to_x = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->width_adjustment)) * zoom; +        data->to_y = gtk_adjustment_get_value (GTK_ADJUSTMENT (data->height_adjustment)) * zoom; + +        gint adj_x = data->from_x; +        gint adj_y = data->from_y;     + +        if (data->from_x > data->to_x) { +            data->from_x = data->to_x; +            data->to_x = adj_x; +        } +        if (data->from_y > data->to_y) { +            data->from_y = data->to_y; +            data->to_y = adj_y; +        } +        data->adj_width = data->to_x - data->from_x; +        data->adj_height = data->to_y - data->from_y; +    } +      data->display_width = (gint) data->width * data->zoom_factor;      data->display_height = (gint) data->height * data->zoom_factor; @@ -462,7 +623,6 @@ preview_frames (void *args)          buffer = uca_ring_buffer_get_current_pointer (data->buffer);          uca_camera_grab (data->camera, buffer, &error); -          if (error == NULL) {              up_and_down_scale (data, buffer); @@ -470,29 +630,29 @@ preview_frames (void *args)              gdk_threads_enter ();              update_pixbuf (data); -            if ((data->ev_x >= 0 && data->ev_y >= 0) && (data->ev_y <= data->display_height && data->ev_x <= data->display_width)) { -                GString *string;  -                string = g_string_new_len (NULL, 32); -                gint i = (data->ev_y / data->zoom_factor) * data->width + data->ev_x / data->zoom_factor; +                if ((data->ev_x >= 0) && (data->ev_y >= 0) && (data->ev_y <= data->display_height) && (data->ev_x <= data->display_width)) { +                    GString *string;  +                    string = g_string_new_len (NULL, 32); +                    gint i = (data->display_y / data->zoom_factor) * data->width + data->display_x / data->zoom_factor; -                if (data->pixel_size == 1) { -                    guint8 *input = (guint8 *) buffer; -                    guint8 val = input[i];    -                    g_string_printf (string, "val = %i", val); -                    gtk_label_set_text (data->val_label, string->str);  -                } -                else if (data->pixel_size == 2) { -                    guint16 *input = (guint16 *) buffer; -                    guint16 val = input[i]; -                    g_string_printf (string, "val = %i", val); -                    gtk_label_set_text (data->val_label, string->str);   +                    if (data->pixel_size == 1) { +                        guint8 *input = (guint8 *) buffer; +                        guint8 val = input[i];    +                        g_string_printf (string, "val = %i", val); +                        gtk_label_set_text (data->val_label, string->str);  +                    } +                    else if (data->pixel_size == 2) { +                        guint16 *input = (guint16 *) buffer; +                        guint16 val = input[i]; +                        g_string_printf (string, "val = %i", val); +                        gtk_label_set_text (data->val_label, string->str);                     } -                g_string_printf (string, "x = %i", data->ev_x); -                gtk_label_set_text (data->x_label, string->str); +                    g_string_printf (string, "x = %i", data->display_x); +                    gtk_label_set_text (data->x_label, string->str); -                g_string_printf (string, "y = %i", data->ev_y); -                gtk_label_set_text (data->y_label, string->str); +                    g_string_printf (string, "y = %i", data->display_y); +                    gtk_label_set_text (data->y_label, string->str);              }              gdk_threads_leave (); @@ -902,6 +1062,10 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)      td.hadjustment      = GTK_ADJUSTMENT (gtk_builder_get_object(builder, "hadjustment"));      td.vadjustment      = GTK_ADJUSTMENT (gtk_builder_get_object(builder, "vadjustment")); +    td.x_adjustment      = GTK_ADJUSTMENT (gtk_builder_get_object(builder, "x_adjustment")); +    td.y_adjustment      = GTK_ADJUSTMENT (gtk_builder_get_object(builder, "y_adjustment")); +    td.width_adjustment  = GTK_ADJUSTMENT (gtk_builder_get_object(builder, "width_adjustment")); +    td.height_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object(builder, "height_adjustment"));      td.event_box        = GTK_WIDGET (gtk_builder_get_object(builder, "eventbox"));      td.mean_label       = GTK_LABEL (gtk_builder_get_object (builder, "mean-label")); @@ -912,6 +1076,10 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)      td.x_label          = GTK_LABEL (gtk_builder_get_object (builder, "x-label1"));      td.y_label          = GTK_LABEL (gtk_builder_get_object (builder, "y-label1"));      td.val_label        = GTK_LABEL (gtk_builder_get_object (builder, "val-label1")); +    td.roix_label        = GTK_LABEL (gtk_builder_get_object (builder, "roix-label")); +    td.roiy_label        = GTK_LABEL (gtk_builder_get_object (builder, "roiy-label")); +    td.roiw_label        = GTK_LABEL (gtk_builder_get_object (builder, "roiw-label")); +    td.roih_label        = GTK_LABEL (gtk_builder_get_object (builder, "roih-label"));      td.download_dialog  = GTK_DIALOG (gtk_builder_get_object (builder, "download-dialog"));      td.download_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "download-adjustment")); @@ -978,6 +1146,8 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)                        "changed", G_CALLBACK (on_colormap_changed), &td);      g_signal_connect (td.event_box, "motion-notify-event", G_CALLBACK (on_motion_notify), &td); +    g_signal_connect (td.event_box, "button-press-event", G_CALLBACK (on_button_press), &td); +    g_signal_connect (td.event_box, "button-release-event", G_CALLBACK (on_button_release), &td);      g_signal_connect (td.frame_slider, "value-changed", G_CALLBACK (on_frame_slider_changed), &td);      g_signal_connect (td.start_button, "clicked", G_CALLBACK (on_start_button_clicked), &td);      g_signal_connect (td.stop_button, "clicked", G_CALLBACK (on_stop_button_clicked), &td); diff --git a/bin/gui/control.glade b/bin/gui/control.glade index 8d72d70..5bd55ff 100644 --- a/bin/gui/control.glade +++ b/bin/gui/control.glade @@ -230,6 +230,11 @@      <property name="step_increment">1</property>      <property name="page_increment">10</property>    </object> +  <object class="GtkAdjustment" id="height_adjustment"> +    <property name="upper">100</property> +    <property name="step_increment">1</property> +    <property name="page_increment">10</property> +  </object>    <object class="GtkAdjustment" id="max-bin-value-adjustment">      <property name="upper">65535</property>      <property name="value">256</property> @@ -246,35 +251,10 @@      <property name="step_increment">1</property>      <property name="page_increment">10</property>    </object> -  <object class="GtkListStore" id="zoom-values"> -    <columns> -      <!-- column-name display --> -      <column type="gchararray"/> -      <!-- column-name factor --> -      <column type="gdouble"/> -    </columns> -    <data> -      <row> -        <col id="0" translatable="yes">400 %</col> -        <col id="1">4</col> -      </row> -      <row> -        <col id="0" translatable="yes">200 %</col> -        <col id="1">2</col> -      </row> -      <row> -        <col id="0" translatable="yes">100 %</col> -        <col id="1">1</col> -      </row> -      <row> -        <col id="0" translatable="yes">50 %</col> -        <col id="1">0.5</col> -      </row> -      <row> -        <col id="0" translatable="yes">25 %</col> -        <col id="1">0.25</col> -      </row> -    </data> +  <object class="GtkAdjustment" id="width_adjustment"> +    <property name="upper">65535</property> +    <property name="step_increment">1</property> +    <property name="page_increment">10</property>    </object>    <object class="GtkWindow" id="window">      <property name="can_focus">False</property> @@ -475,7 +455,7 @@                        <object class="GtkEventBox" id="eventbox">                          <property name="visible">True</property>                          <property name="can_focus">False</property> -                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_STRUCTURE_MASK</property> +                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>                          <property name="resize_mode">queue</property>                          <child>                            <object class="GtkImage" id="image"> @@ -924,6 +904,9 @@                              <property name="column_spacing">6</property>                              <property name="row_spacing">6</property>                              <child> +                              <placeholder/> +                            </child> +                            <child>                                <object class="GtkLabel" id="label21">                                  <property name="visible">True</property>                                  <property name="can_focus">False</property> @@ -1008,7 +991,7 @@                                      <property name="visible">True</property>                                      <property name="can_focus">False</property>                                      <property name="xalign">0</property> -                                    <property name="label" translatable="yes">x = 0.0</property> +                                    <property name="label" translatable="yes">x = 0</property>                                    </object>                                    <packing>                                      <property name="expand">True</property> @@ -1021,7 +1004,7 @@                                      <property name="visible">True</property>                                      <property name="can_focus">False</property>                                      <property name="xalign">0</property> -                                    <property name="label" translatable="yes">y = 0.0</property> +                                    <property name="label" translatable="yes">y = 0</property>                                    </object>                                    <packing>                                      <property name="expand">True</property> @@ -1055,9 +1038,6 @@                                  <property name="y_options"></property>                                </packing>                              </child> -                            <child> -                              <placeholder/> -                            </child>                            </object>                            <packing>                              <property name="expand">True</property> @@ -1168,7 +1148,94 @@                            </packing>                          </child>                          <child> -                          <placeholder/> +                          <object class="GtkTable" id="stats-table1"> +                            <property name="visible">True</property> +                            <property name="can_focus">False</property> +                            <property name="border_width">12</property> +                            <property name="n_columns">2</property> +                            <property name="column_spacing">6</property> +                            <property name="row_spacing">6</property> +                            <child> +                              <object class="GtkLabel" id="label1"> +                                <property name="visible">True</property> +                                <property name="can_focus">False</property> +                                <property name="xalign">0</property> +                                <property name="label" translatable="yes">ROI:</property> +                              </object> +                              <packing> +                                <property name="x_options">GTK_FILL</property> +                              </packing> +                            </child> +                            <child> +                              <object class="GtkHBox" id="hbox7"> +                                <property name="visible">True</property> +                                <property name="can_focus">False</property> +                                <property name="spacing">6</property> +                                <child> +                                  <object class="GtkLabel" id="roix-label"> +                                    <property name="visible">True</property> +                                    <property name="can_focus">False</property> +                                    <property name="xalign">0</property> +                                    <property name="label" translatable="yes">x = 0</property> +                                  </object> +                                  <packing> +                                    <property name="expand">True</property> +                                    <property name="fill">True</property> +                                    <property name="position">0</property> +                                  </packing> +                                </child> +                                <child> +                                  <object class="GtkLabel" id="roiy-label"> +                                    <property name="visible">True</property> +                                    <property name="can_focus">False</property> +                                    <property name="xalign">0</property> +                                    <property name="label" translatable="yes">y = 0</property> +                                  </object> +                                  <packing> +                                    <property name="expand">True</property> +                                    <property name="fill">True</property> +                                    <property name="position">1</property> +                                  </packing> +                                </child> +                                <child> +                                  <object class="GtkLabel" id="roiw-label"> +                                    <property name="visible">True</property> +                                    <property name="can_focus">False</property> +                                    <property name="xalign">0</property> +                                    <property name="label" translatable="yes">width = 0</property> +                                  </object> +                                  <packing> +                                    <property name="expand">True</property> +                                    <property name="fill">True</property> +                                    <property name="position">2</property> +                                  </packing> +                                </child> +                                <child> +                                  <object class="GtkLabel" id="roih-label"> +                                    <property name="visible">True</property> +                                    <property name="can_focus">False</property> +                                    <property name="xalign">0</property> +                                    <property name="label" translatable="yes">height = 0</property> +                                  </object> +                                  <packing> +                                    <property name="expand">True</property> +                                    <property name="fill">True</property> +                                    <property name="position">3</property> +                                  </packing> +                                </child> +                              </object> +                              <packing> +                                <property name="left_attach">1</property> +                                <property name="right_attach">2</property> +                                <property name="y_options"></property> +                              </packing> +                            </child> +                          </object> +                          <packing> +                            <property name="expand">True</property> +                            <property name="fill">True</property> +                            <property name="position">1</property> +                          </packing>                          </child>                          <child>                            <object class="GtkCheckButton" id="logarithm-checkbutton"> @@ -1254,4 +1321,44 @@        </object>      </child>    </object> +  <object class="GtkAdjustment" id="x_adjustment"> +    <property name="upper">65535</property> +    <property name="step_increment">1</property> +    <property name="page_increment">10</property> +  </object> +  <object class="GtkAdjustment" id="y_adjustment"> +    <property name="upper">65535</property> +    <property name="step_increment">1</property> +    <property name="page_increment">10</property> +  </object> +  <object class="GtkListStore" id="zoom-values"> +    <columns> +      <!-- column-name display --> +      <column type="gchararray"/> +      <!-- column-name factor --> +      <column type="gdouble"/> +    </columns> +    <data> +      <row> +        <col id="0" translatable="yes">400 %</col> +        <col id="1">4</col> +      </row> +      <row> +        <col id="0" translatable="yes">200 %</col> +        <col id="1">2</col> +      </row> +      <row> +        <col id="0" translatable="yes">100 %</col> +        <col id="1">1</col> +      </row> +      <row> +        <col id="0" translatable="yes">50 %</col> +        <col id="1">0.5</col> +      </row> +      <row> +        <col id="0" translatable="yes">25 %</col> +        <col id="1">0.25</col> +      </row> +    </data> +  </object>  </interface> | 
