add tap event on iOS
This commit is contained in:
@@ -344,14 +344,20 @@ std::recursive_mutex lock_mutex;
|
|||||||
float get_force(UITouch* t)
|
float get_force(UITouch* t)
|
||||||
{
|
{
|
||||||
//glm::pow(t.force / t.maximumPossibleForce, 0.5);
|
//glm::pow(t.force / t.maximumPossibleForce, 0.5);
|
||||||
return glm::clamp(t.force / 2.0, 0.0, 1.0);
|
return glm::clamp(t.force / 1.0, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<UITouch*> ignored_touch;
|
std::set<UITouch*> ignored_touch;
|
||||||
|
std::map<UITouch*, glm::vec2> touch_start;
|
||||||
|
int max_touch_count = 0;
|
||||||
|
bool is_tap = true;
|
||||||
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
||||||
{
|
{
|
||||||
|
NSUInteger n = [[event allTouches] count];
|
||||||
UITouch *touch = [[event allTouches] anyObject];
|
UITouch *touch = [[event allTouches] anyObject];
|
||||||
|
|
||||||
|
max_touch_count = n;
|
||||||
|
|
||||||
CGPoint touchLocation = [touch locationInView:self.view];
|
CGPoint touchLocation = [touch locationInView:self.view];
|
||||||
float scale = self.view.contentScaleFactor;
|
float scale = self.view.contentScaleFactor;
|
||||||
|
|
||||||
@@ -365,7 +371,15 @@ std::set<UITouch*> ignored_touch;
|
|||||||
|
|
||||||
// apple pencil
|
// apple pencil
|
||||||
if (touch.type == UITouchType::UITouchTypeStylus)
|
if (touch.type == UITouchType::UITouchTypeStylus)
|
||||||
|
{
|
||||||
pen_down = true;
|
pen_down = true;
|
||||||
|
is_tap = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is_tap = true;
|
||||||
|
touch_start.clear();
|
||||||
|
}
|
||||||
|
|
||||||
App::I->ui_task_async([touchLocation, scale, f=force, source] {
|
App::I->ui_task_async([touchLocation, scale, f=force, source] {
|
||||||
App::I->mouse_down(0, touchLocation.x * scale, touchLocation.y * scale, f, source, 0);
|
App::I->mouse_down(0, touchLocation.x * scale, touchLocation.y * scale, f, source, 0);
|
||||||
@@ -375,8 +389,10 @@ std::set<UITouch*> ignored_touch;
|
|||||||
}
|
}
|
||||||
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
||||||
{
|
{
|
||||||
|
is_tap = false;
|
||||||
NSUInteger n = [[event allTouches] count];
|
NSUInteger n = [[event allTouches] count];
|
||||||
float scale = self.view.contentScaleFactor;
|
float scale = self.view.contentScaleFactor;
|
||||||
|
max_touch_count = std::max<int>(max_touch_count, n);
|
||||||
|
|
||||||
std::vector<UITouch*> valid_touches;
|
std::vector<UITouch*> valid_touches;
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
@@ -386,6 +402,11 @@ std::set<UITouch*> ignored_touch;
|
|||||||
if (it == ignored_touch.end())
|
if (it == ignored_touch.end())
|
||||||
{
|
{
|
||||||
valid_touches.push_back(t);
|
valid_touches.push_back(t);
|
||||||
|
if (touch_start.find(t) == touch_start.end())
|
||||||
|
{
|
||||||
|
auto loc = [t locationInView:self.view];
|
||||||
|
touch_start[t] = { loc.x, loc.y };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -458,10 +479,35 @@ std::set<UITouch*> ignored_touch;
|
|||||||
}
|
}
|
||||||
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
||||||
{
|
{
|
||||||
|
static NSTimeInterval last_time = 0;
|
||||||
|
static int tap_count = 1;
|
||||||
|
|
||||||
|
int n = (int)[[event allTouches] count];
|
||||||
UITouch *touch = [[event allTouches] anyObject];
|
UITouch *touch = [[event allTouches] anyObject];
|
||||||
CGPoint touchLocation = [touch locationInView:self.view];
|
CGPoint touchLocation = [touch locationInView:self.view];
|
||||||
float scale = self.view.contentScaleFactor;
|
float scale = self.view.contentScaleFactor;
|
||||||
|
|
||||||
|
if (touch.timestamp - last_time < 0.2)
|
||||||
|
tap_count++;
|
||||||
|
else
|
||||||
|
tap_count = 1;
|
||||||
|
last_time = touch.timestamp;
|
||||||
|
|
||||||
|
glm::vec2 center(0);
|
||||||
|
float max_dist = 0;
|
||||||
|
for (UITouch* t : [event allTouches])
|
||||||
|
{
|
||||||
|
auto loc = [t locationInView:self.view];
|
||||||
|
center += glm::vec2(loc.x, loc.y);
|
||||||
|
if (touch_start.find(t) != touch_start.end())
|
||||||
|
{
|
||||||
|
max_dist = std::max<float>(max_dist, glm::distance(touch_start[t], { loc.x, loc.y }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
center /= (float)n;
|
||||||
|
//LOG("max touches (%d-%d) (max %d) dist %f",
|
||||||
|
// n, (int)touch_start.size(), max_touch_count, (int)max_dist);
|
||||||
|
|
||||||
if (ignored_touch.count(touch))
|
if (ignored_touch.count(touch))
|
||||||
{
|
{
|
||||||
ignored_touch.erase(touch);
|
ignored_touch.erase(touch);
|
||||||
@@ -471,11 +517,13 @@ std::set<UITouch*> ignored_touch;
|
|||||||
kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch;
|
kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch;
|
||||||
pen_down = false;
|
pen_down = false;
|
||||||
|
|
||||||
App::I->ui_task_async([tc=t_count, touchLocation, scale, source] {
|
App::I->ui_task_async([tc=t_count, touchLocation, scale, source, n, center, max_dist] {
|
||||||
if (tc == 2)
|
if (tc == 2)
|
||||||
App::I->gesture_end();
|
App::I->gesture_end();
|
||||||
else
|
else
|
||||||
App::I->mouse_up(0, touchLocation.x * scale, touchLocation.y * scale, source, 0);
|
App::I->mouse_up(0, touchLocation.x * scale, touchLocation.y * scale, source, 0);
|
||||||
|
if (is_tap || max_dist < 10)
|
||||||
|
App::I->touch_tap(center, n == 1 ? max_touch_count : n, tap_count);
|
||||||
});
|
});
|
||||||
|
|
||||||
t_count = 0;
|
t_count = 0;
|
||||||
|
|||||||
@@ -220,6 +220,7 @@ public:
|
|||||||
bool gesture_start(const glm::vec2& p0, const glm::vec2& p1);
|
bool gesture_start(const glm::vec2& p0, const glm::vec2& p1);
|
||||||
bool gesture_move(const glm::vec2& p0, const glm::vec2& p1);
|
bool gesture_move(const glm::vec2& p0, const glm::vec2& p1);
|
||||||
bool gesture_end();
|
bool gesture_end();
|
||||||
|
bool touch_tap(const glm::vec2& pos, int fingers, int tap_count);
|
||||||
bool key_down(kKey key);
|
bool key_down(kKey key);
|
||||||
bool key_up(kKey key);
|
bool key_up(kKey key);
|
||||||
bool key_char(char key);
|
bool key_char(char key);
|
||||||
|
|||||||
@@ -454,6 +454,18 @@ bool App::gesture_end()
|
|||||||
ret = main->on_event(&e);
|
ret = main->on_event(&e);
|
||||||
return ret == kEventResult::Consumed;
|
return ret == kEventResult::Consumed;
|
||||||
}
|
}
|
||||||
|
bool App::touch_tap(const glm::vec2& pos, int fingers, int tap_count)
|
||||||
|
{
|
||||||
|
redraw = true;
|
||||||
|
TouchEvent e;
|
||||||
|
e.m_type = kEventType::TouchTap;
|
||||||
|
e.m_finger_count = fingers;
|
||||||
|
e.m_tap_count = tap_count;
|
||||||
|
kEventResult ret = kEventResult::Available;
|
||||||
|
if (auto* main = layout[main_id])
|
||||||
|
ret = main->on_event(&e);
|
||||||
|
return ret == kEventResult::Consumed;
|
||||||
|
}
|
||||||
bool App::key_down(kKey key)
|
bool App::key_down(kKey key)
|
||||||
{
|
{
|
||||||
if (key == kKey::KeySpacebar && vr_active)
|
if (key == kKey::KeySpacebar && vr_active)
|
||||||
|
|||||||
11
src/event.h
11
src/event.h
@@ -89,6 +89,7 @@ enum class kEventCategory : uint8_t
|
|||||||
KeyEvent,
|
KeyEvent,
|
||||||
ButtonEvent,
|
ButtonEvent,
|
||||||
GestureEvent,
|
GestureEvent,
|
||||||
|
TouchEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class kEventType : uint8_t
|
enum class kEventType : uint8_t
|
||||||
@@ -107,6 +108,7 @@ enum class kEventType : uint8_t
|
|||||||
GestureStart,
|
GestureStart,
|
||||||
GestureMove,
|
GestureMove,
|
||||||
GestureEnd,
|
GestureEnd,
|
||||||
|
TouchTap,
|
||||||
KeyDown,
|
KeyDown,
|
||||||
KeyUp,
|
KeyUp,
|
||||||
KeyChar,
|
KeyChar,
|
||||||
@@ -158,3 +160,12 @@ public:
|
|||||||
glm::vec2 m_pos;
|
glm::vec2 m_pos;
|
||||||
glm::vec2 m_pos_delta;
|
glm::vec2 m_pos_delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TouchEvent : public Event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TouchEvent() { m_cat = kEventCategory::TouchEvent; }
|
||||||
|
glm::vec2 m_pos;
|
||||||
|
int m_finger_count;
|
||||||
|
int m_tap_count;
|
||||||
|
};
|
||||||
|
|||||||
@@ -543,6 +543,7 @@ kEventResult NodeCanvas::handle_event(Event* e)
|
|||||||
MouseEvent* me = static_cast<MouseEvent*>(e);
|
MouseEvent* me = static_cast<MouseEvent*>(e);
|
||||||
KeyEvent* ke = static_cast<KeyEvent*>(e);
|
KeyEvent* ke = static_cast<KeyEvent*>(e);
|
||||||
GestureEvent* ge = static_cast<GestureEvent*>(e);
|
GestureEvent* ge = static_cast<GestureEvent*>(e);
|
||||||
|
TouchEvent* te = static_cast<TouchEvent*>(e);
|
||||||
auto loc = (me->m_pos - m_pos) * root()->m_zoom;
|
auto loc = (me->m_pos - m_pos) * root()->m_zoom;
|
||||||
|
|
||||||
switch (e->m_type)
|
switch (e->m_type)
|
||||||
@@ -631,6 +632,10 @@ kEventResult NodeCanvas::handle_event(Event* e)
|
|||||||
for (auto& mode : *m_canvas->m_mode)
|
for (auto& mode : *m_canvas->m_mode)
|
||||||
mode->on_GestureEvent(ge);
|
mode->on_GestureEvent(ge);
|
||||||
break;
|
break;
|
||||||
|
case kEventType::TouchTap:
|
||||||
|
if (te->m_finger_count == 2)
|
||||||
|
ActionManager::undo();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return kEventResult::Available;
|
return kEventResult::Available;
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user