diff options
Diffstat (limited to 'scene/gui/base_button.cpp')
-rw-r--r-- | scene/gui/base_button.cpp | 375 |
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() +{ +} + + |