<commit_before>/*************************************************************************/
/*  dialogs.cpp                                                          */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                    http://www.godotengine.org                         */
/*************************************************************************/
/* Copyright (c) 2007-2017 <NAME>, <NAME>.                 */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#include "dialogs.h"
#include "line_edit.h"
#include "print_string.h"
#include "translation.h"

#ifdef TOOLS_ENABLED
#include "editor/editor_node.h"
#endif

void WindowDialog::_post_popup() {

	drag_type = DRAG_NONE; // just in case
}

void WindowDialog::_fix_size() {

	// Perhaps this should be called when the viewport resizes aswell or windows go out of bounds...

	// Ensure the whole window is visible.
	Point2i pos = get_global_pos();
	Size2i size = get_size();
	Size2i viewport_size = get_viewport_rect().size;

	// Windows require additional padding to keep the window chrome visible.
	Ref<StyleBox> panel = get_stylebox("panel", "WindowDialog");
	float top = panel->get_margin(MARGIN_TOP);
	float left = panel->get_margin(MARGIN_LEFT);
	float bottom = panel->get_margin(MARGIN_BOTTOM);
	float right = panel->get_margin(MARGIN_RIGHT);

	pos.x = MAX(left, MIN(pos.x, viewport_size.x - size.x - right));
	pos.y = MAX(top, MIN(pos.y, viewport_size.y - size.y - bottom));
	set_global_pos(pos);

	// Also resize the window to fit if a resize should be possible at all.
	if (resizable) {
		size.x = MIN(size.x, viewport_size.x - left - right);
		size.y = MIN(size.y, viewport_size.y - top - bottom);
		set_size(size);
	}
}

bool WindowDialog::has_point(const Point2 &p_point) const {

	Rect2 r(Point2(), get_size());

	// 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) {

	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) {

		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) {

	switch (p_what) {
		case NOTIFICATION_DRAW: {

			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;

		case NOTIFICATION_THEME_CHANGED:
		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;

		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;
#ifdef TOOLS_ENABLED
		case NOTIFICATION_POST_POPUP: {
			if (get_tree() && get_tree()->is_editor_hint())
				EditorNode::get_singleton()->dim_editor(true);
		} break;
		case NOTIFICATION_POPUP_HIDE: {
			if (get_tree() && get_tree()->is_editor_hint())
				EditorNode::get_singleton()->dim_editor(false);
		} break;<commit_msg>WindowDialog: Fix crash when running as ProjectManager<commit_after>/*************************************************************************/
/*  dialogs.cpp                                                          */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                    http://www.godotengine.org                         */
/*************************************************************************/
/* Copyright (c) 2007-2017 <NAME>, <NAME>.                 */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#include "dialogs.h"
#include "line_edit.h"
#include "print_string.h"
#include "translation.h"

#ifdef TOOLS_ENABLED
#include "editor/editor_node.h"
#endif

void WindowDialog::_post_popup() {

	drag_type = DRAG_NONE; // just in case
}

void WindowDialog::_fix_size() {

	// Perhaps this should be called when the viewport resizes aswell or windows go out of bounds...

	// Ensure the whole window is visible.
	Point2i pos = get_global_pos();
	Size2i size = get_size();
	Size2i viewport_size = get_viewport_rect().size;

	// Windows require additional padding to keep the window chrome visible.
	Ref<StyleBox> panel = get_stylebox("panel", "WindowDialog");
	float top = panel->get_margin(MARGIN_TOP);
	float left = panel->get_margin(MARGIN_LEFT);
	float bottom = panel->get_margin(MARGIN_BOTTOM);
	float right = panel->get_margin(MARGIN_RIGHT);

	pos.x = MAX(left, MIN(pos.x, viewport_size.x - size.x - right));
	pos.y = MAX(top, MIN(pos.y, viewport_size.y - size.y - bottom));
	set_global_pos(pos);

	// Also resize the window to fit if a resize should be possible at all.
	if (resizable) {
		size.x = MIN(size.x, viewport_size.x - left - right);
		size.y = MIN(size.y, viewport_size.y - top - bottom);
		set_size(size);
	}
}

bool WindowDialog::has_point(const Point2 &p_point) const {

	Rect2 r(Point2(), get_size());

	// 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) {

	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) {

		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) {

	switch (p_what) {
		case NOTIFICATION_DRAW: {

			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;

		case NOTIFICATION_THEME_CHANGED:
		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;

		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;
#ifdef TOOLS_ENABLED
		case NOTIFICATION_POST_POPUP: {
			if (get_tree() && get_tree()->is_editor_hint() && EditorNode::get_singleton())
				EditorNode::get_singleton()->dim_editor(true);
		} break;
		case NOTIFICATION_POPUP_HIDE: {
			if (get_tree() && get_tree()->is_editor_hint() && EditorNode::get_singleton())
				EditorNode::get_singleton()->dim_editor(false);
		} break;
{'fraction_non_alphanumeric': 0.14777412608305945, 'fraction_numerical': 0.003346280250971019, 'mean_word_length': 3.0474002418379684, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3910253', 'n_tokens_mistral': 5896, 'n_tokens_neox': 5210, 'n_words': 1259}