From ebf121e1ce523b2755323397a757acf4f3923e4b Mon Sep 17 00:00:00 2001
From: Krisjanis Rijnieks <krisjanis.rijnieks@gmail.com>
Date: Sat, 20 Aug 2016 20:58:30 +0200
Subject: [PATCH] Add work in progress `GuiWidgetEvent`

---
 example/example.xcodeproj/project.pbxproj  |  8 +++++
 src/Application/Application.cpp            | 10 ++++++
 src/Application/Application.h              |  2 ++
 src/Application/ApplicationBaseState.h     |  2 ++
 src/Application/Gui.cpp                    | 25 +++++++++++++
 src/Application/Gui.h                      | 18 ++++++++++
 src/Application/ProjectionMappingState.cpp | 41 ++++++++--------------
 src/Application/ProjectionMappingState.h   |  8 ++++-
 src/Application/ScaleWidget.cpp            | 26 +++++++++-----
 src/Application/ScaleWidget.h              |  9 ++---
 src/Surfaces/SurfaceManagerGui.cpp         |  2 ++
 11 files changed, 111 insertions(+), 40 deletions(-)

diff --git a/example/example.xcodeproj/project.pbxproj b/example/example.xcodeproj/project.pbxproj
index dbbd46f..8808cfa 100644
--- a/example/example.xcodeproj/project.pbxproj
+++ b/example/example.xcodeproj/project.pbxproj
@@ -9,6 +9,7 @@
 /* Begin PBXBuildFile section */
 		0117D70A1D64EBB4008FECEB /* ScaleSurfaceDnCmd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0117D7081D64EBB4008FECEB /* ScaleSurfaceDnCmd.cpp */; };
 		0117D70B1D64EBB4008FECEB /* ScaleSurfaceUpCmd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0117D7091D64EBB4008FECEB /* ScaleSurfaceUpCmd.cpp */; };
+		0117D7131D66F16C008FECEB /* ScaleWidget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0117D7121D66F16C008FECEB /* ScaleWidget.cpp */; };
 		0130C9681CE65AA600911E17 /* README.md in Sources */ = {isa = PBXBuildFile; fileRef = 0130C90A1CE65AA600911E17 /* README.md */; };
 		0130C9691CE65AA600911E17 /* lz4.c in Sources */ = {isa = PBXBuildFile; fileRef = 0130C90D1CE65AA600911E17 /* lz4.c */; };
 		0130C96A1CE65AA600911E17 /* Base64Encoding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0130C92E1CE65AA600911E17 /* Base64Encoding.cpp */; };
@@ -169,6 +170,9 @@
 		0117D7071D64EBB4008FECEB /* ScaleSurfaceUpCmd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScaleSurfaceUpCmd.h; path = Commands/ScaleSurfaceUpCmd.h; sourceTree = "<group>"; };
 		0117D7081D64EBB4008FECEB /* ScaleSurfaceDnCmd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScaleSurfaceDnCmd.cpp; path = Commands/ScaleSurfaceDnCmd.cpp; sourceTree = "<group>"; };
 		0117D7091D64EBB4008FECEB /* ScaleSurfaceUpCmd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScaleSurfaceUpCmd.cpp; path = Commands/ScaleSurfaceUpCmd.cpp; sourceTree = "<group>"; };
+		0117D70E1D65A8C1008FECEB /* GuiBaseWidget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GuiBaseWidget.h; sourceTree = "<group>"; };
+		0117D7111D66F16C008FECEB /* ScaleWidget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScaleWidget.h; sourceTree = "<group>"; };
+		0117D7121D66F16C008FECEB /* ScaleWidget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScaleWidget.cpp; sourceTree = "<group>"; };
 		0130C9041CE65AA600911E17 /* alphanum.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = alphanum.hpp; sourceTree = "<group>"; };
 		0130C9071CE65AA600911E17 /* json.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = json.hpp; sourceTree = "<group>"; };
 		0130C9091CE65AA600911E17 /* LICENSE.MIT */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE.MIT; sourceTree = "<group>"; };
@@ -717,6 +721,9 @@
 				39FBE8B31C6A6BDF00155B9E /* GuiEventType.h */,
 				39FBE8B01C6A636900155B9E /* Gui.h */,
 				39FBE8B11C6A636900155B9E /* Gui.cpp */,
+				0117D70E1D65A8C1008FECEB /* GuiBaseWidget.h */,
+				0117D7111D66F16C008FECEB /* ScaleWidget.h */,
+				0117D7121D66F16C008FECEB /* ScaleWidget.cpp */,
 				3968416A1BC91F6F009F0BAE /* Application.h */,
 				396841691BC91F6F009F0BAE /* Application.cpp */,
 				39FA2B7F1C457606003FAB28 /* SettingsLoader.h */,
@@ -1169,6 +1176,7 @@
 				39C1245E19F08965005DF557 /* ImageSource.cpp in Sources */,
 				397C46BD1C398D72002689E2 /* SurfaceStack.cpp in Sources */,
 				3933D5D619BB87BD000ACA55 /* ofxLabel.cpp in Sources */,
+				0117D7131D66F16C008FECEB /* ScaleWidget.cpp in Sources */,
 				39C1245F19F08965005DF557 /* VideoSource.cpp in Sources */,
 				39F0512D1C650D070089A36B /* SelNextVertexCmd.cpp in Sources */,
 				391717F31B0A8A7300F9A484 /* MvAllTexCoordsCmd.cpp in Sources */,
diff --git a/src/Application/Application.cpp b/src/Application/Application.cpp
index 1efddaa..40e5c01 100644
--- a/src/Application/Application.cpp
+++ b/src/Application/Application.cpp
@@ -14,6 +14,8 @@ Application::Application(){
 	ofAddListener(ofEvents().keyPressed, this, &Application::onKeyPressed);
 	ofAddListener(ofEvents().keyReleased, this, &Application::onKeyReleased);
 	ofAddListener(ofEvents().mousePressed, this, &Application::onMousePressed);
+	ofAddListener(ofEvents().mouseReleased, this, &Application::onMouseReleased);
+	ofAddListener(ofEvents().mouseDragged, this, &Application::onMouseDragged);
 	
 	ofAddListener(Gui::instance()->jointPressedEvent, this, &Application::onJointPressed);
 	ofAddListener(Gui::instance()->surfacePressedEvent, this, &Application::onSurfacePressed);
@@ -127,6 +129,14 @@ void Application::onMousePressed(ofMouseEventArgs & args){
     _state->onMousePressed(this, args);
 }
 
+void Application::onMouseReleased(ofMouseEventArgs & args){
+	_state->onMouseReleased(this, args);
+}
+
+void Application::onMouseDragged(ofMouseEventArgs &args){
+	_state->onMouseDragged(this, args);
+}
+
 void Application::onJointPressed(GuiJointEvent & e){
 	_state->onJointPressed(this, e);
 }
diff --git a/src/Application/Application.h b/src/Application/Application.h
index 31a250e..f2adea1 100644
--- a/src/Application/Application.h
+++ b/src/Application/Application.h
@@ -44,6 +44,8 @@ class Application : public KeyListener {
 	
 		// We use this to pass mouse events into the GUI layer
 		void onMousePressed(ofMouseEventArgs & args);
+		void onMouseReleased(ofMouseEventArgs & args);
+		void onMouseDragged(ofMouseEventArgs & args);
 	
 		// Then we catch GUI events with this one and create commands
 		void onJointPressed(GuiJointEvent & e);
diff --git a/src/Application/ApplicationBaseState.h b/src/Application/ApplicationBaseState.h
index 6a7787d..19ca573 100644
--- a/src/Application/ApplicationBaseState.h
+++ b/src/Application/ApplicationBaseState.h
@@ -18,6 +18,8 @@ class ApplicationBaseState {
 		// Event handler virtual methods
 		virtual void onKeyPressed(Application * app, ofKeyEventArgs & args){}
         virtual void onMousePressed(Application * app, ofMouseEventArgs & args){}
+		virtual void onMouseReleased(Application * app, ofMouseEventArgs & args){}
+		virtual void onMouseDragged(Application * app, ofMouseEventArgs & args){}
 		virtual void onJointPressed(Application * app, GuiJointEvent & e){}
 		virtual void onSurfacePressed(Application * app, GuiSurfaceEvent & e){}
 		virtual void onBackgroundPressed(Application * app, GuiBackgroundEvent & e){}
diff --git a/src/Application/Gui.cpp b/src/Application/Gui.cpp
index 3ed3f7e..61acf30 100644
--- a/src/Application/Gui.cpp
+++ b/src/Application/Gui.cpp
@@ -60,5 +60,30 @@ void Gui::notifyBackgroundPressed(ofMouseEventArgs & args){
 	ofNotifyEvent(backgroundPressedEvent, e, this);
 }
 
+void Gui::onMousePressed(ofMouseEventArgs & args){
+	_scaleWidget.onMousePressed(args);
+}
+
+void Gui::onMouseReleased(ofMouseEventArgs & args){
+	_scaleWidget.onMouseReleased(args);
+}
+
+void Gui::onMouseDragged(ofMouseEventArgs & args){
+	_scaleWidget.onMouseDragged(args);
+}
+
+void Gui::notifyGuiWidgetEvent(ofMouseEventArgs &args, ofx::piMapper::GuiBaseWidget * widget){
+	GuiWidgetEvent e;
+	e.args = args;
+	e.widget = widget;
+	ofNotifyEvent(guiWidgetEvent, e, this);
+	
+	cout << "args.Dragged: " << args.Dragged << endl;
+}
+
+ScaleWidget & Gui::getScaleWidget(){
+	return _scaleWidget;
+}
+
 } // piMapper
 } // ofx
\ No newline at end of file
diff --git a/src/Application/Gui.h b/src/Application/Gui.h
index 48b0eab..a0fc2d7 100644
--- a/src/Application/Gui.h
+++ b/src/Application/Gui.h
@@ -4,6 +4,9 @@
 #include "GuiEventType.h"
 #include "BaseSurface.h"
 
+#include "GuiBaseWidget.h"
+#include "ScaleWidget.h"
+
 namespace ofx {
 namespace piMapper {
 
@@ -33,6 +36,11 @@ struct GuiBackgroundEvent{
 	ofMouseEventArgs args;
 };
 
+struct GuiWidgetEvent{
+	ofMouseEventArgs args;
+	GuiBaseWidget * widget;
+};
+
 class Gui {
 	public:
 		static Gui * instance();
@@ -58,8 +66,18 @@ class Gui {
 	
 		void notifyBackgroundPressed(ofMouseEventArgs & args);
 	
+		ScaleWidget & getScaleWidget();
+		ofEvent <GuiWidgetEvent> guiWidgetEvent;
+		void notifyGuiWidgetEvent(ofMouseEventArgs & args, GuiBaseWidget * widget);
+	
+		void onMousePressed(ofMouseEventArgs & args);
+		void onMouseReleased(ofMouseEventArgs & args);
+		void onMouseDragged(ofMouseEventArgs & args);
+	
 	private:
 		static Gui * _instance;
+	
+		ScaleWidget _scaleWidget;
 };
 
 } // piMapper
diff --git a/src/Application/ProjectionMappingState.cpp b/src/Application/ProjectionMappingState.cpp
index 95f76de..ec0d763 100644
--- a/src/Application/ProjectionMappingState.cpp
+++ b/src/Application/ProjectionMappingState.cpp
@@ -15,37 +15,14 @@ ProjectionMappingState * ProjectionMappingState::instance(){
 void ProjectionMappingState::draw(Application * app){
 	app->getGui()->draw();
 	
-	// Draw the new GUI with fresh elements, based on a new pattern.
-	//Gui::instance()->draw();
-	
 	/*
-		Draw scaling widgets. A handle from the center of the surface to a fraction outside
-		the bounding box.
+		Draw scale widget.
 	*/
 	BaseSurface * selectedSurface = app->getSurfaceManager()->getSelectedSurface();
 	if(selectedSurface != 0){
-		ofVec3f centroid = selectedSurface->getMesh().getCentroid();
 		ofRectangle boundingBox = selectedSurface->getBoundingBox();
-		
-		ofPushStyle();
-		
-		ofSetColor(255, 255, 255);
-		ofNoFill();
-		
-		ofDrawCircle(centroid.x, centroid.y, 5);
-		
-		ofDrawLine(centroid.x, centroid.y, boundingBox.x + boundingBox.width + 40, boundingBox.y);
-		
-		ofRectangle handle;
-		handle.width = 20;
-		handle.height = 20;
-		handle.x = boundingBox.x + boundingBox.width + 40 - (handle.width / 2);
-		handle.y = boundingBox.y - (handle.height / 2);
-		ofSetLineWidth(2);
-		
-		ofDrawRectangle(handle);
-		
-		ofPopStyle();
+		Gui::instance()->getScaleWidget().setRect(boundingBox);
+		Gui::instance()->getScaleWidget().draw();
 	}
 	
 	/*
@@ -326,6 +303,18 @@ void ProjectionMappingState::onKeyPressed(Application * app, ofKeyEventArgs & ar
 	}
 }
 
+void ProjectionMappingState::onMousePressed(Application * app, ofMouseEventArgs & args){
+	Gui::instance()->onMousePressed(args);
+}
+
+void ProjectionMappingState::onMouseReleased(Application * app, ofMouseEventArgs & args){
+	Gui::instance()->onMouseReleased(args);
+}
+
+void ProjectionMappingState::onMouseDragged(Application * app, ofMouseEventArgs & args){
+	Gui::instance()->onMouseDragged(args);
+}
+
 void ProjectionMappingState::onJointPressed(Application * app, GuiJointEvent & e){
 	app->getCmdManager()->exec(new SelVertexCmd(app->getSurfaceManager(), e.jointIndex));
 	app->getCmdManager()->exec(new MvSurfaceVertCmd(
diff --git a/src/Application/ProjectionMappingState.h b/src/Application/ProjectionMappingState.h
index 83e5684..471ba31 100644
--- a/src/Application/ProjectionMappingState.h
+++ b/src/Application/ProjectionMappingState.h
@@ -30,6 +30,8 @@
 #include "SurfaceType.h"
 #include "Gui.h"
 
+#include "ScaleWidget.h"
+
 namespace ofx {
 namespace piMapper {
 
@@ -37,15 +39,19 @@ class ProjectionMappingState : public ApplicationBaseState {
 
 	public:
 		static ProjectionMappingState * instance();
+	
 		void draw(Application * app);
 		void onKeyPressed(Application * app, ofKeyEventArgs & args);
+		void onMousePressed(Application * app, ofMouseEventArgs & args);
+		void onMouseReleased(Application * app, ofMouseEventArgs & args);
+		void onMouseDragged(Application * app, ofMouseEventArgs & args);
 		void onJointPressed(Application * app, GuiJointEvent & e);
 		void onSurfacePressed(Application * app, GuiSurfaceEvent & e);
 		void onBackgroundPressed(Application * app, GuiBackgroundEvent & e);
 
 	private:
 		static ProjectionMappingState * _instance;
-
+	
 };
 
 } // namespace piMapper
diff --git a/src/Application/ScaleWidget.cpp b/src/Application/ScaleWidget.cpp
index e2055ce..4ef793f 100644
--- a/src/Application/ScaleWidget.cpp
+++ b/src/Application/ScaleWidget.cpp
@@ -34,22 +34,26 @@ void ScaleWidget::draw(){
 	ofPopStyle();
 }
 
-void ScaleWidget::onMousePressed(ofMouseEventArgs & e){
-	if(_handle.inside(e.x, e.y)){
-		std::cout << "Handle clicked" << std::endl;
+void ScaleWidget::onMousePressed(ofMouseEventArgs & args){
+	if(_handle.inside(args.x, args.y)){
+		std::cout << "ScaleWidget: Handle clicked" << std::endl;
 		_dragging = true;
 	}
 }
 
-void ScaleWidget::onMouseReleased(ofMouseEventArgs & e){
+void ScaleWidget::onMouseReleased(ofMouseEventArgs & args){
+	std::cout << "ScaleWidget: Mouse released" << std::endl;
 	_dragging = false;
 }
 
-void ScaleWidget::onMouseDragged(ofMouseEventArgs & e){
+void ScaleWidget::onMouseDragged(ofMouseEventArgs & args){
+	std::cout << "ScaleWidget: Mouse dragged" << std::endl;
 	if(_dragging){
-		_handle.x = e.x;
-		_handle.y = e.y;
+		_handle.x = args.x - (_handle.width / 2.0f);
+		_handle.y = args.y - (_handle.height / 2.0f);
 	}
+	
+	//Gui::instance()->notifyGuiWidgetEvent(args, this);
 }
 
 bool ScaleWidget::inside(float x, float y){
@@ -58,6 +62,10 @@ bool ScaleWidget::inside(float x, float y){
 }
 
 void ScaleWidget::setRect(ofRectangle rect){
+	if(_dragging){
+		return;
+	}
+	
 	ofPoint center = rect.getCenter();
 	
 	_line.getVertices()[0].x = center.x;
@@ -66,8 +74,8 @@ void ScaleWidget::setRect(ofRectangle rect){
 	_line.getVertices()[1].x = rect.x + rect.width;
 	_line.getVertices()[1].y = rect.y;
 	
-	_handle.x = rect.x + rect.width;
-	_handle.y = rect.y;
+	_handle.x = rect.x + rect.width - (_handle.width / 2.0f);
+	_handle.y = rect.y - (_handle.height / 2.0f);
 }
 
 } // namespace piMapper
diff --git a/src/Application/ScaleWidget.h b/src/Application/ScaleWidget.h
index 4b3210d..1fd39a2 100644
--- a/src/Application/ScaleWidget.h
+++ b/src/Application/ScaleWidget.h
@@ -4,11 +4,12 @@
 #include "ofPolyline.h"
 #include "GuiBaseWidget.h"
 #include "ofGraphics.h"
+//#include "Gui.h"
 
 namespace ofx {
 namespace piMapper {
 
-class ScaleWidget : GuiBaseWidget {
+class ScaleWidget : public GuiBaseWidget {
 	public:
 		ScaleWidget();
 	
@@ -16,9 +17,9 @@ class ScaleWidget : GuiBaseWidget {
 		void update();
 		void draw();
 	
-		void onMousePressed(ofMouseEventArgs & e);
-		void onMouseReleased(ofMouseEventArgs & e);
-		void onMouseDragged(ofMouseEventArgs & e);
+		void onMousePressed(ofMouseEventArgs & args);
+		void onMouseReleased(ofMouseEventArgs & args);
+		void onMouseDragged(ofMouseEventArgs & args);
 	
 		bool inside(float x, float y);
 	
diff --git a/src/Surfaces/SurfaceManagerGui.cpp b/src/Surfaces/SurfaceManagerGui.cpp
index 75e35d3..8efdd67 100644
--- a/src/Surfaces/SurfaceManagerGui.cpp
+++ b/src/Surfaces/SurfaceManagerGui.cpp
@@ -166,6 +166,8 @@ void SurfaceManagerGui::mousePressed(ofMouseEventArgs & args){
 			clickPosition = ofVec2f(args.x, args.y);
 			startDrag(); // TODO: Should be something like `hitSurface->startDrag()`
 			Gui::instance()->notifySurfacePressed(args, hitSurface);
+		}else if(Gui::instance()->getScaleWidget().inside(args.x, args.y)){
+			//
 		}else{
 			Gui::instance()->notifyBackgroundPressed(args);
 		}