listbox and place code refined
This commit is contained in:
parent
49dfaca1ef
commit
9b91d3b55f
@ -503,7 +503,7 @@ namespace nana
|
|||||||
|
|
||||||
static event_handle erase_element(std::vector<element_t>& elements, window handle)
|
static event_handle erase_element(std::vector<element_t>& elements, window handle)
|
||||||
{
|
{
|
||||||
for (auto i = elements.begin(), end = elements.end(); i != end; ++i)
|
for (auto i = elements.begin(); i != elements.end(); ++i)
|
||||||
{
|
{
|
||||||
if (i->handle == handle)
|
if (i->handle == handle)
|
||||||
{
|
{
|
||||||
@ -515,26 +515,16 @@ namespace nana
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
//The defintion is moved after the definition of class division
|
|
||||||
template<typename Function>
|
|
||||||
void _m_for_each(division*, Function);
|
|
||||||
|
|
||||||
//Listen to destroy of a window
|
//Listen to destroy of a window
|
||||||
//It will delete the element and recollocate when the window destroyed.
|
//It will delete the element and recollocate when the window destroyed.
|
||||||
event_handle _m_make_destroy(window wd)
|
event_handle _m_make_destroy(window wd)
|
||||||
{
|
{
|
||||||
return API::events(wd).destroy.connect([this, wd](const arg_destroy&)
|
return API::events(wd).destroy.connect([this, wd](const arg_destroy&)
|
||||||
{
|
{
|
||||||
for (auto i = elements.begin(), end = elements.end(); i != end; ++i)
|
if (erase_element(elements, wd))
|
||||||
{
|
{
|
||||||
if (i->handle == wd)
|
if (!API::is_destroying(API::get_parent_window(wd)))
|
||||||
{
|
place_ptr_->collocate();
|
||||||
elements.erase(i);
|
|
||||||
|
|
||||||
if (!API::is_destroying(API::get_parent_window(wd)))
|
|
||||||
place_ptr_->collocate();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -613,10 +603,7 @@ namespace nana
|
|||||||
|
|
||||||
division(kind k, std::string&& n)
|
division(kind k, std::string&& n)
|
||||||
: kind_of_division(k),
|
: kind_of_division(k),
|
||||||
name(std::move(n)),
|
name(std::move(n))
|
||||||
field(nullptr),
|
|
||||||
div_next(nullptr),
|
|
||||||
div_owner(nullptr)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~division()
|
virtual ~division()
|
||||||
@ -754,7 +741,6 @@ namespace nana
|
|||||||
//Collocate the division and its children divisions,
|
//Collocate the division and its children divisions,
|
||||||
//The window parameter is specified for the window which the place object binded.
|
//The window parameter is specified for the window which the place object binded.
|
||||||
virtual void collocate(window) = 0;
|
virtual void collocate(window) = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
kind kind_of_division;
|
kind kind_of_division;
|
||||||
bool display{ true };
|
bool display{ true };
|
||||||
@ -769,18 +755,11 @@ namespace nana
|
|||||||
|
|
||||||
place_parts::margin margin;
|
place_parts::margin margin;
|
||||||
place_parts::repeated_array gap;
|
place_parts::repeated_array gap;
|
||||||
field_gather * field;
|
field_gather * field{ nullptr };
|
||||||
division * div_next, *div_owner;
|
division * div_next{ nullptr };
|
||||||
|
division * div_owner{ nullptr };
|
||||||
};//end class division
|
};//end class division
|
||||||
|
|
||||||
template<typename Function>
|
|
||||||
void place::implement::field_gather::_m_for_each(division * div, Function fn)
|
|
||||||
{
|
|
||||||
for (auto & up : div->children) //The element of children is unique_ptr
|
|
||||||
fn(up.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class place::implement::div_arrange
|
class place::implement::div_arrange
|
||||||
: public division
|
: public division
|
||||||
{
|
{
|
||||||
|
|||||||
@ -547,8 +547,6 @@ namespace nana
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct essence;
|
|
||||||
|
|
||||||
struct item_data
|
struct item_data
|
||||||
{
|
{
|
||||||
using container = std::vector<cell>;
|
using container = std::vector<cell>;
|
||||||
@ -719,7 +717,7 @@ namespace nana
|
|||||||
|
|
||||||
if (allocate_if_empty)
|
if (allocate_if_empty)
|
||||||
{
|
{
|
||||||
std::make_unique<nana::any>().swap(item.anyobj);
|
item.anyobj.reset(new any);
|
||||||
return item.anyobj.get();
|
return item.anyobj.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1044,8 +1042,8 @@ namespace nana
|
|||||||
{
|
{
|
||||||
auto i = categories_.cbegin();
|
auto i = categories_.cbegin();
|
||||||
std::advance(i, pos.cat);
|
std::advance(i, pos.cat);
|
||||||
if (i->model_ptr && i->model_ptr->container()->immutable())
|
|
||||||
throw std::runtime_error("nana::listbox disallow the operation because of immutable modal");
|
throw_if_immutable_model(i->model_ptr.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1057,8 +1055,7 @@ namespace nana
|
|||||||
std::advance(i, pos.cat);
|
std::advance(i, pos.cat);
|
||||||
if (i->model_ptr)
|
if (i->model_ptr)
|
||||||
{
|
{
|
||||||
if (i->model_ptr->container()->immutable())
|
throw_if_immutable_model(i->model_ptr.get());
|
||||||
throw std::runtime_error("nana::listbox disallow to modify the item because of immutable model");
|
|
||||||
|
|
||||||
i->model_ptr->container()->assign(pos.item, cells);
|
i->model_ptr->container()->assign(pos.item, cells);
|
||||||
}
|
}
|
||||||
@ -1874,7 +1871,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
return index_pair{ absolute(first()) };
|
return index_pair{ absolute(first()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool good(size_type cat) const
|
bool good(size_type cat) const
|
||||||
{
|
{
|
||||||
return (cat < categories_.size());
|
return (cat < categories_.size());
|
||||||
@ -1884,6 +1881,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
return ((pos.cat < categories_.size()) && (pos.item < size_item(pos.cat)));
|
return ((pos.cat < categories_.size()) && (pos.item < size_item(pos.cat)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// if good return the same item (in arg item), or just the next cat and true, but If fail return false
|
/// if good return the same item (in arg item), or just the next cat and true, but If fail return false
|
||||||
bool good_item(index_pair pos, index_pair& item) const
|
bool good_item(index_pair pos, index_pair& item) const
|
||||||
{
|
{
|
||||||
@ -1951,6 +1949,7 @@ namespace nana
|
|||||||
|
|
||||||
return npos;
|
return npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
index_pair relative_pair(const index_pair& pos) const
|
index_pair relative_pair(const index_pair& pos) const
|
||||||
{
|
{
|
||||||
//Returns an empty pos if item is npos
|
//Returns an empty pos if item is npos
|
||||||
@ -2251,19 +2250,14 @@ namespace nana
|
|||||||
adjust_scroll_life(); // call adjust_scroll_value(); //adjust_scroll_value(); // again?
|
adjust_scroll_life(); // call adjust_scroll_value(); //adjust_scroll_value(); // again?
|
||||||
}
|
}
|
||||||
|
|
||||||
void trace_item_abs( index_pair abs_pos )
|
|
||||||
{
|
|
||||||
if( abs_pos.item == npos
|
|
||||||
&& abs_pos.cat == scroll.offset_y_abs.cat
|
|
||||||
&& scroll.offset_y_abs.item == npos ) // if item==off y and is a cat
|
|
||||||
return;
|
|
||||||
|
|
||||||
trace_item_dpl( lister.relative_pair(abs_pos)) ; // ??? scroll_y_dpl_refresh() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
void trace_last_selected_item( )
|
void trace_last_selected_item( )
|
||||||
{
|
{
|
||||||
trace_item_abs(lister.last_selected_abs);
|
if (lister.last_selected_abs.item == npos &&
|
||||||
|
lister.last_selected_abs.cat == scroll.offset_y_abs.cat &&
|
||||||
|
scroll.offset_y_abs.item == npos) // if item==off y and is a cat
|
||||||
|
return;
|
||||||
|
|
||||||
|
trace_item_dpl(lister.relative_pair(lister.last_selected_abs)); // ??? scroll_y_dpl_refresh() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update()
|
void update()
|
||||||
@ -3040,7 +3034,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
auto& cat = *get(pos.cat);
|
auto& cat = *get(pos.cat);
|
||||||
|
|
||||||
if ((pos.item != ::nana::npos) && (pos.item >= cat.items.size()))
|
if ((pos.item != nana::npos) && (pos.item >= cat.items.size()))
|
||||||
throw std::invalid_argument("listbox: invalid pos to scroll");
|
throw std::invalid_argument("listbox: invalid pos to scroll");
|
||||||
|
|
||||||
if (!cat.expand)
|
if (!cat.expand)
|
||||||
@ -3069,12 +3063,12 @@ namespace nana
|
|||||||
if (categories_.back().expand)
|
if (categories_.back().expand)
|
||||||
{
|
{
|
||||||
if (categories_.back().items.empty())
|
if (categories_.back().items.empty())
|
||||||
last.item = npos;
|
last.item = nana::npos;
|
||||||
else
|
else
|
||||||
last.item = categories_.back().items.size() - 1;
|
last.item = categories_.back().items.size() - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
last.item = ::nana::npos;
|
last.item = nana::npos;
|
||||||
|
|
||||||
backward(last, view_items, start_pos);
|
backward(last, view_items, start_pos);
|
||||||
}
|
}
|
||||||
@ -3204,19 +3198,18 @@ namespace nana
|
|||||||
|
|
||||||
std::vector<cell> model_cells;
|
std::vector<cell> model_cells;
|
||||||
|
|
||||||
|
auto const pcell = (cat.model_ptr ? &model_cells : nullptr);
|
||||||
|
|
||||||
for (auto i : cat.sorted)
|
for (auto i : cat.sorted)
|
||||||
{
|
{
|
||||||
auto& item = cat.items[i];
|
auto& item = cat.items[i];
|
||||||
if (item.flags.selected || !exp_opt.only_selected_items)
|
if (item.flags.selected || !exp_opt.only_selected_items)
|
||||||
{
|
{
|
||||||
//Test if the category have a model set.
|
//Test if the category have a model set.
|
||||||
if (cat.model_ptr)
|
if (pcell)
|
||||||
{
|
|
||||||
cat.model_ptr->container()->to_cells(i).swap(model_cells);
|
cat.model_ptr->container()->to_cells(i).swap(model_cells);
|
||||||
list_str += (item.to_string(exp_opt, &model_cells) + exp_opt.endl);
|
|
||||||
}
|
list_str += (item.to_string(exp_opt, pcell) + exp_opt.endl);
|
||||||
else
|
|
||||||
list_str += (item.to_string(exp_opt, nullptr) + exp_opt.endl);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3473,15 +3466,16 @@ namespace nana
|
|||||||
{
|
{
|
||||||
const auto & col = essence_->header.at(essence_->pointer_where.second);
|
const auto & col = essence_->header.at(essence_->pointer_where.second);
|
||||||
|
|
||||||
nana::paint::graphics ext_graph({ col.width_px, essence_->scheme_ptr->header_height });
|
paint::graphics fl_graph({ col.width_px, essence_->scheme_ptr->header_height });
|
||||||
ext_graph.typeface(essence_->graph->typeface());
|
|
||||||
|
fl_graph.typeface(essence_->graph->typeface());
|
||||||
|
|
||||||
int text_top = (essence_->scheme_ptr->header_height - essence_->scheme_ptr->text_height) / 2;
|
int text_top = (essence_->scheme_ptr->header_height - essence_->scheme_ptr->text_height) / 2;
|
||||||
_m_draw_header_item(ext_graph, rectangle{ext_graph.size()}, text_top, colors::white, col, item_state::floated);
|
_m_draw_header_item(fl_graph, rectangle{ fl_graph.size()}, text_top, colors::white, col, item_state::floated);
|
||||||
|
|
||||||
auto xpos = essence_->header.position(col.index, nullptr) + pos.x - grabs_.start_pos;
|
auto xpos = essence_->header.position(col.index, nullptr) + pos.x - grabs_.start_pos;
|
||||||
|
|
||||||
ext_graph.blend(rectangle{ ext_graph.size() }, *(essence_->graph), point{xpos - static_cast<int>(essence_->scroll.x_offset()) + rect.x, rect.y}, 0.5);
|
fl_graph.blend(rectangle{ fl_graph.size() }, *(essence_->graph), point{xpos - static_cast<int>(essence_->scroll.x_offset()) + rect.x, rect.y}, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -5084,9 +5078,6 @@ namespace nana
|
|||||||
API::refresh_window(ess_->listbox_ptr->handle());
|
API::refresh_window(ess_->listbox_ptr->handle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//class cat_proxy
|
|
||||||
|
|
||||||
//end class cat_proxy
|
//end class cat_proxy
|
||||||
}
|
}
|
||||||
}//end namespace drawerbase
|
}//end namespace drawerbase
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user