* * *

Author Topic: SizePriority question  (Read 1444 times)

xinyiman

  • Hero Member
  • *****
  • Posts: 1696
SizePriority question
« on: June 12, 2018, 11:33:26 am »
Hi guys, a question regarding the SizePriority of the TStringGrid. I can not make it work. He does not see any columns available. But I see the columns. Where am I wrong? The attached example goes into error because of the line

Grid.Columns.Items[1].Width:=100; 

Into formcreate procedure.
Ubuntu and Mac
Lazarus: 1.8.0
FPC: 3.0.4

wp

  • Hero Member
  • *****
  • Posts: 4836
Re: SizePriority question
« Reply #1 on: June 12, 2018, 03:01:40 pm »
He does not see any columns available. But I see the columns.
"He" is right although you see columns. The columns "he" is meaning are the columns that are added to the "Columns" collection of the grid. This can be done at designtime (double-click on the "Columns" property") or runtime (Grid.Columns.Add). You did not add "Columns" - so, there are no columns although you see them...

But you must be aware that "Columns" and normal usage of the grid are sometimes mutually excluding. While in the normal usage you can add columns by setting ColCount := something, you must add every single column individually in the "columns" mode. And columns are rather confusing when it comes to indexing: the first column which you add to a grid with 1 fixed column has index 0, but the cells in it are addressed by index 1! Therefore, I normally keep my hands off of "Columns", and I could guess that the merged_grid will have some issues when applied to a grid with "columns". "Columns" do have some nice features, though, like integrated non-standard cell editors, alignment, checkboxes, well - SizePriority, etc. - but these are things which cannot be created in a different way for the standard usage.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

xinyiman

  • Hero Member
  • *****
  • Posts: 1696
Re: SizePriority question
« Reply #2 on: June 12, 2018, 03:05:13 pm »
So I have to write a function of mine to resize? OK thank you very much
Ubuntu and Mac
Lazarus: 1.8.0
FPC: 3.0.4

xinyiman

  • Hero Member
  • *****
  • Posts: 1696
Re: SizePriority question
« Reply #3 on: June 13, 2018, 05:20:04 pm »
Hello wp, a curiosity. I am attaching an example. You will see that if I try to select a cell it takes a long time (2-3 sec.) To assign the focus. Can you explain why?
Ubuntu and Mac
Lazarus: 1.8.0
FPC: 3.0.4

wp

  • Hero Member
  • *****
  • Posts: 4836
Re: SizePriority question
« Reply #4 on: June 13, 2018, 07:22:50 pm »
Hmmm, not so bad for me on Win, the delay is hardly noticeable, absolutely not 2-3 sec. I increased the number of rows and columns to 250, and I noticed that you try to squeeze all columns into the grid width. Now the delay gets a bit longer, but still from being annoying - I would attribute it to the heavy painting load due to the large number of cells.

So, I don't know. How does a standard grid behave? If it is faster try to remove parts from the program (the merged cells, your rounded rectangles, etc) and see which changes makes it fast again.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

xinyiman

  • Hero Member
  • *****
  • Posts: 1696
Re: SizePriority question
« Reply #5 on: June 14, 2018, 03:16:59 pm »
Sorry to bother you, but even now you find it slow? Now also adapt the height of the row
Ubuntu and Mac
Lazarus: 1.8.0
FPC: 3.0.4

wp

  • Hero Member
  • *****
  • Posts: 4836
Re: SizePriority question
« Reply #6 on: June 14, 2018, 03:51:20 pm »
Not super-fast, but certainly not "slow".

I added time-measuring calls to TMcStringGrid.DrawAll (see below) and this tells me that a full repaint takes about 0.3 sec, and that corresponds to the felt delay between click and movement of the cell focusrect.

If I exit your own DrawCell code immediately after its call to inherited the displayed time goes down to 0.11 sec.

If I unassign my own OnDrawCellText and OnMergeCells event handlers (the latter one, of course, does the cell merging...) then the time goes down to 0.09 sec.

Cell merging certainly can be optimized in speed, but it is clear that the main speed killer is you own DrawCell routine. I don't want to investigate this in detail, but you are painting all cells twice: by the inherited call and, because of the "if 1=1", by your own code.

Code: Pascal  [Select]
  1. procedure TMCStringGrid.DrawAllRows;
  2. var
  3.   L, T, R, B: Integer;
  4.   rct: TRect;
  5.   t0: TdateTime;
  6. begin
  7.   t0 := now;   // <--- NEW
  8.   inherited;
  9.   if FocusRectVisible and IsMerged(Col, Row, L, T, R, B) then begin
  10.     rct.TopLeft := CellRect(L, T).TopLeft;
  11.     rct.BottomRight := CellRect(R, B).BottomRight;
  12.     DrawFocusRect(L, T, rct);
  13.   end;
  14.   t0 := now-t0;   // <--- NEW
  15.   Application.Mainform.Caption := FormatDateTime('s.zzz" sec"', t0);   // <--- NEW
  16. end;
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

xinyiman

  • Hero Member
  • *****
  • Posts: 1696
Re: SizePriority question
« Reply #7 on: June 14, 2018, 04:10:17 pm »
Hello, I did not understand why I draw the cells twice and how to do it once.
Ubuntu and Mac
Lazarus: 1.8.0
FPC: 3.0.4

wp

  • Hero Member
  • *****
  • Posts: 4836
Re: SizePriority question
« Reply #8 on: June 14, 2018, 06:07:04 pm »
In your DrawCell method of TMcStringGrid put an "exit" after the line "inherited" and run your demo --> you will see a grid - the first drawing action.

Then remove the "exit" and comment the "inherited" - this will execute only your code. But you'll see a grid again.

So, in total the grid is painted twice, by "inherited" and by your code.

I recommend that you place a breakpoint in DrawAllRows of TCustomGrid, then step through the entire code to see which methods are called - that's how I learned it.

This is the sequence of methods being called.
  • DrawAllRows (called from Paint)
  • DrawRow
  • DrawCell
  • DefaultDrawCell
  • DrawFillRect, DrawColumnCell, DrawTextInCell.
  • DrawTextIncell calls DrawCellText which finally paints the text in the cell
You override DrawCell which is very early in the sequence of calls. Your first call is "inherited" - this means your grid does the same as any other standard string grid, i.e. it calls all these methods mentioned.

After the "inherited" you have a boolean condition "if 1=1" - this is always true, and therefore you execute all the steps following. And these steps essentially do: Fill the cell rect (this is what DrawFillRect above is doing), paint a rounded rect over it, and finally paint the text.

In the end, the "if 1=1" part paints the cell a second time.

I don't know what you want to achieve. I suppose you want every cell to have round corners. The correct way to achieve this would be to override the method DrawFillRect. Unfortunately this method is not virtual and thus is not called from an inherited grid. You can turn off the property DefaultDrawing and hook your own code (the one after "if 1=1") into the OnDrawCell event hander - having DefaultDrawing = false means that the sequence of methods after DefaultDrawCell is not executed any more. But I think the merged cells will not work any more  (not 100% sure - I did not try it).

The other possibility, since TMcStringGrid is a derived grid anyway, is to copy the code from DefaultDrawCell into the mcGrids units. There must be some corrections because the original method calls other routines not accessible here. Then you can add the DrawRoundRect after the DrawfillRect:

Code: Pascal  [Select]
  1. procedure TMCStringGrid.DefaultDrawCell(aCol, aRow: Integer; var aRect: TRect;
  2.   aState: TGridDrawState);
  3. begin
  4.   if goColSpanning in Options then CalcCellExtent(acol, arow, aRect);
  5.  
  6.   if (TitleStyle=tsNative) and (gdFixed in AState) then
  7.     DrawThemedCell(aCol, aRow, aRect, aState)
  8.   else
  9.     DrawFillRect(Canvas, aRect);
  10.  
  11.   Canvas.RoundRect(ARect, 11, 11);
  12.  
  13.   if (goFixedRowNumbering in Options) and (ARow>=FixedRows) and (aCol=0) and (FixedCols>0) then
  14.     DrawCellAutonumbering(aCol, aRow, aRect, IntToStr(aRow-FixedRows+1));
  15.  
  16.   //draw text
  17.   if GetIsCellTitle(aCol, aRow) then
  18.     DrawColumnText(aCol, aRow, aRect, aState)
  19.   else
  20.     DrawTextInCell(aCol,aRow, aRect,aState);
  21. end;

With this modification and removing your DrawCell method I get a speedup of the painting time from 0.3 sec to 0.11-0.12 sec

Note that I dropped some internal features of the usual grid here, like checkbox drawing or button cells.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

xinyiman

  • Hero Member
  • *****
  • Posts: 1696
Re: SizePriority question
« Reply #9 on: June 15, 2018, 12:18:23 pm »
I think I understand the problem thanks to you. I thought that when the cell was selected by clicking the mouse to draw the successful selection, it would redraw the cells. Instead it seems not to be this way. The selection seems to me to be slow. You know why the selection is slow? And on which event should you go to work?

EDIT: I analyzed the situation a little more. Slowness occurs between the MouseDown event and the MouseUp event. I can not understand what in the middle can slow down if the cells are resized. If instead I leave the default size of the cells there is no slowness
« Last Edit: June 15, 2018, 02:19:15 pm by xinyiman »
Ubuntu and Mac
Lazarus: 1.8.0
FPC: 3.0.4

xinyiman

  • Hero Member
  • *****
  • Posts: 1696
Re: SizePriority question
« Reply #10 on: June 16, 2018, 10:09:17 am »
I tried to compile on windows and run them fast. The problem seems to be on mac. Does anyone know why? Moreover wp with your advice has stopped working the text, now it is in the next cells. See for example the cell containing the text "vertical text"
Ubuntu and Mac
Lazarus: 1.8.0
FPC: 3.0.4

xinyiman

  • Hero Member
  • *****
  • Posts: 1696
Re: SizePriority question
« Reply #11 on: June 18, 2018, 04:06:36 pm »
Nobody has managed to understand where it slows down and how to solve?
Ubuntu and Mac
Lazarus: 1.8.0
FPC: 3.0.4

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus