15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/view_prop.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Maints the actual view, key and data. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ViewProp::Data : public base::RefCounted<ViewProp::Data> { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the Data* for the view/key pair. If |create| is false and |Get| 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has not been invoked for the view/key pair, NULL is returned. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void Get(gfx::AcceleratedWidget view, 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* key, 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool create, 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Data>* data) { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data_set_) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_set_ = new DataSet; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Data> new_data(new Data(view, key)); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataSet::const_iterator i = data_set_->find(new_data.get()); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != data_set_->end()) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = *i; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!create) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_set_->insert(new_data.get()); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = new_data.get(); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The data. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_data(void* data) { data_ = data; } 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* data() const { return data_; } 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* key() const { return key_; } 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCounted<Data>; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used to order the Data in the map. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class DataComparator { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator()(const Data* d1, const Data* d2) const { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (d1->view_ == d2->view_) ? (d1->key_ < d2->key_) : 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (d1->view_ < d2->view_); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::set<Data*, DataComparator> DataSet; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Data(gfx::AcceleratedWidget view, const char* key) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : view_(view), 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_(key), 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_(NULL) {} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Data() { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataSet::iterator i = data_set_->find(this); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Also check for equality using == as |Get| creates dummy values in order 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to look up a value. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != data_set_->end() && *i == this) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_set_->erase(i); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The existing set of Data is stored here. ~Data removes from the set. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static DataSet* data_set_; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::AcceleratedWidget view_; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* key_; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* data_; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Data); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ViewProp::Data::DataSet* ViewProp::Data::data_set_ = NULL; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ViewProp::ViewProp(gfx::AcceleratedWidget view, const char* key, void* data) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Data::Get(view, key, true, &data_); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_->set_data(data); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ViewProp::~ViewProp() { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is done to provide similar semantics to SetProp. In particular it's 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // assumed that ~ViewProp should behave as though RemoveProp was invoked. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_->set_data(NULL); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* ViewProp::GetValue(gfx::AcceleratedWidget view, const char* key) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Data> data; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Data::Get(view, key, false, &data); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data.get() ? data->data() : NULL; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ViewProp::Key() const { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data_->key(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 104