File indexing completed on 2024-04-21 03:41:39

0001 /*
0002     SPDX-FileCopyrightText: 2011 Rebetez Etienne <etienne.rebetez@oberwallis.ch>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "periodictablestates.h"
0008 
0009 #include "psetables.h"
0010 
0011 #include <prefs.h>
0012 
0013 #include <QEasingCurve>
0014 #include <QPropertyAnimation>
0015 
0016 PeriodicTableStates::PeriodicTableStates(const QList<ElementItem *> &elementItemList, const QList<NumerationItem *> &numerationItemList)
0017     : m_elementItemList(elementItemList)
0018     , m_numerationItemList(numerationItemList)
0019     , m_width(42)
0020     , m_height(42) // Some space between the elements (px40) looks nice.
0021 {
0022     m_stateSwitcher = new StateSwitcher(&m_states);
0023     m_group = new QParallelAnimationGroup;
0024 
0025     // For every Tabletyp the Position of the Elements are set up.
0026     for (int tableIndex = 0; tableIndex < pseTables::instance()->tables().count(); ++tableIndex) {
0027         m_tableStatesList << new QState(m_stateSwitcher);
0028 
0029         setNumerationItemPositions(tableIndex);
0030 
0031         setElementItemPositions(tableIndex);
0032 
0033         m_stateSwitcher->addState(m_tableStatesList.at(tableIndex), m_group, tableIndex);
0034     }
0035 
0036     m_stateSwitcher->setInitialState(m_tableStatesList.at(Prefs::table()));
0037     m_states.setInitialState(m_stateSwitcher);
0038     m_states.start();
0039 }
0040 
0041 void PeriodicTableStates::setNumerationItemPositions(int tableIndex)
0042 {
0043     hideAllNumerationItems(tableIndex);
0044 
0045     for (int x = 0; x < maxNumerationItemXCoordinate(tableIndex); ++x) {
0046         int numerationId = pseTables::instance()->getTabletype(tableIndex)->numerationAtPos(x);
0047 
0048         if (numerationId >= 0) {
0049             m_tableStatesList.at(tableIndex)->assignProperty(m_numerationItemList.at(numerationId), "pos", QPointF(x * m_width, -m_height * 3 / 4));
0050             addElementAnimation(m_numerationItemList.at(numerationId), x);
0051         }
0052     }
0053 }
0054 
0055 void PeriodicTableStates::hideAllNumerationItems(int tableIndex)
0056 {
0057     for (NumerationItem *item : std::as_const(m_numerationItemList)) {
0058         m_tableStatesList.at(tableIndex)->assignProperty(item, "pos", QPointF(hiddenPoint()));
0059     }
0060 }
0061 
0062 QPoint PeriodicTableStates::hiddenPoint() const
0063 {
0064     return QPoint(-40, -400);
0065 }
0066 
0067 int PeriodicTableStates::maxNumerationItemXCoordinate(int tableIndex)
0068 {
0069     const int maxTableLenght = pseTables::instance()->getTabletype(tableIndex)->tableSize().x();
0070 
0071     return maxTableLenght > m_numerationItemList.count() ? maxTableLenght : m_numerationItemList.count();
0072 }
0073 
0074 void PeriodicTableStates::addElementAnimation(QGraphicsObject *object, int duration)
0075 {
0076     QPropertyAnimation *anim = new QPropertyAnimation(object, "pos");
0077     anim->setDuration(1600 + duration * 2);
0078     anim->setEasingCurve(QEasingCurve::InOutExpo);
0079     m_group->addAnimation(anim);
0080 }
0081 
0082 void PeriodicTableStates::setElementItemPositions(int tableIndex)
0083 {
0084     for (int i = 0; i < m_elementItemList.size(); ++i) {
0085         const int elementNumber = m_elementItemList.at(i)->data(0).toInt();
0086         QPoint itemPosition = pseTables::instance()->getTabletype(tableIndex)->elementCoords(elementNumber);
0087 
0088         // put the not needed elements a bit away
0089         if (itemPosition.x() < 0) {
0090             itemPosition = hiddenPoint();
0091         }
0092 
0093         m_tableStatesList.at(tableIndex)->assignProperty(m_elementItemList.at(i), "pos", QPointF((itemPosition.x()) * m_width, (itemPosition.y()) * m_height));
0094 
0095         addElementAnimation(m_elementItemList.at(i), i);
0096     }
0097 }
0098 
0099 QRectF PeriodicTableStates::pseRect(int tableIndex) const
0100 {
0101     const QPoint maxTableCoords = pseTables::instance()->getTabletype(tableIndex)->tableSize();
0102 
0103     const int x = maxTableCoords.x();
0104 
0105     // adding one for the numeration row.
0106     const int y = maxTableCoords.y() + 1;
0107 
0108     return QRectF(0, -m_height, x * m_width, y * m_height);
0109 }
0110 
0111 void PeriodicTableStates::setTableState(int tableIndex)
0112 {
0113     m_stateSwitcher->switchToState(tableIndex);
0114 }
0115 
0116 PeriodicTableStates::~PeriodicTableStates()
0117 {
0118     delete m_group;
0119     qDeleteAll(m_tableStatesList);
0120     delete m_stateSwitcher;
0121 }