XML dialog - how to - events handling and text gadget

Share your advanced knowledge/code with the community.
ljgww
Posts: 26
Joined: Thu Mar 26, 2020 5:47 pm

XML dialog - how to - events handling and text gadget

Post by ljgww »

Could not find in the documentation an exact example on how to make XML dialog working.
Also, 'Label' or XML variant of text widget is not really documented. All of below code is based on hints elsewhere in the documentation - it took me hours to make it working. So ... sharing it to help someone save time.

Also, if you have some comments on how to make it working better (or more correct), I am always willing to learn. :)

Cheers

Code: Select all

; Based on:
;   SpiderBasic - Simple dialog example file
;    (c) Fantaisie Software

; simplified dialog fields, added example handlers and an example of text gadget

#Xml = 0
#Dialog = 0

Procedure EventProcHandler()
  Debug "Event Triggered with event# " + EventGadget()
  Select EventGadget()
    Case 100003 ; ok
      Debug "OK button clicked"
      ; get the text from the edit field
      stringGadget = DialogGadget(#Dialog, "edit1")
      Debug "Text in the string field: '" + GetGadgetText(stringGadget)+"'"
      FreeDialog(#Dialog) ; close dialog as we do not need it
    Case 100004 ; cancel
      Debug "Cancel button clicked. Abort and Close."
      FreeDialog(#Dialog) ; close dialog as we do not need it
  EndSelect
EndProcedure

; Define our dialog window here, using regular XML
;

XML$ = "<window id='0' name='window0' text='Dialog Title' minwidth='300'" +
  "  minheight='auto' maxheight='auto'" +
  "  flags='#PB_Window_ScreenCentered | #PB_Window_BorderLess | #PB_Window_SizeGadget'>" +
  "  <vbox>" +
  "    <text name='label1' text='Enter String' />" +
  "    <string name='edit1' width='50' height='30' />" +
  "    <hbox>" +
  "      <button name='ok' text='Save/Close' height='30' />" +
  "      <button name='cancel' text='Cancel/Close' />" +
  "    </hbox>" +
  "  </vbox>" +
  "</window>"

If ParseXML(#Xml, XML$) And XMLStatus(#Xml) = #PB_XML_Success
  If CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "window0") ; window to open via ID
    Debug "Dialog created"
    
    ; Example set values when dialog opens
    edit1field = DialogGadget(#Dialog, "edit1")
    SetGadgetText(edit1field, "Some predefined text") ; Set the text in the field
    
    ; Example bind buttons to execution
    okbtn = DialogGadget(#Dialog, "ok")
    cancelbtn = DialogGadget(#Dialog, "cancel")
    BindGadgetEvent(okbtn, @EventProcHandler())
    BindGadgetEvent(cancelbtn, @EventProcHandler())
    
    ; read of entered value in the gadget is done in handler
    
  Else
    Debug "Dialog error: " + DialogError(#Dialog)
  EndIf
Else
  Debug "XML error: " + XMLError(#Xml) + " (Line: " + XMLErrorLine(#Xml) + ")" 
  ; line location not very helpful here all XML is one line string
EndIf  
Image
User avatar
Peter
Posts: 1086
Joined: Mon Feb 24, 2014 10:17 pm
Location: 127.0.0.1:9080
Contact:

Re: XML dialog - how to - events handling and text gadget

Post by Peter »

Next task: Try to assign IDs to the gadgets. :)
ljgww
Posts: 26
Joined: Thu Mar 26, 2020 5:47 pm

Re: XML dialog - how to - events handling and text gadget

Post by ljgww »

Peter wrote:Next task: Try to assign IDs to the gadgets. :)
Actually this would be very useful as auto-ID's keep moving with editing of XML form. Thank you for pointing it out. Came to this changes...

added above :

Code: Select all

Enumeration GadgetIDs
  #BtnOK
  #BtnCancel
EndEnumeration
Changed handler procedure to:

Code: Select all

Procedure EventProcHandler()
  Debug "Event Triggered with event# " + EventGadget()
  Select EventGadget()
    Case #BtnOK ; ok
      Debug "OK button clicked"
      ; get the text from the edit field
      stringGadget = DialogGadget(#Dialog, "edit1")
      Debug "Text in the string field: '" + GetGadgetText(stringGadget)+"'"
      FreeDialog(#Dialog) ; close dialog as we do not need it
    Case #BtnCancel ; cancel
      Debug "Cancel button clicked. Abort and Close."
      FreeDialog(#Dialog) ; close dialog as we do not need it
  EndSelect
and changed XML definition to:

Code: Select all

XML$ = "<window id='0' name='window0' text='Dialog Title' minwidth='300'" +
  "  minheight='auto' maxheight='auto'" +
  "  flags='#PB_Window_ScreenCentered | #PB_Window_BorderLess | #PB_Window_SizeGadget'>" +
  "  <vbox>" +
  "    <text name='label1' text='Enter String' />" +
  "    <string name='edit1' width='50' height='30' />" +
  "    <hbox>" +
  "      <button id='"+#BtnOK+"' name='ok' text='Save/Close' height='30' />" +
  "      <button id='"+#BtnCancel+"' name='cancel' text='Cancel/Close'/>" +
  "    </hbox>" +
  "  </vbox>" +
  "</window>"
Only one problem I could see here is that in some larger context gadget ID's may clash but that is outside (code organization) problem.

Rationale:
- make sense to ID only items that one wants to handle in handler, others can auto-ID
- getting and setting gadget properties can be done via gadget 'name' so I found no need to ID the 'edit field' unless I want to catch some kind of 'on change' event.

Questions/Doubts:

in XML

Code: Select all

XML$ = "<window id='0' ... 
say that I already have window with id='0' elsewhere (e.g. main application window - since dialogs usually would come over something else) - would I need to take care of window id clashes?

----

On that line, did some experiments - strings are not going in ID but... figured out that if go with:

Code: Select all

Runtime Enumeration
  #win1
EndEnumeration
and ID hard coded in XML source.

Code: Select all

"<window id='#win1'
Things are also good to go.
So 'runtime' variant ID's seem to work.

Pros/Cons in using run-time vs meta-programming?
No idea yet but it can be used as another technique I guess. There is can of worms going from here...
User avatar
Peter
Posts: 1086
Joined: Mon Feb 24, 2014 10:17 pm
Location: 127.0.0.1:9080
Contact:

Re: XML dialog - how to - events handling and text gadget

Post by Peter »

Next task: Try to use the event system of the Dialog Library instead of using BindGadgetEvent(). :)
ljgww
Posts: 26
Joined: Thu Mar 26, 2020 5:47 pm

Re: XML dialog - how to - events handling and text gadget

Post by ljgww »

Peter wrote:Next task: Try to use the event system of the Dialog Library instead of using BindGadgetEvent(). :)
Unfortunately I did not get how to do this.

Main reason why I wrote first example was because I did not know how to bind events to a dialog form.
Hence I have no idea what 'event system of the Dialog Library' means as I have not found examples of handlers in examples. (perhaps I do not know where to look for it in the documentation available)

Maybe some hint where I can look into that and learn what is available?
User avatar
Peter
Posts: 1086
Joined: Mon Feb 24, 2014 10:17 pm
Location: 127.0.0.1:9080
Contact:

Re: XML dialog - how to - events handling and text gadget

Post by Peter »

ljgww wrote:Maybe some hint where I can look into that and learn what is available?
ok, here is my attempt:

Code: Select all

EnableExplicit ; <- use it always!

#Xml = 0
#Dialog = 0

Runtime Enumeration Windows
  #win1
EndEnumeration

Runtime Enumeration Gadgets
  #edit1
  #BtnOK
  #BtnCancel
EndEnumeration

Runtime Procedure EventProcHandler()
  Debug "Event Triggered with event# " + EventGadget()
  Select EventGadget()
    Case #BtnOK ; ok
      Debug "OK button clicked"
      ; get the text from the edit field
      Debug "Text in the string field: '" + GetGadgetText(#edit1) + "'"
      FreeDialog(#Dialog) ; close dialog as we do not need it
    Case #BtnCancel       ; cancel
      Debug "Cancel button clicked. Abort and Close."
      FreeDialog(#Dialog) ; close dialog as we do not need it
  EndSelect
EndProcedure

Define XML$

XML$ = "<window id='#win1' name='window0' text='Dialog Title' minwidth='300' minheight='auto' flags='#PB_Window_ScreenCentered | #PB_Window_BorderLess | #PB_Window_SizeGadget'>" +
       "  <vbox>" +
       "    <text text='Enter String' />" +
       "    <string id='#edit1' width='50' height='30' />" +
       "    <hbox>" +
       "      <button id='#BtnOK' text='Save/Close' height='30' onevent='EventProcHandler()' />" +
       "      <button id='#BtnCancel' text='Cancel/Close' onevent='EventProcHandler()' />" +
       "    </hbox>" +
       "  </vbox>" +
       "</window>"

If ParseXML(#Xml, XML$) And XMLStatus(#Xml) = #PB_XML_Success
  If CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "window0") ; window to open via name
    
    ; Example set values when dialog opens
    SetGadgetText(#edit1, "Some predefined text") ; Set the text in the field
    
  Else
    Debug "Dialog error: " + DialogError(#Dialog)
  EndIf
Else
  Debug "XML error: " + XMLError(#Xml) + " (Line: " + XMLErrorLine(#Xml) + ")"
  ; line location not very helpful here all XML is one line string
EndIf 
Notice the 'onevent'-Attribute in the XML.

Greetings ... Peter
ljgww
Posts: 26
Joined: Thu Mar 26, 2020 5:47 pm

Re: XML dialog - how to - events handling and text gadget

Post by ljgww »

Aha! Handler can go as a 'property' of the gadget definition. This makes it even easier and more readable.

I realize I did not catch this on, from the doc: https://www.spiderbasic.com/documentati ... ialog.html

but yes - its there under: V. Gadget elements
along with some other interesting events :)

Thank you for pointing this out.
Post Reply