| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/cocoa/autofill/simple_grid_layout.h" | 5 #include "chrome/browser/ui/cocoa/autofill/simple_grid_layout.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| 11 #include "base/logging.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/stl_util.h" | |
| 13 | 12 |
| 14 namespace { | 13 namespace { |
| 15 const int kAutoColumnIdStart = 1000000; // Starting ID for autogeneration. | 14 const int kAutoColumnIdStart = 1000000; // Starting ID for autogeneration. |
| 16 } | 15 } |
| 17 | 16 |
| 18 // Encapsulates state for a single NSView in the layout | 17 // Encapsulates state for a single NSView in the layout |
| 19 class ViewState { | 18 class ViewState { |
| 20 public: | 19 public: |
| 21 ViewState(NSView* view, ColumnSet* column_set, int row, int column); | 20 ViewState(NSView* view, ColumnSet* column_set, int row, int column); |
| 22 | 21 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 40 int column_; | 39 int column_; |
| 41 float pref_height_; | 40 float pref_height_; |
| 42 }; | 41 }; |
| 43 | 42 |
| 44 class LayoutElement { | 43 class LayoutElement { |
| 45 public: | 44 public: |
| 46 LayoutElement(float resize_percent, int fixed_width); | 45 LayoutElement(float resize_percent, int fixed_width); |
| 47 virtual ~LayoutElement() {} | 46 virtual ~LayoutElement() {} |
| 48 | 47 |
| 49 template <class T> | 48 template <class T> |
| 50 static void ResetSizes(ScopedVector<T>* elements) { | 49 static void ResetSizes(std::vector<std::unique_ptr<T>>* elements) { |
| 51 // Reset the layout width of each column. | 50 // Reset the layout width of each column. |
| 52 for (typename std::vector<T*>::iterator i = elements->begin(); | 51 for (const auto& element : *elements) |
| 53 i != elements->end(); ++i) { | 52 element->ResetSize(); |
| 54 (*i)->ResetSize(); | 53 } |
| 54 |
| 55 template <class T> |
| 56 static void CalculateLocationsFromSize( |
| 57 std::vector<std::unique_ptr<T>>* elements) { |
| 58 // Reset the layout width of each column. |
| 59 int location = 0; |
| 60 for (const auto& element : *elements) { |
| 61 element->SetLocation(location); |
| 62 location += element->Size(); |
| 55 } | 63 } |
| 56 } | 64 } |
| 57 | 65 |
| 58 template <class T> | |
| 59 static void CalculateLocationsFromSize(ScopedVector<T>* elements) { | |
| 60 // Reset the layout width of each column. | |
| 61 int location = 0; | |
| 62 for (typename std::vector<T*>::iterator i = elements->begin(); | |
| 63 i != elements->end(); ++i) { | |
| 64 (*i)->SetLocation(location); | |
| 65 location += (*i)->Size(); | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 float Size() { return size_; } | 66 float Size() { return size_; } |
| 70 | 67 |
| 71 void ResetSize() { | 68 void ResetSize() { |
| 72 size_ = fixed_width_; | 69 size_ = fixed_width_; |
| 73 } | 70 } |
| 74 | 71 |
| 75 void SetSize(float size) { | 72 void SetSize(float size) { |
| 76 size_ = size; | 73 size_ = size; |
| 77 } | 74 } |
| 78 | 75 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 return NSHeight([view_ frame]); | 154 return NSHeight([view_ frame]); |
| 158 } | 155 } |
| 159 | 156 |
| 160 ColumnSet::ColumnSet(int id) : id_(id) { | 157 ColumnSet::ColumnSet(int id) : id_(id) { |
| 161 } | 158 } |
| 162 | 159 |
| 163 ColumnSet::~ColumnSet() { | 160 ColumnSet::~ColumnSet() { |
| 164 } | 161 } |
| 165 | 162 |
| 166 void ColumnSet::AddPaddingColumn(int fixed_width) { | 163 void ColumnSet::AddPaddingColumn(int fixed_width) { |
| 167 columns_.push_back(new Column(0.0f, fixed_width, true)); | 164 columns_.push_back(base::MakeUnique<Column>(0.0f, fixed_width, true)); |
| 168 } | 165 } |
| 169 | 166 |
| 170 void ColumnSet::AddColumn(float resize_percent) { | 167 void ColumnSet::AddColumn(float resize_percent) { |
| 171 columns_.push_back(new Column(resize_percent, 0, false)); | 168 columns_.push_back(base::MakeUnique<Column>(resize_percent, 0, false)); |
| 172 } | 169 } |
| 173 | 170 |
| 174 void ColumnSet::CalculateSize(float width) { | 171 void ColumnSet::CalculateSize(float width) { |
| 175 // Reset column widths | 172 // Reset column widths. |
| 176 LayoutElement::ResetSizes(&columns_); | 173 LayoutElement::ResetSizes(&columns_); |
| 177 width = CalculateRemainingWidth(width); | 174 width = CalculateRemainingWidth(width); |
| 178 DistributeRemainingWidth(width); | 175 DistributeRemainingWidth(width); |
| 179 } | 176 } |
| 180 | 177 |
| 181 void ColumnSet::ResetColumnXCoordinates() { | 178 void ColumnSet::ResetColumnXCoordinates() { |
| 182 LayoutElement::CalculateLocationsFromSize(&columns_); | 179 LayoutElement::CalculateLocationsFromSize(&columns_); |
| 183 } | 180 } |
| 184 | 181 |
| 185 float ColumnSet::CalculateRemainingWidth(float width) { | 182 float ColumnSet::CalculateRemainingWidth(float width) { |
| 186 for (size_t i = 0; i < columns_.size(); ++i) | 183 for (const auto& column : columns_) |
| 187 width -= columns_[i]->Size(); | 184 width -= column->Size(); |
| 188 | 185 |
| 189 return width; | 186 return width; |
| 190 } | 187 } |
| 191 | 188 |
| 192 void ColumnSet::DistributeRemainingWidth(float width) { | 189 void ColumnSet::DistributeRemainingWidth(float width) { |
| 193 float total_resize = 0.0f; | 190 float total_resize = 0.0f; |
| 194 int resizable_columns = 0.0; | 191 int resizable_columns = 0.0; |
| 195 | 192 |
| 196 for (size_t i = 0; i < columns_.size(); ++i) { | 193 for (const auto& column : columns_) { |
| 197 if (columns_[i]->IsResizable()) { | 194 if (column->IsResizable()) { |
| 198 total_resize += columns_[i]->ResizePercent(); | 195 total_resize += column->ResizePercent(); |
| 199 resizable_columns++; | 196 resizable_columns++; |
| 200 } | 197 } |
| 201 } | 198 } |
| 202 | 199 |
| 203 float remaining_width = width; | 200 float remaining_width = width; |
| 204 for (size_t i = 0; i < columns_.size(); ++i) { | 201 for (const auto& column : columns_) { |
| 205 if (columns_[i]->IsResizable()) { | 202 if (column->IsResizable()) { |
| 206 float delta = (resizable_columns == 0) ? remaining_width : | 203 float delta = (resizable_columns == 0) |
| 207 (width * columns_[i]->ResizePercent() / total_resize); | 204 ? remaining_width |
| 205 : (width * column->ResizePercent() / total_resize); |
| 208 remaining_width -= delta; | 206 remaining_width -= delta; |
| 209 columns_[i]->SetSize(columns_[i]->Size() + delta); | 207 column->SetSize(column->Size() + delta); |
| 210 resizable_columns--; | 208 resizable_columns--; |
| 211 } | 209 } |
| 212 } | 210 } |
| 213 } | 211 } |
| 214 | 212 |
| 215 float ColumnSet::GetColumnWidth(int column_index) { | 213 float ColumnSet::GetColumnWidth(int column_index) { |
| 216 if (column_index < 0 || column_index >= num_columns()) | 214 if (column_index < 0 || column_index >= num_columns()) |
| 217 return 0.0; | 215 return 0.0; |
| 218 return columns_[column_index]->Size(); | 216 return columns_[column_index]->Size(); |
| 219 } | 217 } |
| 220 | 218 |
| 221 float ColumnSet::ColumnLocation(int column_index) { | 219 float ColumnSet::ColumnLocation(int column_index) { |
| 222 if (column_index < 0 || column_index >= num_columns()) | 220 if (column_index < 0 || column_index >= num_columns()) |
| 223 return 0.0; | 221 return 0.0; |
| 224 return columns_[column_index]->Location(); | 222 return columns_[column_index]->Location(); |
| 225 } | 223 } |
| 226 | 224 |
| 227 SimpleGridLayout::SimpleGridLayout(NSView* host) | 225 SimpleGridLayout::SimpleGridLayout(NSView* host) |
| 228 : next_column_(0), | 226 : next_column_(0), |
| 229 current_auto_id_(kAutoColumnIdStart), | 227 current_auto_id_(kAutoColumnIdStart), |
| 230 host_(host) { | 228 host_(host) { |
| 231 [host_ frame]; | 229 [host_ frame]; |
| 232 } | 230 } |
| 233 | 231 |
| 234 SimpleGridLayout::~SimpleGridLayout() { | 232 SimpleGridLayout::~SimpleGridLayout() { |
| 235 } | 233 } |
| 236 | 234 |
| 237 ColumnSet* SimpleGridLayout::AddColumnSet(int id) { | 235 ColumnSet* SimpleGridLayout::AddColumnSet(int id) { |
| 238 DCHECK(GetColumnSet(id) == NULL); | 236 DCHECK(GetColumnSet(id) == nullptr); |
| 239 ColumnSet* column_set = new ColumnSet(id); | 237 column_sets_.push_back(base::MakeUnique<ColumnSet>(id)); |
| 240 column_sets_.push_back(column_set); | 238 return column_sets_.back().get(); |
| 241 return column_set; | |
| 242 } | 239 } |
| 243 | 240 |
| 244 ColumnSet* SimpleGridLayout::GetColumnSet(int id) { | 241 ColumnSet* SimpleGridLayout::GetColumnSet(int id) { |
| 245 for (ScopedVector<ColumnSet>::const_iterator i = column_sets_.begin(); | 242 for (const auto& column_set : column_sets_) { |
| 246 i != column_sets_.end(); ++i) { | 243 if (column_set->id() == id) { |
| 247 if ((*i)->id() == id) { | 244 return column_set.get(); |
| 248 return *i; | |
| 249 } | 245 } |
| 250 } | 246 } |
| 251 return NULL; | 247 return nullptr; |
| 252 } | 248 } |
| 253 | 249 |
| 254 void SimpleGridLayout::AddPaddingRow(int fixed_height) { | 250 void SimpleGridLayout::AddPaddingRow(int fixed_height) { |
| 255 AddRow(new Row(0.0f, fixed_height, NULL)); | 251 AddRow(base::MakeUnique<Row>(0.0f, fixed_height, nullptr)); |
| 256 } | 252 } |
| 257 | 253 |
| 258 void SimpleGridLayout::StartRow(float vertical_resize, int column_set_id) { | 254 void SimpleGridLayout::StartRow(float vertical_resize, int column_set_id) { |
| 259 ColumnSet* column_set = GetColumnSet(column_set_id); | 255 ColumnSet* column_set = GetColumnSet(column_set_id); |
| 260 DCHECK(column_set); | 256 DCHECK(column_set); |
| 261 AddRow(new Row(vertical_resize, 0, column_set)); | 257 AddRow(base::MakeUnique<Row>(vertical_resize, 0, column_set)); |
| 262 } | 258 } |
| 263 | 259 |
| 264 ColumnSet* SimpleGridLayout::AddRow() { | 260 ColumnSet* SimpleGridLayout::AddRow() { |
| 265 AddRow(new Row(0, 0, AddColumnSet(current_auto_id_++))); | 261 AddRow(base::MakeUnique<Row>(0, 0, AddColumnSet(current_auto_id_++))); |
| 266 return column_sets_.back(); | 262 return column_sets_.back().get(); |
| 267 } | 263 } |
| 268 | 264 |
| 269 void SimpleGridLayout::SkipColumns(int col_count) { | 265 void SimpleGridLayout::SkipColumns(int col_count) { |
| 270 DCHECK(col_count > 0); | 266 DCHECK(col_count > 0); |
| 271 next_column_ += col_count; | 267 next_column_ += col_count; |
| 272 ColumnSet* current_row_col_set_ = GetLastValidColumnSet(); | 268 ColumnSet* current_row_col_set_ = GetLastValidColumnSet(); |
| 273 DCHECK(current_row_col_set_ && | 269 DCHECK(current_row_col_set_ && |
| 274 next_column_ <= current_row_col_set_->num_columns()); | 270 next_column_ <= current_row_col_set_->num_columns()); |
| 275 SkipPaddingColumns(); | 271 SkipPaddingColumns(); |
| 276 } | 272 } |
| 277 | 273 |
| 278 void SimpleGridLayout::AddView(NSView* view) { | 274 void SimpleGridLayout::AddView(NSView* view) { |
| 279 [host_ addSubview:view]; | 275 [host_ addSubview:view]; |
| 280 DCHECK(next_column_ < GetLastValidColumnSet()->num_columns()); | 276 DCHECK(next_column_ < GetLastValidColumnSet()->num_columns()); |
| 281 view_states_.push_back( | 277 view_states_.push_back(base::MakeUnique<ViewState>( |
| 282 new ViewState(view, | 278 view, GetLastValidColumnSet(), rows_.size() - 1, next_column_++)); |
| 283 GetLastValidColumnSet(), | |
| 284 rows_.size() - 1, | |
| 285 next_column_++)); | |
| 286 SkipPaddingColumns(); | 279 SkipPaddingColumns(); |
| 287 } | 280 } |
| 288 | 281 |
| 289 // Sizes elements to fit into the superViews bounds, according to constraints. | 282 // Sizes elements to fit into the superViews bounds, according to constraints. |
| 290 void SimpleGridLayout::Layout(NSView* superView) { | 283 void SimpleGridLayout::Layout(NSView* superView) { |
| 291 SizeRowsAndColumns(NSWidth([superView bounds])); | 284 SizeRowsAndColumns(NSWidth([superView bounds])); |
| 292 for (std::vector<ViewState*>::iterator i = view_states_.begin(); | 285 for (const auto& view_state : view_states_) { |
| 293 i != view_states_.end(); ++i) { | |
| 294 ViewState* view_state = *i; | |
| 295 NSView* view = view_state->view(); | 286 NSView* view = view_state->view(); |
| 296 NSRect frame = NSMakeRect(view_state->GetColumn()->Location(), | 287 NSRect frame = NSMakeRect(view_state->GetColumn()->Location(), |
| 297 rows_[view_state->row_index()]->Location(), | 288 rows_[view_state->row_index()]->Location(), |
| 298 view_state->GetColumn()->Size(), | 289 view_state->GetColumn()->Size(), |
| 299 rows_[view_state->row_index()]->Size()); | 290 rows_[view_state->row_index()]->Size()); |
| 300 [view setFrame:NSIntegralRect(frame)]; | 291 [view setFrame:NSIntegralRect(frame)]; |
| 301 } | 292 } |
| 302 } | 293 } |
| 303 | 294 |
| 304 void SimpleGridLayout::SizeRowsAndColumns(float width) { | 295 void SimpleGridLayout::SizeRowsAndColumns(float width) { |
| 305 // Size all columns first. | 296 // Size all columns first. |
| 306 for (ScopedVector<ColumnSet>::iterator i = column_sets_.begin(); | 297 for (const auto& column_set : column_sets_) { |
| 307 i != column_sets_.end(); ++i) { | 298 column_set->CalculateSize(width); |
| 308 (*i)->CalculateSize(width); | 299 column_set->ResetColumnXCoordinates(); |
| 309 (*i)->ResetColumnXCoordinates(); | |
| 310 } | 300 } |
| 311 | 301 |
| 312 // Reset the height of each row. | 302 // Reset the height of each row. |
| 313 LayoutElement::ResetSizes(&rows_); | 303 LayoutElement::ResetSizes(&rows_); |
| 314 | 304 |
| 315 // For each ViewState, obtain the preferred height | 305 // For each ViewState, obtain the preferred height |
| 316 for (std::vector<ViewState*>::iterator i= view_states_.begin(); | 306 for (const auto& view_state : view_states_) { |
| 317 i != view_states_.end() ; ++i) { | |
| 318 ViewState* view_state = *i; | |
| 319 | |
| 320 // The view is resizable. As the pref height may vary with the width, | 307 // The view is resizable. As the pref height may vary with the width, |
| 321 // ask for the pref again. | 308 // ask for the pref again. |
| 322 int actual_width = view_state->GetColumnWidth(); | 309 int actual_width = view_state->GetColumnWidth(); |
| 323 | 310 |
| 324 // The width this view will get differs from its preferred. Some Views | 311 // The width this view will get differs from its preferred. Some Views |
| 325 // pref height varies with its width; ask for the preferred again. | 312 // pref height varies with its width; ask for the preferred again. |
| 326 view_state->set_preferred_height( | 313 view_state->set_preferred_height( |
| 327 view_state->GetHeightForWidth(actual_width)); | 314 view_state->GetHeightForWidth(actual_width)); |
| 328 } | 315 } |
| 329 | 316 |
| 330 | 317 |
| 331 // Make sure each row can accommodate all contained ViewStates. | 318 // Make sure each row can accommodate all contained ViewStates. |
| 332 std::vector<ViewState*>::iterator view_states_iterator = view_states_.begin(); | 319 for (const auto& view_state : view_states_) { |
| 333 for (; view_states_iterator != view_states_.end(); ++view_states_iterator) { | 320 Row* row = rows_[view_state->row_index()].get(); |
| 334 ViewState* view_state = *view_states_iterator; | |
| 335 Row* row = rows_[view_state->row_index()]; | |
| 336 row->AdjustSize(view_state->preferred_height()); | 321 row->AdjustSize(view_state->preferred_height()); |
| 337 } | 322 } |
| 338 | 323 |
| 339 // Update the location of each of the rows. | 324 // Update the location of each of the rows. |
| 340 LayoutElement::CalculateLocationsFromSize(&rows_); | 325 LayoutElement::CalculateLocationsFromSize(&rows_); |
| 341 } | 326 } |
| 342 | 327 |
| 343 void SimpleGridLayout::SkipPaddingColumns() { | 328 void SimpleGridLayout::SkipPaddingColumns() { |
| 344 ColumnSet* current_row_col_set_ = GetLastValidColumnSet(); | 329 ColumnSet* current_row_col_set_ = GetLastValidColumnSet(); |
| 345 while (next_column_ < current_row_col_set_->num_columns() && | 330 while (next_column_ < current_row_col_set_->num_columns() && |
| 346 current_row_col_set_->GetColumn(next_column_)->is_padding()) { | 331 current_row_col_set_->GetColumn(next_column_)->is_padding()) { |
| 347 next_column_++; | 332 next_column_++; |
| 348 } | 333 } |
| 349 } | 334 } |
| 350 | 335 |
| 351 ColumnSet* SimpleGridLayout::GetLastValidColumnSet() { | 336 ColumnSet* SimpleGridLayout::GetLastValidColumnSet() { |
| 352 for (int i = num_rows() - 1; i >= 0; --i) { | 337 for (int i = num_rows() - 1; i >= 0; --i) { |
| 353 if (rows_[i]->column_set()) | 338 if (rows_[i]->column_set()) |
| 354 return rows_[i]->column_set(); | 339 return rows_[i]->column_set(); |
| 355 } | 340 } |
| 356 return NULL; | 341 return nullptr; |
| 357 } | 342 } |
| 358 | 343 |
| 359 float SimpleGridLayout::GetRowHeight(int row_index) { | 344 float SimpleGridLayout::GetRowHeight(int row_index) { |
| 360 if (row_index < 0 || row_index >= num_rows()) | 345 if (row_index < 0 || row_index >= num_rows()) |
| 361 return 0.0; | 346 return 0.0; |
| 362 return rows_[row_index]->Size(); | 347 return rows_[row_index]->Size(); |
| 363 } | 348 } |
| 364 | 349 |
| 365 float SimpleGridLayout::GetRowLocation(int row_index) const { | 350 float SimpleGridLayout::GetRowLocation(int row_index) const { |
| 366 if (row_index < 0 || row_index >= num_rows()) | 351 if (row_index < 0 || row_index >= num_rows()) |
| 367 return 0.0; | 352 return 0.0; |
| 368 return rows_[row_index]->Location(); | 353 return rows_[row_index]->Location(); |
| 369 } | 354 } |
| 370 | 355 |
| 371 float SimpleGridLayout::GetPreferredHeightForWidth(float width) { | 356 float SimpleGridLayout::GetPreferredHeightForWidth(float width) { |
| 372 if (rows_.empty()) | 357 if (rows_.empty()) |
| 373 return 0.0f; | 358 return 0.0f; |
| 374 | 359 |
| 375 SizeRowsAndColumns(width); | 360 SizeRowsAndColumns(width); |
| 376 return rows_.back()->Location() + rows_.back()->Size(); | 361 return rows_.back()->Location() + rows_.back()->Size(); |
| 377 } | 362 } |
| 378 | 363 |
| 379 void SimpleGridLayout::AddRow(Row* row) { | 364 void SimpleGridLayout::AddRow(std::unique_ptr<Row> row) { |
| 380 next_column_ = 0; | 365 next_column_ = 0; |
| 381 rows_.push_back(row); | 366 rows_.push_back(std::move(row)); |
| 382 } | 367 } |
| 383 | 368 |
| OLD | NEW |