Πίνακας μηνύματος (C) Ένα απλό πρόγραμμα που χρησιμοποιεί WebKitGTK+ και DOM. Shaun McCance shaunm@gnome.org 2010 Marta Maria Casetti mmcasetti@gmail.com 2013 Ελληνική μεταφραστική ομάδα GNOME team@gnome.gr 2012-2015 Δημήτρης Σπίγγος dmtrs32@gmail.com 2012, 2013 Μαρία Θουκιδίδου marablack3@gmail.com 2014 Θάνος Τρυφωνίδης tomtryf@gmail.com 2014, 2015 Πίνακας μηνύματος

Σε αυτό το μάθημα, θα μάθετε:

Πώς να εμφανίσετε μια ιστοσελίδα με WebKit.

Πώς να χειριστείτε τα περιεχόμενα μιας ιστοσελίδας χρησιμοποιώντας τις συναρτήσεις DOM του WebKit.

Αυτό το μάθημα υποθέτει εξοικείωση με τη γλώσσα προγραμματισμού C και βασική κατανόηση της GTK+, συμπεριλαμβανόμενης της δημιουργίας και τοποθέτησης γραφικών στοιχείων και της σύνδεσης συναρτήσεων επανάκλησης σε σήματα. Δείτε για να μάθετε τα βασικά του GTK+.

Δημιουργία έργου με το Anjuta

Το GNOME περιέχει το WebKitGTK+, κατασκευασμένο πάνω στον ισχυρό σκελετό του WebKit HTML. Το WebKit χρησιμοποιείται μέσα από το GNOME, όχι μόνο για προβολή ιστοσελίδων στο διαδίκτυο, αλλά επίσης για δημιουργία πλούσιων διεπαφών χρήστη που μπορούν εύκολα να μορφοποιηθούν με CSS.

Σε αυτό το μάθημα, θα δημιουργήσετε ένα απλό πίνακα μηνύματος χρησιμοποιώντας WebKit. Ο πίνακας μηνύματος θα επιτρέψει την εισαγωγή κάποιου κειμένου και την προσθήκη του σε μια λίστα μηνυμάτων σε HTML. Πριν την εκκίνηση, χρειαζόσαστε να ρυθμίσετε ένα έργο στο Anjuta.

Στο Anjuta, κάντε κλικ στο ΑρχείοΝέο Έργο για να ανοίξετε τον νέο βοηθό έργου.

Επιλέξτε GTK+ (απλό) στην καρτέλα C και κλικ συνέχεια.

Συμπληρώστε τις λεπτομέρειές σας στη σελίδα βασικές πληροφορίες. Χρησιμοποιήστε πίνακα μηνύματος για το όνομα του έργου. Κλικ συνέχεια.

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

Πρέπει να πείτε στο Anjuta ότι χρησιμοποιείτε WebKitGTK+ για αυτό το έργο. Στη σελίδα επιλογές έργου, επιλέξτε ρύθμιση εξωτερικών πακέτων. Κλικ συνέχεια. Στη σελίδα ρύθμιση εξωτερικών πακέτων, σημειώστε webkitgtk-3.0.

Αφού τελειώσετε με τον βοηθό του νέου έργου, ανοίξτε το αρχείο src/main.c είτε από το έργο ή από την καρτέλα αρχείο. Το Anjuta θα το γεμίσει με κάποιο βασικό κώδικα GTK+ από τα πρότυπά του. Αφού δημιουργείτε ένα έργο WebKit, χρειάζεστε πρώτα να συμπεριλάβετε τις κεφαλίδες WebKit. Μετά τη γραμμή που περιέχει gtk/gtk.h, προσθέστε την παρακάτω γραμμή:

#include <webkit/webkit.h>

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

Τώρα θα μπορείτε να τρέξετε το πρόγραμμα. Κάντε κλικ στο ΤρέξιμοΕκτέλεση ή απλά πατήστε F3. Θα πρέπει να δείτε ένα άδειο παράθυρο.

Διευθέτηση του παραθύρου σας και προβολή ιστού

Τώρα που μπορείτε να δείτε ένα παράθυρο, είναι καιρός να ξεκινήσετε δουλειά με το WebKit. Για αυτό το μάθημα, θα δημιουργηθεί μια καταχώριση κειμένου και μια προβολή ιστού και πακετάρισμα τους σε ένα παράθυρο. Βρείτε τη συνάρτηση create_window και αντικαταστήστε την με την παρακάτω:

static GtkWidget* create_window (void) { GtkWidget *window, *box, *scroll, *view, *entry; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW (window), 400, 400); gtk_window_set_title (GTK_WINDOW (window), "Message Board"); g_signal_connect (window, "delete-event", G_CALLBACK (gtk_main_quit), NULL); box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_container_set_border_width (GTK_CONTAINER (box), 6); gtk_container_add (GTK_CONTAINER (window), box); entry = gtk_entry_new (); gtk_box_pack_start (GTK_BOX (box), entry, FALSE, FALSE, 0); scroll = gtk_scrolled_window_new (NULL, NULL); g_object_set (scroll, "shadow-type", GTK_SHADOW_IN, NULL); gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0); view = webkit_web_view_new (); gtk_container_add (GTK_CONTAINER (scroll), view); webkit_web_view_load_string (WEBKIT_WEB_VIEW (view), "<html><body></body></html>", "text/html", "UTF-8", NULL); gtk_widget_show_all (GTK_WIDGET (box)); return window; }

Δημιουργήστε πρώτα ένα αντικείμενο GtkWindow και ορίστε τον τίτλο το προεπιλεγμένο μέγεθος του. Συνδέστε επίσης τη συνάρτηση gtk_main_quit με το σήμα delete-event. Το σήμα delete-event εκπέμπεται όταν το παράθυρο κλείνει. Η συνάρτηση gtk_main_quit είναι τμήμα του GTK και εγκαταλείπει την εφαρμογή.

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

Έπειτα δημιουργείστε ένα αντικείμενο GtkEntry και πακετάρετε το στο πλαίσιο. Το τρίτο και τέταρτο όρισμα στο gtk_box_pack_start καθορίζει ότι η καταχώριση δεν θα πρέπει να πάρει επιπλέον χώρο που το πλαίσιο έχει διαθέσιμο. Το τέταρτο όρισμα είναι η ποσότητα συμπλήρωσης που θέλετε γύρω από την καταχώριση. Σε αυτή την περίπτωση, ορίζετε τη συμπλήρωση σε μηδέν, επειδή επιτρέπετε στο πλαίσιο να χειριστεί όλη τη συμπλήρωση.

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

Τελικά, δημιουργείτε ένα WebKitWebView και το προσθέτετε στο κυλιόμενο παράθυρο. Έπειτα φορτώνετε μια πολύ βασική σελίδα HTML στην προβολή ιστού καλώντας webkit_web_view_load_string με τα παρακάτω ορίσματα:

<code>WEBKIT_WEB_VIEW (view)</code>

Η ίδια η προβολή. Επειδή η view πληκτρολογείτε ως GtkWidget, πρέπει να χρησιμοποιήσετε WEBKIT_WEB_VIEW για ασφαλή αλλαγή του αντικειμένου.

<code>"<html><body></body></html>"</code>

Το απλούστερο αρχείο HTML που θα μπορούσατε να γράψετε.

<code>"text/html"</code>

Ο τύπος MIME του περιεχομένου που δίνετε. Σε αυτήν την περίπτωση, χρησιμοποιείτε απλό HTML.

<code>"UTF-8"</code>

Η κωδικοποίηση χαρακτήρα του παρεχόμενου περιεχομένου. Αν και χρησιμοποιείτε μόνο ASCII χαρακτήρες, είναι καλή ο καθορισμός UTF-8. Το UTF-8 χρησιμοποιείται ως η προεπιλεγμένη κωδικοποίηση ολοκληρωτικά στο GNOME.

<code>NULL</code>

Η βάση URI. Δεν την χρειαζόσαστε σε αυτό το απλό παράδειγμα, αλλά ίσως θελήσετε να δώσετε ένα file: URI εάν προσθέσετε εικόνες ή άλλα χαρακτηριστικά που θέλετε να χρησιμοποιήσετε σχετικές αναφορές URI.

Κάθε φορά που προσθέτετε ένα γραφικό στοιχείο, πρέπει να καλέσετε gtk_widget_show για να γίνει ορατό. Εάν καλέσετε gtk_widget_show_all σε ένα περιέκτη γραφικού στοιχείου όπως GtkBox, το GTK+ θα εμφανίσει αυτόματα όλα τα γραφικά στοιχεία μέσα στον περιέκτη, σε οποιοδήποτε βάθος. Μερικές φορές δεν θέλετε να καλέσετε gtk_widget_show_all, όπως όταν θέλετε να κρύψετε δυναμικά και να εμφανίσετε μερικά γραφικά στοιχεία σε απάντηση συμβάντων.

Τελικά, πρέπει να καλέσετε gtk_widget_show_all στο πλαίσιο. Αλλιώς, κανένα από τα γραφικά στοιχεία που δημιουργήσατε δεν θα είναι ορατό. (Το παράθυρο εμφανίζεται στη συνάρτηση main με gtk_widget_show.)

Αναπτύξτε και εκτελέστε ξανά τον πίνακα μηνύματος. Πρέπει να δείτε ένα παράθυρο με μια καταχώριση κειμένου και μια προβολή ιστού. Δεν κάνει τίποτα ακόμα, επειδή η καταχώριση κειμένου και η προβολή ιστού δεν ξέρουν τίποτα μεταξύ τους.

Σύνδεση σημάτων

Τώρα, θέλετε να κάνετε τον πίνακα μηνύματος στην πραγματικότητα να κάνει κάτι όταν εισάγετε κείμενο στην καταχώριση κειμένου. Για να το κάνετε αυτό, συνδέστε μια συνάρτηση επανάκλησης στο σήμα activate του entry. Το GTK+ εκπέμπει το σήμα activate όταν ο χρήστης πατά Enter στην καταχώριση. Προσθέστε το παρακάτω στο create_window, οπουδήποτε αφού και entry και view οριστούν:

g_signal_connect (entry, "activate", G_CALLBACK (entry_activate_cb), view);

Τότε πρέπει στην πραγματικότητα να ορίσετε το entry_activate_cb. Ορίστε το όπως ακολουθεί, οπουδήποτε πάνω από το create_window:

static void entry_activate_cb (GtkEntry *entry, WebKitWebView *view) { WebKitDOMDocument *document; WebKitDOMElement *body, *div; document = webkit_web_view_get_dom_document (view); body = webkit_dom_document_query_selector (document, "body", NULL); div = webkit_dom_document_create_element (document, "div", NULL); webkit_dom_node_set_text_content (WEBKIT_DOM_NODE (div), gtk_entry_get_text (entry), NULL); webkit_dom_node_append_child (WEBKIT_DOM_NODE (body), WEBKIT_DOM_NODE (div), NULL); gtk_entry_set_text (entry, ""); }

Το πρώτο πράγμα είναι να πάρετε ένα αντικείμενο WebKitDOMDocument που αντιπροσωπεύει το εμφανιζόμενο έγγραφο στο view. Οι κλάσεις DOM και οι μέθοδοι στο WebKit επιτρέπουν την επιθεώρηση και χειρισμό του εγγράφου HTML και δουλεύουν πολύ παρόμοια με τα APIs DOM που ήδη μπορεί να ξέρετε από το JavaScript.

Μόλις έχετε το έγγραφο, παίρνετε το στοιχείο body, έτσι ώστε να μπορείτε να προσθέσετε τα στοιχεία div σε αυτό. Η συνάρτηση webkit_dom_document_query_selector επιτρέπει την εύρεση ενός στοιχείου στο έγγραφο χρησιμοποιώντας επιλογείς CSS. Αυτό σας γλυτώνει από το γράψιμο κουραστικών βρόχων για πέρασμα του εγγράφου.

Μετά, δημιουργείτε ένα νέο στοιχείο div για κράτημα του μηνύματος. Κάθε στοιχείο που δημιουργείτε πρέπει να προσαρτηθεί σε ένα έγγραφo, έτσι η συνάρτηση στη δημιουργία ενός στοιχείου παίρνει το WebKitDOMDocument ως τα πρώτα της ορίσματα. Έπειτα ορίζετε το περιεχόμενο κειμένου του στοιχείου στα περιεχόμενα της καταχώρισης κειμένου. Επειδή το gtk_entry_get_text επιστρέφει το const gchar*, δεν πρέπει να απελευθερώσετε το αποτέλεσμα.

Τελικά, προσαρτάτε το νέο στοιχείο div στο σώμα και καθαρίστε την καταχώριση κειμένου, έτσι ώστε να μπορείτε να τυπώσετε κάτι νέο. Κατασκευή και εκτέλεση του προγράμματος ξανά και έλεγχος του για σας.

Κάντε το να φαίνεται καλύτερα με CSS

Σε αυτό το σημείο, το πρόγραμμά σας είναι ολότελα λειτουργικό, αλλά όχι πολύ όμορφο. Μπορείτε να μορφοποιήσετε την εμφάνιση μηνύματος με CSS, απλά όπως μπορείτε με κάθε άλλη σελίδα HTML. Υπάρχουν πολλοί τρόποι που θα μπορούσατε να προσαρτήσετε μερικά CSS στη σελίδα: Μπορείτε να τα προσθέσετε στο αρχικό έγγραφο HTML. Θα μπορούσατε να το ενσωματώσετε στο γνώρισμα style των στοιχείων div. Θα μπορούσατε ακόμα να το κατασκευάσετε προγραμματιστικά χρησιμοποιώντας τα APIs DOM.

Σε αυτό το μάθημα, θα επισυνάψετε το CSS χρησιμοποιώντας την ιδιότητα user-stylesheet-uri του προσαρτημένου αντικειμένου WebKitWebSetting στην προβολή σας ιστού. Σε μια πιο πλήρη εφαρμογή, θα θέλατε να αποθηκεύσετε και να φορτώσετε το αρχείο HTML. Διατηρώντας τις πληροφορίες μορφοποίησης έξω από το ενεργό HTML σημαίνει ότι μπορείτε να αλλάξετε ολότελα τη μορφοποίηση μες την εφαρμογή σας, χωρίς να χρειαστεί να αλλάξετε τα αρχεία χρήστη. Κανονικά θα εγκαταστήσετε απλά ένα αρχείο μαζί με την εφαρμογή σας, αλλά για να διατηρήσετε απλά κάθε τι σε ένα αρχείο για αυτή την παρουσίαση, θα χρησιμοποιήσουμε ένα κόλπο που λέγεται δεδομένα URI. Πρώτα, ορίστε το CSS ως στατική συμβολοσειρά κοντά στην κορυφή του αρχείου σας.

static const guchar CSS[] = "body { margin: 0; padding: 0; }\n" "div { " " -webkit-border-radius: 2px;" " background: -webkit-gradient(linear, 0% 100%, 0% 0%," " from(#f1f1f1), to(white));" " border: solid 1px #c6c6c6;" " -webkit-box-shadow: 0px 0px 2px #c6c6c6;" " margin: 12px; padding: 6px;" "}";

Ό,τι έχετε σε αυτό το παράδειγμα είναι στοιχεία div μέσα σε ένα στοιχείο body. Εάν δημιουργήσατε πιο περίπλοκα HTML, θα μπορούσατε να χρησιμοποιήσετε οποιοδήποτε CSS είναι απαραίτητο. Στην πραγματικότητα, εάν είσαστε άνετα με CSS, θα πρέπει να προσπαθήσετε να το αλλάξετε με κάτι που σας αρέσει καλύτερα.

Για εφαρμογή του CSS, ορίζετε τον user-stylesheet-uri στην συνάρτηση create_window, οπουδήποτε μετά τον ορισμό του view.

tmp = g_base64_encode (CSS, strlen((gchar *) CSS)); css = g_strconcat ("data:text/css;charset=utf-8;base64,", tmp, NULL); g_object_set (webkit_web_view_get_settings (WEBKIT_WEB_VIEW (view)), "user-stylesheet-uri", css, NULL); g_free (css); g_free (tmp);

Επίσης, βεβαιωθείτε να προσθέσετε δηλώσεις μεταβλητής για tmp και css στην κορυφή του create_window.

gchar *tmp, *css·

Δεδομένα URI ξεκινούν με data: και μερικές πληροφορίες για τον τύπο περιεχομένου και την κωδικοποίηση δεδομένων. Τα ενεργά δεδομένα ακολουθούν μετά το κόμμα, σε αυτήν την περίπτωση κωδικοποιημένα σε Base64. Αντίθετα με άλλα σχήματα URI όπως http:, ftp: και file:, το σχήμα data: URI δεν καθορίζει πού να βρείτε ένα αρχείο για φόρτωση. Μάλλον, δίνει τα συνολικά περιεχόμενα του αρχείου.

Ο παραπάνω κώδικας πρώτα κωδικοποιεί τους ορισμούς σας CSS σε Base64, έπειτα συνδυάζει αυτό με σταθερή συμβολοσειρά για δημιουργία δεδομένων URI. Η συνάρτηση g_strconcat μπορεί να πάρει οποιοδήποτε αριθμό ορισμάτων συμβολοσειράς και να τα συνενώσει όλα μαζί, έτσι έχετε να περάσετε το NULL ως τελικό όρισμα για να γνωρίζει πότε να σταματήσει. Μην ξεχάσετε να ελευθερώσετε αυτές τις προσωρινές συμβολοσειρές αφού ορίσετε την ιδιότητα φύλλο μορφοποίησης.

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

Μάθετε περισσότερα

Αυτό το μάθημα δείχνει τη δημιουργία μιας βασικής εφαρμογής χρησιμοποιώντας GTK+ και WebKit, περιλαμβάνοντας την εμφάνιση ενός εγγράφου και επεξεργασία των δεδομένων του. Για τη δημιουργία μιας πραγματικής εφαρμογής, θα θέλετε προφανώς να κάνετε κάτι περισσότερο. Προσπαθήστε να προσθέσετε δικά σας χαρακτηριστικά. Να μερικές ιδέες:

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

Τώρα αμέσως, χάνετε όλα τα μηνύματά σας όταν κλείνετε τον πίνακα μηνυμάτων. Δοκιμάστε να αποθηκεύσετε τα περιεχόμενα HTML μετά από κάθε ταχυδρόμηση και φορτώστε το αποθηκευμένο αρχείο (εάν υπάρχει) στην εκκίνηση.

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

Αυτό το πρόγραμμα κρατά τα μηνύματα για πάντα. Σκεφτείτε τρόπους που θα μπορούσαν να επιτρέψουν στο χρήστη να διαγράψει μηνύματα. Ίσως θέλετε τα μηνύματα να εξαφανίζονται αυτόματα όταν παλιώνουν, ή όταν υπάρχει ένας συγκεκριμένος αριθμός μηνυμάτων πριν από αυτά. Ή θα μπορούσατε να προσθέσετε έναν σύνδεσμο σε κάθε μήνυμα για διαγραφή του. Θα μπορούσατε ακόμα να αντικαταστήσετε το μενού περιεχομένου όταν κάνετε δεξιό κλικ σε μήνυμα. Αυτές τα χαρακτηριστικά περιέχουν περισσότερη περιήγηση του DOM API του WebKit.