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