HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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  ~OP_NetworkBox() override;
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  void setXY(fpreal x, fpreal y) override;
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  fpreal getX() const override;
80  fpreal getY() const override;
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  fpreal getW() const override;
104  fpreal getH() const override;
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  const UT_String &getItemName() const override
130  { return myName; };
131  bool setItemName(const UT_String &name) override
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  bool getPicked() const override;
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  bool setPicked(bool on_off,
206  bool propagate_parent_event = true) override;
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  /// Get the alpha value for this drawing network box.
220  fpreal getAlpha() const;
221  /// Set the alpha value for drawing this network box.
222  bool setAlpha(fpreal alpha);
223 
224  /// A very general purpose method used to temporarily mark this network box
225  /// as being involved in an operation. Very useful if e.g. we have a set of
226  /// nodes and network boxes to apply an operation to. In this case we want
227  /// to mark each netbox as we apply our op to it and its contents, in case
228  /// any of the nodes we're passed happen to be in one of those netboxes. In
229  /// this way we can quickly check if a node's owning box has been marked,
230  /// and avoid duplicately applying the operation to the node again. REMEMBER
231  /// to UNMARK all netboxes you marked once you're done with your operation!
232  void setMarked(bool flag);
233  bool getMarked();
234 
235  /// Calculate the smallest bounds we're willing to accept as our size
236  /// given our contents. By default, 'incl_buff_border' is set to add a small
237  /// buffer border to make the layout look pretty. NOTE: If we contain no
238  /// items, we return an inverted bounding box, see implementation for
239  /// further details.
240  void getItemBounds(fpreal &x1, fpreal &y1, fpreal &x2,
241  fpreal &y2, bool incl_buff_border = true)
242  const;
243 
244  /// Automatically alters myX, myY, myW, myH in order to snap the size of
245  /// the netbox to the minimum bounding box enclosing its contents. Will
246  /// ALWAYS resize the box to the minimum bounding box size, unlike
247  /// resizeToFit(). Set 'incl_buff_border' to true if you want a small
248  /// buffer border to make the layout look pretty.
249  void snapToBounds(bool incl_buff_border = true);
250 
251  /// Save the attributes of this network box to the ostream
252  int save(std::ostream &os, const OP_SaveFlags &flags);
253 
254  /// Load the contents of the stream into the attributes of this network
255  /// box; if binary is nonzero, load in binary mode.
256  /// Loading doesn't send the OP_NETWORKBOX_CREATED message to the network;
257  /// the caller is responsible for doing that.
258  bool load(UT_IStream &is);
259  /// Depending on the order in which netboxes are saved, we may load them
260  /// in an order where an owned netbox is loaded before its owner. In this
261  /// case, we need to run through all the netboxes after loading them to
262  /// set up any ownerships that fall into this category.
263  void resolveLoadedOwnerName();
264 
265  /// Returns my item type (OP_ITEMTYPE_NETWORKBOX)
266  OP_ItemType getItemType() const override;
267 
268  const OP_Stat &getStat() const { return myStats; }
269  OP_Stat &getStat() { return myStats; }
270 
271  /// Return the network i'm in
272  OP_Network *getParentNetwork() const override;
273 
274  /// Sets 'cmd' to be a string containing our values for the flags specified
275  /// by 'flags'. If 'flags' == NULL, then we output values for all of our
276  /// flags.
277  void getSaveFlagsString(UT_String &cmd,
278  const char *flags,
279  bool save_to_hip) const;
280 
281  /// Used by opscript, this outputs the sequence of hscript commands
282  /// necessary to recreate this network box. Does not script the box's
283  /// contents. 'dogeneral' is set when opscript is generating a macro.
284  int saveCommand(std::ostream &os, const char *name,
285  int dogeneral) const;
286 
287  /// Each netbox has a unique id. This is used primarily for undos, as we
288  /// also keep a list of netboxes in order of id, so lookup by id becomes
289  /// quite quick.
290  static OP_NetworkBox *lookupNetworkBox(int unique_id);
291  int getUniqueId() const { return myUniqueId; }
292  int64 getItemUniqueId() const override
293  { return myUniqueId; }
294 
295  /// Control the default color used on new network boxes.
296  static const UT_Color &defaultColor();
297  static void setDefaultColor(const UT_Color *color);
298 
299  /// Clear undo flags on all network boxes.
300  static void clearAllPendingUndoFlags();
301 
302  /// ALWAYS call this with 'resizing' == true before you do any resizing
303  /// operations (e.g. setW()), and call it after you're done resizing with
304  /// 'resizing' == false. You should only do this once for each group of
305  /// resizing operations on the same netbox.
306  ///
307  /// This method:
308  /// 1) ensures we get a proper undo block around all the resize ops, and
309  /// 2) allows you to use setXY() to stretch the box to the left (otherwise,
310  /// setXY() just moves the box)
311  void setResizing(bool resizing);
312  bool getResizing() const;
313 
314  /// Accessors for the auto fit flag on the network box.
315  void setAutoFit(bool autofit);
316  bool getAutoFit() const;
317 
318  /// Returns the amount of memory owned by this OP_NetworkBox
319  int64 getMemoryUsage(bool inclusive) const;
320 
321 private:
322  /// Given a delta-x and delta-y, move all our items the same amount
323  void moveItems(fpreal dx, fpreal dy);
324 
325  /// Callback for the network's events
326  static void netChanged(OP_Node *caller, void *callee,
327  OP_EventType type, void *data);
328 
329  void saveForUndoAddItem(OP_NetworkBoxItem *item);
330  void saveForUndoAlpha();
331  void saveForUndoLayout();
332  void saveForUndoMinimize();
333  void saveForUndoRemoveItem(OP_NetworkBoxItem *item);
334  void saveForUndoRename();
335  void saveForUndoComment();
336  void saveForUndoResize();
337 
338  void clearUndoFlags();
339  void setAnyUndoFlag();
340  bool getAnyUndoPending() const;
341 
342  /// This should only be called by our loading mechanism while we load, right
343  /// after we get created!
344  void setUniqueId(int id);
345 
346  OP_Network *myNetwork;
347  UT_String myName;
348  UT_StringHolder myLoadedOwnerName;
349  UT_StringHolder myComment;
350 
351  /// Our alpha value. A negative value indicates we should use the
352  /// default value set in the UI config files.
353  fpreal myAlpha;
354 
355  /// ALWAYS set these through accessors to ensure proper undo creation
356  fpreal myX, myY;
357  fpreal myW, myH;
358 
359  // CAUTION: Do not play with the ordering of these items, they should match
360  // in order with the items in OPUI_NetworkBox for safe and
361  // efficient synchronization between OP and OPUI levels
362  OP_NetworkBoxItemList myItems;
363 
364  /// Keeps info like timestamps for last modification time, creation time,
365  /// etc
366  OP_Stat myStats;
367 
368  /// Encapsulates all our flags
369  OP_NetworkBoxFlags myFlags;
370 
371  UT_AutoUndoBlock *myUndoResizeBlock;
372 
373  // Note that although netboxes share their namespace with nodes, they do not
374  // share their "ID space".
375  int myUniqueId;
376 
377  bool myAnyUndoFlagSet;
378 
379  /// The height of the drag bar. This is initialized for us by the OPUI
380  /// network boxes.
381  static fpreal theDragbarHeight;
382 };
383 
384 ///////////////////////////////////////////////////////////////////////////////
385 //
386 // Method Implementations
387 //
388 
389 template <typename F>
390 void
392  OP_ItemTypeMask item_mask,
393  bool include_hidden,
394  bool recursive,
395  bool picked_only,
396  const F &functor) const
397 {
398  for (exint i = 0, n = myItems.size(); i < n; ++i)
399  {
400  OP_NetworkBoxItem &item = *myItems(i);
401 
402  if ((item.getItemType() & item_mask) != 0)
403  {
404  if (include_hidden ||
405  item.getItemType() != OP_ITEMTYPE_NODE ||
406  (UTverify_cast<const OP_Node *>(myItems(i)))->getExpose())
407  {
408  if (!picked_only || item.getPicked())
409  functor(item);
410  }
411  }
412  if (recursive && myItems(i)->getItemType() == OP_ITEMTYPE_NETWORKBOX)
413  {
414  const OP_NetworkBox
415  &box = *UTverify_cast<const OP_NetworkBox *>(&item);
416  box.traverseItems(item_mask, include_hidden, recursive, picked_only,
417  functor);
418  }
419  }
420 }
421 
422 #endif
const UT_String & getItemName() const override
void traverseItems(OP_ItemTypeMask item_mask, bool include_hidden, bool recursive, bool picked_only, const F &functor) const
GLbitfield flags
Definition: glcorearb.h:1596
virtual OP_ItemType getItemType() const =0
Our children should implement this and return what type of item they are.
bool setItemName(const UT_String &name) override
int64 getMemoryUsage(bool inclusive) const
virtual void setXY(fpreal x, fpreal y)=0
int64 exint
Definition: SYS_Types.h:125
virtual fpreal getY() const =0
const UT_StringHolder & getComment() const
virtual fpreal getX() const =0
OP_Stat & getStat()
GLint y
Definition: glcorearb.h:103
SYS_FORCE_INLINE TO_T UTverify_cast(FROM_T from)
Definition: UT_Assert.h:229
virtual OP_Network * getParentNetwork() const =0
Returns the network that is our parent.
OP_NetworkBoxSaveType
Definition: OP_NetworkBox.h:40
exint size() const
Definition: UT_Array.h:646
GLdouble GLdouble x2
Definition: glad.h:2349
virtual bool setPicked(bool on_off, bool propagate_parent_event=true)=0
OP_ItemType
Definition: OP_ItemId.h:28
virtual fpreal getW() const =0
GLdouble n
Definition: glcorearb.h:2008
GLdouble y1
Definition: glad.h:2349
int64 getItemUniqueId() const override
Functions to get hip-file-unique ids for any item type.
long long int64
Definition: SYS_Types.h:116
GLfloat GLfloat GLfloat alpha
Definition: glcorearb.h:112
GLuint const GLchar * name
Definition: glcorearb.h:786
GLint GLenum GLint x
Definition: glcorearb.h:409
const OP_Stat & getStat() const
unsigned int OP_ItemTypeMask
Definition: OP_ItemId.h:43
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
SIM_API const UT_StringHolder force
GLuint color
Definition: glcorearb.h:1261
fpreal64 fpreal
Definition: SYS_Types.h:277
#define OP_API
Definition: OP_API.h:10
OP_EventType
Definition: OP_Value.h:22
int getUniqueId() const
virtual bool getPicked() const =0
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
virtual fpreal getH() const =0
GLdouble GLdouble GLdouble y2
Definition: glad.h:2349
type
Definition: core.h:1059
Definition: format.h:895