|
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_Group_Type.cxx 8172 2011-01-03 08:28:38Z matt $" 00003 // 00004 // Fl_Group object code for the Fast Light Tool Kit (FLTK). 00005 // 00006 // Object describing an Fl_Group and links to Fl_Window_Type.C and 00007 // the Fl_Tabs widget, with special stuff to select tab items and 00008 // insure that only one is visible. 00009 // 00010 // Copyright 1998-2010 by Bill Spitzak and others. 00011 // 00012 // This library is free software; you can redistribute it and/or 00013 // modify it under the terms of the GNU Library General Public 00014 // License as published by the Free Software Foundation; either 00015 // version 2 of the License, or (at your option) any later version. 00016 // 00017 // This library is distributed in the hope that it will be useful, 00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00020 // Library General Public License for more details. 00021 // 00022 // You should have received a copy of the GNU Library General Public 00023 // License along with this library; if not, write to the Free Software 00024 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00025 // USA. 00026 // 00027 // Please report all bugs and problems on the following page: 00028 // 00029 // http://www.fltk.org/str.php 00030 // 00031 00032 00033 #include <FL/Fl.H> 00034 #include <FL/Fl_Group.H> 00035 #include <FL/Fl_Table.H> 00036 #include <FL/fl_message.H> 00037 #include "Fl_Widget_Type.h" 00038 #include "../src/flstring.h" 00039 00040 // Override group's resize behavior to do nothing to children: 00041 void igroup::resize(int X, int Y, int W, int H) { 00042 Fl_Widget::resize(X,Y,W,H); 00043 redraw(); 00044 } 00045 00046 Fl_Group_Type Fl_Group_type; // the "factory" 00047 00048 Fl_Type *Fl_Group_Type::make() { 00049 return Fl_Widget_Type::make(); 00050 } 00051 00052 void fix_group_size(Fl_Type *tt) { 00053 if (!tt || !tt->is_group()) return; 00054 Fl_Group_Type* t = (Fl_Group_Type*)tt; 00055 int X = t->o->x(); 00056 int Y = t->o->y(); 00057 int R = X+t->o->w(); 00058 int B = Y+t->o->h(); 00059 for (Fl_Type *nn = t->next; nn && nn->level > t->level; nn = nn->next) { 00060 if (!nn->is_widget() || nn->is_menu_item()) continue; 00061 Fl_Widget_Type* n = (Fl_Widget_Type*)nn; 00062 int x = n->o->x(); if (x < X) X = x; 00063 int y = n->o->y(); if (y < Y) Y = y; 00064 int r = x+n->o->w();if (r > R) R = r; 00065 int b = y+n->o->h();if (b > B) B = b; 00066 } 00067 t->o->resize(X,Y,R-X,B-Y); 00068 } 00069 00070 extern int force_parent; 00071 00072 void group_cb(Fl_Widget *, void *) { 00073 // Find the current widget: 00074 Fl_Type *qq = Fl_Type::current; 00075 while (qq && (!qq->is_widget() || qq->is_menu_item())) qq = qq->parent; 00076 if (!qq || qq->level < 1 || (qq->level == 1 && !strcmp(qq->type_name(), "widget_class"))) { 00077 fl_message("Please select widgets to group"); 00078 return; 00079 } 00080 Fl_Widget_Type* q = (Fl_Widget_Type*)qq; 00081 force_parent = 1; 00082 Fl_Group_Type *n = (Fl_Group_Type*)(Fl_Group_type.make()); 00083 n->move_before(q); 00084 n->o->resize(q->o->x(),q->o->y(),q->o->w(),q->o->h()); 00085 for (Fl_Type *t = Fl_Type::first; t;) { 00086 if (t->level != n->level || t == n || !t->selected) { 00087 t = t->next; continue;} 00088 Fl_Type *nxt = t->remove(); 00089 t->add(n); 00090 t = nxt; 00091 } 00092 fix_group_size(n); 00093 } 00094 00095 void ungroup_cb(Fl_Widget *, void *) { 00096 // Find the group: 00097 Fl_Type *q = Fl_Type::current; 00098 while (q && (!q->is_widget() || q->is_menu_item())) q = q->parent; 00099 if (q) q = q->parent; 00100 if (!q || q->level < 1 || (q->level == 1 && !strcmp(q->type_name(), "widget_class"))) { 00101 fl_message("Please select widgets in a group"); 00102 return; 00103 } 00104 Fl_Type* n; 00105 for (n = q->next; n && n->level > q->level; n = n->next) { 00106 if (n->level == q->level+1 && !n->selected) { 00107 fl_message("Please select all widgets in group"); 00108 return; 00109 } 00110 } 00111 for (n = q->next; n && n->level > q->level;) { 00112 Fl_Type *nxt = n->remove(); 00113 n->insert(q); 00114 n = nxt; 00115 } 00116 delete q; 00117 } 00118 00120 00121 #include <stdio.h> 00122 00123 void Fl_Group_Type::write_code1() { 00124 Fl_Widget_Type::write_code1(); 00125 } 00126 00127 void Fl_Group_Type::write_code2() { 00128 const char *var = name() ? name() : "o"; 00129 write_extra_code(); 00130 write_c("%s%s->end();\n", indent(), var); 00131 if (resizable()) { 00132 write_c("%sFl_Group::current()->resizable(%s);\n", indent(), var); 00133 } 00134 write_block_close(); 00135 } 00136 00138 00139 const char pack_type_name[] = "Fl_Pack"; 00140 00141 Fl_Menu_Item pack_type_menu[] = { 00142 {"HORIZONTAL", 0, 0, (void*)Fl_Pack::HORIZONTAL}, 00143 {"VERTICAL", 0, 0, (void*)Fl_Pack::VERTICAL}, 00144 {0}}; 00145 00146 Fl_Pack_Type Fl_Pack_type; // the "factory" 00147 00149 00150 static const int MAX_ROWS = 14; 00151 static const int MAX_COLS = 7; 00152 00153 // this is a minimal table widget used as an example when adding tables in Fluid 00154 class Fluid_Table : public Fl_Table { 00155 int data[MAX_ROWS][MAX_COLS]; // data array for cells 00156 00157 // Draw the row/col headings 00158 // Make this a dark thin upbox with the text inside. 00159 // 00160 void DrawHeader(const char *s, int X, int Y, int W, int H) { 00161 fl_push_clip(X,Y,W,H); 00162 fl_draw_box(FL_THIN_UP_BOX, X,Y,W,H, row_header_color()); 00163 fl_color(FL_BLACK); 00164 fl_draw(s, X,Y,W,H, FL_ALIGN_CENTER); 00165 fl_pop_clip(); 00166 } 00167 // Draw the cell data 00168 // Dark gray text on white background with subtle border 00169 // 00170 void DrawData(const char *s, int X, int Y, int W, int H) { 00171 fl_push_clip(X,Y,W,H); 00172 // Draw cell bg 00173 fl_color(FL_WHITE); fl_rectf(X,Y,W,H); 00174 // Draw cell data 00175 fl_color(FL_GRAY0); fl_draw(s, X,Y,W,H, FL_ALIGN_CENTER); 00176 // Draw box border 00177 fl_color(color()); fl_rect(X,Y,W,H); 00178 fl_pop_clip(); 00179 } 00180 // Handle drawing table's cells 00181 // Fl_Table calls this function to draw each visible cell in the table. 00182 // It's up to us to use FLTK's drawing functions to draw the cells the way we want. 00183 // 00184 void draw_cell(TableContext context, int ROW=0, int COL=0, int X=0, int Y=0, int W=0, int H=0) { 00185 static char s[40]; 00186 switch ( context ) { 00187 case CONTEXT_STARTPAGE: // before page is drawn.. 00188 fl_font(FL_HELVETICA, 16); // set the font for our drawing operations 00189 return; 00190 case CONTEXT_COL_HEADER: // Draw column headers 00191 sprintf(s,"%c",'A'+COL); // "A", "B", "C", etc. 00192 DrawHeader(s,X,Y,W,H); 00193 return; 00194 case CONTEXT_ROW_HEADER: // Draw row headers 00195 sprintf(s,"%03d:",ROW); // "001:", "002:", etc 00196 DrawHeader(s,X,Y,W,H); 00197 return; 00198 case CONTEXT_CELL: // Draw data in cells 00199 sprintf(s,"%d",data[ROW][COL]); 00200 DrawData(s,X,Y,W,H); 00201 return; 00202 default: 00203 return; 00204 } 00205 } 00206 public: 00207 Fluid_Table(int x, int y, int w, int h, const char *l=0L) 00208 : Fl_Table(x, y, w, h, l) { 00209 for ( int r=0; r<MAX_ROWS; r++ ) 00210 for ( int c=0; c<MAX_COLS; c++ ) 00211 data[r][c] = 1000+(r*1000)+c; 00212 // Rows 00213 rows(MAX_ROWS); // how many rows 00214 row_header(1); // enable row headers (along left) 00215 row_height_all(20); // default height of rows 00216 row_resize(0); // disable row resizing // Cols 00217 cols(MAX_COLS); // how many columns 00218 col_header(1); // enable column headers (along top) 00219 col_width_all(80); // default width of columns 00220 col_resize(1); // enable column resizing 00221 } 00222 }; 00223 00224 const char table_type_name[] = "Fl_Table"; 00225 00226 Fl_Table_Type Fl_Table_type; // the "factory" 00227 00228 Fl_Widget *Fl_Table_Type::widget(int X,int Y,int W,int H) { 00229 Fluid_Table *table = new Fluid_Table(X, Y, W, H); 00230 return table; 00231 } 00232 00234 00235 const char tabs_type_name[] = "Fl_Tabs"; 00236 00237 // Override group's resize behavior to do nothing to children: 00238 void itabs::resize(int X, int Y, int W, int H) { 00239 Fl_Widget::resize(X,Y,W,H); 00240 redraw(); 00241 } 00242 00243 Fl_Tabs_Type Fl_Tabs_type; // the "factory" 00244 00245 // This is called when user clicks on a widget in the window. See 00246 // if it is a tab title, and adjust visibility and return new selection: 00247 // If none, return o unchanged: 00248 00249 Fl_Type* Fl_Tabs_Type::click_test(int x, int y) { 00250 Fl_Tabs *t = (Fl_Tabs*)o; 00251 Fl_Widget *a = t->which(x,y); 00252 if (!a) return 0; // didn't click on tab 00253 // changing the visible tab has an impact on the generated 00254 // source code, so mark this project as changed. 00255 int changed = (a!=t->value()); 00256 // okay, run the tabs ui until they let go of mouse: 00257 t->handle(FL_PUSH); 00258 Fl::pushed(t); 00259 while (Fl::pushed()==t) Fl::wait(); 00260 if (changed) set_modflag(1); 00261 return (Fl_Type*)(t->value()->user_data()); 00262 } 00263 00265 00266 const char wizard_type_name[] = "Fl_Wizard"; 00267 00268 // Override group's resize behavior to do nothing to children: 00269 void iwizard::resize(int X, int Y, int W, int H) { 00270 Fl_Widget::resize(X,Y,W,H); 00271 redraw(); 00272 } 00273 00274 Fl_Wizard_Type Fl_Wizard_type; // the "factory" 00275 00276 // This is called when o is created. If it is in the tab group make 00277 // sure it is visible: 00278 00279 void Fl_Group_Type::add_child(Fl_Type* cc, Fl_Type* before) { 00280 Fl_Widget_Type* c = (Fl_Widget_Type*)cc; 00281 Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0; 00282 ((Fl_Group*)o)->insert(*(c->o), b); 00283 o->redraw(); 00284 } 00285 00286 void Fl_Tabs_Type::add_child(Fl_Type* c, Fl_Type* before) { 00287 Fl_Group_Type::add_child(c, before); 00288 } 00289 00290 void Fl_Table_Type::add_child(Fl_Type* cc, Fl_Type* before) { 00291 Fl_Widget_Type* c = (Fl_Widget_Type*)cc; 00292 Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0; 00293 if (((Fl_Table*)o)->children()==1) { // the FLuid_Table has one extra child 00294 fl_message("Inserting child widgets into an Fl_Table is not recommended.\n" 00295 "Please refer to the documentation on Fl_Table."); 00296 } 00297 ((Fl_Table*)o)->insert(*(c->o), b); 00298 o->redraw(); 00299 } 00300 00301 00302 // This is called when o is deleted. If it is in the tab group make 00303 // sure it is not visible: 00304 00305 void Fl_Group_Type::remove_child(Fl_Type* cc) { 00306 Fl_Widget_Type* c = (Fl_Widget_Type*)cc; 00307 ((Fl_Group*)o)->remove(c->o); 00308 o->redraw(); 00309 } 00310 00311 void Fl_Tabs_Type::remove_child(Fl_Type* cc) { 00312 Fl_Widget_Type* c = (Fl_Widget_Type*)cc; 00313 Fl_Tabs *t = (Fl_Tabs*)o; 00314 if (t->value() == c->o) t->value(0); 00315 Fl_Group_Type::remove_child(c); 00316 } 00317 00318 void Fl_Table_Type::remove_child(Fl_Type* cc) { 00319 Fl_Widget_Type* c = (Fl_Widget_Type*)cc; 00320 ((Fl_Table*)o)->remove(*(c->o)); 00321 o->redraw(); 00322 } 00323 00324 // move, don't change selected value: 00325 00326 void Fl_Group_Type::move_child(Fl_Type* cc, Fl_Type* before) { 00327 Fl_Widget_Type* c = (Fl_Widget_Type*)cc; 00328 Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0; 00329 ((Fl_Group*)o)->remove(c->o); 00330 ((Fl_Group*)o)->insert(*(c->o), b); 00331 o->redraw(); 00332 } 00333 00334 void Fl_Table_Type::move_child(Fl_Type* cc, Fl_Type* before) { 00335 Fl_Widget_Type* c = (Fl_Widget_Type*)cc; 00336 Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0; 00337 ((Fl_Table*)o)->remove(*(c->o)); 00338 ((Fl_Table*)o)->insert(*(c->o), b); 00339 o->redraw(); 00340 } 00341 00343 // live mode support 00344 00345 Fl_Widget *Fl_Group_Type::enter_live_mode(int) { 00346 Fl_Group *grp = new Fl_Group(o->x(), o->y(), o->w(), o->h()); 00347 live_widget = grp; 00348 if (live_widget) { 00349 copy_properties(); 00350 Fl_Type *n; 00351 for (n = next; n && n->level > level; n = n->next) { 00352 if (n->level == level+1) 00353 n->enter_live_mode(); 00354 } 00355 grp->end(); 00356 } 00357 return live_widget; 00358 } 00359 00360 Fl_Widget *Fl_Tabs_Type::enter_live_mode(int) { 00361 Fl_Tabs *grp = new Fl_Tabs(o->x(), o->y(), o->w(), o->h()); 00362 live_widget = grp; 00363 if (live_widget) { 00364 copy_properties(); 00365 Fl_Type *n; 00366 for (n = next; n && n->level > level; n = n->next) { 00367 if (n->level == level+1) 00368 n->enter_live_mode(); 00369 } 00370 grp->end(); 00371 } 00372 grp->value(((Fl_Tabs*)o)->value()); 00373 return live_widget; 00374 } 00375 00376 Fl_Widget *Fl_Table_Type::enter_live_mode(int) { 00377 Fl_Group *grp = new Fluid_Table(o->x(), o->y(), o->w(), o->h()); 00378 live_widget = grp; 00379 if (live_widget) { 00380 copy_properties(); 00381 grp->end(); 00382 } 00383 return live_widget; 00384 } 00385 00386 void Fl_Group_Type::leave_live_mode() { 00387 } 00388 00392 void Fl_Group_Type::copy_properties() { 00393 Fl_Widget_Type::copy_properties(); 00394 } 00395 00397 // some other group subclasses that fluid does not treat specially: 00398 00399 #include <FL/Fl_Scroll.H> 00400 00401 const char scroll_type_name[] = "Fl_Scroll"; 00402 00403 Fl_Widget *Fl_Scroll_Type::enter_live_mode(int) { 00404 Fl_Group *grp = new Fl_Scroll(o->x(), o->y(), o->w(), o->h()); 00405 grp->show(); 00406 live_widget = grp; 00407 if (live_widget) { 00408 copy_properties(); 00409 Fl_Type *n; 00410 for (n = next; n && n->level > level; n = n->next) { 00411 if (n->level == level+1) 00412 n->enter_live_mode(); 00413 } 00414 grp->end(); 00415 } 00416 return live_widget; 00417 } 00418 00419 Fl_Menu_Item scroll_type_menu[] = { 00420 {"BOTH", 0, 0, 0/*(void*)Fl_Scroll::BOTH*/}, 00421 {"HORIZONTAL", 0, 0, (void*)Fl_Scroll::HORIZONTAL}, 00422 {"VERTICAL", 0, 0, (void*)Fl_Scroll::VERTICAL}, 00423 {"HORIZONTAL_ALWAYS", 0, 0, (void*)Fl_Scroll::HORIZONTAL_ALWAYS}, 00424 {"VERTICAL_ALWAYS", 0, 0, (void*)Fl_Scroll::VERTICAL_ALWAYS}, 00425 {"BOTH_ALWAYS", 0, 0, (void*)Fl_Scroll::BOTH_ALWAYS}, 00426 {0}}; 00427 00428 Fl_Scroll_Type Fl_Scroll_type; // the "factory" 00429 00430 void Fl_Scroll_Type::copy_properties() { 00431 Fl_Group_Type::copy_properties(); 00432 Fl_Scroll *s = (Fl_Scroll*)o, *d = (Fl_Scroll*)live_widget; 00433 d->position(s->xposition(), s->yposition()); 00434 d->type(s->type()); // TODO: get this flag from Fl_Scroll_Type! 00435 d->scrollbar.align(s->scrollbar.align()); 00436 d->hscrollbar.align(s->hscrollbar.align()); 00437 } 00438 00440 00441 const char tile_type_name[] = "Fl_Tile"; 00442 00443 Fl_Tile_Type Fl_Tile_type; // the "factory" 00444 00445 void Fl_Tile_Type::copy_properties() { 00446 Fl_Group_Type::copy_properties(); 00447 // no additional properties 00448 } 00449 00450 // 00451 // End of "$Id: Fl_Group_Type.cxx 8172 2011-01-03 08:28:38Z matt $". 00452 //