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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
use crate::{
    Colour,
    graphics::GraphicsSettings,
};

use glium::glutin::{
    ReleaseBehavior,
    NotCurrent,
    ContextBuilder,
    dpi::Size,
    window::{
        WindowBuilder,
        WindowAttributes,
        Fullscreen,
        Icon
    },
};

use std::{
    ops::Range,
    path::PathBuf
};

#[derive(Clone,Debug)]
#[allow(dead_code)]
pub struct WindowSettings{
    //--General attributes--\\

    /// Whether the window should be filled with given colour upon creation.
    /// 
    /// The default is None.
    pub initial_colour:Option<Colour>,

    /// The path for the mouse cursor icon.
    /// 
    /// The default is `./mouse_cursor_icon.png`.
    /// 
    /// feature = "mouse_cursor_icon"
    #[cfg(feature="mouse_cursor_icon")]
    pub mouse_cursor_icon_path:PathBuf,

    /// The range of the texture vertex buffer to save
    /// the mouse cursor vertexes.
    /// 
    /// The default is 4..8.
    /// 
    /// feature = "mouse_cursor_icon"
    #[cfg(feature="mouse_cursor_icon")]
    pub mouse_cursor_icon_range:Range<usize>,

    //--Window attributes--\\

    /// The dimensions of the window.
    /// If this is None, some platform-specific dimensions will be used.
    /// 
    /// The default is None.
    pub inner_size:Option<Size>,

    /// The minimum dimensions a window can be.
    /// If this is None, the window will have no minimum dimensions (aside from reserved).
    /// 
    /// The default is None.
    pub min_inner_size:Option<Size>,

    /// The maximum dimensions a window can be.
    /// If this is None, the maximum will have no maximum or will be set to the primary monitor's dimensions by the platform.
    /// 
    /// The default is None.
    pub max_inner_size:Option<Size>,

    /// Whether the window is resizable or not.
    /// 
    /// The default is true.
    pub resizable:bool,

    /// Whether the window should be set as fullscreen upon creation.
    /// 
    /// The default is None.
    pub fullscreen:Option<Fullscreen>,

    /// The title of the window in the title bar.
    /// 
    /// The default is "Window".
    pub title:String,

    /// Whether the window should be maximized upon creation.
    /// 
    /// The default is false.
    pub maximized:bool,

    /// Whether the window should be immediately visible upon creation.
    /// 
    /// The default is true.
    pub visible:bool,

    /// Whether the the window should be transparent.
    /// If this is true, writing colors with alpha values different than 1.0 will produce a transparent window.
    /// 
    /// The default is false.
    pub transparent:bool,

    /// Whether the window should have borders and bars.
    /// 
    /// The default is true.
    pub decorations:bool,

    /// Whether the window should always be on top of other windows.
    /// 
    /// The default is false.
    pub always_on_top:bool,

    /// The window icon.
    /// 
    /// The default is None.
    pub window_icon:Option<Icon>,



    //--OpenGL attributes--\\

    /// Whether to enable the debug flag of the context.
    /// 
    /// Debug contexts are usually slower but give better error reporting.
    /// 
    /// The default is false.
    pub debug:bool,

    /// Whether to use vsync.
    /// If vsync is enabled, calling swap_buffers will block until the screen refreshes.
    /// This is typically used to prevent screen tearing.
    /// 
    /// The default is false.
    pub vsync:bool,



    //--Pixel format requirements--\\

    /// If true, only hardware-accelerated formats will be considered.
    /// If false, only software renderers.
    /// None means "don't care".
    /// 
    /// Default is Some(true).
    pub hardware_accelerated:Option<bool>,

    /// Minimum number of bits for the color buffer, excluding alpha.
    /// None means "don't care".
    /// 
    /// The default is Some(24).
    pub color_bits:Option<u8>,

    /// If true, the color buffer must be in a floating point format.
    /// Using floating points allows you to write values outside of the [0.0, 1.0] range.
    /// 
    /// Default is false.
    pub float_color_buffer:bool,

    /// Minimum number of bits for the alpha in the color buffer.
    /// None means "don't care".
    /// 
    /// The default is Some(8).
    pub alpha_bits:Option<u8>,

    /// Minimum number of bits for the depth buffer.
    /// None means "don't care".
    /// 
    /// The default value is Some(24).
    pub depth_bits:Option<u8>,

    /// Minimum number of stencil bits.
    /// None means "don't care".
    /// 
    /// The default value is Some(8).
    pub stencil_bits:Option<u8>,

    /// If true, only double-buffered formats will be considered.
    /// If false, only single-buffer formats.
    /// None means "don't care".
    /// 
    /// The default is Some(true).
    pub double_buffer:Option<bool>,

    /// Contains the minimum number of samples per pixel in the color, depth and stencil buffers.
    /// None means "don't care".
    /// A value of Some(0) indicates that multisampling must not be enabled.
    /// 
    /// Default is None.
    pub multisampling:Option<u16>,

    /// If true, only stereoscopic formats will be considered.
    /// If false, only non-stereoscopic formats.
    /// 
    /// The default is false.
    pub stereoscopy:bool,

    /// If true, only sRGB-capable formats will be considered.
    /// If false, don't care.
    /// 
    /// The default is true.
    pub srgb:bool,


    /// The behavior when changing the current context.
    /// 
    /// Default is Flush.
    pub release_behavior:ReleaseBehavior,



    //--Local graphics attributes--\\

    /// The default is 8.
    /// 
    /// feature = "texture_graphics"
    #[cfg(feature="texture_graphics")]
    pub texture_vertex_buffer_size:usize,

    /// The default is 100.
    /// 
    /// feature = "simple_graphics"
    #[cfg(feature="simple_graphics")]
    pub simple_vertex_buffer_size:usize,

    /// The default is 2000.
    /// 
    /// feature = "text_graphics"
    #[cfg(feature="text_graphics")]
    pub text_vertex_buffer_size:usize,
}

#[allow(dead_code)]
impl WindowSettings{
    /// Default settings.
    pub fn new()->WindowSettings{

        #[cfg(feature="mouse_cursor_icon")]
        let mut path=PathBuf::new();
        #[cfg(feature="mouse_cursor_icon")]
        path.push("./mouse_cursor_icon.png");

        Self{
            //--General attributes--\\
            initial_colour:None,

            #[cfg(feature="mouse_cursor_icon")]
            mouse_cursor_icon_path:path,

            #[cfg(feature="mouse_cursor_icon")]
            mouse_cursor_icon_range:4..8,

            //--Window attributes--\\
            inner_size:None,
            min_inner_size:None,
            max_inner_size:None,
            resizable:true,
            fullscreen:None,
            title:"Window".to_string(),
            maximized:false,
            visible:true,
            transparent:true,
            decorations:true,
            always_on_top:false,
            window_icon:None,



            //--OpenGL attributes--\\
            debug:false,
            vsync:false,



            //--Pixel format requirements--\\
            hardware_accelerated:Option::None,
            color_bits:Some(24),
            float_color_buffer:false,
            alpha_bits:Some(8),
            depth_bits:Some(24),
            stencil_bits:Some(8),
            double_buffer:Some(true),
            multisampling:None,
            stereoscopy:false,
            srgb:true,
            release_behavior:ReleaseBehavior::Flush,


            //--Local graphics attributes--\\
            #[cfg(feature="texture_graphics")]
            texture_vertex_buffer_size:8usize,
            #[cfg(feature="simple_graphics")]
            simple_vertex_buffer_size:100usize,
            #[cfg(feature="text_graphics")]
            text_vertex_buffer_size:2000usize,
        }
    }

    pub (crate) fn devide<'a>(self)->(WindowBuilder,ContextBuilder<'a,NotCurrent>,GraphicsSettings){
        let window_attributes=WindowAttributes{
            inner_size:self.inner_size,
            min_inner_size:self.min_inner_size,
            max_inner_size:self.max_inner_size,
            resizable:self.resizable,
            fullscreen:self.fullscreen,
            title:self.title,
            maximized:self.maximized,
            visible:self.visible,
            transparent:self.transparent,
            decorations:self.decorations,
            always_on_top:self.always_on_top,
            window_icon:self.window_icon,
        };

        let mut window_builder=WindowBuilder::default();
        window_builder.window=window_attributes;

        let mut context_builder=ContextBuilder::new();
        context_builder.gl_attr.vsync=self.vsync;
        context_builder.gl_attr.debug=self.debug;

        context_builder.pf_reqs.hardware_accelerated=self.hardware_accelerated;
        context_builder.pf_reqs.color_bits=self.color_bits;
        context_builder.pf_reqs.float_color_buffer=self.float_color_buffer;
        context_builder.pf_reqs.alpha_bits=self.alpha_bits;
        context_builder.pf_reqs.depth_bits=self.depth_bits;
        context_builder.pf_reqs.stencil_bits=self.stencil_bits;
        context_builder.pf_reqs.double_buffer=self.double_buffer;
        context_builder.pf_reqs.multisampling=self.multisampling;
        context_builder.pf_reqs.stereoscopy=self.stereoscopy;
        context_builder.pf_reqs.srgb=self.srgb;
        context_builder.pf_reqs.release_behavior=self.release_behavior;
        
        let graphics_settings=GraphicsSettings{
            #[cfg(feature="texture_graphics")]
            texture_vertex_buffer_size:self.texture_vertex_buffer_size,
            #[cfg(feature="simple_graphics")]
            simple_vertex_buffer_size:self.simple_vertex_buffer_size,
            #[cfg(feature="text_graphics")]
            text_vertex_buffer_size:self.text_vertex_buffer_size,
        };

        (window_builder,context_builder,graphics_settings)
    }
}