public void Lift(ItemInstanceView original, bool half = false)
        {
            _originalLiftedItem = original;
            _clonedLiftedItem   = Instantiate(_originalLiftedItem).GetComponent <ItemInstanceView>();
            _clonedLiftedItem._canvasGroup.blocksRaycasts = false;
            _clonedLiftedItem._canvasGroup.interactable   = false;
            _clonedLiftedItem.SetItem(new ItemInstance(_originalLiftedItem.Item));
            var clonedRect = _clonedLiftedItem.GetComponent <RectTransform>();

            clonedRect.sizeDelta = new Vector2(64, 64); // todo; hacky
            clonedRect.pivot     = Vector2.one / 2f;

            int amount = _originalLiftedItem.Item.Quantity.Value;

            if (_singleMode)
            {
                amount = 1;
            }
            else if (half)
            {
                amount = Mathf.Max(1, _originalLiftedItem.Item.Quantity.Value / 2);
            }
            Lift(amount);
            original._canvasGroup.alpha = 0.33f;
            _clonedLiftedItem.transform.SetParent(_mainCanvas);
            _clonedLiftedItem.transform.localScale = Vector3.one;
            var rect = _clonedLiftedItem.transform as RectTransform;

            rect.anchorMin = new Vector2(0.5f, 0.5f);
            rect.anchorMax = new Vector2(0.5f, 0.5f);
            MoveRectToMouse(rect);

            _lifting = true;
            Observable.EveryUpdate().TakeWhile((x) => _lifting).Subscribe(x =>
            {
                MoveRectToMouse(rect);
            });
        }
        private void Lift(int amount)
        {
            var amountLeft = _originalLiftedItem.Item.Quantity.Value - amount;

            _originalLiftedItem.Item.Set(amountLeft);
            _clonedLiftedItem.Item.Set(amount);
            OnCancel = () =>
            {
                _originalLiftedItem.Item.ItemType.Value = _clonedLiftedItem.Item.ItemType.Value;
                _originalLiftedItem.Item.Quantity.Value = _originalLiftedItem.Item.Quantity.Value + _clonedLiftedItem.Item.Quantity.Value;
                CancelLift();
            };
            Action <ItemInstance> move = (target) =>
            {
                // merging
                if (target.ItemType.Value == _clonedLiftedItem.Item.ItemType.Value)
                {
                    var overflow = target.Add(_clonedLiftedItem.Item.Quantity.Value);
                    if (overflow > 0)
                    {
                        _originalLiftedItem.SetItem(new ItemInstance(_clonedLiftedItem.Item.ItemType.Value, overflow));
                    }
                    FinishLift();
                }
                // there is still something in the original stack, cloned stack and target stack. We are lifting a portion, you can't put that in the target stack then
                else if (!_originalLiftedItem.IsEmpty && !_clonedLiftedItem.IsEmpty && !target.IsEmpty)
                {
                    OnCancel();
                }
                // most common case, lifting a full stack onto another item
                else
                {
                    var  targetBefore = new ItemInstance(target);
                    bool success      = target.CanMove(_clonedLiftedItem.Item) && _originalLiftedItem.CanMove(targetBefore);
                    if (success)
                    {
                        target.Set(_clonedLiftedItem.Item);
                        if (_originalLiftedItem.IsEmpty)
                        {
                            _originalLiftedItem.Item.Set(targetBefore);
                        }
                        FinishLift();
                    }
                    else
                    {
                        OnCancel();
                    }
                }
            };

            OnTryLiftEnd = (targetView) =>
            {
                var canMove = targetView.CanMove(_clonedLiftedItem.Item);
                if (canMove)
                {
                    move(targetView.Item);
                }
                else
                {
                    OnCancel();
                }
            };
            OnComplete = (item) =>
            {
                move(item);
            };
        }