Blame platform-demos/de/combobox.js.page

Packit 1470ea
Packit 1470ea
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" xmlns:xi="http://www.w3.org/2001/XInclude" type="guide" style="task" id="combobox.js" xml:lang="de">
Packit 1470ea
  <info>
Packit 1470ea
  <title type="text">ComboBox (JavaScript)</title>
Packit 1470ea
    <link type="guide" xref="beginner.js#menu-combo-toolbar"/>
Packit 1470ea
    <link type="seealso" xref="GtkApplicationWindow.js"/>
Packit 1470ea
    <link type="seealso" xref="comboboxtext.js"/>
Packit 1470ea
    <link type="seealso" xref="messagedialog.js"/>
Packit 1470ea
    <link type="seealso" xref="treeview_simple_liststore.js"/>
Packit 1470ea
    <revision version="0.1" date="2012-07-09" status="draft"/>
Packit 1470ea
Packit 1470ea
    <credit type="author copyright">
Packit 1470ea
      <name>Taryn Fox</name>
Packit 1470ea
      <email its:translate="no">jewelfox@fursona.net</email>
Packit 1470ea
      <years>2012</years>
Packit 1470ea
    </credit>
Packit 1470ea
Packit 1470ea
    <desc>A customizable drop-down menu</desc>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Mario Blättermann</mal:name>
Packit 1470ea
      <mal:email>mario.blaettermann@gmail.com</mal:email>
Packit 1470ea
      <mal:years>2011, 2013</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  </info>
Packit 1470ea
Packit 1470ea
  <title>ComboBox</title>
Packit 1470ea
  <media type="image" mime="image/png" src="media/combobox_multicolumn.png"/>
Packit 1470ea
  

A ComboBox is an extremely customizable drop-down menu. It holds the equivalent of a <link xref="treeview_simple_liststore.js">TreeView</link> widget that appears when you click on it, complete with a ListStore (basically a spreadsheet) that says what's in the rows and columns. In this example, our ListStore has the name of each option in one column, and the name of a stock icon in the other, which the ComboBox then turns into an icon for each option.

Packit 1470ea
  

You select a whole horizontal row at a time, so the icons aren't treated as separate options. They and the text beside them make up each option you can click on.

Packit 1470ea
  <note style="tip">

Working with a ListStore can be time-consuming. If you just want a simple text-only drop-down menu, take a look at the <link xref="comboboxtext.js">ComboBoxText</link>. It doesn't take as much time to set up, and is easier to work with.

</note>
Packit 1470ea
    <links type="section"/>
Packit 1470ea
Packit 1470ea
  <section id="imports">
Packit 1470ea
    <title>Zu importierende Bibliotheken</title>
Packit 1470ea
    
Packit 1470ea
#!/usr/bin/gjs
Packit 1470ea
Packit 1470ea
imports.gi.versions.Gtk = '3.0';
Packit 1470ea
Packit 1470ea
const GObject = imports.gi.GObject;
Packit 1470ea
const Gtk = imports.gi.Gtk;
Packit 1470ea
]]>
Packit 1470ea
    

These are the libraries we need to import for this application to run. Remember that the line which tells GNOME that we're using Gjs always needs to go at the start.

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="applicationwindow">
Packit 1470ea
    <title>Entwurf des Anwendungsfensters</title>
Packit 1470ea
    
Packit 1470ea
class ComboBoxExample {
Packit 1470ea
Packit 1470ea
    // Create the application itself
Packit 1470ea
    constructor() {
Packit 1470ea
        this.application = new Gtk.Application ({
Packit 1470ea
            application_id: 'org.example.jscombobox'});
Packit 1470ea
Packit 1470ea
        // Connect 'activate' and 'startup' signals to the callback functions
Packit 1470ea
        this.application.connect('activate', this._onActivate.bind(this));
Packit 1470ea
        this.application.connect('startup', this._onStartup.bind(this));
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
    // Callback function for 'activate' signal presents windows when active
Packit 1470ea
    _onActivate() {
Packit 1470ea
        this._window.present ();
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
    // Callback function for 'startup' signal builds the UI
Packit 1470ea
    _onStartup() {
Packit 1470ea
        this._buildUI ();
Packit 1470ea
    }
Packit 1470ea
]]>
Packit 1470ea
    

All the code for this sample goes in the ComboBoxExample class. The above code creates a <link href="http://www.roojs.com/seed/gir-1.2-gtk-3.0/gjs/Gtk.Application.html">Gtk.Application</link> for our widgets and window to go in.

Packit 1470ea
    
Packit 1470ea
    // Build the application's UI
Packit 1470ea
    _buildUI() {
Packit 1470ea
Packit 1470ea
        // Create the application window
Packit 1470ea
        this._window = new Gtk.ApplicationWindow  ({
Packit 1470ea
            application: this.application,
Packit 1470ea
            window_position: Gtk.WindowPosition.CENTER,
Packit 1470ea
            title: "Welcome to GNOME",
Packit 1470ea
            default_width: 200,
Packit 1470ea
            border_width: 10 });
Packit 1470ea
]]>
Packit 1470ea
    

The _buildUI function is where we put all the code to create the application's user interface. The first step is creating a new <link xref="GtkApplicationWindow.js">Gtk.ApplicationWindow</link> to put all our widgets into.

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="liststore">
Packit 1470ea
    <title>Creating the ListStore</title>
Packit 1470ea
    
Packit 1470ea
        // Create the liststore to put our options in
Packit 1470ea
        this._listStore = new Gtk.ListStore();
Packit 1470ea
        this._listStore.set_column_types ([
Packit 1470ea
            GObject.TYPE_STRING,
Packit 1470ea
            GObject.TYPE_STRING]);
Packit 1470ea
Packit 1470ea
    

This ListStore works like the one used in the <link xref="treeview_simple_liststore.js">TreeView</link> example. We're giving it two columns, both strings, because one of them will contain the names of <link href="https://developer.gnome.org/gtk3/3.4/gtk3-Stock-Items.html">stock Gtk icons</link>.

Packit 1470ea
    

If we'd wanted to use our own icons that weren't already built in to GNOME, we'd have needed to use the <file>gtk.gdk.Pixbuf</file> type instead. Here are a few other types you can use:

Packit 1470ea
    <list>
Packit 1470ea
      <item>

<file>GObject.TYPE_BOOLEAN</file> -- True or false

</item>
Packit 1470ea
      <item>

<file>GObject.TYPE_FLOAT</file> -- A floating point number (one with a decimal point)

</item>
Packit 1470ea
      <item>

<file>GObject.TYPE_STRING</file> -- A string of letters and numbers

</item>
Packit 1470ea
    </list>
Packit 1470ea
    <note style="tip">

You need to put the line <file>const GObject = imports.gi.GObject;</file> at the start of your application's code, like we did in this example, if you want to be able to use GObject types.

</note>
Packit 1470ea
Packit 1470ea
    
Packit 1470ea
        // This array holds our list of options and their icons
Packit 1470ea
        let options = [{ name: "Select" },
Packit 1470ea
            { name: "New", icon: Gtk.STOCK_NEW },
Packit 1470ea
            { name: "Open", icon: Gtk.STOCK_OPEN },
Packit 1470ea
            { name: "Save", icon: Gtk.STOCK_SAVE }];
Packit 1470ea
Packit 1470ea
        // Put the options in the liststore
Packit 1470ea
        for (let i = 0; i < options.length; i++ ) {
Packit 1470ea
            let option = options[i];
Packit 1470ea
            let iter = this._listStore.append();
Packit 1470ea
            this._listStore.set (iter, [0], [option.name]);
Packit 1470ea
            if ('icon' in option)
Packit 1470ea
                this._listStore.set (iter, [1], [option.icon]);
Packit 1470ea
        }
Packit 1470ea
Packit 1470ea
    

Here we create an array of the text options and their corresponding icons, then put them into the ListStore in much the same way we would for a <link xref="treeview_simple_liststore.js">TreeView's</link> ListStore. We only want to put an icon in if there's actually an icon in the options array, so we make sure to check for that first.

Packit 1470ea
    <note style="tip">

"Select" isn't really an option so much as an invitation to click on our ComboBox, so it doesn't need an icon.

</note>
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="combobox">
Packit 1470ea
    <title>Creating the ComboBox</title>
Packit 1470ea
    
Packit 1470ea
        // Create the combobox
Packit 1470ea
        this._comboBox = new Gtk.ComboBox({
Packit 1470ea
            model: this._listStore});
Packit 1470ea
Packit 1470ea
    

Each ComboBox has an underlying "model" it takes all its options from. You can use a TreeStore if you want to have a ComboBox with branching options. In this case, we're just using the ListStore we already created.

Packit 1470ea
    
Packit 1470ea
        // Create some cellrenderers for the items in each column
Packit 1470ea
        let rendererPixbuf = new Gtk.CellRendererPixbuf();
Packit 1470ea
        let rendererText = new Gtk.CellRendererText();
Packit 1470ea
Packit 1470ea
        // Pack the renderers into the combobox in the order we want to see
Packit 1470ea
        this._comboBox.pack_start (rendererPixbuf, false);
Packit 1470ea
        this._comboBox.pack_start (rendererText, false);
Packit 1470ea
Packit 1470ea
        // Set the renderers to use the information from our liststore
Packit 1470ea
        this._comboBox.add_attribute (rendererText, "text", 0);
Packit 1470ea
        this._comboBox.add_attribute (rendererPixbuf, "stock_id", 1);
Packit 1470ea
Packit 1470ea
    

This part, again, works much like creating CellRenderers and packing them into the columns of a <link xref="treeview_simple_liststore.js">TreeView</link>. The biggest difference is that we don't need to create the ComboBox's columns as separate objects. We just pack the CellRenderers into it in the order we want them to show up, then tell them to pull information from the ListStore (and what type of information we want them to expect).

Packit 1470ea
    

We use a CellRendererText to show the text, and a CellRendererPixbuf to show the icons. We can store the names of the icons' stock types as strings, but when we display them we need a CellRenderer that's designed for pictures.

Packit 1470ea
    <note style="tip">

Just like with a TreeView, the "model" (in this case a ListStore) and the "view" (in this case our ComboBox) are separate. Because of that, we can do things like have the columns in one order in the ListStore, and then pack the CellRenderers that correspond to those columns into the ComboBox in a different order. We can even create a TreeView or other widget that shows the information in the ListStore in a different way, without it affecting our ComboBox.

</note>
Packit 1470ea
Packit 1470ea
    
Packit 1470ea
        // Set the first row in the combobox to be active on startup
Packit 1470ea
        this._comboBox.set_active (0);
Packit 1470ea
Packit 1470ea
        // Connect the combobox's 'changed' signal to our callback function
Packit 1470ea
        this._comboBox.connect ('changed', this._onComboChanged.bind(this));
Packit 1470ea
]]>
Packit 1470ea
    

We want the "Select" text to be the part people see at first, that gets them to click on the ComboBox. So we set it to be the active entry. We also connect the ComboBox's <file>changed</file> signal to a callback function, so that any time someone clicks on a new option something happens. In this case, we're just going to show a popup with a little haiku.

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
        // Add the combobox to the window
Packit 1470ea
        this._window.add (this._comboBox);
Packit 1470ea
Packit 1470ea
        // Show the window and all child widgets
Packit 1470ea
        this._window.show_all();
Packit 1470ea
    }
Packit 1470ea
]]>
Packit 1470ea
    

Finally, we add the ComboBox to the window, and tell the window to show itself and everything inside it.

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="function">
Packit 1470ea
    <title>Function which handles your selection</title>
Packit 1470ea
    
Packit 1470ea
    _selected() {
Packit 1470ea
Packit 1470ea
        // The silly pseudohaiku that we'll use for our messagedialog
Packit 1470ea
        let haiku = ["",
Packit 1470ea
            "You ask for the new\nwith no thought for the aged\nlike fallen leaves trod.",
Packit 1470ea
            "Like a simple clam\nrevealing a lustrous pearl\nit opens for you.",
Packit 1470ea
            "A moment in time\na memory on the breeze\nthese things can't be saved."];
Packit 1470ea
]]>
Packit 1470ea
    

We're going to create a pop-up <link xref="messagedialog.js">MessageDialog</link>, which shows you a silly haiku based on which distro you select. First, we create the array of haiku to use. Since the first string in our ComboBox is just the "Select" message, we make the first string in our array blank.

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
        // Which combobox item is active?
Packit 1470ea
        let activeItem = this._comboBox.get_active();
Packit 1470ea
Packit 1470ea
        // No messagedialog if you choose "Select"
Packit 1470ea
        if (activeItem != 0) {
Packit 1470ea
            this._popUp = new Gtk.MessageDialog ({
Packit 1470ea
                transient_for: this._window,
Packit 1470ea
                modal: true,
Packit 1470ea
                buttons: Gtk.ButtonsType.OK,
Packit 1470ea
                message_type: Gtk.MessageType.INFO,
Packit 1470ea
                text: haiku[activeItem]});
Packit 1470ea
Packit 1470ea
            // Connect the OK button to a handler function
Packit 1470ea
            this._popUp.connect ('response', this._onDialogResponse.bind(this));
Packit 1470ea
Packit 1470ea
            // Show the messagedialog
Packit 1470ea
            this._popUp.show();
Packit 1470ea
        }
Packit 1470ea
Packit 1470ea
    }
Packit 1470ea
]]>
Packit 1470ea
    

Before showing a MessageDialog, we first test to make sure you didn't choose the "Select" message. After that, we set its text to be the haiku in the array that corresponds to the active entry in our ComboBoxText. We do that using the <file>get_active</file> method, which returns the number ID of your selection.

Packit 1470ea
    <note style="tip">

Other methods you can use include <file>get_active_id</file>, which returns the text ID assigned by <file>append</file>, and <file>get_active_text</file>, which returns the full text of the string you selected.

</note>
Packit 1470ea
    

After we create the MessageDialog, we connect its response signal to the _onDialogResponse function, then tell it to show itself.

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
    _onDialogResponse() {
Packit 1470ea
Packit 1470ea
        this._popUp.destroy ();
Packit 1470ea
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
};
Packit 1470ea
]]>
Packit 1470ea
    

Since the only button the MessageDialog has is an OK button, we don't need to test its response_id to see which button was clicked. All we do here is destroy the popup.

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
// Run the application
Packit 1470ea
let app = new ComboBoxExample ();
Packit 1470ea
app.application.run (ARGV);
Packit 1470ea
Packit 1470ea
    

Finally, we create a new instance of the finished ComboBoxExample class, and set the application running.

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="complete">
Packit 1470ea
    <title>Complete code sample</title>
Packit 1470ea
#!/usr/bin/gjs
Packit 1470ea
Packit 1470ea
imports.gi.versions.Gtk = '3.0';
Packit 1470ea
Packit 1470ea
const GObject = imports.gi.GObject;
Packit 1470ea
const Gtk = imports.gi.Gtk;
Packit 1470ea
Packit 1470ea
class ComboBoxExample {
Packit 1470ea
Packit 1470ea
    // Create the application itself
Packit 1470ea
    constructor() {
Packit 1470ea
        this.application = new Gtk.Application ({
Packit 1470ea
            application_id: 'org.example.jscombobox'});
Packit 1470ea
Packit 1470ea
        // Connect 'activate' and 'startup' signals to the callback functions
Packit 1470ea
        this.application.connect('activate', this._onActivate.bind(this));
Packit 1470ea
        this.application.connect('startup', this._onStartup.bind(this));
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
    // Callback function for 'activate' signal presents windows when active
Packit 1470ea
    _onActivate() {
Packit 1470ea
        this._window.present ();
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
    // Callback function for 'startup' signal builds the UI
Packit 1470ea
    _onStartup() {
Packit 1470ea
        this._buildUI();
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
    // Build the application's UI
Packit 1470ea
    _buildUI() {
Packit 1470ea
Packit 1470ea
        // Create the application window
Packit 1470ea
        this._window = new Gtk.ApplicationWindow  ({
Packit 1470ea
            application: this.application,
Packit 1470ea
            window_position: Gtk.WindowPosition.CENTER,
Packit 1470ea
            title: "Welcome to GNOME",
Packit 1470ea
            default_width: 200,
Packit 1470ea
            border_width: 10 });
Packit 1470ea
Packit 1470ea
        // Create the liststore to put our options in
Packit 1470ea
        this._listStore = new Gtk.ListStore();
Packit 1470ea
        this._listStore.set_column_types ([
Packit 1470ea
            GObject.TYPE_STRING,
Packit 1470ea
            GObject.TYPE_STRING]);
Packit 1470ea
Packit 1470ea
        // This array holds our list of options and their icons
Packit 1470ea
        let options = [{ name: "Select" },
Packit 1470ea
            { name: "New", icon: Gtk.STOCK_NEW },
Packit 1470ea
            { name: "Open", icon: Gtk.STOCK_OPEN },
Packit 1470ea
            { name: "Save", icon: Gtk.STOCK_SAVE }];
Packit 1470ea
Packit 1470ea
        // Put the options in the liststore
Packit 1470ea
        for (let i = 0; i < options.length; i++ ) {
Packit 1470ea
            let option = options[i];
Packit 1470ea
            let iter = this._listStore.append();
Packit 1470ea
            this._listStore.set (iter, [0], [option.name]);
Packit 1470ea
            if ('icon' in option)
Packit 1470ea
                this._listStore.set (iter, [1], [option.icon]);
Packit 1470ea
        }
Packit 1470ea
Packit 1470ea
        // Create the combobox
Packit 1470ea
        this._comboBox = new Gtk.ComboBox({
Packit 1470ea
            model: this._listStore});
Packit 1470ea
Packit 1470ea
        // Create some cellrenderers for the items in each column
Packit 1470ea
        let rendererPixbuf = new Gtk.CellRendererPixbuf();
Packit 1470ea
        let rendererText = new Gtk.CellRendererText();
Packit 1470ea
Packit 1470ea
        // Pack the renderers into the combobox in the order we want to see
Packit 1470ea
        this._comboBox.pack_start (rendererPixbuf, false);
Packit 1470ea
        this._comboBox.pack_start (rendererText, false);
Packit 1470ea
Packit 1470ea
        // Set the renderers to use the information from our liststore
Packit 1470ea
        this._comboBox.add_attribute (rendererText, "text", 0);
Packit 1470ea
        this._comboBox.add_attribute (rendererPixbuf, "stock_id", 1);
Packit 1470ea
Packit 1470ea
        // Set the first row in the combobox to be active on startup
Packit 1470ea
        this._comboBox.set_active (0);
Packit 1470ea
Packit 1470ea
        // Connect the combobox's 'changed' signal to our callback function
Packit 1470ea
        this._comboBox.connect ('changed', this._onComboChanged.bind(this));
Packit 1470ea
Packit 1470ea
        // Add the combobox to the window
Packit 1470ea
        this._window.add (this._comboBox);
Packit 1470ea
Packit 1470ea
        // Show the window and all child widgets
Packit 1470ea
        this._window.show_all();
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
    _onComboChanged() {
Packit 1470ea
Packit 1470ea
        // The silly pseudohaiku that we'll use for our messagedialog
Packit 1470ea
        let haiku = ["",
Packit 1470ea
            "You ask for the new\nwith no thought for the aged\nlike fallen leaves trod.",
Packit 1470ea
            "Like a simple clam\nrevealing a lustrous pearl\nit opens for you.",
Packit 1470ea
            "A moment in time\na memory on the breeze\nthese things can't be saved."];
Packit 1470ea
Packit 1470ea
        // Which combobox item is active?
Packit 1470ea
        let activeItem = this._comboBox.get_active();
Packit 1470ea
Packit 1470ea
        // No messagedialog if you choose "Select"
Packit 1470ea
        if (activeItem != 0) {
Packit 1470ea
            this._popUp = new Gtk.MessageDialog ({
Packit 1470ea
                transient_for: this._window,
Packit 1470ea
                modal: true,
Packit 1470ea
                buttons: Gtk.ButtonsType.OK,
Packit 1470ea
                message_type: Gtk.MessageType.INFO,
Packit 1470ea
                text: haiku[activeItem]});
Packit 1470ea
Packit 1470ea
            // Connect the OK button to a handler function
Packit 1470ea
            this._popUp.connect ('response', this._onDialogResponse.bind(this));
Packit 1470ea
Packit 1470ea
            // Show the messagedialog
Packit 1470ea
            this._popUp.show();
Packit 1470ea
        }
Packit 1470ea
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
    _onDialogResponse() {
Packit 1470ea
Packit 1470ea
        this._popUp.destroy ();
Packit 1470ea
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
};
Packit 1470ea
Packit 1470ea
// Run the application
Packit 1470ea
let app = new ComboBoxExample ();
Packit 1470ea
app.application.run (ARGV);
Packit 1470ea
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="in-depth">
Packit 1470ea
    <title>WeiterfĂĽhrende Dokumentation</title>
Packit 1470ea

Packit 1470ea
  In this sample we used the following:
Packit 1470ea

Packit 1470ea
<list>
Packit 1470ea
  <item>

<link href="http://www.roojs.com/seed/gir-1.2-gtk-3.0/gjs/Gtk.Application.html">Gtk.Application</link>

</item>
Packit 1470ea
  <item>

<link href="http://developer.gnome.org/gtk3/stable/GtkApplicationWindow.html">Gtk.ApplicationWindow</link>

</item>
Packit 1470ea
  <item>

<link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.CellRendererPixbuf.html">Gtk.CellRendererPixbuf</link>

</item>
Packit 1470ea
  <item>

<link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.CellRendererText.html">Gtk.CellRendererText</link>

</item>
Packit 1470ea
  <item>

<link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.ComboBox.html">Gtk.ComboBox</link>

</item>
Packit 1470ea
  <item>

<link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.ListStore.html">Gtk.ListStore</link>

</item>
Packit 1470ea
  <item>

<link href="http://www.roojs.com/seed/gir-1.2-gtk-3.0/gjs/Gtk.MessageDialog.html">Gtk.MessageDialog</link>

</item>
Packit 1470ea
  <item>

<link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.TreeIter.html">Gtk.TreeIter</link>

</item>
Packit 1470ea
</list>
Packit 1470ea
  </section>
Packit 1470ea
</page>