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
// Pushrod Rendering Library
// Widget Configuration Store
//
// 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 sdl2::pixels::Color;
use std::collections::HashMap;

/// `Widget` Base `Color` key for `colors` `HashMap`.  This is the base fill color of a `Widget`
/// that is in an unselected state.
pub const COLOR_BASE: u8 = 0;

/// `Widget` Border `Color` key for `colors` `HashMap`.  This should be used for the color of the
/// border, if the `Widget` draws a border.
pub const COLOR_BORDER: u8 = 1;

/// `Widget` Text `Color` key for `colors` `HashMap`.  This should be the color for the text being
/// displayed inside the `Widget`.
pub const COLOR_TEXT: u8 = 2;

/// `Widget` Selected `Color` key for `colors` `HashMap`.  This is the color the `Widget` should
/// display when in selected state.
pub const COLOR_SELECTED: u8 = 3;

/// `Widget` Secondary `Color` key for `colors` `HashMap`.  This is the color the `Widget` should
/// display for any secondary properties, such as a fill color for a progress widget, a spinner,
/// etc.
pub const COLOR_SECONDARY: u8 = 4;

/// This is the store for the `WidgetConfig`, which each `Widget` object needs.  This stores
/// information about the `Widget`.  It currently contains the point of origin, size, a `HashMap` of
/// different `Color`s, a border width, and an invalidation flag.
pub struct WidgetConfig {
    /// This `Vec` contains two points of origin: the physical X and Y coordinates in the
    /// `Canvas`.
    pub origin: Vec<i32>,

    /// This `Vec` contains the width and height of the object.
    pub size: Vec<u32>,

    /// This `HashMap` contains a key/value pair containing colors for the `Widget`.
    pub colors: HashMap<u8, Color>,

    /// This is the border width in pixels.
    pub border_width: u8,

    /// `Widget`'s redraw flag.  Set `true` if the object needs to be redrawn, `false` otherwise.
    invalidated: bool,
}

/// This is the implementation of the `WidgetConfig`.
impl WidgetConfig {
    /// Constructor - takes the X, Y, W, and H coordinates of the `Widget`, physically in the
    /// main `Canvas`.
    pub fn new(x: i32, y: i32, w: u32, h: u32) -> Self {
        Self {
            origin: vec![x, y],
            size: vec![w, h],
            colors: [(COLOR_BASE, Color::RGB(255, 255, 255))]
                .iter()
                .cloned()
                .collect(),
            border_width: 0,
            invalidated: true,
        }
    }

    /// Converts an X point to the physical X point on the `Canvas` plus the point of origin.
    /// Returns `i32` containing the modified X coordinate.  This is a convenience method for the
    /// `Widget` to draw based on a 0x0 point of origin.
    pub fn to_x(&self, x: i32) -> i32 {
        self.origin[0] + x
    }

    /// Converts a Y point to the physical Y point on the `Canvas` plus the point of origin.
    /// Returns `i32` containing the modified Y coordinate.  This is a convenience method for the
    /// `Widget` to draw based on a 0x0 point of origin.
    pub fn to_y(&self, y: i32) -> i32 {
        self.origin[1] + y
    }

    /// Sets the invalidation state of the `Widget`, telling the `Engine` that the `Widget`
    /// contents has changed, and must be redrawn.  Setting the `flag` to `true` indicates that
    /// the `Widget` needs to be redrawn on the screen, `false` indicates that it its state has
    /// not changed, and its image can be pulled from a buffer if necessary, skipping the `draw`
    /// call.
    pub fn set_invalidate(&mut self, flag: bool) {
        self.invalidated = flag;
    }

    /// Returns the `invalidation` state.  Returns a `bool` containing the state.
    pub fn invalidated(&self) -> bool {
        self.invalidated
    }
}