|
@@ -18,8 +18,12 @@
|
|
|
|
|
|
|
|
#include "pgSliderBar.h"
|
|
#include "pgSliderBar.h"
|
|
|
#include "pgMouseWatcherParameter.h"
|
|
#include "pgMouseWatcherParameter.h"
|
|
|
-
|
|
|
|
|
|
|
+#include "clockObject.h"
|
|
|
|
|
+#include "throw_event.h"
|
|
|
|
|
+#include "config_pgui.h"
|
|
|
#include "throw_event.h"
|
|
#include "throw_event.h"
|
|
|
|
|
+#include "transformState.h"
|
|
|
|
|
+#include "mouseButton.h"
|
|
|
|
|
|
|
|
TypeHandle PGSliderBar::_type_handle;
|
|
TypeHandle PGSliderBar::_type_handle;
|
|
|
|
|
|
|
@@ -29,26 +33,26 @@ TypeHandle PGSliderBar::_type_handle;
|
|
|
// Description:
|
|
// Description:
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
PGSliderBar::
|
|
PGSliderBar::
|
|
|
-PGSliderBar(const string &name) :
|
|
|
|
|
- PGItem(name),
|
|
|
|
|
- // _slider("slider"),
|
|
|
|
|
- _left("left"),
|
|
|
|
|
- _right("right")
|
|
|
|
|
|
|
+PGSliderBar(const string &name)
|
|
|
|
|
+ : PGItem(name)
|
|
|
{
|
|
{
|
|
|
- _slider = NULL;
|
|
|
|
|
- _range = 100.0;
|
|
|
|
|
- // _value is a range from (-1 to +1) that represents slider
|
|
|
|
|
- _value = 0.0;
|
|
|
|
|
- // _mapped_value is a mapping of (-1<->1) into (0<->1)
|
|
|
|
|
- _mapped_value = 0.5*_value + 0.5;
|
|
|
|
|
- // _update_x is mapping of _mapped_value wrt slider width
|
|
|
|
|
- _update_x = 0.0; //will be set when _width is defined
|
|
|
|
|
- _speed = 0.05;
|
|
|
|
|
- _scale = 0.05;
|
|
|
|
|
- _bar_state = -1;
|
|
|
|
|
- _update_slider = false;
|
|
|
|
|
- _slider_only = true;
|
|
|
|
|
- _negative_mapping = false;
|
|
|
|
|
|
|
+ _min_value = 0.0f;
|
|
|
|
|
+ _max_value = 1.0f;
|
|
|
|
|
+ set_scroll_size(0.01f);
|
|
|
|
|
+ set_page_size(0.1f);
|
|
|
|
|
+ _ratio = 0.0f;
|
|
|
|
|
+ _resize_thumb = false;
|
|
|
|
|
+ _manage_pieces = false;
|
|
|
|
|
+ _axis.set(1.0f, 0.0f, 0.0f);
|
|
|
|
|
+ _needs_remanage = false;
|
|
|
|
|
+ _needs_recompute = true;
|
|
|
|
|
+ _needs_reposition = false;
|
|
|
|
|
+ _scroll_button_held = NULL;
|
|
|
|
|
+ _mouse_button_page = false;
|
|
|
|
|
+ _dragging = false;
|
|
|
|
|
+ _thumb_width = 0.1f;
|
|
|
|
|
+
|
|
|
|
|
+ set_active(true);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
@@ -68,14 +72,22 @@ PGSliderBar::
|
|
|
PGSliderBar::
|
|
PGSliderBar::
|
|
|
PGSliderBar(const PGSliderBar ©) :
|
|
PGSliderBar(const PGSliderBar ©) :
|
|
|
PGItem(copy),
|
|
PGItem(copy),
|
|
|
- _value(copy._value),
|
|
|
|
|
- _range(copy._range),
|
|
|
|
|
- // _slider(copy._slider),
|
|
|
|
|
- _left(copy._left),
|
|
|
|
|
- _right(copy._right)
|
|
|
|
|
|
|
+ _min_value(copy._min_value),
|
|
|
|
|
+ _max_value(copy._max_value),
|
|
|
|
|
+ _scroll_value(copy._scroll_value),
|
|
|
|
|
+ _scroll_ratio(copy._scroll_ratio),
|
|
|
|
|
+ _page_value(copy._page_value),
|
|
|
|
|
+ _page_ratio(copy._page_ratio),
|
|
|
|
|
+ _ratio(copy._ratio),
|
|
|
|
|
+ _resize_thumb(copy._resize_thumb),
|
|
|
|
|
+ _manage_pieces(copy._manage_pieces),
|
|
|
|
|
+ _axis(copy._axis)
|
|
|
{
|
|
{
|
|
|
- _bar_state = -1;
|
|
|
|
|
- _slider = NULL;
|
|
|
|
|
|
|
+ _needs_remanage = false;
|
|
|
|
|
+ _needs_recompute = true;
|
|
|
|
|
+ _scroll_button_held = NULL;
|
|
|
|
|
+ _mouse_button_page = false;
|
|
|
|
|
+ _dragging = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
@@ -91,6 +103,71 @@ make_copy() const {
|
|
|
return new PGSliderBar(*this);
|
|
return new PGSliderBar(*this);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::press
|
|
|
|
|
+// Access: Public, Virtual
|
|
|
|
|
+// Description: This is a callback hook function, called whenever a
|
|
|
|
|
+// mouse or keyboard button is depressed while the mouse
|
|
|
|
|
+// is within the region.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+press(const MouseWatcherParameter ¶m, bool background) {
|
|
|
|
|
+ if (param.has_mouse()) {
|
|
|
|
|
+ _mouse_pos = param.get_mouse();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (get_active() && param.get_button() == MouseButton::one()) {
|
|
|
|
|
+ if (_needs_recompute) {
|
|
|
|
|
+ recompute();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (_range_x != 0.0f) {
|
|
|
|
|
+ _mouse_button_page = true;
|
|
|
|
|
+ _scroll_button_held = NULL;
|
|
|
|
|
+ advance_page();
|
|
|
|
|
+ _next_advance_time =
|
|
|
|
|
+ ClockObject::get_global_clock()->get_frame_time() + scroll_initial_delay;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ PGItem::press(param, background);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::release
|
|
|
|
|
+// Access: Public, Virtual
|
|
|
|
|
+// Description: This is a callback hook function, called whenever a
|
|
|
|
|
+// mouse or keyboard button previously depressed with
|
|
|
|
|
+// press() is released.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+release(const MouseWatcherParameter ¶m, bool background) {
|
|
|
|
|
+ if (MouseButton::is_mouse_button(param.get_button())) {
|
|
|
|
|
+ _mouse_button_page = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (_dragging) {
|
|
|
|
|
+ end_drag();
|
|
|
|
|
+ }
|
|
|
|
|
+ PGItem::release(param, background);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::move
|
|
|
|
|
+// Access: Protected, Virtual
|
|
|
|
|
+// Description: This is a callback hook function, called whenever a
|
|
|
|
|
+// mouse is moved while within the region.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+move(const MouseWatcherParameter ¶m) {
|
|
|
|
|
+ _mouse_pos = param.get_mouse();
|
|
|
|
|
+ if (_dragging) {
|
|
|
|
|
+ // We only get here if we the user originally clicked on the
|
|
|
|
|
+ // track, which caused the slider to move all the way to the mouse
|
|
|
|
|
+ // position, and then started dragging the mouse along the track.
|
|
|
|
|
+ // In this case, we start moving the thumb as if the user had
|
|
|
|
|
+ // started by dragging the thumb directly.
|
|
|
|
|
+ continue_drag();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: PGSliderBar::has_cull_callback
|
|
// Function: PGSliderBar::has_cull_callback
|
|
|
// Access: Protected, Virtual
|
|
// Access: Protected, Virtual
|
|
@@ -126,161 +203,599 @@ has_cull_callback() const {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
bool PGSliderBar::
|
|
bool PGSliderBar::
|
|
|
cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
|
cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
|
|
- update();
|
|
|
|
|
|
|
+ if (_manage_pieces && _needs_remanage) {
|
|
|
|
|
+ remanage();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (_needs_recompute) {
|
|
|
|
|
+ recompute();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (_scroll_button_held != (PGItem *)NULL &&
|
|
|
|
|
+ _next_advance_time <= ClockObject::get_global_clock()->get_frame_time()) {
|
|
|
|
|
+ advance_scroll();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (_mouse_button_page &&
|
|
|
|
|
+ _next_advance_time <= ClockObject::get_global_clock()->get_frame_time()) {
|
|
|
|
|
+ advance_page();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (_needs_reposition) {
|
|
|
|
|
+ reposition();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
return PGItem::cull_callback(trav, data);
|
|
return PGItem::cull_callback(trav, data);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
-// Function: PGSliderBar::setup
|
|
|
|
|
-// Access: Public
|
|
|
|
|
-// Description: Creates a PGSliderBar with the indicated dimensions,
|
|
|
|
|
-// with the indicated maximum range.
|
|
|
|
|
|
|
+// Function: PGSliderBar::xform
|
|
|
|
|
+// Access: Public, Virtual
|
|
|
|
|
+// Description: Transforms the contents of this node by the indicated
|
|
|
|
|
+// matrix, if it means anything to do so. For most
|
|
|
|
|
+// kinds of nodes, this does nothing.
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
void PGSliderBar::
|
|
void PGSliderBar::
|
|
|
-setup(float width, float height, float range) {
|
|
|
|
|
- //set_state(0);
|
|
|
|
|
- //clear_state_def(0);
|
|
|
|
|
|
|
+xform(const LMatrix4f &mat) {
|
|
|
|
|
+ PGItem::xform(mat);
|
|
|
|
|
+ _axis = _axis * mat;
|
|
|
|
|
+
|
|
|
|
|
+ // Make sure we set the thumb to identity position first, so it
|
|
|
|
|
+ // won't be accidentally flattened.
|
|
|
|
|
+ if (_thumb_button != (PGButton *)NULL) {
|
|
|
|
|
+ _thumb_button->clear_transform();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- _width = 0.5 * width; // quick reference to find the left and right max points
|
|
|
|
|
- //set_frame(-0.5f * width, 0.5f * width, -0.5f * height, 0.5f * height);
|
|
|
|
|
- set_range(range);
|
|
|
|
|
|
|
+ _needs_remanage = true;
|
|
|
|
|
+ _needs_recompute = true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::adjust
|
|
|
|
|
+// Access: Public, Virtual
|
|
|
|
|
+// Description: This is a callback hook function, called whenever the
|
|
|
|
|
+// slider value is adjusted by the user or
|
|
|
|
|
+// programmatically.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+adjust() {
|
|
|
|
|
+ string event = get_adjust_event();
|
|
|
|
|
+ play_sound(event);
|
|
|
|
|
+ throw_event(event);
|
|
|
|
|
|
|
|
- NodePath current = NodePath(this);
|
|
|
|
|
- if (!_slider) {
|
|
|
|
|
- _slider = new PGSliderButton("slider");
|
|
|
|
|
- _slider_button = current.attach_new_node(_slider);
|
|
|
|
|
|
|
+ if (has_notify()) {
|
|
|
|
|
+ get_notify()->slider_bar_adjust(this);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- _slider->set_slider_bar(this);
|
|
|
|
|
- //_slider->setup(_slider->get_name());
|
|
|
|
|
- _slider->setup("");
|
|
|
|
|
- _slider->set_drag_n_drop(true);
|
|
|
|
|
- _slider->set_frame(-1,1,-1.5,1.5);
|
|
|
|
|
- _slider_button.set_scale(_scale);
|
|
|
|
|
- _slider_button.set_pos(0, 0, 0); // center it
|
|
|
|
|
-
|
|
|
|
|
- // if left or right button to control slider desired, create them
|
|
|
|
|
- if (!_slider_only) {
|
|
|
|
|
- _left_button = current.attach_new_node(&_left);
|
|
|
|
|
- _left.set_slider_bar(this);
|
|
|
|
|
- _right_button = current.attach_new_node(&_right);
|
|
|
|
|
- _right.set_slider_bar(this);
|
|
|
|
|
- _left.setup(_left.get_name());
|
|
|
|
|
- _right.setup(_right.get_name());
|
|
|
|
|
- _left_button.set_scale(0.5);
|
|
|
|
|
- _left_button.set_pos(-(_width+1), 0, -0.25);
|
|
|
|
|
- _right_button.set_scale(0.5);
|
|
|
|
|
- _right_button.set_pos((_width+0.5), 0, -0.25);
|
|
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::setup_scroll_bar
|
|
|
|
|
+// Access: Published
|
|
|
|
|
+// Description: Creates PGSliderBar that represents a vertical or
|
|
|
|
|
+// horizontal scroll bar (if vertical is true or false,
|
|
|
|
|
+// respectively), with additional buttons for scrolling,
|
|
|
|
|
+// and a range of 0 .. 1.
|
|
|
|
|
+//
|
|
|
|
|
+// length here is the measurement along the scroll bar,
|
|
|
|
|
+// and width is the measurement across the scroll bar,
|
|
|
|
|
+// whether it is vertical or horizontal (so for a
|
|
|
|
|
+// horizontal scroll bar, the length is actually the x
|
|
|
|
|
+// dimension, and the width is the y dimension).
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+setup_scroll_bar(bool vertical, float length, float width, float bevel) {
|
|
|
|
|
+ set_state(0);
|
|
|
|
|
+ clear_state_def(0);
|
|
|
|
|
+
|
|
|
|
|
+ if (vertical) {
|
|
|
|
|
+ set_frame(-width / 2.0f, width / 2.0f, -length / 2.0f, length / 2.0f);
|
|
|
|
|
+ _axis = LVector3f::rfu(0.0f, 0.0f, -1.0f);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ set_frame(-length / 2.0f, length / 2.0f, -width / 2.0f, width / 2.0f);
|
|
|
|
|
+ _axis = LVector3f::rfu(1.0f, 0.0f, 0.0f);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
PGFrameStyle style;
|
|
PGFrameStyle style;
|
|
|
- style.set_width(0.3f, 0.3f);
|
|
|
|
|
-
|
|
|
|
|
- /*
|
|
|
|
|
style.set_color(0.6f, 0.6f, 0.6f, 1.0f);
|
|
style.set_color(0.6f, 0.6f, 0.6f, 1.0f);
|
|
|
- style.set_type(PGFrameStyle::T_bevel_in);
|
|
|
|
|
- //set_frame_style(0, style);
|
|
|
|
|
- */
|
|
|
|
|
|
|
+ style.set_type(PGFrameStyle::T_flat);
|
|
|
|
|
+ set_frame_style(0, style);
|
|
|
|
|
|
|
|
style.set_color(0.8f, 0.8f, 0.8f, 1.0f);
|
|
style.set_color(0.8f, 0.8f, 0.8f, 1.0f);
|
|
|
style.set_type(PGFrameStyle::T_bevel_out);
|
|
style.set_type(PGFrameStyle::T_bevel_out);
|
|
|
- _slider->set_frame_style(PGButton::S_ready, style);
|
|
|
|
|
- style.set_type(PGFrameStyle::T_bevel_in);
|
|
|
|
|
- _slider->set_frame_style(PGButton::S_depressed, style);
|
|
|
|
|
|
|
+ style.set_width(bevel, bevel);
|
|
|
|
|
+
|
|
|
|
|
+ // Remove the button nodes created by a previous call to setup(), if
|
|
|
|
|
+ // any.
|
|
|
|
|
+ if (_thumb_button != (PGButton *)NULL) {
|
|
|
|
|
+ remove_child(_thumb_button);
|
|
|
|
|
+ set_thumb_button(NULL);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (_left_button != (PGButton *)NULL) {
|
|
|
|
|
+ remove_child(_left_button);
|
|
|
|
|
+ set_left_button(NULL);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (_right_button != (PGButton *)NULL) {
|
|
|
|
|
+ remove_child(_right_button);
|
|
|
|
|
+ set_right_button(NULL);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ PT(PGButton) thumb = new PGButton("thumb");
|
|
|
|
|
+ thumb->setup("", bevel);
|
|
|
|
|
+ thumb->set_frame(-width / 2.0f, width / 2.0f,
|
|
|
|
|
+ -width / 2.0f, width / 2.0f);
|
|
|
|
|
+ add_child(thumb);
|
|
|
|
|
+ set_thumb_button(thumb);
|
|
|
|
|
+
|
|
|
|
|
+ PT(PGButton) left = new PGButton("left");
|
|
|
|
|
+ left->setup("", bevel);
|
|
|
|
|
+ left->set_frame(-width / 2.0f, width / 2.0f,
|
|
|
|
|
+ -width / 2.0f, width / 2.0f);
|
|
|
|
|
+ left->set_transform(TransformState::make_pos(((width - length) / 2.0f) * _axis));
|
|
|
|
|
+ add_child(left);
|
|
|
|
|
+ set_left_button(left);
|
|
|
|
|
+
|
|
|
|
|
+ PT(PGButton) right = new PGButton("right");
|
|
|
|
|
+ right->setup("", bevel);
|
|
|
|
|
+ right->set_frame(-width / 2.0f, width / 2.0f,
|
|
|
|
|
+ -width / 2.0f, width / 2.0f);
|
|
|
|
|
+ right->set_transform(TransformState::make_pos(((length - width) / 2.0f) * _axis));
|
|
|
|
|
+ add_child(right);
|
|
|
|
|
+ set_right_button(right);
|
|
|
|
|
+
|
|
|
|
|
+ set_resize_thumb(true);
|
|
|
|
|
+ set_manage_pieces(true);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
-// Function: PGSliderBar::press
|
|
|
|
|
-// Access: Public, Virtual
|
|
|
|
|
-// Description: This is a callback hook function, called whenever a
|
|
|
|
|
-// mouse or keyboard button is depressed while the mouse
|
|
|
|
|
-// is within the region.
|
|
|
|
|
|
|
+// Function: PGSliderBar::setup_slider
|
|
|
|
|
+// Access: Published
|
|
|
|
|
+// Description: Creates PGSliderBar that represents a slider that the
|
|
|
|
|
+// user can use to control an analog quantity.
|
|
|
|
|
+//
|
|
|
|
|
+// This is functionally the same as a scroll bar, but it
|
|
|
|
|
+// has a distinctive look.
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
void PGSliderBar::
|
|
void PGSliderBar::
|
|
|
-press(const MouseWatcherParameter ¶m, bool background) {
|
|
|
|
|
- PGItem::press(param, background);
|
|
|
|
|
- //pgui_cat.info() << get_name() << "::" << param << endl;
|
|
|
|
|
- //pgui_cat.info() << _slider->get_name() << "::press:x" << _slider_button.get_x()
|
|
|
|
|
- // << " press:y" << _slider_button.get_y() << endl;
|
|
|
|
|
-
|
|
|
|
|
- // translate the mouse param position into frame space
|
|
|
|
|
- LPoint2f mouse_point = param.get_mouse();
|
|
|
|
|
- LVector3f result(mouse_point[0], mouse_point[1], 0);
|
|
|
|
|
- result = get_frame_inv_xform().xform_point(result);
|
|
|
|
|
- _update_slider = true;
|
|
|
|
|
- _update_x = result[0];
|
|
|
|
|
- _update_y = result[1];
|
|
|
|
|
- //_slider_button.set_x(result[0]);
|
|
|
|
|
|
|
+setup_slider(bool vertical, float length, float width, float bevel) {
|
|
|
|
|
+ set_state(0);
|
|
|
|
|
+ clear_state_def(0);
|
|
|
|
|
+
|
|
|
|
|
+ if (vertical) {
|
|
|
|
|
+ set_frame(-width / 2.0f, width / 2.0f, -length / 2.0f, length / 2.0f);
|
|
|
|
|
+ _axis = LVector3f::rfu(0.0f, 0.0f, -1.0f);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ set_frame(-length / 2.0f, length / 2.0f, -width / 2.0f, width / 2.0f);
|
|
|
|
|
+ _axis = LVector3f::rfu(1.0f, 0.0f, 0.0f);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ PGFrameStyle style;
|
|
|
|
|
+ style.set_color(0.6f, 0.6f, 0.6f, 1.0f);
|
|
|
|
|
+ style.set_type(PGFrameStyle::T_flat);
|
|
|
|
|
+ style.set_visible_scale(1.0f, 0.25f);
|
|
|
|
|
+ style.set_width(bevel, bevel);
|
|
|
|
|
+ set_frame_style(0, style);
|
|
|
|
|
+
|
|
|
|
|
+ // Remove the button nodes created by a previous call to setup(), if
|
|
|
|
|
+ // any.
|
|
|
|
|
+ if (_thumb_button != (PGButton *)NULL) {
|
|
|
|
|
+ remove_child(_thumb_button);
|
|
|
|
|
+ set_thumb_button(NULL);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (_left_button != (PGButton *)NULL) {
|
|
|
|
|
+ remove_child(_left_button);
|
|
|
|
|
+ set_left_button(NULL);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (_right_button != (PGButton *)NULL) {
|
|
|
|
|
+ remove_child(_right_button);
|
|
|
|
|
+ set_right_button(NULL);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ PT(PGButton) thumb = new PGButton("thumb");
|
|
|
|
|
+ thumb->setup(" ", bevel);
|
|
|
|
|
+ thumb->set_frame(-width / 4.0f, width / 4.0f,
|
|
|
|
|
+ -width / 2.0f, width / 2.0f);
|
|
|
|
|
+ add_child(thumb);
|
|
|
|
|
+ set_thumb_button(thumb);
|
|
|
|
|
+
|
|
|
|
|
+ set_resize_thumb(false);
|
|
|
|
|
+ set_manage_pieces(true);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
-// Function: PGSliderBar::drag
|
|
|
|
|
-// Access: Public, Virtual
|
|
|
|
|
-// Description: This is a hook function, called when the user
|
|
|
|
|
-// is trying to drag the slider button
|
|
|
|
|
|
|
+// Function: PGSliderBar::set_active
|
|
|
|
|
+// Access: Published, Virtual
|
|
|
|
|
+// Description: Sets whether the PGItem is active for mouse watching.
|
|
|
|
|
+// This is not necessarily related to the
|
|
|
|
|
+// active/inactive appearance of the item, which is
|
|
|
|
|
+// controlled by set_state(), but it does affect whether
|
|
|
|
|
+// it responds to mouse events.
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
void PGSliderBar::
|
|
void PGSliderBar::
|
|
|
-drag(const MouseWatcherParameter ¶m) {
|
|
|
|
|
- //pgui_cat.info() << get_name() << "::" << param << endl;
|
|
|
|
|
- //pgui_cat.info() << _slider->get_name() << "::drag:x" << _slider_button.get_x()
|
|
|
|
|
- // <<" drag:y" << _slider_button.get_y() << endl;
|
|
|
|
|
-
|
|
|
|
|
- // translate the mouse param position into frame space
|
|
|
|
|
- LPoint2f mouse_point = param.get_mouse();
|
|
|
|
|
- LVector3f result(mouse_point[0], mouse_point[1], 0);
|
|
|
|
|
- result = get_frame_inv_xform().xform_point(result);
|
|
|
|
|
- // keep the slider button within slider bar
|
|
|
|
|
- if (result[0] < -_width)
|
|
|
|
|
- result[0] = -_width;
|
|
|
|
|
- if (result[0] > _width)
|
|
|
|
|
- result[0] = _width;
|
|
|
|
|
- _update_slider = true;
|
|
|
|
|
- _update_x = result[0];
|
|
|
|
|
- _update_y = result[1];
|
|
|
|
|
- //_slider_button.set_x(result[0]);
|
|
|
|
|
|
|
+set_active(bool active) {
|
|
|
|
|
+ PGItem::set_active(active);
|
|
|
|
|
+
|
|
|
|
|
+ // This also implicitly sets the managed pieces.
|
|
|
|
|
+ if (_thumb_button != (PGButton *)NULL) {
|
|
|
|
|
+ _thumb_button->set_active(active);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (_left_button != (PGButton *)NULL) {
|
|
|
|
|
+ _left_button->set_active(active);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (_right_button != (PGButton *)NULL) {
|
|
|
|
|
+ _right_button->set_active(active);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
-// Function: PGSliderBar::update
|
|
|
|
|
-// Access: Private
|
|
|
|
|
-// Description: Computes the appropriate size of the bar frame
|
|
|
|
|
-// according to the percentage completed.
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
|
|
-void PGSliderBar::
|
|
|
|
|
-update() {
|
|
|
|
|
- // int state = get_state();
|
|
|
|
|
-
|
|
|
|
|
- // need left and right button input if they exist
|
|
|
|
|
- if (!_slider_only) {
|
|
|
|
|
- // Handle left and right button presses
|
|
|
|
|
- if (_left.is_button_down()) {
|
|
|
|
|
- // move the slider to the left
|
|
|
|
|
- float x = _slider_button.get_x() - _speed;
|
|
|
|
|
- _update_slider = true;
|
|
|
|
|
- _update_x = max(x, -_width);
|
|
|
|
|
- //_slider_button.set_x(max(x, -_width));
|
|
|
|
|
|
|
+// Function: PGSliderBar::remanage
|
|
|
|
|
+// Access: Published
|
|
|
|
|
+// Description: Manages the position and size of the scroll bars and
|
|
|
|
|
+// the thumb. Normally this should not need to be
|
|
|
|
|
+// called directly.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+remanage() {
|
|
|
|
|
+ _needs_remanage = false;
|
|
|
|
|
+
|
|
|
|
|
+ const LVecBase4f &frame = get_frame();
|
|
|
|
|
+
|
|
|
|
|
+ float width, length;
|
|
|
|
|
+ if (fabs(_axis[0]) > fabs(_axis[1] + _axis[2])) {
|
|
|
|
|
+ // The slider is X-dominant.
|
|
|
|
|
+ width = frame[3] - frame[2];
|
|
|
|
|
+ length = frame[1] - frame[0];
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // The slider is Y-dominant.
|
|
|
|
|
+ width = frame[1] - frame[0];
|
|
|
|
|
+ length = frame[3] - frame[2];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ LVector3f center = LVector3f::rfu((frame[0] + frame[1]) / 2.0f,
|
|
|
|
|
+ 0.0f,
|
|
|
|
|
+ (frame[2] + frame[3]) / 2.0f);
|
|
|
|
|
+
|
|
|
|
|
+ if (_left_button != (PGButton *)NULL) {
|
|
|
|
|
+ _left_button->set_frame(-width / 2.0f, width / 2.0f,
|
|
|
|
|
+ -width / 2.0f, width / 2.0f);
|
|
|
|
|
+ _left_button->xform(LMatrix4f::translate_mat(center + ((width - length) / 2.0f) * _axis));
|
|
|
|
|
+ _left_button->clear_transform();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (_right_button != (PGButton *)NULL) {
|
|
|
|
|
+ _right_button->set_frame(-width / 2.0f, width / 2.0f,
|
|
|
|
|
+ -width / 2.0f, width / 2.0f);
|
|
|
|
|
+ _right_button->xform(LMatrix4f::translate_mat(center + ((length - width) / 2.0f) * _axis));
|
|
|
|
|
+ _right_button->clear_transform();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (_thumb_button != (PGButton *)NULL) {
|
|
|
|
|
+ _thumb_button->set_frame(-width / 2.0f, width / 2.0f,
|
|
|
|
|
+ -width / 2.0f, width / 2.0f);
|
|
|
|
|
+ _thumb_button->set_transform(TransformState::make_pos(center));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ recompute();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::recompute
|
|
|
|
|
+// Access: Published
|
|
|
|
|
+// Description: Recomputes the position and size of the thumb.
|
|
|
|
|
+// Normally this should not need to be called directly.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+recompute() {
|
|
|
|
|
+ _needs_recompute = false;
|
|
|
|
|
+
|
|
|
|
|
+ if (_min_value != _max_value) {
|
|
|
|
|
+ _scroll_ratio = fabs(_scroll_value / (_max_value - _min_value));
|
|
|
|
|
+ _page_ratio = fabs(_page_value / (_max_value - _min_value));
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ _scroll_ratio = 0.0f;
|
|
|
|
|
+ _page_ratio = 0.0f;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ LVecBase4f frame = get_frame();
|
|
|
|
|
+ reduce_region(frame, _left_button);
|
|
|
|
|
+ reduce_region(frame, _right_button);
|
|
|
|
|
+
|
|
|
|
|
+ if (fabs(_axis[0]) > fabs(_axis[1] + _axis[2])) {
|
|
|
|
|
+ // The slider is X-dominant.
|
|
|
|
|
+
|
|
|
|
|
+ _min_x = frame[0];
|
|
|
|
|
+ _max_x = frame[1];
|
|
|
|
|
+
|
|
|
|
|
+ float trough_width = _max_x - _min_x;
|
|
|
|
|
+
|
|
|
|
|
+ if (_thumb_button != (PGButton *)NULL) {
|
|
|
|
|
+ const LVecBase4f &thumb_frame = _thumb_button->get_frame();
|
|
|
|
|
+
|
|
|
|
|
+ if (_resize_thumb) {
|
|
|
|
|
+ // If we're allowed to adjust the thumb's size, we don't need to
|
|
|
|
|
+ // find out how wide it is.
|
|
|
|
|
+ _thumb_width = trough_width * min(1.0f, _page_ratio);
|
|
|
|
|
+ _thumb_button->set_frame(-_thumb_width / 2.0f, _thumb_width / 2.0f,
|
|
|
|
|
+ thumb_frame[2], thumb_frame[3]);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // If we're not adjusting the thumb's size, we do need to know
|
|
|
|
|
+ // its current width.
|
|
|
|
|
+ _thumb_width = thumb_frame[1] - thumb_frame[0];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ _range_x = trough_width - _thumb_width;
|
|
|
|
|
+
|
|
|
|
|
+ const LVecBase4f &thumb_frame = _thumb_button->get_frame();
|
|
|
|
|
+ if (_axis[0] >= 0.0f) {
|
|
|
|
|
+ // The slider runs forwards, left to right.
|
|
|
|
|
+ _thumb_start = (_min_x - thumb_frame[0]) * _axis;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // The slider runs backwards: right to left.
|
|
|
|
|
+ _thumb_start = (thumb_frame[1] - _max_x) * _axis;
|
|
|
|
|
+ }
|
|
|
|
|
+ _thumb_start += LVector3f::rfu(0.0f, 0.0f, (frame[2] + frame[3]) / 2.0f);
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // The slider is Y-dominant. We call it X in the variable names,
|
|
|
|
|
+ // but it's really Y (or even Z).
|
|
|
|
|
+
|
|
|
|
|
+ _min_x = frame[2];
|
|
|
|
|
+ _max_x = frame[3];
|
|
|
|
|
+
|
|
|
|
|
+ float trough_width = _max_x - _min_x;
|
|
|
|
|
+
|
|
|
|
|
+ if (_thumb_button == (PGButton *)NULL) {
|
|
|
|
|
+ _thumb_width = 0.0f;
|
|
|
|
|
+ _range_x = 0.0f;
|
|
|
|
|
+ _thumb_start.set(0.0f, 0.0f, 0.0f);
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const LVecBase4f &thumb_frame = _thumb_button->get_frame();
|
|
|
|
|
+
|
|
|
|
|
+ if (_resize_thumb) {
|
|
|
|
|
+ // If we're allowed to adjust the thumb's size, we don't need to
|
|
|
|
|
+ // find out how wide it is.
|
|
|
|
|
+ _thumb_width = trough_width * min(1.0f, _page_ratio);
|
|
|
|
|
+ _thumb_button->set_frame(thumb_frame[0], thumb_frame[1],
|
|
|
|
|
+ -_thumb_width / 2.0f, _thumb_width / 2.0f);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // If we're not adjusting the thumb's size, we do need to know
|
|
|
|
|
+ // its current width.
|
|
|
|
|
+ _thumb_width = thumb_frame[3] - thumb_frame[2];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ _range_x = trough_width - _thumb_width;
|
|
|
|
|
+
|
|
|
|
|
+ if (_axis[1] >= 0.0f && _axis[2] >= 0.0f) {
|
|
|
|
|
+ // The slider runs forwards, bottom to top.
|
|
|
|
|
+ _thumb_start = (_min_x - thumb_frame[2]) * _axis;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // The slider runs backwards: top to bottom.
|
|
|
|
|
+ _thumb_start = (thumb_frame[3] - _max_x) * _axis;
|
|
|
|
|
+ }
|
|
|
|
|
+ _thumb_start += LVector3f::rfu((frame[0] + frame[1]) / 2.0f, 0.0f, 0.0f);
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (_right.is_button_down()) {
|
|
|
|
|
- // move the slider to the right
|
|
|
|
|
- float x = _slider_button.get_x() + _speed;
|
|
|
|
|
- _update_slider = true;
|
|
|
|
|
- _update_x = min(x, _width);
|
|
|
|
|
- //_slider_button.set_x(min(x, _width));
|
|
|
|
|
|
|
+ reposition();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::frame_changed
|
|
|
|
|
+// Access: Protected, Virtual
|
|
|
|
|
+// Description: Called when the user changes the frame size.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+frame_changed() {
|
|
|
|
|
+ PGItem::frame_changed();
|
|
|
|
|
+ _needs_remanage = true;
|
|
|
|
|
+ _needs_recompute = true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::item_transform_changed
|
|
|
|
|
+// Access: Protected, Virtual
|
|
|
|
|
+// Description: Called whenever a watched PGItem's local transform
|
|
|
|
|
+// has been changed.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+item_transform_changed(PGItem *) {
|
|
|
|
|
+ _needs_recompute = true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::item_frame_changed
|
|
|
|
|
+// Access: Protected, Virtual
|
|
|
|
|
+// Description: Called whenever a watched PGItem's frame
|
|
|
|
|
+// has been changed.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+item_frame_changed(PGItem *) {
|
|
|
|
|
+ _needs_recompute = true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::item_draw_mask_changed
|
|
|
|
|
+// Access: Protected, Virtual
|
|
|
|
|
+// Description: Called whenever a watched PGItem's draw_mask
|
|
|
|
|
+// has been changed.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+item_draw_mask_changed(PGItem *) {
|
|
|
|
|
+ _needs_recompute = true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::item_press
|
|
|
|
|
+// Access: Protected, Virtual
|
|
|
|
|
+// Description: Called whenever the "press" event is triggered on a
|
|
|
|
|
+// watched PGItem. See PGItem::press().
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+item_press(PGItem *item, const MouseWatcherParameter ¶m) {
|
|
|
|
|
+ if (param.has_mouse()) {
|
|
|
|
|
+ _mouse_pos = param.get_mouse();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (item == _left_button || item == _right_button) {
|
|
|
|
|
+ _scroll_button_held = item;
|
|
|
|
|
+ _mouse_button_page = false;
|
|
|
|
|
+ advance_scroll();
|
|
|
|
|
+ _next_advance_time =
|
|
|
|
|
+ ClockObject::get_global_clock()->get_frame_time() + scroll_initial_delay;
|
|
|
|
|
+
|
|
|
|
|
+ } else if (item == _thumb_button) {
|
|
|
|
|
+ _scroll_button_held = NULL;
|
|
|
|
|
+ begin_drag();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::item_release
|
|
|
|
|
+// Access: Protected, Virtual
|
|
|
|
|
+// Description: Called whenever the "release" event is triggered on a
|
|
|
|
|
+// watched PGItem. See PGItem::release().
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+item_release(PGItem *item, const MouseWatcherParameter &) {
|
|
|
|
|
+ if (item == _scroll_button_held) {
|
|
|
|
|
+ _scroll_button_held = NULL;
|
|
|
|
|
+
|
|
|
|
|
+ } else if (item == _thumb_button) {
|
|
|
|
|
+ _scroll_button_held = NULL;
|
|
|
|
|
+ if (_dragging) {
|
|
|
|
|
+ end_drag();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::item_move
|
|
|
|
|
+// Access: Protected, Virtual
|
|
|
|
|
+// Description: Called whenever the "move" event is triggered on a
|
|
|
|
|
+// watched PGItem. See PGItem::move().
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+item_move(PGItem *item, const MouseWatcherParameter ¶m) {
|
|
|
|
|
+ _mouse_pos = param.get_mouse();
|
|
|
|
|
+ if (item == _thumb_button) {
|
|
|
|
|
+ if (_dragging) {
|
|
|
|
|
+ continue_drag();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::reposition
|
|
|
|
|
+// Access: Private
|
|
|
|
|
+// Description: A lighter-weight version of recompute(), this just
|
|
|
|
|
+// moves the thumb, assuming all other properties are
|
|
|
|
|
+// unchanged.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+reposition() {
|
|
|
|
|
+ _needs_reposition = false;
|
|
|
|
|
+
|
|
|
|
|
+ float t = get_ratio();
|
|
|
|
|
+
|
|
|
|
|
+ if (_thumb_button != (PGButton *)NULL) {
|
|
|
|
|
+ _thumb_button->set_transform(TransformState::make_pos((t * _range_x) * _axis + _thumb_start));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- // press() and drag() update schedules this values that need to be
|
|
|
|
|
- // applied here so that value of current slider position as a ratio
|
|
|
|
|
- // of range can be updated
|
|
|
|
|
- if (_update_slider) {
|
|
|
|
|
- //pgui_cat.info() << "mouse_point:x " << _update_x
|
|
|
|
|
- // << " mouse_point:y " << _update_y << endl;
|
|
|
|
|
- if (!_slider_button.is_empty())
|
|
|
|
|
- _slider_button.set_x(_update_x);
|
|
|
|
|
- _mapped_value = (_update_x + _width)/(2*_width);
|
|
|
|
|
- _value = _negative_mapping ? ((_mapped_value-0.5)*2) : _mapped_value;
|
|
|
|
|
- _update_slider = false;
|
|
|
|
|
- throw_event(get_click_event());
|
|
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::advance_scroll
|
|
|
|
|
+// Access: Private
|
|
|
|
|
+// Description: Advances the scroll bar by one unit in the left or
|
|
|
|
|
+// right direction while the user is holding down the
|
|
|
|
|
+// left or right scroll button.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+advance_scroll() {
|
|
|
|
|
+ if (_scroll_button_held == _left_button) {
|
|
|
|
|
+ set_ratio(max(_ratio - _scroll_ratio, 0.0f));
|
|
|
|
|
+
|
|
|
|
|
+ } else if (_scroll_button_held == _right_button) {
|
|
|
|
|
+ set_ratio(min(_ratio + _scroll_ratio, 1.0f));
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ _next_advance_time =
|
|
|
|
|
+ ClockObject::get_global_clock()->get_frame_time() + scroll_continued_delay;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::advance_page
|
|
|
|
|
+// Access: Private
|
|
|
|
|
+// Description: Advances the scroll bar by one page in the left or
|
|
|
|
|
+// right direction while the user is holding down the
|
|
|
|
|
+// mouse button on the track.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+advance_page() {
|
|
|
|
|
+ // Is the mouse position left or right of the current thumb
|
|
|
|
|
+ // position?
|
|
|
|
|
+ LPoint3f mouse = mouse_to_local(_mouse_pos) - _thumb_start;
|
|
|
|
|
+ float target_ratio = mouse.dot(_axis) / _range_x;
|
|
|
|
|
+
|
|
|
|
|
+ float t;
|
|
|
|
|
+ if (target_ratio < _ratio) {
|
|
|
|
|
+ t = max(_ratio - _page_ratio + _scroll_ratio, target_ratio);
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ t = min(_ratio + _page_ratio - _scroll_ratio, target_ratio);
|
|
|
|
|
+ }
|
|
|
|
|
+ set_ratio(t);
|
|
|
|
|
+ if (t == target_ratio) {
|
|
|
|
|
+ // We made it; begin dragging from now on until the user releases
|
|
|
|
|
+ // the mouse.
|
|
|
|
|
+ begin_drag();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ _next_advance_time =
|
|
|
|
|
+ ClockObject::get_global_clock()->get_frame_time() + scroll_continued_delay;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::begin_drag
|
|
|
|
|
+// Access: Private
|
|
|
|
|
+// Description: Called when the user clicks down on the thumb button,
|
|
|
|
|
+// possibly to begin dragging.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+begin_drag() {
|
|
|
|
|
+ if (_needs_recompute) {
|
|
|
|
|
+ recompute();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (_range_x != 0.0f) {
|
|
|
|
|
+ float current_x = mouse_to_local(_mouse_pos).dot(_axis);
|
|
|
|
|
+ _drag_start_x = current_x - get_ratio() * _range_x;
|
|
|
|
|
+ _dragging = true;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::continue_drag
|
|
|
|
|
+// Access: Private
|
|
|
|
|
+// Description: Called as the user moves the mouse while still
|
|
|
|
|
+// dragging on the thumb button.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+continue_drag() {
|
|
|
|
|
+ if (_needs_recompute) {
|
|
|
|
|
+ recompute();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (_range_x != 0.0f) {
|
|
|
|
|
+ float current_x = mouse_to_local(_mouse_pos).dot(_axis);
|
|
|
|
|
+ set_ratio((current_x - _drag_start_x) / _range_x);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+// Function: PGSliderBar::end_drag
|
|
|
|
|
+// Access: Private
|
|
|
|
|
+// Description: Called as the user releases the mouse after dragging.
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
|
|
+void PGSliderBar::
|
|
|
|
|
+end_drag() {
|
|
|
|
|
+ _dragging = false;
|
|
|
}
|
|
}
|