GUI evolutions

This commit is contained in:
Sylvain Schneider
2026-03-17 11:53:20 +01:00
parent 03d2e94f8b
commit d48abfba79
5 changed files with 152 additions and 122 deletions

View File

@@ -1,15 +1,16 @@
#include "requirementDetailPanel.h"
#include <wx/statline.h>
using namespace std;
using namespace gui;
//--------------------------------------------------------------
/* Constructor */
RequirementDetailPanel::RequirementDetailPanel(wxWindow *parentWindow, dBus::Bus &bus)
: wxScrolledWindow(parentWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER | wxVSCROLL)
: wxPanel(parentWindow /*, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER*/)
, m_bus(bus)
{
// Initialization
SetScrollRate(0, 10); // Set the scroll rate for the panel (vertical only)
// Creating controls
createControls();
@@ -20,24 +21,35 @@ RequirementDetailPanel::RequirementDetailPanel(wxWindow *parentWindow, dBus::Bus
/* Creating controls */
void RequirementDetailPanel::createControls()
{
const auto mainPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(500, -1), wxSIMPLE_BORDER);
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 wxButton(this, wxID_ANY, _("Close"));
const auto saveButton = new wxButton(this, wxID_ANY, _("Save"));
const auto discardButton = new wxButton(this, wxID_ANY, _("Discard"));
// Controls positioning
const auto ctrlSizer = new wxBoxSizer(wxVERTICAL);
ctrlSizer->Add(createControls_metadata(mainPanel), wxSizerFlags(0).Expand());
ctrlSizer->Add(createControls_details(mainPanel), wxSizerFlags(0).Expand());
ctrlSizer->Add(createControls_classification(mainPanel), wxSizerFlags(0).Expand());
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(0).Expand());
mainSizer->AddStretchSpacer(1);
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
FitInside();
mainPanel->FitInside();
// Harmonize the sizes of the title controls to ensure they have the same width
updateTitleSizes();
@@ -47,46 +59,30 @@ void RequirementDetailPanel::createControls()
/* Creating controls for requirement metadata (ID, UUID, name, description, etc.) */
wxSizer *RequirementDetailPanel::createControls_metadata(wxWindow *owner)
{
struct Item
{
wxWindow *titleCtrl;
wxWindow *inputCtrl;
};
std::vector<Item> items;
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 Item item{ .titleCtrl = createTitle(owner, _T("UUID:")),
.inputCtrl = new wxTextCtrl(owner, wxID_ANY) };
items.push_back(item);
}
{
const Item item{ .titleCtrl = createTitle(owner, _T("ID:")),
.inputCtrl = new wxTextCtrl(owner, wxID_ANY) };
items.push_back(item);
}
{
const Item item{ .titleCtrl = createTitle(owner, _("Author:")),
.inputCtrl = new wxTextCtrl(owner, wxID_ANY) };
items.push_back(item);
}
{
const Item item{ .titleCtrl = createTitle(owner, _("Created at:")),
.inputCtrl = new wxTextCtrl(owner, wxID_ANY) };
items.push_back(item);
}
{
const Item item{ .titleCtrl = createTitle(owner, _("Updated at:")),
.inputCtrl = new wxTextCtrl(owner, wxID_ANY) };
items.push_back(item);
}
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);
for (const auto &item : items)
{
ctrlSizer->Add(item.titleCtrl, wxSizerFlags(0).Expand().CenterVertical());
ctrlSizer->Add(item.inputCtrl, wxSizerFlags(1).Expand());
}
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
@@ -99,55 +95,28 @@ wxSizer *RequirementDetailPanel::createControls_metadata(wxWindow *owner)
/* Creating controls for requirement details (e.g., custom attributes, child requirements, etc.) */
wxSizer *RequirementDetailPanel::createControls_details(wxWindow *owner)
{
struct Item
{
wxWindow *titleCtrl;
wxWindow *inputCtrl;
};
std::vector<Item> items;
const auto titleTitleCtrl = createTitle(owner, _("Title:"));
const auto descriptionTitleCtrl = createTitle(owner, _("Description:"));
const auto acceptanceCriteriaTitleCtrl = createTitle(owner, _("Acceptance criteria:"));
{
const Item item{ .titleCtrl = createTitle(owner, _("Title:")),
.inputCtrl = new wxTextCtrl(owner, wxID_ANY) };
items.push_back(item);
}
{
const Item item{ .titleCtrl = createTitle(owner, _("Description:")),
.inputCtrl = new wxTextCtrl(owner,
wxID_ANY,
wxEmptyString,
wxDefaultPosition,
wxDefaultSize,
wxTE_PROCESS_TAB | wxTE_MULTILINE | wxVSCROLL | wxTE_AUTO_URL) };
items.push_back(item);
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."));
item.inputCtrl->SetMinSize(wxSize(-1, 200));
}
{
const Item item{ .titleCtrl = createTitle(owner, _("Acceptance criteria:")),
.inputCtrl = new wxTextCtrl(owner,
wxID_ANY,
wxEmptyString,
wxDefaultPosition,
wxDefaultSize,
wxTE_PROCESS_TAB | wxTE_MULTILINE | wxVSCROLL) };
items.push_back(item);
item.inputCtrl->SetMinSize(wxSize(-1, 100));
}
{
const Item item{ .titleCtrl = new wxPanel(owner),
.inputCtrl = new wxCheckBox(owner, wxID_ANY, _("S.M.A.R.T.")) };
items.push_back(item);
}
descriptionValueCtrl->SetMinSize(wxSize(-1, 200));
acceptanceCriteriaValueCtrl->SetMinSize(wxSize(-1, 100));
// Controls positioning
const auto ctrlSizer = new wxFlexGridSizer(2, 5, 5);
for (const auto &item : items)
{
ctrlSizer->Add(item.titleCtrl, wxSizerFlags(0).Expand().CenterVertical());
ctrlSizer->Add(item.inputCtrl, wxSizerFlags(1).Expand());
}
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");
@@ -159,41 +128,26 @@ wxSizer *RequirementDetailPanel::createControls_details(wxWindow *owner)
/* Creating controls for requirement classification (e.g., priority, severity, etc.) */
wxSizer *RequirementDetailPanel::createControls_classification(wxWindow *owner)
{
struct Item
{
wxWindow *titleCtrl;
wxWindow *inputCtrl;
};
std::vector<Item> items;
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 Item item{ .titleCtrl = createTitle(owner, "Type:"),
.inputCtrl = new wxTextCtrl(owner, wxID_ANY) };
items.push_back(item);
}
{
const Item item{ .titleCtrl = createTitle(owner, "Category:"),
.inputCtrl = new wxTextCtrl(owner, wxID_ANY) };
items.push_back(item);
}
{
const Item item{ .titleCtrl = createTitle(owner, "Priority:"),
.inputCtrl = new wxTextCtrl(owner, wxID_ANY) };
items.push_back(item);
}
{
const Item item{ .titleCtrl = createTitle(owner, "Status:"),
.inputCtrl = new wxTextCtrl(owner, wxID_ANY) };
items.push_back(item);
}
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);
for (const auto &item : items)
{
ctrlSizer->Add(item.titleCtrl, wxSizerFlags(0).Expand().CenterVertical());
ctrlSizer->Add(item.inputCtrl, wxSizerFlags(1).Expand());
}
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");
@@ -211,6 +165,7 @@ wxStaticText *RequirementDetailPanel::createTitle(wxWindow *owner, const wxStrin
wxDefaultPosition,
wxDefaultSize,
wxST_NO_AUTORESIZE | wxALIGN_RIGHT);
ctrl->SetFont(GetFont().Italic());
m_titleControls.push_back(ctrl);