HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OP_NetworkBox.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: OP_NetworkBox.h (OP Library, C++)
7  *
8  * COMMENTS: Defines network boxes!
9  *
10  */
11 
12 #ifndef __OP_NetworkBox__
13 #define __OP_NetworkBox__
14 
15 #include "OP_API.h"
16 #include "OP_NetworkBoxFlags.h"
17 #include "OP_NetworkBoxItem.h"
18 #include "OP_Node.h"
19 
20 #include <UT/UT_Assert.h>
21 #include <UT/UT_String.h>
22 #include <UT/UT_ValArray.h>
23 #include <SYS/SYS_Types.h>
24 
25 #include <iosfwd>
26 
27 
28 class OP_Network;
29 class OP_Stat;
30 class UT_AutoUndoBlock;
31 
32 #define OP_NETWORKBOX_DEFAULT_W 2.5F
33 #define OP_NETWORKBOX_DEFAULT_H 2.5F
34 #define OP_NETWORKBOX_MINIMUM_W 0.3F
35 #define OP_NETWORKBOX_MINIMUM_H 0.3F
36 #define OP_NETWORKBOX_MINIMIZED_W 2.5F
37 
38 /// When saving a network box to the clipboard, you can use this enumeration
39 /// to specify which of its contents to automatically save with it
41 {
42  OP_NETWORKBOX_SAVE_NO_CONTENTS, // Don't save any items in the box
43  OP_NETWORKBOX_SAVE_ALL_CONTENTS, // Save all items in the box
44  OP_NETWORKBOX_SAVE_PICKED_CONTENTS, // Save only the picked items
45  OP_NETWORKBOX_SAVE_SPEC_CONTENTS // Save only the specified items.
46  // Applies only to nodes (cannot
47  // save an indirect unless you save
48  // its parent subnet entirely).
49  // Supported only by certain
50  // methods which require a node ptr
51  // array passed in
52 };
53 
55 {
56 public:
57  /// Create a network box with the specified name. If a duplicate name is
58  /// passed in, it will be altered to make it unique in the network.
59  OP_NetworkBox(const UT_String &name, OP_Network *net);
60  virtual ~OP_NetworkBox();
61 
62  /// Set the coordinates for this box (lower left corner) in absolute units.
63  /// NOTE: If myResizing is set, then setXY does NOT move the box, but
64  /// effectively resizes it by moving the lower/left corner of the box
65  /// without moving its contents, and this may result in a change in myW
66  /// and/or myH.
67  virtual void setXY(fpreal x, fpreal y);
68 
69  /// Same as setXY(), but here we can force the box to take on these X/Y
70  /// coordinates, even if our contents don't fit us any more. The
71  /// propagate_parent_event tells this method whether or not it should send
72  /// and event after moving the network box -- this should normally be set
73  /// to true.
74  void setXY(fpreal x, fpreal y, bool force,
75  bool propagate_parent_event);
76 
77  /// Get the position of this box. Units are absolute, as opposed
78  /// to relative units found in OPUI.
79  virtual fpreal getX() const;
80  virtual fpreal getY() const;
81 
82  /// Get and set the width and height of this box. Units are absolute
83  /// as opposed to the relative units found in OPUI.
84  /// If the width or height specified is smaller than that which will
85  /// contain all of the items, the width or height respectively will only
86  /// be adjusted to the minimum size required to contain the items. To avoid
87  /// this automatic size check, set 'force' to true.
88  void setW(fpreal w, bool force = false);
89  void setH(fpreal h, bool force = false);
90 
91  /// Set the network box's width like setW(), but first check if the new
92  /// width is valid. This method wraps the resizing operation
93  /// with calls to setResizing(true) and setResizing(false).
94  bool setWWithBoundsChecks(fpreal w);
95 
96  /// Set the network box's width like setH(), but first check if the new
97  /// height is valid. This method wraps the resizing operation
98  /// with calls to setResizing(true) and setResizing(false).
99  bool setHWithBoundsChecks(fpreal h);
100 
101  /// Gives you the w/h of the netbox as you see it, meaning if the netbox is
102  /// minimized, you get the minimized size.
103  virtual fpreal getW() const;
104  virtual fpreal getH() const;
105 
106  /// Return the full maximized size of the netbox, regardless of whether the
107  /// netbox is currently maximized or minimized
108  fpreal getMaximizedW() const;
109  fpreal getMaximizedH() const;
110 
111  /// Using the netbox's current X,Y, width, and height data,
112  /// resize the netbox if necessary to fit its contents. Will ONLY resize if
113  /// the box is too small. WILL add a small buffer border around its contents
114  /// for prettiness.
115  void resizeToFit();
116 
117  /// Given an area defined by the absolute coordinates (xmin, ymin) -
118  /// (xmax, ymax), resize the netbox if necessary to ensure that the area
119  /// can fit inside this box. Will ONLY resize if the box is too small. Will
120  /// NOT add a buffer border around its contents for prettiness.
121  void resizeToFit(fpreal xmin, fpreal ymin, fpreal xmax,
122  fpreal ymax);
123 
124  /// The name which is used for identification and in displays of this
125  /// box. setName() returns true if the name change was successful, and
126  /// alters the name slightly if necessary to make it unique within this
127  /// network.
128  bool setName(const UT_String &name);
129  virtual const UT_String &getItemName() const
130  { return myName; };
131  virtual bool setItemName(const UT_String &name)
132  { return setName(name); }
133 
134  /// The comment that is used to describe the network box.
135  void setComment(const UT_StringHolder &comment);
136  const UT_StringHolder &getComment() const { return myComment; };
137 
138  /// Items which are contained in this box can be OP_Nodes,
139  /// OP_IndirectInputs or OP_NetworkBoxes. They are all encapsulated
140  /// in the OP_NetworkBoxItem class.
141  int getNitems() const;
142  int getNexposedItems() const;
143  OP_NetworkBoxItem *getItem(int idx) const;
144 
145  /// Collect items base on their type, possibly recursively.
146  void getItems(OP_ItemTypeMask item_mask,
147  OP_NetworkBoxItemList &list,
148  bool include_hidden = true,
149  bool recursive = true,
150  bool picked_only = false) const;
151  void getNodes(OP_NodeList &list,
152  bool include_hidden = true,
153  bool recursive = true,
154  bool picked_only = false) const;
155 
156  // Like getItems(), except that it only counts the number of them
157  exint countItems(
158  OP_ItemTypeMask item_mask,
159  bool include_hidden = true,
160  bool recursive = true,
161  bool picked_only = false) const;
162 
163  // Traverse the items returned by getItems()
164  template <typename F>
165  void traverseItems(
166  OP_ItemTypeMask item_mask,
167  bool include_hidden,
168  bool recursive,
169  bool picked_only,
170  const F &functor) const;
171 
172  /// Add an item to this box. If the item was previously in another netbox,
173  /// we remove it from there before we add it here. If 'resize_to_fit' is
174  /// set to true, we'll resize if necessary to fit our contents after the
175  /// item is added - this option should always be on, except when the undo
176  /// mechanism requires some extra control to restore states properly
177  bool addItem(OP_NetworkBoxItem *item,
178  bool propagate_parent_event = true,
179  bool resize_to_fit = true);
180  bool addItems(OP_NetworkBoxItemList &items);
181 
182  /// Remove the item from this box. The item's owner box is set to NULL.
183  bool removeItem(OP_NetworkBoxItem *item,
184  bool propagate_parent_event = true,
185  bool do_reparent = false,
186  bool save_undo = true);
187  bool removeItems(OP_NetworkBoxItemList &items);
188  bool removeAllItems(bool do_reparent = false);
189 
190  /// Sets the network boxes contents to be exactly the items in 'items' (i.e.
191  /// removes any previous contents not in 'items'). Set 'snap_to_bounds' to
192  /// true if you'd like us to make the netbox's dimensions snap to form a
193  /// nice snug fit around its new contents.
194  bool setContents(OP_NetworkBoxItemList &items,
195  bool snap_to_bounds);
196 
197  /// Returns true if this box is currently picked
198  virtual int getPicked() const;
199 
200  /// Set whether this box is picked; returns true if the picked
201  /// status has changed. Setting 'propagate_parent_event' to false stops
202  /// this method from notifying the network of this change, useful when we're
203  /// picking a lot of items at once, it's inefficient to trigger a callback
204  /// for each pick separately, can just do one update at the end
205  virtual int setPicked(int on_off,
206  bool propagate_parent_event = true);
207 
208  /// Get whether this box is currently minimized
209  bool getMinimized() const;
210 
211  /// Set whether this box is currently minimized
212  /// If update_position is true, then the box is moved to accomodate the
213  /// minimized status. If propagate_parent_event is true, an event is sent
214  /// to the network about our minimized state.
215  bool setMinimized(bool isminimized,
216  bool update_position,
217  bool propagate_parent_event);
218 
219  /// A very general purpose method used to temporarily mark this network box
220  /// as being involved in an operation. Very useful if e.g. we have a set of
221  /// nodes and network boxes to apply an operation to. In this case we want
222  /// to mark each netbox as we apply our op to it and its contents, in case
223  /// any of the nodes we're passed happen to be in one of those netboxes. In
224  /// this way we can quickly check if a node's owning box has been marked,
225  /// and avoid duplicately applying the operation to the node again. REMEMBER
226  /// to UNMARK all netboxes you marked once you're done with your operation!
227  void setMarked(bool flag);
228  bool getMarked();
229 
230  /// Calculate the smallest bounds we're willing to accept as our size
231  /// given our contents. By default, 'incl_buff_border' is set to add a small
232  /// buffer border to make the layout look pretty. NOTE: If we contain no
233  /// items, we return an inverted bounding box, see implementation for
234  /// further details.
235  void getItemBounds(fpreal &x1, fpreal &y1, fpreal &x2,
236  fpreal &y2, bool incl_buff_border = true)
237  const;
238 
239  /// Automatically alters myX, myY, myW, myH in order to snap the size of
240  /// the netbox to the minimum bounding box enclosing its contents. Will
241  /// ALWAYS resize the box to the minimum bounding box size, unlike
242  /// resizeToFit(). Set 'incl_buff_border' to true if you want a small
243  /// buffer border to make the layout look pretty.
244  void snapToBounds(bool incl_buff_border = true);
245 
246  /// Save the attributes of this network box to the ostream
247  int save(std::ostream &os, const OP_SaveFlags &flags);
248 
249  /// Load the contents of the stream into the attributes of this network
250  /// box; if binary is nonzero, load in binary mode.
251  /// Loading doesn't send the OP_NETWORKBOX_CREATED message to the network;
252  /// the caller is responsible for doing that.
253  bool load(UT_IStream &is);
254 
255  /// Returns my item type (OP_ITEMTYPE_NETWORKBOX)
256  virtual OP_ItemType getItemType() const;
257 
258  const OP_Stat &getStat() const { return myStats; }
259  OP_Stat &getStat() { return myStats; }
260 
261  /// Return the network i'm in
262  virtual OP_Network *getParentNetwork() const;
263 
264  /// Sets 'cmd' to be a string containing our values for the flags specified
265  /// by 'flags'. If 'flags' == NULL, then we output values for all of our
266  /// flags.
267  void getSaveFlagsString(UT_String &cmd,
268  const char *flags,
269  bool save_to_hip) const;
270 
271  /// Used by opscript, this outputs the sequence of hscript commands
272  /// necessary to recreate this network box. Does not script the box's
273  /// contents. 'dogeneral' is set when opscript is generating a macro.
274  int saveCommand(std::ostream &os, const char *name,
275  int dogeneral) const;
276 
277  /// Each netbox has a unique id. This is used primarily for undos, as we
278  /// also keep a list of netboxes in order of id, so lookup by id becomes
279  /// quite quick.
280  static OP_NetworkBox *lookupNetworkBox(int unique_id);
281  int getUniqueId() const { return myUniqueId; }
282  virtual int64 getItemUniqueId() const { return myUniqueId; }
283 
284  /// Control the default color used on new network boxes.
285  static const UT_Color &defaultColor();
286  static void setDefaultColor(const UT_Color *color);
287 
288  /// Clear undo flags on all network boxes.
289  static void clearAllPendingUndoFlags();
290 
291  /// ALWAYS call this with 'resizing' == true before you do any resizing
292  /// operations (e.g. setW()), and call it after you're done resizing with
293  /// 'resizing' == false. You should only do this once for each group of
294  /// resizing operations on the same netbox.
295  ///
296  /// This method:
297  /// 1) ensures we get a proper undo block around all the resize ops, and
298  /// 2) allows you to use setXY() to stretch the box to the left (otherwise,
299  /// setXY() just moves the box)
300  void setResizing(bool resizing);
301  bool getResizing();
302 
303  /// Accessors for the auto fit flag on the network box.
304  void setAutoFit(bool autofit);
305  bool getAutoFit();
306 
307  /// Returns the amount of memory owned by this OP_NetworkBox
308  int64 getMemoryUsage(bool inclusive) const;
309 
310 private:
311  /// Given a delta-x and delta-y, move all our items the same amount
312  void moveItems(fpreal dx, fpreal dy);
313 
314  /// Callback for the network's events
315  static void netChanged(OP_Node *caller, void *callee,
316  OP_EventType type, void *data);
317 
318  void saveForUndoAddItem(OP_NetworkBoxItem *item);
319  void saveForUndoLayout();
320  void saveForUndoMinimize();
321  void saveForUndoRemoveItem(OP_NetworkBoxItem *item);
322  void saveForUndoRename();
323  void saveForUndoComment();
324  void saveForUndoResize();
325 
326  void clearUndoFlags();
327  void setAnyUndoFlag();
328  bool getAnyUndoPending() const;
329 
330  /// This should only be called by our loading mechanism while we load, right
331  /// after we get created!
332  void setUniqueId(int id);
333 
334  OP_Network *myNetwork;
335  UT_String myName;
336  UT_StringHolder myComment;
337 
338  /// ALWAYS set these through accessors to ensure proper undo creation
339  fpreal myX, myY;
340  fpreal myW, myH;
341 
342  // CAUTION: Do not play with the ordering of these items, they should match
343  // in order with the items in OPUI_NetworkBox for safe and
344  // efficient synchronization between OP and OPUI levels
345  OP_NetworkBoxItemList myItems;
346 
347  /// Keeps info like timestamps for last modification time, creation time,
348  /// etc
349  OP_Stat myStats;
350 
351  /// Encapsulates all our flags
352  OP_NetworkBoxFlags myFlags;
353 
354  UT_AutoUndoBlock *myUndoResizeBlock;
355 
356  // Note that although netboxes share their namespace with nodes, they do not
357  // share their "ID space".
358  int myUniqueId;
359 
360  bool myAnyUndoFlagSet;
361 
362  /// The height of the drag bar. This is initialized for us by the OPUI
363  /// network boxes.
364  static fpreal theDragbarHeight;
365 };
366 
367 ///////////////////////////////////////////////////////////////////////////////
368 //
369 // Method Implementations
370 //
371 
372 template <typename F>
373 void
375  OP_ItemTypeMask item_mask,
376  bool include_hidden,
377  bool recursive,
378  bool picked_only,
379  const F &functor) const
380 {
381  for (exint i = 0, n = myItems.size(); i < n; ++i)
382  {
383  OP_NetworkBoxItem &item = *myItems(i);
384 
385  if ((item.getItemType() & item_mask) != 0)
386  {
387  if (include_hidden ||
388  item.getItemType() != OP_ITEMTYPE_NODE ||
389  (UTverify_cast<const OP_Node *>(myItems(i)))->getExpose())
390  {
391  if (!picked_only || item.getPicked())
392  functor(item);
393  }
394  }
395  if (recursive && myItems(i)->getItemType() == OP_ITEMTYPE_NETWORKBOX)
396  {
397  const OP_NetworkBox
398  &box = *UTverify_cast<const OP_NetworkBox *>(&item);
399  box.traverseItems(item_mask, include_hidden, recursive, picked_only,
400  functor);
401  }
402  }
403 }
404 
405 #endif
void traverseItems(OP_ItemTypeMask item_mask, bool include_hidden, bool recursive, bool picked_only, const F &functor) const
virtual OP_ItemType getItemType() const =0
Our children should implement this and return what type of item they are.
int64 getMemoryUsage(bool inclusive) const
virtual int setPicked(int on_off, bool propagate_parent_event=true)=0
GLuint color
Definition: glcorearb.h:1260
virtual void setXY(fpreal x, fpreal y)=0
virtual fpreal getY() const =0
const UT_StringHolder & getComment() const
virtual fpreal getX() const =0
GLbitfield flags
Definition: glcorearb.h:1595
OP_Stat & getStat()
GLint y
Definition: glcorearb.h:102
virtual OP_Network * getParentNetwork() const =0
Returns the network that is our parent.
OP_NetworkBoxSaveType
Definition: OP_NetworkBox.h:40
png_uint_32 i
Definition: png.h:2877
exint size() const
Definition: UT_Array.h:444
virtual const UT_String & getItemName() const
OP_ItemType
Definition: OP_ItemId.h:23
long long int64
Definition: SYS_Types.h:106
virtual fpreal getW() const =0
GLdouble n
Definition: glcorearb.h:2007
int64 exint
Definition: SYS_Types.h:115
GLboolean * data
Definition: glcorearb.h:130
GLuint const GLchar * name
Definition: glcorearb.h:785
SYS_FORCE_INLINE TO_T UTverify_cast(FROM_T from)
Definition: UT_Assert.h:175
virtual int getPicked() const =0
const OP_Stat & getStat() const
unsigned int OP_ItemTypeMask
Definition: OP_ItemId.h:38
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2001
double fpreal
Definition: SYS_Types.h:269
virtual int64 getItemUniqueId() const
Functions to get hip-file-unique ids for any item type.
#define OP_API
Definition: OP_API.h:10
GLint GLenum GLint x
Definition: glcorearb.h:408
OP_EventType
Definition: OP_Value.h:22
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
int getUniqueId() const
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
virtual bool setItemName(const UT_String &name)
virtual fpreal getH() const =0
png_infop png_uint_32 flag
Definition: png.h:2242