Dialog System

Scripts

14 years
edited 8 years
Compatibility Notice:

  • library name has been changed from Dialogs to Dialog
  • function [lcode=jass]GetTriggerDialog()[/lcode] has been replaced with [lcode=jass]Dialog.Get()[/lcode]

Code (JASS) Select

//==============================================================================
//                    DIALOG SYSTEM BY COHADAR -- v3.1
//==============================================================================
//
//  PURPOUSE:
//       * Displaying dialogs the easy way
//       * Retrieving dialog results the easy way
//
//
//  HOW TO USE:
//       * Dialog is basically a struct wrapper around native dialog
//
//       * First create a dialog,
//            # local Dialog d = Dialog.create()
//
//         than add a title,
//            # call d.SetMessage("Some Text")
//
//         than add couple of buttons
//            # call d.AddButton("First Button",  HK_A)
//            # call d.AddButton("Second Button", HK_B)
//            # call d.AddButton("Third",         HK_C)
//
//         HK_X is a hotkey constant for a button,
//         there are constants for all letters + numbers 0..9
//         hotkeys are not case-sensitive
//
//         now add a callback method for your dialog
//            # call d.AddAction( function SomeFunction )
//         this is the function that will be called when a player presses a button
//
//         And finally show the dialog in one of two ways:
//            # call d.ShowAll()      // Displays dialog to all human players
//            # call d.Show( player ) // Displays dialog to specified player
//
//         Inside your callback function you can get the clicked Dialog struct like this
//         local Dialog d = Dialog.Get()
//         and then use d.GetResult() to get the hotkey of a clicked button
//
//         You can also use GetTriggerPlayer() to find out witch player pressed the button
//
//         When you are done with Dialog you can:
//            # call d.destroy()  // destroy it completely
//            # call d.clear()    // or recycle it
//
//  PROS:
//       * Extremelly easy to use compared to native dialogs
//       * It is fool-proof and will warn you if you try to do something stupid
//
//  DETAILS:
//       * Don't release Dialogs before you are sure user has selected something
//         I recommend to never destroy Dialogs,
//         just create them when they are first time called and then show/hide them as needed
//
//  THANKS:
//       * Magentix for finding the triggeraction leak and suggesting clear method
//       * Vexorian for creating Table so I don't have to mess with handles myself
//         
//  REQUIREMENTS:
//       * Table v3.0 or higher
//
//  HOW TO IMPORT:
//       * Just create a trigger named Dialog
//       * convert it to text and replace the whole trigger text with this one
//
//==============================================================================
library Dialog uses Table

globals
// Dialog button hotkey constants
    constant integer HK_ESC = 512
   
constant integer HK_0 = 48
constant integer HK_1 = 49
constant integer HK_2 = 50
constant integer HK_3 = 51
constant integer HK_4 = 52
constant integer HK_5 = 53
constant integer HK_6 = 54
constant integer HK_7 = 55
constant integer HK_8 = 56
constant integer HK_9 = 57

constant integer HK_A = 65
constant integer HK_B = 66
constant integer HK_C = 67
constant integer HK_D = 68
constant integer HK_E = 69
constant integer HK_F = 70
constant integer HK_G = 71
constant integer HK_H = 72
constant integer HK_I = 73
constant integer HK_J = 74
constant integer HK_K = 75
constant integer HK_L = 76
constant integer HK_M = 77
constant integer HK_N = 78
constant integer HK_O = 79
constant integer HK_P = 80
constant integer HK_Q = 81
constant integer HK_R = 82
constant integer HK_S = 83
constant integer HK_T = 84
constant integer HK_U = 85
constant integer HK_V = 86
constant integer HK_W = 87
constant integer HK_X = 88
constant integer HK_Y = 89
constant integer HK_Z = 90
endglobals

//===========================================================================
struct Dialog
    private trigger t = CreateTrigger()
    private triggeraction a = null
private dialog  d = DialogCreate()
    private string messageText = ""
    private integer button_count = 0
   
    private static HandleTable dialogTable
    private static HandleTable buttonTable
   
    static method onInit takes nothing returns nothing
        set Dialog.dialogTable = HandleTable.create() // Table
        set Dialog.buttonTable = HandleTable.create() // Table
    endmethod
   
static method create takes nothing returns Dialog
local Dialog ret = Dialog.allocate()
    call TriggerRegisterDialogEvent( ret.t, ret.d )
        set .dialogTable[GetClickedDialog()] = ret // Table
return ret
endmethod
   
method clear takes nothing returns nothing
        if .a != null then
            call TriggerRemoveAction(.t, .a)
            set .a = null
        endif
        set .messageText = ""
        set .button_count = 0
        call DialogClear(.d)
endmethod       

method onDestroy takes nothing returns nothing
        if .a != null then
            call TriggerRemoveAction(.t, .a)
        endif
call DestroyTrigger(.t)
        call .dialogTable.flush(.d) // Table
        call DialogDestroy(.d)
endmethod   
   

    static method Get takes nothing returns Dialog
        return .dialogTable[GetClickedDialog()] // Table   
    endmethod
   
method GetResult takes nothing returns integer
return .buttonTable[GetClickedButton()] // Table
endmethod

method SetMessage takes string messageText returns nothing
        set .messageText = messageText
endmethod

    method AddButton takes string buttonText, integer hotkey returns nothing
        set .buttonTable[DialogAddButton(.d,  buttonText, hotkey)] = hotkey
        set .button_count = .button_count + 1
endmethod

method AddAction takes code actionFunc returns nothing
    if .a != null then
    call BJDebugMsg("|c00FF0000Dialog.AddAction: you cannot set more than one dialog action")
else
set .a = TriggerAddAction( .t, actionFunc )
endif
endmethod
   
method Show takes player whichPlayer returns nothing
    if .a == null then
    call BJDebugMsg("|c00FF0000Dialog.Show: You forgot to set a dialog action")
endif
if .button_count == 0 then
    call BJDebugMsg("|c00FF0000Dialog.Show: You cannot show dialog with no buttons")
else
            // message must be set before every display because of some bug.
            call DialogSetMessage( .d, .messageText )
call DialogDisplay(whichPlayer, .d, true)
endif
endmethod

method ShowAll takes nothing returns nothing
local integer i = 0
loop
    exitwhen i>=12 // maximum of human players is 12
if GetPlayerController(Player(i)) == MAP_CONTROL_USER then
            if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
                call .Show(Player(i))
            endif
endif
set i = i + 1
endloop
endmethod

method Hide takes player whichPlayer returns nothing
    call DialogDisplay(whichPlayer, .d, false)
endmethod

method HideAll takes nothing returns nothing
local integer i = 0
loop
    exitwhen i>=12 // maximum of human players is 12
                call .Hide(Player(i))
set i = i + 1
endloop
endmethod

endstruct

endlibrary


Map contains dialog examples and can be used as nice weather testing utility.
  • Dialogs_v3.1.w3x (25.8 KB)