Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Engine/system/api/iosapi.mm
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,11 @@ -(id)init {
return self;
}

- (void)setView:(UIView*)view {
view.multipleTouchEnabled = YES;
[super setView:view];
}

- (void)viewDidLoad {
[super viewDidLoad];
self.extendedLayoutIncludesOpaqueBars = YES;
Expand Down
52 changes: 39 additions & 13 deletions Engine/system/eventdispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ void EventDispatcher::dispatchMouseDown(Widget& wnd, MouseEvent &e) {
Event::MouseDown );
e1.ignore();

auto& btn = mouseUp[e.button];
std::weak_ptr<Widget::Ref> btn;
for(auto i:overlays) {
if(!i->bind(wnd))
continue;
Expand All @@ -37,6 +37,7 @@ void EventDispatcher::dispatchMouseDown(Widget& wnd, MouseEvent &e) {
if(e1.type()==MouseEvent::MouseDown) {
mouseLast = btn;
mouseLastBtn = e.button;
mouseLastId = e.mouseID;
}
}

Expand All @@ -52,8 +53,11 @@ void EventDispatcher::dispatchMouseDown(Widget& wnd, MouseEvent &e) {
mouseLast = btn;
mouseLastTime = Application::tickCount();
mouseLastBtn = e.button;
mouseLastId = e.mouseID;
}

reset(e.mouseID, e.button, btn);

if(auto w = btn.lock()) {
if(w->widget->focusPolicy() & ClickFocus) {
w->widget->implSetFocus(true,Event::FocusReason::ClickReason);
Expand All @@ -64,9 +68,7 @@ void EventDispatcher::dispatchMouseDown(Widget& wnd, MouseEvent &e) {
void EventDispatcher::dispatchMouseUp(Widget& /*wnd*/, MouseEvent &e) {
++mouseEvCount;

auto ptr = mouseUp[e.button];
mouseUp[e.button].reset();

std::weak_ptr<Widget::Ref> ptr = reset(e.mouseID, e.button);
if(auto w = ptr.lock()) {
auto p = e.pos() - w->widget->mapToRoot(Point());
MouseEvent e1( p.x,
Expand All @@ -81,14 +83,15 @@ void EventDispatcher::dispatchMouseUp(Widget& /*wnd*/, MouseEvent &e) {
}

void EventDispatcher::dispatchMouseMove(Widget& wnd, MouseEvent &e) {
auto btn = Event::ButtonNone;
for(uint8_t i=0; i<Event::ButtonLast; ++i)
if(!mouseUp[i].expired()) {
btn = Event::MouseButton(i);
break;
auto btn = Event::ButtonLast;
for(auto& i:mouseUp)
if(i.id==e.mouseID && i.button<btn && !i.ref.expired()) {
btn = i.button;
}
if(btn==Event::ButtonLast)
btn = Event::ButtonNone;

if(auto w = lock(mouseUp[btn])) {
if(auto w = lock(e.mouseID,btn)) {
auto p = e.pos() - w->widget->mapToRoot(Point());
MouseEvent e0( p.x,
p.y,
Expand All @@ -102,7 +105,7 @@ void EventDispatcher::dispatchMouseMove(Widget& wnd, MouseEvent &e) {
return;
}

if(auto w = lock(mouseUp[btn])) {
if(auto w = lock(e.mouseID,btn)) {
auto p = e.pos() - w->widget->mapToRoot(Point());
MouseEvent e1( p.x,
p.y,
Expand All @@ -113,7 +116,7 @@ void EventDispatcher::dispatchMouseMove(Widget& wnd, MouseEvent &e) {
Event::MouseMove );
w->widget->mouseMoveEvent(e1);
if(e.isAccepted()) {
implSetMouseOver(mouseUp[btn].lock(),e);
implSetMouseOver(lock(e.mouseID,btn),e);
return;
}
}
Expand Down Expand Up @@ -304,7 +307,7 @@ std::shared_ptr<Widget::Ref> EventDispatcher::implDispatch(Widget& w, MouseEvent
auto last = mouseLast.lock();
bool dblClick = false;
uint64_t time = Application::tickCount();
if(time-mouseLastTime<1000 && mouseLastBtn==event.button && last!=nullptr && last->widget==it.owner) {
if(time-mouseLastTime<1000 && mouseLastBtn==event.button && mouseLastId==event.mouseID && last!=nullptr && last->widget==it.owner) {
dblClick = true;
}
event.accept();
Expand Down Expand Up @@ -521,6 +524,29 @@ std::shared_ptr<Widget::Ref> EventDispatcher::lock(std::weak_ptr<Widget::Ref>& w
return nullptr;
}

std::shared_ptr<Widget::Ref> EventDispatcher::lock(int id, Event::MouseButton button) {
for(auto& i:mouseUp)
if(i.id==id && i.button==button)
return lock(i.ref);
return nullptr;
}

std::weak_ptr<Widget::Ref> EventDispatcher::reset(int id, Event::MouseButton button, const std::weak_ptr<Widget::Ref>& w) {
for(auto i=mouseUp.begin(); i!=mouseUp.end(); ++i)
if(i->id==id && i->button==button) {
auto ptr = i->ref;
if(w.expired()) {
mouseUp.erase(i);
} else {
i->ref = w;
}
return ptr.lock();
}
if(!w.expired())
mouseUp.push_back({button,id,w});
return {};
}

Event::Modifier EventDispatcher::mkModifier() const {
uint8_t ret = 0;
if(keyMod.ctrlL || keyMod.ctrlR)
Expand Down
12 changes: 11 additions & 1 deletion Engine/system/eventdispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <Tempest/Event>

#include <unordered_map>
#include <vector>

namespace Tempest {

Expand Down Expand Up @@ -33,6 +34,12 @@ class EventDispatcher final {
void dispatchDestroyWindow(SystemApi::Window* w);

private:
struct MouseCapture {
Event::MouseButton button = {};
int id = 0;
std::weak_ptr<Widget::Ref> ref = {};
};

std::shared_ptr<Widget::Ref> implDispatch(Tempest::Widget &w, Tempest::MouseEvent& event);
std::shared_ptr<Widget::Ref> implDispatch(Tempest::Widget &w, Tempest::FocusEvent& event);
void implMouseWheel(Widget &w, MouseEvent &event);
Expand All @@ -44,16 +51,19 @@ class EventDispatcher final {
void handleModKey(const KeyEvent& e);

std::shared_ptr<Widget::Ref> lock(std::weak_ptr<Widget::Ref>& w);
std::shared_ptr<Widget::Ref> lock(int id, Event::MouseButton button);
std::weak_ptr<Widget::Ref> reset(int id, Event::MouseButton button, const std::weak_ptr<Widget::Ref>& w = {});

Widget* customRoot = nullptr;
std::weak_ptr<Widget::Ref> mouseUp[Event::MouseButton::ButtonLast];
std::vector<MouseCapture> mouseUp;
std::weak_ptr<Widget::Ref> mouseLast;
std::weak_ptr<Widget::Ref> mouseOver;

std::weak_ptr<Widget::Ref> focusLast;

std::vector<UiOverlay*> overlays;
Event::MouseButton mouseLastBtn = Event::MouseButton::ButtonNone;
int mouseLastId = 0;
uint64_t mouseLastTime = 0;
uint64_t mouseEvCount = 0;

Expand Down
Loading
Loading