Actual line editing
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user