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