LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiViewerBase3D.h

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

Generated on Sat Apr 10 15:26:22 2010 for LTI-Lib by Doxygen 1.6.1