mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-15 15:58:41 -04:00
refactoring of k-map, see #536
This commit is contained in:
parent
9e478d9f5a
commit
cb2657a65b
@ -50,18 +50,15 @@ public class KarnaughMap implements Iterable<KarnaughMap.Cover> {
|
|||||||
cells = new ArrayList<>();
|
cells = new ArrayList<>();
|
||||||
covers = 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()) {
|
switch (vars.size()) {
|
||||||
case 2: // create the needed KV cells
|
case 2: // create the needed KV cells
|
||||||
for (int row = 0; row < 2; row++)
|
for (int row = 0; row < 2; row++)
|
||||||
for (int col = 0; col < 2; col++)
|
for (int col = 0; col < 2; col++)
|
||||||
cells.add(new Cell(row, col));
|
cells.add(new Cell(row, col));
|
||||||
|
|
||||||
|
boolean leftMode = mapLayout.getInvert(0);
|
||||||
headerLeft = new Header(mapLayout.get(0), !leftMode, leftMode).toRows(2, this);
|
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);
|
headerTop = new Header(mapLayout.get(1), !topMode, topMode).toCols(2, this);
|
||||||
headerRight = null;
|
headerRight = null;
|
||||||
headerBottom = null;
|
headerBottom = null;
|
||||||
@ -71,8 +68,11 @@ public class KarnaughMap implements Iterable<KarnaughMap.Cover> {
|
|||||||
for (int col = 0; col < 4; col++)
|
for (int col = 0; col < 4; col++)
|
||||||
cells.add(new Cell(row, col));
|
cells.add(new Cell(row, col));
|
||||||
|
|
||||||
|
leftMode = mapLayout.getInvert(0);
|
||||||
headerLeft = new Header(mapLayout.get(0), !leftMode, leftMode).toRows(4, this);
|
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);
|
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);
|
headerBottom = new Header(mapLayout.get(2), !bottomMode, bottomMode, bottomMode, !bottomMode).toCols(2, this);
|
||||||
headerRight = null;
|
headerRight = null;
|
||||||
break;
|
break;
|
||||||
@ -81,9 +81,13 @@ public class KarnaughMap implements Iterable<KarnaughMap.Cover> {
|
|||||||
for (int col = 0; col < 4; col++)
|
for (int col = 0; col < 4; col++)
|
||||||
cells.add(new Cell(row, col));
|
cells.add(new Cell(row, col));
|
||||||
|
|
||||||
|
leftMode = mapLayout.getInvert(0);
|
||||||
headerLeft = new Header(mapLayout.get(0), !leftMode, !leftMode, leftMode, leftMode).toRows(4, this);
|
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);
|
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);
|
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);
|
headerBottom = new Header(mapLayout.get(3), !bottomMode, bottomMode, bottomMode, !bottomMode).toCols(4, this);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -38,14 +38,14 @@ public class KarnaughMapComponent extends JComponent {
|
|||||||
private Graphics2D gr;
|
private Graphics2D gr;
|
||||||
private String message = Lang.get("msg_noKVMapAvailable");
|
private String message = Lang.get("msg_noKVMapAvailable");
|
||||||
private final MapLayout mapLayout = new MapLayout(0);
|
private final MapLayout mapLayout = new MapLayout(0);
|
||||||
private final ArrayList<VarRect> varPosList = new ArrayList<>();
|
private final VarRectList varRectList = new VarRectList();
|
||||||
|
|
||||||
private int xOffs;
|
private int xOffs;
|
||||||
private int yOffs;
|
private int yOffs;
|
||||||
private int cellSize;
|
private int cellSize;
|
||||||
private int xDrag;
|
private int xDrag;
|
||||||
private int yDrag;
|
private int yDrag;
|
||||||
private VarRect startVarRect = null;
|
private VarRectList.VarRect startVarRect = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance
|
* Creates a new instance
|
||||||
@ -97,7 +97,6 @@ public class KarnaughMapComponent extends JComponent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintComponent(Graphics graphics) {
|
protected void paintComponent(Graphics graphics) {
|
||||||
varPosList.clear();
|
|
||||||
gr = (Graphics2D) graphics;
|
gr = (Graphics2D) graphics;
|
||||||
gr.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
gr.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||||
gr.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
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.fillRect(0, 0, width, height);
|
||||||
gr.setColor(Color.BLACK);
|
gr.setColor(Color.BLACK);
|
||||||
|
|
||||||
if (startVarRect != null)
|
|
||||||
startVarRect.fragment.draw(gr, xDrag, yDrag);
|
|
||||||
|
|
||||||
if (kv != null) {
|
if (kv != null) {
|
||||||
AffineTransform trans = gr.getTransform(); // store the old transform
|
AffineTransform trans = gr.getTransform(); // store the old transform
|
||||||
|
|
||||||
@ -166,6 +162,9 @@ public class KarnaughMapComponent extends JComponent {
|
|||||||
(cell.getRow() + 2) * cellSize - 1);
|
(cell.getRow() + 2) * cellSize - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove old var rectangles
|
||||||
|
varRectList.reset(xOffs, yOffs);
|
||||||
|
|
||||||
// draw the text in the borders
|
// draw the text in the borders
|
||||||
gr.setColor(Color.BLACK);
|
gr.setColor(Color.BLACK);
|
||||||
gr.setFont(headerFont);
|
gr.setFont(headerFont);
|
||||||
@ -214,6 +213,11 @@ public class KarnaughMapComponent extends JComponent {
|
|||||||
gr.setTransform(trans);
|
gr.setTransform(trans);
|
||||||
} else
|
} else
|
||||||
gr.drawString(message, 10, 20);
|
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) {
|
private boolean isNoHeaderLine(KarnaughMap.Header header, int i) {
|
||||||
@ -232,7 +236,8 @@ public class KarnaughMapComponent extends JComponent {
|
|||||||
dx = cellSize / 2;
|
dx = cellSize / 2;
|
||||||
}
|
}
|
||||||
int var = header.getVar();
|
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;
|
dy = cellSize / 2;
|
||||||
}
|
}
|
||||||
int var = header.getVar();
|
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
|
//CHECKSTYLE.ON: ModifiedControlVariable
|
||||||
@ -258,7 +264,8 @@ public class KarnaughMapComponent extends JComponent {
|
|||||||
gr.drawString(s, row * cellSize + xPos, col * cellSize + yPos);
|
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)
|
if (fr == null)
|
||||||
return;
|
return;
|
||||||
FontMetrics fontMetrics = gr.getFontMetrics();
|
FontMetrics fontMetrics = gr.getFontMetrics();
|
||||||
@ -267,7 +274,10 @@ public class KarnaughMapComponent extends JComponent {
|
|||||||
int xFr = row * cellSize + xPos - xOffs;
|
int xFr = row * cellSize + xPos - xOffs;
|
||||||
int yFr = col * cellSize + yPos - yOffs;
|
int yFr = col * cellSize + yPos - yOffs;
|
||||||
fr.draw(gr, xFr, yFr);
|
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) {
|
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()) {
|
if (x >= 0 && x < kv.getColumns() && y >= 0 && y < kv.getRows()) {
|
||||||
int row = kv.getCell(y, x).getBoolTableRow();
|
int row = kv.getCell(y, x).getBoolTableRow();
|
||||||
tableCellModifier.modify(boolTable, row);
|
tableCellModifier.modify(boolTable, row);
|
||||||
} else {
|
|
||||||
VarRect varAt = findVarRect(mouseEvent);
|
|
||||||
if (varAt != null) {
|
|
||||||
mapLayout.toggleInvertByMouse(varAt.var);
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
startVarRect = findVarRect(e);
|
startVarRect = varRectList.findVarRect(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -337,45 +341,12 @@ public class KarnaughMapComponent extends JComponent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseReleased(MouseEvent e) {
|
public void mouseReleased(MouseEvent e) {
|
||||||
VarRect endVarRect = findVarRect(e);
|
VarRectList.VarRect endVarRect = varRectList.findVarRect(e);
|
||||||
if (startVarRect != null && endVarRect != null
|
if (mapLayout.swapByDragAndDrop(startVarRect, endVarRect))
|
||||||
&& startVarRect.isValid(vars.size())
|
|
||||||
&& endVarRect.isValid(vars.size())
|
|
||||||
&& startVarRect.var != endVarRect.var) {
|
|
||||||
mapLayout.swapByMouse(startVarRect.var, endVarRect.var);
|
|
||||||
startVarRect = null;
|
|
||||||
update();
|
update();
|
||||||
} else {
|
else
|
||||||
startVarRect = null;
|
|
||||||
repaint();
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,16 @@ public class MapLayout {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swapVars(int startVar, int endVar) {
|
private void swapVars(int startVar, int endVar) {
|
||||||
int t = swap[startVar];
|
int t = swap[startVar];
|
||||||
swap[startVar] = swap[endVar];
|
swap[startVar] = swap[endVar];
|
||||||
swap[endVar] = t;
|
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).
|
* 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
|
* If so, the given list is preserved, if not, a simple, non swapping default swap
|
||||||
@ -45,16 +49,19 @@ public class MapLayout {
|
|||||||
mode = 0;
|
mode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swapByMouse(int startVar, int endVar) {
|
boolean swapByDragAndDrop(VarRectList.VarRect startVar, VarRectList.VarRect endVar) {
|
||||||
swapVars(indexOf(startVar), indexOf(endVar));
|
if (startVar == null || endVar == null || startVar.equals(endVar))
|
||||||
}
|
return false;
|
||||||
|
|
||||||
void toggleInvert(int n) {
|
int start = indexOf(startVar.getVar());
|
||||||
mode ^= (1 << n);
|
int end = indexOf(endVar.getVar());
|
||||||
}
|
if (start != end)
|
||||||
|
swapVars(start, end);
|
||||||
|
|
||||||
void toggleInvertByMouse(int n) {
|
if (startVar.getInvert() != endVar.getInvert())
|
||||||
toggleInvert(indexOf(n));
|
toggleInvert(end);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean getInvert(int n) {
|
boolean getInvert(int n) {
|
||||||
|
@ -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<VarRect> 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
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user