mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
1063 lines
31 KiB
C++
1063 lines
31 KiB
C++
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include "homescreenstate.h"
|
|
#include "favouritesmodel.h"
|
|
#include "foliosettings.h"
|
|
#include "pagelistmodel.h"
|
|
|
|
#include <algorithm>
|
|
|
|
// TODO don't hardcode, use something more device dependent?
|
|
constexpr qreal APP_DRAWER_OPEN_DIST = 300;
|
|
constexpr qreal SEARCH_WIDGET_OPEN_DIST = 300;
|
|
|
|
// pixels to move before we determine the swipe type
|
|
constexpr qreal DETERMINE_SWIPE_THRESHOLD = 10;
|
|
|
|
constexpr qreal VERTICAL_FAVOURITES_BAR_THRESHOLD = 400;
|
|
|
|
QPropertyAnimation *HomeScreenState::setupAnimation(QByteArray property, int duration, QEasingCurve::Type curve, qreal endValue)
|
|
{
|
|
auto anim = new QPropertyAnimation{this, property, this};
|
|
anim->setDuration(duration);
|
|
anim->setEndValue(endValue);
|
|
anim->setEasingCurve(curve);
|
|
return anim;
|
|
}
|
|
|
|
HomeScreenState::HomeScreenState(HomeScreen *parent)
|
|
: QObject{parent}
|
|
, m_homeScreen{parent}
|
|
, m_dragState{new DragState{this, parent}}
|
|
, m_appDrawerY{APP_DRAWER_OPEN_DIST}
|
|
, m_searchWidgetY{SEARCH_WIDGET_OPEN_DIST}
|
|
{
|
|
}
|
|
|
|
void HomeScreenState::init()
|
|
{
|
|
const int expoDuration = 800;
|
|
const int cubicDuration = 400;
|
|
|
|
m_openAppDrawerAnim = setupAnimation("appDrawerY", expoDuration, QEasingCurve::OutExpo, 0);
|
|
|
|
connect(m_openAppDrawerAnim, &QPropertyAnimation::valueChanged, this, [this]() {
|
|
// the animation runs too long to connect to QPropertyAnimation::finished
|
|
// instead just have the end behaviour execute once we are 90% through
|
|
if (m_appDrawerOpenProgress > 0.9) {
|
|
setViewState(ViewState::AppDrawerView);
|
|
Q_EMIT appDrawerOpened();
|
|
}
|
|
});
|
|
|
|
m_closeAppDrawerAnim = setupAnimation("appDrawerY", expoDuration, QEasingCurve::OutExpo, APP_DRAWER_OPEN_DIST);
|
|
|
|
connect(m_closeAppDrawerAnim, &QPropertyAnimation::valueChanged, this, [this]() {
|
|
// the animation runs too long to connect to QPropertyAnimation::finished
|
|
// instead just have the end behaviour execute once we are 90% through
|
|
if (m_appDrawerOpenProgress < 0.1) {
|
|
setViewState(ViewState::PageView);
|
|
Q_EMIT appDrawerClosed();
|
|
}
|
|
});
|
|
|
|
m_openSearchWidgetAnim = setupAnimation("searchWidgetY", cubicDuration, QEasingCurve::OutCubic, 0);
|
|
|
|
connect(m_openSearchWidgetAnim, &QPropertyAnimation::finished, this, [this]() {
|
|
setViewState(ViewState::SearchWidgetView);
|
|
});
|
|
|
|
m_closeSearchWidgetAnim = setupAnimation("searchWidgetY", cubicDuration, QEasingCurve::OutCubic, SEARCH_WIDGET_OPEN_DIST);
|
|
|
|
connect(m_closeSearchWidgetAnim, &QPropertyAnimation::finished, this, [this]() {
|
|
setViewState(ViewState::PageView);
|
|
});
|
|
|
|
m_pageAnim = setupAnimation("pageViewX", cubicDuration, QEasingCurve::OutCubic, 0);
|
|
|
|
m_openFolderAnim = setupAnimation("folderOpenProgress", cubicDuration, QEasingCurve::OutCubic, 1.0);
|
|
|
|
connect(m_openFolderAnim, &QPropertyAnimation::finished, this, [this]() {
|
|
setViewState(ViewState::FolderView);
|
|
});
|
|
|
|
m_closeFolderAnim = setupAnimation("folderOpenProgress", cubicDuration, QEasingCurve::OutCubic, 0.0);
|
|
|
|
connect(m_closeFolderAnim, &QPropertyAnimation::finished, this, [this]() {
|
|
setViewState(ViewState::PageView);
|
|
setCurrentFolder(nullptr);
|
|
setFolderViewX(0); // reset to first page
|
|
m_folderPageNum = 0;
|
|
Q_EMIT folderPageNumChanged();
|
|
|
|
Q_EMIT leftCurrentFolder();
|
|
});
|
|
|
|
m_folderPageAnim = setupAnimation("folderViewX", cubicDuration, QEasingCurve::OutCubic, 0);
|
|
|
|
m_openSettingsAnim = setupAnimation("settingsOpenProgress", cubicDuration, QEasingCurve::OutExpo, 1.0);
|
|
|
|
connect(m_openSettingsAnim, &QPropertyAnimation::finished, this, [this]() {
|
|
setViewState(ViewState::SettingsView);
|
|
});
|
|
|
|
m_closeSettingsAnim = setupAnimation("settingsOpenProgress", cubicDuration, QEasingCurve::InOutExpo, 0.0);
|
|
|
|
connect(m_closeSettingsAnim, &QPropertyAnimation::finished, this, [this]() {
|
|
setViewState(ViewState::PageView);
|
|
});
|
|
|
|
connect(this, &HomeScreenState::viewWidthChanged, this, [this]() {
|
|
// TODO: we only support 2 orientations at the moment since we don't know what the device rotated to
|
|
setPageOrientation(m_viewWidth > m_viewHeight ? RotateCounterClockwise : RegularPosition);
|
|
});
|
|
connect(this, &HomeScreenState::viewHeightChanged, this, [this]() {
|
|
setPageOrientation(m_viewWidth > m_viewHeight ? RotateCounterClockwise : RegularPosition);
|
|
});
|
|
connect(this, &HomeScreenState::pageOrientationChanged, this, [this]() {
|
|
Q_EMIT pageRowsChanged();
|
|
Q_EMIT pageColumnsChanged();
|
|
});
|
|
|
|
connect(this, &HomeScreenState::pageWidthChanged, this, &HomeScreenState::calculatePageContentWidth);
|
|
connect(this, &HomeScreenState::pageHeightChanged, this, &HomeScreenState::calculatePageContentHeight);
|
|
|
|
connect(this, &HomeScreenState::pageContentWidthChanged, this, &HomeScreenState::calculatePageCellWidth);
|
|
connect(this, &HomeScreenState::pageColumnsChanged, this, &HomeScreenState::calculatePageCellWidth);
|
|
connect(this, &HomeScreenState::pageContentHeightChanged, this, &HomeScreenState::calculatePageCellHeight);
|
|
connect(this, &HomeScreenState::pageRowsChanged, this, &HomeScreenState::calculatePageCellHeight);
|
|
|
|
connect(this, &HomeScreenState::viewWidthChanged, this, [this]() {
|
|
Q_EMIT favouritesBarLocationChanged();
|
|
});
|
|
connect(this, &HomeScreenState::viewHeightChanged, this, [this]() {
|
|
Q_EMIT favouritesBarLocationChanged();
|
|
});
|
|
|
|
connect(m_homeScreen->folioSettings(), &FolioSettings::homeScreenRowsChanged, this, [this]() {
|
|
Q_EMIT pageRowsChanged();
|
|
Q_EMIT pageColumnsChanged();
|
|
});
|
|
connect(m_homeScreen->folioSettings(), &FolioSettings::homeScreenColumnsChanged, this, [this]() {
|
|
Q_EMIT pageRowsChanged();
|
|
Q_EMIT pageColumnsChanged();
|
|
});
|
|
}
|
|
|
|
HomeScreenState::ViewState HomeScreenState::viewState() const
|
|
{
|
|
return m_viewState;
|
|
}
|
|
|
|
void HomeScreenState::setViewState(ViewState viewState)
|
|
{
|
|
if (viewState != m_viewState) {
|
|
m_viewState = viewState;
|
|
Q_EMIT viewStateChanged();
|
|
}
|
|
}
|
|
|
|
HomeScreenState::SwipeState HomeScreenState::swipeState() const
|
|
{
|
|
return m_swipeState;
|
|
}
|
|
|
|
void HomeScreenState::setSwipeState(SwipeState swipeState)
|
|
{
|
|
if (swipeState != m_swipeState) {
|
|
m_swipeState = swipeState;
|
|
Q_EMIT swipeStateChanged();
|
|
}
|
|
}
|
|
|
|
DragState *HomeScreenState::dragState() const
|
|
{
|
|
return m_dragState;
|
|
}
|
|
|
|
qreal HomeScreenState::viewWidth() const
|
|
{
|
|
return m_viewWidth;
|
|
}
|
|
|
|
void HomeScreenState::setViewWidth(qreal viewWidth)
|
|
{
|
|
if (m_viewWidth != viewWidth) {
|
|
m_viewWidth = viewWidth;
|
|
Q_EMIT viewWidthChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::viewHeight() const
|
|
{
|
|
return m_viewHeight;
|
|
}
|
|
|
|
void HomeScreenState::setViewHeight(qreal viewHeight)
|
|
{
|
|
if (m_viewHeight != viewHeight) {
|
|
m_viewHeight = viewHeight;
|
|
Q_EMIT viewHeightChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::viewTopPadding() const
|
|
{
|
|
return m_viewTopPadding;
|
|
}
|
|
|
|
void HomeScreenState::setViewTopPadding(qreal viewTopPadding)
|
|
{
|
|
if (m_viewTopPadding != viewTopPadding) {
|
|
m_viewTopPadding = viewTopPadding;
|
|
Q_EMIT viewTopPaddingChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::viewBottomPadding() const
|
|
{
|
|
return m_viewBottomPadding;
|
|
}
|
|
|
|
void HomeScreenState::setViewBottomPadding(qreal viewBottomPadding)
|
|
{
|
|
if (m_viewBottomPadding != viewBottomPadding) {
|
|
m_viewBottomPadding = viewBottomPadding;
|
|
Q_EMIT viewBottomPaddingChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::viewLeftPadding() const
|
|
{
|
|
return m_viewLeftPadding;
|
|
}
|
|
|
|
void HomeScreenState::setViewLeftPadding(qreal viewLeftPadding)
|
|
{
|
|
if (m_viewLeftPadding != viewLeftPadding) {
|
|
m_viewLeftPadding = viewLeftPadding;
|
|
Q_EMIT viewLeftPaddingChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::viewRightPadding() const
|
|
{
|
|
return m_viewRightPadding;
|
|
}
|
|
|
|
void HomeScreenState::setViewRightPadding(qreal viewRightPadding)
|
|
{
|
|
if (m_viewRightPadding != viewRightPadding) {
|
|
m_viewRightPadding = viewRightPadding;
|
|
Q_EMIT viewRightPaddingChanged();
|
|
}
|
|
}
|
|
|
|
HomeScreenState::PageOrientation HomeScreenState::pageOrientation() const
|
|
{
|
|
return m_pageOrientation;
|
|
}
|
|
|
|
void HomeScreenState::setPageOrientation(PageOrientation pageOrientation)
|
|
{
|
|
if (m_pageOrientation != pageOrientation) {
|
|
m_pageOrientation = pageOrientation;
|
|
Q_EMIT pageOrientationChanged();
|
|
}
|
|
}
|
|
|
|
HomeScreenState::FavouritesBarLocation HomeScreenState::favouritesBarLocation() const
|
|
{
|
|
// TODO need to determine screen rotation and bottom of screen to have Left and Right accordingly
|
|
return m_viewHeight < VERTICAL_FAVOURITES_BAR_THRESHOLD && m_viewWidth > m_viewHeight ? Right : Bottom;
|
|
}
|
|
|
|
int HomeScreenState::pageRows() const
|
|
{
|
|
if (m_pageOrientation == RegularPosition || m_pageOrientation == RotateUpsideDown) {
|
|
return m_homeScreen->folioSettings()->homeScreenRows();
|
|
} else {
|
|
return m_homeScreen->folioSettings()->homeScreenColumns();
|
|
}
|
|
}
|
|
|
|
int HomeScreenState::pageColumns() const
|
|
{
|
|
if (m_pageOrientation == RegularPosition || m_pageOrientation == RotateUpsideDown) {
|
|
return m_homeScreen->folioSettings()->homeScreenColumns();
|
|
} else {
|
|
return m_homeScreen->folioSettings()->homeScreenRows();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::pageViewX() const
|
|
{
|
|
return m_pageViewX;
|
|
}
|
|
|
|
void HomeScreenState::setPageViewX(qreal pageViewX)
|
|
{
|
|
if (m_pageViewX != pageViewX) {
|
|
m_pageViewX = pageViewX;
|
|
Q_EMIT pageViewXChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::pageWidth() const
|
|
{
|
|
return m_pageWidth;
|
|
}
|
|
|
|
void HomeScreenState::setPageWidth(qreal pageWidth)
|
|
{
|
|
if (m_pageWidth != pageWidth) {
|
|
m_pageWidth = pageWidth;
|
|
Q_EMIT pageWidthChanged();
|
|
|
|
// make sure we snap
|
|
snapPage();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::pageHeight() const
|
|
{
|
|
return m_pageHeight;
|
|
}
|
|
|
|
void HomeScreenState::setPageHeight(qreal pageHeight)
|
|
{
|
|
if (m_pageHeight != pageHeight) {
|
|
m_pageHeight = pageHeight;
|
|
Q_EMIT pageHeightChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::pageContentWidth() const
|
|
{
|
|
return m_pageContentWidth;
|
|
}
|
|
|
|
void HomeScreenState::calculatePageContentWidth()
|
|
{
|
|
const qreal pageContentWidth = std::round(m_pageWidth * 0.95); // 0.05 on both sides
|
|
|
|
if (m_pageContentWidth != pageContentWidth) {
|
|
m_pageContentWidth = pageContentWidth;
|
|
Q_EMIT pageContentWidthChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::pageContentHeight() const
|
|
{
|
|
return m_pageContentHeight;
|
|
}
|
|
|
|
void HomeScreenState::calculatePageContentHeight()
|
|
{
|
|
const qreal pageContentHeight = std::round(m_pageHeight * 0.95); // 0.05 on both sides
|
|
|
|
if (m_pageContentHeight != pageContentHeight) {
|
|
m_pageContentHeight = pageContentHeight;
|
|
Q_EMIT pageContentHeightChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::pageCellWidth() const
|
|
{
|
|
return m_pageCellWidth;
|
|
}
|
|
|
|
void HomeScreenState::calculatePageCellWidth()
|
|
{
|
|
qreal pageCellWidth = (pageColumns() == 0) ? 0 : qMax(0.0, std::round(m_pageContentWidth / pageColumns()));
|
|
|
|
if (m_pageCellWidth != pageCellWidth) {
|
|
m_pageCellWidth = pageCellWidth;
|
|
Q_EMIT pageCellWidthChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::pageCellHeight() const
|
|
{
|
|
return m_pageCellHeight;
|
|
}
|
|
|
|
void HomeScreenState::calculatePageCellHeight()
|
|
{
|
|
qreal pageCellHeight = (pageRows() == 0) ? 0 : std::round(m_pageContentHeight / pageRows());
|
|
|
|
if (m_pageCellHeight != pageCellHeight) {
|
|
m_pageCellHeight = pageCellHeight;
|
|
Q_EMIT pageCellHeightChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::pageDelegateLabelHeight() const
|
|
{
|
|
return m_pageDelegateLabelHeight;
|
|
}
|
|
|
|
void HomeScreenState::setPageDelegateLabelHeight(qreal pageDelegateLabelHeight)
|
|
{
|
|
if (m_pageDelegateLabelHeight != pageDelegateLabelHeight) {
|
|
m_pageDelegateLabelHeight = pageDelegateLabelHeight;
|
|
Q_EMIT pageDelegateLabelHeightChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::pageDelegateLabelSpacing() const
|
|
{
|
|
return m_pageDelegateLabelSpacing;
|
|
}
|
|
|
|
void HomeScreenState::setPageDelegateLabelSpacing(qreal pageDelegateLabelSpacing)
|
|
{
|
|
if (m_pageDelegateLabelSpacing != pageDelegateLabelSpacing) {
|
|
m_pageDelegateLabelSpacing = pageDelegateLabelSpacing;
|
|
Q_EMIT pageDelegateLabelSpacingChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::folderViewX() const
|
|
{
|
|
return m_folderViewX;
|
|
}
|
|
|
|
void HomeScreenState::setFolderViewX(qreal folderViewX)
|
|
{
|
|
if (m_folderViewX != folderViewX) {
|
|
m_folderViewX = folderViewX;
|
|
Q_EMIT folderViewXChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::folderPageWidth() const
|
|
{
|
|
return m_folderPageWidth;
|
|
}
|
|
|
|
void HomeScreenState::setFolderPageWidth(qreal folderPageWidth)
|
|
{
|
|
if (m_folderPageWidth != folderPageWidth) {
|
|
m_folderPageWidth = folderPageWidth;
|
|
Q_EMIT folderPageWidthChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::folderPageHeight() const
|
|
{
|
|
return m_folderPageHeight;
|
|
}
|
|
|
|
void HomeScreenState::setFolderPageHeight(qreal folderPageHeight)
|
|
{
|
|
if (m_folderPageHeight != folderPageHeight) {
|
|
m_folderPageHeight = folderPageHeight;
|
|
Q_EMIT folderPageHeightChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::folderPageContentWidth() const
|
|
{
|
|
return m_folderPageContentWidth;
|
|
}
|
|
|
|
void HomeScreenState::setFolderPageContentWidth(qreal folderPageContentWidth)
|
|
{
|
|
if (m_folderPageContentWidth != folderPageContentWidth) {
|
|
m_folderPageContentWidth = folderPageContentWidth;
|
|
Q_EMIT folderPageContentWidthChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::folderPageContentHeight() const
|
|
{
|
|
return m_folderPageContentHeight;
|
|
}
|
|
|
|
void HomeScreenState::setFolderPageContentHeight(qreal folderPageContentHeight)
|
|
{
|
|
if (m_folderPageContentHeight != folderPageContentHeight) {
|
|
m_folderPageContentHeight = folderPageContentHeight;
|
|
Q_EMIT folderPageContentHeightChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::folderOpenProgress() const
|
|
{
|
|
return m_folderOpenProgress;
|
|
}
|
|
|
|
void HomeScreenState::setFolderOpenProgress(qreal folderOpenProgress)
|
|
{
|
|
if (m_folderOpenProgress != folderOpenProgress) {
|
|
m_folderOpenProgress = folderOpenProgress;
|
|
Q_EMIT folderOpenProgressChanged();
|
|
}
|
|
}
|
|
|
|
FolioApplicationFolder *HomeScreenState::currentFolder() const
|
|
{
|
|
return m_currentFolder;
|
|
}
|
|
|
|
void HomeScreenState::setCurrentFolder(FolioApplicationFolder *folder)
|
|
{
|
|
if (m_currentFolder != folder) {
|
|
m_currentFolder = folder;
|
|
Q_EMIT currentFolderChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::settingsOpenProgress()
|
|
{
|
|
return m_settingsOpenProgress;
|
|
}
|
|
|
|
void HomeScreenState::setSettingsOpenProgress(qreal settingsOpenProgress)
|
|
{
|
|
if (m_settingsOpenProgress != settingsOpenProgress) {
|
|
m_settingsOpenProgress = settingsOpenProgress;
|
|
Q_EMIT settingsOpenProgressChanged();
|
|
}
|
|
}
|
|
|
|
qreal HomeScreenState::appDrawerOpenProgress()
|
|
{
|
|
return m_appDrawerOpenProgress;
|
|
}
|
|
|
|
qreal HomeScreenState::appDrawerY()
|
|
{
|
|
return m_appDrawerY;
|
|
}
|
|
|
|
void HomeScreenState::setAppDrawerY(qreal appDrawerY)
|
|
{
|
|
m_appDrawerY = appDrawerY;
|
|
m_appDrawerOpenProgress = 1 - qBound(0.0, m_appDrawerY, APP_DRAWER_OPEN_DIST) / APP_DRAWER_OPEN_DIST;
|
|
Q_EMIT appDrawerYChanged();
|
|
Q_EMIT appDrawerOpenProgressChanged();
|
|
}
|
|
|
|
qreal HomeScreenState::searchWidgetOpenProgress()
|
|
{
|
|
return m_searchWidgetOpenProgress;
|
|
}
|
|
|
|
qreal HomeScreenState::searchWidgetY()
|
|
{
|
|
return m_searchWidgetOpenProgress;
|
|
}
|
|
|
|
void HomeScreenState::setSearchWidgetY(qreal searchWidgetY)
|
|
{
|
|
m_searchWidgetY = searchWidgetY;
|
|
m_searchWidgetOpenProgress = 1 - qBound(0.0, m_searchWidgetY, SEARCH_WIDGET_OPEN_DIST) / SEARCH_WIDGET_OPEN_DIST;
|
|
Q_EMIT searchWidgetYChanged();
|
|
Q_EMIT searchWidgetOpenProgressChanged();
|
|
}
|
|
|
|
qreal HomeScreenState::delegateDragX()
|
|
{
|
|
return m_delegateDragX;
|
|
}
|
|
|
|
void HomeScreenState::setDelegateDragX(qreal delegateDragX)
|
|
{
|
|
m_delegateDragX = delegateDragX;
|
|
Q_EMIT delegateDragXChanged();
|
|
}
|
|
|
|
qreal HomeScreenState::delegateDragY()
|
|
{
|
|
return m_delegateDragY;
|
|
}
|
|
|
|
void HomeScreenState::setDelegateDragY(qreal delegateDragY)
|
|
{
|
|
m_delegateDragY = delegateDragY;
|
|
Q_EMIT delegateDragYChanged();
|
|
}
|
|
|
|
qreal HomeScreenState::delegateDragPointerOffsetX()
|
|
{
|
|
return m_delegateDragPointerOffsetX;
|
|
}
|
|
|
|
void HomeScreenState::setDelegateDragPointerOffsetX(qreal delegateDragPointerOffsetX)
|
|
{
|
|
m_delegateDragPointerOffsetX = delegateDragPointerOffsetX;
|
|
}
|
|
|
|
qreal HomeScreenState::delegateDragPointerOffsetY()
|
|
{
|
|
return m_delegateDragPointerOffsetY;
|
|
}
|
|
|
|
void HomeScreenState::setDelegateDragPointerOffsetY(qreal delegateDragPointerOffsetY)
|
|
{
|
|
m_delegateDragPointerOffsetY = delegateDragPointerOffsetY;
|
|
}
|
|
|
|
int HomeScreenState::currentPage()
|
|
{
|
|
return m_pageNum;
|
|
}
|
|
|
|
void HomeScreenState::setCurrentPage(int currentPage)
|
|
{
|
|
if (m_pageNum != currentPage) {
|
|
m_pageNum = currentPage;
|
|
Q_EMIT pageNumChanged();
|
|
}
|
|
}
|
|
|
|
int HomeScreenState::currentFolderPage()
|
|
{
|
|
return m_folderPageNum;
|
|
}
|
|
|
|
FolioDelegate *HomeScreenState::getPageDelegateAt(int page, int row, int column)
|
|
{
|
|
PageModel *pageModel = m_homeScreen->pageListModel()->getPage(page);
|
|
if (!pageModel) {
|
|
return nullptr;
|
|
}
|
|
|
|
FolioDelegate *delegate = pageModel->getDelegate(row, column);
|
|
if (!delegate) {
|
|
return nullptr;
|
|
}
|
|
|
|
return delegate;
|
|
}
|
|
|
|
FolioDelegate *HomeScreenState::getFavouritesDelegateAt(int position)
|
|
{
|
|
return m_homeScreen->favouritesModel()->getEntryAt(position);
|
|
}
|
|
|
|
FolioDelegate *HomeScreenState::getFolderDelegateAt(int position)
|
|
{
|
|
if (!m_currentFolder) {
|
|
return nullptr;
|
|
}
|
|
|
|
return m_currentFolder->applications()->getDelegate(position);
|
|
}
|
|
|
|
QPointF HomeScreenState::getPageDelegateScreenPosition(int page, int row, int column)
|
|
{
|
|
Q_UNUSED(page)
|
|
qreal x = m_viewLeftPadding + ((m_pageWidth - m_pageContentWidth) / 2) + (m_pageCellWidth * column);
|
|
qreal y = m_viewTopPadding + ((m_pageHeight - m_pageContentHeight) / 2) + (m_pageCellHeight * row);
|
|
return QPointF{x, y};
|
|
}
|
|
|
|
QPointF HomeScreenState::getFavouritesDelegateScreenPosition(int position)
|
|
{
|
|
return m_homeScreen->favouritesModel()->getDelegateScreenPosition(position);
|
|
}
|
|
|
|
QPointF HomeScreenState::getFolderDelegateScreenPosition(int position)
|
|
{
|
|
if (!m_currentFolder || position < 0 || position >= m_currentFolder->applications()->rowCount()) {
|
|
return {0, 0};
|
|
}
|
|
auto pos = m_currentFolder->applications()->getDelegatePosition(position);
|
|
qreal x = pos.x() + (m_viewWidth - m_viewLeftPadding - m_viewRightPadding - m_folderPageWidth) / 2;
|
|
qreal y = pos.y() + (m_viewHeight - m_viewTopPadding - m_viewBottomPadding - m_folderPageHeight) / 2;
|
|
x += m_viewLeftPadding;
|
|
y += m_viewTopPadding;
|
|
|
|
// adjust for the current page
|
|
x -= currentFolderPage() * m_folderPageWidth;
|
|
|
|
return {x, y};
|
|
}
|
|
|
|
void HomeScreenState::openAppDrawer()
|
|
{
|
|
cancelAppDrawerAnimations();
|
|
m_openAppDrawerAnim->setStartValue(m_appDrawerY);
|
|
m_openAppDrawerAnim->start();
|
|
}
|
|
|
|
void HomeScreenState::closeAppDrawer()
|
|
{
|
|
cancelAppDrawerAnimations();
|
|
m_closeAppDrawerAnim->setStartValue(m_appDrawerY);
|
|
m_closeAppDrawerAnim->start();
|
|
}
|
|
|
|
void HomeScreenState::openSearchWidget()
|
|
{
|
|
cancelSearchWidgetAnimations();
|
|
m_openSearchWidgetAnim->setStartValue(m_searchWidgetY);
|
|
m_openSearchWidgetAnim->start();
|
|
}
|
|
|
|
void HomeScreenState::closeSearchWidget()
|
|
{
|
|
cancelSearchWidgetAnimations();
|
|
m_closeSearchWidgetAnim->setStartValue(m_searchWidgetY);
|
|
m_closeSearchWidgetAnim->start();
|
|
}
|
|
|
|
void HomeScreenState::snapPage()
|
|
{
|
|
const int numOfPages = m_homeScreen->pageListModel()->rowCount();
|
|
|
|
const int leftPage = qBound(0.0, (m_pageViewX / m_pageWidth), numOfPages - 1.0);
|
|
const qreal leftPagePos = -leftPage * m_pageWidth;
|
|
|
|
if (leftPage == numOfPages + 1) {
|
|
// if we are past the last page
|
|
goToPage(leftPage);
|
|
} else {
|
|
const qreal rightPagePos = leftPagePos - m_pageWidth;
|
|
|
|
// go to the closer page (right or left)
|
|
if (qAbs(rightPagePos - m_pageViewX) < qAbs(leftPagePos - m_pageViewX)) {
|
|
goToPage(leftPage + 1);
|
|
} else {
|
|
goToPage(leftPage);
|
|
}
|
|
}
|
|
}
|
|
|
|
void HomeScreenState::goToPage(int page)
|
|
{
|
|
if (page < 0) {
|
|
page = 0;
|
|
}
|
|
|
|
const int numOfPages = m_homeScreen->pageListModel()->rowCount();
|
|
if (page >= numOfPages) {
|
|
page = std::max(0, numOfPages - 1);
|
|
}
|
|
|
|
setCurrentPage(page);
|
|
|
|
m_pageAnim->setStartValue(m_pageViewX);
|
|
m_pageAnim->setEndValue(-page * m_pageWidth);
|
|
m_pageAnim->start();
|
|
}
|
|
|
|
void HomeScreenState::goToFolderPage(int page)
|
|
{
|
|
if (!m_currentFolder) {
|
|
return;
|
|
}
|
|
|
|
if (page < 0) {
|
|
page = 0;
|
|
}
|
|
|
|
int numOfPages = m_currentFolder->applications()->numTotalPages();
|
|
if (page >= numOfPages) {
|
|
page = std::max(0, numOfPages - 1);
|
|
}
|
|
|
|
m_folderPageNum = page;
|
|
Q_EMIT folderPageNumChanged();
|
|
|
|
m_folderPageAnim->setStartValue(m_folderViewX);
|
|
m_folderPageAnim->setEndValue(-page * m_folderPageWidth);
|
|
m_folderPageAnim->start();
|
|
}
|
|
|
|
void HomeScreenState::openFolder(qreal delegateX, qreal delegateY, FolioApplicationFolder *folder)
|
|
{
|
|
setCurrentFolder(folder);
|
|
|
|
m_openFolderAnim->stop();
|
|
m_closeFolderAnim->stop();
|
|
m_openFolderAnim->setStartValue(m_folderOpenProgress);
|
|
m_openFolderAnim->start();
|
|
|
|
Q_EMIT folderAboutToOpen(delegateX, delegateY);
|
|
}
|
|
|
|
void HomeScreenState::closeFolder()
|
|
{
|
|
m_openFolderAnim->stop();
|
|
m_closeFolderAnim->stop();
|
|
m_closeFolderAnim->setStartValue(m_folderOpenProgress);
|
|
m_closeFolderAnim->start();
|
|
}
|
|
|
|
void HomeScreenState::openSettingsView()
|
|
{
|
|
m_closeSettingsAnim->stop();
|
|
m_openSettingsAnim->stop();
|
|
m_openSettingsAnim->setStartValue(m_settingsOpenProgress);
|
|
m_openSettingsAnim->start();
|
|
}
|
|
|
|
void HomeScreenState::closeSettingsView()
|
|
{
|
|
m_openSettingsAnim->stop();
|
|
m_closeSettingsAnim->stop();
|
|
m_closeSettingsAnim->setStartValue(m_settingsOpenProgress);
|
|
m_closeSettingsAnim->start();
|
|
}
|
|
|
|
void HomeScreenState::startDelegateDrag(qreal startX, qreal startY, qreal pointerOffsetX, qreal pointerOffsetY)
|
|
{
|
|
// start drag and drop positions
|
|
setDelegateDragX(startX);
|
|
setDelegateDragY(startY);
|
|
setDelegateDragPointerOffsetX(pointerOffsetX);
|
|
setDelegateDragPointerOffsetY(pointerOffsetY);
|
|
|
|
// end current swipe
|
|
swipeEnded();
|
|
|
|
// start the delegate drag
|
|
setSwipeState(SwipeState::AwaitingDraggingDelegate);
|
|
}
|
|
|
|
void HomeScreenState::startDelegatePageDrag(qreal startX, qreal startY, qreal pointerOffsetX, qreal pointerOffsetY, int page, int row, int column)
|
|
{
|
|
startDelegateDrag(startX, startY, pointerOffsetX, pointerOffsetY);
|
|
Q_EMIT delegateDragFromPageStarted(page, row, column);
|
|
}
|
|
|
|
void HomeScreenState::startDelegateFavouritesDrag(qreal startX, qreal startY, qreal pointerOffsetX, qreal pointerOffsetY, int position)
|
|
{
|
|
startDelegateDrag(startX, startY, pointerOffsetX, pointerOffsetY);
|
|
Q_EMIT delegateDragFromFavouritesStarted(position);
|
|
}
|
|
|
|
void HomeScreenState::startDelegateAppDrawerDrag(qreal startX, qreal startY, qreal pointerOffsetX, qreal pointerOffsetY, QString storageId)
|
|
{
|
|
startDelegateDrag(startX, startY, pointerOffsetX, pointerOffsetY);
|
|
Q_EMIT delegateDragFromAppDrawerStarted(storageId);
|
|
|
|
// we start dragging the delegate immediately from the app drawer, because we don't have a context menu to deal with!
|
|
// NOTE: this has to happen after delegateDragFromAppDrawerStarted, because slots for that expect SwipeState::AwaitingDraggingDelegate
|
|
setSwipeState(SwipeState::DraggingDelegate);
|
|
}
|
|
|
|
void HomeScreenState::startDelegateFolderDrag(qreal startX,
|
|
qreal startY,
|
|
qreal pointerOffsetX,
|
|
qreal pointerOffsetY,
|
|
FolioApplicationFolder *folder,
|
|
int position)
|
|
{
|
|
startDelegateDrag(startX, startY, pointerOffsetX, pointerOffsetY);
|
|
Q_EMIT delegateDragFromFolderStarted(folder, position);
|
|
}
|
|
|
|
void HomeScreenState::startDelegateWidgetListDrag(qreal startX, qreal startY, qreal pointerOffsetX, qreal pointerOffsetY, QString appletPluginId)
|
|
{
|
|
startDelegateDrag(startX, startY, pointerOffsetX, pointerOffsetY);
|
|
Q_EMIT delegateDragFromWidgetListStarted(appletPluginId);
|
|
|
|
// we start dragging the delegate immediately from the app drawer, because we don't have a context menu to deal with!
|
|
// NOTE: this has to happen after delegateDragFromAppDrawerStarted, because slots for that expect SwipeState::AwaitingDraggingDelegate
|
|
setSwipeState(SwipeState::DraggingDelegate);
|
|
}
|
|
|
|
void HomeScreenState::cancelDelegateDrag()
|
|
{
|
|
swipeEnded();
|
|
}
|
|
|
|
void HomeScreenState::swipeStarted()
|
|
{
|
|
if (m_swipeState != SwipeState::None) {
|
|
return;
|
|
}
|
|
|
|
setSwipeState(SwipeState::DeterminingSwipeType);
|
|
}
|
|
|
|
void HomeScreenState::swipeEnded()
|
|
{
|
|
switch (m_swipeState) {
|
|
case SwipeState::SwipingOpenAppDrawer:
|
|
case SwipeState::SwipingCloseAppDrawer:
|
|
if (m_movingUp) {
|
|
closeAppDrawer();
|
|
} else {
|
|
openAppDrawer();
|
|
}
|
|
break;
|
|
case SwipeState::SwipingAppDrawerGrid:
|
|
Q_EMIT appDrawerGridFlickRequested();
|
|
break;
|
|
case SwipeState::SwipingOpenSearchWidget:
|
|
case SwipeState::SwipingCloseSearchWidget:
|
|
if (m_movingUp) {
|
|
openSearchWidget();
|
|
} else {
|
|
closeSearchWidget();
|
|
}
|
|
break;
|
|
case SwipeState::SwipingPages: {
|
|
int page = std::max(0.0, -m_pageViewX) / m_pageWidth;
|
|
|
|
// m_movingRight refers to finger movement
|
|
if (m_movingRight || m_pageViewX > 0) {
|
|
goToPage(page);
|
|
} else {
|
|
goToPage(page + 1);
|
|
}
|
|
break;
|
|
}
|
|
case SwipeState::SwipingFolderPages: {
|
|
int page = std::max(0.0, -m_folderViewX) / m_folderPageWidth;
|
|
|
|
// m_movingRight refers to finger movement
|
|
if (m_movingRight || m_folderViewX > 0) {
|
|
goToFolderPage(page);
|
|
} else {
|
|
goToFolderPage(page + 1);
|
|
}
|
|
break;
|
|
}
|
|
case SwipeState::DraggingDelegate:
|
|
Q_EMIT delegateDragEnded();
|
|
break;
|
|
case SwipeState::AwaitingDraggingDelegate:
|
|
case SwipeState::DeterminingSwipeType:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
setSwipeState(SwipeState::None);
|
|
}
|
|
|
|
void HomeScreenState::swipeMoved(qreal totalDeltaX, qreal totalDeltaY, qreal deltaX, qreal deltaY)
|
|
{
|
|
m_movingUp = deltaY > 0;
|
|
|
|
switch (m_swipeState) {
|
|
case SwipeState::DeterminingSwipeType:
|
|
// check if we can determine the type of swipe this is
|
|
determineSwipeTypeAfterThreshold(totalDeltaX, totalDeltaY);
|
|
break;
|
|
case SwipeState::SwipingOpenSearchWidget:
|
|
case SwipeState::SwipingCloseSearchWidget:
|
|
setSearchWidgetY(m_searchWidgetY - deltaY);
|
|
break;
|
|
case SwipeState::SwipingOpenAppDrawer:
|
|
case SwipeState::SwipingCloseAppDrawer:
|
|
setAppDrawerY(m_appDrawerY + deltaY);
|
|
break;
|
|
case SwipeState::SwipingAppDrawerGrid:
|
|
Q_EMIT appDrawerGridYChanged(deltaY);
|
|
break;
|
|
case SwipeState::SwipingPages:
|
|
m_movingRight = deltaX > 0;
|
|
setPageViewX(m_pageViewX + deltaX);
|
|
break;
|
|
case SwipeState::SwipingFolderPages:
|
|
m_movingRight = deltaX > 0;
|
|
setFolderViewX(m_folderViewX + deltaX);
|
|
break;
|
|
case SwipeState::AwaitingDraggingDelegate:
|
|
setSwipeState(SwipeState::DraggingDelegate);
|
|
break;
|
|
case SwipeState::DraggingDelegate:
|
|
setDelegateDragX(m_delegateDragX + deltaX);
|
|
setDelegateDragY(m_delegateDragY + deltaY);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void HomeScreenState::determineSwipeTypeAfterThreshold(qreal totalDeltaX, qreal totalDeltaY)
|
|
{
|
|
// we check if the x or y movement has passed a certain threshold before determining the swipe type
|
|
|
|
if (qAbs(totalDeltaX) >= DETERMINE_SWIPE_THRESHOLD && (m_viewState == ViewState::PageView || m_viewState == ViewState::SettingsView)) {
|
|
// select horizontal swipe mode (only if in page view)
|
|
setSwipeState(SwipeState::SwipingPages);
|
|
|
|
// ensure no animations are running when starting a swipe
|
|
m_pageAnim->stop();
|
|
|
|
} else if (qAbs(totalDeltaX) >= DETERMINE_SWIPE_THRESHOLD && m_viewState == ViewState::FolderView) {
|
|
// select horizontal swipe mode (only if in page view)
|
|
setSwipeState(SwipeState::SwipingFolderPages);
|
|
|
|
// ensure no animations are running when starting a swipe
|
|
m_folderPageAnim->stop();
|
|
|
|
} else if (qAbs(totalDeltaY) >= DETERMINE_SWIPE_THRESHOLD) {
|
|
// select vertical swipe mode
|
|
|
|
if (m_movingUp) {
|
|
// moving up
|
|
switch (m_viewState) {
|
|
case ViewState::PageView:
|
|
// if the app drawer is still being opened
|
|
if (m_openAppDrawerAnim->state() == QPropertyAnimation::Running) {
|
|
setSwipeState(SwipeState::SwipingOpenAppDrawer);
|
|
cancelAppDrawerAnimations();
|
|
} else {
|
|
setSwipeState(SwipeState::SwipingOpenSearchWidget);
|
|
cancelSearchWidgetAnimations();
|
|
}
|
|
break;
|
|
case ViewState::AppDrawerView:
|
|
setSwipeState(SwipeState::SwipingCloseAppDrawer);
|
|
cancelAppDrawerAnimations();
|
|
break;
|
|
case ViewState::SearchWidgetView:
|
|
setSwipeState(SwipeState::SwipingCloseSearchWidget);
|
|
cancelSearchWidgetAnimations();
|
|
case ViewState::FolderView:
|
|
case ViewState::SettingsView:
|
|
// no vertical behaviour in folder or settings view
|
|
default:
|
|
break;
|
|
}
|
|
} else {
|
|
// moving down
|
|
switch (m_viewState) {
|
|
case ViewState::PageView:
|
|
if (m_openSearchWidgetAnim->state() == QPropertyAnimation::Running) {
|
|
setSwipeState(SwipeState::SwipingOpenSearchWidget);
|
|
cancelSearchWidgetAnimations();
|
|
} else {
|
|
setSwipeState(SwipeState::SwipingOpenAppDrawer);
|
|
cancelAppDrawerAnimations();
|
|
}
|
|
break;
|
|
case ViewState::SearchWidgetView:
|
|
setSwipeState(SwipeState::SwipingCloseSearchWidget);
|
|
cancelSearchWidgetAnimations();
|
|
break;
|
|
case ViewState::AppDrawerView:
|
|
setSwipeState(SwipeState::SwipingAppDrawerGrid);
|
|
// don't call cancelAppDrawerAnimations(), so we don't have it half open
|
|
case ViewState::FolderView:
|
|
case ViewState::SettingsView:
|
|
// no vertical behaviour in folder or settings view
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void HomeScreenState::cancelAppDrawerAnimations()
|
|
{
|
|
m_openAppDrawerAnim->stop();
|
|
m_closeAppDrawerAnim->stop();
|
|
}
|
|
|
|
void HomeScreenState::cancelSearchWidgetAnimations()
|
|
{
|
|
m_openSearchWidgetAnim->stop();
|
|
m_closeSearchWidgetAnim->stop();
|
|
}
|