Archive: Section control


Section control
  The return of the n00bi...

I *thought* $INSTDIR was supposed to be in the installation path box on the instdir page by default. Is this not true? If not, how can I make it the default path?
And if I'm mixing up the Winamp installation directory and the user-chosen directory, just tell me

I also want to know how I can prevent the user from turning options (A) and (B) both on or both off (i.e. to switch one to the other when the other is turned on, and to disable either from being turned off).

Also, is it possible to, when an option in subsubsection (B) is turned on, turn off subsection (A)?


Re: Section control
 

I *thought* $INSTDIR was supposed to be in the installation path box on the instdir page by default. Is this not true? If not, how can I make it the default path?
And if I'm mixing up the Winamp installation directory and the user-chosen directory, just tell me
Yes, $INSTDIR goes into the path box on the instdir. Where do you set it? It's best to set the default $INSTDIR using InstallDir. If you want to set $INST condtionally you should set it in .onInit.

I also want to know how I can prevent the user from turning options (A) and (B) both on or both off (i.e. to switch one to the other when the other is turned on, and to disable either from being turned off).

Also, is it possible to, when an option in subsubsection (B) is turned on, turn off subsection (A)?
Have a look in Examples\one-section.nsi. If you don't understand it, don't hesitate to ask again.

I saw that, it didn't really answer my question, since it doesn't switch between two different options...


It shows you how. Using SectionSetFlags, SectionGetFlags and .onSelChange. You can save the last selected section of the two, on every call to .onSelChange check if it's still checked. If it is checked, and the second one too you need to turn off the second. If it's off and the second one too you should turn on the second. If it's on and the second one is off, do nothing.

One-section does exactly that with 4 sections.


Okay...I think I've got it

Is there any way to have 3 nested menus:
Menu
.Submenu
..Sub-submenu


Sure:


SubSection bla

Section blo
SectionEnd
SubSection innerbla
Section innerblo
SectionEnd
SubSectionEnd
SubSectionEnd
>

Oooh...ahhh...Thanx :p

But now I can't figure out how to set the flag to what I want. I'll assume for now that this is not kosher:

SectionSetFlags ${avs} ${S_SLBLDEXP}
SectionSetFlags ${avs2} ${S_SELECTED}
SectionSetFlags ${avs3} ${S_NOSELECT}
SectionSetFlags ${ape} ${S_SLCTXPND}
SectionSetFlags ${ape2} ${S_SELECTED}
SectionsetFlags ${ape3} ${S_NOSELECT}


SectionSetFlags doesn't care if the section is inside a sub section or not. Just give the section a name and use it with SectionSetFlags, it should work.


...I did do that, didn't I...? Sorry, I'm new to all of this :)


I can't know what you did if I don't have the script ;)

It's just the same as a regualr section:

Section "display name" DEFINED_NAME

And then use it like always:

SectionGetFlags ${DEFINED_NAME} $0


So I can't just do:

SectionSetFlags ${avs} 32

instead I'd do this:
!define EXPANDED 32
...
SectionSetFlags ${avs} ${EXPANDED}

or this:
!define EXPANDED 32
...
StrCpy $0 ${EXPANDED}
SectionSetFlags ${avs} $0

I'm asking because that makes absolutely no sense whatsoever :)

What I meant by "I can't figure out how to set the flag to whatever I want" was "I tried this code and it didn't work." Basically it set everything to 0, except for the section I didn't (try to) set.

I also tried this, and it did the same thing:

Function .onInit

StrCpy $0 ${SELECTED}
IntOp $1 $0 + ${EXPANDED}
IntOp $2 $1 + ${BOLDFACE}
StrCpy $3 ${NOSELECT} ; 0
SectionSetFlags ${avs} $2
SectionSetFlags ${avs2} $0
SectionSetFlags ${avs3} $3
SectionSetFlags ${ape} $1
SectionSetFlags ${ape2} $0
SectionsetFlags ${ape3} $3

FunctionEnd

:conf00zed:


btw, thanks for tolerating me :)


OK, here goes:

Each section, whether inside a sub section or not, has a name and a unique number identifying it. The unique number starts from 1 for the first section and goes up for each section, subsection or subsectionend. To avoid having to count the numbers and change them all whenever you add/remove a section the Section command receives a third parameter that is defined as the number of the section.

For example:
Section bla Sec1
SectionEnd
Section bla Sec2
MessageBox MB_OK ${Sec1}
MessageBox MB_OK ${Sec2}
SectionEnd

Will pop up two message boxes. The first one will say 1, and the second 2.

Every section also has flags which you can get using SectionGetFlags and change using SectionSetFlags. The flags are:


# Section selected

>!define SF_SELECTED 1
># Section is a subsection
>!define SF_SUBSEC 2
># Section is a subsection end
>!define SF_SUBSECEND 4
># Section is shown bold in the components page
>!define SF_BOLD 8
># Section is read-only
>!define SF_RO 16
># Subsection is to be automatically expanded
>!define SF_EXPAND 32
>
All but the first flag is changeable from everywhere. The first flag (selected) should only be changed after the components page is created, because when it is created it checks for the default configuration and selects the appropriate sections according to it. If you don't have installation options (InstType) then you can change the section from .onInit too and it should be ok.

Now, if you want to control what the user can and can not choose you should use the .onSelChange callback function which is called whenever the user clicks on a section. It's in this function where you should determine if the clicked section should remain clicked, be disabled, other section be disabled or enabled, made read-only or bolded.

Now that you know where everything should go, and what it means we shall move on to the real coding.

What you want is to force the user to select only one section out of two. one-section.nsi does the exact same thing with four sections. It does this by first checking only one section and unchecking the rest in .onInit. It also takes note of the section it selected for later use. Whenever the user clicks on a section and .onSelChange is called it turns off the old selected section (line 57 in the script), goes over all four sections and checks which one is selected (could be only one section or zero sections). If no section has been selected it means that the user clicked a section other than the four it is trying to control and that means we should turn the old selected section back on (line 83). If there was a selection it remembers it for the next time .onSelChange will be called. This way, only one section can be selected at a time because we always turn off the old selected section.

I hope this clears it up.

BTW, IntOp $1 $0 + ${BOLDFACE} is not good. You need to or ( using | ) $0 with ${BOLDFACE}, not add them. If you add them and $1 is already bold then 1+1 is 10 and not 1 as you wanted it to be...

I still don't know where I'm supposed to initialize the section flags, which is my problem. Past that I'm pretty damn sure I can make the components selections calculate primes in binary, if I wanted to :p

*thinks about the logic paramaters for a second*

Oh...duh. I should know that by now :rolleyes:


Umm...anyone? :cry:


Sorry, this:

*thinks about the logic paramaters for a second*

Oh...duh. I should know that by now
made me think that you understood.

Initialize the sections in the first call for .onSelChange.

I was talking about the OR vs. +.
And I still don't understand - do you mean the first time .onSelChange is called? And wouldn't that make it so that the first time someone changed the setup, it would initialize; instead of initializing...when the page is...initialized...?


You should always use `|` for flags.

If you initialize the section everytime the page loads, like I said before, it will reset the user selection whenever the user gets back to that page.

If you have install types (InstType) then the first install type will be chosen automatically on start-up and you won't have anything to worry about, but if you don't you will have to set it in .onInit. In any way you will have to set current section variable ($1 in one-section.nsi) to the section that is first selected in .onInit.


God do I feel stupid now :rolleyes: I completely forgot that one of the preset-install-types is selected on the first page load.

Thanx again for your help and toleranace :p


Sorry to keep bothering you about this, but how do I set a section to expanded or boldface .onInit?


SectionGetFlags ${section} $0
IntOp $0 $0 | ${SF_BOLD}
# or
# IntOp $0 $0 | ${SF_EXPAND}
SectionSetFlags ${section} $0


If you mean put that in .onInit it's not working (nothing changed).


Works fine for me. Please attach the script.


:cry:

Here


You work on $R0 yet the flags are in $0 and you set them from $0... Change it to:


SectionGetFlags ${avs} $0

IntOp$0 $0 | ${BOLDFACE}
>IntOp $0 $0 | ${EXPANDED}
>SectionSetFlags ${avs} $0

SectionGetFlags${ape} $0
IntOp$0 $0 | ${EXPANDED}
>SectionSetFlags ${ape} $0
>

Oops. Didn't see that.

It still didn't change though.


Attach the corrected script.


It's exactly the same as before, just with that bit fixed (exactly the way you said).


If this script works you are still using NSIS 2.0a7. Upgrade first.


I did. I just re-installed NSIS2b0.

And what script?


The script you have attached. It uses Fonts.dll:: which is the old syntax of a7 and below. If that works you are still using a7. Make sure in the log that it is b0 you are running.


Whoah...Apparently the wrapper (which is what I've been using) is a7, but the DOS version is b0. I dun get it...

Anyway, using the DOS version works. Thanx


I suggest you delete every directory you have installed NSIS in and install one instance of NSIS 2.0b0. When ohter version come out, install into that directory.


Did so, it's working now :)

Are there any logical operators (as in IF or FOR) in NSIS2b0? It'd make this process so much easier..


Nope, that will come in NSIS 3.


*thinks*

Doesn't seem THAT hard to program, if you have a real language to work with (as opposed to NSIS2 script :p )


I prefer to work on more important stuff for NSIS 2 and not waste my time destroying the current scripting language. It will all be added in NSIS 3 (if, for, while, funcitons with parms, more than one command per line, maybe even classes).


if you ask me, logical flow functions are extremely important to any programming language, and you wouldn't exactly "destroy" nsis by adding it...but that's just one user's opinion :(


Gah...sorry, I just realized what I was doing wrong. If a mod would like to delete this, they may...