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
// Pushrod Events
// Drawing Primitives
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::properties::{
    WidgetProperties, PROPERTY_BORDER_COLOR, PROPERTY_BORDER_WIDTH, PROPERTY_MAIN_COLOR,
};
use sdl2::pixels::Color;
use sdl2::rect::Rect;
use sdl2::render::Canvas;
use sdl2::video::Window;
use sdl2::Sdl;
use sdl2::VideoSubsystem;

/// Initializes an application given a title window, width, and height for the main window.  Returns
/// the initialized `Sdl` context, the `VideoSubsystem` instance, and the reference to the
/// `Window`.
pub fn init_application(title: &str, w: u32, h: u32) -> (Sdl, VideoSubsystem, Window) {
    let sdl_context = sdl2::init().unwrap();
    let video_subsystem = sdl_context.video().unwrap();
    let window = video_subsystem
        .window(title, w, h)
        .position_centered()
        .opengl()
        .build()
        .unwrap();

    (sdl_context, video_subsystem, window)
}

/// Draws the base of the `Widget`, using the main color (background color), the border color, and
/// border width.
pub fn draw_base(canvas: &mut Canvas<Window>, p: &WidgetProperties, alt_color: Option<Color>) {
    // This is the fill color for this Widget.
    let base_color =
        alt_color.unwrap_or_else(|| p.get_color(PROPERTY_MAIN_COLOR, Color::RGB(255, 255, 255)));

    // This is the border paint color.
    let border_color = p.get_color(PROPERTY_BORDER_COLOR, Color::RGB(0, 0, 0));
    let bounds = p.get_bounds();

    // Border width
    let border_width = p.get_value(PROPERTY_BORDER_WIDTH);

    // Fill the texture
    canvas.set_draw_color(base_color);
    canvas.clear();

    if border_width > 0 {
        // Draw the border with the color of the border
        canvas.set_draw_color(border_color);

        for border_width_count in 0..border_width {
            canvas
                .draw_rect(Rect::new(
                    border_width_count,
                    border_width_count,
                    bounds.0 - (border_width_count * 2) as u32,
                    bounds.1 - (border_width_count * 2) as u32,
                ))
                .unwrap();
        }
    }
}

/// Fills a bounding rectangle (x, y, w, h) with the specified `Color`.
pub fn fill_box(canvas: &mut Canvas<Window>, x: u32, y: u32, w: u32, h: u32, color: Color) {
    canvas.set_draw_color(color);
    canvas
        .fill_rect(Rect::new(x as i32, y as i32, w, h))
        .unwrap();
}