summaryrefslogtreecommitdiffstats
path: root/zellij-server/src/panes/active_panes.rs
blob: 039c71c61fa483e56e483340753204a666e0dffc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use crate::tab::Pane;

use crate::{os_input_output::ServerOsApi, panes::PaneId, ClientId};
use std::collections::{BTreeMap, HashMap};

#[derive(Clone)]
pub struct ActivePanes {
    active_panes: HashMap<ClientId, PaneId>,
    os_api: Box<dyn ServerOsApi>,
}

impl ActivePanes {
    pub fn new(os_api: &Box<dyn ServerOsApi>) -> Self {
        let os_api = os_api.clone();
        ActivePanes {
            active_panes: HashMap::new(),
            os_api,
        }
    }
    pub fn get(&self, client_id: &ClientId) -> Option<&PaneId> {
        self.active_panes.get(client_id)
    }
    pub fn insert(
        &mut self,
        client_id: ClientId,
        pane_id: PaneId,
        panes: &mut BTreeMap<PaneId, Box<dyn Pane>>,
    ) {
        self.unfocus_pane_for_client(client_id, panes);
        self.active_panes.insert(client_id, pane_id);
        self.focus_pane(pane_id, panes);
    }
    pub fn clear(&mut self, panes: &mut BTreeMap<PaneId, Box<dyn Pane>>) {
        for pane_id in self.active_panes.values() {
            self.unfocus_pane(*pane_id, panes);
        }
        self.active_panes.clear();
    }
    pub fn is_empty(&self) -> bool {
        self.active_panes.is_empty()
    }
    pub fn iter(&self) -> impl Iterator<Item = (&ClientId, &PaneId)> {
        self.active_panes.iter()
    }
    pub fn values(&self) -> impl Iterator<Item = &PaneId> {
        self.active_panes.values()
    }
    pub fn remove(
        &mut self,
        client_id: &ClientId,
        panes: &mut BTreeMap<PaneId, Box<dyn Pane>>,
    ) -> Option<PaneId> {
        if let Some(pane_id_to_unfocus) = self.active_panes.get(&client_id) {
            self.unfocus_pane(*pane_id_to_unfocus, panes);
        }
        self.active_panes.remove(client_id)
    }
    pub fn unfocus_all_panes(&self, panes: &mut BTreeMap<PaneId, Box<dyn Pane>>) {
        for (_client_id, pane_id) in &self.active_panes {
            self.unfocus_pane(*pane_id, panes);
        }
    }
    pub fn focus_all_panes(&self, panes: &mut BTreeMap<PaneId, Box<dyn Pane>>) {
        for (_client_id, pane_id) in &self.active_panes {
            self.focus_pane(*pane_id, panes);
        }
    }
    pub fn clone_active_panes(&self) -> HashMap<ClientId, PaneId> {
        self.active_panes.clone()
    }
    pub fn contains_key(&self, client_id: &ClientId) -> bool {
        self.active_panes.contains_key(client_id)
    }
    fn unfocus_pane_for_client(
        &self,
        client_id: ClientId,
        panes: &mut BTreeMap<PaneId, Box<dyn Pane>>,
    ) {
        if let Some(pane_id_to_unfocus) = self.active_panes.get(&client_id) {
            self.unfocus_pane(*pane_id_to_unfocus, panes);
        }
    }
    fn unfocus_pane(&self, pane_id: PaneId, panes: &mut BTreeMap<PaneId, Box<dyn Pane>>) {
        if let PaneId::Terminal(terminal_id) = pane_id {
            if let Some(focus_event) = panes.get(&pane_id).and_then(|p| p.unfocus_event()) {
                let _ = self
                    .os_api
                    .write_to_tty_stdin(terminal_id, focus_event.as_bytes());
            }
        }
    }
    fn focus_pane(&self, pane_id: PaneId, panes: &mut BTreeMap<PaneId, Box<dyn Pane>>) {
        if let PaneId::Terminal(terminal_id) = pane_id {
            if let Some(focus_event) = panes.get(&pane_id).and_then(|p| p.focus_event()) {
                let _ = self
                    .os_api
                    .write_to_tty_stdin(terminal_id, focus_event.as_bytes());
            }
        }
    }
    pub fn pane_id_is_focused(&self, pane_id: &PaneId) -> bool {
        self.active_panes
            .values()
            .find(|p_id| **p_id == *pane_id)
            .is_some()
    }
}