From f6912f4241a2dd13d987d27a073a3b76faf2cb7d Mon Sep 17 00:00:00 2001
From: Craig Robbins <kde.psych@gmail.com>
Date: Thu, 9 Oct 2014 17:53:20 +1000
Subject: [PATCH] Right mouse button behaviour for craft/inventory If right
 mousebutton clicked once then don't drop single items into slots. If right
 mouse button has been clicked and held a second time, drop items as the mouse
 is moved. In the second case (automatically drop/place items as mouse is
 moved) only auto-drop into blank slots, or slots that contain the same item.

---
 src/guiFormSpecMenu.cpp | 20 +++++++++++++++++++-
 src/guiFormSpecMenu.h   |  2 ++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp
index 0a7a82399..883228820 100644
--- a/src/guiFormSpecMenu.cpp
+++ b/src/guiFormSpecMenu.cpp
@@ -124,6 +124,7 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
 	m_tooltip_element(NULL),
 	m_hovered_time(0),
 	m_old_tooltip_id(-1),
+	m_rmouse_auto_place(false),
 	m_allowclose(true),
 	m_lock(false),
 	m_form_src(fsrc),
@@ -3153,6 +3154,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
 						m_selected_amount = s_count;
 
 					m_selected_dragging = true;
+					m_rmouse_auto_place = false;
 				}
 			}
 			else { // m_selected_item != NULL
@@ -3205,6 +3207,11 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
 			}
 
 			m_selected_dragging = false;
+			// Keep count of how many times right mouse button has been
+			// clicked. One click is drag without dropping. Click + release
+			// + click changes to drop one item when moved mode
+			if(button == 1 && m_selected_item != NULL)
+				m_rmouse_auto_place = !m_rmouse_auto_place;
 		}
 		else if(updown == -1) {
 			// Mouse has been moved and rmb is down and mouse pointer just
@@ -3213,7 +3220,18 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
 			if(m_selected_item != NULL && s.isValid()){
 				// Move 1 item
 				// TODO: middle mouse to move 10 items might be handy
-				move_amount = 1;
+				if (m_rmouse_auto_place) {
+					// Only move an item if the destination slot is empty
+					// or contains the same item type as what is going to be
+					// moved
+					InventoryList *list_from = inv_selected->getList(m_selected_item->listname);
+					InventoryList *list_to = inv_s->getList(s.listname);
+					assert(list_from && list_to);
+					ItemStack stack_from = list_from->getItem(m_selected_item->i);
+					ItemStack stack_to = list_to->getItem(s.i);
+					if (stack_to.empty() || stack_to.name == stack_from.name)
+						move_amount = 1;
+				}
 			}
 		}
 
diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h
index 455aeaab8..6d6c07453 100644
--- a/src/guiFormSpecMenu.h
+++ b/src/guiFormSpecMenu.h
@@ -328,6 +328,8 @@ class GUIFormSpecMenu : public GUIModalMenu
 	s32 m_old_tooltip_id;
 	std::string m_old_tooltip;
 
+	bool m_rmouse_auto_place;
+
 	bool m_allowclose;
 	bool m_lock;
 	v2u32 m_lockscreensize;
-- 
GitLab