summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/base_button.cpp96
-rw-r--r--scene/gui/base_button.h16
-rw-r--r--scene/gui/button.cpp32
-rw-r--r--scene/gui/button.h16
-rw-r--r--scene/gui/button_array.cpp4
-rw-r--r--scene/gui/button_array.h2
-rw-r--r--scene/gui/button_group.h2
-rw-r--r--scene/gui/check_button.cpp10
-rw-r--r--scene/gui/check_button.h14
-rw-r--r--scene/gui/color_picker.cpp16
-rw-r--r--scene/gui/color_ramp_edit.cpp2
-rw-r--r--scene/gui/control.cpp182
-rw-r--r--scene/gui/control.h64
-rw-r--r--scene/gui/dialogs.cpp22
-rw-r--r--scene/gui/dialogs.h2
-rw-r--r--scene/gui/file_dialog.cpp184
-rw-r--r--scene/gui/file_dialog.h25
-rw-r--r--scene/gui/graph_edit.cpp2
-rw-r--r--scene/gui/graph_edit.h2
-rw-r--r--scene/gui/item_list.cpp56
-rw-r--r--scene/gui/item_list.h7
-rw-r--r--scene/gui/line_edit.cpp276
-rw-r--r--scene/gui/line_edit.h42
-rw-r--r--scene/gui/link_button.cpp124
-rw-r--r--scene/gui/link_button.h40
-rw-r--r--scene/gui/menu_button.cpp10
-rw-r--r--scene/gui/menu_button.h12
-rw-r--r--scene/gui/option_button.cpp60
-rw-r--r--scene/gui/option_button.h18
-rw-r--r--scene/gui/panel.cpp4
-rw-r--r--scene/gui/panel.h4
-rw-r--r--scene/gui/panel_container.cpp7
-rw-r--r--scene/gui/popup.cpp20
-rw-r--r--scene/gui/popup.h12
-rw-r--r--scene/gui/popup_menu.cpp112
-rw-r--r--scene/gui/popup_menu.h26
-rw-r--r--scene/gui/range.cpp34
-rw-r--r--scene/gui/range.h10
-rw-r--r--scene/gui/rich_text_label.cpp6
-rw-r--r--scene/gui/scroll_bar.cpp324
-rw-r--r--scene/gui/scroll_bar.h42
-rw-r--r--scene/gui/scroll_container.cpp38
-rw-r--r--scene/gui/slider.cpp8
-rw-r--r--scene/gui/slider.h2
-rw-r--r--scene/gui/tab_container.cpp4
-rw-r--r--scene/gui/tabs.cpp2
-rw-r--r--scene/gui/text_edit.cpp1747
-rw-r--r--scene/gui/text_edit.h37
-rw-r--r--scene/gui/texture_frame.h2
-rw-r--r--scene/gui/texture_progress.cpp6
-rw-r--r--scene/gui/tree.cpp9
-rw-r--r--scene/gui/tree.h117
52 files changed, 2140 insertions, 1771 deletions
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 698dbce2b5..3bcc60b86a 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -37,19 +37,19 @@ void BaseButton::_input_event(InputEvent p_event) {
if (status.disabled) // no interaction with disabled button
return;
-
+
switch(p_event.type) {
-
+
case InputEvent::MOUSE_BUTTON: {
-
+
const InputEventMouseButton &b=p_event.mouse_button;
-
+
if ( status.disabled || b.button_index!=1 )
return;
if (status.pressing_button)
break;
-
+
if (status.click_on_press) {
if (b.pressed) {
@@ -96,13 +96,13 @@ void BaseButton::_input_event(InputEvent p_event) {
}
if (b.pressed) {
-
+
status.press_attempt=true;
status.pressing_inside=true;
-
+
} else {
-
-
+
+
if (status.press_attempt &&status.pressing_inside) {
if (!toggle_mode) { //mouse press attempt
@@ -114,14 +114,14 @@ void BaseButton::_input_event(InputEvent p_event) {
}
emit_signal("pressed");
-
+
} else {
status.pressed=!status.pressed;
-
+
pressed();
emit_signal("pressed");
-
+
toggled(status.pressed);
emit_signal("toggled",status.pressed);
if (get_script_instance()) {
@@ -134,10 +134,10 @@ void BaseButton::_input_event(InputEvent p_event) {
}
status.press_attempt=false;
-
+
}
-
- update();
+
+ update();
} break;
case InputEvent::MOUSE_MOTION: {
@@ -151,7 +151,7 @@ void BaseButton::_input_event(InputEvent p_event) {
case InputEvent::ACTION:
case InputEvent::JOYSTICK_BUTTON:
case InputEvent::KEY: {
-
+
if (p_event.is_echo()) {
break;
@@ -166,7 +166,7 @@ void BaseButton::_input_event(InputEvent p_event) {
}
if (p_event.is_action("ui_accept")) {
-
+
if (p_event.is_pressed()) {
status.pressing_button++;
@@ -183,18 +183,18 @@ void BaseButton::_input_event(InputEvent p_event) {
status.press_attempt=false;
status.pressing_inside=false;
-
+
if (!toggle_mode) { //mouse press attempt
-
+
pressed();
- emit_signal("pressed");
+ emit_signal("pressed");
} else {
-
+
status.pressed=!status.pressed;
-
+
pressed();
emit_signal("pressed");
-
+
toggled(status.pressed);
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_toggled,status.pressed);
@@ -202,29 +202,29 @@ void BaseButton::_input_event(InputEvent p_event) {
emit_signal("toggled",status.pressed);
}
}
-
+
accept_event();
- update();
+ update();
}
- }
-
+ }
+
}
}
void BaseButton::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_MOUSE_ENTER) {
-
+
status.hovering=true;
update();
}
-
+
if (p_what==NOTIFICATION_MOUSE_EXIT) {
status.hovering=false;
update();
- }
+ }
if (p_what==NOTIFICATION_FOCUS_EXIT) {
if (status.pressing_button && status.press_attempt) {
@@ -282,7 +282,7 @@ void BaseButton::toggled(bool p_pressed) {
void BaseButton::set_disabled(bool p_disabled) {
-
+
status.disabled = p_disabled;
update();
_change_notify("disabled");
@@ -298,7 +298,7 @@ bool BaseButton::is_disabled() const {
}
void BaseButton::set_pressed(bool p_pressed) {
-
+
if (!toggle_mode)
return;
if (status.pressed==p_pressed)
@@ -309,12 +309,12 @@ void BaseButton::set_pressed(bool p_pressed) {
}
bool BaseButton::is_pressing() const{
-
+
return status.press_attempt;
}
bool BaseButton::is_pressed() const {
-
+
return toggle_mode?status.pressed:status.press_attempt;
}
@@ -324,11 +324,11 @@ bool BaseButton::is_hovered() const {
}
BaseButton::DrawMode BaseButton::get_draw_mode() const {
-
+
if (status.disabled) {
return DRAW_DISABLED;
};
-
+
//print_line("press attempt: "+itos(status.press_attempt)+" hover: "+itos(status.hovering)+" pressed: "+itos(status.pressed));
if (status.press_attempt==false && status.hovering && !status.pressed) {
@@ -336,34 +336,34 @@ BaseButton::DrawMode BaseButton::get_draw_mode() const {
return DRAW_HOVER;
} else {
/* determine if pressed or not */
-
+
bool pressing;
if (status.press_attempt) {
-
+
pressing=status.pressing_inside;
if (status.pressed)
pressing=!pressing;
} else {
-
+
pressing=status.pressed;
}
-
- if (pressing)
+
+ if (pressing)
return DRAW_PRESSED;
- else
+ else
return DRAW_NORMAL;
- }
+ }
return DRAW_NORMAL;
}
void BaseButton::set_toggle_mode(bool p_on) {
-
+
toggle_mode=p_on;
}
bool BaseButton::is_toggle_mode() const {
-
+
return toggle_mode;
}
@@ -414,7 +414,7 @@ void BaseButton::_bind_methods() {
}
BaseButton::BaseButton() {
-
+
toggle_mode=false;
status.pressed=false;
status.press_attempt=false;
@@ -426,7 +426,7 @@ BaseButton::BaseButton() {
set_focus_mode( FOCUS_ALL );
group=NULL;
-
+
}
BaseButton::~BaseButton()
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index 83c66326c5..9a5213d971 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -42,9 +42,9 @@ class BaseButton : public Control {
OBJ_TYPE( BaseButton, Control );
bool toggle_mode;
-
+
struct Status {
-
+
bool pressed;
bool hovering;
bool press_attempt;
@@ -55,15 +55,15 @@ class BaseButton : public Control {
int pressing_button;
} status;
-
+
ButtonGroup *group;
-
+
protected:
-
+
virtual void pressed();
virtual void toggled(bool p_pressed);
static void _bind_methods();
@@ -82,7 +82,7 @@ public:
DrawMode get_draw_mode() const;
/* Signals */
-
+
bool is_pressed() const; ///< return wether button is pressed (toggled in)
bool is_pressing() const; ///< return wether button is pressed (toggled in)
bool is_hovered() const;
@@ -90,7 +90,7 @@ public:
void set_pressed(bool p_pressed); ///only works in toggle mode
void set_toggle_mode(bool p_on);
bool is_toggle_mode() const;
-
+
void set_disabled(bool p_disabled);
bool is_disabled() const;
@@ -98,7 +98,7 @@ public:
bool get_click_on_press() const;
- BaseButton();
+ BaseButton();
~BaseButton();
};
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index b9ce46d738..0f3f762ba1 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -45,7 +45,7 @@ Size2 Button::get_minimum_size() const {
_icon=icon;
if (!_icon.is_null()) {
-
+
minsize.height=MAX( minsize.height, _icon->get_height() );
minsize.width+=_icon->get_width();
if (text!="")
@@ -53,48 +53,48 @@ Size2 Button::get_minimum_size() const {
}
return get_stylebox("normal" )->get_minimum_size() + minsize;
-
+
}
void Button::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_DRAW) {
-
+
RID ci = get_canvas_item();
Size2 size=get_size();
Color color;
//print_line(get_text()+": "+itos(is_flat())+" hover "+itos(get_draw_mode()));
-
+
switch( get_draw_mode() ) {
-
+
case DRAW_NORMAL: {
-
+
if (!flat)
get_stylebox("normal" )->draw( ci, Rect2(Point2(0,0), size) );
- color=get_color("font_color");
+ color=get_color("font_color");
} break;
case DRAW_PRESSED: {
-
+
get_stylebox("pressed" )->draw( ci, Rect2(Point2(0,0), size) );
if (has_color("font_color_pressed"))
color=get_color("font_color_pressed");
else
color=get_color("font_color");
-
+
} break;
case DRAW_HOVER: {
-
+
get_stylebox("hover" )->draw( ci, Rect2(Point2(0,0), size) );
color=get_color("font_color_hover");
-
+
} break;
case DRAW_DISABLED: {
get_stylebox("disabled" )->draw( ci, Rect2(Point2(0,0), size) );
color=get_color("font_color_disabled");
-
+
} break;
}
@@ -139,12 +139,12 @@ void Button::_notification(int p_what) {
if (!_icon.is_null()) {
int valign = size.height-style->get_minimum_size().y;
-
+
_icon->draw(ci,style->get_offset()+Point2(0, Math::floor( (valign-_icon->get_height())/2.0 ) ),is_disabled()?Color(1,1,1,0.4):Color(1,1,1) );
}
-
+
}
}
@@ -236,7 +236,7 @@ void Button::_bind_methods() {
}
Button::Button(const String &p_text) {
-
+
flat=false;
clip_text=false;
set_stop_mouse(true);
diff --git a/scene/gui/button.h b/scene/gui/button.h
index bd244f5087..8a17a164a0 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -34,7 +34,7 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class Button : public BaseButton {
-
+
OBJ_TYPE( Button, BaseButton );
public:
@@ -49,25 +49,25 @@ private:
bool flat;
String text;
- Ref<Texture> icon;
+ Ref<Texture> icon;
bool clip_text;
TextAlign align;
-
-protected:
+
+protected:
virtual Size2 get_minimum_size() const;
void _notification(int p_what);
- static void _bind_methods();
+ static void _bind_methods();
public:
-//
+//
void set_text(const String& p_text);
String get_text() const;
-
+
void set_icon(const Ref<Texture>& p_icon);
Ref<Texture> get_icon() const;
-
+
void set_flat(bool p_flat);
bool is_flat() const;
diff --git a/scene/gui/button_array.cpp b/scene/gui/button_array.cpp
index 9e3476899f..de77b83403 100644
--- a/scene/gui/button_array.cpp
+++ b/scene/gui/button_array.cpp
@@ -171,9 +171,9 @@ void ButtonArray::_notification(int p_what) {
case NOTIFICATION_READY:{
MethodInfo mi;
mi.name="mouse_sub_enter";
-
+
add_user_signal(mi);
-
+
}break;
case NOTIFICATION_DRAW: {
diff --git a/scene/gui/button_array.h b/scene/gui/button_array.h
index 39661eaabd..c4b9b0c9e3 100644
--- a/scene/gui/button_array.h
+++ b/scene/gui/button_array.h
@@ -69,7 +69,7 @@ protected:
void _notification(int p_what);
static void _bind_methods();
-
+
public:
void _input_event(const InputEvent& p_event);
diff --git a/scene/gui/button_group.h b/scene/gui/button_group.h
index 38c61991b7..4afba22228 100644
--- a/scene/gui/button_group.h
+++ b/scene/gui/button_group.h
@@ -55,7 +55,7 @@ friend class BaseButton;
public:
void get_button_list(List<BaseButton*> *p_buttons) const;
- BaseButton *get_pressed_button() const;
+ BaseButton *get_pressed_button() const;
BaseButton *get_focused_button() const;
void set_pressed_button(BaseButton *p_button);
int get_pressed_button_index() const;
diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp
index ecaea251a5..f8c0c6b208 100644
--- a/scene/gui/check_button.cpp
+++ b/scene/gui/check_button.cpp
@@ -33,9 +33,9 @@
void CheckButton::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_DRAW) {
-
+
RID ci = get_canvas_item();
Ref<Texture> on=Control::get_icon("on");
@@ -50,17 +50,17 @@ void CheckButton::_notification(int p_what) {
else
off->draw(ci,ofs);
-
+
}
}
CheckButton::CheckButton() {
-
+
set_toggle_mode(true);
set_text_align(ALIGN_LEFT);
-
+
}
diff --git a/scene/gui/check_button.h b/scene/gui/check_button.h
index 022ade2193..a1ed4c1896 100644
--- a/scene/gui/check_button.h
+++ b/scene/gui/check_button.h
@@ -35,18 +35,18 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class CheckButton : public Button {
-
+
OBJ_TYPE( CheckButton, Button );
-
-
-protected:
+
+
+protected:
void _notification(int p_what);
public:
-
- CheckButton();
+
+ CheckButton();
~CheckButton();
-
+
};
#endif
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index f1b910d23f..bd24b43761 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -246,7 +246,7 @@ void ColorPicker::set_raw_mode(bool p_enabled) {
raw_mode_enabled=p_enabled;
if (btn_mode->is_pressed()!=p_enabled)
btn_mode->set_pressed(p_enabled);
-
+
if (!is_inside_tree())
return;
@@ -322,7 +322,7 @@ void ColorPicker::_w_input(const InputEvent &ev) {
if (bev.pressed) {
changing_color = true;
h=1-((float)bev.y)/256.0;
-
+
} else {
changing_color = false;
}
@@ -361,7 +361,10 @@ void ColorPicker::_preset_input(const InputEvent &ev) {
emit_signal("color_changed", color);
} else if (ev.type == InputEvent::MOUSE_MOTION) {
const InputEventMouse &mev = ev.mouse_motion;
- int index = mev.x/(preset->get_size().x/presets.size());
+ int index = mev.x * presets.size();
+ if( preset->get_size().x != 0 ) {
+ index /= preset->get_size().x;
+ }
if (index<0 || index >= presets.size())
return;
preset->set_tooltip("Color: #"+presets[index].to_html(presets[index].a<1)+"\n"
@@ -502,7 +505,7 @@ ColorPicker::ColorPicker() :
args.push_back(1);
args.push_back(c);
c->connect("draw",this,"_hsv_draw",args);
-
+
hb_edit->add_child(uv_edit);
hb_edit->add_child(memnew( VSeparator ));
hb_edit->add_child(w_edit);
@@ -543,7 +546,7 @@ ColorPicker::ColorPicker() :
}
HBoxContainer *hhb = memnew( HBoxContainer );
-
+
btn_mode = memnew( CheckButton );
btn_mode->set_text("RAW Mode");
btn_mode->connect("toggled", this, "set_raw_mode");
@@ -570,7 +573,7 @@ ColorPicker::ColorPicker() :
uv_material->set_shader(s_uv);
w_material.instance();
-
+
Ref<Shader> s_w = get_shader("w_editor");
w_material->set_shader(s_w);
@@ -684,4 +687,3 @@ ColorPickerButton::ColorPickerButton() {
picker->connect("color_changed",this,"_color_changed");
add_child(popup);
}
-
diff --git a/scene/gui/color_ramp_edit.cpp b/scene/gui/color_ramp_edit.cpp
index 14a48fe3d3..2ab004e04b 100644
--- a/scene/gui/color_ramp_edit.cpp
+++ b/scene/gui/color_ramp_edit.cpp
@@ -185,7 +185,7 @@ void ColorRampEdit::_input_event(const InputEvent& p_event) {
int x = p_event.mouse_motion.x;
float newofs = CLAMP(x/float(total_w),0,1);
-
+
//Snap to nearest point if holding shift
if (p_event.key.mod.shift) {
float snap_treshhold = 0.03;
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index af3b37bec2..d7befd6e11 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -39,6 +39,9 @@
#include "scene/scene_string_names.h"
#include "scene/gui/panel.h"
#include "scene/gui/label.h"
+#ifdef TOOLS_ENABLED
+#include "tools/editor/editor_settings.h"
+#endif
#include <stdio.h>
@@ -226,9 +229,9 @@ bool Control::_get(const StringName& p_name,Variant &r_ret) const {
return false;
-
+
return true;
-
+
}
void Control::_get_property_list( List<PropertyInfo> *p_list) const {
@@ -326,7 +329,7 @@ Control *Control::get_parent_control() const {
void Control::_resize(const Size2& p_size) {
-
+
_size_changed();
}
@@ -626,7 +629,7 @@ void Control::set_drag_preview(Control *p_control) {
}
-
+
bool Control::is_window_modal_on_top() const {
@@ -640,7 +643,7 @@ bool Control::is_window_modal_on_top() const {
Size2 Control::get_minimum_size() const {
-
+
ScriptInstance *si = const_cast<Control*>(this)->get_script_instance();
if (si) {
@@ -654,7 +657,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()) {
const Ref<Texture>* tex = data.icon_override.getptr(p_name);
@@ -714,7 +717,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()) {
const Ref<StyleBox>* style = data.style_override.getptr(p_name);
if (style)
@@ -828,12 +831,12 @@ int Control::get_constant(const StringName& p_name,const StringName& p_type) con
return Theme::get_default()->get_constant( p_name, type );
-
+
}
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)
@@ -859,7 +862,7 @@ bool Control::has_icon(const StringName& p_name,const StringName& p_type) const
}
return Theme::get_default()->has_icon( p_name, type );
-
+
}
bool Control::has_shader(const StringName &p_name, const StringName &p_type) const
@@ -889,10 +892,10 @@ bool Control::has_shader(const StringName &p_name, const StringName &p_type) con
}
return Theme::get_default()->has_shader( p_name, type );
-
+
}
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);
@@ -922,7 +925,7 @@ 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)
@@ -952,7 +955,7 @@ bool Control::has_font(const StringName& p_name,const StringName& p_type) const
}
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)
@@ -1024,7 +1027,7 @@ Size2 Control::get_parent_area_size() const {
} else {
parent_size=get_viewport()->get_visible_rect().size;
- }
+ }
return parent_size;
}
@@ -1083,11 +1086,11 @@ void Control::_size_changed() {
}
float Control::_get_parent_range(int p_idx) const {
-
+
if (!is_inside_tree()) {
-
+
return 1.0;
-
+
} if (data.parent_canvas_item) {
return data.parent_canvas_item->get_item_rect().size[p_idx&1];
@@ -1100,21 +1103,21 @@ float Control::_get_parent_range(int p_idx) const {
float Control::_get_range(int p_idx) const {
-
+
p_idx&=1;
float parent_range = _get_parent_range( p_idx );
float from = _a2s( data.margin[p_idx], data.anchor[p_idx], parent_range );
float to = _a2s( data.margin[p_idx+2], data.anchor[p_idx+2], parent_range );
-
+
return to-from;
}
float Control::_s2a(float p_val, AnchorType p_anchor,float p_range) const {
-
+
switch(p_anchor) {
-
- case ANCHOR_BEGIN: {
+
+ case ANCHOR_BEGIN: {
return p_val;
} break;
case ANCHOR_END: {
@@ -1122,21 +1125,21 @@ float Control::_s2a(float p_val, AnchorType p_anchor,float p_range) const {
} break;
case ANCHOR_RATIO: {
return p_val/p_range;
- } break;
+ } break;
case ANCHOR_CENTER: {
return (p_range/2)-p_val;
} break;
- }
-
+ }
+
return 0;
}
float Control::_a2s(float p_val, AnchorType p_anchor,float p_range) const {
-
+
switch(p_anchor) {
-
- case ANCHOR_BEGIN: {
+
+ case ANCHOR_BEGIN: {
return Math::floor(p_val);
} break;
case ANCHOR_END: {
@@ -1144,7 +1147,7 @@ float Control::_a2s(float p_val, AnchorType p_anchor,float p_range) const {
} break;
case ANCHOR_RATIO: {
return Math::floor(p_range*p_val);
- } break;
+ } break;
case ANCHOR_CENTER: {
return Math::floor((p_range/2)-p_val);
} break;
@@ -1153,20 +1156,36 @@ float Control::_a2s(float p_val, AnchorType p_anchor,float p_range) const {
}
-void Control::set_anchor(Margin p_margin,AnchorType p_anchor) {
-
+void Control::set_anchor(Margin p_margin,AnchorType p_anchor, bool p_keep_margin) {
+
if (!is_inside_tree()) {
-
- data.anchor[p_margin]=p_anchor;
- } else {
+
+ data.anchor[p_margin] = p_anchor;
+ } else if(!p_keep_margin) {
float pr = _get_parent_range(p_margin);
float s = _a2s( data.margin[p_margin], data.anchor[p_margin], pr );
- data.anchor[p_margin]=p_anchor;
+ data.anchor[p_margin] = p_anchor;
data.margin[p_margin] = _s2a( s, p_anchor, pr );
+ } else {
+ data.anchor[p_margin] = p_anchor;
+ _size_changed();
}
_change_notify();
}
+void Control::_set_anchor(Margin p_margin,AnchorType p_anchor) {
+ #ifdef TOOLS_ENABLED
+ SceneTree *st=OS::get_singleton()->get_main_loop()->cast_to<SceneTree>();
+ if (st && st->is_editor_hint()) {
+ set_anchor(p_margin, p_anchor, EDITOR_DEF("2d_editor/keep_margins_when_changing_anchors", false));
+ } else {
+ set_anchor(p_margin, p_anchor);
+ }
+ #else
+ set_anchor(p_margin, p_anchor);
+ #endif
+}
+
void Control::set_anchor_and_margin(Margin p_margin,AnchorType p_anchor, float p_pos) {
set_anchor(p_margin,p_anchor);
@@ -1175,8 +1194,8 @@ void Control::set_anchor_and_margin(Margin p_margin,AnchorType p_anchor, float p
Control::AnchorType Control::get_anchor(Margin p_margin) const {
-
- return data.anchor[p_margin];
+
+ return data.anchor[p_margin];
}
@@ -1204,40 +1223,40 @@ void Control::set_margin(Margin p_margin,float p_value) {
}
void Control::set_begin(const Size2& p_point) {
-
+
data.margin[0]=p_point.x;
data.margin[1]=p_point.y;
_size_changed();
}
void Control::set_end(const Size2& p_point) {
-
+
data.margin[2]=p_point.x;
data.margin[3]=p_point.y;
_size_changed();
}
float Control::get_margin(Margin p_margin) const {
-
+
return data.margin[p_margin];
}
Size2 Control::get_begin() const {
-
+
return Size2( data.margin[0], data.margin[1] );
}
Size2 Control::get_end() const {
-
+
return Size2( data.margin[2], data.margin[3] );
}
Point2 Control::get_global_pos() const {
-
+
return get_global_transform().get_origin();
}
void Control::set_global_pos(const Point2& p_point) {
-
+
Matrix32 inv;
if (data.parent_canvas_item) {
@@ -1264,10 +1283,10 @@ void Control::set_pos(const Size2& p_point) {
Size2 size = Size2(MAX( min.width, ret.width),MAX( min.height, ret.height));
float w=size.x;
float h=size.y;
-
+
x=p_point.x;
y=p_point.y;
-
+
data.margin[0] = _s2a( x, data.anchor[0], pw );
data.margin[1] = _s2a( y, data.anchor[1], ph );
data.margin[2] = _s2a( x+w, data.anchor[2], pw );
@@ -1277,26 +1296,26 @@ void Control::set_pos(const Size2& p_point) {
}
void Control::set_size(const Size2& p_size) {
-
+
Size2 new_size=p_size;
Size2 min=get_combined_minimum_size();
if (new_size.x<min.x)
new_size.x=min.x;
if (new_size.y<min.y)
new_size.y=min.y;
-
+
float pw = _get_parent_range(0);
float ph = _get_parent_range(1);
-
+
float x = _a2s( data.margin[0], data.anchor[0], pw );
float y = _a2s( data.margin[1], data.anchor[1], ph );
-
+
float w=new_size.width;
float h=new_size.height;
-
+
data.margin[2] = _s2a( x+w, data.anchor[2], pw );
data.margin[3] = _s2a( y+h, data.anchor[3], ph );
-
+
_size_changed();
}
@@ -1308,13 +1327,13 @@ Size2 Control::get_pos() const {
}
Size2 Control::get_size() const {
-
+
return data.size_cache;
}
Rect2 Control::get_global_rect() const {
-
- return Rect2( get_global_pos(), get_size() );
+
+ return Rect2( get_global_pos(), get_size() );
}
Rect2 Control::get_window_rect() const {
@@ -1326,7 +1345,7 @@ Rect2 Control::get_window_rect() const {
Rect2 Control::get_rect() const {
-
+
return Rect2(get_pos(),get_size());
}
@@ -1336,7 +1355,7 @@ Rect2 Control::get_item_rect() const {
}
void Control::set_area_as_parent_rect(int p_margin) {
-
+
data.anchor[MARGIN_LEFT]=ANCHOR_BEGIN;
data.anchor[MARGIN_TOP]=ANCHOR_BEGIN;
data.anchor[MARGIN_RIGHT]=ANCHOR_END;
@@ -1345,7 +1364,7 @@ void Control::set_area_as_parent_rect(int p_margin) {
data.margin[i]=p_margin;
_size_changed();
-
+
}
void Control::add_icon_override(const StringName& p_name, const Ref<Texture>& p_icon) {
@@ -1354,7 +1373,7 @@ void Control::add_icon_override(const StringName& p_name, const Ref<Texture>& p_
data.icon_override[p_name]=p_icon;
notification(NOTIFICATION_THEME_CHANGED);
update();
-
+
}
void Control::add_shader_override(const StringName &p_name, const Ref<Shader> &p_shader) {
@@ -1406,7 +1425,7 @@ static Control *_next_control(Control *p_from) {
if (p_from->is_set_as_toplevel())
return NULL; // can't go above
- Control *parent = p_from->get_parent()?p_from->get_parent()->cast_to<Control>():NULL;
+ Control *parent = p_from->get_parent()?p_from->get_parent()->cast_to<Control>():NULL;
if (!parent) {
@@ -1432,10 +1451,10 @@ static Control *_next_control(Control *p_from) {
Control *Control::find_next_valid_focus() const {
Control *from = const_cast<Control*>(this);
-
+
while(true) {
-
-
+
+
// find next child
Control *next_child=NULL;
@@ -1494,7 +1513,7 @@ Control *Control::find_next_valid_focus() const {
from = next_child;
}
-
+
return NULL;
@@ -1610,7 +1629,7 @@ void Control::grab_focus() {
get_viewport()->_gui_control_grab_focus(this);
-}
+}
void Control::release_focus() {
@@ -1630,7 +1649,7 @@ bool Control::is_toplevel_control() const {
}
void Control::show_modal(bool p_exclusive) {
-
+
ERR_FAIL_COND(!is_inside_tree());
ERR_FAIL_COND(!data.SI);
@@ -1642,7 +1661,7 @@ void Control::show_modal(bool p_exclusive) {
raise();
data.modal_exclusive=p_exclusive;
data.MI=get_viewport()->_gui_show_modal(this);
-
+
}
void Control::_modal_set_prev_focus_owner(ObjectID p_prev) {
@@ -2090,7 +2109,8 @@ void Control::_bind_methods() {
ObjectTypeDB::bind_method(_MD("accept_event"),&Control::accept_event);
ObjectTypeDB::bind_method(_MD("get_minimum_size"),&Control::get_minimum_size);
ObjectTypeDB::bind_method(_MD("get_combined_minimum_size"),&Control::get_combined_minimum_size);
- ObjectTypeDB::bind_method(_MD("set_anchor","margin","anchor_mode"),&Control::set_anchor);
+ ObjectTypeDB::bind_method(_MD("set_anchor","margin","anchor_mode","keep_margin"),&Control::set_anchor,DEFVAL(false));
+ ObjectTypeDB::bind_method(_MD("_set_anchor","margin","anchor_mode"),&Control::_set_anchor);
ObjectTypeDB::bind_method(_MD("get_anchor","margin"),&Control::get_anchor);
ObjectTypeDB::bind_method(_MD("set_margin","margin","offset"),&Control::set_margin);
ObjectTypeDB::bind_method(_MD("set_anchor_and_margin","margin","anchor_mode","offset"),&Control::set_anchor_and_margin);
@@ -2135,7 +2155,7 @@ void Control::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_theme","theme:Theme"),&Control::set_theme);
ObjectTypeDB::bind_method(_MD("get_theme:Theme"),&Control::get_theme);
-
+
ObjectTypeDB::bind_method(_MD("add_icon_override","name","texture:Texture"),&Control::add_icon_override);
ObjectTypeDB::bind_method(_MD("add_shader_override","name","shader:Shader"),&Control::add_shader_override);
ObjectTypeDB::bind_method(_MD("add_style_override","name","stylebox:StyleBox"),&Control::add_style_override);
@@ -2150,7 +2170,7 @@ void Control::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_constant","name","type"),&Control::get_constant,DEFVAL(""));
- ObjectTypeDB::bind_method(_MD("get_parent_control:Control"),&Control::get_parent_control);
+ ObjectTypeDB::bind_method(_MD("get_parent_control:Control"),&Control::get_parent_control);
ObjectTypeDB::bind_method(_MD("set_tooltip","tooltip"),&Control::set_tooltip);
ObjectTypeDB::bind_method(_MD("get_tooltip","atpos"),&Control::get_tooltip,DEFVAL(Point2()));
@@ -2184,10 +2204,10 @@ void Control::_bind_methods() {
BIND_VMETHOD(MethodInfo(Variant::BOOL,"can_drop_data",PropertyInfo(Variant::VECTOR2,"pos"),PropertyInfo(Variant::NIL,"data")));
BIND_VMETHOD(MethodInfo("drop_data",PropertyInfo(Variant::VECTOR2,"pos"),PropertyInfo(Variant::NIL,"data")));
- ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/left", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("set_anchor"),_SCS("get_anchor"), MARGIN_LEFT );
- ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/top", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("set_anchor"),_SCS("get_anchor"), MARGIN_TOP );
- ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/right", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("set_anchor"),_SCS("get_anchor"), MARGIN_RIGHT );
- ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/bottom", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("set_anchor"),_SCS("get_anchor"), MARGIN_BOTTOM );
+ ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/left", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("_set_anchor"),_SCS("get_anchor"), MARGIN_LEFT );
+ ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/top", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("_set_anchor"),_SCS("get_anchor"), MARGIN_TOP );
+ ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/right", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("_set_anchor"),_SCS("get_anchor"), MARGIN_RIGHT );
+ ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"anchor/bottom", PROPERTY_HINT_ENUM, "Begin,End,Ratio,Center"), _SCS("_set_anchor"),_SCS("get_anchor"), MARGIN_BOTTOM );
ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"margin/left", PROPERTY_HINT_RANGE, "-4096,4096"), _SCS("set_margin"),_SCS("get_margin"), MARGIN_LEFT );
ADD_PROPERTYINZ( PropertyInfo(Variant::INT,"margin/top", PROPERTY_HINT_RANGE, "-4096,4096"), _SCS("set_margin"),_SCS("get_margin"), MARGIN_TOP );
@@ -2214,7 +2234,7 @@ void Control::_bind_methods() {
BIND_CONSTANT( ANCHOR_BEGIN );
BIND_CONSTANT( ANCHOR_END );
- BIND_CONSTANT( ANCHOR_RATIO );
+ BIND_CONSTANT( ANCHOR_RATIO );
BIND_CONSTANT( ANCHOR_CENTER );
BIND_CONSTANT( FOCUS_NONE );
BIND_CONSTANT( FOCUS_CLICK );
@@ -2261,11 +2281,11 @@ void Control::_bind_methods() {
ADD_SIGNAL( MethodInfo("minimum_size_changed") );
ADD_SIGNAL( MethodInfo("modal_close") );
-
+
}
Control::Control() {
-
- data.parent=NULL;
+
+ data.parent=NULL;
data.ignore_mouse=false;
data.stop_mouse=true;
@@ -2297,12 +2317,10 @@ Control::Control() {
-
+
}
Control::~Control()
{
}
-
-
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 74d40b7579..1e2db7a575 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -45,19 +45,19 @@ class Label;
class Panel;
class Control : public CanvasItem {
-
+
OBJ_TYPE( Control, CanvasItem );
OBJ_CATEGORY("GUI Nodes");
public:
-
- enum AnchorType {
+
+ enum AnchorType {
ANCHOR_BEGIN,
ANCHOR_END,
ANCHOR_RATIO,
ANCHOR_CENTER,
};
-
+
enum FocusMode {
FOCUS_NONE,
FOCUS_CLICK,
@@ -106,7 +106,7 @@ private:
};
struct Data {
-
+
Point2 pos_cache;
Size2 size_cache;
@@ -132,7 +132,7 @@ private:
bool modal;
bool modal_exclusive;
Ref<Theme> theme;
- Control *theme_owner;
+ Control *theme_owner;
String tooltip;
CursorShape default_cursor;
@@ -153,7 +153,7 @@ private:
HashMap<StringName, Color, StringNameHasher > color_override;
HashMap<StringName, int, StringNameHasher > constant_override;
} data;
-
+
// used internally
Control* _find_control_at_pos(CanvasItem* p_node,const Point2& p_pos,const Matrix32& p_xform,Matrix32& r_inv_xform);
@@ -162,6 +162,8 @@ private:
Control *_get_focus_neighbour(Margin p_margin,int p_count=0);
+ void _set_anchor(Margin p_margin,AnchorType p_anchor);
+
float _get_parent_range(int p_idx) const;
float _get_range(int p_idx) const;
float _s2a(float p_val, AnchorType p_anchor,float p_range) const;
@@ -184,7 +186,7 @@ friend class Viewport;
void _modal_stack_remove();
void _modal_set_prev_focus_owner(ObjectID p_prev);
-protected:
+protected:
//virtual void _window_input_event(InputEvent p_event);
@@ -194,15 +196,15 @@ protected:
void _notification(int p_notification);
-
- static void _bind_methods();
-
- //bind helpers
-
+
+ static void _bind_methods();
+
+ //bind helpers
+
public:
enum {
-
+
/* NOTIFICATION_DRAW=30,
NOTIFICATION_VISIBILITY_CHANGED=38*/
NOTIFICATION_RESIZED=40,
@@ -241,29 +243,29 @@ public:
Control *get_parent_control() const;
-
+
/* POSITIONING */
-
- void set_anchor(Margin p_margin,AnchorType p_anchor);
+
+ void set_anchor(Margin p_margin,AnchorType p_anchor, bool p_keep_margin=false);
void set_anchor_and_margin(Margin p_margin,AnchorType p_anchor, float p_pos);
-
+
AnchorType get_anchor(Margin p_margin) const;
-
+
void set_margin(Margin p_margin,float p_value);
-
+
void set_begin(const Point2& p_point); // helper
void set_end(const Point2& p_point); // helper
-
-
-
+
+
+
float get_margin(Margin p_margin) const;
Point2 get_begin() const;
Point2 get_end() const;
-
+
void set_pos(const Point2& p_point);
void set_size(const Size2& p_size);
void set_global_pos(const Point2& p_point);
-
+
Point2 get_pos() const;
Point2 get_global_pos() const;
Size2 get_size() const;
@@ -277,9 +279,9 @@ public:
void set_scale(const Vector2& p_scale);
Vector2 get_scale() const;
-
+
void set_area_as_parent_rect(int p_margin=0);
-
+
void show_modal(bool p_exclusive=false);
void set_theme(const Ref<Theme>& p_theme);
@@ -297,7 +299,7 @@ public:
void minimum_size_changed();
/* FOCUS */
-
+
void set_focus_mode(FocusMode p_focus_mode);
FocusMode get_focus_mode() const;
bool has_focus() const;
@@ -319,7 +321,7 @@ public:
bool is_stopping_mouse() const;
/* SKINNING */
-
+
void add_icon_override(const StringName& p_name, const Ref<Texture>& p_icon);
void add_shader_override(const StringName& p_name, const Ref<Shader>& p_shader);
void add_style_override(const StringName& p_name, const Ref<StyleBox>& p_style);
@@ -367,9 +369,9 @@ public:
Control *get_root_parent_control() const;
- Control();
+ Control();
~Control();
-
+
};
VARIANT_ENUM_CAST(Control::AnchorType);
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index 9f08b6f845..d00dacd256 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -188,7 +188,7 @@ void AcceptDialog::_post_popup() {
}
void AcceptDialog::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_MODAL_CLOSE) {
cancel_pressed();
@@ -197,7 +197,7 @@ void AcceptDialog::_notification(int p_what) {
- }
+ }
}
void AcceptDialog::_builtin_text_entered(const String& p_text) {
@@ -206,7 +206,7 @@ void AcceptDialog::_builtin_text_entered(const String& p_text) {
}
void AcceptDialog::_ok_pressed() {
-
+
if (hide_on_ok)
hide();
ok_pressed();
@@ -214,7 +214,7 @@ void AcceptDialog::_ok_pressed() {
}
void AcceptDialog::_close_pressed() {
-
+
cancel_pressed();
}
@@ -223,7 +223,7 @@ String AcceptDialog::get_text() const {
return label->get_text();
}
void AcceptDialog::set_text(String p_text) {
-
+
label->set_text(p_text);
}
@@ -291,7 +291,7 @@ Button* AcceptDialog::add_cancel(const String &p_cancel) {
}
void AcceptDialog::_bind_methods() {
-
+
ObjectTypeDB::bind_method(_MD("_ok"),&AcceptDialog::_ok_pressed);
ObjectTypeDB::bind_method(_MD("get_ok"),&AcceptDialog::get_ok);
ObjectTypeDB::bind_method(_MD("get_label"),&AcceptDialog::get_label);
@@ -321,11 +321,11 @@ void AcceptDialog::set_swap_ok_cancel(bool p_swap) {
}
AcceptDialog::AcceptDialog() {
-
+
int margin = get_constant("margin","Dialogs");
int button_margin = get_constant("button_margin","Dialogs");
-
-
+
+
label = memnew( Label );
label->set_anchor(MARGIN_RIGHT,ANCHOR_END);
label->set_anchor(MARGIN_BOTTOM,ANCHOR_END);
@@ -345,8 +345,8 @@ AcceptDialog::AcceptDialog() {
hbc->add_child(ok);
hbc->add_spacer();
//add_child(ok);
-
-
+
+
ok->connect("pressed", this,"_ok");
set_as_toplevel(true);
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index 7c06ded866..f256c49aee 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -142,7 +142,7 @@ public:
class ConfirmationDialog : public AcceptDialog {
-
+
OBJ_TYPE(ConfirmationDialog,AcceptDialog);
Button *cancel;
protected:
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 56b9260837..64fdfdfefe 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -51,7 +51,7 @@ void FileDialog::_notification(int p_what) {
refresh->set_icon(get_icon("reload"));
}
-
+
if (p_what==NOTIFICATION_DRAW) {
//RID ci = get_canvas_item();
@@ -117,13 +117,13 @@ Vector<String> FileDialog::get_selected_files() const {
};
void FileDialog::update_dir() {
-
+
dir->set_text(dir_access->get_current_dir());
}
void FileDialog::_dir_entered(String p_dir) {
-
-
+
+
dir_access->change_dir(p_dir);
file->set_text("");
invalidate();
@@ -132,13 +132,13 @@ void FileDialog::_dir_entered(String p_dir) {
void FileDialog::_file_entered(const String& p_file) {
- _action_pressed();
+ _action_pressed();
}
void FileDialog::_save_confirm_pressed() {
String f=dir_access->get_current_dir().plus_file(file->get_text());
emit_signal("file_selected",f);
- hide();
+ hide();
}
void FileDialog::_post_popup() {
@@ -158,7 +158,7 @@ void FileDialog::_post_popup() {
}
void FileDialog::_action_pressed() {
-
+
if (mode==MODE_OPEN_FILES) {
TreeItem *ti=tree->get_next_selected(NULL);
@@ -180,13 +180,11 @@ void FileDialog::_action_pressed() {
}
String f=dir_access->get_current_dir().plus_file(file->get_text());
-
- if (mode==MODE_OPEN_FILE && dir_access->file_exists(f)) {
+
+ if ((mode==MODE_OPEN_ANY || mode==MODE_OPEN_FILE) && dir_access->file_exists(f)) {
emit_signal("file_selected",f);
hide();
- }
-
- if (mode==MODE_OPEN_DIR) {
+ }else if (mode==MODE_OPEN_ANY || mode==MODE_OPEN_DIR) {
String path=dir_access->get_current_dir();
@@ -202,7 +200,7 @@ void FileDialog::_action_pressed() {
}
if (mode==MODE_SAVE_FILE) {
-
+
bool valid=false;
if (filter->get_selected()==filter->get_item_count()-1) {
@@ -263,7 +261,7 @@ void FileDialog::_action_pressed() {
confirm_save->set_text("File Exists, Overwrite?");
confirm_save->popup_centered(Size2(200,80));
} else {
-
+
emit_signal("file_selected",f);
hide();
@@ -279,51 +277,51 @@ void FileDialog::_cancel_pressed() {
}
void FileDialog::_tree_selected() {
-
+
TreeItem *ti=tree->get_selected();
if (!ti)
return;
Dictionary d=ti->get_metadata(0);
-
+
if (!d["dir"]) {
-
+
file->set_text(d["name"]);
}
-
+
}
void FileDialog::_tree_dc_selected() {
-
+
TreeItem *ti=tree->get_selected();
if (!ti)
return;
-
+
Dictionary d=ti->get_metadata(0);
if (d["dir"]) {
-
+
dir_access->change_dir(d["name"]);
- if (mode==MODE_OPEN_FILE || mode==MODE_OPEN_FILES || mode==MODE_OPEN_DIR)
+ if (mode==MODE_OPEN_FILE || mode==MODE_OPEN_FILES || mode==MODE_OPEN_DIR || mode==MODE_OPEN_ANY)
file->set_text("");
call_deferred("_update_file_list");
call_deferred("_update_dir");
} else {
-
+
_action_pressed();
}
}
void FileDialog::update_file_list() {
-
+
tree->clear();
dir_access->list_dir_begin();
-
+
TreeItem *root = tree->create_item();
Ref<Texture> folder = get_icon("folder");
List<String> files;
List<String> dirs;
-
+
bool isdir;
bool ishidden;
bool show_hidden = show_hidden_files;
@@ -340,12 +338,12 @@ void FileDialog::update_file_list() {
dirs.push_back(item);
}
}
-
+
dirs.sort_custom<NoCaseComparator>();
files.sort_custom<NoCaseComparator>();
-
+
while(!dirs.empty()) {
-
+
if (dirs.front()->get()!=".") {
TreeItem *ti=tree->create_item(root);
ti->set_text(0,dirs.front()->get()+"/");
@@ -356,23 +354,23 @@ void FileDialog::update_file_list() {
ti->set_metadata(0,d);
}
dirs.pop_front();
-
+
}
-
+
dirs.clear();
-
+
List<String> patterns;
// build filter
if (filter->get_selected()==filter->get_item_count()-1) {
-
- // match all
+
+ // match all
} else if (filters.size()>1 && filter->get_selected()==0) {
// match all filters
for (int i=0;i<filters.size();i++) {
-
+
String f=filters[i].get_slice(";",0);
for (int j=0;j<f.get_slice_count(",");j++) {
-
+
patterns.push_back(f.get_slice(",",j).strip_edges());
}
}
@@ -380,34 +378,34 @@ void FileDialog::update_file_list() {
int idx=filter->get_selected();
if (filters.size()>1)
idx--;
-
+
if (idx>=0 && idx<filters.size()) {
-
+
String f=filters[idx].get_slice(";",0);
for (int j=0;j<f.get_slice_count(",");j++) {
-
+
patterns.push_back(f.get_slice(",",j).strip_edges());
- }
+ }
}
}
String base_dir = dir_access->get_current_dir();
-
-
+
+
while(!files.empty()) {
-
+
bool match=patterns.empty();
-
+
for(List<String>::Element *E=patterns.front();E;E=E->next()) {
-
+
if (files.front()->get().matchn(E->get())) {
-
+
match=true;
break;
}
}
-
+
if (match) {
TreeItem *ti=tree->create_item(root);
ti->set_text(0,files.front()->get());
@@ -426,35 +424,35 @@ void FileDialog::update_file_list() {
d["name"]=files.front()->get();
d["dir"]=false;
ti->set_metadata(0,d);
-
+
if (file->get_text()==files.front()->get())
ti->select(0);
}
-
+
files.pop_front();
}
-
+
if (tree->get_root() && tree->get_root()->get_children())
tree->get_root()->get_children()->select(0);
-
+
files.clear();
-
+
}
void FileDialog::_filter_selected(int) {
-
+
update_file_list();
}
void FileDialog::update_filters() {
-
+
filter->clear();
-
+
if (filters.size()>1) {
String all_filters;
const int max_filters=5;
-
+
for(int i=0;i<MIN( max_filters, filters.size()) ;i++) {
String flt=filters[i].get_slice(";",0);
if (i>0)
@@ -464,11 +462,11 @@ void FileDialog::update_filters() {
if (max_filters<filters.size())
all_filters+=", ...";
-
+
filter->add_item("All Recognized ( "+all_filters+" )");
}
for(int i=0;i<filters.size();i++) {
-
+
String flt=filters[i].get_slice(";",0).strip_edges();
String desc=filters[i].get_slice(";",1).strip_edges();
if (desc.length())
@@ -476,46 +474,46 @@ void FileDialog::update_filters() {
else
filter->add_item("( "+flt+" )");
}
-
+
filter->add_item("All Files (*)");
-
+
}
void FileDialog::clear_filters() {
-
+
filters.clear();
update_filters();
invalidate();
}
void FileDialog::add_filter(const String& p_filter) {
-
+
filters.push_back(p_filter);
update_filters();
invalidate();
-
+
}
String FileDialog::get_current_dir() const {
-
- return dir->get_text();
+
+ return dir->get_text();
}
String FileDialog::get_current_file() const {
-
+
return file->get_text();
}
String FileDialog::get_current_path() const {
-
+
return dir->get_text().plus_file(file->get_text());
}
void FileDialog::set_current_dir(const String& p_dir) {
-
+
dir_access->change_dir(p_dir);
update_dir();
invalidate();
-
+
}
void FileDialog::set_current_file(const String& p_file) {
-
+
file->set_text(p_file);
update_dir();
invalidate();
@@ -525,18 +523,18 @@ void FileDialog::set_current_file(const String& p_file) {
file->grab_focus();
}
-
+
}
void FileDialog::set_current_path(const String& p_path) {
-
+
if (!p_path.size())
return;
int pos=MAX( p_path.find_last("/"), p_path.find_last("\\") );
if (pos==-1) {
-
+
set_current_file(p_path);
} else {
-
+
String dir=p_path.substr(0,pos);
String file=p_path.substr(pos+1,p_path.length());
set_current_dir(dir);
@@ -546,14 +544,15 @@ void FileDialog::set_current_path(const String& p_path) {
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_SAVE_FILE: get_ok()->set_text("Save"); set_title("Save a File"); makedir->show(); 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;
}
if (mode==MODE_OPEN_FILES) {
@@ -565,7 +564,7 @@ void FileDialog::set_mode(Mode p_mode) {
}
FileDialog::Mode FileDialog::get_mode() const {
-
+
return mode;
}
@@ -655,7 +654,7 @@ void FileDialog::_update_drives() {
drives->show();
for(int i=0;i<dir_access->get_drive_count();i++) {
- String d = dir_access->get_drive(i);
+ String d = dir_access->get_drive(i);
drives->add_item(dir_access->get_drive(i));
}
@@ -668,7 +667,7 @@ bool FileDialog::default_show_hidden_files=false;
void FileDialog::_bind_methods() {
-
+
ObjectTypeDB::bind_method(_MD("_unhandled_input"),&FileDialog::_unhandled_input);
ObjectTypeDB::bind_method(_MD("_tree_selected"),&FileDialog::_tree_selected);
@@ -679,7 +678,7 @@ void FileDialog::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_cancel_pressed"),&FileDialog::_cancel_pressed);
ObjectTypeDB::bind_method(_MD("_filter_selected"),&FileDialog::_filter_selected);
ObjectTypeDB::bind_method(_MD("_save_confirm_pressed"),&FileDialog::_save_confirm_pressed);
-
+
ObjectTypeDB::bind_method(_MD("clear_filters"),&FileDialog::clear_filters);
ObjectTypeDB::bind_method(_MD("add_filter","filter"),&FileDialog::add_filter);
ObjectTypeDB::bind_method(_MD("get_current_dir"),&FileDialog::get_current_dir);
@@ -710,6 +709,8 @@ void FileDialog::_bind_methods() {
BIND_CONSTANT( MODE_OPEN_FILE );
BIND_CONSTANT( MODE_OPEN_FILES );
BIND_CONSTANT( MODE_OPEN_DIR );
+ BIND_CONSTANT( MODE_OPEN_ANY );
+
BIND_CONSTANT( MODE_SAVE_FILE );
BIND_CONSTANT( ACCESS_RESOURCES );
@@ -742,7 +743,7 @@ FileDialog::FileDialog() {
mode=MODE_SAVE_FILE;
set_title("Save a File");
-
+
dir = memnew(LineEdit);
HBoxContainer *pathhb = memnew( HBoxContainer );
pathhb->add_child(dir);
@@ -760,17 +761,17 @@ FileDialog::FileDialog() {
makedir->set_text("Create Folder");
makedir->connect("pressed",this,"_make_dir");
pathhb->add_child(makedir);
-
+
vbc->add_margin_child("Path:",pathhb);
-
+
tree = memnew(Tree);
tree->set_hide_root(true);
vbc->add_margin_child("Directories & Files:",tree,true);
-
+
file = memnew(LineEdit);
//add_child(file);
vbc->add_margin_child("File:",file);
-
+
filter = memnew( OptionButton );
//add_child(filter);
@@ -781,7 +782,7 @@ FileDialog::FileDialog() {
access=ACCESS_RESOURCES;
_update_drives();
-
+
connect("confirmed", this,"_action_pressed");
//cancel->connect("pressed", this,"_cancel_pressed");
tree->connect("cell_selected", this,"_tree_selected",varray(),CONNECT_DEFERRED);
@@ -790,12 +791,12 @@ FileDialog::FileDialog() {
file->connect("text_entered", this,"_file_entered");
filter->connect("item_selected", this,"_filter_selected");
-
+
confirm_save = memnew( ConfirmationDialog );
confirm_save->set_as_toplevel(true);
add_child(confirm_save);
-
+
confirm_save->connect("confirmed", this,"_save_confirm_pressed");
makedialog = memnew( ConfirmationDialog );
@@ -828,12 +829,12 @@ FileDialog::FileDialog() {
invalidated=true;
if (register_func)
register_func(this);
-
+
}
FileDialog::~FileDialog() {
-
+
if (unregister_func)
unregister_func(this);
memdelete(dir_access);
@@ -877,3 +878,4 @@ LineEditFileChooser::LineEditFileChooser() {
dialog->connect("files_selected",this,"_chosen");
}
+
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index b71a157fa7..1fcf8387ce 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -41,9 +41,9 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class FileDialog : public ConfirmationDialog {
-
+
OBJ_TYPE( FileDialog, ConfirmationDialog );
-
+
public:
enum Access {
@@ -57,7 +57,8 @@ public:
MODE_OPEN_FILE,
MODE_OPEN_FILES,
MODE_OPEN_DIR,
- MODE_SAVE_FILE,
+ MODE_OPEN_ANY,
+ MODE_SAVE_FILE
};
typedef Ref<Texture> (*GetIconFunc)(const String&);
@@ -89,7 +90,7 @@ private:
ConfirmationDialog *confirm_save;
ToolButton *refresh;
-
+
Vector<String> filters;
@@ -97,13 +98,13 @@ private:
bool show_hidden_files;
bool invalidated;
-
+
void update_dir();
void update_file_list();
void update_filters();
-
+
void _tree_selected();
-
+
void _select_drive(int p_idx);
void _tree_dc_selected();
void _dir_entered(String p_dir);
@@ -122,18 +123,18 @@ private:
virtual void _post_popup();
protected:
-
+
void _notification(int p_what);
static void _bind_methods();
//bind helpers
public:
-
+
void clear_filters();
void add_filter(const String& p_filter);
void set_enable_multiple_selection(bool p_enable);
Vector<String> get_selected_files() const;
-
+
String get_current_dir() const;
String get_current_file() const;
String get_current_path() const;
@@ -156,8 +157,8 @@ public:
static void set_default_show_hidden_files(bool p_show);
void invalidate();
-
- FileDialog();
+
+ FileDialog();
~FileDialog();
};
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index c9c9dbd1d2..9123194589 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -617,7 +617,7 @@ void GraphEdit::_input_event(const InputEvent& p_ev) {
if (b.button_index==BUTTON_LEFT && b.pressed) {
- GraphNode *gn;
+ GraphNode *gn = NULL;
for(int i=get_child_count()-1;i>=0;i--) {
gn=get_child(i)->cast_to<GraphNode>();
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index a189c10046..8a7721b9b5 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -118,7 +118,7 @@ public:
void set_right_disconnects(bool p_enable);
bool is_right_disconnects_enabled() const;
-
+
Vector2 get_scroll_ofs() const;
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 2d2cabfc01..171dd94bfa 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -7,6 +7,7 @@ void ItemList::add_item(const String& p_item,const Ref<Texture>& p_texture,bool
Item item;
item.icon=p_texture;
+ item.icon_region=Rect2i();
item.text=p_item;
item.selectable=p_selectable;
item.selected=false;
@@ -23,6 +24,7 @@ void ItemList::add_icon_item(const Ref<Texture>& p_item,bool p_selectable){
Item item;
item.icon=p_item;
+ item.icon_region=Rect2i();
//item.text=p_item;
item.selectable=p_selectable;
item.selected=false;
@@ -79,6 +81,7 @@ void ItemList::set_item_icon(int p_idx,const Ref<Texture>& p_icon){
}
+
Ref<Texture> ItemList::get_item_icon(int p_idx) const{
ERR_FAIL_INDEX_V(p_idx,items.size(),Ref<Texture>());
@@ -87,6 +90,22 @@ Ref<Texture> ItemList::get_item_icon(int p_idx) const{
}
+void ItemList::set_item_icon_region(int p_idx,const Rect2& p_region) {
+
+ ERR_FAIL_INDEX(p_idx,items.size());
+
+ items[p_idx].icon_region=p_region;
+ update();
+ shape_changed=true;
+}
+
+Rect2 ItemList::get_item_icon_region(int p_idx) const {
+
+ ERR_FAIL_INDEX_V(p_idx,items.size(),Rect2());
+
+ return items[p_idx].icon_region;
+}
+
void ItemList::set_item_custom_bg_color(int p_idx,const Color& p_custom_bg_color) {
ERR_FAIL_INDEX(p_idx,items.size());
@@ -362,7 +381,15 @@ Size2 ItemList::get_min_icon_size() const {
return min_icon_size;
}
+Size2 ItemList::Item::get_icon_size() const {
+ if (icon.is_null())
+ return Size2();
+ if (icon_region.has_no_area())
+ return icon->get_size();
+
+ return icon_region.size;
+}
void ItemList::_input_event(const InputEvent& p_event) {
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_LEFT && p_event.mouse_button.pressed) {
@@ -702,7 +729,9 @@ void ItemList::_notification(int p_what) {
Size2 minsize;
if (items[i].icon.is_valid()) {
- minsize=items[i].icon->get_size();
+
+ minsize=items[i].get_icon_size();
+
if (min_icon_size.x!=0)
minsize.x = MAX(minsize.x,min_icon_size.x);
if (min_icon_size.y!=0)
@@ -851,18 +880,30 @@ void ItemList::_notification(int p_what) {
Vector2 text_ofs;
if (items[i].icon.is_valid()) {
+ Size2 icon_size = items[i].get_icon_size();
+
Vector2 icon_ofs;
if (min_icon_size!=Vector2()) {
- icon_ofs = (min_icon_size - items[i].icon->get_size())/2;
+ icon_ofs = (min_icon_size - icon_size)/2;
}
+ Point2 pos = items[i].rect_cache.pos + icon_ofs + base_ofs;
+
if (icon_mode==ICON_MODE_TOP) {
- draw_texture(items[i].icon,icon_ofs+items[i].rect_cache.pos+Vector2(items[i].rect_cache.size.width/2-items[i].icon->get_width()/2,0).floor()+base_ofs);
- text_ofs.y = MAX(items[i].icon->get_height(),min_icon_size.y)+icon_margin;
+
+ 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;
} else {
- draw_texture(items[i].icon,icon_ofs+items[i].rect_cache.pos+Vector2(0,items[i].rect_cache.size.height/2-items[i].icon->get_height()/2).floor()+base_ofs);
- text_ofs.x = MAX(items[i].icon->get_width(),min_icon_size.x)+icon_margin;
+
+ 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;
}
+
+ if (items[i].icon_region.has_no_area())
+ draw_texture(items[i].icon, pos);
+ else
+ draw_texture_rect_region(items[i].icon, Rect2(pos, icon_size), items[i].icon_region);
+
}
if (items[i].tag_icon.is_valid()) {
@@ -1061,6 +1102,9 @@ void ItemList::_bind_methods(){
ObjectTypeDB::bind_method(_MD("set_item_icon","idx","icon:Texture"),&ItemList::set_item_icon);
ObjectTypeDB::bind_method(_MD("get_item_icon:Texture","idx"),&ItemList::get_item_icon);
+ ObjectTypeDB::bind_method(_MD("set_item_icon_region","idx","rect"),&ItemList::set_item_icon_region);
+ ObjectTypeDB::bind_method(_MD("get_item_icon_region","idx"),&ItemList::get_item_icon_region);
+
ObjectTypeDB::bind_method(_MD("set_item_selectable","idx","selectable"),&ItemList::set_item_selectable);
ObjectTypeDB::bind_method(_MD("is_item_selectable","idx"),&ItemList::is_item_selectable);
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index bd3cf6484e..c9c575fd54 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -22,6 +22,7 @@ private:
struct Item {
Ref<Texture> icon;
+ Rect2i icon_region;
Ref<Texture> tag_icon;
String text;
bool selectable;
@@ -31,9 +32,10 @@ private:
String tooltip;
Color custom_bg;
-
Rect2 rect_cache;
+ Size2 get_icon_size() const;
+
bool operator<(const Item& p_another) const { return text<p_another.text; }
};
@@ -76,6 +78,9 @@ public:
void set_item_icon(int p_idx,const Ref<Texture>& p_icon);
Ref<Texture> get_item_icon(int p_idx) const;
+ void set_item_icon_region(int p_idx,const Rect2& p_region);
+ Rect2 get_item_icon_region(int p_idx) const;
+
void set_item_selectable(int p_idx,bool p_selectable);
bool is_item_selectable(int p_idx) const;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 2a62ab30fc..3953ef06a5 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -36,20 +36,20 @@ void LineEdit::_input_event(InputEvent p_event) {
switch(p_event.type) {
-
+
case InputEvent::MOUSE_BUTTON: {
-
+
const InputEventMouseButton &b = p_event.mouse_button;
if (b.button_index!=1)
break;
-
+
if (b.pressed) {
-
+
set_cursor_at_pixel_pos(b.x);
-
+
if (b.doubleclick) {
-
+
selection.enabled=true;
selection.begin=0;
selection.end=text.length();
@@ -57,9 +57,9 @@ void LineEdit::_input_event(InputEvent p_event) {
}
selection.drag_attempt=false;
-
+
if ((cursor_pos<selection.begin) || (cursor_pos>selection.end) || !selection.enabled) {
-
+
selection_clear();
selection.cursor_start=cursor_pos;
selection.creating=true;
@@ -67,13 +67,13 @@ void LineEdit::_input_event(InputEvent p_event) {
selection.drag_attempt=true;
}
-
+
// if (!editable)
// non_editable_clicked_signal.call();
update();
-
+
} else {
-
+
if ( (!selection.creating) && (!selection.doubleclick)) {
selection_clear();
}
@@ -83,29 +83,29 @@ void LineEdit::_input_event(InputEvent p_event) {
if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->show_virtual_keyboard(get_text(),get_global_rect());
}
-
- update();
+
+ update();
} break;
case InputEvent::MOUSE_MOTION: {
-
+
const InputEventMouseMotion& m=p_event.mouse_motion;
-
+
if (m.button_mask&1) {
-
+
if (selection.creating) {
set_cursor_at_pixel_pos(m.x);
selection_fill_at_cursor();
}
}
-
+
} break;
case InputEvent::KEY: {
-
+
const InputEventKey &k =p_event.key;
-
+
if (!k.pressed)
return;
- unsigned int code = k.scancode;
+ unsigned int code = k.scancode;
if (k.mod.command) {
@@ -346,11 +346,11 @@ void LineEdit::_input_event(InputEvent p_event) {
}
-
+
return;
-
+
} break;
-
+
}
}
@@ -405,30 +405,30 @@ void LineEdit::drop_data(const Point2& p_point,const Variant& p_data){
void LineEdit::_notification(int p_what) {
-
+
switch(p_what) {
-
+
case NOTIFICATION_RESIZED: {
-
+
set_cursor_pos( get_cursor_pos() );
-
+
} break;
case NOTIFICATION_DRAW: {
-
+
int width,height;
-
+
Size2 size=get_size();
width=size.width;
height=size.height;
-
+
RID ci = get_canvas_item();
-
+
Ref<StyleBox> style = get_stylebox("normal");
if (!is_editable())
style=get_stylebox("read_only");
Ref<Font> font=get_font("font");
-
+
style->draw( ci, Rect2( Point2(), size ) );
if (has_focus()) {
@@ -439,7 +439,7 @@ void LineEdit::_notification(int p_what) {
int x_ofs=0;
switch (align) {
-
+
case ALIGN_FILL:
case ALIGN_LEFT: {
@@ -457,19 +457,19 @@ void LineEdit::_notification(int p_what) {
int ofs_max=width-style->get_minimum_size().width;
int char_ofs=window_pos;
-
+
int y_area=height-style->get_minimum_size().height;
int y_ofs=style->get_offset().y;
-
+
int font_ascent=font->get_ascent();
-
+
Color selection_color=get_color("selection_color");
Color font_color=get_color("font_color");
Color font_color_selected=get_color("font_color_selected");
Color cursor_color=get_color("cursor_color");
-
+
while(true) {
-
+
//end of string, break!
if (char_ofs>=text.length())
break;
@@ -477,32 +477,32 @@ void LineEdit::_notification(int p_what) {
CharType cchar=pass?'*':text[char_ofs];
CharType next=pass?'*':text[char_ofs+1];
int char_width=font->get_char_size( cchar,next ).width;
-
+
// end of widget, break!
if ((x_ofs + char_width) > ofs_max)
break;
-
-
+
+
bool selected=selection.enabled && char_ofs>=selection.begin && char_ofs<selection.end;
-
+
if (selected)
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(char_width, y_area)), selection_color);
-
+
font->draw_char(ci, Point2(x_ofs, y_ofs + font_ascent), cchar, next, selected ? font_color_selected : font_color);
-
+
if (char_ofs==cursor_pos && has_focus())
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(
Point2( x_ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color );
-
+
x_ofs+=char_width;
char_ofs++;
}
if (char_ofs==cursor_pos && has_focus()) //may be at the end
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(
- Point2( x_ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color );
-
+ Point2( x_ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color );
+
} break;
case NOTIFICATION_FOCUS_ENTER: {
@@ -521,15 +521,15 @@ void LineEdit::_notification(int p_what) {
}
void LineEdit::copy_text() {
-
+
if(selection.enabled) {
-
+
OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin));
}
}
void LineEdit::cut_text() {
-
+
if(selection.enabled) {
undo_text = text;
OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin));
@@ -538,9 +538,9 @@ void LineEdit::cut_text() {
}
void LineEdit::paste_text() {
-
+
String paste_buffer = OS::get_singleton()->get_clipboard();
-
+
if(paste_buffer != "") {
if(selection.enabled) selection_delete();
@@ -550,28 +550,28 @@ void LineEdit::paste_text() {
_change_notify("text");
}
-
+
}
void LineEdit::shift_selection_check_pre(bool p_shift) {
-
+
if (!selection.old_shift && p_shift) {
selection.cursor_start=cursor_pos;
}
if (!p_shift)
selection_clear();
-
+
}
void LineEdit::shift_selection_check_post(bool p_shift) {
-
+
if (p_shift)
selection_fill_at_cursor();
}
void LineEdit::set_cursor_at_pixel_pos(int p_x) {
-
+
Ref<Font> font = get_font("font");
int ofs = window_pos;
Ref<StyleBox> style = get_stylebox("normal");
@@ -579,10 +579,10 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) {
Size2 size = get_size();
switch (align) {
-
+
case ALIGN_FILL:
case ALIGN_LEFT: {
-
+
pixel_ofs = int(style->get_offset().x);
} break;
case ALIGN_CENTER: {
@@ -597,30 +597,30 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) {
while (ofs<text.length()) {
-
+
int char_w = 0;
if (font != NULL) {
char_w = font->get_char_size(text[ofs]).width;
}
pixel_ofs+=char_w;
-
+
if (pixel_ofs > p_x) { //found what we look for
-
-
+
+
if ( (pixel_ofs-p_x) < (char_w >> 1 ) ) {
-
+
ofs+=1;
}
-
+
break;
}
-
-
+
+
ofs++;
}
-
+
set_cursor_pos( ofs );
-
+
/*
int new_cursor_pos=p_x;
int charwidth=draw_area->get_font_char_width(' ',0);
@@ -631,29 +631,29 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) {
void LineEdit::delete_char() {
-
+
if ((text.length()<=0) || (cursor_pos==0)) return;
-
+
Ref<Font> font = get_font("font");
if (font != NULL) {
cached_width -= font->get_char_size(text[cursor_pos - 1]).width;
}
-
+
text.erase( cursor_pos-1, 1 );
-
+
set_cursor_pos(get_cursor_pos()-1);
-
+
if (cursor_pos==window_pos) {
-
+
// set_window_pos(cursor_pos-get_window_length());
}
-
+
emit_signal("text_changed",text);
_change_notify("text");
}
void LineEdit::set_text(String p_text) {
-
+
clear_internal();
append_at_cursor(p_text);
update();
@@ -662,86 +662,86 @@ void LineEdit::set_text(String p_text) {
}
void LineEdit::clear() {
-
+
clear_internal();
}
String LineEdit::get_text() const {
-
+
return text;
}
void LineEdit::set_cursor_pos(int p_pos) {
-
+
if (p_pos>(int)text.length())
p_pos=text.length();
-
+
if(p_pos<0)
p_pos=0;
-
-
-
+
+
+
cursor_pos=p_pos;
-
+
// if (cursor_pos>(window_pos+get_window_length())) {
// set_window_pos(cursor_pos-get_window_lengt//h());
// }
-
+
if (!is_inside_tree()) {
-
+
window_pos=cursor_pos;
return;
}
-
+
Ref<StyleBox> style = get_stylebox("normal");
Ref<Font> font=get_font("font");
-
+
if (cursor_pos<window_pos) {
/* Adjust window if cursor goes too much to the left */
set_window_pos(cursor_pos);
} else if (cursor_pos>window_pos) {
/* Adjust window if cursor goes too much to the right */
int window_width=get_size().width-style->get_minimum_size().width;
-
+
if (window_width<0)
return;
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;
-
+
while (width_to_cursor >= window_width && wp < text.length()) {
width_to_cursor -= font->get_char_size(text[wp]).width;
wp++;
}
}
-
+
if (wp!=window_pos)
set_window_pos( wp );
-
+
}
update();
}
int LineEdit::get_cursor_pos() const {
-
+
return cursor_pos;
}
void LineEdit::set_window_pos(int p_pos) {
-
+
window_pos=p_pos;
if (window_pos<0) window_pos=0;
}
void LineEdit::append_at_cursor(String p_text) {
-
-
+
+
if ( ( max_length <= 0 ) || (text.length()+p_text.length() <= max_length)) {
-
+
undo_text = text;
Ref<Font> font = get_font("font");
@@ -761,7 +761,7 @@ void LineEdit::append_at_cursor(String p_text) {
}
void LineEdit::clear_internal() {
-
+
cached_width = 0;
cursor_pos=0;
window_pos=0;
@@ -771,21 +771,21 @@ void LineEdit::clear_internal() {
}
Size2 LineEdit::get_minimum_size() const {
-
+
Ref<StyleBox> style = get_stylebox("normal");
Ref<Font> font=get_font("font");
-
+
Size2 min=style->get_minimum_size();
min.height+=font->get_height();
min.width+=get_constant("minimum_spaces")*font->get_char_size(' ').x;
-
+
return min;
}
/* selection */
void LineEdit::selection_clear() {
-
+
selection.begin=0;
selection.end=0;
selection.cursor_start=0;
@@ -798,9 +798,9 @@ void LineEdit::selection_clear() {
void LineEdit::selection_delete() {
-
+
if (selection.enabled) {
-
+
undo_text = text;
if (text.size() > 0)
@@ -818,80 +818,80 @@ void LineEdit::selection_delete() {
text.erase(selection.begin,selection.end-selection.begin);
cursor_pos-=CLAMP( cursor_pos-selection.begin, 0, selection.end-selection.begin);
-
+
if (cursor_pos>=text.length()) {
-
+
cursor_pos=text.length();
}
if (window_pos>cursor_pos) {
-
+
window_pos=cursor_pos;
}
-
+
emit_signal("text_changed",text);
_change_notify("text");
};
-
+
selection_clear();
}
void LineEdit::set_max_length(int p_max_length) {
-
+
ERR_FAIL_COND(p_max_length<0);
max_length = p_max_length;
set_text(text);
}
int LineEdit::get_max_length() const {
-
+
return max_length;
}
void LineEdit::selection_fill_at_cursor() {
-
+
int aux;
-
+
selection.begin=cursor_pos;
selection.end=selection.cursor_start;
-
+
if (selection.end<selection.begin) {
aux=selection.end;
selection.end=selection.begin;
selection.begin=aux;
}
-
+
selection.enabled=(selection.begin!=selection.end);
}
void LineEdit::select_all() {
-
+
if (!text.length())
return;
-
+
selection.begin=0;
selection.end=text.length();
selection.enabled=true;
update();
-
+
}
void LineEdit::set_editable(bool p_editable) {
-
+
editable=p_editable;
update();
}
bool LineEdit::is_editable() const {
-
+
return editable;
}
void LineEdit::set_secret(bool p_secret) {
-
+
pass=p_secret;
update();
}
bool LineEdit::is_secret() const {
-
+
return pass;
}
@@ -928,24 +928,24 @@ bool LineEdit::is_text_field() const {
}
void LineEdit::_bind_methods() {
-
+
ObjectTypeDB::bind_method(_MD("set_align", "align"), &LineEdit::set_align);
ObjectTypeDB::bind_method(_MD("get_align"), &LineEdit::get_align);
ObjectTypeDB::bind_method(_MD("_input_event"),&LineEdit::_input_event);
- ObjectTypeDB::bind_method(_MD("clear"),&LineEdit::clear);
- ObjectTypeDB::bind_method(_MD("select_all"),&LineEdit::select_all);
+ ObjectTypeDB::bind_method(_MD("clear"),&LineEdit::clear);
+ ObjectTypeDB::bind_method(_MD("select_all"),&LineEdit::select_all);
ObjectTypeDB::bind_method(_MD("set_text","text"),&LineEdit::set_text);
- ObjectTypeDB::bind_method(_MD("get_text"),&LineEdit::get_text);
+ ObjectTypeDB::bind_method(_MD("get_text"),&LineEdit::get_text);
ObjectTypeDB::bind_method(_MD("set_cursor_pos","pos"),&LineEdit::set_cursor_pos);
- ObjectTypeDB::bind_method(_MD("get_cursor_pos"),&LineEdit::get_cursor_pos);
+ ObjectTypeDB::bind_method(_MD("get_cursor_pos"),&LineEdit::get_cursor_pos);
ObjectTypeDB::bind_method(_MD("set_max_length","chars"),&LineEdit::set_max_length);
- ObjectTypeDB::bind_method(_MD("get_max_length"),&LineEdit::get_max_length);
+ ObjectTypeDB::bind_method(_MD("get_max_length"),&LineEdit::get_max_length);
ObjectTypeDB::bind_method(_MD("append_at_cursor","text"),&LineEdit::append_at_cursor);
ObjectTypeDB::bind_method(_MD("set_editable","enabled"),&LineEdit::set_editable);
- ObjectTypeDB::bind_method(_MD("is_editable"),&LineEdit::is_editable);
+ ObjectTypeDB::bind_method(_MD("is_editable"),&LineEdit::is_editable);
ObjectTypeDB::bind_method(_MD("set_secret","enabled"),&LineEdit::set_secret);
- ObjectTypeDB::bind_method(_MD("is_secret"),&LineEdit::is_secret);
+ ObjectTypeDB::bind_method(_MD("is_secret"),&LineEdit::is_secret);
ObjectTypeDB::bind_method(_MD("select","from","to"),&LineEdit::select,DEFVAL(0),DEFVAL(-1));
ADD_SIGNAL( MethodInfo("text_changed", PropertyInfo( Variant::STRING, "text" )) );
@@ -964,25 +964,25 @@ void LineEdit::_bind_methods() {
}
LineEdit::LineEdit() {
-
+
align = ALIGN_LEFT;
cached_width = 0;
cursor_pos=0;
window_pos=0;
max_length = 0;
pass=false;
-
+
selection_clear();
set_focus_mode( FOCUS_ALL );
editable=true;
set_default_cursor_shape(CURSOR_IBEAM);
set_stop_mouse(true);
-
-
+
+
}
LineEdit::~LineEdit() {
-
-
+
+
}
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index bf6459361a..207c6b115b 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -34,7 +34,7 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class LineEdit : public Control {
-
+
OBJ_TYPE( LineEdit, Control );
public:
@@ -50,18 +50,18 @@ private:
bool editable;
bool pass;
-
+
String undo_text;
String text;
-
+
int cursor_pos;
int window_pos;
int max_length; // 0 for no maximum
int cached_width;
-
+
struct Selection {
-
+
int begin;
int end;
int cursor_start;
@@ -71,41 +71,41 @@ private:
bool doubleclick;
bool drag_attempt;
} selection;
-
+
void shift_selection_check_pre(bool);
void shift_selection_check_post(bool);
-
+
void selection_clear();
void selection_fill_at_cursor();
void selection_delete();
void set_window_pos(int p_pos);
-
+
void set_cursor_at_pixel_pos(int p_x);
-
+
void clear_internal();
void changed_internal();
-
+
void copy_text();
void cut_text();
void paste_text();
-
+
void _input_event(InputEvent p_event);
void _notification(int p_what);
-
-protected:
- static void _bind_methods();
+
+protected:
+ static void _bind_methods();
public:
void set_align(Align p_align);
Align get_align() const;
-
+
virtual Variant get_drag_data(const Point2& p_point);
virtual bool can_drop_data(const Point2& p_point,const Variant& p_data) const;
virtual void drop_data(const Point2& p_point,const Variant& p_data);
-
+
void select_all();
-
+
void delete_char();
void set_text(String p_text);
String get_text() const;
@@ -115,11 +115,11 @@ public:
int get_max_length() const;
void append_at_cursor(String p_text);
void clear();
-
-
+
+
void set_editable(bool p_editable);
bool is_editable() const;
-
+
void set_secret(bool p_secret);
bool is_secret() const;
@@ -130,7 +130,7 @@ public:
virtual bool is_text_field() const;
LineEdit();
~LineEdit();
-
+
};
diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp
new file mode 100644
index 0000000000..007d0a709e
--- /dev/null
+++ b/scene/gui/link_button.cpp
@@ -0,0 +1,124 @@
+#include "link_button.h"
+
+
+void LinkButton::set_text(const String& p_text) {
+
+ text=p_text;
+ update();
+ minimum_size_changed();
+}
+
+String LinkButton::get_text() const {
+ return text;
+}
+
+void LinkButton::set_underline_mode(UnderlineMode p_underline_mode) {
+
+ underline_mode=p_underline_mode;
+ update();
+}
+
+LinkButton::UnderlineMode LinkButton::get_underline_mode() const {
+
+ return underline_mode;
+}
+
+
+Size2 LinkButton::get_minimum_size() const {
+
+ return get_font("font")->get_string_size( text );
+}
+
+
+
+void LinkButton::_notification(int p_what) {
+
+ switch( p_what ) {
+
+ case NOTIFICATION_DRAW: {
+
+
+ RID ci = get_canvas_item();
+ Size2 size=get_size();
+ Color color;
+ bool do_underline=false;
+
+ //print_line(get_text()+": "+itos(is_flat())+" hover "+itos(get_draw_mode()));
+
+ switch( get_draw_mode() ) {
+
+ case DRAW_NORMAL: {
+
+ color=get_color("font_color");
+ do_underline=underline_mode==UNDERLINE_MODE_ALWAYS;
+ } break;
+ case DRAW_PRESSED: {
+
+ if (has_color("font_color_pressed"))
+ color=get_color("font_color_pressed");
+ else
+ color=get_color("font_color");
+
+ do_underline=true;
+
+ } break;
+ case DRAW_HOVER: {
+
+ color=get_color("font_color_hover");
+ do_underline=true;
+
+ } break;
+ case DRAW_DISABLED: {
+
+ color=get_color("font_color_disabled");
+ do_underline=underline_mode==UNDERLINE_MODE_ALWAYS;
+
+ } break;
+ }
+
+ if (has_focus()) {
+
+ Ref<StyleBox> style = get_stylebox("focus");
+ style->draw(ci,Rect2(Point2(),size));
+ }
+
+ Ref<Font> font=get_font("font");
+
+ draw_string(font,Vector2(0,font->get_ascent()),text,color);
+
+
+
+ if (do_underline) {
+ int underline_spacing = get_constant("underline_spacing");
+ int width = font->get_string_size(text).width;
+ int y = font->get_ascent()+underline_spacing;
+
+ draw_line(Vector2(0,y),Vector2(width,y),color);
+ }
+
+ } break;
+ }
+}
+
+void LinkButton::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_text","text"),&LinkButton::set_text);
+ ObjectTypeDB::bind_method(_MD("get_text"),&LinkButton::get_text);
+
+ ObjectTypeDB::bind_method(_MD("set_underline_mode","underline_mode"),&LinkButton::set_underline_mode);
+ ObjectTypeDB::bind_method(_MD("get_underline_mode"),&LinkButton::get_underline_mode);
+
+
+ BIND_CONSTANT( UNDERLINE_MODE_ALWAYS );
+ BIND_CONSTANT( UNDERLINE_MODE_ON_HOVER );
+
+ ADD_PROPERTYNZ(PropertyInfo(Variant::STRING,"text"), _SCS("set_text"), _SCS("get_text"));
+ ADD_PROPERTYNZ(PropertyInfo(Variant::INT,"underline",PROPERTY_HINT_ENUM,"Always,On Hover"), _SCS("set_underline_mode"), _SCS("get_underline_mode"));
+
+}
+
+LinkButton::LinkButton() {
+ underline_mode=UNDERLINE_MODE_ALWAYS;
+ set_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
new file mode 100644
index 0000000000..d218482337
--- /dev/null
+++ b/scene/gui/link_button.h
@@ -0,0 +1,40 @@
+#ifndef LINKBUTTON_H
+#define LINKBUTTON_H
+
+
+#include "scene/gui/base_button.h"
+#include "scene/resources/bit_mask.h"
+
+class LinkButton : public BaseButton {
+
+ OBJ_TYPE( LinkButton, BaseButton );
+public:
+
+ enum UnderlineMode {
+ UNDERLINE_MODE_ALWAYS,
+ UNDERLINE_MODE_ON_HOVER
+ };
+private:
+ String text;
+ UnderlineMode underline_mode;
+
+protected:
+
+ virtual Size2 get_minimum_size() const;
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+
+ void set_text(const String& p_text);
+ String get_text() const;
+
+ void set_underline_mode(UnderlineMode p_underline_mode);
+ UnderlineMode get_underline_mode() const;
+
+ LinkButton();
+};
+
+VARIANT_ENUM_CAST( LinkButton::UnderlineMode );
+
+#endif // LINKBUTTON_H
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index 26540843de..cb8806e2ef 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -76,18 +76,18 @@ void MenuButton::_unhandled_key_input(InputEvent p_event) {
void MenuButton::pressed() {
-
+
emit_signal("about_to_show");
Size2 size=get_size();
Point2 gp = get_global_pos();
popup->set_global_pos( gp + Size2( 0, size.height ) );
- popup->set_size( Size2( size.width, 0) );
+ popup->set_size( Size2( size.width, 0) );
popup->set_parent_rect( Rect2(Point2(gp-popup->get_global_pos()),get_size()));
popup->popup();
popup->call_deferred("grab_click_focus");
popup->set_invalidate_click_until_motion();
-
+
}
void MenuButton::_input_event(InputEvent p_event) {
@@ -111,7 +111,7 @@ void MenuButton::_input_event(InputEvent p_event) {
}
PopupMenu *MenuButton::get_popup() {
-
+
return popup;
}
@@ -136,7 +136,7 @@ void MenuButton::_bind_methods() {
ADD_SIGNAL( MethodInfo("about_to_show") );
}
MenuButton::MenuButton() {
-
+
set_flat(true);
set_focus_mode(FOCUS_NONE);
diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h
index 2df632811f..650e4aba5c 100644
--- a/scene/gui/menu_button.h
+++ b/scene/gui/menu_button.h
@@ -35,24 +35,24 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class MenuButton : public Button {
-
+
OBJ_TYPE( MenuButton, Button );
bool clicked;
PopupMenu *popup;
- virtual void pressed();
+ virtual void pressed();
void _unhandled_key_input(InputEvent p_event);
Array _get_items() const;
void _set_items(const Array& p_items);
void _input_event(InputEvent p_event);
-protected:
-
+protected:
+
- static void _bind_methods();
+ static void _bind_methods();
public:
-
+
PopupMenu *get_popup();
MenuButton();
~MenuButton();
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 5c8e5a7381..587a68ae37 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -55,7 +55,7 @@ void OptionButton::_notification(int p_what) {
Ref<Texture> arrow = Control::get_icon("arrow");
Ref<StyleBox> normal = get_stylebox("normal" );
- Size2 size = get_size();
+ Size2 size = get_size();
Point2 ofs( size.width - arrow->get_width() - get_constant("arrow_margin"), int(Math::abs((size.height-arrow->get_height())/2)));
arrow->draw(ci,ofs);
@@ -66,7 +66,7 @@ void OptionButton::_notification(int p_what) {
void OptionButton::_selected(int p_which) {
-
+
int selid = -1;
for (int i=0;i<popup->get_item_count();i++) {
@@ -89,39 +89,39 @@ void OptionButton::_selected(int p_which) {
void OptionButton::pressed() {
-
+
Size2 size=get_size();
popup->set_global_pos( get_global_pos() + Size2( 0, size.height ) );
popup->set_size( Size2( size.width, 0) );
-
+
popup->popup();
}
void OptionButton::add_icon_item(const Ref<Texture>& p_icon,const String& p_label,int p_ID) {
-
- popup->add_icon_check_item( p_icon, p_label, p_ID );
+
+ popup->add_icon_check_item( p_icon, p_label, p_ID );
if (popup->get_item_count()==1)
select(0);
}
void OptionButton::add_item(const String& p_label,int p_ID) {
-
- popup->add_check_item( p_label, p_ID );
+
+ popup->add_check_item( p_label, p_ID );
if (popup->get_item_count()==1)
- select(0);
+ select(0);
}
void OptionButton::set_item_text(int p_idx,const String& p_text) {
-
+
popup->set_item_text(p_idx,p_text);
-
+
}
void OptionButton::set_item_icon(int p_idx,const Ref<Texture>& p_icon) {
-
+
popup->set_item_icon(p_idx,p_icon);
-
+
}
void OptionButton::set_item_ID(int p_idx,int p_ID) {
-
+
popup->set_item_ID(p_idx,p_ID);
}
@@ -136,17 +136,17 @@ void OptionButton::set_item_disabled(int p_idx,bool p_disabled) {
}
String OptionButton::get_item_text(int p_idx) const {
-
+
return popup->get_item_text(p_idx);
}
Ref<Texture> OptionButton::get_item_icon(int p_idx) const {
-
+
return popup->get_item_icon(p_idx);
}
int OptionButton::get_item_ID(int p_idx) const {
-
+
return popup->get_item_ID(p_idx);
}
Variant OptionButton::get_item_metadata(int p_idx) const {
@@ -161,17 +161,17 @@ bool OptionButton::is_item_disabled(int p_idx) const {
int OptionButton::get_item_count() const {
-
+
return popup->get_item_count();
}
void OptionButton::add_separator() {
-
+
popup->add_separator();
}
void OptionButton::clear() {
-
+
popup->clear();
set_text("");
current=-1;
@@ -210,12 +210,12 @@ void OptionButton::_select_int(int p_which) {
}
void OptionButton::select(int p_idx) {
-
+
_select(p_idx,false);
}
int OptionButton::get_selected() const {
-
+
return current;
}
@@ -286,9 +286,9 @@ void OptionButton::get_translatable_strings(List<String> *p_strings) const {
void OptionButton::_bind_methods() {
-
+
ObjectTypeDB::bind_method(_MD("_selected"),&OptionButton::_selected);
-
+
ObjectTypeDB::bind_method(_MD("add_item","label","id"),&OptionButton::add_item,DEFVAL(-1));
ObjectTypeDB::bind_method(_MD("add_icon_item","texture:Texture","label","id"),&OptionButton::add_icon_item);
ObjectTypeDB::bind_method(_MD("set_item_text","idx","text"),&OptionButton::set_item_text);
@@ -305,7 +305,7 @@ void OptionButton::_bind_methods() {
ObjectTypeDB::bind_method(_MD("add_separator"),&OptionButton::add_separator);
ObjectTypeDB::bind_method(_MD("clear"),&OptionButton::clear);
ObjectTypeDB::bind_method(_MD("select","idx"),&OptionButton::select);
- ObjectTypeDB::bind_method(_MD("get_selected"),&OptionButton::get_selected);
+ ObjectTypeDB::bind_method(_MD("get_selected"),&OptionButton::get_selected);
ObjectTypeDB::bind_method(_MD("get_selected_ID"),&OptionButton::get_selected_ID);
ObjectTypeDB::bind_method(_MD("get_selected_metadata"),&OptionButton::get_selected_metadata);
ObjectTypeDB::bind_method(_MD("remove_item","idx"),&OptionButton::remove_item);
@@ -320,23 +320,23 @@ void OptionButton::_bind_methods() {
}
OptionButton::OptionButton() {
-
-
+
+
popup = memnew( PopupMenu );
popup->hide();
popup->set_as_toplevel(true);
add_child(popup);
popup->connect("item_pressed", this,"_selected");
-
+
current=-1;
set_text_align(ALIGN_LEFT);
}
OptionButton::~OptionButton() {
-
-
+
+
}
diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h
index 34e2bdd384..70ebc66a46 100644
--- a/scene/gui/option_button.h
+++ b/scene/gui/option_button.h
@@ -35,12 +35,12 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class OptionButton : public Button {
-
+
OBJ_TYPE( OptionButton, Button );
-
+
PopupMenu *popup;
int current;
-
+
void _selected(int p_which);
void _select(int p_which,bool p_emit=false);
void _select_int(int p_which);
@@ -55,10 +55,10 @@ protected:
void _notification(int p_what);
static void _bind_methods();
public:
-
+
void add_icon_item(const Ref<Texture>& p_icon,const String& p_label,int p_ID=-1);
void add_item(const String& p_label,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_ID(int p_idx,int p_ID);
@@ -73,11 +73,11 @@ public:
int get_item_count() const;
-
+
void add_separator();
-
+
void clear();
-
+
void select(int p_idx);
int get_selected() const;
int get_selected_ID() const;
@@ -87,7 +87,7 @@ public:
virtual void get_translatable_strings(List<String> *p_strings) const;
- OptionButton();
+ OptionButton();
~OptionButton();
};
diff --git a/scene/gui/panel.cpp b/scene/gui/panel.cpp
index d40daa972c..682ea5b92c 100644
--- a/scene/gui/panel.cpp
+++ b/scene/gui/panel.cpp
@@ -30,7 +30,7 @@
#include "print_string.h"
void Panel::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_DRAW) {
RID ci = get_canvas_item();
@@ -40,7 +40,7 @@ void Panel::_notification(int p_what) {
}
Panel::Panel() {
-
+
set_stop_mouse(true);
}
diff --git a/scene/gui/panel.h b/scene/gui/panel.h
index ee4bcd139e..efa9ebcaa0 100644
--- a/scene/gui/panel.h
+++ b/scene/gui/panel.h
@@ -34,13 +34,13 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class Panel : public Control{
-
+
OBJ_TYPE(Panel,Control);
protected:
void _notification(int p_what);
public:
- Panel();
+ Panel();
~Panel();
};
diff --git a/scene/gui/panel_container.cpp b/scene/gui/panel_container.cpp
index bcf75b79f8..b5e3ef8c7b 100644
--- a/scene/gui/panel_container.cpp
+++ b/scene/gui/panel_container.cpp
@@ -31,7 +31,12 @@
Size2 PanelContainer::get_minimum_size() const {
- Ref<StyleBox> style=get_stylebox("panel");
+ Ref<StyleBox> style;
+
+ if (has_stylebox("panel"))
+ style=get_stylebox("panel");
+ else
+ style=get_stylebox("panel","PanelContainer");
Size2 ms;
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 1f04985ec6..0d9a76937c 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -32,12 +32,12 @@
void Popup::_input_event(InputEvent p_event) {
-
+
}
void Popup::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_VISIBILITY_CHANGED) {
if (popped_up && !is_visible()) {
popped_up=false;
@@ -58,11 +58,11 @@ void Popup::_notification(int p_what) {
}
void Popup::_fix_size() {
-
+
#if 0
Point2 pos = get_pos();
- Size2 size = get_size();
+ Size2 size = get_size();
Point2 window_size = window==this ? get_parent_area_size() :window->get_size();
#else
@@ -75,7 +75,7 @@ void Popup::_fix_size() {
pos.x=window_size.width-size.width;
if (pos.x<0)
pos.x=0;
-
+
if (pos.y+size.height > window_size.height)
pos.y=window_size.height-size.height;
if (pos.y<0)
@@ -179,7 +179,7 @@ void Popup::popup_centered_minsize(const Size2& p_minsize) {
}
void Popup::popup_centered(const Size2& p_size) {
-
+
Point2 window_size = get_viewport_rect().size;
emit_signal("about_to_show");
@@ -203,9 +203,9 @@ void Popup::popup_centered(const Size2& p_size) {
}
void Popup::popup_centered_ratio(float p_screen_ratio) {
-
-
-
+
+
+
emit_signal("about_to_show");
Rect2 rect;
@@ -214,7 +214,7 @@ void Popup::popup_centered_ratio(float p_screen_ratio) {
rect.pos = ((window_size-rect.size)/2.0).floor();
set_pos( rect.pos );
set_size( rect.size );
-
+
show_modal(exclusive);
_fix_size();
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index 9c66e6d7bd..8afcdc01db 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -35,12 +35,12 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class Popup : public Control {
-
+
OBJ_TYPE( Popup, Control );
bool exclusive;
bool popped_up;
-
+
protected:
virtual void _post_popup() {}
@@ -48,14 +48,14 @@ protected:
void _input_event(InputEvent p_event);
void _notification(int p_what);
void _fix_size();
- static void _bind_methods();
+ static void _bind_methods();
public:
enum {
NOTIFICATION_POST_POPUP=80,
NOTIFICATION_POPUP_HIDE=81
};
-
+
void set_exclusive(bool p_exclusive);
bool is_exclusive() const;
@@ -65,8 +65,8 @@ public:
void set_as_minsize();
virtual void popup();
-
- Popup();
+
+ Popup();
~Popup();
};
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index a93d8e524f..3329d24890 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -59,34 +59,34 @@ Size2 PopupMenu::get_minimum_size() const {
int vseparation = get_constant("vseparation");
int hseparation = get_constant("hseparation");
-
+
Size2 minsize = get_stylebox("panel")->get_minimum_size();
Ref<Font> font = get_font("font");
-
+
float max_w=0;
int font_h = font->get_height();
int check_w = get_icon("checked")->get_width();
int accel_max_w=0;
-
+
for (int i=0;i<items.size();i++) {
-
+
Size2 size;
if (!items[i].icon.is_null()) {
-
+
Size2 icon_size = items[i].icon->get_size();
size.height = MAX( icon_size.height, font_h );
size.width+=icon_size.width;
size.width+=hseparation;
} else {
-
+
size.height=font_h;
}
-
+
if (items[i].checkable) {
-
+
size.width+=check_w+hseparation;
}
-
+
size.width+=font->get_string_size(items[i].text).width;
if (i>0)
size.height+=vseparation;
@@ -100,11 +100,11 @@ Size2 PopupMenu::get_minimum_size() const {
minsize.height+=size.height;
max_w = MAX( max_w, size.width );
-
+
}
-
+
minsize.width+=max_w+accel_max_w;
-
+
return minsize;
}
@@ -115,41 +115,41 @@ int PopupMenu::_get_mouse_over(const Point2& p_over) const {
return -1;
Ref<StyleBox> style = get_stylebox("panel");
-
+
Point2 ofs=style->get_offset();
-
+
if (ofs.y>p_over.y)
return -1;
-
-
- Ref<Font> font = get_font("font");
+
+
+ Ref<Font> font = get_font("font");
int vseparation = get_constant("vseparation");
// int hseparation = get_constant("hseparation");
float font_h=font->get_height();
-
+
for (int i=0;i<items.size();i++) {
-
+
if (i>0)
ofs.y+=vseparation;
float h;
-
+
if (!items[i].icon.is_null()) {
-
+
Size2 icon_size = items[i].icon->get_size();
h = MAX( icon_size.height, font_h );
} else {
-
+
h=font_h;
}
-
+
ofs.y+=h;
if (p_over.y < ofs.y) {
return i;
- }
+ }
}
-
+
return -1;
}
@@ -271,11 +271,11 @@ void PopupMenu::_input_event(const InputEvent &p_event) {
} break;
case InputEvent::MOUSE_BUTTON: {
-
-
+
+
const InputEventMouseButton &b=p_event.mouse_button;
if (b.pressed)
- break;
+ break;
switch(b.button_index) {
@@ -347,11 +347,11 @@ void PopupMenu::_input_event(const InputEvent &p_event) {
} break;
}
-
+
//update();
} break;
case InputEvent::MOUSE_MOTION: {
-
+
if (invalidated_click) {
moved+=Vector2(p_event.mouse_motion.relative_x,p_event.mouse_motion.relative_y);
@@ -409,13 +409,13 @@ bool PopupMenu::has_point(const Point2& p_point) const {
void PopupMenu::_notification(int p_what) {
switch(p_what) {
-
+
case NOTIFICATION_DRAW: {
-
+
RID ci = get_canvas_item();
Size2 size=get_size();
-
+
Ref<StyleBox> style = get_stylebox("panel");
Ref<StyleBox> hover = get_stylebox("hover");
Ref<Font> font = get_font("font");
@@ -423,7 +423,7 @@ void PopupMenu::_notification(int p_what) {
Ref<Texture> uncheck = get_icon("unchecked");
Ref<Texture> submenu= get_icon("submenu");
Ref<StyleBox> separator = get_stylebox("separator");
-
+
style->draw( ci, Rect2( Point2(), get_size() ) );
Point2 ofs=style->get_offset();
int vseparation = get_constant("vseparation");
@@ -433,36 +433,36 @@ void PopupMenu::_notification(int p_what) {
Color font_color_accel = get_color("font_color_accel");
Color font_color_hover = get_color("font_color_hover");
float font_h=font->get_height();
-
+
for (int i=0;i<items.size();i++) {
-
+
if (i>0)
ofs.y+=vseparation;
Point2 item_ofs=ofs;
float h;
Size2 icon_size;
-
+
if (!items[i].icon.is_null()) {
-
+
icon_size = items[i].icon->get_size();
h = MAX( icon_size.height, font_h );
} else {
-
+
h=font_h;
}
-
+
if (i==mouse_over) {
-
+
hover->draw(ci, Rect2( ofs+Point2(-hseparation,-vseparation), Size2( get_size().width - style->get_minimum_size().width + hseparation*2, h+vseparation*2 ) ));
}
-
+
if (items[i].separator) {
-
+
int sep_h=separator->get_center_size().height+separator->get_minimum_size().height;
separator->draw(ci, Rect2( ofs+Point2(0,Math::floor((h-sep_h)/2.0)), Size2( get_size().width - style->get_minimum_size().width , sep_h ) ));
-
+
}
-
+
if (items[i].checkable) {
if (items[i].checked)
@@ -499,16 +499,16 @@ void PopupMenu::_notification(int p_what) {
items[i]._ofs_cache=ofs.y;
ofs.y+=h;
-
+
}
-
+
} break;
case NOTIFICATION_MOUSE_ENTER: {
grab_focus();
} break;
case NOTIFICATION_MOUSE_EXIT: {
-
+
if (mouse_over>=0) {
mouse_over=-1;
update();
@@ -574,7 +574,7 @@ void PopupMenu::set_item_text(int p_idx,const String& p_text) {
ERR_FAIL_INDEX(p_idx,items.size());
items[p_idx].text=XL_MESSAGE(p_text);
-
+
update();
}
@@ -597,8 +597,8 @@ void PopupMenu::set_item_checked(int p_idx,bool p_checked) {
void PopupMenu::set_item_ID(int p_idx,int p_ID) {
ERR_FAIL_INDEX(p_idx,items.size());
- items[p_idx].ID=p_ID;
-
+ items[p_idx].ID=p_ID;
+
update();
}
@@ -785,7 +785,7 @@ void PopupMenu::add_separator() {
items.push_back(sep);
update();
}
-
+
void PopupMenu::clear() {
items.clear();
@@ -888,7 +888,7 @@ void PopupMenu::clear_autohide_areas(){
void PopupMenu::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("_input_event"),&PopupMenu::_input_event);
+ ObjectTypeDB::bind_method(_MD("_input_event"),&PopupMenu::_input_event);
ObjectTypeDB::bind_method(_MD("add_icon_item","texture","label","id","accel"),&PopupMenu::add_icon_item,DEFVAL(-1),DEFVAL(0));
ObjectTypeDB::bind_method(_MD("add_item","label","id","accel"),&PopupMenu::add_item,DEFVAL(-1),DEFVAL(0));
ObjectTypeDB::bind_method(_MD("add_icon_check_item","texture","label","id","accel"),&PopupMenu::add_icon_check_item,DEFVAL(-1),DEFVAL(0));
@@ -916,7 +916,7 @@ void PopupMenu::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_item_ID","idx"),&PopupMenu::get_item_ID);
ObjectTypeDB::bind_method(_MD("get_item_index","id"),&PopupMenu::get_item_index);
ObjectTypeDB::bind_method(_MD("get_item_count"),&PopupMenu::get_item_count);
- ObjectTypeDB::bind_method(_MD("add_separator"),&PopupMenu::add_separator);
+ ObjectTypeDB::bind_method(_MD("add_separator"),&PopupMenu::add_separator);
ObjectTypeDB::bind_method(_MD("remove_item","idx"),&PopupMenu::remove_item);
ObjectTypeDB::bind_method(_MD("clear"),&PopupMenu::clear);
@@ -930,7 +930,7 @@ void PopupMenu::_bind_methods() {
ADD_SIGNAL( MethodInfo("item_pressed", PropertyInfo( Variant::INT,"ID") ) );
}
-
+
void PopupMenu::set_invalidate_click_until_motion() {
moved=Vector2();
@@ -941,7 +941,7 @@ PopupMenu::PopupMenu() {
mouse_over=-1;
-
+
set_focus_mode(FOCUS_ALL);
set_as_toplevel(true);
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index 624f4f542a..72f8795067 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -37,7 +37,7 @@
class PopupMenu : public Popup {
OBJ_TYPE(PopupMenu, Popup );
-
+
struct Item {
Ref<Texture> icon;
String text;
@@ -45,16 +45,16 @@ class PopupMenu : public Popup {
bool checkable;
bool separator;
bool disabled;
- int ID;
+ int ID;
Variant metadata;
String submenu;
String tooltip;
uint32_t accel;
int _ofs_cache;
-
+
Item() { checked=false; checkable=false; separator=false; accel=0; disabled=false; _ofs_cache=0; }
};
-
+
Timer *submenu_timer;
List<Rect2> autohide_areas;
@@ -64,7 +64,7 @@ class PopupMenu : public Popup {
Rect2 parent_rect;
String _get_accel_text(uint32_t p_accel) const;
int _get_mouse_over(const Point2& p_over) const;
- virtual Size2 get_minimum_size() const;
+ virtual Size2 get_minimum_size() const;
void _input_event(const InputEvent &p_event);
void _activate_submenu(int over);
void _submenu_timeout();
@@ -79,11 +79,11 @@ protected:
virtual bool has_point(const Point2& p_point) const;
-friend class MenuButton;
+friend class MenuButton;
void _notification(int p_what);
- static void _bind_methods();
+ static void _bind_methods();
public:
-
+
void add_icon_item(const Ref<Texture>& p_icon,const String& p_label,int p_ID=-1,uint32_t p_accel=0);
void add_item(const String& p_label,int p_ID=-1,uint32_t p_accel=0);
void add_icon_check_item(const Ref<Texture>& p_icon,const String& p_label,int p_ID=-1,uint32_t p_accel=0);
@@ -92,7 +92,7 @@ public:
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);
+ void set_item_checked(int p_idx,bool p_checked);
void set_item_ID(int p_idx,int p_ID);
void set_item_accelerator(int p_idx,uint32_t p_accel);
void set_item_metadata(int p_idx,const Variant& p_meta);
@@ -110,7 +110,7 @@ public:
uint32_t get_item_accelerator(int p_idx) const;
Variant get_item_metadata(int p_idx) const;
bool is_item_disabled(int p_idx) const;
- String get_item_submenu(int p_ID) const;
+ String get_item_submenu(int p_ID) const;
bool is_item_separator(int p_idx) const;
bool is_item_checkable(int p_idx) const;
String get_item_tooltip(int p_idx) const;
@@ -121,9 +121,9 @@ public:
void activate_item(int p_item);
void remove_item(int p_idx);
-
+
void add_separator();
-
+
void clear();
void set_parent_rect(const Rect2& p_rect);
@@ -137,7 +137,7 @@ public:
void set_invalidate_click_until_motion();
- PopupMenu();
+ PopupMenu();
~PopupMenu();
};
diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp
index ffcdf98519..b00fcfe42c 100644
--- a/scene/gui/range.cpp
+++ b/scene/gui/range.cpp
@@ -67,14 +67,14 @@ void Range::Shared::emit_changed(const char *p_what) {
void Range::set_val(double p_val) {
-
+
if(_rounded_values){
p_val = Math::round(p_val);
}
-
+
if (p_val>shared->max-shared->page)
p_val=shared->max-shared->page;
-
+
if (p_val<shared->min)
p_val=shared->min;
@@ -84,58 +84,58 @@ void Range::set_val(double p_val) {
if (shared->val==p_val)
return;
-
+
shared->val=p_val;
-
+
shared->emit_value_changed();
}
void Range::set_min(double p_min) {
-
+
shared->min=p_min;
set_val(shared->val);
-
+
shared->emit_changed("range/min");
}
void Range::set_max(double p_max) {
-
+
shared->max=p_max;
set_val(shared->val);
-
+
shared->emit_changed("range/max");
}
void Range::set_step(double p_step) {
-
+
shared->step=p_step;
shared->emit_changed("range/step");
}
void Range::set_page(double p_page) {
-
+
shared->page=p_page;
set_val(shared->val);
-
+
shared->emit_changed("range/page");
}
double Range::get_val() const {
-
+
return shared->val;
}
double Range::get_min() const {
-
+
return shared->min;
}
double Range::get_max() const {
-
+
return shared->max;
}
double Range::get_step() const {
-
+
return shared->step;
}
double Range::get_page() const {
-
+
return shared->page;
}
diff --git a/scene/gui/range.h b/scene/gui/range.h
index d96ecdfb0b..85c3687b7d 100644
--- a/scene/gui/range.h
+++ b/scene/gui/range.h
@@ -34,7 +34,7 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class Range : public Control {
-
+
OBJ_TYPE( Range, Control );
@@ -57,15 +57,15 @@ class Range : public Control {
void _value_changed_notify();
void _changed_notify(const char *p_what="");
-protected:
+protected:
virtual void _value_changed(double) {}
static void _bind_methods();
-
+
bool _rounded_values;
public:
-
+
void set_val(double p_val);
void set_min(double p_min);
void set_max(double p_max);
@@ -89,7 +89,7 @@ public:
void share(Range *p_range);
void unshare();
- Range();
+ Range();
~Range();
};
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index d4ac2652dc..98bc0b9434 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -237,7 +237,7 @@ if (m_height > line_height) {\
if (font.is_null())
font=p_base_font;
- const CharType *c = text->text.c_str();
+ const CharType *c = text->text.c_str();
const CharType *cf=c;
int fh=font->get_height();
int ascent = font->get_ascent();
@@ -297,7 +297,7 @@ if (m_height > line_height) {\
fw+=cw;
}
- end++;
+ end++;
}
ENSURE_WIDTH(w);
@@ -2058,7 +2058,7 @@ RichTextLabel::RichTextLabel() {
scroll_active=true;
scroll_w=0;
- vscroll = memnew( VScrollBar );
+ vscroll = memnew( VScrollBar );
add_child(vscroll);
vscroll->set_drag_slave(String(".."));
vscroll->set_step(1);
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index 0fd4286f38..d8365feb24 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -35,7 +35,7 @@ bool ScrollBar::focus_by_default=false;
void ScrollBar::set_can_focus_by_default(bool p_can_focus) {
-
+
focus_by_default=p_can_focus;
}
@@ -43,14 +43,14 @@ void ScrollBar::_input_event(InputEvent p_event) {
switch(p_event.type) {
-
+
case InputEvent::MOUSE_BUTTON: {
-
+
const InputEventMouseButton &b=p_event.mouse_button;
accept_event();
if (b.button_index==5 && b.pressed) {
-
+
//if (orientation==VERTICAL)
// set_val( get_val() + get_page() / 4.0 );
//else
@@ -58,16 +58,16 @@ void ScrollBar::_input_event(InputEvent p_event) {
accept_event();
}
-
+
if (b.button_index==4 && b.pressed) {
-
+
//if (orientation==HORIZONTAL)
// set_val( get_val() - get_page() / 4.0 );
//else
set_val( get_val() - get_page() / 4.0 );
accept_event();
}
-
+
if (b.button_index!=1)
return;
@@ -78,177 +78,177 @@ void ScrollBar::_input_event(InputEvent p_event) {
double ofs = orientation==VERTICAL ? b.y : b.x ;
Ref<Texture> decr = get_icon("decrement");
Ref<Texture> incr = get_icon("increment");
-
+
double decr_size = orientation==VERTICAL ? decr->get_height() : decr->get_width();
double incr_size = orientation==VERTICAL ? incr->get_height() : incr->get_width();
double grabber_ofs = get_grabber_offset();
double grabber_size = get_grabber_size();
double total = orientation==VERTICAL ? get_size().height : get_size().width;
-
+
if (ofs < decr_size ) {
-
+
set_val( get_val() - (custom_step>=0?custom_step:get_step()) );
break;
}
-
+
if (ofs > total-incr_size ) {
-
+
set_val( get_val() + (custom_step>=0?custom_step:get_step()) );
break;
}
-
+
ofs-=decr_size;
-
+
if ( ofs < grabber_ofs ) {
-
+
set_val( get_val() - get_page() );
break;
-
- }
-
+
+ }
+
ofs-=grabber_ofs;
-
+
if (ofs < grabber_size ) {
-
+
drag.active=true;
drag.pos_at_click=grabber_ofs+ofs;
- drag.value_at_click=get_unit_value();
+ drag.value_at_click=get_unit_value();
update();
} else {
-
-
+
+
set_val( get_val() + get_page() );
}
-
-
+
+
} else {
-
+
drag.active=false;
update();
}
-
+
} break;
case InputEvent::MOUSE_MOTION: {
-
+
const InputEventMouseMotion &m=p_event.mouse_motion;
accept_event();
-
+
if (drag.active) {
-
+
double ofs = orientation==VERTICAL ? m.y : m.x ;
Ref<Texture> decr = get_icon("decrement");
-
+
double decr_size = orientation==VERTICAL ? decr->get_height() : decr->get_width();
ofs-=decr_size;
-
+
double diff = (ofs-drag.pos_at_click) / get_area_size();
- set_unit_value( drag.value_at_click + diff );
+ set_unit_value( drag.value_at_click + diff );
} else {
-
-
+
+
double ofs = orientation==VERTICAL ? m.y : m.x ;
Ref<Texture> decr = get_icon("decrement");
Ref<Texture> incr = get_icon("increment");
-
+
double decr_size = orientation==VERTICAL ? decr->get_height() : decr->get_width();
double incr_size = orientation==VERTICAL ? incr->get_height() : incr->get_width();
double total = orientation==VERTICAL ? get_size().height : get_size().width;
-
+
HiliteStatus new_hilite;
-
+
if (ofs < decr_size ) {
-
+
new_hilite=HILITE_DECR;
-
+
} else if (ofs > total-incr_size ) {
-
+
new_hilite=HILITE_INCR;
-
+
} else {
-
+
new_hilite=HILITE_RANGE;
}
-
+
if (new_hilite!=hilite) {
-
+
hilite=new_hilite;
update();
-
+
}
-
+
}
} break;
case InputEvent::KEY: {
-
+
const InputEventKey &k=p_event.key;
-
+
if (!k.pressed)
return;
-
+
switch (k.scancode) {
-
+
case KEY_LEFT: {
-
+
if (orientation!=HORIZONTAL)
return;
set_val( get_val() - (custom_step>=0?custom_step:get_step()) );
-
+
} break;
case KEY_RIGHT: {
-
+
if (orientation!=HORIZONTAL)
return;
set_val( get_val() + (custom_step>=0?custom_step:get_step()) );
-
+
} break;
case KEY_UP: {
-
+
if (orientation!=VERTICAL)
return;
-
+
set_val( get_val() - (custom_step>=0?custom_step:get_step()) );
-
-
+
+
} break;
case KEY_DOWN: {
-
+
if (orientation!=VERTICAL)
return;
set_val( get_val() + (custom_step>=0?custom_step:get_step()) );
-
+
} break;
case KEY_HOME: {
-
+
set_val( get_min() );
-
+
} break;
case KEY_END: {
-
+
set_val( get_max() );
-
+
} break;
-
+
} break;
- }
+ }
}
}
void ScrollBar::_notification(int p_what) {
-
+
if (p_what==NOTIFICATION_DRAW) {
-
+
RID ci = get_canvas_item();
-
+
Ref<Texture> decr = hilite==HILITE_DECR ? get_icon("decrement_hilite") : get_icon("decrement");
Ref<Texture> incr = hilite==HILITE_INCR ? get_icon("increment_hilite") : get_icon("increment");
Ref<StyleBox> bg = has_focus() ? get_stylebox("scroll_focus") : get_stylebox("scroll");
Ref<StyleBox> grabber = (drag.active || hilite==HILITE_RANGE) ? get_stylebox("grabber_hilite") : get_stylebox("grabber");
-
+
Point2 ofs;
-
+
VisualServer *vs = VisualServer::get_singleton();
vs->canvas_item_add_texture_rect( ci, Rect2( Point2(), decr->get_size()),decr->get_rid() );
@@ -266,33 +266,33 @@ void ScrollBar::_notification(int p_what) {
area.height-=incr->get_height()+decr->get_height();
bg->draw(ci,Rect2(ofs,area));
-
- if (orientation==HORIZONTAL)
+
+ if (orientation==HORIZONTAL)
ofs.width+=area.width;
else
ofs.height+=area.height;
vs->canvas_item_add_texture_rect( ci, Rect2( ofs, decr->get_size()),incr->get_rid() );
Rect2 grabber_rect;
-
+
if (orientation==HORIZONTAL) {
-
+
grabber_rect.size.width=get_grabber_size();
grabber_rect.size.height=get_size().height;
grabber_rect.pos.y=0;
grabber_rect.pos.x=get_grabber_offset()+decr->get_width()+bg->get_margin( MARGIN_LEFT );
} else {
-
+
grabber_rect.size.width=get_size().width;
grabber_rect.size.height=get_grabber_size();
grabber_rect.pos.y=get_grabber_offset()+decr->get_height()+bg->get_margin( MARGIN_TOP );
- grabber_rect.pos.x=0;
+ grabber_rect.pos.x=0;
}
-
+
grabber->draw(ci,grabber_rect);
-
+
}
-
+
if (p_what==NOTIFICATION_ENTER_TREE) {
@@ -405,48 +405,48 @@ void ScrollBar::_notification(int p_what) {
}
if (p_what==NOTIFICATION_MOUSE_EXIT) {
-
+
hilite=HILITE_NONE;
update();
}
}
double ScrollBar::get_grabber_min_size() const {
-
+
Ref<StyleBox> grabber=get_stylebox("grabber");
Size2 gminsize=grabber->get_minimum_size()+grabber->get_center_size();
- return (orientation==VERTICAL)?gminsize.height:gminsize.width;
+ return (orientation==VERTICAL)?gminsize.height:gminsize.width;
}
double ScrollBar::get_grabber_size() const {
-
+
float range = get_max()-get_min();
if (range<=0)
return 0;
-
+
float page = (get_page()>0)? get_page() : 0;
// if (grabber_range < get_step())
// grabber_range=get_step();
-
+
double area_size=get_area_size();
double grabber_size = page / range * area_size;
return grabber_size+get_grabber_min_size();
-
-}
+
+}
double ScrollBar::get_area_size() const {
-
+
if (orientation==VERTICAL) {
-
+
double area=get_size().height;
area-=get_stylebox("scroll")->get_minimum_size().height;
area-=get_icon("increment")->get_height();
area-=get_icon("decrement")->get_height();
area-=get_grabber_min_size();
return area;
-
+
} else if (orientation==HORIZONTAL) {
-
+
double area=get_size().width;
area-=get_stylebox("scroll")->get_minimum_size().width;
area-=get_icon("increment")->get_width();
@@ -454,38 +454,38 @@ double ScrollBar::get_area_size() const {
area-=get_grabber_min_size();
return area;
} else {
-
+
return 0;
}
-
+
}
double ScrollBar::get_area_offset() const {
-
+
double ofs=0;
-
+
if (orientation==VERTICAL) {
-
+
ofs+=get_stylebox("hscroll")->get_margin( MARGIN_TOP );
ofs+=get_icon("decrement")->get_height();
- }
-
+ }
+
if (orientation==HORIZONTAL) {
-
+
ofs+=get_stylebox("hscroll")->get_margin( MARGIN_LEFT );
ofs+=get_icon("decrement")->get_width();
}
-
- return ofs;
+
+ return ofs;
}
double ScrollBar::get_click_pos(const Point2& p_pos) const {
-
-
+
+
float pos=(orientation==VERTICAL)?p_pos.y:p_pos.x;
pos-=get_area_offset();
-
+
float area=get_area_size();
if (area==0)
return 0;
@@ -495,8 +495,8 @@ double ScrollBar::get_click_pos(const Point2& p_pos) const {
}
double ScrollBar::get_grabber_offset() const {
-
-
+
+
return (get_area_size()) * get_unit_value();
}
@@ -504,30 +504,30 @@ double ScrollBar::get_grabber_offset() const {
Size2 ScrollBar::get_minimum_size() const {
-
+
Ref<Texture> incr = get_icon("increment");
Ref<Texture> decr = get_icon("decrement");
Ref<StyleBox> bg = get_stylebox("scroll");
Size2 minsize;
-
+
if (orientation==VERTICAL) {
-
+
minsize.width=MAX(incr->get_size().width,(bg->get_minimum_size()+bg->get_center_size()).width);
minsize.height+=incr->get_size().height;
minsize.height+=decr->get_size().height;
minsize.height+=bg->get_minimum_size().height;
minsize.height+=get_grabber_min_size();
}
-
+
if (orientation==HORIZONTAL) {
-
+
minsize.height=MAX(incr->get_size().height,(bg->get_center_size()+bg->get_minimum_size()).height);
minsize.width+=incr->get_size().width;
minsize.width+=decr->get_size().width;
minsize.width+=bg->get_minimum_size().width;
minsize.width+=get_grabber_min_size();
}
-
+
return minsize;
}
@@ -671,65 +671,65 @@ NodePath ScrollBar::get_drag_slave() const{
#if 0
void ScrollBar::mouse_button(const Point2& p_pos, int b.button_index,bool b.pressed,int p_modifier_mask) {
-
- // wheel!
-
+
+ // wheel!
+
if (b.button_index==BUTTON_WHEEL_UP && b.pressed) {
-
+
if (orientation==VERTICAL)
set_val( get_val() - get_page() / 4.0 );
else
set_val( get_val() + get_page() / 4.0 );
-
+
}
if (b.button_index==BUTTON_WHEEL_DOWN && b.pressed) {
-
+
if (orientation==HORIZONTAL)
set_val( get_val() - get_page() / 4.0 );
else
set_val( get_val() + get_page() / 4.0 );
}
-
+
if (b.button_index!=BUTTON_LEFT)
return;
-
+
if (b.pressed) {
-
+
int ofs = orientation==VERTICAL ? p_pos.y : p_pos.x ;
int grabber_ofs = get_grabber_offset();
int grabber_size = get_grabber_size();
-
+
if ( ofs < grabber_ofs ) {
-
+
set_val( get_val() - get_page() );
-
+
} else if (ofs > grabber_ofs + grabber_size ) {
-
+
set_val( get_val() + get_page() );
-
+
} else {
-
-
+
+
drag.active=true;
drag.pos_at_click=get_click_pos(p_pos);
drag.value_at_click=get_unit_value();
}
-
-
+
+
} else {
-
+
drag.active=false;
}
-
+
}
void ScrollBar::mouse_motion(const Point2& p_pos, const Point2& p_rel, int b.button_index_mask) {
-
+
if (!drag.active)
return;
-
+
double value_ofs=drag.value_at_click+(get_click_pos(p_pos)-drag.pos_at_click);
-
-
+
+
value_ofs=value_ofs*( get_max() - get_min() );
if (value_ofs<get_min())
value_ofs=get_min();
@@ -737,64 +737,64 @@ void ScrollBar::mouse_motion(const Point2& p_pos, const Point2& p_rel, int b.but
value_ofs=get_max()-get_page();
if (get_val()==value_ofs)
return; //dont bother if the value is the same
-
+
set_val( value_ofs );
-
+
}
bool ScrollBar::key(unsigned long p_unicode, unsigned long p_scan_code,bool b.pressed,bool p_repeat,int p_modifier_mask) {
-
+
if (!b.pressed)
return false;
-
+
switch (p_scan_code) {
-
+
case KEY_LEFT: {
-
+
if (orientation!=HORIZONTAL)
return false;
set_val( get_val() - get_step() );
-
+
} break;
case KEY_RIGHT: {
-
+
if (orientation!=HORIZONTAL)
return false;
set_val( get_val() + get_step() );
-
+
} break;
case KEY_UP: {
-
+
if (orientation!=VERTICAL)
return false;
-
+
set_val( get_val() - get_step() );
-
-
+
+
} break;
case KEY_DOWN: {
-
+
if (orientation!=VERTICAL)
return false;
set_val( get_val() + get_step() );
-
+
} break;
case KEY_HOME: {
-
+
set_val( get_min() );
-
+
} break;
case KEY_END: {
-
+
set_val( get_max() );
-
+
} break;
-
+
default:
return false;
-
+
}
-
+
return true;
}
@@ -823,7 +823,7 @@ ScrollBar::ScrollBar(Orientation p_orientation)
hilite=HILITE_NONE;
custom_step=-1;
drag_slave=NULL;
-
+
drag.active=false;
drag_slave_speed=Vector2();
@@ -833,7 +833,7 @@ ScrollBar::ScrollBar(Orientation p_orientation)
if (focus_by_default)
set_focus_mode( FOCUS_ALL );
-
+
}
diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h
index a629ddc56c..c68db02b33 100644
--- a/scene/gui/scroll_bar.h
+++ b/scene/gui/scroll_bar.h
@@ -36,40 +36,40 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class ScrollBar : public Range {
-
+
OBJ_TYPE( ScrollBar, Range );
-
+
enum HiliteStatus {
HILITE_NONE,
HILITE_DECR,
HILITE_RANGE,
- HILITE_INCR,
+ HILITE_INCR,
};
-
+
static bool focus_by_default;
-
+
Orientation orientation;
Size2 size;
float custom_step;
-
+
HiliteStatus hilite;
-
+
struct Drag {
-
+
bool active;
float pos_at_click;
float value_at_click;
} drag;
-
-
+
+
double get_grabber_size() const;
double get_grabber_min_size() const;
double get_area_size() const;
double get_area_offset() const;
double get_click_pos(const Point2& p_pos) const;
double get_grabber_offset() const;
-
- static void set_can_focus_by_default(bool p_can_focus);
+
+ static void set_can_focus_by_default(bool p_can_focus);
Node* drag_slave;
NodePath drag_slave_path;
@@ -86,12 +86,12 @@ class ScrollBar : public Range {
void _drag_slave_exit();
void _drag_slave_input(const InputEvent& p_input);
-
+
void _input_event(InputEvent p_event);
-protected:
+protected:
void _notification(int p_what);
- static void _bind_methods();
+ static void _bind_methods();
public:
@@ -101,25 +101,25 @@ public:
void set_drag_slave(const NodePath& p_path);
NodePath get_drag_slave() const;
- virtual Size2 get_minimum_size() const;
- ScrollBar(Orientation p_orientation=VERTICAL);
+ virtual Size2 get_minimum_size() const;
+ ScrollBar(Orientation p_orientation=VERTICAL);
~ScrollBar();
};
class HScrollBar : public ScrollBar {
-
+
OBJ_TYPE( HScrollBar, ScrollBar );
public:
-
+
HScrollBar() : ScrollBar(HORIZONTAL) { set_v_size_flags(0); }
};
class VScrollBar : public ScrollBar {
-
+
OBJ_TYPE( VScrollBar, ScrollBar );
public:
-
+
VScrollBar() : ScrollBar(VERTICAL) { set_h_size_flags(0); }
};
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index a2fc038f9e..9bf93aff77 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -35,7 +35,37 @@ bool ScrollContainer::clips_input() const {
Size2 ScrollContainer::get_minimum_size() const {
- return Size2(1, 1);
+
+ Size2 min_size;
+
+ for(int i=0;i<get_child_count();i++) {
+
+ Control *c = get_child(i)->cast_to<Control>();
+ if (!c)
+ continue;
+ if (c->is_set_as_toplevel())
+ continue;
+ if (c == h_scroll || c == v_scroll)
+ continue;
+ Size2 minsize = c->get_combined_minimum_size();
+
+
+ if (!scroll_h) {
+ min_size.x = MAX(min_size.x, minsize.x);
+ }
+ if (!scroll_v) {
+ min_size.y = MAX(min_size.y, minsize.y);
+
+ }
+ }
+
+ if (h_scroll->is_visible()) {
+ min_size.y+=h_scroll->get_minimum_size().y;
+ }
+ if (v_scroll->is_visible()) {
+ min_size.x+=v_scroll->get_minimum_size().x;
+ }
+ return min_size;
};
@@ -179,6 +209,12 @@ void ScrollContainer::_notification(int p_what) {
child_max_size = Size2(0, 0);
Size2 size = get_size();
+ if (h_scroll->is_visible())
+ size.y-=h_scroll->get_minimum_size().y;
+
+ if (v_scroll->is_visible())
+ size.x-=h_scroll->get_minimum_size().x;
+
for(int i=0;i<get_child_count();i++) {
Control *c = get_child(i)->cast_to<Control>();
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 7ef9d4216b..f66f909517 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -231,13 +231,13 @@ void Slider::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_input_event"),&Slider::_input_event);
ObjectTypeDB::bind_method(_MD("set_ticks","count"),&Slider::set_ticks);
ObjectTypeDB::bind_method(_MD("get_ticks"),&Slider::get_ticks);
-
- ObjectTypeDB::bind_method(_MD("get_ticks_on_borders"),&Slider::get_ticks_on_borders);
+
+ ObjectTypeDB::bind_method(_MD("get_ticks_on_borders"),&Slider::get_ticks_on_borders);
ObjectTypeDB::bind_method(_MD("set_ticks_on_borders","ticks_on_border"),&Slider::set_ticks_on_borders);
-
+
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") );
-
+
}
Slider::Slider(Orientation p_orientation) {
diff --git a/scene/gui/slider.h b/scene/gui/slider.h
index f85e6d1807..cf009b9a75 100644
--- a/scene/gui/slider.h
+++ b/scene/gui/slider.h
@@ -53,7 +53,7 @@ protected:
void _notification(int p_what);
static void _bind_methods();
bool ticks_on_borders;
-
+
public:
virtual Size2 get_minimum_size() const;
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 91d0fc157e..1c6a97bab8 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "tab_container.h"
-
+
#include "message_queue.h"
@@ -209,7 +209,7 @@ void TabContainer::_notification(int p_what) {
Ref<Texture> incr = get_icon("increment");
Ref<Texture> incr_hl = get_icon("increment_hilite");
Ref<Texture> decr = get_icon("decrement");
- Ref<Texture> decr_hl = get_icon("decrement_hilite");
+ Ref<Texture> decr_hl = get_icon("decrement_hilite");
Ref<Texture> menu = get_icon("menu");
Ref<Texture> menu_hl = get_icon("menu_hl");
Ref<Font> font = get_font("font");
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index c3e75842c3..9692d08882 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -493,7 +493,7 @@ void Tabs::set_current_tab(int p_current) {
ERR_FAIL_INDEX( p_current, get_tab_count() );
//printf("DEBUG %p: set_current_tab to %i\n", this, p_current);
- current=p_current;
+ current=p_current;
_change_notify("current_tab");
//emit_signal("tab_changed",current);
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index bf012b7a03..e268375c8a 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -38,12 +38,12 @@
#define TAB_PIXELS
static bool _is_text_char(CharType c) {
-
+
return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_';
}
static bool _is_symbol(CharType c) {
-
+
return c!='_' && ((c>='!' && c<='/') || (c>=':' && c<='@') || (c>='[' && c<='`') || (c>='{' && c<='~') || c=='\t');
}
@@ -84,81 +84,81 @@ static CharType _get_right_pair_symbol(CharType c) {
}
void TextEdit::Text::set_font(const Ref<Font>& p_font) {
-
+
font=p_font;
}
void TextEdit::Text::set_tab_size(int p_tab_size) {
-
+
tab_size=p_tab_size;
}
void TextEdit::Text::_update_line_cache(int p_line) const {
-
+
int w = 0;
int tab_w=font->get_char_size(' ').width*tab_size;
int len = text[p_line].data.length();
const CharType *str = text[p_line].data.c_str();
-
+
//update width
-
+
for(int i=0;i<len;i++) {
if (str[i]=='\t') {
-
+
int left = w%tab_w;
if (left==0)
w+=tab_w;
else
w+=tab_w-w%tab_w; // is right...
-
+
} else {
-
+
w+=font->get_char_size(str[i],str[i+1]).width;
}
}
-
-
+
+
text[p_line].width_cache=w;
-
+
//update regions
-
+
text[p_line].region_info.clear();
-
+
for(int i=0;i<len;i++) {
-
+
if (!_is_symbol(str[i]))
continue;
if (str[i]=='\\') {
i++; //skip quoted anything
continue;
}
-
+
int left=len-i;
-
+
for(int j=0;j<color_regions->size();j++) {
-
+
const ColorRegion& cr=color_regions->operator [](j);
-
+
/* BEGIN */
-
+
int lr=cr.begin_key.length();
if (lr==0 || lr>left)
continue;
-
+
const CharType* kc = cr.begin_key.c_str();
-
+
bool match=true;
-
+
for(int k=0;k<lr;k++) {
if (kc[k]!=str[i+k]) {
match=false;
break;
}
}
-
+
if (match) {
-
+
ColorRegionInfo cri;
cri.end=false;
cri.region=j;
@@ -166,26 +166,26 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
i+=lr-1;
break;
}
-
+
/* END */
-
+
lr=cr.end_key.length();
if (lr==0 || lr>left)
continue;
-
+
kc = cr.end_key.c_str();
-
+
match=true;
-
+
for(int k=0;k<lr;k++) {
if (kc[k]!=str[i+k]) {
match=false;
break;
}
}
-
+
if (match) {
-
+
ColorRegionInfo cri;
cri.end=true;
cri.region=j;
@@ -193,72 +193,72 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
i+=lr-1;
break;
}
-
+
}
}
-
-
+
+
}
const Map<int,TextEdit::Text::ColorRegionInfo>& TextEdit::Text::get_color_region_info(int p_line) {
-
+
Map<int,ColorRegionInfo> *cri=NULL;
ERR_FAIL_INDEX_V(p_line,text.size(),*cri); //enjoy your crash
-
+
if (text[p_line].width_cache==-1) {
_update_line_cache(p_line);
}
-
+
return text[p_line].region_info;
}
int TextEdit::Text::get_line_width(int p_line) const {
-
+
ERR_FAIL_INDEX_V(p_line,text.size(),-1);
-
+
if (text[p_line].width_cache==-1) {
_update_line_cache(p_line);
}
-
+
return text[p_line].width_cache;
}
void TextEdit::Text::clear_caches() {
-
+
for(int i=0;i<text.size();i++)
text[i].width_cache=-1;
-
+
}
void TextEdit::Text::clear() {
-
-
+
+
text.clear();;
insert(0,"");
}
int TextEdit::Text::get_max_width() const {
//quite some work.. but should be fast enough.
-
+
int max = 0;
-
+
for(int i=0;i<text.size();i++)
max=MAX(max,get_line_width(i));
return max;
-
+
}
void TextEdit::Text::set(int p_line,const String& p_text) {
-
+
ERR_FAIL_INDEX(p_line,text.size());
-
+
text[p_line].width_cache=-1;
text[p_line].data=p_text;
}
void TextEdit::Text::insert(int p_at,const String& p_text) {
-
+
Line line;
line.marked=false;
line.breakpoint=false;
@@ -267,86 +267,89 @@ void TextEdit::Text::insert(int p_at,const String& p_text) {
text.insert(p_at,line);
}
void TextEdit::Text::remove(int p_at) {
-
+
text.remove(p_at);
}
void TextEdit::_update_scrollbars() {
-
-
+
+
Size2 size = get_size();
Size2 hmin = h_scroll->get_combined_minimum_size();
Size2 vmin = v_scroll->get_combined_minimum_size();
-
-
-
+
+
+
v_scroll->set_begin( Point2(size.width - vmin.width, cache.style_normal->get_margin(MARGIN_TOP)) );
v_scroll->set_end( Point2(size.width, size.height - cache.style_normal->get_margin(MARGIN_TOP) - cache.style_normal->get_margin(MARGIN_BOTTOM)) );
-
+
h_scroll->set_begin( Point2( 0, size.height - hmin.height) );
h_scroll->set_end( Point2(size.width-vmin.width, size.height) );
-
-
+
+
int hscroll_rows = ((hmin.height-1)/get_row_height())+1;
int visible_rows = get_visible_rows();
int total_rows = text.size();
-
+ if (scroll_past_end_of_file_enabled) {
+ total_rows += get_visible_rows() - 1;
+ }
+
int vscroll_pixels = v_scroll->get_combined_minimum_size().width;
int visible_width = size.width - cache.style_normal->get_minimum_size().width;
int total_width = text.get_max_width() + vmin.x;
-
+
if (line_numbers)
total_width += cache.line_number_w;
-
+
bool use_hscroll=true;
bool use_vscroll=true;
-
+
if (total_rows <= visible_rows && total_width <= visible_width) {
//thanks yessopie for this clever bit of logic
use_hscroll=false;
use_vscroll=false;
-
+
} else {
-
+
if (total_rows > visible_rows && total_width <= visible_width - vscroll_pixels) {
//thanks yessopie for this clever bit of logic
use_hscroll=false;
}
-
+
if (total_rows <= visible_rows - hscroll_rows && total_width > visible_width) {
//thanks yessopie for this clever bit of logic
use_vscroll=false;
}
}
-
+
updating_scrolls=true;
-
+
if (use_vscroll) {
-
+
v_scroll->show();
v_scroll->set_max(total_rows);
v_scroll->set_page(visible_rows);
v_scroll->set_val(cursor.line_ofs);
-
+
} else {
cursor.line_ofs = 0;
v_scroll->hide();
}
-
+
if (use_hscroll) {
-
+
h_scroll->show();
h_scroll->set_max(total_width);
h_scroll->set_page(visible_width);
h_scroll->set_val(cursor.x_ofs);
-
+
} else {
-
+
h_scroll->hide();
}
-
-
-
+
+
+
updating_scrolls=false;
}
@@ -375,32 +378,32 @@ void TextEdit::_click_selection_held() {
void TextEdit::_notification(int p_what) {
-
+
switch(p_what) {
case NOTIFICATION_ENTER_TREE: {
-
+
_update_caches();
if (cursor_changed_dirty)
MessageQueue::get_singleton()->push_call(this,"_cursor_changed_emit");
if (text_changed_dirty)
MessageQueue::get_singleton()->push_call(this,"_text_changed_emit");
-
+
} break;
case NOTIFICATION_RESIZED: {
-
+
cache.size=get_size();
adjust_viewport_to_cursor();
-
-
+
+
} break;
case NOTIFICATION_THEME_CHANGED: {
-
+
_update_caches();
};
case NOTIFICATION_DRAW: {
-
+
int line_number_char_count=0;
-
+
{
int lc=text.size()+1;
cache.line_number_w=0;
@@ -408,20 +411,20 @@ void TextEdit::_notification(int p_what) {
cache.line_number_w+=1;
lc/=10;
};
-
+
if (line_numbers) {
-
+
line_number_char_count=cache.line_number_w;
cache.line_number_w=(cache.line_number_w+1)*cache.font->get_char_size('0').width;
} else {
cache.line_number_w=0;
}
-
-
+
+
}
_update_scrollbars();
-
-
+
+
RID ci = get_canvas_item();
int xmargin_beg=cache.style_normal->get_margin(MARGIN_LEFT)+cache.line_number_w;
int xmargin_end=cache.size.width-cache.style_normal->get_margin(MARGIN_RIGHT);
@@ -429,56 +432,56 @@ void TextEdit::_notification(int p_what) {
cache.style_normal->draw(ci,Rect2(Point2(),cache.size));
if (has_focus())
cache.style_focus->draw(ci,Rect2(Point2(),cache.size));
-
-
+
+
int ascent=cache.font->get_ascent();
-
+
int visible_rows = get_visible_rows();
-
+
int tab_w = cache.font->get_char_size(' ').width*tab_size;
-
+
Color color = cache.font_color;
int in_region=-1;
-
+
if (syntax_coloring) {
-
+
if (custom_bg_color.a>0.01) {
-
+
Point2i ofs = Point2i(cache.style_normal->get_offset())/2.0;
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(ofs, get_size()-cache.style_normal->get_minimum_size()+ofs),custom_bg_color);
}
//compute actual region to start (may be inside say, a comment).
//slow in very large documments :( but ok for source!
-
+
for(int i=0;i<cursor.line_ofs;i++) {
-
+
const Map<int,Text::ColorRegionInfo>& cri_map=text.get_color_region_info(i);
-
+
if (in_region>=0 && color_regions[in_region].line_only) {
in_region=-1; //reset regions that end at end of line
}
-
+
for( const Map<int,Text::ColorRegionInfo>::Element* E= cri_map.front();E;E=E->next() ) {
-
+
const Text::ColorRegionInfo &cri=E->get();
-
+
if (in_region==-1) {
-
+
if (!cri.end) {
-
+
in_region=cri.region;
}
} else if (in_region==cri.region && !color_regions[cri.region].line_only) { //ignore otherwise
-
+
if (cri.end || color_regions[cri.region].eq) {
-
+
in_region=-1;
}
}
}
}
}
-
+
int brace_open_match_line=-1;
int brace_open_match_column=-1;
bool brace_open_matching=false;
@@ -487,15 +490,15 @@ void TextEdit::_notification(int p_what) {
int brace_close_match_column=-1;
bool brace_close_matching=false;
bool brace_close_mismatch=false;
-
-
+
+
if (brace_matching_enabled) {
-
+
if (cursor.column<text[cursor.line].length()) {
//check for open
CharType c = text[cursor.line][cursor.column];
CharType closec=0;
-
+
if (c=='[') {
closec=']';
} else if (c=='{') {
@@ -503,17 +506,17 @@ void TextEdit::_notification(int p_what) {
} else if (c=='(') {
closec=')';
}
-
+
if (closec!=0) {
-
+
int stack=1;
-
-
+
+
for(int i=cursor.line;i<text.size();i++) {
-
+
int from = i==cursor.line?cursor.column+1:0;
for(int j=from;j<text[i].length();j++) {
-
+
CharType cc = text[i][j];
//ignore any brackets inside a string
if (cc== '"' || cc == '\'') {
@@ -541,32 +544,32 @@ void TextEdit::_notification(int p_what) {
stack++;
else if (cc==closec)
stack--;
-
+
if (stack==0) {
brace_open_match_line=i;
brace_open_match_column=j;
brace_open_matching=true;
-
+
break;
}
}
if (brace_open_match_line!=-1)
break;
}
-
+
if (!brace_open_matching)
brace_open_mismatch=true;
-
-
+
+
}
}
-
+
if (cursor.column>0) {
CharType c = text[cursor.line][cursor.column-1];
CharType closec=0;
-
-
-
+
+
+
if (c==']') {
closec='[';
} else if (c=='}') {
@@ -574,17 +577,17 @@ void TextEdit::_notification(int p_what) {
} else if (c==')') {
closec='(';
}
-
+
if (closec!=0) {
-
+
int stack=1;
-
-
+
+
for(int i=cursor.line;i>=0;i--) {
-
+
int from = i==cursor.line?cursor.column-2:text[i].length()-1;
for(int j=from;j>=0;j--) {
-
+
CharType cc = text[i][j];
//ignore any brackets inside a string
if (cc== '"' || cc == '\'') {
@@ -613,49 +616,49 @@ void TextEdit::_notification(int p_what) {
stack++;
else if (cc==closec)
stack--;
-
+
if (stack==0) {
brace_close_match_line=i;
brace_close_match_column=j;
brace_close_matching=true;
-
+
break;
}
}
if (brace_close_match_line!=-1)
break;
}
-
+
if (!brace_close_matching)
brace_close_mismatch=true;
-
-
+
+
}
-
-
+
+
}
}
-
-
+
+
int deregion=0; //force it to clear inrgion
Point2 cursor_pos;
-
+
for (int i=0;i<visible_rows;i++) {
-
+
int line=i+cursor.line_ofs;
-
+
if (line<0 || line>=(int)text.size())
continue;
-
+
const String &str=text[line];
-
+
int char_margin=xmargin_beg-cursor.x_ofs;
int char_ofs=0;
int ofs_y=i*get_row_height()+cache.line_spacing/2;
bool prev_is_char=false;
bool in_keyword=false;
Color keyword_color;
-
+
if (cache.line_number_w) {
Color fcol = cache.font_color;
fcol.a*=0.4;
@@ -663,191 +666,191 @@ void TextEdit::_notification(int p_what) {
while (fc.length() < line_number_char_count) {
fc="0"+fc;
}
-
+
cache.font->draw(ci,Point2(cache.style_normal->get_margin(MARGIN_LEFT),ofs_y+cache.font->get_ascent()),fc,fcol);
}
-
+
const Map<int,Text::ColorRegionInfo>& cri_map=text.get_color_region_info(line);
-
-
+
+
if (text.is_marked(line)) {
-
+
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(xmargin_beg, ofs_y,xmargin_end-xmargin_beg,get_row_height()),cache.mark_color);
}
-
+
if (text.is_breakpoint(line)) {
-
+
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(xmargin_beg, ofs_y,xmargin_end-xmargin_beg,get_row_height()),cache.current_line_color);
-
+
}
for (int j=0;j<str.length();j++) {
-
+
//look for keyword
-
+
if (deregion>0) {
deregion--;
if (deregion==0)
in_region=-1;
}
if (syntax_coloring && deregion==0) {
-
-
+
+
color = cache.font_color; //reset
//find keyword
bool is_char = _is_text_char(str[j]);
bool is_symbol=_is_symbol(str[j]);
-
+
if (j==0 && in_region>=0 && color_regions[in_region].line_only) {
in_region=-1; //reset regions that end at end of line
}
-
+
if (is_symbol && cri_map.has(j)) {
-
-
+
+
const Text::ColorRegionInfo &cri=cri_map[j];
-
+
if (in_region==-1) {
-
+
if (!cri.end) {
-
+
in_region=cri.region;
}
} else if (in_region==cri.region && !color_regions[cri.region].line_only) { //ignore otherwise
-
+
if (cri.end || color_regions[cri.region].eq) {
-
+
deregion=color_regions[cri.region].eq?color_regions[cri.region].begin_key.length():color_regions[cri.region].end_key.length();
}
}
}
-
+
if (!is_char)
in_keyword=false;
-
+
if (in_region==-1 && !in_keyword && is_char && !prev_is_char) {
-
+
int to=j;
while(to<str.length() && _is_text_char(str[to]))
to++;
-
+
uint32_t hash = String::hash(&str[j],to-j);
StrRange range(&str[j],to-j);
-
+
const Color *col=keywords.custom_getptr(range,hash);
-
+
if (col) {
-
+
in_keyword=true;
keyword_color=*col;
}
}
-
-
+
+
if (in_region>=0)
color=color_regions[in_region].color;
else if (in_keyword)
color=keyword_color;
else if (is_symbol)
color=symbol_color;
-
+
prev_is_char=is_char;
-
+
}
int char_w;
-
+
//handle tabulator
-
-
+
+
if (str[j]=='\t') {
int left = char_ofs%tab_w;
if (left==0)
char_w=tab_w;
else
char_w=tab_w-char_ofs%tab_w; // is right...
-
+
} else {
char_w=cache.font->get_char_size(str[j],str[j+1]).width;
}
-
+
if ( (char_ofs+char_margin)<xmargin_beg) {
char_ofs+=char_w;
continue;
}
-
+
if ( (char_ofs+char_margin+char_w)>=xmargin_end) {
if (syntax_coloring)
continue;
else
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));
-
-
+
+
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 (brace_matching_enabled) {
if ( (brace_open_match_line==line && brace_open_match_column==j) ||
(cursor.column==j && cursor.line==line && (brace_open_matching||brace_open_mismatch))) {
-
+
if (brace_open_mismatch)
color=cache.brace_mismatch_color;
cache.font->draw_char(ci,Point2i( char_ofs+char_margin, ofs_y+ascent),'_',str[j+1],in_selection?cache.font_selected_color:color);
-
+
}
-
+
if (
(brace_close_match_line==line && brace_close_match_column==j) ||
(cursor.column==j+1 && cursor.line==line && (brace_close_matching||brace_close_mismatch))) {
-
-
+
+
if (brace_close_mismatch)
color=cache.brace_mismatch_color;
cache.font->draw_char(ci,Point2i( char_ofs+char_margin, ofs_y+ascent),'_',str[j+1],in_selection?cache.font_selected_color:color);
-
+
}
}
-
-
+
+
if (str[j]>=32)
cache.font->draw_char(ci,Point2i( char_ofs+char_margin, ofs_y+ascent),str[j],str[j+1],in_selection?cache.font_selected_color:color);
-
+
else if (draw_tabs && str[j]=='\t') {
int yofs= (get_row_height() - cache.tab_icon->get_height())/2;
cache.tab_icon->draw(ci, Point2(char_ofs+char_margin,ofs_y+yofs),in_selection?cache.font_selected_color:color);
}
-
-
+
+
if (cursor.column==j && cursor.line==line) {
-
+
cursor_pos = Point2i( char_ofs+char_margin, ofs_y );
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.font_color);
-
-
+
+
}
char_ofs+=char_w;
-
+
}
-
+
if (cursor.column==str.length() && cursor.line==line && (char_ofs+char_margin)>=xmargin_beg) {
-
+
cursor_pos=Point2i( char_ofs+char_margin, ofs_y );
VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.font_color);
-
+
}
}
-
-
+
+ bool completion_below = false;
if (completion_active) {
// code completion box
Ref<StyleBox> csb = get_stylebox("completion");
@@ -858,15 +861,15 @@ void TextEdit::_notification(int p_what) {
existing.a=0.2;
int scrollw = get_constant("completion_scroll_width");
Color scrollc = get_color("completion_scroll_color");
-
-
-
+
+
+
int lines = MIN(completion_options.size(),maxlines);
int w=0;
int h=lines*get_row_height();
int nofs = cache.font->get_string_size(completion_base).width;
-
-
+
+
if (completion_options.size() < 50) {
for(int i=0;i<completion_options.size();i++) {
int w2=MIN(cache.font->get_string_size(completion_options[i]).x,cmax_width);
@@ -876,39 +879,40 @@ void TextEdit::_notification(int p_what) {
} else {
w=cmax_width;
}
-
+
int th = h + csb->get_minimum_size().y;
+
if (cursor_pos.y+get_row_height()+th > get_size().height) {
completion_rect.pos.y=cursor_pos.y-th;
} else {
completion_rect.pos.y=cursor_pos.y+get_row_height()+csb->get_offset().y;
-
+ completion_below = true;
}
-
+
if (cursor_pos.x-nofs+w+scrollw > get_size().width) {
completion_rect.pos.x=get_size().width-w-scrollw;
} else {
completion_rect.pos.x=cursor_pos.x-nofs;
}
-
+
completion_rect.size.width=w+2;
completion_rect.size.height=h;
if (completion_options.size()<=maxlines)
scrollw=0;
-
+
draw_style_box(csb,Rect2(completion_rect.pos-csb->get_offset(),completion_rect.size+csb->get_minimum_size()+Size2(scrollw,0)));
-
-
+
+
int line_from = CLAMP(completion_index - lines/2, 0, completion_options.size() - lines);
draw_style_box(csel,Rect2(Point2(completion_rect.pos.x,completion_rect.pos.y+(completion_index-line_from)*get_row_height()),Size2(completion_rect.size.width,get_row_height())));
-
+
draw_rect(Rect2(completion_rect.pos,Size2(nofs,completion_rect.size.height)),existing);
-
-
-
-
+
+
+
+
for(int i=0;i<lines;i++) {
-
+
int l = line_from + i;
ERR_CONTINUE( l < 0 || l>= completion_options.size());
Color text_color = cache.font_color;
@@ -919,31 +923,47 @@ void TextEdit::_notification(int p_what) {
}
draw_string(cache.font,Point2(completion_rect.pos.x,completion_rect.pos.y+i*get_row_height()+cache.font->get_ascent()),completion_options[l],text_color,completion_rect.size.width);
}
-
+
if (scrollw) {
//draw a small scroll rectangle to show a position in the options
float r = maxlines / (float)completion_options.size();
float o = line_from / (float)completion_options.size();
draw_rect(Rect2(completion_rect.pos.x+completion_rect.size.width,completion_rect.pos.y+o*completion_rect.size.y,scrollw,completion_rect.size.y*r),scrollc);
}
-
+
completion_line_ofs=line_from;
-
+
}
-
+
+ // check to see if the hint should be drawn
+ bool show_hint = false;
if (completion_hint!="") {
-
+ if (completion_active) {
+ if (completion_below && !callhint_below) {
+ show_hint = true;
+ }
+ else if (!completion_below && callhint_below) {
+ show_hint = true;
+ }
+ }
+ else {
+ show_hint = true;
+ }
+ }
+
+ if (show_hint) {
+
Ref<StyleBox> sb = get_stylebox("panel","TooltipPanel");
Ref<Font> font = cache.font;
Color font_color = get_color("font_color","TooltipLabel");
-
-
+
+
int max_w=0;
int sc = completion_hint.get_slice_count("\n");
int offset=0;
int spacing=0;
for(int i=0;i<sc;i++) {
-
+
String l = completion_hint.get_slice("\n",i);
int len = font->get_string_size(l).x;
max_w = MAX(len,max_w);
@@ -952,35 +972,43 @@ void TextEdit::_notification(int p_what) {
} else {
spacing+=cache.line_spacing;
}
-
-
+
+
}
-
-
-
+
+
+
Size2 size = Size2(max_w,sc*font->get_height()+spacing);
Size2 minsize = size+sb->get_minimum_size();
-
-
+
+
if (completion_hint_offset==-0xFFFF) {
completion_hint_offset=cursor_pos.x-offset;
}
-
-
- Point2 hint_ofs = Vector2(completion_hint_offset,cursor_pos.y-minsize.y);
+
+
+ Point2 hint_ofs = Vector2(completion_hint_offset,cursor_pos.y) + callhint_offset;
+
+ if (callhint_below) {
+ hint_ofs.y += get_row_height() + sb->get_offset().y;
+ }
+ else {
+ hint_ofs.y -= minsize.y + sb->get_offset().y;
+ }
+
draw_style_box(sb,Rect2(hint_ofs,minsize));
-
+
spacing=0;
for(int i=0;i<sc;i++) {
int begin=0;
int end=0;
String l = completion_hint.get_slice("\n",i);
-
+
if (l.find(String::chr(0xFFFF))!=-1) {
begin = font->get_string_size(l.substr(0,l.find(String::chr(0xFFFF)))).x;
end = font->get_string_size(l.substr(0,l.rfind(String::chr(0xFFFF)))).x;
}
-
+
draw_string(font,hint_ofs+sb->get_offset()+Vector2(0,font->get_ascent()+font->get_height()*i+spacing),l.replace(String::chr(0xFFFF),""),font_color);
if (end>0) {
Vector2 b = hint_ofs+sb->get_offset()+Vector2(begin,font->get_height()+font->get_height()*i+spacing-1);
@@ -989,60 +1017,60 @@ void TextEdit::_notification(int p_what) {
spacing+=cache.line_spacing;
}
}
-
-
+
+
} break;
case NOTIFICATION_FOCUS_ENTER: {
-
+
if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->show_virtual_keyboard(get_text(),get_global_rect());
-
+
} break;
case NOTIFICATION_FOCUS_EXIT: {
-
+
if (OS::get_singleton()->has_virtual_keyboard())
OS::get_singleton()->hide_virtual_keyboard();
-
+
} break;
-
+
}
}
void TextEdit::_consume_pair_symbol(CharType ch) {
-
+
int cursor_position_to_move = cursor_get_column() + 1;
-
+
CharType ch_single[2] = {ch, 0};
CharType ch_single_pair[2] = {_get_right_pair_symbol(ch), 0};
CharType ch_pair[3] = {ch, _get_right_pair_symbol(ch), 0};
-
+
if(is_selection_active()) {
-
+
int new_column,new_line;
-
+
_begin_compex_operation();
_insert_text(get_selection_from_line(), get_selection_from_column(),
ch_single,
&new_line, &new_column);
-
+
int to_col_offset = 0;
if(get_selection_from_line() == get_selection_to_line())
to_col_offset = 1;
-
+
_insert_text(get_selection_to_line(),
get_selection_to_column() + to_col_offset,
ch_single_pair,
&new_line,&new_column);
_end_compex_operation();
-
+
cursor_set_line(get_selection_to_line());
cursor_set_column(get_selection_to_column() + to_col_offset);
-
+
deselect();
update();
return;
}
-
+
if( (ch == '\'' || ch == '"') &&
cursor_get_column() > 0 &&
_is_text_char(text[cursor.line][cursor_get_column() - 1])
@@ -1051,7 +1079,7 @@ void TextEdit::_consume_pair_symbol(CharType ch) {
cursor_set_column(cursor_position_to_move);
return;
}
-
+
if(cursor_get_column() < text[cursor.line].length()) {
if(_is_text_char(text[cursor.line][cursor_get_column()])) {
insert_text_at_cursor(ch_single);
@@ -1065,34 +1093,34 @@ void TextEdit::_consume_pair_symbol(CharType ch) {
return;
}
}
-
-
+
+
insert_text_at_cursor(ch_pair);
cursor_set_column(cursor_position_to_move);
return;
-
+
}
void TextEdit::_consume_backspace_for_pair_symbol(int prev_line, int prev_column) {
-
+
bool remove_right_symbol = false;
-
+
if(cursor.column < text[cursor.line].length() && cursor.column > 0) {
-
+
CharType left_char = text[cursor.line][cursor.column - 1];
CharType right_char = text[cursor.line][cursor.column];
-
+
if(right_char == _get_right_pair_symbol(left_char)) {
remove_right_symbol = true;
}
-
+
}
if(remove_right_symbol) {
_remove_text(prev_line,prev_column,cursor.line,cursor.column + 1);
} else {
_remove_text(prev_line,prev_column,cursor.line,cursor.column);
}
-
+
}
void TextEdit::backspace_at_cursor() {
@@ -1101,7 +1129,7 @@ void TextEdit::backspace_at_cursor() {
if (cursor.column==0 && cursor.line==0)
return;
-
+
int prev_line = cursor.column?cursor.line:cursor.line-1;
int prev_column = cursor.column?(cursor.column-1):(text[cursor.line-1].length());
if(auto_brace_completion_enabled &&
@@ -1111,15 +1139,15 @@ void TextEdit::backspace_at_cursor() {
} else {
_remove_text(prev_line,prev_column,cursor.line,cursor.column);
}
-
+
cursor_set_line(prev_line);
cursor_set_column(prev_column);
-
+
}
void TextEdit::_get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) const {
-
+
float rows=p_mouse.y;
rows-=cache.style_normal->get_margin(MARGIN_TOP);
rows/=get_row_height();
@@ -1129,56 +1157,56 @@ void TextEdit::_get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) co
row=0;
int col=0;
-
+
if (row>=text.size()) {
-
+
row=text.size()-1;
col=text[row].size();
} else {
-
+
col=p_mouse.x-(cache.style_normal->get_margin(MARGIN_LEFT)+cache.line_number_w);
col+=cursor.x_ofs;
col=get_char_pos_for( col, get_line(row) );
}
-
+
r_row=row;
r_col=col;
}
void TextEdit::_input_event(const InputEvent& p_input_event) {
-
+
switch(p_input_event.type) {
-
+
case InputEvent::MOUSE_BUTTON: {
-
+
const InputEventMouseButton &mb=p_input_event.mouse_button;
-
+
if (completion_active && completion_rect.has_point(Point2(mb.x,mb.y))) {
-
+
if (!mb.pressed)
return;
-
+
if (mb.button_index==BUTTON_WHEEL_UP) {
if (completion_index>0) {
completion_index--;
completion_current=completion_options[completion_index];
update();
}
-
+
}
if (mb.button_index==BUTTON_WHEEL_DOWN) {
-
+
if (completion_index<completion_options.size()-1) {
completion_index++;
completion_current=completion_options[completion_index];
update();
}
}
-
+
if (mb.button_index==BUTTON_LEFT) {
-
+
completion_index=CLAMP(completion_line_ofs+(mb.y-completion_rect.pos.y)/get_row_height(),0,completion_options.size()-1);
-
+
completion_current=completion_options[completion_index];
update();
if (mb.doubleclick)
@@ -1189,7 +1217,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
_cancel_completion();
_cancel_code_hint();
}
-
+
if (mb.pressed) {
if (mb.button_index==BUTTON_WHEEL_UP) {
v_scroll->set_val( v_scroll->get_val() -3 );
@@ -1204,18 +1232,18 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
h_scroll->set_val( h_scroll->get_val() +3 );
}
if (mb.button_index==BUTTON_LEFT) {
-
+
int row,col;
_get_mouse_pos(Point2i(mb.x,mb.y), row,col);
-
+
int prev_col=cursor.column;
int prev_line=cursor.line;
-
-
-
+
+
+
cursor_set_line( row );
cursor_set_column( col );
-
+
if (mb.mod.shift && (cursor.column!=prev_col || cursor.line!=prev_line)) {
if (!selection.active) {
@@ -1270,99 +1298,99 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
-
+
} else {
-
+
//if sel active and dblick last time < something
-
+
//else
selection.active=false;
selection.selecting_mode=Selection::MODE_POINTER;
selection.selecting_line=row;
selection.selecting_column=col;
}
-
-
+
+
if (!mb.doubleclick && (OS::get_singleton()->get_ticks_msec()-last_dblclk)<600 && cursor.line==prev_line) {
//tripleclick select line
select(cursor.line,0,cursor.line,text[cursor.line].length());
selection.selecting_column=0;
last_dblclk=0;
-
+
} else if (mb.doubleclick && text[cursor.line].length()) {
-
+
//doubleclick select world
String s = text[cursor.line];
int beg=CLAMP(cursor.column,0,s.length());
int end=beg;
-
+
if (s[beg]>32 || beg==s.length()) {
-
+
bool symbol = beg < s.length() && _is_symbol(s[beg]); //not sure if right but most editors behave like this
-
+
while(beg>0 && s[beg-1]>32 && (symbol==_is_symbol(s[beg-1]))) {
beg--;
}
while(end<s.length() && s[end+1]>32 && (symbol==_is_symbol(s[end+1]))) {
end++;
}
-
+
if (end<s.length())
end+=1;
-
+
select(cursor.line,beg,cursor.line,end);
selection.selecting_column=beg;
}
-
+
last_dblclk = OS::get_singleton()->get_ticks_msec();
-
+
}
-
+
update();
}
} else {
if (mb.button_index==BUTTON_LEFT)
click_select_held->stop();
-
+
// notify to show soft keyboard
notification(NOTIFICATION_FOCUS_ENTER);
}
-
+
} break;
case InputEvent::MOUSE_MOTION: {
-
+
const InputEventMouseMotion &mm=p_input_event.mouse_motion;
-
+
if (mm.button_mask&BUTTON_MASK_LEFT) {
-
+
if (selection.selecting_mode!=Selection::MODE_NONE) {
int row,col;
_get_mouse_pos(Point2i(mm.x,mm.y), row,col);
-
+
select(selection.selecting_line,selection.selecting_column,row,col);
-
+
cursor_set_line( row );
cursor_set_column( col );
update();
click_select_held->start();
-
+
}
-
+
}
-
+
} break;
-
+
case InputEvent::KEY: {
-
+
InputEventKey k=p_input_event.key;
-
+
if (!k.pressed)
return;
-
+
if (completion_active) {
if (readonly)
break;
@@ -1370,9 +1398,9 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
bool valid=true;
if (k.mod.command || k.mod.meta)
valid=false;
-
+
if (valid) {
-
+
if (!k.mod.alt) {
if (k.scancode==KEY_UP) {
@@ -1471,13 +1499,13 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
return;
}
}
-
+
if (k.unicode>32) {
-
+
if (cursor.column<text[cursor.line].length() && text[cursor.line][cursor.column]==k.unicode) {
//same char, move ahead
cursor_set_column(cursor.column+1);
-
+
} else {
//different char, go back
const CharType chr[2] = {(CharType)k.unicode, 0};
@@ -1487,34 +1515,34 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
_insert_text_at_cursor(chr);
}
}
-
+
_update_completion_candidates();
accept_event();
-
+
return;
}
}
-
+
_cancel_completion();
-
+
}
-
+
/* TEST CONTROL FIRST!! */
-
+
// some remaps for duplicate functions..
if (k.mod.command && !k.mod.shift && !k.mod.alt && !k.mod.meta && k.scancode==KEY_INSERT) {
-
+
k.scancode=KEY_C;
}
if (!k.mod.command && k.mod.shift && !k.mod.alt && !k.mod.meta && k.scancode==KEY_INSERT) {
-
+
k.scancode=KEY_V;
k.mod.command=true;
k.mod.shift=false;
}
-
+
// stuff to do when selection is active..
-
+
if (selection.active) {
if (readonly)
@@ -1523,16 +1551,16 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
bool clear=false;
bool unselect=false;
bool dobreak=false;
-
+
switch(k.scancode) {
-
+
case KEY_TAB: {
-
+
String txt = _base_get_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
String prev_txt=txt;
-
+
if (k.mod.shift) {
-
+
for(int i=0;i<txt.length();i++) {
if (((i>0 && txt[i-1]=='\n') || (i==0 /*&& selection.from_column==0*/)) && (txt[i]=='\t' || txt[i]==' ')) {
txt.remove(i);
@@ -1540,21 +1568,21 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
}
}
} else {
-
+
for(int i=0;i<txt.length();i++) {
-
+
if (((i>0 && txt[i-1]=='\n') || (i==0 /*&& selection.from_column==0*/))) {
txt=txt.insert(i,"\t");
//i--;
}
}
}
-
+
if (txt!=prev_txt) {
-
+
int sel_line=selection.from_line;
int sel_column=selection.from_column;
-
+
cursor_set_line(selection.from_line);
cursor_set_column(selection.from_column);
_begin_compex_operation();
@@ -1568,10 +1596,10 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
selection.to_line=cursor.line;
update();
}
-
+
dobreak=true;
accept_event();
-
+
} break;
case KEY_X:
case KEY_C:
@@ -1596,21 +1624,21 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
break;
unselect=true;
break;
-
+
default:
if (k.unicode>=32 && !k.mod.command && !k.mod.alt && !k.mod.meta)
clear=true;
if (auto_brace_completion_enabled && _is_pair_left_symbol(k.unicode))
clear=false;
}
-
+
if (unselect) {
selection.active=false;
selection.selecting_mode=Selection::MODE_NONE;
update();
}
if (clear) {
-
+
selection.active=false;
update();
_remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
@@ -1621,15 +1649,15 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
if (dobreak)
break;
}
-
+
selection.selecting_text=false;
-
+
bool scancode_handled=true;
-
+
// special scancode test...
-
+
switch (k.scancode) {
-
+
case KEY_ENTER:
case KEY_RETURN: {
@@ -1637,7 +1665,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
break;
String ins="\n";
-
+
//keep indentation
for(int i=0;i<text[cursor.line].length();i++) {
if (text[cursor.line][i]=='\t')
@@ -1652,33 +1680,54 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
ins+="\t";
}
}
-
+
+ bool first_line = false;
+ if (k.mod.command) {
+ if (k.mod.shift) {
+ if (cursor.line > 0) {
+ cursor_set_line(cursor.line - 1);
+ cursor_set_column(text[cursor.line].length());
+ }
+ else {
+ cursor_set_column(0);
+ first_line = true;
+ }
+ }
+ else {
+ cursor_set_column(text[cursor.line].length());
+ }
+ }
+
_insert_text_at_cursor(ins);
_push_current_op();
-
+
+ if (first_line) {
+ cursor_set_line(0);
+ }
+
} break;
case KEY_ESCAPE: {
if (completion_hint!="") {
completion_hint="";
update();
-
+
}
} break;
case KEY_TAB: {
-
+
if (readonly)
break;
-
+
if (selection.active) {
-
-
+
+
} else {
if (k.mod.shift) {
-
+
int cc = cursor.column;
if (cc>0 && cc<=text[cursor.line].length() && text[cursor.line][cursor.column-1]=='\t') {
//simple unindent
-
+
backspace_at_cursor();
}
} else {
@@ -1686,7 +1735,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
_insert_text_at_cursor("\t");
}
}
-
+
} break;
case KEY_BACKSPACE: {
if (readonly)
@@ -1754,15 +1803,15 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
// numlock disabled. fallthrough to key_left
}
case KEY_LEFT: {
-
+
if (k.mod.shift)
_pre_shift_selection();
-
+
#ifdef APPLE_STYLE_KEYS
if (k.mod.command) {
cursor_set_column(0);
} else if (k.mod.alt) {
-
+
#else
if (k.mod.alt) {
scancode_handled=false;
@@ -1772,21 +1821,21 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
bool prev_char=false;
int cc=cursor.column;
while (cc>0) {
-
+
bool ischar=_is_text_char(text[cursor.line][cc-1]);
-
+
if (prev_char && !ischar)
break;
-
+
prev_char=ischar;
cc--;
-
+
}
-
+
cursor_set_column(cc);
-
+
} else if (cursor.column==0) {
-
+
if (cursor.line>0) {
cursor_set_line(cursor.line-1);
cursor_set_column(text[cursor.line].length());
@@ -1794,10 +1843,10 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
} else {
cursor_set_column(cursor_get_column()-1);
}
-
+
if (k.mod.shift)
_post_shift_selection();
-
+
} break;
case KEY_KP_6: {
if (k.unicode != 0) {
@@ -1807,10 +1856,10 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
// numlock disabled. fallthrough to key_right
}
case KEY_RIGHT: {
-
+
if (k.mod.shift)
_pre_shift_selection();
-
+
#ifdef APPLE_STYLE_KEYS
if (k.mod.command) {
cursor_set_column(text[cursor.line].length());
@@ -1824,19 +1873,19 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
bool prev_char=false;
int cc=cursor.column;
while (cc<text[cursor.line].length()) {
-
+
bool ischar=_is_text_char(text[cursor.line][cc]);
-
+
if (prev_char && !ischar)
break;
prev_char=ischar;
cc++;
}
-
+
cursor_set_column(cc);
-
+
} else if (cursor.column==text[cursor.line].length()) {
-
+
if (cursor.line<text.size()-1) {
cursor_set_line(cursor.line+1);
cursor_set_column(0);
@@ -1844,10 +1893,10 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
} else {
cursor_set_column(cursor_get_column()+1);
}
-
+
if (k.mod.shift)
_post_shift_selection();
-
+
} break;
case KEY_KP_8: {
if (k.unicode != 0) {
@@ -1857,7 +1906,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
// numlock disabled. fallthrough to key_up
}
case KEY_UP: {
-
+
if (k.mod.shift)
_pre_shift_selection();
if (k.mod.alt) {
@@ -1870,11 +1919,11 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
else
#endif
cursor_set_line(cursor_get_line()-1);
-
+
if (k.mod.shift)
_post_shift_selection();
_cancel_code_hint();
-
+
} break;
case KEY_KP_2: {
if (k.unicode != 0) {
@@ -1884,7 +1933,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
// numlock disabled. fallthrough to key_down
}
case KEY_DOWN: {
-
+
if (k.mod.shift)
_pre_shift_selection();
if (k.mod.alt) {
@@ -1897,22 +1946,22 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
else
#endif
cursor_set_line(cursor_get_line()+1);
-
+
if (k.mod.shift)
_post_shift_selection();
_cancel_code_hint();
-
+
} break;
-
+
case KEY_DELETE: {
-
+
if (readonly)
break;
int curline_len = text[cursor.line].length();
-
+
if (cursor.line==text.size()-1 && cursor.column==curline_len)
break; //nothing to do
-
+
int next_line=cursor.column<curline_len?cursor.line:cursor.line+1;
int next_column;
@@ -1980,24 +2029,24 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
}
#ifdef APPLE_STYLE_KEYS
case KEY_HOME: {
-
-
+
+
if (k.mod.shift)
_pre_shift_selection();
-
+
cursor_set_line(0);
-
+
if (k.mod.shift)
_post_shift_selection();
-
+
} break;
#else
case KEY_HOME: {
-
-
+
+
if (k.mod.shift)
_pre_shift_selection();
-
+
// compute whitespace symbols seq length
int current_line_whitespace_len = 0;
while(current_line_whitespace_len < text[cursor.line].length()) {
@@ -2006,20 +2055,20 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
break;
current_line_whitespace_len++;
}
-
+
if(cursor_get_column() == current_line_whitespace_len)
cursor_set_column(0);
else
cursor_set_column(current_line_whitespace_len);
-
+
if (k.mod.command)
cursor_set_line(0);
-
+
if (k.mod.shift)
_post_shift_selection();
_cancel_completion();
completion_hint="";
-
+
} break;
#endif
case KEY_KP_1: {
@@ -2043,20 +2092,20 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
} break;
#else
case KEY_END: {
-
+
if (k.mod.shift)
_pre_shift_selection();
-
+
if (k.mod.command)
cursor_set_line(text.size()-1);
cursor_set_column(text[cursor.line].length());
-
+
if (k.mod.shift)
_post_shift_selection();
_cancel_completion();
completion_hint="";
-
+
} break;
#endif
case KEY_KP_9: {
@@ -2067,19 +2116,19 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
// numlock disabled. fallthrough to key_pageup
}
case KEY_PAGEUP: {
-
+
if (k.mod.shift)
_pre_shift_selection();
-
+
cursor_set_line(cursor_get_line()-get_visible_rows());
-
+
if (k.mod.shift)
_post_shift_selection();
_cancel_completion();
completion_hint="";
-
+
} break;
case KEY_KP_3: {
if (k.unicode != 0) {
@@ -2089,75 +2138,75 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
// numlock disabled. fallthrough to key_pageup
}
case KEY_PAGEDOWN: {
-
+
if (k.mod.shift)
_pre_shift_selection();
-
+
cursor_set_line(cursor_get_line()+get_visible_rows());
-
+
if (k.mod.shift)
_post_shift_selection();
_cancel_completion();
completion_hint="";
-
+
} break;
case KEY_A: {
-
+
if (!k.mod.command || k.mod.shift || k.mod.alt) {
scancode_handled=false;
break;
}
-
+
select_all();
-
+
} break;
case KEY_X: {
-
+
if (!k.mod.command || k.mod.shift || k.mod.alt) {
scancode_handled=false;
break;
}
-
+
if (!selection.active){
-
+
String clipboard = text[cursor.line];
OS::get_singleton()->set_clipboard(clipboard);
cursor_set_line(cursor.line);
cursor_set_column(0);
_remove_text(cursor.line,0,cursor.line,text[cursor.line].length());
-
+
backspace_at_cursor();
update();
cursor_set_line(cursor.line+1);
cut_copy_line = true;
-
+
}
else
{
-
+
String clipboard = _base_get_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
OS::get_singleton()->set_clipboard(clipboard);
-
+
cursor_set_line(selection.from_line);
cursor_set_column(selection.from_column);
-
+
_remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
selection.active=false;
selection.selecting_mode=Selection::MODE_NONE;
update();
cut_copy_line = false;
}
-
+
} break;
case KEY_C: {
-
+
if (!k.mod.command || k.mod.shift || k.mod.alt) {
scancode_handled=false;
break;
}
-
+
if (!selection.active){
String clipboard = _base_get_text(cursor.line,0,cursor.line,text[cursor.line].length());
OS::get_singleton()->set_clipboard(clipboard);
@@ -2170,32 +2219,32 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
}
} break;
case KEY_Z: {
-
+
if (!k.mod.command) {
scancode_handled=false;
break;
}
-
+
if (k.mod.shift)
redo();
else
undo();
} break;
case KEY_V: {
-
+
if (!k.mod.command || k.mod.shift || k.mod.alt) {
scancode_handled=false;
break;
}
-
+
String clipboard = OS::get_singleton()->get_clipboard();
-
+
if (selection.active) {
selection.active=false;
_remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
cursor_set_line(selection.from_line);
cursor_set_column(selection.from_column);
-
+
}
else if (cut_copy_line)
{
@@ -2203,9 +2252,9 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
String ins="\n";
clipboard += ins;
}
-
+
_insert_text_at_cursor(clipboard);
-
+
update();
} break;
case KEY_SPACE: {
@@ -2214,15 +2263,15 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
#else
if (completion_enabled && k.mod.command) {
#endif
-
+
query_code_comple();
scancode_handled=true;
} else {
scancode_handled=false;
}
-
+
} break;
-
+
case KEY_U:{
if (!k.mod.command || k.mod.shift) {
scancode_handled=false;
@@ -2245,40 +2294,40 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
update();
}
break;}
-
+
default: {
-
+
scancode_handled=false;
} break;
-
+
}
-
+
if (scancode_handled)
accept_event();
/*
if (!scancode_handled && !k.mod.command && !k.mod.alt) {
-
+
if (k.unicode>=32) {
-
+
if (readonly)
break;
-
+
accept_event();
} else {
-
+
break;
}
}
*/
if (!scancode_handled && !k.mod.command) { //for german kbds
-
+
if (k.unicode>=32) {
-
+
if (readonly)
break;
-
+
const CharType chr[2] = {(CharType)k.unicode, 0};
-
+
if (completion_hint!="" && k.unicode==')') {
completion_hint="";
}
@@ -2287,27 +2336,27 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
} else {
_insert_text_at_cursor(chr);
}
-
+
accept_event();
} else {
-
+
break;
}
}
-
+
return;
} break;
-
+
}
-
+
}
void TextEdit::_pre_shift_selection() {
-
-
+
+
if (!selection.active || selection.selecting_mode==Selection::MODE_NONE) {
-
+
selection.selecting_line=cursor.line;
selection.selecting_column=cursor.column;
selection.active=true;
@@ -2317,115 +2366,115 @@ void TextEdit::_pre_shift_selection() {
}
void TextEdit::_post_shift_selection() {
-
-
+
+
if (selection.active && selection.selecting_mode==Selection::MODE_SHIFT) {
-
+
select(selection.selecting_line,selection.selecting_column,cursor.line,cursor.column);
update();
}
-
-
+
+
selection.selecting_text=true;
}
/**** TEXT EDIT CORE API ****/
void TextEdit::_base_insert_text(int p_line, int p_char,const String& p_text,int &r_end_line,int &r_end_column) {
-
+
//save for undo...
ERR_FAIL_INDEX(p_line,text.size());
ERR_FAIL_COND(p_char<0);
-
+
/* STEP 1 add spaces if the char is greater than the end of the line */
while(p_char>text[p_line].length()) {
-
+
text.set(p_line,text[p_line]+String::chr(' '));
}
-
+
/* STEP 2 separate dest string in pre and post text */
-
+
String preinsert_text = text[p_line].substr(0,p_char);
String postinsert_text = text[p_line].substr(p_char,text[p_line].size());
-
+
/* STEP 3 remove \r from source text and separate in substrings */
-
+
//buh bye \r and split
Vector<String> substrings = p_text.replace("\r","").split("\n");
-
-
+
+
for(int i=0;i<substrings.size();i++) {
//insert the substrings
-
+
if (i==0) {
-
+
text.set(p_line,preinsert_text+substrings[i]);
} else {
-
+
text.insert(p_line+i,substrings[i]);
}
-
+
if (i==substrings.size()-1){
-
+
text.set(p_line+i,text[p_line+i]+postinsert_text);
}
}
-
+
r_end_line=p_line+substrings.size()-1;
r_end_column=text[r_end_line].length()-postinsert_text.length();
-
+
if (!text_changed_dirty && !setting_text) {
if (is_inside_tree())
MessageQueue::get_singleton()->push_call(this,"_text_changed_emit");
text_changed_dirty=true;
}
-
+
}
String TextEdit::_base_get_text(int p_from_line, int p_from_column,int p_to_line,int p_to_column) const {
-
+
ERR_FAIL_INDEX_V(p_from_line,text.size(),String());
ERR_FAIL_INDEX_V(p_from_column,text[p_from_line].length()+1,String());
ERR_FAIL_INDEX_V(p_to_line,text.size(),String());
ERR_FAIL_INDEX_V(p_to_column,text[p_to_line].length()+1,String());
ERR_FAIL_COND_V(p_to_line < p_from_line ,String()); // from > to
ERR_FAIL_COND_V(p_to_line == p_from_line && p_to_column<p_from_column,String()); // from > to
-
+
String ret;
-
+
for(int i=p_from_line;i<=p_to_line;i++) {
-
+
int begin = (i==p_from_line)?p_from_column:0;
int end = (i==p_to_line)?p_to_column:text[i].length();
-
+
if (i>p_from_line)
ret+="\n";
ret+=text[i].substr(begin,end-begin);
}
-
+
return ret;
}
void TextEdit::_base_remove_text(int p_from_line, int p_from_column,int p_to_line,int p_to_column) {
-
+
ERR_FAIL_INDEX(p_from_line,text.size());
ERR_FAIL_INDEX(p_from_column,text[p_from_line].length()+1);
ERR_FAIL_INDEX(p_to_line,text.size());
ERR_FAIL_INDEX(p_to_column,text[p_to_line].length()+1);
ERR_FAIL_COND(p_to_line < p_from_line ); // from > to
ERR_FAIL_COND(p_to_line == p_from_line && p_to_column<p_from_column); // from > to
-
-
+
+
String pre_text = text[p_from_line].substr(0,p_from_column);
String post_text = text[p_to_line].substr(p_to_column,text[p_to_line].length());
-
+
for(int i=p_from_line;i<p_to_line;i++) {
-
+
text.remove(p_from_line+1);
}
-
+
text.set(p_from_line,pre_text+post_text);
-
+
if (!text_changed_dirty && !setting_text) {
if (is_inside_tree())
MessageQueue::get_singleton()->push_call(this,"_text_changed_emit");
@@ -2434,24 +2483,24 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column,int p_to_lin
}
void TextEdit::_insert_text(int p_line, int p_char,const String& p_text,int *r_end_line,int *r_end_column) {
-
+
if (!setting_text)
idle_detect->start();
-
+
if (undo_enabled) {
_clear_redo();
}
-
+
int retline,retchar;
_base_insert_text(p_line,p_char,p_text,retline,retchar);
if (r_end_line)
*r_end_line=retline;
if (r_end_column)
*r_end_column=retchar;
-
+
if (!undo_enabled)
return;
-
+
/* UNDO!! */
TextOperation op;
op.type=TextOperation::TYPE_INSERT;
@@ -2463,45 +2512,47 @@ void TextEdit::_insert_text(int p_line, int p_char,const String& p_text,int *r_e
op.version=++version;
op.chain_forward=false;
op.chain_backward=false;
-
+
//see if it shold just be set as current op
if (current_op.type!=op.type) {
+ op.prev_version = get_version();
_push_current_op();
current_op=op;
-
+
return; //set as current op, return
}
//see if it can be merged
if (current_op.to_line!=p_line || current_op.to_column!=p_char) {
+ op.prev_version = get_version();
_push_current_op();
current_op=op;
return; //set as current op, return
}
//merge current op
-
+
current_op.text+=p_text;
current_op.to_column=retchar;
current_op.to_line=retline;
current_op.version=op.version;
-
+
}
void TextEdit::_remove_text(int p_from_line, int p_from_column,int p_to_line,int p_to_column) {
-
+
if (!setting_text)
idle_detect->start();
-
+
String text;
if (undo_enabled) {
_clear_redo();
text=_base_get_text(p_from_line,p_from_column,p_to_line,p_to_column);
}
-
+
_base_remove_text(p_from_line,p_from_column,p_to_line,p_to_column);
-
+
if (!undo_enabled)
return;
-
+
/* UNDO!! */
TextOperation op;
op.type=TextOperation::TYPE_REMOVE;
@@ -2513,9 +2564,10 @@ void TextEdit::_remove_text(int p_from_line, int p_from_column,int p_to_line,int
op.version=++version;
op.chain_forward=false;
op.chain_backward=false;
-
+
//see if it shold just be set as current op
if (current_op.type!=op.type) {
+ op.prev_version = get_version();
_push_current_op();
current_op=op;
return; //set as current op, return
@@ -2529,26 +2581,27 @@ void TextEdit::_remove_text(int p_from_line, int p_from_column,int p_to_line,int
return; //update current op
}
if (current_op.from_line==p_from_line && current_op.from_column==p_from_column) {
-
+
//current_op.text=text+current_op.text;
//current_op.from_line=p_from_line;
//current_op.from_column=p_from_column;
//return; //update current op
}
-
+
+ op.prev_version = get_version();
_push_current_op();
current_op=op;
-
+
}
void TextEdit::_insert_text_at_cursor(const String& p_text) {
-
+
int new_column,new_line;
_insert_text(cursor.line,cursor.column,p_text,&new_line,&new_column);
cursor_set_line(new_line);
cursor_set_column(new_column);
-
+
update();
}
@@ -2556,144 +2609,144 @@ void TextEdit::_insert_text_at_cursor(const String& p_text) {
int TextEdit::get_char_count() {
-
+
int totalsize=0;
-
+
for (int i=0;i<text.size();i++) {
-
+
if (i>0)
totalsize++; // incliude \n
totalsize+=text[i].length();
}
-
+
return totalsize; // omit last \n
}
Size2 TextEdit::get_minimum_size() {
-
+
return cache.style_normal->get_minimum_size();
}
int TextEdit::get_visible_rows() const {
-
+
int total=cache.size.height;
total-=cache.style_normal->get_minimum_size().height;
total/=get_row_height();
return total;
}
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;
if (v_scroll->is_visible())
visible_width-=v_scroll->get_combined_minimum_size().width;
visible_width-=20; // give it a little more space
-
-
+
+
//printf("rowofs %i, visrows %i, cursor.line %i\n",cursor.line_ofs,get_visible_rows(),cursor.line);
-
+
int visible_rows = get_visible_rows();
if (h_scroll->is_visible())
visible_rows-=((h_scroll->get_combined_minimum_size().height-1)/get_row_height());
-
+
if (cursor.line>=(cursor.line_ofs+visible_rows))
cursor.line_ofs=cursor.line-visible_rows+1;
if (cursor.line<cursor.line_ofs)
cursor.line_ofs=cursor.line;
-
+
int cursor_x = get_column_x_offset( cursor.column, text[cursor.line] );
-
+
if (cursor_x>(cursor.x_ofs+visible_width))
cursor.x_ofs=cursor_x-visible_width+1;
-
+
if (cursor_x < cursor.x_ofs)
cursor.x_ofs=cursor_x;
-
+
update();
/*
get_range()->set_max(text.size());
-
+
get_range()->set_page(get_visible_rows());
-
+
get_range()->set((int)cursor.line_ofs);
*/
-
-
+
+
}
void TextEdit::cursor_set_column(int p_col, bool p_adjust_viewport) {
-
+
if (p_col<0)
p_col=0;
-
+
cursor.column=p_col;
if (cursor.column > get_line( cursor.line ).length())
cursor.column=get_line( cursor.line ).length();
-
+
cursor.last_fit_x=get_column_x_offset(cursor.column,get_line(cursor.line));
-
+
if (p_adjust_viewport)
adjust_viewport_to_cursor();
-
+
if (!cursor_changed_dirty) {
if (is_inside_tree())
MessageQueue::get_singleton()->push_call(this,"_cursor_changed_emit");
cursor_changed_dirty=true;
}
-
+
}
void TextEdit::cursor_set_line(int p_row, bool p_adjust_viewport) {
-
+
if (setting_row)
return;
-
+
setting_row=true;
if (p_row<0)
p_row=0;
-
-
+
+
if (p_row>=(int)text.size())
p_row=(int)text.size()-1;
-
+
cursor.line=p_row;
cursor.column=get_char_pos_for( cursor.last_fit_x, get_line( cursor.line) );
-
+
if (p_adjust_viewport)
adjust_viewport_to_cursor();
-
+
setting_row=false;
-
-
+
+
if (!cursor_changed_dirty) {
if (is_inside_tree())
MessageQueue::get_singleton()->push_call(this,"_cursor_changed_emit");
cursor_changed_dirty=true;
}
-
+
}
int TextEdit::cursor_get_column() const {
-
+
return cursor.column;
}
int TextEdit::cursor_get_line() const {
-
+
return cursor.line;
}
void TextEdit::_scroll_moved(double p_to_val) {
-
+
if (updating_scrolls)
return;
-
+
if (h_scroll->is_visible())
cursor.x_ofs=h_scroll->get_val();
if (v_scroll->is_visible())
@@ -2706,87 +2759,87 @@ void TextEdit::_scroll_moved(double p_to_val) {
int TextEdit::get_row_height() const {
-
+
return cache.font->get_height()+cache.line_spacing;
}
int TextEdit::get_char_pos_for(int p_px,String p_str) const {
-
+
int px=0;
int c=0;
-
+
int tab_w = cache.font->get_char_size(' ').width*tab_size;
-
+
while (c<p_str.length()) {
-
+
int w=0;
-
+
if (p_str[c]=='\t') {
-
+
int left = px%tab_w;
if (left==0)
w=tab_w;
else
w=tab_w-px%tab_w; // is right...
-
+
} else {
-
+
w=cache.font->get_char_size(p_str[c],p_str[c+1]).width;
}
-
+
if (p_px<(px+w/2))
break;
px+=w;
c++;
}
-
+
return c;
}
int TextEdit::get_column_x_offset(int p_char,String p_str) {
-
+
int px=0;
-
+
int tab_w = cache.font->get_char_size(' ').width*tab_size;
-
+
for (int i=0;i<p_char;i++) {
-
+
if (i>=p_str.length())
break;
-
+
if (p_str[i]=='\t') {
-
+
int left = px%tab_w;
if (left==0)
px+=tab_w;
else
px+=tab_w-px%tab_w; // is right...
-
+
} else {
px+=cache.font->get_char_size(p_str[i],p_str[i+1]).width;
}
}
-
+
return px;
-
+
}
void TextEdit::insert_text_at_cursor(const String& p_text) {
-
+
if (selection.active) {
-
+
cursor_set_line(selection.from_line);
cursor_set_column(selection.from_column);
-
+
_remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
selection.active=false;
selection.selecting_mode=Selection::MODE_NONE;
-
+
}
-
+
_insert_text_at_cursor(p_text);
update();
-
+
}
Control::CursorShape TextEdit::get_cursor_shape(const Point2& p_pos) const {
@@ -2798,7 +2851,7 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2& p_pos) const {
void TextEdit::set_text(String p_text){
-
+
setting_text=true;
clear();
_insert_text_at_cursor(p_text);
@@ -2812,7 +2865,7 @@ void TextEdit::set_text(String p_text){
cursor_set_column(0);
update();
setting_text=false;
-
+
//get_range()->set(0);
};
@@ -2820,53 +2873,53 @@ String TextEdit::get_text() {
String longthing;
int len = text.size();
for (int i=0;i<len;i++) {
-
-
+
+
longthing+=text[i];
if (i!=len-1)
longthing+="\n";
}
-
+
return longthing;
-
+
};
String TextEdit::get_text_for_completion() {
-
+
String longthing;
int len = text.size();
for (int i=0;i<len;i++) {
-
+
if (i==cursor.line) {
longthing+=text[i].substr(0,cursor.column);
longthing+=String::chr(0xFFFF); //not unicode, represents the cursor
longthing+=text[i].substr(cursor.column,text[i].size());
} else {
-
+
longthing+=text[i];
}
-
-
+
+
if (i!=len-1)
longthing+="\n";
}
-
+
return longthing;
-
+
};
String TextEdit::get_line(int line) const {
-
+
if (line<0 || line>=text.size())
return "";
-
+
return text[line];
-
+
};
void TextEdit::_clear() {
-
+
clear_undo_history();
text.clear();
cursor.column=0;
@@ -2879,31 +2932,31 @@ void TextEdit::_clear() {
void TextEdit::clear() {
-
+
setting_text=true;
_clear();
setting_text=false;
-
+
};
void TextEdit::set_readonly(bool p_readonly) {
-
-
+
+
readonly=p_readonly;
}
void TextEdit::set_wrap(bool p_wrap) {
-
+
wrap=p_wrap;
}
void TextEdit::set_max_chars(int p_max_chars) {
-
+
max_chars=p_max_chars;
}
void TextEdit::_update_caches() {
-
+
cache.style_normal=get_stylebox("normal");
cache.style_focus=get_stylebox("focus");
cache.font=get_font("font");
@@ -2919,12 +2972,12 @@ void TextEdit::_update_caches() {
cache.row_height = cache.font->get_height() + cache.line_spacing;
cache.tab_icon=get_icon("tab");
text.set_font(cache.font);
-
+
}
void TextEdit::clear_colors() {
-
+
keywords.clear();
color_regions.clear();;
text.clear_caches();
@@ -2932,40 +2985,40 @@ void TextEdit::clear_colors() {
}
void TextEdit::set_custom_bg_color(const Color& p_color) {
-
+
custom_bg_color=p_color;
update();
}
void TextEdit::add_keyword_color(const String& p_keyword,const Color& p_color) {
-
+
keywords[p_keyword]=p_color;
update();
-
+
}
void TextEdit::add_color_region(const String& p_begin_key,const String& p_end_key,const Color &p_color,bool p_line_only) {
-
+
color_regions.push_back(ColorRegion(p_begin_key,p_end_key,p_color,p_line_only));
text.clear_caches();
update();
-
+
}
void TextEdit::set_symbol_color(const Color& p_color) {
-
+
symbol_color=p_color;
update();
}
void TextEdit::set_syntax_coloring(bool p_enabled) {
-
+
syntax_coloring=p_enabled;
update();
}
bool TextEdit::is_syntax_coloring_enabled() const {
-
+
return syntax_coloring;
}
@@ -2974,28 +3027,28 @@ void TextEdit::set_auto_indent(bool p_auto_indent) {
}
void TextEdit::cut() {
-
+
if (!selection.active)
return;
-
+
String clipboard = _base_get_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
OS::get_singleton()->set_clipboard(clipboard);
-
+
cursor_set_line(selection.from_line);
cursor_set_column(selection.from_column);
-
+
_remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
selection.active=false;
selection.selecting_mode=Selection::MODE_NONE;
update();
-
+
}
void TextEdit::copy() {
-
+
if (!selection.active)
return;
-
+
print_line("from line: "+itos(selection.from_line));
print_line("from column: "+itos(selection.from_column));
print_line("to line: "+itos(selection.to_line));
@@ -3003,29 +3056,29 @@ void TextEdit::copy() {
String clipboard = _base_get_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
OS::get_singleton()->set_clipboard(clipboard);
-
+
}
void TextEdit::paste() {
-
+
if (selection.active) {
-
+
cursor_set_line(selection.from_line);
cursor_set_column(selection.from_column);
-
+
_remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
selection.active=false;
selection.selecting_mode=Selection::MODE_NONE;
-
+
}
-
+
String clipboard = OS::get_singleton()->get_clipboard();
_insert_text_at_cursor(clipboard);
update();
-
+
}
void TextEdit::select_all() {
-
+
if (text.size()==1 && text[0].length()==0)
return;
selection.active=true;
@@ -3040,43 +3093,43 @@ void TextEdit::select_all() {
cursor_set_line( selection.to_line, false );
cursor_set_column( selection.to_column, false );
update();
-
+
}
void TextEdit::deselect() {
-
+
selection.active=false;
update();
}
void TextEdit::select(int p_from_line,int p_from_column,int p_to_line,int p_to_column) {
-
+
if (p_from_line>=text.size())
p_from_line=text.size()-1;
if (p_from_column>=text[p_from_line].length())
p_from_column=text[p_from_line].length();
-
+
if (p_to_line>=text.size())
p_to_line=text.size()-1;
if (p_to_column>=text[p_to_line].length())
p_to_column=text[p_to_line].length();
-
+
selection.from_line=p_from_line;
selection.from_column=p_from_column;
selection.to_line=p_to_line;
selection.to_column=p_to_column;
-
+
selection.active=true;
-
+
if (selection.from_line==selection.to_line) {
-
+
if (selection.from_column==selection.to_column) {
-
+
selection.active=false;
-
+
} else if (selection.from_column>selection.to_column) {
-
+
selection.shiftclick_left = false;
SWAP( selection.from_column, selection.to_column );
} else {
@@ -3084,7 +3137,7 @@ void TextEdit::select(int p_from_line,int p_from_column,int p_to_line,int p_to_c
selection.shiftclick_left = true;
}
} else if (selection.from_line>selection.to_line) {
-
+
selection.shiftclick_left = false;
SWAP( selection.from_line, selection.to_line );
SWAP( selection.from_column, selection.to_column );
@@ -3092,51 +3145,51 @@ void TextEdit::select(int p_from_line,int p_from_column,int p_to_line,int p_to_c
selection.shiftclick_left = true;
}
-
-
+
+
update();
}
bool TextEdit::is_selection_active() const {
-
+
return selection.active;
}
int TextEdit::get_selection_from_line() const {
-
+
ERR_FAIL_COND_V(!selection.active,-1);
return selection.from_line;
-
+
}
int TextEdit::get_selection_from_column() const {
-
+
ERR_FAIL_COND_V(!selection.active,-1);
return selection.from_column;
-
+
}
int TextEdit::get_selection_to_line() const {
-
+
ERR_FAIL_COND_V(!selection.active,-1);
return selection.to_line;
-
+
}
int TextEdit::get_selection_to_column() const {
-
+
ERR_FAIL_COND_V(!selection.active,-1);
return selection.to_column;
-
+
}
String TextEdit::get_selection_text() const {
-
+
if (!selection.active)
return "";
-
+
return _base_get_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column);
-
+
}
String TextEdit::get_word_under_cursor() const {
-
+
int prev_cc = cursor.column;
while(prev_cc >0) {
bool is_char = _is_text_char(text[cursor.line][prev_cc-1]);
@@ -3144,7 +3197,7 @@ String TextEdit::get_word_under_cursor() const {
break;
--prev_cc;
}
-
+
int next_cc = cursor.column;
while(next_cc<text[cursor.line].length()) {
bool is_char = _is_text_char(text[cursor.line][next_cc]);
@@ -3158,7 +3211,7 @@ String TextEdit::get_word_under_cursor() const {
}
DVector<int> TextEdit::_search_bind(const String &p_key,uint32_t p_search_flags, int p_from_line,int p_from_column) const {
-
+
int col,line;
if (search(p_key,p_search_flags,p_from_line,p_from_column,col,line)) {
DVector<int> result;
@@ -3166,46 +3219,46 @@ DVector<int> TextEdit::_search_bind(const String &p_key,uint32_t p_search_flags,
result.set(0,line);
result.set(1,col);
return result;
-
+
} else {
-
+
return DVector<int>();
}
}
bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_line, int p_from_column,int &r_line,int &r_column) const {
-
+
if (p_key.length()==0)
return false;
ERR_FAIL_INDEX_V(p_from_line,text.size(),false);
ERR_FAIL_INDEX_V(p_from_column,text[p_from_line].length()+1,false);
-
+
//search through the whole documment, but start by current line
-
+
int line=-1;
int pos=-1;
-
+
line=p_from_line;
-
+
for(int i=0;i<text.size()+1;i++) {
//backwards is broken...
//int idx=(p_search_flags&SEARCH_BACKWARDS)?(text.size()-i):i; //do backwards seearch
-
-
+
+
if (line<0) {
line=text.size()-1;
}
if (line==text.size()) {
line=0;
}
-
+
String text_line = text[line];
int from_column=0;
if (line==p_from_line) {
-
+
if (i==text.size()) {
//wrapped
-
+
if (p_search_flags&SEARCH_BACKWARDS) {
text_line=text_line.substr(from_column,text_line.length());
from_column=text_line.length();
@@ -3213,13 +3266,13 @@ bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_li
text_line=text_line.substr(0,from_column);
from_column=0;
}
-
+
} else {
-
+
from_column=p_from_column;
}
-
-
+
+
} else {
//text_line=text_line.substr(0,p_from_column); //wrap around for missing begining.
if (p_search_flags&SEARCH_BACKWARDS)
@@ -3227,17 +3280,17 @@ bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_li
else
from_column=0;
}
-
+
pos=-1;
-
+
if (!(p_search_flags&SEARCH_BACKWARDS)) {
-
+
pos = (p_search_flags&SEARCH_MATCH_CASE)?text_line.find(p_key,from_column):text_line.findn(p_key,from_column);
} else {
-
+
pos = (p_search_flags&SEARCH_MATCH_CASE)?text_line.rfind(p_key,from_column):text_line.rfindn(p_key,from_column);
}
-
+
if (pos!=-1 && (p_search_flags&SEARCH_WHOLE_WORDS)) {
//validate for whole words
if (pos>0 && _is_text_char(text_line[pos-1]))
@@ -3245,66 +3298,66 @@ bool TextEdit::search(const String &p_key,uint32_t p_search_flags, int p_from_li
else if (_is_text_char(text_line[pos+p_key.length()]))
pos=-1;
}
-
+
if (pos!=-1)
break;
-
+
if (p_search_flags&SEARCH_BACKWARDS)
line--;
else
line++;
-
+
}
-
+
if (pos==-1) {
r_line=-1;
r_column=-1;
return false;
}
-
+
r_line=line;
r_column=pos;
-
-
+
+
return true;
}
void TextEdit::_cursor_changed_emit() {
-
+
emit_signal("cursor_changed");
cursor_changed_dirty=false;
}
void TextEdit::_text_changed_emit() {
-
+
emit_signal("text_changed");
text_changed_dirty=false;
}
void TextEdit::set_line_as_marked(int p_line,bool p_marked) {
-
+
ERR_FAIL_INDEX(p_line,text.size());
text.set_marked(p_line,p_marked);
update();
}
bool TextEdit::is_line_set_as_breakpoint(int p_line) const {
-
+
ERR_FAIL_INDEX_V(p_line,text.size(),false);
return text.is_breakpoint(p_line);
-
+
}
void TextEdit::set_line_as_breakpoint(int p_line,bool p_breakpoint) {
-
-
+
+
ERR_FAIL_INDEX(p_line,text.size());
text.set_breakpoint(p_line,p_breakpoint);
update();
}
void TextEdit::get_breakpoints(List<int> *p_breakpoints) const {
-
+
for(int i=0;i<text.size();i++) {
if (text.is_breakpoint(i))
p_breakpoints->push_back(i);
@@ -3312,39 +3365,39 @@ void TextEdit::get_breakpoints(List<int> *p_breakpoints) const {
}
int TextEdit::get_line_count() const {
-
+
return text.size();
}
void TextEdit::_do_text_op(const TextOperation& p_op, bool p_reverse) {
-
+
ERR_FAIL_COND(p_op.type==TextOperation::TYPE_NONE);
-
+
bool insert = p_op.type==TextOperation::TYPE_INSERT;
if (p_reverse)
insert=!insert;
-
+
if (insert) {
-
+
int check_line;
int check_column;
_base_insert_text(p_op.from_line,p_op.from_column,p_op.text,check_line,check_column);
ERR_FAIL_COND( check_line != p_op.to_line ); // BUG
ERR_FAIL_COND( check_column != p_op.to_column ); // BUG
} else {
-
+
_base_remove_text(p_op.from_line,p_op.from_column,p_op.to_line,p_op.to_column);
}
-
+
}
void TextEdit::_clear_redo() {
-
+
if (undo_stack_pos==NULL)
return; //nothing to clear
-
+
_push_current_op();
-
+
while (undo_stack_pos) {
List<TextOperation>::Element *elem = undo_stack_pos;
undo_stack_pos=undo_stack_pos->next();
@@ -3354,61 +3407,69 @@ void TextEdit::_clear_redo() {
void TextEdit::undo() {
-
+
_push_current_op();
-
+
if (undo_stack_pos==NULL) {
-
+
if (!undo_stack.size())
return; //nothing to undo
-
+
undo_stack_pos=undo_stack.back();
-
+
} else if (undo_stack_pos==undo_stack.front())
return; // at the bottom of the undo stack
else
undo_stack_pos=undo_stack_pos->prev();
-
- _do_text_op( undo_stack_pos->get(),true);
+
+ TextOperation op = undo_stack_pos->get();
+ _do_text_op(op, true);
+ current_op.version=op.prev_version;
if(undo_stack_pos->get().chain_backward) {
do {
undo_stack_pos = undo_stack_pos->prev();
- _do_text_op(undo_stack_pos->get(), true);
+ op = undo_stack_pos->get();
+ _do_text_op(op, true);
+ current_op.version = op.prev_version;
} while(!undo_stack_pos->get().chain_forward);
}
-
+
cursor_set_line(undo_stack_pos->get().from_line);
cursor_set_column(undo_stack_pos->get().from_column);
update();
}
void TextEdit::redo() {
-
+
_push_current_op();
-
+
if (undo_stack_pos==NULL)
return; //nothing to do.
-
- _do_text_op(undo_stack_pos->get(), false);
+
+ TextOperation op = undo_stack_pos->get();
+ _do_text_op(op, false);
+ current_op.version = op.version;
if(undo_stack_pos->get().chain_forward) {
do {
undo_stack_pos=undo_stack_pos->next();
- _do_text_op(undo_stack_pos->get(), false);
+ op = undo_stack_pos->get();
+ _do_text_op(op, false);
+ current_op.version = op.version;
} while(!undo_stack_pos->get().chain_backward);
}
- cursor_set_line(undo_stack_pos->get().from_line);
- cursor_set_column(undo_stack_pos->get().from_column);
+ cursor_set_line(undo_stack_pos->get().to_line);
+ cursor_set_column(undo_stack_pos->get().to_column);
undo_stack_pos=undo_stack_pos->next();
update();
}
void TextEdit::clear_undo_history() {
-
+
saved_version=0;
current_op.type=TextOperation::TYPE_NONE;
undo_stack_pos=NULL;
undo_stack.clear();
-
+
}
void TextEdit::_begin_compex_operation() {
@@ -3417,42 +3478,49 @@ void TextEdit::_begin_compex_operation() {
}
void TextEdit::_end_compex_operation() {
-
+
_push_current_op();
ERR_FAIL_COND(undo_stack.size() == 0);
-
+
if(undo_stack.back()->get().chain_forward) {
undo_stack.back()->get().chain_forward=false;
return;
}
-
+
undo_stack.back()->get().chain_backward=true;
}
void TextEdit::_push_current_op() {
-
+
if (current_op.type==TextOperation::TYPE_NONE)
return; // do nothing
-
+
if(next_operation_is_complex) {
current_op.chain_forward=true;
next_operation_is_complex=false;
}
-
+
undo_stack.push_back(current_op);
current_op.type=TextOperation::TYPE_NONE;
current_op.text="";
current_op.chain_forward=false;
-
+
+}
+
+void TextEdit::set_tab_size(const int p_size) {
+ ERR_FAIL_COND(p_size <= 0);
+ tab_size = p_size;
+ text.set_tab_size(p_size);
+ update();
}
void TextEdit::set_draw_tabs(bool p_draw) {
-
+
draw_tabs=p_draw;
}
bool TextEdit::is_drawing_tabs() const{
-
+
return draw_tabs;
}
@@ -3460,35 +3528,35 @@ uint32_t TextEdit::get_version() const {
return current_op.version;
}
uint32_t TextEdit::get_saved_version() const {
-
+
return saved_version;
}
void TextEdit::tag_saved_version() {
-
+
saved_version=get_version();
}
int TextEdit::get_v_scroll() const {
-
+
return v_scroll->get_val();
}
void TextEdit::set_v_scroll(int p_scroll) {
-
+
v_scroll->set_val(p_scroll);
cursor.line_ofs=p_scroll;
}
int TextEdit::get_h_scroll() const {
-
+
return h_scroll->get_val();
}
void TextEdit::set_h_scroll(int p_scroll) {
-
+
h_scroll->set_val(p_scroll);
}
void TextEdit::set_completion(bool p_enabled,const Vector<String>& p_prefixes) {
-
+
completion_prefixes.clear();
completion_enabled=p_enabled;
for(int i=0;i<p_prefixes.size();i++)
@@ -3496,7 +3564,7 @@ void TextEdit::set_completion(bool p_enabled,const Vector<String>& p_prefixes) {
}
void TextEdit::_confirm_completion() {
-
+
String remaining=completion_current.substr(completion_base.length(),completion_current.length()-completion_base.length());
String l = text[cursor.line];
bool same=true;
@@ -3508,7 +3576,7 @@ void TextEdit::_confirm_completion() {
break;
}
}
-
+
if (same)
cursor_set_column(cursor.column+remaining.length());
else {
@@ -3518,7 +3586,7 @@ void TextEdit::_confirm_completion() {
cursor.column--;
}
}
-
+
_cancel_completion();
}
@@ -3529,27 +3597,27 @@ void TextEdit::_cancel_code_hint() {
}
void TextEdit::_cancel_completion() {
-
+
if (!completion_active)
return;
-
+
completion_active=false;
update();
-
+
}
static bool _is_completable(CharType c) {
-
+
return !_is_symbol(c) || c=='"' || c=='\'';
}
void TextEdit::_update_completion_candidates() {
-
+
String l = text[cursor.line];
int cofs = CLAMP(cursor.column,0,l.length());
-
-
+
+
String s;
//look for keywords first
@@ -3605,15 +3673,15 @@ void TextEdit::_update_completion_candidates() {
}
}
-
+
update();
-
+
if (cancel || (!pre_keyword && s=="" && (cofs==0 || !completion_prefixes.has(String::chr(l[cofs-1]))))) {
//none to complete, cancel
_cancel_completion();
return;
}
-
+
completion_options.clear();
completion_index=0;
completion_base=s;
@@ -3626,7 +3694,7 @@ void TextEdit::_update_completion_candidates() {
if (max<ci_match)
continue;
for(int j=0;j<max;j++) {
-
+
if (j>=completion_strings[i].length())
break;
if (completion_current[j]!=completion_strings[i][j])
@@ -3637,21 +3705,21 @@ void TextEdit::_update_completion_candidates() {
ci_match=m;
completion_index=completion_options.size()-1;
}
-
+
}
}
-
-
-
+
+
+
if (completion_options.size()==0) {
//no options to complete, cancel
_cancel_completion();
return;
-
+
}
-
+
completion_current=completion_options[completion_index];
-
+
#if 0 // even there's only one option, user still get the chance to choose using it or not
if (completion_options.size()==1) {
//one option to complete, just complete it automagically
@@ -3659,22 +3727,22 @@ void TextEdit::_update_completion_candidates() {
// insert_text_at_cursor(completion_options[0].substr(s.length(),completion_options[0].length()-s.length()));
_cancel_completion();
return;
-
+
}
#endif
if (completion_options.size()==1 && s==completion_options[0])
_cancel_completion();
-
+
completion_enabled=true;
}
void TextEdit::query_code_comple() {
-
+
String l = text[cursor.line];
int ofs = CLAMP(cursor.column,0,l.length());
-
+
bool inquote=false;
int c=ofs-1;
@@ -3686,20 +3754,20 @@ void TextEdit::query_code_comple() {
if (ofs>0 && (inquote || _is_completable(l[ofs-1]) || completion_prefixes.has(String::chr(l[ofs-1]))))
emit_signal("request_completion");
-
+
}
void TextEdit::set_code_hint(const String& p_hint) {
-
+
completion_hint=p_hint;
completion_hint_offset=-0xFFFF;
update();
}
void TextEdit::code_complete(const Vector<String> &p_strings) {
-
-
+
+
completion_strings=p_strings;
completion_active=true;
completion_current="";
@@ -3710,7 +3778,7 @@ void TextEdit::code_complete(const Vector<String> &p_strings) {
String TextEdit::get_tooltip(const Point2& p_pos) const {
-
+
if (!tooltip_obj)
return Control::get_tooltip(p_pos);
int row,col;
@@ -3721,34 +3789,34 @@ String TextEdit::get_tooltip(const Point2& p_pos) const {
return Control::get_tooltip(p_pos);
int beg=CLAMP(col,0,s.length());
int end=beg;
-
-
+
+
if (s[beg]>32 || beg==s.length()) {
-
+
bool symbol = beg < s.length() && _is_symbol(s[beg]); //not sure if right but most editors behave like this
-
+
while(beg>0 && s[beg-1]>32 && (symbol==_is_symbol(s[beg-1]))) {
beg--;
}
while(end<s.length() && s[end+1]>32 && (symbol==_is_symbol(s[end+1]))) {
end++;
}
-
+
if (end<s.length())
end+=1;
-
+
String tt = tooltip_obj->call(tooltip_func,s.substr(beg,end-beg),tooltip_ud);
-
+
return tt;
-
+
}
-
+
return Control::get_tooltip(p_pos);
-
+
}
void TextEdit::set_tooltip_request_func(Object *p_obj, const StringName& p_function,const Variant& p_udata) {
-
+
tooltip_obj=p_obj;
tooltip_func=p_function;
tooltip_ud=p_udata;
@@ -3773,7 +3841,7 @@ void TextEdit::insert_at(const String &p_text, int at)
}
void TextEdit::set_show_line_numbers(bool p_show) {
-
+
line_numbers=p_show;
update();
}
@@ -3783,48 +3851,48 @@ bool TextEdit::is_text_field() const {
return true;
}
void TextEdit::_bind_methods() {
-
-
+
+
ObjectTypeDB::bind_method(_MD("_input_event"),&TextEdit::_input_event);
ObjectTypeDB::bind_method(_MD("_scroll_moved"),&TextEdit::_scroll_moved);
ObjectTypeDB::bind_method(_MD("_cursor_changed_emit"),&TextEdit::_cursor_changed_emit);
ObjectTypeDB::bind_method(_MD("_text_changed_emit"),&TextEdit::_text_changed_emit);
ObjectTypeDB::bind_method(_MD("_push_current_op"),&TextEdit::_push_current_op);
ObjectTypeDB::bind_method(_MD("_click_selection_held"),&TextEdit::_click_selection_held);
-
+
BIND_CONSTANT( SEARCH_MATCH_CASE );
BIND_CONSTANT( SEARCH_WHOLE_WORDS );
BIND_CONSTANT( SEARCH_BACKWARDS );
-
+
/*
ObjectTypeDB::bind_method(_MD("delete_char"),&TextEdit::delete_char);
ObjectTypeDB::bind_method(_MD("delete_line"),&TextEdit::delete_line);
*/
-
+
ObjectTypeDB::bind_method(_MD("set_text","text"),&TextEdit::set_text);
ObjectTypeDB::bind_method(_MD("insert_text_at_cursor","text"),&TextEdit::insert_text_at_cursor);
-
+
ObjectTypeDB::bind_method(_MD("get_line_count"),&TextEdit::get_line_count);
ObjectTypeDB::bind_method(_MD("get_text"),&TextEdit::get_text);
ObjectTypeDB::bind_method(_MD("get_line","line"),&TextEdit::get_line);
-
+
ObjectTypeDB::bind_method(_MD("cursor_set_column","column","adjust_viewport"),&TextEdit::cursor_set_column,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("cursor_set_line","line","adjust_viewport"),&TextEdit::cursor_set_line,DEFVAL(false));
-
+
ObjectTypeDB::bind_method(_MD("cursor_get_column"),&TextEdit::cursor_get_column);
ObjectTypeDB::bind_method(_MD("cursor_get_line"),&TextEdit::cursor_get_line);
-
-
+
+
ObjectTypeDB::bind_method(_MD("set_readonly","enable"),&TextEdit::set_readonly);
ObjectTypeDB::bind_method(_MD("set_wrap","enable"),&TextEdit::set_wrap);
ObjectTypeDB::bind_method(_MD("set_max_chars","amount"),&TextEdit::set_max_chars);
-
+
ObjectTypeDB::bind_method(_MD("cut"),&TextEdit::cut);
ObjectTypeDB::bind_method(_MD("copy"),&TextEdit::copy);
ObjectTypeDB::bind_method(_MD("paste"),&TextEdit::paste);
ObjectTypeDB::bind_method(_MD("select_all"),&TextEdit::select_all);
ObjectTypeDB::bind_method(_MD("select","from_line","from_column","to_line","to_column"),&TextEdit::select);
-
+
ObjectTypeDB::bind_method(_MD("is_selection_active"),&TextEdit::is_selection_active);
ObjectTypeDB::bind_method(_MD("get_selection_from_line"),&TextEdit::get_selection_from_line);
ObjectTypeDB::bind_method(_MD("get_selection_from_column"),&TextEdit::get_selection_from_column);
@@ -3833,30 +3901,30 @@ void TextEdit::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_selection_text"),&TextEdit::get_selection_text);
ObjectTypeDB::bind_method(_MD("get_word_under_cursor"),&TextEdit::get_word_under_cursor);
ObjectTypeDB::bind_method(_MD("search","flags","from_line","from_column","to_line","to_column"),&TextEdit::_search_bind);
-
+
ObjectTypeDB::bind_method(_MD("undo"),&TextEdit::undo);
ObjectTypeDB::bind_method(_MD("redo"),&TextEdit::redo);
ObjectTypeDB::bind_method(_MD("clear_undo_history"),&TextEdit::clear_undo_history);
-
+
ObjectTypeDB::bind_method(_MD("set_syntax_coloring","enable"),&TextEdit::set_syntax_coloring);
ObjectTypeDB::bind_method(_MD("is_syntax_coloring_enabled"),&TextEdit::is_syntax_coloring_enabled);
-
-
+
+
ObjectTypeDB::bind_method(_MD("add_keyword_color","keyword","color"),&TextEdit::add_keyword_color);
ObjectTypeDB::bind_method(_MD("add_color_region","begin_key","end_key","color","line_only"),&TextEdit::add_color_region,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("set_symbol_color","color"),&TextEdit::set_symbol_color);
ObjectTypeDB::bind_method(_MD("set_custom_bg_color","color"),&TextEdit::set_custom_bg_color);
ObjectTypeDB::bind_method(_MD("clear_colors"),&TextEdit::clear_colors);
-
-
+
+
ADD_SIGNAL(MethodInfo("cursor_changed"));
ADD_SIGNAL(MethodInfo("text_changed"));
ADD_SIGNAL(MethodInfo("request_completion"));
-
+
}
TextEdit::TextEdit() {
-
+
readonly=false;
setting_row=false;
draw_tabs=false;
@@ -3876,29 +3944,29 @@ TextEdit::TextEdit() {
// text.insert(1,"Mongolia..");
// text.insert(2,"PAIS GENEROSO!!");
text.set_color_regions(&color_regions);
-
+
h_scroll = memnew( HScrollBar );
v_scroll = memnew( VScrollBar );
-
+
add_child(h_scroll);
add_child(v_scroll);
-
+
updating_scrolls=false;
selection.active=false;
-
+
h_scroll->connect("value_changed", this,"_scroll_moved");
v_scroll->connect("value_changed", this,"_scroll_moved");
-
+
cursor_changed_dirty=false;
text_changed_dirty=false;
-
+
selection.selecting_mode=Selection::MODE_NONE;
selection.selecting_line=0;
selection.selecting_column=0;
selection.selecting_text=false;
selection.active=false;
syntax_coloring=false;
-
+
custom_bg_color=Color(0,0,0,0);
idle_detect = memnew( Timer );
add_child(idle_detect);
@@ -3910,7 +3978,7 @@ TextEdit::TextEdit() {
add_child(click_select_held);
click_select_held->set_wait_time(0.05);
click_select_held->connect("timeout", this,"_click_selection_held");
-
+
#if 0
syntax_coloring=true;
keywords["void"]=Color(0.3,0.0,0.1);
@@ -3920,15 +3988,15 @@ TextEdit::TextEdit() {
keywords["extends"]=Color(0.3,0.0,0.1);
keywords["constructor"]=Color(0.3,0.0,0.1);
symbol_color=Color(0.1,0.0,0.3,1.0);
-
+
color_regions.push_back(ColorRegion("/*","*/",Color(0.4,0.6,0,4)));
color_regions.push_back(ColorRegion("//","",Color(0.6,0.6,0.4)));
color_regions.push_back(ColorRegion("\"","\"",Color(0.4,0.7,0.7)));
color_regions.push_back(ColorRegion("'","'",Color(0.4,0.8,0.8)));
color_regions.push_back(ColorRegion("#","",Color(0.2,1.0,0.2)));
-
+
#endif
-
+
current_op.type=TextOperation::TYPE_NONE;
undo_enabled=true;
undo_stack_pos=NULL;
@@ -3937,13 +4005,14 @@ TextEdit::TextEdit() {
current_op.version=0;
version=0;
saved_version=0;
-
+
completion_enabled=false;
completion_active=false;
completion_line_ofs=0;
tooltip_obj=NULL;
line_numbers=false;
next_operation_is_complex=false;
+ scroll_past_end_of_file_enabled=false;
auto_brace_completion_enabled=false;
brace_matching_enabled=false;
auto_indent=false;
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 2ca5ab054a..d38c57804d 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -128,7 +128,7 @@ class TextEdit : public Control {
void set_font(const Ref<Font>& p_font);
void set_color_regions(const Vector<ColorRegion>*p_regions) { color_regions=p_regions; }
int get_line_width(int p_line) const;
- int get_max_width() const;
+ int get_max_width() const;
const Map<int,ColorRegionInfo>& get_color_region_info(int p_line);
void set(int p_line,const String& p_string);
void set_marked(int p_line,bool p_marked) { text[p_line].marked=p_marked; }
@@ -156,6 +156,7 @@ class TextEdit : public Control {
int from_line,from_column;
int to_line, to_column;
String text;
+ uint32_t prev_version;
uint32_t version;
bool chain_forward;
bool chain_backward;
@@ -210,7 +211,8 @@ class TextEdit : public Control {
bool text_changed_dirty;
bool undo_enabled;
bool line_numbers;
-
+
+ bool scroll_past_end_of_file_enabled;
bool auto_brace_completion_enabled;
bool brace_matching_enabled;
bool auto_indent;
@@ -228,9 +230,12 @@ class TextEdit : public Control {
Object *tooltip_obj;
StringName tooltip_func;
Variant tooltip_ud;
-
+
bool next_operation_is_complex;
+ bool callhint_below;
+ Vector2 callhint_offset;
+
int get_visible_rows() const;
int get_char_count();
@@ -254,13 +259,13 @@ class TextEdit : public Control {
void _update_caches();
void _cursor_changed_emit();
void _text_changed_emit();
-
+
void _begin_compex_operation();
void _end_compex_operation();
void _push_current_op();
/* super internal api, undo/redo builds on it */
-
+
void _base_insert_text(int p_line, int p_column,const String& p_text,int &r_end_line,int &r_end_column);
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);
@@ -278,16 +283,16 @@ class TextEdit : public Control {
protected:
virtual String get_tooltip(const Point2& p_pos) const;
-
+
void _insert_text(int p_line, int p_column,const String& p_text,int *r_end_line=NULL,int *r_end_char=NULL);
void _remove_text(int p_from_line, int p_from_column,int p_to_line,int p_to_column);
void _insert_text_at_cursor(const String& p_text);
void _input_event(const InputEvent& p_input);
void _notification(int p_what);
-
+
void _consume_pair_symbol(CharType ch);
void _consume_backspace_for_pair_symbol(int prev_line, int prev_column);
-
+
static void _bind_methods();
@@ -300,7 +305,7 @@ public:
SEARCH_WHOLE_WORDS=2,
SEARCH_BACKWARDS=4
};
-
+
virtual CursorShape get_cursor_shape(const Point2& p_pos=Point2i()) const;
//void delete_char();
@@ -318,7 +323,11 @@ public:
String get_line(int line) const;
void set_line(int line, String new_text);
void backspace_at_cursor();
-
+
+ inline void set_scroll_pass_end_of_file(bool p_enabled) {
+ scroll_past_end_of_file_enabled = p_enabled;
+ update();
+ }
inline void set_auto_brace_completion(bool p_enabled) {
auto_brace_completion_enabled = p_enabled;
}
@@ -326,6 +335,10 @@ public:
brace_matching_enabled=p_enabled;
update();
}
+ inline void set_callhint_settings(bool below, Vector2 offset) {
+ callhint_below = below;
+ callhint_offset = offset;
+ }
void set_auto_indent(bool p_auto_indent);
void cursor_set_column(int p_col, bool p_adjust_viewport=true);
@@ -366,7 +379,7 @@ public:
void redo();
void clear_undo_history();
-
+ void set_tab_size(const int p_size);
void set_draw_tabs(bool p_draw);
bool is_drawing_tabs() const;
@@ -390,7 +403,7 @@ public:
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);
+ void set_completion(bool p_enabled,const Vector<String>& p_prefixes);
void code_complete(const Vector<String> &p_strings);
void set_code_hint(const String& p_hint);
void query_code_comple();
diff --git a/scene/gui/texture_frame.h b/scene/gui/texture_frame.h
index f6fe6ae89d..e1f0de92df 100644
--- a/scene/gui/texture_frame.h
+++ b/scene/gui/texture_frame.h
@@ -42,7 +42,7 @@ class TextureFrame : public Control {
Ref<Texture> texture;
protected:
- void _notification(int p_what);
+ void _notification(int p_what);
virtual Size2 get_minimum_size() const;
static void _bind_methods();
diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp
index e05d35a81d..923a35031c 100644
--- a/scene/gui/texture_progress.cpp
+++ b/scene/gui/texture_progress.cpp
@@ -195,7 +195,7 @@ void TextureProgress::_notification(int p_what){
draw_texture_rect_region(progress,Rect2(Point2(),Size2(s.x*get_unit_value(),s.y)),Rect2(Point2(),Size2(s.x*get_unit_value(),s.y)));
}
-
+
}
if (over.is_valid())
draw_texture(over,Point2());
@@ -269,10 +269,10 @@ void TextureProgress::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_radial_initial_angle","mode"),&TextureProgress::set_radial_initial_angle);
ObjectTypeDB::bind_method(_MD("get_radial_initial_angle"), &TextureProgress::get_radial_initial_angle);
-
+
ObjectTypeDB::bind_method(_MD("set_radial_center_offset","mode"),&TextureProgress::set_radial_center_offset);
ObjectTypeDB::bind_method(_MD("get_radial_center_offset"), &TextureProgress::get_radial_center_offset);
-
+
ObjectTypeDB::bind_method(_MD("set_fill_degrees","mode"),&TextureProgress::set_fill_degrees);
ObjectTypeDB::bind_method(_MD("get_fill_degrees"), &TextureProgress::get_fill_degrees);
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 05b1e8bcea..483aa47f35 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -574,7 +574,14 @@ void TreeItem::set_custom_color(int p_column,const Color& p_color) {
cells[p_column].color=p_color;
_changed_notify(p_column);
}
+Color TreeItem::get_custom_color(int p_column) const {
+ ERR_FAIL_INDEX_V( p_column, cells.size(), Color() );
+ if (!cells[p_column].custom_color)
+ return Color();
+ return cells[p_column].color;
+
+}
void TreeItem::clear_custom_color(int p_column) {
ERR_FAIL_INDEX( p_column, cells.size() );
@@ -2164,7 +2171,7 @@ void Tree::_input_event(InputEvent p_event) {
float diff_y = -b.relative_y;
diff_y=Math::pow(ABS(diff_y),1.8)*SGN(diff_y);
diff_y*=0.1;
- range_drag_base=CLAMP(range_drag_base + c.step * diff_y, c.min, c.max);
+ range_drag_base=CLAMP(range_drag_base + c.step * diff_y, c.min, c.max);
popup_edited_item->set_range(popup_edited_item_col,range_drag_base);
item_edited(popup_edited_item_col,popup_edited_item);
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index e5c95b4d66..1ba1c6a494 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -46,22 +46,22 @@ class TreeItem : public Object {
OBJ_TYPE(TreeItem,Object);
public:
-
+
enum TreeCellMode {
-
+
CELL_MODE_STRING, ///< just a string
CELL_MODE_CHECK, ///< string + check
CELL_MODE_RANGE, ///< Contains a range
CELL_MODE_ICON, ///< Contains a icon, not editable
CELL_MODE_CUSTOM, ///< Contains a custom value, show a string, and an edit button
};
-
+
private:
friend class Tree;
-
-
+
+
struct Cell {
-
+
TreeCellMode mode;
Ref<Texture> icon;
@@ -92,9 +92,9 @@ friend class Tree;
};
Vector< Button > buttons;
-
+
Cell() {
-
+
custom_draw_obj=0;
mode=TreeItem::CELL_MODE_STRING;
min=0;
@@ -116,30 +116,30 @@ friend class Tree;
void draw_icon(const RID& p_where, const Point2& p_pos, const Size2& p_size=Size2()) const;
};
-
+
Vector<Cell> cells;
-
+
bool collapsed; // wont show childs
-
+
TreeItem *parent; // parent item
TreeItem *next; // next in list
TreeItem *childs; //child items
Tree *tree; //tree (for reference)
-
+
TreeItem(Tree *p_tree);
-
+
void _changed_notify(int p_cell);
void _changed_notify();
void _cell_selected(int p_cell);
void _cell_deselected(int p_cell);
protected:
-
+
static void _bind_methods();
//bind helpers
- Dictionary _get_range_config( int p_column ) {
+ Dictionary _get_range_config( int p_column ) {
Dictionary d;
double min,max,step;
get_range_config(p_column,min,max,step);
@@ -152,18 +152,18 @@ protected:
}
void _remove_child(Object *p_child) { remove_child( p_child->cast_to<TreeItem>() ); }
public:
-
+
/* cell mode */
void set_cell_mode( int p_column, TreeCellMode p_mode );
TreeCellMode get_cell_mode( int p_column ) const;
-
+
/* check mode */
void set_checked(int p_column,bool p_checked);
bool is_checked(int p_column) const;
-
+
void set_text(int p_column,String p_text);
String get_text(int p_column) const;
-
+
void set_icon(int p_column,const Ref<Texture>& p_icon);
Ref<Texture> get_icon(int p_column) const;
@@ -183,22 +183,22 @@ public:
void set_button(int p_column,int p_idx,const Ref<Texture>& p_button);
/* range works for mode number or mode combo */
-
+
void set_range(int p_column,double p_value);
double get_range(int p_column) const;
-
+
void set_range_config(int p_column,double p_min,double p_max,double p_step,bool p_exp=false);
void get_range_config(int p_column,double& r_min,double& r_max,double &r_step) const;
bool is_range_exponential(int p_column) const;
-
+
void set_metadata(int p_column,const Variant& p_meta);
Variant get_metadata(int p_column) const;
-
+
void set_custom_draw(int p_column,Object *p_object,const StringName& p_callback);
-
+
void set_collapsed(bool p_collapsed);
bool is_collapsed();
-
+
TreeItem *get_prev();
TreeItem *get_next();
TreeItem *get_parent();
@@ -206,21 +206,22 @@ public:
TreeItem *get_prev_visible();
TreeItem *get_next_visible();
-
+
void remove_child(TreeItem *p_item);
-
+
void set_selectable(int p_column,bool p_selectable);
bool is_selectable(int p_column) const;
-
+
bool is_selected(int p_column);
void select(int p_column);
void deselect(int p_column);
void set_as_cursor(int p_column);
-
+
void set_editable(int p_column,bool p_editable);
bool is_editable(int p_column);
-
+
void set_custom_color(int p_column,const Color& p_color);
+ Color get_custom_color(int p_column) const;
void clear_custom_color(int p_column);
void set_custom_bg_color(int p_column,const Color& p_color);
@@ -237,7 +238,7 @@ public:
void move_to_bottom();
~TreeItem();
-
+
};
@@ -245,18 +246,18 @@ VARIANT_ENUM_CAST( TreeItem::TreeCellMode );
class Tree : public Control {
-
+
OBJ_TYPE( Tree, Control );
-public:
+public:
enum SelectMode {
SELECT_SINGLE,
SELECT_ROW,
SELECT_MULTI
};
-
-private:
-friend class TreeItem;
-
+
+private:
+friend class TreeItem;
+
TreeItem *root;
TreeItem *popup_edited_item;
TreeItem *selected_item;
@@ -287,7 +288,7 @@ friend class TreeItem;
int blocked;
struct ColumnInfo {
-
+
int min_width;
bool expand;
String title;
@@ -320,21 +321,21 @@ friend class TreeItem;
void value_editor_changed(double p_value);
void popup_select(int p_option);
-
+
void _input_event(InputEvent p_event);
void _notification(int p_what);
-
+
Size2 get_minimum_size() const;
-
+
void item_edited(int p_column,TreeItem *p_item);
void item_changed(int p_column,TreeItem *p_item);
void item_selected(int p_column,TreeItem *p_item);
void item_deselected(int p_column,TreeItem *p_item);
-
+
void propagate_set_columns(TreeItem *p_item);
-
+
struct Cache {
-
+
Ref<Font> font;
Ref<Font> tb_font;
Ref<StyleBox> bg;
@@ -354,14 +355,14 @@ friend class TreeItem;
Ref<Texture> arrow;
Ref<Texture> select_arrow;
Ref<Texture> updown;
-
+
Color font_color;
Color font_color_selected;
Color guide_color;
int hseparation;
int vseparation;
int item_margin;
- int guide_width;
+ int guide_width;
int button_margin;
Point2 offset;
@@ -381,14 +382,14 @@ friend class TreeItem;
int hover_index;
} cache;
-
-
+
+
int _get_title_button_height() const;
void _scroll_moved(float p_value);
HScrollBar *h_scroll;
VScrollBar *v_scroll;
-
+
Size2 get_internal_min_size() const;
void update_cache();
void update_scrollbars();
@@ -423,10 +424,10 @@ friend class TreeItem;
protected:
static void _bind_methods();
-
+
//bind helpers
Object* _create_item(Object *p_parent) { return create_item(p_parent->cast_to<TreeItem>() ); }
- TreeItem *_get_next_selected(Object *p_item) { return get_next_selected(p_item->cast_to<TreeItem>() ); }
+ TreeItem *_get_next_selected(Object *p_item) { return get_next_selected(p_item->cast_to<TreeItem>() ); }
Rect2 _get_item_rect(Object *p_item,int p_column) const { return get_item_rect(p_item->cast_to<TreeItem>(),p_column ); }
public:
@@ -434,21 +435,21 @@ public:
void clear();
- TreeItem* create_item(TreeItem *p_parent=0);
+ TreeItem* create_item(TreeItem *p_parent=0);
TreeItem* get_root();
TreeItem* get_last_item();
void set_column_min_width(int p_column,int p_min_width);
- void set_column_expand(int p_column,bool p_expand);
+ void set_column_expand(int p_column,bool p_expand);
int get_column_width(int p_column) const;
-
+
void set_hide_root(bool p_eanbled);
TreeItem *get_next_selected( TreeItem* p_item);
TreeItem *get_selected() const;
int get_selected_column() const;
int get_pressed_button() const;
void set_select_mode(SelectMode p_mode);
-
+
void set_columns(int p_columns);
int get_columns() const;
@@ -462,11 +463,11 @@ public:
int get_edited_column() const;
void ensure_cursor_is_visible();
-
+
Rect2 get_custom_popup_rect() const;
int get_item_offset(TreeItem *p_item) const;
- Rect2 get_item_rect(TreeItem *p_item,int p_column=-1) const;
+ Rect2 get_item_rect(TreeItem *p_item,int p_column=-1) const;
bool edit_selected();
TreeItem* search_item_text(const String& p_find,int *r_col=NULL,bool p_selectable=false);
@@ -484,7 +485,7 @@ public:
Tree();
- ~Tree();
+ ~Tree();
};