Page 1 of 1

[EXPLAINED] ScrollAreaGadget & #PB_ScrollArea_InnerHeight

Posted: Tue Jan 30, 2024 9:07 pm
by boddhi
Hi there,

I'm confronted with a problem that I can't solve despite several approaches.

I'm creating an application whose purpose is to create a list of fonts in the Windows Fonts system folder or any other folder, and to display a preview of each of them in a ScrollAreaGadget. To do this, I create an image for each font with its graphic representation, which I display progressively in the ScrollAreaGadget using an ImageGadget placed just below the previous one.

My problem is that at a certain point the ordinate value used to position the ImageGadget seems to freeze, as illustrated in the image below
Image

Of course, I've checked the type of variables used, which is Long, which is sufficient in terms of value range.
Here's a snippet of the code, immediately at the end of the processing loop, which allows me to check this:

Code: Select all

          Debug "PositionY finale : "+DonneesGadget\PositionY
          Debug "PositionY finale à l'échelle : "+Str(DonneesGadget\PositionY/FacteurEchelleY)
          ; Méthode 1
          ;SetGadgetAttribute(#GAD_FP_ZD_GALERIE,#PB_ScrollArea_InnerHeight,DonneesGadget\PositionY/FacteurEchelleY)
          ; Méthode 2
          Protected.l ValeurX=DonneesGadget\PositionY/FacteurEchelleY
          SetGadgetAttribute(#GAD_FP_ZD_GALERIE,#PB_ScrollArea_InnerHeight,ValeurX)
          ;
          Debug "Hauteur finale innerheight : "+GetGadgetAttribute(#GAD_FP_ZD_GALERIE,#PB_ScrollArea_InnerHeight)
And now, part of the result of the incremental progression and the final data value:
Image

We can see that the final value of the variable used to determine the internal height required for total display (which will be used for #PB_ScrollArea_InnerHeight), here calculated at 63710 and 50968 with DPI scaling, is consistent.
However, after assigning this value via SetGadgetAttribute(), when I retrieve it via GetGadgetAttribute(), it doesn't match at all.
This phenomenon doesn't occur for a smaller number of ImageGadget().

However, I've done other tests where, for example, I create a ScrollAreaGadget with an internal height of 100,000 pixels, no problem, another with more than 3,000 ImageGadgets, no problem either, hence my total lack of understanding of the behaviors and results described above.
 
 
On the French forum, another method (via CanvasGadget()) was submitted to me:

Code: Select all

; Win OS - Workaround sample for removing the 32k size Limit on the ScrollAreaGadget - First testversion d19 m07 y2017
; Author Werner Albus - www.nachtoptik.de - www.quick-aes-256.de

#ImageHeight=200 ; Change you the height, you must change also the pre defined offset, it's simple
#AmountCanvas=4000
Global Dim y_pos_canvas(#AmountCanvas)

Procedure BindScrollDatas()
	yy=-(#ImageHeight+10)
	offset.f=0.0070042*#AmountCanvas ; Pre defined offset for max 9000 canvas, changeable
	min=#AmountCanvas*(#ImageHeight+10)
	If min<=GadgetHeight(0)
		DisableGadget(0, 1)
	Else
		short_loop_1:
		If y_pos_canvas(#AmountCanvas)-GetGadgetAttribute(0, #PB_ScrollArea_Y)*offset<GadgetHeight(0)-10 And min>GadgetHeight(0)
			offset-0.00001
				Goto short_loop_1
		EndIf
		For a=1 To #AmountCanvas
			yy+(#ImageHeight+10)
			scroll_offset.f=GetGadgetAttribute(0, #PB_ScrollArea_Y)*offset
			If y_pos_canvas(a)-(#ImageHeight+10)-scroll_offset<GadgetHeight(0) And  y_pos_canvas(a)-(#ImageHeight+10)-scroll_offset>-(#ImageHeight+10)
				HideGadget(5+a, 0)
				ResizeGadget(5+a, #PB_Ignore, yy-scroll_offset+10, #PB_Ignore, #PB_Ignore)
			Else
				HideGadget(5+a, 1)
			EndIf
		Next
		DisableGadget(0, 0)
	EndIf 
EndProcedure

If OpenWindow(0, 0, 0, 363, 700, "ScrollAreaGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	ScrollAreaGadget(0, 331, 10, 21, 680, 0, 0, 1500/#AmountCanvas+1, #PB_Container_Single)
	CloseGadgetList()
	ContainerGadget(#PB_Any, 10, 10, 325, GadgetHeight(0), #PB_Container_Double)
	y=10 
	For a=1 To #AmountCanvas
		CreateImage(1, Random(300, 100), #ImageHeight)
		drawX=ImageWidth(1)
		If StartDrawing(ImageOutput(1))
			drawY=0
			For x=0 To drawX Step 10
				RoundBox(x, drawY, drawX-2*x, #ImageHeight-2*drawY, 20, 20, RGB(Random(255), Random(255), Random(255)))
				drawY+10 
			Next x
			DrawText(10, 10, "Image "+Str(a))
			StopDrawing() 
		EndIf
		CanvasGadget(5+a, 10+(300-drawX)/2, y, drawX, #ImageHeight)  : y+#ImageHeight+10
		y_pos_canvas(a)=y
		SetGadgetAttribute(5+a, #PB_Canvas_Image, ImageID(1))
		While WindowEvent() : Wend
	Next
	SetGadgetAttribute(0, #PB_ScrollArea_InnerHeight, 30759-100000/#AmountCanvas)
	BindGadgetEvent(0, @BindScrollDatas())
	Repeat
		Select WaitWindowEvent()
			Case  #PB_Event_CloseWindow
				End
			Case  #PB_Event_Gadget
				Select EventGadget()
				EndSelect
		EndSelect
	ForEver
EndIf
The result is more or less the same:
Image
 
• at the lowest scroll, not all CanvasGadgets are displayed, here 3410 instead of 4000
• AND, as in my code, the final value returned by #PB_ScrollArea_InnerHeight is " locked " at 26214! 8O

Is this a bug, a limitation, a wrong setting of some kind? 🤔 😕
 

Re: ScrollAreaGadget & #PB_ScrollArea_InnerHeight

Posted: Wed Jan 31, 2024 12:18 am
by ChrisR
In the ScrollArea help, it is written that the dimensions of the scrollable area inside the gadget (MS Windows only: These are limited To 32 000 pixels)
That's not quite right, it is limited to 2 octets, 32767 pixels

Try this, you'll get an error message at compile time: [ERROR] Maximum supported gadget height is 32767 pixels

Code: Select all

If OpenWindow(0, 0, 0, 300, 400, "Title", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ScrollAreaGadget(0, 0, 0, 300, 400, 273, 32768, 10, #PB_ScrollArea_Raised)
  CloseGadgetList()
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
And now try this one:

Code: Select all

If OpenWindow(0, 0, 0, 300, 400, "Title", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ScrollAreaGadget(0, 0, 0, 300, 400, 273, 32767, 10, #PB_ScrollArea_Raised)
  CloseGadgetList()
  SetGadgetAttribute(0, #PB_ScrollArea_InnerHeight, 40000)
  Debug GetGadgetAttribute(0, #PB_ScrollArea_InnerHeight) 
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Without the DPIaware compiler flag, you'll get 32767
With the DPIaware compiler flag and your scale factor of 1.25, you'll get 26214 (26214 * 1.25 = 32768.5 and DesktopScaledX(26214) = 32768)

Re: ScrollAreaGadget & #PB_ScrollArea_InnerHeight

Posted: Wed Jan 31, 2024 9:40 am
by boddhi
Salut Chris,
ChrisR wrote: In the ScrollArea help, it is written that the dimensions of the scrollable area inside the gadget (MS Windows only: These are limited To 32 000 pixels)
Le diable se cache souvent dans les petites lignes :oops: :D :wink:
The evil often hides behind small lines.