comparison src/graphics.cc @ 12389:5367bd36b9f8

implement autopositioning requests from text objects to axes
author Konstantinos Poulios <logari81@googlemail.com>
date Sun, 06 Feb 2011 17:17:12 +0100
parents d1e48a4a9a0b
children a3be83af8cfa
comparison
equal deleted inserted replaced
12388:cf9ca0dbc5ee 12389:5367bd36b9f8
2266 graphics_object go = gh_manager::get_object (kids(i)); 2266 graphics_object go = gh_manager::get_object (kids(i));
2267 2267
2268 if (go.valid_object ()) 2268 if (go.valid_object ())
2269 go.get_properties ().update_boundingbox (); 2269 go.get_properties ().update_boundingbox ();
2270 } 2270 }
2271 }
2272
2273 void
2274 base_properties::update_autopos (const std::string& elem_type)
2275 {
2276 graphics_object parent_obj = gh_manager::get_object (get_parent ());
2277
2278 if (parent_obj.valid_object ())
2279 parent_obj.get_properties ().update_autopos (elem_type);
2271 } 2280 }
2272 2281
2273 void 2282 void
2274 base_properties::add_listener (const caseless_str& nm, const octave_value& v, 2283 base_properties::add_listener (const caseless_str& nm, const octave_value& v,
2275 listener_mode mode) 2284 listener_mode mode)
3207 xset (xlabel.handle_value (), "clipping", "off"); 3216 xset (xlabel.handle_value (), "clipping", "off");
3208 xset (ylabel.handle_value (), "clipping", "off"); 3217 xset (ylabel.handle_value (), "clipping", "off");
3209 xset (zlabel.handle_value (), "clipping", "off"); 3218 xset (zlabel.handle_value (), "clipping", "off");
3210 xset (title.handle_value (), "clipping", "off"); 3219 xset (title.handle_value (), "clipping", "off");
3211 3220
3221 xset (xlabel.handle_value (), "autopos_tag", "xlabel");
3222 xset (ylabel.handle_value (), "autopos_tag", "ylabel");
3223 xset (zlabel.handle_value (), "autopos_tag", "zlabel");
3224 xset (title.handle_value (), "autopos_tag", "title");
3225
3212 adopt (xlabel.handle_value ()); 3226 adopt (xlabel.handle_value ());
3213 adopt (ylabel.handle_value ()); 3227 adopt (ylabel.handle_value ());
3214 adopt (zlabel.handle_value ()); 3228 adopt (zlabel.handle_value ());
3215 adopt (title.handle_value ()); 3229 adopt (title.handle_value ());
3216 } 3230 }
3299 xset (xlabel.handle_value (), "rotationmode", "auto"); 3313 xset (xlabel.handle_value (), "rotationmode", "auto");
3300 xset (xlabel.handle_value (), "horizontalalignmentmode", "auto"); 3314 xset (xlabel.handle_value (), "horizontalalignmentmode", "auto");
3301 xset (xlabel.handle_value (), "verticalalignmentmode", "auto"); 3315 xset (xlabel.handle_value (), "verticalalignmentmode", "auto");
3302 xset (xlabel.handle_value (), "clipping", "off"); 3316 xset (xlabel.handle_value (), "clipping", "off");
3303 xset (xlabel.handle_value (), "color", get_xcolor ()); 3317 xset (xlabel.handle_value (), "color", get_xcolor ());
3318 xset (xlabel.handle_value (), "autopos_tag", "xlabel");
3304 update_xlabel_position (); 3319 update_xlabel_position ();
3305 } 3320 }
3306 3321
3307 void 3322 void
3308 axes::properties::set_ylabel (const octave_value& v) 3323 axes::properties::set_ylabel (const octave_value& v)
3312 xset (ylabel.handle_value (), "rotationmode", "auto"); 3327 xset (ylabel.handle_value (), "rotationmode", "auto");
3313 xset (ylabel.handle_value (), "horizontalalignmentmode", "auto"); 3328 xset (ylabel.handle_value (), "horizontalalignmentmode", "auto");
3314 xset (ylabel.handle_value (), "verticalalignmentmode", "auto"); 3329 xset (ylabel.handle_value (), "verticalalignmentmode", "auto");
3315 xset (ylabel.handle_value (), "clipping", "off"); 3330 xset (ylabel.handle_value (), "clipping", "off");
3316 xset (ylabel.handle_value (), "color", get_ycolor ()); 3331 xset (ylabel.handle_value (), "color", get_ycolor ());
3332 xset (ylabel.handle_value (), "autopos_tag", "ylabel");
3317 update_ylabel_position (); 3333 update_ylabel_position ();
3318 } 3334 }
3319 3335
3320 void 3336 void
3321 axes::properties::set_zlabel (const octave_value& v) 3337 axes::properties::set_zlabel (const octave_value& v)
3325 xset (zlabel.handle_value (), "rotationmode", "auto"); 3341 xset (zlabel.handle_value (), "rotationmode", "auto");
3326 xset (zlabel.handle_value (), "horizontalalignmentmode", "auto"); 3342 xset (zlabel.handle_value (), "horizontalalignmentmode", "auto");
3327 xset (zlabel.handle_value (), "verticalalignmentmode", "auto"); 3343 xset (zlabel.handle_value (), "verticalalignmentmode", "auto");
3328 xset (zlabel.handle_value (), "clipping", "off"); 3344 xset (zlabel.handle_value (), "clipping", "off");
3329 xset (zlabel.handle_value (), "color", get_zcolor ()); 3345 xset (zlabel.handle_value (), "color", get_zcolor ());
3346 xset (zlabel.handle_value (), "autopos_tag", "zlabel");
3330 update_zlabel_position (); 3347 update_zlabel_position ();
3331 } 3348 }
3332 3349
3333 void 3350 void
3334 axes::properties::set_title (const octave_value& v) 3351 axes::properties::set_title (const octave_value& v)
3338 xset (title.handle_value (), "horizontalalignment", "center"); 3355 xset (title.handle_value (), "horizontalalignment", "center");
3339 xset (title.handle_value (), "horizontalalignmentmode", "auto"); 3356 xset (title.handle_value (), "horizontalalignmentmode", "auto");
3340 xset (title.handle_value (), "verticalalignment", "bottom"); 3357 xset (title.handle_value (), "verticalalignment", "bottom");
3341 xset (title.handle_value (), "verticalalignmentmode", "auto"); 3358 xset (title.handle_value (), "verticalalignmentmode", "auto");
3342 xset (title.handle_value (), "clipping", "off"); 3359 xset (title.handle_value (), "clipping", "off");
3360 xset (title.handle_value (), "autopos_tag", "title");
3343 update_title_position (); 3361 update_title_position ();
3344 } 3362 }
3345 3363
3346 void 3364 void
3347 axes::properties::set_defaults (base_graphics_object& obj, 3365 axes::properties::set_defaults (base_graphics_object& obj,
3483 xset (xlabel.handle_value (), "clipping", "off"); 3501 xset (xlabel.handle_value (), "clipping", "off");
3484 xset (ylabel.handle_value (), "clipping", "off"); 3502 xset (ylabel.handle_value (), "clipping", "off");
3485 xset (zlabel.handle_value (), "clipping", "off"); 3503 xset (zlabel.handle_value (), "clipping", "off");
3486 xset (title.handle_value (), "clipping", "off"); 3504 xset (title.handle_value (), "clipping", "off");
3487 3505
3506 xset (xlabel.handle_value (), "autopos_tag", "xlabel");
3507 xset (ylabel.handle_value (), "autopos_tag", "ylabel");
3508 xset (zlabel.handle_value (), "autopos_tag", "zlabel");
3509 xset (title.handle_value (), "autopos_tag", "title");
3510
3488 adopt (xlabel.handle_value ()); 3511 adopt (xlabel.handle_value ());
3489 adopt (ylabel.handle_value ()); 3512 adopt (ylabel.handle_value ());
3490 adopt (zlabel.handle_value ()); 3513 adopt (zlabel.handle_value ());
3491 adopt (title.handle_value ()); 3514 adopt (title.handle_value ());
3492 3515
4101 graphics_xform xform = get_transform (); 4124 graphics_xform xform = get_transform ();
4102 4125
4103 text::properties& xlabel_props = reinterpret_cast<text::properties&> 4126 text::properties& xlabel_props = reinterpret_cast<text::properties&>
4104 (gh_manager::get_object (get_xlabel ()).get_properties ()); 4127 (gh_manager::get_object (get_xlabel ()).get_properties ());
4105 4128
4106 if (xlabel_props.horizontalalignmentmode_is ("auto")) 4129 if (! xlabel_props.get_string ().empty ())
4107 { 4130 {
4108 xlabel_props.set_horizontalalignment 4131 xlabel_props.set_autopos_tag ("none");
4109 (xstate > AXE_DEPTH_DIR 4132
4110 ? "center" : (xyzSym ? "left" : "right")); 4133 if (xlabel_props.horizontalalignmentmode_is ("auto"))
4111 4134 {
4112 xlabel_props.set_horizontalalignmentmode ("auto"); 4135 xlabel_props.set_horizontalalignment
4113 } 4136 (xstate > AXE_DEPTH_DIR
4114 4137 ? "center" : (xyzSym ? "left" : "right"));
4115 if (xlabel_props.verticalalignmentmode_is ("auto")) 4138
4116 { 4139 xlabel_props.set_horizontalalignmentmode ("auto");
4117 xlabel_props.set_verticalalignment 4140 }
4118 (xstate == AXE_VERT_DIR || x2Dtop ? "bottom" : "top"); 4141
4119 4142 if (xlabel_props.verticalalignmentmode_is ("auto"))
4120 xlabel_props.set_verticalalignmentmode ("auto"); 4143 {
4121 } 4144 xlabel_props.set_verticalalignment
4122 4145 (xstate == AXE_VERT_DIR || x2Dtop ? "bottom" : "top");
4123 if (xlabel_props.positionmode_is ("auto") 4146
4124 || xlabel_props.rotationmode_is ("auto")) 4147 xlabel_props.set_verticalalignmentmode ("auto");
4125 { 4148 }
4126 Matrix ext (1, 2, 0.0); 4149
4127 ext = get_ticklabel_extents (get_xtick ().matrix_value (), 4150 if (xlabel_props.positionmode_is ("auto")
4128 get_xticklabel ().all_strings (), 4151 || xlabel_props.rotationmode_is ("auto"))
4129 get_xlim ().matrix_value ()); 4152 {
4130 4153 Matrix ext (1, 2, 0.0);
4131 double wmax = ext(0), hmax = ext(1), angle = 0; 4154 ext = get_ticklabel_extents (get_xtick ().matrix_value (),
4132 ColumnVector p = 4155 get_xticklabel ().all_strings (),
4133 graphics_xform::xform_vector ((xpTickN+xpTick)/2, ypTick, zpTick); 4156 get_xlim ().matrix_value ());
4134 4157
4135 bool tick_along_z = nearhoriz || xisinf (fy); 4158 double wmax = ext(0), hmax = ext(1), angle = 0;
4136 if (tick_along_z) 4159 ColumnVector p =
4137 p(2) += (signum(zpTick-zpTickN)*fz*xtickoffset); 4160 graphics_xform::xform_vector ((xpTickN+xpTick)/2, ypTick, zpTick);
4138 else 4161
4139 p(1) += (signum(ypTick-ypTickN)*fy*xtickoffset); 4162 bool tick_along_z = nearhoriz || xisinf (fy);
4140 4163 if (tick_along_z)
4141 p = xform.transform (p(0), p(1), p(2), false); 4164 p(2) += (signum(zpTick-zpTickN)*fz*xtickoffset);
4142 4165 else
4143 switch (xstate) 4166 p(1) += (signum(ypTick-ypTickN)*fy*xtickoffset);
4144 { 4167
4145 case AXE_ANY_DIR: 4168 p = xform.transform (p(0), p(1), p(2), false);
4146 p(0) += (xyzSym ? wmax : -wmax); 4169
4147 p(1) += hmax; 4170 switch (xstate)
4148 break; 4171 {
4149 4172 case AXE_ANY_DIR:
4150 case AXE_VERT_DIR: 4173 p(0) += (xyzSym ? wmax : -wmax);
4151 p(0) -= wmax; 4174 p(1) += hmax;
4152 angle = 90; 4175 break;
4153 break; 4176
4154 4177 case AXE_VERT_DIR:
4155 case AXE_HORZ_DIR: 4178 p(0) -= wmax;
4156 p(1) += (x2Dtop ? -hmax : hmax); 4179 angle = 90;
4157 break; 4180 break;
4158 } 4181
4159 4182 case AXE_HORZ_DIR:
4160 if (xlabel_props.positionmode_is ("auto")) 4183 p(1) += (x2Dtop ? -hmax : hmax);
4161 { 4184 break;
4162 p = xform.untransform (p(0), p(1), p(2), true); 4185 }
4163 xlabel_props.set_position (p.extract_n (0, 3).transpose ()); 4186
4164 xlabel_props.set_positionmode ("auto"); 4187 if (xlabel_props.positionmode_is ("auto"))
4165 } 4188 {
4166 4189 p = xform.untransform (p(0), p(1), p(2), true);
4167 if (xlabel_props.rotationmode_is ("auto")) 4190 xlabel_props.set_position (p.extract_n (0, 3).transpose ());
4168 { 4191 xlabel_props.set_positionmode ("auto");
4169 xlabel_props.set_rotation (angle); 4192 }
4170 xlabel_props.set_rotationmode ("auto"); 4193
4171 } 4194 if (xlabel_props.rotationmode_is ("auto"))
4195 {
4196 xlabel_props.set_rotation (angle);
4197 xlabel_props.set_rotationmode ("auto");
4198 }
4199 }
4200
4201 xlabel_props.set_autopos_tag ("xlabel");
4172 } 4202 }
4173 } 4203 }
4174 4204
4175 void 4205 void
4176 axes::properties::update_ylabel_position (void) 4206 axes::properties::update_ylabel_position (void)
4178 graphics_xform xform = get_transform (); 4208 graphics_xform xform = get_transform ();
4179 4209
4180 text::properties& ylabel_props = reinterpret_cast<text::properties&> 4210 text::properties& ylabel_props = reinterpret_cast<text::properties&>
4181 (gh_manager::get_object (get_ylabel ()).get_properties ()); 4211 (gh_manager::get_object (get_ylabel ()).get_properties ());
4182 4212
4183 if (ylabel_props.horizontalalignmentmode_is ("auto")) 4213 if (! ylabel_props.get_string ().empty ())
4184 { 4214 {
4185 ylabel_props.set_horizontalalignment 4215 ylabel_props.set_autopos_tag ("none");
4186 (ystate > AXE_DEPTH_DIR 4216
4187 ? "center" : (!xyzSym ? "left" : "right")); 4217 if (ylabel_props.horizontalalignmentmode_is ("auto"))
4188 4218 {
4189 ylabel_props.set_horizontalalignmentmode ("auto"); 4219 ylabel_props.set_horizontalalignment
4190 } 4220 (ystate > AXE_DEPTH_DIR
4191 4221 ? "center" : (!xyzSym ? "left" : "right"));
4192 if (ylabel_props.verticalalignmentmode_is ("auto")) 4222
4193 { 4223 ylabel_props.set_horizontalalignmentmode ("auto");
4194 ylabel_props.set_verticalalignment 4224 }
4195 (ystate == AXE_VERT_DIR && !y2Dright ? "bottom" : "top"); 4225
4196 4226 if (ylabel_props.verticalalignmentmode_is ("auto"))
4197 ylabel_props.set_verticalalignmentmode ("auto"); 4227 {
4198 } 4228 ylabel_props.set_verticalalignment
4199 4229 (ystate == AXE_VERT_DIR && !y2Dright ? "bottom" : "top");
4200 if (ylabel_props.positionmode_is ("auto") 4230
4201 || ylabel_props.rotationmode_is ("auto")) 4231 ylabel_props.set_verticalalignmentmode ("auto");
4202 { 4232 }
4203 Matrix ext (1, 2, 0.0); 4233
4204 ext = get_ticklabel_extents (get_ytick ().matrix_value (), 4234 if (ylabel_props.positionmode_is ("auto")
4205 get_yticklabel ().all_strings (), 4235 || ylabel_props.rotationmode_is ("auto"))
4206 get_ylim ().matrix_value ()); 4236 {
4207 4237 Matrix ext (1, 2, 0.0);
4208 double wmax = ext(0), hmax = ext(1), angle = 0; 4238 ext = get_ticklabel_extents (get_ytick ().matrix_value (),
4209 ColumnVector p = 4239 get_yticklabel ().all_strings (),
4210 graphics_xform::xform_vector (xpTick, (ypTickN+ypTick)/2, zpTick); 4240 get_ylim ().matrix_value ());
4211 4241
4212 bool tick_along_z = nearhoriz || xisinf (fx); 4242 double wmax = ext(0), hmax = ext(1), angle = 0;
4213 if (tick_along_z) 4243 ColumnVector p =
4214 p(2) += (signum(zpTick-zpTickN)*fz*ytickoffset); 4244 graphics_xform::xform_vector (xpTick, (ypTickN+ypTick)/2, zpTick);
4215 else 4245
4216 p(0) += (signum(xpTick-xpTickN)*fx*ytickoffset); 4246 bool tick_along_z = nearhoriz || xisinf (fx);
4217 4247 if (tick_along_z)
4218 p = xform.transform (p(0), p(1), p(2), false); 4248 p(2) += (signum(zpTick-zpTickN)*fz*ytickoffset);
4219 4249 else
4220 switch (ystate) 4250 p(0) += (signum(xpTick-xpTickN)*fx*ytickoffset);
4221 { 4251
4222 case AXE_ANY_DIR: 4252 p = xform.transform (p(0), p(1), p(2), false);
4223 p(0) += (!xyzSym ? wmax : -wmax); 4253
4224 p(1) += hmax; 4254 switch (ystate)
4225 break; 4255 {
4226 4256 case AXE_ANY_DIR:
4227 case AXE_VERT_DIR: 4257 p(0) += (!xyzSym ? wmax : -wmax);
4228 p(0) += (y2Dright ? wmax : -wmax); 4258 p(1) += hmax;
4229 angle = 90; 4259 break;
4230 break; 4260
4231 4261 case AXE_VERT_DIR:
4232 case AXE_HORZ_DIR: 4262 p(0) += (y2Dright ? wmax : -wmax);
4233 p(1) += hmax; 4263 angle = 90;
4234 break; 4264 break;
4235 } 4265
4236 4266 case AXE_HORZ_DIR:
4237 if (ylabel_props.positionmode_is ("auto")) 4267 p(1) += hmax;
4238 { 4268 break;
4239 p = xform.untransform (p(0), p(1), p(2), true); 4269 }
4240 ylabel_props.set_position (p.extract_n (0, 3).transpose ()); 4270
4241 ylabel_props.set_positionmode ("auto"); 4271 if (ylabel_props.positionmode_is ("auto"))
4242 } 4272 {
4243 4273 p = xform.untransform (p(0), p(1), p(2), true);
4244 if (ylabel_props.rotationmode_is ("auto")) 4274 ylabel_props.set_position (p.extract_n (0, 3).transpose ());
4245 { 4275 ylabel_props.set_positionmode ("auto");
4246 ylabel_props.set_rotation (angle); 4276 }
4247 ylabel_props.set_rotationmode ("auto"); 4277
4248 } 4278 if (ylabel_props.rotationmode_is ("auto"))
4279 {
4280 ylabel_props.set_rotation (angle);
4281 ylabel_props.set_rotationmode ("auto");
4282 }
4283 }
4284
4285 ylabel_props.set_autopos_tag ("ylabel");
4249 } 4286 }
4250 } 4287 }
4251 4288
4252 void 4289 void
4253 axes::properties::update_zlabel_position (void) 4290 axes::properties::update_zlabel_position (void)
4255 graphics_xform xform = get_transform (); 4292 graphics_xform xform = get_transform ();
4256 4293
4257 text::properties& zlabel_props = reinterpret_cast<text::properties&> 4294 text::properties& zlabel_props = reinterpret_cast<text::properties&>
4258 (gh_manager::get_object (get_zlabel ()).get_properties ()); 4295 (gh_manager::get_object (get_zlabel ()).get_properties ());
4259 4296
4260 bool camAuto = cameraupvectormode_is ("auto"); 4297 if (! zlabel_props.get_string ().empty ())
4261 4298 {
4262 if (zlabel_props.horizontalalignmentmode_is ("auto")) 4299 zlabel_props.set_autopos_tag ("none");
4263 { 4300
4264 zlabel_props.set_horizontalalignment 4301 bool camAuto = cameraupvectormode_is ("auto");
4265 ((zstate > AXE_DEPTH_DIR || camAuto) ? "center" : "right"); 4302
4266 4303 if (zlabel_props.horizontalalignmentmode_is ("auto"))
4267 zlabel_props.set_horizontalalignmentmode ("auto"); 4304 {
4268 } 4305 zlabel_props.set_horizontalalignment
4269 4306 ((zstate > AXE_DEPTH_DIR || camAuto) ? "center" : "right");
4270 if (zlabel_props.verticalalignmentmode_is ("auto")) 4307
4271 { 4308 zlabel_props.set_horizontalalignmentmode ("auto");
4272 zlabel_props.set_verticalalignment 4309 }
4273 (zstate == AXE_VERT_DIR 4310
4274 ? "bottom" : ((zSign || camAuto) ? "bottom" : "top")); 4311 if (zlabel_props.verticalalignmentmode_is ("auto"))
4275 4312 {
4276 zlabel_props.set_verticalalignmentmode ("auto"); 4313 zlabel_props.set_verticalalignment
4277 } 4314 (zstate == AXE_VERT_DIR
4278 4315 ? "bottom" : ((zSign || camAuto) ? "bottom" : "top"));
4279 if (zlabel_props.positionmode_is ("auto") 4316
4280 || zlabel_props.rotationmode_is ("auto")) 4317 zlabel_props.set_verticalalignmentmode ("auto");
4281 { 4318 }
4282 Matrix ext (1, 2, 0.0); 4319
4283 ext = get_ticklabel_extents (get_ztick ().matrix_value (), 4320 if (zlabel_props.positionmode_is ("auto")
4284 get_zticklabel ().all_strings (), 4321 || zlabel_props.rotationmode_is ("auto"))
4285 get_zlim ().matrix_value ()); 4322 {
4286 4323 Matrix ext (1, 2, 0.0);
4287 double wmax = ext(0), hmax = ext(1), angle = 0; 4324 ext = get_ticklabel_extents (get_ztick ().matrix_value (),
4288 ColumnVector p; 4325 get_zticklabel ().all_strings (),
4289 4326 get_zlim ().matrix_value ());
4290 if (xySym) 4327
4291 { 4328 double wmax = ext(0), hmax = ext(1), angle = 0;
4292 p = graphics_xform::xform_vector (xPlaneN, yPlane, 4329 ColumnVector p;
4293 (zpTickN+zpTick)/2); 4330
4294 if (xisinf (fy)) 4331 if (xySym)
4295 p(0) += (signum(xPlaneN-xPlane)*fx*ztickoffset); 4332 {
4333 p = graphics_xform::xform_vector (xPlaneN, yPlane,
4334 (zpTickN+zpTick)/2);
4335 if (xisinf (fy))
4336 p(0) += (signum(xPlaneN-xPlane)*fx*ztickoffset);
4337 else
4338 p(1) += (signum(yPlane-yPlaneN)*fy*ztickoffset);
4339 }
4296 else 4340 else
4297 p(1) += (signum(yPlane-yPlaneN)*fy*ztickoffset); 4341 {
4298 } 4342 p = graphics_xform::xform_vector (xPlane, yPlaneN,
4299 else 4343 (zpTickN+zpTick)/2);
4300 { 4344 if (xisinf (fx))
4301 p = graphics_xform::xform_vector (xPlane, yPlaneN, 4345 p(1) += (signum(yPlaneN-yPlane)*fy*ztickoffset);
4302 (zpTickN+zpTick)/2); 4346 else
4303 if (xisinf (fx)) 4347 p(0) += (signum(xPlane-xPlaneN)*fx*ztickoffset);
4304 p(1) += (signum(yPlaneN-yPlane)*fy*ztickoffset); 4348 }
4305 else 4349
4306 p(0) += (signum(xPlane-xPlaneN)*fx*ztickoffset); 4350 p = xform.transform (p(0), p(1), p(2), false);
4307 } 4351
4308 4352 switch (zstate)
4309 p = xform.transform (p(0), p(1), p(2), false); 4353 {
4310 4354 case AXE_ANY_DIR:
4311 switch (zstate) 4355 if (camAuto)
4312 { 4356 {
4313 case AXE_ANY_DIR: 4357 p(0) -= wmax;
4314 if (camAuto) 4358 angle = 90;
4315 { 4359 }
4360
4361 // FIXME -- what's the correct offset?
4362 //
4363 // p[0] += (!xySym ? wmax : -wmax);
4364 // p[1] += (zSign ? hmax : -hmax);
4365
4366 break;
4367
4368 case AXE_VERT_DIR:
4316 p(0) -= wmax; 4369 p(0) -= wmax;
4317 angle = 90; 4370 angle = 90;
4318 } 4371 break;
4319 4372
4320 // FIXME -- what's the correct offset? 4373 case AXE_HORZ_DIR:
4321 // 4374 p(1) += hmax;
4322 // p[0] += (!xySym ? wmax : -wmax); 4375 break;
4323 // p[1] += (zSign ? hmax : -hmax); 4376 }
4324 4377
4325 break; 4378 if (zlabel_props.positionmode_is ("auto"))
4326 4379 {
4327 case AXE_VERT_DIR: 4380 p = xform.untransform (p(0), p(1), p(2), true);
4328 p(0) -= wmax; 4381 zlabel_props.set_position (p.extract_n (0, 3).transpose ());
4329 angle = 90; 4382 zlabel_props.set_positionmode ("auto");
4330 break; 4383 }
4331 4384
4332 case AXE_HORZ_DIR: 4385 if (zlabel_props.rotationmode_is ("auto"))
4333 p(1) += hmax; 4386 {
4334 break; 4387 zlabel_props.set_rotation (angle);
4335 } 4388 zlabel_props.set_rotationmode ("auto");
4336 4389 }
4337 if (zlabel_props.positionmode_is ("auto")) 4390 }
4338 { 4391
4339 p = xform.untransform (p(0), p(1), p(2), true); 4392 zlabel_props.set_autopos_tag ("zlabel");
4340 zlabel_props.set_position (p.extract_n (0, 3).transpose ());
4341 zlabel_props.set_positionmode ("auto");
4342 }
4343
4344 if (zlabel_props.rotationmode_is ("auto"))
4345 {
4346 zlabel_props.set_rotation (angle);
4347 zlabel_props.set_rotationmode ("auto");
4348 }
4349 } 4393 }
4350 } 4394 }
4351 4395
4352 void 4396 void
4353 axes::properties::update_title_position (void) 4397 axes::properties::update_title_position (void)
4355 graphics_xform xform = get_transform (); 4399 graphics_xform xform = get_transform ();
4356 4400
4357 text::properties& title_props = reinterpret_cast<text::properties&> 4401 text::properties& title_props = reinterpret_cast<text::properties&>
4358 (gh_manager::get_object (get_title ()).get_properties ()); 4402 (gh_manager::get_object (get_title ()).get_properties ());
4359 4403
4360 if (title_props.positionmode_is ("auto")) 4404 if (! title_props.get_string ().empty ())
4361 { 4405 {
4362 // FIXME: bbox should be stored in axes::properties 4406 title_props.set_autopos_tag ("none");
4363 ColumnVector bbox(4); 4407
4364 bbox(0) = octave_Inf; 4408 if (title_props.positionmode_is ("auto"))
4365 bbox(1) = octave_Inf; 4409 {
4366 bbox(2) = -octave_Inf; 4410 // FIXME: bbox should be stored in axes::properties
4367 bbox(3) = -octave_Inf; 4411 ColumnVector bbox(4);
4368 for (int i = 0; i <= 1; i++) 4412 bbox(0) = octave_Inf;
4369 for (int j = 0; j <= 1; j++) 4413 bbox(1) = octave_Inf;
4370 for (int k = 0; k <= 1; k++) 4414 bbox(2) = -octave_Inf;
4371 { 4415 bbox(3) = -octave_Inf;
4372 ColumnVector p = xform.transform (i ? xPlaneN : xPlane, 4416 for (int i = 0; i <= 1; i++)
4373 j ? yPlaneN : yPlane, 4417 for (int j = 0; j <= 1; j++)
4374 k ? zPlaneN : zPlane, false); 4418 for (int k = 0; k <= 1; k++)
4375 bbox(0) = std::min (bbox(0), p(0)); 4419 {
4376 bbox(1) = std::min (bbox(1), p(1)); 4420 ColumnVector p = xform.transform (i ? xPlaneN : xPlane,
4377 bbox(2) = std::max (bbox(2), p(0)); 4421 j ? yPlaneN : yPlane,
4378 bbox(3) = std::max (bbox(3), p(1)); 4422 k ? zPlaneN : zPlane, false);
4379 } 4423 bbox(0) = std::min (bbox(0), p(0));
4380 4424 bbox(1) = std::min (bbox(1), p(1));
4381 bbox(2) = bbox(2)-bbox(0); 4425 bbox(2) = std::max (bbox(2), p(0));
4382 bbox(3) = bbox(3)-bbox(1); 4426 bbox(3) = std::max (bbox(3), p(1));
4383 4427 }
4384 ColumnVector p = xform.untransform (bbox(0)+bbox(2)/2, (bbox(1)-10), 4428
4385 (x_zlim(0)+x_zlim(1))/2, true); 4429 bbox(2) = bbox(2)-bbox(0);
4386 4430 bbox(3) = bbox(3)-bbox(1);
4387 title_props.set_position (p.extract_n(0, 3).transpose ()); 4431
4388 title_props.set_positionmode ("auto"); 4432 ColumnVector p = xform.untransform (bbox(0)+bbox(2)/2, (bbox(1)-10),
4389 } 4433 (x_zlim(0)+x_zlim(1))/2, true);
4434
4435 title_props.set_position (p.extract_n(0, 3).transpose ());
4436 title_props.set_positionmode ("auto");
4437 }
4438
4439 title_props.set_autopos_tag ("title");
4440 }
4441 }
4442
4443 void
4444 axes::properties::update_autopos (const std::string& elem_type)
4445 {
4446 if (elem_type == "xlabel")
4447 update_xlabel_position ();
4448 else if (elem_type == "ylabel")
4449 update_ylabel_position ();
4450 else if (elem_type == "zlabel")
4451 update_zlabel_position ();
4452 else if (elem_type == "title")
4453 update_title_position ();
4390 } 4454 }
4391 4455
4392 static void 4456 static void
4393 normalized_aspectratios (Matrix& aspectratios, const Matrix& scalefactors, 4457 normalized_aspectratios (Matrix& aspectratios, const Matrix& scalefactors,
4394 double xlength, double ylength, double zlength) 4458 double xlength, double ylength, double zlength)
5658 renderer.text_to_pixels (get_string (), pixels, bbox, 5722 renderer.text_to_pixels (get_string (), pixels, bbox,
5659 halign, valign, get_rotation ()); 5723 halign, valign, get_rotation ());
5660 5724
5661 set_extent (bbox); 5725 set_extent (bbox);
5662 #endif 5726 #endif
5727 }
5728
5729 void
5730 text::properties::request_autopos (void)
5731 {
5732 if (autopos_tag_is ("xlabel") || autopos_tag_is ("ylabel") ||
5733 autopos_tag_is ("zlabel") || autopos_tag_is ("title"))
5734 {
5735 const std::string text_type = get_autopos_tag ();
5736 set_autopos_tag ("none");
5737 update_autopos (text_type);
5738 set_autopos_tag (text_type);
5739 }
5663 } 5740 }
5664 5741
5665 void 5742 void
5666 text::properties::update_units (void) 5743 text::properties::update_units (void)
5667 { 5744 {