menu.cpp

Go to the documentation of this file.
00001 #ifndef MENU_IMPLEMENTATION_FILE
00002 #define MENU_IMPLEMENTATION_FILE
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : menu                                                              *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *******************************************************************************
00010 * Copyright (c) 1991-$now By Author.  This program is free software; you can  *
00011 * redistribute it and/or modify it under the terms of the GNU General Public  *
00012 * License as published by the Free Software Foundation; either version 2 of   *
00013 * the License or (at your option) any later version.  This is online at:      *
00014 *     http://www.fsf.org/copyleft/gpl.html                                    *
00015 * Please send any updates to: fred@gruntose.com                               *
00016 \*****************************************************************************/
00017 
00018 #include "menu.h"
00019 
00020 #include <basis/function.h>
00021 #include <wp_passive/wp_implementation.h>
00022 
00023 #include <Xm/CascadeB.h>
00024 #include <Xm/Label.h>
00025 #include <Xm/MenuShell.h>
00026 #include <Xm/PushB.h>
00027 #include <Xm/RowColumn.h>
00028 #include <Xm/Separator.h>
00029 
00030 menu::menu(manager &root, const c_point &origin, const char *title,
00031     const color &foreground, const color &background)
00032 : worker(root, c_rectangle(origin, origin),
00033      XmCreateMenuBar(root.self(), const_cast<char *>(title), NIL, 0),
00034      foreground, background),
00035   menu_list(0), _title(title)
00036 { engage(); }
00037 
00038 menu::~menu()
00039 {
00040 // should go through recursively destroying the submenus and removing
00041 // the callbacks on menu items.
00042 }
00043 
00044 void menu::draw()
00045 {
00046   if (realized()) return;
00047   recursively_create(self(), _title.s(), &menu_list);
00048   worker::draw();
00049 }
00050 
00051 void menu::recursively_create(window_handle parent, const char *title,
00052     amorph<wp_menu_item> *menulist)
00053 {
00054   color f = foreground(); color b = background();
00055   if (title) {
00056     window_handle a1 = XtCreateManagedWidget
00057       (title, xmLabelWidgetClass, parent, NULL, 0);
00058     window_handle a2 = XtCreateManagedWidget
00059       ("separator", xmSeparatorWidgetClass, parent, NULL, 0);
00060     nub temp1(a1, a1); temp1.set_foreground(f); temp1.set_background(b);
00061     nub temp2(a2, a2); temp2.set_foreground(f); temp2.set_background(b);
00062   }
00063 
00064   for (int i = 0; i < menulist->elements(); i++) {
00065     wp_menu_item *menulist_i = menulist->borrow(i);
00066     if (!menulist_i->name.length()) {
00067       // An empty name means insert a separator.
00068       menulist_i->self(XtCreateManagedWidget
00069           ("separator", xmSeparatorWidgetClass, parent, NULL, 0));
00070       nub temp(menulist_i->self(), menulist_i->self());
00071       temp.set_foreground(f); temp.set_background(b);
00072     } else if (menulist_i->i_am_label) {
00073       // a label is an unselectable text blob in the menu.
00074       menulist_i->self(XtCreateWidget
00075           (menulist_i->name.s(), xmLabelWidgetClass, parent, NULL, 0));
00076       nub temp(menulist_i->self(), menulist_i->self());
00077       temp.set_foreground(f); temp.set_background(b);
00078     } else if (!menulist_i->sub_menus.elements()) {
00079       // this is a selectable item without a submenu.
00080       menulist_i->self(XtCreateWidget
00081         (menulist_i->name.s(), xmPushButtonWidgetClass, parent, NULL, 0));
00082       nub temp(menulist_i->self(), menulist_i->self());
00083       temp.set_foreground(f); temp.set_background(b);
00084       XtAddCallback(menulist_i->self(), XmNactivateCallback, 
00085           XtCallbackProc(wp_menu_item_callback), XtPointer(menulist_i));
00086     } else {
00087       // Recursive call to create sub-menu.
00088       window_handle sub_menu = XmCreatePulldownMenu(parent,
00089           menulist_i->sub_menu_title.s(), NULL, 0);
00090         // the window_handle "sub_menu" is currently being ignored once it is
00091         // used.  it may prove necessary to keep track of it at some future
00092         // time...?
00093       nub temp1(sub_menu, sub_menu);
00094       temp1.set_foreground(f); temp1.set_background(b);
00095       argument_list wargs;
00096       wargs.add(XmNsubMenuId, XtArgVal(sub_menu));
00097       menulist_i->self(XtCreateWidget
00098         (menulist_i->name.s(), xmCascadeButtonWidgetClass, parent,
00099          wargs.generate(), wargs.number()));
00100       nub temp2(menulist_i->self(), menulist_i->self());
00101       temp2.set_foreground(f); temp2.set_background(b);
00102       recursively_create
00103           (sub_menu, menulist_i->sub_menu_title.s(), &menulist_i->sub_menus);
00104     }
00105     // manage all wp_menu_items except separators.
00106     if (menulist_i->name.length()) XtManageChild(menulist_i->self());
00107   }
00108 }
00109 
00110 void menu::add(wp_menu_item *to_add) { menu_list.append(to_add); }
00111 
00112 void menu::wp_menu_item_callback(window_handle , wp_menu_item *the_item, caddr_t )
00113 { the_item->item_selected_event(); }
00114 
00116 
00117 wp_menu_item::wp_menu_item(menu &parent_in, const char *name_in, bool label)
00118 : nub(parent.self(), NIL), name(name_in), i_am_label(label), sub_menus(0),
00119   parent(parent_in)
00120 {}
00121 
00122 wp_menu_item::~wp_menu_item() {}
00123 
00124 void wp_menu_item::item_selected_event()
00125 {
00126   FUNCDEF("item_selected_event");
00127   LOG("blank wp_menu_item event");
00128 }
00129 
00130 void wp_menu_item::submenu_name(const istring &name)
00131 { sub_menu_title = name; }
00132 
00133 void wp_menu_item::connect(wp_menu_item *to_connect)
00134 { sub_menus.append(to_connect); }
00135 
00136 
00137 #endif //MENU_IMPLEMENTATION_FILE
00138 

Generated on Fri Nov 28 04:29:04 2008 for HOOPLE Libraries by  doxygen 1.5.1