diff --git a/include/vkcv/Event.hpp b/include/vkcv/Event.hpp
index 092f271c025e63be80b994b6b3921795c3e99671..0836e836e84ff7dfc4931a7cedd65497bf9a89cf 100644
--- a/include/vkcv/Event.hpp
+++ b/include/vkcv/Event.hpp
@@ -34,8 +34,9 @@ namespace vkcv {
          * adds a function handle to the event to be called
          * @param handle of the function
          */
-        void add(typename event_function<T...>::type handle) {
+        typename event_function<T...>::type add(typename event_function<T...>::type handle) {
             this->m_handles.push_back(handle);
+            return handle;
         }
 
         /**
diff --git a/modules/camera/CMakeLists.txt b/modules/camera/CMakeLists.txt
index 0d33d0c3ef2ec9d90380e49861dd6451edc1c791..28080bf2b1cd3bbc88d6c13d7ef26a43d7c3e19a 100644
--- a/modules/camera/CMakeLists.txt
+++ b/modules/camera/CMakeLists.txt
@@ -13,6 +13,8 @@ set(vkcv_camera_sources
 		${vkcv_camera_source}/vkcv/camera/Camera.cpp
 		${vkcv_camera_include}/vkcv/camera/TrackballCamera.hpp
 		${vkcv_camera_source}/vkcv/camera/TrackballCamera.cpp
+		${vkcv_camera_include}/vkcv/camera/CameraManager.hpp
+		${vkcv_camera_source}/vkcv/camera/CameraManager.cpp
 )
 
 # adding source files to the project
diff --git a/modules/camera/include/vkcv/camera/CameraManager.hpp b/modules/camera/include/vkcv/camera/CameraManager.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6e4d577e8b13a7ac50a797e4c70651ac8715e49d
--- /dev/null
+++ b/modules/camera/include/vkcv/camera/CameraManager.hpp
@@ -0,0 +1,46 @@
+#pragma once
+
+#include "TrackballCamera.hpp"
+#include "vkcv/Window.hpp"
+#include <GLFW/glfw3.h>
+#include <functional>
+
+namespace vkcv{
+
+    class CameraManager{
+    private:
+        std::function <void(int, int, int ,int )> m_keyHandle;
+        std::function <void(double, double )> m_mouseMoveHandle;
+        std::function <void(double, double )> m_mouseScrollHandle;
+
+        Window &m_window;
+        Camera m_camera;
+        float m_width;
+        float m_height;
+        std::shared_ptr<vkcv::TrackballCamera> m_trackball;
+        glm::vec3 m_up;
+        glm::vec3 m_position;
+        glm::vec3 m_front;
+        glm::vec3 m_center;
+        float m_radius;
+        float m_cameraSpeed;
+        float m_roll;
+        float m_pitch;
+        float m_yaw;
+
+        bool m_firstMouse = true;
+        double m_lastX ;
+        double m_lastY ;
+
+        void bindCamera();
+        void keyCallback(int key, int scancode, int action, int mods);
+        void scrollCallback( double offsetX, double offsetY);
+        void mouseMoveCallback( double offsetX, double offsetY);
+
+    public:
+        CameraManager(Window &window, float width, float height);
+        CameraManager(Window &window, float width, float height, glm::vec3 up, glm::vec3 position, glm::vec3 front);
+
+        Camera getCamera();
+    };
+}
diff --git a/modules/camera/src/vkcv/camera/CameraManager.cpp b/modules/camera/src/vkcv/camera/CameraManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1219cd3a6544a69ef0abdca7b4ff8457abc9b119
--- /dev/null
+++ b/modules/camera/src/vkcv/camera/CameraManager.cpp
@@ -0,0 +1,139 @@
+#include "vkcv/camera/CameraManager.hpp"
+
+namespace vkcv{
+
+    //  m_window.e_mouseMove.add(this.onMouseMove);\
+
+    CameraManager::CameraManager(Window &window, float width, float height):
+    m_window(window), m_width(width), m_height(height)
+    {
+
+        glfwSetInputMode(m_window.getWindow(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
+        m_camera.setPerspective( glm::radians(60.0f), m_width / m_height, 0.1f, 10.f);
+        m_up = glm::vec3(0.0f, 1.0f, 0.0f);
+        m_position = glm::vec3(0.0f, 0.0f, 0.0f);
+        m_front = glm::vec3(0.0f, 0.0f, -1.0f);
+        m_center = m_position + m_front;
+        m_camera.lookAt(m_position, m_center, m_up);
+        m_radius = 10.0f;
+        m_cameraSpeed = 0.05f;
+        m_roll = 0.0;
+        m_pitch = 0.0;
+        m_yaw = 0.0;
+        bindCamera();
+    }
+
+    CameraManager::CameraManager(Window &window, float width, float height, glm::vec3 up, glm::vec3 position, glm::vec3 front):
+    m_window(window), m_width(width), m_height(height), m_up(up), m_position(position), m_front(front)
+    {
+        glfwSetInputMode(m_window.getWindow(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
+        m_camera.setPerspective( glm::radians(60.0f), m_width / m_height, 0.1f, 10.f);
+        m_up = glm::vec3(0.0f, 1.0f, 0.0f);
+        m_position = glm::vec3(0.0f, 0.0f, 0.0f);
+        m_front = glm::vec3(0.0f, 0.0f, -1.0f);
+        m_center = m_position + m_front;
+        m_camera.lookAt(m_position, m_center, m_up);
+        m_radius = 10.0f;
+        m_cameraSpeed = 0.05f;
+        m_roll = 0.0;
+        m_pitch = 0.0;
+        m_yaw = 0.0;
+        bindCamera();
+    }
+
+    void CameraManager::bindCamera(){
+        m_keyHandle = m_window.e_key.add( [&](int key, int scancode, int action, int mods) { this->keyCallback(key, scancode, action, mods); });
+        m_mouseMoveHandle = m_window.e_mouseMove.add( [&]( double offsetX, double offsetY) {this->mouseMoveCallback( offsetX, offsetY);} );
+        m_mouseScrollHandle =  m_window.e_mouseScroll.add([&](double offsetX, double offsetY) {this->scrollCallback( offsetX, offsetY);} );
+
+    }
+
+    void CameraManager::mouseMoveCallback(double x, double y){
+        if (m_firstMouse) {
+            m_lastX = x;
+            m_lastY = y;
+            m_firstMouse = false;
+        }
+
+        float xoffset = x - m_lastX;
+        float yoffset = m_lastY - y;
+        m_lastX = x;
+        m_lastY = y;
+
+        float sensitivity = 0.1f;
+        xoffset *= sensitivity;
+        yoffset *= sensitivity;
+
+        m_yaw += xoffset;
+        m_pitch += yoffset;
+
+        if (m_pitch > 89.0f) {
+            m_pitch = 89.0f;
+        }
+        if (m_pitch < -89.0f) {
+            m_pitch = -89.0f;
+        }
+
+        glm::vec3 direction;
+        direction.x = cos(glm::radians(m_yaw)) * cos(glm::radians(m_pitch));
+        direction.y = sin(glm::radians(m_pitch));
+        direction.z = sin(glm::radians(m_yaw)) * cos(glm::radians(m_pitch));
+
+        m_front = glm::normalize(direction);
+        m_center = m_position + m_front;
+        m_camera.lookAt(m_position, m_center, m_up);
+    }
+
+    void CameraManager::scrollCallback(double offsetX, double offsetY) {
+
+        float fov = m_camera.getFov();
+        fov -= (float) offsetY;
+        if (fov < 1.0f) {
+            fov = 1.0f;
+        }
+        if (fov > 45.0f) {
+            fov = 45.0f;
+        }
+        m_camera.setFov(fov);
+    }
+
+    void CameraManager::keyCallback(int key, int scancode, int action, int mods) {
+        switch (key) {
+            case GLFW_KEY_W:
+                //std::cout << "Move forward" << std::endl;
+                m_position += m_cameraSpeed * m_front;
+                m_center = m_position + m_front;
+                m_camera.lookAt(m_position, m_center, m_up);
+            case GLFW_KEY_S:
+                //std::cout << "Move left" << std::endl;
+                m_position -= m_cameraSpeed * m_front;
+                m_center = m_position + m_front;
+                m_position += m_cameraSpeed * m_front;
+                m_camera.lookAt(m_position, m_center, m_up);
+                break;
+            case GLFW_KEY_A:
+                //std::cout << "Move backward" << std::endl;
+                m_position += m_cameraSpeed * m_front;
+                m_position -= glm::normalize(glm::cross(m_front, m_up)) * m_cameraSpeed;
+                m_center = m_position + m_front;
+                m_camera.lookAt(m_position, m_center, m_up);
+                break;
+            case GLFW_KEY_D:
+                //std::cout << "Move right" << std::endl;
+                m_position += m_cameraSpeed * m_front;
+                m_position += glm::normalize(glm::cross(m_front, m_up)) * m_cameraSpeed;
+                m_center = m_position + m_front;
+                m_camera.lookAt(m_position, m_center, m_up);
+                break;
+            case GLFW_KEY_ESCAPE:
+                glfwSetWindowShouldClose(m_window.getWindow(), 1);
+                break;
+            default:
+                break;
+        }
+    }
+    Camera CameraManager::getCamera(){
+        return m_camera;
+    }
+
+}
\ No newline at end of file
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index ac6e3325ea32daa1242d068ea698baff5466e22f..7908831a464127306d90759a431cd221938b9d28 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -3,8 +3,7 @@
 #include <vkcv/Window.hpp>
 #include <vkcv/ShaderProgram.hpp>
 #include <GLFW/glfw3.h>
-#include <vkcv/camera/Camera.hpp>
-#include <vkcv/camera/TrackballCamera.hpp>
+#include <vkcv/camera/CameraManager.hpp>
 
 
 int main(int argc, const char** argv) {
@@ -19,110 +18,7 @@ int main(int argc, const char** argv) {
 		false
     );
 
-    // TODO: this code will be put in a camera controller class
-    vkcv::Camera camera;
-    std::shared_ptr<vkcv::TrackballCamera> trackball;
-    camera.setPerspective( glm::radians(60.0f), windowWidth / (float)windowHeight, 0.1f, 10.f);
-    glm::vec3 up(0.0f, 1.0f, 0.0f);
-    glm::vec3 position(0.0f, 0.0f, 0.0f);
-    glm::vec3 front(0.0f, 0.0f, -1.0f);
-    glm::vec3 center = position + front;
-    camera.lookAt(position, center, up);
-    const float radius = 10.0f;
-    const float cameraSpeed = 0.05f;
-    float roll = 0.0;
-    float pitch = 0.0;
-    float yaw = 0.0;
-
-    //TODO? should the standard camera support rotation?
-
-    bool firstMouse = true;
-    double lastX, lastY;
-
-    // showing basic usage lambda events of window
-    window.e_mouseMove.add([&](double x, double y) {
-        //std::cout << "movement: " << x << " , " << y << std::endl;
-
-        if (firstMouse) {
-            lastX = x;
-            lastY = y;
-            firstMouse = false;
-        }
-
-        float xoffset = x - lastX;
-        float yoffset = lastY - y;
-        lastX = x;
-        lastY = y;
-
-        float sensitivity = 0.1f;
-        xoffset *= sensitivity;
-        yoffset *= sensitivity;
-
-        yaw += xoffset;
-        pitch += yoffset;
-
-        if (pitch > 89.0f) {
-            pitch = 89.0f;
-        }
-        if (pitch < -89.0f) {
-            pitch = -89.0f;
-        }
-
-        glm::vec3 direction;
-        direction.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
-        direction.y = sin(glm::radians(pitch));
-        direction.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
-
-        front = glm::normalize(direction);
-        center = position + front;
-        camera.lookAt(position, center, up);
-
-		//std::cout << "New center: " << center.x << ", " << center.y << ", " << center.z << std::endl;
-    });
-
-    window.e_mouseScroll.add([&](double xoffset, double yoffset) {
-        float fov = camera.getFov();
-        fov -= (float)yoffset;
-        if (fov < 1.0f) {
-            fov = 1.0f;
-        }
-        if (fov > 45.0f) {
-            fov = 45.0f;
-        }
-        camera.setFov(fov);
-		//std::cout << "New FOV: " << fov << std::endl;
-    });
-
-    window.e_key.add([&](int key, int scancode, int action, int mods) {
-        switch (key) {
-            case GLFW_KEY_W:
-				//std::cout << "Move forward" << std::endl;
-                position += cameraSpeed * front;
-                center = position + front;
-                camera.lookAt(position, center, up);
-                break;
-            case GLFW_KEY_S:
-				//std::cout << "Move left" << std::endl;
-                position -= cameraSpeed * front;
-                center = position + front;
-                camera.lookAt(position, center, up);
-                break;
-            case GLFW_KEY_A:
-				//std::cout << "Move backward" << std::endl;
-                position -= glm::normalize(glm::cross(front, up)) * cameraSpeed;
-                center = position + front;
-                camera.lookAt(position, center, up);
-                break;
-            case GLFW_KEY_D:
-				//std::cout << "Move right" << std::endl;
-                position += glm::normalize(glm::cross(front, up)) * cameraSpeed;
-                center = position + front;
-                camera.lookAt(position, center, up);
-                break;
-            default:
-				break;//std::cout << "this key is not supported yet: " << std::endl;
-        }
-    });
+    vkcv::CameraManager cameraManager(window, windowWidth, windowHeight);
 
     window.initEvents();
 
@@ -212,7 +108,7 @@ int main(int argc, const char** argv) {
 	{
 		core.beginFrame();
 
-		const glm::mat4 mvp = camera.getProjection() * camera.getView();
+		const glm::mat4 mvp = cameraManager.getCamera().getProjection() * cameraManager.getCamera().getView();
 
 	    core.renderTriangle(trianglePass, trianglePipeline, windowWidth, windowHeight, sizeof(mvp), &mvp);
 	    core.endFrame();