homescreen: Add scale animation when going to homescreen

This commit is contained in:
Devin Lin 2022-04-06 17:59:36 -04:00
parent f861e2df3f
commit c8a366cbbd
4 changed files with 130 additions and 38 deletions

View file

@ -16,7 +16,7 @@ import org.kde.plasma.private.mobileshell 1.0 as MobileShell
* The base homescreen component, implementing features that simplify * The base homescreen component, implementing features that simplify
* homescreen implementation. * homescreen implementation.
*/ */
FocusScope { Item {
id: root id: root
/** /**
@ -35,9 +35,9 @@ FocusScope {
signal requestRelativeScroll(var pos) signal requestRelativeScroll(var pos)
/** /**
* The requested opacity of homescreen elements (for opacity animations). * The visual item that is the homescreen.
*/ */
property real homeScreenOpacity: 1 property alias contentItem: itemContainer.contentItem
/** /**
* Whether a component is being shown on top of the homescreen within the same * Whether a component is being shown on top of the homescreen within the same
@ -45,19 +45,19 @@ FocusScope {
*/ */
property bool overlayShown: taskSwitcher.visible || startupFeedback.visible property bool overlayShown: taskSwitcher.visible || startupFeedback.visible
NumberAnimation on homeScreenOpacity {
id: opacityAnimation
duration: PlasmaCore.Units.longDuration
}
//BEGIN API implementation //BEGIN API implementation
Connections { Connections {
target: MobileShell.HomeScreenControls target: MobileShell.HomeScreenControls
function onOpenHomeScreen() { function onOpenHomeScreen() {
if (!MobileShell.WindowUtil.allWindowsMinimized) {
itemContainer.zoomIn();
}
MobileShell.HomeScreenControls.resetHomeScreenPosition(); MobileShell.HomeScreenControls.resetHomeScreenPosition();
taskSwitcher.visible = false; // will trigger homescreen open taskSwitcher.visible = false; // will trigger homescreen open
taskSwitcher.minimizeAll(); taskSwitcher.minimizeAll();
root.homeTriggered(); root.homeTriggered();
} }
@ -102,15 +102,64 @@ FocusScope {
} }
} }
// homescreen visual component
MobileShell.BaseItem {
id: itemContainer
anchors.fill: parent
// animations
opacity: 0
property real zoomScale: 0.8
Component.onCompleted: zoomIn()
function zoomIn() {
scaleAnim.to = 1;
scaleAnim.restart();
opacityAnim.to = 1;
opacityAnim.restart();
}
function zoomOut() {
scaleAnim.to = 0.8;
scaleAnim.restart();
opacityAnim.to = 0;
opacityAnim.restart();
}
NumberAnimation on opacity {
id: opacityAnim
duration: 300
running: false
}
NumberAnimation on zoomScale {
id: scaleAnim
duration: 600
running: false
easing.type: Easing.OutExpo
}
Connections {
target: MobileShell.WindowUtil
function onActiveWindowIsShellChanged() {
if (MobileShell.WindowUtil.activeWindowIsShell && !taskSwitcher.visible) {
itemContainer.zoomIn();
} else {
itemContainer.zoomOut();
}
}
}
transform: Scale {
origin.x: itemContainer.width / 2;
origin.y: itemContainer.height / 2;
xScale: itemContainer.zoomScale
yScale: itemContainer.zoomScale
}
}
// task switcher component // task switcher component
TaskManager.VirtualDesktopInfo {
id: virtualDesktopInfo
}
TaskManager.ActivityInfo {
id: activityInfo
}
MobileShell.TaskSwitcher { MobileShell.TaskSwitcher {
id: taskSwitcher id: taskSwitcher
z: 999999 z: 999999
@ -125,6 +174,14 @@ FocusScope {
activity: activityInfo.currentActivity activity: activityInfo.currentActivity
} }
TaskManager.VirtualDesktopInfo {
id: virtualDesktopInfo
}
TaskManager.ActivityInfo {
id: activityInfo
}
anchors.fill: parent anchors.fill: parent
// hide homescreen elements to make use of wallpaper // hide homescreen elements to make use of wallpaper
@ -134,15 +191,14 @@ FocusScope {
// only animate if going from homescreen // only animate if going from homescreen
if (taskSwitcher.wasInActiveTask) { if (taskSwitcher.wasInActiveTask) {
opacityAnimation.to = 0; itemContainer.zoomOut();
opacityAnimation.restart();
} else { } else {
root.homeScreenOpacity = 0; itemContainer.zoomOut();
//itemContainer.opacity = 0;
} }
} else { } else {
opacityAnimation.to = 1; itemContainer.zoomIn();
opacityAnimation.restart();
} }
} }
} }

View file

@ -19,6 +19,8 @@ WindowUtil::WindowUtil(QObject *parent)
m_activeWindowTimer->setInterval(ACTIVE_WINDOW_UPDATE_INVERVAL); m_activeWindowTimer->setInterval(ACTIVE_WINDOW_UPDATE_INVERVAL);
connect(m_activeWindowTimer, &QTimer::timeout, this, &WindowUtil::updateActiveWindow); connect(m_activeWindowTimer, &QTimer::timeout, this, &WindowUtil::updateActiveWindow);
connect(this, &WindowUtil::activeWindowChanged, this, &WindowUtil::updateActiveWindowIsShell);
initWayland(); initWayland();
} }
@ -38,6 +40,11 @@ bool WindowUtil::allWindowsMinimized() const
return m_allWindowsMinimized; return m_allWindowsMinimized;
} }
bool WindowUtil::activeWindowIsShell() const
{
return m_activeWindowIsShell;
}
void WindowUtil::initWayland() void WindowUtil::initWayland()
{ {
if (!QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) { if (!QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) {
@ -84,6 +91,7 @@ void WindowUtil::updateActiveWindow()
disconnect(m_activeWindow.data(), &PlasmaWindow::unmapped, this, &WindowUtil::forgetActiveWindow); disconnect(m_activeWindow.data(), &PlasmaWindow::unmapped, this, &WindowUtil::forgetActiveWindow);
} }
m_activeWindow = m_windowManagement->activeWindow(); m_activeWindow = m_windowManagement->activeWindow();
Q_EMIT activeWindowChanged();
if (m_activeWindow) { if (m_activeWindow) {
connect(m_activeWindow.data(), &PlasmaWindow::closeableChanged, this, &WindowUtil::hasCloseableActiveWindowChanged); connect(m_activeWindow.data(), &PlasmaWindow::closeableChanged, this, &WindowUtil::hasCloseableActiveWindowChanged);
@ -133,6 +141,19 @@ void WindowUtil::updateShowingDesktop(bool showing)
} }
} }
void WindowUtil::updateActiveWindowIsShell()
{
if (m_activeWindow) {
if (m_activeWindow->appId() == QStringLiteral("org.kde.plasmashell") && !m_activeWindowIsShell) {
m_activeWindowIsShell = true;
Q_EMIT activeWindowIsShellChanged();
} else if (m_activeWindow->appId() != QStringLiteral("org.kde.plasmashell") && m_activeWindowIsShell) {
m_activeWindowIsShell = false;
Q_EMIT activeWindowIsShellChanged();
}
}
}
void WindowUtil::forgetActiveWindow() void WindowUtil::forgetActiveWindow()
{ {
using namespace KWayland::Client; using namespace KWayland::Client;

View file

@ -24,6 +24,7 @@ class WindowUtil : public QObject
Q_PROPERTY(bool showDesktop READ isShowingDesktop WRITE requestShowingDesktop NOTIFY showingDesktopChanged) Q_PROPERTY(bool showDesktop READ isShowingDesktop WRITE requestShowingDesktop NOTIFY showingDesktopChanged)
Q_PROPERTY(bool allWindowsMinimized READ allWindowsMinimized NOTIFY allWindowsMinimizedChanged) Q_PROPERTY(bool allWindowsMinimized READ allWindowsMinimized NOTIFY allWindowsMinimizedChanged)
Q_PROPERTY(bool hasCloseableActiveWindow READ hasCloseableActiveWindow NOTIFY hasCloseableActiveWindowChanged) Q_PROPERTY(bool hasCloseableActiveWindow READ hasCloseableActiveWindow NOTIFY hasCloseableActiveWindowChanged)
Q_PROPERTY(bool activeWindowIsShell READ activeWindowIsShell NOTIFY activeWindowIsShellChanged)
public: public:
WindowUtil(QObject *parent = nullptr); WindowUtil(QObject *parent = nullptr);
@ -31,6 +32,7 @@ public:
bool isShowingDesktop() const; bool isShowingDesktop() const;
bool allWindowsMinimized() const; bool allWindowsMinimized() const;
bool activeWindowIsShell() const;
bool hasCloseableActiveWindow() const; bool hasCloseableActiveWindow() const;
Q_INVOKABLE void closeActiveWindow(); Q_INVOKABLE void closeActiveWindow();
@ -41,8 +43,11 @@ Q_SIGNALS:
void showingDesktopChanged(bool showingDesktop); void showingDesktopChanged(bool showingDesktop);
void allWindowsMinimizedChanged(); void allWindowsMinimizedChanged();
void hasCloseableActiveWindowChanged(); void hasCloseableActiveWindowChanged();
void activeWindowChanged();
void activeWindowIsShellChanged();
private Q_SLOTS: private Q_SLOTS:
void updateActiveWindowIsShell();
void forgetActiveWindow(); void forgetActiveWindow();
void updateShowingDesktop(bool showing); void updateShowingDesktop(bool showing);
@ -55,5 +60,6 @@ private:
QTimer *m_activeWindowTimer; QTimer *m_activeWindowTimer;
bool m_showingDesktop = false; bool m_showingDesktop = false;
bool m_allWindowsMinimized; bool m_allWindowsMinimized = true;
bool m_activeWindowIsShell = false;
}; };

View file

@ -71,23 +71,32 @@ MobileShell.HomeScreen {
} }
} }
// homescreen component contentItem: Item {
HomeScreen { // homescreen component
id: homescreen HomeScreen {
anchors.fill: parent id: homescreen
opacity: root.homeScreenOpacity * (1 - searchWidget.openFactor) anchors.fill: parent
opacity: (1 - searchWidget.openFactor)
// make the homescreen not interactable when task switcher or startup feedback is on // make the homescreen not interactable when task switcher or startup feedback is on
interactive: !root.overlayShown interactive: !root.overlayShown
} }
// search component // search component
MobileShell.KRunnerWidget { MobileShell.KRunnerWidget {
id: searchWidget id: searchWidget
anchors.fill: parent anchors.fill: parent
opacity: root.homeScreenOpacity visible: openFactor > 0
visible: openFactor > 0
// close search component when task switcher is shown or hidden
Connections {
target: MobileShell.HomeScreenControls.taskSwitcher
function onVisibleChanged() {
searchWidget.close();
}
}
}
} }
Connections { Connections {