dmolony-DiskBrowser/src/com/bytezone/diskbrowser/gui/DiskLayoutPanel.java

274 lines
9.4 KiB
Java
Raw Permalink Normal View History

2015-06-01 09:35:51 +00:00
package com.bytezone.diskbrowser.gui;
import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS;
import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS;
2016-02-28 05:41:10 +00:00
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
2015-06-01 09:35:51 +00:00
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
2021-06-04 06:53:04 +00:00
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
2015-06-01 09:35:51 +00:00
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import com.bytezone.diskbrowser.disk.Disk;
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.disk.FormattedDisk;
2021-05-22 10:15:20 +00:00
import com.bytezone.diskbrowser.disk.HybridDisk;
2015-06-01 09:35:51 +00:00
import com.bytezone.diskbrowser.gui.RedoHandler.RedoEvent;
import com.bytezone.diskbrowser.gui.RedoHandler.RedoListener;
2020-02-08 10:13:51 +00:00
// -----------------------------------------------------------------------------------//
2021-06-04 06:53:04 +00:00
class DiskLayoutPanel extends JPanel implements DiskSelectionListener,
FileSelectionListener, RedoListener, PropertyChangeListener
2020-02-08 10:13:51 +00:00
// -----------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
2016-07-29 12:28:11 +00:00
private static final int SIZE = 15; // basic unit of a display block
2015-06-01 09:35:51 +00:00
2017-01-20 11:13:26 +00:00
private final DiskLayoutImage diskLayoutImage;
2015-06-01 09:35:51 +00:00
private final ScrollRuler verticalRuler;
private final ScrollRuler horizontalRuler;
private final DiskLegendPanel legendPanel;
private final JScrollPane sp;
private LayoutDetails layout;
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2019-08-01 13:39:45 +00:00
public DiskLayoutPanel ()
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
super (new BorderLayout ());
2017-01-20 11:13:26 +00:00
diskLayoutImage = new DiskLayoutImage ();
verticalRuler = new ScrollRuler (diskLayoutImage, ScrollRuler.VERTICAL);
horizontalRuler = new ScrollRuler (diskLayoutImage, ScrollRuler.HORIZONTAL);
2015-06-01 09:35:51 +00:00
legendPanel = new DiskLegendPanel ();
setBackground (Color.WHITE);
2015-06-01 09:35:51 +00:00
2017-01-20 11:13:26 +00:00
sp = new JScrollPane (diskLayoutImage, VERTICAL_SCROLLBAR_ALWAYS,
HORIZONTAL_SCROLLBAR_ALWAYS);
2019-08-01 08:41:37 +00:00
sp.getViewport ().setBackground (Color.WHITE);
2015-06-01 09:35:51 +00:00
sp.setColumnHeaderView (horizontalRuler);
sp.setRowHeaderView (verticalRuler);
sp.setBorder (null);
sp.setCorner (JScrollPane.UPPER_LEFT_CORNER, new Corner (true));
sp.setCorner (JScrollPane.LOWER_LEFT_CORNER, new Corner (false));
sp.setCorner (JScrollPane.UPPER_RIGHT_CORNER, new Corner (false));
sp.setCorner (JScrollPane.LOWER_RIGHT_CORNER, new Corner (false));
// this is just so the pack is correct
add (sp, BorderLayout.CENTER);
add (legendPanel, BorderLayout.SOUTH);
}
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
public void setDisk (final FormattedDisk disk)
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
layout = new LayoutDetails (disk);
2017-01-20 11:13:26 +00:00
diskLayoutImage.setDisk (disk, layout);
2015-06-01 09:35:51 +00:00
verticalRuler.setLayout (layout);
horizontalRuler.setLayout (layout);
legendPanel.setDisk (disk, layout);
2018-06-30 09:40:38 +00:00
// this is the only way I know of to force a refresh
sp.setViewportView (diskLayoutImage);
2015-06-01 09:35:51 +00:00
setLayout (new BorderLayout ());
2019-08-11 04:12:32 +00:00
if (disk.getGridLayout ().height == 35) // what about 48?
2015-06-01 09:35:51 +00:00
{
add (sp, BorderLayout.NORTH);
add (legendPanel, BorderLayout.CENTER);
}
else
{
add (sp, BorderLayout.CENTER);
add (legendPanel, BorderLayout.SOUTH);
}
// Allow the disk to notify us if the interleave or blocksize is changed
disk.getDisk ().addActionListener (new ActionListener ()
{
@Override
public void actionPerformed (ActionEvent e)
{
LayoutDetails layout = new LayoutDetails (disk);
2017-01-20 11:13:26 +00:00
diskLayoutImage.setDisk (disk, layout);
2016-07-29 22:06:41 +00:00
legendPanel.setDisk (disk, layout);
2015-06-01 09:35:51 +00:00
verticalRuler.setLayout (layout);
horizontalRuler.setLayout (layout);
}
});
repaint ();
}
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
public void setHex (boolean hex)
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
verticalRuler.setHex (hex);
horizontalRuler.setHex (hex);
}
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
public void setBlock (boolean block)
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
verticalRuler.setTrackMode (block);
horizontalRuler.setTrackMode (block);
}
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
public void setFree (boolean free)
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
2017-01-20 11:13:26 +00:00
diskLayoutImage.setShowFreeSectors (free);
2015-06-01 09:35:51 +00:00
}
2021-06-04 06:53:04 +00:00
// ---------------------------------------------------------------------------------//
@Override
public void propertyChange (PropertyChangeEvent evt)
// ---------------------------------------------------------------------------------//
{
setFree ((Boolean) evt.getNewValue ());
}
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
public void addSectorSelectionListener (SectorSelectionListener listener)
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
2017-01-20 11:13:26 +00:00
diskLayoutImage.addSectorSelectionListener (listener);
2015-06-01 09:35:51 +00:00
}
2021-05-22 10:15:20 +00:00
// ---------------------------------------------------------------------------------//
public void addSectorSelectionListener (SectorSelectionListener... listeners)
// ---------------------------------------------------------------------------------//
{
for (SectorSelectionListener sectorSelectionListener : listeners)
diskLayoutImage.addSectorSelectionListener (sectorSelectionListener);
}
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
public void removeSectorSelectionListener (SectorSelectionListener listener)
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
2017-01-20 11:13:26 +00:00
diskLayoutImage.removeSectorSelectionListener (listener);
2015-06-01 09:35:51 +00:00
}
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
@Override
public void diskSelected (DiskSelectedEvent event)
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
setDisk (event.getFormattedDisk ());
}
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
@Override
public void fileSelected (FileSelectedEvent event)
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
// This can happen if a file is selected from a dual-dos disk
2019-11-14 11:55:30 +00:00
checkCorrectDisk (event.appleFileSource.getFormattedDisk ());
2015-06-01 09:35:51 +00:00
2019-11-14 11:55:30 +00:00
diskLayoutImage.setSelection (event.appleFileSource.getSectors ());
2015-06-01 09:35:51 +00:00
}
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
class LayoutDetails
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
Dimension block;
Dimension grid;
public LayoutDetails (FormattedDisk formattedDisk)
{
Disk disk = formattedDisk.getDisk ();
block = new Dimension (disk.getBlockSize () == 256 ? SIZE : SIZE * 2, SIZE);
grid = formattedDisk.getGridLayout ();
}
public Rectangle getLocation (DiskAddress da)
{
2020-04-10 23:47:52 +00:00
int y = da.getBlockNo () / grid.width;
int x = da.getBlockNo () % grid.width;
2015-06-01 09:35:51 +00:00
Rectangle r =
2016-02-28 05:41:10 +00:00
new Rectangle (x * block.width, y * block.height, block.width, block.height);
2015-06-01 09:35:51 +00:00
return r;
}
@Override
public String toString ()
{
StringBuilder text = new StringBuilder ();
text.append ("Block " + block + "\n");
text.append ("Grid " + grid);
return text.toString ();
}
}
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
class Corner extends JComponent
2020-02-08 10:13:51 +00:00
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
Color backgroundColor = Color.WHITE;
boolean showHex = true;
2016-07-29 12:28:11 +00:00
public Corner (boolean allowClick)
2015-06-01 09:35:51 +00:00
{
2016-07-29 12:28:11 +00:00
if (allowClick)
2015-06-01 09:35:51 +00:00
addMouseListener (new MouseAdapter ()
{
@Override
public void mouseClicked (MouseEvent e)
{
showHex = !showHex;
verticalRuler.setHex (showHex);
horizontalRuler.setHex (showHex);
}
});
}
@Override
protected void paintComponent (Graphics g)
{
g.setColor (backgroundColor);
g.fillRect (0, 0, getWidth (), getHeight ());
}
}
@Override
public void redo (RedoEvent event)
{
if (!event.type.equals ("SectorEvent"))
return;
// This can happen if sectors are selected from a dual-dos disk
checkCorrectDisk (((SectorSelectedEvent) event.value).getFormattedDisk ());
2017-01-20 11:13:26 +00:00
diskLayoutImage.redo (event);
2015-06-01 09:35:51 +00:00
}
private void checkCorrectDisk (FormattedDisk newDisk)
{
2021-09-19 07:09:34 +00:00
if (newDisk instanceof HybridDisk hybridDisk)
newDisk = hybridDisk.getCurrentDisk (); // never set to a hybrid disk
2017-01-20 11:13:26 +00:00
if (newDisk != diskLayoutImage.getDisk ())
2015-06-01 09:35:51 +00:00
{
LayoutDetails layout = new LayoutDetails (newDisk);
2017-01-20 11:13:26 +00:00
diskLayoutImage.setDisk (newDisk, layout);
2015-06-01 09:35:51 +00:00
legendPanel.setDisk (newDisk, layout);
}
}
}