00001 /* 00002 * PROPRIETARY INFORMATION. This software is proprietary to 00003 * Side Effects Software Inc., and is not to be reproduced, 00004 * transmitted, or disclosed in any way without written permission. 00005 * 00006 * Produced by: 00007 * Joe Drew 00008 * Side Effects Software Inc 00009 * 477 Richmond Street West 00010 * Toronto, Ontario 00011 * Canada M5V 3E7 00012 * 416-504-9876 00013 * 00014 * NAME: OP_NetworkBox.h (OP Library, C++) 00015 * 00016 * COMMENTS: Defines network boxes! 00017 * 00018 */ 00019 00020 #ifndef __OP_NetworkBox__ 00021 #define __OP_NetworkBox__ 00022 00023 #include "OP_API.h" 00024 #include <iostream.h> 00025 00026 #include <SYS/SYS_Types.h> 00027 #include <UT/UT_String.h> 00028 #include <UT/UT_Color.h> 00029 #include <UT/UT_PtrArray.h> 00030 00031 #include "OP_Node.h" 00032 #include "OP_NetworkBoxFlags.h" 00033 #include "OP_NetworkBoxItem.h" 00034 00035 class OP_Network; 00036 class OP_Stat; 00037 class UT_AutoUndoBlock; 00038 00039 #define OP_NETWORKBOX_DEFAULT_W 2.5F 00040 #define OP_NETWORKBOX_DEFAULT_H 2.5F 00041 #define OP_NETWORKBOX_MINIMIZED_W 1.25F 00042 #define OP_NETWORKBOX_MINIMIZED_H 1.25F 00043 #define OP_NETWORKBOX_MINIMUM_W 1.0F 00044 #define OP_NETWORKBOX_MINIMUM_H 1.0F 00045 00046 #define OP_INVALID_NETWORKBOX_ID -999 00047 00048 /// When saving a network box to the clipboard, you can use this enumeration 00049 /// to specify which of its contents to automatically save with it 00050 enum OP_NetworkBoxSaveType 00051 { 00052 OP_NETWORKBOX_SAVE_NO_CONTENTS, // Don't save any items in the box 00053 OP_NETWORKBOX_SAVE_ALL_CONTENTS, // Save all items in the box 00054 OP_NETWORKBOX_SAVE_PICKED_CONTENTS, // Save only the picked items 00055 OP_NETWORKBOX_SAVE_SPEC_CONTENTS // Save only the specified items. 00056 // Applies only to nodes (cannot 00057 // save an indirect unless you save 00058 // its parent subnet entirely). 00059 // Supported only by certain 00060 // methods which require a node ptr 00061 // array passed in 00062 }; 00063 00064 class OP_API OP_NetworkBox : public OP_NetworkBoxItem 00065 { 00066 public: 00067 /// Create a network box with the specified name. If a duplicate name is 00068 /// passed in, it will be altered to make it unique in the network. 00069 OP_NetworkBox(const UT_String &name, OP_Network *net); 00070 virtual ~OP_NetworkBox(); 00071 00072 /// Set the coordinates for this box (lower left corner) in absolute units. 00073 /// NOTE: If myResizing is set, then setXY does NOT move the box, but 00074 /// effectively resizes it by moving the lower/left corner of the box 00075 /// without moving its contents, and this may result in a change in myW 00076 /// and/or myH. 00077 virtual void setXY(fpreal x, fpreal y); 00078 00079 /// Same as setXY(), but here we can force the box to take on these X/Y 00080 /// coordinates, even if our contents don't fit us any more. The 00081 /// propagate_parent_event tells this method whether or not it should send 00082 /// and event after moving the network box -- this should normally be set 00083 /// to true. 00084 void setXY(fpreal x, fpreal y, bool force, 00085 bool propagate_parent_event); 00086 00087 /// Set the network box's location like setXY(), but first check if the new 00088 /// position is valid. This method wraps the resizing operation 00089 /// with calls to setResizing(true) and setResizing(false). 00090 bool setXYWithBoundsChecks(fpreal x, fpreal y); 00091 00092 /// Get the position of this box. Units are absolute, as opposed 00093 /// to relative units found in OPUI. 00094 virtual fpreal getX() const; 00095 virtual fpreal getY() const; 00096 00097 /// Get and set the width and height of this box. Units are absolute 00098 /// as opposed to the relative units found in OPUI. 00099 /// If the width or height specified is smaller than that which will 00100 /// contain all of the items, the width or height respectively will only 00101 /// be adjusted to the minimum size required to contain the items. To avoid 00102 /// this automatic size check, set 'force' to true. 00103 void setW(fpreal w, bool force = false); 00104 void setH(fpreal h, bool force = false); 00105 00106 /// Set the network box's width like setW(), but first check if the new 00107 /// width is valid. This method wraps the resizing operation 00108 /// with calls to setResizing(true) and setResizing(false). 00109 bool setWWithBoundsChecks(fpreal w); 00110 00111 /// Set the network box's width like setH(), but first check if the new 00112 /// height is valid. This method wraps the resizing operation 00113 /// with calls to setResizing(true) and setResizing(false). 00114 bool setHWithBoundsChecks(fpreal h); 00115 00116 /// Gives you the w/h of the netbox as you see it, meaning if the netbox is 00117 /// minimized, you get the minimized size. 00118 virtual fpreal getW() const; 00119 virtual fpreal getH() const; 00120 00121 /// Return the full maximized size of the netbox, regardless of whether the 00122 /// netbox is currently maximized or minimized 00123 fpreal getMaximizedW() const; 00124 fpreal getMaximizedH() const; 00125 00126 /// Using the netbox's current X,Y, width, and height data, 00127 /// resize the netbox if necessary to fit its contents. Will ONLY resize if 00128 /// the box is too small. WILL add a small buffer border around its contents 00129 /// for prettiness. 00130 void resizeToFit(); 00131 00132 /// Given an area defined by the absolute coordinates (xmin, ymin) - 00133 /// (xmax, ymax), resize the netbox if necessary to ensure that the area 00134 /// can fit inside this box. Will ONLY resize if the box is too small. Will 00135 /// NOT add a buffer border around its contents for prettiness. 00136 void resizeToFit(fpreal xmin, fpreal ymin, fpreal xmax, 00137 fpreal ymax); 00138 00139 /// The name which is used for identification and in displays of this 00140 /// box. setName() returns true if the name change was successful, and 00141 /// alters the name slightly if necessary to make it unique within this 00142 /// network. 00143 bool setName(const UT_String &name); 00144 virtual const UT_String &getItemName() const { return myName; }; 00145 00146 /// The colour used to display our background. Returns true if the color 00147 /// changed. 00148 virtual bool setColor(const UT_Color &color); 00149 virtual const UT_Color *getColor() const { return &myColor; } 00150 00151 /// Items which are contained in this box can be OP_Nodes, 00152 /// OP_InputIndirects or OP_NetworkBoxes. They are all encapsulated 00153 /// in the OP_NetworkBoxItem class. 00154 int getNitems() const; 00155 int getNexposedItems() const; 00156 OP_NetworkBoxItem *getItem(int idx) const; 00157 00158 /// A convenience method, sometimes it's handy to get a quick list of all 00159 /// the nodes in a netbox. 00160 void getNodes(OP_NodeList &list, int level = 0) const; 00161 void getPostIts(UT_PtrArray<OP_PostIt*> &list, int level = 0) const; 00162 void getNetboxes(UT_PtrArray<OP_NetworkBox*> &list, int level = 0) const; 00163 00164 /// Add an item to this box. If the item was previously in another netbox, 00165 /// we remove it from there before we add it here. If 'resize_to_fit' is 00166 /// set to true, we'll resize if necessary to fit our contents after the 00167 /// item is added - this option should always be on, except when the undo 00168 /// mechanism requires some extra control to restore states properly 00169 bool addItem(OP_NetworkBoxItem *item, 00170 bool propagate_parent_event = true, 00171 bool resize_to_fit = true); 00172 bool addItems(UT_PtrArray<OP_NetworkBoxItem *> &items); 00173 00174 /// Remove the item from this box. The item's owner box is set to NULL. 00175 bool removeItem(OP_NetworkBoxItem *item, 00176 bool propagate_parent_event = true, bool do_reparent = false); 00177 bool removeItems(UT_PtrArray<OP_NetworkBoxItem *> &items); 00178 bool removeAllItems(bool do_reparent = false); 00179 00180 /// Sets the network boxes contents to be exactly the items in 'items' (i.e. 00181 /// removes any previous contents not in 'items'). Set 'snap_to_bounds' to 00182 /// true if you'd like us to make the netbox's dimensions snap to form a 00183 /// nice snug fit around its new contents. 00184 bool setContents(UT_PtrArray<OP_NetworkBoxItem *> &items, 00185 bool snap_to_bounds); 00186 00187 /// Returns true if this box is currently picked 00188 virtual int getPicked() const; 00189 00190 /// Set whether this box is picked; returns true if the picked 00191 /// status has changed. Setting 'propagate_parent_event' to false stops 00192 /// this method from notifying the network of this change, useful when we're 00193 /// picking a lot of items at once, it's inefficient to trigger a callback 00194 /// for each pick separately, can just do one update at the end 00195 virtual int setPicked(int on_off, 00196 bool propagate_parent_event = true); 00197 00198 /// Get whether this box is currently minimized 00199 bool getMinimized() const; 00200 00201 /// Set whether this box is currently minimized 00202 /// If update_position is true, then the box is moved to accomodate the 00203 /// minimized status. If propagate_parent_event is true, an event is sent 00204 /// to the network about our minimized state. 00205 bool setMinimized(bool isminimized, 00206 bool update_position, 00207 bool propagate_parent_event); 00208 00209 /// A very general purpose method used to temporarily mark this network box 00210 /// as being involved in an operation. Very useful if e.g. we have a set of 00211 /// nodes and network boxes to apply an operation to. In this case we want 00212 /// to mark each netbox as we apply our op to it and its contents, in case 00213 /// any of the nodes we're passed happen to be in one of those netboxes. In 00214 /// this way we can quickly check if a node's owning box has been marked, 00215 /// and avoid duplicately applying the operation to the node again. REMEMBER 00216 /// to UNMARK all netboxes you marked once you're done with your operation! 00217 void setMarked(bool flag); 00218 bool getMarked(); 00219 00220 /// Calculate the smallest bounds we're willing to accept as our size 00221 /// given our contents. By default, 'incl_buff_border' is set to add a small 00222 /// buffer border to make the layout look pretty. NOTE: If we contain no 00223 /// items, we return an inverted bounding box, see implementation for 00224 /// further details. 00225 void getItemBounds(fpreal &x1, fpreal &y1, fpreal &x2, 00226 fpreal &y2, bool incl_buff_border = true) 00227 const; 00228 00229 /// Automatically alters myX, myY, myW, myH in order to snap the size of 00230 /// the netbox to the minimum bounding box enclosing its contents. Will 00231 /// ALWAYS resize the box to the minimum bounding box size, unlike 00232 /// resizeToFit(). Set 'incl_buff_border' to true if you want a small 00233 /// buffer border to make the layout look pretty. 00234 void snapToBounds(bool incl_buff_border = true); 00235 00236 /// Save the attributes of this network box to the ostream 00237 int save(ostream &os, const OP_SaveFlags &flags); 00238 00239 /// Load the contents of the stream into the attributes of this network 00240 /// box; if binary is nonzero, load in binary mode. 00241 /// Loading doesn't send the OP_NETWORKBOX_CREATED message to the network; 00242 /// the caller is responsible for doing that. 00243 bool load(UT_IStream &is); 00244 00245 /// Returns my item type (OP_ITEMTYPE_NETWORKBOX) 00246 virtual OP_ItemType getItemType() const; 00247 00248 const OP_Stat &getStat() const { return myStats; } 00249 OP_Stat &getStat() { return myStats; } 00250 00251 /// Return the network i'm in 00252 virtual OP_Network *getParentNetwork() const; 00253 00254 /// Sets 'cmd' to be a string containing our values for the flags specified 00255 /// by 'flags'. If 'flags' == NULL, then we output values for all of our 00256 /// flags. 00257 void getSaveFlagsString(UT_String &cmd, 00258 const char *flags, 00259 bool save_to_hip) const; 00260 00261 /// Used by opscript, this outputs the sequence of hscript commands 00262 /// necessary to recreate this network box. Does not script the box's 00263 /// contents. 'dogeneral' is set when opscript is generating a macro. 00264 int saveCommand(ostream &os, const char *name, 00265 int dogeneral) const; 00266 00267 /// Each netbox has a unique id. This is used primarily for undos, as we 00268 /// also keep a list of netboxes in order of id, so lookup by id becomes 00269 /// quite quick. 00270 static OP_NetworkBox *lookupNetworkBox(int unique_id); 00271 int getUniqueId() const { return myUniqueId; } 00272 00273 static void clearAllPendingUndoFlags(); 00274 00275 /// ALWAYS call this with 'resizing' == true before you do any resizing 00276 /// operations (e.g. setW()), and call it after you're done resizing with 00277 /// 'resizing' == false. You should only do this once for each group of 00278 /// resizing operations on the same netbox. 00279 /// 00280 /// This method: 00281 /// 1) ensures we get a proper undo block around all the resize ops, and 00282 /// 2) allows you to use setXY() to stretch the box to the left (otherwise, 00283 /// setXY() just moves the box) 00284 void setResizing(bool resizing); 00285 bool getResizing(); 00286 00287 /// Initialize the dragbar height for the network box to use. This gives it 00288 /// a more accurate idea of what its bounds are. 00289 static void setDragbarHeight(fpreal height) 00290 { 00291 theDragbarHeight = height; 00292 } 00293 00294 private: 00295 /// Do NOT allow copying of a network box, as each item can only be in one 00296 /// netbox at a time. If for some reason these ever get implemented, 00297 /// remember to deal with the unique id appropriately. 00298 OP_NetworkBox(const OP_NetworkBox &other); 00299 OP_NetworkBox &operator=(const OP_NetworkBox &other); 00300 00301 /// Given a delta-x and delta-y, move all our items the same amount 00302 void moveItems(fpreal dx, fpreal dy); 00303 00304 /// Callback for the network's events 00305 static void netChanged(OP_Node *caller, void *callee, 00306 OP_EventType type, void *data); 00307 00308 void saveForUndoAddItem(OP_NetworkBoxItem *item); 00309 void saveForUndoColor(); 00310 void saveForUndoLayout(); 00311 void saveForUndoMinimize(); 00312 void saveForUndoPick(); 00313 void saveForUndoRemoveItem(OP_NetworkBoxItem *item); 00314 void saveForUndoRename(); 00315 void saveForUndoResize(); 00316 00317 void clearUndoFlags(); 00318 void setAnyUndoFlag(); 00319 bool getAnyUndoPending() const; 00320 00321 /// This should only be called by our loading mechanism while we load, right 00322 /// after we get created! 00323 void setUniqueId(int id); 00324 00325 OP_Network *myNetwork; 00326 UT_Color myColor; 00327 UT_String myName; 00328 00329 /// ALWAYS set these through accessors to ensure proper undo creation 00330 fpreal myX, myY; 00331 fpreal myW, myH; 00332 00333 // CAUTION: Do not play with the ordering of these items, they should match 00334 // in order with the items in OPUI_NetworkBox for safe and 00335 // efficient synchronization between OP and OPUI levels 00336 UT_PtrArray<OP_NetworkBoxItem *> myItems; 00337 00338 /// Keeps info like timestamps for last modification time, creation time, 00339 /// etc 00340 OP_Stat myStats; 00341 00342 /// Encapsulates all our flags 00343 OP_NetworkBoxFlags myFlags; 00344 00345 UT_AutoUndoBlock *myUndoResizeBlock; 00346 00347 // Note that although netboxes share their namespace with nodes, they do not 00348 // share their "ID space". 00349 int myUniqueId; 00350 00351 bool myAnyUndoFlagSet; 00352 00353 /// The height of the drag bar. This is initialized for us by the OPUI 00354 /// network boxes. 00355 static fpreal theDragbarHeight; 00356 }; 00357 00358 #endif 00359
1.5.9