mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 07:18:39 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
298
layout/xul/nsScrollbarButtonFrame.cpp
Normal file
298
layout/xul/nsScrollbarButtonFrame.cpp
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
//
|
||||
// Eric Vaughan
|
||||
// Netscape Communications
|
||||
//
|
||||
// See documentation in associated header file
|
||||
//
|
||||
|
||||
#include "nsScrollbarButtonFrame.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsSliderFrame.h"
|
||||
#include "nsScrollbarFrame.h"
|
||||
#include "nsIScrollbarMediator.h"
|
||||
#include "nsRepeatService.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/layers/ScrollInputMethods.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using mozilla::layers::ScrollInputMethod;
|
||||
|
||||
//
|
||||
// NS_NewToolbarFrame
|
||||
//
|
||||
// Creates a new Toolbar frame and returns it
|
||||
//
|
||||
nsIFrame*
|
||||
NS_NewScrollbarButtonFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
|
||||
{
|
||||
return new (aPresShell) nsScrollbarButtonFrame(aContext);
|
||||
}
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsScrollbarButtonFrame)
|
||||
|
||||
nsresult
|
||||
nsScrollbarButtonFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
WidgetGUIEvent* aEvent,
|
||||
nsEventStatus* aEventStatus)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEventStatus);
|
||||
|
||||
// If a web page calls event.preventDefault() we still want to
|
||||
// scroll when scroll arrow is clicked. See bug 511075.
|
||||
if (!mContent->IsInNativeAnonymousSubtree() &&
|
||||
nsEventStatus_eConsumeNoDefault == *aEventStatus) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
switch (aEvent->mMessage) {
|
||||
case eMouseDown:
|
||||
mCursorOnThis = true;
|
||||
// if we didn't handle the press ourselves, pass it on to the superclass
|
||||
if (HandleButtonPress(aPresContext, aEvent, aEventStatus)) {
|
||||
return NS_OK;
|
||||
}
|
||||
break;
|
||||
case eMouseUp:
|
||||
HandleRelease(aPresContext, aEvent, aEventStatus);
|
||||
break;
|
||||
case eMouseOut:
|
||||
mCursorOnThis = false;
|
||||
break;
|
||||
case eMouseMove: {
|
||||
nsPoint cursor =
|
||||
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
|
||||
nsRect frameRect(nsPoint(0, 0), GetSize());
|
||||
mCursorOnThis = frameRect.Contains(cursor);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return nsButtonBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||
}
|
||||
|
||||
bool
|
||||
nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext,
|
||||
WidgetGUIEvent* aEvent,
|
||||
nsEventStatus* aEventStatus)
|
||||
{
|
||||
// Get the desired action for the scrollbar button.
|
||||
LookAndFeel::IntID tmpAction;
|
||||
uint16_t button = aEvent->AsMouseEvent()->button;
|
||||
if (button == WidgetMouseEvent::eLeftButton) {
|
||||
tmpAction = LookAndFeel::eIntID_ScrollButtonLeftMouseButtonAction;
|
||||
} else if (button == WidgetMouseEvent::eMiddleButton) {
|
||||
tmpAction = LookAndFeel::eIntID_ScrollButtonMiddleMouseButtonAction;
|
||||
} else if (button == WidgetMouseEvent::eRightButton) {
|
||||
tmpAction = LookAndFeel::eIntID_ScrollButtonRightMouseButtonAction;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the button action metric from the pres. shell.
|
||||
int32_t pressedButtonAction;
|
||||
if (NS_FAILED(LookAndFeel::GetInt(tmpAction, &pressedButtonAction))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the scrollbar control
|
||||
nsIFrame* scrollbar;
|
||||
GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar);
|
||||
|
||||
if (scrollbar == nullptr)
|
||||
return false;
|
||||
|
||||
static nsIContent::AttrValuesArray strings[] = { &nsGkAtoms::increment,
|
||||
&nsGkAtoms::decrement,
|
||||
nullptr };
|
||||
int32_t index = mContent->FindAttrValueIn(kNameSpaceID_None,
|
||||
nsGkAtoms::type,
|
||||
strings, eCaseMatters);
|
||||
int32_t direction;
|
||||
if (index == 0)
|
||||
direction = 1;
|
||||
else if (index == 1)
|
||||
direction = -1;
|
||||
else
|
||||
return false;
|
||||
|
||||
bool repeat = pressedButtonAction != 2;
|
||||
// set this attribute so we can style it later
|
||||
nsWeakFrame weakFrame(this);
|
||||
mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::active, NS_LITERAL_STRING("true"), true);
|
||||
|
||||
nsIPresShell::SetCapturingContent(mContent, CAPTURE_IGNOREALLOWED);
|
||||
|
||||
if (!weakFrame.IsAlive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsScrollbarFrame* sb = do_QueryFrame(scrollbar);
|
||||
if (sb) {
|
||||
nsIScrollbarMediator* m = sb->GetScrollbarMediator();
|
||||
switch (pressedButtonAction) {
|
||||
case 0:
|
||||
sb->SetIncrementToLine(direction);
|
||||
if (m) {
|
||||
m->ScrollByLine(sb, direction, nsIScrollbarMediator::ENABLE_SNAP);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
sb->SetIncrementToPage(direction);
|
||||
if (m) {
|
||||
m->ScrollByPage(sb, direction, nsIScrollbarMediator::ENABLE_SNAP);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
sb->SetIncrementToWhole(direction);
|
||||
if (m) {
|
||||
m->ScrollByWhole(sb, direction, nsIScrollbarMediator::ENABLE_SNAP);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
// We were told to ignore this click, or someone assigned a non-standard
|
||||
// value to the button's action.
|
||||
return false;
|
||||
}
|
||||
if (!weakFrame.IsAlive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS,
|
||||
(uint32_t) ScrollInputMethod::MainThreadScrollbarButtonClick);
|
||||
|
||||
if (!m) {
|
||||
sb->MoveToNewPosition();
|
||||
if (!weakFrame.IsAlive()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (repeat) {
|
||||
StartRepeat();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollbarButtonFrame::HandleRelease(nsPresContext* aPresContext,
|
||||
WidgetGUIEvent* aEvent,
|
||||
nsEventStatus* aEventStatus)
|
||||
{
|
||||
nsIPresShell::SetCapturingContent(nullptr, 0);
|
||||
// we're not active anymore
|
||||
mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::active, true);
|
||||
StopRepeat();
|
||||
nsIFrame* scrollbar;
|
||||
GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar);
|
||||
nsScrollbarFrame* sb = do_QueryFrame(scrollbar);
|
||||
if (sb) {
|
||||
nsIScrollbarMediator* m = sb->GetScrollbarMediator();
|
||||
if (m) {
|
||||
m->ScrollbarReleased(sb);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsScrollbarButtonFrame::Notify()
|
||||
{
|
||||
if (mCursorOnThis ||
|
||||
LookAndFeel::GetInt(
|
||||
LookAndFeel::eIntID_ScrollbarButtonAutoRepeatBehavior, 0)) {
|
||||
// get the scrollbar control
|
||||
nsIFrame* scrollbar;
|
||||
GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar);
|
||||
nsScrollbarFrame* sb = do_QueryFrame(scrollbar);
|
||||
if (sb) {
|
||||
nsIScrollbarMediator* m = sb->GetScrollbarMediator();
|
||||
if (m) {
|
||||
m->RepeatButtonScroll(sb);
|
||||
} else {
|
||||
sb->MoveToNewPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollbarButtonFrame::MouseClicked(WidgetGUIEvent* aEvent)
|
||||
{
|
||||
nsButtonBoxFrame::MouseClicked(aEvent);
|
||||
//MouseClicked();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScrollbarButtonFrame::GetChildWithTag(nsIAtom* atom, nsIFrame* start,
|
||||
nsIFrame*& result)
|
||||
{
|
||||
// recursively search our children
|
||||
for (nsIFrame* childFrame : start->PrincipalChildList())
|
||||
{
|
||||
// get the content node
|
||||
nsIContent* child = childFrame->GetContent();
|
||||
|
||||
if (child) {
|
||||
// see if it is the child
|
||||
if (child->IsXULElement(atom))
|
||||
{
|
||||
result = childFrame;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// recursive search the child
|
||||
GetChildWithTag(atom, childFrame, result);
|
||||
if (result != nullptr)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
result = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScrollbarButtonFrame::GetParentWithTag(nsIAtom* toFind, nsIFrame* start,
|
||||
nsIFrame*& result)
|
||||
{
|
||||
while (start)
|
||||
{
|
||||
start = start->GetParent();
|
||||
|
||||
if (start) {
|
||||
// get the content node
|
||||
nsIContent* child = start->GetContent();
|
||||
|
||||
if (child && child->IsXULElement(toFind)) {
|
||||
result = start;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollbarButtonFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
{
|
||||
// Ensure our repeat service isn't going... it's possible that a scrollbar can disappear out
|
||||
// from under you while you're in the process of scrolling.
|
||||
StopRepeat();
|
||||
nsButtonBoxFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue