add zoom/move functionality
This commit is contained in:
1 parent
87ea8c0c63
commit
c6dd6c3a79
2 files changed
+154
-44
No files matched your search
@@ -1,12 +1,14 @@
|
||||
package me.SoundDraw;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
@@ -20,14 +22,20 @@ public class DrawingBoard extends JPanel {
|
||||
private byte[] data = new byte[DEFAULT_SIZE];
|
||||
private int lastEditedSize = DEFAULT_SIZE;
|
||||
|
||||
private boolean drawing = false;
|
||||
private EnumMouseDrag mouseDrag = EnumMouseDrag.NONE;
|
||||
private Point lastPos;
|
||||
|
||||
private int centerOff = 0;
|
||||
private int movingCenterOff = 0;
|
||||
private int zoom = 1;
|
||||
|
||||
public DrawingBoard() {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
|
||||
setBackground(Color.black);
|
||||
MouseListener listener = new MouseListener();
|
||||
addMouseListener(listener);
|
||||
addMouseMotionListener(listener);
|
||||
addMouseWheelListener(listener);
|
||||
addComponentListener(new ComponentAdapter() {
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e) {
|
||||
@@ -72,51 +80,99 @@ public class DrawingBoard extends JPanel {
|
||||
g.setColor(Color.darkGray);
|
||||
g.drawLine(0, height / 2, width, height / 2);
|
||||
|
||||
g.setColor(Color.white);
|
||||
for (int i = 0; i < data.length - 1; i++) {
|
||||
g.drawLine(i * width / data.length, (data[i] + 128) * height / 256, (i + 1) * width / data.length,
|
||||
(data[i + 1] + 128) * height / 256);
|
||||
int start = 0;
|
||||
|
||||
int length = data.length / zoom;
|
||||
if (zoom != 1) {
|
||||
int mid = data.length / 2 + getCenterOffset();
|
||||
start = mid - length / 2;
|
||||
}
|
||||
|
||||
g.setColor(Color.white);
|
||||
for (int i = 0; i < length - 1; i++) {
|
||||
g.drawLine(i * width / length, (data[start + i] + 128) * height / 256, (i + 1) * width / length,
|
||||
(data[start + i + 1] + 128) * height / 256);
|
||||
}
|
||||
}
|
||||
|
||||
private int getCenterOffset() {
|
||||
return centerOff + movingCenterOff;
|
||||
}
|
||||
|
||||
private enum EnumMouseDrag {
|
||||
NONE, DRAW, MOVE;
|
||||
}
|
||||
|
||||
private class MouseListener extends MouseAdapter {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (e.getButton() != MouseEvent.BUTTON1)
|
||||
return;
|
||||
drawing = true;
|
||||
lastPos = e.getPoint();
|
||||
firePaint(e.getPoint());
|
||||
e.consume();
|
||||
switch (e.getButton()) {
|
||||
case MouseEvent.BUTTON1:
|
||||
mouseDrag = EnumMouseDrag.DRAW;
|
||||
lastPos = e.getPoint();
|
||||
firePaint(e.getPoint());
|
||||
e.consume();
|
||||
break;
|
||||
case MouseEvent.BUTTON3:
|
||||
mouseDrag = EnumMouseDrag.MOVE;
|
||||
lastPos = e.getPoint();
|
||||
e.consume();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (e.getButton() != MouseEvent.BUTTON1)
|
||||
return;
|
||||
firePaint(e.getPoint());
|
||||
drawing = false;
|
||||
lastPos = null;
|
||||
e.consume();
|
||||
switch (e.getButton()) {
|
||||
case MouseEvent.BUTTON1:
|
||||
firePaint(e.getPoint());
|
||||
mouseDrag = EnumMouseDrag.NONE;
|
||||
lastPos = null;
|
||||
e.consume();
|
||||
break;
|
||||
case MouseEvent.BUTTON3:
|
||||
fireMove(e.getPoint());
|
||||
mouseDrag = EnumMouseDrag.NONE;
|
||||
lastPos = null;
|
||||
centerOff += movingCenterOff;
|
||||
movingCenterOff = 0;
|
||||
e.consume();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
if (!drawing)
|
||||
switch (mouseDrag) {
|
||||
case DRAW:
|
||||
firePaint(e.getPoint());
|
||||
e.consume();
|
||||
break;
|
||||
case MOVE:
|
||||
fireMove(e.getPoint());
|
||||
e.consume();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
if (mouseDrag != EnumMouseDrag.NONE)
|
||||
return;
|
||||
firePaint(e.getPoint());
|
||||
e.consume();
|
||||
fireZoom(e.getPoint(), (int) Math.signum(e.getPreciseWheelRotation()));
|
||||
}
|
||||
|
||||
private void firePaint(Point pos) {
|
||||
if (!drawing)
|
||||
if (mouseDrag != EnumMouseDrag.DRAW)
|
||||
return;
|
||||
lastEditedSize = data.length;
|
||||
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
int stepHalfX = width / data.length / 2;
|
||||
int stepHalfY = height / 256 / 2;
|
||||
float stepHalfX = (float) width / data.length * zoom / 2;
|
||||
float stepHalfY = (float) height / 256 / 2;
|
||||
|
||||
if (pos.y < 0)
|
||||
pos.y = 0;
|
||||
@@ -130,8 +186,16 @@ public class DrawingBoard extends JPanel {
|
||||
Point pLow = pos.x < lastPos.x ? pos : lastPos;
|
||||
Point pHigh = pos.x < lastPos.x ? lastPos : pos;
|
||||
|
||||
int lastIdx = (pLow.x + stepHalfX) * data.length / width;
|
||||
int newIdx = (pHigh.x + stepHalfX) * data.length / width;
|
||||
int start = 0;
|
||||
|
||||
int length = data.length / zoom;
|
||||
if (zoom != 1) {
|
||||
int mid = data.length / 2 + getCenterOffset();
|
||||
start = mid - length / 2;
|
||||
}
|
||||
|
||||
int lastIdx = (int) ((pLow.x + stepHalfX) * data.length / zoom / width + start);
|
||||
int newIdx = (int) ((pHigh.x + stepHalfX) * data.length / zoom / width + start);
|
||||
int lastVal = pLow.y;
|
||||
int newVal = pHigh.y;
|
||||
int diffIdx = newIdx - lastIdx + 1;
|
||||
@@ -150,6 +214,60 @@ public class DrawingBoard extends JPanel {
|
||||
lastPos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
private void fireMove(Point pos) {
|
||||
if (mouseDrag != EnumMouseDrag.MOVE)
|
||||
return;
|
||||
|
||||
int width = getWidth();
|
||||
|
||||
int newOff = (int) ((float) (lastPos.x - pos.x) / zoom / ((float) width / data.length));
|
||||
|
||||
int half = data.length / 2;
|
||||
int lowerBound = half / zoom - half - centerOff;
|
||||
int higherBound = data.length - half / zoom - half - centerOff;
|
||||
|
||||
if (newOff < lowerBound) {
|
||||
newOff = lowerBound;
|
||||
} else if (newOff > higherBound) {
|
||||
newOff = higherBound;
|
||||
}
|
||||
|
||||
movingCenterOff = newOff;
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void fireZoom(Point pos, int wheel) {
|
||||
int width = getWidth();
|
||||
|
||||
int oldZoom = zoom;
|
||||
|
||||
if (wheel < 0) {
|
||||
zoom = Math.min(zoom + 1, 32);
|
||||
} else if (wheel > 0) {
|
||||
zoom = Math.max(zoom - 1, 1);
|
||||
}
|
||||
|
||||
if (oldZoom == zoom)
|
||||
return;
|
||||
|
||||
int pseudoMoveOff = (int) ((float) (pos.x - width / 2) / oldZoom / zoom / ((float) width / data.length));
|
||||
centerOff += wheel < 0 ? pseudoMoveOff : -pseudoMoveOff;
|
||||
|
||||
int half = data.length / 2;
|
||||
int lowerBound = half / zoom - half - centerOff;
|
||||
int higherBound = data.length - half / zoom - half - centerOff;
|
||||
|
||||
int newOff = 0;
|
||||
if (lowerBound > 0) {
|
||||
centerOff += lowerBound;
|
||||
} else if (higherBound < 0) {
|
||||
centerOff += higherBound;
|
||||
}
|
||||
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+11
-19
@@ -1,28 +1,20 @@
|
||||
package me.SoundDraw;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Toolkit;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.sound.sampled.LineUnavailableException;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import java.awt.BorderLayout;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.GroupLayout;
|
||||
import javax.swing.GroupLayout.Alignment;
|
||||
import java.awt.FlowLayout;
|
||||
import javax.swing.border.LineBorder;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import java.awt.Color;
|
||||
import javax.swing.SpringLayout;
|
||||
import javax.swing.BoxLayout;
|
||||
import java.awt.Component;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.SpringLayout;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
public class Main {
|
||||
|
||||
@@ -115,8 +107,8 @@ public class Main {
|
||||
sliderLength.setMaximum(SAMPLE_RATE / 100 * 2);
|
||||
sliderLength.setBackground(Color.DARK_GRAY);
|
||||
sliderLength.setSnapToTicks(true);
|
||||
sliderLength.setValue(22);
|
||||
sliderLength.setMinimum(22);
|
||||
sliderLength.setValue(5);
|
||||
sliderLength.setMinimum(5);
|
||||
panelLength.add(sliderLength);
|
||||
sliderLength.setFocusable(false);
|
||||
sliderLength.addChangeListener(e -> {
|
||||
|
||||
Reference in new issue
Block a user