summaryrefslogtreecommitdiffstats
path: root/tools/gui/egg-histogram-view.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gui/egg-histogram-view.c')
-rw-r--r--tools/gui/egg-histogram-view.c524
1 files changed, 0 insertions, 524 deletions
diff --git a/tools/gui/egg-histogram-view.c b/tools/gui/egg-histogram-view.c
deleted file mode 100644
index 812af7a..0000000
--- a/tools/gui/egg-histogram-view.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu>
- (Karlsruhe Institute of Technology)
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by the
- Free Software Foundation; either version 2.1 of the License, or (at your
- option) any later version.
-
- This library is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- details.
-
- You should have received a copy of the GNU Lesser General Public License along
- with this library; if not, write to the Free Software Foundation, Inc., 51
- Franklin St, Fifth Floor, Boston, MA 02110, USA */
-
-#include <math.h>
-#include "egg-histogram-view.h"
-
-G_DEFINE_TYPE (EggHistogramView, egg_histogram_view, GTK_TYPE_DRAWING_AREA)
-
-#define EGG_HISTOGRAM_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), EGG_TYPE_HISTOGRAM_VIEW, EggHistogramViewPrivate))
-
-#define MIN_WIDTH 128
-#define MIN_HEIGHT 128
-#define BORDER 2
-
-struct _EggHistogramViewPrivate
-{
- GdkCursorType cursor_type;
- gboolean grabbing;
-
- /* This could be moved into a real histogram class */
- guint n_bins;
- gint *bins;
- gint *grabbed;
- gint min_border; /* threshold set in screen units */
- gint max_border;
-
- gdouble min_value; /* lowest value of the first bin */
- gdouble max_value; /* highest value of the last bin */
- gdouble range;
-
- gpointer data;
- gint n_elements;
- gint n_bits;
-};
-
-enum
-{
- PROP_0,
- PROP_MINIMUM_BIN_VALUE,
- PROP_MAXIMUM_BIN_VALUE,
- N_PROPERTIES
-};
-
-enum
-{
- CHANGED,
- LAST_SIGNAL
-};
-
-static GParamSpec *egg_histogram_view_properties[N_PROPERTIES] = { NULL, };
-
-static guint egg_histogram_view_signals[LAST_SIGNAL] = { 0 };
-
-
-GtkWidget *
-egg_histogram_view_new (void)
-{
- EggHistogramView *view;
-
- view = EGG_HISTOGRAM_VIEW (g_object_new (EGG_TYPE_HISTOGRAM_VIEW, NULL));
- return GTK_WIDGET (view);
-}
-
-void
-egg_histogram_view_set_data (EggHistogramView *view,
- gpointer data,
- guint n_elements,
- guint n_bits,
- guint n_bins)
-{
- EggHistogramViewPrivate *priv;
-
- g_return_if_fail (EGG_IS_HISTOGRAM_VIEW (view));
- priv = view->priv;
-
- if (priv->bins != NULL)
- g_free (priv->bins);
-
- priv->data = data;
- priv->bins = g_malloc0 (n_bins * sizeof (guint));
- priv->n_bins = n_bins;
- priv->n_bits = n_bits;
- priv->n_elements = n_elements;
-
- priv->min_value = 0.0;
- priv->max_value = (gint) pow(2, n_bits) - 1;
-
- priv->min_border = 0;
- priv->max_border = 256;
- priv->range = priv->max_value - priv->min_value;
-}
-
-void
-egg_histogram_get_visible_range (EggHistogramView *view, gdouble *min, gdouble *max)
-{
- EggHistogramViewPrivate *priv;
- GtkAllocation allocation;
- gdouble width;
-
- g_return_if_fail (EGG_IS_HISTOGRAM_VIEW (view));
-
- gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
- width = (gdouble) allocation.width - 2 * BORDER;
- priv = view->priv;
-
- *min = (priv->min_border - 2) / width * priv->range;
- *max = (priv->max_border - 2) / width * priv->range;
-}
-
-static void
-set_max_border (EggHistogramView *view)
-{
- GtkAllocation allocation;
-
- g_return_if_fail (EGG_IS_HISTOGRAM_VIEW (view));
- gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
- view->priv->max_border = allocation.width - 2 * BORDER;
-}
-
-static void
-compute_histogram (EggHistogramViewPrivate *priv)
-{
- guint n_bins = priv->n_bins - 1;
-
- for (guint i = 0; i < priv->n_bins; i++)
- priv->bins[i] = 0;
-
- if (priv->n_bits == 8) {
- guint8 *data = (guint8 *) priv->data;
-
- for (guint i = 0; i < priv->n_elements; i++) {
- guint8 v = data[i];
-
- if (v >= priv->min_value && v <= priv->max_value) {
- guint index = (guint) round (((gdouble) v) / priv->max_value * n_bins);
- priv->bins[index]++;
- }
- }
- }
- else {
- guint16 *data = (guint16 *) priv->data;
-
- for (guint i = 0; i < priv->n_elements; i++) {
- guint16 v = data[i];
-
- if (v >= priv->min_value && v <= priv->max_value) {
- guint index = (guint) floor (((gdouble ) v) / priv->max_value * n_bins);
- priv->bins[index]++;
- }
- }
- }
-}
-
-static void
-set_cursor_type (EggHistogramView *view, GdkCursorType cursor_type)
-{
- if (cursor_type != view->priv->cursor_type) {
- GdkCursor *cursor = gdk_cursor_new (cursor_type);
-
- gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET(view)), cursor);
- gdk_cursor_unref (cursor);
- view->priv->cursor_type = cursor_type;
- }
-}
-
-static void
-egg_histogram_view_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
-{
- requisition->width = MIN_WIDTH;
- requisition->height = MIN_HEIGHT;
-}
-
-static void
-draw_bins (EggHistogramViewPrivate *priv,
- cairo_t *cr,
- gint width,
- gint height)
-{
- gdouble skip = ((gdouble) width) / priv->n_bins;
- gdouble x = BORDER;
- gdouble ys = height + BORDER - 1;
- gint max_value = 0;
-
- for (guint i = 0; i < priv->n_bins; i++) {
- if (priv->bins[i] > max_value)
- max_value = priv->bins[i];
- }
-
- if (max_value == 0)
- return;
-
- for (guint i = 0; i < priv->n_bins && x < (width - BORDER); i++, x += skip) {
- if (priv->bins[i] == 0)
- continue;
-
- gint y = (gint) ((height - 2) * priv->bins[i]) / max_value;
- cairo_move_to (cr, round (x), ys);
- cairo_line_to (cr, round (x), ys - y);
- cairo_stroke (cr);
- }
-}
-
-static gboolean
-egg_histogram_view_expose (GtkWidget *widget,
- GdkEventExpose *event)
-{
- EggHistogramViewPrivate *priv;
- GtkAllocation allocation;
- GtkStyle *style;
- cairo_t *cr;
- gint width, height;
-
- priv = EGG_HISTOGRAM_VIEW_GET_PRIVATE (widget);
- cr = gdk_cairo_create (gtk_widget_get_window (widget));
-
- gdk_cairo_region (cr, event->region);
- cairo_clip (cr);
-
- style = gtk_widget_get_style (widget);
- gdk_cairo_set_source_color (cr, &style->base[GTK_STATE_NORMAL]);
- cairo_paint (cr);
-
- /* Draw the background */
- gdk_cairo_set_source_color (cr, &style->base[GTK_STATE_NORMAL]);
- cairo_paint (cr);
-
- gtk_widget_get_allocation (widget, &allocation);
- width = allocation.width - 2 * BORDER;
- height = allocation.height - 2 * BORDER;
-
- gdk_cairo_set_source_color (cr, &style->dark[GTK_STATE_NORMAL]);
- cairo_set_line_width (cr, 1.0);
- cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
- cairo_translate (cr, 0.5, 0.5);
- cairo_rectangle (cr, BORDER, BORDER, width - 1, height - 1);
- cairo_stroke (cr);
-
- if (priv->bins == NULL)
- goto cleanup;
-
- compute_histogram (priv);
-
- /* Draw border areas */
- gdk_cairo_set_source_color (cr, &style->dark[GTK_STATE_NORMAL]);
-
- cairo_rectangle (cr, BORDER, BORDER, priv->min_border + 0.5, height - 1);
- cairo_fill (cr);
-
- cairo_rectangle (cr, priv->max_border + 0.5, BORDER, width - priv->max_border + 0.5, height - 1);
- cairo_fill (cr);
-
- /* Draw spikes */
- gdk_cairo_set_source_color (cr, &style->black);
- draw_bins (priv, cr, width, height);
-
-cleanup:
- cairo_destroy (cr);
- return FALSE;
-}
-
-static void
-egg_histogram_view_finalize (GObject *object)
-{
- EggHistogramViewPrivate *priv;
-
- priv = EGG_HISTOGRAM_VIEW_GET_PRIVATE (object);
-
- if (priv->bins)
- g_free (priv->bins);
-
- G_OBJECT_CLASS (egg_histogram_view_parent_class)->finalize (object);
-}
-
-static void
-egg_histogram_view_dispose (GObject *object)
-{
- G_OBJECT_CLASS (egg_histogram_view_parent_class)->dispose (object);
-}
-
-static void
-egg_histogram_view_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- EggHistogramViewPrivate *priv;
-
- g_return_if_fail (EGG_IS_HISTOGRAM_VIEW (object));
- priv = EGG_HISTOGRAM_VIEW_GET_PRIVATE (object);
-
- switch (property_id) {
- case PROP_MINIMUM_BIN_VALUE:
- {
- gdouble v = g_value_get_double (value);
-
- if (v > priv->max_value)
- g_warning ("Minimum value `%f' larger than maximum value `%f'",
- v, priv->max_value);
- else {
- priv->min_value = v;
- priv->range = priv->max_value - v;
- priv->min_border = 0;
- }
- }
- break;
-
- case PROP_MAXIMUM_BIN_VALUE:
- {
- gdouble v = g_value_get_double (value);
-
- if (v < priv->min_value)
- g_warning ("Maximum value `%f' larger than minimum value `%f'",
- v, priv->min_value);
- else {
- priv->max_value = v;
- priv->range = v - priv->min_value;
- set_max_border (EGG_HISTOGRAM_VIEW (object));
- }
- }
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- return;
- }
-}
-
-static void
-egg_histogram_view_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- EggHistogramViewPrivate *priv;
-
- g_return_if_fail (EGG_IS_HISTOGRAM_VIEW (object));
- priv = EGG_HISTOGRAM_VIEW_GET_PRIVATE (object);
-
- switch (property_id) {
- case PROP_MINIMUM_BIN_VALUE:
- g_value_set_double (value, priv->min_value);
- break;
-
- case PROP_MAXIMUM_BIN_VALUE:
- g_value_set_double (value, priv->max_value);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- return;
- }
-}
-
-static gboolean
-is_on_border (EggHistogramViewPrivate *priv,
- gint x)
-{
- gint d1 = (priv->min_border + BORDER) - x;
- gint d2 = (priv->max_border + BORDER) - x;
- return ABS (d1) < 6 || ABS (d2) < 6;
-}
-
-static gint *
-get_grabbed_border (EggHistogramViewPrivate *priv,
- gint x)
-{
- gint d1 = (priv->min_border + BORDER) - x;
- gint d2 = (priv->max_border + BORDER) - x;
-
- if (ABS (d1) < 6)
- return &priv->min_border;
- else if (ABS (d2) < 6)
- return &priv->max_border;
-
- return NULL;
-}
-
-static gboolean
-egg_histogram_view_motion_notify (GtkWidget *widget,
- GdkEventMotion *event)
-{
- EggHistogramView *view;
- EggHistogramViewPrivate *priv;
-
- view = EGG_HISTOGRAM_VIEW (widget);
- priv = view->priv;
-
- if (priv->grabbing) {
- GtkAllocation allocation;
-
- gtk_widget_get_allocation (widget, &allocation);
-
- if ((event->x + BORDER > 0) && (event->x + BORDER < allocation.width)) {
- *priv->grabbed = event->x;
- gtk_widget_queue_draw (widget);
- }
- }
- else {
- if (is_on_border (priv, event->x))
- set_cursor_type (view, GDK_FLEUR);
- else
- set_cursor_type (view, GDK_ARROW);
- }
-
- return TRUE;
-}
-
-static gboolean
-egg_histogram_view_button_release (GtkWidget *widget,
- GdkEventButton *event)
-{
- EggHistogramView *view;
-
- view = EGG_HISTOGRAM_VIEW (widget);
- set_cursor_type (view, GDK_ARROW);
- view->priv->grabbing = FALSE;
- g_signal_emit (widget, egg_histogram_view_signals[CHANGED], 0);
-
- return TRUE;
-}
-
-static gboolean
-egg_histogram_view_button_press (GtkWidget *widget,
- GdkEventButton *event)
-{
- EggHistogramView *view;
- EggHistogramViewPrivate *priv;
-
- view = EGG_HISTOGRAM_VIEW (widget);
- priv = view->priv;
-
- if (is_on_border (priv, event->x)) {
- priv->grabbing = TRUE;
- priv->grabbed = get_grabbed_border (priv, event->x);
- set_cursor_type (view, GDK_FLEUR);
- }
-
- return TRUE;
-}
-
-static void
-egg_histogram_view_class_init (EggHistogramViewClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- object_class->set_property = egg_histogram_view_set_property;
- object_class->get_property = egg_histogram_view_get_property;
- object_class->dispose = egg_histogram_view_dispose;
- object_class->finalize = egg_histogram_view_finalize;
-
- widget_class->size_request = egg_histogram_view_size_request;
- widget_class->expose_event = egg_histogram_view_expose;
- widget_class->button_press_event = egg_histogram_view_button_press;
- widget_class->button_release_event = egg_histogram_view_button_release;
- widget_class->motion_notify_event = egg_histogram_view_motion_notify;
-
- egg_histogram_view_properties[PROP_MINIMUM_BIN_VALUE] =
- g_param_spec_double ("minimum-bin-value",
- "Smallest possible bin value",
- "Smallest possible bin value, everything below is discarded.",
- 0.0, G_MAXDOUBLE, 0.0,
- G_PARAM_READWRITE);
-
- egg_histogram_view_properties[PROP_MAXIMUM_BIN_VALUE] =
- g_param_spec_double ("maximum-bin-value",
- "Largest possible bin value",
- "Largest possible bin value, everything above is discarded.",
- 0.0, G_MAXDOUBLE, 256.0,
- G_PARAM_READWRITE);
-
- g_object_class_install_property (object_class, PROP_MINIMUM_BIN_VALUE, egg_histogram_view_properties[PROP_MINIMUM_BIN_VALUE]);
- g_object_class_install_property (object_class, PROP_MAXIMUM_BIN_VALUE, egg_histogram_view_properties[PROP_MAXIMUM_BIN_VALUE]);
-
- egg_histogram_view_signals[CHANGED] =
- g_signal_new ("changed",
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
- G_STRUCT_OFFSET (EggHistogramViewClass, changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- g_type_class_add_private (klass, sizeof (EggHistogramViewPrivate));
-}
-
-static void
-egg_histogram_view_init (EggHistogramView *view)
-{
- EggHistogramViewPrivate *priv;
-
- view->priv = priv = EGG_HISTOGRAM_VIEW_GET_PRIVATE (view);
-
- priv->bins = NULL;
- priv->data = NULL;
- priv->n_bins = 0;
- priv->n_elements = 0;
- priv->min_value = priv->min_border = 0;
- priv->max_value = priv->max_border = 256;
-
- priv->cursor_type = GDK_ARROW;
- priv->grabbing = FALSE;
-
- gtk_widget_add_events (GTK_WIDGET (view),
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK |
- GDK_BUTTON1_MOTION_MASK |
- GDK_POINTER_MOTION_MASK);
-}