Package pivot.wtk.skin

Source Code of pivot.wtk.skin.CardPaneSkin$SelectionChangeTransition

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pivot.wtk.skin;

import pivot.collections.Sequence;
import pivot.util.Vote;
import pivot.wtk.CardPane;
import pivot.wtk.CardPaneListener;
import pivot.wtk.Component;
import pivot.wtk.Container;
import pivot.wtk.Dimensions;
import pivot.wtk.Orientation;
import pivot.wtk.effects.FadeDecorator;
import pivot.wtk.effects.Transition;
import pivot.wtk.effects.TransitionListener;
import pivot.wtk.effects.easing.Easing;
import pivot.wtk.effects.easing.Quartic;

/**
* Card pane skin.
*
* @author gbrown
*/
public class CardPaneSkin extends ContainerSkin implements CardPaneListener {
    public class SelectionChangeTransition extends Transition {
        private int previousSelectedIndex = -1;
        private int selectedIndex = -1;

        private FadeDecorator fadeOutDecorator = new FadeDecorator();
        private FadeDecorator fadeInDecorator = new FadeDecorator();

        private Easing slideEasing = new Quartic();

        public SelectionChangeTransition(int previousSelectedIndex, int selectedIndex,
            int duration, int rate) {
            super(duration, rate, false);

            this.previousSelectedIndex = previousSelectedIndex;
            this.selectedIndex = selectedIndex;
        }

        @Override
        public void start(TransitionListener transitionListener) {
            Component previousSelectedCard = getPreviousSelectedCard();
            Component selectedCard = getSelectedCard();

            if (matchSelectedCardSize) {
                if (previousSelectedCard != null) {
                    previousSelectedCard.getDecorators().add(fadeOutDecorator);
                }

                if (selectedCard != null) {
                    selectedCard.getDecorators().add(fadeInDecorator);
                }
            }

            super.start(transitionListener);
        }

        @Override
        public void stop() {
            if (matchSelectedCardSize) {
                Component previousSelectedCard = getPreviousSelectedCard();
                Component selectedCard = getSelectedCard();

                if (previousSelectedCard != null) {
                    previousSelectedCard.getDecorators().remove(fadeOutDecorator);
                }

                if (selectedCard != null) {
                    selectedCard.getDecorators().remove(fadeInDecorator);
                }
            }

            invalidateComponent();

            super.stop();
        }

        @Override
        protected void update() {
            if (matchSelectedCardSize) {
                float percentComplete = getPercentComplete();
                fadeOutDecorator.setOpacity(1.0f - percentComplete);
                fadeInDecorator.setOpacity(percentComplete);
            }

            invalidateComponent();
        }

        public float getEasedSlidePercentComplete() {
            return slideEasing.easeOut(getElapsedTime(), 0, 1, getDuration());
        }

        public Component getPreviousSelectedCard() {
            CardPane cardPane = (CardPane)getComponent();
            return previousSelectedIndex == -1 ? null : cardPane.get(previousSelectedIndex);
        }

        public Component getSelectedCard() {
            CardPane cardPane = (CardPane)getComponent();
            return selectedIndex == -1 ? null : cardPane.get(selectedIndex);
        }
    }

    private boolean matchSelectedCardSize = false;

    private SelectionChangeTransition selectionChangeTransition = null;
    private static final int SELECTION_CHANGE_DURATION = 250;
    private static final int SELECTION_CHANGE_RATE = 30;

    @Override
    public void setSize(int width, int height) {
        if (selectionChangeTransition != null) {
            if (!matchSelectedCardSize) {
                CardPane cardPane = (CardPane)getComponent();
                Orientation orientation = cardPane.getOrientation();

                if ((orientation == Orientation.HORIZONTAL && width != getWidth())
                    || (orientation == Orientation.VERTICAL && height != getHeight())) {
                    selectionChangeTransition.end();
                    selectionChangeTransition = null;
                }
            }
        }

        super.setSize(width, height);
    }

    public void install(Component component) {
        super.install(component);

        CardPane cardPane = (CardPane)component;
        cardPane.getCardPaneListeners().add(this);
    }

    public void uninstall() {
        CardPane cardPane = (CardPane)getComponent();
        cardPane.getCardPaneListeners().remove(this);

        super.uninstall();
    }

    public int getPreferredWidth(int height) {
        int preferredWidth = 0;

        CardPane cardPane = (CardPane)getComponent();

        if (selectionChangeTransition == null) {
            if (matchSelectedCardSize) {
                Component selectedCard = cardPane.getSelectedCard();
                if (selectedCard != null) {
                    preferredWidth = selectedCard.getPreferredWidth(height);
                }
            } else {
                int selectedIndex = cardPane.getSelectedIndex();
                Orientation orientation = cardPane.getOrientation();

                if (selectedIndex != -1
                    || orientation == Orientation.HORIZONTAL) {
                    for (Component card : cardPane) {
                        preferredWidth = Math.max(preferredWidth, card.getPreferredWidth(height));
                    }
                }
            }
        } else {
            float percentComplete = selectionChangeTransition.getPercentComplete();

            Component previousSelectedCard = selectionChangeTransition.getPreviousSelectedCard();
            int previousWidth = (previousSelectedCard == null) ? 0 : previousSelectedCard.getWidth();

            Component selectedCard = selectionChangeTransition.getSelectedCard();
            int width = (selectedCard == null) ? 0 : selectedCard.getWidth();

            Orientation orientation = cardPane.getOrientation();

            if (!matchSelectedCardSize
                && orientation == Orientation.HORIZONTAL) {
                preferredWidth = Math.max(previousWidth, width);
            } else {
                preferredWidth = previousWidth + (int)((float)(width - previousWidth)
                    * percentComplete);
            }
        }

        return preferredWidth;
    }

    public int getPreferredHeight(int width) {
        int preferredHeight = 0;

        CardPane cardPane = (CardPane)getComponent();

        if (selectionChangeTransition == null) {
            if (matchSelectedCardSize) {
                Component selectedCard = cardPane.getSelectedCard();
                if (selectedCard != null) {
                    preferredHeight = selectedCard.getPreferredHeight(width);
                }
            } else {
                int selectedIndex = cardPane.getSelectedIndex();
                Orientation orientation = cardPane.getOrientation();

                if (selectedIndex != -1
                    || orientation == Orientation.VERTICAL) {
                    for (Component card : cardPane) {
                        preferredHeight = Math.max(preferredHeight, card.getPreferredHeight(width));
                    }
                }
            }
        } else {
            float percentComplete = selectionChangeTransition.getPercentComplete();

            Component previousSelectedCard = selectionChangeTransition.getPreviousSelectedCard();
            int previousHeight = (previousSelectedCard == null) ? 0 : previousSelectedCard.getHeight();

            Component selectedCard = selectionChangeTransition.getSelectedCard();
            int height = (selectedCard == null) ? 0 : selectedCard.getHeight();

            Orientation orientation = cardPane.getOrientation();

            if (!matchSelectedCardSize
                && orientation == Orientation.VERTICAL) {
                preferredHeight = Math.max(previousHeight, height);
            } else {
                preferredHeight = previousHeight + (int)((float)(height - previousHeight)
                    * percentComplete);
            }
        }

        return preferredHeight;
    }

    public Dimensions getPreferredSize() {
        Dimensions preferredSize;

        CardPane cardPane = (CardPane)getComponent();

        if (selectionChangeTransition == null) {
            if (matchSelectedCardSize) {
                Component selectedCard = cardPane.getSelectedCard();
                if (selectedCard == null) {
                    preferredSize = new Dimensions(0, 0);
                } else {
                    preferredSize = selectedCard.getPreferredSize();
                }
            } else {
                preferredSize = new Dimensions(0, 0);
                Orientation orientation = cardPane.getOrientation();

                int selectedIndex = cardPane.getSelectedIndex();
                for (Component card : cardPane) {
                    Dimensions cardSize = card.getPreferredSize();

                    if (selectedIndex != -1
                        || orientation == Orientation.HORIZONTAL) {
                        preferredSize.width = Math.max(cardSize.width, preferredSize.width);
                    }

                    if (selectedIndex != -1
                        || orientation == Orientation.VERTICAL) {
                        preferredSize.height = Math.max(cardSize.height, preferredSize.height);
                    }
                }
            }
        } else {
            float percentComplete = selectionChangeTransition.getPercentComplete();

            int previousWidth;
            int previousHeight;
            Component previousSelectedCard = selectionChangeTransition.getPreviousSelectedCard();

            if (previousSelectedCard == null) {
                previousWidth = 0;
                previousHeight = 0;
            } else {
                previousWidth = previousSelectedCard.getWidth();
                previousHeight = previousSelectedCard.getHeight();
            }

            int width;
            int height;
            Component selectedCard = selectionChangeTransition.getSelectedCard();

            if (selectedCard == null) {
                width = 0;
                height = 0;
            } else {
                width = selectedCard.getWidth();
                height = selectedCard.getHeight();
            }

            int preferredWidth = 0;
            int preferredHeight = 0;

            Orientation orientation = cardPane.getOrientation();

            if (!matchSelectedCardSize
                && orientation == Orientation.HORIZONTAL) {
                preferredWidth = Math.max(previousWidth, width);
            } else {
                preferredWidth = previousWidth + (int)((float)(width - previousWidth)
                    * percentComplete);
            }

            if (!matchSelectedCardSize
                && orientation == Orientation.VERTICAL) {
                preferredHeight = Math.max(previousHeight, height);
            } else {
                preferredHeight = previousHeight + (int)((float)(height - previousHeight)
                    * percentComplete);
            }

            preferredSize = new Dimensions(preferredWidth, preferredHeight);
        }

        return preferredSize;
    }

    public void layout() {
        CardPane cardPane = (CardPane)getComponent();
        int width = getWidth();
        int height = getHeight();

        if (selectionChangeTransition == null) {
            Component selectedCard = cardPane.getSelectedCard();

            for (Component card : cardPane) {
                // Set the size of the selected component to the container's size
                // and show the card
                if (card == selectedCard) {
                    card.setLocation(0, 0);
                    card.setSize(width, height);
                    card.setVisible(true);
                } else {
                    card.setVisible(false);
                }
            }
        } else {
            if (matchSelectedCardSize) {
                Component previousSelectedCard = selectionChangeTransition.getPreviousSelectedCard();
                Component selectedCard = selectionChangeTransition.getSelectedCard();

                Orientation orientation = cardPane.getOrientation();

                if (selectionChangeTransition.isRunning()) {
                    for (Component card : cardPane) {
                        // Center old and new cards and ensure they are visible
                        if (card == previousSelectedCard
                            || card == selectedCard) {
                            int x = (orientation == Orientation.VERTICAL) ?
                                0 : Math.round((float)(width - card.getWidth()) / 2);
                            int y = (orientation == Orientation.HORIZONTAL) ?
                                0 : Math.round((float)(height - card.getHeight()) / 2);

                            card.setLocation(x, y);
                            card.setVisible(true);
                        } else {
                            card.setVisible(false);
                        }
                    }
                } else {
                    if (previousSelectedCard != null) {
                        previousSelectedCard.setSize(previousSelectedCard.getPreferredSize());
                    }

                    if (selectedCard != null) {
                        selectedCard.setSize(selectedCard.getPreferredSize());
                        selectedCard.setVisible(true);
                    }
                }
            } else {
                if (selectionChangeTransition.isRunning()) {
                    int previousSelectedIndex = selectionChangeTransition.previousSelectedIndex;
                    int selectedIndex = selectionChangeTransition.selectedIndex;

                    if (previousSelectedIndex != -1
                        && selectedIndex != -1) {
                        float percentComplete = selectionChangeTransition.getEasedSlidePercentComplete();

                        int direction = Integer.signum(previousSelectedIndex - selectedIndex);

                        int dx = (int)((float)width * percentComplete) * direction;
                        int dy = (int)((float)height * percentComplete) * direction;

                        Orientation orientation = cardPane.getOrientation();

                        for (int i = 0, n = cardPane.getLength(); i < n; i++) {
                            Component card = cardPane.get(i);

                            if (i == previousSelectedIndex) {
                                if (orientation == Orientation.HORIZONTAL) {
                                    card.setLocation(dx, 0);
                                } else {
                                    card.setLocation(0, dy);
                                }

                                card.setVisible(true);
                            } else if (i == selectedIndex) {
                                if (orientation == Orientation.HORIZONTAL) {
                                    card.setLocation(-width * direction + dx, 0);
                                } else {
                                    card.setLocation(0, -height * direction + dy);
                                }

                                card.setVisible(true);
                            } else {
                                card.setVisible(false);
                            }
                        }
                    }
                } else {
                    Component selectedCard = selectionChangeTransition.getSelectedCard();
                    Orientation orientation = cardPane.getOrientation();

                    if (selectedCard != null) {
                        if (orientation == Orientation.HORIZONTAL) {
                            for (Component card : cardPane) {
                                height = Math.max(height, card.getPreferredHeight(width));
                            }
                        } else {
                            for (Component card : cardPane) {
                                width = Math.max(height, card.getPreferredWidth(height));
                            }
                        }

                        selectedCard.setSize(width, height);
                        selectedCard.setVisible(true);
                    }
                }
            }
        }
    }

    public boolean getMatchSelectedCardSize() {
        return matchSelectedCardSize;
    }

    public void setMatchSelectedCardSize(boolean matchSelectedCardSize) {
        this.matchSelectedCardSize = matchSelectedCardSize;
        invalidateComponent();
    }

    @Override
    public void componentInserted(Container container, int index) {
        if (selectionChangeTransition != null) {
            selectionChangeTransition.stop();
            selectionChangeTransition = null;
        }

        super.componentInserted(container, index);

        invalidateComponent();
    }

    @Override
    public void componentsRemoved(Container container, int index, Sequence<Component> removed) {
        if (selectionChangeTransition != null) {
            selectionChangeTransition.stop();
            selectionChangeTransition = null;
        }

        super.componentsRemoved(container, index, removed);

        invalidateComponent();
    }

    public void orientationChanged(CardPane cardPane, Orientation previousOrientation) {
        // No-op
    }

    public Vote previewSelectedIndexChange(final CardPane cardPane, final int selectedIndex) {
        Vote vote = Vote.APPROVE;

        if (cardPane.isShowing()) {
            if (selectionChangeTransition == null) {
                Orientation orientation = cardPane.getOrientation();

                if (matchSelectedCardSize
                    || orientation != null) {
                    int previousSelectedIndex = cardPane.getSelectedIndex();

                    selectionChangeTransition = new SelectionChangeTransition(previousSelectedIndex, selectedIndex,
                        SELECTION_CHANGE_DURATION, SELECTION_CHANGE_RATE);

                    layout();
                    selectionChangeTransition.start(new TransitionListener() {
                        public void transitionCompleted(Transition transition) {
                            cardPane.setSelectedIndex(selectedIndex);
                            selectionChangeTransition = null;

                            invalidateComponent();
                        }
                    });

                    vote = Vote.DEFER;
                }
            } else {
                if (selectionChangeTransition.isRunning()) {
                    vote = Vote.DEFER;
                }
            }
        }

        return vote;
    }

    public void selectedIndexChangeVetoed(CardPane cardPane, Vote reason) {
        if (reason == Vote.DENY
            && selectionChangeTransition != null) {
            selectionChangeTransition.stop();
            selectionChangeTransition = null;
            invalidateComponent();
        }
    }

    public void selectedIndexChanged(CardPane cardPane, int previousSelectedIndex) {
        invalidateComponent();
    }
}
TOP

Related Classes of pivot.wtk.skin.CardPaneSkin$SelectionChangeTransition

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.