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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use crate::ui::prelude::*;
use buffer_graphics_lib::Graphics;
use rustc_hash::FxHashMap;
use std::hash::Hash;

pub struct ToggleButtonGroup<Key: Hash + Clone + PartialEq + Eq> {
    buttons: FxHashMap<Key, ToggleButton>,
    selected: Key,
}

impl<Key: Hash + Clone + PartialEq + Eq> ToggleButtonGroup<Key> {
    pub fn new(id_button_map: Vec<(Key, ToggleButton)>) -> Self {
        let mut buttons = FxHashMap::default();
        let first = id_button_map.first().unwrap().0.clone();
        for (id, button) in id_button_map.into_iter() {
            buttons.insert(id.clone(), button);
        }
        let mut group = Self {
            buttons,
            selected: first.clone(),
        };
        group.set_selected(first);
        group
    }
}

impl<Key: Hash + Clone + PartialEq + Eq> ToggleButtonGroup<Key> {
    pub fn on_mouse_click(&mut self, down: Coord, up: Coord) -> Option<Key> {
        let mut tmp = None;
        for (idx, button) in &mut self.buttons {
            if button.on_mouse_click(down, up) {
                tmp = Some(idx.clone());
            }
        }
        if let Some(key) = &tmp {
            self.selected = key.clone();
        }
        if let Some(id) = &tmp {
            for (idx, button) in &mut self.buttons {
                button.set_selected(idx == id);
            }
        }
        tmp
    }

    pub fn get(&self, key: Key) -> &ToggleButton {
        &self.buttons[&key]
    }

    pub fn render(&self, graphics: &mut Graphics, mouse: &MouseData) {
        for button in self.buttons.values() {
            button.render(graphics, mouse);
        }
    }

    pub fn get_selected(&self) -> &Key {
        &self.selected
    }

    pub fn set_selected(&mut self, id: Key) {
        for (idx, button) in &mut self.buttons {
            button.set_selected(idx == &id);
        }
        self.selected = id;
    }
}

pub struct ToggleIconButtonGroup<Key: Hash + Clone + PartialEq + Eq> {
    buttons: FxHashMap<Key, ToggleIconButton>,
    selected: Key,
}

impl<Key: Hash + Clone + PartialEq + Eq> ToggleIconButtonGroup<Key> {
    pub fn new(id_button_map: Vec<(Key, ToggleIconButton)>) -> Self {
        let mut buttons = FxHashMap::default();
        let first = id_button_map.first().unwrap().0.clone();
        for (id, button) in id_button_map.into_iter() {
            buttons.insert(id.clone(), button);
        }
        let mut group = Self {
            buttons,
            selected: first.clone(),
        };
        group.set_selected(first);
        group
    }
}

impl<Key: Hash + Clone + PartialEq + Eq> ToggleIconButtonGroup<Key> {
    pub fn on_mouse_click(&mut self, down: Coord, up: Coord) -> Option<Key> {
        let mut tmp = None;
        for (idx, button) in &mut self.buttons {
            if button.on_mouse_click(down, up) {
                tmp = Some(idx.clone());
            }
        }
        if let Some(key) = &tmp {
            self.selected = key.clone();
        }
        if let Some(id) = &tmp {
            for (idx, button) in &mut self.buttons {
                button.set_selected(idx == id);
            }
        }
        tmp
    }

    pub fn get(&self, key: Key) -> &ToggleIconButton {
        &self.buttons[&key]
    }

    pub fn render(&self, graphics: &mut Graphics, mouse: &MouseData) {
        for button in self.buttons.values() {
            button.render(graphics, mouse);
        }
    }

    pub fn get_selected(&self) -> &Key {
        &self.selected
    }

    pub fn set_selected(&mut self, id: Key) {
        for (idx, button) in &mut self.buttons {
            button.set_selected(idx == &id);
        }
        self.selected = id;
    }
}