1
0
mirror of https://github.com/KDE/latte-dock.git synced 2025-01-08 13:18:09 +03:00

fix #100,introduce parabolic edge spacers for main

--new introduced external spacers of main layout are
used from parabolic effect in order to keep the contents
of main layout in balance. That produces a much better
visual result for the user because when the user hovers
an item, that item is zoomed and the mouse is still
present at first hovered position.
This commit is contained in:
Michail Vourlakos 2022-02-27 10:26:53 +02:00
parent d841e1e443
commit 59b422448b
13 changed files with 253 additions and 77 deletions

View File

@ -171,13 +171,9 @@ Item {
//console.log("------Entered check-----");
//console.log("max length: "+ maxLength);
if (root.isVertical) {
layoutLength = (plasmoid.configuration.alignment === LatteCore.Types.Justify) ?
layouts.startLayout.height+layouts.mainLayout.height+layouts.endLayout.height : layouts.mainLayout.height
} else {
layoutLength = (plasmoid.configuration.alignment === LatteCore.Types.Justify) ?
layouts.startLayout.width+layouts.mainLayout.width+layouts.endLayout.width : layouts.mainLayout.width
}
layoutLength = (plasmoid.configuration.alignment === LatteCore.Types.Justify) ?
layouts.startLayout.length+layouts.mainLayout.length+layouts.endLayout.length : layouts.mainLayout.length
var itemLength = metrics.totals.length;

View File

@ -40,7 +40,7 @@ Item {
value: {
var space = 0;
for (var i=0; i<grid.children.length; ++i){
if (grid.children[i] && (grid.children[i].isPlaceHolder || (!grid.children[i].isAutoFillApplet && !grid.children[i].isHidden))) {
if (grid.children[i] && (grid.children[i].isPlaceHolder || (!grid.children[i].isAutoFillApplet && !grid.children[i].isHidden && !grid.children[i].isParabolicEdgeSpacer))) {
if (!grid.children[i].isPlaceHolder && grid.children[i].isInternalViewSplitter) {
space += root.maxJustifySplitterSize;
@ -100,6 +100,7 @@ Item {
var no = 0;
for (var i=0; i<grid.children.length; ++i){
if (grid.children[i]
&& !grid.children[i].isParabolicEdgeSpacer
&& !grid.children[i].isPlaceHolder
&& grid.children[i].isAutoFillApplet
&& !grid.children[i].isHidden) {
@ -120,6 +121,7 @@ Item {
var no = 0;
for (var i=0; i<grid.children.length; ++i){
if (grid.children[i]
&& !grid.children[i].isParabolicEdgeSpacer
&& !grid.children[i].isPlaceHolder
&& grid.children[i].isRequestingFill
&& grid.children[i].applet
@ -182,6 +184,7 @@ Item {
for (var i=0; i<grid.children.length; ++i){
if (grid.children[i]
&& !grid.children[i].isParabolicEdgeSpacer
&& !grid.children[i].isPlaceHolder
&& grid.children[i].isInternalViewSplitter
&& !grid.children[i].isHidden) {

View File

@ -55,6 +55,7 @@ Item {
//! Fill Applet(s)
property bool inFillCalculations: false //temp record, is used in calculations for fillWidth,fillHeight applets
property bool isAutoFillApplet: isRequestingFill
property bool isParabolicEdgeSpacer: false
property bool isRequestingFill: {
if (!applet || !applet.Layout) {
@ -481,7 +482,7 @@ Item {
for(var i=0; i<appletItem.layouter.mainLayout.count; ++i){
var child = layoutsContainer.mainLayout.children[i];
if (child === appletItem){
index = layoutsContainer.mainLayout.beginIndex + i;
index = layoutsContainer.mainLayout.beginIndex + i - 1; //we remove one item because at start of main layout there is a ParabolicEdgeSpacer
break;
}
}

View File

@ -130,17 +130,6 @@ Item {
//use the new parabolic effect manager in order to handle all parabolic effect messages
var scales = parabolic.applyParabolicEffect(index, currentMousePosition, length);
//Left hiddenSpacer
if(appletItem.firstAppletInContainer){
hiddenSpacerLeft.nScale = scales.leftScale - 1;
}
//Right hiddenSpacer ///there is one more item in the currentLayout ????
if(appletItem.lastAppletInContainer){
hiddenSpacerRight.nScale = scales.rightScale - 1;
}
wrapper.zoomScale = parabolic.factor.zoom;
} //scale

View File

@ -131,11 +131,7 @@ BackgroundProperties{
return root.maxLength;
}
if (root.isVertical) {
return Math.max(root.minLength, layoutsContainerItem.mainLayout.height + totals.paddingsLength);
} else {
return Math.max(root.minLength, layoutsContainerItem.mainLayout.width + totals.paddingsLength);
}
return Math.max(root.minLength, layoutsContainerItem.mainLayout.length + totals.paddingsLength);
}
thickness: {
@ -167,7 +163,8 @@ BackgroundProperties{
}
}
return root.offset;// (myView.alignment === LatteCore.Types.Center ? root.offset : 0);
var parabolicOffseting = myView.alignment === LatteCore.Types.Center ? layoutsContainerItem.mainLayout.parabolicOffsetting : 0;
return root.offset + parabolicOffseting;
}
totals.visualThickness: {

View File

@ -133,7 +133,7 @@ MouseArea {
} else {
var item = hoveredItem(mouse.x, mouse.y);
if (root.dragOverlay) {
if (root.dragOverlay && item && !item.isParabolicEdgeSpacer) {
root.dragOverlay.currentApplet = item;
} else {
currentApplet = null;
@ -213,8 +213,6 @@ MouseArea {
placeHolder.parent = configurationArea;
currentApplet.z = 1;
var relevantLayout = mapFromItem(layoutsContainer.mainLayout, 0, 0);
if (root.myView.alignment === LatteCore.Types.Justify) {
fastLayoutManager.moveAppletsBasedOnJustifyAlignment();
}

View File

@ -30,7 +30,8 @@ Grid {
return 1;
}
readonly property int length : root.isHorizontal ? childrenRect.width : childrenRect.height;
readonly property int length : root.isHorizontal ? width - ignoredLength : height - ignoredLength
property int ignoredLength: 0
property int alignment: LatteCore.Types.BottomEdgeCenterAlign
property int beginIndex: 0

View File

@ -288,11 +288,17 @@ Item{
return background.offset + lengthTailPadding;
}
return (root.myView.alignment === LatteCore.Types.Justify) ? inJustifyCenterOffset : background.offset
return (root.myView.alignment === LatteCore.Types.Justify) ? inJustifyCenterOffset : background.offset - parabolicOffsetting
}
ignoredLength: startParabolicSpacer.length + endParabolicSpacer.length
readonly property alias startParabolicSpacer: _startParabolicSpacer
readonly property alias endParabolicSpacer: _endParabolicSpacer
readonly property bool centered: (root.myView.alignment === LatteCore.Types.Center) || (root.myView.alignment === LatteCore.Types.Justify)
readonly property bool reversed: Qt.application.layoutDirection === Qt.RightToLeft
readonly property int parabolicOffsetting: Math.round((startParabolicSpacer.length - endParabolicSpacer.length) / 2)
property int inJustifyCenterOffset: 0
alignment: {
@ -347,6 +353,16 @@ Item{
}
}
ParabolicEdgeSpacer {
id: _startParabolicSpacer
index: mainLayout.beginIndex - 1
}
ParabolicEdgeSpacer {
id: _endParabolicSpacer
index: mainLayout.beginIndex + mainLayout.children.length - 2
}
Binding{
target: _mainLayout
property:"inJustifyCenterOffset"

View File

@ -0,0 +1,122 @@
/*
SPDX-FileCopyrightText: 2022 Michail Vourlakos <mvourlakos@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick 2.7
import org.kde.latte.core 0.2 as LatteCore
Item {
id: edgeSpacer
width: length
height: length
readonly property bool isParabolicEdgeSpacer: true
readonly property bool isHidden: true
readonly property bool isAutoFillApplet: false
readonly property bool isInternalViewSplitter: false
readonly property bool isPlaceHolder: false
readonly property bool isTailSpacer: index < parent.beginIndex
readonly property bool isHeadSpacer: index >= parent.beginIndex
readonly property int animationTime: animations.speedFactor.normal * (1.2*animations.duration.small)
readonly property int hiddenItemsCount: (parabolic.spread - 1)/2
property int index: -1
property int length: 0
Behavior on length {
id: animatedLengthBehavior
enabled: !parabolic.directRenderingEnabled || restoreAnimation.running
NumberAnimation {
duration: 3 * edgeSpacer.animationTime
easing.type: Easing.OutCubic
}
}
Behavior on length {
enabled: !animatedLengthBehavior.enabled
NumberAnimation { duration: 0 }
}
ParallelAnimation{
id: restoreAnimation
PropertyAnimation {
target: edgeSpacer
property: "length"
to: 0
duration: 4 * edgeSpacer.animationTime
easing.type: Easing.InCubic
}
}
function updateScale(istail, newScales) {
var nextFactor = 0;
for (var i=0; i<hiddenItemsCount; ++i) {
if (i<newScales.length) {
nextFactor += (newScales[i] - 1);
}
}
length = nextFactor * metrics.totals.length;
}
function sltUpdateLowerItemScale(delegateIndex, newScales) {
if (!isTailSpacer || delegateIndex !== index) {
return;
}
if (myView.alignment === LatteCore.Types.Center || myView.alignment === LatteCore.Types.Justify) {
updateScale(isTailSpacer, newScales);
} else {
length = 0;
}
//! clear side neighbours
parabolic.sglUpdateLowerItemScale(index - 1, [1]);
}
function sltUpdateHigherItemScale(delegateIndex, newScales) {
if (!isHeadSpacer || delegateIndex !== index) {
return;
}
if (myView.alignment === LatteCore.Types.Center || myView.alignment === LatteCore.Types.Justify) {
updateScale(isHeadSpacer, newScales);
} else {
length = 0;
}
//! clear side neighbours
parabolic.sglUpdateHigherItemScale(index + 1, [1]);
}
function sltClearZoom(){
restoreAnimation.start();
}
Component.onCompleted: {
parabolic.sglClearZoom.connect(sltClearZoom);
parabolic.sglUpdateLowerItemScale.connect(sltUpdateLowerItemScale);
parabolic.sglUpdateHigherItemScale.connect(sltUpdateHigherItemScale);
}
Component.onDestruction: {
parabolic.sglClearZoom.disconnect(sltClearZoom);
parabolic.sglUpdateLowerItemScale.disconnect(sltUpdateLowerItemScale);
parabolic.sglUpdateHigherItemScale.disconnect(sltUpdateHigherItemScale);
}
Loader{
anchors.fill: parent
active: debug.spacersEnabled
sourceComponent: Rectangle{
color: "#44ff0000"
border.width: 1
border.color: "red"
}
}
}

View File

@ -462,6 +462,7 @@ Item {
layouter.appletsInParentChange = false;
}
root.updateIndexes();
plasmoid.configuration.alignment = latteView.alignment;
fastLayoutManager.save();
}

View File

@ -495,15 +495,31 @@ QPoint LayoutManager::indexToMasquearadedPoint(const int &index)
return QPoint(MASQUERADEDINDEXTOPOINTBASE-index, MASQUERADEDINDEXTOPOINTBASE-index);
}
void LayoutManager::reorderParabolicSpacers()
{
QQuickItem *startParabolicSpacer = m_mainLayout->property("startParabolicSpacer").value<QQuickItem *>();
QQuickItem *endParabolicSpacer = m_mainLayout->property("endParabolicSpacer").value<QQuickItem *>();
if (!startParabolicSpacer || !endParabolicSpacer) {
return;
}
insertAtLayoutTail(m_mainLayout, startParabolicSpacer);
insertAtLayoutHead(m_mainLayout, endParabolicSpacer);
}
void LayoutManager::save()
{
QList<int> appletIds;
reorderParabolicSpacers();
int startChilds{0};
for(int i=0; i<m_startLayout->childItems().count(); ++i) {
QQuickItem *item = m_startLayout->childItems()[i];
bool isInternalSplitter = item->property("isInternalViewSplitter").toBool();
if (!isInternalSplitter) {
bool isParabolicEdgeSpacer = item->property("isParabolicEdgeSpacer").toBool();
if (!isInternalSplitter && !isParabolicEdgeSpacer) {
QVariant appletVariant = item->property("applet");
if (!appletVariant.isValid()) {
continue;
@ -528,7 +544,8 @@ void LayoutManager::save()
for(int i=0; i<m_mainLayout->childItems().count(); ++i) {
QQuickItem *item = m_mainLayout->childItems()[i];
bool isInternalSplitter = item->property("isInternalViewSplitter").toBool();
if (!isInternalSplitter) {
bool isParabolicEdgeSpacer = item->property("isParabolicEdgeSpacer").toBool();
if (!isInternalSplitter && !isParabolicEdgeSpacer) {
QVariant appletVariant = item->property("applet");
if (!appletVariant.isValid()) {
continue;
@ -553,7 +570,8 @@ void LayoutManager::save()
for(int i=0; i<m_endLayout->childItems().count(); ++i) {
QQuickItem *item = m_endLayout->childItems()[i];
bool isInternalSplitter = item->property("isInternalViewSplitter").toBool();
if (!isInternalSplitter) {
bool isParabolicEdgeSpacer = item->property("isParabolicEdgeSpacer").toBool();
if (!isInternalSplitter && !isParabolicEdgeSpacer) {
QVariant appletVariant = item->property("applet");
if (!appletVariant.isValid()) {
continue;
@ -716,6 +734,21 @@ void LayoutManager::insertAtLayoutHead(QQuickItem *layout, QQuickItem *item)
item->setParentItem(layout);
}
void LayoutManager::insertAtLayoutIndex(QQuickItem *layout, QQuickItem *item, const int &index)
{
if (!layout || !item) {
return;
}
if (index == 0) {
insertAtLayoutTail(layout, item);
} else if (index >= layout->childItems().count()) {
insertAtLayoutHead(layout, item);
} else {
insertBefore(layout->childItems()[index], item);
}
}
bool LayoutManager::insertAtLayoutCoordinates(QQuickItem *layout, QQuickItem *item, int x, int y)
{
if (!layout || !item || !m_plasmoid || !layout->contains(QPointF(x,y))) {
@ -854,7 +887,8 @@ QQuickItem *LayoutManager::appletItemInLayout(QQuickItem *layout, const int &id)
for(int i=0; i<layout->childItems().count(); ++i) {
QQuickItem *item = layout->childItems()[i];
bool isInternalSplitter = item->property("isInternalViewSplitter").toBool();
if (!isInternalSplitter) {
bool isParabolicEdgeSpacer = item->property("isParabolicEdgeSpacer").toBool();
if (!isInternalSplitter && !isParabolicEdgeSpacer) {
QVariant appletVariant = item->property("applet");
if (!appletVariant.isValid()) {
continue;
@ -905,8 +939,14 @@ int LayoutManager::dndSpacerIndex()
if (alignment == Latte::Types::Justify) {
for(int i=0; i<m_startLayout->childItems().count(); ++i) {
index++;
QQuickItem *item = m_startLayout->childItems()[i];
bool isparabolicspacer = item->property("isParabolicEdgeSpacer").toBool();
if (isparabolicspacer) {
continue;
}
index++;
if (item == m_dndSpacer) {
return index;
}
@ -914,8 +954,14 @@ int LayoutManager::dndSpacerIndex()
}
for(int i=0; i<m_mainLayout->childItems().count(); ++i) {
QQuickItem *item = m_mainLayout->childItems()[i];
bool isparabolicspacer = item->property("isParabolicEdgeSpacer").toBool();
if (isparabolicspacer) {
continue;
}
index++;
QQuickItem *item = m_mainLayout->childItems()[i];
if (item == m_dndSpacer) {
return index;
}
@ -923,8 +969,14 @@ int LayoutManager::dndSpacerIndex()
if (alignment == Latte::Types::Justify) {
for(int i=0; i<m_endLayout->childItems().count(); ++i) {
index++;
QQuickItem *item = m_endLayout->childItems()[i];
bool isparabolicspacer = item->property("isParabolicEdgeSpacer").toBool();
if (isparabolicspacer) {
continue;
}
index++;
if (item == m_dndSpacer) {
return index;
}
@ -1344,13 +1396,13 @@ void LayoutManager::addJustifySplittersInMainLayout()
m_createJustifySplitterMethod.invoke(m_rootItem, Q_RETURN_ARG(QVariant, splitterItemVariant));
QQuickItem *splitterItem = splitterItemVariant.value<QQuickItem *>();
int size = m_mainLayout->childItems().count();
int size = m_mainLayout->childItems().count()-2; //we need to remove parabolic spacers
splitterItem->setParentItem(m_mainLayout);
if (size>0 && splitterIndex>=0) {
bool atend = (splitterIndex >= size);
int validindex = atend ? size-1 : splitterIndex;
int validindex = (atend ? size-1 : splitterIndex) + 1; //we need to take into account first parabolic spacer
QQuickItem *currentitem = m_mainLayout->childItems()[validindex];
if (atend) {
@ -1369,13 +1421,13 @@ void LayoutManager::addJustifySplittersInMainLayout()
m_createJustifySplitterMethod.invoke(m_rootItem, Q_RETURN_ARG(QVariant, splitterItemVariant2));
QQuickItem *splitterItem2 = splitterItemVariant2.value<QQuickItem *>();
int size2 = m_mainLayout->childItems().count();
int size2 = m_mainLayout->childItems().count()-2; //we need to remove parabolic spacers
splitterItem2->setParentItem(m_mainLayout);
if (size2>0 && splitterIndex2>=0) {
bool atend = (splitterIndex2 >= size2);
int validindex2 = atend ? size2-1 : splitterIndex2;
int validindex2 = (atend ? size2-1 : splitterIndex2) + 1; //we need to take into account first parabolic spacer
QQuickItem *currentitem2 = m_mainLayout->childItems()[validindex2];
if (atend) {
@ -1385,7 +1437,7 @@ void LayoutManager::addJustifySplittersInMainLayout()
}
} else if (size2>1){
//! add in last position
QQuickItem *currentitem2 = m_mainLayout->childItems()[size2-1];
QQuickItem *currentitem2 = m_mainLayout->childItems()[size2-1+1]; //we need to take into account first parabolic spacer
splitterItem2->stackAfter(currentitem2);
}
}
@ -1455,6 +1507,8 @@ void LayoutManager::moveAppletsBasedOnJustifyAlignment()
return;
}
reorderParabolicSpacers();
QList<QQuickItem *> appletlist;
appletlist << m_startLayout->childItems();
@ -1468,9 +1522,10 @@ void LayoutManager::moveAppletsBasedOnJustifyAlignment()
for(int i=0; i<appletlist.count(); ++i) {
bool issplitter = appletlist[i]->property("isInternalViewSplitter").toBool();
bool isparabolicspacer = appletlist[i]->property("isParabolicEdgeSpacer").toBool();
if (!firstSplitterFound) {
appletlist[i]->setParentItem(m_startLayout);
insertAtLayoutIndex(m_startLayout, appletlist[i], i);
if (issplitter) {
firstSplitterFound = true;
splitter1 = i;
@ -1479,39 +1534,42 @@ void LayoutManager::moveAppletsBasedOnJustifyAlignment()
if (issplitter) {
secondSplitterFound = true;
splitter2 = i;
appletlist[i]->setParentItem(m_endLayout);
insertAtLayoutTail(m_endLayout, appletlist[i]);
} else {
appletlist[i]->setParentItem(m_mainLayout);
insertAtLayoutIndex(m_mainLayout, appletlist[i], i-splitter1);
}
} else if (firstSplitterFound && secondSplitterFound) {
appletlist[i]->setParentItem(m_endLayout);
insertAtLayoutIndex(m_endLayout, appletlist[i], i-splitter2);
}
}
for(int i=0; i<appletlist.count()-1; ++i) {
QQuickItem *before = appletlist[i];
QQuickItem *after = appletlist[i+1];
reorderParabolicSpacers();
}
if (before->parentItem() == after->parentItem()) {
before->stackBefore(after);
}
}
void LayoutManager::printAppletList(QList<QQuickItem *> list)
{
for(int i=0; i<list.count(); ++i) {
bool issplitter = list[i]->property("isInternalViewSplitter").toBool();
bool isparabolicspacer = list[i]->property("isParabolicEdgeSpacer").toBool();
//! Confirm Last item of End Layout
if (m_endLayout->childItems().count() > 0) {
QQuickItem *lastItem = m_endLayout->childItems()[m_endLayout->childItems().count()-1];
int correctpos{-1};
for(int i=0; i<appletlist.count()-1; ++i) {
if (lastItem == appletlist[i]) {
correctpos = i;
break;
}
if (issplitter) {
qDebug() << i << " __ JUSTIFY SPLITTER";
continue;
}
if (correctpos>=0) {
lastItem->stackBefore(appletlist[correctpos+1]);
if (isparabolicspacer) {
qDebug() << i << " __ PARABOLICSPACER";
continue;
}
QVariant appletVariant = list[i]->property("applet");
if (!appletVariant.isValid()) {
continue;
}
PlasmaQuick::AppletQuickItem *appletitem = appletVariant.value<PlasmaQuick::AppletQuickItem *>();
if (appletitem) {
qDebug() << i << " __ " << appletitem->applet()->pluginMetaData().pluginId();
}
}
}

View File

@ -136,6 +136,7 @@ private slots:
void updateOrder();
void cleanupOptions();
void reorderParabolicSpacers();
private:
void restoreOptions();
@ -148,6 +149,7 @@ private:
void insertAtLayoutTail(QQuickItem *layout, QQuickItem *item);
void insertAtLayoutHead(QQuickItem *layout, QQuickItem *item);
void insertAtLayoutIndex(QQuickItem *layout, QQuickItem *item, const int &index);
void setSplitterPosition(const int &position);
void setSplitterPosition2(const int &position);
@ -172,6 +174,8 @@ private:
QQuickItem *appletItem(const int &id);
QQuickItem *appletItemInLayout(QQuickItem *layout, const int &id);
void printAppletList(QList<QQuickItem *> list);
QList<int> toIntList(const QString &serialized);
QString toStr(const QList<int> &list);

View File

@ -141,16 +141,6 @@ Item {
//use the new parabolic ability in order to handle all parabolic effect messages
var scales = abilityItem.abilities.parabolic.applyParabolicEffect(index, currentMousePosition, length);
//Left hiddenSpacer for first task
if(abilityItem.isFirstItemInContainer) {
hiddenSpacerLeft.nScale = scales.leftScale - 1;
}
//Right hiddenSpacer for last task
if(abilityItem.isLastItemInContainer) {
hiddenSpacerRight.nScale = scales.rightScale - 1;
}
if (!parabolicItem.isUpdatingOnlySpacers) {
abilityItem.parabolicItem.zoom = abilityItem.abilities.parabolic.factor.zoom;
} else {