26 #if defined (HAVE_CONFIG_H)
50 #include "builtin-defun-decls.h"
75 OCTAVE_NORETURN
static
79 error (
"set: invalid value for %s property", pname.c_str ());
88 const std::set<std::string>& pnames,
91 std::size_t
len = pname.length ();
92 std::set<std::string> matches;
95 for (
const auto& propnm : pnames)
99 if (
len == propnm.length ())
102 matches.insert (propnm);
106 std::size_t num_matches = matches.size ();
108 if (num_matches == 0)
109 error (
"%s: unknown %s property %s",
110 who.c_str (), what.c_str (), pname.c_str ());
111 else if (num_matches > 1)
115 std::ostringstream os;
119 std::string match_list = os.str ();
121 error (
"%s: ambiguous %s property name %s; possible matches:\n\n%s",
122 who.c_str (), what.c_str (), pname.c_str (), match_list.c_str ());
127 std::string possible_match = *(matches.begin ());
130 "%s: allowing %s to match %s property %s",
131 who.c_str (), pname.c_str (), what.c_str (),
132 possible_match.c_str ());
134 return possible_match;
149 const double cmapv[] =
151 2.67004010000000e-01, 2.72651720952381e-01, 2.77106307619048e-01,
152 2.80356151428571e-01, 2.82390045238095e-01, 2.83204606666667e-01,
153 2.82809341428571e-01, 2.81230763333333e-01, 2.78516153333333e-01,
154 2.74735528571429e-01, 2.69981791904762e-01, 2.64368580952381e-01,
155 2.58026184285714e-01, 2.51098684761905e-01, 2.43732853333333e-01,
156 2.36073294285714e-01, 2.28263191428571e-01, 2.20424955714286e-01,
157 2.12666598571429e-01, 2.05079113809524e-01, 1.97721880952381e-01,
158 1.90631350000000e-01, 1.83819438571429e-01, 1.77272360952381e-01,
159 1.70957518571429e-01, 1.64832915714286e-01, 1.58845368095238e-01,
160 1.52951235714286e-01, 1.47131626666667e-01, 1.41402210952381e-01,
161 1.35832975714286e-01, 1.30582113809524e-01, 1.25898377619048e-01,
162 1.22163105714286e-01, 1.19872409523810e-01, 1.19626570000000e-01,
163 1.22045948571429e-01, 1.27667691904762e-01, 1.36834947142857e-01,
164 1.49643331428571e-01, 1.65967274285714e-01, 1.85538397142857e-01,
165 2.08030450000000e-01, 2.33127309523809e-01, 2.60531475238095e-01,
166 2.90000730000000e-01, 3.21329971428571e-01, 3.54355250000000e-01,
167 3.88930322857143e-01, 4.24933143333333e-01, 4.62246770476190e-01,
168 5.00753620000000e-01, 5.40336957142857e-01, 5.80861172380952e-01,
169 6.22170772857143e-01, 6.64087320476191e-01, 7.06403823333333e-01,
170 7.48885251428571e-01, 7.91273132857143e-01, 8.33302102380952e-01,
171 8.74717527142857e-01, 9.15296319047619e-01, 9.54839555238095e-01,
172 9.93247890000000e-01, 4.87433000000000e-03, 2.58456800000000e-02,
173 5.09139004761905e-02, 7.42014957142857e-02, 9.59536042857143e-02,
174 1.16893314761905e-01, 1.37350195714286e-01, 1.57479940000000e-01,
175 1.77347967619048e-01, 1.96969168571429e-01, 2.16330337619048e-01,
176 2.35404660952381e-01, 2.54161735714286e-01, 2.72573219047619e-01,
177 2.90619516666667e-01, 3.08291041428571e-01, 3.25586450952381e-01,
178 3.42517215238095e-01, 3.59102207142857e-01, 3.75366067142857e-01,
179 3.91340913333333e-01, 4.07061480000000e-01, 4.22563764285714e-01,
180 4.37885543809524e-01, 4.53062984285714e-01, 4.68129543809524e-01,
181 4.83117059523810e-01, 4.98052961428571e-01, 5.12959473333333e-01,
182 5.27854311428571e-01, 5.42750087142857e-01, 5.57652481904762e-01,
183 5.72563073333333e-01, 5.87476284285714e-01, 6.02382410952381e-01,
184 6.17265840000000e-01, 6.32106955714286e-01, 6.46881817142857e-01,
185 6.61562926190476e-01, 6.76119717142857e-01, 6.90518987142857e-01,
186 7.04725181904762e-01, 7.18700950000000e-01, 7.32406441904762e-01,
187 7.45802021904762e-01, 7.58846480000000e-01, 7.71497934761905e-01,
188 7.83714033809524e-01, 7.95453081428571e-01, 8.06673890000000e-01,
189 8.17337565714286e-01, 8.27409135714286e-01, 8.36858167619048e-01,
190 8.45663399523809e-01, 8.53815582857143e-01, 8.61321019047619e-01,
191 8.68206316666667e-01, 8.74522215714286e-01, 8.80346158571429e-01,
192 8.85780083333333e-01, 8.90945338571429e-01, 8.95973498571429e-01,
193 9.01005800000000e-01, 9.06156570000000e-01, 3.29415190000000e-01,
194 3.53367293333333e-01, 3.76236064761905e-01, 3.97901482857143e-01,
195 4.18250757142857e-01, 4.37178920000000e-01, 4.54595888571429e-01,
196 4.70433883333333e-01, 4.84653865714286e-01, 4.97250492857143e-01,
197 5.08254501428571e-01, 5.17731949047619e-01, 5.25780221428571e-01,
198 5.32522206190476e-01, 5.38097133333333e-01, 5.42651800000000e-01,
199 5.46335411904762e-01, 5.49287148571429e-01, 5.51635008571429e-01,
200 5.53493173333333e-01, 5.54953478571429e-01, 5.56089070000000e-01,
201 5.56952166666667e-01, 5.57576145714286e-01, 5.57974025714286e-01,
202 5.58142745238095e-01, 5.58058673809524e-01, 5.57684744285714e-01,
203 5.56973310000000e-01, 5.55864478571429e-01, 5.54288677142857e-01,
204 5.52175699047619e-01, 5.49445382857143e-01, 5.46023368571429e-01,
205 5.41830633809524e-01, 5.36795616666667e-01, 5.30847985714286e-01,
206 5.23924198571429e-01, 5.15966779523810e-01, 5.06924262857143e-01,
207 4.96751861428571e-01, 4.85412122857143e-01, 4.72873300000000e-01,
208 4.59105875238095e-01, 4.44095883333333e-01, 4.27825852857143e-01,
209 4.10292713809524e-01, 3.91487632857143e-01, 3.71420688571429e-01,
210 3.50098750000000e-01, 3.27544678571429e-01, 3.03798967142857e-01,
211 2.78916748571429e-01, 2.53000856190476e-01, 2.26223670000000e-01,
212 1.98879439523810e-01, 1.71494930000000e-01, 1.45037631428572e-01,
213 1.21291048571429e-01, 1.03326155238095e-01, 9.53507900000000e-02,
214 1.00469958095238e-01, 1.17876387142857e-01, 1.43936200000000e-01
220 std::copy (cmapv, cmapv + (64*3), cmap.
fortran_vec ());
229 return dpy_info.depth ();
241 retval(2) = dpy_info.width ();
242 retval(3) = dpy_info.height ();
252 return (dpy_info.x_dpi () + dpy_info.y_dpi ()) / 2;
258 Matrix retval (7, 3, 0.0);
260 retval(0, 1) = 0.447;
261 retval(0, 2) = 0.741;
263 retval(1, 0) = 0.850;
264 retval(1, 1) = 0.325;
265 retval(1, 2) = 0.098;
267 retval(2, 0) = 0.929;
268 retval(2, 1) = 0.694;
269 retval(2, 2) = 0.125;
271 retval(3, 0) = 0.494;
272 retval(3, 1) = 0.184;
273 retval(3, 2) = 0.556;
275 retval(4, 0) = 0.466;
276 retval(4, 1) = 0.674;
277 retval(4, 2) = 0.188;
279 retval(5, 0) = 0.301;
280 retval(5, 1) = 0.745;
281 retval(5, 2) = 0.933;
283 retval(6, 0) = 0.635;
284 retval(6, 1) = 0.078;
285 retval(6, 2) = 0.184;
339 for (
int col = 0; col < 64; col++)
340 for (
int row = 0; row < 64; row++)
354 for (
int col = 0; col < 3; col++)
355 for (
int row = 0; row < 3; row++)
366 for (
int row = 0; row < 3; row++)
367 for (
int col = 0; col < 3; col++)
378 for (
int row = 0; row < 3; row++)
527 m(0) = 1.3421852580027660;
528 m(1) = 3.3191389435020748;
529 m(2) = 5.8156294839944680;
530 m(3) = 4.3617221129958503;
540 return gtk_mgr.default_toolkit ();
621 bool integer_figure_handle =
false,
622 bool call_createfcn =
true,
623 bool notify_toolkit =
true)
627 return gh_mgr.make_graphics_handle (go_name, parent, integer_figure_handle,
628 call_createfcn, notify_toolkit);
637 if (from_units.
compare (to_units))
643 double points_size = 0;
646 if (from_units.
compare (
"points"))
647 points_size = font_size;
652 if (from_units.
compare (
"pixels"))
653 points_size = font_size * 72.0 / res;
654 else if (from_units.
compare (
"inches"))
655 points_size = font_size * 72.0;
656 else if (from_units.
compare (
"centimeters"))
657 points_size = font_size * 72.0 / 2.54;
658 else if (from_units.
compare (
"normalized"))
659 points_size = font_size * parent_height * 72.0 / res;
662 double new_font_size = 0;
664 if (to_units.
compare (
"points"))
665 new_font_size = points_size;
671 if (to_units.
compare (
"pixels"))
672 new_font_size = points_size * res / 72.0;
673 else if (to_units.
compare (
"inches"))
674 new_font_size = points_size / 72.0;
675 else if (to_units.
compare (
"centimeters"))
676 new_font_size = points_size * 2.54 / 72.0;
677 else if (to_units.
compare (
"normalized"))
681 if (parent_height > 0)
682 new_font_size = points_size * res / (parent_height * 72.0);
686 return new_font_size;
695 bool is_rectangle = (pos.
numel () == 4);
696 bool is_2D = (pos.
numel () == 2);
698 if (from_units.
compare (
"pixels"))
700 else if (from_units.
compare (
"normalized"))
702 retval(0) = pos(0) * parent_dim(0) + 1;
703 retval(1) = pos(1) * parent_dim(1) + 1;
706 retval(2) = pos(2) * parent_dim(0);
707 retval(3) = pos(3) * parent_dim(1);
712 else if (from_units.
compare (
"characters"))
721 f = 12.0 * res / 74.951;
725 retval(0) = 0.5 * pos(0) *
f;
726 retval(1) = pos(1) *
f;
729 retval(2) = 0.5 * pos(2) *
f;
730 retval(3) = pos(3) *
f;
743 if (from_units.
compare (
"points"))
745 else if (from_units.
compare (
"inches"))
747 else if (from_units.
compare (
"centimeters"))
752 retval(0) = pos(0) *
f + 1;
753 retval(1) = pos(1) *
f + 1;
756 retval(2) = pos(2) *
f;
757 retval(3) = pos(3) *
f;
764 if (! to_units.
compare (
"pixels"))
766 if (to_units.
compare (
"normalized"))
768 retval(0) = (retval(0) - 1) / parent_dim(0);
769 retval(1) = (retval(1) - 1) / parent_dim(1);
772 retval(2) /= parent_dim(0);
773 retval(3) /= parent_dim(1);
778 else if (to_units.
compare (
"characters"))
785 f = 12.0 * res / 74.951;
789 retval(0) = 2 * retval(0) /
f;
790 retval(1) = retval(1) /
f;
793 retval(2) = 2 * retval(2) /
f;
794 retval(3) = retval(3) /
f;
807 if (to_units.
compare (
"points"))
809 else if (to_units.
compare (
"inches"))
811 else if (to_units.
compare (
"centimeters"))
816 retval(0) = (retval(0) - 1) /
f;
817 retval(1) = (retval(1) - 1) /
f;
839 graphics_object go = gh_mgr.get_object (props.get___myhandle__ ());
841 graphics_object ax = go.get_ancestor (
"axes");
845 if (ax.valid_object ())
849 graphics_xform ax_xform = ax_props.get_transform ();
850 bool is_rectangle = (pos.
numel () == 4);
851 Matrix ax_bbox = ax_props.get_boundingbox (
true),
852 ax_size = ax_bbox.
extract_n (0, 2, 1, 2);
854 if (from_units.
compare (
"data"))
858 ColumnVector v1 = ax_xform.transform (pos(0), pos(1), 0),
859 v2 = ax_xform.transform (pos(0) + pos(2),
864 retval(0) = v1(0) - ax_bbox(0) + 1;
865 retval(1) = ax_bbox(1) + ax_bbox(3) - v1(1) + 1;
866 retval(2) =
v2(0) - v1(0);
867 retval(3) = v1(1) -
v2(1);
871 ColumnVector v = ax_xform.transform (pos(0), pos(1), pos(2));
875 retval(0) = v(0) - ax_bbox(0) + 1;
876 retval(1) = ax_bbox(1) + ax_bbox(3) - v(1) + 1;
883 if (! to_units.
compare (
"pixels"))
890 v1 = ax_xform.untransform (retval(0) + ax_bbox(0) - 1,
891 ax_bbox(1) + ax_bbox(3) - retval(1) + 1);
892 v2 = ax_xform.untransform (retval(0) + retval(2) + ax_bbox(0) - 1,
893 ax_bbox(1) + ax_bbox(3) - (retval(1) + retval(3)) + 1);
899 retval(2) =
v2(0) - v1(0);
900 retval(3) =
v2(1) - v1(1);
905 v = ax_xform.untransform (retval(0) + ax_bbox(0) - 1,
906 ax_bbox(1) + ax_bbox(3) - retval(1) + 1);
929 graphics_object obj = gh_mgr.get_object (0);
931 Matrix sz = obj.get (
"screensize").matrix_value ();
944 graphics_object fig = gh_mgr.get_object (h).get_ancestor (
"figure");
946 if (fig.valid_object ())
947 retval = fig.get (
"__device_pixel_ratio__").double_value ();
978 av[i+lda] = cmapv[idx+nc];
979 av[i+2*lda] = cmapv[idx+2*nc];
983 template <
typename T>
991 clim_0, clim_1, cmapv, cv[i], lda, nc, i, av);
996 bool is_scaled,
int cdim)
1001 if (dv.
ndims () == cdim && dv(cdim-1) == 3)
1009 graphics_object go = gh_mgr.get_object (props.get___myhandle__ ());
1010 graphics_object ax = go.get_ancestor (
"axes");
1012 if (ax.valid_object ())
1035 const double *cmapv = cmap.
data ();
1037 double clim_0 = clim(0);
1038 double clim_1 = clim(1);
1048 #define CONVERT_CDATA_1(ARRAY_T, VAL_FN, IS_REAL) \
1051 ARRAY_T tmp = cdata. VAL_FN ## array_value (); \
1053 convert_cdata_1 (is_scaled, IS_REAL, clim_0, clim_1, cmapv, \
1054 tmp.data (), lda, nc, av); \
1083 warning (
"unsupported type for cdata (= %s). "
1084 "Valid types are int8, int16, int32, int64, uint8, uint16, "
1085 "uint32, uint64, double, single, and bool.",
1090 #undef CONVERT_CDATA_1
1095 template <
typename T>
1098 double& eminp,
double& emaxp)
1100 const T *data =
m.data ();
1105 double e = double (data[i]);
1116 if (e > 0 && e < eminp)
1119 if (e < 0 && e > emaxp)
1129 int len = name.length ();
1131 bool result =
false;
1142 pfx = name.substr (0, 5);
1148 pfx = name.substr (0, 6);
1154 pfx = name.substr (0, 7);
1162 pfx = name.substr (0, 9);
1169 pfx = name.substr (0, 10);
1171 if (pfx.
compare (
"uipushtool"))
1175 pfx = name.substr (0, 12);
1177 if (pfx.
compare (
"uitoggletool"))
1181 pfx = name.substr (0, 13);
1183 if (pfx.
compare (
"uicontextmenu")
1184 || pfx.
compare (
"uibuttongroup"))
1197 rest = name.substr (offset);
1205 static base_graphics_object *
1210 base_graphics_object *go =
nullptr;
1213 go =
new figure (h, p);
1214 else if (type.
compare (
"axes"))
1215 go =
new axes (h, p);
1216 else if (type.
compare (
"line"))
1217 go =
new line (h, p);
1218 else if (type.
compare (
"text"))
1219 go =
new text (h, p);
1220 else if (type.
compare (
"image"))
1221 go =
new image (h, p);
1222 else if (type.
compare (
"light"))
1223 go =
new light (h, p);
1224 else if (type.
compare (
"patch"))
1225 go =
new patch (h, p);
1226 else if (type.
compare (
"scatter"))
1227 go =
new scatter (h, p);
1228 else if (type.
compare (
"surface"))
1229 go =
new surface (h, p);
1230 else if (type.
compare (
"hggroup"))
1231 go =
new hggroup (h, p);
1232 else if (type.
compare (
"uimenu"))
1233 go =
new uimenu (h, p);
1234 else if (type.
compare (
"uicontrol"))
1235 go =
new uicontrol (h, p);
1236 else if (type.
compare (
"uipanel"))
1237 go =
new uipanel (h, p);
1238 else if (type.
compare (
"uibuttongroup"))
1239 go =
new uibuttongroup (h, p);
1240 else if (type.
compare (
"uicontextmenu"))
1241 go =
new uicontextmenu (h, p);
1242 else if (type.
compare (
"uitable"))
1243 go =
new uitable (h, p);
1244 else if (type.
compare (
"uitoolbar"))
1245 go =
new uitoolbar (h, p);
1246 else if (type.
compare (
"uipushtool"))
1247 go =
new uipushtool (h, p);
1248 else if (type.
compare (
"uitoggletool"))
1249 go =
new uitoggletool (h, p);
1256 base_property::set (
const octave_value& v,
bool do_run,
bool do_notify_toolkit)
1261 if (m_id >= 0 && do_notify_toolkit)
1265 graphics_object go = gh_mgr.get_object (m_parent);
1272 run_listeners (GCB_POSTSET);
1281 base_property::run_listeners (listener_mode mode)
1287 for (
int i = 0; i < l.
length (); i++)
1288 gh_mgr.execute_listener (m_parent, l(i));
1291 radio_values::radio_values (
const std::string& opt_string)
1292 : m_default_val (), m_possible_vals ()
1294 std::size_t beg = 0;
1295 std::size_t
len = opt_string.length ();
1296 bool done =
len == 0;
1300 std::size_t end = opt_string.find (
'|', beg);
1302 if (end == std::string::npos)
1308 std::string t = opt_string.substr (beg, end-beg);
1311 if (t.empty () && opt_string[beg] ==
'|')
1320 t = t.substr (1, t.length () - 2);
1326 m_possible_vals.insert (t);
1333 radio_values::values_as_string (
void)
const
1337 for (
const auto& val : m_possible_vals)
1339 if (retval.empty ())
1341 if (val == default_value ())
1342 retval =
'{' + val +
'}';
1348 if (val == default_value ())
1349 retval +=
" | {" + val +
'}';
1351 retval +=
" | " + val;
1355 if (! retval.empty ())
1356 retval =
"[ " + retval +
" ]";
1362 radio_values::values_as_cell (
void)
const
1365 Cell retval (nelem (), 1);
1367 for (
const auto& val : m_possible_vals)
1368 retval(i++) = std::string (val);
1374 color_values::str2rgb (
const std::string& str_arg)
1378 double tmp_rgb[3] = {0, 0, 0};
1380 std::string str = str_arg;
1381 unsigned int len = str.length ();
1383 std::transform (str.begin (), str.end (), str.begin (), tolower);
1386 if (str.compare (0,
len,
"blue", 0,
len) == 0)
1388 else if (str.compare (0,
len,
"black", 0,
len) == 0
1389 || str.compare (0,
len,
"k", 0,
len) == 0)
1390 tmp_rgb[0] = tmp_rgb[1] = tmp_rgb[2] = 0;
1391 else if (str.compare (0,
len,
"red", 0,
len) == 0)
1393 else if (str.compare (0,
len,
"green", 0,
len) == 0)
1395 else if (str.compare (0,
len,
"yellow", 0,
len) == 0)
1396 tmp_rgb[0] = tmp_rgb[1] = 1;
1397 else if (str.compare (0,
len,
"magenta", 0,
len) == 0)
1398 tmp_rgb[0] = tmp_rgb[2] = 1;
1399 else if (str.compare (0,
len,
"cyan", 0,
len) == 0)
1400 tmp_rgb[1] = tmp_rgb[2] = 1;
1401 else if (str.compare (0,
len,
"white", 0,
len) == 0
1402 || str.compare (0,
len,
"w", 0,
len) == 0)
1403 tmp_rgb[0] = tmp_rgb[1] = tmp_rgb[2] = 1;
1404 else if (str[0] ==
'#' &&
len == 7)
1408 tmp_rgb[0] =
static_cast<double> (stoi (str.substr (1, 2),
nullptr, 16))
1410 tmp_rgb[1] =
static_cast<double> (stoi (str.substr (3, 2),
nullptr, 16))
1412 tmp_rgb[2] =
static_cast<double> (stoi (str.substr (5, 2),
nullptr, 16))
1415 catch (
const octave::execution_exception&)
1420 else if (str[0] ==
'#' &&
len == 4)
1424 tmp_rgb[0] =
static_cast<double> (stoi (str.substr (1, 1),
nullptr, 16))
1426 tmp_rgb[1] =
static_cast<double> (stoi (str.substr (2, 1),
nullptr, 16))
1428 tmp_rgb[2] =
static_cast<double> (stoi (str.substr (3, 1),
nullptr, 16))
1431 catch (
const octave::execution_exception&)
1441 for (
int i = 0; i < 3; i++)
1442 m_rgb(i) = tmp_rgb[i];
1456 error (R
"(invalid value for color property "%s")",
1457 get_name ().c_str ());
1461 if (m_radio_val.contains (s, match))
1463 if (m_current_type != radio_t || match != m_current_val)
1465 if (s.length () != match.length ())
1467 "%s: allowing %s to match %s value %s",
1468 "set", s.c_str (), get_name ().c_str (),
1470 m_current_val = match;
1471 m_current_type = radio_t;
1479 color_values col (s);
1481 if (m_current_type != color_t || col != m_color_val)
1484 m_current_type = color_t;
1488 catch (octave::execution_exception& ee)
1490 error (ee, R
"(invalid value for color property "%s" (value = %s))",
1491 get_name ().c_str (), s.c_str ());
1499 if (
m.numel () != 3)
1500 error (R
"(invalid value for color property "%s")",
1501 get_name ().c_str ());
1503 color_values col (m(0), m(1), m(2));
1505 if (m_current_type != color_t || col != m_color_val)
1508 m_current_type = color_t;
1513 error (R
"(invalid value for color property "%s")",
1514 get_name ().c_str ());
1520 double_radio_property::do_set (
const octave_value& val)
1527 if (s.empty () || ! m_radio_val.contains (s, match))
1528 error (R
"(invalid value for double_radio property "%s")",
1529 get_name ().c_str ());
1531 if (m_current_type != radio_t || match != m_current_val)
1533 if (s.length () != match.length ())
1535 "%s: allowing %s to match %s value %s",
1536 "set", s.c_str (), get_name ().c_str (),
1538 m_current_val = match;
1539 m_current_type = radio_t;
1547 if (m_current_type != double_t || new_dval != m_dval)
1550 m_current_type = double_t;
1555 error (R
"(invalid value for double_radio property "%s")",
1556 get_name ().c_str ());
1567 if (m_type_constraints.size () > 0)
1569 if (m_type_constraints.find (v.
class_name ()) != m_type_constraints.end ())
1574 if (m_type_constraints.find (
"real") != m_type_constraints.end ()
1581 if (xok && m_size_constraints.size () > 0)
1584 int vlen = vdims.
ndims ();
1589 for (
auto it = m_size_constraints.cbegin ();
1590 ! xok && it != m_size_constraints.cend ();
1595 if (itdims.
ndims () == vlen)
1599 for (
int i = 0; xok && i < vlen; i++)
1603 if (itdims(i) != vdims(i))
1606 else if (itdims(i) == 0)
1624 if (m_minval.second && m_minval.first > v_mat(i))
1625 error (R
"(set: "%s" must be greater than or equal to %g)",
1626 get_name ().c_str (), m_minval.first);
1627 else if (! m_minval.second && m_minval.first >= v_mat(i))
1628 error (R
"(set: "%s" must be greater than %g)",
1629 get_name ().c_str (), m_minval.first);
1635 if (m_maxval.second && m_maxval.first < v_mat(i))
1636 error (R
"(set: "%s" must be less than or equal to %g)",
1637 get_name ().c_str (), m_maxval.first);
1638 else if (! m_maxval.second && m_maxval.first <= v_mat(i))
1639 error (R
"(set: "%s" must be less than %g)",
1640 get_name ().c_str (), m_maxval.first);
1643 if (m_finite_constraint == NO_CHECK) { }
1644 else if (m_finite_constraint == FINITE)
1648 error (R
"(set: "%s" must be finite)", get_name ().c_str ());
1650 else if (m_finite_constraint == NOT_NAN)
1654 error (R
"(set: "%s" must not be nan)", get_name ().c_str ());
1656 else if (m_finite_constraint == NOT_INF)
1660 error (R
"(set: "%s" must not be infinite)", get_name ().c_str ());
1671 if (m_data.type_name () == v.
type_name ())
1673 if (m_data.dims () == v.
dims ())
1676 #define CHECK_ARRAY_EQUAL(T, F, A) \
1678 if (m_data.numel () == 1) \
1679 return m_data.F ## scalar_value () == \
1680 v.F ## scalar_value (); \
1686 const A m1 = m_data.F ## array_value (); \
1687 const T *d1 = m1.data (); \
1688 const A m2 = v.F ## array_value (); \
1689 const T *d2 = m2.data (); \
1693 for (int i = 0; flag && i < m_data.numel (); i++) \
1694 if (d1[i] != d2[i]) \
1701 if (m_data.is_double_type () || m_data.islogical ())
1703 else if (m_data.is_single_type ())
1705 else if (m_data.is_int8_type ())
1707 else if (m_data.is_int16_type ())
1709 else if (m_data.is_int32_type ())
1711 else if (m_data.is_int64_type ())
1713 else if (m_data.is_uint8_type ())
1715 else if (m_data.is_uint16_type ())
1717 else if (m_data.is_uint32_type ())
1719 else if (m_data.is_uint64_type ())
1728 array_property::get_data_limits (
void)
1733 if (! m_data.isempty ())
1735 if (m_data.isinteger ())
1737 if (m_data.is_int8_type ())
1739 m_min_val, m_max_val, m_min_pos, m_max_neg);
1740 else if (m_data.is_uint8_type ())
1742 m_min_val, m_max_val, m_min_pos, m_max_neg);
1743 else if (m_data.is_int16_type ())
1745 m_min_val, m_max_val, m_min_pos, m_max_neg);
1746 else if (m_data.is_uint16_type ())
1748 m_min_val, m_max_val, m_min_pos, m_max_neg);
1749 else if (m_data.is_int32_type ())
1751 m_min_val, m_max_val, m_min_pos, m_max_neg);
1752 else if (m_data.is_uint32_type ())
1754 m_min_val, m_max_val, m_min_pos, m_max_neg);
1755 else if (m_data.is_int64_type ())
1757 m_min_val, m_max_val, m_min_pos, m_max_neg);
1758 else if (m_data.is_uint64_type ())
1760 m_min_val, m_max_val, m_min_pos, m_max_neg);
1764 m_min_val, m_max_val, m_min_pos, m_max_neg);
1774 if (! get ().isempty ())
1783 double dv = v.
xdouble_value (R
"(set: invalid graphics handle for property "%s")",
1784 get_name ().c_str ());
1791 bool type_ok =
true;
1792 if (gh.
ok () && ! m_type_constraints.empty ())
1795 graphics_object obj = gh_mgr.get_object (gh);
1797 for (
const auto& type : m_type_constraints)
1808 error (R
"(set: invalid graphics handle (= %g) for property "%s")",
1809 dv, get_name ().c_str ());
1811 error (R
"(set: invalid graphics object type for property "%s")",
1812 get_name ().c_str ());
1815 if (m_current_val != gh)
1843 children_property::do_get_children (
bool return_hidden)
const
1845 Matrix retval (m_children_list.size (), 1);
1850 graphics_object go = gh_mgr.get_object (0);
1855 if (! props.is_showhiddenhandles ())
1857 for (
const auto& hchild : m_children_list)
1861 if (gh_mgr.is_handle_visible (kid))
1863 if (! return_hidden)
1864 retval(k++) = hchild;
1866 else if (return_hidden)
1867 retval(k++) = hchild;
1870 retval.resize (k, 1);
1874 for (
const auto& hchild : m_children_list)
1875 retval(k++) = hchild;
1882 children_property::do_delete_children (
bool clear,
bool from_root)
1890 graphics_object go = gh_mgr.get_object (hchild);
1891 if (go.valid_object ()
1892 && ! go.get_properties ().is_beingdeleted ())
1893 gh_mgr.free (hchild, from_root);
1895 m_children_list.clear ();
1898 while (! m_children_list.empty ())
1902 graphics_object go = gh_mgr.get_object (hchild);
1903 if (go.valid_object ()
1904 && ! go.get_properties ().is_beingdeleted ())
1905 gh_mgr.free (hchild, from_root);
1910 m_children_list.clear ();
1914 callback_property::validate (
const octave_value& v)
const
1952 m_set.insert (
reinterpret_cast<intptr_t
> (ptr));
1955 void erase (
const callback_property *ptr)
1957 m_set.erase (
reinterpret_cast<intptr_t
> (ptr));
1962 return m_set.find (
reinterpret_cast<intptr_t
> (ptr)) !=
m_set.end ();
1977 callback_property::execute (
const octave_value& data)
const
1982 octave::unwind_action executing_callbacks_cleanup
1989 if (m_callback.is_defined () && ! m_callback.isempty ())
1993 gh_mgr.execute_callback (get_parent (), m_callback, data);
2010 std::string sv = (args.
length () > 0 ? args(0).string_value () :
"");
2012 retval = property (
new string_property (name, h, sv));
2014 else if (type.
compare (
"any"))
2019 retval = property (
new any_property (name, h, ov));
2021 else if (type.
compare (
"radio"))
2024 error (
"addproperty: missing possible values for radio property");
2026 std::string sv = args(
2027 0).xstring_value (
"addproperty: argument for radio property must be a string");
2029 retval = property (
new radio_property (name, h, sv));
2032 retval.set (args(1));
2034 else if (type.
compare (
"double"))
2036 double dv = (args.
length () > 0 ? args(0).double_value () : 0.0);
2038 retval = property (
new double_property (name, h, dv));
2040 else if (type.
compare (
"handle"))
2042 double hv = (args.
length () > 0 ? args(0).double_value ()
2047 retval = property (
new handle_property (name, h, gh));
2049 else if (type.
compare (
"boolean"))
2051 retval = property (
new bool_property (name, h,
false));
2054 retval.set (args(0));
2056 else if (type.
compare (
"data"))
2058 retval = property (
new array_property (name, h,
Matrix ()));
2062 retval.set (args(0));
2067 else if (type.
compare (
"color"))
2069 color_values cv (0, 0, 0);
2073 rv = radio_values (args(1).string_value ());
2075 retval = property (
new color_property (name, h, cv, rv));
2077 if (args.
length () > 0 && ! args(0).isempty ())
2078 retval.set (args(0));
2080 retval.set (rv.default_value ());
2087 error (
"addproperty: unsupported type for dynamic property (= %s)",
2092 std::map<caseless_str, graphics_object>::const_iterator it
2101 go = graphics_object (bgo);
2109 if (! go.valid_object ())
2110 error (
"addproperty: invalid object type (= %s)",
2113 property prop = go.get_properties ().get_property (go_rest);
2115 retval = prop.clone ();
2117 retval.set_parent (h);
2118 retval.set_name (name);
2121 retval.set (args(0));
2132 graphics_object go = gh_mgr.get_object (h);
2136 Matrix children = go.get_properties ().get_all_children ();
2138 for (
int k = 0; k < children.
numel (); k++)
2150 graphics_object go = gh_mgr.get_object (h);
2154 Matrix children = go.get_properties ().get_all_children ();
2158 for (
int k = 0; k < children.
numel (); k++)
2164 figure::properties::set_toolkit (
const octave::graphics_toolkit& b)
2170 m___graphics_toolkit__ = b.get_name ();
2171 m___plot_stream__ =
Matrix ();
2180 figure::properties::set___mouse_mode__ (
const octave_value& val_arg)
2182 std::string direction =
"in";
2190 if (modestr ==
"zoom in")
2192 val = modestr =
"zoom";
2195 else if (modestr ==
"zoom out")
2197 val = modestr =
"zoom";
2201 if (m___mouse_mode__.set (val,
true))
2203 std::string mode = m___mouse_mode__.current_value ();
2206 pm.
setfield (
"Enable", mode ==
"pan" ?
"on" :
"off");
2207 set___pan_mode__ (pm);
2210 rm.
setfield (
"Enable", mode ==
"rotate" ?
"on" :
"off");
2211 set___rotate_mode__ (rm);
2214 zm.
setfield (
"Enable", mode ==
"zoom" ?
"on" :
"off");
2215 zm.
setfield (
"Direction", direction);
2216 set___zoom_mode__ (zm);
2220 else if (modestr ==
"zoom")
2223 std::string curr_direction
2226 if (direction != curr_direction)
2228 zm.
setfield (
"Direction", direction);
2229 set___zoom_mode__ (zm);
2238 figure::properties::update_handlevisibility (
void)
2244 octave_value cf = gh_mgr.get_object (0).get (
"currentfigure");
2248 octave::autolock guard (gh_mgr.graphics_lock ());
2250 octave_value kids = gh_mgr.get_object (0).get (
"children");
2253 gh_mgr.get_object (0).set (
"currentfigure",
Matrix ());
2257 gh_mgr.get_object (0).set (
"currentfigure", kidsarray(0));
2262 base_properties::update_handlevisibility ();
2270 graphics_object go = gh_mgr.get_object (h);
2272 if (go.isa (
"text"))
2277 tp.update_text_extent ();
2279 else if (go.isa (
"figure") || go.isa (
"uipanel") || go.isa (
"axes")
2280 || go.isa (
"hggroup"))
2282 Matrix ch = go.get_properties ().get_all_children ();
2286 if (go.isa (
"axes"))
2291 ap.sync_positions ();
2297 figure::properties::update___device_pixel_ratio__ (
void)
2307 std::size_t offset = 0;
2309 std::size_t
len = name.length ();
2320 pfx = name.substr (0, 5);
2326 pfx = name.substr (0, 6);
2332 pfx = name.substr (0, 7);
2340 pfx = name.substr (0, 9);
2347 pfx = name.substr (0, 10);
2349 if (pfx.
compare (
"uipushtool"))
2353 pfx = name.substr (0, 12);
2355 if (pfx.
compare (
"uitoogletool"))
2359 pfx = name.substr (0, 13);
2361 if (pfx.
compare (
"uicontextmenu")
2362 || pfx.
compare (
"uibuttongroup"))
2376 std::string pname = name.substr (offset);
2378 std::transform (pfx.begin (), pfx.end (), pfx.begin (), tolower);
2382 bool has_property =
false;
2384 has_property = axes::properties::has_core_property (pname);
2385 else if (pfx ==
"figure")
2386 has_property = figure::properties::has_core_property (pname);
2387 else if (pfx ==
"line")
2388 has_property = line::properties::has_core_property (pname);
2389 else if (pfx ==
"text")
2390 has_property = text::properties::has_core_property (pname);
2391 else if (pfx ==
"image")
2392 has_property = image::properties::has_core_property (pname);
2393 else if (pfx ==
"patch")
2394 has_property = patch::properties::has_core_property (pname);
2395 else if (pfx ==
"scatter")
2396 has_property = scatter::properties::has_core_property (pname);
2397 else if (pfx ==
"surface")
2398 has_property = surface::properties::has_core_property (pname);
2399 else if (pfx ==
"hggroup")
2400 has_property = hggroup::properties::has_core_property (pname);
2401 else if (pfx ==
"uimenu")
2402 has_property = uimenu::properties::has_core_property (pname);
2403 else if (pfx ==
"uicontrol")
2404 has_property = uicontrol::properties::has_core_property (pname);
2405 else if (pfx ==
"uibuttongroup")
2406 has_property = uibuttongroup::properties::has_core_property (pname);
2407 else if (pfx ==
"uipanel")
2408 has_property = uipanel::properties::has_core_property (pname);
2409 else if (pfx ==
"uicontextmenu")
2410 has_property = uicontextmenu::properties::has_core_property (pname);
2411 else if (pfx ==
"uitable")
2412 has_property = uitable::properties::has_core_property (pname);
2413 else if (pfx ==
"uitoolbar")
2414 has_property = uitoolbar::properties::has_core_property (pname);
2415 else if (pfx ==
"uipushtool")
2416 has_property = uipushtool::properties::has_core_property (pname);
2419 error (
"invalid %s property '%s'", pfx.c_str (), pname.c_str ());
2421 bool remove =
false;
2426 remove = (sval ==
"remove");
2429 pval_map_type& pval_map = m_plist_map[pfx];
2433 auto p = pval_map.find (pname);
2435 if (p != pval_map.end ())
2439 pval_map[pname] = val;
2444 error (
"invalid default property specification");
2452 std::size_t offset = 0;
2454 std::size_t
len = name.length ();
2465 pfx = name.substr (0, 5);
2471 pfx = name.substr (0, 6);
2477 pfx = name.substr (0, 7);
2485 pfx = name.substr (0, 9);
2492 pfx = name.substr (0, 10);
2494 if (pfx.
compare (
"uipushtool"))
2498 pfx = name.substr (0, 12);
2500 if (pfx.
compare (
"uitoggletool"))
2504 pfx = name.substr (0, 13);
2506 if (pfx.
compare (
"uicontextmenu")
2507 || pfx.
compare (
"uibuttongroup"))
2519 std::string pname = name.substr (offset);
2521 std::transform (pfx.begin (), pfx.end (), pfx.begin (), tolower);
2525 plist_map_const_iterator p =
find (pfx);
2529 const pval_map_type& pval_map = p->second;
2531 pval_map_const_iterator q = pval_map.find (pname);
2533 if (q != pval_map.end ())
2543 property_list::as_struct (
const std::string& prefix_arg)
const
2547 for (
auto p = begin (); p != end (); p++)
2549 std::string prefix = prefix_arg + p->first;
2551 for (
const auto& prop_val : p->second)
2552 m.assign (prefix + prop_val.first, prop_val.second);
2563 int nargin = args.
length ();
2566 error (
"graphics_object::set: Nothing to set");
2568 for (
int i = 0; i < nargin; )
2570 if (args(i).isstruct () )
2572 set (args(i).map_value ());
2575 else if (i < nargin - 1)
2577 caseless_str pname = args(i).xstring_value (
"set: argument %d must be a property name", i);
2579 set_value_or_default (pname, val);
2583 error (
"set: invalid number of arguments");
2606 error (
"set: number of names must match number of value columns "
2607 "(%" OCTAVE_IDX_TYPE_FORMAT
" != %" OCTAVE_IDX_TYPE_FORMAT
")",
2617 set_value_or_default (pname, val);
2679 set_value_or_default (pname, val);
2767 graphics_object::set_value_or_default (
const caseless_str& pname,
2776 if (sval ==
"default")
2778 default_val = get_default (pname);
2780 m_rep->set (pname, default_val);
2782 else if (sval ==
"factory")
2784 default_val = get_factory_default (pname);
2786 m_rep->set (pname, default_val);
2791 if (sval == R
"(\default)")
2792 m_rep->set (pname, "default");
2793 else if (sval == R
"(\factory)")
2794 m_rep->set (pname, "factory");
2796 m_rep->set (pname, val);
2800 m_rep->set (pname, val);
2824 static double maxrand = RAND_MAX + 2.0;
2826 return (
rand () + 1.0) / maxrand;
2830 gh_manager::get_handle (
bool integer_figure_handle)
2834 if (integer_figure_handle)
2843 while (m_handle_map.find (retval) != m_handle_map.end ())
2852 auto p = m_handle_free_list.begin ();
2854 if (p != m_handle_free_list.end ())
2857 m_handle_free_list.erase (p);
2875 graphics_object go = gh_mgr.get_object (val);
2877 return go && go.isa (
"figure");
2885 if (h.
value () == 0)
2886 error (
"graphics_handle::free: can't delete root object");
2888 auto p = m_handle_map.find (h);
2890 if (p == m_handle_map.end ())
2891 error (
"graphics_handle::free: invalid object %g", h.
value ());
2893 base_properties& bp = p->second.get_properties ();
2895 if (! p->second.valid_object () || bp.is_beingdeleted ())
2899 graphics_object parent_go =
nullptr;
2901 parent_go = get_object (parent_h);
2903 bp.set_beingdeleted (
true);
2906 p->second.remove_all_listeners ();
2908 bp.delete_children (
true, from_root);
2913 bp.execute_deletefcn ();
2916 p->second.finalize ();
2922 if ((! from_root ||
isfigure (h.
value ())) && parent_go.valid_object ()
2924 parent_go.remove_child (h);
2935 m_handle_map.erase (p);
2938 m_handle_free_list.insert
2947 auto p = m_handle_map.find (old_gh);
2949 if (p == m_handle_map.end ())
2950 error (
"graphics_handle::free: invalid object %g", old_gh.
value ());
2952 graphics_object go = p->second;
2954 m_handle_map.erase (p);
2956 m_handle_map[new_gh] = go;
2958 if (old_gh.
value () < 0)
2962 for (
auto& hfig : m_figure_list)
2978 graphics_object go = gh_mgr.get_object (h);
2980 go.set (pname, val);
2990 graphics_object go = gh_mgr.get_object (h);
3001 graphics_object go = gh_mgr.get_object (h);
3003 return go.get (pname);
3011 double hv = ov.
xdouble_value (
"%s: %s must be a graphics handle",
3012 who.c_str (), pname.c_str ());
3019 error (
"%s: invalid graphics handle (= %g) for %s",
3020 who.c_str (), hv, pname.c_str ());
3022 graphics_object go = gh_mgr.get_object (h);
3026 graphics_object parent_go = gh_mgr.get_object (parent_h);
3028 parent_go.remove_child (h);
3031 go.set (
"parent", new_parent.
value ());
3033 go.reparent (new_parent);
3065 graphics_object go = gh_mgr.get_object (h);
3068 if (! go.get_properties ().is_beingdeleted ())
3073 gh_mgr.free (h, from_root || go.isa (
"figure"));
3108 gh_mgr.execute_callback (h, closerequestfcn);
3124 gh_manager::close_all_figures (
void)
3128 m_event_queue.clear ();
3133 Matrix hlist = figure_handle_list (
true);
3145 hlist = figure_handle_list (
true);
3157 hlist = figure_handle_list (
true);
3159 if (hlist.
numel () != 0)
3160 warning (
"gh_manager::close_all_figures: some graphics elements failed to close");
3164 m_callback_objects.clear ();
3172 graphics_object parent_go = gh_mgr.get_object (parent_h);
3174 parent_go.adopt (h);
3220 graphics_object go = gh_mgr.get_object (h);
3222 go.get_properties ().execute_createfcn ();
3230 graphics_object go = gh_mgr.get_object (h);
3250 else if (
state == 2)
3258 property_list::pval_map_type factory_pval)
3262 graphics_object go = gh_mgr.get_object (h);
3265 std::string go_name = go.get_properties ().graphics_object_name ();
3266 property_list::pval_map_type pval;
3267 go.build_user_defaults_map (pval, go_name);
3269 for (
const auto& p : pval)
3270 factory_pval[p.first] = p.second;
3276 for (
const auto& p : factory_pval)
3278 std::string pname = p.first;
3281 if (! go.has_readonly_property (pname)
3282 && pname.find (
"__") != 0 && pname.find (
"current") != 0
3283 && pname !=
"uicontextmenu" && pname !=
"parent")
3286 if (pname.find (
"mode") == (pname.length () - 4))
3287 pval[pname] = p.second;
3289 go.set (pname, p.second);
3294 for (
const auto& p : pval)
3295 go.set (p.first, p.second);
3303 base_properties::set_from_list (base_graphics_object& bgo,
3304 property_list& defaults)
3306 std::string go_name = graphics_object_name ();
3308 property_list::plist_map_const_iterator plist = defaults.find (go_name);
3310 if (plist != defaults.end ())
3312 const property_list::pval_map_type pval_map = plist->second;
3314 for (
const auto& prop_val : pval_map)
3316 std::string pname = prop_val.first;
3320 bgo.set (pname, prop_val.second);
3322 catch (octave::execution_exception& ee)
3324 error (ee,
"error setting default property %s", pname.c_str ());
3347 base_properties::get_dynamic (
const caseless_str& pname)
const
3349 std::map<caseless_str, property, cmp_caseless_str>::const_iterator it
3350 = m_all_props.find (pname);
3352 if (it == m_all_props.end ())
3353 error (R
"(get: unknown property "%s")", pname.c_str ());
3355 return it->second.get ();
3359 base_properties::get_dynamic (
bool all)
const
3363 for (std::map<caseless_str, property, cmp_caseless_str>::const_iterator
3364 it = m_all_props.begin (); it != m_all_props.end (); ++it)
3365 if (all || ! it->second.is_hidden ())
3366 m.assign (it->second.get_name (), it->second.get ());
3371 std::set<std::string>
3372 base_properties::dynamic_property_names (
void)
const
3374 return m_dynamic_properties;
3378 base_properties::has_dynamic_property (
const std::string& pname)
const
3380 const std::set<std::string>& dynprops = dynamic_property_names ();
3382 if (dynprops.find (pname) != dynprops.end ())
3385 return m_all_props.find (pname) != m_all_props.end ();
3389 base_properties::set_dynamic (
const caseless_str& pname,
3392 auto it = m_all_props.find (pname);
3394 if (it == m_all_props.end ())
3395 error (R
"(set: unknown property "%s")", pname.c_str ());
3397 it->second.set (val);
3399 m_dynamic_properties.insert (pname);
3405 base_properties::get_property_dynamic (
const caseless_str& pname)
const
3407 std::map<caseless_str, property, cmp_caseless_str>::const_iterator it
3408 = m_all_props.find (pname);
3410 if (it == m_all_props.end ())
3411 error (R
"(get_property: unknown property "%s")", pname.c_str ());
3419 double hp = val.
xdouble_value (
"set: parent must be a graphics handle");
3420 if (hp == m___myhandle__)
3421 error (
"set: can not set object parent to be object itself");
3426 if (! new_parent.
ok ())
3427 error (
"set: invalid graphics handle (= %g) for parent", hp);
3430 graphics_object old_parent_go;
3431 old_parent_go = gh_mgr.get_object (get_parent ());
3433 if (old_parent_go.get_handle () != hp)
3434 old_parent_go.remove_child (m___myhandle__);
3439 graphics_object new_parent_go;
3440 new_parent_go = gh_mgr.get_object (new_parent);
3441 if (new_parent_go.get_parent () == m___myhandle__)
3444 new_parent_go.get_properties ().set_parent (get_parent ().as_octave_value ());
3465 base_properties::mark_modified (
void)
3468 m___modified__ =
"on";
3474 graphics_object parent_go = gh_mgr.get_object (get_parent ());
3477 parent_go.mark_modified ();
3481 base_properties::override_defaults (base_graphics_object& obj)
3485 graphics_object parent_go = gh_mgr.get_object (get_parent ());
3488 parent_go.override_defaults (obj);
3492 base_properties::update_axis_limits (
const std::string& axis_type)
const
3496 graphics_object go = gh_mgr.get_object (m___myhandle__);
3499 go.update_axis_limits (axis_type);
3503 base_properties::update_axis_limits (
const std::string& axis_type,
3508 graphics_object go = gh_mgr.get_object (m___myhandle__);
3511 go.update_axis_limits (axis_type, h);
3515 base_properties::update_contextmenu (
void)
const
3517 if (m_contextmenu.get ().isempty ())
3522 graphics_object go = gh_mgr.get_object (m_contextmenu.get ());
3524 if (go && go.isa (
"uicontextmenu"))
3528 props.add_dependent_obj (m___myhandle__);
3535 return (m_handlevisibility.is (
"on")
3539 octave::graphics_toolkit
3540 base_properties::get_toolkit (
void)
const
3544 graphics_object go = gh_mgr.get_object (get_parent ());
3547 return go.get_toolkit ();
3549 return octave::graphics_toolkit ();
3553 base_properties::update_boundingbox (
void)
3555 Matrix kids = get_children ();
3559 for (
int i = 0; i < kids.
numel (); i++)
3561 graphics_object go = gh_mgr.get_object (kids(i));
3563 if (go.valid_object ())
3564 go.get_properties ().update_boundingbox ();
3569 base_properties::update_autopos (
const std::string& elem_type)
3573 graphics_object parent_go = gh_mgr.get_object (get_parent ());
3575 if (parent_go.valid_object ())
3576 parent_go.get_properties ().update_autopos (elem_type);
3580 base_properties::update_handlevisibility (
void)
3589 graphics_object go (gh_mgr.get_object (get___myhandle__ ()));
3591 graphics_object fig (go.get_ancestor (
"figure"));
3593 if (fig.valid_object ())
3598 octave::autolock guard (gh_mgr.graphics_lock ());
3601 fig_props.set_currentobject (
Matrix ());
3645 base_properties::add_listener (
const caseless_str& pname,
3649 property p = get_property (pname);
3652 p.add_listener (val, mode);
3656 base_properties::delete_listener (
const caseless_str& pname,
3660 property p = get_property (pname);
3663 p.delete_listener (val, mode);
3667 base_properties::get_children_of_type (
const caseless_str& chtype,
3670 std::list<graphics_object>& children_list)
const
3674 Matrix ch = get_children ();
3682 graphics_object go = gh_mgr.get_object (hkid);
3683 if ( get_invisible || go.get_properties ().is_visible () )
3685 if (go.isa (chtype))
3686 children_list.push_back (go);
3687 else if (traverse && go.isa (
"hggroup"))
3688 go.get_properties ().get_children_of_type (chtype,
3700 base_graphics_object::update_axis_limits (
const std::string& axis_type)
3702 if (! valid_object ())
3703 error (
"base_graphics_object::update_axis_limits: invalid graphics object");
3707 graphics_object parent_go = gh_mgr.get_object (get_parent ());
3710 parent_go.update_axis_limits (axis_type);
3714 base_graphics_object::update_axis_limits (
const std::string& axis_type,
3717 if (! valid_object ())
3718 error (
"base_graphics_object::update_axis_limits: invalid graphics object");
3722 graphics_object parent_go = gh_mgr.get_object (get_parent ());
3725 parent_go.update_axis_limits (axis_type, h);
3729 base_graphics_object::remove_all_listeners (
void)
3735 for (
const auto& pm :
m)
3741 octave::unwind_protect frame;
3747 property p = get_properties ().get_property (pm.first);
3750 p.delete_listener ();
3752 catch (
const octave::execution_exception&)
3756 interp.recover_from_exception ();
3762 base_graphics_object::build_user_defaults_map (property_list::pval_map_type& def,
3763 const std::string go_name)
const
3765 property_list local_defaults = get_defaults_list ();
3766 const auto it = local_defaults.find (go_name);
3768 if (it != local_defaults.end ())
3770 property_list::pval_map_type pval_lst = it->second;
3771 for (
const auto& prop_val : pval_lst)
3773 std::string pname = prop_val.first;
3774 if (def.find (pname) == def.end ())
3775 def[pname] = prop_val.second;
3781 graphics_object parent_go = gh_mgr.get_object (get_parent ());
3784 parent_go.build_user_defaults_map (def, go_name);
3788 base_graphics_object::reset_default_properties (
void)
3790 if (valid_object ())
3794 property_list::pval_map_type factory_pval
3795 = gh_mgr.get_object (0).get_factory_defaults_list ().find (type ())->second;
3797 remove_all_listeners ();
3803 base_graphics_object::values_as_string (
void)
3805 if (! valid_object ())
3806 error (
"base_graphics_object::values_as_string: invalid graphics object");
3813 graphics_object go = gh_mgr.get_object (get_handle ());
3815 for (
const auto& pm :
m)
3817 const auto& pname = pm.first;
3818 if (pname !=
"children" && ! go.has_readonly_property (pname))
3820 property p = get_properties ().get_property (pname);
3822 if (p.ok () && ! p.is_hidden ())
3824 retval +=
"\n\t" + std::string (pname) +
": ";
3826 retval += p.values_as_string ();
3831 if (! retval.empty ())
3838 base_graphics_object::value_as_string (
const std::string& prop)
3842 if (! valid_object ())
3843 error (
"base_graphics_object::value_as_string: invalid graphics object");
3847 graphics_object go = gh_mgr.get_object (get_handle ());
3849 if (prop !=
"children" && ! go.has_readonly_property (prop))
3851 property p = get_properties ().get_property (prop);
3853 if (p.ok () && ! p.is_hidden ())
3856 retval += p.values_as_string ();
3860 if (! retval.empty ())
3867 base_graphics_object::values_as_struct (
void)
3871 if (! valid_object ())
3872 error (
"base_graphics_object::values_as_struct: invalid graphics object");
3878 graphics_object go = gh_mgr.get_object (get_handle ());
3880 for (
const auto& pm :
m)
3882 const auto& pname = pm.first;
3883 if (pname !=
"children" && ! go.has_readonly_property (pname))
3885 property p = get_properties ().get_property (pname);
3887 if (p.ok () && ! p.is_hidden ())
3890 retval.
assign (p.get_name (), p.values_as_cell ());
3921 graphics_object::get_ancestor (
const std::string& obj_type)
const
3923 if (valid_object ())
3931 return gh_mgr.get_object (get_parent ()).get_ancestor (obj_type);
3935 return graphics_object ();
3940 #include "graphics-props.cc"
3945 root_figure::properties::set_callbackobject (
const octave_value& v)
3952 m_callbackobject = val;
3958 root_figure::properties::set_currentfigure (
const octave_value& v)
3964 m_currentfigure = val;
3970 gh_mgr.push_figure (val);
3978 figure::properties::set_integerhandle (
const octave_value& val)
3980 if (m_integerhandle.set (val,
true))
3982 bool int_fig_handle = m_integerhandle.is_on ();
3986 graphics_object this_go = gh_mgr.get_object (m___myhandle__);
3990 m___myhandle__ = gh_mgr.get_handle (int_fig_handle);
3992 gh_mgr.renumber_figure (old_myhandle, m___myhandle__);
3994 graphics_object parent_go = gh_mgr.get_object (get_parent ());
3996 base_properties& props = parent_go.get_properties ();
3998 props.renumber_child (old_myhandle, m___myhandle__);
4000 Matrix kids = get_children ();
4004 graphics_object kid = gh_mgr.get_object (kids(i));
4006 kid.get_properties ().renumber_parent (m___myhandle__);
4011 if (m___myhandle__ == cf)
4012 xset (0,
"currentfigure", m___myhandle__.value ());
4014 this_go.update (m_integerhandle.get_id ());
4023 root_figure::properties::update_units (
void)
4025 std::string xunits = get_units ();
4029 double dpi = get_screenpixelsperinch ();
4031 if (xunits ==
"pixels")
4036 else if (xunits ==
"normalized")
4038 scrn_sz =
Matrix (1, 4, 1.0);
4042 else if (xunits ==
"inches")
4049 else if (xunits ==
"centimeters")
4053 scrn_sz(2) *= 2.54 / dpi;
4054 scrn_sz(3) *= 2.54 / dpi;
4056 else if (xunits ==
"points")
4060 scrn_sz(2) *= 72 / dpi;
4061 scrn_sz(3) *= 72 / dpi;
4063 else if (xunits ==
"characters")
4069 scrn_sz(2) *= 74.951 / 12.0 / dpi;
4070 scrn_sz(3) *= 74.951 / 12.0 / dpi;
4073 set_screensize (scrn_sz);
4077 root_figure::properties::get_boundingbox (
bool,
const Matrix&)
const
4082 pos(2) = screen_size(0);
4083 pos(3) = screen_size(1);
4114 root_figure::properties::remove_child (
const graphics_handle& h,
bool)
4118 gh_mgr.pop_figure (h);
4124 base_properties::remove_child (h,
true);
4128 root_figure::reset_default_properties (
void)
4131 m_default_properties = property_list ();
4133 remove_all_listeners ();
4135 m_properties.factory_defaults ());
4141 figure::properties::set_currentaxes (
const octave_value& val)
4146 m_currentaxes = hax;
4152 figure::properties::remove_child (
const graphics_handle& h,
bool from_root)
4154 base_properties::remove_child (h, from_root);
4156 if (h == m_currentaxes.handle_value ())
4160 Matrix kids = get_children ();
4168 graphics_object go = gh_mgr.get_object (kid);
4170 if (go.isa (
"axes"))
4172 new_currentaxes = kid;
4177 m_currentaxes = new_currentaxes;
4182 figure::properties::get_number (
void)
const
4184 if (m_integerhandle.is_on ())
4185 return m___myhandle__.value ();
4190 octave::graphics_toolkit
4191 figure::properties::get_toolkit (
void)
const
4197 figure::properties::set___graphics_toolkit__ (
const octave_value& val)
4200 error (
"set___graphics_toolkit__: toolkit must be a string");
4206 octave::graphics_toolkit b = gtk_mgr.find_toolkit (nm);
4208 if (b.get_name () != nm)
4209 error (
"set___graphics_toolkit__: invalid graphics toolkit");
4211 if (nm != get___graphics_toolkit__ ())
4223 if (! get_currentaxes ().ok ())
4227 graphics_object go = gh_mgr.get_object (h);
4229 if (go.type () ==
"axes")
4253 figure::properties::set_visible (
const octave_value& val)
4258 xset (0,
"currentfigure", m___myhandle__.value ());
4264 figure::properties::get_boundingbox (
bool internal,
const Matrix&)
const
4268 get_position ().matrix_value () :
4269 get_outerposition ().matrix_value ());
4275 pos(1) = screen_size(1) - pos(1) - pos(3);
4281 figure::properties::bbox2position (
const Matrix& bb)
const
4286 pos(1) = screen_size(1) - pos(1) - pos(3);
4294 figure::properties::set_boundingbox (
const Matrix& bb,
bool internal,
4295 bool do_notify_toolkit)
4298 Matrix pos = bbox2position (bb);
4301 set_position (pos, do_notify_toolkit);
4303 set_outerposition (pos, do_notify_toolkit);
4307 figure::properties::map_from_boundingbox (
double x,
double y)
const
4309 Matrix bb = get_boundingbox (
true);
4315 pos(1) = bb(3) - pos(1);
4324 figure::properties::map_to_boundingbox (
double x,
double y)
const
4326 Matrix bb = get_boundingbox (
true);
4335 pos(1) = bb(3) - pos(1);
4341 figure::properties::set_position (
const octave_value& v,
4342 bool do_notify_toolkit)
4345 bool modified =
false;
4347 old_bb = get_boundingbox (
true);
4348 modified = m_position.set (v,
false, do_notify_toolkit);
4349 new_bb = get_boundingbox (
true);
4351 if (old_bb != new_bb)
4353 if (old_bb(2) != new_bb(2) || old_bb(3) != new_bb(3))
4357 if (! get_resizefcn ().isempty ())
4358 gh_mgr.post_callback (m___myhandle__,
"resizefcn");
4360 if (! get_sizechangedfcn ().isempty ())
4361 gh_mgr.post_callback (m___myhandle__,
"sizechangedfcn");
4363 update_boundingbox ();
4369 m_position.run_listeners (GCB_POSTSET);
4373 if (m_paperpositionmode.is (
"auto"))
4374 m_paperposition.set (get_auto_paperposition ());
4378 figure::properties::set_outerposition (
const octave_value& v,
4379 bool do_notify_toolkit)
4381 if (m_outerposition.set (v,
true, do_notify_toolkit))
4386 figure::properties::set_paperunits (
const octave_value& val)
4392 error (
"set: can't set paperunits to normalized when papertype is custom");
4395 if (m_paperunits.set (val,
true))
4397 update_paperunits (old_paperunits);
4403 figure::properties::set_papertype (
const octave_value& val)
4409 error (
"set: can't set paperunits to normalized when papertype is custom");
4411 if (m_papertype.set (val,
true))
4413 update_papertype ();
4421 Matrix retval (1, 2, 1.0);
4423 if (! punits.
compare (
"normalized"))
4428 if (punits.
compare (
"inches"))
4431 mm2units = 1 / 25.4;
4433 else if (punits.
compare (
"centimeters"))
4436 mm2units = 1 / 10.0;
4441 mm2units = 72.0 / 25.4;
4444 if (ptype.
compare (
"usletter"))
4446 retval(0) = 8.5 * in2units;
4447 retval(1) = 11.0 * in2units;
4449 else if (ptype.
compare (
"uslegal"))
4451 retval(0) = 8.5 * in2units;
4452 retval(1) = 14.0 * in2units;
4454 else if (ptype.
compare (
"tabloid"))
4456 retval(0) = 11.0 * in2units;
4457 retval(1) = 17.0 * in2units;
4459 else if (ptype.
compare (
"a0"))
4461 retval(0) = 841.0 * mm2units;
4462 retval(1) = 1189.0 * mm2units;
4464 else if (ptype.
compare (
"a1"))
4466 retval(0) = 594.0 * mm2units;
4467 retval(1) = 841.0 * mm2units;
4469 else if (ptype.
compare (
"a2"))
4471 retval(0) = 420.0 * mm2units;
4472 retval(1) = 594.0 * mm2units;
4474 else if (ptype.
compare (
"a3"))
4476 retval(0) = 297.0 * mm2units;
4477 retval(1) = 420.0 * mm2units;
4479 else if (ptype.
compare (
"a4"))
4481 retval(0) = 210.0 * mm2units;
4482 retval(1) = 297.0 * mm2units;
4484 else if (ptype.
compare (
"a5"))
4486 retval(0) = 148.0 * mm2units;
4487 retval(1) = 210.0 * mm2units;
4489 else if (ptype.
compare (
"b0"))
4491 retval(0) = 1029.0 * mm2units;
4492 retval(1) = 1456.0 * mm2units;
4494 else if (ptype.
compare (
"b1"))
4496 retval(0) = 728.0 * mm2units;
4497 retval(1) = 1028.0 * mm2units;
4499 else if (ptype.
compare (
"b2"))
4501 retval(0) = 514.0 * mm2units;
4502 retval(1) = 728.0 * mm2units;
4504 else if (ptype.
compare (
"b3"))
4506 retval(0) = 364.0 * mm2units;
4507 retval(1) = 514.0 * mm2units;
4509 else if (ptype.
compare (
"b4"))
4511 retval(0) = 257.0 * mm2units;
4512 retval(1) = 364.0 * mm2units;
4514 else if (ptype.
compare (
"b5"))
4516 retval(0) = 182.0 * mm2units;
4517 retval(1) = 257.0 * mm2units;
4519 else if (ptype.
compare (
"arch-a"))
4521 retval(0) = 9.0 * in2units;
4522 retval(1) = 12.0 * in2units;
4524 else if (ptype.
compare (
"arch-b"))
4526 retval(0) = 12.0 * in2units;
4527 retval(1) = 18.0 * in2units;
4529 else if (ptype.
compare (
"arch-c"))
4531 retval(0) = 18.0 * in2units;
4532 retval(1) = 24.0 * in2units;
4534 else if (ptype.
compare (
"arch-d"))
4536 retval(0) = 24.0 * in2units;
4537 retval(1) = 36.0 * in2units;
4539 else if (ptype.
compare (
"arch-e"))
4541 retval(0) = 36.0 * in2units;
4542 retval(1) = 48.0 * in2units;
4546 retval(0) = 8.5 * in2units;
4547 retval(1) = 11.0 * in2units;
4551 retval(0) = 11.0 * in2units;
4552 retval(1) = 17.0 * in2units;
4556 retval(0) = 17.0 * in2units;
4557 retval(1) = 22.0 * in2units;
4561 retval(0) = 22.0 * in2units;
4562 retval(1) = 34.0 * in2units;
4566 retval(0) = 34.0 * in2units;
4567 retval(1) = 43.0 * in2units;
4575 figure::properties::get_auto_paperposition (
void)
4577 Matrix pos = get_position ().matrix_value ();
4584 if (funits ==
"normalized" || punits ==
"normalized")
4589 if (punits ==
"normalized")
4598 sz = get_papersize ().matrix_value ();
4600 pos(0) = sz(0)/2 - pos(2)/2;
4601 pos(1) = sz(1)/2 - pos(3)/2;
4690 figure::properties::update_paperunits (
const caseless_str& old_paperunits)
4692 Matrix pos = get_paperposition ().matrix_value ();
4693 Matrix sz = get_papersize ().matrix_value ();
4700 std::string porient = get_paperorientation ();
4704 if (ptype.
compare (
"<custom>"))
4706 if (old_paperunits.
compare (
"centimeters"))
4711 else if (old_paperunits.
compare (
"points"))
4717 if (punits.
compare (
"centimeters"))
4722 else if (punits.
compare (
"points"))
4731 if (porient ==
"landscape")
4732 std::swap (sz(0), sz(1));
4745 figure::properties::update_papertype (
void)
4747 std::string typ = get_papertype ();
4748 if (typ !=
"<custom>")
4751 if (get_paperorientation () ==
"landscape")
4752 std::swap (sz(0), sz(1));
4758 if (m_paperpositionmode.is (
"auto"))
4759 m_paperposition.set (get_auto_paperposition ());
4763 figure::properties::update_papersize (
void)
4765 Matrix sz = get_papersize ().matrix_value ();
4768 std::swap (sz(0), sz(1));
4774 m_paperorientation.set (
"portrait");
4777 std::string punits = get_paperunits ();
4778 if (punits ==
"centimeters")
4783 else if (punits ==
"points")
4788 if (punits ==
"normalized")
4790 if (get_papertype () ==
"<custom>")
4791 error (
"set: can't set the papertype to <custom> when the paperunits is normalized");
4798 std::string ptype =
"<custom>";
4799 const double mm2in = 1.0 / 25.4;
4800 const double tol = 0.01;
4808 else if (
std::abs (sz(0) - 841.0 * mm2in)
4809 +
std::abs (sz(1) - 1198.0 * mm2in) < tol)
4811 else if (
std::abs (sz(0) - 594.0 * mm2in)
4812 +
std::abs (sz(1) - 841.0 * mm2in) < tol)
4814 else if (
std::abs (sz(0) - 420.0 * mm2in)
4815 +
std::abs (sz(1) - 594.0 * mm2in) < tol)
4817 else if (
std::abs (sz(0) - 297.0 * mm2in)
4818 +
std::abs (sz(1) - 420.0 * mm2in) < tol)
4820 else if (
std::abs (sz(0) - 210.0 * mm2in)
4821 +
std::abs (sz(1) - 297.0 * mm2in) < tol)
4823 else if (
std::abs (sz(0) - 148.0 * mm2in)
4824 +
std::abs (sz(1) - 210.0 * mm2in) < tol)
4826 else if (
std::abs (sz(0) - 1029.0 * mm2in)
4827 +
std::abs (sz(1) - 1456.0 * mm2in) < tol)
4829 else if (
std::abs (sz(0) - 728.0 * mm2in)
4830 +
std::abs (sz(1) - 1028.0 * mm2in) < tol)
4832 else if (
std::abs (sz(0) - 514.0 * mm2in)
4833 +
std::abs (sz(1) - 728.0 * mm2in) < tol)
4835 else if (
std::abs (sz(0) - 364.0 * mm2in)
4836 +
std::abs (sz(1) - 514.0 * mm2in) < tol)
4838 else if (
std::abs (sz(0) - 257.0 * mm2in)
4839 +
std::abs (sz(1) - 364.0 * mm2in) < tol)
4841 else if (
std::abs (sz(0) - 182.0 * mm2in)
4842 +
std::abs (sz(1) - 257.0 * mm2in) < tol)
4876 m_papertype.set (ptype);
4878 if (punits ==
"centimeters")
4883 else if (punits ==
"points")
4888 if (get_paperorientation () ==
"landscape")
4890 std::swap (sz(0), sz(1));
4894 if (m_paperpositionmode.is (
"auto"))
4895 m_paperposition.set (get_auto_paperposition ());
4931 figure::properties::update_paperorientation (
void)
4933 std::string porient = get_paperorientation ();
4934 Matrix sz = get_papersize ().matrix_value ();
4935 if ((sz(0) > sz(1) && porient ==
"portrait")
4936 || (sz(0) < sz(1) && porient ==
"landscape"))
4938 std::swap (sz(0), sz(1));
4944 if (m_paperpositionmode.is (
"auto"))
4945 m_paperposition.set (get_auto_paperposition ());
4976 figure::properties::set_units (
const octave_value& val)
4980 if (m_units.set (val,
true))
4982 update_units (old_units);
4988 figure::properties::update_units (
const caseless_str& old_units)
4991 old_units, get_units (),
5014 figure::properties::get_title (
void)
const
5017 if (! get_number ().isempty () && is_numbertitle ())
5019 std::ostringstream os;
5020 std::string nm = get_name ();
5022 os <<
"Figure " << m___myhandle__.value ();
5024 os <<
": " << get_name ();
5029 title = get_name ();
5042 octave_value retval = m_default_properties.lookup (name);
5050 graphics_object parent_go = gh_mgr.get_object (parent_h);
5052 retval = parent_go.get_default (name);
5059 figure::reset_default_properties (
void)
5062 m_default_properties = property_list ();
5063 property_list::pval_map_type plist = m_properties.factory_defaults ();
5065 plist.erase (
"units");
5066 plist.erase (
"position");
5067 plist.erase (
"outerposition");
5068 plist.erase (
"paperunits");
5069 plist.erase (
"paperposition");
5070 plist.erase (
"windowstyle");
5072 remove_all_listeners ();
5079 axes::properties::init (
void)
5081 m_position.add_constraint (
dim_vector (1, 4));
5082 m_outerposition.add_constraint (
dim_vector (1, 4));
5083 m_tightinset.add_constraint (
dim_vector (1, 4));
5084 m_looseinset.add_constraint (
dim_vector (1, 4));
5085 m_colororder.add_constraint (
dim_vector (-1, 3));
5086 m_dataaspectratio.add_constraint (3);
5087 m_dataaspectratio.add_constraint (
"min", 0,
false);
5088 m_dataaspectratio.add_constraint (FINITE);
5089 m_plotboxaspectratio.add_constraint (3);
5090 m_plotboxaspectratio.add_constraint (
"min", 0,
false);
5091 m_plotboxaspectratio.add_constraint (FINITE);
5094 m_alim.add_constraint (2);
5095 m_alim.add_constraint (NOT_NAN);
5096 m_clim.add_constraint (2);
5097 m_clim.add_constraint (NOT_NAN);
5098 m_xlim.add_constraint (2);
5099 m_xlim.add_constraint (NOT_NAN);
5100 m_ylim.add_constraint (2);
5101 m_ylim.add_constraint (NOT_NAN);
5102 m_zlim.add_constraint (2);
5103 m_zlim.add_constraint (NOT_NAN);
5105 m_xtick.add_constraint (FINITE);
5107 m_ytick.add_constraint (FINITE);
5109 m_ztick.add_constraint (FINITE);
5110 m_ticklength.add_constraint (
dim_vector (1, 2));
5115 m_cameraposition.add_constraint (3);
5116 m_cameraposition.add_constraint (FINITE);
5117 m_cameratarget.add_constraint (3);
5118 m_cameratarget.add_constraint (FINITE);
5121 m_cameraupvector = upv;
5122 m_cameraupvector.add_constraint (3);
5123 m_cameraupvector.add_constraint (FINITE);
5124 m_cameraviewangle.add_constraint (FINITE);
5125 m_currentpoint.add_constraint (
dim_vector (2, 3));
5128 m_fontsize.add_constraint (
"min", 0.0,
false);
5129 m_gridalpha.add_constraint (
"min", 0.0,
true);
5130 m_gridalpha.add_constraint (
"max", 1.0,
true);
5131 m_labelfontsizemultiplier.add_constraint (
"min", 0.0,
false);
5132 m_linewidth.add_constraint (
"min", 0.0,
false);
5133 m_minorgridalpha.add_constraint (
"min", 0.0,
true);
5134 m_minorgridalpha.add_constraint (
"max", 1.0,
true);
5135 m_titlefontsizemultiplier.add_constraint (
"min", 0.0,
false);
5140 m_x_zlim.resize (1, 2);
5146 calc_ticklabels (m_xtick, m_xticklabel, m_xscale.is (
"log"),
5147 xaxislocation_is (
"origin"),
5148 m_yscale.is (
"log") ? 2 : (yaxislocation_is (
"origin") ? 0 :
5149 (yaxislocation_is (
"left") ? -1 : 1)), m_xlim);
5150 calc_ticklabels (m_ytick, m_yticklabel, m_yscale.is (
"log"),
5151 yaxislocation_is (
"origin"),
5152 m_xscale.is (
"log") ? 2 : (xaxislocation_is (
"origin") ? 0 :
5153 (xaxislocation_is (
"bottom") ? -1 : 1)), m_ylim);
5154 calc_ticklabels (m_ztick, m_zticklabel, m_zscale.is (
"log"),
5157 xset (m_xlabel.handle_value (),
"handlevisibility",
"off");
5158 xset (m_ylabel.handle_value (),
"handlevisibility",
"off");
5159 xset (m_zlabel.handle_value (),
"handlevisibility",
"off");
5160 xset (m_title.handle_value (),
"handlevisibility",
"off");
5162 xset (m_xlabel.handle_value (),
"horizontalalignment",
"center");
5163 xset (m_xlabel.handle_value (),
"horizontalalignmentmode",
"auto");
5164 xset (m_ylabel.handle_value (),
"horizontalalignment",
"center");
5165 xset (m_ylabel.handle_value (),
"horizontalalignmentmode",
"auto");
5166 xset (m_zlabel.handle_value (),
"horizontalalignment",
"right");
5167 xset (m_zlabel.handle_value (),
"horizontalalignmentmode",
"auto");
5168 xset (m_title.handle_value (),
"horizontalalignment",
"center");
5169 xset (m_title.handle_value (),
"horizontalalignmentmode",
"auto");
5171 xset (m_xlabel.handle_value (),
"verticalalignment",
"top");
5172 xset (m_xlabel.handle_value (),
"verticalalignmentmode",
"auto");
5173 xset (m_ylabel.handle_value (),
"verticalalignment",
"bottom");
5174 xset (m_ylabel.handle_value (),
"verticalalignmentmode",
"auto");
5175 xset (m_title.handle_value (),
"verticalalignment",
"bottom");
5176 xset (m_title.handle_value (),
"verticalalignmentmode",
"auto");
5178 xset (m_ylabel.handle_value (),
"rotation", 90.0);
5179 xset (m_ylabel.handle_value (),
"rotationmode",
"auto");
5181 xset (m_zlabel.handle_value (),
"visible",
"off");
5183 xset (m_xlabel.handle_value (),
"clipping",
"off");
5184 xset (m_ylabel.handle_value (),
"clipping",
"off");
5185 xset (m_zlabel.handle_value (),
"clipping",
"off");
5186 xset (m_title.handle_value (),
"clipping",
"off");
5188 xset (m_xlabel.handle_value (),
"__autopos_tag__",
"xlabel");
5189 xset (m_ylabel.handle_value (),
"__autopos_tag__",
"ylabel");
5190 xset (m_zlabel.handle_value (),
"__autopos_tag__",
"zlabel");
5191 xset (m_title.handle_value (),
"__autopos_tag__",
"title");
5193 double fs = m_labelfontsizemultiplier.double_value () *
5194 m_fontsize.double_value ();
5198 fs = m_titlefontsizemultiplier.double_value () * m_fontsize.double_value ();
5200 xset (m_title.handle_value (),
"fontweight", m_titlefontweight.get ());
5202 adopt (m_xlabel.handle_value ());
5203 adopt (m_ylabel.handle_value ());
5204 adopt (m_zlabel.handle_value ());
5205 adopt (m_title.handle_value ());
5208 tlooseinset(2) = 1-tlooseinset(0)-tlooseinset(2);
5209 tlooseinset(3) = 1-tlooseinset(1)-tlooseinset(3);
5210 m_looseinset = tlooseinset;
5237 axes::properties::calc_tightbox (
const Matrix& init_pos)
5243 graphics_object go = gh_mgr.get_object (get_parent ());
5245 Matrix parent_bb = go.get_properties ().get_boundingbox (
true);
5249 update_ticklength ();
5251 Matrix ext = get_extent (
true,
true);
5252 ext(1) = parent_bb(3) - ext(1) - ext(3);
5257 if (ext(0) < pos(0))
5259 pos(2) += pos(0)-ext(0);
5262 if (ext(0)+ext(2) > pos(0)+pos(2))
5263 pos(2) = ext(0)+ext(2)-pos(0);
5265 if (ext(1) < pos(1))
5267 pos(3) += pos(1)-ext(1);
5270 if (ext(1)+ext(3) > pos(1)+pos(3))
5271 pos(3) = ext(1)+ext(3)-pos(1);
5277 axes::properties::sync_positions (
void)
5280 if (m_positionconstraint.is (
"innerposition"))
5283 update_outerposition ();
5285 set_units (
"normalized");
5286 Matrix pos = m_position.get ().matrix_value ();
5287 Matrix outpos = m_outerposition.get ().matrix_value ();
5288 Matrix tightpos = calc_tightbox (pos);
5289 Matrix tinset (1, 4, 1.0);
5290 tinset(0) = pos(0)-tightpos(0);
5291 tinset(1) = pos(1)-tightpos(1);
5292 tinset(2) = tightpos(0)+tightpos(2)-pos(0)-pos(2);
5293 tinset(3) = tightpos(1)+tightpos(3)-pos(1)-pos(3);
5294 m_tightinset = tinset;
5295 set_units (old_units);
5296 update_transform ();
5297 if (m_positionconstraint.is (
"innerposition"))
5300 update_outerposition ();
5367 axes::properties::set_text_child (handle_property& hp,
5368 const std::string& who,
5373 xset (hp.handle_value (),
"string", v);
5381 graphics_object go = gh_mgr.get_object (gh_mgr.lookup (v));
5383 if (go.isa (
"text"))
5389 error (
"set: expecting text graphics object or character string for %s property, found %s",
5390 who.c_str (), cname.c_str ());
5393 xset (val,
"handlevisibility",
"off");
5395 gh_mgr.free (hp.handle_value ());
5399 adopt (hp.handle_value ());
5405 set_text_child (m_xlabel,
"xlabel", v);
5406 xset (m_xlabel.handle_value (),
"positionmode",
"auto");
5407 xset (m_xlabel.handle_value (),
"rotationmode",
"auto");
5408 xset (m_xlabel.handle_value (),
"horizontalalignmentmode",
"auto");
5409 xset (m_xlabel.handle_value (),
"verticalalignmentmode",
"auto");
5410 xset (m_xlabel.handle_value (),
"clipping",
"off");
5411 xset (m_xlabel.handle_value (),
"color", get_xcolor ());
5412 xset (m_xlabel.handle_value (),
"__autopos_tag__",
"xlabel");
5413 update_xlabel_position ();
5419 set_text_child (m_ylabel,
"ylabel", v);
5420 xset (m_ylabel.handle_value (),
"positionmode",
"auto");
5421 xset (m_ylabel.handle_value (),
"rotationmode",
"auto");
5422 xset (m_ylabel.handle_value (),
"horizontalalignmentmode",
"auto");
5423 xset (m_ylabel.handle_value (),
"verticalalignmentmode",
"auto");
5424 xset (m_ylabel.handle_value (),
"clipping",
"off");
5425 xset (m_ylabel.handle_value (),
"color", get_ycolor ());
5426 xset (m_ylabel.handle_value (),
"__autopos_tag__",
"ylabel");
5427 update_ylabel_position ();
5433 set_text_child (m_zlabel,
"zlabel", v);
5434 xset (m_zlabel.handle_value (),
"positionmode",
"auto");
5435 xset (m_zlabel.handle_value (),
"rotationmode",
"auto");
5436 xset (m_zlabel.handle_value (),
"horizontalalignmentmode",
"auto");
5437 xset (m_zlabel.handle_value (),
"verticalalignmentmode",
"auto");
5438 xset (m_zlabel.handle_value (),
"clipping",
"off");
5439 xset (m_zlabel.handle_value (),
"color", get_zcolor ());
5440 xset (m_zlabel.handle_value (),
"__autopos_tag__",
"zlabel");
5441 update_zlabel_position ();
5447 set_text_child (m_title,
"title", v);
5448 xset (m_title.handle_value (),
"positionmode",
"auto");
5449 xset (m_title.handle_value (),
"horizontalalignment",
"center");
5450 xset (m_title.handle_value (),
"horizontalalignmentmode",
"auto");
5451 xset (m_title.handle_value (),
"verticalalignment",
"bottom");
5452 xset (m_title.handle_value (),
"verticalalignmentmode",
"auto");
5453 xset (m_title.handle_value (),
"clipping",
"off");
5454 xset (m_title.handle_value (),
"__autopos_tag__",
"title");
5455 update_title_position ();
5459 axes::properties::set_defaults (base_graphics_object& bgo,
5460 const std::string& mode)
5478 m_alimmode =
"auto";
5479 m_climmode =
"auto";
5480 m_xlimmode =
"auto";
5481 m_ylimmode =
"auto";
5482 m_zlimmode =
"auto";
5484 m_ambientlightcolor =
Matrix (1, 3, 1.0);
5487 m_boxstyle =
"back";
5490 m_camerapositionmode =
"auto";
5491 m_cameratargetmode =
"auto";
5492 m_cameraupvectormode =
"auto";
5493 m_cameraviewanglemode =
"auto";
5499 m_clippingstyle =
"3dbox";
5501 m_color = color_values (
"white");
5503 m_colororderindex = 1.0;
5506 m_dataaspectratiomode =
"auto";
5508 m_fontangle =
"normal";
5509 m_fontname = OCTAVE_DEFAULT_FONTNAME;
5511 m_fontunits =
"points";
5512 m_fontsmoothing =
"on";
5513 m_fontweight =
"normal";
5516 m_gridalphamode =
"auto";
5517 m_gridcolor = color_values (0.15, 0.15, 0.15);
5518 m_gridcolormode =
"auto";
5519 m_gridlinestyle =
"-";
5521 m_labelfontsizemultiplier = 1.1;
5525 m_linestyleorder =
"-";
5526 m_linestyleorderindex = 1.0;
5530 m_minorgridalpha = 0.25;
5531 m_minorgridalphamode =
"auto";
5532 m_minorgridcolor = color_values (0.1, 0.1, 0.1);
5533 m_minorgridcolormode =
"auto";
5534 m_minorgridlinestyle =
":";
5536 m_nextplot =
"replace";
5539 m_plotboxaspectratiomode =
"auto";
5540 m_projection =
"orthographic";
5542 m_sortmethod =
"depth";
5545 m_tickdirmode =
"auto";
5546 m_ticklabelinterpreter =
"tex";
5549 m_tightinset =
Matrix (1, 4, 0.0);
5551 m_titlefontsizemultiplier = 1.1;
5552 m_titlefontweight =
"bold";
5554 Matrix tview (1, 2, 0.0);
5558 m_xaxislocation =
"bottom";
5560 m_xcolor = color_values (0.15, 0.15, 0.15);
5561 m_xcolormode =
"auto";
5564 m_xminorgrid =
"off";
5565 m_xminortick =
"off";
5566 m_xscale =
"linear";
5569 m_xticklabelmode =
"auto";
5570 m_xticklabelrotation = 0.0;
5571 m_xtickmode =
"auto";
5573 m_yaxislocation =
"left";
5575 m_ycolor = color_values (0.15, 0.15, 0.15);
5576 m_ycolormode =
"auto";
5579 m_yminorgrid =
"off";
5580 m_yminortick =
"off";
5581 m_yscale =
"linear";
5584 m_yticklabelmode =
"auto";
5585 m_yticklabelrotation = 0.0;
5586 m_ytickmode =
"auto";
5588 m_zcolor = color_values (0.15, 0.15, 0.15);
5589 m_zcolormode =
"auto";
5592 m_zminorgrid =
"off";
5593 m_zminortick =
"off";
5594 m_zscale =
"linear";
5597 m_zticklabelmode =
"auto";
5598 m_zticklabelrotation = 0.0;
5599 m_ztickmode =
"auto";
5609 graphics_object go = gh_mgr.get_object (m_xlabel.handle_value ());
5610 go.reset_default_properties ();
5611 go = gh_mgr.get_object (m_ylabel.handle_value ());
5612 go.reset_default_properties ();
5613 go = gh_mgr.get_object (m_zlabel.handle_value ());
5614 go.reset_default_properties ();
5615 go = gh_mgr.get_object (m_title.handle_value ());
5616 go.reset_default_properties ();
5618 xset (m_xlabel.handle_value (),
"handlevisibility",
"off");
5619 xset (m_ylabel.handle_value (),
"handlevisibility",
"off");
5620 xset (m_zlabel.handle_value (),
"handlevisibility",
"off");
5621 xset (m_title.handle_value (),
"handlevisibility",
"off");
5623 xset (m_xlabel.handle_value (),
"horizontalalignment",
"center");
5624 xset (m_xlabel.handle_value (),
"horizontalalignmentmode",
"auto");
5625 xset (m_ylabel.handle_value (),
"horizontalalignment",
"center");
5626 xset (m_ylabel.handle_value (),
"horizontalalignmentmode",
"auto");
5627 xset (m_zlabel.handle_value (),
"horizontalalignment",
"right");
5628 xset (m_zlabel.handle_value (),
"horizontalalignmentmode",
"auto");
5629 xset (m_title.handle_value (),
"horizontalalignment",
"center");
5630 xset (m_title.handle_value (),
"horizontalalignmentmode",
"auto");
5632 xset (m_xlabel.handle_value (),
"verticalalignment",
"top");
5633 xset (m_xlabel.handle_value (),
"verticalalignmentmode",
"auto");
5634 xset (m_ylabel.handle_value (),
"verticalalignment",
"bottom");
5635 xset (m_ylabel.handle_value (),
"verticalalignmentmode",
"auto");
5636 xset (m_title.handle_value (),
"verticalalignment",
"bottom");
5637 xset (m_title.handle_value (),
"verticalalignmentmode",
"auto");
5639 xset (m_ylabel.handle_value (),
"rotation", 90.0);
5640 xset (m_ylabel.handle_value (),
"rotationmode",
"auto");
5642 xset (m_zlabel.handle_value (),
"visible",
"off");
5644 xset (m_xlabel.handle_value (),
"clipping",
"off");
5645 xset (m_ylabel.handle_value (),
"clipping",
"off");
5646 xset (m_zlabel.handle_value (),
"clipping",
"off");
5647 xset (m_title.handle_value (),
"clipping",
"off");
5649 xset (m_xlabel.handle_value (),
"__autopos_tag__",
"xlabel");
5650 xset (m_ylabel.handle_value (),
"__autopos_tag__",
"ylabel");
5651 xset (m_zlabel.handle_value (),
"__autopos_tag__",
"zlabel");
5652 xset (m_title.handle_value (),
"__autopos_tag__",
"title");
5655 fs = m_labelfontsizemultiplier.double_value () * m_fontsize.double_value ();
5659 fs = m_titlefontsizemultiplier.double_value () * m_fontsize.double_value ();
5661 xset (m_title.handle_value (),
"fontweight", m_titlefontweight.get ());
5663 update_transform ();
5665 override_defaults (bgo);
5669 axes::properties::get_colormap (
void)
const
5671 if (m___colormap__.get ().isempty ())
5675 graphics_object go (gh_mgr.get_object (get___myhandle__ ()));
5676 graphics_object go_f (go.get_ancestor (
"figure"));
5679 return figure_props.get_colormap ();
5682 return get___colormap__ ();
5686 axes::properties::delete_text_child (handle_property& hp,
bool from_root)
5694 graphics_object go = gh_mgr.get_object (h);
5696 if (go.valid_object ())
5697 gh_mgr.free (h, from_root);
5705 if (! is_beingdeleted ())
5707 hp = gh_mgr.make_graphics_handle (
"text", m___myhandle__,
false,
false);
5709 xset (hp.handle_value (),
"handlevisibility",
"off");
5711 adopt (hp.handle_value ());
5716 axes::properties::remove_child (
const graphics_handle& h,
bool from_root)
5720 graphics_object go = gh_mgr.get_object (h);
5722 if (m_xlabel.handle_value ().ok () && h == m_xlabel.handle_value ())
5724 delete_text_child (m_xlabel, from_root);
5725 update_xlabel_position ();
5727 else if (m_ylabel.handle_value ().ok () && h == m_ylabel.handle_value ())
5729 delete_text_child (m_ylabel, from_root);
5730 update_ylabel_position ();
5732 else if (m_zlabel.handle_value ().ok () && h == m_zlabel.handle_value ())
5734 delete_text_child (m_zlabel, from_root);
5735 update_zlabel_position ();
5737 else if (m_title.handle_value ().ok () && h == m_title.handle_value ())
5739 delete_text_child (m_title, from_root);
5740 update_title_position ();
5742 else if (get_num_lights () > 0 && go.isa (
"light")
5743 && go.get_properties ().is_visible ())
5744 decrease_num_lights ();
5746 if (go.valid_object ())
5747 base_properties::remove_child (h, from_root);
5756 graphics_object go (gh_mgr.get_object (h));
5758 if (go.isa (
"light") && go.get_properties ().is_visible ())
5759 increase_num_lights ();
5769 if (xlimmode_is (
"auto"))
5770 update_axis_limits (
"xlim");
5772 if (ylimmode_is (
"auto"))
5773 update_axis_limits (
"ylim");
5775 if (zlimmode_is (
"auto"))
5776 update_axis_limits (
"zlim");
5778 if (climmode_is (
"auto"))
5779 update_axis_limits (
"clim");
5781 if (climmode_is (
"auto"))
5782 update_axis_limits (
"alim");
5790 for (
int i = 0; i < 4; i++)
5887 double fact = 1.0 / sqrt (v(0)*v(0)+v(1)*v(1)+v(2)*v(2));
5888 scale (v, fact, fact, fact);
5894 return (v1(0)*
v2(0)+v1(1)*
v2(1)+v1(2)*
v2(2));
5900 return sqrt (
dot (v, v));
5908 r(0) = v1(1)*
v2(2) - v1(2)*
v2(1);
5909 r(1) = v1(2)*
v2(0) - v1(0)*
v2(2);
5910 r(2) = v1(0)*
v2(1) - v1(1)*
v2(0);
5918 static double data[32] =
5931 memcpy (
m.fortran_vec (), data, sizeof (
double)*32);
5941 memcpy (retval.
fortran_vec (),
m.data (), sizeof (
double)*3);
5953 axes::properties::update_camera (
void)
5955 double xd = (xdir_is (
"normal") ? 1 : -1);
5956 double yd = (ydir_is (
"normal") ? 1 : -1);
5957 double zd = (zdir_is (
"normal") ? 1 : -1);
5959 Matrix xlimits = m_sx.scale (get_xlim ().matrix_value ());
5960 Matrix ylimits = m_sy.scale (get_ylim ().matrix_value ());
5961 Matrix zlimits = m_sz.scale (get_zlim ().matrix_value ());
5963 double xo = xlimits(xd > 0 ? 0 : 1);
5964 double yo = ylimits(yd > 0 ? 0 : 1);
5965 double zo = zlimits(zd > 0 ? 0 : 1);
5967 Matrix pb = get_plotboxaspectratio ().matrix_value ();
5969 bool autocam = (camerapositionmode_is (
"auto")
5970 && cameratargetmode_is (
"auto")
5971 && cameraupvectormode_is (
"auto")
5972 && cameraviewanglemode_is (
"auto"));
5973 bool dowarp = (autocam && dataaspectratiomode_is (
"auto")
5974 && plotboxaspectratiomode_is (
"auto"));
5980 if (cameratargetmode_is (
"auto"))
5982 c_center(0) = (xlimits(0) + xlimits(1)) / 2;
5983 c_center(1) = (ylimits(0) + ylimits(1)) / 2;
5984 c_center(2) = (zlimits(0) + zlimits(1)) / 2;
5989 c_center =
cam2xform (get_cameratarget ().matrix_value ());
5991 if (camerapositionmode_is (
"auto"))
5993 Matrix tview = get_view ().matrix_value ();
5994 double az = tview(0);
5995 double el = tview(1);
5996 double d = 5 * sqrt (pb(0)*pb(0) + pb(1)*pb(1) + pb(2)*pb(2));
5998 if (el == 90 || el == -90)
6004 c_eye(0) =
d * cos (el) * sin (az);
6005 c_eye(1) = -
d* cos (el) * cos (az);
6006 c_eye(2) =
d * sin (el);
6008 c_eye(0) = c_eye(0)*(xlimits(1)-xlimits(0))/(xd*pb(0))+c_center(0);
6009 c_eye(1) = c_eye(1)*(ylimits(1)-ylimits(0))/(yd*pb(1))+c_center(1);
6010 c_eye(2) = c_eye(2)*(zlimits(1)-zlimits(0))/(zd*pb(2))+c_center(2);
6015 c_eye =
cam2xform (get_cameraposition ().matrix_value ());
6017 if (cameraupvectormode_is (
"auto"))
6019 Matrix tview = get_view ().matrix_value ();
6020 double az = tview(0);
6021 double el = tview(1);
6023 if (el == 90 || el == -90)
6026 * sin (az*M_PI/180.0)*(xlimits(1)-xlimits(0))/pb(0);
6028 * cos (az*M_PI/180.0)*(ylimits(1)-ylimits(0))/pb(1);
6036 c_upv =
cam2xform (get_cameraupvector ().matrix_value ());
6047 scale (x_pre, pb(0), pb(1), pb(2));
6049 scale (x_pre, xd/(xlimits(1)-xlimits(0)), yd/(ylimits(1)-ylimits(0)),
6050 zd/(zlimits(1)-zlimits(0)));
6053 xform (c_eye, x_pre);
6054 xform (c_center, x_pre);
6055 scale (c_upv, pb(0)/(xlimits(1)-xlimits(0)), pb(1)/(ylimits(1)-ylimits(0)),
6056 pb(2)/(zlimits(1)-zlimits(0)));
6057 translate (c_center, -c_eye(0), -c_eye(1), -c_eye(2));
6065 double fa = 1 / sqrt (1 -
f(2)*
f(2));
6066 scale (UP, fa, fa, fa);
6072 scale (x_view, 1, 1, -1);
6074 l(0, 0) = s(0); l(0, 1) = s(1); l(0, 2) = s(2);
6075 l(1, 0) = u(0); l(1, 1) = u(1); l(1, 2) = u(2);
6076 l(2, 0) = -
f(0); l(2, 1) = -
f(1); l(2, 2) = -
f(2);
6077 x_view = x_view * l;
6078 translate (x_view, -c_eye(0), -c_eye(1), -c_eye(2));
6079 scale (x_view, pb(0), pb(1), pb(2));
6085 double xM = cmax(0) - cmin(0);
6086 double yM = cmax(1) - cmin(1);
6088 Matrix bb = get_boundingbox (
true);
6092 if (cameraviewanglemode_is (
"auto"))
6099 if (
false && dowarp)
6100 af = (1.0 / (xM > yM ? xM : yM));
6103 if ((bb(2)/bb(3)) > (xM/yM))
6108 v_angle = 2 * (180.0 / M_PI) *
atan (1 / (2 * af *
norm (F)));
6110 m_cameraviewangle = v_angle;
6113 v_angle = get_cameraviewangle ();
6115 double pf = 1 / (2 * tan ((v_angle / 2) * M_PI / 180.0) *
norm (F));
6116 scale (x_projection, pf, pf, 1);
6122 translate (x_viewport, bb(0)+bb(2)/2, bb(1)+bb(3)/2, 0);
6123 scale (x_viewport, bb(2)/xM, -bb(3)/yM, 1);
6130 if ((bb(2)/bb(3)) > (xM/yM))
6136 pix = (bb(2) < bb(3) ? bb(2) : bb(3));
6137 translate (x_viewport, bb(0)+bb(2)/2, bb(1)+bb(3)/2, 0);
6138 scale (x_viewport, pix, -pix, 1);
6141 x_normrender = x_viewport * x_projection * x_view;
6147 m_x_zlim(0) = cmin(2);
6148 m_x_zlim(1) = cmax(2);
6150 m_x_render = x_normrender;
6151 scale (m_x_render, xd/(xlimits(1)-xlimits(0)), yd/(ylimits(1)-ylimits(0)),
6152 zd/(zlimits(1)-zlimits(0)));
6155 m_x_render_inv = m_x_render.inverse ();
6159 m_x_gl_mat1 = x_view;
6160 scale (m_x_gl_mat1, xd/(xlimits(1)-xlimits(0)), yd/(ylimits(1)-ylimits(0)),
6161 zd/(zlimits(1)-zlimits(0)));
6163 m_x_gl_mat2 = x_viewport * x_projection;
6169 axes::properties::update_axes_layout (
void)
6174 graphics_xform
xform = get_transform ();
6176 double xd = (xdir_is (
"normal") ? 1 : -1);
6177 double yd = (ydir_is (
"normal") ? 1 : -1);
6178 double zd = (zdir_is (
"normal") ? 1 : -1);
6180 const Matrix xlims =
xform.xscale (get_xlim ().matrix_value ());
6181 const Matrix ylims =
xform.yscale (get_ylim ().matrix_value ());
6182 const Matrix zlims =
xform.zscale (get_zlim ().matrix_value ());
6184 double x_min, x_max, y_min, y_max, z_min, z_max;
6185 x_min = xlims(0), x_max = xlims(1);
6186 y_min = ylims(0), y_max = ylims(1);
6187 z_min = zlims(0), z_max = zlims(1);
6191 m_xstate = m_ystate = m_zstate = AXE_ANY_DIR;
6193 p1 =
xform.transform (x_min, (y_min+y_max)/2, (z_min+z_max)/2,
false);
6194 p2 =
xform.transform (x_max, (y_min+y_max)/2, (z_min+z_max)/2,
false);
6197 dir(2) = (p2(2) - p1(2));
6198 if (dir(0) == 0 && dir(1) == 0)
6199 m_xstate = AXE_DEPTH_DIR;
6200 else if (dir(2) == 0)
6203 m_xstate = AXE_VERT_DIR;
6204 else if (dir(1) == 0)
6205 m_xstate = AXE_HORZ_DIR;
6211 m_xPlane = (dir(0) > 0 ? x_max : x_min);
6213 m_xPlane = (dir(1) < 0 ? x_max : x_min);
6216 m_xPlane = (dir(2) < 0 ? x_min : x_max);
6218 m_xPlaneN = (m_xPlane == x_min ? x_max : x_min);
6219 m_fx = (x_max - x_min) / sqrt (dir(0)*dir(0) + dir(1)*dir(1));
6221 p1 =
xform.transform ((x_min + x_max)/2, y_min, (z_min + z_max)/2,
false);
6222 p2 =
xform.transform ((x_min + x_max)/2, y_max, (z_min + z_max)/2,
false);
6225 dir(2) = (p2(2) - p1(2));
6226 if (dir(0) == 0 && dir(1) == 0)
6227 m_ystate = AXE_DEPTH_DIR;
6228 else if (dir(2) == 0)
6231 m_ystate = AXE_VERT_DIR;
6232 else if (dir(1) == 0)
6233 m_ystate = AXE_HORZ_DIR;
6239 m_yPlane = (dir(0) > 0 ? y_max : y_min);
6241 m_yPlane = (dir(1) < 0 ? y_max : y_min);
6244 m_yPlane = (dir(2) < 0 ? y_min : y_max);
6246 m_yPlaneN = (m_yPlane == y_min ? y_max : y_min);
6247 m_fy = (y_max - y_min) / sqrt (dir(0)*dir(0) + dir(1)*dir(1));
6249 p1 =
xform.transform ((x_min + x_max)/2, (y_min + y_max)/2, z_min,
false);
6250 p2 =
xform.transform ((x_min + x_max)/2, (y_min + y_max)/2, z_max,
false);
6253 dir(2) = (p2(2) - p1(2));
6254 if (dir(0) == 0 && dir(1) == 0)
6255 m_zstate = AXE_DEPTH_DIR;
6256 else if (dir(2) == 0)
6259 m_zstate = AXE_VERT_DIR;
6260 else if (dir(1) == 0)
6261 m_zstate = AXE_HORZ_DIR;
6267 m_zPlane = (dir(0) > 0 ? z_min : z_max);
6269 m_zPlane = (dir(1) < 0 ? z_min : z_max);
6272 m_zPlane = (dir(2) < 0 ? z_min : z_max);
6274 m_zPlaneN = (m_zPlane == z_min ? z_max : z_min);
6275 m_fz = (z_max - z_min) / sqrt (dir(0)*dir(0) + dir(1)*dir(1));
6279 m_xySym = (xd*yd*(m_xPlane-m_xPlaneN)*(m_yPlane-m_yPlaneN) > 0);
6280 m_zSign = (zd*(m_zPlane-m_zPlaneN) <= 0);
6281 m_xyzSym = (m_zSign ? m_xySym : ! m_xySym);
6282 m_xpTick = (m_zSign ? m_xPlaneN : m_xPlane);
6283 m_ypTick = (m_zSign ? m_yPlaneN : m_yPlane);
6284 m_zpTick = (m_zSign ? m_zPlane : m_zPlaneN);
6285 m_xpTickN = (m_zSign ? m_xPlane : m_xPlaneN);
6286 m_ypTickN = (m_zSign ? m_yPlane : m_yPlaneN);
6287 m_zpTickN = (m_zSign ? m_zPlaneN : m_zPlane);
6292 m_layer2Dtop =
false;
6293 if (m_xstate == AXE_HORZ_DIR && m_ystate == AXE_VERT_DIR)
6295 Matrix ylimits = get_ylim ().matrix_value ();
6296 if (xaxislocation_is (
"top")
6297 || (yscale_is (
"log") && xaxislocation_is (
"origin")
6298 && (ylimits(1) < 0.)))
6300 std::swap (m_yPlane, m_yPlaneN);
6303 m_ypTick = m_yPlaneN;
6304 m_ypTickN = m_yPlane;
6305 Matrix xlimits = get_xlim ().matrix_value ();
6306 if (yaxislocation_is (
"right")
6307 || (xscale_is (
"log") && yaxislocation_is (
"origin")
6308 && (xlimits(1) < 0.)))
6310 std::swap (m_xPlane, m_xPlaneN);
6313 m_xpTick = m_xPlaneN;
6314 m_xpTickN = m_xPlane;
6315 if (layer_is (
"top"))
6317 m_zpTick = m_zPlaneN;
6318 m_layer2Dtop =
true;
6321 m_zpTick = m_zPlane;
6324 Matrix viewmat = get_view ().matrix_value ();
6325 m_nearhoriz =
std::abs (viewmat(1)) <= 5;
6326 m_is2D = viewmat(1) == 90;
6328 update_ticklength ();
6332 axes::properties::update_ticklength (
void)
6334 bool mode2D = (((m_xstate > AXE_DEPTH_DIR ? 1 : 0) +
6335 (m_ystate > AXE_DEPTH_DIR ? 1 : 0) +
6336 (m_zstate > AXE_DEPTH_DIR ? 1 : 0)) == 2);
6338 if (tickdirmode_is (
"auto"))
6339 m_tickdir.set (mode2D ?
"in" :
"out",
true);
6341 double ticksign = (tickdir_is (
"in") ? -1 : 1);
6343 Matrix bbox = get_boundingbox (
true);
6344 Matrix ticklen = get_ticklength ().matrix_value ();
6345 ticklen(0) *=
std::max (bbox(2), bbox(3));
6348 ticklen(1) *= (0.76 *
std::max (bbox(2), bbox(3)));
6350 m_xticklen = ticksign * (mode2D ? ticklen(0) : ticklen(1));
6351 m_yticklen = ticksign * (mode2D ? ticklen(0) : ticklen(1));
6352 m_zticklen = ticksign * (mode2D ? ticklen(0) : ticklen(1));
6354 double offset = get___fontsize_points__ () / 2;
6356 m_xtickoffset = (mode2D ?
std::max (0., m_xticklen) : std::
abs (m_xticklen)) +
6357 (m_xstate == AXE_HORZ_DIR ? offset*1.5 : offset);
6358 m_ytickoffset = (mode2D ?
std::max (0., m_yticklen) : std::
abs (m_yticklen)) +
6359 (m_ystate == AXE_HORZ_DIR ? offset*1.5 : offset);
6360 m_ztickoffset = (mode2D ?
std::max (0., m_zticklen) : std::
abs (m_zticklen)) +
6361 (m_zstate == AXE_HORZ_DIR ? offset*1.5 : offset);
6363 update_xlabel_position ();
6364 update_ylabel_position ();
6365 update_zlabel_position ();
6366 update_title_position ();
6390 const graphics_xform&
xform,
6395 std::string to_units = props.get_units ();
6397 if (to_units !=
"data")
6403 retval(0) = v(0) - bbox(0) + 1;
6404 retval(1) = bbox(1) + bbox(3) - v(1) + 1;
6419 axes::properties::update_xlabel_position (
void)
6426 graphics_object go = gh_mgr.get_object (get_xlabel ());
6428 if (! go.valid_object ())
6434 bool isempty = xlabel_props.get_string ().isempty ();
6436 octave::unwind_protect_var<bool>
6441 if (xlabel_props.horizontalalignmentmode_is (
"auto"))
6443 xlabel_props.set_horizontalalignment
6444 (m_xstate > AXE_DEPTH_DIR ?
"center"
6445 : (m_xyzSym ?
"left" :
"right"));
6447 xlabel_props.set_horizontalalignmentmode (
"auto");
6450 if (xlabel_props.verticalalignmentmode_is (
"auto"))
6452 xlabel_props.set_verticalalignment
6453 (m_xstate == AXE_VERT_DIR || m_x2Dtop ?
"bottom" :
"top");
6455 xlabel_props.set_verticalalignmentmode (
"auto");
6459 if (xlabel_props.positionmode_is (
"auto")
6460 || xlabel_props.rotationmode_is (
"auto"))
6462 graphics_xform
xform = get_transform ();
6465 ext = get_ticklabel_extents (get_xtick ().matrix_value (),
6466 get_xticklabel ().string_vector_value (),
6467 get_xlim ().matrix_value ());
6470 double wmax = ext(0) + margin;
6471 double hmax = ext(1) + margin;
6482 p =
xform.transform (p(0), p(1), p(2),
false);
6487 p(0) += (m_xyzSym ? wmax : -wmax);
6497 p(1) += (m_x2Dtop ? -hmax : hmax);
6501 if (xlabel_props.positionmode_is (
"auto"))
6503 p =
xform.untransform (p(0), p(1), p(2),
true);
6506 get_extent (
false));
6509 xlabel_props.set_positionmode (
"auto");
6512 if (! isempty && xlabel_props.rotationmode_is (
"auto"))
6514 xlabel_props.set_rotation (angle);
6515 xlabel_props.set_rotationmode (
"auto");
6523 axes::properties::update_ylabel_position (
void)
6530 graphics_object go = gh_mgr.get_object (get_ylabel ());
6532 if (! go.valid_object ())
6538 bool isempty = ylabel_props.get_string ().isempty ();
6540 octave::unwind_protect_var<bool>
6545 if (ylabel_props.horizontalalignmentmode_is (
"auto"))
6547 ylabel_props.set_horizontalalignment
6548 (m_ystate > AXE_DEPTH_DIR ?
"center"
6549 : (! m_xyzSym ?
"left" :
"right"));
6551 ylabel_props.set_horizontalalignmentmode (
"auto");
6554 if (ylabel_props.verticalalignmentmode_is (
"auto"))
6556 ylabel_props.set_verticalalignment
6557 (m_ystate == AXE_VERT_DIR && ! m_y2Dright ?
"bottom" :
"top");
6559 ylabel_props.set_verticalalignmentmode (
"auto");
6563 if (ylabel_props.positionmode_is (
"auto")
6564 || ylabel_props.rotationmode_is (
"auto"))
6566 graphics_xform
xform = get_transform ();
6570 ext = get_ticklabel_extents (get_ytick ().matrix_value (),
6571 get_yticklabel ().string_vector_value (),
6572 get_ylim ().matrix_value ());
6574 double wmax = ext(0) + margin;
6575 double hmax = ext(1) + margin;
6586 p =
xform.transform (p(0), p(1), p(2),
false);
6591 p(0) += (! m_xyzSym ? wmax : -wmax);
6596 p(0) += (m_y2Dright ? wmax : -wmax);
6605 if (ylabel_props.positionmode_is (
"auto"))
6607 p =
xform.untransform (p(0), p(1), p(2),
true);
6610 get_extent (
false));
6613 ylabel_props.set_positionmode (
"auto");
6616 if (! isempty && ylabel_props.rotationmode_is (
"auto"))
6618 ylabel_props.set_rotation (angle);
6619 ylabel_props.set_rotationmode (
"auto");
6627 axes::properties::update_zlabel_position (
void)
6634 graphics_object go = gh_mgr.get_object (get_zlabel ());
6636 if (! go.valid_object ())
6642 bool camAuto = cameraupvectormode_is (
"auto");
6643 bool isempty = zlabel_props.get_string ().isempty ();
6645 octave::unwind_protect_var<bool>
6650 if (zlabel_props.horizontalalignmentmode_is (
"auto"))
6652 zlabel_props.set_horizontalalignment
6653 ((m_zstate > AXE_DEPTH_DIR || camAuto) ?
"center" :
"right");
6655 zlabel_props.set_horizontalalignmentmode (
"auto");
6658 if (zlabel_props.verticalalignmentmode_is (
"auto"))
6660 zlabel_props.set_verticalalignment
6661 (m_zstate == AXE_VERT_DIR
6662 ?
"bottom" : ((m_zSign || camAuto) ?
"bottom" :
"top"));
6664 zlabel_props.set_verticalalignmentmode (
"auto");
6668 if (zlabel_props.positionmode_is (
"auto")
6669 || zlabel_props.rotationmode_is (
"auto"))
6671 graphics_xform
xform = get_transform ();
6674 ext = get_ticklabel_extents (get_ztick ().matrix_value (),
6675 get_zticklabel ().string_vector_value (),
6676 get_zlim ().matrix_value ());
6679 double wmax = ext(0) + margin;
6680 double hmax = ext(1) + margin;
6687 (m_zpTickN + m_zpTick)/2);
6696 (m_zpTickN + m_zpTick)/2);
6703 p =
xform.transform (p(0), p(1), p(2),
false);
6731 if (zlabel_props.positionmode_is (
"auto"))
6733 p =
xform.untransform (p(0), p(1), p(2),
true);
6736 get_extent (
false));
6739 zlabel_props.set_positionmode (
"auto");
6742 if (! isempty && zlabel_props.rotationmode_is (
"auto"))
6744 zlabel_props.set_rotation (angle);
6745 zlabel_props.set_rotationmode (
"auto");
6753 axes::properties::update_title_position (
void)
6760 graphics_object go = gh_mgr.get_object (get_title ());
6762 if (! go.valid_object ())
6770 if (title_props.positionmode_is (
"auto"))
6772 graphics_xform
xform = get_transform ();
6775 Matrix bbox = get_extent (
false);
6779 (m_x_zlim(0) + m_x_zlim(1))/2);
6784 ext = get_ticklabel_extents (get_xtick ().matrix_value (),
6785 get_xticklabel ().string_vector_value (),
6786 get_xlim ().matrix_value ());
6790 p =
xform.untransform (p(0), p(1), p(2),
true);
6795 title_props.set_positionmode (
"auto");
6800 axes::properties::update_autopos (
const std::string& elem_type)
6802 if (elem_type ==
"xlabel")
6803 update_xlabel_position ();
6804 else if (elem_type ==
"ylabel")
6805 update_ylabel_position ();
6806 else if (elem_type ==
"zlabel")
6807 update_zlabel_position ();
6808 else if (elem_type ==
"title")
6809 update_title_position ();
6810 else if (elem_type ==
"sync")
6816 double xlength,
double ylength,
double zlength)
6818 double xval = xlength / scalefactors(0);
6819 double yval = ylength / scalefactors(1);
6820 double zval = zlength / scalefactors(2);
6824 aspectratios(0) = xval / minval;
6825 aspectratios(1) = yval / minval;
6826 aspectratios(2) = zval / minval;
6831 double pbfactor,
double dafactor,
char limit_type,
bool tight)
6854 axes::properties::update_aspectratios (
void)
6860 Matrix xlimits = get_xlim ().matrix_value ();
6861 Matrix ylimits = get_ylim ().matrix_value ();
6862 Matrix zlimits = get_zlim ().matrix_value ();
6864 double dx = (xlimits(1) - xlimits(0));
6865 double dy = (ylimits(1) - ylimits(0));
6866 double dz = (zlimits(1) - zlimits(0));
6868 Matrix da = get_dataaspectratio ().matrix_value ();
6869 Matrix pba = get_plotboxaspectratio ().matrix_value ();
6871 if (dataaspectratiomode_is (
"auto"))
6873 if (plotboxaspectratiomode_is (
"auto"))
6875 pba =
Matrix (1, 3, 1.0);
6876 m_plotboxaspectratio.set (pba,
false);
6880 m_dataaspectratio.set (da,
false);
6882 else if (plotboxaspectratiomode_is (
"auto"))
6885 m_plotboxaspectratio.set (pba,
false);
6890 bool modified_limits =
false;
6893 if (xlimmode_is (
"auto") && ylimmode_is (
"auto") && zlimmode_is (
"auto"))
6895 modified_limits =
true;
6896 kids = get_children ();
6901 else if (xlimmode_is (
"auto") && ylimmode_is (
"auto"))
6903 modified_limits =
true;
6906 else if (ylimmode_is (
"auto") && zlimmode_is (
"auto"))
6908 modified_limits =
true;
6911 else if (zlimmode_is (
"auto") && xlimmode_is (
"auto"))
6913 modified_limits =
true;
6917 if (modified_limits)
6919 octave::unwind_protect_var<std::set<double>>
6924 dx = pba(0) * da(0);
6925 dy = pba(1) * da(1);
6926 dz = pba(2) * da(2);
6930 if (xlimmode_is (
"auto"))
6933 xlimits(0) = 0.5 * (xlimits(0) + xlimits(1) - dx);
6934 xlimits(1) = xlimits(0) + dx;
6936 set_xlimmode (
"auto");
6939 if (ylimmode_is (
"auto"))
6942 ylimits(0) = 0.5 * (ylimits(0) + ylimits(1) - dy);
6943 ylimits(1) = ylimits(0) + dy;
6945 set_ylimmode (
"auto");
6948 if (zlimmode_is (
"auto"))
6951 zlimits(0) = 0.5 * (zlimits(0) + zlimits(1) - dz);
6952 zlimits(1) = zlimits(0) + dz;
6954 set_zlimmode (
"auto");
6960 m_plotboxaspectratio.set (pba,
false);
6966 axes::properties::update_label_color (handle_property label,
6971 gh_mgr.get_object (label.handle_value ()).set (
"color", col.get ());
6975 axes::properties::update_font (std::string prop)
6979 if (! prop.empty ())
6983 if (prop ==
"fontsize")
6986 get_titlefontsizemultiplier ());
6988 get_labelfontsizemultiplier ());
6990 else if (prop ==
"fontweight")
6991 tval = get (
"titlefontweight");
6993 gh_mgr.get_object (get_xlabel ()).set (prop, val);
6994 gh_mgr.get_object (get_ylabel ()).set (prop, val);
6995 gh_mgr.get_object (get_zlabel ()).set (prop, val);
6996 gh_mgr.get_object (get_title ()).set (prop, tval);
7001 octave::autolock guard (gh_mgr.graphics_lock ());
7003 m_txt_renderer.set_font (get (
"fontname").string_value (),
7004 get (
"fontweight").string_value (),
7005 get (
"fontangle").string_value (),
7006 get (
"__fontsize_points__").double_value () * dpr);
7012 axes::properties::get_boundingbox (
bool internal,
7013 const Matrix& parent_pix_size)
const
7015 Matrix pos = (
internal ? get_position ().matrix_value ()
7016 : get_outerposition ().matrix_value ());
7017 Matrix parent_size (parent_pix_size);
7019 if (parent_size.isempty ())
7023 graphics_object go = gh_mgr.get_object (get_parent ());
7025 if (go.valid_object ())
7027 = go.get_properties ().get_boundingbox (
true).extract_n (0, 2, 1, 2);
7036 pos(1) = parent_size(1) - pos(1) - pos(3);
7042 axes::properties::get_extent (
bool with_text,
bool only_text_height)
const
7044 graphics_xform
xform = get_transform ();
7049 for (
int i = 0; i <= 1; i++)
7050 for (
int j = 0; j <= 1; j++)
7051 for (
int k = 0; k <= 1; k++)
7054 j ? m_yPlaneN : m_yPlane,
7055 k ? m_zPlaneN : m_zPlane,
false);
7064 for (
int i = 0; i < 4; i++)
7068 htext = get_title ();
7070 htext = get_xlabel ();
7072 htext = get_ylabel ();
7074 htext = get_zlabel ();
7080 (gh_mgr.get_object (htext).get_properties ());
7082 Matrix text_pos = text_props.get_data_position ();
7083 text_pos =
xform.transform (text_pos(0), text_pos(1), text_pos(2));
7084 if (text_props.get_string ().isempty ())
7086 ext(0) =
std::min (ext(0), text_pos(0));
7087 ext(1) =
std::min (ext(1), text_pos(1));
7088 ext(2) =
std::max (ext(2), text_pos(0));
7089 ext(3) =
std::max (ext(3), text_pos(1));
7093 Matrix text_ext = text_props.get_extent_matrix (
true);
7099 for (
int j = 0; j < 4; j++)
7102 bool ignore_horizontal =
false;
7103 bool ignore_vertical =
false;
7104 if (only_text_height)
7106 double text_rotation = text_props.get_rotation ();
7107 if (text_rotation == 0. || text_rotation == 180.)
7108 ignore_horizontal =
true;
7109 else if (text_rotation == 90. || text_rotation == 270.)
7110 ignore_vertical =
true;
7113 if (! ignore_horizontal)
7115 ext(0) =
std::min (ext(0), text_pos(0)+text_ext(0));
7117 text_pos(0)+text_ext(0)+text_ext(2));
7120 if (! ignore_vertical)
7123 text_pos(1)-text_ext(1)-text_ext(3));
7124 ext(3) =
std::max (ext(3), text_pos(1)-text_ext(1));
7130 ext(2) = ext(2) - ext(0);
7131 ext(3) = ext(3) - ext(1);
7153 std::ostringstream oss;
7165 std::istringstream iss (valstr);
7169 while (std::getline (iss, tmpstr,
'|'))
7173 if (*valstr.rbegin () ==
'|')
7174 sv.
append (std::string (
""));
7188 axes::properties::set_xticklabel (
const octave_value& val)
7192 set_xticklabelmode (
"manual");
7193 m_xticklabel.run_listeners (GCB_POSTSET);
7197 set_xticklabelmode (
"manual");
7203 axes::properties::set_yticklabel (
const octave_value& val)
7207 set_yticklabelmode (
"manual");
7208 m_yticklabel.run_listeners (GCB_POSTSET);
7212 set_yticklabelmode (
"manual");
7218 axes::properties::set_zticklabel (
const octave_value& val)
7222 set_zticklabelmode (
"manual");
7223 m_zticklabel.run_listeners (GCB_POSTSET);
7227 set_zticklabelmode (
"manual");
7251 std::istringstream iss (valstr);
7255 while (std::getline (iss, tmpstr,
'|'))
7259 if (*valstr.rbegin () ==
'|')
7260 sv.
append (std::string (
""));
7274 axes::properties::set_linestyleorder (
const octave_value& val)
7284 if (m_units.set (val,
true))
7286 update_units (old_units);
7292 axes::properties::update_units (
const caseless_str& old_units)
7296 graphics_object parent_go = gh_mgr.get_object (get_parent ());
7299 = parent_go.get_properties ().get_boundingbox (
true).
extract_n (0, 2, 1, 2);
7304 old_units, new_units, parent_bb)),
7308 old_units, new_units, parent_bb)),
7312 old_units, new_units, parent_bb)),
7316 old_units, new_units, parent_bb)),
7321 axes::properties::set_fontunits (
const octave_value& val)
7325 if (m_fontunits.set (val,
true))
7327 update_fontunits (old_fontunits);
7333 axes::properties::update_fontunits (
const caseless_str& old_units)
7336 double parent_height = get_boundingbox (
true).elem (3);
7337 double fontsz = get_fontsize ();
7345 axes::properties::get___fontsize_points__ (
double box_pix_height)
const
7347 double fontsz = get_fontsize ();
7348 double parent_height = box_pix_height;
7350 if (fontunits_is (
"normalized") && parent_height <= 0)
7351 parent_height = get_boundingbox (
true).elem (3);
7363 graphics_xform::xform_eye (
void)
7382 graphics_xform::untransform (
double x,
double y,
double z,
7383 bool use_scale)
const
7389 v(0) = m_sx.unscale (v(0));
7390 v(1) = m_sy.unscale (v(1));
7391 v(2) = m_sz.unscale (v(2));
7400 octave_value retval = m_default_properties.lookup (pname);
7408 graphics_object parent_go = gh_mgr.get_object (parent_h);
7410 retval = parent_go.get_default (pname);
7441 double& min_pos,
double& max_neg,
7449 if (
m.numel () != 4)
7494 axes::properties::update_outerposition (
void)
7496 set_positionconstraint (
"outerposition");
7498 set_units (
"normalized");
7500 Matrix outerbox = m_outerposition.get ().matrix_value ();
7502 double outer_left = outerbox(0);
7503 double outer_bottom = outerbox(1);
7504 double outer_width = outerbox(2);
7505 double outer_height = outerbox(3);
7507 double outer_right = outer_width + outer_left;
7508 double outer_top = outer_height + outer_bottom;
7510 Matrix linset = m_looseinset.get ().matrix_value ();
7511 Matrix tinset = m_tightinset.get ().matrix_value ();
7513 double left_margin =
std::max (linset(0), tinset(0));
7514 double bottom_margin =
std::max (linset(1), tinset(1));
7515 double right_margin =
std::max (linset(2), tinset(2));
7516 double top_margin =
std::max (linset(3), tinset(3));
7518 double inner_left = outer_left;
7519 double inner_right = outer_right;
7521 if ((left_margin + right_margin) < outer_width)
7523 inner_left += left_margin;
7524 inner_right -= right_margin;
7527 double inner_bottom = outer_bottom;
7528 double inner_top = outer_top;
7530 if ((bottom_margin + top_margin) < outer_height)
7532 inner_bottom += bottom_margin;
7533 inner_top -= top_margin;
7536 double inner_width = inner_right - inner_left;
7537 double inner_height = inner_top - inner_bottom;
7541 innerbox(0) = inner_left;
7542 innerbox(1) = inner_bottom;
7543 innerbox(2) = inner_width;
7544 innerbox(3) = inner_height;
7546 m_position = innerbox;
7548 set_units (old_units);
7549 update_transform ();
7553 axes::properties::update_position (
void)
7555 set_positionconstraint (
"innerposition");
7557 set_units (
"normalized");
7559 Matrix innerbox = m_position.get ().matrix_value ();
7561 double inner_left = innerbox(0);
7562 double inner_bottom = innerbox(1);
7563 double inner_width = innerbox(2);
7564 double inner_height = innerbox(3);
7566 double inner_right = inner_width + inner_left;
7567 double inner_top = inner_height + inner_bottom;
7569 Matrix linset = m_looseinset.get ().matrix_value ();
7570 Matrix tinset = m_tightinset.get ().matrix_value ();
7572 double left_margin =
std::max (linset(0), tinset(0));
7573 double bottom_margin =
std::max (linset(1), tinset(1));
7574 double right_margin =
std::max (linset(2), tinset(2));
7575 double top_margin =
std::max (linset(3), tinset(3));
7579 double outer_left = inner_left - left_margin;
7580 double outer_bottom = inner_bottom - bottom_margin;
7581 double outer_right = inner_right + right_margin;
7582 double outer_top = inner_top + top_margin;
7584 double outer_width = outer_right - outer_left;
7585 double outer_height = outer_top - outer_bottom;
7589 outerbox(0) = outer_left;
7590 outerbox(1) = outer_bottom;
7591 outerbox(2) = outer_width;
7592 outerbox(3) = outer_height;
7594 m_outerposition = outerbox;
7596 set_units (old_units);
7597 update_transform ();
7601 axes::properties::update_looseinset (
void)
7604 set_units (
"normalized");
7606 Matrix linset = m_looseinset.get ().matrix_value ();
7607 Matrix tinset = m_tightinset.get ().matrix_value ();
7609 double left_margin =
std::max (linset(0), tinset(0));
7610 double bottom_margin =
std::max (linset(1), tinset(1));
7611 double right_margin =
std::max (linset(2), tinset(2));
7612 double top_margin =
std::max (linset(3), tinset(3));
7614 if (m_positionconstraint.is (
"innerposition"))
7616 Matrix innerbox = m_position.get ().matrix_value ();
7618 double inner_left = innerbox(0);
7619 double inner_bottom = innerbox(1);
7620 double inner_width = innerbox(2);
7621 double inner_height = innerbox(3);
7623 double inner_right = inner_width + inner_left;
7624 double inner_top = inner_height + inner_bottom;
7628 double outer_left = inner_left - left_margin;
7629 double outer_bottom = inner_bottom - bottom_margin;
7630 double outer_right = inner_right + right_margin;
7631 double outer_top = inner_top + top_margin;
7633 double outer_width = outer_right - outer_left;
7634 double outer_height = outer_top - outer_bottom;
7638 outerbox(0) = outer_left;
7639 outerbox(1) = outer_bottom;
7640 outerbox(2) = outer_width;
7641 outerbox(3) = outer_height;
7643 m_outerposition = outerbox;
7647 Matrix outerbox = m_outerposition.get ().matrix_value ();
7649 double outer_left = outerbox(0);
7650 double outer_bottom = outerbox(1);
7651 double outer_width = outerbox(2);
7652 double outer_height = outerbox(3);
7654 double outer_right = outer_width + outer_left;
7655 double outer_top = outer_height + outer_bottom;
7657 double inner_left = outer_left;
7658 double inner_right = outer_right;
7660 if ((left_margin + right_margin) < outer_width)
7662 inner_left += left_margin;
7663 inner_right -= right_margin;
7666 double inner_bottom = outer_bottom;
7667 double inner_top = outer_top;
7669 if ((bottom_margin + top_margin) < outer_height)
7671 inner_bottom += bottom_margin;
7672 inner_top -= top_margin;
7675 double inner_width = inner_right - inner_left;
7676 double inner_height = inner_top - inner_bottom;
7680 innerbox(0) = inner_left;
7681 innerbox(1) = inner_bottom;
7682 innerbox(2) = inner_width;
7683 innerbox(3) = inner_height;
7685 m_position = innerbox;
7688 set_units (old_units);
7689 update_transform ();
7697 axes::properties::calc_tick_sep (
double lo,
double hi)
7709 magform ((hi - lo) / ticint, a, b);
7711 static const double sqrt_2 = sqrt (2.0);
7712 static const double sqrt_10 = sqrt (10.0);
7713 static const double sqrt_50 = sqrt (50.0);
7717 else if (a < sqrt_10)
7719 else if (a < sqrt_50)
7731 axes::properties::get_axis_limits (
double xmin,
double xmax,
7732 double min_pos,
double max_neg,
7733 const bool logscale,
7734 const std::string& method)
7738 double min_val =
xmin;
7739 double max_val =
xmax;
7764 "axis: omitting non-positive data in log plot");
7767 else if (max_val == 0)
7772 < sqrt (std::numeric_limits<double>::epsilon ()))
7787 if (method ==
"tickaligned")
7802 else if (method ==
"padded")
7807 double pad = (log10 (max_val) - log10 (min_val)) * 0.07;
7808 min_val =
std::pow (10, log10 (min_val) - pad);
7809 max_val =
std::pow (10, log10 (max_val) + pad);
7814 double pad = (log10 (-min_val) - log10 (-max_val)) * 0.07;
7815 min_val = -
std::pow (10, log10 (-min_val) + pad);
7816 max_val = -
std::pow (10, log10 (-max_val) - pad);
7822 if (min_val == 0 && max_val == 0)
7828 else if (
std::abs (min_val - max_val)
7829 < sqrt (std::numeric_limits<double>::epsilon ()))
7831 min_val -= 0.1 *
std::abs (min_val);
7832 max_val += 0.1 *
std::abs (max_val);
7835 if (method ==
"tickaligned")
7837 double tick_sep = calc_tick_sep (min_val, max_val);
7838 double min_tick =
std::floor (min_val / tick_sep);
7839 double max_tick =
std::ceil (max_val / tick_sep);
7841 min_val =
std::min (min_val, tick_sep * min_tick);
7842 max_val =
std::max (max_val, tick_sep * max_tick);
7844 else if (method ==
"padded")
7846 double pad = 0.07 * (max_val - min_val);
7855 retval(0) = min_val;
7856 retval(1) = max_val;
7862 axes::properties::check_axis_limits (
Matrix& limits,
const Matrix kids,
7863 const bool logscale,
char& update_type)
7869 double eps = std::numeric_limits<double>::epsilon ();
7870 bool do_update =
false;
7871 bool have_children_limits =
false;
7879 have_children_limits =
true;
7883 limits(0) = min_val;
7888 limits(1) = max_val;
7891 if (limits(0) == 0 && limits(1) == 0)
7897 else if (! logscale && (
std::abs (limits(0) - limits(1)) < sqrt (
eps)))
7899 limits(0) -= 0.1 *
std::abs (limits(0));
7900 limits(1) += 0.1 *
std::abs (limits(1));
7904 && (
std::abs (std::log10 (limits(0) / limits(1))) < sqrt (
eps)))
7906 limits(0) = (limits(0) < 0 ? 10.0 * limits(0) : 0.1 * limits(0));
7907 limits(1) = (limits(1) < 0 ? 0.1 * limits(1) : 10.0 * limits(1));
7911 if (logscale && limits(0)*limits(1) <= 0)
7913 if (! have_children_limits)
7920 "Non-positive limit for logarithmic axis ignored\n");
7922 limits(0) = min_pos;
7924 limits(0) = 0.1 * limits(1);
7929 "Non-negative limit for logarithmic axis ignored\n");
7931 limits(1) = max_neg;
7933 limits(1) = 0.1 * limits(0);
7936 if (
std::abs (limits(0) - limits(1)) < sqrt (
eps))
8088 axes::properties::calc_ticks_and_lims (array_property& lims,
8089 array_property& ticks,
8090 array_property& mticks,
8091 bool limmode_is_auto,
8092 bool tickmode_is_auto,
8094 bool method_is_padded,
8095 bool method_is_tight)
8097 if (lims.get ().isempty ())
8100 double lo = (lims.get ().matrix_value ())(0);
8101 double hi = (lims.get ().matrix_value ())(1);
8105 bool is_negative = lo < 0 && hi < 0;
8116 hi = std::log10 (-lo);
8117 lo = std::log10 (-tmp);
8121 hi = std::log10 (hi);
8122 lo = std::log10 (lo);
8127 if (tickmode_is_auto)
8139 tick_sep = calc_tick_sep (lo, hi);
8144 if (limmode_is_auto)
8148 if (! method_is_padded && ! method_is_tight)
8151 tmp_lims(0) =
std::min (tick_sep * i1, lo);
8152 tmp_lims(1) =
std::max (tick_sep * i2, hi);
8160 if (i1*tick_sep < lo)
8162 if (i2*tick_sep > hi && i2 > i1)
8168 tmp_lims(0) =
std::pow (10., tmp_lims(0));
8169 tmp_lims(1) =
std::pow (10., tmp_lims(1));
8171 if (tmp_lims(0) <= 0)
8176 double tmp = tmp_lims(0);
8177 tmp_lims(0) = -tmp_lims(1);
8187 if (i1*tick_sep < lo)
8189 if (i2*tick_sep > hi && i2 > i1)
8193 tmp_ticks =
Matrix (1, i2-i1+1);
8194 for (
int i = 0; i <= static_cast<int> (i2-i1); i++)
8196 tmp_ticks(i) = tick_sep * (i+i1);
8198 tmp_ticks(i) =
std::pow (10., tmp_ticks(i));
8200 if (is_logscale && is_negative)
8202 Matrix rev_ticks (1, i2-i1+1);
8203 rev_ticks = -tmp_ticks;
8204 for (
int i = 0; i <= static_cast<int> (i2-i1); i++)
8205 tmp_ticks(i) = rev_ticks(i2-i1-i);
8211 tmp_ticks = ticks.get ().matrix_value ();
8218 int n = (is_logscale ? 8 : 4);
8219 double mult_below = (is_logscale ? tmp_ticks(1) / tmp_ticks(0) : 1);
8220 double mult_above = (is_logscale ? tmp_ticks(n_ticks-1) / tmp_ticks(n_ticks-2)
8223 double d_below = (tmp_ticks(1) - tmp_ticks(0)) / mult_below / (
n+1);
8224 int n_below =
static_cast<int> (
std::floor ((tmp_ticks(0)-lo_lim) / d_below));
8227 int n_between =
n * (n_ticks - 1);
8228 double d_above = (tmp_ticks(n_ticks-1) - tmp_ticks(n_ticks-2)) * mult_above
8230 int n_above =
static_cast<int> (
std::floor ((hi_lim-tmp_ticks(n_ticks-1))
8235 Matrix tmp_mticks (1, n_below + n_between + n_above);
8236 for (
int i = 0; i < n_below; i++)
8237 tmp_mticks(i) = tmp_ticks(0) - (n_below-i) * d_below;
8238 for (
int i = 0; i < n_ticks-1; i++)
8240 double d = (tmp_ticks(i+1) - tmp_ticks(i)) / (
n + 1);
8241 for (
int j = 0; j <
n; j++)
8242 tmp_mticks(n_below+
n*i+j) = tmp_ticks(i) +
d * (j+1);
8244 for (
int i = 0; i < n_above; i++)
8245 tmp_mticks(n_below+n_between+i) = tmp_ticks(n_ticks-1) + (i + 1) * d_above;
8247 mticks = tmp_mticks;
8264 axes::properties::calc_ticklabels (
const array_property& ticks,
8265 any_property& labels,
bool logscale,
8266 const bool is_origin,
8267 const int other_axislocation,
8268 const array_property& axis_lims)
8270 Matrix values = ticks.get ().matrix_value ();
8271 Matrix lims = axis_lims.get ().matrix_value ();
8273 std::ostringstream os;
8277 if (get_is2D () && is_origin)
8279 if (other_axislocation == 0)
8284 else if (other_axislocation == 1)
8285 omit_ticks(0) = lims(1);
8286 else if (other_axislocation == -1)
8287 omit_ticks(0) = lims(0);
8290 omit_ticks(1) = lims(0);
8291 omit_ticks(2) = lims(1);
8299 double exp_max = 0.0;
8300 double exp_min = 0.0;
8302 for (
int i = 0; i < values.
numel (); i++)
8304 double exp = std::log10 (values(i));
8309 for (
int i = 0; i < values.
numel (); i++)
8311 bool omit_tick =
false;
8312 for (
int i_omit = 0; i_omit < omit_ticks.numel (); i_omit++)
8313 if (values(i) == omit_ticks(i_omit))
8321 if (values(i) < 0.0)
8322 exponent =
std::floor (std::log10 (-values(i)));
8324 exponent =
std::floor (std::log10 (values(i)));
8325 significand = values(i) *
std::pow (10., -exponent);
8329 10*std::numeric_limits<double>::epsilon())
8330 os << significand <<
'x';
8331 else if (significand < 0)
8339 exponent = -exponent;
8341 if (exponent < 10. && (exp_max > 9 || exp_min < -9))
8343 os << exponent <<
'}';
8345 if (m_ticklabelinterpreter.is (
"latex"))
8346 c(i) =
"$" + os.str () +
"$";
8353 for (
int i = 0; i < values.
numel (); i++)
8355 bool omit_tick =
false;
8356 for (
int i_omit = 0; i_omit < omit_ticks.numel (); i_omit++)
8357 if (values(i) == omit_ticks(i_omit))
8374 axes::properties::get_ticklabel_extents (
const Matrix& ticks,
8383 for (
int i = 0; i <
n; i++)
8385 double val = ticks(i);
8386 if (limits(0) <= val && val <= limits(1))
8388 std::string label (ticklabels(i));
8389 label.erase (0, label.find_first_not_of (
' '));
8390 label = label.substr (0, label.find_last_not_of (
' ')+1);
8392 if (m_txt_renderer.ok ())
8396 octave::autolock guard (gh_mgr.graphics_lock ());
8398 ext = m_txt_renderer.get_extent (label, 0.0,
8399 get_ticklabelinterpreter ());
8401 wmax =
std::max (wmax, ext(0) / dpr);
8402 hmax =
std::max (hmax, ext(1) / dpr);
8407 double fsize = get (
"fontsize").double_value ();
8408 int len = label.length ();
8423 double& min_pos,
double& max_neg,
8424 const Matrix& kids,
char limit_type)
8435 graphics_object go = gh_mgr.get_object (kids(i));
8437 if (go.is_xliminclude ())
8449 graphics_object go = gh_mgr.get_object (kids(i));
8451 if (go.is_yliminclude ())
8463 graphics_object go = gh_mgr.get_object (kids(i));
8465 if (go.is_zliminclude ())
8477 graphics_object go = gh_mgr.get_object (kids(i));
8479 if (go.is_climinclude ())
8491 graphics_object go = gh_mgr.get_object (kids(i));
8493 if (go.is_aliminclude ())
8510 axes::update_axis_limits (
const std::string& axis_type,
8524 char update_type = 0;
8529 #define FIX_LIMITS \
8531 if (octave::math::isfinite (val)) \
8534 if (octave::math::isfinite (val)) \
8537 if (axis_type ==
"xdata" || axis_type ==
"xscale"
8538 || axis_type ==
"xlimmode" || axis_type ==
"xliminclude"
8539 || axis_type ==
"xlim")
8541 limits = m_properties.get_xlim ().matrix_value ();
8545 if (m_properties.xlimmode_is (
"auto"))
8549 std::string method = m_properties.get_xlimitmethod ();
8550 limits = m_properties.get_axis_limits (min_val, max_val,
8552 m_properties.xscale_is (
"log"),
8556 m_properties.check_axis_limits (limits, kids,
8557 m_properties.xscale_is (
"log"),
8560 else if (axis_type ==
"ydata" || axis_type ==
"yscale"
8561 || axis_type ==
"ylimmode" || axis_type ==
"yliminclude"
8562 || axis_type ==
"ylim")
8564 limits = m_properties.get_ylim ().matrix_value ();
8568 if (m_properties.ylimmode_is (
"auto"))
8572 std::string method = m_properties.get_ylimitmethod ();
8573 limits = m_properties.get_axis_limits (min_val, max_val,
8575 m_properties.yscale_is (
"log"),
8579 m_properties.check_axis_limits (limits, kids,
8580 m_properties.yscale_is (
"log"),
8583 else if (axis_type ==
"zdata" || axis_type ==
"zscale"
8584 || axis_type ==
"zlimmode" || axis_type ==
"zliminclude"
8585 || axis_type ==
"zlim")
8587 limits = m_properties.get_zlim ().matrix_value ();
8591 if (m_properties.zlimmode_is (
"auto"))
8595 m_properties.set_has3Dkids ((max_val - min_val) >
8596 std::numeric_limits<double>::epsilon ());
8598 std::string method = m_properties.get_zlimitmethod ();
8599 limits = m_properties.get_axis_limits (min_val, max_val,
8601 m_properties.zscale_is (
"log"),
8610 m_properties.set_has3Dkids ((max_val - min_val) >
8611 std::numeric_limits<double>::epsilon ());
8613 m_properties.check_axis_limits (limits, kids,
8614 m_properties.zscale_is (
"log"),
8618 else if (axis_type ==
"cdata" || axis_type ==
"climmode"
8619 || axis_type ==
"cdatamapping" || axis_type ==
"climinclude"
8620 || axis_type ==
"clim")
8622 if (m_properties.climmode_is (
"auto"))
8624 limits = m_properties.get_clim ().matrix_value ();
8629 if (min_val > max_val)
8631 min_val = min_pos = 0;
8634 else if (min_val == max_val)
8636 max_val = min_val + 1;
8640 limits(0) = min_val;
8641 limits(1) = max_val;
8646 else if (axis_type ==
"alphadata" || axis_type ==
"alimmode"
8647 || axis_type ==
"alphadatamapping" || axis_type ==
"aliminclude"
8648 || axis_type ==
"alim")
8650 if (m_properties.alimmode_is (
"auto"))
8652 limits = m_properties.get_alim ().matrix_value ();
8657 if (min_val > max_val)
8659 min_val = min_pos = 0;
8662 else if (min_val == max_val)
8663 max_val = min_val + 1;
8665 limits(0) = min_val;
8666 limits(1) = max_val;
8674 octave::unwind_protect_var<std::set<double>>
8680 switch (update_type)
8683 is_auto = m_properties.xlimmode_is (
"auto");
8684 m_properties.set_xlim (limits);
8686 m_properties.set_xlimmode (
"auto");
8687 m_properties.update_xlim ();
8691 is_auto = m_properties.ylimmode_is (
"auto");
8692 m_properties.set_ylim (limits);
8694 m_properties.set_ylimmode (
"auto");
8695 m_properties.update_ylim ();
8699 is_auto = m_properties.zlimmode_is (
"auto");
8700 m_properties.set_zlim (limits);
8702 m_properties.set_zlimmode (
"auto");
8703 m_properties.update_zlim ();
8707 m_properties.set_clim (limits);
8708 m_properties.set_climmode (
"auto");
8712 m_properties.set_alim (limits);
8713 m_properties.set_alimmode (
"auto");
8720 m_properties.update_transform ();
8727 axes::update_axis_limits (
const std::string& axis_type)
8735 Matrix kids = m_properties.get_all_children ();
8742 char update_type = 0;
8746 if (axis_type ==
"xdata" || axis_type ==
"xscale"
8747 || axis_type ==
"xlimmode" || axis_type ==
"xliminclude"
8748 || axis_type ==
"xlim")
8751 if (m_properties.xlimmode_is (
"auto"))
8755 std::string method = m_properties.get_xlimitmethod ();
8756 limits = m_properties.get_axis_limits (min_val, max_val,
8758 m_properties.xscale_is (
"log"),
8763 limits = m_properties.get_xlim ().matrix_value ();
8764 m_properties.check_axis_limits (limits, kids,
8765 m_properties.xscale_is (
"log"),
8767 if (axis_type ==
"xscale")
8771 else if (axis_type ==
"ydata" || axis_type ==
"yscale"
8772 || axis_type ==
"ylimmode" || axis_type ==
"yliminclude"
8773 || axis_type ==
"ylim")
8776 if (m_properties.ylimmode_is (
"auto"))
8780 std::string method = m_properties.get_ylimitmethod ();
8781 limits = m_properties.get_axis_limits (min_val, max_val,
8783 m_properties.yscale_is (
"log"),
8788 limits = m_properties.get_ylim ().matrix_value ();
8789 m_properties.check_axis_limits (limits, kids,
8790 m_properties.yscale_is (
"log"),
8792 if (axis_type ==
"yscale")
8796 else if (axis_type ==
"zdata" || axis_type ==
"zscale"
8797 || axis_type ==
"zlimmode" || axis_type ==
"zliminclude"
8798 || axis_type ==
"zlim")
8801 if (m_properties.zlimmode_is (
"auto"))
8805 m_properties.set_has3Dkids ((max_val - min_val) >
8806 std::numeric_limits<double>::epsilon ());
8811 && ! m_properties.zscale_is (
"log"))
8812 min_val = max_val = 0.;
8814 std::string method = m_properties.get_zlimitmethod ();
8815 limits = m_properties.get_axis_limits (min_val, max_val,
8817 m_properties.zscale_is (
"log"),
8826 m_properties.set_has3Dkids ((max_val - min_val) >
8827 std::numeric_limits<double>::epsilon ());
8829 limits = m_properties.get_zlim ().matrix_value ();
8830 m_properties.check_axis_limits (limits, kids,
8831 m_properties.zscale_is (
"log"),
8833 if (axis_type ==
"zscale")
8837 else if (axis_type ==
"cdata" || axis_type ==
"climmode"
8838 || axis_type ==
"cdatamapping" || axis_type ==
"climinclude"
8839 || axis_type ==
"clim")
8841 if (m_properties.climmode_is (
"auto"))
8845 if (min_val > max_val)
8847 min_val = min_pos = 0;
8850 else if (min_val == max_val)
8852 max_val = min_val + 1;
8858 limits(0) = min_val;
8859 limits(1) = max_val;
8865 else if (axis_type ==
"alphadata" || axis_type ==
"alimmode"
8866 || axis_type ==
"alphadatamapping" || axis_type ==
"aliminclude"
8867 || axis_type ==
"alim")
8869 if (m_properties.alimmode_is (
"auto"))
8873 if (min_val > max_val)
8875 min_val = min_pos = 0;
8878 else if (min_val == max_val)
8879 max_val = min_val + 1;
8883 limits(0) = min_val;
8884 limits(1) = max_val;
8891 octave::unwind_protect_var<std::set<double>>
8897 switch (update_type)
8900 is_auto = m_properties.xlimmode_is (
"auto");
8901 m_properties.set_xlim (limits);
8903 m_properties.set_xlimmode (
"auto");
8904 m_properties.update_xlim ();
8908 is_auto = m_properties.ylimmode_is (
"auto");
8909 m_properties.set_ylim (limits);
8911 m_properties.set_ylimmode (
"auto");
8912 m_properties.update_ylim ();
8916 is_auto = m_properties.zlimmode_is (
"auto");
8917 m_properties.set_zlim (limits);
8919 m_properties.set_zlimmode (
"auto");
8920 m_properties.update_zlim ();
8924 m_properties.set_clim (limits);
8925 m_properties.set_climmode (
"auto");
8929 m_properties.set_alim (limits);
8930 m_properties.set_alimmode (
"auto");
8937 m_properties.update_transform ();
8956 double lo = lims(0);
8957 double hi = lims(1);
8959 bool is_negative = lo < 0 && hi < 0;
8966 hi = std::log10 (-lo);
8967 lo = std::log10 (-tmp);
8968 val = std::log10 (-val);
8972 hi = std::log10 (hi);
8973 lo = std::log10 (lo);
8974 val = std::log10 (val);
8979 lo = val + (lo - val) / factor;
8980 hi = val + (hi - val) / factor;
9004 axes::properties::zoom_about_point (
const std::string& mode,
9005 double x,
double y,
double factor,
9006 bool push_to_zoom_stack)
9009 Matrix xlims = get_xlim ().matrix_value ();
9010 Matrix ylims = get_ylim ().matrix_value ();
9013 Matrix kids = get_children ();
9026 xlims =
do_zoom (
x, factor, xlims, xscale_is (
"log"));
9027 ylims =
do_zoom (y, factor, ylims, yscale_is (
"log"));
9029 zoom (mode, xlims, ylims, push_to_zoom_stack);
9033 axes::properties::zoom (
const std::string& mode,
double factor,
9034 bool push_to_zoom_stack)
9037 Matrix xlims = get_xlim ().matrix_value ();
9038 Matrix ylims = get_ylim ().matrix_value ();
9040 double x = (xlims(0) + xlims(1)) / 2;
9041 double y = (ylims(0) + ylims(1)) / 2;
9043 zoom_about_point (mode,
x, y, factor, push_to_zoom_stack);
9047 axes::properties::push_zoom_stack (
void)
9049 if (m_zoom_stack.empty ())
9051 m_zoom_stack.push_front (m_xlimmode.get ());
9052 m_zoom_stack.push_front (m_xlim.get ());
9053 m_zoom_stack.push_front (m_ylimmode.get ());
9054 m_zoom_stack.push_front (m_ylim.get ());
9055 m_zoom_stack.push_front (m_zlimmode.get ());
9056 m_zoom_stack.push_front (m_zlim.get ());
9057 m_zoom_stack.push_front (m_view.get ());
9062 axes::properties::zoom (
const std::string& mode,
9064 bool push_to_zoom_stack)
9066 if (xl(0) == xl(1) || yl(0) == yl(1))
9068 warning (
"invalid zoom region");
9072 if (push_to_zoom_stack)
9075 if (mode ==
"horizontal" || mode ==
"both")
9078 m_xlimmode =
"manual";
9081 if (mode ==
"vertical" || mode ==
"both")
9084 m_ylimmode =
"manual";
9087 update_transform ();
9089 if (mode ==
"horizontal" || mode ==
"both")
9092 if (mode ==
"vertical" || mode ==
"both")
9101 double lo = lims(0);
9102 double hi = lims(1);
9104 bool is_negative = lo < 0 && hi < 0;
9113 hi = std::log10 (-lo);
9114 lo = std::log10 (-tmp);
9120 hi = std::log10 (hi);
9121 lo = std::log10 (lo);
9124 delta = std::log10 (x0) - std::log10 (x1);
9157 axes::properties::translate_view (
const std::string& mode,
9158 double x0,
double x1,
double y0,
double y1,
9159 bool push_to_zoom_stack)
9162 Matrix xlims = get_xlim ().matrix_value ();
9163 Matrix ylims = get_ylim ().matrix_value ();
9166 Matrix kids = get_children ();
9179 xlims =
do_translate (x0, x1, xlims, xscale_is (
"log"));
9180 ylims =
do_translate (y0, y1, ylims, yscale_is (
"log"));
9182 zoom (mode, xlims, ylims, push_to_zoom_stack);
9186 axes::properties::pan (
const std::string& mode,
double factor,
9187 bool push_to_zoom_stack)
9190 Matrix xlims = get_xlim ().matrix_value ();
9191 Matrix ylims = get_ylim ().matrix_value ();
9193 double x0 = (xlims(0) + xlims(1)) / 2;
9194 double y0 = (ylims(0) + ylims(1)) / 2;
9196 double x1 = x0 + (xlims(1) - xlims(0)) * factor;
9197 double y1 = y0 + (ylims(1) - ylims(0)) * factor;
9199 translate_view (mode, x0, x1, y0, y1, push_to_zoom_stack);
9203 axes::properties::rotate3d (
double x0,
double x1,
double y0,
double y1,
9204 bool push_to_zoom_stack)
9206 if (push_to_zoom_stack)
9209 Matrix bb = get_boundingbox (
true);
9210 Matrix new_view = get_view ().matrix_value ();
9213 new_view(0) += ((x0 - x1) * (180.0 / bb(2)));
9214 new_view(1) += ((y1 - y0) * (180.0 / bb(3)));
9217 new_view(1) =
std::min (new_view(1), 90.0);
9218 new_view(1) =
std::max (new_view(1), -90.0);
9219 if (new_view(0) > 180.0)
9220 new_view(0) -= 360.0;
9221 else if (new_view(0) < -180.0)
9222 new_view(0) += 360.0;
9225 double snapmargin = 1.0;
9226 for (
int a = -90; a <= 90; a += 90)
9228 if ((a - snapmargin) < new_view(1) && new_view(1) < (a + snapmargin))
9235 for (
int a = -180; a <= 180; a += 180)
9236 if ((a - snapmargin) < new_view(0) && new_view(0) < (a + snapmargin))
9246 set_view (new_view);
9250 axes::properties::rotate_view (
double delta_el,
double delta_az,
9251 bool push_to_zoom_stack)
9253 if (push_to_zoom_stack)
9256 Matrix v = get_view ().matrix_value ();
9265 v(0) = fmod (v(0) - delta_az + 720, 360);
9269 update_transform ();
9273 axes::properties::unzoom (
void)
9275 if (m_zoom_stack.size () >= 7)
9277 m_view = m_zoom_stack.front ();
9278 m_zoom_stack.pop_front ();
9280 m_zlim = m_zoom_stack.front ();
9281 m_zoom_stack.pop_front ();
9283 m_zlimmode = m_zoom_stack.front ();
9284 m_zoom_stack.pop_front ();
9286 m_ylim = m_zoom_stack.front ();
9287 m_zoom_stack.pop_front ();
9289 m_ylimmode = m_zoom_stack.front ();
9290 m_zoom_stack.pop_front ();
9292 m_xlim = m_zoom_stack.front ();
9293 m_zoom_stack.pop_front ();
9295 m_xlimmode = m_zoom_stack.front ();
9296 m_zoom_stack.pop_front ();
9298 update_transform ();
9309 axes::properties::update_handlevisibility (
void)
9315 graphics_object go (gh_mgr.get_object (get___myhandle__ ()));
9317 graphics_object fig (go.get_ancestor (
"figure"));
9321 octave::autolock guard (gh_mgr.graphics_lock ());
9325 fig.set (
"currentaxes",
Matrix ());
9329 fig.set (
"currentaxes", kidsarray(0));
9334 base_properties::update_handlevisibility ();
9338 figure::properties::init_toolkit (
void)
9342 m_toolkit = gtk_mgr.get_toolkit ();
9346 axes::properties::clear_zoom_stack (
bool do_unzoom)
9348 std::size_t items_to_leave_on_stack = (do_unzoom ? 7 : 0);
9350 while (m_zoom_stack.size () > items_to_leave_on_stack)
9351 m_zoom_stack.pop_front ();
9358 axes::properties::trigger_normals_calc (
void)
9361 std::list<graphics_object> children_list;
9362 std::list<graphics_object>::iterator children_list_iter;
9363 get_children_of_type (
"patch",
false,
true, children_list);
9364 get_children_of_type (
"surface",
false,
true, children_list);
9367 for (children_list_iter = children_list.begin ();
9368 children_list_iter != children_list.end (); children_list_iter++)
9370 graphics_object kid = *children_list_iter;
9371 if (kid.isa (
"patch"))
9375 patch_props.update_normals (
false);
9381 surface_props.update_normals (
false);
9387 axes::reset_default_properties (
void)
9390 m_default_properties = property_list ();
9396 remove_all_listeners ();
9397 set_defaults (
"reset");
9412 m_properties.sync_positions ();
9418 line::properties::compute_xlim (
void)
const
9422 m(0) = m_xdata.min_val ();
9423 m(1) = m_xdata.max_val ();
9424 m(2) = m_xdata.min_pos ();
9425 m(3) = m_xdata.max_neg ();
9431 line::properties::compute_ylim (
void)
const
9435 m(0) = m_ydata.min_val ();
9436 m(1) = m_ydata.max_val ();
9437 m(2) = m_ydata.min_pos ();
9438 m(3) = m_ydata.max_neg ();
9446 text::properties::get_data_position (
void)
const
9448 Matrix pos = get_position ().matrix_value ();
9450 if (! units_is (
"data"))
9457 text::properties::get_extent_matrix (
bool rotated)
const
9460 Matrix ext = m_extent.get ().matrix_value ();
9462 if (rotated && get_rotation () != 0)
9464 double rot = get_rotation () * 4.0 *
atan (1.0) / 180;
9465 double x0 = ext(0) * cos (rot) - ext(1) * sin (rot);
9467 double y0 = ext(0) * sin (rot) + ext(1) * cos (rot);
9470 double tmp = (ext(0)+ext(2)) * cos (rot) - ext(1) * sin (rot);
9473 tmp = (ext(0)+ext(2)) * sin (rot) + ext(1) * cos (rot);
9477 tmp = (ext(0)+ext(2)) * cos (rot) - (ext(1)+ext(3)) * sin (rot);
9480 tmp = (ext(0)+ext(2)) * sin (rot) + (ext(1)+ext(3)) * cos (rot);
9484 tmp = ext(0) * cos (rot) - (ext(1)+ext(3)) * sin (rot);
9487 tmp = ext(0) * sin (rot) + (ext(1)+ext(3)) * cos (rot);
9501 text::properties::get_extent (
void)
const
9505 Matrix m = get_extent_matrix (
true);
9506 Matrix pos = get_position ().matrix_value ();
9517 bbox(ii) = bbox(ii) / dpr;
9523 text::properties::set_fontunits (
const octave_value& val)
9527 if (m_fontunits.set (val,
true))
9529 update_fontunits (old_fontunits);
9535 text::properties::update_fontunits (
const caseless_str& old_units)
9538 double parent_height = 0;
9539 double fontsz = get_fontsize ();
9541 if (new_units ==
"normalized" || old_units ==
"normalized")
9545 graphics_object go (gh_mgr.get_object (get___myhandle__ ()));
9547 graphics_object ax (go.get_ancestor (
"axes"));
9549 parent_height = ax.get_properties ().get_boundingbox (
true).elem (3);
9558 text::properties::update_font (
void)
9564 octave::autolock guard (gh_mgr.graphics_lock ());
9566 m_txt_renderer.set_font (get (
"fontname").string_value (),
9567 get (
"fontweight").string_value (),
9568 get (
"fontangle").string_value (),
9569 get (
"__fontsize_points__").double_value () * dpr);
9571 m_txt_renderer.set_anti_aliasing (is_fontsmoothing ());
9573 Matrix c = get_color_rgb ();
9575 m_txt_renderer.set_color (c);
9580 text::properties::update_text_extent (
void)
9585 if (horizontalalignment_is (
"center"))
9587 else if (horizontalalignment_is (
"right"))
9590 if (verticalalignment_is (
"middle"))
9592 else if (verticalalignment_is (
"top"))
9594 else if (verticalalignment_is (
"baseline"))
9596 else if (verticalalignment_is (
"cap"))
9609 octave::autolock guard (gh_mgr.graphics_lock ());
9611 m_txt_renderer.text_to_pixels (sv.
join (
"\n"), m_pixels, bbox,
9612 halign, valign, 0.0, get_interpreter ());
9619 if (__autopos_tag___is (
"xlabel") || __autopos_tag___is (
"ylabel")
9620 || __autopos_tag___is (
"zlabel") || __autopos_tag___is (
"title"))
9621 update_autopos (
"sync");
9625 text::properties::request_autopos (
void)
9627 if (__autopos_tag___is (
"xlabel") || __autopos_tag___is (
"ylabel")
9628 || __autopos_tag___is (
"zlabel") || __autopos_tag___is (
"title"))
9629 update_autopos (get___autopos_tag__ ());
9633 text::properties::update_units (
void)
9635 if (! units_is (
"data"))
9637 set_xliminclude (
"off");
9638 set_yliminclude (
"off");
9639 set_zliminclude (
"off");
9642 Matrix pos = get_position ().matrix_value ();
9649 bool autopos = positionmode_is (
"auto");
9654 set_positionmode (
"auto");
9656 if (units_is (
"data"))
9658 set_xliminclude (
"on");
9659 set_yliminclude (
"on");
9661 set_zliminclude (
"off");
9664 m_cached_units = get_units ();
9668 text::properties::get___fontsize_points__ (
double box_pix_height)
const
9670 double fontsz = get_fontsize ();
9671 double parent_height = box_pix_height;
9675 graphics_object go (gh_mgr.get_object (get___myhandle__ ()));
9677 if (fontunits_is (
"normalized") && parent_height <= 0)
9679 graphics_object ax (go.get_ancestor (
"axes"));
9681 parent_height = ax.get_properties ().get_boundingbox (
true).elem (3);
9690 image::properties::get_color_data (
void)
const
9692 return convert_cdata (*
this, get_cdata (), cdatamapping_is (
"scaled"), 3);
9704 =
dynamic_cast<axes::properties&
> (go.get_ancestor (
"axes").get_properties ());
9705 parent_axes_prop.trigger_normals_calc ();
9709 light::properties::update_visible (
void)
9713 graphics_object go = gh_mgr.get_object (get___myhandle__ ());
9716 (go.get_ancestor (
"axes").get_properties ());
9718 ax_props.increase_num_lights ();
9720 ax_props.decrease_num_lights ();
9726 patch::properties::get_do_lighting (
void)
const
9730 graphics_object go = gh_mgr.get_object (get___myhandle__ ());
9733 (go.get_ancestor (
"axes").get_properties ());
9735 return (ax_props.get_num_lights () > 0);
9739 patch::properties::get_color_data (
void)
const
9745 return convert_cdata (*
this, fvc, cdatamapping_is (
"scaled"), 2);
9751 patch::properties::update_fvc (
void)
9756 Matrix xd = get_xdata ().matrix_value ();
9757 Matrix yd = get_ydata ().matrix_value ();
9758 Matrix zd = get_zdata ().matrix_value ();
9759 NDArray cd = get_cdata ().array_value ();
9761 m_bad_data_msg =
"";
9765 m_bad_data_msg =
"x/y/zdata must have the same dimensions";
9774 if (nr == 1 && nc > 1)
9800 vert(kk, 0) = xd(ii, jj);
9801 vert(kk, 1) = yd(ii, jj);
9803 vert(kk, 2) = zd(ii, jj);
9805 idx(jj, ii) =
static_cast<double> (kk+1);
9813 if (cd.
ndims () == 3)
9816 dv(1) = cd.
dims ()(2);
9827 m_vertices.set (vert);
9828 m_facevertexcdata.set (fvc);
9837 double tol = 100 * std::numeric_limits<double>::epsilon ();
9838 EIG eig (cov,
false,
false,
true);
9840 return ev.
min () <= tol * ev.
max ();
9843 std::vector<octave_idx_type>
9847 std::vector<octave_idx_type> coplanar_ends;
9851 plane_pivot(0, i) = vert(idx(0, jj)-1, i);
9869 fc(j-1, i) = vert(idx(j, jj)-1, i) - plane_pivot(i);
9874 coplanar_ends.push_back (nc - 1);
9875 return coplanar_ends;
9885 while (i_start < nc - 1)
9887 i_end = i_start + 2;
9890 coplanar_ends.push_back (nc - 1);
9902 fc(j, i) = vert(idx(j+i_start, jj)-1, i) - plane_pivot(i);
9919 fa(0, i) = vert(idx(i_end, jj)-1, i) - plane_pivot(i);
9923 i_start = i_end - 1;
9924 coplanar_ends.push_back (i_start);
9926 return coplanar_ends;
9930 patch::properties::update_data (
void)
9936 Matrix vert = get_vertices ().matrix_value ();
9943 m_bad_data_msg =
"";
9944 if (
static_cast<double> (nvert) < idx.
row_max ().
max ())
9946 m_bad_data_msg = R
"(some vertices in "faces" property are undefined)";
9955 double valid_vert = idx(0, jj);
9956 bool turn_valid =
false;
9961 idx(ii, jj) = valid_vert;
9965 valid_vert = idx(ii, jj);
9971 int fcmax = idx.
rows ();
9972 if (fcmax > 3 && vert.
columns () > 2
9973 && ! (facecolor_is (
"none") && edgecolor_is (
"none")))
9975 m_coplanar_last_idx.resize (idx.
columns ());
9988 bool is_unclosed =
false;
10007 m_coplanar_last_idx.resize (0);
10012 bool pervertex =
false;
10014 if (fvc.
rows () == nfaces || fvc.
rows () == 1)
10017 dv(1) = fvc.
rows ();
10025 dv(0) = idx.
rows ();
10037 bool has_zd =
false;
10049 xd(ii, jj) = vert(row, 0);
10050 yd(ii, jj) = vert(row, 1);
10053 zd(ii, jj) = vert(row, 2);
10056 for (
int kk = 0; kk < fvc.
columns (); kk++)
10057 cd(ii, jj, kk) = fvc(row, kk);
10062 update_normals (
true);
10074 double x2,
double y2,
double z2,
10075 double&
x,
double& y,
double& z)
10077 x += (y1 * z2 - z1 * y2);
10078 y += (z1 * x2 - x1 * z2);
10079 z += (x1 * y2 - y1 * x2);
10083 patch::properties::calc_face_normals (
Matrix& fn)
10085 Matrix v = get_vertices ().matrix_value ();
10086 Matrix f = get_faces ().matrix_value ();
10088 bool is_3D = (v.
columns () == 3);
10105 if (m_coplanar_last_idx.size () > 0 && m_coplanar_last_idx[i].size () > 1)
10117 double& nx = fnc(0);
10118 double& ny = fnc(1);
10119 double& nz = fnc(2);
10124 i1 =
f(i, 0) - 1; i2 =
f(i, 1) - 1; i3 =
f(i, nc-1) - 1;
10128 (v(i3, 0) - v(i1, 0), v(i3, 1) - v(i1, 1), v(i3, 2) - v(i1, 2),
10129 v(i2, 0) - v(i1, 0), v(i2, 1) - v(i1, 1), v(i2, 2) - v(i1, 2),
10133 nz = (v(i2, 0) - v(i1, 0)) * (v(i3, 1) - v(i1, 1)) -
10134 (v(i2, 1) - v(i1, 1)) * (v(i3, 0) - v(i1, 0));
10136 nz = (nz < 0) ? -nz : nz;
10146 j1 = nc - 1; j2 = 0;
10147 i1 =
f(i, j1) - 1; i2 =
f(i, j2) - 1;
10149 nx = (v(i2, 1) - v(i1, 1)) * (v(i1, 2) + v(i2, 2));
10150 ny = (v(i2, 2) - v(i1, 2)) * (v(i1, 0) + v(i2, 0));
10151 nz = (v(i2, 0) - v(i1, 0)) * (v(i1, 1) + v(i2, 1));
10156 i1 =
f(i, j1) - 1; i2 =
f(i, j2) - 1;
10158 nx += (v(i2, 1) - v(i1, 1)) * (v(i1, 2) + v(i2, 2));
10159 ny += (v(i2, 2) - v(i1, 2)) * (v(i1, 0) + v(i2, 0));
10160 nz += (v(i2, 0) - v(i1, 0)) * (v(i1, 1) + v(i2, 1));
10165 double n_len = sqrt (nx*nx+ny*ny+nz*nz);
10168 if ( n_len < std::numeric_limits<double>::epsilon () )
10173 fn(i, j) = fnc(j) / n_len;
10178 patch::properties::update_face_normals (
bool reset,
bool force)
10183 if (force || ((facelighting_is (
"flat") || edgelighting_is (
"flat"))
10184 && get_do_lighting ()))
10186 Matrix f = get_faces ().matrix_value ();
10189 Matrix fn (num_f, 3, 0.0);
10191 calc_face_normals (fn);
10192 m_facenormals = fn;
10195 m_facenormals =
Matrix ();
10199 patch::properties::update_vertex_normals (
bool reset,
bool force)
10204 if (force || ((facelighting_is (
"gouraud") || facelighting_is (
"phong")
10205 || edgelighting_is (
"gouraud") || edgelighting_is (
"phong"))
10206 && get_do_lighting ()))
10208 Matrix v = get_vertices ().matrix_value ();
10209 Matrix f = get_faces ().matrix_value ();
10220 Matrix fn = get_facenormals ().matrix_value ();
10224 fn =
Matrix (num_f, 3, 0.0);
10225 calc_face_normals (fn);
10237 std::vector<std::vector<RowVector>> vec_vn (num_v);
10254 Matrix vn (num_v, 3, 0.0);
10257 std::vector<RowVector>::iterator it = vec_vn[i].begin ();
10262 if (it != vec_vn[i].end ())
10273 for (++it; it != vec_vn[i].end (); ++it)
10278 double dir = (vn0(0)*vn1(0) + vn0(1)*vn1(1) + vn0(2)*vn1(2) < 0) ? -1 : 1;
10280 vn0(j) += dir * vn1(j);
10284 double n_len = sqrt (vn0(0)*vn0(0)+vn0(1)*vn0(1)+vn0(2)*vn0(2));
10288 vn(i, j) = vn0(j)/n_len;
10292 m_vertexnormals = vn;
10295 m_vertexnormals =
Matrix ();
10306 m_properties.update_normals (
true);
10311 patch::reset_default_properties (
void)
10314 m_default_properties = property_list ();
10320 m_properties.update_normals (
true);
10326 scatter::properties::get_color_data (
void)
const
10336 scatter::properties::update_data (
void)
10338 Matrix xd = get_xdata ().matrix_value ();
10339 Matrix yd = get_ydata ().matrix_value ();
10340 Matrix zd = get_zdata ().matrix_value ();
10341 Matrix cd = get_cdata ().matrix_value ();
10342 Matrix sd = get_sizedata ().matrix_value ();
10344 m_bad_data_msg =
"";
10348 m_bad_data_msg =
"x/y/zdata must have the same dimensions";
10356 if (! cd.
isempty () && (c_rows != 1 || c_cols != 3)
10357 && (c_rows != x_rows || (c_cols != 1 && c_cols != 3)))
10359 m_bad_data_msg =
"cdata must be an rgb triplet or have the same number "
10360 "of rows as X and one or three columns";
10365 if (s_rows != 1 && s_rows != x_rows)
10367 m_bad_data_msg =
"sizedata must be a scalar or a vector with the same "
10376 scatter::properties::update_color (
void)
10381 Matrix series_idx = get_seriesindex ().matrix_value ();
10387 graphics_object go = gh_mgr.get_object (get___myhandle__ ());
10391 (go.get_ancestor (
"axes").get_properties ());
10393 Matrix color_order = parent_axes_prop.get_colororder ().matrix_value ();
10395 % color_order.
rows ();
10398 color(0) = color_order(s, 0);
10399 color(1) = color_order(s, 1);
10400 color(2) = color_order(s, 2);
10405 set_cdatamode (
"auto");
10413 Matrix series_idx = m_properties.get_seriesindex ().matrix_value ();
10419 (go.get_ancestor (
"axes").get_properties ());
10421 if (! parent_axes_prop.nextplot_is (
"add"))
10422 parent_axes_prop.set_nextseriesindex (1);
10424 series_idx.
resize (1, 1);
10425 series_idx(0) = parent_axes_prop.get_nextseriesindex ();
10426 m_properties.set_seriesindex (series_idx);
10428 parent_axes_prop.set_nextseriesindex
10429 (parent_axes_prop.get_nextseriesindex () + 1);
10432 if (m_properties.cdatamode_is (
"auto"))
10433 m_properties.update_color ();
10439 surface::properties::get_color_data (
void)
const
10441 return convert_cdata (*
this, get_cdata (), cdatamapping_is (
"scaled"), 3);
10445 surface::properties::get_do_lighting (
void)
const
10449 graphics_object go = gh_mgr.get_object (get___myhandle__ ());
10452 (go.get_ancestor (
"axes").get_properties ());
10454 return (ax_prop.get_num_lights () > 0);
10458 surface::properties::update_face_normals (
bool reset,
bool force)
10460 if (! facenormalsmode_is (
"auto"))
10463 if (force || ((facelighting_is (
"flat") || edgelighting_is (
"flat"))
10464 && get_do_lighting ()))
10466 Matrix x = get_xdata ().matrix_value ();
10467 Matrix y = get_ydata ().matrix_value ();
10468 Matrix z = get_zdata ().matrix_value ();
10479 if (
x.columns () != p || y.
rows () != q)
10482 bool x_mat = (
x.rows () == q);
10483 bool y_mat = (y.
columns () == p);
10487 int i1, i2, j1, j2;
10490 double x0, x1, x2, x3, y0, y1, y2, y3, z0, z1, z2, z3;
10491 double x1m0, x2m1, x3m2, x0m3, y1m0, y2m1, y3m2, y0m3;
10492 double x1p0, x2p1, x3p2, x0p3, y1p0, y2p1, y3p2, y0p3;
10494 x2m1 = x0m3 = y1m0 = y3m2 = 0;
10497 x1p0 = x3p2 = y2p1 = y0p3 = 1;
10500 for (
int i = 0; i < p-1; i++)
10505 for (
int j = 0; j < q-1; j++)
10510 if (x_mat || y_mat)
10512 x0 =
x(x_mat?j1:0, y_mat?i1:0);
10513 x1 =
x(x_mat?j1:0, y_mat?i2:0);
10514 x2 =
x(x_mat?j2:0, y_mat?i2:0);
10515 x3 =
x(x_mat?j2:0, y_mat?i1:0);
10524 y0 = y(x_mat?j1:0, y_mat?i1:0);
10525 y1 = y(x_mat?j1:0, y_mat?i2:0);
10526 y2 = y(x_mat?j2:0, y_mat?i2:0);
10527 y3 = y(x_mat?j2:0, y_mat?i1:0);
10538 double& nx =
n(j, i, 0);
10539 double& ny =
n(j, i, 1);
10540 double& nz =
n(j, i, 2);
10550 nx = y1m0 * (z1 + z0) + y2m1 * (z2 + z1)
10551 + y3m2 * (z3 + z2) + y0m3 * (z0 + z3);
10552 ny = (z1 - z0) * x1p0 + (z2 - z1) * x2p1
10553 + (z3 - z2) * x3p2 + (z0 - z3) * x0p3;
10554 nz = x1m0 * y1p0 + x2m1 * y2p1 + x3m2 * y3p2 + x0m3 * y0p3;
10566 m_facenormals =
Matrix ();
10570 surface::properties::update_vertex_normals (
bool reset,
bool force)
10572 if (! vertexnormalsmode_is (
"auto"))
10575 if (force || ((facelighting_is (
"gouraud") || facelighting_is (
"phong")
10576 || edgelighting_is (
"gouraud") || edgelighting_is (
"phong"))
10577 && get_do_lighting ()))
10579 Matrix x = get_xdata ().matrix_value ();
10580 Matrix y = get_ydata ().matrix_value ();
10581 Matrix z = get_zdata ().matrix_value ();
10592 if (
x.columns () != p || y.
rows () != q)
10597 bool x_mat = (
x.rows () == q);
10598 bool y_mat = (y.
columns () == p);
10600 int i1, i2, i3, j1, j2, j3;
10604 for (
int i = 0; i < p; i++)
10613 for (
int j = 0; j < q; j++)
10622 double& nx =
n(j, i, 0);
10623 double& ny =
n(j, i, 1);
10624 double& nz =
n(j, i, 2);
10626 if ((j > 0) && (i > 0))
10629 (
x(j1, i-1)-
x(j2, i), y(j-1, i1)-y(j, i2), z(j-1, i-1)-z(j, i),
10630 x(j2, i-1)-
x(j1, i), y(j, i1)-y(j-1, i2), z(j, i-1)-z(j-1, i),
10633 if ((j > 0) && (i < (p -1)))
10636 (
x(j1, i+1)-
x(j2, i), y(j-1, i3)-y(j, i2), z(j-1, i+1)-z(j, i),
10637 x(j1, i)-
x(j2, i+1), y(j-1, i2)-y(j, i3), z(j-1, i)-z(j, i+1),
10640 if ((j < (q - 1)) && (i > 0))
10643 (
x(j2, i-1)-
x(j3, i), y(j, i1)-y(j+1, i2), z(j, i-1)-z(j+1, i),
10644 x(j3, i-1)-
x(j2, i), y(j+1, i1)-y(j, i2), z(j+1, i-1)-z(j, i),
10647 if ((j < (q - 1)) && (i < (p -1)))
10650 (
x(j3, i)-
x(j2, i+1), y(j+1, i2)-y(j, i3), z(j+1, i)-z(j, i+1),
10651 x(j3, i+1)-
x(j2, i), y(j+1, i3)-y(j, i2), z(j+1, i+1)-z(j, i),
10661 m_vertexnormals =
n;
10664 m_vertexnormals =
Matrix ();
10667 DEFMETHOD (__update_normals__, interp, args, ,
10675 gh_manager& gh_mgr = interp.get_gh_manager ();
10677 octave::autolock guard (gh_mgr.graphics_lock ());
10679 if (args.
length () != 1)
10684 graphics_object go = gh_mgr.get_object (val);
10686 if (go.isa (
"surface"))
10690 props.update_normals (
false,
true);
10692 else if (go.isa (
"patch"))
10696 props.update_normals (
false,
true);
10699 error (
"__update_normals__: "
10700 "H must be a handle to a valid surface or patch object.");
10737 hggroup::properties::remove_child (
const graphics_handle& h,
bool from_root)
10741 graphics_object go = gh_mgr.get_object (h);
10743 if (! from_root && go.isa (
"light") && go.get_properties ().is_visible ())
10746 =
dynamic_cast<axes::properties&
> (go.get_ancestor (
"axes").get_properties ());
10747 ax_props.decrease_num_lights ();
10749 base_properties::remove_child (h, from_root);
10758 graphics_object go = gh_mgr.get_object (h);
10760 if (go.isa (
"light") && go.get_properties ().is_visible ())
10763 =
dynamic_cast<axes::properties&
> (go.get_ancestor (
"axes").get_properties ());
10764 ax_props.increase_num_lights ();
10771 hggroup::properties::update_limits (
void)
const
10775 graphics_object go = gh_mgr.get_object (m___myhandle__);
10779 go.update_axis_limits (
"xlim");
10780 go.update_axis_limits (
"ylim");
10781 go.update_axis_limits (
"zlim");
10782 go.update_axis_limits (
"clim");
10783 go.update_axis_limits (
"alim");
10792 graphics_object go = gh_mgr.get_object (m___myhandle__);
10796 go.update_axis_limits (
"xlim", h);
10797 go.update_axis_limits (
"ylim", h);
10798 go.update_axis_limits (
"zlim", h);
10799 go.update_axis_limits (
"clim", h);
10800 go.update_axis_limits (
"alim", h);
10807 hggroup::update_axis_limits (
const std::string& axis_type,
10823 char update_type = 0;
10825 if (axis_type ==
"xlim" || axis_type ==
"xliminclude")
10827 limits = m_properties.get_xlim ().matrix_value ();
10830 else if (axis_type ==
"ylim" || axis_type ==
"yliminclude")
10832 limits = m_properties.get_ylim ().matrix_value ();
10835 else if (axis_type ==
"zlim" || axis_type ==
"zliminclude")
10837 limits = m_properties.get_zlim ().matrix_value ();
10840 else if (axis_type ==
"clim" || axis_type ==
"climinclude")
10842 limits = m_properties.get_clim ().matrix_value ();
10845 else if (axis_type ==
"alim" || axis_type ==
"aliminclude")
10847 limits = m_properties.get_alim ().matrix_value ();
10851 if (limits.
numel () == 4)
10869 limits(0) = min_val;
10870 limits(1) = max_val;
10871 limits(2) = min_pos;
10872 limits(3) = max_neg;
10879 if (limits(0) != min_val || limits(1) != max_val
10880 || limits(2) != min_pos || limits(3) != max_neg)
10882 limits(0) = min_val;
10883 limits(1) = max_val;
10884 limits(2) = min_pos;
10885 limits(3) = max_neg;
10887 switch (update_type)
10890 m_properties.set_xlim (limits);
10894 m_properties.set_ylim (limits);
10898 m_properties.set_zlim (limits);
10902 m_properties.set_clim (limits);
10906 m_properties.set_alim (limits);
10914 base_graphics_object::update_axis_limits (axis_type, hg);
10919 hggroup::update_axis_limits (
const std::string& axis_type)
10924 Matrix kids = m_properties.get_children ();
10931 char update_type = 0;
10933 if (axis_type ==
"xlim" || axis_type ==
"xliminclude")
10939 else if (axis_type ==
"ylim" || axis_type ==
"yliminclude")
10945 else if (axis_type ==
"zlim" || axis_type ==
"zliminclude")
10951 else if (axis_type ==
"clim" || axis_type ==
"climinclude")
10957 else if (axis_type ==
"alim" || axis_type ==
"aliminclude")
10968 limits(0) = min_val;
10969 limits(1) = max_val;
10970 limits(2) = min_pos;
10971 limits(3) = max_neg;
10973 switch (update_type)
10976 m_properties.set_xlim (limits);
10980 m_properties.set_ylim (limits);
10984 m_properties.set_zlim (limits);
10988 m_properties.set_clim (limits);
10992 m_properties.set_alim (limits);
10999 base_graphics_object::update_axis_limits (axis_type);
11005 uicontextmenu::properties::update_beingdeleted (
void)
11008 if (m_beingdeleted.is (
"on"))
11012 std::list<graphics_handle> lst = get_dependent_obj_list ();
11014 for (
auto& hobj : lst)
11016 graphics_object go = gh_mgr.get_object (hobj);
11018 if (go.valid_object ()
11019 && go.get (
"contextmenu") == get___myhandle__ ())
11020 go.set (
"contextmenu",
Matrix ());
11055 uicontrol::properties::get_extent (
void)
const
11057 Matrix m = m_extent.get ().matrix_value ();
11061 graphics_object parent_go = gh_mgr.get_object (get_parent ());
11063 Matrix parent_bbox = parent_go.get_properties ().get_boundingbox (
true);
11070 uicontrol::properties::update_text_extent (
void)
11076 graphics_object go = gh_mgr.get_object (get___myhandle__ ());
11078 set_extent (go.get_toolkit ().get_text_extent (go));
11082 uicontrol::properties::update_units (
void)
11084 Matrix pos = get_position ().matrix_value ();
11088 graphics_object parent_go = gh_mgr.get_object (get_parent ());
11090 Matrix parent_bbox = parent_go.get_properties ().get_boundingbox (
true);
11094 set_position (pos);
11096 m_cached_units = get_units ();
11100 uicontrol::properties::set_style (
const octave_value& st)
11104 graphics_object go_parent = gh_mgr.get_object (get_parent ());
11105 if (go_parent.valid_object () && go_parent.isa (
"uibuttongroup"))
11107 bool was_button = style_is (
"radiobutton") || style_is (
"togglebutton");
11109 bool now_button = style_is (
"radiobutton") || style_is (
"togglebutton");
11113 if (! was_button && now_button && ! props.get_selectedobject ().ok ())
11115 props.set_selectedobject (get___myhandle__ ().value ());
11118 else if (was_button && ! now_button
11119 && (props.get_selectedobject ().value ()
11120 == get___myhandle__ ().value ()))
11121 props.set_selectedobject (
Matrix ());
11125 bool modified = m_style.set (st,
true,
false);
11130 if (style_is (
"listbox") || style_is (
"popupmenu"))
11132 Matrix v = m_value.get ().matrix_value ();
11133 if (v.
numel () == 1 && v(0) == 0)
11139 graphics_object go = gh_mgr.get_object (get___myhandle__ ());
11142 go.update (m_style.get_id ());
11147 uicontrol::properties::get_boundingbox (
bool,
11148 const Matrix& parent_pix_size)
const
11150 Matrix pos = get_position ().matrix_value ();
11151 Matrix parent_size (parent_pix_size);
11157 graphics_object go = gh_mgr.get_object (get_parent ());
11159 if (go.valid_object ())
11160 parent_size = go.get_properties ().get_boundingbox (
true).
extract_n (0, 2, 1, 2);
11169 pos(1) = parent_size(1) - pos(1) - pos(3);
11175 uicontrol::properties::set_fontunits (
const octave_value& val)
11179 if (m_fontunits.set (val,
true))
11181 update_fontunits (old_fontunits);
11187 uicontrol::properties::update_fontunits (
const caseless_str& old_units)
11190 double parent_height = get_boundingbox (
false).elem (3);
11191 double fontsz = get_fontsize ();
11199 uicontrol::properties::get___fontsize_points__ (
double box_pix_height)
const
11201 double fontsz = get_fontsize ();
11202 double parent_height = box_pix_height;
11204 if (fontunits_is (
"normalized") && parent_height <= 0)
11205 parent_height = get_boundingbox (
false).elem (3);
11213 uibuttongroup::properties::get_boundingbox (
bool internal,
11214 const Matrix& parent_pix_size)
const
11216 Matrix pos = get_position ().matrix_value ();
11217 Matrix parent_size (parent_pix_size);
11223 graphics_object go = gh_mgr.get_object (get_parent ());
11225 parent_size = go.get_properties ().get_boundingbox (
true).
extract_n (0, 2, 1, 2);
11232 pos(1) = parent_size(1) - pos(1) - pos(3);
11236 double outer_height = pos(3);
11238 pos(0) = pos(1) = 0;
11240 if (! bordertype_is (
"none"))
11242 double bw = get_borderwidth ();
11245 if (bordertype_is (
"etchedin") || bordertype_is (
"etchedout"))
11248 pos(0) += mul * bw;
11249 pos(1) += mul * bw;
11250 pos(2) -= 2 * mul * bw;
11251 pos(3) -= 2 * mul * bw;
11254 if (! get_title ().empty ())
11256 double fontsz = get_fontsize ();
11258 if (! fontunits_is (
"pixels"))
11262 if (fontunits_is (
"points"))
11263 fontsz *= (res / 72.0);
11264 else if (fontunits_is (
"inches"))
11266 else if (fontunits_is (
"centimeters"))
11267 fontsz *= (res / 2.54);
11268 else if (fontunits_is (
"normalized"))
11269 fontsz *= outer_height;
11272 if (titleposition_is (
"lefttop") || titleposition_is (
"centertop")
11273 || titleposition_is (
"righttop"))
11274 pos(1) += (fontsz / 2);
11275 pos(3) -= (fontsz / 2);
11283 uibuttongroup::properties::set_position (
const octave_value& v)
11286 bool modified =
false;
11288 old_bb = get_boundingbox (
true);
11289 modified = m_position.set (v,
false);
11290 new_bb = get_boundingbox (
true);
11292 if (old_bb != new_bb)
11294 if (old_bb(2) != new_bb(2) || old_bb(3) != new_bb(3))
11298 if (! get_resizefcn ().isempty ())
11299 gh_mgr.post_callback (m___myhandle__,
"resizefcn");
11301 if (! get_sizechangedfcn ().isempty ())
11302 gh_mgr.post_callback (m___myhandle__,
"sizechangedfcn");
11304 update_boundingbox ();
11310 m_position.run_listeners (GCB_POSTSET);
11316 uibuttongroup::properties::set_units (
const octave_value& val)
11320 if (m_units.set (val,
true))
11322 update_units (old_units);
11328 uibuttongroup::properties::update_units (
const caseless_str& old_units)
11330 Matrix pos = get_position ().matrix_value ();
11334 graphics_object parent_go = gh_mgr.get_object (get_parent ());
11336 Matrix parent_bbox = parent_go.get_properties ().get_boundingbox (
true);
11340 set_position (pos);
11344 uibuttongroup::properties::set_fontunits (
const octave_value& val)
11348 if (m_fontunits.set (val,
true))
11350 update_fontunits (old_fontunits);
11356 uibuttongroup::properties::update_fontunits (
const caseless_str& old_units)
11359 double parent_height = get_boundingbox (
false).elem (3);
11360 double fontsz = get_fontsize ();
11368 uibuttongroup::properties::get___fontsize_points__ (
double box_pix_height)
const
11370 double fontsz = get_fontsize ();
11371 double parent_height = box_pix_height;
11373 if (fontunits_is (
"normalized") && parent_height <= 0)
11374 parent_height = get_boundingbox (
false).elem (3);
11380 uibuttongroup::properties::set_selectedobject (
const octave_value& v)
11383 m_selectedobject = current_selectedobject;
11386 if (current_selectedobject.
ok ())
11399 graphics_object go (gh_mgr.get_object (val));
11401 base_properties& gop = go.get_properties ();
11403 if (go.valid_object ()
11404 && gop.get_parent () == get___myhandle__ ()
11405 && go.isa (
"uicontrol"))
11410 if (style.
compare (
"radiobutton") || style.
compare (
"togglebutton"))
11412 m_selectedobject = val;
11426 if (h.
value () == current_selected.
value ())
11427 set_selectedobject (
Matrix ());
11429 base_properties::remove_child (h, from_root);
11438 bool has_selected = current_selected.
ok ();
11442 graphics_object go = gh_mgr.get_object (h);
11444 if (! has_selected && go.valid_object () && go.isa (
"uicontrol"))
11448 if (props.style_is (
"radiobutton") || props.style_is (
"togglebutton"))
11449 set_selectedobject (h.
value ());
11456 uipanel::properties::get_boundingbox (
bool internal,
11457 const Matrix& parent_pix_size)
const
11459 Matrix pos = get_position ().matrix_value ();
11460 Matrix parent_size (parent_pix_size);
11466 graphics_object go = gh_mgr.get_object (get_parent ());
11468 parent_size = go.get_properties ().get_boundingbox (
true).
extract_n (0, 2, 1, 2);
11475 pos(1) = parent_size(1) - pos(1) - pos(3);
11479 double outer_height = pos(3);
11481 pos(0) = pos(1) = 0;
11483 if (! bordertype_is (
"none"))
11485 double bw = get_borderwidth ();
11488 if (bordertype_is (
"etchedin") || bordertype_is (
"etchedout"))
11491 pos(0) += mul * bw;
11492 pos(1) += mul * bw;
11493 pos(2) -= 2 * mul * bw;
11494 pos(3) -= 2 * mul * bw;
11497 if (! get_title ().empty ())
11499 double fontsz = get_fontsize ();
11501 if (! fontunits_is (
"pixels"))
11505 if (fontunits_is (
"points"))
11506 fontsz *= (res / 72.0);
11507 else if (fontunits_is (
"inches"))
11509 else if (fontunits_is (
"centimeters"))
11510 fontsz *= (res / 2.54);
11511 else if (fontunits_is (
"normalized"))
11512 fontsz *= outer_height;
11515 if (titleposition_is (
"lefttop") || titleposition_is (
"centertop")
11516 || titleposition_is (
"righttop"))
11517 pos(1) += (fontsz / 2);
11518 pos(3) -= (fontsz / 2);
11526 uipanel::properties::set_position (
const octave_value& v)
11529 bool modified =
false;
11531 old_bb = get_boundingbox (
true);
11532 modified = m_position.set (v,
false);
11533 new_bb = get_boundingbox (
true);
11535 if (old_bb != new_bb)
11537 if (old_bb(2) != new_bb(2) || old_bb(3) != new_bb(3))
11541 if (! get_resizefcn ().isempty ())
11542 gh_mgr.post_callback (m___myhandle__,
"resizefcn");
11544 if (! get_sizechangedfcn ().isempty ())
11545 gh_mgr.post_callback (m___myhandle__,
"sizechangedfcn");
11547 update_boundingbox ();
11553 m_position.run_listeners (GCB_POSTSET);
11560 uipanel::properties::set_units (
const octave_value& val)
11564 if (m_units.set (val,
true))
11566 update_units (old_units);
11572 uipanel::properties::update_units (
const caseless_str& old_units)
11574 Matrix pos = get_position ().matrix_value ();
11578 graphics_object parent_go = gh_mgr.get_object (get_parent ());
11580 Matrix parent_bbox = parent_go.get_properties ().get_boundingbox (
true);
11584 set_position (pos);
11588 uipanel::properties::set_fontunits (
const octave_value& val)
11592 if (m_fontunits.set (val,
true))
11594 update_fontunits (old_fontunits);
11600 uipanel::properties::update_fontunits (
const caseless_str& old_units)
11603 double parent_height = get_boundingbox (
false).elem (3);
11604 double fontsz = get_fontsize ();
11612 uipanel::properties::get___fontsize_points__ (
double box_pix_height)
const
11614 double fontsz = get_fontsize ();
11615 double parent_height = box_pix_height;
11617 if (fontunits_is (
"normalized") && parent_height <= 0)
11618 parent_height = get_boundingbox (
false).elem (3);
11626 uitable::properties::get_boundingbox (
bool,
11627 const Matrix& parent_pix_size)
const
11629 Matrix pos = get_position ().matrix_value ();
11630 Matrix parent_size (parent_pix_size);
11636 graphics_object go = gh_mgr.get_object (get_parent ());
11638 parent_size = go.get_properties ().get_boundingbox (
true).
extract_n (0, 2, 1, 2);
11645 pos(1) = parent_size(1) - pos(1) - pos(3);
11651 uitable::properties::set_columnformat (
const octave_value& val)
11658 if (m_columnformat.set (val,
true))
11665 for (
int i = 0; i < cell_value.
numel (); i++)
11673 for (
int j = 0; j < popup.
numel (); j++)
11677 error (
"set: pop-up menu definitions must be non-empty strings");
11682 error (
"set: columnformat definintions must be a cellstr of "
11683 "either 'char', 'short [e|g|eng]?', 'long [e|g|eng]?', "
11684 "'numeric', 'bank', '+', 'rat', 'logical', "
11685 "or a cellstr of non-empty pop-up menu definitions.");
11689 if (m_columnformat.set (val,
true))
11694 if (m_columnformat.set (
Cell (),
true))
11699 error (
"set: expecting cell of strings");
11704 uitable::properties::set_columnwidth (
const octave_value& val)
11706 bool error_exists =
false;
11709 error_exists =
false;
11713 for (
int i = 0; i < cell_value.
numel (); i++)
11719 error_exists =
true;
11723 error_exists =
true;
11727 error_exists =
true;
11732 error_exists =
true;
11735 error (
"set: expecting either 'auto' or a cell of pixel values or auto");
11738 if (m_columnwidth.set (val,
true))
11744 uitable::properties::set_units (
const octave_value& val)
11748 if (m_units.set (val,
true))
11750 update_units (old_units);
11756 uitable::properties::update_units (
const caseless_str& old_units)
11758 Matrix pos = get_position ().matrix_value ();
11762 graphics_object parent_go = gh_mgr.get_object (get_parent ());
11764 Matrix parent_bbox = parent_go.get_properties ().get_boundingbox (
true);
11768 set_position (pos);
11772 uitable::properties::set_fontunits (
const octave_value& val)
11776 if (m_fontunits.set (val,
true))
11778 update_fontunits (old_fontunits);
11784 uitable::properties::update_fontunits (
const caseless_str& old_units)
11787 double parent_height = get_boundingbox (
false).elem (3);
11788 double fontsz = get_fontsize ();
11796 uitable::properties::get___fontsize_points__ (
double box_pix_height)
const
11798 double fontsz = get_fontsize ();
11799 double parent_height = box_pix_height;
11801 if (fontunits_is (
"normalized") && parent_height <= 0)
11802 parent_height = get_boundingbox (
false).elem (3);
11808 uitable::properties::get_fontsize_pixels (
double box_pix_height)
const
11810 double fontsz = get_fontsize ();
11811 double parent_height = box_pix_height;
11813 if (fontunits_is (
"normalized") && parent_height <= 0)
11814 parent_height = get_boundingbox (
false).elem (3);
11820 uitable::properties::get_backgroundcolor_rgb (
void)
11822 Matrix bg = m_backgroundcolor.get ().matrix_value ();
11827 uitable::properties::get_alternatebackgroundcolor_rgb (
void)
11830 Matrix bg = m_backgroundcolor.get ().matrix_value ();
11831 if (bg.
rows () > 1)
11838 uitable::properties::get_extent_matrix (
void)
const
11840 return m_extent.get ().matrix_value ();
11844 uitable::properties::get_extent (
void)
const
11847 Matrix m = m_extent.get ().matrix_value ();
11851 graphics_object parent_go = gh_mgr.get_object (get_parent ());
11855 Matrix parent_bbox = parent_go.get_properties ().get_boundingbox (
true);
11867 uitoolbar::get_default (
const caseless_str& pname)
const
11877 graphics_object parent_go = gh_mgr.get_object (parent_h);
11879 retval = parent_go.get_default (pname);
11886 uitoolbar::reset_default_properties (
void)
11889 m_default_properties = property_list ();
11891 remove_all_listeners ();
11898 base_graphics_object::get_default (
const caseless_str& pname)
const
11904 graphics_object parent_go = gh_mgr.get_object (parent_h);
11906 return parent_go.get_default (type () + pname);
11910 base_graphics_object::get_factory_default (
const caseless_str& name)
const
11914 graphics_object parent_go = gh_mgr.get_object (0);
11916 return parent_go.get_factory_default (type () + name);
11921 gh_manager::gh_manager (octave::interpreter& interp)
11922 : m_interpreter (interp), m_handle_map (), m_handle_free_list (),
11923 m_next_handle (-1.0 - (
rand () + 1.0) / (RAND_MAX + 2.0)),
11924 m_figure_list (), m_graphics_lock (), m_event_queue (),
11925 m_callback_objects (), m_event_processing (0)
11927 m_handle_map[0] = graphics_object (
new root_figure ());
11932 gtk_mgr.default_toolkit ();
11938 bool integer_figure_handle,
11939 bool call_createfcn,
bool notify_toolkit)
11946 error (
"gh_manager::make_graphics_handle: invalid object type '%s'",
11949 graphics_object go (bgo);
11951 m_handle_map[h] = go;
11953 if (go_name ==
"axes")
11962 graphics_object tgo;
11964 tgo = get_object (props.get_xlabel ());
11965 tgo.override_defaults ();
11967 tgo = get_object (props.get_ylabel ());
11968 tgo.override_defaults ();
11970 tgo = get_object (props.get_zlabel ());
11971 tgo.override_defaults ();
11973 tgo = get_object (props.get_title ());
11974 tgo.override_defaults ();
11979 go.override_defaults ();
11981 if (call_createfcn)
11982 bgo->get_properties ().execute_createfcn ();
11985 if (notify_toolkit)
11992 gh_manager::make_figure_handle (
double val,
bool notify_toolkit)
11996 base_graphics_object *bgo =
new figure (h, 0);
11997 graphics_object go (bgo);
11999 m_handle_map[h] = go;
12002 if (notify_toolkit)
12005 go.override_defaults ();
12015 m_figure_list.push_front (h);
12021 for (
auto it = m_figure_list.begin (); it != m_figure_list.end (); it++)
12025 m_figure_list.erase (it);
12037 int busyaction = base_graphics_event::QUEUE)
12039 m_callback (), m_callback_data (data) { }
12043 int busyaction = base_graphics_event::QUEUE)
12045 m_callback (cb), m_callback_data (data) { }
12051 if (m_callback.is_defined ())
12052 gh_mgr.execute_callback (m_handle, m_callback, m_callback_data);
12054 gh_mgr.execute_callback (m_handle, m_callback_name, m_callback_data);
12075 int busyaction = base_graphics_event::QUEUE)
12081 if (! m_mcode.empty ())
12085 graphics_object go = gh_mgr.get_object (m_handle);
12087 if (go.valid_object ())
12090 gh_mgr.execute_callback (m_handle, cb);
12126 m_function (m_function_data);
12141 const octave_value& value,
bool do_notify_toolkit =
true,
12142 bool redraw_figure =
false)
12144 m_property_value (value), m_notify_toolkit (do_notify_toolkit),
12145 m_redraw_figure (redraw_figure)
12152 octave::autolock guard (gh_mgr.graphics_lock ());
12154 graphics_object go = gh_mgr.get_object (m_handle);
12158 property p = go.get_properties ().get_property (m_property_name);
12168 if (go.isa (
"figure") && m_property_name ==
"position")
12172 fprops.set_position (m_property_value, m_notify_toolkit);
12174 else if (go.isa (
"figure") && m_property_name ==
"outerposition")
12178 fprops.set_outerposition (m_property_value, m_notify_toolkit);
12181 p.set (m_property_value,
true, m_notify_toolkit);
12183 if (m_redraw_figure)
12185 if (! go.isa (
"figure"))
12186 go = go.get_ancestor (
"figure");
12188 if (go.valid_object ())
12192 fprops.get_toolkit ().redraw_figure (go);
12214 const std::string& name,
12218 return graphics_event (
new callback_event (h, name, data, busyaction));
12227 return graphics_event (
new callback_event (h, cb, data, busyaction));
12232 const std::string& cmd,
12235 return graphics_event (
new mcode_event (h, cmd, busyaction));
12239 graphics_event::create_function_event (graphics_event::event_fcn fcn,
12247 const std::string& name,
12249 bool notify_toolkit,
bool redraw_figure)
12251 return graphics_event (
new set_event (h, name, data, notify_toolkit,
12260 graphics_object go = gh_mgr.get_object (0);
12269 gh_manager::restore_gcbo (
void)
12271 octave::autolock guard (m_graphics_lock);
12273 m_callback_objects.pop_front ();
12282 if (octave::thread::is_thread ())
12286 octave::autolock guard (m_graphics_lock);
12288 post_event (graphics_event::create_callback_event (h, l));
12309 octave::unwind_action_safe restore_gcbo_action
12310 (&gh_manager::restore_gcbo,
this);
12312 graphics_object go (get_object (h));
12317 octave::autolock guard (m_graphics_lock);
12318 m_callback_objects.push_front (go);
12336 m_interpreter.eval_string (s,
false, status, 0);
12338 catch (
const octave::execution_exception& ee)
12340 m_interpreter.handle_exception (ee);
12346 || cb.
cell_value ()(0).is_function_handle ()))
12352 for (
int i = 1; i < c.
numel () ; i++)
12358 error (
"trying to execute non-executable object (class = %s)",
12370 catch (
const octave::execution_exception& ee)
12372 m_interpreter.handle_exception (ee);
12380 std::string go_name
12381 = go.get_properties ().graphics_object_name ();
12383 if (go_name.length () > 1
12384 && go_name[0] ==
'u' && go_name[1] ==
'i')
12399 return gh_mgr.process_events ();
12403 gh_manager::post_event (
const graphics_event& e)
12405 m_event_queue.push_back (e);
12411 gh_manager::post_callback (
const graphics_handle& h,
const std::string& name,
12414 octave::autolock guard (m_graphics_lock);
12416 graphics_object go = get_object (h);
12418 if (go.valid_object ())
12421 int busyaction = base_graphics_event::QUEUE;
12423 if (cname ==
"deletefcn" || cname ==
"createfcn"
12424 || cname ==
"closerequestfcn"
12425 || ((go.isa (
"figure") || go.isa (
"uipanel")
12426 || go.isa (
"uibuttongroup"))
12427 && (cname ==
"resizefcn" || cname ==
"sizechangedfcn")))
12428 busyaction = base_graphics_event::INTERRUPT;
12429 else if (go.get_properties ().get_busyaction () ==
"cancel")
12430 busyaction = base_graphics_event::CANCEL;
12434 if (cname ==
"closerequestfcn")
12436 std::string cmd (
"close (gcbf ());");
12437 post_event (graphics_event::create_mcode_event (h, cmd, busyaction));
12440 post_event (graphics_event::create_callback_event (h, name, data,
12446 gh_manager::post_function (graphics_event::event_fcn fcn,
void *fcn_data)
12448 octave::autolock guard (m_graphics_lock);
12450 post_event (graphics_event::create_function_event (fcn, fcn_data));
12454 gh_manager::post_set (
const graphics_handle& h,
const std::string& name,
12456 bool redraw_figure)
12458 octave::autolock guard (m_graphics_lock);
12460 post_event (graphics_event::create_set_event (h, name, value, notify_toolkit,
12465 gh_manager::process_events (
bool force)
12469 bool events_executed =
false;
12473 e = graphics_event ();
12476 octave::autolock guard (m_graphics_lock);
12478 if (! m_event_queue.empty ())
12480 if (m_callback_objects.empty () || force)
12482 e = m_event_queue.front ();
12484 m_event_queue.pop_front ();
12488 const graphics_object& go = m_callback_objects.front ();
12490 if (go.get_properties ().is_interruptible ())
12492 e = m_event_queue.front ();
12494 m_event_queue.pop_front ();
12498 std::list<graphics_event>::iterator p = m_event_queue.begin ();
12500 while (p != m_event_queue.end ())
12501 if (p->get_busyaction () == base_graphics_event::CANCEL)
12503 p = m_event_queue.erase (p);
12505 else if (p->get_busyaction ()
12506 == base_graphics_event::INTERRUPT)
12509 m_event_queue.erase (p);
12522 events_executed =
true;
12528 octave::autolock guard (m_graphics_lock);
12530 if (m_event_queue.empty () && m_event_processing == 0)
12534 if (events_executed)
12603 gh_manager::enable_event_processing (
bool enable)
12605 octave::autolock guard (m_graphics_lock);
12609 m_event_processing++;
12615 m_event_processing--;
12617 if (m_event_queue.empty () && m_event_processing == 0)
12622 property_list::plist_map_type
12623 root_figure::init_factory_properties (
void)
12625 property_list::plist_map_type plist_map;
12627 plist_map[
"figure"] = figure::properties::factory_defaults ();
12628 plist_map[
"axes"] = axes::properties::factory_defaults ();
12629 plist_map[
"line"] = line::properties::factory_defaults ();
12630 plist_map[
"text"] = text::properties::factory_defaults ();
12631 plist_map[
"image"] = image::properties::factory_defaults ();
12632 plist_map[
"patch"] = patch::properties::factory_defaults ();
12633 plist_map[
"scatter"] = scatter::properties::factory_defaults ();
12634 plist_map[
"surface"] = surface::properties::factory_defaults ();
12635 plist_map[
"light"] = light::properties::factory_defaults ();
12636 plist_map[
"hggroup"] = hggroup::properties::factory_defaults ();
12637 plist_map[
"uimenu"] = uimenu::properties::factory_defaults ();
12638 plist_map[
"uicontrol"] = uicontrol::properties::factory_defaults ();
12639 plist_map[
"uibuttongroup"] = uibuttongroup::properties::factory_defaults ();
12640 plist_map[
"uipanel"] = uipanel::properties::factory_defaults ();
12641 plist_map[
"uicontextmenu"] = uicontextmenu::properties::factory_defaults ();
12642 plist_map[
"uitoolbar"] = uitoolbar::properties::factory_defaults ();
12643 plist_map[
"uipushtool"] = uipushtool::properties::factory_defaults ();
12644 plist_map[
"uitoggletool"] = uitoggletool::properties::factory_defaults ();
12662 gh_manager& gh_mgr = interp.get_gh_manager ();
12664 octave::autolock guard (gh_mgr.graphics_lock ());
12666 if (args.
length () != 1)
12696 return h.
ok () && gh_mgr.is_handle_visible (h);
12729 DEFUN (__is_handle_visible__, args, ,
12735 if (args.
length () != 1)
12756 if (args.
length () != 1)
12760 ColumnVector hcv = args(0).xvector_value (
"reset: H must be a graphics handle");
12762 gh_manager& gh_mgr = interp.get_gh_manager ();
12766 gh_mgr.get_object (hcv(
n)).reset_default_properties ();
12982 gh_manager& gh_mgr = interp.get_gh_manager ();
12984 octave::autolock guard (gh_mgr.graphics_lock ());
12986 int nargin = args.
length ();
12994 ColumnVector hcv = args(0).xvector_value (
"set: H must be a graphics handle");
12996 bool request_drawnow =
false;
13001 graphics_object go = gh_mgr.get_object (hcv(
n));
13004 error (
"set: invalid handle (= %g)", hcv(
n));
13006 if (nargin == 3 && args(1).iscellstr () && args(2).iscell ())
13008 if (args(2).cell_value ().rows () == 1)
13009 go.set (args(1).cellstr_value (), args(2).cell_value (), 0);
13010 else if (hcv.
numel () == args(2).cell_value ().rows ())
13011 go.set (args(1).cellstr_value (), args(2).cell_value (),
n);
13013 error (
"set: number of graphics handles must match number of "
13014 "value rows (%" OCTAVE_IDX_TYPE_FORMAT
" != "
13015 "%" OCTAVE_IDX_TYPE_FORMAT
")",
13016 hcv.
numel (), args(2).cell_value ().rows ());
13018 else if (nargin == 2 && args(1).isstruct ())
13019 go.set (args(1).map_value ());
13020 else if (nargin == 2 && args(1).is_string ())
13022 std::string
property = args(1).string_value ();
13024 property.begin (), tolower);
13028 if (go.has_readonly_property (property))
13033 <<
" is read-only" << std::endl;
13034 else if (pmap.
isfield (property))
13037 retval = pmap.
getfield (property)(0);
13040 std::string s = go.value_as_string (property);
13046 error (R
"(set: unknown property "%s")", property.c_str ());
13048 else if (nargin == 1)
13051 retval = go.values_as_struct ();
13054 std::string s = go.values_as_string ();
13061 go.set (args.
splice (0, 1));
13064 request_drawnow =
true;
13067 if (request_drawnow)
13076 std::string retval;
13080 graphics_object go = gh_mgr.get_object (val);
13083 error (
"get: invalid handle (= %g)", val);
13102 gh_manager& gh_mgr = interp.get_gh_manager ();
13104 octave::autolock guard (gh_mgr.graphics_lock ());
13106 int nargin = args.
length ();
13108 if (nargin < 1 || nargin > 2)
13111 if (args(0).isempty ())
13114 ColumnVector hcv = args(0).xvector_value (
"get: H must be a graphics handle");
13118 if (nargin == 1 && hcv_len > 1)
13127 error (
"get: vector of handles must all have the same type");
13133 bool use_cell_format =
false;
13135 if (nargin > 1 && args(1).iscellstr ())
13141 use_cell_format =
true;
13147 graphics_object go = gh_mgr.get_object (hcv(
n));
13150 error (
"get: invalid handle (= %g)", hcv(
n));
13156 vals(
n,
m) = go.get (property);
13166 1).xstring_value (
"get: second argument must be property name or cell array of property names");
13172 graphics_object go = gh_mgr.get_object (hcv(
n));
13175 error (
"get: invalid handle (= %g)", hcv(
n));
13178 vals(
n) = go.get ();
13180 vals(
n) = go.get (property);
13184 if (use_cell_format)
13192 else if (vals_len == 1)
13194 else if (vals_len > 1 && nargin == 1)
13199 tmp[
n] = vals(
n).scalar_map_value ();
13224 gh_manager& gh_mgr = interp.get_gh_manager ();
13226 octave::autolock guard (gh_mgr.graphics_lock ());
13228 if (args.
length () != 1)
13231 ColumnVector hcv = args(0).xvector_value (
"get: H must be a graphics handle");
13241 graphics_object go = gh_mgr.get_object (hcv(
n));
13244 error (
"get: invalid handle (= %g)", hcv(
n));
13249 vals(
n) = go.get (
true);
13258 else if (vals_len == 1)
13259 return ovl (vals(0));
13266 bool integer_figure_handle,
13279 for (
int i = 0; i < xargs.
length (); i += 2)
13281 if (xargs(i).is_string () && p.
compare (xargs(i).string_value ()))
13283 if (i >= (xargs.
length () - 1))
13284 error (
"__go_%s__: missing value for parent property",
13287 val = xargs(i+1).double_value ();
13289 xargs = xargs.
splice (i, 2);
13295 val = args(0).xdouble_value (
"__go_%s__: invalid parent", go_name.c_str ());
13301 if (! parent.
ok ())
13302 error (
"__go_%s__: invalid parent", go_name.c_str ());
13308 h = gh_mgr.make_graphics_handle (go_name, parent,
13309 integer_figure_handle,
false,
false);
13311 catch (octave::execution_exception& ee)
13313 error (ee,
"__go_%s__: %s, unable to create graphics handle",
13314 go_name.c_str (), ee.message ().c_str ());
13321 catch (octave::execution_exception& ee)
13324 error (ee,
"__go_%s__: %s, unable to create graphics handle",
13325 go_name.c_str (), ee.message ().c_str ());
13333 retval = h.
value ();
13340 DEFMETHOD (__go_figure__, interp, args, ,
13346 gh_manager& gh_mgr = interp.get_gh_manager ();
13348 octave::autolock guard (gh_mgr.graphics_lock ());
13350 if (args.
length () == 0)
13353 double val = args(0).xdouble_value (
"__go_figure__: figure number must be a double value");
13363 retval = h.
value ();
13367 bool int_fig_handle =
true;
13377 for (
int i = 0; i < xargs.
length (); i++)
13379 if (xargs(i).is_string ()
13380 && pname.
compare (xargs(i).string_value ()))
13382 if (i < (xargs.
length () - 1))
13384 std::string pval = xargs(i+1).string_value ();
13387 int_fig_handle = on.
compare (pval);
13388 xargs = xargs.
splice (i, 2);
13395 h = gh_mgr.make_graphics_handle (
"figure", 0, int_fig_handle,
13398 if (! int_fig_handle)
13403 graphics_object go = gh_mgr.get_object (h);
13404 go.get_properties ().init_integerhandle (
"off");
13408 h = gh_mgr.make_figure_handle (val,
false);
13411 error (
"__go_figure__: failed to create figure handle");
13417 catch (octave::execution_exception& ee)
13420 error (ee,
"__go_figure__: unable to create figure handle");
13425 gh_mgr.push_figure (h);
13430 retval = h.
value ();
13436 #define GO_BODY(TYPE) \
13437 gh_manager& gh_mgr = interp.get_gh_manager (); \
13439 octave::autolock guard (gh_mgr.graphics_lock ()); \
13441 if (args.length () == 0) \
13444 return octave_value (make_graphics_object (#TYPE, false, args)); \
13451 if (go.isa (
"surface"))
13453 else if ((go.isa (
"line") || go.isa (
"patch") || go.isa (
"scatter"))
13454 && ! go.get (
"zdata").isempty ())
13458 Matrix kids = go.get_properties ().get_children ();
13468 const graphics_object& kid = gh_mgr.get_object (hkid);
13470 if (kid.valid_object ())
13482 DEFMETHOD (__calc_dimensions__, interp, args, ,
13490 gh_manager& gh_mgr = interp.get_gh_manager ();
13492 octave::autolock guard (gh_mgr.graphics_lock ());
13494 if (args.
length () != 1)
13497 double h = args(0).xdouble_value (
"__calc_dimensions__: first argument must be a graphics handle");
13502 DEFMETHOD (__go_axes__, interp, args, ,
13511 DEFMETHOD (__go_line__, interp, args, ,
13520 DEFMETHOD (__go_text__, interp, args, ,
13529 DEFMETHOD (__go_image__, interp, args, ,
13538 DEFMETHOD (__go_surface__, interp, args, ,
13547 DEFMETHOD (__go_patch__, interp, args, ,
13556 DEFMETHOD (__go_scatter__, interp, args, ,
13565 DEFMETHOD (__go_light__, interp, args, ,
13574 DEFMETHOD (__go_hggroup__, interp, args, ,
13583 DEFMETHOD (__go_uimenu__, interp, args, ,
13592 DEFMETHOD (__go_uicontrol__, interp, args, ,
13601 DEFMETHOD (__go_uibuttongroup__, interp, args, ,
13610 DEFMETHOD (__go_uipanel__, interp, args, ,
13619 DEFMETHOD (__go_uicontextmenu__, interp, args, ,
13628 DEFMETHOD (__go_uitable__, interp, args, ,
13637 DEFMETHOD (__go_uitoolbar__, interp, args, ,
13646 DEFMETHOD (__go_uipushtool__, interp, args, ,
13655 DEFMETHOD (__go_uitoggletool__, interp, args, ,
13664 DEFMETHOD (__go_delete__, interp, args, ,
13670 gh_manager& gh_mgr = interp.get_gh_manager ();
13672 octave::autolock guard (gh_mgr.graphics_lock ());
13674 if (args.
length () != 1)
13679 const NDArray vals = args(0).xarray_value (
"delete: invalid graphics object");
13685 h = gh_mgr.lookup (vals(i));
13688 error (
"delete: invalid graphics object (= %g)", vals(i));
13696 DEFMETHOD (__go_handles__, interp, args, ,
13702 gh_manager& gh_mgr = interp.get_gh_manager ();
13704 octave::autolock guard (gh_mgr.graphics_lock ());
13706 bool show_hidden =
false;
13709 show_hidden = args(0).bool_value ();
13711 return ovl (gh_mgr.handle_list (show_hidden));
13714 DEFMETHOD (__go_figure_handles__, interp, args, ,
13720 gh_manager& gh_mgr = interp.get_gh_manager ();
13722 octave::autolock guard (gh_mgr.graphics_lock ());
13724 bool show_hidden =
false;
13727 show_hidden = args(0).bool_value ();
13729 return ovl (gh_mgr.figure_handle_list (show_hidden));
13732 DEFMETHOD (__go_execute_callback__, interp, args, ,
13739 int nargin = args.
length ();
13741 if (nargin < 2 || nargin > 3)
13744 const NDArray vals = args(0).xarray_value (
"__go_execute_callback__: invalid graphics object");
13746 std::string name = args(1).xstring_value (
"__go_execute_callback__: invalid callback name");
13748 gh_manager& gh_mgr = interp.get_gh_manager ();
13752 double val = vals(i);
13757 error (
"__go_execute_callback__: invalid graphics object (= %g)", val);
13760 gh_mgr.execute_callback (h, name);
13762 gh_mgr.execute_callback (h, name, args(2));
13768 DEFMETHOD (__go_post_callback__, interp, args, ,
13775 int nargin = args.
length ();
13777 if (nargin < 2 || nargin > 3)
13780 const NDArray vals = args(0).xarray_value (
"__go_post_callback__: invalid graphics object");
13782 std::string name = args(1).xstring_value (
"__go_post_callback__: invalid callback name");
13784 gh_manager& gh_mgr = interp.get_gh_manager ();
13788 double val = vals(i);
13793 error (
"__go_execute_callback__: invalid graphics object (= %g)", val);
13796 gh_mgr.post_callback (h, name);
13798 gh_mgr.post_callback (h, name, args(2));
13804 DEFMETHOD (__image_pixel_size__, interp, args, ,
13810 if (args.
length () != 1)
13813 gh_manager& gh_mgr = interp.get_gh_manager ();
13815 double h = args(0).xdouble_value (
"__image_pixel_size__: argument is not a handle");
13817 graphics_object go = gh_mgr.get_object (h);
13819 if (! go || ! go.isa (
"image"))
13820 error (
"__image_pixel_size__: object is not an image");
13826 dp(0) = ip.pixel_xsize ();
13827 dp(1) = ip.pixel_ysize ();
13831 DEFMETHOD (available_graphics_toolkits, interp, , ,
13838 gh_manager& gh_mgr = interp.get_gh_manager ();
13840 octave::autolock guard (gh_mgr.graphics_lock ());
13842 octave::gtk_manager& gtk_mgr = interp.get_gtk_manager ();
13844 return ovl (gtk_mgr.available_toolkits_list ());
13847 DEFMETHOD (register_graphics_toolkit, interp, args, ,
13857 gh_manager& gh_mgr = interp.get_gh_manager ();
13859 octave::autolock guard (gh_mgr.graphics_lock ());
13861 if (args.
length () != 1)
13864 std::string name = args(0).xstring_value (
"register_graphics_toolkit: TOOLKIT must be a string");
13866 octave::gtk_manager& gtk_mgr = interp.get_gtk_manager ();
13868 gtk_mgr.register_toolkit (name);
13873 DEFMETHOD (loaded_graphics_toolkits, interp, , ,
13880 gh_manager& gh_mgr = interp.get_gh_manager ();
13882 octave::autolock guard (gh_mgr.graphics_lock ());
13884 octave::gtk_manager& gtk_mgr = interp.get_gtk_manager ();
13886 return ovl (gtk_mgr.loaded_toolkits_list ());
13889 DEFMETHOD (__show_figure__, interp, args, ,
13895 if (args.
length () != 1)
13898 gh_manager& gh_mgr = interp.get_gh_manager ();
13900 double h = args(0).xdouble_value (
"__show_figure__: invalid handle H");
13905 error (
"__show_figure__: invalid graphics object (= %g)", h);
13907 graphics_object go = gh_mgr.get_object (gh);
13912 fprops.get_toolkit ().show_figure (go);
13943 gh_manager& gh_mgr = interp.get_gh_manager ();
13945 octave::autolock guard (gh_mgr.graphics_lock ());
13947 if (args.
length () <= 1)
13951 bool do_events =
true;
13953 if (args.
length () == 1)
13955 caseless_str val (args(0).xstring_value (
"drawnow: first argument must be a string"));
13960 error (
"drawnow: invalid argument, 'expose' is only valid option");
13967 gh_mgr.process_events ();
13972 Matrix hlist = gh_mgr.figure_handle_list (
true);
13975 for (
int i = 0; i < hlist.
numel (); i++)
13979 if (h.
ok () && h != 0)
13981 graphics_object go = gh_mgr.get_object (h);
13985 if (fprops.is_modified ())
13987 if (fprops.is_visible ())
13991 fprops.get_toolkit ().redraw_figure (go);
13996 fprops.set_modified (
false);
14004 std::string term, file, debug_file;
14006 term = args(0).xstring_value (
"drawnow: TERM must be a string");
14008 file = args(1).xstring_value (
"drawnow: FILE must be a string");
14011 error (
"drawnow: empty output ''");
14012 else if (file.length () == 1 && file[0] ==
'|')
14013 error (
"drawnow: empty pipe '|'");
14014 else if (file[0] !=
'|')
14018 if (pos != std::string::npos)
14020 std::string
dirname = file.substr (0, pos+1);
14022 octave::sys::file_stat fs (
dirname);
14024 if (! fs || ! fs.is_dir ())
14025 error (
"drawnow: nonexistent directory '%s'",
14031 debug_file = (args.
length () > 2 ? args(2).xstring_value (
"drawnow: DEBUG_FILE must be a string") :
14037 error (
"drawnow: nothing to draw");
14039 graphics_object go = gh_mgr.get_object (h);
14043 go.get_toolkit ().print_figure (go, term, file, debug_file);
14052 DEFMETHOD (addlistener, interp, args, ,
14087 gh_manager& gh_mgr = interp.get_gh_manager ();
14089 octave::autolock guard (gh_mgr.graphics_lock ());
14091 int nargin = args.
length ();
14093 if (nargin < 3 || nargin > 4)
14096 double h = args(0).xdouble_value (
"addlistener: invalid handle H");
14098 std::string pname = args(1).xstring_value (
"addlistener: PROP must be a string");
14103 error (
"addlistener: invalid graphics object (= %g)", h);
14105 graphics_object go = gh_mgr.get_object (gh);
14107 go.add_property_listener (pname, args(2), GCB_POSTSET);
14109 if (args.
length () == 4)
14112 if (persistent.
compare (
"persistent"))
14113 go.add_property_listener (pname, args(2), GCB_PERSISTENT);
14119 DEFMETHOD (dellistener, interp, args, ,
14148 gh_manager& gh_mgr = interp.get_gh_manager ();
14150 octave::autolock guard (gh_mgr.graphics_lock ());
14155 double h = args(0).xdouble_value (
"dellistener: invalid handle");
14157 std::string pname = args(1).xstring_value (
"dellistener: PROP must be a string");
14162 error (
"dellistener: invalid graphics object (= %g)", h);
14164 graphics_object go = gh_mgr.get_object (gh);
14166 if (args.
length () == 2)
14167 go.delete_property_listener (pname,
octave_value (), GCB_POSTSET);
14170 if (args(2).is_string ()
14171 && args(2).string_value () ==
"persistent")
14179 go.delete_property_listener (pname, args(2), GCB_POSTSET);
14185 DEFMETHOD (addproperty, interp, args, ,
14257 gh_manager& gh_mgr = interp.get_gh_manager ();
14259 octave::autolock guard (gh_mgr.graphics_lock ());
14264 std::string name = args(0).xstring_value (
"addproperty: NAME must be a string");
14266 double h = args(1).xdouble_value (
"addproperty: invalid handle H");
14271 error (
"addproperty: invalid graphics object (= %g)", h);
14273 graphics_object go = gh_mgr.get_object (gh);
14275 std::string type = args(2).xstring_value (
"addproperty: TYPE must be a string");
14277 if (go.get_properties ().has_property (name))
14278 error (
"addproperty: a '%s' property already exists in the graphics object",
14281 property p = property::create (name, gh, type, args.
splice (0, 3));
14283 go.get_properties ().insert_property (name, p);
14290 const std::string& fcn)
14294 octave::autolock guard (gh_mgr.graphics_lock ());
14296 graphics_object go = gh_mgr.get_object (handle);
14299 error (
"%s: invalid handle (= %g)", fcn.c_str (), handle);
14310 octave::autolock guard (gh_mgr.graphics_lock ());
14312 graphics_object go = gh_mgr.get_object (handle);
14315 error (
"%s: invalid handle (= %g)", fcn.c_str (), handle);
14332 if (result.
length () > 0)
14333 return result(0).bool_value ();
14348 listener_mode mode = GCB_POSTSET)
14352 if (c.
numel () >= 4)
14354 double h = c(2).double_value ();
14360 octave::autolock guard (gh_mgr.graphics_lock ());
14366 graphics_object go = gh_mgr.get_object (gh);
14368 if (go.get_properties ().has_property (pname))
14370 go.get_properties ().delete_listener (pname, listener, mode);
14372 if (mode == GCB_POSTSET)
14373 go.get_properties ().delete_listener (pname, listener,
14392 uint32_t
id = args(2).uint32_scalar_value ().value ();
14396 double h = args(0).double_value ();
14402 octave::autolock guard (gh_mgr.graphics_lock ());
14408 graphics_object go = gh_mgr.get_object (gh);
14426 uint32_t
id = args(2).uint32_scalar_value ().value ();
14477 if (args.
length () == 0)
14481 if (args(0).isempty ())
14484 double h = args(0).xdouble_value (
"waitfor: invalid handle value");
14491 octave::unwind_action cleanup_waitfor_id_action;
14492 octave::unwind_action cleanup_waitfor_postset_listener_action;
14493 octave::unwind_action cleanup_waitfor_predelete_listener_action;
14495 static uint32_t id_counter = 0;
14498 int max_arg_index = 0;
14499 int timeout_index = -1;
14501 double timeout = 0;
14503 gh_manager& gh_mgr = interp.get_gh_manager ();
14507 pname = args(1).xstring_value (
"waitfor: PROP must be a string");
14509 if (pname.empty ())
14510 error (
"waitfor: PROP must be a non-empty string");
14512 if (pname !=
"timeout")
14514 if (pname.
compare (R
"(\timeout)"))
14522 "waitfor_listener"));
14527 if (args(2).is_string ())
14540 Cell listener (1, max_arg_index >= 2 ? 5 : 4);
14546 listener(0) = wf_listener;
14549 listener(3) = pname;
14551 if (max_arg_index >= 2)
14552 listener(4) = args(2);
14556 octave::autolock guard (gh_mgr.graphics_lock ());
14562 graphics_object go = gh_mgr.get_object (gh);
14564 if (max_arg_index >= 2
14569 cleanup_waitfor_postset_listener_action.set
14572 go.add_property_listener (pname, ov_listener, GCB_POSTSET);
14573 go.add_property_listener (pname, ov_listener, GCB_PERSISTENT);
14575 if (go.get_properties ().has_dynamic_property (pname))
14583 "waitfor_del_listener"));
14585 Cell del_listener (1, 4);
14587 del_listener(0) = wf_del_listener;
14589 del_listener(2) = h;
14590 del_listener(3) = pname;
14594 cleanup_waitfor_predelete_listener_action.set
14597 go.add_property_listener (pname, ov_del_listener,
14605 if (timeout_index < 0 && args.
length () > (max_arg_index + 1))
14608 1).xstring_value (
"waitfor: invalid parameter, expected 'timeout'");
14611 error (
"waitfor: invalid parameter '%s'", s.c_str ());
14613 timeout_index = max_arg_index + 1;
14616 if (timeout_index >= 0)
14618 if (args.
length () <= (timeout_index + 1))
14619 error (
"waitfor: missing TIMEOUT value");
14621 timeout = args(timeout_index + 1).xscalar_value (
"waitfor: TIMEOUT must be a scalar >= 1");
14625 warning (
"waitfor: TIMEOUT value must be >= 1, using 1 instead");
14645 octave::sys::time start;
14654 octave::autolock guard (gh_mgr.graphics_lock ());
14671 octave::command_editor::run_event_hooks ();
14675 octave::sys::time now;
14677 if (start + timeout < now)
14693 int nargin = args.
length ();
14695 if (nargin != 2 && nargin != 3)
14698 double h = args(0).double_value ();
14700 gh_manager& gh_mgr = interp.get_gh_manager ();
14702 octave::autolock guard (gh_mgr.graphics_lock ());
14706 if (! handle.
ok ())
14707 error (
"__zoom__: invalid handle");
14709 graphics_object ax = gh_mgr.get_object (handle);
14716 std::string opt = args(1).string_value ();
14718 if (opt ==
"out" || opt ==
"reset")
14722 ax_props.clear_zoom_stack ();
14726 ax_props.clear_zoom_stack (
false);
14731 std::string mode = args(1).string_value ();
14732 double factor = args(2).scalar_value ();
14734 ax_props.zoom (mode, factor);
14741 DEFMETHOD (__get_frame__, interp, args, ,
14750 if (args.
length () != 1)
14753 double h = args(0).xdouble_value (
"__get_frame__: HFIG is not a handle");
14755 gh_manager& gh_mgr = interp.get_gh_manager ();
14757 graphics_object go = gh_mgr.get_object (h);
14759 if (! go || ! go.isa (
"figure"))
14760 error (
"__get_frame__: HFIG is not a figure");
14763 gh_mgr.process_events ();
14765 return ovl (go.get_toolkit ().get_pixels (go));
14768 DEFMETHOD (__get_position__, interp, args, ,
14777 if (args.
length () != 2)
14781 = args(0).xdouble_value (
"__get_position__: H must be a graphics handle");
14784 = args(1).xstring_value (
"__get_position__: UNITS must be a string");
14786 gh_manager& gh_mgr = interp.get_gh_manager ();
14788 graphics_object go = gh_mgr.get_object (h);
14790 if (h == 0 || ! go)
14791 error (
"__get_position__: H must be a handle to a valid graphics object");
14793 graphics_object parent_go = gh_mgr.get_object (go.get_parent ());
14794 Matrix bbox = parent_go.get_properties ().get_boundingbox (
true)
14798 go.get (
"units").string_value (),
14804 DEFUN (__get_system_fonts__, args, ,
14810 if (args.
length () != 0)
14813 octave::text_renderer txt_renderer;
14815 return ovl (txt_renderer.get_system_fonts ());
octave_idx_type lookup(const T *x, octave_idx_type n, T y)
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type columns(void) const
OCTARRAY_OVERRIDABLE_FUNC_API const T * data(void) const
Size of the specified dimension.
OCTARRAY_OVERRIDABLE_FUNC_API bool isempty(void) const
Size of the specified dimension.
OCTARRAY_OVERRIDABLE_FUNC_API Array< T, Alloc > as_column(void) const
Return the array as a column vector.
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type numel(void) const
Number of elements in the array.
OCTARRAY_OVERRIDABLE_FUNC_API const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
OCTARRAY_API void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type rows(void) const
OCTARRAY_API T * fortran_vec(void)
Size of the specified dimension.
OCTARRAY_OVERRIDABLE_FUNC_API int ndims(void) const
Size of the specified dimension.
OCTARRAY_OVERRIDABLE_FUNC_API T & elem(octave_idx_type n)
Size of the specified dimension.
OCTARRAY_API octave_idx_type lookup(const T &value, sortmode mode=UNSORTED) const
Do a binary lookup in a sorted array.
OCTARRAY_OVERRIDABLE_FUNC_API T & xelem(octave_idx_type n)
Size of the specified dimension.
OCTAVE_API double max(void) const
void resize(octave_idx_type n, const double &rfv=0)
OCTAVE_API RowVector transpose(void) const
OCTAVE_API double min(void) const
OCTAVE_API ColumnVector extract_n(octave_idx_type r1, octave_idx_type n) const
ComplexColumnVector eigenvalues(void) const
MArray< T > reshape(const dim_vector &new_dims) const
OCTAVE_API ColumnVector row_max(void) const
OCTAVE_API RowVector row(octave_idx_type i) const
OCTAVE_API Matrix extract_n(octave_idx_type r1, octave_idx_type c1, octave_idx_type nr, octave_idx_type nc) const
OCTAVE_API ColumnVector row_min(void) const
Matrix transpose(void) const
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
OCTAVE_API bool any_element_is_inf_or_nan(void) const
callback_event(const graphics_handle &h, const std::string &name, const octave_value &data=Matrix(), int busyaction=base_graphics_event::QUEUE)
std::string m_callback_name
callback_event(const graphics_handle &h, const octave_value &cb, const octave_value &data=Matrix(), int busyaction=base_graphics_event::QUEUE)
octave_value m_callback_data
~callback_props(void)=default
callback_props(const callback_props &)=delete
void erase(const callback_property *ptr)
callback_props & operator=(const callback_props &)=delete
std::set< intptr_t > m_set
bool contains(const callback_property *ptr) const
void insert(const callback_property *ptr)
bool compare(const std::string &s, std::size_t limit=std::string::npos) const
Vector representing the dimensions (size) of an Array.
void resize(int n, int fill_value=0)
static dim_vector alloc(int n)
octave_idx_type ndims(void) const
Number of dimensions.
graphics_event::event_fcn m_function
function_event(graphics_event::event_fcn fcn, void *data=nullptr)
function_event(void)=delete
function_event(const function_event &)=delete
mcode_event(const graphics_handle &h, const std::string &cmd, int busyaction=base_graphics_event::QUEUE)
octave_value as_octave_value(void) const
Cell getfield(const std::string &key) const
bool isfield(const std::string &name) const
static octave_map cat(int dim, octave_idx_type n, const octave_scalar_map *map_list)
void setfield(const std::string &key, const octave_value &val)
void assign(const std::string &k, const octave_value &val)
octave_value getfield(const std::string &key) const
octave_idx_type length(void) const
octave_value_list splice(octave_idx_type offset, octave_idx_type len, const octave_value_list &lst=octave_value_list()) const
bool is_function(void) const
OCTINTERP_API octave_function * function_value(bool silent=false) const
bool iscellstr(void) const
bool is_uint16_type(void) const
bool is_bool_scalar(void) const
bool is_int8_type(void) const
octave_idx_type rows(void) const
bool isnumeric(void) const
octave_idx_type numel(void) const
bool is_scalar_type(void) const
bool is_string(void) const
bool is_defined(void) const
bool is_double_type(void) const
Cell cell_value(void) const
bool is_function_handle(void) const
std::string class_name(void) const
bool is_uint32_type(void) const
octave_idx_type columns(void) const
bool is_int64_type(void) const
octave_value reshape(const dim_vector &dv) const
std::string string_value(bool force=false) const
bool is_matrix_type(void) const
bool is_int32_type(void) const
bool is_uint64_type(void) const
bool is_int16_type(void) const
string_vector string_vector_value(bool pad=false) const
NDArray array_value(bool frc_str_conv=false) const
bool is_single_type(void) const
bool is_real_scalar(void) const
bool is_undefined(void) const
OCTINTERP_API octave_idx_type length(void) const
bool is_uint8_type(void) const
Matrix matrix_value(bool frc_str_conv=false) const
bool iscomplex(void) const
double double_value(bool frc_str_conv=false) const
std::string type_name(void) const
bool islogical(void) const
dim_vector dims(void) const
OCTINTERP_API double xdouble_value(const char *fmt,...) const
std::string m_property_name
set_event(const graphics_handle &h, const std::string &name, const octave_value &value, bool do_notify_toolkit=true, bool redraw_figure=false)
octave_value m_property_value
string_vector & append(const std::string &s)
std::ostream & list_in_columns(std::ostream &, int width=0, const std::string &prefix="") const
std::string join(const std::string &sep="") const
octave_idx_type numel(void) const
static octave_idx_type find(octave_idx_type i, octave_idx_type *pp)
ColumnVector real(const ComplexColumnVector &a)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DECLARE_STATIC_FUNX(name, args_name, nargout_name)
OCTINTERP_API void print_usage(void)
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void interpreter_try(unwind_protect &frame)
void warning(const char *fmt,...)
void warning_with_id(const char *id, const char *fmt,...)
void error(const char *fmt,...)
octave_value_list set_warning_state(const std::string &id, const std::string &state)
void disable_warning(const std::string &id)
int warning_enabled(const std::string &id)
void error_unless(bool cond)
std::string dirname(const std::string &path)
octave_handle graphics_handle
static double default_screendepth(void)
static Matrix default_patch_vertices(void)
static void xset(const graphics_handle &h, const caseless_str &pname, const octave_value &val)
static graphics_handle reparent(const octave_value &ov, const std::string &who, const std::string &pname, const graphics_handle &new_parent, bool adopt=true)
static Matrix default_surface_ydata(void)
static Matrix default_light_position(void)
static bool compare_property_values(const octave_value &ov1, const octave_value &ov2)
static Matrix default_patch_ydata(void)
static double make_handle_fraction(void)
void cross_product(double x1, double y1, double z1, double x2, double y2, double z2, double &x, double &y, double &z)
double dot(const ColumnVector &v1, const ColumnVector &v2)
static bool updating_zlabel_position
static Matrix default_image_cdata(void)
void translate(Matrix &m, double x, double y, double z)
static std::set< double > updating_aspectratios
OCTAVE_EXPORT octave_value_list Fdrawnow(octave::interpreter &interp, const octave_value_list &args, int)
static caseless_str validate_property_name(const std::string &who, const std::string &what, const std::set< std::string > &pnames, const caseless_str &pname)
static Matrix default_data(void)
bool set_property_in_handle(double handle, const std::string &property, const octave_value &arg, const std::string &fcn)
#define CONVERT_CDATA_1(ARRAY_T, VAL_FN, IS_REAL)
static graphics_handle make_graphics_handle(const std::string &go_name, const graphics_handle &parent, bool integer_figure_handle=false, bool call_createfcn=true, bool notify_toolkit=true)
static bool updating_hggroup_limits
ColumnVector cross(const ColumnVector &v1, const ColumnVector &v2)
static void delete_graphics_objects(const NDArray vals, bool from_root=false)
static void finalize_r(const graphics_handle &h)
static Matrix default_figure_paperposition(void)
static Matrix default_figure_papersize(void)
graphics_handle gca(void)
static Matrix default_table_backgroundcolor(void)
static octave_value convert_ticklabel_string(const octave_value &val)
void get_children_limits(double &min_val, double &max_val, double &min_pos, double &max_neg, const Matrix &kids, char limit_type)
static Matrix screen_size_pixels(void)
double norm(const ColumnVector &v)
static void xreset_default_properties(graphics_handle h, property_list::pval_map_type factory_pval)
static bool updating_patch_data
void xform(ColumnVector &v, const Matrix &m)
static Matrix default_axes_position(void)
static Matrix default_screensize(void)
void normalize(ColumnVector &v)
static Matrix default_axes_view(void)
static Matrix default_surface_xdata(void)
static void close_figure(const graphics_handle &h)
Matrix xform_scale(double x, double y, double z)
static void normalized_aspectratios(Matrix &aspectratios, const Matrix &scalefactors, double xlength, double ylength, double zlength)
static std::map< caseless_str, graphics_object > dprop_obj_map
static Matrix default_control_position(void)
static Matrix do_translate(double x0, double x1, const Matrix &lims, bool is_logscale)
static Matrix default_axes_tick(void)
static bool updating_scatter_cdata
std::vector< octave_idx_type > coplanar_partition(const Matrix &vert, const Matrix &idx, octave_idx_type nc, octave_idx_type jj)
static void update_text_pos(graphics_handle h)
static callback_props executing_callbacks
static double device_pixel_ratio(graphics_handle h)
static Matrix default_control_sliderstep(void)
ColumnVector cam2xform(const Array< double > &m)
static void delete_graphics_object(const graphics_handle &h, bool from_root=false)
static OCTAVE_NORETURN void err_set_invalid(const std::string &pname)
int calc_dimensions(const graphics_object &go)
static bool updating_ylabel_position
static bool ishghandle(const graphics_handle &h)
RowVector xform2cam(const ColumnVector &v)
static bool delete_executing
static void magform(double x, double &a, int &b)
static Matrix papersize_from_type(const caseless_str punits, const caseless_str ptype)
static std::map< uint32_t, bool > waitfor_results
static bool updating_axes_layout
static Matrix default_patch_xdata(void)
static void check_limit_vals(double &min_val, double &max_val, double &min_pos, double &max_neg, const octave_value &data)
static bool lookup_object_name(const caseless_str &name, caseless_str &go_name, caseless_str &rest)
static Matrix default_lim(bool logscale=false)
static void force_close_figure(const graphics_handle &h)
static Matrix default_table_position(void)
static int process_graphics_events(void)
static double convert_font_size(double font_size, const caseless_str &from_units, const caseless_str &to_units, double parent_height=0)
static Matrix viridis_colormap(void)
static void get_array_limits(const Array< T > &m, double &emin, double &emax, double &eminp, double &emaxp)
static void cleanup_waitfor_predelete_listener(const octave_value &listener)
static octave_value_list waitfor_listener(const octave_value_list &args, int)
static std::set< double > updating_axis_limits
static void xset_gcbo(const graphics_handle &h)
static ColumnVector convert_label_position(const ColumnVector &p, const text::properties &props, const graphics_xform &xform, const Matrix &bbox)
void scale(Matrix &m, double x, double y, double z)
static octave_value convert_linestyleorder_string(const octave_value &val)
Matrix xform_translate(double x, double y, double z)
static std::string default_graphics_toolkit(void)
static void initialize_r(const graphics_handle &h)
static void cleanup_waitfor_id(uint32_t id)
static std::string get_graphics_object_type(double val)
Matrix xform_matrix(void)
static double default_screenpixelsperinch(void)
static bool updating_xlabel_position
ColumnVector xform_vector(void)
static Matrix default_surface_cdata(void)
ColumnVector transform(const Matrix &m, double x, double y, double z)
graphics_handle gcf(void)
static void do_cleanup_waitfor_listener(const octave_value &listener, listener_mode mode=GCB_POSTSET)
static void xinitialize(const graphics_handle &h)
static octave_value xget(const graphics_handle &h, const caseless_str &name)
static void convert_cdata_2(bool is_scaled, bool is_real, double clim_0, double clim_1, const double *cmapv, double x, octave_idx_type lda, octave_idx_type nc, octave_idx_type i, double *av)
static Matrix default_data_lim(void)
#define CHECK_ARRAY_EQUAL(T, F, A)
static Matrix default_panel_position(void)
static octave_value_list waitfor_del_listener(const octave_value_list &args, int)
bool is_coplanar(const Matrix &cov)
static Matrix do_zoom(double val, double factor, const Matrix &lims, bool is_logscale)
static bool updating_title_position
static bool is_handle_visible(const graphics_handle &h)
static Matrix default_colororder(void)
static octave_value convert_cdata(const base_properties &props, const octave_value &cdata, bool is_scaled, int cdim)
static void adopt(const graphics_handle &parent_h, const graphics_handle &h)
static Matrix default_axes_ticklength(void)
static base_graphics_object * make_graphics_object_from_type(const caseless_str &type, const graphics_handle &h=graphics_handle(), const graphics_handle &p=graphics_handle())
double force_in_range(double x, double lower, double upper)
static Matrix default_surface_zdata(void)
static void max_axes_scale(double &s, Matrix &limits, const Matrix &kids, double pbfactor, double dafactor, char limit_type, bool tight)
static void xcreatefcn(const graphics_handle &h)
static Matrix default_axes_outerposition(void)
static Matrix convert_position(const Matrix &pos, const caseless_str &from_units, const caseless_str &to_units, const Matrix &parent_dim)
octave_value get_property_from_handle(double handle, const std::string &property, const std::string &fcn)
static Matrix default_patch_faces(void)
static octave_value make_graphics_object(const std::string &go_name, bool integer_figure_handle, const octave_value_list &args)
static Matrix convert_text_position(const Matrix &pos, const text::properties &props, const caseless_str &from_units, const caseless_str &to_units)
static int toggle_warn(std::string id, bool on, int state=-1)
static bool isfigure(double val)
void convert_cdata_1(bool is_scaled, bool is_real, double clim_0, double clim_1, const double *cmapv, const T *cv, octave_idx_type lda, octave_idx_type nc, double *av)
static Matrix default_figure_position(void)
static void cleanup_waitfor_postset_listener(const octave_value &listener)
gtk_manager & __get_gtk_manager__(void)
interpreter & __get_interpreter__(void)
display_info & __get_display_info__(void)
gh_manager & __get_gh_manager__(void)
Complex atan(const Complex &x)
std::complex< T > floor(const std::complex< T > &x)
std::complex< T > ceil(const std::complex< T > &x)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
F77_RET_T const F77_DBLE const F77_DBLE * f
T::properties & properties(graphics_object obj)
octave_int< uint32_t > octave_uint32
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
octave_int< T > xmin(const octave_int< T > &x, const octave_int< T > &y)
octave_int< T > xmax(const octave_int< T > &x, const octave_int< T > &y)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
octave_value_list feval(const char *name, const octave_value_list &args, int nargout)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
static void initialize(void)
static char default_im_data[]
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
const octave_char_matrix & v2
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
static uint32_t state[624]
static std::string dir_sep_chars
void sleep(double seconds, bool do_graphics_events)