changeset 20305:062422f2e399

Show axes coordinates in Qt figures (bug #44959) * Canvas.h: new private bool member m_updtaCurrentPoint, to decide wether update the figure "currentpoint" property * Canvas.h (Canvas::enableCurrentPointUpdates): new method to set m_updtaCurrentPoint * Canvas.cc (Canvas::canvasMousePressEvent): move the code for axes/object selection in a dedicated method and call this method (select_object) instead. * Canvas.cc (Canvas::select_object): new method for axes/object selection. * Canvas.cc (Canvas::canvasMouseMoveEvent): update the parent figure status bar with the hovered axes coordinates * Figure.h: declare new method updateStatusBar * Figure.h: declare new private QStatusBar member m_statusBar. Include QStatusBar.h * Figure.cc (Figure::Figure): unconditionally enable mouse traching * Figure.cc (Figure::Figure): add status below of the canvas * Figure.cc (Figure::update): take status bar into account when updating the figure position * Figure.cc (Figure::update): remove some of the leftover debug comments * Figure.cc: define new method updateStatusBar
author Pantxo Diribarne <pantxo.diribarne@gmail.com>
date Sat, 13 Jun 2015 13:27:01 +0200
parents ce8fda51d236
children ae68b331d6e4
files libgui/graphics/Canvas.cc libgui/graphics/Canvas.h libgui/graphics/Figure.cc libgui/graphics/Figure.h
diffstat 4 files changed, 130 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/graphics/Canvas.cc	Sat Jun 20 16:00:50 2015 -0700
+++ b/libgui/graphics/Canvas.cc	Sat Jun 13 13:27:01 2015 +0200
@@ -395,6 +395,63 @@
   return zm.contents ("Direction").string_value ();
 }
 
+void 
+Canvas::select_object (graphics_object obj, QMouseEvent* event, 
+                       graphics_object &currentObj, graphics_object &axesObj)
+{
+  QList<graphics_object> axesList;
+  Matrix children = obj.get_properties ().get_all_children ();
+  octave_idx_type num_children = children.numel ();
+
+  for (int i = 0; i < num_children; i++)
+    {
+      graphics_object childObj (gh_manager::get_object (children(i)));
+
+      if (childObj.isa ("axes"))
+        axesList.append (childObj);
+      else if (childObj.isa ("uicontrol") || childObj.isa ("uipanel"))
+        {
+          Matrix bb = childObj.get_properties ().get_boundingbox (false);
+          QRectF r (bb(0), bb(1), bb(2), bb(3));
+
+          r.adjust (-5, -5, 5, 5);
+          if (r.contains (event->posF ()))
+            {
+              currentObj = childObj;
+              break;
+            }
+        }
+    }
+
+  if (! currentObj)
+    {
+      for (QList<graphics_object>::ConstIterator it = axesList.begin ();
+           it != axesList.end (); ++it)
+        {
+          graphics_object go = selectFromAxes (*it, event->pos ());
+
+          if (go)
+            {
+              currentObj = go;
+              axesObj = *it;
+            }
+          // FIXME: is this really necessary? the axes object should
+          //        have been selected through selectFromAxes anyway
+          else if (it->get_properties ().is_hittest ())
+            {
+              Matrix bb = it->get_properties ().get_boundingbox (true);
+              QRectF r (bb(0), bb(1), bb(2), bb(3));
+
+              if (r.contains (event->posF ()))
+                axesObj = *it;
+            }
+
+          if (axesObj && currentObj)
+            break;
+        }
+    }
+}
+
 void
 Canvas::canvasMouseMoveEvent (QMouseEvent* event)
 {
@@ -452,7 +509,7 @@
           break;
         }
     }
-  else if (m_mouseMode == NoMode)
+  else if (m_mouseMode == NoMode && m_updateCurrentPoint)
     {
       graphics_object obj = gh_manager::get_object (m_handle);
 
@@ -465,6 +522,23 @@
                                      "windowbuttonmotionfcn");
         }
     }
+
+  // Update mouse coordinates in the figure window status bar 
+  graphics_object obj = gh_manager::get_object (m_handle);
+
+  if (obj.valid_object ())
+    {
+      graphics_object currentObj, axesObj;
+      select_object (obj, event, currentObj, axesObj);
+
+      if (axesObj.valid_object ())
+        {
+          Figure* fig = 
+            dynamic_cast<Figure*> (Backend::toolkitObject (obj));
+          axes::properties& ap = Utils::properties<axes> (axesObj);
+          fig->updateStatusBar (ap.pixel2coord (event->x (), event->y ()));
+        }
+    }    
 }
 
 void
@@ -512,66 +586,16 @@
     {
       graphics_object figObj (obj.get_ancestor ("figure"));
       graphics_object currentObj, axesObj;
-      QList<graphics_object> axesList;
-
-      Matrix children = obj.get_properties ().get_all_children ();
-      octave_idx_type num_children = children.numel ();
-
-      for (int i = 0; i < num_children; i++)
-        {
-          graphics_object childObj (gh_manager::get_object (children(i)));
+      
+      select_object (obj, event, currentObj, axesObj);
 
-          if (childObj.isa ("axes"))
-            axesList.append (childObj);
-          else if (childObj.isa ("uicontrol") || childObj.isa ("uipanel"))
-            {
-              Matrix bb = childObj.get_properties ().get_boundingbox (false);
-              QRectF r (bb(0), bb(1), bb(2), bb(3));
-
-              r.adjust (-5, -5, 5, 5);
-              if (r.contains (event->posF ()))
-                {
-                  currentObj = childObj;
-                  break;
-                }
-            }
-        }
-
-      if (! currentObj)
+      if (axesObj)
         {
-          for (QList<graphics_object>::ConstIterator it = axesList.begin ();
-               it != axesList.end (); ++it)
-            {
-              graphics_object go = selectFromAxes (*it, event->pos ());
-
-              if (go)
-                {
-                  currentObj = go;
-                  axesObj = *it;
-                }
-              // FIXME: is this really necessary? the axes object should
-              //        have been selected through selectFromAxes anyway
-              else if (it->get_properties ().is_hittest ())
-                {
-                  Matrix bb = it->get_properties ().get_boundingbox (true);
-                  QRectF r (bb(0), bb(1), bb(2), bb(3));
-
-                  if (r.contains (event->posF ()))
-                    axesObj = *it;
-                }
-
-              if (axesObj && currentObj)
-                break;
-            }
-
-          if (axesObj)
-            {
-              if (axesObj.get_properties ().handlevisibility_is ("on"))
-                Utils::properties<figure> (figObj)
-                  .set_currentaxes (axesObj.get_handle ().as_octave_value ());
-              if (! currentObj)
-                currentObj = axesObj;
-            }
+          if (axesObj.get_properties ().handlevisibility_is ("on"))
+            Utils::properties<figure> (figObj)
+              .set_currentaxes (axesObj.get_handle ().as_octave_value ());
+          if (! currentObj)
+            currentObj = axesObj;
         }
 
       if (! currentObj)
--- a/libgui/graphics/Canvas.h	Sat Jun 20 16:00:50 2015 -0700
+++ b/libgui/graphics/Canvas.h	Sat Jun 13 13:27:01 2015 +0200
@@ -70,6 +70,7 @@
   virtual void toggleAxes (const graphics_handle& handle) = 0;
   virtual void toggleGrid (const graphics_handle& handle) = 0;
   virtual void autoAxes (const graphics_handle& handle) = 0;
+  void enableCurrentPointUpdates (bool on) { m_updateCurrentPoint = on; }
 
 protected:
   virtual void draw (const graphics_handle& handle) = 0;
@@ -85,7 +86,8 @@
       m_mouseMode (NoMode),
       m_clickMode (false),
       m_eventMask (0),
-      m_rectMode (false)
+      m_rectMode (false),
+      m_updateCurrentPoint (false)
     { }
 
   void canvasToggleAxes (const graphics_handle& handle);
@@ -106,6 +108,8 @@
                            const graphics_object& obj);
 
   void annotation_callback (const octave_value_list& args);
+  void select_object (graphics_object obj, QMouseEvent* event, 
+                      graphics_object &currentObj, graphics_object &axesObj);
 
 private:
   graphics_handle m_handle;
@@ -117,6 +121,7 @@
   graphics_handle m_mouseAxes;
   int m_eventMask;
   bool m_rectMode;
+  bool m_updateCurrentPoint;
 };
 
 }; // namespace QtHandles
--- a/libgui/graphics/Figure.cc	Sat Jun 20 16:00:50 2015 -0700
+++ b/libgui/graphics/Figure.cc	Sat Jun 13 13:27:01 2015 +0200
@@ -129,20 +129,32 @@
 {
   m_container = new Container (win);
   win->setCentralWidget (m_container);
-
+  
   figure::properties& fp = properties<figure> ();
 
-  createFigureToolBarAndMenuBar ();
+  // Enable mouse tracking
+  m_container->setMouseTracking (true);
+  foreach (QWidget* w, m_container->findChildren<QWidget*> ())
+    { w->setMouseTracking (true); }
+  
+  // Status bar
+  m_statusBar = win->statusBar ();
+  m_statusBar->setVisible (true);
+  int boffset = m_statusBar->sizeHint ().height ();
+  
 
-  int offset = 0;
+  // Toolbar and menubar
+  createFigureToolBarAndMenuBar ();
+  int toffset = 0;
+
   if (fp.toolbar_is ("figure") ||
       (fp.toolbar_is ("auto") && fp.menubar_is ("figure") &&
        ! hasUiControlChildren (fp)))
-    offset += m_figureToolBar->sizeHint ().height ();
+    toffset += m_figureToolBar->sizeHint ().height ();
   else
     m_figureToolBar->hide ();
   if (fp.menubar_is ("figure") || hasUiMenuChildren (fp))
-    offset += m_menuBar->sizeHint ().height () + 1;
+    toffset += m_menuBar->sizeHint ().height () + 1;
   else
     m_menuBar->hide ();
 
@@ -150,7 +162,7 @@
   m_outerRect = boundingBoxToRect (fp.get_boundingbox (false));
 
   //qDebug () << "Figure::Figure:" << m_innerRect;
-  win->setGeometry (m_innerRect.adjusted (0, -offset, 0, 0));
+  win->setGeometry (m_innerRect.adjusted (0, -toffset, 0, boffset));
   //qDebug () << "Figure::Figure(adjusted)" << m_innerRect.adjusted (0, -offset, 0, 0);
   win->setWindowTitle (Utils::fromStdString (fp.get_title ()));
 
@@ -411,17 +423,20 @@
     case figure::properties::ID_POSITION:
         {
           m_innerRect = boundingBoxToRect (fp.get_boundingbox (true));
-          //qDebug () << "Figure::update(position):" << m_innerRect;
-          int offset = 0;
+          int toffset = 0;
+          int boffset = 0;
 
           foreach (QToolBar* tb, win->findChildren<QToolBar*> ())
             if (! tb->isHidden ())
-              offset += tb->sizeHint ().height ();
+              toffset += tb->sizeHint ().height ();
+
           if (! m_menuBar->isHidden ())
-            offset += m_menuBar->sizeHint ().height () + 1;
-          //qDebug () << "Figure::update(position)(adjusted):" << m_innerRect.adjusted (0, -offset, 0, 0);
-          win->setGeometry (m_innerRect.adjusted (0, -offset, 0, 0));
-          //qDebug () << "Figure::update(position): done";
+            toffset += m_menuBar->sizeHint ().height () + 1;
+          
+          if (! m_statusBar->isHidden ())
+            boffset += m_statusBar->sizeHint ().height () + 1;
+
+          win->setGeometry (m_innerRect.adjusted (0, -toffset, 0, boffset));
         }
       break;
 
@@ -471,9 +486,7 @@
         {
           bool hasCallback = ! fp.get_windowbuttonmotionfcn ().is_empty ();
 
-          m_container->setMouseTracking (hasCallback);
-          foreach (QWidget* w, m_container->findChildren<QWidget*> ())
-            { w->setMouseTracking (hasCallback); }
+          m_container->canvas (m_handle)->enableCurrentPointUpdates (hasCallback);
         }
       break;
 
@@ -551,6 +564,15 @@
     showMenuBar (Utils::properties<figure> (go).menubar_is ("figure"));
 }
 
+void
+Figure::updateStatusBar (ColumnVector pt)
+{
+  if (! m_statusBar->isHidden ())
+    m_statusBar->showMessage (QString ("(%1, %2)")
+                              .arg (pt(0), 0, 'g', 5)
+                              .arg (pt(1), 0, 'g', 5));
+}
+
 QWidget*
 Figure::menu (void)
 {
--- a/libgui/graphics/Figure.h	Sat Jun 20 16:00:50 2015 -0700
+++ b/libgui/graphics/Figure.h	Sat Jun 13 13:27:01 2015 +0200
@@ -24,6 +24,7 @@
 #define __QtHandles_Figure__ 1
 
 #include <QRect>
+#include <QStatusBar>
 
 #include "GenericEventNotify.h"
 #include "MenuContainer.h"
@@ -78,6 +79,7 @@
 
   Container* innerContainer (void);
   QWidget* menu (void);
+  void updateStatusBar (ColumnVector pt);
 
   bool eventNotifyBefore (QObject* watched, QEvent* event);
   void eventNotifyAfter (QObject* watched, QEvent* event);
@@ -132,6 +134,7 @@
   bool m_blockUpdates;
   QToolBar* m_figureToolBar;
   MenuBar* m_menuBar;
+  QStatusBar* m_statusBar;
   QRect m_innerRect;
   QRect m_outerRect;
   MouseModeActionGroup* m_mouseModeGroup;