PDA

View Full Version : Is it possible to get access to all controls within a window instance dynamicly?



drvolk
April 20th, 2012, 18:14
Hi,

i am looking for a "smart" way to localize the displayed text in a window.
If possible i want to invoke a "translate()" function whenever a new window will be opened, which replaced all text informations with localized text bevor the window will be displayed.

Is this possible somehow ?

For e.g. the "hook" could be installed like this (Could it ?)):


function onInit()
Interface.onWindowOpened = onWindowOpened;
end

function onWindowOpened(window)
-- loop through all controls/widgets within that window
-- loop through all tags within the current control/widget
-- if found a "string" tag (label,static,tooltip,...) replace tag value with translate(tagvalue)
end

Brenn
April 21st, 2012, 01:03
Yes this kind of thing is possible, I think, though you would have to be on the lookout for window lists within the top level window, as they contain their own window instances.

Look in the "Accessing XML parameters from script" section of the Scripting Library Reference. (https://../modguide/scripting.xcp) This obviously wouldn't work with widgets as they have no XML structure.

There are a lot of things that would fall through the cracks though if you approach it from the XML side as many strings are assigned in script.

I by no means am an expert, just throwing this out there. I could be wrong. Now I've warned you... ;)

I've never attempted localization before and it kind of makes my head hurt on how you would implement it in FG. It could get really complicated if the ruleset wasn't designed from the ground up to be localized.

That said, Good luck! ;)

drvolk
April 21st, 2012, 06:43
Hi Brenn,

thanks for your answer !

I allready read the chapter "Scripting Library References" but as i understood this only describes how to access the tag values with a script exwecuted within an XML definition, so the environment of the script is the XML definitiion itself where the script was embedded into. But in my approach i just have a reference to the current open window instance (in the variable "window"),
So i am looking for a way to parse the XML structure of that window instance itself from its reference. Maybe this is not possible, but if it is, it would makes one part of my "localize project" much easier.

The other part "replace all keyword for "parsing / chat display" within the LUA scripts" is the one which makes much more effort and i guess there is no way but to go throug all scripts and change that manually :(

But this project is also an good exercise for me to learn a lot about FG2 and its great customizing functionalities :)

Zeus
April 21st, 2012, 09:31
If I understand what you are trying to achieve I believe you would need to look at this in two stages.

1) For the window control labels and static text
2) For the data that the window presents in its user controllable fields e.g. string fields etc.

For point 1 I believe you need to know the name of the control instances before you can get access to them from the parent window, this as there is no getControls() method for window instances. Are all the controls in the window class dynamically created? Or are they defined in the <sheet> block of the window classes XML?

If the former, you need to maintain a table of references to the controls are creation time. If the latter, you just simply need to access using the regular window control syntax e.g. mywindowcontrol.getValue() mywindowcontrol.setValue().

For point 2, it maybe easier to parse the underlying database nodes that the controls are bound to, particularly as its the database that stores the data and secondly because the DB package exposes some nice methods for iterating through database nodes and reading/setting values. This of course only applies if the windowcontrols are bound to the database.

Given, window labels are generally quite static, it might be a better idea to statically define alternative label text for the controls in the ruleset (controllable though options perhaps).

drvolk
April 22nd, 2012, 08:59
Hi DrZeuss,

thank you very much for your reply. That was exactly what i wanted to know ! So there is in the current release of FG2 no way to implement a "text translation" in that general approach i described in my example code (because there is no "getControls" Method for a given window instance, and you have to know the names of the controls of the windowinstance if you want access them directly).

So i dont will waste too much time by "try and error" to find a way like this anymore. Instead i will write a script which parses all the XMLs of the ruleset for STATIC, LABEL, TEXT tags and replaces the values found with a translated text.

Thanks to all for your help !

drvolk
December 11th, 2012, 07:39
In my little "Hello World!" example i try to access the static value of the stringcontrol in my default_window window instance, within the "Desktop" lua part.

But i got an "warning" and it do not work also in the way tried to do . :(

Can anybody tell me what is wrong here or is it maybe even not possible to do it in this way i tried to do ?


<?xml version="1.0" encoding="iso-8859-1"?>

<!--
Please see the license.html file included with this distribution for
attribution and copyright information.

This is a example of an allmost minimal "ruleset" which only displays a "Hello world!" window on an empty desktop, with one minimal radial main
menu to close the application.
You need following files in the subfolder "resources", otherwise you wont get the default radial main menu to close the ruleset and no text
on your test window:
menuhub.png
menuback.png
icon_closeprogram.png
icon_restorewindow.png
icon_maximizewindow.png
icon_return.png
mini_name.png
dnd35e-regular-8.fgf
-->

<!-- to show a logo for the hellp world "ruleset" in the ruleset selection you need a logo.png file in the root directory of the ruleset.
Just remove logo="logo.pnp" if you do not need it.
-->
<root version="0.1" release="1" logo="logo.png">
<!-- ATTRIBUTES -->
<description>
<text>Test Suite</text>
<author>drvolk</author>
</description>

<!-- RESOURCES -->

<!--
The icons are necessary for the default radial main menu delivered from fg2 engine only for the icons defined here,
the default menu entry will be shown and so be executable
Per default there is also "arrange dice", "set arrange position", "default arrange position" and "return to launcher" function avaible,
yust define the icons here.
If you define a dice then the number icons "2,3,4,5,10,15,20" should be defined here for the "onDice" radial default menu which is also
deliverd per default from the fg2 engine
-->
<icon name="menuhub" file="resources/menuhub.png" />
<icon name="menuback" file="resources/menuback.png" />
<icon name="closeprogram" file="resources/icon_closeprogram.png" />
<icon name="restorewindow" file="resources/icon_restorewindow.png" />
<icon name="maximizewindow" file="resources/icon_maximizewindow.png" />
<icon name="return" file="resources/icon_return.png" />


<!-- the font for the radial main menu -->
<font name="mini_name">
<fgffile name="resources/dnd35e-regular-8.fgf" />
<color value="#000000" />
</font>

<!-- background for default text in radial main menu deliverd from fg2 engine -->
<framedef name="mini_name">
<bitmap file="resources/mini_name.png" />
<offset>7,7,7,7</offset>
</framedef>

<!-- TEST SUITE -->

<!-- define a window -->
<windowclass name="default_window">
<frame>mini_name</frame>

<!-- set the size of the window, per default it will be larger -->
<placement>
<size>
<width>75</width>
<height>25</height>
</size>
</placement>

<!-- to make the window resizeable -->
<sizelimits>
<dynamic />
</sizelimits>

<!-- define the window content -->
<sheetdata>
<stringcontrol>
<!-- the control need an position, could also be a "bounds" definition. if not you get an "warning" message -->
<anchored>
<position>insideleft</position>
<offset>5,-5</offset>
</anchored>

<!-- no font, no text -->
<font>mini_name</font>

<static>Hello World!</static>
</stringcontrol>
</sheetdata>
</windowclass>


<!-- stringcontrol initialized, then windowclass, then onDesktopInit is fired ... -->
<!-- onInit of "base.xml" set a handler to onDesktopInit, where the window will be opened-->
<script name="Desktop">
function onInit()
Interface.onDesktopInit = onDesktopInit;
end

function onDesktopInit()
local w = Interface.openWindow("default_window", "");
w.sheetdata[1].stringcontrol[3].static[1] = "Hallo Welt";
-- warning: attemp to index field "sheetdata" (a nil value)

end
</script>
</root>

Dakadin
December 11th, 2012, 08:17
What warning did you get?

drvolk
December 11th, 2012, 09:22
This warning:
-- warning: attemp to index field "sheetdata" (a nil value)

Cause by calling the Method "onDesktopInit()":


...
<script name="Desktop">
function onInit()
Interface.onDesktopInit = onDesktopInit;
end

function onDesktopInit()
local w = Interface.openWindow("default_window", "");
w.sheetdata[1].stringcontrol[3].static[1] = "Hallo Welt";

end
</script>
...

Dakadin
December 12th, 2012, 06:44
This issue is with how you are trying to access the stringcontrol. I got it working by doing this. I added a name to the stringcontrol as follows:

<stringcontrol name="msg">

Then I changed this line:

w.sheetdata[1].stringcontrol[3].static[1] = "Hallo Welt";

to:

w.msg.setValue("Hallo Welt");

drvolk
December 12th, 2012, 07:13
I want to write an extension which translate an existing ruleset (e.g. 3.5E) into another language (e.g. german, my native language).

Because this existing rulesets are using controls with texts that will be displayed on the tabletop but without name attributs, i am looking for a way to get access to that text values somehow.

In the "Scripting" chapter of the ruleset modification guide is descibed how to access XML parameters from script (sub chapter "Accessing XML parameter from script").

I thought that the way i tried to access the stringcontrol was as descriped in the ruleset modification guide, but obviously it was not :(

Dakadin
December 12th, 2012, 08:06
Ah ok. Sorry didn't realize that.

One thought would be to just write a parser that you could run against a ruleset folder and replaces the appropriate parts that need to be translated. For example, it could search for the contents of the <static> tags and then replace them with the German equivalent. Then you would just use the new version of the ruleset after it was parsed. It seems like an easier approach to me.

I will experiment and see if I can figure it out how that part works if no one else responds that has more expertise with that sub chapter.

drvolk
December 12th, 2012, 09:04
Thanks a lot for your help !

I did allready wrote a script which replaces all "stringcontrol" tags with "localized_stringcontrol" tags.
The new template "localized_stringcontrol" executes in "onInit" the translation function (first try was to overwrite the <stringcontrol> tag itself within an template with the same name, but overwriting of builtin control is not possible ...).

But as you wrote, then i have a copy of the ruleset and i have to repeat that procedure each time the original ruleset will be updated.

I am looking for a "smarter" way to do the translation, and because the framework of FG2 is so powerfull and flexible i hope there is one ...

Moon Wizard
December 12th, 2012, 23:07
drvolk,

There is not really a facility for speeding up translation of rulesets for other languages.

Your approach with a custom stringcontrol template, and an onInit handler, seems like a decent approach with the current implementation.

Localization is on our wish list, but I haven't had the time to implement since it requires new FG API changes as well as a rewrite of the 3.5E and 4E rulesets.

The best thought I have had for localization is to create a new resource type for strings (like icons, fonts, etc.), and then allow stringcontrol and stringfield objects to be initialized from a string resource. I think this is similar to how most programs are internationalized. The primary challenges with this approach are layout issues on the sheets (i.e. character sheets, etc) and the rewrite of rulesets required.

Regards,
JPG

drvolk
December 13th, 2012, 07:20
JPG,

thank you for the answer.

I agree with you that the primary challenges will be the layout issues for the ability to show text with different length for different languages correctly in the sheets.

Rewrite of the ruleset is neccessary for the "hard coded" texts in the lua files i guess (text parsing, text matching)?

One other common method for internationalization is the open source "gettext" framework. I saw that in the open source game "Battle for Wesnoth" which uses an XML like language "WML" combined with LUA for writing extensions/addons and the core system is written in C++.

For this framework unicode is a dependency i think, which is also on the wishlist ;)

Meanwhile localization will be implememted into FG API a will try the "stringcontrol template" approach combined with an "onDesktopInit" translation of all strings within the databasenodes , as DrZeuss allready suggested in his post.
I will do that for Pathfinder ruleset because its under OGL and there is allready a german PRD avaible in the internet, so translation will be mostly yust a copy & paste task for me :)

My opinion is that for storry telling games like RPG games it is big feature to have the ability to play it in your native language. At moment there is not one VTT framework on the market which supports that! So i hope that this task in the wishlist of FG2 will be realized as soon as possible so FG will be the first (and only?) VTT system which supports localization ...

regards
drvolk

drvolk
January 29th, 2013, 13:43
Is there a limitation for changing the text which will be display for emtpy lists in a <windowlist> control (like in the partysheet of 3.5E ruleset) ?
I can change the text within the <empty><text>..</text></empty> tag in the windowlist control (template list_ps) on initialization (e.g. when in the onInit() of the windowlist), but the display allways shows the initial value of that tag (while in Debug.console(windowlist.empty[1].text[1]) the new text is shown ...).

For <windowlists> there is also no "getValue" or "setValue" method, with which i can change the value of <empty> tags in other controls.

Moon Wizard
January 31st, 2013, 19:08
The empty string for lists is relatively new, and it can only be set via XML at this time. It's the same behavior as the stringcontrol and formattedtextcontrol empty strings which have been around for a while.

We'll have to add as a feature request at this point.

Regards,
JPG