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 33 namespace blink { 34 35 Widget::Widget() 36 : m_parent(0) 37 , m_selfVisible(false) 38 , m_parentVisible(false) 39 { 40 } 41 42 Widget::~Widget() 43 { 44 ASSERT(!parent()); 45 } 46 47 void 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 57 Widget* 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 67 IntRect 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 76 IntRect 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 85 IntPoint 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 94 FloatPoint 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 113 IntPoint 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 122 IntRect 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 132 IntRect 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 143 IntPoint 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 151 IntPoint 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 159 IntPoint Widget::convertChildToSelf(const Widget*, const IntPoint& point) const 160 { 161 return point; 162 } 163 164 IntPoint Widget::convertSelfToChild(const Widget*, const IntPoint& point) const 165 { 166 return point; 167 } 168 169 } // namespace blink 170