latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 /*-------------------------------------------------------------------- 00025 * project ....: LTI-Lib: Image Processing and Computer Vision Library 00026 * file .......: ltiViewerBase3D.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 1.12.2001 00030 * revisions ..: $Id: ltiViewerBase3D.h,v 1.8 2006/02/08 12:58:31 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_VIEWER_BASE_3D_H_ 00034 #define _LTI_VIEWER_BASE_3D_H_ 00035 00036 #include "ltiConfig.h" 00037 00038 #ifdef HAVE_GTK 00039 00040 #include "ltiImage.h" 00041 #include "ltiViewerBase.h" 00042 #include "ltiMutex.h" 00043 #include "ltiSemaphore.h" 00044 #include "ltiDraw3D.h" 00045 00046 #include <gtk/gtk.h> 00047 #include "ltiGtkColorDialog.h" 00048 00049 00050 namespace lti { 00051 00052 /** 00053 * \page viewer3D Creating new viewers for 3D data 00054 * 00055 * Even if we have tried to create simple ways to inherit the 3D 00056 * manipulation functionality for 3D viewers, it is necessary to 00057 * explain the steps required when creating new viewer classes. 00058 * 00059 * All classes inherited from viewerBase3D contain three enclosed classes 00060 * (which can of course be inherited from parent classes): 00061 * viewerBase3D::parameters, viewerBase3D::configDialog and 00062 * viewerBase3D::mainWindow 00063 * 00064 * \section v3Dparams Classes parameters and configDialog 00065 * 00066 * Usually, each new viewer will require new parameters that specify 00067 * different display modalities (like show coordinate system, 00068 * display data with lines or points, etc.), and the user usually 00069 * wants to set them interactively using some dialogs. All new 00070 * parameters added should be encapsulated in an enclosed class with the 00071 * name "parameters" in your new %viewer class. These %parameters classes 00072 * are similar to the lti::functor::parameters, but they include also 00073 * some special attributes used to tranfer some information about the 00074 * data being currently displayed to the configuration dialogs(see also 00075 * method lti::viewerBase3D::mainWindow::prepareParameters() ). They will 00076 * implement the typical parameters interface: (read, write, 00077 * getTypeName, copy, clone, and so on). 00078 * 00079 * The dialog used to set this parameters is implemented also in an 00080 * enclosed class named "configDialog". One of the most important 00081 * members in this class is 00082 * lti::viewerBase3D::configDialog::insertPages, which will insert 00083 * the a new settings page into the default dialog. You will 00084 * usually want to add the common dialog with the line 00085 * 00086 * \code 00087 * appendPage(buildCommonPage()); 00088 * \endcode 00089 * 00090 * For your own parameter configuration pages you can create methods like 00091 * 00092 * \code 00093 * configDialog::pageWidget buildMyOwnPage() { 00094 * pageWidget pw; // this object will be returned 00095 * pw.label = "my page"; // the name of the widget 00096 * 00097 * // create the GTK widget 00098 * GtkWidget* theWidget = gtk_vbox_new (FALSE, 0); 00099 * // ... 00100 * 00101 * pw.widget = theWidget; 00102 * return pw; 00103 * }; 00104 * \endcode 00105 * 00106 * The other two methods will copy the data from the parameters into 00107 * the dialog or otherwise. They are called 00108 * lti::viewerBase3D::configDialog::getDialogData() and 00109 * lti::viewerBase3D::configDialog::setDialogData(). 00110 * 00111 * Of course, you don't need to reimplement this two classes if you don't 00112 * have any new parameters in your own viewer. 00113 * 00114 * \section v3Dmainwnd mainWindow 00115 * 00116 * The main window administrates the real viewer, i.e. the window where 00117 * all data is drawn. It also checks for all important events, like 00118 * right-mouse button pressed to show the configuration dialog, and 00119 * drag of mouse to change the 3D camera parameters. 00120 * 00121 * The method lti::viewerBase3D::mainWindow::dataToImage() will draw 00122 * the data using the internal lti::draw3D object 00123 * (lti::viewerBase3D::mainWindow::drawTool) into the proper image. 00124 * You can use here and in other methods the attributes 00125 * lti::viewerBase3D::mainWindow::mouseButtonPressed and 00126 * lti::viewerBase3D::mainWindow::lastMousePos in order to check if 00127 * you want to draw your data in a way or another, depending on how 00128 * the user interacts with the viewer. For example, if the user is 00129 * dragging the camera position, zooming, etc. He has the mouse 00130 * button pressed (mouseButtonPressed!=0), and you can draw a 00131 * preview of the data to allow a faster interation. 00132 * 00133 * When you request the configuration dialog (usually pressing the 00134 * right mouse button), you will need to transfer some informational data 00135 * from the main window to the configuration dialog. This is done through 00136 * the informational attributes of the parameters-class, which can be filled 00137 * within the method lti::viewerBase3D::mainWindow::prepareParameters(). 00138 * 00139 * \section v3Dmethods Important viewerBase3D methods 00140 * 00141 * The inheritance from viewerBase3D implies the implementation of following 00142 * methods: 00143 * 00144 * - lti::viewerBase3D::getNewMainWindow(). Here you will need to return 00145 * a new instance of the proper mainWindow class, i.e. just type a 00146 * <code>return new mainWindow()</code>. 00147 * - show(const T& yourData). These methods should copy the data you 00148 * want to display, into the mainWindow instance. To ensure that 00149 * the proper instance exist, you need to call first 00150 * lti::viewerBase3D::ensureMainWindowInstance(), after that you 00151 * can access your mainWindow through the attribute wnd. At the 00152 * end of your method you can call show() to start drawing the data. 00153 * To protect the multiple access to the data in the mainWindow, 00154 * you can also lock the access at the begin and end. 00155 * A typical show method will look this way: 00156 * \code 00157 * bool myViewerClass::show(const myDataType& data) { 00158 * if (ensureMainWindowInstance()) { 00159 * 00160 * // cast wnd to the proper mainWindow class 00161 * mainWindow* window = dynamic_cast<mainWindow*>(wnd); 00162 * 00163 * if (notNull(window)) { 00164 * window->dolock(); 00165 * 00166 * // transfer your data to wnd 00167 * window->putData(data); // assume your mainWindow class has a 00168 * // method called putData 00169 * window->unlock(); 00170 * return viewerBase3D::show(); 00171 * } 00172 * } 00173 * return false; 00174 * } 00175 * \endcode 00176 */ 00177 00178 /** 00179 * This is the base class for all %viewer classes which show 3D data. 00180 * 00181 * It supports the manipulation of the 3D camera parameters using 00182 * the mouse, and provides all necessary interfaces that simplify 00183 * subclasses accessing configuration dialogs. 00184 * 00185 * @see \ref viewer3D 00186 */ 00187 class viewerBase3D : public viewerBase { 00188 public: 00189 /** 00190 * The parameters for the class viewerBase3D. 00191 * 00192 * The parameters for viewer classes have two functions: 00193 * 00194 * First, the allow the user to indicate display options, like if 00195 * he wants to show the system axes. This is much like the %parameters 00196 * functionality for all functors in the ltilib. 00197 * 00198 * Second, the viewers have usually dialogs, that allow users to 00199 * specify the desired options interactivelly (while displaying 00200 * data). It is often usefull to get in that dialog some 00201 * information about the image or data currently being displayed. This 00202 * information is provided to the configuration dialog using some 00203 * attributes in the parameters class. (this may be changed in the near 00204 * future) 00205 * 00206 * @see \ref viewer3D 00207 */ 00208 class parameters : public viewerBase::parameters { 00209 public: 00210 /** 00211 * default constructor 00212 */ 00213 parameters(); 00214 00215 /** 00216 * copy constructor 00217 * @param other the parameters object to be copied 00218 */ 00219 parameters(const parameters& other); 00220 00221 /** 00222 * destructor 00223 */ 00224 ~parameters(); 00225 00226 /** 00227 * returns name of this type 00228 */ 00229 const char* getTypeName() const; 00230 00231 /** 00232 * copy the contents of a parameters object 00233 * @param other the parameters object to be copied 00234 * @return a reference to this parameters object 00235 */ 00236 virtual parameters& copy(const parameters& other); 00237 00238 /** 00239 * copy the contents of a parameters object 00240 * @param other the parameters object to be copied 00241 * @return a reference to this parameters object 00242 */ 00243 virtual parameters& operator=(const parameters& other); 00244 00245 00246 /** 00247 * returns a pointer to a clone of the parameters 00248 */ 00249 virtual functor::parameters* clone() const; 00250 00251 /** 00252 * write the parameters in the given ioHandler 00253 * @param handler the ioHandler to be used 00254 * @param complete if true (the default) the enclosing begin/end will 00255 * be also written, otherwise only the data block will be written. 00256 * @return true if write was successful 00257 */ 00258 virtual bool write(ioHandler& handler,const bool complete=true) const; 00259 00260 /** 00261 * read the parameters from the given ioHandler 00262 * @param handler the ioHandler to be used 00263 * @param complete if true (the default) the enclosing begin/end will 00264 * be also written, otherwise only the data block will be written. 00265 * @return true if write was successful 00266 */ 00267 virtual bool read(ioHandler& handler,const bool complete=true); 00268 00269 # ifdef _LTI_MSC_6 00270 /** 00271 * this function is required by MSVC only, as a workaround for a 00272 * very awful bug, which exists since MSVC V.4.0, and still by 00273 * V.6.0 with all bugfixes (so called "service packs") remains 00274 * there... This method is also public due to another bug, so please 00275 * NEVER EVER call this method directly: use read() instead 00276 */ 00277 bool readMS(ioHandler& handler,const bool complete=true); 00278 00279 /** 00280 * this function is required by MSVC only, as a workaround for a 00281 * very awful bug, which exists since MSVC V.4.0, and still by 00282 * V.6.0 with all bugfixes (so called "service packs") remains 00283 * there... This method is also public due to another bug, so please 00284 * NEVER EVER call this method directly: use write() instead 00285 */ 00286 bool writeMS(ioHandler& handler,const bool complete=true) const; 00287 # endif 00288 00289 // ------------------------------------------------ 00290 // the parameters 00291 // ------------------------------------------------ 00292 00293 /** 00294 * init filename (with path) for saving 00295 * 00296 * Default: image.png 00297 */ 00298 std::string saveName; 00299 00300 /** 00301 * Color of the background. 00302 * 00303 * Default: lti::Black (lti::rgbPixel(0,0,0)) 00304 */ 00305 rgbPixel backgroundColor; 00306 00307 /** 00308 * Color of the axis, if the corresponding <code>mode</code> is 00309 * specified for a fixed axis color. 00310 * 00311 * Default: lti::White (lti::rgbPixel(255,255,255)) 00312 */ 00313 rgbPixel axisColor; 00314 00315 /** 00316 * Size of the viewer window. 00317 * 00318 * Default: point(256,256) 00319 */ 00320 point windowSize; 00321 00322 /** 00323 * If true, the given color for the axis will be used. Otherwise 00324 * gradients for red, green and blue will be used. 00325 * 00326 * Default: true 00327 */ 00328 bool axisColorFixed; 00329 00330 /** 00331 * camera parameters for the 3D graphics. 00332 * 00333 * Defaut values: camPos = computed from azimuth, elevation, camRadius 00334 * and camTarget. 00335 * azimuth = 45deg (45*Pi/180 radians) 00336 * elevation = 60deg (60*Pi/180 radians) 00337 * center = (0.5,0.5); 00338 * perspective = 0.002; 00339 * zoom = 0.5; 00340 */ 00341 draw3D<rgbPixel>::parameters camParameters; 00342 00343 /** 00344 * Point in the 3D space to which the camera always look at. 00345 * 00346 * Default value: (128,128,128) 00347 */ 00348 dpoint3D camTarget; 00349 00350 /** 00351 * Distance from the camera position to the camera origin 00352 * 00353 * Default value: 200 00354 */ 00355 double camRadius; 00356 }; 00357 00358 /** 00359 * default constructor 00360 */ 00361 viewerBase3D(bool createDefaultParams = true); 00362 00363 /** 00364 * copy constructor 00365 * @param other the object to be copied 00366 */ 00367 viewerBase3D(const viewerBase3D& other); 00368 00369 /** 00370 * constructor with windows title 00371 */ 00372 viewerBase3D(const std::string& title); 00373 00374 /** 00375 * destructor 00376 */ 00377 virtual ~viewerBase3D(); 00378 00379 /** 00380 * returns the name of this type ("viewerBase3D") 00381 */ 00382 virtual const char* getTypeName() const; 00383 00384 /** 00385 * copy data of "other" functor. 00386 * @param other the functor to be copied 00387 * @return a reference to this functor object 00388 */ 00389 viewerBase3D& copy(const viewerBase3D& other); 00390 00391 /** 00392 * alias for copy member 00393 * @param other the functor to be copied 00394 * @return a reference to this functor object 00395 */ 00396 viewerBase3D& operator=(const viewerBase3D& other); 00397 00398 /** 00399 * returns a pointer to a clone of this functor. 00400 */ 00401 virtual viewerBase* clone() const; 00402 00403 /** 00404 * returns used parameters 00405 */ 00406 const parameters& getParameters() const; 00407 00408 /** 00409 * returns used parameters 00410 */ 00411 parameters& getParameters(); 00412 00413 /** 00414 * shows a color image. 00415 * @param data the object to be shown. 00416 * @return true if successful, false otherwise. 00417 */ 00418 virtual bool show(const image& data) {return false;}; 00419 00420 /** 00421 * shows a 8-bit channel 00422 * @param data the object to be shown. 00423 * @return true if successful, false otherwise. 00424 */ 00425 virtual bool show(const channel8& data) {return false;}; 00426 00427 /** 00428 * shows a channel or matrix of float 00429 * @param data the object to be shown. 00430 * @return true if successful, false otherwise. 00431 */ 00432 virtual bool show(const channel& data) {return false;}; 00433 00434 /** 00435 * shows a channel or matrix of float 00436 * @param data the object to be shown. 00437 * @return true if successful, false otherwise. 00438 */ 00439 virtual bool show(const matrix<float>& data) {return false;}; 00440 00441 /** 00442 * shows a vector of double 00443 * @param data the object to be shown. 00444 * @return true if successful, false otherwise. 00445 */ 00446 virtual bool show(const vector<double>& data) {return false;}; 00447 00448 /** 00449 * shows a vector of double 00450 * @param data the object to be shown. 00451 * @return true if successful, false otherwise. 00452 */ 00453 virtual bool show(const vector<float>& data) {return false;}; 00454 00455 /** 00456 * shows a vector of double 00457 * @param data the object to be shown. 00458 * @return true if successful, false otherwise. 00459 */ 00460 virtual bool show(const vector<int>& data) {return false;}; 00461 00462 /** 00463 * shows a matrix of doubles as a channel 00464 * @param data the object to be shown. 00465 * @return true if successful, false otherwise. 00466 */ 00467 virtual bool show(const matrix<double>& data) {return false;}; 00468 00469 /** 00470 * shows a matrix of integers as a channel 00471 * @param data the object to be shown. 00472 * @return true if successful, false otherwise. 00473 */ 00474 virtual bool show(const matrix<int>& data) {return false;}; 00475 00476 /** 00477 * hides the display window 00478 * @return true if successful, false otherwise. 00479 */ 00480 virtual bool hide() {return false;}; 00481 00482 /** 00483 * take a snapshot of the current visualized image. 00484 * 00485 * The image being shown will be saved in a file with the given name. 00486 * All data types supported by lti::saveImage functor will be accepted. 00487 */ 00488 virtual bool snapshot(const std::string& filename) const; 00489 00490 /** 00491 * set the parameters to be used 00492 */ 00493 virtual bool setParameters(const viewerBase::parameters& param); 00494 00495 protected: 00496 /** 00497 * shows the data. 00498 * 00499 * The tasks done by this method are: 00500 * - ensure the existence of a mainWindow instance. 00501 * - indicate the mainWindow to draw the new data. 00502 * @return true if successful, false otherwise. 00503 */ 00504 virtual bool show(); 00505 00506 # ifdef _LTI_MSC_6 00507 public: 00508 # endif 00509 00510 class mainWindow; 00511 00512 /** 00513 * GTK Widget for the configuration dialog of the histogram viewer. 00514 * 00515 * You will usually reimplement the methods insertPages(), setDialogData(), 00516 * getDialogData(), default constructor (which call the constructor of 00517 * the parent class) and destructor (which destroys the whole GTK stuff). 00518 * 00519 * @see \ref viewer3D 00520 */ 00521 class configDialog : public object { 00522 public: 00523 /** 00524 * create dialog and tell it in which parameter block 00525 * the user data should be stored 00526 */ 00527 configDialog(); 00528 00529 /** 00530 * destroy the dialog 00531 */ 00532 virtual ~configDialog(); 00533 00534 /** 00535 * Build the Dialog's GTK+ Widget Tree. 00536 * 00537 * You won't need to reimplement this methode, but insertPages(). 00538 */ 00539 void buildDialog(); 00540 00541 /** 00542 * show the dialog 00543 */ 00544 virtual void show(); 00545 00546 /** 00547 * hide the dialog 00548 */ 00549 virtual void hide(); 00550 00551 /** 00552 * Indicate which parameters object should be used. 00553 * 00554 * This class will not administrate the memory management of the 00555 * object. It will just keep a reference to it. If deleted externally 00556 * an error will occur. 00557 * 00558 * You should also ensure that this method is called before showing 00559 * the dialog for the first time, or all data will be uninitialized! 00560 * 00561 * @return true if successful, false otherwise. 00562 */ 00563 virtual bool useParameters(parameters& theParam); 00564 00565 /** 00566 * set the parent of this dialog to tell it when everything is done! 00567 */ 00568 void whereToCallBack(mainWindow* obj); 00569 00570 /** 00571 * @name Virtual members to be reimplemented 00572 * 00573 * Following members should be reimplemented in your derived class 00574 * if you add new dialog options. 00575 */ 00576 //@{ 00577 00578 /** 00579 * Inserts all pages in the main settings dialog. 00580 * @see \ref viewer3D 00581 * 00582 * You will usually want to overload this member. Here you 00583 * will usually want to call appendPage(buildCommonPage()) followed by 00584 * all methods where you build your pages. 00585 * 00586 * The default implementation will just add the common page, with 00587 * the camera positioning, zoom, perspective and similar settings. 00588 * You could call the parent class method to do this, but is usually 00589 * not done to avoid dealing with a MS VC++ bug. 00590 * 00591 * If you want to add some pages, you will need to create the 00592 * desired GTK Widget, and give a name for it, assign both 00593 * values to a pageWidget structure and append it to the 00594 * current list of pages using appendPage(). 00595 * 00596 * The best way doing so is implementing methods buildABCPage, 00597 * where ABC should be replaced with a meaningful name. These 00598 * methods should return an object pageWidget, that can be 00599 * appended to the pages list. 00600 * Following example illustrate this concept: 00601 * 00602 * \code 00603 * class myViewer : public viewerBase3D { 00604 * // ... implementation of parameters, etc. ... 00605 * class configDialog : public viewerBase3D::configDialog { 00606 * public: 00607 * // default constructor 00608 * configDialog() : viewerBase3D::configDialog() {}; 00609 * 00610 * // build my page 00611 * pageWidget buildMyPage() { 00612 * pageWidget pw; // this object will be returned 00613 * pw.label = "my page"; // the name of the widget 00614 * 00615 * // create the GTK widget 00616 * GtkWidget* theWidget = gtk_vbox_new (FALSE, 0); 00617 * // ... 00618 * 00619 * pw.widget = theWidget; 00620 * return pw; 00621 * }; 00622 * 00623 * // insert pages 00624 * virtual void insertPages() { 00625 * // append first the common dialog (from the parent class) 00626 * appendPage(buildCommonPage()); 00627 * // append my page 00628 * appendPage(buildMyPage()); 00629 * } 00630 * } 00631 * }; 00632 * \endcode 00633 * 00634 * This method will insert the pages in an internal list, that will 00635 * be read in the buildDialog() method. 00636 */ 00637 virtual void insertPages(); 00638 00639 /** 00640 * copy the contents of the dialog in the parameters object. 00641 * 00642 * This method should read all data from the GTK-Widget and write them 00643 * in the parameter object. Do not forget to check first if the 00644 * parameter pointer is valid or not. 00645 * 00646 * @return true if successful, false otherwise. 00647 */ 00648 virtual bool getDialogData(); 00649 00650 /** 00651 * copy the contents of the parameters object into the dialog entries 00652 * 00653 * This method should write all data given in the parameters 00654 * into the GTK-Widget. 00655 * Do not forget to check first if the parameter pointer is 00656 * valid or not. 00657 * 00658 * @return true if successful, false otherwise. 00659 */ 00660 virtual bool setDialogData(); 00661 //@} 00662 00663 # ifdef _LTI_MSC_6 00664 /** 00665 * this function is required by MSVC only, as a workaround for a 00666 * very awful bug, which exists since MSVC V.4.0, and still by 00667 * V.6.0 with all bugfixes (so called "service packs") remains 00668 * there... This method is also public due to another bug, so please 00669 * NEVER EVER call this method directly: use mouseMovedHandler instead 00670 */ 00671 bool getDialogDataMS(); 00672 00673 /** 00674 * this function is required by MSVC only, as a workaround for a 00675 * very awful bug, which exists since MSVC V.4.0, and still by 00676 * V.6.0 with all bugfixes (so called "service packs") remains 00677 * there... This method is also public due to another bug, so please 00678 * NEVER EVER call this method directly: use mouseMovedHandler instead 00679 */ 00680 bool setDialogDataMS(); 00681 # endif 00682 00683 /** 00684 * Structure used in the elements of the list of all 00685 * pages of the configuration dialog. 00686 */ 00687 struct pageWidget { 00688 GtkWidget* widget; 00689 std::string label; 00690 }; 00691 00692 protected: 00693 00694 /** 00695 * Build a page in the main settings dialog. 00696 * 00697 * @return a pageWidget for the common settings. 00698 */ 00699 pageWidget buildCommonPage(); 00700 00701 /** 00702 * copy src to dest and allocates memory for dest 00703 */ 00704 void newStrCopy(char* &dest, const char* src); 00705 00706 /** 00707 * convert a double in an ascii string 00708 */ 00709 std::string toString(const double& value,const int& dec = 4); 00710 00711 /** 00712 * convert an ascii string into a double value 00713 */ 00714 double fromString(const char* value); 00715 00716 /** 00717 * Pointer to the parent mainWindow 00718 */ 00719 mainWindow* theMainWindow; 00720 00721 /** 00722 * pointer to the used viewer parameters. 00723 * 00724 * This class should NEVER delete or create this object, 00725 * because is just a reference to external data. 00726 * 00727 * The methods should check if it points to valid data, i.e. 00728 * if the pointer points to the right type (check it with 00729 * dynamic_cast), or if the pointer is null. 00730 */ 00731 parameters* param; 00732 00733 /** 00734 * userdef background color 00735 * 00736 * Default: lti::Black (lti::rgbPixel(0,0,0)) 00737 */ 00738 rgbPixel userdefBackcolor; 00739 00740 /** 00741 * append a page in the pages list. 00742 */ 00743 void appendPage(pageWidget pw); 00744 00745 /** 00746 * holds the the widges and the names 00747 * for special pages in the settings dialog 00748 */ 00749 std::list<pageWidget> pageList; 00750 00751 /** 00752 * copy the parameters to the mainWindow 00753 * and calls redraw method 00754 */ 00755 virtual void redrawMainWindow(void); 00756 00757 /** 00758 * @name GTK+ Callbacks 00759 * Callback functions created by Glade 00760 */ 00761 //@{ 00762 00763 //mainDialog 00764 static void on_ok_clicked(GtkButton *button, 00765 gpointer user_data); 00766 00767 static void on_cancel_clicked(GtkButton *button, 00768 gpointer user_data); 00769 00770 static void on_apply_clicked(GtkButton *button, 00771 gpointer user_data); 00772 00773 static void on_chooseFilename_clicked(GtkButton *button, 00774 gpointer user_data); 00775 00776 static void chooseFilename_callback(GtkWidget *widget, 00777 gpointer data); 00778 00779 static void on_save_clicked(GtkButton *button, 00780 gpointer user_data); 00781 00782 /* static gint on_close_clicked(GtkButton *button, */ 00783 /* gpointer user_data); */ 00784 00785 // specialPage 00786 static void on_backBlack_toggled(GtkToggleButton *togglebutton, 00787 gpointer user_data); 00788 00789 static void on_backGrey_toggled(GtkToggleButton *togglebutton, 00790 gpointer user_data); 00791 00792 static void on_backWhite_toggled(GtkToggleButton *togglebutton, 00793 gpointer user_data); 00794 00795 static void on_backUserdef_toggled(GtkToggleButton *togglebutton, 00796 gpointer user_data); 00797 00798 static void on_backChoose_clicked(GtkButton *button, 00799 gpointer user_data); 00800 00801 static void on_axisGradient_toggled(GtkToggleButton *togglebutton, 00802 gpointer user_data); 00803 00804 static void on_axisFixed_toggled(GtkToggleButton *togglebutton, 00805 gpointer user_data); 00806 00807 static void on_axisChoose_clicked(GtkButton *button, 00808 gpointer user_data); 00809 00810 static void on_sizex_changed(GtkEditable *editable, 00811 gpointer user_data); 00812 00813 static void on_sizey_changed(GtkEditable *editable, 00814 gpointer user_data); 00815 00816 static void on_centerx_changed(GtkEditable *editable, 00817 gpointer user_data); 00818 00819 static void on_centery_changed(GtkEditable *editable, 00820 gpointer user_data); 00821 00822 static void on_camx_changed(GtkEditable *editable, 00823 gpointer user_data); 00824 00825 static void on_camy_changed(GtkEditable *editable, 00826 gpointer user_data); 00827 00828 static void on_camz_changed(GtkEditable *editable, 00829 gpointer user_data); 00830 00831 static void on_elevation_changed(GtkEditable *editable, 00832 gpointer user_data); 00833 00834 static void on_azimuth_changed(GtkEditable *editable, 00835 gpointer user_data); 00836 00837 static void on_zoom_changed(GtkEditable *editable, 00838 gpointer user_data); 00839 00840 static void on_perspective_changed(GtkEditable *editable, 00841 gpointer user_data); 00842 //@} 00843 00844 protected: 00845 00846 /** 00847 * @name GTK+ Objects 00848 * GTK Widgets 00849 */ 00850 //@{ 00851 00852 /** 00853 * Tooltip: explains parameters 00854 */ 00855 GtkTooltips *tooltips; 00856 00857 /** 00858 * main dialog 00859 */ 00860 GtkWidget *settings; 00861 00862 /** 00863 * file selector 00864 */ 00865 GtkWidget* filew; 00866 00867 /** 00868 * color selection dialog 00869 */ 00870 colorDialog* colorSelector; 00871 00872 /** 00873 * combobox for save-file-names 00874 */ 00875 GtkWidget* comboFilename; 00876 00877 /** 00878 * pointerlist to strings, which saves all 00879 * save-file-names 00880 */ 00881 GList* comboNamelist; 00882 00883 /** 00884 * toggle buttons for backgroundcolor 00885 */ 00886 GtkWidget* backBlack; 00887 GtkWidget* backGrey; 00888 GtkWidget* backWhite; 00889 GtkWidget* backUserdef; 00890 00891 /** 00892 * x,y windows size 00893 */ 00894 GtkWidget* sizex; 00895 GtkWidget* sizey; 00896 00897 /** 00898 * kind(color) of coodinate axis 00899 */ 00900 GtkWidget* axisGradient; 00901 GtkWidget* axisFixed; 00902 00903 /** 00904 * view parameters 00905 */ 00906 GtkWidget* elevation; 00907 GtkWidget* azimuth; 00908 GtkWidget* zoom; 00909 GtkWidget* perspective; 00910 00911 /** 00912 * center position 00913 */ 00914 GtkWidget* centerx; 00915 GtkWidget* centery; 00916 00917 /** 00918 * camera position 00919 */ 00920 GtkWidget* camx; 00921 GtkWidget* camy; 00922 GtkWidget* camz; 00923 00924 //@} 00925 }; 00926 00927 /** 00928 * Widget for the main class of the histogram viewer. 00929 * 00930 * This class administrates the real viewer window. It provides 00931 * the interface with which the data will be drawn. 00932 * For this task you will usually reimplement in your inherited class 00933 * the methods dataToImage() and prepareParameters(). 00934 * 00935 * In your own classes, you should provide methods to set the 00936 * data required in dataToImage(). These methods will be used 00937 * in your %myviewer::show(const classtype& data) methods, to set 00938 * the data that must be displayed. 00939 * 00940 * @see \ref viewer3D 00941 */ 00942 class mainWindow : public object { 00943 public: 00944 /** 00945 * default constructor. 00946 * 00947 * @param setConfigDlg if true (default) the configuration 00948 * dialog will be created and initialized. Otherwise 00949 * it will be left empty 00950 */ 00951 mainWindow(bool setConfigDlg = true); 00952 00953 /** 00954 * copy constructor 00955 */ 00956 mainWindow(const mainWindow& other); 00957 00958 /** 00959 * destructor 00960 */ 00961 ~mainWindow(); 00962 00963 /** 00964 * initialize values for the constructor 00965 */ 00966 void init(void); 00967 00968 /** 00969 * indicate which parameters instance should be used. 00970 */ 00971 virtual bool useParameters(parameters& theParam); 00972 00973 /** 00974 * similar to draw data, but used by other widgets to force image 00975 * display 00976 */ 00977 virtual void redraw(); 00978 00979 /** 00980 * generate an event which will show the data 00981 */ 00982 void drawData(); 00983 00984 /** 00985 * generate an event which will hide the data 00986 */ 00987 void hideData(); 00988 00989 /** 00990 * creates new window 00991 */ 00992 void createWindow(); 00993 00994 /** 00995 * destroy the window 00996 */ 00997 void destroyWindow(); 00998 00999 /** 01000 * return a lti::image with the data being displayed. 01001 * 01002 * Used by the save image routines! 01003 */ 01004 const image& getDisplayedData() const; 01005 01006 /** 01007 * copy this window (only the actual data will be copied. 01008 * The display queue will not be copied! 01009 */ 01010 mainWindow& copy(const mainWindow& other); 01011 01012 /** 01013 * clone this window 01014 */ 01015 mainWindow* clone() const; 01016 01017 /** 01018 * lock internal data 01019 */ 01020 void lock(); 01021 01022 /** 01023 * unlock internal data 01024 */ 01025 void unlock(); 01026 01027 protected: 01028 /** 01029 * @name Members to be reimplemented 01030 */ 01031 //@{ 01032 /** 01033 * This method is the one where your data should be drawn. 01034 * 01035 * When called, you can assume that the <code>drawTool</code> 01036 * attribute of this class has already been initialized with the 01037 * proper parameters, the required canvas image has already been set 01038 * with the proper size and cleaned with the proper background color. 01039 * 01040 */ 01041 virtual void dataToImage(); 01042 01043 /** 01044 * Prepare the parameters before the settings dialog is started. 01045 * 01046 * This member gets some information of the displayed data into 01047 * the informational attributes of the parameters instance. 01048 * It is called just before opening the settings dialog, and is 01049 * the proper place to update the mentioned informational data. 01050 */ 01051 virtual void prepareParameters(); 01052 01053 /** 01054 * Indicate if there are valid data to show. 01055 * 01056 * This method must check if the provided data is ready 01057 * to be shown, i.e. if the dataToImage() can be already 01058 * be used to draw the data. 01059 */ 01060 virtual bool validData(void); 01061 01062 /** 01063 * this method will be called to invalidate the data. 01064 * 01065 * Usually will set a few pointers to NULL to indicate 01066 * that the window has been hidden, and no valid data is 01067 * keeped in this class any more. 01068 */ 01069 virtual void indicateDataHide(void); 01070 01071 //@} 01072 01073 /** 01074 * @name Tools and information flags 01075 */ 01076 //@{ 01077 /** 01078 * draw the coordinate system and an auxiliary box of the given size 01079 * @param size axis size 01080 * @param auxBox if true, an auxiliary box will be drawn. 01081 */ 01082 void draw3DAxis(const double size,const bool auxBox = true); 01083 01084 /** 01085 * mouse being pressed. 01086 * 01087 * This attribute will contain always the status of the mouse 01088 * buttons. The values will usually be: 01089 * \code 01090 * Nothing : 0 01091 * Left button : 1 01092 * Middle button: 2 01093 * Right button : 3 01094 * Wheel Up : 4 01095 * Wheel Down : 5 01096 * \endcode 01097 */ 01098 int mouseButtonPressed; 01099 01100 /** 01101 * last position of the mouse in the window. 01102 */ 01103 point lastMousePos; 01104 //@} 01105 01106 /** 01107 * the viewer parameters. This is just a pointer to an external 01108 * instance. This class will never delete or clone the pointed object 01109 */ 01110 parameters* param; 01111 01112 /** 01113 * the statistics and displaying options dialog 01114 */ 01115 configDialog* options; 01116 01117 /** 01118 * extra width needed for the scrollbars 01119 */ 01120 static const point borderWidth; 01121 01122 /** 01123 * @name Drawing Members. 01124 * 01125 * These members are used usually in your dataToImage method(). 01126 */ 01127 //@{ 01128 /** 01129 * drawTool object 01130 */ 01131 draw3D<rgbPixel> drawTool; 01132 01133 /** 01134 * the data which is been actually displayed. This is the 01135 * canvas used in the drawTool object. 01136 */ 01137 image theImage; 01138 //@} 01139 01140 /** 01141 * if a image is being shown, this attribute is true 01142 */ 01143 bool showingBuffer; 01144 01145 /** 01146 * if the viewer is computing the image to be shown, this 01147 * attribute is true 01148 */ 01149 bool busy; 01150 01151 /** 01152 * data lock. Used to protect the data against parallel access 01153 */ 01154 mutex theLock; 01155 01156 /** 01157 * semaphore used to synchronize destruction of the widgets 01158 */ 01159 semaphore syncEnd; 01160 01161 /** 01162 * if the data has changed, this variable is true 01163 */ 01164 bool dataChanged; 01165 01166 /** 01167 * buffer of image being displayed! 01168 */ 01169 guchar* xbuffer; 01170 01171 /** 01172 * number of rows of the xbuffer 01173 */ 01174 int xbuffer_rows; 01175 01176 /** 01177 * number of columns of the xbuffer 01178 */ 01179 int xbuffer_cols; 01180 01181 /** 01182 * generate xbuffer from an image 01183 */ 01184 void generateXbuffer(const image& img, 01185 GtkWidget *widget, 01186 GdkEventExpose *event); 01187 01188 /** 01189 * name of this window! 01190 */ 01191 std::string winName; 01192 01193 /** 01194 * size of the window 01195 */ 01196 point winSize; 01197 01198 // GTK Internals 01199 01200 /** 01201 * timer tag used in this viewer window 01202 */ 01203 gint timerTag; 01204 01205 /** 01206 * @name GTK+ Widgets 01207 */ 01208 //@{ 01209 01210 /** 01211 * the main dialog window 01212 */ 01213 GtkWidget *window; 01214 01215 /** 01216 * the scrolled window 01217 */ 01218 GtkWidget *scrolledWindow; 01219 01220 /** 01221 * the status bar 01222 */ 01223 GtkWidget *statusBar; 01224 01225 /** 01226 * context id of the status bar 01227 */ 01228 guint statusBarContextId; 01229 01230 /** 01231 * drawing area that holds the image 01232 */ 01233 GtkWidget *darea; 01234 01235 /** 01236 * event box to capture mouse and button events 01237 */ 01238 GtkWidget *eventBox; 01239 01240 /** 01241 * convert the three color components red, green and blue in a guint32 01242 * used by the gtk-color maps. 01243 * @param r red component (between 0 and 255) 01244 * @param g green component (between 0 and 255) 01245 * @param b blue component (between 0 and 255) 01246 * @return an integer value used by gtk-color maps 01247 */ 01248 guint32 rgbToInt(const int& r,const int& g,const int& b) const; 01249 //@} 01250 01251 /** 01252 * unpack an gtk-integer into a rgb pixel 01253 */ 01254 rgbPixel intToRgb(const guint32& rgb) const; 01255 01256 /** 01257 * @name GTK+ callback functions 01258 */ 01259 //@{ 01260 01261 /** 01262 * called when the user selects the "close window" button on the window 01263 */ 01264 static gint delete_event(GtkWidget *widget, 01265 GdkEvent *event, 01266 gpointer data ); 01267 01268 01269 /** 01270 * timeout gtk-callback function, called when the window must be 01271 * destroyed. 01272 * This static function just call the instance member destroyWindow(). 01273 */ 01274 static gint destroyWndTimeout(gpointer data); 01275 01276 /** 01277 * call-back funtion to indicate the end of the whole gtk-application. 01278 * This function will end the gtk main-event-loop! 01279 */ 01280 static void destroy(GtkWidget *widget, 01281 gpointer data ); 01282 01283 01284 /** 01285 * timeout gtk-callback function, called when a new image must be 01286 * displayed! 01287 * 01288 * This function will stop the timeout automatically, if there are 01289 * no more images or objects to be displayed. 01290 */ 01291 static gint show(gpointer data); 01292 01293 /** 01294 * timeout gtk-callback function, called when a new image must be 01295 * hide! 01296 */ 01297 static gint hide(gpointer data); 01298 01299 /** 01300 * timeout gtk-callback function, called when the window must be 01301 * created. 01302 * 01303 * This function just calls createWindowLocal() 01304 */ 01305 static gint createWindowTimeout(gpointer data); 01306 01307 /** 01308 * called by createWindowTimeout to create a window 01309 */ 01310 void createWindowLocal(); 01311 01312 /** 01313 * callback function called when the mouse is moved and a mouse 01314 * button has been pressed. 01315 * 01316 * This function just calls the mouseMovedEventLocal() 01317 */ 01318 static gint mouseMovedEvent(GtkWidget* widget, 01319 GdkEventMotion* event, 01320 gpointer data); 01321 01322 /** 01323 * function called by mouseMovedEvent() when the mouse has been moved. 01324 * 01325 * This will show on the status bar the mouse pointer position and 01326 * the value of the image at this position. 01327 */ 01328 void mouseMovedEventLocal(GtkWidget* widget, 01329 GdkEventMotion* event); 01330 01331 /** 01332 * this function is called when the right button is pressed and moved. 01333 * @param button which button is pressed (0 means none, 01334 * 1 left button, 3 right button) 01335 * @param pos actual position of mouse pointer 01336 * @param shift true if the shift-key has been pressed while moving the 01337 * mouse. 01338 * @param ctrl true if the control-key has been pressed while moving the 01339 * mouse. 01340 */ 01341 virtual void mouseMovedHandler(const int& button, 01342 const point& pos, 01343 const bool shift, 01344 const bool ctrl); 01345 01346 01347 # ifdef _LTI_MSC_6 01348 public: 01349 /** 01350 * this function is required by MSVC only, as a workaround for a 01351 * very awful bug, which exists since MSVC V.4.0, and still by 01352 * V.6.0 with all bugfixes (so called "service packs") remains 01353 * there... This method is also public due to another bug, so please 01354 * NEVER EVER call this method directly: use mouseMovedHandler instead 01355 */ 01356 void mouseMovedHandlerMS(const int& button, 01357 const point& pos, 01358 const bool shift, 01359 const bool ctrl); 01360 protected: 01361 # endif 01362 01363 /** 01364 * function called when any mouse button has been pressed. 01365 */ 01366 static gint buttonPressedEvent(GtkWidget* widget, 01367 GdkEventButton* event, 01368 gpointer data); 01369 01370 /** 01371 * called by buttonPressedEvent() 01372 */ 01373 virtual void buttonPressedEventLocal(GtkWidget* widget, 01374 GdkEventButton* event); 01375 01376 01377 /** 01378 * callback function called when a key is pressed or released 01379 */ 01380 static gint keyboardEvent(GtkWidget* widget, 01381 GdkEventKey* event, 01382 gpointer data); 01383 01384 /** 01385 * show the data in the status bar 01386 */ 01387 void showCameraPosition(); 01388 01389 /** 01390 * gtk-callback funtion to redraw the image been displayed. 01391 * 01392 * This function just calls the dareaExposeLocal() 01393 */ 01394 static gboolean dareaExpose (GtkWidget *widget, 01395 GdkEventExpose *event, 01396 gpointer data); 01397 01398 /** 01399 * This function redraws the image been displayed 01400 */ 01401 virtual gboolean dareaExposeLocal (GtkWidget *widget, 01402 GdkEventExpose *event); 01403 01404 //@} 01405 }; 01406 01407 # ifdef _LTI_MSC_6 01408 protected: 01409 # endif 01410 01411 01412 /** 01413 * the main window. 01414 * 01415 * (have to defined after inhert the mainWindow class) 01416 */ 01417 mainWindow* wnd; 01418 01419 /** 01420 * return a new instance of the mainWindow class. 01421 * 01422 * This class must be reimplemented in order to get the 01423 * proper class instance. 01424 */ 01425 virtual mainWindow* getNewMainWindow() const; 01426 01427 /** 01428 * ensure that a mainWindow instance exist. 01429 * 01430 * You usually do not require to reimplement this method. 01431 * 01432 * @return true if everything is ok, false, if the mainWindow 01433 * do not exist and it could not be created. 01434 */ 01435 virtual bool ensureMainWindowInstance(); 01436 01437 }; 01438 } 01439 01440 #endif 01441 #endif