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