32PGSliderBar(
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);
208xform(
const LMatrix4 &mat) {
215 if (_thumb_button !=
nullptr) {
216 _thumb_button->clear_transform();
219 _needs_remanage =
true;
220 _needs_recompute =
true;
250setup_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));
321setup_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);
558 PGItem::frame_changed();
559 _needs_remanage =
true;
560 _needs_recompute =
true;
567item_transform_changed(
PGItem *) {
569 _needs_recompute =
true;
576item_frame_changed(
PGItem *) {
578 _needs_recompute =
true;
585item_draw_mask_changed(
PGItem *) {
587 _needs_recompute =
true;
600 if (item == _left_button || item == _right_button) {
601 _scroll_button_held = item;
602 _mouse_button_page =
false;
607 }
else if (item == _thumb_button) {
609 _scroll_button_held =
nullptr;
622 if (item == _scroll_button_held) {
623 _scroll_button_held =
nullptr;
625 }
else if (item == _thumb_button) {
626 _scroll_button_held =
nullptr;
641 if (item == _thumb_button) {
654 _needs_reposition =
false;
658 if (_thumb_button !=
nullptr) {
659 LPoint3 pos = (t * _range_x) * _axis + _thumb_start;
661 CPT(
TransformState) orig_transform = _thumb_button->get_transform();
665 if (transform == orig_transform) {
667 }
else if (*transform != *orig_transform) {
668 _thumb_button->set_transform(transform);
679 if (_scroll_button_held == _left_button) {
680 internal_set_ratio(max(_ratio - _scroll_ratio, (PN_stdfloat)0.0));
682 }
else if (_scroll_button_held == _right_button) {
683 internal_set_ratio(min(_ratio + _scroll_ratio, (PN_stdfloat)1.0));
697 LPoint3 mouse = mouse_to_local(_mouse_pos) - _thumb_start;
698 PN_stdfloat target_ratio = mouse.dot(_axis) / _range_x;
701 if (target_ratio < _ratio) {
702 t = max(_ratio - _page_ratio + _scroll_ratio, target_ratio);
705 t = min(_ratio + _page_ratio - _scroll_ratio, target_ratio);
707 internal_set_ratio(t);
708 if (t == target_ratio) {
724 if (_needs_recompute) {
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;
740 if (_needs_recompute) {
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);
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
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.
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 .
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.
const LVecBase4 & get_frame() const
Returns the bounding rectangle of the item.
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...
bool get_active() const
Returns whether the PGItem is currently active for mouse events.
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.
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_frame(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top)
Sets the bounding rectangle of the item, in local coordinates.
virtual void release(const MouseWatcherParameter ¶m, bool background)
This is a callback hook function, called whenever a mouse or keyboard button previously depressed wit...
bool has_notify() const
Returns true if there is an object configured to be notified when the PGItem changes,...
bool has_frame() const
Returns true if the item has a bounding rectangle; see set_frame().
virtual void set_active(bool active)
Sets whether the PGItem is active for mouse watching.
This is a particular kind of PGItem that draws a little bar with a slider that moves from left to rig...
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 ¶m, bool background)
This is a callback hook function, called whenever a mouse or keyboard button previously depressed wit...
virtual void move(const MouseWatcherParameter ¶m)
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 ¶m, 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.
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.
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.
TypeHandle is the identifier used to differentiate C++ class types.
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.