Sampler-focused skin XML examples for building custom panels in a VirtualDJ skin.
This chunk is designed to be pasted inside a deck section such as <deck deck="left">...</deck>. It gives you:
- Current sampler bank display
- Current sampler page display (
1 to 8,9 to 16, etc.) - Bank previous/next buttons
- Page previous/next buttons
- Mode and options buttons
- 8 visible sampler pads that follow the current sampler page
- Empty-pad recording behavior similar to the stock sampler pad page
Use this when you want a skin-native sampler panel instead of relying on the SideView or the deck Pads area.
For the visible sample labels, this chunk uses sampler_pad <n> inside the text format= fields instead of get_sample_name <n>, so the text follows the current sampler page.
Empty-slot guards need separate care: local testing showed sampler_loaded <n> 'auto' can still check the first-page absolute slot. For production skin panels that must hide empty pads on pages 9-16 and later, branch on sampler_pad_page and guard with the absolute slot behind each visible pad.
<deck deck="left">
<panel name="sampler_panel_left" visible="yes">
<group name="sampler_header" x="24" y="24">
<textzone>
<pos x="+0" y="+0"/>
<size width="220" height="20"/>
<text font="Arial" fontsize="14" weight="bold" color="#D7DCE4" text="SAMPLER"/>
</textzone>
<textzone>
<pos x="+0" y="+24"/>
<size width="220" height="22"/>
<text font="Arial" fontsize="15" weight="bold" color="white" format="`get_sampler_bank`"/>
</textzone>
<textzone>
<pos x="+240" y="+24"/>
<size width="120" height="22"/>
<text font="Arial" fontsize="13" align="center" color="#AEB6C2" format="PAGE `sampler_pad_page`"/>
</textzone>
<button action="sampler_bank -1">
<pos x="+0" y="+56"/>
<size width="46" height="26"/>
<up radius="4" border="#4B5563" border_size="1" color="#1F232B"/>
<over radius="4" border="#6B7280" border_size="1" color="#2A3140"/>
<down radius="4" border="#6B7280" border_size="1" color="#394559"/>
<text text="BANK -" align="center" fontsize="11" weight="bold" color="#D7DCE4"/>
</button>
<button action="sampler_bank +1">
<pos x="+52" y="+56"/>
<size width="46" height="26"/>
<up radius="4" border="#4B5563" border_size="1" color="#1F232B"/>
<over radius="4" border="#6B7280" border_size="1" color="#2A3140"/>
<down radius="4" border="#6B7280" border_size="1" color="#394559"/>
<text text="BANK +" align="center" fontsize="11" weight="bold" color="#D7DCE4"/>
</button>
<button action="sampler_pad_page -1">
<pos x="+240" y="+56"/>
<size width="56" height="26"/>
<up radius="4" border="#4B5563" border_size="1" color="#1F232B"/>
<over radius="4" border="#6B7280" border_size="1" color="#2A3140"/>
<down radius="4" border="#6B7280" border_size="1" color="#394559"/>
<text text="PAGE -" align="center" fontsize="11" weight="bold" color="#D7DCE4"/>
</button>
<button action="sampler_pad_page +1">
<pos x="+302" y="+56"/>
<size width="56" height="26"/>
<up radius="4" border="#4B5563" border_size="1" color="#1F232B"/>
<over radius="4" border="#6B7280" border_size="1" color="#2A3140"/>
<down radius="4" border="#6B7280" border_size="1" color="#394559"/>
<text text="PAGE +" align="center" fontsize="11" weight="bold" color="#D7DCE4"/>
</button>
<button action="sampler_mode +1">
<pos x="+380" y="+24"/>
<size width="74" height="26"/>
<up radius="4" border="#4B5563" border_size="1" color="#1F232B"/>
<over radius="4" border="#6B7280" border_size="1" color="#2A3140"/>
<down radius="4" border="#6B7280" border_size="1" color="#394559"/>
<text fontsize="11" align="center" weight="bold" color="#D7DCE4" format="MODE `sampler_mode`"/>
</button>
<button action="sampler_options">
<pos x="+460" y="+24"/>
<size width="76" height="26"/>
<up radius="4" border="#4B5563" border_size="1" color="#1F232B"/>
<over radius="4" border="#6B7280" border_size="1" color="#2A3140"/>
<down radius="4" border="#6B7280" border_size="1" color="#394559"/>
<text text="OPTIONS" align="center" fontsize="11" weight="bold" color="#D7DCE4"/>
</button>
<button action="sampler_output 'popup'">
<pos x="+542" y="+24"/>
<size width="70" height="26"/>
<up radius="4" border="#4B5563" border_size="1" color="#1F232B"/>
<over radius="4" border="#6B7280" border_size="1" color="#2A3140"/>
<down radius="4" border="#6B7280" border_size="1" color="#394559"/>
<text text="OUTPUT" align="center" fontsize="11" weight="bold" color="#D7DCE4"/>
</button>
</group>
<group name="sampler_grid" x="24" y="126">
<button action="sampler_loaded 1 'auto' ? sampler_pad 1 'auto' : sampler_rec 1 'auto'" query="sampler_play 1 'auto'">
<pos x="+0" y="+0"/>
<size width="146" height="64"/>
<off radius="6" border="#3E4552" border_size="1" color="#171A20"/>
<on radius="6" border="#6A7382" border_size="1" color="#253041"/>
<over radius="6" border="#7A8597" border_size="1" color="#2D394D"/>
<down radius="6" border="#7A8597" border_size="1" color="#41506A"/>
</button>
<textzone>
<pos x="+8" y="+10"/>
<size width="130" height="42"/>
<text font="Arial" fontsize="13" multiline="true" align="center" valign="center" color="`sampler_loaded 1 'auto' ? sampler_color 1 'auto' : color '#8993A1'`" format="`sampler_loaded 1 'auto' ? sampler_pad 1 : '(empty 1)'`"/>
</textzone>
<button action="sampler_loaded 2 'auto' ? sampler_pad 2 'auto' : sampler_rec 2 'auto'" query="sampler_play 2 'auto'">
<pos x="+156" y="+0"/>
<size width="146" height="64"/>
<off radius="6" border="#3E4552" border_size="1" color="#171A20"/>
<on radius="6" border="#6A7382" border_size="1" color="#253041"/>
<over radius="6" border="#7A8597" border_size="1" color="#2D394D"/>
<down radius="6" border="#7A8597" border_size="1" color="#41506A"/>
</button>
<textzone>
<pos x="+164" y="+10"/>
<size width="130" height="42"/>
<text font="Arial" fontsize="13" multiline="true" align="center" valign="center" color="`sampler_loaded 2 'auto' ? sampler_color 2 'auto' : color '#8993A1'`" format="`sampler_loaded 2 'auto' ? sampler_pad 2 : '(empty 2)'`"/>
</textzone>
<button action="sampler_loaded 3 'auto' ? sampler_pad 3 'auto' : sampler_rec 3 'auto'" query="sampler_play 3 'auto'">
<pos x="+312" y="+0"/>
<size width="146" height="64"/>
<off radius="6" border="#3E4552" border_size="1" color="#171A20"/>
<on radius="6" border="#6A7382" border_size="1" color="#253041"/>
<over radius="6" border="#7A8597" border_size="1" color="#2D394D"/>
<down radius="6" border="#7A8597" border_size="1" color="#41506A"/>
</button>
<textzone>
<pos x="+320" y="+10"/>
<size width="130" height="42"/>
<text font="Arial" fontsize="13" multiline="true" align="center" valign="center" color="`sampler_loaded 3 'auto' ? sampler_color 3 'auto' : color '#8993A1'`" format="`sampler_loaded 3 'auto' ? sampler_pad 3 : '(empty 3)'`"/>
</textzone>
<button action="sampler_loaded 4 'auto' ? sampler_pad 4 'auto' : sampler_rec 4 'auto'" query="sampler_play 4 'auto'">
<pos x="+468" y="+0"/>
<size width="146" height="64"/>
<off radius="6" border="#3E4552" border_size="1" color="#171A20"/>
<on radius="6" border="#6A7382" border_size="1" color="#253041"/>
<over radius="6" border="#7A8597" border_size="1" color="#2D394D"/>
<down radius="6" border="#7A8597" border_size="1" color="#41506A"/>
</button>
<textzone>
<pos x="+476" y="+10"/>
<size width="130" height="42"/>
<text font="Arial" fontsize="13" multiline="true" align="center" valign="center" color="`sampler_loaded 4 'auto' ? sampler_color 4 'auto' : color '#8993A1'`" format="`sampler_loaded 4 'auto' ? sampler_pad 4 : '(empty 4)'`"/>
</textzone>
<button action="sampler_loaded 5 'auto' ? sampler_pad 5 'auto' : sampler_rec 5 'auto'" query="sampler_play 5 'auto'">
<pos x="+0" y="+76"/>
<size width="146" height="64"/>
<off radius="6" border="#3E4552" border_size="1" color="#171A20"/>
<on radius="6" border="#6A7382" border_size="1" color="#253041"/>
<over radius="6" border="#7A8597" border_size="1" color="#2D394D"/>
<down radius="6" border="#7A8597" border_size="1" color="#41506A"/>
</button>
<textzone>
<pos x="+8" y="+86"/>
<size width="130" height="42"/>
<text font="Arial" fontsize="13" multiline="true" align="center" valign="center" color="`sampler_loaded 5 'auto' ? sampler_color 5 'auto' : color '#8993A1'`" format="`sampler_loaded 5 'auto' ? sampler_pad 5 : '(empty 5)'`"/>
</textzone>
<button action="sampler_loaded 6 'auto' ? sampler_pad 6 'auto' : sampler_rec 6 'auto'" query="sampler_play 6 'auto'">
<pos x="+156" y="+76"/>
<size width="146" height="64"/>
<off radius="6" border="#3E4552" border_size="1" color="#171A20"/>
<on radius="6" border="#6A7382" border_size="1" color="#253041"/>
<over radius="6" border="#7A8597" border_size="1" color="#2D394D"/>
<down radius="6" border="#7A8597" border_size="1" color="#41506A"/>
</button>
<textzone>
<pos x="+164" y="+86"/>
<size width="130" height="42"/>
<text font="Arial" fontsize="13" multiline="true" align="center" valign="center" color="`sampler_loaded 6 'auto' ? sampler_color 6 'auto' : color '#8993A1'`" format="`sampler_loaded 6 'auto' ? sampler_pad 6 : '(empty 6)'`"/>
</textzone>
<button action="sampler_loaded 7 'auto' ? sampler_pad 7 'auto' : sampler_rec 7 'auto'" query="sampler_play 7 'auto'">
<pos x="+312" y="+76"/>
<size width="146" height="64"/>
<off radius="6" border="#3E4552" border_size="1" color="#171A20"/>
<on radius="6" border="#6A7382" border_size="1" color="#253041"/>
<over radius="6" border="#7A8597" border_size="1" color="#2D394D"/>
<down radius="6" border="#7A8597" border_size="1" color="#41506A"/>
</button>
<textzone>
<pos x="+320" y="+86"/>
<size width="130" height="42"/>
<text font="Arial" fontsize="13" multiline="true" align="center" valign="center" color="`sampler_loaded 7 'auto' ? sampler_color 7 'auto' : color '#8993A1'`" format="`sampler_loaded 7 'auto' ? sampler_pad 7 : '(empty 7)'`"/>
</textzone>
<button action="sampler_loaded 8 'auto' ? sampler_pad 8 'auto' : sampler_rec 8 'auto'" query="sampler_play 8 'auto'">
<pos x="+468" y="+76"/>
<size width="146" height="64"/>
<off radius="6" border="#3E4552" border_size="1" color="#171A20"/>
<on radius="6" border="#6A7382" border_size="1" color="#253041"/>
<over radius="6" border="#7A8597" border_size="1" color="#2D394D"/>
<down radius="6" border="#7A8597" border_size="1" color="#41506A"/>
</button>
<textzone>
<pos x="+476" y="+86"/>
<size width="130" height="42"/>
<text font="Arial" fontsize="13" multiline="true" align="center" valign="center" color="`sampler_loaded 8 'auto' ? sampler_color 8 'auto' : color '#8993A1'`" format="`sampler_loaded 8 'auto' ? sampler_pad 8 : '(empty 8)'`"/>
</textzone>
</group>
</panel>
</deck>- The chunk is deck-scoped, so sampler paging and sync stay tied to the deck that contains it.
sampler_pad 1 'auto'throughsampler_pad 8 'auto'follow the current sampler page instead of always hard-targeting slots1-8.sampler_pad_page -1andsampler_pad_page +1move through sample ranges such as1 to 8,9 to 16, and later pages.- Empty pads call
sampler_rec n 'auto'so unlocked banks can record directly from the skin panel, matching the stock sampler workflow. - The visible pad labels come from
sampler_pad <n>in textformat=fields, so the labels follow the current sampler page. query="sampler_play n 'auto'"lights the pad while that visible sample is playing.- Do not treat
sampler_loaded n 'auto'as a reliable page-aware loaded check; use absolute-slot guards such assampler_loaded 16for page 2 pad 8.
If you move this chunk outside a <deck> block, make the pad actions explicit so sync behavior is predictable:
deck active sampler_pad 1 "auto"
deck master sampler_pad 1 "auto"
- Use
deck activeif the sampler should follow the selected/working deck. - Use
deck masterif synced samples should always lock to the current master deck.
If a skin panel needs to follow the current master deck and raw deck master behaves oddly in sampler title or page text, resolve the master deck number explicitly instead of relying on the alias:
<textzone>
<size width="220" height="22"/>
<text font="Arial" fontsize="13" color="#D7DCE4" format="`deck 1 masterdeck ? deck 1 sampler_pad 1 : deck 2 masterdeck ? deck 2 sampler_pad 1 : deck 3 masterdeck ? deck 3 sampler_pad 1 : deck 4 masterdeck ? deck 4 sampler_pad 1 : sampler_pad 1`"/>
</textzone>
<button action="deck 1 masterdeck ? deck 1 sampler_pad_page +1 : deck 2 masterdeck ? deck 2 sampler_pad_page +1 : deck 3 masterdeck ? deck 3 sampler_pad_page +1 : deck 4 masterdeck ? deck 4 sampler_pad_page +1 : sampler_pad_page +1">
<size width="56" height="26"/>
</button>This is heavier than raw deck master, but it avoids the alias in the exact place where sampler title/page text has proven less reliable in recent testing.
If you want a progress bar, add a visual after each button:
<visual source="sampler_position 1" type="linear" orientation="horizontal">
<pos x="+8" y="+54"/>
<size width="130" height="4"/>
<off shape="square" color="#0D0F13"/>
<on shape="square" color="#4E6FA8"/>
</visual>Place it in the same group as the pad and adjust the coordinates to match the pad location.
If you want the classic two-panel workflow:
- Leave the left deck panel on the default
1 to 8. - Put the same chunk on the right deck and either:
- set
samplerSpanAcrossDecks=yes, or - trigger
sampler_pad_page +1once on startup/user action for the right side.
- set
sampler_padandsampler_colorare the safest page-aware helpers for skin-based sampler panels.- In skin text
format=fields,sampler_pad <n>is the safest way to show the currently visible sample name on the active sampler page. deck mastermeans the current master deck, not a separate global sampler scope. In some sampler title/query paths, an explicitdeck 1 masterdeck ? ... : deck 2 masterdeck ? ...resolver is more reliable than rawdeck master.sampler_loaded <n>should be used as an absolute-slot query for row visibility or empty-slot logic. Map the visible page/pad to the real slot first.- If you need fixed absolute slots regardless of the current page, swap
sampler_padforsampler_play, and swap page-aware name/color helpers for absolute ones such asget_sample_name 9andget_sample_color 9. - Duplicate this chunk under
<deck deck="right">if you want a second, independently positioned sampler panel. - Class names are matched case-insensitively in practice. A good convention is
class="SAMPLER_ROW"in<define>andclass="sampler_row"at the call site, while keeping placeholder tokens uppercase, e.g.[INDEX].
- Official Skin SDK overview: Skin SDK
- Official panel syntax: Skin SDK Panel
- Official textzone syntax: Skin SDK Textzone
- Official sampler verbs: VDJScript verbs
- Official sampler pad behavior: Pads manual
- Page-aware custom sampler pad patterns: Custom Sampler Pad Page
- Skin-side sampler naming/color examples: How to read the sample icon in a button?
- Deck-sync guidance for sampler pads: problem with (pad pages) pads sampler sync!
- Master-deck sampler quirks in newer builds: Virtual Dj 2025 Sampler Sync