Add project info editor (#3754)

* Add button to add model info

* Initial impl of project info editor

* Add sidebar item to edit project info

* Add license selector

* Fix use of deprecated apis

* Fix license combox dark mode

* Add back button on project info editor screen

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
Noisyfox 2024-01-21 22:13:37 +08:00 committed by GitHub
parent ead78a98f9
commit 122c5cedd8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 292 additions and 189 deletions

View file

@ -84,9 +84,21 @@ var LangText = {
t89: "Open Containing Folder",
t90: "3D Model",
t91: "Download 3D models",
t92: "Bambu Christmas Cabin",
t93: "Printer Connection",
t94: "Please set up your printer connection to view the device.",
"t92": "Create by",
"t93": "Remixed by",
"t94": "Shared by",
"t95": "Model Information",
"t96": "Accessories",
"t97": "Profile Information",
"t98": "Model name",
"t100":"Model description",
"t101":"BOM",
"t102":"Assembly Guide",
"t103":"Other",
"t104":"Profile name",
"t105":"Profile Author",
"t106":"Profile description",
orca1: "Edit Project Info",
},
es_ES: {
t1: "Bienvenido a Orca Slicer",
@ -173,9 +185,20 @@ var LangText = {
t89: "Abrir carpeta contenedora",
t90: "Modelo 3D",
t91: "Descargar modelos 3D",
t92: "Cabina Bambú de Navidad",
t93: "Conexión de Impresora",
t94: "Por favor, configure la conexión de red de la impresora para encontrarla.",
"t92": "Creado por",
"t93": "Remixado por",
"t94": "Compartido por",
"t95": "Información del modelo",
"t96": "Accesorios",
"t97": "Información del perfil",
"t98": "Nombre del modelo",
"t100": "Descripción del modelo",
"t101": "Lista de materiales",
"t102": "Guía de ensamblaje",
"t103": "Otros",
"t104": "Nombre del perfil",
"t105": "Autor del perfil",
"t106": "Descripción del perfil",
},
de_DE: {
t1: "Willkommen im Orca Slicer",
@ -262,7 +285,20 @@ var LangText = {
t89: "Enthaltenden Ordner öffnen",
t90: "3D-Modell",
t91: "3D-Modelle herunterladen",
t92: "Bambu Weihnachtshütte",
"t92": "Erstellt von",
"t93": "Remixed von",
"t94": "Geteilt von",
"t95": "Modellinformationen",
"t96": "Zubehör",
"t97": "Profilinformationen",
"t98": "Modellname",
"t100": "Modellbeschreibung",
"t101": "Stückliste",
"t102": "Montageanleitung",
"t103": "Andere",
"t104": "Profilname",
"t105": "Profilautor",
"t106": "Profilbeschreibung",
},
cs_CZ: {
t1: "Vítejte v Orca Slicer",
@ -349,7 +385,20 @@ var LangText = {
t89: "Otevřít složku obsahující",
t90: "3D model",
t91: "Stáhnout 3D modely",
t92: "Vánoční kabina Bambu",
"t92": "Vytvořil",
"t93": "Přepracováno",
"t94": "Sdíleno",
"t95": "Informace o modelu",
"t96": "Příslušenství",
"t97": "Informace o profilu",
"t98": "Název modelu",
"t100":"Popis modelu",
"t101":"Seznam součástek (BOM)",
"t102":"Průvodce sestavením",
"t103":"Jiné",
"t104":"Název profilu",
"t105":"Autor profilu",
"t106":"Popis profilu",
},
fr_FR: {
t1: "Bienvenue sur Orca Slicer",
@ -436,9 +485,20 @@ var LangText = {
t89: "Ouvrir le dossier contenant",
t90: "Modèle 3D",
t91: "Télécharger des modèles 3D",
t92: "Cabane de Noël Bambu",
t93: "Connexion à l'imprimante",
t94: "Veuillez configurer la connexion de votre imprimante pour afficher l'interface.",
"t92": "Créé par",
"t93": "Remixé par",
"t94": "Partagé par",
"t95": "Informations sur le modèle",
"t96": "Accessoires",
"t97": "Informations de profil",
"t98": "Nom du modèle",
"t100": "Description du modèle",
"t101": "BOM",
"t102": "Guide d'assemblage",
"t103": "Autre",
"t104": "Nom du profil",
"t105": "Auteur du profil",
"t106": "Description du profil",
t109: "Filaments du système",
t110: "Filaments personnalisés",
t111: "Créer un nouveau filament",
@ -544,7 +604,20 @@ var LangText = {
t89: "打开所在的文件夹",
t90: "3D 模型",
t91: "下载3D模型",
t92: "Bambu圣诞小屋",
"t92": "创作",
"t93": "修改",
"t94": "分享",
"t95": "模型信息",
"t96": "附件",
"t97": "配置信息",
"t98": "模型名称",
"t100":"模型介绍",
"t101":"物料清单",
"t102":"装备指导",
"t103":"其他",
"t104":"配置名称",
"t105":"配置作者",
"t106":"配置介绍",
wk1: "快速入门指南",
wk2: "本文介绍了Orca Slicer的最基本用法。它指导用户配置软件创建项目并逐步完成第一个打印任务。",
wk3: "基于项目的工作流",
@ -561,6 +634,7 @@ var LangText = {
wk14: "与STL相比STEP带来了更多有效的信息。由于STEP的高精度切片时可以生成更多的圆弧路径。STEP还包括模型每个零件的装配关系可分割模型后恢复装配视图。",
wk15: "3D文本",
wk16: "使用3D文本工具用户可以轻松地在项目中创建各种3D文本形状使模型更加个性化。Orca Slicer提供了数十种字体并支持粗体和斜体样式使文本具有更大的灵活性。",
orca1: "编辑项目信息",
},
zh_TW: {
t1: "歡迎使用 Orca Slicer",

View file

@ -66,3 +66,8 @@ a
{
background-color:#36363C;
}
#AddModelInfoBtn:hover
{
color: #000;
}

View file

@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="-3 -3 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.0769 6.84171C12.0769 6.58678 12.2835 6.38017 12.5385 6.38017C12.7934 6.38017 13 6.58678 13 6.84171V10.6923C13 11.9668 11.9668 13 10.6923 13H3.30769C2.03323 13 1 11.9668 1 10.6923V3.30769C1 2.03323 2.03323 1 3.30769 1H7.7006C7.95553 1 8.16214 1.20661 8.16214 1.46154C8.16214 1.71647 7.95553 1.92308 7.7006 1.92308H3.30769C2.54309 1.92308 1.92308 2.54309 1.92308 3.30769V10.6923C1.92308 11.4569 2.54309 12.0769 3.30769 12.0769H10.6923C11.4569 12.0769 12.0769 11.4571 12.0769 10.6923V6.84171ZM11.8775 1.74946C12.0528 1.57007 12.3392 1.5634 12.5226 1.73431C12.706 1.90541 12.7191 2.19171 12.5523 2.37885L7.51689 7.77975C7.34309 7.96617 7.05102 7.97644 6.86442 7.80264C6.67801 7.62885 6.66773 7.33678 6.84153 7.15018L11.8775 1.74946Z" fill="#6B6B6B"/>
</svg>

After

Width:  |  Height:  |  Size: 865 B

View file

@ -26,6 +26,7 @@
<div id="EmptyArea">
<div><img src="img/null.png"></div>
<div>no model information</div>
<div id="AddModelInfoBtn" class="trans TextS1" tid='orca1' onClick="OnClickEditProjectInfo()">Edit Project Info</div>
</div>
<div id="WholeArea">
@ -42,6 +43,9 @@
<div id="Profile_ProcessBar" class="LeftProcessBar" onclick="OnMenuClick('Model_Profile');">
<img class="LeftTipIcon ProfileIcon" src="img/profile_h.svg" /><span class="trans" tid='t97'>Profile Information</span>
</div>
<div id="Edit_ProcessBar" class="LeftProcessBar" onclick="OnClickEditProjectInfo();">
<img class="LeftTipIcon" src="img/edit.svg" /><span class="trans" tid='orca1'>Edit Project Info</span>
</div>
</div>
<div id="LeftEmptyBlock" style="height: 100%;width:280px;">&nbsp;</div>

View file

@ -153,7 +153,7 @@ body
position:fixed;
top: 24px;
width: 264px;
height: 120px;
height: 160px;
flex-shrink: 0;
}
@ -376,3 +376,19 @@ body
background-color: rgba(255,0,0,.5)!important;
}
#AddModelInfoBtn
{
border-width: 1px;
border-style: solid;
padding: 0px 10px;
border-radius: 6px;
line-height: 26px;
height: 26px;
margin-top: 20px;
cursor: pointer;
}
#AddModelInfoBtn:hover
{
background-color:#CDCECE;
}

View file

@ -580,7 +580,14 @@ function OnClickOpenImage( F_ID )
$("img#"+F_ID).click();
}
function OnClickEditProjectInfo()
{
var tSend={};
tSend['sequence_id']=Math.round(new Date() / 1000);
tSend['command']="edit_project_info";
SendWXMessage( JSON.stringify(tSend) );
}

View file

@ -836,7 +836,7 @@ end:
// BBS: backup all in one dir
std::string Model::get_auxiliary_file_temp_path()
{
return get_backup_path("/Auxiliaries");
return get_backup_path("Auxiliaries");
}
// BBS: backup dir

View file

@ -33,17 +33,29 @@ wxDEFINE_EVENT(EVT_AUXILIARY_IMPORT, wxCommandEvent);
wxDEFINE_EVENT(EVT_AUXILIARY_UPDATE_COVER, wxCommandEvent);
wxDEFINE_EVENT(EVT_AUXILIARY_UPDATE_DELETE, wxCommandEvent);
wxDEFINE_EVENT(EVT_AUXILIARY_UPDATE_RENAME, wxCommandEvent);
wxDEFINE_EVENT(EVT_AUXILIARY_DONE, wxCommandEvent);
const std::vector<std::string> license_list = {
"BSD License",
"Apache License",
"GPL License",
"LGPL License",
"MIT License",
"CC License"
"",
"CC0",
"BY",
"BY-SA",
"BY-ND",
"BY-NC",
"BY-NC-SA",
"BY-NC-ND",
};
static std::shared_ptr<ModelInfo> ensure_model_info()
{
auto& model = wxGetApp().plater()->model();
if (model.model_info == nullptr) {
model.model_info = std::make_shared<ModelInfo>();
}
return model.model_info;
}
AuFile::AuFile(wxWindow *parent, fs::path file_path, wxString file_name, AuxiliaryFolderType type, wxWindowID id, const wxPoint &pos, const wxSize &size, long style)
{
m_type = type;
@ -344,7 +356,7 @@ void AuFile::on_input_enter(wxCommandEvent &evt)
}
auto existing = false;
auto dir = m_file_path.branch_path();
auto dir = m_file_path.parent_path();
auto new_fullname = new_file_name + m_file_path.extension().string();
@ -454,14 +466,12 @@ void AuFile::on_mouse_left_up(wxMouseEvent &evt)
void AuFile::on_set_cover()
{
if (wxGetApp().plater()->model().model_info == nullptr) { wxGetApp().plater()->model().model_info = std::make_shared<ModelInfo>(); }
fs::path path(into_path(m_file_name));
wxGetApp().plater()->model().model_info->cover_file = path.string();
ensure_model_info()->cover_file = path.string();
//wxGetApp().plater()->model().model_info->cover_file = m_file_name.ToStdString();
auto full_path = m_file_path.branch_path();
auto full_root_path = full_path.branch_path();
auto full_path = m_file_path.parent_path();
auto full_root_path = full_path.parent_path();
auto full_root_path_str = encode_path(full_root_path.string().c_str());
auto dir = wxString::Format("%s/.thumbnails", full_root_path_str);
@ -505,8 +515,8 @@ void AuFile::on_set_delete()
auto is_fine = fs::remove(bfs_path);
if (m_cover) {
auto full_path = m_file_path.branch_path();
auto full_root_path = full_path.branch_path();
auto full_path = m_file_path.parent_path();
auto full_root_path = full_path.parent_path();
auto full_root_path_str = encode_path(full_root_path.string().c_str());
auto dir = wxString::Format("%s/.thumbnails", full_root_path_str);
fs::path dir_path(dir.ToStdWstring());
@ -520,8 +530,11 @@ void AuFile::on_set_delete()
if (fs::exists(fs::path(middle_img_path))) { fs::remove(fs::path(middle_img_path)); }
}
if (wxGetApp().plater()->model().model_info == nullptr) { wxGetApp().plater()->model().model_info = std::make_shared<ModelInfo>(); }
if (wxGetApp().plater()->model().model_info->cover_file == m_file_name) { wxGetApp().plater()->model().model_info->cover_file = ""; }
if (wxGetApp().plater()->model().model_info != nullptr) {
if (wxGetApp().plater()->model().model_info->cover_file == m_file_name) {
wxGetApp().plater()->model().model_info->cover_file = "";
}
}
if (is_fine) {
auto evt = wxCommandEvent(EVT_AUXILIARY_UPDATE_DELETE);
@ -669,6 +682,7 @@ void AuFolderPanel::update(std::vector<fs::path> paths)
}
m_gsizer_content->Layout();
Layout();
Refresh();
}
void AuFolderPanel::msw_rescale()
@ -820,9 +834,22 @@ void AuxiliaryPanel::init_bitmap()
void AuxiliaryPanel::init_tabpanel()
{
auto m_side_tools = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(220), FromDIP(18)));
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Disabled),
std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Normal));
auto back_btn = new Button(this, _L("Back"), "assemble_return", wxBORDER_NONE | wxBU_LEFT | wxBU_EXACTFIT);
back_btn->SetSize(wxSize(FromDIP(220), FromDIP(18)));
back_btn->SetBackgroundColor(btn_bg_green);
back_btn->SetCornerRadius(0);
back_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](wxEvent& e) {
auto event = wxCommandEvent(EVT_AUXILIARY_DONE);
event.SetEventObject(m_parent);
wxPostEvent(m_parent, event);
});
wxBoxSizer *sizer_side_tools = new wxBoxSizer(wxVERTICAL);
sizer_side_tools->Add(m_side_tools, 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->SetBackgroundColour(wxColour("#FEFFFF"));
m_tabpanel->Bind(wxEVT_BOOKCTRL_PAGE_CHANGED, [this](wxBookCtrlEvent &e) { ; });
@ -872,20 +899,7 @@ bool AuxiliaryPanel::Show(bool show) { return wxPanel::Show(show); }
void AuxiliaryPanel::init_auxiliary()
{
Model &model = wxGetApp().plater()->model();
m_root_dir = encode_path(model.get_auxiliary_file_temp_path().c_str());
if (wxDirExists(m_root_dir)) {
fs::path path_to_del(m_root_dir.ToStdWstring());
try {
fs::remove_all(path_to_del);
} catch (...) {
BOOST_LOG_TRIVIAL(error) << "Failed removing the auxiliary directory " << m_root_dir.c_str();
}
}
fs::path top_dir_path(m_root_dir.ToStdWstring());
fs::create_directory(top_dir_path);
for (auto folder : s_default_folders) create_folder(folder);
Reload(encode_path(model.get_auxiliary_file_temp_path().c_str()), {});
}
void AuxiliaryPanel::on_import_file(wxCommandEvent &event)
@ -947,7 +961,7 @@ void AuxiliaryPanel::on_import_file(wxCommandEvent &event)
boost::system::error_code ec;
if (!fs::copy_file(src_bfs_path, fs::path(dir_path.ToStdWstring()), fs::copy_option::overwrite_if_exists, ec)) continue;
if (!fs::copy_file(src_bfs_path, fs::path(dir_path.ToStdWstring()), fs::copy_options::overwrite_existing, ec)) continue;
Slic3r::put_other_changes();
// add in file list
@ -987,76 +1001,22 @@ std::string AuxiliaryPanel::replaceSpace(std::string s, std::string ts, std::str
return s;
}
void AuxiliaryPanel::Reload(wxString aux_path)
void AuxiliaryPanel::Reload(wxString aux_path, std::map<std::string, std::vector<json>> paths)
{
fs::path new_aux_path(aux_path.ToStdWstring());
try {
fs::remove_all(fs::path(m_root_dir.ToStdWstring()));
} catch (...) {
BOOST_LOG_TRIVIAL(error) << "Failed removing the auxiliary directory " << m_root_dir.c_str();
}
m_root_dir = aux_path;
m_paths_list.clear();
// Check new path. If not exist, create a new one.
if (!fs::exists(new_aux_path)) {
fs::create_directory(new_aux_path);
// Create default folders if they are not loaded
for (auto folder : s_default_folders) {
wxString folder_path = aux_path + "/" + folder;
if (fs::exists(folder_path.ToStdWstring())) continue;
fs::create_directory(folder_path.ToStdWstring());
for (const auto & path : paths) {
m_paths_list[path.first] = std::vector<fs::path>{};
for (const auto & j : path.second) {
m_paths_list[path.first].push_back(j["_filepath"]);
}
update_all_panel();
m_designer_panel->update_info();
return;
}
// Load from new path
std::vector<fs::path> dir_cache;
fs::directory_iterator iter_end;
for (fs::directory_iterator iter(new_aux_path); iter != iter_end; iter++) {
wxString path = iter->path().generic_wstring();
dir_cache.push_back(iter->path());
}
for (auto dir : dir_cache) {
for (fs::directory_iterator iter(dir); iter != iter_end; iter++) {
if (fs::is_directory(iter->path())) continue;
wxString file_path = iter->path().generic_wstring();
//auto file_path_str = encode_path(file_path.c_str());
for (auto folder : s_default_folders) {
auto idx = file_path.find(folder.ToStdString());
if (idx != std::string::npos) {
auto iter = m_paths_list.find(folder.ToStdString());
auto file_path_str = fs::path(file_path.ToStdWstring());
if (iter != m_paths_list.end()) {
m_paths_list[folder.ToStdString()].push_back(file_path_str);
break;
} else {
m_paths_list[folder.ToStdString()] = std::vector<fs::path>{file_path_str};
break;
}
}
}
}
}
// Create default folders if they are not loaded
wxDataViewItemArray default_items;
for (auto folder : s_default_folders) {
wxString folder_path = aux_path + "/" + folder;
if (fs::exists(folder_path.ToStdWstring())) continue;
fs::create_directory(folder_path.ToStdWstring());
}
update_all_panel();
update_all_cover();
m_designer_panel->update_info();
m_tabpanel->SetSelection(0);
}
void AuxiliaryPanel::update_all_panel()
@ -1121,22 +1081,21 @@ void AuxiliaryPanel::update_all_cover()
m_imput_model_name->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1));
m_sizer_model_name->Add(m_imput_model_name, 0, wxALIGN_CENTER, 0);
/*
wxBoxSizer *m_sizer_license = new wxBoxSizer(wxHORIZONTAL);
auto m_text_license = new wxStaticText(this, wxID_ANY, _L("License"), wxDefaultPosition, wxSize(120, -1), 0);
auto m_text_license = new wxStaticText(this, wxID_ANY, _L("License"), wxDefaultPosition, wxSize(180, -1), 0);
m_text_license->Wrap(-1);
m_sizer_license->Add(m_text_license, 0, wxALIGN_CENTER, 0);
m_combo_license = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(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_body->Add( 0, 0, 0, wxTOP, FromDIP(50) );
m_sizer_body->Add(m_sizer_designer, 0, wxLEFT, FromDIP(50));
m_sizer_body->Add( 0, 0, 0, wxTOP, FromDIP(20));
m_sizer_body->Add(m_sizer_model_name, 0, wxLEFT, FromDIP(50));
//m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(20));
//m_sizer_body->Add(m_sizer_license, 0, wxLEFT, FromDIP(50));
//init_license_list();
m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(20));
m_sizer_body->Add(m_sizer_license, 0, wxLEFT, FromDIP(50));
init_license_list();
SetSizer(m_sizer_body);
Layout();
@ -1144,52 +1103,35 @@ void AuxiliaryPanel::update_all_cover()
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_combo_license->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(DesignerPanel::on_select_license), NULL, this);
m_combo_license->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &DesignerPanel::on_select_license, this);
}
DesignerPanel::~DesignerPanel()
{
//m_combo_license->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(DesignerPanel::on_select_license), NULL, this);
}
void DesignerPanel::init_license_list()
{
/*
wxArrayString text_licese;
for (int i = 0; i < license_list.size(); i++) {
text_licese.Add(license_list[i]);
}
m_combo_license->Set(text_licese);
*/
}
void DesignerPanel::on_select_license(wxCommandEvent&evt)
{
int selected = evt.GetInt();
if (selected >= 0 && selected < license_list.size()) {
if (wxGetApp().plater()->model().model_info == nullptr) {
wxGetApp().plater()->model().model_info = std::make_shared<ModelInfo>();
}
if (wxGetApp().plater()->model().model_info != nullptr) {
wxGetApp().plater()->model().model_info->license = license_list[selected];
}
ensure_model_info()->license = license_list[selected];
}
}
bool DesignerPanel::Show(bool show)
{
if ( wxGetApp().plater()->model().design_info != nullptr) {
wxString text = wxString::FromUTF8(wxGetApp().plater()->model().design_info->Designer);
m_input_designer->GetTextCtrl()->SetValue(text);
}
if (wxGetApp().plater()->model().model_info != nullptr) {
wxString text = wxString::FromUTF8(wxGetApp().plater()->model().model_info->model_name);
m_imput_model_name->GetTextCtrl()->SetValue(text);
}
return wxPanel::Show(show);
}
{
if (show) update_info();
return wxPanel::Show(show);
}
void DesignerPanel::on_input_enter_designer(wxCommandEvent &evt)
{
@ -1200,9 +1142,7 @@ void DesignerPanel::on_input_enter_designer(wxCommandEvent &evt)
void DesignerPanel::on_input_enter_model(wxCommandEvent &evt)
{
auto text = evt.GetString();
if (wxGetApp().plater()->model().model_info) {
wxGetApp().plater()->model().model_info->model_name = std::string(text.ToUTF8().data());
}
ensure_model_info()->model_name = std::string(text.ToUTF8().data());
}
void DesignerPanel::update_info()
@ -1215,10 +1155,13 @@ void DesignerPanel::update_info()
}
if (wxGetApp().plater()->model().model_info != nullptr) {
wxString text = wxString::FromUTF8(wxGetApp().plater()->model().model_info->model_name);
m_imput_model_name->GetTextCtrl()->SetValue(text);
m_imput_model_name->GetTextCtrl()->SetValue(wxString::FromUTF8(wxGetApp().plater()->model().model_info->model_name));
if (!m_combo_license->SetStringSelection(wxString::FromUTF8(wxGetApp().plater()->model().model_info->license))) {
m_combo_license->SetSelection(0);
}
} else {
m_imput_model_name->GetTextCtrl()->SetValue(wxEmptyString);
m_imput_model_name->GetTextCtrl()->SetValue(wxEmptyString);
m_combo_license->SetSelection(0);
}
}
@ -1226,6 +1169,7 @@ void DesignerPanel::msw_rescale()
{
m_input_designer->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1));
m_imput_model_name->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1));
m_combo_license->SetSize(wxSize(FromDIP(450), -1));
}
}} // namespace Slic3r::GUI

View file

@ -181,7 +181,7 @@ public:
::TextInput* m_input_designer {nullptr};
::TextInput* m_imput_model_name {nullptr};
//wxComboBox* m_combo_license {nullptr};
ComboBox* m_combo_license {nullptr};
bool Show(bool show) override;
void init_license_list();
void on_input_enter_designer(wxCommandEvent &evt);
@ -232,7 +232,7 @@ public:
void create_folder(wxString name = wxEmptyString);
std::string replaceSpace(std::string s, std::string ts, std::string ns);
void on_import_file(wxCommandEvent &event);
void Reload(wxString aux_path);
void Reload(wxString aux_path, std::map<std::string, std::vector<json>> paths);
void update_all_panel();
void update_all_cover();
@ -242,6 +242,7 @@ wxDECLARE_EVENT(EVT_AUXILIARY_IMPORT, wxCommandEvent);
wxDECLARE_EVENT(EVT_AUXILIARY_UPDATE_COVER, wxCommandEvent);
wxDECLARE_EVENT(EVT_AUXILIARY_UPDATE_DELETE, wxCommandEvent);
wxDECLARE_EVENT(EVT_AUXILIARY_UPDATE_RENAME, wxCommandEvent);
wxDECLARE_EVENT(EVT_AUXILIARY_DONE, wxCommandEvent);
}} // namespace Slic3r::GUI
#endif

View file

@ -2656,7 +2656,7 @@ bool GUI_App::on_init_inner()
sidebar().obj_list()->init();
//sidebar().aux_list()->init_auxiliary();
//mainframe->m_auxiliary->init_auxiliary();
mainframe->m_project->init_auxiliary();
// update_mode(); // !!! do that later
SetTopWindow(mainframe);

View file

@ -62,6 +62,11 @@ ProjectPanel::ProjectPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos,
Bind(EVT_PROJECT_RELOAD, &ProjectPanel::on_reload, this);
m_auxiliary = new AuxiliaryPanel(this);
m_auxiliary->Hide();
main_sizer->Add(m_auxiliary, wxSizerFlags().Expand().Proportion(1));
Bind(EVT_AUXILIARY_DONE, [this](wxCommandEvent& e) { update_model_data();});
SetSizer(main_sizer);
Layout();
Fit();
@ -91,38 +96,39 @@ void ProjectPanel::on_reload(wxCommandEvent& evt)
std::string model_author;
std::string cover_file;
std::string description;
std::map<std::string, std::vector<json>> files;
std::string p_name;
std::string p_author;
std::string p_description;
std::string p_cover_file;
std::map<std::string, std::vector<json>> files;
Model model = wxGetApp().plater()->model();
license = model.model_info->license;
model_name = model.model_info->model_name;
cover_file = model.model_info->cover_file;
description = model.model_info->description;
update_type = model.model_info->origin;
auto model_info = model.model_info;
if (model_info != nullptr) {
license = model_info->license;
model_name = model_info->model_name;
cover_file = model_info->cover_file;
description = model_info->description;
update_type = model_info->origin;
try {
if (!model_info->copyright.empty()) {
json copy_right = json::parse(model_info->copyright);
try {
if (!model.model_info->copyright.empty()) {
json copy_right = json::parse(model.model_info->copyright);
if (copy_right.is_array()) {
for (auto it = copy_right.begin(); it != copy_right.end(); it++) {
if ((*it).contains("author")) {
model_author = (*it)["author"].get<std::string>();
if (copy_right.is_array()) {
for (auto it = copy_right.begin(); it != copy_right.end(); it++) {
if ((*it).contains("author")) {
model_author = (*it)["author"].get<std::string>();
}
}
}
}
} catch (...) {
;
}
}
catch (...) {
;
}
if (model_author.empty() && model.design_info != nullptr)
model_author = model.design_info->Designer;
@ -134,12 +140,44 @@ void ProjectPanel::on_reload(wxCommandEvent& evt)
p_author = model.profile_info->ProfileUserName;
}
//file info
// file info
std::string file_path = encode_path(wxGetApp().plater()->model().get_auxiliary_file_temp_path().c_str());
if (!file_path.empty()) {
files = Reload(file_path);
wxGetApp().CallAfter([this, file_path, files] { m_auxiliary->Reload(file_path, files); });
} else {
clear_model_info();
return;
}
else {
bool has_content = false;
for (const string& v : {
update_type,
license,
model_name,
model_author,
cover_file,
description,
p_name,
p_author,
p_description,
p_cover_file,
}) {
if (!v.empty()) {
has_content = true;
break;
}
}
if (!has_content) {
for (const auto & file : files) {
if (!file.second.empty()) {
has_content = true;
break;
}
}
}
if (!has_content) {
// Nothing to show, just return
clear_model_info();
return;
}
@ -180,6 +218,7 @@ void ProjectPanel::on_reload(wxCommandEvent& evt)
void ProjectPanel::msw_rescale()
{
m_auxiliary->msw_rescale();
}
void ProjectPanel::on_size(wxSizeEvent &event)
@ -215,6 +254,9 @@ void ProjectPanel::OnScriptMessage(wxWebViewEvent& evt)
else if (strCmd == "request_3mf_info") {
m_web_init_completed = true;
}
else if (strCmd == "edit_project_info") {
show_info_editor(true);
}
else if (strCmd == "debug_info") {
//wxString msg = j["msg"];
//OutputDebugString(wxString::Format("Model_Web: msg = %s \r\n", msg));
@ -227,14 +269,24 @@ void ProjectPanel::OnScriptMessage(wxWebViewEvent& evt)
}
}
void ProjectPanel::show_info_editor(bool show)
{
m_browser->Show(!show);
m_auxiliary->Show(show);
Layout();
}
void ProjectPanel::update_model_data()
{
Model model = wxGetApp().plater()->model();
show_info_editor(false);
clear_model_info();
m_auxiliary->init_auxiliary();
//basics info
if (model.model_info == nullptr)
return;
//if (model.model_info == nullptr)
// return;
auto event = wxCommandEvent(EVT_PROJECT_RELOAD);
event.SetEventObject(this);
@ -258,7 +310,6 @@ std::map<std::string, std::vector<json>> ProjectPanel::Reload(wxString aux_path)
{
std::vector<fs::path> dir_cache;
fs::directory_iterator iter_end;
wxString m_root_dir;
std::map<std::string, std::vector<json>> m_paths_list;
const static std::array<wxString, 5> s_default_folders = {
@ -276,24 +327,16 @@ std::map<std::string, std::vector<json>> ProjectPanel::Reload(wxString aux_path)
fs::path new_aux_path(aux_path.ToStdWstring());
try {
fs::remove_all(fs::path(m_root_dir.ToStdWstring()));
}
catch (...) {
BOOST_LOG_TRIVIAL(error) << "Failed removing the auxiliary directory" << m_root_dir.c_str();
}
m_root_dir = aux_path;
// Check new path. If not exist, create a new one.
if (!fs::exists(new_aux_path)) {
fs::create_directory(new_aux_path);
// Create default folders if they are not loaded
for (auto folder : s_default_folders) {
wxString folder_path = aux_path + "/" + folder;
if (fs::exists(folder_path.ToStdWstring())) continue;
fs::create_directory(folder_path.ToStdWstring());
}
return m_paths_list;
}
// Create default folders if they are not loaded
for (auto folder : s_default_folders) {
wxString folder_path = aux_path + "/" + folder;
if (fs::exists(folder_path.ToStdWstring())) continue;
fs::create_directory(folder_path.ToStdWstring());
}
// Load from new path
@ -321,6 +364,7 @@ std::map<std::string, std::vector<json>> ProjectPanel::Reload(wxString aux_path)
wxStat(file_name, &strucStat);
wxFileOffset filelen = strucStat.st_size;
pfile_obj["_filepath"] = file_path;
pfile_obj["filename"] = wxGetApp().url_encode(file_path_obj.filename().string().c_str());
pfile_obj["size"] = formatBytes((unsigned long)filelen);

View file

@ -32,6 +32,7 @@
#include "Event.hpp"
#include "libslic3r/ProjectTask.hpp"
#include "wxExtensions.hpp"
#include "Auxiliary.hpp"
#define AUFILE_GREY700 wxColour(107, 107, 107)
#define AUFILE_GREY500 wxColour(158, 158, 158)
@ -63,10 +64,13 @@ private:
bool m_reload_already = {false};
wxWebView* m_browser = {nullptr};
AuxiliaryPanel* m_auxiliary{nullptr};
wxString m_project_home_url;
wxString m_root_dir;
static inline int m_sequence_id = 8000;
void show_info_editor(bool show);
public:
ProjectPanel(wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
@ -81,6 +85,7 @@ public:
void msw_rescale();
void update_model_data();
void clear_model_info();
void init_auxiliary() { m_auxiliary->init_auxiliary(); }
bool Show(bool show);
void OnScriptMessage(wxWebViewEvent& evt);