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> #include <QTimer>
Cube::Position Cube::s_neighbors[ Cube::NumPositions ][ 4 ] = QPair< Cube::Position, Cube::Edge > Cube::s_neighbors[ Cube::NumPositions ][ Cube::NumEdges ] =
{ {
// Left: // neighbors of Left side:
{ Cube::BackPos, // Left {
Cube::FrontPos, // Right { Cube::BackPos, Cube::BottomEdge }, // going Left
Cube::TopPos, // Top { Cube::FrontPos, Cube::BottomEdge }, // going Right
Cube::BottomPos }, // Bottom { Cube::TopPos, Cube::LeftEdge }, // going Top
{ Cube::BottomPos, Cube::RightEdge } // going Bottom
},
// Right: // Right:
{ Cube::FrontPos, {
Cube::BackPos, { Cube::FrontPos, Cube::BottomEdge },
Cube::TopPos, { Cube::BackPos, Cube::BottomEdge },
Cube::BottomPos }, { Cube::TopPos, Cube::RightEdge },
{ Cube::BottomPos, Cube::LeftEdge }
},
// Top: // Top:
{ Cube::LeftPos, {
Cube::RightPos, { Cube::LeftPos, Cube::RightEdge },
Cube::BackPos, { Cube::RightPos, Cube::LeftEdge },
Cube::FrontPos }, { Cube::BackPos, Cube::TopEdge },
{ Cube::FrontPos, Cube::BottomEdge }
},
// Bottom: // Bottom:
{ Cube::LeftPos, {
Cube::RightPos, { Cube::LeftPos, Cube::LeftEdge },
Cube::FrontPos, { Cube::RightPos, Cube::RightEdge },
Cube::BackPos }, { Cube::FrontPos, Cube::BottomEdge },
{ Cube::BackPos, Cube::TopEdge }
},
// Front: // Front:
{ Cube::LeftPos, {
Cube::RightPos, { Cube::LeftPos, Cube::BottomEdge },
Cube::TopPos, { Cube::RightPos, Cube::BottomEdge },
Cube::BottomPos }, { Cube::TopPos, Cube::BottomEdge },
{ Cube::BottomPos, Cube::BottomEdge }
},
// Back: // Back:
{ Cube::RightPos, {
Cube::LeftPos, { Cube::RightPos, Cube::BottomEdge },
Cube::TopPos, { Cube::LeftPos, Cube::BottomEdge },
Cube::BottomPos }, { 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 ) Cube::Cube( QQuickItem* parent )
: QskStackBox( false, parent ) : QskStackBox( false, parent )
, m_destination( FrontPos ) , m_destination( FrontPos )
, m_previousPosition( FrontPos ) , m_currentEdge( BottomEdge )
, m_isIntermediateHop( false ) , m_isIntermediateHop( false )
{ {
// The code below covers the case where we need 2 cube movements to get // 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_isIntermediateHop = false;
} }
m_previousPosition = m_destination;
const auto orientation = ( direction == Qsk::LeftToRight || direction == Qsk::RightToLeft ) const auto orientation = ( direction == Qsk::LeftToRight || direction == Qsk::RightToLeft )
? Qt::Horizontal : Qt::Vertical; ? Qt::Horizontal : Qt::Vertical;
animator->setOrientation( orientation ); animator->setOrientation( orientation );
@ -121,28 +158,15 @@ void Cube::doSwitch( Qsk::Direction direction, Position position )
const bool inverted = ( direction == Qsk::LeftToRight || direction == Qsk::TopToBottom ); const bool inverted = ( direction == Qsk::LeftToRight || direction == Qsk::TopToBottom );
animator->setInverted( inverted ); animator->setInverted( inverted );
updateEdge( direction, position );
setCurrentIndex( position ); setCurrentIndex( position );
Q_EMIT cubeIndexChanged( position ); Q_EMIT cubeIndexChanged( position ); // ### connect to menu bar
} }
void Cube::switchPosition( const Qsk::Direction direction ) void Cube::switchPosition( const Qsk::Direction direction )
{ {
// keep track of from where we went to top and bottom, m_destination = neighbor( currentPosition(), direction );
// 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 );
}
doSwitch( direction, m_destination ); doSwitch( direction, m_destination );
} }
@ -154,11 +178,10 @@ void Cube::switchToPosition( const Position position )
m_destination = position; m_destination = position;
const auto from = static_cast< Position >( currentIndex() ); const auto direction = this->direction( currentPosition(), position );
const auto direction = this->direction( from, position ); const auto nextPosition = neighbor( currentPosition(), direction );
const auto intermediatePosition = neighbor( currentPosition(), direction );
doSwitch( direction, intermediatePosition ); doSwitch( direction, nextPosition );
} }
Cube::Position Cube::currentPosition() const 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 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; return n;
} }
@ -179,9 +203,9 @@ Qsk::Direction Cube::direction( const Position from, const Position to ) const
const auto neighbors = s_neighbors[ from ]; 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 ); return static_cast< Qsk::Direction >( i );
} }
@ -190,6 +214,18 @@ Qsk::Direction Cube::direction( const Position from, const Position to ) const
return Qsk::RightToLeft; 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 ) MainItem::MainItem( QQuickItem* parent )
: QskControl( parent ) : QskControl( parent )
, m_mainLayout( new QskLinearBox( Qt::Horizontal, this ) ) , m_mainLayout( new QskLinearBox( Qt::Horizontal, this ) )
@ -212,6 +248,9 @@ MainItem::MainItem( QQuickItem* parent )
m_cube->switchToPosition( position ); m_cube->switchToPosition( position );
} ); } );
// ### fix:
// connect( m_cube, &QskStackBox::currentIndexChanged, m_menuBar, &MenuBar::setActivePage );
auto* const dashboardPage = new DashboardPage( m_cube ); auto* const dashboardPage = new DashboardPage( m_cube );
auto* const roomsPage = new RoomsPage( m_cube ); auto* const roomsPage = new RoomsPage( m_cube );
auto* const devicesPage = new DevicesPage( m_cube ); auto* const devicesPage = new DevicesPage( m_cube );

View File

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