mScriptBox Tutorial
$submenu Identifier
Written by blue-elf
Additional Examples added by Merlin
Published with permission.

Table Of Contents

  1. Introduction
  2. More examples
  3. Advanced examples
  4. And even more advanced examples
  5. Re-evaluating identifiers
  6. Hints and Tips
  7. Example Script: File Listings with $submenu
  8. Example Script: Group Popup Configure
  9. Conclusion

1. Introduction  Back to Top

$submenu is a new identifier for mIRC 6.0. The mirc.hlp section explains:

$submenu($id($1)) This identifier allows you to dynamically create a list of menu items, and can only be called from a popup menu definition.

It calls $id($1), where $id() is the name of your identifer, and where $1 = 1, and increases by 1 with each call, adding whatever is returned by $id() to the popup menu.

The value that $id() returns must be a one line definition format for a popup menu.

The iteration ends when $id() returns no value.


menu status {
  Animal
  .$submenu($animal($1))
}

alias animal {
  IF ($1 == begin) { RETURN - }
  IF ($1 == 1) { RETURN Cow:echo Cow }
  IF ($1 == 2) { RETURN Llama:echo Llama }
  IF ($1 == 3) { RETURN Emu:echo Emu }
  IF ($1 == end) { RETURN - }
}

The begin and end values are sent to check if the item should be enclosed in separators.

Note: You can't use this to create nested submenus, it will only build one single submenu.


2. More examples  Back to Top

Unfortunately, the mirc.hlp only provides a very simple example on $submenu.

I do believe that to explain $submenu better is to show examples. So here's the first one:

First create the following alias:


alias _partchan {
  IF ($1 == begin) { RETURN - }
  IF ($chan($1) ischan) { RETURN $ifmatch :part $ifmatch }
}

Doesn't make sense, does it? If you type //echo -a $_partchan(1) and the first channel that you're on is #mirc, it'll show up: '#mirc :part #mirc'

...without the single quotes, of course.

At first glance, it may seem useless. But if you apply that to $submenu, something wonderful happens ;)

Now in your channel popups, put the following:


Part
.All Channels:partall
.$submenu($_partchan($1))

And see what it does. What happens is, mIRC takes every channel that you're on and puts it in the popups. The popup creation is 'virtual' in the sense that you don't see it in any file.

The old method of doing this would be to have in popups:


Part
.All Channels:partall
.-
.$chan(1):part $chan(1)
.$chan(2):part $chan(2)
; and so on, which is tediously repetitive and is very limiting

With the use of $submenu, our work has been cut down greatly. No more repetitive popup scripting.


3. Advanced examples  Back to Top

Another good use for $submenu is when you have a list of items. Supposing you have a %variable that contains channel names. Let's say you have this variable:


%recent.channels #mirc,#irc,#irchelp,#help,#helpdesk

All you need to do is create an alias:


alias _recentchan {
  IF ($gettok(%recent.channels,$1,44)) { RETURN $ifmatch :join $ifmatch }
}

Then paste the following in your popups:


Recent channels
.$submenu($_recentchan($1))

...and voila =)



4. And even more advanced examples  Back to Top

One very good thing about $submenu is that it also allows for $2, $3 and so on. Which means, you can supply other parameters in your custom identifier. Just remember that the $1 will always be a number.

Let's take that recent channels adventure to demonstrate the capabilities of $submenu.

Supposing you have three variables, for recent items. One variable for recent channels, one for recent servers, and one for recent nicks. We will have some variables as below (shown with their values):


%recent.join #mirc,#irc,#irchelp,#help,#helpdesk
%recent.server irc.dal.net,us.undernet.org
%recent.nick Kamek,tabo,blue-elf,Dark_Greg,fubik

You'll see later that the variables have been named with a purpose.

Create an alias as below:


alias _recent {
  IF ($gettok($($+(%,recent.,$2),2),$1,44)) { 
    RETURN $ifmatch : $2 $ifmatch 
  }
}

Here's a breakdown of that alias:


$+(%,recent.,$2) will create %recent.$2
if the value of $2 is join, it will create the variable %recent.join if the value of $2 is nick, it will create the variable %recent.nick if the value of $2 is server, it will create the variable %recent.server

Putting it inside $(%recent.join,2) is actually putting it inside $eval. So now, if we have %recent.join, it will be evaluated and will return the actual value of that variable (the #mirc,#ircnewbies.. and so on).

Now, the $gettok shouldn't need explaining, and same goes for $ifmatch (please check your local mirc.hlp for $gettok and $ifmatch help).

The reason why I named the variables that way, is to make it easier for me to create the $_recent identifier. Thus:


RETURN $ifmatch : $2 $ifmatch

If I supply 'join' as the $2, it will become:


RETURN $ifmatch : join $ifmatch

This speeds up scripting greatly, whether you're talking in terms of typing, or speed of the script itself - since you're using less if-else statements.

But anyway, going back to the subject of $submenu, put this in your popups, preferrably in menubar or status popups:


Recent
.Servers
..$submenu($_recent($1,server))
.Channels
..$submenu($_recent($1,join))
.Nicks
..$submenu($_recent($1,nick))

Now, test it and see what happens ;-) It's as though you wrote this in your popups:


Recent
.Servers
..irc.dal.net : server irc.dal.net
..twisted.ma.us.dal.net : server twisted.ma.us.dal.net
..us.undernet.org : server us.undernet.org

And so on... the only difference is, mIRC is doing it internally for you.


5. Re-evaluating identifiers  Back to Top

Now that we've dealt with that. Let's try some identifiers and variables inside $submenu identifiers.

If you're used to dynamically creating your popups via the /write command, you're probably no stranger to using $!identifiers and % $+ variables. For the uninitiated, when writing to popup files, you'd need $!identifiers so that the actual value of the identifiers aren't written to the file, but the literal '$identifier' itself. The same is true for %variables.

How is this applicable to $submenu?

Let's say we want to use that part example above.


alias _part {
  IF ($chan($1) ischan) { 
    RETURN $ifmatch : part $ifmatch $!input(Enter message,1,Part) 
  }
}

Notice how I used $!input as opposed to $input. This is to prevent mIRC from evaluating the $input command while it is creating the submenu (or the popup item).

So now, if you apply the above to the popups, it'll add an option for you to input a part message. I find that really nifty ;-)

Similarly with variables, if you don't want the variable to be immediately evaluated, just use % $+ variablename.

Here's a personal alias of mine for you to dissect ;-)


alias _rfpop {
  VAR %c = $chan($1)
  VAR %n = $gettok($3,1,33)
  VAR %m = kick %c %n : $!+ $!input(Enter reason to kick %n from %c ,1,Kick)
  IF ($2 == kb) { 
    %m = .raw mode %c +b $mask($gettok($3,2,33),2) $!+ $!lf $!+ %m 
  }
  ELSE { %m = .raw %m }
  IF ($1 isalpha) { RETURN - }
  IF ($comchan(%n,$1).op) { RETURN %c : %m }
  IF ($chan($1) ischan) { RETURN $!style(2) %c :return }
}

Even if you don't understand it, it's just to show that you have to use $!identifiers for things that need to be evaluated later on. One obvious example is the use of $!style(2). This puts a '$style(2)' in the popups, thus disabling the specific item nicely.


6. Hints and Tips  Back to Top

The 'begin' and 'end' are optional. They signify if the $submenu identifier is just starting to create your submenus or if it's about to end creating them. At that point, you can make $submenu return a separator or the '-' character.

$submenu stops itself once you return a $null value. So be careful when you want to skip items. There are two ways of doing this:

1) You can either disable the item with $style.

2) Or you can skip the command part.

Here's an example:


alias _xpopmargin {
  IF ((e isin $1) || ($1 == 1)) { RETURN - }
  IF ($1 isnum 2-20) { 
    return $1 :msg x@channels.undernet.org set $chr(35) floatmargin $1
  }
}

The above is an alias that I use for for setting the floatmargin for channels in Undernet. Don't worry if you don't know what floatmargin is. The point is, the floatmargin range is from 2 to 20. Which means that I had to find a way to skip the 1. But I can't make $submenu return a $null, otherwise, the popup items will not be created.

That is why I have this line:


          IF ((e isin $1) || ($1 == 1)) { RETURN - }

This tells $submenu that if $1 is begin or end or 1, just make it return a - or a separator. Luckily for me, the popup appears like this:


        Undernet
        .Level 450
        ..Set
        ...FloatMargin
        ....$submenu($_xpopmargin($1))
        ; a few more lines here and there

Which means that there will be two separators on top of each other. But the good thing is, they don't show up in this mIRC version :-) So I now have a clean FloatMargin item that starts with 2 and ends in 20.


7. File Listings with $submenu  Back to Top

=======================
Author  : m0rpheus
=======================

Let's start.. This is the first example. menu status { - Quotes List .Read a line from.. ..$submenu($quotesmenu($1)) - } alias -l quotesmenu { ; This is the folder where our .txt quotes are stored. ; Change it to wherever your quotes folder is. ; VAR %p = $mircdir\quotes\ IF ($1 == begin) { RETURN - } ; Now here comes the line that does it all. ; Since $submenu calls this identifier, increasing ; the value of $1 each time, and since it will only ; stop when this identifier returns a $null value ; to it; we can use $findfile to list the files ; within that folder that match a specific wildcard. ; In this initial example, the wildcard will be *.txt ; as you can see below. IF ($1) { VAR %f = $findfile(%p,*.txt,$1) RETURN $nopath(%f) $+ :echo $read(%f) } ; The line RETURN $nopath(%f) $+ :echo $read(%f) ; Will return what would be be interpreted as: ; <filename>:echo <random line from text file> ; So basicly, what it'll do is choose a line from the .txt file, ; and echo it to the current window. IF ($1 == end) { RETURN - } } ; ========================================================= ; End of first example. ; Now on the next example, we're going to make a list of ; all logfiles in the logs folder, and playing them ; to a @window. ; We're going to call this window, @logreader ; menu @logreader { - Logs List .$submenu($logsmenu($1)) - } ; Now we just put a small menu item in the Status ; window to open the @logreader window for us. menu status { open @logreader:window -e @logreader } alias -l logsmenu { VAR %p = $logdir IF ($1 == begin) { RETURN - } IF ($1) { VAR %f = $findfile(%p,*.log,$1) RETURN $nopath(%f) $+ :loadbuf -p @logreader $+(",%f,") } IF ($1 == end) { RETURN - } }

In this example, the wildcard we use is *.log because log files are saved with this file extension. As you see, this is technicaly same thing as we used before, except that this time, instead of echoing a line of the file to the current window, we will load the contents of the whole file to the @logreader window. ;) To do this, we'll use /loadbuf.

Notes:
We use the -p after 'loadbuf' so that lines will be wrapped if they're too long and we use $+(",%f,") to enclose the file path in quotes, so that if it contains any spaces, it'll still be interpreted as a single parameter


8. Group Popup Configure  Back to Top

===================================================================
Author: SyntheroS
Syntax: GPC (Group Popup Configure)
Returns: (How many) (Total Characters)
Description: 
Use: Popup uses $submenu in order to return 
     all groups in use by mirc
     selecting a group will then toggle wether it is on or off
     Put the code below in a remote file
Why: Let's you quickly see which groups are in effect, and wether
     they are on or off, and then change them. Also a good example
     of $submenu
How: Simply right click in nearly any window to view the GPC popup
===================================================================

menu channel,status,menubar,nicklist,query {
  -
  GPC
  .$submenu($group.cfg($1))
}
alias group.cfg {
  IF (($1 isnum) && ($group($1))) {
    RETURN $right($group($1),-1) $+([,$group($1).status,],:,group.toggle $1)
  }
}
alias group.toggle { 
   $iif($group($1).status == on,.disable,.enable) $group($1)
}

9. Conclusion  Back to Top

By now, you should have more ideas from these simple examples. It doesn't matter if you're using variables, ini files, hash tables, or even text files, $submenu can still be used. You just need a little bit of imagination, then you can have tons of fun with this identifier.

If you haven't realized by now, the actual trick with $submenu is not in the $submenu itself, but in the identifier that you supply to it ;-) Of course, in reality, Khaled coming up with this idea is mind-boggling..