浏览代码

first pass: slider bar gui implemented

Asad M. Zaman 21 年之前
父节点
当前提交
78c010ba01

+ 5 - 0
panda/src/event/buttonEvent.h

@@ -78,6 +78,11 @@ public:
     // and has in the process of selecting some possible text to type
     // from a menu.
     T_candidate,
+
+    // T_move is used to indicate that the mouse has moved within the 
+    // current region. Button drag mode needs this, others may ignore
+    // this event
+    T_move,
   };
 
   INLINE ButtonEvent();

+ 9 - 3
panda/src/pgui/Sources.pp

@@ -12,6 +12,7 @@
   #define SOURCES  \
     config_pgui.h \
     pgButton.I pgButton.h \
+    pgSliderButton.I pgSliderButton.h \
     pgCullTraverser.I pgCullTraverser.h \
     pgEntry.I pgEntry.h \
     pgMouseWatcherGroup.I pgMouseWatcherGroup.h \
@@ -21,11 +22,13 @@
     pgMouseWatcherBackground.h \
     pgMouseWatcherRegion.I pgMouseWatcherRegion.h \
     pgTop.I pgTop.h \
-    pgWaitBar.I pgWaitBar.h
+    pgWaitBar.I pgWaitBar.h \
+    pgSliderBar.I pgSliderBar.h
     
   #define INCLUDED_SOURCES  \
     config_pgui.cxx \
     pgButton.cxx \
+    pgSliderButton.cxx \
     pgCullTraverser.cxx \
     pgEntry.cxx \
     pgMouseWatcherGroup.cxx \
@@ -35,10 +38,12 @@
     pgMouseWatcherBackground.cxx \
     pgMouseWatcherRegion.cxx \
     pgTop.cxx \
-    pgWaitBar.cxx
+    pgWaitBar.cxx \
+    pgSliderBar.cxx
 
   #define INSTALL_HEADERS \
     pgButton.I pgButton.h \
+    pgSliderButton.I pgSliderButton.h \
     pgCullTraverser.I pgCullTraverser.h \
     pgEntry.I pgEntry.h \
     pgMouseWatcherGroup.I pgMouseWatcherGroup.h \
@@ -48,7 +53,8 @@
     pgMouseWatcherBackground.h \
     pgMouseWatcherRegion.I pgMouseWatcherRegion.h \
     pgTop.I pgTop.h \
-    pgWaitBar.I pgWaitBar.h
+    pgWaitBar.I pgWaitBar.h \
+    pgSliderBar.I pgSliderBar.h
     
 
   #define IGATESCAN all

+ 4 - 0
panda/src/pgui/config_pgui.cxx

@@ -18,6 +18,7 @@
 
 #include "config_pgui.h"
 #include "pgButton.h"
+#include "pgSliderButton.h"
 #include "pgCullTraverser.h"
 #include "pgEntry.h"
 #include "pgMouseWatcherParameter.h"
@@ -27,6 +28,7 @@
 #include "pgMouseWatcherRegion.h"
 #include "pgTop.h"
 #include "pgWaitBar.h"
+#include "pgSliderBar.h"
 
 #include "dconfig.h"
 
@@ -60,6 +62,7 @@ init_libpgui() {
   initialized = true;
 
   PGButton::init_type();
+  PGSliderButton::init_type();
   PGCullTraverser::init_type();
   PGEntry::init_type();
   PGMouseWatcherParameter::init_type();
@@ -69,4 +72,5 @@ init_libpgui() {
   PGMouseWatcherRegion::init_type();
   PGTop::init_type();
   PGWaitBar::init_type();
+  PGSliderBar::init_type();
 }

+ 10 - 0
panda/src/pgui/pgButton.I

@@ -73,3 +73,13 @@ INLINE string PGButton::
 get_click_event(const ButtonHandle &button) const {
   return "click-" + button.get_name() + "-" + get_id();
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGButton::is_button_down
+//       Access: Published
+//  Description: Returns if the value of button_down
+////////////////////////////////////////////////////////////////////
+INLINE bool PGButton::
+is_button_down() {
+  return _button_down;
+}

+ 12 - 0
panda/src/pgui/pgButton.cxx

@@ -158,6 +158,18 @@ click(const MouseWatcherParameter &param) {
   throw_event(event, EventParameter(ep));
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: PGButton::move
+//       Access: Public, Virtual
+//  Description: This is a callback hook function, called whenever a
+//               mouse is moved while the mouse
+//               is within the region.
+////////////////////////////////////////////////////////////////////
+void PGButton::
+move(const MouseWatcherParameter &param) {
+  PGItem::move(param);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: PGButton::setup
 //       Access: Published

+ 7 - 3
panda/src/pgui/pgButton.h

@@ -37,9 +37,6 @@ PUBLISHED:
   PGButton(const string &name);
   virtual ~PGButton();
 
-protected:
-  PGButton(const PGButton &copy);
-
 public:
   virtual PandaNode *make_copy() const;
 
@@ -49,6 +46,10 @@ public:
   virtual void release(const MouseWatcherParameter &param, bool background);
 
   virtual void click(const MouseWatcherParameter &param);
+  
+  virtual void move(const MouseWatcherParameter &param);
+
+  PGButton(const PGButton &copy);
 
 PUBLISHED:
   enum State {
@@ -72,6 +73,8 @@ PUBLISHED:
   bool remove_click_button(const ButtonHandle &button);
   bool has_click_button(const ButtonHandle &button);
 
+  INLINE bool is_button_down();
+
   INLINE static string get_click_prefix();
   INLINE string get_click_event(const ButtonHandle &button) const;
 
@@ -97,6 +100,7 @@ public:
 
 private:
   static TypeHandle _type_handle;
+
 };
 
 #include "pgButton.I"

+ 10 - 0
panda/src/pgui/pgItem.I

@@ -466,3 +466,13 @@ INLINE PGItem *PGItem::
 get_focus_item() {
   return _focus_item;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGItem::get_frame_inv_xform
+//       Access: Published, Static
+//  Description: Returns the inverse of the frame transform matrix
+////////////////////////////////////////////////////////////////////
+INLINE LMatrix4f PGItem::
+get_frame_inv_xform() const {
+  return _frame_inv_xform;
+}

+ 28 - 1
panda/src/pgui/pgItem.cxx

@@ -297,6 +297,10 @@ activate_region(const LMatrix4f &transform, int sort) {
                      
   _region->set_sort(sort);
   _region->set_active(true);
+
+  // calculate the inverse of this transform, which is needed to 
+  // go back to the frame space.
+  _frame_inv_xform.invert_from(transform);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -314,6 +318,7 @@ enter(const MouseWatcherParameter &param) {
   string event = get_enter_event();
   play_sound(event);
   throw_event(event, EventParameter(ep));
+  //pgui_cat.info() << get_name() << "::enter()" << endl;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -331,6 +336,7 @@ exit(const MouseWatcherParameter &param) {
   string event = get_exit_event();
   play_sound(event);
   throw_event(event, EventParameter(ep));
+  //pgui_cat.info() << get_name() << "::exit()" << endl;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -349,6 +355,7 @@ within(const MouseWatcherParameter &param) {
   string event = get_within_event();
   play_sound(event);
   throw_event(event, EventParameter(ep));
+  //pgui_cat.info() << get_name() << "::within()" << endl;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -364,6 +371,7 @@ without(const MouseWatcherParameter &param) {
   string event = get_without_event();
   play_sound(event);
   throw_event(event, EventParameter(ep));
+  //pgui_cat.info() << get_name() << "::without()" << endl;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -377,6 +385,7 @@ focus_in() {
   string event = get_focus_in_event();
   play_sound(event);
   throw_event(event);
+  //pgui_cat.info() << get_name() << "::focus_in()" << endl;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -390,6 +399,7 @@ focus_out() {
   string event = get_focus_out_event();
   play_sound(event);
   throw_event(event);
+  //pgui_cat.info() << get_name() << "::focus_out()" << endl;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -407,6 +417,7 @@ press(const MouseWatcherParameter &param, bool background) {
     play_sound(event);
     throw_event(event, EventParameter(ep));
   }
+  //pgui_cat.info() << get_name() << "::press()" << endl;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -424,6 +435,7 @@ release(const MouseWatcherParameter &param, bool background) {
     play_sound(event);
     throw_event(event, EventParameter(ep));
   }
+  //pgui_cat.info() << get_name() << "::release()" << endl;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -443,7 +455,7 @@ keystroke(const MouseWatcherParameter &param, bool background) {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: PGItem::keystroke
+//     Function: PGItem::candidate
 //       Access: Public, Virtual
 //  Description: This is a callback hook function, called whenever
 //               the user highlights an option in the IME window.
@@ -453,6 +465,21 @@ candidate(const MouseWatcherParameter &param, bool background) {
   // We don't throw sound events for candidate selections for now.
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: PGItem::move
+//       Access: Public, Virtual
+//  Description: This is a callback hook function, called whenever a
+//               mouse is moved while within the region.
+////////////////////////////////////////////////////////////////////
+void PGItem::
+move(const MouseWatcherParameter &param) {
+  PGMouseWatcherParameter *ep = new PGMouseWatcherParameter(param);
+  string event = get_press_event(param.get_button());
+  play_sound(event);
+  throw_event(event, EventParameter(ep));
+  //pgui_cat.info() << get_name() << "::move()" << endl;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: PGItem::background_press
 //       Access: Public, Static

+ 5 - 0
panda/src/pgui/pgItem.h

@@ -79,6 +79,7 @@ public:
   virtual void release(const MouseWatcherParameter &param, bool background);
   virtual void keystroke(const MouseWatcherParameter &param, bool background);
   virtual void candidate(const MouseWatcherParameter &param, bool background);
+  virtual void move(const MouseWatcherParameter &param);
 
   static void background_press(const MouseWatcherParameter &param);
   static void background_release(const MouseWatcherParameter &param);
@@ -139,6 +140,8 @@ PUBLISHED:
   INLINE string get_release_event(const ButtonHandle &button) const;
   INLINE string get_keystroke_event() const;
 
+  INLINE LMatrix4f get_frame_inv_xform() const;
+
 #ifdef HAVE_AUDIO
   void set_sound(const string &event, AudioSound *sound);
   void clear_sound(const string &event);
@@ -171,6 +174,8 @@ private:
 
   PT(PGMouseWatcherRegion) _region;
 
+  LMatrix4f _frame_inv_xform;
+
   class StateDef {
   public:
     NodePath _root;

+ 13 - 0
panda/src/pgui/pgMouseWatcherRegion.cxx

@@ -164,3 +164,16 @@ candidate(const MouseWatcherParameter &param) {
     _item->candidate(param, false);
   }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGMouseWatcherRegion::move
+//       Access: Public, Virtual
+//  Description: This is a callback hook function, called whenever 
+//               the user moves the mouse within the region
+////////////////////////////////////////////////////////////////////
+void PGMouseWatcherRegion::
+move(const MouseWatcherParameter &param) {
+  if (_item != (PGItem *)NULL) {
+    _item->move(param);
+  }
+}

+ 1 - 0
panda/src/pgui/pgMouseWatcherRegion.h

@@ -45,6 +45,7 @@ public:
   virtual void release(const MouseWatcherParameter &param);
   virtual void keystroke(const MouseWatcherParameter &param);
   virtual void candidate(const MouseWatcherParameter &param);
+  virtual void move(const MouseWatcherParameter &param);
 
 private:
   PGItem *_item;

+ 148 - 0
panda/src/pgui/pgSliderBar.I

@@ -0,0 +1,148 @@
+// Filename: pgSliderBar.I
+// Created by:  masad (19Oct04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::set_range
+//       Access: Published
+//  Description: Sets the value at which the SliderBar indicates 100%.
+////////////////////////////////////////////////////////////////////
+INLINE void PGSliderBar:: 
+set_range(float range) {
+  _range = range;
+  _bar_state = -1;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::get_range
+//       Access: Published
+//  Description: Returns the value at which the SliderBar indicates 100%.
+////////////////////////////////////////////////////////////////////
+INLINE float PGSliderBar:: 
+get_range() const {
+  return _range;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::set_value
+//       Access: Published
+//  Description: Sets the current value of the bar.  This should range
+//               between 0 and get_range().
+////////////////////////////////////////////////////////////////////
+INLINE void PGSliderBar:: 
+set_value(float value) {
+  _value = value;
+  _bar_state = -1;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::get_value
+//       Access: Published
+//  Description: Returns the current value of the bar.
+////////////////////////////////////////////////////////////////////
+INLINE float PGSliderBar:: 
+get_value() const {
+  return _value;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::set_speed
+//       Access: Published
+//  Description: Sets the current speed at which the slider moves
+////////////////////////////////////////////////////////////////////
+INLINE void PGSliderBar:: 
+set_speed(float speed) {
+  _speed = speed;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::get_speed
+//       Access: Published
+//  Description: Returns the current speed at which the slider moves.
+////////////////////////////////////////////////////////////////////
+INLINE float PGSliderBar:: 
+get_speed() const {
+  return _speed;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::get_percent
+//       Access: Published
+//  Description: Returns the percentage complete.
+////////////////////////////////////////////////////////////////////
+INLINE float PGSliderBar:: 
+get_percent() const {
+  return (_value / _range) * 100.0f;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::set_bar_style
+//       Access: Published
+//  Description: Sets the kind of frame that is drawn on top of the
+//               SliderBar to represent the amount completed.
+////////////////////////////////////////////////////////////////////
+INLINE void PGSliderBar:: 
+set_bar_style(const PGFrameStyle &style) {
+  _bar_style = style;
+  _bar_state = -1;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::get_bar_style
+//       Access: Published
+//  Description: Returns the kind of frame that is drawn on top of the
+//               SliderBar to represent the amount completed.
+////////////////////////////////////////////////////////////////////
+INLINE PGFrameStyle PGSliderBar:: 
+get_bar_style() const {
+  return _bar_style;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::get_slider_button
+//       Access: Published
+//  Description: Returns the slider button that is drawn on the
+//               SliderBar to move the slider left or right 
+////////////////////////////////////////////////////////////////////
+INLINE NodePath PGSliderBar::
+get_slider_button() const {
+  return _slider_button;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::get_left_button
+//       Access: Published
+//  Description: Returns the left button that is drawn on left of the
+//               SliderBar to move the slider left
+////////////////////////////////////////////////////////////////////
+INLINE NodePath PGSliderBar::
+get_left_button() const {
+  return _left_button;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::get_right_button
+//       Access: Published
+//  Description: Returns the right button that is drawn on right of the
+//               SliderBar to move the slider right
+////////////////////////////////////////////////////////////////////
+INLINE NodePath PGSliderBar::
+get_right_button() const {
+  return _right_button;
+}
+

+ 247 - 0
panda/src/pgui/pgSliderBar.cxx

@@ -0,0 +1,247 @@
+// Filename: pgSliderBar.cxx
+// Created by:  masad (19Oct04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "pgSliderBar.h"
+#include "pgMouseWatcherParameter.h"
+
+#include "throw_event.h"
+
+TypeHandle PGSliderBar::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::Constructor
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+PGSliderBar::
+PGSliderBar(const string &name) :
+  PGItem(name),
+  _slider("slider"),
+  _left("left"),
+  _right("right")
+{
+  _range = 100.0;
+  _value = 0.0;
+  _speed = 0.05;
+  _bar_state = -1;
+  _update_slider = false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::Destructor
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+PGSliderBar::
+~PGSliderBar() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::Copy Constructor
+//       Access: Protected
+//  Description: 
+////////////////////////////////////////////////////////////////////
+PGSliderBar::
+PGSliderBar(const PGSliderBar &copy) :
+  PGItem(copy),
+  _range(copy._range),
+  _value(copy._value),
+  _slider(copy._slider),
+  _left(copy._left),
+  _right(copy._right)
+{
+  _bar_state = -1;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::make_copy
+//       Access: Public, Virtual
+//  Description: Returns a newly-allocated Node that is a shallow copy
+//               of this one.  It will be a different Node pointer,
+//               but its internal data may or may not be shared with
+//               that of the original Node.
+////////////////////////////////////////////////////////////////////
+PandaNode *PGSliderBar::
+make_copy() const {
+  return new PGSliderBar(*this);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::has_cull_callback
+//       Access: Protected, Virtual
+//  Description: Should be overridden by derived classes to return
+//               true if cull_callback() has been defined.  Otherwise,
+//               returns false to indicate cull_callback() does not
+//               need to be called for this node during the cull
+//               traversal.
+////////////////////////////////////////////////////////////////////
+bool PGSliderBar::
+has_cull_callback() const {
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::cull_callback
+//       Access: Protected, Virtual
+//  Description: If has_cull_callback() returns true, this function
+//               will be called during the cull traversal to perform
+//               any additional operations that should be performed at
+//               cull time.  This may include additional manipulation
+//               of render state or additional visible/invisible
+//               decisions, or any other arbitrary operation.
+//
+//               By the time this function is called, the node has
+//               already passed the bounding-volume test for the
+//               viewing frustum, and the node's transform and state
+//               have already been applied to the indicated
+//               CullTraverserData object.
+//
+//               The return value is true if this node should be
+//               visible, or false if it should be culled.
+////////////////////////////////////////////////////////////////////
+bool PGSliderBar::
+cull_callback(CullTraverser *trav, CullTraverserData &data) {
+  update();
+  return PGItem::cull_callback(trav, data);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::setup
+//       Access: Public
+//  Description: Creates a PGSliderBar with the indicated dimensions,
+//               with the indicated maximum range.
+////////////////////////////////////////////////////////////////////
+void PGSliderBar::
+setup(float width, float height, float range) {
+  set_state(0);
+  clear_state_def(0);
+
+  _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);
+
+  NodePath current = NodePath(this);
+  _slider_button = current.attach_new_node(&_slider);
+  _slider.set_slider_bar(this);
+  _left_button = current.attach_new_node(&_left);
+  _left.set_slider_bar(this);
+  _right_button = current.attach_new_node(&_right);
+  _right.set_slider_bar(this);
+  _slider.setup(_slider.get_name());
+  _slider.set_drag_n_drop(true);
+  _left.setup(_left.get_name());
+  _right.setup(_right.get_name());
+  _slider_button.set_scale(0.5);
+  _slider_button.set_pos(0, 0, -0.25);
+  _left_button.set_scale(0.5);
+  _left_button.set_pos(-6.0, 0, -0.25);
+  _right_button.set_scale(0.5);
+  _right_button.set_pos(5.5, 0, -0.25);
+
+  PGFrameStyle style;
+  style.set_width(0.05f, 0.05f);
+
+  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_color(0.8f, 0.8f, 0.8f, 1.0f);
+  style.set_type(PGFrameStyle::T_bevel_out);
+  set_bar_style(style);
+}
+
+////////////////////////////////////////////////////////////////////
+//     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 &param, bool background) {
+  PGItem::press(param, background);
+  //pgui_cat.info() << get_name() << "::" << param << endl;
+  //pgui_cat.info() << _slider.get_name() << "::" << _slider_button.get_x() << 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);
+  //pgui_cat.info() << "mouse_point: " << result << endl;
+  //_update_slider = true;
+  //_update_value = result[0];
+  _slider_button.set_x(result[0]);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderBar::drag
+//       Access: Public, Virtual
+//  Description: This is a hook function, called when the user 
+//               id trying to drag the slider button 
+////////////////////////////////////////////////////////////////////
+void PGSliderBar::
+drag(const MouseWatcherParameter &param) {
+  //pgui_cat.info() << get_name() << "::" << param << endl;
+  //pgui_cat.info() << _slider.get_name() << "::" << _slider_button.get_x() << 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;
+  //pgui_cat.info() << "mouse_point: " << result << endl;
+  //_update_slider = true;
+  //_update_value = result[0];
+  _slider_button.set_x(result[0]);
+}
+
+////////////////////////////////////////////////////////////////////
+//     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();
+
+  // Handle left and right button presses
+  if (_left.is_button_down()) {
+    // move the slider to the left
+    float x = _slider_button.get_x() - _speed;
+    _slider_button.set_x(max(x, -_width));
+  }
+
+  if (_right.is_button_down()) {
+    // move the slider to the right
+    float x = _slider_button.get_x() + _speed;
+    _slider_button.set_x(min(x, _width));
+  }
+
+  /*
+  // press() and drag() update schedules this values that need to be applied
+  // here so that it keeps integrity of the update regardless of bar orientation
+  if (_update_slider) {
+    _slider_button.set_x(_update_value);
+    _update_slider = false;
+  }
+  */
+}

+ 110 - 0
panda/src/pgui/pgSliderBar.h

@@ -0,0 +1,110 @@
+// Filename: pgSliderBar.h
+// Created by:  masad (19Oct04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef PGSLIDERBAR_H
+#define PGSLIDERBAR_H
+
+#include "pandabase.h"
+
+#include "pgItem.h"
+#include "pgSliderButton.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : PGSliderBar
+// Description : This is a particular kind of PGItem that draws a
+//               little bar with a slider that moves from left to 
+//               right indicating a value between the ranges
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA PGSliderBar : public PGItem {
+PUBLISHED:
+  PGSliderBar(const string &name = "");
+  virtual ~PGSliderBar();
+
+protected:
+  PGSliderBar(const PGSliderBar &copy);
+
+public:
+  virtual PandaNode *make_copy() const;
+  virtual bool has_cull_callback() const;
+  virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data);
+
+  virtual void press(const MouseWatcherParameter &param, bool background);
+  virtual void drag(const MouseWatcherParameter &param);
+
+PUBLISHED:
+  void setup(float width, float height, float range);
+
+  INLINE void set_range(float range);
+  INLINE float get_range() const;
+
+  INLINE void set_value(float value);
+  INLINE float get_value() const;
+
+  INLINE void set_speed(float speed);
+  INLINE float get_speed() const;
+
+  INLINE float get_percent() const;
+
+  INLINE void set_bar_style(const PGFrameStyle &style);
+  INLINE PGFrameStyle get_bar_style() const;
+
+  INLINE NodePath get_slider_button() const;
+  INLINE NodePath get_left_button() const;
+  INLINE NodePath get_right_button() const;
+
+private:
+  void update();
+
+  bool _update_slider;
+  float _update_value;
+
+  float _range, _value;
+  float _speed, _width;
+  int _bar_state;
+  PGFrameStyle _bar_style;
+  PGSliderButton _slider;
+  PGSliderButton _left;
+  PGSliderButton _right;
+  NodePath _bar;
+  NodePath _slider_button;
+  NodePath _left_button;
+  NodePath _right_button;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    PGItem::init_type();
+    register_type(_type_handle, "PGSliderBar",
+                  PGItem::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+
+  friend class PGButton;
+};
+
+#include "pgSliderBar.I"
+
+#endif

+ 48 - 0
panda/src/pgui/pgSliderButton.I

@@ -0,0 +1,48 @@
+// Filename: pgButton.I
+// Created by:  masad (21Oct04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderButton::is_drag_n_drop
+//       Access: Published
+//  Description: Returns if this button is drag_n_drop kind
+////////////////////////////////////////////////////////////////////
+INLINE bool PGSliderButton::
+is_drag_n_drop() {
+  return _drag_n_drop;
+}
+  INLINE bool is_drag_n_drop();
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderButton::set_drag_n_drop
+//       Access: Published
+//  Description: Makes this button a drag_n_drop kind
+////////////////////////////////////////////////////////////////////
+INLINE void PGSliderButton::
+set_drag_n_drop(bool value) {
+  _drag_n_drop = value;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderButton::set_slider_bar
+//       Access: Published
+//  Description: Store a copy of the controlling slider bar item
+////////////////////////////////////////////////////////////////////
+INLINE void PGSliderButton::
+set_slider_bar(PGItem *item) {
+  _slider_bar = item;
+}

+ 67 - 0
panda/src/pgui/pgSliderButton.cxx

@@ -0,0 +1,67 @@
+// Filename: pgSliderButton.cxx
+// Created by:  masad (21Oct04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "pgSliderButton.h"
+#include "pgSliderBar.h"
+#include "dcast.h"
+#include "pgMouseWatcherParameter.h"
+
+#include "throw_event.h"
+#include "mouseButton.h"
+#include "mouseWatcherParameter.h"
+#include "colorAttrib.h"
+#include "transformState.h"
+
+TypeHandle PGSliderButton::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderButton::Constructor
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+PGSliderButton::
+PGSliderButton(const string &name) : PGButton(name)
+{
+  _drag_n_drop = false;
+  _slider_bar = NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderButton::Destructor
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+PGSliderButton::
+~PGSliderButton() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PGSliderButton::move
+//       Access: Public, Virtual
+//  Description: This is a callback hook function, called whenever the
+//               button is dragged left or right  by the user normally.
+////////////////////////////////////////////////////////////////////
+void PGSliderButton::
+move(const MouseWatcherParameter &param) {
+  PGButton::move(param);
+  if (_drag_n_drop && is_button_down()) {
+    PGSliderBar *slider = DCAST(PGSliderBar, _slider_bar);
+    slider->drag(param);
+    //pgui_cat.info() << get_name() << "::move()" << endl;
+  }
+}

+ 75 - 0
panda/src/pgui/pgSliderButton.h

@@ -0,0 +1,75 @@
+// Filename: pgSliderButton.h
+// Created by:  masad (21Oct04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef PGSLIDERBUTTON_H
+#define PGSLIDERBUTTON_H
+
+#include "pandabase.h"
+
+#include "pgButton.h"
+#include "nodePath.h"
+#include "pset.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : PGSliderButton
+// Description : This is a particular kind of PGItem that is
+//               specialized to behave like a normal button object.
+//               It keeps track of its own state, and handles mouse
+//               events sensibly.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA PGSliderButton : public PGButton {
+PUBLISHED:
+  PGSliderButton(const string &name);
+  virtual ~PGSliderButton();
+
+public:
+
+  virtual void move(const MouseWatcherParameter &param);
+  
+PUBLISHED:
+
+  INLINE bool is_drag_n_drop();
+  INLINE void set_drag_n_drop(bool value);
+  INLINE void set_slider_bar(PGItem *item);
+
+public:
+  
+  bool _drag_n_drop;
+  PGItem *_slider_bar;
+
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    PGButton::init_type();
+    register_type(_type_handle, "PGSliderButton",
+                  PGButton::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+
+};
+
+#include "pgSliderButton.I"
+
+#endif

+ 1 - 0
panda/src/pgui/pgui_composite1.cxx

@@ -1,6 +1,7 @@
     
 #include "config_pgui.cxx"
 #include "pgButton.cxx"
+#include "pgSliderButton.cxx"
 #include "pgCullTraverser.cxx"
 #include "pgEntry.cxx"
 #include "pgMouseWatcherGroup.cxx"

+ 1 - 0
panda/src/pgui/pgui_composite2.cxx

@@ -5,4 +5,5 @@
 #include "pgMouseWatcherRegion.cxx"
 #include "pgTop.cxx"
 #include "pgWaitBar.cxx"
+#include "pgSliderBar.cxx"
 

+ 28 - 0
panda/src/tform/mouseWatcher.cxx

@@ -602,6 +602,23 @@ throw_event_pattern(const string &pattern, const MouseWatcherRegion *region,
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: MouseWatcher::move
+//       Access: Protected
+//  Description: Records the indicated mouse or keyboard button as
+//               being moved from last position.
+////////////////////////////////////////////////////////////////////
+void MouseWatcher::
+move(ButtonHandle button) {
+  MouseWatcherParameter param;
+  param.set_button(button);
+  param.set_modifier_buttons(_mods);
+  param.set_mouse(_mouse);
+
+  if (_preferred_button_down_region != (MouseWatcherRegion *)NULL)
+    _preferred_button_down_region->move(param);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: MouseWatcher::press
 //       Access: Protected
@@ -937,6 +954,7 @@ set_mouse(const LVecBase2f &xy, const LVecBase2f &pixel_xy) {
 ////////////////////////////////////////////////////////////////////
 void MouseWatcher::
 do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
+  bool mouse_moved = false;
   // Initially, we do not suppress any events to objects below us in
   // the data graph.
   _suppress_flags = 0;
@@ -954,6 +972,12 @@ do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
     const LVecBase2f &f = xy->get_value();
     const LVecBase2f &p = pixel_xy->get_value();
 
+    // Asad: determine if mouse moved from last position
+    const LVecBase2f &last_f = _xy->get_value();
+    if (f != last_f) {
+      mouse_moved = true;
+    }
+
     if (_display_region != (DisplayRegion *)NULL) {
       // If we've got a display region, constrain the mouse to it.
       int xo, yo, width, height;
@@ -1028,6 +1052,10 @@ do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
 
   if (_has_mouse &&
       (_suppress_flags & MouseWatcherRegion::SF_mouse_position) == 0) {
+    if (mouse_moved) {
+      move(ButtonHandle::none());
+      //tform_cat.info() << "do_transmit_data()::mouse_moved" << endl;
+    }
     // Transmit the mouse position.
     _xy->set_value(_mouse);
     output.set_data(_xy_output, EventParameter(_xy));

+ 1 - 0
panda/src/tform/mouseWatcher.h

@@ -136,6 +136,7 @@ protected:
                            const MouseWatcherRegion *region,
                            const ButtonHandle &button);
 
+  void move(ButtonHandle button);
   void press(ButtonHandle button);
   void release(ButtonHandle button);
   void keystroke(int keycode);

+ 10 - 0
panda/src/tform/mouseWatcherRegion.cxx

@@ -137,3 +137,13 @@ keystroke(const MouseWatcherParameter &) {
 void MouseWatcherRegion::
 candidate(const MouseWatcherParameter &) {
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: MouseWatcherRegion::move
+//       Access: Public, Virtual
+//  Description: This is a callback hook function, called whenever a
+//               mouse is moved within the region.
+////////////////////////////////////////////////////////////////////
+void MouseWatcherRegion::
+move(const MouseWatcherParameter &) {
+}

+ 1 - 0
panda/src/tform/mouseWatcherRegion.h

@@ -78,6 +78,7 @@ public:
   virtual void release(const MouseWatcherParameter &param);
   virtual void keystroke(const MouseWatcherParameter &param);
   virtual void candidate(const MouseWatcherParameter &param);
+  virtual void move(const MouseWatcherParameter &param);
 
 private:
   LVecBase4f _frame;