Grid layout crash fix
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / layouting / grid-locations.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 //CLASS HEADER
18 #include <dali-toolkit/internal/layouting/grid-locations.h>
19
20 // EXTERNAL HEADERS
21 #include <dali/integration-api/debug.h>
22
23 // INTERNAL HEADERS
24 #include <dali-toolkit/devel-api/layouting/layout-item.h>
25
26 namespace
27 {
28
29 #if defined(DEBUG_ENABLED)
30 static Debug::Filter* gLogFilter = Debug::Filter::New( Debug::Concise, false, "LOG_AXIS" );
31 #endif
32
33 }
34
35 namespace Dali
36 {
37 namespace Toolkit
38 {
39 namespace Internal
40 {
41
42 GridLocationsPtr GridLocations::New()
43 {
44   GridLocationsPtr gridAxis( new GridLocations() );
45   return gridAxis;
46 }
47
48 GridLocations::GridLocations()
49 : mLocations()
50 {
51 }
52
53 GridLocations::~GridLocations(){}
54
55 void GridLocations::CalculateLocations( int numberOfColumns,
56                                         unsigned int availableWidth,
57                                         unsigned int availableHeight,
58                                         unsigned int numberOfCells )
59 {
60   DALI_ASSERT_DEBUG( numberOfColumns > 0 && "number of columns should be greater than 0" );
61   numberOfColumns = std::max ( numberOfColumns, 1 );
62   mLocations.clear();
63
64   // Calculate width and height of columns and rows.
65
66   // Calculate numbers of rows, round down result as later check for remainder.
67   unsigned int numberOfRows = numberOfCells/numberOfColumns;
68   // If number of cells not cleanly dividable by colums, add another row to house remainder cells.
69   numberOfRows += (numberOfCells%numberOfColumns)?1:0;
70
71   // Safe as numberOfColumns is guaranteed to be > 0
72   unsigned int columnWidth = availableWidth / numberOfColumns;
73
74   unsigned int rowHeight = availableHeight;
75
76   if( numberOfRows > 0 )
77   {
78     rowHeight = availableHeight / numberOfRows;
79   }
80
81   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "ColumWidth[%d] RowHeight[%d] NumberOfRows[%d] NumberOfColumns[%d]\n",
82                                               columnWidth, rowHeight, numberOfRows, numberOfColumns );
83   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Remainder[%d]\n", numberOfCells%numberOfColumns );
84
85   int  y1 = 0;
86   int  y2 = y1 + rowHeight;
87
88   // Calculate start, end, top and bottom coordinate of each cell.
89
90   // Iterate rows
91   for( auto i = 0u; i < numberOfRows; i++ )
92   {
93     int x1 = 0;
94     int x2 = x1 + columnWidth;
95
96     // Iterate columns
97     for( auto j = 0; j < numberOfColumns; j++ )
98     {
99       GridLocations::Cell cell( x1, x2, y1, y2 );
100       mLocations.push_back( cell );
101       // Calculate starting x and ending x position of each column
102       x1 = x2;
103       x2 = x2 + columnWidth;
104     }
105
106     // Calculate top y and bottom y position of each row.
107     y1 = y2;
108     y2 = y2 + rowHeight;
109   }
110
111 #if defined(DEBUG_ENABLED)
112   std::ostringstream oss;
113   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "GridLocations::CalculateLocations (%d)\n", numberOfCells );
114   for( auto i = 0u; i < numberOfCells; i++ )
115   {
116     DALI_LOG_STREAM( gLogFilter, Debug::Verbose,"x1:"<<mLocations[i].xStart<<" x2:"<<mLocations[i].xEnd<<" y1:"<<mLocations[i].yTop<<" y2:"<<mLocations[i].yBottom);
117   }
118 #endif
119 }
120
121 GridLocations::LocationVector GridLocations::GetLocations()
122 {
123 #if defined(DEBUG_ENABLED)
124   std::ostringstream oss;
125   auto itemCount = mLocations.size(); // mVerticalLocations mirrors this so same size.
126   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "GridLocations::GetLocations for %u cells\n", itemCount );
127   for( auto i = 0u; i < itemCount; i++ )
128   {
129     DALI_LOG_STREAM( gLogFilter, Debug::Verbose,"x1:"<<mLocations[i].xStart<<" x2:"<<mLocations[i].xEnd<<" y1:"<<mLocations[i].yTop<<" y2:"<<mLocations[i].yBottom);
130   }
131 #endif
132
133   return mLocations;
134 }
135
136 } // namespace Internal
137
138 } // namespace Toolkit
139 } // namespace Dali