Serenity Operating System
at hosted 285 lines 7.3 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#pragma once 28 29#include <AK/String.h> 30#include <LibGfx/Font.h> 31#include <LibGfx/Bitmap.h> 32#include <LibGUI/Icon.h> 33 34namespace GUI { 35 36class Variant { 37public: 38 Variant(); 39 Variant(bool); 40 Variant(float); 41 Variant(i32); 42 Variant(i64); 43 Variant(unsigned); 44 Variant(const char*); 45 Variant(const String&); 46 Variant(const FlyString&); 47 Variant(const Gfx::Bitmap&); 48 Variant(const GUI::Icon&); 49 Variant(const Gfx::Point&); 50 Variant(const Gfx::Size&); 51 Variant(const Gfx::Rect&); 52 Variant(const Gfx::Font&); 53 Variant(const AK::JsonValue&); 54 Variant(Color); 55 56 Variant(const Variant&); 57 Variant& operator=(const Variant&); 58 59 Variant(Variant&&) = delete; 60 Variant& operator=(Variant&&); 61 62 void clear(); 63 ~Variant(); 64 65 enum class Type { 66 Invalid, 67 Bool, 68 Int32, 69 Int64, 70 UnsignedInt, 71 Float, 72 String, 73 Bitmap, 74 Color, 75 Icon, 76 Point, 77 Size, 78 Rect, 79 Font, 80 }; 81 82 bool is_valid() const { return m_type != Type::Invalid; } 83 bool is_bool() const { return m_type == Type::Bool; } 84 bool is_i32() const { return m_type == Type::Int32; } 85 bool is_i64() const { return m_type == Type::Int64; } 86 bool is_uint() const { return m_type == Type::UnsignedInt; } 87 bool is_float() const { return m_type == Type::Float; } 88 bool is_string() const { return m_type == Type::String; } 89 bool is_bitmap() const { return m_type == Type::Bitmap; } 90 bool is_color() const { return m_type == Type::Color; } 91 bool is_icon() const { return m_type == Type::Icon; } 92 bool is_point() const { return m_type == Type::Point; } 93 bool is_size() const { return m_type == Type::Size; } 94 bool is_rect() const { return m_type == Type::Rect; } 95 bool is_font() const { return m_type == Type::Font; } 96 Type type() const { return m_type; } 97 98 bool as_bool() const 99 { 100 ASSERT(type() == Type::Bool); 101 return m_value.as_bool; 102 } 103 104 bool to_bool() const 105 { 106 if (type() == Type::Bool) 107 return as_bool(); 108 if (type() == Type::String) 109 return !!m_value.as_string; 110 if (type() == Type::Int32) 111 return m_value.as_i32 != 0; 112 if (type() == Type::Int64) 113 return m_value.as_i64 != 0; 114 if (type() == Type::UnsignedInt) 115 return m_value.as_uint != 0; 116 if (type() == Type::Rect) 117 return !as_rect().is_null(); 118 if (type() == Type::Size) 119 return !as_size().is_null(); 120 if (type() == Type::Point) 121 return !as_point().is_null(); 122 return is_valid(); 123 } 124 125 int as_i32() const 126 { 127 ASSERT(type() == Type::Int32); 128 return m_value.as_i32; 129 } 130 131 int as_i64() const 132 { 133 ASSERT(type() == Type::Int64); 134 return m_value.as_i64; 135 } 136 137 unsigned as_uint() const 138 { 139 ASSERT(type() == Type::UnsignedInt); 140 return m_value.as_uint; 141 } 142 143 template<typename T> 144 T to_integer() const 145 { 146 if (is_i32()) 147 return as_i32(); 148 if (is_i64()) 149 return as_i64(); 150 if (is_bool()) 151 return as_bool() ? 1 : 0; 152 if (is_float()) 153 return (int)as_float(); 154 if (is_uint()) { 155 ASSERT(as_uint() <= INT32_MAX); 156 return (int)as_uint(); 157 } 158 if (is_string()) { 159 bool ok; 160 int value = as_string().to_int(ok); 161 if (!ok) 162 return 0; 163 return value; 164 } 165 return 0; 166 } 167 168 i32 to_i32() const 169 { 170 return to_integer<i32>(); 171 } 172 173 i64 to_i64() const 174 { 175 return to_integer<i64>(); 176 } 177 178 float as_float() const 179 { 180 ASSERT(type() == Type::Float); 181 return m_value.as_float; 182 } 183 184 Gfx::Point as_point() const 185 { 186 return { m_value.as_point.x, m_value.as_point.y }; 187 } 188 189 Gfx::Size as_size() const 190 { 191 return { m_value.as_size.width, m_value.as_size.height }; 192 } 193 194 Gfx::Rect as_rect() const 195 { 196 return { as_point(), as_size() }; 197 } 198 199 String as_string() const 200 { 201 ASSERT(type() == Type::String); 202 return m_value.as_string; 203 } 204 205 const Gfx::Bitmap& as_bitmap() const 206 { 207 ASSERT(type() == Type::Bitmap); 208 return *m_value.as_bitmap; 209 } 210 211 GUI::Icon as_icon() const 212 { 213 ASSERT(type() == Type::Icon); 214 return GUI::Icon(*m_value.as_icon); 215 } 216 217 Color as_color() const 218 { 219 ASSERT(type() == Type::Color); 220 return Color::from_rgba(m_value.as_color); 221 } 222 223 const Gfx::Font& as_font() const 224 { 225 ASSERT(type() == Type::Font); 226 return *m_value.as_font; 227 } 228 229 Color to_color(Color default_value = {}) const 230 { 231 if (type() == Type::Color) 232 return as_color(); 233 if (type() == Type::String) { 234 auto color = Color::from_string(as_string()); 235 if (color.has_value()) 236 return color.value(); 237 } 238 return default_value; 239 } 240 241 String to_string() const; 242 243 bool operator==(const Variant&) const; 244 bool operator<(const Variant&) const; 245 246private: 247 void copy_from(const Variant&); 248 249 struct RawPoint { 250 int x; 251 int y; 252 }; 253 254 struct RawSize { 255 int width; 256 int height; 257 }; 258 259 struct RawRect { 260 RawPoint location; 261 RawSize size; 262 }; 263 264 union { 265 StringImpl* as_string; 266 Gfx::Bitmap* as_bitmap; 267 GUI::IconImpl* as_icon; 268 Gfx::Font* as_font; 269 bool as_bool; 270 i32 as_i32; 271 i64 as_i64; 272 unsigned as_uint; 273 float as_float; 274 Gfx::RGBA32 as_color; 275 RawPoint as_point; 276 RawSize as_size; 277 RawRect as_rect; 278 } m_value; 279 280 Type m_type { Type::Invalid }; 281}; 282 283const char* to_string(Variant::Type); 284 285}