BambuStudio/slic3r/GUI/SliceInfoPanel.cpp

349 lines
12 KiB
C++

#include "SliceInfoPanel.hpp"
#include "I18N.hpp"
#include "Widgets/Label.hpp"
#include "libslic3r/Utils.hpp"
#include <boost/log/trivial.hpp>
namespace Slic3r {
namespace GUI {
#define THUMBNAIL_SIZE (wxSize(FromDIP(60), FromDIP(60)))
#define ICON_SIZE (wxSize(FromDIP(16), FromDIP(16)))
#define PRINT_ICON_SIZE (wxSize(FromDIP(18), FromDIP(18)))
wxIMPLEMENT_CLASS(SliceInfoPopup, PopupWindow);
wxBEGIN_EVENT_TABLE(SliceInfoPopup, PopupWindow)
EVT_MOUSE_EVENTS( SliceInfoPopup::OnMouse )
EVT_SIZE(SliceInfoPopup::OnSize)
EVT_SET_FOCUS( SliceInfoPopup::OnSetFocus )
EVT_KILL_FOCUS( SliceInfoPopup::OnKillFocus )
wxEND_EVENT_TABLE()
static wxColour BUTTON_BORDER_COL = wxColour(255, 255, 255);
inline int hex_digit_to_int(const char c)
{
return
(c >= '0' && c <= '9') ? int(c - '0') :
(c >= 'A' && c <= 'F') ? int(c - 'A') + 10 :
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
}
inline float calc_gray(wxColour color)
{
return 0.299 * (float) color.Red() + 0.587 * (float) color.Green() + 0.114 * (float) color.Blue();
}
static wxColour decode_color(const std::string &color)
{
std::array<int, 3> ret = {0, 0, 0};
const char * c = color.data() + 1;
if (color.size() == 7 && color.front() == '#') {
for (size_t j = 0; j < 3; ++j) {
int digit1 = hex_digit_to_int(*c++);
int digit2 = hex_digit_to_int(*c++);
if (digit1 == -1 || digit2 == -1) break;
ret[j] = float(digit1 * 16 + digit2);
}
}
return wxColour(ret[0], ret[1], ret[2]);
}
SliceInfoPopup::SliceInfoPopup(wxWindow *parent, wxBitmap bmp, BBLSliceInfo *info)
: PopupWindow(parent, wxBORDER_NONE | wxPU_CONTAINS_CONTROLS)
{
#ifdef __WINDOWS__
SetDoubleBuffered(true);
#endif
m_panel = new wxScrolledWindow(this, wxID_ANY);
m_panel->SetBackgroundColour(*wxWHITE);
m_panel->Bind(wxEVT_MOTION, &SliceInfoPopup::OnMouse, this);
wxBoxSizer * main_sizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer * topSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer * caption_sizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer * caption_left_sizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer * caption_right_sizer = new wxBoxSizer(wxHORIZONTAL);
auto prediction_bitmap = new wxStaticBitmap(m_panel, wxID_ANY, create_scaled_bitmap("monitor_item_prediction", nullptr, 16));
wxString predict_text;
if (info)
predict_text = get_bbl_monitor_time_dhm(info->prediction);
auto prediction = new wxStaticText(m_panel, wxID_ANY, predict_text, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
caption_left_sizer->Add(prediction_bitmap, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
caption_left_sizer->Add(prediction, 1, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
prediction->Wrap(-1);
auto cost_bitmap = new wxStaticBitmap(m_panel, wxID_ANY, create_scaled_bitmap("monitor_item_cost", nullptr, 16));
wxString cost_text;
if (info) {
if (info->weight > 0) {
cost_text = wxString::Format("%.2fg", info->weight);
} else {
cost_text = "0g";
}
}
auto used_g_text = new wxStaticText(m_panel, wxID_ANY, cost_text, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
caption_right_sizer->Add(cost_bitmap, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
caption_right_sizer->Add(used_g_text, 1, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
caption_sizer->Add(caption_left_sizer, 1, 0, FromDIP(5));
caption_sizer->Add(caption_right_sizer, 1, 0, FromDIP(5));
topSizer->Add(caption_sizer, 0, wxEXPAND | wxALL, 0);
auto static_line = new StaticLine(m_panel);
topSizer->Add(static_line, 0, wxEXPAND | wxALL, 0);
wxGridSizer *grid_sizer = new wxGridSizer(2, wxSize(FromDIP(10), 0));
if (info) {
for (auto f : info->filaments_info) {
auto f_sizer = new wxBoxSizer(wxHORIZONTAL);
auto f_type = new Button(m_panel, f.type);
f_type->SetBorderColor(BUTTON_BORDER_COL);
wxColour color = decode_color(f.color);
f_type->SetBackgroundColor(color);
auto textcolor = wxColour(0, 0, 0);
if (calc_gray(color) <= 128)
textcolor = wxColour(255, 255, 255);
else
textcolor = wxColour(0, 0, 0);
f_type->SetTextColor(textcolor);
f_type->SetSize(wxSize(FromDIP(40), FromDIP(20)));
f_type->SetMinSize(wxSize(FromDIP(40), FromDIP(20)));
f_type->SetMaxSize(wxSize(FromDIP(40), FromDIP(20)));
f_type->SetCornerRadius(FromDIP(10));
wxString used_g_text = wxString::Format("%.1fg", f.used_g);
auto f_used_g = new wxStaticText(m_panel, wxID_ANY, used_g_text, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
f_used_g->Wrap(-1);
f_used_g->SetSize(wxSize(FromDIP(60), -1));
f_sizer->Add(f_type, 0, wxEXPAND | wxALL, FromDIP(5));
f_sizer->Add(f_used_g, 0, wxEXPAND | wxALL, FromDIP(5));
grid_sizer->Add(f_sizer, 0, wxEXPAND, 0);
f_type->Bind(wxEVT_LEFT_DOWN, [this](auto &e) {});
}
}
topSizer->Add(grid_sizer, 0, wxALL, FromDIP(5));
main_sizer->Add(FromDIP(13), 0, 0, 0);
main_sizer->Add(topSizer, 0, wxEXPAND | wxALL, 0);
main_sizer->Add(FromDIP(13), 0, 0, 0);
main_sizer->SetMinSize(wxSize(FromDIP(200), -1));
m_panel->SetSizer(main_sizer);
m_panel->Layout();
main_sizer->Fit(m_panel);
SetClientSize(m_panel->GetSize());
}
void SliceInfoPopup::Popup(wxWindow *WXUNUSED(focus)) {
PopupWindow::Popup();
}
void SliceInfoPopup::OnDismiss() {
PopupWindow::OnDismiss();
}
bool SliceInfoPopup::ProcessLeftDown(wxMouseEvent &event)
{
return PopupWindow::ProcessLeftDown(event);
}
bool SliceInfoPopup::Show(bool show)
{
return PopupWindow::Show(show);
}
void SliceInfoPopup::OnSize(wxSizeEvent &event)
{
event.Skip();
}
void SliceInfoPopup::OnSetFocus(wxFocusEvent &event)
{
event.Skip();
}
void SliceInfoPopup::OnKillFocus(wxFocusEvent &event)
{
event.Skip();
}
void SliceInfoPopup::OnMouse(wxMouseEvent &event)
{
event.Skip();
}
SliceInfoPanel::SliceInfoPanel(wxWindow *parent, wxBitmap &prediction, wxBitmap &cost, wxBitmap &print,
wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name)
: wxPanel(parent, id, pos, size, style, name)
{
this->SetBackgroundColour(*wxWHITE);
m_item_top_sizer = new wxBoxSizer(wxHORIZONTAL);
m_bmp_item_thumbnail = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW | 0);
m_bmp_item_thumbnail->SetMinSize(THUMBNAIL_SIZE);
m_bmp_item_thumbnail->SetSize(THUMBNAIL_SIZE);
m_item_top_sizer->Add(m_bmp_item_thumbnail, 0, wxALL, 0);
wxBoxSizer *m_item_content_sizer;
m_item_content_sizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *m_item_info_sizer = new wxBoxSizer(wxHORIZONTAL);
m_bmp_item_prediction = new wxStaticBitmap(this, wxID_ANY, prediction);
m_bmp_item_prediction->SetMinSize(ICON_SIZE);
m_bmp_item_prediction->SetSize(ICON_SIZE);
m_item_info_sizer->Add(m_bmp_item_prediction, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
m_text_item_prediction = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(60), -1));
m_text_item_prediction->Wrap(-1);
m_item_info_sizer->Add(m_text_item_prediction, 1, wxALIGN_CENTER_VERTICAL | wxALL, 0);
m_bmp_item_cost = new wxStaticBitmap(this, wxID_ANY, cost);
m_bmp_item_cost->SetMinSize(ICON_SIZE);
m_bmp_item_cost->SetSize(ICON_SIZE);
m_item_info_sizer->Add(m_bmp_item_cost, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
m_text_item_cost = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(35), -1));
m_text_item_cost->Wrap(-1);
m_item_info_sizer->Add(m_text_item_cost, 1, wxALIGN_CENTER_VERTICAL | wxALL, 0);
m_item_content_sizer->Add(m_item_info_sizer, 0, wxEXPAND, 0);
wxGridSizer *m_filament_info_sizer = new wxGridSizer(0, 3, 0, 8);
m_item_content_sizer->Add(m_filament_info_sizer, 0, wxEXPAND, 0);
m_item_top_sizer->Add(m_item_content_sizer, 0, wxEXPAND, 0);
wxBoxSizer *m_item_right_sizer;
m_item_right_sizer = new wxBoxSizer(wxVERTICAL);
m_bmp_item_print = new wxStaticBitmap(this, wxID_ANY, print, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW | 0);
m_bmp_item_print->SetMinSize(PRINT_ICON_SIZE);
m_bmp_item_print->SetSize(PRINT_ICON_SIZE);
m_item_right_sizer->Add(m_bmp_item_print, 0, wxALL, FromDIP(5));
m_item_right_sizer->Add(0, 0, 1, wxEXPAND, FromDIP(5));
m_text_plate_index = new wxStaticText(this, wxID_ANY, "");
m_text_plate_index->Wrap(-1);
m_text_plate_index->SetForegroundColour(wxColour(107, 107, 107));
m_item_right_sizer->Add(m_text_plate_index, 0, wxALIGN_RIGHT | wxALL, FromDIP(5));
m_item_top_sizer->Add(m_item_right_sizer, 0, wxEXPAND, 0);
this->SetSizer(m_item_top_sizer);
this->Layout();
Bind(wxEVT_WEBREQUEST_STATE, &SliceInfoPanel::on_webrequest_state, this);
// Connect Events
m_bmp_item_thumbnail->Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(SliceInfoPanel::on_thumbnail_enter), NULL, this);
m_bmp_item_thumbnail->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(SliceInfoPanel::on_thumbnail_leave), NULL, this);
m_bmp_item_print->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SliceInfoPanel::on_subtask_print), NULL, this);
}
SliceInfoPanel::~SliceInfoPanel()
{
// Disconnect Events
m_bmp_item_thumbnail->Disconnect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(SliceInfoPanel::on_thumbnail_enter), NULL, this);
m_bmp_item_thumbnail->Disconnect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(SliceInfoPanel::on_thumbnail_leave), NULL, this);
m_bmp_item_print->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SliceInfoPanel::on_subtask_print), NULL, this);
}
void SliceInfoPanel::SetImages(wxBitmap &prediction, wxBitmap &cost, wxBitmap &printing)
{
m_bmp_item_prediction->SetBitmap(prediction);
m_bmp_item_cost->SetBitmap(cost);
m_bmp_item_print->SetBitmap(printing);
}
void SliceInfoPanel::on_subtask_print(wxCommandEvent &evt)
{
;
}
void SliceInfoPanel::on_thumbnail_enter(wxMouseEvent &event)
{
/*
m_slice_info_popup = std::make_shared<SliceInfoPopup>(this);
wxWindow *ctrl = (wxWindow *) event.GetEventObject();
wxPoint pos = ctrl->ClientToScreen(wxPoint(0, 0));
wxSize sz = ctrl->GetSize();
m_slice_info_popup->Position(pos, sz);
m_slice_info_popup->Popup();
*/
}
void SliceInfoPanel::on_thumbnail_leave(wxMouseEvent &event)
{
if (m_thumbnail_popup) { m_thumbnail_popup->Hide(); }
}
void SliceInfoPanel::on_mouse_enter(wxMouseEvent &event) { ; }
void SliceInfoPanel::on_mouse_leave(wxMouseEvent &event) { ; }
void SliceInfoPanel::on_webrequest_state(wxWebRequestEvent &evt)
{
BOOST_LOG_TRIVIAL(trace) << "monitor: sub_task_panel web request state = " << evt.GetState();
switch (evt.GetState()) {
case wxWebRequest::State_Completed: {
m_thumbnail_img = *evt.GetResponse().GetStream();
wxImage resize_img = m_thumbnail_img.Scale(m_bmp_item_thumbnail->GetSize().x, m_bmp_item_thumbnail->GetSize().y);
m_bmp_item_thumbnail->SetBitmap(resize_img);
break;
}
case wxWebRequest::State_Failed: {
break;
}
case wxWebRequest::State_Cancelled:
case wxWebRequest::State_Unauthorized:
case wxWebRequest::State_Active:
case wxWebRequest::State_Idle: break;
default: break;
}
}
void SliceInfoPanel::update(BBLSliceInfo *info)
{
wxString prediction = wxString::Format("%s", get_bbl_time_dhms(info->prediction));
m_text_item_prediction->SetLabelText(prediction);
wxString weight = wxString::Format("%.2fg", info->weight);
m_text_item_cost->SetLabelText(weight);
m_text_plate_index->SetLabelText(info->index);
if (web_request.IsOk()) web_request.Cancel();
if (!info->thumbnail_url.empty()) {
web_request = wxWebSession::GetDefault().CreateRequest(this, info->thumbnail_url);
BOOST_LOG_TRIVIAL(trace) << "slice info: start reqeust thumbnail, url = " << info->thumbnail_url;
web_request.Start();
}
this->Layout();
}
void SliceInfoPanel::msw_rescale()
{
m_bmp_item_prediction->SetMinSize(ICON_SIZE);
m_bmp_item_prediction->SetSize(ICON_SIZE);
m_bmp_item_cost->SetMinSize(ICON_SIZE);
m_bmp_item_cost->SetSize(ICON_SIZE);
m_bmp_item_print->SetMinSize(PRINT_ICON_SIZE);
m_bmp_item_print->SetSize(PRINT_ICON_SIZE);
this->Layout();
}
}
}