This project is read-only.

Tab Menu - suggestions

Topics: General
Sep 9, 2008 at 2:03 PM

Hi Zoran,

thank you for your great TabMenu, as well as helpful tutorial, which is written excellent.
As I have tried it, here are some suggestions.

(1) Terminology
The TabMenu looks like MS Ribbon, so I think the terminology could follow the ribbon terminology. The ribbon contains the tab-collection (pageframe) and group-collection on individual tabs. When someone applies TabMenu in its application, manuals or help should take advantage of ribbon terminology, as does the end user. The term TabMenu I found in "MS UX Guide" (p.301 ver. Oct.2007) for a specific way of the navigation. However, there Ribbon is not mentioned at all (because it is patented?).

(2) A collection of menu items
Your menu items have a bit encrypted names, as MenuItem001, PopupMenu002, PopupItem003, ...
(a) Items could be more natural name, as HomeTab, EditGroup, SaveAsCommand. This will be better for recognize the items when we trace the code or write the code.
(b) Why not use the registration of children in the collection, as it is in the OOMenu project? Code will be simpler.
For example in o.AddItem(...) method:
lparameters ...,vcName,vcClass,...
(c) Then iterations items can look like
FOR EACH loItem IN this.oItemCollection

(3) Directories to save bitmap files
Directories should be separated from other graphic directories of the application. Each skin should be complete and encapsulated into its own directory. This allow simply add/change/remove skin. Basic skins (bitmaps) can we include in the application (EXE,APP). The new skins, the user can add to separate directories. Name of the directory can have prefix of the class library (TM_XPBlue, TM_Default,..), because Tab Menu will be not the only library for skin.
This way will allow skin to be:
- skin bitmaps are isolated from the other bitmaps
- application will be extensible with new skins
- skins are encapsulated in its directory
The skin definition table should be in the skin directory too, I think.

(4) Skin Designer Application
Designer-application is the tip to someone who concept of skin will include in its programme or project. This allows 'skin designer' or an experienced user (not the programmer) to create new skin or modify existing one.
This could have some of the features:
- Select skin (directory)
- SaveAs (copy to another directory)
- Edit (browse and edit skin definition table)
- ShowPreview (show example GUI with all used elements and show tooltip with the name of the TabMenu element.
- Validate (test whether each element has defined skin, the bitmap is available and have the right size)

(5) TabMenu Preview
As the TabMenu design is not visual, it would be useful, allow programmers to display a TabMenu (.MPR or .MNX) in the preview mode, as it is in the VFP Menu Designer.

(6) cComponentId property
Codes such as "0000000006" are a bit complicated. Alternative "TM_QUICKBAR" is more friendly.

(7) Skin Definition Table
What is the purpose of this table(?):
- define bitmaps files
- redirect default file definitions in the .Skin() method
- define the elements color
- redefine colors
When all values to .aSkinData are defined in the table, then assigning values to .aSkinData in the .Skin() method is duplicated.When the table contains only redirection, the table may be reduced to changes in those elements which do not share the default values.

(8) .aSkinData[n] property
There are too much numeric indexes in skin definitions: componentid, subitemid and .aSkinData array index. The .aSkinData array is used in many methods. So, it would by more clear, when we use an object .oSkinData instead. Parametric object (based on the Empty class) may have a more readable names of the properties which don't require comment.

(9) Methods of the TabMenu classes
(a) .Skin() methods - I think that a new method .LoadSkinData() with the part of the code from .Skin() method will be clearer. In addition, LoadSkinData() is more suitable for modifications, if we want to change something in the SkinData repository.
(b) .Init() methods - contains often many lines of the code.
I think, it would be better, to move the code into its own methods, such as
.LoadSkinData() ..load bitmaps and colors to the .aSkinData array
.Skin() ..set bitmaps and colors to the object and it's elements
.SetElements() ..set size and position of the object's elements (right/leftImage, CommandButton, HotKeyLabel/Image, ...)
.Arrange() ..set position of the contained objects in the collections, i.e. menu-objects in the main menu/container, tabs in simulated pageframe, groups in page, commandbuttons and other objects in group container.
It is only an idea, some problems can arise, when the behaviors in the methods are not independent.
(c) the same is for .Resize() or .Refresh() methods
If you consider some of the suggestions useful, use it in your project.


Stefan Stehlik