From bcce3dddb582a736003626b0ace9fc1f4c74505c Mon Sep 17 00:00:00 2001
From: Augustin Degomme <augustin.degomme@imag.fr>
Date: Mon, 21 Mar 2011 13:53:53 +0000
Subject: [PATCH] add a vertical helper line when a single click is made on the
 trace. Click again on the same spot or in the containers to hide it. The line
 can also be deactivated in the view menu, and isn't assigned on double clicks

---
 src/common/Info.cpp                 |  1 +
 src/common/Info.hpp                 | 15 ++++++---
 src/interface/Interface_graphic.cpp |  3 ++
 src/interface/Interface_graphic.hpp |  5 +++
 src/interface/main_window.ui        | 12 +++++++
 src/render/Hook_event.cpp           | 46 ++++++++++++++++++++++++--
 src/render/Hook_event.hpp           | 10 ++++++
 src/render/Render_opengl.cpp        | 50 ++++++++++++++++++++++++++---
 src/render/Render_opengl.hpp        | 28 ++++++++++++++++
 9 files changed, 158 insertions(+), 12 deletions(-)

diff --git a/src/common/Info.cpp b/src/common/Info.cpp
index 1a5f4c0d..8441d081 100644
--- a/src/common/Info.cpp
+++ b/src/common/Info.cpp
@@ -75,6 +75,7 @@ Element_pos Info::Render::_info_accurate = 0.0;
 bool        Info::Render::_no_arrows     = false;
 bool        Info::Render::_no_events     = false;
 bool        Info::Render::_shaded_states = true;/* By default, enable shaded state */
+bool        Info::Render::_vertical_line = true;/* By default, enable vertical line */
 
 int Info::Trace::depth=0;
 
diff --git a/src/common/Info.hpp b/src/common/Info.hpp
index eb834cc9..41dfb8f5 100644
--- a/src/common/Info.hpp
+++ b/src/common/Info.hpp
@@ -184,12 +184,17 @@ public:
          */
         static bool _no_events;
 
-	/*!
-	* \brief Control if the color of State is uniform (value is false) or shaded (value is true). (By default, shaded)
-	*/
-	static bool _shaded_states;
+		/*!
+		 * \brief Control if the color of State is uniform (value is false) or shaded (value is true). (By default, shaded)
+		 */
+		static bool _shaded_states;
 
-	/*!
+		/*!
+		 * \brief Control if the vertical line is on. (By default, yes)
+		 */
+		static bool _vertical_line;
+
+		/*!
          * \brief Contains the trace minimum visible time.
          */
         static Element_pos _x_min_visible;
diff --git a/src/interface/Interface_graphic.cpp b/src/interface/Interface_graphic.cpp
index 6d71364f..dd41167d 100644
--- a/src/interface/Interface_graphic.cpp
+++ b/src/interface/Interface_graphic.cpp
@@ -738,6 +738,9 @@ void Interface_graphic::on_fullscreen_triggered(){
         this->showNormal();
 }
 
+void Interface_graphic::on_vertical_line_triggered(){
+    Info::Render::_vertical_line=!Info::Render::_vertical_line;
+}
 
 void Interface_graphic::on_shaded_states_triggered(){
     Info::Render::_shaded_states=!Info::Render::_shaded_states;
diff --git a/src/interface/Interface_graphic.hpp b/src/interface/Interface_graphic.hpp
index a77f8c84..f0716a79 100644
--- a/src/interface/Interface_graphic.hpp
+++ b/src/interface/Interface_graphic.hpp
@@ -549,6 +549,11 @@ protected slots:
      *\brief A slot called when 'Shaded states' in the menu is clicked.
      */
     void on_shaded_states_triggered();
+	
+	/*!
+     *\brief A slot called when 'Vertical line' in the menu is clicked.
+     */
+    void on_vertical_line_triggered();
 
     /*!
      *\brief A slot called when 'Show toolbar' in the menu is clicked.
diff --git a/src/interface/main_window.ui b/src/interface/main_window.ui
index 16adfcac..01d0bde6 100644
--- a/src/interface/main_window.ui
+++ b/src/interface/main_window.ui
@@ -212,6 +212,7 @@
     <addaction name="goto_end"/>
     <addaction name="separator"/>
     <addaction name="shaded_states"/>
+    <addaction name="vertical_line"/>	
     <addaction name="separator"/>
     <addaction name="fullscreen"/>
     <addaction name="separator"/>
@@ -540,6 +541,17 @@
     <string>Shaded states</string>
    </property>
   </action>
+  <action name="vertical_line">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Vertical Line</string>
+   </property>
+  </action>
  </widget>
  <resources>
   <include location="vite.qrc"/>
diff --git a/src/render/Hook_event.cpp b/src/render/Hook_event.cpp
index d554663a..a6c8e888 100644
--- a/src/render/Hook_event.cpp
+++ b/src/render/Hook_event.cpp
@@ -51,6 +51,7 @@
 #include <QMessageBox>
 #include <QMouseEvent>
 #include <QGLWidget>
+#include <QTimer>
 /* -- */
 #include "common/common.hpp"
 #include "common/Info.hpp"
@@ -70,6 +71,21 @@ using namespace std;
 #define message *Message::get_instance() << "(" << __FILE__ << " l." << __LINE__ << "): "
 
 
+#ifdef WIN32
+#define getTimeClick() GetDoubleClickTime()
+#else
+#define getTimeClick() 200/*
+#include "X11/Intrinsic.h"
+#include <QX11Info>
+
+#define getTimeClick() try{\
+XtGetMultiClickTime(((QWidget*)this->parent())->x11Info().display());\
+}catch(char* e){\
+printf("%s \n", e);\
+}*/
+#endif
+
+
 const int Hook_event::DRAWING_STATE_WAITING = 1;
 const int Hook_event::DRAWING_STATE_DRAWING = 2;
 const int Hook_event::_ctrl_scroll_factor = 10;
@@ -160,7 +176,11 @@ Hook_event::Hook_event(Render_opengl* render_instance, Core* core, QWidget *pare
 
     setMouseTracking (true);/* to catch mouse events */
     setFocusPolicy(Qt::StrongFocus);/* to catch keybord events (focus by tabbing or clicking) */
-
+    
+    //initialize the timer for single click handling
+    _timer = new QTimer(this);
+    _timer->setSingleShot(true);
+    _connected=false;
     //updateRender();
    
 }
@@ -268,6 +288,11 @@ void Hook_event::mousePressEvent(QMouseEvent * event){
 void Hook_event::mouseDoubleClickEvent ( QMouseEvent * event ){
     Element_pos x_result, y_result;/* The click coordinates for the Data Structure. */
 
+
+    if(_timer->isActive()){
+        _timer->stop(); 
+    }
+    
     if( Qt::LeftButton == event->button() ){
         x_result = render_to_trace_x(screen_to_render_x(_mouse_x));
         y_result = render_to_trace_y(screen_to_render_y(_mouse_y));
@@ -302,6 +327,13 @@ void Hook_event::mouseMoveEvent(QMouseEvent * event){
 
 
 void Hook_event::mouseReleaseEvent(QMouseEvent * event){
+    //if the timer has not been connected yet, connect it (there is a problem with QT signal/slots and genericty, and the type of this isn't right in the constructor)
+    if(!_connected){
+        connect(_timer, SIGNAL(timeout()), (Hook_event*)this, SLOT(update_vertical_line()));
+        _connected=true;
+    }
+    
+    
     Element_pos invert_buf_x;
     Element_pos invert_buf_y;
 
@@ -335,7 +367,10 @@ void Hook_event::mouseReleaseEvent(QMouseEvent * event){
 
     if (((_new_mouse_x-_mouse_x) < _minimum_distance_for_selection)
         && ((_new_mouse_y-_mouse_y) < _minimum_distance_for_selection)){/* selection is too thin to draw a box. So, it must be a user click to display entity information */
-
+        //start the timer to catch a click or double click
+        _timer->start(getTimeClick());
+		
+			
         _mouse_pressed                  = false;
         _mouse_pressed_inside_container = false;
         _mouse_pressed_inside_ruler     = false;
@@ -346,6 +381,9 @@ void Hook_event::mouseReleaseEvent(QMouseEvent * event){
     /* Thin box in the ruler: ignore */
     if (_mouse_pressed_inside_ruler &&
         ((_new_mouse_x-_mouse_x) < _minimum_distance_for_selection) ){
+		
+        //start the timer to catch a click or double click
+        _timer->start(getTimeClick());
    
         _mouse_pressed              = false;    
         _mouse_pressed_inside_ruler = false;
@@ -357,6 +395,10 @@ void Hook_event::mouseReleaseEvent(QMouseEvent * event){
     if (_mouse_pressed_inside_container &&
         ((_new_mouse_y-_mouse_y) < _minimum_distance_for_selection) ){
 
+        //start the timer to catch a click or double click
+        _timer->start(getTimeClick());
+	    _render_instance->set_vertical_line(0);
+		
         _mouse_pressed                  = false;
         _mouse_pressed_inside_container = false;
         updateRender();
diff --git a/src/render/Hook_event.hpp b/src/render/Hook_event.hpp
index 39cad202..81a4c244 100644
--- a/src/render/Hook_event.hpp
+++ b/src/render/Hook_event.hpp
@@ -115,6 +115,16 @@ protected:
      */
     Core* _core;
 
+    /*!
+     * \brief timer to check whether we launched a double click event or a single click event
+     */
+    QTimer* _timer;
+    
+    /*!
+     * \briefcheck if the timer has already been launched and the signal connected to the slot
+     */
+    bool _connected;
+    
 
     /***********************************
      *
diff --git a/src/render/Render_opengl.cpp b/src/render/Render_opengl.cpp
index 98cd79f9..56db560b 100644
--- a/src/render/Render_opengl.cpp
+++ b/src/render/Render_opengl.cpp
@@ -102,7 +102,7 @@ Render_opengl::Render_opengl(Core* core, QWidget *parent, const QGLFormat& forma
     connect(_wait_timer, SIGNAL(timeout()), _render_instance, SLOT(updateGL()));
     _wait_timer->start(_wait_spf);
 #endif // SPINNING_LOGO
-
+	vertical_line=0;
     setAutoFillBackground(false);
 }
 
@@ -239,6 +239,10 @@ void  Render_opengl::paintGL(){
             
             if (false == Info::Render::_no_events)/* display events */
                 draw_stored_circles();
+				
+			if (Info::Render::_vertical_line){
+				draw_vertical_line();
+			}
 	
             /* Untranslate ruler */
             glEnable(GL_BLEND);
@@ -391,10 +395,10 @@ void  Render_opengl::paintGL(){
                          _minimap.width()/_x_state_scale,
                          _minimap.height()/_y_state_scale
                          );
-       //initialize the minimap if it hasn't been done yet                 
-       if(!_minimap.is_initialized()){
-           QImage buf = grabFrameBuffer(true);
-           _minimap.init(buf);
+       //initialize the minimap if it hasn't been done yet                 
+       if(!_minimap.is_initialized()){
+           QImage buf = grabFrameBuffer(true);
+           _minimap.init(buf);
        }
      
 }
@@ -998,6 +1002,42 @@ void Render_opengl::draw_stored_circles(){
         glPopMatrix();
     }
 }
+
+void Render_opengl::update_vertical_line(){
+        if (_mouse_pressed_inside_container)
+            set_vertical_line(0);
+        else
+            set_vertical_line(render_to_trace_x( screen_to_render_x(_mouse_x)));
+        updateGL();
+}
+
+Element_pos Render_opengl::get_vertical_line(){
+	return vertical_line;
+}
+
+void Render_opengl::set_vertical_line(Element_pos new_coord){
+    if(new_coord==vertical_line)vertical_line=0;
+    else vertical_line=new_coord;
+}
+    
+    
+void Render_opengl::draw_vertical_line(){
+  
+    if(vertical_line==0)return;
+    glPushMatrix();
+	{
+		glLineWidth( 1.0 );
+		/* Draw the line */
+		glBegin(GL_LINES);
+		{
+			glColor3d(1.0,0.0,0.0);
+			glVertex2d( trace_to_render_x(vertical_line),0);
+			glVertex2d( trace_to_render_x(vertical_line),Info::Render::height);
+		}
+		glEnd();
+	}
+    glPopMatrix();
+}
     
 // void Render_opengl::create_minimap(const int width, const int height){
 
diff --git a/src/render/Render_opengl.hpp b/src/render/Render_opengl.hpp
index c618342a..85f1745e 100644
--- a/src/render/Render_opengl.hpp
+++ b/src/render/Render_opengl.hpp
@@ -184,6 +184,10 @@ protected:
      */
     int _wait_spf;
 
+	/*!
+	 * \brief Offset of the vertical helper line
+	 */
+	Element_pos vertical_line;
 
 
     /*!
@@ -614,6 +618,30 @@ public:
     void clear_arrow ();
     /*! Function that only delete the text of the screen */
     void clear_text ();
+	
+	
+    /*!
+     * \brief returns the offset of the vertical helper line
+     */
+	Element_pos get_vertical_line();
+		
+    /*!
+     * \brief set the vertical line offset
+     * \param l the line offset.
+     */
+	void set_vertical_line(Element_pos l);
+	
+    /*!
+     * \brief draws the vertical helper line
+     */	
+    void draw_vertical_line();
+    
+        
+    public slots:
+    /*!
+     * \brief slot connected to the simple click event
+    */
+    void update_vertical_line();
 };
 
 
-- 
GitLab