32 PGSliderBar(
const std::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 =
nullptr;
49 _mouse_button_page =
false;
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),
76 _resize_thumb(copy._resize_thumb),
77 _manage_pieces(copy._manage_pieces),
80 _needs_remanage =
false;
81 _needs_recompute =
true;
82 _scroll_button_held =
nullptr;
83 _mouse_button_page =
false;
109 if (_needs_recompute) {
113 if (_range_x != 0.0f) {
114 _mouse_button_page =
true;
115 _scroll_button_held =
nullptr;
132 _mouse_button_page =
false;
179 if (_manage_pieces && _needs_remanage) {
182 if (_needs_recompute) {
186 if (_scroll_button_held !=
nullptr &&
191 if (_mouse_button_page &&
196 if (_needs_reposition) {
200 return PGItem::cull_callback(trav, data);
215 if (_thumb_button !=
nullptr) {
216 _thumb_button->clear_transform();
219 _needs_remanage =
true;
220 _needs_recompute =
true;
250 setup_scroll_bar(
bool vertical, PN_stdfloat length, PN_stdfloat width, PN_stdfloat bevel) {
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);
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);
265 style.
set_type(PGFrameStyle::T_flat);
269 style.
set_type(PGFrameStyle::T_bevel_out);
273 if (_thumb_button !=
nullptr) {
277 if (_left_button !=
nullptr) {
281 if (_right_button !=
nullptr) {
287 thumb->setup(
"", bevel);
288 thumb->set_frame(-width / 2.0f, width / 2.0f,
289 -width / 2.0f, width / 2.0f);
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));
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));
321 setup_slider(
bool vertical, PN_stdfloat length, PN_stdfloat width, PN_stdfloat bevel) {
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);
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);
336 style.
set_type(PGFrameStyle::T_flat);
342 if (_thumb_button !=
nullptr) {
346 if (_left_button !=
nullptr) {
350 if (_right_button !=
nullptr) {
356 thumb->setup(
" ", bevel);
357 thumb->set_frame(-width / 4.0f, width / 4.0f,
358 -width / 2.0f, width / 2.0f);
378 if (_thumb_button !=
nullptr) {
379 _thumb_button->set_active(active);
381 if (_left_button !=
nullptr) {
382 _left_button->set_active(active);
384 if (_right_button !=
nullptr) {
385 _right_button->set_active(active);
396 _needs_remanage =
false;
400 PN_stdfloat width, length;
401 if (fabs(_axis[0]) > fabs(_axis[1] + _axis[2])) {
403 width = frame[3] - frame[2];
404 length = frame[1] - frame[0];
408 width = frame[1] - frame[0];
409 length = frame[3] - frame[2];
412 LVector3 center = LVector3::rfu((frame[0] + frame[1]) / 2.0f,
414 (frame[2] + frame[3]) / 2.0f);
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));
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));
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));
444 _needs_recompute =
false;
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));
451 _scroll_ratio = 0.0f;
460 _thumb_start.set(0.0f, 0.0f, 0.0f);
464 reduce_region(frame, _left_button);
465 reduce_region(frame, _right_button);
467 if (fabs(_axis[0]) > fabs(_axis[1] + _axis[2])) {
473 PN_stdfloat trough_width = _max_x - _min_x;
475 if (_thumb_button ==
nullptr) {
478 _thumb_start.set(0.0f, 0.0f, 0.0f);
481 const LVecBase4 &thumb_frame = _thumb_button->get_frame();
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]);
492 _thumb_width = thumb_frame[1] - thumb_frame[0];
495 _range_x = trough_width - _thumb_width;
497 if (_axis[0] >= 0.0f) {
499 _thumb_start = (_min_x - thumb_frame[0]) * _axis;
502 _thumb_start = (thumb_frame[1] - _max_x) * _axis;
504 _thumb_start += LVector3::rfu(0.0f, 0.0f, (frame[2] + frame[3]) / 2.0f);
514 PN_stdfloat trough_width = _max_x - _min_x;
516 if (_thumb_button ==
nullptr) {
519 _thumb_start.set(0.0f, 0.0f, 0.0f);
522 const LVecBase4 &thumb_frame = _thumb_button->get_frame();
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);
533 _thumb_width = thumb_frame[3] - thumb_frame[2];
536 _range_x = trough_width - _thumb_width;
538 if (_axis[1] >= 0.0f && _axis[2] >= 0.0f) {
540 _thumb_start = (_min_x - thumb_frame[2]) * _axis;
543 _thumb_start = (thumb_frame[3] - _max_x) * _axis;
545 _thumb_start += LVector3::rfu((frame[0] + frame[1]) / 2.0f, 0.0f, 0.0f);
559 PGItem::frame_changed();
560 _needs_remanage =
true;
561 _needs_recompute =
true;
568 item_transform_changed(
PGItem *) {
570 _needs_recompute =
true;
577 item_frame_changed(
PGItem *) {
579 _needs_recompute =
true;
586 item_draw_mask_changed(
PGItem *) {
588 _needs_recompute =
true;
601 if (item == _left_button || item == _right_button) {
602 _scroll_button_held = item;
603 _mouse_button_page =
false;
608 }
else if (item == _thumb_button) {
609 _scroll_button_held =
nullptr;
621 if (item == _scroll_button_held) {
622 _scroll_button_held =
nullptr;
624 }
else if (item == _thumb_button) {
625 _scroll_button_held =
nullptr;
640 if (item == _thumb_button) {
653 _needs_reposition =
false;
657 if (_thumb_button !=
nullptr) {
658 LPoint3 pos = (t * _range_x) * _axis + _thumb_start;
660 CPT(
TransformState) orig_transform = _thumb_button->get_transform();
664 if (transform == orig_transform) {
666 }
else if (*transform != *orig_transform) {
667 _thumb_button->set_transform(transform);
678 if (_scroll_button_held == _left_button) {
679 internal_set_ratio(max(_ratio - _scroll_ratio, (PN_stdfloat)0.0));
681 }
else if (_scroll_button_held == _right_button) {
682 internal_set_ratio(min(_ratio + _scroll_ratio, (PN_stdfloat)1.0));
696 LPoint3 mouse = mouse_to_local(_mouse_pos) - _thumb_start;
697 PN_stdfloat target_ratio = mouse.dot(_axis) / _range_x;
700 if (target_ratio < _ratio) {
701 t = max(_ratio - _page_ratio + _scroll_ratio, target_ratio);
704 t = min(_ratio + _page_ratio - _scroll_ratio, target_ratio);
706 internal_set_ratio(t);
707 if (t == target_ratio) {
723 if (_needs_recompute) {
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;
739 if (_needs_recompute) {
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);
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.
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.
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.
This is the base class for all the various kinds of gui widget objects.
bool get_active() const
Returns whether the PGItem is currently active for mouse events.
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.
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 ...
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...
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...
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,...
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.
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 ...
virtual void release(const MouseWatcherParameter ¶m, bool background)
This is a callback hook function, called whenever a mouse or keyboard button previously depressed wit...
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.
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.
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.
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_frame() const
Returns true if the item has a bounding rectangle; see set_frame().
void set_left_button(PGButton *left_button)
Sets the PGButton object that will serve as the left scroll button for this slider.
const LVecBase4 & get_frame() const
Returns the bounding rectangle of the item.
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...
PN_stdfloat get_ratio() const
Returns the current value of the slider, expressed in the range 0 .
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,...
virtual PandaNode * make_copy() const
Returns a newly-allocated Node that is a shallow copy of this one.
virtual void set_active(bool active)
Sets whether the PGItem is active for mouse watching.
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...