Line filter is implemented

This commit is contained in:
2024-09-01 06:13:06 +03:00
parent 0e819d6e7e
commit 818c21ecac
3 changed files with 348 additions and 132 deletions

View File

@@ -5,11 +5,13 @@
#include <scene/gui/button.h>
#include <scene/gui/line_edit.h>
#include <scene/gui/spin_box.h>
#include <scene/gui/menu_button.h>
#include <scene/3d/immediate_geometry.h>
#include <scene/3d/camera.h>
#include <core/io/config_file.h>
#include <core/os/file_access.h>
#include <core/io/json.h>
#include <modules/regex/regex.h>
#include "world_editor.h"
#include "from_string.h"
#include "road_lines_editor.h"
@@ -75,19 +77,23 @@ public:
: Object()
, editor(editor)
{
Node *lines_list_node =
editor->scene()->get_node(NodePath("%lines_list"));
LineEdit *filter =
editor->get_as_node<LineEdit>("%road_lines_filter");
filter->connect("text_changed", this, "filter_handler");
filter->connect("text_entered", this, "filter_handler");
ItemList *lines_list =
Object::cast_to<ItemList>(lines_list_node);
editor->get_as_node<ItemList>("%lines_list");
lines_list->connect("item_selected", this, "handler");
}
virtual ~HandleSelection()
{
Node *lines_list_node =
editor->scene()->get_node(NodePath("%lines_list"));
ItemList *lines_list =
Object::cast_to<ItemList>(lines_list_node);
editor->get_as_node<ItemList>("%lines_list");
lines_list->disconnect("item_selected", this, "handler");
LineEdit *filter =
editor->get_as_node<LineEdit>("%road_lines_filter");
filter->disconnect("text_entered", this, "filter_handler");
filter->disconnect("text_changed", this, "filter_handler");
}
protected:
@@ -95,16 +101,20 @@ protected:
{
if (index < 0)
return;
Node *lines_list_node =
editor->scene()->get_node(NodePath("%lines_list"));
ItemList *lines_list =
Object::cast_to<ItemList>(lines_list_node);
editor->get_as_node<ItemList>("%lines_list");
editor->select_line(lines_list->get_item_text(index));
}
void filter_handler(const String &text)
{
editor->line_list_filter_changed(text);
}
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("handler", "index"),
&HandleSelection::handler);
ClassDB::bind_method(D_METHOD("filter_handler", "text"),
&HandleSelection::filter_handler);
}
};
@@ -121,16 +131,9 @@ public:
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,
@@ -147,6 +150,10 @@ protected:
{
editor->set_point_to_cursor();
}
void handle_move_cursor()
{
editor->move_cursor_to_point();
}
static void _bind_methods()
{
ClassDB::bind_method(
@@ -154,6 +161,8 @@ protected:
&HandlePointSelection::handle_value_change);
ClassDB::bind_method(D_METHOD("handle_set_point"),
&HandlePointSelection::handle_set_point);
ClassDB::bind_method(D_METHOD("handle_move_cursor"),
&HandlePointSelection::handle_move_cursor);
}
};
@@ -166,21 +175,31 @@ public:
: Object()
, editor(editor)
{
Button *main_button = editor->get_as_node<Button>(
"%road_lines_create_new_line");
int i;
Node *menu_block =
editor->get_as_node<Node>("%road_lines_menu_block");
for (i = 0; i < menu_block->get_child_count(); i++) {
Node *menu_button_node = menu_block->get_child(i);
MenuButton *menu_button =
Object::cast_to<MenuButton>(menu_button_node);
if (!menu_button)
continue;
PopupMenu *popup = menu_button->get_popup();
popup->connect("id_pressed", this, "main_handler");
// popup->connect("mouse_exited", popup, "hide");
popup->connect("focus_exited", popup, "hide");
}
Button *cancel_button = editor->get_as_node<Button>(
"%road_lines_create_new_cancel");
LineEdit *line_name = editor->get_as_node<LineEdit>(
"%road_lines_create_new_line_name");
main_button->connect("pressed", this, "main_handler");
cancel_button->connect("pressed", this, "cancel_handler");
line_name->connect("text_entered", this, "entered_handler");
line_name->connect("text_changed", this, "changed_handler");
}
virtual ~HandleCreateNewLine()
{
Button *main_button = editor->get_as_node<Button>(
"%road_lines_create_new_line");
int i;
Button *cancel_button = editor->get_as_node<Button>(
"%road_lines_create_new_cancel");
LineEdit *line_name = editor->get_as_node<LineEdit>(
@@ -188,15 +207,50 @@ public:
line_name->disconnect("text_changed", this, "changed_handler");
line_name->disconnect("text_entered", this, "entered_handler");
cancel_button->disconnect("pressed", this, "cancel_handler");
main_button->disconnect("pressed", this, "main_handler");
Node *menu_block =
editor->get_as_node<Node>("%road_lines_menu_block");
for (i = 0; i < menu_block->get_child_count(); i++) {
Node *menu_button_node = menu_block->get_child(i);
MenuButton *menu_button =
Object::cast_to<MenuButton>(menu_button_node);
if (!menu_button)
continue;
PopupMenu *popup = menu_button->get_popup();
popup->disconnect("id_pressed", this, "main_handler");
}
}
protected:
void main_handler()
void main_handler(int id)
{
editor->get_as_node<Control>("%road_lines_base")->hide();
editor->get_as_node<Control>("%road_lines_create_new_line_dlg")
->show();
switch (id) {
case 11:
/* TODO: create point */
break;
case 12:
/* TODO: delete point */
break;
case 21:
/* Create line */
editor->get_as_node<Control>("%road_lines_base")->hide();
editor->get_as_node<Control>(
"%road_lines_create_new_line_dlg")
->show();
break;
case 22:
/* TODO: delete line */
break;
case 51:
/* TODO: point to cursor */
editor->set_point_to_cursor();
break;
case 52:
/* TODO: cursor to point */
editor->move_cursor_to_point();
break;
default:
print_line("menu option pressed: " + itos(id));
}
}
void cancel_handler()
{
@@ -248,7 +302,7 @@ protected:
}
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("main_handler"),
ClassDB::bind_method(D_METHOD("main_handler", "id"),
&HandleCreateNewLine::main_handler);
ClassDB::bind_method(D_METHOD("cancel_handler"),
&HandleCreateNewLine::cancel_handler);
@@ -267,6 +321,7 @@ RoadLinesEditor::RoadLinesEditor(WorldEditor *editor)
: active(false)
, editor(editor)
, cursor_enabled(false)
, filter_text("")
{
}
@@ -274,6 +329,8 @@ RoadLinesEditor::~RoadLinesEditor()
{
if (active && editor->is_inside_tree())
deactivate();
if (re.is_valid())
re.unref();
}
Node *RoadLinesEditor::scene()
@@ -359,6 +416,16 @@ void RoadLinesEditor::set_point_to_cursor()
update_line_geometry();
}
void RoadLinesEditor::move_cursor_to_point()
{
print_line("move_cursor_to_point");
Spatial *cursor = get_as_node<Spatial>("%line_cursor");
SpinBox *sp_line_index = get_as_node<SpinBox>("%line_index");
int index = (int)sp_line_index->get_value();
Transform xform(Basis(), lines[current_line].points[index].origin);
cursor->set_global_transform(xform);
}
void RoadLinesEditor::update(float delta)
{
if (!active)
@@ -387,7 +454,7 @@ void RoadLinesEditor::editor_command(const String &command, const Array &args)
void RoadLinesEditor::editor_event(const String &event, const Array &args)
{
print_line("RoadLinesEditor::event: " + event);
if (event == "mouse_press") {
if (event == "mouse_press" || event == "mouse_drag") {
if (cursor_enabled) {
/* Raycasting outside physics process */
Spatial *cursor = get_as_node<Spatial>("%line_cursor");
@@ -400,6 +467,17 @@ void RoadLinesEditor::editor_event(const String &event, const Array &args)
editor->get_world()->get_direct_space_state();
PhysicsDirectSpaceState::RayResult result;
Set<RID> exclude;
space_state->intersect_ray(start, end, result, exclude,
(1 << 15) | (1 << 0), true,
true);
Vector3 result_pre;
if (result.rid == RID())
goto end;
result_pre = result.position;
result_pre.x = Math::stepify(result_pre.x, 2.0f);
result_pre.z = Math::stepify(result_pre.z, 2.0f);
start = result_pre + Vector3(0.0f, 200.0f, 0.0f);
end = result_pre - Vector3(0.0f, 200.0f, 0.0f);
space_state->intersect_ray(start, end, result, exclude,
(1 << 15) | (1 << 0), true,
true);
@@ -412,6 +490,7 @@ void RoadLinesEditor::editor_event(const String &event, const Array &args)
"line_cursor_motion",
pargs);
}
end:;
}
}
}
@@ -429,10 +508,20 @@ void RoadLinesEditor::update_ui()
lines.get_key_list(&line_keys);
List<String>::Element *e = line_keys.front();
lines_list->clear();
if (!re.is_valid())
re.instance();
re->compile(filter_text);
if (filter_text.length() > 0 && !re->is_valid())
return;
int selected_index = -1;
int index = 0;
while (e) {
String key = e->get();
Array matches = re->search_all(key);
if (filter_text.length() > 0 && matches.size() == 0) {
e = e->next();
continue;
}
if (key == current_line)
selected_index = index;
lines_list->add_item(key);
@@ -441,6 +530,8 @@ void RoadLinesEditor::update_ui()
}
if (selected_index >= 0)
lines_list->set_current(selected_index);
else
lines_list->set_current(0);
}
void RoadLinesEditor::create_new_line_at_cursor(const String &line_name)
@@ -460,6 +551,13 @@ void RoadLinesEditor::set_line_index(int index)
editor->emit_signal("editor_event", "line_cursor_motion", pargs);
}
void RoadLinesEditor::line_list_filter_changed(const String &text)
{
print_line("lines filter update: " + text);
filter_text = text.strip_edges();
update_ui();
}
void RoadLinesEditor::activate()
{
assert(!active);

View File

@@ -2,10 +2,13 @@
#define ROAD_LINES_EDITOR_H
#include "world_editor.h"
class ItemList;
class RegEx;
class RoadLinesEditor {
bool active;
WorldEditor *editor;
bool cursor_enabled;
String filter_text;
Ref<RegEx> re;
public:
RoadLinesEditor(WorldEditor *editor);
@@ -15,6 +18,7 @@ public:
void select_line(const String &line_name);
bool line_exists(const String &line_name);
void set_point_to_cursor();
void move_cursor_to_point();
void update(float delta);
void exit();
void editor_command(const String &command, const Array &args);
@@ -23,6 +27,7 @@ public:
void update_ui();
void create_new_line_at_cursor(const String &line_name);
void set_line_index(int index);
void line_list_filter_changed(const String &text);
template <class T> T *get_as_node(const String &path);
protected: