This commit is contained in:
Denis Molony 2018-07-18 15:14:17 +10:00
parent bebf59d81d
commit 7fa3dfb79a
3 changed files with 114 additions and 113 deletions

View File

@ -6,10 +6,8 @@ import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.util.List; import java.util.List;
import javax.swing.JPanel;
import javax.swing.Scrollable; import javax.swing.Scrollable;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
@ -21,65 +19,57 @@ import com.bytezone.diskbrowser.gui.DiskLayoutPanel.LayoutDetails;
import com.bytezone.diskbrowser.gui.RedoHandler.RedoEvent; import com.bytezone.diskbrowser.gui.RedoHandler.RedoEvent;
import com.bytezone.diskbrowser.gui.RedoHandler.RedoListener; import com.bytezone.diskbrowser.gui.RedoHandler.RedoListener;
class DiskLayoutImage extends JPanel implements Scrollable, RedoListener class DiskLayoutImage extends DiskPanel implements Scrollable, RedoListener
{ {
private static final Cursor crosshairCursor = new Cursor (Cursor.CROSSHAIR_CURSOR); private static final Cursor crosshairCursor = new Cursor (Cursor.CROSSHAIR_CURSOR);
private static final Color[] lightColors = private static final Color[] lightColors =
{ Color.WHITE, Color.YELLOW, Color.PINK, Color.CYAN, Color.ORANGE, Color.GREEN }; { Color.WHITE, Color.YELLOW, Color.PINK, Color.CYAN, Color.ORANGE, Color.GREEN };
private FormattedDisk disk;
private LayoutDetails layoutDetails;
private boolean showFreeSectors; private boolean showFreeSectors;
private final DiskLayoutSelection selectionHandler = new DiskLayoutSelection (); private final DiskLayoutSelection selectionHandler = new DiskLayoutSelection ();
private boolean redo; private boolean redo;
private boolean isRetina;
// set defaults (used until a real disk is set) // set defaults (used until a real disk is set)
private int bw = 30; private int gridWidth = 8;
private int bh = 15; private int gridHeight = 35;
private int gw = 8;
private int gh = 35;
public DiskLayoutImage () public DiskLayoutImage ()
{ {
setPreferredSize (new Dimension (240 + 1, 525 + 1)); setPreferredSize (new Dimension (240 + 1, 525 + 1));
addMouseListener (new MyMouseListener ()); addMouseListener (new MyMouseListener ());
setBackground (new Color (0xE0, 0xE0, 0xE0)); setBackground (backgroundColor);
setOpaque (true); setOpaque (true);
addKeyListener (new MyKeyListener ()); addKeyListener (new MyKeyListener ());
} }
@Override
public void setDisk (FormattedDisk disk, LayoutDetails details) public void setDisk (FormattedDisk disk, LayoutDetails details)
{ {
this.disk = disk; super.setDisk (disk, details);
layoutDetails = details;
bw = layoutDetails.block.width; gridWidth = layoutDetails.grid.width; // width in blocks
bh = layoutDetails.block.height; gridHeight = layoutDetails.grid.height; // height in blocks
gw = layoutDetails.grid.width;
gh = layoutDetails.grid.height;
setPreferredSize (new Dimension (gw * bw + 1, gh * bh + 1)); setPreferredSize (
new Dimension (gridWidth * blockWidth + 1, gridHeight * blockHeight + 1));
selectionHandler.setSelection (null); selectionHandler.setSelection (null);
Graphics2D g = (Graphics2D) this.getGraphics ();
if (g != null) // panel might not be showing
isRetina = g.getFontRenderContext ().getTransform ()
.equals (AffineTransform.getScaleInstance (2.0, 2.0));
repaint (); repaint ();
} }
public FormattedDisk getDisk () public FormattedDisk getDisk ()
{ {
return disk; return formattedDisk;
} }
public void setShowFreeSectors (boolean showFree) public void setShowFreeSectors (boolean showFree)
{ {
showFreeSectors = showFree; if (showFree != showFreeSectors)
repaint (); {
showFreeSectors = showFree;
repaint ();
}
} }
void setSelection (List<DiskAddress> sectors) void setSelection (List<DiskAddress> sectors)
@ -99,80 +89,61 @@ class DiskLayoutImage extends JPanel implements Scrollable, RedoListener
{ {
super.paintComponent (g); super.paintComponent (g);
if (disk == null) if (formattedDisk == null)
return; return;
Rectangle clipRect = g.getClipBounds (); Rectangle clipRect = g.getClipBounds ();
Point p1 = new Point (clipRect.x / bw * bw, clipRect.y / bh * bh); Point topLeft = new Point (clipRect.x / blockWidth * blockWidth,
Point p2 = new Point ((clipRect.x + clipRect.width - 1) / bw * bw, clipRect.y / blockHeight * blockHeight);
(clipRect.y + clipRect.height - 1) / bh * bh); Point bottomRight =
new Point ((clipRect.x + clipRect.width - 1) / blockWidth * blockWidth,
(clipRect.y + clipRect.height - 1) / blockHeight * blockHeight);
int maxBlock = gw * gh; int maxBlock = gridWidth * gridHeight;
Disk d = disk.getDisk (); Disk d = formattedDisk.getDisk ();
// this stops an index error when using alt-5 to switch to 512-byte blocks // this stops an index error when using alt-5 to switch to 512-byte blocks
// if (maxBlock > d.getTotalBlocks ()) // if (maxBlock > d.getTotalBlocks ())
// maxBlock = d.getTotalBlocks (); // maxBlock = d.getTotalBlocks ();
// the index error is caused by not recalculating the grid layout // the index error is caused by not recalculating the grid layout
Graphics2D g2d = (Graphics2D) g; for (int y = topLeft.y; y <= bottomRight.y; y += blockHeight)
for (int x = topLeft.x; x <= bottomRight.x; x += blockWidth)
for (int y = p1.y; y <= p2.y; y += bh)
for (int x = p1.x; x <= p2.x; x += bw)
{ {
int blockNo = y / bh * gw + x / bw; int blockNo = y / blockHeight * gridWidth + x / blockWidth;
if (blockNo < maxBlock) if (blockNo < maxBlock)
{ {
DiskAddress da = d.getDiskAddress (blockNo); SectorType type = formattedDisk.getSectorType (blockNo);
boolean free = showFreeSectors && disk.isSectorFree (da); if (type == null)
boolean selected = selectionHandler.isSelected (da); System.out.println ("Sector type is null " + blockNo);
drawBlock (g2d, blockNo, x, y, free, selected); else
{
DiskAddress da = d.getDiskAddress (blockNo);
boolean free = showFreeSectors && formattedDisk.isSectorFree (da);
boolean selected = selectionHandler.isSelected (da);
drawBlock ((Graphics2D) g, type, x, y, free, selected);
}
} }
} }
} }
private void drawBlock (Graphics2D g, int blockNo, int x, int y, boolean flagFree, private void drawBlock (Graphics2D g, SectorType type, int x, int y, boolean flagFree,
boolean selected) boolean selected)
{ {
SectorType type = disk.getSectorType (blockNo); // draw block
if (type == null)
{
System.out.println ("Sector type is null " + blockNo);
return;
}
int offset = (bw - 4) / 2 + 1;
Rectangle rect = new Rectangle (x, y, bw, bh);
int width = rect.width - (isRetina ? 2 : 3) + 1;
int height = rect.height - (isRetina ? 2 : 3) + 1;
int offset2 = isRetina ? 1 : 2;
// draw frame
// if (false)
// {
// g.setColor (Color.GRAY);
// // g.drawRect (rect.x, rect.y, rect.width, rect.height);
// g.draw (rect);
// }
// draw blocks
g.setColor (type.colour); g.setColor (type.colour);
g.fillRect (rect.x + offset2, rect.y + offset2, width, height); g.fillRect (x + offset, y + offset, width, height);
// draw an indicator in free blocks if (flagFree || selected)
if (flagFree)
{ {
g.setColor (getContrastColor (type)); g.setColor (getContrastColor (type));
g.drawOval (rect.x + offset - 2, rect.y + 4, 7, 7);
}
// draw an indicator in selected blocks if (flagFree)
if (selected) g.drawOval (x + centerOffset - 2, y + 4, 7, 7);
{
g.setColor (getContrastColor (type)); if (selected)
g.fillOval (rect.x + offset, rect.y + 6, 3, 3); g.fillOval (x + centerOffset, y + 6, 3, 3);
} }
} }
@ -194,14 +165,14 @@ class DiskLayoutImage extends JPanel implements Scrollable, RedoListener
public int getScrollableUnitIncrement (Rectangle visibleRect, int orientation, public int getScrollableUnitIncrement (Rectangle visibleRect, int orientation,
int direction) int direction)
{ {
return orientation == SwingConstants.HORIZONTAL ? bw : bh; return orientation == SwingConstants.HORIZONTAL ? blockWidth : blockHeight;
} }
@Override @Override
public int getScrollableBlockIncrement (Rectangle visibleRect, int orientation, public int getScrollableBlockIncrement (Rectangle visibleRect, int orientation,
int direction) int direction)
{ {
return orientation == SwingConstants.HORIZONTAL ? bw * 4 : bh * 10; return orientation == SwingConstants.HORIZONTAL ? blockWidth * 4 : blockHeight * 10;
} }
@Override @Override
@ -231,7 +202,7 @@ class DiskLayoutImage extends JPanel implements Scrollable, RedoListener
private void fireSectorSelectionEvent () private void fireSectorSelectionEvent ()
{ {
SectorSelectedEvent event = SectorSelectedEvent event =
new SectorSelectedEvent (this, selectionHandler.getHighlights (), disk); new SectorSelectedEvent (this, selectionHandler.getHighlights (), formattedDisk);
fireSectorSelectionEvent (event); fireSectorSelectionEvent (event);
} }
@ -265,7 +236,7 @@ class DiskLayoutImage extends JPanel implements Scrollable, RedoListener
case KeyEvent.VK_RIGHT: case KeyEvent.VK_RIGHT:
case KeyEvent.VK_UP: case KeyEvent.VK_UP:
case KeyEvent.VK_DOWN: case KeyEvent.VK_DOWN:
selectionHandler.cursorMove (disk, e); selectionHandler.cursorMove (formattedDisk, e);
fireSectorSelectionEvent (); fireSectorSelectionEvent ();
repaint (); repaint ();
} }
@ -279,15 +250,15 @@ class DiskLayoutImage extends JPanel implements Scrollable, RedoListener
@Override @Override
public void mouseClicked (MouseEvent e) public void mouseClicked (MouseEvent e)
{ {
int x = e.getX () / bw; int x = e.getX () / blockWidth;
int y = e.getY () / bh; int y = e.getY () / blockHeight;
int blockNo = y * gw + x; int blockNo = y * gridWidth + x;
DiskAddress da = disk.getDisk ().getDiskAddress (blockNo); DiskAddress da = formattedDisk.getDisk ().getDiskAddress (blockNo);
boolean extend = ((e.getModifiersEx () & InputEvent.SHIFT_DOWN_MASK) > 0); boolean extend = ((e.getModifiersEx () & InputEvent.SHIFT_DOWN_MASK) > 0);
boolean append = ((e.getModifiersEx () & InputEvent.CTRL_DOWN_MASK) > 0); boolean append = ((e.getModifiersEx () & InputEvent.CTRL_DOWN_MASK) > 0);
selectionHandler.doClick (disk.getDisk (), da, extend, append); selectionHandler.doClick (formattedDisk.getDisk (), da, extend, append);
fireSectorSelectionEvent (); fireSectorSelectionEvent ();
repaint (); repaint ();
requestFocusInWindow (); requestFocusInWindow ();

View File

@ -4,10 +4,6 @@ import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import javax.swing.JPanel;
import com.bytezone.common.Platform; import com.bytezone.common.Platform;
import com.bytezone.common.Platform.FontSize; import com.bytezone.common.Platform.FontSize;
@ -16,15 +12,12 @@ import com.bytezone.diskbrowser.disk.FormattedDisk;
import com.bytezone.diskbrowser.disk.SectorType; import com.bytezone.diskbrowser.disk.SectorType;
import com.bytezone.diskbrowser.gui.DiskLayoutPanel.LayoutDetails; import com.bytezone.diskbrowser.gui.DiskLayoutPanel.LayoutDetails;
class DiskLegendPanel extends JPanel class DiskLegendPanel extends DiskPanel
{ {
private static final int LEFT = 3; private static final int LEFT = 3;
private static final int TOP = 10; private static final int TOP = 10;
private FormattedDisk disk;
private LayoutDetails layoutDetails;
private final Font font; private final Font font;
private boolean isRetina;
public DiskLegendPanel () public DiskLegendPanel ()
{ {
@ -32,15 +25,10 @@ class DiskLegendPanel extends JPanel
setBackground (Color.WHITE); setBackground (Color.WHITE);
} }
@Override
public void setDisk (FormattedDisk disk, LayoutDetails details) public void setDisk (FormattedDisk disk, LayoutDetails details)
{ {
this.disk = disk; super.setDisk (disk, details);
layoutDetails = details;
Graphics2D g = (Graphics2D) this.getGraphics ();
if (g != null) // panel might not be showing
isRetina = g.getFontRenderContext ().getTransform ()
.equals (AffineTransform.getScaleInstance (2.0, 2.0));
repaint (); repaint ();
} }
@ -48,7 +36,7 @@ class DiskLegendPanel extends JPanel
@Override @Override
public Dimension getPreferredSize () public Dimension getPreferredSize ()
{ {
return new Dimension (0, 160); // width/height return new Dimension (0, 160); // width/height
} }
@Override @Override
@ -56,37 +44,35 @@ class DiskLegendPanel extends JPanel
{ {
super.paintComponent (g); super.paintComponent (g);
if (disk == null) if (formattedDisk == null)
return; return;
g.setFont (font); g.setFont (font);
int count = 0; int count = 0;
int lineHeight = 20; int lineHeight = 20;
int width = layoutDetails.block.width - (isRetina ? 2 : 3);
int height = layoutDetails.block.height - (isRetina ? 2 : 3);
int offset = isRetina ? 1 : 2;
for (SectorType type : disk.getSectorTypeList ()) for (SectorType type : formattedDisk.getSectorTypeList ())
{ {
int x = LEFT + (count % 2 == 0 ? 0 : 155); int x = LEFT + (count % 2 == 0 ? 0 : 155);
int y = TOP + count++ / 2 * lineHeight; int y = TOP + count / 2 * lineHeight;
++count;
// draw border // draw border
g.setColor (Color.GRAY); g.setColor (backgroundColor);
g.drawRect (x, y, layoutDetails.block.width, layoutDetails.block.height); g.drawRect (x + 1, y + 1, blockWidth - 1, blockHeight - 1);
// draw the colour // draw block
g.setColor (type.colour); g.setColor (type.colour);
g.fillRect (x + offset, y + offset, width, height); g.fillRect (x + offset, y + offset, width, height);
// draw the text // draw text
g.setColor (Color.BLACK); g.setColor (Color.BLACK);
g.drawString (type.name, x + layoutDetails.block.width + 4, y + 12); g.drawString (type.name, x + blockWidth + 4, y + 12);
} }
int y = ++count / 2 * lineHeight + TOP * 2 + 5; int y = ++count / 2 * lineHeight + TOP * 2 + 5;
int val = disk.falseNegativeBlocks (); int val = formattedDisk.falseNegativeBlocks ();
if (val > 0) if (val > 0)
{ {
g.drawString ( g.drawString (
@ -94,7 +80,7 @@ class DiskLegendPanel extends JPanel
y); y);
y += lineHeight; y += lineHeight;
} }
val = disk.falsePositiveBlocks (); val = formattedDisk.falsePositiveBlocks ();
if (val > 0) if (val > 0)
g.drawString (val + " used sector" + (val == 1 ? "" : "s") + " marked as available", g.drawString (val + " used sector" + (val == 1 ? "" : "s") + " marked as available",
10, y); 10, y);

View File

@ -0,0 +1,44 @@
package com.bytezone.diskbrowser.gui;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import javax.swing.JPanel;
import com.bytezone.diskbrowser.disk.FormattedDisk;
import com.bytezone.diskbrowser.gui.DiskLayoutPanel.LayoutDetails;
public class DiskPanel extends JPanel
{
FormattedDisk formattedDisk;
LayoutDetails layoutDetails;
boolean isRetina;
int blockWidth = 30; // default
int blockHeight = 15; // default
int width;
int height;
int offset;
int centerOffset;
Color backgroundColor = new Color (0xE0, 0xE0, 0xE0);
public void setDisk (FormattedDisk disk, LayoutDetails details)
{
formattedDisk = disk;
layoutDetails = details;
blockWidth = layoutDetails.block.width;
blockHeight = layoutDetails.block.height;
Graphics2D g = (Graphics2D) this.getGraphics ();
if (g != null) // panel might not be showing
isRetina = g.getFontRenderContext ().getTransform ()
.equals (AffineTransform.getScaleInstance (2.0, 2.0));
width = blockWidth - (isRetina ? 2 : 3) + 1;
height = blockHeight - (isRetina ? 2 : 3) + 1;
offset = isRetina ? 1 : 2;
centerOffset = (blockWidth - 4) / 2 + 1;
}
}