Use a fixed curve for the fan

The arc radius no longer grows with the number of entries; a short fan is
the bottom of the same curve, like the Dock. The lean setting becomes a
curve radius in multiples of the icon spacing. The 60° cap only kicks in
for very large fans.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
NotAlexNoyleandClaude Fable 5.1 committed 2026-10-14 17:18:43 -04:00
1 parent 70bdc50dd6
commit 65a3aa4457
4 files changed
+23 -20

No files matched your search

+6 -5
View File
@@ -17,7 +17,7 @@ Escape) to fold the fan back into the icon.
- Thumbnails for images, PDFs, videos and whatever else your thumbnailers
cover, using the same preview plugins as Dolphin.
- Curves to the right, or to the left when the arc would not fit on screen.
- Configurable lean angle, number of entries, icon size, animation length,
- Configurable curve radius, number of entries, icon size, animation length,
folder, panel icon, sort order, hidden files.
- Middle-click the panel icon to open the folder. Drop files on it to move
them into the folder.
@@ -54,7 +54,7 @@ and choose *Configure…* to change the folder, icon and the rest.
| Icon | `folder-download` | Icon shown on the panel |
| Files shown in the fan | 8 | Entries before the "N more…" item |
| Fan icon size | 48 px | Icon size inside the fan |
| Fan lean at the top | 38° | How far the top entry tilts from vertical; the arc starts vertical at the icon |
| Curve radius | 13 × icon spacing | Radius of the arc; the curve is the same however many entries there are. Smaller curls over more |
| Fan curves | Away from the screen edge | Force right or left if you prefer |
| Animation length | 350 ms | Scaled by the global animation speed |
| Sort by / Descending / Folders first | Date, descending | Same options as Folder View |
@@ -85,9 +85,10 @@ Layout:
- `contents/ui/FanItem.qml` – one entry: icon, label, open/close animation
- `contents/ui/configGeneral.qml`, `contents/config/main.xml` – settings
The arc is a circle that leaves the panel icon vertically. Its radius grows
with the number of entries so that the top entry tilts exactly as far as the
configured lean, capped at 60° to keep each label clear of the icon above.
The arc is a circle of fixed radius that leaves the panel icon vertically,
so a short fan is just the bottom of the same curve. Only if a very large fan
would tilt its top entry past 60° does the radius grow, to keep each label
clear of the icon above.
## License
+3 -3
View File
@@ -26,9 +26,9 @@
<label>Put the first file of the sort order (newest, by default) at the top of the fan and the "more" entry at the bottom.</label>
<default>true</default>
</entry>
<entry name="fanLean" type="Int">
<label>How far the top of the fan leans sideways, in degrees from vertical. The fan always starts vertical at the panel icon.</label>
<default>38</default>
<entry name="fanRadius" type="Int">
<label>Radius of the fan's curve, in multiples of the spacing between entries. The curve is the same whatever the number of entries; smaller values curl over more.</label>
<default>13</default>
</entry>
<entry name="direction" type="Int">
<label>Which way the fan curves: 0 = automatic, 1 = right, 2 = left.</label>
+9 -7
View File
@@ -39,11 +39,14 @@ PlasmaCore.Dialog {
readonly property int gap: Math.round(iconSize * 0.35)
readonly property int step: iconSize + gap
readonly property bool newestAtTop: Plasmoid.configuration.newestAtTop
// The arc leaves the dock icon vertically and tilts over until its top
// entry leans this far from vertical (radians). Above ~60° a label, which
// sits beside its icon towards the inside of the curve, would run into
// the icon above it even with the small downward label offset below.
readonly property real maxTangent: Math.max(10, Math.min(60, Plasmoid.configuration.fanLean)) * Math.PI / 180
// The arc leaves the dock icon vertically and curls over with a fixed
// radius, like the Dock's fan: a short fan is simply the bottom of the
// same curve. Above ~60° of tilt a label, which sits beside its icon
// towards the inside of the curve, would run into the icon above it even
// with the small downward label offset, so the radius only grows beyond
// the configured one when a very large fan would pass that.
readonly property real fixedRadius: step * Math.max(4, Math.min(60, Plasmoid.configuration.fanRadius))
readonly property real maxTangent: 60 * Math.PI / 180
readonly property int labelDrop: Math.round(iconSize / 6)
readonly property int labelGap: Math.round(iconSize * 0.25)
readonly property int labelMaxWidth: iconSize * 5
@@ -52,8 +55,7 @@ PlasmaCore.Dialog {
readonly property real firstDistance: dockHalf + iconSize * 0.75
readonly property int itemCount: fanRepeater.count + 1
readonly property real arcLength: firstDistance + (itemCount - 1) * step
// Radius grows with the number of entries so the arc always ends at maxTangent.
readonly property real arcRadius: Math.max(step * 8, arcLength / maxTangent)
readonly property real arcRadius: Math.max(fixedRadius, arcLength / maxTangent)
readonly property real maxAngle: angleFor(itemCount - 1)
readonly property real arcWidth: arcRadius * (1 - Math.cos(maxAngle))
readonly property real arcHeight: arcRadius * Math.sin(maxAngle)
+5 -5
View File
@@ -16,7 +16,7 @@ KCM.SimpleKCM {
property alias cfg_fanIconSize: iconSizeSpin.value
property int cfg_direction
property alias cfg_newestAtTop: newestAtTopCheck.checked
property alias cfg_fanLean: leanSpin.value
property alias cfg_fanRadius: radiusSpin.value
property alias cfg_previews: previewsCheck.checked
property alias cfg_showHiddenFiles: hiddenCheck.checked
property int cfg_sortMode
@@ -70,11 +70,11 @@ KCM.SimpleKCM {
}
QQC2.SpinBox {
id: leanSpin
Kirigami.FormData.label: i18n("Fan lean at the top:")
from: 10
id: radiusSpin
Kirigami.FormData.label: i18n("Curve radius:")
from: 4
to: 60
textFromValue: (value, locale) => i18n("%1°", value)
textFromValue: (value, locale) => i18n("%1 × icon spacing", value)
valueFromText: (text, locale) => parseInt(text)
}