diff --git a/src/comfortable_swipe/gesture/swipe_gesture.cpp b/src/comfortable_swipe/gesture/swipe_gesture.cpp new file mode 100644 index 0000000..f1f45c5 --- /dev/null +++ b/src/comfortable_swipe/gesture/swipe_gesture.cpp @@ -0,0 +1,131 @@ +#ifndef __COMFORTABLE_SWIPE__gesture_swipe_gesture__ +#define __COMFORTABLE_SWIPE__gesture_swipe_gesture__ + +#include // std::cout, std::endl +#include // std::abs +#include "../index.hpp" + +extern "C" +{ + #include // xdo, xdo_new, xdo_free, + // xdo_get_mouse_location + // CURRENT_WINDOW +} + +namespace comfortable_swipe +{ + namespace gesture + { + /** + * Constructs a new swipe gesture with xdo. + */ + swipe_gesture::swipe_gesture + ( + const float threshold, + const char* left3 /* 000 */, + const char* left4 /* 001 */, + const char* right3 /* 010 */, + const char* right4 /* 011 */, + const char* up3 /* 100 */, + const char* up4 /* 101 */, + const char* down3 /* 110 */, + const char* down4 /* 111 */ + ): + xdo(xdo_new(NULL)), + commands(new const char*[8]{left3, left4, right3, right4, up3, up4, down3, down4}) + { } + + /** + * Constructs a new swipe gesture with xdo. + */ + swipe_gesture::~swipe_gesture() + { + xdo_free(this->xdo); + delete[] commands; + } + + /** + * Hook on begin of swipe gesture. + */ + void swipe_gesture::begin() + { + xdo_get_mouse_location(this->xdo, &this->ix, &this->iy, &this->screen_num); + this->previous_gesture = swipe_gesture::FRESH; + this->x = 0; + this->y = 0; + } + + /** + * Hook on update of swipe gesture. + */ + void swipe_gesture::update() + { + this->x += this->dx; + this->y += this->dy; + // scale threshold to 1/10 when gesture is not fresh + float scale = this->previous_gesture == swipe_gesture::FRESH + ? 1.00f + : 0.01f; // square root of 1/10 + if (this->x * this->x + this->y * this->y > this->threshold_squared * scale) + { + int mask = 0; + if (this->fingers == 3) mask |= swipe_gesture::MSK_THREE_FINGERS; + else if (this->fingers == 4) mask |= swipe_gesture::MSK_FOUR_FINGERS; + + if (std::abs(x) > std::abs(y)) + { // horizontal + mask |= swipe_gesture::MSK_HORIZONTAL; + if (x < 0) + mask |= swipe_gesture::MSK_NEGATIVE; + else + mask |= swipe_gesture::MSK_POSITIVE; + } + else /* std::abs(x) <= std::abs(y) */ + { // vertical + mask |= swipe_gesture::MSK_VERTICAL; + if (y < 0) + mask |= swipe_gesture::MSK_NEGATIVE; + else + mask |= swipe_gesture::MSK_POSITIVE; + } + + // send command on fresh OR opposite gesture + if (this->previous_gesture == swipe_gesture::FRESH + || this->previous_gesture == (mask ^ swipe_gesture::MSK_POSITIVE)) + { + this->x = this->y = 0; + this->previous_gesture = mask; + std::cout << "SWIPE " << swipe_gesture::command_map[mask] << std::endl; + xdo_send_keysequence_window(xdo, CURRENTWINDOW, swipe_gesture::commands[mask], 0); + } + } + } + + /** + * Hook on end of swipe gesture. + */ + void swipe_gesture::end() + { } + + /* STATICS DEFINITIONS */ + const int swipe_gesture::MSK_THREE_FINGERS = 0; + const int swipe_gesture::MSK_FOUR_FINGERS = 1; + const int swipe_gesture::MSK_NEGATIVE = 0; + const int swipe_gesture::MSK_POSITIVE = 2; + const int swipe_gesture::MSK_HORIZONTAL = 0; + const int swipe_gesture::MSK_VERTICAL = 4; + const int swipe_gesture::FRESH = -1; + const char * const swipe_gesture::command_map[8] = { + "left 3", + "left 4", + "right 3", + "right 4", + "up 3", + "up 4", + "down 3", + "down 4" + }; + } +} + +#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture__ */ \ No newline at end of file diff --git a/src/comfortable_swipe/gesture/swipe_gesture.h b/src/comfortable_swipe/gesture/swipe_gesture.h new file mode 100644 index 0000000..4811d91 --- /dev/null +++ b/src/comfortable_swipe/gesture/swipe_gesture.h @@ -0,0 +1,64 @@ +#ifndef __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ +#define __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ + +#include +#include + +extern "C" +{ + #include // xdo_t +} + +namespace comfortable_swipe +{ + namespace gesture + { + struct swipe_gesture + { + // constructor + swipe_gesture( + const float, + const char*, + const char*, + const char*, + const char*, + const char*, + const char*, + const char*, + const char* + ); + + ~swipe_gesture(); + + // fields + int fingers; + float dx, dy, udx, udy; + xdo_t * xdo; + + // location of mouse + int screen_num, ix, iy; + + // current location + float x, y, threshold_squared; + int previous_gesture; + const char ** commands; + + // methods + void update(); + void begin(); + void end(); + + // statics + static const int MSK_THREE_FINGERS; + static const int MSK_FOUR_FINGERS; + static const int MSK_NEGATIVE; + static const int MSK_POSITIVE; + static const int MSK_HORIZONTAL; + static const int MSK_VERTICAL; + static const int FRESH; + static const char * const command_map[8]; + }; + } +} + +#endif /* __COMFORTABLE_SWIPE__gesture_swipe_gesture_h__ */ \ No newline at end of file