Repository: godotengine/godot
File: editor/plugins/node_3d_editor_plugin.cpp (C++)

Code before:

			int h_sep = get_theme_constant(SNAME("separation"), SNAME("HSplitContainer"));
			int v_sep = get_theme_constant(SNAME("separation"), SNAME("VSplitContainer"));

			int mid_w = size.width * ratio_h;
			int mid_h = size.height * ratio_v;

			bool was_hovering_h = hovering_h;
			bool was_hovering_v = hovering_v;
			hovering_h = mm->get_position().x > (mid_w - h_sep / 2) && mm->get_position().x < (mid_w + h_sep / 2);
			hovering_v = mm->get_position().y > (mid_h - v_sep / 2) && mm->get_position().y < (mid_h + v_sep / 2);

			if (was_hovering_h != hovering_h || was_hovering_v != hovering_v) {
				queue_redraw();
			}
		}

		if (dragging_h) {
			real_t new_ratio = drag_begin_ratio.x + (mm->get_position().x - drag_begin_pos.x) / get_size().width;
			new_ratio = CLAMP(new_ratio, 40 / get_size().width, (get_size().width - 40) / get_size().width);
			ratio_h = new_ratio;
			queue_sort();
			queue_redraw();
		}
		if (dragging_v) {
			real_t new_ratio = drag_begin_ratio.y + (mm->get_position().y - drag_begin_pos.y) / get_size().height;
			new_ratio = CLAMP(new_ratio, 40 / get_size().height, (get_size().height - 40) / get_size().height);
			ratio_v = new_ratio;
			queue_sort();
			queue_redraw();
		}
	}
}

void Node3DEditorViewportContainer::_notification(int p_what) {
	switch (p_what) {
		case NOTIFICATION_MOUSE_ENTER:
		case NOTIFICATION_MOUSE_EXIT: {
			mouseover = (p_what == NOTIFICATION_MOUSE_ENTER);
			queue_redraw();
		} break;

		case NOTIFICATION_DRAW: {
			if (mouseover) {
				Ref<Texture2D> h_grabber = get_theme_icon(SNAME("grabber"), SNAME("HSplitContainer"));
				Ref<Texture2D> v_grabber = get_theme_icon(SNAME("grabber"), SNAME("VSplitContainer"));

				Ref<Texture2D> hdiag_grabber = get_editor_theme_icon(SNAME("GuiViewportHdiagsplitter"));
				Ref<Texture2D> vdiag_grabber = get_editor_theme_icon(SNAME("GuiViewportVdiagsplitter"));
				Ref<Texture2D> vh_grabber = get_editor_theme_icon(SNAME("GuiViewportVhsplitter"));


Review comment (suggestion):
Scale the outline for hiDPI displays (otherwise, the outline looks thinner relative to the font size):

```suggestion
	ruler_label->add_theme_constant_override("outline_size", 4 * EDSCALE);
```

Code after:
	ruler_material->set_depth_draw_mode(BaseMaterial3D::DEPTH_DRAW_DISABLED);

	ruler_material_xray.instantiate();
	ruler_material_xray->set_albedo(Color(1.0, 0.9, 0.0, 0.15));
	ruler_material_xray->set_flag(BaseMaterial3D::FLAG_DISABLE_FOG, true);
	ruler_material_xray->set_shading_mode(BaseMaterial3D::SHADING_MODE_UNSHADED);
	ruler_material_xray->set_flag(BaseMaterial3D::FLAG_DISABLE_DEPTH_TEST, true);
	ruler_material_xray->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA);
	ruler_material_xray->set_render_priority(BaseMaterial3D::RENDER_PRIORITY_MAX);

	geometry.instantiate();

	ruler_line = memnew(MeshInstance3D);
	ruler_line->set_mesh(geometry);
	ruler_line->set_material_override(ruler_material);

	ruler_line_xray = memnew(MeshInstance3D);
	ruler_line_xray->set_mesh(geometry);
	ruler_line_xray->set_material_override(ruler_material_xray);

	ruler_label = memnew(Label);
	ruler_label->add_theme_color_override(SceneStringName(font_color), Color(1.0, 0.9, 0.0, 1.0));
	ruler_label->add_theme_color_override("font_outline_color", Color(0.0, 0.0, 0.0, 1.0));
	ruler_label->add_theme_constant_override("outline_size", 4 * EDSCALE);
	ruler_label->add_theme_font_size_override(SceneStringName(font_size), 15 * EDSCALE);
	ruler_label->add_theme_font_override(SceneStringName(font), get_theme_font(SNAME("bold"), EditorStringName(EditorFonts)));
	ruler_label->set_visible(false);

	ruler->add_child(ruler_start_point);
	ruler->add_child(ruler_end_point);
	ruler->add_child(ruler_line);
	ruler->add_child(ruler_line_xray);

	viewport->add_child(ruler_label);

	view_type = VIEW_TYPE_USER;
	_update_name();

	EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &Node3DEditorViewport::update_transform_gizmo_view));
}

Node3DEditorViewport::~Node3DEditorViewport() {
	memdelete(ruler);
	memdelete(frame_time_gradient);
}

//////////////////////////////////////////////////////////////

void Node3DEditorViewportContainer::gui_input(const Ref<InputEvent> &p_event) {
	ERR_FAIL_COND(p_event.is_null());