Merge pull request #573 from davidgiven/vfs

Overhaul the GUI.
This commit is contained in:
David Given
2022-09-03 22:21:34 +02:00
committed by GitHub
31 changed files with 4797 additions and 2453 deletions

View File

@@ -22,8 +22,6 @@
# include "hfs.h"
# include "apple.h"
extern int errno;
# define ERROR(code, str) \
do { hfs_error = (str), errno = (code); goto fail; } while (0)

View File

@@ -24,6 +24,7 @@ LIBFLUXENGINE_SRCS = \
lib/fluxsource/hardwarefluxsource.cc \
lib/fluxsource/kryoflux.cc \
lib/fluxsource/kryofluxfluxsource.cc \
lib/fluxsource/memoryfluxsource.cc \
lib/fluxsource/scpfluxsource.cc \
lib/fluxsource/testpatternfluxsource.cc \
lib/globals.cc \

View File

@@ -4,6 +4,7 @@
#include "flags.h"
class CwfFluxSourceProto;
class DiskFlux;
class EraseFluxSourceProto;
class Fl2FluxSourceProto;
class FluxSourceProto;
@@ -38,6 +39,8 @@ private:
static std::unique_ptr<FluxSource> createTestPatternFluxSource(const TestPatternFluxSourceProto& config);
public:
static std::unique_ptr<FluxSource> createMemoryFluxSource(const DiskFlux& flux);
static std::unique_ptr<FluxSource> create(const FluxSourceProto& spec);
static void updateConfigForFilename(FluxSourceProto* proto, const std::string& filename);

View File

@@ -58,6 +58,7 @@ public:
_hardSectorThreshold = 0;
if (_oneRevolution == 0)
{
Logger() << BeginOperationLogMessage{"Measuring drive rotational speed"};
do
{
_oneRevolution =
@@ -71,6 +72,7 @@ public:
retries--;
} while ((_oneRevolution == 0) && (retries > 0));
config.mutable_drive()->set_rotational_period_ms(_oneRevolution / 1e6);
Logger() << EndOperationLogMessage{};
}
if (_oneRevolution == 0)

View File

@@ -0,0 +1,75 @@
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/flux.h"
#include "lib/fluxsource/fluxsource.h"
#include "lib/fluxmap.h"
#include <fmt/format.h>
#include <fstream>
class MemoryFluxSourceIterator : public FluxSourceIterator
{
public:
MemoryFluxSourceIterator(const TrackFlux& track):
_track(track)
{}
bool hasNext() const override
{
return _count < _track.trackDatas.size();
}
std::unique_ptr<const Fluxmap> next() override
{
auto bytes = _track.trackDatas[_count]->fluxmap->rawBytes();
_count++;
return std::make_unique<Fluxmap>(bytes);
}
private:
const TrackFlux& _track;
int _count = 0;
};
class EmptyFluxSourceIterator : public FluxSourceIterator
{
bool hasNext() const override
{
return false;
}
std::unique_ptr<const Fluxmap> next() override
{
Error() << "no flux to read";
}
};
class MemoryFluxSource : public FluxSource
{
public:
MemoryFluxSource(const DiskFlux& flux): _flux(flux)
{
}
public:
std::unique_ptr<FluxSourceIterator> readFlux(int track, int head) override
{
for (const auto& trackFlux : _flux.tracks)
{
if ((trackFlux->location.physicalTrack == track) && (trackFlux->location.head == head))
return std::make_unique<MemoryFluxSourceIterator>(*trackFlux);
}
return std::make_unique<EmptyFluxSourceIterator>();
}
void recalibrate() {}
private:
const DiskFlux& _flux;
};
std::unique_ptr<FluxSource> FluxSource::createMemoryFluxSource(const DiskFlux& flux)
{
return std::make_unique<MemoryFluxSource>(flux);
}

View File

@@ -83,8 +83,10 @@ std::string Logger::toString(const AnyLogMessage& message)
std::set<std::shared_ptr<const Record>> rawRecords;
for (const auto& trackDataFlux : track.trackDatas)
{
rawSectors.insert(trackDataFlux->sectors.begin(), trackDataFlux->sectors.end());
rawRecords.insert(trackDataFlux->records.begin(), trackDataFlux->records.end());
rawSectors.insert(trackDataFlux->sectors.begin(),
trackDataFlux->sectors.end());
rawRecords.insert(trackDataFlux->records.begin(),
trackDataFlux->records.end());
}
nanoseconds_t clock = 0;
@@ -136,6 +138,21 @@ std::string Logger::toString(const AnyLogMessage& message)
stream << fmt::format("{} bytes decoded\n", size);
},
/* Large-scale operation start. */
[&](const BeginOperationLogMessage& m)
{
},
/* Large-scale operation end. */
[&](const EndOperationLogMessage& m)
{
},
/* Large-scale operation progress. */
[&](const OperationProgressLogMessage& m)
{
},
/* Generic text message */
[&](const std::string& s)
{

View File

@@ -10,7 +10,11 @@ class Sector;
struct ErrorLogMessage
{
std::string message;
std::string message;
};
struct EmergencyStopMessage
{
};
struct BeginSpeedOperationLogMessage
@@ -29,7 +33,7 @@ struct TrackReadLogMessage
struct DiskReadLogMessage
{
std::shared_ptr<const DiskFlux> disk;
std::shared_ptr<const DiskFlux> disk;
};
struct BeginReadOperationLogMessage
@@ -40,8 +44,8 @@ struct BeginReadOperationLogMessage
struct EndReadOperationLogMessage
{
std::shared_ptr<const TrackDataFlux> trackDataFlux;
std::set<std::shared_ptr<const Sector>> sectors;
std::shared_ptr<const TrackDataFlux> trackDataFlux;
std::set<std::shared_ptr<const Sector>> sectors;
};
struct BeginWriteOperationLogMessage
@@ -54,19 +58,37 @@ struct EndWriteOperationLogMessage
{
};
struct BeginOperationLogMessage
{
std::string message;
};
struct EndOperationLogMessage
{
std::string message;
};
struct OperationProgressLogMessage
{
unsigned progress;
};
class TrackFlux;
typedef std::variant<
std::string,
ErrorLogMessage,
typedef std::variant<std::string,
ErrorLogMessage,
EmergencyStopMessage,
TrackReadLogMessage,
DiskReadLogMessage,
DiskReadLogMessage,
BeginSpeedOperationLogMessage,
EndSpeedOperationLogMessage,
BeginReadOperationLogMessage,
EndReadOperationLogMessage,
BeginWriteOperationLogMessage,
EndWriteOperationLogMessage>
EndWriteOperationLogMessage,
BeginOperationLogMessage,
EndOperationLogMessage,
OperationProgressLogMessage>
AnyLogMessage;
class Logger

View File

@@ -187,8 +187,17 @@ void writeTracks(FluxSink& fluxSink,
producer,
std::function<bool(const Location& location)> verifier)
{
for (const auto& location : Mapper::computeLocations())
Logger() << BeginOperationLogMessage{"Encoding and writing to disk"};
auto locations = Mapper::computeLocations();
int index = 0;
for (const auto& location : locations)
{
Logger() << OperationProgressLogMessage{
index * 100 / (unsigned)locations.size()};
index++;
testForEmergencyStop();
int retriesRemaining = config.decoder().retries();
@@ -237,6 +246,8 @@ void writeTracks(FluxSink& fluxSink,
retriesRemaining--;
}
}
Logger() << EndOperationLogMessage{"Write complete"};
}
static bool dontVerify(const Location&)
@@ -285,30 +296,38 @@ void writeTracksAndVerify(FluxSink& fluxSink,
return false;
}
Image wanted;
for (const auto& sector : encoder.collectSectors(location, image))
wanted.put(sector->logicalTrack, sector->logicalSide, sector->logicalSector)->data = sector->data;
Image wanted;
for (const auto& sector : encoder.collectSectors(location, image))
wanted
.put(sector->logicalTrack,
sector->logicalSide,
sector->logicalSector)
->data = sector->data;
for (const auto& sector : trackFlux->sectors)
{
const auto s = wanted.get(sector->logicalTrack, sector->logicalSide, sector->logicalSector);
if (!s)
{
Logger() << "spurious sector on verify";
return false;
}
if (s->data != sector->data.slice(0, s->data.size()))
{
Logger() << "data mismatch on verify";
return false;
}
wanted.erase(sector->logicalTrack, sector->logicalSide, sector->logicalSector);
}
if (!wanted.empty())
{
Logger() << "missing sector on verify";
return false;
}
for (const auto& sector : trackFlux->sectors)
{
const auto s = wanted.get(sector->logicalTrack,
sector->logicalSide,
sector->logicalSector);
if (!s)
{
Logger() << "spurious sector on verify";
return false;
}
if (s->data != sector->data.slice(0, s->data.size()))
{
Logger() << "data mismatch on verify";
return false;
}
wanted.erase(sector->logicalTrack,
sector->logicalSide,
sector->logicalSector);
}
if (!wanted.empty())
{
Logger() << "missing sector on verify";
return false;
}
return true;
});
}
@@ -319,14 +338,14 @@ void writeDiskCommand(const Image& image,
AbstractDecoder* decoder,
FluxSource* fluxSource)
{
const Image* imagep = &image;
std::unique_ptr<const Image> remapped;
const Image* imagep = &image;
std::unique_ptr<const Image> remapped;
if (config.has_sector_mapping())
{
{
remapped = Mapper::remapSectorsLogicalToPhysical(
image, config.sector_mapping());
imagep = &*remapped;
}
imagep = &*remapped;
}
if (fluxSource && decoder)
writeTracksAndVerify(fluxSink, encoder, *fluxSource, *decoder, *imagep);
@@ -346,9 +365,8 @@ void writeRawDiskCommand(FluxSource& fluxSource, FluxSink& fluxSink)
dontVerify);
}
std::shared_ptr<TrackFlux> readAndDecodeTrack(FluxSource& fluxSource,
AbstractDecoder& decoder,
const Location& location)
std::shared_ptr<TrackFlux> readAndDecodeTrack(
FluxSource& fluxSource, AbstractDecoder& decoder, const Location& location)
{
auto trackFlux = std::make_shared<TrackFlux>();
trackFlux->location = location;
@@ -378,7 +396,7 @@ std::shared_ptr<TrackFlux> readAndDecodeTrack(FluxSource& fluxSource,
retriesRemaining--;
}
return trackFlux;
return trackFlux;
}
std::shared_ptr<const DiskFlux> readDiskCommand(
@@ -390,12 +408,18 @@ std::shared_ptr<const DiskFlux> readDiskCommand(
auto diskflux = std::make_shared<DiskFlux>();
for (const auto& location : Mapper::computeLocations())
Logger() << BeginOperationLogMessage{"Reading and decoding disk"};
auto locations = Mapper::computeLocations();
unsigned index = 0;
for (const auto& location : locations)
{
Logger() << OperationProgressLogMessage{
index * 100 / (unsigned)locations.size()};
index++;
testForEmergencyStop();
auto trackFlux = readAndDecodeTrack(
fluxSource, decoder, location);
auto trackFlux = readAndDecodeTrack(fluxSource, decoder, location);
diskflux->tracks.push_back(trackFlux);
if (outputFluxSink)
@@ -478,6 +502,7 @@ std::shared_ptr<const DiskFlux> readDiskCommand(
/* diskflux can't be modified below this point. */
Logger() << DiskReadLogMessage{diskflux};
Logger() << EndOperationLogMessage{"Read complete"};
return diskflux;
}
@@ -494,10 +519,20 @@ void readDiskCommand(
void rawReadDiskCommand(FluxSource& fluxsource, FluxSink& fluxsink)
{
for (unsigned track : iterate(config.tracks()))
Logger() << BeginOperationLogMessage{"Performing raw read of disk"};
auto tracks = iterate(config.tracks());
auto heads = iterate(config.heads());
unsigned locations = tracks.size() * heads.size();
unsigned index = 0;
for (unsigned track : tracks)
{
for (unsigned head : iterate(config.heads()))
for (unsigned head : heads)
{
Logger() << OperationProgressLogMessage{index * 100 / locations};
index++;
testForEmergencyStop();
auto fluxSourceIterator = fluxsource.readFlux(track, head);
@@ -511,6 +546,8 @@ void rawReadDiskCommand(FluxSource& fluxsource, FluxSink& fluxsink)
fluxsink.writeFlux(track, head, *fluxmap);
}
}
Logger() << EndOperationLogMessage{"Raw read complete"};
}
void fillBitmapTo(std::vector<bool>& bitmap,

View File

@@ -34,6 +34,20 @@ std::string join(
}
}
std::vector<std::string> split(const std::string& string, char separator)
{
std::vector<std::string> result;
std::stringstream ss(string);
std::string item;
while (std::getline(ss, item, separator))
{
result.push_back(item);
}
return result;
}
bool beginsWith(const std::string& value, const std::string& ending)
{
if (ending.size() > value.size())
@@ -98,61 +112,60 @@ void testForEmergencyStop()
std::string toIso8601(time_t t)
{
auto* tm = std::gmtime(&t);
auto* tm = std::gmtime(&t);
std::stringstream ss;
ss << std::put_time(tm, "%FT%T%z");
return ss.str();
std::stringstream ss;
ss << std::put_time(tm, "%FT%T%z");
return ss.str();
}
std::string quote(const std::string& s)
{
bool spaces = s.find(' ') != std::string::npos;
if (!spaces
&& (s.find('\\') == std::string::npos)
&& (s.find('\'') == std::string::npos)
&& (s.find('"') == std::string::npos))
return s;
bool spaces = s.find(' ') != std::string::npos;
if (!spaces && (s.find('\\') == std::string::npos) &&
(s.find('\'') == std::string::npos) &&
(s.find('"') == std::string::npos))
return s;
std::stringstream ss;
if (spaces)
ss << '"';
std::stringstream ss;
if (spaces)
ss << '"';
for (char c : s)
{
if ((c == '\\') || (c == '\"') || (c == '!'))
ss << '\\';
ss << (char)c;
}
for (char c : s)
{
if ((c == '\\') || (c == '\"') || (c == '!'))
ss << '\\';
ss << (char)c;
}
if (spaces)
ss << '"';
return ss.str();
if (spaces)
ss << '"';
return ss.str();
}
std::string unhex(const std::string& s)
{
std::stringstream sin(s);
std::stringstream sout;
std::stringstream sin(s);
std::stringstream sout;
for (;;)
{
int c = sin.get();
if (c == -1)
break;
if (c == '%')
{
char buf[3];
buf[0] = sin.get();
buf[1] = sin.get();
buf[2] = 0;
for (;;)
{
int c = sin.get();
if (c == -1)
break;
if (c == '%')
{
char buf[3];
buf[0] = sin.get();
buf[1] = sin.get();
buf[2] = 0;
c = std::stoul(buf, nullptr, 16);
}
sout << (char)c;
}
c = std::stoul(buf, nullptr, 16);
}
sout << (char)c;
}
return sout.str();
return sout.str();
}
std::string tohex(const std::string& s)
@@ -169,4 +182,3 @@ std::string tohex(const std::string& s)
return ss.str();
}

View File

@@ -3,7 +3,10 @@
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
extern std::string join(const std::vector<std::string>& values, const std::string& separator);
extern std::string join(
const std::vector<std::string>& values, const std::string& separator);
extern std::vector<std::string> split(
const std::string& string, char separator);
extern bool beginsWith(const std::string& value, const std::string& beginning);
extern bool endsWith(const std::string& value, const std::string& ending);
extern std::string leftTrimWhitespace(std::string value);
@@ -19,8 +22,9 @@ extern std::string tohex(const std::string& s);
*/
extern bool emergencyStop;
class EmergencyStopException {};
class EmergencyStopException
{
};
extern void testForEmergencyStop();
#endif

View File

@@ -1,4 +1,5 @@
comment: 'Commodore 1541 common settings'
is_extension: true
image_reader {
filename: "commodore1541.d64"

View File

@@ -1,4 +1,5 @@
comment: 'DVK MX common settings'
is_extension: true
image_writer {
filename: "mx.img"

View File

@@ -1,12 +1,14 @@
ifneq ($(shell $(WX_CONFIG) --version),)
FLUXENGINE_GUI_SRCS = \
src/gui/customstatusbar.cc \
src/gui/fluxviewercontrol.cc \
src/gui/fluxviewerwindow.cc \
src/gui/hexviewerwindow.cc \
src/gui/layout.cpp \
src/gui/main.cc \
src/gui/mainwindow.cc \
src/gui/texteditorwindow.cc \
src/gui/textviewerwindow.cc \
src/gui/visualisationcontrol.cc \
FLUXENGINE_GUI_OBJS = \
@@ -15,9 +17,9 @@ FLUXENGINE_GUI_OBJS = \
)
OBJS += $(FLUXENGINE_GUI_OBJS)
$(FLUXENGINE_GUI_SRCS): | $(PROTO_HDRS)
$(FLUXENGINE_GUI_OBJS): CFLAGS += $(shell $(WX_CONFIG) --cxxflags core base)
$(FLUXENGINE_GUI_OBJS): CFLAGS += $(shell $(WX_CONFIG) --cxxflags core base adv)
FLUXENGINE_GUI_BIN = $(OBJDIR)/fluxengine-gui.exe
$(FLUXENGINE_GUI_BIN): LDFLAGS += $(shell $(WX_CONFIG) --libs core base)
$(FLUXENGINE_GUI_BIN): LDFLAGS += $(shell $(WX_CONFIG) --libs core base adv)
$(FLUXENGINE_GUI_BIN): $(FLUXENGINE_GUI_OBJS)
$(call use-pkgconfig, $(FLUXENGINE_GUI_BIN), $(FLUXENGINE_GUI_OBJS), fmt)

108
src/gui/customstatusbar.cc Normal file
View File

@@ -0,0 +1,108 @@
#include "lib/globals.h"
#include "gui.h"
#include "customstatusbar.h"
#include <wx/artprov.h>
#include <fmt/format.h>
// clang-format off
BEGIN_EVENT_TABLE(CustomStatusBar, wxStatusBar)
EVT_SIZE(CustomStatusBar::OnSize)
END_EVENT_TABLE()
// clang-format on
wxDEFINE_EVENT(PROGRESSBAR_STOP_EVENT, wxCommandEvent);
CustomStatusBar::CustomStatusBar(wxWindow* parent, wxWindowID id):
wxStatusBar(parent, id)
{
SetFieldsCount(4);
static const int widths[] = {-1, 200, 100, 20};
SetStatusWidths(4, widths);
static const int styles[] = { wxSB_FLAT, wxSB_FLAT, wxSB_FLAT, wxSB_FLAT };
SetStatusStyles(4, styles);
_progressBar.reset(new wxGauge(this,
wxID_ANY,
100,
wxDefaultPosition,
wxDefaultSize,
wxGA_HORIZONTAL | wxGA_SMOOTH));
_stopButton.reset(new wxButton(this,
wxID_ANY,
"Stop",
wxDefaultPosition,
wxDefaultSize,
wxBU_EXACTFIT));
//_stopButton->SetBitmap(wxArtProvider::GetBitmap(wxART_ERROR,
// wxART_BUTTON));
_stopButton->Bind(wxEVT_BUTTON,
[this](auto&)
{
auto* event = new wxCommandEvent(PROGRESSBAR_STOP_EVENT, 0);
event->SetEventObject(this);
QueueEvent(event);
});
_rightLabel.reset(new wxStaticText(this,
wxID_ANY,
"",
wxDefaultPosition,
wxDefaultSize,
wxALIGN_RIGHT | wxST_NO_AUTORESIZE));
HideProgressBar();
Layout();
}
void CustomStatusBar::OnSize(wxSizeEvent& event)
{
auto buttonSize = _stopButton->GetEffectiveMinSize();
wxRect r;
GetFieldRect(1, r);
int x = r.GetLeft();
int y = r.GetTop();
int w = r.GetWidth();
int h = r.GetHeight();
constexpr int b = 5;
_stopButton->SetPosition({x + w - buttonSize.GetWidth(), y});
_stopButton->SetSize(buttonSize.GetWidth(), h);
_progressBar->SetPosition({x, y});
_progressBar->SetSize(w - buttonSize.GetWidth() - b, h);
GetFieldRect(2, r);
_rightLabel->SetPosition(r.GetTopLeft());
_rightLabel->SetSize(r);
}
void CustomStatusBar::ShowProgressBar()
{
_progressBar->Show();
_stopButton->Show();
}
void CustomStatusBar::HideProgressBar()
{
_progressBar->Hide();
_stopButton->Hide();
}
void CustomStatusBar::SetProgress(int amount)
{
_progressBar->SetValue(amount);
}
void CustomStatusBar::SetLeftLabel(const std::string& text)
{
SetStatusText(text, 0);
}
void CustomStatusBar::SetRightLabel(const std::string& text)
{
_rightLabel->SetLabel(text);
}

32
src/gui/customstatusbar.h Normal file
View File

@@ -0,0 +1,32 @@
#ifndef CUSTOMSTATUSBAR_H
#define CUSTOMSTATUSBAR_H
class wxGauge;
class wxButton;
wxDECLARE_EVENT(PROGRESSBAR_STOP_EVENT, wxCommandEvent);
class CustomStatusBar : public wxStatusBar
{
public:
CustomStatusBar(wxWindow* parent, wxWindowID id);
public:
void ShowProgressBar();
void HideProgressBar();
void SetProgress(int amount);
void SetLeftLabel(const std::string& text);
void SetRightLabel(const std::string& text);
private:
void OnSize(wxSizeEvent& event);
private:
std::unique_ptr<wxGauge> _progressBar;
std::unique_ptr<wxButton> _stopButton;
std::unique_ptr<wxStaticText> _rightLabel;
DECLARE_EVENT_TABLE();
};
#endif

View File

@@ -1,7 +1,7 @@
#include "globals.h"
#include "gui.h"
#include "fluxviewercontrol.h"
#include "hexviewerwindow.h"
#include "textviewerwindow.h"
#include "lib/flux.h"
#include "lib/fluxmap.h"
#include "lib/sector.h"
@@ -389,20 +389,21 @@ void FluxViewerControl::ShowSectorMenu(std::shared_ptr<const Sector> sector)
{
wxMenu menu;
menu.Bind(wxEVT_COMMAND_MENU_SELECTED,
menu.Bind(wxEVT_MENU,
[&] (wxCommandEvent&) {
DisplayDecodedData(sector);
},
menu.Append(wxID_ANY, "Show decoded data")->GetId()
);
menu.Bind(wxEVT_COMMAND_MENU_SELECTED,
menu.Bind(wxEVT_MENU,
[&] (wxCommandEvent&) {
DisplayRawData(sector);
},
menu.Append(wxID_ANY, "Show raw data")->GetId()
);
_rightClicked = false;
PopupMenu(&menu, _mouseX, _mouseY);
}
@@ -417,6 +418,7 @@ void FluxViewerControl::ShowRecordMenu(const Location& location, std::shared_ptr
menu.Append(wxID_ANY, "Show record data")->GetId()
);
_rightClicked = false;
PopupMenu(&menu, _mouseX, _mouseY);
}
@@ -443,7 +445,7 @@ void FluxViewerControl::DisplayDecodedData(std::shared_ptr<const Sector> sector)
hexdump(s, sector->data);
HexViewerWindow::Create(this, title, s.str());
TextViewerWindow::Create(this, title, s.str())->Show();
}
void FluxViewerControl::DisplayRawData(std::shared_ptr<const Sector> sector)
@@ -462,7 +464,7 @@ void FluxViewerControl::DisplayRawData(std::shared_ptr<const Sector> sector)
hexdump(s, record->rawData);
}
HexViewerWindow::Create(this, title, s.str());
TextViewerWindow::Create(this, title, s.str())->Show();
}
void FluxViewerControl::DisplayRawData(const Location& location, std::shared_ptr<const Record> record)
@@ -474,5 +476,5 @@ void FluxViewerControl::DisplayRawData(const Location& location, std::shared_ptr
s << title << "\n\n";
hexdump(s, record->rawData);
HexViewerWindow::Create(this, title, s.str());
TextViewerWindow::Create(this, title, s.str())->Show();
}

View File

@@ -9,6 +9,8 @@ class MainWindow;
extern void runOnUiThread(std::function<void()> callback);
extern void runOnWorkerThread(std::function<void()> callback);
wxDECLARE_EVENT(UPDATE_STATE_EVENT, wxCommandEvent);
template <typename R>
static inline R runOnUiThread(std::function<R()> callback)
{
@@ -36,9 +38,13 @@ public:
protected:
virtual wxThread::ExitCode Entry();
private:
static wxWindow* CreateMainWindow();
void SendUpdateEvent();
private:
std::function<void()> _callback;
MainWindow* _mainWindow;
wxWindow* _mainWindow;
};
wxDECLARE_APP(FluxEngineApp);

View File

@@ -1,27 +0,0 @@
#include "globals.h"
#include "gui.h"
#include "layout.h"
#include "hexviewerwindow.h"
#include "fmt/format.h"
HexViewerWindow::HexViewerWindow(wxWindow* parent,
const std::string& title, const std::string& text):
HexViewerWindowGen(parent)
{
auto size = hexEntry->GetTextExtent("M");
SetSize(size.Scale(85, 25));
SetTitle(title);
hexEntry->SetValue(text);
}
void HexViewerWindow::Create(wxWindow* parent, const std::string& title, const std::string& text)
{
(new HexViewerWindow(parent, title, text))->Show(true);
}
void HexViewerWindow::OnExit(wxCommandEvent& event)
{
Close(true);
}

View File

@@ -1,18 +0,0 @@
#ifndef HEXVIEWERWINDOW_H
#define HEXVIEWERWINDOW_H
#include "layout.h"
class HexViewerWindow : public HexViewerWindowGen
{
public:
HexViewerWindow(wxWindow* parent, const std::string& title, const std::string& text);
static void Create(wxWindow* parent, const std::string& title, const std::string& text);
private:
void OnExit(wxCommandEvent& event);
};
#endif

View File

@@ -11,245 +11,393 @@
MainWindowGen::MainWindowGen( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxSize( 450,500 ), wxDefaultSize );
this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK ) );
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
bSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 );
bSizer1->AddGrowableCol( 1 );
bSizer1->AddGrowableRow( 0 );
bSizer1->SetFlexibleDirection( wxHORIZONTAL );
bSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
wxFlexGridSizer* fgSizer4;
fgSizer4 = new wxFlexGridSizer( 2, 1, 0, 0 );
fgSizer4->AddGrowableRow( 0 );
fgSizer4->SetFlexibleDirection( wxBOTH );
fgSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
visualiser = new VisualisationControl( this, wxID_ANY, wxDefaultPosition, wxSize( 200,480 ), wxBORDER_THEME );
visualiser->SetMinSize( wxSize( 200,480 ) );
fgSizer4->Add( visualiser, 1, wxALL|wxEXPAND, 5 );
stopButton = new wxButton( this, wxID_ANY, wxT("Stop"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer4->Add( stopButton, 0, wxALIGN_CENTER|wxALL, 5 );
bSizer1->Add( fgSizer4, 1, wxEXPAND, 5 );
wxFlexGridSizer* fgSizer2;
fgSizer2 = new wxFlexGridSizer( 0, 1, 0, 0 );
fgSizer2->AddGrowableCol( 0 );
fgSizer2->AddGrowableRow( 1 );
fgSizer2->SetFlexibleDirection( wxVERTICAL );
fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
wxFlexGridSizer* fgSizer3;
fgSizer3 = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSizer3->AddGrowableCol( 1 );
fgSizer3->SetFlexibleDirection( wxBOTH );
fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText4 = new wxStaticText( this, wxID_ANY, wxT("Device:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText4->Wrap( -1 );
fgSizer3->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL, 5 );
deviceCombo = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_SORT );
fgSizer3->Add( deviceCombo, 0, wxALL|wxEXPAND, 5 );
m_staticText5 = new wxStaticText( this, wxID_ANY, wxT("Flux source/sink:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText5->Wrap( -1 );
fgSizer3->Add( m_staticText5, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL, 5 );
fluxSourceSinkCombo = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
fluxSourceSinkCombo->Append( wxT("drive:0") );
fluxSourceSinkCombo->Append( wxT("drive:1") );
fgSizer3->Add( fluxSourceSinkCombo, 0, wxALL|wxEXPAND, 5 );
m_staticText51 = new wxStaticText( this, wxID_ANY, wxT("Format:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText51->Wrap( -1 );
fgSizer3->Add( m_staticText51, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL, 5 );
wxArrayString formatChoiceChoices;
formatChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, formatChoiceChoices, wxCB_SORT );
formatChoice->SetSelection( 0 );
fgSizer3->Add( formatChoice, 0, wxALL|wxEXPAND, 5 );
fgSizer3->Add( 0, 0, 1, wxEXPAND, 5 );
highDensityToggle = new wxCheckBox( this, wxID_ANY, wxT("High density disk"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer3->Add( highDensityToggle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL, 5 );
fgSizer2->Add( fgSizer3, 1, wxEXPAND, 5 );
notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_panel1 = new wxPanel( notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxFlexGridSizer* fgSizer5;
fgSizer5 = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSizer5->AddGrowableCol( 0 );
fgSizer5->AddGrowableRow( 0 );
fgSizer5->SetFlexibleDirection( wxBOTH );
fgSizer5->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
additionalSettingsEntry = new wxTextCtrl( m_panel1, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
fgSizer5->Add( additionalSettingsEntry, 0, wxALL|wxEXPAND, 5 );
m_panel1->SetSizer( fgSizer5 );
m_panel1->Layout();
fgSizer5->Fit( m_panel1 );
notebook->AddPage( m_panel1, wxT("Additional settings"), true );
m_panel2 = new wxPanel( notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxFlexGridSizer* fgSizer8;
fgSizer8 = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSizer8->AddGrowableCol( 0 );
fgSizer8->AddGrowableRow( 0 );
fgSizer8->SetFlexibleDirection( wxBOTH );
fgSizer8->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
logEntry = new wxTextCtrl( m_panel2, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH );
fgSizer8->Add( logEntry, 0, wxALL|wxEXPAND, 5 );
m_panel2->SetSizer( fgSizer8 );
m_panel2->Layout();
fgSizer8->Fit( m_panel2 );
notebook->AddPage( m_panel2, wxT("Logs"), false );
m_panel3 = new wxPanel( notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxFlexGridSizer* fgSizer9;
fgSizer9 = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSizer9->AddGrowableCol( 0 );
fgSizer9->AddGrowableRow( 0 );
fgSizer9->SetFlexibleDirection( wxBOTH );
fgSizer9->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
protoConfigEntry = new wxTextCtrl( m_panel3, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY );
fgSizer9->Add( protoConfigEntry, 0, wxALL|wxEXPAND, 5 );
m_panel3->SetSizer( fgSizer9 );
m_panel3->Layout();
fgSizer9->Fit( m_panel3 );
notebook->AddPage( m_panel3, wxT("Debug info"), false );
fgSizer2->Add( notebook, 1, wxEXPAND | wxALL, 5 );
wxGridSizer* m_sizer;
m_sizer = new wxGridSizer( 0, 2, 0, 0 );
readFluxButton = new wxButton( this, wxID_ANY, wxT("Read flux"), wxDefaultPosition, wxDefaultSize, 0 );
m_sizer->Add( readFluxButton, 0, wxALL|wxEXPAND, 5 );
readImageButton = new wxButton( this, wxID_ANY, wxT("Read image"), wxDefaultPosition, wxDefaultSize, 0 );
m_sizer->Add( readImageButton, 0, wxALL|wxEXPAND, 5 );
writeFluxButton = new wxButton( this, wxID_ANY, wxT("Write flux"), wxDefaultPosition, wxDefaultSize, 0 );
m_sizer->Add( writeFluxButton, 0, wxALL|wxEXPAND, 5 );
writeImageButton = new wxButton( this, wxID_ANY, wxT("Write image"), wxDefaultPosition, wxDefaultSize, 0 );
m_sizer->Add( writeImageButton, 0, wxALL|wxEXPAND, 5 );
fgSizer2->Add( m_sizer, 1, wxEXPAND|wxFIXED_MINSIZE, 5 );
bSizer1->Add( fgSizer2, 1, wxEXPAND, 5 );
this->SetSizer( bSizer1 );
this->Layout();
m_menubar1 = new wxMenuBar( 0 );
menuBar = new wxMenuBar( 0 );
m_menu1 = new wxMenu();
wxMenuItem* m_menuItem2;
m_menuItem2 = new wxMenuItem( m_menu1, wxID_ABOUT, wxString( wxT("About") ) , wxEmptyString, wxITEM_NORMAL );
m_menuItem2 = new wxMenuItem( m_menu1, wxID_ABOUT, wxString( wxT("&About") ) , wxEmptyString, wxITEM_NORMAL );
m_menu1->Append( m_menuItem2 );
wxMenuItem* m_menuItem1;
m_menuItem1 = new wxMenuItem( m_menu1, wxID_EXIT, wxString( wxT("E&xit") ) , wxEmptyString, wxITEM_NORMAL );
m_menu1->Append( m_menuItem1 );
m_menubar1->Append( m_menu1, wxT("&File") );
menuBar->Append( m_menu1, wxT("&File") );
this->SetMenuBar( m_menubar1 );
m_menu2 = new wxMenu();
wxMenuItem* m_menuItem3;
m_menuItem3 = new wxMenuItem( m_menu2, wxID_ANY, wxString( wxT("Show &logs...") ) + wxT('\t') + wxT("CTRL+L"), wxEmptyString, wxITEM_NORMAL );
m_menu2->Append( m_menuItem3 );
wxMenuItem* m_menuItem4;
m_menuItem4 = new wxMenuItem( m_menu2, wxID_ANY, wxString( wxT("Show current &configuration...") ) , wxEmptyString, wxITEM_NORMAL );
m_menu2->Append( m_menuItem4 );
menuBar->Append( m_menu2, wxT("&View") );
this->SetMenuBar( menuBar );
wxBoxSizer* bSizer4;
bSizer4 = new wxBoxSizer( wxVERTICAL );
dataNotebook = new wxSimplebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
idlePanel = new wxScrolledWindow( dataNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL );
idlePanel->SetScrollRate( 5, 5 );
wxGridSizer* gSizer11;
gSizer11 = new wxGridSizer( 1, 1, 0, 0 );
wxFlexGridSizer* fgSizer8;
fgSizer8 = new wxFlexGridSizer( 0, 1, 0, 0 );
fgSizer8->AddGrowableCol( 0 );
fgSizer8->SetFlexibleDirection( wxBOTH );
fgSizer8->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
fgSizer8->SetMinSize( wxSize( 400,-1 ) );
m_staticText61 = new wxStaticText( idlePanel, wxID_ANY, wxT("Pick one of:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText61->Wrap( -1 );
fgSizer8->Add( m_staticText61, 0, wxALIGN_CENTER|wxALL, 5 );
realDiskRadioButton = new wxRadioButton( idlePanel, wxID_ANY, wxT("Real disk"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
realDiskRadioButton->SetToolTip( wxT("You want to use a real floppy drive attached to real hardware.") );
fgSizer8->Add( realDiskRadioButton, 0, wxALL|wxEXPAND, 5 );
realDiskRadioButtonPanel = new wxPanel( idlePanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer3;
bSizer3 = new wxBoxSizer( wxVERTICAL );
deviceCombo = new wxComboBox( realDiskRadioButtonPanel, wxID_ANY, wxT("Combo!"), wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
deviceCombo->SetToolTip( wxT("Device ID to use (either the path of a serial port or a USB serial number).") );
bSizer3->Add( deviceCombo, 0, wxALL|wxEXPAND, 5 );
wxString driveChoiceChoices[] = { wxT("drive:0"), wxT("drive:1") };
int driveChoiceNChoices = sizeof( driveChoiceChoices ) / sizeof( wxString );
driveChoice = new wxChoice( realDiskRadioButtonPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, driveChoiceNChoices, driveChoiceChoices, 0 );
driveChoice->SetSelection( 0 );
driveChoice->SetToolTip( wxT("Which drive on the device to use.") );
bSizer3->Add( driveChoice, 0, wxALL|wxEXPAND, 5 );
highDensityToggle = new wxCheckBox( realDiskRadioButtonPanel, wxID_ANY, wxT("This is a high density disk"), wxDefaultPosition, wxDefaultSize, 0 );
highDensityToggle->SetToolTip( wxT("If you are using a high density disk, select this.\nThis can be detected automatically for 3.5\"\ndisks but needs to be set manually for everything\nelse.") );
bSizer3->Add( highDensityToggle, 0, wxALL|wxEXPAND, 5 );
// Connect Events
m_menu1->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainWindowGen::OnAbout ), this, m_menuItem2->GetId());
m_menu1->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainWindowGen::OnExit ), this, m_menuItem1->GetId());
}
realDiskRadioButtonPanel->SetSizer( bSizer3 );
realDiskRadioButtonPanel->Layout();
bSizer3->Fit( realDiskRadioButtonPanel );
fgSizer8->Add( realDiskRadioButtonPanel, 1, wxEXPAND | wxALL, 5 );
MainWindowGen::~MainWindowGen()
{
// Disconnect Events
fluxImageRadioButton = new wxRadioButton( idlePanel, wxID_ANY, wxT("Flux image"), wxDefaultPosition, wxDefaultSize, 0 );
fluxImageRadioButton->SetToolTip( wxT("You want to use an unencoded flux file.") );
}
fgSizer8->Add( fluxImageRadioButton, 0, wxALL|wxEXPAND, 5 );
FluxViewerWindowGen::FluxViewerWindowGen( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
fluxImageRadioButtonPanel = new wxPanel( idlePanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxGridSizer* gSizer121;
gSizer121 = new wxGridSizer( 1, 1, 0, 0 );
m_menubar2 = new wxMenuBar( 0 );
m_menu1 = new wxMenu();
wxMenuItem* m_menuItem1;
m_menuItem1 = new wxMenuItem( m_menu1, wxID_CLOSE, wxString( wxT("&Close") ) , wxEmptyString, wxITEM_NORMAL );
m_menu1->Append( m_menuItem1 );
fluxImagePicker = new wxFilePickerCtrl( fluxImageRadioButtonPanel, wxID_ANY, wxEmptyString, wxT("Select a file"), wxT("*.*"), wxDefaultPosition, wxDefaultSize, wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_USE_TEXTCTRL );
fluxImagePicker->SetToolTip( wxT("Path to a .flux, .scp or other flux file.") );
m_menubar2->Append( m_menu1, wxT("&Window") );
this->SetMenuBar( m_menubar2 );
wxBoxSizer* bSizer1;
bSizer1 = new wxBoxSizer( wxVERTICAL );
fluxviewer = new FluxViewerControl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
bSizer1->Add( fluxviewer, 1, wxEXPAND, 5 );
scrollbar = new wxScrollBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSB_HORIZONTAL );
bSizer1->Add( scrollbar, 0, wxALIGN_BOTTOM|wxEXPAND, 5 );
gSizer121->Add( fluxImagePicker, 0, wxALL|wxEXPAND, 5 );
this->SetSizer( bSizer1 );
fluxImageRadioButtonPanel->SetSizer( gSizer121 );
fluxImageRadioButtonPanel->Layout();
gSizer121->Fit( fluxImageRadioButtonPanel );
fgSizer8->Add( fluxImageRadioButtonPanel, 1, wxEXPAND | wxALL, 5 );
diskImageRadioButton = new wxRadioButton( idlePanel, wxID_ANY, wxT("Disk image"), wxDefaultPosition, wxDefaultSize, 0 );
diskImageRadioButton->SetToolTip( wxT("You want to use a decode file system disk image.") );
fgSizer8->Add( diskImageRadioButton, 0, wxALL|wxEXPAND, 5 );
diskImageRadioButtonPanel = new wxPanel( idlePanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxGridSizer* gSizer1211;
gSizer1211 = new wxGridSizer( 1, 1, 0, 0 );
diskImagePicker = new wxFilePickerCtrl( diskImageRadioButtonPanel, wxID_ANY, wxEmptyString, wxT("Select a file"), wxT("*.*"), wxDefaultPosition, wxDefaultSize, wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_USE_TEXTCTRL );
diskImagePicker->SetToolTip( wxT("The path to the disk image.") );
gSizer1211->Add( diskImagePicker, 0, wxALL|wxEXPAND, 5 );
diskImageRadioButtonPanel->SetSizer( gSizer1211 );
diskImageRadioButtonPanel->Layout();
gSizer1211->Fit( diskImageRadioButtonPanel );
fgSizer8->Add( diskImageRadioButtonPanel, 1, wxEXPAND | wxALL, 5 );
m_staticText23 = new wxStaticText( idlePanel, wxID_ANY, wxT("then select a format:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText23->Wrap( -1 );
fgSizer8->Add( m_staticText23, 0, wxALIGN_CENTER|wxALL, 5 );
m_panel11 = new wxPanel( idlePanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxFlexGridSizer* fgSizer6;
fgSizer6 = new wxFlexGridSizer( 1, 2, 0, 0 );
fgSizer6->AddGrowableCol( 0 );
fgSizer6->SetFlexibleDirection( wxBOTH );
fgSizer6->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
wxArrayString formatChoiceChoices;
formatChoice = new wxChoice( m_panel11, wxID_ANY, wxDefaultPosition, wxDefaultSize, formatChoiceChoices, 0 );
formatChoice->SetSelection( 0 );
formatChoice->SetToolTip( wxT("The format of the disk.") );
fgSizer6->Add( formatChoice, 0, wxALL|wxEXPAND, 5 );
customConfigurationButton = new wxButton( m_panel11, wxID_ANY, wxT("Customise..."), wxDefaultPosition, wxDefaultSize, 0 );
customConfigurationButton->SetToolTip( wxT("Allows you to enter arbitrary configuration parameters.") );
fgSizer6->Add( customConfigurationButton, 0, wxALL, 5 );
m_panel11->SetSizer( fgSizer6 );
m_panel11->Layout();
fgSizer6->Fit( m_panel11 );
fgSizer8->Add( m_panel11, 1, wxEXPAND | wxALL, 5 );
m_staticText19 = new wxStaticText( idlePanel, wxID_ANY, wxT("and press one of:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText19->Wrap( -1 );
fgSizer8->Add( m_staticText19, 0, wxALIGN_CENTER|wxALL, 5 );
wxGridSizer* gSizer9;
gSizer9 = new wxGridSizer( 1, 0, 0, 0 );
readButton = new wxButton( idlePanel, wxID_ANY, wxT("Read disk"), wxDefaultPosition, wxDefaultSize, 0 );
readButton->SetLabelMarkup( wxT("Read disk") );
readButton->SetBitmap( wxArtProvider::GetBitmap( wxART_FILE_OPEN, wxART_TOOLBAR ) );
readButton->SetToolTip( wxT("Read and decode, producing a disk image from a real disk or flux file.") );
gSizer9->Add( readButton, 0, wxALL|wxEXPAND, 5 );
writeButton = new wxButton( idlePanel, wxID_ANY, wxT("Write disk"), wxDefaultPosition, wxDefaultSize, 0 );
writeButton->SetBitmap( wxArtProvider::GetBitmap( wxART_FILE_SAVE, wxART_TOOLBAR ) );
writeButton->SetBitmapDisabled( wxNullBitmap );
writeButton->SetToolTip( wxT("Encode and write to either a real disk or a flux file.") );
gSizer9->Add( writeButton, 0, wxALL|wxEXPAND, 5 );
browseButton = new wxButton( idlePanel, wxID_ANY, wxT("Browse disk"), wxDefaultPosition, wxDefaultSize, 0 );
browseButton->SetBitmap( wxArtProvider::GetBitmap( wxART_FOLDER_OPEN, wxART_TOOLBAR ) );
browseButton->Enable( false );
browseButton->SetToolTip( wxT("Access the files on the disk directly without needing to image it.") );
gSizer9->Add( browseButton, 0, wxALL|wxEXPAND, 5 );
fgSizer8->Add( gSizer9, 1, wxEXPAND, 5 );
gSizer11->Add( fgSizer8, 1, wxALIGN_CENTER|wxALL, 5 );
idlePanel->SetSizer( gSizer11 );
idlePanel->Layout();
gSizer11->Fit( idlePanel );
dataNotebook->AddPage( idlePanel, wxT("a page"), false );
imagePanel = new wxPanel( dataNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer41;
bSizer41 = new wxBoxSizer( wxVERTICAL );
imagerToolbar = new wxToolBar( imagePanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTB_FLAT|wxTB_HORIZONTAL|wxTB_TEXT );
imagerBackTool = imagerToolbar->AddTool( wxID_ANY, wxT("Back"), wxArtProvider::GetBitmap( wxART_GO_BACK, wxART_TOOLBAR ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
imagerToolbar->Realize();
bSizer41->Add( imagerToolbar, 0, wxEXPAND, 5 );
wxGridSizer* gSizer122;
gSizer122 = new wxGridSizer( 0, 2, 0, 0 );
wxGridSizer* gSizer5;
gSizer5 = new wxGridSizer( 0, 1, 0, 0 );
visualiser = new VisualisationControl( imagePanel, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxBORDER_THEME );
gSizer5->Add( visualiser, 0, wxALL|wxEXPAND, 5 );
gSizer122->Add( gSizer5, 1, wxEXPAND, 5 );
wxGridSizer* gSizer7;
gSizer7 = new wxGridSizer( 1, 1, 0, 0 );
wxGridSizer* gSizer8;
gSizer8 = new wxGridSizer( 0, 1, 0, 0 );
imagerSaveImageButton = new wxButton( imagePanel, wxID_ANY, wxT("Save decoded image"), wxDefaultPosition, wxDefaultSize, 0 );
imagerSaveImageButton->SetBitmap( wxArtProvider::GetBitmap( wxART_FILE_SAVE, wxART_BUTTON ) );
gSizer8->Add( imagerSaveImageButton, 0, wxALL|wxEXPAND, 5 );
imagerSaveFluxButton = new wxButton( imagePanel, wxID_ANY, wxT("Save raw flux"), wxDefaultPosition, wxDefaultSize, 0 );
imagerSaveFluxButton->SetBitmap( wxArtProvider::GetBitmap( wxART_FILE_SAVE_AS, wxART_BUTTON ) );
gSizer8->Add( imagerSaveFluxButton, 0, wxALL|wxEXPAND, 5 );
m_staticText4 = new wxStaticText( imagePanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_staticText4->Wrap( -1 );
gSizer8->Add( m_staticText4, 0, wxALL, 5 );
imagerGoAgainButton = new wxButton( imagePanel, wxID_ANY, wxT("Go again"), wxDefaultPosition, wxDefaultSize, 0 );
imagerGoAgainButton->SetBitmap( wxArtProvider::GetBitmap( wxART_REDO, wxART_BUTTON ) );
gSizer8->Add( imagerGoAgainButton, 0, wxALL|wxEXPAND, 5 );
gSizer7->Add( gSizer8, 1, wxALIGN_CENTER, 5 );
gSizer122->Add( gSizer7, 1, wxEXPAND, 5 );
bSizer41->Add( gSizer122, 1, wxEXPAND, 5 );
imagePanel->SetSizer( bSizer41 );
imagePanel->Layout();
bSizer41->Fit( imagePanel );
dataNotebook->AddPage( imagePanel, wxT("a page"), false );
browsePanel = new wxPanel( dataNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxFlexGridSizer* fgSizer23;
fgSizer23 = new wxFlexGridSizer( 0, 1, 0, 0 );
fgSizer23->AddGrowableCol( 0 );
fgSizer23->AddGrowableRow( 1 );
fgSizer23->SetFlexibleDirection( wxBOTH );
fgSizer23->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
browserToolbar = new wxToolBar( browsePanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTB_FLAT|wxTB_HORIZONTAL|wxTB_TEXT );
browserBackTool = browserToolbar->AddTool( wxID_ANY, wxT("Back"), wxArtProvider::GetBitmap( wxART_GO_BACK, wxART_TOOLBAR ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL );
browserToolbar->Realize();
fgSizer23->Add( browserToolbar, 0, wxEXPAND, 5 );
m_scrolledWindow1 = new wxScrolledWindow( browsePanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL );
m_scrolledWindow1->SetScrollRate( 5, 5 );
wxGridSizer* gSizer13;
gSizer13 = new wxGridSizer( 1, 1, 0, 0 );
browserView = new wxDataViewCtrl( m_scrolledWindow1, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
browserFilenameColumn = browserView->AppendTextColumn( wxT("Filename"), 0, wxDATAVIEW_CELL_INERT, -1, static_cast<wxAlignment>(wxALIGN_LEFT), wxDATAVIEW_COL_RESIZABLE );
browserModeColumn = browserView->AppendTextColumn( wxT("Mode"), 1, wxDATAVIEW_CELL_INERT, -1, static_cast<wxAlignment>(wxALIGN_LEFT), wxDATAVIEW_COL_RESIZABLE );
browserLengthColumn = browserView->AppendTextColumn( wxT("Length"), 2, wxDATAVIEW_CELL_INERT, -1, static_cast<wxAlignment>(wxALIGN_LEFT), wxDATAVIEW_COL_RESIZABLE );
browserExtraColumn = browserView->AppendTextColumn( wxT("Additional properties"), 0, wxDATAVIEW_CELL_INERT, -1, static_cast<wxAlignment>(wxALIGN_LEFT), wxDATAVIEW_COL_RESIZABLE );
gSizer13->Add( browserView, 0, wxEXPAND, 5 );
m_scrolledWindow1->SetSizer( gSizer13 );
m_scrolledWindow1->Layout();
gSizer13->Fit( m_scrolledWindow1 );
fgSizer23->Add( m_scrolledWindow1, 1, wxEXPAND | wxALL, 5 );
wxGridSizer* gSizer12;
gSizer12 = new wxGridSizer( 0, 2, 0, 0 );
browserDiscardButton = new wxButton( browsePanel, wxID_ANY, wxT("Discard pending changes"), wxDefaultPosition, wxDefaultSize, 0 );
browserDiscardButton->SetBitmap( wxArtProvider::GetBitmap( wxART_WARNING, wxART_BUTTON ) );
gSizer12->Add( browserDiscardButton, 0, wxALIGN_CENTER|wxALL, 5 );
browserCommitButton = new wxButton( browsePanel, wxID_ANY, wxT("Commit pending changes to disk"), wxDefaultPosition, wxDefaultSize, 0 );
browserCommitButton->SetBitmap( wxArtProvider::GetBitmap( wxART_FILE_SAVE, wxART_BUTTON ) );
gSizer12->Add( browserCommitButton, 0, wxALIGN_CENTER|wxALL, 5 );
fgSizer23->Add( gSizer12, 1, wxEXPAND, 5 );
browsePanel->SetSizer( fgSizer23 );
browsePanel->Layout();
fgSizer23->Fit( browsePanel );
dataNotebook->AddPage( browsePanel, wxT("a page"), false );
bSizer4->Add( dataNotebook, 1, wxEXPAND, 5 );
this->SetSizer( bSizer4 );
this->Layout();
this->Centre( wxBOTH );
// Connect Events
m_menu1->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( FluxViewerWindowGen::OnExit ), this, m_menuItem1->GetId());
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( MainWindowGen::OnClose ) );
m_menu1->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainWindowGen::OnAboutMenuItem ), this, m_menuItem2->GetId());
m_menu1->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainWindowGen::OnExit ), this, m_menuItem1->GetId());
m_menu2->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainWindowGen::OnShowLogWindow ), this, m_menuItem3->GetId());
m_menu2->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainWindowGen::OnShowConfigWindow ), this, m_menuItem4->GetId());
realDiskRadioButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( MainWindowGen::OnConfigRadioButtonClicked ), NULL, this );
deviceCombo->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( MainWindowGen::OnControlsChanged ), NULL, this );
driveChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( MainWindowGen::OnControlsChanged ), NULL, this );
highDensityToggle->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainWindowGen::OnControlsChanged ), NULL, this );
fluxImageRadioButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( MainWindowGen::OnConfigRadioButtonClicked ), NULL, this );
fluxImagePicker->Connect( wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler( MainWindowGen::OnControlsChanged ), NULL, this );
diskImageRadioButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( MainWindowGen::OnConfigRadioButtonClicked ), NULL, this );
diskImagePicker->Connect( wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler( MainWindowGen::OnControlsChanged ), NULL, this );
formatChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( MainWindowGen::OnControlsChanged ), NULL, this );
customConfigurationButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnCustomConfigurationButton ), NULL, this );
readButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnReadButton ), NULL, this );
writeButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnWriteButton ), NULL, this );
this->Connect( imagerBackTool->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( MainWindowGen::OnBackButton ) );
imagerSaveImageButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnSaveImageButton ), NULL, this );
imagerSaveFluxButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnSaveFluxButton ), NULL, this );
imagerGoAgainButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnImagerGoAgainButton ), NULL, this );
this->Connect( browserBackTool->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( MainWindowGen::OnBackButton ) );
}
FluxViewerWindowGen::~FluxViewerWindowGen()
MainWindowGen::~MainWindowGen()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( MainWindowGen::OnClose ) );
realDiskRadioButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( MainWindowGen::OnConfigRadioButtonClicked ), NULL, this );
deviceCombo->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( MainWindowGen::OnControlsChanged ), NULL, this );
driveChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( MainWindowGen::OnControlsChanged ), NULL, this );
highDensityToggle->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainWindowGen::OnControlsChanged ), NULL, this );
fluxImageRadioButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( MainWindowGen::OnConfigRadioButtonClicked ), NULL, this );
fluxImagePicker->Disconnect( wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler( MainWindowGen::OnControlsChanged ), NULL, this );
diskImageRadioButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( MainWindowGen::OnConfigRadioButtonClicked ), NULL, this );
diskImagePicker->Disconnect( wxEVT_COMMAND_FILEPICKER_CHANGED, wxFileDirPickerEventHandler( MainWindowGen::OnControlsChanged ), NULL, this );
formatChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( MainWindowGen::OnControlsChanged ), NULL, this );
customConfigurationButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnCustomConfigurationButton ), NULL, this );
readButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnReadButton ), NULL, this );
writeButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnWriteButton ), NULL, this );
this->Disconnect( imagerBackTool->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( MainWindowGen::OnBackButton ) );
imagerSaveImageButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnSaveImageButton ), NULL, this );
imagerSaveFluxButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnSaveFluxButton ), NULL, this );
imagerGoAgainButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainWindowGen::OnImagerGoAgainButton ), NULL, this );
this->Disconnect( browserBackTool->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( MainWindowGen::OnBackButton ) );
}
HexViewerWindowGen::HexViewerWindowGen( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
TextViewerWindowGen::TextViewerWindowGen( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
m_menubar2 = new wxMenuBar( 0 );
m_menu1 = new wxMenu();
wxMenuItem* m_menuItem1;
m_menuItem1 = new wxMenuItem( m_menu1, wxID_CLOSE, wxString( wxT("&Close") ) , wxEmptyString, wxITEM_NORMAL );
m_menu1->Append( m_menuItem1 );
m_menubar2->Append( m_menu1, wxT("&Window") );
this->SetMenuBar( m_menubar2 );
wxFlexGridSizer* fgSizer8;
fgSizer8 = new wxFlexGridSizer( 1, 1, 0, 0 );
fgSizer8 = new wxFlexGridSizer( 0, 1, 0, 0 );
fgSizer8->AddGrowableCol( 0 );
fgSizer8->AddGrowableRow( 0 );
fgSizer8->SetFlexibleDirection( wxHORIZONTAL );
fgSizer8->SetFlexibleDirection( wxBOTH );
fgSizer8->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
hexEntry = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH );
hexEntry->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
textControl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH );
textControl->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
fgSizer8->Add( hexEntry, 0, wxALL|wxEXPAND, 5 );
fgSizer8->Add( textControl, 0, wxALL|wxEXPAND, 5 );
m_sdbSizer2 = new wxStdDialogButtonSizer();
m_sdbSizer2OK = new wxButton( this, wxID_OK );
m_sdbSizer2->AddButton( m_sdbSizer2OK );
m_sdbSizer2->Realize();
fgSizer8->Add( m_sdbSizer2, 1, wxALL|wxEXPAND, 5 );
this->SetSizer( fgSizer8 );
@@ -258,11 +406,104 @@ HexViewerWindowGen::HexViewerWindowGen( wxWindow* parent, wxWindowID id, const w
this->Centre( wxBOTH );
// Connect Events
m_menu1->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( HexViewerWindowGen::OnExit ), this, m_menuItem1->GetId());
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( TextViewerWindowGen::OnClose ) );
m_sdbSizer2OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( TextViewerWindowGen::OnClose ), NULL, this );
}
HexViewerWindowGen::~HexViewerWindowGen()
TextViewerWindowGen::~TextViewerWindowGen()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( TextViewerWindowGen::OnClose ) );
m_sdbSizer2OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( TextViewerWindowGen::OnClose ), NULL, this );
}
FluxViewerWindowGen::FluxViewerWindowGen( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxSize( 200,100 ), wxDefaultSize );
wxFlexGridSizer* fgSizer5;
fgSizer5 = new wxFlexGridSizer( 0, 1, 0, 0 );
fgSizer5->AddGrowableCol( 0 );
fgSizer5->AddGrowableRow( 0 );
fgSizer5->SetFlexibleDirection( wxBOTH );
fgSizer5->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
fluxviewer = new FluxViewerControl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer5->Add( fluxviewer, 1, wxEXPAND, 5 );
scrollbar = new wxScrollBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSB_HORIZONTAL );
fgSizer5->Add( scrollbar, 0, wxALIGN_BOTTOM|wxEXPAND, 5 );
m_sdbSizer2 = new wxStdDialogButtonSizer();
m_sdbSizer2OK = new wxButton( this, wxID_OK );
m_sdbSizer2->AddButton( m_sdbSizer2OK );
m_sdbSizer2->Realize();
fgSizer5->Add( m_sdbSizer2, 1, wxALL|wxEXPAND, 5 );
this->SetSizer( fgSizer5 );
this->Layout();
this->Centre( wxBOTH );
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( FluxViewerWindowGen::OnClose ) );
m_sdbSizer2OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FluxViewerWindowGen::OnClose ), NULL, this );
}
FluxViewerWindowGen::~FluxViewerWindowGen()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( FluxViewerWindowGen::OnClose ) );
m_sdbSizer2OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FluxViewerWindowGen::OnClose ), NULL, this );
}
TextEditorWindowGen::TextEditorWindowGen( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxFlexGridSizer* fgSizer8;
fgSizer8 = new wxFlexGridSizer( 0, 1, 0, 0 );
fgSizer8->AddGrowableCol( 0 );
fgSizer8->AddGrowableRow( 0 );
fgSizer8->SetFlexibleDirection( wxBOTH );
fgSizer8->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
textControl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_PROCESS_TAB );
textControl->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
fgSizer8->Add( textControl, 0, wxALL|wxEXPAND, 5 );
m_sdbSizer2 = new wxStdDialogButtonSizer();
m_sdbSizer2Save = new wxButton( this, wxID_SAVE );
m_sdbSizer2->AddButton( m_sdbSizer2Save );
m_sdbSizer2Cancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer2->AddButton( m_sdbSizer2Cancel );
m_sdbSizer2->Realize();
fgSizer8->Add( m_sdbSizer2, 1, wxALL|wxEXPAND, 5 );
this->SetSizer( fgSizer8 );
this->Layout();
fgSizer8->Fit( this );
this->Centre( wxBOTH );
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( TextEditorWindowGen::OnClose ) );
m_sdbSizer2Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( TextEditorWindowGen::OnCancel ), NULL, this );
m_sdbSizer2Save->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( TextEditorWindowGen::OnSave ), NULL, this );
}
TextEditorWindowGen::~TextEditorWindowGen()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( TextEditorWindowGen::OnClose ) );
m_sdbSizer2Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( TextEditorWindowGen::OnCancel ), NULL, this );
m_sdbSizer2Save->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( TextEditorWindowGen::OnSave ), NULL, this );
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -9,26 +9,32 @@
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include "visualisationcontrol.h"
#include <wx/string.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/menu.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/button.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/radiobut.h>
#include <wx/combobox.h>
#include <wx/choice.h>
#include <wx/checkbox.h>
#include <wx/textctrl.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/notebook.h>
#include <wx/menu.h>
#include <wx/filepicker.h>
#include <wx/button.h>
#include <wx/scrolwin.h>
#include <wx/toolbar.h>
#include "visualisationcontrol.h"
#include <wx/dataview.h>
#include <wx/simplebook.h>
#include <wx/frame.h>
#include <wx/textctrl.h>
#include <wx/dialog.h>
#include "fluxviewercontrol.h"
#include <wx/scrolbar.h>
@@ -40,91 +46,154 @@
class MainWindowGen : public wxFrame
{
private:
wxFlexGridSizer* bSizer1;
protected:
VisualisationControl* visualiser;
wxButton* stopButton;
wxStaticText* m_staticText4;
wxComboBox* deviceCombo;
wxStaticText* m_staticText5;
wxComboBox* fluxSourceSinkCombo;
wxStaticText* m_staticText51;
wxChoice* formatChoice;
wxCheckBox* highDensityToggle;
wxNotebook* notebook;
wxPanel* m_panel1;
wxTextCtrl* additionalSettingsEntry;
wxPanel* m_panel2;
wxTextCtrl* logEntry;
wxPanel* m_panel3;
wxTextCtrl* protoConfigEntry;
wxButton* readFluxButton;
wxButton* readImageButton;
wxButton* writeFluxButton;
wxButton* writeImageButton;
wxMenuBar* m_menubar1;
wxMenuBar* menuBar;
wxMenu* m_menu1;
wxMenu* m_menu2;
wxSimplebook* dataNotebook;
wxScrolledWindow* idlePanel;
wxStaticText* m_staticText61;
wxRadioButton* realDiskRadioButton;
wxPanel* realDiskRadioButtonPanel;
wxComboBox* deviceCombo;
wxChoice* driveChoice;
wxCheckBox* highDensityToggle;
wxRadioButton* fluxImageRadioButton;
wxPanel* fluxImageRadioButtonPanel;
wxFilePickerCtrl* fluxImagePicker;
wxRadioButton* diskImageRadioButton;
wxPanel* diskImageRadioButtonPanel;
wxFilePickerCtrl* diskImagePicker;
wxStaticText* m_staticText23;
wxPanel* m_panel11;
wxChoice* formatChoice;
wxButton* customConfigurationButton;
wxStaticText* m_staticText19;
wxButton* readButton;
wxButton* writeButton;
wxButton* browseButton;
wxPanel* imagePanel;
wxToolBar* imagerToolbar;
wxToolBarToolBase* imagerBackTool;
VisualisationControl* visualiser;
wxButton* imagerSaveImageButton;
wxButton* imagerSaveFluxButton;
wxStaticText* m_staticText4;
wxButton* imagerGoAgainButton;
wxPanel* browsePanel;
wxToolBar* browserToolbar;
wxToolBarToolBase* browserBackTool;
wxScrolledWindow* m_scrolledWindow1;
wxDataViewCtrl* browserView;
wxDataViewColumn* browserFilenameColumn;
wxDataViewColumn* browserModeColumn;
wxDataViewColumn* browserLengthColumn;
wxDataViewColumn* browserExtraColumn;
wxButton* browserDiscardButton;
wxButton* browserCommitButton;
// Virtual event handlers, override them in your derived class
virtual void OnAbout( wxCommandEvent& event ) { event.Skip(); }
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnAboutMenuItem( wxCommandEvent& event ) { event.Skip(); }
virtual void OnExit( wxCommandEvent& event ) { event.Skip(); }
virtual void OnShowLogWindow( wxCommandEvent& event ) { event.Skip(); }
virtual void OnShowConfigWindow( wxCommandEvent& event ) { event.Skip(); }
virtual void OnConfigRadioButtonClicked( wxCommandEvent& event ) { event.Skip(); }
virtual void OnControlsChanged( wxCommandEvent& event ) { event.Skip(); }
virtual void OnControlsChanged( wxFileDirPickerEvent& event ) { event.Skip(); }
virtual void OnCustomConfigurationButton( wxCommandEvent& event ) { event.Skip(); }
virtual void OnReadButton( wxCommandEvent& event ) { event.Skip(); }
virtual void OnWriteButton( wxCommandEvent& event ) { event.Skip(); }
virtual void OnBackButton( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSaveImageButton( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSaveFluxButton( wxCommandEvent& event ) { event.Skip(); }
virtual void OnImagerGoAgainButton( wxCommandEvent& event ) { event.Skip(); }
public:
MainWindowGen( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("FluxEngine"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 587,595 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
MainWindowGen( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("FluxEngine"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 819,607 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL );
~MainWindowGen();
};
///////////////////////////////////////////////////////////////////////////////
/// Class FluxViewerWindowGen
/// Class TextViewerWindowGen
///////////////////////////////////////////////////////////////////////////////
class FluxViewerWindowGen : public wxFrame
class TextViewerWindowGen : public wxDialog
{
private:
protected:
wxMenuBar* m_menubar2;
wxMenu* m_menu1;
FluxViewerControl* fluxviewer;
wxScrollBar* scrollbar;
wxTextCtrl* textControl;
wxStdDialogButtonSizer* m_sdbSizer2;
wxButton* m_sdbSizer2OK;
// Virtual event handlers, override them in your derived class
virtual void OnExit( wxCommandEvent& event ) { event.Skip(); }
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnClose( wxCommandEvent& event ) { event.Skip(); }
public:
FluxViewerWindowGen( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Flux Viewer"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,300 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
TextViewerWindowGen( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 208,143 ), long style = wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~TextViewerWindowGen();
};
///////////////////////////////////////////////////////////////////////////////
/// Class FluxViewerWindowGen
///////////////////////////////////////////////////////////////////////////////
class FluxViewerWindowGen : public wxDialog
{
private:
protected:
FluxViewerControl* fluxviewer;
wxScrollBar* scrollbar;
wxStdDialogButtonSizer* m_sdbSizer2;
wxButton* m_sdbSizer2OK;
// Virtual event handlers, override them in your derived class
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnClose( wxCommandEvent& event ) { event.Skip(); }
public:
FluxViewerWindowGen( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 400,200 ), long style = wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~FluxViewerWindowGen();
};
///////////////////////////////////////////////////////////////////////////////
/// Class HexViewerWindowGen
/// Class TextEditorWindowGen
///////////////////////////////////////////////////////////////////////////////
class HexViewerWindowGen : public wxFrame
class TextEditorWindowGen : public wxDialog
{
private:
protected:
wxMenuBar* m_menubar2;
wxMenu* m_menu1;
wxTextCtrl* hexEntry;
wxTextCtrl* textControl;
wxStdDialogButtonSizer* m_sdbSizer2;
wxButton* m_sdbSizer2Save;
wxButton* m_sdbSizer2Cancel;
// Virtual event handlers, override them in your derived class
virtual void OnExit( wxCommandEvent& event ) { event.Skip(); }
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSave( wxCommandEvent& event ) { event.Skip(); }
public:
HexViewerWindowGen( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Hex Viewer"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,300 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
TextEditorWindowGen( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~HexViewerWindowGen();
~TextEditorWindowGen();
};

View File

@@ -1,6 +1,6 @@
#include "globals.h"
#include "lib/globals.h"
#include "lib/logger.h"
#include "gui.h"
#include "mainwindow.h"
#include "utils.h"
class FluxEngineApp;
@@ -8,6 +8,8 @@ class ExecEvent;
static wxSemaphore execSemaphore(0);
wxDEFINE_EVENT(UPDATE_STATE_EVENT, wxCommandEvent);
wxDEFINE_EVENT(EXEC_EVENT_TYPE, ExecEvent);
class ExecEvent : public wxThreadEvent
{
@@ -45,7 +47,7 @@ private:
bool FluxEngineApp::OnInit()
{
Bind(EXEC_EVENT_TYPE, &FluxEngineApp::OnExec, this);
_mainWindow = new MainWindow();
_mainWindow = CreateMainWindow();
_mainWindow->Show(true);
return true;
}
@@ -63,13 +65,13 @@ wxThread::ExitCode FluxEngineApp::Entry()
}
catch (const EmergencyStopException& e)
{
Logger() << "Emergency stop!\n";
Logger() << EmergencyStopMessage();
}
runOnUiThread(
[&] {
_callback = nullptr;
_mainWindow->UpdateState();
SendUpdateEvent();
}
);
return 0;
@@ -87,7 +89,15 @@ void FluxEngineApp::RunOnWorkerThread(std::function<void()> callback)
emergencyStop = false;
CreateThread(wxTHREAD_JOINABLE);
GetThread()->Run();
_mainWindow->UpdateState();
SendUpdateEvent();
}
void FluxEngineApp::SendUpdateEvent()
{
auto* event = new wxCommandEvent(UPDATE_STATE_EVENT, 0);
event->SetEventObject(_mainWindow);
QueueEvent(event);
}
void runOnWorkerThread(std::function<void()> callback)

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,46 +0,0 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "layout.h"
#include "logger.h"
#include <wx/config.h>
class CandidateDevice;
class ConfigProto;
class DiskFlux;
class MainWindow : public MainWindowGen
{
public:
MainWindow();
private:
void OnExit(wxCommandEvent& event);
void OnStopButton(wxCommandEvent&);
void OnReadFluxButton(wxCommandEvent&);
void OnReadImageButton(wxCommandEvent&);
void OnWriteFluxButton(wxCommandEvent&);
void OnWriteImageButton(wxCommandEvent&);
void OnLogMessage(std::shared_ptr<const AnyLogMessage> message);
void OnTrackSelection(TrackSelectionEvent&);
void OnControlsChanged(wxCommandEvent&);
public:
void UpdateState();
void UpdateDevices();
void PrepareConfig();
void ShowConfig();
void ApplyCustomSettings();
private:
void SetHighDensity();
private:
wxConfig _config;
std::vector<std::unique_ptr<const ConfigProto>> _formats;
std::vector<std::unique_ptr<const CandidateDevice>> _devices;
std::shared_ptr<const DiskFlux> _currentDisk;
};
#endif

View File

@@ -0,0 +1,60 @@
#include "globals.h"
#include "gui.h"
#include "layout.h"
#include "texteditorwindow.h"
#include "fmt/format.h"
wxDEFINE_EVENT(EDITOR_SAVE_EVENT, EditorSaveEvent);
TextEditorWindow::TextEditorWindow(
wxWindow* parent, const std::string& title, const std::string& text):
TextEditorWindowGen(parent)
{
auto size = textControl->GetTextExtent("M");
SetSize(size.Scale(85, 25));
SetTitle(title);
textControl->SetValue(text);
}
TextEditorWindow* TextEditorWindow::Create(
wxWindow* parent, const std::string& title, const std::string& text)
{
return new TextEditorWindow(parent, title, text);
}
wxTextCtrl* TextEditorWindow::GetTextControl() const
{
return textControl;
}
void TextEditorWindow::OnClose(wxCloseEvent& event)
{
event.Veto();
if (textControl->IsModified())
{
int res = wxMessageBox(
"You have unsaved changes. Do you wish to discard them?",
"Unsaved changes",
wxOK | wxCANCEL | wxICON_WARNING);
if (res != wxOK)
return;
}
Destroy();
}
void TextEditorWindow::OnSave(wxCommandEvent&)
{
EditorSaveEvent event(EDITOR_SAVE_EVENT, GetId());
event.SetEventObject(this);
event.text = textControl->GetValue();
ProcessWindowEvent(event);
Destroy();
}
void TextEditorWindow::OnCancel(wxCommandEvent&)
{
Destroy();
}

View File

@@ -0,0 +1,41 @@
#ifndef TEXTEDITORWINDOW_H
#define TEXTEDITORWINDOW_H
#include "layout.h"
class EditorSaveEvent : public wxEvent
{
public:
EditorSaveEvent(wxEventType eventType, int winId): wxEvent(winId, eventType)
{
}
wxEvent* Clone() const
{
return new EditorSaveEvent(*this);
}
std::string text;
};
wxDECLARE_EVENT(EDITOR_SAVE_EVENT, EditorSaveEvent);
class TextEditorWindow : public TextEditorWindowGen
{
public:
TextEditorWindow(
wxWindow* parent, const std::string& title, const std::string& text);
static TextEditorWindow* Create(
wxWindow* parent, const std::string& title, const std::string& text);
public:
wxTextCtrl* GetTextControl() const;
private:
void OnClose(wxCloseEvent& event) override;
void OnSave(wxCommandEvent& event) override;
void OnCancel(wxCommandEvent& event) override;
};
#endif

View File

@@ -0,0 +1,39 @@
#include "globals.h"
#include "gui.h"
#include "layout.h"
#include "textviewerwindow.h"
#include "fmt/format.h"
TextViewerWindow::TextViewerWindow(wxWindow* parent,
const std::string& title,
const std::string& text,
bool autodestroy):
TextViewerWindowGen(parent),
_autodestroy(autodestroy)
{
auto size = textControl->GetTextExtent("M");
SetSize(size.Scale(85, 25));
SetTitle(title);
textControl->SetValue(text);
}
TextViewerWindow* TextViewerWindow::Create(wxWindow* parent,
const std::string& title,
const std::string& text,
bool autodestroy)
{
return new TextViewerWindow(parent, title, text, autodestroy);
}
wxTextCtrl* TextViewerWindow::GetTextControl() const
{
return textControl;
}
void TextViewerWindow::OnClose(wxCloseEvent& event)
{
if (_autodestroy)
Destroy();
else
Hide();
}

View File

@@ -0,0 +1,29 @@
#ifndef TEXTVIEWERWINDOW_H
#define TEXTVIEWERWINDOW_H
#include "layout.h"
class TextViewerWindow : public TextViewerWindowGen
{
public:
TextViewerWindow(wxWindow* parent,
const std::string& title,
const std::string& text,
bool autodestroy);
static TextViewerWindow* Create(wxWindow* parent,
const std::string& title,
const std::string& text,
bool autodestroy = true);
public:
wxTextCtrl* GetTextControl() const;
private:
void OnClose(wxCloseEvent& event);
private:
bool _autodestroy;
};
#endif

View File

@@ -11,8 +11,6 @@
#define TICK 3
#define TRACKS 82
#define SECTORSIZE 5
wxDEFINE_EVENT(TRACK_SELECTION_EVENT, TrackSelectionEvent);
DECLARE_COLOUR(AXIS, 128, 128, 128);
@@ -30,15 +28,17 @@ VisualisationControl::VisualisationControl(wxWindow* parent,
long style):
wxWindow(parent, id, pos, size, style, "VisualisationControl")
{
SetDoubleBuffered(true);
SetDoubleBuffered(true);
}
// clang-format off
wxBEGIN_EVENT_TABLE(VisualisationControl, wxPanel)
EVT_PAINT(VisualisationControl::OnPaint)
EVT_MOTION(VisualisationControl::OnMotion)
EVT_LEFT_DOWN(VisualisationControl::OnLeftDown)
EVT_LEAVE_WINDOW(VisualisationControl::OnLeaveWindow)
wxEND_EVENT_TABLE()
wxEND_EVENT_TABLE();
// clang-format on
void VisualisationControl::OnPaint(wxPaintEvent&)
{
@@ -46,17 +46,20 @@ void VisualisationControl::OnPaint(wxPaintEvent&)
int w = size.GetWidth();
int w2 = w / 2;
int h = size.GetHeight();
int h2 = h / 2;
int centrey = h * 1.5;
int outerradius = centrey - BORDER;
int innerradius = centrey - h + BORDER;
int scalesize = TRACKS * SECTORSIZE;
int scaletop = h / 2 - scalesize / 2;
int scalesize = h - BORDER * 4;
int sectorsize = scalesize / TRACKS;
scalesize = sectorsize * TRACKS;
int scaletop = h2 - scalesize / 2;
int scalebottom = scaletop + scalesize - 1;
int outerradius = centrey - scaletop + BORDER;
int innerradius = centrey - scalebottom - BORDER;
wxPaintDC dc(this);
dc.SetBackground(*wxWHITE_BRUSH);
dc.Clear();
dc.SetBackground(*wxWHITE_BRUSH);
dc.Clear();
dc.SetPen(*wxBLACK_PEN);
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
@@ -70,33 +73,33 @@ void VisualisationControl::OnPaint(wxPaintEvent&)
if (_mode != VISMODE_NOTHING)
{
if (_mode == VISMODE_READING)
{
dc.SetPen(READ_ARROW_PEN);
dc.SetBrush(READ_ARROW_BRUSH);
}
{
dc.SetPen(READ_ARROW_PEN);
dc.SetBrush(READ_ARROW_BRUSH);
}
else if (_mode == VISMODE_WRITING)
{
dc.SetPen(WRITE_ARROW_PEN);
dc.SetBrush(WRITE_ARROW_BRUSH);
}
{
dc.SetPen(WRITE_ARROW_PEN);
dc.SetBrush(WRITE_ARROW_BRUSH);
}
int factor = (_head == 0) ? -1 : 1;
int y = scaletop + _track * SECTORSIZE;
wxPoint points[] = {
{ w2 + factor*TICK, y-1 },
{ w2 + factor*TICK, y+SECTORSIZE-1 },
{ w2 + factor*TICK*2, y+SECTORSIZE/2 }
};
dc.DrawPolygon(3, points);
int y = scaletop + _track * sectorsize;
wxPoint points[] = {
{w2 + factor * TICK, y - 1 },
{w2 + factor * TICK, y + sectorsize - 1},
{w2 + factor * TICK * 2, y + sectorsize / 2}
};
dc.DrawPolygon(3, points);
}
for (int track = 0; track <= TRACKS; track++)
{
int y = scaletop + track * SECTORSIZE;
int y = scaletop + track * sectorsize;
dc.SetBrush(AXIS_BRUSH);
dc.SetPen(AXIS_PEN);
dc.DrawLine({w2 - TICK, y-1}, {w2 + TICK, y-1});
dc.DrawLine({w2 - TICK, y - 1}, {w2 + TICK, y - 1});
auto drawSectors = [&](int head)
{
@@ -130,11 +133,11 @@ void VisualisationControl::OnPaint(wxPaintEvent&)
if (head == 0)
dc.DrawRectangle(
{w2 - x * SECTORSIZE - (SECTORSIZE - 1), y},
{SECTORSIZE - 1, SECTORSIZE - 1});
{w2 - x * sectorsize - (sectorsize - 1), y},
{sectorsize - 1, sectorsize - 1});
else
dc.DrawRectangle({w2 + x * SECTORSIZE + 1, y},
{SECTORSIZE - 1, SECTORSIZE - 1});
dc.DrawRectangle({w2 + x * sectorsize + 1, y},
{sectorsize - 1, sectorsize - 1});
x++;
}
};
@@ -143,42 +146,59 @@ void VisualisationControl::OnPaint(wxPaintEvent&)
drawSectors(1);
}
if (_selectedTrack != -1)
{
int x = (_selectedHead ? (w2-1) : 0) + SECTORSIZE;
int y = scaletop + _selectedTrack * SECTORSIZE - 1;
int bw = w/2 - SECTORSIZE*2 + 2;
int bh = SECTORSIZE + 3;
dc.SetPen(SELECTION_BOX_PEN);
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRectangle({x, y-1, bw, bh});
if (_selectedTrack != -1)
{
key_t key = {_selectedTrack, _selectedHead};
int sectorCount = 0;
for (auto it = _sectors.lower_bound(key);
it != _sectors.upper_bound(key);
it++)
sectorCount++;
static wxFont font(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
dc.SetFont(font);
dc.SetBackgroundMode(wxTRANSPARENT);
dc.SetTextForeground(*wxBLACK);
if (sectorCount != 0)
{
dc.SetPen(SELECTION_BOX_PEN);
dc.SetBrush(*wxTRANSPARENT_BRUSH);
int bw = sectorCount * sectorsize + 3;
int bh = sectorsize + 3;
int y = scaletop + _selectedTrack * sectorsize - 1;
if (_selectedHead == 0)
{
int x = w2 - bw - sectorsize + 2;
dc.DrawRectangle({x, y - 1, bw, bh});
}
else
{
int x = w2 - 1 + sectorsize;
dc.DrawRectangle({x, y - 1, bw, bh});
}
}
auto centreText = [&](const std::string& text, int y)
{
auto size = dc.GetTextExtent(text);
dc.DrawText(text, { w2 - size.x/2 , y });
};
static wxFont font(
8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
dc.SetFont(font);
dc.SetBackgroundMode(wxTRANSPARENT);
dc.SetTextForeground(*wxBLACK);
centreText(
fmt::format("physical: {}.{}", _selectedTrack, _selectedHead),
scalebottom + 5);
auto centreText = [&](const std::string& text, int y)
{
auto size = dc.GetTextExtent(text);
dc.DrawText(text, {w2 - size.x / 2, y});
};
centreText(
fmt::format("physical: {}.{}", _selectedTrack, _selectedHead),
h - 25);
key_t key = {_selectedTrack, _selectedHead};
auto it = _tracks.find(key);
std::string logicalText = "logical: (none)";
if (it != _tracks.end())
logicalText = fmt::format(
"logical: {}.{}",
it->second->location.logicalTrack,
it->second->location.head);
std::string logicalText = "logical: (none)";
if (it != _tracks.end())
logicalText = fmt::format("logical: {}.{}",
it->second->location.logicalTrack,
it->second->location.head);
centreText(logicalText, scalebottom + 15);
}
centreText(logicalText, h - 35);
}
}
void VisualisationControl::OnMotion(wxMouseEvent& event)
@@ -189,47 +209,49 @@ void VisualisationControl::OnMotion(wxMouseEvent& event)
int h = size.GetHeight();
int centrey = h * 1.5;
int scalesize = TRACKS * SECTORSIZE;
int scalesize = h - BORDER * 4;
int sectorsize = scalesize / TRACKS;
scalesize = sectorsize * TRACKS;
int scaletop = h / 2 - scalesize / 2;
int scalebottom = scaletop + scalesize - 1;
int headno = event.GetX() > w2;
int headno = event.GetX() > w2;
int trackno = (event.GetY() - scaletop) / SECTORSIZE;
if ((trackno < 0) || (trackno >= TRACKS))
trackno = -1;
if ((_selectedHead != headno) || (_selectedTrack != trackno))
{
_selectedTrack = trackno;
_selectedHead = headno;
Refresh();
}
int trackno = (event.GetY() - scaletop) / sectorsize;
if ((trackno < 0) || (trackno >= TRACKS))
trackno = -1;
if ((_selectedHead != headno) || (_selectedTrack != trackno))
{
_selectedTrack = trackno;
_selectedHead = headno;
Refresh();
}
}
void VisualisationControl::OnLeftDown(wxMouseEvent& event)
{
OnMotion(event);
OnMotion(event);
if ((_selectedHead != -1) && (_selectedTrack != -1))
{
key_t key = {_selectedTrack, _selectedHead};
if ((_selectedHead != -1) && (_selectedTrack != -1))
{
key_t key = {_selectedTrack, _selectedHead};
auto it = _tracks.find(key);
if (it != _tracks.end())
{
TrackSelectionEvent event(TRACK_SELECTION_EVENT, GetId());
event.SetEventObject(this);
event.trackFlux = it->second;
ProcessWindowEvent(event);
}
}
if (it != _tracks.end())
{
TrackSelectionEvent event(TRACK_SELECTION_EVENT, GetId());
event.SetEventObject(this);
event.trackFlux = it->second;
ProcessWindowEvent(event);
}
}
else
event.Skip();
}
void VisualisationControl::OnLeaveWindow(wxMouseEvent&)
{
_selectedTrack = _selectedHead = -1;
Refresh();
_selectedTrack = _selectedHead = -1;
Refresh();
}
void VisualisationControl::SetMode(int track, int head, int mode)
@@ -243,14 +265,14 @@ void VisualisationControl::SetMode(int track, int head, int mode)
void VisualisationControl::Clear()
{
_sectors.clear();
_tracks.clear();
_tracks.clear();
Refresh();
}
void VisualisationControl::SetTrackData(std::shared_ptr<const TrackFlux> track)
{
key_t key = {track->location.physicalTrack, track->location.head};
_tracks[key] = track;
_tracks[key] = track;
_sectors.erase(key);
for (auto& sector : track->sectors)
_sectors.insert({key, sector});
@@ -260,18 +282,18 @@ void VisualisationControl::SetTrackData(std::shared_ptr<const TrackFlux> track)
void VisualisationControl::SetDiskData(std::shared_ptr<const DiskFlux> disk)
{
_sectors.clear();
for (const auto& track : disk->tracks)
{
key_t key = {track->location.physicalTrack, track->location.head};
_tracks[key] = track;
}
_sectors.clear();
for (const auto& track : disk->tracks)
{
key_t key = {track->location.physicalTrack, track->location.head};
_tracks[key] = track;
}
for (const auto& sector : *(disk->image))
{
key_t key = {sector->physicalTrack, sector->physicalHead};
_sectors.insert({key, sector});
}
for (const auto& sector : *(disk->image))
{
key_t key = {sector->physicalTrack, sector->physicalHead};
_sectors.insert({key, sector});
}
Refresh();
}

View File

@@ -9,23 +9,27 @@ class Sector;
class DiskFlux;
class TrackFlux;
enum {
VISMODE_NOTHING,
VISMODE_READING,
VISMODE_WRITING
enum
{
VISMODE_NOTHING,
VISMODE_READING,
VISMODE_WRITING
};
class TrackSelectionEvent : public wxEvent
{
public:
TrackSelectionEvent(wxEventType eventType, int winId):
wxEvent(winId, eventType)
{}
TrackSelectionEvent(wxEventType eventType, int winId):
wxEvent(winId, eventType)
{
}
wxEvent *Clone() const
{ return new TrackSelectionEvent(*this); }
wxEvent* Clone() const
{
return new TrackSelectionEvent(*this);
}
std::shared_ptr<const TrackFlux> trackFlux;
std::shared_ptr<const TrackFlux> trackFlux;
};
wxDECLARE_EVENT(TRACK_SELECTION_EVENT, TrackSelectionEvent);
@@ -40,27 +44,27 @@ public:
long style = 0);
public:
void Clear();
void SetMode(int head, int track, int mode);
void SetTrackData(std::shared_ptr<const TrackFlux> track);
void SetDiskData(std::shared_ptr<const DiskFlux> disk);
void Clear();
void SetMode(int head, int track, int mode);
void SetTrackData(std::shared_ptr<const TrackFlux> track);
void SetDiskData(std::shared_ptr<const DiskFlux> disk);
private:
void OnPaint(wxPaintEvent& evt);
void OnMotion(wxMouseEvent& evt);
void OnLeftDown(wxMouseEvent& evt);
void OnLeaveWindow(wxMouseEvent& evt);
void OnPaint(wxPaintEvent& evt);
void OnMotion(wxMouseEvent& evt);
void OnLeftDown(wxMouseEvent& evt);
void OnLeaveWindow(wxMouseEvent& evt);
private:
typedef std::pair<unsigned, unsigned> key_t;
typedef std::pair<unsigned, unsigned> key_t;
int _head;
int _track;
int _mode = VISMODE_NOTHING;
int _selectedHead = -1;
int _selectedTrack = -1;
std::multimap<key_t, std::shared_ptr<const Sector>> _sectors;
std::map<key_t, std::shared_ptr<const TrackFlux>> _tracks;
int _head;
int _track;
int _mode = VISMODE_NOTHING;
int _selectedHead = -1;
int _selectedTrack = -1;
std::multimap<key_t, std::shared_ptr<const Sector>> _sectors;
std::map<key_t, std::shared_ptr<const TrackFlux>> _tracks;
wxDECLARE_EVENT_TABLE();
};