OrcaSlicer/src/slic3r/GUI/Widgets/StepCtrl.cpp
lane.wei e9e4d75877 Update the codes to 01.01.00.10 for the formal release
1. first formal version of macos
2. add the bambu networking plugin install logic
3. auto compute the wipe volume when filament change
4. add the logic of wiping into support
5. refine the GUI layout and icons, improve the gui apperance in lots of
   small places
6. serveral improve to support
7. support AMS auto-mapping
8. disable lots of unstable features: such as params table, media file download, HMS
9. fix serveral kinds of bugs
10. update the document of building
11. ...
2022-07-22 20:35:34 +08:00

303 lines
9.5 KiB
C++

#include "StepCtrl.hpp"
#include "Label.hpp"
wxDEFINE_EVENT( EVT_STEP_CHANGING, wxCommandEvent );
wxDEFINE_EVENT( EVT_STEP_CHANGED, wxCommandEvent );
BEGIN_EVENT_TABLE(StepCtrl, StepCtrlBase)
EVT_LEFT_DOWN(StepCtrl::mouseDown)
EVT_MOTION(StepCtrl::mouseMove)
EVT_LEFT_UP(StepCtrl::mouseUp)
END_EVENT_TABLE()
StepCtrlBase::StepCtrlBase(wxWindow * parent,
wxWindowID id,
const wxPoint & pos,
const wxSize & size,
long style)
: StaticBox(parent, id, pos, size, style)
, font_tip(Label::Body_14)
, clr_bar(0xACACAC)
, clr_step(0xACACAC)
, clr_text(std::make_pair(0x00AE42, (int) StateColor::Checked),
std::make_pair(0x6B6B6B, (int) StateColor::Normal))
, clr_tip(0x828280)
{
SetFont(Label::Body_14);
border_color = StateColor(*wxLIGHT_GREY);
StaticBox::radius = 0;
//wxString reason;
//IsTransparentBackgroundSupported(&reason);
}
StepCtrlBase::~StepCtrlBase()
{
}
int StepCtrlBase::GetSelection() const { return step; }
void StepCtrlBase::SelectItem(int item)
{
if (item == step || item < -1 || item >= steps.size() || !sendStepCtrlEvent(true))
return;
step = item;
sendStepCtrlEvent();
Refresh();
}
void StepCtrlBase::Idle()
{
step = -1;
sendStepCtrlEvent();
Refresh();
}
bool StepCtrlBase::SetTipFont(wxFont const& font)
{
font_tip = font;
return true;
}
int StepCtrlBase::AppendItem(const wxString &item, wxString const & tip)
{
steps.push_back(item);
tips.push_back(tip);
return steps.size() - 1;
}
void StepCtrlBase::DeleteAllItems()
{
steps.clear();
tips.clear();
if (step >= 0) {
step = -1;
sendStepCtrlEvent();
}
}
unsigned int StepCtrlBase::GetCount() const { return steps.size(); }
wxString StepCtrlBase::GetItemText(unsigned int item) const
{
return item < steps.size() ? steps[item] : wxString{};
}
void StepCtrlBase::SetItemText(unsigned int item, wxString const &value)
{
if (item >= steps.size()) return;
steps[item] = value;
}
bool StepCtrlBase::sendStepCtrlEvent(bool changing)
{
wxCommandEvent event(changing ? EVT_STEP_CHANGING : EVT_STEP_CHANGED, GetId());
event.SetEventObject(this);
event.SetInt(step);
GetEventHandler()->ProcessEvent(event);
return true;
}
/* StepCtrl */
StepCtrl::StepCtrl(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style)
: StepCtrlBase(parent, id, pos, size, style)
, bmp_thumb(this, "step_thumb", 36)
{
StaticBox::border_width = 3;
radius = radius * bmp_thumb.GetBmpHeight() / 36;
bar_width = bar_width * bmp_thumb.GetBmpHeight() / 36;
}
void StepCtrl::Rescale()
{
bmp_thumb.msw_rescale();
radius = radius * bmp_thumb.GetBmpHeight() / 36;
bar_width = bar_width * bmp_thumb.GetBmpHeight() / 36;
}
void StepCtrl::mouseDown(wxMouseEvent &event)
{
wxPoint pt;
event.GetPosition(&pt.x, &pt.y);
wxSize size = GetSize();
int itemWidth = size.x / steps.size();
wxRect rcBar = {0, (size.y - 60) / 2, size.x, 60};
int circleX = itemWidth / 2 + itemWidth * step;
wxRect rcThumb = {{circleX, size.y / 2}, bmp_thumb.GetBmpSize()};
rcThumb.x -= rcThumb.width / 2;
rcThumb.y -= rcThumb.height / 2;
if (rcThumb.Contains(pt)) {
pos_thumb = wxPoint{circleX, size.y / 2};
drag_offset = pos_thumb - pt;
} else if (rcBar.Contains(pt)) {
if (pt.x < circleX) {
if (step > 0) SelectItem(step - 1);
} else {
if (step < steps.size() - 1) SelectItem(step + 1);
}
}
}
void StepCtrl::mouseMove(wxMouseEvent &event)
{
if (pos_thumb == wxPoint{0, 0}) return;
wxPoint pt;
event.GetPosition(&pt.x, &pt.y);
pos_thumb.x = pt.x + drag_offset.x;
Refresh();
}
void StepCtrl::mouseUp(wxMouseEvent &event)
{
if (pos_thumb == wxPoint{0, 0}) return;
wxSize size = GetSize();
int itemWidth = size.x / steps.size();
int index = pos_thumb.x / itemWidth;
pos_thumb = {0, 0};
SelectItem(index < steps.size() ? index : steps.size() - 1);
}
void StepCtrl::doRender(wxDC &dc)
{
if (steps.empty()) return;
StaticBox::doRender(dc);
wxSize size = GetSize();
int states = state_handler.states();
int itemWidth = size.x / steps.size();
wxRect rcBar = {itemWidth / 2, (size.y - bar_width) / 2, size.x - itemWidth, bar_width};
dc.SetPen(wxPen(clr_bar.colorForStates(states)));
dc.SetBrush(wxBrush(clr_bar.colorForStates(states)));
dc.DrawRectangle(rcBar);
int circleX = itemWidth / 2;
int circleY = size.y / 2;
dc.SetPen(wxPen(clr_step.colorForStates(states)));
dc.SetBrush(wxBrush(clr_step.colorForStates(states)));
for (int i = 0; i < steps.size(); ++i) {
bool check = pos_thumb == wxPoint{0, 0} ? step == i : (pos_thumb.x >= circleX - itemWidth / 2 && pos_thumb.x < circleX + itemWidth / 2);
dc.DrawEllipse(circleX - radius, circleY - radius, radius * 2, radius * 2);
dc.SetFont(GetFont());
dc.SetTextForeground(clr_text.colorForStates(states | (check ? StateColor::Checked : 0)));
wxSize sz = dc.GetTextExtent(steps[i]);
dc.DrawText(steps[i], circleX - sz.x / 2, circleY + 20);
if (check) {
dc.SetFont(font_tip);
dc.SetTextForeground(clr_tip.colorForStates(states));
wxSize sz = dc.GetTextExtent(tips[i]);
dc.DrawText(tips[i], circleX - sz.x / 2, circleY - 20 - sz.y);
sz = bmp_thumb.GetBmpSize();
dc.DrawBitmap(bmp_thumb.bmp(), circleX - sz.x / 2, circleY - sz.y / 2);
}
circleX += itemWidth;
}
}
/* StepIndicator */
StepIndicator::StepIndicator(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style)
: StepCtrlBase(parent, id, pos, size, style)
, bmp_ok(this, "step_ok", 12)
{
SetFont(Label::Body_12);
font_tip = Label::Body_10;
clr_bar = 0xE1E1E1;
clr_step = StateColor(
std::make_pair(0xACACAC, (int) StateColor::Disabled),
std::make_pair(0x00AE42, 0));
clr_text = StateColor(
std::make_pair(0xACACAC, (int) StateColor::Disabled),
std::make_pair(0x323A3D, (int) StateColor::Checked),
std::make_pair(0x6B6B6B, 0));
clr_tip = *wxWHITE;
StaticBox::border_width = 0;
radius = bmp_ok.GetBmpHeight() / 2;
bar_width = bmp_ok.GetBmpHeight() / 20;
if (bar_width < 2) bar_width = 2;
}
void StepIndicator::Rescale()
{
bmp_ok.msw_rescale();
radius = bmp_ok.GetBmpHeight() / 2;
bar_width = bmp_ok.GetBmpHeight() / 20;
if (bar_width < 2) bar_width = 2;
}
void StepIndicator::SelectNext() { SelectItem(step + 1); }
void StepIndicator::doRender(wxDC &dc)
{
if (steps.empty()) return;
StaticBox::doRender(dc);
wxSize size = GetSize();
int states = state_handler.states();
if (!IsEnabled()) {
states = clr_step.Disabled;
}
int textWidth = size.x - radius * 5;
dc.SetFont(GetFont());
wxString firstLine;
if (step == 0) dc.SetFont(GetFont().Bold());
wxSize firstLineSize = Label::split_lines(dc, textWidth, steps.front(), firstLine);
wxString lastLine;
if (step == steps.size() - 1) dc.SetFont(GetFont().Bold());
wxSize lastLineSize = Label::split_lines(dc, textWidth, steps.back(), lastLine);
int firstPadding = std::max(0, firstLineSize.y / 2 - radius);
int lastPadding = std::max(0, lastLineSize.y / 2 - radius);
wxRect rcBar = {radius * 2 - bar_width / 2, radius * 2 + firstPadding, bar_width, size.y - radius * 6 - firstPadding - lastPadding};
int itemWidth = steps.size() == 1 ? size.y : rcBar.height / (steps.size() - 1);
// Draw thin bar stick
dc.SetPen(wxPen(clr_bar.colorForStates(states)));
dc.SetBrush(wxBrush(clr_bar.colorForStates(states)));
dc.DrawRectangle(rcBar);
int circleX = radius * 2;
int circleY = radius * 3 + firstPadding;
dc.SetPen(wxPen(clr_step.colorForStates(states)));
dc.SetBrush(wxBrush(clr_step.colorForStates(states)));
for (int i = 0; i < steps.size(); ++i) {
bool disabled = step > i;
bool checked = step == i;
// Draw circle point & texts in it
dc.DrawEllipse(circleX - radius, circleY - radius, radius * 2, radius * 2);
// Draw content ( icon or text ) in circle
if (disabled) {
wxSize sz = bmp_ok.GetBmpSize();
dc.DrawBitmap(bmp_ok.bmp(), circleX - radius, circleY - radius);
} else {
dc.SetFont(font_tip);
dc.SetTextForeground(clr_tip.colorForStates(states));
auto tip = tips[i];
if (tip.IsEmpty()) tip.append(1, wchar_t(L'0' + i + 1));
wxSize sz = dc.GetTextExtent(tip);
dc.DrawText(tip, circleX - sz.x / 2, circleY - sz.y / 2 + 1);
}
// Draw step text
dc.SetTextForeground(clr_text.colorForStates(states
| (disabled ? StateColor::Disabled : checked ? StateColor::Checked : 0)));
dc.SetFont(checked ? GetFont().Bold() : GetFont());
wxString text;
wxSize textSize;
if (i == 0) {
text = firstLine;
textSize = firstLineSize;
} else if (i == steps.size() - 1) {
text = lastLine;
textSize = lastLineSize;
} else {
textSize = Label::split_lines(dc, textWidth, steps[i], text);
}
dc.DrawText(text, circleX + radius * 3, circleY - (textSize.y / 2));
circleY += itemWidth;
}
}