1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php 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 package com.android.ide.common.layout.grid; 17 18 import static com.android.SdkConstants.ANDROID_URI; 19 import static com.android.SdkConstants.ATTR_COLUMN_COUNT; 20 import static com.android.SdkConstants.ATTR_LAYOUT_COLUMN; 21 import static com.android.SdkConstants.ATTR_LAYOUT_COLUMN_SPAN; 22 import static com.android.SdkConstants.ATTR_LAYOUT_ROW; 23 import static com.android.SdkConstants.FQCN_BUTTON; 24 25 import com.android.ide.common.api.INode; 26 import com.android.ide.common.api.Rect; 27 import com.android.ide.common.layout.LayoutTestBase; 28 import com.android.ide.common.layout.TestNode; 29 import com.android.ide.common.layout.grid.GridModel.ViewData; 30 31 import java.util.Arrays; 32 import java.util.Collections; 33 34 35 @SuppressWarnings("javadoc") 36 public class GridModelTest extends LayoutTestBase { 37 public void testRemoveFlag() { 38 assertEquals("left", GridModel.removeFlag("top", "top|left")); 39 assertEquals("left", GridModel.removeFlag("top", "top | left")); 40 assertEquals("top", GridModel.removeFlag("left", "top|left")); 41 assertEquals("top", GridModel.removeFlag("left", "top | left")); 42 assertEquals("left | center", GridModel.removeFlag("top", "top | left | center")); 43 assertEquals(null, GridModel.removeFlag("top", "top")); 44 } 45 46 public void testReadModel1() { 47 TestNode targetNode = TestNode.create("android.widget.GridLayout").id("@+id/GridLayout1") 48 .bounds(new Rect(0, 0, 240, 480)).set(ANDROID_URI, ATTR_COLUMN_COUNT, "3"); 49 50 GridModel model = GridModel.get(null, targetNode, null); 51 assertEquals(3, model.declaredColumnCount); 52 assertEquals(1, model.actualColumnCount); 53 assertEquals(1, model.actualRowCount); 54 55 targetNode.add(TestNode.create(FQCN_BUTTON).id("@+id/Button1")); 56 targetNode.add(TestNode.create(FQCN_BUTTON).id("@+id/Button2")); 57 targetNode.add(TestNode.create(FQCN_BUTTON).id("@+id/Button3")); 58 targetNode.add(TestNode.create(FQCN_BUTTON).id("@+id/Button4")); 59 60 model = GridModel.get(null, targetNode, null); 61 assertEquals(3, model.declaredColumnCount); 62 assertEquals(3, model.actualColumnCount); 63 assertEquals(2, model.actualRowCount); 64 } 65 66 public void testSplitColumn() { 67 TestNode targetNode = TestNode.create("android.widget.GridLayout").id("@+id/GridLayout1") 68 .bounds(new Rect(0, 0, 240, 480)).set(ANDROID_URI, ATTR_COLUMN_COUNT, "3"); 69 TestNode b1 = TestNode.create(FQCN_BUTTON).id("@+id/Button1"); 70 TestNode b2 = TestNode.create(FQCN_BUTTON).id("@+id/Button2"); 71 TestNode b3 = TestNode.create(FQCN_BUTTON).id("@+id/Button3"); 72 TestNode b4 = TestNode.create(FQCN_BUTTON).id("@+id/Button4"); 73 targetNode.add(b1); 74 targetNode.add(b2); 75 targetNode.add(b3); 76 targetNode.add(b4); 77 b4.setAttribute(ANDROID_URI, ATTR_LAYOUT_COLUMN_SPAN, "2"); 78 79 GridModel model = GridModel.get(new LayoutTestBase.TestRulesEngine(targetNode.getFqcn()), 80 targetNode, null); 81 assertEquals(3, model.declaredColumnCount); 82 assertEquals(3, model.actualColumnCount); 83 assertEquals(2, model.actualRowCount); 84 85 model.applyPositionAttributes(); 86 assertEquals("0", b1.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN)); 87 assertEquals("0", b1.getStringAttr(ANDROID_URI, ATTR_LAYOUT_ROW)); 88 89 assertEquals("1", b2.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN)); 90 assertEquals("0", b2.getStringAttr(ANDROID_URI, ATTR_LAYOUT_ROW)); 91 92 assertEquals("2", b3.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN)); 93 assertEquals("0", b3.getStringAttr(ANDROID_URI, ATTR_LAYOUT_ROW)); 94 95 assertEquals("0", b4.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN)); 96 assertEquals("1", b4.getStringAttr(ANDROID_URI, ATTR_LAYOUT_ROW)); 97 assertEquals("2", b4.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN_SPAN)); 98 99 model.splitColumn(1, false /*insertMarginColumn*/, 100 /*columnWidthDp*/, 300 /* x */); 100 model.applyPositionAttributes(); 101 102 assertEquals(4, model.declaredColumnCount); 103 assertEquals(4, model.actualColumnCount); 104 assertEquals(2, model.actualRowCount); 105 106 assertEquals("0", b1.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN)); 107 assertEquals("0", b1.getStringAttr(ANDROID_URI, ATTR_LAYOUT_ROW)); 108 109 assertEquals("1", b2.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN)); 110 assertEquals("2", b2.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN_SPAN)); 111 assertEquals("0", b2.getStringAttr(ANDROID_URI, ATTR_LAYOUT_ROW)); 112 113 assertEquals("3", b3.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN)); 114 assertEquals("0", b3.getStringAttr(ANDROID_URI, ATTR_LAYOUT_ROW)); 115 116 assertEquals("0", b4.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN)); 117 assertEquals("1", b4.getStringAttr(ANDROID_URI, ATTR_LAYOUT_ROW)); 118 assertEquals("3", b4.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN_SPAN)); 119 } 120 121 public void testDeletion1() { 122 String xml = 123 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + 124 "<GridLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + 125 " android:layout_width=\"match_parent\"\n" + 126 " android:layout_height=\"match_parent\"\n" + 127 " android:columnCount=\"4\" >\n" + 128 "\n" + 129 " <Button\n" + 130 " android:id=\"@+id/button1\"\n" + 131 " android:layout_column=\"1\"\n" + 132 " android:layout_gravity=\"left|top\"\n" + 133 " android:layout_row=\"1\"\n" + 134 " android:text=\"Button\" />\n" + 135 "\n" + 136 " <TextView\n" + 137 " android:id=\"@+id/TextView1\"\n" + 138 " android:layout_column=\"3\"\n" + 139 " android:layout_gravity=\"left|top\"\n" + 140 " android:layout_row=\"1\"\n" + 141 " android:text=\"Text\" />\n" + 142 "\n" + 143 " <Space\n" + 144 " android:id=\"@+id/wspace1\"\n" + 145 " android:layout_width=\"21dp\"\n" + 146 " android:layout_height=\"1dp\"\n" + 147 " android:layout_column=\"0\"\n" + 148 " android:layout_row=\"0\" />\n" + 149 "\n" + 150 " <Space\n" + 151 " android:id=\"@+id/hspace1\"\n" + 152 " android:layout_width=\"1dp\"\n" + 153 " android:layout_height=\"55dp\"\n" + 154 " android:layout_column=\"0\"\n" + 155 " android:layout_row=\"0\" />\n" + 156 "\n" + 157 " <Space\n" + 158 " android:id=\"@+id/wspace2\"\n" + 159 " android:layout_width=\"10dp\"\n" + 160 " android:layout_height=\"1dp\"\n" + 161 " android:layout_column=\"2\"\n" + 162 " android:layout_row=\"0\" />\n" + 163 "\n" + 164 "</GridLayout>"; 165 166 TestNode targetNode = TestNode.createFromXml(xml); 167 assertNotNull(targetNode); 168 169 TestNode button1 = TestNode.findById(targetNode, "@+id/button1"); 170 TestNode textView1 = TestNode.findById(targetNode, "@+id/TextView1"); 171 TestNode wspace1 = TestNode.findById(targetNode, "@+id/wspace1"); 172 TestNode wspace2 = TestNode.findById(targetNode, "@+id/wspace2"); 173 TestNode hspace1 = TestNode.findById(targetNode, "@+id/hspace1"); 174 assertNotNull(wspace1); 175 assertNotNull(hspace1); 176 assertNotNull(wspace2); 177 assertNotNull(button1); 178 assertNotNull(textView1); 179 180 // Assign some bounds such that the model makes sense when merging spacer sizes 181 // TODO: MAke test utility method to automatically assign half divisions!! 182 button1.bounds(new Rect(90, 10, 100, 40)); 183 textView1.bounds(new Rect(200, 10, 100, 40)); 184 wspace1.bounds(new Rect(0, 0, 90, 1)); 185 wspace1.bounds(new Rect(190, 0, 10, 1)); 186 hspace1.bounds(new Rect(0, 0, 1, 10)); 187 188 GridModel model = GridModel.get(new LayoutTestBase.TestRulesEngine(targetNode.getFqcn()), 189 targetNode, null); 190 assertEquals(4, model.declaredColumnCount); 191 assertEquals(4, model.actualColumnCount); 192 assertEquals(2, model.actualRowCount); 193 194 ViewData textViewData = model.getView(textView1); 195 assertEquals(3, textViewData.column); 196 197 // Delete button1 198 button1.getParent().removeChild(button1); 199 model.onDeleted(Arrays.<INode>asList(button1)); 200 model.applyPositionAttributes(); 201 202 assertEquals(2, model.declaredColumnCount); 203 assertEquals(2, model.actualColumnCount); 204 assertEquals(2, model.actualRowCount); 205 assertNotNull(model.getView(textView1)); 206 assertNull(model.getView(button1)); 207 208 assertEquals( 209 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + 210 "<GridLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + 211 " android:layout_width=\"match_parent\"\n" + 212 " android:layout_height=\"match_parent\"\n" + 213 " android:columnCount=\"2\">\n" + 214 "\n" + 215 " <TextView\n" + 216 " android:id=\"@+id/TextView1\"\n" + 217 " android:layout_column=\"1\"\n" + 218 " android:layout_gravity=\"left|top\"\n" + 219 " android:layout_row=\"1\"\n" + 220 " android:text=\"Text\">\n" + 221 " </TextView>\n" + 222 "\n" + 223 " <Space\n" + 224 " android:id=\"@+id/wspace1\"\n" + 225 " android:layout_width=\"66dp\"\n" + 226 " android:layout_height=\"1dp\"\n" + 227 " android:layout_column=\"0\"\n" + 228 " android:layout_row=\"0\">\n" + 229 " </Space>\n" + 230 "\n" + 231 " <Space\n" + 232 " android:id=\"@+id/hspace1\"\n" + 233 " android:layout_width=\"1dp\"\n" + 234 " android:layout_height=\"55dp\"\n" + 235 " android:layout_column=\"0\"\n" + 236 " android:layout_row=\"0\">\n" + 237 " </Space>\n" + 238 "\n" + 239 "</GridLayout>", TestNode.toXml(targetNode)); 240 241 // Delete textView1 242 243 textView1.getParent().removeChild(textView1); 244 model.onDeleted(Arrays.<INode>asList(textView1)); 245 model.applyPositionAttributes(); 246 247 assertEquals(2, model.declaredColumnCount); 248 assertEquals(0, model.actualColumnCount); 249 assertEquals(0, model.actualRowCount); 250 assertNull(model.getView(textView1)); 251 assertNull(model.getView(button1)); 252 253 assertEquals( 254 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + 255 "<GridLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + 256 " android:layout_width=\"match_parent\"\n" + 257 " android:layout_height=\"match_parent\"\n" + 258 " android:columnCount=\"0\">\n" + 259 "\n" + 260 "</GridLayout>", TestNode.toXml(targetNode)); 261 262 } 263 264 public void testDelete2() throws Exception { 265 String xml = 266 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + 267 "<GridLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + 268 " android:layout_width=\"match_parent\"\n" + 269 " android:layout_height=\"match_parent\"\n" + 270 " android:columnCount=\"4\"\n" + 271 " android:orientation=\"vertical\" >\n" + 272 "\n" + 273 " <Button\n" + 274 " android:id=\"@+id/button1\"\n" + 275 " android:layout_column=\"0\"\n" + 276 " android:layout_columnSpan=\"2\"\n" + 277 " android:layout_gravity=\"left|top\"\n" + 278 " android:layout_row=\"0\"\n" + 279 " android:text=\"Button1\" />\n" + 280 "\n" + 281 " <Button\n" + 282 " android:id=\"@+id/button3\"\n" + 283 " android:layout_column=\"1\"\n" + 284 " android:layout_columnSpan=\"2\"\n" + 285 " android:layout_gravity=\"left|top\"\n" + 286 " android:layout_row=\"1\"\n" + 287 " android:text=\"Button2\" />\n" + 288 "\n" + 289 " <Button\n" + 290 " android:id=\"@+id/button2\"\n" + 291 " android:layout_column=\"2\"\n" + 292 " android:layout_gravity=\"left|top\"\n" + 293 " android:layout_row=\"0\"\n" + 294 " android:text=\"Button3\" />\n" + 295 "\n" + 296 " <Space\n" + 297 " android:id=\"@+id/spacer_177\"\n" + 298 " android:layout_width=\"46dp\"\n" + 299 " android:layout_height=\"1dp\"\n" + 300 " android:layout_column=\"0\"\n" + 301 " android:layout_row=\"0\" />\n" + 302 "\n" + 303 "</GridLayout>"; 304 305 TestNode targetNode = TestNode.createFromXml(xml); 306 assertNotNull(targetNode); 307 308 TestNode button1 = TestNode.findById(targetNode, "@+id/button1"); 309 TestNode button2 = TestNode.findById(targetNode, "@+id/button2"); 310 TestNode button3 = TestNode.findById(targetNode, "@+id/button3"); 311 TestNode hspacer = TestNode.findById(targetNode, "@+id/spacer_177"); 312 assertNotNull(button1); 313 assertNotNull(button2); 314 assertNotNull(button3); 315 assertNotNull(hspacer); 316 317 // Assign some bounds such that the model makes sense when merging spacer sizes 318 // TODO: MAke test utility method to automatically assign half divisions!! 319 button1.bounds(new Rect(0, 0, 100, 40)); 320 button2.bounds(new Rect(100, 0, 100, 40)); 321 button3.bounds(new Rect(50, 40, 100, 40)); 322 hspacer.bounds(new Rect(0, 0, 50, 1)); 323 324 GridModel model = GridModel.get(new LayoutTestBase.TestRulesEngine(targetNode.getFqcn()), 325 targetNode, null); 326 assertEquals(4, model.declaredColumnCount); 327 assertEquals(3, model.actualColumnCount); 328 assertEquals(2, model.actualRowCount); 329 330 ViewData buttonData = model.getView(button1); 331 assertEquals(0, buttonData.column); 332 333 // Delete button1 334 button1.getParent().removeChild(button1); 335 model.onDeleted(Arrays.<INode>asList(button1)); 336 model.applyPositionAttributes(); 337 338 assertEquals(3, model.declaredColumnCount); 339 assertEquals(3, model.actualColumnCount); 340 assertEquals(2, model.actualRowCount); 341 assertNull(model.getView(button1)); 342 343 assertEquals( 344 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + 345 "<GridLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + 346 " android:layout_width=\"match_parent\"\n" + 347 " android:layout_height=\"match_parent\"\n" + 348 " android:columnCount=\"3\"\n" + 349 " android:orientation=\"vertical\">\n" + 350 "\n" + 351 " <Button\n" + 352 " android:id=\"@+id/button3\"\n" + 353 " android:layout_column=\"1\"\n" + 354 " android:layout_columnSpan=\"2\"\n" + 355 " android:layout_gravity=\"left|top\"\n" + 356 " android:layout_row=\"1\"\n" + 357 " android:text=\"Button2\">\n" + 358 " </Button>\n" + 359 "\n" + 360 " <Button\n" + 361 " android:id=\"@+id/button2\"\n" + 362 " android:layout_column=\"2\"\n" + 363 " android:layout_gravity=\"left|top\"\n" + 364 " android:layout_row=\"0\"\n" + 365 " android:text=\"Button3\">\n" + 366 " </Button>\n" + 367 "\n" + 368 " <Space\n" + 369 " android:id=\"@+id/spacer_177\"\n" + 370 " android:layout_width=\"46dp\"\n" + 371 " android:layout_height=\"1dp\"\n" + 372 " android:layout_column=\"0\"\n" + 373 " android:layout_row=\"0\">\n" + 374 " </Space>\n" + 375 "\n" + 376 "</GridLayout>", TestNode.toXml(targetNode)); 377 } 378 379 public void testDelete3_INCOMPLETE() throws Exception { 380 String xml = 381 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + 382 "<GridLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + 383 " android:layout_width=\"match_parent\" android:layout_height=\"match_parent\"\n" + 384 " android:columnCount=\"6\">\n" + 385 " <Button android:id=\"@+id/button1\" android:layout_column=\"1\"\n" + 386 " android:layout_columnSpan=\"2\" android:layout_gravity=\"left|top\"\n" + 387 " android:layout_row=\"1\" android:layout_rowSpan=\"2\" android:text=\"Button\" />\n" + 388 " <TextView android:id=\"@+id/TextView1\" android:layout_column=\"4\"\n" + 389 " android:layout_gravity=\"left|top\" android:layout_row=\"1\"\n" + 390 " android:text=\"Text\" />\n" + 391 " <Button android:id=\"@+id/button3\" android:layout_column=\"5\"\n" + 392 " android:layout_gravity=\"left|top\" android:layout_row=\"2\"\n" + 393 " android:layout_rowSpan=\"2\" android:text=\"Button\" />\n" + 394 " <Button android:id=\"@+id/button2\" android:layout_column=\"2\"\n" + 395 " android:layout_columnSpan=\"3\" android:layout_gravity=\"left|top\"\n" + 396 " android:layout_row=\"4\" android:text=\"Button\" />\n" + 397 " <Space android:id=\"@+id/wspace1\" android:layout_width=\"21dp\"\n" + 398 " android:layout_height=\"1dp\" android:layout_column=\"0\"\n" + 399 " android:layout_row=\"0\" />\n" + 400 " <Space android:id=\"@+id/spacer_630\" android:layout_width=\"1dp\"\n" + 401 " android:layout_height=\"55dp\" android:layout_column=\"0\"\n" + 402 " android:layout_row=\"0\" />\n" + 403 " <Space android:id=\"@+id/wspace2\" android:layout_width=\"10dp\"\n" + 404 " android:layout_height=\"1dp\" android:layout_column=\"3\"\n" + 405 " android:layout_row=\"0\" />\n" + 406 " <Space android:id=\"@+id/spacer_619\" android:layout_width=\"59dp\"\n" + 407 " android:layout_height=\"1dp\" android:layout_column=\"1\"\n" + 408 " android:layout_row=\"0\" />\n" + 409 " <Space android:id=\"@+id/spacer_102\" android:layout_width=\"1dp\"\n" + 410 " android:layout_height=\"30dp\" android:layout_column=\"0\"\n" + 411 " android:layout_row=\"1\" />\n" + 412 " <Space android:id=\"@+id/spacer_109\" android:layout_width=\"1dp\"\n" + 413 " android:layout_height=\"28dp\" android:layout_column=\"0\"\n" + 414 " android:layout_row=\"2\" />\n" + 415 " <Space android:id=\"@+id/spacer_146\" android:layout_width=\"1dp\"\n" + 416 " android:layout_height=\"70dp\" android:layout_column=\"0\"\n" + 417 " android:layout_row=\"3\" />\n" + 418 "</GridLayout>"; 419 TestNode targetNode = TestNode.createFromXml(xml); 420 assertNotNull(targetNode); 421 targetNode.assignBounds( 422 "android.widget.GridLayout [0,109,480,800] <GridLayout>\n" + 423 " android.widget.Button [32,83,148,155] <Button> @+id/button1\n" + 424 " android.widget.TextView [163,83,205,109] <TextView> @+id/TextView1\n" + 425 " android.widget.Button [237,128,353,200] <Button> @+id/button3\n" + 426 " android.widget.Button [121,275,237,347] <Button> @+id/button2\n" + 427 " android.widget.Space [0,0,32,2] <Space> @+id/wspace1\n" + 428 " android.widget.Space [0,0,2,83] <Space> @+id/spacer_630\n" + 429 " android.widget.Space [148,0,163,2] <Space> @+id/wspace2\n" + 430 " android.widget.Space [32,0,121,2] <Space> @+id/spacer_619\n" + 431 " android.widget.Space [0,83,2,128] <Space> @+id/spacer_102\n" + 432 " android.widget.Space [0,128,2,170] <Space> @+id/spacer_109\n" + 433 " android.widget.Space [0,170,2,275] <Space> @+id/spacer_146\n"); 434 TestNode layout = TestNode.findById(targetNode, "@+id/GridLayout1"); 435 //TestNode button1 = TestNode.findById(targetNode, "@+id/button1"); 436 TestNode button2 = TestNode.findById(targetNode, "@+id/button2"); 437 TestNode button3 = TestNode.findById(targetNode, "@+id/button3"); 438 439 GridModel model = GridModel.get(new LayoutTestBase.TestRulesEngine(targetNode.getFqcn()), 440 targetNode, null); 441 assertEquals(6, model.declaredColumnCount); 442 assertEquals(6, model.actualColumnCount); 443 assertEquals(5, model.actualRowCount); 444 445 // TODO: Delete button2 or button3: bad stuff happens visually 446 fail("Finish test"); 447 } 448 449 public void testDelete4_INCOMPLETE() { 450 String xml = "" + 451 "<GridLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + 452 " xmlns:tools=\"http://schemas.android.com/tools\" " + 453 " android:layout_width=\"match_parent\"\n" + 454 " android:layout_height=\"match_parent\" android:columnCount=\"3\"\n" + 455 " android:gravity=\"center\" android:text=\"@string/hello_world\"\n" + 456 " tools:context=\".MainActivity\">\n" + 457 " <Button android:id=\"@+id/button2\" android:layout_column=\"1\"\n" + 458 " android:layout_columnSpan=\"2\" android:layout_gravity=\"left|top\"\n" + 459 " android:layout_row=\"1\" android:text=\"Button\" />\n" + 460 " <Button android:id=\"@+id/button1\" android:layout_column=\"1\"\n" + 461 " android:layout_columnSpan=\"2\" android:layout_gravity=\"left|top\"\n" + 462 " android:layout_row=\"3\" android:text=\"Button\" />\n" + 463 " <Space android:id=\"@+id/spacer_167\" android:layout_width=\"74dp\"\n" + 464 " android:layout_height=\"1dp\" android:layout_column=\"0\"\n" + 465 " android:layout_row=\"0\" />\n" + 466 " <Space android:id=\"@+id/spacer_133\" android:layout_width=\"1dp\"\n" + 467 " android:layout_height=\"21dp\" android:layout_column=\"0\"\n" + 468 " android:layout_row=\"0\" />\n" + 469 " <Space android:id=\"@+id/spacer_142\" android:layout_width=\"1dp\"\n" + 470 " android:layout_height=\"26dp\" android:layout_column=\"0\"\n" + 471 " android:layout_row=\"2\" />\n" + 472 " <Space android:id=\"@+id/spacer_673\" android:layout_width=\"43dp\"\n" + 473 " android:layout_height=\"1dp\" android:layout_column=\"1\"\n" + 474 " android:layout_row=\"0\" />\n" + 475 " <Space android:id=\"@+id/spacer_110\" android:layout_width=\"202dp\"\n" + 476 " android:layout_height=\"15dp\" android:layout_column=\"2\" />\n" + 477 "</GridLayout>"; 478 TestNode targetNode = TestNode.createFromXml(xml); 479 assertNotNull(targetNode); 480 targetNode.assignBounds( 481 "android.widget.GridLayout [0,109,480,800] <GridLayout>\n" + 482 " android.widget.Button [111,32,227,104] <Button> @+id/button2\n" + 483 " android.widget.Button [111,143,227,215] <Button> @+id/button1\n" + 484 " android.widget.Space [0,0,111,2] <Space> @+id/spacer_167\n" + 485 " android.widget.Space [0,0,2,32] <Space> @+id/spacer_133\n" + 486 " android.widget.Space [0,104,2,143] <Space> @+id/spacer_142\n" + 487 " android.widget.Space [111,0,176,2] <Space> @+id/spacer_673\n" + 488 " android.widget.Space [176,668,479,691] <Space> @+id/spacer_110"); 489 490 491 // Remove button2; button1 shifts to the right! 492 493 //TestNode layout = TestNode.findById(targetNode, "@+id/GridLayout1"); 494 //TestNode button1 = TestNode.findById(targetNode, "@+id/button1"); 495 TestNode button2 = TestNode.findById(targetNode, "@+id/button2"); 496 TestNode button3 = TestNode.findById(targetNode, "@+id/button3"); 497 assertEquals(new Rect(111, 32, 227 - 111, 104 - 32), button2.getBounds()); 498 499 GridModel model = GridModel.get(new LayoutTestBase.TestRulesEngine(targetNode.getFqcn()), 500 targetNode, null); 501 assertEquals(3, model.declaredColumnCount); 502 assertEquals(3, model.actualColumnCount); 503 assertEquals(4, model.actualRowCount); 504 fail("Finish test"); 505 } 506 507 public void testDelete5_INCOMPLETE() { 508 String xml = 509 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + 510 "<GridLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + 511 " android:id=\"@+id/GridLayout1\" android:layout_width=\"match_parent\"\n" + 512 " android:layout_height=\"match_parent\" android:columnCount=\"4\"\n" + 513 " android:orientation=\"vertical\">\n" + 514 " <Button android:id=\"@+id/button1\" android:layout_column=\"0\"\n" + 515 " android:layout_gravity=\"center_horizontal|bottom\"\n" + 516 " android:layout_row=\"0\" android:text=\"Button\" />\n" + 517 " <Space android:layout_width=\"66dp\" android:layout_height=\"1dp\"\n" + 518 " android:layout_column=\"0\" android:layout_row=\"0\" />\n" + 519 " <Button android:id=\"@+id/button3\" android:layout_column=\"2\"\n" + 520 " android:layout_gravity=\"left|bottom\" android:layout_row=\"0\"\n" + 521 " android:text=\"Button\" />\n" + 522 " <Button android:id=\"@+id/button2\" android:layout_column=\"3\"\n" + 523 " android:layout_columnSpan=\"2\" android:layout_gravity=\"left|bottom\"\n" + 524 " android:layout_row=\"0\" android:text=\"Button\" />\n" + 525 " <Space android:id=\"@+id/spacer_109\" android:layout_width=\"51dp\"\n" + 526 " android:layout_height=\"1dp\" android:layout_column=\"1\"\n" + 527 " android:layout_row=\"0\" />\n" + 528 " <Space android:layout_width=\"129dp\" android:layout_height=\"1dp\"\n" + 529 " android:layout_column=\"2\" android:layout_row=\"0\" />\n" + 530 " <Space android:layout_width=\"62dp\" android:layout_height=\"1dp\"\n" + 531 " android:layout_column=\"3\" android:layout_row=\"0\" />\n" + 532 " <Space android:id=\"@+id/spacer_397\" android:layout_width=\"1dp\"\n" + 533 " android:layout_height=\"103dp\" android:layout_column=\"0\"\n" + 534 " android:layout_row=\"0\" />\n" + 535 " <Space android:layout_width=\"1dp\" android:layout_height=\"356dp\"\n" + 536 " android:layout_column=\"0\" android:layout_row=\"1\" />\n" + 537 "</GridLayout>"; 538 TestNode targetNode = TestNode.createFromXml(xml); 539 assertNotNull(targetNode); 540 541 targetNode.assignBounds( 542 "android.widget.GridLayout [0,109,480,800] <GridLayout> @+id/GridLayout1\n" + 543 " android.widget.Button [0,83,116,155] <Button> @+id/button1\n" + 544 " android.widget.Space [0,0,99,2] <Space>\n" + 545 " android.widget.Button [193,83,309,155] <Button> @+id/button3\n" + 546 " android.widget.Button [387,83,503,155] <Button> @+id/button2\n" + 547 " android.widget.Space [116,0,193,2] <Space> @+id/spacer_109\n" + 548 " android.widget.Space [193,0,387,2] <Space>\n" + 549 " android.widget.Space [387,0,480,2] <Space>\n" + 550 " android.widget.Space [0,0,2,155] <Space> @+id/spacer_397\n" + 551 " android.widget.Space [0,155,2,689] <Space>"); 552 553 // Delete button3. This causes an array out of bounds exception currently. 554 555 //TestNode layout = TestNode.findById(targetNode, "@+id/GridLayout1"); 556 //TestNode button1 = TestNode.findById(targetNode, "@+id/button1"); 557 TestNode button2 = TestNode.findById(targetNode, "@+id/button2"); 558 TestNode button3 = TestNode.findById(targetNode, "@+id/button3"); 559 assertEquals(new Rect(387, 83, 503 - 387, 155- 83), button2.getBounds()); 560 561 GridModel model = GridModel.get(new LayoutTestBase.TestRulesEngine(targetNode.getFqcn()), 562 targetNode, null); 563 assertEquals(4, model.declaredColumnCount); 564 assertEquals(4, model.actualColumnCount); 565 assertEquals(2, model.actualRowCount); 566 567 model.onDeleted(Collections.<INode>singletonList(button3)); 568 // Exception fixed; todo: Test that the model updates are correct. 569 570 assertEquals(3, model.declaredColumnCount); 571 assertEquals(3, model.actualColumnCount); 572 assertEquals(2, model.actualRowCount); 573 574 fail("Finish test"); 575 } 576 577 public void testInsert1() throws Exception { 578 String xml = 579 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + 580 "<GridLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + 581 " android:id=\"@+id/GridLayout1\"\n" + 582 " android:layout_width=\"match_parent\"\n" + 583 " android:layout_height=\"match_parent\"\n" + 584 " android:columnCount=\"4\"\n" + 585 " android:orientation=\"vertical\" >\n" + 586 "\n" + 587 " <Button\n" + 588 " android:id=\"@+id/button1\"\n" + 589 " android:layout_column=\"0\"\n" + 590 " android:layout_columnSpan=\"4\"\n" + 591 " android:layout_gravity=\"center_horizontal|bottom\"\n" + 592 " android:layout_row=\"0\"\n" + 593 " android:text=\"Button\" />\n" + 594 "\n" + 595 " <Button\n" + 596 " android:id=\"@+id/button2\"\n" + 597 " android:layout_column=\"2\"\n" + 598 " android:layout_gravity=\"left|top\"\n" + 599 " android:layout_row=\"1\"\n" + 600 " android:text=\"Button\" />\n" + 601 "\n" + 602 " <Button\n" + 603 " android:id=\"@+id/button3\"\n" + 604 " android:layout_column=\"3\"\n" + 605 " android:layout_gravity=\"left|top\"\n" + 606 " android:layout_row=\"1\"\n" + 607 " android:text=\"Button\" />\n" + 608 "\n" + 609 " <Space\n" + 610 " android:id=\"@+id/spacer_393\"\n" + 611 " android:layout_width=\"81dp\"\n" + 612 " android:layout_height=\"1dp\"\n" + 613 " android:layout_column=\"1\"\n" + 614 " android:layout_row=\"0\" />\n" + 615 "\n" + 616 " <Space\n" + 617 " android:id=\"@+id/spacer_397\"\n" + 618 " android:layout_width=\"1dp\"\n" + 619 " android:layout_height=\"103dp\"\n" + 620 " android:layout_column=\"0\"\n" + 621 " android:layout_row=\"0\" />\n" + 622 "\n" + 623 "</GridLayout>"; 624 625 TestNode targetNode = TestNode.createFromXml(xml); 626 assertNotNull(targetNode); 627 628 TestNode layout = TestNode.findById(targetNode, "@+id/GridLayout1"); 629 TestNode button1 = TestNode.findById(targetNode, "@+id/button1"); 630 TestNode button2 = TestNode.findById(targetNode, "@+id/button2"); 631 TestNode button3 = TestNode.findById(targetNode, "@+id/button3"); 632 TestNode hspacer = TestNode.findById(targetNode, "@+id/spacer_393"); 633 TestNode vspacer = TestNode.findById(targetNode, "@+id/spacer_397"); 634 assertNotNull(layout); 635 assertNotNull(button1); 636 assertNotNull(button2); 637 assertNotNull(button3); 638 assertNotNull(hspacer); 639 640 // Obtained by setting ViewHierarchy.DUMP_INFO=true: 641 layout.bounds(new Rect(0, 109, 480, 800-109)); 642 button1.bounds(new Rect(182, 83, 298-182, 155-83)); 643 button2.bounds(new Rect(124, 155, 240-124, 227-155)); 644 button3.bounds(new Rect(240, 155, 356-240, 227-155)); 645 hspacer.bounds(new Rect(2, 0, 124-2, 2)); 646 vspacer.bounds(new Rect(0, 0, 2, 155)); 647 648 GridModel model = GridModel.get(new LayoutTestBase.TestRulesEngine(targetNode.getFqcn()), 649 targetNode, null); 650 assertEquals(4, model.declaredColumnCount); 651 assertEquals(4, model.actualColumnCount); 652 assertEquals(2, model.actualRowCount); 653 654 655 model.splitColumn(1, false, 21, 32); 656 int index = model.getInsertIndex(2, 1); 657 GridModel.ViewData next = model.getView(index); 658 INode newChild = targetNode.insertChildAt(FQCN_BUTTON, index); 659 next.applyPositionAttributes(); 660 model.setGridAttribute(newChild, ATTR_LAYOUT_COLUMN, 1); 661 model.setGridAttribute(newChild, ATTR_LAYOUT_COLUMN_SPAN, 3); 662 } 663 664 public void testInsert2() throws Exception { 665 // Drop into a view where there is a centered view: when dropping to the right of 666 // it (on a row further down), ensure that the row span is increased for the 667 // non-left-justified centered view which does not horizontally overlap the view 668 String xml = 669 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + 670 "<GridLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + 671 " android:id=\"@+id/GridLayout1\"\n" + 672 " android:layout_width=\"match_parent\"\n" + 673 " android:layout_height=\"match_parent\"\n" + 674 " android:columnCount=\"3\"\n" + 675 " android:orientation=\"vertical\" >\n" + 676 "\n" + 677 " <Button\n" + 678 " android:id=\"@+id/button1\"\n" + 679 " android:layout_column=\"0\"\n" + 680 " android:layout_columnSpan=\"3\"\n" + 681 " android:layout_gravity=\"center_horizontal|bottom\"\n" + 682 " android:layout_row=\"0\"\n" + 683 " android:text=\"Button\" />\n" + 684 "\n" + 685 " <Button\n" + 686 " android:id=\"@+id/button2\"\n" + 687 " android:layout_column=\"1\"\n" + 688 " android:layout_gravity=\"left|top\"\n" + 689 " android:layout_row=\"1\"\n" + 690 " android:text=\"Button\" />\n" + 691 "\n" + 692 " <Button\n" + 693 " android:id=\"@+id/button3\"\n" + 694 " android:layout_column=\"2\"\n" + 695 " android:layout_gravity=\"left|top\"\n" + 696 " android:layout_row=\"1\"\n" + 697 " android:text=\"Button\" />\n" + 698 "\n" + 699 " <Space\n" + 700 " android:id=\"@+id/spacer_393\"\n" + 701 " android:layout_width=\"81dp\"\n" + 702 " android:layout_height=\"1dp\"\n" + 703 " android:layout_column=\"0\"\n" + 704 " android:layout_row=\"0\" />\n" + 705 "\n" + 706 " \n" + 707 " <Space\n" + 708 " android:id=\"@+id/spacer_397\"\n" + 709 " android:layout_width=\"1dp\"\n" + 710 " android:layout_height=\"103dp\"\n" + 711 " android:layout_column=\"0\"\n" + 712 " android:layout_row=\"0\" />\n" + 713 "\n" + 714 " \n" + 715 "</GridLayout>"; 716 717 TestNode targetNode = TestNode.createFromXml(xml); 718 assertNotNull(targetNode); 719 720 TestNode layout = TestNode.findById(targetNode, "@+id/GridLayout1"); 721 TestNode button1 = TestNode.findById(targetNode, "@+id/button1"); 722 TestNode button2 = TestNode.findById(targetNode, "@+id/button2"); 723 TestNode button3 = TestNode.findById(targetNode, "@+id/button3"); 724 TestNode hspacer = TestNode.findById(targetNode, "@+id/spacer_393"); 725 TestNode vspacer = TestNode.findById(targetNode, "@+id/spacer_397"); 726 assertNotNull(layout); 727 assertNotNull(button1); 728 assertNotNull(button2); 729 assertNotNull(button3); 730 assertNotNull(hspacer); 731 732 // Obtained by setting ViewHierarchy.DUMP_INFO=true: 733 layout.bounds(new Rect(0, 109, 480, 800-109)); 734 button1.bounds(new Rect(182, 83, 298-182, 155-83)); 735 button2.bounds(new Rect(122, 155, 238-122, 227-155)); 736 button3.bounds(new Rect(238, 155, 354-238, 227-155)); 737 hspacer.bounds(new Rect(0, 0, 122, 2)); 738 vspacer.bounds(new Rect(0, 0, 2, 155)); 739 740 GridModel model = GridModel.get(new LayoutTestBase.TestRulesEngine(targetNode.getFqcn()), 741 targetNode, null); 742 assertEquals(3, model.declaredColumnCount); 743 assertEquals(3, model.actualColumnCount); 744 assertEquals(2, model.actualRowCount); 745 746 ViewData view = model.getView(button1); 747 assertNotNull(view); 748 assertEquals(0, view.column); 749 assertEquals(3, view.columnSpan); 750 assertEquals("3", view.node.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN_SPAN)); 751 752 model.splitColumn(3, false, 53, 318); 753 assertEquals(0, view.column); 754 assertEquals(4, view.columnSpan); 755 assertEquals("4", view.node.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN_SPAN)); 756 } 757 758 public void testInsert3_BROKEN() throws Exception { 759 // Check that when we insert a new gap column near an existing column, the 760 // view in that new column does not get moved 761 String xml = 762 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + 763 "<GridLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + 764 " android:id=\"@+id/GridLayout1\"\n" + 765 " android:layout_width=\"match_parent\"\n" + 766 " android:layout_height=\"match_parent\"\n" + 767 " android:columnCount=\"3\"\n" + 768 " android:orientation=\"vertical\" >\n" + 769 "\n" + 770 " <Button\n" + 771 " android:id=\"@+id/button1\"\n" + 772 " android:layout_column=\"0\"\n" + 773 " android:layout_columnSpan=\"3\"\n" + 774 " android:layout_gravity=\"center_horizontal|bottom\"\n" + 775 " android:layout_row=\"0\"\n" + 776 " android:text=\"Button\" />\n" + 777 "\n" + 778 " <Button\n" + 779 " android:id=\"@+id/button2\"\n" + 780 " android:layout_column=\"1\"\n" + 781 " android:layout_gravity=\"left|top\"\n" + 782 " android:layout_row=\"1\"\n" + 783 " android:text=\"Button\" />\n" + 784 "\n" + 785 " <Button\n" + 786 " android:id=\"@+id/button3\"\n" + 787 " android:layout_column=\"2\"\n" + 788 " android:layout_gravity=\"left|top\"\n" + 789 " android:layout_row=\"1\"\n" + 790 " android:text=\"Button\" />\n" + 791 "\n" + 792 " <Space\n" + 793 " android:id=\"@+id/spacer_393\"\n" + 794 " android:layout_width=\"81dp\"\n" + 795 " android:layout_height=\"1dp\"\n" + 796 " android:layout_column=\"0\"\n" + 797 " android:layout_row=\"0\" />\n" + 798 "\n" + 799 " \n" + 800 " <Space\n" + 801 " android:id=\"@+id/spacer_397\"\n" + 802 " android:layout_width=\"1dp\"\n" + 803 " android:layout_height=\"103dp\"\n" + 804 " android:layout_column=\"0\"\n" + 805 " android:layout_row=\"0\" />\n" + 806 "\n" + 807 " \n" + 808 "</GridLayout>"; 809 810 TestNode targetNode = TestNode.createFromXml(xml); 811 assertNotNull(targetNode); 812 813 TestNode layout = TestNode.findById(targetNode, "@+id/GridLayout1"); 814 TestNode button1 = TestNode.findById(targetNode, "@+id/button1"); 815 TestNode button2 = TestNode.findById(targetNode, "@+id/button2"); 816 TestNode button3 = TestNode.findById(targetNode, "@+id/button3"); 817 TestNode hspacer = TestNode.findById(targetNode, "@+id/spacer_393"); 818 TestNode vspacer = TestNode.findById(targetNode, "@+id/spacer_397"); 819 assertNotNull(layout); 820 assertNotNull(button1); 821 assertNotNull(button2); 822 assertNotNull(button3); 823 assertNotNull(hspacer); 824 825 // Obtained by setting ViewHierarchy.DUMP_INFO=true: 826 layout.bounds(new Rect(0, 109, 480, 800-109)); 827 button1.bounds(new Rect(182, 83, 298-182, 155-83)); 828 button2.bounds(new Rect(122, 155, 238-122, 227-155)); 829 button3.bounds(new Rect(238, 155, 354-238, 227-155)); 830 hspacer.bounds(new Rect(0, 0, 122, 2)); 831 vspacer.bounds(new Rect(0, 0, 2, 155)); 832 833 GridModel model = GridModel.get(new LayoutTestBase.TestRulesEngine(targetNode.getFqcn()), 834 targetNode, null); 835 assertEquals(3, model.declaredColumnCount); 836 assertEquals(3, model.actualColumnCount); 837 assertEquals(2, model.actualRowCount); 838 839 ViewData view = model.getView(button3); 840 assertNotNull(view); 841 assertEquals(2, view.column); 842 assertEquals(1, view.columnSpan); 843 assertNull("1", view.node.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN_SPAN)); 844 845 model.splitColumn(2, true, 10, 253); 846 // TODO: Finish this test: Assert that the cells are in the right place 847 //assertEquals(4, view.column); 848 //assertEquals(1, view.columnSpan); 849 //assertEquals("4", view.node.getStringAttr(ANDROID_URI, ATTR_LAYOUT_COLUMN_SPAN)); 850 fail("Finish test"); 851 } 852 } 853