mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-22 06:04:01 -06:00
Merge remote-tracking branch 'origin/dev' into new_main_page_ui
This commit is contained in:
commit
73ee3f77c3
86 changed files with 4884 additions and 2922 deletions
|
@ -70,24 +70,11 @@ sub new {
|
|||
eval { Wx::ToolTip::SetAutoPop(32767) };
|
||||
|
||||
# initialize status bar
|
||||
$self->{statusbar} = Slic3r::GUI::ProgressStatusBar->new($self, Wx::NewId);
|
||||
$self->{statusbar} = Slic3r::GUI::ProgressStatusBar->new();
|
||||
$self->{statusbar}->Embed;
|
||||
$self->{statusbar}->SetStatusText(L("Version ").$Slic3r::VERSION.L(" - Remember to check for updates at http://github.com/prusa3d/slic3r/releases"));
|
||||
$self->SetStatusBar($self->{statusbar});
|
||||
|
||||
# Make the global status bar and its progress indicator available in C++
|
||||
$appController->set_global_progress_indicator(
|
||||
$self->{statusbar}->{prog}->GetId(),
|
||||
$self->{statusbar}->GetId(),
|
||||
);
|
||||
|
||||
$appController->set_model($self->{plater}->{model});
|
||||
$appController->set_print($self->{plater}->{print});
|
||||
|
||||
# Make the global status bar and its progress indicator available in C++
|
||||
$appController->set_global_progress_indicator(
|
||||
$self->{statusbar}->{prog}->GetId(),
|
||||
$self->{statusbar}->GetId(),
|
||||
);
|
||||
$appController->set_global_progress_indicator($self->{statusbar});
|
||||
|
||||
$appController->set_model($self->{plater}->{model});
|
||||
$appController->set_print($self->{plater}->{print});
|
||||
|
|
|
@ -85,9 +85,13 @@ sub new {
|
|||
|
||||
# Initialize handlers for canvases
|
||||
my $on_select_object = sub {
|
||||
my ($obj_idx) = @_;
|
||||
# Ignore the special objects (the wipe tower proxy and such).
|
||||
$self->select_object((defined($obj_idx) && $obj_idx >= 0 && $obj_idx < 1000) ? $obj_idx : undef);
|
||||
my ($obj_idx, $vol_idx) = @_;
|
||||
|
||||
if (($obj_idx != -1) && ($vol_idx == -1)) {
|
||||
# Ignore the special objects (the wipe tower proxy and such).
|
||||
$self->select_object((defined($obj_idx) && $obj_idx >= 0 && $obj_idx < 1000) ? $obj_idx : undef);
|
||||
$self->item_changed_selection($obj_idx) if (defined($obj_idx));
|
||||
}
|
||||
};
|
||||
my $on_double_click = sub {
|
||||
$self->object_settings_dialog if $self->selected_object;
|
||||
|
@ -150,16 +154,15 @@ sub new {
|
|||
};
|
||||
|
||||
# callback to react to gizmo rotate
|
||||
# omitting last three parameters means rotation around Z
|
||||
# otherwise they are the components of the rotation axis vector
|
||||
my $on_gizmo_rotate = sub {
|
||||
my ($angle) = @_;
|
||||
$self->rotate(rad2deg($angle), Z, 'absolute');
|
||||
};
|
||||
|
||||
# callback to react to gizmo flatten
|
||||
my $on_gizmo_flatten = sub {
|
||||
my ($angle, $axis_x, $axis_y, $axis_z) = @_;
|
||||
if (!defined $axis_x) {
|
||||
$self->rotate(rad2deg($angle), Z, 'absolute');
|
||||
}
|
||||
else {
|
||||
$self->rotate(rad2deg($angle), undef, 'absolute', $axis_x, $axis_y, $axis_z) if $angle != 0;
|
||||
}
|
||||
$self->rotate(rad2deg($angle), undef, 'absolute', $axis_x, $axis_y, $axis_z) if $angle != 0;
|
||||
};
|
||||
|
||||
# callback to update object's geometry info while using gizmos
|
||||
|
@ -218,6 +221,29 @@ sub new {
|
|||
my $state = Slic3r::GUI::_3DScene::is_toolbar_item_pressed($self->{canvas3D}, "layersediting");
|
||||
$self->on_layer_editing_toggled($state);
|
||||
};
|
||||
|
||||
my $on_action_selectbyparts = sub {
|
||||
my $curr = Slic3r::GUI::_3DScene::get_select_by($self->{canvas3D});
|
||||
if ($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);
|
||||
}
|
||||
elsif ($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 ($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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
# Initialize 3D plater
|
||||
if ($Slic3r::GUI::have_OpenGL) {
|
||||
|
@ -237,6 +263,7 @@ sub new {
|
|||
Slic3r::GUI::_3DScene::register_on_enable_action_buttons_callback($self->{canvas3D}, $enable_action_buttons);
|
||||
Slic3r::GUI::_3DScene::register_on_gizmo_scale_uniformly_callback($self->{canvas3D}, $on_gizmo_scale_uniformly);
|
||||
Slic3r::GUI::_3DScene::register_on_gizmo_rotate_callback($self->{canvas3D}, $on_gizmo_rotate);
|
||||
Slic3r::GUI::_3DScene::register_on_gizmo_flatten_callback($self->{canvas3D}, $on_gizmo_flatten);
|
||||
Slic3r::GUI::_3DScene::register_on_update_geometry_info_callback($self->{canvas3D}, $on_update_geometry_info);
|
||||
Slic3r::GUI::_3DScene::register_action_add_callback($self->{canvas3D}, $on_action_add);
|
||||
Slic3r::GUI::_3DScene::register_action_delete_callback($self->{canvas3D}, $on_action_delete);
|
||||
|
@ -248,6 +275,7 @@ sub new {
|
|||
Slic3r::GUI::_3DScene::register_action_cut_callback($self->{canvas3D}, $on_action_cut);
|
||||
Slic3r::GUI::_3DScene::register_action_settings_callback($self->{canvas3D}, $on_action_settings);
|
||||
Slic3r::GUI::_3DScene::register_action_layersediting_callback($self->{canvas3D}, $on_action_layersediting);
|
||||
Slic3r::GUI::_3DScene::register_action_selectbyparts_callback($self->{canvas3D}, $on_action_selectbyparts);
|
||||
Slic3r::GUI::_3DScene::enable_gizmos($self->{canvas3D}, 1);
|
||||
Slic3r::GUI::_3DScene::enable_toolbar($self->{canvas3D}, 1);
|
||||
Slic3r::GUI::_3DScene::enable_shader($self->{canvas3D}, 1);
|
||||
|
@ -871,6 +899,15 @@ sub load_files {
|
|||
$model->convert_multipart_object(scalar(@$nozzle_dmrs)) if $dialog->ShowModal() == wxID_YES;
|
||||
}
|
||||
|
||||
# objects imported from 3mf require a call to center_around_origin to have gizmos working properly and this call
|
||||
# need to be done after looks_like_multipart_object detection
|
||||
if ($input_file =~ /.3[mM][fF]$/)
|
||||
{
|
||||
foreach my $model_object (@{$model->objects}) {
|
||||
$model_object->center_around_origin; # also aligns object to Z = 0
|
||||
}
|
||||
}
|
||||
|
||||
if ($one_by_one) {
|
||||
push @obj_idx, $self->load_model_objects(@{$model->objects});
|
||||
} else {
|
||||
|
@ -1161,13 +1198,12 @@ sub rotate {
|
|||
}
|
||||
|
||||
# Let's calculate vector of rotation axis (if we don't have it already)
|
||||
# The minus is there so that the direction is the same as was established
|
||||
if (defined $axis) {
|
||||
if ($axis == X) {
|
||||
$axis_x = -1;
|
||||
$axis_x = 1;
|
||||
}
|
||||
if ($axis == Y) {
|
||||
$axis_y = -1;
|
||||
$axis_y = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1202,11 +1238,7 @@ sub rotate {
|
|||
# $model_object->center_around_origin;
|
||||
# $self->reset_thumbnail($obj_idx);
|
||||
}
|
||||
|
||||
if (defined $axis) {
|
||||
Slic3r::GUI::update_rotation_value(deg2rad($angle), $axis == X ? "x" : ($axis == Y ? "y" : "z"));
|
||||
}
|
||||
|
||||
|
||||
# update print and start background processing
|
||||
$self->{print}->add_model_object($model_object, $obj_idx);
|
||||
|
||||
|
@ -1676,7 +1708,9 @@ sub on_progress_event {
|
|||
my ($self, $percent, $message) = @_;
|
||||
|
||||
$self->statusbar->SetProgress($percent);
|
||||
$self->statusbar->SetStatusText("$message…");
|
||||
# TODO: three dot character is not properly translated into C++
|
||||
# $self->statusbar->SetStatusText("$message…");
|
||||
$self->statusbar->SetStatusText("$message...");
|
||||
}
|
||||
|
||||
# Called when the G-code export finishes, either successfully or with an error.
|
||||
|
@ -2129,17 +2163,18 @@ sub on_config_change {
|
|||
$self->schedule_background_process;
|
||||
}
|
||||
|
||||
sub item_changed_selection{
|
||||
sub item_changed_selection {
|
||||
my ($self, $obj_idx) = @_;
|
||||
|
||||
# $self->{canvas}->Refresh;
|
||||
if ($self->{canvas3D}) {
|
||||
Slic3r::GUI::_3DScene::deselect_volumes($self->{canvas3D});
|
||||
if ($obj_idx >= 0){
|
||||
my $selections = $self->collect_selections;
|
||||
Slic3r::GUI::_3DScene::update_volumes_selection($self->{canvas3D}, \@$selections);
|
||||
if (($obj_idx >= 0) && ($obj_idx < 1000)) { # skip if wipe tower selected
|
||||
if ($self->{canvas3D}) {
|
||||
Slic3r::GUI::_3DScene::deselect_volumes($self->{canvas3D});
|
||||
if ($obj_idx >= 0) {
|
||||
my $selections = $self->collect_selections;
|
||||
Slic3r::GUI::_3DScene::update_volumes_selection($self->{canvas3D}, \@$selections);
|
||||
}
|
||||
# Slic3r::GUI::_3DScene::render($self->{canvas3D});
|
||||
}
|
||||
Slic3r::GUI::_3DScene::render($self->{canvas3D});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2359,12 +2394,24 @@ sub selection_changed {
|
|||
}
|
||||
|
||||
Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, "layersediting", $layers_height_allowed);
|
||||
|
||||
my $can_select_by_parts = 0;
|
||||
|
||||
if ($have_sel) {
|
||||
my $model_object = $self->{model}->objects->[$obj_idx];
|
||||
$can_select_by_parts = ($obj_idx >= 0) && ($obj_idx < 1000) && ($model_object->volumes_count > 1);
|
||||
Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, "fewer", $model_object->instances_count > 1);
|
||||
}
|
||||
|
||||
if ($can_select_by_parts) {
|
||||
# first disable to let the item in the toolbar to switch to the unpressed state
|
||||
Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, "selectbyparts", 0);
|
||||
Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, "selectbyparts", 1);
|
||||
} else {
|
||||
Slic3r::GUI::_3DScene::enable_toolbar_item($self->{canvas3D}, "selectbyparts", 0);
|
||||
Slic3r::GUI::_3DScene::set_select_by($self->{canvas3D}, 'object');
|
||||
}
|
||||
|
||||
if ($self->{object_info_size}) { # have we already loaded the info pane?
|
||||
if ($have_sel) {
|
||||
my $model_object = $self->{model}->objects->[$obj_idx];
|
||||
|
|
|
@ -1,144 +1,18 @@
|
|||
# Status bar at the bottom of the main screen.
|
||||
# Now it just implements cancel cb on perl side, every other functionality is
|
||||
# in C++
|
||||
|
||||
package Slic3r::GUI::ProgressStatusBar;
|
||||
package Slic3r::GUI::ProgressStatusBar;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Wx qw(:gauge :misc);
|
||||
use base 'Wx::StatusBar';
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $self = $class->SUPER::new(@_);
|
||||
|
||||
$self->{busy} = 0;
|
||||
$self->{timer} = Wx::Timer->new($self);
|
||||
$self->{prog} = Wx::Gauge->new($self, wxGA_HORIZONTAL, 100, wxDefaultPosition, wxDefaultSize);
|
||||
$self->{prog}->Hide;
|
||||
$self->{cancelbutton} = Wx::Button->new($self, -1, "Cancel", wxDefaultPosition, wxDefaultSize);
|
||||
$self->{cancelbutton}->Hide;
|
||||
|
||||
$self->SetFieldsCount(3);
|
||||
$self->SetStatusWidths(-1, 150, 155);
|
||||
|
||||
Wx::Event::EVT_TIMER($self, \&OnTimer, $self->{timer});
|
||||
Wx::Event::EVT_SIZE($self, \&OnSize);
|
||||
Wx::Event::EVT_BUTTON($self, $self->{cancelbutton}, sub {
|
||||
$self->{cancel_cb}->();
|
||||
$self->{cancelbutton}->Hide;
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub DESTROY {
|
||||
my $self = shift;
|
||||
$self->{timer}->Stop if $self->{timer} && $self->{timer}->IsRunning;
|
||||
}
|
||||
|
||||
sub OnSize {
|
||||
my ($self, $event) = @_;
|
||||
|
||||
my %fields = (
|
||||
# 0 is reserved for status text
|
||||
1 => $self->{cancelbutton},
|
||||
2 => $self->{prog},
|
||||
);
|
||||
|
||||
foreach (keys %fields) {
|
||||
my $rect = $self->GetFieldRect($_);
|
||||
my $offset = &Wx::wxGTK ? 1 : 0; # add a cosmetic 1 pixel offset on wxGTK
|
||||
my $pos = [$rect->GetX + $offset, $rect->GetY + $offset];
|
||||
$fields{$_}->Move($pos);
|
||||
$fields{$_}->SetSize($rect->GetWidth - $offset, $rect->GetHeight);
|
||||
}
|
||||
|
||||
$event->Skip;
|
||||
}
|
||||
|
||||
sub OnTimer {
|
||||
my ($self, $event) = @_;
|
||||
|
||||
if ($self->{prog}->IsShown) {
|
||||
$self->{timer}->Stop;
|
||||
}
|
||||
$self->{prog}->Pulse if $self->{_busy};
|
||||
}
|
||||
our $cancel_cb;
|
||||
|
||||
sub SetCancelCallback {
|
||||
my $self = shift;
|
||||
my ($cb) = @_;
|
||||
$self->{cancel_cb} = $cb;
|
||||
$cb ? $self->{cancelbutton}->Show : $self->{cancelbutton}->Hide;
|
||||
}
|
||||
|
||||
sub Run {
|
||||
my $self = shift;
|
||||
my $rate = shift || 100;
|
||||
if (!$self->{timer}->IsRunning) {
|
||||
$self->{timer}->Start($rate);
|
||||
}
|
||||
}
|
||||
|
||||
sub GetProgress {
|
||||
my $self = shift;
|
||||
return $self->{prog}->GetValue;
|
||||
}
|
||||
|
||||
sub SetProgress {
|
||||
my $self = shift;
|
||||
my ($val) = @_;
|
||||
if (!$self->{prog}->IsShown) {
|
||||
$self->ShowProgress(1);
|
||||
}
|
||||
if ($val == $self->{prog}->GetRange) {
|
||||
$self->{prog}->SetValue(0);
|
||||
$self->ShowProgress(0);
|
||||
} else {
|
||||
$self->{prog}->SetValue($val);
|
||||
}
|
||||
}
|
||||
|
||||
sub SetRange {
|
||||
my $self = shift;
|
||||
my ($val) = @_;
|
||||
|
||||
if ($val != $self->{prog}->GetRange) {
|
||||
$self->{prog}->SetRange($val);
|
||||
}
|
||||
}
|
||||
|
||||
sub ShowProgress {
|
||||
my $self = shift;
|
||||
my ($show) = @_;
|
||||
|
||||
$self->{prog}->Show($show);
|
||||
$self->{prog}->Pulse;
|
||||
}
|
||||
|
||||
sub StartBusy {
|
||||
my $self = shift;
|
||||
my $rate = shift || 100;
|
||||
|
||||
$self->{_busy} = 1;
|
||||
$self->ShowProgress(1);
|
||||
if (!$self->{timer}->IsRunning) {
|
||||
$self->{timer}->Start($rate);
|
||||
}
|
||||
}
|
||||
|
||||
sub StopBusy {
|
||||
my $self = shift;
|
||||
|
||||
$self->{timer}->Stop;
|
||||
$self->ShowProgress(0);
|
||||
$self->{prog}->SetValue(0);
|
||||
$self->{_busy} = 0;
|
||||
}
|
||||
|
||||
sub IsBusy {
|
||||
my $self = shift;
|
||||
return $self->{_busy};
|
||||
$cancel_cb = $cb;
|
||||
$cb ? $self->ShowCancelButton : $self->HideCancelButton;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue