# HG changeset patch
# User Pantxo Diribarne <pantxo.diribarne@gmail.com>
# Date 1586981837 -7200
#      Wed Apr 15 22:17:17 2020 +0200
# Branch stable
# Node ID ec263cbbf93d6500b065413b3b4e8d18041214bc
# Parent  6cccc3c821759a9ea9b757ef53be6a381f4a2d82
getpixelposition.m: Implement new function (bug #58181)

* graphics.cc (F__get_position__): New builtin function.

* scripts/gui/getpixelposition.m: new function.

* scripts/gui/module.mk: Add new function to build system.

* gui.txi: Add doc string to the manual.


diff -r 6cccc3c82175 -r ec263cbbf93d doc/interpreter/gui.txi
--- a/doc/interpreter/gui.txi	Tue Apr 14 22:53:19 2020 -0400
+++ b/doc/interpreter/gui.txi	Wed Apr 15 22:17:17 2020 +0200
@@ -141,6 +141,8 @@
 
 @DOCSTRING(isguirunning)
 
+@DOCSTRING(getpixelposition)
+
 @DOCSTRING(movegui)
 
 @DOCSTRING(openvar)
diff -r 6cccc3c82175 -r ec263cbbf93d libinterp/corefcn/graphics.cc
--- a/libinterp/corefcn/graphics.cc	Tue Apr 14 22:53:19 2020 -0400
+++ b/libinterp/corefcn/graphics.cc	Wed Apr 15 22:17:17 2020 +0200
@@ -14526,6 +14526,38 @@
   return ovl (go.get_toolkit ().get_pixels (go));
 }
 
+DEFMETHOD (__get_position__, interp, args, ,
+           doc: /* -*- texinfo -*-
+@deftypefn {} {@var{pos} =} __get_position__ (@var{h}, @var{units})
+Internal function.
+@end deftypefn */)
+{
+  if (args.length () != 2)
+    print_usage ();
+
+  double h = args(0).xdouble_value ("__get_position__: H is not a handle");
+
+  std::string units
+    = args(1).xstring_value ("__get_position__: UNITS is not a string");
+
+  gh_manager& gh_mgr = interp.get_gh_manager ();
+
+  graphics_object go = gh_mgr.get_object (h);
+
+  if (h == 0 || ! go)
+    error ("__get_position__: H is not a handle to a valid graphics object");
+  
+  graphics_object parent_go = gh_mgr.get_object (go.get_parent ());
+  Matrix bbox = parent_go.get_properties ().get_boundingbox (true)
+    .extract_n (0, 2, 1, 2);
+      
+  Matrix pos = convert_position (go.get ("position").matrix_value (),
+                                 go.get ("units").string_value (),
+                                 units, bbox);
+
+  return ovl (pos);
+}
+
 DEFUN (__get_system_fonts__, args, ,
        doc: /* -*- texinfo -*-
 @deftypefn {} {@var{font_struct} =} __get_system_fonts__ ()
diff -r 6cccc3c82175 -r ec263cbbf93d scripts/gui/getpixelposition.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/gui/getpixelposition.m	Wed Apr 15 22:17:17 2020 +0200
@@ -0,0 +1,82 @@
+########################################################################
+##
+## Copyright (C) 2020 The Octave Project Developers
+##
+## See the file COPYRIGHT.md in the top-level directory of this
+## distribution or <https://octave.org/copyright/>.
+##
+## This file is part of Octave.
+##
+## Octave is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <https://www.gnu.org/licenses/>.
+##
+########################################################################
+
+## -*- texinfo -*-
+## @deftypefn {} {@var{pos} =} getpixelposition (@var{h})
+## @deftypefnx {} {@var{pos} =} getpixelposition (@var{h}, @var{recursive})
+## Return the position of a graphics object in pixel units.
+##
+## 
+## @seealso{get}
+## @end deftypefn
+
+function pos = getpixelposition (h, recursive = false)
+
+  if (nargin < 1 || nargin > 2 || ! isscalar (h) || ! ishghandle (h))
+    print_usage ();
+  endif
+
+  if (h == groot ())
+    pos = zeros (1, 4);
+    return;
+  endif
+
+  pos = __get_position__ (h, "pixels");
+  
+  if (recursive && ! isfigure (h))
+    do
+      h = get (h, "parent");
+      pos(1:2) += __get_position__ (h, "pixels")(1:2);
+    until (isfigure (h))
+  endif
+  
+endfunction
+
+
+%!test
+%! pos = [0 0 400 400];
+%! hf = figure ("visible", "off", "menubar", "none", "position", pos);
+%! unwind_protect
+%!   hp = uipanel (hf, "position", [0.5 0.5 0.5 0.5]);
+%!   hax = axes (hp, "position", [0.5 0.5 0.5 0.5]);
+%!   assert (getpixelposition (hax), [100 100 100 100], 2);
+%!   assert (getpixelposition (hax, true), [300 300 100 100], 2);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+%!test
+%! ## Compatibility: return zeros for root figure
+%! assert (getpixelposition (groot), zeros (1, 4));
+
+%!test
+%! ## Compatibility: return the same for figures whether recursion is requested
+%! ## or not
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   assert (getpixelposition (hf), getpixelposition (hf, true));
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
diff -r 6cccc3c82175 -r ec263cbbf93d scripts/gui/module.mk
--- a/scripts/gui/module.mk	Tue Apr 14 22:53:19 2020 -0400
+++ b/scripts/gui/module.mk	Wed Apr 15 22:17:17 2020 +0200
@@ -17,6 +17,7 @@
   %reldir%/dialog.m \
   %reldir%/errordlg.m \
   %reldir%/getappdata.m \
+  %reldir%/getpixelposition.m \
   %reldir%/guidata.m \
   %reldir%/guihandles.m \
   %reldir%/helpdlg.m \
