diff --git a/panda/src/event/buttonEvent.h b/panda/src/event/buttonEvent.h index 76c2a7e4f0..1fb0831352 100644 --- a/panda/src/event/buttonEvent.h +++ b/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(); diff --git a/panda/src/pgui/Sources.pp b/panda/src/pgui/Sources.pp index e8c367b597..192fc07090 100644 --- a/panda/src/pgui/Sources.pp +++ b/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 diff --git a/panda/src/pgui/config_pgui.cxx b/panda/src/pgui/config_pgui.cxx index 33645f3586..a331254956 100644 --- a/panda/src/pgui/config_pgui.cxx +++ b/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(); } diff --git a/panda/src/pgui/pgButton.I b/panda/src/pgui/pgButton.I index c402f7d4a4..3ab08255b9 100644 --- a/panda/src/pgui/pgButton.I +++ b/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; +} diff --git a/panda/src/pgui/pgButton.cxx b/panda/src/pgui/pgButton.cxx index 78aef83532..fbe0596035 100644 --- a/panda/src/pgui/pgButton.cxx +++ b/panda/src/pgui/pgButton.cxx @@ -158,6 +158,18 @@ click(const MouseWatcherParameter ¶m) { 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 ¶m) { + PGItem::move(param); +} + //////////////////////////////////////////////////////////////////// // Function: PGButton::setup // Access: Published diff --git a/panda/src/pgui/pgButton.h b/panda/src/pgui/pgButton.h index 53b2244365..4749132562 100644 --- a/panda/src/pgui/pgButton.h +++ b/panda/src/pgui/pgButton.h @@ -37,9 +37,6 @@ PUBLISHED: PGButton(const string &name); virtual ~PGButton(); -protected: - PGButton(const PGButton ©); - public: virtual PandaNode *make_copy() const; @@ -49,6 +46,10 @@ public: virtual void release(const MouseWatcherParameter ¶m, bool background); virtual void click(const MouseWatcherParameter ¶m); + + virtual void move(const MouseWatcherParameter ¶m); + + PGButton(const PGButton ©); 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" diff --git a/panda/src/pgui/pgItem.I b/panda/src/pgui/pgItem.I index ba0003f1a7..ec6666fe0d 100644 --- a/panda/src/pgui/pgItem.I +++ b/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; +} diff --git a/panda/src/pgui/pgItem.cxx b/panda/src/pgui/pgItem.cxx index 6b5d8345f2..d5a42fd3e5 100644 --- a/panda/src/pgui/pgItem.cxx +++ b/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 ¶m) { 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 ¶m) { 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 ¶m) { 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 ¶m) { 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 ¶m, bool background) { play_sound(event); throw_event(event, EventParameter(ep)); } + //pgui_cat.info() << get_name() << "::press()" << endl; } //////////////////////////////////////////////////////////////////// @@ -424,6 +435,7 @@ release(const MouseWatcherParameter ¶m, bool background) { play_sound(event); throw_event(event, EventParameter(ep)); } + //pgui_cat.info() << get_name() << "::release()" << endl; } //////////////////////////////////////////////////////////////////// @@ -443,7 +455,7 @@ keystroke(const MouseWatcherParameter ¶m, 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 ¶m, 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 ¶m) { + 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 diff --git a/panda/src/pgui/pgItem.h b/panda/src/pgui/pgItem.h index ce157dc690..8f7464886d 100644 --- a/panda/src/pgui/pgItem.h +++ b/panda/src/pgui/pgItem.h @@ -79,6 +79,7 @@ public: virtual void release(const MouseWatcherParameter ¶m, bool background); virtual void keystroke(const MouseWatcherParameter ¶m, bool background); virtual void candidate(const MouseWatcherParameter ¶m, bool background); + virtual void move(const MouseWatcherParameter ¶m); static void background_press(const MouseWatcherParameter ¶m); static void background_release(const MouseWatcherParameter ¶m); @@ -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; diff --git a/panda/src/pgui/pgMouseWatcherRegion.cxx b/panda/src/pgui/pgMouseWatcherRegion.cxx index ee8378abaf..c984bf9c87 100644 --- a/panda/src/pgui/pgMouseWatcherRegion.cxx +++ b/panda/src/pgui/pgMouseWatcherRegion.cxx @@ -164,3 +164,16 @@ candidate(const MouseWatcherParameter ¶m) { _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 ¶m) { + if (_item != (PGItem *)NULL) { + _item->move(param); + } +} diff --git a/panda/src/pgui/pgMouseWatcherRegion.h b/panda/src/pgui/pgMouseWatcherRegion.h index fb1c456d4b..6f84005537 100644 --- a/panda/src/pgui/pgMouseWatcherRegion.h +++ b/panda/src/pgui/pgMouseWatcherRegion.h @@ -45,6 +45,7 @@ public: virtual void release(const MouseWatcherParameter ¶m); virtual void keystroke(const MouseWatcherParameter ¶m); virtual void candidate(const MouseWatcherParameter ¶m); + virtual void move(const MouseWatcherParameter ¶m); private: PGItem *_item; diff --git a/panda/src/pgui/pgSliderBar.I b/panda/src/pgui/pgSliderBar.I new file mode 100755 index 0000000000..9d94d68969 --- /dev/null +++ b/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 +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// 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; +} + diff --git a/panda/src/pgui/pgSliderBar.cxx b/panda/src/pgui/pgSliderBar.cxx new file mode 100755 index 0000000000..37bd9828bd --- /dev/null +++ b/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 +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#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 ©) : + 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 ¶m, 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 ¶m) { + //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; + } + */ +} diff --git a/panda/src/pgui/pgSliderBar.h b/panda/src/pgui/pgSliderBar.h new file mode 100755 index 0000000000..3ba5205992 --- /dev/null +++ b/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 +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#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 ©); + +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 ¶m, bool background); + virtual void drag(const MouseWatcherParameter ¶m); + +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 diff --git a/panda/src/pgui/pgSliderButton.I b/panda/src/pgui/pgSliderButton.I new file mode 100755 index 0000000000..967abfcfc9 --- /dev/null +++ b/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 +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////// +// 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; +} diff --git a/panda/src/pgui/pgSliderButton.cxx b/panda/src/pgui/pgSliderButton.cxx new file mode 100755 index 0000000000..b3b3c1fce5 --- /dev/null +++ b/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 +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#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 ¶m) { + 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; + } +} diff --git a/panda/src/pgui/pgSliderButton.h b/panda/src/pgui/pgSliderButton.h new file mode 100755 index 0000000000..36a8ce1412 --- /dev/null +++ b/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 +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#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 ¶m); + +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 diff --git a/panda/src/pgui/pgui_composite1.cxx b/panda/src/pgui/pgui_composite1.cxx index b2e391f435..b97fdbd8c5 100644 --- a/panda/src/pgui/pgui_composite1.cxx +++ b/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" diff --git a/panda/src/pgui/pgui_composite2.cxx b/panda/src/pgui/pgui_composite2.cxx index a728997d8c..2150101e14 100644 --- a/panda/src/pgui/pgui_composite2.cxx +++ b/panda/src/pgui/pgui_composite2.cxx @@ -5,4 +5,5 @@ #include "pgMouseWatcherRegion.cxx" #include "pgTop.cxx" #include "pgWaitBar.cxx" +#include "pgSliderBar.cxx" diff --git a/panda/src/tform/mouseWatcher.cxx b/panda/src/tform/mouseWatcher.cxx index 37fbe596fb..7f83fc3315 100644 --- a/panda/src/tform/mouseWatcher.cxx +++ b/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)); diff --git a/panda/src/tform/mouseWatcher.h b/panda/src/tform/mouseWatcher.h index 8b9905a036..3588397237 100644 --- a/panda/src/tform/mouseWatcher.h +++ b/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); diff --git a/panda/src/tform/mouseWatcherRegion.cxx b/panda/src/tform/mouseWatcherRegion.cxx index e1d47e67f8..1cb945bf2c 100644 --- a/panda/src/tform/mouseWatcherRegion.cxx +++ b/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 &) { +} diff --git a/panda/src/tform/mouseWatcherRegion.h b/panda/src/tform/mouseWatcherRegion.h index d692b3f45b..e0563c59f1 100644 --- a/panda/src/tform/mouseWatcherRegion.h +++ b/panda/src/tform/mouseWatcherRegion.h @@ -78,6 +78,7 @@ public: virtual void release(const MouseWatcherParameter ¶m); virtual void keystroke(const MouseWatcherParameter ¶m); virtual void candidate(const MouseWatcherParameter ¶m); + virtual void move(const MouseWatcherParameter ¶m); private: LVecBase4f _frame;