#include "requirementDetailPanel.h" #include "resources/resources.h" #include using namespace std; using namespace gui; //-------------------------------------------------------------- /* Constructor */ RequirementDetailPanel::RequirementDetailPanel(wxWindow *parentWindow, dBus::Bus &bus) : wxPanel(parentWindow /*, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER*/) , m_bus(bus) { // Initialization // Creating controls createControls(); // Post initialization } //-------------------------------------------------------------- /* Creating controls */ void RequirementDetailPanel::createControls() { const auto mainPanel = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL); mainPanel->SetScrollRate(0, 10); // Set the scroll rate for the panel (vertical only) const auto closeButton = new wxBitmapButton(this, wxID_ANY, icon_xmark_24x24(), wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW | wxBORDER_NONE); const auto saveButton = new wxBitmapButton(this, wxID_ANY, icon_floppy_disk_24x24(), wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW | wxBORDER_NONE); const auto discardButton = new wxBitmapButton(this, wxID_ANY, icon_rotate_left_24x24(), wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW | wxBORDER_NONE); // Controls positioning const auto ctrlSizer = new wxBoxSizer(wxVERTICAL); ctrlSizer->Add(createControls_metadata(mainPanel), wxSizerFlags(0).Expand().Border(wxALL & ~wxTOP, 5)); ctrlSizer->Add(createControls_details(mainPanel), wxSizerFlags(0).Expand().Border(wxALL & ~wxTOP, 5)); ctrlSizer->Add(createControls_classification(mainPanel), wxSizerFlags(0).Expand().Border(wxALL & ~wxTOP & ~wxBOTTOM, 5)); mainPanel->SetSizer(ctrlSizer); const auto buttonSizer = new wxBoxSizer(wxVERTICAL); buttonSizer->Add(closeButton, wxSizerFlags(0).Expand()); buttonSizer->AddStretchSpacer(1); buttonSizer->Add(discardButton, wxSizerFlags(0).Expand().Border(wxBOTTOM, 5)); buttonSizer->Add(saveButton, wxSizerFlags(0).Expand()); const auto mainSizer = new wxBoxSizer(wxHORIZONTAL); mainSizer->Add(mainPanel, wxSizerFlags(1).Expand().Border(wxLEFT | wxRIGHT, 5)); mainSizer->Add(buttonSizer, wxSizerFlags(0).Expand().Border(wxALL, 5)); SetSizer(mainSizer); // Set the virtual size to match the size of the child panel, // enabling scrolling if necessary mainPanel->FitInside(); // Harmonize the sizes of the title controls to ensure they have the same width updateTitleSizes(); Layout(); } //-------------------------------------------------------------- /* Creating controls for requirement metadata (ID, UUID, name, description, etc.) */ wxSizer *RequirementDetailPanel::createControls_metadata(wxWindow *owner) { const auto uuidTitleCtrl = createTitle(owner, _T("UUID:")); const auto idTitleCtrl = createTitle(owner, _T("ID:")); const auto authorTitleCtrl = createTitle(owner, _("Author:")); const auto createdAtTitleCtrl = createTitle(owner, _("Created at:")); const auto updatedAtTitleCtrl = createTitle(owner, _("Updated at:")); const auto uuidValueCtrl = new wxTextCtrl(owner, wxID_ANY); const auto idValueCtrl = new wxTextCtrl(owner, wxID_ANY); const auto authorValueCtrl = new wxTextCtrl(owner, wxID_ANY); const auto createdAtValueCtrl = new wxTextCtrl(owner, wxID_ANY); const auto updatedAtValueCtrl = new wxTextCtrl(owner, wxID_ANY); // Controls positioning const auto ctrlSizer = new wxFlexGridSizer(2, 5, 5); ctrlSizer->Add(uuidTitleCtrl, wxSizerFlags(0).Expand().CenterVertical()); ctrlSizer->Add(uuidValueCtrl, wxSizerFlags(1).Expand()); ctrlSizer->Add(idTitleCtrl, wxSizerFlags(0).Expand().CenterVertical()); ctrlSizer->Add(idValueCtrl, wxSizerFlags(1).Expand()); ctrlSizer->Add(authorTitleCtrl, wxSizerFlags(0).Expand().CenterVertical()); ctrlSizer->Add(authorValueCtrl, wxSizerFlags(1).Expand()); ctrlSizer->Add(createdAtTitleCtrl, wxSizerFlags(0).Expand().CenterVertical()); ctrlSizer->Add(createdAtValueCtrl, wxSizerFlags(1).Expand()); ctrlSizer->Add(updatedAtTitleCtrl, wxSizerFlags(0).Expand().CenterVertical()); ctrlSizer->Add(updatedAtValueCtrl, wxSizerFlags(1).Expand()); ctrlSizer->AddGrowableCol(1, 1); // Controls positioning const auto localSizer = new wxStaticBoxSizer(wxVERTICAL, owner, "Metadata"); localSizer->Add(ctrlSizer, wxSizerFlags(0).Expand().Border(wxALL, 5)); return localSizer; } //-------------------------------------------------------------- /* Creating controls for requirement details (e.g., custom attributes, child requirements, etc.) */ wxSizer *RequirementDetailPanel::createControls_details(wxWindow *owner) { const auto titleTitleCtrl = createTitle(owner, _("Title:")); const auto descriptionTitleCtrl = createTitle(owner, _("Description:")); const auto acceptanceCriteriaTitleCtrl = createTitle(owner, _("Acceptance criteria:")); const auto titleValueCtrl = new wxTextCtrl(owner, wxID_ANY); const auto descriptionValueCtrl = new wxTextCtrl(owner, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_TAB | wxTE_MULTILINE); const auto acceptanceCriteriaValueCtrl = new wxTextCtrl(owner, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_TAB | wxTE_MULTILINE); const auto smartCheckBoxCtrl = new wxCheckBox(owner, wxID_ANY, _("S.M.A.R.T.")); descriptionValueCtrl->SetMinSize(wxSize(-1, 200)); acceptanceCriteriaValueCtrl->SetMinSize(wxSize(-1, 100)); // Controls positioning const auto ctrlSizer = new wxFlexGridSizer(2, 5, 5); ctrlSizer->Add(titleTitleCtrl, wxSizerFlags(0).Expand().CenterVertical()); ctrlSizer->Add(titleValueCtrl, wxSizerFlags(1).Expand()); ctrlSizer->Add(descriptionTitleCtrl, wxSizerFlags(0).Expand()); ctrlSizer->Add(descriptionValueCtrl, wxSizerFlags(1).Expand()); ctrlSizer->Add(acceptanceCriteriaTitleCtrl, wxSizerFlags(0).Expand()); ctrlSizer->Add(acceptanceCriteriaValueCtrl, wxSizerFlags(1).Expand()); ctrlSizer->AddStretchSpacer(); ctrlSizer->Add(smartCheckBoxCtrl, wxSizerFlags(1).Expand()); ctrlSizer->AddGrowableCol(1, 1); const auto localSizer = new wxStaticBoxSizer(wxVERTICAL, owner, "Details"); localSizer->Add(ctrlSizer, wxSizerFlags(0).Expand().Border(wxALL, 5)); return localSizer; } //-------------------------------------------------------------- /* Creating controls for requirement classification (e.g., priority, severity, etc.) */ wxSizer *RequirementDetailPanel::createControls_classification(wxWindow *owner) { const auto typeTitleCtrl = createTitle(owner, _("Type:")); const auto categoryTitleCtrl = createTitle(owner, _("Category:")); const auto priorityTitleCtrl = createTitle(owner, _("Priority:")); const auto statusTitleCtrl = createTitle(owner, _("Status:")); const auto typeValueCtrl = new wxTextCtrl(owner, wxID_ANY); const auto categoryValueCtrl = new wxTextCtrl(owner, wxID_ANY); const auto priorityValueCtrl = new wxTextCtrl(owner, wxID_ANY); const auto statusValueCtrl = new wxTextCtrl(owner, wxID_ANY); // Controls positioning const auto ctrlSizer = new wxFlexGridSizer(2, 5, 5); ctrlSizer->Add(typeTitleCtrl, wxSizerFlags(0).Expand().CenterVertical()); ctrlSizer->Add(typeValueCtrl, wxSizerFlags(1).Expand()); ctrlSizer->Add(categoryTitleCtrl, wxSizerFlags(0).Expand().CenterVertical()); ctrlSizer->Add(categoryValueCtrl, wxSizerFlags(1).Expand()); ctrlSizer->Add(priorityTitleCtrl, wxSizerFlags(0).Expand().CenterVertical()); ctrlSizer->Add(priorityValueCtrl, wxSizerFlags(1).Expand()); ctrlSizer->Add(statusTitleCtrl, wxSizerFlags(0).Expand().CenterVertical()); ctrlSizer->Add(statusValueCtrl, wxSizerFlags(1).Expand()); ctrlSizer->AddGrowableCol(1, 1); const auto localSizer = new wxStaticBoxSizer(wxVERTICAL, owner, "Classification"); localSizer->Add(ctrlSizer, wxSizerFlags(0).Expand().Border(wxALL, 5)); return localSizer; } //-------------------------------------------------------------- /* Helper function to create a section title control */ wxStaticText *RequirementDetailPanel::createTitle(wxWindow *owner, const wxString &title) { const auto ctrl = new wxStaticText(owner, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxST_NO_AUTORESIZE | wxALIGN_RIGHT); ctrl->SetFont(GetFont().Italic()); m_titleControls.push_back(ctrl); return ctrl; } //-------------------------------------------------------------- /* Harmonize the sizes of the title controls to ensure they have the same width */ void RequirementDetailPanel::updateTitleSizes() const { int maxWidth = 0; for (const auto &ctrl : m_titleControls) { maxWidth = std::max(maxWidth, ctrl->GetSize().GetWidth()); } for (const auto &ctrl : m_titleControls) { ctrl->SetMinSize(wxSize(maxWidth, -1)); } } //--------------------------------------------------------------