mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-19 22:35:35 +00:00
Added: Display grid, snap to grid
This commit is contained in:
@@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file.
|
||||
- Objects dragging - show touch point and snap it to 9 important points around object rectangle
|
||||
- [#2370] Snap to guides, objects and pixels, Snap align, toggle with magnet icon
|
||||
- [#2370] Show/Hide guides, lock guides, clear guides actions from icon menu
|
||||
- Display grid, snap to grid
|
||||
|
||||
### Fixed
|
||||
- [#2424] DefineEditText handling of letterSpacing, font size on incorrect values
|
||||
|
||||
@@ -1081,6 +1081,26 @@ public final class Configuration {
|
||||
@ConfigurationCategory("display")
|
||||
public static ConfigurationItem<Boolean> lockGuides = null;
|
||||
|
||||
@ConfigurationDefaultBoolean(false)
|
||||
@ConfigurationCategory("display")
|
||||
public static ConfigurationItem<Boolean> showGrid = null;
|
||||
|
||||
@ConfigurationDefaultInt(10)
|
||||
@ConfigurationCategory("display")
|
||||
public static ConfigurationItem<Integer> gridVerticalSpace = null;
|
||||
|
||||
@ConfigurationDefaultInt(10)
|
||||
@ConfigurationCategory("display")
|
||||
public static ConfigurationItem<Integer> gridHorizontalSpace = null;
|
||||
|
||||
@ConfigurationDefaultBoolean(false)
|
||||
@ConfigurationCategory("display")
|
||||
public static ConfigurationItem<Boolean> snapToGrid = null;
|
||||
|
||||
@ConfigurationDefaultBoolean(false)
|
||||
@ConfigurationCategory("display")
|
||||
public static ConfigurationItem<Boolean> gridOverObjects = null;
|
||||
|
||||
private enum OSId {
|
||||
WINDOWS, OSX, UNIX
|
||||
}
|
||||
|
||||
@@ -910,6 +910,54 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
public void setResample(boolean resample) {
|
||||
this.resample = resample;
|
||||
}
|
||||
|
||||
private static void drawGridSwf(Graphics2D g, Rectangle realRect, double zoom) {
|
||||
g.setColor(new Color(0x94, 0x94, 0x94));
|
||||
double x;
|
||||
double y;
|
||||
int ix;
|
||||
int iy;
|
||||
int minIx = 0;
|
||||
int minIy = 0;
|
||||
int maxIx;
|
||||
int maxIy;
|
||||
|
||||
ix = 0;
|
||||
while ((double) realRect.x + ix * Configuration.gridHorizontalSpace.get() * zoom < realRect.getMaxX()) {
|
||||
ix++;
|
||||
}
|
||||
maxIx = ix;
|
||||
|
||||
iy = 0;
|
||||
while ((double) realRect.y + iy * Configuration.gridVerticalSpace.get() * zoom < realRect.getMaxY()) {
|
||||
iy++;
|
||||
}
|
||||
maxIy = iy;
|
||||
|
||||
for (ix = minIx; ix <= maxIx; ix++) {
|
||||
x = realRect.x + ix * Configuration.gridHorizontalSpace.get() * zoom;
|
||||
Point2D p1 = new Point2D.Double(x, realRect.y + minIy * Configuration.gridVerticalSpace.get() * zoom);
|
||||
Point2D p2 = new Point2D.Double(x, realRect.y + maxIy * Configuration.gridVerticalSpace.get() * zoom);
|
||||
g.drawLine(
|
||||
(int) Math.round(p1.getX()),
|
||||
(int) Math.round(p1.getY()),
|
||||
(int) Math.round(p2.getX()),
|
||||
(int) Math.round(p2.getY())
|
||||
);
|
||||
}
|
||||
|
||||
for (iy = minIy; iy <= maxIy; iy++) {
|
||||
y = realRect.y + iy * Configuration.gridVerticalSpace.get() * zoom;
|
||||
Point2D p1 = new Point2D.Double(realRect.x + minIx * Configuration.gridHorizontalSpace.get() * zoom, y);
|
||||
Point2D p2 = new Point2D.Double(realRect.x + maxIx * Configuration.gridHorizontalSpace.get() * zoom, y);
|
||||
g.drawLine(
|
||||
(int) Math.round(p1.getX()),
|
||||
(int) Math.round(p1.getY()),
|
||||
(int) Math.round(p2.getX()),
|
||||
(int) Math.round(p2.getY())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private class IconPanel extends JPanel {
|
||||
|
||||
@@ -959,7 +1007,69 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
return allowMove;
|
||||
}
|
||||
|
||||
VolatileImage renderImage;
|
||||
VolatileImage renderImage;
|
||||
|
||||
private void drawGridNoSwf(Graphics2D g2, int x, int y) {
|
||||
double zoomDouble = getRealZoom();
|
||||
g2.setColor(new Color(0x94, 0x94, 0x94));
|
||||
double gx;
|
||||
double gy;
|
||||
int ix = 0;
|
||||
int iy = 0;
|
||||
int minIx;
|
||||
int minIy;
|
||||
int maxIx;
|
||||
int maxIy;
|
||||
double sx = x + offsetPoint.getX();
|
||||
double sy = y + offsetPoint.getY();
|
||||
|
||||
while (sx + ix * Configuration.gridHorizontalSpace.get() * zoomDouble > 0) {
|
||||
ix--;
|
||||
}
|
||||
minIx = ix;
|
||||
ix = 0;
|
||||
while (sx + ix * Configuration.gridHorizontalSpace.get() * zoomDouble < getWidth()) {
|
||||
ix++;
|
||||
}
|
||||
maxIx = ix;
|
||||
|
||||
while (sy + iy * Configuration.gridVerticalSpace.get() * zoomDouble > 0) {
|
||||
iy--;
|
||||
}
|
||||
minIy = iy;
|
||||
|
||||
iy = 0;
|
||||
while (sy + iy * Configuration.gridVerticalSpace.get() * zoomDouble < getHeight()) {
|
||||
iy++;
|
||||
}
|
||||
maxIy = iy;
|
||||
|
||||
for (ix = minIx; ix <= maxIx; ix++) {
|
||||
gx = sx + ix * Configuration.gridHorizontalSpace.get() * zoomDouble;
|
||||
|
||||
Point2D p1 = new Point2D.Double(gx, sy + minIy * Configuration.gridVerticalSpace.get() * zoomDouble);
|
||||
Point2D p2 = new Point2D.Double(gx, sy + maxIy * Configuration.gridVerticalSpace.get() * zoomDouble);
|
||||
g2.drawLine(
|
||||
(int) Math.round(p1.getX()),
|
||||
(int) Math.round(p1.getY()),
|
||||
(int) Math.round(p2.getX()),
|
||||
(int) Math.round(p2.getY())
|
||||
);
|
||||
}
|
||||
|
||||
for (iy = minIy; iy <= maxIy; iy++) {
|
||||
gy = sy + iy * Configuration.gridVerticalSpace.get() * zoomDouble;
|
||||
|
||||
Point2D p1 = new Point2D.Double(sx + minIx * Configuration.gridHorizontalSpace.get() * zoomDouble, gy);
|
||||
Point2D p2 = new Point2D.Double(sx + maxIx * Configuration.gridHorizontalSpace.get() * zoomDouble, gy);
|
||||
g2.drawLine(
|
||||
(int) Math.round(p1.getX()),
|
||||
(int) Math.round(p1.getY()),
|
||||
(int) Math.round(p2.getX()),
|
||||
(int) Math.round(p2.getY())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void render() {
|
||||
SerializableImage img = getImg();
|
||||
@@ -1001,8 +1111,18 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
y = (int) offsetPoint.getY();
|
||||
}
|
||||
|
||||
double zoomDouble = zoom.fit ? getZoomToFit() : zoom.value;
|
||||
|
||||
if (Configuration.showGrid.get() && !(timelined instanceof SWF) && !Configuration.gridOverObjects.get()) {
|
||||
drawGridNoSwf(g2, x, y);
|
||||
}
|
||||
|
||||
g2.drawImage(img.getBufferedImage(), x, y, x + img.getWidth(), y + img.getHeight(), 0, 0, img.getWidth(), img.getHeight(), null);
|
||||
|
||||
if (Configuration.showGrid.get() && !(timelined instanceof SWF) && Configuration.gridOverObjects.get()) {
|
||||
drawGridNoSwf(g2, x, y);
|
||||
}
|
||||
|
||||
if (hilightedEdge != null || hilightedPoints != null) {
|
||||
hilightEdgeColor += hilightEdgeColorStep;
|
||||
if (hilightEdgeColor < 100 || hilightEdgeColor > 255) {
|
||||
@@ -1010,7 +1130,6 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
hilightEdgeColor += hilightEdgeColorStep * 2;
|
||||
}
|
||||
RECT timRect = timelined.getRect();
|
||||
double zoomDouble = zoom.fit ? getZoomToFit() : zoom.value;
|
||||
AffineTransform trans = new AffineTransform();
|
||||
trans.translate(offsetPoint.getX(), offsetPoint.getY());
|
||||
trans.scale(1 / SWF.unitDivisor, 1 / SWF.unitDivisor);
|
||||
@@ -1104,7 +1223,6 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
if (!(timelined instanceof SWF) && (doFreeTransform || hilightedPoints != null)) {
|
||||
int axisX = 0;
|
||||
int axisY = 0;
|
||||
double zoomDouble = zoom.fit ? getZoomToFit() : zoom.value;
|
||||
RECT timRect = timelined.getRect();
|
||||
axisX = (int) Math.round(offsetPoint.getX());
|
||||
axisY = (int) Math.round(offsetPoint.getY());
|
||||
@@ -2174,6 +2292,27 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
}
|
||||
}
|
||||
|
||||
if (Configuration.showGrid.get() && Configuration.snapToGrid.get()) {
|
||||
if (snapOffsetX == null) {
|
||||
int positionPxX = (int) Math.round((touchPointPos.getX() - offsetPoint.getX()) / zoomDouble);
|
||||
int d = (positionPxX / Configuration.gridHorizontalSpace.get()) * Configuration.gridHorizontalSpace.get();
|
||||
if ((positionPxX - d) * zoomDouble < SNAP_DISTANCE) {
|
||||
snapOffsetX = d * zoomDouble - touchPointPos.getX() + offsetPoint.getX();
|
||||
} else if ((d + Configuration.gridHorizontalSpace.get() - positionPxX) * zoomDouble < SNAP_DISTANCE) {
|
||||
snapOffsetX = (d + Configuration.gridHorizontalSpace.get()) * zoomDouble - touchPointPos.getX() + offsetPoint.getX();
|
||||
}
|
||||
}
|
||||
if (snapOffsetY == null) {
|
||||
int positionPxY = (int) Math.round((touchPointPos.getY() - offsetPoint.getY()) / zoomDouble);
|
||||
int d = (positionPxY / Configuration.gridVerticalSpace.get()) * Configuration.gridVerticalSpace.get();
|
||||
if ((positionPxY - d) * zoomDouble < SNAP_DISTANCE) {
|
||||
snapOffsetY = d * zoomDouble - touchPointPos.getY() + offsetPoint.getY();
|
||||
} else if ((d + Configuration.gridVerticalSpace.get() - positionPxY) * zoomDouble < SNAP_DISTANCE) {
|
||||
snapOffsetY = (d + Configuration.gridVerticalSpace.get()) * zoomDouble - touchPointPos.getY() + offsetPoint.getY();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Configuration.snapToPixels.get()) {
|
||||
if (snapOffsetX == null) {
|
||||
int positionPxX = (int) Math.round((touchPointPos.getX() - offsetPoint.getX()) / zoomDouble);
|
||||
@@ -4633,6 +4772,11 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
g.fillRect(realRect.x, realRect.y, realRect.width, realRect.height);
|
||||
}
|
||||
|
||||
if (Configuration.showGrid.get() && (drawable instanceof SWF) && !Configuration.gridOverObjects.get()) {
|
||||
Graphics2D g = (Graphics2D) image.getBufferedImage().getGraphics();
|
||||
drawGridSwf(g, realRect, zoom);
|
||||
}
|
||||
|
||||
parentMatrix = new Matrix();
|
||||
List<Integer> ignoreDepths = new ArrayList<>();
|
||||
for (int i = 0; i < parentTimelineds.size(); i++) {
|
||||
@@ -4774,6 +4918,13 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Configuration.showGrid.get() && (drawable instanceof SWF) && Configuration.gridOverObjects.get()) {
|
||||
Graphics2D g = (Graphics2D) image.getBufferedImage().getGraphics();
|
||||
drawGridSwf(g, realRect, zoom);
|
||||
}
|
||||
|
||||
img = image;
|
||||
|
||||
/*if (shouldCache) {
|
||||
|
||||
@@ -50,6 +50,11 @@ public class SnapOptionsButton extends PopupButton {
|
||||
snapAlignMenuItem.addActionListener(this::snapAlignMenuItemActionPerformed);
|
||||
popupMenu.add(snapAlignMenuItem);
|
||||
|
||||
JCheckBox snapToGridMenuItem = new JCheckBox(AppStrings.translate("snap_options.snap_to_grid"));
|
||||
snapToGridMenuItem.setSelected(Configuration.snapToGrid.get());
|
||||
snapToGridMenuItem.addActionListener(this::snapToGridMenuItemActionPerformed);
|
||||
popupMenu.add(snapToGridMenuItem);
|
||||
|
||||
JCheckBox snapToGuidesMenuItem = new JCheckBox(AppStrings.translate("snap_options.snap_to_guides"));
|
||||
snapToGuidesMenuItem.setSelected(Configuration.snapToGuides.get());
|
||||
snapToGuidesMenuItem.addActionListener(this::snapToGuidesMenuItemActionPerformed);
|
||||
@@ -73,6 +78,11 @@ public class SnapOptionsButton extends PopupButton {
|
||||
Configuration.snapAlign.set(menuItem.isSelected());
|
||||
}
|
||||
|
||||
private void snapToGridMenuItemActionPerformed(ActionEvent evt) {
|
||||
JCheckBox menuItem = (JCheckBox) evt.getSource();
|
||||
Configuration.snapToGrid.set(menuItem.isSelected());
|
||||
}
|
||||
|
||||
private void snapToGuidesMenuItemActionPerformed(ActionEvent evt) {
|
||||
JCheckBox menuItem = (JCheckBox) evt.getSource();
|
||||
Configuration.snapToGuides.set(menuItem.isSelected());
|
||||
|
||||
BIN
src/com/jpexs/decompiler/flash/gui/graphics/grid16.png
Normal file
BIN
src/com/jpexs/decompiler/flash/gui/graphics/grid16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
@@ -577,3 +577,19 @@ config.description.showGuides = Set this to false to hide guides.
|
||||
|
||||
config.name.lockGuides = Lock guides
|
||||
config.description.lockGuides = Disables moving of guides so they stay in position and cannot be moved.
|
||||
|
||||
config.name.showGrid = Show grid
|
||||
config.description.showGrid = Shows grid on stage
|
||||
|
||||
config.name.gridVerticalSpace = Grid vertical spacing (px)
|
||||
config.description.gridVerticalSpace = Vertical space between grid lines in pixels.
|
||||
|
||||
config.name.gridHorizontalSpace = Grid horizontal spacing (px)
|
||||
config.description.gridHorizontalSpace = Horizontal space between grid lines in pixels.
|
||||
|
||||
config.name.snapToGrid = Snap to grid
|
||||
config.description.snapToGrid = Enables snapping cursor to grid while moving objects.
|
||||
|
||||
config.name.gridOverObjects = Show grid over objects
|
||||
config.description.gridOverObjects = When the grid is displayed, it is shown over objects on stage.
|
||||
|
||||
|
||||
@@ -1025,6 +1025,7 @@ filter.swf_spl = SWF files (*.swf, *.spl)
|
||||
#after 22.0.2
|
||||
button.snap_options = Snap options
|
||||
snap_options.snap_align = Snap Align
|
||||
snap_options.snap_to_grid = Snap to Grid
|
||||
snap_options.snap_to_guides = Snap to Guides
|
||||
snap_options.snap_to_pixels = Snap to Pixels
|
||||
snap_options.snap_to_objects = Snap to Objects
|
||||
@@ -1034,4 +1035,6 @@ button.ruler.hint = Toggle ruler display
|
||||
button.guides_options.hint = Guides options
|
||||
guides_options.show = Show guides
|
||||
guides_options.lock = Lock guides
|
||||
guides_options.clear = Clear guides
|
||||
guides_options.clear = Clear guides
|
||||
|
||||
button.grid.hint = Toggle grid display
|
||||
@@ -105,6 +105,18 @@ public class ZoomPanel extends JPanel implements MediaDisplayListener {
|
||||
guidesOptionsButton.setToolTipText(AppStrings.translate("button.guides_options.hint"));
|
||||
|
||||
snapOptionsButton = new SnapOptionsButton();
|
||||
|
||||
JToggleButton gridButton = new JToggleButton(View.getIcon("grid16"));
|
||||
gridButton.addActionListener(this::gridButtonActionPerformed);
|
||||
gridButton.setToolTipText(AppStrings.translate("button.grid.hint"));
|
||||
gridButton.setSelected(Configuration.showGrid.get());
|
||||
Configuration.showGrid.addListener(new ConfigurationItemChangeListener<Boolean>() {
|
||||
@Override
|
||||
public void configurationItemChanged(Boolean newValue) {
|
||||
gridButton.setSelected(newValue);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
setLayout(new FlowLayout());
|
||||
add(percentLabel);
|
||||
@@ -113,11 +125,17 @@ public class ZoomPanel extends JPanel implements MediaDisplayListener {
|
||||
add(zoomNoneButton);
|
||||
add(zoomFitButton);
|
||||
add(rulerButton);
|
||||
add(gridButton);
|
||||
add(guidesOptionsButton);
|
||||
add(snapOptionsButton);
|
||||
|
||||
display.addEventListener(this);
|
||||
}
|
||||
|
||||
private void gridButtonActionPerformed(ActionEvent evt) {
|
||||
JToggleButton source = (JToggleButton) evt.getSource();
|
||||
Configuration.showGrid.set(source.isSelected());
|
||||
}
|
||||
|
||||
private void guidesShowActionPerformed(ActionEvent evt) {
|
||||
JCheckBoxMenuItem source = (JCheckBoxMenuItem) evt.getSource();
|
||||
|
||||
Reference in New Issue
Block a user