Blame platform-demos/C/scale.js.page

Packit 1470ea
Packit 1470ea
Packit 1470ea
      xmlns:its="http://www.w3.org/2005/11/its"
Packit 1470ea
      xmlns:xi="http://www.w3.org/2001/XInclude"
Packit 1470ea
      type="guide" style="task"
Packit 1470ea
      id="scale.js">
Packit 1470ea
  <info>
Packit 1470ea
  <title type="text">Scale (JavaScript)</title>
Packit 1470ea
    <link type="guide" xref="beginner.js#entry"/>
Packit 1470ea
    <revision version="0.1" date="2012-06-20" 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 slider which corresponds to a numerical value</desc>
Packit 1470ea
  </info>
Packit 1470ea
Packit 1470ea
  <title>Scale</title>
Packit 1470ea
  <media type="image" mime="image/png" src="media/scalepenguins.png"/>
Packit 1470ea
  

A Scale is a horizontal or vertical slider, that represents a value inside a numerical range. When you create a new Scale, you set what its default position is, what the numbers at the top and bottom of the range are, and things like how much it moves up or down when you click on the Scale to either side of the knob. To keep from having to type all that in every time you create a new Scale, you can create an object called an Adjustment which keeps track of all that, then tell each new Scale to use that Adjustment.

Packit 1470ea
  

This scale is a simple widget that lets you adjust the size of an iceberg that penguins live on. The number of penguins on the iceberg is the product of the values of the two sliders. Try playing with them and seeing what happens.

Packit 1470ea
    <links type="section" />
Packit 1470ea
Packit 1470ea
  <section id="imports">
Packit 1470ea
    <title>Libraries to import</title>
Packit 1470ea
    
Packit 1470ea
#!/usr/bin/gjs
Packit 1470ea
Packit 1470ea
const Gio = imports.gi.Gio;
Packit 1470ea
const Gtk = imports.gi.Gtk;
Packit 1470ea
const Lang = imports.lang;
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>Creating the application window</title>
Packit 1470ea
    
Packit 1470ea
const ScaleExample = new Lang.Class({
Packit 1470ea
    Name: 'Scale Example',
Packit 1470ea
Packit 1470ea
    // Create the application itself
Packit 1470ea
    _init: function() {
Packit 1470ea
        this.application = new Gtk.Application({
Packit 1470ea
            application_id: 'org.example.jsscale'
Packit 1470ea
        });
Packit 1470ea
Packit 1470ea
    // Connect 'activate' and 'startup' signals to the callback functions
Packit 1470ea
    this.application.connect('activate', Lang.bind(this, this._onActivate));
Packit 1470ea
    this.application.connect('startup', Lang.bind(this, this._onStartup));
Packit 1470ea
    },
Packit 1470ea
Packit 1470ea
    // Callback function for 'activate' signal presents window when active
Packit 1470ea
    _onActivate: function() {
Packit 1470ea
        this._window.present();
Packit 1470ea
    },
Packit 1470ea
Packit 1470ea
    // Callback function for 'startup' signal builds the UI
Packit 1470ea
    _onStartup: function() {
Packit 1470ea
        this._buildUI ();
Packit 1470ea
    },
Packit 1470ea
]]>
Packit 1470ea
    

All the code for this sample goes in the ScaleExample 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: function() {
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
            border_width: 20,
Packit 1470ea
            title: "Birds on a Floe"});
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="button">
Packit 1470ea
    <title>Creating the scales</title>
Packit 1470ea
    
Packit 1470ea
        // Create the horizontal scale
Packit 1470ea
        this._hScale = Gtk.Scale.new_with_range (Gtk.Orientation.HORIZONTAL, 0.0, 100.0, 5.0);
Packit 1470ea
        this._hScale.set_valign (Gtk.Align.START);
Packit 1470ea
        this._hScale.set_value (50);
Packit 1470ea
        this._hScale.set_digits (0);
Packit 1470ea
        // this._hScale.set_draw_value (false);
Packit 1470ea
]]>
Packit 1470ea
Packit 1470ea
    

The new_with_range method is one way to create a new Scale widget. The parameters it takes are a <link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.Orientation.html">Gtk.Orientation</link>, the minimum value, the maximum value, and the increment for a single step. After that we use the Scale's methods to set its starting value, and how many decimal places it runs to. We also set its vertical alignment in this case, to control where it appears in the window.

Packit 1470ea
    

We can use the set_draw_value method to tell it whether or not to show the number next to the sliding scale. It's commented out in this example.

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
        // Create a master adjustment to use for the vertical (or any other) scale
Packit 1470ea
        this._adjustment = new Gtk.Adjustment ({
Packit 1470ea
            value: 95,
Packit 1470ea
            lower: 0,
Packit 1470ea
            upper: 100,
Packit 1470ea
            step_increment: 5,
Packit 1470ea
            page_increment: 10 });
Packit 1470ea
]]>
Packit 1470ea
Packit 1470ea
    

An Adjustment is an object we can use to simplify things when creating a new Scale. The Adjustment's "value" property is what the Scale's default value is, while "upper" and "lower" make the high and low ends of the numerical range. Meanwhile, the increment values show how much the slider moves when you do things like click on it.

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
        // Create a vertical scale using the adjustment we just made
Packit 1470ea
        this._vScale = new Gtk.Scale ({
Packit 1470ea
            orientation: Gtk.Orientation.VERTICAL,
Packit 1470ea
            adjustment: this._adjustment,
Packit 1470ea
            digits: 0,
Packit 1470ea
            // draw_value: false,
Packit 1470ea
            margin_left: 10 });
Packit 1470ea
]]>
Packit 1470ea
Packit 1470ea
    

Here we create a new Scale object using _adjustment as its "adjustment" property. This is a great shortcut. We still have to tell it to round off the decimal place, though. Note that the draw_value property is commented out; this is how you tell it not to show the number next to the Scale when you're creating one this way.

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
        // Create the label that shows the product of the two values
Packit 1470ea
        this._product = (this._hScale.get_value() * this._vScale.get_value());
Packit 1470ea
        this._label = new Gtk.Label ({
Packit 1470ea
            label: (String(this._product) + " penguins on the iceberg."),
Packit 1470ea
            height_request: 200,
Packit 1470ea
            width_request: 200,
Packit 1470ea
            wrap: true});
Packit 1470ea
Packit 1470ea
        // Connect the two scales to functions which recalculate the label
Packit 1470ea
        this._hScale.connect ("value-changed", Lang.bind (this, this._recalc));
Packit 1470ea
        this._vScale.connect ("value-changed", Lang.bind (this, this._recalc));
Packit 1470ea
]]>
Packit 1470ea
Packit 1470ea
    

We can use the get_value method to find out the numerical value a Scale is set at. We can then do whatever we want with it, including multiply the two Scales' values together and have a <link xref="label.js">Label</link> show us the product. We set the label's text to wrap around, because we're having it display a silly message too.

Packit 1470ea
    

After we create the Label, we connect the two Scales' "value-changed" signals to _recalc, a function that will recalculate the number of penguins on the iceberg and come up with a new message.

Packit 1470ea
Packit 1470ea
    
Packit 1470ea
        // Create a grid to arrange things in
Packit 1470ea
        this._UIGrid = new Gtk.Grid ({
Packit 1470ea
            halign: Gtk.Align.CENTER,
Packit 1470ea
            valign: Gtk.Align.CENTER,
Packit 1470ea
            margin_top: 20,
Packit 1470ea
            margin_left: 20});
Packit 1470ea
Packit 1470ea
        // Attach everything to the grid
Packit 1470ea
        this._UIGrid.attach (this._label, 0, 0, 1, 1);
Packit 1470ea
        this._UIGrid.attach (this._hScale, 0, 1, 1, 1);
Packit 1470ea
        this._UIGrid.attach (this._vScale, 1, 0, 1, 1);
Packit 1470ea
]]>
Packit 1470ea
    

Here we create a <link xref="grid.js">Grid</link> to put everything in, then attach all our widgets to it. Note that here and on some of the widgets themselves we're using margins to keep things neatly spaced.

Packit 1470ea
    
Packit 1470ea
        // Add the grid to the window
Packit 1470ea
        this._window.add (this._UIGrid);
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 Grid to the window, then tell the window to show itself and all the widgets inside of it.

Packit 1470ea
    </section>
Packit 1470ea
Packit 1470ea
    <section id="scales-handler">
Packit 1470ea
    <title>Function which handles the scales' values changing</title>
Packit 1470ea
Packit 1470ea
    
Packit 1470ea
    _recalc: function() {
Packit 1470ea
Packit 1470ea
        // Figure out what the product of the two scales' values is
Packit 1470ea
        var product = (this._hScale.get_value() * this._vScale.get_value());
Packit 1470ea
Packit 1470ea
        // Create a blank comment line in case there isn't a silly comment to make
Packit 1470ea
        var comment = "";
Packit 1470ea
Packit 1470ea
        // Make a silly comment based on the number of penguins
Packit 1470ea
        if (product > 9000) {
Packit 1470ea
            comment = "It's over 9000!";
Packit 1470ea
        }
Packit 1470ea
        else if (product < 1000 && product > 0) {
Packit 1470ea
            comment = "They're getting lonely.";
Packit 1470ea
        }
Packit 1470ea
        else if (product == 0) {
Packit 1470ea
            comment = "They're all gone ...";
Packit 1470ea
        }
Packit 1470ea
        else comment = "";
Packit 1470ea
Packit 1470ea
        // Set ._label's new text
Packit 1470ea
        this._label.set_label (String (product) + " penguins on the iceberg. " + comment);
Packit 1470ea
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
});
Packit 1470ea
]]>
Packit 1470ea
    

Remember, we can get a Scale's value using its get_value method. Here we simply recalculate what the product of the two values is after one of the Scales is moved, add in a silly message depending on how many penguins are left, and change the wording on _label to show the new number and message.

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

Finally, we create a new instance of the finished ScaleExample 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
<xi:include href="samples/scale.js" parse="text"><xi:fallback/></xi:include>
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="in-depth">
Packit 1470ea
    <title>In-depth documentation</title>
Packit 1470ea
<list>
Packit 1470ea
  <item>

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

</item>
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.Grid.html">Gtk.Grid</link>

</item>
Packit 1470ea
  <item>

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

</item>
Packit 1470ea
  <item>

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

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