Merge branch 'dev' of https://github.com/prusa3d/Slic3r into full_transform
This commit is contained in:
commit
7ef1eb306a
@ -208,10 +208,12 @@ sub _init_tabpanel {
|
||||
EVT_COMMAND($self, -1, $OBJECT_SELECTION_CHANGED_EVENT, sub {
|
||||
my ($self, $event) = @_;
|
||||
my $obj_idx = $event->GetId;
|
||||
my $child = $event->GetInt == 1 ? 1 : undef;
|
||||
# my $child = $event->GetInt == 1 ? 1 : undef;
|
||||
# $self->{plater}->select_object($obj_idx < 0 ? undef: $obj_idx, $child);
|
||||
# $self->{plater}->item_changed_selection($obj_idx);
|
||||
|
||||
$self->{plater}->select_object($obj_idx < 0 ? undef: $obj_idx, $child);
|
||||
$self->{plater}->item_changed_selection($obj_idx);
|
||||
my $vol_idx = $event->GetInt;
|
||||
$self->{plater}->select_object_from_cpp($obj_idx < 0 ? undef: $obj_idx, $vol_idx<0 ? -1 : $vol_idx);
|
||||
});
|
||||
|
||||
# The following event is emited by the C++ GUI implementation on object settings change.
|
||||
|
@ -113,10 +113,11 @@ sub new {
|
||||
# callback to enable/disable action buttons
|
||||
my $enable_action_buttons = sub {
|
||||
my ($enable) = @_;
|
||||
$self->{btn_export_gcode}->Enable($enable);
|
||||
$self->{btn_reslice}->Enable($enable);
|
||||
$self->{btn_print}->Enable($enable);
|
||||
$self->{btn_send_gcode}->Enable($enable);
|
||||
Slic3r::GUI::enable_action_buttons($enable);
|
||||
# $self->{btn_export_gcode}->Enable($enable);
|
||||
# $self->{btn_reslice}->Enable($enable);
|
||||
# $self->{btn_print}->Enable($enable);
|
||||
# $self->{btn_send_gcode}->Enable($enable);
|
||||
};
|
||||
|
||||
# callback to react to gizmo scale
|
||||
@ -239,7 +240,14 @@ sub new {
|
||||
my ($obj_idx, $object) = $self->selected_object;
|
||||
if (defined $obj_idx) {
|
||||
my $vol_idx = Slic3r::GUI::_3DScene::get_first_volume_id($self->{canvas3D}, $obj_idx);
|
||||
Slic3r::GUI::_3DScene::select_volume($self->{canvas3D}, $vol_idx) if ($vol_idx != -1);
|
||||
#Slic3r::GUI::_3DScene::select_volume($self->{canvas3D}, $vol_idx) if ($vol_idx != -1);
|
||||
my $inst_cnt = $self->{model}->objects->[$obj_idx]->instances_count;
|
||||
for (0..$inst_cnt-1){
|
||||
Slic3r::GUI::_3DScene::select_volume($self->{canvas3D}, $_ + $vol_idx) if ($vol_idx != -1);
|
||||
}
|
||||
|
||||
my $volume_idx = Slic3r::GUI::_3DScene::get_in_object_volume_id($self->{canvas3D}, $vol_idx);
|
||||
Slic3r::GUI::select_current_volume($obj_idx, $volume_idx) if ($volume_idx != -1);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -391,26 +399,35 @@ sub new {
|
||||
# }
|
||||
|
||||
### Panel for right column
|
||||
# $self->{right_panel} = Wx::Panel->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
$self->{right_panel} = Wx::ScrolledWindow->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
$self->{right_panel}->SetScrollbars(0, 1, 1, 1);
|
||||
$self->{right_panel} = Wx::Panel->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
# $self->{right_panel} = Wx::ScrolledWindow->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
# $self->{right_panel}->SetScrollbars(0, 1, 1, 1);
|
||||
|
||||
### Scrolled Window for panel without "Export G-code" and "Slice now" buttons
|
||||
my $scrolled_window_sizer = $self->{scrolled_window_sizer} = Wx::BoxSizer->new(wxVERTICAL);
|
||||
$scrolled_window_sizer->SetMinSize([320, -1]);
|
||||
my $scrolled_window_panel = $self->{scrolled_window_panel} = Wx::ScrolledWindow->new($self->{right_panel}, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
$scrolled_window_panel->SetSizer($scrolled_window_sizer);
|
||||
$scrolled_window_panel->SetScrollbars(0, 1, 1, 1);
|
||||
|
||||
# right pane buttons
|
||||
$self->{btn_export_gcode} = Wx::Button->new($self->{right_panel}, -1, L("Export G-code…"), wxDefaultPosition, [-1, 30], wxNO_BORDER);#, wxBU_LEFT);
|
||||
$self->{btn_reslice} = Wx::Button->new($self->{right_panel}, -1, L("Slice now"), wxDefaultPosition, [-1, 30], wxBU_LEFT);
|
||||
$self->{btn_print} = Wx::Button->new($self->{right_panel}, -1, L("Print…"), wxDefaultPosition, [-1, 30], wxBU_LEFT);
|
||||
$self->{btn_send_gcode} = Wx::Button->new($self->{right_panel}, -1, L("Send to printer"), wxDefaultPosition, [-1, 30], wxBU_LEFT);
|
||||
$self->{btn_export_stl} = Wx::Button->new($self->{right_panel}, -1, L("Export STL…"), wxDefaultPosition, [-1, 30], wxBU_LEFT);
|
||||
$self->{btn_export_gcode} = Wx::Button->new($self->{right_panel}, -1, L("Export G-code…"), wxDefaultPosition, [-1, 30],);# wxNO_BORDER);#, wxBU_LEFT);
|
||||
$self->{btn_reslice} = Wx::Button->new($self->{right_panel}, -1, L("Slice now"), wxDefaultPosition, [-1, 30]);#, wxNO_BORDER);#, wxBU_LEFT);
|
||||
# $self->{btn_print} = Wx::Button->new($self->{right_panel}, -1, L("Print…"), wxDefaultPosition, [-1, 30], wxBU_LEFT);
|
||||
# $self->{btn_send_gcode} = Wx::Button->new($self->{right_panel}, -1, L("Send to printer"), wxDefaultPosition, [-1, 30], wxBU_LEFT);
|
||||
$self->{btn_print} = Wx::Button->new($scrolled_window_panel, -1, L("Print…"), wxDefaultPosition, [-1, 30], wxBU_LEFT);
|
||||
$self->{btn_send_gcode} = Wx::Button->new($scrolled_window_panel, -1, L("Send to printer"), wxDefaultPosition, [-1, 30], wxBU_LEFT);
|
||||
#$self->{btn_export_stl} = Wx::Button->new($self->{right_panel}, -1, L("Export STL…"), wxDefaultPosition, [-1, 30], wxBU_LEFT);
|
||||
#$self->{btn_export_gcode}->SetFont($Slic3r::GUI::small_font);
|
||||
#$self->{btn_export_stl}->SetFont($Slic3r::GUI::small_font);
|
||||
$self->{btn_print}->Hide;
|
||||
$self->{btn_send_gcode}->Hide;
|
||||
|
||||
# export_gcode cog_go.png
|
||||
#! reslice reslice.png
|
||||
my %icons = qw(
|
||||
print arrow_up.png
|
||||
send_gcode arrow_up.png
|
||||
reslice reslice.png
|
||||
export_stl brick_go.png
|
||||
);
|
||||
for (grep $self->{"btn_$_"}, keys %icons) {
|
||||
@ -527,9 +544,11 @@ sub new {
|
||||
# $self->{preset_choosers}{$group}[$idx]
|
||||
$self->{preset_choosers} = {};
|
||||
for my $group (qw(print filament sla_material printer)) {
|
||||
my $text = Wx::StaticText->new($self->{right_panel}, -1, "$group_labels{$group}:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
|
||||
# my $text = Wx::StaticText->new($self->{right_panel}, -1, "$group_labels{$group}:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
|
||||
my $text = Wx::StaticText->new($scrolled_window_panel, -1, "$group_labels{$group}:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
|
||||
$text->SetFont($Slic3r::GUI::small_font);
|
||||
my $choice = Wx::BitmapComboBox->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, [], wxCB_READONLY);
|
||||
# my $choice = Wx::BitmapComboBox->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, [], wxCB_READONLY);
|
||||
my $choice = Wx::BitmapComboBox->new($scrolled_window_panel, -1, "", wxDefaultPosition, wxDefaultSize, [], wxCB_READONLY);
|
||||
if ($group eq 'filament') {
|
||||
EVT_LEFT_DOWN($choice, sub { $self->filament_color_box_lmouse_down(0, @_); } );
|
||||
}
|
||||
@ -548,26 +567,13 @@ sub new {
|
||||
}
|
||||
|
||||
my $frequently_changed_parameters_sizer = $self->{frequently_changed_parameters_sizer} = Wx::BoxSizer->new(wxVERTICAL);
|
||||
Slic3r::GUI::add_frequently_changed_parameters($self->{right_panel}, $frequently_changed_parameters_sizer, $presets);
|
||||
|
||||
my $expert_mode_part_sizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
Slic3r::GUI::add_expert_mode_part( $self->{right_panel}, $expert_mode_part_sizer,
|
||||
$self->{model},
|
||||
$self->{event_object_selection_changed},
|
||||
$self->{event_object_settings_changed},
|
||||
$self->{event_remove_object},
|
||||
$self->{event_update_scene});
|
||||
# if ($expert_mode_part_sizer->IsShown(2)==1)
|
||||
# {
|
||||
# $expert_mode_part_sizer->Layout;
|
||||
# $expert_mode_part_sizer->Show(2, 0); # ? Why doesn't work
|
||||
# $self->{right_panel}->Layout;
|
||||
# }
|
||||
#! Slic3r::GUI::add_frequently_changed_parameters($self->{right_panel}, $frequently_changed_parameters_sizer, $presets);
|
||||
Slic3r::GUI::add_frequently_changed_parameters($self->{scrolled_window_panel}, $frequently_changed_parameters_sizer, $presets);
|
||||
|
||||
my $object_info_sizer;
|
||||
{
|
||||
# my $box = Wx::StaticBox->new($scrolled_window_panel, -1, L("Info"));
|
||||
my $box = Wx::StaticBox->new($self->{right_panel}, -1, L("Info"));
|
||||
my $box = Wx::StaticBox->new($scrolled_window_panel, -1, L("Info"));
|
||||
# my $box = Wx::StaticBox->new($self->{right_panel}, -1, L("Info"));
|
||||
$box->SetFont($Slic3r::GUI::small_bold_font);
|
||||
$object_info_sizer = Wx::StaticBoxSizer->new($box, wxVERTICAL);
|
||||
$object_info_sizer->SetMinSize([300,-1]);
|
||||
@ -587,17 +593,17 @@ sub new {
|
||||
);
|
||||
while (my $field = shift @info) {
|
||||
my $label = shift @info;
|
||||
# my $text = Wx::StaticText->new($scrolled_window_panel, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
my $text = Wx::StaticText->new($self->{right_panel}, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
my $text = Wx::StaticText->new($scrolled_window_panel, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
# my $text = Wx::StaticText->new($self->{right_panel}, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
$text->SetFont($Slic3r::GUI::small_font);
|
||||
#!$grid_sizer->Add($text, 0);
|
||||
|
||||
# $self->{"object_info_$field"} = Wx::StaticText->new($scrolled_window_panel, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
$self->{"object_info_$field"} = Wx::StaticText->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
$self->{"object_info_$field"} = Wx::StaticText->new($scrolled_window_panel, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
# $self->{"object_info_$field"} = Wx::StaticText->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
$self->{"object_info_$field"}->SetFont($Slic3r::GUI::small_font);
|
||||
if ($field eq 'manifold') {
|
||||
# $self->{object_info_manifold_warning_icon} = Wx::StaticBitmap->new($scrolled_window_panel, -1, Wx::Bitmap->new(Slic3r::var("error.png"), wxBITMAP_TYPE_PNG));
|
||||
$self->{object_info_manifold_warning_icon} = Wx::StaticBitmap->new($self->{right_panel}, -1, Wx::Bitmap->new(Slic3r::var("error.png"), wxBITMAP_TYPE_PNG));
|
||||
$self->{object_info_manifold_warning_icon} = Wx::StaticBitmap->new($scrolled_window_panel, -1, Wx::Bitmap->new(Slic3r::var("error.png"), wxBITMAP_TYPE_PNG));
|
||||
# $self->{object_info_manifold_warning_icon} = Wx::StaticBitmap->new($self->{right_panel}, -1, Wx::Bitmap->new(Slic3r::var("error.png"), wxBITMAP_TYPE_PNG));
|
||||
#$self->{object_info_manifold_warning_icon}->Hide;
|
||||
$self->{"object_info_manifold_warning_icon_show"} = sub {
|
||||
if ($self->{object_info_manifold_warning_icon}->IsShown() != $_[0]) {
|
||||
@ -623,18 +629,19 @@ sub new {
|
||||
}
|
||||
}
|
||||
|
||||
my $print_info_sizer = $self->{print_info_sizer} = Wx::StaticBoxSizer->new(
|
||||
# Wx::StaticBox->new($scrolled_window_panel, -1, L("Sliced Info")), wxVERTICAL);
|
||||
Wx::StaticBox->new($self->{right_panel}, -1, L("Sliced Info")), wxVERTICAL);
|
||||
my $print_info_box = Wx::StaticBox->new($scrolled_window_panel, -1, L("Sliced Info"));
|
||||
$print_info_box->SetFont($Slic3r::GUI::small_bold_font);
|
||||
my $print_info_sizer = $self->{print_info_sizer} = Wx::StaticBoxSizer->new($print_info_box, wxVERTICAL);
|
||||
# Wx::StaticBox->new($self->{right_panel}, -1, L("Sliced Info")), wxVERTICAL);
|
||||
$print_info_sizer->SetMinSize([300,-1]);
|
||||
|
||||
my $buttons_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
|
||||
$self->{buttons_sizer} = $buttons_sizer;
|
||||
$buttons_sizer->AddStretchSpacer(1);
|
||||
$buttons_sizer->Add($self->{btn_export_stl}, 0, wxALIGN_RIGHT, 0);
|
||||
$buttons_sizer->Add($self->{btn_reslice}, 0, wxALIGN_RIGHT, 0);
|
||||
$buttons_sizer->Add($self->{btn_print}, 0, wxALIGN_RIGHT, 0);
|
||||
$buttons_sizer->Add($self->{btn_send_gcode}, 0, wxALIGN_RIGHT, 0);
|
||||
# $buttons_sizer->Add($self->{btn_export_stl}, 0, wxALIGN_RIGHT, 0);
|
||||
#! $buttons_sizer->Add($self->{btn_reslice}, 0, wxALIGN_RIGHT, 0);
|
||||
$buttons_sizer->Add($self->{btn_print}, 0, wxALIGN_RIGHT | wxBOTTOM | wxTOP, 5);
|
||||
$buttons_sizer->Add($self->{btn_send_gcode}, 0, wxALIGN_RIGHT | wxBOTTOM | wxTOP, 5);
|
||||
|
||||
# $scrolled_window_sizer->Add($self->{list}, 1, wxEXPAND, 5);
|
||||
# $scrolled_window_sizer->Add($object_info_sizer, 0, wxEXPAND, 0);
|
||||
@ -644,24 +651,39 @@ sub new {
|
||||
### Sizer for info boxes
|
||||
my $info_sizer = $self->{info_sizer} = Wx::BoxSizer->new(wxVERTICAL);
|
||||
$info_sizer->SetMinSize([318, -1]);
|
||||
$info_sizer->Add($object_info_sizer, 0, wxEXPAND | wxBOTTOM, 5);
|
||||
$info_sizer->Add($print_info_sizer, 0, wxEXPAND | wxBOTTOM, 5);
|
||||
$info_sizer->Add($object_info_sizer, 0, wxEXPAND | wxTOP, 20);
|
||||
$info_sizer->Add($print_info_sizer, 0, wxEXPAND | wxTOP, 20);
|
||||
|
||||
$scrolled_window_sizer->Add($presets, 0, wxEXPAND | wxLEFT, 2) if defined $presets;
|
||||
$scrolled_window_sizer->Add($frequently_changed_parameters_sizer, 1, wxEXPAND | wxLEFT, 0) if defined $frequently_changed_parameters_sizer;
|
||||
$scrolled_window_sizer->Add($buttons_sizer, 0, wxEXPAND, 0);
|
||||
$scrolled_window_sizer->Add($info_sizer, 0, wxEXPAND | wxLEFT, 20);
|
||||
# Show the box initially, let it be shown after the slicing is finished.
|
||||
$self->print_info_box_show(0);
|
||||
|
||||
### Sizer for "Export G-code" & "Slice now" buttons
|
||||
my $btns_sizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
$btns_sizer->SetMinSize([318, -1]);
|
||||
$btns_sizer->Add($self->{btn_reslice}, 0, wxEXPAND, 0);
|
||||
$btns_sizer->Add($self->{btn_export_gcode}, 0, wxEXPAND | wxTOP, 5);
|
||||
|
||||
my $right_sizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
$self->{right_panel}->SetSizer($right_sizer);
|
||||
$right_sizer->SetMinSize([320, -1]);
|
||||
$right_sizer->Add($presets, 0, wxEXPAND | wxTOP, 10) if defined $presets;
|
||||
$right_sizer->Add($frequently_changed_parameters_sizer, 1, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer;
|
||||
$right_sizer->Add($expert_mode_part_sizer, 0, wxEXPAND | wxTOP, 10) if defined $expert_mode_part_sizer;
|
||||
$right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM | wxTOP, 10);
|
||||
$right_sizer->Add($info_sizer, 0, wxEXPAND | wxLEFT, 20);
|
||||
#! $right_sizer->Add($presets, 0, wxEXPAND | wxTOP, 10) if defined $presets;
|
||||
#! $right_sizer->Add($frequently_changed_parameters_sizer, 1, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer;
|
||||
#! $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM | wxTOP, 10);
|
||||
#! $right_sizer->Add($info_sizer, 0, wxEXPAND | wxLEFT, 20);
|
||||
# Show the box initially, let it be shown after the slicing is finished.
|
||||
$self->print_info_box_show(0);
|
||||
$right_sizer->Add($self->{btn_export_gcode}, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 20);
|
||||
#! $self->print_info_box_show(0);
|
||||
$right_sizer->Add($scrolled_window_panel, 1, wxEXPAND | wxTOP, 5);
|
||||
# $right_sizer->Add($self->{btn_reslice}, 0, wxEXPAND | wxLEFT | wxTOP, 20);
|
||||
# $right_sizer->Add($self->{btn_export_gcode}, 0, wxEXPAND | wxLEFT | wxTOP, 20);
|
||||
$right_sizer->Add($btns_sizer, 0, wxEXPAND | wxLEFT | wxTOP, 20);
|
||||
|
||||
my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL);
|
||||
$hsizer->Add($self->{preview_notebook}, 1, wxEXPAND | wxTOP, 1);
|
||||
$hsizer->Add($self->{right_panel}, 0, wxEXPAND | wxLEFT | wxRIGHT, 3);
|
||||
$hsizer->Add($self->{right_panel}, 0, wxEXPAND | wxLEFT | wxRIGHT, 0);#3);
|
||||
|
||||
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
# $sizer->Add($self->{htoolbar}, 0, wxEXPAND, 0) if $self->{htoolbar};
|
||||
@ -672,16 +694,21 @@ sub new {
|
||||
$self->SetSizer($sizer);
|
||||
|
||||
# Send sizers/buttons to C++
|
||||
Slic3r::GUI::set_objects_from_perl( $self->{right_panel},
|
||||
$frequently_changed_parameters_sizer,
|
||||
$expert_mode_part_sizer,
|
||||
$info_sizer,
|
||||
$self->{btn_export_gcode},
|
||||
$self->{btn_export_stl},
|
||||
$self->{btn_reslice},
|
||||
$self->{btn_print},
|
||||
$self->{btn_send_gcode},
|
||||
$self->{object_info_manifold_warning_icon} );
|
||||
Slic3r::GUI::set_objects_from_perl( $self->{scrolled_window_panel},
|
||||
$frequently_changed_parameters_sizer,
|
||||
$info_sizer,
|
||||
$self->{btn_export_gcode},
|
||||
# $self->{btn_export_stl},
|
||||
$self->{btn_reslice},
|
||||
$self->{btn_print},
|
||||
$self->{btn_send_gcode},
|
||||
$self->{object_info_manifold_warning_icon} );
|
||||
|
||||
Slic3r::GUI::set_model_events_from_perl( $self->{model},
|
||||
$self->{event_object_selection_changed},
|
||||
$self->{event_object_settings_changed},
|
||||
$self->{event_remove_object},
|
||||
$self->{event_update_scene});
|
||||
}
|
||||
|
||||
# Last correct selected item for each preset
|
||||
@ -1758,14 +1785,16 @@ sub print_info_box_show {
|
||||
# my $scrolled_window_panel = $self->{scrolled_window_panel};
|
||||
# my $scrolled_window_sizer = $self->{scrolled_window_sizer};
|
||||
# return if (!$show && ($scrolled_window_sizer->IsShown(2) == $show));
|
||||
my $panel = $self->{right_panel};
|
||||
my $panel = $self->{scrolled_window_panel};#$self->{right_panel};
|
||||
my $sizer = $self->{info_sizer};
|
||||
return if (!$sizer || !$show && ($sizer->IsShown(1) == $show));
|
||||
# return if (!$sizer || !$show && ($sizer->IsShown(1) == $show));
|
||||
return if (!$sizer);
|
||||
|
||||
Slic3r::GUI::set_show_print_info($show);
|
||||
return if (wxTheApp->{app_config}->get("view_mode") eq "simple");
|
||||
# return if (wxTheApp->{app_config}->get("view_mode") eq "simple");
|
||||
|
||||
if ($show) {
|
||||
# if ($show)
|
||||
{
|
||||
my $print_info_sizer = $self->{print_info_sizer};
|
||||
$print_info_sizer->Clear(1);
|
||||
my $grid_sizer = Wx::FlexGridSizer->new(2, 2, 5, 5);
|
||||
@ -1803,7 +1832,7 @@ sub print_info_box_show {
|
||||
|
||||
# $scrolled_window_sizer->Show(2, $show);
|
||||
# $scrolled_window_panel->Layout;
|
||||
$sizer->Show(1, $show);
|
||||
$sizer->Show(1, $show && wxTheApp->{app_config}->get("view_mode") ne "simple");
|
||||
|
||||
$self->Layout;
|
||||
$panel->Refresh;
|
||||
@ -1987,7 +2016,7 @@ sub _get_export_file {
|
||||
# (i.e. when an object is added/removed/moved/rotated/scaled)
|
||||
sub update {
|
||||
my ($self, $force_autocenter) = @_;
|
||||
|
||||
$self->Freeze;
|
||||
if (wxTheApp->{app_config}->get("autocenter") || $force_autocenter) {
|
||||
$self->{model}->center_instances_around_point($self->bed_centerf);
|
||||
}
|
||||
@ -2013,6 +2042,7 @@ sub update {
|
||||
Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 0);
|
||||
$self->{preview3D}->reset_gcode_preview_data if $self->{preview3D};
|
||||
$self->{preview3D}->reload_print if $self->{preview3D};
|
||||
$self->Thaw;
|
||||
}
|
||||
|
||||
# When a printer technology is changed, the UI needs to be updated to show/hide needed preset combo boxes.
|
||||
@ -2045,7 +2075,8 @@ sub on_extruders_change {
|
||||
my @presets = $choices->[0]->GetStrings;
|
||||
|
||||
# initialize new choice
|
||||
my $choice = Wx::BitmapComboBox->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, [@presets], wxCB_READONLY);
|
||||
# my $choice = Wx::BitmapComboBox->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, [@presets], wxCB_READONLY);
|
||||
my $choice = Wx::BitmapComboBox->new($self->{scrolled_window_panel}, -1, "", wxDefaultPosition, wxDefaultSize, [@presets], wxCB_READONLY);
|
||||
my $extruder_idx = scalar @$choices;
|
||||
EVT_LEFT_DOWN($choice, sub { $self->filament_color_box_lmouse_down($extruder_idx, @_); } );
|
||||
push @$choices, $choice;
|
||||
@ -2072,6 +2103,7 @@ sub on_extruders_change {
|
||||
$choices->[-1]->Destroy;
|
||||
pop @$choices;
|
||||
}
|
||||
$self->{right_panel}->Layout;
|
||||
$self->Layout;
|
||||
}
|
||||
|
||||
@ -2455,6 +2487,50 @@ sub select_object {
|
||||
$self->selection_changed(1);
|
||||
}
|
||||
|
||||
sub select_object_from_cpp {
|
||||
my ($self, $obj_idx, $vol_idx) = @_;
|
||||
|
||||
# remove current selection
|
||||
foreach my $o (0..$#{$self->{objects}}) {
|
||||
$self->{objects}->[$o]->selected(0);
|
||||
}
|
||||
|
||||
my $curr = Slic3r::GUI::_3DScene::get_select_by($self->{canvas3D});
|
||||
|
||||
if (defined $obj_idx) {
|
||||
if ($vol_idx == -1){
|
||||
if ($curr eq 'object') {
|
||||
$self->{objects}->[$obj_idx]->selected(1);
|
||||
}
|
||||
elsif ($curr eq 'volume') {
|
||||
Slic3r::GUI::_3DScene::set_select_by($self->{canvas3D}, 'object');
|
||||
}
|
||||
|
||||
my $selections = $self->collect_selections;
|
||||
Slic3r::GUI::_3DScene::set_objects_selections($self->{canvas3D}, \@$selections);
|
||||
Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 1);
|
||||
}
|
||||
else {
|
||||
if ($curr eq 'object') {
|
||||
Slic3r::GUI::_3DScene::set_select_by($self->{canvas3D}, 'volume');
|
||||
}
|
||||
|
||||
my $selections = [];
|
||||
Slic3r::GUI::_3DScene::set_objects_selections($self->{canvas3D}, \@$selections);
|
||||
Slic3r::GUI::_3DScene::deselect_volumes($self->{canvas3D});
|
||||
Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 1);
|
||||
my $volume_idx = Slic3r::GUI::_3DScene::get_first_volume_id($self->{canvas3D}, $obj_idx);
|
||||
|
||||
my $inst_cnt = $self->{model}->objects->[$obj_idx]->instances_count;
|
||||
for (0..$inst_cnt-1){
|
||||
Slic3r::GUI::_3DScene::select_volume($self->{canvas3D}, $vol_idx*$inst_cnt + $_ + $volume_idx) if ($volume_idx != -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$self->selection_changed(1);
|
||||
}
|
||||
|
||||
sub selected_object {
|
||||
my ($self) = @_;
|
||||
my $obj_idx = first { $self->{objects}[$_]->selected } 0..$#{ $self->{objects} };
|
||||
|
@ -5,12 +5,12 @@ use utf8;
|
||||
|
||||
use Slic3r::Print::State ':steps';
|
||||
use Wx qw(:misc :sizer :slider :statictext :keycode wxWHITE wxCB_READONLY);
|
||||
use Wx::Event qw(EVT_SLIDER EVT_KEY_DOWN EVT_CHECKBOX EVT_CHOICE EVT_CHECKLISTBOX);
|
||||
use Wx::Event qw(EVT_SLIDER EVT_KEY_DOWN EVT_CHECKBOX EVT_CHOICE EVT_CHECKLISTBOX EVT_SIZE);
|
||||
use base qw(Wx::Panel Class::Accessor);
|
||||
|
||||
use Wx::Locale gettext => 'L';
|
||||
|
||||
__PACKAGE__->mk_accessors(qw(print gcode_preview_data enabled _loaded canvas slider_low slider_high single_layer));
|
||||
__PACKAGE__->mk_accessors(qw(print gcode_preview_data enabled _loaded canvas slider_low slider_high single_layer double_slider_sizer));
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
@ -27,47 +27,47 @@ sub new {
|
||||
Slic3r::GUI::_3DScene::enable_shader($canvas, 1);
|
||||
Slic3r::GUI::_3DScene::set_config($canvas, $config);
|
||||
$self->canvas($canvas);
|
||||
my $slider_low = Wx::Slider->new(
|
||||
$self, -1,
|
||||
0, # default
|
||||
0, # min
|
||||
# my $slider_low = Wx::Slider->new(
|
||||
# $self, -1,
|
||||
# 0, # default
|
||||
# 0, # min
|
||||
# we set max to a bogus non-zero value because the MSW implementation of wxSlider
|
||||
# will skip drawing the slider if max <= min:
|
||||
1, # max
|
||||
wxDefaultPosition,
|
||||
wxDefaultSize,
|
||||
wxVERTICAL | wxSL_INVERSE,
|
||||
);
|
||||
$self->slider_low($slider_low);
|
||||
my $slider_high = Wx::Slider->new(
|
||||
$self, -1,
|
||||
0, # default
|
||||
0, # min
|
||||
# 1, # max
|
||||
# wxDefaultPosition,
|
||||
# wxDefaultSize,
|
||||
# wxVERTICAL | wxSL_INVERSE,
|
||||
# );
|
||||
# $self->slider_low($slider_low);
|
||||
# my $slider_high = Wx::Slider->new(
|
||||
# $self, -1,
|
||||
# 0, # default
|
||||
# 0, # min
|
||||
# we set max to a bogus non-zero value because the MSW implementation of wxSlider
|
||||
# will skip drawing the slider if max <= min:
|
||||
1, # max
|
||||
wxDefaultPosition,
|
||||
wxDefaultSize,
|
||||
wxVERTICAL | wxSL_INVERSE,
|
||||
);
|
||||
$self->slider_high($slider_high);
|
||||
# 1, # max
|
||||
# wxDefaultPosition,
|
||||
# wxDefaultSize,
|
||||
# wxVERTICAL | wxSL_INVERSE,
|
||||
# );
|
||||
# $self->slider_high($slider_high);
|
||||
|
||||
my $z_label_low = $self->{z_label_low} = Wx::StaticText->new($self, -1, "", wxDefaultPosition,
|
||||
[40,-1], wxALIGN_CENTRE_HORIZONTAL);
|
||||
$z_label_low->SetFont($Slic3r::GUI::small_font);
|
||||
my $z_label_high = $self->{z_label_high} = Wx::StaticText->new($self, -1, "", wxDefaultPosition,
|
||||
[40,-1], wxALIGN_CENTRE_HORIZONTAL);
|
||||
$z_label_high->SetFont($Slic3r::GUI::small_font);
|
||||
# my $z_label_low = $self->{z_label_low} = Wx::StaticText->new($self, -1, "", wxDefaultPosition,
|
||||
# [40,-1], wxALIGN_CENTRE_HORIZONTAL);
|
||||
# $z_label_low->SetFont($Slic3r::GUI::small_font);
|
||||
# my $z_label_high = $self->{z_label_high} = Wx::StaticText->new($self, -1, "", wxDefaultPosition,
|
||||
# [40,-1], wxALIGN_CENTRE_HORIZONTAL);
|
||||
# $z_label_high->SetFont($Slic3r::GUI::small_font);
|
||||
|
||||
my $z_label_low_idx = $self->{z_label_low_idx} = Wx::StaticText->new($self, -1, "", wxDefaultPosition,
|
||||
[40,-1], wxALIGN_CENTRE_HORIZONTAL);
|
||||
$z_label_low_idx->SetFont($Slic3r::GUI::small_font);
|
||||
my $z_label_high_idx = $self->{z_label_high_idx} = Wx::StaticText->new($self, -1, "", wxDefaultPosition,
|
||||
[40,-1], wxALIGN_CENTRE_HORIZONTAL);
|
||||
$z_label_high_idx->SetFont($Slic3r::GUI::small_font);
|
||||
# my $z_label_low_idx = $self->{z_label_low_idx} = Wx::StaticText->new($self, -1, "", wxDefaultPosition,
|
||||
# [40,-1], wxALIGN_CENTRE_HORIZONTAL);
|
||||
# $z_label_low_idx->SetFont($Slic3r::GUI::small_font);
|
||||
# my $z_label_high_idx = $self->{z_label_high_idx} = Wx::StaticText->new($self, -1, "", wxDefaultPosition,
|
||||
# [40,-1], wxALIGN_CENTRE_HORIZONTAL);
|
||||
# $z_label_high_idx->SetFont($Slic3r::GUI::small_font);
|
||||
|
||||
$self->single_layer(0);
|
||||
my $checkbox_singlelayer = $self->{checkbox_singlelayer} = Wx::CheckBox->new($self, -1, L("1 Layer"));
|
||||
# $self->single_layer(0);
|
||||
# my $checkbox_singlelayer = $self->{checkbox_singlelayer} = Wx::CheckBox->new($self, -1, L("1 Layer"));
|
||||
|
||||
my $label_view_type = $self->{label_view_type} = Wx::StaticText->new($self, -1, L("View"));
|
||||
|
||||
@ -102,26 +102,31 @@ sub new {
|
||||
.L("Wipe tower")."|"
|
||||
.L("Custom");
|
||||
Slic3r::GUI::create_combochecklist($combochecklist_features, $feature_text, $feature_items, 1);
|
||||
|
||||
my $double_slider_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
|
||||
Slic3r::GUI::create_double_slider($self, $double_slider_sizer, $self->canvas);
|
||||
$self->double_slider_sizer($double_slider_sizer);
|
||||
|
||||
my $checkbox_travel = $self->{checkbox_travel} = Wx::CheckBox->new($self, -1, L("Travel"));
|
||||
my $checkbox_retractions = $self->{checkbox_retractions} = Wx::CheckBox->new($self, -1, L("Retractions"));
|
||||
my $checkbox_unretractions = $self->{checkbox_unretractions} = Wx::CheckBox->new($self, -1, L("Unretractions"));
|
||||
my $checkbox_shells = $self->{checkbox_shells} = Wx::CheckBox->new($self, -1, L("Shells"));
|
||||
|
||||
my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL);
|
||||
my $vsizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
my $vsizer_outer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
$vsizer->Add($slider_low, 3, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
$vsizer->Add($z_label_low_idx, 0, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
$vsizer->Add($z_label_low, 0, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
$hsizer->Add($vsizer, 0, wxEXPAND, 0);
|
||||
$vsizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
$vsizer->Add($slider_high, 3, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
$vsizer->Add($z_label_high_idx, 0, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
$vsizer->Add($z_label_high, 0, 0, 0);
|
||||
$hsizer->Add($vsizer, 0, wxEXPAND, 0);
|
||||
$vsizer_outer->Add($hsizer, 3, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
$vsizer_outer->Add($checkbox_singlelayer, 0, wxTOP | wxALIGN_CENTER_HORIZONTAL, 5);
|
||||
# my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL);
|
||||
# my $vsizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
# my $vsizer_outer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
# $vsizer->Add($slider_low, 3, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
# $vsizer->Add($z_label_low_idx, 0, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
# $vsizer->Add($z_label_low, 0, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
# $hsizer->Add($vsizer, 0, wxEXPAND, 0);
|
||||
# $vsizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
# $vsizer->Add($slider_high, 3, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
# $vsizer->Add($z_label_high_idx, 0, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
# $vsizer->Add($z_label_high, 0, 0, 0);
|
||||
# $hsizer->Add($vsizer, 0, wxEXPAND, 0);
|
||||
# $vsizer_outer->Add($hsizer, 3, wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
# $vsizer_outer->Add($double_slider_sizer, 3, wxEXPAND, 0);
|
||||
# $vsizer_outer->Add($checkbox_singlelayer, 0, wxTOP | wxALIGN_CENTER_HORIZONTAL, 5);
|
||||
|
||||
my $bottom_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
|
||||
$bottom_sizer->Add($label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5);
|
||||
@ -140,81 +145,83 @@ sub new {
|
||||
|
||||
my $sizer = Wx::BoxSizer->new(wxHORIZONTAL);
|
||||
$sizer->Add($canvas, 1, wxALL | wxEXPAND, 0);
|
||||
$sizer->Add($vsizer_outer, 0, wxTOP | wxBOTTOM | wxEXPAND, 5);
|
||||
# $sizer->Add($vsizer_outer, 0, wxTOP | wxBOTTOM | wxEXPAND, 5);
|
||||
$sizer->Add($double_slider_sizer, 0, wxEXPAND, 0);#wxTOP | wxBOTTOM | wxEXPAND, 5);
|
||||
|
||||
my $main_sizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
$main_sizer->Add($sizer, 1, wxALL | wxEXPAND, 0);
|
||||
$main_sizer->Add($bottom_sizer, 0, wxALL | wxEXPAND, 0);
|
||||
|
||||
EVT_SLIDER($self, $slider_low, sub {
|
||||
$slider_high->SetValue($slider_low->GetValue) if $self->single_layer;
|
||||
$self->set_z_idx_low ($slider_low ->GetValue)
|
||||
});
|
||||
EVT_SLIDER($self, $slider_high, sub {
|
||||
$slider_low->SetValue($slider_high->GetValue) if $self->single_layer;
|
||||
$self->set_z_idx_high($slider_high->GetValue)
|
||||
});
|
||||
EVT_KEY_DOWN($canvas, sub {
|
||||
my ($s, $event) = @_;
|
||||
my $key = $event->GetKeyCode;
|
||||
if ($event->HasModifiers) {
|
||||
$event->Skip;
|
||||
} else {
|
||||
if ($key == ord('U')) {
|
||||
$slider_high->SetValue($slider_high->GetValue + 1);
|
||||
$slider_low->SetValue($slider_high->GetValue) if ($event->ShiftDown());
|
||||
$self->set_z_idx_high($slider_high->GetValue);
|
||||
} elsif ($key == ord('D')) {
|
||||
$slider_high->SetValue($slider_high->GetValue - 1);
|
||||
$slider_low->SetValue($slider_high->GetValue) if ($event->ShiftDown());
|
||||
$self->set_z_idx_high($slider_high->GetValue);
|
||||
} elsif ($key == ord('S')) {
|
||||
$checkbox_singlelayer->SetValue(! $checkbox_singlelayer->GetValue());
|
||||
$self->single_layer($checkbox_singlelayer->GetValue());
|
||||
if ($self->single_layer) {
|
||||
$slider_low->SetValue($slider_high->GetValue);
|
||||
$self->set_z_idx_high($slider_high->GetValue);
|
||||
}
|
||||
} else {
|
||||
$event->Skip;
|
||||
}
|
||||
}
|
||||
});
|
||||
EVT_KEY_DOWN($slider_low, sub {
|
||||
my ($s, $event) = @_;
|
||||
my $key = $event->GetKeyCode;
|
||||
if ($event->HasModifiers) {
|
||||
$event->Skip;
|
||||
} else {
|
||||
if ($key == WXK_LEFT) {
|
||||
} elsif ($key == WXK_RIGHT) {
|
||||
$slider_high->SetFocus;
|
||||
} else {
|
||||
$event->Skip;
|
||||
}
|
||||
}
|
||||
});
|
||||
EVT_KEY_DOWN($slider_high, sub {
|
||||
my ($s, $event) = @_;
|
||||
my $key = $event->GetKeyCode;
|
||||
if ($event->HasModifiers) {
|
||||
$event->Skip;
|
||||
} else {
|
||||
if ($key == WXK_LEFT) {
|
||||
$slider_low->SetFocus;
|
||||
} elsif ($key == WXK_RIGHT) {
|
||||
} else {
|
||||
$event->Skip;
|
||||
}
|
||||
}
|
||||
});
|
||||
EVT_CHECKBOX($self, $checkbox_singlelayer, sub {
|
||||
$self->single_layer($checkbox_singlelayer->GetValue());
|
||||
if ($self->single_layer) {
|
||||
$slider_low->SetValue($slider_high->GetValue);
|
||||
$self->set_z_idx_high($slider_high->GetValue);
|
||||
}
|
||||
});
|
||||
# EVT_SLIDER($self, $slider_low, sub {
|
||||
# $slider_high->SetValue($slider_low->GetValue) if $self->single_layer;
|
||||
# $self->set_z_idx_low ($slider_low ->GetValue)
|
||||
# });
|
||||
# EVT_SLIDER($self, $slider_high, sub {
|
||||
# $slider_low->SetValue($slider_high->GetValue) if $self->single_layer;
|
||||
# $self->set_z_idx_high($slider_high->GetValue)
|
||||
# });
|
||||
# EVT_KEY_DOWN($canvas, sub {
|
||||
# my ($s, $event) = @_;
|
||||
# Slic3r::GUI::update_double_slider_from_canvas($event);
|
||||
# my $key = $event->GetKeyCode;
|
||||
# if ($event->HasModifiers) {
|
||||
# $event->Skip;
|
||||
# } else {
|
||||
# if ($key == ord('U')) {
|
||||
# $slider_high->SetValue($slider_high->GetValue + 1);
|
||||
# $slider_low->SetValue($slider_high->GetValue) if ($event->ShiftDown());
|
||||
# $self->set_z_idx_high($slider_high->GetValue);
|
||||
# } elsif ($key == ord('D')) {
|
||||
# $slider_high->SetValue($slider_high->GetValue - 1);
|
||||
# $slider_low->SetValue($slider_high->GetValue) if ($event->ShiftDown());
|
||||
# $self->set_z_idx_high($slider_high->GetValue);
|
||||
# } elsif ($key == ord('S')) {
|
||||
# $checkbox_singlelayer->SetValue(! $checkbox_singlelayer->GetValue());
|
||||
# $self->single_layer($checkbox_singlelayer->GetValue());
|
||||
# if ($self->single_layer) {
|
||||
# $slider_low->SetValue($slider_high->GetValue);
|
||||
# $self->set_z_idx_high($slider_high->GetValue);
|
||||
# }
|
||||
# } else {
|
||||
# $event->Skip;
|
||||
# }
|
||||
# }
|
||||
# });
|
||||
# EVT_KEY_DOWN($slider_low, sub {
|
||||
# my ($s, $event) = @_;
|
||||
# my $key = $event->GetKeyCode;
|
||||
# if ($event->HasModifiers) {
|
||||
# $event->Skip;
|
||||
# } else {
|
||||
# if ($key == WXK_LEFT) {
|
||||
# } elsif ($key == WXK_RIGHT) {
|
||||
# $slider_high->SetFocus;
|
||||
# } else {
|
||||
# $event->Skip;
|
||||
# }
|
||||
# }
|
||||
# });
|
||||
# EVT_KEY_DOWN($slider_high, sub {
|
||||
# my ($s, $event) = @_;
|
||||
# my $key = $event->GetKeyCode;
|
||||
# if ($event->HasModifiers) {
|
||||
# $event->Skip;
|
||||
# } else {
|
||||
# if ($key == WXK_LEFT) {
|
||||
# $slider_low->SetFocus;
|
||||
# } elsif ($key == WXK_RIGHT) {
|
||||
# } else {
|
||||
# $event->Skip;
|
||||
# }
|
||||
# }
|
||||
# });
|
||||
# EVT_CHECKBOX($self, $checkbox_singlelayer, sub {
|
||||
# $self->single_layer($checkbox_singlelayer->GetValue());
|
||||
# if ($self->single_layer) {
|
||||
# $slider_low->SetValue($slider_high->GetValue);
|
||||
# $self->set_z_idx_high($slider_high->GetValue);
|
||||
# }
|
||||
# });
|
||||
EVT_CHOICE($self, $choice_view_type, sub {
|
||||
my $selection = $choice_view_type->GetCurrentSelection();
|
||||
$self->{preferred_color_mode} = ($selection == $self->{tool_idx}) ? 'tool' : 'feature';
|
||||
@ -243,6 +250,12 @@ sub new {
|
||||
$self->gcode_preview_data->set_shells_visible($checkbox_shells->IsChecked());
|
||||
$self->refresh_print;
|
||||
});
|
||||
|
||||
EVT_SIZE($self, sub {
|
||||
my ($s, $event) = @_;
|
||||
$event->Skip;
|
||||
$self->Refresh;
|
||||
});
|
||||
|
||||
$self->SetSizer($main_sizer);
|
||||
$self->SetMinSize($self->GetSize);
|
||||
@ -392,62 +405,69 @@ sub load_print {
|
||||
sub reset_sliders {
|
||||
my ($self) = @_;
|
||||
$self->enabled(0);
|
||||
$self->set_z_range(0,0);
|
||||
$self->slider_low->Hide;
|
||||
$self->slider_high->Hide;
|
||||
$self->{z_label_low}->SetLabel("");
|
||||
$self->{z_label_high}->SetLabel("");
|
||||
$self->{z_label_low_idx}->SetLabel("");
|
||||
$self->{z_label_high_idx}->SetLabel("");
|
||||
# $self->set_z_range(0,0);
|
||||
# $self->slider_low->Hide;
|
||||
# $self->slider_high->Hide;
|
||||
# $self->{z_label_low}->SetLabel("");
|
||||
# $self->{z_label_high}->SetLabel("");
|
||||
# $self->{z_label_low_idx}->SetLabel("");
|
||||
# $self->{z_label_high_idx}->SetLabel("");
|
||||
|
||||
Slic3r::GUI::reset_double_slider();
|
||||
$self->double_slider_sizer->Hide(0);
|
||||
}
|
||||
|
||||
sub update_sliders
|
||||
{
|
||||
my ($self, $n_layers) = @_;
|
||||
|
||||
my $z_idx_low = $self->slider_low->GetValue;
|
||||
my $z_idx_high = $self->slider_high->GetValue;
|
||||
# my $z_idx_low = $self->slider_low->GetValue;
|
||||
# my $z_idx_high = $self->slider_high->GetValue;
|
||||
$self->enabled(1);
|
||||
$self->slider_low->SetRange(0, $n_layers - 1);
|
||||
$self->slider_high->SetRange(0, $n_layers - 1);
|
||||
# $self->slider_low->SetRange(0, $n_layers - 1);
|
||||
# $self->slider_high->SetRange(0, $n_layers - 1);
|
||||
|
||||
if ($self->{force_sliders_full_range}) {
|
||||
$z_idx_low = 0;
|
||||
$z_idx_high = $n_layers - 1;
|
||||
} elsif ($z_idx_high < $n_layers && ($self->single_layer || $z_idx_high != 0)) {
|
||||
# search new indices for nearest z (size of $self->{layers_z} may change in dependence of what is shown)
|
||||
if (defined($self->{z_low})) {
|
||||
for (my $i = scalar(@{$self->{layers_z}}) - 1; $i >= 0; $i -= 1) {
|
||||
if ($self->{layers_z}[$i] <= $self->{z_low}) {
|
||||
$z_idx_low = $i;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (defined($self->{z_high})) {
|
||||
for (my $i = scalar(@{$self->{layers_z}}) - 1; $i >= 0; $i -= 1) {
|
||||
if ($self->{layers_z}[$i] <= $self->{z_high}) {
|
||||
$z_idx_high = $i;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
} elsif ($z_idx_high >= $n_layers) {
|
||||
# Out of range. Disable 'single layer' view.
|
||||
$self->single_layer(0);
|
||||
$self->{checkbox_singlelayer}->SetValue(0);
|
||||
$z_idx_low = 0;
|
||||
$z_idx_high = $n_layers - 1;
|
||||
} else {
|
||||
$z_idx_low = 0;
|
||||
$z_idx_high = $n_layers - 1;
|
||||
}
|
||||
# if ($self->{force_sliders_full_range}) {
|
||||
# $z_idx_low = 0;
|
||||
# $z_idx_high = $n_layers - 1;
|
||||
# } elsif ($z_idx_high < $n_layers && ($self->single_layer || $z_idx_high != 0)) {
|
||||
# # search new indices for nearest z (size of $self->{layers_z} may change in dependence of what is shown)
|
||||
# if (defined($self->{z_low})) {
|
||||
# for (my $i = scalar(@{$self->{layers_z}}) - 1; $i >= 0; $i -= 1) {
|
||||
# if ($self->{layers_z}[$i] <= $self->{z_low}) {
|
||||
# $z_idx_low = $i;
|
||||
# last;
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# if (defined($self->{z_high})) {
|
||||
# for (my $i = scalar(@{$self->{layers_z}}) - 1; $i >= 0; $i -= 1) {
|
||||
# if ($self->{layers_z}[$i] <= $self->{z_high}) {
|
||||
# $z_idx_high = $i;
|
||||
# last;
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# } elsif ($z_idx_high >= $n_layers) {
|
||||
# # Out of range. Disable 'single layer' view.
|
||||
# $self->single_layer(0);
|
||||
# $self->{checkbox_singlelayer}->SetValue(0);
|
||||
# $z_idx_low = 0;
|
||||
# $z_idx_high = $n_layers - 1;
|
||||
# } else {
|
||||
# $z_idx_low = 0;
|
||||
# $z_idx_high = $n_layers - 1;
|
||||
# }
|
||||
|
||||
$self->slider_low->SetValue($z_idx_low);
|
||||
$self->slider_high->SetValue($z_idx_high);
|
||||
$self->slider_low->Show;
|
||||
$self->slider_high->Show;
|
||||
$self->set_z_range($self->{layers_z}[$z_idx_low], $self->{layers_z}[$z_idx_high]);
|
||||
# $self->slider_low->SetValue($z_idx_low);
|
||||
# $self->slider_high->SetValue($z_idx_high);
|
||||
# $self->slider_low->Show;
|
||||
# $self->slider_high->Show;
|
||||
# $self->set_z_range($self->{layers_z}[$z_idx_low], $self->{layers_z}[$z_idx_high]);
|
||||
|
||||
Slic3r::GUI::update_double_slider($self->{force_sliders_full_range});
|
||||
$self->double_slider_sizer->Show(0);
|
||||
|
||||
$self->Layout;
|
||||
}
|
||||
|
||||
|
@ -5418,6 +5418,7 @@ void GLCanvas3D::_on_select(int volume_idx, int object_idx)
|
||||
}
|
||||
|
||||
m_on_select_object_callback.call(obj_id, vol_id);
|
||||
Slic3r::GUI::select_current_volume(obj_id, vol_id);
|
||||
}
|
||||
|
||||
std::vector<float> GLCanvas3D::_parse_colors(const std::vector<std::string>& colors)
|
||||
|
@ -116,7 +116,6 @@ wxNotebook *g_wxTabPanel = nullptr;
|
||||
AppConfig *g_AppConfig = nullptr;
|
||||
PresetBundle *g_PresetBundle= nullptr;
|
||||
PresetUpdater *g_PresetUpdater = nullptr;
|
||||
_3DScene *g_3DScene = nullptr;
|
||||
wxColour g_color_label_modified;
|
||||
wxColour g_color_label_sys;
|
||||
wxColour g_color_label_default;
|
||||
@ -136,14 +135,9 @@ wxButton* g_wiping_dialog_button = nullptr;
|
||||
//showed/hided controls according to the view mode
|
||||
wxWindow *g_right_panel = nullptr;
|
||||
wxBoxSizer *g_frequently_changed_parameters_sizer = nullptr;
|
||||
wxBoxSizer *g_expert_mode_part_sizer = nullptr;
|
||||
wxBoxSizer *g_scrolled_window_sizer = nullptr;
|
||||
wxBoxSizer *g_info_sizer = nullptr;
|
||||
wxBoxSizer *g_object_list_sizer = nullptr;
|
||||
wxButton *g_btn_export_gcode = nullptr;
|
||||
wxButton *g_btn_export_stl = nullptr;
|
||||
wxButton *g_btn_reslice = nullptr;
|
||||
wxButton *g_btn_print = nullptr;
|
||||
wxButton *g_btn_send_gcode = nullptr;
|
||||
std::vector<wxButton*> g_buttons;
|
||||
wxStaticBitmap *g_manifold_warning_icon = nullptr;
|
||||
bool g_show_print_info = false;
|
||||
bool g_show_manifold_warning_icon = false;
|
||||
@ -224,27 +218,36 @@ void set_preset_updater(PresetUpdater *updater)
|
||||
g_PresetUpdater = updater;
|
||||
}
|
||||
|
||||
void set_3DScene(_3DScene *scene)
|
||||
enum ActionButtons
|
||||
{
|
||||
g_3DScene = scene;
|
||||
}
|
||||
abExportGCode,
|
||||
abReslice,
|
||||
abPrint,
|
||||
abSendGCode,
|
||||
};
|
||||
|
||||
void set_objects_from_perl( wxWindow* parent, wxBoxSizer *frequently_changed_parameters_sizer,
|
||||
wxBoxSizer *expert_mode_part_sizer, wxBoxSizer *scrolled_window_sizer,
|
||||
void set_objects_from_perl( wxWindow* parent,
|
||||
wxBoxSizer *frequently_changed_parameters_sizer,
|
||||
wxBoxSizer *info_sizer,
|
||||
wxButton *btn_export_gcode,
|
||||
wxButton *btn_export_stl, wxButton *btn_reslice,
|
||||
wxButton *btn_print, wxButton *btn_send_gcode,
|
||||
wxButton *btn_reslice,
|
||||
wxButton *btn_print,
|
||||
wxButton *btn_send_gcode,
|
||||
wxStaticBitmap *manifold_warning_icon)
|
||||
{
|
||||
g_right_panel = parent;
|
||||
g_right_panel = parent->GetParent();
|
||||
g_frequently_changed_parameters_sizer = frequently_changed_parameters_sizer;
|
||||
g_expert_mode_part_sizer = expert_mode_part_sizer;
|
||||
g_scrolled_window_sizer = scrolled_window_sizer;
|
||||
g_btn_export_gcode = btn_export_gcode;
|
||||
g_btn_export_stl = btn_export_stl;
|
||||
g_btn_reslice = btn_reslice;
|
||||
g_btn_print = btn_print;
|
||||
g_btn_send_gcode = btn_send_gcode;
|
||||
g_info_sizer = info_sizer;
|
||||
|
||||
g_buttons.push_back(btn_export_gcode);
|
||||
g_buttons.push_back(btn_reslice);
|
||||
g_buttons.push_back(btn_print);
|
||||
g_buttons.push_back(btn_send_gcode);
|
||||
|
||||
// Update font style for buttons
|
||||
for (auto btn : g_buttons)
|
||||
btn->SetFont(bold_font());
|
||||
|
||||
g_manifold_warning_icon = manifold_warning_icon;
|
||||
}
|
||||
|
||||
@ -934,12 +937,11 @@ wxString from_u8(const std::string &str)
|
||||
return wxString::FromUTF8(str.c_str());
|
||||
}
|
||||
|
||||
void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer,
|
||||
Model &model,
|
||||
int event_object_selection_changed,
|
||||
int event_object_settings_changed,
|
||||
int event_remove_object,
|
||||
int event_update_scene)
|
||||
void set_model_events_from_perl(Model &model,
|
||||
int event_object_selection_changed,
|
||||
int event_object_settings_changed,
|
||||
int event_remove_object,
|
||||
int event_update_scene)
|
||||
{
|
||||
set_event_object_selection_changed(event_object_selection_changed);
|
||||
set_event_object_settings_changed(event_object_settings_changed);
|
||||
@ -1076,7 +1078,7 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl
|
||||
};
|
||||
optgroup->append_line(line);
|
||||
|
||||
sizer->Add(optgroup->sizer, 0, wxEXPAND | wxBOTTOM, 2);
|
||||
sizer->Add(optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT, 2);
|
||||
|
||||
m_optgroups.push_back(optgroup);// ogFrequentlyChangingParameters
|
||||
|
||||
@ -1103,25 +1105,24 @@ void show_frequently_changed_parameters(bool show)
|
||||
|
||||
void show_buttons(bool show)
|
||||
{
|
||||
g_btn_export_stl->Show(show);
|
||||
g_btn_reslice->Show(show);
|
||||
g_buttons[abReslice]->Show(show);
|
||||
for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++i) {
|
||||
TabPrinter *tab = dynamic_cast<TabPrinter*>(g_wxTabPanel->GetPage(i));
|
||||
if (!tab)
|
||||
continue;
|
||||
if (g_PresetBundle->printers.get_selected_preset().printer_technology() == ptFFF) {
|
||||
g_btn_print->Show(show && !tab->m_config->opt_string("serial_port").empty());
|
||||
g_btn_send_gcode->Show(show && !tab->m_config->opt_string("print_host").empty());
|
||||
g_buttons[abPrint]->Show(show && !tab->m_config->opt_string("serial_port").empty());
|
||||
g_buttons[abSendGCode]->Show(show && !tab->m_config->opt_string("print_host").empty());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void show_info_sizer(bool show)
|
||||
void show_info_sizer(const bool show, const bool is_update_settings/* = false*/)
|
||||
{
|
||||
g_scrolled_window_sizer->Show(static_cast<size_t>(0), show);
|
||||
g_scrolled_window_sizer->Show(1, show && g_show_print_info);
|
||||
g_manifold_warning_icon->Show(show && g_show_manifold_warning_icon);
|
||||
g_info_sizer->Show(static_cast<size_t>(0), show);
|
||||
g_info_sizer->Show(1, show && g_show_print_info);
|
||||
g_manifold_warning_icon->Show(show && (!is_update_settings && g_show_manifold_warning_icon));
|
||||
}
|
||||
|
||||
void show_object_name(bool show)
|
||||
@ -1133,20 +1134,10 @@ void show_object_name(bool show)
|
||||
|
||||
void update_mode()
|
||||
{
|
||||
wxWindowUpdateLocker noUpdates(g_right_panel);
|
||||
|
||||
// TODO There is a not the best place of it!
|
||||
//*** Update style of the "Export G-code" button****
|
||||
if (g_btn_export_gcode->GetFont() != bold_font()){
|
||||
g_btn_export_gcode->SetBackgroundColour(wxColour(252, 77, 1));
|
||||
g_btn_export_gcode->SetFont(bold_font());
|
||||
}
|
||||
// ***********************************
|
||||
wxWindowUpdateLocker noUpdates(g_right_panel->GetParent());
|
||||
|
||||
ConfigMenuIDs mode = get_view_mode();
|
||||
|
||||
// show_frequently_changed_parameters(mode >= ConfigMenuModeRegular);
|
||||
// g_expert_mode_part_sizer->Show(mode == ConfigMenuModeExpert);
|
||||
g_object_list_sizer->Show(mode == ConfigMenuModeExpert);
|
||||
show_info_sizer(mode == ConfigMenuModeExpert);
|
||||
show_buttons(mode == ConfigMenuModeExpert);
|
||||
@ -1157,7 +1148,7 @@ void update_mode()
|
||||
// show_collpane_settings(mode == ConfigMenuModeExpert);
|
||||
// *************************
|
||||
g_right_panel->Layout();
|
||||
g_right_panel->GetParent()->GetParent()->Layout();
|
||||
g_right_panel->GetParent()->Layout();
|
||||
}
|
||||
|
||||
bool is_expert_mode(){
|
||||
@ -1233,6 +1224,20 @@ void get_current_screen_size(unsigned &width, unsigned &height)
|
||||
height = disp_size.GetHeight();
|
||||
}
|
||||
|
||||
void enable_action_buttons(bool enable)
|
||||
{
|
||||
if (g_buttons.empty())
|
||||
return;
|
||||
|
||||
// Update background colour for buttons
|
||||
const wxColour bgrd_color = enable ? wxColour(224, 224, 224/*255, 96, 0*/) : wxColour(204, 204, 204);
|
||||
|
||||
for (auto btn : g_buttons) {
|
||||
btn->Enable(enable);
|
||||
btn->SetBackgroundColour(bgrd_color);
|
||||
}
|
||||
}
|
||||
|
||||
void about()
|
||||
{
|
||||
AboutDialog dlg;
|
||||
|
@ -35,7 +35,6 @@ class AppConfig;
|
||||
class PresetUpdater;
|
||||
class DynamicPrintConfig;
|
||||
class TabIface;
|
||||
class _3DScene;
|
||||
|
||||
#define _(s) Slic3r::GUI::I18N::translate((s))
|
||||
|
||||
@ -101,13 +100,10 @@ void set_tab_panel(wxNotebook *tab_panel);
|
||||
void set_app_config(AppConfig *app_config);
|
||||
void set_preset_bundle(PresetBundle *preset_bundle);
|
||||
void set_preset_updater(PresetUpdater *updater);
|
||||
void set_3DScene(_3DScene *scene);
|
||||
void set_objects_from_perl( wxWindow* parent,
|
||||
wxBoxSizer *frequently_changed_parameters_sizer,
|
||||
wxBoxSizer *expert_mode_part_sizer,
|
||||
wxBoxSizer *scrolled_window_sizer,
|
||||
wxBoxSizer *info_sizer,
|
||||
wxButton *btn_export_gcode,
|
||||
wxButton *btn_export_stl,
|
||||
wxButton *btn_reslice,
|
||||
wxButton *btn_print,
|
||||
wxButton *btn_send_gcode,
|
||||
@ -186,6 +182,8 @@ bool select_language(wxArrayString & names, wxArrayLong & identifiers);
|
||||
// update right panel of the Plater according to view mode
|
||||
void update_mode();
|
||||
|
||||
void show_info_sizer(const bool show, const bool is_update_settinfs = false);
|
||||
|
||||
std::vector<Tab *>& get_tabs_list();
|
||||
bool checked_tab(Tab* tab);
|
||||
void delete_tab_from_list(Tab* tab);
|
||||
@ -204,12 +202,11 @@ wxString L_str(const std::string &str);
|
||||
// Return wxString from std::string in UTF8
|
||||
wxString from_u8(const std::string &str);
|
||||
|
||||
void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer,
|
||||
Model &model,
|
||||
int event_object_selection_changed,
|
||||
int event_object_settings_changed,
|
||||
int event_remove_object,
|
||||
int event_update_scene);
|
||||
void set_model_events_from_perl(Model &model,
|
||||
int event_object_selection_changed,
|
||||
int event_object_settings_changed,
|
||||
int event_remove_object,
|
||||
int event_update_scene);
|
||||
void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer);
|
||||
// Update view mode according to selected menu
|
||||
void update_mode();
|
||||
@ -228,6 +225,9 @@ int get_export_option(wxFileDialog* dlg);
|
||||
// Returns the dimensions of the screen on which the main frame is displayed
|
||||
void get_current_screen_size(unsigned &width, unsigned &height);
|
||||
|
||||
// Update buttons view according to enable/disable
|
||||
void enable_action_buttons(bool enable);
|
||||
|
||||
// Display an About dialog
|
||||
extern void about();
|
||||
// Ask the destop to open the datadir using the default file explorer.
|
||||
|
@ -13,6 +13,9 @@
|
||||
#include "Geometry.hpp"
|
||||
#include "slic3r/Utils/FixModelByWin10.hpp"
|
||||
|
||||
#include <wx/glcanvas.h>
|
||||
#include "3DScene.hpp"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
namespace GUI
|
||||
@ -23,10 +26,12 @@ wxSizer *m_sizer_object_movers = nullptr;
|
||||
wxDataViewCtrl *m_objects_ctrl = nullptr;
|
||||
PrusaObjectDataViewModel *m_objects_model = nullptr;
|
||||
wxCollapsiblePane *m_collpane_settings = nullptr;
|
||||
PrusaDoubleSlider *m_slider = nullptr;
|
||||
wxGLCanvas *m_preview_canvas = nullptr;
|
||||
|
||||
wxIcon m_icon_modifiermesh;
|
||||
wxIcon m_icon_solidmesh;
|
||||
wxIcon m_icon_manifold_warning;
|
||||
wxBitmap m_icon_modifiermesh;
|
||||
wxBitmap m_icon_solidmesh;
|
||||
wxBitmap m_icon_manifold_warning;
|
||||
wxBitmap m_bmp_cog;
|
||||
wxBitmap m_bmp_split;
|
||||
|
||||
@ -64,8 +69,6 @@ bool m_part_settings_changed = false;
|
||||
wxString g_selected_extruder = "";
|
||||
#endif //__WXOSX__
|
||||
|
||||
// typedef std::map<std::string, std::string> t_category_icon;
|
||||
typedef std::map<std::string, wxBitmap> t_category_icon;
|
||||
inline t_category_icon& get_category_icon() {
|
||||
static t_category_icon CATEGORY_ICON;
|
||||
if (CATEGORY_ICON.empty()){
|
||||
@ -138,11 +141,11 @@ void set_objects_from_model(Model &model) {
|
||||
}
|
||||
|
||||
void init_mesh_icons(){
|
||||
m_icon_modifiermesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG);
|
||||
m_icon_solidmesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG);
|
||||
m_icon_modifiermesh = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG);
|
||||
m_icon_solidmesh = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG);
|
||||
|
||||
// init icon for manifold warning
|
||||
m_icon_manifold_warning = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("exclamation_mark_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG);
|
||||
m_icon_manifold_warning = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("exclamation_mark_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG);
|
||||
|
||||
// init bitmap for "Split to sub-objects" context menu
|
||||
m_bmp_split = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("split.png")), wxBITMAP_TYPE_PNG);
|
||||
@ -233,7 +236,7 @@ wxDataViewColumn* object_ctrl_create_extruder_column(int extruders_count)
|
||||
void create_objects_ctrl(wxWindow* win, wxBoxSizer*& objects_sz)
|
||||
{
|
||||
m_objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
m_objects_ctrl->SetInitialSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects
|
||||
m_objects_ctrl->SetMinSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects
|
||||
|
||||
objects_sz = new wxBoxSizer(wxVERTICAL);
|
||||
objects_sz->Add(m_objects_ctrl, 1, wxGROW | wxLEFT, 20);
|
||||
@ -245,9 +248,10 @@ void create_objects_ctrl(wxWindow* win, wxBoxSizer*& objects_sz)
|
||||
m_objects_ctrl->EnableDropTarget(wxDF_UNICODETEXT);
|
||||
#endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE
|
||||
|
||||
// column 0(Icon+Text) of the view control:
|
||||
m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 200,
|
||||
wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE);
|
||||
// column 0(Icon+Text) of the view control:
|
||||
// And Icon can be consisting of several bitmaps
|
||||
m_objects_ctrl->AppendColumn(new wxDataViewColumn(_(L("Name")), new PrusaBitmapTextRenderer(),
|
||||
0, 200, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE));
|
||||
|
||||
// column 1 of the view control:
|
||||
m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 45,
|
||||
@ -278,7 +282,7 @@ wxBoxSizer* create_objects_list(wxWindow *win)
|
||||
|
||||
m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, [](wxDataViewEvent& event) {
|
||||
object_ctrl_context_menu();
|
||||
event.Skip();
|
||||
// event.Skip();
|
||||
});
|
||||
|
||||
m_objects_ctrl->Bind(wxEVT_CHAR, [](wxKeyEvent& event) { object_ctrl_key_event(event); }); // doesn't work on OSX
|
||||
@ -316,15 +320,15 @@ wxBoxSizer* create_edit_object_buttons(wxWindow* win)
|
||||
|
||||
//*** button's functions
|
||||
btn_load_part->Bind(wxEVT_BUTTON, [win](wxEvent&) {
|
||||
on_btn_load(win);
|
||||
// on_btn_load(win);
|
||||
});
|
||||
|
||||
btn_load_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) {
|
||||
on_btn_load(win, true);
|
||||
// on_btn_load(win, true);
|
||||
});
|
||||
|
||||
btn_load_lambda_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) {
|
||||
on_btn_load(win, true, true);
|
||||
// on_btn_load(win, true, true);
|
||||
});
|
||||
|
||||
btn_delete ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_del(); });
|
||||
@ -663,7 +667,7 @@ void add_object_to_list(const std::string &name, ModelObject* model_object)
|
||||
int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed +
|
||||
stats.facets_added + stats.facets_reversed + stats.backwards_edges;
|
||||
if (errors > 0) {
|
||||
const wxDataViewIconText data(item_name, m_icon_manifold_warning);
|
||||
const PrusaDataViewBitmapText data(item_name, m_icon_manifold_warning);
|
||||
wxVariant variant;
|
||||
variant << data;
|
||||
m_objects_model->SetValue(variant, item, 0);
|
||||
@ -736,6 +740,24 @@ void select_current_object(int idx)
|
||||
g_prevent_list_events = false;
|
||||
}
|
||||
|
||||
void select_current_volume(int idx, int vol_idx)
|
||||
{
|
||||
if (vol_idx < 0) {
|
||||
select_current_object(idx);
|
||||
return;
|
||||
}
|
||||
g_prevent_list_events = true;
|
||||
m_objects_ctrl->UnselectAll();
|
||||
if (idx < 0) {
|
||||
g_prevent_list_events = false;
|
||||
return;
|
||||
}
|
||||
|
||||
m_objects_ctrl->Select(m_objects_model->GetItemByVolumeId(idx, vol_idx));
|
||||
part_selection_changed();
|
||||
g_prevent_list_events = false;
|
||||
}
|
||||
|
||||
void remove()
|
||||
{
|
||||
auto item = m_objects_ctrl->GetSelection();
|
||||
@ -761,8 +783,17 @@ void object_ctrl_selection_changed()
|
||||
|
||||
if (m_event_object_selection_changed > 0) {
|
||||
wxCommandEvent event(m_event_object_selection_changed);
|
||||
event.SetInt(int(m_objects_model->GetParent(m_objects_ctrl->GetSelection()) != wxDataViewItem(0)));
|
||||
event.SetId(m_selected_object_id);
|
||||
event.SetId(m_selected_object_id); // set $obj_idx
|
||||
const wxDataViewItem item = m_objects_ctrl->GetSelection();
|
||||
if (!item || m_objects_model->GetParent(item) == wxDataViewItem(0))
|
||||
event.SetInt(-1); // set $vol_idx
|
||||
else {
|
||||
const int vol_idx = m_objects_model->GetVolumeIdByItem(item);
|
||||
if (vol_idx == -2) // is settings item
|
||||
event.SetInt(m_objects_model->GetVolumeIdByItem(m_objects_model->GetParent(item))); // set $vol_idx
|
||||
else
|
||||
event.SetInt(vol_idx);
|
||||
}
|
||||
get_main_frame()->ProcessWindowEvent(event);
|
||||
}
|
||||
|
||||
@ -775,9 +806,9 @@ void object_ctrl_context_menu()
|
||||
{
|
||||
wxDataViewItem item;
|
||||
wxDataViewColumn* col;
|
||||
printf("object_ctrl_context_menu\n");
|
||||
// printf("object_ctrl_context_menu\n");
|
||||
const wxPoint pt = get_mouse_position_in_control();
|
||||
printf("mouse_position_in_control: x = %d, y = %d\n", pt.x, pt.y);
|
||||
// printf("mouse_position_in_control: x = %d, y = %d\n", pt.x, pt.y);
|
||||
m_objects_ctrl->HitTest(pt, item, col);
|
||||
if (!item)
|
||||
#ifdef __WXOSX__ // #ys_FIXME temporary workaround for OSX
|
||||
@ -791,9 +822,9 @@ void object_ctrl_context_menu()
|
||||
#else
|
||||
return;
|
||||
#endif // __WXOSX__
|
||||
printf("item exists\n");
|
||||
// printf("item exists\n");
|
||||
const wxString title = col->GetTitle();
|
||||
printf("title = *%s*\n", title.data().AsChar());
|
||||
// printf("title = *%s*\n", title.data().AsChar());
|
||||
|
||||
if (title == " ")
|
||||
show_context_menu();
|
||||
@ -839,6 +870,15 @@ void object_ctrl_item_value_change(wxDataViewEvent& event)
|
||||
}
|
||||
}
|
||||
|
||||
void show_manipulation_og(const bool show)
|
||||
{
|
||||
wxGridSizer* grid_sizer = get_optgroup(ogFrequentlyObjectSettings)->get_grid_sizer();
|
||||
if (show == grid_sizer->IsShown(2))
|
||||
return;
|
||||
for (size_t id = 2; id < 12; id++)
|
||||
grid_sizer->Show(id, show);
|
||||
}
|
||||
|
||||
//update_optgroup
|
||||
void update_settings_list()
|
||||
{
|
||||
@ -859,14 +899,19 @@ void update_settings_list()
|
||||
|
||||
m_option_sizer->Clear(true);
|
||||
|
||||
if (m_config)
|
||||
bool show_manipulations = true;
|
||||
const auto item = m_objects_ctrl->GetSelection();
|
||||
if (m_config && m_objects_model->IsSettingsItem(item))
|
||||
{
|
||||
auto extra_column = [](wxWindow* parent, const Line& line)
|
||||
{
|
||||
auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line
|
||||
|
||||
auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("erase.png")), wxBITMAP_TYPE_PNG),
|
||||
auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(from_u8(var("colorchange_delete_on.png")), wxBITMAP_TYPE_PNG),
|
||||
wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
|
||||
#ifdef __WXMSW__
|
||||
btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
#endif // __WXMSW__
|
||||
btn->Bind(wxEVT_BUTTON, [opt_key](wxEvent &event){
|
||||
(*m_config)->erase(opt_key);
|
||||
wxTheApp->CallAfter([]() { update_settings_list(); });
|
||||
@ -876,60 +921,75 @@ void update_settings_list()
|
||||
|
||||
std::map<std::string, std::vector<std::string>> cat_options;
|
||||
auto opt_keys = (*m_config)->keys();
|
||||
if (opt_keys.size() == 1 && opt_keys[0] == "extruder")
|
||||
return;
|
||||
m_og_settings.resize(0);
|
||||
std::vector<std::string> categories;
|
||||
if (!(opt_keys.size() == 1 && opt_keys[0] == "extruder"))// return;
|
||||
{
|
||||
auto extruders_cnt = get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA ? 1 :
|
||||
get_preset_bundle()->printers.get_edited_preset().config.option<ConfigOptionFloats>("nozzle_diameter")->values.size();
|
||||
|
||||
auto extruders_cnt = get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA ? 1 :
|
||||
get_preset_bundle()->printers.get_edited_preset().config.option<ConfigOptionFloats>("nozzle_diameter")->values.size();
|
||||
for (auto& opt_key : opt_keys) {
|
||||
auto category = (*m_config)->def()->get(opt_key)->category;
|
||||
if (category.empty() ||
|
||||
(category == "Extruders" && extruders_cnt == 1)) continue;
|
||||
|
||||
for (auto& opt_key : opt_keys) {
|
||||
auto category = (*m_config)->def()->get(opt_key)->category;
|
||||
if (category.empty() ||
|
||||
(category == "Extruders" && extruders_cnt==1)) continue;
|
||||
std::vector< std::string > new_category;
|
||||
|
||||
std::vector< std::string > new_category;
|
||||
auto& cat_opt = cat_options.find(category) == cat_options.end() ? new_category : cat_options.at(category);
|
||||
cat_opt.push_back(opt_key);
|
||||
if (cat_opt.size() == 1)
|
||||
cat_options[category] = cat_opt;
|
||||
}
|
||||
|
||||
auto& cat_opt = cat_options.find(category) == cat_options.end() ? new_category : cat_options.at(category);
|
||||
cat_opt.push_back(opt_key);
|
||||
if (cat_opt.size() == 1)
|
||||
cat_options[category] = cat_opt;
|
||||
}
|
||||
for (auto& cat : cat_options) {
|
||||
if (cat.second.size() == 1 && cat.second[0] == "extruder")
|
||||
continue;
|
||||
|
||||
auto optgroup = std::make_shared<ConfigOptionsGroup>(parent, cat.first, *m_config, false, ogDEFAULT, extra_column);
|
||||
optgroup->label_width = 150;
|
||||
optgroup->sidetext_width = 70;
|
||||
|
||||
m_og_settings.resize(0);
|
||||
for (auto& cat : cat_options) {
|
||||
if (cat.second.size() == 1 && cat.second[0] == "extruder")
|
||||
continue;
|
||||
for (auto& opt : cat.second)
|
||||
{
|
||||
if (opt == "extruder")
|
||||
continue;
|
||||
Option option = optgroup->get_option(opt);
|
||||
option.opt.width = 70;
|
||||
optgroup->append_single_option_line(option);
|
||||
}
|
||||
optgroup->reload_config();
|
||||
m_option_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0);
|
||||
m_og_settings.push_back(optgroup);
|
||||
|
||||
auto optgroup = std::make_shared<ConfigOptionsGroup>(parent, cat.first, *m_config, false, ogDEFAULT, extra_column);
|
||||
optgroup->label_width = 100;
|
||||
optgroup->sidetext_width = 70;
|
||||
categories.push_back(cat.first);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& opt : cat.second)
|
||||
{
|
||||
if (opt == "extruder")
|
||||
continue;
|
||||
Option option = optgroup->get_option(opt);
|
||||
option.opt.width = 70;
|
||||
optgroup->append_single_option_line(option);
|
||||
}
|
||||
optgroup->reload_config();
|
||||
m_option_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0);
|
||||
m_og_settings.push_back(optgroup);
|
||||
}
|
||||
if (m_og_settings.empty()) {
|
||||
m_objects_ctrl->Select(m_objects_model->Delete(item));
|
||||
part_selection_changed();
|
||||
}
|
||||
else {
|
||||
if (!categories.empty())
|
||||
m_objects_model->UpdateSettingsDigest(item, categories);
|
||||
show_manipulations = false;
|
||||
}
|
||||
}
|
||||
|
||||
show_manipulation_og(show_manipulations);
|
||||
show_info_sizer(show_manipulations && item && m_objects_model->GetParent(item) == wxDataViewItem(0));
|
||||
|
||||
#ifdef __linux__
|
||||
no_updates.reset(nullptr);
|
||||
#endif
|
||||
|
||||
/*get_right_panel()*/parent->Layout();
|
||||
get_right_panel()->GetParent()->GetParent()->Layout();
|
||||
parent->Layout();
|
||||
get_right_panel()->GetParent()->Layout();
|
||||
}
|
||||
|
||||
void get_settings_choice(wxMenu *menu, int id, bool is_part)
|
||||
{
|
||||
auto category_name = menu->GetLabel(id);
|
||||
const auto category_name = menu->GetLabel(id);
|
||||
|
||||
wxArrayString names;
|
||||
wxArrayInt selections;
|
||||
@ -977,15 +1037,35 @@ void get_settings_choice(wxMenu *menu, int id, bool is_part)
|
||||
(*m_config)->set_key_value(opt_key, m_default_config.get()->option(opt_key)->clone());
|
||||
}
|
||||
|
||||
|
||||
// Add settings item for object
|
||||
const auto item = m_objects_ctrl->GetSelection();
|
||||
if (item) {
|
||||
const auto settings_item = m_objects_model->HasSettings(item);
|
||||
m_objects_ctrl->Select(settings_item ? settings_item :
|
||||
m_objects_model->AddSettingsChild(item));
|
||||
#ifndef __WXOSX__
|
||||
part_selection_changed();
|
||||
#endif //no __WXOSX__
|
||||
}
|
||||
else
|
||||
update_settings_list();
|
||||
}
|
||||
|
||||
bool cur_item_hase_children()
|
||||
{
|
||||
wxDataViewItemArray children;
|
||||
if (m_objects_model->GetChildren(m_objects_ctrl->GetSelection(), children) > 0)
|
||||
return true;
|
||||
return false;
|
||||
void menu_item_add_generic(wxMenuItem* &menu, int id) {
|
||||
auto sub_menu = new wxMenu;
|
||||
|
||||
std::vector<std::string> menu_items = { L("Box"), L("Cylinder"), L("Sphere"), L("Slab") };
|
||||
for (auto& item : menu_items)
|
||||
sub_menu->Append(new wxMenuItem(sub_menu, ++id, _(item)));
|
||||
|
||||
#ifndef __WXMSW__
|
||||
sub_menu->Bind(wxEVT_MENU, [sub_menu](wxEvent &event) {
|
||||
load_lambda(sub_menu->GetLabel(event.GetId()).ToStdString());
|
||||
});
|
||||
#endif //no __WXMSW__
|
||||
|
||||
menu->SetSubMenu(sub_menu);
|
||||
}
|
||||
|
||||
wxMenuItem* menu_item_split(wxMenu* menu, int id) {
|
||||
@ -994,11 +1074,11 @@ wxMenuItem* menu_item_split(wxMenu* menu, int id) {
|
||||
return menu_item;
|
||||
}
|
||||
|
||||
wxMenuItem* menu_item_settings(wxMenu* menu, int id) {
|
||||
wxMenuItem* menu_item_settings(wxMenu* menu, int id, const bool is_part) {
|
||||
auto menu_item = new wxMenuItem(menu, id, _(L("Add settings")));
|
||||
menu_item->SetBitmap(m_bmp_cog);
|
||||
|
||||
auto sub_menu = create_add_settings_popupmenu(false);
|
||||
auto sub_menu = create_add_settings_popupmenu(is_part);
|
||||
menu_item->SetSubMenu(sub_menu);
|
||||
return menu_item;
|
||||
}
|
||||
@ -1008,44 +1088,54 @@ wxMenu *create_add_part_popupmenu()
|
||||
wxMenu *menu = new wxMenu;
|
||||
std::vector<std::string> menu_items = { L("Add part"), L("Add modifier"), L("Add generic") };
|
||||
|
||||
wxWindowID config_id_base = wxWindow::NewControlId(menu_items.size()+2);
|
||||
wxWindowID config_id_base = wxWindow::NewControlId(menu_items.size()+4+2);
|
||||
|
||||
int i = 0;
|
||||
for (auto& item : menu_items) {
|
||||
auto menu_item = new wxMenuItem(menu, config_id_base + i, _(item));
|
||||
menu_item->SetBitmap(i == 0 ? m_icon_solidmesh : m_icon_modifiermesh);
|
||||
menu->Append(menu_item);
|
||||
if (item == "Add generic")
|
||||
menu_item_add_generic(menu_item, config_id_base + i);
|
||||
menu->Append(menu_item);
|
||||
i++;
|
||||
}
|
||||
|
||||
menu->AppendSeparator();
|
||||
auto menu_item = menu_item_split(menu, config_id_base + i);
|
||||
auto menu_item = menu_item_split(menu, config_id_base + i + 4);
|
||||
menu->Append(menu_item);
|
||||
menu_item->Enable(!cur_item_hase_children());
|
||||
menu_item->Enable(is_splittable_object(false));
|
||||
|
||||
menu->AppendSeparator();
|
||||
// Append settings popupmenu
|
||||
menu->Append(menu_item_settings(menu, config_id_base + i + 1));
|
||||
menu->Append(menu_item_settings(menu, config_id_base + i + 5, false));
|
||||
|
||||
wxWindow* win = get_tab_panel()->GetPage(0);
|
||||
|
||||
menu->Bind(wxEVT_MENU, [config_id_base, win, menu](wxEvent &event){
|
||||
menu->Bind(wxEVT_MENU, [config_id_base, menu](wxEvent &event){
|
||||
switch (event.GetId() - config_id_base) {
|
||||
case 0:
|
||||
on_btn_load(win);
|
||||
on_btn_load();
|
||||
break;
|
||||
case 1:
|
||||
on_btn_load(win, true);
|
||||
on_btn_load(true);
|
||||
break;
|
||||
case 2:
|
||||
on_btn_load(win, true, true);
|
||||
// on_btn_load(true, true);
|
||||
break;
|
||||
case 3:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
#ifdef __WXMSW__
|
||||
load_lambda(menu->GetLabel(event.GetId()).ToStdString());
|
||||
#endif // __WXMSW__
|
||||
break;
|
||||
case 7: //3:
|
||||
on_btn_split(false);
|
||||
break;
|
||||
default:{
|
||||
default:
|
||||
#ifdef __WXMSW__
|
||||
get_settings_choice(menu, event.GetId(), false);
|
||||
break;}
|
||||
#endif // __WXMSW__
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
@ -1057,11 +1147,13 @@ wxMenu *create_part_settings_popupmenu()
|
||||
wxMenu *menu = new wxMenu;
|
||||
wxWindowID config_id_base = wxWindow::NewControlId(2);
|
||||
|
||||
menu->Append(menu_item_split(menu, config_id_base));
|
||||
auto menu_item = menu_item_split(menu, config_id_base);
|
||||
menu->Append(menu_item);
|
||||
menu_item->Enable(is_splittable_object(true));
|
||||
|
||||
menu->AppendSeparator();
|
||||
// Append settings popupmenu
|
||||
menu->Append(menu_item_settings(menu, config_id_base + 1));
|
||||
menu->Append(menu_item_settings(menu, config_id_base + 1, true));
|
||||
|
||||
menu->Bind(wxEVT_MENU, [config_id_base, menu](wxEvent &event){
|
||||
switch (event.GetId() - config_id_base) {
|
||||
@ -1093,35 +1185,35 @@ wxMenu *create_add_settings_popupmenu(bool is_part)
|
||||
wxNullBitmap : categories.at(cat.first));
|
||||
menu->Append(menu_item);
|
||||
}
|
||||
|
||||
#ifndef __WXMSW__
|
||||
menu->Bind(wxEVT_MENU, [menu](wxEvent &event) {
|
||||
get_settings_choice(menu, event.GetId(), true);
|
||||
});
|
||||
|
||||
#endif //no __WXMSW__
|
||||
return menu;
|
||||
}
|
||||
|
||||
void show_context_menu()
|
||||
{
|
||||
auto item = m_objects_ctrl->GetSelection();
|
||||
const auto item = m_objects_ctrl->GetSelection();
|
||||
if (item)
|
||||
{
|
||||
if (m_objects_model->GetParent(item) == wxDataViewItem(0)) {
|
||||
auto menu = create_add_part_popupmenu();
|
||||
get_tab_panel()->GetPage(0)->PopupMenu(menu);
|
||||
}
|
||||
else {
|
||||
auto menu = create_part_settings_popupmenu();
|
||||
get_tab_panel()->GetPage(0)->PopupMenu(menu);
|
||||
}
|
||||
if (m_objects_model->IsSettingsItem(item))
|
||||
return;
|
||||
const auto menu = m_objects_model->GetParent(item) == wxDataViewItem(0) ?
|
||||
create_add_part_popupmenu() :
|
||||
create_part_settings_popupmenu();
|
||||
get_tab_panel()->GetPage(0)->PopupMenu(menu);
|
||||
}
|
||||
}
|
||||
|
||||
// ******
|
||||
|
||||
void load_part( wxWindow* parent, ModelObject* model_object,
|
||||
void load_part( ModelObject* model_object,
|
||||
wxArrayString& part_names, const bool is_modifier)
|
||||
{
|
||||
wxWindow* parent = get_tab_panel()->GetPage(0);
|
||||
|
||||
wxArrayString input_files;
|
||||
open_model(parent, input_files);
|
||||
for (int i = 0; i < input_files.size(); ++i) {
|
||||
@ -1159,10 +1251,10 @@ void load_part( wxWindow* parent, ModelObject* model_object,
|
||||
}
|
||||
}
|
||||
|
||||
void load_lambda( wxWindow* parent, ModelObject* model_object,
|
||||
void load_lambda( ModelObject* model_object,
|
||||
wxArrayString& part_names, const bool is_modifier)
|
||||
{
|
||||
auto dlg = new LambdaObjectDialog(parent);
|
||||
auto dlg = new LambdaObjectDialog(m_objects_ctrl->GetMainWindow());
|
||||
if (dlg->ShowModal() == wxID_CANCEL) {
|
||||
return;
|
||||
}
|
||||
@ -1208,7 +1300,49 @@ void load_lambda( wxWindow* parent, ModelObject* model_object,
|
||||
m_parts_changed = true;
|
||||
}
|
||||
|
||||
void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/, bool is_lambda/* = false*/)
|
||||
void load_lambda(const std::string& type_name)
|
||||
{
|
||||
if (m_selected_object_id < 0) return;
|
||||
|
||||
auto dlg = new LambdaObjectDialog(m_objects_ctrl->GetMainWindow(), type_name);
|
||||
if (dlg->ShowModal() == wxID_CANCEL)
|
||||
return;
|
||||
|
||||
const std::string name = "lambda-"+type_name;
|
||||
TriangleMesh mesh;
|
||||
|
||||
const auto params = dlg->ObjectParameters();
|
||||
if (type_name == _("Box"))
|
||||
mesh = make_cube(params.dim[0], params.dim[1], params.dim[2]);
|
||||
else if (type_name == _("Cylinder"))
|
||||
mesh = make_cylinder(params.cyl_r, params.cyl_h);
|
||||
else if (type_name == _("Sphere"))
|
||||
mesh = make_sphere(params.sph_rho);
|
||||
else if (type_name == _("Slab")){
|
||||
const auto& size = (*m_objects)[m_selected_object_id]->bounding_box().size();
|
||||
mesh = make_cube(size(0)*1.5, size(1)*1.5, params.slab_h);
|
||||
// box sets the base coordinate at 0, 0, move to center of plate and move it up to initial_z
|
||||
mesh.translate(-size(0)*1.5 / 2.0, -size(1)*1.5 / 2.0, params.slab_z);
|
||||
}
|
||||
mesh.repair();
|
||||
|
||||
auto new_volume = (*m_objects)[m_selected_object_id]->add_volume(mesh);
|
||||
new_volume->modifier = true;
|
||||
new_volume->name = name;
|
||||
// set a default extruder value, since user can't add it manually
|
||||
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
||||
|
||||
m_parts_changed = true;
|
||||
parts_changed(m_selected_object_id);
|
||||
|
||||
m_objects_ctrl->Select(m_objects_model->AddChild(m_objects_ctrl->GetSelection(),
|
||||
name, m_icon_modifiermesh));
|
||||
#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
|
||||
object_ctrl_selection_changed();
|
||||
#endif //no __WXOSX__ //__WXMSW__
|
||||
}
|
||||
|
||||
void on_btn_load(bool is_modifier /*= false*/, bool is_lambda/* = false*/)
|
||||
{
|
||||
auto item = m_objects_ctrl->GetSelection();
|
||||
if (!item)
|
||||
@ -1222,19 +1356,54 @@ void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/, bool is_lambda/
|
||||
if (obj_idx < 0) return;
|
||||
wxArrayString part_names;
|
||||
if (is_lambda)
|
||||
load_lambda(parent, (*m_objects)[obj_idx], part_names, is_modifier);
|
||||
load_lambda((*m_objects)[obj_idx], part_names, is_modifier);
|
||||
else
|
||||
load_part(parent, (*m_objects)[obj_idx], part_names, is_modifier);
|
||||
load_part((*m_objects)[obj_idx], part_names, is_modifier);
|
||||
|
||||
parts_changed(obj_idx);
|
||||
|
||||
for (int i = 0; i < part_names.size(); ++i)
|
||||
m_objects_ctrl->Select( m_objects_model->AddChild(item, part_names.Item(i),
|
||||
is_modifier ? m_icon_modifiermesh : m_icon_solidmesh));
|
||||
// part_selection_changed();
|
||||
#ifdef __WXMSW__
|
||||
#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
|
||||
object_ctrl_selection_changed();
|
||||
#endif //__WXMSW__
|
||||
#endif //no __WXOSX__//__WXMSW__
|
||||
}
|
||||
|
||||
void remove_settings_from_config()
|
||||
{
|
||||
auto opt_keys = (*m_config)->keys();
|
||||
if (opt_keys.size() == 1 && opt_keys[0] == "extruder")
|
||||
return;
|
||||
int extruder = -1;
|
||||
if ((*m_config)->has("extruder"))
|
||||
extruder = (*m_config)->option<ConfigOptionInt>("extruder")->value;
|
||||
|
||||
(*m_config)->clear();
|
||||
|
||||
if (extruder >=0 )
|
||||
(*m_config)->set_key_value("extruder", new ConfigOptionInt(extruder));
|
||||
}
|
||||
|
||||
bool remove_subobject_from_object(const int volume_id)
|
||||
{
|
||||
const auto volume = (*m_objects)[m_selected_object_id]->volumes[volume_id];
|
||||
|
||||
// if user is deleting the last solid part, throw error
|
||||
int solid_cnt = 0;
|
||||
for (auto vol : (*m_objects)[m_selected_object_id]->volumes)
|
||||
if (!vol->modifier)
|
||||
++solid_cnt;
|
||||
if (!volume->modifier && solid_cnt == 1) {
|
||||
Slic3r::GUI::show_error(nullptr, _(L("You can't delete the last solid part from this object.")));
|
||||
return false;
|
||||
}
|
||||
|
||||
(*m_objects)[m_selected_object_id]->delete_volume(volume_id);
|
||||
m_parts_changed = true;
|
||||
|
||||
parts_changed(m_selected_object_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
void on_btn_del()
|
||||
@ -1242,50 +1411,67 @@ void on_btn_del()
|
||||
auto item = m_objects_ctrl->GetSelection();
|
||||
if (!item) return;
|
||||
|
||||
auto volume_id = m_objects_model->GetVolumeIdByItem(item);
|
||||
if (volume_id < 0)
|
||||
const auto volume_id = m_objects_model->GetVolumeIdByItem(item);
|
||||
if (volume_id ==-1)
|
||||
return;
|
||||
auto volume = (*m_objects)[m_selected_object_id]->volumes[volume_id];
|
||||
|
||||
// if user is deleting the last solid part, throw error
|
||||
int solid_cnt = 0;
|
||||
for (auto vol : (*m_objects)[m_selected_object_id]->volumes)
|
||||
if (!vol->modifier)
|
||||
++solid_cnt;
|
||||
if (!volume->modifier && solid_cnt == 1) {
|
||||
Slic3r::GUI::show_error(nullptr, _(L("You can't delete the last solid part from this object.")));
|
||||
return;
|
||||
}
|
||||
|
||||
(*m_objects)[m_selected_object_id]->delete_volume(volume_id);
|
||||
m_parts_changed = true;
|
||||
|
||||
parts_changed(m_selected_object_id);
|
||||
|
||||
if (volume_id ==-2)
|
||||
remove_settings_from_config();
|
||||
else if (!remove_subobject_from_object(volume_id))
|
||||
return;
|
||||
|
||||
m_objects_ctrl->Select(m_objects_model->Delete(item));
|
||||
part_selection_changed();
|
||||
// #ifdef __WXMSW__
|
||||
// object_ctrl_selection_changed();
|
||||
// #endif //__WXMSW__
|
||||
}
|
||||
|
||||
bool get_volume_by_item(const bool split_part, const wxDataViewItem& item, ModelVolume*& volume)
|
||||
{
|
||||
if (!item || m_selected_object_id < 0)
|
||||
return false;
|
||||
const auto volume_id = m_objects_model->GetVolumeIdByItem(item);
|
||||
if (volume_id < 0) {
|
||||
if (split_part) return false;
|
||||
volume = (*m_objects)[m_selected_object_id]->volumes[0];
|
||||
}
|
||||
else
|
||||
volume = (*m_objects)[m_selected_object_id]->volumes[volume_id];
|
||||
if (volume)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_splittable_object(const bool split_part)
|
||||
{
|
||||
const wxDataViewItem item = m_objects_ctrl->GetSelection();
|
||||
if (!item) return false;
|
||||
|
||||
wxDataViewItemArray children;
|
||||
if (!split_part && m_objects_model->GetChildren(item, children) > 0)
|
||||
return false;
|
||||
|
||||
ModelVolume* volume;
|
||||
if (!get_volume_by_item(split_part, item, volume) || !volume)
|
||||
return false;
|
||||
|
||||
TriangleMeshPtrs meshptrs = volume->mesh.split();
|
||||
if (meshptrs.size() <= 1) {
|
||||
delete meshptrs.front();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void on_btn_split(const bool split_part)
|
||||
{
|
||||
auto item = m_objects_ctrl->GetSelection();
|
||||
const auto item = m_objects_ctrl->GetSelection();
|
||||
if (!item || m_selected_object_id<0)
|
||||
return;
|
||||
auto volume_id = m_objects_model->GetVolumeIdByItem(item);
|
||||
ModelVolume* volume;
|
||||
if (volume_id < 0) {
|
||||
if (split_part) return;
|
||||
else
|
||||
volume = (*m_objects)[m_selected_object_id]->volumes[0]; }
|
||||
else
|
||||
volume = (*m_objects)[m_selected_object_id]->volumes[volume_id];
|
||||
DynamicPrintConfig& config = get_preset_bundle()->printers.get_edited_preset().config;
|
||||
auto nozzle_dmrs_cnt = config.option<ConfigOptionFloats>("nozzle_diameter")->values.size();
|
||||
auto split_rez = volume->split(nozzle_dmrs_cnt);
|
||||
if (split_rez == 1) {
|
||||
if (!get_volume_by_item(split_part, item, volume)) return;
|
||||
DynamicPrintConfig& config = get_preset_bundle()->printers.get_edited_preset().config;
|
||||
const auto nozzle_dmrs_cnt = config.option<ConfigOptionFloats>("nozzle_diameter")->values.size();
|
||||
if (volume->split(nozzle_dmrs_cnt) == 1) {
|
||||
wxMessageBox(_(L("The selected object couldn't be split because it contains only one part.")));
|
||||
return;
|
||||
}
|
||||
@ -1299,7 +1485,8 @@ void on_btn_split(const bool split_part)
|
||||
for (auto id = 0; id < model_object->volumes.size(); id++)
|
||||
m_objects_model->AddChild(parent, model_object->volumes[id]->name,
|
||||
model_object->volumes[id]->modifier ? m_icon_modifiermesh : m_icon_solidmesh,
|
||||
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value,
|
||||
model_object->volumes[id]->config.has("extruder") ?
|
||||
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value : 0,
|
||||
false);
|
||||
|
||||
m_objects_ctrl->Expand(parent);
|
||||
@ -1308,10 +1495,14 @@ void on_btn_split(const bool split_part)
|
||||
for (auto id = 0; id < model_object->volumes.size(); id++)
|
||||
m_objects_model->AddChild(item, model_object->volumes[id]->name,
|
||||
m_icon_solidmesh,
|
||||
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value,
|
||||
model_object->volumes[id]->config.has("extruder") ?
|
||||
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value : 0,
|
||||
false);
|
||||
m_objects_ctrl->Expand(item);
|
||||
}
|
||||
|
||||
m_parts_changed = true;
|
||||
parts_changed(m_selected_object_id);
|
||||
}
|
||||
|
||||
void on_btn_move_up(){
|
||||
@ -1392,33 +1583,49 @@ void part_selection_changed()
|
||||
auto item = m_objects_ctrl->GetSelection();
|
||||
int obj_idx = -1;
|
||||
auto og = get_optgroup(ogFrequentlyObjectSettings);
|
||||
m_config = nullptr;
|
||||
wxString object_name = wxEmptyString;
|
||||
if (item)
|
||||
{
|
||||
const bool is_settings_item = m_objects_model->IsSettingsItem(item);
|
||||
bool is_part = false;
|
||||
if (m_objects_model->GetParent(item) == wxDataViewItem(0)) {
|
||||
wxString og_name = wxEmptyString;
|
||||
if (m_objects_model->GetParent(item) == wxDataViewItem(0)) {
|
||||
obj_idx = m_objects_model->GetIdByItem(item);
|
||||
og->set_name(" " + _(L("Object Settings")) + " ");
|
||||
og_name = _(L("Object manipulation"));
|
||||
m_config = std::make_shared<DynamicPrintConfig*>(&(*m_objects)[obj_idx]->config);
|
||||
}
|
||||
else {
|
||||
auto parent = m_objects_model->GetParent(item);
|
||||
// Take ID of the parent object to "inform" perl-side which object have to be selected on the scene
|
||||
// Take ID of the parent object to "inform" perl-side which object have to be selected on the scene
|
||||
obj_idx = m_objects_model->GetIdByItem(parent);
|
||||
og->set_name(" " + _(L("Part Settings")) + " ");
|
||||
is_part = true;
|
||||
auto volume_id = m_objects_model->GetVolumeIdByItem(item);
|
||||
m_config = std::make_shared<DynamicPrintConfig*>(&(*m_objects)[obj_idx]->volumes[volume_id]->config);
|
||||
if (is_settings_item) {
|
||||
if (m_objects_model->GetParent(parent) == wxDataViewItem(0)) {
|
||||
og_name = _(L("Object Settings to modify"));
|
||||
m_config = std::make_shared<DynamicPrintConfig*>(&(*m_objects)[obj_idx]->config);
|
||||
}
|
||||
else {
|
||||
og_name = _(L("Part Settings to modify"));
|
||||
is_part = true;
|
||||
auto main_parent = m_objects_model->GetParent(parent);
|
||||
obj_idx = m_objects_model->GetIdByItem(main_parent);
|
||||
const auto volume_id = m_objects_model->GetVolumeIdByItem(parent);
|
||||
m_config = std::make_shared<DynamicPrintConfig*>(&(*m_objects)[obj_idx]->volumes[volume_id]->config);
|
||||
}
|
||||
}
|
||||
else {
|
||||
og_name = _(L("Part manipulation"));
|
||||
is_part = true;
|
||||
const auto volume_id = m_objects_model->GetVolumeIdByItem(item);
|
||||
m_config = std::make_shared<DynamicPrintConfig*>(&(*m_objects)[obj_idx]->volumes[volume_id]->config);
|
||||
}
|
||||
}
|
||||
|
||||
auto config = m_config;
|
||||
og->set_value("object_name", m_objects_model->GetName(item));
|
||||
og->set_name(" " + og_name + " ");
|
||||
object_name = m_objects_model->GetName(item);
|
||||
m_default_config = std::make_shared<DynamicPrintConfig>(*DynamicPrintConfig::new_from_defaults_keys(get_options(is_part)));
|
||||
}
|
||||
else {
|
||||
wxString empty_str = wxEmptyString;
|
||||
og->set_value("object_name", empty_str);
|
||||
m_config = nullptr;
|
||||
}
|
||||
og->set_value("object_name", object_name);
|
||||
|
||||
update_settings_list();
|
||||
|
||||
@ -1647,7 +1854,7 @@ void on_begin_drag(wxDataViewEvent &event)
|
||||
wxDataViewItem item(event.GetItem());
|
||||
|
||||
// only allow drags for item, not containers
|
||||
if (m_objects_model->GetParent(item) == wxDataViewItem(0)) {
|
||||
if (m_objects_model->GetParent(item) == wxDataViewItem(0) || m_objects_model->IsSettingsItem(item)) {
|
||||
event.Veto();
|
||||
return;
|
||||
}
|
||||
@ -1671,7 +1878,7 @@ void on_drop_possible(wxDataViewEvent &event)
|
||||
|
||||
// only allow drags for item or background, not containers
|
||||
if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0) ||
|
||||
event.GetDataFormat() != wxDF_UNICODETEXT)
|
||||
event.GetDataFormat() != wxDF_UNICODETEXT || m_objects_model->IsSettingsItem(item))
|
||||
event.Veto();
|
||||
}
|
||||
|
||||
@ -1681,7 +1888,7 @@ void on_drop(wxDataViewEvent &event)
|
||||
|
||||
// only allow drops for item, not containers
|
||||
if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0) ||
|
||||
event.GetDataFormat() != wxDF_UNICODETEXT) {
|
||||
event.GetDataFormat() != wxDF_UNICODETEXT || m_objects_model->IsSettingsItem(item)) {
|
||||
event.Veto();
|
||||
return;
|
||||
}
|
||||
@ -1709,6 +1916,9 @@ void on_drop(wxDataViewEvent &event)
|
||||
for (int id = from_volume_id; cnt < abs(from_volume_id - to_volume_id); id+=delta, cnt++)
|
||||
std::swap(volumes[id], volumes[id +delta]);
|
||||
|
||||
m_parts_changed = true;
|
||||
parts_changed(m_selected_object_id);
|
||||
|
||||
g_prevent_list_events = false;
|
||||
}
|
||||
|
||||
@ -1725,5 +1935,103 @@ void update_objects_list_extruder_column(int extruders_count)
|
||||
set_extruder_column_hidden(extruders_count <= 1);
|
||||
}
|
||||
|
||||
void create_double_slider(wxWindow* parent, wxBoxSizer* sizer, wxGLCanvas* canvas)
|
||||
{
|
||||
m_slider = new PrusaDoubleSlider(parent, wxID_ANY, 0, 0, 0, 100);
|
||||
sizer->Add(m_slider, 0, wxEXPAND, 0);
|
||||
|
||||
m_preview_canvas = canvas;
|
||||
m_preview_canvas->Bind(wxEVT_KEY_DOWN, update_double_slider_from_canvas);
|
||||
|
||||
m_slider->Bind(wxEVT_SCROLL_CHANGED, [parent](wxEvent& event) {
|
||||
_3DScene::set_toolpaths_range(m_preview_canvas, m_slider->GetLowerValueD() - 1e-6, m_slider->GetHigherValueD() + 1e-6);
|
||||
if (parent->IsShown())
|
||||
m_preview_canvas->Refresh();
|
||||
});
|
||||
}
|
||||
|
||||
void fill_slider_values(std::vector<std::pair<int, double>> &values,
|
||||
const std::vector<double> &layers_z)
|
||||
{
|
||||
std::vector<double> layers_all_z = _3DScene::get_current_print_zs(m_preview_canvas, false);
|
||||
if (layers_all_z.size() == layers_z.size())
|
||||
for (int i = 0; i < layers_z.size(); i++)
|
||||
values.push_back(std::pair<int, double>(i+1, layers_z[i]));
|
||||
else if (layers_all_z.size() > layers_z.size()) {
|
||||
int cur_id = 0;
|
||||
for (int i = 0; i < layers_z.size(); i++)
|
||||
for (int j = cur_id; j < layers_all_z.size(); j++)
|
||||
if (layers_z[i] - 1e-6 < layers_all_z[j] && layers_all_z[j] < layers_z[i] + 1e-6) {
|
||||
values.push_back(std::pair<int, double>(j+1, layers_z[i]));
|
||||
cur_id = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_double_slider_thumbs( const bool force_sliders_full_range,
|
||||
const std::vector<double> &layers_z,
|
||||
const double z_low, const double z_high)
|
||||
{
|
||||
// Force slider full range only when slider is created.
|
||||
// Support selected diapason on the all next steps
|
||||
if (/*force_sliders_full_range*/z_high == 0.0) {
|
||||
m_slider->SetLowerValue(0);
|
||||
m_slider->SetHigherValue(layers_z.size() - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = layers_z.size() - 1; i >= 0; i--)
|
||||
if (z_low >= layers_z[i]) {
|
||||
m_slider->SetLowerValue(i);
|
||||
break;
|
||||
}
|
||||
for (int i = layers_z.size() - 1; i >= 0 ; i--)
|
||||
if (z_high >= layers_z[i]) {
|
||||
m_slider->SetHigherValue(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void update_double_slider(bool force_sliders_full_range)
|
||||
{
|
||||
std::vector<std::pair<int, double>> values;
|
||||
std::vector<double> layers_z = _3DScene::get_current_print_zs(m_preview_canvas, true);
|
||||
fill_slider_values(values, layers_z);
|
||||
|
||||
const double z_low = m_slider->GetLowerValueD();
|
||||
const double z_high = m_slider->GetHigherValueD();
|
||||
m_slider->SetMaxValue(layers_z.size() - 1);
|
||||
m_slider->SetSliderValues(values);
|
||||
|
||||
set_double_slider_thumbs(force_sliders_full_range, layers_z, z_low, z_high);
|
||||
}
|
||||
|
||||
void reset_double_slider()
|
||||
{
|
||||
m_slider->SetHigherValue(0);
|
||||
m_slider->SetLowerValue(0);
|
||||
}
|
||||
|
||||
void update_double_slider_from_canvas(wxKeyEvent& event)
|
||||
{
|
||||
if (event.HasModifiers()) {
|
||||
event.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto key = event.GetKeyCode();
|
||||
|
||||
if (key == 'U' || key == 'D') {
|
||||
const int new_pos = key == 'U' ? m_slider->GetHigherValue() + 1 : m_slider->GetHigherValue() - 1;
|
||||
m_slider->SetHigherValue(new_pos);
|
||||
if (event.ShiftDown()) m_slider->SetLowerValue(m_slider->GetHigherValue());
|
||||
}
|
||||
else if (key == 'S')
|
||||
m_slider->ChangeOneLayerLock();
|
||||
else
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
} //namespace GUI
|
||||
} //namespace Slic3r
|
@ -9,13 +9,15 @@ class wxArrayString;
|
||||
class wxMenu;
|
||||
class wxDataViewEvent;
|
||||
class wxKeyEvent;
|
||||
class wxControl;
|
||||
class wxGLCanvas;
|
||||
class wxBitmap;
|
||||
|
||||
namespace Slic3r {
|
||||
class ModelObject;
|
||||
class Model;
|
||||
|
||||
namespace GUI {
|
||||
//class wxGLCanvas;
|
||||
|
||||
enum ogGroup{
|
||||
ogFrequentlyChangingParameters,
|
||||
@ -44,6 +46,9 @@ struct OBJECT_PARAMETERS
|
||||
double slab_z = 0.0;
|
||||
};
|
||||
|
||||
typedef std::map<std::string, wxBitmap> t_category_icon;
|
||||
inline t_category_icon& get_category_icon();
|
||||
|
||||
void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer);
|
||||
void add_objects_list(wxWindow* parent, wxBoxSizer* sizer);
|
||||
void add_object_settings(wxWindow* parent, wxBoxSizer* sizer);
|
||||
@ -66,16 +71,17 @@ void set_object_count(int idx, int count);
|
||||
void unselect_objects();
|
||||
// Select current object in the list on c++ side
|
||||
void select_current_object(int idx);
|
||||
// Select current volume in the list on c++ side
|
||||
void select_current_volume(int idx, int vol_idx);
|
||||
// Remove objects/sub-object from the list
|
||||
void remove();
|
||||
|
||||
//void create_double_slider(wxWindow* parent, wxControl* slider);
|
||||
|
||||
void object_ctrl_selection_changed();
|
||||
void object_ctrl_context_menu();
|
||||
void object_ctrl_key_event(wxKeyEvent& event);
|
||||
void object_ctrl_item_value_change(wxDataViewEvent& event);
|
||||
void show_context_menu();
|
||||
bool is_splittable_object(const bool split_part);
|
||||
|
||||
void init_mesh_icons();
|
||||
void set_event_object_selection_changed(const int& event);
|
||||
@ -87,13 +93,14 @@ void set_objects_from_model(Model &model);
|
||||
bool is_parts_changed();
|
||||
bool is_part_settings_changed();
|
||||
|
||||
void load_part( wxWindow* parent, ModelObject* model_object,
|
||||
void load_part( ModelObject* model_object,
|
||||
wxArrayString& part_names, const bool is_modifier);
|
||||
|
||||
void load_lambda(wxWindow* parent, ModelObject* model_object,
|
||||
wxArrayString& part_names, const bool is_modifier);
|
||||
void load_lambda( ModelObject* model_object,
|
||||
wxArrayString& part_names, const bool is_modifier);
|
||||
void load_lambda( const std::string& type_name);
|
||||
|
||||
void on_btn_load(wxWindow* parent, bool is_modifier = false, bool is_lambda = false);
|
||||
void on_btn_load(bool is_modifier = false, bool is_lambda = false);
|
||||
void on_btn_del();
|
||||
void on_btn_split(const bool split_part);
|
||||
void on_btn_move_up();
|
||||
@ -126,6 +133,13 @@ void on_drop(wxDataViewEvent &event);
|
||||
// update extruder column for objects_ctrl according to extruders count
|
||||
void update_objects_list_extruder_column(int extruders_count);
|
||||
|
||||
// Create/Update/Reset double slider on 3dPreview
|
||||
void create_double_slider(wxWindow* parent, wxBoxSizer* sizer, wxGLCanvas* canvas);
|
||||
void update_double_slider(bool force_sliders_full_range);
|
||||
void reset_double_slider();
|
||||
// update DoubleSlider after keyDown in canvas
|
||||
void update_double_slider_from_canvas(wxKeyEvent& event);
|
||||
|
||||
} //namespace GUI
|
||||
} //namespace Slic3r
|
||||
#endif //slic3r_GUI_ObjectParts_hpp_
|
@ -10,10 +10,12 @@ namespace GUI
|
||||
{
|
||||
static wxString dots("…", wxConvUTF8);
|
||||
|
||||
LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
|
||||
LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent,
|
||||
const wxString type_name):
|
||||
m_type_name(type_name)
|
||||
{
|
||||
Create(parent, wxID_ANY, _(L("Lambda Object")),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
parent->GetScreenPosition(), wxDefaultSize,
|
||||
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
|
||||
|
||||
// instead of double dim[3] = { 1.0, 1.0, 1.0 };
|
||||
@ -24,11 +26,20 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
|
||||
sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
// modificator options
|
||||
m_modificator_options_book = new wxChoicebook( this, wxID_ANY, wxDefaultPosition,
|
||||
wxDefaultSize, wxCHB_TOP);
|
||||
sizer->Add(m_modificator_options_book, 1, wxEXPAND| wxALL, 10);
|
||||
if (m_type_name == wxEmptyString) {
|
||||
m_modificator_options_book = new wxChoicebook( this, wxID_ANY, wxDefaultPosition,
|
||||
wxDefaultSize, wxCHB_TOP);
|
||||
sizer->Add(m_modificator_options_book, 1, wxEXPAND | wxALL, 10);
|
||||
}
|
||||
else {
|
||||
m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
sizer->Add(m_panel, 1, wxEXPAND | wxALL, 10);
|
||||
}
|
||||
|
||||
ConfigOptionDef def;
|
||||
def.width = 70;
|
||||
auto optgroup = init_modificator_options_page(_(L("Box")));
|
||||
if (optgroup){
|
||||
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
|
||||
int opt_id = opt_key == "l" ? 0 :
|
||||
opt_key == "w" ? 1 :
|
||||
@ -37,8 +48,6 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
|
||||
object_parameters.dim[opt_id] = boost::any_cast<double>(value);
|
||||
};
|
||||
|
||||
ConfigOptionDef def;
|
||||
def.width = 70;
|
||||
def.type = coFloat;
|
||||
def.default_value = new ConfigOptionFloat{ 1.0 };
|
||||
def.label = L("L");
|
||||
@ -52,8 +61,10 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
|
||||
def.label = L("H");
|
||||
option = Option(def, "h");
|
||||
optgroup->append_single_option_line(option);
|
||||
}
|
||||
|
||||
optgroup = init_modificator_options_page(_(L("Cylinder")));
|
||||
if (optgroup){
|
||||
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
|
||||
int val = boost::any_cast<int>(value);
|
||||
if (opt_key == "cyl_r")
|
||||
@ -66,14 +77,16 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
|
||||
def.type = coInt;
|
||||
def.default_value = new ConfigOptionInt{ 1 };
|
||||
def.label = L("Radius");
|
||||
option = Option(def, "cyl_r");
|
||||
auto option = Option(def, "cyl_r");
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
def.label = L("Height");
|
||||
option = Option(def, "cyl_h");
|
||||
optgroup->append_single_option_line(option);
|
||||
}
|
||||
|
||||
optgroup = init_modificator_options_page(_(L("Sphere")));
|
||||
if (optgroup){
|
||||
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
|
||||
if (opt_key == "sph_rho")
|
||||
object_parameters.sph_rho = boost::any_cast<double>(value);
|
||||
@ -83,10 +96,12 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
|
||||
def.type = coFloat;
|
||||
def.default_value = new ConfigOptionFloat{ 1.0 };
|
||||
def.label = L("Rho");
|
||||
option = Option(def, "sph_rho");
|
||||
auto option = Option(def, "sph_rho");
|
||||
optgroup->append_single_option_line(option);
|
||||
}
|
||||
|
||||
optgroup = init_modificator_options_page(_(L("Slab")));
|
||||
if (optgroup){
|
||||
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
|
||||
double val = boost::any_cast<double>(value);
|
||||
if (opt_key == "slab_z")
|
||||
@ -96,13 +111,16 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
|
||||
else return;
|
||||
};
|
||||
|
||||
def.type = coFloat;
|
||||
def.default_value = new ConfigOptionFloat{ 1.0 };
|
||||
def.label = L("H");
|
||||
option = Option(def, "slab_h");
|
||||
auto option = Option(def, "slab_h");
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
def.label = L("Initial Z");
|
||||
option = Option(def, "slab_z");
|
||||
optgroup->append_single_option_line(option);
|
||||
}
|
||||
|
||||
Bind(wxEVT_CHOICEBOOK_PAGE_CHANGED, ([this](wxCommandEvent e)
|
||||
{
|
||||
@ -127,8 +145,7 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
auto button_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
|
||||
const auto button_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
|
||||
|
||||
wxButton* btn_OK = static_cast<wxButton*>(FindWindowById(wxID_OK, this));
|
||||
btn_OK->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
|
||||
@ -155,9 +172,11 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
|
||||
|
||||
// Called from the constructor.
|
||||
// Create a panel for a rectangular / circular / custom bed shape.
|
||||
ConfigOptionsGroupShp LambdaObjectDialog::init_modificator_options_page(wxString title){
|
||||
ConfigOptionsGroupShp LambdaObjectDialog::init_modificator_options_page(const wxString& title){
|
||||
if (!m_type_name.IsEmpty() && m_type_name != title)
|
||||
return nullptr;
|
||||
|
||||
auto panel = new wxPanel(m_modificator_options_book);
|
||||
auto panel = m_type_name.IsEmpty() ? new wxPanel(m_modificator_options_book) : m_panel;
|
||||
|
||||
ConfigOptionsGroupShp optgroup;
|
||||
optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Add")) + " " +title + " " +dots);
|
||||
@ -165,8 +184,12 @@ ConfigOptionsGroupShp LambdaObjectDialog::init_modificator_options_page(wxString
|
||||
|
||||
m_optgroups.push_back(optgroup);
|
||||
|
||||
panel->SetSizerAndFit(optgroup->sizer);
|
||||
m_modificator_options_book->AddPage(panel, title);
|
||||
if (m_type_name.IsEmpty()) {
|
||||
panel->SetSizerAndFit(optgroup->sizer);
|
||||
m_modificator_options_book->AddPage(panel, title);
|
||||
}
|
||||
else
|
||||
panel->SetSizer(optgroup->sizer);
|
||||
|
||||
return optgroup;
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/choicebk.h>
|
||||
|
||||
class wxPanel;
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
namespace GUI
|
||||
@ -14,16 +16,19 @@ namespace GUI
|
||||
using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
|
||||
class LambdaObjectDialog : public wxDialog
|
||||
{
|
||||
wxChoicebook* m_modificator_options_book;
|
||||
wxChoicebook* m_modificator_options_book = nullptr;
|
||||
std::vector <ConfigOptionsGroupShp> m_optgroups;
|
||||
wxString m_type_name;
|
||||
wxPanel* m_panel = nullptr;
|
||||
public:
|
||||
LambdaObjectDialog(wxWindow* parent);
|
||||
LambdaObjectDialog(wxWindow* parent,
|
||||
const wxString type_name = wxEmptyString);
|
||||
~LambdaObjectDialog(){}
|
||||
|
||||
bool CanClose() { return true; } // ???
|
||||
OBJECT_PARAMETERS& ObjectParameters(){ return object_parameters; }
|
||||
|
||||
ConfigOptionsGroupShp init_modificator_options_page(wxString title);
|
||||
ConfigOptionsGroupShp init_modificator_options_page(const wxString& title);
|
||||
|
||||
// Note whether the window was already closed, so a pending update is not executed.
|
||||
bool m_already_closed = false;
|
||||
|
@ -158,7 +158,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/*
|
||||
// if we have an extra column, build it
|
||||
if (extra_column) {
|
||||
if (extra_column) {
|
||||
grid_sizer->Add(extra_column(parent(), line), 0, wxALIGN_CENTER_VERTICAL, 0);
|
||||
grid_sizer->Add(extra_column(parent(), line), 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3);
|
||||
}
|
||||
else {
|
||||
// if the callback provides no sizer for the extra cell, put a spacer
|
||||
|
@ -161,8 +161,10 @@ public:
|
||||
ogDrawFlag flag = ogDEFAULT, column_t extra_clmn = nullptr) :
|
||||
m_parent(_parent), title(title), m_show_modified_btns(is_tab_opt),
|
||||
staticbox(title!=""), m_flag(flag), extra_column(extra_clmn){
|
||||
stb = new wxStaticBox(_parent, wxID_ANY, title);
|
||||
stb->SetFont(bold_font());
|
||||
if (staticbox) {
|
||||
stb = new wxStaticBox(_parent, wxID_ANY, title);
|
||||
stb->SetFont(bold_font());
|
||||
}
|
||||
sizer = (staticbox ? new wxStaticBoxSizer(stb, wxVERTICAL) : new wxBoxSizer(wxVERTICAL));
|
||||
auto num_columns = 1U;
|
||||
if (label_width != 0) num_columns++;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "GUI.hpp"
|
||||
#include "../../libslic3r/Utils.hpp"
|
||||
#include "BitmapCache.hpp"
|
||||
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/statline.h>
|
||||
@ -357,11 +358,53 @@ void PrusaObjectDataViewModelNode::set_part_action_icon() {
|
||||
m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("cog.png")), wxBITMAP_TYPE_PNG);
|
||||
}
|
||||
|
||||
Slic3r::GUI::BitmapCache *m_bitmap_cache = nullptr;
|
||||
bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vector<std::string>& categories)
|
||||
{
|
||||
if (m_type != "settings" || m_opt_categories == categories)
|
||||
return false;
|
||||
|
||||
m_opt_categories = categories;
|
||||
m_name = wxEmptyString;
|
||||
m_icon = m_empty_icon;
|
||||
|
||||
auto categories_icon = Slic3r::GUI::get_category_icon();
|
||||
|
||||
for (auto& cat : m_opt_categories)
|
||||
m_name += cat + "; ";
|
||||
|
||||
wxBitmap *bmp = m_bitmap_cache->find(m_name.ToStdString());
|
||||
if (bmp == nullptr) {
|
||||
std::vector<wxBitmap> bmps;
|
||||
for (auto& cat : m_opt_categories)
|
||||
bmps.emplace_back(categories_icon.find(cat) == categories_icon.end() ?
|
||||
wxNullBitmap : categories_icon.at(cat));
|
||||
bmp = m_bitmap_cache->insert(m_name.ToStdString(), bmps);
|
||||
}
|
||||
|
||||
m_bmp = *bmp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// ----------------------------------------------------------------------------
|
||||
// PrusaObjectDataViewModel
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
PrusaObjectDataViewModel::PrusaObjectDataViewModel()
|
||||
{
|
||||
m_bitmap_cache = new Slic3r::GUI::BitmapCache;
|
||||
}
|
||||
|
||||
PrusaObjectDataViewModel::~PrusaObjectDataViewModel()
|
||||
{
|
||||
for (auto object : m_objects)
|
||||
delete object;
|
||||
delete m_bitmap_cache;
|
||||
m_bitmap_cache = nullptr;
|
||||
}
|
||||
|
||||
wxDataViewItem PrusaObjectDataViewModel::Add(const wxString &name)
|
||||
{
|
||||
auto root = new PrusaObjectDataViewModelNode(name);
|
||||
@ -386,34 +429,50 @@ wxDataViewItem PrusaObjectDataViewModel::Add(const wxString &name, const int ins
|
||||
|
||||
wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_item,
|
||||
const wxString &name,
|
||||
const wxIcon& icon,
|
||||
const wxBitmap& icon,
|
||||
const int extruder/* = 0*/,
|
||||
const bool create_frst_child/* = true*/)
|
||||
{
|
||||
PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent_item.GetID();
|
||||
if (!root) return wxDataViewItem(0);
|
||||
|
||||
wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder);
|
||||
const wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder);
|
||||
|
||||
if (root->GetChildren().Count() == 0 && create_frst_child)
|
||||
if (create_frst_child && (root->GetChildren().Count() == 0 ||
|
||||
(root->GetChildren().Count() == 1 && root->GetNthChild(0)->m_type == "settings")))
|
||||
{
|
||||
auto icon_solid_mesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG);
|
||||
auto node = new PrusaObjectDataViewModelNode(root, root->m_name, icon_solid_mesh, extruder_str, 0);
|
||||
const auto icon_solid_mesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);
|
||||
const auto node = new PrusaObjectDataViewModelNode(root, root->m_name, icon_solid_mesh, extruder_str, 0);
|
||||
root->Append(node);
|
||||
// notify control
|
||||
wxDataViewItem child((void*)node);
|
||||
const wxDataViewItem child((void*)node);
|
||||
ItemAdded(parent_item, child);
|
||||
}
|
||||
|
||||
auto volume_id = root->GetChildCount();
|
||||
auto node = new PrusaObjectDataViewModelNode(root, name, icon, extruder_str, volume_id);
|
||||
const auto volume_id = root->GetChildCount() > 0 && root->GetNthChild(0)->m_type == "settings" ?
|
||||
root->GetChildCount() - 1 : root->GetChildCount();
|
||||
|
||||
const auto node = new PrusaObjectDataViewModelNode(root, name, icon, extruder_str, volume_id);
|
||||
root->Append(node);
|
||||
// notify control
|
||||
wxDataViewItem child((void*)node);
|
||||
const wxDataViewItem child((void*)node);
|
||||
ItemAdded(parent_item, child);
|
||||
return child;
|
||||
}
|
||||
|
||||
wxDataViewItem PrusaObjectDataViewModel::AddSettingsChild(const wxDataViewItem &parent_item)
|
||||
{
|
||||
PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent_item.GetID();
|
||||
if (!root) return wxDataViewItem(0);
|
||||
|
||||
const auto node = new PrusaObjectDataViewModelNode(root);
|
||||
root->Insert(node, 0);
|
||||
// notify control
|
||||
const wxDataViewItem child((void*)node);
|
||||
ItemAdded(parent_item, child);
|
||||
return child;
|
||||
}
|
||||
|
||||
wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item)
|
||||
{
|
||||
auto ret_item = wxDataViewItem(0);
|
||||
@ -438,7 +497,7 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item)
|
||||
|
||||
//update volume_id value for remaining child-nodes
|
||||
auto children = node_parent->GetChildren();
|
||||
for (size_t i = 0; i < node_parent->GetChildCount(); i++)
|
||||
for (size_t i = 0; i < node_parent->GetChildCount() && v_id>=0; i++)
|
||||
{
|
||||
auto volume_id = children[i]->GetVolumeId();
|
||||
if (volume_id > v_id)
|
||||
@ -460,9 +519,10 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item)
|
||||
delete node;
|
||||
|
||||
// set m_containet to FALSE if parent has no child
|
||||
if (node_parent && node_parent->GetChildCount() == 0){
|
||||
if (node_parent) {
|
||||
#ifndef __WXGTK__
|
||||
node_parent->m_container = false;
|
||||
if (node_parent->GetChildCount() == 0)
|
||||
node_parent->m_container = false;
|
||||
#endif //__WXGTK__
|
||||
ret_item = parent;
|
||||
}
|
||||
@ -522,6 +582,26 @@ wxDataViewItem PrusaObjectDataViewModel::GetItemById(int obj_idx)
|
||||
}
|
||||
|
||||
|
||||
wxDataViewItem PrusaObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volume_idx)
|
||||
{
|
||||
if (obj_idx >= m_objects.size()) {
|
||||
printf("Error! Out of objects range.\n");
|
||||
return wxDataViewItem(0);
|
||||
}
|
||||
|
||||
auto parent = m_objects[obj_idx];
|
||||
if (parent->GetChildCount() == 0) {
|
||||
printf("Error! Object has no one volume.\n");
|
||||
return wxDataViewItem(0);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < parent->GetChildCount(); i++)
|
||||
if (parent->GetNthChild(i)->m_volume_id == volume_idx)
|
||||
return wxDataViewItem(parent->GetNthChild(i));
|
||||
|
||||
return wxDataViewItem(0);
|
||||
}
|
||||
|
||||
int PrusaObjectDataViewModel::GetIdByItem(wxDataViewItem& item)
|
||||
{
|
||||
wxASSERT(item.IsOk());
|
||||
@ -534,7 +614,7 @@ int PrusaObjectDataViewModel::GetIdByItem(wxDataViewItem& item)
|
||||
return it - m_objects.begin();
|
||||
}
|
||||
|
||||
int PrusaObjectDataViewModel::GetVolumeIdByItem(wxDataViewItem& item)
|
||||
int PrusaObjectDataViewModel::GetVolumeIdByItem(const wxDataViewItem& item)
|
||||
{
|
||||
wxASSERT(item.IsOk());
|
||||
|
||||
@ -568,6 +648,12 @@ wxIcon& PrusaObjectDataViewModel::GetIcon(const wxDataViewItem &item) const
|
||||
return node->m_icon;
|
||||
}
|
||||
|
||||
wxBitmap& PrusaObjectDataViewModel::GetBitmap(const wxDataViewItem &item) const
|
||||
{
|
||||
PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
|
||||
return node->m_bmp;
|
||||
}
|
||||
|
||||
void PrusaObjectDataViewModel::GetValue(wxVariant &variant, const wxDataViewItem &item, unsigned int col) const
|
||||
{
|
||||
wxASSERT(item.IsOk());
|
||||
@ -576,8 +662,8 @@ void PrusaObjectDataViewModel::GetValue(wxVariant &variant, const wxDataViewItem
|
||||
switch (col)
|
||||
{
|
||||
case 0:{
|
||||
const wxDataViewIconText data(node->m_name, node->m_icon);
|
||||
variant << data;
|
||||
const PrusaDataViewBitmapText data(node->m_name, node->m_bmp);
|
||||
variant << data;
|
||||
break;}
|
||||
case 1:
|
||||
variant = node->m_copy;
|
||||
@ -667,26 +753,35 @@ wxDataViewItem PrusaObjectDataViewModel::ReorganizeChildren(int current_volume_i
|
||||
if (!node_parent) // happens if item.IsOk()==false
|
||||
return ret_item;
|
||||
|
||||
PrusaObjectDataViewModelNode *deleted_node = node_parent->GetNthChild(current_volume_id);
|
||||
const size_t shift = node_parent->GetChildren().Item(0)->m_type == "settings" ? 1 : 0;
|
||||
|
||||
PrusaObjectDataViewModelNode *deleted_node = node_parent->GetNthChild(current_volume_id+shift);
|
||||
node_parent->GetChildren().Remove(deleted_node);
|
||||
ItemDeleted(parent, wxDataViewItem(deleted_node));
|
||||
node_parent->Insert(deleted_node, new_volume_id);
|
||||
node_parent->Insert(deleted_node, new_volume_id+shift);
|
||||
ItemAdded(parent, wxDataViewItem(deleted_node));
|
||||
const auto settings_item = HasSettings(wxDataViewItem(deleted_node));
|
||||
if (settings_item)
|
||||
ItemAdded(wxDataViewItem(deleted_node), settings_item);
|
||||
|
||||
//update volume_id value for child-nodes
|
||||
auto children = node_parent->GetChildren();
|
||||
int id_frst = current_volume_id < new_volume_id ? current_volume_id : new_volume_id;
|
||||
int id_last = current_volume_id > new_volume_id ? current_volume_id : new_volume_id;
|
||||
for (int id = id_frst; id <= id_last; ++id)
|
||||
children[id]->SetVolumeId(id);
|
||||
children[id+shift]->SetVolumeId(id);
|
||||
|
||||
return wxDataViewItem(node_parent->GetNthChild(new_volume_id));
|
||||
return wxDataViewItem(node_parent->GetNthChild(new_volume_id+shift));
|
||||
}
|
||||
|
||||
// bool MyObjectTreeModel::IsEnabled(const wxDataViewItem &item, unsigned int col) const
|
||||
// {
|
||||
//
|
||||
// }
|
||||
bool PrusaObjectDataViewModel::IsEnabled(const wxDataViewItem &item, unsigned int col) const
|
||||
{
|
||||
wxASSERT(item.IsOk());
|
||||
PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
|
||||
|
||||
// disable extruder selection for the "Settings" item
|
||||
return !(col == 2 && node->m_extruder.IsEmpty());
|
||||
}
|
||||
|
||||
wxDataViewItem PrusaObjectDataViewModel::GetParent(const wxDataViewItem &item) const
|
||||
{
|
||||
@ -738,6 +833,87 @@ unsigned int PrusaObjectDataViewModel::GetChildren(const wxDataViewItem &parent,
|
||||
return count;
|
||||
}
|
||||
|
||||
wxDataViewItem PrusaObjectDataViewModel::HasSettings(const wxDataViewItem &item) const
|
||||
{
|
||||
if (!item.IsOk())
|
||||
return wxDataViewItem(0);
|
||||
|
||||
PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
|
||||
if (node->GetChildCount() == 0)
|
||||
return wxDataViewItem(0);
|
||||
|
||||
auto& children = node->GetChildren();
|
||||
if (children[0]->m_type == "settings")
|
||||
return wxDataViewItem((void*)children[0]);;
|
||||
|
||||
return wxDataViewItem(0);
|
||||
}
|
||||
|
||||
bool PrusaObjectDataViewModel::IsSettingsItem(const wxDataViewItem &item) const
|
||||
{
|
||||
if (!item.IsOk())
|
||||
return false;
|
||||
PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
|
||||
return node->m_type == "settings";
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PrusaObjectDataViewModel::UpdateSettingsDigest(const wxDataViewItem &item,
|
||||
const std::vector<std::string>& categories)
|
||||
{
|
||||
if (!item.IsOk()) return;
|
||||
PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
|
||||
if (!node->update_settings_digest(categories))
|
||||
return;
|
||||
ItemChanged(item);
|
||||
}
|
||||
|
||||
IMPLEMENT_VARIANT_OBJECT(PrusaDataViewBitmapText)
|
||||
// ---------------------------------------------------------
|
||||
// PrusaIconTextRenderer
|
||||
// ---------------------------------------------------------
|
||||
|
||||
bool PrusaBitmapTextRenderer::SetValue(const wxVariant &value)
|
||||
{
|
||||
m_value << value;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PrusaBitmapTextRenderer::GetValue(wxVariant& WXUNUSED(value)) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PrusaBitmapTextRenderer::Render(wxRect rect, wxDC *dc, int state)
|
||||
{
|
||||
int xoffset = 0;
|
||||
|
||||
const wxBitmap& icon = m_value.GetBitmap();
|
||||
if (icon.IsOk())
|
||||
{
|
||||
dc->DrawBitmap(icon, rect.x, rect.y + (rect.height - icon.GetHeight()) / 2);
|
||||
xoffset = icon.GetWidth() + 4;
|
||||
}
|
||||
|
||||
RenderText(m_value.GetText(), xoffset, rect, dc, state);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
wxSize PrusaBitmapTextRenderer::GetSize() const
|
||||
{
|
||||
if (!m_value.GetText().empty())
|
||||
{
|
||||
wxSize size = GetTextExtent(m_value.GetText());
|
||||
|
||||
if (m_value.GetBitmap().IsOk())
|
||||
size.x += m_value.GetBitmap().GetWidth() + 4;
|
||||
return size;
|
||||
}
|
||||
return wxSize(80, 20);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// PrusaDoubleSlider
|
||||
@ -829,16 +1005,28 @@ wxSize PrusaDoubleSlider::DoGetBestSize() const
|
||||
|
||||
void PrusaDoubleSlider::SetLowerValue(const int lower_val)
|
||||
{
|
||||
m_selection = ssLower;
|
||||
m_lower_value = lower_val;
|
||||
correct_lower_value();
|
||||
Refresh();
|
||||
Update();
|
||||
|
||||
wxCommandEvent e(wxEVT_SCROLL_CHANGED);
|
||||
e.SetEventObject(this);
|
||||
ProcessWindowEvent(e);
|
||||
}
|
||||
|
||||
void PrusaDoubleSlider::SetHigherValue(const int higher_val)
|
||||
{
|
||||
m_selection = ssHigher;
|
||||
m_higher_value = higher_val;
|
||||
correct_higher_value();
|
||||
Refresh();
|
||||
Update();
|
||||
|
||||
wxCommandEvent e(wxEVT_SCROLL_CHANGED);
|
||||
e.SetEventObject(this);
|
||||
ProcessWindowEvent(e);
|
||||
}
|
||||
|
||||
void PrusaDoubleSlider::SetMaxValue(const int max_value)
|
||||
@ -905,6 +1093,13 @@ void PrusaDoubleSlider::get_size(int *w, int *h)
|
||||
is_horizontal() ? *w -= m_lock_icon_dim : *h -= m_lock_icon_dim;
|
||||
}
|
||||
|
||||
double PrusaDoubleSlider::get_double_value(const SelectedSlider& selection) const
|
||||
{
|
||||
if (m_values.empty())
|
||||
return 0.0;
|
||||
return m_values[selection == ssLower ? m_lower_value : m_higher_value].second;
|
||||
}
|
||||
|
||||
void PrusaDoubleSlider::get_lower_and_higher_position(int& lower_pos, int& higher_pos)
|
||||
{
|
||||
const double step = get_scroll_step();
|
||||
@ -1010,7 +1205,7 @@ wxString PrusaDoubleSlider::get_label(const SelectedSlider& selection) const
|
||||
|
||||
void PrusaDoubleSlider::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const
|
||||
{
|
||||
if (m_is_one_layer && selection != m_selection || !selection)
|
||||
if ((m_is_one_layer || m_higher_value==m_lower_value) && selection != m_selection || !selection)
|
||||
return;
|
||||
wxCoord text_width, text_height;
|
||||
const wxString label = get_label(selection);
|
||||
@ -1178,6 +1373,20 @@ bool PrusaDoubleSlider::is_point_in_rect(const wxPoint& pt, const wxRect& rect)
|
||||
return false;
|
||||
}
|
||||
|
||||
void PrusaDoubleSlider::ChangeOneLayerLock()
|
||||
{
|
||||
m_is_one_layer = !m_is_one_layer;
|
||||
m_selection == ssLower ? correct_lower_value() : correct_higher_value();
|
||||
if (!m_selection) m_selection = ssHigher;
|
||||
|
||||
Refresh();
|
||||
Update();
|
||||
|
||||
wxCommandEvent e(wxEVT_SCROLL_CHANGED);
|
||||
e.SetEventObject(this);
|
||||
ProcessWindowEvent(e);
|
||||
}
|
||||
|
||||
void PrusaDoubleSlider::OnLeftDown(wxMouseEvent& event)
|
||||
{
|
||||
this->CaptureMouse();
|
||||
@ -1245,6 +1454,10 @@ void PrusaDoubleSlider::OnMotion(wxMouseEvent& event)
|
||||
Refresh();
|
||||
Update();
|
||||
event.Skip();
|
||||
|
||||
wxCommandEvent e(wxEVT_SCROLL_CHANGED);
|
||||
e.SetEventObject(this);
|
||||
ProcessWindowEvent(e);
|
||||
}
|
||||
|
||||
void PrusaDoubleSlider::OnLeftUp(wxMouseEvent& event)
|
||||
|
@ -144,6 +144,49 @@ public:
|
||||
#endif //__WXMSW__
|
||||
|
||||
// *****************************************************************************
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// PrusaDataViewBitmapText: helper class used by PrusaBitmapTextRenderer
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class PrusaDataViewBitmapText : public wxObject
|
||||
{
|
||||
public:
|
||||
PrusaDataViewBitmapText(const wxString &text = wxEmptyString,
|
||||
const wxBitmap& bmp = wxNullBitmap) :
|
||||
m_text(text), m_bmp(bmp)
|
||||
{ }
|
||||
|
||||
PrusaDataViewBitmapText(const PrusaDataViewBitmapText &other)
|
||||
: wxObject(),
|
||||
m_text(other.m_text),
|
||||
m_bmp(other.m_bmp)
|
||||
{ }
|
||||
|
||||
void SetText(const wxString &text) { m_text = text; }
|
||||
wxString GetText() const { return m_text; }
|
||||
void SetBitmap(const wxIcon &icon) { m_bmp = icon; }
|
||||
const wxBitmap &GetBitmap() const { return m_bmp; }
|
||||
|
||||
bool IsSameAs(const PrusaDataViewBitmapText& other) const {
|
||||
return m_text == other.m_text && m_bmp.IsSameAs(other.m_bmp);
|
||||
}
|
||||
|
||||
bool operator==(const PrusaDataViewBitmapText& other) const {
|
||||
return IsSameAs(other);
|
||||
}
|
||||
|
||||
bool operator!=(const PrusaDataViewBitmapText& other) const {
|
||||
return !IsSameAs(other);
|
||||
}
|
||||
|
||||
private:
|
||||
wxString m_text;
|
||||
wxBitmap m_bmp;
|
||||
};
|
||||
DECLARE_VARIANT_OBJECT(PrusaDataViewBitmapText)
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// PrusaObjectDataViewModelNode: a node inside PrusaObjectDataViewModel
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -155,7 +198,9 @@ class PrusaObjectDataViewModelNode
|
||||
{
|
||||
PrusaObjectDataViewModelNode* m_parent;
|
||||
MyObjectTreeModelNodePtrArray m_children;
|
||||
wxIcon m_empty_icon;
|
||||
wxIcon m_empty_icon;
|
||||
wxBitmap m_empty_bmp;
|
||||
std::vector< std::string > m_opt_categories;
|
||||
public:
|
||||
PrusaObjectDataViewModelNode(const wxString &name, const int instances_count=1) {
|
||||
m_parent = NULL;
|
||||
@ -174,18 +219,31 @@ public:
|
||||
|
||||
PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent,
|
||||
const wxString& sub_obj_name,
|
||||
const wxIcon& icon,
|
||||
const wxBitmap& bmp,
|
||||
const wxString& extruder,
|
||||
const int volume_id=-1) {
|
||||
m_parent = parent;
|
||||
m_name = sub_obj_name;
|
||||
m_copy = wxEmptyString;
|
||||
m_icon = icon;
|
||||
m_bmp = bmp;
|
||||
m_type = "volume";
|
||||
m_volume_id = volume_id;
|
||||
m_extruder = extruder;
|
||||
m_extruder = extruder;
|
||||
#ifdef __WXGTK__
|
||||
// it's necessary on GTK because of control have to know if this item will be container
|
||||
// in another case you couldn't to add subitem for this item
|
||||
// it will be produce "segmentation fault"
|
||||
m_container = true;
|
||||
#endif //__WXGTK__
|
||||
set_part_action_icon();
|
||||
}
|
||||
}
|
||||
|
||||
PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent) :
|
||||
m_parent(parent),
|
||||
m_name("Settings to modified"),
|
||||
m_copy(wxEmptyString),
|
||||
m_type("settings"),
|
||||
m_extruder(wxEmptyString) {}
|
||||
|
||||
~PrusaObjectDataViewModelNode()
|
||||
{
|
||||
@ -200,9 +258,10 @@ public:
|
||||
|
||||
wxString m_name;
|
||||
wxIcon& m_icon = m_empty_icon;
|
||||
wxBitmap& m_bmp = m_empty_bmp;
|
||||
wxString m_copy;
|
||||
std::string m_type;
|
||||
int m_volume_id;
|
||||
int m_volume_id = -2;
|
||||
bool m_container = false;
|
||||
wxString m_extruder = "default";
|
||||
wxBitmap m_action_icon;
|
||||
@ -226,6 +285,8 @@ public:
|
||||
}
|
||||
void Insert(PrusaObjectDataViewModelNode* child, unsigned int n)
|
||||
{
|
||||
if (!m_container)
|
||||
m_container = true;
|
||||
m_children.Insert(child, n);
|
||||
}
|
||||
void Append(PrusaObjectDataViewModelNode* child)
|
||||
@ -258,9 +319,9 @@ public:
|
||||
switch (col)
|
||||
{
|
||||
case 0:{
|
||||
wxDataViewIconText data;
|
||||
PrusaDataViewBitmapText data;
|
||||
data << variant;
|
||||
m_icon = data.GetIcon();
|
||||
m_bmp = data.GetBitmap();
|
||||
m_name = data.GetText();
|
||||
return true;}
|
||||
case 1:
|
||||
@ -281,6 +342,11 @@ public:
|
||||
{
|
||||
m_icon = icon;
|
||||
}
|
||||
|
||||
void SetBitmap(const wxBitmap &icon)
|
||||
{
|
||||
m_bmp = icon;
|
||||
}
|
||||
|
||||
void SetType(const std::string& type){
|
||||
m_type = type;
|
||||
@ -326,6 +392,7 @@ public:
|
||||
// Set action icons for node
|
||||
void set_object_action_icon();
|
||||
void set_part_action_icon();
|
||||
bool update_settings_digest(const std::vector<std::string>& categories);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -336,26 +403,24 @@ class PrusaObjectDataViewModel :public wxDataViewModel
|
||||
{
|
||||
std::vector<PrusaObjectDataViewModelNode*> m_objects;
|
||||
public:
|
||||
PrusaObjectDataViewModel(){}
|
||||
~PrusaObjectDataViewModel()
|
||||
{
|
||||
for (auto object : m_objects)
|
||||
delete object;
|
||||
}
|
||||
PrusaObjectDataViewModel();
|
||||
~PrusaObjectDataViewModel();
|
||||
|
||||
wxDataViewItem Add(const wxString &name);
|
||||
wxDataViewItem Add(const wxString &name, const int instances_count);
|
||||
wxDataViewItem AddChild(const wxDataViewItem &parent_item,
|
||||
const wxString &name,
|
||||
const wxIcon& icon,
|
||||
const int = 0,
|
||||
const wxBitmap& icon,
|
||||
const int extruder = 0,
|
||||
const bool create_frst_child = true);
|
||||
wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item);
|
||||
wxDataViewItem Delete(const wxDataViewItem &item);
|
||||
void DeleteAll();
|
||||
void DeleteChildren(wxDataViewItem& parent);
|
||||
wxDataViewItem GetItemById(int obj_idx);
|
||||
wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx);
|
||||
int GetIdByItem(wxDataViewItem& item);
|
||||
int GetVolumeIdByItem(wxDataViewItem& item);
|
||||
int GetVolumeIdByItem(const wxDataViewItem& item);
|
||||
bool IsEmpty() { return m_objects.empty(); }
|
||||
|
||||
// helper method for wxLog
|
||||
@ -363,6 +428,7 @@ public:
|
||||
wxString GetName(const wxDataViewItem &item) const;
|
||||
wxString GetCopy(const wxDataViewItem &item) const;
|
||||
wxIcon& GetIcon(const wxDataViewItem &item) const;
|
||||
wxBitmap& GetBitmap(const wxDataViewItem &item) const;
|
||||
|
||||
// helper methods to change the model
|
||||
|
||||
@ -383,8 +449,7 @@ public:
|
||||
int new_volume_id,
|
||||
const wxDataViewItem &parent);
|
||||
|
||||
// virtual bool IsEnabled(const wxDataViewItem &item,
|
||||
// unsigned int col) const override;
|
||||
virtual bool IsEnabled(const wxDataViewItem &item, unsigned int col) const override;
|
||||
|
||||
virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override;
|
||||
virtual bool IsContainer(const wxDataViewItem &item) const override;
|
||||
@ -394,8 +459,35 @@ public:
|
||||
// Is the container just a header or an item with all columns
|
||||
// In our case it is an item with all columns
|
||||
virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; }
|
||||
|
||||
wxDataViewItem HasSettings(const wxDataViewItem &item) const;
|
||||
bool IsSettingsItem(const wxDataViewItem &item) const;
|
||||
void UpdateSettingsDigest(const wxDataViewItem &item, const std::vector<std::string>& categories);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// PrusaBitmapTextRenderer
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class PrusaBitmapTextRenderer : public wxDataViewCustomRenderer
|
||||
{
|
||||
public:
|
||||
PrusaBitmapTextRenderer( wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT,
|
||||
int align = wxDVR_DEFAULT_ALIGNMENT):
|
||||
wxDataViewCustomRenderer(wxT("wxObject"), mode, align) {}
|
||||
|
||||
bool SetValue(const wxVariant &value);
|
||||
bool GetValue(wxVariant &value) const;
|
||||
|
||||
virtual bool Render(wxRect cell, wxDC *dc, int state);
|
||||
virtual wxSize GetSize() const;
|
||||
|
||||
virtual bool HasEditorCtrl() const { return false; }
|
||||
|
||||
private:
|
||||
// wxDataViewIconText m_value;
|
||||
PrusaDataViewBitmapText m_value;
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -516,7 +608,7 @@ public:
|
||||
int maxValue,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxSL_HORIZONTAL,
|
||||
long style = wxSL_VERTICAL,
|
||||
const wxValidator& val = wxDefaultValidator,
|
||||
const wxString& name = wxEmptyString);
|
||||
~PrusaDoubleSlider(){}
|
||||
@ -528,6 +620,8 @@ public:
|
||||
return m_higher_value;
|
||||
}
|
||||
int GetActiveValue() const;
|
||||
double GetLowerValueD() const { return get_double_value(ssLower); }
|
||||
double GetHigherValueD() const { return get_double_value(ssHigher); }
|
||||
wxSize DoGetBestSize() const override;
|
||||
void SetLowerValue(const int lower_val);
|
||||
void SetHigherValue(const int higher_val);
|
||||
@ -538,6 +632,7 @@ public:
|
||||
void SetSliderValues(const std::vector<std::pair<int, double>>& values) {
|
||||
m_values = values;
|
||||
}
|
||||
void ChangeOneLayerLock();
|
||||
|
||||
void OnPaint(wxPaintEvent& ){ render();}
|
||||
void OnLeftDown(wxMouseEvent& event);
|
||||
@ -583,6 +678,7 @@ protected:
|
||||
wxCoord get_position_from_value(const int value);
|
||||
wxSize get_size();
|
||||
void get_size(int *w, int *h);
|
||||
double get_double_value(const SelectedSlider& selection) const;
|
||||
|
||||
private:
|
||||
int m_min_value;
|
||||
|
@ -87,26 +87,21 @@ void add_frequently_changed_parameters(SV *ui_parent, SV *ui_sizer, SV *ui_p_siz
|
||||
(wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"),
|
||||
(wxFlexGridSizer*)wxPli_sv_2_object(aTHX_ ui_p_sizer, "Wx::FlexGridSizer")); %};
|
||||
|
||||
void add_expert_mode_part( SV *ui_parent, SV *ui_sizer,
|
||||
Model *model,
|
||||
int event_object_selection_changed,
|
||||
int event_object_settings_changed,
|
||||
int event_remove_object,
|
||||
int event_update_scene)
|
||||
%code%{ Slic3r::GUI::add_expert_mode_part( (wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"),
|
||||
(wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"),
|
||||
*model,
|
||||
event_object_selection_changed,
|
||||
event_object_settings_changed,
|
||||
event_remove_object,
|
||||
event_update_scene); %};
|
||||
void set_model_events_from_perl(Model *model,
|
||||
int event_object_selection_changed,
|
||||
int event_object_settings_changed,
|
||||
int event_remove_object,
|
||||
int event_update_scene)
|
||||
%code%{ Slic3r::GUI::set_model_events_from_perl(*model,
|
||||
event_object_selection_changed,
|
||||
event_object_settings_changed,
|
||||
event_remove_object,
|
||||
event_update_scene); %};
|
||||
|
||||
void set_objects_from_perl( SV *ui_parent,
|
||||
SV *frequently_changed_parameters_sizer,
|
||||
SV *expert_mode_part_sizer,
|
||||
SV *scrolled_window_sizer,
|
||||
SV *info_sizer,
|
||||
SV *btn_export_gcode,
|
||||
SV *btn_export_stl,
|
||||
SV *btn_reslice,
|
||||
SV *btn_print,
|
||||
SV *btn_send_gcode,
|
||||
@ -114,10 +109,8 @@ void set_objects_from_perl( SV *ui_parent,
|
||||
%code%{ Slic3r::GUI::set_objects_from_perl(
|
||||
(wxWindow *)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"),
|
||||
(wxBoxSizer *)wxPli_sv_2_object(aTHX_ frequently_changed_parameters_sizer, "Wx::BoxSizer"),
|
||||
(wxBoxSizer *)wxPli_sv_2_object(aTHX_ expert_mode_part_sizer, "Wx::BoxSizer"),
|
||||
(wxBoxSizer *)wxPli_sv_2_object(aTHX_ scrolled_window_sizer, "Wx::BoxSizer"),
|
||||
(wxBoxSizer *)wxPli_sv_2_object(aTHX_ info_sizer, "Wx::BoxSizer"),
|
||||
(wxButton *)wxPli_sv_2_object(aTHX_ btn_export_gcode, "Wx::Button"),
|
||||
(wxButton *)wxPli_sv_2_object(aTHX_ btn_export_stl, "Wx::Button"),
|
||||
(wxButton *)wxPli_sv_2_object(aTHX_ btn_reslice, "Wx::Button"),
|
||||
(wxButton *)wxPli_sv_2_object(aTHX_ btn_print, "Wx::Button"),
|
||||
(wxButton *)wxPli_sv_2_object(aTHX_ btn_send_gcode, "Wx::Button"),
|
||||
@ -152,6 +145,9 @@ void unselect_objects()
|
||||
void select_current_object(int idx)
|
||||
%code%{ Slic3r::GUI::select_current_object(idx); %};
|
||||
|
||||
void select_current_volume(int idx, int vol_idx)
|
||||
%code%{ Slic3r::GUI::select_current_volume(idx, vol_idx); %};
|
||||
|
||||
void remove_obj()
|
||||
%code%{ Slic3r::GUI::remove(); %};
|
||||
|
||||
@ -170,16 +166,23 @@ void desktop_open_datadir_folder()
|
||||
void fix_model_by_win10_sdk_gui(ModelObject *model_object_src, Print *print, Model *model_dst)
|
||||
%code%{ Slic3r::fix_model_by_win10_sdk_gui(*model_object_src, *print, *model_dst); %};
|
||||
|
||||
void set_3DScene(SV *scene)
|
||||
%code%{ Slic3r::GUI::set_3DScene((_3DScene *)wxPli_sv_2_object(aTHX_ scene, "Slic3r::Model::3DScene") ); %};
|
||||
|
||||
void register_on_request_update_callback(SV* callback)
|
||||
%code%{ Slic3r::GUI::g_on_request_update_callback.register_callback(callback); %};
|
||||
|
||||
void deregister_on_request_update_callback()
|
||||
%code%{ Slic3r::GUI::g_on_request_update_callback.deregister_callback(); %};
|
||||
|
||||
//void create_double_slider(SV *ui_parent, SV *ui_ds)
|
||||
// %code%{ Slic3r::GUI::create_double_slider( (wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"),
|
||||
// (wxControl*)wxPli_sv_2_object(aTHX_ ui_ds, "Wx::Control")); %};
|
||||
void create_double_slider(SV *ui_parent, SV *ui_sizer, SV *ui_canvas)
|
||||
%code%{ Slic3r::GUI::create_double_slider( (wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"),
|
||||
(wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"),
|
||||
(wxGLCanvas*)wxPli_sv_2_object(aTHX_ ui_canvas, "Wx::GLCanvas")); %};
|
||||
|
||||
void update_double_slider(bool force_sliders_full_range)
|
||||
%code%{ Slic3r::GUI::update_double_slider(force_sliders_full_range); %};
|
||||
|
||||
void reset_double_slider()
|
||||
%code%{ Slic3r::GUI::reset_double_slider(); %};
|
||||
|
||||
void enable_action_buttons(bool enable)
|
||||
%code%{ Slic3r::GUI::enable_action_buttons(enable); %};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user