init dragdrop

contains a new class simple_dragdrop and changes of listbox for dragdrop
This commit is contained in:
Jinhao
2018-10-09 03:56:50 +08:00
parent 95ccc3cb7e
commit 943a9e444d
17 changed files with 812 additions and 19 deletions

View File

@@ -1968,6 +1968,12 @@ namespace nana
std::vector<inline_pane*> active_panes_;
};//end class es_lister
enum class operation_states
{
none,
msup_deselect
};
/// created and live by the trigger, holds data for listbox: the state of the struct does not effect on member funcions, therefore all data members are public.
struct essence
@@ -1981,7 +1987,9 @@ 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;
@@ -1999,6 +2007,12 @@ namespace nana
std::function<void(paint::graphics&, const rectangle&, bool)> ctg_icon_renderer; ///< Renderer for the category icon
struct operation_rep
{
operation_states state{operation_states::none};
index_pair item;
}operation;
struct mouse_selection_part
{
bool started{ false };
@@ -2121,6 +2135,10 @@ namespace nana
void update_mouse_selection(const point& screen_pos)
{
//Don't update if it is not started
if (!mouse_selection.started)
return;
mouse_selection.screen_pos = screen_pos;
auto logic_pos = coordinate_cast(screen_pos, true);
@@ -4132,8 +4150,13 @@ 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)
essence_->operation.state = operation_states::none;
#endif
bool need_refresh = false;
@@ -4293,21 +4316,44 @@ 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
{
if (nana::mouse::right_button == arg.button)
//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);
if (selected.cend() != std::find(selected.cbegin(), selected.cend(), item_pos))
{
//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);
//If the current selected one has been selected before selecting, remains the selection states for all
//selected items. But these items will be unselected when the mouse is released.
//Other items will be unselected if multiple items are selected.
if (selected.size() > 1)
{
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;
}
}
else
{
//Unselects all selected items except current item if right button clicked.
lister.select_for_all(false, abs_item_pos); //cancel all selections
}
lister.select_for_all(false, abs_item_pos);
}
#endif
}
else
{
@@ -4377,7 +4423,15 @@ 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)
@@ -4419,11 +4473,19 @@ 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;
need_refresh |= essence_->lister.select_for_all(false, essence_->operation.item);
}
if (need_refresh)
{
@@ -5790,6 +5852,18 @@ namespace nana
return item_proxy(ess);
}
listbox::index_pair listbox::hovered() const
{
internal_scope_guard lock;
using parts = drawerbase::listbox::essence::parts;
auto & ptr_where = _m_ess().pointer_where;
if ((ptr_where.first == parts::list || ptr_where.first == parts::checker) && ptr_where.second != npos)
return _m_ess().lister.advance(_m_ess().first_display(), static_cast<int>(ptr_where.second));
return index_pair{ npos, npos };
}
bool listbox::sortable() const
{
internal_scope_guard lock;

View File

@@ -65,7 +65,7 @@ namespace nana {
bool passive{ true }; //The passive mode determines whether to update if scrollbar changes. It updates the client window if passive is true.
bool drag_started{ false };
bool drag_view_move{ false }; //indicates the status of the content-view if it moves origin by dragging
point origin;
std::shared_ptr<cv_scroll_rep> cv_scroll;
@@ -120,19 +120,22 @@ namespace nana {
if (!arg.is_left_button())
return;
this->drag_started = this->view.view_area().is_hit(arg.pos);
this->drag_view_move = this->view.view_area().is_hit(arg.pos);
}
else if (event_code::mouse_move == arg.evt_code)
{
if (this->drag_started && this->drive(arg.pos))
if (this->drag_view_move && (dragdrop_status::not_ready == API::window_dragdrop_status(this->window_handle)))
{
tmr.interval(16);
tmr.start();
if (this->drive(arg.pos))
{
tmr.interval(16);
tmr.start();
}
}
}
else if (event_code::mouse_up == arg.evt_code)
{
this->drag_started = false;
this->drag_view_move = false;
tmr.stop();
}
};