Blue wrote:Does anyone know how to figure out, using only PB code, which item is currently at the top of a Listview gadget ?
I know how to get this information using some API function, but i'm looking into a solution that would work on any platform.
Some features can't be achieved without using API functions. And it's not necessary to rule out the use of API functions completely only because the resulting code wouldn't be cross-platform anymore. You simply have to implement the respective API functions for each OS. I have already put together a list with links to cross-platform code examples which use API functions to implement functions currently not available in PureBasic. And some of these functions have already become implemented natively as PB functions...Blue wrote:But i'm looking for an all platforms solution, written with PB only code.![]()

The above list contains already links to cross-platform examples to display a double-clicked row at the top of a ListIconGadget or display a selected row in the center of a ListIconGadget.
For your conveniance I have taken your code example and added the respective API functions for Linux and MacOS to determine the currently visible row at the top of your ListViewGadget. I have tested the modified example successfully on these operating systems:
- MacOS X 10.6.8 (Snow Leopard) x86
- Ubuntu 14.04 x64 with KDE
- Windows 7 x64 SP1
But this example has one problem which you wouldn't know if only working with Windows: in Windows the top row is normally always visible as a whole row whereras in Linux and MacOS it's possible that only a fraction of the current top row is visible. So as a result it's possible on Linux and MacOS that for example a top row of 0 is reported although the top row seems to be row 1 because only a very small (and nearly unvisible) part of top row 0 is displayed. To solve this problem the example would have to be extended to also count the displayed rows and define a top row fraction of for example a minimum of 80% which has to be visible to be reported as the currently visible top row...
Code: Select all
EnableExplicit
#lignes = 12 ; number of lines displayed by the ListView gadget
Enumeration
#cmd_OK
#input
#liste
#infos_LABEL
#infos
EndEnumeration
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
ImportC ""
gtk_tree_view_get_visible_range(*TreeView.GtkTreeView, *StartPath, *EndPath)
EndImport
CompilerEndIf
Procedure.I GetVisibleTopRow(ListIconID.I)
Protected VisibleTopRow.I
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
Protected *EndPath
Protected *StartPath
If gtk_tree_view_get_visible_range(GadgetID(ListIconID), @*StartPath, @*EndPath)
VisibleTopRow = PeekI(gtk_tree_path_get_indices_(*StartPath))
gtk_tree_path_free_(*StartPath)
gtk_tree_path_free_(*EndPath)
EndIf
CompilerCase #PB_OS_MacOS
Protected ContentView.I
Protected EnclosingScrollView.I
Protected VisibleRange.NSRange
Protected VisibleRect.NSRect
; ----- Get scroll view inside of ListIconGadget
EnclosingScrollView = CocoaMessage(0, GadgetID(ListIconID), "enclosingScrollView")
If EnclosingScrollView
ContentView = CocoaMessage(0, EnclosingScrollView, "contentView")
; ----- Get visible area
; (automatically subtract horizontal scrollbar if shown)
CocoaMessage(@VisibleRect, ContentView, "documentVisibleRect")
; ----- Subtract border width
If CocoaMessage(0, EnclosingScrollView, "borderType") > 0
VisibleRect\size\height - 5
EndIf
; ----- Get visible top row
CocoaMessage(@VisibleRange, GadgetID(ListIconID), "rowsInRect:@", @VisibleRect)
VisibleTopRow = Int(VisibleRange\location)
EndIf
CompilerCase #PB_OS_Windows
VisibleTopRow = SendMessage_(GadgetID(ListIconID), #LB_GETTOPINDEX, 0, 0)
CompilerEndSelect
ProcedureReturn VisibleTopRow
EndProcedure
If 0 = OpenWindow(0,10,10,300,200,"ListView",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
End
EndIf
ButtonGadget(#cmd_OK,180,175,60,20,"Go to >>>")
StringGadget(#input,244,175,30,20,"50", #PB_String_Numeric)
TextGadget(#infos_LABEL,20,175,48,20,"top item = ")
TextGadget(#infos,20+48+6,175,60,20,"0")
Define lvID = ListViewGadget(#liste,10,10,280,160)
Define i
For i = 0 To 100
AddGadgetItem(#liste, i, "Ligne "+Str(i))
Next
Define event, evType, gadget, item
Repeat
event=WaitWindowEvent()
Select event
Case #PB_Event_CloseWindow : Break
Case #PB_Event_Gadget
gadget = EventGadget()
Select gadget
Case #cmd_OK
i = Val(GetGadgetText(#input))
SetGadgetState(#liste,i)
SetGadgetText(#infos,Str(GetVisibleTopRow(#liste)))
Case #liste
SetGadgetText(#infos,Str(GetVisibleTopRow(#liste)))
EndSelect
EndSelect
ForEver
End
Code: Select all
Case #liste
SetGadgetText(#infos,Str(item))
Code: Select all
Case #liste
SetGadgetText(#infos,Str(GetVisibleTopRow(#liste)))