mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-06 21:44:08 -06:00
Initial work for custom bed shape
This commit is contained in:
parent
b142469cf3
commit
4fe2128fc4
8 changed files with 248 additions and 31 deletions
167
lib/Slic3r/GUI/BedShapeDialog.pm
Normal file
167
lib/Slic3r/GUI/BedShapeDialog.pm
Normal file
|
@ -0,0 +1,167 @@
|
|||
package Slic3r::GUI::BedShapeDialog;
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
|
||||
use List::Util qw(min max);
|
||||
use Slic3r::Geometry qw(PI X Y unscale);
|
||||
use Wx qw(:dialog :id :misc :sizer :choicebook wxTAB_TRAVERSAL);
|
||||
use Wx::Event qw(EVT_CLOSE EVT_BUTTON EVT_CHOICE);
|
||||
use base 'Wx::Dialog';
|
||||
|
||||
use constant SHAPE_RECTANGULAR => 0;
|
||||
use constant SHAPE_CIRCULAR => 1;
|
||||
use constant SHAPE_CUSTOM => 2;
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my ($parent, $default) = @_;
|
||||
my $self = $class->SUPER::new($parent, -1, "Bed Shape", wxDefaultPosition, [350,700], wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
|
||||
|
||||
my $box = Wx::StaticBox->new($self, -1, "Shape");
|
||||
my $sbsizer = Wx::StaticBoxSizer->new($box, wxVERTICAL);
|
||||
|
||||
# shape options
|
||||
$self->{shape_options_book} = Wx::Choicebook->new($self, -1, wxDefaultPosition, [300,-1], wxCHB_TOP);
|
||||
$sbsizer->Add($self->{shape_options_book});
|
||||
|
||||
$self->{optgroups} = [];
|
||||
$self->_init_shape_options_page('Rectangular', [
|
||||
{
|
||||
opt_key => 'rect_size',
|
||||
type => 'point',
|
||||
label => 'Size',
|
||||
tooltip => 'Size in X and Y of the rectangular plate.',
|
||||
default => [200,200],
|
||||
},
|
||||
{
|
||||
opt_key => 'rect_origin',
|
||||
type => 'select',
|
||||
label => 'Origin',
|
||||
tooltip => 'Position of the 0,0 point.',
|
||||
labels => ['Front left corner','Center'],
|
||||
values => ['corner','center'],
|
||||
default => 'corner',
|
||||
},
|
||||
]);
|
||||
|
||||
# right pane with preview canvas
|
||||
my $canvas;
|
||||
|
||||
# main sizer
|
||||
my $top_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
|
||||
$top_sizer->Add($sbsizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
|
||||
$top_sizer->Add($canvas, 1, wxEXPAND | wxALL, 0) if $canvas;
|
||||
|
||||
my $main_sizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
$main_sizer->Add($top_sizer, 1, wxEXPAND);
|
||||
$main_sizer->Add($self->CreateButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND);
|
||||
|
||||
$self->SetSizer($main_sizer);
|
||||
$self->SetMinSize($self->GetSize);
|
||||
$main_sizer->SetSizeHints($self);
|
||||
|
||||
# needed to actually free memory
|
||||
EVT_CLOSE($self, sub {
|
||||
$self->EndModal(wxID_OK);
|
||||
$self->Destroy;
|
||||
});
|
||||
|
||||
$self->_set_shape($default);
|
||||
$self->_update_preview;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub _set_shape {
|
||||
my ($self, $points) = @_;
|
||||
|
||||
$self->{bed_shape} = $points;
|
||||
|
||||
# is this a rectangle?
|
||||
if (@$points == 4) {
|
||||
my $polygon = Slic3r::Polygon->new_scale(@$points);
|
||||
my $lines = $polygon->lines;
|
||||
if ($lines->[0]->parallel_to_line($lines->[2]) && $lines->[1]->parallel_to_line($lines->[3])) {
|
||||
# okay, it's a rectangle
|
||||
# let's check whether origin is at a known point
|
||||
my $x_min = min(map $_->[X], @$points);
|
||||
my $x_max = max(map $_->[X], @$points);
|
||||
my $y_min = min(map $_->[Y], @$points);
|
||||
my $y_max = max(map $_->[Y], @$points);
|
||||
my $origin;
|
||||
if ($x_min == 0 && $y_min == 0) {
|
||||
$origin = 'corner';
|
||||
} elsif (($x_min + $x_max)/2 == 0 && ($y_min + $y_max)/2 == 0) {
|
||||
$origin = 'center';
|
||||
}
|
||||
if (defined $origin) {
|
||||
$self->{shape_options_book}->SetSelection(SHAPE_RECTANGULAR);
|
||||
my $optgroup = $self->{optgroups}[SHAPE_RECTANGULAR];
|
||||
$optgroup->set_value('rect_size', [ $x_max-$x_min, $y_max-$y_min ]);
|
||||
$optgroup->set_value('rect_origin', $origin);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$self->{shape_options_book}->SetSelection(SHAPE_CUSTOM);
|
||||
}
|
||||
|
||||
sub _update_shape {
|
||||
my ($self) = @_;
|
||||
|
||||
my $page_idx = $self->{shape_options_book}->GetSelection;
|
||||
if ($page_idx == SHAPE_RECTANGULAR) {
|
||||
return if grep !defined($self->{"_$_"}), qw(rect_size rect_origin); # not loaded yet
|
||||
my ($x, $y) = @{$self->{_rect_size}};
|
||||
my ($x0, $y0) = (0,0);
|
||||
my ($x1, $y1) = ($x,$y);
|
||||
if ($self->{_rect_origin} eq 'center') {
|
||||
$x0 -= $x/2;
|
||||
$x1 -= $x/2;
|
||||
$y0 -= $y/2;
|
||||
$y1 -= $y/2;
|
||||
}
|
||||
$self->{bed_shape} = [
|
||||
[$x0,$y0],
|
||||
[$x1,$y0],
|
||||
[$x1,$y1],
|
||||
[$x0,$y1],
|
||||
];
|
||||
}
|
||||
|
||||
$self->_update_preview;
|
||||
}
|
||||
|
||||
sub _update_preview {
|
||||
my ($self) = @_;
|
||||
|
||||
|
||||
}
|
||||
|
||||
sub _init_shape_options_page {
|
||||
my ($self, $title, $options) = @_;
|
||||
|
||||
my $panel = Wx::Panel->new($self->{shape_options_book});
|
||||
push @{$self->{optgroups}}, my $optgroup = Slic3r::GUI::OptionsGroup->new(
|
||||
parent => $panel,
|
||||
title => 'Settings',
|
||||
options => $options,
|
||||
on_change => sub {
|
||||
my ($opt_key, $value) = @_;
|
||||
$self->{"_$opt_key"} = $value;
|
||||
$self->_update_shape;
|
||||
},
|
||||
label_width => 100,
|
||||
);
|
||||
$panel->SetSizerAndFit($optgroup->sizer);
|
||||
$self->{shape_options_book}->AddPage($panel, $title);
|
||||
}
|
||||
|
||||
sub GetValue {
|
||||
my ($self) = @_;
|
||||
return $self->{bed_shape};
|
||||
}
|
||||
|
||||
1;
|
|
@ -48,6 +48,7 @@ has 'options' => (is => 'ro', required => 1, trigger => 1);
|
|||
has 'lines' => (is => 'lazy');
|
||||
has 'on_change' => (is => 'ro', default => sub { sub {} });
|
||||
has 'no_labels' => (is => 'ro', default => sub { 0 });
|
||||
has 'staticbox' => (is => 'ro', default => sub { 1 });
|
||||
has 'label_width' => (is => 'ro', default => sub { 180 });
|
||||
has 'extra_column' => (is => 'ro');
|
||||
has 'label_font' => (is => 'ro');
|
||||
|
@ -63,9 +64,11 @@ sub _trigger_options {}
|
|||
sub BUILD {
|
||||
my $self = shift;
|
||||
|
||||
{
|
||||
if ($self->staticbox) {
|
||||
my $box = Wx::StaticBox->new($self->parent, -1, $self->title);
|
||||
$self->sizer(Wx::StaticBoxSizer->new($box, wxVERTICAL));
|
||||
} else {
|
||||
$self->sizer(Wx::BoxSizer->new(wxVERTICAL));
|
||||
}
|
||||
|
||||
my $num_columns = $self->extra_column ? 3 : 2;
|
||||
|
@ -79,9 +82,9 @@ sub BUILD {
|
|||
foreach my $line (@{$self->lines}) {
|
||||
if ($line->{sizer}) {
|
||||
$self->sizer->Add($line->{sizer}, 0, wxEXPAND | wxALL, &Wx::wxMAC ? 0 : 15);
|
||||
} elsif ($line->{widget}) {
|
||||
my $window = $line->{widget}->GetWindow($self->parent);
|
||||
$self->sizer->Add($window, 0, wxEXPAND | wxALL, &Wx::wxMAC ? 0 : 15);
|
||||
} elsif ($line->{widget} && $line->{full_width}) {
|
||||
my $sizer = $line->{widget}->($self->parent);
|
||||
$self->sizer->Add($sizer, 0, wxEXPAND | wxALL, &Wx::wxMAC ? 0 : 15);
|
||||
} else {
|
||||
$self->_build_line($line, $grid_sizer);
|
||||
}
|
||||
|
@ -143,7 +146,7 @@ sub _build_line {
|
|||
push @fields, $self->_build_field($opt);
|
||||
push @field_labels, $opt->{label};
|
||||
}
|
||||
if (@fields > 1 || $line->{sidetext}) {
|
||||
if (@fields > 1 || $line->{widget} || $line->{sidetext}) {
|
||||
my $sizer = Wx::BoxSizer->new(wxHORIZONTAL);
|
||||
for my $i (0 .. $#fields) {
|
||||
if (@fields > 1 && $field_labels[$i]) {
|
||||
|
@ -153,7 +156,10 @@ sub _build_line {
|
|||
}
|
||||
$sizer->Add($fields[$i], 0, wxALIGN_CENTER_VERTICAL, 0);
|
||||
}
|
||||
if ($line->{sidetext}) {
|
||||
if ($line->{widget}) {
|
||||
my $widget_sizer = $line->{widget}->($self->parent);
|
||||
$sizer->Add($widget_sizer, 0, wxEXPAND | wxALL, &Wx::wxMAC ? 0 : 15);
|
||||
} elsif ($line->{sidetext}) {
|
||||
my $sidetext = Wx::StaticText->new($self->parent, -1, $line->{sidetext}, wxDefaultPosition, wxDefaultSize);
|
||||
$sidetext->SetFont($self->sidetext_font);
|
||||
$sizer->Add($sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL , 4);
|
||||
|
@ -479,26 +485,24 @@ sub _config_methods {
|
|||
}
|
||||
|
||||
package Slic3r::GUI::OptionsGroup::StaticTextLine;
|
||||
use Moo;
|
||||
use Wx qw(:misc :systemsettings);
|
||||
use base 'Wx::StaticText';
|
||||
|
||||
sub GetWindow {
|
||||
my $self = shift;
|
||||
my ($parent) = @_;
|
||||
sub new {
|
||||
my ($class, $parent) = @_;
|
||||
|
||||
$self->{statictext} = Wx::StaticText->new($parent, -1, "foo", wxDefaultPosition, wxDefaultSize);
|
||||
my $self = $class->SUPER::new($parent, -1, "", wxDefaultPosition, wxDefaultSize);
|
||||
my $font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
$self->{statictext}->SetFont($font);
|
||||
return $self->{statictext};
|
||||
$self->SetFont($font);
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub SetText {
|
||||
my $self = shift;
|
||||
my ($value) = @_;
|
||||
my ($self, $value) = @_;
|
||||
|
||||
$self->{statictext}->SetLabel($value);
|
||||
$self->{statictext}->Wrap(400);
|
||||
$self->{statictext}->GetParent->Layout;
|
||||
$self->SetLabel($value);
|
||||
$self->Wrap(400);
|
||||
$self->GetParent->Layout;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -599,7 +599,11 @@ sub build {
|
|||
Slic3r::GUI::OptionsGroup->single_option_line('cooling'),
|
||||
{
|
||||
label => '',
|
||||
widget => ($self->{description_line} = Slic3r::GUI::OptionsGroup::StaticTextLine->new),
|
||||
full_width => 1,
|
||||
widget => sub {
|
||||
my ($parent) = @_;
|
||||
return $self->{description_line} = Slic3r::GUI::OptionsGroup::StaticTextLine->new($parent);
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -662,6 +666,8 @@ sub on_value_change {
|
|||
|
||||
package Slic3r::GUI::Tab::Printer;
|
||||
use base 'Slic3r::GUI::Tab';
|
||||
use Wx qw(:sizer :button :bitmap :misc :id);
|
||||
use Wx::Event qw(EVT_BUTTON);
|
||||
|
||||
sub name { 'printer' }
|
||||
sub title { 'Printer Settings' }
|
||||
|
@ -671,10 +677,42 @@ sub build {
|
|||
|
||||
$self->{extruders_count} = 1;
|
||||
|
||||
my $bed_shape_widget = sub {
|
||||
my ($parent) = @_;
|
||||
|
||||
my $btn = Wx::Button->new($parent, -1, "Set…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
|
||||
$btn->SetFont($Slic3r::GUI::small_font);
|
||||
if ($Slic3r::GUI::have_button_icons) {
|
||||
$btn->SetBitmap(Wx::Bitmap->new("$Slic3r::var/cog.png", wxBITMAP_TYPE_PNG));
|
||||
}
|
||||
|
||||
my $sizer = Wx::BoxSizer->new(wxHORIZONTAL);
|
||||
$sizer->Add($btn);
|
||||
|
||||
EVT_BUTTON($self, $btn, sub {
|
||||
my $dlg = Slic3r::GUI::BedShapeDialog->new($self, $self->{config}->bed_shape);
|
||||
if ($dlg->ShowModal == wxID_OK) {
|
||||
my $value = $dlg->GetValue;
|
||||
$self->{config}->set('bed_shape', $value);
|
||||
$self->on_value_change('bed_shape', $value);
|
||||
}
|
||||
});
|
||||
|
||||
return $sizer;
|
||||
};
|
||||
|
||||
$self->add_options_page('General', 'printer_empty.png', optgroups => [
|
||||
{
|
||||
title => 'Size and coordinates',
|
||||
options => [qw(bed_size print_center z_offset)],
|
||||
options => [qw(bed_shape print_center z_offset)],
|
||||
lines => [
|
||||
{
|
||||
label => 'Bed shape',
|
||||
widget => $bed_shape_widget,
|
||||
},
|
||||
Slic3r::GUI::OptionsGroup->single_option_line('print_center'),
|
||||
Slic3r::GUI::OptionsGroup->single_option_line('z_offset'),
|
||||
],
|
||||
},
|
||||
{
|
||||
title => 'Firmware',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue