add new overloading of scroll_into_view for treebox
This commit is contained in:
parent
c1b88c430a
commit
074b96a05a
@ -450,8 +450,18 @@ namespace nana
|
|||||||
|
|
||||||
item_proxy selected() const; ///< returns the selected node
|
item_proxy selected() const; ///< returns the selected node
|
||||||
|
|
||||||
/// Scrolls a specified item into view
|
/// Scrolls a specified item into view.
|
||||||
void scroll_into_view(item_proxy item, align_v);
|
/**
|
||||||
|
* @param item An item to be requested.
|
||||||
|
* @param bearing The position where the item to be positioned in the view.
|
||||||
|
*/
|
||||||
|
void scroll_into_view(item_proxy item, align_v bearing);
|
||||||
|
|
||||||
|
/// Scrolls a specified item into view.
|
||||||
|
/**
|
||||||
|
* @param item An item to be requested.
|
||||||
|
*/
|
||||||
|
void scroll_into_view(item_proxy item);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<scroll_operation_interface> _m_scroll_operation() override;
|
std::shared_ptr<scroll_operation_interface> _m_scroll_operation() override;
|
||||||
|
|||||||
@ -578,6 +578,96 @@ namespace nana
|
|||||||
return screen_px / item_px + 1;
|
return screen_px / item_px + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool scroll_into_view(node_type* node, bool use_bearing, align_v bearing)
|
||||||
|
{
|
||||||
|
auto & tree = attr.tree_cont;
|
||||||
|
|
||||||
|
auto parent = node->owner;
|
||||||
|
|
||||||
|
std::vector<node_type*> parent_path;
|
||||||
|
while (parent)
|
||||||
|
{
|
||||||
|
parent_path.push_back(parent);
|
||||||
|
parent = parent->owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_expanded = false;
|
||||||
|
|
||||||
|
//Expands the shrinked nodes which are ancestors of node
|
||||||
|
for (auto i = parent_path.rbegin(); i != parent_path.rend(); ++i)
|
||||||
|
{
|
||||||
|
if (!(*i)->value.second.expanded)
|
||||||
|
{
|
||||||
|
has_expanded = true;
|
||||||
|
(*i)->value.second.expanded = true;
|
||||||
|
item_proxy iprx(data.trigger_ptr, *i);
|
||||||
|
data.widget_ptr->events().expanded.emit(::nana::arg_treebox{ *data.widget_ptr, iprx, true }, data.widget_ptr->handle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pos = tree.distance_if(node, pred_allow_child{});
|
||||||
|
auto last_pos = tree.distance_if(last(true), pred_allow_child{});
|
||||||
|
|
||||||
|
auto const capacity = screen_capacity(true);
|
||||||
|
auto const item_px = data.comp_placer->item_height(*data.graph);
|
||||||
|
|
||||||
|
//If use_bearing is false, it calculates a bearing depending on the current
|
||||||
|
//position of the requested item.
|
||||||
|
if (!use_bearing)
|
||||||
|
{
|
||||||
|
auto first_pos = tree.distance_if(shape.first, pred_allow_child{});
|
||||||
|
|
||||||
|
if (pos < first_pos)
|
||||||
|
bearing = align_v::top;
|
||||||
|
else if (pos >= first_pos + capacity)
|
||||||
|
bearing = align_v::bottom;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//The item is already in the view.
|
||||||
|
//Returns true if a draw operation is needed
|
||||||
|
return has_expanded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (align_v::top == bearing)
|
||||||
|
{
|
||||||
|
if (last_pos - pos + 1 < capacity)
|
||||||
|
{
|
||||||
|
if (last_pos + 1 >= capacity)
|
||||||
|
pos = last_pos + 1 - capacity;
|
||||||
|
else
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (align_v::center == bearing)
|
||||||
|
{
|
||||||
|
auto const short_side = (std::min)(pos, last_pos - pos);
|
||||||
|
if (short_side >= capacity / 2)
|
||||||
|
{
|
||||||
|
pos -= short_side;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (short_side == pos || (last_pos + 1 < capacity))
|
||||||
|
pos = 0;
|
||||||
|
else
|
||||||
|
pos = last_pos + 1 - capacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (align_v::bottom == bearing)
|
||||||
|
{
|
||||||
|
if (pos + 1 >= capacity)
|
||||||
|
pos = pos + 1 - capacity;
|
||||||
|
else
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto prv_first = shape.first;
|
||||||
|
shape.first = attr.tree_cont.advance_if(nullptr, pos, drawerbase::treebox::pred_allow_child{});
|
||||||
|
|
||||||
|
return has_expanded || (prv_first != shape.first);
|
||||||
|
}
|
||||||
|
|
||||||
bool make_adjust(node_type * node, int reason)
|
bool make_adjust(node_type * node, int reason)
|
||||||
{
|
{
|
||||||
if(!node) return false;
|
if(!node) return false;
|
||||||
@ -2287,79 +2377,19 @@ namespace nana
|
|||||||
return item_proxy(const_cast<drawer_trigger_t*>(dw), dw->impl()->node_state.selected);
|
return item_proxy(const_cast<drawer_trigger_t*>(dw), dw->impl()->node_state.selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void treebox::scroll_into_view(item_proxy item, align_v align)
|
void treebox::scroll_into_view(item_proxy item, align_v bearing)
|
||||||
{
|
{
|
||||||
auto node = item._m_node();
|
|
||||||
internal_scope_guard lock;
|
internal_scope_guard lock;
|
||||||
auto impl = get_drawer_trigger().impl();
|
if(get_drawer_trigger().impl()->scroll_into_view(item._m_node(), true, bearing))
|
||||||
|
API::refresh_window(*this);
|
||||||
auto & tree = impl->attr.tree_cont;
|
|
||||||
|
|
||||||
auto parent = node->owner;
|
|
||||||
|
|
||||||
std::vector<drawerbase::treebox::node_type*> parent_path;
|
|
||||||
while (parent)
|
|
||||||
{
|
|
||||||
parent_path.push_back(parent);
|
|
||||||
parent = parent->owner;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Expands the shrinked nodes which are ancestors of node
|
void treebox::scroll_into_view(item_proxy item)
|
||||||
for (auto i = parent_path.rbegin(); i != parent_path.rend(); ++i)
|
|
||||||
{
|
{
|
||||||
if (!(*i)->value.second.expanded)
|
internal_scope_guard lock;
|
||||||
{
|
//The third argument for scroll_into_view is ignored if the second argument is false.
|
||||||
(*i)->value.second.expanded = true;
|
if(get_drawer_trigger().impl()->scroll_into_view(item._m_node(), false, align_v::center))
|
||||||
item_proxy iprx(impl->data.trigger_ptr, *i);
|
API::refresh_window(*this);
|
||||||
impl->data.widget_ptr->events().expanded.emit(::nana::arg_treebox{ *impl->data.widget_ptr, iprx, true }, impl->data.widget_ptr->handle());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pos = tree.distance_if(node, drawerbase::treebox::pred_allow_child{});
|
|
||||||
auto last_pos = tree.distance_if(impl->last(true), drawerbase::treebox::pred_allow_child{});
|
|
||||||
|
|
||||||
auto const capacity = impl->screen_capacity(false);
|
|
||||||
auto const item_px = impl->data.comp_placer->item_height(*impl->data.graph);
|
|
||||||
|
|
||||||
if (align_v::top == align)
|
|
||||||
{
|
|
||||||
if (last_pos - pos + 1 < capacity)
|
|
||||||
{
|
|
||||||
if (last_pos + 1 >= capacity)
|
|
||||||
pos = last_pos + 1 - capacity;
|
|
||||||
else
|
|
||||||
pos = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (align_v::center == align)
|
|
||||||
{
|
|
||||||
auto const short_side = (std::min)(pos, last_pos - pos);
|
|
||||||
if (short_side >= capacity / 2)
|
|
||||||
{
|
|
||||||
pos -= short_side;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (short_side == pos || (last_pos + 1 < capacity))
|
|
||||||
pos = 0;
|
|
||||||
else
|
|
||||||
pos = last_pos + 1 - capacity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (align_v::bottom == align)
|
|
||||||
{
|
|
||||||
if (pos + 1 >= capacity)
|
|
||||||
pos = pos + 1 - capacity;
|
|
||||||
else
|
|
||||||
pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl->shape.first = impl->attr.tree_cont.advance_if(nullptr, pos, drawerbase::treebox::pred_allow_child{});
|
|
||||||
|
|
||||||
impl->draw(true, false, true);
|
|
||||||
|
|
||||||
API::update_window(*this);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<scroll_operation_interface> treebox::_m_scroll_operation()
|
std::shared_ptr<scroll_operation_interface> treebox::_m_scroll_operation()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user