tri_view_unittest.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <memory>
  5. #include <utility>
  6. #include "ash/system/tray/tri_view.h"
  7. #include "testing/gtest/include/gtest/gtest.h"
  8. #include "ui/gfx/geometry/insets.h"
  9. #include "ui/gfx/geometry/rect_conversions.h"
  10. #include "ui/views/layout/box_layout.h"
  11. #include "ui/views/test/test_layout_manager.h"
  12. #include "ui/views/test/test_views.h"
  13. #include "ui/views/view.h"
  14. namespace ash {
  15. namespace {
  16. // Returns a layout manager that will size views according to their preferred
  17. // size.
  18. std::unique_ptr<views::LayoutManager> CreatePreferredSizeLayoutManager() {
  19. auto layout = std::make_unique<views::BoxLayout>(
  20. views::BoxLayout::Orientation::kHorizontal);
  21. layout->set_cross_axis_alignment(
  22. views::BoxLayout::CrossAxisAlignment::kStart);
  23. return layout;
  24. }
  25. } // namespace
  26. class TriViewTest : public testing::Test {
  27. public:
  28. TriViewTest();
  29. TriViewTest(const TriViewTest&) = delete;
  30. TriViewTest& operator=(const TriViewTest&) = delete;
  31. protected:
  32. // Convenience function to get the minimum height of |container|.
  33. int GetMinHeight(TriView::Container container) const;
  34. // Returns the bounds of |child| in the coordinate space of
  35. // |tri_view_|.
  36. gfx::Rect GetBoundsInHost(const views::View* child) const;
  37. // Wrapper functions to access the internals of |tri_view_|.
  38. views::View* GetContainer(TriView::Container container) const;
  39. // The test target.
  40. std::unique_ptr<TriView> tri_view_;
  41. };
  42. TriViewTest::TriViewTest() : tri_view_(std::make_unique<TriView>()) {}
  43. int TriViewTest::GetMinHeight(TriView::Container container) const {
  44. return tri_view_->GetMinSize(container).height();
  45. }
  46. gfx::Rect TriViewTest::GetBoundsInHost(const views::View* child) const {
  47. gfx::RectF rect_f(child->bounds());
  48. views::View::ConvertRectToTarget(child, tri_view_.get(), &rect_f);
  49. return ToNearestRect(rect_f);
  50. }
  51. views::View* TriViewTest::GetContainer(TriView::Container container) const {
  52. return tri_view_->GetContainer(container);
  53. }
  54. TEST_F(TriViewTest, PaddingBetweenContainers) {
  55. const int kPaddingBetweenContainers = 3;
  56. const int kViewWidth = 10;
  57. const int kViewHeight = 10;
  58. const gfx::Size kViewSize(kViewWidth, kViewHeight);
  59. const int kStartChildExpectedX = 0;
  60. const int kCenterChildExpectedX =
  61. kStartChildExpectedX + kViewWidth + kPaddingBetweenContainers;
  62. const int kEndChildExpectedX =
  63. kCenterChildExpectedX + kViewWidth + kPaddingBetweenContainers;
  64. tri_view_ = std::make_unique<TriView>(kPaddingBetweenContainers);
  65. tri_view_->SetBounds(0, 0, 100, 10);
  66. views::View* start_child = new views::StaticSizedView(kViewSize);
  67. views::View* center_child = new views::StaticSizedView(kViewSize);
  68. views::View* end_child = new views::StaticSizedView(kViewSize);
  69. tri_view_->AddView(TriView::Container::START, start_child);
  70. tri_view_->AddView(TriView::Container::CENTER, center_child);
  71. tri_view_->AddView(TriView::Container::END, end_child);
  72. tri_view_->Layout();
  73. EXPECT_EQ(kStartChildExpectedX, GetBoundsInHost(start_child).x());
  74. EXPECT_EQ(kCenterChildExpectedX, GetBoundsInHost(center_child).x());
  75. EXPECT_EQ(kEndChildExpectedX, GetBoundsInHost(end_child).x());
  76. }
  77. TEST_F(TriViewTest, VerticalOrientation) {
  78. const int kViewWidth = 10;
  79. const int kViewHeight = 10;
  80. const gfx::Size kViewSize(kViewWidth, kViewHeight);
  81. tri_view_ = std::make_unique<TriView>(TriView::Orientation::VERTICAL);
  82. tri_view_->SetBounds(0, 0, 10, 100);
  83. views::View* start_child = new views::StaticSizedView(kViewSize);
  84. views::View* center_child = new views::StaticSizedView(kViewSize);
  85. views::View* end_child = new views::StaticSizedView(kViewSize);
  86. tri_view_->AddView(TriView::Container::START, start_child);
  87. tri_view_->AddView(TriView::Container::CENTER, center_child);
  88. tri_view_->AddView(TriView::Container::END, end_child);
  89. tri_view_->Layout();
  90. EXPECT_EQ(0, GetBoundsInHost(start_child).y());
  91. EXPECT_EQ(kViewWidth, GetBoundsInHost(center_child).y());
  92. EXPECT_EQ(kViewWidth * 2, GetBoundsInHost(end_child).y());
  93. }
  94. TEST_F(TriViewTest, MainAxisMinSize) {
  95. tri_view_->SetBounds(0, 0, 100, 10);
  96. const gfx::Size kMinSize(15, 10);
  97. tri_view_->SetMinSize(TriView::Container::START, kMinSize);
  98. views::View* child = new views::StaticSizedView(gfx::Size(10, 10));
  99. tri_view_->AddView(TriView::Container::CENTER, child);
  100. tri_view_->Layout();
  101. EXPECT_EQ(kMinSize.width(), GetBoundsInHost(child).x());
  102. }
  103. TEST_F(TriViewTest, MainAxisMaxSize) {
  104. tri_view_->SetBounds(0, 0, 100, 10);
  105. const gfx::Size kMaxSize(10, 10);
  106. tri_view_->SetMaxSize(TriView::Container::START, kMaxSize);
  107. views::View* start_child = new views::StaticSizedView(gfx::Size(20, 20));
  108. tri_view_->AddView(TriView::Container::START, start_child);
  109. views::View* center_child = new views::StaticSizedView(gfx::Size(10, 10));
  110. tri_view_->AddView(TriView::Container::CENTER, center_child);
  111. tri_view_->Layout();
  112. EXPECT_EQ(kMaxSize.width(), GetBoundsInHost(center_child).x());
  113. }
  114. TEST_F(TriViewTest, ViewsAddedToCorrectContainers) {
  115. views::View* start_child = new views::StaticSizedView();
  116. views::View* center_child = new views::StaticSizedView();
  117. views::View* end_child = new views::StaticSizedView();
  118. tri_view_->AddView(TriView::Container::START, start_child);
  119. tri_view_->AddView(TriView::Container::CENTER, center_child);
  120. tri_view_->AddView(TriView::Container::END, end_child);
  121. EXPECT_TRUE(GetContainer(TriView::Container::START)->Contains(start_child));
  122. EXPECT_EQ(1u, GetContainer(TriView::Container::START)->children().size());
  123. EXPECT_TRUE(GetContainer(TriView::Container::CENTER)->Contains(center_child));
  124. EXPECT_EQ(1u, GetContainer(TriView::Container::CENTER)->children().size());
  125. EXPECT_TRUE(GetContainer(TriView::Container::END)->Contains(end_child));
  126. EXPECT_EQ(1u, GetContainer(TriView::Container::END)->children().size());
  127. }
  128. TEST_F(TriViewTest, MultipleViewsAddedToTheSameContainer) {
  129. views::View* child1 = new views::StaticSizedView();
  130. views::View* child2 = new views::StaticSizedView();
  131. tri_view_->AddView(TriView::Container::START, child1);
  132. tri_view_->AddView(TriView::Container::START, child2);
  133. EXPECT_TRUE(GetContainer(TriView::Container::START)->Contains(child1));
  134. EXPECT_TRUE(GetContainer(TriView::Container::START)->Contains(child2));
  135. }
  136. TEST_F(TriViewTest, Insets) {
  137. const int kInset = 3;
  138. const int kViewHeight = 10;
  139. const int kExpectedViewHeight = kViewHeight - 2 * kInset;
  140. const gfx::Size kStartViewSize(10, kViewHeight);
  141. const gfx::Size kCenterViewSize(100, kViewHeight);
  142. const gfx::Size kEndViewSize(10, kViewHeight);
  143. const int kHostWidth = 100;
  144. tri_view_->SetBounds(0, 0, kHostWidth, kViewHeight);
  145. tri_view_->SetInsets(gfx::Insets(kInset));
  146. views::View* start_child = new views::StaticSizedView(kStartViewSize);
  147. views::View* center_child = new views::StaticSizedView(kCenterViewSize);
  148. views::View* end_child = new views::StaticSizedView(kEndViewSize);
  149. tri_view_->AddView(TriView::Container::START, start_child);
  150. tri_view_->AddView(TriView::Container::CENTER, center_child);
  151. tri_view_->AddView(TriView::Container::END, end_child);
  152. tri_view_->SetFlexForContainer(TriView::Container::CENTER, 1.f);
  153. tri_view_->Layout();
  154. EXPECT_EQ(
  155. gfx::Rect(kInset, kInset, kStartViewSize.width(), kExpectedViewHeight),
  156. GetBoundsInHost(start_child));
  157. EXPECT_EQ(gfx::Rect(kInset + kStartViewSize.width(), kInset,
  158. kHostWidth - kStartViewSize.width() -
  159. kEndViewSize.width() - 2 * kInset,
  160. kExpectedViewHeight),
  161. GetBoundsInHost(center_child));
  162. EXPECT_EQ(gfx::Rect(kHostWidth - kEndViewSize.width() - kInset, kInset,
  163. kEndViewSize.width(), kExpectedViewHeight),
  164. GetBoundsInHost(end_child));
  165. }
  166. TEST_F(TriViewTest, InvisibleContainerDoesntTakeUpSpace) {
  167. const int kViewWidth = 10;
  168. const int kViewHeight = 10;
  169. const gfx::Size kViewSize(kViewWidth, kViewHeight);
  170. tri_view_->SetBounds(0, 0, 30, 10);
  171. views::View* start_child = new views::StaticSizedView(kViewSize);
  172. views::View* center_child = new views::StaticSizedView(kViewSize);
  173. views::View* end_child = new views::StaticSizedView(kViewSize);
  174. tri_view_->AddView(TriView::Container::START, start_child);
  175. tri_view_->AddView(TriView::Container::CENTER, center_child);
  176. tri_view_->AddView(TriView::Container::END, end_child);
  177. tri_view_->SetContainerVisible(TriView::Container::START, false);
  178. tri_view_->Layout();
  179. EXPECT_EQ(gfx::Rect(0, 0, 0, 0), GetBoundsInHost(start_child));
  180. EXPECT_EQ(0, GetBoundsInHost(center_child).x());
  181. EXPECT_EQ(kViewWidth, GetBoundsInHost(end_child).x());
  182. tri_view_->SetContainerVisible(TriView::Container::START, true);
  183. tri_view_->Layout();
  184. EXPECT_EQ(0, GetBoundsInHost(start_child).x());
  185. EXPECT_EQ(kViewWidth, GetBoundsInHost(center_child).x());
  186. EXPECT_EQ(kViewWidth * 2, GetBoundsInHost(end_child).x());
  187. }
  188. TEST_F(TriViewTest, NonZeroFlex) {
  189. const int kHostWidth = 100;
  190. const gfx::Size kDefaultViewSize(10, 10);
  191. const gfx::Size kCenterViewSize(100, 10);
  192. const gfx::Size kExpectedCenterViewSize(
  193. kHostWidth - 2 * kDefaultViewSize.width(), 10);
  194. tri_view_->SetBounds(0, 0, kHostWidth, 10);
  195. views::View* start_child = new views::StaticSizedView(kDefaultViewSize);
  196. views::View* center_child = new views::StaticSizedView(kCenterViewSize);
  197. views::View* end_child = new views::StaticSizedView(kDefaultViewSize);
  198. tri_view_->AddView(TriView::Container::START, start_child);
  199. tri_view_->AddView(TriView::Container::CENTER, center_child);
  200. tri_view_->AddView(TriView::Container::END, end_child);
  201. tri_view_->SetFlexForContainer(TriView::Container::CENTER, 1.f);
  202. tri_view_->Layout();
  203. EXPECT_EQ(kDefaultViewSize, GetBoundsInHost(start_child).size());
  204. EXPECT_EQ(kExpectedCenterViewSize, GetBoundsInHost(center_child).size());
  205. EXPECT_EQ(kDefaultViewSize, GetBoundsInHost(end_child).size());
  206. }
  207. TEST_F(TriViewTest, NonZeroFlexTakesPrecedenceOverMinSize) {
  208. const int kHostWidth = 25;
  209. const gfx::Size kViewSize(10, 10);
  210. const gfx::Size kMinCenterSize = kViewSize;
  211. const gfx::Size kExpectedCenterSize(kHostWidth - 2 * kViewSize.width(), 10);
  212. tri_view_->SetBounds(0, 0, kHostWidth, 10);
  213. views::View* start_child = new views::StaticSizedView(kViewSize);
  214. views::View* center_child = new views::StaticSizedView(kViewSize);
  215. views::View* end_child = new views::StaticSizedView(kViewSize);
  216. tri_view_->AddView(TriView::Container::START, start_child);
  217. tri_view_->AddView(TriView::Container::CENTER, center_child);
  218. tri_view_->AddView(TriView::Container::END, end_child);
  219. tri_view_->SetFlexForContainer(TriView::Container::CENTER, 1.f);
  220. tri_view_->SetMinSize(TriView::Container::CENTER, kMinCenterSize);
  221. tri_view_->Layout();
  222. EXPECT_EQ(kViewSize, GetBoundsInHost(start_child).size());
  223. EXPECT_EQ(kExpectedCenterSize,
  224. GetBoundsInHost(GetContainer(TriView::Container::CENTER)).size());
  225. EXPECT_EQ(kViewSize, GetBoundsInHost(end_child).size());
  226. }
  227. TEST_F(TriViewTest, NonZeroFlexTakesPrecedenceOverMaxSize) {
  228. const int kHostWidth = 100;
  229. const gfx::Size kViewSize(10, 10);
  230. const gfx::Size kMaxCenterSize(20, 10);
  231. const gfx::Size kExpectedCenterSize(kHostWidth - 2 * kViewSize.width(), 10);
  232. tri_view_->SetBounds(0, 0, kHostWidth, 10);
  233. views::View* start_child = new views::StaticSizedView(kViewSize);
  234. views::View* center_child = new views::StaticSizedView(kViewSize);
  235. views::View* end_child = new views::StaticSizedView(kViewSize);
  236. tri_view_->AddView(TriView::Container::START, start_child);
  237. tri_view_->AddView(TriView::Container::CENTER, center_child);
  238. tri_view_->AddView(TriView::Container::END, end_child);
  239. tri_view_->SetFlexForContainer(TriView::Container::CENTER, 1.f);
  240. tri_view_->SetMaxSize(TriView::Container::CENTER, kMaxCenterSize);
  241. tri_view_->Layout();
  242. EXPECT_EQ(kViewSize, GetBoundsInHost(start_child).size());
  243. EXPECT_EQ(kExpectedCenterSize,
  244. GetBoundsInHost(GetContainer(TriView::Container::CENTER)).size());
  245. EXPECT_EQ(kViewSize, GetBoundsInHost(end_child).size());
  246. }
  247. TEST_F(TriViewTest, ChildViewsPreferredSizeChanged) {
  248. const int kHostWidth = 500;
  249. const gfx::Size kMinStartSize(100, 10);
  250. tri_view_->SetBounds(0, 0, kHostWidth, 10);
  251. tri_view_->SetMinSize(TriView::Container::START, kMinStartSize);
  252. tri_view_->SetContainerLayout(TriView::Container::START,
  253. CreatePreferredSizeLayoutManager());
  254. tri_view_->SetFlexForContainer(TriView::Container::CENTER, 1.f);
  255. tri_view_->Layout();
  256. views::ProportionallySizedView* child_view =
  257. new views::ProportionallySizedView(1);
  258. tri_view_->AddView(TriView::Container::START, child_view);
  259. child_view->SetPreferredWidth(1);
  260. EXPECT_EQ(child_view->GetPreferredSize(), child_view->size());
  261. child_view->SetPreferredWidth(2);
  262. EXPECT_EQ(child_view->GetPreferredSize(), child_view->size());
  263. }
  264. TEST_F(TriViewTest, SetMinHeight) {
  265. const int kMinHeight = 10;
  266. EXPECT_NE(kMinHeight, GetMinHeight(TriView::Container::START));
  267. EXPECT_NE(kMinHeight, GetMinHeight(TriView::Container::CENTER));
  268. EXPECT_NE(kMinHeight, GetMinHeight(TriView::Container::END));
  269. tri_view_->SetMinHeight(kMinHeight);
  270. EXPECT_EQ(kMinHeight, GetMinHeight(TriView::Container::START));
  271. EXPECT_EQ(kMinHeight, GetMinHeight(TriView::Container::CENTER));
  272. EXPECT_EQ(kMinHeight, GetMinHeight(TriView::Container::END));
  273. }
  274. TEST_F(TriViewTest, ChangingContainersVisibilityPerformsLayout) {
  275. const int kViewWidth = 10;
  276. const int kViewHeight = 10;
  277. const gfx::Size kEndViewSize(kViewWidth, kViewHeight);
  278. tri_view_->SetBounds(0, 0, 3 * kViewWidth, kViewHeight);
  279. tri_view_->SetFlexForContainer(TriView::Container::CENTER, 1.f);
  280. views::View* start_child = new views::View();
  281. start_child->SetPreferredSize(kEndViewSize);
  282. views::View* center_child = new views::View();
  283. center_child->SetPreferredSize(gfx::Size(2 * kViewWidth, kViewHeight));
  284. views::View* end_child = new views::View();
  285. end_child->SetPreferredSize(kEndViewSize);
  286. tri_view_->AddView(TriView::Container::START, start_child);
  287. tri_view_->AddView(TriView::Container::CENTER, center_child);
  288. tri_view_->AddView(TriView::Container::END, end_child);
  289. tri_view_->Layout();
  290. EXPECT_EQ(gfx::Size(kViewWidth, kViewHeight), center_child->size());
  291. tri_view_->SetContainerVisible(TriView::Container::END, false);
  292. EXPECT_EQ(gfx::Size(2 * kViewWidth, kViewHeight), center_child->size());
  293. }
  294. } // namespace ash