Blame platform-demos/el/image-viewer.js.page

Packit 1470ea
Packit 1470ea
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" type="topic" id="image-viewer.js" xml:lang="el">
Packit 1470ea
Packit 1470ea
  <info>
Packit 1470ea
  <title type="text">Προβολέας εικόνων (JavaScript)</title>
Packit 1470ea
    <link type="guide" xref="js#examples"/>
Packit 1470ea
Packit 1470ea
    <desc>Μια λίγο περισσότερο από απλή εφαρμογή σαν το "Hello world"- συγγραφή ενός προβολέα εικόνων σε GTK+. Περιλαμβάνει μια εισαγωγή στη γλώσσα JavaScript.</desc>
Packit 1470ea
Packit 1470ea
    <revision pkgversion="0.1" version="0.1" date="2011-03-19" status="review"/>
Packit 1470ea
    <credit type="author">
Packit 1470ea
      <name>Jonh Wendell</name>
Packit 1470ea
      <email its:translate="no">jwendell@gnome.org</email>
Packit 1470ea
    </credit>
Packit 1470ea
    <credit type="author">
Packit 1470ea
      <name>Johannes Schmid</name>
Packit 1470ea
      <email its:translate="no">jhs@gnome.org</email>
Packit 1470ea
    </credit>
Packit 1470ea
    <credit type="editor">
Packit 1470ea
      <name>Marta Maria Casetti</name>
Packit 1470ea
      <email its:translate="no">mmcasettii@gmail.com</email>
Packit 1470ea
      <years>2013</years>
Packit 1470ea
    </credit>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Ελληνική μεταφραστική ομάδα GNOME</mal:name>
Packit 1470ea
      <mal:email>team@gnome.gr</mal:email>
Packit 1470ea
      <mal:years>2012-2015</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Δημήτρης Σπίγγος</mal:name>
Packit 1470ea
      <mal:email>dmtrs32@gmail.com</mal:email>
Packit 1470ea
      <mal:years>2012, 2013</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Μαρία Θουκιδίδου</mal:name>
Packit 1470ea
      <mal:email>marablack3@gmail.com</mal:email>
Packit 1470ea
      <mal:years>2014</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  
Packit 1470ea
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
Packit 1470ea
      <mal:name>Θάνος Τρυφωνίδης</mal:name>
Packit 1470ea
      <mal:email>tomtryf@gmail.com</mal:email>
Packit 1470ea
      <mal:years>2014, 2015</mal:years>
Packit 1470ea
    </mal:credit>
Packit 1470ea
  </info>
Packit 1470ea
Packit 1470ea
<title>Προβολή εικόνων</title>
Packit 1470ea
Packit 1470ea
<synopsis>
Packit 1470ea
  

Σε αυτόν το μάθημα θα γράψουμε μια πολύ απλή εφαρμογή σε GTK που φορτώνει και εμφανίζει ένα αρχείο εικόνας. Θα μάθετε πώς να:

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

Γράψε μια βασικά διεπαφή χρήστη GTK σε JavaScript

</item>
Packit 1470ea
    <item>

Να αντιμετωπίζετε συμβάντα συνδέοντας σήματα με τους χειριστές σημάτων

</item>
Packit 1470ea
    <item>

Σχεδιάζετε διεπαφές χρήστη GTK χρησιμοποιώντας περιέκτες

</item>
Packit 1470ea
    <item>

Φορτώνετε και να εμφανίζετε αρχεία εικόνων

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

Θα χρειαστείτε τα παρακάτω για να μπορέσετε να ακολουθήσετε αυτό το μάθημα:

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

Ένα εγκατεστημένο αντίγραφο του <link xref="getting-ready">Anjuta IDE</link>

</item>
Packit 1470ea
    <item>

Ένα εγκατεστημένο αντίγραφο του διερμηνευτή gjs

</item>
Packit 1470ea
    <item>

Βασική γνώση οποιασδήποτε αντικειμενοστραφούς γλώσσας προγραμματισμού

</item>
Packit 1470ea
  </list>
Packit 1470ea
</synopsis>
Packit 1470ea
Packit 1470ea
<media type="image" mime="image/png" src="media/image-viewer.png"/>
Packit 1470ea
Packit 1470ea
<section id="anjuta">
Packit 1470ea
  <title>Δημιουργία έργου με το Anjuta</title>
Packit 1470ea
  

Πριν ξεκινήσετε να προγραμματίζετε, πρέπει να δημιουργήσετε ένα καινούργιο έργο στο Anjuta. Έτσι θα δημιουργηθούν όλα τα απαραίτητα αρχεία που χρειάζονται για την εκτέλεση του κώδικα αργότερα. Επίσης θα ήταν χρήσιμο να τα κρατάτε όλα μαζί.

Packit 1470ea
  <steps>
Packit 1470ea
    <item>
Packit 1470ea
    

Ξεκινήστε το Anjuta και πατήστε <guiseq><gui>αρχείο</gui><gui>νέο</gui><gui>έργο</gui></guiseq> για να ανοίξετε τον οδηγό του έργου.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Επιλέξτε <gui>Γενική Javascript</gui> από την καρτέλα <gui>JS</gui>, πατήστε <gui>Μπροστά</gui>, και συμπληρώστε τις λεπτομέρειές σας στις επόμενες λίγες σελίδες. Χρησιμοποιήστε το <file>image-viewer</file> ως όνομα έργου και καταλόγου.

Packit 1470ea
   	</item>
Packit 1470ea
    <item>
Packit 1470ea
    

Πατήστε <gui>Εφαρμογή</gui> και το έργο θα δημιουργηθεί για εσάς. Ανοίξτε το <file>src/main.js</file> από τις καρτέλες <gui>έργο</gui> ή <gui>αρχείο</gui>. Περιλαμβάνει πολύ βασικό παράδειγμα κώδικα.

Packit 1470ea
    </item>
Packit 1470ea
  </steps>
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
Packit 1470ea
<section id="js">
Packit 1470ea
  <title>Βασικά JavaScript: Hello World</title>
Packit 1470ea
  

Πριν να ξεκινήσουμε την σύνταξη του προβολέα εικόνας, ας εξετάσουμε περισσότερα για τον τρόπο χρήσης του JavaScript στο GNOME. Φυσικά, η πρώτη σας με οποιαδήποτε γλώσσα προγραμματισμού πρέπει να είναι το πρόγραμμα Hello World που μπορεί να βρεθεί ήδη στο <file>main.js</file>:

Packit 1470ea
  εκτύπωση ("Hello world!")·
Packit 1470ea
  

Αυτό θα φαίνεται ολότελα φυσικό, εάν είστε εξοικειωμένος με σχεδόν οποιαδήποτε άλλη γλώσσα προγραμματισμού. Η συνάρτηση print καλείται με το όρισμα "Hello world!", που θα εκτυπωθεί στην οθόνη. Σημειώστε ότι κάθε γραμμή κώδικα τελειώνει με ;.

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="classes">
Packit 1470ea
  <title>Κλάσεις στη JavaScript</title>
Packit 1470ea
  

Αυτός είναι ο τυπικός τρόπος ορισμού μιας κλάσης στη JavaScript:

Packit 1470ea
  
Packit 1470ea
function MyClass () {
Packit 1470ea
  this._init ();
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
MyClass.prototype = {
Packit 1470ea
Packit 1470ea
  _init: function () {
Packit 1470ea
    this.propertyA = "This is an object's field";
Packit 1470ea
    this.propertyB = 10;
Packit 1470ea
  },
Packit 1470ea
Packit 1470ea
  aMethod: function (arg1, arg2) {
Packit 1470ea
    print ("inside aMethod: " + arg1 + " " + arg2);
Packit 1470ea
  },
Packit 1470ea
Packit 1470ea
  dumpProperties: function () {
Packit 1470ea
    print (this.propertyA);
Packit 1470ea
    print (this.propertyB);
Packit 1470ea
  }
Packit 1470ea
Packit 1470ea
}
Packit 1470ea
  

Αυτό ορίζει μια κλάση που λέγεται MyClass. Ας δούμε κάθε τμήμα του ορισμού της κλάσης:

Packit 1470ea
  <steps>
Packit 1470ea
    <item>
Packit 1470ea
    

function MyClass είναι ο κατασκευαστής της κλάσης — το όνομά του πρέπει να ταιριάζει με το όνομα της κλάσης. Μπορείτε να προσπελάσετε οποιοδήποτε μέλος της κλάσης χρησιμοποιώντας το αντικείμενο this· εδώ, ο κατασκευαστής καλεί τη μέθοδο της κλάσης _init.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Η ομάδα MyClass.prototype είναι εκεί που ορίζετε τη δομή της κλάσης. Κάθε κλάση αποτελείται από μεθόδους (συναρτήσεις) και πεδία (μεταβλητές)· υπάρχουν τρεις μέθοδοι και δύο πεδία σε αυτό το παράδειγμα.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Η πρώτη μέθοδος που καθορίστηκε εδώ λέγεται _init και καθορίζουμε ότι είναι μια συνάρτηση χωρίς ορίσματα:

Packit 1470ea
    _init: function ()
Packit 1470ea
    

Γράφουμε τη συνάρτηση μέσα σε μερικές αγκύλες. Δύο πεδία ορίζονται εδώ, propertyA και propertyB. Το πρώτο ορίζεται σε μια συμβολοσειρά και το δεύτερο ορίζεται σε έναν ακέραιο (10). Η συνάρτηση δεν επιστρέφει καμία τιμή.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Η επόμενη μέθοδος λέγεται aMethod και έχει δύο ορίσματα, που εκτυπώνεται όταν την καλείτε. Η τελική μέθοδος είναι dumpProperties και τυπώνει τα πεδία propertyA και propertyB.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Σημειώστε πώς τακτοποιείται ο ορισμός κλάσης (πρωτότυπο)· κάθε ορισμός συνάρτησης ξεχωρίζεται με κόμμα.

Packit 1470ea
    </item>
Packit 1470ea
  </steps>
Packit 1470ea
Packit 1470ea
  

Τώρα που η MyClass ορίστηκε, μπορούμε να παίξουμε μαζί της:

Packit 1470ea
  
Packit 1470ea
var o = new MyClass ();
Packit 1470ea
o.aMethod ("Hello", "world");
Packit 1470ea
o.propertyA = "Just changed its value!";
Packit 1470ea
o.dumpProperties ();
Packit 1470ea
  

Αυτός ο κώδικας δημιουργεί ένα νέο στιγμιότυπο της κλάσης που λέγεται o, τρέχει τη aMethod, αλλάζει την propertyA σε διαφορετική συμβολοσειρά και έπειτα καλεί dumpProperties (που εξάγει τα πεδία).

Packit 1470ea
  

Αποθηκεύστε τον κώδικα στο <file>main.js</file> και έπειτα τρέξτε τον χρησιμοποιώντας <guiseq><gui>τρέξιμο</gui><gui>εκτέλεση</gui></guiseq> από το μενού ή χρησιμοποιώντας την εργαλειοθήκη.

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="gtk">
Packit 1470ea
  <title>Μια πρώτη εφαρμογή σε Gtk</title>
Packit 1470ea
  

Για να δούμε πώς μια πολύ βασική εφαρμογή Gtk φαίνεται σε JavaScript:

Packit 1470ea
  
Packit 1470ea
const Gtk = imports.gi.Gtk;
Packit 1470ea
Packit 1470ea
Gtk.init (null, null);
Packit 1470ea
Packit 1470ea
var w = new Gtk.Window ({title: "Image Viewer Demo"});
Packit 1470ea
w.show ();
Packit 1470ea
Packit 1470ea
Gtk.main ();
Packit 1470ea
  

Ας ρίξουμε μια ματιά στο τι γίνεται:

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

Η πρώτη γραμμή εισάγει το όνομα χώρου Gtk (αυτό είναι που περιέχει την βιβλιοθήκη του Gtk). Οι βιβλιοθήκες παρέχονται από το GObject Introspection (gi), που παρέχει γλωσσικές συσχετίσεις για πολλές βιβλιοθήκες του GNOME.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Το Gtk.init αρχικοποιεί τη βιβλιοθήκη Gtk· αυτή η πρόταση είναι υποχρεωτική για όλα τα προγράμματα Gtk.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Η επόμενη γραμμή δημιουργεί το κύριο παράθυρο δημιουργώντας ένα νέο αντικείμενο Gtk.Window. Μπορείτε να περάσετε αρκετές ιδιότητες στον κατασκευαστή παραθύρου χρησιμοποιώντας τη σύνταξη {property: value, property: value, ...}. Σε αυτήν την περίπτωση ορίζουμε τον τίτλο του παραθύρου.

</item>
Packit 1470ea
    <item>

Η επόμενη γραμμή ρητά εμφανίζει το παράθυρο. Στο Gtk, κάθε γραφικό στοιχείο κρύβεται από προεπιλογή.

</item>
Packit 1470ea
    <item>

Τελικά, το Gtk.main τρέχει τον κύριο βρόχο — με άλλα λόγια, εκτελεί το πρόγραμμα. Ο κύριος βρόχος απαντά σε συμβάντα (σήματα) από τη διεπαφή χρήστη και έπειτα καλεί έναν χειριστή σήματος που θα κάνει κάτι χρήσιμο. Θα μάθουμε περισσότερα για τα σήματα σύντομα.

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

Αποθήκευση του κώδικα στο <file>main.js</file> και εκτέλεσή του. Θα σημειώσετε ότι η εφαρμογή δεν εγκαταλείπει όταν κλείνετε το παράθυρο. Αυτό συμβαίνει επειδή δεν εγκαταστήσαμε έναν χειριστή σήματος για ασχοληθεί με το σήμα του παραθύρου destroy (κλείσιμο) ακόμα. Θα το κάνουμε σύντομα, αλλά για τώρα μπορείτε απλά να πατήσετε <keyseq><key>Ctrl</key><key>C</key></keyseq> στο παράθυρο τερματικού για να αφήσετε το πρόγραμμα.

Packit 1470ea
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="classes2">
Packit 1470ea
  <title>Προσθήκη κλάσεων</title>
Packit 1470ea
  

Ο κατάλληλος τρόπος για να γίνει προγραμματισμός Gtk είναι χρησιμοποιώντας κλάσεις. Ας ξαναγράψουμε τον απλό κώδικα που μόλις γράψατε χρησιμοποιώντας κλάσεις:

Packit 1470ea
  
Packit 1470ea
const Gtk = imports.gi.Gtk;
Packit 1470ea
Packit 1470ea
function ImageViewer () {
Packit 1470ea
  this._init ();
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
ImageViewer.prototype = {
Packit 1470ea
  _init: function () {
Packit 1470ea
    this.window = new Gtk.Window ({title: "Image Viewer Demo"});
Packit 1470ea
    this.window.show ();
Packit 1470ea
  }
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
Gtk.init (null, null);
Packit 1470ea
var iv = new ImageViewer ();
Packit 1470ea
Gtk.main ();
Packit 1470ea
  
Packit 1470ea
  

σημειώστε ότι το πρόγραμμα είναι το ίδιο· μόλις μετακινήσαμε τον κώδικα δημιουργίας παραθύρου στη δική μας κλάση ImageViewer. Ο κατασκευαστής κλάσης καλεί τη μέθοδο _init, που δημιουργεί και εμφανίζει το παράθυρο. Έπειτα δημιουργούμε ένα στιγμιότυπο της κλάσης πριν το τρέξιμο του κύριου βρόχου (Gtk.main).

Packit 1470ea
  

Αυτός ο κώδικας είναι αρθρωτός και μπορεί να σπάσει σε πολλαπλά αρχεία εύκολα. Αυτό τον κάνει καθαρότερο και πιο εύκολα αναγνώσιμο.

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="signals">
Packit 1470ea
  <title>Σήματα</title>
Packit 1470ea
  

Τα σήματα είναι μια από τις έννοιες κλειδιά για τον προγραμματισμό Gtk. Όποτε κάτι συμβαίνει σε ένα αντικείμενο, εκπέμπει ένα σήμα· για παράδειγμα, όταν πατιέται ένα κουμπί εκπέμπει το σήμα clicked. Άμα θέλετε το πρόγραμμά σας να κάνει κάτι όταν αυτό συμβαίνει, πρέπει να συνδέσετε μια συνάρτηση (έναν "χειριστή σημάτων") σε αυτό το σήμα. Ορίστε ένα παράδειγμα:

Packit 1470ea
  
Packit 1470ea
function button_clicked () {
Packit 1470ea
  print ("you clicked me!");
Packit 1470ea
}
Packit 1470ea
var b = new Gtk.Button ({label:"Click me"});
Packit 1470ea
b.connect ("clicked", button_clicked);
Packit 1470ea
  

Οι τελευταίες δύο γραμμές δημιουργούν ένα Gtk.Button που ονομάζεται b και συνδέει το σήμα το clicked στην συνάρτηση button_clicked, η οποία ορίζεται πιο πάνω. Κάθε φορά που πατιέται ένα κουμπί, ο κώδικας στη συνάρτηση button_clicked θα εκτελείται. Εδώ απλά τυπώνει ένα μήνυμα.

Packit 1470ea
  

Η σύνταξη για σύνδεση οποιουδήποτε σήματος σε μια συνάρτηση είναι:

Packit 1470ea
  
Packit 1470ea
object.connect (<signal_name>, <function_to_be_called>);
Packit 1470ea
  

Μπορείτε να βρείτε ορισμούς σήματος για κάθε αντικείμενο στο <link href="https://developer.gnome.org/gtk3/stable/gtkobjects.html">αναφορά κλάσης GTK</link>.

Packit 1470ea
Packit 1470ea
  <note>
Packit 1470ea
    

Μπορείτε να απλοποιήσετε τον κώδικα χρησιμοποιώντας έναν ενσωματωμένο ορισμό συνάρτησης:

Packit 1470ea
    
Packit 1470ea
b.connect ("clicked", function () { print ("you clicked me!"); });
Packit 1470ea
  </note>
Packit 1470ea
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="close">
Packit 1470ea
  <title>Κλείσιμο του παραθύρου</title>
Packit 1470ea
  

Όταν κλείνεται ένα παράθυρο Gtk δεν κλείνει πραγματικά, κρύβεται. Αυτό επιτρέπει τη διατήρηση του παραθύρου τριγύρω (που είναι χρήσιμο εάν θέλετε να ζητήσετε από τον χρήστη εάν θέλει πραγματικά να κλείσει το παράθυρο, για παράδειγμα).

Packit 1470ea
  

Στην περίπτωσή μας, θέλουμε πραγματικά να κλείσουμε το παράθυρο. Ο απλούστερος τρόπος είναι συνδέοντας το σήμα hide του αντικειμένου GtkWindow με μια συνάρτηση που κλείνει την εφαρμογή. Επιστρέψτε στο αρχείο <file>image-viewer.js</file> και προσθέστε τον παρακάτω κώδικα στη μέθοδο _init, στην παραπάνω γραμμή this.window.show:

Packit 1470ea
  this.window.connect ("hide", Gtk.main_quit)·
Packit 1470ea
  

Αυτό συνδέει το σήμα hide του παραθύρου στη συνάρτηση του Gtk main_quit, που τελειώνει την εκτέλεση του κύριου βρόχου Gtk. Μόλις ο κύριος βρόχος τελειώσει, η συνάρτηση Gtk.main επιστρέφει. Το πρόγραμμά μας συνεχίζει να τρέχει οποιοδήποτε κώδικα γραμμένο μετά τη γραμμή Gtk.main ();, αλλά αφού δεν έχουμε οποιοδήποτε κώδικα μετά από αυτό το σημείο, το πρόγραμμα απλά τελειώνει.

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="containers2">
Packit 1470ea
  <title>Περιέκτες: Σχεδίαση διεπαφής χρήστη</title>
Packit 1470ea
  

Γραφικά στοιχεία (έλεγχοι, όπως τα κουμπιά και οι ετικέτες) μπορούν να τοποθετηθούν στο παράθυρο κάνοντας χρήση των περιεκτών. Μπορείτε να οργανώσετε την διάταξη συνδυάζοντας διαφορετικών ειδών περιέκτες, όπως πλαίσια και πλέγματα.

Packit 1470ea
  

Ένα Gtk.Window είναι από μόνο του ένα είδος περιέκτη, αλλά μπορείτε να τοποθετήσετε μόνο ένα γραφικό στοιχείο άμεσα πάνω του. Θα θέλαμε να είχαμε δύο γραφικά στοιχεία, μια εικόνα και ένα κουμπί, άρα θα πρέπει να τοποθετήσουμε έναν υποδοχέα "υψηλότερης χωρητικότητας" μέσα στο παράθυρο για να κρατάει τα άλλα γραφικά στοιχεία. Ένας αριθμός από <link href="http://library.gnome.org/devel/gtk/stable/GtkContainer.html">τύπους περιεκτών</link> είναι διαθέσιμοι, αλλά θα χρησιμοποιήσουμε εδώ ένα Gtk.Box. Ένα Gtk.Box μπορεί να κρατήσει πολλά γραφικά στοιχεία, οργανωμένα οριζόντια ή κάθετα. Μπορείτε να κάνετε και πιο περίπλοκες διατάξεις βάζοντας πολλά πλαίσια το ένα μέσα στο άλλο κ.ο.κ.

Packit 1470ea
  <note>
Packit 1470ea
  

Υπάρχει ένας γραφικός σχεδιαστής διεπαφής χρήστη με όνομα <app>Glade</app> ενσωματωμένος στο <app>Anjuta</app> που κάνει τη σχεδίαση γραφικού περιβάλλοντος πολύ εύκολη. Για αυτό το απλό παράδειγμα, όμως, θα κωδικοποιήσουμε τα πάντα χειροκίνητα.

Packit 1470ea
  </note>
Packit 1470ea
  

Ας προσθέσουμε ένα πλαίσιο και γραφικά στοιχεία στο παράθυρο. Προσθέστε τον παρακάτω κώδικα στη μέθοδο _init, αμέσως πάνω από τη γραμμή this.window.show line:

Packit 1470ea
  
Packit 1470ea
var main_box = new Gtk.Box ({orientation: Gtk.Orientation.VERTICAL, spacing: 0});
Packit 1470ea
this.window.add (main_box);
Packit 1470ea
  

Η πρώτη γραμμή δημιουργεί ένα Gtk.Box που ονομάζεται main_box και ορίζει δύο από τις ιδιότητες του: την orientation που ρυθμίζεται στο κάθετο (οπότε τα γραφικά στοιχεία τακτοποιούνται σε στήλη), και το spacing ανάμεσα στα γραφικά στοιχεία που έχει ρυθμιστεί στα 0 εικονοστοιχεία. Η επόμενη γραμμή έπειτα προσθέτει στο παράθυρο το νεοδημιουργημένο Gtk.Box.

Packit 1470ea
  

Μέχρι στιγμής το παράθυρο περιέχει μόνο ένα άδειο Gtk.Box και άμα εκτελέσετε τώρα το πρόγραμμα δε θα δείτε καμία απολύτως αλλαγή (το Gtk.Box είναι ένας διαφανής περιέκτης, οπότε δεν μπορείτε να δείτε ότι είναι εκεί).

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="packing2">
Packit 1470ea
  <title>Συσκευασία: Πρόσθεση γραφικών στοιχείων στον περιέκτη</title>
Packit 1470ea
  

Για να προσθέσετε κάποια γραφικά στοιχεία στο Gtk.Box, εισάγετε τον ακόλουθο κώδικα ακριβώς κάτω από την γραμμή this.window.add (main_box):

Packit 1470ea
  
Packit 1470ea
this.image = new Gtk.Image ();
Packit 1470ea
main_box.pack_start (this.image, true, true, 0);
Packit 1470ea
  

Η πρώτη γραμμή δημιουργεί ένα καινούργιο Gtk.Image που ονομάζεται image, το οποίο θα εμφανίζει ένα αρχείο εικόνας. Έπειτα, το γραφικό στοιχείο εικόνας προστίθεται (πακεταρισμένο) στον περιέκτη main_box χρησιμοποιώντας τη μέθοδο του Gtk.Box <link href="http://library.gnome.org/devel/gtk/stable/GtkBox.html#gtk-box-pack-start">pack_start</link>.

Packit 1470ea
  

Το pack_start παίρνει 4 ορίσματα: το γραφικό στοιχείο που προστίθεται στο Gtk.Box (child)· αν το Gtk.Box πρέπει να μεγαλώσει όταν προστεθεί νέο γραφικό στοιχείο (expand)· αν το νέο γραφικό στοιχείο θα έπρεπε να καλύψει όλο τον διαθέσιμο χώρο αν μεγαλώσει το Gtk.Box (fill)· και πόσος χώρος πρέπει να υπάρχει, σε εικονοστοιχεία, ανάμεσα στο γραφικό στοιχείο και στους γείτονές του μέσα στο Gtk.Box, (padding).

Packit 1470ea
  

Οι περιέκτες (και τα γραφικά στοιχεία) του Gtk επεκτείνονται δυναμικά για να καλύψουν τον διαθέσιμο χώρο, αν τα αφήσετε. Δεν τοποθετείτε τα γραφικά στοιχεία δίνοντας τους ακριβείς θέσεις x, y-συντεταγμένων στο παράθυρο· αλλά, τοποθετούνται σχετικά μεταξύ τους. Αυτό κάνει το χειρισμό της αλλαγής του μεγέθους του παραθύρου πιο εύκολη και τα γραφικά στοιχεία πρέπει να πάρουν αυτόματα ένα λογικό μέγεθος στις περισσότερες περιπτώσεις.

Packit 1470ea
  

Επίσης σημειώστε πώς τα γραφικά στοιχεία οργανώνονται σε μια ιεραρχία. Μόλις πακεταριστούν μέσα στο Gtk.Box, το Gtk.Image θεωρείται θυγατρικό του Gtk.Box. Αυτό επιτρέπει να συμπεριφερθούμε σε όλα τα θυγατρικά ενός γραφικού στοιχείου ως μια ομάδα· για παράδειγμα, μπορείτε να κρύψετε το Gtk.Box, που θα κρύψει επίσης όλα τα θυγατρικά του ταυτόχρονα.

Packit 1470ea
  

Τώρα προσθέστε αυτές τις δύο γραμμές, κάτω από αυτές που μόλις προσθέσατε:

Packit 1470ea
  
Packit 1470ea
var open_button = new Gtk.Button ({label: "Open a picture..."});
Packit 1470ea
main_box.pack_start (open_button, false, false, 0);
Packit 1470ea
  

Αυτές οι γραμμές είναι παρόμοιες με τις δυο πρώτες, αλλά αυτή τη φορά δημιουργούν ένα Gtk.Button και το προσθέτουν στο main_box. Σημειώστε ότι ορίζουμε το όρισμα expand (το δεύτερο) στο false εδώ, ενώ είχε οριστεί σε true για το Gtk.Image. Αυτό θα προκαλέσει στην εικόνα να καλύψει όλο το διαθέσιμο χώρο και το κουμπί να πάρει μόνο όσο χρειάζεται. Όταν μεγιστοποιήσετε το παράθυρο, το μέγεθος των κουμπιών θα παραμείνει το ίδιο, ενώ το μέγεθος της εικόνας θα αυξηθεί, καταλαμβάνοντας όλο το υπόλοιπο παράθυρο.

Packit 1470ea
  

Τελικά, πρέπει να αλλάξουμε τη γραμμή this.window.show (); για να διαβάσει:

Packit 1470ea
  this.window.show_all ()·
Packit 1470ea
  

Αυτό θα εμφανίσει το θυγατρικό του παραθύρου Gtk και όλα τα θυγατρικά του και τα θυγατρικά των θυγατρικών του κ.ο.κ. (Να θυμάστε ότι τα γραφικά στοιχεία Gtk κρύβονται όλα από προεπιλογή)

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="loading2">
Packit 1470ea
  <title>Φόρτωση της εικόνας: Σύνδεση στο σήμα του κουμπιού clicked</title>
Packit 1470ea
  

Όταν ο χρήστης πατήσει στο κουμπί <gui>άνοιγμα</gui>, ένας διάλογος θα εμφανιστεί έτσι ώστε ο χρήστης να διαλέξει μια εικόνα. Μόλις διαλέξει, η εικόνα θα φορτωθεί και θα εμφανιστεί στο γραφικό στοιχείο της εικόνας.

Packit 1470ea
  

Το πρώτο βήμα είναι να συνδέσουμε το σήμα clicked του κουμπιού με μια συνάρτηση χειριστή σημάτων, την οποία καλούμε με _openClicked. Βάλτε αυτόν τον κώδικα αμέσως μετά την γραμμή var open_button = new Gtk.Button όπου το κουμπί δημιουργήθηκε:

Packit 1470ea
  
Packit 1470ea
open_button.connect ("clicked", Lang.bind (this, this._openClicked));
Packit 1470ea
  

Χρησιμοποιούμε τον βοηθό Lang JavaScript εδώ. Επιτρέπει τη σύνδεση μιας μεθόδου κλάσης με το σήμα, αντί για απλή συνάρτηση (χωρίς κλάση) που χρησιμοποιήσαμε πριν για το σήμα του παραθύρου hide. Μην ανησυχείτε για αυτό για τώρα, είναι απλά μια τεχνική λεπτομέρεια. Για να δουλέψει χρειαζόσαστε επίσης να βάλετε την παρακάτω γραμμή στην κορυφή του αρχείου:

Packit 1470ea
  const Lang = imports.lang·
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="loading3">
Packit 1470ea
  <title>Φόρτωση της εικόνας: Γράφοντας την επανάκληση του σήματος</title>
Packit 1470ea
  

Τώρα μπορούμε να δημιουργήσουμε τη μέθοδο _openClicked(). Εισάγετε τα ακόλουθα στην ομάδα κώδικα ImageViewer.prototype, μετά τη μέθοδο _init (και μη ξεχάσετε το κόμμα):

Packit 1470ea
    
Packit 1470ea
  _openClicked: function () {
Packit 1470ea
    var chooser = new Gtk.FileChooserDialog ({title: "Select an image",
Packit 1470ea
                                              action: Gtk.FileChooserAction.OPEN,
Packit 1470ea
                                              transient_for: this.window,
Packit 1470ea
                                              modal: true});
Packit 1470ea
    chooser.add_button (Gtk.STOCK_CANCEL, 0);
Packit 1470ea
    chooser.add_button (Gtk.STOCK_OPEN, 1);
Packit 1470ea
    chooser.set_default_response (1);
Packit 1470ea
Packit 1470ea
    var filter = new Gtk.FileFilter ();
Packit 1470ea
    filter.add_pixbuf_formats ();
Packit 1470ea
    chooser.filter = filter;
Packit 1470ea
Packit 1470ea
    if (chooser.run () == 1)
Packit 1470ea
      this.image.file = chooser.get_filename ();
Packit 1470ea
Packit 1470ea
    chooser.destroy ();
Packit 1470ea
  }
Packit 1470ea
  

Αυτό είναι λίγο πιο περίπλοκο από όσα έχουμε κάνει μέχρι τώρα, για αυτό θα το χωρίσουμε σε κομμάτια:

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

Η γραμμή που ξεκινάει με var chooser δημιουργεί έναν διάλογο <gui>ανοίγματος</gui>, τον οποίο ο χρήστης μπορεί να χρησιμοποιήσει για επιλογή αρχείων. Ορίζουμε τέσσερις ιδιότητες: τον τίτλο του διαλόγου· την ενέργεια (τύπο) του διαλόγου (είναι διάλογος "open", αλλά θα μπορούσαμε να χρησιμοποιήσουμε SAVE αν η πρόθεση ήταν να αποθηκεύσουμε ένα αρχείο· transient_for, που ορίζει το ανιόν παράθυρο του διαλόγου· και modal που, εάν οριστεί true, αποτρέπει το χρήστη από κλικ σε μια άλλη περιοχή της εφαρμογής μέχρι το κλείσιμο του διαλόγου.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Οι επόμενες δύο γραμμές προσθέτουν τα κουμπιά <gui>Cancel</gui> και <gui>Open</gui> στο διάλογο. Το δεύτερο όρισμα της μεθόδου του add_button είναι η (ακέραιη) τιμή που επιστρέφει όταν πατιέται το κουμπί: 0 για το <gui>Ακύρωση</gui> και 1 για το <gui>Άνοιγμα</gui>.

Packit 1470ea
    

Σημειώστε όταν χρησιμοποιούμε τα προκαθορισμένα ονόματα κουμπιών που υπάρχουν στο Gtk, αντί να γράψουμε οι ίδιοι "Ακύρωση" ή "Άνοιγμα". Το πλεονέκτημα στη χρήση των προκαθορισμένων ονομάτων είναι ότι οι ετικέτες των κουμπιών θα έχουν ήδη μεταφραστεί στη γλώσσα του χρήστη.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

To set_default_response καθορίζει ποιο κουμπί θα ενεργοποιηθεί όταν ο χρήστης επιλέξει ένα αρχείο με διπλό κλικ ή πατήσει <key>Enter</key>. Στην περίπτωση μας, χρησιμοποιούμε το κουμπί <gui>Άνοιγμα</gui> σαν προεπιλεγμένο (το οποίο έχει τιμή 1).

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Οι επόμενες τρεις γραμμές περιορίζουν το διάλογο <gui>Άνοιγμα</gui> να εμφανίζει μόνο αρχεία που μπορούν να ανοιχθούν από το Gtk.Image. Δημιουργούμε πρώτα ένα αντικείμενο φίλτρου· προσθέτουμε στο φίλτρο όλων των ειδών αρχεία που υποστηρίζονται από το Gdk.Pixbuf (το οποίο περιέχει τα περισσότερα είδη εικόνων όπως PNG και JPEG). Τέλος, καθορίζουμε το φίλτρο να είναι το φίλτρο του διαλόγου <gui>Άνοιγμα</gui>.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Το dialog.run εμφανίζει το διάλογο <gui>άνοιγμα</gui>. Ο διάλογος θα περιμένει τον χρήστη να διαλέξει μια εικόνα· όταν διαλέξει, το chooser.run θα επιστρέψει την τιμή <output>1</output> (θα επιστρέψει <output>0</output> αν ο χρήστης πατήσει <gui>ακύρωση</gui>). Η πρόταση if το ελέγχει.

Packit 1470ea
    </item>
Packit 1470ea
    <item>

Αν υποθέσουμε ότι ο χρήστης πάτησε το <gui>Άνοιγμα</gui>, η επόμενη γραμμή ορίζει την ιδιότητα file του Gtk.Image στο όνομα του αρχείου εικόνας που επέλεξε ο χρήστης. Το Gtk.Image θα φορτώσει και θα εμφανίσει την επιλεγμένη εικόνα.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Στην τελευταία γραμμή αυτής της μεθόδου, καταστρέφουμε τον διάλογο <gui>άνοιγμα</gui> γιατί δεν τον χρειαζόμαστε πια.

Packit 1470ea
    </item>
Packit 1470ea
  </list>
Packit 1470ea
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
<section id="run">
Packit 1470ea
  <title>Τρέξτε την εφαρμογή</title>
Packit 1470ea
  

Όλος ο κώδικας που χρειάζεστε πρέπει να είναι τώρα στη θέση του, οπότε δοκιμάστε την εκτέλεση του κώδικα. Αυτό ήτανε· ένας πλήρως λειτουργικός προβολέας εικόνων (και μια περιήγηση του JavaScript και Gtk) σε ελάχιστο χρόνο!

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="impl">
Packit 1470ea
 <title>Υλοποίηση αναφοράς</title>
Packit 1470ea
 

Αν αντιμετωπίσετε πρόβλημα με το μάθημα, συγκρίνετε τον κώδικά σας με αυτόν τον <link href="image-viewer/image-viewer.js">κώδικα αναφοράς</link>.

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="next">
Packit 1470ea
  <title>Επόμενα βήματα</title>
Packit 1470ea
  

Εδώ είναι κάποιες ιδέες για το πώς μπορείτε να επεκτείνετε αυτή την απλή παρουσίαση:

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

Βάλτε τον χρήστη να επιλέξει ένα κατάλογο αντί για αρχείο και δώστε ελέγχους να γυρίζουν όλες τις εικόνες σε έναν κατάλογο.

Packit 1470ea
   </item>
Packit 1470ea
   <item>
Packit 1470ea
   

Εφαρμόστε τυχαία φίλτρα και εφέ στην εικόνα όταν αυτή φορτωθεί και επιτρέψτε στον χρήστη να αποθηκεύσει την επεξεργασμένη εικόνα.

Packit 1470ea
   

Το <link href="http://www.gegl.org/api.html">GEGL</link> παρέχει ισχυρές δυνατότητες επεξεργασίας εικόνας.

Packit 1470ea
   </item>
Packit 1470ea
   <item>
Packit 1470ea
   

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

Packit 1470ea
   

You can use <link href="http://library.gnome.org/devel/gio/unstable/">GIO</link> to handle network file transfers and the like, and <link href="http://library.gnome.org/devel/gnome-scan/unstable/">GNOME Scan</link> to handle scanning.

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