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 /// WidgetFactory.h 00019 00020 #ifndef __WIDGET_FACTORY_DOT_H 00021 #define __WIDGET_FACTORY_DOT_H 00022 00023 #include <smartptr.h> 00024 #include "NodeWidget.h" 00025 #include "EdgeWidget.h" 00026 00027 00028 /// a base class for generating basic widget items. 00029 /// this hides the "appearance" from the behavior levels of the hierarchy, 00030 /// this way we can re-use widgets even if we don't have openGL or don't like 00031 /// the way they look. 00032 /// 00033 /// This class should be restricted to generating only "basic" widget 00034 /// items like, nodes, edges, sliders, and cones. 00035 /// More complex, composite, widgets should take a factory 00036 /// in it's constructor to generate the correct "kind" of basic widgets using 00037 /// the gen*() functions. 00038 /// 00039 /// This is a prototype factory, which means all widgets must implement 00040 /// some form of clone() function. The WidgetItem interface requires 00041 /// you to be able to implement 00042 /// \code WidgetItem *clone() const \endcode 00043 /// However, many classes like NodeWidget and EdgeWidget define the 00044 /// WidgetItem::clone() and declare new clone ops for that specific 00045 /// subclass, which get called by their implementation of WidgetItem::clone(). 00046 /// This is very usefull since we are sepparating the behavior and appearance 00047 /// via the class hierarchy and would still like to copy the widgets. 00048 /// 00049 /// To create a custom factory is simplest to just create a new factory or use/copy 00050 /// an existing "const default" one, for instance 00051 /// here is the definition of the default GLUWidgetFactory : 00052 /// \code 00053 /// const WidgetFactory GLUWidgetFactory(new GLUNodeWidget(...), new GLUEdgeWidget(...)); 00054 /// \endcode 00055 /// To customize just copy and modify: 00056 /// \code 00057 /// WidgetFactory myWF = GLUWidgetFactory; 00058 /// ... /// change atributes of the widget protos to suite 00059 /// \endcode 00060 /// The advantage here is that specifics about color and appearance can remain 00061 /// transparent at the behavior level of the widget hierarchy, it also means 00062 /// that the "style" of the widget-set being used can be easly customeized while 00063 /// the code remains generic. For instance, if the user wants salmon pink nodes 00064 /// and lime green bars, this style can be created by cloning the appropriate 00065 /// prototypes, or by using this "prototype-widget-factory" created from an 00066 /// example salmon-pink node and lime green bars to generate composite widgets 00067 /// such as the FrameWidget. 00068 class WidgetFactory : public gutz::Counted { 00069 public: 00070 WidgetFactory(NodeWidget *nodeProto, EdgeWidget *edgeProto) 00071 : _nodeProto(nodeProto), _edgeProto(edgeProto) 00072 { 00073 //TODO: could use some error checking here to insure we have a 00074 // COMPLETELY and CORRECTLY configured proto factory 00075 } 00076 WidgetFactory(const WidgetFactory &wf) 00077 : _nodeProto(wf._nodeProto->cloneNode()), 00078 _edgeProto(wf._edgeProto->cloneEdge()) 00079 { 00080 } 00081 virtual ~WidgetFactory() {} 00082 00083 WidgetFactory &operator=(const WidgetFactory &wf) 00084 { 00085 _nodeProto = wf._nodeProto->cloneNode(); 00086 _edgeProto = wf._edgeProto->cloneEdge(); 00087 } 00088 00089 ///@name NodeWidget prototypes 00090 ///@{ 00091 virtual NodeWidget *genNode() const 00092 { if(_nodeProto) return _nodeProto->cloneNode(); return 0; } 00093 virtual NodeWidgetSP getNodeProto() 00094 { return _nodeProto; } 00095 virtual const NodeWidget *const getNodeProto() const 00096 { return _nodeProto.getPtr(); } 00097 virtual void setNodeProto(NodeWidget *nw) 00098 { _nodeProto = nw; } 00099 ///@} 00100 00101 ///@name EdgeWidget prototypes 00102 ///@{ 00103 virtual EdgeWidget *genEdge() const 00104 { if(_edgeProto) return _edgeProto->cloneEdge(); return 0; } 00105 virtual EdgeWidgetSP getEdgeProto() 00106 { return _edgeProto; } 00107 virtual const EdgeWidget *const getEdgeProto() const 00108 { return _edgeProto.getPtr(); } 00109 virtual void setEdgeProto(EdgeWidget *ew) 00110 { _edgeProto = ew; } 00111 ///@} 00112 00113 protected: 00114 /// not used 00115 WidgetFactory() {} 00116 00117 NodeWidgetSP _nodeProto; 00118 EdgeWidgetSP _edgeProto; 00119 00120 }; 00121 00122 typedef gutz::SmartPtr<WidgetFactory> WidgetFactorySP; 00123 00124 00125 #endif 00126