Beispiel #1
0
/**
 * gwy_data_view_get_top_layer:
 * @data_view: A #GwyDataView.
 *
 * Returns the top layer this data view currently uses, or %NULL if none
 * is present.
 *
 * Returns: The currently used top layer.
 **/
GwyVectorLayer*
gwy_data_view_get_top_layer(GwyDataView *data_view)
{
    g_return_val_if_fail(GWY_IS_DATA_VIEW(data_view), NULL);

    return GWY_VECTOR_LAYER(data_view->top_layer);
}
Beispiel #2
0
/**
 * gwy_data_view_get_pixbuf:
 * @data_view: A #GwyDataView.
 * @max_width: Pixbuf width that should not be exceeeded.  Value smaller than
 *             1 means unlimited size.
 * @max_height: Pixbuf height that should not be exceeeded.  Value smaller than
 *              1 means unlimited size.
 *
 * Creates and returns a pixbuf from the data view.
 *
 * If the data is not square, the resulting pixbuf is also nonsquare, this is
 * different from gwy_data_view_get_thumbnail().  The returned pixbuf also
 * never has alpha channel.
 *
 * Returns: The pixbuf as a newly created #GdkPixbuf, it should be freed
 *          when no longer needed.  It is never larger than the actual data
 *          size, as @max_width and @max_height are only upper limits.
 *
 * Since: 1.5
 **/
GdkPixbuf*
gwy_data_view_get_pixbuf(GwyDataView *data_view,
                         gint max_width,
                         gint max_height)
{
    GdkPixbuf *pixbuf;
    gint width, height, width_scaled, height_scaled;
    gdouble xscale, yscale, scale;

    g_return_val_if_fail(GWY_IS_DATA_VIEW(data_view), NULL);
    g_return_val_if_fail(data_view->pixbuf, NULL);

    width = gdk_pixbuf_get_width(data_view->pixbuf);
    height = gdk_pixbuf_get_height(data_view->pixbuf);
    xscale = (max_width > 0) ? (gdouble)max_width/width : 1.0;
    yscale = (max_height > 0) ? (gdouble)max_height/height : 1.0;
    scale = MIN(MIN(xscale, yscale), 1.0);
    width_scaled = (gint)(scale*width);
    height_scaled = (gint)(scale*height);
    if (max_width)
        width_scaled = CLAMP(width_scaled, 1, max_width);
    if (max_height)
        height_scaled = CLAMP(height_scaled, 1, max_height);

    pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE,
                            BITS_PER_SAMPLE, width_scaled, height_scaled);
    gwy_debug_objects_creation(G_OBJECT(pixbuf));
    gdk_pixbuf_scale(data_view->pixbuf, pixbuf, 0, 0,
                     width_scaled, height_scaled, 0.0, 0.0,
                     scale, scale, GDK_INTERP_TILES);

    return pixbuf;
}
Beispiel #3
0
static void
gwy_data_view_set_layer(GwyDataView *data_view,
                        GwyDataViewLayer **which,
                        GwyDataViewLayer *layer)
{
    g_return_if_fail(GWY_IS_DATA_VIEW(data_view));
    g_return_if_fail(which);

    if (layer == *which)
        return;
    if (*which) {
        gwy_data_view_layer_unplugged(*which);
        (*which)->parent = NULL;
        g_object_unref(*which);
    }
    if (layer) {
        g_assert(layer->parent == NULL);
        g_object_ref(layer);
        gtk_object_sink(GTK_OBJECT(layer));
        layer->parent = (GtkWidget*)data_view;
        gwy_data_view_layer_plugged(layer);
    }
    *which = layer;
    data_view->force_update = TRUE;
}
Beispiel #4
0
/**
 * gwy_data_view_get_thumbnail:
 * @data_view: A #GwyDataView.
 * @size: Requested thumbnail size.
 *
 * Creates and returns a thumbnail of the data view.
 *
 * If the data is not square, it is centered onto the pixbuf, with transparent
 * borders.  The returned pixbuf always has an alpha channel, even if it fits
 * exactly.
 *
 * Returns: The thumbnail as a newly created #GdkPixbuf, which should be freed
 *          when no longer needed.
 **/
GdkPixbuf*
gwy_data_view_get_thumbnail(GwyDataView *data_view,
                            gint size)
{
    GdkPixbuf *pixbuf;
    gint width, height, width_scaled, height_scaled;
    gdouble scale;

    g_return_val_if_fail(GWY_IS_DATA_VIEW(data_view), NULL);
    g_return_val_if_fail(data_view->pixbuf, NULL);
    g_return_val_if_fail(size > 0, NULL);
    pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE,
                            BITS_PER_SAMPLE, size, size);
    gwy_debug_objects_creation(G_OBJECT(pixbuf));
    gdk_pixbuf_fill(pixbuf, 0x00000000);
    width = gdk_pixbuf_get_width(data_view->pixbuf);
    height = gdk_pixbuf_get_height(data_view->pixbuf);
    scale = MIN((gdouble)size/width, (gdouble)size/height);
    width_scaled = CLAMP((gint)(scale*width), 1, size);
    height_scaled = CLAMP((gint)(scale*height), 1, size);
    gdk_pixbuf_scale(data_view->pixbuf, pixbuf,
                     (size - width_scaled)/2, (size - height_scaled)/2,
                     width_scaled, height_scaled,
                     (size - width_scaled)/2, (size - height_scaled)/2,
                     scale, scale, GDK_INTERP_TILES);

    return pixbuf;
}
Beispiel #5
0
/**
 * gwy_data_view_get_alpha_layer:
 * @data_view: A #GwyDataView.
 *
 * Returns the alpha layer this data view currently uses, or %NULL if none
 * is present.
 *
 * Returns: The currently used alpha layer.
 **/
GwyPixmapLayer*
gwy_data_view_get_alpha_layer(GwyDataView *data_view)
{
    g_return_val_if_fail(GWY_IS_DATA_VIEW(data_view), NULL);

    return GWY_PIXMAP_LAYER(data_view->alpha_layer);
}
Beispiel #6
0
/**
 * gwy_data_view_get_vexcess:
 * @data_view: A #GwyDataView.
 *
 * Return the vertical excess of widget size to data size.
 *
 * Do not use.  Only useful for #GwyDataWindow implementation.
 *
 * Returns: The execess.
 **/
gdouble
gwy_data_view_get_vexcess(GwyDataView *data_view)
{
    g_return_val_if_fail(GWY_IS_DATA_VIEW(data_view), 0);
    if (!data_view->pixbuf)
        return 0;

    return (gdouble)GTK_WIDGET(data_view)->allocation.height
                    / gdk_pixbuf_get_height(data_view->pixbuf) - 1.0;
}
Beispiel #7
0
/**
 * gwy_data_view_coords_real_to_xy:
 * @data_view: A #GwyDataView.
 * @xreal: A physical x-coordinate in the data sample..
 * @yreal: A physical y-coordinate in the data sample.
 * @xscr: Where the screen x-coordinate relative to widget origin should be
 *        stored.
 * @yscr: Where the screen y-coordinate relative to widget origin should be
 *        stored.
 *
 * Recomputes physical coordinate in the sample to screen coordinate relative
 * to widget origin.
 **/
void
gwy_data_view_coords_real_to_xy(GwyDataView *data_view,
                                gdouble xreal, gdouble yreal,
                                gint *xscr, gint *yscr)
{
    g_return_if_fail(GWY_IS_DATA_VIEW(data_view));

    if (xscr)
        *xscr = floor(xreal/data_view->xmeasure + 0.5) + data_view->xoff;
    if (yscr)
        *yscr = floor(yreal/data_view->ymeasure + 0.5) + data_view->yoff;
}
Beispiel #8
0
/**
 * gwy_data_view_coords_xy_to_real:
 * @data_view: A #GwyDataView.
 * @xscr: A screen x-coordinate relative to widget origin.
 * @yscr: A screen y-coordinate relative to widget origin.
 * @xreal: Where the physical x-coordinate in the data sample should be stored.
 * @yreal: Where the physical y-coordinate in the data sample should be stored.
 *
 * Recomputes screen coordinates relative to widget origin to physical
 * coordinates in the sample.
 **/
void
gwy_data_view_coords_xy_to_real(GwyDataView *data_view,
                                gint xscr, gint yscr,
                                gdouble *xreal, gdouble *yreal)
{
    g_return_if_fail(GWY_IS_DATA_VIEW(data_view));

    if (xreal)
        *xreal = (xscr - data_view->xoff) * data_view->xmeasure;
    if (yreal)
        *yreal = (yscr - data_view->yoff) * data_view->ymeasure;
}
Beispiel #9
0
/**
 * gwy_data_view_update:
 * @data_view: A #GwyDataView.
 *
 * Instructs a data view to update self and repaint.
 *
 * It causes "updated" signal emission, among other things.
 *
 * FIXME: This function exists because it's impossible [now?] to watch changes
 * of datafields (and other things) properly.  Call it when you changed data
 * and want the view to reflect the change.
 **/
void
gwy_data_view_update(GwyDataView *data_view)
{
    GtkWidget *widget;

    gwy_debug(" ");
    g_return_if_fail(GWY_IS_DATA_VIEW(data_view));

    data_view->force_update = TRUE;
    gwy_data_view_maybe_resize(data_view);
    widget = GTK_WIDGET(data_view);
    if (widget->window)
        gdk_window_invalidate_rect(widget->window, NULL, TRUE);
    g_signal_emit(data_view, data_view_signals[UPDATED], 0);
}
Beispiel #10
0
/**
 * gwy_set_data_preview_size:
 * @data_view: A data view used for module preview.
 * @max_size: Maximum allowed @data_view size (width and height).
 *
 * Sets up data view zoom to not exceed specified size.
 *
 * Before calling this function, data keys have be set, data fields and layers
 * have to be present and physically square mode set in the container.
 * Sizing of both pixel-wise square and physically square displays is performed
 * correctly.
 *
 * Since: 2.7
 **/
void
gwy_set_data_preview_size(GwyDataView *data_view,
                          gint max_size)
{
    GwyContainer *container;
    GwyDataField *data_field;
    GwyPixmapLayer *layer;
    gdouble zoomval, scale, xreal, yreal;
    gboolean realsquare;
    gint xres, yres;
    const gchar *prefix;
    gchar *key;

    g_return_if_fail(GWY_IS_DATA_VIEW(data_view));
    g_return_if_fail(max_size >= 2);

    container = gwy_data_view_get_data(data_view);
    g_return_if_fail(GWY_IS_CONTAINER(container));

    layer = gwy_data_view_get_base_layer(data_view);
    g_return_if_fail(GWY_IS_PIXMAP_LAYER(layer));
    prefix = gwy_pixmap_layer_get_data_key(layer);
    g_return_if_fail(prefix);

    data_field = gwy_container_get_object_by_name(container, prefix);
    g_return_if_fail(GWY_IS_DATA_FIELD(data_field));

    prefix = gwy_data_view_get_data_prefix(data_view);
    g_return_if_fail(prefix);
    key = g_strconcat(prefix, "/realsquare", NULL);
    realsquare = FALSE;
    gwy_container_gis_boolean_by_name(container, key, &realsquare);
    g_free(key);

    xres = gwy_data_field_get_xres(data_field);
    yres = gwy_data_field_get_yres(data_field);
    if (!realsquare)
        zoomval = max_size/(gdouble)MAX(xres, yres);
    else {
        xreal = gwy_data_field_get_xreal(data_field);
        yreal = gwy_data_field_get_yreal(data_field);
        scale = MAX(xres/xreal, yres/yreal);
        zoomval = max_size/(scale*MAX(xreal, yreal));
    }
    gwy_data_view_set_zoom(data_view, zoomval);
}
Beispiel #11
0
/**
 * gwy_data_view_set_zoom:
 * @data_view: A #GwyDataView.
 * @zoom: A new zoom value.
 *
 * Sets zoom of @data_view to @zoom.
 *
 * Zoom greater than 1 means larger image on screen and vice versa.
 *
 * Note window manager can prevent the window from resize and thus the zoom
 * from change.
 **/
void
gwy_data_view_set_zoom(GwyDataView *data_view,
                       gdouble zoom)
{
    g_return_if_fail(GWY_IS_DATA_VIEW(data_view));
    /* XXX: what was this meant for?
    if (!data_view->pixbuf || !data_view->base_pixbuf)
        return;
        */

    gwy_debug("zoom = %g, new = %g", data_view->newzoom, zoom);
    if (fabs(log(data_view->newzoom/zoom)) < 0.001)
        return;

    data_view->newzoom = zoom;
    gtk_widget_queue_resize(GTK_WIDGET(data_view));
}
Beispiel #12
0
static void
gwy_data_view_destroy(GtkObject *object)
{
    GwyDataView *data_view;

    gwy_debug("destroying a GwyDataView %p (refcount = %u)",
              object, G_OBJECT(object)->ref_count);

    g_return_if_fail(GWY_IS_DATA_VIEW(object));

    data_view = GWY_DATA_VIEW(object);
    gwy_data_view_set_layer(data_view, &data_view->top_layer, NULL);
    gwy_data_view_set_layer(data_view, &data_view->alpha_layer, NULL);
    gwy_data_view_set_layer(data_view, &data_view->base_layer, NULL);

    if (GTK_OBJECT_CLASS(parent_class)->destroy)
        (*GTK_OBJECT_CLASS(parent_class)->destroy)(object);
}
Beispiel #13
0
/**
 * gwy_data_view_coords_xy_clamp:
 * @data_view: A #GwyDataView.
 * @xscr: A screen x-coordinate relative to widget origin.
 * @yscr: A screen y-coordinate relative to widget origin.
 *
 * Fixes screen coordinates @xscr and @yscr to be inside the data-displaying
 * area (which can be smaller than widget size).
 **/
void
gwy_data_view_coords_xy_clamp(GwyDataView *data_view,
                              gint *xscr, gint *yscr)
{
    GtkWidget *widget;
    gint size;

    g_return_if_fail(GWY_IS_DATA_VIEW(data_view));
    widget = GTK_WIDGET(data_view);

    if (xscr) {
        size = gdk_pixbuf_get_width(data_view->pixbuf);
        *xscr = CLAMP(*xscr, data_view->xoff, data_view->xoff + size-1);
    }
    if (yscr) {
        size = gdk_pixbuf_get_height(data_view->pixbuf);
        *yscr = CLAMP(*yscr, data_view->yoff, data_view->yoff + size-1);
    }
}
Beispiel #14
0
static void
gwy_data_view_finalize(GObject *object)
{
    GwyDataView *data_view;

    gwy_debug("finalizing a GwyDataView (refcount = %u)",
              object->ref_count);

    g_return_if_fail(GWY_IS_DATA_VIEW(object));

    data_view = GWY_DATA_VIEW(object);

    gwy_object_unref(data_view->base_layer);
    gwy_object_unref(data_view->alpha_layer);
    gwy_object_unref(data_view->top_layer);
    gwy_debug("    child data ref count %d", G_OBJECT(data_view->data)->ref_count);
    gwy_object_unref(data_view->data);

    G_OBJECT_CLASS(parent_class)->finalize(object);
}
Beispiel #15
0
static void
gwy_data_view_size_allocate(GtkWidget *widget,
                            GtkAllocation *allocation)
{
    GwyDataView *data_view;

    gwy_debug("allocating %d x %d",
              allocation->width, allocation->height);

    g_return_if_fail(widget != NULL);
    g_return_if_fail(GWY_IS_DATA_VIEW(widget));
    g_return_if_fail(allocation != NULL);

    widget->allocation = *allocation;

    if (GTK_WIDGET_REALIZED(widget)) {
        data_view = GWY_DATA_VIEW(widget);

        gdk_window_move_resize(widget->window,
                               allocation->x, allocation->y,
                               allocation->width, allocation->height);
        gwy_data_view_make_pixmap(data_view);
    }
}
Beispiel #16
0
/**
 * gwy_data_view_get_data:
 * @data_view: A #GwyDataView.
 *
 * Returns the data container used by @data_view.
 *
 * Returns: The data as a #GwyContainer.
 **/
GwyContainer*
gwy_data_view_get_data(GwyDataView *data_view)
{
    g_return_val_if_fail(GWY_IS_DATA_VIEW(data_view), NULL);
    return data_view->data;
}
Beispiel #17
0
/**
 * gwy_data_view_get_ymeasure:
 * @data_view: A #GwyDataView.
 *
 * Returns the ratio between vertical physical lengths and horizontal
 * screen lengths in pixels.
 *
 * Returns: The vertical measure.
 **/
gdouble
gwy_data_view_get_ymeasure(GwyDataView *data_view)
{
    g_return_val_if_fail(GWY_IS_DATA_VIEW(data_view), 1.0);
    return data_view->ymeasure;
}
Beispiel #18
0
/**
 * gwy_data_view_get_zoom:
 * @data_view: A #GwyDataView.
 *
 * Returns current zoom of @data_view.
 *
 * When a resize is queued, the new zoom value is returned.
 *
 * Returns: The zoom.
 **/
gdouble
gwy_data_view_get_zoom(GwyDataView *data_view)
{
    g_return_val_if_fail(GWY_IS_DATA_VIEW(data_view), 1.0);
    return data_view->newzoom;
}