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)
This commit is contained in:
Erik Biederstadt 2021-05-25 16:01:32 -06:00 committed by Linus Groh
parent 1ce32ef675
commit 3ea256b1c6
Notes: sideshowbarker 2024-07-18 17:20:53 +09:00

View file

@ -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));