The Wiki pages for Skin SDK will be updated soon with all the details, but in the meantime i thought i should provide some info, regarding the changes and additions that have been provided in VirtualDJ 2020 (and a few Builds before that)
Vector graphics
<button>s, <visual>s, <slider>s etc can have vector graphics instead of pointing to an area in the png. This can significantly reduce the size of the png file, with lots of benefits.
For <up>,<off>,<on>,<selected>,<overselected>,<down>,<downselected> etc. instead of using x="" y="", use ..
shape="square|circle" (default shape is square if not defined), color="" (the fill color of the shape), border="" (color of the border), border_size (size of the border), radius="" (amount of pixels to create smooth edges), gradient="horizontal|vertical|circular" (to create a gradient fill - requires color2=""), color2="" (the 2nd /end color if gradient is used)
Example 1 - Button
Round knob
Button - Icons
Also <icon sysicon=""> can take coloroff, colorselected,colorover etc.
So..
Lines
You can draw lines using the following code and make sure they will retain their small height/width, even if the skin gets resized (versus using <square>) ..
..or drop a shadow ..
large Texture - skin Background
If you need to draw a large background in the skin and fill it with a texture/pattern (like a noise, a metal- or wood-style pattern etc), you dont have to include the entire area in your png, just the part that gets repeated.
or use <background>...
the <off repeat="true"> is the texture in your png that will fill the entire visual area. The (optional) canstretch="true" in the example above, may help in cases the visual covers up the entire skin (incl the browser area), and you want it to stretch/resize along with the entire skin, below the browser area).
Color defines/shortcuts
You can define your colors , even change the default/pre-defined ones like red, blue etc, and later use their color names in your xml. VDJ will look into defines and replace the provided value whenever a color is called by a name.
You can also have different colors (with the same name) for different decks.
The color shortcut names as defined, can be called with all skin parameters that expect a color value to be provided.
Placeholders
Those are working as shortcuts that will be replaced when the class (<define>) is called. The big advantage in this syntax is that when you call the class, you can define the placeholders in a single line without adding its children.
Example:
The placeholders can have a default value, so that you dont always have to define when you call the class.
E.g.
In this case when the class is called in your XML, if you dont define width="", then it will use the default value 50.
Placeholders can also have a * before the name. In this case, it indicates that the placeholder value you provide later when you call the class, will not replace the entire value in <define>, but only part of it.
E.g.
and later call as ..
VU meters
New <visual type="vumeter">. Define each <led> of the VU meter in vector, as a nested skin element, same as you do with other skin elements
More sysicons
sysicon= "settings"| "headphones"| "arrowup"| "arrowdown"| "arrowleft"| "arrowright"| "chevronleft" | "chevronright"| "chevrondown"| "chevronup"
Vector graphics
<button>s, <visual>s, <slider>s etc can have vector graphics instead of pointing to an area in the png. This can significantly reduce the size of the png file, with lots of benefits.
For <up>,<off>,<on>,<selected>,<overselected>,<down>,<downselected> etc. instead of using x="" y="", use ..
shape="square|circle" (default shape is square if not defined), color="" (the fill color of the shape), border="" (color of the border), border_size (size of the border), radius="" (amount of pixels to create smooth edges), gradient="horizontal|vertical|circular" (to create a gradient fill - requires color2=""), color2="" (the 2nd /end color if gradient is used)
Example 1 - Button
<button action="loop">
<size width="70" height="44"/>
<off radius="6" border_size="2" border="black" color="#2F3034" />
<over radius="6" border_size="2" border="black" color="#2C3B47" />
<down radius="6" border_size="2" border="black" color="#1287E0"/>
<selected radius="6" border_size="2" border="black" color="#1287E0"/>
<text size="15" color="#909090" align="center" weight="bold" text="LOOP"/>
<textover size="15" color="#BBBBBB" align="center" weight="bold" text="LOOP"/>
<textdown size="15" color="white" align="center" weight="bold" text="LOOP"/>
<textselected size="15" color="white" align="center" weight="bold" text="LOOP"/>
</button>
Round knob
<slider action="eq_high" frommiddle="true" orientation="round" relative="no" >
<pos x="400" y="200"/>
<size width="48" height="48"/>
<off width="40" height="40" shape="circle" color="#3a3b3e" color2="#252628" gradient="vertical" border="#1e1e20" border_size="2"/>
<fader color="#aaaaaa" width="3" height="17" radius="2" anglemin="-150" anglemax="150"/>
<fill width="48" height="48" radius="18" color="blue" backcolor="#232323"/>
</slider>
Button - Icons
Also <icon sysicon=""> can take coloroff, colorselected,colorover etc.
So..
<button action="play_button">
<up color=""/>
<over color=""/>
<icon sysicon="play_button" width="30" height="30" coloroff="white" colorover="#909090"/>
</button>
Lines
You can draw lines using the following code and make sure they will retain their small height/width, even if the skin gets resized (versus using <square>) ..
<line x="195" y="40" width="140" height="2" color="red"/>
..or drop a shadow ..
<line x="195" y="40" width="140" height="4" highlight="#101010" shadow="#707070"/>
large Texture - skin Background
If you need to draw a large background in the skin and fill it with a texture/pattern (like a noise, a metal- or wood-style pattern etc), you dont have to include the entire area in your png, just the part that gets repeated.
<visual canstretch="true">
<pos x="0" y="0"/>
<size width="1920" height="1080"/>
<off x="46" y="262" width="50" height="50" repeat="true"/>
</visual>
or use <background>...
<background x="1817" y="0" width="100" height="100" repeat="true" condition="var_equal '@$colorscheme' 0"/>
<background x="1817" y="210" width="100" height="100" repeat="true" condition="var_equal '@$colorscheme' 1"/>
the <off repeat="true"> is the texture in your png that will fill the entire visual area. The (optional) canstretch="true" in the example above, may help in cases the visual covers up the entire skin (incl the browser area), and you want it to stretch/resize along with the entire skin, below the browser area).
Color defines/shortcuts
You can define your colors , even change the default/pre-defined ones like red, blue etc, and later use their color names in your xml. VDJ will look into defines and replace the provided value whenever a color is called by a name.
<define color="buttonred" value="#ff0000"/>
<define color="buttonblue" value="#3776C7"/>
....
<button ...>
..
<on color="buttonblue" ..>
</button>
You can also have different colors (with the same name) for different decks.
<define color="textdeck" value="#2e80a7" deck="left"/>
<define color="textdeck" value="#d74344" deck="right"/>
The color shortcut names as defined, can be called with all skin parameters that expect a color value to be provided.
Placeholders
Those are working as shortcuts that will be replaced when the class (<define>) is called. The big advantage in this syntax is that when you call the class, you can define the placeholders in a single line without adding its children.
Example:
<define class="button_main" placeholders="width,height,text,important,textaction,sysicon,iconsize">
<size width="[WIDTH]" height="[HEIGHT]"/>
<off color="coloroff1" color2="coloroff2" gradient="vertical" shape="square" radius="5" border="bordercolor" border_size="1" />
<over color="colorover" shape="square" radius="5" border="bordercolor" border_size="1" />
<selected color="coloron1" color2="coloron2" gradient="vertical" shape="square" radius="5" border="bordercolor" border_size="1" />
<down color="coloron1" color2="coloron2" gradient="vertical" shape="square" radius="5" border="bordercolor" border_size="1" />
<text size="16" weight="bold" color="textdark" align="center" action="[TEXTACTION]" text="[TEXT]" important="[IMPORTANT]"/>
<textover size="16" color="textbright" align="center" weight="bold" action="[TEXTACTION]" text="[TEXT]" important="[IMPORTANT]"/>
<textselected size="16" color="textwhite" align="center" weight="bold" action="[TEXTACTION]" text="[TEXT]" important="[IMPORTANT]"/>
<textdown size="16" color="textwhite" align="center" weight="bold" action="[TEXTACTION]" text="[TEXT]" important="[IMPORTANT]"/>
<icon sysicon="[SYSICON]" coloroff="textdark" colorover="textbright" colordown="textwhite" colorselected="textwhite" width="[ICONSIZE]" height="[ICONSIZE]" />
</define>
<!-- and later call .. -->
<button class="button_main" x="+0" y="+0" width="64" height="35" action="cue_button" textaction="cue_button" important="true" />
<button class="button_main" x="+75" y="+0" width="64" height="35" sysicon="play_button" iconsize="32" action="play_button"/>
<button class="button_main" x="+75+75" y="+0" width="64" height="35" action="sync" text="SYNC" important="true"/>
<button class="button_main" x="+75" y="+100" width="40" height="40" action="loop_out" text="OUT" important="true"
The placeholders can have a default value, so that you dont always have to define when you call the class.
E.g.
<define class="my_tall_button" placeholders="width,height=50,text">....
In this case when the class is called in your XML, if you dont define width="", then it will use the default value 50.
Placeholders can also have a * before the name. In this case, it indicates that the placeholder value you provide later when you call the class, will not replace the entire value in <define>, but only part of it.
E.g.
<define class="my_pad" placeholders="*width="98",action,rightclick,textaction,visualsource,visualvisibility">
<button action="[ACTION]" rightclick="[RIGHTCLICK]">
<pos x="+0" y="+0"/>
<size width="[WIDTH]" height="24"/>
.....
</button>
<square x="+[WIDTH]/4-1" y="+2-1" width="[WIDTH]/2+2" height="2+2" color="black" visibility="[VISUALVISIBILITY]"/>
<visual type="color" source="[VISUALSOURCE]" visibility="[VISUALVISIBILITY]">
<pos x="+[WIDTH]/4" y="+2" width="[WIDTH]/2" height="2"/>
</visual>
</define>
and later call as ..
<panel class="my_pad" x="+0" y="+0" width="80" action="pad 1" rightclick="padshift 1" textaction="pad 1" visualsource="pad_color 1" visualvisibility="pad_color 1 ? true"/>
VU meters
New <visual type="vumeter">. Define each <led> of the VU meter in vector, as a nested skin element, same as you do with other skin elements
<visual type="vumeter" x="200" y="250" width="16" height="100" source="get_level" smooth="true" >
<led x="+0" y="+80" width="16" height="18">
<off color="gray" radius="2" border="black" border_size="1"/>
<on color="green" radius="2" border="black" border_size="1"/>
</led>
<led x="+0" y="+60"width="16" height="18">
<off color="gray" radius="2" border="black" border_size="1"/>
<on color="green" radius="2" border="black" border_size="1"/>
</led>
<led x="+0" y="+40" width="16" height="18">
<off color="gray" radius="2" border="black" border_size="1"/>
<on color="green" radius="2" border="black" border_size="1"/>
</led>
<led x="+0" y="+20" width="16" height="18">
<off color="gray" radius="2" border="black" border_size="1"/>
<on color="orange" radius="2" border="black" border_size="1"/>
</led>
<led x="+0" y="+0" width="16" height="18">
<off color="gray" radius="2" border="black" border_size="1"/>
<on color="red" radius="2" border="black" border_size="1"/>
</led>
</visual>
More sysicons
sysicon= "settings"| "headphones"| "arrowup"| "arrowdown"| "arrowleft"| "arrowright"| "chevronleft" | "chevronright"| "chevrondown"| "chevronup"
Posté Wed 25 Sep 19 @ 3:58 pm
condition
Works like visibility, so it takes a VDJ script action that returns true|false. It's much faster than the visibility in terms of skin refreshing/loading, but the skin has to be reloaded in order the condition to work. Condition can be added to all skin elements and in most of the nested children.
Example of applications buttons (min, max, close etc) when computer is Mac or Windows.
nbdecks
You can now define the number of the used decks in your skin using the <nbdecks> tag
Note that the nbdecks value defines how many "Load On Deck x " you will have in your Browser menu, along with the amount of decks (hidden or visible) that the automatic loading will use. However, the total amount of available decks will be also determined from the amount of decks that your connected hardware is offering. E.g. If you have nbdecks="2" but your controller is offering 4 hardware layers/decks, you will still get 4 decks available to load, so in this case, you should create a deck="left/right" skin and not a deck="1|2"
Custom Icons
Custom Icons can be in separate file (and include in your skin zip) and can have more than one and load depending on some condition.
granularity
In case you are using graphics for VU meters, you can now add granularity="". Just count how many "leds" your graphics offer for the VU meter and add as value for the granularity="". If provided, VDJ will do the math and will offer some color between the off and the on for the top/last led, instead of drawing just part of it
Example from Pro 2020 skin with 13 leds for Master VU meter
available (for panels in group)
You have now the ability to set some panels of the same group as (not) available. By default (if not used) panels will be available.
When a panel is not available (has available="no"), it will not be visible if you cycle through the group using skin_panelgroup 'nameofGroup" +1.
You can use the action skin_panelgroup_available 'nameofGroup' to get a menu of all the panels and let the user decide which panels will be available or you can use available="somescript" instead of yes/no and programmatically set it from somewhere else.
Use the displayname="" parameter to set the name that the panel will have in the menu
Will be adding more, but feel free to ask any questions.
Works like visibility, so it takes a VDJ script action that returns true|false. It's much faster than the visibility in terms of skin refreshing/loading, but the skin has to be reloaded in order the condition to work. Condition can be added to all skin elements and in most of the nested children.
Example of applications buttons (min, max, close etc) when computer is Mac or Windows.
<group name="applicationbuttons" condition="is_pc">
....
</group>
<group name="applicationbuttons" condition="is_mac">
...
</group>
nbdecks
You can now define the number of the used decks in your skin using the <nbdecks> tag
<nbdecks value="2" condition="var_equal '@$4decks' 0"/>
<nbdecks value="4" condition="var_not_equal '@$4decks' 0"/>
Note that the nbdecks value defines how many "Load On Deck x " you will have in your Browser menu, along with the amount of decks (hidden or visible) that the automatic loading will use. However, the total amount of available decks will be also determined from the amount of decks that your connected hardware is offering. E.g. If you have nbdecks="2" but your controller is offering 4 hardware layers/decks, you will still get 4 decks available to load, so in this case, you should create a deck="left/right" skin and not a deck="1|2"
Custom Icons
Custom Icons can be in separate file (and include in your skin zip) and can have more than one and load depending on some condition.
<customicons file="icons.png" iconsize="64" nb="144" nbx="16" condition="var '@$defaulticons' ? false : var_equal '@$lightmode' 0"/>
<customicons file="whiteicons.png" iconsize="64" nb="144" nbx="16" condition="var '@$defaulticons' ? false : var_equal '@$lightmode' 1"/>
granularity
In case you are using graphics for VU meters, you can now add granularity="". Just count how many "leds" your graphics offer for the VU meter and add as value for the granularity="". If provided, VDJ will do the math and will offer some color between the off and the on for the top/last led, instead of drawing just part of it
Example from Pro 2020 skin with 13 leds for Master VU meter
<visual source="get_vu_meter_right 'master'" type="linear" orientation="horizontal" granularity="13">
<pos x="+55" y="+15"/>
<size width="70" height="4"/>
<on x="1669" y="0"/>
<off x="1669" y="15" condition="var_not_equal '@$colorscheme' 2"/>
<off x="1669" y="30" condition="var_equal '@$colorscheme' 2"/>
</visual>
available (for panels in group)
You have now the ability to set some panels of the same group as (not) available. By default (if not used) panels will be available.
When a panel is not available (has available="no"), it will not be visible if you cycle through the group using skin_panelgroup 'nameofGroup" +1.
You can use the action skin_panelgroup_available 'nameofGroup' to get a menu of all the panels and let the user decide which panels will be available or you can use available="somescript" instead of yes/no and programmatically set it from somewhere else.
<panel name="fx1" group="effects" visible="yes" available="yes" displayname="Single FX">
Use the displayname="" parameter to set the name that the panel will have in the menu
Will be adding more, but feel free to ask any questions.
Posté Wed 25 Sep 19 @ 4:36 pm
With the vumeter code, I assume you can just list as many leds as you want in the ladder?
Yes
Is there an option to show bouncing peaks?
No you still have to do it the old way (as an overlay)
Yes
Is there an option to show bouncing peaks?
No you still have to do it the old way (as an overlay)
Posté Wed 25 Sep 19 @ 5:10 pm
groovindj wrote :
Is there an option to show bouncing peaks?
No you still have to do it the old way (as an overlay)
Is there an option to show bouncing peaks?
No you still have to do it the old way (as an overlay)
This was the first question in my mind.
@DJDad:
Thanks for sharing these infos here.
Posté Wed 25 Sep 19 @ 5:25 pm
Maybe Atomix can add that vumeter has a condition peaks colour="white" and maybe a decay timing? It would make things easier...
Posté Wed 25 Sep 19 @ 5:50 pm
djdad wrote :
condition
Works like visibility, so it takes a VDJ script action that returns true|false. It's much faster than the visibility in terms of skin refreshing/loading, but the skin has to be reloaded in order the condition to work. Condition can be added to all skin elements and in most of the nested children.
Example of applications buttons (min, max, close etc) when computer is Mac or Windows.
Works like visibility, so it takes a VDJ script action that returns true|false. It's much faster than the visibility in terms of skin refreshing/loading, but the skin has to be reloaded in order the condition to work. Condition can be added to all skin elements and in most of the nested children.
Example of applications buttons (min, max, close etc) when computer is Mac or Windows.
<group name="applicationbuttons" condition="is_pc">
....
</group>
<group name="applicationbuttons" condition="is_mac">
...
</group>
is the a condition possible like is 64bit / 32bit? Some textfield like songtime/remain are to big sized at 64bit mode
Posté Sat 28 Sep 19 @ 1:01 pm
No, there's not such action currently
Posté Sun 29 Sep 19 @ 8:41 pm
get_hwnd ? true x86 : false x64
Posté Mon 30 Sep 19 @ 5:52 am
djnice :o) wrote :
....
is the a condition possible like is 64bit / 32bit? Some textfield like songtime/remain are to big sized at 64bit mode
is the a condition possible like is 64bit / 32bit? Some textfield like songtime/remain are to big sized at 64bit mode
I suppose its not the case for the new VDJ 2020 skin, right ?
For Custom skins, prefer to use fontsize (new in VDJ 2020) so,
<text fontsize="" .../> instead of size
, but keep in mind that you will probably need to change values too, so for Arial, size="13" is almost fontsize="10"
The fontsize parameter will secure that texts get displayed with the same size in all Win 32, 64 and Mac platforms.
Posté Mon 30 Sep 19 @ 4:16 pm
"quote=locodog]get_hwnd ? true x86 : false x64[/quote"
Lovely hack,
Nobody noticed this bug
Lovely hack,
Nobody noticed this bug
Posté Mon 30 Sep 19 @ 5:40 pm
Would be fine placeholders interpret bacquoted strings
<define class="myclass" placeholders="*myplaceholder=0">
...
</define>
...
<panel class="myclass" myplaceholder="`get_var $myvar`" />
<define class="myclass" placeholders="*myplaceholder=0">
...
</define>
...
<panel class="myclass" myplaceholder="`get_var $myvar`" />
Posté Thu 17 Oct 19 @ 7:13 am
it would be nice to have the vu_meter also for the samples..
Posté Sun 03 Nov 19 @ 10:47 am
This should work already:
get_vu_meter "sampler"
get_vu_meter "sampler"
Posté Sun 03 Nov 19 @ 10:52 am
Hi
I've been trying to make a modification to the default skin and need to move the jogwheel spinners when the 'videomixer' panel is visable. I've noticed the default skin uses "pos" with a condition to move aspects of the skin around so thought I'd have a go.
I've tried
"<panel name="jogwheels">
<pos x="+0" y="+0" condition="not skin_pannel 'videomixer'"/>
<pos x="+0" y="-20" condition="skin_panel 'videomixer'"/>
....
</panel>"
however it doesn't work, other conditions like checking variables etc seem to move the panel fine just not when checking the visibility of a skin_panel, so how does "condition" differ from "visibility" in this case.
I'm a javascript/php programmer so I am probable doing something very simple wrong here with the syntax but any help would be appreciated.
Thanks
I've been trying to make a modification to the default skin and need to move the jogwheel spinners when the 'videomixer' panel is visable. I've noticed the default skin uses "pos" with a condition to move aspects of the skin around so thought I'd have a go.
I've tried
"<panel name="jogwheels">
<pos x="+0" y="+0" condition="not skin_pannel 'videomixer'"/>
<pos x="+0" y="-20" condition="skin_panel 'videomixer'"/>
....
</panel>"
however it doesn't work, other conditions like checking variables etc seem to move the panel fine just not when checking the visibility of a skin_panel, so how does "condition" differ from "visibility" in this case.
I'm a javascript/php programmer so I am probable doing something very simple wrong here with the syntax but any help would be appreciated.
Thanks
Posté Sat 30 Nov 19 @ 2:56 pm
djkrysr wrote :
Hi
"<panel name="jogwheels">
<pos x="+0" y="+0" condition="not skin_pannel 'videomixer'"/>
<pos x="+0" y="-20" condition="skin_panel 'videomixer'"/>
....
</panel>"
"<panel name="jogwheels">
<pos x="+0" y="+0" condition="not skin_pannel 'videomixer'"/>
<pos x="+0" y="-20" condition="skin_panel 'videomixer'"/>
....
</panel>"
Conditions are only "read" at skin-reload. (think of this as somewhat similar to doc ready in javascript world)
Since switching to video mixer doesnt reload the skin, try with visible instead of condition for the <panel> (think of this as visibility style tag, in javascript/css logic)
Posté Sat 30 Nov 19 @ 3:33 pm
Hi
Thanks for the info.
I am already using visibility queries but was hoping to avoid duplicating the <panel> for each visibility condition just to place them in a different position, however loving the new skin additions in 2020.
Thanks for the info.
I am already using visibility queries but was hoping to avoid duplicating the <panel> for each visibility condition just to place them in a different position, however loving the new skin additions in 2020.
Posté Sat 30 Nov 19 @ 4:43 pm
Hello,
the placeholder in define doesn't accept "format=" for textzones. Is this a bug?
for example:
<define class="text17" placeholders="width,height,text,important=true,textaction,weight=bold,textdx,textdy,fontsize,align=center",textformat>
<size width="[WIDTH]" height="[HEIGHT]"/>
<text fontsize="17" weight="[WEIGHT]" color="textcolorgrey" format="[TEXTFORMAT]" align="[ALIGN]" action="[TEXTACTION]" text="[TEXT]" localize="true" important="[IMPORTANT]" scroll="no"/>
</define>
Next question:
What do important & localize?
Offtopic question:
Is there a way to reset the %counter without restart Virtual DJ?
best regards DennYo
EDIT: I found a solution for the placeholder problem. I delete the placeholder action="[textaction]" an now it works.
the placeholder in define doesn't accept "format=" for textzones. Is this a bug?
for example:
<define class="text17" placeholders="width,height,text,important=true,textaction,weight=bold,textdx,textdy,fontsize,align=center",textformat>
<size width="[WIDTH]" height="[HEIGHT]"/>
<text fontsize="17" weight="[WEIGHT]" color="textcolorgrey" format="[TEXTFORMAT]" align="[ALIGN]" action="[TEXTACTION]" text="[TEXT]" localize="true" important="[IMPORTANT]" scroll="no"/>
</define>
Next question:
What do important & localize?
Offtopic question:
Is there a way to reset the %counter without restart Virtual DJ?
best regards DennYo
EDIT: I found a solution for the placeholder problem. I delete the placeholder action="[textaction]" an now it works.
Posté Sun 09 Feb 20 @ 3:18 pm
Denny F. wrote :
What do important & localize?
If you use localize="true" and text="My Text" then in a language XML file, it will search for <mytext>My Text</mytext> node under <skin> node and will replace the text with the translated text.
So, if it finds <mytext>Κείμενο</mytext> it will display Κείμενο instead of MyText if the language file is selected.
If important="true" is used then the size of the text will not have linear resize when you down-resize the skin. If size="20" would become normally 10 if you resize at 50%, it will probably become something like 12 or so, so "important" texts will be still readable.
Denny F. wrote :
Is there a way to reset the %counter without restart Virtual DJ?
Not using any action, but you could try .. <textzone resetcounter="true">
From Wiki http://www.virtualdj.com/wiki/Skin%20SDK%20Textzone.html : resetcounter : if set to "true", the counter will be reset if this textzone is clicked
Posté Sun 09 Feb 20 @ 4:30 pm
Hello djdad,
thanks for the fast awnser. resetcounter works :)
have a nice sunday
thanks for the fast awnser. resetcounter works :)
have a nice sunday
Posté Sun 09 Feb 20 @ 5:01 pm
Forgot the latest additions though ;)
BUILD 5522 (2020-02-06)
-stopwatch and stopwatch_reset actions
BUILD 5522 (2020-02-06)
-stopwatch and stopwatch_reset actions
Posté Sun 09 Feb 20 @ 5:05 pm