Panda3D
pgButton.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file pgButton.cxx
10  * @author drose
11  * @date 2002-03-13
12  */
13 
14 #include "pgButton.h"
16 
17 #include "throw_event.h"
18 #include "mouseButton.h"
19 #include "mouseWatcherParameter.h"
20 #include "colorAttrib.h"
21 #include "transformState.h"
22 
23 TypeHandle PGButton::_type_handle;
24 
25 /**
26  *
27  */
28 PGButton::
29 PGButton(const std::string &name) : PGItem(name)
30 {
31  _button_down = false;
32  _click_buttons.insert(MouseButton::one());
33 
34  set_active(true);
35 }
36 
37 /**
38  *
39  */
40 PGButton::
41 ~PGButton() {
42 }
43 
44 /**
45  *
46  */
47 PGButton::
48 PGButton(const PGButton &copy) :
49  PGItem(copy),
50  _click_buttons(copy._click_buttons)
51 {
52  _button_down = false;
53 }
54 
55 /**
56  * Returns a newly-allocated Node that is a shallow copy of this one. It will
57  * be a different Node pointer, but its internal data may or may not be shared
58  * with that of the original Node.
59  */
61 make_copy() const {
62  LightReMutexHolder holder(_lock);
63  return new PGButton(*this);
64 }
65 
66 /**
67  * This is a callback hook function, called whenever the mouse enters the
68  * region.
69  */
70 void PGButton::
72  LightReMutexHolder holder(_lock);
73  if (get_active()) {
74  set_state(_button_down ? S_depressed : S_rollover);
75  }
76  PGItem::enter_region(param);
77 }
78 
79 /**
80  * This is a callback hook function, called whenever the mouse exits the
81  * region.
82  */
83 void PGButton::
85  LightReMutexHolder holder(_lock);
86  if (get_active()) {
87  set_state(S_ready);
88  }
89  PGItem::exit_region(param);
90 }
91 
92 /**
93  * This is a callback hook function, called whenever a mouse or keyboard
94  * button is depressed while the mouse is within the region.
95  */
96 void PGButton::
97 press(const MouseWatcherParameter &param, bool background) {
98  LightReMutexHolder holder(_lock);
99  if (has_click_button(param.get_button())) {
100  if (get_active()) {
101  _button_down = true;
102  set_state(S_depressed);
103  }
104  }
105  PGItem::press(param, background);
106 }
107 
108 /**
109  * This is a callback hook function, called whenever a mouse or keyboard
110  * button previously depressed with press() is released.
111  */
112 void PGButton::
113 release(const MouseWatcherParameter &param, bool background) {
114  LightReMutexHolder holder(_lock);
115  if (has_click_button(param.get_button())) {
116  _button_down = false;
117  if (get_active()) {
118  if (param.is_outside()) {
119  set_state(S_ready);
120  } else {
121  set_state(S_rollover);
122  click(param);
123  }
124  }
125  }
126  PGItem::release(param, background);
127 }
128 
129 /**
130  * This is a callback hook function, called whenever the button is clicked
131  * down-and-up by the user normally.
132  */
133 void PGButton::
135  LightReMutexHolder holder(_lock);
137  std::string event = get_click_event(param.get_button());
138  play_sound(event);
139  throw_event(event, EventParameter(ep));
140 
141  if (has_notify()) {
142  get_notify()->button_click(this, param);
143  }
144 }
145 
146 /**
147  * Sets up the button as a default text button using the indicated label
148  * string. The TextNode defined by PGItem::get_text_node() will be used to
149  * create the label geometry. This automatically sets up the frame according
150  * to the size of the text.
151  */
152 void PGButton::
153 setup(const std::string &label, PN_stdfloat bevel) {
154  LightReMutexHolder holder(_lock);
155  clear_state_def(S_ready);
156  clear_state_def(S_depressed);
157  clear_state_def(S_rollover);
158  clear_state_def(S_inactive);
159 
160  TextNode *text_node = get_text_node();
161  text_node->set_text(label);
162  PT(PandaNode) geom = text_node->generate();
163 
164  LVecBase4 frame = text_node->get_card_actual();
165  set_frame(frame[0] - 0.4, frame[1] + 0.4, frame[2] - 0.15f, frame[3] + 0.15f);
166 
167  PT(PandaNode) ready = new PandaNode("ready");
168  PT(PandaNode) depressed = new PandaNode("depressed");
169  PT(PandaNode) rollover = new PandaNode("rollover");
170  PT(PandaNode) inactive = new PandaNode("inactive");
171 
172  PGFrameStyle style;
173  style.set_color(0.8f, 0.8f, 0.8f, 1.0f);
174  style.set_width(bevel, bevel);
175 
176  style.set_type(PGFrameStyle::T_bevel_out);
177  set_frame_style(S_ready, style);
178 
179  style.set_color(0.9f, 0.9f, 0.9f, 1.0f);
180  set_frame_style(S_rollover, style);
181 
182  inactive->set_attrib(ColorAttrib::make_flat(LColor(0.8f, 0.8f, 0.8f, 1.0f)));
183  style.set_color(0.6f, 0.6f, 0.6f, 1.0f);
184  set_frame_style(S_inactive, style);
185 
186  style.set_type(PGFrameStyle::T_bevel_in);
187  style.set_color(0.8f, 0.8f, 0.8f, 1.0f);
188  set_frame_style(S_depressed, style);
189  depressed->set_transform(TransformState::make_pos(LVector3(0.05f, 0.0f, -0.05f)));
190 
191  get_state_def(S_ready).attach_new_node(ready, 1);
192  get_state_def(S_depressed).attach_new_node(depressed, 1);
193  get_state_def(S_rollover).attach_new_node(rollover, 1);
194  get_state_def(S_inactive).attach_new_node(inactive, 1);
195 
196  ready->add_child(geom);
197  depressed->add_child(geom);
198  rollover->add_child(geom);
199  inactive->add_child(geom);
200 }
201 
202 /**
203  * Sets up the button using the indicated NodePath as arbitrary geometry.
204  */
205 void PGButton::
206 setup(const NodePath &ready, const NodePath &depressed,
207  const NodePath &rollover, const NodePath &inactive) {
208  LightReMutexHolder holder(_lock);
209  clear_state_def(S_ready);
210  clear_state_def(S_depressed);
211  clear_state_def(S_rollover);
212  clear_state_def(S_inactive);
213 
214  instance_to_state_def(S_ready, ready);
215  instance_to_state_def(S_depressed, depressed);
216  instance_to_state_def(S_rollover, rollover);
217  instance_to_state_def(S_inactive, inactive);
218 
219  // Set the button frame size.
220  LPoint3 min_point, max_point;
221  ready.calc_tight_bounds(min_point, max_point);
222  set_frame(min_point[0], max_point[0],
223  min_point[2], max_point[2]);
224 }
225 
226 /**
227  * Toggles the active/inactive state of the button. In the case of a
228  * PGButton, this also changes its visual appearance.
229  */
230 void PGButton::
231 set_active(bool active) {
232  LightReMutexHolder holder(_lock);
233  if (active != get_active()) {
234  PGItem::set_active(active);
235  set_state(active ? S_ready : S_inactive);
236  }
237 }
238 
239 /**
240  * Adds the indicated button to the set of buttons that can effectively
241  * "click" the PGButton. Normally, this is just MouseButton::one(). Returns
242  * true if the button was added, or false if it was already there.
243  */
244 bool PGButton::
246  LightReMutexHolder holder(_lock);
247  return _click_buttons.insert(button).second;
248 }
249 
250 /**
251  * Removes the indicated button from the set of buttons that can effectively
252  * "click" the PGButton. Normally, this is just MouseButton::one(). Returns
253  * true if the button was removed, or false if it was not in the set.
254  */
255 bool PGButton::
257  LightReMutexHolder holder(_lock);
258  return (_click_buttons.erase(button) != 0);
259 }
260 
261 /**
262  * Returns true if the indicated button is on the set of buttons that can
263  * effectively "click" the PGButton. Normally, this is just
264  * MouseButton::one().
265  */
266 bool PGButton::
268  LightReMutexHolder holder(_lock);
269  return (_click_buttons.count(button) != 0);
270 }
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
virtual void press(const MouseWatcherParameter &param, bool background)
This is a callback hook function, called whenever a mouse or keyboard button is depressed while the m...
Definition: pgButton.cxx:97
This specialization on MouseWatcherParameter allows us to tag on additional elements to events for th...
void set_width(PN_stdfloat x, PN_stdfloat y)
Sets the width parameter, which has meaning only for certain frame types.
Definition: pgFrameStyle.I:139
void setup(const std::string &label, PN_stdfloat bevel=0.1f)
Sets up the button as a default text button using the indicated label string.
Definition: pgButton.cxx:153
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PGButtonNotify * get_notify() const
Returns the object which will be notified when the PGButton changes, if any.
Definition: pgButton.I:30
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the base class for all the various kinds of gui widget objects.
Definition: pgItem.h:53
virtual void enter_region(const MouseWatcherParameter &param)
This is a callback hook function, called whenever the mouse enters the region.
Definition: pgButton.cxx:71
An optional parameter associated with an event.
bool get_active() const
Returns whether the PGItem is currently active for mouse events.
Definition: pgItem.I:160
std::string get_click_event(const ButtonHandle &button) const
Returns the event name that will be thrown when the button is clicked normally.
Definition: pgButton.I:74
This is a particular kind of PGItem that is specialized to behave like a normal button object.
Definition: pgButton.h:29
void set_type(Type type)
Sets the basic type of frame.
Definition: pgFrameStyle.I:64
void set_frame(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top)
Sets the bounding rectangle of the item, in local coordinates.
Definition: pgItem.I:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point, const NodePath &other=NodePath(), Thread *current_thread=Thread::get_current_thread()) const
Calculates the minimum and maximum vertices of all Geoms at this NodePath's bottom node and below.
Definition: nodePath.cxx:5419
static ButtonHandle one()
Returns the ButtonHandle associated with the first mouse button.
Definition: mouseButton.cxx:43
virtual void enter_region(const MouseWatcherParameter &param)
This is a callback hook function, called whenever the mouse enters the region.
Definition: pgItem.cxx:521
bool is_outside() const
Returns true if the mouse was outside the region at the time the event was generated,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual PandaNode * make_copy() const
Returns a newly-allocated Node that is a shallow copy of this one.
Definition: pgButton.cxx:61
A ButtonHandle represents a single button from any device, including keyboard buttons and mouse butto...
Definition: buttonHandle.h:26
virtual void release(const MouseWatcherParameter &param, bool background)
This is a callback hook function, called whenever a mouse or keyboard button previously depressed wit...
Definition: pgButton.cxx:113
set_text
Changes the text that is stored in the encoder.
Definition: textEncoder.h:124
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool has_notify() const
Returns true if there is an object configured to be notified when the PGItem changes,...
Definition: pgItem.I:59
void set_frame_style(int state, const PGFrameStyle &style)
Changes the kind of frame that will be drawn behind the item when it is in the indicated state.
Definition: pgItem.cxx:992
ButtonHandle get_button() const
Returns the mouse or keyboard button associated with this event.
virtual void exit_region(const MouseWatcherParameter &param)
This is a callback hook function, called whenever the mouse exits the region.
Definition: pgButton.cxx:84
virtual void set_active(bool active)
Toggles the active/inactive state of the button.
Definition: pgButton.cxx:231
NodePath instance_to_state_def(int state, const NodePath &path)
Parents an instance of the bottom node of the indicated NodePath to the indicated state index.
Definition: pgItem.cxx:962
virtual void release(const MouseWatcherParameter &param, bool background)
This is a callback hook function, called whenever a mouse or keyboard button previously depressed wit...
Definition: pgItem.cxx:686
void set_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a)
Sets the dominant color of the frame.
Definition: pgFrameStyle.I:80
bool has_click_button(const ButtonHandle &button)
Returns true if the indicated button is on the set of buttons that can effectively "click" the PGButt...
Definition: pgButton.cxx:267
static TextNode * get_text_node()
Returns the TextNode object that will be used by all PGItems to generate default labels given a strin...
Definition: pgItem.cxx:1055
Similar to MutexHolder, but for a light reentrant mutex.
LVecBase4 get_card_actual() const
Returns the actual dimensions of the card around the text.
Definition: textNode.I:503
void set_state(int state)
Sets the "state" of this particular PGItem.
Definition: pgItem.I:141
The primary interface to this module.
Definition: textNode.h:48
void clear_state_def(int state)
Resets the NodePath assigned to the indicated state to its initial default, with only a frame represe...
Definition: pgItem.cxx:944
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
This is sent along as a parameter to most events generated for a region to indicate the mouse and but...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_state_def
Returns the Node that is the root of the subgraph that will be drawn when the PGItem is in the indica...
Definition: pgItem.h:135
virtual void exit_region(const MouseWatcherParameter &param)
This is a callback hook function, called whenever the mouse exits the region.
Definition: pgItem.cxx:545
virtual void click(const MouseWatcherParameter &param)
This is a callback hook function, called whenever the button is clicked down-and-up by the user norma...
Definition: pgButton.cxx:134
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161
virtual void set_active(bool active)
Sets whether the PGItem is active for mouse watching.
Definition: pgItem.cxx:828
bool add_click_button(const ButtonHandle &button)
Adds the indicated button to the set of buttons that can effectively "click" the PGButton.
Definition: pgButton.cxx:245
bool remove_click_button(const ButtonHandle &button)
Removes the indicated button from the set of buttons that can effectively "click" the PGButton.
Definition: pgButton.cxx:256
virtual void press(const MouseWatcherParameter &param, bool background)
This is a callback hook function, called whenever a mouse or keyboard button is depressed while the m...
Definition: pgItem.cxx:657