PDA

View Full Version : Dragging and linking a field without making a link graphic on it...



Oberoten
November 9th, 2018, 23:18
Hola.

I have a matrix of values on my character-sheet that can be manipulated through other fields. (IE, each is a combination of two others), this in turn can be dragged to a windowlist below. Is there a good way to LINK the value in the windowlist so that when I drop per example the contents of "Creo Ignem" on a spell slot it should now hold a link to the node and update when it is changed?

It feels like it should be obvious, I have seen it done on the combat tracker etc but can't seem to figure out the last step.

- Obe

damned
November 9th, 2018, 23:54
would stringcyclers be another way to handle this?

Moon Wizard
November 10th, 2018, 07:48
I think you’d need a more specific example to get an idea of what you want to do.

For combat tracker, specific PC fields are synched between PC record and CT list item.

Regards,
JPG

Oberoten
November 11th, 2018, 00:13
On the combined numberfield i have so far tried this...

function onDrag(button, x, y, draginfo)
local a, b, c
a = getValue();
b = description[1];
c = getName();

draginfo.setShortcutData("charsheet_magic","CrAn");

draginfo.setType("art");
draginfo.setDescription(b);
draginfo.setStringData(c);
draginfo.setNumberData(a);
return true;

end



The receiving numberfield inside a windowlist :

function onDrop(x, y, draginfo)
local temp1
local temp2
local temp3
if draginfo.getType() == "art" then
temp1 = draginfo.getNumberData();
temp2 = draginfo.getDescription();
temp3 = draginfo.getStringData();
local a,b = draginfo.getShortcutData();
print("Triggered Art " .. a .. " " ..b);

forms.setValue(temp3);
castingtotal.setValue(temp1);



end

if draginfo.getType() == "shortcut" then
temp1 = draginfo.getNumberData();
temp2 = draginfo.getDescription();
temp3 = draginfo.getStringData();
local a,b = draginfo.getShortcutData();
print("Triggered shortcut " .. a .. " " ..b);

forms.setValue(temp3);
castingtotal.setValue(temp1);



end



end


... the idea is of course to make a link similar to how it is done on the Combat-tracker. So I have a casting-total for each spell directly on it's listing.

-Obe

Oberoten
November 11th, 2018, 00:24
would stringcyclers be another way to handle this?
Possibly but it is a mix from 10 x 5 fields.Maybe if I did it with two cyclers instead.

- Obe

Moon Wizard
November 11th, 2018, 01:43
You’ll want to use onDragStart; instead of onDrag. The former is called once; the latter is called every time the mouse is moved.

For the capture; you won’t get any number/string data for the “shortcut” type; unless you have a custom drag function setting to shortcut plus extra data elsewhere.

Are you getting the correct values returned by print function? You can also use Debug.chat function to keep from having to check console.

Regards,
JPG

Oberoten
November 11th, 2018, 21:57
Replaced the onDrag with onDragStart.

The line
draginfo.setShortcutData("charsheet_magic","CrAn");

passes over the class and the node name if understand correctly. But how do I turn this into a link so when I raise the CrAn score later the casting-score raises as well?

How do I recieve the data beyond

if draginfo.getType() == "art" then
temp1 = draginfo.getNumberData();
temp2 = draginfo.getDescription();
temp3 = draginfo.getStringData();
local a,b = draginfo.getShortcutData();
print("Triggered shortcut " .. a .. " " ..b);

forms.setValue(temp3);
castingtotal.setValue(temp1);


Which just gives it it's current value?

- Obe

Moon Wizard
November 11th, 2018, 22:47
You would need to start retrieving database nodes based on the link passed; Store the node in a variable; set onUpdate and onDelete handlers for the node; and recalculate/remove based on the event.

The number_linked template and script does something like that. It takes the values passed in the template control XML tags; saves off the nodes; and updates the total when they change.

Regards,
JPG

Oberoten
November 12th, 2018, 23:09
Spent most of the day fiddling with this. ... it didn't go particularily well.

function onDragStart(button, x, y, draginfo)
local a, b, c, d
a = getValue();
b = description[1];
c = getName();

local node = getDatabaseNode();
d = node.getPath();
draginfo.setShortcutData("charsheet_magic",d);

draginfo.setType("art");
draginfo.setDescription(b);
draginfo.setStringData(c);
draginfo.setNumberData(a);
draginfo.setCustomData(d);
return true;

end

gives me charsheet ID node name.
I can drop this to the recepient field (using a version of number_linked) which I fail to get to link to the node itself.

- Obe

Moon Wizard
November 12th, 2018, 23:26
You are already setting the database node in setShortcutData(), so you don't need to add as custom data as well. Just pull out of draginfo.getShortcutData().

This probably isn't the part that's not working as expected, as the dragging is the easy part. It's the handling of the drop, and subsequent linked behavior that will be the meat of the logic.

Where's your code for the drop handling, as well as the handling for adding update events and updating when those events trigger?

Regards,
JPG

Oberoten
November 13th, 2018, 00:06
You are already setting the database node in setShortcutData(), so you don't need to add as custom data as well. Just pull out of draginfo.getShortcutData().

This probably isn't the part that's not working as expected, as the dragging is the easy part. It's the handling of the drop, and subsequent linked behavior that will be the meat of the logic.

Where's your code for the drop handling, as well as the handling for adding update events and updating when those events trigger?

Regards,
JPG



Sorry for being on the slow side, this is what the field has so far... (I have gone over it over and over and have erased and commented out the parts that doesn't work)


function onInit()

end

function onDrop(x, y, draginfo)
local temp1
local temp2
local temp3
local temp4
local a,b
if draginfo.getType() == "art" then
temp1 = draginfo.getNumberData();
temp2 = draginfo.getDescription();
temp3 = draginfo.getStringData();
if draginfo.getShortcutData() then
a,b = draginfo.getShortcutData();
end



--addBitmapWidget("indicator_linked").setPosition("bottomright", -5, -7);

forms.setValue(temp3);
castingtotal.setValue(temp1);
--setLink(b);




end
end

Oberoten
November 13th, 2018, 00:09
Also? Didn't these forums use to have a code-tag?

damned
November 13th, 2018, 00:27
[ code] [ /code] without the spaces.

Oberoten
November 13th, 2018, 00:32
[ code] [ /code] without the spaces.

I have been inactive for FAR too long it seems.

-Obe

Moon Wizard
November 15th, 2018, 22:31
Maybe you can post a work-in-progress so we can take a look at what you are doing? And also post an exact set of steps for how it should work?

At this point, I don't have enough information to suggest a way to do what you are trying to do.

Regards,
JPG

Oberoten
November 16th, 2018, 01:32
What I have :

I have a windowlist (spells) which contains a CastingTotal which is the sum of two numbers from a matrix. I have managed to get so I can drag the numbers and drop them onto the castingtotal so it is simple for players to cast their spells. But when the matrix is changed, it does not update the casting-total.

What I aim for :

Linking the fields so that casting total updates when the source updates.




Current problem :


Runtime Notice: Reloading ruleset and data
Script Error: [string "charsheet_spelllistitem:castingtotal"]:1: attempting to set a nil value as a handler function
Script Error: [string "charsheet_spelllistitem:castingtotal"]:1: attempting to set a nil value as a handler function





I have updated the numberfield "Castingtotal" to have the following in the script....




datanode = nil;

function onInit()
datanode = window.windowlist.getDatabaseNode().createChild("castingtotal", "number");
datanode.onUpdate = update;
update();
end

function onDrop(x, y, draginfo)
local temp1
local temp2
local temp3
local temp4
local a,b
if draginfo.getType() == "art" then
temp1 = draginfo.getNumberData();
temp2 = draginfo.getDescription();
temp3 = draginfo.getStringData();

if draginfo.getShortcutData() then
a,b = draginfo.getShortcutData();
datanode.setValue(b);
end

forms.setValue(temp3);
castingtotal.setValue(temp1);

end
end

Moon Wizard
November 16th, 2018, 09:14
If I understand right, you don't want an update event on the castingtotal database node; since that's the field you want to be updated when other fields change, or when things are dropped on it.

Some questions to help clarify, because I'm just not following what you're trying to do yet:

* What game system are you trying to implement?
* Is there a description of the game mechanic you are trying to recreate somewhere?
* Please provide as much detail as you can, and at least a couple specific examples.

* Do the numbers from the matrix change, or are they static?
* Are there 2 distinct classes of numbers, such that when you drag a different number over that it should replace others?
* Are there a small enough set of numbers that it would make more sense to provide a grid for them to click on to select the two items they want to apply?

Regards,
JPG

Oberoten
November 16th, 2018, 18:37
If I understand right, you don't want an update event on the castingtotal database node; since that's the field you want to be updated when other fields change, or when things are dropped on it.

Some questions to help clarify, because I'm just not following what you're trying to do yet:

* What game system are you trying to implement?
* Is there a description of the game mechanic you are trying to recreate somewhere?
* Please provide as much detail as you can, and at least a couple specific examples.

* Do the numbers from the matrix change, or are they static?
* Are there 2 distinct classes of numbers, such that when you drag a different number over that it should replace others?
* Are there a small enough set of numbers that it would make more sense to provide a grid for them to click on to select the two items they want to apply?

Regards,
JPG

Game system is Ars Magica, based in the CoreRPG set.

* Spells are cast in Ars Magica by combining a Stat (normaly Intelligence or Stamina) with a technique and a form value. Both of the later work as skills and can be raised in the course of the game. Examples of techniques are "Creo" (creation), "Perdo" (destruction), Intelligo (Percieve) combined with a form (What one wants to affect) So I have created a matrix of these.

25308


There is a total of 50 arts, 5 Techniques x 10 Forms.


When either Muto or Animal changes it allready updates the matrix : Giving per example the combination score of Muto (3) Animal (1) of 4.


The spell-list then contains a spell-name, what combination it uses and finaly a casting total which is the getValue of the CombinedValues… What I need is to create a self-updating node that pulls the value of te combined form ciand technique. So if I pull the original value of say Muto Animal to the spell it should show Arts : "Muto Animal" (which it allready does) followed by the combined value in the casting-total.

- Obe

Oberoten
November 16th, 2018, 21:00
Further explanation just because I can :

The Arts are raised by adding Xp to the later number in each of the primary boxes. When enough is accumulated the Level raises and the matrix recalculates.

Currently I can drag and replace a Matrix-number down tot he spell and it will populate the Forms and Casting values, but since the matrix is not static I need the Castingtotal (the value under Casting) to update automarticaly for each spell that shares the same attributes. IE All spells containing any of the Animal forms (and any Technique) should update whenever I raise Animal.

.. the rest of the spell-field is fairly straightforward and works as intended. Lvl is compared to a roll triggered from the casting-total to see if a spell is cast sucessfully and if so at what cost.

- Obe

Moon Wizard
November 17th, 2018, 00:17
I would probably go about this a little differently.

I would place all the code in the high-level window for updating the numbers. Then, in onInit event function, cycle through each spell, and write a function to set the casting total value based on the current technique/form value of the spell. Next, when a technique or form is dropped on a spell, then update the technique value, followed by using the same function to update the casting total based on the current technique/form of the spell. Finally, have each matrix cell control call a window.onMatrixChanged function in the windowclass whenever onValueChanged event fires for that matrix cell. In the onMatrixChanged function, cycle through all the spells again, and update the casting total value based on the current technique/form value of the spell.

This is very similar to how the 5E skills tab works for updating skill totals based on attribute changes. (except attributes are no different tab, so I use database change handlers to capture attribute change events)

Let me know if you have sample ruleset code you want me to look at.

Regards,
JPG

Oberoten
November 17th, 2018, 22:12
Current thought is to let the drag contain custom-data. Specificaly a number telling which part of the matrix was dropped. Then when the onMatrixUpdate triggers it goes in a loop over all the entries and uses a case to drop the proper value. Should be fairly fast at the least.

- Obe

Moon Wizard
November 17th, 2018, 22:33
I would probably just use a custom drag type; and pass the value you need for the technique/form field. Easier to handle the drag field set. But, that’s just details that can be handled different ways. I think you’re on right track now.

Regards,
JPG

Oberoten
November 20th, 2018, 08:21
That seems to be what does the trick best for me. :) Far easier to push change down-stream than pulling it from upstream.
Many thanks for the help.

- Obe

Oberoten
November 24th, 2018, 21:06
I spoke to soon it seems. I have been wrestling with how to find the windowlist (named spelllist) so I can then go over it with a for k,v in ipairs( "The heck do I put here") and find the v.getChild("forms") and set it to the combined name and v.getChild("castingtotal").setValue() to the matrix-value.

... I am frustrated by my inability to do this to say the least. It has been some ages since I had to do it last and I can not for the life of me figure it out.

- Obe

Moon Wizard
November 24th, 2018, 22:19
I would probably do something like this from the windowclass level script for the character spell tab window:


function onMatrixChanged()
for _,w in ipairs(spelllist.getWindows()) do
w.updateSpellCastTotal();
end
end


And something like this from the windowclass level script for the individual spells:


function updateSpellCastTotal()
local nNewCastingTotal = <Calculation>;
catingtotal.setValue(nNewCastingTotal);
end


In Lua, the pairs() construct will allow you to iterate over all key/value pairs in a table, but order is not guaranteed. The ipairs() construct will allow you to iterate (in order) over key/value pairs with numeric keys that start at 1; but will ignore non-numeric keys and will stop at any gaps. (i.e. if table has keys of 1, 2 and 4; then only 1 and 2 will be iterated over.)

The windowlist.getWindows() API returns a table with numeric keys pointing to each window instance.

Regards,
JPG

Oberoten
November 25th, 2018, 05:36
Made a clunky proof of concept that now updates any spell using the forms of "CreoAnimal" on the character-sheet.



function onValueChanged()
local a = getValue();
b = getName();

for _,w in ipairs(window.spelllist.getWindows()) do
local d = w.name.getValue() .. " form : " .. w.forms.getValue() .. " " .. w.castingtotal.getValue();
local form = w.forms.getValue();
if form == b then
w.castingtotal.setValue(a);
end
print(d);
end
end


Many thanks for all the help Jpg. It has been valuable to save my sanity. (Such as sanity is for a beholder to begin with)

/Obe

Moon Wizard
November 26th, 2018, 22:17
I'd probably simply a bit:

In individual matrix field scripts:


function onValueChanged()
window.onMatrixChanged(getName(), getValue());
end


In spell tab window script:


function onMatrixChanged(sForm, nValue)
for _,w in ipairs(spelllist.getWindows()) do
if w.forms.getValue() == sForm then
w.castingtotal.setValue(nValue);
end
end
end


Cheers,
JPG