void SliderView::layout_subviews(Canvas &canvas) { View::layout_subviews(canvas); auto track_geometry = impl->track->geometry(); float track_length = vertical() ? track_geometry.content_box().get_height() : track_geometry.content_box().get_width(); float thumb_length = vertical() ? impl->thumb->get_preferred_height(canvas, track_geometry.content_box().get_width()) : impl->thumb->get_preferred_width(canvas); float t = (float) (impl->_position - impl->_min_position) / (float) (impl->_max_position - impl->_min_position); float thumb_pos = t * (track_length - thumb_length); if (vertical()) { impl->thumb->style()->set("top: %1px;", thumb_pos); } else { impl->thumb->style()->set("left: %1px;", thumb_pos); } }
// Closes the box. LayoutBlockBox::CloseResult LayoutBlockBox::Close() { // If the last child of this block box is an inline box, then we haven't closed it; close it now! if (context == BLOCK) { CloseResult result = CloseInlineBlockBox(); if (result != OK) return LAYOUT_SELF; } // Otherwise, we're an inline context box; so close our last line, which will still be open. else { line_boxes.back()->Close(); // Expand our content area if any line boxes had to push themselves out. Vector2f content_area = box.GetSize(); for (size_t i = 0; i < line_boxes.size(); i++) content_area.x = Math::Max(content_area.x, line_boxes[i]->GetDimensions().x); box.SetContent(content_area); } // Set this box's height, if necessary. if (box.GetSize(Box::CONTENT).y < 0) { Vector2f content_area = box.GetSize(); content_area.y = Math::Clamp(box_cursor, min_height, max_height); if (element != NULL) content_area.y = Math::Max(content_area.y, space->GetDimensions().y); box.SetContent(content_area); } // Set the computed box on the element. if (element != NULL) { if (context == BLOCK) { // Calculate the dimensions of the box's *internal* content; this is the tightest-fitting box around all of the // internal elements, plus this element's padding. Vector2f content_box(0, 0); for (size_t i = 0; i < block_boxes.size(); i++) content_box.x = Math::Max(content_box.x, block_boxes[i]->GetBox().GetSize(Box::MARGIN).x); // Check how big our floated area is. Vector2f space_box = space->GetDimensions(); content_box.x = Math::Max(content_box.x, space_box.x); // If our content is larger than our window, then we can either extend our box, if we're set to not wrap // our inline content, or enable the horizontal scrollbar, if we're set to auto-scrollbars. If we're set to // always use scrollbars, then the horiontal scrollbar will already have been enabled in the constructor. if (content_box.x > box.GetSize().x) { if (!wrap_content) box.SetContent(Vector2f(content_box.x, box.GetSize().y)); else if (overflow_x_property == OVERFLOW_AUTO) { element->GetElementScroll()->EnableScrollbar(ElementScroll::HORIZONTAL, box.GetSize(Box::PADDING).x); if (!CatchVerticalOverflow()) return LAYOUT_SELF; } } content_box.x += (box.GetEdge(Box::PADDING, Box::LEFT) + box.GetEdge(Box::PADDING, Box::RIGHT)); content_box.y = box_cursor; content_box.y = Math::Max(content_box.y, space_box.y); if (!CatchVerticalOverflow(content_box.y)) return LAYOUT_SELF; content_box.y += (box.GetEdge(Box::PADDING, Box::TOP) + box.GetEdge(Box::PADDING, Box::BOTTOM)); element->SetBox(box); element->SetContentBox(space->GetOffset(), content_box); // Format any scrollbars which were enabled on this element. element->GetElementScroll()->FormatScrollbars(); } else element->SetBox(box); } // Increment the parent's cursor. if (parent != NULL) { // If this close fails, it means this block box has caused our parent block box to generate an automatic // vertical scrollbar. if (!parent->CloseBlockBox(this)) return LAYOUT_PARENT; } // If we represent a positioned element, then we can now (as we've been sized) act as the containing block for all // the absolutely-positioned elements of our descendants. if (context == BLOCK && element != NULL) { if (element->GetPosition() != POSITION_STATIC) CloseAbsoluteElements(); } return OK; }