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 46namespace aura { 47namespace { 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 (!). 53template<typename T> 54class 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}; 59template<typename T> 60class 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}; 65template<> 66class 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 74template<typename T> 75struct WindowProperty { 76 T default_value; 77 const char* name; 78 Window::PropertyDeallocator deallocator; 79}; 80 81template<typename T> 82void 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 95template<typename T> 96T Window::GetProperty(const WindowProperty<T>* property) const { 97 return WindowPropertyCaster<T>::FromInt64(GetPropertyInternal( 98 property, WindowPropertyCaster<T>::ToInt64(property->default_value))); 99} 100 101template<typename T> 102void 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