void PaintPropertyTreeBuilder::buildTreeNodes(FrameView& frameView, PaintPropertyTreeBuilderContext& context) { // TODO(pdr): Creating paint properties for FrameView here will not be // needed once settings()->rootLayerScrolls() is enabled. // TODO(pdr): Make this conditional on the rootLayerScrolls setting. TransformationMatrix frameTranslate; frameTranslate.translate(frameView.x() + context.paintOffset.x(), frameView.y() + context.paintOffset.y()); RefPtr<TransformPaintPropertyNode> newTransformNodeForPreTranslation = TransformPaintPropertyNode::create(frameTranslate, FloatPoint3D(), context.currentTransform); context.transformForFixedPosition = newTransformNodeForPreTranslation.get(); context.paintOffsetForFixedPosition = LayoutPoint(); FloatRoundedRect contentClip(IntRect(IntPoint(), frameView.visibleContentSize())); RefPtr<ClipPaintPropertyNode> newClipNodeForContentClip = ClipPaintPropertyNode::create(newTransformNodeForPreTranslation.get(), contentClip, context.currentClip); context.currentClip = context.clipForAbsolutePosition = context.clipForFixedPosition = newClipNodeForContentClip.get(); DoubleSize scrollOffset = frameView.scrollOffsetDouble(); TransformationMatrix frameScroll; frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = TransformPaintPropertyNode::create(frameScroll, FloatPoint3D(), newTransformNodeForPreTranslation); context.currentTransform = context.transformForAbsolutePosition = newTransformNodeForScrollTranslation.get(); context.paintOffset = LayoutPoint(); context.paintOffsetForAbsolutePosition = LayoutPoint(); context.containerForAbsolutePosition = nullptr; frameView.setPreTranslation(newTransformNodeForPreTranslation.release()); frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release()); frameView.setContentClip(newClipNodeForContentClip.release()); }
void PaintPropertyTreeBuilder::walk(FrameView& frameView, const PaintPropertyTreeBuilderContext& context) { PaintPropertyTreeBuilderContext localContext(context); // TODO(pdr): Creating paint properties for FrameView here will not be // needed once settings()->rootLayerScrolls() is enabled. // TODO(pdr): Make this conditional on the rootLayerScrolls setting. TransformationMatrix frameTranslate; frameTranslate.translate(frameView.x(), frameView.y()); // The frame owner applies paint offset already. // This assumption may change in the future. ASSERT(context.paintOffset == LayoutPoint()); RefPtr<TransformPaintPropertyNode> newTransformNodeForPreTranslation = TransformPaintPropertyNode::create(frameTranslate, FloatPoint3D(), context.currentTransform); localContext.transformForFixedPositioned = newTransformNodeForPreTranslation.get(); localContext.paintOffsetForFixedPositioned = LayoutPoint(); FloatRoundedRect contentClip(IntRect(IntPoint(), frameView.visibleContentSize())); RefPtr<ClipPaintPropertyNode> newClipNodeForContentClip = ClipPaintPropertyNode::create(newTransformNodeForPreTranslation.get(), contentClip, localContext.currentClip); localContext.currentClip = localContext.clipForOutOfFlowPositioned = localContext.clipForFixedPositioned = newClipNodeForContentClip.get(); DoubleSize scrollOffset = frameView.scrollOffsetDouble(); TransformationMatrix frameScroll; frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = TransformPaintPropertyNode::create(frameScroll, FloatPoint3D(), newTransformNodeForPreTranslation); localContext.currentTransform = localContext.transformForOutOfFlowPositioned = newTransformNodeForScrollTranslation.get(); localContext.paintOffset = localContext.paintOffsetForOutOfFlowPositioned = LayoutPoint(); frameView.setPreTranslation(newTransformNodeForPreTranslation.release()); frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release()); frameView.setContentClip(newClipNodeForContentClip.release()); if (LayoutView* layoutView = frameView.layoutView()) walk(*layoutView, localContext); for (Frame* child = frameView.frame().tree().firstChild(); child; child = child->tree().nextSibling()) { if (!child->isLocalFrame()) continue; if (FrameView* childView = toLocalFrame(child)->view()) walk(*childView, localContext); } }
void PaintPropertyTreeBuilder::buildTreeNodes( FrameView& frameView, PaintPropertyTreeBuilderContext& context) { if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { LayoutView* layoutView = frameView.layoutView(); if (!layoutView) return; TransformationMatrix frameTranslate; frameTranslate.translate(frameView.x() + layoutView->location().x() + context.current.paintOffset.x(), frameView.y() + layoutView->location().y() + context.current.paintOffset.y()); context.current.transform = layoutView->getMutableForPainting() .ensurePaintProperties() .updatePaintOffsetTranslation(context.current.transform, frameTranslate, FloatPoint3D()); context.current.paintOffset = LayoutPoint(); context.current.renderingContextID = 0; context.current.shouldFlattenInheritedTransform = true; context.absolutePosition = context.current; context.containerForAbsolutePosition = nullptr; // This will get set in updateOutOfFlowContext(). context.fixedPosition = context.current; return; } TransformationMatrix frameTranslate; frameTranslate.translate(frameView.x() + context.current.paintOffset.x(), frameView.y() + context.current.paintOffset.y()); context.current.transform = updateFrameViewPreTranslation( frameView, context.current.transform, frameTranslate, FloatPoint3D()); FloatRoundedRect contentClip( IntRect(IntPoint(), frameView.visibleContentSize())); context.current.clip = updateFrameViewContentClip( frameView, context.current.clip, frameView.preTranslation(), contentClip); // Record the fixed properties before any scrolling occurs. const auto* fixedTransformNode = context.current.transform; auto* fixedScrollNode = context.current.scroll; ScrollOffset scrollOffset = frameView.scrollOffset(); if (frameView.isScrollable() || !scrollOffset.isZero()) { TransformationMatrix frameScroll; frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); context.current.transform = updateFrameViewScrollTranslation( frameView, frameView.preTranslation(), frameScroll, FloatPoint3D()); IntSize scrollClip = frameView.visibleContentSize(); IntSize scrollBounds = frameView.contentsSize(); bool userScrollableHorizontal = frameView.userInputScrollable(HorizontalScrollbar); bool userScrollableVertical = frameView.userInputScrollable(VerticalScrollbar); context.current.scroll = updateFrameViewScroll( frameView, context.current.scroll, frameView.scrollTranslation(), scrollClip, scrollBounds, userScrollableHorizontal, userScrollableVertical); } else { // Ensure pre-existing properties are cleared when there is no scrolling. frameView.setScrollTranslation(nullptr); frameView.setScroll(nullptr); } // Initialize the context for current, absolute and fixed position cases. // They are the same, except that scroll translation does not apply to // fixed position descendants. context.current.paintOffset = LayoutPoint(); context.current.renderingContextID = 0; context.current.shouldFlattenInheritedTransform = true; context.absolutePosition = context.current; context.containerForAbsolutePosition = nullptr; context.fixedPosition = context.current; context.fixedPosition.transform = fixedTransformNode; context.fixedPosition.scroll = fixedScrollNode; std::unique_ptr<PropertyTreeState> contentsState( new PropertyTreeState(context.current.transform, context.current.clip, context.currentEffect, context.current.scroll)); frameView.setTotalPropertyTreeStateForContents(std::move(contentsState)); }
void PaintPropertyTreeBuilder::updateFramePropertiesAndContext( FrameView& frameView, PaintPropertyTreeBuilderContext& context) { if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { // With root layer scrolling, the LayoutView (a LayoutObject) properties are // updated like other objects (see updatePropertiesAndContextForSelf and // updatePropertiesAndContextForChildren) instead of needing LayoutView- // specific property updates here. context.current.paintOffset.moveBy(frameView.location()); context.current.renderingContextID = 0; context.current.shouldFlattenInheritedTransform = true; context.absolutePosition = context.current; context.containerForAbsolutePosition = nullptr; context.fixedPosition = context.current; return; } TransformationMatrix frameTranslate; frameTranslate.translate(frameView.x() + context.current.paintOffset.x(), frameView.y() + context.current.paintOffset.y()); updateFrameViewPreTranslation(frameView, context.current.transform, frameTranslate, FloatPoint3D()); FloatRoundedRect contentClip( IntRect(IntPoint(), frameView.visibleContentSize())); updateFrameViewContentClip(frameView, context.current.clip, frameView.preTranslation(), contentClip); ScrollOffset scrollOffset = frameView.scrollOffset(); if (frameView.isScrollable() || !scrollOffset.isZero()) { TransformationMatrix frameScroll; frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); updateFrameViewScrollTranslation(frameView, frameView.preTranslation(), frameScroll, FloatPoint3D()); IntSize scrollClip = frameView.visibleContentSize(); IntSize scrollBounds = frameView.contentsSize(); bool userScrollableHorizontal = frameView.userInputScrollable(HorizontalScrollbar); bool userScrollableVertical = frameView.userInputScrollable(VerticalScrollbar); updateFrameViewScroll(frameView, context.current.scroll, frameView.scrollTranslation(), scrollClip, scrollBounds, userScrollableHorizontal, userScrollableVertical); } else { // Ensure pre-existing properties are cleared when there is no scrolling. frameView.setScrollTranslation(nullptr); frameView.setScroll(nullptr); } // Initialize the context for current, absolute and fixed position cases. // They are the same, except that scroll translation does not apply to // fixed position descendants. const auto* fixedTransformNode = frameView.preTranslation() ? frameView.preTranslation() : context.current.transform; auto* fixedScrollNode = context.current.scroll; DCHECK(frameView.preTranslation()); context.current.transform = frameView.preTranslation(); DCHECK(frameView.contentClip()); context.current.clip = frameView.contentClip(); if (const auto* scrollTranslation = frameView.scrollTranslation()) context.current.transform = scrollTranslation; if (auto* scroll = frameView.scroll()) context.current.scroll = scroll; context.current.paintOffset = LayoutPoint(); context.current.renderingContextID = 0; context.current.shouldFlattenInheritedTransform = true; context.absolutePosition = context.current; context.containerForAbsolutePosition = nullptr; context.fixedPosition = context.current; context.fixedPosition.transform = fixedTransformNode; context.fixedPosition.scroll = fixedScrollNode; std::unique_ptr<PropertyTreeState> contentsState( new PropertyTreeState(context.current.transform, context.current.clip, context.currentEffect, context.current.scroll)); frameView.setTotalPropertyTreeStateForContents(std::move(contentsState)); }
void WgMenu::_onRender( WgGfxDevice * pDevice, const WgRect& canvas, const WgRect& window, const WgRect& clip ) { WgWidget::_onRender(pDevice,canvas,window,clip); // Render the menu-items WgRect contentRect = m_pSkin?m_pSkin->ContentRect(canvas, m_state):canvas; WgRect contentClip( contentRect, clip ); // A clip rectangle for content. WgMenuItem * pItem = m_items.First(); int yPos = contentRect.y - m_contentOfs; int xPosText = contentRect.x + m_iconFieldWidth; int xPosIcon = contentRect.x; int textFieldLen = contentRect.w - m_iconFieldWidth - m_arrowFieldWidth; WgPen entryPen( pDevice, WgCoord( xPosText, yPos ), contentClip ); WgPen accelPen( pDevice, WgCoord( xPosText, yPos ), contentClip ); unsigned int item = 1; while( pItem ) { if( pItem->IsVisible() ) { if( pItem->GetType() == SEPARATOR ) { if( m_pSeparatorSkin ) { WgRect dest( contentRect.x, yPos + m_sepBorder.top, contentRect.w, m_pSeparatorSkin->PreferredSize().h ); m_pSeparatorSkin->Render( pDevice, dest, m_state, contentClip ); yPos += m_sepHeight; } } else { WgState state = WG_STATE_DISABLED; if( ((WgMenuEntry*)pItem)->IsEnabled() ) state = WG_STATE_NORMAL; if( item == m_markedItem ) state = WG_STATE_HOVERED; // Render the tile for this entry WgRect tileDest( contentRect.x, yPos, contentRect.w, m_entryHeight ); // WgRect tileClip( contentClip, tileDest); if( m_pEntrySkin ) m_pEntrySkin->Render( pDevice, tileDest, state, contentClip ); // Print the text (if any) const WgChar * pText = ((WgMenuEntry*)pItem)->GetText().Chars(); if( pText->Glyph() != 0 ) { WgTextAttr attr; WgTextTool::AddPropAttributes( attr, WgBase::GetDefaultTextprop(), state ); // if( m_pSkin ) // WgTextTool::SetAttrColor( attr, m_pSkin->TextColors(), mode ); WgTextTool::AddPropAttributes( attr, m_pEntryProp, state ); entryPen.SetAttributes( attr ); int y = yPos + (m_entryHeight - entryPen.GetLineHeight())/2 + entryPen.GetBaseline(); entryPen.SetPos( WgCoord( xPosText, y ) ); pDevice->PrintLine( entryPen, attr, pText ); } // Print the accel text (if any) const WgChar * pAccelText = ((WgMenuEntry*)pItem)->GetAccelText().Chars(); if( pAccelText->Glyph() != 0 ) { WgTextAttr attr; WgTextTool::AddPropAttributes( attr, WgBase::GetDefaultTextprop(), state ); // if( m_pSkin ) // WgTextTool::SetAttrColor( attr, m_pSkin->TextColors(), mode ); WgTextTool::AddPropAttributes( attr, m_pKeyAccelProp, state ); accelPen.SetAttributes( attr ); int y = yPos + (m_entryHeight - accelPen.GetLineHeight())/2 + accelPen.GetBaseline(); int width = WgTextTool::lineWidth( attr, state, pAccelText ); int x = xPosText + textFieldLen - width; accelPen.SetPos( WgCoord(x, y) ); pDevice->PrintLine( accelPen, attr, pAccelText ); } // Show the icon/checkbox/radiobutton (if any) switch( pItem->GetType() ) { case ENTRY: { WgSkinPtr pIcon = ((WgMenuEntry*)pItem)->GetIcon(); if( pIcon ) { WgSize sz = pIcon->PreferredSize(); if( sz.w > m_iconFieldWidth ) sz.w = m_iconFieldWidth; if( sz.h > m_entryHeight ) sz.h = m_entryHeight; int y = yPos + (m_entryHeight - sz.h)/2; int x = xPosIcon + (m_iconFieldWidth - sz.w)/2; pIcon->Render( pDevice, WgRect(x,y,sz), state, contentClip ); } } break; case CHECKBOX: { WgState checkboxState = state; if( ((WgMenuCheckBox*)pItem)->IsChecked() ) checkboxState.SetSelected(true); if( m_pCheckBoxSkin ) { WgSize sz = m_pCheckBoxSkin->PreferredSize(); int y = yPos + (m_entryHeight - sz.h)/2; int x = xPosIcon + (m_iconFieldWidth - sz.w)/2; m_pCheckBoxSkin->Render( pDevice, WgRect(x,y,sz), checkboxState, contentClip ); } } break; case RADIOBUTTON: { WgState radiobuttonState = state; if( ((WgMenuRadioButton*)pItem)->IsSelected() ) radiobuttonState.SetSelected(true); if( m_pRadioButtonSkin ) { WgSize sz = m_pRadioButtonSkin->PreferredSize(); int y = yPos + (m_entryHeight - sz.h)/2; int x = xPosIcon + (m_iconFieldWidth - sz.w)/2; m_pRadioButtonSkin->Render( pDevice, WgRect(x,y,sz), radiobuttonState, contentClip ); } } break; case SUBMENU: { //TODO: Show submenu arrow. } break; default: break; } yPos += m_entryHeight; } } pItem = pItem->Next(); item++; } }