Additional Model metadata - Description (#9398)

* starting to add description field to GUI

* additional work to add GUI

* make a multi-line entry

* Remove building of non-mac

* fix tag collision

* debugging suggestions from CoPilot

* yet another debug suggestion

* Fix build with Xcode 16.3

* Simplify OpenVDB patch, from 930c3acb8e (diff-bc3061cc2fe6c64a3d67c8350330bb3a530d01037faace6da27ad9a12aa03e29)

* Fix CGAL header under clang 19
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=281880

* Fix compile error due to removal of base template for `std::char_traits` in clang 19
https://releases.llvm.org/19.1.0/projects/libcxx/docs/ReleaseNotes.html#deprecations-and-removals

* Update Auxiliary.cpp trying to prevent crash

* Add files via upload

* from other branch

* rolling back changes

---------

Co-authored-by: Kaleb Best <kalebbest@MacBook-Air.local>
Co-authored-by: Noisyfox <timemanager.rick@gmail.com>
This commit is contained in:
kfbest 2025-06-01 06:35:48 -04:00 committed by GitHub
parent 5df4275c18
commit 63bca8ab64
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 52 additions and 23 deletions

View file

@ -855,9 +855,9 @@ void AuxiliaryPanel::init_tabpanel()
sizer_side_tools->Add(back_btn, 1, wxEXPAND, 0); sizer_side_tools->Add(back_btn, 1, wxEXPAND, 0);
m_tabpanel = new Tabbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, sizer_side_tools, wxNB_LEFT | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME); m_tabpanel = new Tabbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, sizer_side_tools, wxNB_LEFT | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
m_tabpanel->SetBackgroundColour(wxColour("#FEFFFF")); m_tabpanel->SetBackgroundColour(wxColour("#FEFFFF"));
m_tabpanel->Bind(wxEVT_BOOKCTRL_PAGE_CHANGED, [this](wxBookCtrlEvent &e) { ; }); m_tabpanel->Bind(wxEVT_BOOKCTRL_PAGE_CHANGED, [](wxBookCtrlEvent &e) { /* Event handling */ });
m_designer_panel = new DesignerPanel(m_tabpanel, AuxiliaryFolderType::DESIGNER); m_designer_panel = new DesignerPanel(m_tabpanel, AuxiliaryFolderType::DESIGNER);
m_pictures_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::MODEL_PICTURE); m_pictures_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::MODEL_PICTURE);
m_bill_of_materials_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::BILL_OF_MATERIALS); m_bill_of_materials_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::BILL_OF_MATERIALS);
m_assembly_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::ASSEMBLY_GUIDE); m_assembly_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::ASSEMBLY_GUIDE);
@ -1060,52 +1060,61 @@ void AuxiliaryPanel::update_all_cover()
{ {
SetBackgroundColour(AUFILE_GREY300); SetBackgroundColour(AUFILE_GREY300);
wxBoxSizer *m_sizer_body = new wxBoxSizer(wxVERTICAL); wxBoxSizer *m_sizer_body = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *m_sizer_designer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *m_sizer_designer = new wxBoxSizer(wxHORIZONTAL);
auto m_text_designer = new wxStaticText(this, wxID_ANY, _L("Author"), wxDefaultPosition, wxSize(180, -1), 0); auto m_text_designer = new wxStaticText(this, wxID_ANY, _L("Author"), wxDefaultPosition, wxSize(180, -1), 0);
m_text_designer->Wrap(-1); m_text_designer->Wrap(-1);
m_text_designer->SetForegroundColour(*wxBLACK); m_text_designer->SetForegroundColour(*wxBLACK);
m_sizer_designer->Add(m_text_designer, 0, wxALIGN_CENTER, 0); m_sizer_designer->Add(m_text_designer, 0, wxALIGN_CENTER, 0);
m_input_designer = new ::TextInput(this, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(450), FromDIP(30)), wxTE_PROCESS_ENTER); m_input_designer = new ::TextInput(this, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(450), FromDIP(30)), wxTE_PROCESS_ENTER);
m_input_designer->GetTextCtrl()->SetFont(::Label::Body_14); m_input_designer->GetTextCtrl()->SetFont(::Label::Body_14);
m_input_designer->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1)); m_input_designer->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1));
m_sizer_designer->Add(m_input_designer, 0, wxALIGN_CENTER, 0); m_sizer_designer->Add(m_input_designer, 0, wxALIGN_CENTER, 0);
wxBoxSizer *m_sizer_model_name = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *m_sizer_model_name = new wxBoxSizer(wxHORIZONTAL);
auto m_text_model_name = new wxStaticText(this, wxID_ANY, _L("Model Name"), wxDefaultPosition, wxSize(180, -1), 0); auto m_text_model_name = new wxStaticText(this, wxID_ANY, _L("Model Name"), wxDefaultPosition, wxSize(180, -1), 0);
m_text_model_name->SetForegroundColour(*wxBLACK); m_text_model_name->SetForegroundColour(*wxBLACK);
m_text_model_name->Wrap(-1); m_text_model_name->Wrap(-1);
m_sizer_model_name->Add(m_text_model_name, 0, wxALIGN_CENTER, 0); m_sizer_model_name->Add(m_text_model_name, 0, wxALIGN_CENTER, 0);
m_input_model_name = new ::TextInput(this, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition,wxSize(FromDIP(450),FromDIP(30)), wxTE_PROCESS_ENTER);
m_imput_model_name = new ::TextInput(this, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition,wxSize(FromDIP(450),FromDIP(30)), wxTE_PROCESS_ENTER); m_input_model_name->GetTextCtrl()->SetFont(::Label::Body_14);
m_imput_model_name->GetTextCtrl()->SetFont(::Label::Body_14); m_input_model_name->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1));
m_imput_model_name->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1)); m_sizer_model_name->Add(m_input_model_name, 0, wxALIGN_CENTER, 0);
m_sizer_model_name->Add(m_imput_model_name, 0, wxALIGN_CENTER, 0);
wxBoxSizer *m_sizer_license = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *m_sizer_license = new wxBoxSizer(wxHORIZONTAL);
auto m_text_license = new wxStaticText(this, wxID_ANY, _L("License"), wxDefaultPosition, wxSize(180, -1), 0); auto m_text_license = new wxStaticText(this, wxID_ANY, _L("License"), wxDefaultPosition, wxSize(180, -1), 0);
m_text_license->Wrap(-1); m_text_license->Wrap(-1);
m_sizer_license->Add(m_text_license, 0, wxALIGN_CENTER, 0); m_sizer_license->Add(m_text_license, 0, wxALIGN_CENTER, 0);
m_combo_license = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(450), -1), 0, NULL, wxCB_READONLY); m_combo_license = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(450), -1), 0, NULL, wxCB_READONLY);
m_sizer_license->Add(m_combo_license, 0, wxALIGN_CENTER, 0); m_sizer_license->Add(m_combo_license, 0, wxALIGN_CENTER, 0);
m_sizer_body->Add( 0, 0, 0, wxTOP, FromDIP(50) ); wxBoxSizer *m_sizer_description = new wxBoxSizer(wxHORIZONTAL);
m_sizer_body->Add(m_sizer_designer, 0, wxLEFT, FromDIP(50)); auto m_text_description = new wxStaticText(this, wxID_ANY, _L("Description:"), wxDefaultPosition, wxSize(170, -1), 0); // Using "Description:" with the : because that already exists in the Localizations files
m_sizer_body->Add( 0, 0, 0, wxTOP, FromDIP(20)); m_text_description->SetForegroundColour(*wxBLACK);
m_sizer_body->Add(m_sizer_model_name, 0, wxLEFT, FromDIP(50)); m_text_description->Wrap(-1);
m_sizer_description->Add(m_text_description, 0, wxALIGN_TOP | wxRIGHT, FromDIP(10));
m_input_description = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
wxSize(FromDIP(450), FromDIP(300)), wxTE_MULTILINE | wxTE_PROCESS_ENTER);
m_input_description->SetFont(::Label::Body_14);
m_sizer_description->Add(m_input_description, 0, wxALIGN_CENTER, 0);
m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(50));
m_sizer_body->Add(m_sizer_designer, 0, wxLEFT | wxALIGN_LEFT, FromDIP(50));
m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(20)); m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(20));
m_sizer_body->Add(m_sizer_license, 0, wxLEFT, FromDIP(50)); m_sizer_body->Add(m_sizer_model_name, 0, wxLEFT | wxALIGN_LEFT, FromDIP(50));
m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(20));
m_sizer_body->Add(m_sizer_license, 0, wxLEFT | wxALIGN_LEFT, FromDIP(50));
init_license_list(); init_license_list();
m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(20));
m_sizer_body->Add(m_sizer_description, 0, wxLEFT | wxALIGN_LEFT, FromDIP(50));
SetSizer(m_sizer_body); SetSizer(m_sizer_body);
Layout(); Layout();
Fit(); Fit();
m_input_designer->Bind(wxEVT_TEXT, &DesignerPanel::on_input_enter_designer, this); m_input_designer->Bind(wxEVT_TEXT, &DesignerPanel::on_input_enter_designer, this);
m_imput_model_name->Bind(wxEVT_TEXT, &DesignerPanel::on_input_enter_model, this); m_input_model_name->Bind(wxEVT_TEXT, &DesignerPanel::on_input_enter_model, this);
m_input_description->Bind(wxEVT_TEXT, &DesignerPanel::on_input_enter_description, this);
m_combo_license->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &DesignerPanel::on_select_license, this); m_combo_license->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &DesignerPanel::on_select_license, this);
} }
@ -1148,6 +1157,12 @@ void DesignerPanel::on_input_enter_model(wxCommandEvent &evt)
ensure_model_info()->model_name = std::string(text.ToUTF8().data()); ensure_model_info()->model_name = std::string(text.ToUTF8().data());
} }
void DesignerPanel::on_input_enter_description(wxCommandEvent &evt)
{
auto text = evt.GetString();
ensure_model_info()->description = std::string(text.ToUTF8().data());
}
void DesignerPanel::update_info() void DesignerPanel::update_info()
{ {
if (wxGetApp().plater()->model().design_info != nullptr) { if (wxGetApp().plater()->model().design_info != nullptr) {
@ -1158,12 +1173,14 @@ void DesignerPanel::update_info()
} }
if (wxGetApp().plater()->model().model_info != nullptr) { if (wxGetApp().plater()->model().model_info != nullptr) {
m_imput_model_name->GetTextCtrl()->SetValue(wxString::FromUTF8(wxGetApp().plater()->model().model_info->model_name)); m_input_model_name->GetTextCtrl()->SetValue(wxString::FromUTF8(wxGetApp().plater()->model().model_info->model_name));
m_input_description->ChangeValue(wxString::FromUTF8(wxGetApp().plater()->model().model_info->description));
if (!m_combo_license->SetStringSelection(wxString::FromUTF8(wxGetApp().plater()->model().model_info->license))) { if (!m_combo_license->SetStringSelection(wxString::FromUTF8(wxGetApp().plater()->model().model_info->license))) {
m_combo_license->SetSelection(0); m_combo_license->SetSelection(0);
} }
} else { } else {
m_imput_model_name->GetTextCtrl()->SetValue(wxEmptyString); m_input_model_name->GetTextCtrl()->SetValue(wxEmptyString);
m_input_description->ChangeValue(wxEmptyString);
m_combo_license->SetSelection(0); m_combo_license->SetSelection(0);
} }
} }
@ -1171,8 +1188,8 @@ void DesignerPanel::update_info()
void DesignerPanel::msw_rescale() void DesignerPanel::msw_rescale()
{ {
m_input_designer->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1)); m_input_designer->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1));
m_imput_model_name->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1)); m_input_model_name->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1));
m_combo_license->SetSize(wxSize(FromDIP(450), -1)); m_combo_license->SetSize(wxSize(FromDIP(450), -1));
} m_input_description->SetSize(wxSize(FromDIP(450), -1));}
}} // namespace Slic3r::GUI }} // namespace Slic3r::GUI

View file

@ -180,12 +180,14 @@ public:
~DesignerPanel(); ~DesignerPanel();
::TextInput* m_input_designer {nullptr}; ::TextInput* m_input_designer {nullptr};
::TextInput* m_imput_model_name {nullptr}; ::TextInput* m_input_model_name {nullptr};
wxTextCtrl* m_input_description {nullptr};
ComboBox* m_combo_license {nullptr}; ComboBox* m_combo_license {nullptr};
bool Show(bool show) override; bool Show(bool show) override;
void init_license_list(); void init_license_list();
void on_input_enter_designer(wxCommandEvent &evt); void on_input_enter_designer(wxCommandEvent &evt);
void on_input_enter_model(wxCommandEvent &evt); void on_input_enter_model(wxCommandEvent &evt);
void on_input_enter_description(wxCommandEvent &evt);
void on_select_license(wxCommandEvent& evt); void on_select_license(wxCommandEvent& evt);
void update_info(); void update_info();
void msw_rescale(); void msw_rescale();

View file

@ -76,6 +76,16 @@ ProjectPanel::ProjectPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos,
ProjectPanel::~ProjectPanel() {} ProjectPanel::~ProjectPanel() {}
// Helper to convert newlines to <br>
static std::string convert_newlines_to_br(const std::string& text) {
std::string result = text;
size_t pos = 0;
while ((pos = result.find('\n', pos)) != std::string::npos) {
result.replace(pos, 1, "<br>");
pos += 4;
}
return result;
}
void ProjectPanel::onWebNavigating(wxWebViewEvent& evt) void ProjectPanel::onWebNavigating(wxWebViewEvent& evt)
{ {
@ -189,7 +199,7 @@ void ProjectPanel::on_reload(wxCommandEvent& evt)
j["model"]["name"] = wxGetApp().url_encode(model_name); j["model"]["name"] = wxGetApp().url_encode(model_name);
j["model"]["author"] = wxGetApp().url_encode(model_author);; j["model"]["author"] = wxGetApp().url_encode(model_author);;
j["model"]["cover_img"] = wxGetApp().url_encode(cover_file); j["model"]["cover_img"] = wxGetApp().url_encode(cover_file);
j["model"]["description"] = wxGetApp().url_encode(description); j["model"]["description"] = wxGetApp().url_encode(convert_newlines_to_br(description));
j["model"]["preview_img"] = files["Model Pictures"]; j["model"]["preview_img"] = files["Model Pictures"];
j["model"]["upload_type"] = update_type; j["model"]["upload_type"] = update_type;