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));
}
Beispiel #5
0
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++;
	}
}