Page 1 of 1

How to move list items?

Posted: Wed Nov 27, 2024 8:35 pm
by AZJIO
There are several squares. Some squares can be inside other squares. The smaller square must be above the larger square, otherwise it will not be visible. The goal is to move a square to a different position in the Z display order so that all squares are visible when processing a list of squares. How to make a movement in one cycle? You need to compare each square separately with every other square. To do this, I create a copy of the list and compare all other elements with the first element, then compare all other elements with the second element. If I find a square inside a square and its level is lower, then I try to move it above this square, respectively, if an element is found in position 5, and another element is in position 8, then I need to move 8 to 4.

It would be easier to simplify the example by making the numbers 1 to 10 and the condition to move them by number, but then I would be given a sorting function SortList(), but it would not be applicable to my problem.

The SwapElements() function is also not suitable, since I don't need to swap elements.

Essentially, I need sorting, only manual, to move one element to another position based on comparison criteria.

I need this for the CreationGuiPB program, in which the Frame and Panel elements should have priority in the queue for drawing them on the canvas. But at the same time, observe the order in which the elements are created and do not move them idle according to the size of the occupied area, but only if they cover other elements.

Code: Select all

Procedure MoveElementToPos(List List1.RECT())
	Protected NewList List2.RECT()
	Protected re, indList2Inside, indList1Outside, *e1, *e2
	Protected zz
	CopyList(List1() , List2())
	Repeat
		re = 1
		ForEach List2()
			ForEach List1()
				If List1()\left < List2()\left And List1()\right > List2()\right And List1()\top < List2()\top And List1()\bottom > List2()\bottom
					indList1Outside = ListIndex(List1())
					indList2Inside = ListIndex(List2())
; 					Debug indList1Outside
; 					Debug indList2Inside
					If indList2Inside > indList1Outside ; you can change the sign (<), but the task is to move
						Debug indList2Inside
						Debug indList1Outside
						*e1 = @List1() ; cache the current one
						SelectElement(List1(), indList2Inside) ; select an element to move
						*e2 = @List1()
						ChangeCurrentElement(List1(), *e1) ; restore the current one
; 						PeekI(List1())
; 						MoveElement(List1(), #PB_List_Before, SelectElement(List1(), indList2Inside))
						MoveElement(List1(), #PB_List_Before, *e2) ; move the current one
						; Create a new copy to check again
						CopyList(List1() , List2())
; 						SelectElement(List2(), indList1Outside)
; 						MoveElement(List2(), #PB_List_Before, indList2Inside)
						re = 0 ; move until there are no elements left to move
						zz + 1
						Debug zz ; check how many steps have been completed
						Break 2
					EndIf
				EndIf
			Next
		Next
	Until re
; 	Debug zz
EndProcedure

Define NewList List1.RECT()

AddElement(List1())
List1()\left = 100
List1()\right = 200
List1()\top = 100
List1()\bottom = 200

AddElement(List1())
List1()\left = 120
List1()\right = 180
List1()\top = 120
List1()\bottom = 180

AddElement(List1())
List1()\left = 300
List1()\right = 400
List1()\top = 300
List1()\bottom = 400

AddElement(List1())
List1()\left = 320
List1()\right = 380
List1()\top = 320
List1()\bottom = 380

ForEach List1()
	Debug List1()\left
Next
MoveElementToPos(List1())
ForEach List1()
	Debug List1()\left
Next

Re: How to move list items?

Posted: Wed Nov 27, 2024 9:44 pm
by HeX0R
Not sure I understood, do you mean something like this?

Code: Select all

Procedure SortProcedure(*a.RECT, *b.RECT)
	Protected AreaA, AreaB
	AreaA = (*a\right - *a\left) * (*a\bottom - *a\top)
	AreaB = (*b\right - *b\left) * (*b\bottom - *b\top)
	If AreaA < AreaB
		ProcedureReturn #PB_Sort_Lesser
  ElseIf AreaA > AreaB
    ProcedureReturn #PB_Sort_Greater
  Else
    ProcedureReturn #PB_Sort_Equal
  EndIf
EndProcedure



Define NewList List1.RECT()

AddElement(List1())
List1()\left = 100
List1()\right = 200
List1()\top = 100
List1()\bottom = 200

AddElement(List1())
List1()\left = 120
List1()\right = 180
List1()\top = 120
List1()\bottom = 180

AddElement(List1())
List1()\left = 300
List1()\right = 400
List1()\top = 300
List1()\bottom = 400

AddElement(List1())
List1()\left = 320
List1()\right = 380
List1()\top = 320
List1()\bottom = 380

ForEach List1()
	Debug List1()\left
Next
CustomSortList(List1(), @SortProcedure(), #PB_Sort_Descending)

ForEach List1()
	Debug List1()\left
Next

Re: How to move list items?

Posted: Wed Nov 27, 2024 9:55 pm
by AZJIO
Thank you.
I'll have to use version 6.12 to support this functionality.

Re: How to move list items?

Posted: Thu Nov 28, 2024 3:54 am
by Demivec
I haven't tried your CreationGuiPB code yet and so I was wondering in what order would you want for the following rectangles?

Code: Select all

;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
;a                              fffff        a
;a    bbbbbbbbbbb           eeeefeeefee      a
;a    b         b           e   f   f e      a
;a    b    ddddddddddd     gggggfgggfge      a
;a    b    d    b    d     ge   f   fge      a
;a    b cccdccccbcc  d     geeeefeeefee      a 
;a    b c  d    b c  d     g    f   f        a
;a    b c  d    b c  d     gggggfgggfg       a
;a    bbcbbdbbbbb c  d          f   f        a
;a      c  d      c  d          f   f        a
;a      c  ddddddddddd    iii   fffff        a
;a      c         c       i i                a
;a      ccccccccccc       iii                a
;a                       /                   a
;a--rect. i's size & pos. matches rect. h's--a
;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.

;If the rectangles were initially in the order a,b,c,d,e,f,g,h,i, 
;and that corresponded to their creation order, what order
;should they place in for rendering?

; Here's the same rectangles in a list with fields for left, top, right, bottom values:
;N   L, T;    R, B;  precalculated Area
;a   0, 0;   43,16;  688
;b   5, 2;   15, 9;   70
;c   7, 6;   17,13;   70
;d  10, 4;   20,11;   70
;e  27, 2;   37, 6;   40
;f  31, 1;   35,11;   40
;g  26, 4;   36, 8;   40
;h  25,11;   27,13;    4
;i  25,11;   27,13;    4

If any of the rectangles would be prohibited from being in the position shown then simply state that and eliminate those rectangles from the solution.

Re: How to move list items?

Posted: Fri Nov 29, 2024 2:32 am
by AZJIO
Demivec wrote: Thu Nov 28, 2024 3:54 am I haven't tried your CreationGuiPB code
I recorded a new video on YouTube, but I didn’t show the problematic parts.

In this case, I could manually move the layer. First, click on one element, then call the hotkey, then click on another element so that it moves on top of the second. When there is complete overlap, automatic movement is better, since it is impossible to hook an element if it turns out to be invisible. Or I could manually move the larger element to the bottom.