Exemple #1
0
void
HippoCanvas::setTheme(HippoCanvasTheme *theme)
{
    if (theme_ == theme)
        return;

    theme_ = theme;

    hippo_canvas_context_win_clear_style(context_);
    hippo_canvas_context_emit_style_changed(HIPPO_CANVAS_CONTEXT(context_), TRUE);

    markRequestChanged();
}
void
HippoCanvas::createChildren()
{
    hscroll_->create();
    vscroll_->create();

    tooltip_->setForWindow(window_);
    tooltip_->create();

    // this should register any embedded controls, set their parents,
    // which as a side effect should create them all
    if (root_ != (HippoCanvasItem*) NULL) {
        g_assert(HIPPO_IS_CANVAS_CONTEXT(context_));
        hippo_canvas_item_set_context(root_, HIPPO_CANVAS_CONTEXT(context_));
    }
}
Exemple #3
0
void
HippoCanvas::setRoot(HippoCanvasItem *item)
{
    if (root_ == item)
        return;

    rootDestroy_.disconnect();
    rootRequestChanged_.disconnect();
    rootPaintNeeded_.disconnect();

    root_ = item;
    if (item) {
        rootDestroy_.connect(G_OBJECT(item), "destroy",
            slot(this, &HippoCanvas::onRootDestroy));
        rootRequestChanged_.connect(G_OBJECT(item), "request-changed",
            slot(this, &HippoCanvas::onRootRequestChanged));
        rootPaintNeeded_.connect(G_OBJECT(item), "paint-needed",
            slot(this, &HippoCanvas::onRootPaintNeeded));
        rootTooltipChanged_.connect(G_OBJECT(item), "tooltip-changed",
            slot(this, &HippoCanvas::onRootTooltipChanged));
        hippo_canvas_item_set_context(item, HIPPO_CANVAS_CONTEXT(context_));
    }
    markRequestChanged();
}
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);
    }
}
static PangoLayout*
create_layout(HippoCanvasText *text,
              int              allocation_width)
{
    HippoCanvasBox *box = HIPPO_CANVAS_BOX(text);
    PangoLayout *layout;
    HippoCanvasStyle *style = hippo_canvas_context_get_style(HIPPO_CANVAS_CONTEXT(text));

    g_return_val_if_fail(box->context != NULL, NULL);
    
    layout = hippo_canvas_context_create_layout(box->context);

    if (box->font_desc) {
        PangoFontDescription *merged = pango_font_description_copy(hippo_canvas_style_get_font(style));
        pango_font_description_merge(merged, box->font_desc, TRUE);
        pango_layout_set_font_description(layout, merged);
        pango_font_description_free(merged);
    } else {
        pango_layout_set_font_description(layout, hippo_canvas_style_get_font(style));
    }
    
    {
        PangoAttrList *attrs;
        HippoTextDecoration decoration = hippo_canvas_style_get_text_decoration(style);
        
        if (text->attributes)
            attrs = pango_attr_list_copy(text->attributes);
        else
            attrs = pango_attr_list_new();

        
        if (ABS(1.0 - text->font_scale) > .000001) {
            PangoAttribute *attr = pango_attr_scale_new(text->font_scale);
            attr->start_index = 0;
            attr->end_index = G_MAXUINT;
            pango_attr_list_insert(attrs, attr);
        }

        if ((decoration & HIPPO_TEXT_DECORATION_UNDERLINE) != 0) {
            PangoAttribute *attr = pango_attr_underline_new(TRUE);
            attr->start_index = 0;
            attr->end_index = G_MAXUINT;
            pango_attr_list_insert(attrs, attr);
        }

        if ((decoration & HIPPO_TEXT_DECORATION_LINE_THROUGH) != 0) {
            PangoAttribute *attr = pango_attr_strikethrough_new(TRUE);
            attr->start_index = 0;
            attr->end_index = G_MAXUINT;
            pango_attr_list_insert(attrs, attr);
        }

        pango_layout_set_attributes(layout, attrs);
        pango_attr_list_unref(attrs);
    }
    
    if (text->text != NULL) {
        pango_layout_set_text(layout, text->text, -1);
    }

    if (allocation_width >= 0) {
        int layout_width, layout_height;
        pango_layout_get_size(layout, &layout_width, &layout_height);
        layout_width /= PANGO_SCALE;
        layout_height /= PANGO_SCALE;
        
        /* Force layout smaller if required, but we don't want to make
         * the layout _wider_ because it breaks alignment, so only do
         * this if required.
         */
        if (layout_width > allocation_width) {
            pango_layout_set_width(layout, allocation_width * PANGO_SCALE);

            /* If we set ellipsize, then it overrides wrapping. If we get
             * too-small allocation for HIPPO_CANVAS_SIZE_FULL_WIDTH, then
             * we want to ellipsize instead of wrapping.
             */
            if (text->size_mode == HIPPO_CANVAS_SIZE_WRAP_WORD) {
                pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
            } else {
                pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
            }

            /* For now if we say ellipsize end, we always just want one line.
             * Maybe this should be an orthogonal property?
             */
            if (text->size_mode == HIPPO_CANVAS_SIZE_ELLIPSIZE_END) {
                pango_layout_set_single_paragraph_mode(layout, TRUE);

                /* Pango's line separator character in this case is ugly, so we
                 * fix it. Not a very efficient approach, but oh well.
                 */
                if (text->text != NULL) {
                    char *new_text = remove_newlines(text->text);
                    /* avoid making the layout recompute everything
                     * if we didn't have newlines anyhow
                     */
                    if (strcmp(text->text, new_text) != 0) {
                        pango_layout_set_text(layout, new_text, -1);
                    }
                    g_free(new_text);
                }
            }
        }
    }
    
    return layout;
}