diff --git a/resources/icons/add_text_modifier.svg b/resources/icons/add_text_modifier.svg
new file mode 100644
index 000000000..5172668ce
--- /dev/null
+++ b/resources/icons/add_text_modifier.svg
@@ -0,0 +1,11 @@
+
+
+
diff --git a/resources/icons/add_text_negative.svg b/resources/icons/add_text_negative.svg
new file mode 100644
index 000000000..09591f34f
--- /dev/null
+++ b/resources/icons/add_text_negative.svg
@@ -0,0 +1,13 @@
+
+
+
diff --git a/resources/icons/add_text_part.svg b/resources/icons/add_text_part.svg
new file mode 100644
index 000000000..9c0232873
--- /dev/null
+++ b/resources/icons/add_text_part.svg
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp
index c6bc64287..43306f8eb 100644
--- a/src/slic3r/GUI/GUI_Factories.cpp
+++ b/src/slic3r/GUI/GUI_Factories.cpp
@@ -165,6 +165,14 @@ const std::vector> MenuFactory::ADD_VOLUME_M
{L("Add support enforcer"), "support_enforcer"}, // ~ModelVolumeType::SUPPORT_ENFORCER
};
+// Note: id accords to type of the sub-object (adding volume), so sequence of the menu items is important
+const std::vector MenuFactory::TEXT_VOLUME_ICONS {
+// text_volume bitmap name
+ {"add_text_part" }, // ~ModelVolumeType::MODEL_PART
+ {"add_text_negative" }, // ~ModelVolumeType::NEGATIVE_VOLUME
+ {"add_text_modifier"}, // ~ModelVolumeType::PARAMETER_MODIFIER
+};
+
static Plater* plater()
{
return wxGetApp().plater();
@@ -440,6 +448,15 @@ std::vector MenuFactory::get_volume_bitmaps()
return volume_bmps;
}
+std::vector MenuFactory::get_text_volume_bitmaps()
+{
+ std::vector volume_bmps;
+ volume_bmps.reserve(TEXT_VOLUME_ICONS.size());
+ for (auto item : TEXT_VOLUME_ICONS)
+ volume_bmps.push_back(create_menu_bitmap(item));
+ return volume_bmps;
+}
+
void MenuFactory::append_menu_item_delete(wxMenu* menu)
{
append_menu_item(menu, wxID_ANY, _L("Delete") + "\tDel", _L("Remove the selected object"),
diff --git a/src/slic3r/GUI/GUI_Factories.hpp b/src/slic3r/GUI/GUI_Factories.hpp
index 32890bd1f..64f92af7f 100644
--- a/src/slic3r/GUI/GUI_Factories.hpp
+++ b/src/slic3r/GUI/GUI_Factories.hpp
@@ -34,7 +34,9 @@ class MenuFactory
{
public:
static const std::vector> ADD_VOLUME_MENU_ITEMS;
+ static const std::vector TEXT_VOLUME_ICONS;
static std::vector get_volume_bitmaps();
+ static std::vector get_text_volume_bitmaps();
MenuFactory();
~MenuFactory() = default;
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index 67b709d25..720915fa6 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -2032,6 +2032,7 @@ void ObjectList::split()
for (const ModelVolume* volume : model_object->volumes) {
const wxDataViewItem& vol_item = m_objects_model->AddVolumeChild(parent, from_u8(volume->name),
volume->type(),// is_modifier() ? ModelVolumeType::PARAMETER_MODIFIER : ModelVolumeType::MODEL_PART,
+ volume->text_configuration.has_value(),
get_warning_icon_name(volume->mesh().stats()),
volume->config.has("extruder") ? volume->config.extruder() : 0,
false);
@@ -2684,6 +2685,7 @@ void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed)
const wxDataViewItem& vol_item = m_objects_model->AddVolumeChild(item,
from_u8(volume->name),
volume->type(),
+ volume->text_configuration.has_value(),
get_warning_icon_name(volume->mesh().stats()),
volume->config.has("extruder") ? volume->config.extruder() : 0,
false);
@@ -4344,6 +4346,7 @@ wxDataViewItemArray ObjectList::reorder_volumes_and_get_selection(int obj_idx, s
for (const ModelVolume* volume : object->volumes) {
wxDataViewItem vol_item = m_objects_model->AddVolumeChild(object_item, from_u8(volume->name),
volume->type(),
+ volume->text_configuration.has_value(),
get_warning_icon_name(volume->mesh().stats()),
volume->config.has("extruder") ? volume->config.extruder() : 0,
false);
diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp
index ed4b477b8..d8206bec0 100644
--- a/src/slic3r/GUI/ObjectDataViewModel.cpp
+++ b/src/slic3r/GUI/ObjectDataViewModel.cpp
@@ -56,7 +56,7 @@ const std::map INFO_ITEMS{
ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent,
const wxString& sub_obj_name,
Slic3r::ModelVolumeType type,
- const wxBitmap& bmp,
+ const bool is_text_volume,
const wxString& extruder,
const int idx/* = -1*/,
const std::string& warning_icon_name /*= std::string*/) :
@@ -64,11 +64,11 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* pare
m_name(sub_obj_name),
m_type(itVolume),
m_volume_type(type),
+ m_is_text_volume(is_text_volume),
m_idx(idx),
m_extruder(type == Slic3r::ModelVolumeType::MODEL_PART || type == Slic3r::ModelVolumeType::PARAMETER_MODIFIER ? extruder : ""),
m_warning_icon_name(warning_icon_name)
{
- m_bmp = bmp;
set_action_and_extruder_icons();
init_container();
}
@@ -324,9 +324,10 @@ ObjectDataViewModel::ObjectDataViewModel()
{
m_bitmap_cache = new Slic3r::GUI::BitmapCache;
- m_volume_bmps = MenuFactory::get_volume_bitmaps();
- m_warning_bmp = create_scaled_bitmap(WarningIcon);
- m_warning_manifold_bmp = create_scaled_bitmap(WarningManifoldIcon);
+ m_volume_bmps = MenuFactory::get_volume_bitmaps();
+ m_text_volume_bmps = MenuFactory::get_text_volume_bitmaps();
+ m_warning_bmp = create_scaled_bitmap(WarningIcon);
+ m_warning_manifold_bmp = create_scaled_bitmap(WarningManifoldIcon);
for (auto item : INFO_ITEMS)
m_info_bmps[item.first] = create_scaled_bitmap(item.second.bmp_name);
@@ -366,6 +367,7 @@ wxDataViewItem ObjectDataViewModel::Add(const wxString &name,
wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent_item,
const wxString &name,
const Slic3r::ModelVolumeType volume_type,
+ const bool is_text_volume /*- false*/,
const std::string& warning_icon_name/* = std::string()*/,
const int extruder/* = 0*/,
const bool create_frst_child/* = true*/)
@@ -383,8 +385,8 @@ wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent
if (create_frst_child && root->m_volumes_cnt == 0)
{
const Slic3r::ModelVolumeType type = Slic3r::ModelVolumeType::MODEL_PART;
- const auto node = new ObjectDataViewModelNode(root, root->m_name, type, GetVolumeIcon(type, root->m_warning_icon_name), extruder_str, 0, root->m_warning_icon_name);
-
+ const auto node = new ObjectDataViewModelNode(root, root->m_name, type, root->is_text_volume(), extruder_str, 0, root->m_warning_icon_name);
+ SetVolumeBitmap(node);
insert_position < 0 ? root->Append(node) : root->Insert(node, insert_position);
// notify control
const wxDataViewItem child((void*)node);
@@ -394,7 +396,8 @@ wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent
if (insert_position >= 0) insert_position++;
}
- const auto node = new ObjectDataViewModelNode(root, name, volume_type, GetVolumeIcon(volume_type, warning_icon_name), extruder_str, root->m_volumes_cnt, warning_icon_name);
+ const auto node = new ObjectDataViewModelNode(root, name, volume_type, is_text_volume, extruder_str, root->m_volumes_cnt, warning_icon_name);
+ SetVolumeBitmap(node);
insert_position < 0 ? root->Append(node) : root->Insert(node, insert_position);
// if part with errors is added, but object wasn't marked, then mark it
@@ -1611,20 +1614,9 @@ void ObjectDataViewModel::UpdateSettingsDigest(const wxDataViewItem &item,
ItemChanged(item);
}
-void ObjectDataViewModel::SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType volume_type)
+void ObjectDataViewModel::SetVolumeBitmap(ObjectDataViewModelNode* node)
{
- if (!item.IsOk() || GetItemType(item) != itVolume)
- return;
-
- ObjectDataViewModelNode *node = static_cast(item.GetID());
- node->SetVolumeType(volume_type);
- node->SetBitmap(m_volume_bmps[int(volume_type)]);
- if (volume_type != Slic3r::ModelVolumeType::MODEL_PART && volume_type != Slic3r::ModelVolumeType::PARAMETER_MODIFIER)
- node->SetExtruder(""); // hide extruder
- else if (node->GetExtruder().IsEmpty())
- node->SetExtruder("default"); // show extruder ans set it to default
- node->UpdateExtruderAndColorIcon();
- ItemChanged(item);
+ node->SetBitmap(GetVolumeIcon(node, node->m_warning_icon_name));
}
ModelVolumeType ObjectDataViewModel::GetVolumeType(const wxDataViewItem& item)
@@ -1678,9 +1670,11 @@ wxDataViewItem ObjectDataViewModel::SetObjectPrintableState(
void ObjectDataViewModel::Rescale()
{
- m_volume_bmps = MenuFactory::get_volume_bitmaps();
- m_warning_bmp = create_scaled_bitmap(WarningIcon);
- m_warning_manifold_bmp = create_scaled_bitmap(WarningManifoldIcon);
+ m_volume_bmps = MenuFactory::get_volume_bitmaps();
+ m_text_volume_bmps = MenuFactory::get_text_volume_bitmaps();
+
+ m_warning_bmp = create_scaled_bitmap(WarningIcon);
+ m_warning_manifold_bmp = create_scaled_bitmap(WarningManifoldIcon);
wxDataViewItemArray all_items;
GetAllChildren(wxDataViewItem(0), all_items);
@@ -1699,7 +1693,7 @@ void ObjectDataViewModel::Rescale()
if (node->m_bmp.IsOk()) node->m_bmp = GetWarningBitmap(node->m_warning_icon_name);
break;
case itVolume:
- node->m_bmp = GetVolumeIcon(node->m_volume_type, node->m_warning_icon_name);
+ SetVolumeBitmap(node);
break;
case itLayerRoot:
node->m_bmp = create_scaled_bitmap(LayerRootIcon);
@@ -1713,12 +1707,13 @@ void ObjectDataViewModel::Rescale()
}
}
-wxBitmap ObjectDataViewModel::GetVolumeIcon(const Slic3r::ModelVolumeType vol_type, const std::string& warning_icon_name/* = std::string()*/)
+wxBitmap ObjectDataViewModel::GetVolumeIcon(const ObjectDataViewModelNode* node, const std::string& warning_icon_name)
{
+ const std::vector& bitmaps = node->is_text_volume() ? m_text_volume_bmps : m_volume_bmps;
if (warning_icon_name.empty())
- return m_volume_bmps[static_cast(vol_type)];
+ return bitmaps[node->volume_type()];
- std::string scaled_bitmap_name = warning_icon_name + std::to_string(static_cast(vol_type));
+ std::string scaled_bitmap_name = warning_icon_name + std::to_string(node->volume_type());
scaled_bitmap_name += "-em" + std::to_string(wxGetApp().em_unit()) + (wxGetApp().dark_mode() ? "-dm" : "-lm");
wxBitmap *bmp = m_bitmap_cache->find(scaled_bitmap_name);
@@ -1726,7 +1721,7 @@ wxBitmap ObjectDataViewModel::GetVolumeIcon(const Slic3r::ModelVolumeType vol_ty
std::vector bmps;
bmps.emplace_back(GetWarningBitmap(warning_icon_name));
- bmps.emplace_back(m_volume_bmps[static_cast(vol_type)]);
+ bmps.emplace_back(bitmaps[node->volume_type()]);
bmp = m_bitmap_cache->insert(scaled_bitmap_name, bmps);
}
@@ -1734,6 +1729,11 @@ wxBitmap ObjectDataViewModel::GetVolumeIcon(const Slic3r::ModelVolumeType vol_ty
return *bmp;
}
+wxBitmap ObjectDataViewModel::GetVolumeIcon(const ObjectDataViewModelNode* node)
+{
+ return GetVolumeIcon(node, node->m_warning_icon_name);
+}
+
void ObjectDataViewModel::AddWarningIcon(const wxDataViewItem& item, const std::string& warning_icon_name)
{
if (!item.IsOk())
@@ -1746,7 +1746,7 @@ void ObjectDataViewModel::AddWarningIcon(const wxDataViewItem& item, const std::
}
if (node->GetType() & itVolume) {
- node->SetWarningBitmap(GetVolumeIcon(node->GetVolumeType(), warning_icon_name), warning_icon_name);
+ node->SetWarningBitmap(GetVolumeIcon(node, warning_icon_name), warning_icon_name);
node->GetParent()->SetWarningBitmap(GetWarningBitmap(warning_icon_name), warning_icon_name);
return;
}
diff --git a/src/slic3r/GUI/ObjectDataViewModel.hpp b/src/slic3r/GUI/ObjectDataViewModel.hpp
index f8885b206..9fdcc81ce 100644
--- a/src/slic3r/GUI/ObjectDataViewModel.hpp
+++ b/src/slic3r/GUI/ObjectDataViewModel.hpp
@@ -82,6 +82,7 @@ class ObjectDataViewModelNode
std::string m_action_icon_name = "";
ModelVolumeType m_volume_type;
+ bool m_is_text_volume{ false };
InfoItemType m_info_item_type {InfoItemType::Undef};
public:
@@ -99,7 +100,7 @@ public:
ObjectDataViewModelNode(ObjectDataViewModelNode* parent,
const wxString& sub_obj_name,
Slic3r::ModelVolumeType type,
- const wxBitmap& bmp,
+ const bool is_text_volume,
const wxString& extruder,
const int idx = -1,
const std::string& warning_icon_name = std::string());
@@ -178,7 +179,6 @@ public:
}
bool SetValue(const wxVariant &variant, unsigned int col);
- void SetVolumeType(ModelVolumeType type) { m_volume_type = type; }
void SetBitmap(const wxBitmap &icon) { m_bmp = icon; }
void SetExtruder(const wxString &extruder) { m_extruder = extruder; }
void SetWarningBitmap(const wxBitmap& icon, const std::string& warning_icon_name) { m_bmp = icon; m_warning_icon_name = warning_icon_name; }
@@ -234,6 +234,7 @@ public:
void update_settings_digest_bitmaps();
bool update_settings_digest(const std::vector& categories);
int volume_type() const { return int(m_volume_type); }
+ bool is_text_volume() const { return m_is_text_volume; }
void msw_rescale();
#ifndef NDEBUG
@@ -258,6 +259,7 @@ class ObjectDataViewModel :public wxDataViewModel
{
std::vector m_objects;
std::vector m_volume_bmps;
+ std::vector m_text_volume_bmps;
std::map m_info_bmps;
wxBitmap m_empty_bmp;
wxBitmap m_warning_bmp;
@@ -275,6 +277,7 @@ public:
wxDataViewItem AddVolumeChild( const wxDataViewItem &parent_item,
const wxString &name,
const Slic3r::ModelVolumeType volume_type,
+ const bool is_text_volume = false,
const std::string& warning_icon_name = std::string(),
const int extruder = 0,
const bool create_frst_child = true);
@@ -374,7 +377,7 @@ public:
void UpdateObjectPrintable(wxDataViewItem parent_item);
void UpdateInstancesPrintable(wxDataViewItem parent_item);
- void SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type);
+ void SetVolumeBitmap(ObjectDataViewModelNode* node);
ModelVolumeType GetVolumeType(const wxDataViewItem &item);
wxDataViewItem SetPrintableState( PrintIndicator printable, int obj_idx,
int subobj_idx = -1,
@@ -385,8 +388,9 @@ public:
// Rescale bitmaps for existing Items
void Rescale();
- wxBitmap GetVolumeIcon(const Slic3r::ModelVolumeType vol_type,
- const std::string& warning_icon_name = std::string());
+ wxBitmap GetVolumeIcon(const ObjectDataViewModelNode* node,
+ const std::string& warning_icon_name);
+ wxBitmap GetVolumeIcon(const ObjectDataViewModelNode* node);
void AddWarningIcon(const wxDataViewItem& item, const std::string& warning_name);
void DeleteWarningIcon(const wxDataViewItem& item, const bool unmark_object = false);
void UpdateWarningIcon(const wxDataViewItem& item, const std::string& warning_name);