cognitive_frames/
converting.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//! This module contains extra functionality for converting `frames::Frame` to different
5//! collections.
6
7// -------------------------------------------------------------------------------------------------
8
9use std::collections::HashMap;
10
11use frame::{Frame, Mode};
12
13use qualia::{Position, SurfaceListing, SurfaceContext, WorkspaceInfo, WorkspaceState};
14
15// -------------------------------------------------------------------------------------------------
16
17/// Extension trait for `Frame` adding more displaying functionality.
18pub trait Converting {
19    /// Converts frame three to list of `SurfaceContext` suitable for drawing by renderer.
20    fn to_array(&self,
21                relative_position: Position,
22                listing: &SurfaceListing)
23                -> Vec<SurfaceContext>;
24
25    /// Converts frame tree to structure describing state of workspaces.
26    fn to_workspace_state(&self) -> WorkspaceState;
27}
28
29// -------------------------------------------------------------------------------------------------
30
31impl Converting for Frame {
32    // TODO: Maybe make generic over `SurfaceListing`?
33    // TODO: Do not allocate so much. Make benchmarks?
34    fn to_array(&self,
35                relative_position: Position,
36                listing: &SurfaceListing)
37                -> Vec<SurfaceContext> {
38        let mut result = Vec::new();
39        for frame in self.time_iter() {
40            if let Mode::Workspace{is_active} = frame.get_mode() {
41                if !is_active {
42                    continue;
43                }
44            }
45
46            let pos = relative_position + frame.get_position();
47            if frame.get_sid().is_valid() {
48                if let Some(ref mut array) = listing.get_renderer_context(frame.get_sid()) {
49                    for ref mut c in array.iter().rev() {
50                        result.push(c.moved(pos));
51                    }
52                }
53            } else {
54                result.append(&mut frame.to_array(pos, listing));
55            }
56        }
57        result
58    }
59
60    fn to_workspace_state(&self) -> WorkspaceState {
61        let mut state = WorkspaceState::empty();
62        root_to_displays(self, &mut state.workspaces);
63        state
64    }
65}
66
67// -------------------------------------------------------------------------------------------------
68
69fn root_to_displays(frame: &Frame, displays: &mut HashMap<i32, Vec<WorkspaceInfo>>) {
70    if let Mode::Display{id} = frame.get_mode() {
71        let mut workspaces = Vec::new();
72        display_to_workspaces(frame, &mut workspaces);
73        workspaces.sort();
74        displays.insert(id, workspaces);
75    } else {
76        for subframe in frame.space_iter() {
77            root_to_displays(&subframe, displays);
78        }
79    }
80}
81
82// -------------------------------------------------------------------------------------------------
83
84fn display_to_workspaces(frame: &Frame, workspaces: &mut Vec<WorkspaceInfo>) {
85    if let Mode::Workspace{is_active} = frame.get_mode() {
86        workspaces.push(WorkspaceInfo::new(frame.get_title(), is_active));
87    } else {
88        for subframe in frame.space_iter() {
89            display_to_workspaces(&subframe, workspaces);
90        }
91    }
92}
93
94// -------------------------------------------------------------------------------------------------