#include <memory>
#include <ostream>
#include <vector>
#include <cstdlib>
#include <iostream>
#include <variant>
#include <mutex>
#include "libtouch.h"
namespace events {
struct pan_event {
int64_t pan_amount;
};
struct interrupt_event {
};
struct fling_event {
};
struct event {
enum lscroll_input_source_t source;
};
}
struct lscroll_scrollview {
std::recursive_mutex lock;
struct {
int64_t panned_by_x = 0;
int64_t panned_by_y = 0;
int64_t absolute_x = 0;
int64_t absolute_y = 0;
bool active = true; } frame_pan;
uint64_t content_width = 0;
uint64_t content_height = 0;
uint64_t viewport_width = 0;
uint64_t viewport_height = 0;
int64_t viewport_position_x = 0;
int64_t viewport_position_y = 0;
double current_velocity_x = 0;
double current_velocity_y = 0;
std::vector<std::variant<events::pan_event, events::interrupt_event, events::fling_event>> events_x;
std::vector<std::variant<events::pan_event, events::interrupt_event, events::fling_event>> events_y;
lscroll_scrollview() {
}
~lscroll_scrollview(void) {
}
};
extern "C" {
struct lscroll_scrollview* lscroll_create_scrollview() {
struct lscroll_scrollview* sv = new lscroll_scrollview;
return sv;
};
void lscroll_destroy_scrollview(struct lscroll_scrollview* sv) {
delete sv;
}
void lscroll_set_geometry(
struct lscroll_scrollview* handle,
uint64_t content_height,
uint64_t content_width,
uint64_t viewport_height,
uint64_t viewport_width
) {
#ifdef lscroll_thread_safe
handle->lock.lock();
#endif
std::cout << "scrollview geometry updated to" << std::endl
<< "viewport w/h: " << viewport_width << ", " << viewport_height << std::endl
<< " content w/h: " << content_width << ", " << content_height << std::endl;
#ifdef lscroll_thread_safe
handle->lock.unlock();
#endif
}
void lscroll_add_scroll_x(lscroll_scrollview* handle, int64_t motion_x) {
#ifdef lscroll_thread_safe
handle->lock.lock();
#endif
handle->events_x.push_back(events::pan_event{motion_x});
#ifdef lscroll_thread_safe
handle->lock.unlock();
#endif
}
void lscroll_add_scroll_y(lscroll_scrollview* handle, int64_t motion_y) {
#ifdef lscroll_thread_safe
handle->lock.lock();
#endif
handle->events_y.push_back(events::pan_event{motion_y});
#ifdef lscroll_thread_safe
handle->lock.unlock();
#endif
}
void lscroll_add_scroll(
lscroll_scrollview* handle,
int64_t motion_x,
int64_t motion_y
) {
#ifdef lscroll_thread_safe
handle->lock.lock();
#endif
handle->events_y.push_back(events::pan_event{motion_y});
handle->events_x.push_back(events::pan_event{motion_x});
#ifdef lscroll_thread_safe
handle->lock.unlock();
#endif
}
void lscroll_add_scroll_interrupt(lscroll_scrollview* handle) {
#ifdef lscroll_thread_safe
handle->lock.lock();
#endif
handle->events_y.push_back(events::interrupt_event{});
handle->events_x.push_back(events::interrupt_event{});
#ifdef lscroll_thread_safe
handle->lock.unlock();
#endif
}
void lscroll_add_scroll_release(lscroll_scrollview* handle) {
#ifdef lscroll_thread_safe
handle->lock.lock();
#endif
handle->events_y.push_back(events::fling_event{});
handle->events_x.push_back(events::fling_event{});
#ifdef lscroll_thread_safe
handle->lock.unlock();
#endif
}
void lscroll_mark_frame(lscroll_scrollview* handle) {
#ifdef lscroll_thread_safe
handle->lock.lock();
#endif
int64_t pan_x = 0;
int64_t pan_y = 0;
for(auto event: handle->events_x) {
if(std::holds_alternative<events::pan_event>(event)) {
pan_x += std::get<events::pan_event>(event).pan_amount;
} else if(std::holds_alternative<events::fling_event>(event)) {
} else if(std::holds_alternative<events::interrupt_event>(event)) {
} else {
std::cerr << "LibScroll: Not accounting for passed event in lscroll_mark_frame" << std::endl;
}
}
for(auto event: handle->events_y) {
if(std::holds_alternative<events::pan_event>(event)) {
pan_y += std::get<events::pan_event>(event).pan_amount;
} else if(std::holds_alternative<events::fling_event>(event)) {
} else if(std::holds_alternative<events::interrupt_event>(event)) {
} else {
std::cerr << "LibScroll: Not accounting for passed event in lscroll_mark_frame" << std::endl;
exit(-1);
}
}
handle->frame_pan.panned_by_x = pan_x;
handle->frame_pan.panned_by_y = pan_y;
handle->frame_pan.absolute_x += pan_x;
handle->frame_pan.absolute_y += pan_y;
#ifdef lscroll_thread_safe
handle->lock.unlock();
#endif
}
int64_t lscroll_get_pan_x(lscroll_scrollview* handle) {
return handle->frame_pan.panned_by_x;
}
int64_t lscroll_get_pan_y(lscroll_scrollview* handle) {
return handle->frame_pan.panned_by_y;
}
int64_t lscroll_get_pos_x(lscroll_scrollview* handle) {
return handle->frame_pan.absolute_x;
}
int64_t lscroll_get_pos_y(lscroll_scrollview* handle) {
return handle->frame_pan.absolute_y;
}
bool lscroll_query_pan_active(lscroll_scrollview* handle) {
return handle->frame_pan.active;
}
void lscroll_force_pan(
lscroll_scrollview* handle,
int64_t x_dp,
int64_t y_dp
) {
lscroll_add_scroll(handle, x_dp, y_dp);
}
void lscroll_force_jump(
lscroll_scrollview* handle,
int64_t x_absolute,
int64_t y_absolute
) {
lscroll_add_scroll(
handle,
x_absolute - handle->frame_pan.absolute_x,
y_absolute - handle->frame_pan.absolute_y);
}
}