Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
nsresult
nsSliderFrame::MouseDown(nsIDOMEvent* aMouseEvent)
{
#ifdef DEBUG_SLIDER
  printf("Begin dragging\n");
#endif

  if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
                            nsGkAtoms::_true, eCaseMatters))
    return NS_OK;

  nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(aMouseEvent));
  PRUint16 button = 0;
  mouseEvent->GetButton(&button);
  if (!(button == 0 || (button == 1 && gMiddlePref)))
    return NS_OK;

  PRBool isHorizontal = IsHorizontal();

  PRBool scrollToClick = PR_FALSE;
#ifndef XP_MACOSX
  // On Mac there's no scroll-to-here when clicking the thumb
  mouseEvent->GetShiftKey(&scrollToClick);
  if (button != 0) {
    scrollToClick = PR_TRUE;
  }
#endif

  nsPoint pt =  nsLayoutUtils::GetDOMEventCoordinatesRelativeTo(mouseEvent,
                                                                this);
  nscoord pos = isHorizontal ? pt.x : pt.y;

  // If shift click or middle button, first
  // place the middle of the slider thumb under the click
  nsCOMPtr<nsIContent> scrollbar;
  nscoord newpos = pos;
  if (scrollToClick) {
    // 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;

    newpos -= (thumbLength/2);

    nsIBox* scrollbarBox = GetScrollbar();
    scrollbar = GetContentOfBox(scrollbarBox);
  }

  DragThumb(PR_TRUE);

  if (scrollToClick) {
    // should aMaySnap be PR_TRUE here?
    SetCurrentThumbPosition(scrollbar, newpos, PR_FALSE, PR_FALSE, PR_FALSE);
  }

  nsIFrame* thumbFrame = mFrames.FirstChild();
  if (!thumbFrame) {
    return NS_OK;
  }

  if (isHorizontal)
    mThumbStart = thumbFrame->GetPosition().x;
  else
    mThumbStart = thumbFrame->GetPosition().y;

  mDragStart = pos - mThumbStart;

#ifdef DEBUG_SLIDER
  printf("Pressed mDragStart=%d\n",mDragStart);
#endif

  return NS_OK;
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
/// @brief Updates the slider when it is the widget of choice
/// @param fCursorX Cursor x coordinate, in [0,1]
/// @param fCursorY Cursor y coordinate, in [0,1]
/// @param bPressed If true, the cursor is pressed
/// @param pContext [in-out] User-defined context parameter
/// @return A boolean indicating whether the slider is no longer the widget of choice
/// @note Tested
bool Slider::Update (float fCursorX, float fCursorY, bool bPressed, void * pContext)
{
	/////////////////////////////////////////////////////////////////////////////////
	// If the cursor is over the slider, we check three conditions: First, we check
	// whether the cursor has just entered the slider; if so, we enter the slider. 
	// Second, we check whether the cursor just entered the thumb; if so, we enter
	// the thumb. Third, we check whether the slider and its thumb are not yet held,
	// and if there was a press.
	/////////////////////////////////////////////////////////////////////////////////
	if (mStatus[eUnder])
	{
		if (!mStatus[eIn]) Enter(pContext);
		if (!mStatus[eThumbIn] && mStatus[eThumbUnder]) EnterThumb(pContext);

		if (bPressed && !(mStatus[eHeld] || mStatus[eThumbHeld]))
		{
			///////////////////////////////////////////////////////////////////////
			// If the cursor is over the thumb, we grab the thumb; if the thumb is
			// draggable, we also catch the thumb.
			///////////////////////////////////////////////////////////////////////
			if (mStatus[eThumbUnder])
			{
				GrabThumb(pContext);

				if (!mStatus[eThumbCannotDrag]) CatchThumb(fCursorX, fCursorY, pContext);
			}

			////////////////////////////////////////////////////////////////////////////////
			// Otherwise, we grab the slider. If the slider is snappable, we fit the cursor
			// coordinates to an offset. If the offset varies from the current offset, we
			// snap the thumb to it.
			////////////////////////////////////////////////////////////////////////////////
			else
			{
				Grab(pContext);

				if (!mStatus[eThumbCannotSnap])
				{
					float fOffset = GetOffset(fCursorX, fCursorY, pContext);

					if (mOffset - fOffset != 0.0f) SnapThumb(fOffset, pContext);                    
				}
			}
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////
	// If the cursor is not over the thumb, but was during the last propagation, then we
	// leave the thumb. Likewise, we leave the slider if its confinement changes.
	////////////////////////////////////////////////////////////////////////////////////
	if (!mStatus[eThumbUnder] && mStatus[eThumbIn]) LeaveThumb(pContext);
	if (!mStatus[eUnder] && mStatus[eIn]) Leave(pContext);

	////////////////////////////////////////////////////////////////////////////////////
	// If there is no press, we check whether the thumb or slider is held. In the first
	// case, we release the thumb if it is caught, and drop the thumb; in the second, 
	// we drop the slider.
	////////////////////////////////////////////////////////////////////////////////////
	if (!bPressed)
	{
		assert(!(mStatus[eHeld] && mStatus[eThumbHeld]));

		if (mStatus[eThumbHeld])
		{
			if (mStatus[eThumbCaught]) ReleaseThumb(pContext);

			DropThumb(pContext);
		}

		else if (mStatus[eHeld]) Drop(pContext);
	}

	//////////////////////////////////////////////////////////////////////////////////////
	// If the thumb is caught, we check for movement. If there is any, we drag the thumb.
	//////////////////////////////////////////////////////////////////////////////////////
	if (mStatus[eThumbCaught])
	{
		float fOffset = GetOffset(fCursorX, fCursorY, pContext);

		if (mOffset - fOffset != 0.0f) DragThumb(fOffset, pContext);
	}

	//////////////////////////////////////////////////////////////////////////////////////
	// Finally, if the cursor is not over the slider and neither the slider nor the thumb
	// is held, the slider is no longer the widget of choice.
	//////////////////////////////////////////////////////////////////////////////////////
	return !mStatus[eUnder] && !(mStatus[eHeld] || mStatus[eThumbHeld]);
}