text: 
  from albow.widgets.WidgetUtilities import wrapped_label
  
  from albow.widgets.Button import Button
  from albow.widgets.Label import Label
  
  from albow.dialog.Dialog import Dialog
  from albow.dialog.TitledDialog import TitledDialog
  
  from albow.layout.Row import Row
  from albow.layout.Column import Column
  from albow.input.TextField import TextField
  
  DEFAULT_ASK_RESPONSES = ["OK", "Cancel"]
  
  
  def alert(theMessage: str, theTitle: str = 'Alert!', theWrapWidth=100, **kwds):
      """
      Displays a message in a modal dialog, wrapped to the specified width in characters. The dialog can be dismissed by
      pressing Return, Enter or Escape.
  
      Args:
          theMessage:  The alert message to display
  
          theTitle:  The title to display in the dialog title bar
  
          theWrapWidth:  The wrap width in characters
  
          **kwds: Additional keyword parameters passed to the `albow.dialog.Dialog` constructor.
      """
      ttlDlg = TitledDialog(title=theTitle, message=theMessage, wrapWidth=theWrapWidth, **kwds)
      ttlDlg.present()
  
  
  def ask(theMessage: str, theResponses=None, default=0, cancel=-1, wrap_width=60, **kwds):
      """
      Displays a message in a modal dialog with a set of buttons labelled with the specified responses. Clicking a
      button causes the ask function to return the corresponding response string as its value. The default and
      cancel parameters are indexes into the response list specifying the values to be returned by Return/Enter
      and Escape, respectively.
  
      Args:
          theMessage: The message to display
  
          theResponses:  Possible responses
  
          default:  The index to the default message
  
          cancel: The index to the cancel message
  
          wrap_width:  The wrap width in characters
  
          **kwds: Additional keyword parameters passed to the Dialog constructor.
  
      Returns:    The dialog modal result
  
      """
  
      #
      # Fix 'Mutable default arguments'
      #
      if theResponses is None:
          theResponses = DEFAULT_ASK_RESPONSES
  
      box = Dialog(**kwds)
      d   = box.margin
      lb  = wrapped_label(theMessage, wrap_width)
  
      lb.topleft = (d, d)
      buts = []
      for caption in theResponses:
          but = Button(caption, action=lambda x=caption: box.dismiss(x))
          buts.append(but)
  
      brow = Row(buts, spacing=d, equalize='w')
      lb.width = max(lb.width, brow.width)
      col = Column([lb, brow], spacing=d, align='r')
      col.topleft = (d, d)
  
      if default is not None:
          box.enter_response = theResponses[default]
      else:
          box.enter_response = None
      if cancel is not None:
          box.cancel_response = theResponses[cancel]
      else:
          box.cancel_response = None
  
      box.add(col)
      box.shrink_wrap()
  
      return box.present()
  
  
  def input_text(thePrompt: str, theInputWidth: int, theDefaultInput: str = None, **kwds):
  
      """
      Presents a modal dialog containing the given prompt and a text field. The theInputWidth is the width of
      the text field, and the theDefaultInput, if any, is its initial contents. If the dialog is dismissed by pressing
      Return or Enter, the contents of the text field is returned. If it is dismissed by pressing Escape, None
      is returned.
  
      Args:
          thePrompt:      The message to prompt with
  
          theInputWidth:  The width of the input text widget
  
          theDefaultInput: A possible default input
  
          **kwds:  Additional keyword parameters passed to the Dialog constructor.
  
      Returns:  The value that the user input
      """
      box = Dialog(**kwds)
      d = box.margin
  
      def ok():
          box.dismiss(True)
  
      def cancel():
          box.dismiss(False)
  
      lb = Label(thePrompt)
      lb.topleft = (d, d)
      tf = TextField(theInputWidth)
      if theDefaultInput:
          tf.set_text(theDefaultInput)
      tf.enter_action = ok
      tf.escape_action = cancel
      tf.top = lb.top
      tf.left = lb.right + 5
      box.add(lb)
      box.add(tf)
      tf.focus()
      box.shrink_wrap()
      if box.present():
          return tf.get_text()
      else:
          return None
  