From 5a5fbc8e4d739fe9eb1da7288125d0d7817bf371 Mon Sep 17 00:00:00 2001 From: Relintai Date: Sat, 20 Aug 2022 21:50:44 +0200 Subject: [PATCH] Implemented the initial version of the WebEditor. It's currently a simple preview gui. --- modules/web/SCsub | 2 + modules/web/editor/web_editor.cpp | 181 ++++++++++++++++++ modules/web/editor/web_editor.h | 22 ++- modules/web/editor/web_editor_plugin.cpp | 2 +- modules/web/editor/web_editor_web_server.cpp | 27 +++ modules/web/editor/web_editor_web_server.h | 26 +++ .../editor/web_editor_web_server_request.cpp | 84 ++++++++ .../editor/web_editor_web_server_request.h | 63 ++++++ 8 files changed, 404 insertions(+), 3 deletions(-) create mode 100644 modules/web/editor/web_editor_web_server.cpp create mode 100644 modules/web/editor/web_editor_web_server.h create mode 100644 modules/web/editor/web_editor_web_server_request.cpp create mode 100644 modules/web/editor/web_editor_web_server_request.h diff --git a/modules/web/SCsub b/modules/web/SCsub index 315328c54..b7bf516d3 100644 --- a/modules/web/SCsub +++ b/modules/web/SCsub @@ -60,6 +60,8 @@ sources = [ if env["tools"]: sources.append("editor/web_editor.cpp") sources.append("editor/web_editor_plugin.cpp") + sources.append("editor/web_editor_web_server.cpp") + sources.append("editor/web_editor_web_server_request.cpp") if ARGUMENTS.get('custom_modules_shared', 'no') == 'yes': # Shared lib compilation diff --git a/modules/web/editor/web_editor.cpp b/modules/web/editor/web_editor.cpp index 4b925f165..7cf0ce742 100644 --- a/modules/web/editor/web_editor.cpp +++ b/modules/web/editor/web_editor.cpp @@ -22,12 +22,147 @@ SOFTWARE. #include "web_editor.h" +#include "../http/web_node.h" +#include "../http/web_server_cookie.h" +#include "scene/gui/rich_text_label.h" +#include "scene/gui/text_edit.h" + +#include "../html/html_parser.h" +#include "web_editor_web_server.h" +#include "web_editor_web_server_request.h" + +void WebEditor::edit(WebNode *web_node) { + _edited_node = web_node; + + refresh(); +} + +void WebEditor::refresh() { + if (_edited_node && !ObjectDB::instance_validate(_edited_node)) { + _edited_node = nullptr; + } + + clear(); + + if (_edited_node == nullptr) { + //Add "Select a node" text + return; + } + + Ref request; + request.instance(); + + _web_server->web_editor_request(_edited_node, request); + + String request_info; + + request_info += "Response type: "; + switch (request->_response_type) { + case WebEditorWebServerRequest::RESPONSE_TYPE_NONE: { + request_info += "NONE"; + } break; + case WebEditorWebServerRequest::RESPONSE_TYPE_NORMAL: { + request_info += "NORMAL"; + } break; + case WebEditorWebServerRequest::RESPONSE_TYPE_FILE: { + request_info += "FILE"; + } break; + case WebEditorWebServerRequest::RESPONSE_TYPE_REDIRECT: { + request_info += "REDIRECT"; + } break; + default: { + request_info += "ERROR"; + } break; + } + request_info += ". "; + + request_info += "Status code: "; + request_info += itos(static_cast(request->get_status_code())); + request_info += ". "; + + request_info += "Error handler was called: "; + if (request->_error_handler_called) { + request_info += "YES"; + } else { + request_info += "NO"; + } + request_info += "."; + + _result_info_label->set_bbcode(request_info); + + String body; + + int cookie_count = request->response_get_cookie_count(); + + if (cookie_count > 0) { + body += "====================\n"; + + body += "Cookies set:\n"; + + for (int i = 0; i < cookie_count; ++i) { + Ref cookie = request->response_get_cookie(i); + + ERR_CONTINUE(!cookie.is_valid()); + + String cookie_str = cookie->get_response_header_string(); + + if (cookie_str != "") { + body += cookie_str; + } + } + + body += "====================\n\n"; + } + + switch (request->_response_type) { + case WebEditorWebServerRequest::RESPONSE_TYPE_NONE: { + body += request->_sent_message; + } break; + case WebEditorWebServerRequest::RESPONSE_TYPE_NORMAL: { + if (_prettify_html) { + HTMLParser p; + p.parse(request->_sent_message); + body += p.convert_to_string(); + } else { + body += request->_sent_message; + } + } break; + case WebEditorWebServerRequest::RESPONSE_TYPE_FILE: { + body += "Sent file:\n"; + body += request->_sent_message; + } break; + case WebEditorWebServerRequest::RESPONSE_TYPE_REDIRECT: { + if (_prettify_html) { + HTMLParser p; + p.parse(request->_sent_message); + body += p.convert_to_string(); + } else { + body += request->_sent_message; + } + } break; + default: { + body += request->_sent_message; + } break; + } + + _results_label->set_text(body); +} + +void WebEditor::clear() { + _result_info_label->clear(); + _results_label->clear(); +} void WebEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { } break; case NOTIFICATION_VISIBILITY_CHANGED: { + if (!is_visible_in_tree()) { + return; + } + + refresh(); } break; case NOTIFICATION_POSTINITIALIZE: { } break; @@ -37,6 +172,52 @@ void WebEditor::_notification(int p_what) { } WebEditor::WebEditor() { + _prettify_html = false; + + _web_server = memnew(WebEditorWebServer); + add_child(_web_server); + + set_h_size_flags(SIZE_EXPAND_FILL); + set_v_size_flags(SIZE_EXPAND_FILL); + set_anchors_and_margins_preset(Control::PRESET_WIDE); + + _toolbar = memnew(HBoxContainer); + _toolbar->set_h_size_flags(SIZE_EXPAND_FILL); + //TODO + add_child(_toolbar); + + _result_info_label = memnew(RichTextLabel); + _result_info_label->set_h_size_flags(SIZE_EXPAND_FILL); + _result_info_label->set_fit_content_height(true); + _result_info_label->set_scroll_active(false); + _result_info_label->set_selection_enabled(true); + _result_info_label->set_use_bbcode(true); + add_child(_result_info_label); + + _results_label = memnew(TextEdit); + _results_label->set_h_size_flags(SIZE_EXPAND_FILL); + _results_label->set_v_size_flags(SIZE_EXPAND_FILL); + _results_label->set_readonly(true); + _results_label->set_highlight_current_line(true); + _results_label->set_syntax_coloring(true); + _results_label->set_show_line_length_guidelines(true); + _results_label->set_draw_fold_gutter(true); + _results_label->set_highlight_all_occurrences(true); + _results_label->set_draw_minimap(true); + _results_label->set_right_click_moves_caret(false); + + add_child(_results_label); + + //todo add all + _results_label->add_color_region("", "", Color::color8(153, 153, 255, 255), false); + _results_label->add_color_region("", "", Color::color8(153, 255, 153, 255), false); + _results_label->add_color_region("", "", Color::color8(255, 153, 153, 255), false); + _results_label->add_color_region("", "", Color::color8(255, 255, 102, 255), false); + _results_label->add_color_region("", Color::color8(153, 204, 255, 255), false); + _results_label->add_color_region("", Color::color8(255, 204, 153, 255), true); + _results_label->add_color_region("
", "
", Color::color8(192, 192, 192, 255), false); + _results_label->add_color_region("
", "
", Color::color8(175, 238, 238, 255), false); + _results_label->add_color_region("", "", Color::color8(135, 206, 235, 255), false); } WebEditor::~WebEditor() { diff --git a/modules/web/editor/web_editor.h b/modules/web/editor/web_editor.h index 15504765d..b08353697 100644 --- a/modules/web/editor/web_editor.h +++ b/modules/web/editor/web_editor.h @@ -27,16 +27,34 @@ SOFTWARE. #include "scene/gui/box_container.h" -class WebEditor : public HBoxContainer { - GDCLASS(WebEditor, HBoxContainer); +class WebNode; +class WebEditorWebServer; +class RichTextLabel; +class TextEdit; + +class WebEditor : public VBoxContainer { + GDCLASS(WebEditor, VBoxContainer); public: + void edit(WebNode *web_node); + void refresh(); + void clear(); + WebEditor(); ~WebEditor(); protected: void _notification(int p_what); static void _bind_methods(); + + bool _prettify_html; + + WebNode *_edited_node; + WebEditorWebServer *_web_server; + HBoxContainer *_toolbar; + + RichTextLabel *_result_info_label; + TextEdit *_results_label; }; #endif diff --git a/modules/web/editor/web_editor_plugin.cpp b/modules/web/editor/web_editor_plugin.cpp index 03490a870..f3f19c275 100644 --- a/modules/web/editor/web_editor_plugin.cpp +++ b/modules/web/editor/web_editor_plugin.cpp @@ -54,7 +54,7 @@ void WebEditorPlugin::edit(Object *p_object) { WebNode *wn = Object::cast_to(p_object); if (wn) { - // window->set_node(wn); + window->edit(wn); get_editor_interface()->set_main_screen_editor("Web"); } diff --git a/modules/web/editor/web_editor_web_server.cpp b/modules/web/editor/web_editor_web_server.cpp new file mode 100644 index 000000000..344526384 --- /dev/null +++ b/modules/web/editor/web_editor_web_server.cpp @@ -0,0 +1,27 @@ +#include "web_editor_web_server.h" + +#include "../http/web_node.h" +#include "web_editor_web_server_request.h" + + +void WebEditorWebServer::web_editor_request(WebNode *node, Ref request) { + _web_root = node; + _last_request = request; + + //server_handle_request(request); + + request->_set_server(this); + request->_set_web_root(_web_root); + + node->handle_request(request); +} + +WebEditorWebServer::WebEditorWebServer() { + _is_running = true; +} + +WebEditorWebServer::~WebEditorWebServer() { +} + +void WebEditorWebServer::_bind_methods() { +} diff --git a/modules/web/editor/web_editor_web_server.h b/modules/web/editor/web_editor_web_server.h new file mode 100644 index 000000000..7c9e395f0 --- /dev/null +++ b/modules/web/editor/web_editor_web_server.h @@ -0,0 +1,26 @@ +#ifndef WEB_EDITOR_WEB_SERVER_H +#define WEB_EDITOR_WEB_SERVER_H + +#include "core/object/reference.h" + +#include "../http/web_server.h" + +class WebNode; +class WebEditorWebServerRequest; + +class WebEditorWebServer : public WebServer { + GDCLASS(WebEditorWebServer, WebServer); + +public: + void web_editor_request(WebNode *node, Ref request); + + WebEditorWebServer(); + ~WebEditorWebServer(); + + Ref _last_request; + +protected: + static void _bind_methods(); +}; + +#endif diff --git a/modules/web/editor/web_editor_web_server_request.cpp b/modules/web/editor/web_editor_web_server_request.cpp new file mode 100644 index 000000000..6d57b0efe --- /dev/null +++ b/modules/web/editor/web_editor_web_server_request.cpp @@ -0,0 +1,84 @@ +#include "web_editor_web_server_request.h" + +#include "core/object/object.h" +#include "core/variant/variant.h" + +#include "../http/web_server.h" +#include "../http/web_node.h" + +String WebEditorWebServerRequest::get_cookie(const String &key) { + return ""; +} + +HTTPServerEnums::HTTPMethod WebEditorWebServerRequest::get_method() const { + return HTTPServerEnums::HTTP_METHOD_GET; +} + +void WebEditorWebServerRequest::parse_files() { +} +int WebEditorWebServerRequest::get_file_count() const { + return 0; +} +String WebEditorWebServerRequest::get_file_file_name(const int index) const { + return ""; +} +String WebEditorWebServerRequest::get_file_key(const int index) const { + return ""; +} +int WebEditorWebServerRequest::get_file_length(const int index) const { + return 0; +} +PoolByteArray WebEditorWebServerRequest::get_file_data(const int index) const { + return PoolByteArray(); +} +String WebEditorWebServerRequest::get_file_data_str(const int index) const { + return ""; +} + +String WebEditorWebServerRequest::get_parameter(const String &key) const { + return ""; +} + +void WebEditorWebServerRequest::send_redirect(const String &location, const HTTPServerEnums::HTTPStatusCode status_code) { + _response_type = RESPONSE_TYPE_REDIRECT; + _status_code = status_code; + _sent_message = location; +} + +void WebEditorWebServerRequest::send() { + _response_type = RESPONSE_TYPE_NORMAL; + _sent_message = get_compiled_body(); +} + +void WebEditorWebServerRequest::send_file(const String &p_file_path) { + _response_type = RESPONSE_TYPE_FILE; + _sent_message = p_file_path; +} + +void WebEditorWebServerRequest::send_error(int error_code) { + _error_handler_called = true; + + _server->get_web_root()->handle_error_send_request(this, error_code); +} + +String WebEditorWebServerRequest::parser_get_path() { + return ""; +} + +String WebEditorWebServerRequest::get_host() const { + return ""; +} + +void WebEditorWebServerRequest::update() { +} + +WebEditorWebServerRequest::WebEditorWebServerRequest() { + _response_type = RESPONSE_TYPE_NONE; + _error_handler_called = false; +} + +WebEditorWebServerRequest::~WebEditorWebServerRequest() { +} + +void WebEditorWebServerRequest::_bind_methods() { +} diff --git a/modules/web/editor/web_editor_web_server_request.h b/modules/web/editor/web_editor_web_server_request.h new file mode 100644 index 000000000..e385372a3 --- /dev/null +++ b/modules/web/editor/web_editor_web_server_request.h @@ -0,0 +1,63 @@ +#ifndef WEB_EDITOR_WEB_SERVER_REQUEST_H +#define WEB_EDITOR_WEB_SERVER_REQUEST_H + +#include "core/containers/vector.h" +#include "core/string/ustring.h" +#include "core/variant/dictionary.h" + +#include "../http/web_server_request.h" + +#include "../http/http_server_enums.h" + +class WebServer; +class WebServerCookie; +class HTTPSession; +class WebPermission; +class WebNode; + +class WebEditorWebServerRequest : public WebServerRequest { + GDCLASS(WebEditorWebServerRequest, WebServerRequest); + +public: + enum ResponseType { + RESPONSE_TYPE_NONE = 0, + RESPONSE_TYPE_NORMAL, + RESPONSE_TYPE_FILE, + RESPONSE_TYPE_REDIRECT, + }; + + String get_cookie(const String &key); + + HTTPServerEnums::HTTPMethod get_method() const; + + void parse_files(); + int get_file_count() const; + String get_file_file_name(const int index) const; + String get_file_key(const int index) const; + int get_file_length(const int index) const; + PoolByteArray get_file_data(const int index) const; + String get_file_data_str(const int index) const; + + String get_parameter(const String &key) const; + + void send_redirect(const String &location, const HTTPServerEnums::HTTPStatusCode status_code = HTTPServerEnums::HTTP_STATUS_CODE_302_FOUND); + void send(); + void send_file(const String &p_file_path); + void send_error(int error_code); + String parser_get_path(); + String get_host() const; + + void update(); + + WebEditorWebServerRequest(); + ~WebEditorWebServerRequest(); + + ResponseType _response_type; + String _sent_message; + bool _error_handler_called; + +protected: + static void _bind_methods(); +}; + +#endif