radio_box.cpp

Go to the documentation of this file.
00001 #ifndef RADIO_BOX_IMPLEMENTATION_FILE
00002 #define RADIO_BOX_IMPLEMENTATION_FILE
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : radio_box                                                         *
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 // An earlier version was implemented by Douglas Young
00019 
00020 #include "radio_box.h"
00021 
00022 #include <basis/guards.h>
00023 #include <wp_passive/argument_list.h>
00024 #include <wp_passive/resources.h>
00025 #include <wp_passive/wp_implementation.h>
00026 
00027 #include <Xm/ToggleB.h>
00028 #include <Xm/RowColumn.h>
00029 
00031 
00032 class radio_mouse : public mouse
00033 {
00034 public:
00035   radio_mouse(radio_box *to_connect)
00036       : mouse(*(nub *)to_connect), _radio_box(to_connect) {}
00037   IMPLEMENT_CLASS_NAME("radio_mouse");
00038   virtual void button_event(const c_point &, int , button_positions ) {
00039     FUNCDEF("button_event");
00040     LOG(isprintf("radmous: but_event: [%d]", _radio_box->current()));
00041     _radio_box->press(_radio_box->current(), false); 
00042   }
00043 
00044 private:
00045   radio_box *_radio_box;
00046 };
00047 
00049 
00050 radio_box_button::radio_box_button(radio_box *parent,
00051     const istring &button_name, int number)
00052 : worker(parent->root(), c_rectangle(0,0,0,0),
00053       XtCreateWidget(button_name.s(), xmToggleButtonWidgetClass,
00054           parent->self(), NULL, 0)),
00055   _name(button_name), button_number(number), interactive_press(true),
00056   _parent(parent)
00057 {
00058   XtAddCallback(self(), XmNvalueChangedCallback, 
00059   XtCallbackProc(radio_box::radio_box_callback), XtPointer(this));
00060   engage();
00061 }
00062 
00063 radio_box_button::~radio_box_button()
00064 {
00065   // remove the button's callbacks.
00066   XtRemoveCallback(self(), XmNvalueChangedCallback,
00067   XtCallbackProc(radio_box::radio_box_callback), XtPointer(_parent));
00068 }
00069 
00071 
00072 radio_box::radio_box(manager &parent, const c_point &origin,
00073     const color &foreground, const color &background)
00074 : worker(parent, c_rectangle(origin, origin), NIL, foreground, background),
00075   array<radio_box_button *> (0),
00076   active(NIL),
00077   touched_box_manager(NIL)
00078 {
00079   argument_list wargs;
00080   wargs.add(XmNentryClass, XtArgVal(xmToggleButtonWidgetClass));
00081   self(XmCreateRadioBox(parent.self(), (char *)"radio_box",
00082       wargs.generate(), wargs.number()));
00083   wargs.apply(self());
00084   engage();
00085   touched_box_manager = new radio_mouse(this);
00086 }
00087 
00088 radio_box::~radio_box() { delete touched_box_manager; }
00089 
00090 istring radio_box::lookup(int index) const { return get(index)->_name; }
00091 
00092 int radio_box::current() const
00093   { return (active? lookup(active->_name) : RB_NO_BUTTON); }
00094 
00095 int radio_box::buttons() const { return length(); }
00096 
00097 int radio_box::add(const istring &butname)
00098 {
00099   radio_box_button *new_button = new radio_box_button(this, butname, length());
00100   insert(length(), 1);
00101   put(length() - 1, new_button);
00102   if (!active) {
00103     active = new_button;
00104     // the press below should be moved to a radio_box draw function at some
00105     // point so that the press is never attempted before the box is on the
00106     // screen.
00107     press(0, false);
00108   }
00109   return length() - 1;
00110 }
00111 
00112 int radio_box::lookup(const istring &to_find) const
00113 {
00114   for (int i = 0; i < length(); i++) if (get(i)->_name == to_find) return i;
00115   return RB_NO_BUTTON;
00116 }
00117 
00118 void radio_box::press(int index, bool call_back)
00119 {
00120   FUNCDEF("press");
00121   if ( (index < 0) || (index > length() - 1) ) return;
00122   active = get(index);
00123   if (!active) {
00124 LOG("rb: press: active=nil!");
00125 return;
00126   }
00127   active->interactive_press = call_back;
00128   argument_list wargs;
00129   wargs.add(XmNset, true);
00130   wargs.apply(active->self());
00131   active->interactive_press = true;
00132 }
00133 
00134 void radio_box::radio_box_callback(window_handle formal(w),
00135     radio_box_button *pressed,
00136     XmToggleButtonCallbackStruct *call_data)
00137 {
00138   FUNCDEF("radio_box_callback");
00139   // ignore calls that are not for a button set.
00140   if (call_data->set) {
00141     pressed->_parent->active = pressed;
00142     if (pressed->interactive_press) {
00143 LOG("priv rad call: interactive");
00144       // this callback occurs due to the user pressing the button with
00145       // the mouse, and so the appearance of the button is dealt with by X.
00146       pressed->_parent->button_event
00147           (pressed->_parent->lookup(pressed->_name));
00148     } else {
00149       // This callback is the result of a press_button request, and we are
00150       // causing the appearance to change.
00151 LOG("priv rad call: non-interactive");
00152       argument_list wargs;
00153       wargs.add(XmNset, true);
00154       wargs.apply(pressed->self());
00155     }
00156   }
00157 }
00158 
00159 void radio_box::button_event(int index)
00160 {
00161   FUNCDEF("button_event");
00162   LOG(isprintf("radio_box::button_event: [%s] hit in blank event function.",
00163       lookup(index).s()));
00164 }
00165 
00166 
00167 #endif //RADIO_BOX_IMPLEMENTATION_FILE
00168 

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