Пример #1
0
        private void TableKeyDown(object source, TableKeyEventArgs te)
        {
            try
            {
                // Fix: keyboard shortcuts are forbidden during a DnD
                if (_isDragging)
                {
                    te.Handled = te.KeyEventArgs.Handled = true;
                    return;
                }

                KeyEventArgs e = te.KeyEventArgs;
                switch (e.Key)
                {
                case Key.PageUp:
                    Program.GameEngine.Table.BringToFront(Card);
                    e.Handled = te.Handled = true;
                    break;

                case Key.PageDown:
                    Program.GameEngine.Table.SendToBack(Card);
                    e.Handled = te.Handled = true;
                    break;

                case Key.P:
                    if (e.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Control) && !Card.FaceUp)
                    {
                        if (Card != null)
                        {
                            Card.Peek();
                        }
                        break;
                    }
                    goto default;

                default:
                    // Look for a custom shortcut in the game definition
                    ActionShortcut[] shortcuts = Card.Group.CardShortcuts;
                    ActionShortcut   match     =
                        shortcuts.FirstOrDefault(shortcut => shortcut.Key.Matches(this, te.KeyEventArgs));
                    if (match != null && Card.Group.CanManipulate())
                    {
                        // Look for cards to execute it upon, shortcuts are applied to selection first
                        IEnumerable <Card> targets;
                        if (!Selection.IsEmpty())
                        {
                            targets = Selection.Cards;
                        }
                        else if (Card.CanManipulate())
                        {
                            targets = Selection.ExtendToSelection(Card);
                        }
                        else
                        {
                            break;
                        }
                        // If the card is on the table, extract the cursor position
                        Point?pos = GroupControl is TableControl
                                             ? ((TableControl)GroupControl).MousePosition()
                                             : (Point?)null;
                        if (match.ActionDef.AsAction().Execute != null)
                        {
                            ScriptEngine.ExecuteOnCards(match.ActionDef.AsAction().Execute, targets, pos);
                        }
                        else if (match.ActionDef.AsAction().BatchExecute != null)
                        {
                            ScriptEngine.ExecuteOnBatch(match.ActionDef.AsAction().BatchExecute, targets, pos);
                        }
                        e.Handled = te.Handled = true;
                        break;
                    }

                    // Look for a "Move to" shortcut
                    Group group =
                        Player.LocalPlayer.Groups.FirstOrDefault(
                            g => g.MoveToShortcut != null && g.MoveToShortcut.Matches(this, te.KeyEventArgs));
                    bool toBottom = false;
                    // If no group is found, try to match a shortcut with "Alt" and use it as "Move to bottom"
                    if (group == null)
                    {
                        group =
                            Player.LocalPlayer.Groups.FirstOrDefault(
                                g =>
                                g.MoveToShortcut != null &&
                                new KeyGesture(g.MoveToShortcut.Key, g.MoveToShortcut.Modifiers | ModifierKeys.Alt).
                                Matches(this, te.KeyEventArgs));
                        if (group is Pile)
                        {
                            toBottom = true;
                        }
                    }
                    if (group != null && group.CanManipulate())
                    {
                        Action <Card> moveAction = toBottom
                                                          ? (c => c.MoveTo(@group, true, @group.Count))
                                                          : new Action <Card>(c => c.MoveTo(group, true));
                        if (!Selection.IsEmpty())
                        {
                            Selection.ForEachModifiable(moveAction);
                        }
                        else if (count.IsMouseOver)
                        {
                            for (int i = MultipleCards.Count - 1; i >= 0; --i)
                            {
                                var c = (Card)MultipleCards[i];
                                if (c.CanManipulate())
                                {
                                    moveAction(c);
                                }
                            }
                        }
                        else if (Card.CanManipulate())
                        {
                            moveAction(Card);
                        }
                        else
                        {
                            break;
                        }
                        e.Handled = te.Handled = true;
                        break;
                    }
                    break;
                }
            }
            catch (Exception e)
            {
                Log.Warn("TableKeyDown Error", e);
            }
        }
Пример #2
0
        protected void DragCardStarted()
        {
            DraggedCards.Clear();
            // in theory draggedCards should already be empty, but it's better to recover if there was a problem during last DnD
            if (!Selection.IsEmpty())
            {
                DraggedCards.AddRange(Selection.Cards);
            }
            else if (_isOverCount)
            {
                DraggedCards.AddRange(MultipleCards.Cast <Card>());
            }
            else if (Card != null)
            {
                DraggedCards.Add(Card);
            }
            else
            {
                return;
            }
            // Fix: Card == null can occur, e.g. hold the mouse down but don't move, dismiss the card with a keyboard shortcut (e.g. Delete) and move the mouse after that (with the left button still down).

            _isDragging = true;

            // Keep control of the card and the group it's in
            foreach (Card c in DraggedCards)
            {
                c.KeepControl();
            }
            Card.Group.KeepControl();

            // Hides the card view
            RaiseEvent(new CardEventArgs(CardHoveredEvent, this));

            // Starts the drag-and-drop
            ScaleFactor = TransformToAncestor(_mainWin).TransformBounds(new Rect(0, 0, 1, 1)).Size;
            //bool rot90 = (Card.Orientation & CardOrientation.Rot90) != 0;
            _mouseOffset =
                new Vector(_mousePt.X * Program.GameEngine.Definition.CardWidth / ActualWidth,
                           _mousePt.Y * Program.GameEngine.Definition.CardHeight / ActualHeight);

            // Create adorners
            var          mwn   = _mainWin.Content as Visual;
            AdornerLayer layer = null;

            if (mwn != null)
            {
                layer = AdornerLayer.GetAdornerLayer(mwn);
            }
            double offset = 0;
            double step   = ActualWidth * 1.05;

            // HACK: if the selected card is in HandControl, its ContentPresenter has a RenderTransform,
            // which we must account for
            if (GroupControl is HandControl)
            {
                var parent = VisualTreeHelper.GetParent(this) as ContentPresenter;
                if (parent != null)
                {
                    step = 1.05 * parent.RenderTransform.TransformBounds(new Rect(0, 0, ActualWidth, 0)).Width;
                }
            }
            foreach (CardControl cardCtrl in Selection.GetCardControls(GroupControl, this))
            {
                // Create an adorner
                if (Card.Group is Table)
                {
                    var overlay = new CardDragAdorner(cardCtrl, _mouseOffset);
                    OverlayElements.Add(overlay);
                    if (layer != null)
                    {
                        layer.Add(overlay);
                    }
                }
                else
                {
                    // If there are multiple cards but they don't come from the table,
                    // layout the adorners properly
                    var overlay = new CardDragAdorner(this, cardCtrl, _mouseOffset);
                    OverlayElements.Add(overlay);
                    if (cardCtrl != this)
                    {
                        offset += step;
                        overlay.OffsetBy(offset, 0);
                        overlay.CollapseTo(0, 0, false);
                    }
                    if (layer != null)
                    {
                        layer.Add(overlay);
                    }
                }

                // Make the card translucent
                cardCtrl.Opacity = 0.4;
            }
            if (!Selection.IsEmpty() || !_isOverCount)
            {
                return;
            }
            // Create additional fake adorners when dragging from the count label
            offset = 0;
            foreach (Card c in MultipleCards.Skip(1))
            {
                offset += step;
                var overlay = new CardDragAdorner(this, _mouseOffset);
                overlay.OffsetBy(offset, 0);
                overlay.CollapseTo(0, 0, false);
                OverlayElements.Add(overlay);
                if (layer != null)
                {
                    layer.Add(overlay);
                }
            }
        }
Пример #3
0
        protected override void OnCardDropped(object sender, CardsEventArgs e)
        {
            e.Handled = e.CanDrop = true;
            var cardCtrl = e.OriginalSource as CardControl;

            int    delta = Program.GameEngine.Definition.CardHeight - Program.GameEngine.Definition.CardWidth;
            Table  table = Program.GameEngine.Table;
            Vector mouseOffset;

            if (cardCtrl != null && (cardCtrl.IsInverted ||
                                     (Player.LocalPlayer.InvertedTable && !cardCtrl.IsOnTableCanvas)))
            {
                mouseOffset = new Vector(Program.GameEngine.Definition.CardWidth - e.MouseOffset.X, Program.GameEngine.Definition.CardHeight - e.MouseOffset.Y);
            }
            else
            {
                mouseOffset = e.MouseOffset;
            }
            Point pt = MousePosition();

            pt -= mouseOffset;

            if (Selection.IsEmpty() || !(Selection.Source is Table))
            {
                if (Program.GameSettings.UseTwoSidedTable && (e.ClickedCard.Orientation & CardOrientation.Rot90) != 0)
                {
                    // We have to offset the position if we cross the middle line
                    bool newPosInverted = IsInInvertedZone(pt.Y);
                    if (cardCtrl != null && (!cardCtrl.IsInverted && newPosInverted))
                    {
                        pt.X += delta;
                        pt.Y += delta;
                    }
                    else if (cardCtrl != null && (cardCtrl.IsInverted && !newPosInverted))
                    {
                        pt.X -= delta;
                        pt.Y -= delta;
                    }
                }

                int idx = table.GetCardIndex(e.ClickedCard);
                if (idx != -1 || table.Visibility != DataNew.Entities.GroupVisibility.Undefined)
                {
                    e.FaceUp = e.ClickedCard.FaceUp;
                }
                if (idx == -1)
                {
                    idx = table.Cards.Count;
                }
                e.ClickedCard.MoveToTable((int)pt.X, (int)pt.Y, e.FaceUp != null && e.FaceUp.Value, idx, false);

                // If there were other cards (i.e. dragging from a count number in GroupWindow), move them accordingly
                double xOffset = Program.GameEngine.Definition.CardWidth * 1.05;
                foreach (Card c in e.Cards.Where(c => c != e.ClickedCard))
                {
                    pt.X += xOffset;
                    c.MoveToTable((int)pt.X, (int)pt.Y, e.FaceUp != null && e.FaceUp.Value, idx, false);
                }
            }
            else
            {
                // There are multiple cards, coming from the table. Offset them accordingly
                double dx = pt.X - e.ClickedCard.X;
                double dy = pt.Y - e.ClickedCard.Y;
                foreach (Card c in Selection.Cards)
                {
                    int x = (int)(c.X + dx), y = (int)(c.Y + dy);
                    int idx = table.GetCardIndex(c);
                    // If the card is tapped and has crossed the middle line in a two-sided table, we have to adjust its position
                    if (Program.GameSettings.UseTwoSidedTable && (c.Orientation & CardOrientation.Rot90) != 0)
                    {
                        bool oldPosInverted = IsInInvertedZone(c.Y);
                        bool newPosInverted = IsInInvertedZone(y);
                        if (!oldPosInverted && newPosInverted)
                        {
                            x += delta;
                            y += delta;
                        }
                        else if (oldPosInverted && !newPosInverted)
                        {
                            x -= delta;
                            y -= delta;
                        }
                    }
                    c.MoveToTable(x, y, c.FaceUp, idx, false);
                }
            }
        }