Actual line editing

This commit is contained in:
2024-08-31 11:53:28 +03:00
parent 1aa73b4367
commit 0e819d6e7e
4 changed files with 184 additions and 197 deletions

View File

@@ -195,7 +195,7 @@ text = "POI mode"
unique_name_in_owner = true
margin_top = 330.0
margin_right = 162.0
margin_bottom = 636.0
margin_bottom = 724.0
[node name="HSeparator" type="HSeparator" parent="VBoxContainer/v_road_lines"]
margin_right = 162.0
@@ -205,13 +205,13 @@ margin_bottom = 4.0
unique_name_in_owner = true
margin_top = 8.0
margin_right = 162.0
margin_bottom = 240.0
margin_bottom = 328.0
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/v_road_lines/road_lines_base"]
margin_left = 7.0
margin_top = 7.0
margin_right = 155.0
margin_bottom = 225.0
margin_bottom = 313.0
size_flags_horizontal = 3
size_flags_vertical = 3
@@ -234,32 +234,63 @@ margin_top = 122.0
margin_right = 148.0
margin_bottom = 146.0
[node name="road_lines_move_point" type="Button" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"]
[node name="road_lines_set_point" type="Button" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"]
unique_name_in_owner = true
margin_top = 150.0
margin_right = 148.0
margin_bottom = 170.0
text = "Move Point To Cursor"
text = "Set Point To Cursor"
[node name="road_lines_create_point" type="Button" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"]
[node name="road_lines_move_cursor" type="Button" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"]
unique_name_in_owner = true
margin_top = 174.0
margin_right = 148.0
margin_bottom = 194.0
text = "Move Cursor To Point"
[node name="HSeparator" type="HSeparator" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"]
margin_top = 198.0
margin_right = 148.0
margin_bottom = 202.0
[node name="road_lines_create_point" type="Button" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"]
unique_name_in_owner = true
margin_top = 206.0
margin_right = 148.0
margin_bottom = 226.0
text = "Create Point"
[node name="road_lines_remove_point" type="Button" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"]
unique_name_in_owner = true
margin_top = 230.0
margin_right = 148.0
margin_bottom = 250.0
text = "Remove Point"
[node name="HSeparator2" type="HSeparator" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"]
margin_top = 254.0
margin_right = 148.0
margin_bottom = 258.0
[node name="road_lines_create_new_line" type="Button" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"]
unique_name_in_owner = true
margin_top = 198.0
margin_top = 262.0
margin_right = 148.0
margin_bottom = 218.0
margin_bottom = 282.0
text = "Creeate New Line"
[node name="road_lines_delete_line" type="Button" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"]
unique_name_in_owner = true
margin_top = 286.0
margin_right = 148.0
margin_bottom = 306.0
text = "Delete Line"
[node name="road_lines_create_new_line_dlg" type="PanelContainer" parent="VBoxContainer/v_road_lines"]
unique_name_in_owner = true
margin_top = 244.0
margin_top = 332.0
margin_right = 162.0
margin_bottom = 306.0
margin_bottom = 394.0
[node name="v" type="VBoxContainer" parent="VBoxContainer/v_road_lines/road_lines_create_new_line_dlg"]
margin_left = 7.0
@@ -281,9 +312,9 @@ text = "Cancel"
[node name="v_npc" type="VBoxContainer" parent="VBoxContainer"]
unique_name_in_owner = true
margin_top = 640.0
margin_top = 728.0
margin_right = 162.0
margin_bottom = 662.0
margin_bottom = 750.0
[node name="HSeparator" type="HSeparator" parent="VBoxContainer/v_npc"]
margin_right = 162.0

View File

@@ -4,6 +4,7 @@
#include <scene/gui/item_list.h>
#include <scene/gui/button.h>
#include <scene/gui/line_edit.h>
#include <scene/gui/spin_box.h>
#include <scene/3d/immediate_geometry.h>
#include <scene/3d/camera.h>
#include <core/io/config_file.h>
@@ -107,6 +108,55 @@ protected:
}
};
class HandlePointSelection : public Object {
GDCLASS(HandlePointSelection, Object)
RoadLinesEditor *editor;
public:
HandlePointSelection(RoadLinesEditor *editor)
: Object()
, editor(editor)
{
SpinBox *sp_line_point =
editor->get_as_node<SpinBox>("%line_index");
sp_line_point->connect("value_changed", this,
"handle_value_change");
Button *bt_line_set_point =
editor->get_as_node<Button>("%road_lines_set_point");
bt_line_set_point->connect("pressed", this, "handle_set_point");
}
virtual ~HandlePointSelection()
{
Button *bt_line_set_point =
editor->get_as_node<Button>("%road_lines_set_point");
bt_line_set_point->disconnect("pressed", this,
"handle_set_point");
SpinBox *sp_line_point =
editor->get_as_node<SpinBox>("%line_index");
sp_line_point->disconnect("value_changed", this,
"handle_value_change");
}
protected:
void handle_value_change(float value)
{
int index = (int)value;
editor->set_line_index(index);
}
void handle_set_point()
{
editor->set_point_to_cursor();
}
static void _bind_methods()
{
ClassDB::bind_method(
D_METHOD("handle_value_change", "value"),
&HandlePointSelection::handle_value_change);
ClassDB::bind_method(D_METHOD("handle_set_point"),
&HandlePointSelection::handle_set_point);
}
};
class HandleCreateNewLine : public Object {
GDCLASS(HandleCreateNewLine, Object)
RoadLinesEditor *editor;
@@ -211,6 +261,7 @@ protected:
static HandleSelection *selection_handler = nullptr;
static HandleCreateNewLine *new_line_handler = nullptr;
static HandlePointSelection *point_selection_handler = nullptr;
RoadLinesEditor::RoadLinesEditor(WorldEditor *editor)
: active(false)
@@ -231,10 +282,64 @@ Node *RoadLinesEditor::scene()
}
static String current_line = "";
void RoadLinesEditor::update_line_geometry()
{
if (!lines.has(current_line)) {
if (line_im)
line_im->clear();
return;
}
if (line_im) {
int i;
line_im->clear();
line_im->begin(Mesh::PRIMITIVE_LINES);
line_im->set_color(Color(1.0f, 0.0f, 0.0f, 1.0f));
line_im->add_vertex(Vector3(0.0f, -100.0f, 0.0f));
line_im->set_color(Color(1.0f, 0.0f, 0.0f, 1.0f));
line_im->add_vertex(Vector3(0.0f, 100.0f, 0.0f));
line_im->end();
if (lines[current_line].points.size() > 1) {
line_im->begin(Mesh::PRIMITIVE_LINES);
for (i = 0;
i < (int)lines[current_line].points.size() - 1;
i++) {
Vector3 pt1 =
lines[current_line].points[i].origin;
Vector3 pt2 =
lines[current_line].points[i + 1].origin;
line_im->set_color(
Color(0.0f, 0.0f, 0.5f, 1.0f));
line_im->add_vertex(pt1);
line_im->set_color(
Color(0.0f, 0.0f, 0.5f, 1.0f));
line_im->add_vertex(pt2);
line_im->set_color(
Color(0.0f, 0.0f, 0.5f, 1.0f));
line_im->add_vertex(pt2);
line_im->set_color(
Color(0.0f, 0.0f, 0.5f, 1.0f));
line_im->add_vertex(pt2 +
Vector3(0.0f, 1.0f, 0.0f));
}
line_im->end();
}
}
}
void RoadLinesEditor::select_line(const String &line_name)
{
print_line("selected line: " + line_name);
current_line = line_name;
assert(lines.has(line_name));
if (current_line != line_name) {
SpinBox *sp_line_index = get_as_node<SpinBox>("%line_index");
sp_line_index->set_max(lines[line_name].points.size() - 1);
sp_line_index->set_min(0);
current_line = line_name;
sp_line_index->set_value(0);
/* as actual index of SpinBox might not change
call point selection explicitly */
set_line_index(0);
update_line_geometry();
}
update_ui();
}
@@ -243,6 +348,17 @@ bool RoadLinesEditor::line_exists(const String &line_name)
return lines.has(line_name);
}
void RoadLinesEditor::set_point_to_cursor()
{
print_line("set_point_to_cursor");
Spatial *cursor = get_as_node<Spatial>("%line_cursor");
Transform xform = cursor->get_global_transform();
SpinBox *sp_line_index = get_as_node<SpinBox>("%line_index");
int index = (int)sp_line_index->get_value();
lines[current_line].points[index].origin = xform.origin;
update_line_geometry();
}
void RoadLinesEditor::update(float delta)
{
if (!active)
@@ -273,15 +389,8 @@ void RoadLinesEditor::editor_event(const String &event, const Array &args)
print_line("RoadLinesEditor::event: " + event);
if (event == "mouse_press") {
if (cursor_enabled) {
/* Raycasting outside physics process */
Spatial *cursor = get_as_node<Spatial>("%line_cursor");
/*
var camera = get_viewport().get_camera()
var start = camera.project_ray_origin(position)
var normal = camera.project_ray_normal(position)
var end = start + normal * camera.get_zfar()
var space_state = get_world().direct_space_state
var result = space_state.intersect_ray(start, end, [], 1 << 15, false, true)
*/
Vector2 position = args[0];
Camera *cam = editor->get_viewport()->get_camera();
Vector3 start = cam->project_ray_origin(position);
@@ -330,7 +439,8 @@ void RoadLinesEditor::update_ui()
e = e->next();
index++;
}
lines_list->set_current(selected_index);
if (selected_index >= 0)
lines_list->set_current(selected_index);
}
void RoadLinesEditor::create_new_line_at_cursor(const String &line_name)
@@ -338,6 +448,18 @@ void RoadLinesEditor::create_new_line_at_cursor(const String &line_name)
print_line("creating new line called: " + line_name);
}
void RoadLinesEditor::set_line_index(int index)
{
assert(lines.has(current_line));
assert(index < (int)lines[current_line].points.size());
Vector3 cursor_position = lines[current_line].points[index].origin;
Spatial *cursor = get_as_node<Spatial>("%line_cursor");
cursor->set_global_transform(Transform(Basis(), cursor_position));
Array pargs;
pargs.push_back(cursor_position);
editor->emit_signal("editor_event", "line_cursor_motion", pargs);
}
void RoadLinesEditor::activate()
{
assert(!active);
@@ -368,6 +490,8 @@ void RoadLinesEditor::activate()
selection_handler = memnew(HandleSelection(this));
if (!new_line_handler)
new_line_handler = memnew(HandleCreateNewLine(this));
if (!point_selection_handler)
point_selection_handler = memnew(HandlePointSelection(this));
active = true;
}
@@ -399,6 +523,10 @@ void RoadLinesEditor::deactivate()
memdelete(gd_editor_event);
gd_editor_event = nullptr;
}
if (point_selection_handler) {
memdelete(point_selection_handler);
point_selection_handler = nullptr;
}
active = false;
}

View File

@@ -11,8 +11,10 @@ public:
RoadLinesEditor(WorldEditor *editor);
virtual ~RoadLinesEditor();
Node *scene();
void update_line_geometry();
void select_line(const String &line_name);
bool line_exists(const String &line_name);
void set_point_to_cursor();
void update(float delta);
void exit();
void editor_command(const String &command, const Array &args);
@@ -20,6 +22,7 @@ public:
int get_camera_mode() const;
void update_ui();
void create_new_line_at_cursor(const String &line_name);
void set_line_index(int index);
template <class T> T *get_as_node(const String &path);
protected:

View File

@@ -1,175 +0,0 @@
From 9ba74bdb924158dfe1644a6dd9dbf7712b025dd2 Mon Sep 17 00:00:00 2001
From: pattlebass <49322676+pattlebass@users.noreply.github.com>
Date: Mon, 2 Jan 2023 15:15:36 +0200
Subject: [PATCH] Fix Range-derived nodes not redrawing
When using set_value_no_signal(), Range-derived nodes wouldn't redraw.
Also added a dedicated method to SpinBox to update its text.
---
scene/gui/range.cpp | 24 ++++++++++++++++++++++--
scene/gui/range.h | 2 ++
scene/gui/spin_box.cpp | 17 +++++++++++------
scene/gui/spin_box.h | 2 +-
4 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp
index 4d48cf307d..9d3ad6dec8 100644
--- a/scene/gui/range.cpp
+++ b/scene/gui/range.cpp
@@ -76,16 +76,26 @@ void Range::Shared::emit_changed(const char *p_what) {
}
}
+void Range::Shared::redraw_owners() {
+ for (Set<Range *>::Element *E = owners.front(); E; E = E->next()) {
+ Range *r = E->get();
+ if (!r->is_inside_tree()) {
+ continue;
+ }
+ r->update();
+ }
+}
+
void Range::set_value(double p_val) {
double prev_val = shared->val;
- set_value_no_signal(p_val);
+ _set_value_no_signal(p_val);
if (shared->val != prev_val) {
shared->emit_value_changed();
}
}
-void Range::set_value_no_signal(double p_val) {
+void Range::_set_value_no_signal(double p_val) {
if (shared->step > 0) {
p_val = Math::round((p_val - shared->min) / shared->step) * shared->step + shared->min;
}
@@ -108,6 +118,16 @@ void Range::set_value_no_signal(double p_val) {
shared->val = p_val;
}
+
+void Range::set_value_no_signal(double p_val) {
+ double prev_val = shared->val;
+ _set_value_no_signal(p_val);
+
+ if (shared->val != prev_val) {
+ shared->redraw_owners();
+ }
+}
+
void Range::set_min(double p_min) {
shared->min = p_min;
set_value(shared->val);
diff --git a/scene/gui/range.h b/scene/gui/range.h
index f64f2620e1..ea5f882f17 100644
--- a/scene/gui/range.h
+++ b/scene/gui/range.h
@@ -45,6 +45,7 @@ class Range : public Control {
Set<Range *> owners;
void emit_value_changed();
void emit_changed(const char *p_what = "");
+ void redraw_owners();
};
Shared *shared;
@@ -56,6 +57,7 @@ class Range : public Control {
void _value_changed_notify();
void _changed_notify(const char *p_what = "");
+ void _set_value_no_signal(double p_val);
protected:
virtual void _value_changed(double) {}
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 15561cf172..452b2c0456 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -38,7 +38,7 @@ Size2 SpinBox::get_minimum_size() const {
return ms;
}
-void SpinBox::_value_changed(double) {
+void SpinBox::_update_text() {
String value = String::num(get_value(), Math::range_step_decimals(get_step()));
if (!line_edit->has_focus()) {
@@ -66,7 +66,7 @@ void SpinBox::_text_entered(const String &p_string) {
if (value.get_type() != Variant::NIL) {
set_value(value);
}
- _value_changed(0);
+ _update_text();
}
LineEdit *SpinBox::get_line_edit() {
@@ -172,11 +172,15 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
void SpinBox::_line_edit_focus_enter() {
int col = line_edit->get_cursor_position();
- _value_changed(0); // Update the LineEdit's text.
+ _update_text();
line_edit->set_cursor_position(col);
}
void SpinBox::_line_edit_focus_exit() {
+ // discontinue because the focus_exit was caused by left-clicking the arrows.
+ if (get_focus_owner() == get_line_edit()) {
+ return;
+ }
// discontinue because the focus_exit was caused by right-click context menu
if (line_edit->get_menu()->is_visible()) {
return;
@@ -196,6 +200,7 @@ inline void SpinBox::_adjust_width_for_icon(const Ref<Texture> &icon) {
void SpinBox::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAW) {
Ref<Texture> updown = get_icon("updown");
+ _update_text();
_adjust_width_for_icon(updown);
@@ -208,7 +213,7 @@ void SpinBox::_notification(int p_what) {
//_value_changed(0);
} else if (p_what == NOTIFICATION_ENTER_TREE) {
_adjust_width_for_icon(get_icon("updown"));
- _value_changed(0);
+ _update_text();
} else if (p_what == NOTIFICATION_EXIT_TREE) {
_release_mouse();
} else if (p_what == NOTIFICATION_THEME_CHANGED) {
@@ -227,7 +232,7 @@ LineEdit::Align SpinBox::get_align() const {
void SpinBox::set_suffix(const String &p_suffix) {
suffix = p_suffix;
- _value_changed(0);
+ _update_text();
}
String SpinBox::get_suffix() const {
@@ -236,7 +241,7 @@ String SpinBox::get_suffix() const {
void SpinBox::set_prefix(const String &p_prefix) {
prefix = p_prefix;
- _value_changed(0);
+ _update_text();
}
String SpinBox::get_prefix() const {
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index b308b41647..49101fd90f 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -46,7 +46,7 @@ class SpinBox : public Range {
void _release_mouse();
void _text_entered(const String &p_string);
- virtual void _value_changed(double);
+ void _update_text();
String prefix;
String suffix;
double custom_arrow_step = 0.0;
--
2.34.1