|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 // 00002 // "$Id: Fl_Type.cxx 8172 2011-01-03 08:28:38Z matt $" 00003 // 00004 // Widget type code for the Fast Light Tool Kit (FLTK). 00005 // 00006 // Each object described by Fluid is one of these objects. They 00007 // are all stored in a double-linked list. 00008 // 00009 // They "type" of the object is covered by the virtual functions. 00010 // There will probably be a lot of these virtual functions. 00011 // 00012 // The type browser is also a list of these objects, but they 00013 // are "factory" instances, not "real" ones. These objects exist 00014 // only so the "make" method can be called on them. They are 00015 // not in the linked list and are not written to files or 00016 // copied or otherwise examined. 00017 // 00018 // Copyright 1998-2010 by Bill Spitzak and others. 00019 // 00020 // This library is free software; you can redistribute it and/or 00021 // modify it under the terms of the GNU Library General Public 00022 // License as published by the Free Software Foundation; either 00023 // version 2 of the License, or (at your option) any later version. 00024 // 00025 // This library is distributed in the hope that it will be useful, 00026 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00027 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00028 // Library General Public License for more details. 00029 // 00030 // You should have received a copy of the GNU Library General Public 00031 // License along with this library; if not, write to the Free Software 00032 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00033 // USA. 00034 // 00035 // Please report all bugs and problems on the following page: 00036 // 00037 // http://www.fltk.org/str.php 00038 // 00039 00040 #include <FL/Fl.H> 00041 #include <FL/Fl_Browser_.H> 00042 #include <FL/fl_draw.H> 00043 #include <stdlib.h> 00044 #include "../src/flstring.h" 00045 #include <stdio.h> 00046 00047 #include "Fl_Type.h" 00048 #include "undo.h" 00049 00050 #include <FL/Fl_Pixmap.H> 00051 #include "pixmaps/lock.xpm" 00052 #include "pixmaps/protected.xpm" 00053 //#include "pixmaps/unlock.xpm" 00054 00055 static Fl_Pixmap lock_pixmap(lock_xpm); 00056 static Fl_Pixmap protected_pixmap(protected_xpm); 00057 //static Fl_Pixmap unlock_pixmap(unlock_xpm); 00058 00059 #include "pixmaps/flWindow.xpm" 00060 #include "pixmaps/flButton.xpm" 00061 #include "pixmaps/flCheckButton.xpm" 00062 #include "pixmaps/flRoundButton.xpm" 00063 #include "pixmaps/flBox.xpm" 00064 #include "pixmaps/flGroup.xpm" 00065 #include "pixmaps/flFunction.xpm" 00066 #include "pixmaps/flCode.xpm" 00067 #include "pixmaps/flCodeBlock.xpm" 00068 #include "pixmaps/flComment.xpm" 00069 #include "pixmaps/flData.xpm" 00070 #include "pixmaps/flDeclaration.xpm" 00071 #include "pixmaps/flDeclarationBlock.xpm" 00072 #include "pixmaps/flClass.xpm" 00073 #include "pixmaps/flTabs.xpm" 00074 #include "pixmaps/flInput.xpm" 00075 #include "pixmaps/flChoice.xpm" 00076 #include "pixmaps/flMenuitem.xpm" 00077 #include "pixmaps/flMenubar.xpm" 00078 #include "pixmaps/flSubmenu.xpm" 00079 #include "pixmaps/flScroll.xpm" 00080 #include "pixmaps/flTile.xpm" 00081 #include "pixmaps/flWizard.xpm" 00082 #include "pixmaps/flPack.xpm" 00083 #include "pixmaps/flReturnButton.xpm" 00084 #include "pixmaps/flLightButton.xpm" 00085 #include "pixmaps/flRepeatButton.xpm" 00086 #include "pixmaps/flMenuButton.xpm" 00087 #include "pixmaps/flOutput.xpm" 00088 #include "pixmaps/flTextDisplay.xpm" 00089 #include "pixmaps/flTextEdit.xpm" 00090 #include "pixmaps/flFileInput.xpm" 00091 #include "pixmaps/flBrowser.xpm" 00092 #include "pixmaps/flCheckBrowser.xpm" 00093 #include "pixmaps/flFileBrowser.xpm" 00094 #include "pixmaps/flClock.xpm" 00095 #include "pixmaps/flHelp.xpm" 00096 #include "pixmaps/flProgress.xpm" 00097 #include "pixmaps/flSlider.xpm" 00098 #include "pixmaps/flScrollBar.xpm" 00099 #include "pixmaps/flValueSlider.xpm" 00100 #include "pixmaps/flAdjuster.xpm" 00101 #include "pixmaps/flCounter.xpm" 00102 #include "pixmaps/flDial.xpm" 00103 #include "pixmaps/flRoller.xpm" 00104 #include "pixmaps/flValueInput.xpm" 00105 #include "pixmaps/flValueOutput.xpm" 00106 #include "pixmaps/flSpinner.xpm" 00107 #include "pixmaps/flWidgetClass.xpm" 00108 #include "pixmaps/flTree.xpm" 00109 #include "pixmaps/flTable.xpm" 00110 00111 static Fl_Pixmap window_pixmap(flWindow_xpm); 00112 static Fl_Pixmap button_pixmap(flButton_xpm); 00113 static Fl_Pixmap checkbutton_pixmap(flCheckButton_xpm); 00114 static Fl_Pixmap roundbutton_pixmap(flRoundButton_xpm); 00115 static Fl_Pixmap box_pixmap(flBox_xpm); 00116 static Fl_Pixmap group_pixmap(flGroup_xpm); 00117 static Fl_Pixmap function_pixmap(flFunction_xpm); 00118 static Fl_Pixmap code_pixmap(flCode_xpm); 00119 static Fl_Pixmap codeblock_pixmap(flCodeBlock_xpm); 00120 static Fl_Pixmap comment_pixmap(flComment_xpm); 00121 static Fl_Pixmap declaration_pixmap(flDeclaration_xpm); 00122 static Fl_Pixmap declarationblock_pixmap(flDeclarationBlock_xpm); 00123 static Fl_Pixmap class_pixmap(flClass_xpm); 00124 static Fl_Pixmap tabs_pixmap(flTabs_xpm); 00125 static Fl_Pixmap input_pixmap(flInput_xpm); 00126 static Fl_Pixmap choice_pixmap(flChoice_xpm); 00127 static Fl_Pixmap menuitem_pixmap(flMenuitem_xpm); 00128 static Fl_Pixmap menubar_pixmap(flMenubar_xpm); 00129 static Fl_Pixmap submenu_pixmap(flSubmenu_xpm); 00130 static Fl_Pixmap scroll_pixmap(flScroll_xpm); 00131 static Fl_Pixmap tile_pixmap(flTile_xpm); 00132 static Fl_Pixmap wizard_pixmap(flWizard_xpm); 00133 static Fl_Pixmap pack_pixmap(flPack_xpm); 00134 static Fl_Pixmap returnbutton_pixmap(flReturnButton_xpm); 00135 static Fl_Pixmap lightbutton_pixmap(flLightButton_xpm); 00136 static Fl_Pixmap repeatbutton_pixmap(flRepeatButton_xpm); 00137 static Fl_Pixmap menubutton_pixmap(flMenuButton_xpm); 00138 static Fl_Pixmap output_pixmap(flOutput_xpm); 00139 static Fl_Pixmap textdisplay_pixmap(flTextDisplay_xpm); 00140 static Fl_Pixmap textedit_pixmap(flTextEdit_xpm); 00141 static Fl_Pixmap fileinput_pixmap(flFileInput_xpm); 00142 static Fl_Pixmap browser_pixmap(flBrowser_xpm); 00143 static Fl_Pixmap checkbrowser_pixmap(flCheckBrowser_xpm); 00144 static Fl_Pixmap filebrowser_pixmap(flFileBrowser_xpm); 00145 static Fl_Pixmap clock_pixmap(flClock_xpm); 00146 static Fl_Pixmap help_pixmap(flHelp_xpm); 00147 static Fl_Pixmap progress_pixmap(flProgress_xpm); 00148 static Fl_Pixmap slider_pixmap(flSlider_xpm); 00149 static Fl_Pixmap scrollbar_pixmap(flScrollBar_xpm); 00150 static Fl_Pixmap valueslider_pixmap(flValueSlider_xpm); 00151 static Fl_Pixmap adjuster_pixmap(flAdjuster_xpm); 00152 static Fl_Pixmap counter_pixmap(flCounter_xpm); 00153 static Fl_Pixmap dial_pixmap(flDial_xpm); 00154 static Fl_Pixmap roller_pixmap(flRoller_xpm); 00155 static Fl_Pixmap valueinput_pixmap(flValueInput_xpm); 00156 static Fl_Pixmap valueoutput_pixmap(flValueOutput_xpm); 00157 static Fl_Pixmap spinner_pixmap(flSpinner_xpm); 00158 static Fl_Pixmap widgetclass_pixmap(flWidgetClass_xpm); 00159 static Fl_Pixmap data_pixmap(flData_xpm); 00160 static Fl_Pixmap tree_pixmap(flTree_xpm); 00161 static Fl_Pixmap table_pixmap(flTable_xpm); 00162 00163 Fl_Pixmap *pixmap[] = { 0, &window_pixmap, &button_pixmap, &checkbutton_pixmap, &roundbutton_pixmap, /* 0..4 */ 00164 &box_pixmap, &group_pixmap, &function_pixmap, &code_pixmap, &codeblock_pixmap, &declaration_pixmap, /* 5..10 */ 00165 &declarationblock_pixmap, &class_pixmap, &tabs_pixmap, &input_pixmap, &choice_pixmap, /* 11..15 */ 00166 &menuitem_pixmap, &menubar_pixmap, &submenu_pixmap, &scroll_pixmap, &tile_pixmap, &wizard_pixmap, /* 16..21 */ 00167 &pack_pixmap, &returnbutton_pixmap, &lightbutton_pixmap, &repeatbutton_pixmap, &menubutton_pixmap, /* 22..26 */ 00168 &output_pixmap, &textdisplay_pixmap, &textedit_pixmap, &fileinput_pixmap, &browser_pixmap, /* 27..32 */ 00169 &checkbrowser_pixmap, &filebrowser_pixmap, &clock_pixmap, &help_pixmap, &progress_pixmap, /* 33..36 */ 00170 &slider_pixmap, &scrollbar_pixmap, &valueslider_pixmap, &adjuster_pixmap, &counter_pixmap, /* 37..41 */ 00171 &dial_pixmap, &roller_pixmap, &valueinput_pixmap, &valueoutput_pixmap, &comment_pixmap, /* 42..46 */ 00172 &spinner_pixmap, &widgetclass_pixmap, &data_pixmap, &tree_pixmap, &table_pixmap }; /* 47..51 */ 00173 00174 extern int show_comments; 00175 00177 00178 class Widget_Browser : public Fl_Browser_ { 00179 friend class Fl_Type; 00180 00181 // required routines for Fl_Browser_ subclass: 00182 void *item_first() const ; 00183 void *item_next(void *) const ; 00184 void *item_prev(void *) const ; 00185 int item_selected(void *) const ; 00186 void item_select(void *,int); 00187 int item_width(void *) const ; 00188 int item_height(void *) const ; 00189 void item_draw(void *,int,int,int,int) const ; 00190 int incr_height() const ; 00191 00192 public: 00193 00194 int handle(int); 00195 void callback(); 00196 Widget_Browser(int,int,int,int,const char * =0); 00197 }; 00198 00199 static Widget_Browser *widget_browser; 00200 Fl_Widget *make_widget_browser(int x,int y,int w,int h) { 00201 return (widget_browser = new Widget_Browser(x,y,w,h)); 00202 } 00203 00204 void select(Fl_Type *o, int v) { 00205 widget_browser->select(o,v,1); 00206 // Fl_Type::current = o; 00207 } 00208 00209 void select_only(Fl_Type *o) { 00210 widget_browser->select_only(o,1); 00211 } 00212 00213 void deselect() { 00214 widget_browser->deselect(); 00215 //Fl_Type::current = 0; // this breaks the paste & merge functions 00216 } 00217 00218 Fl_Type *Fl_Type::first; 00219 Fl_Type *Fl_Type::last; 00220 00221 static void Widget_Browser_callback(Fl_Widget *o,void *) { 00222 ((Widget_Browser *)o)->callback(); 00223 } 00224 00225 Widget_Browser::Widget_Browser(int X,int Y,int W,int H,const char*l) 00226 : Fl_Browser_(X,Y,W,H,l) { 00227 type(FL_MULTI_BROWSER); 00228 Fl_Widget::callback(Widget_Browser_callback); 00229 when(FL_WHEN_RELEASE); 00230 } 00231 00232 void *Widget_Browser::item_first() const {return Fl_Type::first;} 00233 00234 void *Widget_Browser::item_next(void *l) const {return ((Fl_Type*)l)->next;} 00235 00236 void *Widget_Browser::item_prev(void *l) const {return ((Fl_Type*)l)->prev;} 00237 00238 int Widget_Browser::item_selected(void *l) const {return ((Fl_Type*)l)->new_selected;} 00239 00240 void Widget_Browser::item_select(void *l,int v) {((Fl_Type*)l)->new_selected = v;} 00241 00242 int Widget_Browser::item_height(void *l) const { 00243 Fl_Type *t = (Fl_Type*)l; 00244 if (t->visible) { 00245 if (show_comments && t->comment()) 00246 return textsize()*2+1; 00247 else 00248 return textsize()+2; 00249 } else { 00250 return 0; 00251 } 00252 return ((Fl_Type *)l)->visible ? textsize()+2 : 0; 00253 } 00254 00255 int Widget_Browser::incr_height() const {return textsize()+2;} 00256 00257 static Fl_Type* pushedtitle; 00258 00259 // Generate a descriptive text for this item, to put in browser & window titles 00260 const char* Fl_Type::title() { 00261 const char* c = name(); if (c) return c; 00262 return type_name(); 00263 } 00264 00265 extern const char* subclassname(Fl_Type*); 00266 00267 void Widget_Browser::item_draw(void *v, int X, int Y, int, int) const { 00268 Fl_Type *l = (Fl_Type *)v; 00269 X += 3 + 18 + l->level * 12; 00270 int comment_incr = 0; 00271 if (show_comments && l->comment()) { 00272 char buf[82], *d = buf; 00273 const char *s = l->comment(); 00274 for (int i=0; i<80; i++) { 00275 char c = *s++; 00276 if (c==0 || c=='\n') break; 00277 *d++ = c; 00278 } 00279 *d = 0; 00280 comment_incr = textsize()-1; 00281 if (l->new_selected) fl_color(fl_contrast(FL_DARK_GREEN,FL_SELECTION_COLOR)); 00282 else fl_color(fl_contrast(FL_DARK_GREEN,color())); 00283 fl_font(textfont()+FL_ITALIC, textsize()-2); 00284 fl_draw(buf, (l->is_parent())?X+12:X, Y+12); 00285 Y += comment_incr/2; 00286 comment_incr -= comment_incr/2; 00287 } 00288 if (l->new_selected) fl_color(fl_contrast(FL_FOREGROUND_COLOR,FL_SELECTION_COLOR)); 00289 else fl_color(FL_FOREGROUND_COLOR); 00290 Fl_Pixmap *pm = pixmap[l->pixmapID()]; 00291 if (pm) pm->draw(X-18, Y); 00292 switch (l->is_public()) { 00293 case 0: lock_pixmap.draw(X - 17, Y); break; 00294 case 2: protected_pixmap.draw(X - 17, Y); break; 00295 } 00296 if (l->is_parent()) { 00297 if (!l->next || l->next->level <= l->level) { 00298 if (l->open_!=(l==pushedtitle)) { 00299 fl_loop(X,Y+7,X+5,Y+12,X+10,Y+7); 00300 } else { 00301 fl_loop(X+2,Y+2,X+7,Y+7,X+2,Y+12); 00302 } 00303 } else { 00304 if (l->open_!=(l==pushedtitle)) { 00305 fl_polygon(X,Y+7,X+5,Y+12,X+10,Y+7); 00306 } else { 00307 fl_polygon(X+2,Y+2,X+7,Y+7,X+2,Y+12); 00308 } 00309 } 00310 X += 10; 00311 } 00312 Y += comment_incr; 00313 if (l->is_widget() || l->is_class()) { 00314 const char* c = subclassname(l); 00315 if (!strncmp(c,"Fl_",3)) c += 3; 00316 fl_font(textfont(), textsize()); 00317 fl_draw(c, X, Y+13); 00318 X += int(fl_width(c)+fl_width('n')); 00319 c = l->name(); 00320 if (c) { 00321 fl_font(textfont()|FL_BOLD, textsize()); 00322 fl_draw(c, X, Y+13); 00323 } else if ((c=l->label())) { 00324 char buf[50]; char* p = buf; 00325 *p++ = '"'; 00326 for (int i = 20; i--;) { 00327 if (! (*c & -32)) break; 00328 *p++ = *c++; 00329 } 00330 if (*c) {strcpy(p,"..."); p+=3;} 00331 *p++ = '"'; 00332 *p = 0; 00333 fl_draw(buf, X, Y+13); 00334 } 00335 } else { 00336 const char* c = l->title(); 00337 char buf[60]; char* p = buf; 00338 for (int i = 55; i--;) { 00339 if (! (*c & -32)) break; 00340 *p++ = *c++; 00341 } 00342 if (*c) {strcpy(p,"..."); p+=3;} 00343 *p = 0; 00344 fl_font(textfont() | (l->is_code_block() && (l->level==0 || l->parent->is_class())?0:FL_BOLD), textsize()); 00345 fl_draw(buf, X, Y+13); 00346 } 00347 } 00348 00349 int Widget_Browser::item_width(void *v) const { 00350 Fl_Type *l = (Fl_Type *)v; 00351 00352 if (!l->visible) return 0; 00353 00354 int W = 3 + 16 + 18 + l->level*10; 00355 if (l->is_parent()) W += 10; 00356 00357 if (l->is_widget() || l->is_class()) { 00358 const char* c = l->type_name(); 00359 if (!strncmp(c,"Fl_",3)) c += 3; 00360 fl_font(textfont(), textsize()); 00361 W += int(fl_width(c) + fl_width('n')); 00362 c = l->name(); 00363 if (c) { 00364 fl_font(textfont()|FL_BOLD, textsize()); 00365 W += int(fl_width(c)); 00366 } else if ((c=l->label())) { 00367 char buf[50]; char* p = buf; 00368 *p++ = '"'; 00369 for (int i = 20; i--;) { 00370 if (! (*c & -32)) break; 00371 *p++ = *c++; 00372 } 00373 if (*c) {strcpy(p,"..."); p+=3;} 00374 *p++ = '"'; 00375 *p = 0; 00376 W += int(fl_width(buf)); 00377 } 00378 } else { 00379 const char* c = l->title(); 00380 char buf[60]; char* p = buf; 00381 for (int i = 55; i--;) { 00382 if (! (*c & -32)) break; 00383 *p++ = *c++; 00384 } 00385 if (*c) {strcpy(p,"..."); p+=3;} 00386 *p = 0; 00387 fl_font(textfont() | (l->is_code_block() && (l->level==0 || l->parent->is_class())?0:FL_BOLD), textsize()); 00388 W += int(fl_width(buf)); 00389 } 00390 00391 return W; 00392 } 00393 00394 void redraw_browser() { 00395 widget_browser->redraw(); 00396 } 00397 00398 void Widget_Browser::callback() { 00399 selection_changed((Fl_Type*)selection()); 00400 } 00401 00402 int Widget_Browser::handle(int e) { 00403 static Fl_Type *title; 00404 Fl_Type *l; 00405 int X,Y,W,H; bbox(X,Y,W,H); 00406 switch (e) { 00407 case FL_PUSH: 00408 if (!Fl::event_inside(X,Y,W,H)) break; 00409 l = (Fl_Type*)find_item(Fl::event_y()); 00410 if (l) { 00411 X += 12*l->level + 18 - hposition(); 00412 if (l->is_parent() && Fl::event_x()>X && Fl::event_x()<X+13) { 00413 title = pushedtitle = l; 00414 redraw_line(l); 00415 return 1; 00416 } 00417 } 00418 break; 00419 case FL_DRAG: 00420 if (!title) break; 00421 l = (Fl_Type*)find_item(Fl::event_y()); 00422 if (l) { 00423 X += 12*l->level + 18 - hposition(); 00424 if (l->is_parent() && Fl::event_x()>X && Fl::event_x()<X+13) ; 00425 else l = 0; 00426 } 00427 if (l != pushedtitle) { 00428 if (pushedtitle) redraw_line(pushedtitle); 00429 if (l) redraw_line(l); 00430 pushedtitle = l; 00431 } 00432 return 1; 00433 case FL_RELEASE: 00434 if (!title) { 00435 l = (Fl_Type*)find_item(Fl::event_y()); 00436 if (l && l->new_selected && (Fl::event_clicks() || Fl::event_state(FL_CTRL))) 00437 l->open(); 00438 break; 00439 } 00440 l = pushedtitle; 00441 title = pushedtitle = 0; 00442 if (l) { 00443 if (l->open_) { 00444 l->open_ = 0; 00445 for (Fl_Type*k = l->next; k&&k->level>l->level; k = k->next) 00446 k->visible = 0; 00447 } else { 00448 l->open_ = 1; 00449 for (Fl_Type*k=l->next; k&&k->level>l->level;) { 00450 k->visible = 1; 00451 if (k->is_parent() && !k->open_) { 00452 Fl_Type *j; 00453 for (j = k->next; j && j->level>k->level; j = j->next); 00454 k = j; 00455 } else 00456 k = k->next; 00457 } 00458 } 00459 redraw(); 00460 } 00461 return 1; 00462 } 00463 return Fl_Browser_::handle(e); 00464 } 00465 00466 Fl_Type::Fl_Type() { 00467 factory = 0; 00468 parent = 0; 00469 next = prev = 0; 00470 selected = new_selected = 0; 00471 visible = 0; 00472 name_ = 0; 00473 label_ = 0; 00474 user_data_ = 0; 00475 user_data_type_ = 0; 00476 callback_ = 0; 00477 comment_ = 0; 00478 rtti = 0; 00479 level = 0; 00480 code_position = header_position = -1; 00481 code_position_end = header_position_end = -1; 00482 } 00483 00484 static void fixvisible(Fl_Type *p) { 00485 Fl_Type *t = p; 00486 for (;;) { 00487 if (t->parent) t->visible = t->parent->visible && t->parent->open_; 00488 else t->visible = 1; 00489 t = t->next; 00490 if (!t || t->level <= p->level) break; 00491 } 00492 } 00493 00494 // turn a click at x,y on this into the actual picked object: 00495 Fl_Type* Fl_Type::click_test(int,int) {return 0;} 00496 void Fl_Type::add_child(Fl_Type*, Fl_Type*) {} 00497 void Fl_Type::move_child(Fl_Type*, Fl_Type*) {} 00498 void Fl_Type::remove_child(Fl_Type*) {} 00499 00500 // add a list of widgets as a new child of p: 00501 void Fl_Type::add(Fl_Type *p) { 00502 if (p && parent == p) return; 00503 undo_checkpoint(); 00504 parent = p; 00505 Fl_Type *end = this; 00506 while (end->next) end = end->next; 00507 Fl_Type *q; 00508 int newlevel; 00509 if (p) { 00510 for (q = p->next; q && q->level > p->level; q = q->next); 00511 newlevel = p->level+1; 00512 } else { 00513 q = 0; 00514 newlevel = 0; 00515 } 00516 for (Fl_Type *t = this->next; t; t = t->next) t->level += (newlevel-level); 00517 level = newlevel; 00518 if (q) { 00519 prev = q->prev; 00520 prev->next = this; 00521 q->prev = end; 00522 end->next = q; 00523 } else if (first) { 00524 prev = last; 00525 prev->next = this; 00526 end->next = 0; 00527 last = end; 00528 } else { 00529 first = this; 00530 last = end; 00531 prev = end->next = 0; 00532 } 00533 if (p) p->add_child(this,0); 00534 open_ = 1; 00535 fixvisible(this); 00536 set_modflag(1); 00537 widget_browser->redraw(); 00538 } 00539 00540 // add to a parent before another widget: 00541 void Fl_Type::insert(Fl_Type *g) { 00542 Fl_Type *end = this; 00543 while (end->next) end = end->next; 00544 parent = g->parent; 00545 int newlevel = g->level; 00546 visible = g->visible; 00547 for (Fl_Type *t = this->next; t; t = t->next) t->level += newlevel-level; 00548 level = newlevel; 00549 prev = g->prev; 00550 if (prev) prev->next = this; else first = this; 00551 end->next = g; 00552 g->prev = end; 00553 fixvisible(this); 00554 if (parent) parent->add_child(this, g); 00555 widget_browser->redraw(); 00556 } 00557 00558 // Return message number for I18N... 00559 int 00560 Fl_Type::msgnum() { 00561 int count; 00562 Fl_Type *p; 00563 00564 for (count = 0, p = this; p;) { 00565 if (p->label()) count ++; 00566 if (p != this && p->is_widget() && ((Fl_Widget_Type *)p)->tooltip()) count ++; 00567 00568 if (p->prev) p = p->prev; 00569 else p = p->parent; 00570 } 00571 00572 return count; 00573 } 00574 00575 00576 // delete from parent: 00577 Fl_Type *Fl_Type::remove() { 00578 Fl_Type *end = this; 00579 for (;;) { 00580 if (!end->next || end->next->level <= level) break; 00581 end = end->next; 00582 } 00583 if (prev) prev->next = end->next; 00584 else first = end->next; 00585 if (end->next) end->next->prev = prev; 00586 else last = prev; 00587 Fl_Type *r = end->next; 00588 prev = end->next = 0; 00589 if (parent) parent->remove_child(this); 00590 parent = 0; 00591 widget_browser->redraw(); 00592 selection_changed(0); 00593 return r; 00594 } 00595 00596 // update a string member: 00597 int storestring(const char *n, const char * & p, int nostrip) { 00598 if (n == p) return 0; 00599 undo_checkpoint(); 00600 int length = 0; 00601 if (n) { // see if blank, strip leading & trailing blanks 00602 if (!nostrip) while (isspace(*n)) n++; 00603 const char *e = n + strlen(n); 00604 if (!nostrip) while (e > n && isspace(*(e-1))) e--; 00605 length = e-n; 00606 if (!length) n = 0; 00607 } 00608 if (n == p) return 0; 00609 if (n && p && !strncmp(n,p,length) && !p[length]) return 0; 00610 if (p) free((void *)p); 00611 if (!n || !*n) { 00612 p = 0; 00613 } else { 00614 char *q = (char *)malloc(length+1); 00615 strlcpy(q,n,length+1); 00616 p = q; 00617 } 00618 set_modflag(1); 00619 return 1; 00620 } 00621 00622 void Fl_Type::name(const char *n) { 00623 int nostrip = is_comment(); 00624 if (storestring(n,name_,nostrip)) { 00625 if (visible) widget_browser->redraw(); 00626 } 00627 } 00628 00629 void Fl_Type::label(const char *n) { 00630 if (storestring(n,label_,1)) { 00631 setlabel(label_); 00632 if (visible && !name_) widget_browser->redraw(); 00633 } 00634 } 00635 00636 void Fl_Type::callback(const char *n) { 00637 storestring(n,callback_); 00638 } 00639 00640 void Fl_Type::user_data(const char *n) { 00641 storestring(n,user_data_); 00642 } 00643 00644 void Fl_Type::user_data_type(const char *n) { 00645 storestring(n,user_data_type_); 00646 } 00647 00648 void Fl_Type::comment(const char *n) { 00649 storestring(n, comment_, 1); 00650 } 00651 00652 void Fl_Type::open() { 00653 printf("Open of '%s' is not yet implemented\n",type_name()); 00654 } 00655 00656 void Fl_Type::setlabel(const char *) {} 00657 00658 Fl_Type::~Fl_Type() { 00659 // warning: destructor only works for widgets that have been add()ed. 00660 if (widget_browser) widget_browser->deleting(this); 00661 if (prev) prev->next = next; else first = next; 00662 if (next) next->prev = prev; else last = prev; 00663 if (current == this) current = 0; 00664 if (parent) parent->remove_child(this); 00665 if (name_) free((void*)name_); 00666 if (label_) free((void*)label_); 00667 if (callback_) free((void*)callback_); 00668 if (user_data_) free((void*)user_data_); 00669 if (user_data_type_) free((void*)user_data_type_); 00670 if (comment_) free((void*)comment_); 00671 } 00672 00673 int Fl_Type::is_parent() const {return 0;} 00674 int Fl_Type::is_widget() const {return 0;} 00675 int Fl_Type::is_valuator() const {return 0;} 00676 int Fl_Type::is_spinner() const {return 0;} 00677 int Fl_Type::is_button() const {return 0;} 00678 int Fl_Type::is_input() const {return 0;} 00679 int Fl_Type::is_value_input() const {return 0;} 00680 int Fl_Type::is_text_display() const {return 0;} 00681 int Fl_Type::is_menu_item() const {return 0;} 00682 int Fl_Type::is_menu_button() const {return 0;} 00683 int Fl_Type::is_group() const {return 0;} 00684 int Fl_Type::is_window() const {return 0;} 00685 int Fl_Type::is_code_block() const {return 0;} 00686 int Fl_Type::is_decl_block() const {return 0;} 00687 int Fl_Type::is_comment() const {return 0;} 00688 int Fl_Type::is_class() const {return 0;} 00689 int Fl_Type::is_public() const {return 1;} 00690 00691 int Fl_Code_Type::is_public()const { return -1; } 00692 int Fl_CodeBlock_Type::is_public()const { return -1; } 00693 00694 00696 00697 Fl_Type *in_this_only; // set if menu popped-up in window 00698 00699 void select_all_cb(Fl_Widget *,void *) { 00700 Fl_Type *p = Fl_Type::current ? Fl_Type::current->parent : 0; 00701 if (in_this_only) { 00702 Fl_Type *t = p; 00703 for (; t && t != in_this_only; t = t->parent); 00704 if (t != in_this_only) p = in_this_only; 00705 } 00706 for (;;) { 00707 if (p) { 00708 int foundany = 0; 00709 for (Fl_Type *t = p->next; t && t->level>p->level; t = t->next) { 00710 if (!t->new_selected) {widget_browser->select(t,1,0); foundany = 1;} 00711 } 00712 if (foundany) break; 00713 p = p->parent; 00714 } else { 00715 for (Fl_Type *t = Fl_Type::first; t; t = t->next) 00716 widget_browser->select(t,1,0); 00717 break; 00718 } 00719 } 00720 selection_changed(p); 00721 } 00722 00723 void select_none_cb(Fl_Widget *,void *) { 00724 Fl_Type *p = Fl_Type::current ? Fl_Type::current->parent : 0; 00725 if (in_this_only) { 00726 Fl_Type *t = p; 00727 for (; t && t != in_this_only; t = t->parent); 00728 if (t != in_this_only) p = in_this_only; 00729 } 00730 for (;;) { 00731 if (p) { 00732 int foundany = 0; 00733 for (Fl_Type *t = p->next; t && t->level>p->level; t = t->next) { 00734 if (t->new_selected) {widget_browser->select(t,0,0); foundany = 1;} 00735 } 00736 if (foundany) break; 00737 p = p->parent; 00738 } else { 00739 for (Fl_Type *t = Fl_Type::first; t; t = t->next) 00740 widget_browser->select(t,0,0); 00741 break; 00742 } 00743 } 00744 selection_changed(p); 00745 } 00746 00747 static void delete_children(Fl_Type *p) { 00748 Fl_Type *f; 00749 for (f = p; f && f->next && f->next->level > p->level; f = f->next); 00750 for (; f != p; ) { 00751 Fl_Type *g = f->prev; 00752 delete f; 00753 f = g; 00754 } 00755 } 00756 00757 void delete_all(int selected_only) { 00758 for (Fl_Type *f = Fl_Type::first; f;) { 00759 if (f->selected || !selected_only) { 00760 delete_children(f); 00761 Fl_Type *g = f->next; 00762 delete f; 00763 f = g; 00764 } else f = f->next; 00765 } 00766 if(!selected_only) { 00767 include_H_from_C=1; 00768 use_FL_COMMAND=0; 00769 } 00770 00771 selection_changed(0); 00772 } 00773 00774 // move f (and it's children) into list before g: 00775 // returns pointer to whatever is after f & children 00776 void Fl_Type::move_before(Fl_Type* g) { 00777 if (level != g->level) printf("move_before levels don't match! %d %d\n", 00778 level, g->level); 00779 Fl_Type* n; 00780 for (n = next; n && n->level > level; n = n->next); 00781 if (n == g) return; 00782 Fl_Type *l = n ? n->prev : Fl_Type::last; 00783 prev->next = n; 00784 if (n) n->prev = prev; else Fl_Type::last = prev; 00785 prev = g->prev; 00786 l->next = g; 00787 if (prev) prev->next = this; else Fl_Type::first = this; 00788 g->prev = l; 00789 if (parent && is_widget()) parent->move_child(this,g); 00790 widget_browser->inserting(g, this); 00791 widget_browser->display(this); 00792 widget_browser->redraw(); 00793 } 00794 00795 // move selected widgets in their parent's list: 00796 void earlier_cb(Fl_Widget*,void*) { 00797 Fl_Type *f; 00798 int mod = 0; 00799 for (f = Fl_Type::first; f; ) { 00800 Fl_Type* nxt = f->next; 00801 if (f->selected) { 00802 Fl_Type* g; 00803 for (g = f->prev; g && g->level > f->level; g = g->prev); 00804 if (g && g->level == f->level && !g->selected) { 00805 f->move_before(g); 00806 mod = 1; 00807 } 00808 } 00809 f = nxt; 00810 } 00811 if (mod) set_modflag(1); 00812 } 00813 00814 void later_cb(Fl_Widget*,void*) { 00815 Fl_Type *f; 00816 int mod = 0; 00817 for (f = Fl_Type::last; f; ) { 00818 Fl_Type* prv = f->prev; 00819 if (f->selected) { 00820 Fl_Type* g; 00821 for (g = f->next; g && g->level > f->level; g = g->next); 00822 if (g && g->level == f->level && !g->selected) { 00823 g->move_before(f); 00824 mod = 1; 00825 } 00826 } 00827 f = prv; 00828 } 00829 if (mod) set_modflag(1); 00830 } 00831 00833 00834 // write a widget and all it's children: 00835 void Fl_Type::write() { 00836 write_indent(level); 00837 write_word(type_name()); 00838 00839 if (is_class()) { 00840 const char * p = ((Fl_Class_Type*)this)->prefix(); 00841 if (p && strlen(p)) 00842 write_word(p); 00843 } 00844 00845 write_word(name()); 00846 write_open(level); 00847 write_properties(); 00848 write_close(level); 00849 if (!is_parent()) return; 00850 // now do children: 00851 write_open(level); 00852 Fl_Type *child; 00853 for (child = next; child && child->level > level; child = child->next) 00854 if (child->level == level+1) child->write(); 00855 write_close(level); 00856 } 00857 00858 void Fl_Type::write_properties() { 00859 // repeat this for each attribute: 00860 if (label()) { 00861 write_indent(level+1); 00862 write_word("label"); 00863 write_word(label()); 00864 } 00865 if (user_data()) { 00866 write_indent(level+1); 00867 write_word("user_data"); 00868 write_word(user_data()); 00869 } 00870 if (user_data_type()) { 00871 write_word("user_data_type"); 00872 write_word(user_data_type()); 00873 } 00874 if (callback()) { 00875 write_indent(level+1); 00876 write_word("callback"); 00877 write_word(callback()); 00878 } 00879 if (comment()) { 00880 write_indent(level+1); 00881 write_word("comment"); 00882 write_word(comment()); 00883 } 00884 if (is_parent() && open_) write_word("open"); 00885 if (selected) write_word("selected"); 00886 } 00887 00888 void Fl_Type::read_property(const char *c) { 00889 if (!strcmp(c,"label")) 00890 label(read_word()); 00891 else if (!strcmp(c,"user_data")) 00892 user_data(read_word()); 00893 else if (!strcmp(c,"user_data_type")) 00894 user_data_type(read_word()); 00895 else if (!strcmp(c,"callback")) 00896 callback(read_word()); 00897 else if (!strcmp(c,"comment")) 00898 comment(read_word()); 00899 else if (!strcmp(c,"open")) 00900 open_ = 1; 00901 else if (!strcmp(c,"selected")) 00902 select(this,1); 00903 else 00904 read_error("Unknown property \"%s\"", c); 00905 } 00906 00907 int Fl_Type::read_fdesign(const char*, const char*) {return 0;} 00908 00912 int has_toplevel_function(const char *rtype, const char *sig) { 00913 Fl_Type *child; 00914 for (child = Fl_Type::first; child; child = child->next) { 00915 if (!child->is_in_class() && strcmp(child->type_name(), "Function")==0) { 00916 const Fl_Function_Type *fn = (const Fl_Function_Type*)child; 00917 if (fn->has_signature(rtype, sig)) 00918 return 1; 00919 } 00920 } 00921 return 0; 00922 } 00923 00927 void Fl_Type::write_comment_h(const char *pre) 00928 { 00929 if (comment()) { 00930 write_h("%s/**\n", pre); 00931 const char *s = comment(); 00932 write_h("%s ", pre); 00933 while(*s) { 00934 if (*s=='\n') { 00935 if (s[1]) { 00936 write_h("\n%s ", pre); 00937 } 00938 } else { 00939 write_h("%c", *s); // FIXME this is much too slow! 00940 } 00941 s++; 00942 } 00943 write_h("\n%s*/\n", pre); 00944 } 00945 } 00946 00950 void Fl_Type::write_comment_c(const char *pre) 00951 { 00952 if (comment()) { 00953 write_c("%s/**\n", pre); 00954 const char *s = comment(); 00955 write_c("%s ", pre); 00956 while(*s) { 00957 if (*s=='\n') { 00958 if (s[1]) { 00959 write_c("\n%s ", pre); 00960 } 00961 } else { 00962 write_c("%c", *s); // FIXME this is much too slow! 00963 } 00964 s++; 00965 } 00966 write_c("\n%s*/\n", pre); 00967 } 00968 } 00969 00974 void reveal_in_browser(Fl_Type *t) { 00975 Fl_Type *p = t->parent; 00976 if (p) { 00977 for (;;) { 00978 if (!p->open_) 00979 p->open_ = 1; 00980 if (!p->parent) break; 00981 p = p->parent; 00982 } 00983 fixvisible(p); 00984 } 00985 widget_browser->display(t); 00986 redraw_browser(); 00987 } 00988 00994 Fl_Widget *Fl_Type::enter_live_mode(int) { 00995 return 0L; 00996 } 00997 01002 void Fl_Type::leave_live_mode() { 01003 } 01004 01008 void Fl_Type::copy_properties() { 01009 } 01010 01019 int Fl_Type::user_defined(const char* cbname) const { 01020 for (Fl_Type* p = Fl_Type::first; p ; p = p->next) 01021 if (strcmp(p->type_name(), "Function") == 0 && p->name() != 0) 01022 if (strncmp(p->name(), cbname, strlen(cbname)) == 0) 01023 if (p->name()[strlen(cbname)] == '(') 01024 return 1; 01025 return 0; 01026 } 01027 01028 01029 // 01030 // End of "$Id: Fl_Type.cxx 8172 2011-01-03 08:28:38Z matt $". 01031 //