GNU Octave  8.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
Figure.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2011-2023 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <QAction>
31 #include <QActionEvent>
32 #include <QApplication>
33 #include <QClipboard>
34 #include <QEvent>
35 #include <QFileDialog>
36 #include <QFileInfo>
37 #include <QFrame>
38 #include <QImage>
39 #include <QMainWindow>
40 #include <QMenu>
41 #include <QMenuBar>
42 #include <QMessageBox>
43 #include <QtDebug>
44 #include <QTimer>
45 #include <QToolBar>
46 #if defined (HAVE_QSCREEN_DEVICEPIXELRATIO)
47 # include <QWindow>
48 # include <QScreen>
49 #endif
50 
51 #include "Canvas.h"
52 #include "Container.h"
53 #include "Figure.h"
54 #include "FigureWindow.h"
55 #include "QtHandlesUtils.h"
56 
57 #include "gui-preferences-global.h"
58 #include "qt-interpreter-events.h"
59 
60 #include "file-ops.h"
61 #include "unwind-prot.h"
62 #include "utils.h"
63 #include "version.h"
64 
65 #include "builtin-defun-decls.h"
66 #include "interpreter.h"
67 
69 
71 
72 static QRect
74 {
75  QRect r;
76 
77  if (bb.numel () == 4)
78  {
79  r = QRect (octave::math::round (bb(0)), octave::math::round (bb(1)),
80  octave::math::round (bb(2)), octave::math::round (bb(3)));
81  if (! r.isValid ())
82  r = QRect ();
83  }
84 
85  return r;
86 }
87 
88 static QImage
89 pointer_to_qimage (const Matrix& cdata)
90 {
91  QImage retval (cdata.rows (), cdata.columns (), QImage::Format_ARGB32);
92  QColor tmp ("White");
93  QColor black ("Black");
94  QColor white ("White");
95  for (octave_idx_type ii = 0; ii < cdata.rows (); ii++)
96  for (octave_idx_type jj = 0; jj < cdata.columns (); jj++)
97  {
98  if (cdata(ii, jj) == 1.0)
99  tmp = black;
100  else if (cdata(ii, jj) == 2.0)
101  tmp = white;
102  else
103  tmp.setAlpha (0);
104 
105  retval.setPixel (jj, ii, tmp.rgba ());
106  }
107 
108  return retval;
109 }
110 
111 Figure *
112 Figure::create (octave::base_qobject& oct_qobj, octave::interpreter& interp,
113  const graphics_object& go)
114 {
115  return new Figure (oct_qobj, interp, go, new FigureWindow ());
116 }
117 
118 Figure::Figure (octave::base_qobject& oct_qobj, octave::interpreter& interp,
119  const graphics_object& go, FigureWindow *win)
120  : Object (oct_qobj, interp, go, win), m_blockUpdates (false),
121  m_figureToolBar (nullptr), m_menuBar (nullptr), m_innerRect (),
122  m_outerRect (), m_previousHeight (0), m_resizable (true)
123 {
124  m_container = new Container (win, oct_qobj, interp);
125  win->setCentralWidget (m_container);
126 
129 
132 
133  figure::properties& fp = properties<figure> ();
134 
135  // Adjust figure position
136  m_innerRect = boundingBoxToRect (fp.get_boundingbox (true));
137  m_outerRect = boundingBoxToRect (fp.get_boundingbox (false));
138 
140 
141  // Menubar
142  m_menuBar = new MenuBar (win);
143  win->setMenuBar (m_menuBar);
144  m_menuBar->addReceiver (this);
145  m_menuBar->setStyleSheet (m_menuBar->styleSheet () + global_menubar_style);
146 
147  // Status bar
148  m_statusBar = win->statusBar ();
149  m_statusBar->setVisible (false);
150 
151  if (fp.toolbar_is ("figure")
152  || (fp.toolbar_is ("auto") && fp.menubar_is ("figure")))
153  showFigureStatusBar (true);
154 
155  // Enable mouse tracking unconditionally
157 
158  // When this constructor gets called all properties are already
159  // set, even non default. We force "update" here to get things right.
160 
161  // Figure title
162  update (figure::properties::ID_NUMBERTITLE);
163 
164  // Decide what keyboard events we listen to
166  update (figure::properties::ID_KEYPRESSFCN);
167  update (figure::properties::ID_KEYRELEASEFCN);
168 
169  // modal style
170  update (figure::properties::ID_WINDOWSTYLE);
171 
172  // Handle resizing constraints
173  update (figure::properties::ID_RESIZE);
174 
175  // Custom pointer data
176  update (figure::properties::ID_POINTERSHAPECDATA);
177 
178  // Visibility
179  update (figure::properties::ID_VISIBLE);
180 
181  connect (this, &Figure::asyncUpdate, this, &Figure::updateContainer);
182 
183  // Register for the signal that indicates when a window has moved
184  // to a different screen
185  connect (win, &FigureWindow::figureWindowShown,
187 
188  win->addReceiver (this);
189  m_container->addReceiver (this);
190 }
191 
193 { }
194 
195 QString
197 {
198  gh_manager& gh_mgr = m_interpreter.get_gh_manager ();
199 
200  octave::autolock guard (gh_mgr.graphics_lock ());
201 
202  const figure::properties& fp = properties<figure> ();
203 
204  std::string name = fp.get_filename ();
205 
206  return QString::fromStdString (name);
207 }
208 
209 void
210 Figure::setFileName (const QString& name)
211 {
212  gh_manager& gh_mgr = m_interpreter.get_gh_manager ();
213 
214  octave::autolock guard (gh_mgr.graphics_lock ());
215 
216  figure::properties& fp = properties<figure> ();
217 
218  fp.set_filename (name.toStdString ());
219 }
220 
221 MouseMode
223 {
224  gh_manager& gh_mgr = m_interpreter.get_gh_manager ();
225 
226  octave::autolock guard (gh_mgr.graphics_lock ());
227 
228  const figure::properties& fp = properties<figure> ();
229 
230  std::string mode = fp.get___mouse_mode__ ();
231 
232  if (mode == "zoom")
233  {
234  octave_scalar_map zm = fp.get___zoom_mode__ ().scalar_map_value ();
235 
236  std::string direction = zm.getfield ("Direction").string_value ();
237 
238  mode += ' ' + direction;
239  }
240 
241  if (mode == "rotate")
242  return RotateMode;
243  else if (mode == "zoom in")
244  return ZoomInMode;
245  else if (mode == "zoom out")
246  return ZoomOutMode;
247  else if (mode == "pan")
248  return PanMode;
249  else if (mode == "text")
250  return TextMode;
251 
252  return NoMode;
253 }
254 
255 void
257 {
258  QMainWindow *win = qWidget<QMainWindow> ();
259 
260  if (! m_resizable)
261  {
262  win->setSizePolicy (QSizePolicy::Preferred, QSizePolicy::Preferred);
263  win->setFixedSize (QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
264  }
265 
266  // Unlock window if it is maximized or full-screen
267  int state = win->windowState ();
268  if (state == Qt::WindowFullScreen || state == Qt::WindowMaximized)
269  win->setWindowState (Qt::WindowNoState);
270 
271  win->setGeometry (r);
272 
273  if (! m_resizable)
274  {
275  win->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
276  win->setFixedSize(win->size ());
277  }
278 }
279 
280 Container *
282 {
283  return m_container;
284 }
285 
286 void
288 {
289  Canvas *canvas = m_container->canvas (m_handle);
290 
291  if (canvas)
292  canvas->redraw ();
293 
294  for (auto *qobj : qWidget<QWidget> ()->findChildren<QObject *> ())
295  {
296  if (qobj->objectName () == "UIPanel"
297  || qobj->objectName () == "UIButtonGroup"
298  || qobj->objectName () == "UIControl"
299  || qobj->objectName () == "UITable")
300  {
301  Object *obj = Object::fromQObject (qobj);
302 
303  if (obj)
304  obj->slotRedraw ();
305  }
306  }
307 }
308 
309 void
311 {
312  QWidget *win = qWidget<QWidget> ();
313 
314  win->activateWindow ();
315  win->raise ();
316 }
317 
318 void
319 Figure::print (const QString& file_cmd, const QString& term)
320 {
321  Canvas *canvas = m_container->canvas (m_handle);
322 
323  if (canvas)
324  canvas->print (file_cmd, term);
325 }
326 
329 {
330  uint8NDArray retval;
331  Canvas *canvas = m_container->canvas (m_handle);
332 
333  if (canvas)
334  {
335  gh_manager& gh_mgr = m_interpreter.get_gh_manager ();
336 
337  gh_mgr.process_events ();
338  octave::autolock guard (gh_mgr.graphics_lock ());
339  retval = canvas->getPixels ();
340  }
341 
342  return retval;
343 }
344 
345 void
347 {
348  Canvas *canvas = m_container->canvas (m_handle.value (), false);
349 
350  if (canvas)
351  canvas->blockRedraw (true);
352 
353  m_container->removeReceiver (this);
354  qWidget<FigureWindow> ()->removeReceiver (this);
355 }
356 
357 void
358 Figure::update (int pId)
359 {
360  if (m_blockUpdates)
361  return;
362 
363  figure::properties& fp = properties<figure> ();
364 
365  if (fp.is___printing__ ())
366  return;
367 
368  QMainWindow *win = qWidget<QMainWindow> ();
369 
370  // If the window doesn't exist, there's nothing we can do.
371  if (! win)
372  return;
373 
374  m_blockUpdates = true;
375 
376  switch (pId)
377  {
378  case figure::properties::ID_POSITION:
379  {
380  m_innerRect = boundingBoxToRect (fp.get_boundingbox (true));
381  int toffset = 0;
382  int boffset = 0;
383 
384  for (auto *tb : win->findChildren<QToolBar *> ())
385  if (! tb->isHidden ())
386  toffset += tb->sizeHint ().height ();
387 
388  if (! m_menuBar->isHidden ())
389  toffset += m_menuBar->sizeHint ().height ();
390 
391  if (! m_statusBar->isHidden ())
392  boffset += m_statusBar->sizeHint ().height ();
393 
394  set_geometry (m_innerRect.adjusted (0, -toffset, 0, boffset));
395  }
396  break;
397 
398  case figure::properties::ID_NAME:
399  case figure::properties::ID_NUMBERTITLE:
400  win->setWindowTitle (Utils::fromStdString (fp.get_title ()));
401  break;
402 
403  case figure::properties::ID_VISIBLE:
404  if (fp.is_visible ())
405  {
406  QTimer::singleShot (0, win, &QMainWindow::show);
407  if (! fp.is___gl_window__ ())
408  {
409  gh_manager& gh_mgr = m_interpreter.get_gh_manager ();
410 
411  octave::autolock guard (gh_mgr.graphics_lock ());
412  fp.set ("__gl_window__", "on");
413  }
414  }
415  else
416  win->hide ();
417  break;
418 
419  case figure::properties::ID_RESIZE:
420  if (fp.is_resize ())
421  {
422  win->setSizePolicy (QSizePolicy::Preferred, QSizePolicy::Preferred);
423  win->setFixedSize (QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
424  m_resizable = true;
425  }
426  else
427  {
428  win->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
429  win->setFixedSize(win->size ());
430  m_resizable = false;
431  }
432  break;
433 
434  case figure::properties::ID_MENUBAR:
435  case figure::properties::ID_TOOLBAR:
436  if (fp.toolbar_is ("none"))
437  showFigureStatusBar (false);
438  else if (fp.toolbar_is ("figure"))
439  showFigureStatusBar (true);
440  else // "auto"
441  showFigureStatusBar (fp.menubar_is ("figure"));
442  break;
443 
444  case figure::properties::ID_KEYPRESSFCN:
445  if (fp.get_keypressfcn ().isempty ())
447  else
449  // Signal the change to uipanels as well
450  for (auto *qobj : qWidget<QWidget> ()->findChildren<QObject *> ())
451  {
452  if (qobj->objectName () == "UIPanel")
453  {
454  Object *obj = Object::fromQObject (qobj);
455 
456  if (obj)
457  {
458  if (fp.get_keypressfcn ().isempty ())
459  obj->innerContainer ()->canvas (m_handle)->
460  clearEventMask (Canvas::KeyPress);
461  else
462  obj->innerContainer ()->canvas (m_handle)->
463  addEventMask (Canvas::KeyPress);
464  }
465  }
466  }
467  break;
468 
469  case figure::properties::ID_KEYRELEASEFCN:
470  if (fp.get_keyreleasefcn ().isempty ())
472  else
474  break;
475  // Signal the change to uipanels as well
476  for (auto *qobj : qWidget<QWidget> ()->findChildren<QObject *> ())
477  {
478  if (qobj->objectName () == "UIPanel")
479  {
480  Object *obj = Object::fromQObject (qobj);
481 
482  if (obj)
483  {
484  if (fp.get_keypressfcn ().isempty ())
485  obj->innerContainer ()->canvas (m_handle)->
486  clearEventMask (Canvas::KeyRelease);
487  else
488  obj->innerContainer ()->canvas (m_handle)->
489  addEventMask (Canvas::KeyRelease);
490  }
491  }
492  }
493  break;
494 
495  case figure::properties::ID_WINDOWSTYLE:
496  if (fp.windowstyle_is ("modal"))
497  {
498  bool is_visible = win->isVisible ();
499 
500  // if window is already visible, need to hide and reshow it in order to
501  // make it use the modal settings
502  if (is_visible)
503  win->setVisible (false);
504 
505  win->setWindowModality (Qt::ApplicationModal);
506  win->setVisible (is_visible);
507  }
508  else
509  win->setWindowModality (Qt::NonModal);
510 
511  break;
512 
513  case figure::properties::ID_POINTERSHAPECDATA:
515  pointer_to_qimage (fp.get_pointershapecdata ().matrix_value ());
516  if (fp.get_pointer () != "custom")
517  break;
518  OCTAVE_FALLTHROUGH;
519 
520  case figure::properties::ID_POINTER:
521  case figure::properties::ID_POINTERSHAPEHOTSPOT:
522  case figure::properties::ID___MOUSE_MODE__:
523  case figure::properties::ID___ZOOM_MODE__:
525  fp.get_pointer (),
527  fp.get_pointershapehotspot ()
528  .matrix_value());
529  break;
530 
531  default:
532  break;
533  }
534 
535  m_blockUpdates = false;
536 }
537 
538 void
540 {
541  if (m_statusBar
542  && (! m_statusBar->isHidden ()) != visible)
543  {
544  int dy = m_statusBar->sizeHint ().height ();
545  QRect r = qWidget<QWidget> ()->geometry ();
546 
547  if (! visible)
548  r.adjust (0, 0, 0, -dy);
549  else
550  r.adjust (0, 0, 0, dy);
551 
552  m_blockUpdates = true;
553  set_geometry (r);
554  m_statusBar->setVisible (visible);
555  m_blockUpdates = false;
556 
557  updateBoundingBox (false);
558  }
559 }
560 
561 void
563 {
564  gh_manager& gh_mgr = m_interpreter.get_gh_manager ();
565 
566  octave::autolock guard (gh_mgr.graphics_lock ());
567  graphics_object go = object ();
568 
569  if (go.valid_object () && dh != 0)
570  {
571  QRect r = qWidget<QWidget> ()->geometry ();
572 
573  r.adjust (0, dh, 0, 0);
574 
575  m_blockUpdates = true;
576  set_geometry (r);
577  m_blockUpdates = false;
578 
579  updateBoundingBox (false);
580  }
581 }
582 
583 void
585 {
586  if (! m_statusBar->isHidden ())
587  m_statusBar->showMessage (QString ("(%1, %2)")
588  .arg (pt(0), 0, 'g', 5)
589  .arg (pt(1), 0, 'g', 5));
590 }
591 
592 void
593 Figure::do_connections (const QObject *receiver, const QObject * /* emitter */)
594 {
595  Object::do_connections (receiver);
597 }
598 
599 QWidget *
601 {
602  return qWidget<QMainWindow> ()->menuBar ();
603 }
604 
605 void
606 Figure::updateBoundingBox (bool internal, int flags)
607 {
608  QWidget *win = qWidget<QWidget> ();
609  Matrix bb (1, 4);
610  std::string prop;
611 
612  if (internal)
613  {
614  prop = "position";
615  QRect r = m_innerRect;
616 
617  if (flags & UpdateBoundingBoxPosition)
618  r.moveTopLeft (win->mapToGlobal (m_container->pos ()));
619  if (flags & UpdateBoundingBoxSize)
620  r.setSize (m_container->size ());
621 
622  if (r.isValid () && r != m_innerRect)
623  {
624  m_innerRect = r;
625 
626  bb(0) = r.x ();
627  bb(1) = r.y ();
628  bb(2) = r.width ();
629  bb(3) = r.height ();
630  }
631  else
632  return;
633  }
634  else
635  {
636  prop = "outerposition";
637  QRect r = m_outerRect;
638 
639  if (flags & UpdateBoundingBoxPosition)
640  r.moveTopLeft (win->pos ());
641  if (flags & UpdateBoundingBoxSize)
642  r.setSize (win->frameGeometry ().size ());
643 
644  if (r.isValid () && r != m_outerRect)
645  {
646  m_outerRect = r;
647 
648  bb(0) = r.x ();
649  bb(1) = r.y ();
650  bb(2) = r.width ();
651  bb(3) = r.height ();
652  }
653  else
654  return;
655  }
656 
657  figure::properties& fp = properties<figure> ();
658 
659  emit gh_set_event (m_handle, prop, fp.bbox2position (bb), false,
660  prop == "position");
661 }
662 
663 bool
664 Figure::eventNotifyBefore (QObject *obj, QEvent *xevent)
665 {
666  if (! m_blockUpdates)
667  {
668  // Clicking the toolbar or the menubar makes this figure current
669  if (xevent->type () == QEvent::MouseButtonPress)
670  {
671  figure::properties& fp = properties<figure> ();
672 
673  gh_manager& gh_mgr = m_interpreter.get_gh_manager ();
674 
675  graphics_object root = gh_mgr.get_object (0);
676 
677  if (fp.get_handlevisibility () == "on")
678  root.set ("currentfigure",
679  fp.get___myhandle__ ().as_octave_value ());
680  }
681 
682  if (obj == m_container)
683  {
684  // Do nothing...
685  }
686  else if (obj == m_menuBar)
687  {
688  switch (xevent->type ())
689  {
690  case QEvent::ActionAdded:
691  case QEvent::ActionChanged:
692  case QEvent::ActionRemoved:
693  m_previousHeight = m_menuBar->sizeHint ().height ();
694 
695  default:
696  break;
697  }
698  }
699  else
700  {
701  switch (xevent->type ())
702  {
703  case QEvent::Close:
704  xevent->ignore ();
705  emit gh_callback_event (m_handle, "closerequestfcn");
706  return true;
707 
708  default:
709  break;
710  }
711  }
712  }
713 
714  return false;
715 }
716 
717 void
718 Figure::eventNotifyAfter (QObject *watched, QEvent *xevent)
719 {
720  if (! m_blockUpdates)
721  {
722  if (watched == m_container)
723  {
724  gh_manager& gh_mgr = m_interpreter.get_gh_manager ();
725 
726  switch (xevent->type ())
727  {
728  case QEvent::Resize:
730  break;
731 
732  case QEvent::ChildAdded:
733  if (dynamic_cast<QChildEvent *> (xevent)->child
734  ()->isWidgetType())
735  {
736  octave::autolock guard (gh_mgr.graphics_lock ());
737  update (figure::properties::ID_TOOLBAR);
738 
740  }
741  break;
742 
743  case QEvent::ChildRemoved:
744  if (dynamic_cast<QChildEvent *> (xevent)->child
745  ()->isWidgetType())
746  {
747  octave::autolock guard (gh_mgr.graphics_lock ());
748  update (figure::properties::ID_TOOLBAR);
749  }
750  break;
751 
752  default:
753  break;
754  }
755  }
756  else if (watched == m_menuBar)
757  {
758  switch (xevent->type ())
759  {
760  case QEvent::ActionAdded:
761  case QEvent::ActionChanged:
762  case QEvent::ActionRemoved:
763  // The menubar may have been resized if no action is visible
764  {
765  QAction *a = dynamic_cast<QActionEvent *> (xevent)->action ();
766  int currentHeight = m_menuBar->sizeHint ().height ();
767  if (currentHeight != m_previousHeight
768  && ! a->isSeparator ())
769  updateFigureHeight (m_previousHeight - currentHeight);
770  }
771  break;
772 
773  default:
774  break;
775  }
776  }
777  else
778  {
779  switch (xevent->type ())
780  {
781  case QEvent::Move:
784  break;
785 
786  case QEvent::Resize:
788  break;
789 
790  default:
791  break;
792  }
793  }
794  }
795 }
796 
797 void
798 Figure::addCustomToolBar (QToolBar *bar, bool visible, bool isdefault)
799 {
800  QMainWindow *win = qWidget<QMainWindow> ();
801 
802  if (isdefault)
803  m_figureToolBar = bar;
804 
805  if (! visible)
806  win->addToolBar (bar);
807  else
808  {
809  QSize sz = bar->sizeHint ();
810  QRect r = win->geometry ();
811 
812  r.adjust (0, -sz.height (), 0, 0);
813 
814  m_blockUpdates = true;
815  set_geometry (r);
816  win->addToolBarBreak ();
817  win->addToolBar (bar);
818  m_blockUpdates = false;
819 
820  updateBoundingBox (false);
821  }
822 }
823 
824 void
825 Figure::showCustomToolBar (QToolBar *bar, bool visible)
826 {
827  QMainWindow *win = qWidget<QMainWindow> ();
828 
829  if ((! bar->isHidden ()) != visible)
830  {
831  QSize sz = bar->sizeHint ();
832  QRect r = win->geometry ();
833 
834  if (visible)
835  r.adjust (0, -sz.height (), 0, 0);
836  else
837  r.adjust (0, sz.height (), 0, 0);
838 
839  m_blockUpdates = true;
840  set_geometry (r);
841  bar->setVisible (visible);
842  m_blockUpdates = false;
843 
844  updateBoundingBox (false);
845  }
846 }
847 
848 void
850 {
851  redraw ();
852 }
853 
854 void
856 {
857 #if defined (HAVE_QSCREEN_DEVICEPIXELRATIO)
858  QWindow *window = qWidget<QMainWindow> ()->windowHandle ();
859  QScreen *screen = window->screen ();
860 
861  gh_manager& gh_mgr = m_interpreter.get_gh_manager ();
862 
863  octave::autolock guard (gh_mgr.graphics_lock ());
864 
865  figure::properties& fp = properties<figure> ();
866  fp.set___device_pixel_ratio__ (screen->devicePixelRatio ());
867 
868  connect (window, &QWindow::screenChanged, this, &Figure::screenChanged);
869 #endif
870 }
871 
872 void
873 Figure::screenChanged (QScreen *screen)
874 {
875 #if defined (HAVE_QSCREEN_DEVICEPIXELRATIO)
876  gh_manager& gh_mgr = m_interpreter.get_gh_manager ();
877 
878  octave::autolock guard (gh_mgr.graphics_lock ());
879 
880  figure::properties& fp = properties<figure> ();
881  double old_dpr = fp.get___device_pixel_ratio__ ();
882  double new_dpr = screen->devicePixelRatio ();
883  if (old_dpr != new_dpr)
884  {
885  fp.set___device_pixel_ratio__ (new_dpr);
886 
887  // For some obscure reason, changing the __device_pixel_ratio__ property
888  // from the GUI thread does not necessarily trigger a redraw. Force it.
889  redraw ();
890  }
891 #else
892  octave_unused_parameter (screen);
893 #endif
894 }
895 
896 void
898 {
899  // Enable mouse tracking on every widgets
900  m_container->setMouseTracking (true);
901  m_container->canvas (m_handle)->qWidget ()->setMouseTracking (true);
902  for (auto *w : m_container->findChildren<QWidget *> ())
903  w->setMouseTracking (true);
904 }
905 
OCTAVE_END_NAMESPACE(octave)
static QImage pointer_to_qimage(const Matrix &cdata)
Definition: Figure.cc:89
static QRect boundingBoxToRect(const Matrix &bb)
Definition: Figure.cc:73
MouseMode
Definition: Figure.h:46
@ TextMode
Definition: Figure.h:53
@ PanMode
Definition: Figure.h:51
@ NoMode
Definition: Figure.h:47
@ RotateMode
Definition: Figure.h:48
@ ZoomOutMode
Definition: Figure.h:50
@ ZoomInMode
Definition: Figure.h:49
#define DECLARE_GENERICEVENTNOTIFY_SENDER(T, B)
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type columns(void) const
Definition: Array.h:471
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type rows(void) const
Definition: Array.h:459
Definition: Canvas.h:50
void addEventMask(int m)
Definition: Canvas.h:71
void print(const QString &file_cmd, const QString &term)
Definition: Canvas.h:66
void setEventMask(int m)
Definition: Canvas.h:73
void clearEventMask(int m)
Definition: Canvas.h:72
virtual uint8NDArray getPixels(void)
Definition: Canvas.h:85
void redraw(bool sync=false)
Definition: Canvas.cc:57
void blockRedraw(bool block=true)
Definition: Canvas.cc:71
void setCursor(MouseMode mode, std::string fallback, QImage cdata, Matrix hotspot)
Definition: Canvas.cc:87
@ KeyRelease
Definition: Canvas.h:57
@ KeyPress
Definition: Canvas.h:56
virtual QWidget * qWidget(void)=0
void interpreter_event(const octave::fcn_callback &fcn)
Canvas * canvas(const graphics_handle &handle, bool create=true)
Definition: Container.cc:55
void figureWindowShown()
Definition: Figure.h:65
static Figure * create(octave::base_qobject &oct_qobj, octave::interpreter &interp, const graphics_object &go)
Definition: Figure.cc:112
void eventNotifyAfter(QObject *watched, QEvent *event)
Definition: Figure.cc:718
void setFileName(const QString &name)
Definition: Figure.cc:210
uint8NDArray slotGetPixels(void)
Definition: Figure.cc:328
int m_previousHeight
Definition: Figure.h:141
void show(void)
Definition: Figure.cc:310
~Figure(void)
Definition: Figure.cc:192
QRect m_innerRect
Definition: Figure.h:138
bool m_blockUpdates
Definition: Figure.h:134
void beingDeleted(void)
Definition: Figure.cc:346
QString fileName(void)
Definition: Figure.cc:196
void updateFigureHeight(int delta_h)
Definition: Figure.cc:562
QRect m_outerRect
Definition: Figure.h:139
void addCustomToolBar(QToolBar *bar, bool visible, bool isdefault)
Definition: Figure.cc:798
void figureWindowShown()
Definition: Figure.cc:855
void interpreter_event(const octave::fcn_callback &fcn)
Figure(octave::base_qobject &oct_qobj, octave::interpreter &interp, const graphics_object &go, FigureWindow *win)
Definition: Figure.cc:118
QWidget * menu(void)
Definition: Figure.cc:600
MenuBar * m_menuBar
Definition: Figure.h:136
QStatusBar * m_statusBar
Definition: Figure.h:137
QToolBar * m_figureToolBar
Definition: Figure.h:135
void enableMouseTracking(void)
Definition: Figure.cc:897
void print(const QString &file_cmd, const QString &term)
Definition: Figure.cc:319
void do_connections(const QObject *receiver, const QObject *emitter=nullptr)
Definition: Figure.cc:593
bool eventNotifyBefore(QObject *watched, QEvent *event)
Definition: Figure.cc:664
void set_geometry(QRect r)
Definition: Figure.cc:256
void screenChanged(QScreen *)
Definition: Figure.cc:873
Container * innerContainer(void)
Definition: Figure.cc:281
void showFigureStatusBar(bool visible)
Definition: Figure.cc:539
bool m_resizable
Definition: Figure.h:142
@ UpdateBoundingBoxPosition
Definition: Figure.h:97
@ UpdateBoundingBoxSize
Definition: Figure.h:98
void asyncUpdate(void)
void showCustomToolBar(QToolBar *bar, bool visible)
Definition: Figure.cc:825
Container * m_container
Definition: Figure.h:133
void update(int pId)
Definition: Figure.cc:358
void updateStatusBar(ColumnVector pt)
Definition: Figure.cc:584
void redraw(void)
Definition: Figure.cc:287
QImage m_pointer_cdata
Definition: Figure.h:140
MouseMode mouseMode(void)
Definition: Figure.cc:222
void updateBoundingBox(bool internal=false, int flags=0)
Definition: Figure.cc:606
void updateContainer(void)
Definition: Figure.cc:849
void addReceiver(GenericEventNotifyReceiver *r)
void removeReceiver(GenericEventNotifyReceiver *r)
Definition: dMatrix.h:42
Definition: Object.h:47
void gh_callback_event(const graphics_handle &h, const std::string &name)
virtual void do_connections(const QObject *receiver, const QObject *emitter=nullptr)
Definition: Object.cc:224
graphics_handle m_handle
Definition: Object.h:153
static Object * fromQObject(QObject *obj)
Definition: Object.cc:213
void gh_set_event(const graphics_handle &h, const std::string &name, const octave_value &value)
graphics_object object(void) const
Definition: Object.cc:82
virtual Container * innerContainer(void)=0
octave::interpreter & m_interpreter
Definition: Object.h:136
void slotRedraw(void)
Definition: Object.cc:130
double value(void) const
Definition: oct-handle.h:78
octave_value getfield(const std::string &key) const
Definition: oct-map.cc:183
std::string string_value(bool force=false) const
Definition: ov.h:1019
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
const QString global_menubar_style("QMenuBar {" "margin-top: 0px;" "margin-bottom: 0px;" "padding-top: 0px;" "padding-bottom: 0px;" "}")
double round(double x)
Definition: lo-mappers.h:136
T * r
Definition: mx-inlines.cc:773
std::complex< double > w(std::complex< double > z, double relerr=0)
QString fromStdString(const std::string &s)
T::properties & properties(graphics_object obj)
static uint32_t state[624]
Definition: randmtzig.cc:193