float ScrollView::calculate_preferred_height(Canvas &canvas, float width) { if (style_cascade().computed_value("height").is_length()) return style_cascade().computed_value("height").number(); float height = impl->content_container->get_preferred_height(canvas, width); if (impl->overflow_y == ContentOverflow::scroll) height += impl->scroll_x->get_preferred_height(canvas, width); return height; }
float LabelView::calculate_preferred_height(Canvas &canvas, float width) { if (style_cascade().computed_value("height").is_keyword("auto")) { Font font = impl->get_font(this, canvas); return font.get_font_metrics(canvas).get_line_height(); } else return style_cascade().computed_value("height").number(); }
float ScrollView::calculate_preferred_width(Canvas &canvas) { if (style_cascade().computed_value("width").is_length()) return style_cascade().computed_value("width").number(); float width = impl->content_container->get_preferred_width(canvas); if (impl->overflow_x == ContentOverflow::scroll) width += impl->scroll_x->get_preferred_width(canvas); return width; }
float LabelView::calculate_preferred_width(Canvas &canvas) { if (style_cascade().computed_value("width").is_keyword("auto")) { Font font = impl->get_font(this, canvas); return font.measure_text(canvas, impl->_text).advance.width + 1.0f; } else return style_cascade().computed_value("width").number(); }
void LabelView::render_content(Canvas &canvas) { Font font = impl->get_font(this, canvas); FontMetrics font_metrics = font.get_font_metrics(canvas); float baseline = font_metrics.get_baseline_offset(); std::string clipped_text = impl->_text; GlyphMetrics advance = font.measure_text(canvas, clipped_text); if (advance.advance.width > geometry().content_width) { std::string ellipsis = StringHelp::unicode_to_utf8(0x2026); GlyphMetrics ellipsis_advance = font.measure_text(canvas, ellipsis); switch (impl->_line_break_mode) { case LineBreakMode::clipping: clipped_text = clipped_text.substr(0, font.clip_from_left(canvas, clipped_text, geometry().content_width)); break; case LineBreakMode::truncating_head: clipped_text = ellipsis + clipped_text.substr(font.clip_from_right(canvas, clipped_text, geometry().content_width - ellipsis_advance.advance.width)); break; case LineBreakMode::truncating_middle: { std::string text_left = clipped_text.substr(0, font.clip_from_left(canvas, clipped_text, geometry().content_width * 0.5f - ellipsis_advance.advance.width)); std::string text_right = clipped_text.substr(font.clip_from_right(canvas, clipped_text, geometry().content_width * 0.5f - ellipsis_advance.advance.width)); clipped_text = text_left + ellipsis + text_right; } break; case LineBreakMode::truncating_tail: clipped_text = clipped_text.substr(0, font.clip_from_left(canvas, clipped_text, geometry().content_width - ellipsis_advance.advance.width)) + ellipsis; break; default: break; } advance = font.measure_text(canvas, clipped_text); if (advance.advance.width > geometry().content_width) return; // Still no room. Draw nothing! } Colorf color = style_cascade().computed_value("color").color(); if (impl->text_alignment == TextAlignment::left) { font.draw_text(canvas, Pointf(0.0f, baseline), clipped_text, color); } else if (impl->text_alignment == TextAlignment::right) { font.draw_text(canvas, Pointf(geometry().content_width - advance.advance.width, baseline), clipped_text, color); } else if (impl->text_alignment == TextAlignment::center) { font.draw_text(canvas, Pointf(std::round((geometry().content_width - advance.advance.width) * 0.5f), baseline), clipped_text, color); } }
void layout_subviews(Canvas &canvas) override { for (auto &view : subviews()) { // To do: maybe we need a mode to specify if the X axis is locked or infinite float width = geometry().content_width; //view->get_preferred_width(canvas); float height = view->get_preferred_height(canvas, width); ViewGeometry geometry = ViewGeometry::from_content_box(style_cascade(), Rectf(0.0f, 0.0f, width, height)); geometry.content_x = 0.0f; geometry.content_y = 0.0f; view->set_geometry(geometry); view->layout_subviews(canvas); // Maybe this should be handled in View? } }
bool ScrollBarView::vertical() const { return style_cascade().computed_value("flex-direction").is_keyword("column"); }
void LabelView::layout_subviews(Canvas &canvas) { View::layout_subviews(canvas); impl->font = style_cascade().get_font(canvas); // Reset the font on new layout }
void LabelView::reset_font() { /// Reset the font. impl->font = style_cascade().font(Canvas()); // Canvas actually is not needed in this case, use stub. impl->font_color = style_cascade().computed_value("color").color(); }