pkulchenko / wxlua

wxlua: Lua bindings for wxWidgets cross-platform GUI toolkit; supports Lua 5.1, 5.2, 5.3, 5.4, LuaJIT and wxWidgets 3.x
306 stars 59 forks source link

wxTreeListCtrl::GetItemData returns base wxClientData with no methods #125

Open sokolas opened 1 year ago

sokolas commented 1 year ago

I'm trying to store custom data in a wxTreeListCtrl items like this:

local item = myListCtrl:AppendItem(parentItem, "name", -1, -1)
local obj = wx.wxStringClientData("test data")
myListCtrl:SetItemData(item, obj)

It runs fine with no errors. However, when I try to retrieve this data, I get errors:

local s = myListCtrl:GetItemData(item)
Log(s)  -- produces "userdata: 000001eeef206148 [wxClientData(000001eeef2e2070, 26)]"
Log(s:GetData()) -- "attempt to call method 'GetData' (a nil value)"

Is it possible to cast wxClientData back to wxStringClientData or use another class to store the data? I'm using luaJIT 2.1, wxlua built from master with webview;xrc;xml;media;richtext;propgrid;gl;html;adv;core;net;base libraries, wxWidgets 3.2.2.1 with 3.0 compatibility.

pkulchenko commented 1 year ago

Normally you can cast using DynamicCast function, but it only works for those objects that are derived from wxObject and these are not. I cannot simply add GetData and SetData to wxClientData either, as they need to have specific type returned.

It's likely that something similar to wxLuaTreeItemData class will need to be done, but for wxClientData. It will accept any Lua type and return the same type in that case, which would do whatever you need without any casting.

There is some inconsistency, as wxTabCtrl uses wxObject for GetItemData and SetItemData, wxTreeCtrl uses wxLuaTreeItemData, while wxListCtrl and wxTreeListCtrl both use wxClientData. wxDataView* methods return long, wxClientData, and wxUIntPtr.

It may be possible to update them all to use wxObject for consistency (or possibly make wxClientData to inherit from wxObject), but I'll have to check on what the implications may be and do a bit of testing.

pkulchenko commented 1 year ago

@sokolas, as a workaround you should be able to use a regular Lua table referenced by item (of userdata type). You can potentially mark the keys as weak to allow the userdata/items to be garbage collected.