[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12. Selecting Colors, Files and Fonts


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.1 Selecting Colors


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.1.1 Representing Colors

Colors are represented as a structure of the type gdk-rgba, which is defined in the library GDK. The stucture has the properties red, green, blue, and alpha to represent rgba colors. It is based on cairo's way to deal with colors and mirrors its behavior. All values are in the range from 0.0d0 to 1.0d0 inclusive. So the color (0.0d0, 0.0d0, 0.0d0, 0.0d0) represents transparent black and (1.0d0, 1.0d0, 1.0d0, 1.0d0) is opaque white. Other values will be clamped to this range when drawing.

To create a representation of the color red use (make-gdk-rgba :red 1.0d0). The function make-gdk-rgba is the constructor of the Lisp implementation for creating a gdk-rgba structure. Alternatively, the function gdk-rgba-parse parses a textual representation of a color, filling in the red, green, blue and alpha fields of the gdk-rgba structure. The string can be either one of:

Where r, g, b and a are respectively the red, green, blue and alpha color values. In the last two cases, r, g and b are either integers in the range 0 to 255 or precentage values in the range 0% to 100%, and a is a floating point value in the range 0 to 1.

Conversely, the function gdk-rgba-to-string returns a textual specification of the rgba color in the form rgb (r, g, b) or rgba (r, g, b, a), where r, g, b and a represent the red, green, blue and alpha values respectively. r, g, and b are represented as integers in the range 0 to 255, and a is represented as floating point value in the range 0 to 1.

These string forms are string forms those supported by the CSS3 colors module, and can be parsed by the function gdk-rgba-parse.

Note that this string representation may loose some precision, since r, g, and b are represented as 8-bit integers. If this is a concern, you should use a different representation.

A simple example is the representation of the color red, which can be created with the call (gdk-rgba-parse "Red" from a string and converted back to a textual with the call (gdk-rgba-to-string (gdk-rgba-parse "Red")). The result of the last function is "rgba(255,0,0,0)".

Note, that GTK+ knows a second representation of colors as a structure of type gdk-color. The implementation is semilar. The widgets for choosing a color know both representations.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.1.2 Color Button and Color Chooser Dialog

figures/color-button

Figure 12.1: Color Selecting Dialog

The gtk-color-button is a button which displays the currently selected color and allows to open a color selection dialog to change the color. It is suitable widget for selecting a color in a preference dialog. It implements the gtk-color-chooser interface.

example-color-button shows a simple implementation of a GtkColorButton. The example displays a button with the predefined color gray. When clicking the button, a color selection dialog is opened. The dialog is shown in figure-color-button. To get the currently selected color you should connect a signal handler to the signal "color-set" and the retrieve the color with the function gtk-color-chooser-get-rgba.

Example 12.1: Color Button

(let ((color (gdk-rgba-parse "Gray")))
  (defun example-color-button ()
    (within-main-loop
      (let ((window (make-instance 'gtk-window
                                   :title "Example Color Button"
                                   :border-width 12
                                   :default-width 250
                                   :default-height 200))
            (button (make-instance 'gtk-color-button
                                   :rgba color)))
        (g-signal-connect window "destroy"
                          (lambda (widget)
                            (declare (ignore widget))
                            (leave-gtk-main)))
        (g-signal-connect button "color-set"
           (lambda (widget)
             (let ((rgba (gtk-color-chooser-get-rgba widget)))
               (format t "Selected color is ~A~%"
                       (gdk-rgba-to-string rgba)))))
        (gtk-container-add window button)
        (gtk-widget-show-all window)))))

The gtk-color-chooser-dialog widget is a dialog for choosing a color. It implements the gtk-color-chooser interface. To provide a dialog in the gtk-color-chooser-dialog the gtk-color-chooser-widget is used.

By default, the chooser presents a prefined palette of colors, plus a small number of settable custom colors. It is also possible to select a different color with the single-color editor. To enter the single-color editing mode, use the context menu of any color of the palette, or use the '+' button to add a new custom color.

The chooser automatically remembers the last selection, as well as custom colors.

To change the initially selected color, use the function gtk-color-chooser-set-rgba. To get the selected color use the function gtk-color-chooser-get-rgba.

example-color-chooser-dialog shows how to replace the default color palette and the default gray palette with the function gtk-color-chooser-add-palette.

figures/color-chooser-dialog

Figure 12.2: Color Selecting Dialog with a custom color and gray palette

Example 12.2: Color Chooser Dialog

(let ((color (gdk-rgba-parse "Blue"))
      ;; Color palette with 4 rgba colors
      (palette1 (list (gdk-rgba-parse "Red")
                      (gdk-rgba-parse "Yellow")
                      (gdk-rgba-parse "Blue")
                      (gdk-rgba-parse "Green")))
      ;; Gray palette with 3 rgba grays
      (palette2 (list (gdk-rgba-parse "White")
                      (gdk-rgba-parse "Gray")
                      (gdk-rgba-parse "Black"))))
  (defun drawing-area-event (widget event area)
    (declare (ignore widget))
    (let ((handled nil))
      (when (eql (gdk-event-type event) :button-press)
        (let ((dialog (make-instance 'gtk-color-chooser-dialog
                                      :color color
                                      :use-alpha nil)))
          (setq handled t)
          ;; Add a custom palette to the dialog
          (gtk-color-chooser-add-palette dialog :vertical 1 palette1)
          ;; Add a second coustom palette to the dialog
          (gtk-color-chooser-add-palette dialog :vertical 1 palette2)
          ;; Run the color chooser dialog
          (let ((response (gtk-dialog-run dialog)))
            (when (eql response :ok)
              (setq color (gtk-color-chooser-get-rgba dialog)))
            ;; Set the color of the area widget
            (gtk-widget-override-background-color area :normal color)
            ;; Destroy the color chooser dialog
            (gtk-widget-destroy dialog))))
      handled))

  (defun example-color-chooser-dialog ()
    (within-main-loop
      (let ((window (make-instance 'gtk-window
                                   :title "Example Color Chooser Dialog"
                                   :default-width 300))
            (area (make-instance 'gtk-drawing-area)))
        (g-signal-connect window "destroy"
                          (lambda (widget)
                            (declare (ignore widget))
                            (leave-gtk-main)))
        (gtk-widget-override-background-color area :normal color)
        (setf (gtk-widget-events area) :button-press-mask)
        (g-signal-connect area "event"
                          (lambda (widget event)
                            (drawing-area-event widget event area)))
        (gtk-container-add window area)
        (gtk-widget-show-all window)))))

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.2 Selecting Files

figures/file-chooser-dialog

Figure 12.3: File Chooser Dialog

gtk-file-chooser is an interface that can be implemented by file selection widgets. In GTK+, the main objects that implement this interface are gtk-file-chooser-widget, gtk-file-chooser-dialog, and gtk-file-chooser-button. You do not need to write an object that implements the gtk-file-chooser interface unless you are trying to adapt an existing file selector to expose a standard programming interface.

gtk-file-chooser allows for shortcuts to various places in the filesystem. In the default implementation these are displayed in the left pane. It may be a bit confusing at first that these shortcuts come from various sources and in various flavours, so lets explain the terminology here:

Bookmarks

are created by the user, by dragging folders from the right pane to the left pane, or by using the "Add". Bookmarks can be renamed and deleted by the user.

Shortcuts

can be provided by the application or by the underlying filesystem abstraction (e.g. both the gnome-vfs and the Windows filesystems provide "Desktop" shortcuts). Shortcuts cannot be modified by the user.

Volumes

are provided by the underlying filesystem abstraction. They are the "roots" of the filesystem.

File Names and Encodings

When the user is finished selecting files in a gtk-file-chooser, your program can get the selected names either as filenames or as URIs. For URIs, the normal escaping rules are applied if the URI contains non-ASCII characters. However, filenames are always returned in the character set specified by the G_FILENAME_ENCODING environment variable. Please see the Glib documentation for more details about this variable.

Note: This means that while you can pass the result of gtk-file-chooser-get-filename to open(2) or fopen(3), you may not be able to directly set it as the text of a gtk-label widget unless you convert it first to UTF-8, which all GTK+ widgets expect. You should use the function g-filename-to-utf8 to convert filenames into strings that can be passed to GTK+ widgets.

Adding a Preview Widget

You can add a custom preview widget to a file chooser and then get notification about when the preview needs to be updated. To install a preview widget, use gtk-file-chooser-set-preview-widget. Then, connect to the "update-preview" signal to get notified when you need to update the contents of the preview.

Your callback should use gtk-file-chooser-get-preview-filename to see what needs previewing. Once you have generated the preview for the corresponding file, you must call gtk-file-chooser-set-preview-widget-active with a boolean flag that indicates whether your callback could successfully generate a preview.

Adding Extra Widgets

You can add extra widgets to a file chooser to provide options that are not present in the default design. For example, you can add a toggle button to give the user the option to open a file in read-only mode. You can use gtk-file-chooser-set-extra-widget to insert additional widgets in a file chooser.

Note: If you want to set more than one extra widget in the file chooser, you can use a container such as a gtk-vbox or a gtk-table and include your widgets in it. Then, set the container as the whole extra widget.

gtk-file-chooser-dialog is a dialog box suitable for use with "File/Open" or "File/Save as" commands. This widget works by putting a gtk-file-chooser-widget inside a gtk-dialog. It exposes the GtkFileChooserIface interface, so you can use all of the gtk-file-chooser functions on the file chooser dialog as well as those for gtk-dialog.

Note that gtk-file-chooser-dialog does not have any methods of its own. Instead, you should use the functions that work on a gtk-file-chooser.

Setting up a file chooser dialog

The enumeration gtk-file-chooser-action describes whether a gtk-file-chooser is being used to open existing files or to save to a possibly new file. These are the cases in which you may need to use a gtk-file-chooser-dialog.

Response Codes

gtk-file-chooser-dialog inherits from gtk-dialog, so buttons that go in its action area have response codes such as :accept and :canel. For example, you could create a file chooser dialog as follows:

(let ((dialog (gtk-file-chooser-dialog-new "Speichern"
                                           nil
                                           :save
                                           "gtk-save" :accept
                                           "gtk-cancel" :cancel)))
[...]

This will create buttons for "Cancel" and "Save" that use stock response identifiers from gtk-response-type. For most dialog boxes you can use your own custom response codes rather than the ones in gtk-response-type, but gtk-file-chooser-dialog assumes that its "accept"-type action, e. g. an "Open" or "Save" button, will have one of the following response codes :accept, :ok, :yes, or :apply.

This is because gtk-file-chooser-dialog must intercept responses and switch to folders if appropriate, rather than letting the dialog terminate - the implementation uses these known response codes to know which responses can be blocked if appropriate. To summarize, make sure you use a stock response code when you use gtk-file-chooser-dialog to ensure proper operation.

example-file-chooser-dialog shows an example for selecting a file for save. The dialog is shown in figure-file-chooser-dialog.

Example 53: File Chooser Dialog

(defun example-file-chooser-dialog ()
  (within-main-loop
    (let ((window (make-instance 'gtk-window
                                 :title "Example File Chooser Dialog"
                                 :type :toplevel
                                 :border-width 12
                                 :default-width 300
                                 :default-height 100))
          (button (make-instance 'gtk-button
                                 :label "Select a file for save ..."
                                 :image
                                 (gtk-image-new-from-stock "gtk-save"
                                                           :button))))
      ;; Handle the signal "destroy" for the window.
      (g-signal-connect window "destroy"
                        (lambda (widget)
                          (declare (ignore widget))
                          (leave-gtk-main)))
      ;; Handle the signal "clicked" for the button.
      (g-signal-connect button "clicked"
         (lambda (widget)
           (declare (ignore widget))
           (let ((dialog (gtk-file-chooser-dialog-new "Speichern"
                                                      nil
                                                      :save
                                                      "gtk-save" :accept
                                                      "gtk-cancel" :cancel)))
             (when (eq (gtk-dialog-run dialog) :accept)
               (format t "Saved to file ~A~%"
                       (gtk-file-chooser-get-filename dialog)))
             (gtk-widget-destroy dialog))))
      (gtk-container-add window button)
      (gtk-widget-show-all window))))

The gtk-file-chooser-button is a widget that lets the user select a file. It implements the gtk-file-chooser interface. Visually, it is a file name with a button to bring up a gtk-file-chooser-dialog. The user can then use that dialog to change the file associated with that button.

example-file-chooser-button shows an example for a file chooser button to open a file.

Example 54: File Chooser Button

(defun example-file-chooser-button ()
  (within-main-loop
    (let ((window (make-instance 'gtk-window
                                 :title "Example File Chooser Button"
                                 :type :toplevel
                                 :border-width 12
                                 :default-width 300
                                 :default-height 100))
          (button (make-instance 'gtk-file-chooser-button
                                 :action :open)))
      (g-signal-connect window "destroy"
                        (lambda (widget)
                          (declare (ignore widget))
                          (leave-gtk-main)))
      (g-signal-connect button "file-set"
                        (lambda (widget)
                          (declare (ignore widget))
                          (format t "File set: ~A~%"
                                  (gtk-file-chooser-get-filename button))))
      (gtk-container-add window button)
      (gtk-widget-show-all window))))

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.3 Selecting Fonts

figures/font-chooser-dialog

Figure 12.4: Font Chooser Dialog

The gtk-font-chooser-widget widget lists the available fonts, styles and sizes, allowing the user to select a font. It is used in the gtk-font-chooser-dialog widget to provide a dialog box for selecting fonts.

The gtk-font-chooser-dialog widget is a dialog for selecting a font. It implements the gtk-font-chooser interface.

To set the font which is initially selected, use the functions gtk-font-chooser-set-font or gtk-font-chooser-set-font-desc.

To get the selected font use the functions gtk-font-chooser-get-font or gtk-font-chooser-get-font-desc.

To change the text which is shown in the preview area, use the function gtk-font-chooser-set-preview-text.

The gtk-font-button is a button which displays the currently selected font and allows to open a font chooser dialog to change the font. It is a suitable widget for selecting a font in a preference dialog.

Example 12.1: Font Chooser Dialog with a filter to select fonts

(defun font-filter (family face)
  (declare (ignore face))
  (member (pango-font-family-get-name family)
          '("Sans" "Serif")
          :test #'equal))

(defun example-font-button ()
  (within-main-loop
    (let ((window (make-instance 'gtk-window
                                 :title "Example Font Chooser Button"
                                 :type :toplevel
                                 :border-width 12
                                 :default-width 300
                                 :default-height 100))
          (button (make-instance 'gtk-font-button)))
      (g-signal-connect window "destroy"
                        (lambda (widget)
                          (declare (ignore widget))
                          (leave-gtk-main)))
      ;; Set a filter function to select fonts for the font chooser
      (gtk-font-chooser-set-filter-func button #'font-filter)
      (g-signal-connect button "font-set"
         (lambda (widget)
           (declare (ignore widget))
           (format t "Font is set:~%")
           (format t "   Font name   : ~A~%"
                   (gtk-font-chooser-get-font button))
           (format t "   Font family : ~A~%"
                   (pango-font-family-get-name
                     (gtk-font-chooser-get-font-family button)))
           (format t "   Font face   : ~A~%"
                   (pango-font-face-get-face-name
                     (gtk-font-chooser-get-font-face button)))
           (format t "   Font size   : ~A~%"
                   (gtk-font-chooser-get-font-size button))))
      (gtk-container-add window button)
      (gtk-widget-show-all window))))

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Crategus on January, 10 2016 using texi2html 1.76.