Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scroll support #161

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
4 changes: 2 additions & 2 deletions src/logid/Configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Configuration::Configuration(const std::string& config_file)
}

try {
auto& ignore = root.lookup("ignore");
auto& ignore = root["ignore"];
if(ignore.getType() == libconfig::Setting::TypeInt) {
_ignore_list.insert((int)ignore);
} else if(ignore.isList() || ignore.isArray()) {
Expand All @@ -116,7 +116,7 @@ Configuration::Configuration(const std::string& config_file)
} catch(const SettingNotFoundException& e) {
// May be called blacklist
try {
auto& ignore = root.lookup("blacklist");
auto& ignore = root["blacklist"];
if(ignore.getType() == libconfig::Setting::TypeInt) {
_ignore_list.insert((int)ignore);
} else if(ignore.isList() || ignore.isArray()) {
Expand Down
4 changes: 2 additions & 2 deletions src/logid/actions/Action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ std::shared_ptr<Action> Action::makeAction(Device *device, libconfig::Setting
}

try {
auto& action_type = setting.lookup("type");
auto& action_type = setting["type"];

if(action_type.getType() != libconfig::Setting::TypeString) {
logPrintf(WARN, "Line %d: Action type must be a string",
Expand Down Expand Up @@ -76,4 +76,4 @@ std::shared_ptr<Action> Action::makeAction(Device *device, libconfig::Setting
setting.getSourceLine());
throw InvalidAction();
}
}
}
5 changes: 5 additions & 0 deletions src/logid/actions/Action.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ namespace actions {
// Suppress unused warning
(void)x; (void)y;
}
virtual void scroll(int16_t s)
{
// Suppress unused warning
(void)s;
};

virtual bool pressed()
{
Expand Down
6 changes: 3 additions & 3 deletions src/logid/actions/ChangeDPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ ChangeDPI::Config::Config(Device *device, libconfig::Setting &config) :
}

try {
auto& inc = config.lookup("inc");
auto& inc = config["inc"];
if(inc.getType() != libconfig::Setting::TypeInt)
logPrintf(WARN, "Line %d: inc must be an integer",
inc.getSourceLine());
Expand All @@ -88,7 +88,7 @@ ChangeDPI::Config::Config(Device *device, libconfig::Setting &config) :
}

try {
auto& sensor = config.lookup("sensor");
auto& sensor = config["sensor"];
if(sensor.getType() != libconfig::Setting::TypeInt)
logPrintf(WARN, "Line %d: sensor must be an integer",
sensor.getSourceLine());
Expand All @@ -106,4 +106,4 @@ uint16_t ChangeDPI::Config::interval() const
uint8_t ChangeDPI::Config::sensor() const
{
return _sensor;
}
}
4 changes: 2 additions & 2 deletions src/logid/actions/ChangeHostAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ ChangeHostAction::Config::Config(Device *device, libconfig::Setting& config)
: Action::Config(device)
{
try {
auto& host = config.lookup("host");
auto& host = config["host"];
if(host.getType() == libconfig::Setting::TypeInt) {
_offset = false;
_host = host;
Expand Down Expand Up @@ -116,4 +116,4 @@ uint8_t ChangeHostAction::Config::nextHost(hidpp20::ChangeHost::HostInfo info)
} else
return _host;
}
}
}
6 changes: 3 additions & 3 deletions src/logid/actions/CycleDPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ CycleDPI::Config::Config(Device *device, libconfig::Setting &config) :
}

try {
auto& sensor = config.lookup("sensor");
auto& sensor = config["sensor"];
if(sensor.getType() != Setting::TypeInt)
logPrintf(WARN, "Line %d: sensor must be an integer",
sensor.getSourceLine());
Expand All @@ -87,7 +87,7 @@ CycleDPI::Config::Config(Device *device, libconfig::Setting &config) :
}

try {
auto& dpis = config.lookup("dpis");
auto& dpis = config["dpis"];
if(!dpis.isList() && !dpis.isArray()) {
logPrintf(WARN, "Line %d: dpis must be a list or array, skipping.",
dpis.getSourceLine());
Expand Down Expand Up @@ -130,4 +130,4 @@ bool CycleDPI::Config::empty() const
uint8_t CycleDPI::Config::sensor() const
{
return _sensor;
}
}
187 changes: 88 additions & 99 deletions src/logid/actions/GestureAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,26 @@ GestureAction::Direction GestureAction::toDirection(std::string direction)
return Left;
else if(direction == "right")
return Right;
else if(direction == "scrollup")
return ScrollUp;
else if(direction == "scrolldown")
return ScrollDown;
else if(direction == "none")
return None;
else
throw std::invalid_argument("direction");
}

GestureAction::Direction GestureAction::toDirection(int16_t x, int16_t y)
GestureAction::Direction GestureAction::toDirection(int16_t x, int16_t y, int16_t s)
{
if(x >= 0 && y >= 0)
return x >= y ? Right : Down;
else if(x < 0 && y >= 0)
return -x <= y ? Down : Left;
else if(x <= 0 && y < 0)
return x <= y ? Left : Up;
if(isScroll())
return s > 0 ? ScrollUp : ScrollDown;
else if(isVertical())
return y < 0 ? Up : Down;
else if(isHorizontal())
return x < 0 ? Left : Right;
else
return x <= -y ? Up : Right;
return None;
}

GestureAction::GestureAction(Device* dev, libconfig::Setting& config) :
Expand All @@ -70,104 +74,89 @@ void GestureAction::press()
void GestureAction::release()
{
_pressed = false;
bool threshold_met = false;

auto d = toDirection(_x, _y);
auto primary_gesture = _config.gestures().find(d);
if(primary_gesture != _config.gestures().end()) {
threshold_met = primary_gesture->second->metThreshold();
primary_gesture->second->release(true);
}
Direction d = toDirection(_x, _y, _s);

for(auto& gesture : _config.gestures()) {
if(gesture.first == d)
continue;
if(!threshold_met) {
if(gesture.second->metThreshold()) {
// If the primary gesture did not meet its threshold, use the
// secondary one.
threshold_met = true;
gesture.second->release(true);
break;
}
} else {
gesture.second->release(false);
}
gesture.second->release(gesture.first == d);
}

if(!threshold_met) {
if(_config.noneAction()) {
_config.noneAction()->press();
_config.noneAction()->release();
}
if(d == None && _config.noneAction()) {
_config.noneAction()->press();
_config.noneAction()->release();
}
}

void GestureAction::move(int16_t x, int16_t y)
bool GestureAction::isScroll()
{
auto new_x = _x + x, new_y = _y + y;

if(abs(x) > 0) {
if(_x < 0 && new_x >= 0) { // Left -> Origin/Right
auto left = _config.gestures().find(Left);
if(left != _config.gestures().end())
left->second->move(_x);
if(new_x) { // Ignore to origin
auto right = _config.gestures().find(Right);
if(right != _config.gestures().end())
right->second->move(new_x);
}
} else if(_x > 0 && new_x <= 0) { // Right -> Origin/Left
auto right = _config.gestures().find(Right);
if(right != _config.gestures().end())
right->second->move(-_x);
if(new_x) { // Ignore to origin
auto left = _config.gestures().find(Left);
if(left != _config.gestures().end())
left->second->move(-new_x);
}
} else if(new_x < 0) { // Origin/Left to Left
auto left = _config.gestures().find(Left);
if(left != _config.gestures().end())
left->second->move(-x);
} else if(new_x > 0) { // Origin/Right to Right
auto right = _config.gestures().find(Right);
if(right != _config.gestures().end())
right->second->move(x);
}
auto scrollUp = _config.gestures().find(ScrollUp);
bool isScrollUp = scrollUp == _config.gestures().end() ? false : scrollUp->second->metThreshold();
auto scrollDown = _config.gestures().find(ScrollDown);
bool isScrollDown = scrollDown == _config.gestures().end() ? false : scrollDown->second->metThreshold();
return isScrollUp || isScrollDown;
}

bool GestureAction::isVertical()
{
auto up = _config.gestures().find(Up);
bool isUp = up == _config.gestures().end() ? false : up->second->metThreshold();
auto down = _config.gestures().find(Down);
bool isDown = down == _config.gestures().end() ? false : down->second->metThreshold();
return isUp || isDown;
}

bool GestureAction::isHorizontal()
{
auto left = _config.gestures().find(Left);
bool isLeft = left == _config.gestures().end() ? false : left->second->metThreshold();
auto right = _config.gestures().find(Right);
bool isRight = right == _config.gestures().end() ? false : right->second->metThreshold();
return isLeft || isRight;
}

void GestureAction::move3D(int16_t x, int16_t y, int16_t s)
{
auto gesture = _config.gestures().end();
int16_t axis = 0;

bool isS = isScroll();
bool isV = isVertical();
bool isH = isHorizontal();

if (!isS && !isV && x < 0) {
gesture = _config.gestures().find(Left);
axis = -x;
}

if(abs(y) > 0) {
if(_y > 0 && new_y <= 0) { // Up -> Origin/Down
auto up = _config.gestures().find(Up);
if(up != _config.gestures().end())
up->second->move(_y);
if(new_y) { // Ignore to origin
auto down = _config.gestures().find(Down);
if(down != _config.gestures().end())
down->second->move(new_y);
}
} else if(_y < 0 && new_y >= 0) { // Down -> Origin/Up
auto down = _config.gestures().find(Down);
if(down != _config.gestures().end())
down->second->move(-_y);
if(new_y) { // Ignore to origin
auto up = _config.gestures().find(Up);
if(up != _config.gestures().end())
up->second->move(-new_y);
}
} else if(new_y < 0) { // Origin/Up to Up
auto up = _config.gestures().find(Up);
if(up != _config.gestures().end())
up->second->move(-y);
} else if(new_y > 0) {// Origin/Down to Down
auto down = _config.gestures().find(Down);
if(down != _config.gestures().end())
down->second->move(y);
}
if (!isS && !isV && x > 0) {
gesture = _config.gestures().find(Right);
axis = x;
}

if (!isS && !isH && y < 0) {
gesture = _config.gestures().find(Up);
axis = -y;
}

_x = new_x; _y = new_y;
if (!isS && !isH && y > 0) {
gesture = _config.gestures().find(Down);
axis = y;
}

if (!isV && !isH && s > 0) {
gesture = _config.gestures().find(ScrollUp);
axis = s;
}

if (!isV && !isH && s < 0) {
gesture = _config.gestures().find(ScrollDown);
axis = -s;
}

if (gesture != _config.gestures().end())
gesture->second->move(axis);

_x += x; _y += y; _s += s;
}

uint8_t GestureAction::reprogFlags() const
Expand All @@ -180,7 +169,7 @@ GestureAction::Config::Config(Device* device, libconfig::Setting &root) :
Action::Config(device)
{
try {
auto& gestures = root.lookup("gestures");
auto& gestures = root["gestures"];

if(!gestures.isList()) {
logPrintf(WARN, "Line %d: gestures must be a list, ignoring.",
Expand All @@ -199,7 +188,7 @@ GestureAction::Config::Config(Device* device, libconfig::Setting &root) :

Direction d;
try {
auto& direction = gestures[i].lookup("direction");
auto& direction = gestures[i]["direction"];
if(direction.getType() != libconfig::Setting::TypeString) {
logPrintf(WARN, "Line %d: direction must be a string, "
"skipping.", direction.getSourceLine());
Expand Down Expand Up @@ -228,7 +217,7 @@ GestureAction::Config::Config(Device* device, libconfig::Setting &root) :

if(d == None) {
try {
auto& mode = gestures[i].lookup("mode");
auto& mode = gestures[i]["mode"];
if(mode.getType() == libconfig::Setting::TypeString) {
std::string mode_str = mode;
std::transform(mode_str.begin(), mode_str.end(),
Expand All @@ -251,10 +240,10 @@ GestureAction::Config::Config(Device* device, libconfig::Setting &root) :

try {
_none_action = Action::makeAction(_device,
gestures[i].lookup("action"));
gestures[i]["action"]);
} catch (InvalidAction& e) {
logPrintf(WARN, "Line %d: %s is not a valid action, "
"skipping.", gestures[i].lookup("action")
"skipping.", gestures[i]["action"]
.getSourceLine(), e.what());
} catch (libconfig::SettingNotFoundException& e) {
logPrintf(WARN, "Line %d: action is a required field, "
Expand Down Expand Up @@ -288,4 +277,4 @@ std::map<GestureAction::Direction, std::shared_ptr<Gesture>>&
std::shared_ptr<Action> GestureAction::Config::noneAction()
{
return _none_action;
}
}
Loading