PDA

View Full Version : Parse control info tag


DanTm
2005-05-10, 17:08
been searching for it, but could not find a solution for it yet, should be easy to implement.

the info tag from the the label control now only takes one infoitem, e.g. musicplayer.artist. it would be nice to be able to supply more than one item and fixed characters.
something like <info>[musicplayer.artist] - *[musicplayer.title]</info>

this would be easily achieved using a regularexpression which matches some trigger sequence (like [<something>]) and replaces it with the prober value.

another solution to achieve the same (but probably more difficult to implement) is to be able to attach a control to the side of another control (so when the size of the 1st control changes, the attached control will reposition).

last but not least multiple info tags (like in the fadelabel) could be rendered behind eachother (so the above example would become <info>musicplayer.artist</info><info> - </info><info>musicplayer.title</info>). this would probably be the easiest to implement (no regex stuff).

jmarshall
2005-05-10, 18:19
i've been thinking on this for quite a while, but have yet to come up with an ideal solution (both simple from the skinners point of view and the code point of view).

remember that we need localisation, so any additional strings must be localizable (ie can be references into strings.xml). this tends to complicate things somewhat.

i guess the easiest to implement would be the one where it's all in one tag, with pieces of information that xbmc should replace being contained in some predefined delimiters (eg square brackets as you indicate). i don't think using <blah> is valid, as the xml parser will screw up with that. either that, or we use something like + between each expression that requires concating together.

i think it's essential to have some form of delimiter as it makes it so much easier (and quicker) to produce the format string needed in the end.

comments/opinions are most welcome :)

cheers,
jonathan

DanTm
2005-05-10, 18:46
you could just treat anything between the delimeters as parsable, either an info string (musicplayer.foo) or a string id that can be localised (localize.155 or something).

so you could make something like:
<info>[localize.654321] [queue.currenttrack] [localize.1234567] [queue.totaltracks]</info>

which would render into:
track 6 of 18

my c++ is a bit rusty.. but in c# it would be something like
public string parseinfotag(string infotag)
{
system.text.stringbuilder newline = new system.text.stringbuilder(infotag);

if (expression.indexof('[') > -1)
{
system.text.regularexpressions.regex r = new system.text.regularexpressions.regex(@"\[([\w\d\./]*(\(\))?(\([\d]+\))?(\(""[^""]*""\))?)*(\[[^\[\]] *\])*\]", system.text.regularexpressions.regexoptions.ignore case | system.text.regularexpressions.regexoptions.compil ed );
system.text.regularexpressions.match m;

string field;
for ( m = r.match( expression ); m.success; m = m.nextmatch() )
{
if (m.groups[0].length > 0)
{
field = m.groups[0].tostring().substring(1,m.groups[0].len gth-2);
string result = "";
if (field.tolower().startswith("localize.")
{
//localize whats behind localize.
result = "foo";
}
else
{
//try to parse e.g. musicplayer.album
result = "foo";
}
newline.replace(m.groups[0].tostring(),result);
}
}
}
return newline.tostring();

}

never mind the regex.. i copied some code from a project i work on.. it matches with 'most' stuff between [].. *and some other criteria.. but reading back a regex i created like a year ago is too much work for now:)

we use it for similar purposes, where the parsable parts are executed using reflection on an object, so you only have to define properties or methods on a 'scripting' object that you want to expose, and execute them using reflection. no need to manually parse items anymore. instead of [localize.1234] you could use [localize(1234)], where you have a function localize(string id) exposed as public on the scripting object. nyway.. i have enough c# code for that around here:)

maybe if i'm in the mood for it i'll try to install vs2003 and get some xbmc code... and look at it.. but since i'm already programming all day.. i can't promise nything

-edit-
i forgot.. unmanaged c++ doesn't support reflection.. nyway.. solutions enough i think

DanTm
2005-05-11, 23:35
i made a very small patch for my own use by copying some code from the fadelabel (for handling multiple info tags).
then while rendering i loop over the info id's and concat a string using a default seperator (' - ') in this case...

in cguilabelcontrol:


void cguilabelcontrol::render()
{
*if (m_vecinfo.size())
*{
*// check if we need to update our info
*wstring strlabel ( l"" );
*for (unsigned int i = 0; i < m_vecinfo.size(); i++)
*{
*int m_info = m_vecinfo[i];
*wstring labelpart = g_infomanager.getlabel(m_info);
*if (strlabel.length())
*{
*strlabel.append(l" - ");
*}
*strlabel.append(labelpart);
*}

* *if (strlabel != m_strlabel)
setlabel(strlabel);
*}

if anyone is interested in the other neccessary code changes let me know.. i think it's all a bit too small to be really benificial.. but i like that i now have: musicplayer.year - musicplayer.album on one row, and musicplayer.time - musicplayer.duration on another...

i'll now see if i can implement a localize.<stringid> info tag in order for me to use any seperator (or localized text) i like..

but i have to admit... damn.. unmanaged c++ sucks big time.. i'm glad i program c# during the day

kraqh3d
2005-05-12, 00:43
why not extend the label tag to accept more than one info and/or label tag? the system should concatenate them in the order they are found.

<type>label</type>
<info>musicplayer.artist</info>
<label> - </label>
<info>musicplayer.album</info>

and as dantm says, this is already very similar to how the fadelabel works.

alternatively, the xml could be something like this:

<type>label</type>
<concat>
<info>musicplayer.artist</info>
<label> - </label>
<info>musicplayer.album</info>
</concat>

to denote which pieces to concatenate. then this could even be ported into a fadelabel too.

<type>fadelabel</type>
<concat>
<info>musicplayer.artist</info>
<label> - </label>
<info>musicplayer.album</info>
</concat>
<concat>
<info>musicplayer.time</info>
<label>/</label>
<info>musicplayer.duration</info>
</concat>

DanTm
2005-05-12, 00:54
i now have it working like this:

* *<control>
* * *<description>time</description>
* * *<type>label</type>
* * *<id>1</id>
* * *<visible>player.hasaudio</visible>
* * *<posx>640</posx>
* * *<posy>436</posy>
* * *<info>musicplayer.time</info>
* * *<info>15215</info>
* * *<info>musicplayer.duration</info>
* * *<align>right</align>
* * *<font>font10</font>
* *</control> *

where 15214 is an id in the string db so localisation works..
it shows something like 2:13 / 14:18
but any string could be put in the concatenation.. there are still a few problems.. leading and trailing spaces are removed from the localization strings, so i hardcoded a space inbetween all concatenations.

the other problem is that it always shows the localized strings, even if no music is playing. gonna look into that now, probably the visible tag is not getting parsed properly (or not used at all, who knows).

jmarshall
2005-05-12, 00:55
i kinda like the second idea - much more xml-ish, though order is still important.

replace <concat> with <combinedinfo> and we're all rosy i think.

cheers,
jonathan

DanTm
2005-05-12, 01:05
pictures:

http://www.inden.demon.nl/screenshot000.jpg

and

http://www.inden.demon.nl/screenshot002.jpg

DanTm
2005-05-12, 01:58
after some checking i noticed that conditional visibility is not present in the labelcontrol (only in image and edit?).. so i copied it from image to labelcontrol..

but shouldn't it be in the base control class so all controls automagically benefit from it?

DanTm
2005-05-12, 11:21
i put a patch up on sourceforge for those interested:

patch 1200420 (http://sourceforge.net/tracker/index.php?func=detail&aid=1200420&group_id=87054&atid=581840)

pike
2005-05-12, 16:41
great, lets hope a dev agress and adds it to cvs if it's a cool ™ patch ;)

DanTm
2005-05-12, 16:50
great, lets hope a dev agress and adds it to cvs if it's a cool ™ patch ;)
i think it needs some more working to be cool :)
it works as it is, but it's not a perfect solution.. it's more the idea...
but i'm pretty sure a dev can do it a lot quicker than that i have to look to pages of unfamiliar coding using unfamiliar libraries.

DanTm
2005-05-13, 14:14
ok.. i'm busy making some changes, the old patch will be discarded, the new format will be as following:

use a <label> tag to specify what you want to see and put the infotags numbered into the label (or the localized string).

an example will be better:)

* *<control>
* * *<description>time</description>
* * *<type>label</type>
* * *<id>1</id>
* * *<visible>player.hasaudio</visible>
* * *<label>[1] / [2]</label>
* * *<posx>640</posx>
* * *<posy>446</posy>
* * *<info>musicplayer.time</info>
* * *<info>musicplayer.duration</info>
* * *<align>right</align>
* * *<font>font10</font>
* *</control> * *

it will parse the info tags into the label. i still have to test it, but when its working i will put up a new (updated) patch.

gr.
dan