Welcome

User: Pass:   register


This article is designed to expand your knowledge of dialogs. If you don’t know how to make a dialog, I strongly suggest you read over the Introduction To Dialogs first. This article contains information on the on DIALOG event, modal dialogs, dynamic dialog names and general design layout.

I use a few abbreviations which I use when discussing something (But never in any code). Instead of saying on DIALOG:dname:eventname:id: I will usually say eventname event e.g. the dclick event instead of on DIALOG:dname:dclick:id: (I’m sure you all know this, but I’m just covering my back here =) )

Contents

On DIALOG:dname:sclick:id: { }

As a reminder, this event reacts when you click once on most items in a dialog. Exceptions to this are the text, edit, and box (And with some combo & list) items.

Why do you use the sclick event? Some people such as myself have picked up a bad habit of using this event to track changes in settings. So when someone for example checks/unchecks the “save window position” check box I would have a sclick event ready to change a variable to the tune of set %var $did(id).state.

Of course in hindsight I really should not do this. What if someone makes a mistake and doesn’t want to use the changes? Well most programs provide a save or done button and a cancel button. So as a general rule it seems to be better to save the settings once the user sclicks on the Save button and not on the individual setting.

You can also use the sclick event to change items in the dialog depending on what the user is doing. By this I mean doing stuff like disabling a button when it cannot be used, or enabling it when it can. Or hiding/unveiling new controls when someone pushes a button. Here are a few examples:

  • i. You have an autojoin list. Channels are listed in a combo. There is an add and a remove button. The buttons add/remove the selected channel in the combo’s list area. Now if there is no channel selected in the list (which is what happens when the dialog first opens) then you cannot remove the channel (because there is no channel to remove!). Now if we click on a channel we can enable the Remove button. How do we know we clicked on a channel? We use the sclick event of course.
  • ii. You have an away script. It has a simple and an advanced mode (Like ICQ). Normally the dialog would just show the simple stuff like away message, away nick, pager + logger status. Use a push checkbox which to flip between Simple and Advanced mode. When depressed it should put us in advanced mode. We could show & enable (did -v and did -e) the advanced functions like auto deop, logging directory, anti idle, auto away etc… By using a sclick event you can switch between the two modes whenever the user clicks on that push check box.

Another thing that I should mention is that whenever you click on the [x] button to close the dialog, the button with the cancel style is sclicked. So lets say your script saves the window positions whenever the window is closed. The follow buttons would close the dialog: ok & cancel & the [x] button. Now insert some code into the script. On *:DIALOG:dname:sclick:*: if ($istok(1 2,$did,32)) set %xy $dialog($dname).x $dialog($dname).y

Now the above event was scripted assuming that your OK and Cancel buttons were id 1 & 2. But some scripts don’t have a need for a cancel button, so why include one? For that sort of script you could just use a hidden (style: hide cancel) cancel button.


On DIALOG:dname:init:id: { }

As a reminder, this event reacts when a dialog is first opened. The dialog becomes ‘visible’ after this event is called (So if you did a long loop in this event it would take a long time for the window to appear, however you can still use /did to change things on the dialog.). The ID you should use is 0.

Why do we use this event? I use it mainly with settings dialogs. When the dialog is opened I need to show what everything in the dialog is set to.

Lets say I had a Talker script. It’s settings dialog lets me choose if I want to talk using the talker all the time, and what my default talking style should be (eg. bold, underline, rainbow, reverse, plain, random). Not only when I sclick on the Save button do I need to store the settings, but when the dialog is opened again I need to show the new/relevant settings. This is where the init event takes place.

Dialog Code:

dialog talker.settings {
 title "Talker Settings"
 size -1 -1 300 115
 box "Default Talker Type",1, 5 5 230 100
 combo 2, 15 25 210 90, drop
 check "Use talker always",3, 15 60 150 25
 button "Save",4, 245 5 50 50, ok
 button "Cancel",5, 245 60 50 50, cancel
}
on *:DIALOG:talker.settings:init:0: {
 did -a $dname 2 1) None
 did -a $dname 2 2) Bold
 did -a $dname 2 3) Underline
 did -a $dname 2 4) Reverse
 did -a $dname 2 5) Rainbow
 did -a $dname 2 6) Random
 did -c $dname 2 %talker.settings.type
 if (%talker.settings.always == 1) did -c $dname 3
}
on *:DIALOG:talker.settings:sclick:4: {
 if ($did(2,$did(2).sel).text) set %talker.settings.type $left($did(2,$did(2).sel).text,-1)
 set %talker.settings.always $did(3).state
}

So basically the init is used by scripters to load dynamic information into a dialog (or non dynamic text in a listbox, combo, or read only edit). This information doesn’t always have to be just for settings. For example if you made a news ticker like the 7am News Ticker that I made, the init event is used to load the news items into the dialog. The process is quite long, which brings me to another point. If you are doing something that will tie down/lock up mIRC for a few seconds or more its probably a good idea to put in something showing the scripts progress and maybe an ETA - more on this later in the interface section but for now lets just stick to the events themselves.


On DIALOG:dname:edit:id: { }

As a reminder, this event reacts whenever you edit the contents of an edit box (adding and removing text). So every time you hit a key on the keyboard that places text into the editbox or edit section of a combo, this event will react. Lets say you decided to write “xmas” into an editbox. Something similar to below would happen:

[x] on dialog edit event reacts [m] on dialog edit event reacts [a] on dialog edit event reacts [d] on dialog edit event reacts (Opps we pressed d not s!) [Backspace] on dialog edit event reacts [s] on dialog edit event reacts

What I am trying to show (and badly at that) is that every time a change - no matter how small - to the text in the edit box occurs the on dialog edit event reacts. That’s every time, not just after you finish typing a word or after you ‘click’ out of the edit box.

So why do we use it? I have a horrible habit of using it to record settings changes (like when someone enters in a new nickname in say an away settings dialog). Not many ideas spring to mind when I think of the edit event, but here are a few:

  • i. Computer game which uses the dialog as its display. Make the player click in the editbox (or just place the focus on it as soon as the dialog opens and make the editbox out of view so the user doesn’t actually know you are using an editbox) and then press keys to play the game. I’ll try and use Tetris for my example. You control the falling blocks (we could make them icons) - make them go left,right,rotate and go down faster. You could make [a] = left, [d] = right, [s] = down, [w] = rotate. Then you would need to use some code:
    on *:DIALOG:tetris-example:edit:id-of-editbox: {
     if ($right($did($did).text,1) = a) move.left.by.one
     if ($right($did($did).text,1) = d) move.right.by.one
     if ($right($did($did).text,1) = s) move.down.by.one
     if ($right($did($did).text,1) = w) rotate.clockwise.by.one
     did -d $dname $did
     ;also because edit boxes have limits to the amount of text you can put into them,
     ;I feel that clearing the editbox after each button would be a good idea.
    }
  • ii. Spell Check as you type? Nick completion as you type? Maybe use it to replace the old tried and true command line. It could sit on top of your old command line and add extra functions like spell check & nc as you type, and maybe auto complete stuff like URL’s, auto complete commands, etc… It could have a button or combo that lets you select the output type (normal text, coloured, rainbow, reverse, op notice, etc…) or for those who don’t like auto completes another smaller dialog could popup when it thinks it could auto complete for you - that way you could stop bad auto completes.

Problems could occur if its a very lengthy piece of code; the script would have to be called after every little change! I haven’t tested with it myself so I’m not sure if there will be a noticeable slowdown.

On DIALOG:dname:dclick:id: { }

As a reminder, this event reacts when you double click on certain items in a dialog. Such items could be some text in a list or combo, an icon etc.

So why do we use this event? The main thing I see useful about this event is it lets you extend the capabilities of the mouse. For my 7am news ticker there are two lists in a dialog. One list contained the news sources I want to view, the other list displays the sources I do not want to view. There is an Add and a Del button to add/remove news sources that I want to view. So if I want to add a source, I select that source then click on the Add button. If I want to remove a source, I select that source then click on the Del button. With the dclick event you can speed up this procedure by double clicking on the source instead of selecting then clicking a button. You will find this sort of feature in most dialogs with editable lists of any sorts (For Windows and not just mIRC). If you are using Netscape to view this page check out the history window (Communicator/Tools/History I think). If you double click on any of the URL’s listed in the window Netscape will go to them. Now imagine if you could not double click? You would probably have to select the item, click on a menu, then click on Open Location or something like that.

I have to admit that I haven’t used this event a lot, and have just recently started to catch on to its goodies.

Dialog & Modal Dialogs

Most of the time I use the $dialog identifier to get info about an already created dialog (Say its x-y co-ords). However it has a really great but often looked over ability. So what can it do? Create a modal dialog.

A modal dialog is used to return information from an id in a dialog (e.g. the text in an editbox). While a modal dialog is opened the script halts/pauses. In order to continue the script you must do whatever is required by the dialog (e.g. push a button or check a box or whatever).

How do you call a modal dialog?

The format is: $dialog(name,table[,parent])

Now an explantion:

  • Name - Just like with calling a dialog using the /dialog command you need to give that specific dialog a name
  • Table - Once again like /dialog. You need to specify what table mIRC should use to make the dialog
  • Parent - This is optional. It defines what window the dialog is ‘attached’ to. This can be a window name, or -1 = Desktop window, -2 = Main mIRC window, -3 = Currently active window, -4 = Currently active dialog, if no dialog is open, defaults to -3 behaviour.

Now there is one last thing to do- in the dialog table you need to say where mIRC should find the stuff it has to return (Remember this is a $identifier and $identifiers return stuff). You need to give this id the result style. This means ONCE the user clicks on the OK button on the dialog the $dialog identifier that called the dialog will RETURN the value of the ITEM/ID that was given the result style.

Now why would we want to use a modal dialog? The most obvious reason I can think of is because we need immediate input for something and don’t want to use the old standard boring $? type identifiers, and making another /dialog means you have to have more dialog events and such to return the information you wanted.

You can only have one id with the result style and you can have multiple items in a dialog. Now lets say you had a $dialog() that called a dialog that had three buttons. The first says “Overwrite”, the second says “Resume” and the third says “Cancel”. Now you can’t give all three buttons the result style, and you need (should) to give one button the ok style (when the ok button is pressed the $dialog() returns the stuff from the result id. So my suggestion is to create a hidden editbox with the result style. When the user sclicks any button use the on DIALOG:dname:sclick:id: did -ra $dname id.of.editbox $did | dialog -k $dname. Where $did is, feel free to put whatever you want the modal dialog to return (I used $did because it will make the dialog return the id of the button pressed).


Dynamic Dialog Names

What is this and why should I even be reading about it? It is about not giving a dialog a hard coded name (That is, writing the dialog name in the script so it can only be changed when the user edits the script file). Instead the dialog name is dynamic, thus allowing you to open multiple dialogs. You don’t need to use a dynamic name for every dialog you open. Settings and options dialogs should have a fixed name. Dialogs that show error messages or other types of messages would benefit from a dynamic dialog name - that way they can show more then one error dialog at a time.

The way to decide on what type of dialog name to use is easy: If many dialogs will be called, and each dialog is to display different information (eg, like Getright, it displays multiple windows each about a single download. Each window has the same ‘look & feel’ to it - the same layout) then use dynamic dialog names. If you only need one dialog to be open (eg, a settings or setup dialog) then you don’t need to use dynamic dialog names.

So if you do use dynamic dialog names you need to be careful when dealing with the on DIALOG events, $did /did $dialog & /dialog. If you are using the on DIALOG event then instead of using the dialog name for anything use $dname. $dname returns the name of the dialog that made the event react. See the Error Message section for an example.

Designing An Interface

Why do we use dialogs?

For the above reason: its use as an interface from the script to the user. It provides an easy and simple means for the user to interact and use the script. Mostly this interaction is used to change settings for the script (eg. away script, channel protection script) but some others use dialogs to display information that the script has made from the settings it was given (eg. 7am news ticker, second IRC connection channel window, channel stats, userlist editor, etc…).

To help the user use the script

So what makes a good interface?

The layout of items in the dialog is very important. You have to decide what the dialog will be used for. Is it for settings? Is it to view results? Is it something completely different? Whatever it is, you need to give the user what they want - the tools that they need. Customization is king.

General layout tips:

  • Keep the dialog Clutter Free and Easy To Use. Don’t go awol with your item placement. If you find there is not enough room for all the items that you wanted to put in it you should consider sectioning off the settings to their own dialogs or tabs. Clutter = confusion for the user. Confusion creates frustration and frustration results in them ditching your script for something easier to use.
  • Keep buttons (and boxes to a certain extent) at the same size as any other button you used in your script. There are a few exceptions to this, such as a large OK or DONE or HELP button - which I usually use as a space filler. Generally I like to use 80 25 or 80 30 as my w/h for the buttons.
  • If your dialog contains tabs then please please please use the dbu option in your table so things actually fit! Also remember if you are placing in “option dbu” into a table that was made without this option you will need to go over the x y w h parts of all the items in your dialog. This is why pre planning would be a good thing to do next time: Do I need to use tabs? Or Could it need tabs at a later point? Yes - well then I had better put “option dbu” in there at the very start.
  • Keep your dialogs uniform. If you use multiple dialogs, give every dialog the same feel/look. So if you used a box with a height of 2 to separate a text item from the rest of the dialog (So it makes the text seem like the heading) in one dialog, do the same for other titles in other dialogs. This point is a larger extension of the Keep Buttons tip. The general idea is that familiar looking dialogs are easier to use first time round, and don’t seem as hard to use. It also makes the script less ‘jumbled up’ when all the dialogs are in uniform - just like a theme script.

Settings Specific Tips:

  • Box off each section of settings (eg. away settings in one box, auto away in another box, user info in yet another box).
  • Clearly label each option. If you have an auto away function which is enabled with a check box then make the text say “Enable Auto Away” or at least “Auto Away”. Don’t just put “Auto” or even no text at all (I realise that this is an extreme example but I can’t think of anything else at the moment!).
  • Disable settings that a user cannot modify (Using the did -b/e command). So if a user doesn’t want to use the Auto Away feature of an away script, disable the controls for it (This is why its a good idea to put boxes around settings). Of course when the user wants to use the Auto Away you just need to enable the controls again.
  • Only save the settings once the user clicks on the OK button.
  • If you need the user to enter a number (say for the time before you set auto away), don’t use an edit box or a massive line of radio buttons or a list box. Instead use a drop down combo. This is good for several reasons: It conserves space on the dialog. It minimises the chance of the user making an error because the user has to choose from a preset list of valid options. If we used an edit box instead, the user could instead of entering a number, enter letters (And we want them to the auto away time not some letters!) which would bring up errors. With the edit box the user could also type in other invalid values like “5mins” “5 minutes” “five minutes” “an hour” etc… Now you could be bothered to write an alias to parse and return the numerical value of this but wouldn’t it be a LOT easier to just let them choose from a pre-made list?
  • Give the user what they want. Once again I have to say Customization is king. Some people call it ‘options overload’. All it is, is letting the user change nearly every aspect of what the script does. We will use the away script as our example again. Now what could the user do to make this script function differently?

We should include the standard on/off feature. But what if the person wants to display a message when they go away? What about an option that lets you have a default away nickname (Or even better an editable list of away nicknames). We should include at least an editbox for the away message, an option that sets where the message should be shown (one channel, channels, none) and even a combo that lets you choose if you want to redisplay the message at a later time. What about a CTCP/Private Message/When someone says your name in the channel logger. What about letting you say where the log should be placed. Maybe there could be an option to send a reply to the person who just messaged/ctcp/page etc… it could even be based on user levels. How about an option to enable/disable the pager, and another option to play a sound when you are paged or to open a message window. How about a “come back from away on keypress” option that removes you from away once you start talking again. Next there is the auto away. It needs an enable/disable feature. It could also use a combo to select how long you have to be idle before it sets auto away, another to select the auto away message, another to use verbose (message the channel) mode, another to auto change nicks or not. Maybe the auto away should have an auto deop yourself option as well. I’m sure there are tons more options just for an away script. Like I said before, don’t clutter things. Maybe have an advanced/simple switch (Another example of customization).

Wow that took a long time to do. However its a lot easier to read when the settings are made accessible by a dialog.


Providing Responses When They Are Needed

Now I know I have gone on a bit about “Disabling settings the user cannot modify” which does provide a response to a users actions or in-actions, but what I’m going to talk about now is different. This time its about informing the user what has happened, or what is about to happen.

Some Examples:

   “Please Wait While Script Loads…”
   “Loading… xxx%”
   “Cannot Find Required File, Halting Script”
   “Insufficient Parameters”
   “You must select an xxxx first”
   “Someone just paged you”
   “You are now set away”
   “You are now set back”
   “Error… blah blah blah has gone wrong, please do blah blah blah to fix it”

Now these are just a few examples of responses from a script. It is easy to give a response - all you need is the echo command. But why use echo when you can use a dialog? Well its really up to you to decide which fits for your script. If you find that your script is fairly visible to the user (Will the user have to tinker with the script constantly or does it run by itself without much intervention) then maybe a dialog would be better, but if it prefers to ‘run in the background’ then maybe an echo would be better.

So how could you display these messages and more in a dialog? Here are a few suggestions:

For Loading/Please Wait Messages, in particular ones that ‘lock up’ mIRC until the script has finished: I recommend you use a separate small modeless dialog with these items:

  • A text item to show the user what is loading, and maybe how much has already been loaded (In percent).
  • A long row of icons to use as a percentage bar. In the table itself give each of the icons the hide style so when the dialog first opens the ‘percentage bar’ won’t be full. As the progress of the script increases, make more and more icons visible. If you want an example of this try the 7am News Ticker.
  • A button with the styles “hide ok”. Why hide it? Well why would you use it? Its unlikely that you would use it to close the dialog, especially if the script it is reporting on locks up mIRC. If you think you would use it by all means put it in, but I can’t really see a good reason to do so.
  • If you can figure out the time remaining then by all means you should have another text item to display that information.

Don’t forget to close the dialog as soon as the script has finished doing whatever it was doing!

For frequently occurring messages, and/or which are not too important: I recommend you use a ‘status bar’ at an edge of the existing dialog. You can see programs like Netscape Communicator, WS FTP, McAfee Virus Scan, etc… using this a lot. Its small, out of the way, but still gets the message through. All you need to do is to make a read only edit box. In my email checker I used “read autohs” for the edit style. Just make sure that whatever you put in this ‘status bar’ fits.

Error Messages: I recommend you use a separate modeless dialog. It should have the following:

  • Modeless Table, dynamic dialog name
  • Always On Top setting
  • A visible OK button, and if you want a button that opens some sort of help (Like a readme file)
  • Title saying “Error” along with a text item saying “Error” or other appropriate title.
  • An item to display the actual error. It could be a text item or maybe a ready only edit box.

You could also possibly include the following:

  • An icon for the script’s logo
  • A check box that lets you choose not to see this particular error message again

I made a script to simplify it (It's a modification of my previous error message attempts):

dialog scriptname.error {
 title "ERROR"
 size -1 -1 300 155
 box "Error:",1, 5 5 4 105
 text "",2, 20 20 230 105
 check "Do not &display this error again",3,5 130 170 25
 icon 4, 260 120 32 32, mirc32.exe
 button "&OK",5,255 5 40 50, ok
 button "&Help",6,255 60 40 50, cancel
}
alias scriptname.error {
 if ($readini $scriptdirerror.dat noshow $1 == 1) return
 var %scriptname.error.dialogname = scriptname.error. [ $+ [ $1 [ $+ [ . [ $+ [ $ticks ] ] ] ] ] ]
 dialog -mdo %scriptname.error.dialogname scriptname.error
 .timer -m 1 1 did -a %scriptname.error.dialogname 2 $2-
}

on *:DIALOG:scriptname.error.*:sclick:*: {
 if ($istok(5 6,$did,32)) writeini $scriptdirerror.dat noshow $gettok($dname,3,46) $did(3).state
 if ($did == 6) run scripts-help-file.ext
}

Now to use this error system, whenever an error occurs and you wish to inform the user, use the /scriptname.error alias. Its format is /scriptname.error <error reference number> <error message>. The error reference number is a number that you make up (no order or pattern is needed) to identify the type of error message you want to display. Why? Well so when people click on the “Do not display this error again” check box the script will record the <error reference number> to an ini file. Whenever you try and create an error message again with that reference number the error alias will just ignore it.

So why, you ask, do I have to write out the error message each time? Can’t I just let the error alias read an ini file using the error reference number? In short you could. I don’t because it lets my error messages be more dynamic: I can change the error message to suit the needs of the user. I will use a WWW Downloader script for the example this time. Lets say it has the following message types (Reference numbers included)

   1 File not found
   2 Cannot connect to server
   3 Cannot resolve host
   4 File not fully downloaded
   5 Unexpected File Size
   6 Connection Reset by Peer

Now for the File not found message we can personalize it by saying what file was not found: /dload.error 1 I’m sorry but I cannot find %dload.file from %dload.server

For the Unexpected File Size error, we can say what file size we expected and what file size we got: /dload.error 5 The size of the file we downloaded ( $+ %dload.downloaded.size $+ ) does not match the anticipated download size ( $+ %dload.anticipated.size $+ ). Perhaps you should download %dload.url again.

(Please note that I just made up all the variables off the top of my head)

End File

Well that’s about all I can think of at the moment. Designing dialogs is still a new territory for mIRC scripters. Don’t be afraid to explore different techniques. Be creative & Enjoy :)

Release 1 Written by Pasmal
Latest mIRC version at time of release: 5.61
Copyright © 1998,1999 #HelpDesk, All rights reserved.

"the next step" in dialogs, a continuation from Intro to Dialogs






© 1996-2010 hdesk.org and dalnethelpdesk.com