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_)); } }
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; }