Scripting question

Moho allows users to write new tools and plugins. Discuss scripting ideas and problems here.

Moderators: Víctor Paredes, Belgarath, slowtiger

Post Reply
User avatar
synthsin75
Posts: 10153
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Scripting question

Post by synthsin75 »

Is there some reason I can't seem to find any tools with tool option radio buttons? I have it working, but for the life of me I can't get AS to remember which one is selected. All the tools I've looked at seem to only use radio buttons in dialogs.

Am I better off using check boxes, and if so, how do make them mutually exclusive like the radio buttons do automatically?
User avatar
heyvern
Posts: 7035
Joined: Fri Sep 02, 2005 4:49 am

Post by heyvern »

For some reason I've never needed to use radio buttons so I don't have a ton of experience with them. What I find is that a SINGLE check box can represent at most TWO radio buttons. If there is only two choices I prefer a single check box with text indicating the choice. this takes less space. If you need more than two choices for an option a set of radio buttons would be needed.

From what I can tell a radio button is EXACTLY the same... exactly the same as a check box in basic true/false functionality. The only difference is that a "group" of radio buttons in sequence when setting up the dialog box that contains them controls how they behave. As long as they aren't separated by another "control" item they work as a unit.

Here is an example from the "Fade" menu script:

These two radio buttons determine weather you want to fade in or fade out. They appear in the dialog together one after the other and that means they work in the same group.

Code: Select all

	d.fadeIn = LM.GUI.RadioButton(MOHO.Localize(HV_radiotest.BASE_STR + 5, "Fade in"))
	l:AddChild(d.fadeIn, LM.GUI.ALIGN_LEFT)
	d.fadeOut = LM.GUI.RadioButton(MOHO.Localize(HV_radiotest.BASE_STR + 6, "Fade out"))
	l:AddChild(d.fadeOut, LM.GUI.ALIGN_LEFT)
A set of radio buttons one after the other will control the true/false value of EACH radio button in that group. To maintain the selected state of those buttons when using the script you would use the same technique that is used with check boxes. You create global variables that belong to that script only, that keep that value in memory. When the script is run the first time a "default" value is assigned to a check box or radio button. Once a selection is made a global variable is assigned the value of that object. When the script is called AGAIN that global variable is then used to assign the value from the last use to the check box or radio box.

At least this is how I learned to do it by reading the scripts that came with AS. This applies mostly to menu and button scripts with a pop up dialog.

In tool scripts from AS like the "Translate Points" tool you can go a bit further. The boolean (true/false) value of a check box is assigned to the "Save prefs" function so that the last "state" of the check box or radio button is "remembered" even when AS is closed and reopened.

Here is a snippet of code that saves and loads the boolean value of the "Auto Weld" and "Auto Fill" check boxes in the "Translate Points" tool:

In the first one I think I covered this in another thread about script prefs. The value is loaded from the prefs. If there is no setting in the prefs a "default" value is used instead. ie; (.... , true) the ", true" is the default value if the prefs value doesn't exist.

Code: Select all

function LM_TranslatePoints:LoadPrefs(prefs)
	self.autoWeld = prefs:GetBool("LM_TranslatePoints.autoWeld", true)
	self.autoFill = prefs:GetBool("LM_TranslatePoints.autoFill", false)
end
Here we are SAVING the prefs from the value of a global variable that matches the value of the check box defined in another function.

Code: Select all

function LM_TranslatePoints:SavePrefs(prefs)
	prefs:SetBool("LM_TranslatePoints.autoWeld", self.autoWeld)
	prefs:SetBool("LM_TranslatePoints.autoFill", self.autoFill)
end
The key to saving and keeping those values when the script or tool is run over and over and changed is to assign the value of the check box or radio button to a GLOBAL variable that stays in memory as long as AS is open. Saving to the prefs file just goes the extra mile so that it stays that way even after the program is closed.

This would work the same for a radio button... uh... I assume it would. It should. I don't know for absolute certainty that it does but it most certainly should work the same since both types have the same true/false behavior and properties.

In the same script there is a function called "DoLayout" which creates the buttons and text boxes etc we see at the top of the edit window when the tool is selected. The "DoLayout" function is where the check boxes are created.

Here is the snippet from that function that refers to the "autoweld check box":

Code: Select all

	self.autoWeldCheck = LM.GUI.CheckBox(MOHO.Localize(MOHO.STR_AUTOWELD, "Auto-weld"), self.AUTOWELD)
	layout:AddChild(self.autoWeldCheck)
Notice the check box being created is called "autoWeldCheck". It is not called "autoWeld" as in the previous function. It is still a variable that can be accessed by calling "self.autoWeldCheck" to get or set the value but in this case it is separate and unique from the saved variable that defines the true/false value.

Later in the "UpDateWidgets" function that will change these text box values when the user changes them or selects the tool we set the value based on the SAVED prefs value:

Code: Select all

	self.autoWeldCheck:SetValue(self.autoWeld)
See what happened? It used the saved prefs value to set the value of the check box. When the tool setting is changed that saved variable (self.autoWeld) is changed which then changes the check box (self.autoWeldCheck). Two different variables but connected to the same object.

This is a more... advanced way of storing those values. You don't have to save them in the prefs. You could just have a global variable that is tied in the same way to the check box value and keeps those values just during the current session or the time you have AS open. When you close it and relaunch it the values are reset to defaults.

If you need more help let me know, maybe we can work on figuring it out more together. I get VERY CONFUSED trying to get these things to work. Just when I think I have it figured out... I forget how I did and have to refresh my memory. It feels a bit like magic to me sometimes. Sometimes I wear beads, wave chicken feet and chant over the computer when I get stuck with a bug. It almost seems that has as much effect as studying the code. ;)

-vern
User avatar
synthsin75
Posts: 10153
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Post by synthsin75 »

Thanks a lot Vern!!!! I had been putting the wrong if statement in the UpdateWidgets function. So now I have:

Code: Select all

if (Syn_CreateShapev3.MODE == 1) then
    self.bothRad:SetValue(true) 

    elseif (Syn_CreateShapev3.MODE == 2) then
      self.outlineRad:SetValue(true) 

    elseif (Syn_CreateShapev3.MODE == 3) then
      self.fillRad:SetValue(true) 
  end
In the DoLayout function, and:

Code: Select all

if (self.bothRad:Value() == true) then
    Syn_CreateShapev3.MODE = 1
    elseif (self.outlineRad:Value() == true) then
    Syn_CreateShapev3.MODE = 2
    elseif (self.fillRad:Value() == true) then
    Syn_CreateShapev3.MODE = 3
  end
In the UpdateWidgets function.

The only thing is you have to actually create a shape before anything but the default radio button selection is remembered. I'm assuming there's no getting around that though, since that's the only way the script completes a run.

Once I get it cleaned up (and perhaps commented), I'll post this tool mod. The first version I posted I took down for lack of response. Hopefully this one does better. :roll:
Post Reply