Conditional visibility: Difference between revisions

From Official Kodi Wiki
Jump to navigation Jump to search
>Dankula
mNo edit summary
(20 intermediate revisions by 8 users not shown)
Line 1: Line 1:
==Using the <visible> tag for controls in your skin==
<section begin="main content" />
===Introduction===
All controls benefit from '''conditional visibility''' support. This means that instead of specifying just YES or NO for the <visible> tag, you can provide one of the many preset [[List of Boolean Conditions|boolean conditions]]. Not only that, you can also specify how Kodi should transistion between a visible state and a hidden state.
Recently, we've been modularising much of the code that controls when items should be rendered, and when they should be left as-is.
 
All controls can now benefit from “conditional visibility” support. This means that, instead of specifying just “yes” or “no” for the <visible> tag, you can now provide one of the many preset [[List of Boolean Conditions|boolean conditions]]. Not only that, you can also specify how XBMC should transistion between a visible state and a hidden state.


For example, the Project Mayhem 3 skin has ''<visible>!Player.HasMedia</visible>'' tags on all the background images on the home page. The reason is that we don't want the images being displayed while a media file (audio or video) is playing or paused, as the video or visualisation will cover the images anyway, so they only take up memory unnecessarily. They also slow down navigation, as the need to be loaded/unloaded depending on whether they are visible (ie whether or not the user has a particular button focused).
For example, the Project Mayhem 3 skin has ''<visible>!Player.HasMedia</visible>'' tags on all the background images on the home page. The reason is that we don't want the images being displayed while a media file (audio or video) is playing or paused, as the video or visualisation will cover the images anyway, so they only take up memory unnecessarily. They also slow down navigation, as the need to be loaded/unloaded depending on whether they are visible (ie whether or not the user has a particular button focused).


==How They Work==
== How They Work ==
The condition given in the <visible> tag is evaluated at during the control's Render() function. XBMC decides whether or not the condition is true, and updates the control's visibility accordingly. Thus, it all happens without XBMC having to do the extra chores of maintaining which controls need to be shown at which points in time. The controls automatically update themselves.
The condition given in the <visible> tag is evaluated at during the control's Render() function. Kodi decides whether or not the condition is true, and updates the control's visibility accordingly. So it all happens without Kodi having to do the extra chores of maintaining which controls need to be shown at which points in time. The controls automatically update themselves.


==Conditional Visibility for Dialogs==
== Conditional Visibility for Dialogs ==
Dialogs can also be made to popup automatically based on a visibility condition. This is done by supplying the <visible> tag at the top of the window file (where the <id>, <type> and <coordinate> tags are). XBMC once again evaluates this visibility at render time, and if needbe, will create and show the dialog at the appropriate time. It'll also close them once that visibility has vanished.
Dialogs can also be made to popup automatically based on a visibility condition. This is done by supplying the <visible> tag at the top of the window file (where the <id>, <type> and <coordinate> tags are). Kodi once again evaluates this visibility at render time, and if necessary, will create and show the dialog at the appropriate time. It'll also close them once that visibility has vanished.


This only works with dialogs. For custom windows, you can specify the type of window you require by specifying it using the <type> tag. For more information see the [[Window Structure|window .xml structure page]].
This only works with dialogs. For custom windows, you can specify the type of window you require by specifying it using the <type> tag. For more information see the [[Window Structure|window .xml structure page]].


==[[List of Boolean Conditions]]==
==Combining Conditions==
==Combining Conditions==
You can combine two (or more) of the above settings by using "+" as an AND operator, "|" as an OR operator, “!" as a NOT operator, and "[" and "]" to bracket expressions. For example, <visible>Player.HasVideo + Player.Rewinding8x</visible> will only show the control when the player is rewinding a video at 8x, whereas <visible>Player.HasVideo | Player.IsRecording</visible> will show the control if a video is playing, or if we are recording something. The AND operator takes precedence over the OR operator when evaluating the logic, and operators are read from left to right. So if you want to show something when condition1 OR condition2 is true AND condition3 is true, you can do:
You can combine two (or more) of the above settings by using:
* + as AND operator
* | as OR operator
* ! as NOT operator
* [ and ] to bracket expressions


For example, <visible>Player.HasVideo + Player.Rewinding8x</visible> will only show the control when the player is rewinding a video at 8x, whereas <visible>Player.HasVideo | Player.IsRecording</visible> will show the control if a video is playing, or if we are recording something.
The AND operator takes precedence over the OR operator when evaluating the logic. AND operators are read from left to right.
So if you want to show something when condition1 OR condition2 is true AND condition3 is true, you can do:
<visible>[condition1 | condition2] + condition3</visible>
<visible>[condition1 | condition2] + condition3</visible>


Note that if you missed the brackets, then it would actually be reading «if condition1 or (condition2 and condition3)" due to AND taking precedence over OR.
Note that if you missed the brackets, then it would actually be reading «if condition1 or (condition2 and condition3)" due to AND taking precedence over OR.


Some pointers on boolean logic:
Some pointers on boolean logic.
 
The following holds true:
The following holds true:


A + (B | C) = A + B| A + C<br>
A + (B | C) = A + B | A + C<br />
A | (B + C) = (A | B) + (A | C)<br>
A | (B + C) = (A | B) + (A | C)<br />
<br>
<br />
!(A + B) =! A |! B<br>
!(A + B) =!A | !B<br />
!(A | B) =! A +! B
!(A | B) =!A + !B


A common mistake is to do something like this:
A common mistake is to do something like this:


! A |! B |! C
!A | !B | !C


This is false only if A, B and C are all simultaneously true (as it's the same as !(A + B + C)), and you may have possibly been after
This is false only if A, B and C are all simultaneously true (as it's the same as !(A + B + C)), and you may have possibly been after


! A +! B +! C
!A + !B + !C


which is false if A is true, or B is true, or C is true.
which is false if A is true, or B is true, or C is true.


One thing you will notice, is that when a control is hidden, it can't be focused. This means you can't move to a control and have it automatically become visible (eg even if it had Control.HasFocus(myID) it wouldn't come back on, as XBMC wouldn't allow navigation to the hidden control). To solve this issue, you can use:
One thing you will notice, is that when a control is hidden, it can't be focused. This means you can't move to a control and have it automatically become visible (eg even if it had Control.HasFocus(myID) it wouldn't come back on, as Kodi wouldn't allow navigation to the hidden control). To solve this issue, you can use:
<xml>
<syntaxhighlight lang="xml" enclose="div">
   <visible allowhiddenfocus="true">Control.HasFocus(21)</visible>
   <visible allowhiddenfocus="true">Control.HasFocus(21)</visible>
</xml>
</syntaxhighlight>
on a control of <id> 21. This will allow the control to be focusable even when it's hidden. When the user moves to the hidden control, it will automatically unhide itself, due to the Control.HasFocus(21) visibility condition.
on a control of <id> 21. This will allow the control to be focusable even when it's hidden. When the user moves to the hidden control, it will automatically unhide itself, due to the Control.HasFocus(21) visibility condition.
<section end="main content" />
== See also ==
'''Development:'''
* [[Add-on development]]
* [[Skinning]]


==Specifying the Transition Animation==
[[Category:Skin development]]
You can also specify how XBMC renders the transistion between the hidden and visible states (as well as between other states).
[[Animating Your Skin|See here for how to add animations to your skin.]]

Revision as of 19:19, 13 July 2022

All controls benefit from conditional visibility support. This means that instead of specifying just YES or NO for the <visible> tag, you can provide one of the many preset boolean conditions. Not only that, you can also specify how Kodi should transistion between a visible state and a hidden state.

For example, the Project Mayhem 3 skin has <visible>!Player.HasMedia</visible> tags on all the background images on the home page. The reason is that we don't want the images being displayed while a media file (audio or video) is playing or paused, as the video or visualisation will cover the images anyway, so they only take up memory unnecessarily. They also slow down navigation, as the need to be loaded/unloaded depending on whether they are visible (ie whether or not the user has a particular button focused).

How They Work

The condition given in the <visible> tag is evaluated at during the control's Render() function. Kodi decides whether or not the condition is true, and updates the control's visibility accordingly. So it all happens without Kodi having to do the extra chores of maintaining which controls need to be shown at which points in time. The controls automatically update themselves.

Conditional Visibility for Dialogs

Dialogs can also be made to popup automatically based on a visibility condition. This is done by supplying the <visible> tag at the top of the window file (where the <id>, <type> and <coordinate> tags are). Kodi once again evaluates this visibility at render time, and if necessary, will create and show the dialog at the appropriate time. It'll also close them once that visibility has vanished.

This only works with dialogs. For custom windows, you can specify the type of window you require by specifying it using the <type> tag. For more information see the window .xml structure page.

Combining Conditions

You can combine two (or more) of the above settings by using:

  • + as AND operator
  • | as OR operator
  • ! as NOT operator
  • [ and ] to bracket expressions

For example, <visible>Player.HasVideo + Player.Rewinding8x</visible> will only show the control when the player is rewinding a video at 8x, whereas <visible>Player.HasVideo | Player.IsRecording</visible> will show the control if a video is playing, or if we are recording something.

The AND operator takes precedence over the OR operator when evaluating the logic. AND operators are read from left to right.

So if you want to show something when condition1 OR condition2 is true AND condition3 is true, you can do: <visible>[condition1 | condition2] + condition3</visible>

Note that if you missed the brackets, then it would actually be reading «if condition1 or (condition2 and condition3)" due to AND taking precedence over OR.

Some pointers on boolean logic. The following holds true:

A + (B | C) = A + B | A + C
A | (B + C) = (A | B) + (A | C)

!(A + B) =!A | !B
!(A | B) =!A + !B

A common mistake is to do something like this:

!A | !B | !C

This is false only if A, B and C are all simultaneously true (as it's the same as !(A + B + C)), and you may have possibly been after

!A + !B + !C

which is false if A is true, or B is true, or C is true.

One thing you will notice, is that when a control is hidden, it can't be focused. This means you can't move to a control and have it automatically become visible (eg even if it had Control.HasFocus(myID) it wouldn't come back on, as Kodi wouldn't allow navigation to the hidden control). To solve this issue, you can use:

  <visible allowhiddenfocus="true">Control.HasFocus(21)</visible>

on a control of <id> 21. This will allow the control to be focusable even when it's hidden. When the user moves to the hidden control, it will automatically unhide itself, due to the Control.HasFocus(21) visibility condition.


See also

Development: