apps/graphics/twm4nx/README.txt: Add an overview of how to create Twm4Nx applications.

This commit is contained in:
Gregory Nutt 2019-05-28 08:53:00 -06:00
parent 72f536866b
commit f937077b0e

View File

@ -208,3 +208,173 @@ Issues:
that results in a large line spacing on the display and, hence, that results in a large line spacing on the display and, hence,
fewer lines visible in the small window. This is latter issues is fewer lines visible in the small window. This is latter issues is
a problem with the fonts not Twm4Nx, however. a problem with the fonts not Twm4Nx, however.
Adding Twm4Nx Applications
==========================
Application Factories and the Main Menu
---------------------------------------
The original TWM supported a .twmrc in which you could describe application
programs supported on the desktop. Currently no such start-up file is
available for Twm4Nx. Rather, all applications must be added via run-time
interfaces. And overview of these interfaces is provided in this
paragraph.
Currently, there are only two applications developed for Twm4Nx: (1) An
NxTerm hosting NSH that is analogous to an XTerm hosting the Bash shell
in a Unix environment, and (2) a touchscreen calibration application.
Let's focus instead on the NxTerm application as an example because the
touchscreen calibration is a rather unusual beast.
These example applications can be found at: apps/graphics/twm4nx/apps and
apps/include/graphics/twm4nx/apps
In short, adding an application involves a "Factory Object" that is
hooked into the Main Menu. A Factory Object is an object that is used
to create other object instances. The way in which the Factory Object
is represented is purely a decision of the application developer. One
option, however, is to use the pure virtual base class IApplicationFactory
as defined in apps/include/graphics/twm4nx/iapplication.hxx. This base
class provides only a single method:
bool initialize(FAR CTwm4Nx *twm4nx);
where CTwm4Nx is the Twm4NX session instance that allows the class
implementation to interact with session specific resources. Multiple
sessions would be required, for example, if the platform supported
multiple displays.
In practice, the application factory implementation class inherits from
the following base classes:
1. IApplicationFactory. Provides the common initialize() method.
2. IApplication. Provides the information for the application's entry
in the Main Menu
3. CTwm4NxEvent. Hooks the application factory into the Twm4Nx event
notification system.
Initialization consists of instantiating the application factory instance
and calling its IApplicationFactory::initialize() method. The application
factory instance is a singleton that must persist for the life of the
session. For the NxTerm application factory, this is done in
apps/graphics/twm4nx/src/twm4nx_main.c like:
CNxTermFactory nxtermFactory;
success = nxtermFactory.initialize(twm4nx);
In addition to general initialization, the IApplicationFactory::initialize()
method must register a new entry with the main menu. You can see an
example of this in apps/graphics/twm4nx/apps/cnxterm.c:
FAR CMainMenu *cmain = twm4nx->getMainMenu();
return cmain->addApplication(this);
The argument to the CMainMenu::addApplication() method is of type
IApplication *. Remember, however, that our application implementation
class inherited from IApplication.
The IApplication pure virtual base class is also defined in
apps/include/graphics/twm4nx/iapplication.hxx. It essentially describes
what the Main Menu logic should do when the menu item is selected. It
includes these methods:
1. getName(). Provides the name string that will be shown in the
Main Menu for this selection.
2. getSubMenu(). One possibility is that selecting the Main Menu item
is that it may bring up yet another sub-menu of options.
3. getEventHandler(). Returns an instance of CTwm4NxEvent that is used
to route menu selection events. Remember that our application
factory inherits from CTwm4NxEvent so this function only needs to
return the 'this' pointer.
4. getEvent(). Provides the event ID that will be used in the event
notification. The returned value must conform to the description
in apps/include/graphics/twm4nx/twm4nx_events.hxx. In particular,
the recipient of the event must be EVENT_RECIPIENT_APP.
The Twm4Nx application is then started when the application factory's
CTwm4NxEvent::event() method is called with the specified event.
Application Windows
-------------------
How the application factory starts an application instance is purely up
to the application designer. Typically this would include starting a
new application task. General characteristics of an application include:
1. It probably should inherit from CTwm4NxEvent so that it can receive
events from the system.
2. To create the window, it must instantiate and initialize an instance
of CWindow.
3. It must configure application events to receive notifications from
Twm4Nx.
To create an application window, the application must call the
CWindowFactory::createWindow() method. For the NxTerm example, this looks
like:
NXWidgets::CNxString name("NuttShell");
uint8_t wflags = (WFLAGS_NO_MENU_BUTTON | WFLAGS_HIDDEN);
FAR CWindowFactory *factory = m_twm4nx->getWindowFactory();
m_nxtermWindow = factory->createWindow(name, &CONFIG_TWM4NX_NXTERM_ICON,
(FAR CIconMgr *)0, wflags);
The window factory is another factory that creates and manages window
instance. The createWindow() method requires four parameters:
1. The name of the window. This is the name that is show in the window
toolbar and may be the same name as was used in the Main Menu entry.
2. A reference to the the Icon image associated with the window. This
is the image that is show on the desktop when the window is
iconified. It is of type NXWidgets::SRlePaletteBitmap.
3. A pointer to the Icon Manager instance that this window belongs with.
This can be NULL to use the default Twm4Nx Icon Manager.
4. A set of flags that describe properties of the windows.
The flag values are defined byte WFLAGS_* definitions provided in
apps/include/graphics/twm4nx/cwindow.hxx:
1. WFLAGS_NO_MENU_BUTTON Omit the menu button from the toolbar
2. WFLAGS_NO_DELETE_BUTTON Omit the delete button from the toolbar
3. WFLAGS_NO_RESIZE_BUTTON Omit the resize button from the toolbar
4. WFLAGS_NO_MINIMIZE_BUTTON Omit the minimize button from the toolbar
5. WFLAGS_NO_TOOLBAR Omit the toolbar altogether
6. WFLAGS_ICONMGR This window is an icon manager
7. WFLAGS_MENU This window is a menu window
8. WFLAGS_HIDDEN Start with the window hidden
Once the CWindow is instantiated, events needed by the application can
be configured as is done in the NxTerm application:
struct SAppEvents events;
events.eventObj = (FAR void *)this;
events.redrawEvent = EVENT_NXTERM_REDRAW;
events.resizeEvent = EVENT_NXTERM_RESIZE;
events.mouseEvent = EVENT_NXTERM_XYINPUT;
events.kbdEvent = EVENT_NXTERM_KBDINPUT;
events.closeEvent = EVENT_NXTERM_CLOSE;
events.deleteEvent = EVENT_NXTERM_DELETE;
bool success = m_nxtermWindow->configureEvents(events);
Again, recall that the application inherits from CTwm4NxEvent. So passing
'this' as the event object above assures that the specific events are
routed to the application instance.
Drawing in the application window can be performed using that facilities
of NXWidgets using the NXWidgets::CGraphicsPort associated with the
window. The NxTerm application does not perform any drawing, however;
that drawing is performed by the NxTerm driver.
The NXWidgets::CGraphicsPort can be obtained from a CWindow instance,
say m_window, like:
FAR NXWidgets::CWidgetControl *control = m_window->getWidgetControl();
NXWidgets::CGraphicsPort *port = control->getGraphicsPort();
That CGraphicsPort is then passed to the widget constructor, binding the
widget to that window and forcing all widget drawing to occur within the
window.
Obviously, a lot more could be written about drawing, much more than can
be addressed in this README file.