1/* 2 * Copyright (C) 2004, 2005, 2006, 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2013 Google Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "config.h" 28#include "platform/Widget.h" 29 30 31#include "wtf/Assertions.h" 32 33namespace blink { 34 35Widget::Widget() 36 : m_parent(0) 37 , m_selfVisible(false) 38 , m_parentVisible(false) 39{ 40} 41 42Widget::~Widget() 43{ 44 ASSERT(!parent()); 45} 46 47void Widget::setParent(Widget* widget) 48{ 49 ASSERT(!widget || !m_parent); 50 if (!widget || !widget->isVisible()) 51 setParentVisible(false); 52 m_parent = widget; 53 if (widget && widget->isVisible()) 54 setParentVisible(true); 55} 56 57Widget* Widget::root() const 58{ 59 const Widget* top = this; 60 while (top->parent()) 61 top = top->parent(); 62 if (top->isFrameView()) 63 return const_cast<Widget*>(static_cast<const Widget*>(top)); 64 return 0; 65} 66 67IntRect Widget::convertFromContainingWindow(const IntRect& windowRect) const 68{ 69 if (const Widget* parentWidget = parent()) { 70 IntRect parentRect = parentWidget->convertFromContainingWindow(windowRect); 71 return convertFromContainingView(parentRect); 72 } 73 return windowRect; 74} 75 76IntRect Widget::convertToContainingWindow(const IntRect& localRect) const 77{ 78 if (const Widget* parentWidget = parent()) { 79 IntRect parentRect = convertToContainingView(localRect); 80 return parentWidget->convertToContainingWindow(parentRect); 81 } 82 return localRect; 83} 84 85IntPoint Widget::convertFromContainingWindow(const IntPoint& windowPoint) const 86{ 87 if (const Widget* parentWidget = parent()) { 88 IntPoint parentPoint = parentWidget->convertFromContainingWindow(windowPoint); 89 return convertFromContainingView(parentPoint); 90 } 91 return windowPoint; 92} 93 94FloatPoint Widget::convertFromContainingWindow(const FloatPoint& windowPoint) const 95{ 96 // Widgets / windows are required to be IntPoint aligned, but we may need to convert 97 // FloatPoint values within them (eg. for event co-ordinates). 98 IntPoint flooredPoint = flooredIntPoint(windowPoint); 99 FloatPoint parentPoint = this->convertFromContainingWindow(flooredPoint); 100 FloatSize windowFraction = windowPoint - flooredPoint; 101 // Use linear interpolation handle any fractional value (eg. for iframes subject to a transform 102 // beyond just a simple translation). 103 // FIXME: Add FloatPoint variants of all co-ordinate space conversion APIs. 104 if (!windowFraction.isEmpty()) { 105 const int kFactor = 1000; 106 IntPoint parentLineEnd = this->convertFromContainingWindow(flooredPoint + roundedIntSize(windowFraction.scaledBy(kFactor))); 107 FloatSize parentFraction = (parentLineEnd - parentPoint).scaledBy(1.0f / kFactor); 108 parentPoint.move(parentFraction); 109 } 110 return parentPoint; 111} 112 113IntPoint Widget::convertToContainingWindow(const IntPoint& localPoint) const 114{ 115 if (const Widget* parentWidget = parent()) { 116 IntPoint parentPoint = convertToContainingView(localPoint); 117 return parentWidget->convertToContainingWindow(parentPoint); 118 } 119 return localPoint; 120} 121 122IntRect Widget::convertToContainingView(const IntRect& localRect) const 123{ 124 if (const Widget* parentWidget = parent()) { 125 IntRect parentRect(localRect); 126 parentRect.setLocation(parentWidget->convertChildToSelf(this, localRect.location())); 127 return parentRect; 128 } 129 return localRect; 130} 131 132IntRect Widget::convertFromContainingView(const IntRect& parentRect) const 133{ 134 if (const Widget* parentWidget = parent()) { 135 IntRect localRect = parentRect; 136 localRect.setLocation(parentWidget->convertSelfToChild(this, localRect.location())); 137 return localRect; 138 } 139 140 return parentRect; 141} 142 143IntPoint Widget::convertToContainingView(const IntPoint& localPoint) const 144{ 145 if (const Widget* parentWidget = parent()) 146 return parentWidget->convertChildToSelf(this, localPoint); 147 148 return localPoint; 149} 150 151IntPoint Widget::convertFromContainingView(const IntPoint& parentPoint) const 152{ 153 if (const Widget* parentWidget = parent()) 154 return parentWidget->convertSelfToChild(this, parentPoint); 155 156 return parentPoint; 157} 158 159IntPoint Widget::convertChildToSelf(const Widget*, const IntPoint& point) const 160{ 161 return point; 162} 163 164IntPoint Widget::convertSelfToChild(const Widget*, const IntPoint& point) const 165{ 166 return point; 167} 168 169} // namespace blink 170