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);