Taryn Fox
jewelfox@fursona.net 2012
Ditt första GNOME-program!
Sebastian Rasmussen
sebras@gmail.com 2019
Anders Jonsson
anders.jonsson@norsjovallen.se 2021

# 1. Hej GNOME!

        Denna handledning kommer visa dig hur du skriver ditt första GNOME-program i Javascript. Du kommer använda Javascript för att skriva för GNOME på samma sätt som du skulle skriva för webben. Efteråt kommer du lära dig hur du använder ”inhemska” komponenter för att skriva program som ser ut som och känns som andra GNOME-program.
        Har du GNOME installerat på din dator, och gedit konfigurerat för att skriva kod med? Du kommer vilja göra dessa saker först.

# Låt oss börja med en webbsida

Här är lite grundläggande HTML-, CSS- och Javascript-kod. Verkar det bekant?

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

<!-- Använd Javascript för att visa en hälsning när någon klickar på knappen --> <script type="application/javascript"> function greeting () { document.getElementById ("greeting").innerHTML = ("O hai!"); } </script>

<!-- Väldigt enkel CSS-stil som använder GNOME-typsnittet --> <style type="text/css"> body { font-face: Cantarell, sans-serif; text-align: center; } </style>

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

<!-- Tomt H1-element som blir ifyllt när knappen klickas på --> <h1 id="greeting"></h1> </body> </html>

Låt oss spara detta som hellognome.html, och se hur det ser ut när vi kör det!

Du kan köra koden ovan genom att öppna hellognome.html i en webbläsare. Men här kommer vi skapa ett GNOME-program som kör vår webbapplikation inuti sig, precis som du ser i skärmbilden. Du kommer kunna ändra storlek på och maximera fönstret, och klicka på X i hörnet för att stänga det, precis som du skulle förvänta dig från vilket annat GNOME-program som helst. Skillnaden är att detta kommer att köra vår webbkod i sig.

Det bästa med det? Vi kommer fortsätta använda Javascript för alla delar som gör att vårt program fungerar med GNOME. Låt oss ta en titt på koden, och se hur det görs!

# Skapa ett GNOME-fönster för att rama in vår webbapplikation

Först behöver vi säga till GNOME att detta är ett Javascript-program som använder gjs. Gjs är GNOME:s sätt att förvandla din Javascript-kod till instruktioner som det förstår, så denna rad måste alltid finnas i början av dina program.

#!/usr/bin/gjs

Sedan ska vi ställa in versionerna av biblioteken som vi kommer använda.

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

Efter det behöver vi säga till GNOME vilka bibliotek som vi vill importera.

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

Precis som hur tilläggsbibliotek som jQuery låter oss göra extra saker med Javascript så ger vart och ett av dessa bibliotek oss nya förmågor till våra GNOME-program:

Gtk är den grundläggande delen av alla GNOME-program, vilket låter dig skapa fönster och komponenter och binda ihop dem.

GLib är ett hjälpbibliotek, vilket låter oss göra saker som att säga till GNOME var filen hellognome.html som vi skapade finns.

Webkit är slutligen en webbrenderingsmotor, vilken vi kommer använda för att praktiskt taget skapa ett webbläsarfönster att öppna vår HTML-fil med.

Nu skapar vi programmet i sig:

class HelloGNOME {

Detta kommer verka bekant för dig om du har arbetat med objektorienterad Javascript innan. Det stämmer: hela vårt program är en klass med namnet HelloGNOME.

// Skapa programmet i sig constructor() { this.application = new Gtk.Application();

// Anslut ”activate”- och ”startup”-signaler till återanropsfunktionerna this.application.connect('activate', this._onActivate.bind(this)); this.application.connect('startup', this._onStartup.bind(this)); }

// Återanropsfunktion för ”activate”-signal visar fönster när den aktiveras _onActivate() { this._window.present(); }

// Återanropsfunktion för ”startup”-signal bygger användargränssnittet _onStartup() { this._buildUI(); }

Här är lite kod du mer eller mindre kommer kopiera och klistra för varje Javascript-program som du bygger. Det skapar en ny Application, och binder sedan dess ”activate”- och ”startup”-signaler till funktioner som får fönstret att visa sig respektive bygga sitt användargränssnitt.

Vad betyder det här? Tja, allt i ett GNOME-program skickar ut en signal då något viktigt händer. En knapp kan exempelvis skicka ut signalen ”clicked” när du klickar på den. Vårt jobb är att ansluta signalerna till funktioner som hanterar dem, och får de saker som vi vill ska hända att inträffa. Vi gör detta genom att använda varje objekts ”connect”-metod, vilken tar två argument: signalen som vi vill hantera, och den bundna funktionen, vilken vi måste använda för att säga till ”connect” vilken funktion vi vill ska hantera signalen.

I detta fall vill vi att _onActivate ska hantera ”activate”-signalen, och att _onStartup ska hantera ”startup”-signalen. _onActivate säger bara till fönstret att visa sig; i princip så att närhelst du använder Alt Tabb för att växla till programmet så visas det, som du skulle förvänta dig. _onStartup anropar _buildUI vilket är funktionen som skapar vårt användargränssnitt och är nästa del som vi kommer att ta en titt på.

När du kopierar och klistrar in koden ovan för dina egna program, säkerställ att du ändrar klassnamnet till ett unikt namn varje gång.

# Designa vårt fönsters användargränssnitt

I _buildUI-funktionen kommer vi säga till GNOME om vårt fönster och sakerna i det, en åt gången. Efter det kommer vi koppla ihop allting och visa upp det.

// Bygg programmets användargränssnitt _buildUI() {

// Skapa programfönstret this._window = new Gtk.ApplicationWindow ({ application: this.application, title: "Välkommen till GNOME", default_height: 200, default_width: 400, window_position: Gtk.WindowPosition.CENTER });

Det första objektet vi skapar är ett ApplicationWindow. Det behöver en titel till namnlisten, och dess ”application”-egenskap måste vara programmet vi skapade ovan. Bortom det så finns det olika sätt att anpassa hur det ser ut, vilket referenssidan ApplicationWindow kommer gå in på mer detaljerat. Som du kan se här så gav vi det en standardbredd och standardhöjd (mätt i bildpunkter), och sa till GNOME att vi vill att vårt fönster ska dyka upp i mitten på skärmen.

// Skapa en webbvy för att visa webbapplikationen this._webView = new Webkit.WebView ();

// Stoppa webbapplikationen i webbvyn this._webView.load_uri (GLib.filename_to_uri (GLib.get_current_dir() + "/hellognome.html", null));

Kommer du ihåg hur vi importerade Webkit i början? Här skapar vi en ny instans av en Webkit-klass som kallas en WebView, vilken mer eller mindre är ett webbläsarfönster som du kan stoppa i ditt program. Efter det ger vi den URI:n som vi vill att den ska läsa in när programmet startar.

Vi skulle kunna bara ge den en webb-URI, som http://gnome.org. Istället använder vi några GLib-hjälpfunktioner för att säga till vår WebView var vår fil hellognome.html är. GLib.get_current_dir returnerar katalogen som vårt program körs i, och GLib.filename_to_uri omvandlar vår fils sökväg och filnamn till en URI som vår WebViews load_uri-funktion förstår. (Den andra parametern för filename_to_uri ska vara null om du inte vet vad den används för och har en anledning att ändra den.)

// Stoppa webbvyn i fönstret this._window.add (this._webView);

// Visa fönstret och alla barnkomponenter this._window.show_all(); },

});

Varje fönster kan hålla en, och endast en, komponent. Vanligen skulle vi använda en behållarkomponent som en Grid att stoppa flera komponenter i, och sedan fönstrets add-funktion för att lägga till denna Grid till det. Här behöver vi bara en WebView, så det är allt vi lägger till i fönstret. Efter det, som sista del av _buildUI-funktionen som skapar vårt fönster, säger vi till fönstret att visa sig och sitt innehåll.

// Kör programmet let app = new HelloGNOME (); app.application.run (ARGV);

Slutligen skapar vi en ny instans av vår HelloGNOME-klass, och säger till GNOME att köra den.

# Köra ditt GNOME-program

Nu då vi skapat vårt första GNOME-program så är det dags att testa det! Du behöver inte kompilera ditt program eller installera någon speciell programvara för detta, GNOME har gjs inbyggt för att låta det köra GNOME-skalet. Spara bara hellognome.html och vårt faktiska program, hellognome.js, till en katalog som du kan komma åt med terminalen. (De öppnas vanligen i din hemkatalog, den som har ditt användarnamn som namn.) Öppna efter det en terminal, gå dit, och skriv:

     $ gjs hellognome.js

Du bör se mer eller mindre samma skärmbild som tidigare, med en knapp som du kan klicka på för att få ett kort meddelande att dyka upp.

Du kan använda terminalkommandot

     $ cd (katalognamn)

to navigate between directories inside the Terminal, in order to get to where you saved the files. There is also an extension for Nautilus, GNOME's file manager, which lets you right-click anywhere inside it to open a terminal window right there. Check the app you use to install new software (like Add/Remove Programs or the Software Center) for it.

# Vad är nästa steg?

Fortsätt till nästa handledning för att lära dig hur du bygger ”inhemska” GNOME-program som ser ut och känns som de andra, istället för en webbvy med HTML-kod inuti. Eller ta en titt på några kodexempel, om du vill se exempelkod för varje Gtk-komponent.

Slutligen, om du bara vill bygga GNOME-program med Javascript-bibliotek som designats för webben så kan du praktiskt taget sluta här och gå och göra det! Ta en titt på de senare handledningarna om du vill se hur du kan skapa en .desktop-fil för ditt program, vilken låter det dyka upp i ditt skrivbords aktivitetsmeny med alla dina andra program.

# Fullständigt kodexempel

#!/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 {

// Skapa programmet i sig constructor() { this.application = new Gtk.Application ();

// Anslut ”activate”- och ”startup”-signaler till återanropsfunktionerna this.application.connect('activate', this._onActivate.bind(this)); this.application.connect('startup', this._onStartup.bind(this)); }

// Återanropsfunktion för ”activate”-signal visar fönster när den aktiveras _onActivate() { this._window.present(); }

// Återanropsfunktion för ”startup”-signal bygger användargränssnittet _onStartup() { this._buildUI(); }

// Bygg programmets användargränssnitt _buildUI() {

// Skapa programfönstret this._window = new Gtk.ApplicationWindow ({ application: this.application, title: "Välkommen till GNOME", default_height: 200, default_width: 400, window_position: Gtk.WindowPosition.CENTER });

// Skapa en webbvy för att visa webbapplikationen this._webView = new Webkit.WebView ();

// Stoppa webbapplikationen i webbvyn this._webView.load_uri (GLib.filename_to_uri (GLib.get_current_dir() + "/hellognome.html", null));

// Stoppa webbvyn i fönstret this._window.add (this._webView);

// Visa fönstret och alla barnkomponenter this._window.show_all(); }

};

// Kör programmet let app = new HelloGNOME (); app.application.run (ARGV);