Difference between revisions of "QML GUI"

From Navit's Wiki
Jump to: navigation, search
(Download Qt libraries: fix version note & download link)
 
(19 intermediate revisions by 5 users not shown)
Line 1: Line 1:
QML gui is designed to be a modern and flexible replacement of internal gui. It is based on Qt's Declarative UI framework, therefore it could be run on ant Qt platform, including mobile platforms with touchscreens etc
+
[[Image:Qml point 20100404.png|thumb]]
 +
The QML GIU is designed to be a modern and flexible replacement of internal gui. It is based on [http://en.wikipedia.org/wiki/QML Qt's modelling language UI framework], therefore it could be run on any Qt platform, including mobile platforms with touchscreens etc
 +
 
 +
{{warning
 +
|The QML GUI is currently unmaintained and buggy. So feel free to test it, but be prepared to fix it...
 +
}}
  
 
==Building it==
 
==Building it==
  
First of all - you have to install [ftp://ftp.trolltech.com/qt/source/ Qt 4.6] and a [ftp://ftp.trolltech.com/qml/ SNAPSHOT of a Declarative UI] With snapshot mentioned above you have to use exactly Qt version 4.6.0, for other 4.6.x releases you have to manually checkout Declarative UI from git. Qt version 4.7 is unsupported yet.
+
===Install from source or from distribution packages?===
 +
The following instructions are for installing the Qt libraries from source. On Linux, it is usually easier to install Qt from the package manager instead. See [[Dependencies]] for the packages to install.
  
When you have prepared your Qt environment, it's time to build Navit:
+
===Download Qt libraries===
 +
So you have decided to install from source? Fine.
  
 +
First of all - you will need the Qt 4 libraries and headers installed. Navit needs Qt 4.7 or 4.8. This can be downloaded from:
 +
* [http://download.qt.io/archive/qt/ http://download.qt.io/archive/qt/]
 +
* download the .tar.gz file
 +
 +
===Configure and build Qt===
 +
The following example instructions are for configuring and building Qt on Ubuntu 10.04. The procedure for your particular device may vary. Note: The "4.8.0" has to be adjusted depending on the version you install.
 +
 +
* Unzip the archive into a folder of your choice. The following example has unzipped to ~/src.
 +
* cd to that folder in a terminal
 +
<pre>cd ~/src/qt-everywhere-opensource-src-4.8.0/</pre>
 +
* Configure Qt
 
<pre>
 
<pre>
./configure --enable-gui-qml
+
./configure
 
</pre>
 
</pre>
 +
* During configure:
 +
** Asks what type to use: Commercial or Open Source. Select Open Source ('o')
 +
** Asks to accept licence: Chose 'yes'
 +
* Make Qt (this may take a long time: ~5hrs on a netbook)
 +
<pre> make </pre>
 +
* Install Qt
 +
<pre> sudo make install </pre>
 +
 +
===Add Qt to your environment===
 +
Issue the following commands at a terminal to ensure that Navit can find Qt:
 +
<pre>
 +
PATH=/usr/local/Trolltech/Qt-4.8.0/bin:$PATH
 +
export PATH
 +
export PKG_CONFIG_PATH=/usr/local/Trolltech/Qt-4.8.0/lib/pkgconfig
 +
</pre>
 +
 +
===Build Navit===
 +
Once you have prepared your Qt environment, it's time to build Navit. If Qt is installed correctly, the CMake build should pick it up and enable Qt support automatically.
  
 
At the script output you should have the following lines:
 
At the script output you should have the following lines:
 
<pre>
 
<pre>
Graphics types: yes (default)
+
Enabled   qt_qpainter ( Qt libraries found )
   qt_qpainter:      yes (default)
+
[...]
GUI types:
+
Enabled   qml ( Qt Declarative found )
   qml:              yes (configure parameter)
 
 
</pre>
 
</pre>
  
both of them are required for gui qml. So if those lines present, do your usual make && make install/dpkg-buildpackage/your platform specific thing.
+
Both qt_qpainter and qml are required to successfully run the qml GUI. If those lines are present, do your usual make && make install/dpkg-buildpackage/your-platform-specific thing.
 
 
==Configuring it==
 
  
Right now QML gui is compatible only with qt_qpainter graphics type. I hope there will be more graphics types in the future, but now you have to switch to qt_qpainter:
+
==Configuring Navit.xml==
 +
Right now QML gui is compatible only with qt_qpainter graphics type. I hope there will be more graphics types in the future, but right now you have to switch to qt_qpainter:
  
 
<pre>
 
<pre>
Line 42: Line 76:
 
in their configuration stanzas.
 
in their configuration stanzas.
  
QML gui doesn't requires any special configuration, but it could be tuned. It support the following parameters:
+
==Configuring QML GUI==
    * fullscreen - "1"-Default is fullscreen mode,'''"0"-Default is windows mode'''
+
 
    * menu_on_map_click - '''"1"-single click on map will switch to gui''',"0"-Gui could be switched only by command (not yet implemented)
+
QML gui doesn't require any special configuration, but it can be tuned. It supports the following parameters, which go inside the <gui> tag (default values in '''bold'''). You can have as many of the parameters as you want in the <gui> tag:
    * signal_on_map_click - "1"-DBus signal will be sent on single click on map,'''"0"-map click processing will be controlled bu menu_on_map_click'''
+
====fullscreen====
    * radius - Distance in meters for searching point name. '''Default is 10'''
+
* '''"0" - Start Navit in windowed mode (default)'''
    * pitch - Initial pitch for 3D view. '''Default is 20'''
+
* "1" - Start Navit in fullscreen mode
    * lazy - '''"1"-Gui should be lazy and keep it state between calls''',"0"-Gui is always reset to main page when called
+
Example:
    * width #height - Width and height for gui window. '''Default values are 800 and 600'''
+
<pre> <gui type="qml" enabled="yes" fullscreen="1"></pre>
    * source - Directory with qml skins. '''Default value is NAVIT_SHAREDIR/gui/qml/skins'''
+
 
    * skin - Skin for gui. '''Default skin is navit'''
+
====menu_on_map_click====
    * icon_src - Directory with icons for gui.'''Default value is NAVIT_SHAREDIR/xpm/
+
* "0" - Menu GUI is switched by a command ''(not yet implemented)''
 +
* '''"1" - Single click on map will bring up the menu GUI (default)'''
 +
Example:
 +
<pre> <gui type="qml" enabled="yes" menu_on_map_click="1">
 +
(A bit useless since this is the default anyway...)</pre>
 +
 
 +
====signal_on_map_click====
 +
* '''"0" - When single clicking on the map, processing to be controlled by menu_on_map_click (default)'''
 +
* "1" - When single clicking on the map, send a DBus signal
 +
 
 +
====radius====
 +
This takes a number, which is the distance in kilometres which POI search will restrict to
 +
* '''"10" - Default POI search radius, in kilometres (default)'''
 +
Example:
 +
<pre> <gui type="qml" enabled="yes" radius="5">
 +
(Restrict POI search to a 5km radius)</pre>
 +
 
 +
====pitch====
 +
This takes a number, which is the angle of the 3D view in degrees with which Navit should start when in 3D mode.
 +
* '''"20" - Default 3D pitch, in degrees (default)'''
 +
 
 +
====lazy====
 +
* "0" - When menu GUI is called (such as when single-clicking on the map), always show the main menu page
 +
* '''"1" - When menu GUI is called (such as when single-clicking on the map), show the menu page which was last used (i.e. remember menu page states between calls) (default)'''
 +
Example:
 +
<pre> <gui type="qml" enabled="yes" lazy="0"></pre>
 +
 
 +
====width/height====
 +
This takes a number, which is the desired width/height of the GUI window, in pixels
 +
* '''width=800 - Default width of GUI window, in pixels (default)'''
 +
* '''height=600 - Default height of GUI window, in pixels (default)'''
 +
 
 +
====source====
 +
This takes a directory path, pointing to the qml skins.
 +
* '''"NAVIT_SHAREDIR/gui/qml/skins" - Default qml skins directory (default)'''
 +
Example:
 +
<pre> <gui type="qml" enabled="yes" source="/home/netbook/src/navit/navit/gui/qml/skins">
 +
(Use the full path, not "~/")</pre>
 +
 
 +
====skin====
 +
This takes a string of text, with the name of the skin to use for the menu GUI. These are defined within the skins folder (see above).
 +
* '''"navit" - Default menu GUI skin (default)'''
 +
 
 +
====icon_src====
 +
This takes a directory path, pointing to the icons for the menu GUI
 +
* '''"NAVIT_SHAREDIR/xpm/" - Default menu GUI icons directory (default)'''
  
 
==Using it==
 
==Using it==
  
 
I can't give any advices on using this gui, cause it is very flexible by it's nature, so there could be a lot of variations and customizations on it, but there are exists some hardcoded things.  
 
I can't give any advices on using this gui, cause it is very flexible by it's nature, so there could be a lot of variations and customizations on it, but there are exists some hardcoded things.  
With LEFT click on map (or touchscreen tap) gui is usually switched on. This behavior could be controlled by two attributes:
+
With click on map (or touchscreen tap) gui is usually switched on. This behavior could be controlled by two attributes:
 
     * menu_on_map_click - controls whether menu should be called on map click or not
 
     * menu_on_map_click - controls whether menu should be called on map click or not
 
and
 
and
 
     * signal_on_map_click - controls whether signal should be sent on map click or usual click processing should be used
 
     * signal_on_map_click - controls whether signal should be sent on map click or usual click processing should be used
  
RIGHT click on map (or loooong tap on touch screen) turns on the gui with special point screen.
+
Depending on "lazy" attribute, menu will be reset to point page before switching to or not, but current point is always updated after click.
  
==Redesigning in==
+
==Redesigning it==
  
The gui qml skin is just a directory containing qml applcation of any kind of complexity (yes, you CAN add twitter client into gui, no  
+
The gui qml skin is just a directory containing qml application of any kind of complexity (yes, you CAN add twitter client into gui, no  
problem at all). Navit requires that qml app to contain two files:
+
problem at all). Navit requires that qml app must contain two files:
 
     * main.qml
 
     * main.qml
     * point.qml
+
     * command.js
  
'''main.qml''' will be instantiated when calling a gui for the first time (or every time when "lazy" set to "0") and '''point.qml''' used for a special point screen mentioned above. Every other aspect of gui structure and desing is controlled by you, but gui qml module provides some helper functions.
+
'''main.qml''' is used as a menu entry page.'''command.js''' is used to handle a OSD command. Every other aspect of gui structure and desigg is controlled by you, but gui qml module provides some helper functions.
  
 
==gui object==
 
==gui object==
Line 80: Line 159:
 
     * localeName *langName *ctryName - Name of POSIX locale and WIN32 language and country names (READ ONLY)
 
     * localeName *langName *ctryName - Name of POSIX locale and WIN32 language and country names (READ ONLY)
 
     * iconPath - Directory for icons (READ ONLY)
 
     * iconPath - Directory for icons (READ ONLY)
     * returnSource - Tree of visited pages (see below)
+
     * commandFunction - name of a command to execute, see commands section for details (READ ONLY)
  
 
gui object also have some slots:
 
gui object also have some slots:
    * setPage
 
 
     * backToMap
 
     * backToMap
     * backToPrevPage
+
     * pushPage(QString)
 +
    * popPage()
 +
    * lengthPage()
 +
 
 +
Those slots are related to 'page switch helper'.  backToMap switches between map and gui widget, obviously. The *Page() slots are more interesting - pushPage(QString) puts some string value into the stack and popPage() returns top string from the stach. lengthPage() return stack's size. This stack could be used for keeping page switching history, so you 'push' a page when you switch to it and 'pop' a page to know, where to get back.
 +
 
 +
==Proxy objects==
 +
The gui object above is a kind of a '''proxy object''' Navit is written in pure C and QML is based on Qt, so there are no direct way of exposing Navit's data to qml engine, so we have to use proxies between them. Generic proxy object is based on NGQProxy class
 +
<pre>
 +
class NGQProxy : public QObject {
 +
Q_OBJECT;
 +
 
 +
public:
 +
    NGQProxy(struct gui_priv* this_,QObject *parent) : QObject(parent);
 +
public slots:
 +
//Attribute read/write
 +
QString getAttr(const QString &attr_name);
 +
void setAttr(const QString &attr_name, const QString &attr_string);
 +
};
 +
</pre>
 +
 
 +
NGQProxy provides generic setAttr/getAttr functions, that are mediating between QML and Navit's attributes system. I have to metion specially here - setAttr will convert "true" and "false" in attr_string variable to "1" and "0". It's not a bug :-)
 +
 
 +
NGQProxy inherited by the following classes:
 +
 
 +
===NGQProxySearch===
  
All of those slots and returnSource property are related to 'page switch helper'.  The idea behind them is to encapsulate every dialog into different qml file and switch them programatically directly from qml. So you may define a button for maps and call gui.setPage("maps.qml") when it is clicked. Every setPage call modifies returnSource property, storing the history of your setPage calls, so when you done with your maps.qml from the example aboe, you could just call gui.backToPrevPage() in it (in maps.qml) and it will work like a back button. gui.backToMap() switch from gui to map, it's obvious. But what if you want to return to your starting point? You could use the following code:
+
Object of this class is injected into qml namespace as a '''search''' and provides access to the Navit's search API.
 
<pre>
 
<pre>
    gui.returnSource=""; gui.setPage("main.qml");
+
class NGQProxySearch : public NGQProxy {
 +
 
 +
Q_PROPERTY(QString countryName READ countryName WRITE setCountryName NOTIFY countryNameSignal);
 +
Q_PROPERTY(QString countryISO2 READ countryISO2 WRITE setCountryISO2 NOTIFY countryISO2Signal);
 +
Q_PROPERTY(QString townName READ townName WRITE setTownName NOTIFY townNameSignal);
 +
Q_PROPERTY(QString streetName READ streetName WRITE setStreetName NOTIFY streetNameSignal);
 +
 
 +
Q_PROPERTY(QString searchContext READ searchContext WRITE setSearchContext);
 +
 
 +
public slots:
 +
void setPointToResult();
 +
QString searchXml();
 +
};
 
</pre>
 
</pre>
  
in you qml application. Even more - you could use returnSource any way you like - for returning to the every odd page for exmaple or inserting some new pages into history on some even. You may also not use this functionality at all and implement everything right in the QML app.
+
To search something, we need to set a
 +
    * 'searchContext' property to one of the search targets: '''country''','''town''','''street''','''number'''
 +
    * put your query into corresponding *Name property
 +
    * call searchXML
 +
 
 +
the '''searchXML''' return search result in the following format
  
==Proxy objects==
+
<pre>
[[Category:Gui]]
+
    <search>
 +
        <item>
 +
            <id></id>
 +
            <name></name>
 +
            <icon></icon>
 +
        </item>
 +
        ....more items here...
 +
    </search>
 +
</pre>
 +
 
 +
So it can be easily used with XmlListModel. Search expected to be used in hierarchical way, that means that you should first select a country, then city, then street and, finally, house number. You may stop at any level you want, actually :) Search will work, if you start with some sub-level, without searching for upper levels, but will react much more slowly.
 +
 
 +
===NGQProxyGui===
 +
Object of this class is injected into qml namespace as a '''gui''' and described above.
 +
 
 +
===NGQProxyBookmarks===
 +
 
 +
Object of this class is injected into qml namespace as a '''bookmarks'''. This object provides access to the bookmark manager. It have following slots:
 +
    * getAttrList
 +
    * AddBookmark(name)
 +
    * Cut(name)
 +
    * Copy(name)
 +
    * Paste(name)
 +
    * Delete(name)
 +
    * setPoint(name)
 +
 
 +
and single property:
 +
    * currentPath
 +
It doesn't provides valid setAttr/getAttr functions! They will always fail.
 +
For AddBookmark/Cut/Copy/Page/Delete/setPoint you MUST specify full bookmark name, with path, but for Paste just a PATH, without name part, should be specified. AddBookmark uses coordinates from a current 'point' object (see below) and setPoint sets the current 'point' object to point in the bookmark. currentPath property used for traversing the bookmarks tree and positioning in it. getAttrList provides QML namespace with 'listModel' object of type NGQStandardItemModel (see below) for bookmarks list view.
 +
 
 +
===NGQProxyNavit===
 +
 
 +
Object of this class is injected into qml namespace as a '''navit'''. This object provides access to the global navit object.
 +
Slots are:
 +
    * quit - quits the Navit immediately
 +
    * setObjectByName(name,value) - sets the current values of various objects by their name (only 'layout' and 'vehicle' supported right now)
 +
    * setDestination/setPosition - sets the destination/position to the current point
 +
    * getAttrList - Proveds QML nameSpaces with 'listModel' object (see below) containing lists of different types of attributes ('layout' and 'vehicle' only at the moment)
 +
 
 +
 
 +
==The current point concept==
 +
 
 +
There are special object 'point' of type NGQPoint that represents a 'current point'. Current point is a point on map (with coordinates and may be with name and other attributes) which is used by other proxy objects. So you don't pass the coordinates or something to navit.setDestination or bookmarks.AddBookmark. You set current point object to their values and call a function, that processes it. The current point object is set in following cases:
 +
  * Click on map
 +
  * navit.getPosition/navit.getDestination call
 +
  * bookmarks.setPoint call
 +
  * point.setNewPoint call
 +
 
 +
Point could have a type:
 +
 
 +
<pre>
 +
    enum NGQPointTypes {MapPoint,Bookmark,Position,Destination,PointOfInterest};
 +
</pre>
 +
 
 +
which could be used for conditional rendering etc
 +
 
 +
Point object provides three properties:
 +
    * coordString - Formatted textual representation of point's coordinates.
 +
    * pointName - Name of a point, either specified during point creation/setting or calculated from map data.
 +
    * pointType - Name of point's type.
 +
 
 +
==The listModel==
 +
 
 +
In a few words - listModel is a way to represent list data to qml. It is a variation of QStandardItemModel, but with several new roles defined:
 +
 
 +
<pre>
 +
enum listRoles {ItemId=Qt::UserRole+1,ItemName=Qt::UserRole+2,ItemIcon=Qt::UserRole+3,ItemPath=Qt::UserRole+4};
 +
</pre>
 +
 
 +
the listModel is filled by getAttrList call andstored in global QML namespace. That also means, that you only can use a single list on a page :-)
 +
 
 +
==Commands==
 +
 
 +
Navit supports scriptable commands, usually found in OSD, but not limited to and those commands are another one way of user interaction with gui. Commands are usually defined in a form of a:
 +
<pre>
 +
    object.command(attribute=value,attribute=value,...,attribute=value)
 +
</pre>
 +
 
 +
so gui (our object) gets a call from navit to execute a command with some parameters. In qml gui we delegate execution function to command.qml which should read the current command from a gui.commandFunction and execute it somehow. It is designed to be very flexible, so command to this gui should be in form of:
 +
<pre>
 +
    gui.command(attribute=value)
 +
</pre>
 +
 
 +
The internal callback handler reads the function name and stores it in the gui.commandFunction property, so adding a new command does not requires a c++ coding.
 +
 
 +
[[Category:GUI]]

Latest revision as of 00:45, 25 December 2014

Qml point 20100404.png

The QML GIU is designed to be a modern and flexible replacement of internal gui. It is based on Qt's modelling language UI framework, therefore it could be run on any Qt platform, including mobile platforms with touchscreens etc

Building it[edit]

Install from source or from distribution packages?[edit]

The following instructions are for installing the Qt libraries from source. On Linux, it is usually easier to install Qt from the package manager instead. See Dependencies for the packages to install.

Download Qt libraries[edit]

So you have decided to install from source? Fine.

First of all - you will need the Qt 4 libraries and headers installed. Navit needs Qt 4.7 or 4.8. This can be downloaded from:

Configure and build Qt[edit]

The following example instructions are for configuring and building Qt on Ubuntu 10.04. The procedure for your particular device may vary. Note: The "4.8.0" has to be adjusted depending on the version you install.

  • Unzip the archive into a folder of your choice. The following example has unzipped to ~/src.
  • cd to that folder in a terminal
cd ~/src/qt-everywhere-opensource-src-4.8.0/
  • Configure Qt
./configure
  • During configure:
    • Asks what type to use: Commercial or Open Source. Select Open Source ('o')
    • Asks to accept licence: Chose 'yes'
  • Make Qt (this may take a long time: ~5hrs on a netbook)
 make 
  • Install Qt
 sudo make install 

Add Qt to your environment[edit]

Issue the following commands at a terminal to ensure that Navit can find Qt:

PATH=/usr/local/Trolltech/Qt-4.8.0/bin:$PATH
export PATH
export PKG_CONFIG_PATH=/usr/local/Trolltech/Qt-4.8.0/lib/pkgconfig

Build Navit[edit]

Once you have prepared your Qt environment, it's time to build Navit. If Qt is installed correctly, the CMake build should pick it up and enable Qt support automatically.

At the script output you should have the following lines:

Enabled   qt_qpainter ( Qt libraries found )
[...]
Enabled   qml ( Qt Declarative found )

Both qt_qpainter and qml are required to successfully run the qml GUI. If those lines are present, do your usual make && make install/dpkg-buildpackage/your-platform-specific thing.

Configuring Navit.xml[edit]

Right now QML gui is compatible only with qt_qpainter graphics type. I hope there will be more graphics types in the future, but right now you have to switch to qt_qpainter:

    <graphics type="qt_qpainter"/>

And enable qml gui:

    <gui type="qml" enabled="yes"/>

All other gui modules MUST be disabled by setting

    enabled="no"

in their configuration stanzas.

Configuring QML GUI[edit]

QML gui doesn't require any special configuration, but it can be tuned. It supports the following parameters, which go inside the <gui> tag (default values in bold). You can have as many of the parameters as you want in the <gui> tag:

fullscreen[edit]

  • "0" - Start Navit in windowed mode (default)
  • "1" - Start Navit in fullscreen mode

Example:

 <gui type="qml" enabled="yes" fullscreen="1">

menu_on_map_click[edit]

  • "0" - Menu GUI is switched by a command (not yet implemented)
  • "1" - Single click on map will bring up the menu GUI (default)

Example:

 <gui type="qml" enabled="yes" menu_on_map_click="1">
(A bit useless since this is the default anyway...)

signal_on_map_click[edit]

  • "0" - When single clicking on the map, processing to be controlled by menu_on_map_click (default)
  • "1" - When single clicking on the map, send a DBus signal

radius[edit]

This takes a number, which is the distance in kilometres which POI search will restrict to

  • "10" - Default POI search radius, in kilometres (default)

Example:

 <gui type="qml" enabled="yes" radius="5">
(Restrict POI search to a 5km radius)

pitch[edit]

This takes a number, which is the angle of the 3D view in degrees with which Navit should start when in 3D mode.

  • "20" - Default 3D pitch, in degrees (default)

lazy[edit]

  • "0" - When menu GUI is called (such as when single-clicking on the map), always show the main menu page
  • "1" - When menu GUI is called (such as when single-clicking on the map), show the menu page which was last used (i.e. remember menu page states between calls) (default)

Example:

 <gui type="qml" enabled="yes" lazy="0">

width/height[edit]

This takes a number, which is the desired width/height of the GUI window, in pixels

  • width=800 - Default width of GUI window, in pixels (default)
  • height=600 - Default height of GUI window, in pixels (default)

source[edit]

This takes a directory path, pointing to the qml skins.

  • "NAVIT_SHAREDIR/gui/qml/skins" - Default qml skins directory (default)

Example:

 <gui type="qml" enabled="yes" source="/home/netbook/src/navit/navit/gui/qml/skins">
(Use the full path, not "~/")

skin[edit]

This takes a string of text, with the name of the skin to use for the menu GUI. These are defined within the skins folder (see above).

  • "navit" - Default menu GUI skin (default)

icon_src[edit]

This takes a directory path, pointing to the icons for the menu GUI

  • "NAVIT_SHAREDIR/xpm/" - Default menu GUI icons directory (default)

Using it[edit]

I can't give any advices on using this gui, cause it is very flexible by it's nature, so there could be a lot of variations and customizations on it, but there are exists some hardcoded things. With click on map (or touchscreen tap) gui is usually switched on. This behavior could be controlled by two attributes:

   * menu_on_map_click - controls whether menu should be called on map click or not

and

   * signal_on_map_click - controls whether signal should be sent on map click or usual click processing should be used

Depending on "lazy" attribute, menu will be reset to point page before switching to or not, but current point is always updated after click.

Redesigning it[edit]

The gui qml skin is just a directory containing qml application of any kind of complexity (yes, you CAN add twitter client into gui, no problem at all). Navit requires that qml app must contain two files:

   * main.qml
   * command.js

main.qml is used as a menu entry page.command.js is used to handle a OSD command. Every other aspect of gui structure and desigg is controlled by you, but gui qml module provides some helper functions.

gui object[edit]

Gui qml module injects a 'gui' object into global qml namespace. This object contains following properties:

   * width - current width of gui's window
   * height - current height of gui's window
   * localeName *langName *ctryName - Name of POSIX locale and WIN32 language and country names (READ ONLY)
   * iconPath - Directory for icons (READ ONLY)
   * commandFunction - name of a command to execute, see commands section for details (READ ONLY)

gui object also have some slots:

   * backToMap
   * pushPage(QString)
   * popPage()
   * lengthPage()

Those slots are related to 'page switch helper'. backToMap switches between map and gui widget, obviously. The *Page() slots are more interesting - pushPage(QString) puts some string value into the stack and popPage() returns top string from the stach. lengthPage() return stack's size. This stack could be used for keeping page switching history, so you 'push' a page when you switch to it and 'pop' a page to know, where to get back.

Proxy objects[edit]

The gui object above is a kind of a proxy object Navit is written in pure C and QML is based on Qt, so there are no direct way of exposing Navit's data to qml engine, so we have to use proxies between them. Generic proxy object is based on NGQProxy class

class NGQProxy : public QObject {
	Q_OBJECT;

public:
    NGQProxy(struct gui_priv* this_,QObject *parent) : QObject(parent);
public slots:
	//Attribute read/write
	QString getAttr(const QString &attr_name);
	void setAttr(const QString &attr_name, const QString &attr_string);
};

NGQProxy provides generic setAttr/getAttr functions, that are mediating between QML and Navit's attributes system. I have to metion specially here - setAttr will convert "true" and "false" in attr_string variable to "1" and "0". It's not a bug :-)

NGQProxy inherited by the following classes:

NGQProxySearch[edit]

Object of this class is injected into qml namespace as a search and provides access to the Navit's search API.

class NGQProxySearch : public NGQProxy {

	Q_PROPERTY(QString countryName READ countryName WRITE setCountryName NOTIFY countryNameSignal);
	Q_PROPERTY(QString countryISO2 READ countryISO2 WRITE setCountryISO2 NOTIFY countryISO2Signal);
	Q_PROPERTY(QString townName READ townName WRITE setTownName NOTIFY townNameSignal);
	Q_PROPERTY(QString streetName READ streetName WRITE setStreetName NOTIFY streetNameSignal);

	Q_PROPERTY(QString searchContext READ searchContext WRITE setSearchContext);

public slots:
	void setPointToResult();
	QString searchXml();
};

To search something, we need to set a

   * 'searchContext' property to one of the search targets: country,town,street,number
   * put your query into corresponding *Name property
   * call searchXML

the searchXML return search result in the following format

    <search>
        <item>
            <id></id>
            <name></name>
            <icon></icon>
        </item>
        ....more items here...
    </search>

So it can be easily used with XmlListModel. Search expected to be used in hierarchical way, that means that you should first select a country, then city, then street and, finally, house number. You may stop at any level you want, actually :) Search will work, if you start with some sub-level, without searching for upper levels, but will react much more slowly.

NGQProxyGui[edit]

Object of this class is injected into qml namespace as a gui and described above.

NGQProxyBookmarks[edit]

Object of this class is injected into qml namespace as a bookmarks. This object provides access to the bookmark manager. It have following slots:

   * getAttrList
   * AddBookmark(name)
   * Cut(name)
   * Copy(name)
   * Paste(name)
   * Delete(name)
   * setPoint(name)

and single property:

   * currentPath

It doesn't provides valid setAttr/getAttr functions! They will always fail. For AddBookmark/Cut/Copy/Page/Delete/setPoint you MUST specify full bookmark name, with path, but for Paste just a PATH, without name part, should be specified. AddBookmark uses coordinates from a current 'point' object (see below) and setPoint sets the current 'point' object to point in the bookmark. currentPath property used for traversing the bookmarks tree and positioning in it. getAttrList provides QML namespace with 'listModel' object of type NGQStandardItemModel (see below) for bookmarks list view.

NGQProxyNavit[edit]

Object of this class is injected into qml namespace as a navit. This object provides access to the global navit object. Slots are:

   * quit - quits the Navit immediately
   * setObjectByName(name,value) - sets the current values of various objects by their name (only 'layout' and 'vehicle' supported right now)
   * setDestination/setPosition - sets the destination/position to the current point
   * getAttrList - Proveds QML nameSpaces with 'listModel' object (see below) containing lists of different types of attributes ('layout' and 'vehicle' only at the moment)


The current point concept[edit]

There are special object 'point' of type NGQPoint that represents a 'current point'. Current point is a point on map (with coordinates and may be with name and other attributes) which is used by other proxy objects. So you don't pass the coordinates or something to navit.setDestination or bookmarks.AddBookmark. You set current point object to their values and call a function, that processes it. The current point object is set in following cases:

  * Click on map
  * navit.getPosition/navit.getDestination call
  * bookmarks.setPoint call
  * point.setNewPoint call

Point could have a type:

    enum NGQPointTypes {MapPoint,Bookmark,Position,Destination,PointOfInterest};

which could be used for conditional rendering etc

Point object provides three properties:

   * coordString - Formatted textual representation of point's coordinates.
   * pointName - Name of a point, either specified during point creation/setting or calculated from map data.
   * pointType - Name of point's type.

The listModel[edit]

In a few words - listModel is a way to represent list data to qml. It is a variation of QStandardItemModel, but with several new roles defined:

	enum listRoles {ItemId=Qt::UserRole+1,ItemName=Qt::UserRole+2,ItemIcon=Qt::UserRole+3,ItemPath=Qt::UserRole+4};

the listModel is filled by getAttrList call andstored in global QML namespace. That also means, that you only can use a single list on a page :-)

Commands[edit]

Navit supports scriptable commands, usually found in OSD, but not limited to and those commands are another one way of user interaction with gui. Commands are usually defined in a form of a:

    object.command(attribute=value,attribute=value,...,attribute=value)

so gui (our object) gets a call from navit to execute a command with some parameters. In qml gui we delegate execution function to command.qml which should read the current command from a gui.commandFunction and execute it somehow. It is designed to be very flexible, so command to this gui should be in form of:

    gui.command(attribute=value)

The internal callback handler reads the function name and stores it in the gui.commandFunction property, so adding a new command does not requires a c++ coding.