349 lines
12 KiB
C++
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();
|
|
}
|
|
|
|
|
|
}
|
|
} |