NS_IMETHODIMP nsSliderFrame::HandlePress(nsPresContext* aPresContext, nsGUIEvent* aEvent, nsEventStatus* aEventStatus) { #ifdef XP_MACOSX // On Mac the option key inverts the scroll-to-here preference. if (((nsMouseEvent *)aEvent)->isAlt != GetScrollToClick()) #else if (((nsMouseEvent *)aEvent)->isShift != GetScrollToClick()) #endif return NS_OK; nsIFrame* thumbFrame = mFrames.FirstChild(); if (!thumbFrame) // display:none? return NS_OK; if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled, nsGkAtoms::_true, eCaseMatters)) return NS_OK; nsRect thumbRect = thumbFrame->GetRect(); nscoord change = 1; nsPoint eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this); if (IsHorizontal() ? eventPoint.x < thumbRect.x : eventPoint.y < thumbRect.y) change = -1; mChange = change; DragThumb(PR_TRUE); mDestinationPoint = eventPoint; StartRepeat(); PageUpDown(change); return NS_OK; }
NS_IMETHODIMP nsSliderFrame::HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, nsEventStatus* aEventStatus) { NS_ENSURE_ARG_POINTER(aEventStatus); if (nsEventStatus_eConsumeNoDefault == *aEventStatus) { return NS_OK; } nsIBox* scrollbarBox = GetScrollbar(); nsCOMPtr<nsIContent> scrollbar; scrollbar = GetContentOfBox(scrollbarBox); PRBool isHorizontal = IsHorizontal(); if (isDraggingThumb()) { switch (aEvent->message) { case NS_MOUSE_MOVE: { nsPoint eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this); if (mChange) { // We're in the process of moving the thumb to the mouse, // but the mouse just moved. Make sure to update our // destination point. mDestinationPoint = eventPoint; StopRepeat(); StartRepeat(); break; } nscoord pos = isHorizontal ? eventPoint.x : eventPoint.y; nsIFrame* thumbFrame = mFrames.FirstChild(); if (!thumbFrame) { return NS_OK; } // take our current position and subtract the start location pos -= mDragStart; PRBool isMouseOutsideThumb = PR_FALSE; if (gSnapMultiplier) { nsSize thumbSize = thumbFrame->GetSize(); if (isHorizontal) { // horizontal scrollbar - check if mouse is above or below thumb // XXXbz what about looking at the .y of the thumb's rect? Is that // always zero here? if (eventPoint.y < -gSnapMultiplier * thumbSize.height || eventPoint.y > thumbSize.height + gSnapMultiplier * thumbSize.height) isMouseOutsideThumb = PR_TRUE; } else { // vertical scrollbar - check if mouse is left or right of thumb if (eventPoint.x < -gSnapMultiplier * thumbSize.width || eventPoint.x > thumbSize.width + gSnapMultiplier * thumbSize.width) isMouseOutsideThumb = PR_TRUE; } } if (isMouseOutsideThumb) { SetCurrentThumbPosition(scrollbar, mThumbStart, PR_FALSE, PR_TRUE, PR_FALSE); return NS_OK; } // set it SetCurrentThumbPosition(scrollbar, pos, PR_FALSE, PR_TRUE, PR_TRUE); // with snapping } break; case NS_MOUSE_BUTTON_UP: if (static_cast<nsMouseEvent*>(aEvent)->button == nsMouseEvent::eLeftButton || (static_cast<nsMouseEvent*>(aEvent)->button == nsMouseEvent::eMiddleButton && gMiddlePref)) { // stop capturing AddListener(); DragThumb(PR_FALSE); if (mChange) { StopRepeat(); mChange = 0; } //we MUST call nsFrame HandleEvent for mouse ups to maintain the selection state and capture state. return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } } //return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus); return NS_OK; } else if ((aEvent->message == NS_MOUSE_BUTTON_DOWN && static_cast<nsMouseEvent*>(aEvent)->button == nsMouseEvent::eLeftButton && #ifdef XP_MACOSX // On Mac the option key inverts the scroll-to-here preference. (static_cast<nsMouseEvent*>(aEvent)->isAlt != GetScrollToClick())) || #else (static_cast<nsMouseEvent*>(aEvent)->isShift != GetScrollToClick())) || #endif (gMiddlePref && aEvent->message == NS_MOUSE_BUTTON_DOWN && static_cast<nsMouseEvent*>(aEvent)->button == nsMouseEvent::eMiddleButton)) { nsPoint eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this); nscoord pos = isHorizontal ? eventPoint.x : eventPoint.y; // adjust so that the middle of the thumb is placed under the click nsIFrame* thumbFrame = mFrames.FirstChild(); if (!thumbFrame) { return NS_OK; } nsSize thumbSize = thumbFrame->GetSize(); nscoord thumbLength = isHorizontal ? thumbSize.width : thumbSize.height; // set it nsWeakFrame weakFrame(this); // should aMaySnap be PR_TRUE here? SetCurrentThumbPosition(scrollbar, pos - thumbLength/2, PR_FALSE, PR_FALSE, PR_FALSE); NS_ENSURE_TRUE(weakFrame.IsAlive(), NS_OK); DragThumb(PR_TRUE); if (isHorizontal) mThumbStart = thumbFrame->GetPosition().x; else mThumbStart = thumbFrame->GetPosition().y; mDragStart = pos - mThumbStart; } // XXX hack until handle release is actually called in nsframe. // if (aEvent->message == NS_MOUSE_EXIT_SYNTH || aEvent->message == NS_MOUSE_RIGHT_BUTTON_UP || aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) // HandleRelease(aPresContext, aEvent, aEventStatus); if (aEvent->message == NS_MOUSE_EXIT_SYNTH && mChange) HandleRelease(aPresContext, aEvent, aEventStatus); return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus); }
PRBool nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext, nsGUIEvent* aEvent, nsEventStatus* aEventStatus) { // Get the desired action for the scrollbar button. nsILookAndFeel::nsMetricID tmpAction; if (aEvent->eventStructType == NS_MOUSE_EVENT && aEvent->message == NS_MOUSE_BUTTON_DOWN) { PRUint16 button = static_cast<nsMouseEvent*>(aEvent)->button; if (button == nsMouseEvent::eLeftButton) { tmpAction = nsILookAndFeel::eMetric_ScrollButtonLeftMouseButtonAction; } else if (button == nsMouseEvent::eMiddleButton) { tmpAction = nsILookAndFeel::eMetric_ScrollButtonMiddleMouseButtonAction; } else if (button == nsMouseEvent::eRightButton) { tmpAction = nsILookAndFeel::eMetric_ScrollButtonRightMouseButtonAction; } else { return PR_FALSE; } } else { return PR_FALSE; } // Get the button action metric from the pres. shell. PRInt32 pressedButtonAction; if (NS_FAILED(aPresContext->LookAndFeel()->GetMetric(tmpAction, pressedButtonAction))) return PR_FALSE; // get the scrollbar control nsIFrame* scrollbar; GetParentWithTag(nsGkAtoms::scrollbar, this, scrollbar); if (scrollbar == nsnull) return PR_FALSE; // get the scrollbars content node nsIContent* content = scrollbar->GetContent(); static nsIContent::AttrValuesArray strings[] = { &nsGkAtoms::increment, &nsGkAtoms::decrement, nsnull }; PRInt32 index = mContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::type, strings, eCaseMatters); PRInt32 direction; if (index == 0) direction = 1; else if (index == 1) direction = -1; else return PR_FALSE; // Whether or not to repeat the click action. PRBool repeat = PR_TRUE; // Use smooth scrolling by default. PRBool smoothScroll = PR_TRUE; switch (pressedButtonAction) { case 0: mIncrement = direction * nsSliderFrame::GetIncrement(content); break; case 1: mIncrement = direction * nsSliderFrame::GetPageIncrement(content); break; case 2: if (direction == -1) mIncrement = -nsSliderFrame::GetCurrentPosition(content); else mIncrement = nsSliderFrame::GetMaxPosition(content) - nsSliderFrame::GetCurrentPosition(content); // Don't repeat or use smooth scrolling if scrolling to beginning or end // of a page. repeat = smoothScroll = PR_FALSE; break; case 3: default: // We were told to ignore this click, or someone assigned a non-standard // value to the button's action. return PR_FALSE; } // set this attribute so we can style it later nsWeakFrame weakFrame(this); mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::active, NS_LITERAL_STRING("true"), PR_TRUE); if (weakFrame.IsAlive()) { DoButtonAction(smoothScroll); } if (repeat) StartRepeat(); return PR_TRUE; }