IOT dashboard: fix cube logic by keeping track of which edge we are on

This commit is contained in:
Peter Hartmann 2023-01-04 10:07:03 +01:00 committed by uwerat
parent 83a9d835b5
commit 4b1a03cf1d
2 changed files with 109 additions and 59 deletions

View File

@ -20,49 +20,88 @@
#include <QTimer>
Cube::Position Cube::s_neighbors[ Cube::NumPositions ][ 4 ] =
QPair< Cube::Position, Cube::Edge > Cube::s_neighbors[ Cube::NumPositions ][ Cube::NumEdges ] =
{
// Left:
{ Cube::BackPos, // Left
Cube::FrontPos, // Right
Cube::TopPos, // Top
Cube::BottomPos }, // Bottom
// neighbors of Left side:
{
{ Cube::BackPos, Cube::BottomEdge }, // going Left
{ Cube::FrontPos, Cube::BottomEdge }, // going Right
{ Cube::TopPos, Cube::LeftEdge }, // going Top
{ Cube::BottomPos, Cube::RightEdge } // going Bottom
},
// Right:
{ Cube::FrontPos,
Cube::BackPos,
Cube::TopPos,
Cube::BottomPos },
{
{ Cube::FrontPos, Cube::BottomEdge },
{ Cube::BackPos, Cube::BottomEdge },
{ Cube::TopPos, Cube::RightEdge },
{ Cube::BottomPos, Cube::LeftEdge }
},
// Top:
{ Cube::LeftPos,
Cube::RightPos,
Cube::BackPos,
Cube::FrontPos },
{
{ Cube::LeftPos, Cube::RightEdge },
{ Cube::RightPos, Cube::LeftEdge },
{ Cube::BackPos, Cube::TopEdge },
{ Cube::FrontPos, Cube::BottomEdge }
},
// Bottom:
{ Cube::LeftPos,
Cube::RightPos,
Cube::FrontPos,
Cube::BackPos },
{
{ Cube::LeftPos, Cube::LeftEdge },
{ Cube::RightPos, Cube::RightEdge },
{ Cube::FrontPos, Cube::BottomEdge },
{ Cube::BackPos, Cube::TopEdge }
},
// Front:
{ Cube::LeftPos,
Cube::RightPos,
Cube::TopPos,
Cube::BottomPos },
{
{ Cube::LeftPos, Cube::BottomEdge },
{ Cube::RightPos, Cube::BottomEdge },
{ Cube::TopPos, Cube::BottomEdge },
{ Cube::BottomPos, Cube::BottomEdge }
},
// Back:
{ Cube::RightPos,
Cube::LeftPos,
Cube::TopPos,
Cube::BottomPos },
{
{ Cube::RightPos, Cube::BottomEdge },
{ Cube::LeftPos, Cube::BottomEdge },
{ Cube::TopPos, Cube::TopEdge },
{ Cube::BottomPos, Cube::BottomEdge }
}
};
Cube::Edge Cube::s_edgeTransformations[ Cube::NumEdges ][ Cube::NumEdges ] =
{
// current edge is LeftEdge:
{ Cube::TopEdge, // Left
Cube::BottomEdge, // Right
Cube::RightEdge, // Top
Cube::LeftEdge }, // Bottom
// Right:
{ Cube::BottomEdge,
Cube::TopEdge,
Cube::LeftEdge,
Cube::RightEdge },
// Top:
{ Cube::RightEdge,
Cube::LeftEdge,
Cube::BottomEdge,
Cube::TopEdge },
// Bottom:
{ Cube::LeftEdge,
Cube::RightEdge,
Cube::TopEdge,
Cube::BottomEdge }
};
Cube::Cube( QQuickItem* parent )
: QskStackBox( false, parent )
, m_destination( FrontPos )
, m_previousPosition( FrontPos )
, m_currentEdge( BottomEdge )
, m_isIntermediateHop( false )
{
// The code below covers the case where we need 2 cube movements to get
@ -112,8 +151,6 @@ void Cube::doSwitch( Qsk::Direction direction, Position position )
m_isIntermediateHop = false;
}
m_previousPosition = m_destination;
const auto orientation = ( direction == Qsk::LeftToRight || direction == Qsk::RightToLeft )
? Qt::Horizontal : Qt::Vertical;
animator->setOrientation( orientation );
@ -121,28 +158,15 @@ void Cube::doSwitch( Qsk::Direction direction, Position position )
const bool inverted = ( direction == Qsk::LeftToRight || direction == Qsk::TopToBottom );
animator->setInverted( inverted );
updateEdge( direction, position );
setCurrentIndex( position );
Q_EMIT cubeIndexChanged( position );
Q_EMIT cubeIndexChanged( position ); // ### connect to menu bar
}
void Cube::switchPosition( const Qsk::Direction direction )
{
// keep track of from where we went to top and bottom,
// so that going up and down will result in going back
// to the same position:
// (We don't want to model the complete cube logic with
// keeping track of the edges here, because that doesn't
// make sense wrt. being upside down etc.)
if( ( m_destination == TopPos && direction == Qsk::BottomToTop )
|| ( m_destination == BottomPos && direction == Qsk::TopToBottom ) )
{
m_destination = m_previousPosition; // ### doesn't work completely yet
}
else
{
m_destination = neighbor( m_destination, direction );
}
m_destination = neighbor( currentPosition(), direction );
doSwitch( direction, m_destination );
}
@ -154,11 +178,10 @@ void Cube::switchToPosition( const Position position )
m_destination = position;
const auto from = static_cast< Position >( currentIndex() );
const auto direction = this->direction( from, position );
const auto intermediatePosition = neighbor( currentPosition(), direction );
const auto direction = this->direction( currentPosition(), position );
const auto nextPosition = neighbor( currentPosition(), direction );
doSwitch( direction, intermediatePosition );
doSwitch( direction, nextPosition );
}
Cube::Position Cube::currentPosition() const
@ -168,7 +191,8 @@ Cube::Position Cube::currentPosition() const
Cube::Position Cube::neighbor( const Position position, const Qsk::Direction direction ) const
{
const auto n = s_neighbors[ position ][ direction ];
const auto index = s_edgeTransformations[ m_currentEdge ][ direction ];
const auto n = s_neighbors[ position ][ index ].first;
return n;
}
@ -179,9 +203,9 @@ Qsk::Direction Cube::direction( const Position from, const Position to ) const
const auto neighbors = s_neighbors[ from ];
for( int i = 0; i < 4; ++i )
for( int i = 0; i < NumEdges; ++i )
{
if( neighbors[ i ] == to )
if( neighbors[ i ].first == to )
{
return static_cast< Qsk::Direction >( i );
}
@ -190,6 +214,18 @@ Qsk::Direction Cube::direction( const Position from, const Position to ) const
return Qsk::RightToLeft;
}
void Cube::updateEdge( Qsk::Direction direction, Position position )
{
m_currentEdge = s_neighbors[ currentPosition() ][ direction ].second;
// When going back to Front, Left etc., switch back to
// the bottom edge, otherwise it gets to confusing:
if( position != TopPos && position != BottomPos )
{
m_currentEdge = BottomEdge;
}
}
MainItem::MainItem( QQuickItem* parent )
: QskControl( parent )
, m_mainLayout( new QskLinearBox( Qt::Horizontal, this ) )
@ -212,6 +248,9 @@ MainItem::MainItem( QQuickItem* parent )
m_cube->switchToPosition( position );
} );
// ### fix:
// connect( m_cube, &QskStackBox::currentIndexChanged, m_menuBar, &MenuBar::setActivePage );
auto* const dashboardPage = new DashboardPage( m_cube );
auto* const roomsPage = new RoomsPage( m_cube );
auto* const devicesPage = new DevicesPage( m_cube );

View File

@ -15,11 +15,20 @@ class Cube : public QskStackBox
Q_OBJECT
public:
enum Edge {
LeftEdge = Qsk::LeftToRight,
RightEdge = Qsk::RightToLeft,
TopEdge = Qsk::TopToBottom,
BottomEdge = Qsk::BottomToTop,
NumEdges
};
Q_ENUM( Edge )
enum Position {
LeftPos,
RightPos,
TopPos,
BottomPos,
LeftPos = LeftEdge,
RightPos = RightEdge,
TopPos = TopEdge,
BottomPos = BottomEdge,
FrontPos,
BackPos,
NumPositions
@ -40,13 +49,15 @@ class Cube : public QskStackBox
Position currentPosition() const;
Position neighbor( const Position position, const Qsk::Direction direction ) const;
Qsk::Direction direction( const Position from, const Position to ) const;
void updateEdge( Qsk::Direction direction, Position position );
void doSwitch( Qsk::Direction direction, Position position );
Position m_destination;
Position m_previousPosition;
Edge m_currentEdge;
bool m_isIntermediateHop;
static Position s_neighbors[ NumPositions ][ 4 ];
static QPair< Position, Edge > s_neighbors[ NumPositions ][ NumEdges ];
static Edge s_edgeTransformations[ NumEdges ][ NumEdges ];
};
class MainItem : public QskControl