add new features to listbox
a method to enable/disable the number of items methods about expanding category methods about category icons
This commit is contained in:
@@ -1052,6 +1052,19 @@ namespace nana
|
||||
cat_proxy & select(bool);
|
||||
bool selected() const;
|
||||
|
||||
/// Enables/disables the number of items in the category to be displayed behind the category title
|
||||
cat_proxy& display_number(bool display);
|
||||
|
||||
/// Determines whether the category is expanded.
|
||||
bool expanded() const;
|
||||
|
||||
/// Expands/collapses the category
|
||||
/**
|
||||
* @param expand Indicates whether to expand or collapse the category. If this parameter is true, it expands the category. If the parameter is false, it collapses the category.
|
||||
* @return the reference of *this.
|
||||
*/
|
||||
cat_proxy& expanded(bool expand);
|
||||
|
||||
/// Behavior of a container
|
||||
void push_back(std::string text_utf8);
|
||||
|
||||
@@ -1484,6 +1497,22 @@ the nana::detail::basic_window member pointer scheme
|
||||
void enable_single(bool for_selection, bool category_limited);
|
||||
void disable_single(bool for_selection);
|
||||
export_options& def_export_options();
|
||||
|
||||
|
||||
/// Sets a renderer for category icon
|
||||
/**
|
||||
* @param icon_renderer The renderer of category icon
|
||||
* @return the reference of *this.
|
||||
*/
|
||||
listbox& category_icon(std::function<void(paint::graphics& graph, const rectangle& rt_icon, bool expanded)> icon_renderer);
|
||||
|
||||
/// Sets category icons
|
||||
/**
|
||||
* @param img_expanded An icon displayed in front of category title when the category is expanded.
|
||||
* @param img_collapsed An icon displayed in front of category title when the category is collapsed.
|
||||
* @return the reference of *this.
|
||||
*/
|
||||
listbox& category_icon(const paint::image& img_expanded, const paint::image&& img_collapsed);
|
||||
private:
|
||||
drawerbase::listbox::essence & _m_ess() const;
|
||||
nana::any* _m_anyobj(size_type cat, size_type index, bool allocate_if_empty) const override;
|
||||
|
||||
@@ -659,7 +659,8 @@ namespace nana
|
||||
|
||||
std::unique_ptr<model_interface> model_ptr;
|
||||
|
||||
bool expand{true};
|
||||
bool expand{ true };
|
||||
bool display_number{ true };
|
||||
|
||||
//A cat may have a key object to identify the category
|
||||
std::shared_ptr<nana::detail::key_interface> key_ptr;
|
||||
@@ -1938,6 +1939,8 @@ namespace nana
|
||||
|
||||
std::unique_ptr<widgets::skeletons::content_view> content_view;
|
||||
|
||||
std::function<void(paint::graphics&, const rectangle&, bool)> ctg_icon_renderer; ///< Renderer for the category icon
|
||||
|
||||
struct mouse_selection_part
|
||||
{
|
||||
bool started{ false };
|
||||
@@ -3544,27 +3547,36 @@ namespace nana
|
||||
|
||||
color txt_color{ static_cast<color_rgb>(0x3399) };
|
||||
|
||||
facade<element::arrow> arrow("double");
|
||||
arrow.direction(categ.expand ? ::nana::direction::north : ::nana::direction::south);
|
||||
arrow.draw( *graph, {}, txt_color,
|
||||
{ x + 5, y + static_cast<int>(item_height - 16) / 2, 16, 16 },
|
||||
element_state::normal);
|
||||
//Area of category icon
|
||||
rectangle rt_ctg_icon{ x + 5, y + static_cast<int>(item_height - 16) / 2, 16, 16 };
|
||||
|
||||
if (essence_->ctg_icon_renderer)
|
||||
{
|
||||
essence_->ctg_icon_renderer(*graph, rt_ctg_icon, categ.expand);
|
||||
}
|
||||
else
|
||||
{
|
||||
facade<element::arrow> arrow("double");
|
||||
arrow.direction(categ.expand ? ::nana::direction::south : ::nana::direction::east);
|
||||
arrow.draw(*graph, {}, txt_color, rt_ctg_icon, element_state::normal);
|
||||
}
|
||||
|
||||
graph->string({ x + 20, y + txtoff }, categ.text, txt_color);
|
||||
|
||||
native_string_type str = to_nstring('(' + std::to_string(categ.items.size()) + ')');
|
||||
|
||||
auto text_s = graph->text_extent_size(categ.text).width;
|
||||
auto extend_text_w = text_s + graph->text_extent_size(str).width;
|
||||
|
||||
graph->string({ x + 25 + static_cast<int>(text_s), y + txtoff }, str);
|
||||
|
||||
if (35 + extend_text_w < width)
|
||||
auto text_px = graph->text_extent_size(categ.text).width;
|
||||
if (categ.display_number)
|
||||
{
|
||||
::nana::point pos{ x + 30 + static_cast<int>(extend_text_w), y + static_cast<int>(item_height) / 2 };
|
||||
//Display the number of items in the category
|
||||
native_string_type str = to_nstring('(' + std::to_string(categ.items.size()) + ')');
|
||||
graph->string({ x + 25 + static_cast<int>(text_px), y + txtoff }, str);
|
||||
text_px += graph->text_extent_size(str).width;
|
||||
}
|
||||
|
||||
graph->line(pos, { x + static_cast<int>(width) - 5, pos.y },
|
||||
txt_color);
|
||||
if (35 + text_px < width)
|
||||
{
|
||||
::nana::point pos{ x + 30 + static_cast<int>(text_px), y + static_cast<int>(item_height) / 2 };
|
||||
|
||||
graph->line(pos, { x + static_cast<int>(width) - 5, pos.y }, txt_color);
|
||||
}
|
||||
|
||||
//Draw selecting inner rectangle
|
||||
@@ -4814,6 +4826,32 @@ namespace nana
|
||||
return true;
|
||||
}
|
||||
|
||||
cat_proxy& cat_proxy::display_number(bool display)
|
||||
{
|
||||
if (cat_->display_number != display)
|
||||
{
|
||||
cat_->display_number = display;
|
||||
ess_->update();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool cat_proxy::expanded() const
|
||||
{
|
||||
return cat_->expand;
|
||||
}
|
||||
|
||||
cat_proxy& cat_proxy::expanded(bool expand)
|
||||
{
|
||||
//The first category isn't allowed to be collapsed
|
||||
if ((expand != cat_->expand) && pos_)
|
||||
{
|
||||
cat_->expand = expand;
|
||||
ess_->update();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto cat_proxy::columns() const -> size_type
|
||||
{
|
||||
return ess_->header.cont().size();
|
||||
@@ -5585,6 +5623,32 @@ namespace nana
|
||||
return _m_ess().def_exp_options;
|
||||
}
|
||||
|
||||
listbox& listbox::category_icon(std::function<void(paint::graphics& graph, const rectangle& rt_icon, bool expanded)> icon_renderer)
|
||||
{
|
||||
_m_ess().ctg_icon_renderer.swap(icon_renderer);
|
||||
_m_ess().update();
|
||||
return *this;
|
||||
}
|
||||
|
||||
listbox& listbox::category_icon(const paint::image& img_expanded, const paint::image&& img_collapsed)
|
||||
{
|
||||
_m_ess().ctg_icon_renderer = [img_expanded, img_collapsed](paint::graphics& graph, const rectangle& rt_icon, bool expanded)
|
||||
{
|
||||
if (expanded)
|
||||
{
|
||||
img_expanded.stretch(rectangle{ img_expanded.size() }, graph, rt_icon);
|
||||
}
|
||||
else
|
||||
{
|
||||
img_collapsed.stretch(rectangle{ img_collapsed.size() }, graph, rt_icon);
|
||||
}
|
||||
};
|
||||
|
||||
_m_ess().update();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
drawerbase::listbox::essence & listbox::_m_ess() const
|
||||
{
|
||||
return get_drawer_trigger().ess();
|
||||
|
||||
Reference in New Issue
Block a user