ScrollViewAndroid.cpp revision 9364f22aed35e1a1e9d07c121510f80be3ab0502
1/* 2** 3** Copyright 2007, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#include "config.h" 19#include "ScrollView.h" 20 21#include "FloatRect.h" 22#include "IntRect.h" 23 24#include "WebCoreViewBridge.h" 25 26#define LOG_TAG "WebCore" 27#undef LOG 28#include "utils/Log.h" 29 30/* hack to allow the DOM to communicate how to interpret inval requests, since 31 it doesn't have the notion of distinguishing between the screen and the DOM 32 but we do, since we have a copy of the display in our picture, and we don't 33 want to rebuild the picture unless the DOM has actually been changed. 34*/ 35bool gAndroid_treatInvalForScreen; 36 37#define verifiedOk() // no need to do anything in this function 38 39/* 40 This class implementation does NOT actually emulate the Qt ScrollView. 41 It does provide an implementation that khtml will use to interact with 42 WebKit's WebFrameView documentView and our NSScrollView subclass. 43 44 ScrollView's view is a NSScrollView (or subclass of NSScrollView) 45 in most cases. That scrollview is a subview of an 46 WebCoreFrameView. The WebCoreFrameView's documentView will also be 47 the scroll view's documentView. 48 49 The WebCoreFrameView's size is the frame size. The WebCoreFrameView's documentView 50 corresponds to the frame content size. The scrollview itself is autosized to the 51 WebCoreFrameView's size (see Widget::resize). 52*/ 53 54namespace WebCore { 55 56struct ScrollView::ScrollViewPrivate 57{ 58public: 59 ScrollViewPrivate() : 60 hasStaticBackground(false), ignoreUpdateContents(false), 61 vScrollbarMode(ScrollbarAuto), 62 hScrollbarMode(ScrollbarAuto) {} 63 IntSize contentsSize; 64 bool hasStaticBackground; 65 bool ignoreUpdateContents; 66 ScrollbarMode vScrollbarMode; 67 ScrollbarMode hScrollbarMode; 68}; 69 70ScrollView::ScrollView() 71{ 72 m_data = new ScrollViewPrivate; 73} 74 75ScrollView::~ScrollView() 76{ 77 delete m_data; 78} 79 80int ScrollView::visibleWidth() const 81{ 82 LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); 83 return this->getWebCoreViewBridge()->width(); 84} 85 86int ScrollView::visibleHeight() const 87{ 88 LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); 89 return this->getWebCoreViewBridge()->height(); 90} 91 92FloatRect ScrollView::visibleContentRect() const 93{ 94 LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); 95 IntRect rect = this->getWebCoreViewBridge()->getBounds(); 96 // FIXME: This is a hack to get subframes drawing correctly. Since subframes cannot 97 // scroll, we know that if this view has a parent, the visible rect is (0, 0, w, h) 98 if (this->getWebCoreViewBridge()->getParent()) 99 return FloatRect(0, 0, rect.width(), rect.height()); 100 return FloatRect(rect.x(), rect.y(), rect.width(), rect.height()); 101} 102 103int ScrollView::contentsWidth() const 104{ 105 return m_data->contentsSize.width(); 106} 107 108int ScrollView::contentsHeight() const 109{ 110 return m_data->contentsSize.height(); 111} 112 113int ScrollView::contentsX() const 114{ 115 return scrollOffset().width(); 116} 117 118int ScrollView::contentsY() const 119{ 120 return scrollOffset().height(); 121} 122 123IntSize ScrollView::scrollOffset() const 124{ 125 LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); 126 WebCoreViewBridge* bridge = this->getWebCoreViewBridge(); 127 // FIXME: This is a hack to get subframes drawing correctly. Since subframes cannot 128 // scroll, we know that if this view has a parent, the scroll offset is always (0, 0) 129 if (bridge->getParent()) 130 return IntSize(0, 0); 131 return IntSize(bridge->locX(), bridge->locY()); 132} 133 134void ScrollView::scrollBy(int dx, int dy) 135{ 136 LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); 137 this->getWebCoreViewBridge()->scrollBy(dx, dy); 138} 139 140void WebCore::ScrollView::update() 141{ 142 LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); 143 this->getWebCoreViewBridge()->contentInvalidate(); 144} 145 146void WebCore::ScrollView::scrollRectIntoViewRecursively(WebCore::IntRect const& r) 147{ 148 LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); 149 int x = r.x(); 150 int y = r.y(); 151 IntPoint p(x > 0 ? x : 0, y > 0 ? y : 0); 152 ScrollView* view = this; 153 while (view) { 154 view->setContentsPos(p.x(), p.y()); 155 p.move(view->x() - view->scrollOffset().width(), view->y() - view->scrollOffset().height()); 156 if (view->getWebCoreViewBridge()->getParent()) 157 view = static_cast<ScrollView*>(view->getWebCoreViewBridge()->getParent()->widget()); 158 else 159 view = NULL; 160 } 161} 162 163WebCore::FloatRect WebCore::ScrollView::visibleContentRectConsideringExternalScrollers() const { 164 return FloatRect(contentsX(), contentsY(), contentsWidth(), contentsHeight()); 165} 166 167void ScrollView::setContentsPos(int x, int y) 168{ 169 LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); 170 this->getWebCoreViewBridge()->scrollTo(x, y); 171} 172 173//--------------------------------------------------------------------- 174// Scroll bar methods 175// 176// These methods are largely unimplemented meaning that the 177// state of the scroll bars in the only data maintained. If 178// a scroll bar is needed, the set(V|H)ScrollbarMode methods 179// need to update the scroll bar widget through the java 180// layer and display the new scroll bars. 181// 182//--------------------------------------------------------------------- 183 184void ScrollView::setVScrollbarMode(ScrollbarMode vMode) 185{ 186 m_data->vScrollbarMode = vMode; 187} 188 189void ScrollView::setHScrollbarMode(ScrollbarMode hMode) 190{ 191 m_data->hScrollbarMode = hMode; 192} 193 194void ScrollView::setScrollbarsMode(ScrollbarMode mode) 195{ 196 m_data->hScrollbarMode = mode; 197 m_data->vScrollbarMode = mode; 198} 199 200ScrollbarMode ScrollView::vScrollbarMode() const 201{ 202 return m_data->vScrollbarMode; 203} 204 205ScrollbarMode ScrollView::hScrollbarMode() const 206{ 207 return m_data->hScrollbarMode; 208} 209 210void ScrollView::suppressScrollbars(bool suppressed, bool repaintOnUnsuppress) 211{ 212 verifiedOk(); 213} 214 215//--------------------------------------------------------------------- 216// End Scroll bar methods 217//--------------------------------------------------------------------- 218 219void ScrollView::addChild(Widget* child) 220{ 221 LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); 222 WebCoreViewBridge* childBridge = child->getWebCoreViewBridge(); 223 // FIXME: For now just check this, it should be an assert down the road. 224 if (!childBridge) 225 { 226 LOGV("childBridge is not set"); 227 return; 228 } 229 LOG_ASSERT(child != this, "Child has no view bridge or child == this!"); 230 WebCoreViewBridge* thisBridge = this->getWebCoreViewBridge(); 231 LOG_ASSERT(thisBridge && thisBridge != childBridge, "Our bridge is not set or thisBridge == childBridge!"); 232 LOGV("Adding parent"); 233 childBridge->setParent(thisBridge); 234} 235 236void ScrollView::ignoreUpdateContents(bool ignore) 237{ 238 m_data->ignoreUpdateContents = ignore; 239} 240 241void ScrollView::removeChild(Widget* child) 242{ 243 // FIXME: Make this only an assert once all widgets have views 244 if (!child->getWebCoreViewBridge()) 245 { 246 LOGV("child has no bridge"); 247 return; 248 } 249 LOG_ASSERT(child->getWebCoreViewBridge(), "Child has no view bridge"); 250 child->getWebCoreViewBridge()->setParent(NULL); 251} 252 253void ScrollView::resizeContents(int w, int h) 254{ 255 LOG_ASSERT(this->getWebCoreViewBridge(), "ScrollView does not have a WebCoreViewBridge"); 256 if (w < 0) 257 w = 0; 258 if (h < 0) 259 h = 0; 260 261 IntSize newSize(w, h); 262 m_data->contentsSize = newSize; 263} 264 265void ScrollView::updateContents(const IntRect &rect, bool now) 266{ 267 LOG_ASSERT(this->getWebCoreViewBridge(), 268 "ScrollView does not have a WebCoreViewBridge"); 269 270 WebCoreViewBridge* bridge = this->getWebCoreViewBridge(); 271 272 if (gAndroid_treatInvalForScreen) { 273// SkDebugf("------ contentInvalidate sent to viewInvalidate [%d %d]\n", rect.width(), rect.height()); 274 bridge->viewInvalidate(); 275 } else if (m_data->ignoreUpdateContents == false) { 276 bridge->contentInvalidate(rect); 277 } 278} 279 280IntPoint ScrollView::windowToContents(const IntPoint& contentsPoint) const 281{ 282 WebCoreViewBridge* bridge = this->getWebCoreViewBridge(); 283 WebCoreViewBridge* parent = bridge->getParent(); 284 int x = 0, y= 0; 285 while (parent) { 286 x += bridge->locX(); 287 y += bridge->locY(); 288 bridge = parent; 289 parent = bridge->getParent(); 290 } 291 return IntPoint(contentsPoint.x() - x, contentsPoint.y() - y); 292} 293 294IntPoint ScrollView::contentsToWindow(const IntPoint& viewportPoint) const 295{ 296 WebCoreViewBridge* bridge = this->getWebCoreViewBridge(); 297 WebCoreViewBridge* parent = bridge->getParent(); 298 int x = 0, y= 0; 299 while (parent) { 300 x += bridge->locX(); 301 y += bridge->locY(); 302 bridge = parent; 303 parent = bridge->getParent(); 304 } 305 return IntPoint(viewportPoint.x() + x, viewportPoint.y() + y); 306} 307 308void ScrollView::setStaticBackground(bool) 309{ 310 // we don't have any optimizations for this 311 verifiedOk(); 312} 313 314bool ScrollView::inWindow() const 315{ 316 LOGV("inWindow Unimplemented"); 317#if 0 318 return [getView() window]; 319#endif 320 return true; 321} 322 323void ScrollView::wheelEvent(PlatformWheelEvent&) 324{ 325 verifiedOk(); 326} 327 328PlatformScrollbar* ScrollView::scrollbarUnderMouse(const PlatformMouseEvent& mouseEvent) 329{ 330 verifiedOk(); 331 return NULL; 332} 333 334} 335