I wasn't sure how to word the title, but here we go.
Let's say I made a Lua function to create a 2D box appear on the screen - for example:
box = createObject("Box")
How would I create properties for box that would subsequently change how box looks or reacts? For example I may want to do
box.PositionX = 0
box.PositionY = 60
How do I do that in C++?
Just answering the direct question itself, things are simple:
Just use the standard metatable-aware add/set-table-index API.
If we look at how box itself should look, things get interesting:
If createObject "Box" returns a Lua table and you don't need to react immediately on change, just don't do anything special.
If createObject "Box" returns a Lua table but you need to react immediately, let it act as a proxy object, aka force using the metatable function by never adding that element to the table itself. Remap to another index or another table saved at a dedicated index or in the metatable/metatable function closures.
If createObject "Box" returns a userdata, do the same as for 2, maybe saving non-lua-values in C for faster access/higher efficiency, using the environment table for all other values.
Related
There is a structure that holds raw data (consider int) and a gui that should visualize this data. Gui part consists of a few models and and a few standard views (table and tree). The value should be presented either as a string or as a picture depend on user choice. There are some additional difficulties: in some cases the text is different for different elements - i.e., for the same column 0 normally means "Ok", but for a particular element it should be printed as "Yes", also depend on a user choice some columns should not print text for 0 values at all, living a cell empty and don't clutter the table; next, sometimes cell should show two values - e.g., current value and requested - something like "Yes -> No". This also applies to the case when user wants to see icons.
I see two options:
The model forms string text itself and store it somewhere (in the model item may be). The model also forms composite icon from base icons if it is needed. In that scenario I can use standard delegate and just use standard roles reimplementing QAbstractItemModel::data() method.
Reimplement delegates' paint() method (actually I need to reimplement delegates anyway because I need custom editors like QComboBox). The delegate can get any information it needs through the model and custom roles in paint() method and form the string or complex icon itself. As a suboption, I suppose, it's possible for a model to compose needed information itself, like returning std::tuple<int /*value*/, int /*requested value*/, int /*source element type*/, bool /*text or icon*/> in data() method for Qt::DisplayRole.
Update: I want add one thought about second option. Presumably delegates were introduced to handle the work of representing data. One of the consequences of that is the flexibility delegates can give. If you want to see a raw number in some column, you can just leave the default delegate, if you want some additional info presented in a cell you can set a special delegate for that specific column. And it seems you don't need even touch the model or something else.
I’m getting crazy with Pro Motion table and I cannot find any discussion about this online.
I’m using a PM::TableScreen and I need to have selectable table rows. I manage the raw selection in an array but I don’t know how can I get the cell object to call cell.accessoryType = UITableViewCellAccessoryCheckmark if is selected or cell.accessoryType = UITableViewCellAccessoryNone if not selected.
Here is the gist of my screen: I try to intercept the cell passing a value in the arguments (row) but I cannot find a method to get the cell object.
In my original idea the place for the selection is inside my tapped_cell method byt maybe there is a better way to manage a multiselection.
My Gist
You don't want to memoize the table data. I've created a pull request with the fix:
https://github.com/robypez/rm_quiz/pull/1
Hard to summarize here, although I know Stackoverflow doesn't like us relying on links.
Lua tables can have a table as a key, for instance:
a = {[{}]=true}
I'm wondering how I can index this from the lua C++ api. For instance, I can do:
lua_getfield(L, -1, variablename);
To get a string key'd value of a table on the stack. How would I put a table-valued key onto the stack?
lua_getfield is nothing more than syntactic sugar around a series of commands you could do on your own:
lua_pushstring(L, variablename);
lua_gettable(L -1 - 1); //The second minus one represents the fact that your table is actually one index below the top now.
You push the key onto the stack, then use lua_gettable to access it. This is true regardless of what kind of key it is.
The only question you have to answer is how to actually get that key in the first place. For that... you're on your own. Every Lua table has a different value from every other Lua table. And if your Lua script just jammed a freshly-created Lua table in the key like that, without handing a reference to the table to you or storing a reference globally, you're hosed.
Your only recourse then is to just iterate through the table with lua_next and hope that a key who's type is "table" is the key you're looking for.
I would say you need to iterate the table with lua_next.
This link describes the process: http://pgl.yoyo.org/luai/i/lua_next.
Investigate the iterated tables and determine if its the one that you are searching for.
I'm brand new to Lua/LuaPlus and trying to figure out how metatables work.
In this code taken from the manual:
LuaObject metaTableObj = state->GetGlobals().CreateTable("MultiObjectMetaTable");
metaTableObj.SetObject("__index", metaTableObj);
metaTableObj.RegisterObjectFunctor("Print", &MultiObject::Print);
In the first line we create a new table, but the second line is a little confusing. In this table we just created, we are setting the element with key __index equal to the table itself. Why is __index chosen as a key and why set an element of the table to be equal to the table itself?
And then in the next section of code:
MultiObject obj1(10);
LuaObject obj1Obj = state->BoxPointer(&obj1);
obj1Obj.SetMetaTable(metaTableObj);
state->GetGlobals().SetObject("obj1", obj1Obj);
We create a C++ object, associate its address with a LuaObject via the BoxPointer call, and set the metatable so that we can use the Print function.
But for the last line, is that just creating a global Lua variable called "obj1"? At this point "obj1" and "MultiObjectMetaTable" will be global Lua variables?
This is not standard Lua, it looks like you're using some C++ wrapper that I'm unfamiliar with, but I can make some guesses
In the first line we create a new table, but the second line is a
little confusing. In this table we just created, we are setting the
element with key __index equal to the table itself. Why is __index
chosen as a key and why set an element of the table to be equal to the
table itself?
__index is a special key when using metatables. If I have a table t and I try to index into it with a key of foo for example, naturally, I'll get back the value associated with that key. But lets say there's nothing there. Normally if you try to index into a spot that has nothing, you'll get nil back.
But not if you have a metatable with the special key __index in it! If you have a metatable with an __index function or table, it'll use that to find you your value. If you have a table assigned to __index as you do here, it'll look into that table and return the value at the key you provided. This allows you get inheritance-like behavior. i.e. if table t doesn't have this value, default to the value in this other table instead.
But for the last line, is that just creating a global Lua variable called "obj1"? At this point "obj1" and "MultiObjectMetaTable" will be global Lua variables?
As I mentioned, this is not standard Lua, so I'm not totally sure what's happening there. (Mixing C++ and Lua can get tricky though, so while you're still learning Lua it's probably better that you stick to the C interface so you can understand whats really happening. Once you understand that you can move on to more automated solutions)
I am using a List Control to display a representation of elements within a vector. When the list is clicked on another control shows information about that element. The index of the element is currently determined by its index in the control, however if I wish to sort or filter the results this will no longer work.
I have been told that I could use a virtual list control, but the MSDN is not very friendly, can someone run me through how I could use a virtual list control for this?
Frankly - tying data (the position in your data vector) to the presentation of the data in the list control (the position in the list ctrl) is something I would stay away from.
In MFC each control has a "Data" DWORD member variable - when coding in MFC I Always called "SetItemData" for each item added and passed in a pointer that the relevant row referred to e.g.
YourListCtrl.SetItemData((DWORDPTR)&YourData);
Then when the ListCtrl item is selected, you just call
DataTypeYouWant* pData = (DataTypeYouWant*)(YourListCtrl.GetItemData(indexofselecteditem));
Or somesuch thing.
Alternatively - if you don't want to use pointers - hold the index of the item in your original vector in the itemdata for your row (just pass it into the above fns).
To use a virtual list control, set the LVS_OWNERDATA style. You then need to handle the LVN_GETDISPINFO notification message (which is sent via WM_NOTIFY).
If you do this, you are entirely responsible for the data, including the order in which it is shown. Therefore it is up to you to handle sorting and so forth.
By far the easiest way is just to use the item data to set/get an ID that can be used to retrieve the original data, whether that's a vector index or a pointer to the data, or even a key into an associative container.
It really depends on the performance you require.
I have personally seen MAJOR increases in performance for lists holding massive amount of data. However it is much more work to implement, thus for simple uses with not so many data I recommend staying away from it.
Basically, what happens with virtual list controls is that you have your data somewhere in some data structure of your own. Since the list view shows only a small subset of the whole data, it queries you for the content to display when ever something happens (redraw necessary, scroll up or down, change the sorting, etc.).
I don't have handy examples for you. But you can look on codeguru, I am quite sure there are very good examples to start from.
The purpose of virtual list controls is totally different: You should use it for performance reason when you have A LOT of items in your list (I'd say 2500+).
In your case, all you need is to store the vector index in the list item data as NotJarvis explains.