Commit 3fb84ea7 authored by Holger Kaelberer's avatar Holger Kaelberer Committed by Bruno Coudoin
Browse files

core: add initial version of doxygen/kapidox documentation

Documents the most important files from core subdeviding logically
into "Infrastructure" (like ApplicationSettings, etc.) and "QML
Components" (e.g. GCText, etc).

Basic ideas while documenting:

- For .cpp files exposed to the QML layer document the Q_PROPERTY
  definitions only (not also all getter and setter), plus internal
  methods where considered important. The rest has been marked
  INTERNAL_DOCS.

- For QML components defined in .qml documents all properties that are
  part of the public interface (not the ones used internally only). All
  properties that have been considered purely internal have been marked
  INTERNAL_DOCS.

- Restructured all documented files slightly to group public
  documented members together, preferably at the top of the class
  defininition.

Mainpage.dox defines the "Main page" plus the

Build by running kgenapidox at the top level directory.

ToDos/Issues:

- How to include core.js to the documented files?
- How to eliminate the doxyqml error for GCSingletonFontLoader?
- Some missing .qml files in core/.
- Refine public interface if necessary: Are additional properties
- Shall we suppress to generate files for all activities?
- Need to address something from doxygen-warnings.log?
parent 2bd4fd14
PROJECT_NAME = GCompris-qt
DISTRIBUTE_GROUP_DOC = yes
FILTER_PATTERNS = *.qml=doxyqml
EXTENSION_MAPPING = qml=C++ js=C++
/**
@mainpage GCompris-qt Core Documentation
The GCompris core comprises different classes and QML components, that can
be used by activities for their purposes. The core can roughly be
subdivided into
<ol>
<li>
@ref infrastructure, that consists of some fundamental source code
infrastructure needed by the bare GCompris application to run and
</li>
<li>
@ref components that define some common building blocks for activities
and thus assure a consistent integration into the GCompris ecosystem.
</li>
</ol>
Accordingly, activity developers should first have a look at the
@ref components section to get an overview of the activity interface they
have to implement.
Most of the classes from the @ref infrastructure section are not of immediate
use for activity developers, unless they want to contribute/extend core
functionalities. One exception is the ApplicationInfo singleton
that contains some accessor methods to the native layer, that are often of
use for concrete activitites.
*/
/**
@defgroup infrastructure Core Infrastructure
This section contains all objects that implement internal core functions
needed by the bare GCompris application to run.
Among the more important classes are the following:
<ul>
<li>
The ApplicationSettings singleton maintains the persistent settings of
GCompris.
</li>
<li>
ApplicationInfo is kind of a general purpose container for helper functions
often accessing native platform properties that are needed in many places
of GCompris.
</li>
</ul>
@endgroup
*/
/**
@defgroup components Core QML Components
This section contains all core QML components, that encapsulate common
behaviour and can be used by activities in order to integrate well into the
GCompris ecosystem.
Each activity has to provide meta information about itself by implementing the
ActivityInfo template and derive from ActivityBase as a container for its
QML scene.
Each activity @em must add a navigation Bar to its viewport. Activities that
support sublevels should use a Score element. The Bonus component can be used
for audio feedback upon winning/loosing. If an activity uses per-activity
configuration it should use DialogActivityConfig.
For audio playback the GCAudio wrapper should be used, and GCText's purpose is
to unify Text handling in GCompris.
Besides these, there are more components that provide controls or
styles for GCompris.
Cf. Template.qml for a skeleton that can also be used as a starting point for
developing new activities.
Last but not least have a look at the existing activities to learn by example.
@endgroup
*/
......@@ -24,6 +24,23 @@ import GCompris 1.0
import "qrc:/gcompris/src/core/core.js" as Core
import QtGraphicalEffects 1.0
/**
* GCompris' top level menu screen.
*
* Displays a grid of available activities divided subdivided in activity
* categories/sections.
*
* The visibility of the section row is toggled by the setting
* ApplicationSettings.sectionVisible.
*
* The list of available activities depends on the following settings:
*
* * ApplicationSettings.showLockedActivities
* * ApplicationSettings.filterLevelMin
* * ApplicationSettings.filterLevelMax
*
* @inherit QtQuick.Item
*/
ActivityBase {
id: menuActivity
focus: true
......@@ -43,6 +60,7 @@ ActivityBase {
onDisplayDialog: pageView.push(dialog)
// @cond INTERNAL_DOCS
property string url: "qrc:/gcompris/src/activities/menu/resource/"
property variant sections: [
{
......@@ -83,6 +101,7 @@ ActivityBase {
},
]
property string currentTag: sections[0].tag
/// @endcond
pageComponent: Image {
id: background
......
......@@ -22,23 +22,133 @@ import QtQuick 2.2
import GCompris 1.0
import "qrc:/gcompris/src/core/core.js" as Core
/**
* The base QML component for activities in GCompris.
* @ingroup components
*
* Each activity should be derived from this component. It is responsible for
*
* * basic common key handling,
* * unified audio handling,
* * screen switching dynamics (from/to Menu/DialogHelp/etc.)
*
* The following common keys are handled so far:
*
* * @c Ctrl+q: Exit the application.
* * @c Ctrl+b: Toggle the bar.
* * @c Ctrl+f: Toggle fullscreen.
* * @c Ctrl+m: Toggle audio effects.
* * @c Ctrl+w: Exit the current activity and return to the menu.
* * @c Ctrl+p: Make a screenshot.
* * @c Back: Return to the home screen (corresponds to the 'Back' button on
* Android).
*
* Cf. Template.qml for a sample skeleton activity.
*
* Cf.
* [the wiki](http://gcompris.net/wiki/Qt_Quick_development_process#Adding_a_new_activity)
* for further information about creating a new activity.
*
* @inherit QtQuick.Item
*/
Item {
id: page
/**
* type:Item
* Parent object.
*/
property Item main: parent;
/**
* type:Component
* The top-level component containing the visible viewport of an activity.
*
* Put all you want to present the user into this container. Mostly
* implemented using a Rectangle or Image component, itself
* containing further graphical elements. You are pretty free of doing
* whatever you want inside this component.
*
* Also common elements as Bar, Score, DialogHelp, etc. should be placed
* inside this element.
*/
property Component pageComponent
/**
* type:QtObject
* Reference to the menu activity.
*
* Populated automatically during activity-loading.
*/
property QtObject menu
/**
* type:QtObject
* Reference to the ActivityInfo object of the activity.
*
* Populated automatically during activity-loading.
*/
property QtObject activityInfo
// The global audio item, append to it to play your voices after the
// intro music
/**
* type:GCAudio
* The global audio item for voices.
*
* Because of problems synchronizing multiple Audio objects between
* global/menu/main and individual activities, activities should refrain
* from implementing additional Audio elements.
*
* Instead append to this global object to play your voices after the
* intro music.
* @sa GCAudio audioEffects
*/
property GCAudio audioVoices
// The global audio effect, use it to play sound effects
/**
* type:GCAudio
* The global audio item for audio effects.
*
* Append to it to play your effects.
* @sa GCAudio audioEffects
*/
property GCAudio audioEffects
/* FIXME: What is this? Still needed? */
property bool isLocked: true
/**
* Emitted when the user wants to return to the Home/Menu screen.
*/
signal home
/**
* Emitted every time the activity has been started.
*
* Initialize your activity upon this signal.
*/
signal start
/* FIXME: is this used? */
signal pause
/* FIXME: is this used? */
signal play
/**
* Emitted when the activity is about to stop
*
* Shutdown whatever you need to upon this signal.
*/
signal stop
/**
* Emitted when dialog @p dialog should be shown
*
* Emit this signal when you want to show another dialog, e.g. on
* Bar.onHelpClicked
*
* @param dialog Dialog to show.
*/
signal displayDialog(Item dialog)
onHome: menu ? menu.home() : ""
......
......@@ -23,27 +23,100 @@
#include <qqml.h>
/**
* @class ActivityInfo
* @short A QML component holding meta information about an activity.
* @ingroup components
*
* Each GCompris activity has to provide some meta data about itself in form
* of an ActivityInfo definition. This data will be used to register it in the
* ActivityInfoTree, and populate the full screen help dialog.
*
* @sa DialogHelp
*/
class ActivityInfo : public QObject
{
Q_OBJECT
/**
* Name of the main activity QML file.
*
* Example: "activity/Activity.qml"
*/
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
/* FIXME: what's this? */
Q_PROPERTY(QString dir READ dir WRITE setDir NOTIFY dirChanged)
/**
* Section(s) this activity belongs to.
*
* An activity can belong to one or multiple activity sections
* (seperated by whitespace) out of:
* computer, discovery, experiment, fun, math, puzzle,
* reading, strategy.
*/
Q_PROPERTY(QString section READ section WRITE setSection NOTIFY sectionChanged)
/**
* Difficulty of the activity.
*
* A difficulty level from 1 (easiest) to 6 (most difficult).
*/
Q_PROPERTY(int difficulty READ difficulty WRITE setDifficulty NOTIFY difficultyChanged)
/**
* Relative path to the icon of the activity.
*
* Example: "activity/activity.svg"
*/
Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged)
/**
* Author of the activity.
*/
Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
/**
* Whether the activity is part of the demo version of GCompris.
*/
Q_PROPERTY(bool demo READ demo WRITE setDemo NOTIFY demoChanged)
/**
* Title of the activity.
*/
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
/**
* Description of the activity.
*/
Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged)
/**
* Goal that this activity wants to achieve.
*/
Q_PROPERTY(QString goal READ goal WRITE setGoal NOTIFY goalChanged)
/**
* Prerequisite for using this activity.
*/
Q_PROPERTY(QString prerequisite READ prerequisite WRITE setPrerequisite NOTIFY prerequisiteChanged)
/**
* Manual describing the activity's usage.
*/
Q_PROPERTY(QString manual READ manual WRITE setManual NOTIFY manualChanged)
/**
* Credits to third parties.
*/
Q_PROPERTY(QString credit READ credit WRITE setCredit NOTIFY creditChanged)
Q_PROPERTY(bool favorite READ favorite WRITE setFavorite NOTIFY favoriteChanged)
public:
/// @cond INTERNAL_DOCS
explicit ActivityInfo(QObject *parent = 0);
QString name() const;
......@@ -93,7 +166,8 @@ signals:
void manualChanged();
void creditChanged();
void favoriteChanged();
/// @endcond
private:
QString m_name;
QString m_type;
......
......@@ -36,7 +36,7 @@
**
** $QT_END_LICENSE$
**
****************************************************************************/
***************************************************************************/
#include "ApplicationInfo.h"
......@@ -148,10 +148,6 @@ QString ApplicationInfo::getAudioFilePath(const QString &file)
return getResourceDataPath() + '/' + filename;
}
// Given a file name, if it contains $LOCALE it is replaced by
// the current locale like 'en' while in the English locale.
// e.g. qrc:/foo/bar_$LOCALE.json => qrc:/foo/bar_en.json
// FIXME should check long locale first
QString ApplicationInfo::getLocaleFilePath(const QString &file)
{
QString localeShortName = localeShort();
......
......@@ -36,7 +36,7 @@
**
** $QT_END_LICENSE$
**
****************************************************************************/
***************************************************************************/
#ifndef APPLICATIONINFO_H
#define APPLICATIONINFO_H
......@@ -50,45 +50,171 @@
class QQuickWindow;
/**
* @class ApplicationInfo
* @short A general purpose singleton that exposes miscellaneous native
* functions to the QML layer.
* @ingroup infrastructure
*/
class ApplicationInfo : public QObject
{
Q_OBJECT
Q_ENUMS(Platform)
/**
* Width of the application viewport.
*/
Q_PROPERTY(int applicationWidth READ applicationWidth WRITE setApplicationWidth NOTIFY applicationWidthChanged)
Q_PROPERTY(Platform platform READ platform CONSTANT)
Q_PROPERTY(bool isMobile READ isMobile CONSTANT)
Q_PROPERTY(bool hasShader READ hasShader CONSTANT)
Q_PROPERTY(bool isPortraitMode READ isPortraitMode WRITE setIsPortraitMode NOTIFY portraitModeChanged)
/**
* Platform the application is currently running on.
*/
Q_PROPERTY(Platform platform READ platform CONSTANT)
/**
* Whether the application is currently running on a mobile platform.
*
* Mobile platforms are Android, Ios (not supported yet),
* Blackberry (not supported)
*/
Q_PROPERTY(bool isMobile READ isMobile CONSTANT)
/**
* Whether the current platform supports fragment shaders.
*
* This flag is used in some core modules to selectively deactivate
* particle effects which cause crashes on some Android devices.
*
* cf. https://bugreports.qt.io/browse/QTBUG-44194
*
* For now always set to false, to prevent crashes.
*/
Q_PROPERTY(bool hasShader READ hasShader CONSTANT)
/**
* Whether currently in portrait mode, on mobile platforms.
*
* Based on viewport geometry.
*/
Q_PROPERTY(bool isPortraitMode READ isPortraitMode WRITE setIsPortraitMode NOTIFY portraitModeChanged)
/**
* Ratio factor used for scaling of sizes on high-dpi devices.
*
* Must be used by activities as a scaling factor to all pixel values.
*/
Q_PROPERTY(qreal ratio READ ratio NOTIFY ratioChanged)
Q_PROPERTY(qreal fontRatio READ fontRatio NOTIFY fontRatioChanged)
/**
* Ratio factor used for font scaling.
*
* On some low-dpi Android devices with high res (e.g. Galaxy Tab 4) the
* fonts in Text-like elements appear too small with respect to the other
* graphics -- also if we are using font.pointSize.
*
* For these cases we calculate a fontRatio in ApplicationInfo that takes
* dpi information into account, as proposed on
* http://doc.qt.io/qt-5/scalability.html#calculating-scaling-ratio
*
* GCText applies this factor automatically on its new fontSize property.
*/
Q_PROPERTY(qreal fontRatio READ fontRatio NOTIFY fontRatioChanged)
// FIXME: still needed?
Q_PROPERTY(qreal hMargin READ hMargin NOTIFY hMarginChanged)
// FIXME: still needed?
Q_PROPERTY(qreal sliderHandleWidth READ sliderHandleWidth NOTIFY ratioChanged)
// FIXME: still needed?
Q_PROPERTY(qreal sliderHandleHeight READ sliderHandleHeight NOTIFY ratioChanged)
// FIXME: still needed?
Q_PROPERTY(qreal sliderGapWidth READ sliderGapWidth NOTIFY ratioChanged)
Q_PROPERTY(QString localeShort READ localeShort)
Q_PROPERTY(QString GCVersion READ GCVersion CONSTANT)
Q_PROPERTY(QString QTVersion READ QTVersion CONSTANT)
Q_PROPERTY(QString CompressedAudio READ CompressedAudio CONSTANT)
/**
* Short (2-letter) locale string of the currently active language.
*/
Q_PROPERTY(QString localeShort READ localeShort)
/**
* GCompris version string (compile time).
*/
Q_PROPERTY(QString GCVersion READ GCVersion CONSTANT)
/**
* Qt version string (runtime).
*/
Q_PROPERTY(QString QTVersion READ QTVersion CONSTANT)
/**
* Audio codec used for voices resources.
*
* This is determined at compile time (ogg for free platforms, aac on
* MacOSX and IOS).
*/
Q_PROPERTY(QString CompressedAudio READ CompressedAudio CONSTANT)
public:
/**
* Known host platforms.
*/
enum Platform {
Linux,
Windows,
MacOSX,
Android,
Ios,
Blackberry
Linux, /**< Linux (except Android) */
Windows, /**< Windows */
MacOSX, /**< MacOSX */
Android, /**< Android */
Ios, /**< IOS (not supported) */
Blackberry /**< Blackberry (not supported) */
};
explicit ApplicationInfo(QObject *parent = 0);
~ApplicationInfo();
/**
* Registers singleton in the QML engine.
*
* It is not recommended to create a singleton of Qml Singleton registered
* object but we could not found a better way to let us access ApplicationInfo
* on the C++ side. All our test shows that it works.
*/
static void init();
// It is not recommended to create a singleton of Qml Singleton registered
// object but we could not found a better way to let us access ApplicationInfo
// on the C++ side. All our test shows that it works.
/**
* Returns an absolute and platform independent path to the passed @p file
*
* @param file A relative filename.
* @returns Absolute path to the file.
*/
static QString getFilePath(const QString &file);
/**
* Returns the short locale name for the passed @p locale.
*
* Handles also 'system' (GC_DEFAULT_LOCALE) correctly which resolves to
* QLocale::system().name().
*
* @param locale A locale string of the form \<language\>_\<country\>
* @returns A short locale string of the form \<language\>
*/
static QString localeShort(const QString &locale) {
QString _locale = locale;
if(_locale == GC_DEFAULT_LOCALE) {
_locale = QLocale::system().name();
}
// Can't use left(2) because of Asturian where there are 3 chars
return _locale.left(_locale.indexOf('_'));
}
/**
* Returns a locale string that can be used in voices filenames.
*
* @param locale A locale string of the form \<language\>_\<country\>
* @returns A locale string as used in voices filenames.
*/
Q_INVOKABLE QString getVoicesLocale(const QString &locale);
/// @cond INTERNAL_DOCS
static ApplicationInfo *getInstance() {
if(!m_instance) {
m_instance = new ApplicationInfo();
......@@ -97,43 +223,22 @@ public:
}
static QObject *systeminfoProvider(QQmlEngine *engine,
QJSEngine *scriptEngine);
static void setWindow(QQuickWindow *window);
static QString getFilePath(const QString &file);
explicit ApplicationInfo(QObject *parent = 0);
~ApplicationInfo();
int applicationWidth() const { return m_applicationWidth; }
void setApplicationWidth(const int newWidth);
Platform platform() const { return m_platform; }
bool isPortraitMode() const { return m_isPortraitMode; }
void setIsPortraitMode(const bool newMode);
bool isMobile() const { return m_isMobile; }
// On some platforms shader crashes, let's put them back when we
// know how to detect the platforms that support it
// https://bugreports.qt.io/browse/QTBUG-44194
bool hasShader() const { return false; }
qreal hMargin() const { return m_hMargin; }
qreal ratio() const { return m_ratio; }
qreal fontRatio() const { return m_fontRatio; }
qreal sliderHandleHeight() { return m_sliderHandleHeight; }
qreal sliderGapWidth() { return m_sliderGapWidth; }
qreal sliderHandleWidth() { return m_sliderHandleWidth; }