Panda3D
Loading...
Searching...
No Matches
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"
20#include "colorAttrib.h"
21#include "transformState.h"
22
23TypeHandle PGButton::_type_handle;
24
25/**
26 *
27 */
28PGButton::
29PGButton(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 */
40PGButton::
41~PGButton() {
42}
43
44/**
45 *
46 */
47PGButton::
48PGButton(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 */
61make_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 */
72 LightReMutexHolder holder(_lock);
73 if (get_active()) {
74 set_state(_button_down ? S_depressed : S_rollover);
75 }
77}
78
79/**
80 * This is a callback hook function, called whenever the mouse exits the
81 * region.
82 */
85 LightReMutexHolder holder(_lock);
86 if (get_active()) {
87 set_state(S_ready);
88 }
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 */
97press(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 */
113release(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 // Note that a "click" may come from a keyboard button press. In that
119 // case, instead of checking that the mouse cursor is still over the
120 // button, we check whether the item has keyboard focus.
121 if (param.is_outside() &&
123 set_state(S_ready);
124 } else {
125 set_state(S_rollover);
126 click(param);
127 }
128 }
129 }
130 PGItem::release(param, background);
131}
132
133/**
134 * This is a callback hook function, called whenever the button is clicked
135 * down-and-up by the user normally.
136 */
138click(const MouseWatcherParameter &param) {
139 LightReMutexHolder holder(_lock);
141 std::string event = get_click_event(param.get_button());
142 play_sound(event);
143 throw_event(event, EventParameter(ep));
144
145 if (has_notify()) {
146 get_notify()->button_click(this, param);
147 }
148}
149
150/**
151 * Sets up the button as a default text button using the indicated label
152 * string. The TextNode defined by PGItem::get_text_node() will be used to
153 * create the label geometry. This automatically sets up the frame according
154 * to the size of the text.
155 */
157setup(const std::string &label, PN_stdfloat bevel) {
158 LightReMutexHolder holder(_lock);
159 clear_state_def(S_ready);
160 clear_state_def(S_depressed);
161 clear_state_def(S_rollover);
162 clear_state_def(S_inactive);
163
164 TextNode *text_node = get_text_node();
165 text_node->set_text(label);
166 PT(PandaNode) geom = text_node->generate();
167
168 LVecBase4 frame = text_node->get_card_actual();
169 set_frame(frame[0] - 0.4, frame[1] + 0.4, frame[2] - 0.15f, frame[3] + 0.15f);
170
171 PT(PandaNode) ready = new PandaNode("ready");
172 PT(PandaNode) depressed = new PandaNode("depressed");
173 PT(PandaNode) rollover = new PandaNode("rollover");
174 PT(PandaNode) inactive = new PandaNode("inactive");
175
176 PGFrameStyle style;
177 style.set_color(0.8f, 0.8f, 0.8f, 1.0f);
178 style.set_width(bevel, bevel);
179
180 style.set_type(PGFrameStyle::T_bevel_out);
181 set_frame_style(S_ready, style);
182
183 style.set_color(0.9f, 0.9f, 0.9f, 1.0f);
184 set_frame_style(S_rollover, style);
185
186 inactive->set_attrib(ColorAttrib::make_flat(LColor(0.8f, 0.8f, 0.8f, 1.0f)));
187 style.set_color(0.6f, 0.6f, 0.6f, 1.0f);
188 set_frame_style(S_inactive, style);
189
190 style.set_type(PGFrameStyle::T_bevel_in);
191 style.set_color(0.8f, 0.8f, 0.8f, 1.0f);
192 set_frame_style(S_depressed, style);
193 depressed->set_transform(TransformState::make_pos(LVector3(0.05f, 0.0f, -0.05f)));
194
195 get_state_def(S_ready).attach_new_node(ready, 1);
196 get_state_def(S_depressed).attach_new_node(depressed, 1);
197 get_state_def(S_rollover).attach_new_node(rollover, 1);
198 get_state_def(S_inactive).attach_new_node(inactive, 1);
199
200 ready->add_child(geom);
201 depressed->add_child(geom);
202 rollover->add_child(geom);
203 inactive->add_child(geom);
204}
205
206/**
207 * Sets up the button using the indicated NodePath as arbitrary geometry.
208 */
210setup(const NodePath &ready, const NodePath &depressed,
211 const NodePath &rollover, const NodePath &inactive) {
212 LightReMutexHolder holder(_lock);
213 clear_state_def(S_ready);
214 clear_state_def(S_depressed);
215 clear_state_def(S_rollover);
216 clear_state_def(S_inactive);
217
218 instance_to_state_def(S_ready, ready);
219 instance_to_state_def(S_depressed, depressed);
220 instance_to_state_def(S_rollover, rollover);
221 instance_to_state_def(S_inactive, inactive);
222
223 // Set the button frame size.
224 LPoint3 min_point, max_point;
225 ready.calc_tight_bounds(min_point, max_point);
226 set_frame(min_point[0], max_point[0],
227 min_point[2], max_point[2]);
228}
229
230/**
231 * Toggles the active/inactive state of the button. In the case of a
232 * PGButton, this also changes its visual appearance.
233 */
235set_active(bool active) {
236 LightReMutexHolder holder(_lock);
237 if (active != get_active()) {
238 PGItem::set_active(active);
239 set_state(active ? S_ready : S_inactive);
240 }
241}
242
243/**
244 * Adds the indicated button to the set of buttons that can effectively
245 * "click" the PGButton. Normally, this is just MouseButton::one(). Returns
246 * true if the button was added, or false if it was already there.
247 */
249add_click_button(const ButtonHandle &button) {
250 LightReMutexHolder holder(_lock);
251 return _click_buttons.insert(button).second;
252}
253
254/**
255 * Removes the indicated button from the set of buttons that can effectively
256 * "click" the PGButton. Normally, this is just MouseButton::one(). Returns
257 * true if the button was removed, or false if it was not in the set.
258 */
260remove_click_button(const ButtonHandle &button) {
261 LightReMutexHolder holder(_lock);
262 return (_click_buttons.erase(button) != 0);
263}
264
265/**
266 * Returns true if the indicated button is on the set of buttons that can
267 * effectively "click" the PGButton. Normally, this is just
268 * MouseButton::one().
269 */
271has_click_button(const ButtonHandle &button) {
272 LightReMutexHolder holder(_lock);
273 return (_click_buttons.count(button) != 0);
274}
A ButtonHandle represents a single button from any device, including keyboard buttons and mouse butto...
An optional parameter associated with an event.
Similar to MutexHolder, but for a light reentrant mutex.
static bool is_mouse_button(ButtonHandle button)
Returns true if the indicated ButtonHandle is a mouse button, false if it is some other kind of butto...
static ButtonHandle one()
Returns the ButtonHandle associated with the first mouse button.
This is sent along as a parameter to most events generated for a region to indicate the mouse and but...
ButtonHandle get_button() const
Returns the mouse or keyboard button associated with this event.
bool is_outside() const
Returns true if the mouse was outside the region at the time the event was generated,...
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition nodePath.h:159
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.
This is a particular kind of PGItem that is specialized to behave like a normal button object.
Definition pgButton.h:29
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:157
virtual void set_active(bool active)
Toggles the active/inactive state of the button.
Definition pgButton.cxx:235
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:249
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
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:138
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
virtual void enter_region(const MouseWatcherParameter &param)
This is a callback hook function, called whenever the mouse enters the region.
Definition pgButton.cxx:71
virtual PandaNode * make_copy() const
Returns a newly-allocated Node that is a shallow copy of this one.
Definition pgButton.cxx:61
virtual void exit_region(const MouseWatcherParameter &param)
This is a callback hook function, called whenever the mouse exits the region.
Definition pgButton.cxx:84
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:271
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:260
PGButtonNotify * get_notify() const
Returns the object which will be notified when the PGButton changes, if any.
Definition pgButton.I:30
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
void set_type(Type type)
Sets the basic type of frame.
void set_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a)
Sets the dominant color of the frame.
void set_width(PN_stdfloat x, PN_stdfloat y)
Sets the width parameter, which has meaning only for certain frame types.
This is the base class for all the various kinds of gui widget objects.
Definition pgItem.h:53
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:674
bool get_active() const
Returns whether the PGItem is currently active for mouse events.
Definition pgItem.I:160
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:1007
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:953
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
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:1076
bool get_focus() const
Returns whether the PGItem currently has focus for keyboard events.
Definition pgItem.I:170
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:703
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:977
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:562
bool has_notify() const
Returns true if there is an object configured to be notified when the PGItem changes,...
Definition pgItem.I:59
virtual void enter_region(const MouseWatcherParameter &param)
This is a callback hook function, called whenever the mouse enters the region.
Definition pgItem.cxx:538
virtual void set_active(bool active)
Sets whether the PGItem is active for mouse watching.
Definition pgItem.cxx:837
This specialization on MouseWatcherParameter allows us to tag on additional elements to events for th...
A basic node of the scene graph or data graph.
Definition pandaNode.h:65
set_state
Sets the complete RenderState that will be applied to all nodes at this level and below.
Definition pandaNode.h:173
set_text
Changes the text that is stored in the encoder.
The primary interface to this module.
Definition textNode.h:48
LVecBase4 get_card_actual() const
Returns the actual dimensions of the card around the text.
Definition textNode.I:503
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.