# HG changeset patch
# User Pantxo Diribarne <pantxo.diribarne@gmail.com>
# Date 1546446081 -3600
#      Wed Jan 02 17:21:21 2019 +0100
# Branch stable
# Node ID 7d7fdce0f8d2b7b0c7b96c505d51c1d7e6a472e6
# Parent  69cbbd2711ed21b9d7f0d3234eb822ae68e2341b
Use event queue to pass position changes from teh GUI thread (bug #48519)

* Figure.cc (Figure::updateBoundingBox): Use gh_manager::post_set to trigger
  the figure (outer)position change.

* graphics.h/cc (figure::properties::bbox2position): New public method.
  (figure::properties::set_boundingbox): Make use of bbox2position;
  (set_event::m_redraw_figure): New data member.
  (set_event::set_event, gh_manager::post_set): New signature including
  redraw_figure argument. Change set_event calls accordingly.
  (set_event::execute): For figure position and outerposition properties,
  directly call figure::properties::set_xxx instead of xxx::set. Redraw figure
  if necessary.
  
diff -r 69cbbd2711ed -r 7d7fdce0f8d2 libgui/graphics/Figure.cc
--- a/libgui/graphics/Figure.cc	Wed Jan 02 13:25:01 2019 +0100
+++ b/libgui/graphics/Figure.cc	Wed Jan 02 17:21:21 2019 +0100
@@ -328,10 +328,7 @@
     Canvas *canvas = m_container->canvas (m_handle);
 
     if (canvas)
-      {
-        canvas->redraw ();
-        //canvas->setMouseMode (RotateMode);
-      }
+      canvas->redraw ();
 
     foreach (QFrame *frame,
              qWidget<QWidget> ()->findChildren<QFrame*> ())
@@ -621,9 +618,11 @@
   {
     QWidget *win = qWidget<QWidget> ();
     Matrix bb (1, 4);
+    std::string prop;
 
     if (internal)
       {
+        prop = "position";
         QRect r = m_innerRect;
 
         if (flags & UpdateBoundingBoxPosition)
@@ -645,6 +644,7 @@
       }
     else
       {
+        prop = "outerposition";
         QRect r = m_outerRect;
 
         if (flags & UpdateBoundingBoxPosition)
@@ -665,14 +665,9 @@
           return;
       }
 
-    UpdateBoundingBoxData *d = new UpdateBoundingBoxData ();
-
-    d->m_bbox = bb;
-    d->m_internal = internal;
-    d->m_handle = m_handle;
-    d->m_figure = this;
-
-    gh_manager::post_function (Figure::updateBoundingBoxHelper, d);
+    figure::properties& fp = properties<figure> ();
+    
+    gh_manager::post_set (m_handle, prop, fp.bbox2position (bb), false, true);
   }
 
   void
diff -r 69cbbd2711ed -r 7d7fdce0f8d2 libinterp/corefcn/graphics.cc
--- a/libinterp/corefcn/graphics.cc	Wed Jan 02 13:25:01 2019 +0100
+++ b/libinterp/corefcn/graphics.cc	Wed Jan 02 17:21:21 2019 +0100
@@ -4087,9 +4087,8 @@
   return pos;
 }
 
-void
-figure::properties::set_boundingbox (const Matrix& bb, bool internal,
-                                     bool do_notify_toolkit)
+Matrix
+figure::properties::bbox2position (const Matrix& bb) const
 {
   Matrix screen_size = screen_size_pixels ();
   Matrix pos = bb;
@@ -4098,6 +4097,15 @@
   pos(1)++;
   pos(0)++;
   pos = convert_position (pos, "pixels", get_units (), screen_size);
+  return pos;
+}
+
+void
+figure::properties::set_boundingbox (const Matrix& bb, bool internal,
+                                     bool do_notify_toolkit)
+{
+  Matrix screen_size = screen_size_pixels ();
+  Matrix pos = bbox2position (bb);
 
   if (internal)
     set_position (pos, do_notify_toolkit);
@@ -11403,9 +11411,12 @@
 {
 public:
   set_event (const graphics_handle& h, const std::string& name,
-             const octave_value& value, bool do_notify_toolkit = true)
+             const octave_value& value, bool do_notify_toolkit = true,
+             bool redraw_figure = false)
     : base_graphics_event (), handle (h), property_name (name),
-      property_value (value), notify_toolkit (do_notify_toolkit) { }
+      property_value (value), notify_toolkit (do_notify_toolkit),
+      m_redraw_figure (redraw_figure)
+  { }
 
   void execute (void)
   {
@@ -11418,10 +11429,41 @@
         property p = go.get_properties ().get_property (property_name);
 
         if (p.ok ())
-          p.set (property_value, true, notify_toolkit);
+          {
+            // FIXME: There is no way to call the actual
+            // base_properties::set_prop without notifying the toolkit, hence
+            // the psecial case here.
+            if (go.isa ("figure") && property_name == "position")
+              {
+                figure::properties& fprops
+                  = dynamic_cast<figure::properties&> (go.get_properties ());
+                fprops.set_position (property_value, notify_toolkit);
+              }
+            else if (go.isa ("figure") && property_name == "outerposition")
+              {
+                figure::properties& fprops
+                  = dynamic_cast<figure::properties&> (go.get_properties ());
+                fprops.set_outerposition (property_value, notify_toolkit);
+              }
+            else
+              p.set (property_value, true, notify_toolkit);
+
+            if (m_redraw_figure)
+              {
+                if (! go.isa ("figure"))
+                  go = go.get_ancestor ("figure");
+
+                if (go.valid_object ())
+                  {
+                    figure::properties& fprops
+                      = dynamic_cast<figure::properties&> (go.get_properties ());
+                    fprops.get_toolkit ().redraw_figure (go);
+                  }
+              }
+          }
       }
   }
-
+    
 private:
   set_event (void)
     : base_graphics_event (), handle (), property_name (), property_value ()
@@ -11432,6 +11474,7 @@
   std::string property_name;
   octave_value property_value;
   bool notify_toolkit;
+  bool m_redraw_figure;
 };
 
 graphics_event
@@ -11463,9 +11506,10 @@
 graphics_event::create_set_event (const graphics_handle& h,
                                   const std::string& name,
                                   const octave_value& data,
-                                  bool notify_toolkit)
-{
-  return graphics_event (new set_event (h, name, data, notify_toolkit));
+                                  bool notify_toolkit, bool redraw_figure)
+{
+  return graphics_event (new set_event (h, name, data, notify_toolkit,
+                                        redraw_figure));
 }
 
 static void
@@ -11660,12 +11704,14 @@
 
 void
 gh_manager::do_post_set (const graphics_handle& h, const std::string& name,
-                         const octave_value& value, bool notify_toolkit)
+                         const octave_value& value, bool notify_toolkit,
+                         bool redraw_figure)
 {
   gh_manager::auto_lock guard;
 
   do_post_event (graphics_event::create_set_event (h, name, value,
-                                                   notify_toolkit));
+                                                   notify_toolkit,
+                                                   redraw_figure));
 }
 
 int
diff -r 69cbbd2711ed -r 7d7fdce0f8d2 libinterp/corefcn/graphics.in.h
--- a/libinterp/corefcn/graphics.in.h	Wed Jan 02 13:25:01 2019 +0100
+++ b/libinterp/corefcn/graphics.in.h	Wed Jan 02 17:21:21 2019 +0100
@@ -3092,6 +3092,8 @@
     void set_outerposition (const octave_value& val,
                             bool do_notify_toolkit = true);
 
+    Matrix bbox2position (const Matrix& bbox) const;
+
     Matrix get_boundingbox (bool internal = false,
                             const Matrix& parent_pix_size = Matrix ()) const;
 
@@ -6162,8 +6164,8 @@
 
   static graphics_event
   create_set_event (const graphics_handle& h, const std::string& name,
-                    const octave_value& value,
-                    bool notify_toolkit = true);
+                    const octave_value& value, bool notify_toolkit = true,
+                    bool redraw_figure = false);
 private:
 
   std::shared_ptr <base_graphics_event> rep;
@@ -6356,10 +6358,11 @@
   }
 
   static void post_set (const graphics_handle& h, const std::string& name,
-                        const octave_value& value, bool notify_toolkit = true)
+                        const octave_value& value, bool notify_toolkit = true,
+                        bool redraw_figure = false)
   {
     if (instance_ok ())
-      instance->do_post_set (h, name, value, notify_toolkit);
+      instance->do_post_set (h, name, value, notify_toolkit, redraw_figure);
   }
 
   static int process_events (void)
@@ -6551,7 +6554,8 @@
   void do_post_function (graphics_event::event_fcn fcn, void *fcn_data);
 
   void do_post_set (const graphics_handle& h, const std::string& name,
-                    const octave_value& value, bool notify_toolkit = true);
+                    const octave_value& value, bool notify_toolkit = true,
+                    bool redraw_figure = false);
 
   int do_process_events (bool force = false);
 
