Forum > LCL
[solved--so far]Scrollbox -- why are controls not drawn in the order created?
indydev:
Maybe my description doesn't describe better what is happening. See the attached images. My panels are loading from a database and each panel needs to convert Markdown text (of varying complexity) into the appropriate display.
Your example works because you are adding one panel at a time (by a button), and your panels have nothing in them. My panels work fine in that situation as well.
Edit: I can see how my description could be misleading. When I load a session, I call into a database and grab the Markdown, a loop calls the CreateTxtDisplay procedure until all the messages from the session are loaded. Each panel has to add the converted Markdown Text (done prior to creating the Discussion Panel) into the Display. Thus the Panels can get pretty complicated.
wp:
A modified version of the demo in which random text is added to the panel along with an icon, and in which multiple panels can be added - panels are added in order.
VisualLab:
--- Quote from: indydev on July 17, 2024, 01:06:58 am ---I have a Lazarus client that interacts with several different AI models. Questions and Responses are placed on TPanels in a TScrollbox. Loading sessions that have more than 4 TPanels begin to be displayed out of order (different from how they are created and assigned to the scrollbox), though not always. The more TPanels the greater the chance of this "out of order" display. (See attachments: second one is the out of order display).
Is the drawing method for TScrollbox threaded? Is there a way for me to force the drawing order of the TPanels?
--- End quote ---
If there are a lot of these panels, the program will load RAM and CPU quite heavily (TPanel is a class derived from TWinControl, which is quite extensive). In the screenshot shown, you can see that each section contains a frame with text and a small simple raster graphic. Maybe a better solution would be to create a simple class derived from TCustomControl that would draw subsequent sections, one below the other. The difficult part would be writing the code to handle vertical scrolling of the content.
indydev:
Thank you for your example. After playing with your example, cutting out part of my code and inserting yours, here is what I found.
Without calculating the top of the panel the panels always display from the bottom to the top. I don't know why that is. It does not matter if I always set Top to 0 or to High(SmallInt), the panels display from the bottom up. If I use your example outside of my code, it displays top to bottom.
If I calculate the top (i.e. use DTop) and use your example code (cutting out my display calculations etc.) I get the result you see in your example.
But this tends to confirm my position that the calculations are taking too long, causing the drawing to happen out of order.
My previous posting of the code stripped out what I thought would be unnecessary. Here is the full code block in all of its ugliness:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---constructor TDiscussionPanel.Create(AOwner: TComponent; DText, KyWord: string; DTop, MLeft, MWidth, SgNum: Integer; CodeBlock, Q, Err: Boolean; const Pics: TBmpRecord);const border = 8;begin inherited Create(AOwner); Self.Parent := AOwner as TWinControl; Self.Align := alTop; Self.Top := DTop; //High(SmallInt); BevelOuter := bvNone; if Q then Color := TColor($00544644) else Color := TColor($00413534); ParentBackground := False; ParentColor := False; FIsQuestion := Q; FUsePics := Pics.Use; FPanelNum := Parent.ControlCount - 1; FSegNum := SgNum; case KyWord of 'EQ':begin BlockType := btEquation; CreateEquation; end; 'TABLE':begin BlockType := btTable; FisCodeBlock := FALSE; CreateTable(MLeft, MWidth, DText); end; 'StdTxt':begin BlockType := btText; CreateDialogue(MLeft, MWidth, DText); end; else begin BlockType := btCode; FCodeKeyword := KyWord; FIsCodeBlock := CodeBlock; CreateCodeBlock(MLeft, MWidth, Q, DText); end; end; FError := Err; // Create and configure the agent picture if UsePics then begin AssignPics(Pics); Self.OnPaint:=@PaintHandler; end else Self.OnPaint:=@PaintHandler2; Self.OnResize:=@Resize; Self.OnClick:=@SelfClick; Self.OnMouseMove:=@SelfMouseMove; Self.OnMouseDown:=@SelfMouseDown; Self.OnMouseUp:=@SelfMouseUp;end;
Each block calls another method constructor based on the content needed to be displayed (which includes a highly customized TRichMemo control). While it doesn't seem slow when I run it, there is a significant amount of processing going on.
At this point I don't expect anyone to 'Debug' my code, as it gets extensive. I believe I am stressing the display process. The problem I have does not always appear, but it appears more than 50% of the time, and it only appears upon loading the session messages into the ScrollBox. I will continue to work on it until I either solve it or have something more concrete to question.
Thanks to Martin_fr and wp for responding.
Edit: I posted before seeing your response VisualLab. Iterative coding is a death nail >:D Will consider your advice.
indydev:
--- Quote from: VisualLab on July 18, 2024, 12:02:18 am ---The difficult part would be writing the code to handle vertical scrolling of the content.
--- End quote ---
...yeah, need to figure out how that would be done?
Navigation
[0] Message Index
[#] Next page
[*] Previous page