mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-07-26 06:14:45 +00:00
homescreens/folio: Homescreen folder page snapping position bugfix
This fixes an issue where if the device is rotated in a folder, the page would not snap immediately back to the right position, but would instead animate icon position changes. To achieve this, the following changes were made. - changes were made to how the folder gird size is calculated to prevent an issue with the grid size changing for a brief period of time during screen rotation, causing problems with snapping to the correct page. - icons position animations are now done by a animated index value to prevent it from animating when the device rotates - when the device screen size changes (ex: device rotation), it now snaps to the current folder page, as before it would just stay in between the two pages.
This commit is contained in:
parent
a508c8d524
commit
f52bf0bd71
6 changed files with 175 additions and 144 deletions
|
|
@ -694,7 +694,7 @@ void DragState::onChangeFolderPageTimerFinished()
|
||||||
// if we are at the left edge, go left
|
// if we are at the left edge, go left
|
||||||
int page = m_state->currentFolderPage() - 1;
|
int page = m_state->currentFolderPage() - 1;
|
||||||
if (page >= 0) {
|
if (page >= 0) {
|
||||||
m_state->goToFolderPage(page);
|
m_state->goToFolderPage(page, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (x >= rightPagePosition - PAGE_CHANGE_THRESHOLD) {
|
} else if (x >= rightPagePosition - PAGE_CHANGE_THRESHOLD) {
|
||||||
|
|
@ -703,7 +703,7 @@ void DragState::onChangeFolderPageTimerFinished()
|
||||||
|
|
||||||
// go to page if it exists
|
// go to page if it exists
|
||||||
if (page < folder->applications()->numTotalPages()) {
|
if (page < folder->applications()->numTotalPages()) {
|
||||||
m_state->goToFolderPage(page);
|
m_state->goToFolderPage(page, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ void FolioApplicationFolder::setApplications(QList<FolioApplication *> applicati
|
||||||
m_delegates.append({new FolioDelegate{app, m_homeScreen}, 0, 0});
|
m_delegates.append({new FolioDelegate{app, m_homeScreen}, 0, 0});
|
||||||
}
|
}
|
||||||
m_applicationFolderModel = new ApplicationFolderModel{this};
|
m_applicationFolderModel = new ApplicationFolderModel{this};
|
||||||
m_applicationFolderModel->evaluateDelegatePositions();
|
m_applicationFolderModel->evaluateDelegateIndexes();
|
||||||
|
|
||||||
Q_EMIT applicationsChanged();
|
Q_EMIT applicationsChanged();
|
||||||
Q_EMIT applicationsReset();
|
Q_EMIT applicationsReset();
|
||||||
|
|
@ -128,28 +128,28 @@ ApplicationFolderModel::ApplicationFolderModel(FolioApplicationFolder *folder)
|
||||||
{
|
{
|
||||||
HomeScreenState *homeScreenState = folder->m_homeScreen->homeScreenState();
|
HomeScreenState *homeScreenState = folder->m_homeScreen->homeScreenState();
|
||||||
connect(homeScreenState, &HomeScreenState::folderPageWidthChanged, this, [this]() {
|
connect(homeScreenState, &HomeScreenState::folderPageWidthChanged, this, [this]() {
|
||||||
evaluateDelegatePositions();
|
evaluateDelegateIndexes();
|
||||||
});
|
});
|
||||||
connect(homeScreenState, &HomeScreenState::folderPageHeightChanged, this, [this]() {
|
connect(homeScreenState, &HomeScreenState::folderPageHeightChanged, this, [this]() {
|
||||||
evaluateDelegatePositions();
|
evaluateDelegateIndexes();
|
||||||
});
|
});
|
||||||
connect(homeScreenState, &HomeScreenState::folderPageContentWidthChanged, this, [this]() {
|
connect(homeScreenState, &HomeScreenState::folderPageContentWidthChanged, this, [this]() {
|
||||||
evaluateDelegatePositions();
|
evaluateDelegateIndexes();
|
||||||
});
|
});
|
||||||
connect(homeScreenState, &HomeScreenState::folderPageContentHeightChanged, this, [this]() {
|
connect(homeScreenState, &HomeScreenState::folderPageContentHeightChanged, this, [this]() {
|
||||||
evaluateDelegatePositions();
|
evaluateDelegateIndexes();
|
||||||
});
|
});
|
||||||
connect(homeScreenState, &HomeScreenState::viewWidthChanged, this, [this]() {
|
connect(homeScreenState, &HomeScreenState::viewWidthChanged, this, [this]() {
|
||||||
evaluateDelegatePositions();
|
evaluateDelegateIndexes();
|
||||||
});
|
});
|
||||||
connect(homeScreenState, &HomeScreenState::viewHeightChanged, this, [this]() {
|
connect(homeScreenState, &HomeScreenState::viewHeightChanged, this, [this]() {
|
||||||
evaluateDelegatePositions();
|
evaluateDelegateIndexes();
|
||||||
});
|
});
|
||||||
connect(homeScreenState, &HomeScreenState::pageCellWidthChanged, this, [this]() {
|
connect(homeScreenState, &HomeScreenState::pageCellWidthChanged, this, [this]() {
|
||||||
evaluateDelegatePositions();
|
evaluateDelegateIndexes();
|
||||||
});
|
});
|
||||||
connect(homeScreenState, &HomeScreenState::pageCellHeightChanged, this, [this]() {
|
connect(homeScreenState, &HomeScreenState::pageCellHeightChanged, this, [this]() {
|
||||||
evaluateDelegatePositions();
|
evaluateDelegateIndexes();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,10 +167,12 @@ QVariant ApplicationFolderModel::data(const QModelIndex &index, int role) const
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case DelegateRole:
|
case DelegateRole:
|
||||||
return QVariant::fromValue(m_folder->m_delegates.at(index.row()).delegate);
|
return QVariant::fromValue(m_folder->m_delegates.at(index.row()).delegate);
|
||||||
case XPositionRole:
|
case columnIndexRole:
|
||||||
return QVariant::fromValue(m_folder->m_delegates.at(index.row()).xPosition);
|
return QVariant::fromValue(m_folder->m_delegates.at(index.row()).columnIndex);
|
||||||
case YPositionRole:
|
case rowIndexRole:
|
||||||
return QVariant::fromValue(m_folder->m_delegates.at(index.row()).yPosition);
|
return QVariant::fromValue(m_folder->m_delegates.at(index.row()).rowIndex);
|
||||||
|
case pageIndexRole:
|
||||||
|
return QVariant::fromValue(m_folder->m_delegates.at(index.row()).pageIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
@ -178,7 +180,7 @@ QVariant ApplicationFolderModel::data(const QModelIndex &index, int role) const
|
||||||
|
|
||||||
QHash<int, QByteArray> ApplicationFolderModel::roleNames() const
|
QHash<int, QByteArray> ApplicationFolderModel::roleNames() const
|
||||||
{
|
{
|
||||||
return {{DelegateRole, "delegate"}, {XPositionRole, "xPosition"}, {YPositionRole, "yPosition"}};
|
return {{DelegateRole, "delegate"}, {columnIndexRole, "columnIndex"}, {rowIndexRole, "rowIndex"}, {pageIndexRole, "pageIndex"}};
|
||||||
}
|
}
|
||||||
|
|
||||||
FolioDelegate *ApplicationFolderModel::getDelegate(int index)
|
FolioDelegate *ApplicationFolderModel::getDelegate(int index)
|
||||||
|
|
@ -209,7 +211,7 @@ void ApplicationFolderModel::moveEntry(int fromRow, int toRow)
|
||||||
}
|
}
|
||||||
endMoveRows();
|
endMoveRows();
|
||||||
|
|
||||||
evaluateDelegatePositions();
|
evaluateDelegateIndexes();
|
||||||
|
|
||||||
Q_EMIT m_folder->applicationsChanged();
|
Q_EMIT m_folder->applicationsChanged();
|
||||||
Q_EMIT m_folder->saveRequested();
|
Q_EMIT m_folder->saveRequested();
|
||||||
|
|
@ -237,18 +239,18 @@ bool ApplicationFolderModel::addDelegate(FolioDelegate *delegate, int index)
|
||||||
if (index == m_folder->m_delegates.size()) {
|
if (index == m_folder->m_delegates.size()) {
|
||||||
beginInsertRows(QModelIndex(), index, index);
|
beginInsertRows(QModelIndex(), index, index);
|
||||||
m_folder->m_delegates.append({delegate, 0, 0});
|
m_folder->m_delegates.append({delegate, 0, 0});
|
||||||
evaluateDelegatePositions(false);
|
evaluateDelegateIndexes(false);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
} else if (m_folder->m_delegates[index].delegate->type() == FolioDelegate::None) {
|
} else if (m_folder->m_delegates[index].delegate->type() == FolioDelegate::None) {
|
||||||
replaceGhostEntry(delegate);
|
replaceGhostEntry(delegate);
|
||||||
} else {
|
} else {
|
||||||
beginInsertRows(QModelIndex(), index, index);
|
beginInsertRows(QModelIndex(), index, index);
|
||||||
m_folder->m_delegates.insert(index, {delegate, 0, 0});
|
m_folder->m_delegates.insert(index, {delegate, 0, 0});
|
||||||
evaluateDelegatePositions(false);
|
evaluateDelegateIndexes(false);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
evaluateDelegatePositions();
|
evaluateDelegateIndexes();
|
||||||
|
|
||||||
Q_EMIT m_folder->applicationsChanged();
|
Q_EMIT m_folder->applicationsChanged();
|
||||||
Q_EMIT m_folder->saveRequested();
|
Q_EMIT m_folder->saveRequested();
|
||||||
|
|
@ -268,7 +270,7 @@ void ApplicationFolderModel::removeDelegate(int index)
|
||||||
m_folder->m_delegates.removeAt(index);
|
m_folder->m_delegates.removeAt(index);
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
|
|
||||||
evaluateDelegatePositions();
|
evaluateDelegateIndexes();
|
||||||
|
|
||||||
Q_EMIT m_folder->applicationsChanged();
|
Q_EMIT m_folder->applicationsChanged();
|
||||||
Q_EMIT m_folder->saveRequested();
|
Q_EMIT m_folder->saveRequested();
|
||||||
|
|
@ -280,7 +282,18 @@ QPointF ApplicationFolderModel::getDelegatePosition(int index)
|
||||||
return {0, 0};
|
return {0, 0};
|
||||||
}
|
}
|
||||||
auto delegate = m_folder->m_delegates[index];
|
auto delegate = m_folder->m_delegates[index];
|
||||||
return {delegate.xPosition, delegate.yPosition};
|
qreal pageContentWidth = m_folder->m_homeScreen->homeScreenState()->folderPageContentWidth();
|
||||||
|
qreal margin = horizontalPageMargin();
|
||||||
|
|
||||||
|
int cellSize = pageContentWidth / numGridLengthOnPage();
|
||||||
|
|
||||||
|
qreal cellWitdhRecenter = (cellSize - m_folder->m_homeScreen->homeScreenState()->pageCellWidth()) / 2;
|
||||||
|
qreal cellHeightRecenter = (cellSize - m_folder->m_homeScreen->homeScreenState()->pageCellHeight()) / 2;
|
||||||
|
|
||||||
|
qreal xPosition = cellWitdhRecenter + margin + delegate.columnIndex * cellSize;
|
||||||
|
qreal yPosition = cellHeightRecenter + delegate.rowIndex * cellSize;
|
||||||
|
|
||||||
|
return {xPosition, yPosition};
|
||||||
}
|
}
|
||||||
|
|
||||||
int ApplicationFolderModel::getGhostEntryPosition()
|
int ApplicationFolderModel::getGhostEntryPosition()
|
||||||
|
|
@ -344,27 +357,27 @@ void ApplicationFolderModel::deleteGhostEntry()
|
||||||
|
|
||||||
int ApplicationFolderModel::dropInsertPosition(int page, qreal x, qreal y)
|
int ApplicationFolderModel::dropInsertPosition(int page, qreal x, qreal y)
|
||||||
{
|
{
|
||||||
qreal cellWidth = m_folder->m_homeScreen->homeScreenState()->pageCellWidth();
|
qreal pageContentWidth = m_folder->m_homeScreen->homeScreenState()->folderPageContentWidth();
|
||||||
qreal cellHeight = m_folder->m_homeScreen->homeScreenState()->pageCellHeight();
|
qreal cellSize = (pageContentWidth) / numGridLengthOnPage();
|
||||||
|
|
||||||
int row = (y - topMarginFromScreenEdge()) / cellHeight;
|
int row = (y - topMarginFromScreenEdge()) / cellSize;
|
||||||
row = std::max(0, std::min(numRowsOnPage(), row));
|
row = std::max(0, std::min(numGridLengthOnPage(), row));
|
||||||
|
|
||||||
// the index that the position is over
|
// the index that the position is over
|
||||||
int leftColumn = std::max(0.0, x - leftMarginFromScreenEdge()) / cellWidth;
|
int leftColumn = std::max(0.0, x - leftMarginFromScreenEdge()) / cellSize;
|
||||||
leftColumn = std::min(numColumnsOnPage() - 1, leftColumn);
|
leftColumn = std::min(numGridLengthOnPage() - 1, leftColumn);
|
||||||
|
|
||||||
qreal leftColumnPosition = leftColumn * cellWidth + leftMarginFromScreenEdge();
|
qreal leftColumnPosition = leftColumn * cellSize + leftMarginFromScreenEdge();
|
||||||
|
|
||||||
int column = leftColumn + 1;
|
int column = leftColumn + 1;
|
||||||
|
|
||||||
// if it's the left half of this position or it's the last column on this row, return itself
|
// if it's the left half of this position or it's the last column on this row, return itself
|
||||||
if ((x < leftColumnPosition + cellWidth * 0.5) || (leftColumn == numColumnsOnPage() - 1)) {
|
if ((x < leftColumnPosition + cellSize * 0.5) || (leftColumn == numGridLengthOnPage() - 1)) {
|
||||||
column = leftColumn;
|
column = leftColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate the position based on the page, row and column it is at
|
// calculate the position based on the page, row and column it is at
|
||||||
int pos = (page * numRowsOnPage() * numColumnsOnPage()) + (row * numColumnsOnPage()) + column;
|
int pos = (page * numGridLengthOnPage() * numGridLengthOnPage()) + (row * numGridLengthOnPage()) + column;
|
||||||
// make sure it's in bounds
|
// make sure it's in bounds
|
||||||
return std::min((int)m_folder->m_delegates.size(), std::max(0, pos));
|
return std::min((int)m_folder->m_delegates.size(), std::max(0, pos));
|
||||||
}
|
}
|
||||||
|
|
@ -375,17 +388,10 @@ bool ApplicationFolderModel::isDropPositionOutside(qreal x, qreal y)
|
||||||
|| (y < topMarginFromScreenEdge()) || (y > m_folder->m_homeScreen->homeScreenState()->viewHeight() - topMarginFromScreenEdge());
|
|| (y < topMarginFromScreenEdge()) || (y > m_folder->m_homeScreen->homeScreenState()->viewHeight() - topMarginFromScreenEdge());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationFolderModel::evaluateDelegatePositions(bool emitSignal)
|
void ApplicationFolderModel::evaluateDelegateIndexes(bool emitSignal)
|
||||||
{
|
{
|
||||||
qreal pageWidth = m_folder->m_homeScreen->homeScreenState()->folderPageWidth();
|
int rows = numGridLengthOnPage();
|
||||||
qreal topMargin = verticalPageMargin();
|
int columns = numGridLengthOnPage();
|
||||||
qreal leftMargin = horizontalPageMargin();
|
|
||||||
|
|
||||||
qreal cellWidth = m_folder->m_homeScreen->homeScreenState()->pageCellWidth();
|
|
||||||
qreal cellHeight = m_folder->m_homeScreen->homeScreenState()->pageCellHeight();
|
|
||||||
|
|
||||||
int rows = numRowsOnPage();
|
|
||||||
int columns = numColumnsOnPage();
|
|
||||||
int numOfDelegates = m_folder->m_delegates.size();
|
int numOfDelegates = m_folder->m_delegates.size();
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
@ -394,11 +400,12 @@ void ApplicationFolderModel::evaluateDelegatePositions(bool emitSignal)
|
||||||
while (index < m_folder->m_delegates.size()) {
|
while (index < m_folder->m_delegates.size()) {
|
||||||
int prevIndex = index;
|
int prevIndex = index;
|
||||||
|
|
||||||
// determine positions page-by-page
|
// determine the row and column index page-by-page
|
||||||
for (int row = 0; row < rows && index < numOfDelegates; row++) {
|
for (int row = 0; row < rows && index < numOfDelegates; row++) {
|
||||||
for (int column = 0; column < columns && index < numOfDelegates; column++) {
|
for (int column = 0; column < columns && index < numOfDelegates; column++) {
|
||||||
m_folder->m_delegates[index].xPosition = qRound(page * pageWidth + leftMargin + column * cellWidth);
|
m_folder->m_delegates[index].columnIndex = column;
|
||||||
m_folder->m_delegates[index].yPosition = qRound(topMargin + row * cellHeight);
|
m_folder->m_delegates[index].rowIndex = row;
|
||||||
|
m_folder->m_delegates[index].pageIndex = page;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -411,8 +418,9 @@ void ApplicationFolderModel::evaluateDelegatePositions(bool emitSignal)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emitSignal) {
|
if (emitSignal) {
|
||||||
Q_EMIT dataChanged(createIndex(0, 0), createIndex(m_folder->m_delegates.size() - 1, 0), {XPositionRole});
|
Q_EMIT dataChanged(createIndex(0, 0), createIndex(m_folder->m_delegates.size() - 1, 0), {columnIndexRole});
|
||||||
Q_EMIT dataChanged(createIndex(0, 0), createIndex(m_folder->m_delegates.size() - 1, 0), {YPositionRole});
|
Q_EMIT dataChanged(createIndex(0, 0), createIndex(m_folder->m_delegates.size() - 1, 0), {rowIndexRole});
|
||||||
|
Q_EMIT dataChanged(createIndex(0, 0), createIndex(m_folder->m_delegates.size() - 1, 0), {pageIndexRole});
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_EMIT numberOfPagesChanged();
|
Q_EMIT numberOfPagesChanged();
|
||||||
|
|
@ -429,26 +437,13 @@ QPointF ApplicationFolderModel::getDelegateStartPosition(int page)
|
||||||
|
|
||||||
int ApplicationFolderModel::numTotalPages()
|
int ApplicationFolderModel::numTotalPages()
|
||||||
{
|
{
|
||||||
int numOfDelegatesOnPage = numRowsOnPage() * numColumnsOnPage();
|
int numOfDelegatesOnPage = numGridLengthOnPage() * numGridLengthOnPage();
|
||||||
return std::ceil(((qreal)m_folder->m_delegates.size()) / numOfDelegatesOnPage);
|
return std::ceil(((qreal)m_folder->m_delegates.size()) / numOfDelegatesOnPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ApplicationFolderModel::numRowsOnPage()
|
int ApplicationFolderModel::numGridLengthOnPage()
|
||||||
{
|
{
|
||||||
HomeScreenState *homeScreenState = m_folder->m_homeScreen->homeScreenState();
|
return m_folder->m_homeScreen->homeScreenState()->folderGridLength();
|
||||||
qreal contentHeight = homeScreenState->folderPageContentHeight();
|
|
||||||
qreal cellHeight = homeScreenState->pageCellHeight();
|
|
||||||
|
|
||||||
return std::max(0.0, contentHeight / cellHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ApplicationFolderModel::numColumnsOnPage()
|
|
||||||
{
|
|
||||||
HomeScreenState *homeScreenState = m_folder->m_homeScreen->homeScreenState();
|
|
||||||
qreal contentWidth = homeScreenState->folderPageContentWidth();
|
|
||||||
qreal cellWidth = homeScreenState->pageCellWidth();
|
|
||||||
|
|
||||||
return std::max(0.0, contentWidth / cellWidth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal ApplicationFolderModel::leftMarginFromScreenEdge()
|
qreal ApplicationFolderModel::leftMarginFromScreenEdge()
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,9 @@ private:
|
||||||
|
|
||||||
struct ApplicationDelegate {
|
struct ApplicationDelegate {
|
||||||
FolioDelegate *delegate;
|
FolioDelegate *delegate;
|
||||||
qreal xPosition;
|
int columnIndex;
|
||||||
qreal yPosition;
|
int rowIndex;
|
||||||
|
int pageIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ApplicationFolderModel : public QAbstractListModel
|
class ApplicationFolderModel : public QAbstractListModel
|
||||||
|
|
@ -86,8 +87,9 @@ class ApplicationFolderModel : public QAbstractListModel
|
||||||
public:
|
public:
|
||||||
enum Roles {
|
enum Roles {
|
||||||
DelegateRole = Qt::UserRole + 1,
|
DelegateRole = Qt::UserRole + 1,
|
||||||
XPositionRole,
|
columnIndexRole,
|
||||||
YPositionRole,
|
rowIndexRole,
|
||||||
|
pageIndexRole,
|
||||||
};
|
};
|
||||||
ApplicationFolderModel(FolioApplicationFolder *folder);
|
ApplicationFolderModel(FolioApplicationFolder *folder);
|
||||||
|
|
||||||
|
|
@ -126,13 +128,12 @@ Q_SIGNALS:
|
||||||
void numberOfPagesChanged();
|
void numberOfPagesChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void evaluateDelegatePositions(bool emitSignal = true);
|
void evaluateDelegateIndexes(bool emitSignal = true);
|
||||||
|
|
||||||
// get the position where delegates start being placed
|
// get the position where delegates start being placed
|
||||||
QPointF getDelegateStartPosition(int page);
|
QPointF getDelegateStartPosition(int page);
|
||||||
|
|
||||||
int numRowsOnPage();
|
int numGridLengthOnPage();
|
||||||
int numColumnsOnPage();
|
|
||||||
|
|
||||||
// distance between folder edge and page content
|
// distance between folder edge and page content
|
||||||
qreal horizontalPageMargin();
|
qreal horizontalPageMargin();
|
||||||
|
|
|
||||||
|
|
@ -120,13 +120,32 @@ void HomeScreenState::init()
|
||||||
Q_EMIT pageColumnsChanged();
|
Q_EMIT pageColumnsChanged();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(this, &HomeScreenState::pageWidthChanged, this, &HomeScreenState::calculatePageContentWidth);
|
connect(this, &HomeScreenState::pageWidthChanged, [this]() {
|
||||||
connect(this, &HomeScreenState::pageHeightChanged, this, &HomeScreenState::calculatePageContentHeight);
|
calculatePageContentWidth();
|
||||||
|
calculateFolderGridLength();
|
||||||
|
});
|
||||||
|
connect(this, &HomeScreenState::pageHeightChanged, [this]() {
|
||||||
|
calculatePageContentHeight();
|
||||||
|
calculateFolderGridLength();
|
||||||
|
});
|
||||||
|
connect(this, &HomeScreenState::pageContentWidthChanged, [this]() {
|
||||||
|
calculatePageCellWidth();
|
||||||
|
calculateFolderGridLength();
|
||||||
|
});
|
||||||
|
connect(this, &HomeScreenState::pageColumnsChanged, [this]() {
|
||||||
|
calculatePageCellWidth();
|
||||||
|
calculateFolderGridLength();
|
||||||
|
});
|
||||||
|
connect(this, &HomeScreenState::pageContentHeightChanged, [this]() {
|
||||||
|
calculatePageCellHeight();
|
||||||
|
calculateFolderGridLength();
|
||||||
|
});
|
||||||
|
connect(this, &HomeScreenState::pageRowsChanged, [this]() {
|
||||||
|
calculatePageCellHeight();
|
||||||
|
calculateFolderGridLength();
|
||||||
|
});
|
||||||
|
|
||||||
connect(this, &HomeScreenState::pageContentWidthChanged, this, &HomeScreenState::calculatePageCellWidth);
|
connect(m_homeScreen->folioSettings(), &FolioSettings::delegateIconSizeChanged, this, &HomeScreenState::calculateFolderGridLength);
|
||||||
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]() {
|
connect(this, &HomeScreenState::viewWidthChanged, this, [this]() {
|
||||||
Q_EMIT favouritesBarLocationChanged();
|
Q_EMIT favouritesBarLocationChanged();
|
||||||
|
|
@ -317,6 +336,7 @@ void HomeScreenState::setPageWidth(qreal pageWidth)
|
||||||
|
|
||||||
// make sure we snap
|
// make sure we snap
|
||||||
goToPage(m_pageNum, true);
|
goToPage(m_pageNum, true);
|
||||||
|
goToFolderPage(m_folderPageNum, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -510,6 +530,22 @@ void HomeScreenState::setCurrentFolder(FolioApplicationFolder *folder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int HomeScreenState::folderGridLength() const
|
||||||
|
{
|
||||||
|
return m_folderGridLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HomeScreenState::calculateFolderGridLength()
|
||||||
|
{
|
||||||
|
const int folderGridLength = std::max(2, qRound(std::min(m_viewWidth, m_viewHeight) * 0.6 / m_homeScreen->folioSettings()->delegateIconSize() * 0.6));
|
||||||
|
|
||||||
|
if (m_folderGridLength != folderGridLength) {
|
||||||
|
m_folderGridLength = folderGridLength;
|
||||||
|
Q_EMIT folderGridLengthChanged();
|
||||||
|
goToFolderPage(m_folderPageNum, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qreal HomeScreenState::settingsOpenProgress()
|
qreal HomeScreenState::settingsOpenProgress()
|
||||||
{
|
{
|
||||||
return m_settingsOpenProgress;
|
return m_settingsOpenProgress;
|
||||||
|
|
@ -667,13 +703,8 @@ QPointF HomeScreenState::getFolderDelegateScreenPosition(int position)
|
||||||
return {0, 0};
|
return {0, 0};
|
||||||
}
|
}
|
||||||
auto pos = m_currentFolder->applications()->getDelegatePosition(position);
|
auto pos = m_currentFolder->applications()->getDelegatePosition(position);
|
||||||
qreal x = pos.x() + (m_viewWidth - m_viewLeftPadding - m_viewRightPadding - m_folderPageWidth) / 2;
|
qreal x = pos.x() + (m_viewWidth - m_folderPageWidth) / 2;
|
||||||
qreal y = pos.y() + (m_viewHeight - m_viewTopPadding - m_viewBottomPadding - m_folderPageHeight) / 2;
|
qreal y = pos.y() + (m_viewHeight - m_folderPageHeight) / 2;
|
||||||
x += m_viewLeftPadding;
|
|
||||||
y += m_viewTopPadding;
|
|
||||||
|
|
||||||
// adjust for the current page
|
|
||||||
x -= currentFolderPage() * m_folderPageWidth;
|
|
||||||
|
|
||||||
return {x, y};
|
return {x, y};
|
||||||
}
|
}
|
||||||
|
|
@ -735,7 +766,7 @@ void HomeScreenState::goToPage(int page, bool snap)
|
||||||
m_pageAnim->start();
|
m_pageAnim->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HomeScreenState::goToFolderPage(int page)
|
void HomeScreenState::goToFolderPage(int page, bool snap)
|
||||||
{
|
{
|
||||||
if (!m_currentFolder) {
|
if (!m_currentFolder) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -753,7 +784,12 @@ void HomeScreenState::goToFolderPage(int page)
|
||||||
m_folderPageNum = page;
|
m_folderPageNum = page;
|
||||||
Q_EMIT folderPageNumChanged();
|
Q_EMIT folderPageNumChanged();
|
||||||
|
|
||||||
m_folderPageAnim->setStartValue(m_folderViewX);
|
if (snap) {
|
||||||
|
// Skip the animation and go straight to the intended page
|
||||||
|
m_folderPageAnim->setStartValue(-page * m_folderPageWidth);
|
||||||
|
} else {
|
||||||
|
m_folderPageAnim->setStartValue(m_folderViewX);
|
||||||
|
}
|
||||||
m_folderPageAnim->setEndValue(-page * m_folderPageWidth);
|
m_folderPageAnim->setEndValue(-page * m_folderPageWidth);
|
||||||
m_folderPageAnim->start();
|
m_folderPageAnim->start();
|
||||||
}
|
}
|
||||||
|
|
@ -908,9 +944,9 @@ void HomeScreenState::swipeEnded()
|
||||||
|
|
||||||
// m_movingRight refers to finger movement
|
// m_movingRight refers to finger movement
|
||||||
if (m_movingRight || m_folderViewX > 0) {
|
if (m_movingRight || m_folderViewX > 0) {
|
||||||
goToFolderPage(page);
|
goToFolderPage(page, false);
|
||||||
} else {
|
} else {
|
||||||
goToFolderPage(page + 1);
|
goToFolderPage(page + 1, false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ class HomeScreenState : public QObject
|
||||||
Q_PROPERTY(qreal folderPageContentHeight READ folderPageContentHeight WRITE setFolderPageContentHeight NOTIFY folderPageContentHeightChanged)
|
Q_PROPERTY(qreal folderPageContentHeight READ folderPageContentHeight WRITE setFolderPageContentHeight NOTIFY folderPageContentHeightChanged)
|
||||||
Q_PROPERTY(qreal folderOpenProgress READ folderOpenProgress WRITE setFolderOpenProgress NOTIFY folderOpenProgressChanged)
|
Q_PROPERTY(qreal folderOpenProgress READ folderOpenProgress WRITE setFolderOpenProgress NOTIFY folderOpenProgressChanged)
|
||||||
Q_PROPERTY(FolioApplicationFolder *currentFolder READ currentFolder NOTIFY currentFolderChanged)
|
Q_PROPERTY(FolioApplicationFolder *currentFolder READ currentFolder NOTIFY currentFolderChanged)
|
||||||
|
Q_PROPERTY(qreal folderGridLength READ folderGridLength NOTIFY folderGridLengthChanged)
|
||||||
|
|
||||||
Q_PROPERTY(qreal settingsOpenProgress READ settingsOpenProgress WRITE setSettingsOpenProgress NOTIFY settingsOpenProgressChanged)
|
Q_PROPERTY(qreal settingsOpenProgress READ settingsOpenProgress WRITE setSettingsOpenProgress NOTIFY settingsOpenProgressChanged)
|
||||||
|
|
||||||
|
|
@ -204,6 +205,9 @@ public:
|
||||||
qreal folderOpenProgress() const;
|
qreal folderOpenProgress() const;
|
||||||
void setFolderOpenProgress(qreal folderOpenProgress);
|
void setFolderOpenProgress(qreal folderOpenProgress);
|
||||||
|
|
||||||
|
int folderGridLength() const;
|
||||||
|
void calculateFolderGridLength();
|
||||||
|
|
||||||
FolioApplicationFolder *currentFolder() const;
|
FolioApplicationFolder *currentFolder() const;
|
||||||
void setCurrentFolder(FolioApplicationFolder *folder);
|
void setCurrentFolder(FolioApplicationFolder *folder);
|
||||||
|
|
||||||
|
|
@ -286,6 +290,7 @@ Q_SIGNALS:
|
||||||
void folderPageContentWidthChanged();
|
void folderPageContentWidthChanged();
|
||||||
void folderPageContentHeightChanged();
|
void folderPageContentHeightChanged();
|
||||||
void folderOpenProgressChanged();
|
void folderOpenProgressChanged();
|
||||||
|
void folderGridLengthChanged();
|
||||||
void currentFolderChanged();
|
void currentFolderChanged();
|
||||||
void settingsOpenProgressChanged();
|
void settingsOpenProgressChanged();
|
||||||
void appDrawerOpenProgressChanged();
|
void appDrawerOpenProgressChanged();
|
||||||
|
|
@ -318,7 +323,7 @@ public Q_SLOTS:
|
||||||
|
|
||||||
void goToPage(int page, bool snap);
|
void goToPage(int page, bool snap);
|
||||||
|
|
||||||
void goToFolderPage(int page);
|
void goToFolderPage(int page, bool snap);
|
||||||
void openFolder(qreal delegateX, qreal delegateY, FolioApplicationFolder *folder);
|
void openFolder(qreal delegateX, qreal delegateY, FolioApplicationFolder *folder);
|
||||||
void closeFolder();
|
void closeFolder();
|
||||||
|
|
||||||
|
|
@ -385,6 +390,7 @@ private:
|
||||||
qreal m_folderPageContentHeight{0};
|
qreal m_folderPageContentHeight{0};
|
||||||
qreal m_folderOpenProgress{0};
|
qreal m_folderOpenProgress{0};
|
||||||
FolioApplicationFolder *m_currentFolder{nullptr};
|
FolioApplicationFolder *m_currentFolder{nullptr};
|
||||||
|
int m_folderGridLength{0};
|
||||||
|
|
||||||
qreal m_settingsOpenProgress{0};
|
qreal m_settingsOpenProgress{0};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ Folio.DelegateTouchArea {
|
||||||
width: root.width
|
width: root.width
|
||||||
|
|
||||||
// have to use y instead of anchors to avoid animations
|
// have to use y instead of anchors to avoid animations
|
||||||
y: Math.round((root.height / 2) - (folderBackground.height / 2) - Kirigami.Units.gridUnit - height)
|
y: Math.round(((root.height / 2) - (folderBackground.height / 2)) * 0.9 - height)
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
|
@ -61,14 +61,12 @@ Folio.DelegateTouchArea {
|
||||||
|
|
||||||
function updateContentWidth() {
|
function updateContentWidth() {
|
||||||
let margin = folderBackground.margin;
|
let margin = folderBackground.margin;
|
||||||
let columns = Math.floor((folderBackground.width - margin * 2) / folio.HomeScreenState.pageCellWidth);
|
folio.HomeScreenState.folderPageContentWidth = (folderBackground.width - margin * 2);
|
||||||
folio.HomeScreenState.folderPageContentWidth = columns * folio.HomeScreenState.pageCellWidth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateContentHeight() {
|
function updateContentHeight() {
|
||||||
let margin = folderBackground.margin;
|
let margin = folderBackground.margin;
|
||||||
let rows = Math.floor((folderBackground.height - margin * 2) / folio.HomeScreenState.pageCellHeight);
|
folio.HomeScreenState.folderPageContentHeight = (folderBackground.height - margin * 2);
|
||||||
folio.HomeScreenState.folderPageContentHeight = rows * folio.HomeScreenState.pageCellHeight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
|
@ -90,28 +88,26 @@ Folio.DelegateTouchArea {
|
||||||
color: Qt.rgba(255, 255, 255, 0.3)
|
color: Qt.rgba(255, 255, 255, 0.3)
|
||||||
radius: Kirigami.Units.gridUnit
|
radius: Kirigami.Units.gridUnit
|
||||||
|
|
||||||
readonly property real margin: Kirigami.Units.largeSpacing
|
readonly property int gridLength: folio.HomeScreenState.folderGridLength
|
||||||
readonly property real maxLength: Math.min(root.width * 0.9, root.height * 0.9)
|
|
||||||
|
|
||||||
width: {
|
readonly property int margin: Kirigami.Units.largeSpacing
|
||||||
let perRow = 0;
|
readonly property int maxLength: Math.min(root.width - Kirigami.Units.gridUnit * 4, root.height - Kirigami.Units.gridUnit * 2)
|
||||||
if (root.width < root.height) {
|
|
||||||
perRow = Math.floor((maxLength - margin * 2) / folio.HomeScreenState.pageCellWidth);
|
readonly property int pageSize: Math.min(maxLength, (folio.FolioSettings.delegateIconSize + Kirigami.Units.gridUnit * 3) * gridLength + Kirigami.Units.gridUnit * 2)
|
||||||
} else {
|
|
||||||
// try to get the same number of rows as columns
|
width: pageSize - margin * 2
|
||||||
perRow = Math.floor((maxLength - margin * 2) / folio.HomeScreenState.pageCellHeight);
|
height: pageSize
|
||||||
}
|
|
||||||
return Math.min(root.width * 0.9, perRow * folio.HomeScreenState.pageCellWidth + margin * 2);
|
QQC2.PageIndicator {
|
||||||
}
|
visible: count > 1
|
||||||
height: {
|
Kirigami.Theme.inherit: false
|
||||||
let perRow = 0;
|
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
|
||||||
if (root.width < root.height) {
|
|
||||||
// try to get the same number of rows as columns
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
perRow = Math.floor((maxLength - margin * 2) / folio.HomeScreenState.pageCellWidth);
|
anchors.bottom: parent.bottom
|
||||||
} else {
|
|
||||||
perRow = Math.floor((maxLength - margin * 2) / folio.HomeScreenState.pageCellHeight);
|
currentIndex: folio.HomeScreenState.currentFolderPage
|
||||||
}
|
count: folio.HomeScreenState.currentFolder ? folio.HomeScreenState.currentFolder.applications.numberOfPages : 0
|
||||||
return Math.min(root.height * 0.9, perRow * folio.HomeScreenState.pageCellHeight + margin * 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onWidthChanged: {
|
onWidthChanged: {
|
||||||
|
|
@ -173,27 +169,42 @@ Folio.DelegateTouchArea {
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
id: delegate
|
id: delegate
|
||||||
|
|
||||||
property var delegateModel: model.delegate
|
readonly property var delegateModel: model.delegate
|
||||||
property int index: model.index
|
readonly property int index: model.index
|
||||||
|
|
||||||
property var dragState: folio.HomeScreenState.dragState
|
readonly property int folderCellSize: folio.HomeScreenState.folderPageContentWidth / folderBackground.gridLength
|
||||||
property bool isDropPositionThis: dragState.candidateDropPosition.location === Folio.DelegateDragPosition.Folder &&
|
readonly property int cellWidth: folio.HomeScreenState.pageCellWidth
|
||||||
dragState.candidateDropPosition.folderPosition === index
|
readonly property int cellHeight: folio.HomeScreenState.pageCellHeight
|
||||||
|
|
||||||
x: model.xPosition
|
readonly property var dragState: folio.HomeScreenState.dragState
|
||||||
y: model.yPosition
|
readonly property bool isDropPositionThis: dragState.candidateDropPosition.location === Folio.DelegateDragPosition.Folder &&
|
||||||
|
dragState.candidateDropPosition.folderPosition === index
|
||||||
|
|
||||||
Behavior on x {
|
// get the index position value so we can animate them
|
||||||
|
property double columnValue: model.columnIndex
|
||||||
|
property double rowValue: model.rowIndex
|
||||||
|
property double pageValue: model.pageIndex
|
||||||
|
Behavior on columnValue {
|
||||||
NumberAnimation { duration: 250; easing.type: Easing.InOutQuad }
|
NumberAnimation { duration: 250; easing.type: Easing.InOutQuad }
|
||||||
}
|
}
|
||||||
Behavior on y {
|
Behavior on rowValue {
|
||||||
|
NumberAnimation { duration: 250; easing.type: Easing.InOutQuad }
|
||||||
|
}
|
||||||
|
Behavior on pageValue {
|
||||||
NumberAnimation { duration: 250; easing.type: Easing.InOutQuad }
|
NumberAnimation { duration: 250; easing.type: Easing.InOutQuad }
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitWidth: folio.HomeScreenState.pageCellWidth
|
// multiply the index values by the cell size to get the actual position
|
||||||
implicitHeight: folio.HomeScreenState.pageCellHeight
|
readonly property int positionColumn: folderCellSize * columnValue
|
||||||
width: folio.HomeScreenState.pageCellWidth
|
readonly property int positionRow: folderCellSize * rowValue
|
||||||
height: folio.HomeScreenState.pageCellHeight
|
|
||||||
|
x: (folderCellSize - cellWidth) / 2 + folderBackground.margin + pageValue * folderBackground.width + positionColumn
|
||||||
|
y: (folderCellSize - cellHeight) / 2 + folderBackground.margin + positionRow
|
||||||
|
|
||||||
|
implicitWidth: cellWidth
|
||||||
|
implicitHeight: cellHeight
|
||||||
|
width: cellWidth
|
||||||
|
height: cellHeight
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: delegateLoader
|
id: delegateLoader
|
||||||
|
|
@ -282,22 +293,4 @@ Folio.DelegateTouchArea {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QQC2.PageIndicator {
|
|
||||||
visible: count > 1
|
|
||||||
Kirigami.Theme.inherit: false
|
|
||||||
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
|
|
||||||
|
|
||||||
// have to use y instead of anchors to avoid animations
|
|
||||||
y: Math.round((root.height / 2) + (folderBackground.height / 2) + Kirigami.Units.largeSpacing)
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
currentIndex: folio.HomeScreenState.currentFolderPage
|
|
||||||
count: folio.HomeScreenState.currentFolder ? folio.HomeScreenState.currentFolder.applications.numberOfPages : 0
|
|
||||||
|
|
||||||
opacity: (root.opacity === 1) ? 1 : 0
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: Kirigami.Units.shortDuration }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue