GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
BaseControl.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2011-2018 Michael Goffioul
4 
5 This file is part of Octave.
6 
7 Octave is free software: you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <https://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include <QEvent>
28 #include <QKeyEvent>
29 #include <QMouseEvent>
30 #include <QWidget>
31 
32 #include "BaseControl.h"
33 #include "ContextMenu.h"
34 #include "QtHandlesUtils.h"
35 
36 namespace QtHandles
37 {
38 
39  static void
41  {
42  QPalette p = w->palette ();
43 
44  if (props.style_is ("edit")
45  || props.style_is ("listbox"))
46  {
47  p.setColor (QPalette::Base,
48  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
49  p.setColor (QPalette::Text,
50  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
51  }
52  else if (props.style_is ("popupmenu"))
53  {
54  // popumenu (QComboBox) is a listbox with a button, so needs set colors for both
55  p.setColor (QPalette::Base,
56  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
57  p.setColor (QPalette::Text,
58  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
59  p.setColor (QPalette::Button,
60  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
61  p.setColor (QPalette::ButtonText,
62  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
63  }
64  else if (props.style_is ("radiobutton")
65  || props.style_is ("checkbox"))
66  {
67  p.setColor (QPalette::Button,
68  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
69  p.setColor (QPalette::WindowText,
70  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
71  }
72  else if (props.style_is ("pushbutton")
73  || props.style_is ("togglebutton"))
74  {
75  p.setColor (QPalette::Button,
76  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
77  p.setColor (QPalette::ButtonText,
78  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
79  }
80  else
81  {
82  p.setColor (QPalette::Window,
83  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
84  p.setColor (QPalette::WindowText,
85  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
86  }
87 
88  w->setPalette (p);
89  }
90 
92  : Object (go, w), m_normalizedFont (false), m_keyPressHandlerDefined (false)
93  {
94  init (w);
95  }
96 
97  void
98  BaseControl::init (QWidget *w, bool callBase)
99  {
100  if (callBase)
101  Object::init (w, callBase);
102 
103  uicontrol::properties& up = properties<uicontrol> ();
104 
105  Matrix bb = up.get_boundingbox (false);
106  w->setGeometry (octave::math::round (bb(0)), octave::math::round (bb(1)),
107  octave::math::round (bb(2)), octave::math::round (bb(3)));
108  w->setFont (Utils::computeFont<uicontrol> (up, bb(3)));
109  updatePalette (up, w);
110  w->setEnabled (up.enable_is ("on"));
111  w->setToolTip (Utils::fromStdString (up.get_tooltipstring ()));
112  w->setVisible (up.is_visible ());
113  m_keyPressHandlerDefined = ! up.get_keypressfcn ().isempty ();
114 
115  w->installEventFilter (this);
116 
117  m_normalizedFont = up.fontunits_is ("normalized");
118  }
119 
121  { }
122 
123  void
125  {
126  uicontrol::properties& up = properties<uicontrol> ();
127  QWidget *w = qWidget<QWidget> ();
128 
129  switch (pId)
130  {
131  case uicontrol::properties::ID_POSITION:
132  {
133  Matrix bb = up.get_boundingbox (false);
134  w->setGeometry (octave::math::round (bb(0)), octave::math::round (bb(1)),
135  octave::math::round (bb(2)), octave::math::round (bb(3)));
136  }
137  break;
138 
139  case uicontrol::properties::ID_FONTNAME:
140  case uicontrol::properties::ID_FONTSIZE:
141  case uicontrol::properties::ID_FONTWEIGHT:
142  case uicontrol::properties::ID_FONTANGLE:
143  w->setFont (Utils::computeFont<uicontrol> (up));
144  break;
145 
146  case uicontrol::properties::ID_FONTUNITS:
147  // FIXME: We shouldn't have to do anything, octave should update
148  // the "fontsize" property automatically to the new units.
149  // Hence the actual font used shouldn't change.
150  m_normalizedFont = up.fontunits_is ("normalized");
151  break;
152 
153  case uicontrol::properties::ID_BACKGROUNDCOLOR:
154  case uicontrol::properties::ID_FOREGROUNDCOLOR:
155  updatePalette (up, w);
156  break;
157 
158  case uicontrol::properties::ID_ENABLE:
159  w->setEnabled (up.enable_is ("on"));
160  break;
161 
162  case uicontrol::properties::ID_TOOLTIPSTRING:
163  w->setToolTip (Utils::fromStdString (up.get_tooltipstring ()));
164  break;
165 
166  case base_properties::ID_VISIBLE:
167  w->setVisible (up.is_visible ());
168  break;
169 
170  case uicontrol::properties::ID_KEYPRESSFCN:
171  m_keyPressHandlerDefined = ! up.get_keypressfcn ().isempty ();
172  break;
173 
174  default:
175  break;
176  }
177  }
178 
179  bool
180  BaseControl::eventFilter (QObject *watched, QEvent *xevent)
181  {
182  switch (xevent->type ())
183  {
184  case QEvent::Resize:
185  if (m_normalizedFont)
186  {
188 
189  qWidget<QWidget> ()->setFont (Utils::computeFont<uicontrol>
190  (properties<uicontrol> ()));
191  }
192  break;
193 
194  case QEvent::MouseButtonPress:
195  {
197 
198  QMouseEvent *m = dynamic_cast<QMouseEvent *> (xevent);
199  graphics_object go = object ();
200  uicontrol::properties& up = Utils::properties<uicontrol> (go);
201  graphics_object fig = go.get_ancestor ("figure");
202 
203  if (m->button () != Qt::LeftButton
204  || ! up.enable_is ("on"))
205  {
206  gh_manager::post_set (fig.get_handle (), "selectiontype",
207  Utils::figureSelectionType (m), false);
208  gh_manager::post_set (fig.get_handle (), "currentpoint",
209  Utils::figureCurrentPoint (fig, m),
210  false);
211  gh_manager::post_callback (fig.get_handle (),
212  "windowbuttondownfcn");
213  gh_manager::post_callback (m_handle, "buttondownfcn");
214 
215  if (m->button () == Qt::RightButton)
216  ContextMenu::executeAt (up, m->globalPos ());
217  }
218  else
219  {
220  if (up.style_is ("listbox"))
221  gh_manager::post_set (fig.get_handle (), "selectiontype",
222  Utils::figureSelectionType (m), false);
223  else
224  gh_manager::post_set (fig.get_handle (), "selectiontype",
225  octave_value ("normal"), false);
226  }
227  }
228  break;
229 
230  case QEvent::MouseMove:
231  if (qWidget<QWidget> ()->hasMouseTracking ())
232  {
234 
235  QMouseEvent *m = dynamic_cast<QMouseEvent *> (xevent);
236  graphics_object go = object ();
237  graphics_object fig = go.get_ancestor ("figure");
238 
239  gh_manager::post_set (fig.get_handle (), "currentpoint",
240  Utils::figureCurrentPoint (fig, m), false);
241  gh_manager::post_callback (fig.get_handle (), "windowbuttonmotionfcn");
242  }
243  break;
244 
245  case QEvent::KeyPress:
247  {
249 
250  octave_scalar_map keyData =
251  Utils::makeKeyEventStruct (dynamic_cast<QKeyEvent *> (xevent));
252  graphics_object fig = object ().get_ancestor ("figure");
253 
254  gh_manager::post_set (fig.get_handle (), "currentcharacter",
255  keyData.getfield ("Character"), false);
256  gh_manager::post_callback (m_handle, "keypressfcn", keyData);
257  }
258  break;
259 
260  default:
261  break;
262  }
263 
264  return Object::eventFilter (watched, xevent);
265  }
266 
267 }
static void post_callback(const graphics_handle &h, const std::string &name, const octave_value &data=Matrix())
Definition: graphics.in.h:6214
graphics_handle get_handle(void) const
Definition: graphics.in.h:2774
QString fromStdString(const std::string &s)
bool eventFilter(QObject *watched, QEvent *e)
Definition: BaseControl.cc:180
void init(QWidget *w, bool callBase=false)
Definition: BaseControl.cc:98
Matrix figureCurrentPoint(const graphics_object &fig, QMouseEvent *event)
template QFont computeFont< uicontrol >(const uicontrol::properties &props, int height)
static void executeAt(const base_properties &props, const QPoint &pt)
Definition: ContextMenu.cc:113
QColor fromRgb(const Matrix &rgb)
static void updatePalette(const uicontrol::properties &props, QWidget *w)
Definition: BaseControl.cc:40
octave_scalar_map makeKeyEventStruct(QKeyEvent *event)
std::complex< double > w(std::complex< double > z, double relerr=0)
void init(QObject *obj, bool callBase=false)
Definition: Object.cc:51
graphics_handle m_handle
Definition: Object.h:115
is false
Definition: cellfun.cc:400
Matrix get_boundingbox(bool internal=false, const Matrix &parent_pix_size=Matrix()) const
Definition: graphics.cc:9527
Definition: dMatrix.h:36
octave_value getfield(const std::string &key) const
Definition: oct-map.cc:184
graphics_object object(void) const
Definition: Object.cc:72
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
void update(int pId)
Definition: BaseControl.cc:124
std::string figureSelectionType(QMouseEvent *event, bool isDoubleClick)
p
Definition: lu.cc:138
double round(double x)
Definition: lo-mappers.h:145
BaseControl(const graphics_object &go, QWidget *w)
Definition: BaseControl.cc:91
graphics_object get_ancestor(const std::string &type) const
Definition: graphics.cc:3613
static void post_set(const graphics_handle &h, const std::string &name, const octave_value &value, bool notify_toolkit=true)
Definition: graphics.in.h:6228