Skip to content

Commit

Permalink
GH-651 Move build/validate output to a bottom panel
Browse files Browse the repository at this point in the history
  • Loading branch information
Naros committed Aug 3, 2024
1 parent b92bc43 commit 5eb65d9
Show file tree
Hide file tree
Showing 11 changed files with 294 additions and 56 deletions.
6 changes: 6 additions & 0 deletions src/common/scene_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ namespace SceneUtils
return vbox->get_theme_font(p_font_name, "EditorFonts");
}

int get_editor_font_size(const String& p_font_name)
{
VBoxContainer* vbox = OrchestratorPlugin::get_singleton()->get_editor_interface()->get_editor_main_screen();
return vbox->get_theme_font_size(p_font_name, "EditorFonts");
}

Ref<StyleBox> get_editor_stylebox(const String& p_stylebox_name, const String& p_class_name)
{
VBoxContainer* vbox = OrchestratorPlugin::get_singleton()->get_editor_interface()->get_editor_main_screen();
Expand Down
5 changes: 5 additions & 0 deletions src/common/scene_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ namespace SceneUtils
/// @return the font reference or an invalid reference if the font isn't found
Ref<Font> get_editor_font(const String& p_font_name);

/// Get an editor font size
/// @param p_font_name the font name
/// @return the font size
int get_editor_font_size(const String& p_font_name);

/// Get an editor stylebox
/// @return the stylebox or an invalid reference if it wasn't found
Ref<StyleBox> get_editor_stylebox(const String& p_stylebox_name, const String& p_class_type);
Expand Down
119 changes: 119 additions & 0 deletions src/editor/build_output_panel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// This file is part of the Godot Orchestrator project.
//
// Copyright (c) 2023-present Vahera Studios LLC and its contributors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "editor/build_output_panel.h"

#include "common/callable_lambda.h"
#include "common/scene_utils.h"
#include "common/version.h"
#include "plugins/orchestrator_editor_plugin.h"

#include <godot_cpp/classes/label.hpp>
#include <godot_cpp/classes/v_box_container.hpp>

void OrchestratorBuildOutputPanel::_append_text(const String& p_text)
{
_rtl->append_text(p_text);
}

void OrchestratorBuildOutputPanel::reset()
{
if (_button)
_button->set_button_icon(Ref<Texture2D>());

_rtl->clear();
_rtl->append_text(vformat("%s - (c) 2023-present Vahera Studios, LCC and its contributors.\n\n", VERSION_FULL_NAME));
}

void OrchestratorBuildOutputPanel::add_error(const String& p_text)
{
_append_text(vformat("* [b][color=#a95853]ERROR[/color][/b] : %s\n\n", p_text));
_button->set_button_icon(SceneUtils::get_editor_icon("Error"));
}

void OrchestratorBuildOutputPanel::add_warning(const String& p_text)
{
_append_text(vformat("* [b][color=yellow]WARNING[/color][/b] : %s\n\n", p_text));
_button->set_button_icon(SceneUtils::get_editor_icon("Error"));
}

void OrchestratorBuildOutputPanel::add_message(const String& p_text)
{
_append_text(p_text);
}

void OrchestratorBuildOutputPanel::set_tool_button(Button* p_button)
{
_button = p_button;
}

void OrchestratorBuildOutputPanel::_notification(int p_what)
{
if (p_what == NOTIFICATION_THEME_CHANGED)
{
const Ref<Font> normal_font = SceneUtils::get_editor_font("output_source");
if (normal_font.is_valid())
_rtl->add_theme_font_override("normal_font", normal_font);

const Ref<Font> bold_normal_font = SceneUtils::get_editor_font("output_source_bold");
if (bold_normal_font.is_valid())
_rtl->add_theme_font_override("bold_font", bold_normal_font);

const Ref<Font> mono_font = SceneUtils::get_editor_font("output_source_mono");
if (mono_font.is_valid())
_rtl->add_theme_font_override("mono_font", mono_font);

const int font_size = SceneUtils::get_editor_font_size("output_source_size");
_rtl->begin_bulk_theme_override();
_rtl->add_theme_font_size_override("normal_font_size", font_size);
_rtl->add_theme_font_size_override("bold_font_size", font_size);
_rtl->add_theme_font_size_override("italics_font_size", font_size);
_rtl->add_theme_font_size_override("mono_font_size", font_size);
_rtl->end_bulk_theme_override();
}
else if (p_what == NOTIFICATION_READY)
{
_rtl->connect("meta_clicked", callable_mp_lambda(this, [this](const Variant& p_meta) {
emit_signal("meta_clicked", p_meta);
}));

_clear_button->set_button_icon(SceneUtils::get_editor_icon("Clear"));
_clear_button->connect("pressed", callable_mp_lambda(this, [this] { reset(); }));
}
}

void OrchestratorBuildOutputPanel::_bind_methods()
{
ADD_SIGNAL(MethodInfo("meta_clicked", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
}

OrchestratorBuildOutputPanel::OrchestratorBuildOutputPanel()
{
_rtl = memnew(RichTextLabel);
_rtl->set_h_size_flags(SIZE_EXPAND_FILL);
_rtl->set_v_size_flags(SIZE_EXPAND_FILL);
_rtl->set_use_bbcode(true);
add_child(_rtl);

VBoxContainer* button_container = memnew(VBoxContainer);
_clear_button = memnew(Button);
_clear_button->set_focus_mode(FOCUS_NONE);
_clear_button->set_tooltip_text("Clear Orchestrator's Build Output");
button_container->add_child(_clear_button);
add_child(button_container);

reset();
}
65 changes: 65 additions & 0 deletions src/editor/build_output_panel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// This file is part of the Godot Orchestrator project.
//
// Copyright (c) 2023-present Vahera Studios LLC and its contributors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef ORCHESTRATOR_BUILD_OUTPUT_PANEL_H
#define ORCHESTRATOR_BUILD_OUTPUT_PANEL_H

#include <godot_cpp/classes/button.hpp>
#include <godot_cpp/classes/h_box_container.hpp>
#include <godot_cpp/classes/rich_text_label.hpp>

using namespace godot;

/// An editor bottom panel that outputs the build and validation status details.
class OrchestratorBuildOutputPanel : public HBoxContainer
{
GDCLASS(OrchestratorBuildOutputPanel, HBoxContainer);
static void _bind_methods();

protected:
RichTextLabel* _rtl{ nullptr };
Button* _button{ nullptr };
Button* _clear_button{ nullptr };

//~ Begin Wrapped Interface
void _notification(int p_what);
//~ End Wrapped Interface

void _append_text(const String& p_text);

public:
/// Resets the output panel
void reset();

/// Adds an error to the output log
/// @param p_text the error text to be appended
void add_error(const String& p_text);

/// Adds a warning to the output log
/// @param p_text the warning text to be appended
void add_warning(const String& p_text);

/// Adds a basic message text
/// @param p_text the message text
void add_message(const String& p_text);

/// The activating button
void set_tool_button(Button* p_button);

OrchestratorBuildOutputPanel();
};

#endif // ORCHESTRATOR_BUILD_OUTPUT_PANEL_H
31 changes: 31 additions & 0 deletions src/editor/editor_panel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <godot_cpp/classes/engine.hpp>
#include <godot_cpp/classes/h_box_container.hpp>
#include <godot_cpp/classes/h_split_container.hpp>
#include <godot_cpp/classes/json.hpp>
#include <godot_cpp/classes/label.hpp>
#include <godot_cpp/classes/line_edit.hpp>
#include <godot_cpp/classes/option_button.hpp>
Expand Down Expand Up @@ -704,6 +705,29 @@ void OrchestratorEditorPanel::_focus_viewport(OrchestratorEditorViewport* p_view
}
}

void OrchestratorEditorPanel::_build_log_meta_clicked(const Variant& p_meta)
{
const Dictionary value = JSON::parse_string(String(p_meta));
if (value.has("script"))
{
for (const OrchestrationFile& file : _files_context.open_files)
{
if (file.file_name == value["script"])
{
if (value.has("goto_node"))
file.viewport->goto_node(value["goto_node"]);
return;
}
}

if (value.has("goto_node"))
{
_open_script_file(value["script"]);
_files_context.get_selected()->viewport->goto_node(value["goto_node"]);
}
}
}

#if GODOT_VERSION >= 0x040300
void OrchestratorEditorPanel::_goto_script_line(const Ref<Script>& p_script, int p_line)
{
Expand Down Expand Up @@ -795,6 +819,9 @@ void OrchestratorEditorPanel::edit_script(const Ref<OScript>& p_script)
{
ERR_FAIL_COND_MSG(p_script->get_path().is_empty(), "Script has no path, cannot be opened.");

// When editing an Orchestration; make panel active
OrchestratorPlugin::get_singleton()->make_active();

// Before opening a new file, all existing file viewports should be hidden.
// Unlike the Script tab, we do not use tabs but rather control which editor is visible.
_files_context.hide_all();
Expand Down Expand Up @@ -1106,6 +1133,10 @@ void OrchestratorEditorPanel::_notification(int p_what)
_script_create_dialog->connect("script_created", callable_mp(this, &OrchestratorEditorPanel::_script_file_created));
add_child(_script_create_dialog);

OrchestratorPlugin::get_singleton()->get_build_panel()->connect(
"meta_clicked",
callable_mp(this, &OrchestratorEditorPanel::_build_log_meta_clicked));

break;
}
case NOTIFICATION_ENTER_TREE:
Expand Down
1 change: 1 addition & 0 deletions src/editor/editor_panel.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ class OrchestratorEditorPanel : public PanelContainer
void _folder_removed(const String& p_folder_name);
void _add_script_function(Object* p_object, const String& p_function_name, const PackedStringArray& p_args);
void _focus_viewport(OrchestratorEditorViewport* p_viewport);
void _build_log_meta_clicked(const Variant& p_meta);

#if GODOT_VERSION >= 0x040300
void _goto_script_line(const Ref<Script>& p_script, int p_line);
Expand Down
Loading

0 comments on commit 5eb65d9

Please sign in to comment.