diff options
author | Erik Biederstadt <biederstadterik@gmail.com> | 2021-05-25 16:01:32 -0600 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-05-27 08:57:13 +0100 |
commit | 3ea256b1c60b7b9cb951a86f85efc6bd07400811 (patch) | |
tree | 78150912fd075c371ce7a77ebbaee3eacab28669 /Userland/Applications | |
parent | 1ce32ef675aa576e4d99c9408539c32c5bbc40d5 (diff) | |
download | serenity-3ea256b1c60b7b9cb951a86f85efc6bd07400811.zip |
3DFileViewer: Add view menu
The view menu contains:
1. A fullscreen option (also accessed by pressing F11).
2. Rotation axis controls (x, y, z, or any combination)
3. Rotation speed controls (No rotation, slow, normal, or fast)
Diffstat (limited to 'Userland/Applications')
-rw-r--r-- | Userland/Applications/3DFileViewer/main.cpp | 78 |
1 files changed, 67 insertions, 11 deletions
diff --git a/Userland/Applications/3DFileViewer/main.cpp b/Userland/Applications/3DFileViewer/main.cpp index cc8573d703..a224ccc6a0 100644 --- a/Userland/Applications/3DFileViewer/main.cpp +++ b/Userland/Applications/3DFileViewer/main.cpp @@ -8,6 +8,7 @@ #include <LibCore/File.h> #include <LibGL/GL/gl.h> #include <LibGL/GLContext.h> +#include <LibGUI/ActionGroup.h> #include <LibGUI/Application.h> #include <LibGUI/FilePicker.h> #include <LibGUI/Icon.h> @@ -32,6 +33,10 @@ class GLContextWidget final : public GUI::Frame { public: bool load(const String& fname); + void toggle_rotate_x() { m_rotate_x = !m_rotate_x; } + void toggle_rotate_y() { m_rotate_y = !m_rotate_y; } + void toggle_rotate_z() { m_rotate_z = !m_rotate_z; } + void set_rotation_speed(float speed) { m_rotation_speed = speed; } private: GLContextWidget() @@ -71,6 +76,10 @@ private: OwnPtr<GL::GLContext> m_context; NonnullOwnPtr<WavefrontOBJLoader> m_mesh_loader; GLuint m_init_list { 0 }; + bool m_rotate_x = true; + bool m_rotate_y = false; + bool m_rotate_z = true; + float m_rotation_speed = 1.f; }; void GLContextWidget::paint_event(GUI::PaintEvent& event) @@ -88,17 +97,12 @@ void GLContextWidget::timer_event(Core::TimerEvent&) glCallList(m_init_list); angle -= 0.01f; - auto matrix = Gfx::translation_matrix(FloatVector3(0, 0, -8.5)) - * Gfx::rotation_matrix(FloatVector3(1, 0, 0), angle) - * Gfx::rotation_matrix(FloatVector3(0, 1, 0), 0.0f) - * Gfx::rotation_matrix(FloatVector3(0, 0, 1), angle); - - // We need to transpose here because OpenGL expects matrices in column major order - // but our matrix class stores elements in row major order. - matrix = matrix.transpose(); - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf((float*)matrix.elements()); + glLoadIdentity(); + glTranslatef(0, 0, -8.5); + glRotatef(m_rotate_x ? angle * m_rotation_speed : 0.f, 1, 0, 0); + glRotatef(m_rotate_y ? angle * m_rotation_speed : 0.f, 0, 1, 0); + glRotatef(m_rotate_z ? angle * m_rotation_speed : 0.f, 0, 0, 1); if (!m_mesh.is_null()) m_mesh->draw(); @@ -198,10 +202,62 @@ int main(int argc, char** argv) load_model(open_path.value()); })); - file_menu.add_action(GUI::CommonActions::make_quit_action([&](auto&) { + file_menu.add_action(GUI::CommonActions::make_quit_action([&] { app->quit(); })); + auto& view_menu = menubar->add_menu("&View"); + view_menu.add_action(GUI::CommonActions::make_fullscreen_action([&] { + window->set_fullscreen(!window->is_fullscreen()); + })); + + auto& rotation_axis_menu = view_menu.add_submenu("Rotation &Axis"); + auto rotation_x_action = GUI::Action::create_checkable("&X", [&widget] { + widget.toggle_rotate_x(); + }); + auto rotation_y_action = GUI::Action::create_checkable("&Y", [&widget] { + widget.toggle_rotate_y(); + }); + auto rotation_z_action = GUI::Action::create_checkable("&Z", [&widget] { + widget.toggle_rotate_z(); + }); + + rotation_axis_menu.add_action(*rotation_x_action); + rotation_axis_menu.add_action(*rotation_y_action); + rotation_axis_menu.add_action(*rotation_z_action); + + rotation_x_action->set_checked(true); + rotation_z_action->set_checked(true); + + auto& rotation_speed_menu = view_menu.add_submenu("Rotation &Speed"); + GUI::ActionGroup rotation_speed_actions; + rotation_speed_actions.set_exclusive(true); + + auto no_rotation_action = GUI::Action::create_checkable("N&o Rotation", [&widget] { + widget.set_rotation_speed(0.f); + }); + auto slow_rotation_action = GUI::Action::create_checkable("&Slow", [&widget] { + widget.set_rotation_speed(0.5f); + }); + auto normal_rotation_action = GUI::Action::create_checkable("&Normal", [&widget] { + widget.set_rotation_speed(1.f); + }); + auto fast_rotation_action = GUI::Action::create_checkable("&Fast", [&widget] { + widget.set_rotation_speed(1.5f); + }); + + rotation_speed_actions.add_action(*no_rotation_action); + rotation_speed_actions.add_action(*slow_rotation_action); + rotation_speed_actions.add_action(*normal_rotation_action); + rotation_speed_actions.add_action(*fast_rotation_action); + + rotation_speed_menu.add_action(*no_rotation_action); + rotation_speed_menu.add_action(*slow_rotation_action); + rotation_speed_menu.add_action(*normal_rotation_action); + rotation_speed_menu.add_action(*fast_rotation_action); + + normal_rotation_action->set_checked(true); + auto& help_menu = menubar->add_menu("&Help"); help_menu.add_action(GUI::CommonActions::make_about_action("3D File Viewer", app_icon, window)); |