BambuStudio/slic3r/GUI/Widgets/TextInput.cpp

243 lines
7.1 KiB
C++

#include "TextInput.hpp"
#include "Label.hpp"
#include "TextCtrl.h"
#include <wx/dcclient.h>
#include <wx/dcgraph.h>
BEGIN_EVENT_TABLE(TextInput, wxPanel)
EVT_PAINT(TextInput::paintEvent)
END_EVENT_TABLE()
/*
* Called by the system of by wxWidgets when the panel needs
* to be redrawn. You can also trigger this call by
* calling Refresh()/Update().
*/
TextInput::TextInput()
: label_color(std::make_pair(0x909090, (int) StateColor::Disabled),
std::make_pair(0x6B6B6B, (int) StateColor::Normal))
, text_color(std::make_pair(0x909090, (int) StateColor::Disabled),
std::make_pair(0x262E30, (int) StateColor::Normal))
{
radius = 0;
border_width = 1;
//border_color = StateColor(std::make_pair(0xDBDBDB, (int) StateColor::Disabled), std::make_pair(0x00AE42, (int) StateColor::Hovered),
border_color = StateColor(std::make_pair(0xDBDBDB, (int) StateColor::Disabled), std::make_pair(0x215F9A, (int) StateColor::Hovered),
std::make_pair(0xDBDBDB, (int) StateColor::Normal));
background_color = StateColor(std::make_pair(0xF0F0F1, (int) StateColor::Disabled), std::make_pair(*wxWHITE, (int) StateColor::Normal));
SetFont(Label::Body_12);
}
TextInput::TextInput(wxWindow * parent,
wxString text,
wxString label,
wxString icon,
const wxPoint &pos,
const wxSize & size,
long style)
: TextInput()
{
Create(parent, text, label, icon, pos, size, style);
}
void TextInput::Create(wxWindow * parent,
wxString text,
wxString label,
wxString icon,
const wxPoint &pos,
const wxSize & size,
long style)
{
text_ctrl = nullptr;
StaticBox::Create(parent, wxID_ANY, pos, size, style);
wxWindow::SetLabel(label);
style &= ~wxRIGHT;
state_handler.attach({&label_color, & text_color});
state_handler.update_binds();
text_ctrl = new TextCtrl(this, wxID_ANY, text, {4, 4}, wxDefaultSize, style | wxBORDER_NONE | wxTE_PROCESS_ENTER);
text_ctrl->SetFont(Label::Body_14);
text_ctrl->SetInitialSize(text_ctrl->GetBestSize());
text_ctrl->SetBackgroundColour(background_color.colorForStates(state_handler.states()));
text_ctrl->SetForegroundColour(text_color.colorForStates(state_handler.states()));
state_handler.attach_child(text_ctrl);
text_ctrl->Bind(wxEVT_KILL_FOCUS, [this](auto &e) {
OnEdit();
e.SetId(GetId());
ProcessEventLocally(e);
e.Skip();
});
text_ctrl->Bind(wxEVT_TEXT_ENTER, [this](auto &e) {
OnEdit();
e.SetId(GetId());
ProcessEventLocally(e);
});
text_ctrl->Bind(wxEVT_RIGHT_DOWN, [this](auto &e) {}); // disable context menu
if (!icon.IsEmpty()) {
this->icon = ScalableBitmap(this, icon.ToStdString(), 16);
}
messureSize();
}
void TextInput::SetCornerRadius(double radius)
{
this->radius = radius;
Refresh();
}
void TextInput::SetLabel(const wxString& label)
{
wxWindow::SetLabel(label);
messureSize();
Refresh();
}
void TextInput::SetIcon(const wxBitmap &icon)
{
this->icon = ScalableBitmap();
this->icon.bmp() = icon;
Rescale();
}
void TextInput::SetIcon(const wxString &icon)
{
if (this->icon.name() == icon.ToStdString())
return;
this->icon = ScalableBitmap(this, icon.ToStdString(), 16);
Rescale();
}
void TextInput::SetLabelColor(StateColor const &color)
{
label_color = color;
state_handler.update_binds();
}
void TextInput::SetTextColor(StateColor const& color)
{
text_color= color;
state_handler.update_binds();
}
void TextInput::Rescale()
{
if (!this->icon.name().empty())
this->icon.msw_rescale();
messureSize();
Refresh();
}
bool TextInput::Enable(bool enable)
{
bool result = text_ctrl->Enable(enable) && wxWindow::Enable(enable);
if (result) {
wxCommandEvent e(EVT_ENABLE_CHANGED);
e.SetEventObject(this);
GetEventHandler()->ProcessEvent(e);
text_ctrl->SetBackgroundColour(background_color.colorForStates(state_handler.states()));
text_ctrl->SetForegroundColour(text_color.colorForStates(state_handler.states()));
}
return result;
}
void TextInput::SetMinSize(const wxSize& size)
{
wxSize size2 = size;
if (size2.y < 0) {
#ifdef __WXMAC__
if (GetPeer()) // peer is not ready in Create on mac
#endif
size2.y = GetSize().y;
}
wxWindow::SetMinSize(size2);
}
void TextInput::DoSetSize(int x, int y, int width, int height, int sizeFlags)
{
wxWindow::DoSetSize(x, y, width, height, sizeFlags);
if (sizeFlags & wxSIZE_USE_EXISTING) return;
wxSize size = GetSize();
wxPoint textPos = {5, 0};
if (this->icon.bmp().IsOk()) {
wxSize szIcon = this->icon.GetBmpSize();
textPos.x += szIcon.x;
}
bool align_right = GetWindowStyle() & wxRIGHT;
if (align_right)
textPos.x += labelSize.x;
if (text_ctrl) {
wxSize textSize = text_ctrl->GetSize();
textSize.x = size.x - textPos.x - labelSize.x - 10;
text_ctrl->SetSize(textSize);
text_ctrl->SetPosition({textPos.x, (size.y - textSize.y) / 2});
}
}
void TextInput::DoSetToolTipText(wxString const &tip)
{
wxWindow::DoSetToolTipText(tip);
text_ctrl->SetToolTip(tip);
}
void TextInput::paintEvent(wxPaintEvent &evt)
{
// depending on your system you may need to look at double-buffered dcs
wxPaintDC dc(this);
render(dc);
}
/*
* Here we do the actual rendering. I put it in a separate
* method so that it can work no matter what type of DC
* (e.g. wxPaintDC or wxClientDC) is used.
*/
void TextInput::render(wxDC& dc)
{
StaticBox::render(dc);
int states = state_handler.states();
wxSize size = GetSize();
bool align_right = GetWindowStyle() & wxRIGHT;
// start draw
wxPoint pt = {5, 0};
if (icon.bmp().IsOk()) {
wxSize szIcon = icon.GetBmpSize();
pt.y = (size.y - szIcon.y) / 2;
dc.DrawBitmap(icon.bmp(), pt);
pt.x += szIcon.x + 0;
}
auto text = wxWindow::GetLabel();
if (!text.IsEmpty()) {
wxSize textSize = text_ctrl->GetSize();
if (align_right) {
if (pt.x + labelSize.x > size.x)
text = wxControl::Ellipsize(text, dc, wxELLIPSIZE_END, size.x - pt.x);
pt.y = (size.y - labelSize.y) / 2;
} else {
pt.x += textSize.x;
pt.y = (size.y + textSize.y) / 2 - labelSize.y;
}
dc.SetTextForeground(label_color.colorForStates(states));
dc.SetFont(GetFont());
dc.DrawText(text, pt);
}
}
void TextInput::messureSize()
{
wxSize size = GetSize();
wxClientDC dc(this);
labelSize = dc.GetTextExtent(wxWindow::GetLabel());
wxSize textSize = text_ctrl->GetSize();
int h = textSize.y + 8;
if (size.y < h) {
size.y = h;
}
wxSize minSize = size;
minSize.x = GetMinWidth();
SetMinSize(minSize);
SetSize(size);
}