summaryrefslogtreecommitdiff
path: root/dom/events/WheelHandlingHelper.h
blob: b88aa23b2d4c1771596b713d36114fe7125760b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_WheelHandlingHelper_h_
#define mozilla_WheelHandlingHelper_h_

#include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"
#include "nsCoord.h"
#include "nsIFrame.h"
#include "nsPoint.h"

class nsIScrollableFrame;
class nsITimer;

namespace mozilla {

class EventStateManager;

/**
 * DeltaValues stores two delta values which are along X and Y axis.  This is
 * useful for arguments and results of some methods.
 */

struct DeltaValues
{
  DeltaValues()
    : deltaX(0.0)
    , deltaY(0.0)
  {
  }

  DeltaValues(double aDeltaX, double aDeltaY)
    : deltaX(aDeltaX)
    , deltaY(aDeltaY)
  {
  }

  explicit DeltaValues(WidgetWheelEvent* aEvent);

  double deltaX;
  double deltaY;
};

/**
 * WheelHandlingUtils provides some static methods which are useful at handling
 * wheel events.
 */

class WheelHandlingUtils
{
public:
  /**
   * Returns true if aFrame is a scrollable frame and it can be scrolled to
   * either aDirectionX or aDirectionY along each axis.  Or if aFrame is a
   * plugin frame (in this case, aDirectionX and aDirectionY are ignored).
   * Otherwise, false.
   */
  static bool CanScrollOn(nsIFrame* aFrame,
                          double aDirectionX, double aDirectionY);
  /**
   * Returns true if the scrollable frame can be scrolled to either aDirectionX
   * or aDirectionY along each axis.  Otherwise, false.
   */
  static bool CanScrollOn(nsIScrollableFrame* aScrollFrame,
                          double aDirectionX, double aDirectionY);

private:
  static bool CanScrollInRange(nscoord aMin, nscoord aValue, nscoord aMax,
                               double aDirection);
};

/**
 * ScrollbarsForWheel manages scrollbars state during wheel operation.
 * E.g., on some platforms, scrollbars should show only while user attempts to
 * scroll.  At that time, scrollbars which may be possible to scroll by
 * operation of wheel at the point should show temporarily.
 */

class ScrollbarsForWheel
{
public:
  static void PrepareToScrollText(EventStateManager* aESM,
                                  nsIFrame* aTargetFrame,
                                  WidgetWheelEvent* aEvent);
  static void SetActiveScrollTarget(nsIScrollableFrame* aScrollTarget);
  // Hide all scrollbars (both mActiveOwner's and mActivatedScrollTargets')
  static void MayInactivate();
  static void Inactivate();
  static bool IsActive();
  static void OwnWheelTransaction(bool aOwn);

protected:
  static const size_t kNumberOfTargets = 4;
  static const DeltaValues directions[kNumberOfTargets];
  static nsWeakFrame sActiveOwner;
  static nsWeakFrame sActivatedScrollTargets[kNumberOfTargets];
  static bool sHadWheelStart;
  static bool sOwnWheelTransaction;


  /**
   * These two methods are called upon eWheelOperationStart/eWheelOperationEnd
   * events to show/hide the right scrollbars.
   */
  static void TemporarilyActivateAllPossibleScrollTargets(
                EventStateManager* aESM,
                nsIFrame* aTargetFrame,
                WidgetWheelEvent* aEvent);
  static void DeactivateAllTemporarilyActivatedScrollTargets();
};

/**
 * WheelTransaction manages a series of wheel events as a transaction.
 * While in a transaction, every wheel event should scroll the same scrollable
 * element even if a different scrollable element is under the mouse cursor.
 *
 * Additionally, this class also manages wheel scroll speed acceleration.
 */

class WheelTransaction
{
public:
  static nsIFrame* GetTargetFrame() { return sTargetFrame; }
  static void EndTransaction();
  /**
   * WillHandleDefaultAction() is called before handling aWheelEvent on
   * aTargetFrame.
   *
   * @return    false if the caller cannot continue to handle the default
   *            action.  Otherwise, true.
   */ 
  static bool WillHandleDefaultAction(WidgetWheelEvent* aWheelEvent,
                                      nsWeakFrame& aTargetWeakFrame);
  static bool WillHandleDefaultAction(WidgetWheelEvent* aWheelEvent,
                                      nsIFrame* aTargetFrame)
  {
    nsWeakFrame targetWeakFrame(aTargetFrame);
    return WillHandleDefaultAction(aWheelEvent, targetWeakFrame);
  }
  static void OnEvent(WidgetEvent* aEvent);
  static void Shutdown();
  static uint32_t GetTimeoutTime();

  static void OwnScrollbars(bool aOwn);

  static DeltaValues AccelerateWheelDelta(WidgetWheelEvent* aEvent,
                                          bool aAllowScrollSpeedOverride);

protected:
  static void BeginTransaction(nsIFrame* aTargetFrame,
                               WidgetWheelEvent* aEvent);
  // Be careful, UpdateTransaction may fire a DOM event, therefore, the target
  // frame might be destroyed in the event handler.
  static bool UpdateTransaction(WidgetWheelEvent* aEvent);
  static void MayEndTransaction();

  static nsIntPoint GetScreenPoint(WidgetGUIEvent* aEvent);
  static void OnFailToScrollTarget();
  static void OnTimeout(nsITimer* aTimer, void* aClosure);
  static void SetTimeout();
  static uint32_t GetIgnoreMoveDelayTime();
  static int32_t GetAccelerationStart();
  static int32_t GetAccelerationFactor();
  static DeltaValues OverrideSystemScrollSpeed(WidgetWheelEvent* aEvent);
  static double ComputeAcceleratedWheelDelta(double aDelta, int32_t aFactor);
  static bool OutOfTime(uint32_t aBaseTime, uint32_t aThreshold);

  static nsWeakFrame sTargetFrame;
  static uint32_t sTime; // in milliseconds
  static uint32_t sMouseMoved; // in milliseconds
  static nsITimer* sTimer;
  static int32_t sScrollSeriesCounter;
  static bool sOwnScrollbars;
};

} // namespace mozilla

#endif // mozilla_WheelHandlingHelper_h_