GVariant.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #pragma once
  2. #include <AK/String.h>
  3. #include <LibGUI/GIcon.h>
  4. #include <LibDraw/GraphicsBitmap.h>
  5. namespace AK {
  6. class JsonValue;
  7. }
  8. class GVariant {
  9. public:
  10. GVariant();
  11. GVariant(bool);
  12. GVariant(float);
  13. GVariant(int);
  14. GVariant(unsigned);
  15. GVariant(const char*);
  16. GVariant(const String&);
  17. GVariant(const GraphicsBitmap&);
  18. GVariant(const GIcon&);
  19. GVariant(const Point&);
  20. GVariant(const Size&);
  21. GVariant(const Rect&);
  22. GVariant(const AK::JsonValue&);
  23. GVariant(Color);
  24. GVariant(const GVariant&);
  25. GVariant& operator=(const GVariant&);
  26. GVariant(GVariant&&) = delete;
  27. GVariant& operator=(GVariant&&);
  28. void clear();
  29. ~GVariant();
  30. enum class Type {
  31. Invalid,
  32. Bool,
  33. Int,
  34. UnsignedInt,
  35. Float,
  36. String,
  37. Bitmap,
  38. Color,
  39. Icon,
  40. Point,
  41. Size,
  42. Rect,
  43. };
  44. bool is_valid() const { return m_type != Type::Invalid; }
  45. bool is_bool() const { return m_type == Type::Bool; }
  46. bool is_int() const { return m_type == Type::Int; }
  47. bool is_uint() const { return m_type == Type::UnsignedInt; }
  48. bool is_float() const { return m_type == Type::Float; }
  49. bool is_string() const { return m_type == Type::String; }
  50. bool is_bitmap() const { return m_type == Type::Bitmap; }
  51. bool is_color() const { return m_type == Type::Color; }
  52. bool is_icon() const { return m_type == Type::Icon; }
  53. bool is_point() const { return m_type == Type::Point; }
  54. bool is_size() const { return m_type == Type::Size; }
  55. bool is_rect() const { return m_type == Type::Rect; }
  56. Type type() const { return m_type; }
  57. bool as_bool() const
  58. {
  59. ASSERT(type() == Type::Bool);
  60. return m_value.as_bool;
  61. }
  62. bool to_bool() const
  63. {
  64. if (type() == Type::Bool)
  65. return as_bool();
  66. if (type() == Type::String)
  67. return !!m_value.as_string;
  68. if (type() == Type::Int)
  69. return m_value.as_int != 0;
  70. if (type() == Type::UnsignedInt)
  71. return m_value.as_uint != 0;
  72. if (type() == Type::Rect)
  73. return !as_rect().is_null();
  74. if (type() == Type::Size)
  75. return !as_size().is_null();
  76. if (type() == Type::Point)
  77. return !as_point().is_null();
  78. return is_valid();
  79. }
  80. int as_int() const
  81. {
  82. ASSERT(type() == Type::Int);
  83. return m_value.as_int;
  84. }
  85. unsigned as_uint() const
  86. {
  87. ASSERT(type() == Type::UnsignedInt);
  88. return m_value.as_uint;
  89. }
  90. int to_int() const
  91. {
  92. if (is_int())
  93. return as_int();
  94. if (is_bool())
  95. return as_bool() ? 1 : 0;
  96. if (is_float())
  97. return (int)as_float();
  98. if (is_uint()) {
  99. ASSERT(as_uint() <= INT32_MAX);
  100. return (int)as_uint();
  101. }
  102. if (is_string()) {
  103. bool ok;
  104. int value = as_string().to_int(ok);
  105. if (!ok)
  106. return 0;
  107. return value;
  108. }
  109. return 0;
  110. }
  111. float as_float() const
  112. {
  113. ASSERT(type() == Type::Float);
  114. return m_value.as_float;
  115. }
  116. Point as_point() const
  117. {
  118. return { m_value.as_point.x, m_value.as_point.y };
  119. }
  120. Size as_size() const
  121. {
  122. return { m_value.as_size.width, m_value.as_size.height };
  123. }
  124. Rect as_rect() const
  125. {
  126. return { as_point(), as_size() };
  127. }
  128. String as_string() const
  129. {
  130. ASSERT(type() == Type::String);
  131. return m_value.as_string;
  132. }
  133. const GraphicsBitmap& as_bitmap() const
  134. {
  135. ASSERT(type() == Type::Bitmap);
  136. return *m_value.as_bitmap;
  137. }
  138. GIcon as_icon() const
  139. {
  140. ASSERT(type() == Type::Icon);
  141. return GIcon(*m_value.as_icon);
  142. }
  143. Color as_color() const
  144. {
  145. ASSERT(type() == Type::Color);
  146. return Color::from_rgba(m_value.as_color);
  147. }
  148. Color to_color(Color default_value = {}) const
  149. {
  150. if (type() == Type::Color)
  151. return as_color();
  152. if (type() == Type::String) {
  153. auto color = Color::from_string(as_string());
  154. if (color.has_value())
  155. return color.value();
  156. }
  157. return default_value;
  158. }
  159. String to_string() const;
  160. bool operator==(const GVariant&) const;
  161. bool operator<(const GVariant&) const;
  162. private:
  163. void copy_from(const GVariant&);
  164. struct RawPoint {
  165. int x;
  166. int y;
  167. };
  168. struct RawSize {
  169. int width;
  170. int height;
  171. };
  172. struct RawRect {
  173. RawPoint location;
  174. RawSize size;
  175. };
  176. union {
  177. StringImpl* as_string;
  178. GraphicsBitmap* as_bitmap;
  179. GIconImpl* as_icon;
  180. bool as_bool;
  181. int as_int;
  182. unsigned as_uint;
  183. float as_float;
  184. RGBA32 as_color;
  185. RawPoint as_point;
  186. RawSize as_size;
  187. RawRect as_rect;
  188. } m_value;
  189. Type m_type { Type::Invalid };
  190. };
  191. const char* to_string(GVariant::Type);