bug fix and improvement of listbox
This commit is contained in:
@@ -1987,9 +1987,6 @@ namespace nana
|
|||||||
bool auto_draw{true};
|
bool auto_draw{true};
|
||||||
bool checkable{false};
|
bool checkable{false};
|
||||||
bool if_image{false};
|
bool if_image{false};
|
||||||
#if 0 //deprecated
|
|
||||||
bool deselect_deferred{ false }; //deselects items when mouse button is released.
|
|
||||||
#endif
|
|
||||||
unsigned text_height;
|
unsigned text_height;
|
||||||
|
|
||||||
::nana::listbox::export_options def_exp_options;
|
::nana::listbox::export_options def_exp_options;
|
||||||
@@ -3544,7 +3541,7 @@ namespace nana
|
|||||||
:essence_(es)
|
:essence_(es)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void draw(const nana::rectangle& rect)
|
void draw(const nana::rectangle& visual_r)
|
||||||
{
|
{
|
||||||
internal_scope_guard lock;
|
internal_scope_guard lock;
|
||||||
|
|
||||||
@@ -3568,10 +3565,10 @@ namespace nana
|
|||||||
auto const origin = essence_->content_view->origin();
|
auto const origin = essence_->content_view->origin();
|
||||||
|
|
||||||
auto const header_margin = essence_->header.margin();
|
auto const header_margin = essence_->header.margin();
|
||||||
if (header_w + header_margin < origin.x + rect.width)
|
if (header_w + header_margin < origin.x + visual_r.width)
|
||||||
{
|
{
|
||||||
rectangle r{ point{ rect.x + static_cast<int>(header_w + header_margin) - origin.x, rect.y },
|
rectangle r{ point{ visual_r.x + static_cast<int>(header_w + header_margin) - origin.x, visual_r.y },
|
||||||
size{ rect.width + origin.x - header_w, rect.height } };
|
size{ visual_r.width + origin.x - header_w, visual_r.height } };
|
||||||
|
|
||||||
if (!API::dev::copy_transparent_background(essence_->listbox_ptr->handle(), r, *essence_->graph, r.position()))
|
if (!API::dev::copy_transparent_background(essence_->listbox_ptr->handle(), r, *essence_->graph, r.position()))
|
||||||
essence_->graph->rectangle(r, true);
|
essence_->graph->rectangle(r, true);
|
||||||
@@ -3579,7 +3576,7 @@ namespace nana
|
|||||||
|
|
||||||
if (header_margin > 0)
|
if (header_margin > 0)
|
||||||
{
|
{
|
||||||
rectangle r = rect;
|
rectangle r = visual_r;
|
||||||
r.width = header_margin;
|
r.width = header_margin;
|
||||||
|
|
||||||
if (!API::dev::copy_transparent_background(essence_->listbox_ptr->handle(), r, *essence_->graph, r.position()))
|
if (!API::dev::copy_transparent_background(essence_->listbox_ptr->handle(), r, *essence_->graph, r.position()))
|
||||||
@@ -3593,8 +3590,8 @@ namespace nana
|
|||||||
auto first_disp = essence_->first_display();
|
auto first_disp = essence_->first_display();
|
||||||
|
|
||||||
point item_coord{
|
point item_coord{
|
||||||
essence_->item_xpos(rect),
|
essence_->item_xpos(visual_r),
|
||||||
rect.y - static_cast<int>(origin.y % item_height_px)
|
visual_r.y - static_cast<int>(origin.y % item_height_px)
|
||||||
};
|
};
|
||||||
|
|
||||||
essence_->inline_buffered_table.swap(essence_->inline_table);
|
essence_->inline_buffered_table.swap(essence_->inline_table);
|
||||||
@@ -3610,17 +3607,13 @@ namespace nana
|
|||||||
hoverred_pos = lister.advance(first_disp, static_cast<int>(ptr_where.second));
|
hoverred_pos = lister.advance(first_disp, static_cast<int>(ptr_where.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const columns = essence_->ordered_columns(rect.width);
|
auto const columns = essence_->ordered_columns(visual_r.width);
|
||||||
|
|
||||||
if (columns.empty())
|
if (columns.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto const txtoff = static_cast<int>(essence_->scheme_ptr->item_height_ex) / 2;
|
auto const txtoff = static_cast<int>(essence_->scheme_ptr->item_height_ex) / 2;
|
||||||
|
|
||||||
auto i_categ = lister.get(first_disp.cat);
|
|
||||||
|
|
||||||
auto idx = first_disp;
|
|
||||||
|
|
||||||
for (auto & cat : lister.cat_container())
|
for (auto & cat : lister.cat_container())
|
||||||
for (auto & ind : cat.indicators)
|
for (auto & ind : cat.indicators)
|
||||||
{
|
{
|
||||||
@@ -3628,75 +3621,49 @@ namespace nana
|
|||||||
ind->detach();
|
ind->detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Here we draw the root categ (0) or a first item if the first drawing is not a categ.(item!=npos))
|
auto idx = first_disp;
|
||||||
if (idx.cat == 0 || !idx.is_category())
|
for (auto i_categ = lister.get(first_disp.cat); i_categ != lister.cat_container().end(); ++i_categ)
|
||||||
{
|
{
|
||||||
if (idx.cat == 0 && idx.is_category()) // the 0 cat
|
if (item_coord.y > visual_r.bottom())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (idx.cat > 0 && idx.is_category())
|
||||||
{
|
{
|
||||||
first_disp.item = 0;
|
_m_draw_categ(*i_categ, visual_r.x - origin.x, item_coord.y, txtoff, header_w, bgcolor,
|
||||||
|
(hoverred_pos.is_category() && (idx.cat == hoverred_pos.cat) ? item_state::highlighted : item_state::normal)
|
||||||
|
);
|
||||||
|
item_coord.y += static_cast<int>(item_height_px);
|
||||||
idx.item = 0;
|
idx.item = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t size = i_categ->items.size();
|
if (i_categ->expand)
|
||||||
for (std::size_t offs = first_disp.item; offs < size; ++offs, ++idx.item)
|
|
||||||
{
|
{
|
||||||
if (item_coord.y >= rect.bottom())
|
auto size = i_categ->items.size();
|
||||||
break;
|
for (; idx.item < size; ++idx.item)
|
||||||
|
{
|
||||||
|
if (item_coord.y > visual_r.bottom())
|
||||||
|
break;
|
||||||
|
|
||||||
auto item_pos = lister.index_cast(index_pair{ idx.cat, offs }, true); //convert display position to absolute position
|
auto item_pos = lister.index_cast(index_pair{ idx.cat, idx.item }, true); //convert display position to absolute position
|
||||||
|
|
||||||
_m_draw_item(*i_categ, item_pos, item_coord, txtoff, header_w, rect, columns, bgcolor, fgcolor,
|
_m_draw_item(*i_categ, item_pos, item_coord, txtoff, header_w, visual_r, columns, bgcolor, fgcolor,
|
||||||
(hoverred_pos == idx ? item_state::highlighted : item_state::normal)
|
(idx == hoverred_pos ? item_state::highlighted : item_state::normal)
|
||||||
);
|
);
|
||||||
|
|
||||||
item_coord.y += static_cast<int>(item_height_px);
|
item_coord.y += static_cast<int>(item_height_px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++i_categ;
|
|
||||||
++idx.cat;
|
++idx.cat;
|
||||||
}
|
idx.item = nana::npos;
|
||||||
|
|
||||||
for (; i_categ != lister.cat_container().end(); ++i_categ, ++idx.cat)
|
|
||||||
{
|
|
||||||
if (item_coord.y > rect.bottom())
|
|
||||||
break;
|
|
||||||
|
|
||||||
idx.item = 0;
|
|
||||||
|
|
||||||
_m_draw_categ(*i_categ, rect.x - origin.x, item_coord.y, txtoff, header_w, bgcolor,
|
|
||||||
(hoverred_pos.is_category() && (idx.cat == hoverred_pos.cat) ? item_state::highlighted : item_state::normal)
|
|
||||||
);
|
|
||||||
item_coord.y += static_cast<int>(item_height_px);
|
|
||||||
|
|
||||||
if (false == i_categ->expand)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto size = i_categ->items.size();
|
|
||||||
for (decltype(size) pos = 0; pos < size; ++pos)
|
|
||||||
{
|
|
||||||
if (item_coord.y > rect.bottom())
|
|
||||||
break;
|
|
||||||
|
|
||||||
auto item_pos = lister.index_cast(index_pair{ idx.cat, pos }, true); //convert display position to absolute position
|
|
||||||
|
|
||||||
_m_draw_item(*i_categ, item_pos, item_coord, txtoff, header_w, rect, columns, bgcolor, fgcolor,
|
|
||||||
(idx == hoverred_pos ? item_state::highlighted : item_state::normal)
|
|
||||||
);
|
|
||||||
|
|
||||||
item_coord.y += static_cast<int>(item_height_px);
|
|
||||||
if (item_coord.y >= rect.bottom())
|
|
||||||
break;
|
|
||||||
|
|
||||||
++idx.item;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
essence_->inline_buffered_table.clear();
|
essence_->inline_buffered_table.clear();
|
||||||
|
|
||||||
if (item_coord.y < rect.bottom())
|
if (item_coord.y < visual_r.bottom())
|
||||||
{
|
{
|
||||||
rectangle bground_r{ rect.x, item_coord.y, rect.width, static_cast<unsigned>(rect.bottom() - item_coord.y) };
|
rectangle bground_r{ visual_r.x, item_coord.y, visual_r.width, static_cast<unsigned>(visual_r.bottom() - item_coord.y) };
|
||||||
if (!API::dev::copy_transparent_background(essence_->listbox_ptr->handle(), bground_r, *essence_->graph, bground_r.position()))
|
if (!API::dev::copy_transparent_background(essence_->listbox_ptr->handle(), bground_r, *essence_->graph, bground_r.position()))
|
||||||
essence_->graph->rectangle(bground_r, true, bgcolor);
|
essence_->graph->rectangle(bground_r, true, bgcolor);
|
||||||
}
|
}
|
||||||
@@ -3820,10 +3787,10 @@ namespace nana
|
|||||||
void _m_draw_item(const category_t& cat,
|
void _m_draw_item(const category_t& cat,
|
||||||
const index_pair& item_pos,
|
const index_pair& item_pos,
|
||||||
const point& coord,
|
const point& coord,
|
||||||
const int txtoff, ///< below y to print the text
|
const int txtoff, ///< below y to print the text
|
||||||
unsigned width,
|
unsigned header_width, ///< width of all visible columns, in pixel
|
||||||
const nana::rectangle& content_r, ///< the rectangle where the full list content have to be drawn
|
const nana::rectangle& content_r, ///< the rectangle where the full list content have to be drawn
|
||||||
const std::vector<size_type>& seqs, ///< columns to print
|
const std::vector<size_type>& seqs, ///< columns to print
|
||||||
nana::color bgcolor,
|
nana::color bgcolor,
|
||||||
nana::color fgcolor,
|
nana::color fgcolor,
|
||||||
item_state state
|
item_state state
|
||||||
@@ -3842,12 +3809,16 @@ namespace nana
|
|||||||
if(!item.fgcolor.invisible())
|
if(!item.fgcolor.invisible())
|
||||||
fgcolor = item.fgcolor;
|
fgcolor = item.fgcolor;
|
||||||
|
|
||||||
const unsigned show_w = (std::min)(content_r.width, width - essence_->content_view->origin().x);
|
const unsigned columns_shown_width = (std::min)(content_r.width, header_width - essence_->content_view->origin().x);
|
||||||
|
|
||||||
auto graph = essence_->graph;
|
auto graph = essence_->graph;
|
||||||
|
|
||||||
//draw the background for the whole item
|
//draw the background for the whole item
|
||||||
rectangle bground_r{ content_r.x + static_cast<int>(essence_->header.margin()), coord.y, show_w, essence_->item_height() };
|
rectangle bground_r{
|
||||||
|
content_r.x + static_cast<int>(essence_->header.margin()) - essence_->content_view->origin().x,
|
||||||
|
coord.y,
|
||||||
|
columns_shown_width + essence_->content_view->origin().x,
|
||||||
|
essence_->item_height() };
|
||||||
auto const state_bgcolor = this->_m_draw_item_bground(bground_r, bgcolor, {}, state, item);
|
auto const state_bgcolor = this->_m_draw_item_bground(bground_r, bgcolor, {}, state, item);
|
||||||
|
|
||||||
//The position of column in x-axis.
|
//The position of column in x-axis.
|
||||||
@@ -4051,7 +4022,6 @@ namespace nana
|
|||||||
void _m_draw_item_border(int item_top) const
|
void _m_draw_item_border(int item_top) const
|
||||||
{
|
{
|
||||||
//Draw selecting inner rectangle
|
//Draw selecting inner rectangle
|
||||||
|
|
||||||
rectangle r{
|
rectangle r{
|
||||||
essence_->content_area().x - essence_->content_view->origin().x + static_cast<int>(essence_->header.margin()),
|
essence_->content_area().x - essence_->content_view->origin().x + static_cast<int>(essence_->header.margin()),
|
||||||
item_top,
|
item_top,
|
||||||
@@ -4150,13 +4120,8 @@ namespace nana
|
|||||||
using item_state = essence::item_state;
|
using item_state = essence::item_state;
|
||||||
using parts = essence::parts;
|
using parts = essence::parts;
|
||||||
|
|
||||||
#if 0 //deprecated
|
if ((operation_states::msup_deselect == essence_->operation.state) && API::dev::window_draggable(arg.window_handle))
|
||||||
//Cancel deferred deselection operation when mouse moves.
|
|
||||||
essence_->deselect_deferred = false;
|
|
||||||
#else
|
|
||||||
if (operation_states::msup_deselect == essence_->operation.state)
|
|
||||||
essence_->operation.state = operation_states::none;
|
essence_->operation.state = operation_states::none;
|
||||||
#endif
|
|
||||||
|
|
||||||
bool need_refresh = false;
|
bool need_refresh = false;
|
||||||
|
|
||||||
@@ -4316,20 +4281,6 @@ namespace nana
|
|||||||
essence_->mouse_selection.reverse_selection = true;
|
essence_->mouse_selection.reverse_selection = true;
|
||||||
new_selected_status = !essence_->cs_status(abs_item_pos, true);
|
new_selected_status = !essence_->cs_status(abs_item_pos, true);
|
||||||
}
|
}
|
||||||
#if 0 //deprecated
|
|
||||||
else if (nana::mouse::right_button == arg.button)
|
|
||||||
{
|
|
||||||
//Unselects all selected items if the current item is not selected before selecting.
|
|
||||||
auto selected = lister.pick_items(true);
|
|
||||||
if (selected.cend() == std::find(selected.cbegin(), selected.cend(), item_pos))
|
|
||||||
lister.select_for_all(false, abs_item_pos);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Unselects all selected items except current item if right button clicked.
|
|
||||||
lister.select_for_all(false, abs_item_pos); //cancel all selections
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto selected = lister.pick_items(true);
|
auto selected = lister.pick_items(true);
|
||||||
@@ -4343,17 +4294,13 @@ namespace nana
|
|||||||
{
|
{
|
||||||
essence_->operation.item = abs_item_pos;
|
essence_->operation.item = abs_item_pos;
|
||||||
|
|
||||||
//Don't deselect the selections if the listbox is draggable.
|
//Don't deselect the selections, let it determine in mouse_move event depending on whether dnd is enabled.
|
||||||
//It should remain the selections for drag-and-drop
|
essence_->operation.state = operation_states::msup_deselect;
|
||||||
|
|
||||||
if (!API::dev::window_draggable(arg.window_handle))
|
|
||||||
essence_->operation.state = operation_states::msup_deselect;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
lister.select_for_all(false, abs_item_pos);
|
lister.select_for_all(false, abs_item_pos);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -4423,15 +4370,11 @@ namespace nana
|
|||||||
|
|
||||||
//Deselection of all items is deferred to the mouse up event when ctrl or shift is not pressed
|
//Deselection of all items is deferred to the mouse up event when ctrl or shift is not pressed
|
||||||
//Pressing ctrl or shift is to selects other items without deselecting current selections.
|
//Pressing ctrl or shift is to selects other items without deselecting current selections.
|
||||||
#if 0 //deprecated
|
|
||||||
essence_->deselect_deferred = !(arg.ctrl || arg.shift);
|
|
||||||
#else
|
|
||||||
if (!(arg.ctrl || arg.shift))
|
if (!(arg.ctrl || arg.shift))
|
||||||
{
|
{
|
||||||
essence_->operation.state = operation_states::msup_deselect;
|
essence_->operation.state = operation_states::msup_deselect;
|
||||||
essence_->operation.item = index_pair{nana::npos, nana::npos};
|
essence_->operation.item = index_pair{nana::npos, nana::npos};
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(update)
|
if(update)
|
||||||
@@ -4473,14 +4416,6 @@ namespace nana
|
|||||||
need_refresh = true;
|
need_refresh = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 //deprecated
|
|
||||||
if (essence_->deselect_deferred)
|
|
||||||
{
|
|
||||||
essence_->deselect_deferred = false;
|
|
||||||
need_refresh |= (essence_->lister.select_for_all(false));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (operation_states::msup_deselect == essence_->operation.state)
|
if (operation_states::msup_deselect == essence_->operation.state)
|
||||||
{
|
{
|
||||||
essence_->operation.state = operation_states::none;
|
essence_->operation.state = operation_states::none;
|
||||||
|
|||||||
Reference in New Issue
Block a user