- 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>
278 lines
11 KiB
C++
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);
|