@@ -93,8 +93,9 @@ int getMargin(CoolItem item) {
9393 int minWidth (CoolItem item ) {
9494 return 7 + 2 + item .minimumWidth + (item .minimumWidth != 0 ? 4 : 0 ) + (!isLastItemOfRow (indexOf (item )) ? 2 : 0 );
9595 }
96- boolean moveDelta (int index , int cx , int cy , int dx , int dy ) {
96+ boolean moveDelta (int index , int dx , int dy ) {
9797 if (dx == 0 && dy == 0 ) return false ;
98+ boolean needResize = false ;
9899 boolean needLayout = false ;
99100 if (dy == 0 ) {
100101 int [] ws = new int [items .length ];
@@ -113,6 +114,10 @@ boolean moveDelta(int index, int cx, int cy, int dx, int dy) {
113114 CoolItem next = items [index + 1 ];
114115 items [index ] = next ;
115116 items [index + 1 ] = item ;
117+ if (item .wrap ) {
118+ next .wrap = true ;
119+ item .wrap = false ;
120+ }
116121 int width = next .idealWidth ;
117122 next .idealWidth = item .idealWidth ;
118123 item .idealWidth = width ;
@@ -189,6 +194,10 @@ boolean moveDelta(int index, int cx, int cy, int dx, int dy) {
189194 while (dx >= minWidth (swpItem )) {
190195 items [swpIndex + 1 ] = items [swpIndex ];
191196 items [swpIndex ] = swpItem ;
197+ if (swpItem .wrap ) {
198+ items [swpIndex ].wrap = true ;
199+ swpItem .wrap = false ;
200+ }
192201 swpItem = items [swpIndex + 1 ];
193202 needLayout = true ;
194203 dx -= minWidth (swpItem );
@@ -228,13 +237,192 @@ boolean moveDelta(int index, int cx, int cy, int dx, int dy) {
228237 }
229238 }
230239 }
240+ } else { // dy != 0
241+ int line = verticalLine (index );
242+ if (line + dy < 0 ) {
243+ if (index == 0 && isLastItemOfRow (index )) {
244+ // already the top line, no need to add a new line
245+ } else {
246+ // Move upwards, add a new line
247+ CoolItem ci = items [index ];
248+ if ((index == 0 && items .length > 1 ) // first line's first item moves upwards
249+ || (ci .wrap && index < items .length - 1 )) { // some inner item
250+ items [index + 1 ].wrap = true ;
251+ }
252+ for (int i = index ; i > 0 ; i --) {
253+ items [i ] = items [i - 1 ];
254+ }
255+ items [0 ] = ci ;
256+ items [1 ].wrap = true ;
257+ ci .wrap = false ;
258+ needLayout = true ;
259+ needResize = true ;
260+ }
261+ } else if (line + dy < getVerticalLines ()) {
262+ // inline move, no need to create new line, but maybe remove lines
263+ int lineNumber = line + dy ;
264+ int i = 0 ;
265+ for (i = 0 ; i < items .length ; i ++) {
266+ if (lineNumber == 0 ) {
267+ // should always breaks from here
268+ //i++;
269+ break ;
270+ }
271+ if (items [i ].wrap ) {
272+ lineNumber --;
273+ }
274+ }
275+ if (i > 0 ) i --; // re-adjust the index the above line's last item
276+ CoolItem ci = items [index ];
277+ if (index == 0 && isLastItemOfRow (index )) {
278+ needResize = true ;
279+ }
280+ if (ci .wrap ) {
281+ if (isLastItemOfRow (index )) {
282+ // remove a line
283+ needResize = true ;
284+ }
285+ if (index < items .length - 1 ) { // index != 0 because ci.wrap
286+ items [index + 1 ].wrap = true ;
287+ }
288+ }
289+ int x = ci .getPosition ().x + dx ;
290+ if (x <= 0 ) { // to left most
291+ if (i == 0 ) { // move upwards to line 0
292+ ci .wrap = false ;
293+ } else {
294+ if (index == 0 && i == 1 ) { // move the first single item to the second line
295+ } else {
296+ ci .wrap = true ;
297+ }
298+ if (i < items .length - 1 ) {
299+ items [i + 1 ].wrap = false ;
300+ }
301+ }
302+ } else { // inside the line
303+ int rowWidth = 0 ;
304+ int separator = 2 ;
305+ for (; i < items .length ; i ++) {
306+ CoolItem item = items [i ];
307+ int minimum = item .minimumWidth + (item .minimumWidth != 0 ? 2 : 0 );
308+ rowWidth += 7 + 2 + Math .max (item .idealWidth , minimum ) + separator ;
309+ int xx = item .getPosition ().x ;
310+ if (xx < x && (x <= rowWidth || isLastItemOfRow (i ))) {
311+ item .idealWidth = Math .max (0 , x - xx - (7 + 2 + minimum + separator ));
312+ minimum = ci .minimumWidth + (ci .minimumWidth != 0 ? 2 : 0 );
313+ int mw = 7 + 2 + minimum + separator ;
314+ ci .idealWidth = Math .max (item .minimumWidth , Math .max (ci .idealWidth , rowWidth - x - mw ));
315+ if (rowWidth - x - mw < ci .idealWidth ) {
316+ needResize = true ;
317+ }
318+ break ;
319+ }
320+ }
321+ ci .wrap = false ;
322+ }
323+ // copy and move items -- re-order
324+ if (dy < 0 && x > 0 && i < items .length - 1 ) {
325+ i ++;
326+ }
327+ if (dy > 0 ) {
328+ for (int j = index ; j < i ; j ++) {
329+ items [j ] = items [j + 1 ];
330+ }
331+ } else {
332+ for (int j = index ; j > i ; j --) {
333+ items [j ] = items [j - 1 ];
334+ }
335+ }
336+ items [i ] = ci ;
337+ items [0 ].wrap = false ;
338+ needLayout = true ;
339+ } else { // total lines is greater than current line count
340+ if ((items [index ].wrap || index == 0 ) && isLastItemOfRow (index )) {
341+ // already the bottom line!
342+ } else {
343+ // append new line
344+ CoolItem ci = items [index ];
345+ if (index > 0 && ci .wrap ) {
346+ items [index + 1 ].wrap = true ;
347+ }
348+ for (int i = index ; i < items .length - 1 ; i ++) {
349+ items [i ] = items [i + 1 ];
350+ }
351+ items [items .length - 1 ] = ci ;
352+ ci .wrap = true ;
353+ needLayout = true ;
354+ needResize = true ;
355+ }
356+ }
357+ }
358+ int w = width ;
359+ int h = height ;
360+ if (needResize ) {
361+ Point computeSize = computeSize (-1 , -1 , false );
362+ w = computeSize .x ;
363+ h = computeSize .y ;
231364 }
232365 if (needLayout ) {
233- SetWindowPos (null , null , 0 , 0 , width , height , -1 );
366+ SetWindowPos (null , null , 0 , 0 , width , h , -1 );
367+ }
368+ if (w > width ) {
369+ for (int i = index + 1 ; i < items .length ; i ++) {
370+ if (isLastItemOfRow (i )) {
371+ moveDelta (i , width - height , 0 );
372+ break ;
373+ }
374+ }
234375 }
235376 return needLayout ;
236377 }
237378
379+ int getVerticalLines () {
380+ int lines = 0 ;
381+ for (int i = 0 ; i < items .length ; i ++) {
382+ if (items [i ].wrap ) {
383+ lines ++;
384+ }
385+ }
386+ return lines + 1 ;
387+ }
388+ int verticalLine (int index ) {
389+ int lines = 0 ;
390+ for (int i = 0 ; i <= index ; i ++) {
391+ if (items [i ].wrap ) {
392+ lines ++;
393+ }
394+ }
395+ return lines ;
396+ }
397+
398+ int verticalLineByPixel (int px ) {
399+ if (px < 0 ) {
400+ return -1 ;
401+ }
402+ int lines = 0 ;
403+ int rowHeight = 0 ;
404+ int height = 0 ;
405+ for (int i = 0 ; i < items .length ; i ++) {
406+ if (items [i ].wrap ) {
407+ height += rowHeight + 2 ;
408+ rowHeight = 0 ;
409+ if (px < height ) {
410+ return lines ;
411+ }
412+ lines ++;
413+ }
414+ if (items [i ].control == null ) {
415+ rowHeight = Math .max (rowHeight , 4 );
416+ } else if (items [i ].ideal ) {
417+ rowHeight = Math .max (rowHeight , items [i ].idealHeight );
418+ }
419+ }
420+ height += rowHeight ;
421+ if (px < height ) {
422+ return lines ;
423+ }
424+ return lines + 1 ;
425+ }
238426 protected boolean SetWindowPos (Object hWnd , Object hWndInsertAfter , int X , int Y , int cx , int cy , int uFlags ) {
239427 width = cx ;
240428 height = cy ;
0 commit comments