arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

FrameWidget.h

Go to the documentation of this file.
00001 //------------------------------------------------------------------------
00002 //
00003 //   Joe Kniss
00004 //     6-20-03
00005 //                   ________    ____   ___ 
00006 //                  |        \  /    | /  /
00007 //                  +---+     \/     |/  /
00008 //                  +--+|  |\    /|     < 
00009 //                  |  ||  | \  / |  |\  \ 
00010 //                  |      |  \/  |  | \  \ 
00011 //                   \_____|      |__|  \__\
00012 //                       Copyright  2003 
00013 //                      Joe Michael Kniss
00014 //                   <<< jmk@cs.utah.edu >>>
00015 //               "All Your Base are Belong to Us"
00016 //-------------------------------------------------------------------------
00017 
00018 // FrameWidget.h
00019 
00020 #ifndef __FRAME_WIDGET_DOT_H
00021 #define __FRAME_WIDGET_DOT_H
00022 
00023 #include "PolygonWidget.h"
00024 #include <signalGutz.h>
00025 #include "SurfaceWidget.h"
00026 #include "WidgetFactory.h"
00027 #include <mathGutz.h>
00028 
00029 /////////////////////////////////////////////////////////////////////////////
00030 /// a Frame/Square PolygonWidget.
00031 /// This is a composite widget, so it doesn't need any farther implementation
00032 /// to work.  It is a widget built from other widgets, namely nodes/edges/ and
00033 /// an optional SurfaceWidget.  To create a frame widget you need a WidgetFactory
00034 /// that will generate the desired sub-widgets.  You have to attatch the 
00035 /// SurfaceWidget yourself.
00036 /////////////////////////////////////////////////////////////////////////////
00037 class FrameWidget : public PolygonWidget {
00038 public:
00039 
00040    /// supports gutz signals & slots
00041    HAS_SLOTS;
00042 
00043    /// construct from a factory
00044    FrameWidget(const WidgetFactory &wf, 
00045                WidgetItem *parent = 0,
00046                const gutz::vec3f &ll = gutz::vec3f(-1,-1,0),
00047                const gutz::vec3f &lr = gutz::vec3f(1,-1,0),
00048                const gutz::vec3f &ul = gutz::vec3f(-1,1,0),
00049                const gutz::vec3f &ur = gutz::vec3f(1,1,0));
00050 
00051    /// construct from a prototype of NodeWidget and EdgeWidget
00052    FrameWidget(const NodeWidget *const nodeProto, 
00053                const EdgeWidget *const edgeProto,
00054                WidgetItem *parent = 0,
00055                const gutz::vec3f &ll = gutz::vec3f(-1,-1,0),
00056                const gutz::vec3f &lr = gutz::vec3f(1,-1,0),
00057                const gutz::vec3f &ul = gutz::vec3f(-1,1,0),
00058                const gutz::vec3f &ur = gutz::vec3f(1,1,0));
00059 
00060    /// copy from existing FrameWidget
00061    FrameWidget(const FrameWidget &fw);
00062 
00063    virtual ~FrameWidget() { delSurface(); _planeConst = 0; }
00064 
00065    /// just copies the positions, nothing else
00066    FrameWidget &operator=(const FrameWidget &fw)
00067    {
00068       _nodes[LL]->setPoint(fw._nodes[LL]->getPoint());
00069       _nodes[LR]->setPoint(fw._nodes[LR]->getPoint());
00070       _nodes[UL]->setPoint(fw._nodes[UL]->getPoint());
00071       _nodes[UR]->setPoint(fw._nodes[UR]->getPoint());
00072    }
00073 
00074    /////////////////////////////////////////////////////
00075    ///@name Clones
00076    ///@{
00077    WidgetItem *clone() const
00078    {  return cloneFrame(); }
00079    
00080    /// notice that this ISN'T pure virtual, rather
00081    /// it is virtual since we only need to clone 
00082    /// our sub-widgets, however if you sub-class from this,
00083    /// you REALLY need to override this clone.
00084    virtual FrameWidget *cloneFrame() const
00085    {  return new FrameWidget(*this); }
00086    ///@}
00087    /////////////////////////////////////////////////////
00088 
00089    /// object changed
00090    virtual void setChanged()
00091    {
00092       for(unsigned int i=0; i<_nodes.size(); ++i)
00093          _nodes[i]->setChanged();
00094       planeChanged(getPlane());
00095       updateManip();
00096    }
00097 
00098    /////////////////////////////////////////////////////
00099    /// index enums for accessing the _nodes vector
00100    enum FRAME_NODES {
00101       LL,        ///< Lower Left
00102       LR,        ///< Lower Right
00103       UL,        ///< Upper Left
00104       UR,        ///< Upper Right
00105       NODE_LAST
00106    };
00107    /// index enums for accessing the _edges vector
00108    enum FRAME_EDGES {
00109       LEFT,  
00110       RIGHT,
00111       TOP,
00112       BOTTOM,
00113       EDGE_LAST
00114    };
00115    /////////////////////////////////////////////////////
00116 
00117    /////////////////////////////////////////////////////
00118    ///@name Modify the dimensions 
00119    ///    With some higher-level symantics, none of these
00120    ///   are well tested yet!
00121    ///@{
00122 
00123    /// dimensions: width & height
00124    virtual void setDims(float width, float height);
00125 
00126    /// Width
00127    float        getWidth() const 
00128    { 
00129       return (_nodes[LR]->getPoint() - _nodes[LL]->getPoint()).norm();
00130    }
00131    virtual void setWidth(float width);
00132 
00133    /// Height
00134    float        getHeight() const
00135    { 
00136       return (_nodes[UL]->getPoint() - _nodes[LL]->getPoint()).norm();
00137    }
00138    virtual void setHeight(float height);
00139 
00140    /// Center
00141    gutz::vec3f  getCenter() const
00142    {
00143       return   _nodes[LL]->getPoint() 
00144                + (_nodes[UR]->getPoint() - _nodes[LL]->getPoint()) * .5f;
00145    }
00146    virtual void setCenter(const gutz::vec3f &center);
00147 
00148    ///@}
00149    /////////////////////////////////////////////////////
00150 
00151    /////////////////////////////////////////////////////
00152    ///@name Behaviors from PolygonWidget
00153    ///  Notice that we dont define our own move() and mouse(), since we
00154    ///  don't render any geometry of our own, all events will come 
00155    ///  through our children.
00156    ///@{
00157 
00158    /// child mousing, right now the Frame doesn't do anything with the
00159    ///   mouse event, only the move event.
00160    virtual bool mouseChild(WidgetItem *child, const gutz::MouseEvent &me);
00161 
00162    /// child moving
00163    virtual bool moveChild(WidgetItem *child, const gutz::MouseMoveEvent &mme);
00164 
00165    /// draw just forwards event to children, this widget
00166    /// is a composite so we don't draw anything ourselves.
00167    virtual void drawDef(const gutz::RenderEvent &r)
00168    {
00169       PolygonWidget::drawDef(r);
00170       if(_surface)
00171          _surface->draw(r);
00172    }
00173 
00174    /// override of delChild from WidgetItem
00175    virtual void delChild(WidgetItem *child);
00176 
00177    ///@}
00178    /////////////////////////////////////////////////////
00179 
00180    /////////////////////////////////////////////////////
00181    ///@name Plane get
00182    ///@{
00183    /// get the gutz::plane defined by the frame
00184    inline
00185    gutz::planef  getPlane() const
00186    {  return gutz::planef(_nodes[LL]->getPoint(), 
00187                           _nodes[LR]->getPoint(),
00188                           _nodes[UL]->getPoint());
00189    }
00190    ///@}
00191    /////////////////////////////////////////////////////
00192 
00193    /////////////////////////////////////////////////////
00194    /// THE Frame Constraint
00195    /// a node widget moved, not rotation! This will make sure the widget
00196    ///  stays a frame.  This is "what" a frame is, i.e. THE frame constraint. \n
00197    /// TODO: this function could be implemented as a Constraint.
00198    void nodeMoved(int idx, const gutz::vec3f &oldW, const gutz::vec3f &oldH);
00199    /////////////////////////////////////////////////////
00200 
00201    /////////////////////////////////////////////////////
00202    ///@name Surface set/get/del
00203    ///@{
00204    void             setSurface(SurfaceWidget *sw);
00205    SurfaceWidgetSP  getSurface() const { return _surface; }
00206    virtual void     delSurface();
00207    ///@}
00208    /////////////////////////////////////////////////////
00209 
00210    /////////////////////////////////////////////////////
00211    ///@name Signals 
00212    ///  see gutz::Signal for API details
00213    ///@{
00214 
00215    /// signal: planeChanged(gutz::planef p);
00216    gutz::Signal<gutz::planef>  planeChanged;
00217 
00218    ///@}
00219    /////////////////////////////////////////////////////
00220 
00221 protected:
00222 
00223    void updateManip() 
00224    {
00225       _manip->setCenter( _manip->getLocalPosWorld( getCenter() ) );
00226       _manip->setRad( ( _nodes[LL]->getPoint() - _nodes[UR]->getPoint() ).norm() );
00227    }
00228 
00229    /// creates/recreates the frame
00230    void configureFrame(const NodeWidget *const nodeProto, 
00231                        const EdgeWidget *const edgeProto,
00232                        const gutz::vec3f &ll, const gutz::vec3f &lr, 
00233                        const gutz::vec3f &ul, const gutz::vec3f &ur);
00234 
00235    FrameWidget(); ///<not used
00236 
00237    gutz::ManipEventSP _planeConst;
00238 
00239    SurfaceWidgetSP   _surface;
00240 
00241    float             _rad; ///< for rotation, set when mouse goes down.
00242 };
00243 
00244 typedef gutz::SmartPtr<FrameWidget> FrameWidgetSP;
00245 
00246 
00247 #endif
00248 
00249 

Send questions, comments, and bug reports to:
jmk