Page 1 of 1

Adding to index 0 of ListIconGadget with large icons

Posted: Sun Nov 23, 2014 10:43 am
by PB
Just stumbled across this problem, and it appears to be a bug?

I need to use large icons with a ListIconGadget, and I need to
add items to the top of its list (index 0). With small icons, it
works. With large icons, the items get added to the end, as
if I'd used position parameter -1 instead of 0.

Check it out. Run this, then click the ListIconGadget to see
that new items are correctly added to the TOP with every
click. Then, uncomment the large icon line, and run again.
They're added to the BOTTOM instead. The manual says
that using 0 as the param adds them to the TOP, but
clearly it doesn't with large icon mode. A bug?

Code: Select all

CreateImage(0,32,32,24,#Red)

OpenWindow(0,200,200,200,250,"test",#PB_Window_SystemMenu)

ListIconGadget(0,10,10,180,230,"test",80)
;SetGadgetAttribute(0,#PB_ListIcon_DisplayMode,#PB_ListIcon_LargeIcon)

For a=4 To 1 Step -1
  AddGadgetItem(0,0,Str(a),ImageID(0))
Next

Repeat
  ev=WaitWindowEvent()
  If ev=#PB_Event_Gadget
    AddGadgetItem(0,0,Str(Random(999)),ImageID(0))
  EndIf
Until ev=#PB_Event_CloseWindow

Re: Adding to index 0 of ListIconGadget with large icons

Posted: Sun Nov 23, 2014 12:39 pm
by PB
Here's my (crappy) work-around for now:

Code: Select all

CreateImage(0,32,32,24,#Red)

OpenWindow(0,200,200,200,250,"test",#PB_Window_SystemMenu)

ListIconGadget(0,10,10,180,230,"test",80)
SetGadgetAttribute(0,#PB_ListIcon_DisplayMode,#PB_ListIcon_LargeIcon)

For a=4 To 1 Step -1
  AddGadgetItem(0,0,Str(a),ImageID(0))
Next

Repeat
  ev=WaitWindowEvent()
  If ev=#PB_Event_Gadget
    LockWindowUpdate_(GadgetID(0))
    AddGadgetItem(0,0,Str(Random(999)),ImageID(0))
    SetGadgetAttribute(0,#PB_ListIcon_DisplayMode,#PB_ListIcon_SmallIcon)
    SetGadgetAttribute(0,#PB_ListIcon_DisplayMode,#PB_ListIcon_LargeIcon)
    SetGadgetState(0,0)
    LockWindowUpdate_(0)
  EndIf
Until ev=#PB_Event_CloseWindow

Re: Adding to index 0 of ListIconGadget with large icons

Posted: Mon Nov 24, 2014 9:23 am
by netmaestro
It's a feature of the SysListview32 control. PureBasic just wraps the APIs and so the behavior is passed on. To override it would mean a workaround in PB's wrapping code and the team would have to decide if it were something worth doing or not. Replace all the PB commands relating to the ListIcon with their API counterparts and you see the same behavior:

Code: Select all

CreateImage(0,32,32,24,#Red)
imglist = ImageList_Create_(32, 32, #True, 1, 0)
ImageList_Add_(imglist, ImageID(0), 0)

OpenWindow(0,200,200,200,450,"test",#PB_Window_SystemMenu)
ButtonGadget(1, 50, 350, 100, 20, "Add Item")

listicon = CreateWindowEx_(0, "SysListview32", "", #WS_CHILD | #WS_VISIBLE | #LVS_ICON, 10, 10, 180, 230, WindowID(0), 0, GetModuleHandle_(0), 0)
SendMessage_(listicon, #LVM_SETIMAGELIST, #LVSIL_NORMAL, imglist)

For i=4 To 1 Step -1
  this$ = Str(i)
  With ii.LVITEM
    \mask = #LVIF_TEXT|#LVIF_IMAGE
    \iItem = 0
    \pszText = @this$
    \iImage = 0
  EndWith
  SendMessage_(listicon, #LVM_INSERTITEM, 0, @ii)
Next

Repeat
  ev=WaitWindowEvent()
  If ev=#PB_Event_Gadget And EventGadget() = 1
    this$ = Str(Random(100))
    With ii.LVITEM
      \mask = #LVIF_TEXT|#LVIF_IMAGE
      \iItem = 0
      \pszText = @this$
      \iImage = 0
    EndWith
    SendMessage_(listicon, #LVM_INSERTITEM, 0, @ii)
  EndIf
Until ev=#PB_Event_CloseWindow

Re: Adding to index 0 of ListIconGadget with large icons

Posted: Mon Nov 24, 2014 10:12 am
by seeker
hi,
i need to add small jpg pictures to the grid. can it be done this way? are there any demos? i couldn't find any.

thanks

Re: Adding to index 0 of ListIconGadget with large icons

Posted: Mon Nov 24, 2014 11:31 am
by PB
> i need to add small jpg pictures to the grid. can it be done this way?

If you replace my red image above with the ID of a loaded JPG, then
yes; but they can only be a maximum of 32x32 pixels in size.

> are there any demos? i couldn't find any.

My first post above shows how to add an image to a ListIconGadget.
In the post, the image is just a red box. Load your image from a file
and then use it's ImageID as shown in my post.

@NM: A shame about the non-top adding with large icons. I'll keep
using my work-around then, and request that the manual be amended
to mention this problem with AddGadgetItem and large list icons.

Re: Adding to index 0 of ListIconGadget with large icons

Posted: Mon Nov 24, 2014 11:52 am
by seeker
thanks for your answer.
is there any grid you know of, that doesn't bind you to the 32x32 size?

Re: Adding to index 0 of ListIconGadget with large icons

Posted: Mon Nov 24, 2014 7:33 pm
by freak
The item is always added to the beginning of the list. It is just displayed somewhere else. See for yourself:

Code: Select all

CreateImage(0,32,32,24,#Red)

OpenWindow(0,200,200,200,250,"test",#PB_Window_SystemMenu)

ListIconGadget(0,10,10,180,230,"test",80)
SetGadgetAttribute(0,#PB_ListIcon_DisplayMode,#PB_ListIcon_LargeIcon)

For a=4 To 1 Step -1
  AddGadgetItem(0,0,Str(a),ImageID(0))
Next

Repeat
  ev=WaitWindowEvent()
  If ev=#PB_Event_Gadget
    AddGadgetItem(0,0,Str(Random(999)),ImageID(0))
  EndIf
Until ev=#PB_Event_CloseWindow

; show the actual order of items in the gadget
For i = 0 To CountGadgetItems(0)-1
  Debug GetGadgetItemText(0, i)
Next i
Dunno if this behavior can be changed.

Re: Adding to index 0 of ListIconGadget with large icons

Posted: Tue Nov 25, 2014 3:50 am
by RASHAD
Simple workaround
- Cross Platform
- Add item when clicked in an empty area
- No add 2 items with second left click

Code: Select all

CreateImage(0,32,32,24,#Red)

Procedure AddItem()
  If GetGadgetAttribute(0,#PB_ListIcon_DisplayMode) = #PB_ListIcon_LargeIcon And GetGadgetState(0) = -1
    SetGadgetAttribute(0,#PB_ListIcon_DisplayMode,#PB_ListIcon_SmallIcon)
    AddGadgetItem(0,0,Str(Random(999)),ImageID(0))   ;0 for Inser item at index 0 -1 for append after last item
    SetGadgetAttribute(0,#PB_ListIcon_DisplayMode,#PB_ListIcon_LargeIcon)
  EndIf
EndProcedure

OpenWindow(0,200,200,200,250,"test",#PB_Window_SystemMenu)

ListIconGadget(0,10,10,180,230,"test",80)
SetGadgetAttribute(0,#PB_ListIcon_DisplayMode,#PB_ListIcon_LargeIcon)

For a=0 To 4
  AddGadgetItem(0,-1,Str(a),ImageID(0))
Next

BindGadgetEvent(0,@AddItem(),#PB_EventType_LeftClick)

Repeat
  Select WaitWindowEvent()
     Case #PB_Event_CloseWindow
             Quit = 1             
             
     Case #PB_Event_Gadget
             Select EventGadget()
                   Case 0                   
             EndSelect
  EndSelect
Until Quit = 1
Edit :Fixed some bugs

Re: Adding to index 0 of ListIconGadget with large icons

Posted: Tue Nov 25, 2014 12:32 pm
by PB
> ; show the actual order of items in the gadget
> For i = 0 To CountGadgetItems(0)-1
> Debug GetGadgetItemText(0, i)
> Next i

Interesting. I didn't think to check that. But it doesn't solve the
problem at all, which is I need to show the "latest" added item
at the top of my list. I'll keep using my work-around then. :(
I just wish it worked like small icons did. Damn Windows.

@Rashad: Thanks, but it's basically what my work-around does.
That is, I see no advantage to your code over mine? We're both
still toggling between large/small icons to force the work-around.

Also, I need to use LockWindowUpdate with both your code and
mine, otherwise the ListIconGadget has a horrible flicker when
the new items are "pushed" to the top by the toggle.