Panda3D
Loading...
Searching...
No Matches
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
23using std::max;
24using std::min;
25
26TypeHandle PGSliderBar::_type_handle;
27
28/**
29 *
30 */
31PGSliderBar::
32PGSliderBar(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 */
59PGSliderBar::
60~PGSliderBar() {
61}
62
63/**
64 *
65 */
66PGSliderBar::
67PGSliderBar(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 */
93make_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 */
103press(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 */
129release(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 */
145move(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 */
208xform(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 */
228adjust() {
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 */
250setup_scroll_bar(bool vertical, PN_stdfloat length, PN_stdfloat width, PN_stdfloat bevel) {
251 LightReMutexHolder holder(_lock);
252 set_state(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 */
321setup_slider(bool vertical, PN_stdfloat length, PN_stdfloat width, PN_stdfloat bevel) {
322 LightReMutexHolder holder(_lock);
323 set_state(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 */
373set_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 */
394remanage() {
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 */
442recompute() {
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. Assumes the lock is held.
555 */
556void PGSliderBar::
557frame_changed() {
558 PGItem::frame_changed();
559 _needs_remanage = true;
560 _needs_recompute = true;
561}
562
563/**
564 * Called whenever a watched PGItem's local transform has been changed.
565 */
566void PGSliderBar::
567item_transform_changed(PGItem *) {
568 LightReMutexHolder holder(_lock);
569 _needs_recompute = true;
570}
571
572/**
573 * Called whenever a watched PGItem's frame has been changed.
574 */
575void PGSliderBar::
576item_frame_changed(PGItem *) {
577 LightReMutexHolder holder(_lock);
578 _needs_recompute = true;
579}
580
581/**
582 * Called whenever a watched PGItem's draw_mask has been changed.
583 */
584void PGSliderBar::
585item_draw_mask_changed(PGItem *) {
586 LightReMutexHolder holder(_lock);
587 _needs_recompute = true;
588}
589
590/**
591 * Called whenever the "press" event is triggered on a watched PGItem. See
592 * PGItem::press().
593 */
594void PGSliderBar::
595item_press(PGItem *item, const MouseWatcherParameter &param) {
596 LightReMutexHolder holder(_lock);
597 if (param.has_mouse()) {
598 _mouse_pos = param.get_mouse();
599 }
600 if (item == _left_button || item == _right_button) {
601 _scroll_button_held = item;
602 _mouse_button_page = false;
603 advance_scroll();
604 _next_advance_time =
605 ClockObject::get_global_clock()->get_frame_time() + scroll_initial_delay;
606
607 } else if (item == _thumb_button) {
608 if (((PGButton *)item)->has_click_button(param.get_button())) {
609 _scroll_button_held = nullptr;
610 begin_drag();
611 }
612 }
613}
614
615/**
616 * Called whenever the "release" event is triggered on a watched PGItem. See
617 * PGItem::release().
618 */
619void PGSliderBar::
620item_release(PGItem *item, const MouseWatcherParameter &) {
621 LightReMutexHolder holder(_lock);
622 if (item == _scroll_button_held) {
623 _scroll_button_held = nullptr;
624
625 } else if (item == _thumb_button) {
626 _scroll_button_held = nullptr;
627 if (_dragging) {
628 end_drag();
629 }
630 }
631}
632
633/**
634 * Called whenever the "move" event is triggered on a watched PGItem. See
635 * PGItem::move().
636 */
637void PGSliderBar::
638item_move(PGItem *item, const MouseWatcherParameter &param) {
639 LightReMutexHolder holder(_lock);
640 _mouse_pos = param.get_mouse();
641 if (item == _thumb_button) {
642 if (_dragging) {
643 continue_drag();
644 }
645 }
646}
647
648/**
649 * A lighter-weight version of recompute(), this just moves the thumb,
650 * assuming all other properties are unchanged.
651 */
652void PGSliderBar::
653reposition() {
654 _needs_reposition = false;
655
656 PN_stdfloat t = get_ratio();
657
658 if (_thumb_button != nullptr) {
659 LPoint3 pos = (t * _range_x) * _axis + _thumb_start;
660 CPT(TransformState) transform = TransformState::make_pos(pos);
661 CPT(TransformState) orig_transform = _thumb_button->get_transform();
662
663 // It's important not to update the transform frivolously, or we'll get
664 // caught in an update loop.
665 if (transform == orig_transform) {
666 // No change.
667 } else if (*transform != *orig_transform) {
668 _thumb_button->set_transform(transform);
669 }
670 }
671}
672
673/**
674 * Advances the scroll bar by one unit in the left or right direction while
675 * the user is holding down the left or right scroll button.
676 */
677void PGSliderBar::
678advance_scroll() {
679 if (_scroll_button_held == _left_button) {
680 internal_set_ratio(max(_ratio - _scroll_ratio, (PN_stdfloat)0.0));
681
682 } else if (_scroll_button_held == _right_button) {
683 internal_set_ratio(min(_ratio + _scroll_ratio, (PN_stdfloat)1.0));
684 }
685
686 _next_advance_time =
687 ClockObject::get_global_clock()->get_frame_time() + scroll_continued_delay;
688}
689
690/**
691 * Advances the scroll bar by one page in the left or right direction while
692 * the user is holding down the mouse button on the track.
693 */
694void PGSliderBar::
695advance_page() {
696 // Is the mouse position left or right of the current thumb position?
697 LPoint3 mouse = mouse_to_local(_mouse_pos) - _thumb_start;
698 PN_stdfloat target_ratio = mouse.dot(_axis) / _range_x;
699
700 PN_stdfloat t;
701 if (target_ratio < _ratio) {
702 t = max(_ratio - _page_ratio + _scroll_ratio, target_ratio);
703
704 } else {
705 t = min(_ratio + _page_ratio - _scroll_ratio, target_ratio);
706 }
707 internal_set_ratio(t);
708 if (t == target_ratio) {
709 // We made it; begin dragging from now on until the user releases the
710 // mouse.
711 begin_drag();
712 }
713
714 _next_advance_time =
715 ClockObject::get_global_clock()->get_frame_time() + scroll_continued_delay;
716}
717
718/**
719 * Called when the user clicks down on the thumb button, possibly to begin
720 * dragging.
721 */
722void PGSliderBar::
723begin_drag() {
724 if (_needs_recompute) {
725 recompute();
726 }
727 if (_range_x != 0.0f) {
728 PN_stdfloat current_x = mouse_to_local(_mouse_pos).dot(_axis);
729 _drag_start_x = current_x - get_ratio() * _range_x;
730 _dragging = true;
731 }
732}
733
734/**
735 * Called as the user moves the mouse while still dragging on the thumb
736 * button.
737 */
738void PGSliderBar::
739continue_drag() {
740 if (_needs_recompute) {
741 recompute();
742 }
743 if (_range_x != 0.0f) {
744 PN_stdfloat current_x = mouse_to_local(_mouse_pos).dot(_axis);
745 internal_set_ratio((current_x - _drag_start_x) / _range_x);
746 }
747}
748
749/**
750 * Called as the user releases the mouse after dragging.
751 */
752void PGSliderBar::
753end_drag() {
754 _dragging = false;
755}
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
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
This collects together the pieces of data that are accumulated for each node while walking the scene ...
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Similar to MutexHolder, but for a light reentrant mutex.
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...
static ButtonHandle one()
Returns the ButtonHandle associated with the first mouse button.
This is sent along as a parameter to most events generated for a region to indicate the mouse and but...
ButtonHandle get_button() const
Returns the mouse or keyboard button associated with this event.
bool has_mouse() const
Returns true if this parameter has an associated mouse position, false otherwise.
const LPoint2 & get_mouse() const
Returns the mouse position at the time the event was generated, in the normalized range (-1 .
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.
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.
void set_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a)
Sets the dominant color of the frame.
void set_width(PN_stdfloat x, PN_stdfloat y)
Sets the width parameter, which has meaning only for certain frame types.
This is the base class for all the various kinds of gui widget objects.
Definition pgItem.h:53
const LVecBase4 & get_frame() const
Returns the bounding rectangle of the item.
Definition pgItem.I:106
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:674
bool get_active() const
Returns whether the PGItem is currently active for mouse events.
Definition pgItem.I:160
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:1007
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:953
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
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:703
bool has_notify() const
Returns true if there is an object configured to be notified when the PGItem changes,...
Definition pgItem.I:59
bool has_frame() const
Returns true if the item has a bounding rectangle; see set_frame().
Definition pgItem.I:116
virtual void set_active(bool active)
Sets whether the PGItem is active for mouse watching.
Definition pgItem.cxx:837
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
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...
void set_resize_thumb(bool resize_thumb)
Sets the resize_thumb flag.
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 move(const MouseWatcherParameter &param)
This is a callback hook function, called whenever a mouse is moved while within the region.
virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data)
This function will be called during the cull traversal to perform any additional operations that shou...
virtual PandaNode * make_copy() const
Returns a newly-allocated Node that is a shallow copy of this one.
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this node by the indicated matrix, if it means anything to do so.
void remanage()
Manages the position and size of the scroll bars and the thumb.
virtual void set_active(bool active)
Sets whether the PGItem is active for mouse watching.
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_thumb_button(PGButton *thumb_button)
Sets the PGButton object that will serve as the thumb for this slider.
virtual void adjust()
This is a callback hook function, called whenever the slider value is adjusted by the user or program...
void set_left_button(PGButton *left_button)
Sets the PGButton object that will serve as the left scroll button for this slider.
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...
PN_stdfloat get_ratio() const
Returns the current value of the slider, expressed in the range 0 .
PGSliderBarNotify * get_notify() const
Returns the object which will be notified when the PGSliderBar changes, if any.
Definition pgSliderBar.I:30
void set_manage_pieces(bool manage_pieces)
Sets the manage_pieces flag.
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...
void recompute()
Recomputes the position and size of the thumb.
void set_right_button(PGButton *right_button)
Sets the PGButton object that will serve as the right scroll button for this slider.
A basic node of the scene graph or data graph.
Definition pandaNode.h:65
void remove_child(int child_index, Thread *current_thread=Thread::get_current_thread())
Removes the nth child from the node.
set_state
Sets the complete RenderState that will be applied to all nodes at this level and below.
Definition pandaNode.h:173
Indicates a coordinate-system transform on vertices.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.