pcbjam/tests/apps/standalone/specialized/specialized_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

278 lines
11 KiB
C++

// Specialized wxWidgets Controls Test
// Tests: wxTreebook, wxBitmapComboBox, wxSpinCtrl
// These are used in KiCad for settings dialogs and layer management
#include "wx/wx.h"
#include "wx/treebook.h"
#include "wx/bmpcbox.h"
#include "wx/dcmemory.h"
#include "wx/spinctrl.h"
// Helper to create color swatch bitmaps for wxBitmapComboBox
wxBitmap CreateColorSwatch(const wxColour& color, int width = 16, int height = 16)
{
wxBitmap bmp(width, height);
wxMemoryDC dc(bmp);
dc.SetPen(*wxBLACK_PEN);
dc.SetBrush(wxBrush(color));
dc.DrawRectangle(0, 0, width, height);
return bmp;
}
class SpecializedFrame : public wxFrame
{
public:
SpecializedFrame() : wxFrame(nullptr, wxID_ANY, "Specialized wxWidgets Controls Test",
wxDefaultPosition, wxSize(900, 700))
{
wxPanel* mainPanel = new wxPanel(this);
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
// Description
wxStaticText* desc = new wxStaticText(mainPanel, wxID_ANY,
"KiCad uses specialized controls for settings and layer management.\n"
"Tests: wxTreebook (settings pages), wxBitmapComboBox (layer chooser), wxListBox (layer list).");
mainSizer->Add(desc, 0, wxALL, 5);
// Split into left and right panels
wxBoxSizer* contentSizer = new wxBoxSizer(wxHORIZONTAL);
// Left: wxTreebook
wxStaticBoxSizer* treebookSizer = new wxStaticBoxSizer(wxVERTICAL, mainPanel, "wxTreebook (Settings)");
CreateTreebook(mainPanel);
treebookSizer->Add(m_treebook, 1, wxEXPAND | wxALL, 5);
contentSizer->Add(treebookSizer, 1, wxEXPAND | wxALL, 5);
// Right: wxBitmapComboBox and wxListBox for layer list
wxBoxSizer* rightSizer = new wxBoxSizer(wxVERTICAL);
// wxBitmapComboBox
wxStaticBoxSizer* bmpComboSizer = new wxStaticBoxSizer(wxVERTICAL, mainPanel, "wxBitmapComboBox (Layer Chooser)");
CreateBitmapComboBox(mainPanel);
bmpComboSizer->Add(m_layerCombo, 0, wxEXPAND | wxALL, 5);
wxStaticText* comboLabel = new wxStaticText(mainPanel, wxID_ANY, "Selected: (none)");
m_comboLabel = comboLabel;
bmpComboSizer->Add(comboLabel, 0, wxALL, 5);
rightSizer->Add(bmpComboSizer, 0, wxEXPAND | wxALL, 5);
// Layer List (simulating wxRearrangeCtrl with wxCheckListBox)
wxStaticBoxSizer* listSizer = new wxStaticBoxSizer(wxVERTICAL, mainPanel, "Layer List (Visibility)");
CreateLayerList(mainPanel);
listSizer->Add(m_layerList, 1, wxEXPAND | wxALL, 5);
wxButton* btnGetOrder = new wxButton(mainPanel, wxID_ANY, "Get Layer Status");
btnGetOrder->Bind(wxEVT_BUTTON, &SpecializedFrame::OnGetOrder, this);
listSizer->Add(btnGetOrder, 0, wxALL, 5);
rightSizer->Add(listSizer, 1, wxEXPAND | wxALL, 5);
contentSizer->Add(rightSizer, 1, wxEXPAND);
mainSizer->Add(contentSizer, 1, wxEXPAND);
// 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);
CreateStatusBar();
SetStatusText("Specialized controls test app started");
Log("Specialized controls test app started");
}
private:
void CreateTreebook(wxWindow* parent)
{
m_treebook = new wxTreebook(parent, wxID_ANY);
// General settings page
wxPanel* generalPage = new wxPanel(m_treebook);
wxBoxSizer* generalSizer = new wxBoxSizer(wxVERTICAL);
generalSizer->Add(new wxStaticText(generalPage, wxID_ANY, "General Settings"), 0, wxALL, 10);
generalSizer->Add(new wxCheckBox(generalPage, wxID_ANY, "Show grid"), 0, wxALL, 5);
generalSizer->Add(new wxCheckBox(generalPage, wxID_ANY, "Auto-save"), 0, wxALL, 5);
generalSizer->Add(new wxCheckBox(generalPage, wxID_ANY, "Show welcome dialog"), 0, wxALL, 5);
generalPage->SetSizer(generalSizer);
m_treebook->AddPage(generalPage, "General");
// Display page with sub-pages
wxPanel* displayPage = new wxPanel(m_treebook);
wxBoxSizer* displaySizer = new wxBoxSizer(wxVERTICAL);
displaySizer->Add(new wxStaticText(displayPage, wxID_ANY, "Display Settings"), 0, wxALL, 10);
displaySizer->Add(new wxCheckBox(displayPage, wxID_ANY, "Anti-aliasing"), 0, wxALL, 5);
displayPage->SetSizer(displaySizer);
m_treebook->AddPage(displayPage, "Display");
// Display sub-page: Colors
wxPanel* colorsPage = new wxPanel(m_treebook);
wxBoxSizer* colorsSizer = new wxBoxSizer(wxVERTICAL);
colorsSizer->Add(new wxStaticText(colorsPage, wxID_ANY, "Color Settings"), 0, wxALL, 10);
colorsSizer->Add(new wxStaticText(colorsPage, wxID_ANY, "Background:"), 0, wxLEFT | wxTOP, 5);
wxChoice* bgChoice = new wxChoice(colorsPage, wxID_ANY);
bgChoice->Append("White");
bgChoice->Append("Black");
bgChoice->Append("Gray");
bgChoice->SetSelection(0);
colorsSizer->Add(bgChoice, 0, wxALL, 5);
colorsPage->SetSizer(colorsSizer);
m_treebook->AddSubPage(colorsPage, "Colors");
// Display sub-page: Grid
wxPanel* gridPage = new wxPanel(m_treebook);
wxBoxSizer* gridSizer = new wxBoxSizer(wxVERTICAL);
gridSizer->Add(new wxStaticText(gridPage, wxID_ANY, "Grid Settings"), 0, wxALL, 10);
gridSizer->Add(new wxStaticText(gridPage, wxID_ANY, "Grid size (mm):"), 0, wxLEFT | wxTOP, 5);
gridSizer->Add(new wxSpinCtrl(gridPage, wxID_ANY, "1", wxDefaultPosition, wxDefaultSize,
wxSP_ARROW_KEYS, 1, 100, 1), 0, wxALL, 5);
gridPage->SetSizer(gridSizer);
m_treebook->AddSubPage(gridPage, "Grid");
// Editing page
wxPanel* editPage = new wxPanel(m_treebook);
wxBoxSizer* editSizer = new wxBoxSizer(wxVERTICAL);
editSizer->Add(new wxStaticText(editPage, wxID_ANY, "Editing Settings"), 0, wxALL, 10);
editSizer->Add(new wxCheckBox(editPage, wxID_ANY, "Magnetic pads"), 0, wxALL, 5);
editSizer->Add(new wxCheckBox(editPage, wxID_ANY, "Magnetic graphics"), 0, wxALL, 5);
editSizer->Add(new wxCheckBox(editPage, wxID_ANY, "Allow free pads"), 0, wxALL, 5);
editPage->SetSizer(editSizer);
m_treebook->AddPage(editPage, "Editing");
// Editing sub-page: Defaults
wxPanel* defaultsPage = new wxPanel(m_treebook);
wxBoxSizer* defaultsSizer = new wxBoxSizer(wxVERTICAL);
defaultsSizer->Add(new wxStaticText(defaultsPage, wxID_ANY, "Default Values"), 0, wxALL, 10);
defaultsSizer->Add(new wxStaticText(defaultsPage, wxID_ANY, "Track width (mm):"), 0, wxLEFT | wxTOP, 5);
defaultsSizer->Add(new wxTextCtrl(defaultsPage, wxID_ANY, "0.25"), 0, wxALL, 5);
defaultsSizer->Add(new wxStaticText(defaultsPage, wxID_ANY, "Via size (mm):"), 0, wxLEFT | wxTOP, 5);
defaultsSizer->Add(new wxTextCtrl(defaultsPage, wxID_ANY, "0.8"), 0, wxALL, 5);
defaultsPage->SetSizer(defaultsSizer);
m_treebook->AddSubPage(defaultsPage, "Defaults");
// Printing page
wxPanel* printPage = new wxPanel(m_treebook);
wxBoxSizer* printSizer = new wxBoxSizer(wxVERTICAL);
printSizer->Add(new wxStaticText(printPage, wxID_ANY, "Print Settings"), 0, wxALL, 10);
printSizer->Add(new wxCheckBox(printPage, wxID_ANY, "Print mirrored"), 0, wxALL, 5);
printSizer->Add(new wxCheckBox(printPage, wxID_ANY, "Print in black"), 0, wxALL, 5);
printPage->SetSizer(printSizer);
m_treebook->AddPage(printPage, "Printing");
m_treebook->Bind(wxEVT_TREEBOOK_PAGE_CHANGED, &SpecializedFrame::OnTreebookPageChanged, this);
}
void CreateBitmapComboBox(wxWindow* parent)
{
m_layerCombo = new wxBitmapComboBox(parent, wxID_ANY, "", wxDefaultPosition,
wxSize(200, -1), 0, nullptr, wxCB_READONLY);
// Add layers with color swatches
m_layerCombo->Append("F.Cu (Top Copper)", CreateColorSwatch(*wxRED));
m_layerCombo->Append("B.Cu (Bottom Copper)", CreateColorSwatch(*wxBLUE));
m_layerCombo->Append("F.SilkS (Top Silk)", CreateColorSwatch(*wxYELLOW));
m_layerCombo->Append("B.SilkS (Bottom Silk)", CreateColorSwatch(wxColour(255, 0, 255)));
m_layerCombo->Append("F.Mask (Top Mask)", CreateColorSwatch(wxColour(0, 128, 0)));
m_layerCombo->Append("B.Mask (Bottom Mask)", CreateColorSwatch(wxColour(0, 128, 128)));
m_layerCombo->Append("Edge.Cuts", CreateColorSwatch(*wxWHITE));
m_layerCombo->Append("Dwgs.User", CreateColorSwatch(wxColour(128, 128, 128)));
m_layerCombo->SetSelection(0);
m_layerCombo->Bind(wxEVT_COMBOBOX, &SpecializedFrame::OnLayerComboChanged, this);
}
void CreateLayerList(wxWindow* parent)
{
wxArrayString items;
items.Add("F.Cu");
items.Add("In1.Cu");
items.Add("In2.Cu");
items.Add("B.Cu");
items.Add("F.SilkS");
items.Add("B.SilkS");
items.Add("F.Mask");
items.Add("B.Mask");
m_layerList = new wxCheckListBox(parent, wxID_ANY, wxDefaultPosition,
wxSize(-1, 200), items);
// Check all by default
for (unsigned int i = 0; i < m_layerList->GetCount(); i++)
{
m_layerList->Check(i, true);
}
m_layerList->Bind(wxEVT_CHECKLISTBOX, &SpecializedFrame::OnLayerListCheck, this);
}
void OnTreebookPageChanged(wxBookCtrlEvent& event)
{
int page = event.GetSelection();
wxString pageName = m_treebook->GetPageText(page);
Log(wxString::Format("Treebook page changed to: %s (page %d)", pageName, page));
}
void OnLayerComboChanged(wxCommandEvent& event)
{
int sel = m_layerCombo->GetSelection();
if (sel != wxNOT_FOUND)
{
wxString layer = m_layerCombo->GetString(sel);
m_comboLabel->SetLabel(wxString::Format("Selected: %s", layer));
Log(wxString::Format("Layer selected: %s", layer));
}
}
void OnLayerListCheck(wxCommandEvent& event)
{
int idx = event.GetInt();
bool checked = m_layerList->IsChecked(idx);
wxString layer = m_layerList->GetString(idx);
Log(wxString::Format("Layer %s visibility: %s", layer, checked ? "visible" : "hidden"));
}
void OnGetOrder(wxCommandEvent& event)
{
wxString orderStr = "Layer status:\n";
for (unsigned int i = 0; i < m_layerList->GetCount(); i++)
{
wxString layer = m_layerList->GetString(i);
bool visible = m_layerList->IsChecked(i);
orderStr += wxString::Format(" %d. %s [%s]\n",
(int)(i + 1), layer, visible ? "visible" : "hidden");
}
Log(orderStr);
}
void Log(const wxString& msg)
{
m_log->AppendText(msg + "\n");
}
wxTreebook* m_treebook;
wxBitmapComboBox* m_layerCombo;
wxStaticText* m_comboLabel;
wxCheckListBox* m_layerList;
wxTextCtrl* m_log;
};
class SpecializedApp : public wxApp
{
public:
virtual bool OnInit() override
{
SpecializedFrame* frame = new SpecializedFrame();
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(SpecializedApp);