📄 render_layer.cpp
字号:
delete m_hBar;
m_hBar = 0;
}
}
void
RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
{
if (hasScrollbar && !m_vBar) {
QScrollView* scrollView = m_object->element()->getDocument()->view();
m_vBar = new QScrollBar(Qt::Vertical, 0);
scrollView->addChild(m_vBar, 0, -50000);
if (!m_scrollMediator)
m_scrollMediator = new RenderScrollMediator(this);
m_scrollMediator->connect(m_vBar, SIGNAL(valueChanged(int)), SLOT(slotValueChanged(int)));
}
else if (!hasScrollbar && m_vBar) {
QScrollView* scrollView = m_object->element()->getDocument()->view();
scrollView->removeChild (m_vBar);
m_scrollMediator->disconnect(m_vBar, SIGNAL(valueChanged(int)),
m_scrollMediator, SLOT(slotValueChanged(int)));
delete m_vBar;
m_vBar = 0;
}
}
int
RenderLayer::verticalScrollbarWidth()
{
if (!m_vBar)
return 0;
return m_vBar->width();
}
int
RenderLayer::horizontalScrollbarHeight()
{
if (!m_hBar)
return 0;
return m_hBar->height();
}
void
RenderLayer::moveScrollbarsAside()
{
if (m_hBar)
m_hBar->move(0, -50000);
if (m_vBar)
m_vBar->move(0, -50000);
}
void
RenderLayer::positionScrollbars(const QRect& absBounds)
{
if (m_vBar) {
m_vBar->move(absBounds.x()+absBounds.width()-m_object->borderRight()-m_vBar->width(),
absBounds.y()+m_object->borderTop());
m_vBar->resize(m_vBar->width(), absBounds.height() -
(m_object->borderTop()+m_object->borderBottom()) -
(m_hBar ? m_hBar->height()-1 : 0));
}
if (m_hBar) {
m_hBar->move(absBounds.x()+m_object->borderLeft(),
absBounds.y()+absBounds.height()-m_object->borderBottom()-m_hBar->height());
m_hBar->resize(absBounds.width() - (m_object->borderLeft()+m_object->borderRight()) -
(m_vBar ? m_vBar->width()-1 : 0),
m_hBar->height());
}
}
int RenderLayer::scrollWidth()
{
if (m_scrollDimensionsDirty)
computeScrollDimensions();
return m_scrollWidth;
}
int RenderLayer::scrollHeight()
{
if (m_scrollDimensionsDirty)
computeScrollDimensions();
return m_scrollHeight;
}
void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar)
{
m_scrollDimensionsDirty = false;
int rightPos = m_object->rightmostPosition(true, false) - m_object->borderLeft();
int bottomPos = m_object->lowestPosition(true, false) - m_object->borderTop();
int clientWidth = m_object->clientWidth();
int clientHeight = m_object->clientHeight();
m_scrollWidth = kMax(rightPos, clientWidth);
m_scrollHeight = kMax(bottomPos, clientHeight);
if (needHBar)
*needHBar = rightPos > clientWidth;
if (needVBar)
*needVBar = bottomPos > clientHeight;
}
void
RenderLayer::updateScrollInfoAfterLayout()
{
m_scrollDimensionsDirty = true;
if (m_object->style()->overflow() == OHIDDEN)
return; // All we had to do was dirty.
bool needHorizontalBar, needVerticalBar;
computeScrollDimensions(&needHorizontalBar, &needVerticalBar);
if (m_object->style()->overflow() != OMARQUEE) {
// Layout may cause us to be in an invalid scroll position. In this case we need
// to pull our scroll offsets back to the max (or push them up to the min).
int newX = kMax(0, kMin(m_scrollX, scrollWidth() - m_object->clientWidth()));
int newY = kMax(0, kMin(m_scrollY, scrollHeight() - m_object->clientHeight()));
if (newX != m_scrollX || newY != m_scrollY)
scrollToOffset(newX, newY);
}
bool haveHorizontalBar = m_hBar;
bool haveVerticalBar = m_vBar;
// overflow:scroll should just enable/disable.
if (m_object->style()->overflow() == OSCROLL) {
m_hBar->setEnabled(needHorizontalBar);
m_vBar->setEnabled(needVerticalBar);
}
// overflow:auto may need to lay out again if scrollbars got added/removed.
bool scrollbarsChanged = (m_object->hasAutoScrollbars()) &&
(haveHorizontalBar != needHorizontalBar || haveVerticalBar != needVerticalBar);
if (scrollbarsChanged) {
setHasHorizontalScrollbar(needHorizontalBar);
setHasVerticalScrollbar(needVerticalBar);
#if APPLE_CHANGES
// Force an update since we know the scrollbars have changed things.
if (m_object->document()->hasDashboardRegions())
m_object->document()->setDashboardRegionsDirty(true);
#endif
m_object->repaint();
if (m_object->style()->overflow() == OAUTO) {
// Our proprietary overflow: overlay value doesn't trigger a layout.
m_object->setNeedsLayout(true);
if (m_object->isRenderBlock())
static_cast<RenderBlock*>(m_object)->layoutBlock(true);
else
m_object->layout();
}
}
// Set up the range (and page step/line step).
if (m_hBar) {
int clientWidth = m_object->clientWidth();
int pageStep = (clientWidth-PAGE_KEEP);
if (pageStep < 0) pageStep = clientWidth;
m_hBar->setSteps(LINE_STEP, pageStep);
#ifdef APPLE_CHANGES
m_hBar->setKnobProportion(clientWidth, m_scrollWidth);
#else
m_hBar->setRange(0, m_scrollWidth-clientWidth);
m_object->repaintRectangle(QRect(m_object->borderLeft(), m_object->borderTop() + clientHeight(),
horizontalScrollbarHeight(),
m_object->width() - m_object->borderLeft() - m_object->borderRight()));
#endif
}
if (m_vBar) {
int clientHeight = m_object->clientHeight();
int pageStep = (clientHeight-PAGE_KEEP);
if (pageStep < 0) pageStep = clientHeight;
m_vBar->setSteps(LINE_STEP, pageStep);
#ifdef APPLE_CHANGES
m_vBar->setKnobProportion(clientHeight, m_scrollHeight);
#else
m_vBar->setRange(0, m_scrollHeight-clientHeight);
#endif
m_object->repaintRectangle(QRect(m_object->borderLeft() + m_object->clientWidth(),
m_object->borderTop(), verticalScrollbarWidth(),
m_object->height() - m_object->borderTop() - m_object->borderBottom()));
}
#if APPLE_CHANGES
// Force an update since we know the scrollbars have changed things.
if (m_object->document()->hasDashboardRegions())
m_object->document()->setDashboardRegionsDirty(true);
#endif
m_object->repaint();
}
#if APPLE_CHANGES
void
RenderLayer::paintScrollbars(QPainter* p, const QRect& damageRect)
{
// Move the widgets if necessary. We normally move and resize widgets during layout, but sometimes
// widgets can move without layout occurring (most notably when you scroll a document that
// contains fixed positioned elements).
if (m_hBar || m_vBar) {
int x = 0;
int y = 0;
convertToLayerCoords(root(), x, y);
QRect layerBounds = QRect(x, y, width(), height());
positionScrollbars(layerBounds);
}
// Now that we're sure the scrollbars are in the right place, paint them.
if (m_hBar)
m_hBar->paint(p, damageRect);
if (m_vBar)
m_vBar->paint(p, damageRect);
}
#endif
bool RenderLayer::scroll(KWQScrollDirection direction, KWQScrollGranularity granularity, float multiplier)
{
bool didHorizontalScroll = false;
bool didVerticalScroll = false;
if (m_hBar != 0) {
if (granularity == KWQScrollDocument) {
// Special-case for the KWQScrollDocument granularity. A document scroll can only be up
// or down and in both cases the horizontal bar goes all the way to the left.
didHorizontalScroll = m_hBar->scroll(KWQScrollLeft, KWQScrollDocument, multiplier);
} else {
didHorizontalScroll = m_hBar->scroll(direction, granularity, multiplier);
}
}
if (m_vBar != 0) {
didVerticalScroll = m_vBar->scroll(direction, granularity, multiplier);
}
return (didHorizontalScroll || didVerticalScroll);
}
void
RenderLayer::paint(QPainter *p, const QRect& damageRect, bool selectionOnly, RenderObject *paintingRoot)
{
paintLayer(this, p, damageRect, false, selectionOnly, paintingRoot);
}
static void setClip(QPainter* p, const QRect& paintDirtyRect, const QRect& clipRect)
{
if (paintDirtyRect == clipRect)
return;
p->save();
#if APPLE_CHANGES
p->addClip(clipRect);
#else
QRect clippedRect = p->xForm(clipRect);
QRegion creg(clippedRect);
QRegion old = p->clipRegion();
if (!old.isNull())
creg = old.intersect(creg);
p->setClipRegion(creg);
#endif
}
static void restoreClip(QPainter* p, const QRect& paintDirtyRect, const QRect& clipRect)
{
if (paintDirtyRect == clipRect)
return;
p->restore();
}
#ifdef NOKIA_CHANGES
void RenderLayer::getRenderersInRect(RenderLayer* rootLayer, QPtrList<LayerInfo>* layerInfoList,const QRect& rect,int deltaX,int deltaY, int layerZIndex)
{
// Calculate the top left position for the layer.
int x = 0;
int y = 0;
convertToLayerCoords(rootLayer,x,y);
// Ensure our z-order lists are up-to-date.
updateZOrderLists();
// Now walk the sorted list of children with negative z-indices.
if (m_negZOrderList) {
uint count = m_negZOrderList->count();
for (uint i = 0; i < count; i++) {
RenderLayer* child = m_negZOrderList->at(i);
child->getRenderersInRect(rootLayer,layerInfoList,rect,deltaX,deltaY,layerZIndex + zIndex());
}
}
LayerInfo *layerInfo = new LayerInfo;
QPtrList<BoxInfo> *layerBoxInfoList = new QPtrList<BoxInfo>;
layerBoxInfoList->setAutoDelete(true);
layerInfo->boxInfoList = layerBoxInfoList;
layerInfo->zIndex = layerZIndex + zIndex();
layerInfoList->append(layerInfo);
renderer()->getRenderersInRect(*layerBoxInfoList,deltaX + x - renderer()->xPos(), deltaY + y - renderer()->yPos(),rect);
// Now walk the sorted list of children with positive z-indices.
if (m_posZOrderList) {
uint count = m_posZOrderList->count();
for (uint i = 0; i < count; i++) {
RenderLayer* child = m_posZOrderList->at(i);
child->getRenderersInRect(rootLayer,layerInfoList,rect,deltaX,deltaY,layerZIndex + zIndex());
}
}
}
#endif
void
RenderLayer::paintLayer(RenderLayer* rootLayer, QPainter *p,
const QRect& paintDirtyRect, bool haveTransparency, bool selectionOnly,
RenderObject *paintingRoot)
{
// Calculate the clip rects we should use.
QRect layerBounds, damageRect, clipRectToApply;
calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply);
int x = layerBounds.x();
int y = layerBounds.y();
// Ensure our z-order lists are up-to-date.
updateZOrderLists();
#if APPLE_CHANGES
if (isTransparent())
haveTransparency = true;
#endif
// If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
// is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
// Else, our renderer tree may or may not contain the painting root, so we pass that root along
// so it will be tested against as we decend through the renderers.
RenderObject *paintingRootForRenderer = 0;
if (paintingRoot && !m_object->hasAncestor(paintingRoot)) {
paintingRootForRenderer = paintingRoot;
}
// We want to paint our layer, but only if we intersect the damage rect.
bool shouldPaint = intersectsDamageRect(layerBounds, damageRect);
if (shouldPaint && !selectionOnly && !damageRect.isEmpty()) {
#if APPLE_CHANGES
// Begin transparency layers lazily now that we know we have to paint something.
if (haveTransparency)
beginTransparencyLayers(p);
#endif
// Paint our background first, before painting any child layers.
// Establish the clip used to paint our background.
setClip(p, paintDirtyRect, damageRect);
// Paint the background.
RenderObject::PaintInfo info(p, damageRect, PaintActionBlockBackground, paintingRootForRenderer);
renderer()->paint(info, x - renderer()->xPos(), y - renderer()->yPos() + renderer()->borderTopExtra());
#if APPLE_CHANGES
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -