1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef UI_AURA_WINDOW_PROPERTY_H_ 6 #define UI_AURA_WINDOW_PROPERTY_H_ 7 8 #include "base/basictypes.h" 9 #include "ui/aura/aura_export.h" 10 #include "ui/aura/window.h" 11 12 // This header should be included by code that defines WindowProperties. It 13 // should not be included by code that only gets and sets WindowProperties. 14 // 15 // To define a new WindowProperty: 16 // 17 // #include "foo/foo_export.h" 18 // #include "ui/aura/window_property.h" 19 // 20 // DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(FOO_EXPORT, MyType); 21 // namespace foo { 22 // // Use this to define an exported property that is premitive, 23 // // or a pointer you don't want automatically deleted. 24 // DEFINE_WINDOW_PROPERTY_KEY(MyType, kMyKey, MyDefault); 25 // 26 // // Use this to define an exported property whose value is a heap 27 // // allocated object, and has to be owned and freed by the window. 28 // DEFINE_OWNED_WINDOW_PROPERTY_KEY(gfx::Rect, kRestoreBoundsKey, NULL); 29 // 30 // // Use this to define a non exported property that is primitive, 31 // // or a pointer you don't want to automatically deleted, and is used 32 // // only in a specific file. This will define the property in an unnamed 33 // // namespace which cannot be accessed from another file. 34 // DEFINE_LOCAL_WINDOW_PROPERTY_KEY(MyType, kMyKey, MyDefault); 35 // 36 // } // foo namespace 37 // 38 // To define a new type used for WindowProperty. 39 // 40 // // outside all namespaces: 41 // DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(FOO_EXPORT, MyType) 42 // 43 // If a property type is not exported, use DECLARE_WINDOW_PROPERTY_TYPE(MyType) 44 // which is a shorthand for DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(, MyType). 45 46 namespace aura { 47 namespace { 48 49 // No single new-style cast works for every conversion to/from int64, so we 50 // need this helper class. A third specialization is needed for bool because 51 // MSVC warning C4800 (forcing value to bool) is not suppressed by an explicit 52 // cast (!). 53 template<typename T> 54 class WindowPropertyCaster { 55 public: 56 static int64 ToInt64(T x) { return static_cast<int64>(x); } 57 static T FromInt64(int64 x) { return static_cast<T>(x); } 58 }; 59 template<typename T> 60 class WindowPropertyCaster<T*> { 61 public: 62 static int64 ToInt64(T* x) { return reinterpret_cast<int64>(x); } 63 static T* FromInt64(int64 x) { return reinterpret_cast<T*>(x); } 64 }; 65 template<> 66 class WindowPropertyCaster<bool> { 67 public: 68 static int64 ToInt64(bool x) { return static_cast<int64>(x); } 69 static bool FromInt64(int64 x) { return x != 0; } 70 }; 71 72 } // namespace 73 74 template<typename T> 75 struct WindowProperty { 76 T default_value; 77 const char* name; 78 Window::PropertyDeallocator deallocator; 79 }; 80 81 template<typename T> 82 void Window::SetProperty(const WindowProperty<T>* property, T value) { 83 int64 old = SetPropertyInternal( 84 property, 85 property->name, 86 value == property->default_value ? NULL : property->deallocator, 87 WindowPropertyCaster<T>::ToInt64(value), 88 WindowPropertyCaster<T>::ToInt64(property->default_value)); 89 if (property->deallocator && 90 old != WindowPropertyCaster<T>::ToInt64(property->default_value)) { 91 (*property->deallocator)(old); 92 } 93 } 94 95 template<typename T> 96 T Window::GetProperty(const WindowProperty<T>* property) const { 97 return WindowPropertyCaster<T>::FromInt64(GetPropertyInternal( 98 property, WindowPropertyCaster<T>::ToInt64(property->default_value))); 99 } 100 101 template<typename T> 102 void Window::ClearProperty(const WindowProperty<T>* property) { 103 SetProperty(property, property->default_value); 104 } 105 106 } // namespace aura 107 108 // Macros to instantiate the property getter/setter template functions. 109 #define DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(EXPORT, T) \ 110 template EXPORT void aura::Window::SetProperty( \ 111 const aura::WindowProperty<T >*, T); \ 112 template EXPORT T aura::Window::GetProperty( \ 113 const aura::WindowProperty<T >*) const; \ 114 template EXPORT void aura::Window::ClearProperty( \ 115 const aura::WindowProperty<T >*); 116 #define DECLARE_WINDOW_PROPERTY_TYPE(T) \ 117 DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(, T) 118 119 #define DEFINE_WINDOW_PROPERTY_KEY(TYPE, NAME, DEFAULT) \ 120 COMPILE_ASSERT(sizeof(TYPE) <= sizeof(int64), property_type_too_large); \ 121 namespace { \ 122 const aura::WindowProperty<TYPE> NAME ## _Value = {DEFAULT, #NAME, NULL}; \ 123 } \ 124 const aura::WindowProperty<TYPE>* const NAME = & NAME ## _Value; 125 126 #define DEFINE_LOCAL_WINDOW_PROPERTY_KEY(TYPE, NAME, DEFAULT) \ 127 COMPILE_ASSERT(sizeof(TYPE) <= sizeof(int64), property_type_too_large); \ 128 namespace { \ 129 const aura::WindowProperty<TYPE> NAME ## _Value = {DEFAULT, #NAME, NULL}; \ 130 const aura::WindowProperty<TYPE>* const NAME = & NAME ## _Value; \ 131 } 132 133 #define DEFINE_OWNED_WINDOW_PROPERTY_KEY(TYPE, NAME, DEFAULT) \ 134 namespace { \ 135 void Deallocator ## NAME (int64 p) { \ 136 enum { type_must_be_complete = sizeof(TYPE) }; \ 137 delete aura::WindowPropertyCaster<TYPE*>::FromInt64(p); \ 138 } \ 139 const aura::WindowProperty<TYPE*> NAME ## _Value = \ 140 {DEFAULT,#NAME,&Deallocator ## NAME}; \ 141 } \ 142 const aura::WindowProperty<TYPE*>* const NAME = & NAME ## _Value; 143 144 #endif // UI_AURA_WINDOW_PROPERTY_H_ 145