Panda3D
pgSliderBar.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file pgSliderBar.cxx
10  * @author masad
11  * @date 2004-10-19
12  */
13 
14 #include "pgSliderBar.h"
16 #include "clockObject.h"
17 #include "throw_event.h"
18 #include "config_pgui.h"
19 #include "throw_event.h"
20 #include "transformState.h"
21 #include "mouseButton.h"
22 
23 using std::max;
24 using std::min;
25 
26 TypeHandle PGSliderBar::_type_handle;
27 
28 /**
29  *
30  */
31 PGSliderBar::
32 PGSliderBar(const std::string &name)
33  : PGItem(name)
34 {
35  set_cull_callback();
36 
37  _min_value = 0.0f;
38  _max_value = 1.0f;
39  set_scroll_size(0.01f);
40  set_page_size(0.1f);
41  _ratio = 0.0f;
42  _resize_thumb = false;
43  _manage_pieces = false;
44  _axis.set(1.0f, 0.0f, 0.0f);
45  _needs_remanage = false;
46  _needs_recompute = true;
47  _needs_reposition = false;
48  _scroll_button_held = nullptr;
49  _mouse_button_page = false;
50  _dragging = false;
51  _thumb_width = 0.1f;
52 
53  set_active(true);
54 }
55 
56 /**
57  *
58  */
59 PGSliderBar::
60 ~PGSliderBar() {
61 }
62 
63 /**
64  *
65  */
66 PGSliderBar::
67 PGSliderBar(const PGSliderBar &copy) :
68  PGItem(copy),
69  _min_value(copy._min_value),
70  _max_value(copy._max_value),
71  _scroll_value(copy._scroll_value),
72  _scroll_ratio(copy._scroll_ratio),
73  _page_value(copy._page_value),
74  _page_ratio(copy._page_ratio),
75  _ratio(copy._ratio),
76  _resize_thumb(copy._resize_thumb),
77  _manage_pieces(copy._manage_pieces),
78  _axis(copy._axis)
79 {
80  _needs_remanage = false;
81  _needs_recompute = true;
82  _scroll_button_held = nullptr;
83  _mouse_button_page = false;
84  _dragging = false;
85 }
86 
87 /**
88  * Returns a newly-allocated Node that is a shallow copy of this one. It will
89  * be a different Node pointer, but its internal data may or may not be shared
90  * with that of the original Node.
91  */
93 make_copy() const {
94  LightReMutexHolder holder(_lock);
95  return new PGSliderBar(*this);
96 }
97 
98 /**
99  * This is a callback hook function, called whenever a mouse or keyboard
100  * button is depressed while the mouse is within the region.
101  */
102 void PGSliderBar::
103 press(const MouseWatcherParameter &param, bool background) {
104  LightReMutexHolder holder(_lock);
105  if (param.has_mouse()) {
106  _mouse_pos = param.get_mouse();
107  }
108  if (get_active() && param.get_button() == MouseButton::one()) {
109  if (_needs_recompute) {
110  recompute();
111  }
112 
113  if (_range_x != 0.0f) {
114  _mouse_button_page = true;
115  _scroll_button_held = nullptr;
116  advance_page();
117  _next_advance_time =
118  ClockObject::get_global_clock()->get_frame_time() + scroll_initial_delay;
119  }
120  }
121  PGItem::press(param, background);
122 }
123 
124 /**
125  * This is a callback hook function, called whenever a mouse or keyboard
126  * button previously depressed with press() is released.
127  */
128 void PGSliderBar::
129 release(const MouseWatcherParameter &param, bool background) {
130  LightReMutexHolder holder(_lock);
132  _mouse_button_page = false;
133  }
134  if (_dragging) {
135  end_drag();
136  }
137  PGItem::release(param, background);
138 }
139 
140 /**
141  * This is a callback hook function, called whenever a mouse is moved while
142  * within the region.
143  */
144 void PGSliderBar::
146  LightReMutexHolder holder(_lock);
147  _mouse_pos = param.get_mouse();
148  if (_dragging) {
149  // We only get here if we the user originally clicked on the track, which
150  // caused the slider to move all the way to the mouse position, and then
151  // started dragging the mouse along the track. In this case, we start
152  // moving the thumb as if the user had started by dragging the thumb
153  // directly.
154  continue_drag();
155  }
156 }
157 
158 /**
159  * This function will be called during the cull traversal to perform any
160  * additional operations that should be performed at cull time. This may
161  * include additional manipulation of render state or additional
162  * visible/invisible decisions, or any other arbitrary operation.
163  *
164  * Note that this function will *not* be called unless set_cull_callback() is
165  * called in the constructor of the derived class. It is necessary to call
166  * set_cull_callback() to indicated that we require cull_callback() to be
167  * called.
168  *
169  * By the time this function is called, the node has already passed the
170  * bounding-volume test for the viewing frustum, and the node's transform and
171  * state have already been applied to the indicated CullTraverserData object.
172  *
173  * The return value is true if this node should be visible, or false if it
174  * should be culled.
175  */
176 bool PGSliderBar::
178  LightReMutexHolder holder(_lock);
179  if (_manage_pieces && _needs_remanage) {
180  remanage();
181  }
182  if (_needs_recompute) {
183  recompute();
184  }
185 
186  if (_scroll_button_held != nullptr &&
187  _next_advance_time <= ClockObject::get_global_clock()->get_frame_time()) {
188  advance_scroll();
189  }
190 
191  if (_mouse_button_page &&
192  _next_advance_time <= ClockObject::get_global_clock()->get_frame_time()) {
193  advance_page();
194  }
195 
196  if (_needs_reposition) {
197  reposition();
198  }
199 
200  return PGItem::cull_callback(trav, data);
201 }
202 
203 /**
204  * Transforms the contents of this node by the indicated matrix, if it means
205  * anything to do so. For most kinds of nodes, this does nothing.
206  */
207 void PGSliderBar::
208 xform(const LMatrix4 &mat) {
209  LightReMutexHolder holder(_lock);
210  PGItem::xform(mat);
211  _axis = _axis * mat;
212 
213  // Make sure we set the thumb to identity position first, so it won't be
214  // accidentally flattened.
215  if (_thumb_button != nullptr) {
216  _thumb_button->clear_transform();
217  }
218 
219  _needs_remanage = true;
220  _needs_recompute = true;
221 }
222 
223 /**
224  * This is a callback hook function, called whenever the slider value is
225  * adjusted by the user or programmatically.
226  */
227 void PGSliderBar::
229  LightReMutexHolder holder(_lock);
230  std::string event = get_adjust_event();
231  play_sound(event);
232  throw_event(event);
233 
234  if (has_notify()) {
235  get_notify()->slider_bar_adjust(this);
236  }
237 }
238 
239 /**
240  * Creates PGSliderBar that represents a vertical or horizontal scroll bar (if
241  * vertical is true or false, respectively), with additional buttons for
242  * scrolling, and a range of 0 .. 1.
243  *
244  * length here is the measurement along the scroll bar, and width is the
245  * measurement across the scroll bar, whether it is vertical or horizontal (so
246  * for a horizontal scroll bar, the length is actually the x dimension, and
247  * the width is the y dimension).
248  */
249 void PGSliderBar::
250 setup_scroll_bar(bool vertical, PN_stdfloat length, PN_stdfloat width, PN_stdfloat bevel) {
251  LightReMutexHolder holder(_lock);
252  set_state(0);
253  clear_state_def(0);
254 
255  if (vertical) {
256  set_frame(-width / 2.0f, width / 2.0f, -length / 2.0f, length / 2.0f);
257  _axis = LVector3::rfu(0.0f, 0.0f, -1.0f);
258  } else {
259  set_frame(-length / 2.0f, length / 2.0f, -width / 2.0f, width / 2.0f);
260  _axis = LVector3::rfu(1.0f, 0.0f, 0.0f);
261  }
262 
263  PGFrameStyle style;
264  style.set_color(0.6f, 0.6f, 0.6f, 1.0f);
265  style.set_type(PGFrameStyle::T_flat);
266  set_frame_style(0, style);
267 
268  style.set_color(0.8f, 0.8f, 0.8f, 1.0f);
269  style.set_type(PGFrameStyle::T_bevel_out);
270  style.set_width(bevel, bevel);
271 
272  // Remove the button nodes created by a previous call to setup(), if any.
273  if (_thumb_button != nullptr) {
274  remove_child(_thumb_button);
275  set_thumb_button(nullptr);
276  }
277  if (_left_button != nullptr) {
278  remove_child(_left_button);
279  set_left_button(nullptr);
280  }
281  if (_right_button != nullptr) {
282  remove_child(_right_button);
283  set_right_button(nullptr);
284  }
285 
286  PT(PGButton) thumb = new PGButton("thumb");
287  thumb->setup("", bevel);
288  thumb->set_frame(-width / 2.0f, width / 2.0f,
289  -width / 2.0f, width / 2.0f);
290  add_child(thumb);
291  set_thumb_button(thumb);
292 
293  PT(PGButton) left = new PGButton("left");
294  left->setup("", bevel);
295  left->set_frame(-width / 2.0f, width / 2.0f,
296  -width / 2.0f, width / 2.0f);
297  left->set_transform(TransformState::make_pos(((width - length) / 2.0f) * _axis));
298  add_child(left);
299  set_left_button(left);
300 
301  PT(PGButton) right = new PGButton("right");
302  right->setup("", bevel);
303  right->set_frame(-width / 2.0f, width / 2.0f,
304  -width / 2.0f, width / 2.0f);
305  right->set_transform(TransformState::make_pos(((length - width) / 2.0f) * _axis));
306  add_child(right);
307  set_right_button(right);
308 
309  set_resize_thumb(true);
310  set_manage_pieces(true);
311 }
312 
313 /**
314  * Creates PGSliderBar that represents a slider that the user can use to
315  * control an analog quantity.
316  *
317  * This is functionally the same as a scroll bar, but it has a distinctive
318  * look.
319  */
320 void PGSliderBar::
321 setup_slider(bool vertical, PN_stdfloat length, PN_stdfloat width, PN_stdfloat bevel) {
322  LightReMutexHolder holder(_lock);
323  set_state(0);
324  clear_state_def(0);
325 
326  if (vertical) {
327  set_frame(-width / 2.0f, width / 2.0f, -length / 2.0f, length / 2.0f);
328  _axis = LVector3::rfu(0.0f, 0.0f, -1.0f);
329  } else {
330  set_frame(-length / 2.0f, length / 2.0f, -width / 2.0f, width / 2.0f);
331  _axis = LVector3::rfu(1.0f, 0.0f, 0.0f);
332  }
333 
334  PGFrameStyle style;
335  style.set_color(0.6f, 0.6f, 0.6f, 1.0f);
336  style.set_type(PGFrameStyle::T_flat);
337  style.set_visible_scale(1.0f, 0.25f);
338  style.set_width(bevel, bevel);
339  set_frame_style(0, style);
340 
341  // Remove the button nodes created by a previous call to setup(), if any.
342  if (_thumb_button != nullptr) {
343  remove_child(_thumb_button);
344  set_thumb_button(nullptr);
345  }
346  if (_left_button != nullptr) {
347  remove_child(_left_button);
348  set_left_button(nullptr);
349  }
350  if (_right_button != nullptr) {
351  remove_child(_right_button);
352  set_right_button(nullptr);
353  }
354 
355  PT(PGButton) thumb = new PGButton("thumb");
356  thumb->setup(" ", bevel);
357  thumb->set_frame(-width / 4.0f, width / 4.0f,
358  -width / 2.0f, width / 2.0f);
359  add_child(thumb);
360  set_thumb_button(thumb);
361 
362  set_resize_thumb(false);
363  set_manage_pieces(true);
364 }
365 
366 /**
367  * Sets whether the PGItem is active for mouse watching. This is not
368  * necessarily related to the active/inactive appearance of the item, which is
369  * controlled by set_state(), but it does affect whether it responds to mouse
370  * events.
371  */
372 void PGSliderBar::
373 set_active(bool active) {
374  LightReMutexHolder holder(_lock);
375  PGItem::set_active(active);
376 
377  // This also implicitly sets the managed pieces.
378  if (_thumb_button != nullptr) {
379  _thumb_button->set_active(active);
380  }
381  if (_left_button != nullptr) {
382  _left_button->set_active(active);
383  }
384  if (_right_button != nullptr) {
385  _right_button->set_active(active);
386  }
387 }
388 
389 /**
390  * Manages the position and size of the scroll bars and the thumb. Normally
391  * this should not need to be called directly.
392  */
393 void PGSliderBar::
395  LightReMutexHolder holder(_lock);
396  _needs_remanage = false;
397 
398  const LVecBase4 &frame = get_frame();
399 
400  PN_stdfloat width, length;
401  if (fabs(_axis[0]) > fabs(_axis[1] + _axis[2])) {
402  // The slider is X-dominant.
403  width = frame[3] - frame[2];
404  length = frame[1] - frame[0];
405 
406  } else {
407  // The slider is Y-dominant.
408  width = frame[1] - frame[0];
409  length = frame[3] - frame[2];
410  }
411 
412  LVector3 center = LVector3::rfu((frame[0] + frame[1]) / 2.0f,
413  0.0f,
414  (frame[2] + frame[3]) / 2.0f);
415 
416  if (_left_button != nullptr) {
417  _left_button->set_frame(-width / 2.0f, width / 2.0f,
418  -width / 2.0f, width / 2.0f);
419  _left_button->set_transform(TransformState::make_pos(center + ((width - length) / 2.0f) * _axis));
420  }
421 
422  if (_right_button != nullptr) {
423  _right_button->set_frame(-width / 2.0f, width / 2.0f,
424  -width / 2.0f, width / 2.0f);
425  _right_button->set_transform(TransformState::make_pos(center + ((length - width) / 2.0f) * _axis));
426  }
427 
428  if (_thumb_button != nullptr) {
429  _thumb_button->set_frame(-width / 2.0f, width / 2.0f,
430  -width / 2.0f, width / 2.0f);
431  _thumb_button->set_transform(TransformState::make_pos(center));
432  }
433 
434  recompute();
435 }
436 
437 /**
438  * Recomputes the position and size of the thumb. Normally this should not
439  * need to be called directly.
440  */
441 void PGSliderBar::
443  LightReMutexHolder holder(_lock);
444  _needs_recompute = false;
445 
446  if (_min_value != _max_value) {
447  _scroll_ratio = fabs(_scroll_value / (_max_value - _min_value));
448  _page_ratio = fabs(_page_value / (_max_value - _min_value));
449 
450  } else {
451  _scroll_ratio = 0.0f;
452  _page_ratio = 0.0f;
453  }
454 
455  if (!has_frame()) {
456  _min_x = 0.0f;
457  _max_x = 0.0f;
458  _thumb_width = 0.0f;
459  _range_x = 0.0f;
460  _thumb_start.set(0.0f, 0.0f, 0.0f);
461 
462  } else {
463  LVecBase4 frame = get_frame();
464  reduce_region(frame, _left_button);
465  reduce_region(frame, _right_button);
466 
467  if (fabs(_axis[0]) > fabs(_axis[1] + _axis[2])) {
468  // The slider is X-dominant.
469 
470  _min_x = frame[0];
471  _max_x = frame[1];
472 
473  PN_stdfloat trough_width = _max_x - _min_x;
474 
475  if (_thumb_button == nullptr) {
476  _thumb_width = 0.0f;
477  _range_x = 0.0f;
478  _thumb_start.set(0.0f, 0.0f, 0.0f);
479 
480  } else {
481  const LVecBase4 &thumb_frame = _thumb_button->get_frame();
482 
483  if (_resize_thumb) {
484  // If we're allowed to adjust the thumb's size, we don't need to
485  // find out how wide it is.
486  _thumb_width = trough_width * min((PN_stdfloat)1.0, _page_ratio);
487  _thumb_button->set_frame(-_thumb_width / 2.0f, _thumb_width / 2.0f,
488  thumb_frame[2], thumb_frame[3]);
489  } else {
490  // If we're not adjusting the thumb's size, we do need to know its
491  // current width.
492  _thumb_width = thumb_frame[1] - thumb_frame[0];
493  }
494 
495  _range_x = trough_width - _thumb_width;
496 
497  if (_axis[0] >= 0.0f) {
498  // The slider runs forwards, left to right.
499  _thumb_start = (_min_x - thumb_frame[0]) * _axis;
500  } else {
501  // The slider runs backwards: right to left.
502  _thumb_start = (thumb_frame[1] - _max_x) * _axis;
503  }
504  _thumb_start += LVector3::rfu(0.0f, 0.0f, (frame[2] + frame[3]) / 2.0f);
505  }
506 
507  } else {
508  // The slider is Y-dominant. We call it X in the variable names, but
509  // it's really Y (or even Z).
510 
511  _min_x = frame[2];
512  _max_x = frame[3];
513 
514  PN_stdfloat trough_width = _max_x - _min_x;
515 
516  if (_thumb_button == nullptr) {
517  _thumb_width = 0.0f;
518  _range_x = 0.0f;
519  _thumb_start.set(0.0f, 0.0f, 0.0f);
520 
521  } else {
522  const LVecBase4 &thumb_frame = _thumb_button->get_frame();
523 
524  if (_resize_thumb) {
525  // If we're allowed to adjust the thumb's size, we don't need to
526  // find out how wide it is.
527  _thumb_width = trough_width * min((PN_stdfloat)1.0, _page_ratio);
528  _thumb_button->set_frame(thumb_frame[0], thumb_frame[1],
529  -_thumb_width / 2.0f, _thumb_width / 2.0f);
530  } else {
531  // If we're not adjusting the thumb's size, we do need to know its
532  // current width.
533  _thumb_width = thumb_frame[3] - thumb_frame[2];
534  }
535 
536  _range_x = trough_width - _thumb_width;
537 
538  if (_axis[1] >= 0.0f && _axis[2] >= 0.0f) {
539  // The slider runs forwards, bottom to top.
540  _thumb_start = (_min_x - thumb_frame[2]) * _axis;
541  } else {
542  // The slider runs backwards: top to bottom.
543  _thumb_start = (thumb_frame[3] - _max_x) * _axis;
544  }
545  _thumb_start += LVector3::rfu((frame[0] + frame[1]) / 2.0f, 0.0f, 0.0f);
546  }
547  }
548  }
549 
550  reposition();
551 }
552 
553 /**
554  * Called when the user changes the frame size.
555  */
556 void PGSliderBar::
557 frame_changed() {
558  LightReMutexHolder holder(_lock);
559  PGItem::frame_changed();
560  _needs_remanage = true;
561  _needs_recompute = true;
562 }
563 
564 /**
565  * Called whenever a watched PGItem's local transform has been changed.
566  */
567 void PGSliderBar::
568 item_transform_changed(PGItem *) {
569  LightReMutexHolder holder(_lock);
570  _needs_recompute = true;
571 }
572 
573 /**
574  * Called whenever a watched PGItem's frame has been changed.
575  */
576 void PGSliderBar::
577 item_frame_changed(PGItem *) {
578  LightReMutexHolder holder(_lock);
579  _needs_recompute = true;
580 }
581 
582 /**
583  * Called whenever a watched PGItem's draw_mask has been changed.
584  */
585 void PGSliderBar::
586 item_draw_mask_changed(PGItem *) {
587  LightReMutexHolder holder(_lock);
588  _needs_recompute = true;
589 }
590 
591 /**
592  * Called whenever the "press" event is triggered on a watched PGItem. See
593  * PGItem::press().
594  */
595 void PGSliderBar::
596 item_press(PGItem *item, const MouseWatcherParameter &param) {
597  LightReMutexHolder holder(_lock);
598  if (param.has_mouse()) {
599  _mouse_pos = param.get_mouse();
600  }
601  if (item == _left_button || item == _right_button) {
602  _scroll_button_held = item;
603  _mouse_button_page = false;
604  advance_scroll();
605  _next_advance_time =
606  ClockObject::get_global_clock()->get_frame_time() + scroll_initial_delay;
607 
608  } else if (item == _thumb_button) {
609  _scroll_button_held = nullptr;
610  begin_drag();
611  }
612 }
613 
614 /**
615  * Called whenever the "release" event is triggered on a watched PGItem. See
616  * PGItem::release().
617  */
618 void PGSliderBar::
619 item_release(PGItem *item, const MouseWatcherParameter &) {
620  LightReMutexHolder holder(_lock);
621  if (item == _scroll_button_held) {
622  _scroll_button_held = nullptr;
623 
624  } else if (item == _thumb_button) {
625  _scroll_button_held = nullptr;
626  if (_dragging) {
627  end_drag();
628  }
629  }
630 }
631 
632 /**
633  * Called whenever the "move" event is triggered on a watched PGItem. See
634  * PGItem::move().
635  */
636 void PGSliderBar::
637 item_move(PGItem *item, const MouseWatcherParameter &param) {
638  LightReMutexHolder holder(_lock);
639  _mouse_pos = param.get_mouse();
640  if (item == _thumb_button) {
641  if (_dragging) {
642  continue_drag();
643  }
644  }
645 }
646 
647 /**
648  * A lighter-weight version of recompute(), this just moves the thumb,
649  * assuming all other properties are unchanged.
650  */
651 void PGSliderBar::
652 reposition() {
653  _needs_reposition = false;
654 
655  PN_stdfloat t = get_ratio();
656 
657  if (_thumb_button != nullptr) {
658  LPoint3 pos = (t * _range_x) * _axis + _thumb_start;
659  CPT(TransformState) transform = TransformState::make_pos(pos);
660  CPT(TransformState) orig_transform = _thumb_button->get_transform();
661 
662  // It's important not to update the transform frivolously, or we'll get
663  // caught in an update loop.
664  if (transform == orig_transform) {
665  // No change.
666  } else if (*transform != *orig_transform) {
667  _thumb_button->set_transform(transform);
668  }
669  }
670 }
671 
672 /**
673  * Advances the scroll bar by one unit in the left or right direction while
674  * the user is holding down the left or right scroll button.
675  */
676 void PGSliderBar::
677 advance_scroll() {
678  if (_scroll_button_held == _left_button) {
679  internal_set_ratio(max(_ratio - _scroll_ratio, (PN_stdfloat)0.0));
680 
681  } else if (_scroll_button_held == _right_button) {
682  internal_set_ratio(min(_ratio + _scroll_ratio, (PN_stdfloat)1.0));
683  }
684 
685  _next_advance_time =
686  ClockObject::get_global_clock()->get_frame_time() + scroll_continued_delay;
687 }
688 
689 /**
690  * Advances the scroll bar by one page in the left or right direction while
691  * the user is holding down the mouse button on the track.
692  */
693 void PGSliderBar::
694 advance_page() {
695  // Is the mouse position left or right of the current thumb position?
696  LPoint3 mouse = mouse_to_local(_mouse_pos) - _thumb_start;
697  PN_stdfloat target_ratio = mouse.dot(_axis) / _range_x;
698 
699  PN_stdfloat t;
700  if (target_ratio < _ratio) {
701  t = max(_ratio - _page_ratio + _scroll_ratio, target_ratio);
702 
703  } else {
704  t = min(_ratio + _page_ratio - _scroll_ratio, target_ratio);
705  }
706  internal_set_ratio(t);
707  if (t == target_ratio) {
708  // We made it; begin dragging from now on until the user releases the
709  // mouse.
710  begin_drag();
711  }
712 
713  _next_advance_time =
714  ClockObject::get_global_clock()->get_frame_time() + scroll_continued_delay;
715 }
716 
717 /**
718  * Called when the user clicks down on the thumb button, possibly to begin
719  * dragging.
720  */
721 void PGSliderBar::
722 begin_drag() {
723  if (_needs_recompute) {
724  recompute();
725  }
726  if (_range_x != 0.0f) {
727  PN_stdfloat current_x = mouse_to_local(_mouse_pos).dot(_axis);
728  _drag_start_x = current_x - get_ratio() * _range_x;
729  _dragging = true;
730  }
731 }
732 
733 /**
734  * Called as the user moves the mouse while still dragging on the thumb
735  * button.
736  */
737 void PGSliderBar::
738 continue_drag() {
739  if (_needs_recompute) {
740  recompute();
741  }
742  if (_range_x != 0.0f) {
743  PN_stdfloat current_x = mouse_to_local(_mouse_pos).dot(_axis);
744  internal_set_ratio((current_x - _drag_start_x) / _range_x);
745  }
746 }
747 
748 /**
749  * Called as the user releases the mouse after dragging.
750  */
751 void PGSliderBar::
752 end_drag() {
753  _dragging = false;
754 }
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
Definition: clockObject.I:215
virtual void set_active(bool active)
Sets whether the PGItem is active for mouse watching.
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
void set_visible_scale(PN_stdfloat x, PN_stdfloat y)
Sets a scale factor on the visible representation of the frame, in the X and Y directions.
Definition: pgFrameStyle.I:197
void set_width(PN_stdfloat x, PN_stdfloat y)
Sets the width parameter, which has meaning only for certain frame types.
Definition: pgFrameStyle.I:139
void remove_child(int child_index, Thread *current_thread=Thread::get_current_thread())
Removes the nth child from the node.
Definition: pandaNode.cxx:570
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Indicates a coordinate-system transform on vertices.
bool has_mouse() const
Returns true if this parameter has an associated mouse position, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_resize_thumb(bool resize_thumb)
Sets the resize_thumb flag.
Definition: pgSliderBar.I:197
This is the base class for all the various kinds of gui widget objects.
Definition: pgItem.h:53
bool get_active() const
Returns whether the PGItem is currently active for mouse events.
Definition: pgItem.I:160
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this node by the indicated matrix, if it means anything to do so.
This is a particular kind of PGItem that is specialized to behave like a normal button object.
Definition: pgButton.h:29
void set_type(Type type)
Sets the basic type of frame.
Definition: pgFrameStyle.I:64
void set_frame(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top)
Sets the bounding rectangle of the item, in local coordinates.
Definition: pgItem.I:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This collects together the pieces of data that are accumulated for each node while walking the scene ...
static ButtonHandle one()
Returns the ButtonHandle associated with the first mouse button.
Definition: mouseButton.cxx:43
virtual void move(const MouseWatcherParameter &param)
This is a callback hook function, called whenever a mouse is moved while within the region.
virtual void press(const MouseWatcherParameter &param, bool background)
This is a callback hook function, called whenever a mouse or keyboard button is depressed while the m...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::string get_adjust_event() const
Returns the event name that will be thrown when the slider bar value is adjusted by the user or progr...
Definition: pgSliderBar.I:373
virtual void adjust()
This is a callback hook function, called whenever the slider value is adjusted by the user or program...
void remanage()
Manages the position and size of the scroll bars and the thumb.
bool has_notify() const
Returns true if there is an object configured to be notified when the PGItem changes,...
Definition: pgItem.I:59
void set_frame_style(int state, const PGFrameStyle &style)
Changes the kind of frame that will be drawn behind the item when it is in the indicated state.
Definition: pgItem.cxx:992
ButtonHandle get_button() const
Returns the mouse or keyboard button associated with this event.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
Definition: clockObject.h:91
virtual void release(const MouseWatcherParameter &param, bool background)
This is a callback hook function, called whenever a mouse or keyboard button previously depressed wit...
virtual void release(const MouseWatcherParameter &param, bool background)
This is a callback hook function, called whenever a mouse or keyboard button previously depressed wit...
Definition: pgItem.cxx:686
void set_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a)
Sets the dominant color of the frame.
Definition: pgFrameStyle.I:80
const LPoint2 & get_mouse() const
Returns the mouse position at the time the event was generated, in the normalized range (-1 .
Similar to MutexHolder, but for a light reentrant mutex.
PGSliderBarNotify * get_notify() const
Returns the object which will be notified when the PGSliderBar changes, if any.
Definition: pgSliderBar.I:30
void set_right_button(PGButton *right_button)
Sets the PGButton object that will serve as the right scroll button for this slider.
Definition: pgSliderBar.I:326
void setup_slider(bool vertical, PN_stdfloat length, PN_stdfloat width, PN_stdfloat bevel)
Creates PGSliderBar that represents a slider that the user can use to control an analog quantity.
void set_state(int state)
Sets the "state" of this particular PGItem.
Definition: pgItem.I:141
void set_manage_pieces(bool manage_pieces)
Sets the manage_pieces flag.
Definition: pgSliderBar.I:219
void clear_state_def(int state)
Resets the NodePath assigned to the indicated state to its initial default, with only a frame represe...
Definition: pgItem.cxx:944
void set_thumb_button(PGButton *thumb_button)
Sets the PGButton object that will serve as the thumb for this slider.
Definition: pgSliderBar.I:244
bool has_frame() const
Returns true if the item has a bounding rectangle; see set_frame().
Definition: pgItem.I:116
static bool is_mouse_button(ButtonHandle button)
Returns true if the indicated ButtonHandle is a mouse button, false if it is some other kind of butto...
void set_left_button(PGButton *left_button)
Sets the PGButton object that will serve as the left scroll button for this slider.
Definition: pgSliderBar.I:285
const LVecBase4 & get_frame() const
Returns the bounding rectangle of the item.
Definition: pgItem.I:106
void recompute()
Recomputes the position and size of the thumb.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
This is sent along as a parameter to most events generated for a region to indicate the mouse and but...
PN_stdfloat get_ratio() const
Returns the current value of the slider, expressed in the range 0 .
Definition: pgSliderBar.I:174
void setup_scroll_bar(bool vertical, PN_stdfloat length, PN_stdfloat width, PN_stdfloat bevel)
Creates PGSliderBar that represents a vertical or horizontal scroll bar (if vertical is true or false...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition: cullTraverser.h:45
virtual PandaNode * make_copy() const
Returns a newly-allocated Node that is a shallow copy of this one.
Definition: pgSliderBar.cxx:93
virtual void set_active(bool active)
Sets whether the PGItem is active for mouse watching.
Definition: pgItem.cxx:828
virtual void press(const MouseWatcherParameter &param, bool background)
This is a callback hook function, called whenever a mouse or keyboard button is depressed while the m...
Definition: pgItem.cxx:657
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data)
This function will be called during the cull traversal to perform any additional operations that shou...
This is a particular kind of PGItem that draws a little bar with a slider that moves from left to rig...
Definition: pgSliderBar.h:31