diff --git a/src/slic3r/GUI/ImageGrid.cpp b/src/slic3r/GUI/ImageGrid.cpp index c6a6f479c..f3493d704 100644 --- a/src/slic3r/GUI/ImageGrid.cpp +++ b/src/slic3r/GUI/ImageGrid.cpp @@ -105,7 +105,8 @@ void Slic3r::GUI::ImageGrid::SetGroupMode(int mode) void Slic3r::GUI::ImageGrid::SetSelecting(bool selecting) { m_selecting = selecting; - if (!m_selecting) m_file_sys->SelectAll(false); + if (m_file_sys) + m_file_sys->SelectAll(false); Refresh(); } @@ -143,7 +144,24 @@ void Slic3r::GUI::ImageGrid::DoAction(size_t index, int action) { if (action == 0) { m_file_sys->DeleteFiles(index); - } else { + } else if (action == 1) { + if (index != -1) { + auto &file = m_file_sys->GetFile(index); + if (file.IsDownload() && file.progress >= -1) { + if (file.progress >= 100) { +#ifdef __WXMSW__ + wxExecute("cmd /c start " + from_u8(file.path), wxEXEC_HIDE_CONSOLE); +#else + wxShell("open " + file.path); +#endif + } else { + m_file_sys->DownloadCancel(index); + } + return; + } + } + m_file_sys->DownloadFiles(index, wxGetApp().app_config->get("download_path")); + } else if (action == 2) { if (index != -1) { auto &file = m_file_sys->GetFile(index); if (file.IsDownload() && file.progress >= -1) { @@ -254,7 +272,9 @@ std::pair Slic3r::GUI::ImageGrid::HitTest(wxPoint const &pt) if (index >= m_file_sys->GetCount()) { return {HIT_NONE, -1}; } if (!m_selecting) { wxRect hover_rect{0, m_image_size.y - 40, m_image_size.GetWidth(), 40}; - if (hover_rect.Contains(off.x, off.y)) { return {HIT_ACTION, index * 2 + off.x * 2 / hover_rect.GetWidth()}; } // Two buttons + auto & file = m_file_sys->GetFile(index); + int btn = file.IsDownload() && file.progress >= 100 ? 3 : 2; + if (hover_rect.Contains(off.x, off.y)) { return {HIT_ACTION, index * 4 + off.x * btn / hover_rect.GetWidth()}; } // Two buttons } return {HIT_ITEM, index}; } @@ -316,7 +336,7 @@ void ImageGrid::mouseReleased(wxMouseEvent& event) if (m_hit_type == HIT_ITEM) Select(m_hit_item); else if (m_hit_type == HIT_ACTION) - DoAction(m_hit_item / 2, m_hit_item & 1); + DoAction(m_hit_item / 4, m_hit_item & 3); else if (m_hit_type == HIT_MODE) SetGroupMode(static_cast(2 - m_hit_item)); else if (m_hit_type == HIT_STATUS) @@ -462,7 +482,7 @@ void ImageGrid::render(wxDC& dc) constexpr wchar_t const * formats[] = {_T("%Y-%m-%d"), _T("%Y-%m"), _T("%Y")}; size_t start = index; size_t end = index; - size_t hit_image = m_selecting ? size_t(-1) : m_hit_type == HIT_ITEM ? m_hit_item : m_hit_type == HIT_ACTION ? m_hit_item / 2 :size_t(-1); + size_t hit_image = m_selecting ? size_t(-1) : m_hit_type == HIT_ITEM ? m_hit_item : m_hit_type == HIT_ACTION ? m_hit_item / 4 :size_t(-1); // Draw items with background while (off.y < size.y) { @@ -492,6 +512,7 @@ void ImageGrid::render(wxDC& dc) else if (m_file_sys->GetGroupMode() == PrinterFileSystem::G_NONE) { wxString nonHoverText; wxString secondAction = _L("Download"); + wxString thirdAction; int states = 0; // Draw download progress if (file.IsDownload()) { @@ -503,7 +524,8 @@ void ImageGrid::render(wxDC& dc) nonHoverText = _L("Download failed"); states = StateColor::Checked; } else if (file.progress >= 100) { - secondAction = _L("Open Folder"); + secondAction = _L("Play"); + thirdAction = _L("Open Folder"); nonHoverText = _L("Download finished"); } else { secondAction = _L("Cancel"); @@ -513,7 +535,8 @@ void ImageGrid::render(wxDC& dc) // Draw buttons on hovered item wxRect rect{pt.x, pt.y + m_image_size.y - m_buttons_background.GetHeight(), m_image_size.GetWidth(), m_buttons_background.GetHeight()}; if (hit_image == index) { - renderButtons(dc, {_L("Delete"), (wxChar const *) secondAction, nullptr}, rect, m_hit_type == HIT_ACTION ? m_hit_item & 1 : -1, states); + renderButtons(dc, {_L("Delete"), (wxChar const *) secondAction, thirdAction.IsEmpty() ? nullptr : (wxChar const *) thirdAction, nullptr}, rect, + m_hit_type == HIT_ACTION ? m_hit_item & 3 : -1, states); } else if (!nonHoverText.IsEmpty()) { renderButtons(dc, {(wxChar const *) nonHoverText, nullptr}, rect, -1, states); } @@ -580,12 +603,12 @@ void Slic3r::GUI::ImageGrid::renderButtons(wxDC &dc, wxStringList const &texts, for (size_t i = 0; i < texts.size(); ++i) { int states2 = hit == i ? state : 0; // Draw button background - rect.Deflate(10, 5); //dc.Blit(rect.GetTopLeft(), rect.GetSize(), &mdc, {m_buttonBackgroundColor.colorIndexForStates(states) * 128, 0}); //dc.DrawBitmap(m_button_background, rect2.GetTopLeft()); // Draw button splitter if (i > 0) dc.DrawLine(rect.GetLeftTop(), rect.GetLeftBottom()); // Draw button text + rect.Deflate(10, 5); renderText(dc, texts[i], rect, states | states2); rect.Inflate(10, 5); rect.Offset(rect.GetWidth(), 0); diff --git a/src/slic3r/GUI/MediaFilePanel.cpp b/src/slic3r/GUI/MediaFilePanel.cpp index 51862aeb3..ca5e0066e 100644 --- a/src/slic3r/GUI/MediaFilePanel.cpp +++ b/src/slic3r/GUI/MediaFilePanel.cpp @@ -73,7 +73,8 @@ MediaFilePanel::MediaFilePanel(wxWindow * parent) type_sizer->Add(m_button_timelapse, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 24); type_sizer->Add(m_button_video, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 24); m_type_panel->SetSizer(type_sizer); - //top_sizer->Add(m_type_panel, 0, wxALIGN_CENTER_VERTICAL); + m_type_panel->Hide(); + // top_sizer->Add(m_type_panel, 0, wxALIGN_CENTER_VERTICAL); // File management m_manage_panel = new ::StaticBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); @@ -85,16 +86,15 @@ MediaFilePanel::MediaFilePanel(wxWindow * parent) m_button_management = new ::Button(m_manage_panel, _L("Select")); m_button_management->SetToolTip(L("Batch manage files.")); for (auto b : {m_button_delete, m_button_download, m_button_management}) { - b->SetBackgroundColor(StateColor()); b->SetFont(Label::Body_12); b->SetCornerRadius(12); b->SetPaddingSize({10, 6}); b->SetCanFocus(false); } - m_button_delete->SetBorderColor(wxColor("#FF6F00")); - m_button_delete->SetTextColor(wxColor("#FF6F00")); + m_button_delete->SetBorderColorNormal(wxColor("#FF6F00")); + m_button_delete->SetTextColorNormal(wxColor("#FF6F00")); m_button_management->SetBorderWidth(0); - m_button_management->SetBackgroundColor(wxColor("#00AE42")); + m_button_management->SetBackgroundColorNormal(wxColor("#00AE42")); wxBoxSizer *manage_sizer = new wxBoxSizer(wxHORIZONTAL); manage_sizer->AddStretchSpacer(1); @@ -163,25 +163,18 @@ MediaFilePanel::MediaFilePanel(wxWindow * parent) b->GetEventHandler()->ProcessEvent(e); } - auto set_selecting = [this](bool selecting) { - m_image_grid->SetSelecting(selecting); - m_button_management->SetLabel(selecting ? _L("Cancel") : _L("Select")); - m_manage_panel->GetSizer()->Show(m_button_download, selecting); - m_manage_panel->GetSizer()->Show(m_button_delete, selecting); - m_manage_panel->Layout(); - }; // File management - m_button_management->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this, set_selecting](auto &e) { + m_button_management->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &e) { e.Skip(); - set_selecting(!m_image_grid->IsSelecting()); + SetSelecting(!m_image_grid->IsSelecting()); }); - m_button_download->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this, set_selecting](auto &e) { + m_button_download->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &e) { m_image_grid->DoActionOnSelection(1); - set_selecting(false); + SetSelecting(false); }); - m_button_delete->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this, set_selecting](auto &e) { + m_button_delete->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &e) { m_image_grid->DoActionOnSelection(0); - set_selecting(false); + SetSelecting(false); }); auto onShowHide = [this](auto &e) { @@ -222,6 +215,8 @@ void MediaFilePanel::SetMachineObject(MachineObject* obj) fs->Unbind(EVT_MODE_CHANGED, &MediaFilePanel::modeChanged, this); fs->Stop(true); } + m_button_management->Enable(false); + SetSelecting(false); if (m_machine.empty()) { m_image_grid->SetStatus(m_bmp_failed.bmp(), _L("No printers.")); } else if (m_lan_ip.empty() && (m_lan_mode && !m_tutk_support)) { @@ -231,8 +226,26 @@ void MediaFilePanel::SetMachineObject(MachineObject* obj) fs->Attached(); m_image_grid->SetFileType(m_last_type); m_image_grid->SetFileSystem(fs); + fs->Bind(EVT_FILE_CHANGED, [this, wfs = boost::weak_ptr(fs)](auto &e) { + e.Skip(); + boost::shared_ptr fs(wfs.lock()); + if (m_image_grid->GetFileSystem() != fs) // canceled + return; + m_button_management->Enable(fs->GetCount() > 0); + if (fs->GetCount() == 0) + SetSelecting(false); + }); + fs->Bind(EVT_SELECT_CHANGED, [this, wfs = boost::weak_ptr(fs)](auto &e) { + e.Skip(); + boost::shared_ptr fs(wfs.lock()); + if (m_image_grid->GetFileSystem() != fs) // canceled + return; + m_button_delete->Enable(e.GetInt() > 0); + m_button_download->Enable(e.GetInt() > 0); + }); fs->Bind(EVT_MODE_CHANGED, &MediaFilePanel::modeChanged, this); fs->Bind(EVT_STATUS_CHANGED, [this, wfs = boost::weak_ptr(fs)](auto &e) { + e.Skip(); boost::shared_ptr fs(wfs.lock()); if (m_image_grid->GetFileSystem() != fs) // canceled return; @@ -279,6 +292,15 @@ void MediaFilePanel::Rescale() m_image_grid->Rescale(); } +void MediaFilePanel::SetSelecting(bool selecting) +{ + m_image_grid->SetSelecting(selecting); + m_button_management->SetLabel(selecting ? _L("Cancel") : _L("Select")); + m_manage_panel->GetSizer()->Show(m_button_download, selecting); + m_manage_panel->GetSizer()->Show(m_button_delete, selecting); + m_manage_panel->Layout(); +} + void MediaFilePanel::modeChanged(wxCommandEvent& e1) { e1.Skip(); diff --git a/src/slic3r/GUI/MediaFilePanel.h b/src/slic3r/GUI/MediaFilePanel.h index 3b47ac8d9..6a07fe28d 100644 --- a/src/slic3r/GUI/MediaFilePanel.h +++ b/src/slic3r/GUI/MediaFilePanel.h @@ -39,6 +39,8 @@ public: public: void Rescale(); + void SetSelecting(bool selecting); + private: void modeChanged(wxCommandEvent & e); diff --git a/src/slic3r/GUI/Printer/PrinterFileSystem.cpp b/src/slic3r/GUI/Printer/PrinterFileSystem.cpp index 4a82118d6..1f9ef376c 100644 --- a/src/slic3r/GUI/Printer/PrinterFileSystem.cpp +++ b/src/slic3r/GUI/Printer/PrinterFileSystem.cpp @@ -17,6 +17,7 @@ wxDEFINE_EVENT(EVT_STATUS_CHANGED, wxCommandEvent); wxDEFINE_EVENT(EVT_MODE_CHANGED, wxCommandEvent); wxDEFINE_EVENT(EVT_FILE_CHANGED, wxCommandEvent); +wxDEFINE_EVENT(EVT_SELECT_CHANGED, wxCommandEvent); wxDEFINE_EVENT(EVT_THUMBNAIL, wxCommandEvent); wxDEFINE_EVENT(EVT_DOWNLOAD, wxCommandEvent); @@ -37,7 +38,7 @@ PrinterFileSystem::PrinterFileSystem() m_session.owner = this; #ifdef PRINTER_FILE_SYSTEM_TEST auto time = wxDateTime::Now(); - for (int i = 0; i < 800; ++i) { + for (int i = 0; i < 100; ++i) { auto name = wxString::Format(L"img-%03d.jpg", i + 1); wxImage im(L"D:\\work\\pic\\" + name); m_file_list.push_back({name.ToUTF8().data(), time.GetTicks(), 26937, im, i < 20 ? FF_DOWNLOAD : 0, i * 10 - 40}); @@ -226,17 +227,30 @@ size_t PrinterFileSystem::GetIndexAtTime(boost::uint32_t time) void PrinterFileSystem::ToggleSelect(size_t index) { - if (index < m_file_list.size()) m_file_list[index].flags ^= FF_SELECT; + if (index < m_file_list.size()) { + m_file_list[index].flags ^= FF_SELECT; + if (m_file_list[index].flags & FF_SELECT) + ++m_select_count; + else + --m_select_count; + } + SendChangedEvent(EVT_SELECT_CHANGED, m_select_count); } void PrinterFileSystem::SelectAll(bool select) { - if (select) + if (select) { for (auto &f : m_file_list) f.flags |= FF_SELECT; - else + m_select_count = m_file_list.size(); + } else { for (auto &f : m_file_list) f.flags &= ~FF_SELECT; + m_select_count = 0; + } + SendChangedEvent(EVT_SELECT_CHANGED, m_select_count); } +size_t PrinterFileSystem::GetSelectCount() const { return m_select_count; } + void PrinterFileSystem::SetFocusRange(size_t start, size_t count) { m_lock_start = start; diff --git a/src/slic3r/GUI/Printer/PrinterFileSystem.h b/src/slic3r/GUI/Printer/PrinterFileSystem.h index 53c1e8e28..886bc67e5 100644 --- a/src/slic3r/GUI/Printer/PrinterFileSystem.h +++ b/src/slic3r/GUI/Printer/PrinterFileSystem.h @@ -18,6 +18,7 @@ using nlohmann::json; wxDECLARE_EVENT(EVT_STATUS_CHANGED, wxCommandEvent); wxDECLARE_EVENT(EVT_MODE_CHANGED, wxCommandEvent); wxDECLARE_EVENT(EVT_FILE_CHANGED, wxCommandEvent); +wxDECLARE_EVENT(EVT_SELECT_CHANGED, wxCommandEvent); wxDECLARE_EVENT(EVT_THUMBNAIL, wxCommandEvent); wxDECLARE_EVENT(EVT_DOWNLOAD, wxCommandEvent); @@ -137,6 +138,8 @@ public: void SelectAll(bool select); + size_t GetSelectCount() const; + void SetFocusRange(size_t start, size_t count); File const &GetFile(size_t index); @@ -263,6 +266,7 @@ protected: std::vector m_group_month; private: + size_t m_select_count = 0; size_t m_lock_start = 0; size_t m_lock_end = 0; int m_task_flags = 0; diff --git a/src/slic3r/GUI/Widgets/Button.cpp b/src/slic3r/GUI/Widgets/Button.cpp index 401fb89c9..fa1dc15ee 100644 --- a/src/slic3r/GUI/Widgets/Button.cpp +++ b/src/slic3r/GUI/Widgets/Button.cpp @@ -24,7 +24,6 @@ END_EVENT_TABLE() Button::Button() : paddingSize(10, 8) - , text_color(*wxBLACK) { background_color = StateColor( std::make_pair(0xF0F0F0, (int) StateColor::Disabled), @@ -32,6 +31,9 @@ Button::Button() std::make_pair(0x00AE42, (int) StateColor::Checked), std::make_pair(*wxLIGHT_GREY, (int) StateColor::Hovered), std::make_pair(*wxWHITE, (int) StateColor::Normal)); + text_color = StateColor( + std::make_pair(*wxLIGHT_GREY, (int) StateColor::Disabled), + std::make_pair(*wxBLACK, (int) StateColor::Normal)); } Button::Button(wxWindow* parent, wxString text, wxString icon, long style, int iconSize) diff --git a/src/slic3r/GUI/Widgets/StaticBox.cpp b/src/slic3r/GUI/Widgets/StaticBox.cpp index e318a3916..1a806e000 100644 --- a/src/slic3r/GUI/Widgets/StaticBox.cpp +++ b/src/slic3r/GUI/Widgets/StaticBox.cpp @@ -18,9 +18,11 @@ END_EVENT_TABLE() StaticBox::StaticBox() : state_handler(this) - , border_color(0x303A3C) , radius(8) { + border_color = StateColor( + std::make_pair(*wxLIGHT_GREY, (int) StateColor::Disabled), + std::make_pair(0x303A3C, (int) StateColor::Normal)); } StaticBox::StaticBox(wxWindow* parent, @@ -62,6 +64,12 @@ void StaticBox::SetBorderColor(StateColor const &color) Refresh(); } +void StaticBox::SetBorderColorNormal(wxColor const &color) +{ + border_color.setColorForStates(color, 0); + Refresh(); +} + void StaticBox::SetBackgroundColor(StateColor const &color) { background_color = color; @@ -69,6 +77,12 @@ void StaticBox::SetBackgroundColor(StateColor const &color) Refresh(); } +void StaticBox::SetBackgroundColorNormal(wxColor const &color) +{ + background_color.setColorForStates(color, 0); + Refresh(); +} + void StaticBox::SetBackgroundColor2(StateColor const &color) { background_color2 = color; diff --git a/src/slic3r/GUI/Widgets/StaticBox.hpp b/src/slic3r/GUI/Widgets/StaticBox.hpp index e3e3f0684..871c5651d 100644 --- a/src/slic3r/GUI/Widgets/StaticBox.hpp +++ b/src/slic3r/GUI/Widgets/StaticBox.hpp @@ -29,8 +29,12 @@ public: void SetBorderColor(StateColor const & color); + void SetBorderColorNormal(wxColor const &color); + void SetBackgroundColor(StateColor const &color); + void SetBackgroundColorNormal(wxColor const &color); + void SetBackgroundColor2(StateColor const &color); static wxColor GetParentBackgroundColor(wxWindow * parent);