2 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
3 * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
4 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
5 * Copyright (C) 2003, 2005, 2006, 2008 Apple Inc. All rights reserved.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
24 #include "MouseRelatedEvent.h"
26 #include "DOMWindow.h"
29 #include "FrameView.h"
30 #include "RenderLayer.h"
31 #include "RenderObject.h"
35 MouseRelatedEvent::MouseRelatedEvent()
36 : m_isSimulated(false)
37 , m_hasCachedRelativePosition(false)
41 static LayoutSize contentsScrollOffset(AbstractView* abstractView)
45 Frame* frame = abstractView->frame();
48 FrameView* frameView = frame->view();
51 return LayoutSize(frameView->scrollX() / frame->pageZoomFactor(),
52 frameView->scrollY() / frame->pageZoomFactor());
55 MouseRelatedEvent::MouseRelatedEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtr<AbstractView> abstractView,
56 int detail, const LayoutPoint& screenLocation, const LayoutPoint& windowLocation,
57 bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool isSimulated)
58 : UIEventWithKeyState(eventType, canBubble, cancelable, abstractView, detail, ctrlKey, altKey, shiftKey, metaKey)
59 , m_screenLocation(screenLocation)
60 , m_isSimulated(isSimulated)
62 LayoutPoint adjustedPageLocation;
63 LayoutPoint scrollPosition;
65 Frame* frame = view() ? view()->frame() : 0;
66 if (frame && !isSimulated) {
67 if (FrameView* frameView = frame->view()) {
68 scrollPosition = frameView->scrollPosition();
69 adjustedPageLocation = frameView->windowToContents(windowLocation);
70 float pageZoom = frame->pageZoomFactor();
71 if (pageZoom != 1.0f) {
72 // Adjust our pageX and pageY to account for the page zoom.
73 adjustedPageLocation.scale(1 / pageZoom, 1 / pageZoom);
75 // FIXME: Change this to use float math and proper rounding (or
76 // better yet, use LayoutPoint::scale).
77 scrollPosition.setX(scrollPosition.x() / pageZoom);
78 scrollPosition.setY(scrollPosition.y() / pageZoom);
83 m_clientLocation = adjustedPageLocation - toSize(scrollPosition);
84 m_pageLocation = adjustedPageLocation;
89 void MouseRelatedEvent::initCoordinates()
91 // Set up initial values for coordinates.
92 // Correct values are computed lazily, see computeRelativePosition.
93 m_layerLocation = m_pageLocation;
94 m_offsetLocation = m_pageLocation;
96 computePageLocation();
97 m_hasCachedRelativePosition = false;
100 void MouseRelatedEvent::initCoordinates(const LayoutPoint& clientLocation)
102 // Set up initial values for coordinates.
103 // Correct values are computed lazily, see computeRelativePosition.
104 m_clientLocation = clientLocation;
105 m_pageLocation = clientLocation + contentsScrollOffset(view());
107 m_layerLocation = m_pageLocation;
108 m_offsetLocation = m_pageLocation;
110 computePageLocation();
111 m_hasCachedRelativePosition = false;
114 static float pageZoomFactor(const UIEvent* event)
116 DOMWindow* window = event->view();
119 Frame* frame = window->frame();
122 return frame->pageZoomFactor();
125 void MouseRelatedEvent::computePageLocation()
127 float zoomFactor = pageZoomFactor(this);
128 setAbsoluteLocation(roundedLayoutPoint(FloatPoint(pageX() * zoomFactor, pageY() * zoomFactor)));
131 void MouseRelatedEvent::receivedTarget()
133 m_hasCachedRelativePosition = false;
136 void MouseRelatedEvent::computeRelativePosition()
138 Node* targetNode = target() ? target()->toNode() : 0;
142 // Compute coordinates that are based on the target.
143 m_layerLocation = m_pageLocation;
144 m_offsetLocation = m_pageLocation;
146 // Must have an updated render tree for this math to work correctly.
147 targetNode->document()->updateStyleIfNeeded();
149 // Adjust offsetLocation to be relative to the target's position.
150 if (!isSimulated()) {
151 if (RenderObject* r = targetNode->renderer()) {
152 FloatPoint localPos = r->absoluteToLocal(absoluteLocation(), false, true);
153 m_offsetLocation = roundedLayoutPoint(localPos);
154 float scaleFactor = 1 / pageZoomFactor(this);
155 if (scaleFactor != 1.0f)
156 m_offsetLocation.scale(scaleFactor, scaleFactor);
160 // Adjust layerLocation to be relative to the layer.
161 // FIXME: We're pretty sure this is the wrong definition of "layer."
162 // Our RenderLayer is a more modern concept, and layerX/Y is some
163 // other notion about groups of elements (left over from the Netscape 4 days?);
164 // we should test and fix this.
165 Node* n = targetNode;
166 while (n && !n->renderer())
170 if (n && (layer = n->renderer()->enclosingLayer())) {
171 layer->updateLayerPosition();
172 for (; layer; layer = layer->parent()) {
173 m_layerLocation -= toSize(layer->location());
177 m_hasCachedRelativePosition = true;
180 int MouseRelatedEvent::layerX()
182 if (!m_hasCachedRelativePosition)
183 computeRelativePosition();
184 return m_layerLocation.x();
187 int MouseRelatedEvent::layerY()
189 if (!m_hasCachedRelativePosition)
190 computeRelativePosition();
191 return m_layerLocation.y();
194 int MouseRelatedEvent::offsetX()
196 if (!m_hasCachedRelativePosition)
197 computeRelativePosition();
198 return m_offsetLocation.x();
201 int MouseRelatedEvent::offsetY()
203 if (!m_hasCachedRelativePosition)
204 computeRelativePosition();
205 return m_offsetLocation.y();
208 int MouseRelatedEvent::pageX() const
210 return m_pageLocation.x();
213 int MouseRelatedEvent::pageY() const
215 return m_pageLocation.y();
218 const LayoutPoint& MouseRelatedEvent::pageLocation() const
220 return m_pageLocation;
223 int MouseRelatedEvent::x() const
225 // FIXME: This is not correct.
226 // See Microsoft documentation and <http://www.quirksmode.org/dom/w3c_events.html>.
227 return m_clientLocation.x();
230 int MouseRelatedEvent::y() const
232 // FIXME: This is not correct.
233 // See Microsoft documentation and <http://www.quirksmode.org/dom/w3c_events.html>.
234 return m_clientLocation.y();
237 } // namespace WebCore