|
|
HybridOS Specification 01-C
|
|
|
Topic: HybridOS Foundation Class Library
|
|
|
Author: Vincent Wei
|
|
|
Category: App Framework
|
|
|
Date: November 2018
|
|
|
Status: Proposal
|
|
|
|
|
|
*Copyright Notice*
|
|
|
|
|
|
Copyright (C) 2018, 2019 [FMSoft Technologies]
|
|
|
All Rights Reserved.
|
|
|
|
|
|
## Introduction
|
|
|
|
|
|
HFCL (HybridOS Foundation Class Library) is a C++ class library. It is derived
|
|
|
from mGNGUX, a C++ library for MiniGUI. mGNGUX had been used as the foundation
|
|
|
of two MMI (man-machine interface) solutions for feature phones.
|
|
|
|
|
|
mGNGUX introduced a new MMI framework for feature phone, and borrowed some
|
|
|
concepts from other operating system (especially Android). mGNGUX also
|
|
|
provided a new set of controls/widgets in C++ classes. These classes construct
|
|
|
the view hierarchy of mGNGUX app framework.
|
|
|
|
|
|
The most important feature of mGNGUX is it introduced a new way to define
|
|
|
the UI elements, including resource, views, and menus. And we can easily define
|
|
|
the maps of views to C++ class member variables. Indeed, the UI definition files
|
|
|
are C++ source files, but we wrote them in pre-defined C++ macros.
|
|
|
|
|
|
However, mGNGUX still uses the traditional widget-based programming mechanism,
|
|
|
which does not provide a good solution for decoupling relationship among
|
|
|
data, interaction, and rendering.
|
|
|
|
|
|
Therefore, as described in [HybridOS Architecture], we use [HybrdOS View Markup
|
|
|
Language] and [hiWebKit] to support HVML and render the activities.
|
|
|
|
|
|
HFCL implements the view types for HVML and help the developer to create and
|
|
|
manage resource, activities, and services for HybrdiOS apps. The key features
|
|
|
of HFCL are follow:
|
|
|
|
|
|
* It acts as the framework for the C++ edition of your HybridOS app.
|
|
|
|
|
|
* It manages the resource (images, fonts, l10n text, CSS definitions,
|
|
|
and others assets) for your app. On device, these assets are loaded from disk
|
|
|
or embedded directly into the program image. HFCL provides a universal
|
|
|
way to manage the assets.
|
|
|
|
|
|
* It manages the activites and the services of your app. You can launch
|
|
|
an activity and pass an intent to it.
|
|
|
|
|
|
* It provides a complete set of views which is conformed HVML specification.
|
|
|
|
|
|
* It provides the standard DOM interfaces for your app to manipulate the DOM
|
|
|
tree, including the nodes, the content, the style, and the attributes of them.
|
|
|
|
|
|
* It is the foundation of Hybrid App Engine.
|
|
|
|
|
|
## Resource Assets
|
|
|
|
|
|
We treat HVML files, CSS files, JavaScript files, images, and l10n text are
|
|
|
all resource assets of a HybridOS apps.
|
|
|
|
|
|
Unlike web browser, for an app running in a device or client, the assets
|
|
|
generally stored locally, either on the filesystem or embedded in the app
|
|
|
program image.
|
|
|
|
|
|
HybridOS provides an easy and magic way for developer to define the assets
|
|
|
and bind the assets with your C++ code.
|
|
|
|
|
|
Specifically, HFCL uses pre-defined C++ macros to define the resource assets.
|
|
|
For our first sample, the main asset file will look like:
|
|
|
|
|
|
begin_app(firstSample)
|
|
|
begin_assets()
|
|
|
image(defAvatar, "file:///assets/image/def-avatar.png")
|
|
|
css(default, "file:///assets/css/default.css"
|
|
|
activity(userList, "file:///assets/hvml/userlist.hvml")
|
|
|
activity(userInfo, "file:///assets/hvml/userInfo.hvml")
|
|
|
l10n(en, "file:///assets/message/en.mo")
|
|
|
l10n(zh_CN, "file:///assets/message/zh_CN.mo")
|
|
|
l10n(zh_TW, "file:///assets/message/zh_TW.mo")
|
|
|
end_assets
|
|
|
end_app(en, userList)
|
|
|
|
|
|
### L10N of Text
|
|
|
|
|
|
For the L10N (localization) text, HFCL provides two ways:
|
|
|
|
|
|
1. Using .mo files of GNU gettext.
|
|
|
1. Using identifiers instead of text as GNU `gettext` does.
|
|
|
|
|
|
The interpreter `hfclify` can generate the C++ L10N translation
|
|
|
source files for the app according to the L10N translation file specified
|
|
|
in the assets section of the app.
|
|
|
|
|
|
The identifiers referred as `STRID_TITLE` or `STRID_COPYING` will be
|
|
|
defined as C++ macros, and the l10n text table can be zipped by
|
|
|
using `zlib`.
|
|
|
|
|
|
### Assets Management
|
|
|
|
|
|
Not like HVML apps, the link of an asset (e.g., an image file) defined in
|
|
|
a HFCL app is handled as a reference key first. We can integrate the assets
|
|
|
data into the executable image of your app. We call them as in-core resource.
|
|
|
If HFCL could not load a specific asset from the in-core resource, it will
|
|
|
try to load if from the URL specified in the `begin_assets` section.
|
|
|
|
|
|
In this way, HFCL will provide a maximal flexibility for the app developers.
|
|
|
|
|
|
## Activity and Intent
|
|
|
|
|
|
## Customized View
|
|
|
|
|
|
## Service
|
|
|
|
|
|
## Components of HFCL
|
|
|
|
|
|
The components of HFCL are classified into the folllowing categories:
|
|
|
|
|
|
1. Activity management
|
|
|
* Resource management
|
|
|
* Define customized HVML view types
|
|
|
* Activity and intent
|
|
|
* Animation and transition
|
|
|
|
|
|
1. Service management
|
|
|
* WebSocket responder
|
|
|
* HTTP responder
|
|
|
* MQTT service provider
|
|
|
* ...
|
|
|
|
|
|
1. System classes
|
|
|
* hiBus event and task management
|
|
|
* SQLite queries
|
|
|
* JSON data
|
|
|
* Async task management
|
|
|
|
|
|
------
|
|
|
|
|
|
_The below words are deprecated..._
|
|
|
|
|
|
For our user list activity, the asset code will look like:
|
|
|
|
|
|
begin_activity(userList, ActivityUserList)
|
|
|
def_name(thePanel)
|
|
|
def_name(theHeader)
|
|
|
def_name(theList)
|
|
|
def_name(theFooter)
|
|
|
|
|
|
begin_view_template(UserItemView, ItemView, my_style_sheet(normalItem))
|
|
|
begin_view(HiddenView, NULL))
|
|
|
set(Name, "id")
|
|
|
end_view
|
|
|
begin_view(ImageView, my_style_sheet(userAvatar)))
|
|
|
set(Name, "avatar")
|
|
|
end_view
|
|
|
begin_view(TextView, my_style_sheet(userName)))
|
|
|
set(Name, "name")
|
|
|
end_view
|
|
|
end_view_template
|
|
|
|
|
|
begin_view(PanelView, my_style_sheet(panel))
|
|
|
map(my(thePanel))
|
|
|
begin_view(TextView, my_style_sheet(panelHeader))
|
|
|
map(my(theHeader))
|
|
|
set(Content, STRID_TITLE)
|
|
|
end_view
|
|
|
begin_view(ListView, my_style_sheet(userList))
|
|
|
map(my(theList))
|
|
|
set(ItemTemplate, my_template(UserItemView))
|
|
|
set(Name, "userItem")
|
|
|
end_view
|
|
|
begin_view(TextView, my_style_sheet(panelFooter))
|
|
|
map(my(theFooter))
|
|
|
set(Content, STRID_COPYING)
|
|
|
end_view
|
|
|
end_view
|
|
|
end_activity
|
|
|
|
|
|
begin_activity(userInfo)
|
|
|
begin_view(PanelView, ...)
|
|
|
...
|
|
|
end_view
|
|
|
end_activity
|
|
|
|
|
|
This file (assume named `firstsample.res.inc") will be pre-compiled by
|
|
|
your C++ compiler in a magic way:
|
|
|
|
|
|
* In a C++ header file, include the resource file in the following way
|
|
|
to generate the identifiers and names of the resource:
|
|
|
|
|
|
#include <hfcl/resource/resdefines.head.h>
|
|
|
#include "firstsample.res.inc"
|
|
|
#include <hfcl/resource/resundefines.h>
|
|
|
|
|
|
#include <hfcl/resource/resdefines.name.h>
|
|
|
#include "firstsample.res.inc"
|
|
|
#include <hfcl/resource/resundefines.h>
|
|
|
|
|
|
* In a C++ source file, include the resource file in the following way to
|
|
|
generate the source code and the initialization code:
|
|
|
|
|
|
#include <hfcl/resource/resdefines.source.h>
|
|
|
#include "firstsample.res.inc"
|
|
|
#include <hfcl/resource/resundefines.h>
|
|
|
|
|
|
#include <hfcl/resource/resdefines.init.h>
|
|
|
#include "firstsample.res.inc"
|
|
|
#include <hfcl/resource/resundefines.h>
|
|
|
|
|
|
By using the method described above, we do not need a utility tool
|
|
|
to interpret the resource file and generate the souce code, the C++
|
|
|
compiler will do this for us.
|
|
|
|
|
|
The another advantage is that we seperate the resource data with the
|
|
|
app logical code in a good way.
|
|
|
|
|
|
The last advantage is that the resource file can be generated from
|
|
|
the HVML tags. Thus, if you have to use C++ to write your device app
|
|
|
because the poor hardware performance, you can easily keep up your C++
|
|
|
code with the JavaScript code.
|
|
|
|
|
|
If you have some expirience with HTML and CSS, you will easily get the
|
|
|
the define the style sheet of views with the same manner of CSS. For example,
|
|
|
the style sheet of the user name corresponds to the following CSS definition:
|
|
|
|
|
|
.userAvatar {
|
|
|
display: inline-block;
|
|
|
position: relative;
|
|
|
margin: 0px 0px 0px 0px;
|
|
|
padding: 0px 0px 0px 0px;
|
|
|
height: 20px;
|
|
|
width: 20px;
|
|
|
border-radius: 5px 5px 5px 5px;
|
|
|
}
|
|
|
|
|
|
For performance reason, we do not use the direct literal CSS definition in HFCL.
|
|
|
We use the macros to define every style element in C++ way instead:
|
|
|
|
|
|
begin_css(userAvatar, ".avatar")
|
|
|
style(Display, PV_INLINE_BLOCK)
|
|
|
style(Position, PV_RELATIVE)
|
|
|
style(Margin, PV_LENGTH_PX, 0)
|
|
|
style(Padding, PV_LENGTH_PX, 0)
|
|
|
style(Height, PV_LENGTH_PX, 20.0f)
|
|
|
style(Width, PV_PERCENTAGE, 100.0f)
|
|
|
style(BorderRadius, PV_LENGTH_PX, 5.0f)
|
|
|
end_css
|
|
|
|
|
|
In the definition of a view which uses a style sheet, we passed the class of
|
|
|
the way:
|
|
|
|
|
|
begin_view_ex(hvimage, "avatar", ...))
|
|
|
...
|
|
|
end_view
|
|
|
|
|
|
### Translate HTML/HVML and CSS into C++ Code
|
|
|
|
|
|
It will be a trouble if we write the style sheets and views by hand in the way
|
|
|
above. So we introduce a interpreting tool which can translate the HVML tags
|
|
|
and CSS into the HFCL resource source files.
|
|
|
|
|
|
This tool is called `hfclify`, and it will be written in Python.
|
|
|
|
|
|
If you want to change the style sheet of one view on the fly, you can call
|
|
|
one of the following APIs of HFCL:
|
|
|
|
|
|
view->addStyleSheet (HFCL_STYLE_SET_NAME (firstSample, activeItem));
|
|
|
view->useStyleSheet (HFCL_STYLE_SET_NAME (firstSample, focusItem));
|
|
|
view->setStyleProperty (HCFL_STYLE_COLOR, Color::WHITE);
|
|
|
|
|
|
Note that the resource source file can not reflect all details in your
|
|
|
HVML tags. You need to write the interaction code in your C++ source
|
|
|
file. For example, in HVML tags, you can define the iteration of
|
|
|
an item from a template view by using the property `hbd-iterate-by`,
|
|
|
but in HFCL, we can not do this for you. You need to initialize the
|
|
|
list view in your implementation classes manually.
|
|
|
|
|
|
When you re-generate the resource source file from HVML tags,
|
|
|
because the real implemenations are seperated from the
|
|
|
resource source files, the translator will not override your own code.
|
|
|
|
|
|
In HFCL, a view template is defined as a derived class of one standard view,
|
|
|
as shown in the sample:
|
|
|
|
|
|
begin_view_template(UserItemView, ItemView, my_style_sheet(normalItem))
|
|
|
...
|
|
|
end_view_template
|
|
|
|
|
|
The `UserItemView` will be defined by the macro as a new view class
|
|
|
in the resource header file, just a simply subclass of ItemView:
|
|
|
|
|
|
class UserItemView : public ItemView {
|
|
|
public:
|
|
|
UserItemView (View* parent) : ItemView (parent) { }
|
|
|
UserItemView (View* parent, StyleSheet* style_sheet) : ItemView (parent, style_sheet) { }
|
|
|
virtual ~UserItemView () {};
|
|
|
}
|
|
|
|
|
|
----
|
|
|
|
|
|
The `UserItemView` will be defined by the macro as an interface class
|
|
|
in the resource header file. You should define the implemetation class
|
|
|
by yourself (in separated files):
|
|
|
|
|
|
class UserItemViewIf : public ItemView {
|
|
|
public:
|
|
|
UserItemViewIf (View* parent) : ItemView (parent) { }
|
|
|
UserItemViewIf (View* parent, StyleSheet* ss) : ItemView (parent, ss) { }
|
|
|
|
|
|
virtual View* getChildByName (const char* name) = 0;
|
|
|
virtual ~UserItemViewIf () {};
|
|
|
}
|
|
|
|
|
|
class UserItemViewIm : public UserItemViewIf {
|
|
|
public:
|
|
|
UserItemViewIm (View* parent);
|
|
|
UserItemViewIm (View* parent, StyleSheet* ss);
|
|
|
virtual View* getChildByName (const char* name);
|
|
|
...
|
|
|
|
|
|
private:
|
|
|
...
|
|
|
}
|
|
|
|
|
|
_...The above words are deprecated._
|
|
|
|
|
|
[Beijing FMSoft Technologies Co., Ltd.]: https://www.fmsoft.cn
|
|
|
[FMSoft Technologies]: https://www.fmsoft.cn
|
|
|
[HybridOS Official Site]: https://hybrid.fmsoft.cn
|
|
|
|
|
|
[MiniGUI]: http:/www.minigui.com
|
|
|
[WebKit]: https://webkit.org
|
|
|
[HTML 5.3]: https://www.w3.org/TR/html53/
|
|
|
[DOM Specification]: https://dom.spec.whatwg.org/
|
|
|
[WebIDL Specification]: https://heycam.github.io/webidl/
|
|
|
[CSS 2.2]: https://www.w3.org/TR/CSS22/
|
|
|
[CSS Box Model Module Level 3]: https://www.w3.org/TR/css-box-3/
|
|
|
|
|
|
[HybridOS Architecture]: https://github.com/FMSoftCN/hybridos/wiki/HybridOS-Architecture
|
|
|
[HybridOS App Framework]: https://github.com/FMSoftCN/hybridos/wiki/HybridOS-App-Framework
|
|
|
[HybridOS View Markup Language]: https://github.com/FMSoftCN/hybridos/wiki/HybridOS-View-Markup-Language
|
|
|
[hiWebKit]: https://github.com/FMSoftCN/hybridos/wiki/hiWebKit:-An-WebKit-Derivative-for-HybridOS
|
|
|
[hiBus]: https://github.com/FMSoftCN/hybridos/wiki/hiBus:-A-Secure-Data-Bus-Mechanism
|
|
|
[HybridOS Foundation Class Library]: https://github.com/FMSoftCN/hybridos/wiki/HybridOS-Foundation-Class-Library
|
|
|
[HybridOS Security Design]: https://github.com/FMSoftCN/hybridos/wiki/HybridOS-Security-Design
|
|
|
[HybridOS Device Simulation Environment]: https://github.com/FMSoftCN/hybridos/wiki/HybridOS-Device-Simulation-Environment
|
|
|
[HybridOS Code and Development Convention]: https://github.com/FMSoftCN/hybridos/wiki/HybridOS-Code-and-Development-Convention
|
|
|
|