SpinInputDouble

+ Update font size for application in respect to the display size
This commit is contained in:
YuSanka 2023-10-18 14:03:37 +02:00 committed by Lukas Matena
parent fea655f668
commit 8d1165d6ed
9 changed files with 626 additions and 327 deletions

View File

@ -1981,7 +1981,7 @@ void PageDiameters::apply_custom_config(DynamicPrintConfig &config)
set_extrusion_width("solid_infill_extrusion_width", 0.45);
}
class SpinCtrlDouble: public wxSpinCtrlDouble
class SpinCtrlDouble: public ::SpinInputDouble
{
public:
SpinCtrlDouble(wxWindow* parent)
@ -1991,10 +1991,7 @@ public:
#else
long style = wxSP_ARROW_KEYS;
#endif
Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, style);
#ifdef _WIN32
wxGetApp().UpdateDarkUI(this->GetText());
#endif
Create(parent, "", wxEmptyString, wxDefaultPosition, wxSize(6* wxGetApp().em_unit(), -1), style);
this->Refresh();
}
~SpinCtrlDouble() {}

View File

@ -32,6 +32,7 @@
#include "SavePresetDialog.hpp"
#include "wxExtensions.hpp"
#include "Widgets/SpinInput.hpp"
namespace fs = boost::filesystem;
@ -510,8 +511,8 @@ struct PageDiameters: ConfigWizardPage
struct PageTemperatures: ConfigWizardPage
{
wxSpinCtrlDouble *spin_extr;
wxSpinCtrlDouble *spin_bed;
::SpinInputDouble *spin_extr;
::SpinInputDouble *spin_bed;
PageTemperatures(ConfigWizard *parent);
virtual void apply_custom_config(DynamicPrintConfig &config);

View File

@ -1093,6 +1093,16 @@ bool GUI_App::OnInit()
}
}
static int get_app_font_pt_size(const AppConfig* app_config)
{
if (!app_config->has("font_pt_size"))
return -1;
const int font_pt_size = atoi(app_config->get("font_pt_size").c_str());
const int max_font_pt_size = wxGetApp().get_max_font_pt_size();
return (font_pt_size > max_font_pt_size) ? max_font_pt_size : font_pt_size;
}
bool GUI_App::on_init_inner()
{
// Set initialization of image handlers before any UI actions - See GH issue #7469
@ -1326,7 +1336,7 @@ bool GUI_App::on_init_inner()
if (!delayed_error_load_presets.empty())
show_error(nullptr, delayed_error_load_presets);
mainframe = new MainFrame(app_config->has("font_pt_size") ? atoi(app_config->get("font_pt_size").c_str()) : -1);
mainframe = new MainFrame(get_app_font_pt_size(app_config));
// hide settings tabs after first Layout
if (is_editor())
mainframe->select_tab(size_t(0));
@ -1662,6 +1672,17 @@ void GUI_App::SetWindowVariantForButton(wxButton* btn)
#endif
}
int GUI_App::get_max_font_pt_size()
{
const unsigned disp_count = wxDisplay::GetCount();
for (int i = 0; i < disp_count; i++) {
const wxRect display_rect = wxDisplay(i).GetGeometry();
if (display_rect.width >= 2560 && display_rect.height >= 1440)
return 20;
}
return 15;
}
void GUI_App::init_fonts()
{
m_small_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
@ -1863,7 +1884,7 @@ void GUI_App::recreate_GUI(const wxString& msg_name)
dlg.Update(10, _L("Recreating") + dots);
MainFrame *old_main_frame = mainframe;
mainframe = new MainFrame(app_config->has("font_pt_size") ? atoi(app_config->get("font_pt_size").c_str()) : -1);
mainframe = new MainFrame(get_app_font_pt_size(app_config));
if (is_editor())
// hide settings tabs after first Layout
mainframe->select_tab(size_t(0));

View File

@ -251,6 +251,7 @@ public:
bool tabs_as_menu() const;
bool suppress_round_corners() const;
wxSize get_min_size(wxWindow* display_win) const;
int get_max_font_pt_size();
float toolbar_icon_scale(const bool is_limited = false) const;
void set_auto_toolbar_icon_scale(float scale) const;
void check_printer_presets();

View File

@ -1094,17 +1094,6 @@ void PreferencesDialog::create_settings_mode_color_widget()
append_preferences_option_to_searcher(m_optgroup_gui, opt_key, title);
}
static int get_max_font_pt_size()
{
const unsigned disp_count = wxDisplay::GetCount();
for (int i = 0; i < disp_count; i++) {
const wxRect display_rect = wxDisplay(i).GetGeometry();
if (display_rect.width >= 2560 && display_rect.height >= 1440)
return 20;
}
return 15;
}
void PreferencesDialog::create_settings_font_widget()
{
wxWindow* parent = m_optgroup_other->parent();
@ -1125,7 +1114,7 @@ void PreferencesDialog::create_settings_font_widget()
#ifdef _WIN32
| wxBORDER_SIMPLE
#endif
, 8, get_max_font_pt_size());
, 8, wxGetApp().get_max_font_pt_size());
wxGetApp().UpdateDarkUI(size_sc);
auto apply_font = [this, font_example, opt_key, stb_sizer](const int val, const wxFont& font) {

View File

@ -10,22 +10,23 @@
#include <wx/spinctrl.h>
#include <wx/valtext.h>
BEGIN_EVENT_TABLE(SpinInput, wxPanel)
BEGIN_EVENT_TABLE(SpinInputBase, wxPanel)
EVT_KEY_DOWN(SpinInput::keyPressed)
EVT_MOUSEWHEEL(SpinInput::mouseWheelMoved)
EVT_KEY_DOWN(SpinInputBase::keyPressed)
EVT_MOUSEWHEEL(SpinInputBase::mouseWheelMoved)
EVT_PAINT(SpinInput::paintEvent)
EVT_PAINT(SpinInputBase::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().
*/
SpinInput::SpinInput()
SpinInputBase::SpinInputBase()
: 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))
{
@ -34,6 +35,230 @@ SpinInput::SpinInput()
border_width = 1;
}
Button * SpinInputBase::create_button(ButtonId id)
{
auto btn = new Button(this, "", id == ButtonId::btnIncrease ? "spin_inc_act" : "spin_dec_act", wxBORDER_NONE, wxSize(12, 7));
btn->SetCornerRadius(0);
btn->SetInactiveIcon(id == ButtonId::btnIncrease ? "spin_inc" : "spin_dec");
btn->DisableFocusFromKeyboard();
btn->SetSelected(false);
bind_inc_dec_button(btn, id);
return btn;
}
void SpinInputBase::SetCornerRadius(double radius)
{
this->radius = radius;
Refresh();
}
void SpinInputBase::SetLabel(const wxString &label)
{
wxWindow::SetLabel(label);
messureSize();
Refresh();
}
void SpinInputBase::SetLabelColor(StateColor const &color)
{
label_color = color;
state_handler.update_binds();
}
void SpinInputBase::SetTextColor(StateColor const &color)
{
text_color = color;
state_handler.update_binds();
}
void SpinInputBase::SetSize(wxSize const &size)
{
wxWindow::SetSize(size);
Rescale();
}
wxString SpinInputBase::GetTextValue() const
{
return text_ctrl->GetValue();
}
void SpinInput::SetRange(int min, int max)
{
this->min = min;
this->max = max;
}
void SpinInputBase::SetSelection(long from, long to)
{
if (text_ctrl)
text_ctrl->SetSelection(from, to);
}
bool SpinInputBase::SetFont(wxFont const& font)
{
if (text_ctrl)
return text_ctrl->SetFont(font);
return StaticBox::SetFont(font);
}
bool SpinInputBase::SetBackgroundColour(const wxColour& colour)
{
const int clr_background_disabled = Slic3r::GUI::wxGetApp().dark_mode() ? clr_background_disabled_dark : clr_background_disabled_light;
StateColor clr_state(std::make_pair(clr_background_disabled, (int)StateColor::Disabled),
std::make_pair(clr_background_focused, (int)StateColor::Checked),
std::make_pair(colour, (int)StateColor::Focused),
std::make_pair(colour, (int)StateColor::Normal));
StaticBox::SetBackgroundColor(clr_state);
if (text_ctrl)
text_ctrl->SetBackgroundColour(colour);
if (button_inc)
button_inc->SetBackgroundColor(clr_state);
if (button_dec)
button_dec->SetBackgroundColor(clr_state);
return true;
}
bool SpinInputBase::SetForegroundColour(const wxColour& colour)
{
StateColor clr_state(std::make_pair(clr_foreground_disabled, (int)StateColor::Disabled),
std::make_pair(colour, (int)StateColor::Normal));
SetLabelColor(clr_state);
SetTextColor(clr_state);
if (text_ctrl)
text_ctrl->SetForegroundColour(colour);
if (button_inc)
button_inc->SetTextColor(clr_state);
if (button_dec)
button_dec->SetTextColor(clr_state);
return true;
}
void SpinInputBase::SetBorderColor(StateColor const &color)
{
StaticBox::SetBorderColor(color);
if (button_inc)
button_inc->SetBorderColor(color);
if (button_dec)
button_dec->SetBorderColor(color);
}
void SpinInputBase::DoSetToolTipText(wxString const &tip)
{
wxWindow::DoSetToolTipText(tip);
text_ctrl->SetToolTip(tip);
}
void SpinInputBase::Rescale()
{
SetFont(Slic3r::GUI::wxGetApp().normal_font());
text_ctrl->SetInitialSize(text_ctrl->GetBestSize());
button_inc->Rescale();
button_dec->Rescale();
messureSize();
}
bool SpinInputBase::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()));
button_inc->Enable(enable);
button_dec->Enable(enable);
}
return result;
}
void SpinInputBase::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 SpinInputBase::render(wxDC& dc)
{
StaticBox::render(dc);
int states = state_handler.states();
wxSize size = GetSize();
// draw seperator of buttons
wxPoint pt = button_inc->GetPosition();
pt.y = size.y / 2;
dc.SetPen(wxPen(border_color.defaultColor()));
const double scale = dc.GetContentScaleFactor();
const int btn_w = button_inc->GetSize().GetWidth();
dc.DrawLine(pt, pt + wxSize{ btn_w - int(scale), 0});
// draw label
auto label = GetLabel();
if (!label.IsEmpty()) {
pt.x = size.x - labelSize.x - 5;
pt.y = (size.y - labelSize.y) / 2;
dc.SetFont(GetFont());
dc.SetTextForeground(label_color.colorForStates(states));
dc.DrawText(label, pt);
}
}
void SpinInputBase::messureSize()
{
wxSize size = GetSize();
wxSize textSize = text_ctrl->GetSize();
int h = textSize.y + 8;
if (size.y != h) {
size.y = h;
SetSize(size);
SetMinSize(size);
}
wxSize btnSize = {14, (size.y - 4) / 2};
btnSize.x = btnSize.x * btnSize.y / 10;
const double scale = this->GetContentScaleFactor();
wxClientDC dc(this);
labelSize = dc.GetMultiLineTextExtent(GetLabel());
textSize.x = size.x - labelSize.x - btnSize.x - 16;
text_ctrl->SetSize(textSize);
text_ctrl->SetPosition({int(3. * scale), (size.y - textSize.y) / 2});
button_inc->SetSize(btnSize);
button_dec->SetSize(btnSize);
button_inc->SetPosition({size.x - btnSize.x - int(3. * scale), size.y / 2 - btnSize.y/* - 1*/});
button_dec->SetPosition({size.x - btnSize.x - int(3. * scale), size.y / 2 + 1});
}
void SpinInputBase::onText(wxCommandEvent &event)
{
sendSpinEvent();
event.SetId(GetId());
ProcessEventLocally(event);
}
void SpinInputBase::sendSpinEvent()
{
wxCommandEvent event(wxEVT_SPINCTRL, GetId());
event.SetEventObject(this);
GetEventHandler()->ProcessEvent(event);
}
// SpinInput
SpinInput::SpinInput(wxWindow *parent,
wxString text,
@ -42,7 +267,7 @@ SpinInput::SpinInput(wxWindow *parent,
const wxSize & size,
long style,
int min, int max, int initial)
: SpinInput()
: SpinInputBase()
{
Create(parent, text, label, pos, size, style, min, max, initial);
}
@ -91,35 +316,29 @@ void SpinInput::Create(wxWindow *parent,
messureSize();
}
void SpinInput::SetCornerRadius(double radius)
void SpinInput::bind_inc_dec_button(Button *btn, ButtonId id)
{
this->radius = radius;
Refresh();
}
void SpinInput::SetLabel(const wxString &label)
{
wxWindow::SetLabel(label);
messureSize();
Refresh();
}
void SpinInput::SetLabelColor(StateColor const &color)
{
label_color = color;
state_handler.update_binds();
}
void SpinInput::SetTextColor(StateColor const &color)
{
text_color = color;
state_handler.update_binds();
}
void SpinInput::SetSize(wxSize const &size)
{
wxWindow::SetSize(size);
Rescale();
btn->Bind(wxEVT_LEFT_DOWN, [this, btn, id](auto& e) {
delta = id == ButtonId::btnIncrease ? 1 : -1;
SetValue(val + delta);
text_ctrl->SetFocus();
btn->CaptureMouse();
delta *= 8;
timer.Start(100);
sendSpinEvent();
});
btn->Bind(wxEVT_LEFT_DCLICK, [this, btn, id](auto& e) {
delta = id == ButtonId::btnIncrease ? 1 : -1;
btn->CaptureMouse();
SetValue(val + delta);
sendSpinEvent();
});
btn->Bind(wxEVT_LEFT_UP, [this, btn](auto& e) {
btn->ReleaseMouse();
timer.Stop();
text_ctrl->SelectAll();
delta = 0;
});
}
void SpinInput::SetValue(const wxString &text)
@ -144,202 +363,6 @@ int SpinInput::GetValue()const
return val;
}
wxString SpinInput::GetTextValue() const
{
return text_ctrl->GetValue();
}
void SpinInput::SetRange(int min, int max)
{
this->min = min;
this->max = max;
}
void SpinInput::SetSelection(long from, long to)
{
if (text_ctrl)
text_ctrl->SetSelection(from, to);
}
bool SpinInput::SetFont(wxFont const& font)
{
if (text_ctrl)
return text_ctrl->SetFont(font);
return StaticBox::SetFont(font);
}
bool SpinInput::SetBackgroundColour(const wxColour& colour)
{
const int clr_background_disabled = Slic3r::GUI::wxGetApp().dark_mode() ? clr_background_disabled_dark : clr_background_disabled_light;
StateColor clr_state(std::make_pair(clr_background_disabled, (int)StateColor::Disabled),
std::make_pair(clr_background_focused, (int)StateColor::Checked),
std::make_pair(colour, (int)StateColor::Focused),
std::make_pair(colour, (int)StateColor::Normal));
StaticBox::SetBackgroundColor(clr_state);
if (text_ctrl)
text_ctrl->SetBackgroundColour(colour);
if (button_inc)
button_inc->SetBackgroundColor(clr_state);
if (button_dec)
button_dec->SetBackgroundColor(clr_state);
return true;
}
bool SpinInput::SetForegroundColour(const wxColour& colour)
{
StateColor clr_state(std::make_pair(clr_foreground_disabled, (int)StateColor::Disabled),
std::make_pair(colour, (int)StateColor::Normal));
SetLabelColor(clr_state);
SetTextColor(clr_state);
if (text_ctrl)
text_ctrl->SetForegroundColour(colour);
if (button_inc)
button_inc->SetTextColor(clr_state);
if (button_dec)
button_dec->SetTextColor(clr_state);
return true;
}
void SpinInput::SetBorderColor(StateColor const &color)
{
StaticBox::SetBorderColor(color);
if (button_inc)
button_inc->SetBorderColor(color);
if (button_dec)
button_dec->SetBorderColor(color);
}
void SpinInput::DoSetToolTipText(wxString const &tip)
{
wxWindow::DoSetToolTipText(tip);
text_ctrl->SetToolTip(tip);
}
void SpinInput::Rescale()
{
SetFont(Slic3r::GUI::wxGetApp().normal_font());
text_ctrl->SetInitialSize(text_ctrl->GetBestSize());
button_inc->Rescale();
button_dec->Rescale();
messureSize();
}
bool SpinInput::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()));
button_inc->Enable(enable);
button_dec->Enable(enable);
}
return result;
}
void SpinInput::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 SpinInput::render(wxDC& dc)
{
StaticBox::render(dc);
int states = state_handler.states();
wxSize size = GetSize();
// draw seperator of buttons
wxPoint pt = button_inc->GetPosition();
pt.y = size.y / 2;
dc.SetPen(wxPen(border_color.defaultColor()));
const double scale = dc.GetContentScaleFactor();
const int btn_w = button_inc->GetSize().GetWidth();
dc.DrawLine(pt, pt + wxSize{ btn_w - int(scale), 0});
// draw label
auto label = GetLabel();
if (!label.IsEmpty()) {
pt.x = size.x - labelSize.x - 5;
pt.y = (size.y - labelSize.y) / 2;
dc.SetFont(GetFont());
dc.SetTextForeground(label_color.colorForStates(states));
dc.DrawText(label, pt);
}
}
void SpinInput::messureSize()
{
wxSize size = GetSize();
wxSize textSize = text_ctrl->GetSize();
int h = textSize.y + 8;
if (size.y != h) {
size.y = h;
SetSize(size);
SetMinSize(size);
}
wxSize btnSize = {14, (size.y - 4) / 2};
btnSize.x = btnSize.x * btnSize.y / 10;
const double scale = this->GetContentScaleFactor();
wxClientDC dc(this);
labelSize = dc.GetMultiLineTextExtent(GetLabel());
textSize.x = size.x - labelSize.x - btnSize.x - 16;
text_ctrl->SetSize(textSize);
text_ctrl->SetPosition({int(3. * scale), (size.y - textSize.y) / 2});
button_inc->SetSize(btnSize);
button_dec->SetSize(btnSize);
button_inc->SetPosition({size.x - btnSize.x - int(3. * scale), size.y / 2 - btnSize.y/* - 1*/});
button_dec->SetPosition({size.x - btnSize.x - int(3. * scale), size.y / 2 + 1});
}
Button *SpinInput::create_button(ButtonId id)
{
auto btn = new Button(this, "", id == ButtonId::btnIncrease ? "spin_inc_act" : "spin_dec_act", wxBORDER_NONE, wxSize(12, 7));
btn->SetCornerRadius(0);
btn->SetInactiveIcon(id == ButtonId::btnIncrease ? "spin_inc" : "spin_dec");
btn->DisableFocusFromKeyboard();
btn->SetSelected(false);
btn->Bind(wxEVT_LEFT_DOWN, [=](auto &e) {
delta = id == ButtonId::btnIncrease ? 1 : -1;
SetValue(val + delta);
text_ctrl->SetFocus();
btn->CaptureMouse();
delta *= 8;
timer.Start(100);
sendSpinEvent();
});
btn->Bind(wxEVT_LEFT_DCLICK, [=](auto &e) {
delta = id == ButtonId::btnIncrease ? 1 : -1;
btn->CaptureMouse();
SetValue(val + delta);
sendSpinEvent();
});
btn->Bind(wxEVT_LEFT_UP, [=](auto &e) {
btn->ReleaseMouse();
timer.Stop();
text_ctrl->SelectAll();
delta = 0;
});
return btn;
}
void SpinInput::onTimer(wxTimerEvent &evnet) {
if (delta < -1 || delta > 1) {
delta /= 2;
@ -367,7 +390,9 @@ void SpinInput::onTextLostFocus(wxEvent &event)
void SpinInput::onTextEnter(wxCommandEvent &event)
{
long value;
if (!text_ctrl->GetValue().ToLong(&value)) { value = val; }
if (!text_ctrl->GetValue().ToLong(&value))
value = val;
if (value != val) {
SetValue(value);
sendSpinEvent();
@ -376,13 +401,6 @@ void SpinInput::onTextEnter(wxCommandEvent &event)
ProcessEventLocally(event);
}
void SpinInput::onText(wxCommandEvent &event)
{
sendSpinEvent();
event.SetId(GetId());
ProcessEventLocally(event);
}
void SpinInput::mouseWheelMoved(wxMouseEvent &event)
{
auto delta = (event.GetWheelRotation() < 0 == event.IsWheelInverted()) ? 1 : -1;
@ -412,9 +430,204 @@ void SpinInput::keyPressed(wxKeyEvent &event)
}
}
void SpinInput::sendSpinEvent()
// SpinInputDouble
SpinInputDouble::SpinInputDouble(wxWindow * parent,
wxString text,
wxString label,
const wxPoint &pos,
const wxSize & size,
long style,
double min, double max, double initial,
double inc)
: SpinInputBase()
{
wxCommandEvent event(wxEVT_SPINCTRL, GetId());
event.SetEventObject(this);
GetEventHandler()->ProcessEvent(event);
Create(parent, text, label, pos, size, style, min, max, initial, inc);
}
void SpinInputDouble::Create(wxWindow *parent,
wxString text,
wxString label,
const wxPoint &pos,
const wxSize & size,
long style,
double min, double max, double initial,
double inc)
{
StaticBox::Create(parent, wxID_ANY, pos, size);
wxWindow::SetLabel(label);
state_handler.attach({&label_color, &text_color});
state_handler.update_binds();
text_ctrl = new wxTextCtrl(this, wxID_ANY, text, {20, 4}, wxDefaultSize, style | wxBORDER_NONE | wxTE_PROCESS_ENTER, wxTextValidator(wxFILTER_DIGITS));
#ifdef __WXOSX__
text_ctrl->OSXDisableAllSmartSubstitutions();
#endif // __WXOSX__
text_ctrl->SetInitialSize(text_ctrl->GetBestSize());
state_handler.attach_child(text_ctrl);
text_ctrl->Bind(wxEVT_KILL_FOCUS, &SpinInputDouble::onTextLostFocus, this);
text_ctrl->Bind(wxEVT_TEXT, &SpinInputDouble::onText, this);
text_ctrl->Bind(wxEVT_TEXT_ENTER, &SpinInputDouble::onTextEnter, this);
text_ctrl->Bind(wxEVT_KEY_DOWN, &SpinInputDouble::keyPressed, this);
text_ctrl->Bind(wxEVT_RIGHT_DOWN, [this](auto &e) {}); // disable context menu
button_inc = create_button(ButtonId::btnIncrease);
button_dec = create_button(ButtonId::btnDecrease);
delta = 0;
timer.Bind(wxEVT_TIMER, &SpinInputDouble::onTimer, this);
SetFont(Slic3r::GUI::wxGetApp().normal_font());
if (parent) {
SetBackgroundColour(parent->GetBackgroundColour());
SetForegroundColour(parent->GetForegroundColour());
}
double initialFromText;
if (text.ToDouble(&initialFromText)) initial = initialFromText;
SetRange(min, max);
SetIncrement(inc);
SetValue(initial);
messureSize();
}
void SpinInputDouble::bind_inc_dec_button(Button *btn, ButtonId id)
{
btn->Bind(wxEVT_LEFT_DOWN, [this, btn, id](auto& e) {
delta = id == ButtonId::btnIncrease ? inc : -inc;
SetValue(val + delta);
text_ctrl->SetFocus();
btn->CaptureMouse();
delta *= 8;
timer.Start(100);
sendSpinEvent();
});
btn->Bind(wxEVT_LEFT_DCLICK, [this, btn, id](auto& e) {
delta = id == ButtonId::btnIncrease ? inc : -inc;
btn->CaptureMouse();
SetValue(val + delta);
sendSpinEvent();
});
btn->Bind(wxEVT_LEFT_UP, [this, btn](auto& e) {
btn->ReleaseMouse();
timer.Stop();
text_ctrl->SelectAll();
delta = 0;
});
}
void SpinInputDouble::SetValue(const wxString &text)
{
double value;
if ( text.ToDouble(&value) )
SetValue(value);
else
text_ctrl->SetValue(text);
}
void SpinInputDouble::SetValue(double value)
{
if (Slic3r::is_approx(value, val))
return;
if (value < min) value = min;
else if (value > max) value = max;
this->val = value;
wxString str_val = wxString::FromDouble(value, digits);
text_ctrl->SetValue(str_val);
}
double SpinInputDouble::GetValue()const
{
return val;
}
void SpinInputDouble::SetRange(double min, double max)
{
this->min = min;
this->max = max;
}
void SpinInputDouble::SetIncrement(double inc_in)
{
inc = inc_in;
}
void SpinInputDouble::SetDigits(unsigned digits_in)
{
digits = int(digits_in);
}
void SpinInputDouble::onTimer(wxTimerEvent &evnet) {
if (delta < -inc || delta > inc) {
delta /= 2;
return;
}
SetValue(val + delta);
sendSpinEvent();
}
void SpinInputDouble::onTextLostFocus(wxEvent &event)
{
timer.Stop();
for (auto * child : GetChildren())
if (auto btn = dynamic_cast<Button*>(child))
if (btn->HasCapture())
btn->ReleaseMouse();
wxCommandEvent e;
onTextEnter(e);
// pass to outer
event.SetId(GetId());
ProcessEventLocally(event);
e.Skip();
}
void SpinInputDouble::onTextEnter(wxCommandEvent &event)
{
double value;
if (!text_ctrl->GetValue().ToDouble(&value))
val = value;
if (!Slic3r::is_approx(value, val)) {
SetValue(value);
sendSpinEvent();
}
event.SetId(GetId());
ProcessEventLocally(event);
}
void SpinInputDouble::mouseWheelMoved(wxMouseEvent &event)
{
auto delta = (event.GetWheelRotation() < 0 == event.IsWheelInverted()) ? inc : -inc;
SetValue(val + delta);
sendSpinEvent();
text_ctrl->SetFocus();
}
void SpinInputDouble::keyPressed(wxKeyEvent &event)
{
switch (event.GetKeyCode()) {
case WXK_UP:
case WXK_DOWN:
double value;
if (!text_ctrl->GetValue().ToDouble(&value))
val = value;
if (event.GetKeyCode() == WXK_DOWN && value > min) {
value -= inc;
} else if (event.GetKeyCode() == WXK_UP && value + inc < max) {
value += inc;
}
if (!Slic3r::is_approx(value, val)) {
SetValue(value);
sendSpinEvent();
}
break;
default: event.Skip(); break;
}
}

View File

@ -6,8 +6,9 @@
class Button;
class SpinInput : public wxNavigationEnabled<StaticBox>
class SpinInputBase : public wxNavigationEnabled<StaticBox>
{
protected:
wxSize labelSize;
StateColor label_color;
StateColor text_color;
@ -16,11 +17,6 @@ class SpinInput : public wxNavigationEnabled<StaticBox>
Button * button_dec {nullptr};
wxTimer timer;
int val;
int min;
int max;
int delta;
static const int SpinInputWidth = 200;
static const int SpinInputHeight = 50;
@ -31,8 +27,69 @@ class SpinInput : public wxNavigationEnabled<StaticBox>
};
public:
SpinInput();
SpinInputBase();
void SetCornerRadius(double radius);
void SetLabel(const wxString &label) wxOVERRIDE;
void SetLabelColor(StateColor const &color);
void SetTextColor(StateColor const &color);
void SetSize(wxSize const &size);
void Rescale();
virtual bool Enable(bool enable = true) wxOVERRIDE;
wxTextCtrl * GetText() { return text_ctrl; }
virtual void SetValue(const wxString &text) = 0;
wxString GetTextValue() const;
bool SetFont(wxFont const& font) override;
bool SetBackgroundColour(const wxColour& colour) override;
bool SetForegroundColour(const wxColour& colour) override;
void SetBorderColor(StateColor const& color);
void SetSelection(long from, long to);
protected:
void DoSetToolTipText(wxString const &tip) override;
void paintEvent(wxPaintEvent& evt);
void render(wxDC& dc);
void messureSize();
Button *create_button(ButtonId id);
virtual void bind_inc_dec_button(Button *btn, ButtonId id) = 0;
// some useful events
virtual void mouseWheelMoved(wxMouseEvent& event) = 0;
virtual void keyPressed(wxKeyEvent& event) = 0;
virtual void onTimer(wxTimerEvent &evnet) = 0;
virtual void onTextLostFocus(wxEvent &event) = 0;
virtual void onTextEnter(wxCommandEvent &event) = 0;
void onText(wxCommandEvent &event);
void sendSpinEvent();
DECLARE_EVENT_TABLE()
};
class SpinInput : public SpinInputBase
{
int val;
int min;
int max;
int delta;
public:
SpinInput(wxWindow * parent,
wxString text,
wxString label = "",
@ -51,64 +108,83 @@ public:
int max = 100,
int initial = 0);
void SetCornerRadius(double radius);
void SetLabel(const wxString &label) wxOVERRIDE;
void SetLabelColor(StateColor const &color);
void SetTextColor(StateColor const &color);
void SetSize(wxSize const &size);
void Rescale();
virtual bool Enable(bool enable = true) wxOVERRIDE;
wxTextCtrl * GetText() { return text_ctrl; }
void SetValue(const wxString &text);
void SetValue(const wxString &text) override;
void SetValue (int value);
int GetValue () const;
wxString GetTextValue() const;
void SetRange(int min, int max);
bool SetFont(wxFont const& font) override;
bool SetBackgroundColour(const wxColour& colour) override;
bool SetForegroundColour(const wxColour& colour) override;
void SetBorderColor(StateColor const& color);
int GetMin() const { return this->min; }
int GetMax() const { return this->max; }
void SetSelection(long from, long to);
protected:
void DoSetToolTipText(wxString const &tip) override;
private:
void paintEvent(wxPaintEvent& evt);
void render(wxDC& dc);
void messureSize();
Button *create_button(ButtonId id);
void bind_inc_dec_button(Button* btn, ButtonId id) override;
// some useful events
void mouseWheelMoved(wxMouseEvent& event);
void keyPressed(wxKeyEvent& event);
void onTimer(wxTimerEvent &evnet);
void onTextLostFocus(wxEvent &event);
void onText(wxCommandEvent &event);
void onTextEnter(wxCommandEvent &event);
void mouseWheelMoved(wxMouseEvent& event) override;
void keyPressed(wxKeyEvent& event) override;
void onTimer(wxTimerEvent& evnet) override;
void onTextLostFocus(wxEvent& event) override;
void onTextEnter(wxCommandEvent& event) override;
};
void sendSpinEvent();
class SpinInputDouble : public SpinInputBase
{
double val;
double min;
double max;
double inc;
double delta;
int digits {-1};
DECLARE_EVENT_TABLE()
public:
SpinInputDouble() : SpinInputBase() {}
SpinInputDouble(wxWindow* parent,
wxString text,
wxString label = "",
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0,
double min = 0.,
double max = 100.,
double initial = 0.,
double inc = 1.);
void Create(wxWindow* parent,
wxString text,
wxString label = "",
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0,
double min = 0.,
double max = 100.,
double initial = 0.,
double inc = 1.);
void SetValue(const wxString& text) override;
void SetValue(double value);
double GetValue() const;
//wxString GetTextValue() const override;
void SetRange(double min, double max);
void SetIncrement(double inc);
void SetDigits(unsigned digits);
double GetMin() const { return this->min; }
double GetMax() const { return this->max; }
protected:
void bind_inc_dec_button(Button* btn, ButtonId id) override;
// some useful events
void mouseWheelMoved(wxMouseEvent& event) override;
void keyPressed(wxKeyEvent& event) override;
void onTimer(wxTimerEvent& evnet) override;
void onTextLostFocus(wxEvent& event) override;
void onTextEnter(wxCommandEvent& event) override;
};
#endif // !slic3r_GUI_SpinInput_hpp_

View File

@ -109,7 +109,8 @@ RammingPanel::RammingPanel(wxWindow* parent, const std::string& parameters)
#endif
sizer_chart->Add(m_chart, 0, wxALL, 5);
m_widget_time = new wxSpinCtrlDouble(this,wxID_ANY,wxEmptyString,wxDefaultPosition,wxSize(ITEM_WIDTH(), -1),style,0.,5.0,3.,0.5);
m_widget_time = new ::SpinInputDouble(this,"", wxEmptyString, wxDefaultPosition, wxSize(ITEM_WIDTH(), -1), style, 0., 5., 3., 0.5);
m_widget_time->SetDigits(2);
m_widget_volume = new ::SpinInput(this,"",wxEmptyString,wxDefaultPosition,wxSize(ITEM_WIDTH(), -1),style,0,10000,0);
m_widget_ramming_line_width_multiplicator = new ::SpinInput(this,"",wxEmptyString,wxDefaultPosition,wxSize(ITEM_WIDTH(), -1),style,10,200,100);
m_widget_ramming_step_multiplicator = new ::SpinInput(this,"",wxEmptyString,wxDefaultPosition,wxSize(ITEM_WIDTH(), -1),style,10,200,100);
@ -136,7 +137,6 @@ RammingPanel::RammingPanel(wxWindow* parent, const std::string& parameters)
sizer_param->Add(gsizer_param, 0, wxTOP, scale(10));
m_widget_time->SetValue(m_chart->get_time());
m_widget_time->SetDigits(2);
m_widget_volume->SetValue(m_chart->get_volume());
m_widget_volume->Disable();
m_widget_ramming_line_width_multiplicator->SetValue(m_ramming_line_width_multiplicator);
@ -152,8 +152,9 @@ RammingPanel::RammingPanel(wxWindow* parent, const std::string& parameters)
sizer->SetSizeHints(this);
SetSizer(sizer);
m_widget_time->Bind(wxEVT_TEXT,[this](wxCommandEvent&) {m_chart->set_xy_range(m_widget_time->GetValue(),-1);});
m_widget_time->Bind(wxEVT_SPINCTRL,[this](wxCommandEvent&) { m_chart->set_xy_range(m_widget_time->GetValue(),-1); });
m_widget_time->Bind(wxEVT_CHAR,[](wxKeyEvent&){}); // do nothing - prevents the user to change the value
m_widget_time->GetText()->Bind(wxEVT_CHAR,[](wxKeyEvent&){}); // do nothing - prevents the user to change the value
m_widget_volume->Bind(wxEVT_CHAR,[](wxKeyEvent&){}); // do nothing - prevents the user to change the value
Bind(EVT_WIPE_TOWER_CHART_CHANGED,[this](wxCommandEvent&) {m_widget_volume->SetValue(m_chart->get_volume()); m_widget_time->SetValue(m_chart->get_time());} );
Refresh(true); // erase background

View File

@ -26,7 +26,7 @@ private:
::SpinInput* m_widget_volume = nullptr;
::SpinInput* m_widget_ramming_line_width_multiplicator = nullptr;
::SpinInput* m_widget_ramming_step_multiplicator = nullptr;
wxSpinCtrlDouble* m_widget_time = nullptr;
::SpinInputDouble* m_widget_time = nullptr;
int m_ramming_step_multiplicator;
int m_ramming_line_width_multiplicator;