# Ραδιοπλήκτρα -RadioButton- (JavaScript)

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

# Ράδιοπλήκτρο (RadioButton)

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

Κάθε RadioButton χρειάζεται μία ετικέτα κειμένου και μια ομάδα. Μόνο ένα κουμπί σε μια ομάδα μπορεί να επιλεγεί τη φορά. Δεν ονομάζετε κάθε ομάδα· μόλις ρυθμίσατε νέα RadioButtons για να είναι τμήμα της ίδιας ομάδας ως μια υπάρχουσα. Εάν δημιουργείτε ένα νέο εκτός μιας ομάδας, δημιουργεί αυτόματα μια νέα ομάδα για να είναι μέρος του.

# Βιβλιοθήκες για εισαγωγή

#!/usr/bin/gjs

const Gio = imports.gi.Gio; const Gtk = imports.gi.Gtk; const Lang = imports.lang;

Αυτές είναι οι βιβλιοθήκες που χρειαζόμαστε να εισάγουμε αυτήν την εφαρμογή για να εκτελεστεί. Να θυμόσαστε ότι η γραμμή που λέει στο GNOME ότι χρησιμοποιούμε Gjs χρειάζεται πάντοτε να πάει στην αρχή.

# Δημιουργία του παραθύρου εφαρμογής

const RadioButtonExample = new Lang.Class({ Name: 'RadioButton Example',

// Δημιουργία της εφαρμογής αυτής καθεαυτής _init: function() { this.application = new Gtk.Application({ application_id: 'org.example.jsradiobutton', flags: Gio.ApplicationFlags.FLAGS_NONE });

// Σύνδεση των σημάτων 'activate' και 'startup' με τις συναρτήσεις επανάκλησης this.application.connect('activate', Lang.bind(this, this._onActivate)); this.application.connect('startup', Lang.bind(this, this._onStartup)); },

// Η συνάρτηση επανάκλησης για το σήμα 'activate' παρουσιάζει παράθυρο όταν είναι ενεργή _onActivate: function() { this._window.present(); },

// Η συνάρτηση επανάκλησης για το σήμα 'startup' δομέί τη διεπαφή χρήστη _onStartup: function() { this._buildUI (); },

Όλος ο κώδικας για αυτό το παράδειγμα πηγαίνει στην κλάση RadioButtonExample. Ο παραπάνω κώδικας δημιουργεί μια Gtk.Application για να μπουν μέσα τα γραφικά στοιχεία μας και τα παράθυρα.

// Δόμηση της διεπαφής χρήστη της εφαρμογής _buildUI: function() {

// Δημιουργία του παραθύρου της εφαρμογής this._window = new Gtk.ApplicationWindow({ application: this.application, window_position: Gtk.WindowPosition.CENTER, border_width: 20, title: "Travel Planning"});

Η συνάρτηση _buildUI είναι εκεί που βάζουμε όλον τον κώδικα για να δημιουργήσουμε τη διεπαφή χρήστη της εφαρμογής. Το πρώτο βήμα δημιουργεί ένα νέο Gtk.ApplicationWindow για να βάλουμε μέσα τα γραφικά στοιχεία μας.

# Δημιουργία των ραδιοκουμπιών

// Δημιουργία μιας ετικέτας για την πρώτη ομάδα κουμπιών this._placeLabel = new Gtk.Label ({label: "Where would you like to travel to?"});

Χρησιμοποιούμε μια Gtk.Label για να ορίσουμε κάθε ομάδα RadioButtons ανεξάρτητα. Τίποτα δεν σας εμποδίζει να βάλετε τα RadioButtons από όλες τις διαφορετικές ομάδες όπου θέλετε, έτσι εάν θέλετε οι άλλοι να ξέρουν ποιο πηγαίνει μαζί, χρειαζόσαστε να οργανώσετε τα πράγματα ανάλογα.

// Δημιουργία τριών ραδιοπλήκτρων τριών διαφορετικών τρόπων this._place1 = new Gtk.RadioButton ({label: "The Beach"});

this._place2 = Gtk.RadioButton.new_from_widget (this._place1); this._place2.set_label ("The Moon");

this._place3 = Gtk.RadioButton.new_with_label_from_widget (this._place1, "Antarctica"); // this._place3.set_active (true);

Εδώ υπάρχουν τρεις διαφορετικοί τρόποι να δημιουργήσετε RadioButtons. Ο πρώτος είναι ο συνηθισμένος τρόπος, όπου δημιουργούμε ένα νέο Gtk.RadioButton και αποδίδουμε τις ιδιότητές του ταυτόχρονα. Ο δεύτερος και τρίτος χρησιμοποιούν συναρτήσεις που χειρίζονται αυτόματα μερικές από τις ιδιότητες· το new_from_widget παίρνει ένα μοναδικό όρισμα, το RadioButton στο οποίο θέλετε να βάλετε αυτό το νέο στην ίδια ομάδα. Εν τω μεταξύ, το new_with_label_from_widget το παίρνει καθώς και την ετικέτα του RadioButton ταυτόχρονα.

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

// Δημιουργία μιας ετικέτας για τη δεύτερη ομάδα κουμπιών this._thingLabel = new Gtk.Label ({label: "And what would you like to bring?" });

// Δημιουργία τριών επιπλέον ραδιοπλήκτρων this._thing1 = new Gtk.RadioButton ({label: "Penguins" }); this._thing2 = new Gtk.RadioButton ({label: "Sunscreen", group: this._thing1 }); this._thing3 = new Gtk.RadioButton ({label: "A spacesuit", group: this._thing1 });

Εδώ δημιουργούμε την ετικέτα για τη δεύτερη ομάδα κουμπιών και έπειτα τα δημιουργούμε όλα με τον ίδιο τρόπο.

# Δημιουργία της υπόλοιπης διεπαφής χρήστη

// Δημιουργία ενός πλήκτρου παρακαταθήκης ΕΝΤΑΞΕΙ this._okButton = new Gtk.Button ({ label: 'gtk-ok', use_stock: 'true', halign: Gtk.Align.END });

// Σύνδεση του κουμπιού με τη συνάρτηση που χειρίζεται το πάτημά του this._okButton.connect ('clicked', Lang.bind (this, this._okClicked));

Αυτός ο κώδικας δημιουργεί ένα Gtk.Button και το συνδέει με μια συνάρτηση που θα εμφανίσει στους άλλους ένα χαζό μήνυμα όταν πατήσουν εντάξει, ανάλογα με τα επιλεγμένα RadioButtons.

Για να βεβαιωθείτε ότι η ετικέτα του κουμπιού "OK" εμφανίζεται κατάλληλα σε κάθε γλώσσα στην οποία μεταφράζεται το GNOME, να θυμάστε να χρησιμοποιήσετε έναν από τους τύπους κουμπιών παρακαταθήκης του Gtk.

// Δημιουρία ενός πλέγματος για τοποθέτηση των στοιχείων "place" μέσα this._places = new Gtk.Grid ();

// Προσάρτηση των στοιχείων "place" στο πλέγμα this._places.attach (this._placeLabel, 0, 0, 1, 1); this._places.attach (this._place1, 0, 1, 1, 1); this._places.attach (this._place2, 0, 2, 1, 1); this._places.attach (this._place3, 0, 3, 1, 1);

// Δημιουργία ενός πλέγματος για τοποθέτηση των στοιχείων "thing" μέσα this._things = new Gtk.Grid ({ margin_top: 50 });

// Προσάρτηση των στοιχείων "thing" στο πλέγμα this._things.attach (this._thingLabel, 0, 0, 1, 1); this._things.attach (this._thing1, 0, 1, 1, 1); this._things.attach (this._thing2, 0, 2, 1, 1); this._things.attach (this._thing3, 0, 3, 1, 1);

// Δημιουργία ενός πλέγματος για τοποθέτηση όλων μέσα this._grid = new Gtk.Grid ({ halign: Gtk.Align.CENTER, valign: Gtk.Align.CENTER, margin_left: 40, margin_right: 50 });

// Προσάρτηση όλων στο πλέγμα this._grid.attach (this._places, 0, 0, 1, 1); this._grid.attach (this._things, 0, 1, 1, 1); this._grid.attach (this._okButton, 0, 2, 1, 1);

// Προσάρτηση του πλέγματος στο παράθυρο this._window.add (this._grid);

Χρησιμοποιούμε ένα ανεξάρτητο Gtk.Grid για να οργανώσουμε κάθε ομάδα ραδιοπλήκτρων. Με αυτό τον τρόπο μπορούμε να αλλάξουμε τη διάταξη με λιγότερη αναστάτωση αργότερα. Το δεύτερο πλέγμα έχει ένα περιθώριο στην κορυφή, για οπτική διάκριση των δύο συνόλων επιλογών.

Αφού τα οργανώσουμε, τα βάζουμε σε ένα τρίτο, κύριο πλέγμα, μαζί με το κουμπί εντάξει. Έπειτα το προσαρτούμε στο παράθυρο.

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

Τελικά, λέμε στο παράθυρο και σε κάθε τι που είναι μέσα του να γίνει ορατό όταν τρέχει η εφαρμογή.

# Η συνάρτηση που χειρίζεται την επιλογή σας

_okClicked: function () {

// Δημιουργία ενός αναδυόμενου που εμφανίζει ένα χαζό μήνυμα this._travel = new Gtk.MessageDialog ({ transient_for: this._window, modal: true, message_type: Gtk.MessageType.OTHER, buttons: Gtk.ButtonsType.OK, text: this._messageText() });

// Εμφάνιση του αναδυόμενου this._travel.show();

// Σύνδεση του κουμπιού ΕΝΤΑΞΕΙ με τη συνάρτηση που κλείνει το αναδυόμενο this._travel.connect ("response", Lang.bind (this, this._clearTravelPopUp));

},

Όταν πατάτε εντάξει, ένας Gtk.MessageDialog εμφανίζεται. Αυτή η συνάρτηση δημιουργεί και εμφανίζει το αναδυόμενο παράθυρο, έπειτα συνδέει το κουμπί της εντάξει με τη συνάρτηση που το κλείνει. Τι κείμενο εμφανίζεται στο αναδυόμενο εξαρτάται από τη συνάρτηση _messageText(), που επιστρέφει μια διαφορετική τιμή ανάλογα με το σύνολο επιλογών που διαλέξατε.

_messageText: function() {

// Δημιουργία ενός χαζού μηνύματος για το αναδυόμενο ανάλογα με το τι διαλέξατε var stringMessage = "";

if (this._place1.get_active()) {

if (this._thing1.get_active()) stringMessage = "Penguins love the beach, too!";

else if (this._thing2.get_active()) stringMessage = "Make sure to put on that sunscreen!";

else stringMessage = "Are you going to the beach in space?";

}

else if (this._place2.get_active()) {

if (this._thing1.get_active()) stringMessage = "The penguins will take over the moon!";

else if (this._thing2.get_active()) stringMessage = "A lack of sunscreen will be the least of your problems!";

else stringMessage = "You'll probably want a spaceship, too!"; }

else if (this._place3.get_active()) {

if (this._thing1.get_active()) stringMessage = "The penguins will be happy to be back home!";

else if (this._thing2.get_active()) stringMessage = "Antarctic sunbathing may be hazardous to your health!";

else stringMessage = "Try bringing a parka instead!"; }

return stringMessage;

},

Η μέθοδος get_active() λέει πώς μπορούμε να πούμε ποιο RadioButton πατιέται. Αυτή η συνάρτηση επιστρέφει ένα διαφορετικό χαζό μήνυμα ανάλογα με ποιο σύνολο κουμπιών πατήθηκε. Η επιστρεφόμενη τιμή χρησιμοποιείται ως ιδιότητα κειμένου του MessageDialog.

_clearTravelPopUp: function () {

this._travel.destroy();

}

});

Αυτή η συνάρτηση καλείται όταν το κουμπί εντάξει του MessageDialog πατιέται. Κάνει απλά το αναδυόμενο να φύγει.

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

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

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

#!/usr/bin/gjs

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

const Gio = imports.gi.Gio; const Gtk = imports.gi.Gtk;

class RadioButtonExample {

// Create the application itself constructor() { this.application = new Gtk.Application({ application_id: 'org.example.jsradiobutton', flags: Gio.ApplicationFlags.FLAGS_NONE });

// 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 window 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, window_position: Gtk.WindowPosition.CENTER, border_width: 20, title: "Travel Planning"});

// Create a label for the first group of buttons this._placeLabel = new Gtk.Label ({label: "Where would you like to travel to?"});

// Create three radio buttons three different ways this._place1 = new Gtk.RadioButton ({label: "The Beach"});

this._place2 = Gtk.RadioButton.new_from_widget (this._place1); this._place2.set_label ("The Moon");

this._place3 = Gtk.RadioButton.new_with_label_from_widget (this._place1, "Antarctica"); // this._place3.set_active (true);

// Create a label for the second group of buttons this._thingLabel = new Gtk.Label ({label: "And what would you like to bring?" });

// Create three more radio buttons this._thing1 = new Gtk.RadioButton ({label: "Penguins" }); this._thing2 = new Gtk.RadioButton ({label: "Sunscreen", group: this._thing1 }); this._thing3 = new Gtk.RadioButton ({label: "A spacesuit", group: this._thing1 });

// Create a stock OK button this._okButton = new Gtk.Button ({ label: 'gtk-ok', use_stock: 'true', halign: Gtk.Align.END });

// Connect the button to the function which handles clicking it this._okButton.connect ('clicked', this._okClicked.bind(this));

// Create a grid to put the "place" items in this._places = new Gtk.Grid ();

// Attach the "place" items to the grid this._places.attach (this._placeLabel, 0, 0, 1, 1); this._places.attach (this._place1, 0, 1, 1, 1); this._places.attach (this._place2, 0, 2, 1, 1); this._places.attach (this._place3, 0, 3, 1, 1);

// Create a grid to put the "thing" items in this._things = new Gtk.Grid ({ margin_top: 50 });

// Attach the "thing" items to the grid this._things.attach (this._thingLabel, 0, 0, 1, 1); this._things.attach (this._thing1, 0, 1, 1, 1); this._things.attach (this._thing2, 0, 2, 1, 1); this._things.attach (this._thing3, 0, 3, 1, 1);

// Create a grid to put everything in this._grid = new Gtk.Grid ({ halign: Gtk.Align.CENTER, valign: Gtk.Align.CENTER, margin_left: 40, margin_right: 50 });

// Attach everything to the grid this._grid.attach (this._places, 0, 0, 1, 1); this._grid.attach (this._things, 0, 1, 1, 1); this._grid.attach (this._okButton, 0, 2, 1, 1);

// Add the grid to the window this._window.add (this._grid);

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

_okClicked() {

// Create a popup that shows a silly message this._travel = new Gtk.MessageDialog ({ transient_for: this._window, modal: true, message_type: Gtk.MessageType.OTHER, buttons: Gtk.ButtonsType.OK, text: this._messageText() });

// Show the popup this._travel.show();

// Bind the OK button to the function that closes the popup this._travel.connect ("response", this._clearTravelPopUp.bind(this));

}

_messageText() {

// Create a silly message for the popup depending on what you selected var stringMessage = "";

if (this._place1.get_active()) {

if (this._thing1.get_active()) stringMessage = "Penguins love the beach, too!";

else if (this._thing2.get_active()) stringMessage = "Make sure to put on that sunscreen!";

else stringMessage = "Are you going to the beach in space?";

}

else if (this._place2.get_active()) {

if (this._thing1.get_active()) stringMessage = "The penguins will take over the moon!";

else if (this._thing2.get_active()) stringMessage = "A lack of sunscreen will be the least of your problems!";

else stringMessage = "You'll probably want a spaceship, too!"; }

else if (this._place3.get_active()) {

if (this._thing1.get_active()) stringMessage = "The penguins will be happy to be back home!";

else if (this._thing2.get_active()) stringMessage = "Antarctic sunbathing may be hazardous to your health!";

else stringMessage = "Try bringing a parka instead!"; }

return stringMessage;

}

_clearTravelPopUp() { this._travel.destroy(); } };

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

# Τεκμηρίωση σε βάθος

Gtk.Application

Gtk.ApplicationWindow

Gtk.Button

Gtk.Grid

Gtk.Label

Gtk.RadioButton