improve the spinbox and inputbox
improve the input check for spinbox add a verifier to check user input for inputbox
This commit is contained in:
parent
e0a9a94a8b
commit
274155b1da
@ -206,6 +206,9 @@ namespace nana
|
|||||||
|
|
||||||
return _m_open(contents, true);
|
return _m_open(contents, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets a verifier to verify the user input.
|
||||||
|
void verify(std::function<bool(window)> verifier);
|
||||||
private:
|
private:
|
||||||
void _m_fetch_args(std::vector<abstract_content*>&);
|
void _m_fetch_args(std::vector<abstract_content*>&);
|
||||||
|
|
||||||
@ -221,6 +224,7 @@ namespace nana
|
|||||||
window owner_;
|
window owner_;
|
||||||
::nana::string description_;
|
::nana::string description_;
|
||||||
::nana::string title_;
|
::nana::string title_;
|
||||||
|
std::function<bool(window)> verifier_;
|
||||||
};
|
};
|
||||||
}//end namespace nana
|
}//end namespace nana
|
||||||
|
|
||||||
|
|||||||
@ -69,6 +69,8 @@ namespace nana
|
|||||||
/// "corrected" size that changes lines to fit the text into the specified width
|
/// "corrected" size that changes lines to fit the text into the specified width
|
||||||
nana::size measure(unsigned allowed_width_in_pixel) const;
|
nana::size measure(unsigned allowed_width_in_pixel) const;
|
||||||
|
|
||||||
|
static ::nana::size measure(::nana::paint::graphics&, const ::nana::string&, unsigned allowed_width_in_pixel, bool format_enabled, align h_align, align_v v_align);
|
||||||
|
|
||||||
label& text_align(align horizontal_align, align_v vertical_align= align_v::top);
|
label& text_align(align horizontal_align, align_v vertical_align= align_v::top);
|
||||||
private:
|
private:
|
||||||
//Overrides widget's virtual function
|
//Overrides widget's virtual function
|
||||||
|
|||||||
@ -93,8 +93,8 @@ namespace nana
|
|||||||
void range(double begin, double last, double step);
|
void range(double begin, double last, double step);
|
||||||
|
|
||||||
/// Sets the string spin values.
|
/// Sets the string spin values.
|
||||||
void range(std::initializer_list<std::string> steps_utf8);
|
void range(std::initializer_list<std::string> values_utf8);
|
||||||
void range(std::initializer_list<std::wstring> steps);
|
void range(std::initializer_list<std::wstring> values);
|
||||||
|
|
||||||
/// Gets the spined value
|
/// Gets the spined value
|
||||||
::nana::string value() const;
|
::nana::string value() const;
|
||||||
@ -102,22 +102,9 @@ namespace nana
|
|||||||
int to_int() const;
|
int to_int() const;
|
||||||
double to_double() const;
|
double to_double() const;
|
||||||
|
|
||||||
/// Sets a predicator that determines whether accepts the current user input.
|
/// Sets the modifiers
|
||||||
/// @param pred Predicator to determines the input.
|
void modifier(std::wstring prefix, std::wstring suffix);
|
||||||
void set_accept(std::function<bool(::nana::char_t)> pred);
|
void modifier(const std::string & prefix_utf8, const std::string& suffix_utf8);
|
||||||
|
|
||||||
/// Sets the spinbox that only accepts integer input.
|
|
||||||
void set_accept_integer();
|
|
||||||
|
|
||||||
/// Sets the spinbox that only accepts real number input.
|
|
||||||
void set_accept_real();
|
|
||||||
|
|
||||||
/// Removes the accept excluding predicate accept.
|
|
||||||
void remove_accept();
|
|
||||||
|
|
||||||
/// Sets the qualifications
|
|
||||||
void qualify(std::wstring prefix, std::wstring suffix);
|
|
||||||
void qualify(const std::string & prefix_utf8, const std::string& suffix_utf8);
|
|
||||||
private:
|
private:
|
||||||
::nana::string _m_caption() const;
|
::nana::string _m_caption() const;
|
||||||
void _m_caption(::nana::string&&);
|
void _m_caption(::nana::string&&);
|
||||||
|
|||||||
@ -321,7 +321,7 @@ namespace detail
|
|||||||
//Thread-Safe Required!
|
//Thread-Safe Required!
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
if (impl_->wd_register.available(parent) == false)
|
if (impl_->wd_register.available(parent) == false)
|
||||||
return nullptr;
|
throw std::invalid_argument("invalid parent/owner handle");
|
||||||
|
|
||||||
core_window_t * wd;
|
core_window_t * wd;
|
||||||
if(is_lite)
|
if(is_lite)
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
#include <nana/gui/place.hpp>
|
#include <nana/gui/place.hpp>
|
||||||
#include <nana/datetime.hpp>
|
#include <nana/datetime.hpp>
|
||||||
#include <nana/internationalization.hpp>
|
#include <nana/internationalization.hpp>
|
||||||
|
#include <functional>
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#elif defined(NANA_X11)
|
#elif defined(NANA_X11)
|
||||||
@ -473,7 +474,7 @@ namespace nana
|
|||||||
: public ::nana::form
|
: public ::nana::form
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inputbox_window(window owner, const ::nana::string & desc, const ::nana::string& title, std::size_t contents, unsigned fixed_pixels)
|
inputbox_window(window owner, const ::nana::string & desc, const ::nana::string& title, std::size_t contents, unsigned fixed_pixels, const std::vector<unsigned>& each_height)
|
||||||
: form(owner, API::make_center(owner, 500, 300), appear::decorate<>())
|
: form(owner, API::make_center(owner, 500, 300), appear::decorate<>())
|
||||||
{
|
{
|
||||||
desc_.create(*this);
|
desc_.create(*this);
|
||||||
@ -483,6 +484,10 @@ namespace nana
|
|||||||
btn_ok_.create(*this);
|
btn_ok_.create(*this);
|
||||||
btn_ok_.i18n(i18n_eval("OK"));
|
btn_ok_.i18n(i18n_eval("OK"));
|
||||||
btn_ok_.events().click.connect_unignorable([this]{
|
btn_ok_.events().click.connect_unignorable([this]{
|
||||||
|
|
||||||
|
if (verifier_ && !verifier_(handle()))
|
||||||
|
return;
|
||||||
|
|
||||||
close();
|
close();
|
||||||
valid_input_ = true;
|
valid_input_ = true;
|
||||||
});
|
});
|
||||||
@ -500,8 +505,15 @@ namespace nana
|
|||||||
ss << "margin=10 vert <desc weight=" << desc_extent.height << "><vert margin=[10]";
|
ss << "margin=10 vert <desc weight=" << desc_extent.height << "><vert margin=[10]";
|
||||||
|
|
||||||
for (std::size_t i = 0; i < contents; ++i)
|
for (std::size_t i = 0; i < contents; ++i)
|
||||||
ss << "<weight=27 margin=[3] input_"<<i<<">";
|
{
|
||||||
height += 28 * contents;
|
unsigned px = 27;
|
||||||
|
if (each_height[i] > 27)
|
||||||
|
px = each_height[i];
|
||||||
|
|
||||||
|
ss << "<weight="<<px<<" margin=[3] input_" << i << ">";
|
||||||
|
|
||||||
|
height += px + 1;
|
||||||
|
}
|
||||||
|
|
||||||
ss << "><margin=[15] weight=38<><buttons arrange=80 gap=10 weight=170>>";
|
ss << "><margin=[15] weight=38<><buttons arrange=80 gap=10 weight=170>>";
|
||||||
|
|
||||||
@ -520,8 +532,10 @@ namespace nana
|
|||||||
caption(title);
|
caption(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_input(const std::vector<window>& inputs)
|
void set_input(const std::vector<window>& inputs, std::function<bool(window)> verifier)
|
||||||
{
|
{
|
||||||
|
verifier_ = std::move(verifier);
|
||||||
|
|
||||||
std::size_t index = 0;
|
std::size_t index = 0;
|
||||||
for (auto wd : inputs)
|
for (auto wd : inputs)
|
||||||
{
|
{
|
||||||
@ -543,6 +557,7 @@ namespace nana
|
|||||||
::nana::button btn_cancel_;
|
::nana::button btn_cancel_;
|
||||||
bool valid_input_{ false };
|
bool valid_input_{ false };
|
||||||
::nana::place place_;
|
::nana::place place_;
|
||||||
|
std::function<bool(window)> verifier_;
|
||||||
};
|
};
|
||||||
|
|
||||||
//class integer
|
//class integer
|
||||||
@ -603,7 +618,7 @@ namespace nana
|
|||||||
|
|
||||||
impl->spinbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
|
impl->spinbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
|
||||||
impl->spinbox.range(impl->begin, impl->last, impl->step);
|
impl->spinbox.range(impl->begin, impl->last, impl->step);
|
||||||
impl->spinbox.set_accept_integer();
|
//impl->spinbox.set_accept_integer(); //deprecated
|
||||||
|
|
||||||
//Workaround for no implementation of std::to_wstring by MinGW.
|
//Workaround for no implementation of std::to_wstring by MinGW.
|
||||||
ss.str(L"");
|
ss.str(L"");
|
||||||
@ -613,8 +628,8 @@ namespace nana
|
|||||||
|
|
||||||
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg)
|
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg)
|
||||||
{
|
{
|
||||||
impl->label.size({ label_px, arg.height });
|
impl->label.size({ label_px, 24 });
|
||||||
impl->spinbox.size({ value_px, arg.height });
|
impl->spinbox.size({ value_px, 24 });
|
||||||
});
|
});
|
||||||
|
|
||||||
impl->spinbox.events().destroy.connect_unignorable([impl]
|
impl->spinbox.events().destroy.connect_unignorable([impl]
|
||||||
@ -690,7 +705,7 @@ namespace nana
|
|||||||
|
|
||||||
impl->spinbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
|
impl->spinbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
|
||||||
impl->spinbox.range(impl->begin, impl->last, impl->step);
|
impl->spinbox.range(impl->begin, impl->last, impl->step);
|
||||||
impl->spinbox.set_accept_real();
|
//impl->spinbox.set_accept_real(); //deprecated
|
||||||
|
|
||||||
//Workaround for no implementation of std::to_wstring by MinGW.
|
//Workaround for no implementation of std::to_wstring by MinGW.
|
||||||
ss.str(L"");
|
ss.str(L"");
|
||||||
@ -700,8 +715,8 @@ namespace nana
|
|||||||
|
|
||||||
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg)
|
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg)
|
||||||
{
|
{
|
||||||
impl->label.size({ label_px, arg.height });
|
impl->label.size({ label_px, 24 });
|
||||||
impl->spinbox.size({ value_px, arg.height });
|
impl->spinbox.size({ value_px, 24 });
|
||||||
});
|
});
|
||||||
|
|
||||||
impl->spinbox.events().destroy.connect_unignorable([impl]
|
impl->spinbox.events().destroy.connect_unignorable([impl]
|
||||||
@ -790,15 +805,17 @@ namespace nana
|
|||||||
|
|
||||||
for (auto & s : impl->options)
|
for (auto & s : impl->options)
|
||||||
impl->combox.push_back(s);
|
impl->combox.push_back(s);
|
||||||
|
|
||||||
|
impl->combox.option(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg)
|
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg)
|
||||||
{
|
{
|
||||||
impl->label.size({ label_px, arg.height });
|
impl->label.size({ label_px, arg.height });
|
||||||
if (value_px)
|
if (value_px)
|
||||||
impl->combox.size({ value_px, arg.height });
|
impl->combox.size({ value_px, 24 });
|
||||||
else
|
else
|
||||||
impl->textbox.size({arg.width - label_px - 10, arg.height});
|
impl->textbox.size({arg.width - label_px - 10, 24});
|
||||||
});
|
});
|
||||||
|
|
||||||
auto & wdg = (value_px ? static_cast<widget&>(impl->combox) : static_cast<widget&>(impl->textbox));
|
auto & wdg = (value_px ? static_cast<widget&>(impl->combox) : static_cast<widget&>(impl->textbox));
|
||||||
@ -890,12 +907,12 @@ namespace nana
|
|||||||
left += 104;
|
left += 104;
|
||||||
impl->wdg_day.create(impl->dock, rectangle{ left, 0, 38, 0 });
|
impl->wdg_day.create(impl->dock, rectangle{ left, 0, 38, 0 });
|
||||||
impl->wdg_day.range(1, ::nana::date::month_days(today.year, today.month), 1);
|
impl->wdg_day.range(1, ::nana::date::month_days(today.year, today.month), 1);
|
||||||
impl->wdg_day.set_accept_integer();
|
//impl->wdg_day.set_accept_integer(); //deprecated
|
||||||
|
|
||||||
left += 48;
|
left += 48;
|
||||||
impl->wdg_year.create(impl->dock, rectangle{left, 0, 50, 0});
|
impl->wdg_year.create(impl->dock, rectangle{left, 0, 50, 0});
|
||||||
impl->wdg_year.range(1601, 9999, 1);
|
impl->wdg_year.range(1601, 9999, 1);
|
||||||
impl->wdg_year.set_accept_integer();
|
//impl->wdg_year.set_accept_integer(); //deprecated
|
||||||
|
|
||||||
impl->wdg_month.option(today.month - 1);
|
impl->wdg_month.option(today.month - 1);
|
||||||
|
|
||||||
@ -911,15 +928,15 @@ namespace nana
|
|||||||
{
|
{
|
||||||
impl->label.size({ label_px, arg.height });
|
impl->label.size({ label_px, arg.height });
|
||||||
auto sz = impl->wdg_month.size();
|
auto sz = impl->wdg_month.size();
|
||||||
sz.height = arg.height;
|
sz.height = 24;
|
||||||
impl->wdg_month.size(sz);
|
impl->wdg_month.size(sz);
|
||||||
|
|
||||||
sz = impl->wdg_day.size();
|
sz = impl->wdg_day.size();
|
||||||
sz.height = arg.height;
|
sz.height = 24;
|
||||||
impl->wdg_day.size(sz);
|
impl->wdg_day.size(sz);
|
||||||
|
|
||||||
sz = impl->wdg_year.size();
|
sz = impl->wdg_year.size();
|
||||||
sz.height = arg.height;
|
sz.height = 24;
|
||||||
impl->wdg_year.size(sz);
|
impl->wdg_year.size(sz);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -970,35 +987,40 @@ namespace nana
|
|||||||
title_(std::move(title))
|
title_(std::move(title))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
void inputbox::verify(std::function<bool(window)> verifier)
|
||||||
|
{
|
||||||
|
verifier_ = std::move(verifier);
|
||||||
|
}
|
||||||
|
|
||||||
void inputbox::_m_fetch_args(std::vector<abstract_content*>&)
|
void inputbox::_m_fetch_args(std::vector<abstract_content*>&)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
bool inputbox::_m_open(std::vector<abstract_content*>& contents, bool modal)
|
bool inputbox::_m_open(std::vector<abstract_content*>& contents, bool modal)
|
||||||
{
|
{
|
||||||
|
std::vector<unsigned> each_pixels;
|
||||||
unsigned label_px = 0, fixed_px = 0;
|
unsigned label_px = 0, fixed_px = 0;
|
||||||
paint::graphics graph({ 5, 5 });
|
paint::graphics graph({ 5, 5 });
|
||||||
for (auto p : contents)
|
for (auto p : contents)
|
||||||
{
|
{
|
||||||
auto px = graph.text_extent_size(p->label()).width;
|
auto px = label::measure(graph, p->label(), 150, true, align::right, align_v::center);
|
||||||
if (px > label_px)
|
if (px.width > label_px)
|
||||||
label_px = px;
|
label_px = px.width;
|
||||||
|
|
||||||
px = p->fixed_pixels();
|
px.width = p->fixed_pixels();
|
||||||
if (px > fixed_px)
|
if (px.width > fixed_px)
|
||||||
fixed_px = px;
|
fixed_px = px.width;
|
||||||
|
|
||||||
|
each_pixels.push_back(px.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (label_px > 120)
|
inputbox_window input_wd(owner_, description_, title_, contents.size(), label_px + 10 + fixed_px, each_pixels);
|
||||||
label_px = 120;
|
|
||||||
|
|
||||||
inputbox_window input_wd(owner_, description_, title_, contents.size(), label_px + 10 + fixed_px);
|
|
||||||
|
|
||||||
std::vector<window> inputs;
|
std::vector<window> inputs;
|
||||||
for (auto p : contents)
|
for (auto p : contents)
|
||||||
inputs.push_back(p->create(input_wd, label_px));
|
inputs.push_back(p->create(input_wd, label_px));
|
||||||
|
|
||||||
input_wd.set_input(inputs);
|
input_wd.set_input(inputs, verifier_);
|
||||||
|
|
||||||
if (modal)
|
if (modal)
|
||||||
input_wd.modality();
|
input_wd.modality();
|
||||||
|
|||||||
@ -837,6 +837,14 @@ namespace nana
|
|||||||
return impl->renderer.measure(*graph_ptr, limited, impl->text_align, impl->text_align_v);
|
return impl->renderer.measure(*graph_ptr, limited, impl->text_align, impl->text_align_v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::nana::size label::measure(paint::graphics& graph, const ::nana::string& str, unsigned allowed_width_in_pixel, bool format_enabled, align h_align, align_v v_align)
|
||||||
|
{
|
||||||
|
drawerbase::label::renderer rd;
|
||||||
|
rd.format(format_enabled);
|
||||||
|
rd.parse(str);
|
||||||
|
return rd.measure(graph, allowed_width_in_pixel, h_align, v_align);
|
||||||
|
}
|
||||||
|
|
||||||
label& label::text_align(align th, align_v tv)
|
label& label::text_align(align th, align_v tv)
|
||||||
{
|
{
|
||||||
internal_scope_guard isg;
|
internal_scope_guard isg;
|
||||||
|
|||||||
@ -53,7 +53,11 @@ namespace nana
|
|||||||
virtual ~range_interface() = default;
|
virtual ~range_interface() = default;
|
||||||
|
|
||||||
virtual std::wstring value() const = 0;
|
virtual std::wstring value() const = 0;
|
||||||
virtual bool value(const std::wstring&) = 0;
|
|
||||||
|
//sets a new value, the diff indicates whether the new value is different from the current value.
|
||||||
|
//returns true if the new value is acceptable.
|
||||||
|
virtual bool value(const std::wstring& new_value, bool& diff) = 0;
|
||||||
|
|
||||||
virtual bool check_value(const std::wstring&) const = 0;
|
virtual bool check_value(const std::wstring&) const = 0;
|
||||||
virtual void spin(bool increase) = 0;
|
virtual void spin(bool increase) = 0;
|
||||||
};
|
};
|
||||||
@ -74,29 +78,57 @@ namespace nana
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool value(const std::wstring& value_str) override
|
bool value(const std::wstring& value_str, bool & diff) override
|
||||||
{
|
{
|
||||||
std::wstringstream ss;
|
std::wstringstream ss;
|
||||||
ss << value_str;
|
ss << value_str;
|
||||||
|
|
||||||
T v;
|
T v;
|
||||||
ss >> v;
|
ss >> v;
|
||||||
if (begin_ <= v && v <= last_)
|
if (v < begin_ || last_ < v)
|
||||||
{
|
return false;
|
||||||
value_ = v;
|
|
||||||
return true;
|
diff = (value_ != v);
|
||||||
}
|
value_ = v;
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_value(const std::wstring& value_str) const override
|
bool check_value(const std::wstring& str) const override
|
||||||
{
|
{
|
||||||
std::wstringstream ss;
|
if (str.empty())
|
||||||
ss << value_str;
|
return true;
|
||||||
|
|
||||||
T v;
|
auto size = str.size();
|
||||||
ss >> v;
|
std::size_t pos = 0;
|
||||||
return (begin_ <= v && v <= last_);
|
if (str[0] == '+' || str[0] == '-')
|
||||||
|
pos = 1;
|
||||||
|
|
||||||
|
if (std::is_same<T, int>::value)
|
||||||
|
{
|
||||||
|
for (; pos < size; ++pos)
|
||||||
|
{
|
||||||
|
auto ch = str[pos];
|
||||||
|
if (ch < '0' || '9' < ch)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool dot = false;
|
||||||
|
for (; pos < size; ++pos)
|
||||||
|
{
|
||||||
|
auto ch = str[pos];
|
||||||
|
if (('.' == ch) && (!dot))
|
||||||
|
{
|
||||||
|
dot = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch < '0' || '9' < ch)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void spin(bool increase) override
|
void spin(bool increase) override
|
||||||
@ -145,11 +177,12 @@ namespace nana
|
|||||||
return texts_[pos_];
|
return texts_[pos_];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool value(const std::wstring& value_str) override
|
bool value(const std::wstring& value_str, bool & diff) override
|
||||||
{
|
{
|
||||||
auto i = std::find(texts_.cbegin(), texts_.cend(), value_str);
|
auto i = std::find(texts_.cbegin(), texts_.cend(), value_str);
|
||||||
if (i != texts_.cend())
|
if (i != texts_.cend())
|
||||||
{
|
{
|
||||||
|
diff = (*i == value_str);
|
||||||
pos_ = i - texts_.cbegin();
|
pos_ = i - texts_.cbegin();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -158,12 +191,15 @@ namespace nana
|
|||||||
|
|
||||||
bool check_value(const std::wstring& str) const override
|
bool check_value(const std::wstring& str) const override
|
||||||
{
|
{
|
||||||
for (auto & s : texts_)
|
if (str.empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto i = std::find_if(texts_.cbegin(), texts_.cend(), [&str](const std::wstring& value)
|
||||||
{
|
{
|
||||||
if (s.find(str) != s.npos)
|
return (value.find(str) != value.npos);
|
||||||
return true;
|
});
|
||||||
}
|
|
||||||
return false;
|
return (i != texts_.cend());
|
||||||
}
|
}
|
||||||
|
|
||||||
void spin(bool increase) override
|
void spin(bool increase) override
|
||||||
@ -198,7 +234,7 @@ namespace nana
|
|||||||
timer_.elapse([this]
|
timer_.elapse([this]
|
||||||
{
|
{
|
||||||
range_->spin(buttons::increase == spin_stated_);
|
range_->spin(buttons::increase == spin_stated_);
|
||||||
_m_text();
|
reset_text();
|
||||||
API::update_window(editor_->window_handle());
|
API::update_window(editor_->window_handle());
|
||||||
|
|
||||||
auto intv = timer_.interval();
|
auto intv = timer_.interval();
|
||||||
@ -219,7 +255,15 @@ namespace nana
|
|||||||
editor_->set_accept([this](::nana::char_t ch)
|
editor_->set_accept([this](::nana::char_t ch)
|
||||||
{
|
{
|
||||||
auto str = editor_->text();
|
auto str = editor_->text();
|
||||||
str += ch;
|
auto pos = editor_->caret().x;
|
||||||
|
if (ch == '\b')
|
||||||
|
{
|
||||||
|
if (pos > 0)
|
||||||
|
str.erase(pos - 1, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
str.insert(pos, 1, ch);
|
||||||
|
|
||||||
return range_->check_value(str);
|
return range_->check_value(str);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -229,7 +273,7 @@ namespace nana
|
|||||||
if (!range_)
|
if (!range_)
|
||||||
range_.reset(new range_numeric<int>(0, 100, 1));
|
range_.reset(new range_numeric<int>(0, 100, 1));
|
||||||
|
|
||||||
_m_text();
|
reset_text();
|
||||||
|
|
||||||
API::tabstop(wd);
|
API::tabstop(wd);
|
||||||
API::eat_tabstop(wd, true);
|
API::eat_tabstop(wd, true);
|
||||||
@ -251,10 +295,12 @@ namespace nana
|
|||||||
|
|
||||||
bool value(const ::nana::string& value_str)
|
bool value(const ::nana::string& value_str)
|
||||||
{
|
{
|
||||||
if (!range_->value(value_str))
|
bool diff;
|
||||||
|
if (!range_->value(value_str, diff))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_m_text();
|
if (diff)
|
||||||
|
reset_text();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,17 +308,17 @@ namespace nana
|
|||||||
{
|
{
|
||||||
range_.swap(ptr);
|
range_.swap(ptr);
|
||||||
|
|
||||||
_m_text();
|
reset_text();
|
||||||
}
|
}
|
||||||
|
|
||||||
void qualify(std::wstring&& prefix, std::wstring&& suffix)
|
void modifier(std::wstring&& prefix, std::wstring&& suffix)
|
||||||
{
|
{
|
||||||
surround_.prefix = std::move(prefix);
|
modifier_.prefix = std::move(prefix);
|
||||||
surround_.suffix = std::move(suffix);
|
modifier_.suffix = std::move(suffix);
|
||||||
|
|
||||||
if (editor_)
|
if (editor_)
|
||||||
{
|
{
|
||||||
_m_text();
|
reset_text();
|
||||||
API::update_window(editor_->window_handle());
|
API::update_window(editor_->window_handle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,7 +342,7 @@ namespace nana
|
|||||||
void mouse_wheel(bool upwards)
|
void mouse_wheel(bool upwards)
|
||||||
{
|
{
|
||||||
range_->spin(!upwards);
|
range_->spin(!upwards);
|
||||||
_m_text();
|
reset_text();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mouse_button(const ::nana::arg_mouse& arg, bool pressed)
|
bool mouse_button(const ::nana::arg_mouse& arg, bool pressed)
|
||||||
@ -315,10 +361,11 @@ namespace nana
|
|||||||
{
|
{
|
||||||
API::capture_window(editor_->window_handle(), true);
|
API::capture_window(editor_->window_handle(), true);
|
||||||
range_->spin(buttons::increase == spin_stated_);
|
range_->spin(buttons::increase == spin_stated_);
|
||||||
_m_text();
|
reset_text();
|
||||||
timer_.start();
|
timer_.start();
|
||||||
}
|
}
|
||||||
_m_draw_spins(spin_stated_);
|
else
|
||||||
|
_m_draw_spins(spin_stated_);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,16 +416,20 @@ namespace nana
|
|||||||
else
|
else
|
||||||
editor_->text_area({ 2, 2, graph_->width() - spins_r.width - 2, spins_r.height - 2 });
|
editor_->text_area({ 2, 2, graph_->width() - spins_r.width - 2, spins_r.height - 2 });
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
void _m_text()
|
void reset_text()
|
||||||
{
|
{
|
||||||
if (editor_)
|
if (!editor_)
|
||||||
{
|
return;
|
||||||
std::wstring text = surround_.prefix + range_->value() + surround_.suffix;
|
|
||||||
editor_->text(std::move(text));
|
if (API::is_focus_window(editor_->window_handle()))
|
||||||
_m_draw_spins(spin_stated_);
|
editor_->text(range_->value());
|
||||||
}
|
else
|
||||||
|
editor_->text(modifier_.prefix + range_->value() + modifier_.suffix);
|
||||||
|
|
||||||
|
_m_draw_spins(spin_stated_);
|
||||||
}
|
}
|
||||||
|
private:
|
||||||
|
|
||||||
::nana::rectangle _m_spins_area() const
|
::nana::rectangle _m_spins_area() const
|
||||||
{
|
{
|
||||||
@ -436,11 +487,11 @@ namespace nana
|
|||||||
std::unique_ptr<range_interface> range_;
|
std::unique_ptr<range_interface> range_;
|
||||||
::nana::timer timer_;
|
::nana::timer timer_;
|
||||||
|
|
||||||
struct surround_data
|
struct modifiers
|
||||||
{
|
{
|
||||||
std::wstring prefix;
|
std::wstring prefix;
|
||||||
std::wstring suffix;
|
std::wstring suffix;
|
||||||
}surround_;
|
}modifier_;
|
||||||
};
|
};
|
||||||
|
|
||||||
//class drawer
|
//class drawer
|
||||||
@ -469,8 +520,9 @@ namespace nana
|
|||||||
impl_->render();
|
impl_->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::focus(graph_reference, const arg_focus&)
|
void drawer::focus(graph_reference, const arg_focus& arg)
|
||||||
{
|
{
|
||||||
|
impl_->reset_text();
|
||||||
impl_->render();
|
impl_->render();
|
||||||
impl_->editor()->reset_caret();
|
impl_->editor()->reset_caret();
|
||||||
API::lazy_refresh();
|
API::lazy_refresh();
|
||||||
@ -521,7 +573,9 @@ namespace nana
|
|||||||
{
|
{
|
||||||
if (impl_->editor()->respone_keyboard(arg.key))
|
if (impl_->editor()->respone_keyboard(arg.key))
|
||||||
{
|
{
|
||||||
impl_->draw_spins();
|
if (!impl_->value(impl_->editor()->text()))
|
||||||
|
impl_->draw_spins();
|
||||||
|
|
||||||
API::lazy_refresh();
|
API::lazy_refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -619,46 +673,14 @@ namespace nana
|
|||||||
return ::nana::stod(value());
|
return ::nana::stod(value());
|
||||||
}
|
}
|
||||||
|
|
||||||
void spinbox::set_accept(std::function<bool(::nana::char_t)> pred)
|
void spinbox::modifier(std::wstring prefix, std::wstring suffix)
|
||||||
{
|
{
|
||||||
internal_scope_guard lock;
|
get_drawer_trigger().impl()->modifier(std::move(prefix), std::move(suffix));
|
||||||
auto editor = get_drawer_trigger().impl()->editor();
|
|
||||||
if (editor)
|
|
||||||
editor->set_accept(std::move(pred));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void spinbox::set_accept_integer()
|
void spinbox::modifier(const std::string & prefix_utf8, const std::string& suffix_utf8)
|
||||||
{
|
{
|
||||||
using accepts = ::nana::widgets::skeletons::text_editor::accepts;
|
modifier(static_cast<std::wstring>(::nana::charset(prefix_utf8, ::nana::unicode::utf8)), static_cast<std::wstring>(::nana::charset(suffix_utf8, ::nana::unicode::utf8)));
|
||||||
auto editor = get_drawer_trigger().impl()->editor();
|
|
||||||
if (editor)
|
|
||||||
editor->set_accept(accepts::integer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void spinbox::set_accept_real()
|
|
||||||
{
|
|
||||||
using accepts = ::nana::widgets::skeletons::text_editor::accepts;
|
|
||||||
auto editor = get_drawer_trigger().impl()->editor();
|
|
||||||
if (editor)
|
|
||||||
editor->set_accept(accepts::real);
|
|
||||||
}
|
|
||||||
|
|
||||||
void spinbox::remove_accept()
|
|
||||||
{
|
|
||||||
using accepts = ::nana::widgets::skeletons::text_editor::accepts;
|
|
||||||
auto editor = get_drawer_trigger().impl()->editor();
|
|
||||||
if (editor)
|
|
||||||
editor->set_accept(accepts::no_restrict);
|
|
||||||
}
|
|
||||||
|
|
||||||
void spinbox::qualify(std::wstring prefix, std::wstring suffix)
|
|
||||||
{
|
|
||||||
get_drawer_trigger().impl()->qualify(std::move(prefix), std::move(suffix));
|
|
||||||
}
|
|
||||||
|
|
||||||
void spinbox::qualify(const std::string & prefix_utf8, const std::string& suffix_utf8)
|
|
||||||
{
|
|
||||||
qualify(static_cast<std::wstring>(::nana::charset(prefix_utf8, ::nana::unicode::utf8)), static_cast<std::wstring>(::nana::charset(suffix_utf8, ::nana::unicode::utf8)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::nana::string spinbox::_m_caption() const
|
::nana::string spinbox::_m_caption() const
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user