summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/base_button.cpp58
-rw-r--r--scene/gui/base_button.h11
-rw-r--r--scene/gui/box_container.cpp1
-rw-r--r--scene/gui/button.cpp1
-rw-r--r--scene/gui/button.h4
-rw-r--r--scene/gui/color_picker.cpp5
-rw-r--r--scene/gui/color_picker.h2
-rw-r--r--scene/gui/color_ramp_edit.cpp28
-rw-r--r--scene/gui/color_ramp_edit.h28
-rw-r--r--scene/gui/control.cpp253
-rw-r--r--scene/gui/control.h18
-rw-r--r--scene/gui/custom_button.cpp40
-rw-r--r--scene/gui/custom_button.h43
-rw-r--r--scene/gui/dialogs.cpp87
-rw-r--r--scene/gui/dialogs.h7
-rw-r--r--scene/gui/file_dialog.cpp41
-rw-r--r--scene/gui/graph_edit.cpp28
-rw-r--r--scene/gui/graph_edit.h28
-rw-r--r--scene/gui/graph_node.cpp28
-rw-r--r--scene/gui/graph_node.h28
-rw-r--r--scene/gui/grid_container.cpp1
-rw-r--r--scene/gui/input_action.cpp125
-rw-r--r--scene/gui/input_action.h26
-rw-r--r--scene/gui/item_list.cpp198
-rw-r--r--scene/gui/item_list.h54
-rw-r--r--scene/gui/label.cpp8
-rw-r--r--scene/gui/line_edit.cpp22
-rw-r--r--scene/gui/link_button.cpp30
-rw-r--r--scene/gui/link_button.h28
-rw-r--r--scene/gui/menu_button.cpp21
-rw-r--r--scene/gui/patch_9_frame.cpp66
-rw-r--r--scene/gui/patch_9_frame.h32
-rw-r--r--scene/gui/popup_menu.cpp176
-rw-r--r--scene/gui/popup_menu.h19
-rw-r--r--scene/gui/rich_text_label.cpp9
-rw-r--r--scene/gui/slider.cpp1
-rw-r--r--scene/gui/split_container.cpp2
-rw-r--r--scene/gui/split_container.h2
-rw-r--r--scene/gui/tab_container.cpp13
-rw-r--r--scene/gui/text_edit.cpp201
-rw-r--r--scene/gui/text_edit.h24
-rw-r--r--scene/gui/texture_frame.cpp72
-rw-r--r--scene/gui/texture_frame.h16
-rw-r--r--scene/gui/tree.cpp20
-rw-r--r--scene/gui/tree.h3
-rw-r--r--scene/gui/video_player.cpp13
46 files changed, 1550 insertions, 371 deletions
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 3bcc60b86a..bc498f47bc 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -289,7 +289,7 @@ void BaseButton::set_disabled(bool p_disabled) {
if (p_disabled)
set_focus_mode(FOCUS_NONE);
else
- set_focus_mode(FOCUS_ALL);
+ set_focus_mode(enabled_focus_mode);
}
bool BaseButton::is_disabled() const {
@@ -377,12 +377,61 @@ bool BaseButton::get_click_on_press() const {
return status.click_on_press;
}
+void BaseButton::set_enabled_focus_mode(FocusMode p_mode) {
+ enabled_focus_mode = p_mode;
+ if (!status.disabled) {
+ set_focus_mode( p_mode );
+ }
+}
+
+Control::FocusMode BaseButton::get_enabled_focus_mode() const {
+
+ return enabled_focus_mode;
+}
+
+void BaseButton::set_shortcut(const Ref<ShortCut>& p_shortcut) {
+
+ if (shortcut.is_null() == p_shortcut.is_null())
+ return;
+
+ shortcut=p_shortcut;
+ set_process_unhandled_input(shortcut.is_valid());
+}
+
+Ref<ShortCut> BaseButton:: get_shortcut() const {
+ return shortcut;
+}
+void BaseButton::_unhandled_input(InputEvent p_event) {
+
+ if (!is_disabled() && is_visible() && shortcut.is_valid() && shortcut->is_shortcut(p_event)) {
+ if (is_toggle_mode()) {
+ set_pressed(!is_pressed());
+ emit_signal("toggled",is_pressed());
+ }
+
+ emit_signal("pressed");
+ }
+}
+
+String BaseButton::get_tooltip(const Point2& p_pos) const {
+
+ String tooltip=Control::get_tooltip(p_pos);
+ if (shortcut.is_valid() && shortcut->is_valid()) {
+ if (tooltip.find("$sc")!=-1) {
+ tooltip=tooltip.replace_first("$sc","("+shortcut->get_as_text()+")");
+ } else {
+ tooltip+=" ("+shortcut->get_as_text()+")";
+ }
+ }
+ return tooltip;
+}
void BaseButton::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_input_event"),&BaseButton::_input_event);
+ ObjectTypeDB::bind_method(_MD("_unhandled_input"),&BaseButton::_unhandled_input);
ObjectTypeDB::bind_method(_MD("set_pressed","pressed"),&BaseButton::set_pressed);
ObjectTypeDB::bind_method(_MD("is_pressed"),&BaseButton::is_pressed);
ObjectTypeDB::bind_method(_MD("is_hovered"),&BaseButton::is_hovered);
@@ -393,6 +442,10 @@ void BaseButton::_bind_methods() {
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);
ObjectTypeDB::bind_method(_MD("get_draw_mode"),&BaseButton::get_draw_mode);
+ ObjectTypeDB::bind_method(_MD("set_enabled_focus_mode","mode"),&BaseButton::set_enabled_focus_mode);
+ ObjectTypeDB::bind_method(_MD("get_enabled_focus_mode"),&BaseButton::get_enabled_focus_mode);
+ ObjectTypeDB::bind_method(_MD("set_shortcut","shortcut"),&BaseButton::set_shortcut);
+ ObjectTypeDB::bind_method(_MD("get_shortcut"),&BaseButton::get_shortcut);
BIND_VMETHOD(MethodInfo("_pressed"));
BIND_VMETHOD(MethodInfo("_toggled",PropertyInfo(Variant::BOOL,"pressed")));
@@ -404,6 +457,8 @@ void BaseButton::_bind_methods() {
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "toggle_mode"), _SCS("set_toggle_mode"), _SCS("is_toggle_mode"));
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "is_pressed"), _SCS("set_pressed"), _SCS("is_pressed"));
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "click_on_press"), _SCS("set_click_on_press"), _SCS("get_click_on_press"));
+ ADD_PROPERTY( PropertyInfo( Variant::INT,"enabled_focus_mode", PROPERTY_HINT_ENUM, "None,Click,All" ), _SCS("set_enabled_focus_mode"), _SCS("get_enabled_focus_mode") );
+ ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "shortcut",PROPERTY_HINT_RESOURCE_TYPE,"ShortCut"), _SCS("set_shortcut"), _SCS("get_shortcut"));
BIND_CONSTANT( DRAW_NORMAL );
@@ -424,6 +479,7 @@ BaseButton::BaseButton() {
status.click_on_press=false;
status.pressing_button=0;
set_focus_mode( FOCUS_ALL );
+ enabled_focus_mode = FOCUS_ALL;
group=NULL;
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index 9a5213d971..0056b00f33 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -42,6 +42,8 @@ class BaseButton : public Control {
OBJ_TYPE( BaseButton, Control );
bool toggle_mode;
+ FocusMode enabled_focus_mode;
+ Ref<ShortCut> shortcut;
struct Status {
@@ -56,6 +58,7 @@ class BaseButton : public Control {
} status;
+
ButtonGroup *group;
@@ -68,6 +71,7 @@ protected:
virtual void toggled(bool p_pressed);
static void _bind_methods();
virtual void _input_event(InputEvent p_event);
+ virtual void _unhandled_input(InputEvent p_event);
void _notification(int p_what);
public:
@@ -97,6 +101,13 @@ public:
void set_click_on_press(bool p_click_on_press);
bool get_click_on_press() const;
+ void set_enabled_focus_mode(FocusMode p_mode);
+ FocusMode get_enabled_focus_mode() const;
+
+ void set_shortcut(const Ref<ShortCut>& p_shortcut);
+ Ref<ShortCut> get_shortcut() const;
+
+ virtual String get_tooltip(const Point2& p_pos) const;
BaseButton();
~BaseButton();
diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp
index a9522cf248..a6ffc30a83 100644
--- a/scene/gui/box_container.cpp
+++ b/scene/gui/box_container.cpp
@@ -280,6 +280,7 @@ BoxContainer::AlignMode BoxContainer::get_alignment() const {
void BoxContainer::add_spacer(bool p_begin) {
Control *c = memnew( Control );
+ c->set_stop_mouse(false);
if (vertical)
c->set_v_size_flags(SIZE_EXPAND_FILL);
else
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 0f1622a838..579f6e08c9 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -213,7 +213,6 @@ Button::TextAlign Button::get_text_align() const {
return align;
}
-
void Button::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_text","text"),&Button::set_text);
diff --git a/scene/gui/button.h b/scene/gui/button.h
index 8a17a164a0..c39237c9af 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -54,7 +54,6 @@ private:
TextAlign align;
-
protected:
virtual Size2 get_minimum_size() const;
@@ -62,6 +61,8 @@ protected:
static void _bind_methods();
public:
//
+
+
void set_text(const String& p_text);
String get_text() const;
@@ -77,6 +78,7 @@ public:
void set_text_align(TextAlign p_align);
TextAlign get_text_align() const;
+
Button(const String& p_text=String());
~Button();
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index bd24b43761..d6bbdf2d21 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -664,10 +664,15 @@ bool ColorPickerButton::is_editing_alpha() const{
}
+ColorPicker *ColorPickerButton::get_picker() {
+ return picker;
+}
+
void ColorPickerButton::_bind_methods(){
ObjectTypeDB::bind_method(_MD("set_color","color"),&ColorPickerButton::set_color);
ObjectTypeDB::bind_method(_MD("get_color"),&ColorPickerButton::get_color);
+ ObjectTypeDB::bind_method(_MD("get_picker:ColorPicker"),&ColorPickerButton::get_picker);
ObjectTypeDB::bind_method(_MD("set_edit_alpha","show"),&ColorPickerButton::set_edit_alpha);
ObjectTypeDB::bind_method(_MD("is_editing_alpha"),&ColorPickerButton::is_editing_alpha);
ObjectTypeDB::bind_method(_MD("_color_changed"),&ColorPickerButton::_color_changed);
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 4559bc7391..f5de982200 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -133,6 +133,8 @@ public:
void set_edit_alpha(bool p_show);
bool is_editing_alpha() const;
+ ColorPicker *get_picker();
+
ColorPickerButton();
};
diff --git a/scene/gui/color_ramp_edit.cpp b/scene/gui/color_ramp_edit.cpp
index 2ab004e04b..50e1ffbec9 100644
--- a/scene/gui/color_ramp_edit.cpp
+++ b/scene/gui/color_ramp_edit.cpp
@@ -1,3 +1,31 @@
+/*************************************************************************/
+/* color_ramp_edit.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 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 "color_ramp_edit.h"
#include "os/keyboard.h"
diff --git a/scene/gui/color_ramp_edit.h b/scene/gui/color_ramp_edit.h
index 91292eed0d..61365d9f07 100644
--- a/scene/gui/color_ramp_edit.h
+++ b/scene/gui/color_ramp_edit.h
@@ -1,3 +1,31 @@
+/*************************************************************************/
+/* color_ramp_edit.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 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. */
+/*************************************************************************/
#ifndef SCENE_GUI_COLOR_RAMP_EDIT_H_
#define SCENE_GUI_COLOR_RAMP_EDIT_H_
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 73e7237058..edc8a8bcb8 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -153,6 +153,9 @@ bool Control::_set(const StringName& p_name, const Variant& p_value) {
update();
} else if (name.begins_with("custom_fonts/")) {
String dname = name.get_slicec('/',1);
+ if (data.font_override.has(dname)) {
+ _unref_font(data.font_override[dname]);
+ }
data.font_override.erase(dname);
notification(NOTIFICATION_THEME_CHANGED);
update();
@@ -223,7 +226,7 @@ bool Control::_get(const StringName& p_name,Variant &r_ret) const {
String sname=p_name;
- if (!sname.begins_with("custom"))
+ if (!sname.begins_with("custom")) {
if (sname.begins_with("margin/")) {
String dname = sname.get_slicec('/', 1);
if (dname == "left") {
@@ -248,6 +251,7 @@ bool Control::_get(const StringName& p_name,Variant &r_ret) const {
} else {
return false;
}
+ }
if (sname.begins_with("custom_icons/")) {
String name = sname.get_slicec('/',1);
@@ -436,11 +440,17 @@ void Control::_notification(int p_notification) {
if (is_set_as_toplevel()) {
data.SI=get_viewport()->_gui_add_subwindow_control(this);
+
+ if (data.theme.is_null() && data.parent && data.parent->data.theme_owner) {
+ data.theme_owner=data.parent->data.theme_owner;
+ notification(NOTIFICATION_THEME_CHANGED);
+ }
+
} else {
Node *parent=this; //meh
- Node *parent_control=NULL;
+ Control *parent_control=NULL;
bool subwindow=false;
while(parent) {
@@ -456,8 +466,9 @@ void Control::_notification(int p_notification) {
break;
}
- if (parent->cast_to<Control>()) {
- parent_control=parent->cast_to<Control>();
+ parent_control=parent->cast_to<Control>();
+
+ if (parent_control) {
break;
} else if (ci) {
@@ -469,6 +480,10 @@ void Control::_notification(int p_notification) {
if (parent_control) {
//do nothing, has a parent control
+ if (data.theme.is_null() && parent_control->data.theme_owner) {
+ data.theme_owner=parent_control->data.theme_owner;
+ notification(NOTIFICATION_THEME_CHANGED);
+ }
} else if (subwindow) {
//is a subwindow (process input before other controls for that canvas)
data.SI=get_viewport()->_gui_add_subwindow_control(this);
@@ -489,6 +504,10 @@ void Control::_notification(int p_notification) {
}
+ if (data.theme.is_null() && data.parent && data.parent->data.theme_owner) {
+ data.theme_owner=data.parent->data.theme_owner;
+ notification(NOTIFICATION_THEME_CHANGED);
+ }
} break;
case NOTIFICATION_EXIT_CANVAS: {
@@ -520,26 +539,9 @@ void Control::_notification(int p_notification) {
data.parent=NULL;
data.parent_canvas_item=NULL;
-
- } break;
-
-
- case NOTIFICATION_PARENTED: {
-
- Control * parent = get_parent()->cast_to<Control>();
-
- //make children reference them theme
-
- if (parent && data.theme.is_null() && parent->data.theme_owner) {
- _propagate_theme_changed(parent->data.theme_owner);
- }
-
- } break;
- case NOTIFICATION_UNPARENTED: {
-
- //make children unreference the theme
- if (data.theme.is_null() && data.theme_owner) {
- _propagate_theme_changed(NULL);
+ if (data.theme_owner && data.theme.is_null()) {
+ data.theme_owner=NULL;
+ //notification(NOTIFICATION_THEME_CHANGED);
}
} break;
@@ -770,7 +772,7 @@ Size2 Control::get_minimum_size() const {
Ref<Texture> Control::get_icon(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
+ if (p_type==StringName() || p_type=="") {
const Ref<Texture>* tex = data.icon_override.getptr(p_name);
if (tex)
@@ -785,7 +787,7 @@ Ref<Texture> Control::get_icon(const StringName& p_name,const StringName& p_type
while(theme_owner) {
if (theme_owner->data.theme->has_icon(p_name, type ) )
- return data.theme_owner->data.theme->get_icon(p_name, type );
+ return theme_owner->data.theme->get_icon(p_name, type );
Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to<Control>():NULL;
if (parent)
@@ -800,7 +802,7 @@ Ref<Texture> Control::get_icon(const StringName& p_name,const StringName& p_type
}
Ref<Shader> Control::get_shader(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
+ if (p_type==StringName() || p_type=="") {
const Ref<Shader>* sdr = data.shader_override.getptr(p_name);
if (sdr)
@@ -815,7 +817,7 @@ Ref<Shader> Control::get_shader(const StringName& p_name,const StringName& p_typ
while(theme_owner) {
if (theme_owner->data.theme->has_shader(p_name, type))
- return data.theme_owner->data.theme->get_shader(p_name, type );
+ return theme_owner->data.theme->get_shader(p_name, type );
Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to<Control>():NULL;
if (parent)
@@ -830,7 +832,7 @@ Ref<Shader> Control::get_shader(const StringName& p_name,const StringName& p_typ
Ref<StyleBox> Control::get_stylebox(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
+ if (p_type==StringName() || p_type=="") {
const Ref<StyleBox>* style = data.style_override.getptr(p_name);
if (style)
return *style;
@@ -843,8 +845,9 @@ Ref<StyleBox> Control::get_stylebox(const StringName& p_name,const StringName& p
while(theme_owner) {
- if (theme_owner->data.theme->has_stylebox(p_name, type ) )
- return data.theme_owner->data.theme->get_stylebox(p_name, type );
+ if (theme_owner->data.theme->has_stylebox(p_name, type ) ) {
+ return theme_owner->data.theme->get_stylebox(p_name, type );
+ }
Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to<Control>():NULL;
if (parent)
@@ -858,7 +861,7 @@ Ref<StyleBox> Control::get_stylebox(const StringName& p_name,const StringName& p
}
Ref<Font> Control::get_font(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
+ if (p_type==StringName() || p_type=="") {
const Ref<Font>* font = data.font_override.getptr(p_name);
if (font)
return *font;
@@ -872,7 +875,7 @@ Ref<Font> Control::get_font(const StringName& p_name,const StringName& p_type) c
while(theme_owner) {
if (theme_owner->data.theme->has_font(p_name, type ) )
- return data.theme_owner->data.theme->get_font(p_name, type );
+ return theme_owner->data.theme->get_font(p_name, type );
if (theme_owner->data.theme->get_default_theme_font().is_valid())
return theme_owner->data.theme->get_default_theme_font();
Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to<Control>():NULL;
@@ -889,7 +892,7 @@ Ref<Font> Control::get_font(const StringName& p_name,const StringName& p_type) c
}
Color Control::get_color(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
+ if (p_type==StringName() || p_type=="") {
const Color* color = data.color_override.getptr(p_name);
if (color)
return *color;
@@ -902,7 +905,7 @@ Color Control::get_color(const StringName& p_name,const StringName& p_type) cons
while(theme_owner) {
if (theme_owner->data.theme->has_color(p_name, type ) )
- return data.theme_owner->data.theme->get_color(p_name, type );
+ return theme_owner->data.theme->get_color(p_name, type );
Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to<Control>():NULL;
if (parent)
@@ -918,7 +921,7 @@ Color Control::get_color(const StringName& p_name,const StringName& p_type) cons
int Control::get_constant(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
+ if (p_type==StringName() || p_type=="") {
const int* constant = data.constant_override.getptr(p_name);
if (constant)
return *constant;
@@ -931,7 +934,7 @@ int Control::get_constant(const StringName& p_name,const StringName& p_type) con
while(theme_owner) {
if (theme_owner->data.theme->has_constant(p_name, type ) )
- return data.theme_owner->data.theme->get_constant(p_name, type );
+ return theme_owner->data.theme->get_constant(p_name, type );
Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to<Control>():NULL;
if (parent)
@@ -946,12 +949,64 @@ int Control::get_constant(const StringName& p_name,const StringName& p_type) con
}
+bool Control::has_icon_override(const StringName& p_name) const {
+
+ const Ref<Texture>* tex = data.icon_override.getptr(p_name);
+ if (tex)
+ return true;
+ else
+ return false;
+}
+
+bool Control::has_shader_override(const StringName &p_name) const {
+
+ const Ref<Shader>* sdr = data.shader_override.getptr(p_name);
+ if (sdr)
+ return true;
+ else
+ return false;
+}
+
+bool Control::has_stylebox_override(const StringName& p_name) const {
+
+ const Ref<StyleBox>* style = data.style_override.getptr(p_name);
+ if (style)
+ return true;
+ else
+ return false;
+}
+
+bool Control::has_font_override(const StringName& p_name) const {
+
+ const Ref<Font>* font = data.font_override.getptr(p_name);
+ if (font)
+ return true;
+ else
+ return false;
+}
+
+bool Control::has_color_override(const StringName& p_name) const {
+
+ const Color* color = data.color_override.getptr(p_name);
+ if (color)
+ return true;
+ else
+ return false;
+}
+
+bool Control::has_constant_override(const StringName& p_name) const {
+
+ const int* constant = data.constant_override.getptr(p_name);
+ if (constant)
+ return true;
+ else
+ return false;
+}
bool Control::has_icon(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
- const Ref<Texture>* tex = data.icon_override.getptr(p_name);
- if (tex)
+ if (p_type==StringName() || p_type=="") {
+ if (has_icon_override(p_name) == true)
return true;
}
@@ -977,11 +1032,10 @@ bool Control::has_icon(const StringName& p_name,const StringName& p_type) const
}
-bool Control::has_shader(const StringName &p_name, const StringName &p_type) const
-{
- if (p_type==StringName()) {
- const Ref<Shader>* sdr = data.shader_override.getptr(p_name);
- if (sdr)
+bool Control::has_shader(const StringName &p_name, const StringName &p_type) const {
+
+ if (p_type==StringName() || p_type=="") {
+ if (has_shader_override(p_name)==true)
return true;
}
@@ -1008,10 +1062,8 @@ bool Control::has_shader(const StringName &p_name, const StringName &p_type) con
}
bool Control::has_stylebox(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
- const Ref<StyleBox>* style = data.style_override.getptr(p_name);
-
- if (style)
+ if (p_type==StringName() || p_type=="") {
+ if (has_stylebox_override(p_name)==true)
return true;
}
@@ -1038,9 +1090,8 @@ bool Control::has_stylebox(const StringName& p_name,const StringName& p_type) co
}
bool Control::has_font(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
- const Ref<Font>* font = data.font_override.getptr(p_name);
- if (font)
+ if (p_type==StringName() || p_type=="") {
+ if (has_font_override(p_name)==true)
return true;
}
@@ -1066,11 +1117,11 @@ bool Control::has_font(const StringName& p_name,const StringName& p_type) const
return Theme::get_default()->has_font( p_name, type );
}
-bool Control::has_color(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
- const Color* color = data.color_override.getptr(p_name);
- if (color)
+bool Control::has_color(const StringName& p_name, const StringName& p_type) const {
+
+ if (p_type==StringName() || p_type=="") {
+ if (has_color_override(p_name)==true)
return true;
}
@@ -1098,10 +1149,8 @@ bool Control::has_color(const StringName& p_name,const StringName& p_type) const
bool Control::has_constant(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
-
- const int* constant = data.constant_override.getptr(p_name);
- if (constant)
+ if (p_type==StringName() || p_type=="") {
+ if (has_constant_override(p_name) == true)
return true;
}
@@ -1505,7 +1554,15 @@ void Control::add_style_override(const StringName& p_name, const Ref<StyleBox>&
void Control::add_font_override(const StringName& p_name, const Ref<Font>& p_font) {
ERR_FAIL_COND(p_font.is_null());
+ if (data.font_override.has(p_name)) {
+ _unref_font(data.font_override[p_name]);
+ }
data.font_override[p_name]=p_font;
+
+ if (p_font.is_valid()) {
+ _ref_font(p_font);
+ }
+
notification(NOTIFICATION_THEME_CHANGED);
update();
}
@@ -1794,34 +1851,46 @@ void Control::_modal_stack_remove() {
}
-void Control::_propagate_theme_changed(Control *p_owner) {
+void Control::_propagate_theme_changed(CanvasItem *p_at,Control *p_owner) {
- for(int i=0;i<get_child_count();i++) {
+ Control *c = p_at->cast_to<Control>();
+
+ if (c && c!=p_owner && c->data.theme.is_valid()) // has a theme, this can't be propagated
+ return;
+
+ for(int i=0;i<p_at->get_child_count();i++) {
+
+ CanvasItem *child = p_at->get_child(i)->cast_to<CanvasItem>();
+ if (child) {
+ _propagate_theme_changed(child,p_owner);
+ }
- Control *child = get_child(i)->cast_to<Control>();
- if (child && child->data.theme.is_null()) //has no theme, propagate
- child->_propagate_theme_changed(p_owner);
}
- data.theme_owner=p_owner;
- _notification(NOTIFICATION_THEME_CHANGED);
- update();
+
+ if (c) {
+
+ c->data.theme_owner=p_owner;
+ c->_notification(NOTIFICATION_THEME_CHANGED);
+ c->update();
+ }
}
void Control::set_theme(const Ref<Theme>& p_theme) {
+
data.theme=p_theme;
if (!p_theme.is_null()) {
- _propagate_theme_changed(this);
+ _propagate_theme_changed(this,this);
} else {
Control *parent = get_parent()?get_parent()->cast_to<Control>():NULL;
if (parent && parent->data.theme_owner) {
- _propagate_theme_changed(parent->data.theme_owner);
+ _propagate_theme_changed(this,parent->data.theme_owner);
} else {
- _propagate_theme_changed(NULL);
+ _propagate_theme_changed(this,NULL);
}
}
@@ -2186,6 +2255,33 @@ float Control::_get_rotation_deg() const {
WARN_PRINT("Deprecated method Control._get_rotation_deg(): This method was renamed to get_rotation_deg. Please adapt your code accordingly, as the old method will be obsoleted.");
return get_rotation_deg();
}
+//needed to update the control if the font changes..
+void Control::_ref_font( Ref<Font> p_sc) {
+
+ if (!data.font_refcount.has(p_sc)) {
+ data.font_refcount[p_sc]=1;
+ p_sc->connect("changed",this,"_font_changed");
+ } else {
+ data.font_refcount[p_sc]+=1;
+ }
+}
+
+void Control::_unref_font(Ref<Font> p_sc) {
+
+ ERR_FAIL_COND(!data.font_refcount.has(p_sc));
+ data.font_refcount[p_sc]--;
+ if (data.font_refcount[p_sc]==0) {
+ p_sc->disconnect("changed",this,"_font_changed");
+ data.font_refcount.erase(p_sc);
+ }
+}
+
+void Control::_font_changed(){
+
+ update();
+ notification(NOTIFICATION_THEME_CHANGED);
+ minimum_size_changed(); //fonts affect minimum size pretty much almost always
+}
void Control::set_scale(const Vector2& p_scale){
@@ -2265,6 +2361,7 @@ void Control::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_area_as_parent_rect","margin"),&Control::set_area_as_parent_rect,DEFVAL(0));
ObjectTypeDB::bind_method(_MD("show_modal","exclusive"),&Control::show_modal,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("set_focus_mode","mode"),&Control::set_focus_mode);
+ ObjectTypeDB::bind_method(_MD("get_focus_mode"),&Control::get_focus_mode);
ObjectTypeDB::bind_method(_MD("has_focus"),&Control::has_focus);
ObjectTypeDB::bind_method(_MD("grab_focus"),&Control::grab_focus);
ObjectTypeDB::bind_method(_MD("release_focus"),&Control::release_focus);
@@ -2295,6 +2392,17 @@ void Control::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_color","name","type"),&Control::get_color,DEFVAL(""));
ObjectTypeDB::bind_method(_MD("get_constant","name","type"),&Control::get_constant,DEFVAL(""));
+ ObjectTypeDB::bind_method(_MD("has_icon_override", "name"), &Control::has_icon_override);
+ ObjectTypeDB::bind_method(_MD("has_stylebox_override", "name"), &Control::has_stylebox_override);
+ ObjectTypeDB::bind_method(_MD("has_font_override", "name"), &Control::has_font_override);
+ ObjectTypeDB::bind_method(_MD("has_color_override", "name"), &Control::has_color_override);
+ ObjectTypeDB::bind_method(_MD("has_constant_override", "name"), &Control::has_constant_override);
+
+ ObjectTypeDB::bind_method(_MD("has_icon", "name", "type"), &Control::has_icon, DEFVAL(""));
+ ObjectTypeDB::bind_method(_MD("has_stylebox", "name", "type"), &Control::has_stylebox, DEFVAL(""));
+ ObjectTypeDB::bind_method(_MD("has_font", "name", "type"), &Control::has_font, DEFVAL(""));
+ ObjectTypeDB::bind_method(_MD("has_color", "name", "type"), &Control::has_color, DEFVAL(""));
+ ObjectTypeDB::bind_method(_MD("has_constant", "name", "type"), &Control::has_constant, DEFVAL(""));
ObjectTypeDB::bind_method(_MD("get_parent_control:Control"),&Control::get_parent_control);
@@ -2324,6 +2432,9 @@ void Control::_bind_methods() {
ObjectTypeDB::bind_method(_MD("warp_mouse","to_pos"),&Control::warp_mouse);
+ ObjectTypeDB::bind_method(_MD("minimum_size_changed"), &Control::minimum_size_changed);
+
+ ObjectTypeDB::bind_method(_MD("_font_changed"), &Control::_font_changed);
BIND_VMETHOD(MethodInfo("_input_event",PropertyInfo(Variant::INPUT_EVENT,"event")));
BIND_VMETHOD(MethodInfo(Variant::VECTOR2,"get_minimum_size"));
diff --git a/scene/gui/control.h b/scene/gui/control.h
index f720185c9d..07a28de1ea 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -35,7 +35,7 @@
#include "scene/2d/canvas_item.h"
#include "math_2d.h"
#include "rid.h"
-
+#include "scene/gui/input_action.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -153,6 +153,8 @@ private:
HashMap<StringName, Ref<Font>, StringNameHasher > font_override;
HashMap<StringName, Color, StringNameHasher > color_override;
HashMap<StringName, int, StringNameHasher > constant_override;
+ Map< Ref<Font>, int> font_refcount;
+
} data;
// used internally
@@ -169,7 +171,7 @@ private:
float _get_range(int p_idx) const;
float _s2a(float p_val, AnchorType p_anchor,float p_range) const;
float _a2s(float p_val, AnchorType p_anchor,float p_range) const;
- void _propagate_theme_changed(Control *p_owner);
+ void _propagate_theme_changed(CanvasItem *p_at, Control *p_owner);
void _change_notify_margins();
void _update_minimum_size();
@@ -184,6 +186,11 @@ private:
void _set_rotation_deg(float p_degrees);
float _get_rotation_deg() const;
+ void _ref_font(Ref<Font> p_sc);
+ void _unref_font( Ref<Font> p_sc);
+ void _font_changed();
+
+
friend class Viewport;
void _modal_stack_remove();
void _modal_set_prev_focus_owner(ObjectID p_prev);
@@ -341,6 +348,13 @@ public:
Color get_color(const StringName& p_name,const StringName& p_type=StringName()) const;
int get_constant(const StringName& p_name,const StringName& p_type=StringName()) const;
+ bool has_icon_override(const StringName& p_name) const;
+ bool has_shader_override(const StringName& p_name) const;
+ bool has_stylebox_override(const StringName& p_name) const;
+ bool has_font_override(const StringName& p_name) const;
+ bool has_color_override(const StringName& p_name) const;
+ bool has_constant_override(const StringName& p_name) const;
+
bool has_icon(const StringName& p_name,const StringName& p_type=StringName()) const;
bool has_shader(const StringName& p_name,const StringName& p_type=StringName()) const;
bool has_stylebox(const StringName& p_name,const StringName& p_type=StringName()) const;
diff --git a/scene/gui/custom_button.cpp b/scene/gui/custom_button.cpp
deleted file mode 100644
index a70af05418..0000000000
--- a/scene/gui/custom_button.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*************************************************************************/
-/* custom_button.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2016 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 "custom_button.h"
-
-CustomButton::CustomButton()
-{
-}
-
-
-CustomButton::~CustomButton()
-{
-}
-
-
diff --git a/scene/gui/custom_button.h b/scene/gui/custom_button.h
deleted file mode 100644
index 2492750489..0000000000
--- a/scene/gui/custom_button.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*************************************************************************/
-/* custom_button.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2016 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. */
-/*************************************************************************/
-#ifndef CUSTOM_BUTTON_H
-#define CUSTOM_BUTTON_H
-
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-class CustomButton{
-public:
- CustomButton();
-
- ~CustomButton();
-
-};
-
-#endif
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index 51242d89bd..6342391383 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -118,6 +118,16 @@ void WindowDialog::set_title(const String& p_title) {
update();
}
+Size2 WindowDialog::get_minimum_size() const {
+
+ Ref<Font> font = get_font("title_font","WindowDialog");
+ int msx=close_button->get_combined_minimum_size().x;
+ msx+=font->get_string_size(title).x;
+
+ return Size2(msx,1);
+}
+
+
String WindowDialog::get_title() const {
return title;
@@ -192,11 +202,9 @@ void AcceptDialog::_notification(int p_what) {
if (p_what==NOTIFICATION_MODAL_CLOSE) {
cancel_pressed();
- } if (p_what==NOTIFICATION_DRAW) {
-
-
-
+ } if (p_what==NOTIFICATION_RESIZED) {
+ _update_child_rect();
}
}
@@ -244,12 +252,69 @@ void AcceptDialog::register_text_enter(Node *p_line_edit) {
p_line_edit->connect("text_entered", this,"_builtin_text_entered");
}
+void AcceptDialog::_update_child_rect() {
+
+ int margin = get_constant("margin","Dialogs");
+ Size2 size = get_size();
+ Size2 hminsize = hbc->get_combined_minimum_size();
+
+ Vector2 cpos(margin,margin);
+ Vector2 csize(size.x-margin*2,size.y-margin*3-hminsize.y);
+ label->set_pos(cpos);
+ label->set_size(csize);
+
+ if (child) {
+
+ child->set_pos(cpos);
+ child->set_size(csize);
+ }
+
+ cpos.y+=csize.y+margin;
+ csize.y=hminsize.y;
+
+ hbc->set_pos(cpos);
+ hbc->set_size(csize);
+
+}
+
+Size2 AcceptDialog::get_minimum_size() const {
+
+ int margin = get_constant("margin","Dialogs");
+ Size2 minsize = label->get_combined_minimum_size();
+ if (child) {
+
+ Size2 cminsize = child->get_combined_minimum_size();
+ minsize.x=MAX(cminsize.x,minsize.x);
+ minsize.y=MAX(cminsize.y,minsize.y);
+ }
+
+ Size2 hminsize = hbc->get_combined_minimum_size();
+ minsize.x = MAX(hminsize.x,minsize.x);
+ minsize.y+=hminsize.y;
+ minsize.x+=margin*2;
+ minsize.y+=margin*3; //one as separation between hbc and child
+
+ Size2 wmsize = WindowDialog::get_minimum_size();
+ minsize.x=MAX(wmsize.x,minsize.x);
+ return minsize;
+}
+
+
void AcceptDialog::set_child_rect(Control *p_child) {
ERR_FAIL_COND(p_child->get_parent()!=this);
- p_child->set_area_as_parent_rect(get_constant("margin","Dialogs"));
- p_child->set_margin(MARGIN_BOTTOM, get_constant("button_margin","Dialogs")+10);
+ //p_child->set_area_as_parent_rect(get_constant("margin","Dialogs"));
+ child=p_child;
+ minimum_size_changed();
+ _update_child_rect();
+}
+
+void AcceptDialog::remove_child_notify(Node *p_child) {
+
+ if (p_child==child) {
+ child=NULL;
+ }
}
void AcceptDialog::_custom_action(const String& p_action) {
@@ -284,7 +349,7 @@ Button* AcceptDialog::add_cancel(const String &p_cancel) {
String c = p_cancel;
if (p_cancel=="")
- c="Cancel";
+ c=RTR("Cancel");
Button *b = swap_ok_cancel ? add_button(c,true) : add_button(c);
b->connect("pressed",this,"_closed");
return b;
@@ -341,7 +406,7 @@ AcceptDialog::AcceptDialog() {
hbc->add_spacer();
ok = memnew( Button );
- ok->set_text("OK");
+ ok->set_text(RTR("OK"));
hbc->add_child(ok);
hbc->add_spacer();
//add_child(ok);
@@ -351,7 +416,9 @@ AcceptDialog::AcceptDialog() {
set_as_toplevel(true);
hide_on_ok=true;
- set_title("Alert!");
+ set_title(RTR("Alert!"));
+
+ child=NULL;
}
@@ -372,6 +439,6 @@ Button *ConfirmationDialog::get_cancel() {
ConfirmationDialog::ConfirmationDialog() {
- set_title("Please Confirm...");
+ set_title(RTR("Please Confirm..."));
cancel = add_cancel();
}
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index f256c49aee..d00bb41ff6 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -64,6 +64,8 @@ public:
void set_title(const String& p_title);
String get_title() const;
+ Size2 get_minimum_size() const;
+
WindowDialog();
~WindowDialog();
@@ -89,6 +91,7 @@ class AcceptDialog : public WindowDialog {
OBJ_TYPE(AcceptDialog,WindowDialog);
+ Control *child;
HBoxContainer *hbc;
Label *label;
Button *ok;
@@ -100,10 +103,12 @@ class AcceptDialog : public WindowDialog {
void _ok_pressed();
void _close_pressed();
void _builtin_text_entered(const String& p_text);
+ void _update_child_rect();
static bool swap_ok_cancel;
+ virtual void remove_child_notify(Node *p_child);
protected:
@@ -116,6 +121,8 @@ protected:
virtual void custom_action(const String&) {}
public:
+ Size2 get_minimum_size() const;
+
Label *get_label() { return label; }
static void set_swap_ok_cancel(bool p_swap);
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 705ce55d42..d335399caa 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -258,7 +258,7 @@ void FileDialog::_action_pressed() {
}
if (dir_access->file_exists(f)) {
- confirm_save->set_text("File Exists, Overwrite?");
+ confirm_save->set_text(RTR("File Exists, Overwrite?"));
confirm_save->popup_centered(Size2(200,80));
} else {
@@ -339,6 +339,11 @@ void FileDialog::update_file_list() {
}
}
+ if (dirs.find("..")==NULL) {
+ //may happen if lacking permissions
+ dirs.push_back("..");
+ }
+
dirs.sort_custom<NoCaseComparator>();
files.sort_custom<NoCaseComparator>();
@@ -463,7 +468,7 @@ void FileDialog::update_filters() {
if (max_filters<filters.size())
all_filters+=", ...";
- filter->add_item("All Recognized ( "+all_filters+" )");
+ filter->add_item(RTR("All Recognized")+" ( "+all_filters+" )");
}
for(int i=0;i<filters.size();i++) {
@@ -475,7 +480,7 @@ void FileDialog::update_filters() {
filter->add_item("( "+flt+" )");
}
- filter->add_item("All Files (*)");
+ filter->add_item(RTR("All Files (*)"));
}
@@ -548,11 +553,11 @@ void FileDialog::set_mode(Mode p_mode) {
mode=p_mode;
switch(mode) {
- case MODE_OPEN_FILE: get_ok()->set_text("Open"); set_title("Open a File"); makedir->hide(); break;
- case MODE_OPEN_FILES: get_ok()->set_text("Open"); set_title("Open File(s)"); makedir->hide(); break;
- case MODE_OPEN_DIR: get_ok()->set_text("Open"); set_title("Open a Directory"); makedir->show(); break;
- case MODE_OPEN_ANY: get_ok()->set_text("Open"); set_title("Open a File or Directory"); makedir->show(); break;
- case MODE_SAVE_FILE: get_ok()->set_text("Save"); set_title("Save a File"); makedir->show(); break;
+ case MODE_OPEN_FILE: get_ok()->set_text(RTR("Open")); set_title(RTR("Open a File")); makedir->hide(); break;
+ case MODE_OPEN_FILES: get_ok()->set_text(RTR("Open")); set_title(RTR("Open File(s)")); makedir->hide(); break;
+ case MODE_OPEN_DIR: get_ok()->set_text(RTR("Open")); set_title(RTR("Open a Directory")); makedir->show(); break;
+ case MODE_OPEN_ANY: get_ok()->set_text(RTR("Open")); set_title(RTR("Open a File or Directory")); makedir->show(); break;
+ case MODE_SAVE_FILE: get_ok()->set_text(RTR("Save")); set_title(RTR("Save a File")); makedir->show(); break;
}
if (mode==MODE_OPEN_FILES) {
@@ -742,7 +747,7 @@ FileDialog::FileDialog() {
set_child_rect(vbc);
mode=MODE_SAVE_FILE;
- set_title("Save a File");
+ set_title(RTR("Save a File"));
dir = memnew(LineEdit);
HBoxContainer *pathhb = memnew( HBoxContainer );
@@ -758,24 +763,24 @@ FileDialog::FileDialog() {
drives->connect("item_selected",this,"_select_drive");
makedir = memnew( Button );
- makedir->set_text("Create Folder");
+ makedir->set_text(RTR("Create Folder"));
makedir->connect("pressed",this,"_make_dir");
pathhb->add_child(makedir);
- vbc->add_margin_child("Path:",pathhb);
+ vbc->add_margin_child(RTR("Path:"),pathhb);
tree = memnew(Tree);
tree->set_hide_root(true);
- vbc->add_margin_child("Directories & Files:",tree,true);
+ vbc->add_margin_child(RTR("Directories & Files:"),tree,true);
file = memnew(LineEdit);
//add_child(file);
- vbc->add_margin_child("File:",file);
+ vbc->add_margin_child(RTR("File:"),file);
filter = memnew( OptionButton );
//add_child(filter);
- vbc->add_margin_child("Filter:",filter);
+ vbc->add_margin_child(RTR("Filter:"),filter);
filter->set_clip_text(true);//too many extensions overflow it
dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES);
@@ -800,21 +805,21 @@ FileDialog::FileDialog() {
confirm_save->connect("confirmed", this,"_save_confirm_pressed");
makedialog = memnew( ConfirmationDialog );
- makedialog->set_title("Create Folder");
+ makedialog->set_title(RTR("Create Folder"));
VBoxContainer *makevb= memnew( VBoxContainer );
makedialog->add_child(makevb);
makedialog->set_child_rect(makevb);
makedirname = memnew( LineEdit );
- makevb->add_margin_child("Name:",makedirname);
+ makevb->add_margin_child(RTR("Name:"),makedirname);
add_child(makedialog);
makedialog->register_text_enter(makedirname);
makedialog->connect("confirmed",this,"_make_dir_confirm");
mkdirerr = memnew( AcceptDialog );
- mkdirerr->set_text("Could not create folder.");
+ mkdirerr->set_text(RTR("Could not create folder."));
add_child(mkdirerr);
exterr = memnew( AcceptDialog );
- exterr->set_text("Must use a valid extension.");
+ exterr->set_text(RTR("Must use a valid extension."));
add_child(exterr);
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 9123194589..ee3b8913b4 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -1,3 +1,31 @@
+/*************************************************************************/
+/* graph_edit.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 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 "graph_edit.h"
#include "os/input.h"
#include "os/keyboard.h"
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index 8a7721b9b5..ac4e71ba49 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -1,3 +1,31 @@
+/*************************************************************************/
+/* graph_edit.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 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. */
+/*************************************************************************/
#ifndef GRAPH_EDIT_H
#define GRAPH_EDIT_H
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index eef1bf79c4..94001b2ac1 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -1,3 +1,31 @@
+/*************************************************************************/
+/* graph_node.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 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 "graph_node.h"
#include "method_bind_ext.inc"
diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h
index dc407a6809..5a50d0d68d 100644
--- a/scene/gui/graph_node.h
+++ b/scene/gui/graph_node.h
@@ -1,3 +1,31 @@
+/*************************************************************************/
+/* graph_node.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 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. */
+/*************************************************************************/
#ifndef GRAPH_NODE_H
#define GRAPH_NODE_H
diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp
index a514f1b3d7..dde9768a6d 100644
--- a/scene/gui/grid_container.cpp
+++ b/scene/gui/grid_container.cpp
@@ -158,6 +158,7 @@ void GridContainer::set_columns(int p_columns) {
columns=p_columns;
queue_sort();
+ minimum_size_changed();
}
diff --git a/scene/gui/input_action.cpp b/scene/gui/input_action.cpp
new file mode 100644
index 0000000000..c4e7a75298
--- /dev/null
+++ b/scene/gui/input_action.cpp
@@ -0,0 +1,125 @@
+#include "input_action.h"
+#include "os/keyboard.h"
+
+void ShortCut::set_shortcut(const InputEvent& p_shortcut){
+
+ shortcut=p_shortcut;
+ emit_changed();
+}
+
+InputEvent ShortCut::get_shortcut() const{
+
+ return shortcut;
+}
+
+bool ShortCut::is_shortcut(const InputEvent& p_event) const {
+
+ bool same=false;
+
+
+ switch(p_event.type) {
+
+ case InputEvent::KEY: {
+
+ same=(shortcut.key.scancode==p_event.key.scancode && shortcut.key.mod == p_event.key.mod);
+
+ } break;
+ case InputEvent::JOYSTICK_BUTTON: {
+
+ same=(shortcut.joy_button.button_index==p_event.joy_button.button_index);
+
+ } break;
+ case InputEvent::MOUSE_BUTTON: {
+
+ same=(shortcut.mouse_button.button_index==p_event.mouse_button.button_index);
+
+ } break;
+ case InputEvent::JOYSTICK_MOTION: {
+
+ same=(shortcut.joy_motion.axis==p_event.joy_motion.axis && (shortcut.joy_motion.axis_value < 0) == (p_event.joy_motion.axis_value < 0));
+
+ } break;
+ default: {};
+ }
+
+ return same;
+}
+
+String ShortCut::get_as_text() const {
+
+ switch(shortcut.type) {
+
+ case InputEvent::NONE: {
+
+ return "None";
+ } break;
+ case InputEvent::KEY: {
+
+ String str;
+ if (shortcut.key.mod.shift)
+ str+=RTR("Shift+");
+ if (shortcut.key.mod.alt)
+ str+=RTR("Alt+");
+ if (shortcut.key.mod.control)
+ str+=RTR("Ctrl+");
+ if (shortcut.key.mod.meta)
+ str+=RTR("Meta+");
+
+ str+=keycode_get_string(shortcut.key.scancode).capitalize();
+
+ return str;
+ } break;
+ case InputEvent::JOYSTICK_BUTTON: {
+
+ String str = RTR("Device")+" "+itos(shortcut.device)+", "+RTR("Button")+" "+itos(shortcut.joy_button.button_index);
+ str+=".";
+
+ return str;
+ } break;
+ case InputEvent::MOUSE_BUTTON: {
+
+ String str = RTR("Device")+" "+itos(shortcut.device)+", ";
+ switch (shortcut.mouse_button.button_index) {
+ case BUTTON_LEFT: str+=RTR("Left Button."); break;
+ case BUTTON_RIGHT: str+=RTR("Right Button."); break;
+ case BUTTON_MIDDLE: str+=RTR("Middle Button."); break;
+ case BUTTON_WHEEL_UP: str+=RTR("Wheel Up."); break;
+ case BUTTON_WHEEL_DOWN: str+=RTR("Wheel Down."); break;
+ default: str+=RTR("Button")+" "+itos(shortcut.mouse_button.button_index)+".";
+ }
+
+ return str;
+ } break;
+ case InputEvent::JOYSTICK_MOTION: {
+
+ int ax = shortcut.joy_motion.axis;
+ String str = RTR("Device")+" "+itos(shortcut.device)+", "+RTR("Axis")+" "+itos(ax)+".";
+
+ return str;
+ } break;
+ }
+
+ return "";
+}
+
+bool ShortCut::is_valid() const {
+
+ return shortcut.type!=InputEvent::NONE;
+}
+
+void ShortCut::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_shortcut","event"),&ShortCut::set_shortcut);
+ ObjectTypeDB::bind_method(_MD("get_shortcut"),&ShortCut::get_shortcut);
+
+ ObjectTypeDB::bind_method(_MD("is_valid"),&ShortCut::is_valid);
+
+ ObjectTypeDB::bind_method(_MD("is_shortcut","event"),&ShortCut::is_shortcut);
+ ObjectTypeDB::bind_method(_MD("get_as_text"),&ShortCut::get_as_text);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INPUT_EVENT,"shortcut"),_SCS("set_shortcut"),_SCS("get_shortcut"));
+}
+
+ShortCut::ShortCut(){
+
+}
diff --git a/scene/gui/input_action.h b/scene/gui/input_action.h
new file mode 100644
index 0000000000..8e0e1ef0bd
--- /dev/null
+++ b/scene/gui/input_action.h
@@ -0,0 +1,26 @@
+#ifndef INPUTACTION_H
+#define INPUTACTION_H
+
+#include "resource.h"
+
+class ShortCut : public Resource {
+
+ OBJ_TYPE(ShortCut,Resource);
+
+ InputEvent shortcut;
+protected:
+
+ static void _bind_methods();
+public:
+
+ void set_shortcut(const InputEvent& p_shortcut);
+ InputEvent get_shortcut() const;
+ bool is_shortcut(const InputEvent& p_Event) const;
+ bool is_valid() const;
+
+ String get_as_text() const;
+
+ ShortCut();
+};
+
+#endif // INPUTACTION_H
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index c1a0e43e49..5379836746 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -1,3 +1,31 @@
+/*************************************************************************/
+/* item_list.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 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 "item_list.h"
#include "os/os.h"
#include "globals.h"
@@ -325,6 +353,18 @@ int ItemList::get_fixed_column_width() const{
return fixed_column_width;
}
+void ItemList::set_same_column_width(bool p_enable){
+
+ same_column_width=p_enable;
+ update();
+ shape_changed=true;
+
+}
+int ItemList::is_same_column_width() const{
+
+ return same_column_width;
+}
+
void ItemList::set_max_text_lines(int p_lines){
ERR_FAIL_COND(p_lines<1);
@@ -372,27 +412,16 @@ ItemList::IconMode ItemList::get_icon_mode() const{
return icon_mode;
}
-void ItemList::set_min_icon_size(const Size2& p_size) {
-
- min_icon_size=p_size;
- update();
-}
-
-Size2 ItemList::get_min_icon_size() const {
-
- return min_icon_size;
-}
+void ItemList::set_fixed_icon_size(const Size2& p_size) {
-void ItemList::set_max_icon_size(const Size2& p_size) {
-
- max_icon_size=p_size;
+ fixed_icon_size=p_size;
update();
}
-Size2 ItemList::get_max_icon_size() const {
+Size2 ItemList::get_fixed_icon_size() const {
- return max_icon_size;
+ return fixed_icon_size;
}
Size2 ItemList::Item::get_icon_size() const {
@@ -720,51 +749,21 @@ void ItemList::ensure_current_is_visible() {
update();
}
-static Size2 _adjust_to_max_size(Size2 p_size, Size2 p_max_size) {
-
- if (p_max_size.x<=0)
- p_max_size.x=1e20;
- if (p_max_size.y<=0)
- p_max_size.y=1e20;
-
-
- Size2 new_size;
+static Rect2 _adjust_to_max_size(Size2 p_size, Size2 p_max_size) {
- if (p_size.x > p_max_size.x) {
+ Size2 size=p_max_size;
+ int tex_width = p_size.width * size.height / p_size.height;
+ int tex_height = size.height;
- new_size.width=p_max_size.x;
- new_size.height=p_size.height * p_max_size.width / p_size.width;
-
- if (new_size.height > p_max_size.height) {
- new_size=Size2(); //invalid
- }
+ if (tex_width>size.width) {
+ tex_width=size.width;
+ tex_height=p_size.height * tex_width / p_size.width;
}
+ int ofs_x=(size.width - tex_width)/2;
+ int ofs_y=(size.height - tex_height)/2;
- if (p_size.y > p_max_size.y) {
-
- Size2 new_size2;
- new_size2.height=p_max_size.y;
- new_size2.width=p_size.width * p_max_size.height / p_size.height;
-
- if (new_size2.width < p_max_size.width) {
-
- if (new_size!=Size2()) {
-
- if (new_size2.x*new_size2.y > new_size.x*new_size.y) {
- new_size=new_size2;
- }
- } else {
- new_size=new_size2;
- }
- }
-
- }
-
- if (new_size==Size2())
- return p_size;
- else
- return new_size;
+ return Rect2(ofs_x,ofs_y,tex_width,tex_height);
}
@@ -824,6 +823,8 @@ void ItemList::_notification(int p_what) {
}
if (shape_changed) {
+
+ float max_column_width = 0;
//1- compute item minimum sizes
for(int i=0;i<items.size();i++) {
@@ -831,7 +832,11 @@ void ItemList::_notification(int p_what) {
Size2 minsize;
if (items[i].icon.is_valid()) {
- minsize=_adjust_to_max_size(items[i].get_icon_size(),max_icon_size);
+ if (fixed_icon_size.x>0 && fixed_icon_size.y>0) {
+ minsize=fixed_icon_size* icon_scale;
+ } else {
+ minsize=items[i].get_icon_size() *icon_scale;
+ }
if (items[i].text!="") {
if (icon_mode==ICON_MODE_TOP) {
@@ -864,10 +869,11 @@ void ItemList::_notification(int p_what) {
}
-
- items[i].rect_cache.size=minsize;
if (fixed_column_width>0)
- items[i].rect_cache.size.x=fixed_column_width;
+ minsize.x=fixed_column_width;
+ max_column_width=MAX(max_column_width,minsize.x);
+ items[i].rect_cache.size=minsize;
+ items[i].min_rect_cache.size=minsize;
}
@@ -896,17 +902,23 @@ void ItemList::_notification(int p_what) {
break;
}
+ items[i].rect_cache=items[i].min_rect_cache;
+ if(same_column_width)
+ items[i].rect_cache.size.x=max_column_width;
items[i].rect_cache.pos=ofs;
max_h=MAX(max_h,items[i].rect_cache.size.y);
- ofs.x+=items[i].rect_cache.size.x;
+ ofs.x+=items[i].rect_cache.size.x + hseparation;
//print_line("item "+itos(i)+" ofs "+rtos(items[i].rect_cache.size.x));
- if (col>0)
- ofs.x+=hseparation;
col++;
if (col==current_columns) {
if (i<items.size()-1)
separators.push_back(ofs.y+max_h+vseparation/2);
+
+ for(int j=i;j>=0 && col>0;j--, col--) {
+ items[j].rect_cache.size.y = max_h;
+ }
+
ofs.x=0;
ofs.y+=max_h+vseparation;
col=0;
@@ -914,6 +926,10 @@ void ItemList::_notification(int p_what) {
}
}
+ for(int j=items.size()-1;j>=0 && col>0;j--, col--) {
+ items[j].rect_cache.size.y = max_h;
+ }
+
if (all_fit) {
float max = MAX(page,ofs.y+max_h);
scroll_bar->set_max(max);
@@ -976,29 +992,47 @@ void ItemList::_notification(int p_what) {
Vector2 text_ofs;
if (items[i].icon.is_valid()) {
- Size2 icon_size = _adjust_to_max_size(items[i].get_icon_size(),max_icon_size);
+ Size2 icon_size;
+ //= _adjust_to_max_size(items[i].get_icon_size(),fixed_icon_size) * icon_scale;
+
+ if (fixed_icon_size.x>0 && fixed_icon_size.y>0) {
+ icon_size=fixed_icon_size* icon_scale;
+ } else {
+ icon_size=items[i].get_icon_size() *icon_scale;
- Vector2 icon_ofs;
- if (min_icon_size!=Vector2()) {
- icon_ofs = (min_icon_size - icon_size)/2;
}
+ Vector2 icon_ofs;
+
Point2 pos = items[i].rect_cache.pos + icon_ofs + base_ofs;
if (icon_mode==ICON_MODE_TOP) {
pos.x += Math::floor((items[i].rect_cache.size.width - icon_size.width)/2);
- text_ofs.y = MAX(icon_size.height, min_icon_size.y) + icon_margin;
+ pos.y += MIN(
+ Math::floor((items[i].rect_cache.size.height - icon_size.height)/2),
+ items[i].rect_cache.size.height - items[i].min_rect_cache.size.height
+ );
+ text_ofs.y = icon_size.height + icon_margin;
+ text_ofs.y += items[i].rect_cache.size.height - items[i].min_rect_cache.size.height;
} else {
pos.y += Math::floor((items[i].rect_cache.size.height - icon_size.height)/2);
- text_ofs.x = MAX(icon_size.width, min_icon_size.x) + icon_margin;
+ text_ofs.x = icon_size.width + icon_margin;
+ }
+
+ Rect2 draw_rect=Rect2(pos,icon_size);
+
+ if (fixed_icon_size.x>0 && fixed_icon_size.y>0) {
+ Rect2 adj = _adjust_to_max_size(items[i].get_icon_size() * icon_scale,icon_size);
+ draw_rect.pos+=adj.pos;
+ draw_rect.size=adj.size;
}
if (items[i].icon_region.has_no_area())
- draw_texture_rect(items[i].icon, Rect2(pos,icon_size) );
+ draw_texture_rect(items[i].icon, draw_rect );
else
- draw_texture_rect_region(items[i].icon, Rect2(pos, icon_size), items[i].icon_region);
+ draw_texture_rect_region(items[i].icon, draw_rect, items[i].icon_region);
}
@@ -1014,6 +1048,8 @@ void ItemList::_notification(int p_what) {
Vector2 size = font->get_string_size(items[i].text);
if (fixed_column_width)
max_len=fixed_column_width;
+ else if(same_column_width)
+ max_len=items[i].rect_cache.size.x;
else
max_len=size.x;
@@ -1201,6 +1237,14 @@ bool ItemList::get_allow_rmb_select() const {
return allow_rmb_select;
}
+void ItemList::set_icon_scale(real_t p_scale) {
+ icon_scale = p_scale;
+}
+
+real_t ItemList::get_icon_scale() const {
+ return icon_scale;
+}
+
void ItemList::_bind_methods(){
ObjectTypeDB::bind_method(_MD("add_item","text","icon:Texture","selectable"),&ItemList::add_item,DEFVAL(Variant()),DEFVAL(true));
@@ -1243,6 +1287,9 @@ void ItemList::_bind_methods(){
ObjectTypeDB::bind_method(_MD("set_fixed_column_width","width"),&ItemList::set_fixed_column_width);
ObjectTypeDB::bind_method(_MD("get_fixed_column_width"),&ItemList::get_fixed_column_width);
+ ObjectTypeDB::bind_method(_MD("set_same_column_width","enable"),&ItemList::set_same_column_width);
+ ObjectTypeDB::bind_method(_MD("is_same_column_width"),&ItemList::is_same_column_width);
+
ObjectTypeDB::bind_method(_MD("set_max_text_lines","lines"),&ItemList::set_max_text_lines);
ObjectTypeDB::bind_method(_MD("get_max_text_lines"),&ItemList::get_max_text_lines);
@@ -1255,11 +1302,12 @@ void ItemList::_bind_methods(){
ObjectTypeDB::bind_method(_MD("set_icon_mode","mode"),&ItemList::set_icon_mode);
ObjectTypeDB::bind_method(_MD("get_icon_mode"),&ItemList::get_icon_mode);
- ObjectTypeDB::bind_method(_MD("set_min_icon_size","size"),&ItemList::set_min_icon_size);
- ObjectTypeDB::bind_method(_MD("get_min_icon_size"),&ItemList::get_min_icon_size);
- ObjectTypeDB::bind_method(_MD("set_max_icon_size","size"),&ItemList::set_max_icon_size);
- ObjectTypeDB::bind_method(_MD("get_max_icon_size"),&ItemList::get_max_icon_size);
+ ObjectTypeDB::bind_method(_MD("set_fixed_icon_size","size"),&ItemList::set_fixed_icon_size);
+ ObjectTypeDB::bind_method(_MD("get_fixed_icon_size"),&ItemList::get_fixed_icon_size);
+
+ ObjectTypeDB::bind_method(_MD("set_icon_scale","scale"),&ItemList::set_icon_scale);
+ ObjectTypeDB::bind_method(_MD("get_icon_scale"),&ItemList::get_icon_scale);
ObjectTypeDB::bind_method(_MD("set_allow_rmb_select","allow"),&ItemList::set_allow_rmb_select);
ObjectTypeDB::bind_method(_MD("get_allow_rmb_select"),&ItemList::get_allow_rmb_select);
@@ -1292,6 +1340,7 @@ ItemList::ItemList() {
icon_mode=ICON_MODE_LEFT;
fixed_column_width=0;
+ same_column_width = false;
max_text_lines=1;
max_columns=1;
@@ -1308,6 +1357,7 @@ ItemList::ItemList() {
defer_select_single=-1;
allow_rmb_select=false;
+ icon_scale = 1.0f;
}
ItemList::~ItemList() {
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index 59fa1d8270..aa6dd64c50 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -1,3 +1,31 @@
+/*************************************************************************/
+/* item_list.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 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. */
+/*************************************************************************/
#ifndef ITEMLIST_H
#define ITEMLIST_H
@@ -33,6 +61,7 @@ private:
Color custom_bg;
Rect2 rect_cache;
+ Rect2 min_rect_cache;
Size2 get_icon_size() const;
@@ -44,6 +73,7 @@ private:
bool shape_changed;
bool ensure_selected_visible;
+ bool same_column_width;
Vector<Item> items;
Vector<int> separators;
@@ -59,14 +89,21 @@ private:
int fixed_column_width;
int max_text_lines;
int max_columns;
- Size2 min_icon_size;
- Size2 max_icon_size;
+
+ Size2 fixed_icon_size;
+
+ Size2 max_item_size_cache;
+
int defer_select_single;
bool allow_rmb_select;
+ real_t icon_scale;
+
void _scroll_changed(double);
void _input_event(const InputEvent& p_event);
+
+
protected:
void _notification(int p_what);
@@ -121,6 +158,9 @@ public:
void set_fixed_column_width(int p_size);
int get_fixed_column_width() const;
+ void set_same_column_width(bool p_enable);
+ int is_same_column_width() const;
+
void set_max_text_lines(int p_amount);
int get_max_text_lines() const;
@@ -133,11 +173,8 @@ public:
void set_icon_mode(IconMode p_mode);
IconMode get_icon_mode() const;
- void set_min_icon_size(const Size2& p_size);
- Size2 get_min_icon_size() const;
-
- void set_max_icon_size(const Size2& p_size);
- Size2 get_max_icon_size() const;
+ void set_fixed_icon_size(const Size2& p_size);
+ Size2 get_fixed_icon_size() const;
void set_allow_rmb_select(bool p_allow);
bool get_allow_rmb_select() const;
@@ -150,6 +187,9 @@ public:
virtual String get_tooltip(const Point2& p_pos) const;
int get_item_at_pos(const Point2& p_pos,bool p_exact=false) const;
+ void set_icon_scale(real_t p_scale);
+ real_t get_icon_scale() const;
+
ItemList();
~ItemList();
};
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 09c6a77b42..2d4438c48c 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -92,7 +92,9 @@ void Label::_notification(int p_what) {
VisualServer::get_singleton()->canvas_item_set_distance_field_mode(get_canvas_item(),font.is_valid() && font->is_distance_field_hint());
int font_h = font->get_height()+line_spacing;
- int lines_visible = size.y/font_h;
+
+ int lines_visible = (size.y+line_spacing)/font_h;
+
int space_w=font->get_char_size(' ').width;
int chars_total=0;
@@ -488,9 +490,9 @@ void Label::regenerate_word_cache() {
if (!autowrap) {
minsize.width=width;
if (max_lines_visible > 0 && line_count > max_lines_visible) {
- minsize.height=(font->get_height()+line_spacing)*max_lines_visible;
+ minsize.height=(font->get_height() * max_lines_visible) + (line_spacing * (max_lines_visible - 1));
} else {
- minsize.height=(font->get_height()+line_spacing)*line_count;
+ minsize.height=(font->get_height() * line_count)+(line_spacing * (line_count - 1));
}
}
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 14dac454bd..ab556ede0c 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -731,14 +731,21 @@ void LineEdit::set_cursor_pos(int p_pos) {
int width_to_cursor=0;
int wp=window_pos;
- if (font != NULL) {
- for (int i=window_pos;i<cursor_pos;i++)
- width_to_cursor+=font->get_char_size( text[i] ).width;
+ if (font.is_valid()) {
+
+ int accum_width=0;
- while (width_to_cursor >= window_width && wp < text.length()) {
+ for(int i=cursor_pos;i>=window_pos;i--) {
+
+ if (i>=text.length()) {
+ accum_width=font->get_char_size(' ').width; //anything should do
+ } else {
+ accum_width+=font->get_char_size(text[i],i+1<text.length()?text[i+1]:0).width; //anything should do
+ }
+ if (accum_width>=window_width)
+ break;
- width_to_cursor -= font->get_char_size(text[wp]).width;
- wp++;
+ wp=i;
}
}
@@ -801,7 +808,6 @@ Size2 LineEdit::get_minimum_size() const {
Size2 min=style->get_minimum_size();
min.height+=font->get_height();
min.width+=get_constant("minimum_spaces")*font->get_char_size(' ').x;
-
return min;
}
@@ -1027,7 +1033,7 @@ void LineEdit::_bind_methods() {
ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "max_length" ), _SCS("set_max_length"),_SCS("get_max_length") );
ADD_PROPERTYNO( PropertyInfo( Variant::BOOL, "editable" ), _SCS("set_editable"),_SCS("is_editable") );
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "secret" ), _SCS("set_secret"),_SCS("is_secret") );
-
+ ADD_PROPERTY( PropertyInfo( Variant::INT,"focus_mode", PROPERTY_HINT_ENUM, "None,Click,All" ), _SCS("set_focus_mode"), _SCS("get_focus_mode") );
}
diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp
index 007d0a709e..62829fd5a4 100644
--- a/scene/gui/link_button.cpp
+++ b/scene/gui/link_button.cpp
@@ -1,3 +1,31 @@
+/*************************************************************************/
+/* link_button.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 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 "link_button.h"
@@ -119,6 +147,6 @@ void LinkButton::_bind_methods() {
LinkButton::LinkButton() {
underline_mode=UNDERLINE_MODE_ALWAYS;
- set_focus_mode(FOCUS_NONE);
+ set_enabled_focus_mode(FOCUS_NONE);
set_default_cursor_shape(CURSOR_POINTING_HAND);
}
diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h
index d218482337..9978f66cc0 100644
--- a/scene/gui/link_button.h
+++ b/scene/gui/link_button.h
@@ -1,3 +1,31 @@
+/*************************************************************************/
+/* link_button.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 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. */
+/*************************************************************************/
#ifndef LINKBUTTON_H
#define LINKBUTTON_H
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index 0f415f013d..28d67287d5 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -32,30 +32,15 @@
void MenuButton::_unhandled_key_input(InputEvent p_event) {
- //check accelerators
- if (p_event.type==InputEvent::KEY && p_event.key.pressed) {
+ if (p_event.is_pressed() && !p_event.is_echo() && (p_event.type==InputEvent::KEY || p_event.type==InputEvent::ACTION || p_event.type==InputEvent::JOYSTICK_BUTTON)) {
if (!get_parent() || !is_visible() || is_disabled())
return;
- uint32_t code=p_event.key.scancode;
- if (code==0)
- code=p_event.key.unicode;
- if (p_event.key.mod.control)
- code|=KEY_MASK_CTRL;
- if (p_event.key.mod.alt)
- code|=KEY_MASK_ALT;
- if (p_event.key.mod.meta)
- code|=KEY_MASK_META;
- if (p_event.key.mod.shift)
- code|=KEY_MASK_SHIFT;
-
-
- int item = popup->activate_item_by_accelerator(code);
+ int item = popup->activate_item_by_event(p_event);
}
-
}
@@ -123,7 +108,7 @@ MenuButton::MenuButton() {
set_flat(true);
- set_focus_mode(FOCUS_NONE);
+ set_enabled_focus_mode(FOCUS_NONE);
popup = memnew( PopupMenu );
popup->hide();
add_child(popup);
diff --git a/scene/gui/patch_9_frame.cpp b/scene/gui/patch_9_frame.cpp
index b6e261714c..a6a3490ad2 100644
--- a/scene/gui/patch_9_frame.cpp
+++ b/scene/gui/patch_9_frame.cpp
@@ -1,3 +1,31 @@
+/*************************************************************************/
+/* patch_9_frame.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 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 "patch_9_frame.h"
#include "servers/visual_server.h"
@@ -9,10 +37,9 @@ void Patch9Frame::_notification(int p_what) {
if (texture.is_null())
return;
-
Size2 s=get_size();
RID ci = get_canvas_item();
- VS::get_singleton()->canvas_item_add_style_box(ci,Rect2(Point2(),s),texture->get_rid(),Vector2(margin[MARGIN_LEFT],margin[MARGIN_TOP]),Vector2(margin[MARGIN_RIGHT],margin[MARGIN_BOTTOM]),draw_center,modulate);
+ VS::get_singleton()->canvas_item_add_style_box(ci,Rect2(Point2(),s),region_rect,texture->get_rid(),Vector2(margin[MARGIN_LEFT],margin[MARGIN_TOP]),Vector2(margin[MARGIN_RIGHT],margin[MARGIN_BOTTOM]),draw_center,modulate);
// draw_texture_rect(texture,Rect2(Point2(),s),false,modulate);
/*
@@ -47,12 +74,15 @@ void Patch9Frame::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_modulate"), & Patch9Frame::get_modulate );
ObjectTypeDB::bind_method(_MD("set_patch_margin","margin","value"), & Patch9Frame::set_patch_margin );
ObjectTypeDB::bind_method(_MD("get_patch_margin","margin"), & Patch9Frame::get_patch_margin );
+ ObjectTypeDB::bind_method(_MD("set_region_rect","rect"),&Patch9Frame::set_region_rect);
+ ObjectTypeDB::bind_method(_MD("get_region_rect"),&Patch9Frame::get_region_rect);
ObjectTypeDB::bind_method(_MD("set_draw_center","draw_center"), & Patch9Frame::set_draw_center );
ObjectTypeDB::bind_method(_MD("get_draw_center"), & Patch9Frame::get_draw_center );
ADD_PROPERTYNZ( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), _SCS("set_texture"),_SCS("get_texture") );
ADD_PROPERTYNO( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate") );
ADD_PROPERTYNO( PropertyInfo( Variant::BOOL, "draw_center"), _SCS("set_draw_center"),_SCS("get_draw_center") );
+ ADD_PROPERTYNZ( PropertyInfo( Variant::RECT2, "region_rect"), _SCS("set_region_rect"),_SCS("get_region_rect"));
ADD_PROPERTYINZ( PropertyInfo( Variant::INT, "patch_margin/left",PROPERTY_HINT_RANGE,"0,16384,1"), _SCS("set_patch_margin"),_SCS("get_patch_margin"),MARGIN_LEFT );
ADD_PROPERTYINZ( PropertyInfo( Variant::INT, "patch_margin/top",PROPERTY_HINT_RANGE,"0,16384,1"), _SCS("set_patch_margin"),_SCS("get_patch_margin"),MARGIN_TOP );
ADD_PROPERTYINZ( PropertyInfo( Variant::INT, "patch_margin/right",PROPERTY_HINT_RANGE,"0,16384,1"), _SCS("set_patch_margin"),_SCS("get_patch_margin"),MARGIN_RIGHT );
@@ -93,6 +123,20 @@ void Patch9Frame::set_patch_margin(Margin p_margin,int p_size) {
margin[p_margin]=p_size;
update();
minimum_size_changed();
+ switch (p_margin) {
+ case MARGIN_LEFT:
+ _change_notify("patch_margin/left");
+ break;
+ case MARGIN_TOP:
+ _change_notify("patch_margin/top");
+ break;
+ case MARGIN_RIGHT:
+ _change_notify("patch_margin/right");
+ break;
+ case MARGIN_BOTTOM:
+ _change_notify("patch_margin/bottom");
+ break;
+ }
}
int Patch9Frame::get_patch_margin(Margin p_margin) const{
@@ -101,6 +145,22 @@ int Patch9Frame::get_patch_margin(Margin p_margin) const{
return margin[p_margin];
}
+void Patch9Frame::set_region_rect(const Rect2& p_region_rect) {
+
+ if (region_rect==p_region_rect)
+ return;
+
+ region_rect=p_region_rect;
+
+ item_rect_changed();
+ _change_notify("region_rect");
+}
+
+Rect2 Patch9Frame::get_region_rect() const {
+
+ return region_rect;
+}
+
void Patch9Frame::set_draw_center(bool p_draw) {
draw_center=p_draw;
@@ -128,5 +188,3 @@ Patch9Frame::Patch9Frame() {
Patch9Frame::~Patch9Frame()
{
}
-
-
diff --git a/scene/gui/patch_9_frame.h b/scene/gui/patch_9_frame.h
index 562a5b1d77..7763db567a 100644
--- a/scene/gui/patch_9_frame.h
+++ b/scene/gui/patch_9_frame.h
@@ -1,3 +1,31 @@
+/*************************************************************************/
+/* patch_9_frame.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 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. */
+/*************************************************************************/
#ifndef PATCH_9_FRAME_H
#define PATCH_9_FRAME_H
@@ -11,6 +39,7 @@ class Patch9Frame : public Control {
bool draw_center;
int margin[4];
+ Rect2 region_rect;
Color modulate;
Ref<Texture> texture;
protected:
@@ -30,6 +59,9 @@ public:
void set_patch_margin(Margin p_margin,int p_size);
int get_patch_margin(Margin p_margin) const;
+ void set_region_rect(const Rect2& p_region_rect);
+ Rect2 get_region_rect() const;
+
void set_draw_center(bool p_enable);
bool get_draw_center() const;
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 819885809b..b3f18bf8fa 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -32,9 +32,16 @@
#include "translation.h"
#include "os/input.h"
-String PopupMenu::_get_accel_text(uint32_t p_accel) const {
+String PopupMenu::_get_accel_text(int p_item) const {
+
+ ERR_FAIL_INDEX_V(p_item,items.size(),String());
+
+ if (items[p_item].shortcut.is_valid())
+ return items[p_item].shortcut->get_as_text();
+ else if (items[p_item].accel)
+ return keycode_get_string(items[p_item].accel);
+ return String();
- return keycode_get_string(p_accel);
/*
String atxt;
if (p_accel&KEY_MASK_SHIFT)
@@ -87,14 +94,15 @@ Size2 PopupMenu::get_minimum_size() const {
size.width+=check_w+hseparation;
}
- size.width+=font->get_string_size(items[i].text).width;
+ String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].text;
+ size.width+=font->get_string_size(text).width;
if (i>0)
size.height+=vseparation;
- if (items[i].accel) {
+ if (items[i].accel || (items[i].shortcut.is_valid() && items[i].shortcut->is_valid())) {
int accel_w = hseparation*2;
- accel_w+=font->get_string_size(_get_accel_text(items[i].accel)).width;
+ accel_w+=font->get_string_size(_get_accel_text(i)).width;
accel_max_w = MAX( accel_w, accel_max_w );
}
@@ -484,13 +492,15 @@ void PopupMenu::_notification(int p_what) {
}
item_ofs.y+=font->get_ascent();
- if (!items[i].separator)
- font->draw(ci,item_ofs+Point2(0,Math::floor((h-font_h)/2.0)),items[i].text,items[i].disabled?font_color_disabled:(i==mouse_over?font_color_hover:font_color));
+ String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].text;
+ if (!items[i].separator) {
+ font->draw(ci,item_ofs+Point2(0,Math::floor((h-font_h)/2.0)),text,items[i].disabled?font_color_disabled:(i==mouse_over?font_color_hover:font_color));
+ }
- if (items[i].accel) {
+ if (items[i].accel || (items[i].shortcut.is_valid() && items[i].shortcut->is_valid())) {
//accelerator
- String text = _get_accel_text(items[i].accel);
+ String text = _get_accel_text(i);
item_ofs.x=size.width-style->get_margin(MARGIN_RIGHT)-font->get_string_size(text).width;
font->draw(ci,item_ofs+Point2(0,Math::floor((h-font_h)/2.0)),text,i==mouse_over?font_color_hover:font_color_accel);
@@ -570,6 +580,64 @@ void PopupMenu::add_check_item(const String& p_label,int p_ID,uint32_t p_accel)
update();
}
+
+void PopupMenu::add_icon_shortcut(const Ref<Texture>& p_icon,const Ref<ShortCut>& p_shortcut,int p_ID) {
+
+ ERR_FAIL_COND(p_shortcut.is_null());
+
+ _ref_shortcut(p_shortcut);
+
+ Item item;
+ item.ID=p_ID;
+ item.icon=p_icon;
+ item.shortcut=p_shortcut;
+ items.push_back(item);
+ update();
+
+}
+
+void PopupMenu::add_shortcut(const Ref<ShortCut>& p_shortcut,int p_ID){
+
+ ERR_FAIL_COND(p_shortcut.is_null());
+
+ _ref_shortcut(p_shortcut);
+
+ Item item;
+ item.ID=p_ID;
+ item.shortcut=p_shortcut;
+ items.push_back(item);
+ update();
+
+}
+void PopupMenu::add_icon_check_shortcut(const Ref<Texture>& p_icon,const Ref<ShortCut>& p_shortcut,int p_ID){
+
+ ERR_FAIL_COND(p_shortcut.is_null());
+
+ _ref_shortcut(p_shortcut);
+
+ Item item;
+ item.ID=p_ID;
+ item.shortcut=p_shortcut;
+ item.checkable=true;
+ item.icon=p_icon;
+ items.push_back(item);
+ update();
+}
+
+void PopupMenu::add_check_shortcut(const Ref<ShortCut>& p_shortcut,int p_ID){
+
+ ERR_FAIL_COND(p_shortcut.is_null());
+
+ _ref_shortcut(p_shortcut);
+
+ Item item;
+ item.ID=p_ID;
+ item.shortcut=p_shortcut;
+ item.checkable=true;
+ items.push_back(item);
+ update();
+}
+
void PopupMenu::set_item_text(int p_idx,const String& p_text) {
ERR_FAIL_INDEX(p_idx,items.size());
@@ -701,6 +769,12 @@ String PopupMenu::get_item_tooltip(int p_idx) const {
return items[p_idx].tooltip;
}
+Ref<ShortCut> PopupMenu::get_item_shortcut(int p_idx) const {
+
+ ERR_FAIL_INDEX_V(p_idx,items.size(),Ref<ShortCut>());
+ return items[p_idx].shortcut;
+}
+
void PopupMenu::set_item_as_separator(int p_idx, bool p_separator) {
ERR_FAIL_INDEX(p_idx,items.size());
@@ -730,6 +804,21 @@ void PopupMenu::set_item_tooltip(int p_idx,const String& p_tooltip) {
update();
}
+void PopupMenu::set_item_shortcut(int p_idx, const Ref<ShortCut>& p_shortcut) {
+ ERR_FAIL_INDEX(p_idx,items.size());
+ if (items[p_idx].shortcut.is_valid()) {
+ _unref_shortcut(items[p_idx].shortcut);
+ }
+ items[p_idx].shortcut=p_shortcut;
+
+ if (items[p_idx].shortcut.is_valid()) {
+ _ref_shortcut(items[p_idx].shortcut);
+ }
+
+
+ update();
+}
+
bool PopupMenu::is_item_checkable(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,items.size(),false);
return items[p_idx].checkable;
@@ -740,14 +829,36 @@ int PopupMenu::get_item_count() const {
return items.size();
}
-bool PopupMenu::activate_item_by_accelerator(uint32_t p_accel) {
+bool PopupMenu::activate_item_by_event(const InputEvent& p_event) {
+
+ uint32_t code=0;
+ if (p_event.type==InputEvent::KEY) {
+ code=p_event.key.scancode;
+ if (code==0)
+ code=p_event.key.unicode;
+ if (p_event.key.mod.control)
+ code|=KEY_MASK_CTRL;
+ if (p_event.key.mod.alt)
+ code|=KEY_MASK_ALT;
+ if (p_event.key.mod.meta)
+ code|=KEY_MASK_META;
+ if (p_event.key.mod.shift)
+ code|=KEY_MASK_SHIFT;
+ }
+
int il=items.size();
for(int i=0;i<il;i++) {
if (is_item_disabled(i))
continue;
- if (items[i].accel==p_accel) {
+
+ if (items[i].shortcut.is_valid() && items[i].shortcut->is_shortcut(p_event)) {
+ activate_item(i);
+ return true;
+ }
+
+ if (code!=0 && items[i].accel==code) {
activate_item(i);
return true;
}
@@ -761,7 +872,7 @@ bool PopupMenu::activate_item_by_accelerator(uint32_t p_accel) {
if(!pm)
continue;
- if(pm->activate_item_by_accelerator(p_accel)) {
+ if(pm->activate_item_by_event(p_event)) {
return true;
}
}
@@ -791,6 +902,12 @@ void PopupMenu::activate_item(int p_item) {
void PopupMenu::remove_item(int p_idx) {
+ ERR_FAIL_INDEX(p_idx,items.size());
+
+ if (items[p_idx].shortcut.is_valid()) {
+ _unref_shortcut(items[p_idx].shortcut);
+ }
+
items.remove(p_idx);
update();
}
@@ -806,6 +923,11 @@ void PopupMenu::add_separator() {
void PopupMenu::clear() {
+ for(int i=0;i<items.size();i++) {
+ if (items[i].shortcut.is_valid()) {
+ _unref_shortcut(items[i].shortcut);
+ }
+ }
items.clear();
mouse_over=-1;
update();
@@ -834,6 +956,27 @@ Array PopupMenu::_get_items() const {
return items;
}
+
+void PopupMenu::_ref_shortcut( Ref<ShortCut> p_sc) {
+
+ if (!shortcut_refcount.has(p_sc)) {
+ shortcut_refcount[p_sc]=1;
+ p_sc->connect("changed",this,"update");
+ } else {
+ shortcut_refcount[p_sc]+=1;
+ }
+}
+
+void PopupMenu::_unref_shortcut(Ref<ShortCut> p_sc) {
+
+ ERR_FAIL_COND(!shortcut_refcount.has(p_sc));
+ shortcut_refcount[p_sc]--;
+ if (shortcut_refcount[p_sc]==0) {
+ p_sc->disconnect("changed",this,"update");
+ shortcut_refcount.erase(p_sc);
+ }
+}
+
void PopupMenu::_set_items(const Array& p_items){
ERR_FAIL_COND(p_items.size() % 10);
@@ -912,12 +1055,20 @@ void PopupMenu::_bind_methods() {
ObjectTypeDB::bind_method(_MD("add_icon_check_item","texture","label","id","accel"),&PopupMenu::add_icon_check_item,DEFVAL(-1),DEFVAL(0));
ObjectTypeDB::bind_method(_MD("add_check_item","label","id","accel"),&PopupMenu::add_check_item,DEFVAL(-1),DEFVAL(0));
ObjectTypeDB::bind_method(_MD("add_submenu_item","label","submenu","id"),&PopupMenu::add_submenu_item,DEFVAL(-1));
+
+ ObjectTypeDB::bind_method(_MD("add_icon_shortcut","texture","shortcut:ShortCut","id"),&PopupMenu::add_icon_shortcut,DEFVAL(-1));
+ ObjectTypeDB::bind_method(_MD("add_shortcut","shortcut:ShortCut","id"),&PopupMenu::add_shortcut,DEFVAL(-1));
+ ObjectTypeDB::bind_method(_MD("add_icon_check_shortcut","texture","shortcut:ShortCut","id"),&PopupMenu::add_icon_check_shortcut,DEFVAL(-1));
+ ObjectTypeDB::bind_method(_MD("add_check_shortcut","shortcut:ShortCut","id"),&PopupMenu::add_check_shortcut,DEFVAL(-1));
+
+
ObjectTypeDB::bind_method(_MD("set_item_text","idx","text"),&PopupMenu::set_item_text);
ObjectTypeDB::bind_method(_MD("set_item_icon","idx","icon"),&PopupMenu::set_item_icon);
ObjectTypeDB::bind_method(_MD("set_item_accelerator","idx","accel"),&PopupMenu::set_item_accelerator);
ObjectTypeDB::bind_method(_MD("set_item_metadata","idx","metadata"),&PopupMenu::set_item_metadata);
ObjectTypeDB::bind_method(_MD("set_item_checked","idx","checked"),&PopupMenu::set_item_checked);
ObjectTypeDB::bind_method(_MD("set_item_disabled","idx","disabled"),&PopupMenu::set_item_disabled);
+ ObjectTypeDB::bind_method(_MD("set_item_shortcut","idx","shortcut:ShortCut"),&PopupMenu::set_item_shortcut);
ObjectTypeDB::bind_method(_MD("set_item_submenu","idx","submenu"),&PopupMenu::set_item_submenu);
ObjectTypeDB::bind_method(_MD("set_item_as_separator","idx","enable"),&PopupMenu::set_item_as_separator);
ObjectTypeDB::bind_method(_MD("set_item_as_checkable","idx","enable"),&PopupMenu::set_item_as_checkable);
@@ -926,6 +1077,7 @@ void PopupMenu::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_item_icon","idx"),&PopupMenu::get_item_icon);
ObjectTypeDB::bind_method(_MD("get_item_metadata","idx"),&PopupMenu::get_item_metadata);
ObjectTypeDB::bind_method(_MD("get_item_accelerator","idx"),&PopupMenu::get_item_accelerator);
+ ObjectTypeDB::bind_method(_MD("get_item_shortcut:ShortCut","idx"),&PopupMenu::get_item_shortcut);
ObjectTypeDB::bind_method(_MD("get_item_submenu","idx"),&PopupMenu::get_item_submenu);
ObjectTypeDB::bind_method(_MD("is_item_separator","idx"),&PopupMenu::is_item_separator);
ObjectTypeDB::bind_method(_MD("is_item_checkable","idx"),&PopupMenu::is_item_checkable);
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index 0e98765dc4..f35e91d4e4 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -34,6 +34,9 @@
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
+
+
+
class PopupMenu : public Popup {
OBJ_TYPE(PopupMenu, Popup );
@@ -51,6 +54,7 @@ class PopupMenu : public Popup {
String tooltip;
uint32_t accel;
int _ofs_cache;
+ Ref<ShortCut> shortcut;
Item() { checked=false; checkable=false; separator=false; accel=0; disabled=false; _ofs_cache=0; }
};
@@ -62,7 +66,7 @@ class PopupMenu : public Popup {
int mouse_over;
int submenu_over;
Rect2 parent_rect;
- String _get_accel_text(uint32_t p_accel) const;
+ String _get_accel_text(int p_item) const;
int _get_mouse_over(const Point2& p_over) const;
virtual Size2 get_minimum_size() const;
void _input_event(const InputEvent &p_event);
@@ -75,6 +79,10 @@ class PopupMenu : public Popup {
Array _get_items() const;
void _set_items(const Array& p_items);
+ Map< Ref<ShortCut>, int> shortcut_refcount;
+
+ void _ref_shortcut(Ref<ShortCut> p_sc);
+ void _unref_shortcut( Ref<ShortCut> p_sc);
protected:
virtual bool has_point(const Point2& p_point) const;
@@ -90,6 +98,11 @@ public:
void add_check_item(const String& p_label,int p_ID=-1,uint32_t p_accel=0);
void add_submenu_item(const String& p_label,const String& p_submenu, int p_ID=-1);
+ void add_icon_shortcut(const Ref<Texture>& p_icon,const Ref<ShortCut>& p_shortcut,int p_ID=-1);
+ void add_shortcut(const Ref<ShortCut>& p_shortcut,int p_ID=-1);
+ void add_icon_check_shortcut(const Ref<Texture>& p_icon,const Ref<ShortCut>& p_shortcut,int p_ID=-1);
+ void add_check_shortcut(const Ref<ShortCut>& p_shortcut,int p_ID=-1);
+
void set_item_text(int p_idx,const String& p_text);
void set_item_icon(int p_idx,const Ref<Texture>& p_icon);
void set_item_checked(int p_idx,bool p_checked);
@@ -101,6 +114,7 @@ public:
void set_item_as_separator(int p_idx, bool p_separator);
void set_item_as_checkable(int p_idx, bool p_checkable);
void set_item_tooltip(int p_idx,const String& p_tooltip);
+ void set_item_shortcut(int p_idx, const Ref<ShortCut>& p_shortcut);
String get_item_text(int p_idx) const;
Ref<Texture> get_item_icon(int p_idx) const;
@@ -114,10 +128,11 @@ public:
bool is_item_separator(int p_idx) const;
bool is_item_checkable(int p_idx) const;
String get_item_tooltip(int p_idx) const;
+ Ref<ShortCut> get_item_shortcut(int p_idx) const;
int get_item_count() const;
- bool activate_item_by_accelerator(uint32_t p_accel);
+ bool activate_item_by_event(const InputEvent& p_event);
void activate_item(int p_item);
void remove_item(int p_idx);
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 98bc0b9434..786ce27a0c 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -278,6 +278,11 @@ if (m_height > line_height) {\
if (c[end]=='\t') {
cw=tab_size*font->get_char_size(' ').width;
}
+
+ if (end>0 && w+cw+begin > p_width ) {
+ break; //don't allow lines longer than assigned width
+ }
+
w+=cw;
if (c[end]==' ') {
@@ -340,10 +345,12 @@ if (m_height > line_height) {\
int cw=font->get_char_size(c[i],c[i+1]).x;
+
if (c[i]=='\t') {
cw=tab_size*font->get_char_size(' ').width;
}
+
if (p_click_pos.x-cw/2>p_ofs.x+align_ofs+pofs) {
rchar=int((&c[i])-cf);
@@ -374,6 +381,8 @@ if (m_height > line_height) {\
int cw=0;
bool visible = visible_characters<0 || p_char_count<visible_characters;
+ if (c[i]=='\t')
+ visible=false;
if (selected) {
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index f66f909517..d5d14ad649 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -237,6 +237,7 @@ void Slider::_bind_methods() {
ADD_PROPERTY( PropertyInfo( Variant::INT, "tick_count", PROPERTY_HINT_RANGE,"0,4096,1"), _SCS("set_ticks"), _SCS("get_ticks") );
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "ticks_on_borders" ), _SCS("set_ticks_on_borders"), _SCS("get_ticks_on_borders") );
+ ADD_PROPERTY( PropertyInfo( Variant::INT,"focus_mode", PROPERTY_HINT_ENUM, "None,Click,All" ), _SCS("set_focus_mode"), _SCS("get_focus_mode") );
}
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index d22f6a0229..6b36a60ea2 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -351,7 +351,7 @@ void SplitContainer::_input_event(const InputEvent& p_event) {
}
-Control::CursorShape SplitContainer::get_cursor_shape(const Point2& p_pos) {
+Control::CursorShape SplitContainer::get_cursor_shape(const Point2& p_pos) const {
if (collapsed)
return Control::get_cursor_shape(p_pos);
diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h
index f721d16310..d2dc42165e 100644
--- a/scene/gui/split_container.h
+++ b/scene/gui/split_container.h
@@ -75,7 +75,7 @@ public:
void set_dragger_visibility(DraggerVisibility p_visibility);
DraggerVisibility get_dragger_visibility() const;
- virtual CursorShape get_cursor_shape(const Point2& p_pos=Point2i());
+ virtual CursorShape get_cursor_shape(const Point2& p_pos=Point2i()) const;
virtual Size2 get_minimum_size() const;
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 1c6a97bab8..37c68a295d 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -411,6 +411,10 @@ void TabContainer::_notification(int p_what) {
panel->draw(ci, Rect2( 0, top_size.height, size.width, size.height-top_size.height));
} break;
+ case NOTIFICATION_THEME_CHANGED: {
+
+ call_deferred("set_current_tab",get_current_tab()); //wait until all changed theme
+ } break;
}
}
@@ -700,13 +704,13 @@ Size2 TabContainer::get_minimum_size() const {
if (c->is_set_as_toplevel())
continue;
- if (!c->has_meta("_tab_name"))
- continue;
+ //if (!c->has_meta("_tab_name"))
+ // continue;
if (!c->is_visible())
continue;
- Size2 cms = c->get_minimum_size();
+ Size2 cms = c->get_combined_minimum_size();
ms.x=MAX(ms.x,cms.x);
ms.y=MAX(ms.y,cms.y);
}
@@ -718,6 +722,9 @@ Size2 TabContainer::get_minimum_size() const {
ms.y+=MAX(tab_bg->get_minimum_size().y,tab_fg->get_minimum_size().y);
ms.y+=font->get_height();
+ Ref<StyleBox> sb = get_stylebox("panel");
+ ms+=sb->get_minimum_size();
+
return ms;
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 03024daff5..49d7527786 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -314,6 +314,10 @@ void TextEdit::_update_scrollbars() {
if (line_numbers)
total_width += cache.line_number_w;
+ if (draw_breakpoint_gutter) {
+ total_width += cache.breakpoint_gutter_width;
+ }
+
bool use_hscroll=true;
bool use_vscroll=true;
@@ -412,9 +416,16 @@ void TextEdit::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED: {
_update_caches();
- };
+ } break;
case NOTIFICATION_DRAW: {
+ if (draw_breakpoint_gutter) {
+ breakpoint_gutter_width = (get_row_height() * 55) / 100;
+ cache.breakpoint_gutter_width = breakpoint_gutter_width;
+ } else {
+ cache.breakpoint_gutter_width = 0;
+ }
+
int line_number_char_count=0;
{
@@ -439,7 +450,7 @@ void TextEdit::_notification(int p_what) {
RID ci = get_canvas_item();
- int xmargin_beg=cache.style_normal->get_margin(MARGIN_LEFT)+cache.line_number_w;
+ int xmargin_beg=cache.style_normal->get_margin(MARGIN_LEFT)+cache.line_number_w+cache.breakpoint_gutter_width;
int xmargin_end=cache.size.width-cache.style_normal->get_margin(MARGIN_RIGHT);
//let's do it easy for now:
cache.style_normal->draw(ci,Rect2(Point2(),cache.size));
@@ -682,18 +693,13 @@ void TextEdit::_notification(int p_what) {
// check if line contains highlighted word
int highlighted_text_col = -1;
- if (highlighted_text.length() != 0) {
- highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, 0);
- }
+ int search_text_col = -1;
- if (cache.line_number_w) {
- String fc = String::num(line+1);
- while (fc.length() < line_number_char_count) {
- fc="0"+fc;
- }
+ if (!search_text.empty())
+ search_text_col = _get_column_pos_of_word(search_text, str, search_flags, 0);
- cache.font->draw(ci,Point2(cache.style_normal->get_margin(MARGIN_LEFT),ofs_y+cache.font->get_ascent()),fc,cache.line_number_color);
- }
+ if (highlighted_text.length() != 0 && highlighted_text != search_text)
+ highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE|SEARCH_WHOLE_WORDS, 0);
const Map<int,Text::ColorRegionInfo>& cri_map=text.get_color_region_info(line);
@@ -708,11 +714,30 @@ void TextEdit::_notification(int p_what) {
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(xmargin_beg, ofs_y,xmargin_end-xmargin_beg,get_row_height()),cache.breakpoint_color);
}
-
if (line==cursor.line) {
+ VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(0, ofs_y,xmargin_end,get_row_height()),cache.current_line_color);
+ }
+
+ // draw breakpoint marker
+ if (text.is_breakpoint(line)) {
+ if (draw_breakpoint_gutter) {
+ int vertical_gap = (get_row_height() * 40) / 100;
+ int horizontal_gap = (cache.breakpoint_gutter_width * 30) / 100;
+ int marker_height = get_row_height() - (vertical_gap * 2);
+ int marker_width = cache.breakpoint_gutter_width - (horizontal_gap * 2);
+ // no transparency on marker
+ VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cache.style_normal->get_margin(MARGIN_LEFT) + horizontal_gap - 2, ofs_y + vertical_gap ,marker_width, marker_height),Color(cache.breakpoint_color.r, cache.breakpoint_color.g, cache.breakpoint_color.b));
+ }
+ }
- VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(xmargin_beg, ofs_y,xmargin_end-xmargin_beg,get_row_height()),cache.current_line_color);
+ if (cache.line_number_w) {
+ String fc = String::num(line+1);
+ while (fc.length() < line_number_char_count) {
+ fc="0"+fc;
+ }
+
+ cache.font->draw(ci,Point2(cache.style_normal->get_margin(MARGIN_LEFT)+cache.breakpoint_gutter_width,ofs_y+cache.font->get_ascent()),fc,cache.line_number_color);
}
for (int j=0;j<str.length();j++) {
@@ -879,20 +904,45 @@ void TextEdit::_notification(int p_what) {
break;
}
- bool in_selection = (selection.active && line>=selection.from_line && line<=selection.to_line && (line>selection.from_line || j>=selection.from_column) && (line<selection.to_line || j<selection.to_column));
+ bool in_search_result=false;
+
+ if (search_text_col != -1) {
+ // if we are at the end check for new search result on same line
+ if (j >= search_text_col+search_text.length())
+ search_text_col = _get_column_pos_of_word(search_text, str, search_flags, j);
+
+ in_search_result = j >= search_text_col && j < search_text_col+search_text.length();
+
+ if (in_search_result) {
+ VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin, ofs_y ), Size2i(char_w, get_row_height())),cache.search_result_color);
+ }
+ }
+ bool in_selection = (selection.active && line>=selection.from_line && line<=selection.to_line && (line>selection.from_line || j>=selection.from_column) && (line<selection.to_line || j<selection.to_column));
if (in_selection) {
//inside selection!
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin, ofs_y ), Size2i(char_w,get_row_height())),cache.selection_color);
}
+ if (in_search_result) {
+ Color border_color=(line==search_result_line && j>=search_result_col && j<search_result_col+search_text.length())?cache.font_color:cache.search_result_border_color;
+
+ VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin, ofs_y ), Size2i(char_w,1)),border_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin, ofs_y+get_row_height()-1 ), Size2i(char_w,1)),border_color);
+
+ if (j==search_text_col)
+ VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin, ofs_y ), Size2i(1,get_row_height())),border_color);
+ if (j==search_text_col+search_text.length()-1)
+ VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin+char_w-1, ofs_y ), Size2i(1,get_row_height())),border_color);
+ }
+
if (highlight_all_occurrences) {
if (highlighted_text_col != -1) {
// if we are at the end check for new word on same line
if (j > highlighted_text_col+highlighted_text.length()) {
- highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, j);
+ highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE|SEARCH_WHOLE_WORDS, j);
}
bool in_highlighted_word = (j >= highlighted_text_col && j < highlighted_text_col+highlighted_text.length());
@@ -1347,7 +1397,7 @@ void TextEdit::_get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) co
col=text[row].size();
} else {
- col=p_mouse.x-(cache.style_normal->get_margin(MARGIN_LEFT)+cache.line_number_w);
+ col=p_mouse.x-(cache.style_normal->get_margin(MARGIN_LEFT)+cache.line_number_w+cache.breakpoint_gutter_width);
col+=cursor.x_ofs;
col=get_char_pos_for( col, get_line(row) );
}
@@ -1421,6 +1471,15 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
int row,col;
_get_mouse_pos(Point2i(mb.x,mb.y), row,col);
+ // toggle breakpoint on gutter click
+ if (draw_breakpoint_gutter) {
+ int gutter=cache.style_normal->get_margin(MARGIN_LEFT);
+ if (mb.x > gutter && mb.x <= gutter + cache.breakpoint_gutter_width + 3) {
+ set_line_as_breakpoint(row, !is_line_set_as_breakpoint(row));
+ return;
+ }
+ }
+
int prev_col=cursor.column;
int prev_line=cursor.line;
@@ -1820,7 +1879,9 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
}
if (clear) {
- begin_complex_operation();
+ if (!dobreak) {
+ begin_complex_operation();
+ }
selection.active=false;
update();
_remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
@@ -1892,7 +1953,8 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
if (completion_hint!="") {
completion_hint="";
update();
-
+ } else {
+ scancode_handled=false;
}
} break;
case KEY_TAB: {
@@ -2830,7 +2892,7 @@ int TextEdit::get_char_count() {
return totalsize; // omit last \n
}
-Size2 TextEdit::get_minimum_size() {
+Size2 TextEdit::get_minimum_size() const {
return cache.style_normal->get_minimum_size();
}
@@ -2846,7 +2908,7 @@ void TextEdit::adjust_viewport_to_cursor() {
if (cursor.line_ofs>cursor.line)
cursor.line_ofs=cursor.line;
- int visible_width=cache.size.width-cache.style_normal->get_minimum_size().width-cache.line_number_w;
+ int visible_width=cache.size.width-cache.style_normal->get_minimum_size().width-cache.line_number_w-cache.breakpoint_gutter_width;
if (v_scroll->is_visible())
visible_width-=v_scroll->get_combined_minimum_size().width;
visible_width-=20; // give it a little more space
@@ -3075,7 +3137,8 @@ void TextEdit::insert_text_at_cursor(const String& p_text) {
}
Control::CursorShape TextEdit::get_cursor_shape(const Point2& p_pos) const {
- if(completion_active && completion_rect.has_point(p_pos)) {
+ int gutter=cache.style_normal->get_margin(MARGIN_LEFT)+cache.line_number_w+cache.breakpoint_gutter_width;
+ if((completion_active && completion_rect.has_point(p_pos)) || p_pos.x < gutter) {
return CURSOR_ARROW;
}
return CURSOR_IBEAM;
@@ -3198,7 +3261,9 @@ void TextEdit::_reset_caret_blink_timer() {
void TextEdit::_toggle_draw_caret() {
draw_caret = !draw_caret;
- update();
+ if (is_visible()) {
+ update();
+ }
}
void TextEdit::_update_caches() {
@@ -3220,6 +3285,8 @@ void TextEdit::_update_caches() {
cache.breakpoint_color=get_color("breakpoint_color");
cache.brace_mismatch_color=get_color("brace_mismatch_color");
cache.word_highlighted_color=get_color("word_highlighted_color");
+ cache.search_result_color=get_color("search_result_color");
+ cache.search_result_border_color=get_color("search_result_border_color");
cache.line_spacing=get_constant("line_spacing");
cache.row_height = cache.font->get_height() + cache.line_spacing;
cache.tab_icon=get_icon("tab");
@@ -3481,12 +3548,26 @@ String TextEdit::get_word_under_cursor() const {
return text[cursor.line].substr(prev_cc, next_cc-prev_cc);
}
+void TextEdit::set_search_text(const String &p_search_text) {
+ search_text = p_search_text;
+}
+
+void TextEdit::set_search_flags(uint32_t p_flags) {
+ search_flags = p_flags;
+}
+
+void TextEdit::set_current_search_result(int line, int col) {
+ search_result_line = line;
+ search_result_col = col;
+ update();
+}
+
void TextEdit::set_highlight_all_occurrences(const bool p_enabled) {
highlight_all_occurrences = p_enabled;
update();
}
-int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_search, int p_from_column) {
+int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_search, uint32_t p_search_flags, int p_from_column) {
int col = -1;
if (p_key.length() > 0 && p_search.length() > 0) {
@@ -3494,12 +3575,15 @@ int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_searc
p_from_column = 0;
}
- while (col == -1 && p_from_column <= p_search.length()) {
- // match case
- col = p_search.findn(p_key, p_from_column);
+ while (col == -1 && p_from_column <= p_search.length()) {
+ if (p_search_flags&SEARCH_MATCH_CASE) {
+ col = p_search.find(p_key,p_from_column);
+ } else {
+ col = p_search.findn(p_key,p_from_column);
+ }
// whole words only
- if (col != -1) {
+ if (col != -1 && p_search_flags&SEARCH_WHOLE_WORDS) {
p_from_column=col;
if (col > 0 && _is_text_char(p_search[col-1])) {
@@ -3565,10 +3649,8 @@ bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_li
//wrapped
if (p_search_flags&SEARCH_BACKWARDS) {
- text_line=text_line.substr(from_column,text_line.length());
from_column=text_line.length();
} else {
- text_line=text_line.substr(0,from_column);
from_column=0;
}
@@ -3579,7 +3661,6 @@ bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_li
} else {
- //text_line=text_line.substr(0,p_from_column); //wrap around for missing begining.
if (p_search_flags&SEARCH_BACKWARDS)
from_column=text_line.length()-1;
else
@@ -3588,12 +3669,25 @@ bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_li
pos=-1;
- if (!(p_search_flags&SEARCH_BACKWARDS)) {
+ int pos_from=0;
+ int last_pos=-1;
+ while ((last_pos=(p_search_flags&SEARCH_MATCH_CASE)?text_line.find(p_key,pos_from):text_line.findn(p_key,pos_from))!=-1) {
- pos = (p_search_flags&SEARCH_MATCH_CASE)?text_line.find(p_key,from_column):text_line.findn(p_key,from_column);
- } else {
+ if (p_search_flags&SEARCH_BACKWARDS) {
+
+ if (last_pos>from_column)
+ break;
+ pos=last_pos;
+
+ } else {
- pos = (p_search_flags&SEARCH_MATCH_CASE)?text_line.rfind(p_key,from_column):text_line.rfindn(p_key,from_column);
+ if (last_pos>=from_column) {
+ pos=last_pos;
+ break;
+ }
+ }
+
+ pos_from=last_pos+p_key.length();
}
if (pos!=-1 && (p_search_flags&SEARCH_WHOLE_WORDS)) {
@@ -3731,12 +3825,16 @@ void TextEdit::undo() {
_do_text_op(op, true);
current_op.version=op.prev_version;
if(undo_stack_pos->get().chain_backward) {
- do {
+ while(true) {
+ ERR_BREAK(!undo_stack_pos->prev());
undo_stack_pos = undo_stack_pos->prev();
op = undo_stack_pos->get();
_do_text_op(op, true);
current_op.version = op.prev_version;
- } while(!undo_stack_pos->get().chain_forward);
+ if (undo_stack_pos->get().chain_forward) {
+ break;
+ }
+ }
}
cursor_set_line(undo_stack_pos->get().from_line);
@@ -3755,12 +3853,16 @@ void TextEdit::redo() {
_do_text_op(op, false);
current_op.version = op.version;
if(undo_stack_pos->get().chain_forward) {
- do {
+
+ while(true) {
+ ERR_BREAK(!undo_stack_pos->next());
undo_stack_pos=undo_stack_pos->next();
op = undo_stack_pos->get();
_do_text_op(op, false);
current_op.version = op.version;
- } while(!undo_stack_pos->get().chain_backward);
+ if (undo_stack_pos->get().chain_backward)
+ break;
+ }
}
cursor_set_line(undo_stack_pos->get().to_line);
cursor_set_column(undo_stack_pos->get().to_column);
@@ -4167,6 +4269,24 @@ void TextEdit::set_show_line_numbers(bool p_show) {
update();
}
+void TextEdit::set_draw_breakpoint_gutter(bool p_draw) {
+ draw_breakpoint_gutter = p_draw;
+ update();
+}
+
+bool TextEdit::is_drawing_breakpoint_gutter() const {
+ return draw_breakpoint_gutter;
+}
+
+void TextEdit::set_breakpoint_gutter_width(int p_gutter_width) {
+ breakpoint_gutter_width = p_gutter_width;
+ update();
+}
+
+int TextEdit::get_breakpoint_gutter_width() const {
+ return cache.breakpoint_gutter_width;
+}
+
bool TextEdit::is_text_field() const {
return true;
@@ -4308,6 +4428,8 @@ TextEdit::TextEdit() {
cache.row_height=1;
cache.line_spacing=1;
cache.line_number_w=1;
+ cache.breakpoint_gutter_width=0;
+ breakpoint_gutter_width = 0;
tab_size=4;
text.set_tab_size(tab_size);
@@ -4389,6 +4511,7 @@ TextEdit::TextEdit() {
completion_line_ofs=0;
tooltip_obj=NULL;
line_numbers=false;
+ draw_breakpoint_gutter=false;
next_operation_is_complex=false;
scroll_past_end_of_file_enabled=false;
auto_brace_completion_enabled=false;
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index dbe6293240..22f024c491 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -88,10 +88,13 @@ class TextEdit : public Control {
Color current_line_color;
Color brace_mismatch_color;
Color word_highlighted_color;
+ Color search_result_color;
+ Color search_result_border_color;
int row_height;
int line_spacing;
int line_number_w;
+ int breakpoint_gutter_width;
Size2 size;
} cache;
@@ -222,6 +225,8 @@ class TextEdit : public Control {
bool text_changed_dirty;
bool undo_enabled;
bool line_numbers;
+ bool draw_breakpoint_gutter;
+ int breakpoint_gutter_width;
bool highlight_all_occurrences;
bool scroll_past_end_of_file_enabled;
@@ -249,6 +254,11 @@ class TextEdit : public Control {
bool callhint_below;
Vector2 callhint_offset;
+ String search_text;
+ uint32_t search_flags;
+ int search_result_line;
+ int search_result_col;
+
int get_visible_rows() const;
int get_char_count();
@@ -268,7 +278,7 @@ class TextEdit : public Control {
void _scroll_lines_down();
// void mouse_motion(const Point& p_pos, const Point& p_rel, int p_button_mask);
- Size2 get_minimum_size();
+ Size2 get_minimum_size() const;
int get_row_height() const;
@@ -287,7 +297,7 @@ class TextEdit : public Control {
String _base_get_text(int p_from_line, int p_from_column,int p_to_line,int p_to_column) const;
void _base_remove_text(int p_from_line, int p_from_column,int p_to_line,int p_to_column);
- int _get_column_pos_of_word(const String &p_key, const String &p_search, int p_from_column);
+ int _get_column_pos_of_word(const String &p_key, const String &p_search, uint32_t p_search_flags, int p_from_column);
DVector<int> _search_bind(const String &p_key,uint32_t p_search_flags, int p_from_line,int p_from_column) const;
@@ -408,6 +418,10 @@ public:
void select(int p_from_line,int p_from_column,int p_to_line,int p_to_column);
void deselect();
+ void set_search_text(const String& p_search_text);
+ void set_search_flags(uint32_t p_flags);
+ void set_current_search_result(int line, int col);
+
void set_highlight_all_occurrences(const bool p_enabled);
bool is_selection_active() const;
int get_selection_from_line() const;
@@ -451,6 +465,12 @@ public:
void set_show_line_numbers(bool p_show);
+ void set_draw_breakpoint_gutter(bool p_draw);
+ bool is_drawing_breakpoint_gutter() const;
+
+ void set_breakpoint_gutter_width(int p_gutter_width);
+ int get_breakpoint_gutter_width() const;
+
void set_tooltip_request_func(Object *p_obj, const StringName& p_function, const Variant& p_udata);
void set_completion(bool p_enabled,const Vector<String>& p_prefixes);
diff --git a/scene/gui/texture_frame.cpp b/scene/gui/texture_frame.cpp
index 73fecf591a..143f0e83b8 100644
--- a/scene/gui/texture_frame.cpp
+++ b/scene/gui/texture_frame.cpp
@@ -37,9 +37,54 @@ void TextureFrame::_notification(int p_what) {
return;
- Size2 s=expand?get_size():texture->get_size();
+
RID ci = get_canvas_item();
- draw_texture_rect(texture,Rect2(Point2(),s),false,modulate);
+
+ switch(stretch_mode) {
+ case STRETCH_SCALE_ON_EXPAND: {
+ Size2 s=expand?get_size():texture->get_size();
+ draw_texture_rect(texture,Rect2(Point2(),s),false,modulate);
+ } break;
+ case STRETCH_SCALE: {
+ draw_texture_rect(texture,Rect2(Point2(),get_size()),false,modulate);
+ } break;
+ case STRETCH_TILE: {
+ draw_texture_rect(texture,Rect2(Point2(),get_size()),true,modulate);
+ } break;
+ case STRETCH_KEEP: {
+ draw_texture_rect(texture,Rect2(Point2(),texture->get_size()),false,modulate);
+
+ } break;
+ case STRETCH_KEEP_CENTERED: {
+
+ Vector2 ofs = (get_size() - texture->get_size())/2;
+ draw_texture_rect(texture,Rect2(ofs,texture->get_size()),false,modulate);
+ } break;
+ case STRETCH_KEEP_ASPECT_CENTERED:
+ case STRETCH_KEEP_ASPECT: {
+
+ Size2 size=get_size();
+ int tex_width = texture->get_width() * size.height / texture ->get_height();
+ int tex_height = size.height;
+
+ if (tex_width>size.width) {
+ tex_width=size.width;
+ tex_height=texture->get_height() * tex_width / texture->get_width();
+ }
+
+ int ofs_x = 0;
+ int ofs_y = 0;
+
+ if (stretch_mode==STRETCH_KEEP_ASPECT_CENTERED) {
+ ofs_x+=(size.width - tex_width)/2;
+ ofs_y+=(size.height - tex_height)/2;
+ }
+
+ draw_texture_rect(texture,Rect2(ofs_x,ofs_y,tex_width,tex_height));
+ } break;
+
+ }
+
/*
Vector<Point2> points;
@@ -76,10 +121,21 @@ void TextureFrame::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_modulate"), & TextureFrame::get_modulate );
ObjectTypeDB::bind_method(_MD("set_expand","enable"), & TextureFrame::set_expand );
ObjectTypeDB::bind_method(_MD("has_expand"), & TextureFrame::has_expand );
+ ObjectTypeDB::bind_method(_MD("set_stretch_mode","stretch_mode"), & TextureFrame::set_stretch_mode );
+ ObjectTypeDB::bind_method(_MD("get_stretch_mode"), & TextureFrame::get_stretch_mode );
ADD_PROPERTYNZ( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), _SCS("set_texture"),_SCS("get_texture") );
ADD_PROPERTYNO( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate") );
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "expand" ), _SCS("set_expand"),_SCS("has_expand") );
+ ADD_PROPERTYNO( PropertyInfo( Variant::INT, "stretch_mode",PROPERTY_HINT_ENUM,"Scale On Expand (Compat),Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered"), _SCS("set_stretch_mode"),_SCS("get_stretch_mode") );
+
+ BIND_CONSTANT( STRETCH_SCALE_ON_EXPAND );
+ BIND_CONSTANT( STRETCH_SCALE );
+ BIND_CONSTANT( STRETCH_TILE );
+ BIND_CONSTANT( STRETCH_KEEP );
+ BIND_CONSTANT( STRETCH_KEEP_CENTERED );
+ BIND_CONSTANT( STRETCH_KEEP_ASPECT );
+ BIND_CONSTANT( STRETCH_KEEP_ASPECT_CENTERED );
}
@@ -121,12 +177,24 @@ bool TextureFrame::has_expand() const {
return expand;
}
+void TextureFrame::set_stretch_mode(StretchMode p_mode) {
+
+ stretch_mode=p_mode;
+ update();
+}
+
+TextureFrame::StretchMode TextureFrame::get_stretch_mode() const {
+
+ return stretch_mode;
+}
+
TextureFrame::TextureFrame() {
expand=false;
modulate=Color(1,1,1,1);
set_ignore_mouse(true);
+ stretch_mode=STRETCH_SCALE_ON_EXPAND;
}
diff --git a/scene/gui/texture_frame.h b/scene/gui/texture_frame.h
index e1f0de92df..0b47202532 100644
--- a/scene/gui/texture_frame.h
+++ b/scene/gui/texture_frame.h
@@ -36,10 +36,22 @@
class TextureFrame : public Control {
OBJ_TYPE(TextureFrame,Control);
+public:
+ enum StretchMode {
+ STRETCH_SCALE_ON_EXPAND, //default, for backwards compatibility
+ STRETCH_SCALE,
+ STRETCH_TILE,
+ STRETCH_KEEP,
+ STRETCH_KEEP_CENTERED,
+ STRETCH_KEEP_ASPECT,
+ STRETCH_KEEP_ASPECT_CENTERED,
+ };
+private:
bool expand;
Color modulate;
Ref<Texture> texture;
+ StretchMode stretch_mode;
protected:
void _notification(int p_what);
@@ -57,9 +69,13 @@ public:
void set_expand(bool p_expand);
bool has_expand() const;
+ void set_stretch_mode(StretchMode p_mode);
+ StretchMode get_stretch_mode() const;
+
TextureFrame();
~TextureFrame();
};
+VARIANT_ENUM_CAST( TextureFrame::StretchMode );
#endif // TEXTURE_FRAME_H
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 2c39aea08c..f8516f8f5d 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -811,6 +811,8 @@ void Tree::update_cache() {
cache.item_margin=get_constant("item_margin");
cache.button_margin=get_constant("button_margin");
cache.guide_width=get_constant("guide_width");
+ cache.draw_relationship_lines=get_constant("draw_relationship_lines");
+ cache.relationship_line_color=get_color("relationship_line_color");
cache.title_button = get_stylebox("title_button_normal");
cache.title_button_pressed = get_stylebox("title_button_pressed");
@@ -1186,7 +1188,8 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2&
Ref<Texture> updown = cache.updown;
- String valtext = String::num( p_item->cells[i].val, Math::decimals( p_item->cells[i].step ) );
+ //String valtext = String::num( p_item->cells[i].val, Math::decimals( p_item->cells[i].step ) );
+ String valtext = rtos( p_item->cells[i].val );
font->draw( ci, text_pos, valtext, col, item_rect.size.x-updown->get_width());
if (!p_item->cells[i].editable)
@@ -1294,9 +1297,21 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2&
while (c) {
+ if (cache.draw_relationship_lines == 1){
+ int root_ofs = children_pos.x + (hide_folding?cache.hseparation:cache.item_margin);
+ int parent_ofs = p_pos.x + (hide_folding?cache.hseparation:cache.item_margin);
+ Point2i root_pos = Point2i(root_ofs, children_pos.y + label_h/2)-cache.offset+p_draw_ofs;
+ if (c->get_children() > 0)
+ root_pos -= Point2i(cache.arrow->get_width(),0);
+
+ Point2i parent_pos = Point2i(parent_ofs - cache.arrow->get_width()/2, p_pos.y + label_h/2 + cache.arrow->get_height()/2)-cache.offset+p_draw_ofs;
+ VisualServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x, root_pos.y), cache.relationship_line_color);
+ VisualServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y), parent_pos, cache.relationship_line_color);
+ }
+
int child_h=draw_item(children_pos, p_draw_ofs, p_draw_size, c );
- if (child_h<0)
+ if (child_h<0 && cache.draw_relationship_lines == 0)
return -1; // break, stop drawing, no need to anymore
htotal+=child_h;
@@ -3673,4 +3688,3 @@ Tree::~Tree() {
}
}
-
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 1dad26dffe..0172546c1d 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -377,6 +377,7 @@ friend class TreeItem;
Color font_color_selected;
Color guide_color;
Color drop_position_color;
+ Color relationship_line_color;
int hseparation;
int vseparation;
@@ -384,6 +385,7 @@ friend class TreeItem;
int guide_width;
int button_margin;
Point2 offset;
+ int draw_relationship_lines;
enum ClickType {
CLICK_NONE,
@@ -532,4 +534,3 @@ public:
VARIANT_ENUM_CAST( Tree::SelectMode );
#endif
-
diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp
index 89dacc6577..e9ff76bd91 100644
--- a/scene/gui/video_player.cpp
+++ b/scene/gui/video_player.cpp
@@ -131,7 +131,7 @@ void VideoPlayer::_notification(int p_notification) {
if (!playback->is_playing())
return;
- double audio_time = OS::get_singleton()->get_ticks_usec()/1000000.0; //AudioServer::get_singleton()->get_mix_time();
+ double audio_time = USEC_TO_SEC(OS::get_singleton()->get_ticks_usec()); //AudioServer::get_singleton()->get_mix_time();
double delta = last_audio_time==0?0:audio_time-last_audio_time;
last_audio_time=audio_time;
@@ -208,10 +208,17 @@ void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) {
playback->set_paused(paused);
texture=playback->get_texture();
+ const int channels = playback->get_channels();
+
AudioServer::get_singleton()->lock();
- resampler.setup(playback->get_channels(),playback->get_mix_rate(),server_mix_rate,buffering_ms,0);
+ if (channels > 0)
+ resampler.setup(channels,playback->get_mix_rate(),server_mix_rate,buffering_ms,0);
+ else
+ resampler.clear();
AudioServer::get_singleton()->unlock();
- playback->set_mix_callback(_audio_mix_callback,this);
+
+ if (channels > 0)
+ playback->set_mix_callback(_audio_mix_callback,this);
} else {
texture.unref();