jurialmunkey / script.skinvariables

A helper script for Kodi skinners to construct multiple variables
GNU General Public License v3.0
37 stars 16 forks source link

Asking for guidance. #31

Closed JayDee696969 closed 8 months ago

JayDee696969 commented 9 months ago

Good morning jurial, Im really trying to implement this feature in the Xonfluence skin and I am having a hard time. Xonfluence skin: https://github.com/bartolomesoriano/skin.xonfluence. So I successfully created the skinviewtypes.json (Attached) skinviewtypes.json I added the onload to home.xml, and the script successfully created the script-skinviewtypes-includes.xml. Its the last part that Im having an issue with. Im not exactly sure which skin related visibility conditions I should be changing. For example I have tried many different combinations.. <visible>Control.IsVisible(501)</visible> to: <visible>$EXP[Exp_View_501]</visible>, along with all the other viewtypes in the skin.. <visible>Control.IsVisible(501) + [Container.Content(Movies) | Container.Content(Sets)]</visible> to: <visible>$EXP[Exp_View_501] + [Container.Content(Movies) | Container.Content(Sets)]</visible> Then theres other ones like. <visible>!Control.HasFocus(503)</visible>, I changed to <visible>!$EXP[Exp_View_503]</visible> Im doing something wrong, because the viewtypes look all messed up after I make the edits. Mainly the places where I have found viewtype options are ViewsVideoLibrary.xml, DialogVideoInfo.xml, MyVideoNav.xml. Can you give me any pointers or suggestions as to what Im doing wrong? Ive made shortcuts to the commands to run the view changer. That all works, just the views are messed up looking. Thanks. I would appreciate any help.

jurialmunkey commented 9 months ago

You should only use the $EXP conditions and no other visibility. <visible>$EXP[Exp_View_501]</visible>

Every single one of your view ID controls (the ones that go in <views> tags) absolutely must use the corresponding expression for visibility. If you have even one that has an additional visibility condition not controlled by the script then it won't work correctly.

That's because it works on the idea that if all views are not visible except the desired one then it forces Kodi to use that particular view (because there's no others that can be visible).

e.g. say the user chooses view 51 via the script to be the view they want for Container.Content(movies) then that means the script will set !Container.Content(movies) for view 52, 53, 54 etc. -- that way the only possibility when movies is content is 51

All the rules should for each view should be defined in skinviewtypes.json in the rules section. The rules determine which viewtypes are made available to the user under which conditions. The script will then handle the rest in terms of figuring out the visibility conditions for each view ID.

That also means that all you views need to be defined in skinviewtypes.json -- you cannot have a single view that is not managed via the script.

I hope that makes sense.

jurialmunkey commented 9 months ago

As an example this is wrong:

<visible>$EXP[Exp_View_501] + [Container.Content(Movies) | Container.Content(Sets)]</visible>

IT must be only <visible>$EXP[Exp_View_501]</visible>

You then define the availability in the skinviewtypes.json rules for each content type:

"rules": {
        "movies": {
            "rule": "Container.Content(movies)",
            "viewtypes": ["501", "502"],
            "library": "501",
            "plugins": "501"
        },
        "sets": {
            "rule": "Container.Content(sets)",
            "viewtypes": ["501", "503"],
            "library": "501",
            "plugins": "501"
        },

In the above rules, 501 is allowed to be selected for either movies or sets (because it is listed in the "viewtypes" for those rules).

501 is also the default view for both movies and sets in both the library and all plugins (because 501 is set as the "library" and "plugins" value for each rule)

Additionally, the above allows the user to change the view to 502 for movies (because the movies "viewtypes" rule also lists 502) and to 503 for sets (because the tvshows "viewtypes" rule also lists 503).

JayDee696969 commented 9 months ago

Thank you!! I definitely was leaving some views out that I didnt care about setting a specific view for. Now I have a better idea, and will have to find every view in the skin and be sure they are all added to the .json. Thanks for the pointers. I will attempt again.

JayDee696969 commented 9 months ago

Ok, so Ive added all viewtypes in the skin to skinveiwtypes.json. Now the next question. Im still a little confused on exactly where througout the skin I need add the $EXP[Exp_View_XXX] to which lines. Do I need to focus on only viewtypes that I have made rules for in the .json? Or is it necessary to find all lines that have a mention of a view id even if I dont create a rule for? For example a 450 View seems to be a view for myfavorites.xml. Is that something I would need to switch to $EXP[Exp_View_450]? Even if im not setting rules for this? The lines seem to get a little confusing. For example <visible>Integer.IsGreater(Container(450).NumItems,8)</visible> or is it only: <visible>!Control.HasFocus(450)</visible> I need to change?

jurialmunkey commented 9 months ago

You don't need to use it in every window, but if you use SkinVariables to manage a view within a window then you must use it for all <views> in that window to work.

e.g. You can still leave it to Kodi to manage views in MyFavourites or MyPVRGuide etc., but if you use SkinVariables to manage a view in MyVideoNav then all of the <views> IDs used in MyVideoNav must be managed via SkinVariables with rules.

Generally you will want to use it for MyVideoNav, MyMusicNav, MyPrograms and MyPics as those reuse views.

The visibility should go into the view itself e.g.

<control type="list" id="50">
    <visible>$EXP[Exp_View_50]</visible>
    [...]
</control>

You do not need to touch any other visibility conditions, just the view itself needs to have its visibility controlled. Then all other conditions like Control.HasFocus(50) or Control.IsVisible(50) will still work elsewhere.

jurialmunkey commented 9 months ago

It might help to understand how the script works if you look at the includes file Arctic Fuse generates by default https://gist.githubusercontent.com/jurialmunkey/0432c4c5307022d9c8769f0712ef2387/raw/30e260772dd198a6203246aaf9ea3db27258a9ad/script-skinvariables-includes.xml

This is created via this rules file using the default values https://github.com/jurialmunkey/skin.arctic.fuse/blob/omega/shortcuts/skinviewtypes.json

For example you can see view ID 56 is currently set only for songs in both library and plugins so it ends up generating the expression as such:

<expression name="Exp_View_56">[[Container.Content(songs) + [[String.IsEmpty(Container.PluginName)] | [!String.IsEmpty(Container.PluginName)]]]]</expression>

If the user were to change the view for songs in the library to be 500, but leave it as 56 for plugins then you would end up with

<expression name="Exp_View_56">[[Container.Content(songs) + [[!String.IsEmpty(Container.PluginName)]]]]</expression>
<expression name="Exp_View_500">[[Container.Content(songs) + [[String.IsEmpty(Container.PluginName)]]]]</expression>

Basically the script sets {rule} + [{library} | [{plugins}]]

Where:

In the includes file above you can see how that plays out for a view ID set where there are multiple rules that are true

It basically follows this pattern [{rule_a} + [{library} | [{plugins}]] | [{rule_b} + [{library} | [{plugins}]] | [{rule_c} + [{library} | [{plugins}]] etc.

JayDee696969 commented 9 months ago

Ok, so for something like this: <visible>![Control.IsVisible(500) | Control.IsVisible(732)]</visible> Would this be correct? <visible>![$EXP[Exp_View_500] | $EXP[Exp_View_732]>

JayDee696969 commented 9 months ago

Or this: <visible>Container.Content(Episodes) + !Control.IsVisible(515) + Skin.HasSetting(EpisodeBackground) + !String.IsEqual(ListItem.Label,..)</visible>

I suppose would be this?:
<visible>!$EXP[Exp_View_515] + Skin.HasSetting(EpisodeBackground) + !String.IsEqual(ListItem.Label,..)</visible>

JayDee696969 commented 9 months ago

Ehhhh, forget it. Tried for days. Ill never get it right. Too many various visibility conditions to figure out which ones I need to edit. I failed, lol. Thanks anyways.

jurialmunkey commented 9 months ago

You're massively over complicating it. You don't need to replace my visibility anywhere except for the list itself.

Eg control type="list" with id="50" should have the visibility condition from the expression (and no other conditions). Everywhere else you leave the visibility alone as control.isvisible(50) will still work.

JayDee696969 commented 9 months ago

control type="list"

You're massively over complicating it. You don't need to replace my visibility anywhere except for the list itself.

Eg control type="list" with id="50" should have the visibility condition from the expression (and no other conditions). Everywhere else you leave the visibility alone as control.isvisible(50) will still work.

Hmm, Ok. Ill try again. I think it just threw me off because I would think every viewtype would havecontrol type="list" called out, but doing a search only comes up with some of the viewtypes....

Screenshot_2
jurialmunkey commented 8 months ago

There's other types of list e.g. panel, fixedlist, wraplist as well that you would need to check for. But also looking at those results, there's a bunch of those you probably don't need to touch like Weather and PVR and Playlist Editor

Open MyVideoNav.xml and look at the <views> line. This will list all the view IDs that you need to update.

Then you just need to find those view IDs and update/change/add visibility conditions so that their visibility is controlled via the script expressions. e.g.

<control type="list" id="50">
    <visible>$EXP[Exp_View_50]</visible>
    [...]
</control>

...

<control type="fixedlist" id="501">
    <visible>$EXP[Exp_View_501]</visible>
    [...]
</control>

etc.

You don't need to touch visibility conditions anywhere else in the skin. It is just the list/panel/fixedlist/wraplist itself which should have visibility controlled by the script. Then all your other visibility conditions will still work as normal.

jurialmunkey commented 8 months ago

Example -- please read comment above first For example for xonfluence (not sure if there's a newer version of the skin but this is the one from Helly's repo)

These are the views for MyVideoNav so you should focus on finding these views and replacing their visibility conditions https://github.com/Helly1206/skin.xonfluence/blob/52844a477e5ef143b964e79cf8323a9fc823b9f4/xml/MyVideoNav.xml#L5

<views>50,51,500,732,724,550,551,560,501,508,504,503,515,505,511</views>

It looks like the includes for where these views are, are listed below in the file: https://github.com/Helly1206/skin.xonfluence/blob/52844a477e5ef143b964e79cf8323a9fc823b9f4/xml/MyVideoNav.xml#L15-L45

First a simple one For e.g. CommonListView is the include for id="50" in that skin which is here: https://github.com/Helly1206/skin.xonfluence/blob/52844a477e5ef143b964e79cf8323a9fc823b9f4/xml/ViewsFileMode.xml#L7

Since the list doesn't have any visibility conditions, all you need to do is add it and that's it

<control type="list" id="50">
    <visible>$EXP[Exp_View_50]</visible>

Now a more complex one For e.g. PosterWrapView 501 you can find that here https://github.com/Helly1206/skin.xonfluence/blob/52844a477e5ef143b964e79cf8323a9fc823b9f4/xml/ViewsVideoLibrary.xml#L14-L16

You can see that originally it had visibility conditions:

<control type="fixedlist" id="501">
    <visible>Container.Content(Movies) | Container.Content(Seasons) | Container.Content(TVShows) | Container.Content(Sets)</visible>
    <visible>!Container.Content(LiveTV)</visible>

So you replace these with the expression

<control type="fixedlist" id="501">
    <visible>$EXP[Exp_View_501]</visible>

Those original conditions should then be which rules you add the view to as an option e.g. you would add 501 to the list of views for movies, for seasons, for tvshows, and for sets.

BTW The !Container.Content(LiveTV) part actually did nothing so you simply remove that part. However, if it were actually doing something the way to transform it to a rule is simply to not add that view ID to rules about livetv

JayDee696969 commented 8 months ago

Ok, I will have another go. Appreciate it. As linked in the first comment the more updated skin im using is here, but probably very similar if not the same.. https://github.com/bartolomesoriano/skin.xonfluence.

JayDee696969 commented 8 months ago

OMG, Im making progress!!!

JayDee696969 commented 8 months ago

Ok, having some issues. My viewtypes are looking good now without the distortion I saw before. But, seems like its not choosing the view I select in the runscript(script.skinvariables,action=buildviews,configure) dialog. For example if I choose Commonrootview (50) for a viewtype for files, the actual viewtype presents as (500) Thumbnailpreview when browsing TMDBH root. They dont match up to what im selecting. Looking at the generated script-skinviewtypes-includes.xml. I was under the impression if a view is called out in one of the rules in the.json then it should show [True] in the includes.xml correct? Along with the content rules. Some do, some dont. If you look at a snippet of my .json these views have rules called out, but shows [False] in the includes. Screenshot_11 Screenshot_10 skinviewtypes.json

jurialmunkey commented 8 months ago

For example if I choose Commonrootview (50) for a viewtype for files, the actual viewtype presents as (500) Thumbnailpreview when browsing TMDBH root. They dont match up to what im selecting.

That's because that's not the content type. Menus are not files.

You can check the content type of a container by using $INFO[Container.Content]

In this case the content type is none - i.e. Container.Content() - which you do not have a rule for so you get weird behaviour. You need to have a rule for all content types.

I was under the impression if a view is called out in one of the rules in the.json then it should show [True] in the includes.xml correct?

Incorrect.

The include condition will be [False] if the view is not being used by the user. It will only be [True] if it has been selected as a view either by the user or because it is the default and the user did not change it.

The point is that only views actually being used are included. The idea is that this helps performance because Kodi is not loading includes it doesnt need and isn't evaluating code which is never used.

skinviewtypes.json

Your file looks good but it is missing a few rules for some content types:

Container.Content()
Container.Content(actors)
Container.Content(countries)
Container.Content(directors)
Container.Content(games)
Container.Content(playlists)
Container.Content(recordings)
Container.Content(roles)
Container.Content(songs)
Container.Content(studios)
Container.Content(tags)
Container.Content(videoversions)
Container.Content(years)

Also these two rules about tvshow/season episode groups will be a problem because you only have a rule for not equal but no complimentary rule for when it is equal -- so if you have a tvshow or season with episode groups then it will not be displayed as there is no possible valid rule

"!String.IsEqual(Container.Property(param.info),episode_groups) + Container.Content(tvshows)"
"!String.IsEqual(Container.Property(param.info),episode_group_seasons) + Container.Content(seasons)"
JayDee696969 commented 8 months ago

Thanks again for the tips. The not having a "None" did fix part of the problem. Now Im kinda rethinking things and have a question. My goal is simply to control the views for addons only. (Movies, TV Shows, Seasons, episodes). Im not really interested in Kodi library views. Can I remove the "library" lines from the rules or does it need to be there? Or would it not make sense since the container is used for both anyway?

JayDee696969 commented 8 months ago

Ok, I give up. Im tapping out. Movie views keep defaulting to 500 (Thumbnail). No matter what I choose for the view. Thanks for your help anyway.

JayDee696969 commented 8 months ago

Jurial!!!! I did it!!! I did it!!! I didnt give up, and I read and re-read your tips and learned more and more how everything works and finally nailed it. All views are working and selectable. Thank you soo much for your very useful tips. I really appreciate it.

JayDee696969 commented 8 months ago

Ok, maybe just one last thing you can help me with.. So now that I have the viewtypes working, I would like to make the configuration dialog open onclick when I click the view: in the left sideblade. I figured it out by finding the button id in MyVideoNav.xml, and added the line <onclick>runscript(script.skinvariables,action=buildviews,configure)</onclick>. So it looks like this: (See Screenshot) Now this works as it should, but can I narrow down the viewtypes dialog to filter the list depending on the current container? For example if I am in a movies container I would like the dialog to only show Runscript(script.skinvariables,action=buildviews,contentid=movies). Can you help me with the correct <onclick>XXXX</onclick> that could work? Or is there more to it? Thanks!

Screenshot_2 Screenshot_3

JayDee696969 commented 8 months ago

Ok, maybe not. Comparing other skins, it looks like there might be more to it like adding some includes lines also. Ill keep trying...

jurialmunkey commented 8 months ago

For example if I am in a movies container I would like the dialog to only show Runscript(script.skinvariables,action=buildviews,contentid=movies)

Assuming that your contentid rule names match the Container.Content() name then simplest way is to use a variable which either returns the container.content if not empty, or none if it is -- e.g.

Runscript(script.skinvariables,action=buildviews,contentid=$VAR[Items_ViewMode_Switch],pluginname=$INFO[Container.PluginName])

Then you would define the variable like:

<variable name="Items_ViewMode_Switch">
        <value condition="!String.IsEmpty(Container.Content)">$INFO[Container.Content]</value>
        <value>none</value>
    </variable>

You can also see how I handle some more advanced rules using this same approach here: https://github.com/jurialmunkey/skin.arctic.fuse/blob/1d5c13d188231d97336bea5e49c3e497ebad9410/1080i/Includes_Items.xml#L12-L24

JayDee696969 commented 8 months ago

Ok, I did try this and seems to do exactly what I was looking for.. Runscript(script.skinvariables,action=buildviews,contentid=movies,pluginname=plugins) Would there be some negative effect by doing it this way? *EDIT, nevermind, seems to only show movies container..

JayDee696969 commented 8 months ago

Now would the proper xml to put the Items_ViewMode_Switch code be Includes.xml, or IncludesVariables.xml?

JayDee696969 commented 8 months ago

Got it! Made me realize I had missed a few more visible conditions..

JayDee696969 commented 8 months ago

Ok, nearly done. One issue Im having is the root of addon browser comes up blank. Sections like Video addons, Program, and music addons sections in addonbrowser show normally using direct shortcuts. Now you said earlier "You can check the content type of a container by using $INFO[Container.Content]". Im using the standard debugging="true" in addon.xml to see what window I am in, but cant see the container content. Can you elaborate a little on where I put the $INFO[Container.Content] line to see this? And where does it show? Does it show next to the debugging info? Im so close to finishing this, and testing all functions. Thanks!

JayDee696969 commented 8 months ago

Lol, figured it out... I had a rule for none-videos, but didnt have a rule for just none "rule": "Container.Content()",