297 lines
10 KiB
C++
297 lines
10 KiB
C++
// Filename: pgButton.cxx
|
|
// Created by: drose (13Mar02)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 "pgButton.h"
|
|
#include "pgMouseWatcherParameter.h"
|
|
|
|
#include "throw_event.h"
|
|
#include "mouseButton.h"
|
|
#include "mouseWatcherParameter.h"
|
|
#include "colorAttrib.h"
|
|
#include "transformState.h"
|
|
|
|
TypeHandle PGButton::_type_handle;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::Constructor
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
PGButton::
|
|
PGButton(const string &name) : PGItem(name)
|
|
{
|
|
_button_down = false;
|
|
_click_buttons.insert(MouseButton::one());
|
|
|
|
set_active(true);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::Destructor
|
|
// Access: Public, Virtual
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
PGButton::
|
|
~PGButton() {
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::Copy Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
PGButton::
|
|
PGButton(const PGButton ©) :
|
|
PGItem(copy),
|
|
_click_buttons(copy._click_buttons)
|
|
{
|
|
_button_down = false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::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 *PGButton::
|
|
make_copy() const {
|
|
return new PGButton(*this);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::enter_region
|
|
// Access: Public, Virtual
|
|
// Description: This is a callback hook function, called whenever the
|
|
// mouse enters the region.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PGButton::
|
|
enter_region(const MouseWatcherParameter ¶m) {
|
|
if (get_active()) {
|
|
set_state(_button_down ? S_depressed : S_rollover);
|
|
}
|
|
PGItem::enter_region(param);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::exit_region
|
|
// Access: Public, Virtual
|
|
// Description: This is a callback hook function, called whenever the
|
|
// mouse exits the region.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PGButton::
|
|
exit_region(const MouseWatcherParameter ¶m) {
|
|
if (get_active()) {
|
|
set_state(S_ready);
|
|
}
|
|
PGItem::exit_region(param);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::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 PGButton::
|
|
press(const MouseWatcherParameter ¶m, bool background) {
|
|
if (has_click_button(param.get_button())) {
|
|
if (get_active()) {
|
|
_button_down = true;
|
|
set_state(S_depressed);
|
|
}
|
|
}
|
|
PGItem::press(param, background);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::release
|
|
// Access: Public, Virtual
|
|
// Description: This is a callback hook function, called whenever a
|
|
// mouse or keyboard button previously depressed with
|
|
// press() is released.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PGButton::
|
|
release(const MouseWatcherParameter ¶m, bool background) {
|
|
if (has_click_button(param.get_button())) {
|
|
_button_down = false;
|
|
if (get_active()) {
|
|
if (param.is_outside()) {
|
|
set_state(S_ready);
|
|
} else {
|
|
set_state(S_rollover);
|
|
click(param);
|
|
}
|
|
}
|
|
}
|
|
PGItem::release(param, background);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::click
|
|
// Access: Public, Virtual
|
|
// Description: This is a callback hook function, called whenever the
|
|
// button is clicked down-and-up by the user normally.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PGButton::
|
|
click(const MouseWatcherParameter ¶m) {
|
|
PGMouseWatcherParameter *ep = new PGMouseWatcherParameter(param);
|
|
string event = get_click_event(param.get_button());
|
|
play_sound(event);
|
|
throw_event(event, EventParameter(ep));
|
|
|
|
if (has_notify()) {
|
|
get_notify()->button_click(this, param);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::setup
|
|
// Access: Published
|
|
// Description: Sets up the button as a default text button using the
|
|
// indicated label string. The TextNode defined by
|
|
// PGItem::get_text_node() will be used to create the
|
|
// label geometry. This automatically sets up the frame
|
|
// according to the size of the text.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PGButton::
|
|
setup(const string &label, float bevel) {
|
|
clear_state_def(S_ready);
|
|
clear_state_def(S_depressed);
|
|
clear_state_def(S_rollover);
|
|
clear_state_def(S_inactive);
|
|
|
|
TextNode *text_node = get_text_node();
|
|
text_node->set_text(label);
|
|
PT(PandaNode) geom = text_node->generate();
|
|
|
|
LVecBase4f frame = text_node->get_card_actual();
|
|
set_frame(frame[0] - 0.4f, frame[1] + 0.4f, frame[2] - 0.15f, frame[3] + 0.15f);
|
|
|
|
PT(PandaNode) ready = new PandaNode("ready");
|
|
PT(PandaNode) depressed = new PandaNode("depressed");
|
|
PT(PandaNode) rollover = new PandaNode("rollover");
|
|
PT(PandaNode) inactive = new PandaNode("inactive");
|
|
|
|
PGFrameStyle style;
|
|
style.set_color(0.8f, 0.8f, 0.8f, 1.0f);
|
|
style.set_width(bevel, bevel);
|
|
|
|
style.set_type(PGFrameStyle::T_bevel_out);
|
|
set_frame_style(S_ready, style);
|
|
|
|
style.set_color(0.9f, 0.9f, 0.9f, 1.0f);
|
|
set_frame_style(S_rollover, style);
|
|
|
|
inactive->set_attrib(ColorAttrib::make_flat(Colorf(0.8f, 0.8f, 0.8f, 1.0f)));
|
|
style.set_color(0.6f, 0.6f, 0.6f, 1.0f);
|
|
set_frame_style(S_inactive, style);
|
|
|
|
style.set_type(PGFrameStyle::T_bevel_in);
|
|
style.set_color(0.8f, 0.8f, 0.8f, 1.0f);
|
|
set_frame_style(S_depressed, style);
|
|
depressed->set_transform(TransformState::make_pos(LVector3f(0.05f, 0.0f, -0.05f)));
|
|
|
|
get_state_def(S_ready).attach_new_node(ready);
|
|
get_state_def(S_depressed).attach_new_node(depressed);
|
|
get_state_def(S_rollover).attach_new_node(rollover);
|
|
get_state_def(S_inactive).attach_new_node(inactive);
|
|
|
|
ready->add_child(geom);
|
|
depressed->add_child(geom);
|
|
rollover->add_child(geom);
|
|
inactive->add_child(geom);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::setup
|
|
// Access: Published
|
|
// Description: Sets up the button using the indicated NodePath as
|
|
// arbitrary geometry.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PGButton::
|
|
setup(const NodePath &ready, const NodePath &depressed,
|
|
const NodePath &rollover, const NodePath &inactive) {
|
|
clear_state_def(S_ready);
|
|
clear_state_def(S_depressed);
|
|
clear_state_def(S_rollover);
|
|
clear_state_def(S_inactive);
|
|
|
|
instance_to_state_def(S_ready, ready);
|
|
instance_to_state_def(S_depressed, depressed);
|
|
instance_to_state_def(S_rollover, rollover);
|
|
instance_to_state_def(S_inactive, inactive);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::set_active
|
|
// Access: Published, Virtual
|
|
// Description: Toggles the active/inactive state of the button. In
|
|
// the case of a PGButton, this also changes its visual
|
|
// appearance.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PGButton::
|
|
set_active(bool active) {
|
|
if (active != get_active()) {
|
|
PGItem::set_active(active);
|
|
set_state(active ? S_ready : S_inactive);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::add_click_button
|
|
// Access: Published
|
|
// Description: Adds the indicated button to the set of buttons that
|
|
// can effectively "click" the PGButton. Normally, this
|
|
// is just MouseButton::one(). Returns true if the
|
|
// button was added, or false if it was already there.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PGButton::
|
|
add_click_button(const ButtonHandle &button) {
|
|
return _click_buttons.insert(button).second;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::remove_click_button
|
|
// Access: Published
|
|
// Description: Removes the indicated button from the set of buttons
|
|
// that can effectively "click" the PGButton. Normally,
|
|
// this is just MouseButton::one(). Returns true if the
|
|
// button was removed, or false if it was not in the
|
|
// set.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PGButton::
|
|
remove_click_button(const ButtonHandle &button) {
|
|
return (_click_buttons.erase(button) != 0);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PGButton::has_click_button
|
|
// Access: Published
|
|
// Description: Returns true if the indicated button is on the set of
|
|
// buttons that can effectively "click" the PGButton.
|
|
// Normally, this is just MouseButton::one().
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PGButton::
|
|
has_click_button(const ButtonHandle &button) {
|
|
return (_click_buttons.count(button) != 0);
|
|
}
|