Kodi Community Forum

Full Version: getControl on control in skin XML?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,
Trying to write a script to modify some controls in a windows defined in the skin (ultimately some sliders, in the manner of this post)

Have a window defined like this:

Code:
<window id="6660">
    <onload>runscript(special://skin/extras/scripts/timeshiftprogress.py)</onload>
    <controls>
        <control type="label" id="6661">
            <top>134</top>
            <left>700</left>
            <width>50%</width>
            <height>60</height>
            <label>XXXX</label>
            <shadowcolor>black</shadowcolor>
        </control>
          ......

The script contains:

Code:
import xbmc
import xbmcgui

w = xbmcgui.WindowDialog(6660)
c = w.getControl(6661)
c.setLabel('hello')

The window comes up and shows the label, the script runs, but Kodi reports
EXCEPTION: Non-Existent Control 6661 in the log. Any existing control id in the XML behaves the same.

Should I be able to do this? I have read hints elsewhere that only script-created controls can be got with getControl; is this the case? (I will try it, anyway)

Curiously, if I try to get the window ID with xbmcgui.Window(6660) it reports a nonexistent window. Not sure if this is a clue (the window actually is a dialog, afaik - it is DialogSeekBar.xml of estuary)
window id's are assigned by kodi, it is not something you can define in the xml file (with the exception of custom skin windows).
a list of window id's can be found in the wiki: http://kodi.wiki/view/Window_IDs

i don't think you can use getControl on skin windows, afaik it will only work on python windows.
you might want to use window properties instead, to set the label value.
I have made some progress, but not everything works - I can get a window based on xbmcgui.getCurrentWindowId() and create labels in it, but not a progress bar. The script is run in the <onload> of the seek bar window in DialogSeekBar.xml.

Code:
import xbmc
import xbmcgui

# These are existing image files in the skin
white50 = 'special://skin/media/colors/white50.png'
white = 'special://skin/media/colors/white.png'

w = xbmcgui.Window(xbmcgui.getCurrentWindowId())

# This works
debugLabel = xbmcgui.ControlLabel(300, 300, 1500, 50, 'Hello')
w.addControl(debugLabel)

# This doesn't work
progressTsEnd = xbmcgui.ControlProgress(100, 300, 1500, 15, texturebg=white50, texturemid=white)
w.addControl(progressTsEnd)
progressTsEnd.setPercent(50)

Curiously, the text label hangs around after the seek bar is unloaded - am I creating a new window here, or obtaining a handle to an existing one?
Plot thickens... getCurrentWindowId() returns 12005 (the fullscreen video) and not the expected 10115 (seek bar). If I create the label control inside window 10115, they don't show up at all.
it's a dialog, so you need to use getCurrentWindowDialogId()
http://mirrors.xbmc.org/docs/python-docs...owDialogId
OK, I'm going down the other route of setting a window property in the script, and retrieving it in the skin xml. So far so good, but I'm stopped on one small point: a progress control wants an integer value (like Player.Progress) and a window property can only be a string. Is is possible to convert it to integer in the xml? Or for a progress bar to be updated by a percentage in a string?
I have also tried creating a new Python window with the progress bar in it. The intention is to slip it between (in zorder) the video window and the OSD, so the OSD buttons can still be used. Creating the new window as a dialog allows it to be above the video (and hence visible) but it seems to sit on top of all the XML dialogs and hence stop all mouse/keyboard events going through to them.

The order should be:

OSD (z=1)
my new window (created as a dialog, so zorder should be 1)
DialogSeekBar (z=0 set in the xml)
video window
base window

but the OSD is getting covered up.
Setting the zorder of the OSD to 2 didn't help. is what I'm trying to do possible? Or do I need to take the whole OSD functionality into my script?
This is the first time I've read about <zorder>.
I usually just z-order them by how they are declared in the xml file.
Controls at the top of the xml file are always below controls that are after it.
I'm not talking about controls within one window though - <zorder> is supposed to set the zorder of a window among other windows. My problem was that Python dialogs always seem to be on top of XML dialogs, even if you give the XML window a higher zorder.
I think you need to create your own custom gui incorporating the base window, video, seek bar and osd in one xml file.
or
yes, find a way to replace the osd window with yours (imitating the looks of the osd + your own progress bar)

even if you find a way to insert your seek bar between the video and osd,
Dialog windows cover the entire screen, they just have a transparent background.
user clicks/activity is not sent to the window below it. (I could be wrong)
Yes I have discovered this about dialogs too, that's why I had hoped to put it beneath the OSD.

I have made progress using a python script to display the existing OSD as an XML window, and adding controls to it. There are bugs(*) to step around but it is basically working now. I'll post the code here when it's better looking and some screenies.

Ran into known bug with the existing slider and Player.Progress (bug tracker #17469) - it's much more obvious with my mod, as the timeshift buffer is shown to scale.

(*) some things found:
- you can't interact with XML controls in python
- progress controls don't display reliably
- python controls don't take the focus

I ended up making my own progress bar out of buttons.