Official ScriptUO EasyUO Scripts > Scripting Tutorials

Creating a user interface, step by step

(1/2) > >>

TrailMyx:
There seems to be a lot of confusion about how user interfaces work in EasyUO.  Actually there are many ways to implement these, so in this example I will describe creating a UI that will:

1) Continuously scan for user input
2) Continuously update the user interface for changing information.

The initial structure:

Script flow is important when setting up a user interface.  You don't want to call a menu item constructor more than once, so typically you will have one routine that will draw your entire user interface panel.  After the initial drawing, you may delete/add menu items as the script runs.  The code generated by the EasyUO Menu Designer lends itself perfectly to this method since all the necessary code to draw your newly created UI is located in one sub typicall named showEUOMenu1.

So here is the basic layout of a user interfaced script:

1) Setup your UI panel (typically a call to showEUOMenu1 or your own UI code)
2) Setup of your variables used for your script.
3) Main loop starts here
4)     Update UI information (handling input read (menu get) from UI controls via #MENURES
5)     Sample UI input from #MENUBUTTON
6)     If #MENUBUTTON <> N/A, then handle this button action (possibly 1+ function per button action)
7)     Housekeeping routines
8 )     Loop back to Main loop

Here is an example script which I wrote specifically for this tutorial:




--- Code: easyuo ---;=================================================================; Script Name: TrailMyx's UI Tutorial - Spellcasting; Author: TrailMyx; Version: 0.68; Shard OSI / FS: OSI / FS OK; Revision Date: 9/29/2007;; Purpose:;; Globals/System variables:;; Special Thanks:;; Revision History:;gosub showEUOMenu1gosub Setupset #MENUBUTTON N/A set %current_circle 1set %current_log_selection 0set %last_target N/A mainloop1:;; Update Window;  gosub UpdateLogWindow   menu get CircleMenu  if #MENURES <> %current_circle  {    set %current_circle #MENURES    gosub UpdateSpellMenu %current_circle  }   menu get EUOListLogWindow  if #MENURES <> %current_log_selection  {    set %current_log_selection #MENURES    set %temp %journal . %current_log_selection    menu set EUOStatus %temp  };; Handle Buttons/Checkmarks;  if #MENUBUTTON = EUOButtonCast  {    set #MENUBUTTON N/A ; Always remember to reset #MENUBUTTON when you handle it!    menu delete EUOShape1    menu Shape EUOShape1 168 40 105 21 3 7 1 Black 7 Red    menu get CircleMenu    set %circle #MENURES    menu get SpellMenu    set %spell #MENURES    menu get EUOCheckWaitForTarget    set %waitfortarget #MENURES     if %circle = 9 ; Computer the event macro 15 spell number...      set %spell_num 100 + %spell    else      set %spell_num ( ( %circle - 1 ) * 8 ) + %spell - 1     event macro 15 %spell_num    if %waitfortarget = #TRUE    {      target 10s      if %last_target = N/A      {        repeat        until #TARGCURS = 0        set %last_target #LTARGETID      }      event macro 22 0    }    menu get EUOEditDelay    wait #MENURES    menu delete EUOShape1    menu Shape EUOShape1 168 40 105 21 3 7 1 Black 7 Lime  }   if #MENUBUTTON = EUOButtonResetTarget  {    set #MENUBUTTON N/A ; Always remember to reset #MENUBUTTON when you handle it!    set %last_target N/A  }   menu get EUOCheckLoop  if #MENURES = #TRUE  {    set #MENUBUTTON EUOButtonCast ; Force the Cast button to be pressed again!  }goto mainloop1;--------------------------------------------------------------sub Setup  menu Combo Add CircleMenu First Circle  menu Combo Add CircleMenu Second Circle  menu Combo Add CircleMenu Third Circle  menu Combo Add CircleMenu Forth Circle  menu Combo Add CircleMenu Fifth Circle  menu Combo Add CircleMenu Sixth Circle  menu Combo Add CircleMenu Seventh Circle  menu Combo Add CircleMenu Eighth Circle  menu Combo Add CircleMenu Necromancy Circle  menu Combo Select CircleMenu 1 ; select 1st circle  gosub UpdateSpellMenu 1 ; redraw combo SpellMenu with 1st circle spells  menu Combo Select SpellMenu 1 ; always select the first combo select so it's visiblereturn;--------------------------------------------------------------sub UpdateSpellMenu  set %circle %1  menu Delete SpellMenu  menu Font BGColor White  menu Combo Create SpellMenu 12 64 145   menu get EUOCheckOSI  set %shard_kind #MENURES ; OSI and RunUO have different spells for 1st  if %circle = 1  {    if %shard_kind = #TRUE    {      menu Combo Add SpellMenu Clumsy      menu Combo Add SpellMenu Create Food      menu Combo Add SpellMenu Feeblemind      menu Combo Add SpellMenu Heal      menu Combo Add SpellMenu Magic Arrow      menu Combo Add SpellMenu Night Sight      menu Combo Add SpellMenu Reactive Armor      menu Combo Add SpellMenu Weaken    }    else    {      menu Combo Add SpellMenu Reactive Armor      menu Combo Add SpellMenu Clumsy      menu Combo Add SpellMenu Create Food      menu Combo Add SpellMenu Feeblemind      menu Combo Add SpellMenu Heal      menu Combo Add SpellMenu Magic Arrow      menu Combo Add SpellMenu Night Sight      menu Combo Add SpellMenu Weaken    }    return  }  if %circle = 2  {    menu Combo Add SpellMenu Agility    menu Combo Add SpellMenu Cunning    menu Combo Add SpellMenu Cure    menu Combo Add SpellMenu Harm    menu Combo Add SpellMenu Magic Trap    menu Combo Add SpellMenu Magic Untrap    menu Combo Add SpellMenu Protection    menu Combo Add SpellMenu Strength  }  if %circle = 3  {    menu Combo Add SpellMenu Bless    menu Combo Add SpellMenu Fireball    menu Combo Add SpellMenu Magic Lock    menu Combo Add SpellMenu Poison    menu Combo Add SpellMenu Telekinesis    menu Combo Add SpellMenu Teleport    menu Combo Add SpellMenu Unlock    menu Combo Add SpellMenu Wall of Stone  }  if %circle = 4  {    menu Combo Add SpellMenu Arch Cure    menu Combo Add SpellMenu Arch Protection    menu Combo Add SpellMenu Curse    menu Combo Add SpellMenu Fire Field    menu Combo Add SpellMenu Greater Heal    menu Combo Add SpellMenu Lightning    menu Combo Add SpellMenu Mana Drain    menu Combo Add SpellMenu Recall  }  if %circle = 5  {    menu Combo Add SpellMenu Blade Spirits    menu Combo Add SpellMenu Dispel Field    menu Combo Add SpellMenu Incognito    menu Combo Add SpellMenu Magic Reflection    menu Combo Add SpellMenu Mind Blast    menu Combo Add SpellMenu Paralyze    menu Combo Add SpellMenu Poison Field    menu Combo Add SpellMenu Summon Creature  }  if %circle = 6  {    menu Combo Add SpellMenu Dispel    menu Combo Add SpellMenu Energy Bolt    menu Combo Add SpellMenu Explosion    menu Combo Add SpellMenu Invisibility    menu Combo Add SpellMenu Mark    menu Combo Add SpellMenu Mass Curse    menu Combo Add SpellMenu Paralyze Field    menu Combo Add SpellMenu Reveal  }  if %circle = 7  {    menu Combo Add SpellMenu Chain Lightning    menu Combo Add SpellMenu Energy Field    menu Combo Add SpellMenu Flame Strike    menu Combo Add SpellMenu Gate Travel    menu Combo Add SpellMenu Mana Vampire    menu Combo Add SpellMenu Mass Dispel    menu Combo Add SpellMenu Meteor Swarm    menu Combo Add SpellMenu Polymorph  }  if %circle = 8  {    menu Combo Add SpellMenu Earthquake    menu Combo Add SpellMenu Energy Vortex    menu Combo Add SpellMenu Resurrection    menu Combo Add SpellMenu Air Elemental    menu Combo Add SpellMenu Summon Daemon    menu Combo Add SpellMenu Earth Elemental    menu Combo Add SpellMenu Fire Elemental    menu Combo Add SpellMenu Water Elemental  }  if %circle = 9  {    menu Combo Add SpellMenu Animate Dead    menu Combo Add SpellMenu Blood Oath    menu Combo Add SpellMenu Corpse Skin    menu Combo Add SpellMenu Curse Weapon    menu Combo Add SpellMenu Evil Omen    menu Combo Add SpellMenu Horrific Beast    menu Combo Add SpellMenu Lich Form    menu Combo Add SpellMenu Mind Rot    menu Combo Add SpellMenu Pain Spike    menu Combo Add SpellMenu Poison Strike    menu Combo Add SpellMenu Strangle    menu Combo Add SpellMenu Summon Familiar    menu Combo Add SpellMenu Vampiric Embrace    menu Combo Add SpellMenu Vengeful Spirit    menu Combo Add SpellMenu Wither    menu Combo Add SpellMenu Wraith Form    menu Combo Add SpellMenu Exorcism  }return;--------------------------------------------------------------sub UpdateLogWindow  if %jindex = N/A    set %jindex #JINDEX  if %journal_pointer = N/A    set %journal_pointer 1  if %journal_pointer > 200  {    set %journal_pointer 1    menu delete EUOListLogWindow ; remember when you want to redraw a control, you MUST!! delete it first.    menu List Create EUOListLogWindow 12 136 257 225  }  while %jindex < #JINDEX  {    scanjournal %jindex    gosub AddSpace #JOURNAL    menu List add EUOListLogWindow #RESULT    set %journal . %journal_pointer #RESULT    set %journal_pointer %journal_pointer + 1    set %jindex %jindex + 1  } return;--------------------------------------------------------------; %1 - string to mungsub AddSpace  namespace push  namespace local AS  set !tempstring %1  AddSpace_loop1:    str pos !tempstring _    if #STRRES <> 0    {      set !val #STRRES - 1      str left !tempstring !val      set !left #STRRES      set !val !val + 1      str del !tempstring 1 !val      set !tempstring !left , #SPC , #STRRES      goto AddSpace_loop1    }  set #RESULT !tempstring  namespace popreturn #RESULT;--------------------------------------------------------------sub UpdateNecromancySpellMenu  menu Delete SpellMenu  menu Combo Create SpellMenu 12 20 145  menu Combo Add SpellMenu Animate Dead  menu Combo Add SpellMenu Blood Oath  menu Combo Add SpellMenu Corpse Skin  menu Combo Add SpellMenu Curse Weapon  menu Combo Add SpellMenu Evil Omen  menu Combo Add SpellMenu Horrific Beast  menu Combo Add SpellMenu Lich Form  menu Combo Add SpellMenu Mind Rot  menu Combo Add SpellMenu Pain Spike  menu Combo Add SpellMenu Poison Strike  menu Combo Add SpellMenu Strangle  menu Combo Add SpellMenu Summon Familiar  menu Combo Add SpellMenu Vampiric Embrace  menu Combo Add SpellMenu Vengeful Spirit  menu Combo Add SpellMenu Wither  menu Combo Add SpellMenu Wraith Form  menu Combo Add SpellMenu Exorcismreturn;--------- EasyUO Menu Designer Code Begin ---------sub showEUOMenu1        menu Clear        menu Window Title TrailMyx's Spell Caster        menu Window Color BtnFace        menu Window Size 277 392        menu Font Transparent #true        menu Font Align Right        menu Font Name MS Sans Serif        menu Font Size 8        menu Font Style        menu Font Color WindowText        menu Font Transparent #false        menu Font Align Left        menu Text EUOLabel1 8 4 Spell circle/Necro:        menu Text EUOLabel2 8 48 Spell name:        menu Text EUOLabel3 8 120 Log Display:        menu Shape EUOShape1 168 40 105 21 3 7 1 Black 7 Lime        menu Text EUOLabel4 16 96 Delay        menu Font BGColor Window        menu Combo Create CircleMenu 12 20 145        menu Combo Create SpellMenu 12 64 145        menu List Create EUOListLogWindow 12 136 257 225        menu Font BGColor BtnFace        menu Button EUOButtonCast 184 12 75 25 Cast        menu Check EUOCheckOSI 172 64 73 17 #true OSI        menu Font BGColor Window        menu Edit EUOStatus 12 368 257 ...        menu Font BGColor BtnFace        menu Check EUOCheckLoop 172 80 93 17 #false Loop?        menu Check EUOCheckWaitForTarget 172 96 109 17 #false Wait for Target?        menu Font BGColor Window        menu Edit EUOEditDelay 48 92 81 20        menu Font BGColor BtnFace        menu Button EUOButtonResetTarget 184 116 75 21 Reset Target        menu Show 421 270return;--------- EasyUO Menu Designer Code End --------- 
Here is a VERY simplified version of what this script does (psudocode)


--- Code: easyuo ---gosub showEUOMenu1 ; build and show showEUOMenu1 menu (generated with Menu Designer)gosub Setup ; setup menu informationmainloop1:  gosub UpdateLogWindow   [i]if MenuCircle has changed[/i]    gosub UpdateSpellMenu %current_circle   [i]if EUOListLogWindow selection has changed    Get currently selected item in EUOListLogWindow     Set this value as text within EUOStatus [/i]   if #MENUBUTTON = EUOButtonCast    [i]Cast the spell[/i]   if #MENUBUTTON = EUOButtonResetTarget    set %last_target N/A   menu get EUOCheckLoop  if #MENURES = #TRUE    set #MENUBUTTON EUOButtonCast ; force the casting of the last spell   goto mainloop1 

So we talked about the menu, and here it is:


--- Quote ---;--------- EasyUO Menu Designer Code Begin ---------
sub showEUOMenu1
   menu Clear
   menu Window Title TrailMyx's Spell Caster
   menu Window Color BtnFace
   menu Window Size 277 392
   menu Font Transparent #true
   menu Font Align Right
   menu Font Name MS Sans Serif
   menu Font Size 8
   menu Font Style
   menu Font Color WindowText
   menu Font Transparent #false
   menu Font Align Left
   menu Text EUOLabel1 8 4 Spell circle/Necro:
   menu Text EUOLabel2 8 48 Spell name:
   menu Text EUOLabel3 8 120 Log Display:
   menu Shape EUOShape1 168 40 105 21 3 7 1 Black 7 Lime
   menu Text EUOLabel4 16 96 Delay
   menu Font BGColor Window
   menu Combo Create CircleMenu 12 20 145
   menu Combo Create SpellMenu 12 64 145
   menu List Create EUOListLogWindow 12 136 257 225
   menu Font BGColor BtnFace
   menu Button EUOButtonCast 184 12 75 25 Cast
   menu Check EUOCheckOSI 172 64 73 17 #true OSI
   menu Font BGColor Window
   menu Edit EUOStatus 12 368 257 ...
   menu Font BGColor BtnFace
   menu Check EUOCheckLoop 172 80 93 17 #false Loop?
   menu Check EUOCheckWaitForTarget 172 96 109 17 #false Wait for Target?
   menu Font BGColor Window
   menu Edit EUOEditDelay 48 92 81 20
   menu Font BGColor BtnFace
   menu Button EUOButtonResetTarget 184 116 75 21 Reset Target
   menu Show 421 270
return
;--------- EasyUO Menu Designer Code End ---------
--- End quote ---

You can see that there are a few different menu elements that we'll need to manipulate, but there are several that will effect the script flow so we'll concentrate on:

menu combo
menu list
menu check
menu edit

First, I'll discuss a bit more of what's happening in the main loop.  For the first button item EUOButtonCast, there are some items you should be aware of.  First is that when I'm casting a spell, I change the "green" box into a "red" box.  Unfortunately with EasyUO, there's no way to change the drawing attributes of an items that's already drawn.  The only thing you can do is to delete the item, and redraw it with the correct color/font/background.  So this code:


--- Code: easyuo ---    menu delete EUOShape1    menu Shape EUOShape1 168 40 105 21 3 7 1 Black 7 Red 
will delete the "green" box and redraw the box as "red"  It's IMPORTANT to say again that you should always delete the existing item, otherwise you'll be accumulating unused drawing objects in your UI which will impact your performance and possibily crash EasyUO in time.

The next important point I'd like to make here is that every time you handle a valid #MENUBUTTON press, you should reset the #MENUBUTTON value to some unknown value.  I generally use "N/A" and I do this right after the condition:


--- Code: easyuo ---  if #MENUBUTTON = EUOButtonCast  {    set #MENUBUTTON N/A ; Always remember to reset #MENUBUTTON when you handle it!... 
When you are looking at controls on the UI, there's only one method you can retrieve information from them (2 if you include buttons).  #MENURES holds the value of any "menu get" command issued.  So this code:


--- Code: easyuo ---    menu get CircleMenu    set %circle #MENURES    menu get SpellMenu    set %spell #MENURES    menu get EUOCheckWaitForTarget    set %waitfortarget #MENURES 
Retrieves the values of the ComboBoxes CircleMenu and SpellMenu as well as the CheckBox EUOCheckWaitForTarget.  ListBox and ComboBox #MENURES values start at 1 for the first selection and so forth.  A #MENURES of 0 means there's nothing selected

But you see in the above code, we have to read the value of the control, then store that value in a variable in order to check more than one control at a time.

Dynamic UI Information

You'll notice when you run this script, that when you change the Circle number, you change the menu selections for the SpellMenu.  I've included this function because there are some annoying quirks to using ComboBoxes and ListBoxes within EasyUO.  These are the quirks I'm talking about:

1) You cannot read the text from a Combo/List box, only the index
2) You cannot DELETE an item from a Combo/List box. 

The second one is totally annoying when you are trying to manipulate the contents of one of these Boxes.  In order to delete information from a Combo/List box, you have to completely re-draw the entire control.  Yes, you have to delete it, and then add back all the information that was originally contained but omitting the information you wanted to delete.  Kinda dumb?  Yes, I think so to.  However, it's what we have to work with, so I have implemented code in this sample script to help you understand that.

Here is how you first add information to a List/Combo box:


--- Code: easyuo ---  menu Combo Add CircleMenu First Circle  menu Combo Add CircleMenu Second Circle  menu Combo Add CircleMenu Third Circle  menu Combo Add CircleMenu Forth Circle  menu Combo Add CircleMenu Fifth Circle  menu Combo Add CircleMenu Sixth Circle  menu Combo Add CircleMenu Seventh Circle  menu Combo Add CircleMenu Eighth Circle  menu Combo Add CircleMenu Necromancy Circle  menu Combo Select CircleMenu 1 ; select 1st circle... 
Using a script, you can select which item in the list you want to have highlighted with the "menu Combo Select ControlName" command.  Otherwise this value will be zero and you won't have an item selected until you do it by hand during script execution.

In the sub UpdateSpellMenu function, you can see what I'm talking about when you have to redraw a List/Combo control with different information:


--- Code: easyuo ---  menu Delete SpellMenu    menu Font BGColor White  menu Combo Create SpellMenu 12 64 145   menu get EUOCheckOSI  set %shard_kind #MENURES ; OSI and RunUO have different spells for 1st  if %circle = 1  {    if %shard_kind = #TRUE    {      menu Combo Add SpellMenu Clumsy      menu Combo Add SpellMenu Create Food      menu Combo Add SpellMenu Feeblemind      menu Combo Add SpellMenu Heal      menu Combo Add SpellMenu Magic Arrow      menu Combo Add SpellMenu Night Sight      menu Combo Add SpellMenu Reactive Armor      menu Combo Add SpellMenu Weaken    }... 
We delete the whole control SpellMenu:

--- Code: easyuo ---  menu Delete SpellMenu 
then create another exact copy with the same dimensions:

--- Code: easyuo --- menu Combo Create SpellMenu 12 64 145 
Then you just add the information back that you want to be included in the control.

You'll notice that this script logs anything that happens in the journal to the EUOListLogWindow ListBox.  The function UpdateLogWindow also maintains a record of the text contained in this list box since the ListBox control doesn't do this for you.  That way, when you click of of the items in the EUOListLogWindow control, that value is copied to the EUOStatus EditBox.


--- Code: easyuo ---;--------------------------------------------------------------sub UpdateLogWindow  if %jindex = N/A    set %jindex #JINDEX  if %journal_pointer = N/A    set %journal_pointer 1  if %journal_pointer > 200  {    set %journal_pointer 1    menu delete EUOListLogWindow ; remember when you want to redraw a control, you MUST!! delete it first.    menu List Create EUOListLogWindow 12 136 257 225  }  while %jindex < #JINDEX  {    scanjournal %jindex    gosub AddSpace #JOURNAL    menu List add EUOListLogWindow #RESULT    set %journal . %journal_pointer #RESULT    set %journal_pointer %journal_pointer + 1    set %jindex %jindex + 1  }return 
I hold the information that's shown in the journal in an array starting at index 0.  I only hold 200 entries, then start over again.  Specifically, that's what this code does:


--- Code: easyuo ---    scanjournal %jindex    gosub AddSpace #JOURNAL    menu List add EUOListLogWindow #RESULT    set %journal . %journal_pointer #RESULT    set %journal_pointer %journal_pointer + 1    set %jindex %jindex + 1 
And you get a data structure like this:


--- Quote ---%journal0 <- Journal entry 0
%journal1 <- Journal entry 1
%journal2 <- Journal entry 2
...

--- End quote ---

I make a call to AddSpace because the information contained in the #JOURNAL system variable containes underscores and not spaces, so AddSpace converts the underscores to spaces so they look better contained in the ListBox and EditBox.  One thing to keep in mind at this point is:

1) #JOURNAL contains "_" for spaces
2) #PROPERTY contains spaces. 

It's common for the programmer to forget this, so be sure you remember this when you are doing string comparisons between #JOURNAL and #PROPERTY entries.

valen2.0:
I cannot get that program to work that you posted to create a UI. is it broke?

The Ghost:
It work perfectly.  Not sure what broken. 

This is not design to get you fighting monster. It an example on how to build a menu and how to use it.

valen2.0:
I was more talking about easyuo design program. But I figured it out.

The Ghost:
can be tricky to run the first time.

Navigation

[0] Message Index

[#] Next page

Go to full version