0 votes
by (300 points)

Hey everyone,

I have a question regarding the Settings API in Sugarcube.

var settingTest = ["Default", "500","1000" ];
var settingTestHandler = function () {
    var test = State.variables.test;
    switch (settings.Test123){
      case "Default":
        break;
      case "500":
        test = test+500;
        break;
      case "1000":
        test =test+1000;
        break;
    }
    State.variables.test = test;
};
​
var settingCheatHandler = function () {
  if (settings.Cheats) { // is true
    if (typeof settings.Test123 == 'undefined'){
    Setting.addList("Test123", {
    label    : "Test ",
    list     : settingTest,
  default  : "Default",
    onInit   : settingTestHandler,
    onChange : settingTestHandler
});
    };
    Setting.save();
  }
  else { // is false
    if (typeof settings.Test123 !== 'undefined'){
    delete settings.Test123;
    Setting.save();
  };
    };
};
​
Setting.addToggle("Cheats", {
  label : "Enable cheats?",
  default  : false,
  onInit   : settingCheatHandler,
  onChange : settingCheatHandler
});

I'm trying to hide the Test123 setting List in the setting menu when settings.Cheats is false. Is there any way this is possible? I have tried deleting the Test123 property from settings, but this does not seem to work.

 

Is there a way to delete a setting?

Thanks in advance

1 Answer

+1 vote
by (159k points)
selected by
 
Best answer

If you defined the following two settings...

var settingCheatHandler = function () {
	/* Cheat handler code will go here. */
};

Setting.addToggle("Cheats", {
	label : "Enable cheats?",
	default  : false,
	onInit   : settingCheatHandler,
	onChange : settingCheatHandler
});


var settingTest = ["Default", "500","1000" ];
var settingTestHandler = function () {
    var test = State.variables.test;
    switch (settings.Test123){
      case "Default":
        break;
      case "500":
        test = test+500;
        break;
      case "1000":
        test =test+1000;
        break;
    }
    State.variables.test = test;
};
Setting.addList("Test123", {
    label    : "Test ",
    list     : settingTest,
	default  : "Default",
    onInit   : settingTestHandler,
    onChange : settingTestHandler
});

... and then used your web-browser's built-in Web Developer Tools to Inspect the HTML elements that are generated when the Settings Dialog is displayed you will see that the outter structure looks something like the following...

<div id="ui-dialog-body" class="settings">
	<div id="setting-body-cheats">
		/* HTML used to represent this setting's interface. */
	</div>
	<div id="setting-body-test123">
		/* HTML used to represent this setting's interface. */
	</div>
	<ul class="buttons">
		/* HTML used to show the buttons. */
	</ul>
</div>

... and you will notice that each setting within the dialog has been wrapper within a HTML div element that has been assigned a unique ID attribute that is based on the name of the setting's identifier. You can use these IDs to manipulate the HTML element's properties.

1. Define a CSS class like the following in your project's Story Stylesheet area, it will be used to 'hide' unwanted settings.

.hidden {
	display: none;
}

2. Change the settingCheatHandler within your project's Story Javascript area to apply/remove the new CSS class as required.

var settingCheatHandler = function () {
	if (settings.Cheats) {
		/* Reveal any 'hidden' settings. */
		$('#setting-body-test123').removeClass('hidden');
	}
	else {
		/* 'hide' settings as required. */
		$('#setting-body-test123').addClass('hidden');
	}
};

At this point you can view the Settings Dialog and use the Cheats setting to toggle the visibility of the other setting(s). There is still one more issues to solve, the initial visibility state of the Cheat related settings when the dialog is first opened.

There is an undocumented :dialogopen event that is sent every time a SugarCube Dialog is opened which you can monitor. If you associate a event handler with this event then you can check which CSS class has been assigned to the #ui-dialog-body element to determine which of the core dialogs have been opened.

The following example can be added to your project's Story Javascript area, it monitors for the event and hides the required settings if Cheats is disabled.

/* Monitor for when the Settings dialog is opened. */
$(document).on(':dialogopen', function () {
    setTimeout(function () {
		if ($('#ui-dialog-body').hasClass('settings')) {
			/* Hide the cheat related settings when required. */
			if (!settings.Cheats) {
				$('#setting-body-test123').addClass('hidden');
			}
		}
	}, Engine.minDomActionDelay);
});

warning: because the above needs to wait until after the HTML elements of the dialog have been rendered before it can modify those element you may notice a brief flicker as the contents of the dialog is updated ot 'hide' the other settings.

by (300 points)
Thanks greyelf!
...