mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-12-02 07:11:05 -07:00
Merge branch 'main' into dev/gizmo
This commit is contained in:
commit
f6e4c48fe7
248 changed files with 7277 additions and 7612 deletions
|
|
@ -91,8 +91,26 @@ void CBaseException::ShowLoadModules()
|
|||
|
||||
void CBaseException::ShowCallstack(HANDLE hThread, const CONTEXT* context)
|
||||
{
|
||||
OutputString(_T("Show CallStack:\r\n"));
|
||||
LPSTACKINFO phead = StackWalker(hThread, context);
|
||||
OutputString(_T("Show CallStack:\n"));
|
||||
LPSTACKINFO phead = StackWalker(hThread, context);
|
||||
|
||||
// Show RVA of each call stack, so we can locate the symbol using pdb file
|
||||
// To show the symbol, load the <szFaultingModule> in WinDBG with pdb file, then type the following commands:
|
||||
// > lm which gives you the start address of each module, as well as module names
|
||||
// > !dh <module name> list all module headers. Find the <virtual address> of the section given by
|
||||
// the <section> output in the crash log
|
||||
// > ln <module start address> + <section virtual address> + <offset> reveals the debug symbol
|
||||
OutputString(_T("\nLogical Address:\n"));
|
||||
TCHAR szFaultingModule[MAX_PATH];
|
||||
DWORD section, offset;
|
||||
for (LPSTACKINFO ps = phead; ps != nullptr; ps = ps->pNext) {
|
||||
if (GetLogicalAddress((PVOID) ps->szFncAddr, szFaultingModule, sizeof(szFaultingModule), section, offset)) {
|
||||
OutputString(_T("0x%X 0x%X:0x%X %s\n"), ps->szFncAddr, section, offset, szFaultingModule);
|
||||
} else {
|
||||
OutputString(_T("0x%X Unknown\n"), ps->szFncAddr);
|
||||
}
|
||||
}
|
||||
|
||||
FreeStackInformations(phead);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -491,7 +491,7 @@ LPSTACKINFO CStackWalker::StackWalker(HANDLE hThread, const CONTEXT* context)
|
|||
}else
|
||||
{
|
||||
//调用错误一般是487(地址无效或者没有访问的权限、在符号表中未找到指定地址的相关信息)
|
||||
this->OutputString(_T("Call SymGetSymFromAddr64 ,Address %08x Error:%08x\r\n"), sf.AddrPC.Offset, GetLastError());
|
||||
//this->OutputString(_T("Call SymGetSymFromAddr64 ,Address %08x Error:%08x\n"), sf.AddrPC.Offset, GetLastError());
|
||||
|
||||
StringCchCopy(pCallStack->undFullName, STACKWALK_MAX_NAMELEN, textconv_helper::A2T_("Unknown"));
|
||||
}
|
||||
|
|
@ -502,14 +502,14 @@ LPSTACKINFO CStackWalker::StackWalker(HANDLE hThread, const CONTEXT* context)
|
|||
pCallStack->uFileNum = pLine->LineNumber;
|
||||
}else
|
||||
{
|
||||
this->OutputString(_T("Call SymGetLineFromAddr64 ,Address %08x Error:%08x\r\n"), sf.AddrPC.Offset, GetLastError());
|
||||
//this->OutputString(_T("Call SymGetLineFromAddr64 ,Address %08x Error:%08x\n"), sf.AddrPC.Offset, GetLastError());
|
||||
|
||||
StringCchCopy(pCallStack->szFileName, MAX_PATH, textconv_helper::A2T_("Unknown file"));
|
||||
pCallStack->uFileNum = -1;
|
||||
}
|
||||
|
||||
//这里为了将获取函数信息失败的情况与正常的情况一起输出,防止用户在查看时出现误解
|
||||
this->OutputString(_T("%08llx:%s [%s][%ld]\r\n"), pCallStack->szFncAddr, pCallStack->undFullName, pCallStack->szFileName, pCallStack->uFileNum);
|
||||
this->OutputString(_T("%08llx:%s [%s][%ld]\n"), pCallStack->szFncAddr, pCallStack->undFullName, pCallStack->szFileName, pCallStack->uFileNum);
|
||||
if (NULL == pHead)
|
||||
{
|
||||
pHead = pCallStack;
|
||||
|
|
|
|||
|
|
@ -2578,6 +2578,7 @@ this->placeholder_parser().set("z_offset", new ConfigOptionFloat(m_config.z_offs
|
|||
m_writer.extruders(),
|
||||
// Modifies
|
||||
print.m_print_statistics));
|
||||
print.m_print_statistics.initial_tool = initial_extruder_id;
|
||||
if (!is_bbl_printers) {
|
||||
file.write_format("; total filament used [g] = %.2lf\n",
|
||||
print.m_print_statistics.total_weight);
|
||||
|
|
@ -5448,8 +5449,12 @@ std::string GCode::set_extruder(unsigned int extruder_id, double print_z)
|
|||
old_retract_length = m_config.retraction_length.get_at(previous_extruder_id);
|
||||
old_retract_length_toolchange = m_config.retract_length_toolchange.get_at(previous_extruder_id);
|
||||
old_filament_temp = this->on_first_layer()? m_config.nozzle_temperature_initial_layer.get_at(previous_extruder_id) : m_config.nozzle_temperature.get_at(previous_extruder_id);
|
||||
wipe_volume = flush_matrix[previous_extruder_id * number_of_extruders + extruder_id];
|
||||
wipe_volume *= m_config.flush_multiplier;
|
||||
if (m_config.purge_in_prime_tower) {
|
||||
wipe_volume = flush_matrix[previous_extruder_id * number_of_extruders + extruder_id];
|
||||
wipe_volume *= m_config.flush_multiplier;
|
||||
} else {
|
||||
wipe_volume = m_config.prime_volume;
|
||||
}
|
||||
old_filament_e_feedrate = (int)(60.0 * m_config.filament_max_volumetric_speed.get_at(previous_extruder_id) / filament_area);
|
||||
old_filament_e_feedrate = old_filament_e_feedrate == 0 ? 100 : old_filament_e_feedrate;
|
||||
//BBS: must clean m_start_gcode_filament
|
||||
|
|
|
|||
|
|
@ -57,17 +57,20 @@ inline void export_thumbnails_to_file(ThumbnailsGeneratorCallback &thumbnail_cb,
|
|||
std::string encoded;
|
||||
encoded.resize(boost::beast::detail::base64::encoded_size(compressed->size));
|
||||
encoded.resize(boost::beast::detail::base64::encode((void *) encoded.data(), (const void *) compressed->data,
|
||||
compressed->size));
|
||||
output((boost::format("; thumbnail begin %dx%d %d\n") % data.width % data.height % encoded.size()).str().c_str());
|
||||
compressed->size));
|
||||
output((boost::format("\n;\n; %s begin %dx%d %d\n") % compressed->tag() % data.width % data.height % encoded.size())
|
||||
.str()
|
||||
.c_str());
|
||||
while (encoded.size() > max_row_length) {
|
||||
output((boost::format("; %s\n") % encoded.substr(0, max_row_length)).str().c_str());
|
||||
encoded = encoded.substr(max_row_length);
|
||||
}
|
||||
|
||||
// Orca write remaining ecoded data
|
||||
if (encoded.size() > 0)
|
||||
output((boost::format("; %s\n") % encoded).str().c_str());
|
||||
|
||||
output("; thumbnail end\n");
|
||||
output((boost::format("; %s end\n") % compressed->tag()).str().c_str());
|
||||
}
|
||||
throw_if_canceled();
|
||||
}
|
||||
|
|
@ -81,4 +84,4 @@ inline void export_thumbnails_to_file(ThumbnailsGeneratorCallback &thumbnail_cb,
|
|||
|
||||
} // namespace Slic3r::GCodeThumbnails
|
||||
|
||||
#endif // slic3r_GCodeThumbnails_hpp_
|
||||
#endif // slic3r_GCodeThumbnails_hpp_
|
||||
|
|
|
|||
|
|
@ -738,8 +738,16 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume()
|
|||
const unsigned int number_of_extruders = (unsigned int) (sqrt(flush_matrix.size()) + EPSILON);
|
||||
// Extract purging volumes for each extruder pair:
|
||||
std::vector<std::vector<float>> wipe_volumes;
|
||||
for (unsigned int i = 0; i < number_of_extruders; ++i)
|
||||
wipe_volumes.push_back(std::vector<float>(flush_matrix.begin() + i * number_of_extruders, flush_matrix.begin() + (i + 1) * number_of_extruders));
|
||||
if (m_print_config_ptr->purge_in_prime_tower) {
|
||||
for (unsigned int i = 0; i < number_of_extruders; ++i)
|
||||
wipe_volumes.push_back(
|
||||
std::vector<float>(flush_matrix.begin() + i * number_of_extruders, flush_matrix.begin() + (i + 1) * number_of_extruders));
|
||||
} else {
|
||||
// populate wipe_volumes with prime_volume
|
||||
for (unsigned int i = 0; i < number_of_extruders; ++i) {
|
||||
wipe_volumes.push_back(std::vector<float>(number_of_extruders, m_print_config_ptr->prime_volume));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int current_extruder_id = -1;
|
||||
for (int i = 0; i < m_layer_tools.size(); ++i) {
|
||||
|
|
|
|||
|
|
@ -1021,7 +1021,6 @@ void WipeTower2::toolchange_Change(
|
|||
|
||||
// This is where we want to place the custom gcodes. We will use placeholders for this.
|
||||
// These will be substituted by the actual gcodes when the gcode is generated.
|
||||
writer.append("[filament_end_gcode]\n");
|
||||
writer.append("[change_filament_gcode]\n");
|
||||
|
||||
// Travel to where we assume we are. Custom toolchange or some special T code handling (parking extruder etc)
|
||||
|
|
@ -1093,7 +1092,8 @@ void WipeTower2::toolchange_Wipe(
|
|||
float dy = (is_first_layer() ? 1.f : m_extra_spacing) * m_perimeter_width; // Don't use the extra spacing for the first layer.
|
||||
// All the calculations in all other places take the spacing into account for all the layers.
|
||||
|
||||
const float target_speed = is_first_layer() ? m_first_layer_speed * 60.f : m_infill_speed * 60.f;
|
||||
// If spare layers are excluded->if 1 or less toolchange has been done, it must be sill the first layer, too.So slow down.
|
||||
const float target_speed = is_first_layer() || (m_num_tool_changes <= 1 && m_no_sparse_layers) ? m_first_layer_speed * 60.f : std::min(5400.f, m_infill_speed * 60.f);
|
||||
float wipe_speed = 0.33f * target_speed;
|
||||
|
||||
// if there is less than 2.5*m_perimeter_width to the edge, advance straightaway (there is likely a blob anyway)
|
||||
|
|
@ -1161,9 +1161,10 @@ WipeTower::ToolChangeResult WipeTower2::finish_layer()
|
|||
|
||||
|
||||
// Slow down on the 1st layer.
|
||||
bool first_layer = is_first_layer();
|
||||
float feedrate = first_layer ? m_first_layer_speed * 60.f : m_infill_speed * 60.f;
|
||||
float current_depth = m_layer_info->depth - m_layer_info->toolchanges_depth();
|
||||
// If spare layers are excluded -> if 1 or less toolchange has been done, it must be still the first layer, too. So slow down.
|
||||
bool first_layer = is_first_layer() || (m_num_tool_changes <= 1 && m_no_sparse_layers);
|
||||
float feedrate = first_layer ? m_first_layer_speed * 60.f : std::min(5400.f, m_infill_speed * 60.f);
|
||||
float current_depth = m_layer_info->depth - m_layer_info->toolchanges_depth();
|
||||
WipeTower::box_coordinates fill_box(Vec2f(m_perimeter_width, m_layer_info->depth-(current_depth-m_perimeter_width)),
|
||||
m_wipe_tower_width - 2 * m_perimeter_width, current_depth-m_perimeter_width);
|
||||
|
||||
|
|
|
|||
|
|
@ -899,7 +899,7 @@ void PerimeterGenerator::split_top_surfaces(const ExPolygons &orig_polygons, ExP
|
|||
offset_top_surface = 0;
|
||||
// don't takes into account too thin areas
|
||||
// skip if the exposed area is smaller than "min_width_top_surface"
|
||||
double min_width_top_surface = std::max(double(ext_perimeter_spacing / 2 + 10), config->min_width_top_surface.get_abs_value(perimeter_width));
|
||||
double min_width_top_surface = std::max(double(ext_perimeter_spacing / 2 + 10), scale_(config->min_width_top_surface.get_abs_value(unscale_(perimeter_width))));
|
||||
|
||||
Polygons grown_upper_slices = offset(*this->upper_slices, min_width_top_surface);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
///|/
|
||||
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#include "Config.hpp"
|
||||
#include "Exception.hpp"
|
||||
#include "Print.hpp"
|
||||
#include "BoundingBox.hpp"
|
||||
|
|
@ -2463,7 +2464,7 @@ void Print::_make_wipe_tower()
|
|||
}
|
||||
this->throw_if_canceled();
|
||||
|
||||
if (!m_config.purge_in_prime_tower) {
|
||||
if (is_BBL_printer()) {
|
||||
// in BBL machine, wipe tower is only use to prime extruder. So just use a global wipe volume.
|
||||
WipeTower wipe_tower(m_config, m_plate_index, m_origin, m_config.prime_volume, m_wipe_tower_data.tool_ordering.first_extruder(),
|
||||
m_wipe_tower_data.tool_ordering.empty() ? 0.f : m_wipe_tower_data.tool_ordering.back().print_z);
|
||||
|
|
@ -2587,17 +2588,20 @@ void Print::_make_wipe_tower()
|
|||
for (const auto extruder_id : layer_tools.extruders) {
|
||||
if (/*(first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back()) || */ extruder_id !=
|
||||
current_extruder_id) {
|
||||
float volume_to_wipe = wipe_volumes[current_extruder_id][extruder_id]; // total volume to wipe after this toolchange
|
||||
volume_to_wipe *= m_config.flush_multiplier;
|
||||
// Not all of that can be used for infill purging:
|
||||
volume_to_wipe -= (float) m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id);
|
||||
float volume_to_wipe = m_config.prime_volume;
|
||||
if (m_config.purge_in_prime_tower) {
|
||||
volume_to_wipe = wipe_volumes[current_extruder_id][extruder_id]; // total volume to wipe after this toolchange
|
||||
volume_to_wipe *= m_config.flush_multiplier;
|
||||
// Not all of that can be used for infill purging:
|
||||
volume_to_wipe -= (float) m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id);
|
||||
|
||||
// try to assign some infills/objects for the wiping:
|
||||
volume_to_wipe = layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, current_extruder_id, extruder_id,
|
||||
volume_to_wipe);
|
||||
// try to assign some infills/objects for the wiping:
|
||||
volume_to_wipe = layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, current_extruder_id, extruder_id,
|
||||
volume_to_wipe);
|
||||
|
||||
// add back the minimal amount toforce on the wipe tower:
|
||||
volume_to_wipe += (float) m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id);
|
||||
// add back the minimal amount toforce on the wipe tower:
|
||||
volume_to_wipe += (float) m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id);
|
||||
}
|
||||
|
||||
// request a toolchange at the wipe tower with at least volume_to_wipe purging amount
|
||||
wipe_tower.plan_toolchange((float) layer_tools.print_z, (float) layer_tools.wipe_tower_layer_height,
|
||||
|
|
@ -2712,6 +2716,7 @@ DynamicConfig PrintStatistics::config() const
|
|||
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));
|
||||
config.set_key_value("initial_tool", new ConfigOptionInt(static_cast<int>(this->initial_tool)));
|
||||
return config;
|
||||
}
|
||||
|
||||
|
|
@ -2721,7 +2726,7 @@ DynamicConfig PrintStatistics::placeholders()
|
|||
for (const std::string &key : {
|
||||
"print_time", "normal_print_time", "silent_print_time",
|
||||
"used_filament", "extruded_volume", "total_cost", "total_weight",
|
||||
"total_toolchanges", "total_wipe_tower_cost", "total_wipe_tower_filament"})
|
||||
"initial_tool", "total_toolchanges", "total_wipe_tower_cost", "total_wipe_tower_filament"})
|
||||
config.set_key_value(key, new ConfigOptionString(std::string("{") + key + "}"));
|
||||
return config;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -742,6 +742,7 @@ struct PrintStatistics
|
|||
double total_weight;
|
||||
double total_wipe_tower_cost;
|
||||
double total_wipe_tower_filament;
|
||||
unsigned int initial_tool;
|
||||
std::map<size_t, double> filament_stats;
|
||||
|
||||
// Config with the filled in print statistics.
|
||||
|
|
@ -759,6 +760,7 @@ struct PrintStatistics
|
|||
total_weight = 0.;
|
||||
total_wipe_tower_cost = 0.;
|
||||
total_wipe_tower_filament = 0.;
|
||||
initial_tool = 0;
|
||||
filament_stats.clear();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1454,7 +1454,6 @@ void PrintConfigDef::init_fff_params()
|
|||
"Can't be zero");
|
||||
def->sidetext = L("mm³/s");
|
||||
def->min = 0;
|
||||
def->max = 200;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloats { 2. });
|
||||
|
||||
|
|
@ -2817,7 +2816,7 @@ def = this->add("filament_loading_speed", coFloats);
|
|||
def->tooltip = L("User can self-define the project file name when export");
|
||||
def->full_width = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionString("{input_filename_base}_{filament_type[0]}_{print_time}.gcode"));
|
||||
def->set_default_value(new ConfigOptionString("{input_filename_base}_{filament_type[initial_tool]}_{print_time}.gcode"));
|
||||
|
||||
def = this->add("make_overhang_printable", coBool);
|
||||
def->label = L("Make overhang printable");
|
||||
|
|
|
|||
|
|
@ -22,8 +22,10 @@ namespace GUI
|
|||
ObjectLayers::ObjectLayers(wxWindow* parent) :
|
||||
OG_Settings(parent, true)
|
||||
{
|
||||
m_grid_sizer = new wxFlexGridSizer(3, 0, wxGetApp().em_unit()); // "Min Z", "Max Z", "Layer height" & buttons sizer
|
||||
m_grid_sizer = new wxFlexGridSizer(5, 0, wxGetApp().em_unit()); // Title, Min Z, "to", Max Z, unit & buttons sizer
|
||||
m_grid_sizer->SetFlexibleDirection(wxHORIZONTAL);
|
||||
m_grid_sizer->AddGrowableCol(1);
|
||||
m_grid_sizer->AddGrowableCol(3);
|
||||
|
||||
m_og->activate();
|
||||
m_og->sizer->Clear(true);
|
||||
|
|
@ -75,7 +77,7 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range, PlusMinus
|
|||
auto head_text = new wxStaticText(m_parent, wxID_ANY, _L("Height Range"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
|
||||
head_text->SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||
head_text->SetFont(wxGetApp().normal_font());
|
||||
m_grid_sizer->Add(head_text, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, wxGetApp().em_unit());
|
||||
m_grid_sizer->Add(head_text, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
// Add control for the "Min Z"
|
||||
|
||||
|
|
@ -101,14 +103,12 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range, PlusMinus
|
|||
|
||||
select_editor(editor, is_last_edited_range);
|
||||
|
||||
auto sizer1 = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer1->Add(editor);
|
||||
m_grid_sizer->Add(editor, 1, wxEXPAND);
|
||||
|
||||
auto middle_text = new wxStaticText(m_parent, wxID_ANY, _L("to"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
|
||||
middle_text->SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||
middle_text->SetFont(wxGetApp().normal_font());
|
||||
sizer1->Add(middle_text, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, wxGetApp().em_unit());
|
||||
|
||||
m_grid_sizer->Add(sizer1);
|
||||
m_grid_sizer->Add(middle_text, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
// Add control for the "Max Z"
|
||||
|
||||
|
|
@ -132,13 +132,13 @@ wxSizer* ObjectLayers::create_layer(const t_layer_height_range& range, PlusMinus
|
|||
});
|
||||
|
||||
//select_editor(editor, is_last_edited_range);
|
||||
m_grid_sizer->Add(editor, 1, wxEXPAND);
|
||||
|
||||
auto sizer2 = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer2->Add(editor);
|
||||
auto unit_text = new wxStaticText(m_parent, wxID_ANY, _L("mm"), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
|
||||
unit_text->SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||
unit_text->SetFont(wxGetApp().normal_font());
|
||||
sizer2->Add(unit_text, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, wxGetApp().em_unit());
|
||||
sizer2->Add(unit_text, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
m_grid_sizer->Add(sizer2);
|
||||
|
||||
|
|
@ -335,7 +335,7 @@ LayerRangeEditor::LayerRangeEditor( ObjectLayers* parent,
|
|||
m_type(type),
|
||||
m_set_focus_data(set_focus_data_fn),
|
||||
wxTextCtrl(parent->m_parent, wxID_ANY, value, wxDefaultPosition,
|
||||
wxSize(8 * em_unit(parent->m_parent), wxDefaultCoord), wxTE_PROCESS_ENTER
|
||||
wxSize(em_unit(parent->m_parent), wxDefaultCoord), wxTE_PROCESS_ENTER
|
||||
#ifdef _WIN32
|
||||
| wxBORDER_SIMPLE
|
||||
#endif
|
||||
|
|
@ -444,7 +444,7 @@ coordf_t LayerRangeEditor::get_value()
|
|||
|
||||
void LayerRangeEditor::msw_rescale()
|
||||
{
|
||||
SetMinSize(wxSize(8 * wxGetApp().em_unit(), wxDefaultCoord));
|
||||
SetMinSize(wxSize(wxGetApp().em_unit(), wxDefaultCoord));
|
||||
}
|
||||
|
||||
} //namespace GUI
|
||||
|
|
|
|||
|
|
@ -591,6 +591,15 @@ void ParamsPanel::set_active_tab(wxPanel* tab)
|
|||
wxString title = cur_tab->type() == Preset::TYPE_FILAMENT ? _L("Filament settings") : _L("Printer settings");
|
||||
dialog->SetTitle(title);
|
||||
}
|
||||
|
||||
auto tab_print = dynamic_cast<Tab *>(m_tab_print);
|
||||
if (cur_tab == m_tab_print) {
|
||||
if (tab_print)
|
||||
tab_print->toggle_line("print_flow_ratio", false);
|
||||
} else {
|
||||
if (tab_print)
|
||||
tab_print->toggle_line("print_flow_ratio", false);
|
||||
}
|
||||
}
|
||||
|
||||
bool ParamsPanel::is_active_and_shown_tab(wxPanel* tab)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue