diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/DragManager.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/DragManager.java
new file mode 100644
index 0000000..462be26
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/DragManager.java
@@ -0,0 +1,77 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.client.graphics.gui;
+
+import java.util.Objects;
+
+import glm.vec._2.d.Vec2d;
+import ru.windcorp.progressia.client.graphics.gui.event.DragEvent;
+import ru.windcorp.progressia.client.graphics.gui.event.DragStartEvent;
+import ru.windcorp.progressia.client.graphics.gui.event.DragStopEvent;
+import ru.windcorp.progressia.client.graphics.input.CursorMoveEvent;
+import ru.windcorp.progressia.client.graphics.input.KeyEvent;
+import ru.windcorp.progressia.client.graphics.input.KeyMatcher;
+import ru.windcorp.progressia.client.graphics.input.bus.InputBus;
+
+public class DragManager {
+
+ private Component component;
+
+ private boolean isDragged = false;
+ private final Vec2d change = new Vec2d();
+
+ public void install(Component c) {
+ Objects.requireNonNull(c, "c");
+ if (c == component) {
+ return;
+ }
+ if (component != null) {
+ throw new IllegalStateException("Already installed on " + component + "; attempted to install on " + c);
+ }
+
+ component = c;
+
+ c.addInputListener(CursorMoveEvent.class, this::onCursorMove, InputBus.Option.ALWAYS);
+ c.addKeyListener(KeyMatcher.LMB, this::onLMB, InputBus.Option.ALWAYS, InputBus.Option.IGNORE_ACTION);
+ }
+
+ private void onCursorMove(CursorMoveEvent e) {
+ if (isDragged) {
+ Vec2d currentChange = e.getChange(null);
+ change.add(currentChange);
+ component.dispatchEvent(new DragEvent(component, currentChange, change));
+ }
+ }
+
+ private void onLMB(KeyEvent e) {
+ if (isDragged && e.isRelease()) {
+
+ isDragged = false;
+ component.dispatchEvent(new DragStopEvent(component, change));
+
+ } else if (!isDragged && !e.isConsumed() && e.isPress() && component.isHovered()) {
+
+ isDragged = true;
+ change.set(0, 0);
+ component.dispatchEvent(new DragStartEvent(component));
+ e.consume();
+
+ }
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/DragEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/DragEvent.java
new file mode 100644
index 0000000..74c91ae
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/DragEvent.java
@@ -0,0 +1,58 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.client.graphics.gui.event;
+
+import glm.vec._2.d.Vec2d;
+import ru.windcorp.progressia.client.graphics.gui.Component;
+
+public class DragEvent extends ComponentEvent {
+
+ private final Vec2d currentChange = new Vec2d();
+ private final Vec2d totalChange = new Vec2d();
+
+ public DragEvent(Component component, Vec2d currentChange, Vec2d totalChange) {
+ super(component);
+ this.currentChange.set(currentChange.x, currentChange.y);
+ this.totalChange.set(totalChange.x, totalChange.y);
+ }
+
+ public Vec2d getCurrentChange() {
+ return currentChange;
+ }
+
+ public double getCurrentChangeX() {
+ return currentChange.x;
+ }
+
+ public double getCurrentChangeY() {
+ return currentChange.y;
+ }
+
+ public Vec2d getTotalChange() {
+ return totalChange;
+ }
+
+ public double getTotalChangeX() {
+ return totalChange.x;
+ }
+
+ public double getTotalChangeY() {
+ return totalChange.y;
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/DragStartEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/DragStartEvent.java
new file mode 100644
index 0000000..232b02a
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/DragStartEvent.java
@@ -0,0 +1,28 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.client.graphics.gui.event;
+
+import ru.windcorp.progressia.client.graphics.gui.Component;
+
+public class DragStartEvent extends ComponentEvent {
+
+ public DragStartEvent(Component component) {
+ super(component);
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/DragStopEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/DragStopEvent.java
new file mode 100644
index 0000000..bc23628
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/DragStopEvent.java
@@ -0,0 +1,44 @@
+/*
+ * Progressia
+ * Copyright (C) 2020-2021 Wind Corporation and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package ru.windcorp.progressia.client.graphics.gui.event;
+
+import glm.vec._2.d.Vec2d;
+import ru.windcorp.progressia.client.graphics.gui.Component;
+
+public class DragStopEvent extends ComponentEvent {
+
+ private final Vec2d totalChange = new Vec2d();
+
+ public DragStopEvent(Component component, Vec2d totalChange) {
+ super(component);
+ this.totalChange.set(totalChange.x, totalChange.y);
+ }
+
+ public Vec2d getTotalChange() {
+ return totalChange;
+ }
+
+ public double getTotalChangeX() {
+ return totalChange.x;
+ }
+
+ public double getTotalChangeY() {
+ return totalChange.y;
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/input/CursorMoveEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/input/CursorMoveEvent.java
index c87fc62..ff7ea82 100644
--- a/src/main/java/ru/windcorp/progressia/client/graphics/input/CursorMoveEvent.java
+++ b/src/main/java/ru/windcorp/progressia/client/graphics/input/CursorMoveEvent.java
@@ -18,7 +18,6 @@
package ru.windcorp.progressia.client.graphics.input;
-import glm.vec._2.Vec2;
import glm.vec._2.d.Vec2d;
public class CursorMoveEvent extends CursorEvent {
@@ -81,7 +80,10 @@ public class CursorMoveEvent extends CursorEvent {
return getNewY() - getPreviousY();
}
- public Vec2 getChange(Vec2 result) {
+ public Vec2d getChange(Vec2d result) {
+ if (result == null) {
+ result = new Vec2d();
+ }
return result.set(getChangeX(), getChangeY());
}