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  */
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  */
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  */
145 move(const MouseWatcherParameter &param) {
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  */
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  */
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  */
228 adjust() {
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  */
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  */
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  */
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  */
394 remanage() {
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  */
442 recompute() {
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 }
PGItem::clear_state_def
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
MouseButton::one
static ButtonHandle one()
Returns the ButtonHandle associated with the first mouse button.
Definition: mouseButton.cxx:43
PGItem::set_frame
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
MouseWatcherParameter::get_mouse
const LPoint2 & get_mouse() const
Returns the mouse position at the time the event was generated, in the normalized range (-1 .
Definition: mouseWatcherParameter.I:263
throw_event.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PGSliderBar::setup_scroll_bar
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...
Definition: pgSliderBar.cxx:250
PGItem::press
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
PGSliderBar::press
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: pgSliderBar.cxx:103
MouseWatcherParameter
This is sent along as a parameter to most events generated for a region to indicate the mouse and but...
Definition: mouseWatcherParameter.h:28
PGItem
This is the base class for all the various kinds of gui widget objects.
Definition: pgItem.h:53
LightReMutexHolder
Similar to MutexHolder, but for a light reentrant mutex.
Definition: lightReMutexHolder.h:25
mouseButton.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pgMouseWatcherParameter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PGSliderBar::move
virtual void move(const MouseWatcherParameter &param)
This is a callback hook function, called whenever a mouse is moved while within the region.
Definition: pgSliderBar.cxx:145
clockObject.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
ClockObject::get_global_clock
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
Definition: clockObject.I:215
CullTraverser
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition: cullTraverser.h:45
PGSliderBar::set_resize_thumb
void set_resize_thumb(bool resize_thumb)
Sets the resize_thumb flag.
Definition: pgSliderBar.I:197
PandaNode::set_state
set_state
Sets the complete RenderState that will be applied to all nodes at this level and below.
Definition: pandaNode.h:173
PGItem::get_frame
const LVecBase4 & get_frame() const
Returns the bounding rectangle of the item.
Definition: pgItem.I:106
PGSliderBar
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
MouseWatcherParameter::has_mouse
bool has_mouse() const
Returns true if this parameter has an associated mouse position, false otherwise.
Definition: mouseWatcherParameter.I:253
PGItem::has_frame
bool has_frame() const
Returns true if the item has a bounding rectangle; see set_frame().
Definition: pgItem.I:116
PGSliderBar::remanage
void remanage()
Manages the position and size of the scroll bars and the thumb.
Definition: pgSliderBar.cxx:394
PGSliderBar::xform
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this node by the indicated matrix, if it means anything to do so.
Definition: pgSliderBar.cxx:208
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
transformState.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PGFrameStyle::set_width
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
PGFrameStyle
Definition: pgFrameStyle.h:29
TransformState
Indicates a coordinate-system transform on vertices.
Definition: transformState.h:54
pgSliderBar.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PGSliderBar::get_adjust_event
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
PGSliderBar::adjust
virtual void adjust()
This is a callback hook function, called whenever the slider value is adjusted by the user or program...
Definition: pgSliderBar.cxx:228
PandaNode::remove_child
void remove_child(int child_index, Thread *current_thread=Thread::get_current_thread())
Removes the nth child from the node.
Definition: pandaNode.cxx:564
CullTraverserData
This collects together the pieces of data that are accumulated for each node while walking the scene ...
Definition: cullTraverserData.h:40
PGSliderBar::release
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: pgSliderBar.cxx:129
MouseButton::is_mouse_button
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...
Definition: mouseButton.cxx:120
PGItem::get_active
bool get_active() const
Returns whether the PGItem is currently active for mouse events.
Definition: pgItem.I:160
PGSliderBar::get_notify
PGSliderBarNotify * get_notify() const
Returns the object which will be notified when the PGSliderBar changes, if any.
Definition: pgSliderBar.I:30
PGFrameStyle::set_visible_scale
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
PGFrameStyle::set_color
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
config_pgui.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PGSliderBar::set_left_button
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
PGItem::set_frame_style
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
PGButton
This is a particular kind of PGItem that is specialized to behave like a normal button object.
Definition: pgButton.h:29
PGItem::release
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
PGSliderBar::recompute
void recompute()
Recomputes the position and size of the thumb.
Definition: pgSliderBar.cxx:442
ClockObject::get_frame_time
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
PGSliderBar::setup_slider
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.
Definition: pgSliderBar.cxx:321
PGItem::set_active
virtual void set_active(bool active)
Sets whether the PGItem is active for mouse watching.
Definition: pgItem.cxx:828
PGSliderBar::get_ratio
PN_stdfloat get_ratio() const
Returns the current value of the slider, expressed in the range 0 .
Definition: pgSliderBar.I:174
PGFrameStyle::set_type
void set_type(Type type)
Sets the basic type of frame.
Definition: pgFrameStyle.I:64
MouseWatcherParameter::get_button
ButtonHandle get_button() const
Returns the mouse or keyboard button associated with this event.
Definition: mouseWatcherParameter.I:148
PGSliderBar::set_right_button
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
PGSliderBar::set_manage_pieces
void set_manage_pieces(bool manage_pieces)
Sets the manage_pieces flag.
Definition: pgSliderBar.I:219
PandaNode
A basic node of the scene graph or data graph.
Definition: pandaNode.h:65
PGItem::has_notify
bool has_notify() const
Returns true if there is an object configured to be notified when the PGItem changes,...
Definition: pgItem.I:59
PGSliderBar::cull_callback
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data)
This function will be called during the cull traversal to perform any additional operations that shou...
Definition: pgSliderBar.cxx:177
PGSliderBar::set_thumb_button
void set_thumb_button(PGButton *thumb_button)
Sets the PGButton object that will serve as the thumb for this slider.
Definition: pgSliderBar.I:244
PGSliderBar::set_active
virtual void set_active(bool active)
Sets whether the PGItem is active for mouse watching.
Definition: pgSliderBar.cxx:373
PGSliderBar::make_copy
virtual PandaNode * make_copy() const
Returns a newly-allocated Node that is a shallow copy of this one.
Definition: pgSliderBar.cxx:93