Taryn Fox
jewelfox@fursona.net 2012
Η πρώτη σας εφαρμογή σε GNOME!
Ελληνική μεταφραστική ομάδα GNOME
team@gnome.gr 2012-2015
Δημήτρης Σπίγγος
dmtrs32@gmail.com 2012, 2013
Μαρία Θουκιδίδου
marablack3@gmail.com 2014
Θάνος Τρυφωνίδης
tomtryf@gmail.com 2014, 2015

# 1. Hello, GNOME!

        Αυτό το μάθημα θα σας δείξει πώς να γράψετε την πρώτη σας εφαρμογή GNOME σε JavaScript. Θα χρησιμοποιήσετε JavaScript για να γράψετε για GNOME με τον ίδιο τρόπο που θα έπρεπε για τον ιστό. Κατόπιν, θα μάθετε πώς να χρησιμοποιήσετε "native" γραφικά στοιχεία, για να γράψετε εφαρμογές που δείχνουν και αισθάνονται σαν άλλες εφαρμογές GNOME.
        Έχετε πάρει τον υπολογιστή σας με εγκατεστημένο το GNOME και gedit ρυθμισμένο να γράφει κώδικα με ?. Θα θέλετε να κάνετε αυτά τα πράγματα πρώτα.

# Ας αρχίσουμε με μια ιστοσελίδα

Ιδού κάποιος βασικός κώδικας HTML, CSS και JavaScript. Σας φαίνεται αυτός οικείος;

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello, GNOME!</title>

<!-- Use JavaScript to show a greeting when someone clicks the button --> <script type="application/javascript"> function greeting () { document.getElementById ("greeting").innerHTML = ("O hai!"); } </script>

<!-- Very basic CSS style using the GNOME font --> <style type="text/css"> body { font-face: Cantarell, sans-serif; text-align: center; } </style>

</head> <body> <br /> <br /> <button type="button" onclick="greeting()">Hello, GNOME!</button>

<!-- Empty H1 element gets filled in when the button is clicked --> <h1 id="greeting"></h1> </body> </html>

Ας το αποθηκεύσουμε ως hellognome.html και να δούμε πώς φαίνεται όταν τον εκτελούμε!

Μπορείτε να εκτελέσετε τον παραπάνω κώδικα ανοίγοντας το hellognome.html σε έναν περιηγητή ιστού. Αλλά εδώ, πρόκειται να δημιουργήσουμε μια εφαρμογή GNOME που τρέχει την εφαρμογή ιστού μας μέσα του, ακριβώς όπως βλέπετε στο στιγμιότυπο. Θα μπορέσετε να αυξομειώσετε και να μεγιστοποιήσετε το παράθυρο και πατώντας το Χ στη γωνία να το κλείσετε, ακριβώς όπως θα περιμένατε από κάθε άλλη εφαρμογή GNOME. Η διαφορά είναι ότι αυτό θα εκτελέσει τον κώδικα του ιστού μέσα του.

Το άριστο μέρος; Πρόκειται να συνεχίσουμε να χρησιμοποιούμε JavaScript, να γράψουμε όλα τα μέρη που κάνουν την εφαρμογή μας να δουλεύει με GNOME. Ας κοιτάξουμε τον κώδικα και ας δούμε πώς τελειώνει!

# Δημιουργία ενός παραθύρου GNOME ως πλαισίου για την εφαρμογή μας

Πρώτα, χρειαζόμαστε να πούμε στο GNOME ότι αυτή είναι μια εφαρμογή JavaScript, που χρησιμοποιεί gjs. Gjs είναι ένας τρόπος του GNOME να μετατρέπει τον κώδικα σας JavaScript σε οδηγίες που καταλαβαίνει, έτσι αυτή η γραμμή πρέπει πάντα να πηγαίνει στην αρχή των εφαρμογών σας.

#!/usr/bin/gjs

Then we should set the versions of the libraries we'll be using.

imports.gi.versions.Gtk = '3.0'; imports.gi.versions.WebKit2 = '4.0';

Μετά από αυτό, χρειαζόμαστε να πούμε στο GNOME ποιες βιβλιοθήκες θέλουμε να εισάγουμε.

const GLib = imports.gi.GLib; const Gtk = imports.gi.Gtk; const Webkit = imports.gi.WebKit2;

Πώς πρόσθετες βιβλιοθήκες όπως η jQuery μας επιτρέπουν να κάνουμε πρόσθετα πράγματα με την JavaScript, καθεμιά από αυτές τις βιβλιοθήκες μας δίνει νέες δυνατότητες για τις εφαρμογές μας στο GNOME:

Gtk is the basic part of any GNOME application, which lets you create windows and widgets and tie them together.

Η GLib είναι μια βοηθητική βιβλιοθήκη, που επιτρέπει να κάνετε πράγματα όπως να πείτε στο GNOME πού είναι το αρχείο hellognome.htmlπου δημιουργήσαμε.

Και το Webkit είναι μια μηχανή απόδοσης ιστού, που θα χρησιμοποιήσουμε για να δημιουργήσουμε βασικά ένα παράθυρο περιηγητή για να ανοίξουμε το αρχείο μας HTML.

Τώρα δημιουργούμε την ίδια την εφαρμογή:

class HelloGNOME {

This will look familiar to you if you've worked with object-oriented JavaScript before. That's right; our whole application is a class called HelloGNOME.

// Create the application itself constructor() { this.application = new Gtk.Application();

// Connect 'activate' and 'startup' signals to the callback functions this.application.connect('activate', this._onActivate.bind(this)); this.application.connect('startup', this._onStartup.bind(this)); }

// Callback function for 'activate' signal presents windows when active _onActivate() { this._window.present(); }

// Callback function for 'startup' signal builds the UI _onStartup() { this._buildUI(); }

Ιδού μερικός κώδικας που περισσότερο ή λιγότερο θα αντιγράψετε και θα επικολλήσετε για κάθε εφαρμογή JavaScript που κατασκευάζετε. Δημιουργεί μια νέα εφαρμογή και έπειτα συνδέει τα ενεργοποιημένα και αρχικά σήματα της με συναρτήσεις που κάνουν το παράθυρο να εμφανίζεται το ίδιο και να κατασκευάζει τη διεπαφή χρήστη της αντίστοιχα.

What does that mean? Well, everything in a GNOME application sends out a signal when something important happens. A button might send out the clicked signal when you click on it, for instance. Our job is to connect the signals to functions which handle them, and make the things that we want to have happen occur. We do this using each object's connect method, which takes two arguments: The signal we want to handle, and the bound function, which we have to use to tell connect which function we want to have handle the signal.

Σε αυτήν την περίπτωση, θέλουμε την _onActivate να χειριστεί το ενεργοποιημένο σήμα και το _onStartup να χειριστεί το αρχικό σήμα. Η _onActivate απλά λέει στο παράθυρο να παρουσιάσει τον εαυτόν του· έτσι βασικά, όποτε πατάτε Alt Tab στην εφαρμογή φαίνεται, όπως θα το περιμένατε. Η _onStartup καλεί _buildUI, που είναι η συνάρτηση που δημιουργεί τη διεπαφή χρήστη μας και είναι το επόμενο μέρος που θα κοιτάξουμε.

When you copy and paste the above code for your own applications, be sure to change the class name to a unique one each time.

# Σχεδίαση της UI του παραθύρου μας

Στη συνάρτηση _buildUI, πρόκειται να πούμε στο GNOME για το παράθυρό μας και τα πράγματα μέσα του, ένα τη φορά. Μετά από αυτό, πρόκειται να συνδέσουμε το καθετί μαζί και να το βάλουμε όλο σε προβολή.

// Build the application's UI _buildUI() {

// Create the application window this._window = new Gtk.ApplicationWindow ({ application: this.application, title: "Welcome to GNOME", default_height: 200, default_width: 400, window_position: Gtk.WindowPosition.CENTER });

Το πρώτο αντικείμενο που δημιουργούμε είναι ένα ApplicationWindow. Χρειάζεται έναν τίτλο να μπει στη γραμμή τίτλου και η ιδιότητα εφαρμογής του χρειάζεται να είναι η εφαρμογή που δημιουργήσαμε, παραπάνω. Πέρα από αυτό, υπάρχουν ποικίλοι τρόποι προσαρμογής της εμφάνισης του, που η σελίδα αναφοράς ApplicationWindow θα μπει σε περισσότερες λεπτομέρειες. Όπως μπορείτε να δείτε εδώ, του δίνουμε ένα προεπιλεγμένο ύψος και πλάτος (μετρημένο σε εικονοστοιχεία) και λέμε στο GNOME ότι θέλουμε το παράθυρο μας να εμφανιστεί στο κέντρο της οθόνης.

// Δημιουργία μιας προβολής ιστού για προβολή της εφαρμογής ιστού this._webView = new Webkit.WebView ();

// Τοποθέτηση της εφαρμογής ιστού στην προβολή ιστού this._webView.load_uri (GLib.filename_to_uri (GLib.get_current_dir() + "/hellognome.html", null));

Να θυμάστε πώς εισάγαμε το Webkit δεξιά στην αρχή. Εδώ δημιουργούμε ένα νέο στιγμιότυπο της κλάσης Webkit που λέγεται μια WebView, που είναι περισσότερο ή λιγότερο ένα παράθυρο περιηγητή όπου μπορείτε να βάλετε μέσα την εφαρμογή σας. Μετά από αυτό, του δίνουμε έπειτα την URI που θέλουμε να φορτώσει όταν η εφαρμογή ξεκινά.

Θα μπορούσαμε να του δώσουμε μόνο μια URI ιστού, όπως http://gnome.org. Αντίθετα, εδώ χρησιμοποιούμε λίγες βοηθητικές συναρτήσεις του GLib για να πούμε στο WebView που είναι το αρχείο μας hellognome.html. Ο GLib.get_current_dir επιστρέφει τον κατάλογο που εκτελείται η εφαρμογή μας και το GLib.filename_to_uri επιστρέφει τη διαδρομή του αρχείου μας και το όνομα αρχείου σε μια URI που η συνάρτηση load_uri της WebView καταλαβαίνει. (η δεύτερη παράμετρος filename_to_uri's πρέπει να είναι μηδέν εκτός και ξέρετε τι χρησιμοποιείται και έχετε έναν λόγο να το αλλάξετε.)

// Τοποθέτηση της προβολής ιστού στο παράθυρο this._window.add (this._webView);

// Εμφάνιση του παραθύρου και όλων των θυγατρικών γραφικών στοιχείων this._window.show_all(); },

});

Κάθε παράθυρο μπορεί να κρατήσει ένα και μόνο ένα γραφικό στοιχείο. Κανονικά, θα πρέπει να χρησιμοποιήσουμε έναν περιέκτη γραφικού στοιχείου όπως ένα πλέγμα για να βάλουμε πολλαπλά γραφικά στοιχεία σε αυτό, έπειτα χρησιμοποιήστε τη συνάρτηση προσθήκης παραθύρου για να προσθέσετε το πλέγμα σε αυτό. Εδώ, προσθέτουμε απλά την WebView, έτσι ώστε να είναι ότι προσθέτουμε στο παράθυρο. Μετά από αυτό, ως το τελευταίο μέρος της συνάρτησης _buildUI που δημιουργεί το παράθυρο μας, λέμε στο παράθυρο να εμφανίσει τον εαυτόν του και τα περιεχόμενά του.

// Εκτέλεση της εφαρμογής let app = new HelloGNOME (); app.application.run (ARGV);

Τελικά, δημιουργούμε ένα νέο στιγμιότυπο της κλάσης HelloGNOME και λέμε στο GNOME να εκτελέσει την εφαρμογή.

# Εκτέλεση της εφαρμογής σας GNOME

Τώρα που έχουμε δημιουργήσει την πρώτη μας εφαρμογή GNOME, είναι καιρός να τη δοκιμάσουμε! Δεν χρειάζεται να μεταγλωττίσετε την εφαρμογή σας ή να εγκαταστήσετε οποιοδήποτε ειδικό λογισμικό για αυτό· το GNOME έχει ενσωματωμένο το gjs για να μπορέσετε να εκτελέσετε το κέλυφος GNOME. Απλά αποθηκεύστε το hellognome.html και την ενεργή μας εφαρμογή, hellognome.js, σε έναν κατάλογο που μπορείτε να πάρετε με το τερματικό. (Συνήθως ανοίγουν στον προσωπικό σας κατάλογο, αυτόν που ονομάζεται με το όνομα σας του χρήστη.) Μετά από αυτό, ανοίξτε ένα τερματικό, πηγαίνετε εκεί και πληκτρολογήστε:

     $ gjs hellognome.js

Θα πρέπει να δείτε πάνω κάτω το ίδιο στιγμιότυπο όπως πριν, με ένα κουμπί όπου μπορείτε να πατήσετε για να προκαλέσετε την εμφάνιση ενός σύντομου μηνύματος.

Μπορείτε να χρησιμοποιήσετε την εντολή τερματικού

     $ cd (directory name)

για να περιηγηθείτε μεταξύ καταλόγων μες τον τερματικό, για να δείτε πού αποθηκεύσατε τα αρχεία. Υπάρχει επίσης μια επέκταση για τον Ναυτίλο, τον διαχειριστή αρχείων του GNOME, που σας επιτρέπει με δεξί κλικ οπουδήποτε μέσα του να ανοίξετε ένα τερματικό παράθυρο ακριβώς εκεί. Ελέγξτε την εφαρμογή που χρησιμοποιείτε για την εγκατάσταση νέου λογισμικού (όπως προσθήκη/αφαίρεση προγραμμάτων στο κέντρο λογισμικού) για αυτό.

# Ποιο είναι το επόμενο;

Συνεχίστε με το επόμενο μάθημα για να μάθετε πώς να δομήσετε "native" εφαρμογές GNOME που φαίνονται και αισθάνονται όπως οι άλλες, αντίθετα από μια προβολή ιστού με κώδικα HTML μέσα της. Ή ρίξτε μια ματιά σε κάποια δείγματα κώδικα, εάν θα θέλατε να δείτε τον κώδικα του παραδείγματος για κάθε γραφικό στοιχείο Gtk.

Τελικά, εάν θέλετε να κατασκευάσετε απλά εφαρμογές GNOME χρησιμοποιώντας βιβλιοθήκες JavaScript που σχεδιάστηκαν για τον ιστό, μπορείτε βασικά να σταματήσετε εδώ και να πάτε να το κάνετε! Ελέγξετε τα τελευταία μαθήματα εάν θα θέλατε να δείτε τη δημιουργία ενός αρχείου .desktop για την εφαρμογή σας, που θα επιτρέψει την εμφάνισή του στο μενού ενεργειών της επιφάνειας εργασίας σας με όλες τις άλλες εφαρμογές σας.

# Δείγμα πλήρους κώδικα

#!/usr/bin/gjs

imports.gi.versions.Gtk = '3.0'; imports.gi.versions.WebKit2 = '4.0';

const GLib = imports.gi.GLib; const Gtk = imports.gi.Gtk; const Webkit = imports.gi.WebKit2;

class HelloGNOME {

// Create the application itself constructor() { this.application = new Gtk.Application ();

// Connect 'activate' and 'startup' signals to the callback functions this.application.connect('activate', this._onActivate.bind(this)); this.application.connect('startup', this._onStartup.bind(this)); }

// Callback function for 'activate' signal presents windows when active _onActivate() { this._window.present(); }

// Callback function for 'startup' signal builds the UI _onStartup() { this._buildUI(); }

// Build the application's UI _buildUI() {

// Create the application window this._window = new Gtk.ApplicationWindow ({ application: this.application, title: "Welcome to GNOME", default_height: 200, default_width: 400, window_position: Gtk.WindowPosition.CENTER });

// Create a webview to show the web app this._webView = new Webkit.WebView ();

// Put the web app into the webview this._webView.load_uri (GLib.filename_to_uri (GLib.get_current_dir() + "/hellognome.html", null));

// Put the webview into the window this._window.add (this._webView);

// Show the window and all child widgets this._window.show_all(); }

};

// Run the application let app = new HelloGNOME (); app.application.run (ARGV);