cognitive_frames/
frame.rs

1// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
2// the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/
3
4//! Defines `Frame` data structure representing space and time layout of surfaces.
5
6// -------------------------------------------------------------------------------------------------
7
8use std::{fmt, mem, ptr};
9use std::default::Default;
10
11use qualia::{SurfaceId, Area, Position, Size};
12
13// -------------------------------------------------------------------------------------------------
14
15/// Alias for optional frame.
16type Link = Option<Frame>;
17
18// -------------------------------------------------------------------------------------------------
19
20/// Helper data structure for defining edges and nodes in frame tree graph.
21struct Edges {
22    /// Links to previous frame in order.
23    prev: Link,
24
25    /// Links to next frame in order.
26    next: Link,
27
28    /// Links to child first in order.
29    first: Link,
30
31    /// Links to child last in order.
32    last: Link,
33}
34
35// -------------------------------------------------------------------------------------------------
36
37impl 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
48// -------------------------------------------------------------------------------------------------
49
50/// Helper data structure for defining edges and nodes in frame tree graph.
51struct Node {
52    /// Links to parent frame.
53    matter: Link,
54
55    /// Links to space-like siblings and children.
56    space: Edges,
57
58    /// Links to time-like siblings and children.
59    time: Edges,
60}
61
62// -------------------------------------------------------------------------------------------------
63
64impl 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// -------------------------------------------------------------------------------------------------
75
76/// Defines geometry of the frame.
77#[derive(Clone, Copy, Debug, PartialEq)]
78pub enum Geometry {
79    /// Children of frame with this geometry are placed vertically - in one row.
80    Vertical,
81
82    /// Children of frame with this geometry are placed how - in one column.
83    Horizontal,
84
85    /// Children of frame with this geometry are placed on stack - only one is visible at a time.
86    Stacked,
87}
88
89// -------------------------------------------------------------------------------------------------
90
91/// Defines what spatial operations are allowed in the frame.
92#[derive(Clone, Copy, Debug, PartialEq)]
93pub enum Mobility {
94    /// Frame can be moved and resized.
95    Floating,
96
97    /// Frame can only be resized.
98    Anchored,
99
100    /// Frame cannot be moved nor resized.
101    Docked,
102}
103
104// -------------------------------------------------------------------------------------------------
105
106impl Mobility {
107    /// Returns `true` if frame can be moved or resized.
108    pub fn is_floating(&self) -> bool {
109        *self == Mobility::Floating
110    }
111
112    /// Returns `true` if frame can be resized but not moved.
113    pub fn is_anchored(&self) -> bool {
114        *self == Mobility::Anchored
115    }
116
117    /// Returns `true` if frame cannot be resized nor moved.
118    pub fn is_docked(&self) -> bool {
119        *self == Mobility::Docked
120    }
121}
122
123// -------------------------------------------------------------------------------------------------
124
125/// Defines mode of the frame.
126#[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
135// -------------------------------------------------------------------------------------------------
136
137impl Mode {
138    /// Returns `true` if mode is `Display`, `false` otherwise.
139    pub fn is_display(&self) -> bool {
140        if let Mode::Display{id: _} = *self {
141            true
142        } else {
143            false
144        }
145    }
146
147    /// Returns `true` if mode is `Workspace`, `false` otherwise.
148    pub fn is_workspace(&self) -> bool {
149        if let Mode::Workspace{is_active: _} = *self {
150            true
151        } else {
152            false
153        }
154    }
155
156    /// Returns `true` if mode is `Leaf`, `false` otherwise.
157    pub fn is_leaf(&self) -> bool {
158        *self == Mode::Leaf
159    }
160}
161
162// -------------------------------------------------------------------------------------------------
163
164/// Enum used to define place relative to some frame.
165#[derive(Clone, Copy, Debug, PartialEq)]
166pub enum Side {
167    /// Before; on the left; above.
168    Before,
169
170    /// In the same place.
171    On,
172
173    /// After; on the right; below.
174    After,
175}
176
177// -------------------------------------------------------------------------------------------------
178
179/// Parameters of the frame defining its properties.
180pub struct Parameters {
181    /// ID of assigned surface.
182    pub sid: SurfaceId,
183
184    /// Geometry.
185    pub geometry: Geometry,
186
187    /// Mobility.
188    pub mobility: Mobility,
189
190    /// Mode.
191    pub mode: Mode,
192
193    /// Position.
194    pub pos: Position,
195
196    /// Size.
197    pub size: Size,
198
199    /// Title.
200    pub title: String,
201}
202
203// -------------------------------------------------------------------------------------------------
204
205impl Parameters {
206    /// Creates new parameters for root frame.
207    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    /// Creates new parameters for display frame.
220    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    /// Creates new parameters for workspace frame.
233    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    /// Creates new parameters for container frame.
246    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    /// Creates new parameters for leaf frame.
259    ///
260    /// Position, size and anchorization state are not important now. They will be set during
261    /// settling the frame.
262    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
275// -------------------------------------------------------------------------------------------------
276
277/// Helper structure for defining `Frame` structure.
278pub struct InnerFrame {
279    /// Parameters.
280    params: Parameters,
281
282    /// Links to neighbouring frames.
283    node: Node,
284}
285
286
287// -------------------------------------------------------------------------------------------------
288
289/// Frame main data structure.
290#[derive(Clone)]
291pub struct Frame {
292    inner: *mut InnerFrame,
293}
294
295// -------------------------------------------------------------------------------------------------
296
297/// Public constructors and destructor.
298impl Frame {
299    /// Creates new generic frame.
300    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    /// Creates new root frame.
323    pub fn new_root() -> Self {
324        Self::allocate(InnerFrame {
325                           params: Parameters::new_root(),
326                           node: Node::default(),
327                       })
328    }
329
330    /// Creates new display frame.
331    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    /// Creates new workspace frame.
339    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    /// Creates new container frame.
347    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    /// Creates new leaf frame.
355    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    /// Destroys frame recursively and deallocate memory.
363    pub fn destroy(&self) {
364        for f in self.time_iter() {
365            f.destroy();
366        }
367        self.deallocate();
368    }
369}
370
371// -------------------------------------------------------------------------------------------------
372
373/// Getting iterators.
374impl Frame {
375    /// Gets iterator over children in time order.
376    pub fn time_iter(&self) -> FrameTimeIterator {
377        FrameTimeIterator { frame: self.get_first_time() }
378    }
379
380    /// Gets iterator over children in time reversed order.
381    pub fn time_rev_iter(&self) -> FrameTimeReveresedIterator {
382        FrameTimeReveresedIterator { frame: self.get_last_time() }
383    }
384
385    /// Gets iterator over children in space order.
386    pub fn space_iter(&self) -> FrameSpaceIterator {
387        FrameSpaceIterator { frame: self.get_first_space() }
388    }
389
390    /// Gets iterator over children in space reversed order.
391    pub fn space_rev_iter(&self) -> FrameSpaceReveresedIterator {
392        FrameSpaceReveresedIterator { frame: self.get_last_space() }
393    }
394}
395
396// -------------------------------------------------------------------------------------------------
397
398/// Public getters for frame internals.
399impl Frame {
400    /// Gets ID of assigned surface.
401    #[inline]
402    pub fn get_sid(&self) -> SurfaceId {
403        unsafe { (*self.inner).params.sid }
404    }
405
406    /// Gets mode.
407    #[inline]
408    pub fn get_mode(&self) -> Mode {
409        unsafe { (*self.inner).params.mode }
410    }
411
412    /// Gets geometry.
413    #[inline]
414    pub fn get_geometry(&self) -> Geometry {
415        unsafe { (*self.inner).params.geometry }
416    }
417
418    /// Gets mobility.
419    #[inline]
420    pub fn get_mobility(&self) -> Mobility {
421        unsafe { (*self.inner).params.mobility }
422    }
423
424    /// Gets position.
425    #[inline]
426    pub fn get_position(&self) -> Position {
427        unsafe { (*self.inner).params.pos.clone() }
428    }
429
430    /// Gets size.
431    #[inline]
432    pub fn get_size(&self) -> Size {
433        unsafe { (*self.inner).params.size.clone() }
434    }
435
436    /// Gets area.
437    #[inline]
438    pub fn get_area(&self) -> Area {
439        Area::new(self.get_position(), self.get_size())
440    }
441
442    /// Gets title.
443    pub fn get_title(&self) -> String {
444        unsafe { (*self.inner).params.title.clone() }
445    }
446
447    /// Check if frame is spacial and should be ignored while normal surface management.
448    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    /// Returns `true` if frame with this mode can be reanchorized, `false` otherwise.
455    ///
456    /// NOTE: Display must be floating. Otherwise it could be relaxed. For the same reason
457    /// workspace must be anchored.
458    pub fn is_reanchorizable(&self) -> bool {
459        !self.is_top()
460    }
461
462    /// Check if it should be possible to reorient or resize contents of frame.
463    pub fn is_reorientable(&self) -> bool {
464        (!self.is_top()) || (self.get_mode().is_workspace())
465    }
466
467    /// Activates or deactivates the frame.
468    ///
469    /// This method has effect only on workspaces. Not active workspace should not be drawn on
470    /// screen.
471    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
480// -------------------------------------------------------------------------------------------------
481
482/// Public setters for frame internals.
483impl Frame {
484    /// Sets surface id without informing other parts of application.
485    #[inline]
486    pub fn set_plumbing_sid(&mut self, sid: SurfaceId) {
487        unsafe {
488            (*self.inner).params.sid = sid;
489        }
490    }
491
492    /// Sets size without informing other parts of application.
493    #[inline]
494    pub fn set_plumbing_position(&mut self, pos: Position) {
495        unsafe {
496            (*self.inner).params.pos = pos;
497        }
498    }
499
500    /// Sets size without informing other parts of application.
501    #[inline]
502    pub fn set_plumbing_size(&mut self, size: Size) {
503        unsafe {
504            (*self.inner).params.size = size;
505        }
506    }
507
508    /// Sets geometry without adjusting any sizes an positions.
509    #[inline]
510    pub fn set_plumbing_geometry(&mut self, geometry: Geometry) {
511        unsafe {
512            (*self.inner).params.geometry = geometry;
513        }
514    }
515
516    /// Sets mobility without any checks.
517    #[inline]
518    pub fn set_plumbing_mobility(&mut self, mobility: Mobility) {
519        unsafe {
520            (*self.inner).params.mobility = mobility;
521        }
522    }
523
524    /// Sets mode without any checks.
525    #[inline]
526    pub fn set_plumbing_mode(&mut self, mode: Mode) {
527        unsafe {
528            (*self.inner).params.mode = mode;
529        }
530    }
531
532    /// Sets position and size without informing other parts of application.
533    #[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
544// -------------------------------------------------------------------------------------------------
545
546/// Public getters for neighbouring frames.
547impl Frame {
548    /// Checks if frame has parent.
549    #[inline]
550    pub fn has_parent(&self) -> bool {
551        unsafe { (*self.inner).node.matter.is_some() }
552    }
553
554    /// Checks if frame has children.
555    #[inline]
556    pub fn has_children(&self) -> bool {
557        unsafe { (*self.inner).node.time.last.is_some() }
558    }
559
560    /// Optionally returns frames parent.
561    #[inline]
562    pub fn get_parent(&self) -> Option<Frame> {
563        unsafe { (*self.inner).node.matter.clone() }
564    }
565
566    /// Optionally returns child first in time order.
567    #[inline]
568    pub fn get_first_time(&self) -> Option<Frame> {
569        unsafe { (*self.inner).node.time.first.clone() }
570    }
571
572    /// Optionally returns child last in time order.
573    #[inline]
574    pub fn get_last_time(&self) -> Option<Frame> {
575        unsafe { (*self.inner).node.time.last.clone() }
576    }
577
578    /// Optionally returns sibling previous in time order.
579    #[inline]
580    pub fn get_prev_time(&self) -> Option<Frame> {
581        unsafe { (*self.inner).node.time.prev.clone() }
582    }
583
584    /// Optionally returns sibling next in time order.
585    #[inline]
586    pub fn get_next_time(&self) -> Option<Frame> {
587        unsafe { (*self.inner).node.time.next.clone() }
588    }
589
590    /// Optionally returns child first in space order.
591    #[inline]
592    pub fn get_first_space(&self) -> Option<Frame> {
593        unsafe { (*self.inner).node.space.first.clone() }
594    }
595
596    /// Optionally returns child last in space order.
597    #[inline]
598    pub fn get_last_space(&self) -> Option<Frame> {
599        unsafe { (*self.inner).node.space.last.clone() }
600    }
601
602    /// Optionally returns sibling previous in space order.
603    #[inline]
604    pub fn get_prev_space(&self) -> Option<Frame> {
605        unsafe { (*self.inner).node.space.prev.clone() }
606    }
607
608    /// Optionally returns sibling next in space order.
609    #[inline]
610    pub fn get_next_space(&self) -> Option<Frame> {
611        unsafe { (*self.inner).node.space.next.clone() }
612    }
613}
614
615// -------------------------------------------------------------------------------------------------
616
617/// Public manipulators. Allow to change order relations between frames.
618impl Frame {
619    /// Prepends in spatial order and appends in time order given frame to self children.
620    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    /// Appends in spatial order and appends in time order given frame to self children.
627    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    /// Inserts given frame as previous in spatial order sibling of self. Frame becomes last
634    /// sibling in time order.
635    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    /// Inserts given frame as next in spatial order sibling of self. Frame becomes last
649    /// sibling in time order.
650    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    /// Make given frame first in time order of all its siblings. Spatial order is untouched.
664    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    /// Remove given frame from its parent children.
672    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
681// -------------------------------------------------------------------------------------------------
682
683/// Private manipulators. Allow to change order relations between frames.
684impl Frame {
685    /// Set parent.
686    #[inline]
687    fn set_matter(&mut self, frame: &Frame) {
688        unsafe {
689            (*self.inner).node.matter = Some(frame.clone());
690        }
691    }
692
693    /// Unset parent.
694    #[inline]
695    fn reset_matter(&mut self) {
696        unsafe {
697            (*self.inner).node.matter = None;
698        }
699    }
700
701    /// Prepend frame in time order.
702    #[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    /// Append frame in time order.
716    #[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    /// Prepend frame in space order.
730    #[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    /// Append frame in space order.
743    #[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    /// Join two frames in space order. `self` becomes previous from `frame` and `frame` next from
756    /// `self`.
757    #[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    /// Remove given frame from time order.
766    #[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    /// Remove given frame from space order.
785    #[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
804// -------------------------------------------------------------------------------------------------
805
806/// Allocators/deallocators.
807impl Frame {
808    /// Helper method for allocating new frame on heap.
809    fn allocate(inner: InnerFrame) -> Self {
810        let ptr = {
811            // NOTE: `alloc` crate would be more clean solution but it is unstable:
812            // ```
813            // alloc::heap::allocate(mem::size_of::<InnerFrame>(), mem::align_of::<InnerFrame>())
814            // ```
815            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    /// Helper method for destroying frame. Deallocate memory on heap.
829    fn deallocate(&self) {
830        let ptr = self.inner as *mut _;
831        unsafe {
832            // NOTE: `alloc` crate would be more clean solution but it is unstable:
833            // ```
834            // alloc::heap::deallocate(ptr,
835            //                         mem::size_of::<InnerFrame>(),
836            //                         mem::align_of::<InnerFrame>());
837            // ```
838            mem::drop(Vec::from_raw_parts(ptr, 0, mem::size_of::<InnerFrame>()));
839        }
840    }
841}
842
843// -------------------------------------------------------------------------------------------------
844
845/// Miscellaneous other methods.
846impl Frame {
847    /// Compares frame internals for check if frames are not only same but **the** same.
848    #[inline]
849    pub fn equals_exact(&self, other: &Frame) -> bool {
850        self.inner == other.inner
851    }
852
853    /// Counts children and returns their number.
854    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    /// Counts anchored children and returns their number.
863    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    /// Calculates global position of the frame.
874    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
883// -------------------------------------------------------------------------------------------------
884
885impl 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
903// -------------------------------------------------------------------------------------------------
904
905/// Iterator over frames in time order.
906pub struct FrameTimeIterator {
907    frame: Link,
908}
909
910// -------------------------------------------------------------------------------------------------
911
912impl 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
926// -------------------------------------------------------------------------------------------------
927
928/// Iterator over frames in reversed time order.
929pub struct FrameTimeReveresedIterator {
930    frame: Link,
931}
932
933// -------------------------------------------------------------------------------------------------
934
935impl 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
949// -------------------------------------------------------------------------------------------------
950
951/// Iterator over frames in space order.
952pub struct FrameSpaceIterator {
953    frame: Link,
954}
955
956// -------------------------------------------------------------------------------------------------
957
958impl 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
972// -------------------------------------------------------------------------------------------------
973
974/// Iterator over frames in reversed space order.
975pub struct FrameSpaceReveresedIterator {
976    frame: Link,
977}
978
979// -------------------------------------------------------------------------------------------------
980
981impl 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// -------------------------------------------------------------------------------------------------