Lazarus

Programming => Widgetset => Cocoa => Topic started by: VTwin on September 18, 2019, 03:50:24 am

Title: TDrawGrid/TStringGrid character entry
Post by: VTwin on September 18, 2019, 03:50:24 am
When entering data into a TDrawGrid cell, the first keystroke enters the character, but also selects it. The second keystroke therefore deletes the first character.

This did not happen in Carbon.

I will try to write a simple example showing this behavior, but would like to know if others have observed this.
Title: Re: TDrawGrid character entry
Post by: VTwin on September 18, 2019, 04:04:11 pm
It happens in a stringgrid as well. Try to enter data in cells.

Title: Re: TDrawGrid character entry
Post by: VTwin on September 20, 2019, 03:25:04 am
I have no option but to release software with this bug. If anyone can provide a patch I would be very grateful.
Title: Re: TDrawGrid character entry
Post by: VTwin on September 27, 2019, 03:49:04 pm
Can anyone verify this bug?

I can file a bug report, but would appreciate confirmation first.
Title: Re: TDrawGrid character entry
Post by: VTwin on September 28, 2019, 04:12:23 pm
Reported.
Title: Re: TDrawGrid character entry
Post by: VTwin on October 24, 2019, 10:46:52 pm
Here is the report:

https://bugs.freepascal.org/view.php?id=36111

It is an extremely annoying bug if you are using TStringGrid or TDrawGrid for data entry.
Title: Re: TDrawGrid/TStringGrid character entry
Post by: winni on October 25, 2019, 12:25:27 am
Hi!

You call from a TStringGrid the TStringCellEditor.
Inherited from TCustomEdit from TWinControl

So you got OnKeyDown/OnKeyUp/OnKeypress which should notice every char.

And there is a property SelLength.

So set the SelLength := 0 on every key event. That is the length of the selection.
If I havnt overlooked something very tricky this should work.

Winni

Title: Re: TDrawGrid/TStringGrid character entry
Post by: VTwin on October 27, 2019, 07:26:52 pm
Thanks Winni!

The following code:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: char);
  2. var
  3.   ed: TStringCellEditor;
  4. begin
  5.   {$IFDEF DARWIN}
  6.   if StringGrid1.Editor is TStringCellEditor then begin
  7.     ed := TStringCellEditor(StringGrid1.Editor);
  8.     if Length(ed.EditText) = 1 then begin
  9.       ed.SelStart := 1;
  10.       ed.SelLength := 0;
  11.     end;
  12.   end;
  13.   {$ENDIF}
  14. end;

seems to be a workaround for a StringGrid. However, OnEditingDone is incorrectly called for the first key press, which has broken the code for my DrawGrid. OnEditingDone is not called for subsequent key presses, until the editing is actually done (e.g., by pressing Enter).

Title: Re: TDrawGrid/TStringGrid character entry
Post by: VTwin on October 30, 2019, 05:58:39 pm
A better kludge:

Code: Pascal  [Select][+][-]
  1. procedure TDataForm.grdDataKeyDown(Sender: TObject; var Key: Word;
  2.   Shift: TShiftState);
  3. var
  4.   ed: TStringCellEditor;
  5. begin
  6.   {$IFDEF DARWIN}
  7.   if Key in [VK_RETURN, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN{, VK_TAB}] then begin // done
  8.     grdData.OnEditingDone := fOnEditingDone;
  9.   end else begin // not done
  10.     grdData.OnEditingDone := nil;
  11.     if grdData.Editor is TStringCellEditor then begin
  12.       ed := TStringCellEditor(grdData.Editor);
  13.       if Length(ed.EditText) = 1 then begin
  14.         ed.SelStart := 1;
  15.         ed.SelLength := 0;
  16.       end;
  17.     end;
  18.   end;
  19.   {$ENDIF}
  20. end;  

This prevents OnEditingDone from firing until editing is actually done, so works with a TDrawGrid.

A separate question is, how to make VK_TAB act like VK_RIGHT, and call OnEditingDone as is common in a spreadsheet. I can't seem to make that work.
Title: Re: TDrawGrid/TStringGrid character entry
Post by: winni on October 30, 2019, 06:25:17 pm
Hi!

A separate question is, how to make VK_TAB act like VK_RIGHT

You have to disable TabStop  in the object inspector!!!

Then onKeyDown/Up:

Code: Pascal  [Select][+][-]
  1. if key = VK_Tab then key := VK_Right
  2.  

Winni
Title: Re: TDrawGrid/TStringGrid character entry
Post by: Soner on October 30, 2019, 06:43:01 pm
Hi!

A separate question is, how to make VK_TAB act like VK_RIGHT

You have to disable TabStop  in the object inspector!!!

Then onKeyDown/Up:

Code: Pascal  [Select][+][-]
  1. if key = VK_Tab then key := VK_Right
  2.  

Winni
There is better way in TStringGrid for this.
Add goTAbs to TStringGrid.Options then you can control with TStringGrid.TabAdvance how do you want it.
Title: Re: TDrawGrid/TStringGrid character entry
Post by: VTwin on October 30, 2019, 08:46:38 pm
Thanks.

I had already tried all of these suggestions:

TabStop disabled.

Code: Pascal  [Select][+][-]
  1. if key = VK_Tab then key := VK_Right
set in KeyUp/KeyDown

TabAdvance aaRight

It does not work in Mac, Win, or Lin. I have attached a project, perhaps you can point out the problem?

Title: Re: TDrawGrid/TStringGrid character entry
Post by: VTwin on October 30, 2019, 09:11:58 pm
I also tried goTabs = true.

Once in the StringCellEditor, only the arrow and enter keys trigger EditDone, and leave the editor. As far as I can tell, the above suggestions apply to the Grid, not the StringCellEditor.
Title: Re: TDrawGrid/TStringGrid character entry
Post by: VTwin on October 31, 2019, 07:22:49 pm
The trick to using tab seems to be to create a simple descendant of TStringCellEditor:

Code: Pascal  [Select][+][-]
  1. TTabStringCellEditor = class(TStringCellEditor)
  2. protected
  3.   procedure KeyDown(var Key : Word; Shift : TShiftState); override;
  4. end;
  5.  
  6. procedure TTabStringCellEditor.KeyDown(var Key : Word; Shift : TShiftState);
  7. begin
  8.   if Key = VK_TAB then
  9.     Key := VK_RIGHT;
  10.   inherited;
  11. end;

The attached project gives a workaround for the cocoa bug, and implements tab editing done. Tested on Mac, Win, and Lin for StringGrid and DrawGrid.

EDIT: Enable TabStop to set focus on Grid, so a mouse click is not required.
Title: Re: TDrawGrid/TStringGrid character entry
Post by: VTwin on July 14, 2020, 02:06:12 am
Bump.

This continues to be a problem for entering data into StringGrid and DrawGrid.

Can I get any confirmations?
Title: Re: TDrawGrid/TStringGrid character entry
Post by: trev on July 14, 2020, 03:15:42 am
I downloaded your demo from https://forum.lazarus.freepascal.org/index.php/topic,46787.msg334041.html#msg334041

The problem seems to be worse now with Lazarus & FPC trunks (see signature).

Whichever cell I choose to edit, the first character is focussed, entering a character deletes it. So far this agrees with your issue.

But now I cannot edit any other cell. If I click on another cell, the cell outline is highlighted, but anything I enter turns up in the first cell I edited! It seems that the focus remains stuck on the first cell I edited.
Title: Re: TDrawGrid/TStringGrid character entry
Post by: VTwin on July 14, 2020, 03:32:43 am
Thanks so much trev. This has been making me crazy.

I thought I had a work around, but now I'm jammed in another application.
Title: Re: TDrawGrid/TStringGrid character entry
Post by: VTwin on July 14, 2020, 11:19:08 pm
The bug report I filed was closed and reopened. Dmitry is working on it.

Perhaps it would be useful for you to add a note on this new behavior? 
Title: Re: TDrawGrid/TStringGrid character entry
Post by: trev on July 15, 2020, 11:51:16 am
Bug report updated.
Title: Re: TDrawGrid/TStringGrid character entry
Post by: bigeno on July 15, 2020, 03:49:23 pm
Thats rev 63541 bug.
Title: Re: TDrawGrid/TStringGrid character entry
Post by: VTwin on January 22, 2022, 11:06:07 pm
Bump

This is a serious bug for anyone using a StringGrid or DrawGrid. It has not been resolved as of Lazarus 2.2.0. Does anyone have a fix or workaround?
TinyPortal © 2005-2018