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
// Configurable Implementation
//
// 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 piston_window::types::Color;
use std::collections::HashMap;

use crate::core::point::Point;

/// A programmatic type identifying the type of key (and most importantly, size) that is used
/// for storing configuration values for a `Widget` in the config `HashMap`.
pub type ConfigKey = u8;

/// Config entry key for invalidated object (invalidated means "requires screen refresh")
pub const CONFIG_INVALIDATE: u8 = 0;

/// Config entry key for retrieving the `Point` of origin.
pub const CONFIG_ORIGIN: u8 = 1;

/// Config entry key for retrieving the `Size` of the widget.
pub const CONFIG_SIZE: u8 = 2;

/// Config entry key for autoclipping the widget's drawing area.
pub const CONFIG_AUTOCLIP: u8 = 3;

/// Config entry key for retrieving the widget's color.
pub const CONFIG_COLOR: u8 = 4;

/// Config entry key for retrieving the widget's border color.
pub const CONFIG_COLOR_BORDER: u8 = 5;

/// Config entry key for retrieving the widget's border width.
pub const CONFIG_BORDER_WIDTH: u8 = 6;

/// Config entry key for retrieving the widget's text color.
pub const CONFIG_TEXT_COLOR: u8 = 7;

/// Enumeration data type containing storage areas for each configuration object.
pub enum WidgetConfig {
    /// Indicates that a widget's paint contents have become invalidated, and need to be redrawn.
    Invalidate {},

    /// `Point` of origin of this Widget.
    Origin { point: Point },

    /// `Size` of this widget.
    Size { size: crate::core::point::Size },

    /// Indicates whether or not to automatically clip the drawing area to the bounds of the
    /// widget.
    Autoclip { clip: bool },

    /// The `types::Color` of this widget: `[f64; 4]` where the values are
    /// `[red, green, blue, transparency]`, values between 0 and 1.0.
    Color { color: Color },

    /// The `types::Color` of the border of this widget: `[f64; 4]` where the values are
    /// `[red, green, blue, transparency]`, values between 0 and 1.0.
    BorderColor { color: Color },

    /// Indicates the thickness of the border width to be drawn inside widgets that draw a
    /// border.  (See `BorderColor`.)
    BorderWidth { thickness: u8 },

    /// The `types::Color` of the text for thsi widget: `[f64; 4]` where the values are
    /// `[red, green, blue, transparency]`, values between 0 and 1.0.
    TextColor { color: Color },
}

/// This structure is used for the configuration store of `Widget` settings.  It contains its
/// own structure internally, so all that is used inside extended `Widget` objects is a simple
/// instantiation of a new `Configurable` object as part of your extension.
pub struct Configurable {
    config: HashMap<ConfigKey, WidgetConfig>,
}

/// Implementation of the `Configurable` object.  Contains methods to extend the `HashMap` that
/// is used for underlying storage.
impl Configurable {
    /// Creates a new instance of this object.
    pub fn new() -> Self {
        Self {
            config: HashMap::new(),
        }
    }

    /// Sets a configuration key by its `ConfigKey` ID, assigning a new `WidgetConfig` value
    /// to that key.
    pub fn set(&mut self, key: ConfigKey, value: WidgetConfig) {
        self.config.insert(key, value);
    }

    /// Retrieves an `Option<&WidgetConfig>` for the key specified.  If the key does not exist,
    /// a `None` is returned.
    pub fn get(&self, key: ConfigKey) -> Option<&WidgetConfig> {
        self.config.get(&key)
    }

    /// Removes the value for the specified key, if one exists.
    pub fn remove(&mut self, key: ConfigKey) {
        self.config.remove(&key);
    }

    /// Indicates whether or not a `Configurable` store contains a value for the specified key.
    /// Returns `true` if one is stored, `false` otherwise.
    pub fn contains_key(&self, key: ConfigKey) -> bool {
        self.config.contains_key(&key)
    }
}