1
Graphics / [solved] Dragging with mouse
« on: April 18, 2011, 07:43:46 pm »
Awesome, thanks Laurent.
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
sf::Vector2f pos = sf::Vector2f((float)input.GetMouseX(), (float)input.GetMouseY());
_thisRect = sf::FloatRect(GetPosition().x, GetPosition().y, 100.0f, 100.0f);
if(_thisRect.Contains(pos))
class DragDropTest : public sf::Drawable
{
public:
DragDropTest()
{
_thisRect = sf::FloatRect(100.0f, 100.0f, 100.0f, 100.0f);
_rect = sf::Shape::Rectangle(_thisRect, sf::Color::Blue);
}
void Input(const sf::Input &input)
{
static bool dragging = false;
static sf::Vector2f startPos = sf::Vector2f(0.0f, 0.0f);
sf::Vector2f pos = sf::Vector2f((float)input.GetMouseX(), (float)input.GetMouseY());
if(_thisRect.Contains(pos))
{
if(input.IsMouseButtonDown(sf::Mouse::Left))
{
if(!dragging)
startPos = pos;
dragging = true;
}
else
dragging = false;
}
else
dragging = false;
if(dragging)
SetPosition(pos.x - startPos.x, pos.y - startPos.y);
}
private:
virtual void Render(sf::RenderTarget &target, sf::Renderer &renderer) const
{
target.Draw(_rect);
}
sf::Shape _rect;
sf::FloatRect _thisRect;
};
int main()
{
sf::RenderWindow app(sf::VideoMode(800, 600), "SFML Test");
app.SetFramerateLimit(30);
DragDropTest test;
sf::Event evt;
while(app.IsOpened())
{
while(app.PollEvent(evt))
if(evt.Type == evt.Closed)
app.Close();
app.Clear();
test.Input(app.GetInput());
app.Draw(test);
app.Display();
}
}
class Button : public sf::Drawable, public toj::IInput // just know that an IInput will receive input notifications
{
public:
Button(const std::wstring &label = L"", sf::Vector2f pos = sf::Vector2f(0, 0),
sf::Vector2f size = sf::Vector2f(0, 0));
void SetSize(const sf::Vector2f &size) { _size = size; }
void SetLabel(const std::wstring &label) { _label.SetString(label); }
void SetOnClick(Functor &onClick) { _onClick = &onClick; }
void SetOnClickStop(Functor &onClickStop) { _onClickStop = &onClickStop; }
void SetOnHover(Functor &onHover) { _onHover = &onHover; }
void SetOnHoverExit(Functor &onHoverExit) { _onHoverExit = &onHoverExit; }
void ResetPosition() { SetPosition(_startPos); }
private:
virtual void Render(sf::RenderTarget &target, sf::Renderer &renderer) const;
virtual void Input(const sf::Input &input);
Functor *_onClick;
Functor *_onClickStop;
Functor *_onHover;
Functor *_onHoverExit;
sf::Text _label;
sf::Vector2f _size;
sf::Vector2f _startPos;
bool _mouseHovering;
bool _mouseClicking;
};
/* virtual */ void Button::Input(const sf::Input &input)
{
sf::RenderWindow &window = App::GetInst().GetWindow();
sf::Vector2f mouseCoords = TransformToLocal(window.ConvertCoords(input.GetMouseX(), input.GetMouseY())); // Is there a better way to get mouse coords in...scene view?
mouseCoords.x -= GetPosition().x;
mouseCoords.y -= GetPosition().y;
sf::FloatRect thisRect(0, 0, _size.x, _size.y);
if(thisRect.Contains(mouseCoords.x, mouseCoords.y))
{
if(input.IsMouseButtonDown(sf::Mouse::Left))
{
if(_onClick)
(*_onClick)();
_mouseClicking = true;
}
else
{
if(_onClickStop && _mouseClicking)
(*_onClickStop)();
if(_onHover && !_mouseHovering)
(*_onHover)();
_mouseClicking = false;
}
_mouseHovering = true;
}
else
{
if(_onClickStop && _mouseClicking)
(*_onClickStop)();
if(_onHoverExit && _mouseHovering)
(*_onHoverExit)();
_mouseHovering = false;
_mouseClicking = false;
}
}
class HUD : public sf::Drawable, public toj::IInputObjectParent, public toj::IInput
{
class ButtonClickHandler : public toj::Functor // Click handler will call StartDrag with a button reference
class ButtonClickStopHandler : public toj::Functor // Click stop handler will call EndDrag
public:
toj::Button test;
HUD();
private:
virtual void Render(sf::RenderTarget &target, sf::Renderer &renderer) const;
virtual std::vector<toj::IInput*> GetInputObjects();
virtual void Input(const sf::Input &input);
void StartDrag(toj::Button &btn) { _dragged = &btn; }
void EndDrag();
toj::Button *_dragged;
bool _isDragging;
};
HUD::HUD() : _onClickTest(this, test), _onClickStop(this),
_dragged(NULL), _isDragging(false),
test(L"dzsd", sf::Vector2f(50.0f, 250.0f), sf::Vector2f(100.0f, 100.0f)) // I don't understand positioning...this appears perfectly flush with...
{
_rect = sf::Shape::Rectangle(0.0f, 500.0f, 800.0f, 600.0f, sf::Color(190, 190, 190)); // ...this, but there's a 250px difference in the y-val
test.SetOnClick(_onClickTest);
test.SetOnClickStop(_onClickStop);
}
void HUD::EndDrag()
{
if(_dragged)
{
_dragged->ResetPosition();
_dragged = NULL;
}
_isDragging = false;
}
/* virtual */ void HUD::Render(sf::RenderTarget &target, sf::Renderer &renderer) const
{
target.Draw(_rect);
target.Draw(test);
}
/* virtual */ std::vector<IInput*> HUD::GetInputObjects()
{
std::vector<IInput*> objects;
objects.push_back(&test); // The button gets input to determine what the mouse is doing to it (i.e. clicking, hovering)
objects.push_back(this); // HUD gets input to manipulate button based on whether or not it's being dragged (input code in 1st post)
return objects;
}
/* virtual */ void HUD::Input(const sf::Input &input)
{
static sf::Vector2f startMousePos = sf::Vector2f(0.0f, 0.0f);
if(_dragged)
{
if(!_isDragging)
{
startMousePos = App::GetInst().GetWindow().ConvertCoords(
input.GetMouseX(), input.GetMouseY());
startMousePos -= _dragged->GetPosition();
_isDragging = true;
}
sf::Vector2f curMousePos = App::GetInst().GetWindow().ConvertCoords(
input.GetMouseX(), input.GetMouseY());
_dragged->SetPosition(curMousePos - startMousePos);
}
}