bug fix and improvement of listbox
This commit is contained in:
parent
72f779b4bd
commit
b87d17cac1
@ -1987,9 +1987,6 @@ namespace nana
|
||||
bool auto_draw{true};
|
||||
bool checkable{false};
|
||||
bool if_image{false};
|
||||
#if 0 //deprecated
|
||||
bool deselect_deferred{ false }; //deselects items when mouse button is released.
|
||||
#endif
|
||||
unsigned text_height;
|
||||
|
||||
::nana::listbox::export_options def_exp_options;
|
||||
@ -3544,7 +3541,7 @@ namespace nana
|
||||
:essence_(es)
|
||||
{}
|
||||
|
||||
void draw(const nana::rectangle& rect)
|
||||
void draw(const nana::rectangle& visual_r)
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
|
||||
@ -3568,10 +3565,10 @@ namespace nana
|
||||
auto const origin = essence_->content_view->origin();
|
||||
|
||||
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 },
|
||||
size{ rect.width + origin.x - header_w, rect.height } };
|
||||
rectangle r{ point{ visual_r.x + static_cast<int>(header_w + header_margin) - origin.x, visual_r.y },
|
||||
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()))
|
||||
essence_->graph->rectangle(r, true);
|
||||
@ -3579,7 +3576,7 @@ namespace nana
|
||||
|
||||
if (header_margin > 0)
|
||||
{
|
||||
rectangle r = rect;
|
||||
rectangle r = visual_r;
|
||||
r.width = header_margin;
|
||||
|
||||
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();
|
||||
|
||||
point item_coord{
|
||||
essence_->item_xpos(rect),
|
||||
rect.y - static_cast<int>(origin.y % item_height_px)
|
||||
essence_->item_xpos(visual_r),
|
||||
visual_r.y - static_cast<int>(origin.y % item_height_px)
|
||||
};
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
auto const columns = essence_->ordered_columns(rect.width);
|
||||
auto const columns = essence_->ordered_columns(visual_r.width);
|
||||
|
||||
if (columns.empty())
|
||||
return;
|
||||
|
||||
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 & ind : cat.indicators)
|
||||
{
|
||||
@ -3628,75 +3621,49 @@ namespace nana
|
||||
ind->detach();
|
||||
}
|
||||
|
||||
//Here we draw the root categ (0) or a first item if the first drawing is not a categ.(item!=npos))
|
||||
if (idx.cat == 0 || !idx.is_category())
|
||||
auto idx = first_disp;
|
||||
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;
|
||||
}
|
||||
|
||||
std::size_t size = i_categ->items.size();
|
||||
for (std::size_t offs = first_disp.item; offs < size; ++offs, ++idx.item)
|
||||
if (i_categ->expand)
|
||||
{
|
||||
if (item_coord.y >= rect.bottom())
|
||||
break;
|
||||
auto size = i_categ->items.size();
|
||||
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,
|
||||
(hoverred_pos == idx ? item_state::highlighted : item_state::normal)
|
||||
);
|
||||
_m_draw_item(*i_categ, item_pos, item_coord, txtoff, header_w, visual_r, columns, bgcolor, fgcolor,
|
||||
(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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
idx.item = nana::npos;
|
||||
}
|
||||
}
|
||||
|
||||
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()))
|
||||
essence_->graph->rectangle(bground_r, true, bgcolor);
|
||||
}
|
||||
@ -3820,10 +3787,10 @@ namespace nana
|
||||
void _m_draw_item(const category_t& cat,
|
||||
const index_pair& item_pos,
|
||||
const point& coord,
|
||||
const int txtoff, ///< below y to print the text
|
||||
unsigned width,
|
||||
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 int txtoff, ///< below y to print the text
|
||||
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 std::vector<size_type>& seqs, ///< columns to print
|
||||
nana::color bgcolor,
|
||||
nana::color fgcolor,
|
||||
item_state state
|
||||
@ -3842,12 +3809,16 @@ namespace nana
|
||||
if(!item.fgcolor.invisible())
|
||||
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;
|
||||
|
||||
//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);
|
||||
|
||||
//The position of column in x-axis.
|
||||
@ -4051,7 +4022,6 @@ namespace nana
|
||||
void _m_draw_item_border(int item_top) const
|
||||
{
|
||||
//Draw selecting inner rectangle
|
||||
|
||||
rectangle r{
|
||||
essence_->content_area().x - essence_->content_view->origin().x + static_cast<int>(essence_->header.margin()),
|
||||
item_top,
|
||||
@ -4150,13 +4120,8 @@ namespace nana
|
||||
using item_state = essence::item_state;
|
||||
using parts = essence::parts;
|
||||
|
||||
#if 0 //deprecated
|
||||
//Cancel deferred deselection operation when mouse moves.
|
||||
essence_->deselect_deferred = false;
|
||||
#else
|
||||
if (operation_states::msup_deselect == essence_->operation.state)
|
||||
if ((operation_states::msup_deselect == essence_->operation.state) && API::dev::window_draggable(arg.window_handle))
|
||||
essence_->operation.state = operation_states::none;
|
||||
#endif
|
||||
|
||||
bool need_refresh = false;
|
||||
|
||||
@ -4316,20 +4281,6 @@ namespace nana
|
||||
essence_->mouse_selection.reverse_selection = 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
|
||||
{
|
||||
auto selected = lister.pick_items(true);
|
||||
@ -4343,17 +4294,13 @@ namespace nana
|
||||
{
|
||||
essence_->operation.item = abs_item_pos;
|
||||
|
||||
//Don't deselect the selections if the listbox is draggable.
|
||||
//It should remain the selections for drag-and-drop
|
||||
|
||||
if (!API::dev::window_draggable(arg.window_handle))
|
||||
essence_->operation.state = operation_states::msup_deselect;
|
||||
//Don't deselect the selections, let it determine in mouse_move event depending on whether dnd is enabled.
|
||||
essence_->operation.state = operation_states::msup_deselect;
|
||||
}
|
||||
}
|
||||
else
|
||||
lister.select_for_all(false, abs_item_pos);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
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
|
||||
//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))
|
||||
{
|
||||
essence_->operation.state = operation_states::msup_deselect;
|
||||
essence_->operation.item = index_pair{nana::npos, nana::npos};
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if(update)
|
||||
@ -4473,14 +4416,6 @@ namespace nana
|
||||
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)
|
||||
{
|
||||
essence_->operation.state = operation_states::none;
|
||||
|
Loading…
x
Reference in New Issue
Block a user