1use crate::enums::{Color, Font, FrameType, Key};
2use crate::image::Image;
3use crate::prelude::*;
4use crate::utils::FlString;
5use crate::widget::Widget;
6use fltk_sys::tree::*;
7use std::{
8 ffi::{CStr, CString},
9 mem,
10 os::raw,
11};
12
13#[repr(i32)]
15#[derive(Debug, Copy, Clone, PartialEq, Eq)]
16pub enum TreeSort {
17 None = 0,
19 Ascending = 1,
21 Descending = 2,
23}
24
25#[repr(i32)]
27#[derive(Debug, Copy, Clone, PartialEq, Eq)]
28pub enum TreeConnectorStyle {
29 None = 0,
31 Dotted = 1,
33 Solid = 2,
35}
36
37#[repr(i32)]
39#[derive(Debug, Copy, Clone, PartialEq, Eq)]
40pub enum TreeSelect {
41 None = 0,
43 Single = 1,
45 Multi = 2,
47 SingleDraggable = 3,
49}
50
51#[repr(i32)]
53#[derive(Debug, Copy, Clone, PartialEq, Eq)]
54pub enum TreeItemSelect {
55 Deselect = 0,
57 Select = 1,
59 Toggle = 2,
61}
62
63#[repr(i32)]
65#[derive(Debug, Copy, Clone, PartialEq, Eq)]
66pub enum TreeReason {
67 None = 0,
69 Selected,
71 Deselected,
73 Reselected,
75 Opened,
77 Closed,
79 Dragged,
81}
82
83#[repr(i32)]
85#[derive(Debug, Copy, Clone, PartialEq, Eq)]
86pub enum TreeItemReselectMode {
87 Once = 0,
89 Always,
91}
92
93#[repr(i32)]
95#[derive(Debug, Copy, Clone, PartialEq, Eq)]
96pub enum TreeItemDrawMode {
97 Default = 0,
99 LabelAndWidget = 1,
101 HeightFromWidget = 2,
103}
104
105#[derive(Debug)]
107pub struct Tree {
108 inner: crate::widget::WidgetTracker,
109 is_derived: bool,
110}
111
112crate::macros::widget::impl_widget_ext!(Tree, Fl_Tree);
113crate::macros::widget::impl_widget_base!(Tree, Fl_Tree);
114crate::macros::widget::impl_widget_default!(Tree, Fl_Tree);
115
116#[derive(Debug, Clone)]
118pub struct TreeItem {
119 inner: *mut Fl_Tree_Item,
120 parent: *const Fl_Tree_Item,
121 tree: Tree,
122 is_root: bool,
123 is_derived: bool,
124}
125
126#[derive(Debug)]
128struct TreeItemArray {
129 inner: *mut Fl_Tree_Item_Array,
130}
131
132impl Tree {
133 pub unsafe fn from_raw(ptr: *mut Fl_Tree) -> Option<Tree> {
137 if ptr.is_null() {
138 None
139 } else {
140 let inner = crate::widget::WidgetTracker::new(ptr as _);
141 let x = Tree {
142 inner,
143 is_derived: false,
144 };
145 Some(x)
146 }
147 }
148
149 pub fn begin(&self) {
151 unsafe { Fl_Tree_begin(self.inner.widget() as _) }
152 }
153
154 pub fn end(&self) {
156 unsafe { Fl_Tree_end(self.inner.widget() as _) }
157 }
158
159 pub fn show_self(&mut self) {
161 unsafe { Fl_Tree_show_self(self.inner.widget() as _) }
162 }
163
164 pub fn set_root_label(&mut self, new_label: &str) {
166 let new_label = CString::safe_new(new_label);
167 unsafe { Fl_Tree_root_label(self.inner.widget() as _, new_label.as_ptr()) }
168 }
169
170 pub fn root(&self) -> Option<TreeItem> {
172 unsafe { TreeItem::from_raw(Fl_Tree_root(self.inner.widget() as _)) }
173 }
174
175 pub fn set_root(&mut self, new_item: Option<TreeItem>) {
177 let ptr = match new_item {
178 None => std::ptr::null_mut(),
179 Some(item) => item.inner,
180 };
181 unsafe { Fl_Tree_set_root(self.inner.widget() as _, ptr) }
182 }
183
184 pub fn add(&mut self, path: &str) -> Option<TreeItem> {
186 let path = CString::safe_new(path);
187 unsafe {
188 let x = Fl_Tree_add(self.inner.widget() as _, path.as_ptr() as *mut raw::c_char);
189 TreeItem::from_raw(x)
190 }
191 }
192
193 pub fn add_item(&mut self, path: &str, item: &TreeItem) -> Option<TreeItem> {
195 let path = CString::safe_new(path);
196 unsafe {
197 let x = Fl_Tree_add_item(
198 self.inner.widget() as _,
199 path.as_ptr() as *mut raw::c_char,
200 item.inner,
201 );
202 TreeItem::from_raw(x)
203 }
204 }
205
206 pub fn insert_above(&mut self, above: &TreeItem, name: &str) -> Option<TreeItem> {
208 if above.inner.is_null() {
209 return None;
210 }
211 let name = CString::safe_new(name);
212 unsafe {
213 let x = Fl_Tree_insert_above(
214 self.inner.widget() as _,
215 above.inner,
216 name.as_ptr() as *mut raw::c_char,
217 );
218 TreeItem::from_raw(x)
219 }
220 }
221
222 pub fn insert(&mut self, item: &TreeItem, name: &str, pos: i32) -> Option<TreeItem> {
224 if item.inner.is_null() {
225 return None;
226 }
227 let name = CString::safe_new(name);
228 unsafe {
229 let x = Fl_Tree_insert(
230 self.inner.widget() as _,
231 item.inner,
232 name.as_ptr() as *mut raw::c_char,
233 pos,
234 );
235 TreeItem::from_raw(x)
236 }
237 }
238
239 pub fn remove(&mut self, item: &TreeItem) -> Result<(), FltkError> {
243 if item.inner.is_null() {
244 return Err(FltkError::Internal(FltkErrorKind::FailedOperation));
245 }
246 unsafe {
247 match Fl_Tree_remove(self.inner.widget() as _, item.inner) {
248 0 => Ok(()),
249 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
250 }
251 }
252 }
253
254 pub fn clear(&mut self) {
256 unsafe { Fl_Tree_clear(self.inner.widget() as _) }
257 }
258
259 pub fn clear_children(&mut self, item: &TreeItem) {
261 assert!(!item.inner.is_null());
262 unsafe { Fl_Tree_clear_children(self.inner.widget() as *mut Fl_Tree, item.inner) }
263 }
264
265 pub fn find_item(&self, path: &str) -> Option<TreeItem> {
267 let path = CString::safe_new(path);
268 unsafe {
269 let x = Fl_Tree_find_item(self.inner.widget() as _, path.as_ptr() as *mut raw::c_char);
270 if x.is_null() {
271 None
272 } else {
273 TreeItem::from_raw(x as *mut Fl_Tree_Item)
274 }
275 }
276 }
277
278 pub fn find_clicked(&self, yonly: bool) -> Option<TreeItem> {
280 unsafe {
281 TreeItem::from_raw(
282 Fl_Tree_find_clicked(self.inner.widget() as _, i32::from(yonly))
283 as *mut Fl_Tree_Item,
284 )
285 }
286 }
287
288 pub fn first(&self) -> Option<TreeItem> {
290 unsafe { TreeItem::from_raw(Fl_Tree_first(self.inner.widget() as _)) }
291 }
292
293 pub fn first_visible_item(&self) -> Option<TreeItem> {
295 unsafe { TreeItem::from_raw(Fl_Tree_first_visible_item(self.inner.widget() as _)) }
296 }
297
298 pub fn next(&self, item: &TreeItem) -> Option<TreeItem> {
300 if item.inner.is_null() {
301 return None;
302 }
303 unsafe { TreeItem::from_raw(Fl_Tree_next(self.inner.widget() as _, item.inner)) }
304 }
305
306 pub fn prev(&self, item: &TreeItem) -> Option<TreeItem> {
308 if item.inner.is_null() {
309 return None;
310 }
311 unsafe { TreeItem::from_raw(Fl_Tree_prev(self.inner.widget() as _, item.inner)) }
312 }
313
314 pub fn last(&self) -> Option<TreeItem> {
316 unsafe { TreeItem::from_raw(Fl_Tree_last(self.inner.widget() as _)) }
317 }
318
319 pub fn last_visible_item(&self) -> Option<TreeItem> {
321 unsafe { TreeItem::from_raw(Fl_Tree_last_visible_item(self.inner.widget() as _)) }
322 }
323
324 pub fn next_visible_item(&self, start: &TreeItem, direction_key: Key) -> Option<TreeItem> {
326 if start.inner.is_null() {
327 return None;
328 }
329 unsafe {
330 TreeItem::from_raw(Fl_Tree_next_visible_item(
331 self.inner.widget() as _,
332 start.inner,
333 direction_key.bits(),
334 ))
335 }
336 }
337
338 pub fn first_selected_item(&self) -> Option<TreeItem> {
340 unsafe { TreeItem::from_raw(Fl_Tree_first_selected_item(self.inner.widget() as _)) }
341 }
342
343 pub fn last_selected_item(&self) -> Option<TreeItem> {
345 unsafe { TreeItem::from_raw(Fl_Tree_last_selected_item(self.inner.widget() as _)) }
346 }
347
348 pub fn next_item(
350 &self,
351 item: &TreeItem,
352 direction_key: Key,
353 visible: bool,
354 ) -> Option<TreeItem> {
355 if item.inner.is_null() {
356 return None;
357 }
358 unsafe {
359 TreeItem::from_raw(Fl_Tree_next_item(
360 self.inner.widget() as _,
361 item.inner,
362 direction_key.bits(),
363 i32::from(visible),
364 ))
365 }
366 }
367
368 pub fn next_selected_item(&mut self, item: &TreeItem, direction_key: Key) -> Option<TreeItem> {
370 if item.inner.is_null() {
371 return None;
372 }
373 unsafe {
374 TreeItem::from_raw(Fl_Tree_next_selected_item(
375 self.inner.widget() as _,
376 item.inner,
377 direction_key.bits(),
378 ))
379 }
380 }
381
382 pub fn get_selected_items(&self) -> Option<Vec<TreeItem>> {
384 unsafe {
385 let mut items = TreeItemArray {
386 inner: std::ptr::null_mut(),
387 };
388 let ret = Fl_Tree_get_selected_items(self.inner.widget() as _, &mut items.inner);
389 if ret == 0 { None } else { items.into_vec() }
390 }
391 }
392
393 pub fn get_items(&self) -> Option<Vec<TreeItem>> {
395 unsafe {
396 let mut items = TreeItemArray {
397 inner: std::ptr::null_mut(),
398 };
399 let ret = Fl_Tree_get_items(self.inner.widget() as _, &mut items.inner);
400 if ret == 0 { None } else { items.into_vec() }
401 }
402 }
403
404 pub fn open(&mut self, path: &str, do_callback: bool) -> Result<(), FltkError> {
408 let path = CString::safe_new(path);
409 unsafe {
410 match Fl_Tree_open(
411 self.inner.widget() as _,
412 path.as_ptr() as *mut raw::c_char,
413 i32::from(do_callback),
414 ) {
415 0 | 1 => Ok(()),
416 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
417 }
418 }
419 }
420
421 pub fn open_toggle(&mut self, item: &TreeItem, do_callback: bool) {
423 assert!(!item.inner.is_null());
424 unsafe { Fl_Tree_open_toggle(self.inner.widget() as _, item.inner, i32::from(do_callback)) }
425 }
426
427 pub fn close(&mut self, path: &str, do_callback: bool) -> Result<(), FltkError> {
431 let path = CString::safe_new(path);
432 unsafe {
433 match Fl_Tree_close(
434 self.inner.widget() as _,
435 path.as_ptr() as *mut raw::c_char,
436 i32::from(do_callback),
437 ) {
438 -1 => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
439 _ => Ok(()),
440 }
441 }
442 }
443
444 pub fn is_open(&self, path: &str) -> bool {
446 let path = CString::safe_new(path);
447 unsafe { Fl_Tree_is_open(self.inner.widget() as _, path.as_ptr() as *mut raw::c_char) != 0 }
448 }
449
450 pub fn is_close(&self, path: &str) -> bool {
452 let path = CString::safe_new(path);
453 unsafe {
454 Fl_Tree_is_close(self.inner.widget() as _, path.as_ptr() as *mut raw::c_char) != 0
455 }
456 }
457
458 pub fn select(&mut self, path: &str, do_callback: bool) -> Result<(), FltkError> {
462 let path = CString::safe_new(path);
463 unsafe {
464 match Fl_Tree_select(
465 self.inner.widget() as _,
466 path.as_ptr() as *mut raw::c_char,
467 i32::from(do_callback),
468 ) {
469 0 => Ok(()),
470 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
471 }
472 }
473 }
474
475 pub fn select_toggle(&mut self, item: &TreeItem, do_callback: bool) {
477 assert!(!item.inner.is_null());
478 unsafe {
479 Fl_Tree_select_toggle(self.inner.widget() as _, item.inner, i32::from(do_callback));
480 }
481 }
482
483 pub fn deselect(&mut self, path: &str, do_callback: bool) -> Result<(), FltkError> {
487 let path = CString::safe_new(path);
488 unsafe {
489 match Fl_Tree_deselect(
490 self.inner.widget() as _,
491 path.as_ptr() as *mut raw::c_char,
492 i32::from(do_callback),
493 ) {
494 0 => Ok(()),
495 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
496 }
497 }
498 }
499
500 pub fn deselect_all(&mut self, item: &TreeItem, do_callback: bool) -> Result<(), FltkError> {
504 if item.inner.is_null() {
505 return Err(FltkError::Internal(FltkErrorKind::FailedOperation));
506 }
507 unsafe {
508 match Fl_Tree_deselect_all(self.inner.widget() as _, item.inner, i32::from(do_callback))
509 {
510 0 => Ok(()),
511 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
512 }
513 }
514 }
515
516 pub fn select_only(
520 &mut self,
521 selected_item: &TreeItem,
522 do_callback: bool,
523 ) -> Result<(), FltkError> {
524 if selected_item.inner.is_null() {
525 return Err(FltkError::Internal(FltkErrorKind::FailedOperation));
526 }
527 unsafe {
528 match Fl_Tree_select_only(
529 self.inner.widget() as _,
530 selected_item.inner,
531 i32::from(do_callback),
532 ) {
533 0 => Ok(()),
534 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
535 }
536 }
537 }
538
539 pub fn select_all(&mut self, item: &TreeItem, do_callback: bool) -> Result<(), FltkError> {
543 if item.inner.is_null() {
544 return Err(FltkError::Internal(FltkErrorKind::FailedOperation));
545 }
546 unsafe {
547 match Fl_Tree_select_all(self.inner.widget() as _, item.inner, i32::from(do_callback)) {
548 0 => Ok(()),
549 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
550 }
551 }
552 }
553
554 pub fn extend_selection_dir(
558 &mut self,
559 from: &TreeItem,
560 to: &TreeItem,
561 direction_key: Key,
562 val: TreeItemSelect,
563 visible: bool,
564 ) -> Result<(), FltkError> {
565 if from.inner.is_null() || to.inner.is_null() {
566 return Err(FltkError::Internal(FltkErrorKind::FailedOperation));
567 }
568 unsafe {
569 match Fl_Tree_extend_selection_dir(
570 self.inner.widget() as _,
571 from.inner,
572 to.inner,
573 direction_key.bits(),
574 val as i32,
575 i32::from(visible),
576 ) {
577 0 => Ok(()),
578 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
579 }
580 }
581 }
582
583 pub fn extend_selection(
587 &mut self,
588 from: &TreeItem,
589 to: &TreeItem,
590 val: TreeItemSelect,
591 visible: bool,
592 ) -> Result<(), FltkError> {
593 if from.inner.is_null() || to.inner.is_null() {
594 return Err(FltkError::Internal(FltkErrorKind::FailedOperation));
595 }
596 unsafe {
597 match Fl_Tree_extend_selection(
598 self.inner.widget() as _,
599 from.inner,
600 to.inner,
601 val as i32,
602 i32::from(visible),
603 ) {
604 0 => Ok(()),
605 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
606 }
607 }
608 }
609
610 pub fn set_item_focus(&mut self, item: &TreeItem) {
612 assert!(!item.inner.is_null());
613 unsafe { Fl_Tree_set_item_focus(self.inner.widget() as _, item.inner) }
614 }
615
616 pub fn get_item_focus(&self) -> Option<TreeItem> {
618 unsafe { TreeItem::from_raw(Fl_Tree_get_item_focus(self.inner.widget() as _)) }
619 }
620
621 pub fn is_selected(&self, path: &str) -> bool {
623 let path = CString::safe_new(path);
624 unsafe {
625 Fl_Tree_is_selected(self.inner.widget() as _, path.as_ptr() as *mut raw::c_char) != 0
626 }
627 }
628
629 pub fn item_label_font(&self) -> Font {
631 unsafe { mem::transmute(Fl_Tree_item_labelfont(self.inner.widget() as _)) }
632 }
633
634 pub fn set_item_label_font(&mut self, val: Font) {
636 unsafe { Fl_Tree_set_item_labelfont(self.inner.widget() as _, val.bits()) }
637 }
638
639 pub fn item_label_size(&self) -> i32 {
641 unsafe { Fl_Tree_item_labelsize(self.inner.widget() as _) }
642 }
643
644 pub fn set_item_label_size(&mut self, val: i32) {
646 let val = if val < 1 { 1 } else { val };
647 unsafe { Fl_Tree_set_item_labelsize(self.inner.widget() as _, val) }
648 }
649
650 pub fn item_label_fgcolor(&self) -> Color {
652 unsafe { mem::transmute(Fl_Tree_item_labelfgcolor(self.inner.widget() as _)) }
653 }
654
655 pub fn set_item_label_fgcolor(&mut self, val: Color) {
657 unsafe { Fl_Tree_set_item_labelfgcolor(self.inner.widget() as _, val.bits()) }
658 }
659
660 pub fn item_label_bgcolor(&self) -> Color {
662 unsafe { mem::transmute(Fl_Tree_item_labelbgcolor(self.inner.widget() as _)) }
663 }
664
665 pub fn set_item_label_bgcolor(&mut self, val: Color) {
667 unsafe { Fl_Tree_set_item_labelbgcolor(self.inner.widget() as _, val.bits()) }
668 }
669
670 pub fn connector_color(&self) -> Color {
672 unsafe { mem::transmute(Fl_Tree_connectorcolor(self.inner.widget() as _)) }
673 }
674
675 pub fn set_connector_color(&mut self, val: Color) {
677 unsafe { Fl_Tree_set_connectorcolor(self.inner.widget() as _, val.bits()) }
678 }
679
680 pub fn margin_left(&self) -> i32 {
682 unsafe { Fl_Tree_marginleft(self.inner.widget() as _) }
683 }
684
685 pub fn set_margin_left(&mut self, val: i32) {
687 unsafe { Fl_Tree_set_marginleft(self.inner.widget() as _, val) }
688 }
689
690 pub fn margin_top(&self) -> i32 {
692 unsafe { Fl_Tree_margintop(self.inner.widget() as _) }
693 }
694
695 pub fn set_margin_top(&mut self, val: i32) {
697 unsafe { Fl_Tree_set_margintop(self.inner.widget() as _, val) }
698 }
699
700 pub fn margin_bottom(&self) -> i32 {
702 unsafe { Fl_Tree_marginbottom(self.inner.widget() as _) }
703 }
704
705 pub fn set_margin_bottom(&mut self, val: i32) {
707 unsafe { Fl_Tree_set_marginbottom(self.inner.widget() as _, val) }
708 }
709
710 pub fn line_spacing(&self) -> i32 {
712 unsafe { Fl_Tree_linespacing(self.inner.widget() as _) }
713 }
714
715 pub fn set_line_spacing(&mut self, val: i32) {
717 unsafe { Fl_Tree_set_linespacing(self.inner.widget() as _, val) }
718 }
719
720 pub fn open_child_margin_bottom(&self) -> i32 {
722 unsafe { Fl_Tree_openchild_marginbottom(self.inner.widget() as _) }
723 }
724
725 pub fn set_open_child_margin_bottom(&mut self, val: i32) {
727 unsafe { Fl_Tree_set_openchild_marginbottom(self.inner.widget() as _, val) }
728 }
729
730 pub fn user_icon_margin_left(&self) -> i32 {
732 unsafe { Fl_Tree_usericonmarginleft(self.inner.widget() as _) }
733 }
734
735 pub fn set_user_icon_margin_left(&mut self, val: i32) {
737 unsafe { Fl_Tree_set_usericonmarginleft(self.inner.widget() as _, val) }
738 }
739
740 pub fn label_margin_left(&self) -> i32 {
742 unsafe { Fl_Tree_labelmarginleft(self.inner.widget() as _) }
743 }
744
745 pub fn set_label_margin_left(&mut self, val: i32) {
747 unsafe { Fl_Tree_set_labelmarginleft(self.inner.widget() as _, val) }
748 }
749
750 pub fn widget_margin_left(&self) -> i32 {
752 unsafe { Fl_Tree_widgetmarginleft(self.inner.widget() as _) }
753 }
754
755 pub fn set_widget_margin_left(&mut self, val: i32) {
757 unsafe { Fl_Tree_set_widgetmarginleft(self.inner.widget() as _, val) }
758 }
759
760 pub fn connector_width(&self) -> i32 {
762 unsafe { Fl_Tree_connectorwidth(self.inner.widget() as _) }
763 }
764
765 pub fn set_connector_width(&mut self, val: i32) {
767 unsafe { Fl_Tree_set_connectorwidth(self.inner.widget() as _, val) }
768 }
769
770 pub fn user_icon(&self) -> Option<Box<dyn ImageExt>> {
772 unsafe {
773 let image_ptr = Fl_Tree_usericon(self.inner.widget() as _);
774 if image_ptr.is_null() {
775 None
776 } else {
777 Some(Box::new(Image::from_image_ptr(
778 image_ptr as *mut fltk_sys::image::Fl_Image,
779 )))
780 }
781 }
782 }
783
784 pub fn set_user_icon<Img: ImageExt>(&mut self, image: Option<Img>) {
786 if let Some(image) = image {
787 assert!(!image.was_deleted());
788 unsafe {
789 Fl_Tree_set_usericon(self.inner.widget() as _, image.as_image_ptr() as *mut _);
790 }
791 } else {
792 unsafe {
793 Fl_Tree_set_usericon(
794 self.inner.widget() as _,
795 std::ptr::null_mut::<raw::c_void>(),
796 );
797 }
798 }
799 }
800
801 pub fn open_icon(&self) -> Option<Box<dyn ImageExt>> {
803 unsafe {
804 let image_ptr = Fl_Tree_openicon(self.inner.widget() as _);
805 if image_ptr.is_null() {
806 None
807 } else {
808 Some(Box::new(Image::from_image_ptr(
809 image_ptr as *mut fltk_sys::image::Fl_Image,
810 )))
811 }
812 }
813 }
814
815 pub fn set_open_icon<Img: ImageExt>(&mut self, image: Option<Img>) {
817 if let Some(image) = image {
818 assert!(!image.was_deleted());
819 unsafe {
820 Fl_Tree_set_openicon(self.inner.widget() as _, image.as_image_ptr() as *mut _);
821 }
822 } else {
823 unsafe {
824 Fl_Tree_set_openicon(
825 self.inner.widget() as _,
826 std::ptr::null_mut::<raw::c_void>(),
827 );
828 }
829 }
830 }
831
832 pub fn close_icon(&self) -> Option<Box<dyn ImageExt>> {
834 unsafe {
835 let image_ptr = Fl_Tree_closeicon(self.inner.widget() as _);
836 if image_ptr.is_null() {
837 None
838 } else {
839 Some(Box::new(Image::from_image_ptr(
840 image_ptr as *mut fltk_sys::image::Fl_Image,
841 )))
842 }
843 }
844 }
845
846 pub fn set_close_icon<Img: ImageExt>(&mut self, image: Option<Img>) {
848 if let Some(image) = image {
849 assert!(!image.was_deleted());
850 unsafe {
851 Fl_Tree_set_closeicon(self.inner.widget() as _, image.as_image_ptr() as *mut _);
852 }
853 } else {
854 unsafe {
855 Fl_Tree_set_closeicon(
856 self.inner.widget() as _,
857 std::ptr::null_mut::<raw::c_void>(),
858 );
859 }
860 }
861 }
862
863 pub fn show_collapse(&self) -> bool {
865 unsafe { Fl_Tree_showcollapse(self.inner.widget() as _) != 0 }
866 }
867
868 pub fn set_show_collapse(&mut self, flag: bool) {
870 unsafe { Fl_Tree_set_showcollapse(self.inner.widget() as _, i32::from(flag)) }
871 }
872
873 pub fn show_root(&self) -> bool {
875 unsafe { Fl_Tree_showroot(self.inner.widget() as _) != 0 }
876 }
877
878 pub fn set_show_root(&mut self, flag: bool) {
880 unsafe { Fl_Tree_set_showroot(self.inner.widget() as _, i32::from(flag)) }
881 }
882
883 pub fn connector_style(&self) -> TreeConnectorStyle {
885 unsafe { mem::transmute(Fl_Tree_connectorstyle(self.inner.widget() as _)) }
886 }
887
888 pub fn set_connector_style(&mut self, val: TreeConnectorStyle) {
890 unsafe { Fl_Tree_set_connectorstyle(self.inner.widget() as _, val as i32) }
891 }
892
893 pub fn sort_order(&self) -> TreeSort {
895 unsafe { mem::transmute(Fl_Tree_sortorder(self.inner.widget() as _)) }
896 }
897
898 pub fn set_sort_order(&mut self, val: TreeSort) {
900 unsafe { Fl_Tree_set_sortorder(self.inner.widget() as _, val as i32) }
901 }
902
903 pub fn select_frame(&self) -> FrameType {
905 unsafe { FrameType::from_i32(Fl_Tree_selectbox(self.inner.widget() as _)) }
906 }
907
908 pub fn set_select_frame(&mut self, val: FrameType) {
910 unsafe { Fl_Tree_set_selectbox(self.inner.widget() as _, val.as_i32()) }
911 }
912
913 pub fn select_mode(&self) -> TreeSelect {
915 unsafe { mem::transmute(Fl_Tree_selectmode(self.inner.widget() as _)) }
916 }
917
918 pub fn set_select_mode(&mut self, val: TreeSelect) {
920 unsafe { Fl_Tree_set_selectmode(self.inner.widget() as _, val as i32) }
921 }
922
923 pub fn item_reselect_mode(&self) -> TreeItemReselectMode {
925 unsafe { mem::transmute(Fl_Tree_item_reselect_mode(self.inner.widget() as _)) }
926 }
927
928 pub fn set_item_reselect_mode(&mut self, mode: TreeItemReselectMode) {
930 unsafe { Fl_Tree_set_item_reselect_mode(self.inner.widget() as _, mode as i32) }
931 }
932
933 pub fn item_draw_mode(&self) -> TreeItemDrawMode {
935 unsafe { mem::transmute(Fl_Tree_item_draw_mode(self.inner.widget() as _)) }
936 }
937
938 pub fn set_item_draw_mode(&mut self, mode: TreeItemDrawMode) {
940 unsafe { Fl_Tree_set_item_draw_mode(self.inner.widget() as _, mode as i32) }
941 }
942
943 pub fn calc_dimensions(&mut self) {
945 unsafe { Fl_Tree_calc_dimensions(self.inner.widget() as _) }
946 }
947
948 pub fn calc_tree(&mut self) {
950 unsafe { Fl_Tree_calc_tree(self.inner.widget() as _) }
951 }
952
953 pub fn recalc_tree(&mut self) {
955 unsafe { Fl_Tree_recalc_tree(self.inner.widget() as _) }
956 }
957
958 pub fn displayed(&mut self, item: &TreeItem) -> bool {
960 assert!(!item.inner.is_null());
961 unsafe { Fl_Tree_displayed(self.inner.widget() as _, item.inner) != 0 }
962 }
963
964 pub fn show_item(&mut self, item: &TreeItem, y_offset: i32) {
966 assert!(!item.inner.is_null());
967 unsafe { Fl_Tree_show_item(self.inner.widget() as _, item.inner, y_offset) }
968 }
969
970 pub fn show_item_top(&mut self, item: &TreeItem) {
972 assert!(!item.inner.is_null());
973 unsafe { Fl_Tree_show_item_top(self.inner.widget() as _, item.inner) }
974 }
975
976 pub fn show_item_middle(&mut self, item: &TreeItem) {
978 assert!(!item.inner.is_null());
979 unsafe { Fl_Tree_show_item_middle(self.inner.widget() as _, item.inner) }
980 }
981
982 pub fn show_item_bottom(&mut self, item: &TreeItem) {
984 assert!(!item.inner.is_null());
985 unsafe { Fl_Tree_show_item_bottom(self.inner.widget() as _, item.inner) }
986 }
987
988 pub fn display(&mut self, item: &TreeItem) {
990 assert!(!item.inner.is_null());
991 unsafe { Fl_Tree_display(self.inner.widget() as _, item.inner) }
992 }
993
994 pub fn vposition(&self) -> i32 {
996 unsafe { Fl_Tree_vposition(self.inner.widget() as _) }
997 }
998
999 pub fn set_vposition(&mut self, pos: i32) {
1001 unsafe { Fl_Tree_set_vposition(self.inner.widget() as _, pos) }
1002 }
1003
1004 pub fn hposition(&self) -> i32 {
1006 unsafe { Fl_Tree_hposition(self.inner.widget() as _) }
1007 }
1008
1009 pub fn set_hposition(&mut self, pos: i32) {
1011 unsafe { Fl_Tree_set_hposition(self.inner.widget() as _, pos) }
1012 }
1013
1014 pub fn is_scrollbar<W: WidgetExt>(&mut self, w: &W) -> bool {
1016 unsafe {
1017 Fl_Tree_is_scrollbar(
1018 self.inner.widget() as _,
1019 w.as_widget_ptr() as *mut Fl_Widget,
1020 ) != 0
1021 }
1022 }
1023
1024 pub fn scrollbar_size(&self) -> i32 {
1026 unsafe { Fl_Tree_scrollbar_size(self.inner.widget() as _) }
1027 }
1028
1029 pub fn set_scrollbar_size(&mut self, sz: i32) {
1031 unsafe { Fl_Tree_set_scrollbar_size(self.inner.widget() as _, sz) }
1032 }
1033
1034 pub fn is_vscroll_visible(&self) -> bool {
1036 unsafe { Fl_Tree_is_vscroll_visible(self.inner.widget() as _) != 0 }
1037 }
1038
1039 pub fn is_hscroll_visible(&self) -> bool {
1041 unsafe { Fl_Tree_is_hscroll_visible(self.inner.widget() as _) != 0 }
1042 }
1043
1044 pub fn set_callback_item(&mut self, item: &TreeItem) {
1046 assert!(!item.inner.is_null());
1047 unsafe { Fl_Tree_set_callback_item(self.inner.widget() as _, item.inner) }
1048 }
1049
1050 pub fn callback_item(&self) -> Option<TreeItem> {
1052 unsafe { TreeItem::from_raw(Fl_Tree_callback_item(self.inner.widget() as _)) }
1053 }
1054
1055 pub fn set_callback_reason(&mut self, reason: TreeReason) {
1057 unsafe { Fl_Tree_set_callback_reason(self.inner.widget() as _, reason as i32) }
1058 }
1059
1060 pub fn callback_reason(&self) -> TreeReason {
1062 unsafe { mem::transmute(Fl_Tree_callback_reason(self.inner.widget() as _)) }
1063 }
1064
1065 pub fn item_pathname(&self, item: &TreeItem) -> Result<String, FltkError> {
1067 let mut temp = vec![0u8; 256];
1068 unsafe {
1069 let ret = Fl_Tree_item_pathname(
1070 self.inner.widget() as _,
1071 temp.as_mut_ptr() as _,
1072 256,
1073 item.inner,
1074 );
1075 if ret == 0 {
1076 if let Some(pos) = temp.iter().position(|x| *x == 0) {
1077 temp = temp.split_at(pos).0.to_vec();
1078 }
1079 Ok(String::from_utf8_lossy(&temp).to_string())
1080 } else {
1081 Err(FltkError::Internal(FltkErrorKind::FailedOperation))
1082 }
1083 }
1084 }
1085}
1086
1087impl IntoIterator for Tree {
1088 type Item = TreeItem;
1089 type IntoIter = std::vec::IntoIter<Self::Item>;
1090
1091 fn into_iter(self) -> Self::IntoIter {
1092 self.get_items().map_or_else(
1093 || Vec::with_capacity(0).into_iter(),
1094 std::iter::IntoIterator::into_iter,
1095 )
1096 }
1097}
1098
1099impl TreeItem {
1100 pub unsafe fn from_raw(ptr: *mut Fl_Tree_Item) -> Option<TreeItem> {
1104 unsafe {
1105 if ptr.is_null() {
1106 None
1107 } else {
1108 let w = Fl_Tree_Item_tree(ptr) as *mut Fl_Tree;
1109 let inner = crate::widget::WidgetTracker::new(w as _);
1110 let tree = Tree {
1111 inner,
1112 is_derived: false,
1113 };
1114 let parent = Fl_Tree_Item_parent(ptr);
1115 let is_root = Fl_Tree_Item_is_root(ptr) != 0;
1116 Some(TreeItem {
1117 inner: ptr,
1118 parent,
1119 tree,
1120 is_root,
1121 is_derived: false,
1122 })
1123 }
1124 }
1125 }
1126
1127 pub fn new(tree: &Tree, label: &str) -> Self {
1129 let label = CString::safe_new(label);
1130 unsafe {
1131 let ptr = Fl_Tree_Item_new(tree.inner.widget() as _, label.as_ptr());
1132 assert!(!ptr.is_null());
1133 Self {
1134 inner: ptr,
1135 parent: ptr,
1136 tree: tree.clone(),
1137 is_root: true,
1138 is_derived: true,
1139 }
1140 }
1141 }
1142
1143 pub fn draw_item_content<F: FnMut(&mut Self, bool) -> i32>(&mut self, cb: F) {
1178 assert!(self.is_derived);
1179 unsafe {
1180 unsafe extern "C" fn shim(
1181 item: *mut Fl_Tree_Item,
1182 render: i32,
1183 data: *mut raw::c_void,
1184 ) -> i32 {
1185 unsafe {
1186 let mut item = TreeItem::from_raw(item).unwrap();
1187 let a = data as *mut Box<dyn FnMut(&mut TreeItem, bool) -> i32>;
1188 let f: &mut (dyn FnMut(&mut TreeItem, bool) -> i32) = &mut **a;
1189 std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
1190 f(&mut item, render != 0)
1191 }))
1192 .unwrap_or_default()
1193 }
1194 }
1195 #[allow(clippy::type_complexity)]
1196 let a: *mut Box<dyn FnMut(&mut Self, bool) -> i32> =
1197 Box::into_raw(Box::new(Box::new(cb)));
1198 let data: *mut raw::c_void = a as *mut raw::c_void;
1199 let callback: Option<
1200 unsafe extern "C" fn(
1201 self_: *mut Fl_Tree_Item,
1202 arg1: i32,
1203 arg2: *mut raw::c_void,
1204 ) -> i32,
1205 > = Some(shim);
1206 Fl_Tree_Item_draw_item_content(self.inner, callback, data);
1207 }
1208 }
1209
1210 pub fn set_user_data<T: Clone + 'static>(&mut self, data: T) {
1214 unsafe {
1215 Fl_Tree_Item_set_user_data(self.inner, Box::into_raw(Box::from(data)) as _);
1216 }
1217 }
1218
1219 pub unsafe fn user_data<T: Clone + 'static>(&self) -> Option<T> {
1223 unsafe {
1224 let ptr = Fl_Tree_Item_user_data(self.inner);
1225 if ptr.is_null() {
1226 None
1227 } else {
1228 let data = ptr as *const _ as *mut T;
1229 Some((*data).clone())
1230 }
1231 }
1232 }
1233
1234 pub fn x(&self) -> i32 {
1236 unsafe { Fl_Tree_Item_x(self.inner) }
1237 }
1238
1239 pub fn y(&self) -> i32 {
1241 unsafe { Fl_Tree_Item_y(self.inner) }
1242 }
1243
1244 pub fn w(&self) -> i32 {
1246 unsafe { Fl_Tree_Item_w(self.inner) }
1247 }
1248
1249 pub fn h(&self) -> i32 {
1251 unsafe { Fl_Tree_Item_h(self.inner) }
1252 }
1253
1254 pub fn label_x(&self) -> i32 {
1256 unsafe { Fl_Tree_Item_label_x(self.inner) }
1257 }
1258
1259 pub fn label_y(&self) -> i32 {
1261 unsafe { Fl_Tree_Item_label_y(self.inner) }
1262 }
1263
1264 pub fn label_w(&self) -> i32 {
1266 unsafe { Fl_Tree_Item_label_w(self.inner) }
1267 }
1268
1269 pub fn label_h(&self) -> i32 {
1271 unsafe { Fl_Tree_Item_label_h(self.inner) }
1272 }
1273
1274 pub fn show_self(&self, indent: &str) {
1276 let indent = CString::safe_new(indent);
1277 unsafe { Fl_Tree_Item_show_self(self.inner, indent.as_ptr() as *mut raw::c_char) }
1278 }
1279
1280 pub fn set_label(&mut self, val: &str) {
1282 let val = CString::safe_new(val);
1283 unsafe { Fl_Tree_set_Item_label(self.inner, val.as_ptr() as *mut raw::c_char) }
1284 }
1285
1286 pub fn label(&self) -> Option<String> {
1288 unsafe {
1289 let x = Fl_Tree_Item_label(self.inner);
1290 if x.is_null() {
1291 None
1292 } else {
1293 Some(
1294 CStr::from_ptr(x as *mut raw::c_char)
1295 .to_string_lossy()
1296 .to_string(),
1297 )
1298 }
1299 }
1300 }
1301
1302 pub fn set_label_font(&mut self, val: Font) {
1304 unsafe { Fl_Tree_Item_set_labelfont(self.inner, val.bits()) }
1305 }
1306
1307 pub fn label_font(&self) -> Font {
1309 unsafe { mem::transmute(Fl_Tree_Item_labelfont(self.inner)) }
1310 }
1311
1312 pub fn set_label_size(&mut self, sz: i32) {
1314 let sz = if sz < 1 { 1 } else { sz };
1315 unsafe { Fl_Tree_Item_set_labelsize(self.inner, sz) }
1316 }
1317
1318 pub fn label_size(&self) -> i32 {
1320 unsafe { Fl_Tree_Item_labelsize(self.inner) }
1321 }
1322
1323 pub fn set_label_fgcolor(&mut self, val: Color) {
1325 unsafe { Fl_Tree_Item_set_labelfgcolor(self.inner, val.bits()) }
1326 }
1327
1328 pub fn label_fgcolor(&self) -> Color {
1330 unsafe { mem::transmute(Fl_Tree_Item_labelfgcolor(self.inner)) }
1331 }
1332
1333 pub fn set_label_color(&mut self, val: Color) {
1335 unsafe { Fl_Tree_Item_set_labelcolor(self.inner, val.bits()) }
1336 }
1337
1338 pub fn label_color(&self) -> Color {
1340 unsafe { mem::transmute(Fl_Tree_Item_labelcolor(self.inner)) }
1341 }
1342
1343 pub fn set_label_bgcolor(&mut self, val: Color) {
1345 unsafe { Fl_Tree_Item_set_labelbgcolor(self.inner, val.bits()) }
1346 }
1347
1348 pub fn label_bgcolor(&self) -> Color {
1350 unsafe { mem::transmute(Fl_Tree_Item_labelbgcolor(self.inner)) }
1351 }
1352
1353 pub fn set_widget<W: WidgetExt>(&mut self, val: &W) {
1355 unsafe { Fl_Tree_Item_set_widget(self.inner, val.as_widget_ptr() as *mut Fl_Widget) }
1356 }
1357
1358 pub fn widget(&self) -> Option<impl WidgetExt> {
1360 unsafe {
1361 let ptr = Fl_Tree_Item_widget(self.inner) as *mut fltk_sys::widget::Fl_Widget;
1362 if ptr.is_null() {
1363 None
1364 } else {
1365 Some(Widget::from_widget_ptr(ptr))
1366 }
1367 }
1368 }
1369
1370 pub fn children(&self) -> i32 {
1372 unsafe { Fl_Tree_Item_children(self.inner) }
1373 }
1374
1375 pub fn child(&self, idx: i32) -> Option<TreeItem> {
1377 if idx < 0 || idx >= self.children() {
1378 return None;
1379 }
1380
1381 unsafe { TreeItem::from_raw(Fl_Tree_Item_child(self.inner, idx) as *mut Fl_Tree_Item) }
1382 }
1383
1384 pub fn has_children(&self) -> bool {
1386 unsafe { Fl_Tree_Item_has_children(self.inner) != 0 }
1387 }
1388
1389 pub fn find_child(&mut self, name: &str) -> Result<i32, FltkError> {
1393 let name = CString::safe_new(name);
1394 unsafe {
1395 let x = Fl_Tree_Item_find_child(self.inner, name.as_ptr());
1396 if x == -1 {
1397 Err(FltkError::Internal(FltkErrorKind::FailedOperation))
1398 } else {
1399 Ok(x)
1400 }
1401 }
1402 }
1403
1404 pub fn remove_child(&mut self, new_label: &str) -> Result<(), FltkError> {
1408 let new_label = CString::safe_new(new_label);
1409 unsafe {
1410 match Fl_Tree_Item_remove_child(self.inner, new_label.as_ptr()) {
1411 0 => Ok(()),
1412 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
1413 }
1414 }
1415 }
1416
1417 pub fn clear_children(&mut self) {
1419 unsafe { Fl_Tree_Item_clear_children(self.inner) }
1420 }
1421
1422 pub fn swap_children(&mut self, a: &TreeItem, b: &TreeItem) -> Result<(), FltkError> {
1426 assert!(!self.was_deleted() && !a.was_deleted() && !b.was_deleted());
1427 unsafe {
1428 match Fl_Tree_Item_swap_children(self.inner, a.inner, b.inner) {
1429 0 => Ok(()),
1430 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
1431 }
1432 }
1433 }
1434
1435 pub fn find_child_item(&self, name: &str) -> Option<TreeItem> {
1437 let name = CString::safe_new(name);
1438 unsafe {
1439 TreeItem::from_raw(
1440 Fl_Tree_Item_find_child_item(self.inner, name.as_ptr()) as *mut Fl_Tree_Item
1441 )
1442 }
1443 }
1444
1445 pub fn replace(&mut self, new_item: &TreeItem) -> Option<TreeItem> {
1447 assert!(!self.was_deleted() && !new_item.was_deleted());
1448 unsafe { TreeItem::from_raw(Fl_Tree_Item_replace(self.inner, new_item.inner)) }
1449 }
1450
1451 pub fn replace_child(&mut self, old_item: &TreeItem, new_item: &TreeItem) -> Option<TreeItem> {
1453 assert!(!self.was_deleted() && !old_item.was_deleted() && !new_item.was_deleted());
1454 unsafe {
1455 TreeItem::from_raw(Fl_Tree_Item_replace_child(
1456 self.inner,
1457 old_item.inner,
1458 new_item.inner,
1459 ))
1460 }
1461 }
1462
1463 pub fn deparent(&mut self, index: i32) -> Option<TreeItem> {
1465 if index < 0 || index >= self.children() {
1466 return None;
1467 }
1468 unsafe { TreeItem::from_raw(Fl_Tree_Item_deparent(self.inner, index)) }
1469 }
1470
1471 pub fn reparent(&mut self, new_child: &TreeItem, index: i32) -> Result<(), FltkError> {
1475 assert!(!self.was_deleted() && !new_child.was_deleted());
1476 if index < 0 || index >= self.children() {
1477 return Err(FltkError::Internal(FltkErrorKind::FailedOperation));
1478 }
1479 unsafe {
1480 match Fl_Tree_Item_reparent(self.inner, new_child.inner, index) {
1481 0 => Ok(()),
1482 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
1483 }
1484 }
1485 }
1486
1487 pub fn move_item(&mut self, to: i32, from: i32) -> Result<(), FltkError> {
1491 unsafe {
1492 match Fl_Tree_Item_move(self.inner, to, from) {
1493 0 => Ok(()),
1494 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
1495 }
1496 }
1497 }
1498
1499 pub fn move_above(&mut self, item: &TreeItem) -> Result<(), FltkError> {
1503 assert!(!self.was_deleted() && !item.was_deleted());
1504 unsafe {
1505 match Fl_Tree_Item_move_above(self.inner, item.inner) {
1506 0 => Ok(()),
1507 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
1508 }
1509 }
1510 }
1511
1512 pub fn move_below(&mut self, item: &TreeItem) -> Result<(), FltkError> {
1516 assert!(!self.was_deleted() && !item.was_deleted());
1517 unsafe {
1518 match Fl_Tree_Item_move_below(self.inner, item.inner) {
1519 0 => Ok(()),
1520 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
1521 }
1522 }
1523 }
1524
1525 pub fn move_into(&mut self, item: &TreeItem, pos: i32) -> Result<(), FltkError> {
1529 assert!(!self.was_deleted() && !item.was_deleted());
1530 unsafe {
1531 match Fl_Tree_Item_move_into(self.inner, item.inner, pos) {
1532 0 => Ok(()),
1533 _ => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
1534 }
1535 }
1536 }
1537
1538 pub fn depth(&self) -> i32 {
1540 unsafe { Fl_Tree_Item_depth(self.inner) }
1541 }
1542
1543 pub fn prev(&self) -> Option<TreeItem> {
1545 unsafe { TreeItem::from_raw(Fl_Tree_Item_prev(self.inner)) }
1546 }
1547
1548 pub fn next(&self) -> Option<TreeItem> {
1550 unsafe { TreeItem::from_raw(Fl_Tree_Item_next(self.inner)) }
1551 }
1552
1553 pub fn next_sibling(&self) -> Option<TreeItem> {
1555 unsafe { TreeItem::from_raw(Fl_Tree_Item_next_sibling(self.inner)) }
1556 }
1557
1558 pub fn prev_sibling(&self) -> Option<TreeItem> {
1560 unsafe { TreeItem::from_raw(Fl_Tree_Item_prev_sibling(self.inner)) }
1561 }
1562
1563 pub fn update_prev_next(&mut self, index: i32) {
1565 unsafe { Fl_Tree_Item_update_prev_next(self.inner, index) }
1566 }
1567
1568 pub fn parent(&self) -> Option<TreeItem> {
1570 unsafe { TreeItem::from_raw(Fl_Tree_Item_parent(self.inner) as *mut Fl_Tree_Item) }
1571 }
1572
1573 pub fn set_parent(&mut self, val: &TreeItem) {
1575 unsafe { Fl_Tree_Item_set_parent(self.inner, val.inner) }
1576 }
1577
1578 pub fn tree(&self) -> Option<Tree> {
1580 unsafe { Tree::from_raw(Fl_Tree_Item_tree(self.inner) as *mut Fl_Tree) }
1581 }
1582
1583 pub fn open(&mut self) {
1585 unsafe { Fl_Tree_Item_open(self.inner) }
1586 }
1587
1588 pub fn close(&mut self) {
1590 unsafe { Fl_Tree_Item_close(self.inner) }
1591 }
1592
1593 pub fn is_open(&self) -> bool {
1595 unsafe { Fl_Tree_Item_is_open(self.inner) != 0 }
1596 }
1597
1598 pub fn is_close(&self) -> bool {
1600 unsafe { Fl_Tree_Item_is_close(self.inner) != 0 }
1601 }
1602
1603 pub fn open_toggle(&mut self) {
1605 unsafe { Fl_Tree_Item_open_toggle(self.inner) }
1606 }
1607
1608 pub fn select(&mut self, index: i32) {
1610 unsafe { Fl_Tree_Item_select(self.inner, index) }
1611 }
1612
1613 pub fn select_toggle(&mut self) {
1615 unsafe { Fl_Tree_Item_select_toggle(self.inner) }
1616 }
1617
1618 pub fn select_all(&mut self) -> i32 {
1620 unsafe { Fl_Tree_Item_select_all(self.inner) }
1621 }
1622
1623 pub fn deselect(&mut self) {
1625 unsafe { Fl_Tree_Item_deselect(self.inner) }
1626 }
1627
1628 pub fn deselect_all(&mut self) -> i32 {
1630 unsafe { Fl_Tree_Item_deselect_all(self.inner) }
1631 }
1632
1633 pub fn is_root(&self) -> bool {
1635 unsafe { Fl_Tree_Item_is_root(self.inner) != 0 }
1636 }
1637
1638 pub fn is_visible(&self) -> bool {
1640 unsafe { Fl_Tree_Item_is_visible(self.inner) != 0 }
1641 }
1642
1643 pub fn is_active(&self) -> bool {
1645 unsafe { Fl_Tree_Item_is_active(self.inner) != 0 }
1646 }
1647
1648 pub fn is_activated(&self) -> bool {
1650 unsafe { Fl_Tree_Item_is_activated(self.inner) != 0 }
1651 }
1652
1653 pub fn deactivate(&mut self) {
1655 unsafe { Fl_Tree_Item_deactivate(self.inner) }
1656 }
1657
1658 pub fn activate(&mut self, val: bool) {
1660 unsafe { Fl_Tree_Item_activate(self.inner, i32::from(val)) }
1661 }
1662
1663 pub fn is_selected(&self) -> bool {
1665 unsafe { Fl_Tree_Item_is_selected(self.inner) != 0 }
1666 }
1667
1668 pub fn was_deleted(&self) -> bool {
1670 unsafe {
1671 let parent = self.parent;
1672 let is_root = self.is_root;
1673 if self.tree.was_deleted() {
1674 return true;
1675 }
1676 if is_root {
1677 self.tree.root().is_none() || self.inner.is_null()
1678 } else {
1679 Fl_Tree_Item_children(parent) == 0 || self.inner.is_null()
1680 }
1681 }
1682 }
1683
1684 pub fn user_icon(&self) -> Option<Box<dyn ImageExt>> {
1686 unsafe {
1687 let image_ptr = Fl_Tree_Item_usericon(self.inner);
1688 if image_ptr.is_null() {
1689 None
1690 } else {
1691 Some(Box::new(Image::from_image_ptr(
1692 image_ptr as *mut fltk_sys::image::Fl_Image,
1693 )))
1694 }
1695 }
1696 }
1697
1698 pub fn set_user_icon<Img: ImageExt>(&mut self, image: Option<Img>) {
1700 if let Some(image) = image {
1701 assert!(!image.was_deleted());
1702 unsafe { Fl_Tree_Item_set_usericon(self.inner, image.as_image_ptr() as *mut _) }
1703 } else {
1704 unsafe { Fl_Tree_Item_set_usericon(self.inner, std::ptr::null_mut::<raw::c_void>()) }
1705 }
1706 }
1707
1708 pub fn as_ptr(&self) -> *mut Fl_Tree_Item {
1710 self.inner
1711 }
1712}
1713
1714impl Iterator for TreeItem {
1715 type Item = TreeItem;
1716 fn next(&mut self) -> Option<Self::Item> {
1718 unsafe { TreeItem::from_raw(Fl_Tree_Item_next(self.inner)) }
1719 }
1720}
1721
1722impl TreeItemArray {
1723 fn total(&self) -> i32 {
1725 unsafe { Fl_Tree_Item_Array_total(self.inner) }
1726 }
1727
1728 #[allow(dead_code)]
1730 fn swap(&mut self, ax: i32, bx: i32) {
1731 unsafe { Fl_Tree_Item_Array_swap(self.inner, ax, bx) }
1732 }
1733
1734 #[allow(dead_code)]
1736 fn move_item(&mut self, to: i32, from: i32) -> i32 {
1737 unsafe { Fl_Tree_Item_Array_move(self.inner, to, from) }
1738 }
1739
1740 #[allow(dead_code)]
1742 fn deparent(&mut self, pos: i32) -> i32 {
1743 unsafe { Fl_Tree_Item_Array_deparent(self.inner, pos) }
1744 }
1745
1746 #[allow(dead_code)]
1748 fn reparent(&mut self, item: &TreeItem, newparent: &TreeItem, pos: i32) -> i32 {
1749 unsafe { Fl_Tree_Item_Array_reparent(self.inner, item.inner, newparent.inner, pos) }
1750 }
1751
1752 #[allow(dead_code)]
1754 fn clear(&mut self) {
1755 unsafe { Fl_Tree_Item_Array_clear(self.inner) }
1756 }
1757
1758 #[allow(dead_code)]
1760 fn add(&mut self, val: &TreeItem) {
1761 unsafe { Fl_Tree_Item_Array_add(self.inner, val.inner) }
1762 }
1763
1764 #[allow(dead_code)]
1766 fn insert(&mut self, pos: i32, new_item: &TreeItem) {
1767 unsafe { Fl_Tree_Item_Array_insert(self.inner, pos, new_item.inner) }
1768 }
1769
1770 #[allow(dead_code)]
1772 fn replace(&mut self, pos: i32, new_item: &TreeItem) {
1773 unsafe { Fl_Tree_Item_Array_replace(self.inner, pos, new_item.inner) }
1774 }
1775
1776 #[allow(dead_code)]
1778 fn remove(&mut self, index: i32) {
1779 unsafe { Fl_Tree_Item_Array_remove(self.inner, index) }
1780 }
1781
1782 #[allow(dead_code)]
1784 fn remove_item(&mut self, item: &TreeItem) -> i32 {
1785 unsafe { Fl_Tree_Item_Array_remove_item(self.inner, item.inner) }
1786 }
1787
1788 fn at(&self, idx: i32) -> Option<TreeItem> {
1790 unsafe { TreeItem::from_raw(Fl_Tree_Item_Array_at(self.inner, idx)) }
1791 }
1792
1793 fn into_vec(self) -> Option<Vec<TreeItem>> {
1795 let c = self.total();
1796 let mut v: Vec<TreeItem> = vec![];
1797 if c == 0 {
1798 None
1799 } else {
1800 for i in 0..c {
1801 let val = self.at(i);
1802 val.as_ref()?;
1803 v.push(val.unwrap());
1804 }
1805 Some(v)
1806 }
1807 }
1808}
1809
1810impl IntoIterator for TreeItemArray {
1811 type Item = TreeItem;
1812 type IntoIter = std::vec::IntoIter<Self::Item>;
1813
1814 fn into_iter(self) -> Self::IntoIter {
1815 self.into_vec().map_or_else(
1816 || Vec::with_capacity(0).into_iter(),
1817 std::iter::IntoIterator::into_iter,
1818 )
1819 }
1820}
1821
1822#[cfg(not(feature = "single-threaded"))]
1823unsafe impl Send for TreeItem {}
1824
1825#[cfg(not(feature = "single-threaded"))]
1826unsafe impl Sync for TreeItem {}
1827
1828impl PartialEq for TreeItem {
1829 fn eq(&self, other: &Self) -> bool {
1830 self.inner == other.inner
1831 }
1832}
1833
1834impl Eq for TreeItem {}
1835
1836impl Drop for TreeItemArray {
1837 fn drop(&mut self) {
1838 unsafe { Fl_Tree_Item_Array_delete(self.inner) }
1839 }
1840}