Recent

Author Topic: TListBox or similar with TWO columns  (Read 3576 times)

robert rozee

  • Sr. Member
  • ****
  • Posts: 377
TListBox or similar with TWO columns
« on: April 22, 2020, 05:02:54 pm »
hi,
    i'm using lazarus 2.0.6 under linux. while i've been using delphi 5 for many years, this is my first foray into lazarus and writing applications for linux.

the problem: i want to display a short list of information consisting of pairs of data - each line being a device handle, followed by a driver name. i'm having a devil of a time trying to figure out how to do this nicely! the application i'm creating does not have ANY user input, it just sits there in the corner of the desktop quietly doing its thing. fyi, the purpose is to display the list of usable/live serial ports on a linux machine.

1. I started with a TMemo, but found that i couldn't change the tab width. now the data in the first column is of an inconvenient width (6-10 characters) such that the default tab width isn't usable.

2. next, i moved on to a TListBox. this looked hopeful, but then i discovered that while delphi supports setting a TabWidth value, lazarus does NOT.

3. then i tried a TStringGrid, but it rapidly got far too complex. what i'm wanting to do is pretty basic stuff, after all.

4. finally i moved on to a TValueListEditor, which can be massaged to almost do what i want... except i can't seem to get rid of, or hide, the dotted red focus box. there user will in no way interact with the control, and the dotted red box irks me. i have already set the GridLineWidth to zero to produce something that looks close to a simple TMemo.

without wanting to add custom components to lazarus, or use a sledge-hammer to put in what is really just a thumb-tack, can anyone suggest a SIMPLE solution? at the moment i'm leaning slightly towards a TMemo with a monospaced font, and just pack the columns with space characters!

btw: it would be really handy if the IDE could display a list of ALL the GUI widgets, or at least allowed you to somehow type in the name of a widget to find it. this would save having to slowly search through all the tabs every time you want to use something new - or is this already there?


cheers,
Rob   :-)
« Last Edit: April 22, 2020, 05:04:35 pm by robert rozee »

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: TListBox or similar with TWO columns
« Reply #1 on: April 22, 2020, 05:07:29 pm »
btw: it would be really handy if the IDE could display a list of ALL the GUI widgets, or at least allowed you to somehow type in the name of a widget to find it. this would save having to slowly search through all the tabs every time you want to use something new - or is this already there?
It's already present: View -> Components (default shortcut Ctrl+Alt+P).

zeljko

  • Hero Member
  • *****
  • Posts: 1951
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: TListBox or similar with TWO columns
« Reply #2 on: April 22, 2020, 05:11:03 pm »
hi,
    i'm using lazarus 2.0.6 under linux. while i've been using delphi 5 for many years, this is my first foray into lazarus and writing applications for linux.

the problem: i want to display a short list of information consisting of pairs of data - each line being a device handle, followed by a driver name. i'm having a devil of a time trying to figure out how to do this nicely! the application i'm creating does not have ANY user input, it just sits there in the corner of the desktop quietly doing its thing. fyi, the purpose is to display the list of usable/live serial ports on a linux machine.


Use TListView with Style = vsReport, add 2 columns and you're ready to go ... just add items.
Also, for such purpose you can use TTreeView, TVirtualStringTree also.

zeljko

robert rozee

  • Sr. Member
  • ****
  • Posts: 377
Re: TListBox or similar with TWO columns
« Reply #3 on: April 22, 2020, 05:36:44 pm »
howardpc: excellent, that is just what i am after!

zeljko: ok, i've placed the component and created two columns. looks good so far. i'm now stumbling on how to add the text strings, presumably a pair at a time. something like ListView1.Items.Add(), but how do i package up my two strings to pass to this?


cheers,
rob   :-)

wp

  • Hero Member
  • *****
  • Posts: 13556
Re: TListBox or similar with TWO columns
« Reply #4 on: April 22, 2020, 05:52:31 pm »
I'd use a TValuelistEditor, your application is just what it is made for. It has a boolean property "FocusRectVisible" which you can switch to false in order to hide the red dotted rectangle - note that this is a public property (not published) and therefore is not seen in the ObjectInspector (I wonder why it is not published...). To highlight the entire selected row you can turn on the Option goRowSelect (or goRowHightlight with a more decent color). Since you do not plan to edit cells you should also turn off goEditing. And when you turn off also goHorzLine, goVertLine, goFixedHorzLine and goFixedVertLine the ValueListEditor almost looks like a TListView. Additionally I turn on goThumbTracking to track the scrollbar immediately, not only when the mouse button is released.

lucamar

  • Hero Member
  • *****
  • Posts: 4217
Re: TListBox or similar with TWO columns
« Reply #5 on: April 22, 2020, 05:59:59 pm »
3. then i tried a TStringGrid, but it rapidly got far too complex. what i'm wanting to do is pretty basic stuff, after all.

I'm curious: what do you mean by "too complex"? I'd think a two-column string grid with  would be almost ideal for what you want: all you have to do is to add/update rows with whatever info you get at any moment.

You can even make a little effort and use a CSV-formated TStringStream (or any other in-memory stream) to hold/update the information and simply use TStringGrid.LoadFromCSVStream() to update the GUI.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: TListBox or similar with TWO columns
« Reply #6 on: April 22, 2020, 06:05:38 pm »
If you use a string grid, set it up with some variation on this:
Code: Pascal  [Select][+][-]
  1. const   DriverCount = 10;
  2.  
  3. procedure TForm1.FormCreate(Sender: TObject);
  4. var
  5.   r: Integer;
  6. begin
  7.   with DisplayGrid do begin
  8.     Options := [];
  9.     AutoEdit := False;
  10.     FixedCols := 0;
  11.     RowCount := DriverCount+1;
  12.     ColCount := 2;
  13.     FixedRows := 1;
  14.     FixedColor := clForm;
  15.     DefaultDrawing := False;
  16.     ScrollBars := ssNone;
  17.     DefaultColWidth := 100;
  18.     Width := 200;
  19.     Height := DefaultRowHeight * Succ(DriverCount) + 3;
  20.  
  21.     for r := 0 to DriverCount do
  22.       begin
  23.         case r of
  24.           0: begin
  25.                Cells[0, r] := 'Device handle';
  26.                Cells[1, r] := 'Device name';
  27.              end;
  28.           else
  29.             Cells[0, r] := Format('handle%d', [r]);
  30.             Cells[1, r] := Format('driver%d', [r]);
  31.         end;
  32.       end;
  33.   end;
  34. end;



robert rozee

  • Sr. Member
  • ****
  • Posts: 377
Re: TListBox or similar with TWO columns
« Reply #7 on: April 22, 2020, 06:16:47 pm »
TListView is looking like a passable solution, except i can't seem to shove the data into it! at the moment:

1. i can only add items to the first column in the forms designer,

2. and can only add items into the second column at runtime, using   ListView1.Items.Add.Subitems.Add('123456');

what is the incantation to add items to the first column at runtime?


cheers,
rob   :-)
« Last Edit: April 22, 2020, 06:18:43 pm by robert rozee »

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: TListBox or similar with TWO columns
« Reply #8 on: April 22, 2020, 06:47:47 pm »
Assuming your TListView named ListView is set up with 2 columns you want something along these lines:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2.  
  3.   procedure AddTwoColValues(aListView: TListView; const aCol1, aCol2: String);
  4.   var
  5.     c: TListItem;
  6.   begin
  7.     c := aListView.Items.Add;
  8.     c.Caption := aCol1;
  9.     c.SubItems.Add(aCol2);
  10.   end;
  11.  
  12. var
  13.   r: Integer;
  14. begin
  15.   for r := 1 to DriverCount do
  16.     AddTwoColValues(ListView, Format('handle%d', [r]), Format('driver%d', [r]));
  17. end;


lucamar

  • Hero Member
  • *****
  • Posts: 4217
Re: TListBox or similar with TWO columns
« Reply #9 on: April 22, 2020, 06:55:08 pm »
what is the incantation to add items to the first column at runtime?

IIRC, depending on how you want to build it you can use TListView.AddItem, TListView.Items.Add or TListView.Items.AddItem. For your use you'll most probably want to use TListView.Items.Add, since it returns a TListItem in which you can then call SubItems.Add.

ETA
Yeah, as Howard showed in his example :-[
« Last Edit: April 22, 2020, 06:58:48 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

robert rozee

  • Sr. Member
  • ****
  • Posts: 377
Re: TListBox or similar with TWO columns
« Reply #10 on: April 22, 2020, 07:41:36 pm »
howardpc's bit of code works a treat!

have worked out how to find the length of the list and delete items:
Code: Pascal  [Select][+][-]
  1. if ListView1.Items.Count>4 then ListView1.Items.Delete(0);

just one more question: how do i find the index of a given string, ie. search for 'abc' and return the index of the line that has exactly that string in column 1?


cheers,
rob   :-)

lucamar

  • Hero Member
  • *****
  • Posts: 4217
Re: TListBox or similar with TWO columns
« Reply #11 on: April 22, 2020, 08:19:54 pm »
just one more question: how do i find the index of a given string, ie. search for 'abc' and return the index of the line that has exactly that string in column 1?

[note: deleted wrong answer. I was looking to TListBox instead of TListView :-[ ]

OK, I've not tested it but I think you can use TListView.Items.FindCaption() for that.

« Last Edit: April 22, 2020, 08:29:16 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

robert rozee

  • Sr. Member
  • ****
  • Posts: 377
Re: TListBox or similar with TWO columns
« Reply #12 on: April 23, 2020, 05:11:15 am »
yep, managed to get FindCaption working:

Code: Pascal  [Select][+][-]
  1.  var  temp:TListItem;    
  2.  
  3. [...]
  4.  
  5. temp:=ListView1.Items.FindCaption(0,'ttyUSB0',false,true,false);
  6. if temp=nil then writeln('not found')
  7.             else writeln('index =',temp.Index);

many thanks to you all for your assistance, without it i'm pretty sure i'd have been stumped!


cheers,
rob   :-)

 

TinyPortal © 2005-2018