listicon gadget speed (with large images, 2000+ items)

Just starting out? Need help? Post your questions and find answers here.
Heathen
Enthusiast
Enthusiast
Posts: 498
Joined: Tue Sep 27, 2005 6:54 pm
Location: At my pc coding..

listicon gadget speed (with large images, 2000+ items)

Post by Heathen »

I'm having a little problem. In my program I am using a listicon with large images, but I'm finding that on some computers it goes EXTREMELY slow after about 2,000 items. Basically, it would freeze the program. This doesn't happen on my computer as it has pretty high specs, but it happens on slower computers, such as my buddy's laptop. It's really important that I can support a very large list. I was wondering if it's possible to do some sort of optimizations to perhaps load each image in the list on the fly? Or something to that extent? Also, has anyone else bumped into this problem?


Thanks in advance.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

The smaller the image the less the problem.

What is the memory and graphics processor of your buddys laptop?
What CPU )pII, pIII etc( ?
8)

Also what size are the image files? Are they consistent?
What format the image files?

Any info would be helpful.
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

Have you watched memory usage?

cheers
Heathen
Enthusiast
Enthusiast
Posts: 498
Joined: Tue Sep 27, 2005 6:54 pm
Location: At my pc coding..

Post by Heathen »

Yes, I have watched memory usage, it has worried me a bit, it doesn't rise above 50 megs though.. yet.... The image sizes are all identical size (32x32). What I was thinking was perhaps using a window callback to load only the visible icons and unload the non visible icons, perhaps I can also do the same for the text following the icon. Just not sure how I would do this.
What is the memory and graphics processor of your buddys laptop?
What CPU )pII, pIII etc( ?
Not sure of the specs, I'll ask him later
Also what size are the image files? Are they consistent?
Yes, 32x32
What format the image files?
Not sure why that matters, but they are grabbed from a larger tileset, which is PNG.


Thanks for the responses :)
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

I believe rendering 2000+ images from scratch would be a little time comsuming. When I open a directory of lots of images in preview mode, it takes a little while for them all to be available.

Where are they coming from? I wouldn't think disk would be a problem, but on an older slower machine it could have an impact.

You might consider rendering in a thread?

I'm sure the real experts will have some tips. Good luck :)

cheers,
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

You could use the loading style like in Windows for folders with thumbnail view. The 2000+ items are added right from the beginning. So you have two options now:

1.) Thread Rendering:

In order that the GUI won't freeze and still reacts on user input load all images in the background till it's done and destroy the thread.

2.) Onthefly Rendering:

You calculate how many and wich items are currently in the clipping rect of the gadget and then load the images acordingly.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

OK so I ask questions... these are PNG, nice format... lossless...
I am thinking you have an ALPHA layer for transparency maybe?

Have you considered JPG?

I know a 32X32 png on my system with NO ALPHA is 1.93k and the exact same JPG is 2.1k... Hmmmm let me cut the PNG to 256 colors and see that as well...

256color PNG at 32X32 is 1.71k... slight savings...

so 2000 of those would take up 3420k more or less.

3.42mb? I must have dropped a 0 somewhere! :D

Also are all the images the same? As I read this it seems to me the answer must be yes.

You could just load one image and copy it to all new images.

:D

You know this would be a good time to query srod if his esGrid can handle your tasks!

http://www.purebasic.fr/english/viewtopic.php?t=26647
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
Heathen
Enthusiast
Enthusiast
Posts: 498
Joined: Tue Sep 27, 2005 6:54 pm
Location: At my pc coding..

Post by Heathen »

Fluid Byte wrote:You could use the loading style like in Windows for folders with thumbnail view. The 2000+ items are added right from the beginning. So you have two options now:

1.) Thread Rendering:

In order that the GUI won't freeze and still reacts on user input load all images in the background till it's done and destroy the thread.

2.) Onthefly Rendering:

You calculate how many and wich items are currently in the clipping rect of the gadget and then load the images acordingly.
Thanks again for the responses guys. I'm probably going to go with #2 to load and unload the images on the fly, I'm going to fiddle with my code and see if I can figure it out.
I love Purebasic.
Heathen
Enthusiast
Enthusiast
Posts: 498
Joined: Tue Sep 27, 2005 6:54 pm
Location: At my pc coding..

Post by Heathen »

Can someone tell me how I could get the range of items which are currently visible?
I love Purebasic.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

Well you should be able to see which items are currently selected, but I have been having problems keeping the ListIconGadget set on the last line entered, can't even make that work.

Only thing I can think of is to add 1 to the listicongadget with SetGadgetItemData() by keeping tabs on the #PB_EventType_Change in Event... then you have to assume that is the number of the gadget at the TOP of the ListIconGadget... and ADD your lines displayed from there and display with: SetGadgetItemState() with that number as your new index start...

But I am probably wrong

Quick Question:

Are you using CatchImage(#PB_Any, MemoryAddress) to create copies of this image?

Here I used 3000 48X48 jpg images... works well...

Code: Select all

   ; Shows possible flags of ListIconGadget in action...
  UseJPEGImageDecoder()
      If LoadImage(0, "resQ0.jpg")     ; change path/filename to your own 32x32 pixel image
      EndIf
      
  If OpenWindow(0, 0, 0, 640, 300, "ListIconGadgets", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
    ; left column
        ListIconGadget(5, 10, 10, 620, 165, "", 200,#PB_ListIcon_GridLines)
    ; Here we change the ListIcon display to large icons and show an image

      ChangeListIconGadgetDisplay(5, 0)
      ; AddGadgetItem(5, 1, "Picture 1", ImageID(0))
      For X = 0 To 3000 ; change number to test start with 100, then 500, then 1000, then 1500, 2000 3000 etc
      AddGadgetItem(5, x, "Picture "+Str(x), ImageID(0))
     Next X 

    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
  EndIf
8) Change the number where indicated and maybe compile different versions of this and test your buddies computer with different image number versions.
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

A slightly more complex way:

Code: Select all

Enumeration
#Window_0
#Text_Selected
#LI_0
EndEnumeration

Global Window_0, ListIcon_0, Text_0, Button_0

Structure VisualDesignerGadgets
  Gadget.l
  EventFunction.l
EndStructure

Global NewList EventProcedures.VisualDesignerGadgets()

  UseJPEGImageDecoder()
      If LoadImage(0, "resQ0.jpg")     ; change path/filename to your own 32x32 pixel image
      EndIf

Procedure LI_0_Event(Window, Event, Gadget, Type)
  Debug "#LI_0"
  SetGadgetText(#Text_Selected, "")
    Result = GetGadgetState(#LI_0)
      parsley$ = GetGadgetItemText(#LI_0, Result,0)
        SetGadgetText(#Text_Selected, parsley$)
EndProcedure


Procedure RegisterGadgetEvent(Gadget, *Function)
  
  If IsGadget(Gadget)
    AddElement(EventProcedures())
    EventProcedures()\Gadget        = Gadget
    EventProcedures()\EventFunction = *Function
  EndIf
  
EndProcedure

Procedure CallEventFunction(Window, Event, Gadget, Type)
  
  ForEach EventProcedures()
    If EventProcedures()\Gadget = Gadget
      CallFunctionFast(EventProcedures()\EventFunction, Window, Event, Gadget, Type)
      LastElement(EventProcedures())
    EndIf
  Next
  
EndProcedure

Procedure Open_Window_0()
  
  Window_0 = OpenWindow(#Window_0, 5, 5, 400, 408, "Window 0",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
  If Window_0
    If CreateGadgetList(WindowID(#Window_0))
      ListIconGadget(#LI_0, 10, 10, 370, 290, "Column1", 100, #PB_ListIcon_GridLines)
      RegisterGadgetEvent(#LI_0, @LI_0_Event()) 
      ChangeListIconGadgetDisplay(#LI_0, 0)
      TextGadget(#Text_Selected, 10, 310, 370, 20, "", #PB_Text_Center | #PB_Text_Border)
      ButtonGadget(#PB_Any, 10, 340, 370, 40, "BIG FAKE BUTTON")
      
    EndIf
  EndIf
EndProcedure

Open_Window_0()

      For X = 0 To 3006 ; change number to test start with 100, then 500, then 1000, then 1500, 2000 3000 etc
      AddGadgetItem(#LI_0, x, "Picture "+Str(x), ImageID(0))
     Next X 
     
Repeat

  
  Event  = WaitWindowEvent()
  Gadget = EventGadget()
  Type   = EventType()
  Window = EventWindow()
  
  Select Event
    Case #PB_Event_Gadget
      CallEventFunction(Window, Event, Gadget, Type)
      
  EndSelect
  
Until Event = #PB_Event_CloseWindow

End
Well thats all I got on that! You can reference the selected to open a file or do something etc.

8)
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
Heathen
Enthusiast
Enthusiast
Posts: 498
Joined: Tue Sep 27, 2005 6:54 pm
Location: At my pc coding..

Post by Heathen »

What I'm hoping for is an elegant solution using #LVM messages in order to get the top visible item. The only solution I have found is #LVM_GETTOPINDEX, but that supposedly only works when not using icons.
I love Purebasic.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

Well you can store a value in the Gadget (like the position, and retrieve it as well... It will never show to the user.

Let me monkey with my code a second or two...
8)
Well I think you have discovered a new feature request.

I did this to my LI_0 procedure

Code: Select all

Procedure LI_0_Event(Window, Event, Gadget, Type)

Select Type
      Case #PB_EventType_Change
      value = value + 3
        Debug "VALUE: "+Str(value) 
EndSelect

  SetGadgetText(#Text_Selected, "")
    Result = GetGadgetState(#LI_0)
      parsley$ = GetGadgetItemText(#LI_0, Result,0)
        SetGadgetText(#Text_Selected, parsley$)

            SetGadgetItemData(#LI_0, 1, Value)

EndProcedure
The Select Type section does work, but ONLY if an item is clicked on by the user... Apparently just dragging the scrollbar is not enough to trigger a change.

So the List is one giant entity.

I suppose the feature request woudl be a way to get the TOP line and the BOTTOM line of a ListIcon_Gadget that are displayed.

@srod! Does eGrid tell you that?

If he doesn't answer you might ask him on the eGrid thread!
8)
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

EsGRID is a listicon in report mode, so I don't think it would help out here.
I may look like a mule, but I'm not a complete ass.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

By the way, do you disable redrawing before you add the items?
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
Post Reply