1use std::{fmt, mem, ptr};
9use std::default::Default;
10
11use qualia::{SurfaceId, Area, Position, Size};
12
13type Link = Option<Frame>;
17
18struct Edges {
22 prev: Link,
24
25 next: Link,
27
28 first: Link,
30
31 last: Link,
33}
34
35impl Default for Edges {
38 fn default() -> Self {
39 Edges {
40 prev: None,
41 next: None,
42 first: None,
43 last: None,
44 }
45 }
46}
47
48struct Node {
52 matter: Link,
54
55 space: Edges,
57
58 time: Edges,
60}
61
62impl Default for Node {
65 fn default() -> Self {
66 Node {
67 matter: None,
68 space: Edges::default(),
69 time: Edges::default(),
70 }
71 }
72}
73
74#[derive(Clone, Copy, Debug, PartialEq)]
78pub enum Geometry {
79 Vertical,
81
82 Horizontal,
84
85 Stacked,
87}
88
89#[derive(Clone, Copy, Debug, PartialEq)]
93pub enum Mobility {
94 Floating,
96
97 Anchored,
99
100 Docked,
102}
103
104impl Mobility {
107 pub fn is_floating(&self) -> bool {
109 *self == Mobility::Floating
110 }
111
112 pub fn is_anchored(&self) -> bool {
114 *self == Mobility::Anchored
115 }
116
117 pub fn is_docked(&self) -> bool {
119 *self == Mobility::Docked
120 }
121}
122
123#[derive(Clone, Copy, Debug, PartialEq)]
127pub enum Mode {
128 Root,
129 Display{id: i32},
130 Workspace{is_active: bool},
131 Container,
132 Leaf,
133}
134
135impl Mode {
138 pub fn is_display(&self) -> bool {
140 if let Mode::Display{id: _} = *self {
141 true
142 } else {
143 false
144 }
145 }
146
147 pub fn is_workspace(&self) -> bool {
149 if let Mode::Workspace{is_active: _} = *self {
150 true
151 } else {
152 false
153 }
154 }
155
156 pub fn is_leaf(&self) -> bool {
158 *self == Mode::Leaf
159 }
160}
161
162#[derive(Clone, Copy, Debug, PartialEq)]
166pub enum Side {
167 Before,
169
170 On,
172
173 After,
175}
176
177pub struct Parameters {
181 pub sid: SurfaceId,
183
184 pub geometry: Geometry,
186
187 pub mobility: Mobility,
189
190 pub mode: Mode,
192
193 pub pos: Position,
195
196 pub size: Size,
198
199 pub title: String,
201}
202
203impl Parameters {
206 pub fn new_root() -> Self {
208 Parameters {
209 sid: SurfaceId::invalid(),
210 geometry: Geometry::Stacked,
211 mobility: Mobility::Floating,
212 mode: Mode::Root,
213 pos: Position::default(),
214 size: Size::default(),
215 title: "root".to_owned(),
216 }
217 }
218
219 pub fn new_display(id: i32, area: Area, title: String) -> Self {
221 Parameters {
222 sid: SurfaceId::invalid(),
223 geometry: Geometry::Stacked,
224 mobility: Mobility::Floating,
225 mode: Mode::Display{id: id},
226 pos: area.pos,
227 size: area.size,
228 title: title,
229 }
230 }
231
232 pub fn new_workspace(title: String, geometry: Geometry, active: bool) -> Self {
234 Parameters {
235 sid: SurfaceId::invalid(),
236 geometry: geometry,
237 mobility: Mobility::Anchored,
238 mode: Mode::Workspace{is_active: active},
239 pos: Position::default(),
240 size: Size::default(),
241 title: title,
242 }
243 }
244
245 pub fn new_container(geometry: Geometry) -> Self {
247 Parameters {
248 sid: SurfaceId::invalid(),
249 geometry: geometry,
250 mobility: Mobility::Anchored,
251 mode: Mode::Container,
252 pos: Position::default(),
253 size: Size::default(),
254 title: "".to_owned(),
255 }
256 }
257
258 pub fn new_leaf(sid: SurfaceId, geometry: Geometry) -> Self {
263 Parameters {
264 sid: sid,
265 geometry: geometry,
266 mobility: Mobility::Anchored,
267 mode: Mode::Leaf,
268 pos: Position::default(),
269 size: Size::default(),
270 title: "".to_owned(),
271 }
272 }
273}
274
275pub struct InnerFrame {
279 params: Parameters,
281
282 node: Node,
284}
285
286
287#[derive(Clone)]
291pub struct Frame {
292 inner: *mut InnerFrame,
293}
294
295impl Frame {
299 pub fn new(sid: SurfaceId,
301 geometry: Geometry,
302 mobility: Mobility,
303 mode: Mode,
304 pos: Position,
305 size: Size,
306 title: String)
307 -> Self {
308 Self::allocate(InnerFrame {
309 params: Parameters {
310 sid: sid,
311 geometry: geometry,
312 mobility: mobility,
313 mode: mode,
314 pos: pos,
315 size: size,
316 title: title,
317 },
318 node: Node::default(),
319 })
320 }
321
322 pub fn new_root() -> Self {
324 Self::allocate(InnerFrame {
325 params: Parameters::new_root(),
326 node: Node::default(),
327 })
328 }
329
330 pub fn new_display(id: i32, area: Area, title: String) -> Self {
332 Self::allocate(InnerFrame {
333 params: Parameters::new_display(id, area, title),
334 node: Node::default(),
335 })
336 }
337
338 pub fn new_workspace(title: String, geometry: Geometry, active: bool) -> Self {
340 Self::allocate(InnerFrame {
341 params: Parameters::new_workspace(title, geometry, active),
342 node: Node::default(),
343 })
344 }
345
346 pub fn new_container(geometry: Geometry) -> Self {
348 Self::allocate(InnerFrame {
349 params: Parameters::new_container(geometry),
350 node: Node::default(),
351 })
352 }
353
354 pub fn new_leaf(sid: SurfaceId, geometry: Geometry) -> Self {
356 Self::allocate(InnerFrame {
357 params: Parameters::new_leaf(sid, geometry),
358 node: Node::default(),
359 })
360 }
361
362 pub fn destroy(&self) {
364 for f in self.time_iter() {
365 f.destroy();
366 }
367 self.deallocate();
368 }
369}
370
371impl Frame {
375 pub fn time_iter(&self) -> FrameTimeIterator {
377 FrameTimeIterator { frame: self.get_first_time() }
378 }
379
380 pub fn time_rev_iter(&self) -> FrameTimeReveresedIterator {
382 FrameTimeReveresedIterator { frame: self.get_last_time() }
383 }
384
385 pub fn space_iter(&self) -> FrameSpaceIterator {
387 FrameSpaceIterator { frame: self.get_first_space() }
388 }
389
390 pub fn space_rev_iter(&self) -> FrameSpaceReveresedIterator {
392 FrameSpaceReveresedIterator { frame: self.get_last_space() }
393 }
394}
395
396impl Frame {
400 #[inline]
402 pub fn get_sid(&self) -> SurfaceId {
403 unsafe { (*self.inner).params.sid }
404 }
405
406 #[inline]
408 pub fn get_mode(&self) -> Mode {
409 unsafe { (*self.inner).params.mode }
410 }
411
412 #[inline]
414 pub fn get_geometry(&self) -> Geometry {
415 unsafe { (*self.inner).params.geometry }
416 }
417
418 #[inline]
420 pub fn get_mobility(&self) -> Mobility {
421 unsafe { (*self.inner).params.mobility }
422 }
423
424 #[inline]
426 pub fn get_position(&self) -> Position {
427 unsafe { (*self.inner).params.pos.clone() }
428 }
429
430 #[inline]
432 pub fn get_size(&self) -> Size {
433 unsafe { (*self.inner).params.size.clone() }
434 }
435
436 #[inline]
438 pub fn get_area(&self) -> Area {
439 Area::new(self.get_position(), self.get_size())
440 }
441
442 pub fn get_title(&self) -> String {
444 unsafe { (*self.inner).params.title.clone() }
445 }
446
447 pub fn is_top(&self) -> bool {
449 let mode = self.get_mode();
450 let mobility = self.get_mobility();
451 (mobility == Mobility::Docked) || ((mode != Mode::Container) && (mode != Mode::Leaf))
452 }
453
454 pub fn is_reanchorizable(&self) -> bool {
459 !self.is_top()
460 }
461
462 pub fn is_reorientable(&self) -> bool {
464 (!self.is_top()) || (self.get_mode().is_workspace())
465 }
466
467 pub fn make_active(&self, active: bool) {
472 if self.get_mode().is_workspace() {
473 unsafe {
474 (*self.inner).params.mode = Mode::Workspace{is_active: active};
475 }
476 }
477 }
478}
479
480impl Frame {
484 #[inline]
486 pub fn set_plumbing_sid(&mut self, sid: SurfaceId) {
487 unsafe {
488 (*self.inner).params.sid = sid;
489 }
490 }
491
492 #[inline]
494 pub fn set_plumbing_position(&mut self, pos: Position) {
495 unsafe {
496 (*self.inner).params.pos = pos;
497 }
498 }
499
500 #[inline]
502 pub fn set_plumbing_size(&mut self, size: Size) {
503 unsafe {
504 (*self.inner).params.size = size;
505 }
506 }
507
508 #[inline]
510 pub fn set_plumbing_geometry(&mut self, geometry: Geometry) {
511 unsafe {
512 (*self.inner).params.geometry = geometry;
513 }
514 }
515
516 #[inline]
518 pub fn set_plumbing_mobility(&mut self, mobility: Mobility) {
519 unsafe {
520 (*self.inner).params.mobility = mobility;
521 }
522 }
523
524 #[inline]
526 pub fn set_plumbing_mode(&mut self, mode: Mode) {
527 unsafe {
528 (*self.inner).params.mode = mode;
529 }
530 }
531
532 #[inline]
534 pub fn set_plumbing_position_and_size(&mut self, pos: Position, size: Size) {
535 unsafe {
536 (*self.inner).params.pos = pos;
537 }
538 unsafe {
539 (*self.inner).params.size = size;
540 }
541 }
542}
543
544impl Frame {
548 #[inline]
550 pub fn has_parent(&self) -> bool {
551 unsafe { (*self.inner).node.matter.is_some() }
552 }
553
554 #[inline]
556 pub fn has_children(&self) -> bool {
557 unsafe { (*self.inner).node.time.last.is_some() }
558 }
559
560 #[inline]
562 pub fn get_parent(&self) -> Option<Frame> {
563 unsafe { (*self.inner).node.matter.clone() }
564 }
565
566 #[inline]
568 pub fn get_first_time(&self) -> Option<Frame> {
569 unsafe { (*self.inner).node.time.first.clone() }
570 }
571
572 #[inline]
574 pub fn get_last_time(&self) -> Option<Frame> {
575 unsafe { (*self.inner).node.time.last.clone() }
576 }
577
578 #[inline]
580 pub fn get_prev_time(&self) -> Option<Frame> {
581 unsafe { (*self.inner).node.time.prev.clone() }
582 }
583
584 #[inline]
586 pub fn get_next_time(&self) -> Option<Frame> {
587 unsafe { (*self.inner).node.time.next.clone() }
588 }
589
590 #[inline]
592 pub fn get_first_space(&self) -> Option<Frame> {
593 unsafe { (*self.inner).node.space.first.clone() }
594 }
595
596 #[inline]
598 pub fn get_last_space(&self) -> Option<Frame> {
599 unsafe { (*self.inner).node.space.last.clone() }
600 }
601
602 #[inline]
604 pub fn get_prev_space(&self) -> Option<Frame> {
605 unsafe { (*self.inner).node.space.prev.clone() }
606 }
607
608 #[inline]
610 pub fn get_next_space(&self) -> Option<Frame> {
611 unsafe { (*self.inner).node.space.next.clone() }
612 }
613}
614
615impl Frame {
619 pub fn prepend(&mut self, frame: &mut Frame) {
621 self.append_time(frame);
622 self.prepend_space(frame);
623 frame.set_matter(self);
624 }
625
626 pub fn append(&mut self, frame: &mut Frame) {
628 self.append_time(frame);
629 self.append_space(frame);
630 frame.set_matter(self);
631 }
632
633 pub fn prejoin(&mut self, frame: &mut Frame) {
636 if let Some(ref mut parent) = self.get_parent() {
637 parent.append_time(frame);
638 if let Some(ref mut prev) = self.get_prev_space() {
639 prev.join_space(frame);
640 frame.join_space(self);
641 } else {
642 parent.prepend_space(frame);
643 }
644 frame.set_matter(parent);
645 }
646 }
647
648 pub fn adjoin(&mut self, frame: &mut Frame) {
651 if let Some(ref mut parent) = self.get_parent() {
652 parent.append_time(frame);
653 if let Some(ref mut next) = self.get_next_space() {
654 self.join_space(frame);
655 frame.join_space(next);
656 } else {
657 parent.append_space(frame);
658 }
659 frame.set_matter(parent);
660 }
661 }
662
663 pub fn pop(&mut self) {
665 if let Some(ref mut parent) = self.get_parent() {
666 self.unjoin_time();
667 parent.prepend_time(self);
668 }
669 }
670
671 pub fn remove(&mut self) {
673 if self.has_parent() {
674 self.unjoin_time();
675 self.unjoin_space();
676 self.reset_matter();
677 }
678 }
679}
680
681impl Frame {
685 #[inline]
687 fn set_matter(&mut self, frame: &Frame) {
688 unsafe {
689 (*self.inner).node.matter = Some(frame.clone());
690 }
691 }
692
693 #[inline]
695 fn reset_matter(&mut self) {
696 unsafe {
697 (*self.inner).node.matter = None;
698 }
699 }
700
701 #[inline]
703 fn prepend_time(&mut self, frame: &mut Frame) {
704 unsafe {
705 if let Some(ref mut first_time) = (*self.inner).node.time.first {
706 (*first_time.inner).node.time.prev = Some(frame.clone());
707 (*frame.inner).node.time.next = Some(first_time.clone());
708 } else {
709 (*self.inner).node.time.last = Some(frame.clone());
710 }
711 (*self.inner).node.time.first = Some(frame.clone());
712 }
713 }
714
715 #[inline]
717 fn append_time(&mut self, frame: &mut Frame) {
718 unsafe {
719 if let Some(ref mut last_time) = (*self.inner).node.time.last {
720 (*last_time.inner).node.time.next = Some(frame.clone());
721 (*frame.inner).node.time.prev = Some(last_time.clone());
722 } else {
723 (*self.inner).node.time.first = Some(frame.clone());
724 }
725 (*self.inner).node.time.last = Some(frame.clone());
726 }
727 }
728
729 #[inline]
731 fn prepend_space(&mut self, frame: &mut Frame) {
732 unsafe {
733 if let Some(ref mut first_space) = (*self.inner).node.space.first {
734 frame.join_space(first_space);
735 } else {
736 (*self.inner).node.space.last = Some(frame.clone());
737 }
738 (*self.inner).node.space.first = Some(frame.clone());
739 }
740 }
741
742 #[inline]
744 fn append_space(&mut self, frame: &mut Frame) {
745 unsafe {
746 if let Some(ref mut last_space) = (*self.inner).node.space.last {
747 last_space.join_space(frame);
748 } else {
749 (*self.inner).node.space.first = Some(frame.clone());
750 }
751 (*self.inner).node.space.last = Some(frame.clone());
752 }
753 }
754
755 #[inline]
758 fn join_space(&mut self, frame: &mut Frame) {
759 unsafe {
760 (*self.inner).node.space.next = Some(frame.clone());
761 (*frame.inner).node.space.prev = Some(self.clone());
762 }
763 }
764
765 #[inline]
767 fn unjoin_time(&mut self) {
768 unsafe {
769 if let Some(ref mut next_time) = (*self.inner).node.time.next {
770 (*next_time.inner).node.time.prev = (*self.inner).node.time.prev.clone();
771 } else if let Some(ref mut matter) = (*self.inner).node.matter {
772 (*matter.inner).node.time.last = (*self.inner).node.time.prev.clone();
773 }
774 if let Some(ref mut prev_time) = (*self.inner).node.time.prev {
775 (*prev_time.inner).node.time.next = (*self.inner).node.time.next.clone();
776 } else if let Some(ref mut matter) = (*self.inner).node.matter {
777 (*matter.inner).node.time.first = (*self.inner).node.time.next.clone();
778 }
779 (*self.inner).node.time.prev = None;
780 (*self.inner).node.time.next = None;
781 }
782 }
783
784 #[inline]
786 fn unjoin_space(&mut self) {
787 unsafe {
788 if let Some(ref mut next_space) = (*self.inner).node.space.next {
789 (*next_space.inner).node.space.prev = (*self.inner).node.space.prev.clone();
790 } else if let Some(ref mut matter) = (*self.inner).node.matter {
791 (*matter.inner).node.space.last = (*self.inner).node.space.prev.clone();
792 }
793 if let Some(ref mut prev_space) = (*self.inner).node.space.prev {
794 (*prev_space.inner).node.space.next = (*self.inner).node.space.next.clone();
795 } else if let Some(ref mut matter) = (*self.inner).node.matter {
796 (*matter.inner).node.space.first = (*self.inner).node.space.next.clone();
797 }
798 (*self.inner).node.space.prev = None;
799 (*self.inner).node.space.next = None;
800 }
801 }
802}
803
804impl Frame {
808 fn allocate(inner: InnerFrame) -> Self {
810 let ptr = {
811 let mut v = Vec::with_capacity(mem::size_of::<InnerFrame>());
816 let ptr = v.as_mut_ptr();
817 mem::forget(v);
818 ptr
819 } as *mut _;
820
821 unsafe {
822 ptr::write(ptr, inner);
823 }
824
825 Frame { inner: ptr }
826 }
827
828 fn deallocate(&self) {
830 let ptr = self.inner as *mut _;
831 unsafe {
832 mem::drop(Vec::from_raw_parts(ptr, 0, mem::size_of::<InnerFrame>()));
839 }
840 }
841}
842
843impl Frame {
847 #[inline]
849 pub fn equals_exact(&self, other: &Frame) -> bool {
850 self.inner == other.inner
851 }
852
853 pub fn count_children(&self) -> usize {
855 let mut result = 0;
856 for _ in self.time_iter() {
857 result += 1
858 }
859 result
860 }
861
862 pub fn count_anchored_children(&self) -> usize {
864 let mut result = 0;
865 for child in self.time_iter() {
866 if child.get_mobility().is_anchored() {
867 result += 1
868 }
869 }
870 result
871 }
872
873 pub fn calculate_global_position(&self) -> Position {
875 if let Some(parent) = self.get_parent() {
876 self.get_position() + parent.calculate_global_position()
877 } else {
878 Position::default()
879 }
880 }
881}
882
883impl fmt::Debug for Frame {
886 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
887 let pos = self.get_position();
888 let size = self.get_size();
889 write!(f,
890 "Frame {{ sid: {:?}, '{}', {:?}, {:?}, {:?}, {}x{}+{}+{} }}",
891 self.get_sid(),
892 self.get_title(),
893 self.get_mode(),
894 self.get_geometry(),
895 self.get_mobility(),
896 size.width,
897 size.height,
898 pos.x,
899 pos.y)
900 }
901}
902
903pub struct FrameTimeIterator {
907 frame: Link,
908}
909
910impl Iterator for FrameTimeIterator {
913 type Item = Frame;
914
915 fn next(&mut self) -> Option<Frame> {
916 let result = self.frame.clone();
917 self.frame = if let Some(ref mut frame) = self.frame {
918 frame.get_next_time()
919 } else {
920 None
921 };
922 result
923 }
924}
925
926pub struct FrameTimeReveresedIterator {
930 frame: Link,
931}
932
933impl Iterator for FrameTimeReveresedIterator {
936 type Item = Frame;
937
938 fn next(&mut self) -> Option<Frame> {
939 let result = self.frame.clone();
940 self.frame = if let Some(ref mut frame) = self.frame {
941 frame.get_prev_time()
942 } else {
943 None
944 };
945 result
946 }
947}
948
949pub struct FrameSpaceIterator {
953 frame: Link,
954}
955
956impl Iterator for FrameSpaceIterator {
959 type Item = Frame;
960
961 fn next(&mut self) -> Option<Frame> {
962 let result = self.frame.clone();
963 self.frame = if let Some(ref mut frame) = self.frame {
964 frame.get_next_space()
965 } else {
966 None
967 };
968 result
969 }
970}
971
972pub struct FrameSpaceReveresedIterator {
976 frame: Link,
977}
978
979impl Iterator for FrameSpaceReveresedIterator {
982 type Item = Frame;
983
984 fn next(&mut self) -> Option<Frame> {
985 let result = self.frame.clone();
986 self.frame = if let Some(ref mut frame) = self.frame {
987 frame.get_prev_space()
988 } else {
989 None
990 };
991 result
992 }
993}
994
995