summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/color_picker.cpp474
-rw-r--r--scene/gui/color_picker.h53
-rw-r--r--scene/gui/control.cpp1129
-rw-r--r--scene/gui/control.h64
-rw-r--r--scene/gui/popup.cpp12
-rw-r--r--scene/gui/split_container.cpp33
-rw-r--r--scene/gui/split_container.h15
7 files changed, 628 insertions, 1152 deletions
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 7d6c986d96..8685ec1c99 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -28,25 +28,43 @@
/*************************************************************************/
#include "color_picker.h"
+#include "scene/gui/separator.h"
+#include "scene/main/viewport.h"
+#include "os/os.h"
+#include "os/input.h"
+#include "os/keyboard.h"
+
+void update_material(Ref<CanvasItemMaterial>mat,const Color& p_color) {
+ if (!mat.is_valid())
+ return;
+ Ref<Shader> sdr = mat->get_shader();
+ if (!sdr.is_valid())
+ return;
-
+ mat->set_shader_param("R",p_color.r);
+ mat->set_shader_param("G",p_color.g);
+ mat->set_shader_param("B",p_color.b);
+ mat->set_shader_param("H",p_color.get_h());
+ mat->set_shader_param("S",p_color.get_s());
+ mat->set_shader_param("V",p_color.get_v());
+ mat->set_shader_param("A",p_color.a);
+}
void ColorPicker::_notification(int p_what) {
switch(p_what) {
case NOTIFICATION_THEME_CHANGED: {
-
+ uv_material->set_shader(get_shader("uv_editor"));
+ w_material->set_shader(get_shader("w_editor"));
+ update_material(uv_material,color);
+ update_material(w_material,color);
_update_controls();
} break;
-/* case NOTIFICATION_DRAW: {
-
- int w = get_constant("color_width");
- int h = ms.height;
- VisualServer::get_singleton()->canvas_item_add_rect(get_canvas_item(),Rect2(0,0,w,h),color);
-
- } break;*/
+ case NOTIFICATION_ENTER_TREE: {
+ btn_pick->set_icon(get_icon("screen_picker", "ColorPicker"));
+ }
}
}
@@ -64,10 +82,16 @@ void ColorPicker::_update_controls() {
}
-
void ColorPicker::set_color(const Color& p_color) {
color=p_color;
+ h=color.get_h();
+ s=color.get_s();
+ v=color.get_v();
+ update_material(uv_material, color);
+ update_material(w_material, color);
+ uv_edit->get_child(0)->cast_to<Control>()->update();
+ w_edit->get_child(0)->cast_to<Control>()->update();
_update_color();
}
@@ -77,7 +101,7 @@ void ColorPicker::set_edit_alpha(bool p_show) {
edit_alpha=p_show;
_update_controls();
_update_color();
- color_box->update();
+ sample->update();
}
bool ColorPicker::is_editing_alpha() const {
@@ -90,35 +114,17 @@ void ColorPicker::_value_changed(double) {
if (updating)
return;
- switch(mode) {
-
- case MODE_RGB: {
-
- for(int i=0;i<4;i++) {
- color.components[i] = scroll[i]->get_val() / 255.0;
- }
-
- } break;
- case MODE_HSV: {
-
- color.set_hsv( CLAMP(scroll[0]->get_val()/359,0,0.9972), scroll[1]->get_val()/100, scroll[2]->get_val()/100 );
- color.a=scroll[3]->get_val()/100.0;
-
- } break;
- case MODE_RAW: {
-
- for(int i=0;i<4;i++) {
- color.components[i] = scroll[i]->get_val();
- }
-
- } break;
-
+ for(int i=0;i<3;i++) {
+ color.components[i] = scroll[i]->get_val()/(raw_mode_enabled?1.0:255.0);
}
+ color.components[3] = scroll[3]->get_val()/255.0;
+ update_material(uv_material,color);
+ update_material(w_material,color);
html->set_text(color.to_html(edit_alpha && color.a<1));
- color_box->update();
+ sample->update();
emit_signal("color_changed",color);
@@ -138,144 +144,325 @@ void ColorPicker::_update_color() {
updating=true;
- switch(mode) {
-
- case MODE_RAW: {
-
- static const char*_lt[4]={"R","G","B","A"};
-
- for(int i=0;i<4;i++) {
- scroll[i]->set_max(255);
- scroll[i]->set_step(0.01);
- scroll[i]->set_val(color.components[i]);
- labels[i]->set_text(_lt[i]);
- }
- } break;
- case MODE_RGB: {
-
- static const char*_lt[4]={"R","G","B","A"};
-
- for(int i=0;i<4;i++) {
- scroll[i]->set_max(255);
- scroll[i]->set_step(1);
- scroll[i]->set_val(color.components[i]*255);
- labels[i]->set_text(_lt[i]);
- }
-
- } break;
- case MODE_HSV: {
-
- static const char*_lt[4]={"H","S","V","A"};
+ for(int i=0;i<4;i++) {
+ scroll[i]->set_max(255);
+ scroll[i]->set_step(0.01);
+ if (raw_mode_enabled && i != 3)
+ scroll[i]->set_val(color.components[i]);
+ else
+ scroll[i]->set_val(color.components[i]*255);
+ }
- for(int i=0;i<4;i++) {
- labels[i]->set_text(_lt[i]);
- }
+ html->set_text(color.to_html(edit_alpha && color.a<1));
- scroll[0]->set_max(359);
- scroll[0]->set_step(0.01);
- scroll[0]->set_val( color.get_h()*359 );
+ sample->update();
+ updating=false;
+}
- scroll[1]->set_max(100);
- scroll[1]->set_step(0.01);
- scroll[1]->set_val( color.get_s()*100 );
+void ColorPicker::_update_presets()
+{
+ Size2 size=bt_add_preset->get_size();
+ preset->set_custom_minimum_size(Size2(size.width*presets.size(),size.height));
+ Image i(size.x*presets.size(),size.y, false, Image::FORMAT_RGB);
+ for (int y=0;y<size.y;y++)
+ for (int x=0;x<size.x*presets.size();x++)
+ i.put_pixel(x,y,presets[(int)x/size.x]);
+ Ref<ImageTexture> t;
+ t.instance();
+ t->create_from_image(i);
+ preset->set_texture(t);
+}
- scroll[2]->set_max(100);
- scroll[2]->set_step(0.01);
- scroll[2]->set_val( color.get_v()*100 );
+Color ColorPicker::get_color() const {
- scroll[3]->set_max(100);
- scroll[3]->set_step(0.01);
- scroll[3]->set_val( color.a*100);
+ return color;
+}
- } break;
+void ColorPicker::add_preset(const Color &p_color)
+{
+ if (presets.find(p_color)) {
+ presets.move_to_back(presets.find(p_color));
+ } else {
+ presets.push_back(p_color);
}
+ _update_presets();
+ if (presets.size()==10)
+ bt_add_preset->hide();
+}
- html->set_text(color.to_html(edit_alpha && color.a<1));
+void ColorPicker::set_raw_mode(bool p_enabled) {
- color_box->update();
- updating=false;
+ if (raw_mode_enabled==p_enabled)
+ return;
+ raw_mode_enabled=p_enabled;
+ if (btn_mode->is_pressed()!=p_enabled)
+ btn_mode->set_pressed(p_enabled);
+
+ _update_controls();
+ _update_color();
}
-Color ColorPicker::get_color() const {
+bool ColorPicker::is_raw_mode() const {
- return color;
+ return raw_mode_enabled;
}
+void ColorPicker::_sample_draw() {
+ sample->draw_rect(Rect2(Point2(),Size2(256,20)),color);
+}
-void ColorPicker::set_mode(Mode p_mode) {
+void ColorPicker::_hsv_draw(int p_wich,Control* c)
+{
+ if (!c)
+ return;
+ if (p_wich==0) {
+ int x=c->get_size().x*color.get_s();
+ int y=c->get_size().y-c->get_size().y*color.get_v();
+ c->draw_line(Point2(x,0),Point2(x,c->get_size().y),color.inverted());
+ c->draw_line(Point2(0,y),Point2(c->get_size().x,y),color.inverted());
+ c->draw_line(Point2(x,y),Point2(x,y),Color(1,1,1),2);
+ } else if (p_wich==1) {
+ int y=c->get_size().y-c->get_size().y*color.get_h();
+ Color col=Color();
+ col.set_hsv(color.get_h(),1,1);
+ c->draw_line(Point2(0,y),Point2(c->get_size().x,y),col.inverted());
+ }
+}
- ERR_FAIL_INDEX(p_mode,3);
- mode=p_mode;
- if (mode_box->get_selected()!=p_mode)
- mode_box->select(p_mode);
+void ColorPicker::_uv_input(const InputEvent &ev) {
+ if (ev.type == InputEvent::MOUSE_BUTTON) {
+ const InputEventMouseButton &bev = ev.mouse_button;
+ if (bev.pressed) {
+ changing_color = true;
+ float x = CLAMP((float)bev.x,0,256);
+ float y = CLAMP((float)bev.y,0,256);
+ s=x/256;
+ v=1.0-y/256.0;
+ color.set_hsv(h,s,v,color.a);
+ set_color(color);
+ _update_color();
+ emit_signal("color_changed", color);
+ } else {
+ changing_color = false;
+ }
+ } else if (ev.type == InputEvent::MOUSE_MOTION) {
+ const InputEventMouse &bev = ev.mouse_motion;
+ if (!changing_color)
+ return;
+ float x = CLAMP((float)bev.x,0,256);
+ float y = CLAMP((float)bev.y,0,256);
+ s=x/256;
+ v=1.0-y/256.0;
+ color.set_hsv(h,s,v,color.a);
+ set_color(color);
+ _update_color();
+ emit_signal("color_changed", color);
+ }
+}
- _update_controls();
- _update_color();
+void ColorPicker::_w_input(const InputEvent &ev) {
+ if (ev.type == InputEvent::MOUSE_BUTTON) {
+ const InputEventMouseButton &bev = ev.mouse_button;
+ if (bev.pressed) {
+ changing_color = true;
+ h=1-((float)bev.y)/256.0;
+
+ } else {
+ changing_color = false;
+ }
+ color.set_hsv(h,s,v,color.a);
+ set_color(color);
+ _update_color();
+ emit_signal("color_changed", color);
+ } else if (ev.type == InputEvent::MOUSE_MOTION) {
+ const InputEventMouse &bev = ev.mouse_motion;
+ if (!changing_color)
+ return;
+ float y = CLAMP((float)bev.y,0,256);
+ h=1.0-y/256.0;
+ color.set_hsv(h,s,v,color.a);
+ set_color(color);
+ _update_color();
+ emit_signal("color_changed", color);
+ }
}
-ColorPicker::Mode ColorPicker::get_mode() const {
+void ColorPicker::_preset_input(const InputEvent &ev) {
+ if (ev.type == InputEvent::MOUSE_BUTTON) {
+ const InputEventMouseButton &bev = ev.mouse_button;
+ if (bev.pressed && bev.button_index==BUTTON_LEFT) {
+ int index = bev.x/(preset->get_size().x/presets.size());
+ set_color(presets[index]);
+ } else if (bev.pressed && bev.button_index==BUTTON_RIGHT) {
+ int index = bev.x/(preset->get_size().x/presets.size());
+ presets.erase(presets[index]);
+ _update_presets();
+ bt_add_preset->show();
+ }
+ _update_color();
+ 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());
+ if (index<0 || index >= presets.size())
+ return;
+ preset->set_tooltip("Color: #"+presets[index].to_html(presets[index].a<1)+"\n"
+ "LMB: Set color\n"
+ "RMB: Remove preset");
+ }
+}
- return mode;
+void ColorPicker::_screen_input(const InputEvent &ev)
+{
+ if (ev.type==InputEvent::MOUSE_BUTTON) {
+ const InputEventMouseButton &bev = ev.mouse_button;
+ if (bev.button_index==BUTTON_LEFT&&!bev.pressed) {
+ emit_signal("color_changed", color);
+ screen->hide();
+ }
+ } else if (ev.type==InputEvent::MOUSE_MOTION) {
+ const InputEventMouse &mev = ev.mouse_motion;
+ Viewport *r=get_tree()->get_root();
+ if (!r->get_rect().has_point(Point2(mev.global_x,mev.global_y)))
+ return;
+ Image img =r->get_screen_capture();
+ if (!img.empty())
+ last_capture=img;
+ r->queue_screen_capture();
+ if (!last_capture.empty())
+ set_color(last_capture.get_pixel(mev.global_x,mev.global_y));
+ }
}
-void ColorPicker::_color_box_draw() {
+void ColorPicker::_add_preset_pressed() {
+ add_preset(color);
+}
- color_box->draw_rect( Rect2( Point2(), color_box->get_size()), color);
+void ColorPicker::_screen_pick_pressed()
+{
+ Viewport *r=get_tree()->get_root();
+ if (!screen) {
+ screen=memnew( Control );
+ r->add_child(screen);
+ screen->set_area_as_parent_rect();
+ screen->connect("input_event",this,"_screen_input");
+ }
+ screen->raise();
+ screen->show();
+ r->queue_screen_capture();
}
void ColorPicker::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_color","color"),&ColorPicker::set_color);
ObjectTypeDB::bind_method(_MD("get_color"),&ColorPicker::get_color);
- ObjectTypeDB::bind_method(_MD("set_mode","mode"),&ColorPicker::set_mode);
- ObjectTypeDB::bind_method(_MD("get_mode"),&ColorPicker::get_mode);
+ ObjectTypeDB::bind_method(_MD("set_raw_mode","mode"),&ColorPicker::set_raw_mode);
+ ObjectTypeDB::bind_method(_MD("is_raw_mode"),&ColorPicker::is_raw_mode);
ObjectTypeDB::bind_method(_MD("set_edit_alpha","show"),&ColorPicker::set_edit_alpha);
ObjectTypeDB::bind_method(_MD("is_editing_alpha"),&ColorPicker::is_editing_alpha);
+ ObjectTypeDB::bind_method(_MD("add_preset"), &ColorPicker::add_preset);
ObjectTypeDB::bind_method(_MD("_value_changed"),&ColorPicker::_value_changed);
ObjectTypeDB::bind_method(_MD("_html_entered"),&ColorPicker::_html_entered);
- ObjectTypeDB::bind_method(_MD("_color_box_draw"),&ColorPicker::_color_box_draw);
+ ObjectTypeDB::bind_method(_MD("_add_preset_pressed"), &ColorPicker::_add_preset_pressed);
+ ObjectTypeDB::bind_method(_MD("_screen_pick_pressed"), &ColorPicker::_screen_pick_pressed);
+ ObjectTypeDB::bind_method(_MD("_sample_draw"),&ColorPicker::_sample_draw);
+ ObjectTypeDB::bind_method(_MD("_hsv_draw"),&ColorPicker::_hsv_draw);
+ ObjectTypeDB::bind_method(_MD("_uv_input"),&ColorPicker::_uv_input);
+ ObjectTypeDB::bind_method(_MD("_w_input"),&ColorPicker::_w_input);
+ ObjectTypeDB::bind_method(_MD("_preset_input"),&ColorPicker::_preset_input);
+ ObjectTypeDB::bind_method(_MD("_screen_input"),&ColorPicker::_screen_input);
ADD_SIGNAL( MethodInfo("color_changed",PropertyInfo(Variant::COLOR,"color")));
}
+ColorPicker::ColorPicker() :
+ BoxContainer(true) {
-
-
-ColorPicker::ColorPicker() {
-
-
- //edit_alpha=false;
updating=true;
edit_alpha=true;
+ raw_mode_enabled=false;
+ changing_color=false;
+ screen=NULL;
+
+ HBoxContainer *hb_smpl = memnew( HBoxContainer );
+ btn_pick = memnew( ToolButton );
+ btn_pick->connect("pressed",this,"_screen_pick_pressed");
+
+ sample = memnew( TextureFrame );
+ sample->set_h_size_flags(SIZE_EXPAND_FILL);
+ sample->connect("draw",this,"_sample_draw");
+
+ hb_smpl->add_child(sample);
+ hb_smpl->add_child(btn_pick);
+ add_child(hb_smpl);
+
+ HBoxContainer *hb_edit = memnew( HBoxContainer );
+
+ uv_edit= memnew ( TextureFrame );
+ Image i(256, 256, false, Image::FORMAT_RGB);
+ for (int y=0;y<256;y++)
+ for (int x=0;x<256;x++)
+ i.put_pixel(x,y,Color());
+ Ref<ImageTexture> t;
+ t.instance();
+ t->create_from_image(i);
+ uv_edit->set_texture(t);
+ uv_edit->set_ignore_mouse(false);
+ uv_edit->set_custom_minimum_size(Size2(256,256));
+ uv_edit->connect("input_event", this, "_uv_input");
+ Control *c= memnew( Control );
+ uv_edit->add_child(c);
+ c->set_area_as_parent_rect();
+ c->set_stop_mouse(false);
+ c->set_material(memnew ( CanvasItemMaterial ));
+ Vector<Variant> args=Vector<Variant>();
+ args.push_back(0);
+ args.push_back(c);
+ c->connect("draw",this,"_hsv_draw",args);
+
+ add_child(hb_edit);
+ w_edit= memnew( TextureFrame );
+ i = Image(15, 256, false, Image::FORMAT_RGB);
+ for (int y=0;y<256;y++)
+ for (int x=0;x<15;x++)
+ i.put_pixel(x,y,Color());
+ Ref<ImageTexture> tw;
+ tw.instance();
+ tw->create_from_image(i);
+ w_edit->set_texture(tw);
+ w_edit->set_ignore_mouse(false);
+ w_edit->set_custom_minimum_size(Size2(15,256));
+ w_edit->connect("input_event", this, "_w_input");
+ c= memnew( Control );
+ w_edit->add_child(c);
+ c->set_area_as_parent_rect();
+ c->set_stop_mouse(false);
+ c->set_material(memnew ( CanvasItemMaterial ));
+ args.clear();
+ 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);
VBoxContainer *vbl = memnew( VBoxContainer );
add_child(vbl);
- mode_box = memnew( OptionButton );
- mode_box->add_item("RGB");
- mode_box->add_item("HSV");
- mode_box->add_item("RAW");
- mode_box->connect("item_selected",this,"set_mode");
-
- color_box=memnew( Control );
- color_box->set_v_size_flags(SIZE_EXPAND_FILL);
- vbl->add_child(color_box);
- color_box->connect("draw",this,"_color_box_draw");
-
- vbl->add_child(mode_box);
-
+ add_child(memnew( HSeparator ));
VBoxContainer *vbr = memnew( VBoxContainer );
add_child(vbr);
vbr->set_h_size_flags(SIZE_EXPAND_FILL);
-
+ const char* lt[4] = {"R","G","B","A"};
for(int i=0;i<4;i++) {
HBoxContainer *hbc = memnew( HBoxContainer );
- labels[i]=memnew( Label );
+ labels[i]=memnew( Label(lt[i]) );
hbc->add_child(labels[i]);
scroll[i]=memnew( HSlider );
@@ -294,10 +481,14 @@ ColorPicker::ColorPicker() {
vbr->add_child(hbc);
-
}
HBoxContainer *hhb = memnew( HBoxContainer );
+
+ btn_mode = memnew( CheckButton );
+ btn_mode->set_text("RAW Mode");
+ btn_mode->connect("toggled", this, "set_raw_mode");
+ hhb->add_child(btn_mode);
vbr->add_child(hhb);
html_num = memnew( Label );
hhb->add_child(html_num);
@@ -309,11 +500,49 @@ ColorPicker::ColorPicker() {
html->set_h_size_flags(SIZE_EXPAND_FILL);
- mode=MODE_RGB;
_update_controls();
_update_color();
updating=false;
+ uv_material.instance();
+ Ref<Shader> s_uv = get_shader("uv_editor");
+ uv_material->set_shader(s_uv);
+
+ w_material.instance();
+
+ Ref<Shader> s_w = get_shader("w_editor");
+ w_material->set_shader(s_w);
+
+ uv_edit->set_material(uv_material);
+ w_edit->set_material(w_material);
+
+ set_color(Color(1,1,1));
+
+ i.create(256,20,false,Image::FORMAT_RGB);
+ for (int y=0;y<20;y++)
+ for(int x=0;x<256;x++)
+ if ((x/4+y/4)%2)
+ i.put_pixel(x,y,Color(1,1,1));
+ else
+ i.put_pixel(x,y,Color(0.6,0.6,0.6));
+ Ref<ImageTexture> t_smpl;
+ t_smpl.instance();
+ t_smpl->create_from_image(i);
+ sample->set_texture(t_smpl);
+
+ HBoxContainer *bbc = memnew( HBoxContainer );
+ add_child(bbc);
+
+ preset = memnew( TextureFrame );
+ bbc->add_child(preset);
+ preset->set_ignore_mouse(false);
+ preset->connect("input_event", this, "_preset_input");
+
+ bt_add_preset = memnew ( Button );
+ bt_add_preset->set_icon(get_icon("add_preset"));
+ bt_add_preset->set_tooltip("Add current color as a preset");
+ bt_add_preset->connect("pressed", this, "_add_preset_pressed");
+ bbc->add_child(bt_add_preset);
}
@@ -331,7 +560,7 @@ void ColorPickerButton::_color_changed(const Color& p_color) {
void ColorPickerButton::pressed() {
- Size2 ms = Size2(350, picker->get_combined_minimum_size().height+10);
+ Size2 ms = Size2(300, picker->get_combined_minimum_size().height+10);
popup->set_pos(get_global_pos()-Size2(0,ms.height));
popup->set_size(ms);
popup->popup();
@@ -347,7 +576,6 @@ void ColorPickerButton::_notification(int p_what) {
}
}
-
void ColorPickerButton::set_color(const Color& p_color){
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 95c26a9c6f..c6c7fe537d 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -36,25 +36,29 @@
#include "scene/gui/button.h"
#include "scene/gui/popup.h"
#include "scene/gui/box_container.h"
-#include "scene/gui/option_button.h"
+#include "scene/gui/texture_frame.h"
+#include "scene/gui/tool_button.h"
+#include "scene/gui/check_button.h"
+#include "scene/resources/material.h"
-class ColorPicker : public HBoxContainer {
+class ColorPicker : public BoxContainer {
- OBJ_TYPE(ColorPicker,HBoxContainer);
-public:
+ OBJ_TYPE(ColorPicker,BoxContainer);
- enum Mode {
- MODE_RGB,
- MODE_HSV,
- MODE_RAW
- };
private:
- Mode mode;
-
- OptionButton *mode_box;
-
- Control *color_box;
+ Control *screen;
+ Image last_capture;
+ TextureFrame *uv_edit;
+ TextureFrame *w_edit;
+ TextureFrame *sample;
+ TextureFrame *preset;
+ Button *bt_add_preset;
+ List<Color> presets;
+ ToolButton *btn_pick;
+ CheckButton *btn_mode;
+ Ref<CanvasItemMaterial> uv_material;
+ Ref<CanvasItemMaterial> w_material;
HSlider *scroll[4];
SpinBox *values[4];
Label *labels[4];
@@ -64,13 +68,25 @@ private:
Size2i ms;
Color color;
+ bool raw_mode_enabled;
bool updating;
+ bool changing_color;
+ float h,s,v;
void _html_entered(const String& p_html);
void _value_changed(double);
void _update_controls();
void _update_color();
- void _color_box_draw();
+ void _update_presets();
+ void _sample_draw();
+ void _hsv_draw(int p_wich,Control *c);
+
+ void _uv_input(const InputEvent& p_input);
+ void _w_input(const InputEvent& p_input);
+ void _preset_input(const InputEvent& p_input);
+ void _screen_input(const InputEvent& p_input);
+ void _add_preset_pressed();
+ void _screen_pick_pressed();
protected:
void _notification(int);
@@ -83,15 +99,14 @@ public:
void set_color(const Color& p_color);
Color get_color() const;
- void set_mode(Mode p_mode);
- Mode get_mode() const;
+ void add_preset(const Color& p_color);
+ void set_raw_mode(bool p_enabled);
+ bool is_raw_mode() const;
ColorPicker();
};
-VARIANT_ENUM_CAST( ColorPicker::Mode );
-
class ColorPickerButton : public Button {
OBJ_TYPE(ColorPickerButton,Button);
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 5a8ecfeffe..90c72989bd 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -42,37 +42,6 @@
#include <stdio.h>
-class TooltipPanel : public Panel {
-
- OBJ_TYPE(TooltipPanel,Panel)
-public:
- TooltipPanel() {};
-
-};
-
-class TooltipLabel : public Label {
-
- OBJ_TYPE(TooltipLabel,Label)
-public:
- TooltipLabel() {};
-
-};
-
-Control::Window::Window() {
-
-
- mouse_focus=NULL;
- mouse_focus_button=-1;
- key_focus=NULL;
- mouse_over=NULL;
- disable_input=false;
-
- cancelled_input_ID=0;
- tooltip=NULL;
- tooltip_popup=NULL;
- tooltip_label=NULL;
- subwindow_order_dirty=false;
-}
Variant Control::edit_get_state() const {
@@ -140,6 +109,11 @@ bool Control::_set(const StringName& p_name, const Variant& p_value) {
data.icon_override.erase(dname);
notification(NOTIFICATION_THEME_CHANGED);
update();
+ } else if (name.begins_with("custom_shaders/")) {
+ String dname = name.get_slicec('/',1);
+ data.shader_override.erase(dname);
+ notification(NOTIFICATION_THEME_CHANGED);
+ update();
} else if (name.begins_with("custom_styles/")) {
String dname = name.get_slicec('/',1);
data.style_override.erase(dname);
@@ -168,6 +142,10 @@ bool Control::_set(const StringName& p_name, const Variant& p_value) {
String dname = name.get_slicec('/',1);
notification(NOTIFICATION_THEME_CHANGED);
add_icon_override(dname,p_value);
+ } else if (name.begins_with("custom_shaders/")) {
+ String dname = name.get_slicec('/',1);
+ add_shader_override(dname,p_value);
+ notification(NOTIFICATION_THEME_CHANGED);
} else if (name.begins_with("custom_styles/")) {
String dname = name.get_slicec('/',1);
add_style_override(dname,p_value);
@@ -220,6 +198,10 @@ bool Control::_get(const StringName& p_name,Variant &r_ret) const {
String name = sname.get_slicec('/',1);
r_ret= data.icon_override.has(name)?Variant(data.icon_override[name]):Variant();
+ } else if (sname.begins_with("custom_shaders/")) {
+ String name = sname.get_slicec('/',1);
+
+ r_ret= data.shader_override.has(name)?Variant(data.shader_override[name]):Variant();
} else if (sname.begins_with("custom_styles/")) {
String name = sname.get_slicec('/',1);
@@ -269,6 +251,18 @@ void Control::_get_property_list( List<PropertyInfo> *p_list) const {
}
{
List<StringName> names;
+ theme->get_shader_list(get_type_name(),&names);
+ for(List<StringName>::Element *E=names.front();E;E=E->next()) {
+
+ uint32_t hint= PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_CHECKABLE;
+ if (data.shader_override.has(E->get()))
+ hint|=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_CHECKED;
+
+ p_list->push_back( PropertyInfo(Variant::OBJECT,"custom_shaders/"+E->get(),PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemShader,CanvasItemShaderGraph",hint) );
+ }
+ }
+ {
+ List<StringName> names;
theme->get_stylebox_list(get_type_name(),&names);
for(List<StringName>::Element *E=names.front();E;E=E->next()) {
@@ -325,19 +319,6 @@ Control *Control::get_parent_control() const {
return data.parent;
}
-void Control::_input_text(const String& p_text) {
-
- if (!window)
- return;
- if (window->key_focus)
- window->key_focus->call("set_text",p_text);
-
-}
-
-void Control::_gui_input(const InputEvent& p_event) {
-
- _window_input_event(p_event);
-}
void Control::_resize(const Size2& p_size) {
@@ -353,79 +334,12 @@ void Control::_notification(int p_notification) {
case NOTIFICATION_ENTER_TREE: {
- if (data.window==this) {
-
- window = memnew( Window );
- add_to_group("_vp_gui_input"+itos(get_viewport()->get_instance_ID()));
- add_to_group("windows");
-
- window->tooltip_timer = memnew( Timer );
- add_child(window->tooltip_timer);
- window->tooltip_timer->force_parent_owned();
- window->tooltip_timer->set_wait_time( GLOBAL_DEF("display/tooltip_delay",0.7));
- window->tooltip_timer->connect("timeout",this,"_window_show_tooltip");
- window->tooltip=NULL;
- window->tooltip_popup = memnew( TooltipPanel );
- add_child(window->tooltip_popup);
- window->tooltip_popup->force_parent_owned();
- window->tooltip_label = memnew( TooltipLabel );
- window->tooltip_popup->add_child(window->tooltip_label);
- window->tooltip_popup->set_as_toplevel(true);
- window->tooltip_popup->hide();
- window->drag_attempted=false;
- window->drag_preview=NULL;
-
- if (get_tree()->is_editor_hint()) {
-
- Node *n = this;
- while(n) {
-
- if (n->has_meta("_editor_disable_input")) {
- window->disable_input=true;
- break;
- }
- n=n->get_parent();
- }
- }
-
- } else {
- window=NULL;
- }
-
_size_changed();
} break;
case NOTIFICATION_EXIT_TREE: {
- if (data.window) {
-
- if (data.window->window->mouse_focus == this)
- data.window->window->mouse_focus=NULL;
- if (data.window->window->key_focus == this)
- data.window->window->key_focus=NULL;
- if (data.window->window->mouse_over == this)
- data.window->window->mouse_over=NULL;
- if (data.window->window->tooltip == this)
- data.window->window->tooltip=NULL;
- }
-
- if (window) {
-
- remove_from_group("_vp_gui_input"+itos(get_viewport()->get_instance_ID()));
- remove_from_group("windows");
- if (window->tooltip_timer)
- memdelete(window->tooltip_timer);
- window->tooltip_timer=NULL;
- window->tooltip=NULL;
- if (window->tooltip_popup)
- memdelete(window->tooltip_popup);
- window->tooltip_popup=NULL;
-
- memdelete(window);
- window=NULL;
-
- }
-
+ get_viewport()->_gui_remove_control(this);
} break;
@@ -433,112 +347,94 @@ void Control::_notification(int p_notification) {
case NOTIFICATION_ENTER_CANVAS: {
- data.window=NULL;
- data.viewport=NULL;
- data.parent=NULL;
-
- Control *_window=this;
- bool gap=false;
- bool gap_valid=true;
- bool window_found=false;
+ data.parent=get_parent()->cast_to<Control>();
- Node *parent=_window->get_parent();
- if (parent && parent->cast_to<Control>()) {
+ if (is_set_as_toplevel()) {
+ data.SI=get_viewport()->_gui_add_subwindow_control(this);
+ } else {
- data.parent=parent->cast_to<Control>();
- }
- Viewport *viewport=NULL;
+ Node *parent=this; //meh
+ Node *parent_control=NULL;
+ bool subwindow=false;
- parent=this; //meh
+ while(parent) {
- while(parent) {
+ parent=parent->get_parent();
- Control *c=parent->cast_to<Control>();
+ if (!parent)
+ break;
- if (!window_found && c) {
- if (!gap && c!=this) {
- gap_valid=false;
+ CanvasItem *ci =parent->cast_to<CanvasItem>();
+ if (ci && ci->is_set_as_toplevel()) {
+ subwindow=true;
+ break;
}
- _window = c;
- }
-
- CanvasItem *ci =parent->cast_to<CanvasItem>();
+ if (parent->cast_to<Control>()) {
+ parent_control=parent->cast_to<Control>();
+ break;
+ } else if (ci) {
- if ((ci && ci->is_set_as_toplevel()) || !ci) {
- gap=true;
+ } else {
+ break;
+ }
}
- if (parent->cast_to<CanvasLayer>()) {
- window_found=true; //don't go beyond canvas layer
- }
- viewport =parent->cast_to<Viewport>();
- if (viewport) {
- break; //no go beyond viewport either
+ if (parent_control) {
+ //do nothing, has a parent control
+ } else if (subwindow) {
+ //is a subwindow (process input before other controls for that canvas)
+ data.SI=get_viewport()->_gui_add_subwindow_control(this);
+ } else {
+ //is a regular root control
+ data.RI=get_viewport()->_gui_add_root_control(this);
}
- parent=parent->get_parent();
- }
-
- data.window=_window;
- data.viewport=viewport;
- data.parent_canvas_item=get_parent_item();
-
- if (data.parent_canvas_item) {
-
- data.parent_canvas_item->connect("item_rect_changed",this,"_size_changed");
- } else if (data.viewport) {
+ data.parent_canvas_item=get_parent_item();
- //connect viewport
- data.viewport->connect("size_changed",this,"_size_changed");
- } else {
+ if (data.parent_canvas_item) {
+ data.parent_canvas_item->connect("item_rect_changed",this,"_size_changed");
+ } else {
+ //connect viewport
+ get_viewport()->connect("size_changed",this,"_size_changed");
+ }
}
- if (gap && gap_valid && data.window!=this) {
- //is a subwindow, conditions to meet subwindow status are quite complex..
- data.SI = data.window->window->subwindows.push_back(this);
- data.window->window->subwindow_order_dirty=true;
-
- }
-
} break;
case NOTIFICATION_EXIT_CANVAS: {
-
if (data.parent_canvas_item) {
data.parent_canvas_item->disconnect("item_rect_changed",this,"_size_changed");
data.parent_canvas_item=NULL;
- } else if (data.viewport) {
-
+ } else if (!is_set_as_toplevel()) {
//disconnect viewport
- data.viewport->disconnect("size_changed",this,"_size_changed");
- } else {
+ get_viewport()->disconnect("size_changed",this,"_size_changed");
}
if (data.MI) {
-
- if (data.window && data.window->window)
- data.window->window->modal_stack.erase(data.MI);
+ get_viewport()->_gui_remove_modal_control(data.MI);
data.MI=NULL;
}
if (data.SI) {
- //erase from subwindows
- if (data.window && data.window->window)
- data.window->window->subwindows.erase(data.SI);
+ get_viewport()->_gui_remove_subwindow_control(data.SI);
data.SI=NULL;
}
- data.viewport=NULL;
- data.window=NULL;
+ if (data.RI) {
+ get_viewport()->_gui_remove_root_control(data.RI);
+ data.RI=NULL;
+ }
+
data.parent=NULL;
+ data.parent_canvas_item=NULL;
} break;
@@ -569,8 +465,11 @@ void Control::_notification(int p_notification) {
data.parent->update();
update();
- if (data.SI && data.window) {
- data.window->window->subwindow_order_dirty=true;
+ if (data.SI) {
+ get_viewport()->_gui_set_subwindow_order_dirty();
+ }
+ if (data.RI) {
+ get_viewport()->_gui_set_root_order_dirty();
}
} break;
@@ -614,26 +513,8 @@ void Control::_notification(int p_notification) {
if (!is_visible()) {
- if (data.window->window->mouse_focus == this) {
- data.window->window->mouse_focus=NULL;
- }
- if (data.window==this) {
- window->drag_data=Variant();
- if (window->drag_preview) {
- memdelete( window->drag_preview);
- window->drag_preview=NULL;
- }
- }
-
- if (data.window->window->key_focus == this)
- data.window->window->key_focus=NULL;
- if (data.window->window->mouse_over == this)
- data.window->window->mouse_over=NULL;
- if (data.window->window->tooltip == this)
- data.window->window->tooltip=NULL;
- if (data.window->window->tooltip == this)
- data.window->window->tooltip=NULL;
+ get_viewport()->_gui_hid_control(this);
_modal_stack_remove();
minimum_size_changed();
@@ -647,10 +528,7 @@ void Control::_notification(int p_notification) {
} break;
case SceneTree::NOTIFICATION_WM_UNFOCUS_REQUEST: {
- if (!window)
- return;
- if (window->key_focus)
- window->key_focus->release_focus();
+ get_viewport()->_gui_unfocus_control(this);
} break;
@@ -726,617 +604,30 @@ void Control::drop_data(const Point2& p_point,const Variant& p_data){
void Control::force_drag(const Variant& p_data,Control *p_control) {
ERR_FAIL_COND(!is_inside_tree());
- ERR_FAIL_COND(!data.window);
ERR_FAIL_COND(p_data.get_type()==Variant::NIL);
+ get_viewport()->_gui_force_drag(p_data,p_control);
-
- data.window->window->drag_data=p_data;
- data.window->window->mouse_focus=NULL;
-
- if (p_control) {
- data.window->set_drag_preview(p_control);
- }
}
void Control::set_drag_preview(Control *p_control) {
- ERR_FAIL_NULL(p_control);
- ERR_FAIL_COND( !((Object*)p_control)->cast_to<Control>());
- ERR_FAIL_COND(!is_inside_tree() || !data.window);
- ERR_FAIL_COND(p_control->is_inside_tree());
- ERR_FAIL_COND(p_control->get_parent()!=NULL);
-
- if (data.window->window->drag_preview) {
- memdelete(data.window->window->drag_preview);
- }
- p_control->set_as_toplevel(true);
- p_control->set_pos(data.window->window->last_mouse_pos);
- data.window->add_child(p_control);
- if (data.window->window->drag_preview) {
- memdelete( data.window->window->drag_preview );
- }
-
- data.window->window->drag_preview=p_control;
-
-}
-
-
-Control* Control::_find_next_visible_control_at_pos(Node* p_node,const Point2& p_global,Matrix32& r_xform) const {
-
- return NULL;
+ ERR_FAIL_COND(!is_inside_tree());
+ get_viewport()->_gui_set_drag_preview(p_control);
}
-Control* Control::_find_control_at_pos(CanvasItem* p_node,const Point2& p_global,const Matrix32& p_xform,Matrix32& r_inv_xform) {
-
- if (p_node->cast_to<Viewport>())
- return NULL;
-
- Control *c=p_node->cast_to<Control>();
-
- if (c) {
- // print_line("at "+String(c->get_path())+" POS "+c->get_pos()+" bt "+p_xform);
- }
-
- if (c==data.window) {
- //try subwindows first!!
-
- c->_window_sort_subwindows(); // sort them
-
- for (List<Control*>::Element *E=c->window->subwindows.back();E;E=E->prev()) {
-
- Control *sw = E->get();
- if (!sw->is_visible())
- continue;
-
- Matrix32 xform;
- CanvasItem *pci = sw->get_parent_item();
- if (pci)
- xform=pci->get_global_transform();
-
- Control *ret = _find_control_at_pos(sw,p_global,xform,r_inv_xform);
- if (ret)
- return ret;
-
- }
- }
-
- if (p_node->is_hidden()) {
- //return _find_next_visible_control_at_pos(p_node,p_global,r_inv_xform);
- return NULL; //canvas item hidden, discard
- }
-
- Matrix32 matrix = p_xform * p_node->get_transform();
-
- if (!c || !c->clips_input() || c->has_point(matrix.affine_inverse().xform(p_global))) {
-
- for(int i=p_node->get_child_count()-1;i>=0;i--) {
-
- if (p_node==data.window->window->tooltip_popup)
- continue;
-
- CanvasItem *ci = p_node->get_child(i)->cast_to<CanvasItem>();
- if (!ci || ci->is_set_as_toplevel())
- continue;
-
- Control *ret=_find_control_at_pos(ci,p_global,matrix,r_inv_xform);;
- if (ret)
- return ret;
- }
- }
- if (!c)
- return NULL;
-
- matrix.affine_invert();
-
- //conditions for considering this as a valid control for return
- if (!c->data.ignore_mouse && c->has_point(matrix.xform(p_global)) && (!window->drag_preview || (c!=window->drag_preview && !window->drag_preview->is_a_parent_of(c)))) {
- r_inv_xform=matrix;
- return c;
- } else
- return NULL;
-}
-
-void Control::_window_cancel_input_ID(int p_input) {
-
- window->cancelled_input_ID=(unsigned int)p_input;
-}
-
-void Control::_window_remove_focus() {
-
- if (window->key_focus) {
- Node *f=window->key_focus;
- window->key_focus=NULL;
- f->notification( NOTIFICATION_FOCUS_EXIT,true );
-
- }
-}
-
-bool Control::window_has_modal_stack() const {
- if (!data.window)
- return false;
- return data.window->window->modal_stack.size();
-}
-
bool Control::is_window_modal_on_top() const {
- if (window_has_modal_stack())
- return data.window->window->modal_stack.back()->get()==this;
- return false;
-}
-
-void Control::_window_cancel_tooltip() {
-
- window->tooltip=NULL;
- if (window->tooltip_timer)
- window->tooltip_timer->stop();
- if (window->tooltip_popup)
- window->tooltip_popup->hide();
-
-}
-
-void Control::_window_show_tooltip() {
-
- if (!window->tooltip) {
- return;
- }
-
- String tooltip = window->tooltip->get_tooltip( window->tooltip->get_global_transform().xform_inv(window->tooltip_pos) );
- if (tooltip.length()==0)
- return; // bye
-
-
- if (!window->tooltip_label) {
- return;
- }
- Ref<StyleBox> ttp = get_stylebox("panel","TooltipPanel");
-
- window->tooltip_label->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,ttp->get_margin(MARGIN_LEFT));
- window->tooltip_label->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,ttp->get_margin(MARGIN_TOP));
- window->tooltip_label->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,ttp->get_margin(MARGIN_RIGHT));
- window->tooltip_label->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,ttp->get_margin(MARGIN_BOTTOM));
- window->tooltip_label->set_text(tooltip);
- Rect2 r(window->tooltip_pos+Point2(10,10),window->tooltip_label->get_combined_minimum_size()+ttp->get_minimum_size());
- Rect2 vr = get_viewport_rect();
- if (r.size.x+r.pos.x>vr.size.x)
- r.pos.x=vr.size.x-r.size.x;
- else if (r.pos.x<0)
- r.pos.x=0;
-
- if (r.size.y+r.pos.y>vr.size.y)
- r.pos.y=vr.size.y-r.size.y;
- else if (r.pos.y<0)
- r.pos.y=0;
-
- window->tooltip_popup->set_pos(r.pos);
- window->tooltip_popup->set_size(r.size);
-
- window->tooltip_popup->raise();
-
- window->tooltip_popup->show();
-}
-
-
-void Control::_window_call_input(Control *p_control,const InputEvent& p_input) {
-
-// _block();
-
- while(p_control) {
-
- p_control->call_multilevel(SceneStringNames::get_singleton()->_input_event,p_input);
- if (window->key_event_accepted)
- break;
- p_control->emit_signal(SceneStringNames::get_singleton()->input_event,p_input);
- if (p_control->is_set_as_toplevel()) {
- break;
- }
- if (window->key_event_accepted)
- break;
- if (p_control->data.stop_mouse && (p_input.type==InputEvent::MOUSE_BUTTON || p_input.type==InputEvent::MOUSE_MOTION))
- break;
- p_control=p_control->data.parent;
- }
-
- //_unblock();
-
-}
-
-void Control::_window_input_event(InputEvent p_event) {
-
-
-
- if (!window)
- return;
-
- if (window->disable_input)
- return;
-
- if (p_event.ID==window->cancelled_input_ID) {
- return;
- }
- if (!is_visible()) {
- return; //simple and plain
- }
- switch(p_event.type) {
-
- case InputEvent::MOUSE_BUTTON: {
-
-
- window->key_event_accepted=false;
-
- Point2 mpos =(get_canvas_transform()).affine_inverse().xform(Point2(p_event.mouse_button.x,p_event.mouse_button.y));
- if (p_event.mouse_button.pressed) {
-
-
-
- Size2 pos = mpos;
- if (window->mouse_focus && p_event.mouse_button.button_index!=window->mouse_focus_button) {
-
- //do not steal mouse focus and stuff
-
- } else {
-
-
- _window_sort_modal_stack();
- while (!window->modal_stack.empty()) {
-
- Control *top = window->modal_stack.back()->get();
- if (!top->has_point(top->get_global_transform().affine_inverse().xform(pos))) {
-
- if (top->data.modal_exclusive) {
- //cancel event, sorry, modal exclusive EATS UP ALL
- get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID);
- get_tree()->set_input_as_handled();
- return; // no one gets the event if exclusive NO ONE
- }
-
- top->notification(NOTIFICATION_MODAL_CLOSE);
- top->_modal_stack_remove();
- top->hide();
- } else {
- break;
- }
- }
-
-
-
- Matrix32 parent_xform;
-
- if (data.parent_canvas_item)
- parent_xform=data.parent_canvas_item->get_global_transform();
-
-
-
- window->mouse_focus = _find_control_at_pos(this,pos,parent_xform,window->focus_inv_xform);
- //print_line("has mf "+itos(window->mouse_focus!=NULL));
- window->mouse_focus_button=p_event.mouse_button.button_index;
-
- if (!window->mouse_focus) {
- break;
- }
-
- if (p_event.mouse_button.button_index==BUTTON_LEFT) {
- window->drag_accum=Vector2();
- window->drag_attempted=false;
- window->drag_data=Variant();
- }
-
-
- }
-
- p_event.mouse_button.global_x = pos.x;
- p_event.mouse_button.global_y = pos.y;
-
- pos = window->focus_inv_xform.xform(pos);
- p_event.mouse_button.x = pos.x;
- p_event.mouse_button.y = pos.y;
-
-#ifdef DEBUG_ENABLED
- if (ScriptDebugger::get_singleton()) {
-
- Array arr;
- arr.push_back(window->mouse_focus->get_path());
- arr.push_back(window->mouse_focus->get_type());
- ScriptDebugger::get_singleton()->send_message("click_ctrl",arr);
- }
-
- /*if (bool(GLOBAL_DEF("debug/print_clicked_control",false))) {
-
- print_line(String(window->mouse_focus->get_path())+" - "+pos);
- }*/
-#endif
-
- if (window->mouse_focus->get_focus_mode()!=FOCUS_NONE && window->mouse_focus!=window->key_focus && p_event.mouse_button.button_index==BUTTON_LEFT) {
- // also get keyboard focus
- window->mouse_focus->grab_focus();
- }
-
-
- if (window->mouse_focus->can_process()) {
- _window_call_input(window->mouse_focus,p_event);
- }
-
- get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID);
- get_tree()->set_input_as_handled();
-
- window->tooltip_popup->hide();
-
- } else {
-
- if (window->drag_preview && p_event.mouse_button.button_index==BUTTON_LEFT) {
- memdelete( window->drag_preview );
- window->drag_preview=NULL;
- }
-
- if (!window->mouse_focus) {
-
- if (window->mouse_over && window->drag_data.get_type()!=Variant::NIL && p_event.mouse_button.button_index==BUTTON_LEFT) {
-
- Size2 pos = mpos;
- pos = window->focus_inv_xform.xform(pos);
-
- window->mouse_over->drop_data(pos,window->drag_data);
- window->drag_data=Variant();
- //change mouse accordingly
- }
-
- break;
- }
-
- Size2 pos = mpos;
- p_event.mouse_button.global_x = pos.x;
- p_event.mouse_button.global_y = pos.y;
- pos = window->focus_inv_xform.xform(pos);
- p_event.mouse_button.x = pos.x;
- p_event.mouse_button.y = pos.y;
-
- if (window->mouse_focus->can_process()) {
- _window_call_input(window->mouse_focus,p_event);
- }
-
- if (p_event.mouse_button.button_index==window->mouse_focus_button) {
- window->mouse_focus=NULL;
- window->mouse_focus_button=-1;
- }
-
- if (window->drag_data.get_type()!=Variant::NIL && p_event.mouse_button.button_index==BUTTON_LEFT) {
- window->drag_data=Variant(); //always clear
- }
-
-
- get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID);
- get_tree()->set_input_as_handled();
-
- }
- } break;
- case InputEvent::MOUSE_MOTION: {
-
- window->key_event_accepted=false;
-
- Matrix32 localizer = (get_canvas_transform()).affine_inverse();
- Size2 pos = localizer.xform(Size2(p_event.mouse_motion.x,p_event.mouse_motion.y));
- Vector2 speed = localizer.basis_xform(Point2(p_event.mouse_motion.speed_x,p_event.mouse_motion.speed_y));
- Vector2 rel = localizer.basis_xform(Point2(p_event.mouse_motion.relative_x,p_event.mouse_motion.relative_y));
-
- window->last_mouse_pos=pos;
-
- Control *over = NULL;
-
- Matrix32 parent_xform;
- if (data.parent_canvas_item)
- parent_xform=data.parent_canvas_item->get_global_transform();
-
- // D&D
- if (!window->drag_attempted && window->mouse_focus && p_event.mouse_motion.button_mask&BUTTON_MASK_LEFT) {
-
- window->drag_accum+=rel;
- float len = window->drag_accum.length();
- if (len>10) {
- window->drag_data=window->mouse_focus->get_drag_data(window->focus_inv_xform.xform(pos)-window->drag_accum);
- if (window->drag_data.get_type()!=Variant::NIL) {
-
- window->mouse_focus=NULL;
- }
- window->drag_attempted=true;
- }
- }
-
-
- if (window->mouse_focus) {
- over=window->mouse_focus;
- //recompute focus_inv_xform again here
-
- } else {
-
- over = _find_control_at_pos(this,pos,parent_xform,window->focus_inv_xform);
- }
-
-
- if (window->drag_data.get_type()==Variant::NIL && over && !window->modal_stack.empty()) {
-
- Control *top = window->modal_stack.back()->get();
- if (over!=top && !top->is_a_parent_of(over)) {
-
- break; // don't send motion event to anything below modal stack top
- }
- }
-
- if (over!=window->mouse_over) {
-
- if (window->mouse_over)
- window->mouse_over->notification(NOTIFICATION_MOUSE_EXIT);
-
- if (over)
- over->notification(NOTIFICATION_MOUSE_ENTER);
-
- }
-
- window->mouse_over=over;
-
- get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_tooltip");
-
- if (window->drag_preview) {
- window->drag_preview->set_pos(pos);
- }
-
- if (!over) {
- OS::get_singleton()->set_cursor_shape(OS::CURSOR_ARROW);
- break;
- }
-
- p_event.mouse_motion.global_x = pos.x;
- p_event.mouse_motion.global_y = pos.y;
- p_event.mouse_motion.speed_x=speed.x;
- p_event.mouse_motion.speed_y=speed.y;
- p_event.mouse_motion.relative_x=rel.x;
- p_event.mouse_motion.relative_y=rel.y;
-
- if (p_event.mouse_motion.button_mask==0 && window->tooltip_timer) {
- //nothing pressed
-
- bool can_tooltip=true;
-
- if (!window->modal_stack.empty()) {
- if (window->modal_stack.back()->get()!=over && !window->modal_stack.back()->get()->is_a_parent_of(over))
- can_tooltip=false;
-
- }
-
-
- if (can_tooltip) {
-
- window->tooltip=over;
- window->tooltip_pos=(parent_xform * get_transform()).affine_inverse().xform(pos);
- window->tooltip_timer->start();
- }
- }
-
-
- pos = window->focus_inv_xform.xform(pos);
-
-
- p_event.mouse_motion.x = pos.x;
- p_event.mouse_motion.y = pos.y;
-
-
- CursorShape cursor_shape = over->get_cursor_shape(pos);
- OS::get_singleton()->set_cursor_shape( (OS::CursorShape)cursor_shape );
-
-
- if (over->can_process()) {
- _window_call_input(over,p_event);
- }
-
-
-
- get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID);
- get_tree()->set_input_as_handled();
-
-
- if (window->drag_data.get_type()!=Variant::NIL && p_event.mouse_motion.button_mask&BUTTON_MASK_LEFT) {
-
- /*bool can_drop =*/ over->can_drop_data(pos,window->drag_data);
- //change mouse accordingly i guess
- }
-
- } break;
- case InputEvent::ACTION:
- case InputEvent::JOYSTICK_BUTTON:
- case InputEvent::KEY: {
-
- if (window->key_focus) {
-
- window->key_event_accepted=false;
- if (window->key_focus->can_process()) {
- window->key_focus->call_multilevel("_input_event",p_event);
- if (window->key_focus) //maybe lost it
- window->key_focus->emit_signal(SceneStringNames::get_singleton()->input_event,p_event);
- }
-
-
- if (window->key_event_accepted) {
-
- get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID);
- break;
- }
- }
-
-
- if (p_event.is_pressed() && p_event.is_action("ui_cancel") && !window->modal_stack.empty()) {
-
- _window_sort_modal_stack();
- Control *top = window->modal_stack.back()->get();
- if (!top->data.modal_exclusive) {
-
- top->notification(NOTIFICATION_MODAL_CLOSE);
- top->_modal_stack_remove();
- top->hide();
- }
- }
-
-
- Control * from = window->key_focus ? window->key_focus : NULL; //hmm
-
- //keyboard focus
- //if (from && p_event.key.pressed && !p_event.key.mod.alt && !p_event.key.mod.meta && !p_event.key.mod.command) {
-
- if (from && p_event.is_pressed()) {
- Control * next=NULL;
-
- if (p_event.is_action("ui_focus_next")) {
-
- next = from->find_next_valid_focus();
- }
-
- if (p_event.is_action("ui_focus_prev")) {
-
- next = from->find_prev_valid_focus();
- }
-
- if (p_event.is_action("ui_up")) {
-
- next = from->_get_focus_neighbour(MARGIN_TOP);
- }
-
- if (p_event.is_action("ui_left")) {
-
- next = from->_get_focus_neighbour(MARGIN_LEFT);
- }
-
- if (p_event.is_action("ui_right")) {
-
- next = from->_get_focus_neighbour(MARGIN_RIGHT);
- }
-
- if (p_event.is_action("ui_down")) {
-
- next = from->_get_focus_neighbour(MARGIN_BOTTOM);
- }
-
-
- if (next) {
- next->grab_focus();
- get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_cancel_input_ID",p_event.ID);
- }
- }
+ if (!is_inside_tree())
+ return false;
- } break;
- }
+ return get_viewport()->_gui_is_modal_on_top(this);
}
-Control *Control::get_window() const {
-
- return data.window;
-}
-
-bool Control::is_window() const {
-
- return (is_inside_tree() && window);
-}
Size2 Control::get_minimum_size() const {
@@ -1384,6 +675,35 @@ Ref<Texture> Control::get_icon(const StringName& p_name,const StringName& p_type
}
+Ref<Shader> Control::get_shader(const StringName& p_name,const StringName& p_type) const {
+ if (p_type==StringName()) {
+
+ const Ref<Shader>* sdr = data.shader_override.getptr(p_name);
+ if (sdr)
+ return *sdr;
+ }
+
+ StringName type = p_type?p_type:get_type_name();
+
+ // try with custom themes
+ Control *theme_owner = data.theme_owner;
+
+ while(theme_owner) {
+
+ if (theme_owner->data.theme->has_shader(p_name, type))
+ return data.theme_owner->data.theme->get_shader(p_name, type );
+ Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to<Control>():NULL;
+
+ if (parent)
+ theme_owner=parent->data.theme_owner;
+ else
+ theme_owner=NULL;
+
+ }
+
+ return Theme::get_default()->get_shader( p_name, type );
+}
+
Ref<StyleBox> Control::get_stylebox(const StringName& p_name,const StringName& p_type) const {
if (p_type==StringName()) {
@@ -1530,7 +850,37 @@ 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
+{
+ if (p_type==StringName()) {
+ const Ref<Shader>* sdr = data.shader_override.getptr(p_name);
+ if (sdr)
+ return true;
+ }
+
+ StringName type = p_type?p_type:get_type_name();
+
+ // try with custom themes
+ Control *theme_owner = data.theme_owner;
+
+ while(theme_owner) {
+
+ if (theme_owner->data.theme->has_shader(p_name, type))
+ return true;
+ Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to<Control>():NULL;
+ if (parent)
+ theme_owner=parent->data.theme_owner;
+ else
+ theme_owner=NULL;
+
+ }
+
+ return Theme::get_default()->has_shader( p_name, type );
+
}
bool Control::has_stylebox(const StringName& p_name,const StringName& p_type) const {
@@ -1662,9 +1012,9 @@ Size2 Control::get_parent_area_size() const {
if (data.parent_canvas_item) {
parent_size=data.parent_canvas_item->get_item_rect().size;
- } else if (data.viewport) {
+ } else {
- parent_size=data.viewport->get_visible_rect().size;
+ parent_size=get_viewport()->get_visible_rect().size;
}
return parent_size;
@@ -1732,8 +1082,8 @@ float Control::_get_parent_range(int p_idx) const {
} if (data.parent_canvas_item) {
return data.parent_canvas_item->get_item_rect().size[p_idx&1];
- } else if (data.viewport) {
- return data.viewport->get_visible_rect().size[p_idx&1];
+ } else {
+ return get_viewport()->get_visible_rect().size[p_idx&1];
}
return 1.0;
@@ -1959,10 +1309,9 @@ Rect2 Control::get_global_rect() const {
}
Rect2 Control::get_window_rect() const {
-
+ ERR_FAIL_COND_V(!is_inside_tree(),Rect2());
Rect2 gr = get_global_rect();
- if (data.viewport)
- gr.pos+=data.viewport->get_visible_rect().pos;
+ gr.pos+=get_viewport()->get_visible_rect().pos;
return gr;
}
@@ -1996,7 +1345,14 @@ 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) {
+ ERR_FAIL_COND(p_shader.is_null());
+ data.shader_override[p_name]=p_shader;
+ notification(NOTIFICATION_THEME_CHANGED);
+ update();
}
void Control::add_style_override(const StringName& p_name, const Ref<StyleBox>& p_style) {
@@ -2104,7 +1460,17 @@ Control *Control::find_next_valid_focus() const {
}
if (!next_child) {
- next_child=get_window();
+
+ next_child=const_cast<Control*>(this);;
+ while(next_child) {
+
+ if (next_child->data.SI || next_child->data.RI)
+ break;
+ next_child=next_child->get_parent_control();
+
+ }
+
+
}
}
@@ -2222,128 +1588,69 @@ Control::FocusMode Control::get_focus_mode() const {
}
bool Control::has_focus() const {
- return (data.window && data.window->window->key_focus==this);
+ return is_inside_tree() && get_viewport()->_gui_control_has_focus(this);
}
void Control::grab_focus() {
ERR_FAIL_COND(!is_inside_tree());
- ERR_FAIL_COND(!data.window);
-
if (data.focus_mode==FOCUS_NONE)
return;
-
- //no need for change
- if (data.window->window->key_focus && data.window->window->key_focus==this)
- return;
-
- get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_window_remove_focus");
- data.window->window->key_focus=this;
- notification(NOTIFICATION_FOCUS_ENTER);
-#ifdef DEBUG_ENABLED
- if (GLOBAL_DEF("debug/print_clicked_control", false)) {
- print_line(String(get_path())+" - focus");
- };
-#endif
- update();
+
+ get_viewport()->_gui_control_grab_focus(this);
}
void Control::release_focus() {
ERR_FAIL_COND(!is_inside_tree());
- ERR_FAIL_COND(!data.window);
if (!has_focus())
return;
- get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,"windows","_window_remove_focus");
- //data.window->window->key_focus=this;
- //notification(NOTIFICATION_FOCUS_ENTER);
+ get_viewport()->_gui_remove_focus();
update();
}
bool Control::is_toplevel_control() const {
- return is_inside_tree() && (!data.parent_canvas_item && !window && is_set_as_toplevel());
+ return is_inside_tree() && (!data.parent_canvas_item && !data.RI && is_set_as_toplevel());
}
void Control::show_modal(bool p_exclusive) {
ERR_FAIL_COND(!is_inside_tree());
- ERR_FAIL_COND(!data.SI && data.window!=this);
- ERR_FAIL_COND(!data.window);
+ ERR_FAIL_COND(!data.SI);
if (is_visible())
hide();
- ERR_FAIL_COND( data.MI );
+ ERR_FAIL_COND( data.MI!=NULL );
show();
raise();
-
- data.window->window->modal_stack.push_back(this);
- data.MI = data.window->window->modal_stack.back();
data.modal_exclusive=p_exclusive;
- if (data.window->window->key_focus)
- data.modal_prev_focus_owner = data.window->window->key_focus->get_instance_ID();
- else
- data.modal_prev_focus_owner=0;
+ data.MI=get_viewport()->_gui_show_modal(this);
}
-void Control::_window_sort_subwindows() {
-
- if (!window->subwindow_order_dirty)
- return;
-
-
- window->modal_stack.sort_custom<CComparator>();
- window->subwindows.sort_custom<CComparator>();
-
- window->subwindow_order_dirty=false;
-
-}
-
-void Control::_window_sort_modal_stack() {
-
- window->modal_stack.sort_custom<CComparator>();
+void Control::_modal_set_prev_focus_owner(ObjectID p_prev) {
+ data.modal_prev_focus_owner=p_prev;
}
void Control::_modal_stack_remove() {
- List<Control*>::Element *next=NULL; //transfer the focus stack to the next
-
-
- if (data.window && data.MI) {
-
- next = data.MI->next();
-
-
- data.window->window->modal_stack.erase(data.MI);
- data.MI=NULL;
- }
-
- if (data.modal_prev_focus_owner) {
+ ERR_FAIL_COND(!is_inside_tree());
- if (!next) { //top of stack
+ if (!data.MI)
+ return;
- Object *pfo = ObjectDB::get_instance(data.modal_prev_focus_owner);
- Control *pfoc = pfo->cast_to<Control>();
- if (!pfoc)
- return;
+ get_viewport()->_gui_remove_from_modal_stack(data.MI,data.modal_prev_focus_owner);
- if (!pfoc->is_inside_tree() || !pfoc->is_visible())
- return;
- pfoc->grab_focus();
- } else {
-
- next->get()->data.modal_prev_focus_owner=data.modal_prev_focus_owner;
- }
+ data.MI=NULL;
+ data.modal_prev_focus_owner=0;
- data.modal_prev_focus_owner=0;
- }
}
void Control::_propagate_theme_changed(Control *p_owner) {
@@ -2381,17 +1688,11 @@ void Control::set_theme(const Ref<Theme>& p_theme) {
}
-void Control::_window_accept_event() {
+void Control::accept_event() {
- window->key_event_accepted=true;
if (is_inside_tree())
- get_tree()->set_input_as_handled();
+ get_viewport()->_gui_accept_event();
-}
-void Control::accept_event() {
-
- if (is_inside_tree() && get_window())
- get_window()->_window_accept_event();
}
@@ -2520,7 +1821,7 @@ Control *Control::_get_focus_neighbour(Margin p_margin,int p_count) {
if (c) {
if (c->data.SI)
break;
- if (c==data.window)
+ if (c->data.RI)
break;
}
base=base->get_parent();
@@ -2639,35 +1940,8 @@ void Control::grab_click_focus() {
ERR_FAIL_COND(!is_inside_tree());
- if (data.window && data.window->window->mouse_focus) {
-
- Window *w=data.window->window;
- if (w->mouse_focus==this)
- return;
- InputEvent ie;
- ie.type=InputEvent::MOUSE_BUTTON;
- InputEventMouseButton &mb=ie.mouse_button;
-
- //send unclic
-
- Point2 click =w->mouse_focus->get_global_transform().affine_inverse().xform(w->last_mouse_pos);
- mb.x=click.x;
- mb.y=click.y;
- mb.button_index=w->mouse_focus_button;
- mb.pressed=false;
- w->mouse_focus->call_deferred("_input_event",ie);
-
+ get_viewport()->_gui_grab_click_focus(this);
- w->mouse_focus=this;
- w->focus_inv_xform=w->mouse_focus->get_global_transform().affine_inverse();
- click =w->mouse_focus->get_global_transform().affine_inverse().xform(w->last_mouse_pos);
- mb.x=click.x;
- mb.y=click.y;
- mb.button_index=w->mouse_focus_button;
- mb.pressed=true;
- w->mouse_focus->call_deferred("_input_event",ie);
-
- }
}
void Control::minimum_size_changed() {
@@ -2716,8 +1990,7 @@ bool Control::is_stopping_mouse() const {
Control *Control::get_focus_owner() const {
ERR_FAIL_COND_V(!is_inside_tree(),NULL);
- ERR_FAIL_COND_V(!data.window,NULL);
- return data.window->window->key_focus;
+ return get_viewport()->_gui_get_focus_owner();
}
@@ -2776,22 +2049,14 @@ Vector2 Control::get_scale() const{
void Control::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("_window_input_event"),&Control::_window_input_event);
- ObjectTypeDB::bind_method(_MD("_gui_input"),&Control::_gui_input);
- ObjectTypeDB::bind_method(_MD("_input_text"),&Control::_input_text);
+
// ObjectTypeDB::bind_method(_MD("_window_resize_event"),&Control::_window_resize_event);
- ObjectTypeDB::bind_method(_MD("_window_remove_focus"),&Control::_window_remove_focus);
- ObjectTypeDB::bind_method(_MD("_cancel_input_ID"),&Control::_window_cancel_input_ID);
- ObjectTypeDB::bind_method(_MD("_cancel_tooltip"),&Control::_window_cancel_tooltip);
- ObjectTypeDB::bind_method(_MD("_window_show_tooltip"),&Control::_window_show_tooltip);
ObjectTypeDB::bind_method(_MD("_size_changed"),&Control::_size_changed);
ObjectTypeDB::bind_method(_MD("_update_minimum_size"),&Control::_update_minimum_size);
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("is_window"),&Control::is_window);
- ObjectTypeDB::bind_method(_MD("get_window"),&Control::get_window);
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);
@@ -2837,8 +2102,9 @@ 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);
ObjectTypeDB::bind_method(_MD("add_font_override","name","font:Font"),&Control::add_font_override);
ObjectTypeDB::bind_method(_MD("add_color_override","name","color"),&Control::add_color_override);
@@ -2965,15 +2231,15 @@ void Control::_bind_methods() {
}
Control::Control() {
- data.parent=NULL;
- data.window=NULL;
- data.viewport=NULL;
+ data.parent=NULL;
+
data.ignore_mouse=false;
data.stop_mouse=true;
- window=NULL;
+
data.SI=NULL;
data.MI=NULL;
+ data.RI=NULL;
data.modal=false;
data.theme_owner=NULL;
data.modal_exclusive=false;
@@ -2983,6 +2249,7 @@ Control::Control() {
data.expand=1;
data.pending_min_size_update=false;
data.rotation=0;
+ data.parent_canvas_item=NULL;
data.scale=Vector2(1,1);
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 0ead632aab..ab777a6a6c 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -124,7 +124,6 @@ private:
bool stop_mouse;
Control *parent;
- Control *window;
bool modal;
bool modal_exclusive;
Ref<Theme> theme;
@@ -134,81 +133,40 @@ private:
List<Control*>::Element *MI; //modal item
List<Control*>::Element *SI;
+ List<Control*>::Element *RI;
CanvasItem *parent_canvas_item;
- Viewport *viewport;
-
ObjectID modal_prev_focus_owner;
NodePath focus_neighbour[4];
HashMap<StringName, Ref<Texture>, StringNameHasher > icon_override;
+ HashMap<StringName, Ref<Shader>, StringNameHasher > shader_override;
HashMap<StringName, Ref<StyleBox>, StringNameHasher > style_override;
HashMap<StringName, Ref<Font>, StringNameHasher > font_override;
HashMap<StringName, Color, StringNameHasher > color_override;
HashMap<StringName, int, StringNameHasher > constant_override;
} data;
-
- struct Window {
- // info used when this is a window
-
- bool key_event_accepted;
- Control *mouse_focus;
- int mouse_focus_button;
- Control *key_focus;
- Control *mouse_over;
- Control *tooltip;
- Panel *tooltip_popup;
- Label *tooltip_label;
- Point2 tooltip_pos;
- Point2 last_mouse_pos;
- Point2 drag_accum;
- bool drag_attempted;
- Variant drag_data;
- Control *drag_preview;
- Timer *tooltip_timer;
- List<Control*> modal_stack;
- unsigned int cancelled_input_ID;
- Matrix32 focus_inv_xform;
- bool subwindow_order_dirty;
- List<Control*> subwindows;
- bool disable_input;
-
- Window();
- };
-
- Window *window;
-
+
// used internally
- Control* _find_next_visible_control_at_pos(Node* p_node,const Point2& p_global,Matrix32& r_xform) const;
Control* _find_control_at_pos(CanvasItem* p_node,const Point2& p_pos,const Matrix32& p_xform,Matrix32& r_inv_xform);
- void _window_sort_subwindows();
- void _window_accept_event();
- void _window_remove_focus();
- void _window_cancel_input_ID(int p_input);
- void _window_sort_modal_stack();
void _window_find_focus_neighbour(const Vector2& p_dir, Node *p_at, const Point2* p_points ,float p_min,float &r_closest_dist,Control **r_closest);
Control *_get_focus_neighbour(Margin p_margin,int p_count=0);
- void _window_call_input(Control *p_control,const InputEvent& p_input);
+
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;
float _a2s(float p_val, AnchorType p_anchor,float p_range) const;
- void _modal_stack_remove();
void _propagate_theme_changed(Control *p_owner);
void _change_notify_margins();
- void _window_cancel_tooltip();
- void _window_show_tooltip();
void _update_minimum_size();
void _update_scroll();
- void _gui_input(const InputEvent& p_event); //used by scene main loop
- void _input_text(const String& p_text);
void _resize(const Size2& p_size);
void _size_changed();
@@ -217,10 +175,13 @@ private:
void _set_rotation_deg(float p_rot);
float _get_rotation_deg() const;
+friend class Viewport;
+ void _modal_stack_remove();
+ void _modal_set_prev_focus_owner(ObjectID p_prev);
+
protected:
- bool window_has_modal_stack() const;
- virtual void _window_input_event(InputEvent p_event);
+ //virtual void _window_input_event(InputEvent p_event);
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
@@ -272,8 +233,6 @@ public:
bool is_window_modal_on_top() const;
- bool is_window() const;
- Control *get_window() const;
Control *get_parent_control() const;
@@ -357,18 +316,21 @@ public:
/* 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);
void add_font_override(const StringName& p_name, const Ref<Font>& p_font);
void add_color_override(const StringName& p_name, const Color& p_color);
void add_constant_override(const StringName& p_name, int p_constant);
Ref<Texture> get_icon(const StringName& p_name,const StringName& p_type=StringName()) const;
+ Ref<Shader> get_shader(const StringName &p_name, const StringName &p_type=StringName()) const;
Ref<StyleBox> get_stylebox(const StringName& p_name,const StringName& p_type=StringName()) const;
Ref<Font> get_font(const StringName& p_name,const StringName& p_type=StringName()) const;
Color get_color(const StringName& p_name,const StringName& p_type=StringName()) const;
int get_constant(const StringName& p_name,const StringName& p_type=StringName()) const;
bool has_icon(const StringName& p_name,const StringName& p_type=StringName()) const;
+ bool has_shader(const StringName& p_name,const StringName& p_type=StringName()) const;
bool has_stylebox(const StringName& p_name,const StringName& p_type=StringName()) const;
bool has_font(const StringName& p_name,const StringName& p_type=StringName()) const;
bool has_color(const StringName& p_name,const StringName& p_type=StringName()) const;
@@ -400,7 +362,7 @@ public:
Control();
~Control();
-
+
};
VARIANT_ENUM_CAST(Control::AnchorType);
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 03ef50c491..1f04985ec6 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -59,8 +59,6 @@ void Popup::_notification(int p_what) {
void Popup::_fix_size() {
- Control *window = get_window();
- ERR_FAIL_COND(!window);
#if 0
Point2 pos = get_pos();
@@ -182,14 +180,12 @@ void Popup::popup_centered_minsize(const Size2& p_minsize) {
void Popup::popup_centered(const Size2& p_size) {
- Control *window = get_window();
- ERR_FAIL_COND(!window);
-
+ Point2 window_size = get_viewport_rect().size;
emit_signal("about_to_show");
Rect2 rect;
rect.size = p_size==Size2()?get_size():p_size;
- Point2 window_size = window==this ? get_parent_area_size() :window->get_size();
+
rect.pos = ((window_size-rect.size)/2.0).floor();
set_pos( rect.pos );
set_size( rect.size );
@@ -209,13 +205,11 @@ void Popup::popup_centered(const Size2& p_size) {
void Popup::popup_centered_ratio(float p_screen_ratio) {
- Control *window = get_window();
- ERR_FAIL_COND(!window);
emit_signal("about_to_show");
Rect2 rect;
- Point2 window_size = window==this ? get_parent_area_size() :window->get_size();
+ Point2 window_size = get_viewport_rect().size;
rect.size = (window_size * p_screen_ratio).floor();
rect.pos = ((window_size-rect.size)/2.0).floor();
set_pos( rect.pos );
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index b0d089fcf3..d22f6a0229 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -109,7 +109,7 @@ void SplitContainer::_resort() {
int sep=get_constant("separation");
Ref<Texture> g = get_icon("grabber");
- if (collapsed || !dragger_visible) {
+ if (dragger_visibility==DRAGGER_HIDDEN_COLLAPSED) {
sep=0;
} else {
sep=MAX(sep,vertical?g->get_height():g->get_width());
@@ -221,7 +221,7 @@ Size2 SplitContainer::get_minimum_size() const {
Size2i minimum;
int sep=get_constant("separation");
Ref<Texture> g = get_icon("grabber");
- sep=dragger_visible?MAX(sep,vertical?g->get_height():g->get_width()):0;
+ sep=(dragger_visibility!=DRAGGER_HIDDEN_COLLAPSED)?MAX(sep,vertical?g->get_height():g->get_width()):0;
for(int i=0;i<2;i++) {
@@ -278,19 +278,19 @@ void SplitContainer::_notification(int p_what) {
if (collapsed || (!mouse_inside && get_constant("autohide")))
return;
- int sep=dragger_visible?get_constant("separation"):0;
+ int sep=dragger_visibility!=DRAGGER_HIDDEN_COLLAPSED?get_constant("separation"):0;
Ref<Texture> tex = get_icon("grabber");
Size2 size=get_size();
if (vertical) {
//draw_style_box( get_stylebox("bg"), Rect2(0,middle_sep,get_size().width,sep));
- if (dragger_visible)
+ if (dragger_visibility==DRAGGER_VISIBLE)
draw_texture(tex,Point2i((size.x-tex->get_width())/2,middle_sep+(sep-tex->get_height())/2));
} else {
//draw_style_box( get_stylebox("bg"), Rect2(middle_sep,0,sep,get_size().height));
- if (dragger_visible)
+ if (dragger_visibility==DRAGGER_VISIBLE)
draw_texture(tex,Point2i(middle_sep+(sep-tex->get_width())/2,(size.y-tex->get_height())/2));
}
@@ -301,7 +301,7 @@ void SplitContainer::_notification(int p_what) {
void SplitContainer::_input_event(const InputEvent& p_event) {
- if (collapsed || !_getch(0) || !_getch(1) || !dragger_visible)
+ if (collapsed || !_getch(0) || !_getch(1) || dragger_visibility!=DRAGGER_VISIBLE)
return;
if (p_event.type==InputEvent::MOUSE_BUTTON) {
@@ -400,19 +400,19 @@ void SplitContainer::set_collapsed(bool p_collapsed) {
}
-void SplitContainer::set_dragger_visible(bool p_true) {
+void SplitContainer::set_dragger_visibility(DraggerVisibility p_visibility) {
- dragger_visible=p_true;
+ dragger_visibility=p_visibility;
queue_sort();
update();
}
-bool SplitContainer::is_dragger_visible() const{
+SplitContainer::DraggerVisibility SplitContainer::get_dragger_visibility() const {
-
- return dragger_visible;
+ return dragger_visibility;
}
+
bool SplitContainer::is_collapsed() const {
@@ -429,15 +429,18 @@ void SplitContainer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_collapsed","collapsed"),&SplitContainer::set_collapsed);
ObjectTypeDB::bind_method(_MD("is_collapsed"),&SplitContainer::is_collapsed);
- ObjectTypeDB::bind_method(_MD("set_dragger_visible","visible"),&SplitContainer::set_dragger_visible);
- ObjectTypeDB::bind_method(_MD("is_dragger_visible"),&SplitContainer::is_dragger_visible);
+ ObjectTypeDB::bind_method(_MD("set_dragger_visibility","mode"),&SplitContainer::set_dragger_visibility);
+ ObjectTypeDB::bind_method(_MD("get_dragger_visibility"),&SplitContainer::get_dragger_visibility);
ADD_SIGNAL( MethodInfo("dragged",PropertyInfo(Variant::INT,"offset")));
ADD_PROPERTY( PropertyInfo(Variant::INT,"split/offset"),_SCS("set_split_offset"),_SCS("get_split_offset"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"split/collapsed"),_SCS("set_collapsed"),_SCS("is_collapsed"));
- ADD_PROPERTY( PropertyInfo(Variant::BOOL,"split/dragger_visible"),_SCS("set_dragger_visible"),_SCS("is_dragger_visible"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"split/dragger_visibility",PROPERTY_HINT_ENUM,"Visible,Hidden,Hidden & Collapsed"),_SCS("set_dragger_visibility"),_SCS("get_dragger_visibility"));
+ BIND_CONSTANT( DRAGGER_VISIBLE );
+ BIND_CONSTANT( DRAGGER_HIDDEN );
+ BIND_CONSTANT( DRAGGER_HIDDEN_COLLAPSED );
}
@@ -450,7 +453,7 @@ SplitContainer::SplitContainer(bool p_vertical) {
vertical=p_vertical;
dragging=false;
collapsed=false;
- dragger_visible=true;
+ dragger_visibility=DRAGGER_VISIBLE;
}
diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h
index c8cfa3d69b..f721d16310 100644
--- a/scene/gui/split_container.h
+++ b/scene/gui/split_container.h
@@ -35,7 +35,13 @@
class SplitContainer : public Container {
OBJ_TYPE(SplitContainer,Container);
-
+public:
+ enum DraggerVisibility {
+ DRAGGER_VISIBLE,
+ DRAGGER_HIDDEN,
+ DRAGGER_HIDDEN_COLLAPSED
+ };
+private:
bool vertical;
int expand_ofs;
int middle_sep;
@@ -43,7 +49,7 @@ class SplitContainer : public Container {
int drag_from;
int drag_ofs;
bool collapsed;
- bool dragger_visible;
+ DraggerVisibility dragger_visibility;
bool mouse_inside;
@@ -66,8 +72,8 @@ public:
void set_collapsed(bool p_collapsed);
bool is_collapsed() const;
- void set_dragger_visible(bool p_true);
- bool is_dragger_visible() const;
+ void set_dragger_visibility(DraggerVisibility p_visibility);
+ DraggerVisibility get_dragger_visibility() const;
virtual CursorShape get_cursor_shape(const Point2& p_pos=Point2i());
@@ -76,6 +82,7 @@ public:
SplitContainer(bool p_vertical=false);
};
+VARIANT_ENUM_CAST(SplitContainer::DraggerVisibility);
class HSplitContainer : public SplitContainer {