ComponentDragger problem


#1

I want to drag a small circle(a knob) inside a large circle. It's fine if i start the drag on the small circle. I added a call to place the small circle on the position of the left click on the large circle (so that it immediatly jumps to that position) - that's fine too. But if i do the latter then the drag event will not start, i need to release the mouse and click again on the same point. The example code below:

void LargeCircleComponent::mouseDown (const MouseEvent& e)
{
    //[UserCode_mouseDown] -- Add your code here...
    if (e.eventComponent == &knob)
    {
        knobDragger.startDraggingComponent (&knob, e);
    }
    else
    {
        knob.setCentrePosition (e.x, e.y);
        knobDragger.startDraggingComponent (&knob, e);
    }
    //[/UserCode_mouseDown]
}

void LargeCircleComponent::mouseDrag (const MouseEvent& e)
{
    //[UserCode_mouseDrag] -- Add your code here...
    if (e.eventComponent == &knob)
        knobDragger.dragComponent (&knob, e, knobDraggerConstrainer);
    //[/UserCode_mouseDrag]
}

Is there a way to fix this or to get the behavior i want without setting some weird bool values around to detect this ?

I noticed that if I look at the result of the knob.isMouseOver() method it does not return TRUE after the knob jumped to a new position after a click on the larget circle, and that's not right since the mouse is over the small circle.


#2

Just disable mouse input on the small circle (setInterceptsMouseClicks(false,false)), and do it all in the big one :)


#3

If i do that, then e.eventComponent == &knob will never be true and in order to drag the smaller circle

i'd have to do bound checking (mouse position against the smaller circle bounds), and that just seems weird.

--- Edit

nevermind i got it, the solution you proposed works

knob.addMouseListener (this, false);
knob.setInterceptsMouseClicks (false, false);

void BenderMotorControlUI::mouseDown (const MouseEvent& e)
{
    //[UserCode_mouseDown] -- Add your code here...
    knob.setCentrePosition (e.x, e.y);
    knobDragger.startDraggingComponent (&knob, e);
    //[/UserCode_mouseDown]
}

void BenderMotorControlUI::mouseDrag (const MouseEvent& e)
{
    //[UserCode_mouseDrag] -- Add your code here...
    knobDragger.dragComponent (&knob, e, knobDraggerConstrainer);
    //[/UserCode_mouseDrag]
}

#4

You might want to consider checking if (!knob.contains(e.x, e.y)) before calling knob.setCentrePosition(e.x, e.y). Doing that would make a 'drag' (i.g. when grabbing the handle part directly) seem a bit more like a natural drag rather than it just snapping to the mouse position.

However, it entirely depends on the feel you're after from the control! There are plenty of controls that *should* behave just like that (snapping directly to the mouse position) - the 'correct' behaviour is whatever feels right when you use the control :) so don't take the above as anything more than a suggestion!


#5

I'll try both, it's something i'm doing as a fun project, this will control 2 motors on a robot and i'd like some sort of "linear" or "fluent" control of how it behaves.

 

Thank you for your help.