mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-20 17:58:18 +03:00
HackStudio: Move editors inside tab widgets
This will move the editors inside a tab widget and the user will be able to add new editors as tabs as well as add new tab widgets. The user will be able to easily switch between editors as well as the tab widgets.
This commit is contained in:
parent
da714f771d
commit
23643cf21b
Notes:
sideshowbarker
2024-07-17 17:49:11 +09:00
Author: https://github.com/ry-sev Commit: https://github.com/SerenityOS/serenity/commit/23643cf21b Pull-request: https://github.com/SerenityOS/serenity/pull/12938 Reviewed-by: https://github.com/itamar8910 ✅
@ -108,7 +108,6 @@ const EditorWrapper& Editor::wrapper() const
|
|||||||
|
|
||||||
void Editor::focusin_event(GUI::FocusEvent& event)
|
void Editor::focusin_event(GUI::FocusEvent& event)
|
||||||
{
|
{
|
||||||
wrapper().set_editor_has_focus({}, true);
|
|
||||||
if (on_focus)
|
if (on_focus)
|
||||||
on_focus();
|
on_focus();
|
||||||
GUI::TextEditor::focusin_event(event);
|
GUI::TextEditor::focusin_event(event);
|
||||||
@ -116,7 +115,6 @@ void Editor::focusin_event(GUI::FocusEvent& event)
|
|||||||
|
|
||||||
void Editor::focusout_event(GUI::FocusEvent& event)
|
void Editor::focusout_event(GUI::FocusEvent& event)
|
||||||
{
|
{
|
||||||
wrapper().set_editor_has_focus({}, false);
|
|
||||||
GUI::TextEditor::focusout_event(event);
|
GUI::TextEditor::focusout_event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,10 +321,10 @@ void Editor::mousedown_event(GUI::MouseEvent& event)
|
|||||||
if (event.button() == GUI::MouseButton::Primary && event.position().x() < ruler_line_rect.width()) {
|
if (event.button() == GUI::MouseButton::Primary && event.position().x() < ruler_line_rect.width()) {
|
||||||
if (!breakpoint_lines().contains_slow(text_position.line())) {
|
if (!breakpoint_lines().contains_slow(text_position.line())) {
|
||||||
breakpoint_lines().append(text_position.line());
|
breakpoint_lines().append(text_position.line());
|
||||||
Debugger::the().on_breakpoint_change(wrapper().filename_label().text(), text_position.line(), BreakpointChange::Added);
|
Debugger::the().on_breakpoint_change(wrapper().filename_title(), text_position.line(), BreakpointChange::Added);
|
||||||
} else {
|
} else {
|
||||||
breakpoint_lines().remove_first_matching([&](size_t line) { return line == text_position.line(); });
|
breakpoint_lines().remove_first_matching([&](size_t line) { return line == text_position.line(); });
|
||||||
Debugger::the().on_breakpoint_change(wrapper().filename_label().text(), text_position.line(), BreakpointChange::Removed);
|
Debugger::the().on_breakpoint_change(wrapper().filename_title(), text_position.line(), BreakpointChange::Removed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,15 +21,7 @@ EditorWrapper::EditorWrapper()
|
|||||||
{
|
{
|
||||||
set_layout<GUI::VerticalBoxLayout>();
|
set_layout<GUI::VerticalBoxLayout>();
|
||||||
|
|
||||||
auto& label_wrapper = add<GUI::Widget>();
|
m_filename_title = untitled_label;
|
||||||
label_wrapper.set_fixed_height(14);
|
|
||||||
label_wrapper.set_fill_with_background_color(true);
|
|
||||||
label_wrapper.set_layout<GUI::HorizontalBoxLayout>();
|
|
||||||
label_wrapper.layout()->set_margins({ 0, 2 });
|
|
||||||
|
|
||||||
m_filename_label = label_wrapper.add<GUI::Label>(untitled_label);
|
|
||||||
m_filename_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
|
|
||||||
m_filename_label->set_fixed_height(14);
|
|
||||||
|
|
||||||
// FIXME: Propagate errors instead of giving up
|
// FIXME: Propagate errors instead of giving up
|
||||||
m_editor = MUST(try_add<Editor>());
|
m_editor = MUST(try_add<Editor>());
|
||||||
@ -49,12 +41,6 @@ EditorWrapper::EditorWrapper()
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorWrapper::set_editor_has_focus(Badge<Editor>, bool focus)
|
|
||||||
{
|
|
||||||
auto& font = Gfx::FontDatabase::default_font();
|
|
||||||
m_filename_label->set_font(focus ? font.bold_variant() : font);
|
|
||||||
}
|
|
||||||
|
|
||||||
LanguageClient& EditorWrapper::language_client() { return m_editor->language_client(); }
|
LanguageClient& EditorWrapper::language_client() { return m_editor->language_client(); }
|
||||||
|
|
||||||
void EditorWrapper::set_mode_displayable()
|
void EditorWrapper::set_mode_displayable()
|
||||||
@ -121,7 +107,7 @@ void EditorWrapper::update_title()
|
|||||||
|
|
||||||
if (editor().document().is_modified())
|
if (editor().document().is_modified())
|
||||||
title.append(" (*)");
|
title.append(" (*)");
|
||||||
m_filename_label->set_text(title.to_string());
|
m_filename_title = title.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorWrapper::set_debug_mode(bool enabled)
|
void EditorWrapper::set_debug_mode(bool enabled)
|
||||||
|
@ -32,10 +32,6 @@ public:
|
|||||||
|
|
||||||
void save();
|
void save();
|
||||||
|
|
||||||
GUI::Label& filename_label() { return *m_filename_label; }
|
|
||||||
const GUI::Label& filename_label() const { return *m_filename_label; }
|
|
||||||
|
|
||||||
void set_editor_has_focus(Badge<Editor>, bool);
|
|
||||||
LanguageClient& language_client();
|
LanguageClient& language_client();
|
||||||
|
|
||||||
void set_mode_displayable();
|
void set_mode_displayable();
|
||||||
@ -43,6 +39,7 @@ public:
|
|||||||
void set_debug_mode(bool);
|
void set_debug_mode(bool);
|
||||||
void set_filename(const String&);
|
void set_filename(const String&);
|
||||||
const String& filename() const { return m_filename; }
|
const String& filename() const { return m_filename; }
|
||||||
|
String const& filename_title() const { return m_filename_title; }
|
||||||
|
|
||||||
Optional<String> const& project_root() const { return m_project_root; }
|
Optional<String> const& project_root() const { return m_project_root; }
|
||||||
void set_project_root(String const& project_root);
|
void set_project_root(String const& project_root);
|
||||||
@ -53,6 +50,7 @@ public:
|
|||||||
Vector<Diff::Hunk> const& hunks() const { return m_hunks; }
|
Vector<Diff::Hunk> const& hunks() const { return m_hunks; }
|
||||||
|
|
||||||
Function<void()> on_change;
|
Function<void()> on_change;
|
||||||
|
Function<void(EditorWrapper&)> on_tab_close_request;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr auto untitled_label = "(Untitled)";
|
static constexpr auto untitled_label = "(Untitled)";
|
||||||
@ -62,7 +60,7 @@ private:
|
|||||||
void update_title();
|
void update_title();
|
||||||
|
|
||||||
String m_filename;
|
String m_filename;
|
||||||
RefPtr<GUI::Label> m_filename_label;
|
String m_filename_title;
|
||||||
RefPtr<Editor> m_editor;
|
RefPtr<Editor> m_editor;
|
||||||
|
|
||||||
Optional<String> m_project_root;
|
Optional<String> m_project_root;
|
||||||
|
@ -111,11 +111,13 @@ HackStudioWidget::HackStudioWidget(String path_to_project)
|
|||||||
|
|
||||||
m_editors_splitter = m_right_hand_stack->add<GUI::VerticalSplitter>();
|
m_editors_splitter = m_right_hand_stack->add<GUI::VerticalSplitter>();
|
||||||
m_editors_splitter->layout()->set_margins({ 3, 0, 0 });
|
m_editors_splitter->layout()->set_margins({ 3, 0, 0 });
|
||||||
add_new_editor(*m_editors_splitter);
|
add_new_editor_tab_widget(*m_editors_splitter);
|
||||||
|
|
||||||
|
m_switch_to_next_editor_tab_widget = create_switch_to_next_editor_tab_widget_action();
|
||||||
m_switch_to_next_editor = create_switch_to_next_editor_action();
|
m_switch_to_next_editor = create_switch_to_next_editor_action();
|
||||||
m_switch_to_previous_editor = create_switch_to_previous_editor_action();
|
m_switch_to_previous_editor = create_switch_to_previous_editor_action();
|
||||||
|
|
||||||
|
m_remove_current_editor_tab_widget_action = create_remove_current_editor_tab_widget_action();
|
||||||
m_remove_current_editor_action = create_remove_current_editor_action();
|
m_remove_current_editor_action = create_remove_current_editor_action();
|
||||||
m_open_action = create_open_action();
|
m_open_action = create_open_action();
|
||||||
m_save_action = create_save_action();
|
m_save_action = create_save_action();
|
||||||
@ -124,6 +126,7 @@ HackStudioWidget::HackStudioWidget(String path_to_project)
|
|||||||
|
|
||||||
create_action_tab(*m_right_hand_splitter);
|
create_action_tab(*m_right_hand_splitter);
|
||||||
|
|
||||||
|
m_add_editor_tab_widget_action = create_add_editor_tab_widget_action();
|
||||||
m_add_editor_action = create_add_editor_action();
|
m_add_editor_action = create_add_editor_action();
|
||||||
m_add_terminal_action = create_add_terminal_action();
|
m_add_terminal_action = create_add_terminal_action();
|
||||||
m_remove_current_terminal_action = create_remove_current_terminal_action();
|
m_remove_current_terminal_action = create_remove_current_terminal_action();
|
||||||
@ -358,7 +361,7 @@ bool HackStudioWidget::open_file(const String& full_filename, size_t line, size_
|
|||||||
m_project_tree_view->update();
|
m_project_tree_view->update();
|
||||||
|
|
||||||
current_editor_wrapper().set_filename(filename);
|
current_editor_wrapper().set_filename(filename);
|
||||||
|
update_current_editor_title();
|
||||||
current_editor().set_focus(true);
|
current_editor().set_focus(true);
|
||||||
|
|
||||||
current_editor().on_cursor_change = [this] { on_cursor_change(); };
|
current_editor().on_cursor_change = [this] { on_cursor_change(); };
|
||||||
@ -396,6 +399,18 @@ void HackStudioWidget::close_file_in_all_editors(String const& filename)
|
|||||||
m_open_files_view->model()->invalidate();
|
m_open_files_view->model()->invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GUI::TabWidget& HackStudioWidget::current_editor_tab_widget()
|
||||||
|
{
|
||||||
|
VERIFY(m_current_editor_tab_widget);
|
||||||
|
return *m_current_editor_tab_widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
GUI::TabWidget const& HackStudioWidget::current_editor_tab_widget() const
|
||||||
|
{
|
||||||
|
VERIFY(m_current_editor_tab_widget);
|
||||||
|
return *m_current_editor_tab_widget;
|
||||||
|
}
|
||||||
|
|
||||||
EditorWrapper& HackStudioWidget::current_editor_wrapper()
|
EditorWrapper& HackStudioWidget::current_editor_wrapper()
|
||||||
{
|
{
|
||||||
VERIFY(m_current_editor_wrapper);
|
VERIFY(m_current_editor_wrapper);
|
||||||
@ -643,70 +658,137 @@ NonnullRefPtr<GUI::Action> HackStudioWidget::create_new_project_action()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void HackStudioWidget::add_new_editor(GUI::Widget& parent)
|
NonnullRefPtr<GUI::Action> HackStudioWidget::create_remove_current_editor_tab_widget_action()
|
||||||
{
|
{
|
||||||
auto wrapper = EditorWrapper::construct();
|
return GUI::Action::create("Switch to Next Editor Group", { Mod_Alt | Mod_Shift, Key_Backslash }, [this](auto&) {
|
||||||
if (m_action_tab_widget) {
|
if (m_all_editor_tab_widgets.size() <= 1)
|
||||||
parent.insert_child_before(wrapper, *m_action_tab_widget);
|
return;
|
||||||
} else {
|
auto tab_widget = m_current_editor_tab_widget;
|
||||||
parent.add_child(wrapper);
|
while (tab_widget->children().size() > 1) {
|
||||||
|
auto active_wrapper = tab_widget->active_widget();
|
||||||
|
tab_widget->remove_tab(*active_wrapper);
|
||||||
|
m_all_editor_wrappers.remove_first_matching([&active_wrapper](auto& entry) { return entry == active_wrapper; });
|
||||||
}
|
}
|
||||||
|
tab_widget->on_tab_close_click(*tab_widget->active_widget());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void HackStudioWidget::add_new_editor_tab_widget(GUI::Widget& parent)
|
||||||
|
{
|
||||||
|
auto tab_widget = GUI::TabWidget::construct();
|
||||||
|
if (m_action_tab_widget) {
|
||||||
|
parent.insert_child_before(tab_widget, *m_action_tab_widget);
|
||||||
|
} else {
|
||||||
|
parent.add_child(tab_widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_current_editor_tab_widget = tab_widget;
|
||||||
|
m_all_editor_tab_widgets.append(tab_widget);
|
||||||
|
|
||||||
|
tab_widget->set_reorder_allowed(true);
|
||||||
|
|
||||||
|
if (m_all_editor_tab_widgets.size() > 1) {
|
||||||
|
for (auto& widget : m_all_editor_tab_widgets)
|
||||||
|
widget.set_close_button_enabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
tab_widget->on_change = [&](auto& widget) {
|
||||||
|
auto& wrapper = static_cast<EditorWrapper&>(widget);
|
||||||
|
set_current_editor_wrapper(wrapper);
|
||||||
|
current_editor().set_focus(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
tab_widget->on_middle_click = [](auto& widget) {
|
||||||
|
auto& wrapper = static_cast<EditorWrapper&>(widget);
|
||||||
|
wrapper.on_tab_close_request(wrapper);
|
||||||
|
};
|
||||||
|
|
||||||
|
tab_widget->on_tab_close_click = [](auto& widget) {
|
||||||
|
auto& wrapper = static_cast<EditorWrapper&>(widget);
|
||||||
|
wrapper.on_tab_close_request(wrapper);
|
||||||
|
};
|
||||||
|
|
||||||
|
add_new_editor(*m_current_editor_tab_widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HackStudioWidget::add_new_editor(GUI::TabWidget& parent)
|
||||||
|
{
|
||||||
|
auto& wrapper = parent.add_tab<EditorWrapper>("(Untitled)");
|
||||||
|
parent.set_active_widget(&wrapper);
|
||||||
|
if (parent.children().size() > 1 || m_all_editor_tab_widgets.size() > 1)
|
||||||
|
parent.set_close_button_enabled(true);
|
||||||
|
|
||||||
auto previous_editor_wrapper = m_current_editor_wrapper;
|
auto previous_editor_wrapper = m_current_editor_wrapper;
|
||||||
m_current_editor_wrapper = wrapper;
|
m_current_editor_wrapper = wrapper;
|
||||||
m_all_editor_wrappers.append(wrapper);
|
m_all_editor_wrappers.append(wrapper);
|
||||||
wrapper->editor().set_focus(true);
|
wrapper.editor().set_focus(true);
|
||||||
wrapper->editor().set_font(*m_editor_font);
|
wrapper.editor().set_font(*m_editor_font);
|
||||||
wrapper->set_project_root(m_project->root_path());
|
wrapper.set_project_root(m_project->root_path());
|
||||||
wrapper->editor().on_cursor_change = [this] { on_cursor_change(); };
|
wrapper.editor().on_cursor_change = [this] { on_cursor_change(); };
|
||||||
wrapper->on_change = [this] { update_gml_preview(); };
|
wrapper.on_change = [this] { update_gml_preview(); };
|
||||||
set_edit_mode(EditMode::Text);
|
set_edit_mode(EditMode::Text);
|
||||||
if (previous_editor_wrapper && previous_editor_wrapper->editor().editing_engine()->is_regular())
|
if (previous_editor_wrapper && previous_editor_wrapper->editor().editing_engine()->is_regular())
|
||||||
wrapper->editor().set_editing_engine(make<GUI::RegularEditingEngine>());
|
wrapper.editor().set_editing_engine(make<GUI::RegularEditingEngine>());
|
||||||
else if (previous_editor_wrapper && previous_editor_wrapper->editor().editing_engine()->is_vim())
|
else if (previous_editor_wrapper && previous_editor_wrapper->editor().editing_engine()->is_vim())
|
||||||
wrapper->editor().set_editing_engine(make<GUI::VimEditingEngine>());
|
wrapper.editor().set_editing_engine(make<GUI::VimEditingEngine>());
|
||||||
else
|
else
|
||||||
wrapper->editor().set_editing_engine(make<GUI::RegularEditingEngine>());
|
wrapper.editor().set_editing_engine(make<GUI::RegularEditingEngine>());
|
||||||
|
|
||||||
|
wrapper.on_tab_close_request = [this, &parent](auto& tab) {
|
||||||
|
parent.deferred_invoke([this, &parent, &tab] {
|
||||||
|
set_current_editor_wrapper(tab);
|
||||||
|
parent.remove_tab(tab);
|
||||||
|
m_all_editor_wrappers.remove_first_matching([&tab](auto& entry) { return entry == &tab; });
|
||||||
|
if (parent.children().is_empty()) {
|
||||||
|
m_switch_to_next_editor_tab_widget->activate();
|
||||||
|
m_editors_splitter->remove_child(parent);
|
||||||
|
m_all_editor_tab_widgets.remove_first_matching([&parent](auto& entry) { return entry == &parent; });
|
||||||
|
if (m_current_editor_tab_widget->children().size() == 1)
|
||||||
|
m_current_editor_tab_widget->set_close_button_enabled(false);
|
||||||
|
}
|
||||||
|
if (parent.children().size() == 1 && m_all_editor_tab_widgets.size() <= 1)
|
||||||
|
parent.set_close_button_enabled(false);
|
||||||
|
update_actions();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
NonnullRefPtr<GUI::Action> HackStudioWidget::create_switch_to_next_editor_tab_widget_action()
|
||||||
|
{
|
||||||
|
return GUI::Action::create("Switch to Next Editor Group", { Mod_Ctrl | Mod_Shift, Key_T }, [this](auto&) {
|
||||||
|
if (m_all_editor_tab_widgets.size() <= 1)
|
||||||
|
return;
|
||||||
|
Vector<GUI::TabWidget&> tab_widgets;
|
||||||
|
m_editors_splitter->for_each_child_of_type<GUI::TabWidget>([&tab_widgets](auto& child) {
|
||||||
|
tab_widgets.append(child);
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
|
for (size_t i = 0; i < tab_widgets.size(); ++i) {
|
||||||
|
if (m_current_editor_tab_widget.ptr() == &tab_widgets[i]) {
|
||||||
|
if (i == tab_widgets.size() - 1)
|
||||||
|
m_current_editor_tab_widget = tab_widgets[0];
|
||||||
|
else
|
||||||
|
m_current_editor_tab_widget = tab_widgets[i + 1];
|
||||||
|
auto wrapper = static_cast<EditorWrapper*>(m_current_editor_tab_widget->active_widget());
|
||||||
|
set_current_editor_wrapper(wrapper);
|
||||||
|
current_editor().set_focus(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GUI::Action> HackStudioWidget::create_switch_to_next_editor_action()
|
NonnullRefPtr<GUI::Action> HackStudioWidget::create_switch_to_next_editor_action()
|
||||||
{
|
{
|
||||||
return GUI::Action::create("Switch to &Next Editor", { Mod_Ctrl, Key_E }, [this](auto&) {
|
return GUI::Action::create("Switch to &Next Editor", { Mod_Ctrl, Key_E }, [this](auto&) {
|
||||||
if (m_all_editor_wrappers.size() <= 1)
|
m_current_editor_tab_widget->activate_next_tab();
|
||||||
return;
|
|
||||||
Vector<EditorWrapper&> wrappers;
|
|
||||||
m_editors_splitter->for_each_child_of_type<EditorWrapper>([&wrappers](auto& child) {
|
|
||||||
wrappers.append(child);
|
|
||||||
return IterationDecision::Continue;
|
|
||||||
});
|
|
||||||
for (size_t i = 0; i < wrappers.size(); ++i) {
|
|
||||||
if (m_current_editor_wrapper.ptr() == &wrappers[i]) {
|
|
||||||
if (i == wrappers.size() - 1)
|
|
||||||
wrappers[0].editor().set_focus(true);
|
|
||||||
else
|
|
||||||
wrappers[i + 1].editor().set_focus(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GUI::Action> HackStudioWidget::create_switch_to_previous_editor_action()
|
NonnullRefPtr<GUI::Action> HackStudioWidget::create_switch_to_previous_editor_action()
|
||||||
{
|
{
|
||||||
return GUI::Action::create("Switch to &Previous Editor", { Mod_Ctrl | Mod_Shift, Key_E }, [this](auto&) {
|
return GUI::Action::create("Switch to &Previous Editor", { Mod_Ctrl | Mod_Shift, Key_E }, [this](auto&) {
|
||||||
if (m_all_editor_wrappers.size() <= 1)
|
m_current_editor_tab_widget->activate_previous_tab();
|
||||||
return;
|
|
||||||
Vector<EditorWrapper&> wrappers;
|
|
||||||
m_editors_splitter->for_each_child_of_type<EditorWrapper>([&wrappers](auto& child) {
|
|
||||||
wrappers.append(child);
|
|
||||||
return IterationDecision::Continue;
|
|
||||||
});
|
|
||||||
for (int i = wrappers.size() - 1; i >= 0; --i) {
|
|
||||||
if (m_current_editor_wrapper.ptr() == &wrappers[i]) {
|
|
||||||
if (i == 0)
|
|
||||||
wrappers.last().editor().set_focus(true);
|
|
||||||
else
|
|
||||||
wrappers[i - 1].editor().set_focus(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -715,10 +797,10 @@ NonnullRefPtr<GUI::Action> HackStudioWidget::create_remove_current_editor_action
|
|||||||
return GUI::Action::create("&Remove Current Editor", { Mod_Alt | Mod_Shift, Key_E }, Gfx::Bitmap::try_load_from_file("/res/icons/hackstudio/remove-editor.png").release_value_but_fixme_should_propagate_errors(), [this](auto&) {
|
return GUI::Action::create("&Remove Current Editor", { Mod_Alt | Mod_Shift, Key_E }, Gfx::Bitmap::try_load_from_file("/res/icons/hackstudio/remove-editor.png").release_value_but_fixme_should_propagate_errors(), [this](auto&) {
|
||||||
if (m_all_editor_wrappers.size() <= 1)
|
if (m_all_editor_wrappers.size() <= 1)
|
||||||
return;
|
return;
|
||||||
auto wrapper = m_current_editor_wrapper;
|
auto tab_widget = m_current_editor_tab_widget;
|
||||||
m_switch_to_next_editor->activate();
|
auto* active_wrapper = tab_widget->active_widget();
|
||||||
m_editors_splitter->remove_child(*wrapper);
|
VERIFY(active_wrapper);
|
||||||
m_all_editor_wrappers.remove_first_matching([&wrapper](auto& entry) { return entry == wrapper.ptr(); });
|
tab_widget->on_tab_close_click(*active_wrapper);
|
||||||
update_actions();
|
update_actions();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -782,6 +864,7 @@ NonnullRefPtr<GUI::Action> HackStudioWidget::create_save_as_action()
|
|||||||
m_open_files_vector.remove_all_matching([&old_filename](auto const& element) { return element == old_filename; });
|
m_open_files_vector.remove_all_matching([&old_filename](auto const& element) { return element == old_filename; });
|
||||||
|
|
||||||
update_window_title();
|
update_window_title();
|
||||||
|
update_current_editor_title();
|
||||||
|
|
||||||
m_project->model().invalidate();
|
m_project->model().invalidate();
|
||||||
update_tree_view();
|
update_tree_view();
|
||||||
@ -804,12 +887,21 @@ NonnullRefPtr<GUI::Action> HackStudioWidget::create_remove_current_terminal_acti
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NonnullRefPtr<GUI::Action> HackStudioWidget::create_add_editor_tab_widget_action()
|
||||||
|
{
|
||||||
|
return GUI::Action::create("Add New Editor Group", { Mod_Ctrl | Mod_Alt, Key_Backslash },
|
||||||
|
[this](auto&) {
|
||||||
|
add_new_editor_tab_widget(*m_editors_splitter);
|
||||||
|
update_actions();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
NonnullRefPtr<GUI::Action> HackStudioWidget::create_add_editor_action()
|
NonnullRefPtr<GUI::Action> HackStudioWidget::create_add_editor_action()
|
||||||
{
|
{
|
||||||
return GUI::Action::create("Add New &Editor", { Mod_Ctrl | Mod_Alt, Key_E },
|
return GUI::Action::create("Add New &Editor", { Mod_Ctrl | Mod_Alt, Key_E },
|
||||||
Gfx::Bitmap::try_load_from_file("/res/icons/hackstudio/add-editor.png").release_value_but_fixme_should_propagate_errors(),
|
Gfx::Bitmap::try_load_from_file("/res/icons/hackstudio/add-editor.png").release_value_but_fixme_should_propagate_errors(),
|
||||||
[this](auto&) {
|
[this](auto&) {
|
||||||
add_new_editor(*m_editors_splitter);
|
add_new_editor(*m_current_editor_tab_widget);
|
||||||
update_actions();
|
update_actions();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1003,11 +1095,19 @@ Project& HackStudioWidget::project()
|
|||||||
return *m_project;
|
return *m_project;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HackStudioWidget::set_current_editor_tab_widget(RefPtr<GUI::TabWidget> tab_widget)
|
||||||
|
{
|
||||||
|
m_current_editor_tab_widget = tab_widget;
|
||||||
|
}
|
||||||
|
|
||||||
void HackStudioWidget::set_current_editor_wrapper(RefPtr<EditorWrapper> editor_wrapper)
|
void HackStudioWidget::set_current_editor_wrapper(RefPtr<EditorWrapper> editor_wrapper)
|
||||||
{
|
{
|
||||||
m_current_editor_wrapper = editor_wrapper;
|
m_current_editor_wrapper = editor_wrapper;
|
||||||
update_window_title();
|
update_window_title();
|
||||||
|
update_current_editor_title();
|
||||||
update_tree_view();
|
update_tree_view();
|
||||||
|
set_current_editor_tab_widget(static_cast<GUI::TabWidget*>(m_current_editor_wrapper->parent()));
|
||||||
|
update_statusbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HackStudioWidget::file_renamed(String const& old_name, String const& new_name)
|
void HackStudioWidget::file_renamed(String const& old_name, String const& new_name)
|
||||||
@ -1034,6 +1134,9 @@ void HackStudioWidget::file_renamed(String const& old_name, String const& new_na
|
|||||||
VERIFY(!m_file_watcher->remove_watch(old_name).is_error());
|
VERIFY(!m_file_watcher->remove_watch(old_name).is_error());
|
||||||
VERIFY(!m_file_watcher->add_watch(new_name, Core::FileWatcherEvent::Type::Deleted).is_error());
|
VERIFY(!m_file_watcher->add_watch(new_name, Core::FileWatcherEvent::Type::Deleted).is_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_window_title();
|
||||||
|
update_current_editor_title();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HackStudioWidget::configure_project_tree_view()
|
void HackStudioWidget::configure_project_tree_view()
|
||||||
@ -1331,6 +1434,7 @@ void HackStudioWidget::create_view_menu(GUI::Window& window)
|
|||||||
view_menu.add_action(*m_editor_font_action);
|
view_menu.add_action(*m_editor_font_action);
|
||||||
|
|
||||||
view_menu.add_separator();
|
view_menu.add_separator();
|
||||||
|
view_menu.add_action(*m_add_editor_tab_widget_action);
|
||||||
view_menu.add_action(*m_add_editor_action);
|
view_menu.add_action(*m_add_editor_action);
|
||||||
view_menu.add_action(*m_remove_current_editor_action);
|
view_menu.add_action(*m_remove_current_editor_action);
|
||||||
view_menu.add_action(*m_add_terminal_action);
|
view_menu.add_action(*m_add_terminal_action);
|
||||||
@ -1412,7 +1516,7 @@ void HackStudioWidget::close_current_project()
|
|||||||
m_all_editor_wrappers.clear();
|
m_all_editor_wrappers.clear();
|
||||||
m_open_files.clear();
|
m_open_files.clear();
|
||||||
m_open_files_vector.clear();
|
m_open_files_vector.clear();
|
||||||
add_new_editor(*m_editors_splitter);
|
add_new_editor(*m_current_editor_tab_widget);
|
||||||
m_find_in_files_widget->reset();
|
m_find_in_files_widget->reset();
|
||||||
m_todo_entries_widget->clear();
|
m_todo_entries_widget->clear();
|
||||||
m_terminal_wrapper->clear_including_history();
|
m_terminal_wrapper->clear_including_history();
|
||||||
@ -1470,7 +1574,12 @@ void HackStudioWidget::update_tree_view()
|
|||||||
|
|
||||||
void HackStudioWidget::update_window_title()
|
void HackStudioWidget::update_window_title()
|
||||||
{
|
{
|
||||||
window()->set_title(String::formatted("{} - {} - Hack Studio", m_current_editor_wrapper->filename_label().text(), m_project->name()));
|
window()->set_title(String::formatted("{} - {} - Hack Studio", m_current_editor_wrapper->filename_title(), m_project->name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HackStudioWidget::update_current_editor_title()
|
||||||
|
{
|
||||||
|
current_editor_tab_widget().set_tab_title(current_editor_wrapper(), current_editor_wrapper().filename_title());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HackStudioWidget::on_cursor_change()
|
void HackStudioWidget::on_cursor_change()
|
||||||
@ -1614,5 +1723,4 @@ bool HackStudioWidget::semantic_syntax_highlighting_is_enabled() const
|
|||||||
{
|
{
|
||||||
return m_toggle_semantic_highlighting_action->is_checked();
|
return m_toggle_semantic_highlighting_action->is_checked();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,10 @@ public:
|
|||||||
EditorWrapper& current_editor_wrapper();
|
EditorWrapper& current_editor_wrapper();
|
||||||
EditorWrapper const& current_editor_wrapper() const;
|
EditorWrapper const& current_editor_wrapper() const;
|
||||||
void set_current_editor_wrapper(RefPtr<EditorWrapper>);
|
void set_current_editor_wrapper(RefPtr<EditorWrapper>);
|
||||||
|
void set_current_editor_tab_widget(RefPtr<GUI::TabWidget>);
|
||||||
|
|
||||||
|
GUI::TabWidget& current_editor_tab_widget();
|
||||||
|
GUI::TabWidget const& current_editor_tab_widget() const;
|
||||||
|
|
||||||
const String& active_file() const { return m_current_editor_wrapper->filename(); }
|
const String& active_file() const { return m_current_editor_wrapper->filename(); }
|
||||||
void initialize_menubar(GUI::Window&);
|
void initialize_menubar(GUI::Window&);
|
||||||
@ -98,13 +102,16 @@ private:
|
|||||||
NonnullRefPtr<GUI::Action> create_open_selected_action();
|
NonnullRefPtr<GUI::Action> create_open_selected_action();
|
||||||
NonnullRefPtr<GUI::Action> create_delete_action();
|
NonnullRefPtr<GUI::Action> create_delete_action();
|
||||||
NonnullRefPtr<GUI::Action> create_new_project_action();
|
NonnullRefPtr<GUI::Action> create_new_project_action();
|
||||||
|
NonnullRefPtr<GUI::Action> create_switch_to_next_editor_tab_widget_action();
|
||||||
NonnullRefPtr<GUI::Action> create_switch_to_next_editor_action();
|
NonnullRefPtr<GUI::Action> create_switch_to_next_editor_action();
|
||||||
NonnullRefPtr<GUI::Action> create_switch_to_previous_editor_action();
|
NonnullRefPtr<GUI::Action> create_switch_to_previous_editor_action();
|
||||||
|
NonnullRefPtr<GUI::Action> create_remove_current_editor_tab_widget_action();
|
||||||
NonnullRefPtr<GUI::Action> create_remove_current_editor_action();
|
NonnullRefPtr<GUI::Action> create_remove_current_editor_action();
|
||||||
NonnullRefPtr<GUI::Action> create_open_action();
|
NonnullRefPtr<GUI::Action> create_open_action();
|
||||||
NonnullRefPtr<GUI::Action> create_save_action();
|
NonnullRefPtr<GUI::Action> create_save_action();
|
||||||
NonnullRefPtr<GUI::Action> create_save_as_action();
|
NonnullRefPtr<GUI::Action> create_save_as_action();
|
||||||
NonnullRefPtr<GUI::Action> create_show_in_file_manager_action();
|
NonnullRefPtr<GUI::Action> create_show_in_file_manager_action();
|
||||||
|
NonnullRefPtr<GUI::Action> create_add_editor_tab_widget_action();
|
||||||
NonnullRefPtr<GUI::Action> create_add_editor_action();
|
NonnullRefPtr<GUI::Action> create_add_editor_action();
|
||||||
NonnullRefPtr<GUI::Action> create_add_terminal_action();
|
NonnullRefPtr<GUI::Action> create_add_terminal_action();
|
||||||
NonnullRefPtr<GUI::Action> create_remove_current_terminal_action();
|
NonnullRefPtr<GUI::Action> create_remove_current_terminal_action();
|
||||||
@ -115,7 +122,8 @@ private:
|
|||||||
NonnullRefPtr<GUI::Action> create_toggle_syntax_highlighting_mode_action();
|
NonnullRefPtr<GUI::Action> create_toggle_syntax_highlighting_mode_action();
|
||||||
void create_location_history_actions();
|
void create_location_history_actions();
|
||||||
|
|
||||||
void add_new_editor(GUI::Widget& parent);
|
void add_new_editor_tab_widget(GUI::Widget& parent);
|
||||||
|
void add_new_editor(GUI::TabWidget& parent);
|
||||||
RefPtr<EditorWrapper> get_editor_of_file(const String& filename);
|
RefPtr<EditorWrapper> get_editor_of_file(const String& filename);
|
||||||
String get_project_executable_path() const;
|
String get_project_executable_path() const;
|
||||||
|
|
||||||
@ -149,6 +157,7 @@ private:
|
|||||||
void update_gml_preview();
|
void update_gml_preview();
|
||||||
void update_tree_view();
|
void update_tree_view();
|
||||||
void update_window_title();
|
void update_window_title();
|
||||||
|
void update_current_editor_title();
|
||||||
void on_cursor_change();
|
void on_cursor_change();
|
||||||
void file_renamed(String const& old_name, String const& new_name);
|
void file_renamed(String const& old_name, String const& new_name);
|
||||||
|
|
||||||
@ -163,6 +172,8 @@ private:
|
|||||||
|
|
||||||
NonnullRefPtrVector<EditorWrapper> m_all_editor_wrappers;
|
NonnullRefPtrVector<EditorWrapper> m_all_editor_wrappers;
|
||||||
RefPtr<EditorWrapper> m_current_editor_wrapper;
|
RefPtr<EditorWrapper> m_current_editor_wrapper;
|
||||||
|
NonnullRefPtrVector<GUI::TabWidget> m_all_editor_tab_widgets;
|
||||||
|
RefPtr<GUI::TabWidget> m_current_editor_tab_widget;
|
||||||
|
|
||||||
HashMap<String, NonnullRefPtr<ProjectFile>> m_open_files;
|
HashMap<String, NonnullRefPtr<ProjectFile>> m_open_files;
|
||||||
RefPtr<Core::FileWatcher> m_file_watcher;
|
RefPtr<Core::FileWatcher> m_file_watcher;
|
||||||
@ -208,13 +219,16 @@ private:
|
|||||||
RefPtr<GUI::Action> m_delete_action;
|
RefPtr<GUI::Action> m_delete_action;
|
||||||
RefPtr<GUI::Action> m_tree_view_rename_action;
|
RefPtr<GUI::Action> m_tree_view_rename_action;
|
||||||
RefPtr<GUI::Action> m_new_project_action;
|
RefPtr<GUI::Action> m_new_project_action;
|
||||||
|
RefPtr<GUI::Action> m_switch_to_next_editor_tab_widget;
|
||||||
RefPtr<GUI::Action> m_switch_to_next_editor;
|
RefPtr<GUI::Action> m_switch_to_next_editor;
|
||||||
RefPtr<GUI::Action> m_switch_to_previous_editor;
|
RefPtr<GUI::Action> m_switch_to_previous_editor;
|
||||||
|
RefPtr<GUI::Action> m_remove_current_editor_tab_widget_action;
|
||||||
RefPtr<GUI::Action> m_remove_current_editor_action;
|
RefPtr<GUI::Action> m_remove_current_editor_action;
|
||||||
RefPtr<GUI::Action> m_open_action;
|
RefPtr<GUI::Action> m_open_action;
|
||||||
RefPtr<GUI::Action> m_save_action;
|
RefPtr<GUI::Action> m_save_action;
|
||||||
RefPtr<GUI::Action> m_save_as_action;
|
RefPtr<GUI::Action> m_save_as_action;
|
||||||
RefPtr<GUI::Action> m_add_editor_action;
|
RefPtr<GUI::Action> m_add_editor_action;
|
||||||
|
RefPtr<GUI::Action> m_add_editor_tab_widget_action;
|
||||||
RefPtr<GUI::Action> m_add_terminal_action;
|
RefPtr<GUI::Action> m_add_terminal_action;
|
||||||
RefPtr<GUI::Action> m_remove_current_terminal_action;
|
RefPtr<GUI::Action> m_remove_current_terminal_action;
|
||||||
RefPtr<GUI::Action> m_stop_action;
|
RefPtr<GUI::Action> m_stop_action;
|
||||||
|
Loading…
Reference in New Issue
Block a user