Warning: main(/www/www/htdocs/style/globals.php) [function.main]: failed to open stream: No such file or directory in /www/www/docs/6.4.1/photon/prog_guide/tutorls.html on line 1
Warning: main() [function.include]: Failed opening '/www/www/htdocs/style/globals.php' for inclusion (include_path='.:/www/www/common:/www/www/php/lib/php') in /www/www/docs/6.4.1/photon/prog_guide/tutorls.html on line 1
Warning: main(/www/www/htdocs/style/header.php) [function.main]: failed to open stream: No such file or directory in /www/www/docs/6.4.1/photon/prog_guide/tutorls.html on line 8
Warning: main() [function.include]: Failed opening '/www/www/htdocs/style/header.php' for inclusion (include_path='.:/www/www/common:/www/www/php/lib/php') in /www/www/docs/6.4.1/photon/prog_guide/tutorls.html on line 8
The best way to get to know PhAB is to use it. This chapter provides hands-on
sessions to give you a jump start on creating applications.
This chapter includes:
We'll take a closer look at using PhAB in the chapters that follow.
The first two tutorials cover the basics: creating widgets, changing
how widgets look and behave, generating code, running your application,
and so on.
The remaining tutorials go beyond the basics to show you how
to create working menus, dialogs, and windows. When you've completed
these tutorials, you'll be ready to start building almost any Photon
application.
If you're developing Photon applications in the IDE, the way
you use PhAB there is slightly different than from standalone PhAB.
The differences are:
- New projects — When using the IDE, you create a QNX Photon
Appbuilder project in the IDE, and then use PhAB to create the user
interface. Using standalone PhAB, you create the project from within
PhAB.
- Editing code — The IDE allows you to edit your project's
code, and take advantage of features like syntax highlighting. When you
use standalone PhAB, you use an external editor, such as vi,
to edit code.
- Building and compiling — The IDE manages building and running
your application, and you have to set up a target to run and debug
the application on. Using standalone PhAB, you can build and run
your application from within PhAB. Note that in both cases you
need to configure targets within PhAB.
To create a new PhAB project, see “Creating
a QNX Photon Appbuilder project” in the Developing Photon Applications chapter of the IDE
User's Guide. When you create a new project, the IDE opens PhAB,
and you see the New Window Style dialog from which you
can select the type of base window for your application.
You can start PhAB from the Launch menu in the lower-left corner
of the screen; choose the Development submenu, and then choose Builder.
You can also start PhAB from a pterm window by typing:
appbuilder
For information about command-line options, see
appbuilder in the QNX Neutrino Utilities Reference.
Before you start the tutorials, take a moment to make yourself
familiar with PhAB's user interface:
Overview of PhAB's user interface.
- Menubar
- Import graphics, create windows and dialogs, generate C
and/or C++ code to implement your entire user interface, and more.
- Toolbars
- Save time with the toolbars—with a couple of mouse
clicks you can duplicate, move, align, group, or resize any number
of widgets.
- Work area
- Provides a flexible area where you can work on several application
modules all at once.
- Widget palette
- Makes it easy to add widgets to your application. Just click
the widget you want, then click where you want it.
- Control panels
- Let you fully customize your application's widgets. You can
choose text fonts, modify colors, customize bitmaps, and attach
callbacks that will pop up dialogs or invoke C and/or C++ code
you've supplied.
The widget palette and control panels are initially in the same
window, but you can drag any of them into a different window. To
switch between panels in a window, click the tab at the top and
choose a panel from the menu.
If you close a control panel, you can redisplay it by selecting
the appropriate item from the View menu.
In this tutorial you learn how to use PhAB to create and compile
a simple application.
- Create a new project. See “Creating a Photon project and starting PhAB” above.
- PhAB displays a dialog to let you choose the style for the new
application's default base window:
- Choose a style and click Done; PhAB creates the base window and
displays it.
- Whenever you create a new application within standalone PhAB, it's
a good idea to save the application and give it a name. (If you're
running PhAB from the IDE, you've already saved the application
when you created the project).
From the File menu, choose Save As to open the Application Selector
dialog. Click the Application Name field, type tut1,
then press Enter or click Save Application.
- Look at PhAB's titlebar. It now indicates that the current application
is named tut1.
- If the widget palette isn't displayed, click the tab at the
top of the current control panel and choose Widgets from the menu
that appears.
- Drag the widget palette away from the other control panels by pointing
to the left of its tab, holding down the mouse button, and pointing
to PhAB's work area.
- If you wish, resize the widget palette and control panels.
- Go to the widget palette and click the PtLabel widget
icon:
- Move the pointer into the application's base window (the pointer
changes to a crosshair) and click anywhere near the center
of the window.
PhAB automatically:
- creates a new PtLabel widget
- selects the widget so you can edit its resources
- places resize handles around the widget
- displays the widget's resources in the Resources and Callbacks
control panels.
- Go to the Resources control panel and highlight the text Label
beside the Label Text resource.
- Change the text to Hello World. As you type, the
text in the widget changes:
Now you're ready to generate, compile, and execute the application. How
you perform this step depends on whether you're using PhAB from the
IDE or standalone.
When running PhAB from the IDE, PhAB generates the code for your application's
user interface, and the IDE compiles and executes the application.
You'll notice that only the Generate UI item is
available in PhAB's Build menu.
- In PhAB, chose Generate UI from the Build menu
to generate the user interface code.
- Switch to the IDE.
- To build the application, follow the instructions in
Building projects in the Developing C/C++ Programs chapter of the IDE User's
Guide.
- To run the application, follow the instructions in
Running projects in the Developing C/C++ Programs chapter of the IDE User's
Guide.
- From the Build menu, choose Build & Run.
PhAB displays a dialog for selecting a platform, which is a combination
of the operating system, computer, compiler, and endian format. Choose
the appropriate platform for your application. For example, if you're
using the Neutrino OS on an Intel x86 machine and the gcc compiler,
choose X86 (Little Endian).
- Click Done once you've made your platform selection.
Your application will be generated, compiled and linked. PhAB displays
a dialog for entering run arguments. Click OK. Your application
runs.
The application will appear in its own window, with the text “Hello World” in
the center and the default title “My Application” in
the title bar:
Congratulations! You've just created your first Photon application
using PhAB.
To quit the application, click the window menu button in its
top-left corner, then choose the Close item.
For more info on compiling, running, and debugging an application,
see the
Generating, Compiling, and Running
Code chapter.
This tutorial introduces you to PhAB's resource editors, which
let you change how widgets look and behave. You'll find out how
to edit virtually any kind of resource a widget may have, including:
- numerical resources (e.g. border width)
- text fonts
- text strings
- flags
- colors
- pixmaps
You'll also learn how to create a template so you can create
other instances of an existing widget.
- Create a new application called tut2. Choose
the Plain window style.
- Click PtButton in the widget palette:
- Click near the center of the application's window. You'll
see a button widget.
- Drag any of the button's resize handles until the button matches
the following picture:
Let's now edit a numerical resource—the button's bevel
width.
- Click the Bevel Width resource in the Control Panel.
You'll see the number editor:
This editor lets you change the value of any numerical widget resource.
- Change the value to 6. To do this, you can:
- type in the new value
or:
- click the increment/decrement buttons.
- To apply the new value and close the editor, press Enter or click Done.
|
You can also edit this resource (and most resources) right
in the Resources control panel. Choose whichever method you like. |
Let's change the font of the button's text:
- Click the Font resource. You'll see the font editor,
which displays the button's current font:
This editor lets you change the text font of any widget
that has text.
- Click the Font box or the Size box, select a typeface or
size from the displayed list, and click Apply. The button
displays the new font.
- Click Default. The editor displays the widget's default
font, but doesn't apply the font to the widget.
- If you want to keep the new font that you selected, click
Cancel to ignore the default. If you want to apply the default, click
Done. Either way, the editor closes.
Now let's change the button's horizontal text alignment:
- Scroll through the Resources control panel to find the Horz Alignment
resource, then click it. You'll see the flag/option editor,
which displays the widget's current text alignment:
This editor serves a dual purpose in PhAB:
- It modifies any resource—such as text alignment—that
can have one of several preset values.
- It selects one or more flags in any flag resource
- Click Pt_LEFT or Pt_RIGHT,
then click Apply. You'll see the button text move to the left
or right edge of the button.
- Click Done.
You can also set this resource right in the Resources control
panel.
Let's now use the flag/option editor to set one of the widget's
flags:
- Scroll through the Resources control panel to find the Basic Flags resource,
then click it. The flag/option editor reopens, but this time
it shows the widget's current PtBasic flag settings:
The bits in this flag resource aren't mutually exclusive, so this
time you can use the editor to select multiple options, if
desired.
- Set the Pt_TOP_INLINE, Pt_BOTTOM_INLINE,
Pt_LEFT_INLINE, and Pt_RIGHT_INLINE
flags, then click Done. PhAB draws the button with an inner border:
Let's change a color resource—the button's fill color.
- Click the button's Color: Fill resource.
You'll see the color editor, which displays the current fill
color:
This editor lets you edit any color resource. It provides
several preset base colors, which should work well with all
graphic drivers, and 48 customizable colors for drivers that
support 256 or more colors.
- Click any color in the Base Colors set, then click on Apply. The
button is filled with the color you selected.
- Select a color from the Custom Colors set. The sliders will display
the color's Red/Green/Blue (RGB) values. Change these values
till you get a color you want, then apply your changes.
If you'd like to experiment with the Hue/Saturation/Brightness (HSB)
color model, click the HSB Model button.
- Click Done when you've finished experimenting with the editor.
Your button should now look something like this:
Don't delete this widget; we'll use it to create a template later
on, so that you can create other widgets like it.
Let's now use the pixmap editor to edit a
PtLabel widget. This editor is called “pixmap” instead
of “bitmap” since it lets you edit many types of image
resources besides bitmaps.
A PtLabel widget display text and/or an image.
- Click PtLabel in the widget palette:
- Move the pointer into the main window and click below the button
widget you created. You'll see a PtLabel widget.
- Click the Label Type resource in the Resources control panel,
and set it to Pt_IMAGE.
- Click the Label Image resource in the Resources control panel to
bring up the pixmap editor.
- Next, bring up the color editor to select a draw color. Just
click the following button:
- Select a color from the pixmap palette. You'll see that the
draw color in the pixmap editor changes immediately.
If you click Edit Color, you'll see the Color Editor, as described
earlier.
- To draw a simple image, you can:
- click the left mouse button to fill a cell with the draw color
- click the right mouse button to fill a cell with the background
color
- hold down a mouse button and drag the pointer to draw
freehand
Feel free to try the other drawing tools.
- When you're done, click the pixmap editor's Done button to apply
your changes and close the editor.
Next, we'll edit a multiline text resource—the text of
a PtMultiText widget.
- Click PtMultiText in the widget palette:
- Move the pointer below the label widget you've just created,
and drag until the new PtMultiText widget appears
big enough to hold a few lines of text.
- Click the Text String resource in the Resources control
panel to bring up the multiline text editor:
- Type a few lines of text. To create a new line, press Enter.
For example:
Mary hadEnter
aEnter
little lamb.Enter
- Click Done. Your text should appear exactly as you typed it.
If it doesn't, try resizing the widget—the widget might
not be wide enough or tall enough.
- For a different effect, look for the Horz Alignment
resource, click the arrow, and change the text alignment to Pt_CENTER.
As you can see, each line is now centered individually.
- If you haven't already, resize the widget by dragging on
one of its resize handles. You'll see the text update automatically
to adjust to the new size. For example:
|
You can edit the text right in the control panel, but it displays
only the current line of text. |
Let's now create a PtList widget and add text
to the widget using the list editor. This editor lets you add and
edit text for any widget that provides a list of text items.
- Click PtList in the widget palette:
- Move the pointer into the application's base window, and drag the
pointer until the new PtList widget appears
big enough to hold a few lines of text.
- Click the List of Items resource to bring up the
list editor:
- Click the text box at the bottom of the editor. You'll see
the text-input cursor.
- Type some text, then click Add After to place the first item
in the list.
- Now let's create the second item. Click in the text box,
and type Ctrl-U
to erase the text in the text box, then type some new text.
Click Add After to place this new item after the previous
item.
- Repeat the above step as often as you'd like.
- Click Apply. The PtList widget should now
display the list you've created.
- Now try editing the list:
- To modify an existing item, click the item, edit the
item's text, then click Edit.
- To delete an item, click the item, then click Remove.
- When you're finished experimenting, click on Done to apply your
changes and close the editor.
At times, you might want to create many widgets that look and behave
alike. You can do this by creating a widget, editing its resources, and
then copying and pasting it, but this isn't always very convenient, and doesn't
copy certain important elements like callbacks.
PhAB makes it simpler by letting you create a template from
an existing widget or widgets. PhAB creates a palette, similar to
the widget palette, for your templates.
Let's create a template from the button that you created earlier
in this tutorial.
- Start by selecting the button.
- Click the Widget menu, and then choose Define Template. The Define
Template dialog appears.
- You need to create a folder in which to store the template,
so click on Add Folder. This dialog is displayed:
- The new folder can be a user folder or a PhAB folder. A user folder
is personal and can't be viewed by any other PhAB users logged on
to the system. If you choose PhAB folder, the new folder
can be shared between users; you must have the necessary permissions
to create a PhAB folder.
Choose User Folder, type My_templates as
the folder's name, and click Add. The dialog closes, and
the folder's name is displayed in the Define template dialog.
- Give the template a name, such as Big green button.
This is the name that PhAB uses in the palette.
- You can create an icon for the palette entry for the template.
If you do not create an icon for the template entry, a default icon
is used for it. To create the icon, click the icon Edit button,
and then follow the instructions given earlier for editing pixmaps. You
should make the icon look something like the widget:
- Optionally, choose the background color for the palette entry
by clicking on the Color box. You can use different background colors
in a palette to distinguish widgets that are used for different
purposes (e.g. buttons and text widgets).
- Choose a resize method. This determines whether you drag or just
click when you create instances of your template. For this button,
choose the dragging method.
- The dialog should now look something like this:
Click Done.
You've just created a template! Now, let's see how to use it.
- Select .
On the list of items, select Show My Templates. If the
menu item is Hide My Templates, it means that My Templates
is already displayed and visible on the screen.
- Go to the control panels, and click the top tab. The popup
menu now includes My_templates; choose it to display the palette.
- Click the icon for your customized button, create an instance
of it, and edit it as you wish:
If you wish, you can save, generate, make, and run the application.
Whenever you start PhAB, it automatically loads the palette for My_templates.
You now know the basics of editing any widget resource in PhAB.
For more information, see the following sections in the Editing
Resources and Callbacks in PhAB chapter:
For more information on templates, see “Templates” in the Creating Widgets in PhAB chapter.
This tutorial takes you through the steps required to create menus and
menubars.
In this tutorial, you'll learn how to set up a link callback,
one of the key components of PhAB. To understand what a link callback
is, let's start with some background info on widget callbacks.
Almost all widgets support a variety of callbacks. These callbacks
enable your application's interface to interact with your application
code. For example, let's say you want your application to perform
an action when the user clicks on a button. In that case, you would
attach a callback function to the button's “Activate” callback.
In some windowing environments, you can attach only code functions
to widget callbacks. But whenever you use PhAB to create a callback,
you can go one step further and attach entire windows, dialogs,
menus, and much more. It's this extended functionality that we call
a link callback.
PhAB provides two basic types of link callbacks:
- Module-type link callback
- Attaches an application module (such as a window, dialog,
or menu) to any widget callback. The module opens whenever the callback's
conditions are met. In this tutorial, you'll link a menu module
to a button's “Arm” callback.
- Code-type link callback
- Attaches a code function to any widget callback. The
widget invokes the function whenever the callback's conditions
are met. Note that some code-type link callbacks let you
close the parent module automatically. In this tutorial, you'll
link a code function to a menu item's callback.
To access a widget from your application code, you must first
give the widget an instance name. Since all widget instance
names reside in the same global namespace, no two widgets within
an application can have the same instance name.
We recommend that you start every instance name with a module
prefix. For example, if your base window has a PtButton widget
that contains the label text “Blue,” you could give
this widget an instance name of base_blue.
|
Adopting a naming convention for your widgets will make it
easier for you to work with large applications. |
To learn about using link callbacks, let's create two functioning menus—File
and Help—that you can later incorporate into your own applications.
In PhAB, menus are built in two pieces:
- a menu button, which you'll click to display the menu
- a menu module, which contains the menu items.
Using link callbacks, you'll link the menu modules to the File
and Help buttons in a menubar. You'll also link a code-type callback
to the Quit menu item in the File menu module. This callback will
enable the Quit item to close the application.
- Create a new application named tut3. Choose the
Plain window style.
- Select the PtMenuBar widget from the widget
palette, point at the top left cornet of the main window's canvas,
and drag until the menu bar is the width of the window.
The menubar grows and shrinks as you change the width of the window,
and it always stays at the top of the window. You can see this
by clicking in the titlebar of the window, then resizing
the window by dragging on one of its resize handles.
|
If you accidentally click the Test button, the window won't resize
or accept new widgets. If this happens, you just switched into
Test Mode. To go back to Edit Mode, select . |
By the time you're finished the following steps, the menubar
will look like this:
- Place a PtMenuButton widget in the menubar
you just created. The menu button is automatically centered
vertically in the menubar.
- Go to the Resources control panel and click the widget instance
name just below the class name. Change the button's instance
name to base_file:
- Change the button's Label Text resource to File.
- Place another PtMenuButton widget next to the
first. Change its instance name to base_help and
its text to Help.
Now that you have menu buttons, you need to create your menu modules.
Let's start with the File menu.
- Select . A new
menu module appears.
- Change the name of the menu from Menu0 to filemenu:
Let's now add some menu items to the File menu.
|
If you click another module, the menu module becomes deselected, which
means you can't work on it. To reselect the menu module, click its
titlebar. |
- Click the Menu Items resource in the Resources control panel.
You'll see the menu editor:
If you look at the Menu Items list, you'll see that the <New> item is
selected. This special item lets you add menu items to the menu.
- To add your first menu item—which also happens to be
called “New”—click the Item Text
field, then type New.
- Now give the item an instance name. In the Inst Name
field, type file_new.
- Click Apply to add the item to the menu. You'll see the
item's name in Menu Items list, prefixed by CMD.
The CMD means this is a Command item; that is, an
item that invokes a PhAB callback.
- Repeat the above steps to create the two menu items labeled Save and Save
As. Give these items the instance names file_save
and file_as.
- Up to now, you've added Command-type menu items. You'll now
add a Separator item. Just click on the Separator button near
the upper-right corner
- Click Apply to get the default separator style, which
is Etched - in.
- Now let's add the Quit item. Click the Command button, then specify Quit as
the item text and file_quit as the instance name.
- You're finished with this menu module for now, so click Done.
The module displays the items you just created:
- You'll want to keep this module neatly out of the way while you
work on your next task. So click the module's minimize button
(the left button at the right side of the title bar), or select the
Work menu button (upper-left corner) and choose Minimize.
Using what you just learned about creating a menu module, do
the following:
- Create your Help menu module and give it a name of helpmenu.
- In this module, place a single command item called About Demo and
give the item an instance name of help_about.
When you're finished, minimize the module.
|
If one of your menu modules seems to “disappear” (you
may have accidentally closed it or placed it behind another module),
it's easy to bring the module back into view. See the “Finding lost modules and icons” in the Working with Modules chapter. |
Let's return to the menu buttons you created earlier and attach
link callbacks so that the buttons can pop up your menu modules.
- Select the File menu button, then switch to the Callbacks control
panel You'll see the File button's callback list:
- To have the File menu module pop up when you press the File button,
you need to attach an Arm callback to the button. By attaching
an Arm callback, you can open the menu using either click-move-click or press-drag-release.
Click Arm to bring up the callback editor.
- The Module Types area of the editor let you choose the type
of module you wish to link to. Because you want to link the
File button to a menu module, click Menu.
- Click the Name list and type filemenu (or select filemenu from
the list) which is the name you gave your File menu module. This
links the menu button to that module.
You can also select filemenu from a popup list
of available modules. To bring up the list, click the icon
to the right of the Name field.
- Click Apply to add the link callback, then click Done to
close the callback editor.
- Repeat the above steps to link the Help menu button to the Help
menu module.
Let's now attach a code-type link callback to the File menu's
Quit item so that it can terminate the application.
- Double-click the iconified filemenu module.
This opens and selects the module.
- Switch to the Resources control panel, then click the Menu Items
resource.
- Select the Quit item in the Menu Items list.
- Click the icon next to the Callback field to open the callback editor:
- When the editor opens, the default callback type is Code.
Since this is the type you want, all you have to do is specify
the name of the function you want to call.
The function should have a meaningful name. So type quit in the
Function field.
- Click Apply to update the Callbacks list, then click Done to close
the editor.
- Click Done again to close the menu editor.
You'll now generate the code for your application and edit a
generated code stub so that the Quit item will cause your application
to exit.
- Select . This
generates the necessary application files.
- After the generation process is complete, open the Browse Files palette
window by selection .
Scroll through the list until you see the quit.c file.
This is the generic code template that PhAB generated for your quit()
function.
- You need to make the function exit the program. To do this, select quit.c from
the file list, click the Edit button, or double-click quit.c,
then change the quit() function to the following:
int
quit( PtWidget_t *widget, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
/* eliminate 'unreferenced' warnings */
widget = widget,
apinfo = apinfo,
cbinfo = cbinfo;
PtExit( EXIT_SUCCESS );
/* This statement won't be reached, but it
will keep the compiler happy. */
return( Pt_CONTINUE );
}
PtExit() is a function that cleans up the Photon environment and
then exits the application. It's described in the Photon Library
Reference.
|
If you are using the IDE, you can also
edit quit.c, or any other source code file, from the IDE editor
by double-clicking the file in the project navigator tree. |
- After you've edited the code, saved your changes, and closed
the editor, build and run your application.
- Once your application is running, try clicking on the File button
to bring up the File menu. Then choose Quit. Your application
will immediately terminate and close.
For more info on: |
See the section: |
In the chapter: |
Widget callbacks |
Callbacks |
Editing Resources and Callbacks in PhAB |
|
Editing callbacks |
Editing Resources and Callbacks in PhAB |
Instance names |
Instance names |
Creating Widgets in PhAB |
Menu modules |
Menu modules |
Working with Modules |
This tutorial describes how to create a dialog. It also provides
a good example of how you can use setup code to modify a widget's
resources before the widget appears onscreen.
|
This tutorial uses the application you created in Tutorial 3. |
In this tutorial, you'll:
- link the About Demo item in the Help menu to a dialog
- add labels and a Done button to the new dialog
- define a setup function that changes the text of one of
the labels to display a version number when the dialog is realized.
Dialog modules are designed to let you obtain additional information from
the user. Typically, you use this information to carry out a particular command
or task.
Since you don't usually need to get the same information twice,
dialogs are single-instance modules. That is, you can't realize
the same dialog more than once at the same time. If you try create
a second instance of a dialog, PhAB simply brings the existing dialog
to the front and gives it focus.
If you need to create a window that supports multiple instances,
use a window module. You'll learn about window modules in the next
tutorial.
To make it easier for you to access widgets from within your
application code, PhAB generates a constant and a manifest.
Both of these are based on the widget's instance name.
The constant, which has the prefix ABN_, represents
the widget's name. The manifest, which has the prefix ABW_,
represents the widget's instance pointer.
For example, let's say you have a widget named about_version. PhAB
uses this name to generate a constant named ABN_about_version and
a manifest named ABW_about_version.
In this tutorial you'll learn how to use these generated names.
|
The value of a widget's ABN_... constant is
unique in the entire application. |
- Make a copy of the tut3 application you created
and name it tut4:
- From the IDE — select the project, select , and then select .
You can enter the new name for the project in the dialog that appears.
- From standalone PhAB — open the tut3 application and
use the File menu's Save As item to save the application as tut4.
- Open the Help menu module you created (it may still be iconified).
- Click the Menu Items resource in the Resources control panel
to open the menu editor.
- Select the About Demo item, then click the icon
next to the Callback field to open the callback editor:
- When the editor opens, the default callback type is Code.
Go to the Module Types group and change the callback type to Dialog.
- In the Name field, type aboutdlg as the name
of the dialog module you want to link to. (This dialog doesn't
exist yet, but PhAB will ask you later to create it.)
- In the Setup Function field, type aboutdlg_setup.
This is the name we're giving to the setup function that
will be called before the dialog is realized.
Using this function, we'll change the content of a label
widget within the dialog to display a version number.
- Since you want the aboutdlg_setup function to be
called before the dialog is realized, make sure the Prerealize
button is enabled.
- Click the Location icon to specify where you want the dialog to
appear when it gets realized. (The Center Screen location
is a good choice.) Click Done.
Your callback information should now look something like this
(depending on the location you chose):
- Click on Apply in the Actions group to add the link callback.
Since the dialog module you want to link to doesn't exist
yet, PhAB asks you to choose a style; select Plain and click Done.
You'll see the new dialog in the work area. You'll also see
the new callback in the Callbacks list in the callback editor.
- Click Done to close the callback editor, then click Done
again to close the menu editor.
- Open the aboutdlg dialog module.
- Place two PtLabel widgets in the top half
of the dialog, and a PtButton near the bottom:
- Select the top PtLabel widget and change its
label text resource to About this Demo. Then
change its horizontal alignment to Pt_CENTER.
- Select the other PtLabel widget and change
its label text to a blank string. Then change its horizontal
alignment to Pt_CENTER.
Later, you'll fill in the aboutdlg_setup() function
so that it changes the blank text of this label to display
a version number.
- You must give this blank PtLabel widget an
instance name since you'll be referring to it in code. So
change its instance name to about_version.
- Select the PtButton widget and change its
button text resource to Done. Then change its instance
name to about_done.
- Let's center the widgets horizontally in the dialog. Select
both PtLabel widgets and the PtButton widget,
choose Align from the Widget menu, and then choose Alignment Tool
from the submenu. You'll see the Align Widgets dialog:
- In the Horizontal column, click Align Centers and on Align to Container.
Then click the Align button.
The two labels and the button should now be centered horizontally within
your dialog. Your aboutdlg module should now look
like this:
Now let's add a callback to the Done button so that the dialog
closes when the user clicks on the button.
- Select the Done button, then switch to the Callbacks control panel.
- Click Activate to add an activate callback. You'll see the callback
editor.
- Select the Done code type, then click Apply. Don't enter anything
in the Function field.
Selecting the Done code type tells the widget to perform
a “Done” operation when the widget is activated.
That is, the widget calls the function specified in the Function
field (if one is specified) and then closes the dialog module.
- Close the editor. The callback list now indicates that you've added
an Activate callback called Done:
You'll now modify the generated aboutdlg_setup() function
so that it changes the text of the about_version label
to show a version number.
- Select . This
save yours application and generates the necessary files.
- When code generation is complete, choose to
bring the Browse Files palette window to front. Select aboutdlg_setup.c from
the file list, and click Edit, or double-click the filename.
If you are using PhAB from the IDE, you can open and edit this file
in the IDE.
Change the code from:
int
aboutdlg_setup( PtWidget_t *link_instance,
ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
/* eliminate 'unreferenced' warnings */
link_instance = link_instance,
apinfo = apinfo,
cbinfo = cbinfo;
return( Pt_CONTINUE );
}
to the following:
int
aboutdlg_setup( PtWidget_t *link_instance,
ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
/* eliminate 'unreferenced' warnings */
link_instance = link_instance, apinfo = apinfo,
cbinfo = cbinfo;
PtSetResource( ABW_about_version, Pt_ARG_TEXT_STRING,
"1.00", 0);
return( Pt_CONTINUE );
}
The code is placing the version number (1.00) into the text
string resource for the about_version widget. To
do this, the code calls PtSetResource() to set the
resource for the about_version widget. The code
uses the PhAB-generated manifest ABW_about_version,
which provides access to the widget's instance pointer.
We can use this manifest safely since we're dealing with
a dialog module—PhAB ensures that only one instance
of the dialog will exist at any given time.
- Save your changes and exit the text editor.
You're now ready to compile and run the program:
- Build and run your application. If your program compiles and links
without errors (which it should if you edited the function correctly),
it will run.
- From the running application, open the Help menu and choose About
Demo. The dialog will open, and you'll see the version number
(1.00) under the label About this Demo. Note that the
dialog appears in the location you specified.
- Now try to bring up a second instance of the dialog. As you
see, it won't work. PhAB always ensures that there is only one
instance of a Dialog widget.
- Click Done to close the dialog, then quit the application
by choosing Quit from its File menu.
In the previous tutorial, you learned how to handle dialog modules, which
support just one instance. In this tutorial you'll learn how to
handle window modules, which support multiple instances.
|
This tutorial uses the application you created in Tutorial 4. |
By supporting multiple instances, window modules provide more flexibility
than dialogs. But to take advantage of this flexibility, you must keep
track of each window's instance pointer. Doing so ensures that you correctly
reference the widgets within each instance of a window. You can't
safely use the generated global ABW_xxx manifest
since it refers only to the last instance created.
To simplify the task of working with multiple instances, PhAB
provides API library functions that let you access any widget by
means of its generated constant name (ABN_xxx).
To start, let's create a window module and attach it to the New
menu item in the File menu in tut4. This window will
contain buttons that change the color of another widget.
In the previous tutorial, you created a dialog module from within
the callback editor. But this time you'll add the window from the Project menu.
In the future, use whatever method you prefer.
- Make a copy of the tut4 application and call
it tut5.
- Iconify the aboutdlg dialog module.
- From the Project menu, select Add Window.
When PhAB prompts you for a window style, choose the Plain style.
- Change the new window's instance name from Window0 to newwin,
by typing the new name in the instance name field in the control
Panel.
- The window module should now be the currently selected item.
Because a window module supports multiple instances, you have
to create code functions that will be called whenever the window
opens or closes (i.e. whenever the window is created or destroyed).
So let's first set up a callback to detect when the window closes:
- Switch to the Callbacks control panel, if necessary.
- From the list of callbacks, choose Window Manager. You want
to use the Window Manager callback since it's invoked when the
Photon Window Manager closes the window.
- In the Function field, type newwin_close. You
don't have to choose a callback type since the default, Code, is
the one you want.
Click Apply, then Done.
- Switch to the Resources control panel and select the Flags: Notify
resource. Make sure that the Ph_WM_CLOSE flag is
set (i.e. highlighted), then click Done. This flag tells the
Window Manager to notify your application when the window is
closed.
- Now let's set up a function that's invoked when the window opens.
Open the filemenu menu module, then select
the Menu Items resource in the Resources control panel. You'll
see the menu editor.
- Make sure the menu's New item is currently selected in the Menu
Items list, then click the Callback icon to open the callback
editor.
- Choose the Window module type, then click the arrow next
to the Name field. You'll see the list of existing window modules.
- Choose newwin, which is the window you just
created.
- In the Setup Function field, enter newwin_setup as
the name of the setup function. Later, you'll modify newwin_setup()
to handle the window's multiple instances.
- Click Apply, then on Done. Click Done again to close the menu editor.
Let's now add some widgets to the newwin window
module. Using these widgets, you'll learn how to update information
in the current or other instances of a window module.
- Add a PtRect widget and four PtButton widgets
as follows:
- Now modify the left button:
- Change the button's label text to Red.
- Give the button an instance name of btn_red.
- Attach an Activate callback, specifying a “Code” code
type and a function name of color_change.
- Modify the middle button:
- Change the label text to Green.
- Specify an instance name of btn_green.
- Attach an Activate/Code callback to the same function as above, color_change.
- Modify the right button:
- Change the label text to Blue.
- Specify an instance name of btn_blue.
- Attach an Activate/Code callback to the same function as above.
- Modify the large button:
- Change the label text to Change previous window's color.
- Specify an instance name of btn_prev.
- Attach an Activate/Code callback to the same function as above.
- Last of all, give the rectangle an instance name of color_rect.
You need to specify this name so that the color_change() function
can change the color of the rectangle.
Your window should now look something like this:
In the last tutorial, you used the generated ABW_xxx manifest
to access a dialog's instance pointer. You can't use this manifest
when dealing with multiple instances of a window module since it
refers only to the last window created. Instead, you have to add
code to the generated window-setup function so that it stores a
copy of each window-instance pointer in a global widget array. In
this tutorial, you'll need these pointers for the Change Previous
Window Color button to work.
Open the Build menu and select Generate UI.
Now let's modify the newwin_setup() function so that
it:
- limits the number of possible instances to five
- stores a copy of each window pointer
- displays a window's instance number in that window's titlebar
Edit the newwin_setup.c file as follows:
int win_ctr = 0;
PtWidget_t *win[5];
int
newwin_setup( PtWidget_t *link_instance,
ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
char buffer[40];
/* eliminate 'unreferenced' warnings */
link_instance = link_instance, apinfo = apinfo;
cbinfo = cbinfo;
/* Note: Returning Pt_END in a prerealize setup
function tells PhAB to destroy the module
without realizing it */
/* allow only 5 windows max */
if ( win_ctr == 5 ) {
return( Pt_END );
}
/* save window-module instance pointer */
win[win_ctr] = link_instance;
sprintf( buffer, "Window %d", win_ctr + 1 );
PtSetResource( win[win_ctr], Pt_ARG_WINDOW_TITLE,
buffer, 0 );
win_ctr++;
return( Pt_CONTINUE );
}
Now let's modify the color_change() function so that:
- pressing a Red, Green, or Blue button changes the rectangle color
to the button color
- pressing the Change Previous Window Color button changes the
background of the previous window to a color from an array.
|
If this were a dialog module you could use the ABW_color_rect manifest
to update the color of the rectangle. However, because these are
window modules, you must use the instance pointer for the window
in which the button is being pressed. |
To get the instance pointer of a widget in the current window,
you need to call:
- ApGetInstance() to get a pointer to the window that contains the widget
that invoked the callback
- ApGetWidgetPtr() to get a pointer to the widget with a given ABN_... manifest.
If only one instance of the window were guaranteed, the following
would work:
PtSetResource( ABW_color_rect, Pt_ARG_FILL_COLOR,
buffer, 0 );
But in this case color_change() has to use:
PtSetResource( ApGetWidgetPtr( ApGetInstance( widget ),
ABN_color_rect ), Pt_ARG_FILL_COLOR,
buffer, 0 );
So you need to change color_change.c to look like:
PgColor_t colors[5] = {Pg_BLACK, Pg_YELLOW,
Pg_MAGENTA, Pg_CYAN,
Pg_GREEN};
int base_clr = -1;
extern int win_ctr;
extern PtWidget_t *win[5];
int
color_change( PtWidget_t *widget, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
int i, prev;
PtWidget_t *this_window;
/* eliminate 'unreferenced' warnings */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;
/* Get a pointer to the current window. */
this_window = ApGetInstance( widget );
if ( ApName( widget ) == ABN_btn_red ) {
PtSetResource(
ApGetWidgetPtr( this_window, ABN_color_rect ),
Pt_ARG_FILL_COLOR, Pg_RED, 0 );
} else if ( ApName( widget ) == ABN_btn_green ) {
PtSetResource(
ApGetWidgetPtr( this_window, ABN_color_rect ),
Pt_ARG_FILL_COLOR, Pg_GREEN, 0 );
} else if ( ApName( widget ) == ABN_btn_blue ) {
PtSetResource(
ApGetWidgetPtr( this_window, ABN_color_rect ),
Pt_ARG_FILL_COLOR, Pg_BLUE, 0 );
} else if ( ApName( widget ) == ABN_btn_prev ) {
/* Note: Here we use the window-module instance
pointers saved in newwin_setup to update
the window previous to the current window
provided it hasn't been closed.
Determine which window is previous to this window. */
prev = -1;
for ( i = 0; i < win_ctr; i++ ) {
if ( win[i] == this_window ) {
prev = i - 1;
break;
}
}
/* If the window still exists, update its background
color. */
if ( prev != -1 && win[prev] ) {
base_clr++;
if (base_clr >= 5) {
base_clr = 0;
}
PtSetResource( win[prev], Pt_ARG_FILL_COLOR,
colors[base_clr], 0 );
}
}
return( Pt_CONTINUE );
}
Last of all, you need to modify newwin_close() so
that it sets the win array of instance pointers to NULL for
a window when it's closed. That way, you can check for NULL in
the win array to determine whether the window still
exists.
Modify newwin_close.c as follows:
extern int win_ctr;
extern PtWidget_t *win[5];
int
newwin_close( PtWidget_t *widget, ApInfo_t *apinfo,
PtCallbackInfo_t *cbinfo )
{
PhWindowEvent_t *we = cbinfo->cbdata;
int i;
/* eliminate 'unreferenced' warnings */
apinfo = apinfo;
/* only process WM close events */
if ( we->event_f != Ph_WM_CLOSE ) {
return( Pt_CONTINUE );
}
/* okay it's a close so who is it? */
for ( i = 0; i < win_ctr; i++ ) {
if ( win[i] == widget ) {
win[i] = NULL;
break;
}
}
return( Pt_CONTINUE );
}
- Make and run the application.
- From the application's File menu, choose New several times
to create multiple windows. You'll see each window's relative number
in its titlebar.
- Click a color button to make the rectangle change color.
Then click the Change Previous Window Color button in any window
to change the background color of the previous window.
Warning: main(/www/www/htdocs/style/footer.php) [function.main]: failed to open stream: No such file or directory in /www/www/docs/6.4.1/photon/prog_guide/tutorls.html on line 1783
Warning: main() [function.include]: Failed opening '/www/www/htdocs/style/footer.php' for inclusion (include_path='.:/www/www/common:/www/www/php/lib/php') in /www/www/docs/6.4.1/photon/prog_guide/tutorls.html on line 1783