mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-09-30 13:58:30 +00:00
232 lines
6.5 KiB
Java
232 lines
6.5 KiB
Java
package com.bytezone.diskbrowser.gui;
|
|
|
|
import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS;
|
|
import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS;
|
|
|
|
import java.awt.BorderLayout;
|
|
import java.awt.Color;
|
|
import java.awt.Dimension;
|
|
import java.awt.Graphics;
|
|
import java.awt.Rectangle;
|
|
import java.awt.event.ActionEvent;
|
|
import java.awt.event.ActionListener;
|
|
import java.awt.event.MouseAdapter;
|
|
import java.awt.event.MouseEvent;
|
|
|
|
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.DualDosDisk;
|
|
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
|
import com.bytezone.diskbrowser.gui.RedoHandler.RedoEvent;
|
|
import com.bytezone.diskbrowser.gui.RedoHandler.RedoListener;
|
|
|
|
class DiskLayoutPanel extends JPanel
|
|
implements DiskSelectionListener, FileSelectionListener, RedoListener
|
|
{
|
|
private static final int SIZE = 15; // basic unit of a display block
|
|
|
|
private final DiskLayoutImage diskLayoutImage;
|
|
private final ScrollRuler verticalRuler;
|
|
private final ScrollRuler horizontalRuler;
|
|
private final DiskLegendPanel legendPanel;
|
|
private final JScrollPane sp;
|
|
private LayoutDetails layout;
|
|
|
|
public DiskLayoutPanel ()
|
|
{
|
|
super (new BorderLayout ());
|
|
|
|
diskLayoutImage = new DiskLayoutImage ();
|
|
verticalRuler = new ScrollRuler (diskLayoutImage, ScrollRuler.VERTICAL);
|
|
horizontalRuler = new ScrollRuler (diskLayoutImage, ScrollRuler.HORIZONTAL);
|
|
legendPanel = new DiskLegendPanel ();
|
|
|
|
setBackground (Color.WHITE);
|
|
|
|
sp = new JScrollPane (diskLayoutImage, VERTICAL_SCROLLBAR_ALWAYS,
|
|
HORIZONTAL_SCROLLBAR_ALWAYS);
|
|
sp.getViewport ().setBackground (Color.WHITE);
|
|
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);
|
|
}
|
|
|
|
public void setDisk (final FormattedDisk disk)
|
|
{
|
|
layout = new LayoutDetails (disk);
|
|
diskLayoutImage.setDisk (disk, layout);
|
|
verticalRuler.setLayout (layout);
|
|
horizontalRuler.setLayout (layout);
|
|
legendPanel.setDisk (disk, layout);
|
|
|
|
// this is the only way I know of to force a refresh
|
|
sp.setViewportView (diskLayoutImage);
|
|
|
|
setLayout (new BorderLayout ());
|
|
if (disk.getGridLayout ().height == 35) // what about 48?
|
|
{
|
|
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);
|
|
|
|
diskLayoutImage.setDisk (disk, layout);
|
|
legendPanel.setDisk (disk, layout);
|
|
|
|
verticalRuler.setLayout (layout);
|
|
horizontalRuler.setLayout (layout);
|
|
}
|
|
});
|
|
|
|
repaint ();
|
|
}
|
|
|
|
public void setHex (boolean hex)
|
|
{
|
|
verticalRuler.setHex (hex);
|
|
horizontalRuler.setHex (hex);
|
|
}
|
|
|
|
public void setBlock (boolean block)
|
|
{
|
|
verticalRuler.setTrackMode (block);
|
|
horizontalRuler.setTrackMode (block);
|
|
}
|
|
|
|
public void setFree (boolean free)
|
|
{
|
|
diskLayoutImage.setShowFreeSectors (free);
|
|
}
|
|
|
|
public void addSectorSelectionListener (SectorSelectionListener listener)
|
|
{
|
|
diskLayoutImage.addSectorSelectionListener (listener);
|
|
}
|
|
|
|
public void removeSectorSelectionListener (SectorSelectionListener listener)
|
|
{
|
|
diskLayoutImage.removeSectorSelectionListener (listener);
|
|
}
|
|
|
|
@Override
|
|
public void diskSelected (DiskSelectedEvent event)
|
|
{
|
|
setDisk (event.getFormattedDisk ());
|
|
}
|
|
|
|
@Override
|
|
public void fileSelected (FileSelectedEvent event)
|
|
{
|
|
// This can happen if a file is selected from a dual-dos disk
|
|
checkCorrectDisk (event.file.getFormattedDisk ());
|
|
|
|
diskLayoutImage.setSelection (event.file.getSectors ());
|
|
}
|
|
|
|
class LayoutDetails
|
|
{
|
|
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)
|
|
{
|
|
int y = da.getBlock () / grid.width;
|
|
int x = da.getBlock () % grid.width;
|
|
Rectangle r =
|
|
new Rectangle (x * block.width, y * block.height, block.width, block.height);
|
|
return r;
|
|
}
|
|
|
|
@Override
|
|
public String toString ()
|
|
{
|
|
StringBuilder text = new StringBuilder ();
|
|
text.append ("Block " + block + "\n");
|
|
text.append ("Grid " + grid);
|
|
return text.toString ();
|
|
}
|
|
}
|
|
|
|
class Corner extends JComponent
|
|
{
|
|
Color backgroundColor = Color.WHITE;
|
|
boolean showHex = true;
|
|
|
|
public Corner (boolean allowClick)
|
|
{
|
|
if (allowClick)
|
|
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 ());
|
|
|
|
diskLayoutImage.redo (event);
|
|
}
|
|
|
|
private void checkCorrectDisk (FormattedDisk newDisk)
|
|
{
|
|
if (newDisk instanceof DualDosDisk)
|
|
newDisk = ((DualDosDisk) newDisk).getCurrentDisk (); // never set to a Dual-dos disk
|
|
if (newDisk != diskLayoutImage.getDisk ())
|
|
{
|
|
LayoutDetails layout = new LayoutDetails (newDisk);
|
|
diskLayoutImage.setDisk (newDisk, layout);
|
|
legendPanel.setDisk (newDisk, layout);
|
|
}
|
|
}
|
|
} |