15 #include "pgSliderBar.h"
16 #include "pgMouseWatcherParameter.h"
17 #include "clockObject.h"
18 #include "throw_event.h"
19 #include "config_pgui.h"
20 #include "throw_event.h"
21 #include "transformState.h"
22 #include "mouseButton.h"
32 PGSliderBar(
const string &name)
39 set_scroll_size(0.01f);
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 = NULL;
49 _mouse_button_page =
false;
73 _min_value(copy._min_value),
74 _max_value(copy._max_value),
75 _scroll_value(copy._scroll_value),
76 _scroll_ratio(copy._scroll_ratio),
77 _page_value(copy._page_value),
78 _page_ratio(copy._page_ratio),
80 _resize_thumb(copy._resize_thumb),
81 _manage_pieces(copy._manage_pieces),
84 _needs_remanage =
false;
85 _needs_recompute =
true;
86 _scroll_button_held = NULL;
87 _mouse_button_page =
false;
119 if (_needs_recompute) {
123 if (_range_x != 0.0f) {
124 _mouse_button_page =
true;
125 _scroll_button_held = NULL;
145 _mouse_button_page =
false;
201 if (_manage_pieces && _needs_remanage) {
204 if (_needs_recompute) {
208 if (_scroll_button_held != (
PGItem *)NULL &&
213 if (_mouse_button_page &&
218 if (_needs_reposition) {
222 return PGItem::cull_callback(trav, data);
240 if (_thumb_button != (
PGButton *)NULL) {
241 _thumb_button->clear_transform();
244 _needs_remanage =
true;
245 _needs_recompute =
true;
282 setup_scroll_bar(
bool vertical, PN_stdfloat length, PN_stdfloat width, PN_stdfloat bevel) {
288 set_frame(-width / 2.0f, width / 2.0f, -length / 2.0f, length / 2.0f);
291 set_frame(-length / 2.0f, length / 2.0f, -width / 2.0f, width / 2.0f);
297 style.
set_type(PGFrameStyle::T_flat);
301 style.
set_type(PGFrameStyle::T_bevel_out);
306 if (_thumb_button != (
PGButton *)NULL) {
310 if (_left_button != (
PGButton *)NULL) {
314 if (_right_button != (
PGButton *)NULL) {
320 thumb->setup(
"", bevel);
321 thumb->set_frame(-width / 2.0f, width / 2.0f,
322 -width / 2.0f, width / 2.0f);
327 left->setup(
"", bevel);
328 left->set_frame(-width / 2.0f, width / 2.0f,
329 -width / 2.0f, width / 2.0f);
330 left->set_transform(TransformState::make_pos(((width - length) / 2.0f) * _axis));
335 right->setup(
"", bevel);
336 right->set_frame(-width / 2.0f, width / 2.0f,
337 -width / 2.0f, width / 2.0f);
338 right->set_transform(TransformState::make_pos(((length - width) / 2.0f) * _axis));
356 setup_slider(
bool vertical, PN_stdfloat length, PN_stdfloat width, PN_stdfloat bevel) {
362 set_frame(-width / 2.0f, width / 2.0f, -length / 2.0f, length / 2.0f);
365 set_frame(-length / 2.0f, length / 2.0f, -width / 2.0f, width / 2.0f);
371 style.
set_type(PGFrameStyle::T_flat);
378 if (_thumb_button != (
PGButton *)NULL) {
382 if (_left_button != (
PGButton *)NULL) {
386 if (_right_button != (
PGButton *)NULL) {
392 thumb->setup(
" ", bevel);
393 thumb->set_frame(-width / 4.0f, width / 4.0f,
394 -width / 2.0f, width / 2.0f);
417 if (_thumb_button != (
PGButton *)NULL) {
418 _thumb_button->set_active(active);
420 if (_left_button != (
PGButton *)NULL) {
421 _left_button->set_active(active);
423 if (_right_button != (
PGButton *)NULL) {
424 _right_button->set_active(active);
438 _needs_remanage =
false;
442 PN_stdfloat width, length;
443 if (fabs(_axis[0]) > fabs(_axis[1] + _axis[2])) {
445 width = frame[3] - frame[2];
446 length = frame[1] - frame[0];
450 width = frame[1] - frame[0];
451 length = frame[3] - frame[2];
456 (frame[2] + frame[3]) / 2.0f);
458 if (_left_button != (
PGButton *)NULL) {
459 _left_button->set_frame(-width / 2.0f, width / 2.0f,
460 -width / 2.0f, width / 2.0f);
461 _left_button->set_transform(TransformState::make_pos(center + ((width - length) / 2.0f) * _axis));
464 if (_right_button != (
PGButton *)NULL) {
465 _right_button->set_frame(-width / 2.0f, width / 2.0f,
466 -width / 2.0f, width / 2.0f);
467 _right_button->set_transform(TransformState::make_pos(center + ((length - width) / 2.0f) * _axis));
470 if (_thumb_button != (
PGButton *)NULL) {
471 _thumb_button->set_frame(-width / 2.0f, width / 2.0f,
472 -width / 2.0f, width / 2.0f);
473 _thumb_button->set_transform(TransformState::make_pos(center));
488 _needs_recompute =
false;
490 if (_min_value != _max_value) {
491 _scroll_ratio = fabs(_scroll_value / (_max_value - _min_value));
492 _page_ratio = fabs(_page_value / (_max_value - _min_value));
495 _scroll_ratio = 0.0f;
504 _thumb_start.set(0.0f, 0.0f, 0.0f);
508 reduce_region(frame, _left_button);
509 reduce_region(frame, _right_button);
511 if (fabs(_axis[0]) > fabs(_axis[1] + _axis[2])) {
517 PN_stdfloat trough_width = _max_x - _min_x;
519 if (_thumb_button == (
PGButton *)NULL) {
522 _thumb_start.set(0.0f, 0.0f, 0.0f);
525 const LVecBase4 &thumb_frame = _thumb_button->get_frame();
530 _thumb_width = trough_width * min((PN_stdfloat)1.0, _page_ratio);
531 _thumb_button->set_frame(-_thumb_width / 2.0f, _thumb_width / 2.0f,
532 thumb_frame[2], thumb_frame[3]);
536 _thumb_width = thumb_frame[1] - thumb_frame[0];
539 _range_x = trough_width - _thumb_width;
541 if (_axis[0] >= 0.0f) {
543 _thumb_start = (_min_x - thumb_frame[0]) * _axis;
546 _thumb_start = (thumb_frame[1] - _max_x) * _axis;
548 _thumb_start +=
LVector3::rfu(0.0f, 0.0f, (frame[2] + frame[3]) / 2.0f);
558 PN_stdfloat trough_width = _max_x - _min_x;
560 if (_thumb_button == (
PGButton *)NULL) {
563 _thumb_start.set(0.0f, 0.0f, 0.0f);
566 const LVecBase4 &thumb_frame = _thumb_button->get_frame();
571 _thumb_width = trough_width * min((PN_stdfloat)1.0, _page_ratio);
572 _thumb_button->set_frame(thumb_frame[0], thumb_frame[1],
573 -_thumb_width / 2.0f, _thumb_width / 2.0f);
577 _thumb_width = thumb_frame[3] - thumb_frame[2];
580 _range_x = trough_width - _thumb_width;
582 if (_axis[1] >= 0.0f && _axis[2] >= 0.0f) {
584 _thumb_start = (_min_x - thumb_frame[2]) * _axis;
587 _thumb_start = (thumb_frame[3] - _max_x) * _axis;
589 _thumb_start +=
LVector3::rfu((frame[0] + frame[1]) / 2.0f, 0.0f, 0.0f);
605 PGItem::frame_changed();
606 _needs_remanage =
true;
607 _needs_recompute =
true;
617 item_transform_changed(
PGItem *) {
619 _needs_recompute =
true;
629 item_frame_changed(
PGItem *) {
631 _needs_recompute =
true;
641 item_draw_mask_changed(
PGItem *) {
643 _needs_recompute =
true;
658 if (item == _left_button || item == _right_button) {
659 _scroll_button_held = item;
660 _mouse_button_page =
false;
665 }
else if (item == _thumb_button) {
666 _scroll_button_held = NULL;
680 if (item == _scroll_button_held) {
681 _scroll_button_held = NULL;
683 }
else if (item == _thumb_button) {
684 _scroll_button_held = NULL;
701 if (item == _thumb_button) {
717 _needs_reposition =
false;
721 if (_thumb_button != (
PGButton *)NULL) {
722 LPoint3 pos = (t * _range_x) * _axis + _thumb_start;
723 CPT(TransformState) transform = TransformState::make_pos(pos);
724 CPT(TransformState) orig_transform = _thumb_button->get_transform();
728 if (transform == orig_transform) {
730 }
else if (*transform != *orig_transform) {
731 _thumb_button->set_transform(transform);
745 if (_scroll_button_held == _left_button) {
746 internal_set_ratio(max(_ratio - _scroll_ratio, (PN_stdfloat)0.0));
748 }
else if (_scroll_button_held == _right_button) {
749 internal_set_ratio(min(_ratio + _scroll_ratio, (PN_stdfloat)1.0));
767 LPoint3 mouse = mouse_to_local(_mouse_pos) - _thumb_start;
768 PN_stdfloat target_ratio = mouse.dot(_axis) / _range_x;
771 if (target_ratio < _ratio) {
772 t = max(_ratio - _page_ratio + _scroll_ratio, target_ratio);
775 t = min(_ratio + _page_ratio - _scroll_ratio, target_ratio);
777 internal_set_ratio(t);
778 if (t == target_ratio) {
796 if (_needs_recompute) {
799 if (_range_x != 0.0f) {
800 PN_stdfloat current_x = mouse_to_local(_mouse_pos).dot(_axis);
801 _drag_start_x = current_x -
get_ratio() * _range_x;
814 if (_needs_recompute) {
817 if (_range_x != 0.0f) {
818 PN_stdfloat current_x = mouse_to_local(_mouse_pos).dot(_axis);
819 internal_set_ratio((current_x - _drag_start_x) / _range_x);
ButtonHandle get_button() const
Returns the mouse or keyboard button associated with this event.
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
virtual void set_active(bool active)
Sets whether the PGItem is active for mouse watching.
const LVecBase4 & get_frame() const
Returns the bounding rectangle of the item.
A basic node of the scene graph or data graph.
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_width(PN_stdfloat x, PN_stdfloat y)
Sets the width parameter, which has meaning only for certain frame types.
void remove_child(int child_index, Thread *current_thread=Thread::get_current_thread())
Removes the nth child from the node.
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this node by the indicated matrix, if it means anything to do so...
void set_resize_thumb(bool resize_thumb)
Sets the resize_thumb flag.
This is the base class for all the various kinds of gui widget objects.
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...
PGSliderBarNotify * get_notify() const
Returns the object which will be notified when the PGSliderBar changes, if any.
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this node by the indicated matrix, if it means anything to do so...
void set_type(Type type)
Sets the basic type of 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.
This collects together the pieces of data that are accumulated for each node while walking the scene ...
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
virtual void move(const MouseWatcherParameter ¶m)
This is a callback hook function, called whenever a mouse is moved while within the region...
virtual void press(const MouseWatcherParameter ¶m, bool background)
This is a callback hook function, called whenever a mouse or keyboard button is depressed while the m...
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
virtual PandaNode * make_copy() const
Returns a newly-allocated Node that is a shallow copy of this one.
virtual void adjust()
This is a callback hook function, called whenever the slider value is adjusted by the user or program...
static LVector3f rfu(float right, float fwd, float up, CoordinateSystem cs=CS_default)
Returns a vector that is described by its right, forward, and up components, in whatever way the coor...
bool has_frame() const
Returns true if the item has a bounding rectangle; see set_frame().
void remanage()
Manages the position and size of the scroll bars and the thumb.
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...
const LPoint2 & get_mouse() const
Returns the mouse position at the time the event was generated, in the normalized range (-1 ...
bool has_notify() const
Returns true if there is an object configured to be notified when the PGItem changes, false otherwise.
virtual void release(const MouseWatcherParameter ¶m, bool background)
This is a callback hook function, called whenever a mouse or keyboard button previously depressed wit...
This is a 4-by-4 transform matrix.
double get_frame_time(Thread *current_thread=Thread::get_current_thread()) const
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
virtual void release(const MouseWatcherParameter ¶m, bool background)
This is a callback hook function, called whenever a mouse or keyboard button previously depressed wit...
void set_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a)
Sets the dominant color of the frame.
bool get_active() const
Returns whether the PGItem is currently active for mouse events.
Similar to MutexHolder, but for a light reentrant mutex.
void set_right_button(PGButton *right_button)
Sets the PGButton object that will serve as the right scroll button for this 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...
This is the base class for all three-component vectors and points.
void set_state(int state)
Sets the "state" of this particular PGItem.
void set_manage_pieces(bool manage_pieces)
Sets the manage_pieces flag.
void clear_state_def(int state)
Resets the NodePath assigned to the indicated state to its initial default, with only a frame represe...
void set_thumb_button(PGButton *thumb_button)
Sets the PGButton object that will serve as the thumb for this slider.
bool has_mouse() const
Returns true if this parameter has an associated mouse position, false otherwise. ...
void set_left_button(PGButton *left_button)
Sets the PGButton object that will serve as the left scroll button for this slider.
void recompute()
Recomputes the position and size of the thumb.
TypeHandle is the identifier used to differentiate C++ class types.
This is sent along as a parameter to most events generated for a region to indicate the mouse and but...
void add_child(PandaNode *child_node, int sort=0, Thread *current_thread=Thread::get_current_thread())
Adds a new child to the node.
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...
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling...
virtual void set_active(bool active)
Sets whether the PGItem is active for mouse watching.
PN_stdfloat get_ratio() const
Returns the current value of the slider, expressed in the range 0 .
virtual void press(const MouseWatcherParameter ¶m, bool background)
This is a callback hook function, called whenever a mouse or keyboard button is depressed while the m...
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...