File indexing completed on 2025-01-26 05:06:18
0001 /* 0002 SPDX-FileCopyrightText: 2012-2013 Eike Hein <hein@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 .import org.kde.kirigami 2.20 as Kirigami 0008 0009 const iconMargin = Math.round(Kirigami.Units.smallSpacing / 4); 0010 const labelMargin = Kirigami.Units.smallSpacing; 0011 0012 function horizontalMargins() { 0013 const spacingAdjustment = (tasks.plasmoid.pluginName === "org.kde.plasma.icontasks") ? (Kirigami.Settings.tabletMode ? 3 : tasks.plasmoid.configuration.iconSpacing) : 1 0014 return (taskFrame.margins.left + taskFrame.margins.right) * (tasks.vertical ? 1 : spacingAdjustment); 0015 } 0016 0017 function verticalMargins() { 0018 const spacingAdjustment = (tasks.plasmoid.pluginName === "org.kde.plasma.icontasks") ? (Kirigami.Settings.tabletMode ? 3 : tasks.plasmoid.configuration.iconSpacing) : 1 0019 return (taskFrame.margins.top + taskFrame.margins.bottom) * (tasks.vertical ? spacingAdjustment : 1); 0020 } 0021 0022 function adjustMargin(height, margin) { 0023 var available = height - verticalMargins(); 0024 0025 if (available < Kirigami.Units.iconSizes.small) { 0026 return Math.floor((margin * (Kirigami.Units.iconSizes.small / available)) / 3); 0027 } 0028 0029 return margin; 0030 } 0031 0032 function launcherLayoutTasks() { 0033 return Math.round(tasksModel.logicalLauncherCount / Math.floor(preferredMinWidth() / launcherWidth())); 0034 } 0035 0036 function launcherLayoutWidthDiff() { 0037 return (launcherLayoutTasks() * taskWidth()) - (tasksModel.logicalLauncherCount * launcherWidth()); 0038 } 0039 0040 function logicalTaskCount() { 0041 var count = (tasksModel.count - tasksModel.logicalLauncherCount) + launcherLayoutTasks(); 0042 0043 return Math.max(tasksModel.count ? 1 : 0, count); 0044 } 0045 0046 function maxStripes() { 0047 var length = tasks.vertical ? tasks.width : tasks.height; 0048 var minimum = tasks.vertical ? preferredMinWidth() : preferredMinHeight(); 0049 0050 return Math.min(tasks.plasmoid.configuration.maxStripes, Math.max(1, Math.floor(length / minimum))); 0051 } 0052 0053 function tasksPerStripe() { 0054 if (tasks.plasmoid.configuration.forceStripes) { 0055 return Math.ceil(logicalTaskCount() / maxStripes()); 0056 } else { 0057 var length = tasks.vertical ? taskList.height : taskList.width; 0058 var minimum = tasks.vertical ? preferredMinHeight() : preferredMinWidth(); 0059 0060 return Math.floor(length / minimum); 0061 } 0062 } 0063 0064 function calculateStripes() { 0065 var stripes = tasks.plasmoid.configuration.forceStripes ? tasks.plasmoid.configuration.maxStripes : Math.min(tasks.plasmoid.configuration.maxStripes, Math.ceil(logicalTaskCount() / tasksPerStripe())); 0066 0067 return Math.min(stripes, maxStripes()); 0068 } 0069 0070 function full() { 0071 return (maxStripes() == calculateStripes()); 0072 } 0073 0074 function optimumCapacity(width, height) { 0075 var length = tasks.vertical ? height : width; 0076 var maximum = tasks.vertical ? preferredMaxHeight() : preferredMaxWidth(); 0077 0078 if (!tasks.vertical) { 0079 // Fit more tasks in this case, that is possible to cut text, before combining tasks. 0080 return Math.ceil(length / maximum) * maxStripes() + 1; 0081 } 0082 0083 return Math.floor(length / maximum) * maxStripes(); 0084 } 0085 0086 function layoutWidth() { 0087 if (tasks.plasmoid.configuration.forceStripes && !tasks.vertical) { 0088 return Math.min(tasks.width, Math.max(preferredMaxWidth(), tasksPerStripe() * preferredMaxWidth())); 0089 } else { 0090 return tasks.width; 0091 } 0092 } 0093 0094 function layoutHeight() { 0095 if (tasks.plasmoid.configuration.forceStripes && tasks.vertical) { 0096 return Math.min(tasks.height, Math.max(preferredMaxHeight(), tasksPerStripe() * preferredMaxHeight())); 0097 } else { 0098 return tasks.height; 0099 } 0100 } 0101 0102 function preferredMinWidth() { 0103 var width = launcherWidth(); 0104 0105 if (!tasks.vertical && !tasks.iconsOnly) { 0106 width += 0107 (Kirigami.Units.smallSpacing * 2) + 0108 (Kirigami.Units.gridUnit * 8); 0109 } 0110 0111 return width; 0112 } 0113 0114 function preferredMaxWidth() { 0115 if (tasks.iconsOnly) { 0116 if (tasks.vertical) { 0117 return tasks.width + verticalMargins(); 0118 } else { 0119 return tasks.height + horizontalMargins(); 0120 } 0121 } 0122 0123 if (tasks.plasmoid.configuration.groupingStrategy != 0 && !tasks.plasmoid.configuration.groupPopups && !tasks.iconsOnly) { 0124 return preferredMinWidth(); 0125 } 0126 0127 return Math.floor(preferredMinWidth() * 1.6); 0128 } 0129 0130 function preferredMinHeight() { 0131 // TODO FIXME UPSTREAM: Port to proper font metrics for descenders once we have access to them. 0132 return Kirigami.Units.iconSizes.sizeForLabels + 4; 0133 } 0134 0135 function preferredMaxHeight() { 0136 if (tasks.vertical) { 0137 return verticalMargins() + 0138 Math.min( 0139 // Do not allow the preferred icon size to exceed the width of 0140 // the vertical task manager. 0141 tasks.width, 0142 tasks.iconsOnly ? tasks.width : 0143 Math.max( 0144 Kirigami.Units.iconSizes.sizeForLabels, 0145 Kirigami.Units.iconSizes.medium 0146 ) 0147 ); 0148 } else { 0149 return verticalMargins() + 0150 Math.min( 0151 Kirigami.Units.iconSizes.small * 3, 0152 Kirigami.Units.iconSizes.sizeForLabels * 0153 3); 0154 } 0155 } 0156 0157 // Returns the number of 'm' characters whose joint width must be available in the task button label 0158 // so that the button text is rendered at all. 0159 function minimumMColumns() { 0160 return tasks.vertical ? 4 : 5; 0161 } 0162 0163 function taskWidth() { 0164 if (tasks.vertical) { 0165 return Math.floor(taskList.width / calculateStripes()); 0166 } else { 0167 if (full() && Math.max(1, logicalTaskCount()) > tasksPerStripe()) { 0168 return Math.floor(taskList.width / Math.ceil(logicalTaskCount() / maxStripes())); 0169 } else { 0170 return Math.min(preferredMaxWidth(), Math.floor(taskList.width / Math.min(logicalTaskCount(), tasksPerStripe()))); 0171 } 0172 } 0173 } 0174 0175 function taskHeight() { 0176 if (tasks.vertical) { 0177 if (full() && Math.max(1, logicalTaskCount()) > tasksPerStripe()) { 0178 return Math.floor(taskList.height / Math.ceil(logicalTaskCount() / maxStripes())); 0179 } else { 0180 return Math.min(preferredMaxHeight(), Math.floor(taskList.height / Math.min(logicalTaskCount(), tasksPerStripe()))); 0181 } 0182 } else { 0183 return Math.floor(taskList.height / calculateStripes()); 0184 } 0185 } 0186 0187 function launcherWidth() { 0188 var baseWidth = tasks.vertical ? preferredMinHeight() : Math.min(tasks.height, Kirigami.Units.iconSizes.small * 3); 0189 0190 return (baseWidth + horizontalMargins()) 0191 - (adjustMargin(baseWidth, taskFrame.margins.top) + adjustMargin(baseWidth, taskFrame.margins.bottom)); 0192 } 0193 0194 function maximumContextMenuTextWidth() { 0195 return (Kirigami.Units.iconSizes.sizeForLabels * 28); 0196 } 0197 0198 function layout(container) { 0199 var item; 0200 var stripes = calculateStripes(); 0201 var taskCount = tasksModel.count - tasksModel.logicalLauncherCount; 0202 var width = taskWidth(); 0203 var adjustedWidth = width; 0204 var height = taskHeight(); 0205 0206 if (!tasks.vertical && stripes == 1 && taskCount) 0207 { 0208 var shrink = ((tasksModel.count - tasksModel.logicalLauncherCount) * preferredMaxWidth()) 0209 + (tasksModel.logicalLauncherCount * launcherWidth()) > taskList.width; 0210 width = Math.min(shrink ? width + Math.floor(launcherLayoutWidthDiff() / taskCount) : width, 0211 preferredMaxWidth()); 0212 } 0213 0214 for (var i = 0; i < container.count; ++i) { 0215 item = container.itemAt(i); 0216 0217 if (!item) { 0218 continue; 0219 } 0220 0221 adjustedWidth = width; 0222 0223 if (!tasks.vertical && !tasks.iconsOnly && (tasks.plasmoid.configuration.separateLaunchers || stripes == 1)) { 0224 if (item.model && (item.model.IsLauncher 0225 || (!tasks.plasmoid.configuration.separateLaunchers && item.model.IsStartup && item.model.HasLauncher))) { 0226 adjustedWidth = launcherWidth(); 0227 } else if (stripes > 1 && i == tasksModel.logicalLauncherCount) { 0228 adjustedWidth += launcherLayoutWidthDiff(); 0229 } 0230 } 0231 0232 item.width = adjustedWidth; 0233 item.height = height; 0234 item.visible = true; 0235 } 0236 }