RenderScrollbarPart.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * Copyright (C) 2008 Apple Inc. All Rights Reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
  17. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "config.h"
  26. #include "RenderScrollbarPart.h"
  27. #include "PaintInfo.h"
  28. #include "RenderScrollbar.h"
  29. #include "RenderScrollbarTheme.h"
  30. #include "RenderView.h"
  31. #include <wtf/StackStats.h>
  32. using namespace std;
  33. namespace WebCore {
  34. RenderScrollbarPart::RenderScrollbarPart(RenderScrollbar* scrollbar, ScrollbarPart part)
  35. : RenderBlock(0)
  36. , m_scrollbar(scrollbar)
  37. , m_part(part)
  38. {
  39. }
  40. RenderScrollbarPart::~RenderScrollbarPart()
  41. {
  42. }
  43. RenderScrollbarPart* RenderScrollbarPart::createAnonymous(Document* document, RenderScrollbar* scrollbar, ScrollbarPart part)
  44. {
  45. RenderScrollbarPart* renderer = new (document->renderArena()) RenderScrollbarPart(scrollbar, part);
  46. renderer->setDocumentForAnonymous(document);
  47. return renderer;
  48. }
  49. void RenderScrollbarPart::layout()
  50. {
  51. StackStats::LayoutCheckPoint layoutCheckPoint;
  52. setLocation(LayoutPoint()); // We don't worry about positioning ourselves. We're just determining our minimum width/height.
  53. if (m_scrollbar->orientation() == HorizontalScrollbar)
  54. layoutHorizontalPart();
  55. else
  56. layoutVerticalPart();
  57. setNeedsLayout(false);
  58. }
  59. void RenderScrollbarPart::layoutHorizontalPart()
  60. {
  61. if (m_part == ScrollbarBGPart) {
  62. setWidth(m_scrollbar->width());
  63. computeScrollbarHeight();
  64. } else {
  65. computeScrollbarWidth();
  66. setHeight(m_scrollbar->height());
  67. }
  68. }
  69. void RenderScrollbarPart::layoutVerticalPart()
  70. {
  71. if (m_part == ScrollbarBGPart) {
  72. computeScrollbarWidth();
  73. setHeight(m_scrollbar->height());
  74. } else {
  75. setWidth(m_scrollbar->width());
  76. computeScrollbarHeight();
  77. }
  78. }
  79. static int calcScrollbarThicknessUsing(SizeType sizeType, const Length& length, int containingLength, RenderView* renderView)
  80. {
  81. if (!length.isIntrinsicOrAuto() || (sizeType == MinSize && length.isAuto()))
  82. return minimumValueForLength(length, containingLength, renderView);
  83. return ScrollbarTheme::theme()->scrollbarThickness();
  84. }
  85. void RenderScrollbarPart::computeScrollbarWidth()
  86. {
  87. if (!m_scrollbar->owningRenderer())
  88. return;
  89. RenderView* renderView = view();
  90. // FIXME: We are querying layout information but nothing guarantees that it's up-to-date, especially since we are called at style change.
  91. // FIXME: Querying the style's border information doesn't work on table cells with collapsing borders.
  92. int visibleSize = m_scrollbar->owningRenderer()->width() - m_scrollbar->owningRenderer()->style()->borderLeftWidth() - m_scrollbar->owningRenderer()->style()->borderRightWidth();
  93. int w = calcScrollbarThicknessUsing(MainOrPreferredSize, style()->width(), visibleSize, renderView);
  94. int minWidth = calcScrollbarThicknessUsing(MinSize, style()->minWidth(), visibleSize, renderView);
  95. int maxWidth = style()->maxWidth().isUndefined() ? w : calcScrollbarThicknessUsing(MaxSize, style()->maxWidth(), visibleSize, renderView);
  96. setWidth(max(minWidth, min(maxWidth, w)));
  97. // Buttons and track pieces can all have margins along the axis of the scrollbar.
  98. m_marginBox.setLeft(minimumValueForLength(style()->marginLeft(), visibleSize, renderView));
  99. m_marginBox.setRight(minimumValueForLength(style()->marginRight(), visibleSize, renderView));
  100. }
  101. void RenderScrollbarPart::computeScrollbarHeight()
  102. {
  103. if (!m_scrollbar->owningRenderer())
  104. return;
  105. RenderView* renderView = view();
  106. // FIXME: We are querying layout information but nothing guarantees that it's up-to-date, especially since we are called at style change.
  107. // FIXME: Querying the style's border information doesn't work on table cells with collapsing borders.
  108. int visibleSize = m_scrollbar->owningRenderer()->height() - m_scrollbar->owningRenderer()->style()->borderTopWidth() - m_scrollbar->owningRenderer()->style()->borderBottomWidth();
  109. int h = calcScrollbarThicknessUsing(MainOrPreferredSize, style()->height(), visibleSize, renderView);
  110. int minHeight = calcScrollbarThicknessUsing(MinSize, style()->minHeight(), visibleSize, renderView);
  111. int maxHeight = style()->maxHeight().isUndefined() ? h : calcScrollbarThicknessUsing(MaxSize, style()->maxHeight(), visibleSize, renderView);
  112. setHeight(max(minHeight, min(maxHeight, h)));
  113. // Buttons and track pieces can all have margins along the axis of the scrollbar.
  114. m_marginBox.setTop(minimumValueForLength(style()->marginTop(), visibleSize, renderView));
  115. m_marginBox.setBottom(minimumValueForLength(style()->marginBottom(), visibleSize, renderView));
  116. }
  117. void RenderScrollbarPart::computePreferredLogicalWidths()
  118. {
  119. if (!preferredLogicalWidthsDirty())
  120. return;
  121. m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0;
  122. setPreferredLogicalWidthsDirty(false);
  123. }
  124. void RenderScrollbarPart::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
  125. {
  126. RenderBlock::styleWillChange(diff, newStyle);
  127. setInline(false);
  128. }
  129. void RenderScrollbarPart::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
  130. {
  131. RenderBlock::styleDidChange(diff, oldStyle);
  132. setInline(false);
  133. clearPositionedState();
  134. setFloating(false);
  135. setHasOverflowClip(false);
  136. if (oldStyle && m_scrollbar && m_part != NoPart && diff >= StyleDifferenceRepaint)
  137. m_scrollbar->theme()->invalidatePart(m_scrollbar, m_part);
  138. }
  139. void RenderScrollbarPart::imageChanged(WrappedImagePtr image, const IntRect* rect)
  140. {
  141. if (m_scrollbar && m_part != NoPart)
  142. m_scrollbar->theme()->invalidatePart(m_scrollbar, m_part);
  143. else {
  144. if (FrameView* frameView = view()->frameView()) {
  145. if (frameView->isFrameViewScrollCorner(this)) {
  146. frameView->invalidateScrollCorner(frameView->scrollCornerRect());
  147. return;
  148. }
  149. }
  150. RenderBlock::imageChanged(image, rect);
  151. }
  152. }
  153. void RenderScrollbarPart::paintIntoRect(GraphicsContext* graphicsContext, const LayoutPoint& paintOffset, const LayoutRect& rect)
  154. {
  155. // Make sure our dimensions match the rect.
  156. setLocation(rect.location() - toSize(paintOffset));
  157. setWidth(rect.width());
  158. setHeight(rect.height());
  159. if (graphicsContext->paintingDisabled())
  160. return;
  161. // Now do the paint.
  162. PaintInfo paintInfo(graphicsContext, pixelSnappedIntRect(rect), PaintPhaseBlockBackground, PaintBehaviorNormal);
  163. paint(paintInfo, paintOffset);
  164. paintInfo.phase = PaintPhaseChildBlockBackgrounds;
  165. paint(paintInfo, paintOffset);
  166. paintInfo.phase = PaintPhaseFloat;
  167. paint(paintInfo, paintOffset);
  168. paintInfo.phase = PaintPhaseForeground;
  169. paint(paintInfo, paintOffset);
  170. paintInfo.phase = PaintPhaseOutline;
  171. paint(paintInfo, paintOffset);
  172. }
  173. RenderObject* RenderScrollbarPart::rendererOwningScrollbar() const
  174. {
  175. if (!m_scrollbar)
  176. return 0;
  177. return m_scrollbar->owningRenderer();
  178. }
  179. }