@@ -28,6 +28,7 @@ Control {
2828
2929 property string iconSource
3030 property bool dndEnabled: false
31+ property bool isDragHover: false
3132 readonly property bool isWindowedMode: LauncherController .currentFrame === " WindowedFrame"
3233 property alias displayFont: iconItemLabel .font
3334 property real iconScaleFactor: 1.0
@@ -57,6 +58,14 @@ Control {
5758 ColorSelector .pressed : false
5859 ColorSelector .family : D .Palette .CrystalColor
5960 flat: true
61+
62+ Rectangle {
63+ anchors .fill : parent
64+ color: " transparent"
65+ border .width : 2
66+ border .color : " blue"
67+ z: 999
68+ }
6069 contentItem: Column {
6170 anchors .fill : parent
6271
@@ -71,6 +80,22 @@ Control {
7180 height: width
7281 anchors .horizontalCenter : parent .horizontalCenter
7382
83+ Rectangle {
84+ id: dragHoverBackground
85+ visible: root .isDragHover
86+ anchors .centerIn : parent
87+ width: (parent .width + 16 ) * root .iconScaleFactor
88+ height: (parent .height + 16 ) * root .iconScaleFactor
89+ radius: isWindowedMode ? 10 : 18
90+ color: Qt .rgba (1 , 1 , 1 , 0.25 )
91+ }
92+
93+ // Rectangle {
94+ // anchors.fill: parent
95+ // border.width: 1
96+ // border.color: "red"
97+ // }
98+
7499 Loader {
75100 id: iconLoader
76101 anchors .fill : parent
@@ -91,6 +116,7 @@ Control {
91116 // Item will be hidden by checking the dndItem.currentlyDraggedId property. We assign the value
92117 // to that property here
93118 dndItem .currentlyDraggedId = target .Drag .mimeData [" text/x-dde-launcher-dnd-desktopId" ]
119+ dndItem .currentlyDraggedIconName = root .iconSource
94120 dndItem .Drag .hotSpot = target .Drag .hotSpot
95121 dndItem .Drag .mimeData = target .Drag .mimeData
96122
@@ -119,35 +145,149 @@ Control {
119145 id: folderComponent
120146
121147 Rectangle {
148+ id: ddd
122149 anchors .fill : parent
123150 color: " #26FFFFFF"
124151 radius: 12
125152
126- GridLayout {
127- id: folderGrid
128- anchors .fill : parent
129- rows: 2
130- columns: 2
131- anchors .margins : 8
132- columnSpacing: 8
133- rowSpacing: 8
153+ property real itemWidth: (width - (3 * 8 )) / 2
154+ property real itemHeight: (height - (3 * 8 )) / 2
155+
156+ function getItemX (index ) {
157+ let col = index % 2
158+ let ret = (col + 1 ) * 8 + col * itemWidth
159+ console .warn (" getItemX for index" , index, " itemWidth" , itemWidth,
160+ " ret" , ret)
161+ return ret
162+ }
163+
164+ function getItemY (index ) {
165+ let row = Math .floor (index / 2 )
166+ let ret = (row + 1 ) * 8 + row * itemHeight
167+ console .warn (" getItemY for index" , index, " itemHeight" , itemHeight, " ret" , ret)
168+ return ret
169+ }
170+ Rectangle {
171+ width: 100
172+ height: 100
173+ color: " red"
174+ id: testRect
175+ scale: 1.5
176+ x: 93
177+ y: 95
178+ visible: true
179+ }
180+
181+ // GridLayout {
182+ // id: folderGrid
183+ // anchors.fill: parent
184+ // rows: 2
185+ // columns: 2
186+ // anchors.margins: 8
187+ // columnSpacing: 8
188+ // rowSpacing: 8
134189
135190 Repeater {
136191 model: icons
137192
138193 DciIcon {
194+ id: folderIcon
139195 Layout .fillHeight : true
140196 Layout .fillWidth : true
141197 Layout .alignment : Qt .AlignTop | Qt .AlignLeft
142198
143199 // 添加最大高度限制,确保图标高度一致
144200 Layout .maximumHeight : Math .max (0 , parent .height / 2 - folderGrid .rowSpacing / 2 )
145201
202+ x: ddd .getItemX (index)
203+ y: ddd .getItemY (index)
204+
205+ width: ddd .itemWidth
206+ height: ddd .itemHeight
207+
146208 name: modelData
147- sourceSize: Qt .size (root .maxIconSizeInFolder , root .maxIconSizeInFolder )
148- scale: (parent .width / 2 / root .maxIconSizeInFolder ) * root .iconScaleFactor
209+ property var maxSize: Math .min (root .maxIconSizeInFolder , Math .min (width, height))
210+ sourceSize: Qt .size (Math .min (width, root .maxIconSizeInFolder ), Math .min (height, root .maxIconSizeInFolder ))
211+ scale: (parent .width / 2 / maxSize) * root .iconScaleFactor * introScale
212+
213+ onSourceSizeChanged: {
214+ console .warn (" sourceSize changed for index" , index, " new sourceSize" , sourceSize,
215+ " maxSize" , maxSize, " width" , width, " height" , height)
216+ }
217+ property real introScale: 1.0
218+
149219 palette: DTK .makeIconPalette (root .palette )
150220 theme: ApplicationHelper .DarkType
221+
222+ Rectangle {
223+ visible: false
224+ anchors .fill : parent
225+ border .width : 3
226+ border .color : " red"
227+ color: " transparent"
228+ z: 999
229+ }
230+
231+ // 位移动画属性
232+ property real introTranslateX: 0
233+ property real introTranslateY: 0
234+ ParallelAnimation {
235+ id: iconIntroAnim
236+
237+ NumberAnimation {
238+ target: folderIcon
239+ property: " introScale"
240+ from: folderIcon .introScale ; to: 1.0
241+ duration: 1000
242+ easing .type : Easing .OutCubic
243+ }
244+ NumberAnimation {
245+ target: folderIcon
246+ property: " x"
247+ from: folderIcon .introTranslateX ; to: ddd .getItemX (index)
248+ duration: 1000
249+ easing .type : Easing .OutCubic
250+ }
251+ NumberAnimation {
252+ target: folderIcon
253+ property: " y"
254+ from: folderIcon .introTranslateY ; to: ddd .getItemY (index)
255+ duration: 1000
256+ easing .type : Easing .OutCubic
257+ }
258+
259+ onFinished: {
260+ dndItem .mergeAnimPending = false
261+ dndItem .mergeAnimTargetIcon = " "
262+ dndItem .mergeAnimTargetIcon2 = " "
263+ }
264+ }
265+
266+ Component .onCompleted : {
267+ if (dndItem .mergeAnimPending
268+ && modelData === dndItem .mergeAnimTargetIcon ) {
269+ folderIcon .visible = false
270+ introScale = 2
271+ // introScale = 1
272+ Qt .callLater (function () {
273+ let localPos = ddd .mapFromItem (null ,
274+ dndItem .mergeAnimStartX , dndItem .mergeAnimStartY )
275+ folderIcon .introTranslateX = localPos .x + folderIcon .width / 2 * (folderIcon .scale - 1 )
276+ folderIcon .introTranslateY = localPos .y + folderIcon .height / 2 * (folderIcon .scale - 1 )
277+ console .warn (" local:" , localPos, " introTranslateX" ,dndItem .mergeAnimStartX , " introTranslateY" , dndItem .mergeAnimStartY )
278+ folderIcon .visible = true
279+ iconIntroAnim .start ()
280+ testRect .x = localPos .x + testRect .width / 2 * (testRect .scale - 1 )
281+ testRect .y = localPos .y + testRect .height / 2 * (testRect .scale - 1 )
282+ testRect .z = 999
283+ })
284+ } else if (dndItem .mergeAnimPending
285+ && modelData === dndItem .mergeAnimTargetIcon2 ) {
286+ introScale = 2
287+ // introScale = 1
288+ iconIntroAnim .start ()
289+ }
290+ }
151291 }
152292 }
153293
@@ -163,7 +303,7 @@ Control {
163303 height: parent .height / 2
164304 }
165305 }
166- }
306+ // }
167307 }
168308 }
169309
@@ -178,7 +318,14 @@ Control {
178318 scale: (parent .width / root .maxIconSize ) * root .iconScaleFactor
179319 palette: DTK .makeIconPalette (root .palette )
180320 theme: ApplicationHelper .DarkType
181- fillMode: Image .PreserveAspectFit
321+
322+ Rectangle {
323+ anchors .fill : parent
324+ color: " transparent"
325+ border .width : 2
326+ border .color : " red"
327+ }
328+ // fillMode: Image.PreserveAspectFit
182329 }
183330 }
184331 }
@@ -193,6 +340,7 @@ Control {
193340 property bool singleRow: font .pixelSize > (isWindowedMode ? Helper .windowed .doubleRowMaxFontSize : Helper .fullscreen .doubleRowMaxFontSize )
194341 property bool isNewlyInstalled: model .lastLaunchedTime === 0 && model .installedTime !== 0
195342 id: iconItemLabel
343+ visible: ! root .isDragHover
196344 text: isNewlyInstalled ? (" <font color='#669DFF' size='1' style='text-shadow: 0 0 1px rgba(255,255,255,0.1)'>●</font> " + root .text ) : root .text
197345 textFormat: isNewlyInstalled ? Text .StyledText : Text .PlainText
198346 width: parent .width
0 commit comments