Cycle through Layouts

This button lets you cycle through the layouts defined in Preferences / Layouts and Styles / Layouts. It shows the current layout as the label and the next and previous layout from the list as the tooltip. Layouts that sit in folders will be ignored.

Click the button to call the next layout. Hold Shift while clicking to open the previous layout.

2024-06-11 - 13.46.33

The button for Opus 12 has the same functionality but lacks the dynamic info.

The script that runs in the background and supplies the layout info will work for all versions.

// For reference only. Get the fully functional button from below

// ** Opus 12 **

Prefs LAYOUT="{$lst:nextLayout}"

Prefs LAYOUT="{$lst:prevLayout}"

// ** Opus 13 **

@label:cL=Val("$lst:currLayout");Format(original_label, (cL=="" ? "<none>" : cL))
Prefs LAYOUT="{=KeyDown("shift") ? Val("$lst:prevLayout") : Val("$lst:nextLayout")=}"

How to set up and use

:one: Save EventSaveLayoutsAsVars.js.txt to   ↓

%appdata%\GPSoftware\Directory Opus\Script AddIns

:two: Copy-paste the button to any toolbar

Opus 12
<?xml version="1.0"?>
<button backcol="none" display="both" label_pos="right" textcol="none">
	<label>Cycle Layouts</label>
	<tip>Call next layout (Shift to call previous)</tip>
	<function type="normal">
		<instruction>Prefs LAYOUT=&quot;{$lst:nextLayout}&quot;</instruction>
		<instruction />
		<instruction>Prefs LAYOUT=&quot;{$lst:prevLayout}&quot;</instruction>
		<instruction />
Opus 13
<?xml version="1.0"?>
<button backcol="none" display="both" label_pos="right" textcol="none">
	<tip>=Val(&quot;$lst:nextLayout&quot;) + &quot;\n&quot; + Val(&quot;$lst:prevLayout&quot;) + &quot; (Shift)&quot;</tip>
	<function type="normal">
		<instruction>@label:cL=Val(&quot;$lst:currLayout&quot;);Format(original_label, (cL==&quot;&quot; ? &quot;&lt;none&gt;&quot; : cL))</instruction>
		<instruction>Prefs LAYOUT=&quot;{=KeyDown(&quot;shift&quot;) ? Val(&quot;$lst:prevLayout&quot;) : Val(&quot;$lst:nextLayout&quot;)=}&quot;</instruction>
		<instruction />

Things you might enjoy reading

Inspired by Hide Layout Buttons
How to use buttons and scripts from this forum

The script's inner workings

function OnInit(initData) { = 'SaveLayoutsAsVars';
    initData.version = '2024-06-11';
    initData.url = '';
    initData.default_enable = true;
    initData.min_version = '12.0';

function OnActivateLister(activateListerData) {
    if (! return;

    var cmd = DOpus.Create().Command();
    var stt = DOpus.Create().StringTools();
    var vec = DOpus.Create().Vector();
    var fsu = DOpus.FSUtil();

    var lst = activateListerData.lister;

    var xmlOrder = fsu.GetItem(fsu.Resolve('/dopusdata\\Layouts\\order.xml'));
    if (!fsu.Exists(xmlOrder)) return;

    var arr = stt.Decode(xmlOrder.Open().Read(), 'utf8').split('\r\n');

    var re = /.*<layout name="(.*)" \/>.*/;

    for (var i = 0; i < arr.length; i++) {
        var tmp = arr[i].match(re);
        if (!tmp) continue;
        if (tmp.length != 2) continue;
        var layoutName = tmp[1];
        if (!fsu.Exists('/dopusdata\\Layouts\\' + layoutName + '.oll')) continue;

    if (vec.empty) return;

    var currLayout = lst.layout;

    var k = 0;
    for (var i = 0; i < vec.length; i++) {
        if (vec[i] != currLayout) continue;
        k = i;

    var prev = k - 1;
    if (prev < 0) prev = vec.length - 1;

    var next = k + 1;
    if (next == vec.length) next = 0;

    lst.vars.Set('prevLayout', vec[prev]);
    lst.vars.Set('currLayout', currLayout);
    lst.vars.Set('nextLayout', vec[next]);


Looks like the Code for both Opus 12 and Opus 13 is missing. Please check.

Forget my above comment. Now I can see the actual codes. Thanks.

Wow, wow, wow @lxp this is absolutely beyond fantastic :trophy:, I'm literally jumping behind my desk of excitement :smiley: !!! If this is not being served, I don't know what is :smile:

Thank you very much for creating and sharing this impressive work and for all the effort you've put in to it. It's contributions like this that make DOpus even greater and adds new levels to its usability and workflow efficiency.

Hats off to you and a humble jolly big thank you! :slightly_smiling_face:

1 Like

I'm getting the following error. Any ideas?

You might have changed the button's function type.

What should it be set to? It was set to 'standard' - based on your reply I tried changing to script but got the same error.

The button is oven-ready, just copy-paste-enjoy. Which Opus version do you run?

Yes, I pasted it in like I usually do. I'm on 13.6.8 beta.

The type should be set to standard; you definitely wouldn't get that error in that case as script parse errors can only happen with the button set to script mode.

Well, that's current enough :slight_smile:

Does this button work?

<?xml version="1.0"?>
<button backcol="none" display="both" label_pos="right" textcol="none">
	<label>New Button</label>
	<function type="normal">

It doesn't work either.

What happens?

Nothing happens when I click it. Except I get the script error shown above showing in the script log.

As I said, you won't get that script error unless the button type is set as 'script', which it shouldn't be.

If you edit the button does it show that the first line is @script JScript ?
If it does, that is the problem.

Does adding an equals sign make a difference?


I am starting to think it might be an underlying Windows problem :frowning:

I somehow lost my current layout after pressing the first time on the new button.
This layout never came back again when cylcing through all layouts.

I guess, I've not saved my previous into any custom layout so far.

Unfortunately, none of my backups does not restore my previous layout either.

Any chance to find the previous layout somewhere?

Isn't this the default lister? You should be able to get it back by running


Jon, it's set to "Standard Function" but I'm getting the script error each time I click on it.