786 :
787 GUI::DPIDialog(parent, wxID_ANY,
_(
L(
"Firmware flasher")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
789{
790 const int em = GUI::wxGetApp().em_unit();
794
795
796
797
798
799 const wxFont& font = GUI::wxGetApp().normal_font();
800 SetFont(font);
801 wxFont status_font = font;
802 status_font.MakeBold();
803 wxFont mono_font = GUI::wxGetApp().code_font();
804 mono_font.MakeSmaller();
805
806
807
808 auto *panel = new wxPanel(this);
809 wxBoxSizer *vsizer = new wxBoxSizer(wxVERTICAL);
810 panel->SetSizer(vsizer);
811
812 auto *label_hex_picker =
new wxStaticText(panel, wxID_ANY,
_(
L(
"Firmware image:")));
813 p->hex_picker =
new wxFilePickerCtrl(panel, wxID_ANY, wxEmptyString,
_L(
"Select a file"),
814 "Hex files (*.hex)|*.hex|All files|*.*");
815 p->hex_picker->GetPickerCtrl()->SetLabelText(
_(
L(
"Browse")));
816
817 auto *label_port_picker =
new wxStaticText(panel, wxID_ANY,
_(
L(
"Serial port:")));
818 p->port_picker =
new wxComboBox(panel, wxID_ANY);
819 p->txt_port_autodetect =
new wxStaticText(panel, wxID_ANY,
_(
L(
"Autodetected")));
820 p->btn_rescan =
new wxButton(panel, wxID_ANY,
_(
L(
"Rescan")));
821 auto *port_sizer = new wxBoxSizer(wxHORIZONTAL);
822 port_sizer->Add(
p->port_picker, 1, wxEXPAND | wxRIGHT,
SPACING);
823 port_sizer->Add(
p->btn_rescan, 0);
824 port_sizer->Add(
p->txt_port_autodetect, 1, wxEXPAND);
825 p->set_autodetect(
false);
826
827 auto *label_progress =
new wxStaticText(panel, wxID_ANY,
_(
L(
"Progress:")));
828 p->progressbar =
new wxGauge(panel, wxID_ANY, 1, wxDefaultPosition, wxDefaultSize, wxGA_HORIZONTAL | wxGA_SMOOTH);
829
830 auto *label_status =
new wxStaticText(panel, wxID_ANY,
_(
L(
"Status:")));
831 p->txt_status =
new wxStaticText(panel, wxID_ANY,
_(
L(
"Ready")));
832 p->txt_status->SetFont(status_font);
833
835 grid->AddGrowableCol(1);
836
837 grid->Add(label_hex_picker, 0, wxALIGN_CENTER_VERTICAL);
838 grid->Add(
p->hex_picker, 0, wxEXPAND);
839
840 grid->Add(label_port_picker, 0, wxALIGN_CENTER_VERTICAL);
841 grid->Add(port_sizer, 0, wxEXPAND);
842
843 grid->Add(label_progress, 0, wxALIGN_CENTER_VERTICAL);
844 grid->Add(
p->progressbar, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL);
845
846 grid->Add(label_status, 0, wxALIGN_CENTER_VERTICAL);
847 grid->Add(
p->txt_status, 0, wxEXPAND);
848
849 vsizer->Add(
grid, 0, wxEXPAND | wxTOP | wxBOTTOM,
SPACING);
850
851 p->spoiler =
new wxCollapsiblePane(panel, wxID_ANY,
_(
L(
"Advanced: Output log")), wxDefaultPosition, wxDefaultSize, wxCP_DEFAULT_STYLE | wxCP_NO_TLW_RESIZE);
852 auto *spoiler_pane =
p->spoiler->GetPane();
853 auto *spoiler_sizer = new wxBoxSizer(wxVERTICAL);
854 p->txt_stdout =
new wxTextCtrl(spoiler_pane, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY);
855 p->txt_stdout->SetFont(mono_font);
856 spoiler_sizer->Add(
p->txt_stdout, 1, wxEXPAND);
857 spoiler_pane->SetSizer(spoiler_sizer);
858
859
860 vsizer->Add(
p->spoiler, 1, wxEXPAND | wxBOTTOM,
SPACING);
861
862 p->btn_close =
new wxButton(panel, wxID_CLOSE,
_(
L(
"Close")));
863 p->btn_flash =
new wxButton(panel, wxID_ANY,
p->btn_flash_label_ready);
864 p->btn_flash->Disable();
865 auto *bsizer = new wxBoxSizer(wxHORIZONTAL);
866 bsizer->Add(
p->btn_close);
867 bsizer->AddStretchSpacer();
868 bsizer->Add(
p->btn_flash);
869 vsizer->Add(bsizer, 0, wxEXPAND);
870
871 GUI::wxGetApp().UpdateDlgDarkUI(this);
872
873 auto *topsizer = new wxBoxSizer(wxVERTICAL);
875 SetMinSize(wxSize(
p->min_width,
p->min_height));
876 SetSizerAndFit(topsizer);
877 const auto size = GetSize();
878 SetSize(std::max(
size.GetWidth(),
static_cast<int>(
p->min_width)), std::max(
size.GetHeight(),
static_cast<int>(
p->min_height)));
879 Layout();
880
881 SetEscapeId(wxID_CLOSE);
882
883
884
885 p->hex_picker->Bind(wxEVT_FILEPICKER_CHANGED, [
this](wxFileDirPickerEvent& evt) {
886 if (wxFileExists(evt.GetPath())) {
887 this->p->load_hex_file(evt.GetPath());
888 }
889 p->update_flash_enabled();
890 });
891
892 p->port_picker->Bind(wxEVT_COMBOBOX, [
this](wxCommandEvent &) {
p->update_flash_enabled(); });
893 p->port_picker->Bind(wxEVT_TEXT, [
this](wxCommandEvent &) {
p->update_flash_enabled(); });
894
895 p->spoiler->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, [=](wxCollapsiblePaneEvent &evt) {
896 if (evt.GetCollapsed()) {
897 this->SetMinSize(wxSize(
p->min_width,
p->min_height));
898 const auto new_height = this->GetSize().GetHeight() - this->
p->txt_stdout->GetSize().GetHeight();
899 this->SetSize(this->GetSize().GetWidth(), new_height);
900 } else {
901 this->SetMinSize(wxSize(
p->min_width,
p->min_height_expanded));
902 }
903
904 this->Layout();
905 this->
p->fit_no_shrink();
906 });
907
908 p->btn_rescan->Bind(
wxEVT_BUTTON, [
this](wxCommandEvent &) { this->
p->find_serial_ports(); });
909
911 if (this->
p->avrdude) {
912
913
914 GUI::MessageDialog dlg(this,
915 _(
L(
"Are you sure you want to cancel firmware flashing?\nThis could leave your printer in an unusable state!")),
916 _(
L(
"Confirmation")),
917 wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
918 if (dlg.ShowModal() == wxID_YES) {
919 this->
p->set_txt_status(
_(
L(
"Cancelling...")));
920 this->
p->user_cancel();
921 }
922 } else {
923
924 this->
p->perform_upload();
925 }
926 });
927
928 Bind(wxEVT_TIMER, [
this](wxTimerEvent &evt) { this->
p->progressbar->Pulse(); });
929
930 Bind(EVT_AVRDUDE, [
this](wxCommandEvent &evt) { this->
p->on_avrdude(evt); });
931 Bind(EVT_ASYNC_DIALOG, [
this](wxCommandEvent &evt) { this->
p->on_async_dialog(evt); });
932
933 Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent &evt) {
934 if (this->
p->avrdude) {
935 evt.Veto();
936 } else {
937 this->EndModal(wxID_CLOSE);
938 evt.Skip();
939 }
940 });
941
942 p->find_serial_ports();
943}
std::unique_ptr< priv > p
Definition FirmwareDialog.hpp:37
#define _(msgid)
Definition getopt.c:87
DPIAware< wxDialog > DPIDialog
Definition GUI_Utils.hpp:279
std::vector< ArithmeticOnly< T > > grid(const T &start, const T &stop, const T &stride)
A set of equidistant values starting from 'start' (inclusive), ending in the closest multiple of 'str...
Definition MTUtils.hpp:125
constexpr auto size(const C &c) -> decltype(c.size())
Definition span.hpp:183
Definition CutSurface.cpp:39
#define L(s)
Definition I18N.hpp:18
#define _L(s)
Definition I18N.hpp:3
#define wxEVT_BUTTON
Definition wxinit.h:18