HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BM_State.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: Direct manipulation library (C++)
7  *
8  * COMMENTS:
9  * The base class of a BM state.
10  *
11  */
12 #ifndef __BM_State_H__
13 #define __BM_State_H__
14 
15 #include "BM_API.h"
16 #include "BM_ParmState.h"
17 #include <UI/UI_Keyboard.h>
18 #include <UT/UT_Array.h>
19 
20 
21 class DD_ChoiceList;
22 class DD_Source;
23 class UT_Options;
24 class UT_StringHolder;
25 class UT_Undo;
26 class UI_KeyResolveInfo;
27 class PI_StateTemplate;
28 class OP_Node;
29 class OP_Network;
30 class BM_OpHandleLink;
31 
33 {
34 public:
36  sticky = 1; // must be sticky by default (obsolete)
37  entered = 0;
38  scratch = 0;
39  requestnew = 0;
40  preempted = 0;
41  busybuild = 0;
42  wantlocate = 0;
43  modifier = 0;
44  concealed = 0;
45  }
46  unsigned sticky:1, // does not pop back after an operation
47  entered:3, // the way it was entered (BM_EntryType)
48  scratch:3, // entered from scratch
49  requestnew:1, // a new node is requested when generating
50  preempted:1, // have I been interrupted or not
51  busybuild:1, // I'm in the building stage (not editing)
52  wantlocate:1, // want to get locate events
53  modifier:1, // changes geometry, etc or not?
54  concealed:1; // are we concealed in a non-visible desktop?
55 };
56 
58 {
59 public:
60  enum BM_GenerateMode { BM_INLINE = 0x01,
61  BM_OUTLINE = 0x02,
62  BM_REGENERATE = 0x04
63  };
64 
65  // Class constructor and destructor.
66  BM_State( BM_SceneManager &app,
67  PI_StateTemplate &templ,
68  const char *cursor = 0,
69  const char *const *vnames = 0,
70  UI_EventMethod const *vmethods = 0);
71  ~BM_State() override;
72 
73  // Return the current status string for this state. This is used by the
74  // viewport rendering code to display some extra information in the
75  // viewport instead of in the blue status bar. If this string is
76  // returned empty (the default), it is ignored.
77  virtual void status(UT_String &s) const { s.harden(""); }
78 
79  // Render whatever extra things may be needed beside the status string.
80  // You can assume that translations to that location have been performed
81  // already (i.e., you can render without moving).
82  virtual void renderStatusExtras(RE_Render *) {}
83 
84  int isHandle() const override { return 0; }
85 
86  // Enter or exit this state. There are 2 entry types:
87  // 1. fulltime (BM_FULLTIME_ENTRY): the state stays on until another one
88  // is invoked; that other state replaces the current.
89  // 2. overlay (BM_OVERLAY_ENTRY): also known as "volatile", it gets
90  // triggered by pressing a key and stays on until the key is released.
91  // Upon exiting it returns control to the previous state. It is not
92  // allowed to overlay the current state with itself or to have
93  // nested overlay states. When starting the overlay state, the
94  // previous state is _interrupted_, not exited; then, it is _resumed_.
95  // enter() returns 0 if entered and -1 if not.
96  int enter(BM_SimpleState::BM_EntryType how) override;
97  void exit() override;
98 
99 
100  //
101  // When the current desktop is changed, it's possible that the state might
102  // have to clean up some stuff. The concealed() method is called when the
103  // desktop is changed, the revealed() method when the desktop is re-opened.
104  // Note, it may be possible to get a revealed() called without having the
105  // concealed called.
106  //
107  virtual void concealState();
108  virtual void revealState();
109 
110  // Interrupt this state or resume its activity. These methods should
111  // be called by overlay states when entering and exiting respectively.
112  // Interrupt will leave the state in limbo and will usually turn off
113  // the feed from the app; resume will do the opposite. interrupt()
114  // should not change the modeler's current state. If 'state' is given, it
115  // is the state that has interrupted/resumed us. This may be particularly
116  // useful if we are interrupted by a handle (possibly ours).
117  void interrupt(BM_SimpleState *state = 0) override;
118  void resume(BM_SimpleState *state = 0) override;
119  virtual void handleVolatileChanges() {}
120 
121  // Pre-process a mouse start event, in case we wish to push/position a
122  // handle so the mouse event is processed by the handle.
123  virtual int preprocessSelect(UI_Event *event);
124 
125  // Deal with the events the modeler has sent me. Scene events imply use
126  // of the mouse. Return 1 if consumed and 0 otherwise.
127  int handleMouseEvent (UI_Event *event) override;
128 
129  // This is where mouse wheel events get sent.
130  // Integer deltas are stored into event->state.values[Z] where 1 step is a
131  // multiple of 100. Positive values indicates that the wheel rotated
132  // forwards away from the use, while negative values are the opposite.
133  // Return 1 if consumed and 0 otherwise.
134  virtual int handleMouseWheelEvent(UI_Event *event);
135 
136  // Return false if un-handled.
137  virtual bool handleDoubleClickEvent(UI_Event *);
138 
139  // Called whenever the geometry changed (but not when the change was
140  // caused by modelling in this state)
141  virtual void handleGeoChangedEvent(UI_Event *);
142 
143  // Called by the viewport to allow the state to render its own bits.
144  // It calls doRender(), which is what derived classes should implement.
145  void render(RE_Render *r, int x, int y) override;
146 
147  // The state might contain something that it wants to display in a
148  // non-destructive manner (eg. by xor'ing). Note that this method is not
149  // called during the normal rendering of the workbench.
150  virtual void renderPartialOverlay(RE_Render *r, int x, int y);
151 
152  // Similar to enter, but totally from scratch. At this level, it's the
153  // same as doing an enter. It cannot be entered in volatile mode.
154  // We can start generating either in inline (insert) mode
155  // or in branching-off mode. The generation mode is relevant only when
156  // generating ops in a network. Some states reuse existing ops when
157  // possible instead of generating new ones. A request can be made for
158  // new ops here, but it is up to the individual state to interpret it.
159  virtual int generate(BM_SimpleState::BM_EntryType how,
160  bool insertmode = true,
161  bool requestnew = false);
162 
163  // Start or stop the generation process. At this level, generating doesn't
164  // mean a thing. We can start generating either in inline (insert) mode
165  // or in branching-off mode. The inline mode is the default. The mode
166  // is relevant only when generating ops in a network.
169  bool requestnew = false)
170  {
171  myFlags.scratch = how;
172  myFlags.requestnew = requestnew;
173  }
174  virtual void stopGenerating()
175  {
176  myFlags.scratch = 0;
177  myFlags.requestnew = 0;
178  }
179 
180  // Restart cancels what is currently being done and starts generating anew.
181  virtual void restart();
182 
183  // Check if the state will allow a restart to be triggered by a given key
184  // event. Override this to return false if you do not want this key to
185  // trigger a restart.
186  virtual bool allowRestartWithKey(const UI_Event &event) const;
187 
188  // Also, find out whether you meet the conditions to be entered, or simply
189  // if the given key matches (one of) yours:
190  int meetsEntryConditions (const UI_Event &event) const;
191  virtual int isEntryCondition (UI_Keyboard key) const;
192 
193  virtual void getKeyResolveInfo(UI_KeyResolveInfo &info);
194 
195  // Override this to handle transitory key presses, default implementation
196  // does nothing. Return true if key was handled. The key is in
197  // event.state.id and the keypress state is in event.state.data.
198  virtual bool handleTransitoryKey(const UI_Event & /*event*/)
199  { return false; }
200 
201  // Called if the state needs to handle changes in op parameters
202  virtual int hasOpNode(const OP_Node &/*node*/) const;
203  virtual void handleOpNodeChange(OP_Node &/*node*/);
204  virtual void handleOpUIChange(OP_Node &/*node*/);
205  virtual void handleOpNetChange(OP_Network &/*net*/);
206  virtual void handleOpNetClear();
207 
208  // See how you can handle a node being deleted. If it's an implicit
209  // node we might be OK. Return 0 if we can handle it, -1 if we must be
210  // exited or restarted from scratch.
211  virtual int handleNodeDeleted(OP_Node &/*node*/);
212 
213  // Set or get the "locate" flag, which determines whether we're interested
214  // in locate events or not.
215  void wantsLocates(int yesNo) { myFlags.wantlocate=yesNo; }
216  virtual int hasLocates() const{ return myFlags.wantlocate;}
217  virtual bool doesHandleLocates() const { return false; }
218 
219  // Query some of the flags:
220  int isPreempted() const { return myFlags.preempted; }
221  int isBuilding () const { return myFlags.busybuild; }
222  int isEntered() const { return myFlags.entered; }
223  bool isConcealed() const { return myFlags.concealed; }
224 
225  int isGenerating() const { return myFlags.scratch; }
226  int isGeneratingInline() const
227  { return myFlags.scratch==BM_State::BM_INLINE; }
228  bool isRequestingNew() const
229  { return myFlags.requestnew; }
230  int isRegenerating() const
231  { return myFlags.scratch==BM_State::BM_REGENERATE; }
232 
233  bool isOverlay() const override
234  {
235  return (myFlags.entered &
237  }
238  int isFullTime() const
239  {
240  return myFlags.entered &
242  }
243  int isModifier() const override
244  {
245  return myFlags.modifier;
246  }
247 
248  // If a state generates a sop and displays it (eg. a hide sop), it
249  // will want the state controller to ignore the change so the state
250  // doesn't exit.
251  virtual bool ignoreDisplayFlagChange() const { return false; }
252 
253  // Return a pointer to the feel containing the extra buttons of the state.
254  // If a state has no extra buttons, 0 will be returned.
255  virtual int findPI(BM_OpHandleLink *pi) const;
256 
257  // Find out if the state is inherently sticky whether entered FULLTIME or
258  // not. Non-sticky (ie oneTime) states pop back to the view state after
259  // they've completed an operation. A state is sticky by default.
260  int isSticky() const { return myFlags.sticky; }
261 
262  // Check if MMB can be used for indirect handle drags. Some states use
263  // the MMB themselves.
264  virtual bool getAllowIndirectHandleDrag() const { return true; }
265 
266  // Checks if and how an RMB menu can be popped up. Usually, when the state
267  // is in building mode, the RMB menus are not allowed (since RMB is used
268  // to complete building/drawing/selection).
270  {
271  BM_RMB_MENU_ALLOWED, // show the menu right away
272  BM_RMB_MENU_DELAYED, // wait and show menu if mouse was not dragged
273  BM_RMB_MENU_DENIED // don't show the menu at all
274  };
275  virtual BM_RMBMenuPopupMode getRMBMenuPopupMode(short altflags) const;
276 
277  // Return this state's index in the list of states:
278  int index() const { return myIndex; }
279  void index(int idx) { myIndex = idx; }
280 
281  // The name of this class:
282  const char *className() const override;
283 
284  const PI_StateTemplate &getTemplate() const { return myTemplate; }
285  PI_StateTemplate &getTemplate() { return myTemplate; }
286 
287  // For most states, op dependency is determined entirely by the state
288  // template. It is possible, however, for the state instance itself
289  // to dynamically change whether or not it is op dependent on the fly.
290  // Any state changing its op dependency in this fashion must notify the
291  // appropriate BM_OpStateControl by calling its updateOpDependence()
292  // method. In general, getTemplate().opIndependent() should be false
293  // for such states to allow use of switchToOpDependent().
294  virtual int isOpIndependent() const;
295 
296  // Normally, when a user wants to switch to a node's default state, say
297  // by hitting BM_KEY_ACCEPT, when already in that state, we have to use
298  // a new instance whenever the current instance is not op dependent.
299  //
300  // These methods make it possible to override that behavior and change
301  // the current instance to be op dependent.
302  //
303  // NB: Only used when !getTemplate().opIndependent() && isOpIndependent(),
304  // i.e., it is registered as an op dependent state that is currently
305  // not op dependent, and hasOpNode() returns true for the target node.
306  virtual bool canSwitchToOpDependent() const { return false; }
307  virtual void switchToOpDependent();
308 
309  // Returns the icon name and label that should appear in the viewer
310  // operation controls bar when we are in this state. The default
311  // implementation extracts this information from the state template.
312  const char *getOperationBarIconName() const override;
313  const char *getOperationBarLabel() const override;
314  const char *getHotkeyString() const override;
315 
316  virtual void afterUndo();
317 
318  // The user can dynamically change the bindings from the textport
319  // We need to refresh the current handles in the viewport because
320  // they could be affected.
321  virtual void refreshBindings(int id, const char *op_type);
322  // This method is called reload the stored settings of any attached
323  // PIs when these settings may have been changed.
324  virtual void refreshSettings(int id, const char *op_type);
325 
326  const char *replaceCursor(const char *newcursor) override;
327 
328  // Return the help for this state in the string that's passed in.
329  // (Note that custom states may override getHelp() to
330  // provide help, even though there is no actual help file.) is_html
331  // will be set to indicate if the help is in html or not.
332  // NOTE: The help file may contain unexpanded hotkey variables.
333  virtual void getHelp(UT_String &help_text, bool &is_html);
334 
335  // Find all help file information, see FUSE:openHdoxURL().
336  virtual void getHelpDirAndNameOrUrl(UT_StringHolder &dir,
338  UT_StringHolder &url);
339 
340  // Show persistent handles in this state?
341  virtual bool showPersistent() const { return true; }
342 
343  // Return true if we would like to receive an event intended for the
344  // click-orienter but was not consumed by it. All normal states should
345  // only want this event if they are overlay states.
346  virtual bool wantFailedOrienterEvent() const { return isOverlay(); }
347 
348  // Show the geometry of the selected operator in this state?
349  virtual bool getShowSelectedOp() const { return true; }
350 
351  // Reset and clear any remembered state data. Used mainly for states such
352  // as view, which would like to home on world origin again, etc.
353  virtual void resetStateForNew() { };
354 
355  // A state can override what appears in the select mode side bar of the
356  // viewer.
357  virtual UI_Feel *getCustomSelectModeSideBar() const { return 0; }
358 
359  // Returns true if the state respects the secure selection setting.
360  virtual bool useSecureSelection() const { return true; }
361 
362  // Returns true if the state supports volatile selections.
363  virtual bool useVolatileSelection() const { return false; }
364 
365  // Get the global state preferences. Preferences for individual states
366  // should be prefixed with "<getTemplate().name()>.".
367  static UT_Options &getGlobalPrefs();
368 
369  // returns true if this instance is executing code in a 'busy' mode
370  bool isBusyProcessing() const
371  {
372  return myBusyCounter > 0;
373  }
374 
375  // Drag and drop support
376  virtual int testDragDrop(DD_Source &)
377  {
378  return 0;
379  }
381  {
382  }
383  virtual int acceptDragDrop(DD_Source &, const char * /*label*/)
384  {
385  return 0;
386  }
387 
388 protected:
389  friend class Busy;
390 
391  // The state might contain some geometry it wants to display, but may not
392  // want it to be part of the main gdp. This method allows the state to
393  // "sneak in" this special geometry that it might have (eg. a rubber band
394  // when building curves). This method is called by DM_State::render().
395  virtual void doRender(RE_Render *r, int x, int y, int ghost);
396 
397  // Similar to doRender() but called on a saved (interrupted) state for
398  // states which may want to handle it.
399  virtual void doRenderSaved(RE_Render *r, int x, int y, int ghost);
400 
401  // Make this a state that changes data or not (0 by default):
402  void setModifier(int yn) { myFlags.modifier = yn; }
403 
404  // Find out whether the general entry conditions for overlay states
405  // are met (before you test for your specific key conditions).
406  // The basic conditions are that:
407  // - the event type is key up/down
408  // - no mouse button is down
409  // - we're not the current state
410  // - the current state is not and overlay itself
411  int meetsBasicEntryConditions(const UI_Event &e) const;
412 
413  // Set the build flag, ie. whether we're actually building something now
414  // or making changes to geometry that is linked to this state.
415  virtual void setBuild(int onOff);
416 
417  void handleMouseEventVoidRet(UI_Event *event);
418 
419  // Call doRenderSaved on saved states recursively in case they want to
420  // handle it.
421  void renderSaved(RE_Render *r, int x, int y, int ghost);
422 
423  // This class is intended for classes deriving from BM_State to execute
424  // their code in a 'busy' mode. While the code executes, calling
425  // BM_State::isBusyProcessing() will return true. The 'busy' mode gets reset
426  // when the derived class method using Busy goes out of scope.
427  struct Busy
428  {
429  Busy() = delete;
430 
431  Busy( BM_State & state ) : myState(state)
432  {
433  myState.myBusyCounter++;
434  }
435 
437  {
438  if (myState.myBusyCounter > 0)
439  {
440  myState.myBusyCounter--;
441  }
442  }
443 
445  };
446 
447  BM_StateFlags myFlags; // useful flags
448 
451 
452 private:
453  PI_StateTemplate &myTemplate;
454 
455  UT_Array<int> myVolatileKeys;// the key used for entry condition
456  int myIndex; // index in the list of states
457 
458  bool myCursorPushed;
459  int myBusyCounter;
460 };
461 
462 #endif
GLdouble s
Definition: glew.h:1390
virtual void stopGenerating()
Definition: BM_State.h:174
virtual bool ignoreDisplayFlagChange() const
Definition: BM_State.h:251
GLuint const GLchar * name
Definition: glew.h:1814
virtual void status(UT_String &s) const
Definition: BM_State.h:77
static UI_Event theDelayedSelectionEvent
Definition: BM_State.h:450
int isPreempted() const
Definition: BM_State.h:220
virtual bool getShowSelectedOp() const
Definition: BM_State.h:349
int isGenerating() const
Definition: BM_State.h:225
const char * className() const override
void index(int idx)
Definition: BM_State.h:279
BM_RMBMenuPopupMode
Definition: BM_State.h:269
PI_StateTemplate & getTemplate()
Definition: BM_State.h:285
virtual int testDragDrop(DD_Source &)
Definition: BM_State.h:376
int isRegenerating() const
Definition: BM_State.h:230
void setModifier(int yn)
Definition: BM_State.h:402
virtual void resume(BM_SimpleState *=0)
virtual bool useVolatileSelection() const
Definition: BM_State.h:363
virtual const char * getOperationBarIconName() const
static bool theDelayedSelectionEventIsValid
Definition: BM_State.h:449
bool isBusyProcessing() const
Definition: BM_State.h:370
virtual int enter(BM_EntryType how=BM_SimpleState::BM_OVERLAY_ENTRY)=0
int isEntered() const
Definition: BM_State.h:222
virtual const char * replaceCursor(const char *newcursor)
void wantsLocates(int yesNo)
Definition: BM_State.h:215
virtual const char * getOperationBarLabel() const
int isBuilding() const
Definition: BM_State.h:221
virtual UI_Feel * getCustomSelectModeSideBar() const
Definition: BM_State.h:357
GLint GLint GLint GLint GLint x
Definition: glew.h:1252
BM_GenerateMode
Definition: BM_State.h:60
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1252
bool isOverlay() const override
Definition: BM_State.h:233
virtual void resetStateForNew()
Definition: BM_State.h:353
virtual bool useSecureSelection() const
Definition: BM_State.h:360
int index() const
Definition: BM_State.h:278
bool isConcealed() const
Definition: BM_State.h:223
void harden()
Take shallow copy and make it deep.
Definition: UT_String.h:213
virtual void interrupt(BM_SimpleState *=0)
void startGenerating(BM_State::BM_GenerateMode how=BM_State::BM_INLINE, bool requestnew=false)
Definition: BM_State.h:167
virtual bool wantFailedOrienterEvent() const
Definition: BM_State.h:346
Busy(BM_State &state)
Definition: BM_State.h:431
#define BM_API
Definition: BM_API.h:10
BM_State & myState
Definition: BM_State.h:444
bool isRequestingNew() const
Definition: BM_State.h:228
A map of string to various well defined value types.
Definition: UT_Options.h:84
cl_event event
Definition: glew.h:3695
UI_Keyboard
Definition: UI_Keyboard.h:6
int isGeneratingInline() const
Definition: BM_State.h:226
const PI_StateTemplate & getTemplate() const
Definition: BM_State.h:284
virtual void exit()=0
BM_StateFlags myFlags
Definition: BM_State.h:447
int isModifier() const override
Definition: BM_State.h:243
virtual bool getAllowIndirectHandleDrag() const
Definition: BM_State.h:264
virtual int handleMouseEvent(UI_Event *event)=0
virtual bool handleTransitoryKey(const UI_Event &)
Definition: BM_State.h:198
virtual void getDragDropChoice(DD_Source &, DD_ChoiceList &)
Definition: BM_State.h:380
virtual bool isOverlay() const
virtual int acceptDragDrop(DD_Source &, const char *)
Definition: BM_State.h:383
GLdouble GLdouble GLdouble r
Definition: glew.h:1406
int isHandle() const override
Definition: BM_State.h:84
virtual const char * getHotkeyString() const
void(UI_Object::* UI_EventMethod)(UI_Event *)
Definition: UI_Object.h:35
virtual void render(RE_Render *r, int x, int y)
constexpr T pi()
Pi constant taken from Boost to match old behaviour.
Definition: Math.h:108
virtual bool showPersistent() const
Definition: BM_State.h:341
virtual void renderStatusExtras(RE_Render *)
Definition: BM_State.h:82
virtual void handleVolatileChanges()
Definition: BM_State.h:119
virtual bool canSwitchToOpDependent() const
Definition: BM_State.h:306
int isFullTime() const
Definition: BM_State.h:238
virtual bool doesHandleLocates() const
Definition: BM_State.h:217
int isSticky() const
Definition: BM_State.h:260
virtual int hasLocates() const
Definition: BM_State.h:216