Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: sky/engine/core/rendering/RenderLayerScrollableArea.cpp

Issue 689283003: Remove scroll corners and resizers. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
3 * 3 *
4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
5 * 5 *
6 * Other contributors: 6 * Other contributors:
7 * Robert O'Callahan <roc+@cs.cmu.edu> 7 * Robert O'Callahan <roc+@cs.cmu.edu>
8 * David Baron <dbaron@fas.harvard.edu> 8 * David Baron <dbaron@fas.harvard.edu>
9 * Christian Biesinger <cbiesinger@web.de> 9 * Christian Biesinger <cbiesinger@web.de>
10 * Randall Jesup <rjesup@wgate.com> 10 * Randall Jesup <rjesup@wgate.com>
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 #include "platform/PlatformGestureEvent.h" 63 #include "platform/PlatformGestureEvent.h"
64 #include "platform/PlatformMouseEvent.h" 64 #include "platform/PlatformMouseEvent.h"
65 #include "platform/graphics/GraphicsContextStateSaver.h" 65 #include "platform/graphics/GraphicsContextStateSaver.h"
66 #include "platform/graphics/GraphicsLayer.h" 66 #include "platform/graphics/GraphicsLayer.h"
67 #include "platform/scroll/ScrollAnimator.h" 67 #include "platform/scroll/ScrollAnimator.h"
68 #include "platform/scroll/Scrollbar.h" 68 #include "platform/scroll/Scrollbar.h"
69 #include "public/platform/Platform.h" 69 #include "public/platform/Platform.h"
70 70
71 namespace blink { 71 namespace blink {
72 72
73 const int ResizerControlExpandRatioForTouch = 2;
74
75 RenderLayerScrollableArea::RenderLayerScrollableArea(RenderLayer& layer) 73 RenderLayerScrollableArea::RenderLayerScrollableArea(RenderLayer& layer)
76 : m_layer(layer) 74 : m_layer(layer)
77 , m_inResizeMode(false)
78 , m_scrollsOverflow(false) 75 , m_scrollsOverflow(false)
79 , m_scrollDimensionsDirty(true) 76 , m_scrollDimensionsDirty(true)
80 , m_inOverflowRelayout(false) 77 , m_inOverflowRelayout(false)
81 , m_nextTopmostScrollChild(0) 78 , m_nextTopmostScrollChild(0)
82 , m_topmostScrollChild(0) 79 , m_topmostScrollChild(0)
83 , m_needsCompositedScrolling(false) 80 , m_needsCompositedScrolling(false)
84 { 81 {
85 ScrollableArea::setConstrainsScrollingToContentEdge(false); 82 ScrollableArea::setConstrainsScrollingToContentEdge(false);
86 83
87 Node* node = box().node(); 84 Node* node = box().node();
88 if (node && node->isElementNode()) { 85 if (node && node->isElementNode()) {
89 // We save and restore only the scrollOffset as the other scroll values are recalculated. 86 // We save and restore only the scrollOffset as the other scroll values are recalculated.
90 Element* element = toElement(node); 87 Element* element = toElement(node);
91 m_scrollOffset = element->savedLayerScrollOffset(); 88 m_scrollOffset = element->savedLayerScrollOffset();
92 if (!m_scrollOffset.isZero()) 89 if (!m_scrollOffset.isZero())
93 scrollAnimator()->setCurrentPosition(FloatPoint(m_scrollOffset.width (), m_scrollOffset.height())); 90 scrollAnimator()->setCurrentPosition(FloatPoint(m_scrollOffset.width (), m_scrollOffset.height()));
94 element->setSavedLayerScrollOffset(IntSize()); 91 element->setSavedLayerScrollOffset(IntSize());
95 } 92 }
96
97 updateResizerAreaSet();
98 } 93 }
99 94
100 RenderLayerScrollableArea::~RenderLayerScrollableArea() 95 RenderLayerScrollableArea::~RenderLayerScrollableArea()
101 { 96 {
102 if (inResizeMode() && !box().documentBeingDestroyed()) {
103 if (LocalFrame* frame = box().frame())
104 frame->eventHandler().resizeScrollableAreaDestroyed();
105 }
106
107 if (box().frame() && box().frame()->page()) { 97 if (box().frame() && box().frame()->page()) {
108 if (ScrollingCoordinator* scrollingCoordinator = box().frame()->page()-> scrollingCoordinator()) 98 if (ScrollingCoordinator* scrollingCoordinator = box().frame()->page()-> scrollingCoordinator())
109 scrollingCoordinator->willDestroyScrollableArea(this); 99 scrollingCoordinator->willDestroyScrollableArea(this);
110 } 100 }
111 101
112 if (!box().documentBeingDestroyed()) { 102 if (!box().documentBeingDestroyed()) {
113 Node* node = box().node(); 103 Node* node = box().node();
114 if (node && node->isElementNode()) 104 if (node && node->isElementNode())
115 toElement(node)->setSavedLayerScrollOffset(m_scrollOffset); 105 toElement(node)->setSavedLayerScrollOffset(m_scrollOffset);
116 } 106 }
117 107
118 if (LocalFrame* frame = box().frame()) {
119 if (FrameView* frameView = frame->view())
120 frameView->removeResizerArea(box());
121 }
122
123 destroyScrollbar(HorizontalScrollbar); 108 destroyScrollbar(HorizontalScrollbar);
124 destroyScrollbar(VerticalScrollbar); 109 destroyScrollbar(VerticalScrollbar);
125 } 110 }
126 111
127 HostWindow* RenderLayerScrollableArea::hostWindow() const 112 HostWindow* RenderLayerScrollableArea::hostWindow() const
128 { 113 {
129 if (Page* page = box().frame()->page()) 114 if (Page* page = box().frame()->page())
130 return &page->chrome(); 115 return &page->chrome();
131 return nullptr; 116 return nullptr;
132 } 117 }
(...skipping 12 matching lines...) Expand all
145 } 130 }
146 131
147 GraphicsLayer* RenderLayerScrollableArea::layerForVerticalScrollbar() const 132 GraphicsLayer* RenderLayerScrollableArea::layerForVerticalScrollbar() const
148 { 133 {
149 // See crbug.com/343132. 134 // See crbug.com/343132.
150 DisableCompositingQueryAsserts disabler; 135 DisableCompositingQueryAsserts disabler;
151 136
152 return layer()->hasCompositedLayerMapping() ? layer()->compositedLayerMappin g()->layerForVerticalScrollbar() : 0; 137 return layer()->hasCompositedLayerMapping() ? layer()->compositedLayerMappin g()->layerForVerticalScrollbar() : 0;
153 } 138 }
154 139
155 GraphicsLayer* RenderLayerScrollableArea::layerForScrollCorner() const
156 {
157 // See crbug.com/343132.
158 DisableCompositingQueryAsserts disabler;
159
160 return layer()->hasCompositedLayerMapping() ? layer()->compositedLayerMappin g()->layerForScrollCorner() : 0;
161 }
162
163 void RenderLayerScrollableArea::invalidateScrollbarRect(Scrollbar* scrollbar, co nst IntRect& rect) 140 void RenderLayerScrollableArea::invalidateScrollbarRect(Scrollbar* scrollbar, co nst IntRect& rect)
164 { 141 {
165 // See crbug.com/343132. 142 // See crbug.com/343132.
166 DisableCompositingQueryAsserts disabler; 143 DisableCompositingQueryAsserts disabler;
167 144
168 if (scrollbar == m_vBar.get()) { 145 if (scrollbar == m_vBar.get()) {
169 if (GraphicsLayer* layer = layerForVerticalScrollbar()) { 146 if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
170 layer->setNeedsDisplayInRect(rect); 147 layer->setNeedsDisplayInRect(rect);
171 return; 148 return;
172 } 149 }
(...skipping 18 matching lines...) Expand all
191 return; 168 return;
192 169
193 IntRect intRect = pixelSnappedIntRect(scrollRect); 170 IntRect intRect = pixelSnappedIntRect(scrollRect);
194 171
195 if (box().frameView()->isInPerformLayout()) 172 if (box().frameView()->isInPerformLayout())
196 addScrollbarDamage(scrollbar, intRect); 173 addScrollbarDamage(scrollbar, intRect);
197 else 174 else
198 box().invalidatePaintRectangle(intRect); 175 box().invalidatePaintRectangle(intRect);
199 } 176 }
200 177
201 void RenderLayerScrollableArea::invalidateScrollCornerRect(const IntRect& rect)
202 {
203 if (GraphicsLayer* layer = layerForScrollCorner()) {
204 layer->setNeedsDisplayInRect(rect);
205 return;
206 }
207 }
208
209 bool RenderLayerScrollableArea::isActive() const 178 bool RenderLayerScrollableArea::isActive() const
210 { 179 {
211 Page* page = box().frame()->page(); 180 Page* page = box().frame()->page();
212 return page && page->focusController().isActive(); 181 return page && page->focusController().isActive();
213 } 182 }
214 183
215 bool RenderLayerScrollableArea::isScrollCornerVisible() const
216 {
217 return !scrollCornerRect().isEmpty();
218 }
219
220 static int cornerStart(const RenderStyle* style, int minX, int maxX, int thickne ss) 184 static int cornerStart(const RenderStyle* style, int minX, int maxX, int thickne ss)
221 { 185 {
222 if (style->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) 186 if (style->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
223 return minX + style->borderLeftWidth(); 187 return minX + style->borderLeftWidth();
224 return maxX - thickness - style->borderRightWidth(); 188 return maxX - thickness - style->borderRightWidth();
225 } 189 }
226 190
227 static IntRect cornerRect(const RenderStyle* style, const Scrollbar* horizontalS crollbar, const Scrollbar* verticalScrollbar, const IntRect& bounds) 191 IntRect RenderLayerScrollableArea::scrollCornerRect() const
228 { 192 {
229 int horizontalThickness; 193 // We have a scrollbar corner when a scrollbar is visible and not filling th e entire length of the box.
230 int verticalThickness; 194 // This happens when both scrollbars are present.
231 if (!verticalScrollbar && !horizontalScrollbar) { 195 const Scrollbar* horizontalBar = horizontalScrollbar();
232 // FIXME: This isn't right. We need to know the thickness of custom scro llbars 196 const Scrollbar* verticalBar = verticalScrollbar();
233 // even when they don't exist in order to set the resizer square size pr operly. 197 if (!horizontalBar || !verticalBar)
234 horizontalThickness = Scrollbar::scrollbarThickness(); 198 return IntRect();
235 verticalThickness = horizontalThickness; 199
236 } else if (verticalScrollbar && !horizontalScrollbar) { 200 const RenderStyle* style = box().style();
237 horizontalThickness = verticalScrollbar->width(); 201 int horizontalThickness = verticalBar->width();
238 verticalThickness = horizontalThickness; 202 int verticalThickness = horizontalBar->height();
239 } else if (horizontalScrollbar && !verticalScrollbar) { 203 const IntRect& bounds = box().pixelSnappedBorderBoxRect();
240 verticalThickness = horizontalScrollbar->height();
241 horizontalThickness = verticalThickness;
242 } else {
243 horizontalThickness = verticalScrollbar->width();
244 verticalThickness = horizontalScrollbar->height();
245 }
246 return IntRect(cornerStart(style, bounds.x(), bounds.maxX(), horizontalThick ness), 204 return IntRect(cornerStart(style, bounds.x(), bounds.maxX(), horizontalThick ness),
247 bounds.maxY() - verticalThickness - style->borderBottomWidth(), 205 bounds.maxY() - verticalThickness - style->borderBottomWidth(),
248 horizontalThickness, verticalThickness); 206 horizontalThickness, verticalThickness);
249 } 207 }
250 208
251 IntRect RenderLayerScrollableArea::scrollCornerRect() const
252 {
253 // We have a scrollbar corner when a scrollbar is visible and not filling th e entire length of the box.
254 // This happens when:
255 // (a) A resizer is present and at least one scrollbar is present
256 // (b) Both scrollbars are present.
257 bool hasHorizontalBar = horizontalScrollbar();
258 bool hasVerticalBar = verticalScrollbar();
259 bool hasResizer = box().style()->resize() != RESIZE_NONE;
260 if ((hasHorizontalBar && hasVerticalBar) || (hasResizer && (hasHorizontalBar || hasVerticalBar)))
261 return cornerRect(box().style(), horizontalScrollbar(), verticalScrollba r(), box().pixelSnappedBorderBoxRect());
262 return IntRect();
263 }
264
265 IntRect RenderLayerScrollableArea::convertFromScrollbarToContainingView(const Sc rollbar* scrollbar, const IntRect& scrollbarRect) const 209 IntRect RenderLayerScrollableArea::convertFromScrollbarToContainingView(const Sc rollbar* scrollbar, const IntRect& scrollbarRect) const
266 { 210 {
267 RenderView* view = box().view(); 211 RenderView* view = box().view();
268 if (!view) 212 if (!view)
269 return scrollbarRect; 213 return scrollbarRect;
270 214
271 IntRect rect = scrollbarRect; 215 IntRect rect = scrollbarRect;
272 rect.move(scrollbarOffset(scrollbar)); 216 rect.move(scrollbarOffset(scrollbar));
273 217
274 return view->frameView()->convertFromRenderer(box(), rect); 218 return view->frameView()->convertFromRenderer(box(), rect);
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 // When switching to another value, we need to re-enable them (see bug 11985 ). 612 // When switching to another value, we need to re-enable them (see bug 11985 ).
669 if (needsHorizontalScrollbar && oldStyle && oldStyle->overflowX() == OSCROLL && overflowX != OSCROLL) { 613 if (needsHorizontalScrollbar && oldStyle && oldStyle->overflowX() == OSCROLL && overflowX != OSCROLL) {
670 ASSERT(hasHorizontalScrollbar()); 614 ASSERT(hasHorizontalScrollbar());
671 m_hBar->setEnabled(true); 615 m_hBar->setEnabled(true);
672 } 616 }
673 617
674 if (needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == OSCROLL & & overflowY != OSCROLL) { 618 if (needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == OSCROLL & & overflowY != OSCROLL) {
675 ASSERT(hasVerticalScrollbar()); 619 ASSERT(hasVerticalScrollbar());
676 m_vBar->setEnabled(true); 620 m_vBar->setEnabled(true);
677 } 621 }
678
679 updateResizerAreaSet();
680 } 622 }
681 623
682 bool RenderLayerScrollableArea::updateAfterCompositingChange() 624 bool RenderLayerScrollableArea::updateAfterCompositingChange()
683 { 625 {
684 layer()->updateScrollingStateAfterCompositingChange(); 626 layer()->updateScrollingStateAfterCompositingChange();
685 const bool layersChanged = m_topmostScrollChild != m_nextTopmostScrollChild; 627 const bool layersChanged = m_topmostScrollChild != m_nextTopmostScrollChild;
686 m_topmostScrollChild = m_nextTopmostScrollChild; 628 m_topmostScrollChild = m_nextTopmostScrollChild;
687 m_nextTopmostScrollChild = nullptr; 629 m_nextTopmostScrollChild = nullptr;
688 return layersChanged; 630 return layersChanged;
689 } 631 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 688
747 LayoutUnit RenderLayerScrollableArea::verticalScrollbarStart(int minX, int maxX) const 689 LayoutUnit RenderLayerScrollableArea::verticalScrollbarStart(int minX, int maxX) const
748 { 690 {
749 if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) 691 if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
750 return minX + box().borderLeft(); 692 return minX + box().borderLeft();
751 return maxX - box().borderRight() - m_vBar->width(); 693 return maxX - box().borderRight() - m_vBar->width();
752 } 694 }
753 695
754 LayoutUnit RenderLayerScrollableArea::horizontalScrollbarStart(int minX) const 696 LayoutUnit RenderLayerScrollableArea::horizontalScrollbarStart(int minX) const
755 { 697 {
756 int x = minX + box().borderLeft(); 698 return minX + box().borderLeft();
757 if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
758 x += m_vBar ? m_vBar->width() : resizerCornerRect(box().pixelSnappedBord erBoxRect(), ResizerForPointer).width();
759 return x;
760 } 699 }
761 700
762 IntSize RenderLayerScrollableArea::scrollbarOffset(const Scrollbar* scrollbar) c onst 701 IntSize RenderLayerScrollableArea::scrollbarOffset(const Scrollbar* scrollbar) c onst
763 { 702 {
764 if (scrollbar == m_vBar.get()) 703 if (scrollbar == m_vBar.get())
765 return IntSize(verticalScrollbarStart(0, box().width()), box().borderTop ()); 704 return IntSize(verticalScrollbarStart(0, box().width()), box().borderTop ());
766 705
767 if (scrollbar == m_hBar.get()) 706 if (scrollbar == m_hBar.get())
768 return IntSize(horizontalScrollbarStart(0), box().height() - box().borde rBottom() - scrollbar->height()); 707 return IntSize(horizontalScrollbarStart(0), box().height() - box().borde rBottom() - scrollbar->height());
769 708
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 770
832 int RenderLayerScrollableArea::horizontalScrollbarHeight(OverlayScrollbarSizeRel evancy relevancy) const 771 int RenderLayerScrollableArea::horizontalScrollbarHeight(OverlayScrollbarSizeRel evancy relevancy) const
833 { 772 {
834 if (!m_hBar || (m_hBar->isOverlayScrollbar() && (relevancy == IgnoreOverlayS crollbarSize || !m_hBar->shouldParticipateInHitTesting()))) 773 if (!m_hBar || (m_hBar->isOverlayScrollbar() && (relevancy == IgnoreOverlayS crollbarSize || !m_hBar->shouldParticipateInHitTesting())))
835 return 0; 774 return 0;
836 return m_hBar->height(); 775 return m_hBar->height();
837 } 776 }
838 777
839 void RenderLayerScrollableArea::positionOverflowControls(const IntSize& offsetFr omRoot) 778 void RenderLayerScrollableArea::positionOverflowControls(const IntSize& offsetFr omRoot)
840 { 779 {
841 if (!hasScrollbar() && !box().canResize()) 780 if (!hasScrollbar())
842 return; 781 return;
843 782
844 const IntRect borderBox = box().pixelSnappedBorderBoxRect(); 783 const IntRect borderBox = box().pixelSnappedBorderBoxRect();
845 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) { 784 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) {
846 IntRect vBarRect = rectForVerticalScrollbar(borderBox); 785 IntRect vBarRect = rectForVerticalScrollbar(borderBox);
847 vBarRect.move(offsetFromRoot); 786 vBarRect.move(offsetFromRoot);
848 verticalScrollbar->setFrameRect(vBarRect); 787 verticalScrollbar->setFrameRect(vBarRect);
849 } 788 }
850 789
851 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) { 790 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 843
905 // This check is required to avoid painting custom CSS scrollbars twice. 844 // This check is required to avoid painting custom CSS scrollbars twice.
906 if (paintingOverlayControls && !hasOverlayScrollbars()) 845 if (paintingOverlayControls && !hasOverlayScrollbars())
907 return; 846 return;
908 847
909 // Now that we're sure the scrollbars are in the right place, paint them. 848 // Now that we're sure the scrollbars are in the right place, paint them.
910 if (m_hBar && !layerForHorizontalScrollbar()) 849 if (m_hBar && !layerForHorizontalScrollbar())
911 m_hBar->paint(context, damageRect); 850 m_hBar->paint(context, damageRect);
912 if (m_vBar && !layerForVerticalScrollbar()) 851 if (m_vBar && !layerForVerticalScrollbar())
913 m_vBar->paint(context, damageRect); 852 m_vBar->paint(context, damageRect);
914
915 if (layerForScrollCorner())
916 return;
917
918 // We fill our scroll corner with white if we have a scrollbar that doesn't run all the way up to the
919 // edge of the box.
920 paintScrollCorner(context, adjustedPaintOffset, damageRect);
921
922 // Paint our resizer last, since it sits on top of the scroll corner.
923 paintResizer(context, adjustedPaintOffset, damageRect);
924 }
925
926 void RenderLayerScrollableArea::paintScrollCorner(GraphicsContext* context, cons t IntPoint& paintOffset, const IntRect& damageRect)
927 {
928 IntRect absRect = scrollCornerRect();
929 absRect.moveBy(paintOffset);
930 if (!absRect.intersects(damageRect))
931 return;
932
933 // We don't want to paint white if we have overlay scrollbars, since we need
934 // to see what is behind it.
935 if (!hasOverlayScrollbars())
936 context->fillRect(absRect, Color::white);
937 }
938
939 bool RenderLayerScrollableArea::hitTestOverflowControls(HitTestResult& result, c onst IntPoint& localPoint)
940 {
941 if (!hasScrollbar() && !box().canResize())
942 return false;
943
944 IntRect resizeControlRect;
945 if (box().style()->resize() != RESIZE_NONE) {
946 resizeControlRect = resizerCornerRect(box().pixelSnappedBorderBoxRect(), ResizerForPointer);
947 if (resizeControlRect.contains(localPoint))
948 return true;
949 }
950
951 int resizeControlSize = max(resizeControlRect.height(), 0);
952 if (m_vBar && m_vBar->shouldParticipateInHitTesting()) {
953 LayoutRect vBarRect(verticalScrollbarStart(0, box().width()),
954 box().borderTop(),
955 m_vBar->width(),
956 box().height() - (box().borderTop() + box().borderBottom()) - (m_hBa r ? m_hBar->height() : resizeControlSize));
957 if (vBarRect.contains(localPoint)) {
958 result.setScrollbar(m_vBar.get());
959 return true;
960 }
961 }
962
963 resizeControlSize = max(resizeControlRect.width(), 0);
964 if (m_hBar && m_hBar->shouldParticipateInHitTesting()) {
965 LayoutRect hBarRect(horizontalScrollbarStart(0),
966 box().height() - box().borderBottom() - m_hBar->height(),
967 box().width() - (box().borderLeft() + box().borderRight()) - (m_vBar ? m_vBar->width() : resizeControlSize),
968 m_hBar->height());
969 if (hBarRect.contains(localPoint)) {
970 result.setScrollbar(m_hBar.get());
971 return true;
972 }
973 }
974
975 return false;
976 }
977
978 IntRect RenderLayerScrollableArea::resizerCornerRect(const IntRect& bounds, Resi zerHitTestType resizerHitTestType) const
979 {
980 if (box().style()->resize() == RESIZE_NONE)
981 return IntRect();
982 IntRect corner = cornerRect(box().style(), horizontalScrollbar(), verticalSc rollbar(), bounds);
983
984 if (resizerHitTestType == ResizerForTouch) {
985 // We make the resizer virtually larger for touch hit testing. With the
986 // expanding ratio k = ResizerControlExpandRatioForTouch, we first move
987 // the resizer rect (of width w & height h), by (-w * (k-1), -h * (k-1)) ,
988 // then expand the rect by new_w/h = w/h * k.
989 int expandRatio = ResizerControlExpandRatioForTouch - 1;
990 corner.move(-corner.width() * expandRatio, -corner.height() * expandRati o);
991 corner.expand(corner.width() * expandRatio, corner.height() * expandRati o);
992 }
993
994 return corner;
995 }
996
997 IntRect RenderLayerScrollableArea::scrollCornerAndResizerRect() const
998 {
999 IntRect scrollCornerAndResizer = scrollCornerRect();
1000 if (scrollCornerAndResizer.isEmpty())
1001 scrollCornerAndResizer = resizerCornerRect(box().pixelSnappedBorderBoxRe ct(), ResizerForPointer);
1002 return scrollCornerAndResizer;
1003 } 853 }
1004 854
1005 bool RenderLayerScrollableArea::overflowControlsIntersectRect(const IntRect& loc alRect) const 855 bool RenderLayerScrollableArea::overflowControlsIntersectRect(const IntRect& loc alRect) const
1006 { 856 {
1007 const IntRect borderBox = box().pixelSnappedBorderBoxRect(); 857 const IntRect borderBox = box().pixelSnappedBorderBoxRect();
1008 858
1009 if (rectForHorizontalScrollbar(borderBox).intersects(localRect)) 859 if (rectForHorizontalScrollbar(borderBox).intersects(localRect))
1010 return true; 860 return true;
1011 861
1012 if (rectForVerticalScrollbar(borderBox).intersects(localRect)) 862 if (rectForVerticalScrollbar(borderBox).intersects(localRect))
1013 return true; 863 return true;
1014 864
1015 if (scrollCornerRect().intersects(localRect))
1016 return true;
1017
1018 if (resizerCornerRect(borderBox, ResizerForPointer).intersects(localRect))
1019 return true;
1020
1021 return false; 865 return false;
1022 } 866 }
1023 867
1024 void RenderLayerScrollableArea::paintResizer(GraphicsContext* context, const Int Point& paintOffset, const IntRect& damageRect)
1025 {
1026 if (box().style()->resize() == RESIZE_NONE)
1027 return;
1028
1029 IntRect absRect = resizerCornerRect(box().pixelSnappedBorderBoxRect(), Resiz erForPointer);
1030 absRect.moveBy(paintOffset);
1031 if (!absRect.intersects(damageRect))
1032 return;
1033
1034 drawPlatformResizerImage(context, absRect);
1035
1036 // Draw a frame around the resizer (1px grey line) if there are any scrollba rs present.
1037 // Clipping will exclude the right and bottom edges of this frame.
1038 if (!hasOverlayScrollbars() && hasScrollbar()) {
1039 GraphicsContextStateSaver stateSaver(*context);
1040 context->clip(absRect);
1041 IntRect largerCorner = absRect;
1042 largerCorner.setSize(IntSize(largerCorner.width() + 1, largerCorner.heig ht() + 1));
1043 context->setStrokeColor(Color(217, 217, 217));
1044 context->setStrokeThickness(1.0f);
1045 context->setFillColor(Color::transparent);
1046 context->drawRect(largerCorner);
1047 }
1048 }
1049
1050 bool RenderLayerScrollableArea::isPointInResizeControl(const IntPoint& absoluteP oint, ResizerHitTestType resizerHitTestType) const
1051 {
1052 if (!box().canResize())
1053 return false;
1054
1055 IntPoint localPoint = roundedIntPoint(box().absoluteToLocal(absolutePoint, U seTransforms));
1056 IntRect localBounds(0, 0, box().pixelSnappedWidth(), box().pixelSnappedHeigh t());
1057 return resizerCornerRect(localBounds, resizerHitTestType).contains(localPoin t);
1058 }
1059
1060 bool RenderLayerScrollableArea::hitTestResizerInFragments(const LayerFragments& layerFragments, const HitTestLocation& hitTestLocation) const
1061 {
1062 if (!box().canResize())
1063 return false;
1064
1065 if (layerFragments.isEmpty())
1066 return false;
1067
1068 for (int i = layerFragments.size() - 1; i >= 0; --i) {
1069 const LayerFragment& fragment = layerFragments.at(i);
1070 if (fragment.backgroundRect.intersects(hitTestLocation) && resizerCorner Rect(pixelSnappedIntRect(fragment.layerBounds), ResizerForPointer).contains(hitT estLocation.roundedPoint()))
1071 return true;
1072 }
1073
1074 return false;
1075 }
1076
1077 void RenderLayerScrollableArea::updateResizerAreaSet()
1078 {
1079 LocalFrame* frame = box().frame();
1080 if (!frame)
1081 return;
1082 FrameView* frameView = frame->view();
1083 if (!frameView)
1084 return;
1085 if (box().canResize())
1086 frameView->addResizerArea(box());
1087 else
1088 frameView->removeResizerArea(box());
1089 }
1090
1091 void RenderLayerScrollableArea::drawPlatformResizerImage(GraphicsContext* contex t, IntRect resizerCornerRect)
1092 {
1093 float deviceScaleFactor = blink::deviceScaleFactor(box().frame());
1094
1095 RefPtr<Image> resizeCornerImage;
1096 IntSize cornerResizerSize;
1097 if (deviceScaleFactor >= 2) {
1098 DEFINE_STATIC_REF(Image, resizeCornerImageHiRes, (Image::loadPlatformRes ource("textAreaResizeCorner@2x")));
1099 resizeCornerImage = resizeCornerImageHiRes;
1100 cornerResizerSize = resizeCornerImage->size();
1101 cornerResizerSize.scale(0.5f);
1102 } else {
1103 DEFINE_STATIC_REF(Image, resizeCornerImageLoRes, (Image::loadPlatformRes ource("textAreaResizeCorner")));
1104 resizeCornerImage = resizeCornerImageLoRes;
1105 cornerResizerSize = resizeCornerImage->size();
1106 }
1107
1108 if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
1109 context->save();
1110 context->translate(resizerCornerRect.x() + cornerResizerSize.width(), re sizerCornerRect.y() + resizerCornerRect.height() - cornerResizerSize.height());
1111 context->scale(-1.0, 1.0);
1112 context->drawImage(resizeCornerImage.get(), IntRect(IntPoint(), cornerRe sizerSize));
1113 context->restore();
1114 return;
1115 }
1116 IntRect imageRect(resizerCornerRect.maxXMaxYCorner() - cornerResizerSize, co rnerResizerSize);
1117 context->drawImage(resizeCornerImage.get(), imageRect);
1118 }
1119
1120 IntSize RenderLayerScrollableArea::offsetFromResizeCorner(const IntPoint& absolu tePoint) const
1121 {
1122 // Currently the resize corner is either the bottom right corner or the bott om left corner.
1123 // FIXME: This assumes the location is 0, 0. Is this guaranteed to always be the case?
1124 IntSize elementSize = layer()->size();
1125 if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
1126 elementSize.setWidth(0);
1127 IntPoint resizerPoint = IntPoint(elementSize);
1128 IntPoint localPoint = roundedIntPoint(box().absoluteToLocal(absolutePoint, U seTransforms));
1129 return localPoint - resizerPoint;
1130 }
1131
1132 void RenderLayerScrollableArea::resize(const PlatformEvent& evt, const LayoutSiz e& oldOffset)
1133 {
1134 // FIXME: This should be possible on generated content but is not right now.
1135 if (!inResizeMode() || !box().canResize() || !box().node())
1136 return;
1137
1138 ASSERT(box().node()->isElementNode());
1139 Element* element = toElement(box().node());
1140
1141 Document& document = element->document();
1142
1143 IntPoint pos;
1144 const PlatformGestureEvent* gevt = 0;
1145
1146 switch (evt.type()) {
1147 case PlatformEvent::MouseMoved:
1148 if (!document.frame()->eventHandler().mousePressed())
1149 return;
1150 pos = static_cast<const PlatformMouseEvent*>(&evt)->position();
1151 break;
1152 case PlatformEvent::GestureScrollUpdate:
1153 case PlatformEvent::GestureScrollUpdateWithoutPropagation:
1154 pos = static_cast<const PlatformGestureEvent*>(&evt)->position();
1155 gevt = static_cast<const PlatformGestureEvent*>(&evt);
1156 pos = gevt->position();
1157 pos.move(gevt->deltaX(), gevt->deltaY());
1158 break;
1159 default:
1160 ASSERT_NOT_REACHED();
1161 }
1162
1163 float zoomFactor = box().style()->effectiveZoom();
1164
1165 LayoutSize newOffset = offsetFromResizeCorner(document.view()->windowToConte nts(pos));
1166 newOffset.setWidth(newOffset.width() / zoomFactor);
1167 newOffset.setHeight(newOffset.height() / zoomFactor);
1168
1169 LayoutSize currentSize = LayoutSize(box().width() / zoomFactor, box().height () / zoomFactor);
1170 LayoutSize minimumSize = element->minimumSizeForResizing().shrunkTo(currentS ize);
1171 element->setMinimumSizeForResizing(minimumSize);
1172
1173 LayoutSize adjustedOldOffset = LayoutSize(oldOffset.width() / zoomFactor, ol dOffset.height() / zoomFactor);
1174 if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
1175 newOffset.setWidth(-newOffset.width());
1176 adjustedOldOffset.setWidth(-adjustedOldOffset.width());
1177 }
1178
1179 LayoutSize difference = (currentSize + newOffset - adjustedOldOffset).expand edTo(minimumSize) - currentSize;
1180
1181 bool isBoxSizingBorder = box().style()->boxSizing() == BORDER_BOX;
1182
1183 EResize resize = box().style()->resize();
1184 if (resize != RESIZE_VERTICAL && difference.width()) {
1185 LayoutUnit baseWidth = box().width() - (isBoxSizingBorder ? LayoutUnit() : box().borderAndPaddingWidth());
1186 baseWidth = baseWidth / zoomFactor;
1187 element->setInlineStyleProperty(CSSPropertyWidth, roundToInt(baseWidth + difference.width()), CSSPrimitiveValue::CSS_PX);
1188 }
1189
1190 if (resize != RESIZE_HORIZONTAL && difference.height()) {
1191 LayoutUnit baseHeight = box().height() - (isBoxSizingBorder ? LayoutUnit () : box().borderAndPaddingHeight());
1192 baseHeight = baseHeight / zoomFactor;
1193 element->setInlineStyleProperty(CSSPropertyHeight, roundToInt(baseHeight + difference.height()), CSSPrimitiveValue::CSS_PX);
1194 }
1195
1196 document.updateLayout();
1197
1198 // FIXME (Radar 4118564): We should also autoscroll the window as necessary to keep the point under the cursor in view.
1199 }
1200
1201 LayoutRect RenderLayerScrollableArea::exposeRect(const LayoutRect& rect, const S crollAlignment& alignX, const ScrollAlignment& alignY) 868 LayoutRect RenderLayerScrollableArea::exposeRect(const LayoutRect& rect, const S crollAlignment& alignX, const ScrollAlignment& alignY)
1202 { 869 {
1203 LayoutRect localExposeRect(box().absoluteToLocalQuad(FloatQuad(FloatRect(rec t)), UseTransforms).boundingBox()); 870 LayoutRect localExposeRect(box().absoluteToLocalQuad(FloatQuad(FloatRect(rec t)), UseTransforms).boundingBox());
1204 LayoutRect layerBounds(0, 0, box().clientWidth(), box().clientHeight()); 871 LayoutRect layerBounds(0, 0, box().clientWidth(), box().clientHeight());
1205 LayoutRect r = ScrollAlignment::getRectToExpose(layerBounds, localExposeRect , alignX, alignY); 872 LayoutRect r = ScrollAlignment::getRectToExpose(layerBounds, localExposeRect , alignX, alignY);
1206 873
1207 IntSize clampedScrollOffset = clampScrollOffset(adjustedScrollOffset() + toI ntSize(roundedIntRect(r).location())); 874 IntSize clampedScrollOffset = clampScrollOffset(adjustedScrollOffset() + toI ntSize(roundedIntRect(r).location()));
1208 if (clampedScrollOffset == adjustedScrollOffset()) 875 if (clampedScrollOffset == adjustedScrollOffset())
1209 return rect; 876 return rect;
1210 877
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 void RenderLayerScrollableArea::setTopmostScrollChild(RenderLayer* scrollChild) 952 void RenderLayerScrollableArea::setTopmostScrollChild(RenderLayer* scrollChild)
1286 { 953 {
1287 // We only want to track the topmost scroll child for scrollable areas with 954 // We only want to track the topmost scroll child for scrollable areas with
1288 // overlay scrollbars. 955 // overlay scrollbars.
1289 if (!hasOverlayScrollbars()) 956 if (!hasOverlayScrollbars())
1290 return; 957 return;
1291 m_nextTopmostScrollChild = scrollChild; 958 m_nextTopmostScrollChild = scrollChild;
1292 } 959 }
1293 960
1294 } // namespace blink 961 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/core/rendering/RenderLayerScrollableArea.h ('k') | sky/engine/core/rendering/compositing/CompositedLayerMapping.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698