View Issue Details

IDProjectCategoryView StatusLast Update
0027509PatchesPatchpublic2015-02-22 18:30
Reportertheo Assigned ToZeljan Rikalo  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version1.3 (SVN) 
Summary0027509: TCustomListView.ShowEditor: Placement of editor does not take Icons into account.
DescriptionTCustomListView.ShowEditor: Placement of editor does not take Icons into account on all interfaces.

Attached patch fixes this as far as possible.
Please read comment in code.
TagsNo tags attached.
Fixed in Revision47941,47942,47944
LazTarget-
Widgetset
Attached Files

Activities

theo

2015-02-20 18:34

reporter  

clvedpos.diff (1,130 bytes)   
Index: lcl/include/customlistview.inc
===================================================================
--- lcl/include/customlistview.inc	(Revision 47919)
+++ lcl/include/customlistview.inc	(Arbeitskopie)
@@ -431,7 +431,7 @@
 var
   Item: TListItem;
   R: TRect;
-  TempHeight: Integer;
+  TempHeight, IconWidth: Integer;
   S: String;
 begin
   if (ItemIndex >= 0) and (ItemIndex < Items.Count) then
@@ -445,6 +445,17 @@
     exit;
 
   R := Item.DisplayRect(drBounds);
+
+  if (ViewStyle>vsSmallIcon) and (Assigned(SmallImages) or Assigned(StateImages)) then
+  begin
+    IconWidth:=Item.DisplayRect(drIcon).Right;
+    {Following code is for Interfaces where drIcon is not working.
+    Still important to try drIcon first, because under Win32 it reports SmallImage PLUS StateImage width.
+    GTK2 and Qt do not show Stateimage separately but GTK2 reports correct width of SmallImage while Qt reports 0}
+    if (Assigned(SmallImages) and (IconWidth=0)) then IconWidth:=SmallImages.Width;
+    R:=Rect(R.Left+IconWidth,R.Top,R.Right,R.Bottom);
+  end;
+
   if LCLIntf.IsRectEmpty(R) then
     exit;
   S := Item.Caption;

clvedpos.diff (1,130 bytes)   

Zeljan Rikalo

2015-02-20 19:02

developer   ~0081287

Better fix Qt than use workarounds in LCL.

Zeljan Rikalo

2015-02-20 19:03

developer   ~0081288

Think that qt does not return iconsize if icon isn't assigned.

theo

2015-02-20 19:42

reporter   ~0081289

Not sure if I understand you.
I think it's not a workaround but a safety measure. ;-)
I can't test on carbon etc. So it if we don't get any data, we have a fallback value.
If you can fix Qt, all the better.

Zeljan Rikalo

2015-02-20 20:18

developer   ~0081290

Qt is fixed in r47923

Zeljan Rikalo

2015-02-20 20:21

developer   ~0081291

Does drBounds include icon + text on windows or ?

theo

2015-02-20 20:35

reporter   ~0081292

Thanks, Qt works now without the extra line.

drBounds in current win32 implementation is simply the whole line meaning from the left Border of the first column to the right border of the last column.
This is inconsistent. Gtk2 and Qt widths are only for the first column.
All include icons, so there is no information about icon offset in drBounds.

theo

2015-02-20 20:42

reporter  

winlved.png (4,424 bytes)   
winlved.png (4,424 bytes)   

theo

2015-02-20 20:44

reporter   ~0081293

Last edited: 2015-02-20 20:47

View 2 revisions

Win32 screenshot attached. You see the editor (drBounds) fills the width of the control. This is now with the new code, which respects icon offset.

Zeljan Rikalo

2015-02-20 21:08

developer   ~0081295

What's correct drBounds=Column or line ? Besides that, if drBounds = complete line how to get column size for editing in that column ?

theo

2015-02-20 21:18

reporter   ~0081296

We should probably take drSelectBounds for the editor.
https://msdn.microsoft.com/en-us/library/windows/desktop/bb761049%28v=vs.85%29.aspx

Zeljan Rikalo

2015-02-21 08:42

developer   ~0081304

Hm...explanation looks strange. When my brain translate it then drBounds should return item dricon + drlabel , so item in column. Drselectbounds is complete line....it excludes columns

theo

2015-02-21 11:49

reporter   ~0081306

Yes, it is not very clear. The only thing I can say:
if we change the code in procedure TCustomListView.ShowEditor to

R := Item.DisplayRect(drSelectBounds);

Win32 works as I Would expect it and the way delphi 6 does.
The editor then only fills the first column.
The other columns are not editable anyway.

Zeljan Rikalo

2015-02-21 13:00

developer   ~0081307

Ok then we'll use drselectbounds, i'll implement it in other ws.

theo

2015-02-21 14:46

reporter   ~0081308

You are a hero! ;-)

Zeljan Rikalo

2015-02-21 15:19

developer   ~0081309

I need more informations since documentation isn't complete (about Delphi behaviour).
1.drBounds = width = What ? (visible, clientwidth or sum of columns widths)
2.drSelectBounds = that switches something. In win32wscustomlistview.inc calling
subitem ... when TDisplayCode = drSelectBounds, then it switches to drBounds ?!?
So, won't touch anything until all rules are clear.
Besides that, drSelectBounds returns complete item (drIcon + drLabel) according to the docs.

theo

2015-02-21 16:31

reporter   ~0081311

OK, I've made a test on D6. Does this help you?
See 2nd attached image. These are the values for this ListView in D6:

----------------------------------
Without Icon

BoundsRect L:0 T:41 R:289 B:400
ClientRect L:0 T:0 R:285 B:355
drBounds L:0 T:19 R:150 B:33
drSelectBounds L:2 T:19 R:24 B:33
drIcon L:2 T:19 R:2 B:33
drLabel L:2 T:19 R:50 B:33


With Icon

BoundsRect L:0 T:41 R:289 B:400
ClientRect L:0 T:0 R:285 B:355
drBounds L:0 T:19 R:150 B:36
drSelectBounds L:2 T:19 R:40 B:36
drIcon L:2 T:19 R:18 B:36
drLabel L:18 T:19 R:50 B:36

----------------------------------
Code used to produce this output:

function RectToString(ARect: TRect;Fna:String): string;
begin
  Result :=Fna+' '+Format('L:%d T:%d R:%d B:%d',[ARect.Left,ARect.Top,ARect.Right,ARect.Bottom]);
end;


procedure TForm1.Button1Click(Sender: TObject);
var R:TRect;
begin
  ListView1.Items[0].Selected:=True;

  R:=ListView1.BoundsRect;
  Memo1.Lines.add(RectToString(R,'BoundsRect'));

  R:=ListView1.ClientRect;
  Memo1.Lines.add(RectToString(R,'ClientRect'));

  R := ListView1.Selected.DisplayRect(drBounds);
  Memo1.Lines.add(RectToString(R,'drBounds'));

  R := ListView1.Selected.DisplayRect(drSelectBounds);
  Memo1.Lines.add(RectToString(R,'drSelectBounds'));

  R := ListView1.Selected.DisplayRect(drIcon);
  Memo1.Lines.add(RectToString(R,'drIcon'));

  R := ListView1.Selected.DisplayRect(drLabel);
  Memo1.Lines.add(RectToString(R,'drLabel'));
end;

theo

2015-02-21 16:32

reporter  

d6lvtest.png (1,441 bytes)   
d6lvtest.png (1,441 bytes)   

Zeljan Rikalo

2015-02-21 17:30

developer   ~0081317

It looks like Delphi bug to me. drSelectBounds is not drIcon + drLabel (looking width only). drSelectBounds should be R=50 , and not R=40 when icon is assigned,
or to be clear, it must be same size as drLabel without icon.
Also, when there's no icon it sends R=2 and L=2 , so width = 0, and that's how it was before I've touched qt .... I'll revert that part.

theo

2015-02-21 17:38

reporter   ~0081318

Last edited: 2015-02-21 17:41

View 2 revisions

I don't believe in Delphi Bugs on this Level.
It's a rather straightforward API call ending in:

Result := Bool( SendMessage(hWnd, LVM_GETITEMRECT, i, Longint(@prc)) );

where "i" is sth. like LVIR_SELECTBOUNDS

If it is a bug, then it is probably a Win2k Bug. Testing in VBox/Win2k Server.

Zeljan Rikalo

2015-02-21 17:47

developer   ~0081319

I don't have Delphi, so no chance to test. drSelectBounds output looks weird isn't it (with or without icon) ?
without icon width = 22, drLabel width = 32, drIcon = 0
with icon width = 38, drLabel width = 32, drIcon = 16
so my question is what drSelectBounds represents exactly ?

theo

2015-02-21 18:05

reporter   ~0081322

Please look at the 3rd image. The same LV as before with Icon.
Visualized with code like this:


----------------------------------

  R := ListView1.Selected.DisplayRect(drBounds);
  PaintBox1.Canvas.Brush.color:=clPurple;
  PaintBox1.Canvas.FillRect(R);

  R := ListView1.Selected.DisplayRect(drSelectBounds);
  OffsetRect(R,0,R.Bottom-R.Top);
  PaintBox1.Canvas.Brush.color:=clRed;
  PaintBox1.Canvas.FillRect(R);

  R := ListView1.Selected.DisplayRect(drIcon);
  OffsetRect(R,0,2*(R.Bottom-R.Top));
  PaintBox1.Canvas.Brush.color:=clGreen;
  PaintBox1.Canvas.FillRect(R);

  R := ListView1.Selected.DisplayRect(drLabel);
  OffsetRect(R,0,3*(R.Bottom-R.Top));
  PaintBox1.Canvas.Brush.color:=clBlue;
  PaintBox1.Canvas.FillRect(R);


----------------------------------

Looks like some Borders are sometimes included or not.

theo

2015-02-21 18:05

reporter  

d6lvtest2.png (429 bytes)   
d6lvtest2.png (429 bytes)   

Zeljan Rikalo

2015-02-21 18:39

developer   ~0081323

It is clear that drSelectBounds are strange. Anyway, under others (non win32) drSelectBounds meaning will be item rect (column width) and row height.
drIcon (if associated) then icon width, else 0, height is always row height afair.
drLabel drSelectbounds - drIcon.
drBounds = width = sum of visible columns (max = clientWidth)

Zeljan Rikalo

2015-02-21 18:43

developer   ~0081324

Now I see, seem that drSelectBounds = drIcon + text width (not drLabel which is size of container for label = item width - icon width).
IMO, we should use drLabel in TListView for editor rect (of course stuff have to be implemented in widgetsets first), and not drSelectBounds because then editor covers icon.

theo

2015-02-21 18:57

reporter   ~0081326

Yes. Of course, drLabel is correct for the editor.

Zeljan Rikalo

2015-02-21 20:32

developer   ~0081327

LCL part is fixed in 47941, I'll reopen and try to fix drLabel to show in right of icon as it is with win32.

Zeljan Rikalo

2015-02-21 20:33

developer   ~0081328

you can test if drLabel is ok for win32 now.

theo

2015-02-21 20:55

reporter   ~0081329

Thank you, it works. Even with additional StateImages on win32.

Zeljan Rikalo

2015-02-21 21:53

developer   ~0081333

Qt fixed in r47942.

Zeljan Rikalo

2015-02-21 22:04

developer   ~0081334

At least drLabel now works correct for win32,gtk2 and qt. Please test and close if ok.

theo

2015-02-21 22:15

reporter   ~0081335

It works in ViewStyle vsReport for the three WS now.
Qt does not indent in vsList. Not sure if vsList is meant for Icons?
Although it works for win32.
GTK2 and Qt do not have StateImages. Is this a decision/impossible or just a missing feature?

Thanks a lot.

Zeljan Rikalo

2015-02-22 10:18

developer   ~0081342

vsList with Qt uses another widget, didn't fixed it yet (displayRect) ... I'll try today. Icons can be setted up in vsList (small icons).
StateImages does not work since there's place for only one icon per item.

Zeljan Rikalo

2015-02-22 10:33

developer   ~0081345

Qt's vsList should work ok from r47946

theo

2015-02-22 12:12

reporter   ~0081347

Thanks a lot.

One more problem: Editing in GTK2 now _only_ works if there is an ImageList (smallimages). It does not trigger the Edit Control without ImageList.

> StateImages does not work since there's place for only one icon per item.
Should this go to the restriction browser?

Thank you.

theo

2015-02-22 12:56

reporter  

restriction.diff (936 bytes)   
Index: lcl/interfaces/gtk2/issues.xml
===================================================================
--- lcl/interfaces/gtk2/issues.xml	(Revision 47946)
+++ lcl/interfaces/gtk2/issues.xml	(Arbeitskopie)
@@ -40,5 +40,8 @@
 		<issue name="TListView.Columns">
 			<short>Multiple columns then ViewStyle=vsList is not supported</short>
 		</issue>		
+		<issue name="TListView.StateImages">
+			<short>StateImages are not supported</short>
+		</issue>		
 	</widgetset>
 </package>
Index: lcl/interfaces/qt/issues.xml
===================================================================
--- lcl/interfaces/qt/issues.xml	(Revision 47946)
+++ lcl/interfaces/qt/issues.xml	(Arbeitskopie)
@@ -25,5 +25,8 @@
 		<issue name="TCheckListBox.Columns">
 			<short>Multiple columns is not supported</short>
 		</issue>
+		<issue name="TListView.StateImages">
+			<short>StateImages are not supported</short>
+		</issue>		
 	</widgetset>
 </package>
restriction.diff (936 bytes)   

theo

2015-02-22 12:57

reporter   ~0081350

Attached a patch for issues.xml. See "restriction.diff"

Zeljan Rikalo

2015-02-22 13:07

developer   ~0081351

hm...probably gtk2 drLabel is in wrong part of code, so returned rect is too small for editor.

theo

2015-02-22 17:40

reporter  

lvvslist.diff (2,077 bytes)   
Index: lcl/interfaces/gtk2/gtk2wscustomlistview.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2wscustomlistview.inc	(Revision 47948)
+++ lcl/interfaces/gtk2/gtk2wscustomlistview.inc	(Arbeitskopie)
@@ -1143,22 +1143,25 @@
         if (ACode in [drIcon, drLabel]) and not TLVHack(ALV).OwnerDraw then
         begin
           IconRect := ItemRect;
-          APGList := gtk_tree_view_column_get_cell_renderers(gtk_tree_view_get_column(PGtkTreeView(MainView), 0));
-          pixrenderer := PGtkCellRenderer(g_list_last(APGList)^.prev^.data);
-          gtk_cell_renderer_get_fixed_size(pixrenderer, @AWidth, @AHeight);
-          if AWidth > 0 then
-            IconRect.Width := AWidth - 2;
-          if AHeight > 0 then
-            IconRect.Height := AHeight - 2;
-          g_list_free(APGList);
-          if ACode = drIcon then
-            ItemRect := IconRect
-          else
-          begin
-            ItemRect.x += IconRect.width + IconRect.x + 2;
-            ItemRect.y += 2; // offset
-            ItemRect.Width -= IconRect.Width + 2;
-            ItemRect.height -= 2; // offset
+          if (ALV is TListView) and Assigned(TListView(ALV).SmallImages) then
+            begin
+            APGList := gtk_tree_view_column_get_cell_renderers(gtk_tree_view_get_column(PGtkTreeView(MainView), 0));
+            pixrenderer := PGtkCellRenderer(g_list_last(APGList)^.prev^.data);
+            gtk_cell_renderer_get_fixed_size(pixrenderer, @AWidth, @AHeight);
+            if AWidth > 0 then
+              IconRect.Width := AWidth - 2;
+            if AHeight > 0 then
+              IconRect.Height := AHeight - 2;
+            g_list_free(APGList);
+            if ACode = drIcon then
+              ItemRect := IconRect
+            else
+            begin
+              ItemRect.x += IconRect.width + IconRect.x + 2;
+              ItemRect.y += 2; // offset
+              ItemRect.Width -= IconRect.Width + 2;
+              ItemRect.height -= 2; // offset
+            end;
           end;
         end;
lvvslist.diff (2,077 bytes)   

theo

2015-02-22 18:25

reporter   ~0081362

Second Patch is better lvvslist2.diff

theo

2015-02-22 18:25

reporter  

lvvslist2.diff (876 bytes)   
Index: lcl/interfaces/gtk2/gtk2wscustomlistview.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2wscustomlistview.inc	(Revision 47948)
+++ lcl/interfaces/gtk2/gtk2wscustomlistview.inc	(Arbeitskopie)
@@ -1140,7 +1140,8 @@
           inc(ItemRect.y, H);
         end;
 
-        if (ACode in [drIcon, drLabel]) and not TLVHack(ALV).OwnerDraw then
+        if (ACode in [drIcon, drLabel]) and ((ALV is TListView) and
+        Assigned(TListView(ALV).SmallImages)) and not TLVHack(ALV).OwnerDraw then
         begin
           IconRect := ItemRect;
           APGList := gtk_tree_view_column_get_cell_renderers(gtk_tree_view_get_column(PGtkTreeView(MainView), 0));
@@ -1161,7 +1162,6 @@
             ItemRect.height -= 2; // offset
           end;
         end;
-
       end
       else
       if GTK_IS_ICON_VIEW(MainView) then
lvvslist2.diff (876 bytes)   

theo

2015-02-22 18:30

reporter   ~0081363

Note: GTK2 only shows Images if a column is added.

Issue History

Date Modified Username Field Change
2015-02-20 18:34 theo New Issue
2015-02-20 18:34 theo File Added: clvedpos.diff
2015-02-20 19:02 Zeljan Rikalo Note Added: 0081287
2015-02-20 19:03 Zeljan Rikalo Note Added: 0081288
2015-02-20 19:42 theo Note Added: 0081289
2015-02-20 20:18 Zeljan Rikalo LazTarget => -
2015-02-20 20:18 Zeljan Rikalo Note Added: 0081290
2015-02-20 20:18 Zeljan Rikalo Status new => feedback
2015-02-20 20:21 Zeljan Rikalo Note Added: 0081291
2015-02-20 20:35 theo Note Added: 0081292
2015-02-20 20:35 theo Status feedback => new
2015-02-20 20:42 theo File Added: winlved.png
2015-02-20 20:44 theo Note Added: 0081293
2015-02-20 20:47 theo Note Edited: 0081293 View Revisions
2015-02-20 21:08 Zeljan Rikalo Note Added: 0081295
2015-02-20 21:18 theo Note Added: 0081296
2015-02-21 08:42 Zeljan Rikalo Note Added: 0081304
2015-02-21 11:49 theo Note Added: 0081306
2015-02-21 13:00 Zeljan Rikalo Note Added: 0081307
2015-02-21 14:46 theo Note Added: 0081308
2015-02-21 15:19 Zeljan Rikalo Note Added: 0081309
2015-02-21 16:31 theo Note Added: 0081311
2015-02-21 16:32 theo File Added: d6lvtest.png
2015-02-21 17:30 Zeljan Rikalo Note Added: 0081317
2015-02-21 17:38 theo Note Added: 0081318
2015-02-21 17:41 theo Note Edited: 0081318 View Revisions
2015-02-21 17:47 Zeljan Rikalo Note Added: 0081319
2015-02-21 18:05 theo Note Added: 0081322
2015-02-21 18:05 theo File Added: d6lvtest2.png
2015-02-21 18:39 Zeljan Rikalo Note Added: 0081323
2015-02-21 18:43 Zeljan Rikalo Note Added: 0081324
2015-02-21 18:57 theo Note Added: 0081326
2015-02-21 20:32 Zeljan Rikalo Fixed in Revision => 47941
2015-02-21 20:32 Zeljan Rikalo Note Added: 0081327
2015-02-21 20:32 Zeljan Rikalo Status new => resolved
2015-02-21 20:32 Zeljan Rikalo Resolution open => fixed
2015-02-21 20:32 Zeljan Rikalo Assigned To => Zeljan Rikalo
2015-02-21 20:33 Zeljan Rikalo Note Added: 0081328
2015-02-21 20:33 Zeljan Rikalo Status resolved => feedback
2015-02-21 20:55 theo Note Added: 0081329
2015-02-21 20:55 theo Status feedback => assigned
2015-02-21 21:53 Zeljan Rikalo Note Added: 0081333
2015-02-21 22:04 Zeljan Rikalo Fixed in Revision 47941 => 47941,47942,47944
2015-02-21 22:04 Zeljan Rikalo Note Added: 0081334
2015-02-21 22:04 Zeljan Rikalo Status assigned => resolved
2015-02-21 22:15 theo Note Added: 0081335
2015-02-22 10:18 Zeljan Rikalo Note Added: 0081342
2015-02-22 10:33 Zeljan Rikalo Note Added: 0081345
2015-02-22 12:12 theo Note Added: 0081347
2015-02-22 12:56 theo File Added: restriction.diff
2015-02-22 12:57 theo Note Added: 0081350
2015-02-22 13:07 Zeljan Rikalo Note Added: 0081351
2015-02-22 17:40 theo File Added: lvvslist.diff
2015-02-22 18:25 theo Note Added: 0081362
2015-02-22 18:25 theo File Added: lvvslist2.diff
2015-02-22 18:30 theo Note Added: 0081363