pcbjam/tests/apps/standalone/dataviewvirtual/dataviewvirtual_test.cpp
Viktor Vaczi a26b40c063 Reorganize project structure for clarity
- Rename tests/wasm-app/ to tests/apps/ for brevity
- Move lib/gl_immediate_shim.js to wasm/shims/ (consolidates WASM files)
- Delete docs/ directory (outdated Nov 2024 research docs)
- Delete patches/ directory (already applied to fork submodules)
- Delete wasm/patches/ and wasm/config/ (empty/unused)
- Update all file references in scripts, configs, and documentation
- Update .gitignore for new tests/apps/ paths

Verified both build workflows pass:
- wxWidgets tests: 255 passed
- Docker KiCad build: completed successfully

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 14:06:23 +01:00

306 lines
11 KiB
C++

// wxDataViewCtrl Virtual Mode Test - Zone Manager/Net Inspector simulation
// Tests wxDataViewCtrl with virtual data model for large datasets
#include "wx/wx.h"
#include "wx/dataview.h"
#include "wx/splitter.h"
// Virtual data model for large datasets (like Zone Manager or Net Inspector)
class VirtualNetModel : public wxDataViewVirtualListModel
{
public:
VirtualNetModel(int itemCount = 10000) : m_itemCount(itemCount)
{
// Pre-generate some sample data patterns
m_netClasses = {"Default", "Power", "Signal", "Clock", "Differential"};
}
virtual unsigned int GetColumnCount() const override { return 4; }
virtual wxString GetColumnType(unsigned int col) const override
{
return "string";
}
virtual unsigned int GetCount() const override { return m_itemCount; }
virtual void GetValueByRow(wxVariant& variant, unsigned int row, unsigned int col) const override
{
switch (col)
{
case 0: // Net Name
variant = wxString::Format("NET_%05d", row);
break;
case 1: // Net Class
variant = m_netClasses[row % m_netClasses.size()];
break;
case 2: // Connection Count
variant = wxString::Format("%d", (row * 7 + 3) % 50);
break;
case 3: // Length (mm)
variant = wxString::Format("%.2f", (row * 13 + 5) % 1000 / 10.0);
break;
}
}
virtual bool SetValueByRow(const wxVariant& variant, unsigned int row, unsigned int col) override
{
return false; // Read-only for this test
}
void SetItemCount(int count)
{
m_itemCount = count;
Reset(count);
}
private:
int m_itemCount;
std::vector<wxString> m_netClasses;
};
// Zone model for Zone Manager simulation
class VirtualZoneModel : public wxDataViewVirtualListModel
{
public:
VirtualZoneModel(int itemCount = 1000) : m_itemCount(itemCount)
{
m_layers = {"F.Cu", "B.Cu", "In1.Cu", "In2.Cu"};
m_priorities = {"0", "1", "2", "3"};
}
virtual unsigned int GetColumnCount() const override { return 5; }
virtual wxString GetColumnType(unsigned int col) const override
{
return "string";
}
virtual unsigned int GetCount() const override { return m_itemCount; }
virtual void GetValueByRow(wxVariant& variant, unsigned int row, unsigned int col) const override
{
switch (col)
{
case 0: // Zone Name
variant = wxString::Format("Zone_%03d", row);
break;
case 1: // Net
variant = wxString::Format("NET_%04d", row % 500);
break;
case 2: // Layer
variant = m_layers[row % m_layers.size()];
break;
case 3: // Priority
variant = m_priorities[row % m_priorities.size()];
break;
case 4: // Area (mm²)
variant = wxString::Format("%.1f", (row * 17 + 100) % 5000 / 10.0);
break;
}
}
virtual bool SetValueByRow(const wxVariant& variant, unsigned int row, unsigned int col) override
{
return false;
}
void SetItemCount(int count)
{
m_itemCount = count;
Reset(count);
}
private:
int m_itemCount;
std::vector<wxString> m_layers;
std::vector<wxString> m_priorities;
};
class DataViewVirtualFrame : public wxFrame
{
public:
DataViewVirtualFrame() : wxFrame(nullptr, wxID_ANY, "wxDataViewCtrl Virtual Mode Test",
wxDefaultPosition, wxSize(1200, 700))
{
wxPanel* mainPanel = new wxPanel(this);
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
// Description
wxStaticText* desc = new wxStaticText(mainPanel, wxID_ANY,
"KiCad uses wxDataViewCtrl with virtual models for Zone Manager and Net Inspector.\n"
"Virtual mode handles 10,000+ items efficiently by only creating visible rows.");
mainSizer->Add(desc, 0, wxALL, 5);
// Controls
wxBoxSizer* controlSizer = new wxBoxSizer(wxHORIZONTAL);
controlSizer->Add(new wxStaticText(mainPanel, wxID_ANY, "Item Count:"), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
wxButton* btn100 = new wxButton(mainPanel, wxID_ANY, "100");
wxButton* btn1000 = new wxButton(mainPanel, wxID_ANY, "1,000");
wxButton* btn10000 = new wxButton(mainPanel, wxID_ANY, "10,000");
wxButton* btn50000 = new wxButton(mainPanel, wxID_ANY, "50,000");
btn100->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { SetNetCount(100); });
btn1000->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { SetNetCount(1000); });
btn10000->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { SetNetCount(10000); });
btn50000->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { SetNetCount(50000); });
controlSizer->Add(btn100, 0, wxRIGHT, 2);
controlSizer->Add(btn1000, 0, wxRIGHT, 2);
controlSizer->Add(btn10000, 0, wxRIGHT, 2);
controlSizer->Add(btn50000, 0, wxRIGHT, 10);
controlSizer->Add(new wxStaticText(mainPanel, wxID_ANY, "Scroll:"), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
wxButton* btnTop = new wxButton(mainPanel, wxID_ANY, "Top");
wxButton* btnMiddle = new wxButton(mainPanel, wxID_ANY, "Middle");
wxButton* btnBottom = new wxButton(mainPanel, wxID_ANY, "Bottom");
btnTop->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { ScrollTo(0); });
btnMiddle->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { ScrollTo(m_netModel->GetCount() / 2); });
btnBottom->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { ScrollTo(m_netModel->GetCount() - 1); });
controlSizer->Add(btnTop, 0, wxRIGHT, 2);
controlSizer->Add(btnMiddle, 0, wxRIGHT, 2);
controlSizer->Add(btnBottom, 0);
mainSizer->Add(controlSizer, 0, wxALL, 5);
// Count label
m_countLabel = new wxStaticText(mainPanel, wxID_ANY, "Current items: 10,000");
mainSizer->Add(m_countLabel, 0, wxLEFT | wxBOTTOM, 5);
// Splitter for two DataViewCtrls
wxSplitterWindow* splitter = new wxSplitterWindow(mainPanel, wxID_ANY);
// Net Inspector panel (left)
wxPanel* netPanel = new wxPanel(splitter);
wxBoxSizer* netSizer = new wxBoxSizer(wxVERTICAL);
netSizer->Add(new wxStaticText(netPanel, wxID_ANY, "Net Inspector (Virtual List - 10,000 items)"), 0, wxBOTTOM, 5);
m_netView = new wxDataViewCtrl(netPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxDV_ROW_LINES | wxDV_VERT_RULES);
m_netModel = new VirtualNetModel(10000);
m_netView->AssociateModel(m_netModel);
m_netModel->DecRef(); // Model is now owned by the view
m_netView->AppendTextColumn("Net Name", 0, wxDATAVIEW_CELL_INERT, 120);
m_netView->AppendTextColumn("Net Class", 1, wxDATAVIEW_CELL_INERT, 100);
m_netView->AppendTextColumn("Connections", 2, wxDATAVIEW_CELL_INERT, 100);
m_netView->AppendTextColumn("Length (mm)", 3, wxDATAVIEW_CELL_INERT, 100);
netSizer->Add(m_netView, 1, wxEXPAND);
netPanel->SetSizer(netSizer);
// Zone Manager panel (right)
wxPanel* zonePanel = new wxPanel(splitter);
wxBoxSizer* zoneSizer = new wxBoxSizer(wxVERTICAL);
zoneSizer->Add(new wxStaticText(zonePanel, wxID_ANY, "Zone Manager (Virtual List - 1,000 items)"), 0, wxBOTTOM, 5);
m_zoneView = new wxDataViewCtrl(zonePanel, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxDV_ROW_LINES | wxDV_VERT_RULES);
m_zoneModel = new VirtualZoneModel(1000);
m_zoneView->AssociateModel(m_zoneModel);
m_zoneModel->DecRef();
m_zoneView->AppendTextColumn("Zone", 0, wxDATAVIEW_CELL_INERT, 80);
m_zoneView->AppendTextColumn("Net", 1, wxDATAVIEW_CELL_INERT, 100);
m_zoneView->AppendTextColumn("Layer", 2, wxDATAVIEW_CELL_INERT, 80);
m_zoneView->AppendTextColumn("Priority", 3, wxDATAVIEW_CELL_INERT, 70);
m_zoneView->AppendTextColumn("Area (mm²)", 4, wxDATAVIEW_CELL_INERT, 90);
zoneSizer->Add(m_zoneView, 1, wxEXPAND);
zonePanel->SetSizer(zoneSizer);
splitter->SplitVertically(netPanel, zonePanel, 500);
mainSizer->Add(splitter, 1, wxEXPAND | wxALL, 5);
// Event log
mainSizer->Add(new wxStaticText(mainPanel, wxID_ANY, "Event Log"), 0, wxLEFT | wxTOP, 5);
m_log = new wxTextCtrl(mainPanel, wxID_ANY, "", wxDefaultPosition, wxSize(-1, 100),
wxTE_MULTILINE | wxTE_READONLY);
mainSizer->Add(m_log, 0, wxEXPAND | wxALL, 5);
mainPanel->SetSizer(mainSizer);
// Bind selection events
m_netView->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, &DataViewVirtualFrame::OnNetSelected, this);
m_zoneView->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, &DataViewVirtualFrame::OnZoneSelected, this);
// Status bar
CreateStatusBar();
SetStatusText("DataViewCtrl virtual mode test app started");
Log("DataViewVirtual test app started");
Log("Net Inspector: 10,000 virtual items");
Log("Zone Manager: 1,000 virtual items");
}
private:
void Log(const wxString& msg)
{
m_log->AppendText(msg + "\n");
}
void SetNetCount(int count)
{
m_netModel->SetItemCount(count);
m_countLabel->SetLabel(wxString::Format("Current items: %d", count));
Log(wxString::Format("Net Inspector set to %d items", count));
}
void ScrollTo(int row)
{
wxDataViewItem item = m_netModel->GetItem(row);
m_netView->EnsureVisible(item);
Log(wxString::Format("Scrolled to row %d", row));
}
void OnNetSelected(wxDataViewEvent& event)
{
wxDataViewItem item = event.GetItem();
if (item.IsOk())
{
int row = m_netModel->GetRow(item);
wxVariant val;
m_netModel->GetValueByRow(val, row, 0);
Log(wxString::Format("Net selected: %s (row %d)", val.GetString(), row));
}
}
void OnZoneSelected(wxDataViewEvent& event)
{
wxDataViewItem item = event.GetItem();
if (item.IsOk())
{
int row = m_zoneModel->GetRow(item);
wxVariant val;
m_zoneModel->GetValueByRow(val, row, 0);
Log(wxString::Format("Zone selected: %s (row %d)", val.GetString(), row));
}
}
wxDataViewCtrl* m_netView;
wxDataViewCtrl* m_zoneView;
VirtualNetModel* m_netModel;
VirtualZoneModel* m_zoneModel;
wxStaticText* m_countLabel;
wxTextCtrl* m_log;
};
class DataViewVirtualApp : public wxApp
{
public:
virtual bool OnInit() override
{
DataViewVirtualFrame* frame = new DataViewVirtualFrame();
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(DataViewVirtualApp);