Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
35a8a5374c
8 changed files with 208 additions and 51 deletions
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "PrintExport.hpp"
|
#include "PrintExport.hpp"
|
||||||
|
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
//! macro used to mark string used at localization,
|
//! macro used to mark string used at localization,
|
||||||
//! return same string
|
//! return same string
|
||||||
#define L(s) Slic3r::I18N::translate(s)
|
#define L(s) Slic3r::I18N::translate(s)
|
||||||
|
@ -1864,14 +1866,92 @@ std::string Print::output_filename() const
|
||||||
{
|
{
|
||||||
// Set the placeholders for the data know first after the G-code export is finished.
|
// Set the placeholders for the data know first after the G-code export is finished.
|
||||||
// These values will be just propagated into the output file name.
|
// These values will be just propagated into the output file name.
|
||||||
|
DynamicConfig config = this->finished() ? this->print_statistics().config() : this->print_statistics().placeholders();
|
||||||
|
return this->PrintBase::output_filename(m_config.output_filename_format.value, "gcode", &config);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shorten the dhms time by removing the seconds, rounding the dhm to full minutes
|
||||||
|
// and removing spaces.
|
||||||
|
static std::string short_time(const std::string &time)
|
||||||
|
{
|
||||||
|
// Parse the dhms time format.
|
||||||
|
int days = 0;
|
||||||
|
int hours = 0;
|
||||||
|
int minutes = 0;
|
||||||
|
int seconds = 0;
|
||||||
|
if (time.find('d') != std::string::npos)
|
||||||
|
::sscanf(time.c_str(), "%dd %dh %dm %ds", &days, &hours, &minutes, &seconds);
|
||||||
|
else if (time.find('h') != std::string::npos)
|
||||||
|
::sscanf(time.c_str(), "%dh %dm %ds", &hours, &minutes, &seconds);
|
||||||
|
else if (time.find('m') != std::string::npos)
|
||||||
|
::sscanf(time.c_str(), "%dm %ds", &minutes, &seconds);
|
||||||
|
else if (time.find('s') != std::string::npos)
|
||||||
|
::sscanf(time.c_str(), "%ds", &seconds);
|
||||||
|
// Round to full minutes.
|
||||||
|
if (days + hours + minutes > 0 && seconds >= 30) {
|
||||||
|
if (++ minutes == 60) {
|
||||||
|
minutes = 0;
|
||||||
|
if (++ hours == 24) {
|
||||||
|
hours = 0;
|
||||||
|
++ days;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Format the dhm time.
|
||||||
|
char buffer[64];
|
||||||
|
if (days > 0)
|
||||||
|
::sprintf(buffer, "%dd%dh%dm", days, hours, minutes);
|
||||||
|
else if (hours > 0)
|
||||||
|
::sprintf(buffer, "%dh%dm", hours, minutes);
|
||||||
|
else if (minutes > 0)
|
||||||
|
::sprintf(buffer, "%dm", minutes);
|
||||||
|
else
|
||||||
|
::sprintf(buffer, "%ds", seconds);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicConfig PrintStatistics::config() const
|
||||||
|
{
|
||||||
|
DynamicConfig config;
|
||||||
|
std::string normal_print_time = short_time(this->estimated_normal_print_time);
|
||||||
|
std::string silent_print_time = short_time(this->estimated_silent_print_time);
|
||||||
|
config.set_key_value("print_time", new ConfigOptionString(normal_print_time));
|
||||||
|
config.set_key_value("normal_print_time", new ConfigOptionString(normal_print_time));
|
||||||
|
config.set_key_value("silent_print_time", new ConfigOptionString(silent_print_time));
|
||||||
|
config.set_key_value("used_filament", new ConfigOptionFloat (this->total_used_filament));
|
||||||
|
config.set_key_value("extruded_volume", new ConfigOptionFloat (this->total_extruded_volume));
|
||||||
|
config.set_key_value("total_cost", new ConfigOptionFloat (this->total_cost));
|
||||||
|
config.set_key_value("total_weight", new ConfigOptionFloat (this->total_weight));
|
||||||
|
config.set_key_value("total_wipe_tower_cost", new ConfigOptionFloat (this->total_wipe_tower_cost));
|
||||||
|
config.set_key_value("total_wipe_tower_filament", new ConfigOptionFloat (this->total_wipe_tower_filament));
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicConfig PrintStatistics::placeholders()
|
||||||
|
{
|
||||||
DynamicConfig config;
|
DynamicConfig config;
|
||||||
for (const std::string &key : {
|
for (const std::string &key : {
|
||||||
"print_time", "normal_print_time", "silent_print_time",
|
"print_time", "normal_print_time", "silent_print_time",
|
||||||
"used_filament", "extruded_volume", "total_cost", "total_weight",
|
"used_filament", "extruded_volume", "total_cost", "total_weight",
|
||||||
"total_wipe_tower_cost", "total_wipe_tower_filament"})
|
"total_wipe_tower_cost", "total_wipe_tower_filament"})
|
||||||
config.set_key_value(key, new ConfigOptionString(std::string("{") + key + "}"));
|
config.set_key_value(key, new ConfigOptionString(std::string("{") + key + "}"));
|
||||||
return this->PrintBase::output_filename(m_config.output_filename_format.value, "gcode", &config);
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PrintStatistics::finalize_output_path(const std::string &path_in) const
|
||||||
|
{
|
||||||
|
std::string final_path;
|
||||||
|
try {
|
||||||
|
boost::filesystem::path path(path_in);
|
||||||
|
DynamicConfig cfg = this->config();
|
||||||
|
PlaceholderParser pp;
|
||||||
|
std::string new_stem = pp.process(path.stem().string(), 0, &cfg);
|
||||||
|
final_path = (path.parent_path() / (new_stem + path.extension().string())).string();
|
||||||
|
} catch (const std::exception &ex) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "Failed to apply the print statistics to the export file name: " << ex.what();
|
||||||
|
final_path = path_in;
|
||||||
|
}
|
||||||
|
return final_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
|
|
@ -249,6 +249,13 @@ struct PrintStatistics
|
||||||
double total_wipe_tower_filament;
|
double total_wipe_tower_filament;
|
||||||
std::map<size_t, float> filament_stats;
|
std::map<size_t, float> filament_stats;
|
||||||
|
|
||||||
|
// Config with the filled in print statistics.
|
||||||
|
DynamicConfig config() const;
|
||||||
|
// Config with the statistics keys populated with placeholder strings.
|
||||||
|
static DynamicConfig placeholders();
|
||||||
|
// Replace the print statistics placeholders in the path.
|
||||||
|
std::string finalize_output_path(const std::string &path_in) const;
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
estimated_normal_print_time.clear();
|
estimated_normal_print_time.clear();
|
||||||
estimated_silent_print_time.clear();
|
estimated_silent_print_time.clear();
|
||||||
|
|
|
@ -82,32 +82,7 @@ void BackgroundSlicingProcess::process_fff()
|
||||||
if (! m_export_path.empty()) {
|
if (! m_export_path.empty()) {
|
||||||
//FIXME localize the messages
|
//FIXME localize the messages
|
||||||
// Perform the final post-processing of the export path by applying the print statistics over the file name.
|
// Perform the final post-processing of the export path by applying the print statistics over the file name.
|
||||||
std::string export_path;
|
std::string export_path = m_fff_print->print_statistics().finalize_output_path(m_export_path);
|
||||||
{
|
|
||||||
const PrintStatistics &stats = m_fff_print->print_statistics();
|
|
||||||
PlaceholderParser pp;
|
|
||||||
std::string normal_print_time = stats.estimated_normal_print_time;
|
|
||||||
std::string silent_print_time = stats.estimated_silent_print_time;
|
|
||||||
normal_print_time.erase(std::remove_if(normal_print_time.begin(), normal_print_time.end(), isspace), normal_print_time.end());
|
|
||||||
silent_print_time.erase(std::remove_if(silent_print_time.begin(), silent_print_time.end(), isspace), silent_print_time.end());
|
|
||||||
pp.set("print_time", new ConfigOptionString(normal_print_time));
|
|
||||||
pp.set("normal_print_time", new ConfigOptionString(normal_print_time));
|
|
||||||
pp.set("silent_print_time", new ConfigOptionString(silent_print_time));
|
|
||||||
pp.set("used_filament", new ConfigOptionFloat (stats.total_used_filament));
|
|
||||||
pp.set("extruded_volume", new ConfigOptionFloat (stats.total_extruded_volume));
|
|
||||||
pp.set("total_cost", new ConfigOptionFloat (stats.total_cost));
|
|
||||||
pp.set("total_weight", new ConfigOptionFloat (stats.total_weight));
|
|
||||||
pp.set("total_wipe_tower_cost", new ConfigOptionFloat (stats.total_wipe_tower_cost));
|
|
||||||
pp.set("total_wipe_tower_filament", new ConfigOptionFloat (stats.total_wipe_tower_filament));
|
|
||||||
boost::filesystem::path path(m_export_path);
|
|
||||||
try {
|
|
||||||
std::string new_stem = pp.process(path.stem().string(), 0);
|
|
||||||
export_path = (path.parent_path() / (new_stem + path.extension().string())).string();
|
|
||||||
} catch (const std::exception &ex) {
|
|
||||||
BOOST_LOG_TRIVIAL(error) << "Failed to apply the print statistics to the export file name: " << ex.what();
|
|
||||||
export_path = m_export_path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (copy_file(m_temp_output_path, export_path) != 0)
|
if (copy_file(m_temp_output_path, export_path) != 0)
|
||||||
throw std::runtime_error("Copying of the temporary G-code to the output G-code failed");
|
throw std::runtime_error("Copying of the temporary G-code to the output G-code failed");
|
||||||
m_print->set_status(95, "Running post-processing scripts");
|
m_print->set_status(95, "Running post-processing scripts");
|
||||||
|
|
|
@ -4094,7 +4094,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||||
|
|
||||||
m_reload_delayed = ! m_canvas->IsShown() && ! refresh_immediately && ! force_full_scene_refresh;
|
m_reload_delayed = ! m_canvas->IsShown() && ! refresh_immediately && ! force_full_scene_refresh;
|
||||||
|
|
||||||
PrinterTechnology printer_technology = m_process->current_printer_technology();
|
PrinterTechnology printer_technology = m_process->current_printer_technology();
|
||||||
|
int volume_idx_wipe_tower_old = -1;
|
||||||
|
|
||||||
if (m_regenerate_volumes)
|
if (m_regenerate_volumes)
|
||||||
{
|
{
|
||||||
|
@ -4152,6 +4153,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||||
}
|
}
|
||||||
if (mvs == nullptr || force_full_scene_refresh) {
|
if (mvs == nullptr || force_full_scene_refresh) {
|
||||||
// This GLVolume will be released.
|
// This GLVolume will be released.
|
||||||
|
if (volume->is_wipe_tower) {
|
||||||
|
// There is only one wipe tower.
|
||||||
|
assert(volume_idx_wipe_tower_old == -1);
|
||||||
|
volume_idx_wipe_tower_old = (int)volume_id;
|
||||||
|
}
|
||||||
volume->release_geometry();
|
volume->release_geometry();
|
||||||
if (! m_reload_delayed)
|
if (! m_reload_delayed)
|
||||||
delete volume;
|
delete volume;
|
||||||
|
@ -4319,8 +4325,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||||
float depth = print->get_wipe_tower_depth();
|
float depth = print->get_wipe_tower_depth();
|
||||||
if (!print->is_step_done(psWipeTower))
|
if (!print->is_step_done(psWipeTower))
|
||||||
depth = (900.f/w) * (float)(extruders_count - 1) ;
|
depth = (900.f/w) * (float)(extruders_count - 1) ;
|
||||||
m_volumes.load_wipe_tower_preview(1000, x, y, w, depth, (float)height, a, m_use_VBOs && m_initialized, !print->is_step_done(psWipeTower),
|
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
|
||||||
print->config().nozzle_diameter.values[0] * 1.25f * 4.5f);
|
1000, x, y, w, depth, (float)height, a, m_use_VBOs && m_initialized, !print->is_step_done(psWipeTower),
|
||||||
|
print->config().nozzle_diameter.values[0] * 1.25f * 4.5f);
|
||||||
|
if (volume_idx_wipe_tower_old != -1)
|
||||||
|
map_glvolume_old_to_new[volume_idx_wipe_tower_old] = volume_idx_wipe_tower_new;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,8 @@ ObjectList::ObjectList(wxWindow* parent) :
|
||||||
Bind(wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE, &ObjectList::OnDropPossible, this);
|
Bind(wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE, &ObjectList::OnDropPossible, this);
|
||||||
Bind(wxEVT_DATAVIEW_ITEM_DROP, &ObjectList::OnDrop, this);
|
Bind(wxEVT_DATAVIEW_ITEM_DROP, &ObjectList::OnDrop, this);
|
||||||
|
|
||||||
|
Bind(wxEVT_DATAVIEW_ITEM_EDITING_DONE, &ObjectList::OnEditingDone, this);
|
||||||
|
|
||||||
Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, &ObjectList::ItemValueChanged, this);
|
Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, &ObjectList::ItemValueChanged, this);
|
||||||
|
|
||||||
Bind(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, [this](wxCommandEvent& e) { last_volume_is_deleted(e.GetInt()); });
|
Bind(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, [this](wxCommandEvent& e) { last_volume_is_deleted(e.GetInt()); });
|
||||||
|
@ -290,6 +292,21 @@ void ObjectList::update_extruder_in_config(const wxDataViewItem& item)
|
||||||
wxGetApp().plater()->update();
|
wxGetApp().plater()->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectList::update_name_in_model(const wxDataViewItem& item)
|
||||||
|
{
|
||||||
|
const int obj_idx = m_objects_model->GetObjectIdByItem(item);
|
||||||
|
if (obj_idx < 0) return;
|
||||||
|
|
||||||
|
if (m_objects_model->GetParent(item) == wxDataViewItem(0)) {
|
||||||
|
(*m_objects)[obj_idx]->name = m_objects_model->GetName(item).ToStdString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int volume_id = m_objects_model->GetVolumeIdByItem(item);
|
||||||
|
if (volume_id < 0) return;
|
||||||
|
(*m_objects)[obj_idx]->volumes[volume_id]->name = m_objects_model->GetName(item).ToStdString();
|
||||||
|
}
|
||||||
|
|
||||||
void ObjectList::init_icons()
|
void ObjectList::init_icons()
|
||||||
{
|
{
|
||||||
m_bmp_modifiermesh = wxBitmap(from_u8(var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG);
|
m_bmp_modifiermesh = wxBitmap(from_u8(var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG);
|
||||||
|
@ -337,9 +354,7 @@ void ObjectList::selection_changed()
|
||||||
|
|
||||||
void ObjectList::OnChar(wxKeyEvent& event)
|
void ObjectList::OnChar(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
// printf("KeyDown event\n");
|
|
||||||
if (event.GetKeyCode() == WXK_BACK){
|
if (event.GetKeyCode() == WXK_BACK){
|
||||||
printf("WXK_BACK\n");
|
|
||||||
remove();
|
remove();
|
||||||
}
|
}
|
||||||
else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_SHIFT))
|
else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_SHIFT))
|
||||||
|
@ -370,15 +385,14 @@ void ObjectList::OnContextMenu(wxDataViewEvent&)
|
||||||
|
|
||||||
if (title == " ")
|
if (title == " ")
|
||||||
show_context_menu();
|
show_context_menu();
|
||||||
|
else if (title == _("Name") && pt.x >15 &&
|
||||||
else if (title == _("Name") && pt.x >15 &&
|
m_objects_model->GetBitmap(item).GetRefData() == m_bmp_manifold_warning.GetRefData())
|
||||||
m_objects_model->GetBitmap(item).GetRefData() == m_bmp_manifold_warning.GetRefData())
|
{
|
||||||
{
|
if (is_windows10()) {
|
||||||
if (is_windows10()) {
|
const auto obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item));
|
||||||
const auto obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item));
|
wxGetApp().plater()->fix_through_netfabb(obj_idx);
|
||||||
wxGetApp().plater()->fix_through_netfabb(obj_idx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#ifndef __WXMSW__
|
#ifndef __WXMSW__
|
||||||
GetMainWindow()->SetToolTip(""); // hide tooltip
|
GetMainWindow()->SetToolTip(""); // hide tooltip
|
||||||
#endif //__WXMSW__
|
#endif //__WXMSW__
|
||||||
|
@ -455,10 +469,10 @@ void ObjectList::OnDropPossible(wxDataViewEvent &event)
|
||||||
wxDataViewItem item(event.GetItem());
|
wxDataViewItem item(event.GetItem());
|
||||||
|
|
||||||
// only allow drags for item or background, not containers
|
// only allow drags for item or background, not containers
|
||||||
if (item.IsOk() &&
|
if (!item.IsOk() ||
|
||||||
(m_objects_model->GetParent(item) == wxDataViewItem(0) ||
|
m_objects_model->GetParent(item) == wxDataViewItem(0) ||
|
||||||
m_objects_model->GetItemType(item) != itVolume ||
|
m_objects_model->GetItemType(item) != itVolume ||
|
||||||
m_dragged_data.obj_idx() != m_objects_model->GetObjectIdByItem(item)))
|
m_dragged_data.obj_idx() != m_objects_model->GetObjectIdByItem(item))
|
||||||
event.Veto();
|
event.Veto();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,9 +480,9 @@ void ObjectList::OnDrop(wxDataViewEvent &event)
|
||||||
{
|
{
|
||||||
wxDataViewItem item(event.GetItem());
|
wxDataViewItem item(event.GetItem());
|
||||||
|
|
||||||
if (item.IsOk() && ( m_objects_model->GetParent(item) == wxDataViewItem(0) ||
|
if (!item.IsOk() || m_objects_model->GetParent(item) == wxDataViewItem(0) ||
|
||||||
m_objects_model->GetItemType(item) != itVolume) ||
|
m_objects_model->GetItemType(item) != itVolume ||
|
||||||
m_dragged_data.obj_idx() != m_objects_model->GetObjectIdByItem(item)) {
|
m_dragged_data.obj_idx() != m_objects_model->GetObjectIdByItem(item)) {
|
||||||
event.Veto();
|
event.Veto();
|
||||||
m_dragged_data.clear();
|
m_dragged_data.clear();
|
||||||
return;
|
return;
|
||||||
|
@ -1667,7 +1681,22 @@ void ObjectList::update_settings_items()
|
||||||
|
|
||||||
void ObjectList::ItemValueChanged(wxDataViewEvent &event)
|
void ObjectList::ItemValueChanged(wxDataViewEvent &event)
|
||||||
{
|
{
|
||||||
update_extruder_in_config(event.GetItem());
|
if (event.GetColumn() == 0)
|
||||||
|
update_name_in_model(event.GetItem());
|
||||||
|
else if (event.GetColumn() == 1)
|
||||||
|
update_extruder_in_config(event.GetItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectList::OnEditingDone(wxDataViewEvent &event)
|
||||||
|
{
|
||||||
|
if (event.GetColumn() != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto renderer = dynamic_cast<PrusaBitmapTextRenderer*>(GetColumn(0)->GetRenderer());
|
||||||
|
|
||||||
|
if (renderer->WasCanceled())
|
||||||
|
show_error(this, _(L("The supplied name is not valid;")) + "\n" +
|
||||||
|
_(L("the following characters are not allowed:")) + " <>:/\\|?*\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace GUI
|
} //namespace GUI
|
||||||
|
|
|
@ -128,6 +128,8 @@ public:
|
||||||
void set_extruder_column_hidden(const bool hide) const;
|
void set_extruder_column_hidden(const bool hide) const;
|
||||||
// update extruder in current config
|
// update extruder in current config
|
||||||
void update_extruder_in_config(const wxDataViewItem& item);
|
void update_extruder_in_config(const wxDataViewItem& item);
|
||||||
|
// update changed name in the object model
|
||||||
|
void update_name_in_model(const wxDataViewItem& item);
|
||||||
void update_extruder_values_for_items(const int max_extruder);
|
void update_extruder_values_for_items(const int max_extruder);
|
||||||
|
|
||||||
void init_icons();
|
void init_icons();
|
||||||
|
@ -227,6 +229,7 @@ private:
|
||||||
void OnDrop(wxDataViewEvent &event);
|
void OnDrop(wxDataViewEvent &event);
|
||||||
|
|
||||||
void ItemValueChanged(wxDataViewEvent &event);
|
void ItemValueChanged(wxDataViewEvent &event);
|
||||||
|
void OnEditingDone(wxDataViewEvent &event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1281,6 +1281,52 @@ wxSize PrusaBitmapTextRenderer::GetSize() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxWindow* PrusaBitmapTextRenderer::CreateEditorCtrl(wxWindow* parent, wxRect labelRect, const wxVariant& value)
|
||||||
|
{
|
||||||
|
wxDataViewCtrl* const dv_ctrl = GetOwner()->GetOwner();
|
||||||
|
PrusaObjectDataViewModel* const model = dynamic_cast<PrusaObjectDataViewModel*>(dv_ctrl->GetModel());
|
||||||
|
|
||||||
|
if ( !(model->GetItemType(dv_ctrl->GetSelection()) & (itVolume | itObject)) )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
PrusaDataViewBitmapText data;
|
||||||
|
data << value;
|
||||||
|
m_bmp_from_editing_item = data.GetBitmap();
|
||||||
|
m_was_unusable_symbol = false;
|
||||||
|
|
||||||
|
wxPoint position = labelRect.GetPosition();
|
||||||
|
if (m_bmp_from_editing_item.IsOk()) {
|
||||||
|
const int bmp_width = m_bmp_from_editing_item.GetWidth();
|
||||||
|
position.x += bmp_width;
|
||||||
|
labelRect.SetWidth(labelRect.GetWidth() - bmp_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxTextCtrl* text_editor = new wxTextCtrl(parent, wxID_ANY, data.GetText(),
|
||||||
|
position, labelRect.GetSize(), wxTE_PROCESS_ENTER);
|
||||||
|
text_editor->SetInsertionPointEnd();
|
||||||
|
|
||||||
|
return text_editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrusaBitmapTextRenderer::GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant& value)
|
||||||
|
{
|
||||||
|
wxTextCtrl* text_editor = wxDynamicCast(ctrl, wxTextCtrl);
|
||||||
|
if (!text_editor || text_editor->GetValue().IsEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string chosen_name = Slic3r::normalize_utf8_nfc(text_editor->GetValue().ToUTF8());
|
||||||
|
const char* unusable_symbols = "<>:/\\|?*\"";
|
||||||
|
for (size_t i = 0; i < std::strlen(unusable_symbols); i++) {
|
||||||
|
if (chosen_name.find_first_of(unusable_symbols[i]) != std::string::npos) {
|
||||||
|
m_was_unusable_symbol = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
value << PrusaDataViewBitmapText(text_editor->GetValue(), m_bmp_from_editing_item);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// PrusaDoubleSlider
|
// PrusaDoubleSlider
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -522,7 +522,7 @@ public:
|
||||||
class PrusaBitmapTextRenderer : public wxDataViewCustomRenderer
|
class PrusaBitmapTextRenderer : public wxDataViewCustomRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PrusaBitmapTextRenderer( wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT,
|
PrusaBitmapTextRenderer( wxDataViewCellMode mode = wxDATAVIEW_CELL_EDITABLE,
|
||||||
int align = wxDVR_DEFAULT_ALIGNMENT):
|
int align = wxDVR_DEFAULT_ALIGNMENT):
|
||||||
wxDataViewCustomRenderer(wxT("PrusaDataViewBitmapText"), mode, align) {}
|
wxDataViewCustomRenderer(wxT("PrusaDataViewBitmapText"), mode, align) {}
|
||||||
|
|
||||||
|
@ -532,10 +532,18 @@ public:
|
||||||
virtual bool Render(wxRect cell, wxDC *dc, int state);
|
virtual bool Render(wxRect cell, wxDC *dc, int state);
|
||||||
virtual wxSize GetSize() const;
|
virtual wxSize GetSize() const;
|
||||||
|
|
||||||
virtual bool HasEditorCtrl() const { return false; }
|
bool HasEditorCtrl() const override { return true; }
|
||||||
|
wxWindow* CreateEditorCtrl(wxWindow* parent,
|
||||||
|
wxRect labelRect,
|
||||||
|
const wxVariant& value) override;
|
||||||
|
bool GetValueFromEditorCtrl( wxWindow* ctrl,
|
||||||
|
wxVariant& value) override;
|
||||||
|
bool WasCanceled() const { return m_was_unusable_symbol; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PrusaDataViewBitmapText m_value;
|
PrusaDataViewBitmapText m_value;
|
||||||
|
wxBitmap m_bmp_from_editing_item;
|
||||||
|
bool m_was_unusable_symbol;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue