Okay, the visualiser looks pretty much done.

This commit is contained in:
David Given
2022-02-26 00:23:17 +01:00
parent a59b59fea4
commit 1d7a75c7b3

View File

@@ -12,130 +12,156 @@
#define SECTORSIZE 5 #define SECTORSIZE 5
static const wxColour DARK_GREY(0x80, 0x80, 0x80); #define DECLARE_COLOUR(name, red, green, blue) \
static const wxBrush DARK_GREY_BRUSH(DARK_GREY); static const wxColour name##_COLOUR(red, green, blue); \
static const wxPen DARK_GREY_PEN(DARK_GREY); static const wxBrush name##_BRUSH(name##_COLOUR); \
static const wxPen name##_PEN(name##_COLOUR)
DECLARE_COLOUR(AXIS, 128, 128, 128);
DECLARE_COLOUR(GOOD_SECTOR, 0, 158, 115);
DECLARE_COLOUR(BAD_SECTOR, 213, 94, 0);
DECLARE_COLOUR(MISSING_SECTOR, 86, 180, 233);
DECLARE_COLOUR(READ_ARROW, 0, 128, 0);
DECLARE_COLOUR(WRITE_ARROW, 128, 0, 0);
VisualisationControl::VisualisationControl(wxWindow* parent, VisualisationControl::VisualisationControl(wxWindow* parent,
wxWindowID id, wxWindowID id,
const wxPoint& pos, const wxPoint& pos,
const wxSize& size, const wxSize& size,
long style): long style):
wxWindow(parent, id, pos, size, style, "VisualisationControl") wxWindow(parent, id, pos, size, style, "VisualisationControl")
{ {
} }
wxBEGIN_EVENT_TABLE(VisualisationControl, wxPanel) wxBEGIN_EVENT_TABLE(VisualisationControl, wxPanel)
EVT_PAINT(VisualisationControl::OnPaint) EVT_PAINT(VisualisationControl::OnPaint) wxEND_EVENT_TABLE()
wxEND_EVENT_TABLE()
void VisualisationControl::OnPaint(wxPaintEvent&) void VisualisationControl::OnPaint(wxPaintEvent&)
{ {
auto size = GetSize(); auto size = GetSize();
int w = size.GetWidth(); int w = size.GetWidth();
int w2 = w/2; int w2 = w / 2;
int h = size.GetHeight(); int h = size.GetHeight();
int centrey = h * 1.5; int centrey = h * 1.5;
int outerradius = centrey - BORDER; int outerradius = centrey - BORDER;
int innerradius = centrey - h + BORDER; int innerradius = centrey - h + BORDER;
int scalesize = TRACKS*SECTORSIZE; int scalesize = TRACKS * SECTORSIZE;
int scaletop = h/2 - scalesize/2; int scaletop = h / 2 - scalesize / 2;
int scalebottom = scaletop + scalesize; int scalebottom = scaletop + scalesize - 1;
wxPaintDC dc(this); wxPaintDC dc(this);
dc.SetPen(*wxBLACK_PEN); dc.SetPen(*wxBLACK_PEN);
dc.SetBrush(*wxLIGHT_GREY_BRUSH); dc.SetBrush(*wxLIGHT_GREY_BRUSH);
dc.DrawCircle({ w2, centrey }, outerradius); dc.DrawCircle({w2, centrey}, outerradius);
dc.SetBrush(dc.GetBackground()); dc.SetBrush(dc.GetBackground());
dc.DrawCircle({ w2, centrey }, innerradius); dc.DrawCircle({w2, centrey}, innerradius);
dc.SetPen(DARK_GREY_PEN); dc.SetPen(AXIS_PEN);
dc.DrawLine({ w2, scaletop }, { w2, scalebottom }); dc.DrawLine({w2, scaletop}, {w2, scalebottom});
if (_mode != VISMODE_NOTHING) if (_mode != VISMODE_NOTHING)
{ {
if (_mode == VISMODE_READING) if (_mode == VISMODE_READING)
dc.SetBrush(*wxGREEN_BRUSH); {
else if (_mode == VISMODE_WRITING) dc.SetPen(READ_ARROW_PEN);
dc.SetBrush(*wxRED_BRUSH); dc.SetBrush(READ_ARROW_BRUSH);
}
else if (_mode == VISMODE_WRITING)
{
dc.SetPen(WRITE_ARROW_PEN);
dc.SetBrush(WRITE_ARROW_BRUSH);
}
int factor = (_head == 0) ? -1 : 1; int factor = (_head == 0) ? -1 : 1;
dc.SetPen(*wxTRANSPARENT_PEN); int y = scaletop + _cylinder * SECTORSIZE;
int y = scaletop + _cylinder * SECTORSIZE; wxPoint points[] = {
dc.DrawRectangle( { w2 + factor*TICK, y-1 },
{ w2 + factor*SECTORSIZE, y }, { w2 + factor*TICK, y+SECTORSIZE-1 },
{ factor*SECTORSIZE*82, SECTORSIZE-1 } { w2 + factor*TICK*2, y+SECTORSIZE/2 }
); };
} dc.DrawPolygon(3, points);
}
for (int track = 0; track <= TRACKS; track++) for (int track = 0; track <= TRACKS; track++)
{ {
int y = scaletop + track*SECTORSIZE; int y = scaletop + track * SECTORSIZE;
dc.SetBrush(DARK_GREY_BRUSH); dc.SetBrush(AXIS_BRUSH);
dc.SetPen(DARK_GREY_PEN); dc.SetPen(AXIS_PEN);
dc.DrawRectangle( dc.DrawLine({w2 - TICK, y-1}, {w2 + TICK, y-1});
{ w2-TICK/2, y },
{ TICK, SECTORSIZE-1 }
);
auto drawSectors = auto drawSectors = [&](int head)
[&](int head) { {
key_t key = { track, head }; key_t key = {track, head};
std::vector<std::shared_ptr<const Sector>> sectors; std::vector<std::shared_ptr<const Sector>> sectors;
for (auto it = _sectors.lower_bound(key); it != _sectors.upper_bound(key); it++) for (auto it = _sectors.lower_bound(key);
sectors.push_back(it->second); it != _sectors.upper_bound(key);
std::sort(sectors.begin(), sectors.end(), sectorPointerSortPredicate); it++)
sectors.push_back(it->second);
std::sort(
sectors.begin(), sectors.end(), sectorPointerSortPredicate);
int x = 1; int x = 1;
for (const auto& sector : sectors) for (const auto& sector : sectors)
{ {
if (head == 0) if (sector->status == Sector::OK)
dc.DrawRectangle( {
{ w2 - x*SECTORSIZE - (SECTORSIZE-1), y }, dc.SetBrush(GOOD_SECTOR_BRUSH);
{ SECTORSIZE-1, SECTORSIZE-1 } dc.SetPen(GOOD_SECTOR_PEN);
); }
else else if (sector->status == Sector::MISSING)
dc.DrawRectangle( {
{ w2 + x*SECTORSIZE, y }, dc.SetBrush(MISSING_SECTOR_BRUSH);
{ SECTORSIZE-1, SECTORSIZE-1 } dc.SetPen(MISSING_SECTOR_PEN);
); }
x++; else
} {
}; dc.SetBrush(BAD_SECTOR_BRUSH);
dc.SetPen(BAD_SECTOR_PEN);
}
drawSectors(0); if (head == 0)
drawSectors(1); dc.DrawRectangle(
} {w2 - x * SECTORSIZE - (SECTORSIZE - 1), y},
{SECTORSIZE - 1, SECTORSIZE - 1});
else
dc.DrawRectangle({w2 + x * SECTORSIZE + 1, y},
{SECTORSIZE - 1, SECTORSIZE - 1});
x++;
}
};
drawSectors(0);
drawSectors(1);
}
} }
void VisualisationControl::SetMode(int cylinder, int head, int mode) void VisualisationControl::SetMode(int cylinder, int head, int mode)
{ {
_cylinder = cylinder; _cylinder = cylinder;
_head = head; _head = head;
_mode = mode; _mode = mode;
Refresh(); Refresh();
} }
void VisualisationControl::Clear() void VisualisationControl::Clear()
{ {
_sectors.clear(); _sectors.clear();
Refresh(); Refresh();
} }
void VisualisationControl::SetTrackData(std::shared_ptr<const TrackFlux> track) void VisualisationControl::SetTrackData(std::shared_ptr<const TrackFlux> track)
{ {
key_t key = { track->physicalCylinder, track->physicalHead }; key_t key = {track->physicalCylinder, track->physicalHead};
_sectors.erase(key); _sectors.erase(key);
for (auto& sector : track->sectors) for (auto& sector : track->sectors)
_sectors.insert({ key, sector }); _sectors.insert({key, sector});
Refresh(); Refresh();
} }
void VisualisationControl::SetDiskData(std::shared_ptr<const DiskFlux> disk) void VisualisationControl::SetDiskData(std::shared_ptr<const DiskFlux> disk)
{ {
Refresh(); Refresh();
} }