Improve spinbox

This commit is contained in:
cnjinhao
2015-01-23 03:27:21 +08:00
parent 4ff3a6afd5
commit 02b77d2a26
9 changed files with 200 additions and 66 deletions

View File

@@ -1,7 +1,7 @@
/*
* A Combox Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -61,13 +61,13 @@ namespace nana
using graph_reference = paint::graphics&;
using widget_reference = widget&;
enum class where_t{unknown, text, push_button};
enum class parts{none, text, push_button};
drawer_impl()
{
state_.focused = false;
state_.button_state = element_state::normal;
state_.pointer_where = where_t::unknown;
state_.pointer_where = parts::none;
state_.lister = nullptr;
}
@@ -105,7 +105,7 @@ namespace nana
API::refresh_window(widget_->handle());
}
where_t get_where() const
parts get_where() const
{
return state_.pointer_where;
}
@@ -174,14 +174,13 @@ namespace nana
bool calc_where(graph_reference graph, int x, int y)
{
auto new_where = where_t::unknown;
auto new_where = parts::none;
if(1 < x && x < static_cast<int>(graph.width()) - 2 && 1 < y && y < static_cast<int>(graph.height()) - 2)
{
if((editor_->attr().editable == false) || (static_cast<int>(graph.width()) - 22 <= x))
new_where = where_t::push_button;
new_where = parts::push_button;
else
new_where = where_t::text;
new_where = parts::text;
}
if(new_where != state_.pointer_where)
@@ -195,7 +194,7 @@ namespace nana
void set_mouse_over(bool mo)
{
state_.button_state = (mo ? element_state::hovered : element_state::normal);
state_.pointer_where = where_t::unknown;
state_.pointer_where = parts::none;
}
void set_mouse_press(bool mp)
@@ -459,7 +458,7 @@ namespace nana
auto estate = state_.button_state;
if (enabled && !items_.empty())
{
if (has_lister() || (element_state::pressed == estate && state_.pointer_where == where_t::push_button))
if (has_lister() || (element_state::pressed == estate && state_.pointer_where == parts::push_button))
estate = element_state::pressed;
}
else
@@ -521,21 +520,21 @@ namespace nana
img.stretch(img.size(), *graph_, nana::rectangle(pos, imgsz));
}
private:
std::vector<std::shared_ptr<item> > items_;
std::vector<std::shared_ptr<item>> items_;
nana::float_listbox::module_type module_;
::nana::combox * widget_ = nullptr;
nana::paint::graphics * graph_ = nullptr;
drawerbase::float_listbox::item_renderer* item_renderer_ = nullptr;
::nana::combox * widget_{ nullptr };
nana::paint::graphics * graph_{ nullptr };
drawerbase::float_listbox::item_renderer* item_renderer_{ nullptr };
bool image_enabled_ = false;
unsigned image_pixels_ = 16;
widgets::skeletons::text_editor * editor_ = nullptr;
bool image_enabled_{ false };
unsigned image_pixels_{ 16 };
widgets::skeletons::text_editor * editor_{ nullptr };
struct state_type
{
bool focused;
element_state button_state;
where_t pointer_where;
parts pointer_where;
nana::float_listbox * lister;
std::size_t item_index_before_selection;
@@ -553,11 +552,6 @@ namespace nana
delete drawer_;
}
void trigger::set_accept(std::function<bool(nana::char_t)>&& pred)
{
pred_acceptive_ = std::move(pred);
}
drawer_impl& trigger::get_drawer_impl()
{
return *drawer_;
@@ -626,7 +620,7 @@ namespace nana
{
auto * editor = drawer_->editor();
if(false == editor->mouse_down(arg.left_button, arg.pos))
if(drawer_impl::where_t::push_button == drawer_->get_where())
if(drawer_impl::parts::push_button == drawer_->get_where())
drawer_->open_lister();
drawer_->draw();
@@ -716,8 +710,7 @@ namespace nana
void trigger::key_char(graph_reference graph, const arg_keyboard& arg)
{
bool enterable = drawer_->widget_ptr()->enabled() && (!pred_acceptive_ || pred_acceptive_(arg.key));
if (drawer_->editor()->respone_keyboard(arg.key, enterable))
if (drawer_->editor()->respone_keyboard(arg.key))
API::lazy_refresh();
}
//end class trigger
@@ -913,7 +906,9 @@ namespace nana
void combox::set_accept(std::function<bool(nana::char_t)> pred)
{
internal_scope_guard lock;
get_drawer_trigger().set_accept(std::move(pred));
auto editor = get_drawer_trigger().get_drawer_impl().editor();
if(editor)
editor->set_accept(std::move(pred));
}
combox& combox::push_back(nana::string text)

View File

@@ -1,7 +1,7 @@
/*
* A text editor implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -1355,7 +1355,17 @@ namespace nana{ namespace widgets
keywords_->kwbase.erase(i);
}
bool text_editor::respone_keyboard(nana::char_t key, bool enterable) //key is a character of ASCII code
void text_editor::set_accept(std::function<bool(char_type)> pred)
{
attributes_.pred_acceptive = std::move(pred);
}
void text_editor::set_accept(accepts acceptive)
{
attributes_.acceptive = acceptive;
}
bool text_editor::respone_keyboard(char_type key) //key is a character of ASCII code
{
switch (key)
{
@@ -1367,7 +1377,7 @@ namespace nana{ namespace widgets
return true;
}
if (attributes_.editable && enterable)
if (attributes_.editable && API::window_enabled(window_) && (!attributes_.pred_acceptive || attributes_.pred_acceptive(key)))
{
switch (key)
{
@@ -1389,6 +1399,9 @@ namespace nana{ namespace widgets
undo(false);
break;
default:
if (!_m_accepts(key))
return false;
if (key > 0x7F || (32 <= key && key <= 126))
put(key);
else if (sizeof(nana::char_t) == sizeof(char))
@@ -1958,6 +1971,19 @@ namespace nana{ namespace widgets
nana::string text;
nana::system::dataexch().get(text);
//If it is required check the acceptable
if (accepts::no_restrict != attributes_.acceptive)
{
for (auto i = text.begin(); i != text.end(); ++i)
{
if (!_m_accepts(*i))
{
text.erase(i, text.end());
break;
}
}
}
if (!text.empty())
put(std::move(text));
}
@@ -2239,6 +2265,23 @@ namespace nana{ namespace widgets
return false;
}
bool text_editor::_m_accepts(char_type ch) const
{
if (accepts::no_restrict == attributes_.acceptive)
return true;
//Checks the input whether it meets the requirement for a numeric.
auto str = text();
if ('+' == ch || '-' == ch)
return str.empty();
if ((accepts::real == attributes_.acceptive) && ('.' == ch))
return (str.find(L'.') == str.npos);
return ('0' <= ch && ch <= '9');
}
::nana::color text_editor::_m_bgcolor() const
{
return (!API::window_enabled(window_) ? color{ 0xE0, 0xE0, 0xE0 } : API::bgcolor(window_));

View File

@@ -137,7 +137,7 @@ namespace nana
timer_.interval(intv / 2);
});
timer_.interval(1000);
timer_.interval(600);
}
void attach(::nana::widget& wdg, ::nana::paint::graphics& graph)
@@ -185,6 +185,11 @@ namespace nana
}
}
void draw_spins()
{
_m_draw_spins(buttons::none);
}
void render()
{
editor_->render(API::is_focus_window(editor_->window_handle()));
@@ -208,7 +213,7 @@ namespace nana
{
API::capture_window(editor_->window_handle(), false);
timer_.stop();
timer_.interval(1000);
timer_.interval(600);
}
if (buttons::none != spin_stated_)
@@ -409,6 +414,24 @@ namespace nana
API::lazy_refresh();
}
void drawer::key_press(graph_reference, const arg_keyboard& arg)
{
if (impl_->editor()->move(arg.key))
{
impl_->editor()->reset_caret();
impl_->draw_spins();
API::lazy_refresh();
}
}
void drawer::key_char(graph_reference, const arg_keyboard& arg)
{
if (impl_->editor()->respone_keyboard(arg.key))
{
impl_->draw_spins();
API::lazy_refresh();
}
}
}
}//end namespace drawerbase
@@ -425,6 +448,20 @@ namespace nana
this->create(wd, r, visible);
}
void spinbox::editable(bool accept)
{
internal_scope_guard lock;
auto editor = get_drawer_trigger().impl()->editor();
if (editor)
editor->editable(accept);
}
bool spinbox::editable() const
{
auto editor = get_drawer_trigger().impl()->editor();
return (editor ? editor->attr().editable : false);
}
void spinbox::range(int begin, int last, int step)
{
using namespace drawerbase::spinbox;
@@ -453,6 +490,39 @@ namespace nana
API::refresh_window(handle());
}
void spinbox::set_accept(std::function<bool(::nana::char_t)> pred)
{
internal_scope_guard lock;
auto editor = get_drawer_trigger().impl()->editor();
if (editor)
editor->set_accept(std::move(pred));
}
void spinbox::set_accept_integer()
{
using accepts = ::nana::widgets::skeletons::text_editor::accepts;
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));

View File

@@ -1,7 +1,7 @@
/*
* A Textbox Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@@ -45,11 +45,6 @@ namespace nana{ namespace drawerbase {
return editor_;
}
void drawer::set_accept(std::function<bool(nana::char_t)> && fn)
{
pred_acceptive_ = std::move(fn);
}
void drawer::attached(widget_reference wdg, graph_reference graph)
{
auto wd = wdg.handle();
@@ -139,8 +134,7 @@ namespace nana{ namespace drawerbase {
void drawer::key_char(graph_reference, const arg_keyboard& arg)
{
bool enterable = widget_->enabled() && (!pred_acceptive_ || pred_acceptive_(arg.key));
if (editor_->respone_keyboard(arg.key, enterable))
if (editor_->respone_keyboard(arg.key))
API::lazy_refresh();
}
@@ -348,7 +342,9 @@ namespace nana{ namespace drawerbase {
void textbox::set_accept(std::function<bool(nana::char_t)> fn)
{
internal_scope_guard lock;
get_drawer_trigger().set_accept(std::move(fn));
auto editor = get_drawer_trigger().editor();
if(editor)
editor->set_accept(std::move(fn));
}
textbox& textbox::tip_string(nana::string str)