Recent

Author Topic: How to make TListView selection visible?  (Read 538 times)

BosseB

  • New Member
  • *
  • Posts: 34
How to make TListView selection visible?
« on: August 19, 2019, 08:56:04 pm »
Lazarus 2.0.4 on Windows 7.
TListView on a small form.
Created 4 columns in Lazarus editor
ViewStyle = vsReport
Rowselect = true
Gridlines = true
Everything else are default settings.

I can fill the listview with data from a dynamic array of records and if I click on a line it is selected and marked with a darker color.

My aim is to use this as an editor for records where I want to change the order of the items and delete some items. So I have buttons for these actions.
The button procedures work fine for my actions but:

Problem:
When I hit a button the visible marking of the selected line in the listview disappears (it returns to the default color).
After the button action is done and the listview is re-populated with data I set the ItemIndex property in code to the index of the line I want to select but selection is not visible.
Only if I click the mouse on a non-active part of the listview does the selected line show up with the proper color marking.

How can I make the visibility of the selection of the line in the listview persistent?

I do not recall ever having this problem when coding in Delphi...
« Last Edit: August 19, 2019, 08:59:41 pm by BosseB »
--
Bo Berglund
Sweden

wp

  • Hero Member
  • *****
  • Posts: 6136
Re: How to make TListView selection visible?
« Reply #1 on: August 19, 2019, 10:05:10 pm »
TListView and TTreeView have a property HideSelection which stupidly defaults to true. This means that when the ListView loses focus, e.g. because you click on a button, the selected item is no longer highlighted. But when you set HideSelection to false it remains highlighted all the time.

Quote
I do not recall ever having this problem when coding in Delphi...
It is the same behavior as in Delphi 7. Recent versions, however, keep the selected item highlighted even when the ListView has lost focus. This makes the property HideSelection which still exists kind of useless...

Quote
[...] selection of the line in the listview[...]?
If you want to see the entire line highlighted (not just the item in the first column) you must set "RowSelect" to true.
« Last Edit: August 19, 2019, 11:55:12 pm by wp »
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

ASerge

  • Hero Member
  • *****
  • Posts: 1388
Re: How to make TListView selection visible?
« Reply #2 on: August 19, 2019, 10:07:08 pm »
Created 4 columns in Lazarus editor
ViewStyle = vsReport
Rowselect = true
Gridlines = true
Everything else are default settings.
...
Only if I click the mouse on a non-active part of the listview does the selected line show up with the proper color marking.
What about property HideSelection?

jamie

  • Hero Member
  • *****
  • Posts: 1894
Re: How to make TListView selection visible?
« Reply #3 on: August 19, 2019, 11:25:11 pm »
OwnerDraw usually solves these problems...

Make it what ever you want.

BosseB

  • New Member
  • *
  • Posts: 34
Re: How to make TListView selection visible?
« Reply #4 on: August 20, 2019, 08:25:03 am »
I ended up adding the code below after reading this article.



Code: Pascal  [Select]
  1. procedure TfrmEditCuts.lvCutListCustomDrawItem(Sender:
  2. TCustomListView;
  3.   Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
  4. const
  5.   cStripe = $FF9933;  // colour of selected list items
  6. begin
  7.   if Item.Index = lvCutList.ItemIndex then
  8.   begin
  9.     lvCutList.Canvas.Brush.Color := cStripe;
  10.     lvCutList.Canvas.Font.Color := clWhite;
  11.   end
  12.   else
  13.     lvCutList.Canvas.Brush.Color := clWindow;
  14. end;

This made the selected row stay colored even though the listview lost
focus when I clicked the buttons.

I had to probe the selection color in my paint program to set the
cStripe value to the same because when clicking on an item the
CustomDrawItem event seems not to be called. So on initial click the
row was colored blue and when I used my buttons to move the row it was
colored in the cStripe value that I originally used (light green).
Changing the cStripe value to the color of initial selection made the
row move without visible color change....

PS: I had no knowledge of the property HideSelection, but when I saw mention of it I tested it and it did not work well to set it to false.
Other issues popped up like losing the selection if returning to the listview.
And the selection changed color when I clicked elsewhere.
The code above works, but I cannot use any other color than the one the selection defaults to, since I don't know where to change that. Initial selection is always blue...
DS
--
Bo Berglund
Sweden

BosseB

  • New Member
  • *
  • Posts: 34
Re: How to make TListView selection visible?
« Reply #5 on: August 20, 2019, 08:42:29 am »
BTW: Is the TListView portable, i.e. is it Windows only or does it have siblings on Linux too?
--
Bo Berglund
Sweden

wp

  • Hero Member
  • *****
  • Posts: 6136
Re: How to make TListView selection visible?
« Reply #6 on: August 20, 2019, 10:16:24 am »
TListView is portable like all LCL controls. But, as usual, be prepared to expect differences in the sequence of effects, or sometimes there are restrictions on certain widgetset-controlled properties.

I don't know what you are doing that HideSelection is not working - the attached demo shows that it does. Tested on Win10 and Win 7 and Lubuntu/gtk2.

Depending on the widgetset and theme, the color of the selection may change when the focus is moved away from the ListView; this is intended to give a visual feedback that the ListView is not focused any more. The normal color is given by the values of clHighlight and clHighlightText which are system colors determined by the theme setting, the non-focused color probably has no entry in the list of predefined colors.

Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

lucamar

  • Hero Member
  • *****
  • Posts: 1982
Re: How to make TListView selection visible?
« Reply #7 on: August 20, 2019, 03:02:31 pm »
The code above works, but I cannot use any other color than the one the selection defaults to, since I don't know where to change that. Initial selection is always blue...

The colors are set by the Window Manager theme; should correspond to clHighlight for the background and clHighlightText for the font, IIRC.

ETA: Oops. Yeah, what wp said  :-[
« Last Edit: August 20, 2019, 03:05:38 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

BosseB

  • New Member
  • *
  • Posts: 34
Re: How to make TListView selection visible?
« Reply #8 on: August 20, 2019, 03:36:05 pm »
I don't know what you are doing that HideSelection is not working - the attached demo shows that it does. Tested on Win10 and Win 7 and Lubuntu/gtk2.
By not working I meant that the selected line changed color from dark blue into some light gray when I moved to the button. Previously it changed to not show at all.
But I want the selected row to remain as is irrespective of if I click a button...
Quote
Depending on the widgetset and theme, the color of the selection may change when the focus is moved away from the ListView; this is intended to give a visual feedback that the ListView is not focused any more. The normal color is given by the values of clHighlight and clHighlightText which are system colors determined by the theme setting, the non-focused color probably has no entry in the list of predefined colors.
OK so I could use these color names instead of the hex RGB to make the highlight follow the theme.
Seems to work in a quick test.
--
Bo Berglund
Sweden

lucamar

  • Hero Member
  • *****
  • Posts: 1982
Re: How to make TListView selection visible?
« Reply #9 on: August 20, 2019, 04:27:14 pm »
By not working I meant that the selected line changed color from dark blue into some light gray when I moved to the button. Previously it changed to not show at all.
But I want the selected row to remain as is irrespective of if I click a button...

Most, if not all, systems I've ever seen hide the selection or change its color to signal the change of focus to the user and that can not be changed unless you use custom drawing.

A "trick" I use sometimes (and only if absolutely needed) to do what you want is to change the focus back to the list box (or whatever control) in the button's OnClick handler. There will be some barely noticeable "flash" which, depending on your p.o.v., can be good or annoying :)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

wp

  • Hero Member
  • *****
  • Posts: 6136
Re: How to make TListView selection visible?
« Reply #10 on: August 20, 2019, 04:45:06 pm »
Yes, I think controls which do not signal focus change by a change of background color are irritating. Unfortunately the LCL has some of them: TStringGrid (when option goDrawFocusSelected is set), TListbox, TCheckListbox, TColorListbox (the faint red dotted focus rectangle sometimes is hard to see).
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

BosseB

  • New Member
  • *
  • Posts: 34
Re: How to make TListView selection visible?
« Reply #11 on: August 20, 2019, 04:49:46 pm »
Quote
A "trick" I use sometimes (and only if absolutely needed) to do what you want is to change the focus back to the list box (or whatever control) in the button's OnClick handler. There will be some barely noticeable "flash" which, depending on your p.o.v., can be good or annoying
Yes, I thought about that as well, but I did not test it.
One complication is that I am clearing and repopulating the listview after each button click so the old selection is no longer present, I have to set itemindex in code.
Since the customdrawitem seemingly makes it work as I intended I think I am good now.

My next step is to port the project over to Lazarus 2.0.4 on Raspbian (Debian derivative).
It turns out that even though the project builds fine also on Linux, the form design is screwed up because a different font size is used. I did not set the font size on Windows but Lazarus used some default value (9). But on Linux it switched to using size 10 and it causes carefully aligned controls to grow in size and overlap. Bad.
But it is another topic in need of a thread of its own....
« Last Edit: August 20, 2019, 11:58:54 pm by BosseB »
--
Bo Berglund
Sweden

BosseB

  • New Member
  • *
  • Posts: 34
Re: How to make TListView selection visible?
« Reply #12 on: August 22, 2019, 12:42:30 pm »
My next step is to port the project over to Lazarus 2.0.4 on Raspbian (Debian derivative).
It turns out that even though the project builds fine also on Linux, the form design is screwed up because a different font size is used. I did not set the font size on Windows but Lazarus used some default value (9). But on Linux it switched to using size 10 and it causes carefully aligned controls to grow in size and overlap. Bad.
But it is another topic in need of a thread of its own....
I ended up setting the font.size property for all affected controls in the form.Show event.
This fixed the size difference between Lazarus on Windows and Raspbian.
--
Bo Berglund
Sweden

lucamar

  • Hero Member
  • *****
  • Posts: 1982
Re: How to make TListView selection visible?
« Reply #13 on: August 22, 2019, 04:19:42 pm »
That problem is probably caused by theme differences. This wiki pages (and related ones) may be useful for you: Autosize/Layout
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.