Fix second events' detection bugs.
This commit is contained in:
parent
4b63b35d07
commit
c7cd5bad91
|
@ -1,3 +1,5 @@
|
|||
#include <iostream>
|
||||
|
||||
#include <sftk.hpp>
|
||||
|
||||
int main()
|
||||
|
@ -5,5 +7,13 @@ int main()
|
|||
auto &window = sftk::Window::create(800, 600, L"demo1");
|
||||
auto container = sftk::Container::create(vec(100.f, 100.f), vec(400.f, 400.f), window.getRoot());
|
||||
container->setBackgroudColor(sf::Color::White);
|
||||
container->registerEvent(
|
||||
sftk::EventType::MouseDragged,
|
||||
std::function(
|
||||
[](sf::Vector2f start, sf::Vector2f now, sf::Mouse::Button button)
|
||||
{ std::cout << "(" << start.x << "," << start.y << ")"
|
||||
<< "->(" << now.x << "," << now.y << ")"
|
||||
<< "|" << button
|
||||
<< std::endl; }));
|
||||
window.exec();
|
||||
}
|
||||
|
|
|
@ -96,7 +96,9 @@ namespace sftk
|
|||
std::function<void(wchar_t)> textInputed;
|
||||
|
||||
private: // Second events asistant vars
|
||||
// When the values is not -1, mouse had pressed.
|
||||
int64_t lastMousePressTime[sf::Mouse::Button::ButtonCount];
|
||||
// When the values is not (-1, -1), mouse had pressed.
|
||||
sf::Vector2f lastMousePressPos[sf::Mouse::Button::ButtonCount];
|
||||
|
||||
bool focused;
|
||||
|
@ -116,6 +118,13 @@ namespace sftk
|
|||
NotAWindowObj(Container *container);
|
||||
const char *what() const noexcept override;
|
||||
};
|
||||
|
||||
class HandlerNotMatched : public SFTKException<Container>
|
||||
{
|
||||
public:
|
||||
HandlerNotMatched(Container *container);
|
||||
const char *what() const noexcept override;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <gtypes.hpp>
|
||||
#include <window.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
|
||||
using namespace sftk;
|
||||
|
@ -33,6 +34,8 @@ Container::Container(pContainer parent) : parent(nullptr)
|
|||
this->parent = parent;
|
||||
}
|
||||
this->parent->childs.push_back(pContainer(this));
|
||||
for (auto &p : lastMousePressPos)
|
||||
p = vec(-1.f, -1.f);
|
||||
}
|
||||
|
||||
Container::Container(sf::Vector2f pos, sf::Vector2f size, pContainer parent)
|
||||
|
@ -57,6 +60,8 @@ Container::Container(sf::Vector2f pos, sf::Vector2f size, pContainer parent)
|
|||
view.setViewport(vec(
|
||||
(parent->basepos.x + pos.x) / rootsize.x, (parent->basepos.y + pos.y) / rootsize.y,
|
||||
size.x / rootsize.x, size.y / rootsize.y));
|
||||
for (auto &p : lastMousePressPos)
|
||||
p = vec(-1.f, -1.f);
|
||||
}
|
||||
|
||||
Container::Container(sf::Vector2f pos, sf::Vector2f size, bool root)
|
||||
|
@ -68,6 +73,8 @@ Container::Container(sf::Vector2f pos, sf::Vector2f size, bool root)
|
|||
backgroudColor(sf::Color::Black)
|
||||
{
|
||||
view.setViewport(vec(0.f, 0.f, 1.f, 1.f));
|
||||
for (auto &p : lastMousePressPos)
|
||||
p = vec(-1.f, -1.f);
|
||||
}
|
||||
|
||||
pContainer Container::create(pContainer parent)
|
||||
|
@ -147,13 +154,15 @@ void Container::update() const
|
|||
if (isRoot())
|
||||
{
|
||||
window.clear(backgroudColor);
|
||||
return;
|
||||
}
|
||||
window.setView(view);
|
||||
sf::RectangleShape bg(vec(size.x, size.y));
|
||||
bg.setPosition(vec(0.f, 0.f));
|
||||
bg.setFillColor(backgroudColor);
|
||||
window.draw(bg);
|
||||
else
|
||||
{
|
||||
window.setView(view);
|
||||
sf::RectangleShape bg(vec(size.x, size.y));
|
||||
bg.setPosition(vec(0.f, 0.f));
|
||||
bg.setFillColor(backgroudColor);
|
||||
window.draw(bg);
|
||||
}
|
||||
for (auto c : childs)
|
||||
{
|
||||
c->update();
|
||||
|
@ -165,7 +174,7 @@ void Container::registerEvent(EventType type, std::function<void()> handler)
|
|||
{
|
||||
if (type != EventType::Closed)
|
||||
return;
|
||||
closed = handler;
|
||||
closed = std::move(handler);
|
||||
}
|
||||
|
||||
template <>
|
||||
|
@ -174,17 +183,19 @@ void Container::registerEvent(EventType type, std::function<void(sf::Vector2f)>
|
|||
switch (type)
|
||||
{
|
||||
case EventType::Resized:
|
||||
resized = handler;
|
||||
resized = std::move(handler);
|
||||
break;
|
||||
case EventType::MouseEntered:
|
||||
mouseEntered = handler;
|
||||
mouseEntered = std::move(handler);
|
||||
break;
|
||||
case EventType::MouseLeft:
|
||||
mouseLeft = handler;
|
||||
mouseLeft = std::move(handler);
|
||||
break;
|
||||
case EventType::MouseMoved:
|
||||
mouseMoved = handler;
|
||||
mouseMoved = std::move(handler);
|
||||
break;
|
||||
default:
|
||||
throw new HandlerNotMatched(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,14 +205,16 @@ void Container::registerEvent(EventType type, std::function<void(sf::Vector2f, s
|
|||
switch (type)
|
||||
{
|
||||
case EventType::MousePressed:
|
||||
mousePressed = handler;
|
||||
mousePressed = std::move(handler);
|
||||
break;
|
||||
case EventType::MouseReleased:
|
||||
mouseReleased = handler;
|
||||
mouseReleased = std::move(handler);
|
||||
break;
|
||||
case EventType::MouseClicked:
|
||||
mouseClicked = handler;
|
||||
mouseClicked = std::move(handler);
|
||||
break;
|
||||
default:
|
||||
throw new HandlerNotMatched(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,7 +223,7 @@ void Container::registerEvent(EventType type, std::function<void(sf::Vector2f, s
|
|||
{
|
||||
if (type != EventType::MouseDragged)
|
||||
return;
|
||||
mouseDragged = handler;
|
||||
mouseDragged = std::move(handler);
|
||||
}
|
||||
|
||||
template <>
|
||||
|
@ -218,7 +231,7 @@ void Container::registerEvent(EventType type, std::function<void(float)> handler
|
|||
{
|
||||
if (type != EventType::MouseScrolled)
|
||||
return;
|
||||
mouseScrolled = handler;
|
||||
mouseScrolled = std::move(handler);
|
||||
}
|
||||
|
||||
template <>
|
||||
|
@ -226,7 +239,7 @@ void Container::registerEvent(EventType type, std::function<void(wchar_t)> handl
|
|||
{
|
||||
if (type != EventType::TextInputed)
|
||||
return;
|
||||
textInputed = handler;
|
||||
textInputed = std::move(handler);
|
||||
}
|
||||
|
||||
void Container::dispatchEvent(sf::Event &event)
|
||||
|
@ -317,6 +330,8 @@ bool Container::dispatchEvent(Event &event)
|
|||
_MouseEnteredLeftMoved mmov;
|
||||
_MouseDragged mdra;
|
||||
|
||||
time_t now;
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case EventType::Closed:
|
||||
|
@ -346,31 +361,39 @@ bool Container::dispatchEvent(Event &event)
|
|||
break;
|
||||
case EventType::MousePressed:
|
||||
mpr = event.data.mousePressed;
|
||||
if (mousePressed && getGlobalBouds().contains(mpr.pos))
|
||||
if (mouseLocated)
|
||||
{
|
||||
handler_effective = true;
|
||||
mousePressed(mpr.pos - basepos - pos, mpr.button);
|
||||
if (mousePressed)
|
||||
{
|
||||
handler_effective = true;
|
||||
mousePressed(mpr.pos - basepos - pos, mpr.button);
|
||||
}
|
||||
lastMousePressTime[mpr.button] = currentTime();
|
||||
lastMousePressPos[mpr.button] = mpr.pos;
|
||||
}
|
||||
lastMousePressTime[mpr.button] = currentTime();
|
||||
break;
|
||||
case EventType::MouseReleased:
|
||||
mrel = event.data.mouseReleased;
|
||||
lastMousePressTime[mrel.button] = -1;
|
||||
lastMousePressPos[mrel.button] = vec(-1.f, -1.f);
|
||||
if (mouseReleased && getGlobalBouds().contains(mrel.pos))
|
||||
if (mouseLocated)
|
||||
{
|
||||
handler_effective = true;
|
||||
mouseReleased(mrel.pos - basepos - pos, mrel.button);
|
||||
}
|
||||
if (isRoot() &&
|
||||
lastMousePressTime[mrel.button] >= 0 &&
|
||||
lastMousePressTime[mrel.button] < maxClickTime)
|
||||
{
|
||||
auto tmp = Event{
|
||||
.type = EventType::MouseClicked,
|
||||
.data = EventData{
|
||||
.mouseClicked = mrel}};
|
||||
dispatchEvent(tmp);
|
||||
if (mouseReleased)
|
||||
{
|
||||
handler_effective = true;
|
||||
mouseReleased(mrel.pos - basepos - pos, mrel.button);
|
||||
}
|
||||
now = currentTime();
|
||||
if (isRoot() &&
|
||||
now - lastMousePressTime[mrel.button] >= 0 &&
|
||||
now - lastMousePressTime[mrel.button] < maxClickTime)
|
||||
{
|
||||
auto tmp = Event{
|
||||
.type = EventType::MouseClicked,
|
||||
.data = EventData{
|
||||
.mouseClicked = mrel}};
|
||||
dispatchEvent(tmp);
|
||||
}
|
||||
lastMousePressTime[mrel.button] = -1;
|
||||
lastMousePressPos[mrel.button] = vec(-1.f, -1.f);
|
||||
}
|
||||
break;
|
||||
case EventType::MouseClicked:
|
||||
|
@ -390,6 +413,7 @@ bool Container::dispatchEvent(Event &event)
|
|||
}
|
||||
break;
|
||||
case EventType::MouseEntered:
|
||||
spread = false;
|
||||
mouseLocated = true;
|
||||
if (mouseEntered)
|
||||
{
|
||||
|
@ -398,6 +422,7 @@ bool Container::dispatchEvent(Event &event)
|
|||
}
|
||||
break;
|
||||
case EventType::MouseLeft:
|
||||
spread = false;
|
||||
mouseLocated = false;
|
||||
if (mouseLeft)
|
||||
{
|
||||
|
@ -407,33 +432,38 @@ bool Container::dispatchEvent(Event &event)
|
|||
break;
|
||||
case EventType::MouseMoved:
|
||||
mmov = event.data.mouseMoved;
|
||||
if (getGlobalBouds().contains(mmov.pos))
|
||||
if (getGlobalBouds().contains(mmov.pos) && mouseMoved)
|
||||
{
|
||||
if (mouseMoved)
|
||||
{
|
||||
handler_effective = true;
|
||||
mouseMoved(mmov.pos - basepos - pos);
|
||||
}
|
||||
if (isRoot() && !mouseLocated)
|
||||
handler_effective = true;
|
||||
mouseMoved(mmov.pos - basepos - pos);
|
||||
}
|
||||
// Enter and left
|
||||
if (!isRoot() && getGlobalBouds().contains(mmov.pos))
|
||||
{
|
||||
if (!mouseLocated)
|
||||
{
|
||||
auto tmp = Event{
|
||||
.type = EventType::MouseEntered,
|
||||
.data = event.data};
|
||||
.data = {
|
||||
.mouseEntered = _MouseEnteredLeftMoved{
|
||||
.pos = mmov.pos}}};
|
||||
dispatchEvent(tmp);
|
||||
}
|
||||
}
|
||||
else if (isRoot() && mouseLocated)
|
||||
else if (!isRoot() && mouseLocated)
|
||||
{
|
||||
auto tmp = Event{
|
||||
.type = EventType::MouseLeft,
|
||||
.data = event.data};
|
||||
.data = {
|
||||
.mouseEntered = _MouseEnteredLeftMoved{
|
||||
.pos = mmov.pos}}};
|
||||
dispatchEvent(tmp);
|
||||
}
|
||||
if (!isRoot())
|
||||
break;
|
||||
for (auto i = 0; i < sf::Mouse::Button::ButtonCount; i++)
|
||||
{
|
||||
if (lastMousePressPos[i] == vec(-1.f, -1.f))
|
||||
if (lastMousePressPos[i] == vec(-1.f, -1.f) || lastMousePressTime[i] == -1)
|
||||
continue;
|
||||
auto tmp = Event{
|
||||
.type = EventType::MouseDragged,
|
||||
|
@ -447,10 +477,10 @@ bool Container::dispatchEvent(Event &event)
|
|||
break;
|
||||
case EventType::MouseDragged:
|
||||
mdra = event.data.mouseDragged;
|
||||
if (mouseDragged)
|
||||
if (mouseDragged && getGlobalBouds().contains(mdra.start))
|
||||
{
|
||||
handler_effective = true;
|
||||
mouseDragged(mdra.start, mdra.now, mdra.button);
|
||||
mouseDragged(mdra.start - basepos - pos, mdra.now - basepos - pos, mdra.button);
|
||||
}
|
||||
break;
|
||||
case EventType::MouseScrolled:
|
||||
|
@ -472,6 +502,9 @@ bool Container::dispatchEvent(Event &event)
|
|||
if (!spread)
|
||||
return handler_effective;
|
||||
|
||||
if (!broadcast && handler_effective)
|
||||
return true;
|
||||
|
||||
bool child_handled;
|
||||
bool handler_handled = false;
|
||||
for (auto container : childs)
|
||||
|
@ -527,3 +560,13 @@ const char *Container::NotAWindowObj::what() const noexcept
|
|||
SFTKException::formatAddress(msg, sizeof(msg));
|
||||
return msg;
|
||||
}
|
||||
|
||||
Container::HandlerNotMatched::HandlerNotMatched(Container *container)
|
||||
: SFTKException(container) {}
|
||||
|
||||
const char *Container::HandlerNotMatched::what() const noexcept
|
||||
{
|
||||
static char msg[] = "sftk::Container 0x********_********: When calling Container::registerEvent(), passed a closure with wrong arguments.";
|
||||
SFTKException::formatAddress(msg, sizeof(msg));
|
||||
return msg;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue