freya_winit/
config.rs

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
use std::io::Cursor;

use freya_core::{
    event_loop_messages::EventLoopMessage,
    plugins::{
        FreyaPlugin,
        PluginsManager,
    },
    style::fallback_fonts,
    window_config::WindowConfig,
};
use image::ImageReader;
use winit::{
    event_loop::EventLoopBuilder,
    window::Icon,
};

pub type EventLoopBuilderHook = Box<dyn FnOnce(&mut EventLoopBuilder<EventLoopMessage>)>;
pub type EmbeddedFonts<'a> = Vec<(&'a str, &'a [u8])>;

/// Launch configuration.
pub struct LaunchConfig<'a> {
    pub windows_configs: Vec<WindowConfig>,

    pub embedded_fonts: EmbeddedFonts<'a>,
    pub plugins: PluginsManager,
    pub fallback_fonts: Vec<String>,

    /// Hook function called with the Event Loop Builder.
    pub event_loop_builder_hook: Option<EventLoopBuilderHook>,
}

impl Default for LaunchConfig<'_> {
    fn default() -> Self {
        Self {
            windows_configs: Default::default(),
            embedded_fonts: Default::default(),
            plugins: Default::default(),
            fallback_fonts: fallback_fonts(),
            event_loop_builder_hook: None,
        }
    }
}

impl<'a> LaunchConfig<'a> {
    pub fn new() -> LaunchConfig<'a> {
        LaunchConfig::default()
    }
}

impl LaunchConfig<'_> {
    pub fn load_icon(icon: &[u8]) -> Icon {
        let reader = ImageReader::new(Cursor::new(icon))
            .with_guessed_format()
            .expect("Cursor io never fails");
        let image = reader
            .decode()
            .expect("Failed to open icon path")
            .into_rgba8();
        let (width, height) = image.dimensions();
        let rgba = image.into_raw();
        Icon::from_rgba(rgba, width, height).expect("Failed to open icon")
    }
}

impl<'a> LaunchConfig<'a> {
    /// Register a window configuration. You can call this multiple times.
    pub fn with_window(mut self, window_config: WindowConfig) -> Self {
        self.windows_configs.push(window_config);
        self
    }

    /// Embed a font.
    pub fn with_font(mut self, font_name: &'a str, font: &'a [u8]) -> Self {
        self.embedded_fonts.push((font_name, font));
        self
    }

    /// Register a fallback font. Will be used if the default fonts are not available.
    pub fn with_fallback_font(mut self, font_name: &str) -> Self {
        self.fallback_fonts.push(font_name.to_string());
        self
    }

    /// Register a default font. Will be used if found.
    pub fn with_default_font(mut self, font_name: &str) -> Self {
        self.fallback_fonts.insert(0, font_name.to_string());
        self
    }

    /// Add a new plugin.
    pub fn with_plugin(mut self, plugin: impl FreyaPlugin + 'static) -> Self {
        self.plugins.add_plugin(plugin);
        self
    }

    /// Register an Event Loop Builder hook.
    pub fn with_event_loop_builder(
        mut self,
        event_loop_builder_hook: impl FnOnce(&mut EventLoopBuilder<EventLoopMessage>) + 'static,
    ) -> Self {
        self.event_loop_builder_hook = Some(Box::new(event_loop_builder_hook));
        self
    }
}