Development/Tutorials/Plasma4/JavaScript/GettingStarted: Difference between revisions

From KDE TechBase
 
(25 intermediate revisions by 10 users not shown)
Line 1: Line 1:
{{TutorialBrowser|
series=JavaScript Plasmoids|
name=Introduction To Writing Plasmoids with JavaScript|
next=[[../DataEngine|Getting Data: How to retrieve data from a DataEngine]]|
reading=[[../API|JavaScript Plasmoid API reference]]
}}
== Abstract ==
== Abstract ==
In this tutorial we'll cover creating a very simple Plasmoid in JavaScript, otherwise known as [http://doc.trolltech.com/latest/qtscript.html QtScript] or [http://www.ecmascript.org/ ECMAScript], to provide a Plasma widget.


In this tutorial we'll cover creating a very simple plasmoid in [http://doc.trolltech.com/latest/qtscript.html QtScript], Qt's ECMAScript implementation, to provide a Plasma widget.  ECMAScript may be more familiar to you as JavaScript or JScript, which are Netscape's and Microsoft's implementations of the language, respectively.
Using JavaScript doesn't require any external dependencies, since it is part of the Qt libraries. As of KDE 4.3, the Plasma JavaScript engine is part of kdebase/runtime, and so can be used in any Plasma-based application, not just the Plasma Desktop.


Using QtScript doesn't require any external dependecies, since it is part of the Qt libraries.  As of KDE 4.3, the Plasma QtScript engine is part of kdebase/runtime, and so can be used in any libplasma-based application, not just the Plasma desktop.
== What is a widget? ==
In the context of Plasma, a "widget" is a single, self-contained graphical object on the canvas. They can be added and removed individually, configured separately from other widgets, etc. These "mini applications" are sometimes referred to in other widget platforms as "applets", "apps", "gadgets", "karambas", "desklets". We chose the word "widget" for Plasma as it is used by other some other existing systems.


Some terminology: <strong>widget</strong> refers to what the user will see on their desktop, and <strong>plasmoid</strong> refers to the package you will create by following this tutorial.  The distinction is not very strong, since a plasmoid always shows a widget, and the terms can be used interchangably to a certain extent. Just remember that "widget" is what the user will see.
The API of a widget is defined by the host "ScriptEngine", with the exception of native Plasma widgets written in C++ which allows plugins in loadable libraries which use the API of the Plasma library directly. Currently Plasma supports both such "native" widgets written in C++, ones written in various dynamic languages (Plasmoids) as well as:


* SuperKaramba's karambas
* Enlightenment 17 edje content
* Google Gadgets
* MacOS dashboard widgets (though not all)


== Project Structure ==
These are loaded via host AppletScriptEngine plugins that bridge between the widget itself and Plasma's canvas.


The first step for any software project is to set up your project's directory on disk. For this tutorial we are going to create a very simple "hello-qtscript" plasmoid. Create a directory on somewhere called <tt>hello-qtscript</tt> which in turn contains a <tt>contents</tt> directory which then contains a <tt>code</tt> directory. This command below will do all this.
== What is a Plasmoid? ==
<code bash>
A Plasmoid is a widget that can be loaded into Plasma that uses the native Plasma API and comes packaged in a single archive file which includes the code, metadata, images, configuration definitions, etc. Plasmoids may be currently written using various scripting languages and APIs. This tutorial covers the Simplified JavaScript API for Plasmoids
mkdir -p hello-qtscript/contents/code
 
</code>
== Hello world ==
The first step for any software project is to set up your project's directory on disk. For this tutorial we are going to create a very simple [http://en.wikipedia.org/wiki/Hello_world "Hello world"] plasmoid called "hello-javascript". Create a directory on somewhere called <tt>hello-javascript</tt> which in turn contains a <tt>contents</tt> directory which then contains a <tt>code</tt> directory. This command below will do all this.
<syntaxhighlight lang="bash">
cd
mkdir -p hello-javascript/contents/code
</syntaxhighlight>


The only required part of the structure, in fact, is the <tt>contents</tt> directory - almost everything will go in this directory.  But separating your code into a different directory from application data is a good habit to have.
The only required part of the structure, in fact, is the <tt>contents</tt> directory - almost everything will go in this directory.  But separating your code into a different directory from application data is a good habit to have.


=== Metadata.desktop ===
In the <tt>hello-javascript</tt> directory [[Development/Tutorials/Desktop_File|create a .desktop file]] called <tt>metadata.desktop</tt> with the following content:


== Metadata.desktop ==
<syntaxhighlight lang="ini">
 
In the <tt>hello-qtscript</tt> directory create a file called <tt>metadata.desktop</tt> and open it in your text editor. Copy the following code into <tt>metadata.desktop</tt>.
 
<code ini>
[Desktop Entry]
[Desktop Entry]
Name=Hello QtScript
Name=Hello JavaScript
Comment=An example QtScript widget
Comment=An example JavaScript widget
Icon=chronometer
Icon=chronometer


Line 37: Line 58:
X-KDE-PluginInfo-Author=<Your name here>
X-KDE-PluginInfo-Author=<Your name here>
X-KDE-PluginInfo-Email=<Your email here>
X-KDE-PluginInfo-Email=<Your email here>
X-KDE-PluginInfo-Name=hello-qtscript
X-KDE-PluginInfo-Name=hello-javascript
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=http://plasma.kde.org/
X-KDE-PluginInfo-Website=http://plasma.kde.org/
Line 44: Line 65:
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-KDE-PluginInfo-EnabledByDefault=true
</code>
</syntaxhighlight>


This <tt>metadata.desktop</tt> file list important information needed by Plasma to load the widget, and also information about what the widget is and who created it.
This <tt>metadata.desktop</tt> file list important information needed by Plasma to load the widget, and also information about what the widget is and who created it.


<tt>Name</tt> gives the name of widget as seen by the user when they go to the Add Widget dialog on the desktop.  There can be additional name entries for different languages.  For example, you could add a Dutch translation by inserting the line <tt>Name[nl]=Hallo QtScript</tt>.
<tt>Name</tt> gives the name of widget as seen by the user when they go to the Add Widget dialog on the desktop.  There can be additional name entries for different languages.  For example, you could add a Dutch translation by inserting the line <tt>Name[nl]=Hallo JavaScript</tt>.


<tt>Comment</tt> gives a more detailed description of the widget.  This is also displayed in the Add Widget dialog, and can be translated in the same way as <tt>Name</tt>.
<tt>Comment</tt> gives a more detailed description of the widget.  This is also displayed in the Add Widget dialog, and can be translated in the same way as <tt>Name</tt>.


<tt>Icon</tt> gives the name of the icon to associate with this plasmoid. The icon is shown in the Add Widget dialog.  It must be the name of an icon that is either distributed with KDE (such as <tt>chronometer</tt>) or provided by your plasmoid.
<tt>Icon</tt> gives the name of the icon to associate with this plasmoid. The icon is shown in the Add Widget dialog.  It must be the name of an icon that is either distributed with KDE (such as <tt>chronometer</tt>) or provided by your plasmoid. If you want to provide the icon, you can use <tt>Icon=icon.png</tt>.


The <tt>Type</tt>, <tt>X-KDE-ServiceTypes</tt>, <tt>X-Plasma-API</tt> and <tt>X-Plasma-MainScript</tt> fields are required for Plasma to find your plasmoid and know what to do with it.  Note that <tt>X-Plasma-MainScript</tt> is a path relative the <tt>contents</tt> directory.
The <tt>Type</tt>, <tt>X-KDE-ServiceTypes</tt>, <tt>X-Plasma-API</tt> and <tt>X-Plasma-MainScript</tt> fields are required for Plasma to find your plasmoid and know what to do with it.  Note that <tt>X-Plasma-MainScript</tt> is a path relative the <tt>contents</tt> directory.
Line 66: Line 87:
<tt>X-KDE-PluginInfo-EnabledByDefault</tt> and <tt>X-KDE-PluginInfo-Depends</tt> rarely need to be changed from the values given here.
<tt>X-KDE-PluginInfo-EnabledByDefault</tt> and <tt>X-KDE-PluginInfo-Depends</tt> rarely need to be changed from the values given here.


=== Main script ===
The name of the main script file is given by <tt>X-Plasma-MainScript</tt> in metadata.desktop, and is relative to the <tt>contents</tt> directory.  In our case, we will need to create the file <tt>hello-javascript/contents/code/main.js</tt>.  Put the following code in it:


== Main script ==
<syntaxhighlight lang="javascript">
 
The name of the main script file is given by <tt>X-Plasma-MainScript</tt> in metadata.desktop, and is relative to the <tt>contents</tt> directory.  In our case, we will need to create the file <tt>hello-qtscript/contents/code/main.js</tt>.  Put the following code in it:
 
<code>
layout = new LinearLayout(plasmoid);
layout = new LinearLayout(plasmoid);


Line 77: Line 96:
layout.addItem(label);
layout.addItem(label);


label.text = 'Hello QtScript!';
label.text = 'Hello JavaScript!';
</code>
</syntaxhighlight>


<strong>plasmoid</strong> is a global variable that represents your widget.  It has some useful methods that we'll come to in later tutorials.
<strong>plasmoid</strong> is a global variable that represents your widget.  It has some useful methods that we'll come to in later tutorials.
Line 86: Line 105:
Next we add a label to the layout, and finally we set the label text.
Next we add a label to the layout, and finally we set the label text.


== Testing (KDE 4.3+) ==
=== Testing (KDE 4.3+) ===
If you have KDE 4.3 or later, you can test your plasmoid without installing it by entering the <tt>hello-javascript</tt> directory and running <tt>plasmoidviewer</tt>.  Alternatively, call
<syntaxhighlight lang="bash">
plasmoidviewer ~/hello-javascript
</syntaxhighlight>


If you have KDE 4.3 or later, you can now test your plasmoid without installing it by entering the <tt>hello-qtscript</tt> directory and running <tt>plasmoidviewer</tt>. Alternatively, call
This is very convenient for development as you can edit the Plasmoid and test the changes immediately without re-installing the plasmoid over and over again.
<code bash>
plasmoidviewer /path/to/hello-qtscript
</code>


Note that with KDE 4.2, you will have to install the plasmoid first (see below).  After that, you can run plasmoidviewer with the name of the plasmoid given by <tt>X-KDE-PluginInfo-Name</tt> in <tt>metadata.desktop</tt>.  For example:
=== Installing ===
<code bash>
You can install the plasmoid by running the following command from within the <tt>hello-javascript</tt> directory:
plasmoidviewer hello-qtscript
<syntaxhighlight lang="bash">
</code>
 
 
== Installing ==
 
You can install the plasmoid by running the following command from within the <tt>hello-qtscript</tt> directory:
<code bash>
plasmapkg -i .
plasmapkg -i .
</code>
</syntaxhighlight>


The final argument to <tt>plasmapkg</tt> is the path to the directory containing <tt>metadata.desktop</tt> and the <tt>contents</tt> directory.
The final argument to <tt>plasmapkg</tt> is the path to the directory containing <tt>metadata.desktop</tt> and the <tt>contents</tt> directory.


You can now add your widget to the desktop using the Add Widgets dialog, or view it by running
You can now add your widget to the desktop using the Add Widgets dialog, or view it by running
<code bash>
<syntaxhighlight lang="bash">
plasmoidviewer hello-qtscript
plasmoidviewer hello-javascript
</code>
</syntaxhighlight>


If you want to see where your plasmoid has actually been installed you can find out like this:
# plasmapkg -i .
plasmapkg(6482)/libplasma Plasma::Package::installPackage: "/root/.kde4/share/apps/plasma/plasmoids//hello-javascript" already exists
Installation of /root/hello-javascript failed.
In this case it has been installed to /root/.kde4/share/apps/plasma/plasmoids//hello-javascript.


== Packaging ==
=== Packaging ===
If you want to share your plasmoid, you'll have to package it.  Run the following from within the <tt>hello-javascript</tt> directory:
<syntaxhighlight lang="bash">
zip -r ../hello-javascript.zip . &&
mv ../hello-javascript.zip ../hello-javascript.plasmoid
</syntaxhighlight>


If you want to share your plasmoid, you'll have to package it.  Run the following from within the <tt>hello-qtscript</tt> directory:
You now have a plasmoid package you can share with the world.  To install it, either use the "Install new widgets" functionality in the Add Widgets dialog, or go to the directory containing <tt>hello-javascript.plasmoid</tt> and run
<code bash>
<syntaxhighlight lang="bash">
zip -r ../hello-qtscript.zip . &&
plasmapkg -i hello-javascript.plasmoid
mv ../hello-qtscript.zip ../hello-qtscript.plasmoid
</syntaxhighlight>
</code>
 
You now have a plasmoid package you can share with the world.  To install it, either use the "Install new widgets" functionality in the Add Widgets dialog, or go to the directory containing <tt>hello-qtscript.plasmoid</tt> and run
<code bash>
plasmapkg -i hello-qtscript.plasmoid
</code>


To uninstall the plasmoid, use <tt>plasmapkg</tt> again with its -r option:
To uninstall the plasmoid, use <tt>plasmapkg</tt> again with its -r option:
<code bash>
<syntaxhighlight lang="bash">
plasmapkg -r hello-qtscript
plasmapkg -r hello-javascript
</code>
</syntaxhighlight>


Note that while the argument to <tt>plasmapkg -i</tt> is a file or directory, you need to pass the plasmoid name (given by <tt>X-KDE-PluginInfo-Name</tt> in <tt>metadata.desktop</tt>) to <tt>plasmapkg -r</tt>.
Note that while the argument to <tt>plasmapkg -i</tt> is a file or directory, you need to pass the plasmoid name (given by <tt>X-KDE-PluginInfo-Name</tt> in <tt>metadata.desktop</tt>) to <tt>plasmapkg -r</tt>.
== QtScript ==
The Simplified JavaScript API is powered by Qt's QtScript system which provides access to a full featured ECMA Script interpreter. If it works in ECMA Script, it will work in a Simplified JavaScript Plasmoid.
{{note|QtScript uses the high performance ECMA Script interpreter from WebKit and shares this code with QtWebKit.
However, QtScript does not include things such as a DOM API those familiar with JavaScript from a web browser context may expect. It is ''just'' ECMA Script with Qt integration.}}
On top of the ECMA Script language, QtScript provides Qt integration features. Probably the most useful one in the context of writing Plasmoids is the use of signals and slots which is Qt's callback mechanism. Signals may be emitted in QtScript by calling the signal method in question, a signal can be connected to a slot by using the connect() method (and disconnected with disconnect()) and any function defined in the Plasmoid may be used as a slot. For example:
<syntaxhighlight lang="javascript">
function onClick()
{
    print("We got clicked!")
}
function onFirstClick()
{
    print("First click!")
    button.clicked.disconnect(onFirstClick)
}
button = new PushButton
button.clicked.connect(onClick)
button.clicked.connect(onFirstClick)
button.clicked()
</syntaxhighlight>
This will print out:
<syntaxhighlight lang="text">
We got clicked!
First click!
</syntaxhighlight>
on the console when the Plasmoid starts, and the "We got clicked!" again whenever the button is clicked by the user.

Latest revision as of 23:27, 11 September 2014

Introduction To Writing Plasmoids with JavaScript
Tutorial Series   JavaScript Plasmoids
Previous   None
What's Next   Getting Data: How to retrieve data from a DataEngine
Further Reading   JavaScript Plasmoid API reference

Abstract

In this tutorial we'll cover creating a very simple Plasmoid in JavaScript, otherwise known as QtScript or ECMAScript, to provide a Plasma widget.

Using JavaScript doesn't require any external dependencies, since it is part of the Qt libraries. As of KDE 4.3, the Plasma JavaScript engine is part of kdebase/runtime, and so can be used in any Plasma-based application, not just the Plasma Desktop.

What is a widget?

In the context of Plasma, a "widget" is a single, self-contained graphical object on the canvas. They can be added and removed individually, configured separately from other widgets, etc. These "mini applications" are sometimes referred to in other widget platforms as "applets", "apps", "gadgets", "karambas", "desklets". We chose the word "widget" for Plasma as it is used by other some other existing systems.

The API of a widget is defined by the host "ScriptEngine", with the exception of native Plasma widgets written in C++ which allows plugins in loadable libraries which use the API of the Plasma library directly. Currently Plasma supports both such "native" widgets written in C++, ones written in various dynamic languages (Plasmoids) as well as:

  • SuperKaramba's karambas
  • Enlightenment 17 edje content
  • Google Gadgets
  • MacOS dashboard widgets (though not all)

These are loaded via host AppletScriptEngine plugins that bridge between the widget itself and Plasma's canvas.

What is a Plasmoid?

A Plasmoid is a widget that can be loaded into Plasma that uses the native Plasma API and comes packaged in a single archive file which includes the code, metadata, images, configuration definitions, etc. Plasmoids may be currently written using various scripting languages and APIs. This tutorial covers the Simplified JavaScript API for Plasmoids

Hello world

The first step for any software project is to set up your project's directory on disk. For this tutorial we are going to create a very simple "Hello world" plasmoid called "hello-javascript". Create a directory on somewhere called hello-javascript which in turn contains a contents directory which then contains a code directory. This command below will do all this.

cd
mkdir -p hello-javascript/contents/code

The only required part of the structure, in fact, is the contents directory - almost everything will go in this directory. But separating your code into a different directory from application data is a good habit to have.

Metadata.desktop

In the hello-javascript directory create a .desktop file called metadata.desktop with the following content:

[Desktop Entry]
Name=Hello JavaScript
Comment=An example JavaScript widget
Icon=chronometer

Type=Service
X-KDE-ServiceTypes=Plasma/Applet

X-Plasma-API=javascript
X-Plasma-MainScript=code/main.js
X-Plasma-DefaultSize=200,100

X-KDE-PluginInfo-Author=<Your name here>
X-KDE-PluginInfo-Email=<Your email here>
X-KDE-PluginInfo-Name=hello-javascript
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=http://plasma.kde.org/
X-KDE-PluginInfo-Category=Examples
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true

This metadata.desktop file list important information needed by Plasma to load the widget, and also information about what the widget is and who created it.

Name gives the name of widget as seen by the user when they go to the Add Widget dialog on the desktop. There can be additional name entries for different languages. For example, you could add a Dutch translation by inserting the line Name[nl]=Hallo JavaScript.

Comment gives a more detailed description of the widget. This is also displayed in the Add Widget dialog, and can be translated in the same way as Name.

Icon gives the name of the icon to associate with this plasmoid. The icon is shown in the Add Widget dialog. It must be the name of an icon that is either distributed with KDE (such as chronometer) or provided by your plasmoid. If you want to provide the icon, you can use Icon=icon.png.

The Type, X-KDE-ServiceTypes, X-Plasma-API and X-Plasma-MainScript fields are required for Plasma to find your plasmoid and know what to do with it. Note that X-Plasma-MainScript is a path relative the contents directory.

X-Plasma-DefaultSize specifies the default size for widget, as width,height. While the units aren't technically pixels, they have the same value as pixels providing you don't do anything like zoom in or out on your desktop.

X-KDE-PluginInfo-Category gives a category for the widget. This is used in the Add Widgets dialog to group and filter widgets. The value must be one of the category names listed at Projects/Plasma/PIG.

X-KDE-PluginInfo-Name is the internal name of the plasmoid (you can think of this as the name of the plasmoid, as opposed to the name of the widget which is given by Name). This is the name you will use as an argument to plasmoidviewer or plasmapkg when you need to provide a plasmoid name rather than a path. It doesn't have to be the same name as the directory containing metadata.desktop.

X-KDE-PluginInfo-Author, X-KDE-PluginInfo-Email, X-KDE-PluginInfo-Version, X-KDE-PluginInfo-Website and X-KDE-PluginInfo-License are informational, and are displayed in the About dialog for the plasmoid (which can be viewed by clicking the information icon next to the corresponding widget in the Add Widgets dialog of plasma).

X-KDE-PluginInfo-EnabledByDefault and X-KDE-PluginInfo-Depends rarely need to be changed from the values given here.

Main script

The name of the main script file is given by X-Plasma-MainScript in metadata.desktop, and is relative to the contents directory. In our case, we will need to create the file hello-javascript/contents/code/main.js. Put the following code in it:

layout = new LinearLayout(plasmoid);

label = new Label();
layout.addItem(label);

label.text = 'Hello JavaScript!';

plasmoid is a global variable that represents your widget. It has some useful methods that we'll come to in later tutorials.

First, we create a layout, because plasmoids don't have a layout by default. This just makes sure that the label is the correct size and in the correct place. Passing plasmoid to the LinearLayout attaches the layout to the widget.

Next we add a label to the layout, and finally we set the label text.

Testing (KDE 4.3+)

If you have KDE 4.3 or later, you can test your plasmoid without installing it by entering the hello-javascript directory and running plasmoidviewer. Alternatively, call

plasmoidviewer ~/hello-javascript

This is very convenient for development as you can edit the Plasmoid and test the changes immediately without re-installing the plasmoid over and over again.

Installing

You can install the plasmoid by running the following command from within the hello-javascript directory:

plasmapkg -i .

The final argument to plasmapkg is the path to the directory containing metadata.desktop and the contents directory.

You can now add your widget to the desktop using the Add Widgets dialog, or view it by running

plasmoidviewer hello-javascript

If you want to see where your plasmoid has actually been installed you can find out like this:

# plasmapkg -i .
plasmapkg(6482)/libplasma Plasma::Package::installPackage: "/root/.kde4/share/apps/plasma/plasmoids//hello-javascript" already exists 
Installation of /root/hello-javascript failed.

In this case it has been installed to /root/.kde4/share/apps/plasma/plasmoids//hello-javascript.

Packaging

If you want to share your plasmoid, you'll have to package it. Run the following from within the hello-javascript directory:

zip -r ../hello-javascript.zip . &&
mv ../hello-javascript.zip ../hello-javascript.plasmoid

You now have a plasmoid package you can share with the world. To install it, either use the "Install new widgets" functionality in the Add Widgets dialog, or go to the directory containing hello-javascript.plasmoid and run

plasmapkg -i hello-javascript.plasmoid

To uninstall the plasmoid, use plasmapkg again with its -r option:

plasmapkg -r hello-javascript

Note that while the argument to plasmapkg -i is a file or directory, you need to pass the plasmoid name (given by X-KDE-PluginInfo-Name in metadata.desktop) to plasmapkg -r.

QtScript

The Simplified JavaScript API is powered by Qt's QtScript system which provides access to a full featured ECMA Script interpreter. If it works in ECMA Script, it will work in a Simplified JavaScript Plasmoid.

Note
QtScript uses the high performance ECMA Script interpreter from WebKit and shares this code with QtWebKit. However, QtScript does not include things such as a DOM API those familiar with JavaScript from a web browser context may expect. It is just ECMA Script with Qt integration.


On top of the ECMA Script language, QtScript provides Qt integration features. Probably the most useful one in the context of writing Plasmoids is the use of signals and slots which is Qt's callback mechanism. Signals may be emitted in QtScript by calling the signal method in question, a signal can be connected to a slot by using the connect() method (and disconnected with disconnect()) and any function defined in the Plasmoid may be used as a slot. For example:

function onClick()
{
    print("We got clicked!")
}

function onFirstClick()
{
    print("First click!")
    button.clicked.disconnect(onFirstClick)
}

button = new PushButton
button.clicked.connect(onClick)
button.clicked.connect(onFirstClick)
button.clicked()

This will print out:

We got clicked!
First click!

on the console when the Plasmoid starts, and the "We got clicked!" again whenever the button is clicked by the user.