Merge branch 'hotfix-1.4' into develop
This commit is contained in:
@@ -442,8 +442,6 @@ namespace nana
|
||||
|
||||
bool basic_window::set_events(const std::shared_ptr<general_events>& p)
|
||||
{
|
||||
if (annex.events_ptr)
|
||||
return false;
|
||||
annex.events_ptr = p;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -626,30 +626,38 @@ namespace detail
|
||||
if(pressed_wd_space)
|
||||
break;
|
||||
|
||||
msgwnd = wd_manager.find_window(native_window, xevent.xbutton.x, xevent.xbutton.y);
|
||||
if(nullptr == msgwnd)
|
||||
break;
|
||||
|
||||
if(xevent.xbutton.button == Button4 || xevent.xbutton.button == Button5)
|
||||
{
|
||||
//The hovered window receives the message, unlike in Windows, no redirection is required.
|
||||
nana::point mspos{xevent.xbutton.x, xevent.xbutton.y};
|
||||
while(msgwnd)
|
||||
auto evt_wd = msgwnd;
|
||||
while(evt_wd)
|
||||
{
|
||||
if(msgwnd->annex.events_ptr->mouse_wheel.length() != 0)
|
||||
if(evt_wd->annex.events_ptr->mouse_wheel.length() != 0)
|
||||
{
|
||||
mspos -= msgwnd->pos_root;
|
||||
arg_wheel arg;
|
||||
arg.which = arg_wheel::wheel::vertical;
|
||||
assign_arg(arg, msgwnd, xevent);
|
||||
brock.emit(event_code::mouse_wheel, msgwnd, arg, true, &context);
|
||||
assign_arg(arg, evt_wd, xevent);
|
||||
brock.emit(event_code::mouse_wheel, evt_wd, arg, true, &context);
|
||||
break;
|
||||
}
|
||||
msgwnd = msgwnd->parent;
|
||||
evt_wd = evt_wd->parent;
|
||||
}
|
||||
|
||||
if(msgwnd && (nullptr == evt_wd))
|
||||
{
|
||||
arg_wheel arg;
|
||||
arg.which = arg_wheel::wheel::vertical;
|
||||
assign_arg(arg, msgwnd, xevent);
|
||||
draw_invoker(&drawer::mouse_wheel, msgwnd, arg, &context);
|
||||
wd_manager.do_lazy_refresh(msgwnd, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
msgwnd = wd_manager.find_window(native_window, xevent.xbutton.x, xevent.xbutton.y);
|
||||
if(nullptr == msgwnd)
|
||||
break;
|
||||
|
||||
msgwnd->set_action(mouse_action::normal);
|
||||
if(msgwnd->flags.enabled)
|
||||
{
|
||||
|
||||
@@ -1124,8 +1124,6 @@ namespace detail
|
||||
if (evt_wd->annex.events_ptr->mouse_wheel.length() != 0)
|
||||
{
|
||||
def_window_proc = false;
|
||||
nana::point mspos{ scr_pos.x, scr_pos.y };
|
||||
wd_manager.calc_window_point(evt_wd, mspos);
|
||||
|
||||
arg_wheel arg;
|
||||
arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical);
|
||||
@@ -1138,9 +1136,6 @@ namespace detail
|
||||
|
||||
if (scrolled_wd && (nullptr == evt_wd))
|
||||
{
|
||||
nana::point mspos{ scr_pos.x, scr_pos.y };
|
||||
wd_manager.calc_window_point(scrolled_wd, mspos);
|
||||
|
||||
arg_wheel arg;
|
||||
arg.which = (WM_MOUSEHWHEEL == message ? arg_wheel::wheel::horizontal : arg_wheel::wheel::vertical);
|
||||
assign_arg(arg, scrolled_wd, pmdec);
|
||||
|
||||
@@ -1714,6 +1714,11 @@ namespace detail
|
||||
wd->annex.caret_ptr = nullptr;
|
||||
}
|
||||
|
||||
using effect_renderer = detail::edge_nimbus_renderer<basic_window>;
|
||||
|
||||
//remove the window from edge nimbus effect when it is destroying
|
||||
effect_renderer::instance().erase(wd);
|
||||
|
||||
arg_destroy arg;
|
||||
arg.window_handle = reinterpret_cast<window>(wd);
|
||||
brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context());
|
||||
|
||||
@@ -498,24 +498,26 @@ namespace nana
|
||||
if(name.empty() || (name.front() == '.'))
|
||||
continue;
|
||||
|
||||
auto fpath = i->path().native();
|
||||
auto fattr = fs::status(fpath);
|
||||
|
||||
item_fs m;
|
||||
m.name = name;
|
||||
m.directory = fs::is_directory(fattr);
|
||||
|
||||
auto fattr = fs::status(path + m.name);
|
||||
|
||||
if(fattr.type() != fs::file_type::not_found && fattr.type() != fs::file_type::unknown)
|
||||
{
|
||||
m.bytes = fs::file_size(path + m.name);
|
||||
m.directory = fs::is_directory(fattr);
|
||||
fs_ext::modified_file_time(path + m.name, m.modified_time);
|
||||
}
|
||||
else
|
||||
switch(fattr.type())
|
||||
{
|
||||
case fs::file_type::not_found:
|
||||
case fs::file_type::unknown:
|
||||
case fs::file_type::directory:
|
||||
m.bytes = 0;
|
||||
m.directory = fs::is_directory(*i);
|
||||
fs_ext::modified_file_time(path + i->path().filename().native(), m.modified_time);
|
||||
break;
|
||||
default:
|
||||
m.bytes = fs::file_size(fpath);
|
||||
}
|
||||
|
||||
fs_ext::modified_file_time(fpath, m.modified_time);
|
||||
|
||||
file_container_.push_back(m);
|
||||
|
||||
if(m.directory)
|
||||
|
||||
@@ -679,6 +679,16 @@ namespace nana
|
||||
}
|
||||
};
|
||||
|
||||
struct inline_pane
|
||||
{
|
||||
::nana::panel<false> pane_bottom; //pane for pane_widget
|
||||
::nana::panel<false> pane_widget; //pane for placing user-define widget
|
||||
std::unique_ptr<inline_notifier_interface> inline_ptr;
|
||||
inline_indicator * indicator;
|
||||
index_pair item_pos; //The item index of the inline widget
|
||||
std::size_t column_pos;
|
||||
};
|
||||
|
||||
class es_lister
|
||||
{
|
||||
public:
|
||||
@@ -727,6 +737,40 @@ namespace nana
|
||||
|
||||
std::string to_string(const export_options& exp_opt) const;
|
||||
|
||||
std::vector<inline_pane*> get_inline_pane(const index_pair& item_pos)
|
||||
{
|
||||
std::vector<inline_pane*> panes;
|
||||
for (auto p : active_panes_)
|
||||
{
|
||||
if (p && (p->item_pos == item_pos))
|
||||
{
|
||||
panes.emplace_back(p);
|
||||
}
|
||||
}
|
||||
return panes;
|
||||
}
|
||||
|
||||
void emit_checked(index_pair pos)
|
||||
{
|
||||
item_proxy i(ess_, pos);
|
||||
arg_listbox arg{ i };
|
||||
wd_ptr()->events().checked.emit(arg, wd_ptr()->handle());
|
||||
|
||||
auto panes = get_inline_pane(pos);
|
||||
for (auto p : panes)
|
||||
p->inline_ptr->notify_status(inline_widget_status::checking, i.checked());
|
||||
}
|
||||
|
||||
void emit_selected(index_pair pos)
|
||||
{
|
||||
item_proxy i(ess_, pos);
|
||||
arg_listbox arg{ i };
|
||||
wd_ptr()->events().selected.emit(arg, wd_ptr()->handle());
|
||||
|
||||
auto panes = get_inline_pane(pos);
|
||||
for (auto p : panes)
|
||||
p->inline_ptr->notify_status(inline_widget_status::selecting, i.selected());
|
||||
}
|
||||
|
||||
// Definition is provided after struct essence
|
||||
unsigned column_content_pixels(size_type pos) const;
|
||||
@@ -1122,6 +1166,14 @@ namespace nana
|
||||
return get(pos.cat)->items.at(index);
|
||||
}
|
||||
|
||||
void append_active_panes(inline_pane* p)
|
||||
{
|
||||
if (nullptr == p)
|
||||
active_panes_.clear();
|
||||
else
|
||||
active_panes_.push_back(p);
|
||||
}
|
||||
|
||||
// Removes all items of a specified category
|
||||
// It throws when the category is out of range or has an immutable model.
|
||||
void clear(size_type cat)
|
||||
@@ -1453,9 +1505,7 @@ namespace nana
|
||||
if(m.flags.checked != ck)
|
||||
{
|
||||
m.flags.checked = ck;
|
||||
|
||||
arg_listbox arg{ item_proxy{ess_, pos}};
|
||||
wd_ptr()->events().checked.emit(arg, wd_ptr()->handle());
|
||||
emit_checked(pos);
|
||||
}
|
||||
++pos.item;
|
||||
}
|
||||
@@ -1480,10 +1530,15 @@ namespace nana
|
||||
|
||||
void select_display_range(index_pair fr_abs, index_pair to_dpl, bool sel)
|
||||
{
|
||||
const auto already_selected = this->pick_items(true);
|
||||
|
||||
index_pair fr_dpl (fr_abs.cat, this->display_order(fr_abs.cat, fr_abs.item));
|
||||
if (fr_dpl > to_dpl)
|
||||
std::swap(fr_dpl, to_dpl);
|
||||
|
||||
const auto begin = fr_dpl;
|
||||
const auto last = to_dpl;
|
||||
|
||||
for (; fr_dpl != to_dpl; forward(fr_dpl, 1, fr_dpl))
|
||||
{
|
||||
if (fr_dpl.is_item())
|
||||
@@ -1492,6 +1547,14 @@ namespace nana
|
||||
|
||||
if (to_dpl.is_item())
|
||||
item_proxy(ess_, index_pair(to_dpl.cat, absolute( to_dpl ) )).select(sel);
|
||||
|
||||
//Unselects the already selected which is out of range [begin, last]
|
||||
for (auto index : already_selected)
|
||||
{
|
||||
index_pair disp_order{ index.cat, this->display_order(index.cat, index.item) };
|
||||
if (begin > disp_order || disp_order > last)
|
||||
item_proxy(ess_, index_pair(index.cat, absolute(disp_order))).select(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool select_for_all(bool sel)
|
||||
@@ -1508,8 +1571,7 @@ namespace nana
|
||||
changed = true;
|
||||
m.flags.selected = sel;
|
||||
|
||||
arg_listbox arg{ item_proxy(ess_, i) };
|
||||
wd_ptr()->events().selected.emit(arg, wd_ptr()->handle());
|
||||
this->emit_selected(i);
|
||||
|
||||
if (m.flags.selected)
|
||||
last_selected_abs = i;
|
||||
@@ -1599,18 +1661,17 @@ namespace nana
|
||||
return (for_selection ? m.flags.selected : m.flags.checked);
|
||||
};
|
||||
|
||||
auto do_cancel = [this, for_selection](category_t::container::value_type& m, std::size_t cat_pos, std::size_t item_pos)
|
||||
auto do_cancel = [this, for_selection](category_t::container::value_type& m, const index_pair& item_pos)
|
||||
{
|
||||
arg_listbox arg{ item_proxy(ess_, index_pair(cat_pos, item_pos)) };
|
||||
if (for_selection)
|
||||
{
|
||||
m.flags.selected = false;
|
||||
widget_->events().selected.emit(arg, widget_->handle());
|
||||
this->emit_selected(item_pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
m.flags.checked = false;
|
||||
widget_->events().checked.emit(arg, widget_->handle());
|
||||
this->emit_checked(item_pos);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1622,7 +1683,7 @@ namespace nana
|
||||
for (auto & m : i->items)
|
||||
{
|
||||
if ((item_pos != except.item) && pred(m))
|
||||
do_cancel(m, except.cat, item_pos);
|
||||
do_cancel(m, index_pair{ except.cat, item_pos });
|
||||
|
||||
++item_pos;
|
||||
}
|
||||
@@ -1638,7 +1699,7 @@ namespace nana
|
||||
for (auto & m : cat.items)
|
||||
{
|
||||
if (pred(m))
|
||||
do_cancel(m, cat_pos, item_pos);
|
||||
do_cancel(m, index_pair{ cat_pos, item_pos });
|
||||
++item_pos;
|
||||
}
|
||||
}
|
||||
@@ -1648,7 +1709,7 @@ namespace nana
|
||||
for (auto & m : cat.items)
|
||||
{
|
||||
if ((item_pos != except.item) && pred(m))
|
||||
do_cancel(m, cat_pos, item_pos);
|
||||
do_cancel(m, index_pair{ cat_pos, item_pos });
|
||||
++item_pos;
|
||||
}
|
||||
}
|
||||
@@ -1682,18 +1743,17 @@ namespace nana
|
||||
return (for_selection ? m.flags.selected : m.flags.checked);
|
||||
};
|
||||
|
||||
auto cancel = [this, for_selection](category_t::container::value_type& m, std::size_t cat_pos, std::size_t item_pos)
|
||||
auto cancel = [this, for_selection](category_t::container::value_type& m, const index_pair& item_pos)
|
||||
{
|
||||
arg_listbox arg{ item_proxy(ess_, index_pair(cat_pos, item_pos)) };
|
||||
if (for_selection)
|
||||
{
|
||||
m.flags.selected = false;
|
||||
widget_->events().selected.emit(arg, widget_->handle());
|
||||
this->emit_selected(item_pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
m.flags.checked = false;
|
||||
widget_->events().checked.emit(arg, widget_->handle());
|
||||
this->emit_checked(item_pos);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1709,7 +1769,7 @@ namespace nana
|
||||
for (auto end = cat.items.end(); i != end; ++i)
|
||||
{
|
||||
if (pred(*i))
|
||||
cancel(*i, cat_pos, i - cat.items.begin());
|
||||
cancel(*i, index_pair{ cat_pos, static_cast<size_type>(i - cat.items.begin()) });
|
||||
}
|
||||
}
|
||||
++cat_pos;
|
||||
@@ -1732,7 +1792,7 @@ namespace nana
|
||||
for (++i; i != end; ++i)
|
||||
{
|
||||
if (pred(*i))
|
||||
cancel(*i, cat_pos, i - cat.items.begin());
|
||||
cancel(*i, index_pair{ cat_pos, static_cast<std::size_t>(i - cat.items.begin()) });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1744,7 +1804,7 @@ namespace nana
|
||||
for (auto & m : cat.items)
|
||||
{
|
||||
if (pred(m))
|
||||
cancel(m, cat_pos, item_pos);
|
||||
cancel(m, index_pair{ cat_pos, item_pos });
|
||||
|
||||
++item_pos;
|
||||
}
|
||||
@@ -1791,10 +1851,7 @@ namespace nana
|
||||
if(m.flags.checked != ck)
|
||||
{
|
||||
m.flags.checked = ck;
|
||||
|
||||
arg_listbox arg{ item_proxy(ess_, index_pair(cat, index)) };
|
||||
wd_ptr()->events().checked.emit(arg, widget_->handle());
|
||||
|
||||
this->emit_checked(index_pair{cat, index});
|
||||
changed = true;
|
||||
}
|
||||
++index;
|
||||
@@ -2050,7 +2107,7 @@ namespace nana
|
||||
return i;
|
||||
}
|
||||
public:
|
||||
index_pair last_selected_abs, last_selected_dpl;
|
||||
index_pair last_selected_abs;
|
||||
private:
|
||||
essence * ess_{nullptr};
|
||||
nana::listbox * widget_{nullptr};
|
||||
@@ -2065,6 +2122,8 @@ namespace nana
|
||||
bool single_selection_category_limited_{ false };
|
||||
bool single_check_{ false };
|
||||
bool single_check_category_limited_{ false };
|
||||
|
||||
std::vector<inline_pane*> active_panes_;
|
||||
};//end class es_lister
|
||||
|
||||
|
||||
@@ -2108,17 +2167,6 @@ namespace nana
|
||||
}scroll;
|
||||
|
||||
|
||||
struct inline_pane
|
||||
{
|
||||
::nana::panel<false> pane_bottom; //pane for pane_widget
|
||||
::nana::panel<false> pane_widget; //pane for placing user-define widget
|
||||
std::unique_ptr<inline_notifier_interface> inline_ptr;
|
||||
inline_indicator * indicator;
|
||||
index_pair item_pos; //The item index of the inline widget
|
||||
std::size_t column_pos;
|
||||
::std::string text; //text in UTF-8 encoded
|
||||
};
|
||||
|
||||
std::map<pat::detail::abstract_factory_base*, std::deque<std::unique_ptr<inline_pane>>> inline_table, inline_buffered_table;
|
||||
|
||||
essence()
|
||||
@@ -2963,8 +3011,8 @@ namespace nana
|
||||
: ess_{ ess }, column_pos_{column_pos}
|
||||
{
|
||||
}
|
||||
|
||||
void attach(index_type pos, essence::inline_pane* pane)
|
||||
|
||||
void attach(index_type pos, inline_pane* pane)
|
||||
{
|
||||
for (auto & pn : panes_)
|
||||
{
|
||||
@@ -2988,6 +3036,11 @@ namespace nana
|
||||
return *ess_->lister.wd_ptr();
|
||||
}
|
||||
|
||||
std::size_t column() const override
|
||||
{
|
||||
return column_pos_;
|
||||
}
|
||||
|
||||
void modify(index_type pos, const value_type& value) const override
|
||||
{
|
||||
ess_->lister.throw_if_immutable_model(pos);
|
||||
@@ -3000,15 +3053,6 @@ namespace nana
|
||||
|
||||
if (cells[column_pos_].text != value)
|
||||
{
|
||||
for (auto & pn : panes_)
|
||||
{
|
||||
if (pn.first == pos)
|
||||
{
|
||||
pn.second->text = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cells[column_pos_].text = value;
|
||||
|
||||
if (model_cells.size())
|
||||
@@ -3040,7 +3084,7 @@ namespace nana
|
||||
private:
|
||||
essence * const ess_;
|
||||
const std::size_t column_pos_;
|
||||
std::vector<std::pair<index_type, essence::inline_pane*>> panes_;
|
||||
std::vector<std::pair<index_type, inline_pane*>> panes_;
|
||||
};
|
||||
|
||||
void es_lister::scroll(const index_pair& pos, bool to_bottom)
|
||||
@@ -3116,7 +3160,7 @@ namespace nana
|
||||
|
||||
void es_lister::move_select(bool upwards, bool unselect_previous, bool trace_selected)
|
||||
{
|
||||
auto next_selected_dpl = relative_pair ( last_selected_abs); // last_selected_dpl; // ??
|
||||
auto next_selected_dpl = relative_pair ( last_selected_abs);
|
||||
if (next_selected_dpl.empty()) // has no cat ? (cat == npos) => beging from first cat
|
||||
{
|
||||
bool good = false;
|
||||
@@ -3237,7 +3281,7 @@ namespace nana
|
||||
if (it.selected() != sel)
|
||||
it.select(sel);
|
||||
}
|
||||
last_selected_abs = last_selected_dpl = index_pair{cat, npos};
|
||||
last_selected_abs = index_pair{cat, npos};
|
||||
}
|
||||
|
||||
class drawer_header_impl
|
||||
@@ -3520,15 +3564,19 @@ namespace nana
|
||||
public:
|
||||
using item_state = essence::item_state;
|
||||
using parts = essence::parts;
|
||||
using status_type = inline_notifier_interface::status_type;
|
||||
|
||||
drawer_lister_impl(essence * es)
|
||||
:essence_(es)
|
||||
{}
|
||||
|
||||
void draw(const nana::rectangle& rect) const
|
||||
void draw(const nana::rectangle& rect)
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
|
||||
//clear active panes
|
||||
essence_->lister.append_active_panes(nullptr);
|
||||
|
||||
//The count of items to be drawn
|
||||
auto item_count = essence_->number_of_lister_items(true);
|
||||
if (0 == item_count)
|
||||
@@ -3711,7 +3759,7 @@ namespace nana
|
||||
nana::color bgcolor,
|
||||
nana::color fgcolor,
|
||||
item_state state
|
||||
) const
|
||||
)
|
||||
{
|
||||
auto & item = cat.items[item_pos.item];
|
||||
|
||||
@@ -3825,35 +3873,31 @@ namespace nana
|
||||
else
|
||||
visible_state = false;
|
||||
|
||||
::nana::size sz{ wdg_w, essence_->scheme_ptr->item_height };
|
||||
inline_wdg->pane_widget.size(sz);
|
||||
inline_wdg->inline_ptr->resize(sz);
|
||||
|
||||
draw_column = inline_wdg->inline_ptr->whether_to_draw();
|
||||
|
||||
inline_wdg->item_pos = item_pos;
|
||||
inline_wdg->column_pos = column_pos;
|
||||
inline_wdg->inline_ptr->activate(*inline_wdg->indicator, item_pos);
|
||||
|
||||
::nana::size sz{ wdg_w, essence_->scheme_ptr->item_height };
|
||||
inline_wdg->pane_widget.size(sz);
|
||||
inline_wdg->inline_ptr->resize(sz);
|
||||
|
||||
inline_wdg->inline_ptr->notify_status(status_type::selected, item.flags.selected);
|
||||
inline_wdg->inline_ptr->notify_status(status_type::checked, item.flags.checked);
|
||||
|
||||
inline_wdg->indicator->attach(item_pos, inline_wdg);
|
||||
|
||||
//To reduce the memory usage, the cells may not be allocated
|
||||
if (cells.size() > column_pos)
|
||||
{
|
||||
auto & text = cells[column_pos].text;
|
||||
if (text != inline_wdg->text)
|
||||
{
|
||||
inline_wdg->text = text;
|
||||
inline_wdg->inline_ptr->set(text);
|
||||
}
|
||||
}
|
||||
inline_wdg->inline_ptr->set(cells[column_pos].text);
|
||||
else
|
||||
{
|
||||
inline_wdg->text.clear();
|
||||
inline_wdg->inline_ptr->set({});
|
||||
}
|
||||
|
||||
API::show_window(inline_wdg->pane_bottom, visible_state);
|
||||
|
||||
essence_->lister.append_active_panes(inline_wdg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3903,18 +3947,20 @@ namespace nana
|
||||
_m_draw_border(content_r.x, y, show_w);
|
||||
}
|
||||
|
||||
essence::inline_pane * _m_get_inline_pane(const category_t& cat, std::size_t column_pos) const
|
||||
inline_pane * _m_get_inline_pane(const category_t& cat, std::size_t column_pos) const
|
||||
{
|
||||
if (column_pos < cat.factories.size())
|
||||
{
|
||||
auto & factory = cat.factories[column_pos];
|
||||
if (factory)
|
||||
{
|
||||
return essence_->open_inline(factory.get(), cat.indicators[column_pos].get());
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
essence::inline_pane* _m_find_inline_pane(const index_pair& pos, std::size_t column_pos) const
|
||||
inline_pane* _m_find_inline_pane(const index_pair& pos, std::size_t column_pos) const
|
||||
{
|
||||
auto & cat = *essence_->lister.get(pos.cat);
|
||||
|
||||
@@ -4151,7 +4197,18 @@ namespace nana
|
||||
if (!lister.single_selection())
|
||||
{
|
||||
if (arg.shift)
|
||||
lister.select_display_range(lister.last_selected_abs , item_pos, sel);
|
||||
{
|
||||
//Set the first item as the begin of selected item if there
|
||||
//is not a last selected item.(#154 reported by RenaudAlpes)
|
||||
if (lister.last_selected_abs.empty() || lister.last_selected_abs.is_category())
|
||||
lister.last_selected_abs.set_both(0);
|
||||
|
||||
auto before = lister.last_selected_abs;
|
||||
|
||||
lister.select_display_range(lister.last_selected_abs, item_pos, sel);
|
||||
|
||||
lister.last_selected_abs = before;
|
||||
}
|
||||
else if (arg.ctrl)
|
||||
sel = !item_proxy(essence_, abs_item_pos).selected();
|
||||
else
|
||||
@@ -4167,19 +4224,20 @@ namespace nana
|
||||
|
||||
if(item_ptr)
|
||||
{
|
||||
item_ptr->flags.selected = sel;
|
||||
|
||||
arg_listbox arg{ item_proxy{ essence_, abs_item_pos } };
|
||||
lister.wd_ptr()->events().selected.emit(arg, lister.wd_ptr()->handle());
|
||||
|
||||
if (item_ptr->flags.selected)
|
||||
if (item_ptr->flags.selected != sel)
|
||||
{
|
||||
lister.cancel_others_if_single_enabled(true, abs_item_pos);
|
||||
essence_->lister.last_selected_abs = abs_item_pos;
|
||||
item_ptr->flags.selected = sel;
|
||||
|
||||
lister.emit_selected(abs_item_pos);
|
||||
|
||||
if (item_ptr->flags.selected)
|
||||
{
|
||||
lister.cancel_others_if_single_enabled(true, abs_item_pos);
|
||||
essence_->lister.last_selected_abs = abs_item_pos;
|
||||
}
|
||||
else if (essence_->lister.last_selected_abs == abs_item_pos)
|
||||
essence_->lister.last_selected_abs.set_both(npos);
|
||||
}
|
||||
else if (essence_->lister.last_selected_abs == abs_item_pos)
|
||||
essence_->lister.last_selected_abs.set_both(npos);
|
||||
}
|
||||
else if(!lister.single_selection())
|
||||
lister.categ_selected(item_pos.cat, true);
|
||||
@@ -4190,8 +4248,7 @@ namespace nana
|
||||
{
|
||||
item_ptr->flags.checked = ! item_ptr->flags.checked;
|
||||
|
||||
arg_listbox arg{ item_proxy{ essence_, abs_item_pos } };
|
||||
lister.wd_ptr()->events().checked.emit(arg, lister.wd_ptr()->handle());
|
||||
lister.emit_checked(abs_item_pos);
|
||||
|
||||
if (item_ptr->flags.checked)
|
||||
lister.cancel_others_if_single_enabled(false, abs_item_pos);
|
||||
@@ -4456,12 +4513,13 @@ namespace nana
|
||||
|
||||
item_proxy & item_proxy::check(bool ck)
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
auto & m = cat_->items.at(pos_.item);
|
||||
if(m.flags.checked != ck)
|
||||
{
|
||||
m.flags.checked = ck;
|
||||
arg_listbox arg{*this};
|
||||
ess_->lister.wd_ptr()->events().checked.emit(arg, ess_->lister.wd_ptr()->handle());
|
||||
ess_->lister.emit_checked(pos_);
|
||||
|
||||
ess_->update();
|
||||
}
|
||||
return *this;
|
||||
@@ -4475,13 +4533,14 @@ namespace nana
|
||||
/// is ignored if no change (maybe set last_selected anyway??), but if change emit event, deselect others if need ans set/unset last_selected
|
||||
item_proxy & item_proxy::select(bool s)
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
|
||||
//pos_ never represents a category if this item_proxy is available.
|
||||
auto & m = cat_->items.at(pos_.item); // a ref to the real item
|
||||
if(m.flags.selected == s) return *this; // ignore if no change
|
||||
m.flags.selected = s; // actually change selection
|
||||
|
||||
arg_listbox arg{*this};
|
||||
ess_->lister.wd_ptr()->events().selected.emit(arg, ess_->lister.wd_ptr()->handle());
|
||||
ess_->lister.emit_selected(this->pos_);
|
||||
|
||||
if (m.flags.selected)
|
||||
{
|
||||
@@ -4750,10 +4809,11 @@ namespace nana
|
||||
for (item_proxy &it : *this )
|
||||
it.select(sel);
|
||||
|
||||
ess_->lister.last_selected_abs = ess_->lister.last_selected_dpl = index_pair {this->pos_, npos};
|
||||
ess_->lister.last_selected_abs = index_pair {this->pos_, npos};
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool cat_proxy::selected() const
|
||||
{
|
||||
for (item_proxy &it : *this )
|
||||
|
||||
@@ -441,6 +441,9 @@ namespace nana{ namespace widgets
|
||||
text_ptr = &mask_str;
|
||||
}
|
||||
|
||||
if (pos.x > text_ptr->size())
|
||||
pos.x = text_ptr->size();
|
||||
|
||||
pos.x = editor_._m_pixels_by_char(*text_ptr, pos.x) + editor_.text_area_.area.x;
|
||||
int pos_y = static_cast<int>((pos.y - editor_.points_.offset.y) * editor_.line_height() + editor_._m_text_top_base());
|
||||
|
||||
@@ -1990,20 +1993,22 @@ namespace nana{ namespace widgets
|
||||
|
||||
//move_caret
|
||||
//Set caret position through text coordinate
|
||||
void text_editor::move_caret(const upoint& crtpos)
|
||||
{
|
||||
if (!API::is_focus_ready(window_))
|
||||
return;
|
||||
|
||||
bool text_editor::move_caret(const upoint& crtpos, bool reset_caret)
|
||||
{
|
||||
const unsigned line_pixels = line_height();
|
||||
auto pos = impl_->capacities.behavior->caret_to_screen(crtpos);
|
||||
const int line_bottom = pos.y + static_cast<int>(line_pixels);
|
||||
|
||||
if (reset_caret)
|
||||
points_.caret = this->impl_->capacities.behavior->screen_to_caret(pos);
|
||||
|
||||
if (!API::is_focus_ready(window_))
|
||||
return false;
|
||||
|
||||
auto caret = API::open_caret(window_, true);
|
||||
|
||||
auto text_area = _m_text_area();
|
||||
|
||||
bool visible = false;
|
||||
auto text_area = _m_text_area();
|
||||
if (text_area.is_hit(pos) && (line_bottom > text_area.y))
|
||||
{
|
||||
visible = true;
|
||||
@@ -2019,6 +2024,16 @@ namespace nana{ namespace widgets
|
||||
caret->visible(visible);
|
||||
if(visible)
|
||||
caret->position(pos);
|
||||
|
||||
//Adjust the caret into screen when the caret position is modified by this function
|
||||
if (reset_caret && (!hit_text_area(pos)))
|
||||
{
|
||||
impl_->capacities.behavior->adjust_caret_into_screen();
|
||||
render(true);
|
||||
caret->visible(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void text_editor::move_caret_end()
|
||||
@@ -2507,6 +2522,11 @@ namespace nana{ namespace widgets
|
||||
_m_scrollbar();
|
||||
}
|
||||
|
||||
void text_editor::set_undo_queue_length(std::size_t len)
|
||||
{
|
||||
impl_->undo.max_steps(len);
|
||||
}
|
||||
|
||||
void text_editor::move_ns(bool to_north)
|
||||
{
|
||||
const bool redraw_required = _m_cancel_select(0);
|
||||
|
||||
@@ -345,8 +345,8 @@ namespace drawerbase {
|
||||
{
|
||||
auto editor = get_drawer_trigger().editor();
|
||||
internal_scope_guard lock;
|
||||
if (editor)
|
||||
editor->move_caret(pos);
|
||||
if (editor && editor->move_caret(pos, true))
|
||||
API::refresh_window(handle());
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -628,6 +628,14 @@ namespace drawerbase {
|
||||
editor->select_behavior(move_to_end);
|
||||
}
|
||||
|
||||
void textbox::set_undo_queue_length(std::size_t len)
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
auto editor = get_drawer_trigger().editor();
|
||||
if (editor)
|
||||
editor->set_undo_queue_length(len);
|
||||
}
|
||||
|
||||
//Override _m_caption for caption()
|
||||
auto textbox::_m_caption() const throw() -> native_string_type
|
||||
{
|
||||
|
||||
@@ -382,12 +382,6 @@ namespace nana
|
||||
}
|
||||
|
||||
//class widget_base
|
||||
widget_base::~widget_base()
|
||||
{
|
||||
if (handle_)
|
||||
API::close_window(handle_);
|
||||
}
|
||||
|
||||
window widget_base::handle() const
|
||||
{
|
||||
return handle_;
|
||||
|
||||
Reference in New Issue
Block a user