|
@@ -33,76 +33,145 @@
|
|
|
|
|
|
void WindowDialog::_post_popup() {
|
|
void WindowDialog::_post_popup() {
|
|
|
|
|
|
- dragging=false; //just in case
|
|
|
|
|
|
+ drag_type = DRAG_NONE; // just in case
|
|
}
|
|
}
|
|
|
|
|
|
bool WindowDialog::has_point(const Point2& p_point) const {
|
|
bool WindowDialog::has_point(const Point2& p_point) const {
|
|
|
|
|
|
|
|
+ Rect2 r(Point2(), get_size());
|
|
|
|
|
|
- int extra = get_constant("titlebar_height","WindowDialog");
|
|
|
|
- Rect2 r( Point2(), get_size() );
|
|
|
|
- r.pos.y-=extra;
|
|
|
|
- r.size.y+=extra;
|
|
|
|
- return r.has_point(p_point);
|
|
|
|
|
|
+ // Enlarge upwards for title bar.
|
|
|
|
+ int titlebar_height = get_constant("titlebar_height", "WindowDialog");
|
|
|
|
+ r.pos.y -= titlebar_height;
|
|
|
|
+ r.size.y += titlebar_height;
|
|
|
|
+
|
|
|
|
+ // Inflate by the resizable border thickness.
|
|
|
|
+ if (resizable) {
|
|
|
|
+ int scaleborder_size = get_constant("scaleborder_size", "WindowDialog");
|
|
|
|
+ r.pos.x -= scaleborder_size;
|
|
|
|
+ r.size.width += scaleborder_size * 2;
|
|
|
|
+ r.pos.y -= scaleborder_size;
|
|
|
|
+ r.size.height += scaleborder_size * 2;
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ return r.has_point(p_point);
|
|
}
|
|
}
|
|
|
|
|
|
void WindowDialog::_gui_input(const InputEvent& p_event) {
|
|
void WindowDialog::_gui_input(const InputEvent& p_event) {
|
|
|
|
|
|
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_LEFT) {
|
|
|
|
-
|
|
|
|
- if (p_event.mouse_button.pressed && p_event.mouse_button.y < 0)
|
|
|
|
- dragging=true;
|
|
|
|
- else if (dragging && !p_event.mouse_button.pressed)
|
|
|
|
- dragging=false;
|
|
|
|
|
|
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == BUTTON_LEFT) {
|
|
|
|
+
|
|
|
|
+ if (p_event.mouse_button.pressed) {
|
|
|
|
+ // Begin a possible dragging operation.
|
|
|
|
+ drag_type = _drag_hit_test(Point2(p_event.mouse_button.x, p_event.mouse_button.y));
|
|
|
|
+ if (drag_type != DRAG_NONE)
|
|
|
|
+ drag_offset = get_global_mouse_pos() - get_pos();
|
|
|
|
+ drag_offset_far = get_pos() + get_size() - get_global_mouse_pos();
|
|
|
|
+ } else if (drag_type != DRAG_NONE && !p_event.mouse_button.pressed) {
|
|
|
|
+ // End a dragging operation.
|
|
|
|
+ drag_type = DRAG_NONE;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
- if (p_event.type == InputEvent::MOUSE_MOTION && dragging) {
|
|
|
|
-
|
|
|
|
- Point2 rel( p_event.mouse_motion.relative_x, p_event.mouse_motion.relative_y );
|
|
|
|
- Point2 pos = get_pos();
|
|
|
|
-
|
|
|
|
- pos+=rel;
|
|
|
|
-
|
|
|
|
- if (pos.y<0)
|
|
|
|
- pos.y=0;
|
|
|
|
-
|
|
|
|
- set_pos(pos);
|
|
|
|
|
|
+ if (p_event.type == InputEvent::MOUSE_MOTION) {
|
|
|
|
+
|
|
|
|
+ if (drag_type == DRAG_NONE) {
|
|
|
|
+ // Update the cursor while moving along the borders.
|
|
|
|
+ CursorShape cursor = CURSOR_ARROW;
|
|
|
|
+ if (resizable) {
|
|
|
|
+ int preview_drag_type = _drag_hit_test(Point2(p_event.mouse_button.x, p_event.mouse_button.y));
|
|
|
|
+ switch (preview_drag_type) {
|
|
|
|
+ case DRAG_RESIZE_TOP:
|
|
|
|
+ case DRAG_RESIZE_BOTTOM:
|
|
|
|
+ cursor = CURSOR_VSIZE;
|
|
|
|
+ break;
|
|
|
|
+ case DRAG_RESIZE_LEFT:
|
|
|
|
+ case DRAG_RESIZE_RIGHT:
|
|
|
|
+ cursor = CURSOR_HSIZE;
|
|
|
|
+ break;
|
|
|
|
+ case DRAG_RESIZE_TOP + DRAG_RESIZE_LEFT:
|
|
|
|
+ case DRAG_RESIZE_BOTTOM + DRAG_RESIZE_RIGHT:
|
|
|
|
+ cursor = CURSOR_FDIAGSIZE;
|
|
|
|
+ break;
|
|
|
|
+ case DRAG_RESIZE_TOP + DRAG_RESIZE_RIGHT:
|
|
|
|
+ case DRAG_RESIZE_BOTTOM + DRAG_RESIZE_LEFT:
|
|
|
|
+ cursor = CURSOR_BDIAGSIZE;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (get_cursor_shape() != cursor)
|
|
|
|
+ set_default_cursor_shape(cursor);
|
|
|
|
+ } else {
|
|
|
|
+ // Update while in a dragging operation.
|
|
|
|
+ Point2 global_pos = get_global_mouse_pos();
|
|
|
|
+ global_pos.y = MAX(global_pos.y, 0); // Ensure title bar stays visible.
|
|
|
|
+
|
|
|
|
+ Rect2 rect = get_rect();
|
|
|
|
+ Size2 min_size = get_minimum_size();
|
|
|
|
+
|
|
|
|
+ if (drag_type == DRAG_MOVE) {
|
|
|
|
+ rect.pos = global_pos - drag_offset;
|
|
|
|
+ } else {
|
|
|
|
+ if (drag_type & DRAG_RESIZE_TOP) {
|
|
|
|
+ int bottom = rect.pos.y + rect.size.height;
|
|
|
|
+ int max_y = bottom - min_size.height;
|
|
|
|
+ rect.pos.y = MIN(global_pos.y - drag_offset.y, max_y);
|
|
|
|
+ rect.size.height = bottom - rect.pos.y;
|
|
|
|
+ } else if (drag_type & DRAG_RESIZE_BOTTOM) {
|
|
|
|
+ rect.size.height = global_pos.y - rect.pos.y + drag_offset_far.y;
|
|
|
|
+ }
|
|
|
|
+ if (drag_type & DRAG_RESIZE_LEFT) {
|
|
|
|
+ int right = rect.pos.x + rect.size.width;
|
|
|
|
+ int max_x = right - min_size.width;
|
|
|
|
+ rect.pos.x = MIN(global_pos.x - drag_offset.x, max_x);
|
|
|
|
+ rect.size.width = right - rect.pos.x;
|
|
|
|
+ } else if (drag_type & DRAG_RESIZE_RIGHT) {
|
|
|
|
+ rect.size.width = global_pos.x - rect.pos.x + drag_offset_far.x;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ set_size(rect.size);
|
|
|
|
+ set_pos(rect.pos);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void WindowDialog::_notification(int p_what) {
|
|
void WindowDialog::_notification(int p_what) {
|
|
|
|
|
|
- switch(p_what) {
|
|
|
|
-
|
|
|
|
|
|
+ switch (p_what) {
|
|
case NOTIFICATION_DRAW: {
|
|
case NOTIFICATION_DRAW: {
|
|
|
|
|
|
- RID ci = get_canvas_item();
|
|
|
|
- Size2 s = get_size();
|
|
|
|
- Ref<StyleBox> st = get_stylebox("panel","WindowDialog");
|
|
|
|
- st->draw(ci,Rect2(Point2(),s));
|
|
|
|
- int th = get_constant("title_height","WindowDialog");
|
|
|
|
- Color tc = get_color("title_color","WindowDialog");
|
|
|
|
- Ref<Font> font = get_font("title_font","WindowDialog");
|
|
|
|
- int ofs = (s.width-font->get_string_size(title).width)/2;
|
|
|
|
- //int ofs = st->get_margin(MARGIN_LEFT);
|
|
|
|
- draw_string(font,Point2(ofs,-th+font->get_ascent()),title,tc,s.width - st->get_minimum_size().width);
|
|
|
|
|
|
+ RID canvas = get_canvas_item();
|
|
|
|
+ Size2 size = get_size();
|
|
|
|
+
|
|
|
|
+ Ref<StyleBox> panel = get_stylebox("panel", "WindowDialog");
|
|
|
|
+ panel->draw(canvas, Rect2(Point2(), size));
|
|
|
|
|
|
|
|
+ int title_height = get_constant("title_height", "WindowDialog");
|
|
|
|
+ Color title_color = get_color("title_color", "WindowDialog");
|
|
|
|
+ Ref<Font> font = get_font("title_font", "WindowDialog");
|
|
|
|
+ int ofs = (size.width - font->get_string_size(title).width) / 2;
|
|
|
|
+ draw_string(font, Point2(ofs, -title_height + font->get_ascent()), title, title_color, size.width - panel->get_minimum_size().width);
|
|
|
|
|
|
} break;
|
|
} break;
|
|
|
|
+
|
|
case NOTIFICATION_THEME_CHANGED:
|
|
case NOTIFICATION_THEME_CHANGED:
|
|
case NOTIFICATION_ENTER_TREE: {
|
|
case NOTIFICATION_ENTER_TREE: {
|
|
|
|
+ close_button->set_normal_texture(get_icon("close", "WindowDialog"));
|
|
|
|
+ close_button->set_pressed_texture(get_icon("close", "WindowDialog"));
|
|
|
|
+ close_button->set_hover_texture(get_icon("close_hilite", "WindowDialog"));
|
|
|
|
+ close_button->set_anchor(MARGIN_LEFT, ANCHOR_END);
|
|
|
|
+ close_button->set_begin(Point2(get_constant("close_h_ofs", "WindowDialog"), -get_constant("close_v_ofs", "WindowDialog")));
|
|
|
|
+ } break;
|
|
|
|
|
|
- close_button->set_normal_texture( get_icon("close","WindowDialog"));
|
|
|
|
- close_button->set_pressed_texture( get_icon("close","WindowDialog"));
|
|
|
|
- close_button->set_hover_texture( get_icon("close_hilite","WindowDialog"));
|
|
|
|
- close_button->set_anchor(MARGIN_LEFT,ANCHOR_END);
|
|
|
|
- close_button->set_begin( Point2( get_constant("close_h_ofs","WindowDialog"), -get_constant("close_v_ofs","WindowDialog") ));
|
|
|
|
-
|
|
|
|
|
|
+ case NOTIFICATION_MOUSE_EXIT: {
|
|
|
|
+ // Reset the mouse cursor when leaving the resizable window border.
|
|
|
|
+ if (resizable && !drag_type) {
|
|
|
|
+ if (get_default_cursor_shape() != CURSOR_ARROW)
|
|
|
|
+ set_default_cursor_shape(CURSOR_ARROW);
|
|
|
|
+ }
|
|
} break;
|
|
} break;
|
|
}
|
|
}
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void WindowDialog::_closed() {
|
|
void WindowDialog::_closed() {
|
|
@@ -111,11 +180,48 @@ void WindowDialog::_closed() {
|
|
hide();
|
|
hide();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+int WindowDialog::_drag_hit_test(const Point2& pos) const {
|
|
|
|
+ int drag_type = DRAG_NONE;
|
|
|
|
+
|
|
|
|
+ if (resizable) {
|
|
|
|
+ int titlebar_height = get_constant("titlebar_height", "WindowDialog");
|
|
|
|
+ int scaleborder_size = get_constant("scaleborder_size", "WindowDialog");
|
|
|
|
+
|
|
|
|
+ Rect2 rect = get_rect();
|
|
|
|
+
|
|
|
|
+ if (pos.y < (-titlebar_height + scaleborder_size))
|
|
|
|
+ drag_type = DRAG_RESIZE_TOP;
|
|
|
|
+ else if (pos.y >= (rect.size.height - scaleborder_size))
|
|
|
|
+ drag_type = DRAG_RESIZE_BOTTOM;
|
|
|
|
+ if (pos.x < scaleborder_size)
|
|
|
|
+ drag_type |= DRAG_RESIZE_LEFT;
|
|
|
|
+ else if (pos.x >= (rect.size.width - scaleborder_size))
|
|
|
|
+ drag_type |= DRAG_RESIZE_RIGHT;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (drag_type == DRAG_NONE && pos.y < 0)
|
|
|
|
+ drag_type = DRAG_MOVE;
|
|
|
|
+
|
|
|
|
+ return drag_type;
|
|
|
|
+}
|
|
|
|
+
|
|
void WindowDialog::set_title(const String& p_title) {
|
|
void WindowDialog::set_title(const String& p_title) {
|
|
|
|
|
|
title=XL_MESSAGE(p_title);
|
|
title=XL_MESSAGE(p_title);
|
|
update();
|
|
update();
|
|
}
|
|
}
|
|
|
|
+String WindowDialog::get_title() const {
|
|
|
|
+
|
|
|
|
+ return title;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void WindowDialog::set_resizable(bool p_resizable) {
|
|
|
|
+ resizable = p_resizable;
|
|
|
|
+}
|
|
|
|
+bool WindowDialog::get_resizable() const {
|
|
|
|
+ return resizable;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
|
|
Size2 WindowDialog::get_minimum_size() const {
|
|
Size2 WindowDialog::get_minimum_size() const {
|
|
|
|
|
|
@@ -127,11 +233,6 @@ Size2 WindowDialog::get_minimum_size() const {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-String WindowDialog::get_title() const {
|
|
|
|
-
|
|
|
|
- return title;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
|
|
TextureButton *WindowDialog::get_close_button() {
|
|
TextureButton *WindowDialog::get_close_button() {
|
|
|
|
|
|
@@ -144,19 +245,23 @@ void WindowDialog::_bind_methods() {
|
|
ClassDB::bind_method( D_METHOD("_gui_input"),&WindowDialog::_gui_input);
|
|
ClassDB::bind_method( D_METHOD("_gui_input"),&WindowDialog::_gui_input);
|
|
ClassDB::bind_method( D_METHOD("set_title","title"),&WindowDialog::set_title);
|
|
ClassDB::bind_method( D_METHOD("set_title","title"),&WindowDialog::set_title);
|
|
ClassDB::bind_method( D_METHOD("get_title"),&WindowDialog::get_title);
|
|
ClassDB::bind_method( D_METHOD("get_title"),&WindowDialog::get_title);
|
|
|
|
+ ClassDB::bind_method( D_METHOD("set_resizable","resizable"),&WindowDialog::set_resizable);
|
|
|
|
+ ClassDB::bind_method( D_METHOD("get_resizable"), &WindowDialog::get_resizable);
|
|
ClassDB::bind_method( D_METHOD("_closed"),&WindowDialog::_closed);
|
|
ClassDB::bind_method( D_METHOD("_closed"),&WindowDialog::_closed);
|
|
ClassDB::bind_method( D_METHOD("get_close_button:TextureButton"),&WindowDialog::get_close_button);
|
|
ClassDB::bind_method( D_METHOD("get_close_button:TextureButton"),&WindowDialog::get_close_button);
|
|
|
|
|
|
ADD_PROPERTY( PropertyInfo(Variant::STRING,"window_title",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_DEFAULT_INTL),"set_title","get_title");
|
|
ADD_PROPERTY( PropertyInfo(Variant::STRING,"window_title",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_DEFAULT_INTL),"set_title","get_title");
|
|
|
|
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL,"resizable",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_DEFAULT_INTL),"set_resizable","get_resizable");
|
|
}
|
|
}
|
|
|
|
|
|
WindowDialog::WindowDialog() {
|
|
WindowDialog::WindowDialog() {
|
|
|
|
|
|
//title="Hello!";
|
|
//title="Hello!";
|
|
- dragging=false;
|
|
|
|
- close_button = memnew( TextureButton );
|
|
|
|
|
|
+ drag_type = DRAG_NONE;
|
|
|
|
+ resizable = false;
|
|
|
|
+ close_button = memnew(TextureButton);
|
|
add_child(close_button);
|
|
add_child(close_button);
|
|
- close_button->connect("pressed",this,"_closed");
|
|
|
|
|
|
+ close_button->connect("pressed", this, "_closed");
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -186,7 +291,7 @@ PopupDialog::~PopupDialog() {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-//
|
|
|
|
|
|
+// AcceptDialog
|
|
|
|
|
|
|
|
|
|
void AcceptDialog::_post_popup() {
|
|
void AcceptDialog::_post_popup() {
|