@c -----------------------------------------------------------------------------
@c File     : gtk-dialogs.texi
@c License  : GNU General Public License (GPL)
@c Language : English
@c Author   : Dieter Kaiser
@c Date     : 11.09.2013
@c Revision : 11.09.2013
@c
@c Copyright (C) 2013 by Dieter Kaiser
@c -----------------------------------------------------------------------------

@menu
* General Dialog::
* Message Dialog::
* About Dialog::
@end menu

@c -----------------------------------------------------------------------------
@node General Dialog, Message Dialog, Top, Top
@section General Dialog

@ifnotinfo
@float Figure, figure-dialog-window
@caption{General Dialog Window}
@center @image{figures/dialog-window403x167, 269pt}
@end float
@end ifnotinfo

@findex GtkDialog
@findex gtk-dialog
@findex dialog, gtk-dialog

@findex gtk-dialog-new
@findex dialog-new, gtk-dialog-new

@findex gtk-dialog-new-with-buttons
@findex dialog-new-with-buttons, gtk-dialog-new-with-buttons

The dialog widget is just a window with a few things pre-packed into it.  The
dialog widget is of type @code{GtkDialog} which is represented by the Lisp
class @xurl{gtk-dialog}.  A dialog widget can be created with the function
@xurl{gtk-dialog-new} or the call @code{(make-instance 'gtk-dialog)}.  The
function @xurl{gtk-dialog-new} does not take an argument.  In addition the
function @xurl{gtk-dialog-new-with-buttons} is available.  It allows you to set
the dialog title, some convenient flags, and add simple buttons.

The dialog widget consists of an content area which is of type @xurl{gtk-box}
with the value @code{:vertical} of type @xurl{gtk-orientation}.  The content
area can be filled with the content of a dialog.  At the button of the window
the dialog widget has an action area which takes the desired buttons of the
dialog.

@findex gtk-dialog-get-content-area
@findex dialog-get-content-area, gtk-dialog-get-content-area

The function @xurl{gtk-dialog-get-content-area} gets the content area of a
dialog.  Because the content area is a vertical box of type @xurl{gtk-box} any
desired widgets can be added to the content area with the functions
@xurl{gtk-box-pack-start} or @xurl{gtk-box-pack-end}.  To display the content
area it is necessary to call the function @xurl{gtk-widget-show} explicitly.
The function @code{create-dialog} in @ref{example-dialog-window} shows
how to fill widgets into a dialog widget.

@findex gtk-dialog-add-button
@findex dialog-add-button, gtk-dialog-add-button

@findex GtkResponseType
@findex gtk-response-type
@findex response-type, gtk-response-type

The action area can be filled with the desired buttons for the dialog window.
Standard buttons can be added with the function @xurl{gtk-dialog-add-button}.
The function takes three arguments.  The first argument is the dialog window
the button is added to.  The second argument is a string which is the text
of the button or a stock ID.  The last argument is of the enumeration type
@xurl{gtk-response-type} and defines the response type of the button.  Possible
values of @xurl{gtk-response-type} are shown in @ref{table-gtk-response-type}.

@findex gtk-dialog-get-action-area
@findex dialog-get-action-area, gtk-dialog-get-action-area

Alternatively to the function @xurl{gtk-dialog-add-button} buttons can be
added with the functions @xurl{gtk-box-pack-start} or @xurl{gtk-box-pack-end} to
the action area.  The action area is of type @xurl{gtk-button-box} with a
@code{:horizontal} orientation and can be get with the function
@xurl{gtk-dialog-get-action-area}.

@float Table, table-gtk-response-type
@caption{Values of the @xurl{gtk-response-type} enumeration}
@end float
@table @code
@item :none
      Returned if an action widget has no response ID, or if the dialog gets
      programmatically hidden or destroyed.
@item :reject
      Generic response ID, not used by GTK+ dialogs
@item :accept
      Generic response ID, not used by GTK+ dialogs
@item :event
      Returned if the dialog is deleted
@item :ok
      Returned by OK buttons in GTK+ dialogs
@item :cancel
      Returned by Cancel buttons in GTK+ dialogs
@item :close
      Returned by Close buttons in GTK+ dialogs
@item :yes
      Returned by Yes buttons in GTK+ dialogs
@item :no
      Returned by No buttons in GTK+ dialogs
@item :apply
      Returned by Apply buttons in GTK+ dialogs
@item :help
      Returned by Help buttons in GTK+ dialogs
@end table

@findex gtk-dialog-run
@findex dialog-run, gtk-dialog-run

After creation and configuration of the dialog window the dialog is executed
with the function @xurl{gtk-dialog-run}.  The function takes the dialog window
of type @xurl{gtk-dialog} as the only argument.  After closing the dialog window
with one of the buttons the response is returned as an integer value of type
@xurl{gtk-response-type}.

@c -----------------------------------------------------------------------------
@node Message Dialog, About Dialog, General Dialog, Top
@section Message Dialog

@findex GtkMessageDialog
@findex gtk-message-dialog
@findex message-dialog, gtk-message-dialog

@ifnotinfo
@float Figure, figure-message-dialog
@caption{Message Dialog}
@center @image{figures/message-dialog480x157, 320pt}
@end float
@end ifnotinfo

A message dialog @xurl{gtk-message-dialog} is a subclass of the more general
class @xurl{gtk-dialog} and gives an easy way to display messages to the user.
@ref{figure-message-dialog} shows an example for an informational message.

@findex gtk-message-dialog-new
@findex message-dialog-new, gtk-message-dialog-new

@findex gtk-message-dialog-new-with-markup
@findex message-dialog-new-with-markup, gtk-message-dialog-new-with-markup

@findex gtk-message-type
@findex message-type, gtk-message-type

@findex gtk-buttons-type
@findex buttons-type, gtk-buttons-type

A message dialog is created with the call
@code{(make-instance 'gtk-message-dialog)} or the functions
@xurl{gtk-message-dialog-new} and @xurl{gtk-message-dialog-new-with-markup}.
Various properties control the appearance of a message dialog.  The function
@code{create-message-dialog} in @ref{example-dialog-window} shows the settings
of the properties @code{message-type}, @code{buttons}, @code{text}, and
@code{secondary-text}.  The type of a message dialog is one of the values of
the @xurl{gtk-message-type} enumeration.  The possible values are listed in
@ref{table-gtk-message-type}.  Predefined buttons of the @xurl{gtk-buttons-type}
enumeration for a message dialog are listed in @ref{table-gtk-buttons-type}.

@float Table, table-gtk-message-type
@caption{The type of message being displayed in the dialog.}
@shortcaption{Values of the type @xurl{gtk-message-type}}
@end float
@table @code
@item :info
      Informational message
@item :warning
      Nonfatal warning message
@item :question
      Question requiring a choice
@item :error
      Fatal error message
@item :other
      None of the above, doesn't get an icon
@end table

@float Table, table-gtk-buttons-type
@caption{Prebuilt sets of buttons for a message dialog.}
@end float
@table @code
@item :none
      no buttons at all
@item :ok
      an OK button
@item :close
      a Close button
@item :canel
      a Cancel button
@item :yes-no
      Yes and No buttons
@item :ok-cancel
      OK and Cancel buttons
@end table

@c -----------------------------------------------------------------------------
@node About Dialog, , Message Dialog, Top
@section About Dialog

@findex GtkAboutDialog
@findex gtk-about-dialog
@findex about-dialog, gtk-about-dialog

@ifnotinfo
@float Figure, figure-about-dialog
@caption{About Dialog}
@center @image{figures/about-dialog353x228, 235pt}
@end float
@end ifnotinfo

The @xurl{gtk-about-dialog} offers a simple way to display information about a
program like its logo, name, copyright, website and license.  It is also
possible to give credits to the authors, documenters, translators and
artists who have worked on the program.  An about dialog is typically opened
when the user selects the About option from the Help menu.  All parts of the
dialog are optional.

About dialogs often contain links and email addresses.  @xurl{gtk-about-dialog}
displays these as clickable links.  By default, it calls the function
@xurl{gtk-show-uri} when a user clicks one.  The behavior can be overridden with
the "activate-link" signal.

To make constructing a @xurl{gtk-about-dialog} as convenient as possible, the
function @xurl{gtk-show-about-dialog} is available which constructs and
shows a dialog and keeps it around so that it can be shown again.

Note that GTK+ sets a default title of @code{_("About %s")} on the dialog
window, where @code{%s} is replaced by the name of the application, but in
order to ensure proper translation of the title, applications should set the
title property explicitly when constructing a @xurl{gtk-about-dialog}.

It is possible to show a @xurl{gtk-about-dialog} like any other
@xurl{gtk-dialog}, e. g. using @xurl{gtk-dialog-run}.  In this case, you might
need to know that the 'Close' button returns the @code{:cancel} response ID.

@float Example, example-dialog-window
@caption{Examples for a general, a message, and an about dialog.}
@end float
@verbatim
(defun license-text ()
  (format nil
          "This program is free software: you can redistribute it and/or ~
          modify it under the terms of the GNU Lesser General Public ~
          License for Lisp as published by the Free Software Foundation, ~
          either version 3 of the License, or (at your option) any later ~
          version and with a preamble to the GNU Lesser General Public ~
          License that clarifies the terms for use with Lisp programs and ~
          is referred as the LLGPL.~%~% ~
          This program is distributed in the hope that it will be useful, ~
          but WITHOUT ANY WARRANTY; without even the implied warranty of ~
          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ~
          GNU Lesser General Public License for more details. ~%~% ~
          You should have received a copy of the GNU Lesser General Public ~
          License along with this program and the preamble to the Gnu ~
          Lesser General Public License.  If not, see ~
          <http://www.gnu.org/licenses/> and ~
          <http://opensource.franz.com/preamble.html>."))

(defun create-dialog ()
  (let ((dialog (make-instance 'gtk-dialog
                               :title "Dialog Window"
                               :has-separator t)))
    ;; Add a border width to the vbox of the content area
    (setf (gtk-container-border-width (gtk-dialog-get-content-area dialog))
          12)
    ;; Add a label widget with text to the content area
    (let ((vbox (make-instance 'gtk-vbox :border-width 12))
          (label (make-instance 'gtk-label
                                :wrap t
                                :label
                                (format nil
                                        "The content area is the place to ~
                                         put in the widgets.~%~% ~
                                         The action area is separated from ~
                                         the content area with a horizontal ~
                                         line."))))
      (gtk-box-pack-start vbox label)
      (gtk-box-pack-start (gtk-dialog-get-content-area dialog) vbox)
      ;; Show the content area of the dialog
      (gtk-widget-show (gtk-dialog-get-content-area dialog)))
    ;; Add buttons with a stock ID to the action area
    (gtk-dialog-add-button dialog "gtk-yes" :yes)
    (gtk-dialog-add-button dialog "gtk-no" :no)
    (gtk-dialog-add-button dialog "gtk-cancel" :cancel)
    (gtk-dialog-set-default-response dialog :cancel)
    ;; Change the order of the buttons
    (gtk-dialog-set-alternative-button-order dialog
                                             (list :yes :cancel :no))
    ;; Run the dialog and print the message on the console
    (format t "Response was: ~S~%" (gtk-dialog-run dialog))
    ;; Destroy the dialog
    (gtk-widget-destroy dialog)))

(defun create-message-dialog ()
  (let ((dialog (make-instance 'gtk-message-dialog
                               :message-type :info
                               :buttons :ok
                               :text "Info Message Dialog"
                               :secondary-text
                               (format nil
                                       "This is a message dialog of type ~
                                        :info with a secondary text."))))
    ;; Run the message dialog
    (gtk-dialog-run dialog)
    ;; Destroy the message dialog
    (gtk-widget-destroy dialog)))

(defun create-about-dialog ()
  (let ((dialog (make-instance 'gtk-about-dialog
                               :program-name "Example Dialog"
                               :version "0.00"
                               :copyright "(c) Dieter Kaiser"
                               :website
                               "github.com/crategus/cl-cffi-gtk"
                               :website-label "Project web site"
                               :license (license-text)
                               :authors '("Kalyanov Dmitry"
                                          "Dieter Kaiser")
                               :documenters '("Dieter Kaiser")
                               :artists '("None")
                               :logo-icon-name
                               "applications-development"
                               :wrap-license t)))
    ;; Run the about dialog
    (gtk-dialog-run dialog)
    ;; Destroy the about dialog
    (gtk-widget-destroy dialog)))

(defun example-dialog ()
  (within-main-loop
    (let ((window (make-instance 'gtk-window
                                 :type :toplevel
                                 :title "Example Dialog"
                                 :default-width 250
                                 :border-width 12))
          (vbox (make-instance 'gtk-vbox
                               :spacing 6)))
      (g-signal-connect window "destroy"
                        (lambda (widget)
                          (declare (ignore widget))
                          (leave-gtk-main)))
      (gtk-container-add window vbox)
      (let ((button (make-instance 'gtk-button
                                   :label "Open a Dialog Window")))
        (gtk-box-pack-start vbox button)
        (g-signal-connect button "clicked"
           (lambda (widget)
             (declare (ignore widget))
             ;; Create and show the dialog
             (create-dialog))))
      (let ((button (make-instance 'gtk-button
                                   :label "Open a Message Dialog")))
        (gtk-box-pack-start vbox button)
        (g-signal-connect button "clicked"
           (lambda (widget)
             (declare (ignore widget))
             ;; Create and show the message dialog
             (create-message-dialog))))
      (let ((button (make-instance 'gtk-button
                                   :label "Open an About Dialog")))
        (gtk-box-pack-start vbox button)
        (g-signal-connect button "clicked"
           (lambda (widget)
             (declare (ignore widget))
             ;; Create and show the about dialog
             (create-about-dialog))))
      (gtk-box-pack-start vbox
                          (make-instance 'gtk-hseparator))
      ;; Create a quit button
      (let ((button (make-instance 'gtk-button
                                   :label "Quit")))
        (g-signal-connect button "clicked"
                          (lambda (widget)
                            (declare (ignore widget))
                            (gtk-widget-destroy window)))
        (gtk-box-pack-start vbox button))
      (gtk-widget-show window))))
@end verbatim

