26#if defined (HAVE_CONFIG_H)
30#include <QApplication>
33#include <QInputDialog>
49#include "builtin-defun-decls.h"
84 return QCursor (icon.pixmap (22, 22), hot_x, hot_y);
89 QImage cdata,
Matrix hotspot)
92 QCursor cursor = Qt::ArrowCursor;
99 cursor = Qt::ArrowCursor;
101 if (fallback ==
"arrow")
102 cursor = Qt::ArrowCursor;
103 else if (fallback ==
"botl")
104 cursor =
make_cursor (
"bottom_left_corner", 5, 16);
105 else if (fallback ==
"botr")
106 cursor =
make_cursor (
"bottom_right_corner", 16, 16);
107 else if (fallback ==
"bottom")
109 else if (fallback ==
"circle")
111 else if (fallback ==
"cross" || fallback ==
"crosshair")
113 else if (fallback ==
"custom")
115 if (hotspot(0) > cdata.width () || hotspot(0) < 1.0
116 || hotspot(1) > cdata.height () || hotspot(1) < 1.0)
117 hotspot =
Matrix (1, 2, 1);
119 cursor = QCursor (QPixmap::fromImage (cdata),
120 static_cast<int> (hotspot(1) - 1),
121 static_cast<int> (hotspot(0) - 1));
123 else if (fallback ==
"fleur")
125 else if (fallback ==
"hand")
127 else if (fallback ==
"ibeam")
128 cursor = Qt::IBeamCursor;
129 else if (fallback ==
"left")
131 else if (fallback ==
"right")
133 else if (fallback ==
"top")
135 else if (fallback ==
"topl")
137 else if (fallback ==
"topr")
139 else if (fallback ==
"watch")
140 cursor = Qt::BusyCursor;
144 cursor = Qt::ArrowCursor;
156 cursor = Qt::IBeamCursor;
168 cursor = Qt::ArrowCursor;
171 w->setCursor (cursor);
182 const graphics_object& obj, QMouseEvent *event)
191 Matrix children = obj.get_properties ().get_children ();
194 for (
int i = 0; i < num_children; i++)
196 graphics_object childObj (gh_mgr.get_object (children(i)));
198 if (childObj.isa (
"axes"))
201 Matrix x_zlim = ap.get_transform_zlim ();
202 graphics_xform x_form = ap.get_transform ();
204 ColumnVector p1 = x_form.untransform (event->x (), event->y (),
206 ColumnVector p2 = x_form.untransform (event->x (), event->y (),
211 cp(0, 0) = p1(0); cp(0, 1) = p1(1); cp(0, 2) = p1(2);
212 cp(1, 0) = p2(0); cp(1, 1) = p2(1); cp(1, 2) = p2(2);
214 emit
gh_set_event (childObj.get_handle (),
"currentpoint", cp,
222 const graphics_object& obj)
231 Matrix children = obj.get_properties ().get_children ();
234 for (
int i = 0; i < num_children; i++)
236 graphics_object childObj (gh_mgr.get_object (children(i)));
238 if (childObj.isa (
"axes"))
243 QPoint p =
w->mapFromGlobal (QCursor::pos ());
245 Matrix x_zlim = ap.get_transform_zlim ();
246 graphics_xform x_form = ap.get_transform ();
248 ColumnVector p1 = x_form.untransform (p.x (), p.y (), x_zlim(0));
249 ColumnVector p2 = x_form.untransform (p.x (), p.y (), x_zlim(1));
253 cp(0, 0) = p1(0); cp(0, 1) = p1(1); cp(0, 2) = p1(2);
254 cp(1, 0) = p2(0); cp(1, 1) = p2(1); cp(1, 2) = p2(2);
256 emit
gh_set_event (childObj.get_handle (),
"currentpoint", cp,
268 ap.clear_zoom_stack (
false);
270 ap.set_xlimmode (
"auto");
271 ap.set_ylimmode (
"auto");
272 ap.set_zlimmode (
"auto");
296 = Utils::properties<figure> (figObj).get___pan_mode__ ();
308 = Utils::properties<figure> (figObj).get___pan_mode__ ();
320 = Utils::properties<figure> (figObj).get___zoom_mode__ ();
332 = Utils::properties<figure> (figObj).get___zoom_mode__ ();
341 graphics_object& currentObj, graphics_object& axesObj,
342 bool axes_only, std::vector<std::string> omit)
345 Matrix children = obj.get_properties ().get_all_children ();
350 for (
int i = 0; i < num_children; i++)
352 graphics_object childObj (gh_mgr.get_object (children(i)));
354 if (childObj.isa (
"axes"))
356 auto p = omit.begin ();
357 bool omitfound =
false;
358 while (p != omit.end () && ! omitfound)
360 omitfound = (childObj.get (
"tag").string_value () == *p);
364 axesList.append (childObj);
366 else if (childObj.isa (
"uicontrol") || childObj.isa (
"uipanel")
367 || childObj.isa (
"uibuttongroup") || childObj.isa (
"uitable"))
369 Matrix bb = childObj.get_properties ().get_boundingbox (
false);
370 QRectF r (bb(0), bb(1), bb(2), bb(3));
372 r.adjust (-5, -5, 5, 5);
374 bool rect_contains_pos = r.contains (event->localPos ());
375 if (rect_contains_pos)
377 currentObj = childObj;
385 QPoint pt =
event->pos ();
388 it != axesList.end (); ++it)
394 Matrix xlim = ap.get_xlim ().matrix_value ();
395 Matrix ylim = ap.get_ylim ().matrix_value ();
397 if (xlim(0) < p0(0) && xlim(1) > p0(0)
398 && ylim(0) < p0(1) && ylim(1) > p0(1))
405 else if (! currentObj)
408 it != axesList.end (); ++it)
419 else if (it->get_properties ().is_hittest ())
421 Matrix bb = it->get_properties ().get_boundingbox (
true);
422 QRectF r (bb(0), bb(1), bb(2), bb(3));
426 r.adjust (-20, -20, 20, 20);
428 bool rect_contains_pos = r.contains (event->localPos ());
429 if (rect_contains_pos)
433 if (axesObj && currentObj)
446 graphics_object ax = gh_mgr.get_object (
m_mouseAxes);
477 graphics_object figObj (ax.get_ancestor (
"figure"));
479 std::string mode =
pan_mode (figObj);
486 ap.translate_view (mode, p0(0), p1(0), p0(1), p1(1));
501 graphics_object obj = gh_mgr.get_object (
m_handle);
503 if (obj.valid_object ())
505 graphics_object figObj (obj.get_ancestor (
"figure"));
507 if (figObj.valid_object ()
508 && ! figObj.get (
"windowbuttonmotionfcn").isempty ())
512 "windowbuttonmotionfcn");
518 graphics_object obj = gh_mgr.get_object (
m_handle);
519 graphics_object figObj = obj.get_ancestor (
"figure");
521 if (figObj.valid_object () && obj.valid_object ())
523 graphics_object currentObj, axesObj;
524 std::vector<std::string> omit = {
"legend",
"colorbar",
"scribeoverlay"};
527 if (axesObj.valid_object ())
553 switch (event->button ())
559 case Qt::MiddleButton:
563 case Qt::RightButton:
581 graphics_object obj = gh_mgr.get_object (
m_handle);
583 bool isdblclick = (
event->type () == QEvent::MouseButtonDblClick);
585 if (obj.valid_object ())
587 graphics_object figObj (obj.get_ancestor (
"figure"));
592 graphics_object root = gh_mgr.get_object (0);
593 Utils::properties<root_figure> (root)
594 .set_currentfigure (figObj.get_handle ().as_octave_value ());
597 graphics_object currentObj, axesObj;
606 if (! currentObj.valid_object ())
608 else if (! currentObj.get_properties ().is_hittest ())
612 graphics_object tmpgo;
613 tmpgo = gh_mgr.get_object (currentObj.get_parent ());
614 while (tmpgo && ! tmpgo.get_properties ().is_hittest ())
615 tmpgo = gh_mgr.get_object (tmpgo.get_parent ());
617 if (tmpgo && tmpgo.get_handle () != 0.0)
620 currentObj = graphics_object ();
624 bool valid_axes = axesObj.valid_object ()
625 && axesObj.get_properties ().handlevisibility_is (
"on")
626 && axesObj.get_properties ().get_tag () !=
"legend"
627 && axesObj.get_properties ().get_tag () !=
"colorbar";
630 Utils::properties<figure> (figObj)
631 .set_currentaxes (axesObj.get_handle ().as_octave_value ());
640 switch (newMouseMode)
645 auto& fprop = Utils::properties<figure> (figObj);
648 && currentObj.get_properties ().handlevisibility_is (
"on"))
649 fprop.set_currentobject (currentObj.get_handle ()
650 .as_octave_value ());
652 fprop.set_currentobject (
Matrix ());
655 emit
gh_set_event (figObj.get_handle (),
"selectiontype",
662 "windowbuttondownfcn",
667 if (currentObj && ! currentObj.get (
"buttondownfcn").isempty ())
670 else if (figObj && ! figObj.get (
"buttondownfcn").isempty ())
675 if (currentObj && event->button () == Qt::RightButton)
677 currentObj.get_properties (),
678 event->globalPos ());
684 if (event->modifiers () == Qt::NoModifier)
686 switch (event->buttons ())
704 bool redraw_figure =
true;
708 if (event->button () == Qt::LeftButton)
716 redraw_figure =
false;
719 else if (event->modifiers () == Qt::NoModifier)
721 switch (event->buttons ())
730 case Qt::RightButton:
741 case Qt::MiddleButton:
744 Utils::properties<axes> (axesObj);
751 redraw_figure =
false;
755 else if (event->modifiers () == Qt::ShiftModifier)
757 switch (event->buttons ())
770 redraw_figure =
false;
797 graphics_object ax = gh_mgr.get_object (
m_mouseAxes);
799 if (ax.valid_object ())
803 graphics_object obj = gh_mgr.get_object (
m_handle);
805 graphics_object figObj (obj.get_ancestor (
"figure"));
813 ColumnVector p1 = ap.pixel2coord (event->x (),
event->y ());
815 ap.zoom_about_point (zm, p1(0), p1(1), factor);
832 ap.zoom (zm, xl, yl);
842 graphics_object obj = gh_mgr.get_object (
m_handle);
844 if (obj.valid_object ())
846 graphics_object figObj (obj.get_ancestor (
"figure"));
856 graphics_object figObj
857 = gh_mgr.get_object (
m_handle).get_ancestor (
"figure");
859 if (figObj.valid_object ())
864 Matrix bb = figObj.get (
"position").matrix_value ();
874 if (anno_dlg.exec () == QDialog::Accepted)
877 props.
prepend (figObj.get_handle ().as_octave_value ());
880 ([=] (octave::interpreter& interp)
884 interp.feval (
"annotation", props);
904 graphics_object obj = gh_mgr.get_object (
m_handle);
906 if (obj.valid_object ())
910 graphics_object figObj (obj.get_ancestor (
"figure"));
912 graphics_object axesObj;
914 Matrix children = obj.get_properties ().get_children ();
917 for (
int i = 0; i < num_children; i++)
919 graphics_object childObj (gh_mgr.get_object (children(i)));
921 if (childObj.isa (
"axes"))
923#if defined (HAVE_QWHEELEVENT_POSITION)
924 QPoint pos =
event->position().toPoint ();
926 QPoint pos =
event->pos ();
947 if (axesObj.get_properties ().handlevisibility_is (
"on"))
949 Utils::properties<figure> (figObj)
950 .set_currentaxes (axesObj.get_handle ().as_octave_value ());
954#if defined (HAVE_QWHEELEVENT_ANGLEDELTA)
955 if (event->angleDelta().y () > 0)
957 if (event->delta () > 0)
973 bool redrawFigure =
true;
975 switch (newMouseMode)
983 double wheel_zoom_speed = ap.get_mousewheelzoom ();
987 ? 1 / (1.0 - wheel_zoom_speed)
988 : 1.0 - wheel_zoom_speed);
992 ap.zoom (mode, factor);
1000#if defined (HAVE_QWHEELEVENT_ANGLEDELTA)
1001 double factor = (
event->angleDelta().y () > 0 ? 0.1 : -0.1);
1003 double factor = (
event->delta () > 0 ? 0.1 : -0.1);
1006 if (event->modifiers () == Qt::NoModifier
1007 && mode !=
"horizontal")
1008 ap.pan (
"vertical", factor);
1009 else if (event->modifiers () == Qt::ShiftModifier
1010 && mode !=
"vertical")
1011 ap.pan (
"horizontal", factor);
1016 redrawFigure =
false;
1024 if (! figObj.get (
"windowscrollwheelfcn").isempty ())
1042 graphics_object obj = gh_mgr.get_object (
m_handle);
1044 if (obj.valid_object ())
1046 graphics_object figObj (obj.get_ancestor (
"figure"));
1052 emit
gh_set_event (figObj.get_handle (),
"currentcharacter",
1053 eventData.
getfield (
"Character"),
false);
1073 graphics_object obj = gh_mgr.get_object (
m_handle);
1075 if (obj.valid_object ())
1077 graphics_object figObj (obj.get_ancestor (
"figure"));
1091 const std::string& )
1094 return new GLCanvas (oct_qobj, interp, handle, parent);
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
octave_idx_type numel(void) const
Number of elements in the array.
octave_value_list get_properties() const
bool canvasKeyPressEvent(QKeyEvent *event)
void canvasMouseReleaseEvent(QMouseEvent *event)
bool canvasKeyReleaseEvent(QKeyEvent *event)
void gh_callback_event(const graphics_handle &h, const std::string &name)
void canvasPaintEvent(void)
void updateCurrentPoint(const graphics_object &fig, const graphics_object &obj, QMouseEvent *event)
static Canvas * create(octave::base_qobject &oct_qobj, octave::interpreter &interp, const graphics_handle &handle, QWidget *parent, const std::string &name)
void blockRedraw(bool block=true)
void gh_set_event(const graphics_handle &h, const std::string &name, const octave_value &value)
graphics_handle m_mouseAxes
virtual graphics_object selectFromAxes(const graphics_object &ax, const QPoint &pt)=0
void canvasMouseMoveEvent(QMouseEvent *event)
void canvasMousePressEvent(QMouseEvent *event)
octave::interpreter & m_interpreter
octave::base_qobject & m_octave_qobj
void setCursor(MouseMode mode, std::string fallback, QImage cdata, Matrix hotspot)
void redraw(bool sync=false)
QCursor make_cursor(const QString &name, int hot_x=-1, int hot_y=-1)
void select_object(graphics_object obj, QMouseEvent *event, graphics_object ¤tObj, graphics_object &axesObj, bool axes_only=false, std::vector< std::string > omit=std::vector< std::string >())
virtual void drawZoomBox(const QPoint &p1, const QPoint &p2)=0
virtual void draw(const graphics_handle &handle)=0
void interpreter_event(const octave::fcn_callback &fcn)
void canvasMouseDoubleClickEvent(QMouseEvent *event)
virtual QWidget * qWidget(void)=0
void canvasWheelEvent(QWheelEvent *event)
Base class for Octave interfaces that use Qt.
resource_manager & get_resource_manager(void)
QIcon icon(const QString &icon_name, bool fallback=true)
const octave_value & contents(const_iterator p) const
octave_value getfield(const std::string &key) const
octave_value_list & prepend(const octave_value &val)
OCTINTERP_API octave_scalar_map scalar_map_value(void) const
std::string string_value(bool force=false) const
octave_handle graphics_handle
std::complex< double > w(std::complex< double > z, double relerr=0)
octave_scalar_map makeScrollEventStruct(QWheelEvent *event)
std::string figureSelectionType(QMouseEvent *event, bool isDoubleClick)
T::properties & properties(graphics_object obj)
octave_scalar_map makeKeyEventStruct(QKeyEvent *event)
Matrix figureCurrentPoint(const graphics_object &fig, QMouseEvent *event)
static std::string pan_mode(const graphics_object figObj)
static bool zoom_enabled(const graphics_object figObj)
static void autoscale_axes(gh_manager &gh_mgr, axes::properties &ap)
static std::string zoom_mode(const graphics_object figObj)
static bool pan_enabled(const graphics_object figObj)
static double button_number(QMouseEvent *event)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.