Commit 84300b51 authored by Eike Hein's avatar Eike Hein

Fix DND onto Task Manager for groups, group dialog scrollbar

Summary:
With this patch drag-hover activation will work for group children,
and moving between different group parents while dragging will
correctly refresh the dialog contents.
BUG:379888

The patch also makes GroupDialog more similar to CompactApplet in
desktoppackage/, in particular managing applet status and activa-
ting the window explicitly. There is no concrete reason for this,
but it seemed like a good idea while debugging the DND issues.

Further, while inverting the MouseHandler<>ScrollArea nesting I
removed some dodgy geometry-setting code for the inside item, and
the ScrollArea viewport now is a single item. This very likely
addresses some reports that the scrollbar sometimes wouldn't appear
when required.
BUG:379037

Reviewers: #plasma

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D6231
parent 9d8879a1
......@@ -35,12 +35,13 @@ PlasmaCore.Dialog {
hideOnWindowDeactivate: true
location: plasmoid.location
property int preferredWidth: Screen.width / (3 * Screen.devicePixelRatio)
property int preferredHeight: Screen.height / (2 * Screen.devicePixelRatio)
property int contentWidth: scrollArea.overflowing ? mainItem.width - (units.smallSpacing * 3) : mainItem.width
property TextMetrics textMetrics: TextMetrics {}
readonly property int preferredWidth: Screen.width / (3 * Screen.devicePixelRatio)
readonly property int preferredHeight: Screen.height / (2 * Screen.devicePixelRatio)
readonly property int contentWidth: scrollArea.overflowing ? mainItem.width - (units.smallSpacing * 3) : mainItem.width
readonly property TextMetrics textMetrics: TextMetrics {}
property alias overflowing: scrollArea.overflowing
property alias activeTask: focusActiveTaskTimer.targetIndex
property var _oldAppletStatus: PlasmaCore.Types.UnknownStatus
function selectTask(task) {
if (!task) {
......@@ -51,65 +52,63 @@ PlasmaCore.Dialog {
scrollArea.ensureItemVisible(task);
}
mainItem: PlasmaExtras.ScrollArea {
id: scrollArea
mainItem: MouseHandler {
id: mouseHandler
property bool overflowing: (viewport.height < contentItem.height)
target: taskList
handleWheelEvents: !scrollArea.overflowing
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
Timer {
id: focusActiveTaskTimer
function ensureItemVisible(item) {
var itemTop = item.y;
var itemBottom = (item.y + item.height);
property var targetIndex: null
if (itemTop < flickableItem.contentY) {
flickableItem.contentY = itemTop;
}
interval: 0
repeat: false
if ((itemBottom - flickableItem.contentY) > viewport.height) {
flickableItem.contentY = Math.abs(viewport.height - itemBottom);
}
}
onTriggered: {
// Now we can home in on the previously active task
// collected in groupDialog.onVisibleChanged.
MouseHandler {
id: mouseHandler
if (targetIndex != null) {
for (var i = 0; i < groupRepeater.count; ++i) {
var task = groupRepeater.itemAt(i);
width: parent.width
height: (groupRepeater.count * (LayoutManager.verticalMargins()
+ Math.max(theme.mSize(theme.defaultFont).height, units.iconSizes.medium)))
if (task.modelIndex() == targetIndex) {
selectTask(task);
return;
}
}
}
}
}
target: taskList
handleWheelEvents: !scrollArea.overflowing
PlasmaExtras.ScrollArea {
id: scrollArea
Timer {
id: focusActiveTaskTimer
anchors.fill: parent
property var targetIndex: null
readonly property bool overflowing: (viewport.height < contentItem.height)
interval: 0
repeat: false
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
onTriggered: {
// Now we can home in on the previously active task
// collected in groupDialog.onVisibleChanged.
function ensureItemVisible(item) {
var itemTop = item.y;
var itemBottom = (item.y + item.height);
if (targetIndex != null) {
for (var i = 0; i < groupRepeater.count; ++i) {
var task = groupRepeater.itemAt(i);
if (itemTop < flickableItem.contentY) {
flickableItem.contentY = itemTop;
}
if (task.modelIndex() == targetIndex) {
selectTask(task);
return;
}
}
}
if ((itemBottom - flickableItem.contentY) > viewport.height) {
flickableItem.contentY = Math.abs(viewport.height - itemBottom);
}
}
TaskList {
id: taskList
anchors.fill: parent
width: parent.width
add: Transition {
// We trigger a null-interval timer in the first add
......@@ -189,21 +188,24 @@ PlasmaCore.Dialog {
]
onVisualParentChanged: {
if (!visualParent) {
if (visible && visualParent) {
attachModel();
} else {
visible = false;
}
}
onVisibleChanged: {
if (visible && visualParent) {
groupFilter.model = tasksModel;
groupFilter.rootIndex = groupFilter.modelIndex(visualParent.itemIndex);
_oldAppletStatus = plasmoid.status;
plasmoid.status = PlasmaCore.Types.RequiresAttentionStatus;
groupRepeater.aboutToPopulate = true;
groupRepeater.model = groupFilter;
attachModel();
mainItem.forceActiveFocus();
groupDialog.requestActivate();
mouseHandler.forceActiveFocus();
} else {
plasmoid.status = _oldAppletStatus;
visualParent = null;
groupRepeater.model = undefined;
groupFilter.model = undefined;
......@@ -211,14 +213,40 @@ PlasmaCore.Dialog {
}
}
function attachModel() {
if (!visualParent) {
return;
}
if (!groupFilter.model) {
groupFilter.model = tasksModel;
}
groupRepeater.aboutToPopulate = true;
groupFilter.rootIndex = tasksModel.makeModelIndex(visualParent.itemIndex);
if (!groupRepeater.model) {
groupRepeater.model = groupFilter;
}
}
function updateSize() {
if (!visible || !visualParent) {
if (!visible) {
return;
}
if (!visualParent) {
visible = false;
return;
}
if (!groupRepeater.count) {
if (!visualParent.childCount) {
visible = false;
} else {
// Setting VisualDataModel.rootIndex drops groupRepeater.count to 0
// before the actual row count. updateSize is therefore invoked twice;
// only update size once the repeater count matches the model role.
} else if (visualParent.childCount == groupRepeater.count) {
var task;
var maxWidth = 0;
var maxHeight = 0;
......@@ -238,9 +266,16 @@ PlasmaCore.Dialog {
task.labelTextChanged.connect(updateSize);
}
maxWidth += LayoutManager.horizontalMargins() + units.iconSizes.medium + 2 * units.smallSpacing;
maxHeight = groupRepeater.count * (LayoutManager.verticalMargins() + Math.max(theme.mSize(theme.defaultFont).height, units.iconSizes.medium));
maxWidth += LayoutManager.horizontalMargins() + units.iconSizes.medium + 2 * units.smallSpacing;
// Add horizontal space for scrollbar if needed.
// FIXME TODO HACK: Use actuall scrollbar width instead of a good guess.
if (maxHeight > preferredHeight) {
maxWidth += (units.smallSpacing * 3);
}
mainItem.height = Math.min(preferredHeight, maxHeight);
mainItem.width = Math.min(preferredWidth, (tasks.vertical ? Math.max(maxWidth, tasks.width) : Math.min(maxWidth, tasks.width)));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment