Exemple #1
0
static void
hippo_canvas_grip_paint_below_children(HippoCanvasBox  *box,
                                       cairo_t         *cr,
                                       HippoRectangle  *damaged_box)
{
    HIPPO_CANVAS_BOX_CLASS(hippo_canvas_grip_parent_class)->paint_below_children(box, cr, damaged_box);

#if 0
    HippoCanvasGrip *grip = HIPPO_CANVAS_GRIP(box);
    int x, y, w, h;

    get_grip_request(grip, &w, &h);

    hippo_canvas_box_align(box, w, h, &x, &y, &w, &h);

    cairo_rectangle(cr, x, y, w, h);
    cairo_clip(cr);

    if (grip->prelighted)
        hippo_cairo_set_source_rgba32(cr,
                                      hippo_canvas_context_get_color(box->context,
                                              HIPPO_STOCK_COLOR_BG_PRELIGHT));
    else
        hippo_cairo_set_source_rgba32(cr,
                                      hippo_canvas_context_get_color(box->context,
                                              HIPPO_STOCK_COLOR_BG_NORMAL));

    cairo_paint(cr);
#endif
}
Exemple #2
0
static void
hippo_canvas_image_paint_below_children(HippoCanvasBox  *box,
                                        cairo_t         *cr,
                                        HippoRectangle  *damaged_box)
{
    HippoCanvasImage *image = HIPPO_CANVAS_IMAGE(box);
    int x, y, w, h;
    int image_width, image_height;
    double xscale;
    double yscale;

    if (image->surface == NULL)
        return;

    image_width = cairo_image_surface_get_width(image->surface);
    image_height = cairo_image_surface_get_height(image->surface);

    /* Immediately short-circuit 0-sized image or scaled image,
     * which saves special cases in the math later on, in addition
     * to saving work
     */
    if (image_width == 0 || image_height == 0 ||
        image->scale_width == 0 || image->scale_height == 0)
        return;

    if (image->scale_width >= 0) {
        w = image->scale_width;
        xscale = image->scale_width / (double) image_width;
    } else {
        w = image_width;
        xscale = 1.0;
    }
    if (image->scale_height >= 0) {
        h = image->scale_height;
        yscale = image->scale_height / (double) image_height;
    } else {
        h = image_height;
        yscale = 1.0;
    }

    /* note that if an alignment is FILL the w/h will be increased
     * beyond the image's natural size, which will result in
     * a tiled image
     */
    
    hippo_canvas_box_align(box, w, h, &x, &y, &w, &h);

    cairo_rectangle(cr, x, y, w, h);
    cairo_clip(cr);

    cairo_scale (cr, xscale, yscale);
    cairo_translate (cr, x, y);
    cairo_set_source_surface(cr, image->surface, 0, 0);
    cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
    cairo_paint(cr);

    /* g_debug("cairo status %s", cairo_status_to_string(cairo_status(cr))); */
}
static void
hippo_canvas_widget_allocate(HippoCanvasItem *item,
                             int              width,
                             int              height,
                             gboolean         origin_changed)
{
    int x, y, w, h;
    int widget_x, widget_y;
    GtkAllocation child_allocation;
    HippoCanvasWidget *widget;
    HippoCanvasBox *box;

    widget = HIPPO_CANVAS_WIDGET(item);
    box = HIPPO_CANVAS_BOX(item);
    
    /* get the box set up */
    item_parent_class->allocate(item, width, height, origin_changed);

    if (widget->widget == NULL)
        return;
    
    /* this probably queues a resize, which is not ideal */
    update_widget_visibility(widget);
    
    /* Now do the GTK allocation for the child widget */
    w = widget->widget->requisition.width;
    h = widget->widget->requisition.height;

    hippo_canvas_box_align(box, w, h, &x, &y, &w, &h);

    widget_x = 0;
    widget_y = 0;
    if (box->context)
        hippo_canvas_context_translate_to_widget(box->context, item,
                                                 &widget_x, &widget_y);

    child_allocation.x = widget_x + x;
    child_allocation.y = widget_y + y;
    child_allocation.width = MAX(w, 1);
    child_allocation.height = MAX(h, 1);

    gtk_widget_size_allocate(widget->widget, &child_allocation);
}
static void
hippo_canvas_widget_allocate(HippoCanvasItem *item,
                             int              width,
                             int              height,
                             gboolean         origin_changed)
{
    int x, y, w, h;
    int widget_x, widget_y;
    GtkAllocation child_allocation;
    HippoCanvasWidget *widget;
    HippoCanvasBox *box;

    widget = HIPPO_CANVAS_WIDGET(item);
    box = HIPPO_CANVAS_BOX(item);
    
    /* get the box set up */
    item_parent_class->allocate(item, width, height, origin_changed);

    /* Now do the GTK allocation for the child widget */
    if (widget->widget == NULL || !GTK_WIDGET_VISIBLE(widget->widget))
        return;
    
    w = widget->widget->requisition.width;
    h = widget->widget->requisition.height;

    hippo_canvas_box_align(box, w, h, &x, &y, &w, &h);

    widget_x = 0;
    widget_y = 0;
    if (box->context)
        hippo_canvas_context_translate_to_widget(box->context, item,
                                                 &widget_x, &widget_y);

    child_allocation.x = widget_x + x;
    child_allocation.y = widget_y + y;
    child_allocation.width = w;
    child_allocation.height = h;

    gtk_widget_size_allocate(widget->widget, &child_allocation);
}
static void
hippo_canvas_control_position(HippoCanvasControl *control)
{
    HippoCanvasItem *item = HIPPO_CANVAS_ITEM(control);
    HippoCanvasBox *box = HIPPO_CANVAS_BOX(item);

    int x, y, w, h;
    int control_x, control_y;
    
    if (control->control == NULL)
        return;

    control->control->getLastRequest(&w, &h);

    hippo_canvas_box_align(box, w, h, &x, &y, &w, &h);

    control_x = 0;
    control_y = 0;
    if (box->context)
        hippo_canvas_context_translate_to_widget(box->context, item,
                                                 &control_x, &control_y);

    control->control->sizeAllocate(control_x + x, control_y + y, w, h);
}
static void
hippo_canvas_text_paint_below_children(HippoCanvasBox  *box,
                                       cairo_t         *cr,
                                       GdkRegion       *damaged_region)
{
    HippoCanvasText *text = HIPPO_CANVAS_TEXT(box);
    guint32 color_rgba;

    if (box->color_set) {
        color_rgba = box->color_rgba;
    } else {
        HippoCanvasStyle *style = hippo_canvas_context_get_style(HIPPO_CANVAS_CONTEXT(text));
        color_rgba = hippo_canvas_style_get_foreground_color(style);
    }
        
    /* It would seem more natural to compute whether we are ellipsized or
     * not when we are allocated to some width, but we don't have a layout
     * at that point. We could do it in get_content_height_request(), but
     * the parent could theoretically give us more width than it asked us
     * about (and there are also some quirks in HippoCanvasBox where it 
     * will call get_content_height_request() with a width if 0 at odd times),
     * so doing it here is more reliable. We use is_ellipsized only for
     * computing whether to show a tooltip, and we make the assumption that
     * if the user hasn't seen the text item drawn, they won't need a 
     * tooltip for it.
     */
    text->is_ellipsized = FALSE;

    if ((color_rgba & 0xff) != 0 && text->text != NULL) {
        PangoLayout *layout;
        int layout_width, layout_height;
        int x, y, w, h;
        int allocation_width, allocation_height;
        
        int space_left = box->border_left + box->padding_left;
        int space_right = box->border_right + box->padding_right;

        
        hippo_canvas_item_get_allocation(HIPPO_CANVAS_ITEM(box),
                                         &allocation_width, &allocation_height);
        
        layout = create_layout(text, allocation_width - space_left - space_right);
        pango_layout_get_size(layout, &layout_width, &layout_height);
        layout_width /= PANGO_SCALE;
        layout_height /= PANGO_SCALE;

        text->is_ellipsized = layout_is_ellipsized(layout);
        
        hippo_canvas_box_align(box,
                               layout_width, layout_height,
                               &x, &y, &w, &h);

        /* we can't really "fill" so we fall back to center if we seem to be
         * in fill mode
         */
        if (w > layout_width) {
            x += (w - layout_width) / 2;
        }
        if (h > layout_height) {
            y += (h - layout_height) / 2;
        }
        
        /* Clipping is needed since the layout size could exceed our
         * allocation if we got a too-small allocation.
         * FIXME It would be better to ellipsize or something instead, though.
         */
        cairo_save(cr);
        cairo_rectangle(cr, 0, 0, allocation_width, allocation_height);
        cairo_clip(cr);

        cairo_move_to (cr, x, y);
        hippo_cairo_set_source_rgba32(cr, color_rgba);
        pango_cairo_show_layout(cr, layout);
        cairo_restore(cr);
        
        g_object_unref(layout);
    }
}