home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
yacl-012.zip
/
ui
/
menu.h
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-08
|
10KB
|
331 lines
#ifndef _menu_h_ /* Mon Sep 20 21:20:32 1993 */
#define _menu_h_
/*
*
* Copyright (C) 1994, M. A. Sridhar
*
*
* This software is Copyright M. A. Sridhar, 1994. You are free
* to copy, modify or distribute this software as you see fit,
* and to use it for any purpose, provided this copyright
* notice and the following disclaimer are included with all
* copies.
*
* DISCLAIMER
*
* The author makes no warranties, either expressed or implied,
* with respect to this software, its quality, performance,
* merchantability, or fitness for any particular purpose. This
* software is distributed AS IS. The user of this software
* assumes all risks as to its quality and performance. In no
* event shall the author be liable for any direct, indirect or
* consequential damages, even if the author has been advised
* as to the possibility of such damages.
*
*/
// A Menu is thought of as a labeled tree, each of whose nodes is a
// MenuItem object, and the label of a given node is the handle of the
// corresponding MenuItem object. Thus we require that the labels of the
// MenuItem objects are all distinct. The root of the tree is a dummy
// node. (This formulation allows direct use of CL_Tree.) Each MenuItem
// object is (derived from) a VisualObject, and therefore supports an
// event-handling protocol. In particular, it displays a picture in its
// view area, which most often is a simple text string, and it provides a
// "highlighting" capability for what it displays.
//
// The MenuItem responds to the GetFocus, Select and LoseFocus
// events. Its response to the GetFocus event (the WM_INITMENU message
// under Windows) is to highlight its view, and notifying any clients
// that might be interested in that event. Similarly, its response to the
// LoseFocus event is to notify any clients interested in the event. Its
// response to the Select event depends on whether it is a leaf in the
// tree or not. If it is not a leaf in the tree, it displays the submenu
// associated with it. If it is a leaf, it simply notifies any clients
// interested in that event.
//
// Since every simple visual object must contain a model, we use a string as
// model for the MenuItem. This model is the value displayed by default
// in the MenuItem's view. (Custom MenuItem objects that draw fancy
// graphics in their view might or might not use this string.) An
// assignment to this model changes the picture drawn in the view.
//
// The Menu class simply functions as a container for MenuItem objects,
// and provides convenience functions for accessing MenuItems.
//
// The MenuBar and PopupMenu classes are derived from the Menu class, and
// are simply two different ways of representing the "main" menu, i.e.,
// the children of the root of the menu tree.
//
// The abstraction of the menu represented by the UI_Menu class is the
// following. The Menu is thought of as a container for MenuItem
// objects. Thus all the contained MenuItems must have
// distinct Id's. Note that this view "linearizes" the traditional
// tree-structured view of a menu in which the children of the root are the
// main menu items, and their children are submenu items.
//
// The root uses an id of 0, so all menu items must have distinct id's that
// are greater than 0.
#if defined(__GNUC__)
#pragma interface
#endif
#include "base/tree.h"
#include "base/clntset.h"
#include "ui/simple.h"
class CL_EXPORT UI_MenuItem;
class CL_EXPORT UI_PopupMenu;
struct UI_MenuItemDescriptor;
class CL_EXPORT UI_CompositeVObject;
class CL_EXPORT UI_Menu: public UI_VisualObject {
public:
UI_MenuItem* operator[] (UI_ViewID id);
// Return a pointer to the menu item with the given id. The returned
// object remains owned by the Menu, and may not be destroyed by the
// caller. This method returns NULL if no such id exists in the menu.
bool Add (UI_ViewID id, const char* label,
UI_ViewID parent_id = 0, short rank = 32000);
// Add a new menu item, with view id {\tt id} and label {\tt label}, as
// a child of the item with id {\tt parent_id}. The new item is added
// immediately to the right of the child at position {\tt rank}.
// Specifying a rank that is too large causes the item to be added as
// the rightmost child; specifying -1 causes it to become the leftmost
// child.
//
// The method returns TRUE if the addition was successful, FALSE
// otherwise (e.g., a duplicate view id or an invalid parent id was
// specified).
bool AddSeparator (UI_ViewID parent_id, short rank);
// Add a separator as a part of the sub-menu whose root is {\tt
// parent_id}. The value of {\tt rank} is as in the {\tt Add} method.
bool Remove (UI_ViewID id);
// Remove the menu item with view id {\tt id}, along with all its
// descendants in the menu tree. Return TRUE if successful, FALSE if an
// invalid item was specified.
UI_ViewID RootID () const;
// Return the view id of the dummy MenuItem at the root of the menu
// tree. This method is only needed for menu tree traversal.
short ChildCount (UI_ViewID id) const;
// Return the number of children of the item with the given id. This
// method returns -1 if there is no MenuItem with the given id in the
// menu.
UI_MenuItem* Child (UI_ViewID id, short i) const;
// Return a pointer to the child $i$ of the menu item with view id {\tt
// id}. The value $i$ must be between 0 and $n-1$, where $n$ is the
// number of children of
// the specified menu item. If this is not the case, or if there is no
// menu item with the given id, this method returns NULL.
short Index (UI_ViewID id) const;
// Return the rank of the menu item with the given id among its
// siblings; for example, if it is the first child, this method returns
// 0. This method returns -1 if there is no menu item with the given id.
UI_WindowClass WindowClass () const;
bool IsTabStop () const {return FALSE;};
// Return FALSE unconditionally, since menus cannot be tab stops.
const char* ClassName () const { return "UI_Menu";};
protected:
UI_Menu (UI_CompositeVObject* parent, UI_MenuItemDescriptor* item);
~UI_Menu ();
short _BuildMenuSubtree (UI_MenuItemDescriptor* items, UI_ViewID id);
bool _CreateMenuItemVisual (CL_IntegerTreeNode&);
bool MakeVisualElement () = 0;
bool HandleEvent (UI_Event* e);
bool DestroyVisualElement ();
// Instance data:
CL_IntegerTree _menuTree;
UI_MenuItem* _focusItem;
#if defined(__MS_WINDOWS__) || defined(__OS2__)
public:
void MoveFocusTo (UI_MenuItem* item);
// [Specific to MS-Windows and OS/2. Internal use only.]
UI_MenuItem* Focus () const {return _focusItem;};
// [Specific to MS-Windows and OS/2. Internal use only.]
#endif
};
class CL_EXPORT UI_MenuItem: public UI_SimpleVObject {
public:
// Overridden inherited methods:
bool Enable ();
bool Disable ();
bool IsTabStop () const {return FALSE;};
// Return FALSE unconditionally, since menus cannot be tab stops.
CL_Object& Model() {return _title;};
// Return reference to the string label.
UI_Menu& Container () {return _container;};
// Return a reference to the menu that contains us.
UI_ViewHandle ViewHandle () const;
UI_WindowClass WindowClass () const;
const char* ClassName() const { return "UI_MenuItem";};
protected:
friend UI_Menu;
friend class UI_MenuBar;
friend class UI_PopupMenu;
UI_MenuItem (UI_Menu* container, const char* label, UI_ViewID id);
~UI_MenuItem();
bool MakeVisualElement ();
void _PrivateInitialize ();
bool _TitleChanged (CL_Object&, long);
bool DestroyVisualElement ();
#if defined(__X_MOTIF__)
void SetLabel ();
#endif
//
// Instance variables
//
UI_Menu& _container; // The menu object of which we are a
// part
private:
#if defined(__MS_WINDOWS__)
void _SetState ();
UI_ViewHandle _parentHandle;
#elif defined(__OS2__)
UI_ViewHandle _parentHandle;
#elif defined (__X_MOTIF__)
struct _WidgetRec* _xitemw;
static void GetFocusCallback (struct _WidgetRec*, void *, void *);
static void LoseFocusCallback (struct _WidgetRec*, void *, void *);
static void SelectionCallback (struct _WidgetRec*, void *, void *);
#endif
};
#define UIMenu_Separator "---"
struct UI_MenuItemDescriptor {
char* label; // Set this field to UIMenu_Separator
// for a separator; the remaining fields
// are ignored for separators
UI_ViewID id;
UI_MenuItemDescriptor* submenu;
};
class CL_EXPORT UI_MenuBar: public UI_Menu {
public:
UI_MenuBar (UI_CompositeVObject* parent, UI_MenuItemDescriptor* item );
// The descriptor array {\tt item} must contain at least one
// item. Otherwise the results can be unpredictable.
const char* ClassName() const { return "UI_MenuBar";};
protected:
bool MakeVisualElement ();
};
class CL_EXPORT UI_PopupMenu: public UI_Menu {
public:
UI_PopupMenu (UI_CompositeVObject* parent, UI_MenuItemDescriptor* item);
// The descriptor array {\tt item} must contain at least one
// item. Otherwise the results can be unpredictable.
~UI_PopupMenu ();
bool ShowAt (const UI_Point& p);
// Show the popup menu at the given point
const char* ClassName () const { return "UI_PopupMenu";};
protected:
bool MakeVisualElement ();
};
#endif