From cb2657a65bceadc0d65eeb0c3e8660e92c317a83 Mon Sep 17 00:00:00 2001 From: hneemann Date: Sat, 24 Oct 2020 11:43:11 +0200 Subject: [PATCH] refactoring of k-map, see #536 --- .../gui/components/karnaugh/KarnaughMap.java | 14 ++- .../karnaugh/KarnaughMapComponent.java | 79 +++++----------- .../gui/components/karnaugh/MapLayout.java | 25 +++-- .../gui/components/karnaugh/VarRectList.java | 91 +++++++++++++++++++ 4 files changed, 141 insertions(+), 68 deletions(-) create mode 100644 src/main/java/de/neemann/digital/gui/components/karnaugh/VarRectList.java diff --git a/src/main/java/de/neemann/digital/gui/components/karnaugh/KarnaughMap.java b/src/main/java/de/neemann/digital/gui/components/karnaugh/KarnaughMap.java index 82126c231..98aae0269 100644 --- a/src/main/java/de/neemann/digital/gui/components/karnaugh/KarnaughMap.java +++ b/src/main/java/de/neemann/digital/gui/components/karnaugh/KarnaughMap.java @@ -50,18 +50,15 @@ public class KarnaughMap implements Iterable { cells = new ArrayList<>(); covers = new ArrayList<>(); - boolean leftMode = mapLayout.getInvert(0); - boolean rightMode = mapLayout.getInvert(1); - boolean topMode = mapLayout.getInvert(2); - boolean bottomMode = mapLayout.getInvert(3); - switch (vars.size()) { case 2: // create the needed KV cells for (int row = 0; row < 2; row++) for (int col = 0; col < 2; col++) cells.add(new Cell(row, col)); + boolean leftMode = mapLayout.getInvert(0); headerLeft = new Header(mapLayout.get(0), !leftMode, leftMode).toRows(2, this); + boolean topMode = mapLayout.getInvert(1); headerTop = new Header(mapLayout.get(1), !topMode, topMode).toCols(2, this); headerRight = null; headerBottom = null; @@ -71,8 +68,11 @@ public class KarnaughMap implements Iterable { for (int col = 0; col < 4; col++) cells.add(new Cell(row, col)); + leftMode = mapLayout.getInvert(0); headerLeft = new Header(mapLayout.get(0), !leftMode, leftMode).toRows(4, this); + topMode = mapLayout.getInvert(1); headerTop = new Header(mapLayout.get(1), !topMode, !topMode, topMode, topMode).toCols(2, this); + boolean bottomMode = mapLayout.getInvert(2); headerBottom = new Header(mapLayout.get(2), !bottomMode, bottomMode, bottomMode, !bottomMode).toCols(2, this); headerRight = null; break; @@ -81,9 +81,13 @@ public class KarnaughMap implements Iterable { for (int col = 0; col < 4; col++) cells.add(new Cell(row, col)); + leftMode = mapLayout.getInvert(0); headerLeft = new Header(mapLayout.get(0), !leftMode, !leftMode, leftMode, leftMode).toRows(4, this); + boolean rightMode = mapLayout.getInvert(1); headerRight = new Header(mapLayout.get(1), !rightMode, rightMode, rightMode, !rightMode).toRows(4, this); + topMode = mapLayout.getInvert(2); headerTop = new Header(mapLayout.get(2), !topMode, !topMode, topMode, topMode).toCols(4, this); + bottomMode = mapLayout.getInvert(3); headerBottom = new Header(mapLayout.get(3), !bottomMode, bottomMode, bottomMode, !bottomMode).toCols(4, this); break; default: diff --git a/src/main/java/de/neemann/digital/gui/components/karnaugh/KarnaughMapComponent.java b/src/main/java/de/neemann/digital/gui/components/karnaugh/KarnaughMapComponent.java index 8951bc0ec..d55054580 100644 --- a/src/main/java/de/neemann/digital/gui/components/karnaugh/KarnaughMapComponent.java +++ b/src/main/java/de/neemann/digital/gui/components/karnaugh/KarnaughMapComponent.java @@ -38,14 +38,14 @@ public class KarnaughMapComponent extends JComponent { private Graphics2D gr; private String message = Lang.get("msg_noKVMapAvailable"); private final MapLayout mapLayout = new MapLayout(0); - private final ArrayList varPosList = new ArrayList<>(); + private final VarRectList varRectList = new VarRectList(); private int xOffs; private int yOffs; private int cellSize; private int xDrag; private int yDrag; - private VarRect startVarRect = null; + private VarRectList.VarRect startVarRect = null; /** * Creates a new instance @@ -97,7 +97,6 @@ public class KarnaughMapComponent extends JComponent { @Override protected void paintComponent(Graphics graphics) { - varPosList.clear(); gr = (Graphics2D) graphics; gr.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); gr.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); @@ -109,9 +108,6 @@ public class KarnaughMapComponent extends JComponent { gr.fillRect(0, 0, width, height); gr.setColor(Color.BLACK); - if (startVarRect != null) - startVarRect.fragment.draw(gr, xDrag, yDrag); - if (kv != null) { AffineTransform trans = gr.getTransform(); // store the old transform @@ -166,6 +162,9 @@ public class KarnaughMapComponent extends JComponent { (cell.getRow() + 2) * cellSize - 1); } + // remove old var rectangles + varRectList.reset(xOffs, yOffs); + // draw the text in the borders gr.setColor(Color.BLACK); gr.setFont(headerFont); @@ -214,6 +213,11 @@ public class KarnaughMapComponent extends JComponent { gr.setTransform(trans); } else gr.drawString(message, 10, 20); + + if (startVarRect != null) { + gr.setColor(Color.BLACK); + startVarRect.getFragment().draw(gr, xDrag, yDrag); + } } private boolean isNoHeaderLine(KarnaughMap.Header header, int i) { @@ -232,7 +236,8 @@ public class KarnaughMapComponent extends JComponent { dx = cellSize / 2; } int var = header.getVar(); - drawFragment(getFragment(var, header.getInvert(i)), i + 1, pos, dx, 0, var); + boolean invert = header.getInvert(i); + drawFragment(var, invert, i + 1, pos, dx, 0); } } @@ -245,7 +250,8 @@ public class KarnaughMapComponent extends JComponent { dy = cellSize / 2; } int var = header.getVar(); - drawFragment(getFragment(var, header.getInvert(i)), pos, i + 1, 0, dy, var); + boolean invert = header.getInvert(i); + drawFragment(var, invert, pos, i + 1, 0, dy); } } //CHECKSTYLE.ON: ModifiedControlVariable @@ -258,7 +264,8 @@ public class KarnaughMapComponent extends JComponent { gr.drawString(s, row * cellSize + xPos, col * cellSize + yPos); } - private void drawFragment(GraphicsFormatter.Fragment fr, int row, int col, int xOffs, int yOffs, int var) { + private void drawFragment(int var, boolean invert, int row, int col, int xOffs, int yOffs) { + GraphicsFormatter.Fragment fr = getFragment(var, invert); if (fr == null) return; FontMetrics fontMetrics = gr.getFontMetrics(); @@ -267,7 +274,10 @@ public class KarnaughMapComponent extends JComponent { int xFr = row * cellSize + xPos - xOffs; int yFr = col * cellSize + yPos - yOffs; fr.draw(gr, xFr, yFr); - varPosList.add(new VarRect(var, xFr, yFr + fontMetrics.getDescent() - fr.getHeight(), fr.getWidth(), fr.getHeight(), fr)); + + // register fragment for drag&drop action + Rectangle r = new Rectangle(xFr, yFr + fontMetrics.getDescent() - fr.getHeight(), fr.getWidth(), fr.getHeight()); + varRectList.add(var, invert, r, fr); } private GraphicsFormatter.Fragment getFragment(int var, boolean invert) { @@ -311,19 +321,13 @@ public class KarnaughMapComponent extends JComponent { if (x >= 0 && x < kv.getColumns() && y >= 0 && y < kv.getRows()) { int row = kv.getCell(y, x).getBoolTableRow(); tableCellModifier.modify(boolTable, row); - } else { - VarRect varAt = findVarRect(mouseEvent); - if (varAt != null) { - mapLayout.toggleInvertByMouse(varAt.var); - update(); - } } } } @Override public void mousePressed(MouseEvent e) { - startVarRect = findVarRect(e); + startVarRect = varRectList.findVarRect(e); } @Override @@ -337,45 +341,12 @@ public class KarnaughMapComponent extends JComponent { @Override public void mouseReleased(MouseEvent e) { - VarRect endVarRect = findVarRect(e); - if (startVarRect != null && endVarRect != null - && startVarRect.isValid(vars.size()) - && endVarRect.isValid(vars.size()) - && startVarRect.var != endVarRect.var) { - mapLayout.swapByMouse(startVarRect.var, endVarRect.var); - startVarRect = null; + VarRectList.VarRect endVarRect = varRectList.findVarRect(e); + if (mapLayout.swapByDragAndDrop(startVarRect, endVarRect)) update(); - } else { - startVarRect = null; + else repaint(); - } + startVarRect = null; } } - - private VarRect findVarRect(MouseEvent e) { - int x = e.getX() - xOffs; - int y = e.getY() - yOffs; - for (VarRect r : varPosList) { - if (r.rect.contains(x, y)) - return r; - } - return null; - } - - private static final class VarRect { - private final Rectangle rect; - private final int var; - private final GraphicsFormatter.Fragment fragment; - - private VarRect(int var, int x, int y, int width, int height, GraphicsFormatter.Fragment fragment) { - this.var = var; - rect = new Rectangle(x, y, width, height); - this.fragment = fragment; - } - - private boolean isValid(int size) { - return var >= 0 && var < size; - } - } - } diff --git a/src/main/java/de/neemann/digital/gui/components/karnaugh/MapLayout.java b/src/main/java/de/neemann/digital/gui/components/karnaugh/MapLayout.java index 439951667..5c8f8c205 100644 --- a/src/main/java/de/neemann/digital/gui/components/karnaugh/MapLayout.java +++ b/src/main/java/de/neemann/digital/gui/components/karnaugh/MapLayout.java @@ -23,12 +23,16 @@ public class MapLayout { return -1; } - void swapVars(int startVar, int endVar) { + private void swapVars(int startVar, int endVar) { int t = swap[startVar]; swap[startVar] = swap[endVar]; swap[endVar] = t; } + private void toggleInvert(int n) { + mode ^= (1 << n); + } + /** * Checks is the given swap list is valid (not null and of the correct size). * If so, the given list is preserved, if not, a simple, non swapping default swap @@ -45,16 +49,19 @@ public class MapLayout { mode = 0; } - void swapByMouse(int startVar, int endVar) { - swapVars(indexOf(startVar), indexOf(endVar)); - } + boolean swapByDragAndDrop(VarRectList.VarRect startVar, VarRectList.VarRect endVar) { + if (startVar == null || endVar == null || startVar.equals(endVar)) + return false; - void toggleInvert(int n) { - mode ^= (1 << n); - } + int start = indexOf(startVar.getVar()); + int end = indexOf(endVar.getVar()); + if (start != end) + swapVars(start, end); - void toggleInvertByMouse(int n) { - toggleInvert(indexOf(n)); + if (startVar.getInvert() != endVar.getInvert()) + toggleInvert(end); + + return true; } boolean getInvert(int n) { diff --git a/src/main/java/de/neemann/digital/gui/components/karnaugh/VarRectList.java b/src/main/java/de/neemann/digital/gui/components/karnaugh/VarRectList.java new file mode 100644 index 000000000..ab1f20cba --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/components/karnaugh/VarRectList.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2020 Helmut Neemann. + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +package de.neemann.digital.gui.components.karnaugh; + +import de.neemann.digital.draw.graphics.text.formatter.GraphicsFormatter; + +import java.awt.*; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Objects; + +final class VarRectList { + private final ArrayList varRectList; + private int xOffs; + private int yOffs; + + VarRectList() { + varRectList = new ArrayList<>(); + } + + public void reset(int xOffs, int yOffs) { + this.xOffs = xOffs; + this.yOffs = yOffs; + varRectList.clear(); + } + + public void add(int var, boolean invert, Rectangle r, GraphicsFormatter.Fragment fr) { + varRectList.add(new VarRect(var, invert, r, fr)); + } + + VarRect findVarRect(MouseEvent e) { + int x = e.getX() - xOffs; + int y = e.getY() - yOffs; + for (VarRect r : varRectList) { + if (r.rect.contains(x, y)) + return r; + } + return null; + } + + static final class VarRect { + private final boolean invert; + private final Rectangle rect; + private final int var; + private final GraphicsFormatter.Fragment fragment; + + private VarRect(int var, boolean invert, Rectangle rect, GraphicsFormatter.Fragment fragment) { + this.var = var; + this.invert = invert; + this.rect = rect; + this.fragment = fragment; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + VarRect varRect = (VarRect) o; + return invert == varRect.invert && var == varRect.var; + } + + @Override + public int hashCode() { + return Objects.hash(invert, var); + } + + int getVar() { + return var; + } + + boolean getInvert() { + return invert; + } + + GraphicsFormatter.Fragment getFragment() { + return fragment; + } + + @Override + public String toString() { + return "VarRect{" + + "invert=" + + invert + + ", var=" + var + + '}'; + } + } +}