[Omnis-Newsletter] Omnis Technical Newsletter

omnis-news-admin@omnis.net omnis-news-admin@omnis.net
Wed, 3 Apr 2002 17:05:58 +0100


 April 3rd, 2002

========================================

UNSUBSCRIBE OPTIONS: You have been sent this email because you have directly
signed up for, or expressed an interest in receiving a technical newsletter
when you downloaded an evaluation of Omnis Studio, or registered the Lite
version of Omnis Studio. If, however you feel you have received this email
in error you can unsubscribe as well as change your subscription options at
www.omnis.net/newsletter.

N.B.  If you subscribed by checking a box on one of our forms, you will not
have received a password. You will need to submit your email address at
www.omnis.net/newsletter and select the 'email me my password' option on the
next page in order to receive this.

========================================

WELCOME!

Welcome and thank you for subscribing to the Omnis Technical Newsletter.
Published fortnightly, it is intended for Omnis developers of all levels and
experience, for those people evaluating Omnis Studio, or for developers
moving from a similar tool. We think you'll find the content both
interesting and useful for your Omnis development needs and hopefully it
will help you become more productive in Omnis application design.

In the first article in this newsletter, Geir Fjaerli continues his tutorial
by showing you how to create a report for the Employee/Tasks application
using a Report Wizard in Omnis. In the second article, David Swain discusses
the Omnis Icon Editor and describes how you can add and store icons in your
Omnis applications. You may find it easier to work through the exercises and
examples in this newsletter by printing it out before you begin.

CONTENTS:
-About the Authors
-Building part 20: Our first report, by Geir Fjaerli.
-Developer Resources on the Omnis web site
-Icons and the Icon Editor, by David Swain
-Copyright and Unsubscribe details


========================================

About the Authors

The Omnis Technical Newsletter contains high quality content from two
leading and well respected Omnis developers, Geir Fjaerli and David Swain.

Geir Fjaerli is based in Norway and has been an Omnis professional developer
for many years as well as a Regional Sales Manager for Omnis. He is
currently working freelance again developing a range of products (in Omnis
of course) including his Prophet5 sales and customer relationship management
solution, now available for Mac OS X. Geir is a regular contributor to the
annual Omnis Developer conferences in the US and Europe, speaking about
Object-Oriented programming in Omnis and SQL development, amongst other
things.

David Swain is the founder and president of Polymath Business Systems, for
many years a leading provider of Omnis training. His expertise in Omnis
programming and his ability to make complex concepts understandable are
recognized throughout the worldwide Omnis community. Latterly, David has
appeared at Omnis Developer conferences providing his own Studio 101
introductory course to Omnis programming and application development.


========================================

Building part 20: Our first report.
By Geir Fjaerli, Sunshine Data
Email: geir@sunshinedata.net
Web: www.sunshinedata.net

Hi, and welcome back to our Omnis Studio tutorial.

Here is our work so far:
Part 1: Hello World, our first little Studio application
Part 2: The Studio Classes. The classes are the building blocks of an
application, and include windows, reports, menus etc.
Part 3: The Omnis Integrated Development Environment. Here we looked at the
Component store, the Property Manager and the Catalog.
Part 4: The Data Structure. Including basic terminology.
Part 5: Creating schemas and database tables.
Part 6: Adding table classes and using our schemas in application windows.
Part 7: What did the wizard build, and a tour of the method editor.
Part 8: The logon window and object class.
Part 9: The task window.
Part 10: The task window continued.
Part 11: Designing a proper data entry interface.
Part 12: Implementing the data entry interface.
Part 13: Implementing the data entry interface, part 2.
Part 14: Implementing the data entry interface, part 3.
Part 15: Implementing the data entry interface, part 4.
Part 16: Implementing the data entry interface, part 5.
Part 17: Toolbars and menus.
part 18: Toolbars and menus, part 2.
Part 19: Toolbars and menus, part 3.
You should have those handy, and your "tasks.lbs" library file.

As usual, I strongly suggest that you refer to these parts if you haven't
already, or if you feel uncertain about the details. From part 5 onwards,
each new part will be based on programming done in previous parts, so you
have to follow them all. (For back issues, please go to
www.omnis.net/newsletter and click on the Newsletter Archive link.)

WHERE ARE WE?
In the last issue we implemented our main toolbar and the window "commands"
toolbar. That completes our task window for now.

CORRECTIONS.
Before we continue, let me clear some errors from the previous issues. In
the last issue about toolbars and icons I wrote:
"Personally, I prefer to store custom icons in the #icons table of my
library. The main disadvantage of this approach is that the icons will only
be visible to this library, so if you have multiple libraries they will each
need a separate copy of any common icons."

Paul Smyth spotted and reported my error here. #ICONS (note the spelling
should be upper case as well) can in fact be shared by other libraries. The
way to do it is to set the $iconlib property of the "client" library to
point to an open library containing the icons you want to use. So if you
have two libraries, MyMainlib and MyIconlib, and you want MyMainlib to use
icons from MyIconlib, then open the Property Manager for MyMainlib and
select the Prefs tab. Set the iconlib property to MyIconlib. You can also do
this notationally.

Then my good friend Kelly Burgess reported that in issue 18, after creating
the new tSession task variable and then doing a find and replace, the old
iSession instance var was renamed as well, and now both vars had the same
name, (which is not good.) Then he was not able to delete the instance var,
because the methods still linked to it. Not sure why that didn't happen to
me. Obviously the trick here is to rename everything except the instance
var. You can do that by Deleting the line from the Find and Replace log and
then check "Replace all in selected log lines only".

Thanks to Paul and Kelly.

REPORTS.
Today we are going to take our first look on the reports in Omnis. Reports
are a critical part of almost any application, even in the so called
"paperless" society. Imagine a sales system that cannot print an invoice. Or
an accounting system that cannot produce the masses of paper that the IRS
and your auditors want. Also, a report isn't just something that is printed
on paper, Omnis reports can be sent to file, generated as HTML to be viewed
over the Internet, and so on.

We are going to start with the normal list type report, which can be sent to
your printer or to screen. To get a quick start and produce something that
actually works and gives us something to look at, we are going to use a
wizard to produce this first report, just as we did with the Employee
window.

The first report will also be based on the Employee table. So to prepare for
today's work, start Omnis and the Tasks application. Open the Browser to
show the classes of the application and the Component Store.

As discussed earlier, the Component Store is divided in two parts. Assuming
you still use the default horizontal small icons view, the top half will
show the various groups, e.g. windows, reports, menus and net classes, while
the bottom shows the classes, templates and wizards for the selected group.
To add a new report using a wizard, select the fifth group, which is Report
Classes. Here you will find three icons. One is an empty report template,
used to build a report from scratch. The two others are report wizards that
build a report class for us, based on our input, one for native Omnis data
and one for SQL.

Our application is built on SQL, so select the third icon, the SQL Report
Wizard. Drag it into the Browser, name it rEmployee and hit Return to start
the wizard. The class wizard starts, displaying the first step in the report
creation process.

ROWS OR COLUMNS?
This step is to decide if we want a Rows or Columns based report. The
difference is the orientation of the fields on the report:

"Columns" has the labels on top of the page, and then the fields as columns,
and records as rows:
First name Last name
Geir Fjaerli
Peter Pan

"Rows" has one line per field, with the label in front:
First name: Geir
Last name: Fjaerli

First name: Peter
Last name: Pan

For this first exercise, select Columns. Then click Next.

SELECT FIELDS
The next step is to select the fields to include. The report wizard only
allows us to select fields from one table, if we want a multi table report
we must build it ourselves. Check the checkbox for sEmployee in the tree
list. This will include all the columns of the Employee table. You can also
expand the sEmployee node and select individual columns if you do not want
all of them. Click Next again.

SELECT TASK
Next step is to select the session to use for this report. Unless you have
been doing stuff on your own, there is only one session to use, so check the
TASK session checkbox. Click Next.

CREATE REPORT
This was in fact the last step of the wizard, it is now ready to build the
report for us. So now click the Finish button. The report is fairly simple,
and should be ready almost as soon as you click the button.

While we have no menu option to print the report from yet, you can test it
by right-clicking the report class in the Browser and selecting Print
report. Before you do that, you may want to verify the current report
destination. The standard File menu has a menu item called Print
Destination, which currently may show 'Screen', unless you have already
changed it of course. Select it to open the Report Destination dialog.

This will show an icon view with all the available destinations, which
includes:
Printer: send report to the currently selected printer.
Preview: Show a report page on screen scaled to show the full page
Screen: Send the report to screen.
And so on. Some of the destinations have additional parameters, like file
name for reports printed to disk. Note that these parameters also can be
assigned dynamically using notation, though that is beyond the scope of this
tutorial.

After you have test printed your report, close it if it was printed to
screen.

THE REPORT LAYOUT.
Now it is time to look how an Omnis report looks. Double-click the report
class in the Browser to open the report editor.

You will notice that the window is grey, with a white area divided by
horizontal grey bars. These grey bars are called sections, and is how Omnis
reports are structured. This is different from a word processor or page
layout program. In PageMaker you place your objects on the "actual" page.
What you see is what you get.

A report editor like the one in Omnis, on the other hand, is aimed at
repeated data, like a product list or phone directory. A page may have 50
phone entries, and you don't want to have to position those fields 50 times.
Instead you say "I want the first phone entry to start in this position, and
then repeat as many times as there is room on the page."

THE SECTIONS.
So let us look at our new report. As we can see, it is divided by four
sections:
Report heading: This is printed once on the first page of the report, like
the title on a book.
Page Heading: This is printed on top of each page.
Record: This is the "repeating" section, printed for each record of data.
End of report: This marks that there are no more report elements following
it.

There are other sections as well. Usually they are added by setting the
appropriate section property to true in the Property Manager. This makes
sense since their order is fixed. Click the white space in the report to
deselect any selected report components, and open the Property Manager. As
you can see, you can have up to nine levels of subtotals, each with a
corresponding subtotal header, as well as a grand total and a page footer.

One section is special. The Position section is added from the Component
Store, since it can be placed anywhere in the report. We shall not discuss
this section in the tutorial.

A section has a number of properties to decide its positioning on the page.
You can say that a Record section should always follow the previous section,
or always start a new page if you want one record per page. Do you want the
page heading on the first page. Etc.

FIELDS AND LABELS.
Once you are familiar with the sections, take a look at the fields and
labels. The Report Heading has a single label that says "Report for
sEmployee". This will be printed once on the first page.

Next is the Page header. Since we chose to make a columns report, it
contains the labels for the data columns, and is printed on the top of each
page.

Next is the Record section. This is repeated down the page for as long as
there are more records to print, and continues on the next page(s) if
needed. Since we have no other sections, the space between it and the End of
report section defines the height of each record. By moving the End of
report section up and down, we can adjust the space between each record. (A
more precise way is to set the record spacing property for the report, and
then turn on userecspacing for the section.)

In the Record section we find the actual data fields. Click on the first one
and look at its dataname property. It reads iSqlData.cID. The report has its
own methods and variables that it uses to print itself. We shall look at
this in a moment.

REPORT FIELD PROPERTIES.
Each field on the report has properties as well. Some are familiar by now,
some are special to report objects. For instance the $nolineifempty property
prevents Omnis from printing blank lines if there is no data for a given
record. Say for instance an address label with three post address fields and
the city and zip code. If two of the address fields are empty, Omnis will
move the city and zip up so that there is no white space between in the
address.

Another is "duplicates blank", which prevents Omnis from printing repeated
values more than once. So if you have the following table:
Pan Peter
Pan Mary
Pan George
Smith John
Smith Joe

It will print as:
Pan Peter
Mary
George
Smith John
Joe

Yet another will print zeros as blanks, so you only see the non zero values.

One thing to be aware of is that Omnis reports show a line-based heritage.
Omnis appeared before the first laser printer, and still some applications
use non-graphical printers. If you try to move one of the report fields up
or down, you can see that it moves by a whole line. You can override this by
setting the $floating property to true.

Note also that report fields unlike window equivalents do not have any
background. If you want a background color, you have to add a rectangle to
the report behind it.

REPORT PROPERTIES.
The report itself has a number of properties. These include among others:
Margin properties.
Label properties. Print labels. e.g. 3x8 labels per page.
Export format. Print your report to file as comma or tab separated, or other
formats.
Page setup. Orientation, scale, number of copies...

Note that these properties can be controlled at runtime, which allows for
very powerful functionality. You can force data to be printed at given
places on a page, print some pages in portrait and some in landscape mode
etc. Most of this is beyond the scope of this tutorial. If you are
interested in reports, I strongly recommend my co-author David Swain's
report training classes. Check his training offerings at
www.polymath-bus-sys.com.

THE REPORT METHODS.
We were able to print the report without creating any code. The wizard
created that for us. And all that code is placed inside the report itself.
To edit the methods, double-click the report in the report editor or
right-click and select Class Methods, just as you do for window classes. The
familiar method editor opens.

Select the $construct method. It contains the following code, most of which
should be familiar to you by now:

  Set current session {TASK}
  Do iSqlData.$definefromsqlclass('sEmployee')
  Do iSqlData.$select()
  Do iSqlData.$fetch() Returns lStatus
  While lStatus=kFetchOk
    Do $cinst.$printrecord()
    Do iSqlData.$fetch() Returns lStatus
  End While
  Do $cinst.$endprint()

This method uses an instance row var called iSqlData to fetch data from the
database. As you can see it is defined from sEmployee. We could have used
tEmployee instead, but it doesn't really matter here. Then it does a Select,
which basically selects all rows in the Employee table.

Next it tries to fetch a record, and if it gets one, then it enters the
print loop. It does

  Do $cinst.$printrecord()

which prints the record, and then it goes on to fetch the next one. When
there are no more rows to print, it does a $endprint().

That is all the code there is. But we could have more. Each section and each
field on the report can have its own method. So a field could calculate its
own value, or move itself around to a given position on the page, and so on.
To do this, add a $print method to the field/section, and add you custom
code there. $print is called every time a report component is printed.
Remember that you are in effect overriding the built in $print, which
actually prints the component on the page. So you must add a "Do default" to
your method, or else the field will not print.

Feel free to play around with the report a bit, to see what the various
properties do. Also, you may want to improve the layout a bit, e.g. replace
the labels in the Page heading. You can do whatever you like to this report.
If you manage to ruin it beyond repair, you can always delete it and go back
and run the wizard again.

REPORT COMPONENTS.
Before we close our report, let us take a look in the Component Store to see
what kind of components are available in a report.

The Component Store has four groups of report components: Report fields,
Background objects, External components and Background components.

The Report fields contain the Entry field, Picture field and the Positioning
section.
The Background objects include various lines, shapes and text objects.
The External components include GIF, JPEG and RTF controls, a control that
prints Omnis Graphs and a set of HTML controls, etc.
And finally the Background components group contains String labels.

When you are done, close the report editor. Now we shall add our report to
the Main menu.

PRINT FROM THE MENU.
Go back to the Browser and open mMain in the menu editor. Add a menu item
called "Print employees". Tip: Click on the separator line between Employees
and Log Off (if you have got one) and hit Return twice. This will give you
two new separators and move Log off down.  Click on the middle separator and
type the name of the new menu item.

Now open the method editor for the new menu item. (Double-click or
right-click and select line methods.) This will open $event for the menu
item.

The method is really simple, one or two lines, depending on whether you want
to prompt for destination. And then maybe you want to start the method with
On evClick, though as I have said before, that is optional since menu lines
only take click events. The methods then looks like this:

  On evClick
    Prompt for destination
    Do $clib.$reports.rEmployee.$open('*')

First prompt for destination, then "open" a new instance of the report
class. When it is opened, $construct is triggered, and the report takes care
of itself from there on.

Remember that you have to remove and reinstall the menu for the changes to
the layout to take effect.

So that was our first report. That wasn't so bad? The next one will be a bit
more complicated, as we have to print both the task and the employee for
that task.

That's it for today. See you again soon.

Take care!

Geir :)


========================================

Developer Resources on the Omnis web site

The Omnis web site has a number of resources for developers to help you in
your application development, including technical notes and white papers.

   -Information Notes cover general issues of interest to most Omnis
developers.
   -Tech Notes section offers a range of technical documents on all kinds of
Studio topics, from the IDE to Notation to Web Client and Server deployment;
there are several new ones added recently.
   -White Papers discussing Omnis Studio 3.0, and using Studio as a
prototyping tool.
   -Conversion Tools for converting your Omnis 7 libraries to Studio.
   -FAQs about how Omnis Studio differs from Omnis 7, Omnis Studio for
Linux, and more.

To view the Developer Resources, visit:
www.omnis.net/develop/resources


========================================

Icons and the Icon Editor
By David Swain, Polymath Business Systems Inc
Email: dataguru@polymath-bus-sys.com
Web: www.polymath-bus-sys.com

------------------------------------------------------------------

Many components within an Omnis Studio application can display an icon. Most
icon-bearing elements are controls (pushbuttons, toolbar tools, tabs on tab
panes, etc.), but even static text blocks can contain icons within a line of
text. We can also transfer icon images into picture variables for certain
special uses. Icons are visual shortcuts that identify the use of an object
in lieu of or supplemental to labeling text. There are also special icons
used for the mouse pointer (mouse cursor) that indicate the "current
context" for the mouse.

Objects that can display icons contain "iconid" properties (sometimes more
than one, with slightly different names, for the same object) that can be
set using the Property Manager or notation. An "iconid" property has two
parts: the ID number of the icon slot itself and a size modifier. There are
three sizes of icon used by Omnis Studio (excluding mouse cursor icons and
standalone icon pages to be discussed later in this article): 16x16 pixels,
32x32 pixels and 48x48 pixels. Each icon may have a "default size" assigned,
but can still be used at the other sizes. The use will often dictate the
appropriate size for an icon, or at least the proper default size.

When assigning an icon to an object using the Property Manager, we are
offered a view of the contents of an icon store associated with our copy of
Omnis Studio through which we can browse to select an appropriate icon.
Clicking on the "iconid" property value opens an "icon browser" that allows
us to select an icon store and flip through its pages.

Omnis Icon Stores

There are three sources of icons for an Omnis Studio application: the
omnispic.df1 icon datafile associated with the copy of Omnis Studio
currently running, the userpic.df1 icon datafile (also associated with our
copy of Omnis Studio), and the #ICONS System Table of the currently open
library. (There are also some built-in mouse pointer icons that are not
associated with any of these stores but are kept within resources of the
Omnis Studio program itself. We will ignore them for this discussion.) An
icon from any of these sources can be applied to an icon-bearing component
object.

The first two sources are native Omnis datafiles kept in a special directory
named "icons" tucked inside the Omnis Studio directory on our hard drive.
These are among the many "auxiliary files" that ship with Omnis Studio.
Studio does not recognize other icon datafiles if we try to introduce them.
(The path to these icon sources is hard-coded into the Omnis Studio program
itself, apparently.) The third source is stored within each library file.
The use of each icon store is as follows:

Omnispic.df1 Datafile

The "omnispic.df1" datafile contains all the icons used internally by Omnis
Studio. This includes the icons used for radio buttons and checkboxes (for
each supported platform) and all the icons used for the tools of the
Integrated Development Environment (IDE). This icon store should not be
modified (as it is important to the proper operation of Omnis Studio as it
stands), but we can still open it with the Icon Editor for reasons that will
become clear later in this article.

Userpic.df1 Datafile

The "userpic.df1" datafile is actually a converted copy of the "old"
omnispic.df1 datafile from Omnis 7 (the previous generation of the Omnis
product line for you newbies), so it contains legacy icons from earlier
incarnations of Omnis.

In "The Old Days" there was only this one icon source for an application, so
any custom icons were included with those Omnis needed internally. 48x48
pixel icons were only used by some applications that Blyth Software tried to
sell for a while, so most pages in "userpic.df1" don't support that size.
Also, the classic Omnis 7 era predates transparency support so no
transparent colors are defined for "userpic.df1" pages.

Omnis Studio icon stores have a slightly different format from those of
Omnis 7. This means that people who wish to convert old Omnis 7 projects
that include custom icons need to convert their old omnispic.df1 file to the
new Omnis Studio icon file format, rename the file as "userpic.df1" and
replace the one that ships with Omnis Studio. But there is another option
for storing custom icons available in Omnis Studio...

#ICONS System File

Each library in Omnis Studio contains a System Table class named "#ICONS".
It is empty when a library is newly created. If custom icons are required
for a specific project, this is the best place to put them. A major reason
for this is that these icons are stored with the library, so anywhere the
library is deployed, our custom icons are already there.

A major hassle with storing custom icons in the "userpic.df1" file is that
each update to Omnis Studio replaces this file with one that does not
contain our custom icons. Updating to a new version of Omnis Studio will not
affect any icons stored within the #ICONS System Table of a library, so
there is no need to train end users to avoid overwriting the "userpic.df1"
file.

Another advantage of the #ICONS System Table is that it can be copied from
library to another like any other class. It can also be checked into the
Omnis Studio Version Control System for even easier access and control.

But there is another reason to put custom and commonly used icons into
#ICONS...

Order of Icon Search

The #ICONS System Table of the library to which a class belongs is searched
first when an object in that class requires an icon. This makes sense since
the library file is already open and searching elsewhere will take more
time. If Omnis Studio does not find the required icon ID in #ICONS, it
searches next in "omnispic.df1" (which is where the majority of its
internally used icons are located). Only after searching through these first
two sources does it search the "userpic.df1" file. Although some would argue
that the lag time is minimal, locating custom icons in "userpic.df1" is
measurably slower than locating custom icons in #ICONS.

On the other hand, icons stored in "userpic.df1" are available to ALL
libraries from a single source, so they might be more appropriate for
multi-library deployments. It's your choice...

So Why Do They Let Us Edit Omnispic,df1?

There is nothing but a warning from Raining Data and common sense to keep us
from modifying our copy of the "omnispic.df1" icon store. So why do they let
us even open it? My best guess (I admit that I have not asked anyone) is
that this allows us to COPY existing icons from it to either create modified
versions of them or to safely tuck those we need into our libraries and
remove dependence on the "omnispic.df1" file for our deployed applications.
As we have seen, there may be a slight speed advantage to doing this, but it
can also simplify our final deployment.

Accessing the Icon Editor

But we came here to discuss the Icon Editor, so let's get to it! The Icon
Editor is available through the "Tools" menu of the Omnis Studio IDE and the
associated IDE toolbar (the "paintbrush" icon). It is also accessed by
double-clicking on the #ICONS System Table in the Class Browser.

Open the Icon Editor to follow along as we explore how icons are stored and
manipulated by Omnis Studio. You will notice that the Icon Editor window has
optional Menu, Tool and Status Bars that are visible by default. The rest of
the window is structured as follows:

The image for the current icon is displayed in detail and can be modified in
a box in the upper left corner of the window. The icon to be so displayed is
selected from icon image slots in the upper right of the window. This
displays all the image slots for the current icon page in the current size
(which is only an issue for "Basic" style icon pages where size matters).

The lower left corner of the Editor window displays the current icon in all
supported sizes on "Basic" (and "Multistate" and "Working") icon pages, but
only an empty rectangle for "Cursor" and "Standalone" pages. (These page
types are explained below.)

The lower right corner of the Editor window contains a list that allows us
to select which icon page to view from those in the currently open icon
source.

Of course, all of this will be empty if no icon source is open. If we opened
the Icon Editor by double-clicking in the #ICONS System Table in the Class
Browser, the title of the Editor window will be "Icons - Library " followed
by the internal name of our library - and we will be viewing the contents of
the first icon page within that icon store (if one exists). If we opened the
Editor by any other means, no icon store is automatically opened, so we must
choose one.

Opening an Icon Store

The "File" menu of the Editor window offers us some options. The two of
interest to us right now are "Open Icon File..." and "Open #ICONS". The
"Open #ICONS" option offers a submenu that lists all currently open
libraries (including the Component Library if we have opened it for
modification). Since these libraries are probably devoid of custom icons for
most readers, we will skip this option for now.

As the ellipsis suggests, the "Open Icon File..." options opens a file
selection dialog that allows us to navigate to an icon datafile. We should
make sure we are editing one associated with our currently open copy of
Omnis Studio (just in case we have more than on copy installed on our
computer). This allows us to open either "omnispic.df1" or "userpic.df1",
both of which can be found in the "icons" directory inside our main Omnis
Studio directory. For purposes of exploration, open the "omnispic.df1" file.
A list of icon pages should appear in the lower right corner of the Editor
window with the "Classes" icon page selected. The upper right corner of the
window should display twenty icon images with icon number 1700 shown in
detail in the upper left. In the lower left, three boxes should be visible
displaying different sizes of this icon. The 32x32 size should be empty and
grayed out, the 16x16 and 48x48 sizes should have images and the 16x16size
should be highlighted to indicate this is the currently displayed size.

By the way, the "File" menu of the Editor window should now show the path to
"omnispic.df1" at its bottom. The most recently opened icon stores can also
be accessed in this way.

Icon Pages

Within an icon store, clusters of icons are kept on "icon pages". Icon
images are associated with an "icon ID" number that must be unique among the
three icon stores. There is a "main" icon ID that we directly assign to an
icon slot, but the "real" icon ID is a combination of the assigned ID number
and a long integer that indicates the size of the icon. Each icon slot can
therefore "contain" up to three images associated with the "same" ID number.

Each page has properties that affect all the icons stored within it. For
example, the type of icon page determines how Omnis Studio deals with them
and, to some extent, how many icon Ids are likely to be stored on that page.
The page also determines how many sizes each icon stored on it can have.
This in turn determines how much storage space is required for the page.
When an icon page is first created, blank icons are created for each icon
slot on the page.

Icon Page Types

Icon pages come in four flavors: Basic, Multistate, Cursor and Standalone.
We can also use a collection of icons from a Basic page as a series of
"animation cells" for working message windows. (More on this later!)

Here is a brief description of the possible icon page types and what they
contain. Later in this article we will examine how to create and populate
each of them:

Basic

A "Basic" icon page is the most common type. This is the type of the
"Classes" page we are currently viewing. It can store up to 20 icon Ids in
up to three standard sizes. For this type of icon page, we specify what
sizes we want the page to support, which, in turn, determines how much
storage space is required for the page.

When we add support for a size, a blank icon image in that size for each
potential icon slot is created. This is true whether or not any icon IDs
have been assigned to the page. On the other hand, if we remove support for
a size, that size icon is removed for all icon slots on the page, whether or
not any images existed in those cells. The amount of storage required for an
icon page is directly determined by which icon sizes it supports.

To see which sizes are supported for a specific icon page, open that page in
the Editor and pull down the "Page" menu. There are three items in this menu
labeled "16x16 Support", "32x32 Support" and "48x48 Support". A check mark
will appear next to each supported size. To add support for a size not yet
supported, just select that menu item. To remove support for a supported
size, just select it again. Selecting a "checkable" line toggles it. Items
in this menu apply to the current page.

To view the current page in a different supported size, pull down the "View"
menu of the Editor window. There are three items at the top of this menu
labeled "Page as 16x16", "Page as 32x32" and "Page as 48x48". Unsupported
options are grayed out and a check mark appears next to the currently
displayed size. To display a different supported size, just select it from
the menu. The window will be redrawn to reflect this change of view. We can
also toggle the display of icon Ids on the grid in the upper right by
selecting the "Show IconID" item from this menu. Items in this menu apply to
the Editor window in general, except for the "Page as" items which reset as
we go from page to page.

Icons have a "default size" which is automatically used if no size is
specified when an icon ID is given for an "iconid" property. This is set
using the "Default to " items in the "Image" menu. Items in this menu apply
to the currently selected icon ID.

There are other options for "Basic" icon pages we will explore later. But
one of the more important of these is "Multistate Support" from the "Page"
menu.

Multistate

A "Multistate" icon page is actually a special case of a "Basic" icon page,
not a separate type. It contains the same number of icon image slots, but
the arrangement is more structured. In its most common form, it can store up
to 4 icon Ids in up to three sizes, but each icon ID also has five "states"
for a total of twenty icon image slots per size. We create a "Multistate"
icon page by first creating a "Basic" icon page and then turning on
"Multistate Support" for it.

The five "states" are known as "Normal" ("Collapsed" for a tree list node),
"Checked" ("Expanded" for a tree list node), "Hilited", "Checked and
Hilited", and "Checked, Hilited and Grayed". These are used by multistate
controls like radio buttons and check boxes. The first two are also used by
the "Expand/Collapse" node icon of a tree list field as indicated above.

Cursor

A "Cursor" icon page stores up to four icon Ids, but also four styles for
each of four platforms - but these may not be the platforms you would think.
Omnis Studio still supports cursors for archaic systems on which it may
still be deployed (black&white Macintosh and 16 bit Windows machines) and
these take up space on a "Cursor" icon page. The styles are as follows:

16 B/W

This style is for MacOS in black and white mode. Such icons are 16x16 pixels
in size. When creating them, only use the colors black and white. We can
also use a transparent color if we have set one for the page.

16 Color

This style is for MacOS in color mode. This is the standard mode for modern
Macintosh systems. Icons are still 16x16 pixels in size, but can contain any
colors in the palette.

32 B/W

This style is for 16 bit Windows systems. Like the archaic MacOS systems
mentioned above, only black and white pixels should be used for these icons
(plus the transparent color if one has been set for the page), but the icons
are 32x32 pixels in size.

32 Color

This style is for normal 32 bit Windows systems. The icons are still 32x32
pixels in size, but can support any colors in the palette.

Each icon image on a "Cursor" icon page must contain a "hot spot". This is
the pixel location on the icon that determines where the cursor is
considered to be "located" when an action like a click occurs. By default,
the hot spot is located in the upper left corner of the icon, but it should
be moved to a more appropriate location on the image (where the image seems
to "point").

We use "Cursor" icons when we want to show a special "context" for the
mouse, such as being over an entry field as opposed to over a pushbutton.
Omnis Studio does some of this "context indication" for us automatically,
but we can use custom cursors to control this directly if we wish.

Standalone

A "Standalone" icon page stores a single picture of any size and associates
it with an icon ID. Such icons would not normally be assigned to the
"iconid" property of a control or as the icon image for a mouse pointer, but
can be retrieved and converted into a picture using the $getpict() function
of the OmnisIcn Library extension.

This is a convenient place to store commonly used graphic images for use
within an application. Examples of candidates for this type of storage
include company logos, accentuating graphics for windows, remote forms and
reports, and other commonly used images.

The advantage of storing such images in this way instead of pasting them
onto the background of GUI classes is that they are easier to maintain since
they are stored in one place. The advantage of storing them in #ICONS
instead of in the database itself is that they are more immediately
accessible when needed rather than requiring a separate trip to the
application's data source.

Working Dialog Images

We can also store a series of related images in a "Basic" icon page that can
be used as "animation cells" for a working message display. While this is
not a separate "type" of icon page, it is a specialized use - and one that
bears closer examination later in this article. Icons used for this purpose
don't necessarily have to be on the same icon page (although that would be a
wise move!), but they must be in sequential icon ID order with no "outside"
icons intervening.

Icon Size Options

Omnis Studio supports icons on a "Basic" (or "Multistate" or "Working") page
in three well-defined icon sizes: 16x16 pixels, 32x32 pixels and 48x48
pixels. (Standalone pages are a special case where the single "icon" on the
page can be a picture of any size. Cursor pages are also special in that a
specific combination of 16x16 and 32x32 icons are always stored there.) The
different sizes have common uses with certain components.

For example, 16x16 icons are used for toolbar buttons, pushbuttons, tree
list node icons and the "small" view of icon array components (like in the
Library and Class Browsers). Radio button and checkbox components also use
this size for the non-text part of the control.

32x32 icons are a good size for node icons in hierarchical tree lists, like
the Field List window for a Window Class.

48x48 icons are used for such things as sidebars and the large view of icon
arrays. The "Report Destination" dialog window also uses this icon size.

Icon Size Constants

We specify a size for an icon when we assign an "iconid" property by adding
the base icon ID to an Icon Size constant. This generates a unique internal
ID number for each variant of an icon ID. There are four such constants:
k16x16, k32x32, k48x48 and kDefault. The first three have large integer
values. kDefault has a value of zero, so adding it essentially does nothing
to the base icon ID. While the numbers chosen for these constants are
interesting (basically 2^28 times an offset), it is only important to know
that there is a large enough difference between them that we can have
millions of icon ID numbers in our applications in all three sizes without
fear of ID number conflicts as long as our base ID numbers are unique.

For custom icons, the manual suggests beginning with the number 10000 and
incrementing this by 100 for each additional icon page. Since only twenty
icon IDs can be used per page, we could get away with only incrementing the
initial icon ID by 20 for each additional page if we choose to use
sequential ID numbers.

Basic Features of the Icon Editor

Unlike most other work areas in Omnis Studio, there just isn't enough room
to have toolbar elements representing the majority of the menu options of
the Icon Editor's menus AND the many drawing tools as well, so the menus for
the Icon Editor offer a separate set of options from its toolbar. There is
very little overlap.

Icon Editor Menus

The menu options of the Icon Editor primarily deal with managing icon store
pages or overall properties of the selected icon. There are four menus:

File

This menu is used to manipulate the current icon store, including opening,
closing, saving and reverting the icon store. There are two types of icon
store recognized by this menu: icon datafiles and #ICONS System Tables.

There is also an option to create a new icon datafile. Since Omnis Studio
cannot use other than the two supplied with it ("omnispic.df1" and
"userpic.df1"), one might ask why we would create a new one. There is at
least one simple answer: we can use one as a master development icon
repository - a place to put ALL custom icons for ALL projects. We would not
deploy such a monster icon datafile, but we could use it to retrieve
favorite icons from past projects into new ones.

The "File" menu also contains an item titled "Convert Old OmnisPic Into
IconFile". This performs the operation it describes, which is thoroughly
detailed in the "Using Omnis Studio" manual.

Page

This menu is used to set properties for an entire icon page as well as to
create new pages and rename, resize and delete existing pages.

Image

This menu is used to set properties of the currently selected image,
including its icon ID number.

View

This menu is used to manage the Icon Editor window, including which size
icon to display for pages that support multiple sizes.

Icon Editor Tools

The tools offered on the Icon Editor toolbar are almost entirely devoted to
manipulating "internal" aspects of the selected icon. This includes drawing
tools, a "hot spot" tool, a tool for toggling a grid on the image detail
area and tools for zooming into and out of large "Standalone" images. There
are a few tools that overlap certain menu options ("Open", "Close" and
"Save" from the "File" menu and "Clear Image" and "Fill Image" from the
"Image" menu), but otherwise these tools are entirely independent of the
menus.

We will detail these tools and menu items while creating a few new icon
pages for practice.

Creating a "Basic" Icon Page

Let's begin by creating a new checkbox icon for printing on reports. We
already have a reasonable candidate in our "userpic.df1" file (icon ID
number 404), but we only have a "checked" version of it. We'll copy this and
paste it onto a new page in the #ICONS System Table of a library.

Open the "userpic.df1" file in the Icon Editor. Now go to the page named
"Normal Page 3" and view the page as 32x32. You will see a checkbox icon in
the third column of the third row. Choose the "Marquee" tool from the
toolbar (the one that looks like a dotted rectangle on the far left of the
toolbar) and select the box by drawing around its outline. This is
technically a 32x32 icon, but it is less than 16 pixels square so we're
going to move it to a 16x16 location. Once you have selected the box, choose
"Copy" from the "Edit" menu. Now close the icon file.

Now open the #ICONS class from a library (you have to have one open in the
Library Browser to do this). Using the "New Page..." item from the "Page"
menu, create a new icon page and name it "Report Icons 1". This page should
default to 16x16 support only.


Now select the upper left slot in the grid of twenty icon image slots, and
then select "Paste" from the "Edit" menu. The icon image should appear in
three places: in the selected grid slot, in the detail area (greatly
enlarged) and in the 16x16 box in the lower left corner of the Editor
window. In the detail area in the upper left, the image should appear not
quite centered (down and to the right one pixel). This is to be expected
since the image is an odd number of pixels square and the slot is an even
number square.

Notice that the image is slightly gray inside. For black and white printing
we would like it to be white inside. Furthermore, we would like to remove
the "X" in the middle for our first icon. (We'll make another in a moment.)

There is a very easy way to remove the interior of this box. Using the
"Marquee" tool again, select the area just inside the edge of the box and
then press the "Backspace" key. The box should now be empty (filled with
white, and with no "X").

We must now give our new icon an ID number. Select the "Set Icon ID..." item
from the "Image" menu and assign the number 10000 to our first custom icon.

Now select the next icon image slot to the right of this one in the grid.
Our checkbox image should still be on the clipboard, so "Paste" again. This
time we want to keep the "X" in the box, but change the interior color to
white instead of that light gray color. To do this, we use the "Fill" tool
(looks like a paint can pouring paint). Click on this tool and then click on
the colored rectangle (should be white at this point) above the right side
of the image detail area. This will open the color palette. Make sure that
white is selected by clicking on the white square in the upper left corner
of the palette. The palette should disappear. Now click inside each
triangular area within the checkbox using the "Fill" tool. The color of the
whole area should change to white. Assign an ID number of 10001 to this
icon. Choose "Save" from the "File" menu.

For extra practice, go back into "userpic.df1" and copy icon number 405 (the
radio button) in the same way.

This was too easy! We need something more challenging.

Transparency

The icons we have created so far will be filled with white (their background
color) for the area outside the main image to a full 16x16 pixels. For their
purpose, this is not a problem. We'll be printing onto white paper, so a
white background around our icons won't be noticed. But for icons destined
for pushbuttons or some other control that has a body color of its own, or
even for radio buttons and checkboxes intended for use on a window, this is
unacceptable.

One very important attribute of an icon is the ability to have some portion
of it (usually the background) be transparent. This way it can be placed on
any background and only the icon image will be apparent. Even though it is
still a rectangular object, it appears to be a more "natural" shape and its
own background seems to "blend into" its surroundings.

We achieve this by adding transparency support to the icon page on which the
icon resides. Toggling on the "Substitute Transparent Color" item in the
"Page" menu does this.

Create another icon page in #ICONS and name it "Transparent Icons 1". Select
the upper left image slot and give it an ID number of 10020. Toggle on the
"Substitute Transparent Color" item in the "Page" menu. Now click on the
colored rectangle to show the color palette. Notice that there is now an
item on the right end of the sixth row of the palette (color number 192 out
of the 256 colors in the palette) that shows a black "T" on a white
background. This is the "transparent" color. It actually displays a medium
green color, but any pixel with that color will be transparent in use.
Select the transparent color. Now find the tool on the toolbar named "Fill
Image" and click it. This fills the image area with the transparent color.

Select another color (it doesn't have to "go with" the transparent color)
and a drawing tool and draw something. I chose "red" (second row, fourth
column of the palette) and the oval tool to draw a simple circle, then the
line tool to draw a diagonal line through the circle.

Save the icon file and close the Icon Editor. Then open or create some
window class in the library, place a pushbutton on the window and assign
icon ID 10020 (at 16x16) to the "iconid" property of the pushbutton. Notice
that the area surrounding the icon allows the background to show through. We
could have drawn the image first and then filled the icon background with
the transparent color, but sometimes it's easier to begin with a transparent
background like we did here.

Additional System Colors

Windows-based systems allow the user to set custom color schemes, including
3D highlight and shadow colors, etc. Omnis Studio accommodates this by
allowing us to substitute various "system colors" in the same way that we
substituted a "transparent" color above. The five system colors Studio
supports in this way are: kColor3Dface, kColor3Dshadow, kColor3Dhilite,
kColorWindow, and kColorWindowText (color numbers 32, 64, 96, 128, and 160
respectively - the ones at the right end of each row in the palette). We see
these applied to certain 3D icons in "omnispic.df1" (most notably radio
button and checkbox multistates), but we can use them on our custom icons as
well. To do this, we must toggle on the "Embed System Colors" item in the
"Page" menu. Icons created using these colors will then have a consistent
look on Windows machines with custom color schemes.

Scaling Images

We may often want or need to have the "same" icon in multiple sizes. (This
only applies to "Basic" pages and variants.) Rather than drawing the icon in
each size separately, we can create one size and then clone the image to the
other sizes. It is best to begin with largest image and let the Icon Editor
scale it for us.

We do this by using the "icon size display" area in the lower left corner of
the Editor window. We simply drag the current icons image from one of those
boxes to another (usually from a larger to a smaller size). This works
really well for most cases.

We can also use image editing software like PhotoShop to scale an icon image
down. This may provide more control in some cases, but care must be taken to
create an image in one of the standard sizes.

Creating a "Multistate" Icon Page

There are many items that show multiple states in an Omnis Studio
application. Check boxes and radio buttons immediately come to mind, but
there are also the expand/collapse node icons of a tree list and other
toggle states of controls. There are up to five states that can be applied
to a "Multistate" icon, but not all icons will require all five. Many, in
fact, will only require two states: "On" and "Off" (or equivalent concepts).

Although icon pages with "Multistate Support" toggled on are nicely laid out
to contain four icon ID numbers with five states each, the states are not
determined by the column in which an image finds itself. Rather, the state
is determined by the number of icon image slots following the slot that set
the icon ID number. Let me clarify this...

Suppose I want to create a page filled with two-state icon pairs. I can have
ten such pairs on a single icon page with multistate support turned on. I
assign an icon ID (say 10040) to the upper left image slot and place an
image there with the matching image in the next slot to the right. In the
third slot (in the column labeled "Hilited") I place the first icon image of
my second pair and give that slot a unique icon ID number (perhaps 10041)
and then put the corresponding icon image into slot number four (under
"C/H"). This pair will work just as well as the first pair. I can continue
filling my page with such icon sets. Each set begins with the icon slot to
which I assign an ID number.

By the same token, if I never want to bother with the "C/H/G" ("Checked,
Hilited and Grayed") option, I can have five sets of icons with four states
on a page. I can also mix two-, three-, four- and five-state sets on the
same page. I only have to know where each set begins, but I can easily see
that information by toggling on the "Show ID" item in the "View" menu. Then
it's just a matter of counting.

Creating a "Cursor" Icon Page

To create a "Cursor" icon page, just select the "New Cursor Page" item from
the "Page" menu of the Icon Editor window and give it an appropriate name
when prompted. A page is created with room for four icon ID numbers with
four variants of each icon for different platforms as described above. Two
variant slots are 16x16 and two are 32x32. An icon ID number is assigned to
each "row" in the grid and each "column" determines in which environment
that image will be used for that ID number.

"Cursor" pages can support both a transparent color and embedded system
colors. The most critical aspect of a "Cursor" page, though, is the
placement of the "hot spot".

To test this, create a "Cursor" page and name it "Test Cursors". Notice that
each slot already contains a little red square that indicates which pixel
will contain the hot spot. To modify this, select the "HotSpot" tool. Now
whichever pixel you click on in the detail area will become the new hot spot
for that icon image. Cursor icons generally indicate some sort of action, so
choose the pixel that best indicates where the action should occur.

Creating a "Standalone" Icon Page

"Standalone" pages can be created in either of two ways: from scratch or
from the contents of the clipboard.

To create a "Standalone" page from scratch, use the "New Standalone Page"
command from the "Page" menu. A dialog then appears that requests the width
and height of the image for the page in pixels. If we know what size the
image is or if we are setting up a canvas to do some drawing, this works
fine.

If we have an image that must be pasted in from an external source anyway,
the second technique works better. Simply go to the source (Photoshop or
whatever), select the image and copy it. It is now on the clipboard. Now
return to the Icon Editor and select "New Standalone Page From Clipboard"
from the "Page" menu. A page named "New Clipboard Page" is created with the
image already pasted in! We didn't even have to know what size to make the
page. All we have to do is rename the page to something more descriptive.

I hope this exploration has been useful to you.


========================================

I hope you've found this issue of the Omnis Tech Newsletter both interesting
and informative. Please send me your comments and feedback, and include
suggestions for future articles if you like. We would like to hear from
you...

Regards,
--Andrew Smith.
Omnis Technical Newsletter Editor
Email: editor@omnis.net

========================================

No part of this newsletter may be reproduced, transmitted, stored in a
retrieval system or translated into any language in any form by any means
without the written permission of Raining Data.
(c) Copyright Raining Data, Inc., and its licensors 2002. All rights
reserved.
Omnis(r) is a registered trademark and Omnis 7(tm), and Omnis Studio are
trademarks of Raining Data UK Ltd. Other products mentioned are trademarks
or registered trademarks of their corporations.

========================================

To unsubscribe from this newsletter or change your subscription options,
please go to:
www.omnis.net/newsletter