Skip to content

Commit

Permalink
iOS: finger scrolling in controls.
Browse files Browse the repository at this point in the history
(cherry picked from commit ccb5ccd)
  • Loading branch information
singalen authored and Vultraz committed Oct 28, 2018
1 parent e88d56c commit 046fbc5
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 11 deletions.
28 changes: 28 additions & 0 deletions src/gui/core/event/distributor.cpp
Expand Up @@ -125,6 +125,15 @@ mouse_motion::mouse_motion(widget& owner,
_5),
queue_position);

owner.connect_signal<event::SDL_TOUCH_MOTION>(
std::bind(&mouse_motion::signal_handler_sdl_touch_motion,
this,
_2,
_3,
_5,
_6),
queue_position);

owner_.connect_signal<event::SDL_WHEEL_UP>(std::bind(
&mouse_motion::signal_handler_sdl_wheel, this, _2, _3, _5));
owner_.connect_signal<event::SDL_WHEEL_DOWN>(std::bind(
Expand Down Expand Up @@ -199,6 +208,25 @@ void mouse_motion::signal_handler_sdl_mouse_motion(const event::ui_event event,
handled = true;
}

void mouse_motion::signal_handler_sdl_touch_motion(const event::ui_event event,
bool& handled,
const point& coordinate,
const point& distance)
{
DBG_GUI_E << LOG_HEADER << event << ".\n";

if(mouse_captured_) {
assert(mouse_focus_);
owner_.fire(event, *mouse_focus_, coordinate, distance);
} else {
widget* mouse_over = owner_.find_at(coordinate, true);
if(mouse_over) {
owner_.fire(event, *mouse_over, coordinate, distance);
}
}
handled = true;
}

void mouse_motion::signal_handler_sdl_wheel(const event::ui_event event,
bool& handled,
const point& coordinate)
Expand Down
5 changes: 5 additions & 0 deletions src/gui/core/event/distributor.hpp
Expand Up @@ -138,6 +138,11 @@ class mouse_motion
bool& handled,
const point& coordinate);

void signal_handler_sdl_touch_motion(const event::ui_event event,
bool& handled,
const point& coordinate,
const point& distance);

void signal_handler_sdl_wheel(const event::ui_event event,
bool& handled,
const point& coordinate);
Expand Down
7 changes: 7 additions & 0 deletions src/gui/widgets/scrollbar.cpp
Expand Up @@ -43,6 +43,8 @@ scrollbar_base::scrollbar_base(const implementation::builder_styled_widget& buil
&scrollbar_base::signal_handler_mouse_enter, this, _2, _3, _4));
connect_signal<event::MOUSE_MOTION>(std::bind(
&scrollbar_base::signal_handler_mouse_motion, this, _2, _3, _4, _5));
connect_signal<event::SDL_TOUCH_MOTION>(std::bind(
&scrollbar_base::signal_handler_mouse_motion, this, _2, _3, _4, _5));
connect_signal<event::MOUSE_LEAVE>(std::bind(
&scrollbar_base::signal_handler_mouse_leave, this, _2, _3));
connect_signal<event::LEFT_BUTTON_DOWN>(std::bind(
Expand All @@ -60,6 +62,11 @@ void scrollbar_base::finalize_setup()
}
}

void scrollbar_base::scroll_by(const int pixels)
{
move_positioner(static_cast<int>(pixels_per_step_ * pixels));
}

void scrollbar_base::scroll(const scroll_mode scroll)
{
switch(scroll) {
Expand Down
2 changes: 2 additions & 0 deletions src/gui/widgets/scrollbar.hpp
Expand Up @@ -71,6 +71,8 @@ class scrollbar_base : public styled_widget
* @param scroll 'step size' to scroll.
*/
void scroll(const scroll_mode scroll);

void scroll_by(const int pixels);

/** Is the positioner at the beginning of the scrollbar? */
bool at_begin() const
Expand Down
44 changes: 44 additions & 0 deletions src/gui/widgets/scrollbar_container.cpp
Expand Up @@ -98,6 +98,15 @@ scrollbar_container::scrollbar_container(
connect_signal<event::SDL_WHEEL_RIGHT>(
std::bind(&scrollbar_container::signal_handler_sdl_wheel_right, this, _2, _3),
event::dispatcher::back_post_child);

connect_signal<event::SDL_TOUCH_MOTION>(
std::bind(&scrollbar_container::signal_handler_sdl_touch_motion,
this,
_2,
_3,
_5,
_6),
event::dispatcher::back_post_child);
}

void scrollbar_container::layout_initialize(const bool full_initialization)
Expand Down Expand Up @@ -1178,4 +1187,39 @@ void scrollbar_container::signal_handler_sdl_wheel_right(const event::ui_event e
}
}

void
scrollbar_container::signal_handler_sdl_touch_motion(const event::ui_event event,
bool& handled,
const point& position,
const point& distance)
{
(void) position;
DBG_GUI_E << LOG_HEADER << event << ".\n";

bool is_scrollbar_moved = false;

if (horizontal_scrollbar_grid_ && horizontal_scrollbar_) {

if(horizontal_scrollbar_grid_->get_visible() == widget::visibility::visible) {
horizontal_scrollbar_->scroll_by(-distance.x);
is_scrollbar_moved = true;
}
}

if (vertical_scrollbar_grid_ && vertical_scrollbar_) {

if(vertical_scrollbar_grid_->get_visible() == widget::visibility::visible) {
vertical_scrollbar_->scroll_by(-distance.y);
is_scrollbar_moved = true;
}
}

if (is_scrollbar_moved) {
scrollbar_moved();
handled = true;
}
}



} // namespace gui2
2 changes: 2 additions & 0 deletions src/gui/widgets/scrollbar_container.hpp
Expand Up @@ -540,6 +540,8 @@ class scrollbar_container : public container_base
void signal_handler_sdl_wheel_down(const event::ui_event event, bool& handled);
void signal_handler_sdl_wheel_left(const event::ui_event event, bool& handled);
void signal_handler_sdl_wheel_right(const event::ui_event event, bool& handled);
void signal_handler_sdl_touch_motion(const event::ui_event event, bool& handled,
const point& position, const point& distance);

public:
scrollbar_base* horizontal_scrollbar()
Expand Down
63 changes: 52 additions & 11 deletions src/widgets/scrollarea.cpp
Expand Up @@ -18,14 +18,15 @@

#include "widgets/scrollarea.hpp"
#include "sdl/rect.hpp"
#include "video.hpp"


namespace gui {

scrollarea::scrollarea(CVideo &video, const bool auto_join)
: widget(video, auto_join), scrollbar_(video),
old_position_(0), recursive_(false), shown_scrollbar_(false),
shown_size_(0), full_size_(0)
shown_size_(0), full_size_(0), swipe_dy_(0)
{
scrollbar_.hide(true);
}
Expand Down Expand Up @@ -153,19 +154,59 @@ void scrollarea::handle_event(const SDL_Event& event)
if (mouse_locked() || hidden())
return;

if (event.type != SDL_MOUSEWHEEL)
return;
if (event.type == SDL_MOUSEWHEEL) {
const SDL_MouseWheelEvent &ev = event.wheel;
int x, y;
SDL_GetMouseState(&x, &y);
if (sdl::point_in_rect(x, y, inner_location())) {
if (ev.y > 0) {
scrollbar_.scroll_up();
} else if (ev.y < 0) {
scrollbar_.scroll_down();
}
}
}

if (event.type == SDL_FINGERUP) {
swipe_dy_ = 0;
}

if (event.type == SDL_FINGERDOWN || event.type == SDL_FINGERMOTION) {
SDL_Rect r = video().screen_area();
auto tx = static_cast<int>(event.tfinger.x * r.w);
auto ty = static_cast<int>(event.tfinger.y * r.h);
auto dy = static_cast<int>(event.tfinger.dy * r.h);

if (event.type == SDL_FINGERDOWN) {
swipe_dy_ = 0;
swipe_origin_.x = tx;
swipe_origin_.y = ty;
}

const SDL_MouseWheelEvent &ev = event.wheel;
int x, y;
SDL_GetMouseState(&x, &y);
if (sdl::point_in_rect(x, y, inner_location())) {
if (ev.y > 0) {
scrollbar_.scroll_up();
} else if (ev.y < 0) {
scrollbar_.scroll_down();
if (event.type == SDL_FINGERMOTION) {

swipe_dy_ += dy;
if (scrollbar_.get_max_position() == 0) {
return;
}

int scrollbar_step = scrollbar_.height() / scrollbar_.get_max_position();
if (scrollbar_step <= 0) {
return;
}

if (sdl::point_in_rect(swipe_origin_.x, swipe_origin_.y, inner_location())
&& abs(swipe_dy_) >= scrollbar_step)
{
unsigned int pos = std::max(
static_cast<int>(scrollbar_.get_position() - swipe_dy_ / scrollbar_step),
0);
scrollbar_.set_position(pos);
swipe_dy_ %= scrollbar_step;
}
}
}

}

} // end namespace gui
5 changes: 5 additions & 0 deletions src/widgets/scrollarea.hpp
Expand Up @@ -60,6 +60,11 @@ class scrollarea : public widget
bool recursive_, shown_scrollbar_;
unsigned shown_size_;
unsigned full_size_;
int swipe_dy_;
struct {
int x;
int y;
} swipe_origin_;

void test_scrollbar();
};
Expand Down

0 comments on commit 046fbc5

Please sign in to comment.