00001 /*
00002 File: Forms.cc
00003
00004 Function: See header file
00005
00006 Author(s): Andrew Willmott
00007
00008 Copyright: (c) 1997-2000, Andrew Willmott
00009
00010 Notes:
00011
00012 */
00013
00014 // NOTE: not currently part of the GCL lib -- included separately
00015 // by a few programs.
00016
00017 #include "gcl/Forms.h"
00018
00019
00020 // --- Forms Graphics System --------------------------------------------------
00021
00022
00023 FormsGraphicsSystem::FormsGraphicsSystem(int argc, char **argv, char *name) :
00024 XGraphicsSystem()
00025 {
00026 itsEventsMask = StructureNotifyMask;
00027
00028 if (name == 0)
00029 name = argv[0];
00030
00031 fl_initialize(&argc, argv, name, 0, 0);
00032 }
00033
00034 int FormsXCallback(XEvent *event, Void *data)
00035 {
00036 ((XEventPane *) data)->XHandleEvent(event);
00037
00038 return(1);
00039 }
00040
00041 Void FormsGraphicsSystem::CreateFormsPane(XEventPane *xevpane, FL_OBJECT *object)
00042 {
00043 const Int inset = 4;
00044
00045 CreateSubwindow(xevpane, FL_OBJECT_WID(object), object->x + inset,
00046 object->y + inset, object->w - 2 * inset, object->h - 2 * inset);
00047
00048 fl_add_event_callback(xevpane->paneXID, Expose, FormsXCallback, xevpane);
00049 fl_add_event_callback(xevpane->paneXID, ButtonPress, FormsXCallback, xevpane);
00050 fl_add_event_callback(xevpane->paneXID, KeyPress, FormsXCallback, xevpane);
00051
00052 fl_activate_event_callbacks(xevpane->paneXID);
00053 }
00054
00055 Void FormsGraphicsSystem::CreateWindow(XEventPane *xevpane, Char *title,
00056 Int width, Int height)
00057 {
00058 XGraphicsSystem::CreateWindow(xevpane, title, width, height);
00059
00060 fl_add_event_callback(xevpane->paneXID, Expose, FormsXCallback, xevpane);
00061 fl_add_event_callback(xevpane->paneXID, ButtonPress, FormsXCallback, xevpane);
00062 fl_add_event_callback(xevpane->paneXID, KeyPress, FormsXCallback, xevpane);
00063
00064 fl_activate_event_callbacks(xevpane->paneXID);
00065 }
00066
00067 Void FormsGraphicsSystem::GetMouse(XEventPane *pane, Int *x, Int *y,
00068 UInt *keyState)
00069 {
00070 fl_get_win_mouse(pane->paneXID, x, y, keyState);
00071 }
00072
00073 Void FormsGraphicsSystem::Spin()
00074 {
00075 FL_OBJECT *choice;
00076
00077 choice = fl_check_forms();
00078
00079 if (choice != 0)
00080 cerr << "Uncaptured forms event: " << choice << endl;
00081 }
00082
00083 Void FormsGraphicsSystem::Run()
00084 {
00085 finished = false;
00086 fl_do_forms();
00087 finished = true;
00088 }
00089
00090 Void FormsGraphicsSystem::SignalDone()
00091 {
00092 fl_finish();
00093 }
00094
00095 // --- The Field Class --------------------------------------------------------
00096
00097
00098 ostream &show(ostream &s)
00099 {
00100 Field *cs = (Field *) &s; // C++: hate, hate, hate...
00101 // There is no way to do this safely, i.e.,
00102 cs->Show(); // guarantee it will only be run on a Field.
00103
00104 return(s);
00105 }
00106
00107 Void Field::Show()
00108 {
00109 // glibc under linux seems to have a bug whereby strstreams don't terminate
00110 // strings returned by str() properly.
00111 Char glibcWorkaround[1024];
00112
00113 memcpy(glibcWorkaround, str(), pcount());
00114 glibcWorkaround[pcount()] = 0;
00115
00116 fl_set_object_label(object, glibcWorkaround);
00117 fl_check_only_forms();
00118 }
00119
00120 Void InputField::Show()
00121 {
00122 fl_set_input(object, str());
00123 }
00124
00125
00126 // --- Extra forms routines ---------------------------------------------------
00127
00128
00129 Void fl_set_menu_item_check(FL_OBJECT *obj, int item, Bool b)
00130 {
00131 int other = fl_get_menu_item_mode(obj, item) &
00132 ~(FL_PUP_CHECK | FL_PUP_BOX);
00133
00134 if (!b)
00135 fl_set_menu_item_mode(obj, item,
00136 other | FL_PUP_BOX);
00137 else
00138 fl_set_menu_item_mode(obj, item,
00139 other | FL_PUP_CHECK);
00140 }
00141
00142 Bool fl_get_menu_item_check(FL_OBJECT *obj, int item)
00143 {
00144 return(fl_get_menu_item_mode(obj, item) & FL_PUP_CHECK);
00145 }
00146
00147 Void fl_update_colors(FL_FORM *form)
00148 {
00149 FL_OBJECT *obj;
00150
00151 for (obj = form->first; obj != 0; obj = obj->next)
00152 {
00153 if (obj->active == 1 && obj->lcol == FL_INACTIVE)
00154 {
00155 fl_set_object_lcol(obj, FL_BLACK);
00156 fl_set_object_color(obj, obj->col1, FL_BLACK);
00157 }
00158 else if (obj->active == -1 && obj->lcol == FL_BLACK)
00159 {
00160 fl_set_object_lcol(obj, FL_INACTIVE);
00161 fl_set_object_color(obj, obj->col1, FL_INACTIVE);
00162 }
00163 }
00164 }
00165
00166 Void fl_deactivate_group(FL_OBJECT *obj)
00167 {
00168 fl_deactivate_object(obj);
00169 fl_update_colors(obj->form);
00170 }
00171
00172 Void fl_activate_group(FL_OBJECT *obj)
00173 {
00174 fl_activate_object(obj);
00175 fl_update_colors(obj->form);
00176 }
00177
00178 Void my_activate(FL_OBJECT *obj)
00179 {
00180 fl_activate_object(obj);
00181 fl_set_object_lcol(obj, FL_BLACK);
00182 fl_set_object_color(obj, obj->col1, FL_BLACK);
00183 }
00184
00185 Void my_deactivate(FL_OBJECT *obj)
00186 {
00187 fl_deactivate_object(obj);
00188 fl_set_object_lcol(obj, FL_INACTIVE);
00189 fl_set_object_color(obj, obj->col1, FL_INACTIVE);
00190 }
00191
00192
00193 // --- Form class -------------------------------------------------------------
00194
00195 Form::Form() : title("untitled")
00196 {
00197 }
00198
00199 Void ObjFormCallback(FL_OBJECT *object, Void *data)
00200 {
00201 if (object->u_vdata)
00202 ((Form *) object->u_vdata)->Event(object);
00203 else
00204 Expect(false, "Received event for unhandled object.");
00205 }
00206
00207 Void Form::RegisterForm(FL_FORM *form)
00208 {
00209 fl_set_form_callback(form, ObjFormCallback, 0);
00210 }
00211
00212 Void Form::RegisterObj(FL_OBJECT *object)
00213 {
00214 object->u_vdata = this;
00215 }
00216
00217 Void Form::Event(FL_OBJECT *object)
00218 {
00219 cerr << "Received event for object :" << object << " in form " << this
00220 << "." << endl;
00221 }
00222
00223 Void Form::Show()
00224 {
00225 fl_show_form(form, FL_PLACE_SIZE, FL_FULLBORDER, title);
00226 }
00227
00228 Void Form::Hide()
00229 {
00230 fl_hide_form(form);
00231 }
00232
00233 Void Form::SetTitle(const Char *title)
00234 {
00235 this->title = title;
00236 }
00237