2001-09-29 00:14:13 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
1999-06-15 08:02:43 +04:00
|
|
|
|
|
|
|
//
|
|
|
|
// Eric Vaughan
|
|
|
|
// Netscape Communications
|
|
|
|
//
|
|
|
|
// See documentation in associated header file
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "nsScrollbarButtonFrame.h"
|
2004-08-01 03:15:21 +04:00
|
|
|
#include "nsPresContext.h"
|
1999-06-15 08:02:43 +04:00
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "nsCOMPtr.h"
|
2014-02-28 03:04:46 +04:00
|
|
|
#include "nsNameSpaceManager.h"
|
2006-12-26 20:47:52 +03:00
|
|
|
#include "nsGkAtoms.h"
|
1999-06-15 08:02:43 +04:00
|
|
|
#include "nsSliderFrame.h"
|
2011-07-11 18:05:09 +04:00
|
|
|
#include "nsScrollbarFrame.h"
|
2000-06-07 03:13:05 +04:00
|
|
|
#include "nsIScrollbarMediator.h"
|
1999-08-20 02:16:23 +04:00
|
|
|
#include "nsRepeatService.h"
|
2011-09-09 06:27:13 +04:00
|
|
|
#include "mozilla/LookAndFeel.h"
|
2013-09-25 15:21:18 +04:00
|
|
|
#include "mozilla/MouseEvents.h"
|
2011-09-09 06:27:13 +04:00
|
|
|
|
|
|
|
using namespace mozilla;
|
1999-06-15 08:02:43 +04:00
|
|
|
|
|
|
|
//
|
|
|
|
// NS_NewToolbarFrame
|
|
|
|
//
|
2005-10-27 01:46:39 +04:00
|
|
|
// Creates a new Toolbar frame and returns it
|
1999-06-15 08:02:43 +04:00
|
|
|
//
|
2005-10-27 01:46:39 +04:00
|
|
|
nsIFrame*
|
2006-03-27 01:30:36 +04:00
|
|
|
NS_NewScrollbarButtonFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
|
1999-06-15 08:02:43 +04:00
|
|
|
{
|
2015-01-06 12:27:56 +03:00
|
|
|
return new (aPresShell) nsScrollbarButtonFrame(aContext);
|
2009-09-12 20:49:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMPL_FRAMEARENA_HELPERS(nsScrollbarButtonFrame)
|
1999-06-15 08:02:43 +04:00
|
|
|
|
2014-02-18 11:47:48 +04:00
|
|
|
nsresult
|
2013-10-02 07:46:03 +04:00
|
|
|
nsScrollbarButtonFrame::HandleEvent(nsPresContext* aPresContext,
|
|
|
|
WidgetGUIEvent* aEvent,
|
2005-04-29 03:48:28 +04:00
|
|
|
nsEventStatus* aEventStatus)
|
1999-06-15 08:02:43 +04:00
|
|
|
{
|
2009-02-27 13:48:25 +03:00
|
|
|
NS_ENSURE_ARG_POINTER(aEventStatus);
|
2010-04-12 17:59:16 +04:00
|
|
|
|
|
|
|
// 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) {
|
2009-02-27 13:48:25 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-11-18 03:41:35 +04:00
|
|
|
switch (aEvent->message) {
|
|
|
|
case NS_MOUSE_BUTTON_DOWN:
|
|
|
|
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 NS_MOUSE_BUTTON_UP:
|
|
|
|
HandleRelease(aPresContext, aEvent, aEventStatus);
|
|
|
|
break;
|
|
|
|
case NS_MOUSE_EXIT_SYNTH:
|
|
|
|
mCursorOnThis = false;
|
|
|
|
break;
|
|
|
|
case NS_MOUSE_MOVE: {
|
|
|
|
nsPoint cursor =
|
|
|
|
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
|
|
|
|
nsRect frameRect(nsPoint(0, 0), GetSize());
|
|
|
|
mCursorOnThis = frameRect.Contains(cursor);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nsButtonBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
1999-06-15 08:02:43 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2013-10-02 07:46:03 +04:00
|
|
|
nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext,
|
|
|
|
WidgetGUIEvent* aEvent,
|
|
|
|
nsEventStatus* aEventStatus)
|
1999-08-20 02:16:23 +04:00
|
|
|
{
|
2006-07-18 21:01:40 +04:00
|
|
|
// Get the desired action for the scrollbar button.
|
2011-09-09 06:27:13 +04:00
|
|
|
LookAndFeel::IntID tmpAction;
|
2013-10-22 12:55:20 +04:00
|
|
|
uint16_t button = aEvent->AsMouseEvent()->button;
|
2013-10-02 10:38:27 +04:00
|
|
|
if (button == WidgetMouseEvent::eLeftButton) {
|
2011-11-18 03:41:35 +04:00
|
|
|
tmpAction = LookAndFeel::eIntID_ScrollButtonLeftMouseButtonAction;
|
2013-10-02 10:38:27 +04:00
|
|
|
} else if (button == WidgetMouseEvent::eMiddleButton) {
|
2011-11-18 03:41:35 +04:00
|
|
|
tmpAction = LookAndFeel::eIntID_ScrollButtonMiddleMouseButtonAction;
|
2013-10-02 10:38:27 +04:00
|
|
|
} else if (button == WidgetMouseEvent::eRightButton) {
|
2011-11-18 03:41:35 +04:00
|
|
|
tmpAction = LookAndFeel::eIntID_ScrollButtonRightMouseButtonAction;
|
2006-11-17 00:35:39 +03:00
|
|
|
} else {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2006-11-17 00:35:39 +03:00
|
|
|
}
|
2006-07-18 21:01:40 +04:00
|
|
|
|
|
|
|
// Get the button action metric from the pres. shell.
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t pressedButtonAction;
|
2011-09-09 06:27:13 +04:00
|
|
|
if (NS_FAILED(LookAndFeel::GetInt(tmpAction, &pressedButtonAction))) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2011-09-09 06:27:13 +04:00
|
|
|
}
|
2006-07-18 21:01:40 +04:00
|
|
|
|
|
|
|
// get the scrollbar control
|
|
|
|
nsIFrame* scrollbar;
|
2006-12-26 20:47:52 +03:00
|
|
|
GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar);
|
2006-07-18 21:01:40 +04:00
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
if (scrollbar == nullptr)
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2014-02-05 05:30:34 +04:00
|
|
|
|
2006-12-26 20:47:52 +03:00
|
|
|
static nsIContent::AttrValuesArray strings[] = { &nsGkAtoms::increment,
|
|
|
|
&nsGkAtoms::decrement,
|
2012-07-30 18:20:58 +04:00
|
|
|
nullptr };
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t index = mContent->FindAttrValueIn(kNameSpaceID_None,
|
2006-12-26 20:47:52 +03:00
|
|
|
nsGkAtoms::type,
|
2006-07-18 21:01:40 +04:00
|
|
|
strings, eCaseMatters);
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t direction;
|
2014-02-05 05:30:34 +04:00
|
|
|
if (index == 0)
|
2006-07-18 21:01:40 +04:00
|
|
|
direction = 1;
|
|
|
|
else if (index == 1)
|
|
|
|
direction = -1;
|
|
|
|
else
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2006-07-18 21:01:40 +04:00
|
|
|
|
2014-02-05 05:30:34 +04:00
|
|
|
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) {
|
2006-07-18 21:01:40 +04:00
|
|
|
case 0:
|
2014-02-05 05:30:34 +04:00
|
|
|
sb->SetIncrementToLine(direction);
|
|
|
|
if (m) {
|
2015-03-25 21:40:31 +03:00
|
|
|
m->ScrollByLine(sb, direction, nsIScrollbarMediator::ENABLE_SNAP);
|
2014-02-05 05:30:34 +04:00
|
|
|
}
|
2006-07-18 21:01:40 +04:00
|
|
|
break;
|
|
|
|
case 1:
|
2014-02-05 05:30:34 +04:00
|
|
|
sb->SetIncrementToPage(direction);
|
|
|
|
if (m) {
|
2015-03-25 21:40:31 +03:00
|
|
|
m->ScrollByPage(sb, direction, nsIScrollbarMediator::ENABLE_SNAP);
|
2014-02-05 05:30:34 +04:00
|
|
|
}
|
2006-07-18 21:01:40 +04:00
|
|
|
break;
|
|
|
|
case 2:
|
2014-02-05 05:30:34 +04:00
|
|
|
sb->SetIncrementToWhole(direction);
|
|
|
|
if (m) {
|
2015-03-25 21:40:31 +03:00
|
|
|
m->ScrollByWhole(sb, direction, nsIScrollbarMediator::ENABLE_SNAP);
|
2014-02-05 05:30:34 +04:00
|
|
|
}
|
2006-07-18 21:01:40 +04:00
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
default:
|
|
|
|
// We were told to ignore this click, or someone assigned a non-standard
|
|
|
|
// value to the button's action.
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2014-02-05 05:30:34 +04:00
|
|
|
}
|
|
|
|
if (!weakFrame.IsAlive()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!m) {
|
|
|
|
sb->MoveToNewPosition();
|
|
|
|
if (!weakFrame.IsAlive()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2006-07-18 21:01:40 +04:00
|
|
|
}
|
2014-02-05 05:30:34 +04:00
|
|
|
if (repeat) {
|
2008-02-15 05:04:34 +03:00
|
|
|
StartRepeat();
|
2014-02-05 05:30:34 +04:00
|
|
|
}
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
1999-08-20 02:16:23 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2013-10-02 07:46:03 +04:00
|
|
|
nsScrollbarButtonFrame::HandleRelease(nsPresContext* aPresContext,
|
|
|
|
WidgetGUIEvent* aEvent,
|
|
|
|
nsEventStatus* aEventStatus)
|
1999-08-20 02:16:23 +04:00
|
|
|
{
|
2012-07-30 18:20:58 +04:00
|
|
|
nsIPresShell::SetCapturingContent(nullptr, 0);
|
2011-08-03 07:39:02 +04:00
|
|
|
// we're not active anymore
|
2011-10-17 18:59:28 +04:00
|
|
|
mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::active, true);
|
2008-02-15 05:04:34 +03:00
|
|
|
StopRepeat();
|
2015-03-25 21:40:31 +03:00
|
|
|
nsIFrame* scrollbar;
|
|
|
|
GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar);
|
|
|
|
nsScrollbarFrame* sb = do_QueryFrame(scrollbar);
|
|
|
|
if (sb) {
|
|
|
|
nsIScrollbarMediator* m = sb->GetScrollbarMediator();
|
|
|
|
if (m) {
|
|
|
|
m->ScrollbarReleased(sb);
|
|
|
|
}
|
|
|
|
}
|
2011-08-03 07:39:02 +04:00
|
|
|
return NS_OK;
|
1999-08-20 02:16:23 +04:00
|
|
|
}
|
|
|
|
|
2008-02-15 05:04:34 +03:00
|
|
|
void nsScrollbarButtonFrame::Notify()
|
1999-08-20 02:16:23 +04:00
|
|
|
{
|
2011-11-18 03:41:35 +04:00
|
|
|
if (mCursorOnThis ||
|
|
|
|
LookAndFeel::GetInt(
|
|
|
|
LookAndFeel::eIntID_ScrollbarButtonAutoRepeatBehavior, 0)) {
|
2014-02-05 05:30:34 +04:00
|
|
|
// 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();
|
|
|
|
}
|
|
|
|
}
|
2011-11-18 03:41:35 +04:00
|
|
|
}
|
1999-08-20 02:16:23 +04:00
|
|
|
}
|
|
|
|
|
1999-06-15 08:02:43 +04:00
|
|
|
void
|
2013-10-02 07:46:03 +04:00
|
|
|
nsScrollbarButtonFrame::MouseClicked(nsPresContext* aPresContext,
|
|
|
|
WidgetGUIEvent* aEvent)
|
1999-08-20 02:16:23 +04:00
|
|
|
{
|
2000-08-25 01:28:22 +04:00
|
|
|
nsButtonBoxFrame::MouseClicked(aPresContext, aEvent);
|
1) implememted box reflow coelescing.
2) implemented gfx scrollbars for list boxes
3) fixed progess meter to be an animated gif
4) fixed bugs 23521, 24721, 19114, 20546, 24385, 24457, 23156, 20226, 22543
-r hyatt, troy, rod
2000-02-10 01:02:40 +03:00
|
|
|
//MouseClicked();
|
1999-08-20 02:16:23 +04:00
|
|
|
}
|
|
|
|
|
1999-06-15 08:02:43 +04:00
|
|
|
nsresult
|
2004-08-01 03:15:21 +04:00
|
|
|
nsScrollbarButtonFrame::GetChildWithTag(nsPresContext* aPresContext,
|
2003-11-19 04:20:56 +03:00
|
|
|
nsIAtom* atom, nsIFrame* start,
|
|
|
|
nsIFrame*& result)
|
1999-06-15 08:02:43 +04:00
|
|
|
{
|
|
|
|
// recursively search our children
|
2011-08-25 00:54:30 +04:00
|
|
|
nsIFrame* childFrame = start->GetFirstPrincipalChild();
|
2012-07-30 18:20:58 +04:00
|
|
|
while (nullptr != childFrame)
|
1999-06-15 08:02:43 +04:00
|
|
|
{
|
|
|
|
// get the content node
|
2003-08-04 16:39:51 +04:00
|
|
|
nsIContent* child = childFrame->GetContent();
|
1999-06-15 08:02:43 +04:00
|
|
|
|
|
|
|
if (child) {
|
|
|
|
// see if it is the child
|
2015-03-03 14:09:00 +03:00
|
|
|
if (child->IsXULElement(atom))
|
1999-06-15 08:02:43 +04:00
|
|
|
{
|
|
|
|
result = childFrame;
|
2003-11-19 04:20:56 +03:00
|
|
|
|
1999-06-15 08:02:43 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// recursive search the child
|
2000-01-22 04:16:50 +03:00
|
|
|
GetChildWithTag(aPresContext, atom, childFrame, result);
|
2012-07-30 18:20:58 +04:00
|
|
|
if (result != nullptr)
|
1999-06-15 08:02:43 +04:00
|
|
|
return NS_OK;
|
|
|
|
|
2003-08-04 16:39:51 +04:00
|
|
|
childFrame = childFrame->GetNextSibling();
|
1999-06-15 08:02:43 +04:00
|
|
|
}
|
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
result = nullptr;
|
1999-06-15 08:02:43 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2003-11-19 04:20:56 +03:00
|
|
|
nsScrollbarButtonFrame::GetParentWithTag(nsIAtom* toFind, nsIFrame* start,
|
|
|
|
nsIFrame*& result)
|
1999-06-15 08:02:43 +04:00
|
|
|
{
|
2003-08-04 16:39:51 +04:00
|
|
|
while (start)
|
1999-06-15 08:02:43 +04:00
|
|
|
{
|
2003-08-04 16:39:51 +04:00
|
|
|
start = start->GetParent();
|
1999-06-15 08:02:43 +04:00
|
|
|
|
|
|
|
if (start) {
|
|
|
|
// get the content node
|
2003-08-04 16:39:51 +04:00
|
|
|
nsIContent* child = start->GetContent();
|
1999-06-15 08:02:43 +04:00
|
|
|
|
2015-03-03 14:09:00 +03:00
|
|
|
if (child && child->IsXULElement(toFind)) {
|
2003-11-19 04:20:56 +03:00
|
|
|
result = start;
|
|
|
|
return NS_OK;
|
1999-06-15 08:02:43 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
result = nullptr;
|
1999-06-15 08:02:43 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2006-04-10 04:16:29 +04:00
|
|
|
void
|
2009-12-24 08:21:15 +03:00
|
|
|
nsScrollbarButtonFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
1999-08-29 14:51:15 +04:00
|
|
|
{
|
|
|
|
// 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.
|
2008-02-15 05:04:34 +03:00
|
|
|
StopRepeat();
|
2009-12-24 08:21:15 +03:00
|
|
|
nsButtonBoxFrame::DestroyFrom(aDestructRoot);
|
1999-08-29 14:51:15 +04:00
|
|
|
}
|