Closed nico1080 closed 3 years ago
What you describe is the natural consequence of the procedural flow the code must go through following the addition of callback functions (to replace the previous "special treatment"). It really has nothing to do with sharing of elements across layouts.
If the name of the entry matches that for a callback function, then the callback function has full responsibility for what then happens.
If this post explains things adequately, please feel free to close the issue.
For concreteness, here's the structure that now exists within text_fields()
:
# Check for any defined callback functions. If an entry
# exists in the lookup table, invoke the specified function
# with all of the arguments discussed in earlier comments.
if field_info["name"] in ELEMENT_CB:
# ... invoke ELEMENT_CB function ...
elif field_info["name"] in STRING_CB:
# ... invoke STRING_CB function ...
else:
if (field_info["name"] in info.keys() and
info[field_info["name"]] != ""):
# Use format_str or prefix/suffic approach, in that order
if field_info.get("format_str", ""):
display_string = format_InfoLabels(
field_info["format_str"], info, screen_mode, layout_name)
else:
display_string = (field_info.get("prefix", "") +
info[field_info["name"]] +
field_info.get("suffix", ""))
Only the final else
makes use of format_str
or prefix
and suffix
.
One change I can make is to change the conditional that is used within that final else
above...
Right now, an element's name has to either match some existing InfoLabel key or be the name identifying a callback function to use. That test against the InfoLabel keys could be dropped when a format_str
is present. That would permit more generic names for entries within the fields
array for every layout.
Right now, an element's name has to either match some existing InfoLabel key or be the name identifying a callback function to use.
See if commit b970a648350a20b288f41f56cfb580cc4f911534 helps at all...
Entries within the fields
array for a layout that specify a format_str
can now have any name, so long as it doesn't collide with an entry in the callback tables. Non-colliding entries with a format_str
always get that string evaluated and, if that results in something non-empty, the result gets displayed.
Entries that have a name corresponding to an InfoLabel still get processed only if that InfoLabel is non-empty. (I have plans to add an exclude
option for handling things like the "00" ChannelNumber you mentioned in discussions.)
Even with the above change, it is still the case that using a name
that matches a callback function leaves that callback function "fully in charge" of what happens next. (For element callbacks that want to draw or render something directly, it made no sense even to attempt using them for string interpolation. For string callbacks, one can now have the field
array entry named anything you like and just invoke the string callback via format_str
.)
Commit 50bce995b2ab3c891df3bc423e78242855bcf74c updates all of the example setup files to explain the available 'name' options for entries in the fields
array of each layout, as well as the restriction that exists on the use of format_str
.
Here is the new text that starts out the Audio Screens comment block:
# Entries within the "fields" array generally correspond to text
# fields, but the introduction of the ELEMENT_CB lookup table (if
# customized) does permit for additional graphical elements. Such
# customization does require a bit of Python programming.
#
# Note that the available InfoLabels can be augmented via use of
# the AUDIO_LABELS list (see earlier in this file).
#
# Each entry must have a 'name' key that corresponds to ONE of
# the following:
#
# - Exactly matching one of the InfoLabels retrieved from Kodi.
# Such entries are only rendered if the corresponding InfoLabel
# is non-empty.
#
# - One of the callback functions named in either the ELEMENT_CB
# table or the STRING_CB table. That string matching triggers
# execution of the corresponding callback function.
#
# - An arbitrary string, not matching an InfoLabel or any callback
# function names, provided that the entry ALSO specifies a
# 'format_str' key.
#
# The execution path followed by any of the above naming choices is
# typically expected to yield a text string to display. Remaining
# keys that control the rendering of that text are as follows:
The format_str
description now reads:
# format_str Alternatively, rather than using prefix and suffix,
# and if one is NOT triggering a callback function, a
# formatting string can be specified. The string
# should contain one or more InfoLabels to substitute,
# enclosed within curly braces. See the status layout
# screen text fields for examples.
#
# Terms to be substituted can also make use of any
# entries defined within the string-manipulation
# callback table (see the STRING_CB dictionary in
# kodi_panel_display.py)
Hopefully those changes clarify things a little. If not, please respond. I'll close this issue if I don't hear from you in a few days.
I realized that I left out the option of using a newly-introduced shared element. So, the "each entry must ..." text is being updated to read
# Unless making use of a shared element, each entry must have a
# 'name' key that corresponds to ONE of the following:
Commit 50bce99 updates all of the example setup files to explain the available 'name' options for entries in the
fields
array of each layout, as well as the restriction that exists on the use offormat_str
.Here is the new text that starts out the Audio Screens comment block:
# Entries within the "fields" array generally correspond to text # fields, but the introduction of the ELEMENT_CB lookup table (if # customized) does permit for additional graphical elements. Such # customization does require a bit of Python programming. # # Note that the available InfoLabels can be augmented via use of # the AUDIO_LABELS list (see earlier in this file). # # Each entry must have a 'name' key that corresponds to ONE of # the following: # # - Exactly matching one of the InfoLabels retrieved from Kodi. # Such entries are only rendered if the corresponding InfoLabel # is non-empty. # # - One of the callback functions named in either the ELEMENT_CB # table or the STRING_CB table. That string matching triggers # execution of the corresponding callback function. # # - An arbitrary string, not matching an InfoLabel or any callback # function names, provided that the entry ALSO specifies a # 'format_str' key. # # The execution path followed by any of the above naming choices is # typically expected to yield a text string to display. Remaining # keys that control the rendering of that text are as follows:
The
format_str
description now reads:# format_str Alternatively, rather than using prefix and suffix, # and if one is NOT triggering a callback function, a # formatting string can be specified. The string # should contain one or more InfoLabels to substitute, # enclosed within curly braces. See the status layout # screen text fields for examples. # # Terms to be substituted can also make use of any # entries defined within the string-manipulation # callback table (see the STRING_CB dictionary in # kodi_panel_display.py)
Hopefully those changes clarify things a little. If not, please respond. I'll close this issue if I don't hear from you in a few days.
To be sure to understand: Shared elements don't need a name field if they have a format_str field If a shared element have a name field, matching a callback function it will display the callback function ( format_str , preffix/suffix ignored) like any field
fields within layout (= not Shared elements) need to have a name. depending of the names:
It is a bit difficult to follow of the possibilities :)
Shared elements don't need a name field if they have a format_str field
Not quite. The new documentation was meant to provide guidance solely on the contents with a layout's fields
array.
The definition of entries within the shared_element
table is exactly what an earlier comment block dictates. Shared elements get dropped into a layout table exactly as they are written. So, if a shared element is supposed to be dropped into the fields
array for a layout, then that shared element must have a name
, because every entry within fields
must have a name.
In contrast if the shared element is, say, a progress bar, then no name
is needed for that (since the prog
entry at the top-level of a layout never needs a name
).
(As an aside, there are presently just 3 "top-level" entries possible for a layout:
thumb
(cover art)prog
(progress bar)background
(your suggestion)Everything else is an entry within the fields
array. There likely is little need to continue having thumb
and prog
be top-level entries. They could likely be folded into the fields
array as well, but doing so might break existing setup.toml files. There likely aren't that many users at present, but it's nice not to surprise people.)
If a shared element have a name field, matching a callback function it will display the callback function ( format_str , preffix/suffix ignored) like any field
Entries within the fields
array always need a name
. If that name
matches a callback function, then that function is what gets invoked.
Per my first statements above, shared elements might or might not need a name
-- it depends upon where the end-user intends on making use of them.
fields within layout (= not Shared elements) need to have a name. depending of the names:
if name match an infolabel (and that infolabel is not empty) it will display prefix/infolabel/suffix+label or format_str+label
Correct.
if name match callback function it will display callback function+label (format_str ignored)
Correct. The label is suppressed if the callback function returns an empty string.
If name match nothing (custom name) it will display format_str+label( prefix/suffix ignored)
Correct.
Originally, a name
had to exactly match an InfoLabel (aside from the hard-coded special treatment names). The resulting string was then exactly that InfoLabel, provided it was non-empty. That was the extent of the original functionality.
Then the prefix
and suffix
functionality got added. The InfoLabel still had to be non-empty in order for the prefix and suffix to be employed.
Subsequent to that, I figured out how to make format_str
work. With format strings, prefix
and suffix
already get ignored (why use those, when the user can just specify that text as part of the format_str
itself).
Even though a format_str
could make use of any InfoLabel for substitution, having the entry still carry a name
was still useful -- the specified InfoLabel could be checked to see if it was non-empty.
The most recent change to the code just permits an entry that has a format_str
to use any name
it wants. That might be useful if you have a format_str
that contains multiple distinct InfoLabels and always want it rendered.
It is a bit difficult to follow of the possibilities :)
I think things can be distilled to the following points:
All entries within a layout's fields
array need a `name. That name can be:
ELEMENT_CB
or STRING_CB
tables; orformat_str
that is always to be rendered.Shared elements are a "substitution game".
fields
entry that wants to make use of a shared element does so via a shared_element
key; this is the only time an fields
entry does not need to specify a name
, since that key is assumed to come from the shared element that gets substituted.The main use cases for the fields
array are still
Commit e078b4d4836a600dbc977104879bcb1d4c663d1e has another update to the example setup files.
The documentation now reads:
# All entries in the "fields" array" MUST have a name (either
# specified explicitly or inherited from a shared element
# reference). The 'name' key corresponds to ONE of the following:
#
# - An exact match for one of the InfoLabels retrieved from Kodi.
# The entry is only rendered if the corresponding InfoLabel is
# non-empty.
#
# - An exact match for one of the callback functions named in the
# ELEMENT_CB table or the STRING_CB table. That match triggers
# execution of the corresponding callback function.
#
# - An arbitrary string (not matching an InfoLabel or any callback
# function names), provided that the entry ALSO specifies a
# 'format_str' key. The interpolated format_str always gets
# rendered.
Very clear, I am closing this issue as it is just a mis understanding of the functions.
When using the format_str to display a "special treatment" if the name match the special treatment the format_str will not be used eg:
will display the acodec result --> format_str not work
But if I change the name to any info label:
It will display acodec result + test --> format_str works