00001 // Filename: pgItem.I 00002 // Created by: drose (13Mar02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 00016 //////////////////////////////////////////////////////////////////// 00017 // Function: PGItem::set_name 00018 // Access: Public 00019 // Description: 00020 //////////////////////////////////////////////////////////////////// 00021 INLINE void PGItem:: 00022 set_name(const string &name) { 00023 Namable::set_name(name); 00024 _lock.set_name(name); 00025 } 00026 00027 //////////////////////////////////////////////////////////////////// 00028 // Function: PGItem::get_region 00029 // Access: Public 00030 // Description: Returns the MouseWatcherRegion associated with this 00031 // item. Every PGItem has a MouseWatcherRegion 00032 // associated with it, that is created when the PGItem 00033 // is created; it does not change during the lifetime of 00034 // the PGItem. Even items that do not have a frame have 00035 // an associated MouseWatcherRegion, although it will 00036 // not be used in this case. 00037 //////////////////////////////////////////////////////////////////// 00038 INLINE PGMouseWatcherRegion *PGItem:: 00039 get_region() const { 00040 LightReMutexHolder holder(_lock); 00041 return _region; 00042 } 00043 00044 //////////////////////////////////////////////////////////////////// 00045 // Function: PGItem::set_notify 00046 // Access: Published 00047 // Description: Sets the object which will be notified when the 00048 // PGItem changes. Set this to NULL to disable 00049 // this effect. The PGItem does not retain 00050 // ownership of the pointer; it is your responsibility 00051 // to ensure that the notify object does not destruct. 00052 //////////////////////////////////////////////////////////////////// 00053 INLINE void PGItem:: 00054 set_notify(PGItemNotify *notify) { 00055 LightReMutexHolder holder(_lock); 00056 if (_notify != (PGItemNotify *)NULL) { 00057 _notify->remove_item(this); 00058 } 00059 _notify = notify; 00060 if (_notify != (PGItemNotify *)NULL) { 00061 _notify->add_item(this); 00062 } 00063 } 00064 00065 //////////////////////////////////////////////////////////////////// 00066 // Function: PGItem::has_notify 00067 // Access: Published 00068 // Description: Returns true if there is an object configured to be 00069 // notified when the PGItem changes, false otherwise. 00070 //////////////////////////////////////////////////////////////////// 00071 INLINE bool PGItem:: 00072 has_notify() const { 00073 LightReMutexHolder holder(_lock); 00074 return (_notify != (PGItemNotify *)NULL); 00075 } 00076 00077 //////////////////////////////////////////////////////////////////// 00078 // Function: PGItem::get_notify 00079 // Access: Published 00080 // Description: Returns the object which will be notified when the 00081 // PGItem changes, if any. Returns NULL if there 00082 // is no such object configured. 00083 //////////////////////////////////////////////////////////////////// 00084 INLINE PGItemNotify *PGItem:: 00085 get_notify() const { 00086 LightReMutexHolder holder(_lock); 00087 return _notify; 00088 } 00089 00090 //////////////////////////////////////////////////////////////////// 00091 // Function: PGItem::set_frame 00092 // Access: Published 00093 // Description: Sets the bounding rectangle of the item, in local 00094 // coordinates. This is the region on screen within 00095 // which the mouse will be considered to be within the 00096 // item. Normally, it should correspond to the bounding 00097 // rectangle of the visible geometry of the item. 00098 //////////////////////////////////////////////////////////////////// 00099 INLINE void PGItem:: 00100 set_frame(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top) { 00101 set_frame(LVecBase4(left, right, bottom, top)); 00102 } 00103 00104 //////////////////////////////////////////////////////////////////// 00105 // Function: PGItem::set_frame 00106 // Access: Published 00107 // Description: Sets the bounding rectangle of the item, in local 00108 // coordinates. This is the region on screen within 00109 // which the mouse will be considered to be within the 00110 // item. Normally, it should correspond to the bounding 00111 // rectangle of the visible geometry of the item. 00112 //////////////////////////////////////////////////////////////////// 00113 INLINE void PGItem:: 00114 set_frame(const LVecBase4 &frame) { 00115 LightReMutexHolder holder(_lock); 00116 if (!_has_frame || _frame != frame) { 00117 _has_frame = true; 00118 _frame = frame; 00119 frame_changed(); 00120 } 00121 } 00122 00123 //////////////////////////////////////////////////////////////////// 00124 // Function: PGItem::get_frame 00125 // Access: Published 00126 // Description: Returns the bounding rectangle of the item. See 00127 // set_frame(). It is an error to call this if 00128 // has_frame() returns false. 00129 //////////////////////////////////////////////////////////////////// 00130 INLINE const LVecBase4 &PGItem:: 00131 get_frame() const { 00132 LightReMutexHolder holder(_lock); 00133 nassertr(has_frame(), _frame); 00134 return _frame; 00135 } 00136 00137 //////////////////////////////////////////////////////////////////// 00138 // Function: PGItem::has_frame 00139 // Access: Published 00140 // Description: Returns true if the item has a bounding rectangle; 00141 // see set_frame(). 00142 //////////////////////////////////////////////////////////////////// 00143 INLINE bool PGItem:: 00144 has_frame() const { 00145 LightReMutexHolder holder(_lock); 00146 return _has_frame; 00147 } 00148 00149 //////////////////////////////////////////////////////////////////// 00150 // Function: PGItem::clear_frame 00151 // Access: Published 00152 // Description: Removes the bounding rectangle from the item. It 00153 // will no longer be possible to position the mouse 00154 // within the item; see set_frame(). 00155 //////////////////////////////////////////////////////////////////// 00156 INLINE void PGItem:: 00157 clear_frame() { 00158 LightReMutexHolder holder(_lock); 00159 if (_has_frame) { 00160 _has_frame = false; 00161 frame_changed(); 00162 } 00163 } 00164 00165 //////////////////////////////////////////////////////////////////// 00166 // Function: PGItem::set_state 00167 // Access: Published 00168 // Description: Sets the "state" of this particular PGItem. 00169 // 00170 // The PGItem node will render as if it were the 00171 // subgraph assigned to the corresponding index via 00172 // set_state_def(). 00173 //////////////////////////////////////////////////////////////////// 00174 INLINE void PGItem:: 00175 set_state(int state) { 00176 LightReMutexHolder holder(_lock); 00177 _state = state; 00178 } 00179 00180 //////////////////////////////////////////////////////////////////// 00181 // Function: PGItem::get_state 00182 // Access: Published 00183 // Description: Returns the "state" of this particular PGItem. See 00184 // set_state(). 00185 //////////////////////////////////////////////////////////////////// 00186 INLINE int PGItem:: 00187 get_state() const { 00188 LightReMutexHolder holder(_lock); 00189 return _state; 00190 } 00191 00192 //////////////////////////////////////////////////////////////////// 00193 // Function: PGItem::get_active 00194 // Access: Published 00195 // Description: Returns whether the PGItem is currently active for 00196 // mouse events. See set_active(). 00197 //////////////////////////////////////////////////////////////////// 00198 INLINE bool PGItem:: 00199 get_active() const { 00200 LightReMutexHolder holder(_lock); 00201 return (_flags & F_active) != 0; 00202 } 00203 00204 //////////////////////////////////////////////////////////////////// 00205 // Function: PGItem::get_focus 00206 // Access: Published 00207 // Description: Returns whether the PGItem currently has focus for 00208 // keyboard events. See set_focus(). 00209 //////////////////////////////////////////////////////////////////// 00210 INLINE bool PGItem:: 00211 get_focus() const { 00212 LightReMutexHolder holder(_lock); 00213 return (_flags & F_focus) != 0; 00214 } 00215 00216 //////////////////////////////////////////////////////////////////// 00217 // Function: PGItem::get_background_focus 00218 // Access: Published 00219 // Description: Returns whether background_focus is currently 00220 // enabled. See set_background_focus(). 00221 //////////////////////////////////////////////////////////////////// 00222 INLINE bool PGItem:: 00223 get_background_focus() const { 00224 LightReMutexHolder holder(_lock); 00225 return (_flags & F_background_focus) != 0; 00226 } 00227 00228 //////////////////////////////////////////////////////////////////// 00229 // Function: PGItem::set_suppress_flags 00230 // Access: Published 00231 // Description: This is just an interface to set the suppress flags 00232 // on the underlying MouseWatcherRegion. See 00233 // MouseWatcherRegion::set_suppress_flags(). 00234 //////////////////////////////////////////////////////////////////// 00235 INLINE void PGItem:: 00236 set_suppress_flags(int suppress_flags) { 00237 LightReMutexHolder holder(_lock); 00238 _region->set_suppress_flags(suppress_flags); 00239 } 00240 00241 //////////////////////////////////////////////////////////////////// 00242 // Function: PGItem::get_suppress_flags 00243 // Access: Published 00244 // Description: This is just an interface to get the suppress flags 00245 // on the underlying MouseWatcherRegion. See 00246 // MouseWatcherRegion::get_suppress_flags(). 00247 //////////////////////////////////////////////////////////////////// 00248 INLINE int PGItem:: 00249 get_suppress_flags() const { 00250 LightReMutexHolder holder(_lock); 00251 return _region->get_suppress_flags(); 00252 } 00253 00254 //////////////////////////////////////////////////////////////////// 00255 // Function: PGItem::get_id 00256 // Access: Published 00257 // Description: Returns the unique ID assigned to this PGItem. This 00258 // will be assigned to the region created with the 00259 // MouseWatcher, and will thus be used to generate event 00260 // names. 00261 //////////////////////////////////////////////////////////////////// 00262 INLINE const string &PGItem:: 00263 get_id() const { 00264 LightReMutexHolder holder(_lock); 00265 return _region->get_name(); 00266 } 00267 00268 //////////////////////////////////////////////////////////////////// 00269 // Function: PGItem::set_id 00270 // Access: Published 00271 // Description: Set the unique ID assigned to this PGItem. It is the 00272 // user's responsibility to ensure that this ID is 00273 // unique. 00274 // 00275 // Normally, this should not need to be called, as the 00276 // PGItem will assign itself an ID when it is created, 00277 // but this function allows the user to decide to 00278 // redefine the ID to be something possibly more 00279 // meaningful. 00280 //////////////////////////////////////////////////////////////////// 00281 INLINE void PGItem:: 00282 set_id(const string &id) { 00283 LightReMutexHolder holder(_lock); 00284 _region->set_name(id); 00285 } 00286 00287 //////////////////////////////////////////////////////////////////// 00288 // Function: PGItem::get_enter_prefix 00289 // Access: Published, Static 00290 // Description: Returns the prefix that is used to define the enter 00291 // event for all PGItems. The enter event is the 00292 // concatenation of this string followed by get_id(). 00293 //////////////////////////////////////////////////////////////////// 00294 INLINE string PGItem:: 00295 get_enter_prefix() { 00296 return "enter-"; 00297 } 00298 00299 //////////////////////////////////////////////////////////////////// 00300 // Function: PGItem::get_exit_prefix 00301 // Access: Published, Static 00302 // Description: Returns the prefix that is used to define the exit 00303 // event for all PGItems. The exit event is the 00304 // concatenation of this string followed by get_id(). 00305 //////////////////////////////////////////////////////////////////// 00306 INLINE string PGItem:: 00307 get_exit_prefix() { 00308 return "exit-"; 00309 } 00310 00311 //////////////////////////////////////////////////////////////////// 00312 // Function: PGItem::get_within_prefix 00313 // Access: Published, Static 00314 // Description: Returns the prefix that is used to define the within 00315 // event for all PGItems. The within event is the 00316 // concatenation of this string followed by get_id(). 00317 //////////////////////////////////////////////////////////////////// 00318 INLINE string PGItem:: 00319 get_within_prefix() { 00320 return "within-"; 00321 } 00322 00323 //////////////////////////////////////////////////////////////////// 00324 // Function: PGItem::get_without_prefix 00325 // Access: Published, Static 00326 // Description: Returns the prefix that is used to define the without 00327 // event for all PGItems. The without event is the 00328 // concatenation of this string followed by get_id(). 00329 //////////////////////////////////////////////////////////////////// 00330 INLINE string PGItem:: 00331 get_without_prefix() { 00332 return "without-"; 00333 } 00334 00335 //////////////////////////////////////////////////////////////////// 00336 // Function: PGItem::get_focus_in_prefix 00337 // Access: Published, Static 00338 // Description: Returns the prefix that is used to define the focus_in 00339 // event for all PGItems. The focus_in event is the 00340 // concatenation of this string followed by get_id(). 00341 // 00342 // Unlike most item events, this event is thrown with no 00343 // parameters. 00344 //////////////////////////////////////////////////////////////////// 00345 INLINE string PGItem:: 00346 get_focus_in_prefix() { 00347 return "fin-"; 00348 } 00349 00350 //////////////////////////////////////////////////////////////////// 00351 // Function: PGItem::get_focus_out_prefix 00352 // Access: Published, Static 00353 // Description: Returns the prefix that is used to define the focus_out 00354 // event for all PGItems. The focus_out event is the 00355 // concatenation of this string followed by get_id(). 00356 // 00357 // Unlike most item events, this event is thrown with no 00358 // parameters. 00359 //////////////////////////////////////////////////////////////////// 00360 INLINE string PGItem:: 00361 get_focus_out_prefix() { 00362 return "fout-"; 00363 } 00364 00365 //////////////////////////////////////////////////////////////////// 00366 // Function: PGItem::get_press_prefix 00367 // Access: Published, Static 00368 // Description: Returns the prefix that is used to define the press 00369 // event for all PGItems. The press event is the 00370 // concatenation of this string followed by a button 00371 // name, followed by a hyphen and get_id(). 00372 //////////////////////////////////////////////////////////////////// 00373 INLINE string PGItem:: 00374 get_press_prefix() { 00375 return "press-"; 00376 } 00377 00378 //////////////////////////////////////////////////////////////////// 00379 // Function: PGItem::get_repeat_prefix 00380 // Access: Published, Static 00381 // Description: Returns the prefix that is used to define the repeat 00382 // event for all PGItems. The repeat event is the 00383 // concatenation of this string followed by a button 00384 // name, followed by a hyphen and get_id(). 00385 //////////////////////////////////////////////////////////////////// 00386 INLINE string PGItem:: 00387 get_repeat_prefix() { 00388 return "repeat-"; 00389 } 00390 00391 //////////////////////////////////////////////////////////////////// 00392 // Function: PGItem::get_release_prefix 00393 // Access: Published, Static 00394 // Description: Returns the prefix that is used to define the release 00395 // event for all PGItems. The release event is the 00396 // concatenation of this string followed by a button 00397 // name, followed by a hyphen and get_id(). 00398 //////////////////////////////////////////////////////////////////// 00399 INLINE string PGItem:: 00400 get_release_prefix() { 00401 return "release-"; 00402 } 00403 00404 //////////////////////////////////////////////////////////////////// 00405 // Function: PGItem::get_keystroke_prefix 00406 // Access: Published, Static 00407 // Description: Returns the prefix that is used to define the 00408 // keystroke event for all PGItems. The keystroke event 00409 // is the concatenation of this string followed by a 00410 // hyphen and get_id(). 00411 //////////////////////////////////////////////////////////////////// 00412 INLINE string PGItem:: 00413 get_keystroke_prefix() { 00414 return "keystroke-"; 00415 } 00416 00417 //////////////////////////////////////////////////////////////////// 00418 // Function: PGItem::get_enter_event 00419 // Access: Published 00420 // Description: Returns the event name that will be thrown when the 00421 // item is active and the mouse enters its frame, but 00422 // not any nested frames. 00423 //////////////////////////////////////////////////////////////////// 00424 INLINE string PGItem:: 00425 get_enter_event() const { 00426 LightReMutexHolder holder(_lock); 00427 return get_enter_prefix() + get_id(); 00428 } 00429 00430 //////////////////////////////////////////////////////////////////// 00431 // Function: PGItem::get_exit_event 00432 // Access: Published 00433 // Description: Returns the event name that will be thrown when the 00434 // item is active and the mouse exits its frame, or 00435 // enters a nested frame. 00436 //////////////////////////////////////////////////////////////////// 00437 INLINE string PGItem:: 00438 get_exit_event() const { 00439 LightReMutexHolder holder(_lock); 00440 return get_exit_prefix() + get_id(); 00441 } 00442 00443 //////////////////////////////////////////////////////////////////// 00444 // Function: PGItem::get_within_event 00445 // Access: Published 00446 // Description: Returns the event name that will be thrown when the 00447 // item is active and the mouse moves within the 00448 // boundaries of the frame. This is different from the 00449 // enter_event in that the mouse is considered within 00450 // the frame even if it is also within a nested frame. 00451 //////////////////////////////////////////////////////////////////// 00452 INLINE string PGItem:: 00453 get_within_event() const { 00454 LightReMutexHolder holder(_lock); 00455 return get_within_prefix() + get_id(); 00456 } 00457 00458 //////////////////////////////////////////////////////////////////// 00459 // Function: PGItem::get_without_event 00460 // Access: Published 00461 // Description: Returns the event name that will be thrown when the 00462 // item is active and the mouse moves completely outside 00463 // the boundaries of the frame. This is different from 00464 // the exit_event in that the mouse is considered 00465 // within the frame even if it is also within a nested 00466 // frame. 00467 //////////////////////////////////////////////////////////////////// 00468 INLINE string PGItem:: 00469 get_without_event() const { 00470 LightReMutexHolder holder(_lock); 00471 return get_without_prefix() + get_id(); 00472 } 00473 00474 //////////////////////////////////////////////////////////////////// 00475 // Function: PGItem::get_focus_in_event 00476 // Access: Published 00477 // Description: Returns the event name that will be thrown when the 00478 // item gets the keyboard focus. 00479 //////////////////////////////////////////////////////////////////// 00480 INLINE string PGItem:: 00481 get_focus_in_event() const { 00482 LightReMutexHolder holder(_lock); 00483 return get_focus_in_prefix() + get_id(); 00484 } 00485 00486 //////////////////////////////////////////////////////////////////// 00487 // Function: PGItem::get_focus_out_event 00488 // Access: Published 00489 // Description: Returns the event name that will be thrown when the 00490 // item loses the keyboard focus. 00491 //////////////////////////////////////////////////////////////////// 00492 INLINE string PGItem:: 00493 get_focus_out_event() const { 00494 LightReMutexHolder holder(_lock); 00495 return get_focus_out_prefix() + get_id(); 00496 } 00497 00498 //////////////////////////////////////////////////////////////////// 00499 // Function: PGItem::get_press_event 00500 // Access: Published 00501 // Description: Returns the event name that will be thrown when the 00502 // item is active and the indicated mouse or keyboard 00503 // button is depressed while the mouse is within the 00504 // frame. 00505 //////////////////////////////////////////////////////////////////// 00506 INLINE string PGItem:: 00507 get_press_event(const ButtonHandle &button) const { 00508 LightReMutexHolder holder(_lock); 00509 return get_press_prefix() + button.get_name() + "-" + get_id(); 00510 } 00511 00512 //////////////////////////////////////////////////////////////////// 00513 // Function: PGItem::get_repeat_event 00514 // Access: Published 00515 // Description: Returns the event name that will be thrown when the 00516 // item is active and the indicated mouse or keyboard 00517 // button is continuously held down while the mouse is 00518 // within the frame. 00519 //////////////////////////////////////////////////////////////////// 00520 INLINE string PGItem:: 00521 get_repeat_event(const ButtonHandle &button) const { 00522 LightReMutexHolder holder(_lock); 00523 return get_repeat_prefix() + button.get_name() + "-" + get_id(); 00524 } 00525 00526 //////////////////////////////////////////////////////////////////// 00527 // Function: PGItem::get_release_event 00528 // Access: Published 00529 // Description: Returns the event name that will be thrown when the 00530 // item is active and the indicated mouse or keyboard 00531 // button, formerly clicked down is within the frame, is 00532 // released. 00533 //////////////////////////////////////////////////////////////////// 00534 INLINE string PGItem:: 00535 get_release_event(const ButtonHandle &button) const { 00536 LightReMutexHolder holder(_lock); 00537 return get_release_prefix() + button.get_name() + "-" + get_id(); 00538 } 00539 00540 //////////////////////////////////////////////////////////////////// 00541 // Function: PGItem::get_keystroke_event 00542 // Access: Published 00543 // Description: Returns the event name that will be thrown when the 00544 // item is active and any key is pressed by the user. 00545 //////////////////////////////////////////////////////////////////// 00546 INLINE string PGItem:: 00547 get_keystroke_event() const { 00548 LightReMutexHolder holder(_lock); 00549 return get_keystroke_prefix() + get_id(); 00550 } 00551 00552 //////////////////////////////////////////////////////////////////// 00553 // Function: PGItem::set_text_node 00554 // Access: Published, Static 00555 // Description: Changes the TextNode object that will be used by all 00556 // PGItems to generate default labels given a string. 00557 // This can be loaded with the default font, etc. 00558 //////////////////////////////////////////////////////////////////// 00559 INLINE void PGItem:: 00560 set_text_node(TextNode *node) { 00561 _text_node = node; 00562 } 00563 00564 //////////////////////////////////////////////////////////////////// 00565 // Function: PGItem::get_focus_item 00566 // Access: Published, Static 00567 // Description: Returns the one PGItem in the world that currently 00568 // has keyboard focus, if any, or NULL if no item has 00569 // keyboard focus. Use PGItem::set_focus() to activate 00570 // or deactivate keyboard focus on a particular item. 00571 //////////////////////////////////////////////////////////////////// 00572 INLINE PGItem *PGItem:: 00573 get_focus_item() { 00574 return _focus_item; 00575 } 00576 00577 //////////////////////////////////////////////////////////////////// 00578 // Function: PGItem::get_frame_inv_xform 00579 // Access: Published, Static 00580 // Description: Returns the inverse of the frame transform matrix 00581 //////////////////////////////////////////////////////////////////// 00582 INLINE LMatrix4 PGItem:: 00583 get_frame_inv_xform() const { 00584 LightReMutexHolder holder(_lock); 00585 return _frame_inv_xform; 00586 } 00587 00588 //////////////////////////////////////////////////////////////////// 00589 // Function: PGItem::compute_area 00590 // Access: Private, Static 00591 // Description: Computes the area of the indicated frame. 00592 //////////////////////////////////////////////////////////////////// 00593 INLINE PN_stdfloat PGItem:: 00594 compute_area(const LVecBase4 &frame) { 00595 return (frame[1] - frame[0]) * (frame[3] - frame[2]); 00596 } 00597 00598 //////////////////////////////////////////////////////////////////// 00599 // Function: PGItem::compare_largest 00600 // Access: Private, Static 00601 // Description: Given that largest is the pointer to the largest 00602 // frame so far, and largest_area is its area, compare 00603 // that to the area of the new frame; if the new frame 00604 // is larger, adjust largest and largest_area 00605 // appropriately. 00606 //////////////////////////////////////////////////////////////////// 00607 INLINE void PGItem:: 00608 compare_largest(const LVecBase4 *&largest, PN_stdfloat &largest_area, 00609 const LVecBase4 *new_frame) { 00610 PN_stdfloat new_area = compute_area(*new_frame); 00611 if (new_area > largest_area) { 00612 largest = new_frame; 00613 largest_area = new_area; 00614 } 00615 } 00616 00617 //////////////////////////////////////////////////////////////////// 00618 // Function: PGItem::StateDef::Constructor 00619 // Access: Public 00620 // Description: 00621 //////////////////////////////////////////////////////////////////// 00622 INLINE PGItem::StateDef:: 00623 StateDef() : 00624 _frame_stale(true) 00625 { 00626 }