code refine for button and category

This commit is contained in:
Jinhao 2016-01-23 23:27:09 +08:00
parent 818136a18a
commit ccc30265f5
4 changed files with 160 additions and 192 deletions

View File

@ -1,7 +1,7 @@
/** /**
* A Button Implementation * A Button Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at

View File

@ -1,7 +1,7 @@
/** /**
* A Categorize Implementation * A Categorize Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at

View File

@ -1,7 +1,7 @@
/* /*
* A Button Implementation * A Button Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -336,16 +336,14 @@ namespace nana{ namespace drawerbase
void trigger::_m_press(graph_reference graph, bool is_pressed) void trigger::_m_press(graph_reference graph, bool is_pressed)
{ {
bool draw = false;
if (is_pressed) if (is_pressed)
{ {
if (attr_.e_state != element_state::pressed) if (attr_.e_state == element_state::pressed)
{ return;
attr_.e_state = element_state::pressed;
attr_.keep_pressed = true; attr_.e_state = element_state::pressed;
API::capture_window(*wdg_, true); attr_.keep_pressed = true;
draw = true; API::capture_window(*wdg_, true);
}
} }
else else
{ {
@ -354,24 +352,19 @@ namespace nana{ namespace drawerbase
if (attr_.enable_pushed && (false == attr_.pushed)) if (attr_.enable_pushed && (false == attr_.pushed))
{ {
attr_.pushed = true; attr_.pushed = true;
return;
} }
if (element_state::pressed == attr_.e_state)
attr_.e_state = element_state::hovered;
else else
{ attr_.e_state = element_state::normal;
if (element_state::pressed == attr_.e_state)
attr_.e_state = element_state::hovered;
else
attr_.e_state = element_state::normal;
attr_.pushed = false; attr_.pushed = false;
draw = true;
}
} }
if (draw) refresh(graph);
{ API::lazy_refresh();
refresh(graph);
API::lazy_refresh();
}
} }
void trigger::emit_click() void trigger::emit_click()
@ -518,14 +511,12 @@ namespace nana{ namespace drawerbase
{ {
API::unregister_shortkey(handle()); API::unregister_shortkey(handle());
native_string_type ntext = std::move(text);
wchar_t shortkey; wchar_t shortkey;
API::transform_shortkey_text(to_utf8(ntext), shortkey, nullptr); API::transform_shortkey_text(to_utf8(text), shortkey, nullptr);
if (shortkey) if (shortkey)
API::register_shortkey(handle(), shortkey); API::register_shortkey(handle(), shortkey);
base_type::_m_caption(std::move(ntext)); base_type::_m_caption(std::move(text));
} }
//end class button //end class button
}//end namespace nana }//end namespace nana

View File

@ -1,7 +1,7 @@
/* /*
* A Categorize Implementation * A Categorize Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@ -78,7 +78,7 @@ namespace nana
if(ue.what == ue.none || (API::window_enabled(wd) == false)) if(ue.what == ue.none || (API::window_enabled(wd) == false))
{ //the mouse is out of the widget. { //the mouse is out of the widget.
style_.bgcolor = style_.bgcolor.blend(color{ 0xa0, 0xc9, 0xf5 }, 0.9); style_.bgcolor = style_.bgcolor.blend(static_cast<color_rgb>(0xa0c9f5), 0.9);
} }
graph.rectangle(r, true, style_.bgcolor); graph.rectangle(r, true, style_.bgcolor);
} }
@ -90,7 +90,7 @@ namespace nana
if(ui_el_.what == ui_el_.item_root) if(ui_el_.what == ui_el_.item_root)
{ {
_m_item_bground(graph, r.x + 1, r.y, r.width - 2, r.height, (state == mouse_action::pressed ? mouse_action::pressed : mouse_action::over)); _m_item_bground(graph, r.x + 1, r.y, r.width - 2, r.height, (state == mouse_action::pressed ? mouse_action::pressed : mouse_action::over));
graph.rectangle(r, false, color{ 0x3C, 0x7F, 0xB1 }); graph.rectangle(r, false, static_cast<color_rgb>(0x3C7FB1));
if(state == mouse_action::pressed) if(state == mouse_action::pressed)
{ {
++arrow_r.x; ++arrow_r.x;
@ -128,7 +128,7 @@ namespace nana
unsigned width = r.width - 2; unsigned width = r.width - 2;
unsigned height = r.height - 2; unsigned height = r.height - 2;
::nana::color clr{ 0x3C, 0x7F, 0xB1 }; ::nana::color clr{static_cast<color_rgb>(0x3C7FB1)};
if(has_child) if(has_child)
{ {
width -= 16; width -= 16;
@ -192,11 +192,13 @@ namespace nana
int right = x + width - 1; int right = x + width - 1;
graph.palette(false, static_cast<color_rgb>(0x6E8D9F)); graph.palette(false, static_cast<color_rgb>(0x6E8D9F));
graph.line(point{ x, y }, point{right, y}); graph.line(point{ x, y }, point{ right, y });
graph.line(point{ x, y + 1 }, point{ x, bottom }); graph.line(point{ x, y + 1 }, point{ x, bottom });
++x; ++x;
++y; ++y;
graph.palette(false, color(0xa6, 0xc7, 0xd9));
graph.palette(false, static_cast<color_rgb>(0xa6c7d9));
graph.line(point{ x, y }, point{ right, y }); graph.line(point{ x, y }, point{ right, y });
graph.line(point{ x, y + 1 }, point{ x, bottom }); graph.line(point{ x, y + 1 }, point{ x, bottom });
} }
@ -268,18 +270,19 @@ namespace nana
cur_ = tree_.ref(key); cur_ = tree_.ref(key);
} }
node_handle at(std::size_t index) const node_handle at(std::size_t pos) const
{ {
std::vector<node_handle> v; std::vector<node_handle> v;
_m_read_node_path(v); _m_read_node_path(v);
return (index < v.size() ? v[index] : nullptr); return (pos < v.size() ? v[pos] : nullptr);
} }
node_handle tail(std::size_t index) node_handle tail(std::size_t index)
{ {
node_handle i = at(index); auto node = at(index);
if(i) cur_ = i; if(node)
return i; cur_ = node;
return node;
} }
node_handle cur() const node_handle cur() const
@ -287,9 +290,9 @@ namespace nana
return cur_; return cur_;
} }
void cur(node_handle i) void cur(node_handle node)
{ {
cur_ = i; cur_ = node;
} }
void insert(const std::string& name, const nana::any& value) void insert(const std::string& name, const nana::any& value)
@ -304,10 +307,10 @@ namespace nana
{ {
if(cur_) if(cur_)
{ {
item_tag m; auto cur_before_insert = cur_;
m.pixels = 0;
m.value = value; insert(name, value);
tree_.insert(cur_, name, m); cur_ = cur_before_insert;
return true; return true;
} }
return false; return false;
@ -315,18 +318,12 @@ namespace nana
bool childset_erase(const std::string& name) bool childset_erase(const std::string& name)
{ {
if(cur_) auto node = find_child(name);
{ if (!node)
for(node_handle i = cur_->child; i; i = i->next) return false;
{
if(i->value.first == name) tree_.remove(node);
{ return true;
tree_.remove(i);
return true;
}
}
}
return false;
} }
node_handle find_child(const std::string& name) const node_handle find_child(const std::string& name) const
@ -352,11 +349,11 @@ namespace nana
return false; return false;
} }
private: private:
void _m_read_node_path(std::vector<node_handle>& v) const void _m_read_node_path(std::vector<node_handle>& nodes) const
{ {
node_handle root = tree_.get_root(); auto root = tree_.get_root();
for(node_handle i = cur_; i && (i != root); i = i->owner) for(auto i = cur_; i && (i != root); i = i->owner)
v.insert(v.begin(), i); nodes.insert(nodes.begin(), i);
} }
private: private:
container tree_; container tree_;
@ -384,17 +381,15 @@ namespace nana
style_.listbox = nullptr; style_.listbox = nullptr;
} }
void attach(window wd, nana::paint::graphics* graph) void attach(window wd)
{ {
window_ = wd; window_ = wd;
API::bgcolor(wd, colors::white); API::bgcolor(wd, colors::white);
graph_ = graph;
} }
void detach() void detach()
{ {
window_ = nullptr; window_ = nullptr;
graph_ = nullptr;
} }
window window_handle() const window window_handle() const
@ -402,88 +397,81 @@ namespace nana
return window_; return window_;
} }
const container& tree() const
{
return treebase_;
}
container& tree() container& tree()
{ {
return treebase_; return treebase_;
} }
void draw() void draw(graph_reference graph)
{ {
_m_calc_scale(); _m_calc_scale(graph);
nana::rectangle r = _m_make_rectangle(); //_m_make_rectangle must be called after _m_calc_scale() nana::rectangle r = _m_make_rectangle(); //_m_make_rectangle must be called after _m_calc_scale()
_m_calc_pixels(r); _m_calc_pixels(r);
proto_.ui_renderer->background(*graph_, window_, r, ui_el_); proto_.ui_renderer->background(graph, window_, r, ui_el_);
if(head_) if(head_)
proto_.ui_renderer->root_arrow(*graph_, _m_make_root_rectangle(), style_.state); proto_.ui_renderer->root_arrow(graph, _m_make_root_rectangle(), style_.state);
_m_draw_items(r); _m_draw_items(graph, r);
proto_.ui_renderer->border(*graph_); proto_.ui_renderer->border(graph);
} }
bool locate(int x, int y) const bool locate(int x, int y) const
{ {
if(graph_) if(head_)
{ {
if(head_) auto r = _m_make_root_rectangle();
if (r.is_hit(x, y))
{ {
auto r = _m_make_root_rectangle(); style_.active_item_rectangle = r;
if (r.is_hit(x, y)) if(ui_el_.what == ui_el_.item_root)
{ return false;
style_.active_item_rectangle = r; ui_el_.what = ui_el_.item_root;
if(ui_el_.what == ui_el_.item_root) return true;
return false;
ui_el_.what = ui_el_.item_root;
return true;
}
}
nana::rectangle r = _m_make_rectangle();
std::vector<node_handle> seq;
if(r.is_hit(x, y) && treebase_.seq(head_, seq))
{
const int xbase = r.x;
const int xend = static_cast<int>(r.width) + r.x;
//Change the meaning of variable r. Now, r indicates the area of a item
r.height = item_height_;
std::size_t seq_index = 0;
for(auto i : seq)
{
r.width = i->value.second.pixels;
//If the item is over the right border of widget, the item would be painted at
//the begining of the next line.
if(static_cast<int>(r.width) + r.x > xend)
{
r.x = xbase;
r.y += r.height;
}
if(r.is_hit(x, y))
{
style_.active_item_rectangle = r;
std::size_t index = seq_index + head_;
ui_element::t what = ((i->child && (r.x + static_cast<int>(r.width) - 16 < x))
? ui_el_.item_arrow : ui_el_.item_name);
if(what == ui_el_.what && index == ui_el_.index)
return false;
ui_el_.what = what;
ui_el_.index = index;
return true;
}
r.x += r.width;
++seq_index;
}
} }
} }
nana::rectangle r = _m_make_rectangle();
std::vector<node_handle> seq;
if(r.is_hit(x, y) && treebase_.seq(head_, seq))
{
const int xbase = r.x;
const int xend = r.right();
//Change the meaning of variable r. Now, r indicates the area of a item
r.height = item_height_;
std::size_t seq_index = 0;
for(auto i : seq)
{
r.width = i->value.second.pixels;
//If the item is over the right border of widget, the item would be painted at
//the begining of the next line.
if(r.right() > xend)
{
r.x = xbase;
r.y += r.height;
}
if(r.is_hit(x, y))
{
style_.active_item_rectangle = r;
std::size_t index = seq_index + head_;
ui_element::t what = ((i->child && (r.right() - 16 < x))
? ui_el_.item_arrow : ui_el_.item_name);
if(what == ui_el_.what && index == ui_el_.index)
return false;
ui_el_.what = what;
ui_el_.index = index;
return true;
}
r.x += r.width;
++seq_index;
}
}
if(ui_el_.what == ui_el_.somewhere) return false; if(ui_el_.what == ui_el_.somewhere) return false;
ui_el_.what = ui_el_.somewhere; ui_el_.what = ui_el_.somewhere;
return true; return true;
@ -499,7 +487,7 @@ namespace nana
return true; return true;
} }
ui_element locate() const const ui_element& locate() const
{ {
return ui_el_; return ui_el_;
} }
@ -507,15 +495,12 @@ namespace nana
void mouse_pressed() void mouse_pressed()
{ {
style_.state = mouse_action::pressed; style_.state = mouse_action::pressed;
switch(ui_el_.what)
//Check the click whether to show the list
if (ui_element::item_root == ui_el_.what || ui_element::item_arrow == ui_el_.what)
{ {
case ui_element::item_root:
case ui_element::item_arrow:
_m_show_list(); _m_show_list();
style_.mode = mode::floatlist; style_.mode = mode::floatlist;
break;
default: //Don't take care about other elements
break;
} }
} }
@ -582,58 +567,48 @@ namespace nana
} }
r.y += r.height; r.y += r.height;
r.width = r.height = 100; r.width = r.height = 100;
style_.listbox = &(form_loader<nana::float_listbox>()(window_, r, true)); style_.listbox = &(form_loader<nana::float_listbox>()(window_, r, true));
style_.listbox->set_module(style_.module, 16); style_.listbox->set_module(style_.module, 16);
style_.listbox->events().destroy.connect_unignorable([this] style_.listbox->events().destroy.connect_unignorable([this]
{ {
_m_list_closed(); //Close list when listbox is destoryed
}); style_.mode = mode::normal;
} style_.state = mouse_action::normal;
void _m_list_closed() if ((style_.module.index != npos) && style_.module.have_selected)
{
style_.mode = mode::normal;
style_.state = mouse_action::normal;
bool is_draw = false;
if((style_.module.index != npos) && style_.module.have_selected)
{
switch(style_.list_trigger)
{ {
case ui_element::item_arrow: if (ui_element::item_arrow == style_.list_trigger)
{ {
treebase_.tail(style_.active); treebase_.tail(style_.active);
node_handle node = treebase_.find_child(style_.module.items[style_.module.index]->text()); node_handle node = treebase_.find_child(style_.module.items[style_.module.index]->text());
if(node) if (!node)
{ {
treebase_.cur(node); style_.listbox = nullptr;
_m_selected(node); return;
is_draw = true;
} }
treebase_.cur(node);
_m_selected(node);
}
else if (ui_element::item_root != style_.list_trigger)
{
style_.listbox = nullptr;
return;
} }
break;
case ui_element::item_root:
_m_selected(treebase_.tail(style_.module.index)); _m_selected(treebase_.tail(style_.module.index));
is_draw = true;
break;
default: //Don't take care about other elements
break;
} }
}
else
is_draw = true;
if(is_draw) API::refresh_window(window_);
{
draw();
API::update_window(window_); API::update_window(window_);
} style_.listbox = nullptr;
style_.listbox = nullptr; });
} }
private: private:
unsigned _m_item_fix_scale() const unsigned _m_item_fix_scale() const
{ {
return graph_->height() - 2; return (API::window_size(this->window_handle()).height - 2);
} }
nana::rectangle _m_make_root_rectangle() const nana::rectangle _m_make_root_rectangle() const
@ -645,7 +620,8 @@ namespace nana
//@brief: This function calculate the items area. This must be called after _m_calc_scale() //@brief: This function calculate the items area. This must be called after _m_calc_scale()
nana::rectangle _m_make_rectangle() const nana::rectangle _m_make_rectangle() const
{ {
nana::rectangle r(1, 1, graph_->width() - 2, _m_item_fix_scale()); auto dimension = API::window_size(this->window_handle());
nana::rectangle r(1, 1, dimension.width - 2, _m_item_fix_scale());
unsigned px = r.width; unsigned px = r.width;
std::size_t lines = item_lines_; std::size_t lines = item_lines_;
@ -679,7 +655,7 @@ namespace nana
return r; return r;
} }
void _m_calc_scale() void _m_calc_scale(graph_reference graph)
{ {
nana::size tsz; nana::size tsz;
unsigned highest = 0; unsigned highest = 0;
@ -687,7 +663,7 @@ namespace nana
treebase_.seq(0, v); treebase_.seq(0, v);
for(auto node : v) for(auto node : v)
{ {
node->value.second.scale = graph_->text_extent_size(node->value.first); node->value.second.scale = graph.text_extent_size(node->value.first);
if(highest < node->value.second.scale.height) if(highest < node->value.second.scale.height)
highest = node->value.second.scale.height; highest = node->value.second.scale.height;
@ -697,10 +673,12 @@ namespace nana
highest += 6; //the default height of item. highest += 6; //the default height of item.
item_lines_ = (graph_->height() - 2) / highest; auto fixed_scale_px = _m_item_fix_scale();
item_lines_ = fixed_scale_px / highest;
if(item_lines_ == 0) if(item_lines_ == 0)
item_lines_ = 1; item_lines_ = 1;
item_height_ = (1 != item_lines_ ? highest : _m_item_fix_scale()); item_height_ = (1 != item_lines_ ? highest : fixed_scale_px);
} }
void _m_calc_pixels(const nana::rectangle& r) void _m_calc_pixels(const nana::rectangle& r)
@ -739,12 +717,12 @@ namespace nana
} }
} }
unsigned _m_minimial_pixels() static unsigned _m_minimial_pixels()
{ {
return 46; return 46;
} }
void _m_draw_items(const nana::rectangle& r) void _m_draw_items(graph_reference graph, const nana::rectangle& r)
{ {
nana::rectangle item_r = r; nana::rectangle item_r = r;
item_r.height = item_height_; item_r.height = item_height_;
@ -761,13 +739,12 @@ namespace nana
item_r.y += item_height_; item_r.y += item_height_;
} }
item_r.width = i->value.second.pixels; item_r.width = i->value.second.pixels;
proto_.ui_renderer->item(*graph_, item_r, index++, i->value.first, i->value.second.scale.height, i->child != 0, style_.state); proto_.ui_renderer->item(graph, item_r, index++, i->value.first, i->value.second.scale.height, i->child != 0, style_.state);
item_r.x += item_r.width; item_r.x += item_r.width;
} }
} }
private: private:
window window_{nullptr}; window window_{nullptr};
nana::paint::graphics * graph_{nullptr};
std::size_t head_; std::size_t head_;
unsigned item_height_; unsigned item_height_;
std::size_t item_lines_; std::size_t item_lines_;
@ -808,14 +785,14 @@ namespace nana
throw_not_utf8(str); throw_not_utf8(str);
scheme_->tree().insert(str, value); scheme_->tree().insert(str, value);
API::dev::window_caption(scheme_->window_handle(), to_nstring(scheme_->tree().path())); API::dev::window_caption(scheme_->window_handle(), to_nstring(scheme_->tree().path()));
scheme_->draw(); API::refresh_window(this->scheme_->window_handle());
} }
bool trigger::childset(const std::string& str, nana::any value) bool trigger::childset(const std::string& str, nana::any value)
{ {
if(scheme_->tree().childset(str, value)) if(scheme_->tree().childset(str, value))
{ {
scheme_->draw(); API::refresh_window(this->scheme_->window_handle());
return true; return true;
} }
return false; return false;
@ -825,7 +802,7 @@ namespace nana
{ {
if(scheme_->tree().childset_erase(str)) if(scheme_->tree().childset_erase(str))
{ {
scheme_->draw(); API::refresh_window(this->scheme_->window_handle());
return true; return true;
} }
return false; return false;
@ -835,7 +812,7 @@ namespace nana
{ {
if(scheme_->tree().clear()) if(scheme_->tree().clear())
{ {
scheme_->draw(); API::refresh_window(this->scheme_->window_handle());
return true; return true;
} }
return false; return false;
@ -867,7 +844,7 @@ namespace nana
if(node) if(node)
return node->value.second.value; return node->value.second.value;
throw std::runtime_error("Nana.GUI.categorize::value(), current category is empty"); throw std::runtime_error("nana::categorize::value, current category is empty");
} }
void trigger::_m_event_agent_ready() const void trigger::_m_event_agent_ready() const
@ -878,9 +855,9 @@ namespace nana
}; };
} }
void trigger::attached(widget_reference widget, graph_reference graph) void trigger::attached(widget_reference widget, graph_reference)
{ {
scheme_->attach(widget, &graph); scheme_->attach(widget);
} }
void trigger::detached() void trigger::detached()
@ -888,51 +865,51 @@ namespace nana
scheme_->detach(); scheme_->detach();
} }
void trigger::refresh(graph_reference) void trigger::refresh(graph_reference graph)
{ {
scheme_->draw(); scheme_->draw(graph);
} }
void trigger::mouse_down(graph_reference, const arg_mouse&) void trigger::mouse_down(graph_reference graph, const arg_mouse&)
{ {
if(scheme_->locate().what > ui_element::somewhere) if(scheme_->locate().what > ui_element::somewhere)
{ {
if(API::window_enabled(scheme_->window_handle())) if(API::window_enabled(scheme_->window_handle()))
{ {
scheme_->mouse_pressed(); scheme_->mouse_pressed();
scheme_->draw(); scheme_->draw(graph);
API::lazy_refresh(); API::lazy_refresh();
} }
} }
} }
void trigger::mouse_up(graph_reference, const arg_mouse&) void trigger::mouse_up(graph_reference graph, const arg_mouse&)
{ {
if(scheme_->locate().what > ui_element::somewhere) if(scheme_->locate().what > ui_element::somewhere)
{ {
if(API::window_enabled(scheme_->window_handle())) if(API::window_enabled(scheme_->window_handle()))
{ {
scheme_->mouse_release(); scheme_->mouse_release();
scheme_->draw(); scheme_->draw(graph);
API::lazy_refresh(); API::lazy_refresh();
} }
} }
} }
void trigger::mouse_move(graph_reference, const arg_mouse& arg) void trigger::mouse_move(graph_reference graph, const arg_mouse& arg)
{ {
if(scheme_->locate(arg.pos.x, arg.pos.y) && API::window_enabled(scheme_->window_handle())) if(scheme_->locate(arg.pos.x, arg.pos.y) && API::window_enabled(scheme_->window_handle()))
{ {
scheme_->draw(); scheme_->draw(graph);
API::lazy_refresh(); API::lazy_refresh();
} }
} }
void trigger::mouse_leave(graph_reference, const arg_mouse&) void trigger::mouse_leave(graph_reference graph, const arg_mouse&)
{ {
if(API::window_enabled(scheme_->window_handle()) && (scheme_->is_list_shown() == false) && scheme_->erase_locate()) if(API::window_enabled(scheme_->window_handle()) && (scheme_->is_list_shown() == false) && scheme_->erase_locate())
{ {
scheme_->draw(); scheme_->draw(graph);
API::lazy_refresh(); API::lazy_refresh();
} }
} }