diff --git a/AK/Tests/TestJSON.cpp b/AK/Tests/TestJSON.cpp index 30cef3fd3e8..bbdfd258177 100644 --- a/AK/Tests/TestJSON.cpp +++ b/AK/Tests/TestJSON.cpp @@ -9,7 +9,7 @@ TEST_CASE(load_form) { - FILE* fp = fopen("../../Base/home/anon/test.frm", "r"); + FILE* fp = fopen("../../Base/home/anon/little/test.frm", "r"); ASSERT(fp); StringBuilder builder; diff --git a/Base/home/anon/little/little.files b/Base/home/anon/little/little.files index c4647b0dc77..46648a0e185 100644 --- a/Base/home/anon/little/little.files +++ b/Base/home/anon/little/little.files @@ -1,3 +1,4 @@ main.cpp Makefile little.files +test.frm diff --git a/Base/home/anon/test.frm b/Base/home/anon/little/test.frm similarity index 100% rename from Base/home/anon/test.frm rename to Base/home/anon/little/test.frm diff --git a/DevTools/HackStudio/FormEditorWidget.cpp b/DevTools/HackStudio/FormEditorWidget.cpp new file mode 100644 index 00000000000..14c82943380 --- /dev/null +++ b/DevTools/HackStudio/FormEditorWidget.cpp @@ -0,0 +1,28 @@ +#include "FormEditorWidget.h" +#include "FormWidget.h" +#include + +FormEditorWidget::FormEditorWidget(GWidget* parent) + : GScrollableWidget(parent) +{ + set_fill_with_background_color(true); + set_background_color(Color::White); + + set_frame_shape(FrameShape::Container); + set_frame_shadow(FrameShadow::Sunken); + set_frame_thickness(2); + + m_form_widget = FormWidget::construct(*this); +} + +FormEditorWidget::~FormEditorWidget() +{ +} + +void FormEditorWidget::paint_event(GPaintEvent& event) +{ + GFrame::paint_event(event); + + GPainter painter(*this); + painter.add_clip_rect(event.rect()); +} diff --git a/DevTools/HackStudio/FormEditorWidget.h b/DevTools/HackStudio/FormEditorWidget.h new file mode 100644 index 00000000000..ef53044f8f4 --- /dev/null +++ b/DevTools/HackStudio/FormEditorWidget.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +class FormWidget; + +class FormEditorWidget final : public GScrollableWidget { + C_OBJECT(FormEditorWidget) +public: + virtual ~FormEditorWidget() override; + +private: + virtual void paint_event(GPaintEvent&) override; + + explicit FormEditorWidget(GWidget* parent); + + RefPtr m_form_widget; +}; diff --git a/DevTools/HackStudio/FormWidget.cpp b/DevTools/HackStudio/FormWidget.cpp new file mode 100644 index 00000000000..03d8555ad3c --- /dev/null +++ b/DevTools/HackStudio/FormWidget.cpp @@ -0,0 +1,27 @@ +#include "FormWidget.h" +#include "FormEditorWidget.h" +#include + +FormWidget::FormWidget(FormEditorWidget& parent) + : GWidget(&parent) +{ + set_fill_with_background_color(true); + set_background_color(Color::WarmGray); + set_relative_rect(20, 20, 400, 300); +} + +FormWidget::~FormWidget() +{ +} + +void FormWidget::paint_event(GPaintEvent& event) +{ + GPainter painter(*this); + painter.add_clip_rect(event.rect()); + + for (int y = 0; y < height(); y += m_grid_size) { + for (int x = 0; x < width(); x += m_grid_size) { + painter.set_pixel({ x, y }, Color::from_rgb(0x404040)); + } + } +} diff --git a/DevTools/HackStudio/FormWidget.h b/DevTools/HackStudio/FormWidget.h new file mode 100644 index 00000000000..c309b7e6a11 --- /dev/null +++ b/DevTools/HackStudio/FormWidget.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +class FormEditorWidget; + +class FormWidget final : public GWidget { + C_OBJECT(FormWidget) +public: + virtual ~FormWidget() override; + + FormEditorWidget& editor(); + const FormEditorWidget& editor() const; + +private: + virtual void paint_event(GPaintEvent&) override; + + explicit FormWidget(FormEditorWidget& parent); + + // FIXME: This should be an app-wide preference instead. + int m_grid_size { 5 }; +}; diff --git a/DevTools/HackStudio/Makefile b/DevTools/HackStudio/Makefile index e37a4dd47b5..964f5dd86c3 100644 --- a/DevTools/HackStudio/Makefile +++ b/DevTools/HackStudio/Makefile @@ -6,6 +6,8 @@ OBJS = \ TerminalWrapper.o \ FindInFilesWidget.o \ ProcessStateWidget.o \ + FormEditorWidget.o \ + FormWidget.o \ CppLexer.o \ Editor.o \ EditorWrapper.o \ diff --git a/DevTools/HackStudio/main.cpp b/DevTools/HackStudio/main.cpp index f5521ef867e..d4e508f399c 100644 --- a/DevTools/HackStudio/main.cpp +++ b/DevTools/HackStudio/main.cpp @@ -2,6 +2,7 @@ #include "Editor.h" #include "EditorWrapper.h" #include "FindInFilesWidget.h" +#include "FormEditorWidget.h" #include "Locator.h" #include "Project.h" #include "TerminalWrapper.h" @@ -19,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +37,9 @@ String g_currently_open_file; OwnPtr g_project; RefPtr g_window; RefPtr g_project_list_view; +RefPtr g_right_hand_stack; +RefPtr g_inner_splitter; +RefPtr g_form_editor_widget; static RefPtr s_action_tab_widget; @@ -51,6 +56,20 @@ void add_new_editor(GWidget& parent) wrapper->editor().set_focus(true); } +enum class EditMode { + Text, + Form, +}; + +void set_edit_mode(EditMode mode) +{ + if (mode == EditMode::Text) { + g_right_hand_stack->set_active_widget(g_inner_splitter); + } else if (mode == EditMode::Form) { + g_right_hand_stack->set_active_widget(g_form_editor_widget); + } +} + EditorWrapper& current_editor_wrapper() { ASSERT(g_current_editor_wrapper); @@ -98,9 +117,13 @@ int main(int argc, char** argv) g_project_list_view->set_size_policy(SizePolicy::Fixed, SizePolicy::Fill); g_project_list_view->set_preferred_size(140, 0); - auto inner_splitter = GSplitter::construct(Orientation::Vertical, outer_splitter); - inner_splitter->layout()->set_margins({ 0, 3, 0, 0 }); - add_new_editor(inner_splitter); + g_right_hand_stack = GStackWidget::construct(outer_splitter); + + g_form_editor_widget = FormEditorWidget::construct(g_right_hand_stack); + + g_inner_splitter = GSplitter::construct(Orientation::Vertical, g_right_hand_stack); + g_inner_splitter->layout()->set_margins({ 0, 3, 0, 0 }); + add_new_editor(*g_inner_splitter); auto new_action = GAction::create("Add new file to project...", { Mod_Ctrl, Key_N }, GraphicsBitmap::load_from_file("/res/icons/16x16/new.png"), [&](const GAction&) { auto input_box = GInputBox::construct("Enter name of new file:", "Add new file to project", g_window); @@ -136,7 +159,7 @@ int main(int argc, char** argv) if (g_all_editor_wrappers.size() <= 1) return; Vector wrappers; - inner_splitter->for_each_child_of_type([&](auto& child) { + g_inner_splitter->for_each_child_of_type([&](auto& child) { wrappers.append(&child); return IterationDecision::Continue; }); @@ -154,7 +177,7 @@ int main(int argc, char** argv) if (g_all_editor_wrappers.size() <= 1) return; Vector wrappers; - inner_splitter->for_each_child_of_type([&](auto& child) { + g_inner_splitter->for_each_child_of_type([&](auto& child) { wrappers.append(&child); return IterationDecision::Continue; }); @@ -173,7 +196,7 @@ int main(int argc, char** argv) return; auto wrapper = g_current_editor_wrapper; switch_to_next_editor->activate(); - inner_splitter->remove_child(*wrapper); + g_inner_splitter->remove_child(*wrapper); g_all_editor_wrappers.remove_first_matching([&](auto& entry) { return entry == wrapper.ptr(); }); update_actions(); }); @@ -202,7 +225,7 @@ int main(int argc, char** argv) open_file(filename); }; - s_action_tab_widget = GTabWidget::construct(inner_splitter); + s_action_tab_widget = GTabWidget::construct(g_inner_splitter); s_action_tab_widget->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed); s_action_tab_widget->set_preferred_size(0, 24); @@ -222,7 +245,7 @@ int main(int argc, char** argv) }); auto add_editor_action = GAction::create("Add new editor", { Mod_Ctrl | Mod_Alt, Key_E }, [&](auto&) { - add_new_editor(inner_splitter); + add_new_editor(*g_inner_splitter); update_actions(); }); @@ -379,6 +402,12 @@ void open_file(const String& filename) current_editor().on_change = nullptr; } + if (filename.ends_with(".frm")) { + set_edit_mode(EditMode::Form); + } else { + set_edit_mode(EditMode::Text); + } + g_currently_open_file = filename; g_window->set_title(String::format("%s - HackStudio", g_currently_open_file.characters())); g_project_list_view->update();