November 28, 2020, 02:36:07 PM

Author Topic: [bmx] Auto Form by Otus [ 1+ years ago ]  (Read 723 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] Auto Form by Otus [ 1+ years ago ]
« on: June 29, 2017, 12:28:42 AM »
Title : Auto Form
Author : Otus
Posted : 1+ years ago

Description : Input data from user to an object based on field names. A form is automatically generated using reflection and MaxGUI.

Supports text fields, requesters, check boxes and combo boxes.

Edit: Refactored the magic numbers and strings out.
Edit2: Added file&dir requesters

Example:
Code: [Select]
SuperStrict

Framework MaxGUI.Drivers

Import "autoform.bmx"

Type TCustomer

Field Name:String

Field Age:Int

' Creates a combo box
Field _Type:String = "Unknown" { choose = "Regular,First_Timer,Unknown" }

' Creates a checkbox
Field Send_spam:Int = True { bool }

' Creates a file requester
Field Data_file:String { loadfile="Data_files_(*.dat):dat;All_files_(*.*):*" }

End Type


Local c:TCustomer = New TCustomer

AutoForm "Please enter details", c, FORM_TRIM_|FORM_RESIZABLE

Print c._type+": " + c.Name +" ("+c.age+") ["+c.Send_spam+"]"
Print c.Data_file

AutoForm "Modify details", c, FORM_RESET|FORM_TRIM_

Print c._type+": " + c.Name +" ("+c.age+") ["+c.Send_spam+"]"
Print c.Data_file


The code: [/i]

Code :
Code: BlitzMax
  1. SuperStrict
  2.  
  3. Import BRL.EventQueue
  4. Import BRL.Reflection
  5. Import MaxGUI.MaxGUI
  6.  
  7. Private
  8.  
  9. ' Sizes and spacing for general gadgets
  10. Const GADGET_X:Int = 170
  11. Const GADGET_Y:Int = 25
  12. Const SPACE_X:Int = 15
  13. Const SPACE_Y:Int = 10
  14.  
  15. ' Button (max) width
  16. Const BUTTON_X:Int = 80
  17.  
  18. ' Label height
  19. Const LABEL_Y:Int = 20
  20.  
  21. ' Strings
  22.  
  23. ' Meta strings to match
  24. Const META_DIRECTORY:String     = "directory"
  25. Const META_LOAD:String          = "loadfile"
  26. Const META_SAVE:String          = "savefile"
  27. Const META_CHECKBOX:String      = "bool"
  28. Const META_COMBOBOX:String      = "choose"
  29. Const META_SEPARATOR:String     = ","
  30.  
  31. ' Labels
  32. Const LABEL_AFTER:String                = ":"
  33. Const LABEL_BROWSE:String       = "Browse..."
  34. Const LABEL_OK:String           = "OK"
  35. Const LABEL_RESET:String                = "Reset"
  36.  
  37. ' Special characters
  38. Const UNDERSCORE:String         = "_"
  39. Const SPACE:String                      = " "
  40.  
  41. Public
  42.  
  43. Const FORM_TRIM_:Int    = 1             'Replace underscores with spaces and trim (Default)
  44. Const FORM_RESET:Int    = 2             'Show a Reset button
  45. Const FORM_SKIP_:Int    = 4             'Skip fields beginning with underscores
  46. Const FORM_RESIZABLE:Int        = 8             'Window allows resizing
  47.  
  48. ' Automatically generate a MaxGUI form based on an object
  49. ' Returns: True on success (OK), False on quit (WINDOW_CLOSE)
  50. Function AutoForm:Int(title:String, o:Object, opts:Int = FORM_TRIM_ )
  51.         Local i% = 0
  52.        
  53.         ' Object is required
  54.         If Not o Return False
  55.        
  56.         ' Find Type ID
  57.         Local tid:TTypeId = TTypeId.ForObject(o)
  58.        
  59.         ' Find Fields and calculate window size
  60.         Local flist:TList = tid.EnumFields()
  61.         Local fields:TField[flist.Count()]
  62.         Local sizex:Int = GADGET_X + 2*SPACE_X
  63.         Local sizey:Int = GADGET_Y + 2*SPACE_Y
  64.         For Local f:TField = EachIn flist
  65.                 ' Skip?
  66.                 If opts&FORM_SKIP_ And f.Name().StartsWith(UNDERSCORE) Then Continue
  67.                
  68.                 fields[i] = f
  69.                
  70.                 ' Calculate size
  71.                 If fields[i].MetaData(META_CHECKBOX)
  72.                         sizey :+ GADGET_Y + SPACE_Y
  73.                 Else If fields[i].MetaData(META_DIRECTORY) ..
  74.                         Or fields[i].MetaData(META_SAVE)..
  75.                         Or fields[i].MetaData(META_LOAD)
  76.                        
  77.                         sizex = GADGET_X + 3*SPACE_X + BUTTON_X
  78.                         sizey :+ LABEL_Y + GADGET_Y + SPACE_Y
  79.                 Else
  80.                         sizey :+ LABEL_Y + GADGET_Y + SPACE_Y
  81.                 End If
  82.                
  83.                 i :+ 1
  84.         Next
  85.         If FORM_SKIP_ fields = fields[..i]              'Removes empty elements
  86.        
  87.         ' Create window
  88.         Local flags:Int = WINDOW_CLIENTCOORDS | WINDOW_TITLEBAR | WINDOW_CENTER
  89.         If opts & FORM_RESIZABLE flags = flags | WINDOW_RESIZABLE
  90.         Local win:TGadget = CreateWindow( title, 0,0, sizex,sizey, Null, flags )
  91.        
  92.         ' Create gadgets for fields
  93.         Local flabels:TGadget[fields.length]    'Labels
  94.         Local ftexts:TGadget[fields.length]     'Text fields
  95.         Local fcombos:TGadget[fields.length]    'Combo boxes
  96.         Local fchecks:TGadget[fields.length]    'Check boxes
  97.         Local fbuttons:TGadget[fields.length]   'Buttons (browse)
  98.         Local y:Int = 10
  99.         For i = 0 Until fields.length
  100.                 ' Get Field name and trim
  101.                 Local n:String = fields[i].Name()
  102.                 If opts & FORM_TRIM_ Then n = n.Replace(UNDERSCORE, SPACE).Trim()
  103.                
  104.                 If fields[i].MetaData(META_CHECKBOX)
  105.                         ' Checkbox
  106.                         fchecks[i] = CreateButton(n, SPACE_X,y, GADGET_X,GADGET_Y, win, BUTTON_CHECKBOX)
  107.                         y :+ GADGET_Y + SPACE_Y
  108.                         SetButtonState fchecks[i], fields[i].GetInt(o)
  109.                         Continue
  110.                 End If
  111.                
  112.                 ' Create label
  113.                 flabels[i] = CreateLabel(n+LABEL_AFTER, SPACE_X,y, GADGET_X,LABEL_Y, win)
  114.                 y :+ LABEL_Y
  115.                
  116.                 Local c:String = fields[i].MetaData(META_COMBOBOX)
  117.                 If c    'Combo box
  118.                         If opts & FORM_TRIM_ Then c = c.Replace(UNDERSCORE, SPACE).Trim()
  119.                        
  120.                         fcombos[i] = CreateComboBox(SPACE_X,y, GADGET_X,GADGET_Y, win)
  121.                         Local value:String = fields[i].GetString(o)
  122.                         Local items:String[] = c.Split(META_SEPARATOR)
  123.                         For Local j:Int = 0 Until items.length
  124.                                 AddGadgetItem fcombos[i], items[j]
  125.                                 If items[j]=value Then SelectGadgetItem fcombos[i], j
  126.                         Next
  127.                        
  128.                 Else 'Text field
  129.                         ftexts[i] = CreateTextField(SPACE_X,y, GADGET_X,GADGET_Y, win)
  130.                         SetGadgetText ftexts[i], fields[i].GetString(o)
  131.                        
  132.                         If fields[i].MetaData(META_DIRECTORY)..
  133.                                 Or fields[i].MetaData(META_SAVE)..
  134.                                 Or fields[i].MetaData(META_LOAD)
  135.                                 fbuttons[i] = CreateButton( LABEL_BROWSE, 2*SPACE_X+GADGET_X,y, ..
  136.                                         BUTTON_X,GADGET_Y, win )
  137.                         End If
  138.                 End If
  139.                 y :+ GADGET_Y + SPACE_Y
  140.         Next
  141.        
  142.         ' Create buttons
  143.         Local ok:TGadget, reset:TGadget
  144.         If opts & FORM_RESET
  145.                 Local bx:Int = Min((sizex-3*SPACE_X)/2, BUTTON_X)
  146.                 Local sx:Int = (sizex-2*bx)/3
  147.                 ok = CreateButton(LABEL_OK, sx,y, bx,GADGET_Y, win, BUTTON_OK)
  148.                 reset = CreateButton(LABEL_RESET, 2*sx+bx,y, bx,GADGET_Y, win)
  149.         Else
  150.                 ok = CreateButton(LABEL_OK, (sizex-BUTTON_X)/2,y, BUTTON_X,GADGET_Y, win, BUTTON_OK)
  151.         End If
  152.        
  153.         ' Main loop
  154.         Repeat
  155.                 Select WaitEvent()
  156.                 Case EVENT_GADGETACTION
  157.                         Local source:Object = EventSource()
  158.                         ' OK
  159.                         If source=ok
  160.                                 Exit
  161.                        
  162.                         ' Reset
  163.                         Else If source=reset
  164.                                 For i = 0 Until fields.length
  165.                                         If ftexts[i]            'Text field
  166.                                                 SetGadgetText ftexts[i], fields[i].GetString(o)
  167.                                                
  168.                                         Else If fcombos[i]      'Combo box
  169.                                                 Local value:String = fields[i].GetString(o)
  170.                                                 For Local j% = 0 Until CountGadgetItems(fcombos[i])
  171.                                                         If GadgetItemText(fcombos[i],j)=value
  172.                                                                 SelectGadgetItem fcombos[i], j
  173.                                                                 Exit
  174.                                                         End If
  175.                                                 Next
  176.                                                
  177.                                         Else If fchecks[i]      'Check box
  178.                                                 SetButtonState fchecks[i], fields[i].GetInt(o)
  179.                                         End If
  180.                                 Next
  181.                        
  182.                         ' Browse
  183.                         Else
  184.                                 For i = 0 Until fields.length
  185.                                         If Not fbuttons[i] Or source<>fbuttons[i] Then Continue
  186.                                        
  187.                                         Local t:String = GadgetText(ftexts[i])
  188.                                         If fields[i].MetaData(META_DIRECTORY)
  189.                                                 t = RequestDir( GadgetText(flabels[i]), t )
  190.                                                
  191.                                         Else
  192.                                                 Local s:Int = True
  193.                                                 Local exts:String = fields[i].MetaData(META_SAVE)
  194.                                                 If Not exts
  195.                                                         s = False
  196.                                                         exts = fields[i].MetaData(META_LOAD)
  197.                                                 End If
  198.                                                 If opts & FORM_TRIM_
  199.                                                         exts = exts.Replace(UNDERSCORE, SPACE).Trim()
  200.                                                 End If
  201.                                                
  202.                                                 t = RequestFile( GadgetText(flabels[i]), exts, s, t )
  203.                                         End If
  204.                                         SetGadgetText ftexts[i], t
  205.                                 Next
  206.                         End If
  207.                        
  208.                 Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE
  209.                         ' Free all gadgets
  210.                         For Local g:TGadget = EachIn flabels+ftexts+fcombos+fchecks + [ok,reset,win]
  211.                                 FreeGadget g
  212.                         Next
  213.                         Return False
  214.                 End Select
  215.         Forever
  216.        
  217.         ' Write data to object
  218.         For i = 0 Until fields.length
  219.                 If ftexts[i]
  220.                         fields[i].SetString o, GadgetText(ftexts[i])
  221.                 Else If fcombos[i]
  222.                         fields[i].SetString o, GadgetItemText( fcombos[i], SelectedGadgetItem(fcombos[i]) )
  223.                 Else If fchecks[i]
  224.                         fields[i].SetInt o, ButtonState(fchecks[i])
  225.                 End If
  226.         Next
  227.        
  228.         ' Free all gadgets
  229.         For Local g:TGadget = EachIn flabels+ftexts+fcombos+fchecks + [ok,reset,win]
  230.                 FreeGadget g
  231.         Next
  232.        
  233.         Return True
  234. End Function


Comments : none...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal