After more than 6 years of waiting for an implementation in PureBasic, I decided to program a cross-platform GetGadgetItemImage() procedure which I have tested successfully with PB 5.46 in both ASCII and Unicode mode on these operating systems:
- Linux Mint 19.1 x64 'Tessa' with Cinnamon using GTK2 and GTK3
- MacOS 10.6.8 'Snow Leopard'
- MacOS 10.14.5 'Mojave'
- Windows 7 x64 SP1
- Windows 10 x64 Version 1809
Code: Select all
EnableExplicit
UsePNGImageDecoder()
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
#G_TYPE_OBJECT = 20 << 2
ImportC ""
g_object_get_property(*Object.GObject, PropertyName.P-UTF8,
*PropertyValue.GValue)
g_type_check_instance_is_a(*Instance.GTypeInstance, *Type.GTypeClass)
gtk_cell_layout_get_cells(*CellLayout)
gtk_widget_get_realized(*Widget.GtkWidget)
EndImport
CompilerEndIf
Procedure GetGadgetItemImage(ListIconID.I, Row.I)
Protected Image.I
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
Protected CellRenderer.I
Protected CellRendererList.I
Protected PixBuf.GValue
Protected SelectedRow.I
Protected *TreeColumn
SelectedRow = GetGadgetState(ListIconID)
; ----- Select row with image to get the correct CellRenderer
; for that row
SetGadgetState(ListIconID, Row)
*TreeColumn = gtk_tree_view_get_column_(GadgetID(ListIconID), 0)
CellRendererList = gtk_cell_layout_get_cells(*TreeColumn)
CellRenderer = g_list_nth_data_(CellRendererList, 0)
If g_type_check_instance_is_a(CellRenderer,
gtk_cell_renderer_pixbuf_get_type_())
PixBuf\g_type = #G_TYPE_OBJECT
g_object_get_property(CellRenderer, "pixbuf", @PixBuf)
Image = g_value_get_object_(@PixBuf)
EndIf
SetGadgetState(ListIconID, SelectedRow)
g_list_free_(CellRendererList)
CompilerCase #PB_OS_MacOS
Protected ColumnObject.I
Protected ColumnObjectArray.I
Protected ImageCell.I
CocoaMessage(@ColumnObjectArray, GadgetID(ListIconID), "tableColumns")
CocoaMessage(@ColumnObject, ColumnObjectArray, "objectAtIndex:", 0)
If PeekS(CocoaMessage(0, CocoaMessage(0,
ColumnObject, "identifier"), "UTF8String"), -1, #PB_UTF8) = "Image"
ImageCell = CocoaMessage(0, GadgetID(ListIconID),
"preparedCellAtColumn:", 0,
"row:", 0)
If ImageCell
Image = CocoaMessage(0, ImageCell, "image")
EndIf
EndIf
CompilerCase #PB_OS_Windows
Protected ImageIndex.I
Protected ImageListHandle.I
Protected Item.LV_ITEM
Item.LV_ITEM
Item\Mask = #LVIF_IMAGE
Item\iItem = Row
SendMessage_(GadgetID(ListIconID), #LVM_GETITEM, 0, @Item)
ImageIndex = Item\iImage
ImageListHandle = SendMessage_(GadgetID(ListIconID), #LVM_GETIMAGELIST,
#LVSIL_SMALL, 0)
Image = ImageList_GetIcon_(ImageListHandle, ImageIndex, #ILD_TRANSPARENT)
CompilerEndSelect
ProcedureReturn Image
EndProcedure
If LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/world.png") = 0
MessageRequester("Error",
"Unable to load image CdPlayer.ico")
End
EndIf
OpenWindow(0, 270, 100, 220, 130, "GetGadgetItemImage()")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 50,
"Column 1", WindowWidth(0) - 52)
AddGadgetItem(0, -1, "Row with image")
TextGadget(1, 10, GadgetHeight(0) + 20, 100, 25, "Grabbed image:")
ImageGadget(2, 110, GadgetHeight(0) + 20, 16, 16, 0)
SetGadgetItemImage(0, 0, ImageID(0))
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
; ----- Wait until ListIconGadget is initialized
While gtk_widget_get_realized(GadgetID(0)) = #False
Delay(10)
Wend
CompilerEndIf
SetGadgetState(2, GetGadgetItemImage(0, 0))
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Update:
- I had to update the Linux part of procedure GetGadgetItemImage() because the old code didn't use the row parameter and always returned the image which was the last to have been rendered by the CellRenderer. The trick is to store the actual selected row in variable SelectedRow, select the wanted row (that will now be rendered again by the correct CellRenderer) and afterwards restore the selected row from variable SelectedRow (which may be -1, if no row was selected at all).
- I replaced the general code
Code: Select all
; ----- Wait until Window and Widgets are initialized (Necessary in Linux)
Repeat : Until WindowEvent() = 0
by the more target-oriented code
Code: Select all
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
; ----- Wait until listIconGadget is initialized
While gtk_widget_get_realized(GadgetID(0)) = #False
Delay(10)
Wend
CompilerEndIf
which only in Linux will wait until the ListIconGadget is initialized internally and the following call of GetGadgetItemImage() will safely work.