13
0

DndVBox: implement drag-refuse and drag move action

This commit is contained in:
Robin Gareus 2024-11-19 04:28:59 +01:00
parent 4687a5a886
commit 4a966d5015
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04

View File

@ -62,8 +62,9 @@ template <class T>
class /*LIBGTKMM2EXT_API*/ DnDVBox : public Gtk::EventBox class /*LIBGTKMM2EXT_API*/ DnDVBox : public Gtk::EventBox
{ {
public: public:
DnDVBox (std::list<Gtk::TargetEntry> targets) DnDVBox (std::list<Gtk::TargetEntry> targets, Gdk::DragAction actions = Gdk::ACTION_COPY)
: _targets (targets) : _targets (targets)
, _actions (actions)
, _active (0) , _active (0)
, _drag_icon (0) , _drag_icon (0)
, _expecting_unwanted_button_event (false) , _expecting_unwanted_button_event (false)
@ -85,7 +86,7 @@ public:
_internal_vbox.show (); _internal_vbox.show ();
drag_dest_set (_targets); drag_dest_set (_targets, Gtk::DEST_DEFAULT_ALL, _actions);
signal_drag_data_received().connect (mem_fun (*this, &DnDVBox::drag_data_received)); signal_drag_data_received().connect (mem_fun (*this, &DnDVBox::drag_data_received));
} }
@ -100,9 +101,9 @@ public:
void add_child (T* child, std::list<Gtk::TargetEntry> targets = std::list<Gtk::TargetEntry>()) void add_child (T* child, std::list<Gtk::TargetEntry> targets = std::list<Gtk::TargetEntry>())
{ {
if (targets.empty ()) { if (targets.empty ()) {
child->action_widget().drag_source_set (_targets); child->action_widget().drag_source_set (_targets, Gdk::MODIFIER_MASK, _actions);
} else { } else {
child->action_widget().drag_source_set (targets); child->action_widget().drag_source_set (targets, Gdk::MODIFIER_MASK, _actions);
} }
child->action_widget().signal_drag_begin().connect (sigc::bind (mem_fun (*this, &DnDVBox::drag_begin), child)); child->action_widget().signal_drag_begin().connect (sigc::bind (mem_fun (*this, &DnDVBox::drag_begin), child));
child->action_widget().signal_drag_data_get().connect (sigc::bind (mem_fun (*this, &DnDVBox::drag_data_get), child)); child->action_widget().signal_drag_data_get().connect (sigc::bind (mem_fun (*this, &DnDVBox::drag_data_get), child));
@ -255,6 +256,8 @@ public:
sigc::signal<void> SelectionChanged; sigc::signal<void> SelectionChanged;
sigc::signal<void,T&> SelectionAdded; sigc::signal<void,T&> SelectionAdded;
sigc::signal<bool, DnDVBox*, T*> DragRefuse;
private: private:
/** @return the bottom y position of a child, pretending any placeholder /** @return the bottom y position of a child, pretending any placeholder
@ -478,6 +481,13 @@ private:
bool top_half = (c - int (c)) < .5; bool top_half = (c - int (c)) < .5;
bool bottom_half = !top_half; bool bottom_half = !top_half;
if (_drag_source != this) {
if (DragRefuse (_drag_source, at)) {
ctx->drag_refuse (tme);
return true;
}
}
if (_drag_source != this /* re-order */ if (_drag_source != this /* re-order */
&& _drag_source && at && _drag_source && at
&& _drag_source->_drag_child && _drag_source->_drag_child
@ -512,7 +522,7 @@ private:
if (_drag_source == this /* re-order */) { if (_drag_source == this /* re-order */) {
ctx->drag_status (Gdk::ACTION_MOVE, tme); ctx->drag_status (Gdk::ACTION_MOVE, tme);
} else { } else {
ctx->drag_status (Gdk::ACTION_COPY, tme); ctx->drag_status (ctx->get_suggested_action (), tme);
} }
} else { } else {
ctx->drag_status (Gdk::ACTION_LINK, tme); ctx->drag_status (Gdk::ACTION_LINK, tme);
@ -664,6 +674,7 @@ private:
Gtk::VBox _internal_vbox; Gtk::VBox _internal_vbox;
std::list<Gtk::TargetEntry> _targets; std::list<Gtk::TargetEntry> _targets;
Gdk::DragAction _actions;
std::list<T*> _children; std::list<T*> _children;
std::list<T*> _selection; std::list<T*> _selection;
T* _active; T* _active;