1 // Take a look at the license at the top of the repository in the LICENSE file. 2 3 use crate::translate::*; 4 use crate::utils::is_canonical_pspec_name; 5 use crate::ParamFlags; 6 use crate::StaticType; 7 use crate::Type; 8 use crate::Value; 9 10 use std::char::CharTryFromError; 11 use std::convert::TryFrom; 12 use std::ffi::CStr; 13 14 // Can't use get_type here as this is not a boxed type but another fundamental type 15 wrapper! { 16 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 17 #[doc(alias = "GParamSpec")] 18 pub struct ParamSpec(Shared<gobject_ffi::GParamSpec>); 19 20 match fn { 21 ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr), 22 unref => |ptr| gobject_ffi::g_param_spec_unref(ptr), 23 } 24 } 25 26 impl StaticType for ParamSpec { static_type() -> Type27 fn static_type() -> Type { 28 unsafe { from_glib(gobject_ffi::G_TYPE_PARAM) } 29 } 30 } 31 32 #[doc(hidden)] 33 impl crate::value::ValueType for ParamSpec { 34 type Type = ParamSpec; 35 } 36 37 #[doc(hidden)] 38 unsafe impl<'a> crate::value::FromValue<'a> for ParamSpec { 39 type Checker = crate::value::GenericValueTypeOrNoneChecker<Self>; 40 from_value(value: &'a crate::Value) -> Self41 unsafe fn from_value(value: &'a crate::Value) -> Self { 42 let ptr = gobject_ffi::g_value_dup_param(value.to_glib_none().0); 43 assert!(!ptr.is_null()); 44 from_glib_full(ptr as *mut gobject_ffi::GParamSpec) 45 } 46 } 47 48 #[doc(hidden)] 49 impl crate::value::ToValue for ParamSpec { to_value(&self) -> crate::Value50 fn to_value(&self) -> crate::Value { 51 unsafe { 52 let mut value = crate::Value::from_type(ParamSpec::static_type()); 53 gobject_ffi::g_value_take_param( 54 value.to_glib_none_mut().0, 55 self.to_glib_full() as *mut _, 56 ); 57 value 58 } 59 } 60 value_type(&self) -> crate::Type61 fn value_type(&self) -> crate::Type { 62 ParamSpec::static_type() 63 } 64 } 65 66 #[doc(hidden)] 67 impl crate::value::ToValueOptional for ParamSpec { to_value_optional(s: Option<&Self>) -> crate::Value68 fn to_value_optional(s: Option<&Self>) -> crate::Value { 69 let mut value = crate::Value::for_value_type::<Self>(); 70 unsafe { 71 gobject_ffi::g_value_take_param(value.to_glib_none_mut().0, s.to_glib_full() as *mut _); 72 } 73 74 value 75 } 76 } 77 78 unsafe impl Send for ParamSpec {} 79 unsafe impl Sync for ParamSpec {} 80 81 impl ParamSpec { downcast<T: ParamSpecType>(self) -> Result<T, ParamSpec>82 pub fn downcast<T: ParamSpecType>(self) -> Result<T, ParamSpec> { 83 unsafe { 84 if self.type_() == T::static_type() { 85 Ok(from_glib_full(self.to_glib_full())) 86 } else { 87 Err(self) 88 } 89 } 90 } 91 downcast_ref<T: ParamSpecType>(&self) -> Option<&T>92 pub fn downcast_ref<T: ParamSpecType>(&self) -> Option<&T> { 93 unsafe { 94 if self.type_() == T::static_type() { 95 Some(&*(self as *const ParamSpec as *const T)) 96 } else { 97 None 98 } 99 } 100 } 101 102 #[doc(alias = "get_type")] type_(&self) -> Type103 pub fn type_(&self) -> Type { 104 unsafe { 105 let ptr = self.to_glib_none().0; 106 107 from_glib((*(*ptr).g_type_instance.g_class).g_type) 108 } 109 } 110 111 #[doc(alias = "get_value_type")] value_type(&self) -> crate::Type112 pub fn value_type(&self) -> crate::Type { 113 unsafe { from_glib((*self.to_glib_none().0).value_type) } 114 } 115 116 #[doc(alias = "get_owner_type")] owner_type(&self) -> crate::Type117 pub fn owner_type(&self) -> crate::Type { 118 unsafe { from_glib((*self.to_glib_none().0).owner_type) } 119 } 120 121 #[doc(alias = "get_flags")] flags(&self) -> ParamFlags122 pub fn flags(&self) -> ParamFlags { 123 unsafe { from_glib((*self.to_glib_none().0).flags) } 124 } 125 126 #[doc(alias = "g_param_spec_get_blurb")] 127 #[doc(alias = "get_blurb")] blurb(&self) -> &str128 pub fn blurb(&self) -> &str { 129 unsafe { 130 CStr::from_ptr(gobject_ffi::g_param_spec_get_blurb(self.to_glib_none().0)) 131 .to_str() 132 .unwrap() 133 } 134 } 135 136 #[doc(alias = "g_param_spec_get_default_value")] 137 #[doc(alias = "get_default_value")] default_value(&self) -> &Value138 pub fn default_value(&self) -> &Value { 139 unsafe { 140 &*(gobject_ffi::g_param_spec_get_default_value(self.to_glib_none().0) 141 as *const crate::Value) 142 } 143 } 144 145 #[doc(alias = "g_param_spec_get_name")] 146 #[doc(alias = "get_name")] name<'a>(&self) -> &'a str147 pub fn name<'a>(&self) -> &'a str { 148 unsafe { 149 CStr::from_ptr(gobject_ffi::g_param_spec_get_name(self.to_glib_none().0)) 150 .to_str() 151 .unwrap() 152 } 153 } 154 155 #[doc(alias = "g_param_spec_get_name_quark")] 156 #[doc(alias = "get_name_quark")] name_quark(&self) -> crate::Quark157 pub fn name_quark(&self) -> crate::Quark { 158 unsafe { 159 from_glib(gobject_ffi::g_param_spec_get_name_quark( 160 self.to_glib_none().0, 161 )) 162 } 163 } 164 165 #[doc(alias = "g_param_spec_get_nick")] 166 #[doc(alias = "get_nick")] nick(&self) -> &str167 pub fn nick(&self) -> &str { 168 unsafe { 169 CStr::from_ptr(gobject_ffi::g_param_spec_get_nick(self.to_glib_none().0)) 170 .to_str() 171 .unwrap() 172 } 173 } 174 175 //pub fn get_qdata(&self, quark: /*Ignored*/glib::Quark) -> /*Unimplemented*/Option<Fundamental: Pointer> { 176 // unsafe { TODO: call gobject_ffi::g_param_spec_get_qdata() } 177 //} 178 179 #[doc(alias = "g_param_spec_get_redirect_target")] 180 #[doc(alias = "get_redirect_target")] redirect_target(&self) -> Option<ParamSpec>181 pub fn redirect_target(&self) -> Option<ParamSpec> { 182 unsafe { 183 from_glib_none(gobject_ffi::g_param_spec_get_redirect_target( 184 self.to_glib_none().0, 185 )) 186 } 187 } 188 189 //pub fn set_qdata(&self, quark: /*Ignored*/glib::Quark, data: Option</*Unimplemented*/Fundamental: Pointer>) { 190 // unsafe { TODO: call gobject_ffi::g_param_spec_set_qdata() } 191 //} 192 193 //pub fn set_qdata_full(&self, quark: /*Ignored*/glib::Quark, data: Option</*Unimplemented*/Fundamental: Pointer>, destroy: /*Unknown conversion*//*Unimplemented*/DestroyNotify) { 194 // unsafe { TODO: call gobject_ffi::g_param_spec_set_qdata_full() } 195 //} 196 197 //pub fn steal_qdata(&self, quark: /*Ignored*/glib::Quark) -> /*Unimplemented*/Option<Fundamental: Pointer> { 198 // unsafe { TODO: call gobject_ffi::g_param_spec_steal_qdata() } 199 //} 200 201 #[doc(alias = "g_param_spec_boolean")] new_boolean( name: &str, nick: &str, blurb: &str, default_value: bool, flags: ParamFlags, ) -> ParamSpec202 pub fn new_boolean( 203 name: &str, 204 nick: &str, 205 blurb: &str, 206 default_value: bool, 207 flags: ParamFlags, 208 ) -> ParamSpec { 209 assert!( 210 is_canonical_pspec_name(name), 211 "{} is not a valid canonical parameter name", 212 name 213 ); 214 unsafe { 215 from_glib_none(gobject_ffi::g_param_spec_boolean( 216 name.to_glib_none().0, 217 nick.to_glib_none().0, 218 blurb.to_glib_none().0, 219 default_value.into_glib(), 220 flags.into_glib(), 221 )) 222 } 223 } 224 225 #[doc(alias = "g_param_spec_boxed")] new_boxed( name: &str, nick: &str, blurb: &str, boxed_type: crate::Type, flags: ParamFlags, ) -> ParamSpec226 pub fn new_boxed( 227 name: &str, 228 nick: &str, 229 blurb: &str, 230 boxed_type: crate::Type, 231 flags: ParamFlags, 232 ) -> ParamSpec { 233 assert!( 234 is_canonical_pspec_name(name), 235 "{} is not a valid canonical parameter name", 236 name 237 ); 238 unsafe { 239 from_glib_none(gobject_ffi::g_param_spec_boxed( 240 name.to_glib_none().0, 241 nick.to_glib_none().0, 242 blurb.to_glib_none().0, 243 boxed_type.into_glib(), 244 flags.into_glib(), 245 )) 246 } 247 } 248 249 #[doc(alias = "g_param_spec_char")] new_char( name: &str, nick: &str, blurb: &str, minimum: i8, maximum: i8, default_value: i8, flags: ParamFlags, ) -> ParamSpec250 pub fn new_char( 251 name: &str, 252 nick: &str, 253 blurb: &str, 254 minimum: i8, 255 maximum: i8, 256 default_value: i8, 257 flags: ParamFlags, 258 ) -> ParamSpec { 259 assert!( 260 is_canonical_pspec_name(name), 261 "{} is not a valid canonical parameter name", 262 name 263 ); 264 unsafe { 265 from_glib_none(gobject_ffi::g_param_spec_char( 266 name.to_glib_none().0, 267 nick.to_glib_none().0, 268 blurb.to_glib_none().0, 269 minimum, 270 maximum, 271 default_value, 272 flags.into_glib(), 273 )) 274 } 275 } 276 277 #[doc(alias = "g_param_spec_double")] new_double( name: &str, nick: &str, blurb: &str, minimum: f64, maximum: f64, default_value: f64, flags: ParamFlags, ) -> ParamSpec278 pub fn new_double( 279 name: &str, 280 nick: &str, 281 blurb: &str, 282 minimum: f64, 283 maximum: f64, 284 default_value: f64, 285 flags: ParamFlags, 286 ) -> ParamSpec { 287 assert!( 288 is_canonical_pspec_name(name), 289 "{} is not a valid canonical parameter name", 290 name 291 ); 292 unsafe { 293 from_glib_none(gobject_ffi::g_param_spec_double( 294 name.to_glib_none().0, 295 nick.to_glib_none().0, 296 blurb.to_glib_none().0, 297 minimum, 298 maximum, 299 default_value, 300 flags.into_glib(), 301 )) 302 } 303 } 304 305 #[doc(alias = "g_param_spec_enum")] new_enum( name: &str, nick: &str, blurb: &str, enum_type: crate::Type, default_value: i32, flags: ParamFlags, ) -> ParamSpec306 pub fn new_enum( 307 name: &str, 308 nick: &str, 309 blurb: &str, 310 enum_type: crate::Type, 311 default_value: i32, 312 flags: ParamFlags, 313 ) -> ParamSpec { 314 assert!( 315 is_canonical_pspec_name(name), 316 "{} is not a valid canonical parameter name", 317 name 318 ); 319 unsafe { 320 from_glib_none(gobject_ffi::g_param_spec_enum( 321 name.to_glib_none().0, 322 nick.to_glib_none().0, 323 blurb.to_glib_none().0, 324 enum_type.into_glib(), 325 default_value, 326 flags.into_glib(), 327 )) 328 } 329 } 330 331 #[doc(alias = "g_param_spec_flags")] new_flags( name: &str, nick: &str, blurb: &str, flags_type: crate::Type, default_value: u32, flags: ParamFlags, ) -> ParamSpec332 pub fn new_flags( 333 name: &str, 334 nick: &str, 335 blurb: &str, 336 flags_type: crate::Type, 337 default_value: u32, 338 flags: ParamFlags, 339 ) -> ParamSpec { 340 assert!( 341 is_canonical_pspec_name(name), 342 "{} is not a valid canonical parameter name", 343 name 344 ); 345 unsafe { 346 from_glib_none(gobject_ffi::g_param_spec_flags( 347 name.to_glib_none().0, 348 nick.to_glib_none().0, 349 blurb.to_glib_none().0, 350 flags_type.into_glib(), 351 default_value, 352 flags.into_glib(), 353 )) 354 } 355 } 356 357 #[doc(alias = "g_param_spec_float")] new_float( name: &str, nick: &str, blurb: &str, minimum: f32, maximum: f32, default_value: f32, flags: ParamFlags, ) -> ParamSpec358 pub fn new_float( 359 name: &str, 360 nick: &str, 361 blurb: &str, 362 minimum: f32, 363 maximum: f32, 364 default_value: f32, 365 flags: ParamFlags, 366 ) -> ParamSpec { 367 assert!( 368 is_canonical_pspec_name(name), 369 "{} is not a valid canonical parameter name", 370 name 371 ); 372 unsafe { 373 from_glib_none(gobject_ffi::g_param_spec_float( 374 name.to_glib_none().0, 375 nick.to_glib_none().0, 376 blurb.to_glib_none().0, 377 minimum, 378 maximum, 379 default_value, 380 flags.into_glib(), 381 )) 382 } 383 } 384 385 #[doc(alias = "g_param_spec_gtype")] new_type( name: &str, nick: &str, blurb: &str, is_a_type: crate::Type, flags: ParamFlags, ) -> ParamSpec386 pub fn new_type( 387 name: &str, 388 nick: &str, 389 blurb: &str, 390 is_a_type: crate::Type, 391 flags: ParamFlags, 392 ) -> ParamSpec { 393 assert!( 394 is_canonical_pspec_name(name), 395 "{} is not a valid canonical parameter name", 396 name 397 ); 398 unsafe { 399 from_glib_none(gobject_ffi::g_param_spec_gtype( 400 name.to_glib_none().0, 401 nick.to_glib_none().0, 402 blurb.to_glib_none().0, 403 is_a_type.into_glib(), 404 flags.into_glib(), 405 )) 406 } 407 } 408 409 #[doc(alias = "g_param_spec_int")] new_int( name: &str, nick: &str, blurb: &str, minimum: i32, maximum: i32, default_value: i32, flags: ParamFlags, ) -> ParamSpec410 pub fn new_int( 411 name: &str, 412 nick: &str, 413 blurb: &str, 414 minimum: i32, 415 maximum: i32, 416 default_value: i32, 417 flags: ParamFlags, 418 ) -> ParamSpec { 419 assert!( 420 is_canonical_pspec_name(name), 421 "{} is not a valid canonical parameter name", 422 name 423 ); 424 unsafe { 425 from_glib_none(gobject_ffi::g_param_spec_int( 426 name.to_glib_none().0, 427 nick.to_glib_none().0, 428 blurb.to_glib_none().0, 429 minimum, 430 maximum, 431 default_value, 432 flags.into_glib(), 433 )) 434 } 435 } 436 437 #[doc(alias = "g_param_spec_int64")] new_int64( name: &str, nick: &str, blurb: &str, minimum: i64, maximum: i64, default_value: i64, flags: ParamFlags, ) -> ParamSpec438 pub fn new_int64( 439 name: &str, 440 nick: &str, 441 blurb: &str, 442 minimum: i64, 443 maximum: i64, 444 default_value: i64, 445 flags: ParamFlags, 446 ) -> ParamSpec { 447 assert!( 448 is_canonical_pspec_name(name), 449 "{} is not a valid canonical parameter name", 450 name 451 ); 452 unsafe { 453 from_glib_none(gobject_ffi::g_param_spec_int64( 454 name.to_glib_none().0, 455 nick.to_glib_none().0, 456 blurb.to_glib_none().0, 457 minimum, 458 maximum, 459 default_value, 460 flags.into_glib(), 461 )) 462 } 463 } 464 465 #[doc(alias = "g_param_spec_long")] new_long( name: &str, nick: &str, blurb: &str, minimum: libc::c_long, maximum: libc::c_long, default_value: libc::c_long, flags: ParamFlags, ) -> ParamSpec466 pub fn new_long( 467 name: &str, 468 nick: &str, 469 blurb: &str, 470 minimum: libc::c_long, 471 maximum: libc::c_long, 472 default_value: libc::c_long, 473 flags: ParamFlags, 474 ) -> ParamSpec { 475 assert!( 476 is_canonical_pspec_name(name), 477 "{} is not a valid canonical parameter name", 478 name 479 ); 480 unsafe { 481 from_glib_none(gobject_ffi::g_param_spec_long( 482 name.to_glib_none().0, 483 nick.to_glib_none().0, 484 blurb.to_glib_none().0, 485 minimum, 486 maximum, 487 default_value, 488 flags.into_glib(), 489 )) 490 } 491 } 492 493 #[doc(alias = "g_param_spec_object")] new_object( name: &str, nick: &str, blurb: &str, object_type: crate::Type, flags: ParamFlags, ) -> ParamSpec494 pub fn new_object( 495 name: &str, 496 nick: &str, 497 blurb: &str, 498 object_type: crate::Type, 499 flags: ParamFlags, 500 ) -> ParamSpec { 501 assert!( 502 is_canonical_pspec_name(name), 503 "{} is not a valid canonical parameter name", 504 name 505 ); 506 unsafe { 507 from_glib_none(gobject_ffi::g_param_spec_object( 508 name.to_glib_none().0, 509 nick.to_glib_none().0, 510 blurb.to_glib_none().0, 511 object_type.into_glib(), 512 flags.into_glib(), 513 )) 514 } 515 } 516 517 #[doc(alias = "g_param_spec_override")] new_override(name: &str, overridden: &ParamSpec) -> ParamSpec518 pub fn new_override(name: &str, overridden: &ParamSpec) -> ParamSpec { 519 assert!( 520 is_canonical_pspec_name(name), 521 "{} is not a valid canonical parameter name", 522 name 523 ); 524 unsafe { 525 from_glib_none(gobject_ffi::g_param_spec_override( 526 name.to_glib_none().0, 527 overridden.to_glib_none().0, 528 )) 529 } 530 } 531 532 #[doc(alias = "g_param_spec_param")] new_param( name: &str, nick: &str, blurb: &str, param_type: crate::Type, flags: ParamFlags, ) -> ParamSpec533 pub fn new_param( 534 name: &str, 535 nick: &str, 536 blurb: &str, 537 param_type: crate::Type, 538 flags: ParamFlags, 539 ) -> ParamSpec { 540 assert!( 541 is_canonical_pspec_name(name), 542 "{} is not a valid canonical parameter name", 543 name 544 ); 545 unsafe { 546 from_glib_none(gobject_ffi::g_param_spec_param( 547 name.to_glib_none().0, 548 nick.to_glib_none().0, 549 blurb.to_glib_none().0, 550 param_type.into_glib(), 551 flags.into_glib(), 552 )) 553 } 554 } 555 556 #[doc(alias = "g_param_spec_pointer")] new_pointer(name: &str, nick: &str, blurb: &str, flags: ParamFlags) -> ParamSpec557 pub fn new_pointer(name: &str, nick: &str, blurb: &str, flags: ParamFlags) -> ParamSpec { 558 assert!( 559 is_canonical_pspec_name(name), 560 "{} is not a valid canonical parameter name", 561 name 562 ); 563 unsafe { 564 from_glib_none(gobject_ffi::g_param_spec_pointer( 565 name.to_glib_none().0, 566 nick.to_glib_none().0, 567 blurb.to_glib_none().0, 568 flags.into_glib(), 569 )) 570 } 571 } 572 573 #[doc(alias = "g_param_spec_string")] new_string( name: &str, nick: &str, blurb: &str, default_value: Option<&str>, flags: ParamFlags, ) -> ParamSpec574 pub fn new_string( 575 name: &str, 576 nick: &str, 577 blurb: &str, 578 default_value: Option<&str>, 579 flags: ParamFlags, 580 ) -> ParamSpec { 581 assert!( 582 is_canonical_pspec_name(name), 583 "{} is not a valid canonical parameter name", 584 name 585 ); 586 let default_value = default_value.to_glib_none(); 587 unsafe { 588 from_glib_none(gobject_ffi::g_param_spec_string( 589 name.to_glib_none().0, 590 nick.to_glib_none().0, 591 blurb.to_glib_none().0, 592 default_value.0, 593 flags.into_glib(), 594 )) 595 } 596 } 597 598 #[doc(alias = "g_param_spec_uchar")] new_uchar( name: &str, nick: &str, blurb: &str, minimum: u8, maximum: u8, default_value: u8, flags: ParamFlags, ) -> ParamSpec599 pub fn new_uchar( 600 name: &str, 601 nick: &str, 602 blurb: &str, 603 minimum: u8, 604 maximum: u8, 605 default_value: u8, 606 flags: ParamFlags, 607 ) -> ParamSpec { 608 assert!( 609 is_canonical_pspec_name(name), 610 "{} is not a valid canonical parameter name", 611 name 612 ); 613 unsafe { 614 from_glib_none(gobject_ffi::g_param_spec_uchar( 615 name.to_glib_none().0, 616 nick.to_glib_none().0, 617 blurb.to_glib_none().0, 618 minimum, 619 maximum, 620 default_value, 621 flags.into_glib(), 622 )) 623 } 624 } 625 626 #[doc(alias = "g_param_spec_uint")] new_uint( name: &str, nick: &str, blurb: &str, minimum: u32, maximum: u32, default_value: u32, flags: ParamFlags, ) -> ParamSpec627 pub fn new_uint( 628 name: &str, 629 nick: &str, 630 blurb: &str, 631 minimum: u32, 632 maximum: u32, 633 default_value: u32, 634 flags: ParamFlags, 635 ) -> ParamSpec { 636 assert!( 637 is_canonical_pspec_name(name), 638 "{} is not a valid canonical parameter name", 639 name 640 ); 641 unsafe { 642 from_glib_none(gobject_ffi::g_param_spec_uint( 643 name.to_glib_none().0, 644 nick.to_glib_none().0, 645 blurb.to_glib_none().0, 646 minimum, 647 maximum, 648 default_value, 649 flags.into_glib(), 650 )) 651 } 652 } 653 654 #[doc(alias = "g_param_spec_uint64")] new_uint64( name: &str, nick: &str, blurb: &str, minimum: u64, maximum: u64, default_value: u64, flags: ParamFlags, ) -> ParamSpec655 pub fn new_uint64( 656 name: &str, 657 nick: &str, 658 blurb: &str, 659 minimum: u64, 660 maximum: u64, 661 default_value: u64, 662 flags: ParamFlags, 663 ) -> ParamSpec { 664 assert!( 665 is_canonical_pspec_name(name), 666 "{} is not a valid canonical parameter name", 667 name 668 ); 669 unsafe { 670 from_glib_none(gobject_ffi::g_param_spec_uint64( 671 name.to_glib_none().0, 672 nick.to_glib_none().0, 673 blurb.to_glib_none().0, 674 minimum, 675 maximum, 676 default_value, 677 flags.into_glib(), 678 )) 679 } 680 } 681 682 #[doc(alias = "g_param_spec_ulong")] new_ulong( name: &str, nick: &str, blurb: &str, minimum: libc::c_ulong, maximum: libc::c_ulong, default_value: libc::c_ulong, flags: ParamFlags, ) -> ParamSpec683 pub fn new_ulong( 684 name: &str, 685 nick: &str, 686 blurb: &str, 687 minimum: libc::c_ulong, 688 maximum: libc::c_ulong, 689 default_value: libc::c_ulong, 690 flags: ParamFlags, 691 ) -> ParamSpec { 692 assert!( 693 is_canonical_pspec_name(name), 694 "{} is not a valid canonical parameter name", 695 name 696 ); 697 unsafe { 698 from_glib_none(gobject_ffi::g_param_spec_ulong( 699 name.to_glib_none().0, 700 nick.to_glib_none().0, 701 blurb.to_glib_none().0, 702 minimum, 703 maximum, 704 default_value, 705 flags.into_glib(), 706 )) 707 } 708 } 709 710 #[doc(alias = "g_param_spec_unichar")] new_unichar( name: &str, nick: &str, blurb: &str, default_value: char, flags: ParamFlags, ) -> ParamSpec711 pub fn new_unichar( 712 name: &str, 713 nick: &str, 714 blurb: &str, 715 default_value: char, 716 flags: ParamFlags, 717 ) -> ParamSpec { 718 assert!( 719 is_canonical_pspec_name(name), 720 "{} is not a valid canonical parameter name", 721 name 722 ); 723 unsafe { 724 from_glib_none(gobject_ffi::g_param_spec_unichar( 725 name.to_glib_none().0, 726 nick.to_glib_none().0, 727 blurb.to_glib_none().0, 728 default_value.into_glib(), 729 flags.into_glib(), 730 )) 731 } 732 } 733 734 #[doc(alias = "g_param_spec_value_array")] new_value_array( name: &str, nick: &str, blurb: &str, element_spec: &ParamSpec, flags: ParamFlags, ) -> ParamSpec735 pub fn new_value_array( 736 name: &str, 737 nick: &str, 738 blurb: &str, 739 element_spec: &ParamSpec, 740 flags: ParamFlags, 741 ) -> ParamSpec { 742 assert!( 743 is_canonical_pspec_name(name), 744 "{} is not a valid canonical parameter name", 745 name 746 ); 747 unsafe { 748 from_glib_none(gobject_ffi::g_param_spec_value_array( 749 name.to_glib_none().0, 750 nick.to_glib_none().0, 751 blurb.to_glib_none().0, 752 element_spec.to_glib_none().0, 753 flags.into_glib(), 754 )) 755 } 756 } 757 758 #[doc(alias = "g_param_spec_variant")] new_variant( name: &str, nick: &str, blurb: &str, type_: &crate::VariantTy, default_value: Option<&crate::Variant>, flags: ParamFlags, ) -> ParamSpec759 pub fn new_variant( 760 name: &str, 761 nick: &str, 762 blurb: &str, 763 type_: &crate::VariantTy, 764 default_value: Option<&crate::Variant>, 765 flags: ParamFlags, 766 ) -> ParamSpec { 767 assert!( 768 is_canonical_pspec_name(name), 769 "{} is not a valid canonical parameter name", 770 name 771 ); 772 unsafe { 773 from_glib_none(gobject_ffi::g_param_spec_variant( 774 name.to_glib_none().0, 775 nick.to_glib_none().0, 776 blurb.to_glib_none().0, 777 type_.to_glib_none().0, 778 default_value.to_glib_none().0, 779 flags.into_glib(), 780 )) 781 } 782 } 783 } 784 785 pub unsafe trait ParamSpecType: 786 StaticType + FromGlibPtrFull<*mut gobject_ffi::GParamSpec> + 'static 787 { 788 } 789 790 #[link(name = "gobject-2.0")] 791 extern "C" { 792 pub static g_param_spec_types: *const ffi::GType; 793 } 794 795 macro_rules! define_param_spec { 796 ($rust_type:ident, $ffi_type:path, $mod_name:ident, $rust_type_offset:expr) => { 797 // Can't use get_type here as this is not a boxed type but another fundamental type 798 wrapper! { 799 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 800 pub struct $rust_type(Shared<$ffi_type>); 801 802 match fn { 803 ref => |ptr| gobject_ffi::g_param_spec_ref_sink(ptr as *mut gobject_ffi::GParamSpec) as *mut $ffi_type, 804 unref => |ptr| gobject_ffi::g_param_spec_unref(ptr as *mut gobject_ffi::GParamSpec), 805 } 806 } 807 808 impl StaticType for $rust_type { 809 fn static_type() -> Type { 810 unsafe { 811 from_glib(*g_param_spec_types.add($rust_type_offset)) 812 } 813 } 814 } 815 816 #[doc(hidden)] 817 impl crate::value::ValueType for $rust_type { 818 type Type = $rust_type; 819 } 820 821 #[doc(hidden)] 822 unsafe impl<'a> crate::value::FromValue<'a> for $rust_type { 823 type Checker = $crate::value::GenericValueTypeOrNoneChecker<Self>; 824 825 unsafe fn from_value(value: &'a crate::Value) -> Self { 826 let ptr = gobject_ffi::g_value_dup_param(value.to_glib_none().0); 827 assert!(!ptr.is_null()); 828 from_glib_full(ptr as *mut $ffi_type) 829 } 830 } 831 832 #[doc(hidden)] 833 impl crate::value::ToValue for $rust_type { 834 fn to_value(&self) -> crate::Value { 835 unsafe { 836 let mut value = crate::Value::from_type($rust_type::static_type()); 837 gobject_ffi::g_value_take_param(value.to_glib_none_mut().0, self.to_glib_full() as *mut _); 838 value 839 } 840 } 841 842 fn value_type(&self) -> crate::Type { 843 $rust_type::static_type() 844 } 845 } 846 847 #[doc(hidden)] 848 impl crate::value::ToValueOptional for $rust_type { 849 fn to_value_optional(s: Option<&Self>) -> crate::Value { 850 let mut value = crate::Value::for_value_type::<Self>(); 851 unsafe { 852 gobject_ffi::g_value_take_param(value.to_glib_none_mut().0, s.to_glib_full() as *mut _); 853 } 854 855 value 856 } 857 } 858 859 unsafe impl Send for $rust_type {} 860 unsafe impl Sync for $rust_type {} 861 862 impl std::ops::Deref for $rust_type { 863 type Target = ParamSpec; 864 865 fn deref(&self) -> &Self::Target { 866 unsafe { 867 &*(self as *const $rust_type as *const ParamSpec) 868 } 869 } 870 } 871 872 unsafe impl ParamSpecType for $rust_type {} 873 874 #[doc(hidden)] 875 impl FromGlibPtrFull<*mut gobject_ffi::GParamSpec> for $rust_type { 876 unsafe fn from_glib_full(ptr: *mut gobject_ffi::GParamSpec) -> Self { 877 from_glib_full(ptr as *mut $ffi_type) 878 } 879 } 880 881 impl $rust_type { 882 pub fn upcast(self) -> ParamSpec { 883 unsafe { 884 from_glib_full(self.to_glib_full() as *mut gobject_ffi::GParamSpec) 885 } 886 } 887 888 pub fn upcast_ref(&self) -> &ParamSpec { 889 &*self 890 } 891 } 892 }; 893 } 894 895 macro_rules! define_param_spec_default { 896 ($rust_type:ident, $value_type:ty, $from_glib:expr) => { 897 impl $rust_type { 898 pub fn default_value(&self) -> $value_type { 899 unsafe { 900 let ptr = self.to_glib_none().0; 901 $from_glib((*ptr).default_value) 902 } 903 } 904 } 905 }; 906 } 907 908 macro_rules! define_param_spec_min_max { 909 ($rust_type:ident, $value_type:ty, $from_glib:expr) => { 910 impl $rust_type { 911 pub fn minimum(&self) -> $value_type { 912 unsafe { 913 let ptr = self.to_glib_none().0; 914 $from_glib((*ptr).minimum) 915 } 916 } 917 918 pub fn maximum(&self) -> $value_type { 919 unsafe { 920 let ptr = self.to_glib_none().0; 921 $from_glib((*ptr).maximum) 922 } 923 } 924 } 925 }; 926 } 927 928 macro_rules! define_param_spec_numeric { 929 ($rust_type:ident, $ffi_type:path, $value_type:ty, $mod_name:ident, $rust_type_offset:expr, $from_glib:expr) => { 930 define_param_spec!($rust_type, $ffi_type, $mod_name, $rust_type_offset); 931 define_param_spec_default!($rust_type, $value_type, $from_glib); 932 define_param_spec_min_max!($rust_type, $value_type, $from_glib); 933 }; 934 } 935 936 define_param_spec_numeric!( 937 ParamSpecChar, 938 gobject_ffi::GParamSpecChar, 939 i8, 940 param_spec_char, 941 0, 942 |x| x 943 ); 944 945 define_param_spec_numeric!( 946 ParamSpecUChar, 947 gobject_ffi::GParamSpecUChar, 948 u8, 949 param_spec_uchar, 950 1, 951 |x| x 952 ); 953 954 define_param_spec!( 955 ParamSpecBoolean, 956 gobject_ffi::GParamSpecBoolean, 957 param_spec_bool, 958 2 959 ); 960 961 define_param_spec_default!(ParamSpecBoolean, bool, |x| from_glib(x)); 962 963 define_param_spec_numeric!( 964 ParamSpecInt, 965 gobject_ffi::GParamSpecInt, 966 i32, 967 param_spec_int, 968 3, 969 |x| x 970 ); 971 972 define_param_spec_numeric!( 973 ParamSpecUInt, 974 gobject_ffi::GParamSpecUInt, 975 u32, 976 param_spec_uint, 977 4, 978 |x| x 979 ); 980 981 define_param_spec_numeric!( 982 ParamSpecLong, 983 gobject_ffi::GParamSpecLong, 984 libc::c_long, 985 param_spec_long, 986 5, 987 |x| x 988 ); 989 990 define_param_spec_numeric!( 991 ParamSpecULong, 992 gobject_ffi::GParamSpecULong, 993 libc::c_ulong, 994 param_spec_ulong, 995 6, 996 |x| x 997 ); 998 999 define_param_spec_numeric!( 1000 ParamSpecInt64, 1001 gobject_ffi::GParamSpecInt64, 1002 i64, 1003 param_spec_int64, 1004 7, 1005 |x| x 1006 ); 1007 1008 define_param_spec_numeric!( 1009 ParamSpecUInt64, 1010 gobject_ffi::GParamSpecUInt64, 1011 u64, 1012 param_spec_uint64, 1013 8, 1014 |x| x 1015 ); 1016 1017 define_param_spec!( 1018 ParamSpecUnichar, 1019 gobject_ffi::GParamSpecUnichar, 1020 param_spec_unichar, 1021 9 1022 ); 1023 1024 define_param_spec_default!(ParamSpecUnichar, Result<char, CharTryFromError>, TryFrom::try_from); 1025 1026 define_param_spec!( 1027 ParamSpecEnum, 1028 gobject_ffi::GParamSpecEnum, 1029 param_spec_enum, 1030 10 1031 ); 1032 1033 define_param_spec_default!(ParamSpecEnum, i32, |x| x); 1034 1035 impl ParamSpecEnum { 1036 #[doc(alias = "get_enum_class")] enum_class(&self) -> crate::EnumClass1037 pub fn enum_class(&self) -> crate::EnumClass { 1038 unsafe { 1039 let ptr = self.to_glib_none().0; 1040 1041 assert!(!(*ptr).enum_class.is_null()); 1042 1043 crate::EnumClass::new(from_glib((*(*ptr).enum_class).g_type_class.g_type)) 1044 .expect("Invalid enum class") 1045 } 1046 } 1047 } 1048 1049 define_param_spec!( 1050 ParamSpecFlags, 1051 gobject_ffi::GParamSpecFlags, 1052 param_spec_flags, 1053 11 1054 ); 1055 1056 define_param_spec_default!(ParamSpecFlags, u32, |x| x); 1057 1058 impl ParamSpecFlags { 1059 #[doc(alias = "get_flags_class")] flags_class(&self) -> crate::FlagsClass1060 pub fn flags_class(&self) -> crate::FlagsClass { 1061 unsafe { 1062 let ptr = self.to_glib_none().0; 1063 1064 assert!(!(*ptr).flags_class.is_null()); 1065 1066 crate::FlagsClass::new(from_glib((*(*ptr).flags_class).g_type_class.g_type)) 1067 .expect("Invalid flags class") 1068 } 1069 } 1070 } 1071 1072 define_param_spec_numeric!( 1073 ParamSpecFloat, 1074 gobject_ffi::GParamSpecFloat, 1075 f32, 1076 param_spec_float, 1077 12, 1078 |x| x 1079 ); 1080 1081 define_param_spec_numeric!( 1082 ParamSpecDouble, 1083 gobject_ffi::GParamSpecDouble, 1084 f64, 1085 param_spec_double, 1086 13, 1087 |x| x 1088 ); 1089 1090 define_param_spec!( 1091 ParamSpecString, 1092 gobject_ffi::GParamSpecString, 1093 param_spec_string, 1094 14 1095 ); 1096 1097 define_param_spec_default!(ParamSpecString, Option<&str>, |x: *mut libc::c_char| { 1098 use std::ffi::CStr; 1099 1100 if x.is_null() { 1101 None 1102 } else { 1103 Some(CStr::from_ptr(x).to_str().unwrap()) 1104 } 1105 }); 1106 1107 define_param_spec!( 1108 ParamSpecParam, 1109 gobject_ffi::GParamSpecParam, 1110 param_spec_param, 1111 15 1112 ); 1113 1114 define_param_spec!( 1115 ParamSpecBoxed, 1116 gobject_ffi::GParamSpecBoxed, 1117 param_spec_boxed, 1118 16 1119 ); 1120 1121 define_param_spec!( 1122 ParamSpecPointer, 1123 gobject_ffi::GParamSpecPointer, 1124 param_spec_pointer, 1125 17 1126 ); 1127 1128 define_param_spec!( 1129 ParamSpecValueArray, 1130 gobject_ffi::GParamSpecValueArray, 1131 param_spec_value_array, 1132 18 1133 ); 1134 1135 impl ParamSpecValueArray { 1136 #[doc(alias = "get_element_spec")] element_spec(&self) -> Option<ParamSpec>1137 pub fn element_spec(&self) -> Option<ParamSpec> { 1138 unsafe { 1139 let ptr = self.to_glib_none().0; 1140 1141 from_glib_none((*ptr).element_spec) 1142 } 1143 } 1144 1145 #[doc(alias = "get_fixed_n_elements")] fixed_n_elements(&self) -> u321146 pub fn fixed_n_elements(&self) -> u32 { 1147 unsafe { 1148 let ptr = self.to_glib_none().0; 1149 1150 (*ptr).fixed_n_elements 1151 } 1152 } 1153 } 1154 1155 define_param_spec!( 1156 ParamSpecObject, 1157 gobject_ffi::GParamSpecObject, 1158 param_spec_object, 1159 19 1160 ); 1161 1162 define_param_spec!( 1163 ParamSpecOverride, 1164 gobject_ffi::GParamSpecOverride, 1165 param_spec_override, 1166 20 1167 ); 1168 1169 impl ParamSpecOverride { 1170 #[doc(alias = "get_overridden")] overridden(&self) -> ParamSpec1171 pub fn overridden(&self) -> ParamSpec { 1172 unsafe { 1173 let ptr = self.to_glib_none().0; 1174 1175 from_glib_none((*ptr).overridden) 1176 } 1177 } 1178 } 1179 1180 define_param_spec!( 1181 ParamSpecGType, 1182 gobject_ffi::GParamSpecGType, 1183 param_spec_gtype, 1184 21 1185 ); 1186 1187 define_param_spec!( 1188 ParamSpecVariant, 1189 gobject_ffi::GParamSpecVariant, 1190 param_spec_variant, 1191 22 1192 ); 1193 1194 define_param_spec_default!( 1195 ParamSpecVariant, 1196 Option<crate::Variant>, 1197 |x: *mut ffi::GVariant| from_glib_none(x) 1198 ); 1199 1200 impl ParamSpecVariant { 1201 #[doc(alias = "get_type")] type_(&self) -> Option<&crate::VariantTy>1202 pub fn type_(&self) -> Option<&crate::VariantTy> { 1203 unsafe { 1204 let ptr = self.to_glib_none().0; 1205 1206 if (*ptr).type_.is_null() { 1207 None 1208 } else { 1209 Some(crate::VariantTy::from_ptr((*ptr).type_)) 1210 } 1211 } 1212 } 1213 } 1214 1215 #[cfg(test)] 1216 mod tests { 1217 use super::*; 1218 1219 #[test] test_param_spec_string()1220 fn test_param_spec_string() { 1221 let pspec = ParamSpec::new_string( 1222 "name", 1223 "nick", 1224 "blurb", 1225 Some("default"), 1226 ParamFlags::READWRITE, 1227 ); 1228 1229 assert_eq!(pspec.name(), "name"); 1230 assert_eq!(pspec.nick(), "nick"); 1231 assert_eq!(pspec.blurb(), "blurb"); 1232 let default_value = pspec.default_value(); 1233 assert_eq!(default_value.get::<&str>().unwrap(), "default"); 1234 assert_eq!(pspec.flags(), ParamFlags::READWRITE); 1235 assert_eq!(pspec.value_type(), Type::STRING); 1236 assert_eq!(pspec.type_(), ParamSpecString::static_type()); 1237 1238 let pspec_ref = pspec 1239 .downcast_ref::<ParamSpecString>() 1240 .expect("Not a string param spec"); 1241 assert_eq!(pspec_ref.default_value(), Some("default")); 1242 1243 let pspec = pspec 1244 .downcast::<ParamSpecString>() 1245 .expect("Not a string param spec"); 1246 assert_eq!(pspec.default_value(), Some("default")); 1247 } 1248 } 1249