Work on the graphical interface for presenting requirements details
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
#include "requirementDetailPanel.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace gui;
|
||||
//--------------------------------------------------------------
|
||||
/* Constructor */
|
||||
RequirementDetailPanel::RequirementDetailPanel(wxWindow *parentWindow, dBus::Bus &bus)
|
||||
: wxScrolledWindow(parentWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER | wxVSCROLL)
|
||||
, m_bus(bus)
|
||||
{
|
||||
// Initialization
|
||||
SetScrollRate(0, 10); // Set the scroll rate for the panel (vertical only)
|
||||
|
||||
// Creating controls
|
||||
createControls();
|
||||
|
||||
// Post initialization
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Creating controls */
|
||||
void RequirementDetailPanel::createControls()
|
||||
{
|
||||
const auto mainPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(500, -1), wxSIMPLE_BORDER);
|
||||
|
||||
// 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());
|
||||
mainPanel->SetSizer(ctrlSizer);
|
||||
|
||||
const auto mainSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
mainSizer->Add(mainPanel, wxSizerFlags(0).Expand());
|
||||
mainSizer->AddStretchSpacer(1);
|
||||
|
||||
SetSizer(mainSizer);
|
||||
|
||||
// Set the virtual size to match the size of the child panel,
|
||||
// enabling scrolling if necessary
|
||||
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)
|
||||
{
|
||||
struct Item
|
||||
{
|
||||
wxWindow *titleCtrl;
|
||||
wxWindow *inputCtrl;
|
||||
};
|
||||
std::vector<Item> items;
|
||||
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// 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->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)
|
||||
{
|
||||
struct Item
|
||||
{
|
||||
wxWindow *titleCtrl;
|
||||
wxWindow *inputCtrl;
|
||||
};
|
||||
std::vector<Item> items;
|
||||
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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->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)
|
||||
{
|
||||
struct Item
|
||||
{
|
||||
wxWindow *titleCtrl;
|
||||
wxWindow *inputCtrl;
|
||||
};
|
||||
std::vector<Item> items;
|
||||
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// 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->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);
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <dBus/dBus.h>
|
||||
#include <wx/wx.h>
|
||||
|
||||
namespace gui
|
||||
{
|
||||
//--------------------------------------------------------------
|
||||
class RequirementDetailPanel : public wxScrolledWindow
|
||||
{
|
||||
public:
|
||||
RequirementDetailPanel() = delete; // Default constructor
|
||||
virtual ~RequirementDetailPanel() = default; // Default destructor
|
||||
RequirementDetailPanel(const RequirementDetailPanel &obj) = delete; // Copy constructor
|
||||
RequirementDetailPanel(RequirementDetailPanel &&obj) noexcept = delete; // Move constructor
|
||||
RequirementDetailPanel &operator=(const RequirementDetailPanel &obj) = delete; // Copy assignment operator
|
||||
RequirementDetailPanel &operator=(RequirementDetailPanel &&obj) noexcept = delete; // Move assignment operator
|
||||
|
||||
explicit RequirementDetailPanel(wxWindow *parentWindow, dBus::Bus &bus); // Constructor
|
||||
|
||||
protected:
|
||||
dBus::Bus &m_bus; // Reference to the application bus
|
||||
std::vector<wxControl *> m_titleControls; // Titles controls for each section (metadata, details, classification)
|
||||
|
||||
private:
|
||||
void createControls(); // Creating controls
|
||||
wxSizer *createControls_metadata(wxWindow *owner); // Creating controls for requirement metadata
|
||||
wxSizer *createControls_details(wxWindow *owner); // Creating controls for requirement details
|
||||
wxSizer *createControls_classification(wxWindow *owner); // Creating controls for requirement classification
|
||||
|
||||
wxStaticText *createTitle(wxWindow *owner, const wxString &title); // Helper function to create a section title control
|
||||
void updateTitleSizes() const; // Harmonize the sizes of the title controls to ensure they have the same width
|
||||
};
|
||||
//--------------------------------------------------------------
|
||||
} // namespace gui
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "requirementListPanel.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace gui;
|
||||
//--------------------------------------------------------------
|
||||
/* Constructor */
|
||||
RequirementListPanel::RequirementListPanel(wxWindow *parentWindow, dBus::Bus &bus)
|
||||
: wxPanel(parentWindow, wxID_ANY, wxDefaultPosition, wxSize(300, -1), wxSIMPLE_BORDER)
|
||||
, m_bus(bus)
|
||||
{
|
||||
// Initialization
|
||||
|
||||
// Creating controls
|
||||
createControls();
|
||||
|
||||
// Post initialization
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Creating controls */
|
||||
void RequirementListPanel::createControls()
|
||||
{
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <dBus/dBus.h>
|
||||
#include <wx/wx.h>
|
||||
|
||||
namespace gui
|
||||
{
|
||||
//--------------------------------------------------------------
|
||||
class RequirementListPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
RequirementListPanel() = delete; // Default constructor
|
||||
virtual ~RequirementListPanel() = default; // Default destructor
|
||||
RequirementListPanel(const RequirementListPanel &obj) = delete; // Copy constructor
|
||||
RequirementListPanel(RequirementListPanel &&obj) noexcept = delete; // Move constructor
|
||||
RequirementListPanel &operator=(const RequirementListPanel &obj) = delete; // Copy assignment operator
|
||||
RequirementListPanel &operator=(RequirementListPanel &&obj) noexcept = delete; // Move assignment operator
|
||||
|
||||
explicit RequirementListPanel(wxWindow *parentWindow, dBus::Bus &bus); // Constructor
|
||||
|
||||
protected:
|
||||
dBus::Bus &m_bus; // Reference to the application bus
|
||||
|
||||
private:
|
||||
void createControls(); // Creating controls
|
||||
};
|
||||
//--------------------------------------------------------------
|
||||
} // namespace gui
|
||||
40
src/gui/requirementsPanel/requirementsPanel.cpp
Normal file
40
src/gui/requirementsPanel/requirementsPanel.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include "requirementsPanel.h"
|
||||
|
||||
#include "requirementDetailPanel/requirementDetailPanel.h"
|
||||
#include "requirementListPanel/requirementListPanel.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace gui;
|
||||
//--------------------------------------------------------------
|
||||
/* Constructor */
|
||||
RequirementsPanel::RequirementsPanel(wxWindow *parentWindow, dBus::Bus &bus)
|
||||
: wxPanel(parentWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER)
|
||||
, dBus::wxNode(this, bus)
|
||||
{
|
||||
// Initialization
|
||||
|
||||
// Creating controls
|
||||
createControls();
|
||||
|
||||
// Post initialization
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Creating controls */
|
||||
void RequirementsPanel::createControls()
|
||||
{
|
||||
m_requirementListPanel = new RequirementListPanel(this, m_bus);
|
||||
m_requirementDetailPanel = new RequirementDetailPanel(this, m_bus);
|
||||
|
||||
// Controls positioning
|
||||
const auto mainSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
mainSizer->Add(m_requirementListPanel, wxSizerFlags(0).Expand().Border(wxALL, 5));
|
||||
mainSizer->Add(m_requirementDetailPanel, wxSizerFlags(1).Expand().Border(wxALL, 5));
|
||||
|
||||
SetSizer(mainSizer);
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* dBus message reception handler */
|
||||
void RequirementsPanel::on_receiveMessageFromBus(MessageID messageID, MessagePtr message)
|
||||
{
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
68
src/gui/requirementsPanel/requirementsPanel.h
Normal file
68
src/gui/requirementsPanel/requirementsPanel.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include "gui/wxNode.h"
|
||||
|
||||
#include <dBus/dBus.h>
|
||||
#include <wx/wx.h>
|
||||
|
||||
namespace gui
|
||||
{
|
||||
class RequirementDetailPanel;
|
||||
class RequirementListPanel;
|
||||
|
||||
//--------------------------------------------------------------
|
||||
class RequirementsPanel : public wxPanel
|
||||
, public dBus::wxNode
|
||||
{
|
||||
public:
|
||||
RequirementsPanel() = delete; // Default constructor
|
||||
virtual ~RequirementsPanel() = default; // Default destructor
|
||||
RequirementsPanel(const RequirementsPanel &obj) = delete; // Copy constructor
|
||||
RequirementsPanel(RequirementsPanel &&obj) noexcept = delete; // Move constructor
|
||||
RequirementsPanel &operator=(const RequirementsPanel &obj) = delete; // Copy assignment operator
|
||||
RequirementsPanel &operator=(RequirementsPanel &&obj) noexcept = delete; // Move assignment operator
|
||||
|
||||
explicit RequirementsPanel(wxWindow *parentWindow, dBus::Bus &bus); // Constructor
|
||||
|
||||
protected:
|
||||
// Controls
|
||||
RequirementListPanel *m_requirementListPanel = nullptr; // Pointer to the requirement list panel control
|
||||
RequirementDetailPanel *m_requirementDetailPanel = nullptr; // Pointer to the requirement detail panel control
|
||||
|
||||
private:
|
||||
void createControls(); // Creating controls
|
||||
|
||||
// Events
|
||||
void on_receiveMessageFromBus(MessageID messageID, MessagePtr message) override; // dBus message reception handler
|
||||
};
|
||||
//--------------------------------------------------------------
|
||||
} // namespace gui
|
||||
|
||||
/*
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ ▼ Métadonnées │
|
||||
│ ID: [REQ-001] 🔒 │
|
||||
│ UUID: [abc-123-def] 🔒 │
|
||||
│ Auteur: [John Doe] 🔒 │
|
||||
│ Créé le: [2026-03-13 14:30] 🔒 │
|
||||
│ Modifié le: [2026-03-13 15:45] 🔒 │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ ▼ Détails │
|
||||
│ Nom: [________________] │
|
||||
│ Description: [ ] │
|
||||
│ [ ] │
|
||||
│ [________________] │
|
||||
│ Critères: [ ] │
|
||||
│ [________________] │
|
||||
│ □ SMART │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ ▼ Classification │
|
||||
│ Type: [Functional ▼] │
|
||||
│ Catégorie: [Backend ▼] │
|
||||
│ Priorité: ● ● ● ○ ○ (3/5) │
|
||||
│ Statut: ○ Draft ○ Review │
|
||||
│ ● Approved ○ Rejected │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ [Enregistrer] [Annuler] │
|
||||
└─────────────────────────────────────────────┘
|
||||
*/
|
||||
Reference in New Issue
Block a user