Initial work for a controller GUI
This commit is contained in:
parent
29d64107de
commit
c06ce3b58c
@ -9,6 +9,8 @@ use Slic3r::GUI::AboutDialog;
|
||||
use Slic3r::GUI::BedShapeDialog;
|
||||
use Slic3r::GUI::BonjourBrowser;
|
||||
use Slic3r::GUI::ConfigWizard;
|
||||
use Slic3r::GUI::Controller::Frame;
|
||||
use Slic3r::GUI::Controller::PrinterPanel;
|
||||
use Slic3r::GUI::MainFrame;
|
||||
use Slic3r::GUI::Notifier;
|
||||
use Slic3r::GUI::Plater;
|
||||
@ -292,4 +294,12 @@ sub CallAfter {
|
||||
push @cb, $cb;
|
||||
}
|
||||
|
||||
sub show_printer_controller {
|
||||
my ($self) = @_;
|
||||
|
||||
$self->{controller_frame} = Slic3r::GUI::Controller::Frame->new;
|
||||
$self->{controller_frame}->Show;
|
||||
return $self->{controller_frame};
|
||||
}
|
||||
|
||||
1;
|
||||
|
33
lib/Slic3r/GUI/Controller/Frame.pm
Normal file
33
lib/Slic3r/GUI/Controller/Frame.pm
Normal file
@ -0,0 +1,33 @@
|
||||
package Slic3r::GUI::Controller::Frame;
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
|
||||
use Wx qw(:frame :id :misc :sizer);
|
||||
use Wx::Event qw(EVT_CLOSE);
|
||||
use base 'Wx::Frame';
|
||||
|
||||
sub new {
|
||||
my ($class) = @_;
|
||||
my $self = $class->SUPER::new(undef, -1, "Controller", wxDefaultPosition, [500,350], wxDEFAULT_FRAME_STYLE);
|
||||
|
||||
$self->{sizer} = my $sizer = Wx::BoxSizer->new(wxVERTICAL);
|
||||
$sizer->Add(Slic3r::GUI::Controller::PrinterPanel->new($self), 1, wxEXPAND);
|
||||
|
||||
$self->SetSizer($sizer);
|
||||
$self->SetMinSize($self->GetSize);
|
||||
$sizer->SetSizeHints($self);
|
||||
$self->Layout;
|
||||
|
||||
EVT_CLOSE($self, sub {
|
||||
my (undef, $event) = @_;
|
||||
|
||||
# ...
|
||||
|
||||
$event->Skip;
|
||||
});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
1;
|
142
lib/Slic3r/GUI/Controller/PrinterPanel.pm
Normal file
142
lib/Slic3r/GUI/Controller/PrinterPanel.pm
Normal file
@ -0,0 +1,142 @@
|
||||
package Slic3r::GUI::Controller::PrinterPanel;
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
|
||||
use Wx qw(:panel :id :misc :sizer :button :bitmap);
|
||||
use Wx::Event qw(EVT_BUTTON);
|
||||
use base qw(Wx::Panel Class::Accessor);
|
||||
|
||||
__PACKAGE__->mk_accessors(qw(sender));
|
||||
|
||||
sub new {
|
||||
my ($class, $parent) = @_;
|
||||
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
$self->{sizer} = my $sizer = Wx::StaticBoxSizer->new(Wx::StaticBox->new($self, -1, "Printer"), wxVERTICAL);
|
||||
|
||||
# connection info
|
||||
{
|
||||
my $conn_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
|
||||
$sizer->Add($conn_sizer, 0, wxEXPAND);
|
||||
{
|
||||
my $text = Wx::StaticText->new($self, -1, "Port:", wxDefaultPosition, wxDefaultSize);
|
||||
$conn_sizer->Add($text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
|
||||
}
|
||||
{
|
||||
$self->{serial_port_combobox} = Wx::ComboBox->new($self, -1, "", wxDefaultPosition, wxDefaultSize, []);
|
||||
$self->scan_serial_ports;
|
||||
$conn_sizer->Add($self->{serial_port_combobox}, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 1);
|
||||
}
|
||||
{
|
||||
$self->{btn_rescan_serial} = my $btn = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new("$Slic3r::var/arrow_rotate_clockwise.png", wxBITMAP_TYPE_PNG),
|
||||
wxDefaultPosition, wxDefaultSize, &Wx::wxBORDER_NONE);
|
||||
$conn_sizer->Add($btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
|
||||
EVT_BUTTON($self, $btn, sub { $self->scan_serial_ports });
|
||||
}
|
||||
{
|
||||
my $text = Wx::StaticText->new($self, -1, "Speed:", wxDefaultPosition, wxDefaultSize);
|
||||
$conn_sizer->Add($text, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
|
||||
}
|
||||
{
|
||||
$self->{serial_speed_combobox} = Wx::ComboBox->new($self, -1, "250000", wxDefaultPosition, wxDefaultSize,
|
||||
["115200", "250000"]);
|
||||
$conn_sizer->Add($self->{serial_speed_combobox}, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
|
||||
}
|
||||
}
|
||||
|
||||
# buttons
|
||||
{
|
||||
my $buttons_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
|
||||
$sizer->Add($buttons_sizer, 0, wxEXPAND);
|
||||
{
|
||||
$self->{btn_connect} = my $btn = Wx::Button->new($self, -1, "Connect", wxDefaultPosition, wxDefaultSize);
|
||||
$buttons_sizer->Add($btn, 0, wxRIGHT, 5);
|
||||
EVT_BUTTON($self, $btn, \&connect);
|
||||
}
|
||||
{
|
||||
$self->{btn_disconnect} = my $btn = Wx::Button->new($self, -1, "Disconnect", wxDefaultPosition, wxDefaultSize);
|
||||
$buttons_sizer->Add($btn, 0, wxRIGHT, 5);
|
||||
EVT_BUTTON($self, $btn, \&disconnect);
|
||||
}
|
||||
}
|
||||
|
||||
# status
|
||||
$self->{status_text} = Wx::StaticText->new($self, -1, "Not connected", wxDefaultPosition, wxDefaultSize);
|
||||
$sizer->Add($self->{status_text}, 0, wxEXPAND);
|
||||
|
||||
$self->SetSizer($sizer);
|
||||
$self->SetMinSize($self->GetSize);
|
||||
$sizer->SetSizeHints($self);
|
||||
|
||||
$self->_update_connection_controls;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub _update_connection_controls {
|
||||
my ($self) = @_;
|
||||
|
||||
if ($self->sender && $self->sender->is_connected) {
|
||||
$self->{btn_connect}->Hide;
|
||||
$self->{btn_disconnect}->Show;
|
||||
$self->{serial_port_combobox}->Disable;
|
||||
$self->{serial_speed_combobox}->Disable;
|
||||
$self->{btn_rescan_serial}->Disable;
|
||||
} else {
|
||||
$self->{btn_connect}->Show;
|
||||
$self->{btn_disconnect}->Hide;
|
||||
$self->{serial_port_combobox}->Enable;
|
||||
$self->{serial_speed_combobox}->Enable;
|
||||
$self->{btn_rescan_serial}->Enable;
|
||||
}
|
||||
}
|
||||
|
||||
sub set_status {
|
||||
my ($self, $status) = @_;
|
||||
$self->{status_text}->SetLabel($status);
|
||||
$self->{status_text}->Refresh;
|
||||
}
|
||||
|
||||
sub connect {
|
||||
my ($self) = @_;
|
||||
|
||||
return if $self->sender && $self->sender->is_connected;
|
||||
|
||||
$self->set_status("Connecting...");
|
||||
$self->sender(Slic3r::GCode::Sender->new);
|
||||
my $res = $self->sender->connect(
|
||||
$self->{serial_port_combobox}->GetValue,
|
||||
$self->{serial_speed_combobox}->GetValue,
|
||||
);
|
||||
if (!$res) {
|
||||
$self->set_status("Connection failed");
|
||||
}
|
||||
1 until $self->sender->is_connected;
|
||||
$self->set_status("Connected");
|
||||
$self->_update_connection_controls;
|
||||
}
|
||||
|
||||
sub disconnect {
|
||||
my ($self) = @_;
|
||||
|
||||
return if !$self->sender || !$self->sender->is_connected;
|
||||
|
||||
$self->sender->disconnect;
|
||||
$self->set_status("Not connected");
|
||||
$self->_update_connection_controls;
|
||||
}
|
||||
|
||||
sub scan_serial_ports {
|
||||
my ($self) = @_;
|
||||
|
||||
$self->{serial_port_combobox}->Clear;
|
||||
|
||||
# TODO: Windows ports
|
||||
|
||||
# UNIX and OS X
|
||||
$self->{serial_port_combobox}->Append($_)
|
||||
for glob '/dev/{ttyUSB,ttyACM,tty.,cu.,rfcomm}*';
|
||||
}
|
||||
|
||||
1;
|
@ -228,6 +228,10 @@ sub _init_menubar {
|
||||
$self->_append_menu_item($windowMenu, "Select Print&er Settings Tab\tCtrl+4", 'Show the printer settings', sub {
|
||||
$self->select_tab($tab_count-1);
|
||||
});
|
||||
$windowMenu->AppendSeparator();
|
||||
$self->_append_menu_item($windowMenu, "Printer Controller", 'Show the printer controller', sub {
|
||||
wxTheApp->show_printer_controller;
|
||||
});
|
||||
}
|
||||
|
||||
# Help menu
|
||||
|
@ -7,22 +7,53 @@
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#if __APPLE__
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include <IOKit/serial/ioss.h>
|
||||
#endif
|
||||
#ifdef __linux
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include <linux/serial.h>
|
||||
#endif
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
namespace asio = boost::asio;
|
||||
|
||||
GCodeSender::GCodeSender(std::string devname, unsigned int baud_rate)
|
||||
GCodeSender::GCodeSender()
|
||||
: io(), serial(io), can_send(false), sent(0), error(false), connected(false)
|
||||
{}
|
||||
|
||||
GCodeSender::~GCodeSender()
|
||||
{
|
||||
this->serial.open(devname);
|
||||
this->serial.set_option(asio::serial_port_base::baud_rate(baud_rate));
|
||||
this->disconnect();
|
||||
}
|
||||
|
||||
bool
|
||||
GCodeSender::connect(std::string devname, unsigned int baud_rate)
|
||||
{
|
||||
|
||||
try {
|
||||
this->serial.open(devname);
|
||||
} catch (boost::system::system_error &e) {
|
||||
this->error = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
this->serial.set_option(asio::serial_port_base::parity(asio::serial_port_base::parity::odd));
|
||||
this->serial.set_option(asio::serial_port_base::character_size(asio::serial_port_base::character_size(8)));
|
||||
this->serial.set_option(asio::serial_port_base::flow_control(asio::serial_port_base::flow_control::none));
|
||||
this->serial.set_option(asio::serial_port_base::stop_bits(asio::serial_port_base::stop_bits::one));
|
||||
this->set_baud_rate(baud_rate);
|
||||
|
||||
this->serial.close();
|
||||
this->serial.open(devname);
|
||||
this->serial.set_option(asio::serial_port_base::parity(asio::serial_port_base::parity::none));
|
||||
|
||||
// set baud rate again because set_option overwrote it
|
||||
this->set_baud_rate(baud_rate);
|
||||
this->open = true;
|
||||
|
||||
// this gives some work to the io_service before it is started
|
||||
@ -32,6 +63,52 @@ GCodeSender::GCodeSender(std::string devname, unsigned int baud_rate)
|
||||
// start reading in the background thread
|
||||
boost::thread t(boost::bind(&asio::io_service::run, &this->io));
|
||||
this->background_thread.swap(t);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GCodeSender::set_baud_rate(unsigned int baud_rate)
|
||||
{
|
||||
try {
|
||||
// This does not support speeds > 115200
|
||||
this->serial.set_option(asio::serial_port_base::baud_rate(baud_rate));
|
||||
} catch (boost::system::system_error &e) {
|
||||
boost::asio::serial_port::native_handle_type handle = this->serial.native_handle();
|
||||
|
||||
#if __APPLE__
|
||||
termios ios;
|
||||
::tcgetattr(handle, &ios);
|
||||
::cfsetspeed(&ios, baud_rate);
|
||||
speed_t newSpeed = baud_rate;
|
||||
ioctl(handle, IOSSIOSPEED, &newSpeed);
|
||||
::tcsetattr(handle, TCSANOW, &ios);
|
||||
#endif
|
||||
#ifdef __linux
|
||||
termios ios;
|
||||
::tcgetattr(handle, &ios);
|
||||
::cfsetispeed(&ios, B38400);
|
||||
::cfsetospeed(&ios, B38400);
|
||||
::tcflush(handle, TCIFLUSH);
|
||||
::tcsetattr(handle, TCSANOW, &ios);
|
||||
|
||||
struct serial_struct ss;
|
||||
ioctl(handle, TIOCGSERIAL, &ss);
|
||||
ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
|
||||
ss.custom_divisor = (ss.baud_base + (baud_rate / 2)) / baud_rate;
|
||||
//cout << "bbase " << ss.baud_base << " div " << ss.custom_divisor;
|
||||
long closestSpeed = ss.baud_base / ss.custom_divisor;
|
||||
//cout << " Closest speed " << closestSpeed << endl;
|
||||
ss.reserved_char[0] = 0;
|
||||
if (closestSpeed < baud * 98 / 100 || closestSpeed > baud_rate * 102 / 100) {
|
||||
throw std::exception("Failed to set baud rate");
|
||||
}
|
||||
|
||||
ioctl(handle, TIOCSSERIAL, &ss);
|
||||
#else
|
||||
//throw invalid_argument ("OS does not currently support custom bauds");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -16,7 +16,9 @@ namespace asio = boost::asio;
|
||||
|
||||
class GCodeSender : private boost::noncopyable {
|
||||
public:
|
||||
GCodeSender(std::string devname, unsigned int baud_rate);
|
||||
GCodeSender();
|
||||
~GCodeSender();
|
||||
bool connect(std::string devname, unsigned int baud_rate);
|
||||
void send(const std::vector<std::string> &lines);
|
||||
void send(const std::string &s);
|
||||
void disconnect();
|
||||
@ -39,6 +41,7 @@ class GCodeSender : private boost::noncopyable {
|
||||
bool can_send;
|
||||
size_t sent;
|
||||
|
||||
void set_baud_rate(unsigned int baud_rate);
|
||||
void set_error_status(bool e);
|
||||
void do_close();
|
||||
void do_read();
|
||||
|
@ -8,12 +8,13 @@
|
||||
%}
|
||||
|
||||
%name{Slic3r::GCode::Sender} class GCodeSender {
|
||||
GCodeSender(std::string port, unsigned int baud_rate);
|
||||
GCodeSender();
|
||||
~GCodeSender();
|
||||
|
||||
bool connect(std::string port, unsigned int baud_rate);
|
||||
void disconnect();
|
||||
bool is_connected() const;
|
||||
int queue_size() const;
|
||||
void disconnect();
|
||||
void send(std::string s);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user