1/*
2 * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef PlatformWheelEvent_h
27#define PlatformWheelEvent_h
28
29#include "IntPoint.h"
30#include "PlatformEvent.h"
31#include <wtf/WindowsExtras.h>
32
33#if PLATFORM(GTK)
34typedef struct _GdkEventScroll GdkEventScroll;
35#endif
36
37#if PLATFORM(EFL)
38typedef struct _Evas_Event_Mouse_Wheel Evas_Event_Mouse_Wheel;
39#endif
40
41namespace WebCore {
42
43    class FloatPoint;
44    class FloatSize;
45
46    // Wheel events come in two flavors:
47    // The ScrollByPixelWheelEvent is a fine-grained event that specifies the precise number of pixels to scroll.  It is sent directly by MacBook touchpads on OS X,
48    // and synthesized in other cases where platforms generate line-by-line scrolling events.
49    // The ScrollByPageWheelEvent indicates that the wheel event should scroll an entire page.  In this case WebCore's built in paging behavior is used to page
50    // up and down (you get the same behavior as if the user was clicking in a scrollbar track to page up or page down).
51    enum PlatformWheelEventGranularity : uint64_t {
52        ScrollByPageWheelEvent,
53        ScrollByPixelWheelEvent,
54    };
55
56#if PLATFORM(COCOA)
57    enum PlatformWheelEventPhase : uint64_t {
58        PlatformWheelEventPhaseNone        = 0,
59        PlatformWheelEventPhaseBegan       = 1 << 0,
60        PlatformWheelEventPhaseStationary  = 1 << 1,
61        PlatformWheelEventPhaseChanged     = 1 << 2,
62        PlatformWheelEventPhaseEnded       = 1 << 3,
63        PlatformWheelEventPhaseCancelled   = 1 << 4,
64        PlatformWheelEventPhaseMayBegin    = 1 << 5,
65    };
66#endif
67
68    class PlatformWheelEvent : public PlatformEvent {
69    public:
70        PlatformWheelEvent()
71            : PlatformEvent(PlatformEvent::Wheel)
72            , m_deltaX(0)
73            , m_deltaY(0)
74            , m_wheelTicksX(0)
75            , m_wheelTicksY(0)
76            , m_granularity(ScrollByPixelWheelEvent)
77            , m_directionInvertedFromDevice(false)
78#if PLATFORM(COCOA)
79            , m_hasPreciseScrollingDeltas(false)
80            , m_phase(PlatformWheelEventPhaseNone)
81            , m_momentumPhase(PlatformWheelEventPhaseNone)
82            , m_scrollCount(0)
83            , m_unacceleratedScrollingDeltaX(0)
84            , m_unacceleratedScrollingDeltaY(0)
85#endif
86        {
87        }
88
89        PlatformWheelEvent(IntPoint position, IntPoint globalPosition, float deltaX, float deltaY, float wheelTicksX, float wheelTicksY, PlatformWheelEventGranularity granularity, bool shiftKey, bool ctrlKey, bool altKey, bool metaKey)
90            : PlatformEvent(PlatformEvent::Wheel, shiftKey, ctrlKey, altKey, metaKey, 0)
91            , m_position(position)
92            , m_globalPosition(globalPosition)
93            , m_deltaX(deltaX)
94            , m_deltaY(deltaY)
95            , m_wheelTicksX(wheelTicksX)
96            , m_wheelTicksY(wheelTicksY)
97            , m_granularity(granularity)
98            , m_directionInvertedFromDevice(false)
99#if PLATFORM(COCOA)
100            , m_hasPreciseScrollingDeltas(false)
101            , m_phase(PlatformWheelEventPhaseNone)
102            , m_momentumPhase(PlatformWheelEventPhaseNone)
103            , m_scrollCount(0)
104            , m_unacceleratedScrollingDeltaX(0)
105            , m_unacceleratedScrollingDeltaY(0)
106#endif
107        {
108        }
109
110        PlatformWheelEvent copyTurningVerticalTicksIntoHorizontalTicks() const
111        {
112            PlatformWheelEvent copy = *this;
113
114            copy.m_deltaX = copy.m_deltaY;
115            copy.m_deltaY = 0;
116            copy.m_wheelTicksX = copy.m_wheelTicksY;
117            copy.m_wheelTicksY = 0;
118
119            return copy;
120        }
121
122        PlatformWheelEvent copyIgnoringHorizontalDelta() const
123        {
124            PlatformWheelEvent copy = *this;
125            copy.m_deltaX = 0;
126            return copy;
127        }
128
129        PlatformWheelEvent copyIgnoringVerticalDelta() const
130        {
131            PlatformWheelEvent copy = *this;
132            copy.m_deltaY = 0;
133            return copy;
134        }
135
136        const IntPoint& position() const { return m_position; } // PlatformWindow coordinates.
137        const IntPoint& globalPosition() const { return m_globalPosition; } // Screen coordinates.
138
139        float deltaX() const { return m_deltaX; }
140        float deltaY() const { return m_deltaY; }
141
142        float wheelTicksX() const { return m_wheelTicksX; }
143        float wheelTicksY() const { return m_wheelTicksY; }
144
145        PlatformWheelEventGranularity granularity() const { return m_granularity; }
146
147        bool directionInvertedFromDevice() const { return m_directionInvertedFromDevice; }
148
149#if PLATFORM(GTK)
150        explicit PlatformWheelEvent(GdkEventScroll*);
151#endif
152
153#if PLATFORM(EFL)
154        explicit PlatformWheelEvent(const Evas_Event_Mouse_Wheel*);
155#endif
156
157#if PLATFORM(COCOA)
158        bool hasPreciseScrollingDeltas() const { return m_hasPreciseScrollingDeltas; }
159        void setHasPreciseScrollingDeltas(bool b) { m_hasPreciseScrollingDeltas = b; }
160        PlatformWheelEventPhase phase() const { return m_phase; }
161        PlatformWheelEventPhase momentumPhase() const { return m_momentumPhase; }
162        unsigned scrollCount() const { return m_scrollCount; }
163        float unacceleratedScrollingDeltaX() const { return m_unacceleratedScrollingDeltaX; }
164        float unacceleratedScrollingDeltaY() const { return m_unacceleratedScrollingDeltaY; }
165        bool useLatchedEventElement() const
166        {
167            return m_phase == PlatformWheelEventPhaseBegan || m_phase == PlatformWheelEventPhaseChanged
168                || m_momentumPhase == PlatformWheelEventPhaseBegan || m_momentumPhase == PlatformWheelEventPhaseChanged;
169        }
170        bool shouldConsiderLatching() const
171        {
172            return m_phase == PlatformWheelEventPhaseBegan || m_phase == PlatformWheelEventPhaseMayBegin;
173        }
174        bool shouldResetLatching() const
175        {
176            if (m_phase == PlatformWheelEventPhaseCancelled || m_phase == PlatformWheelEventPhaseMayBegin)
177                return true;
178
179            if (m_phase == PlatformWheelEventPhaseNone && m_momentumPhase == PlatformWheelEventPhaseEnded)
180                return true;
181
182            return false;
183        }
184#else
185        bool useLatchedEventElement() const { return false; }
186#endif
187
188#if PLATFORM(WIN)
189        PlatformWheelEvent(HWND, WPARAM, LPARAM, bool isMouseHWheel);
190        PlatformWheelEvent(HWND, const FloatSize& delta, const FloatPoint& location);
191#endif
192
193    protected:
194        IntPoint m_position;
195        IntPoint m_globalPosition;
196        float m_deltaX;
197        float m_deltaY;
198        float m_wheelTicksX;
199        float m_wheelTicksY;
200        PlatformWheelEventGranularity m_granularity;
201        bool m_directionInvertedFromDevice;
202#if PLATFORM(COCOA)
203        bool m_hasPreciseScrollingDeltas;
204        PlatformWheelEventPhase m_phase;
205        PlatformWheelEventPhase m_momentumPhase;
206        unsigned m_scrollCount;
207        float m_unacceleratedScrollingDeltaX;
208        float m_unacceleratedScrollingDeltaY;
209#endif
210    };
211
212} // namespace WebCore
213
214#endif // PlatformWheelEvent_h
215