Page 1 of 1

Posted: Sat Jan 06, 2007 2:36 pm
by srod
Hi,

I had to contend with these issues whilst writing the egrid control and they are far from trivial! :) Placing the controls is one thing, keeping them positioned whilst the user scrolls the list icon or drags columns or resizes a column is an entirely different matter!

Anyhow, I'll see if I can shed any light.

First thing to say is that these controls you wish to embed within the ListIcon should be made child's of the listicon. I'd say don't waste your time tyring to position controls which are not child controls of the list icon, this is asking for trouble!

1) Once the list icon has been created, it is not necessarily a good idea to change the row height. Is it not a better idea, when creating the child control, to size this accordingly - i.e. make it fit the dimensions of the cell which the user has clicked?

2)

Code: Select all

#LVM_SUBITEMHITTEST = #LVM_FIRST+57 

If OpenWindow(0, 100, 100, 300, 100, "ListIcon Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   If CreateGadgetList(WindowID(0))
     ListIconGadget(0, 5, 5, 290, 90, "Name", 100, #PB_ListIcon_AlwaysShowSelection)
     AddGadgetColumn(0, 1, "Address", 250)
     AddGadgetItem(0, -1, "Harry Rannit"+Chr(10)+"12 Parliament Way, Battle Street, By the Bay")
     AddGadgetItem(0, -1, "Ginger Brokeit"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity")
     Repeat
       Event = WaitWindowEvent()
        If event=#WM_LBUTTONDOWN
          Define PInfo.LVHITTESTINFO
          GetCursorPos_(rc.POINT)
          MapWindowPoints_(0, GadgetID(0),rc,1)
          PInfo\pt\x = rc\x
          PInfo\pt\y = rc\y 
          SendMessage_(GadgetID(0), #LVM_SUBITEMHITTEST, 0, PInfo) 
          Debug "("+Str(PInfo\iItem)+", "+Str(PInfo\iSubitem)+")"
        EndIf
     Until Event = #PB_Event_CloseWindow
   EndIf
 EndIf
I found early on in the development of egrid that the zero column of the underlying listicon could throw a spanner in the works. Just try the above code and click any non-text part of a cell in column 0 to see what I mean. For this reason (amongst many), I always blanked out the zero column, i.e. set it's width to zero. Of course this depends on your requirements whether you should follow suit.

Aligning the controls to exactly fit the cell in question is a royal pain in the a***! To avoid massive flicker you need to account for gridlines (if any are present?)
It seems that your program will need to place a child control when the user clicks a cell, i.e. the control is removed as soon as focus moves to another cell. This means that only one of each type of supported control needs to be created, which I think is the best way. In itself this is fine, except if you wish to align the text in the control perfectly with the text in the underlying cell. This took me days to get this right (but then I did have to account for the text justification etc.)

The following post might prove useful:

http://www.purebasic.fr/english/viewtop ... s+listicon

I'm not sure if all this helps.

Posted: Sat Jan 06, 2007 8:40 pm
by netmaestro
To place your child controls on the ListIcon gadget, you need to know the location and size of the clicked item, right? At least that's what I took from your post. Here's an example that takes srod's work just a bit further so that you obtain those values so you can place your child. Note that I'm in agreement with srod on Column 0 (I hate it) so I'm factoring it the hell out of the example:

Code: Select all

#LVM_SUBITEMHITTEST = #LVM_FIRST + 57 
#LVM_GETSUBITEMRECT = #LVM_FIRST + 56

Global oldproc

Procedure SubClass_LV(hwnd, msg, wparam, lparam) 
  result = CallWindowProc_(oldproc, hwnd, msg, wparam, lparam) 
  If msg = #WM_RBUTTONDOWN or msg = #WM_LBUTTONDOWN
    GetCursorPos_(@cp.POINT)
    MapWindowPoints_(0,hwnd,@cp,1)
    HitInfo.LVHITTESTINFO 
    Hitinfo\pt\x = cp\x
    HitInfo\pt\y = cp\y
    SendMessage_(hwnd,#LVM_SUBITEMHITTEST ,0,@HitInfo)
    If hitinfo\isubitem > 0 And HitInfo\iItem >= 0
      RtlZeroMemory_(@itemrect.RECT,SizeOf(RECT))
      itemrect\top = hitinfo\iSubItem
      SendMessage_(hwnd,#LVM_GETSUBITEMRECT, hitinfo\iitem, @itemrect)
      Debug ""
      Debug "Item Left: " + Str(itemrect\left)
      Debug "Item Top: " + Str(itemrect\top)
      Debug "Item Width: " + Str(itemrect\right-itemrect\left)
      Debug "Item Height: " + Str(itemrect\bottom-itemrect\top)
    EndIf
  EndIf 
  ProcedureReturn result 
EndProcedure 

If OpenWindow(0, 100, 100, 400, 200, "ListIcon Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
   If CreateGadgetList(WindowID(0)) 
     ListIconGadget(0, 5, 5, 355, 200, "", 0, #PB_ListIcon_AlwaysShowSelection) 
     oldproc = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @SubClass_LV())
     
     AddGadgetColumn(0, 1, "Name", 100)
     AddGadgetColumn(0, 2, "Address", 250) 
     AddGadgetItem(0, -1, Chr(10)+"Harry Rannit"+Chr(10)+"12 Parliament Way, Battle Street, By the Bay") 
     AddGadgetItem(0, -1, Chr(10)+"Ginger Brokeit"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity") 
     AddGadgetItem(0, -1, Chr(10)+"srod Ateit"+Chr(10)+"34 API Road, BigTown, CodeCity")      
     AddGadgetItem(0, -1, Chr(10)+"fangbeast Drankit"+Chr(10)+"144 EasyStreet, BigTown, CodeCity")      
     Repeat 
       Event = WaitWindowEvent() 

     Until Event = #PB_Event_CloseWindow 
   EndIf 
 EndIf 

Posted: Sun Jan 07, 2007 2:30 am
by DARKGirl
well Srod, I first want to thank you for the lovely code snipplets that I shall add to my own, but unfortunately, the gadgets that I want to use have a minimum size, and cannot be sized to fit the listicongadget, therefore, I must size the cells to the minimul size of the gadget

Posted: Sun Jan 07, 2007 7:14 am
by netmaestro
Sample provided, moved to Tips & Tricks:

http://www.purebasic.fr/english/viewtop ... 712#176712

Posted: Sun Jan 07, 2007 2:18 pm
by srod
Nice example Netmaestro. :) I always tend to steer away from ownerdrawn methods with list view controls because of the requirement to paint all subitems in one go etc. but that is a very slick example.

@Darkgirl: If you're talking about different heights for different rows then I don't think it is possible as List View controls do not have a #LVS_OWNERDRAWVARIABLE style (unlike list box controls).

If you're talking about altering the height of all rows together then you either need to use the #LVS_OWNERDRAWFIXED style as Netmaestro's example shows (but which involves you taking charge of drawing all items within the control), or you adopt a 'dirty' little trick involving imagelists which allows you to alter the height of all rows dynamically and at any time. I can post an example if you wish. This latter method does not require custom draw or owner draw etc.

Posted: Tue Jan 09, 2007 12:36 pm
by Fangbeast
"AddGadgetItem(0, -1, Chr(10)+"Harry Rannit"

Blimey, seems like years since I worked on the PureBasic docs (because it is) and I recognise that bit.

"AddGadgetItem(0, -1, Chr(10)+"fangbeast Drankit"+Chr(10)+"

If it's soy milk with milo and fresh hamsters, I probably did!!!