summaryrefslogtreecommitdiff
path: root/scene/gui/base_button.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/base_button.cpp')
-rw-r--r--scene/gui/base_button.cpp375
1 files changed, 375 insertions, 0 deletions
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
new file mode 100644
index 0000000000..2e03871063
--- /dev/null
+++ b/scene/gui/base_button.cpp
@@ -0,0 +1,375 @@
+/*************************************************************************/
+/* base_button.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "base_button.h"
+#include "os/keyboard.h"
+#include "print_string.h"
+#include "button_group.h"
+
+
+void BaseButton::_input_event(InputEvent p_event) {
+
+
+ if (status.disabled) // no interaction with disabled button
+ return;
+
+ switch(p_event.type) {
+
+ case InputEvent::MOUSE_BUTTON: {
+
+ const InputEventMouseButton &b=p_event.mouse_button;
+
+ if ( status.disabled || b.button_index!=1 )
+ return;
+
+ if (status.pressing_button)
+ break;
+
+ if (status.click_on_press) {
+
+ if (b.pressed) {
+
+ if (!toggle_mode) { //mouse press attempt
+
+ pressed();
+ emit_signal("pressed");
+
+ } else {
+
+ status.pressed=!status.pressed;
+ pressed();
+ emit_signal("pressed");
+
+ toggled(status.pressed);
+ emit_signal("toggled",status.pressed);
+
+ }
+
+
+ }
+
+ break;
+ }
+
+ if (b.pressed) {
+
+ status.press_attempt=true;
+ status.pressing_inside=true;
+
+ } else {
+
+
+ if (status.press_attempt &&status.pressing_inside) {
+
+ if (!toggle_mode) { //mouse press attempt
+
+ pressed();
+ emit_signal("pressed");
+
+ } else {
+
+ status.pressed=!status.pressed;
+
+ pressed();
+ emit_signal("pressed");
+
+ toggled(status.pressed);
+ emit_signal("toggled",status.pressed);
+
+ }
+
+ }
+
+ status.press_attempt=false;
+
+ }
+
+ update();
+ } break;
+ case InputEvent::MOUSE_MOTION: {
+
+ if (status.press_attempt && status.pressing_button==0) {
+ bool last_press_inside=status.pressing_inside;
+ status.pressing_inside=has_point(Point2(p_event.mouse_motion.x,p_event.mouse_motion.y));
+ if (last_press_inside!=status.pressing_inside)
+ update();
+ }
+ } break;
+ case InputEvent::JOYSTICK_BUTTON:
+ case InputEvent::KEY: {
+
+
+ if (p_event.is_echo()) {
+ break;
+ }
+
+ if (status.disabled) {
+ break;
+ }
+
+ if (status.press_attempt && status.pressing_button==0) {
+ break;
+ }
+
+ if (p_event.is_action("ui_accept")) {
+
+ if (p_event.is_pressed()) {
+
+ status.pressing_button++;
+ status.press_attempt=true;
+ status.pressing_inside=true;
+
+ } else if (status.press_attempt) {
+
+ if (status.pressing_button)
+ status.pressing_button--;
+
+ if (status.pressing_button)
+ break;
+
+ status.press_attempt=false;
+ status.pressing_inside=false;
+
+ if (!toggle_mode) { //mouse press attempt
+
+ pressed();
+ emit_signal("pressed");
+ } else {
+
+ status.pressed=!status.pressed;
+
+ pressed();
+ emit_signal("pressed");
+
+ toggled(status.pressed);
+ emit_signal("toggled",status.pressed);
+ }
+ }
+
+ accept_event();
+ update();
+
+ }
+ }
+
+ }
+}
+
+void BaseButton::_notification(int p_what) {
+
+
+ if (p_what==NOTIFICATION_MOUSE_ENTER) {
+
+ status.hovering=true;
+ update();
+ }
+
+ if (p_what==NOTIFICATION_MOUSE_EXIT) {
+ status.hovering=false;
+ update();
+ }
+ if (p_what==NOTIFICATION_FOCUS_EXIT) {
+
+ if (status.pressing_button && status.press_attempt) {
+ status.press_attempt=false;
+ status.pressing_button=0;
+ }
+ }
+
+ if (p_what==NOTIFICATION_ENTER_SCENE) {
+
+ CanvasItem *ci=this;
+ while(ci) {
+
+ ButtonGroup *bg = ci->cast_to<ButtonGroup>();
+ if (bg) {
+
+ group=bg;
+ group->_add_button(this);
+ }
+
+ ci=ci->get_parent_item();
+ }
+ }
+
+ if (p_what==NOTIFICATION_EXIT_SCENE) {
+
+ if (group)
+ group->_remove_button(this);
+ }
+
+}
+
+void BaseButton::pressed() {
+
+ if (get_script_instance())
+ get_script_instance()->call("pressed");
+}
+
+void BaseButton::toggled(bool p_pressed) {
+
+ if (get_script_instance())
+ get_script_instance()->call("toggled",p_pressed);
+
+}
+
+
+void BaseButton::set_disabled(bool p_disabled) {
+
+ status.disabled = p_disabled;
+ update();
+ _change_notify("disabled");
+ if (p_disabled)
+ set_focus_mode(FOCUS_NONE);
+ else
+ set_focus_mode(FOCUS_ALL);
+};
+
+bool BaseButton::is_disabled() const {
+
+ return status.disabled;
+};
+
+void BaseButton::set_pressed(bool p_pressed) {
+
+ if (!toggle_mode)
+ return;
+ if (status.pressed==p_pressed)
+ return;
+ _change_notify("pressed");
+ status.pressed=p_pressed;
+ update();
+}
+
+bool BaseButton::is_pressing() const{
+
+ return status.press_attempt;
+}
+
+bool BaseButton::is_pressed() const {
+
+ return toggle_mode?status.pressed:status.press_attempt;
+}
+
+
+BaseButton::DrawMode BaseButton::get_draw_mode() const {
+
+ if (status.disabled) {
+ return DRAW_DISABLED;
+ };
+
+ //print_line("press attempt: "+itos(status.press_attempt)+" hover: "+itos(status.hovering)+" pressed: "+itos(status.pressed));
+ if (status.press_attempt==false && status.hovering && !status.pressed) {
+
+
+ return DRAW_HOVER;
+ } else {
+ /* determine if pressed or not */
+
+ bool pressing;
+ if (status.press_attempt) {
+
+ pressing=status.pressing_inside;
+ if (status.pressed)
+ pressing=!pressing;
+ } else {
+
+ pressing=status.pressed;
+ }
+
+ if (pressing)
+ return DRAW_PRESSED;
+ else
+ return DRAW_NORMAL;
+ }
+
+ return DRAW_NORMAL;
+}
+
+void BaseButton::set_toggle_mode(bool p_on) {
+
+ toggle_mode=p_on;
+}
+
+bool BaseButton::is_toggle_mode() const {
+
+ return toggle_mode;
+}
+
+void BaseButton::set_click_on_press(bool p_click_on_press) {
+
+ status.click_on_press=p_click_on_press;
+}
+
+bool BaseButton::get_click_on_press() const {
+
+ return status.click_on_press;
+}
+
+
+void BaseButton::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("_input_event"),&BaseButton::_input_event);
+ ObjectTypeDB::bind_method(_MD("set_pressed","pressed"),&BaseButton::set_pressed);
+ ObjectTypeDB::bind_method(_MD("is_pressed"),&BaseButton::is_pressed);
+ ObjectTypeDB::bind_method(_MD("set_toggle_mode","enabled"),&BaseButton::set_toggle_mode);
+ ObjectTypeDB::bind_method(_MD("is_toggle_mode"),&BaseButton::is_toggle_mode);
+ ObjectTypeDB::bind_method(_MD("set_disabled","disabled"),&BaseButton::set_disabled);
+ ObjectTypeDB::bind_method(_MD("is_disabled"),&BaseButton::is_disabled);
+ ObjectTypeDB::bind_method(_MD("set_click_on_press","enable"),&BaseButton::set_click_on_press);
+ ObjectTypeDB::bind_method(_MD("get_click_on_press"),&BaseButton::get_click_on_press);
+
+ ADD_SIGNAL( MethodInfo("pressed" ) );
+ ADD_SIGNAL( MethodInfo("toggled", PropertyInfo( Variant::BOOL,"pressed") ) );
+ ADD_PROPERTY( PropertyInfo( Variant::BOOL, "disabled"), _SCS("set_disabled"), _SCS("is_disabled"));
+ ADD_PROPERTY( PropertyInfo( Variant::BOOL, "toggle_mode"), _SCS("set_toggle_mode"), _SCS("is_toggle_mode"));
+ ADD_PROPERTY( PropertyInfo( Variant::BOOL, "click_on_press"), _SCS("set_click_on_press"), _SCS("get_click_on_press"));
+
+}
+
+BaseButton::BaseButton() {
+
+ toggle_mode=false;
+ status.pressed=false;
+ status.press_attempt=false;
+ status.hovering=false;
+ status.pressing_inside=false;
+ status.disabled = false;
+ status.click_on_press=false;
+ status.pressing_button=0;
+ set_focus_mode( FOCUS_ALL );
+ group=NULL;
+
+
+}
+
+BaseButton::~BaseButton()
+{
+}
+
+