00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _UT_LAYOUT_VIEW_H_
00026 #define _UT_LAYOUT_VIEW_H_
00027
00030
00031
00032
00033
00034
00035 #include "UTView.h"
00036 #include "UTTask.h"
00037 #include "UTMessageDestination.h"
00038
00039
00040
00041
00042
00043
00044
00045
00046 struct RowOrColumnInfo_t
00047 {
00048 float min_size;
00049 float size;
00050 float after_spacing;
00051 float start_position;
00052 };
00053
00054 enum layout_vh_align_mode_t
00055 {
00056 eLVHAM_align_start = 0,
00057 eLVHAM_center = 1,
00058 eLVHAM_align_end = 2
00059 };
00060
00061
00062
00063
00067 enum layout_h_align_mode_t
00068 {
00069 eLHAM_align_left = 0,
00070 eLHAM_center = 1,
00071 eLHAM_align_right = 2
00072 };
00073
00074
00078 enum layout_v_align_mode_t
00079 {
00080 eLVAM_align_top = 0,
00081 eLVAM_center = 1,
00082 eLVAM_align_bottom = 2
00083 };
00084
00087 typedef int row_column_set_token_t;
00088
00089
00090
00091
00092
00093
00094
00095
00096 class LayoutViewWeight_t;
00097 class LayoutViewChildInfo_t;
00098 class LayoutViewSameMinSet_t;
00099
00100
00101
00102
00103
00104 class UTGUI_EXPORT LayoutView_t
00105
00113 : public View_t,
00114 public Task_t
00115 {
00116
00117 public:
00118
00119 LayoutView_t();
00123
00124 virtual ~LayoutView_t();
00126
00127 void AddChild( View_t* child,
00128 int grid_left,
00129 float left_min_spacing,
00130 int grid_top,
00131 float top_min_spacing,
00132 int grid_right,
00133 float right_min_spacing,
00134 int grid_bottom,
00135 float bottom_min_spacing,
00136 layout_h_align_mode_t h_align_mode = eLHAM_center,
00137 layout_v_align_mode_t v_align_mode = eLVAM_center );
00173
00174 virtual void AddChild(takes View_t* child);
00177
00178 virtual gives View_t* RemoveChild(View_t* child);
00181
00182 void SetAbsoluteMinMaxSizeBehavior( float absolute_min_width,
00183 bool max_width_from_children,
00184 float absolute_max_width,
00185 float absolute_min_height,
00186 bool max_height_from_children,
00187 float absolute_max_height );
00210
00211 void SetDefaultRowWeight(float row_weight);
00217
00218 void SetDefaultColumnWeight(float column_weight);
00224
00225 void SetRowWeight( int row_index, float row_weight );
00231
00232 void SetColumnWeight( int column_index, float column_weight );
00238
00239 void RemoveRowWeight(int row_index );
00244
00245 void RemoveColumnWeight(int row_index );
00250
00251 row_column_set_token_t SetRowsUseSameMinHeight( int first_row_index, ... );
00258
00259 row_column_set_token_t SetRowsUseSameMinHeight( const int* row_indices, int num_row_indices );
00265
00266 row_column_set_token_t SetColumnsUseSameMinWidth( int first_column_index, ... );
00273
00274 row_column_set_token_t SetColumnsUseSameMinWidth( const int* column_indices,
00275 int num_column_indices );
00281
00282 void RemoveRowsUseSameMinHeight( int first_row_index, ... );
00287
00288 void RemoveColumnsUseSameMinWidth( int first_column_index, ... );
00293
00294 void RemoveRowsUseSameMinHeight(row_column_set_token_t token);
00297
00298 void RemoveColumnsUseSameMinWidth(row_column_set_token_t token);
00301
00302 inline int CountRows() const;
00304
00305 inline float RowHeight(int index) const;
00307
00308 inline float RowTop(int index) const;
00311
00312 inline int CountColumns() const;
00315
00316 inline float ColumnWidth(int index) const;
00318
00319 inline float ColumnLeft(int index) const;
00322
00323
00324 protected:
00325
00326 virtual void LBoundsChanged( const Rect_t& old_lbounds,
00327 const Rect_t& new_lbounds );
00331
00332 virtual void ChildMinMaxSizeChanged(View_t* child);
00338
00339
00340 private:
00341
00342 int ExtractRowColumnSameMinSet( int* stack_buffer,
00343 int** indices,
00344 int first_index,
00345 va_list args );
00346 row_column_set_token_t UniqueSameMinSetToken(OwnedLinkedList_t<LayoutViewSameMinSet_t>* sets);
00347 void RelayoutAsync();
00348 void RelayoutNow(bool size_decrease_allowed);
00349 void RelayoutNow( bool size_decrease_allowed, int recursion_depth );
00350 void CalculateGridSize();
00351 void SetupGridRowColumnBufs( byte* stack_buffer_grid,
00352 int stack_buffer_grid_size );
00353 float CalculateRowWeight(int index);
00354 float CalculateColumnWeight(int index);
00355 void CollectFirstPassInfo();
00356 static void ApplySameMinSizeRules(
00357 const OwnedLinkedList_t<LayoutViewSameMinSet_t>& rules,
00358 RowOrColumnInfo_t* states,
00359 int num_states );
00360
00361 float CollectAllMultiColumnMinViewSizes(
00362 RowOrColumnInfo_t* states,
00363 int num_states,
00364 const OwnedLinkedList_t<LayoutViewSameMinSet_t>& rules,
00365 int orientation );
00366 void AddMultiColumnViewMinSize( LayoutViewChildInfo_t* child,
00367 RowOrColumnInfo_t* states,
00368 int add_total_pixels,
00369 int grid_start,
00370 int grid_end,
00371 int orientation );
00372
00373 float CalculateMaxSize( RowOrColumnInfo_t* states,
00374 int num_states,
00375 int orientation );
00376 float CalculatePixelsToAddForMaxSizeIteration( RowOrColumnInfo_t* states,
00377 int num_states,
00378 int orientation );
00379 float CalculateChildViewPixelsToAddForMaxSize(
00380 LayoutViewChildInfo_t* child_info,
00381 RowOrColumnInfo_t* states,
00382 int orientation,
00383 int* child_grid_end );
00384 void DistributePixelsToStates( float add_pixels,
00385 RowOrColumnInfo_t* states,
00386 int num_states,
00387 int orientation );
00388
00389 void ApplyMinMaxSizesIfNeeded(bool size_decrease_allowed);
00390 void InvalidateSkipRelayoutInfo();
00391 void FinishLVMinMaxSizeCalculations();
00392
00393 void ApplyCurrentSize(int recursion_depth);
00394 void CalculateStartPositions( float before_spacing,
00395 RowOrColumnInfo_t* states,
00396 int num_states );
00397
00398
00399 private:
00400
00401 float m_absolute_min_width;
00402 float m_absolute_max_width;
00403 float m_absolute_min_height;
00404 float m_absolute_max_height;
00405
00406 bool m_max_width_from_children;
00407 bool m_max_height_from_children;
00408
00409 float m_unspecified_row_weight;
00410 OwnedBTree_t< LayoutViewWeight_t, int > m_row_weights;
00411 float m_unspecified_column_weight;
00412 OwnedBTree_t< LayoutViewWeight_t, int > m_column_weights;
00413 OwnedLinkedList_t<LayoutViewSameMinSet_t> m_row_same_min_sets;
00414 OwnedLinkedList_t<LayoutViewSameMinSet_t> m_column_same_min_sets;
00415 row_column_set_token_t m_next_same_min_set_token;
00416 OwnedLinkedList_t<LayoutViewChildInfo_t> m_children_info;
00417 BTree_t< LayoutViewChildInfo_t, View_t* > m_children_info_by_view;
00418
00419
00420 RowOrColumnInfo_t* m_rows;
00421 int m_num_rows;
00422 int m_num_allocated_row_infos;
00423 RowOrColumnInfo_t* m_columns;
00424 int m_num_columns;
00425 int m_num_allocated_column_infos;
00426
00427 bool m_max_width_from_children_applies;
00428 bool m_max_height_from_children_applies;
00429 Rect_t m_skip_relayout_old_lbounds;
00430 Rect_t m_skip_relayout_new_lbounds;
00431 float m_skip_relayout_lv_min_width;
00432 float m_skip_relayout_lv_max_width;
00433 float m_skip_relayout_lv_min_height;
00434 float m_skip_relayout_lv_max_height;
00435
00436
00437 bool m_async_relayout_queued;
00438 int m_relayout_recursion_depth;
00439 LayoutViewChildInfo_t** m_grid;
00440 int m_grid_allocated_size_bytes;
00441 void* m_free_grid;
00442 float m_left_spacing;
00443 float m_top_spacing;
00444 float m_lv_min_width;
00445 float m_lv_max_width;
00446 float m_lv_min_height;
00447 float m_lv_max_height;
00448
00449
00450 private:
00451
00452 void RelayoutReceived(const Message_t* message);
00453 MessageReceiver_t< LayoutView_t, Message_t > m_RelayoutReceiver;
00454 };
00455
00456
00457
00458
00459
00460
00461 class LayoutViewWeight_t
00462
00463 : public BTreeNode_t< LayoutViewWeight_t, int >
00464 {
00465
00466 public:
00467
00468 inline LayoutViewWeight_t( int row_column_index, float weight );
00469
00470 inline int Compare(int other_index) const;
00471 inline operator int() const;
00472
00473
00474 private:
00475
00476 int m_row_column_index;
00477 float m_weight;
00478
00479 friend class LayoutView_t;
00480 };
00481
00482
00483
00484 struct VorHLayoutChildInfo_t
00485
00486 {
00487 int grid_start;
00488 int grid_end;
00489 float before_spacing;
00490 float after_spacing;
00491 layout_vh_align_mode_t align_mode;
00492 };
00493
00494
00495
00496 class LayoutViewChildInfo_t
00497
00498 : public LinkedListNode_t<LayoutViewChildInfo_t>,
00499 public BTreeNode_t< LayoutViewChildInfo_t, View_t* >
00500 {
00501
00502 public:
00503
00504 inline LayoutViewChildInfo_t( View_t* view,
00505 int grid_left,
00506 float left_min_spacing,
00507 int grid_top,
00508 float top_min_spacing,
00509 int grid_right,
00510 float right_min_spacing,
00511 int grid_bottom,
00512 float bottom_min_spacing,
00513 layout_h_align_mode_t h_align_mode,
00514 layout_v_align_mode_t v_align_mode );
00515
00516 inline int Compare(View_t* other_view) const;
00517 inline operator View_t*() const;
00518
00519
00520 private:
00521
00522 View_t* m_view;
00523 VorHLayoutChildInfo_t m_vh_info[2];
00524 #define cLVHI_h 0
00525 #define cLVHI_v 1
00526
00527 friend class LayoutView_t;
00528 };
00529
00530
00531
00532 class LayoutViewSameMinSet_t
00533
00534 : public LinkedListNode_t<LayoutViewSameMinSet_t>
00535 {
00536 public:
00537 LayoutViewSameMinSet_t( row_column_set_token_t token,
00538 const int* indices,
00539 int num_indices );
00540 ~LayoutViewSameMinSet_t();
00541
00542 bool Matches( const int* other_indices, int other_num_indices );
00543
00544 row_column_set_token_t token;
00545 int* indices;
00546 int num_indices;
00547
00548 friend class LayoutView_t;
00549 };
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 inline int
00562 LayoutView_t::CountRows() const
00563 {
00564 return m_num_rows;
00565 }
00566
00567
00568 inline float
00569 LayoutView_t::RowHeight(int index) const
00570 {
00571 assert(index < m_num_rows);
00572 return m_rows[index].size;
00573 }
00574
00575
00576 inline float
00577 LayoutView_t::RowTop(int index) const
00578 {
00579 assert(index < m_num_rows);
00580 return m_rows[index].start_position;
00581 }
00582
00583
00584 inline int
00585 LayoutView_t::CountColumns() const
00586 {
00587 return m_num_columns;
00588 }
00589
00590
00591 inline float
00592 LayoutView_t::ColumnWidth(int index) const
00593 {
00594 assert(index < m_num_columns);
00595 return m_columns[index].size;
00596 }
00597
00598
00599 inline float
00600 LayoutView_t::ColumnLeft(int index) const
00601 {
00602 assert(index < m_num_columns);
00603 return m_columns[index].start_position;
00604 }
00605
00606
00607 inline
00608 LayoutViewWeight_t::LayoutViewWeight_t( int row_column_index, float weight )
00609 {
00610 m_row_column_index = row_column_index;
00611 m_weight = weight;
00612 }
00613
00614
00615 inline int
00616 LayoutViewWeight_t::Compare(int other_index) const
00617 {
00618 return m_row_column_index - other_index;
00619 }
00620
00621
00622 inline
00623 LayoutViewWeight_t::operator int() const
00624 {
00625 return m_row_column_index;
00626 }
00627
00628
00629 inline
00630 LayoutViewChildInfo_t::LayoutViewChildInfo_t( View_t* view,
00631 int grid_left,
00632 float left_min_spacing,
00633 int grid_top,
00634 float top_min_spacing,
00635 int grid_right,
00636 float right_min_spacing,
00637 int grid_bottom,
00638 float bottom_min_spacing,
00639 layout_h_align_mode_t h_align_mode,
00640 layout_v_align_mode_t v_align_mode )
00641 {
00642 m_view = view;
00643
00644 m_vh_info[cLVHI_h].grid_start = grid_left;
00645 m_vh_info[cLVHI_h].grid_end = grid_right;
00646 m_vh_info[cLVHI_h].before_spacing = left_min_spacing;
00647 m_vh_info[cLVHI_h].after_spacing = right_min_spacing;
00648 m_vh_info[cLVHI_h].align_mode = static_cast<layout_vh_align_mode_t>(h_align_mode);
00649
00650 m_vh_info[cLVHI_v].grid_start = grid_top;
00651 m_vh_info[cLVHI_v].grid_end = grid_bottom;
00652 m_vh_info[cLVHI_v].before_spacing = top_min_spacing;
00653 m_vh_info[cLVHI_v].after_spacing = bottom_min_spacing;
00654 m_vh_info[cLVHI_v].align_mode = static_cast<layout_vh_align_mode_t>(v_align_mode);
00655 }
00656
00657
00658 inline int
00659 LayoutViewChildInfo_t::Compare(View_t* other_view) const
00660 {
00661 if(m_view < other_view)
00662 return -1;
00663 else if(m_view > other_view)
00664 return 1;
00665 else
00666 return 0;
00667 }
00668
00669
00670 inline
00671 LayoutViewChildInfo_t::operator View_t*() const
00672 {
00673 return m_view;
00674 }
00675
00676
00677
00678
00679 #endif // _UT_LAYOUT_VIEW_H_