From 9781441fa162e32e5796658d4169387a3ffb5d88 Mon Sep 17 00:00:00 2001 From: Adeel Kazmi Date: Mon, 11 May 2015 18:15:27 +0100 Subject: [PATCH] Refactored Item Layouts - Removed boost::function usage - DepthLayout, GridLayout & SpiralLayout removed from Public API - Added a helper API to create the default layouts using an ENUM - Reworked the constraints in each layout - Removed automatic animations between layouts (broken anyway) - Added future extension to ItemLayout Change-Id: I3265f190eccd8396d689d6f74c5e70cc8905c744 --- automated-tests/src/dali-toolkit/CMakeLists.txt | 3 - .../src/dali-toolkit/utc-Dali-DepthLayout.cpp | 618 ----------------- .../src/dali-toolkit/utc-Dali-GridLayout.cpp | 548 --------------- .../src/dali-toolkit/utc-Dali-ItemLayout.cpp | 2 +- .../src/dali-toolkit/utc-Dali-ItemView.cpp | 26 +- .../src/dali-toolkit/utc-Dali-SpiralLayout.cpp | 570 --------------- dali-toolkit/dali-toolkit.h | 4 +- .../controls/scrollable/item-view/depth-layout.cpp | 618 +++++++++++++++++ .../controls/scrollable/item-view/depth-layout.h | 83 +-- .../controls/scrollable/item-view/grid-layout.cpp | 733 ++++++++++++++++++++ .../controls/scrollable/item-view/grid-layout.h | 59 +- .../scrollable/item-view/item-view-impl.cpp | 64 +- .../controls/scrollable/item-view/item-view-impl.h | 14 +- .../scrollable/item-view/spiral-layout.cpp | 551 +++++++++++++++ .../controls/scrollable/item-view/spiral-layout.h | 65 +- dali-toolkit/internal/file.list | 3 + .../scrollable/item-view/default-item-layout.cpp | 75 ++ .../scrollable/item-view/default-item-layout.h | 56 ++ .../controls/scrollable/item-view/depth-layout.cpp | 764 -------------------- .../controls/scrollable/item-view/grid-layout.cpp | 765 --------------------- .../controls/scrollable/item-view/item-layout.cpp | 273 +------- .../controls/scrollable/item-view/item-layout.h | 117 +--- .../scrollable/item-view/spiral-layout.cpp | 601 ---------------- dali-toolkit/public-api/file.list | 10 +- 24 files changed, 2198 insertions(+), 4424 deletions(-) delete mode 100644 automated-tests/src/dali-toolkit/utc-Dali-DepthLayout.cpp delete mode 100644 automated-tests/src/dali-toolkit/utc-Dali-GridLayout.cpp delete mode 100644 automated-tests/src/dali-toolkit/utc-Dali-SpiralLayout.cpp create mode 100644 dali-toolkit/internal/controls/scrollable/item-view/depth-layout.cpp rename dali-toolkit/{public-api => internal}/controls/scrollable/item-view/depth-layout.h (67%) create mode 100644 dali-toolkit/internal/controls/scrollable/item-view/grid-layout.cpp rename dali-toolkit/{public-api => internal}/controls/scrollable/item-view/grid-layout.h (78%) create mode 100644 dali-toolkit/internal/controls/scrollable/item-view/spiral-layout.cpp rename dali-toolkit/{public-api => internal}/controls/scrollable/item-view/spiral-layout.h (72%) create mode 100644 dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.cpp create mode 100644 dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h delete mode 100644 dali-toolkit/public-api/controls/scrollable/item-view/depth-layout.cpp delete mode 100644 dali-toolkit/public-api/controls/scrollable/item-view/grid-layout.cpp delete mode 100644 dali-toolkit/public-api/controls/scrollable/item-view/spiral-layout.cpp diff --git a/automated-tests/src/dali-toolkit/CMakeLists.txt b/automated-tests/src/dali-toolkit/CMakeLists.txt index 5688a3c..2b30d02 100644 --- a/automated-tests/src/dali-toolkit/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit/CMakeLists.txt @@ -16,7 +16,6 @@ SET(TC_SOURCES utc-Dali-CarouselEffect.cpp utc-Dali-CheckBoxButton.cpp utc-Dali-CubeTransitionEffect.cpp - utc-Dali-DepthLayout.cpp utc-Dali-DisplacementEffect.cpp utc-Dali-DistanceFieldEffect.cpp utc-Dali-GaussianBlurView.cpp @@ -31,7 +30,6 @@ SET(TC_SOURCES utc-Dali-ShearEffect.cpp utc-Dali-Slider.cpp utc-Dali-SoftButtonEffect.cpp - utc-Dali-SpiralLayout.cpp utc-Dali-SpotEffect.cpp utc-Dali-SquareDissolveEffect.cpp utc-Dali-TableView.cpp @@ -45,7 +43,6 @@ SET(TC_SOURCES utc-Dali-DefaultControls.cpp utc-Dali-DissolveEffect.cpp utc-Dali-FocusManager.cpp - utc-Dali-GridLayout.cpp utc-Dali-IrisEffect.cpp utc-Dali-ItemLayout.cpp utc-Dali-ItemView.cpp diff --git a/automated-tests/src/dali-toolkit/utc-Dali-DepthLayout.cpp b/automated-tests/src/dali-toolkit/utc-Dali-DepthLayout.cpp deleted file mode 100644 index 90b92f6..0000000 --- a/automated-tests/src/dali-toolkit/utc-Dali-DepthLayout.cpp +++ /dev/null @@ -1,618 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include -#include // for FLT_MAX -#include -#include -#include - -using namespace Dali; -using namespace Toolkit; - -namespace -{ -const unsigned int TOTAL_ITEM_NUMBER = 200; - -Vector3 DepthLayoutItemSizeFunction(unsigned int numberOfColumns, float layoutWidth) -{ - float width = (layoutWidth / static_cast(numberOfColumns + 1)) * 0.8f; - return Vector3(width, width, width); -} - -float DepthLayoutBottomMarginFunction(float layoutHeight) -{ - return layoutHeight * 0.25f; -} - -float DepthLayoutColumnPositionFunction(unsigned int numberOfColumns, unsigned int columnNumber, const Vector3& itemSize, float layoutWidth) -{ - float availableSpace = layoutWidth - itemSize.width * numberOfColumns; - float leftMargin = availableSpace / numberOfColumns * 0.5f; - float columnPosition = leftMargin + itemSize.width * 0.5f + columnNumber * (itemSize.width + availableSpace / numberOfColumns); - return columnPosition - layoutWidth * 0.5f; -} -} // namespace - - -// Implementation of ItemFactory for providing actors to ItemView -class TestItemFactory : public ItemFactory -{ -public: - - /** - * Constructor - * @param application class, stored as reference - */ - TestItemFactory() - { - } - -public: // From ItemFactory - - /** - * Query the number of items available from the factory. - * The maximum available item has an ID of GetNumberOfItems() - 1. - */ - virtual unsigned int GetNumberOfItems() - { - return TOTAL_ITEM_NUMBER; - } - - /** - * Create an Actor to represent a visible item. - * @param itemId - * @return the created actor. - */ - virtual Actor NewItem(unsigned int itemId) - { - // Create an test actor for this item - ImageActor actor = CreateSolidColorActor(Color::RED); - actor.SetSize(64.0f, 64.0f); - - return actor; - } -}; - - -void depth_layout_startup(void) -{ -} - -void depth_layout_cleanup(void) -{ -} - -int UtcDaliDepthLayoutNew(void) -{ - ToolkitTestApplication application; - - // Create a depth layout - DepthLayoutPtr depthLayout = DepthLayout::New(); - - DALI_TEST_CHECK(depthLayout); - END_TEST; -} - -int UtcDaliDepthLayoutSetAndGetNumberOfColumns(void) -{ - ToolkitTestApplication application; - - // Create a depth layout - DepthLayoutPtr depthLayout = DepthLayout::New(); - - // Set the number of columns - depthLayout->SetNumberOfColumns(5); - - // Check whether we get the correct number of columns - DALI_TEST_CHECK(depthLayout->GetNumberOfColumns() == 5); - END_TEST; -} - -int UtcDaliDepthLayoutSetAndGetNumberOfRows(void) -{ - ToolkitTestApplication application; - - // Create a depth layout - DepthLayoutPtr depthLayout = DepthLayout::New(); - - // Set the number of rows - depthLayout->SetNumberOfRows(15); - - // Check whether we get the correct number of rows - DALI_TEST_CHECK(depthLayout->GetNumberOfRows() == 15); - END_TEST; -} - -int UtcDaliDepthLayoutSetAndGetRowSpacing(void) -{ - ToolkitTestApplication application; - - // Create a depth layout - DepthLayoutPtr depthLayout = DepthLayout::New(); - - // Set the row spacing - depthLayout->SetRowSpacing(30.0f); - - // Check whether we get the correct row spacing - DALI_TEST_EQUALS(depthLayout->GetRowSpacing(), 30.0f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliDepthLayoutSetAndGetTiltAngle(void) -{ - ToolkitTestApplication application; - - // Create a depth layout - DepthLayoutPtr depthLayout = DepthLayout::New(); - - // Set the tilt angle - depthLayout->SetTiltAngle(Degree(25.0f)); - - // Check whether we get the correct tilt angle - DALI_TEST_EQUALS(depthLayout->GetTiltAngle(), Degree(25.0f), 0.001f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliDepthLayoutSetAndGetItemSizeFunction(void) -{ - ToolkitTestApplication application; - - // Create a depth layout - DepthLayoutPtr depthLayout = DepthLayout::New(); - - // Set the item size function - depthLayout->SetItemSizeFunction(DepthLayoutItemSizeFunction); - - // Check whether we get the correct item size function - DALI_TEST_CHECK(depthLayout->GetItemSizeFunction() == DepthLayoutItemSizeFunction); - END_TEST; -} - -int UtcDaliDepthLayoutSetAndGetBottomMarginFunction(void) -{ - ToolkitTestApplication application; - - // Create a depth layout - DepthLayoutPtr depthLayout = DepthLayout::New(); - - // Set the bottom margin function - depthLayout->SetBottomMarginFunction(DepthLayoutBottomMarginFunction); - - // Check whether we get the correct bottom margin function - DALI_TEST_CHECK(depthLayout->GetBottomMarginFunction() == DepthLayoutBottomMarginFunction); - END_TEST; -} - -int UtcDaliDepthLayoutSetAndGetItemTiltAngle(void) -{ - ToolkitTestApplication application; - - // Create a depth layout - DepthLayoutPtr depthLayout = DepthLayout::New(); - - // Set the item's tilt angle - depthLayout->SetItemTiltAngle(Degree(5.0f)); - - // Check whether we get the correct item's tilt angle - DALI_TEST_EQUALS(depthLayout->GetItemTiltAngle(), Degree(5.0f), 0.001f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliDepthLayoutSetAndGetColumnPositionFunction(void) -{ - ToolkitTestApplication application; - - // Create a depth layout - DepthLayoutPtr depthLayout = DepthLayout::New(); - - // Set the column position function - depthLayout->SetColumnPositionFunction(DepthLayoutColumnPositionFunction); - - // Check whether we get the correct column position function - DALI_TEST_CHECK(depthLayout->GetColumnPositionFunction() == DepthLayoutColumnPositionFunction); - END_TEST; -} - -int UtcDaliDepthLayoutSetAndGetScrollSpeedFactor(void) -{ - ToolkitTestApplication application; - - // Create a depth layout - DepthLayoutPtr depthLayout = DepthLayout::New(); - - // Set the scroll speed factor - depthLayout->SetScrollSpeedFactor(0.05f); - - // Check whether we get the correct scroll speed factor - DALI_TEST_EQUALS(depthLayout->GetScrollSpeedFactor(), 0.05f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliDepthLayoutSetAndGetMaximumSwipeSpeed(void) -{ - ToolkitTestApplication application; - - // Create a depth layout - DepthLayoutPtr depthLayout = DepthLayout::New(); - - // Set the maximum swipe speed - depthLayout->SetMaximumSwipeSpeed(50.0f); - - // Check whether we get the correct maximum swipe speed - DALI_TEST_EQUALS(depthLayout->GetMaximumSwipeSpeed(), 50.0f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliDepthLayoutSetAndGetItemFlickAnimationDuration(void) -{ - ToolkitTestApplication application; - - // Create a depth layout - DepthLayoutPtr depthLayout = DepthLayout::New(); - - // Set the flick animaiton duration - depthLayout->SetItemFlickAnimationDuration(0.35f); - - // Check whether we get the correct flick animaiton duration - DALI_TEST_EQUALS( depthLayout->GetItemFlickAnimationDuration(), 0.35f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliDepthLayoutConstraintLeft(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - DepthLayoutPtr navigationLayout = DepthLayout::New(); - navigationLayout->SetNumberOfColumns(6); - - view.SetName("view actor"); - view.AddLayout(*navigationLayout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - navigationLayout->SetOrientation(ControlOrientation::Left); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - // Confirm: we have actors in the view and they are positioned some distance from the origin. - int nonZeroCount = 0; - int elementsFound = 0; - for(unsigned int i = 0; i < 10; i++) - { - Actor testActor = view.GetItem(i); - if (testActor) - { - elementsFound++; - Vector3 pos = testActor.GetCurrentPosition(); - - if (pos.LengthSquared() > 0.0f) - { - nonZeroCount++; - } - } - } - - DALI_TEST_CHECK((elementsFound > 0) && (nonZeroCount == elementsFound)); - Stage::GetCurrent().Remove(view); - END_TEST; -} - -int UtcDaliDepthLayoutConstraintRight(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - DepthLayoutPtr navigationLayout = DepthLayout::New(); - navigationLayout->SetNumberOfColumns(6); - - view.SetName("view actor"); - view.AddLayout(*navigationLayout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - navigationLayout->SetOrientation(ControlOrientation::Right); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - // Confirm: we have actors in the view and they are positioned some distance from the origin. - int nonZeroCount = 0; - int elementsFound = 0; - for(unsigned int i = 0; i < 10; i++) - { - Actor testActor = view.GetItem(i); - if (testActor) - { - elementsFound++; - Vector3 pos = testActor.GetCurrentPosition(); - - if (pos.LengthSquared() > 0.0f) - { - nonZeroCount++; - } - } - } - - DALI_TEST_CHECK((elementsFound > 0) && (nonZeroCount == elementsFound)); - Stage::GetCurrent().Remove(view); - END_TEST; -} - -int UtcDaliDepthLayoutConstraintUp(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - DepthLayoutPtr navigationLayout = DepthLayout::New(); - navigationLayout->SetNumberOfColumns(6); - - view.SetName("view actor"); - view.AddLayout(*navigationLayout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - navigationLayout->SetOrientation(ControlOrientation::Up); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - // Confirm: we have actors in the view and they are positioned some distance from the origin. - int nonZeroCount = 0; - int elementsFound = 0; - for(unsigned int i = 0; i < 10; i++) - { - Actor testActor = view.GetItem(i); - if (testActor) - { - elementsFound++; - Vector3 pos = testActor.GetCurrentPosition(); - - if (pos.LengthSquared() > 0.0f) - { - nonZeroCount++; - } - } - } - - DALI_TEST_CHECK((elementsFound > 0) && (nonZeroCount == elementsFound)); - Stage::GetCurrent().Remove(view); - END_TEST; -} - -int UtcDaliDepthLayoutConstraintDown(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - DepthLayoutPtr navigationLayout = DepthLayout::New(); - navigationLayout->SetNumberOfColumns(6); - - view.SetName("view actor"); - view.AddLayout(*navigationLayout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - navigationLayout->SetOrientation(ControlOrientation::Down); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - // Confirm: we have actors in the view and they are positioned some distance from the origin. - int nonZeroCount = 0; - int elementsFound = 0; - for(unsigned int i = 0; i < 10; i++) - { - Actor testActor = view.GetItem(i); - if (testActor) - { - elementsFound++; - Vector3 pos = testActor.GetCurrentPosition(); - - if (pos.LengthSquared() > 0.0f) - { - nonZeroCount++; - } - } - } - - DALI_TEST_CHECK((elementsFound > 0) && (nonZeroCount == elementsFound)); - Stage::GetCurrent().Remove(view); - END_TEST; -} - -int UtcDaliDepthLayoutGetScrollToPosition(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - DepthLayoutPtr layout = DepthLayout::New(); - - view.SetName("view actor"); - view.AddLayout(*layout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - layout->SetOrientation(ControlOrientation::Up); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - // Confirm: we have actors in the view. - std::vector indices; - for(unsigned int i = 0; i < 10; i++) - { - Actor testActor = view.GetItem(i); - if (testActor) - { - indices.push_back(i); - } - } - - try - { - if (!indices.empty()) - { - const unsigned int firstTargetIndex = indices[indices.size()-1]; - // scroll to last item - view.ScrollToItem(firstTargetIndex, 0.00f); - application.Render(16); // 60hz frames - - std::size_t moveCount = 0; - for(std::size_t i = 0; i < indices.size(); i++) - { - float layoutPosBefore = view.GetCurrentLayoutPosition(i); - view.ScrollToItem(indices[i], 0.0f); - - application.Render(16); // 60hz frame - - float layoutPosAfter = view.GetCurrentLayoutPosition(i); - - if (fabs(layoutPosBefore-layoutPosAfter) <= FLT_EPSILON) - { - ++moveCount; - } - } - - DALI_TEST_CHECK((moveCount == indices.size())); - } - } - catch(...) - { - tet_result(TET_FAIL); - } - - Stage::GetCurrent().Remove(view); - END_TEST; -} - -int UtcDaliDepthLayoutScrollDirection(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - DepthLayoutPtr navigationLayout = DepthLayout::New(); - - view.SetName("view actor"); - view.AddLayout(*navigationLayout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - navigationLayout->SetOrientation(ControlOrientation::Left); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - ItemLayoutPtr layout = navigationLayout; - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - navigationLayout->SetOrientation(ControlOrientation::Up); - view.ActivateLayout(0, vec, 0.0f); - application.SendNotification(); - application.Render(); - - Degree deg = layout->GetScrollDirection(); - DALI_TEST_CHECK(deg.degree == 180.0f); - - navigationLayout->SetOrientation(ControlOrientation::Down); - view.ActivateLayout(0, vec, 0.0f); - application.SendNotification(); - application.Render(); - - deg = layout->GetScrollDirection(); - DALI_TEST_CHECK((deg.degree == 0.0f)); - - layout->SetOrientation(ControlOrientation::Left); - view.ActivateLayout(0, vec, 0.0f); - application.SendNotification(); - application.Render(); - - deg = layout->GetScrollDirection(); - DALI_TEST_CHECK(deg.degree == 270.0f); - - navigationLayout->SetOrientation(ControlOrientation::Right); - view.ActivateLayout(0, vec, 0.0f); - application.SendNotification(); - application.Render(); - - deg = layout->GetScrollDirection(); - DALI_TEST_CHECK(deg.degree == 90.0f); - - Stage::GetCurrent().Remove(view); - END_TEST; -} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-GridLayout.cpp b/automated-tests/src/dali-toolkit/utc-Dali-GridLayout.cpp deleted file mode 100644 index 6b050bc..0000000 --- a/automated-tests/src/dali-toolkit/utc-Dali-GridLayout.cpp +++ /dev/null @@ -1,548 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include -#include -#include // for FLT_MAX - -// Need to override adaptor classes for toolkit test harness, so include -// test harness headers before dali headers. -#include - -#include -#include - -using namespace Dali; -using namespace Toolkit; - -void utc_dali_toolkit_grid_layout_startup(void) -{ - test_return_value = TET_UNDEF; -} - -void utc_dali_toolkit_grid_layout_cleanup(void) -{ - test_return_value = TET_PASS; -} - - -namespace -{ - -const unsigned int TOTAL_ITEM_NUMBER = 200; - -Vector3 GridLayoutItemSizeFunction(unsigned int numberOfColumns, float layoutWidth, float sideMargin, float columnSpacing) -{ - float width = (layoutWidth - sideMargin * 2.0f - columnSpacing * static_cast(numberOfColumns - 1)) / static_cast(numberOfColumns); - - return Vector3(width, width, width); -} - - -// Implementation of ItemFactory for providing actors to ItemView -class TestItemFactory : public ItemFactory -{ -public: - - /** - * Constructor - * @param application class, stored as reference - */ - TestItemFactory() - { - } - -public: // From ItemFactory - - /** - * Query the number of items available from the factory. - * The maximum available item has an ID of GetNumberOfItems() - 1. - */ - virtual unsigned int GetNumberOfItems() - { - return TOTAL_ITEM_NUMBER; - } - - /** - * Create an Actor to represent a visible item. - * @param itemId - * @return the created actor. - */ - virtual Actor NewItem(unsigned int itemId) - { - // Create an test actor for this item - ImageActor actor = CreateSolidColorActor(Color::RED); - actor.SetSize(64.0f, 64.0f); - return actor; - } -}; - -} // namespace - - - -int UtcDaliGridLayoutNew(void) -{ - ToolkitTestApplication application; - - // Create a grid layout - GridLayoutPtr gridLayout = GridLayout::New(); - - DALI_TEST_CHECK(gridLayout); - END_TEST; -} - -int UtcDaliGridLayoutSetAndGetNumberOfColumns(void) -{ - ToolkitTestApplication application; - - // Create a grid layout - GridLayoutPtr gridLayout = GridLayout::New(); - - // Set the number of columns - gridLayout->SetNumberOfColumns(6); - - // Check whether we get the correct number of columns - DALI_TEST_CHECK(gridLayout->GetNumberOfColumns() == 6); - END_TEST; -} - -int UtcDaliGridLayoutSetAndGetRowSpacing(void) -{ - ToolkitTestApplication application; - - // Create a grid layout - GridLayoutPtr gridLayout = GridLayout::New(); - - // Set the row spacing - gridLayout->SetRowSpacing(10.0f); - - // Check whether we get the correct row spacing - DALI_TEST_EQUALS(gridLayout->GetRowSpacing(), 10.0f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliGridLayoutSetAndGetColumnSpacing(void) -{ - ToolkitTestApplication application; - - // Create a grid layout - GridLayoutPtr gridLayout = GridLayout::New(); - - // Set the column spacing - gridLayout->SetColumnSpacing(10.0f); - - // Check whether we get the correct column spacing - DALI_TEST_EQUALS(gridLayout->GetColumnSpacing(), 10.0f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliGridLayoutSetAndGetTopMargin(void) -{ - ToolkitTestApplication application; - - // Create a grid layout - GridLayoutPtr gridLayout = GridLayout::New(); - - // Set the top margin - gridLayout->SetTopMargin(30.0f); - - // Check whether we get the correct top margin - DALI_TEST_EQUALS(gridLayout->GetTopMargin(), 30.0f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliGridLayoutSetAndGetBottomMargin(void) -{ - ToolkitTestApplication application; - - // Create a grid layout - GridLayoutPtr gridLayout = GridLayout::New(); - - // Set the bottom margin - gridLayout->SetBottomMargin(30.0f); - - // Check whether we get the correct bottom margin - DALI_TEST_EQUALS(gridLayout->GetBottomMargin(), 30.0f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliGridLayoutSetAndGetSideMargin(void) -{ - ToolkitTestApplication application; - - // Create a grid layout - GridLayoutPtr gridLayout = GridLayout::New(); - - // Set the side margin - gridLayout->SetSideMargin(10.0f); - - // Check whether we get the correct side margin - DALI_TEST_EQUALS(gridLayout->GetSideMargin(), 10.0f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliGridLayoutSetAndGetZGap(void) -{ - ToolkitTestApplication application; - - // Create a grid layout - GridLayoutPtr gridLayout = GridLayout::New(); - - // Set the gap of items in the Z axis in different columns - gridLayout->SetZGap(5.0f); - - // Check whether we get the correct Z gap - DALI_TEST_EQUALS(gridLayout->GetZGap(), 5.0f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliGridLayoutSetAndGetItemSizeFunction(void) -{ - ToolkitTestApplication application; - - // Create a grid layout - GridLayoutPtr gridLayout = GridLayout::New(); - - // Set the item size function - gridLayout->SetItemSizeFunction(GridLayoutItemSizeFunction); - - // Check whether we get the correct item size function - DALI_TEST_CHECK(gridLayout->GetItemSizeFunction() == GridLayoutItemSizeFunction); - END_TEST; -} - -int UtcDaliGridLayoutSetAndGetScrollSpeedFactor(void) -{ - ToolkitTestApplication application; - - // Create a grid layout - GridLayoutPtr gridLayout = GridLayout::New(); - - // Set the scroll speed factor - gridLayout->SetScrollSpeedFactor(0.05f); - - // Check whether we get the correct scroll speed factor - DALI_TEST_EQUALS(gridLayout->GetScrollSpeedFactor(), 0.05f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliGridLayoutSetAndGetMaximumSwipeSpeed(void) -{ - ToolkitTestApplication application; - - // Create a grid layout - GridLayoutPtr gridLayout = GridLayout::New(); - - // Set the maximum swipe speed - gridLayout->SetMaximumSwipeSpeed(50.0f); - - // Check whether we get the correct maximum swipe speed - DALI_TEST_EQUALS(gridLayout->GetMaximumSwipeSpeed(), 50.0f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliGridLayoutSetAndGetItemFlickAnimationDuration(void) -{ - ToolkitTestApplication application; - - // Create a grid layout - GridLayoutPtr gridLayout = GridLayout::New(); - - // Set the flick animaiton duration - gridLayout->SetItemFlickAnimationDuration(0.35f); - - // Check whether we get the correct flick animaiton duration - DALI_TEST_EQUALS( gridLayout->GetItemFlickAnimationDuration(), 0.35f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliGridLayoutConstraintLeft(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - GridLayoutPtr gridLayout = GridLayout::New(); - gridLayout->SetNumberOfColumns(6); - - view.SetName("view actor"); - view.AddLayout(*gridLayout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - gridLayout->SetOrientation(ControlOrientation::Left); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - // Confirm: we have actors in the view and they are positioned some distance from the origin. - int nonZeroCount = 0; - int elementsFound = 0; - for(unsigned int i = 0; i < 10; i++) - { - Actor testActor = view.GetItem(i); - if (testActor) - { - elementsFound++; - Vector3 pos = testActor.GetCurrentPosition(); - - if (pos.LengthSquared() > 0.0f) - { - nonZeroCount++; - } - } - } - - DALI_TEST_CHECK((elementsFound > 0) && (nonZeroCount == elementsFound)); - Stage::GetCurrent().Remove(view); - END_TEST; -} - -int UtcDaliGridLayoutConstraintRight(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - GridLayoutPtr gridLayout = GridLayout::New(); - gridLayout->SetNumberOfColumns(6); - - view.SetName("view actor"); - view.AddLayout(*gridLayout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - gridLayout->SetOrientation(ControlOrientation::Right); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - // Confirm: we have actors in the view and they are positioned some distance from the origin. - int nonZeroCount = 0; - int elementsFound = 0; - for(unsigned int i = 0; i < 10; i++) - { - Actor testActor = view.GetItem(i); - if (testActor) - { - elementsFound++; - Vector3 pos = testActor.GetCurrentPosition(); - - if (pos.LengthSquared() > 0.0f) - { - nonZeroCount++; - } - } - } - - DALI_TEST_CHECK((elementsFound > 0) && (nonZeroCount == elementsFound)); - Stage::GetCurrent().Remove(view); - END_TEST; -} - -int UtcDaliGridLayoutConstraintUp(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - GridLayoutPtr gridLayout = GridLayout::New(); - gridLayout->SetNumberOfColumns(6); - - view.SetName("view actor"); - view.AddLayout(*gridLayout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - gridLayout->SetOrientation(ControlOrientation::Up); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - // Confirm: we have actors in the view and they are positioned some distance from the origin. - int nonZeroCount = 0; - int elementsFound = 0; - for(unsigned int i = 0; i < 10; i++) - { - Actor testActor = view.GetItem(i); - if (testActor) - { - elementsFound++; - Vector3 pos = testActor.GetCurrentPosition(); - - if (pos.LengthSquared() > 0.0f) - { - nonZeroCount++; - } - } - } - - DALI_TEST_CHECK((elementsFound > 0) && (nonZeroCount == elementsFound)); - - ItemLayoutPtr layout = gridLayout; - layout->GetClosestOnScreenLayoutPosition(0, 0.0f, vec); - int nextItem = layout->GetNextFocusItemID(0, 10, Dali::Toolkit::Control::Right, false); - DALI_TEST_CHECK(nextItem == 1); - - Stage::GetCurrent().Remove(view); - END_TEST; -} - -int UtcDaliGridLayoutConstraintDown(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - GridLayoutPtr gridLayout = GridLayout::New(); - gridLayout->SetNumberOfColumns(6); - - view.SetName("view actor"); - view.AddLayout(*gridLayout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - gridLayout->SetOrientation(ControlOrientation::Down); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - // Confirm: we have actors in the view and they are positioned some distance from the origin. - int nonZeroCount = 0; - int elementsFound = 0; - for(unsigned int i = 0; i < 10; i++) - { - Actor testActor = view.GetItem(i); - if (testActor) - { - elementsFound++; - Vector3 pos = testActor.GetCurrentPosition(); - - if (pos.LengthSquared() > 0.0f) - { - nonZeroCount++; - } - } - } - - DALI_TEST_CHECK((elementsFound > 0) && (nonZeroCount == elementsFound)); - Stage::GetCurrent().Remove(view); - END_TEST; -} - -int UtcDaliGridLayoutScrollDirection(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - GridLayoutPtr gridLayout = GridLayout::New(); - gridLayout->SetNumberOfColumns(6); - - view.SetName("view actor"); - view.AddLayout(*gridLayout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - gridLayout->SetOrientation(ControlOrientation::Left); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - ItemLayoutPtr layout = gridLayout; - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - gridLayout->SetOrientation(ControlOrientation::Up); - view.ActivateLayout(0, vec, 0.0f); - application.SendNotification(); - application.Render(); - - Degree deg = layout->GetScrollDirection(); - DALI_TEST_CHECK(deg.degree == 0.0f); - - gridLayout->SetOrientation(ControlOrientation::Down); - view.ActivateLayout(0, vec, 0.0f); - application.SendNotification(); - application.Render(); - - deg = layout->GetScrollDirection(); - DALI_TEST_CHECK((deg.degree == 180.0f)); - - layout->SetOrientation(ControlOrientation::Left); - view.ActivateLayout(0, vec, 0.0f); - application.SendNotification(); - application.Render(); - - deg = layout->GetScrollDirection(); - DALI_TEST_CHECK(deg.degree == 90.f); - - gridLayout->SetOrientation(ControlOrientation::Right); - view.ActivateLayout(0, vec, 0.0f); - application.SendNotification(); - application.Render(); - - deg = layout->GetScrollDirection(); - DALI_TEST_CHECK(deg.degree == 270.0f); - - Stage::GetCurrent().Remove(view); - END_TEST; -} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ItemLayout.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ItemLayout.cpp index dea4d52..b04201b 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ItemLayout.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ItemLayout.cpp @@ -83,7 +83,7 @@ int UtcDaliItemLayoutSetAndGetOrientation(void) ItemView view = ItemView::New(factory); // Create a grid layout and add it to ItemView - GridLayoutPtr gridLayout = GridLayout::New(); + ItemLayoutPtr gridLayout = DefaultItemLayout::New( DefaultItemLayout::GRID ); view.AddLayout(*gridLayout); // Set the orientation of the layout to be horizontal from left to right diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ItemView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ItemView.cpp index c66a650..920e152 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ItemView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ItemView.cpp @@ -143,21 +143,21 @@ int UtcDaliItemViewAddAndGetLayout(void) ItemView view = ItemView::New(factory); // Create a grid layout and add it to ItemView - GridLayoutPtr gridLayout = GridLayout::New(); + ItemLayoutPtr gridLayout = DefaultItemLayout::New( DefaultItemLayout::GRID ); view.AddLayout(*gridLayout); // As we have added one layout, check the number of layout is now 1 DALI_TEST_CHECK(view.GetLayoutCount() == 1); // Create a depth layout and add it to ItemView - DepthLayoutPtr depthLayout = DepthLayout::New(); + ItemLayoutPtr depthLayout = DefaultItemLayout::New( DefaultItemLayout::DEPTH ); view.AddLayout(*depthLayout); // As we have added another layout, check the number of layout is now 2 DALI_TEST_CHECK(view.GetLayoutCount() == 2); // Create a spiral layout and add it to ItemView - SpiralLayoutPtr spiralLayout = SpiralLayout::New(); + ItemLayoutPtr spiralLayout = DefaultItemLayout::New( DefaultItemLayout::SPIRAL ); view.AddLayout(*spiralLayout); // As we have added another layout, check the number of layout is now 3 @@ -179,14 +179,14 @@ int UtcDaliItemViewAddAndRemoveLayout(void) ItemView view = ItemView::New(factory); // Create a grid layout and add it to ItemView - GridLayoutPtr gridLayout = GridLayout::New(); + ItemLayoutPtr gridLayout = DefaultItemLayout::New( DefaultItemLayout::GRID ); view.AddLayout(*gridLayout); // As we have added one layout, check the number of layout is now 1 DALI_TEST_CHECK(view.GetLayoutCount() == 1); // Create a depth layout and add it to ItemView - DepthLayoutPtr depthLayout = DepthLayout::New(); + ItemLayoutPtr depthLayout = DefaultItemLayout::New( DefaultItemLayout::DEPTH ); view.AddLayout(*depthLayout); // As we have added another layout, check the number of layout is now 2 @@ -222,15 +222,15 @@ int UtcDaliItemViewActivateLayoutAndGetActiveLayout(void) ItemView view = ItemView::New(factory); // Create a grid layout and add it to ItemView - GridLayoutPtr gridLayout = GridLayout::New(); + ItemLayoutPtr gridLayout = DefaultItemLayout::New( DefaultItemLayout::GRID ); view.AddLayout(*gridLayout); // Create a depth layout and add it to ItemView - DepthLayoutPtr depthLayout = DepthLayout::New(); + ItemLayoutPtr depthLayout = DefaultItemLayout::New( DefaultItemLayout::DEPTH ); view.AddLayout(*depthLayout); // Create a spiral layout and add it to ItemView - SpiralLayoutPtr spiralLayout = SpiralLayout::New(); + ItemLayoutPtr spiralLayout = DefaultItemLayout::New( DefaultItemLayout::SPIRAL ); view.AddLayout(*spiralLayout); // As we have added three layouts, check the number of layout is now 3 @@ -269,7 +269,7 @@ int UtcDaliItemViewDeactivateCurrentLayout(void) ItemView view = ItemView::New(factory); // Create a grid layout and add it to ItemView - GridLayoutPtr gridLayout = GridLayout::New(); + ItemLayoutPtr gridLayout = DefaultItemLayout::New( DefaultItemLayout::GRID ); view.AddLayout(*gridLayout); // Check there is no active layout at the moment @@ -299,7 +299,7 @@ int UtcDaliItemViewGetItemAndGetItemId(void) ItemView view = ItemView::New(factory); // Create a grid layout and add it to ItemView - GridLayoutPtr gridLayout = GridLayout::New(); + ItemLayoutPtr gridLayout = DefaultItemLayout::New( DefaultItemLayout::GRID ); view.AddLayout(*gridLayout); // Activate the grid layout so that the items will be created and added to ItemView @@ -323,7 +323,7 @@ int UtcDaliItemViewRemoveItem(void) ItemView view = ItemView::New(factory); // Create a grid layout and add it to ItemView - GridLayoutPtr gridLayout = GridLayout::New(); + ItemLayoutPtr gridLayout = DefaultItemLayout::New( DefaultItemLayout::GRID ); view.AddLayout(*gridLayout); // Activate the grid layout so that the items will be created and added to ItemView @@ -356,7 +356,7 @@ int UtcDaliItemViewGetCurrentLayoutPosition(void) ItemView view = ItemView::New(factory); // Create a grid layout and add it to ItemView - GridLayoutPtr gridLayout = GridLayout::New(); + ItemLayoutPtr gridLayout = DefaultItemLayout::New( DefaultItemLayout::GRID ); view.AddLayout(*gridLayout); // Activate the grid layout so that the items will be created and added to ItemView @@ -456,7 +456,7 @@ int UtcDaliItemViewScrollToItem(void) TestItemFactory factory; ItemView view = ItemView::New(factory); Vector3 vec(480.0f, 800.0f, 0.0f); - GridLayoutPtr layout = GridLayout::New(); + ItemLayoutPtr layout = DefaultItemLayout::New( DefaultItemLayout::GRID ); view.SetName("view actor"); view.AddLayout(*layout); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-SpiralLayout.cpp b/automated-tests/src/dali-toolkit/utc-Dali-SpiralLayout.cpp deleted file mode 100644 index 2bed81a..0000000 --- a/automated-tests/src/dali-toolkit/utc-Dali-SpiralLayout.cpp +++ /dev/null @@ -1,570 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include -#include -#include // for FLT_MAX -#include -#include - - -using namespace Dali; -using namespace Toolkit; - -void spiral_layout_startup(void) -{ - test_return_value = TET_UNDEF; -} - -void spiral_layout_cleanup(void) -{ - test_return_value = TET_PASS; -} - -namespace -{ -const unsigned int TOTAL_ITEM_NUMBER = 200; - -Vector3 SpiralLayoutItemSizeFunction(const Vector3& layoutSize) -{ - float width = layoutSize.width * 0.2f; - return Vector3(width, width, width); -} - -float SpiralLayoutSpiralRadiusFunction(const Vector3& layoutSize) -{ - return layoutSize.width * 0.5f; -} - - -// Implementation of ItemFactory for providing actors to ItemView -class TestItemFactory : public ItemFactory -{ -public: - - /** - * Constructor - * @param application class, stored as reference - */ - TestItemFactory() - { - } - -public: // From ItemFactory - - /** - * Query the number of items available from the factory. - * The maximum available item has an ID of GetNumberOfItems() - 1. - */ - virtual unsigned int GetNumberOfItems() - { - return TOTAL_ITEM_NUMBER; - } - - /** - * Create an Actor to represent a visible item. - * @param itemId - * @return the created actor. - */ - virtual Actor NewItem(unsigned int itemId) - { - // Create an test actor for this item - ImageActor actor = CreateSolidColorActor(Color::RED); - actor.SetSize(64.0f, 64.0f); - - return actor; - } -}; - -} // namespace - - -int UtcDaliSpiralLayoutNew(void) -{ - ToolkitTestApplication application; - - // Create a spiral layout - SpiralLayoutPtr spiralLayout = SpiralLayout::New(); - - DALI_TEST_CHECK(spiralLayout); - END_TEST; -} - -int UtcDaliSpiralSetAndGetItemSizeFunction(void) -{ - ToolkitTestApplication application; - - // Create a spiral layout - SpiralLayoutPtr spiralLayout = SpiralLayout::New(); - - // Set the item size function - spiralLayout->SetItemSizeFunction(SpiralLayoutItemSizeFunction); - - // Check whether we get the correct item size function - DALI_TEST_CHECK(spiralLayout->GetItemSizeFunction() == SpiralLayoutItemSizeFunction); - END_TEST; -} - -int UtcDaliSpiralSetAndGetItemSpacing(void) -{ - ToolkitTestApplication application; - - // Create a spiral layout - SpiralLayoutPtr spiralLayout = SpiralLayout::New(); - - // Set the item spacing - spiralLayout->SetItemSpacing(Radian(0.6f)); - - // Check whether we get the correct item spacing - DALI_TEST_EQUALS(spiralLayout->GetItemSpacing(), Radian(0.6f), TEST_LOCATION ); - END_TEST; -} - -int UtcDaliSpiralSetAndGetRevolutionDistance(void) -{ - ToolkitTestApplication application; - - // Create a spiral layout - SpiralLayoutPtr spiralLayout = SpiralLayout::New(); - - // Set the revolution distance - spiralLayout->SetRevolutionDistance(150.0f); - - // Check whether we get the correct revolution distance - DALI_TEST_EQUALS(spiralLayout->GetRevolutionDistance(), 150.0f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliSpiralSetAndGetSpiralRadiusFunction(void) -{ - ToolkitTestApplication application; - - // Create a spiral layout - SpiralLayoutPtr spiralLayout = SpiralLayout::New(); - - // Set the spiral radius function - spiralLayout->SetSpiralRadiusFunction(SpiralLayoutSpiralRadiusFunction); - - // Check whether we get the correct spiral radius function - DALI_TEST_CHECK(spiralLayout->GetSpiralRadiusFunction() == SpiralLayoutSpiralRadiusFunction); - END_TEST; -} - -int UtcDaliSpiralSetAndGetTopItemAlignment(void) -{ - ToolkitTestApplication application; - - // Create a spiral layout - SpiralLayoutPtr spiralLayout = SpiralLayout::New(); - - // Set the alignment of the top item - spiralLayout->SetTopItemAlignment(-0.25f); - - // Check whether we get the correct alignment of the top item - DALI_TEST_EQUALS(spiralLayout->GetTopItemAlignment(), -0.25f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliSpiralSetAndGetScrollSpeedFactor(void) -{ - ToolkitTestApplication application; - - // Create a spiral layout - SpiralLayoutPtr spiralLayout = SpiralLayout::New(); - - // Set the scroll speed factor - spiralLayout->SetScrollSpeedFactor(0.05f); - - // Check whether we get the correct scroll speed factor - DALI_TEST_EQUALS(spiralLayout->GetScrollSpeedFactor(), 0.05f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliSpiralSetAndGetMaximumSwipeSpeed(void) -{ - ToolkitTestApplication application; - - // Create a spiral layout - SpiralLayoutPtr spiralLayout = SpiralLayout::New(); - - // Set the maximum swipe speed - spiralLayout->SetMaximumSwipeSpeed(50.0f); - - // Check whether we get the correct maximum swipe speed - DALI_TEST_EQUALS(spiralLayout->GetMaximumSwipeSpeed(), 50.0f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliSpiralLayoutSetAndGetItemFlickAnimationDuration(void) -{ - ToolkitTestApplication application; - - // Create a spiral layout - SpiralLayoutPtr spiralLayout = SpiralLayout::New(); - - // Set the flick animaiton duration - spiralLayout->SetItemFlickAnimationDuration(0.35f); - - // Check whether we get the correct flick animaiton duration - DALI_TEST_EQUALS( spiralLayout->GetItemFlickAnimationDuration(), 0.35f, TEST_LOCATION ); - END_TEST; -} - -int UtcDaliSpiralLayoutConstraintLeft(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - SpiralLayoutPtr layout = SpiralLayout::New(); - - view.SetName("view actor"); - view.AddLayout(*layout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - layout->SetOrientation(ControlOrientation::Left); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - // Confirm: we have actors in the view and they are positioned some distance from the origin. - int nonZeroCount = 0; - int elementsFound = 0; - for(unsigned int i = 0; i < 10; i++) - { - Actor testActor = view.GetItem(i); - if (testActor) - { - elementsFound++; - Vector3 pos = testActor.GetCurrentPosition(); - - if (pos.LengthSquared() > 0.0f) - { - nonZeroCount++; - } - } - } - - DALI_TEST_CHECK((elementsFound > 0) && (nonZeroCount == elementsFound)); - Stage::GetCurrent().Remove(view); - END_TEST; -} - -int UtcDaliSpiralLayoutConstraintRight(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - SpiralLayoutPtr layout = SpiralLayout::New(); - - view.SetName("view actor"); - view.AddLayout(*layout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - layout->SetOrientation(ControlOrientation::Right); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - // Confirm: we have actors in the view and they are positioned some distance from the origin. - int nonZeroCount = 0; - int elementsFound = 0; - for(unsigned int i = 0; i < 10; i++) - { - Actor testActor = view.GetItem(i); - if (testActor) - { - elementsFound++; - Vector3 pos = testActor.GetCurrentPosition(); - - if (pos.LengthSquared() > 0.0f) - { - nonZeroCount++; - } - } - } - - DALI_TEST_CHECK((elementsFound > 0) && (nonZeroCount == elementsFound)); - Stage::GetCurrent().Remove(view); - END_TEST; -} - -int UtcDaliSpiralLayoutConstraintUp(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - SpiralLayoutPtr layout = SpiralLayout::New(); - - view.SetName("view actor"); - view.AddLayout(*layout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - layout->SetOrientation(ControlOrientation::Up); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - // Confirm: we have actors in the view and they are positioned some distance from the origin. - int nonZeroCount = 0; - int elementsFound = 0; - for(unsigned int i = 0; i < 10; i++) - { - Actor testActor = view.GetItem(i); - if (testActor) - { - elementsFound++; - Vector3 pos = testActor.GetCurrentPosition(); - - if (pos.LengthSquared() > 0.0f) - { - nonZeroCount++; - } - } - } - - DALI_TEST_CHECK((elementsFound > 0) && (nonZeroCount == elementsFound)); - - layout->GetClosestOnScreenLayoutPosition(0, 0.0f, vec); - int nextItem = layout->GetNextFocusItemID(0, 10, Dali::Toolkit::Control::Right, false); - DALI_TEST_CHECK(nextItem == 1); - - Stage::GetCurrent().Remove(view); - END_TEST; -} - -int UtcDaliSpiralLayoutConstraintDown(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - SpiralLayoutPtr layout = SpiralLayout::New(); - - view.SetName("view actor"); - view.AddLayout(*layout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - layout->SetOrientation(ControlOrientation::Down); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - // Confirm: we have actors in the view and they are positioned some distance from the origin. - int nonZeroCount = 0; - int elementsFound = 0; - for(unsigned int i = 0; i < 10; i++) - { - Actor testActor = view.GetItem(i); - if (testActor) - { - elementsFound++; - Vector3 pos = testActor.GetCurrentPosition(); - - if (pos.LengthSquared() > 0.0f) - { - nonZeroCount++; - } - } - } - - DALI_TEST_CHECK((elementsFound > 0) && (nonZeroCount == elementsFound)); - Stage::GetCurrent().Remove(view); - END_TEST; -} - -int UtcDaliSpiralLayoutScrollDirection(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - SpiralLayoutPtr navigationLayout = SpiralLayout::New(); - - view.SetName("view actor"); - view.AddLayout(*navigationLayout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - navigationLayout->SetOrientation(ControlOrientation::Left); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - ItemLayoutPtr layout = navigationLayout; - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - navigationLayout->SetOrientation(ControlOrientation::Up); - view.ActivateLayout(0, vec, 0.0f); - application.SendNotification(); - application.Render(); - - Degree deg = layout->GetScrollDirection(); - DALI_TEST_CHECK(deg.degree == -45.0f); - - navigationLayout->SetOrientation(ControlOrientation::Down); - view.ActivateLayout(0, vec, 0.0f); - application.SendNotification(); - application.Render(); - - deg = layout->GetScrollDirection(); - DALI_TEST_CHECK((deg.degree == 180.0f - 45.0f)); - - layout->SetOrientation(ControlOrientation::Left); - view.ActivateLayout(0, vec, 0.0f); - application.SendNotification(); - application.Render(); - - deg = layout->GetScrollDirection(); - DALI_TEST_CHECK(deg.degree == 45.0f); - - navigationLayout->SetOrientation(ControlOrientation::Right); - view.ActivateLayout(0, vec, 0.0f); - application.SendNotification(); - application.Render(); - - deg = layout->GetScrollDirection(); - DALI_TEST_CHECK(deg.degree == (270.0f - 45.0f)); - - Stage::GetCurrent().Remove(view); - END_TEST; -} - -int UtcDaliSpiralLayoutGetScrollToPosition(void) -{ - ToolkitTestApplication application; - - // Create the ItemView actor - TestItemFactory factory; - ItemView view = ItemView::New(factory); - Vector3 vec(480.0f, 800.0f, 0.0f); - SpiralLayoutPtr layout = SpiralLayout::New(); - - view.SetName("view actor"); - view.AddLayout(*layout); - view.SetSize(vec); - - Stage::GetCurrent().Add(view); - layout->SetOrientation(ControlOrientation::Up); - view.ActivateLayout(0, vec, 0.0f); - - application.SendNotification(); - application.Render(0); - - // render 10 frames - for(int i = 0; i < 10; ++i) - { - application.Render(16); // 60hz frames - } - - // Confirm: we have actors in the view. - std::vector indices; - for(unsigned int i = 0; i < 10; i++) - { - Actor testActor = view.GetItem(i); - if (testActor) - { - indices.push_back(i); - } - } - - try - { - if (!indices.empty()) - { - const unsigned int firstTargetIndex = indices[indices.size()-1]; - // scroll to last item - view.ScrollToItem(firstTargetIndex, 0.00f); - application.Render(16); // 60hz frames - - std::size_t moveCount = 0; - for(std::size_t i = 0; i < indices.size(); i++) - { - float layoutPosBefore = view.GetCurrentLayoutPosition(i); - view.ScrollToItem(indices[i], 0.0f); - - application.Render(16); // 60hz frame - - float layoutPosAfter = view.GetCurrentLayoutPosition(i); - - if (fabs(layoutPosBefore-layoutPosAfter) <= FLT_EPSILON) - { - ++moveCount; - } - } - - DALI_TEST_CHECK((moveCount == indices.size())); - } - } - catch(...) - { - tet_result(TET_FAIL); - } - - Stage::GetCurrent().Remove(view); - END_TEST; -} diff --git a/dali-toolkit/dali-toolkit.h b/dali-toolkit/dali-toolkit.h index fe3a2f9..6930e46 100644 --- a/dali-toolkit/dali-toolkit.h +++ b/dali-toolkit/dali-toolkit.h @@ -45,12 +45,10 @@ #include #include #include -#include -#include +#include #include #include #include -#include #include #include #include diff --git a/dali-toolkit/internal/controls/scrollable/item-view/depth-layout.cpp b/dali-toolkit/internal/controls/scrollable/item-view/depth-layout.cpp new file mode 100644 index 0000000..34838ad --- /dev/null +++ b/dali-toolkit/internal/controls/scrollable/item-view/depth-layout.cpp @@ -0,0 +1,618 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include +#include +#include + +// INTERNAL INCLUDES +#include + +using namespace Dali; +using namespace Dali::Toolkit; + +namespace // unnamed namespace +{ + +const unsigned int DEFAULT_NUMBER_OF_COLUMNS = 3; +const float DEFAULT_NUMBER_OF_ROWS = 26.0f; +const float DEFAULT_ROW_SPACING = 55.0f; +const float DEFAULT_BOTTOM_MARGIN_FACTOR = 0.2f; +const Radian DEFAULT_TILT_ANGLE ( Math::PI*0.15f ); +const Radian DEFAULT_ITEM_TILT_ANGLE ( -Math::PI*0.025f ); +const float DEFAULT_SCROLL_SPEED_FACTOR = 0.02f; +const float DEFAULT_MAXIMUM_SWIPE_SPEED = 50.0f; +const float DEFAULT_ITEM_FLICK_ANIMATION_DURATION = 0.03f; + +inline float GetColumnPosition( unsigned int numberOfColumns, unsigned int columnNumber, const Vector3& itemSize, float layoutWidth ) +{ + // Share the available space between margins & column spacings + float availableSpace = std::max( 0.0f, ( layoutWidth - itemSize.width * numberOfColumns ) ); + + float leftMargin = availableSpace / numberOfColumns * 0.5f; + + float columnPosition = leftMargin + itemSize.width * 0.5f + columnNumber * ( itemSize.width + availableSpace / numberOfColumns ); + + return columnPosition - layoutWidth * 0.5f; +} + +struct DepthPositionConstraint +{ + DepthPositionConstraint( unsigned int itemId, + unsigned int numberOfColumns, + unsigned int columnNumber, + const Vector3& itemSize, + float heightScale, + float depthScale ) + : mItemSize( itemSize ), + mItemId( itemId ), + mNumberOfColumns( numberOfColumns ), + mColumnNumber( columnNumber ), + mHeightScale( heightScale ), + mDepthScale( depthScale ) + { + } + + inline void Orientation0( Vector3& current, float layoutPosition, const Vector3& layoutSize ) + { + float rowLayoutPositon = layoutPosition - static_cast< float >( mColumnNumber ); + + current.x = GetColumnPosition( mNumberOfColumns, mColumnNumber, mItemSize, layoutSize.width ); + current.y = rowLayoutPositon * mHeightScale + layoutSize.height * 0.5f - DEFAULT_BOTTOM_MARGIN_FACTOR * layoutSize.height - mItemSize.height * 0.5f; + current.z = -rowLayoutPositon * mDepthScale; + } + + inline void Orientation90( Vector3& current, float layoutPosition, const Vector3& layoutSize ) + { + float rowLayoutPositon = layoutPosition - static_cast< float >( mColumnNumber ) + mNumberOfColumns * 0.5f; + + current.x = rowLayoutPositon * mHeightScale + layoutSize.width * 0.5f - DEFAULT_BOTTOM_MARGIN_FACTOR * layoutSize.width - mItemSize.height * 0.5f; + current.y = -GetColumnPosition( mNumberOfColumns, mColumnNumber, mItemSize, layoutSize.height ); + current.z = -rowLayoutPositon * mDepthScale; + } + + inline void Orientation180( Vector3& current, float layoutPosition, const Vector3& layoutSize ) + { + float rowLayoutPositon = layoutPosition - static_cast< float >( mColumnNumber ); + + current.x = -GetColumnPosition( mNumberOfColumns, mColumnNumber, mItemSize, layoutSize.width ); + current.y = -( rowLayoutPositon * mHeightScale + layoutSize.height * 0.5f - DEFAULT_BOTTOM_MARGIN_FACTOR * layoutSize.height - mItemSize.height * 0.5f ); + current.z = -rowLayoutPositon * mDepthScale; + } + + inline void Orientation270( Vector3& current, float layoutPosition, const Vector3& layoutSize ) + { + float rowLayoutPositon = layoutPosition - static_cast< float >( mColumnNumber ) + mNumberOfColumns * 0.5f; + + current.x = -( rowLayoutPositon * mHeightScale + layoutSize.width * 0.5f - DEFAULT_BOTTOM_MARGIN_FACTOR * layoutSize.width - mItemSize.height * 0.5f ); + current.y = GetColumnPosition( mNumberOfColumns, mColumnNumber, mItemSize, layoutSize.height ); + current.z = -rowLayoutPositon * mDepthScale; + } + + void Orientation0( Vector3& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + Orientation0( current, layoutPosition, layoutSize ); + } + + void Orientation90( Vector3& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + Orientation90( current, layoutPosition, layoutSize ); + } + + void Orientation180( Vector3& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + Orientation180( current, layoutPosition, layoutSize ); + } + + void Orientation270( Vector3& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + Orientation270( current, layoutPosition, layoutSize ); + } + + Vector3 mItemSize; + unsigned int mItemId; + unsigned int mNumberOfColumns; + unsigned int mColumnNumber; + float mHeightScale; + float mDepthScale; +}; + +struct DepthRotationConstraint +{ + DepthRotationConstraint( Radian angleRadians, ControlOrientation::Type orientation ) + : mTiltAngle( angleRadians ), + mMultiplier( 0.0f ) + { + if ( orientation == ControlOrientation::Up ) + { + mMultiplier = 0.0f; + } + else if ( orientation == ControlOrientation::Left ) + { + mMultiplier = 1.5f; + } + else if ( orientation == ControlOrientation::Down ) + { + mMultiplier = -1.0f; + } + else // orientation == ControlOrientation::Right + { + mMultiplier = 0.5f; + } + } + + void operator()( Quaternion& current, const PropertyInputContainer& /* inputs */ ) + { + current = Quaternion( Radian( mMultiplier * Math::PI ), Vector3::ZAXIS ) * Quaternion( mTiltAngle, Vector3::XAXIS ); + } + + Radian mTiltAngle; + float mMultiplier; +}; + +struct DepthColorConstraint +{ + DepthColorConstraint( unsigned int itemId, unsigned int numberOfColumns, float numberOfRows, unsigned int columnNumber ) + : mItemId( itemId ), + mNumberOfColumns( numberOfColumns ), + mNumberOfRows( numberOfRows ), + mColumnNumber( columnNumber ) + { + } + + void operator()( Vector4& current, const Dali::PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + float row = ( layoutPosition - static_cast( mColumnNumber ) ) / mNumberOfColumns; + + float darkness(1.0f); + float alpha(1.0f); + + if (row < 0.0f) + { + darkness = alpha = std::max(0.0f, 1.0f + row); + } + else + { + if (row > mNumberOfRows) + { + darkness = 0.0f; + } + else + { + darkness = 1.0f - ( 1.0f * (row / mNumberOfRows) ); + } + + if (row > (mNumberOfRows-1.0f)) + { + alpha = std::max(0.0f, 1.0f - (row-(mNumberOfRows-1.0f))); + } + } + + current.r = current.g = current.b = darkness; + current.a *= alpha; + } + + unsigned int mItemId; + unsigned int mNumberOfColumns; + float mNumberOfRows; + unsigned int mColumnNumber; +}; + +struct DepthVisibilityConstraint +{ + DepthVisibilityConstraint( unsigned int itemId, unsigned int numberOfColumns, float numberOfRows, unsigned int columnNumber ) + : mItemId( itemId ), + mNumberOfColumns(numberOfColumns), + mNumberOfRows(numberOfRows), + mColumnNumber(columnNumber) + { + } + + void operator()( bool& current, const Dali::PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + float row = ( layoutPosition - static_cast< float >( mColumnNumber ) ) / mNumberOfColumns; + + current = ( row > -1.0f ) && ( row < mNumberOfRows ); + } + + unsigned int mItemId; + unsigned int mNumberOfColumns; + float mNumberOfRows; + unsigned int mColumnNumber; +}; + +} // unnamed namespace + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +struct DepthLayout::Impl +{ + Impl() + : mNumberOfColumns(DEFAULT_NUMBER_OF_COLUMNS), + mNumberOfRows(DEFAULT_NUMBER_OF_ROWS), + mRowSpacing(DEFAULT_ROW_SPACING), + mTiltAngle(DEFAULT_TILT_ANGLE), + mItemTiltAngle(DEFAULT_ITEM_TILT_ANGLE), + mScrollSpeedFactor(DEFAULT_SCROLL_SPEED_FACTOR), + mMaximumSwipeSpeed(DEFAULT_MAXIMUM_SWIPE_SPEED), + mItemFlickAnimationDuration(DEFAULT_ITEM_FLICK_ANIMATION_DURATION) + { + } + + unsigned int mNumberOfColumns; + unsigned int mNumberOfRows; + + float mRowSpacing; + + Radian mTiltAngle; + Radian mItemTiltAngle; + + float mScrollSpeedFactor; + float mMaximumSwipeSpeed; + float mItemFlickAnimationDuration; +}; + +DepthLayoutPtr DepthLayout::New() +{ + return DepthLayoutPtr(new DepthLayout()); +} + +DepthLayout::~DepthLayout() +{ + delete mImpl; +} + +void DepthLayout::SetNumberOfColumns(unsigned int columns) +{ + mImpl->mNumberOfColumns = columns; +} + +unsigned int DepthLayout::GetNumberOfColumns() const +{ + return mImpl->mNumberOfColumns; +} + +void DepthLayout::SetNumberOfRows(unsigned int rows) +{ + mImpl->mNumberOfRows = rows; +} + +unsigned int DepthLayout::GetNumberOfRows() const +{ + return mImpl->mNumberOfRows; +} + +void DepthLayout::SetRowSpacing(float spacing) +{ + mImpl->mRowSpacing = spacing; +} + +float DepthLayout::GetRowSpacing() const +{ + return mImpl->mRowSpacing; +} + +void DepthLayout::SetTiltAngle(Degree angle) +{ + mImpl->mTiltAngle = Degree( Clamp( angle, -45.0f, 45.0f ) ); +} + +Degree DepthLayout::GetTiltAngle() const +{ + return Degree( mImpl->mTiltAngle ); +} + +void DepthLayout::SetItemTiltAngle(Degree angle) +{ + mImpl->mItemTiltAngle = angle; +} + +Degree DepthLayout::GetItemTiltAngle() const +{ + return Degree( mImpl->mItemTiltAngle ); +} + +void DepthLayout::SetScrollSpeedFactor(float scrollSpeed) +{ + mImpl->mScrollSpeedFactor = scrollSpeed; +} + +void DepthLayout::SetMaximumSwipeSpeed(float speed) +{ + mImpl->mMaximumSwipeSpeed = speed; +} + +void DepthLayout::SetItemFlickAnimationDuration(float durationSeconds) +{ + mImpl->mItemFlickAnimationDuration = durationSeconds; +} + +float DepthLayout::GetScrollSpeedFactor() const +{ + return mImpl->mScrollSpeedFactor; +} + +float DepthLayout::GetMaximumSwipeSpeed() const +{ + return mImpl->mMaximumSwipeSpeed; +} + +float DepthLayout::GetItemFlickAnimationDuration() const +{ + return mImpl->mItemFlickAnimationDuration; +} + +float DepthLayout::GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const +{ + return static_cast(mImpl->mNumberOfColumns) - static_cast(numberOfItems); +} + +float DepthLayout::GetClosestAnchorPosition(float layoutPosition) const +{ + float rowIndex = static_cast(round(layoutPosition / mImpl->mNumberOfColumns)); + return rowIndex * static_cast(mImpl->mNumberOfColumns); +} + +float DepthLayout::GetItemScrollToPosition(unsigned int itemId) const +{ + float rowIndex = static_cast(itemId / mImpl->mNumberOfColumns); + return -rowIndex * static_cast(mImpl->mNumberOfColumns); +} + +ItemRange DepthLayout::GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const +{ + float firstRow = -(firstItemPosition/mImpl->mNumberOfColumns); + float lastRow = firstRow + mImpl->mNumberOfRows * 0.5f; + + unsigned int firstItem = static_cast(std::max(0.0f, firstRow * mImpl->mNumberOfColumns)); + unsigned int lastItem = static_cast(std::max(0.0f, lastRow * mImpl->mNumberOfColumns)); + + return ItemRange(firstItem, lastItem+1); +} + +unsigned int DepthLayout::GetReserveItemCount(Vector3 layoutSize) const +{ + float itemsWithinLayout = (layoutSize.depth * mImpl->mNumberOfColumns) / (cosf(mImpl->mTiltAngle) * mImpl->mRowSpacing); + + return static_cast(itemsWithinLayout); +} + +void DepthLayout::GetDefaultItemSize( unsigned int itemId, const Vector3& layoutSize, Vector3& itemSize ) const +{ + // 1x1 aspect ratio + itemSize.width = itemSize.height = itemSize.depth = ( IsVertical( GetOrientation() ) ? layoutSize.width : layoutSize.height ) / static_cast( mImpl->mNumberOfColumns + 1 ); +} + +void DepthLayout::GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const +{ + if(animation) + { + animation.AnimateTo( Property( actor, Actor::Property::SIZE ), size ); + } +} + +Degree DepthLayout::GetScrollDirection() const +{ + Degree scrollDirection(0.0f); + ControlOrientation::Type orientation = GetOrientation(); + + if ( orientation == ControlOrientation::Up ) + { + scrollDirection = Degree( 180.0f ); + } + else if ( orientation == ControlOrientation::Left ) + { + scrollDirection = Degree( 270.0f ); + } + else if ( orientation == ControlOrientation::Down ) + { + scrollDirection = Degree( 0.0f ); + } + else // orientation == ControlOrientation::Right + { + scrollDirection = Degree( 90.0f ); + } + + return scrollDirection; +} + +void DepthLayout::ApplyConstraints( Actor& actor, const int itemId, const Vector3& layoutSize, const Actor& itemViewActor ) +{ + Dali::Toolkit::ItemView itemView = Dali::Toolkit::ItemView::DownCast( itemViewActor ); + if( itemView ) + { + Vector3 itemSize; + GetItemSize( itemId, layoutSize, itemSize ); + + ControlOrientation::Type orientation = GetOrientation(); + + // Position constraint + Constraint constraint; + DepthPositionConstraint depthPositionStruct( itemId, + mImpl->mNumberOfColumns, + itemId % mImpl->mNumberOfColumns, + itemSize, + -sinf( mImpl->mTiltAngle ) * mImpl->mRowSpacing, + cosf( mImpl->mTiltAngle ) * mImpl->mRowSpacing ); + if ( orientation == ControlOrientation::Up ) + { + constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, depthPositionStruct, &DepthPositionConstraint::Orientation0 ); + } + else if ( orientation == ControlOrientation::Left ) + { + constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, depthPositionStruct, &DepthPositionConstraint::Orientation90 ); + } + else if ( orientation == ControlOrientation::Down ) + { + constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, depthPositionStruct, &DepthPositionConstraint::Orientation180 ); + } + else // orientation == ControlOrientation::Right + { + constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, depthPositionStruct, &DepthPositionConstraint::Orientation270 ); + } + constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) ); + constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); + constraint.Apply(); + + // Rotation constraint + constraint = Constraint::New< Quaternion >( actor, Actor::Property::ORIENTATION, DepthRotationConstraint( mImpl->mItemTiltAngle, orientation ) ); + constraint.Apply(); + + // Color constraint + constraint = Constraint::New< Vector4 >( actor, Actor::Property::COLOR, DepthColorConstraint( itemId, mImpl->mNumberOfColumns, mImpl->mNumberOfRows*0.5f, itemId % mImpl->mNumberOfColumns ) ); + constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) ); + constraint.SetRemoveAction( Dali::Constraint::Discard ); + constraint.Apply(); + + // Visibility constraint + constraint = Constraint::New< bool >( actor, Actor::Property::VISIBLE, DepthVisibilityConstraint( itemId, mImpl->mNumberOfColumns, mImpl->mNumberOfRows*0.5f, itemId % mImpl->mNumberOfColumns ) ); + constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) ); + constraint.SetRemoveAction( Dali::Constraint::Discard ); + constraint.Apply(); + } +} + +Vector3 DepthLayout::GetItemPosition( int itemID, float currentLayoutPosition, const Vector3& layoutSize ) const +{ + Vector3 itemPosition = Vector3::ZERO; + + const float heightScale = -sinf( mImpl->mTiltAngle ) * mImpl->mRowSpacing; + const float depthScale = cosf( mImpl->mTiltAngle ) * mImpl->mRowSpacing; + + Vector3 itemSize; + GetItemSize( itemID, layoutSize, itemSize ); + DepthPositionConstraint positionFunctor = DepthPositionConstraint( itemID, + mImpl->mNumberOfColumns, + itemID % mImpl->mNumberOfColumns, + itemSize, + heightScale, + depthScale ); + ControlOrientation::Type orientation = GetOrientation(); + if ( orientation == ControlOrientation::Up ) + { + positionFunctor.Orientation0( itemPosition, currentLayoutPosition + itemID, layoutSize ); + } + else if ( orientation == ControlOrientation::Left ) + { + positionFunctor.Orientation90( itemPosition, currentLayoutPosition + itemID, layoutSize ); + } + else if ( orientation == ControlOrientation::Down ) + { + positionFunctor.Orientation180( itemPosition, currentLayoutPosition + itemID, layoutSize ); + } + else // orientation == ControlOrientation::Right + { + positionFunctor.Orientation270( itemPosition, currentLayoutPosition + itemID, layoutSize ); + } + + return itemPosition; +} + +DepthLayout::DepthLayout() +: mImpl(NULL) +{ + mImpl = new Impl(); +} + +float DepthLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) +{ + float scrollTo = currentLayoutPosition; + float row = (currentLayoutPosition + itemID - static_cast(itemID % mImpl->mNumberOfColumns)) / mImpl->mNumberOfColumns; + + // Check whether item is not within viewable area + if(row <= -1.0f) + { + scrollTo = GetItemScrollToPosition(itemID); + } + else if(row > mImpl->mNumberOfRows * 0.5f - 1.0f) + { + scrollTo = GetItemScrollToPosition(itemID) + (mImpl->mNumberOfRows - 1.0f) * 0.5f * mImpl->mNumberOfColumns; + } + + return scrollTo; +} + +int DepthLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled) +{ + switch( direction ) + { + case Toolkit::Control::Left: + { + itemID--; + if( itemID < 0 ) + { + itemID = loopEnabled ? maxItems - 1 : 0; + } + break; + } + case Toolkit::Control::Up: + { + itemID += mImpl->mNumberOfColumns; + if( itemID >= maxItems ) + { + itemID = loopEnabled ? 0 : itemID - mImpl->mNumberOfColumns; + } + break; + } + case Toolkit::Control::Right: + { + itemID++; + if( itemID >= maxItems ) + { + itemID = loopEnabled ? 0 : maxItems - 1; + } + break; + } + case Toolkit::Control::Down: + { + itemID -= mImpl->mNumberOfColumns; + if( itemID < 0 ) + { + itemID = loopEnabled ? itemID + maxItems : itemID + mImpl->mNumberOfColumns; + } + break; + } + } + return itemID; +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/public-api/controls/scrollable/item-view/depth-layout.h b/dali-toolkit/internal/controls/scrollable/item-view/depth-layout.h similarity index 67% rename from dali-toolkit/public-api/controls/scrollable/item-view/depth-layout.h rename to dali-toolkit/internal/controls/scrollable/item-view/depth-layout.h index 9452931..1d16a03 100644 --- a/dali-toolkit/public-api/controls/scrollable/item-view/depth-layout.h +++ b/dali-toolkit/internal/controls/scrollable/item-view/depth-layout.h @@ -27,6 +27,9 @@ namespace Dali namespace Toolkit { +namespace Internal +{ + class DepthLayout; typedef IntrusivePtr DepthLayoutPtr; @@ -34,19 +37,10 @@ typedef IntrusivePtr DepthLayoutPtr; /** * This layout arranges items in a grid, which scrolls along the Z-Axis. */ -class DALI_IMPORT_API DepthLayout : public ItemLayout +class DepthLayout : public ItemLayout { public: - typedef boost::function ItemSizeFunction; - - typedef boost::function BottomMarginFunction; - - typedef boost::function ColumnPositionFunction; - /** * Create a new spiral layout */ @@ -107,30 +101,6 @@ public: Degree GetTiltAngle() const; /** - * Set the function used to calculate the item-size, for a given layout-size. - * @param[in] function The item-size function. - */ - void SetItemSizeFunction(ItemSizeFunction function); - - /** - * Get the function used to calculate the item-size. - * @return The item-size function. - */ - ItemSizeFunction GetItemSizeFunction() const; - - /** - * Set the function used to calculate the margin in the bottom of the layout, for a given layout-size. - * @param[in] function The bottom margin function. - */ - void SetBottomMarginFunction(BottomMarginFunction function); - - /** - * Get the function used to calculate the margin in the bottom of the layout. - * @return The bottom margin function. - */ - BottomMarginFunction GetBottomMarginFunction() const; - - /** * Set the tilt angle of the individual items in the layout. * @param[in] angle The item tilt angle in degrees. */ @@ -143,18 +113,6 @@ public: Degree GetItemTiltAngle() const; /** - * Set the function used to calculate the horizontal position of each column, for a given column, item-size & layout-size. - * @param[in] function The column-position function. - */ - void SetColumnPositionFunction(ColumnPositionFunction function); - - /** - * Get the function used to calculate the horizontal position of each column - * @return The column-position function. - */ - ColumnPositionFunction GetColumnPositionFunction() const; - - /** * Set the factor used to customise the scroll speed while dragging and swiping the layout. * @param[in] scrollSpeed The scroll speed factor. */ @@ -228,9 +186,9 @@ private: virtual unsigned int GetReserveItemCount(Vector3 layoutSize) const; /** - * @copydoc ItemLayout::GetItemSize() + * @copydoc ItemLayout::GetDefaultItemSize() */ - virtual bool GetItemSize(unsigned int itemId, Vector3 layoutSize, Vector3& itemSize) const; + virtual void GetDefaultItemSize( unsigned int itemId, const Vector3& layoutSize, Vector3& itemSize ) const; /** * @copydoc ItemLayout::GetResizeAnimation() @@ -238,34 +196,19 @@ private: virtual void GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const; /** - * @copydoc ItemLayout::GetPositionConstraint() - */ - virtual bool GetPositionConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const; - - /** - * @copydoc ItemLayout::GetRotationConstraint() - */ - virtual bool GetRotationConstraint(unsigned int itemId, ItemLayout::QuaternionFunction& constraint) const; - - /** - * @copydoc ItemLayout::GetScaleConstraint() - */ - virtual bool GetScaleConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const; - - /** - * @copydoc ItemLayout::GetColorConstraint() + * @copydoc ItemLayout::GetScrollDirection() */ - virtual bool GetColorConstraint(unsigned int itemId, ItemLayout::Vector4Function& constraint) const; + virtual Degree GetScrollDirection() const; /** - * @copydoc ItemLayout::GetVisibilityConstraint() + * @copydoc ItemLayout::ApplyConstraints() */ - virtual bool GetVisibilityConstraint(unsigned int itemId, ItemLayout::BoolFunction& constraint) const; + virtual void ApplyConstraints( Actor& actor, const int itemId, const Vector3& layoutSize, const Actor& itemViewActor ); /** - * @copydoc ItemLayout::GetScrollDirection() + * @copydoc ItemLayout::GetItemPosition() */ - virtual Degree GetScrollDirection() const; + virtual Vector3 GetItemPosition( int itemID, float currentLayoutPosition, const Vector3& layoutSize ) const; protected: @@ -280,6 +223,8 @@ private: Impl* mImpl; }; +} // namespace Internal + } // namespace Toolkit } // namespace Dali diff --git a/dali-toolkit/internal/controls/scrollable/item-view/grid-layout.cpp b/dali-toolkit/internal/controls/scrollable/item-view/grid-layout.cpp new file mode 100644 index 0000000..020bbcf --- /dev/null +++ b/dali-toolkit/internal/controls/scrollable/item-view/grid-layout.cpp @@ -0,0 +1,733 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include +#include +#include + +// INTERNAL INCLUDES +#include + +using namespace Dali; +using namespace Dali::Toolkit; + +namespace // unnamed namespace +{ + +const unsigned int DEFAULT_NUMBER_OF_COLUMNS = 4; +const float DEFAULT_TOP_MARGIN = 95.0f; +const float DEFAULT_BOTTOM_MARGIN = 20.0f; +const float DEFAULT_SIDE_MARGIN = 20.0f; +const float DEFAULT_COLUMN_SPACING = 20.0f; +const float DEFAULT_ROW_SPACING = 20.0f; +const float DEFAULT_SCROLL_SPEED_FACTOR = 0.03f; +const float DEFAULT_MAXIMUM_SWIPE_SPEED = 100.0f; +const float DEFAULT_ITEM_FLICK_ANIMATION_DURATION = 0.015f; + +struct GridPositionConstraint +{ + GridPositionConstraint( + unsigned int itemId, + const unsigned int columnIndex, + const unsigned int numberOfColumns, + const float rowSpacing, + const float columnSpacing, + const float topMargin, + const float sideMargin, + const Vector3& itemSize, + const float gap ) + : mItemSize( itemSize ), + mItemId( itemId ), + mColumnIndex( columnIndex ), + mNumberOfColumns( numberOfColumns ), + mRowSpacing( rowSpacing ), + mColumnSpacing( columnSpacing ), + mTopMargin( topMargin ), + mSideMargin( sideMargin ), + mZGap( gap ) + { + } + + inline void Orientation0( Vector3& current, float layoutPosition, const Vector3& layoutSize ) + { + current.x = mSideMargin + ( mColumnIndex * ( mItemSize.x + mColumnSpacing ) ) + mItemSize.x * 0.5f - layoutSize.x * 0.5f; + current.y = ( ( mItemSize.y + mRowSpacing ) * ( layoutPosition - mColumnIndex) ) / mNumberOfColumns - layoutSize.height * 0.5f + mItemSize.y * 0.5f + mTopMargin; + current.z = mColumnIndex * mZGap; + } + + inline void Orientation90( Vector3& current, float layoutPosition, const Vector3& layoutSize ) + { + current.x = ( ( mItemSize.y + mRowSpacing ) * ( layoutPosition - mColumnIndex ) ) / mNumberOfColumns - layoutSize.width * 0.5f + mItemSize.y * 0.5f + mTopMargin; + current.y = -( mSideMargin + ( mColumnIndex * ( mItemSize.x + mColumnSpacing ) ) + mItemSize.x * 0.5f - layoutSize.y * 0.5f ); + current.z = mColumnIndex * mZGap; + } + + inline void Orientation180( Vector3& current, float layoutPosition, const Vector3& layoutSize ) + { + current.x = -(mSideMargin + (mColumnIndex * (mItemSize.x + mColumnSpacing)) + mItemSize.x * 0.5f - layoutSize.x * 0.5f); + current.y = -( ( ( mItemSize.y + mRowSpacing ) * ( layoutPosition - mColumnIndex ) ) / mNumberOfColumns - layoutSize.height * 0.5f + mItemSize.y * 0.5f + mTopMargin ); + current.z = mColumnIndex * mZGap; + } + + inline void Orientation270( Vector3& current, float layoutPosition, const Vector3& layoutSize ) + { + current.x = -( ( ( mItemSize.y + mRowSpacing ) * ( layoutPosition - mColumnIndex ) ) / mNumberOfColumns - layoutSize.width * 0.5f + mItemSize.y * 0.5f + mTopMargin ); + current.y = mSideMargin + ( mColumnIndex * ( mItemSize.x + mColumnSpacing ) ) + mItemSize.x * 0.5f - layoutSize.y * 0.5f; + current.z = mColumnIndex * mZGap; + } + + void Orientation0( Vector3& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + Orientation0( current, layoutPosition, layoutSize ); + } + + void Orientation90( Vector3& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + Orientation90( current, layoutPosition, layoutSize ); + } + + void Orientation180( Vector3& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + Orientation180( current, layoutPosition, layoutSize ); + } + + void Orientation270( Vector3& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + Orientation270( current, layoutPosition, layoutSize ); + } + +public: + + Vector3 mItemSize; + unsigned int mItemId; + unsigned int mColumnIndex; + unsigned int mNumberOfColumns; + float mRowSpacing; + float mColumnSpacing; + float mTopMargin; + float mSideMargin; + float mZGap; +}; + +void GridRotationConstraint0( Quaternion& current, const PropertyInputContainer& /* inputs */ ) +{ + current = Quaternion( Radian( 0.0f ), Vector3::ZAXIS ); +} + +void GridRotationConstraint90( Quaternion& current, const PropertyInputContainer& /* inputs */ ) +{ + current = Quaternion( Radian( 1.5f * Math::PI ), Vector3::ZAXIS ); +} + +void GridRotationConstraint180( Quaternion& current, const PropertyInputContainer& /* inputs */ ) +{ + current = Quaternion( Radian( Math::PI ), Vector3::ZAXIS ); +} + +void GridRotationConstraint270( Quaternion& current, const PropertyInputContainer& /* inputs */ ) +{ + current = Quaternion( Radian( 0.5f * Math::PI ), Vector3::ZAXIS ); +} + +void GridColorConstraint( Vector4& current, const PropertyInputContainer& /* inputs */ ) +{ + current.r = current.g = current.b = 1.0f; +} + +struct GridVisibilityConstraint +{ + GridVisibilityConstraint( + unsigned int itemId, + const unsigned int columnIndex, + const unsigned int numberOfColumns, + const float rowSpacing, + const float columnSpacing, + const float sideMargin, + const Vector3& itemSize ) + : mItemSize( itemSize ), + mItemId( itemId ), + mColumnIndex( columnIndex ), + mNumberOfColumns( numberOfColumns ), + mRowSpacing( rowSpacing ), + mColumnSpacing( columnSpacing ), + mSideMargin( sideMargin ) + { + } + + void Portrait( bool& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + + float row = ( layoutPosition - static_cast< float >( mColumnIndex ) ) / mNumberOfColumns; + int rowsPerPage = ceil( layoutSize.height / ( mItemSize.y + mRowSpacing ) ); + + current = ( row > -2.0f ) && ( row < rowsPerPage ); + } + + void Landscape( bool& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + + float row = ( layoutPosition - static_cast< float >( mColumnIndex ) ) / mNumberOfColumns; + int rowsPerPage = ceil( layoutSize.width / ( mItemSize.y + mRowSpacing ) ); + + current = ( row > -2.0f ) && ( row < rowsPerPage ); + } + +public: + + Vector3 mItemSize; + unsigned int mItemId; + unsigned int mColumnIndex; + unsigned int mNumberOfColumns; + float mRowSpacing; + float mColumnSpacing; + float mSideMargin; +}; + +} // unnamed namespace + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +struct GridLayout::Impl +{ + Impl() + : mNumberOfColumns(DEFAULT_NUMBER_OF_COLUMNS), + mRowSpacing(DEFAULT_ROW_SPACING), + mColumnSpacing(DEFAULT_COLUMN_SPACING), + mTopMargin(DEFAULT_TOP_MARGIN), + mBottomMargin(DEFAULT_BOTTOM_MARGIN), + mSideMargin(DEFAULT_SIDE_MARGIN), + mZGap(0.f), + mScrollSpeedFactor(DEFAULT_SCROLL_SPEED_FACTOR), + mMaximumSwipeSpeed(DEFAULT_MAXIMUM_SWIPE_SPEED), + mItemFlickAnimationDuration(DEFAULT_ITEM_FLICK_ANIMATION_DURATION) + { + } + + unsigned int mNumberOfColumns; + float mRowSpacing; + float mColumnSpacing; + float mTopMargin; + float mBottomMargin; + float mSideMargin; + float mZGap; + + float mScrollSpeedFactor; + float mMaximumSwipeSpeed; + float mItemFlickAnimationDuration; +}; + +GridLayoutPtr GridLayout::New() +{ + return GridLayoutPtr(new GridLayout()); +} + +GridLayout::~GridLayout() +{ + delete mImpl; +} + +void GridLayout::SetNumberOfColumns(unsigned int columns) +{ + mImpl->mNumberOfColumns = columns; +} + +unsigned int GridLayout::GetNumberOfColumns() const +{ + return mImpl->mNumberOfColumns; +} + +void GridLayout::SetRowSpacing(float spacing) +{ + mImpl->mRowSpacing = spacing; +} + +float GridLayout::GetRowSpacing() const +{ + return mImpl->mRowSpacing; +} + +void GridLayout::SetColumnSpacing(float spacing) +{ + mImpl->mColumnSpacing = spacing; +} + +float GridLayout::GetColumnSpacing() const +{ + return mImpl->mColumnSpacing; +} + +void GridLayout::SetTopMargin(float margin) +{ + mImpl->mTopMargin = margin; +} + +float GridLayout::GetTopMargin() const +{ + return mImpl->mTopMargin; +} + +void GridLayout::SetBottomMargin(float margin) +{ + mImpl->mBottomMargin = margin; +} + +float GridLayout::GetBottomMargin() const +{ + return mImpl->mBottomMargin; +} + +void GridLayout::SetSideMargin(float margin) +{ + mImpl->mSideMargin = margin; +} + +float GridLayout::GetSideMargin() const +{ + return mImpl->mSideMargin; +} + +void GridLayout::SetZGap(float gap) +{ + mImpl->mZGap = gap; +} + +float GridLayout::GetZGap() const +{ + return mImpl->mZGap; +} + +void GridLayout::SetScrollSpeedFactor(float scrollSpeed) +{ + mImpl->mScrollSpeedFactor = scrollSpeed; +} + +void GridLayout::SetMaximumSwipeSpeed(float speed) +{ + mImpl->mMaximumSwipeSpeed = speed; +} + +void GridLayout::SetItemFlickAnimationDuration(float durationSeconds) +{ + mImpl->mItemFlickAnimationDuration = durationSeconds; +} + +float GridLayout::GetScrollSpeedFactor() const +{ + return mImpl->mScrollSpeedFactor; +} + +float GridLayout::GetMaximumSwipeSpeed() const +{ + return mImpl->mMaximumSwipeSpeed; +} + +float GridLayout::GetItemFlickAnimationDuration() const +{ + return mImpl->mItemFlickAnimationDuration; +} + +float GridLayout::GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const +{ + float layoutHeight = IsHorizontal( GetOrientation() ) ? layoutSize.width : layoutSize.height; + + Vector3 itemSize; + GetItemSize( 0, layoutSize, itemSize ); + + unsigned int itemsLastRow = numberOfItems % mImpl->mNumberOfColumns; + if (itemsLastRow == 0) + { + itemsLastRow = mImpl->mNumberOfColumns; + } + + float rowsLastPage = (layoutHeight - mImpl->mBottomMargin - mImpl->mTopMargin + mImpl->mRowSpacing) / (itemSize.y + mImpl->mRowSpacing); + float itemsLastPage = (rowsLastPage - 1.0f) * static_cast(mImpl->mNumberOfColumns) + static_cast(itemsLastRow); + + return itemsLastPage - static_cast(numberOfItems); +} + +float GridLayout::GetClosestAnchorPosition(float layoutPosition) const +{ + float rowIndex = static_cast(round(layoutPosition / mImpl->mNumberOfColumns)); + return rowIndex * static_cast(mImpl->mNumberOfColumns); +} + +float GridLayout::GetItemScrollToPosition(unsigned int itemId) const +{ + float rowIndex = static_cast(itemId / mImpl->mNumberOfColumns); + return -rowIndex * static_cast(mImpl->mNumberOfColumns); +} + +ItemRange GridLayout::GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const +{ + float layoutHeight = IsHorizontal( GetOrientation() ) ? layoutSize.width : layoutSize.height; + + Vector3 itemSize; + GetItemSize( 0, layoutSize, itemSize ); + + int itemsPerPage = mImpl->mNumberOfColumns * ceil(layoutHeight / (itemSize.y + mImpl->mRowSpacing)); + int firstVisibleItem = -(static_cast(firstItemPosition / mImpl->mNumberOfColumns)) * mImpl->mNumberOfColumns; + + int firstItemIndex = std::max(0, firstVisibleItem - static_cast(mImpl->mNumberOfColumns)); + int lastItemIndex = std::max(0, firstVisibleItem + itemsPerPage); + + return ItemRange(firstItemIndex, lastItemIndex); +} + +float GridLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) +{ + Vector3 itemPosition = GetItemPosition( itemID, currentLayoutPosition, layoutSize ); + Vector3 itemSize; + ControlOrientation::Type orientation = GetOrientation(); + + GetItemSize(itemID, layoutSize, itemSize); + Vector3 onScreenArea = ( layoutSize - ( IsVertical( orientation ) ? itemSize : Vector3( itemSize.y, itemSize.x, itemSize.z ) ) ) * 0.5f; + if (itemPosition.x < -onScreenArea.x + || itemPosition.x > onScreenArea.x + || itemPosition.y < -onScreenArea.y + || itemPosition.y > onScreenArea.y) + { + // item not within viewable area + float rowHeight = itemSize.y + mImpl->mRowSpacing; + Vector3 firstItemPosition = GetItemPosition( itemID, 0.0f, layoutSize ); + float offset = 0.0f; + switch( orientation ) + { + case ControlOrientation::Up: + { + if(itemPosition.y > onScreenArea.y) + { + offset = ((layoutSize.y - rowHeight) * 0.5f) - firstItemPosition.y; + } + else + { + offset = ((-layoutSize.y + rowHeight) * 0.5f) - firstItemPosition.y; + } + break; + } + case ControlOrientation::Down: + { + if(itemPosition.y < -onScreenArea.y) + { + offset = ((layoutSize.y - rowHeight) * 0.5f) - firstItemPosition.y; + } + else + { + offset = ((-layoutSize.y + rowHeight) * 0.5f) - firstItemPosition.y; + } + break; + } + case ControlOrientation::Left: + { + if(itemPosition.x > onScreenArea.x) + { + offset = ((layoutSize.x - rowHeight) * 0.5f) - firstItemPosition.x; + } + else + { + offset = ((-layoutSize.x + rowHeight) * 0.5f) - firstItemPosition.x; + } + break; + } + case ControlOrientation::Right: + { + if(itemPosition.x < -onScreenArea.x) + { + offset = ((layoutSize.x - rowHeight) * 0.5f) - firstItemPosition.x; + } + else + { + offset = ((-layoutSize.x + rowHeight) * 0.5f) - firstItemPosition.x; + } + break; + } + } + // work out number of rows from first item position to an item aligned to bottom of screen + float rowDiff = offset / rowHeight; + float layoutPositionOffset = rowDiff * mImpl->mNumberOfColumns; + float scrollTo = GetItemScrollToPosition(itemID) + layoutPositionOffset; + return scrollTo; + } + return currentLayoutPosition; +} + +unsigned int GridLayout::GetReserveItemCount(Vector3 layoutSize) const +{ + float layoutHeight = IsHorizontal( GetOrientation() ) ? layoutSize.width : layoutSize.height; + + Vector3 itemSize; + GetItemSize( 0, layoutSize, itemSize ); + int itemsPerPage = mImpl->mNumberOfColumns * ceil(layoutHeight / (itemSize.y + mImpl->mRowSpacing)); + return itemsPerPage; +} + +void GridLayout::GetDefaultItemSize( unsigned int itemId, const Vector3& layoutSize, Vector3& itemSize ) const +{ + float layoutWidth = IsHorizontal( GetOrientation() ) ? layoutSize.height : layoutSize.width; + itemSize.width = ( layoutWidth - mImpl->mSideMargin * 2.0f - mImpl->mColumnSpacing * static_cast( mImpl->mNumberOfColumns - 1 ) ) / static_cast( mImpl->mNumberOfColumns ); + + // 4x3 aspect ratio + itemSize.height = itemSize.depth = itemSize.width * 0.75f; +} + +void GridLayout::GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const +{ + if(animation) + { + Vector3 currentSize( actor.GetCurrentSize() ); + Vector3 shrink( currentSize ); + + shrink.width = std::min(size.width, currentSize.width); + shrink.height = std::min(size.height, currentSize.height); + + // Do a nonlinear size animation to shrink the actor first when the actor size changes, + // so that we can avoid the actors overlapping during orientation change. + animation.AnimateTo( Property( actor, Actor::Property::SIZE ), shrink, AlphaFunction::EASE_OUT, TimePeriod( 0.0f, durationSeconds * 0.5f ) ); + animation.AnimateTo( Property( actor, Actor::Property::SIZE ), size, AlphaFunction::EASE_IN, TimePeriod( 0.0f, durationSeconds ) ); + } +} + +Degree GridLayout::GetScrollDirection() const +{ + Degree scrollDirection(0.0f); + ControlOrientation::Type orientation = GetOrientation(); + + if ( orientation == ControlOrientation::Up ) + { + scrollDirection = Degree( 0.0f ); + } + else if ( orientation == ControlOrientation::Left ) + { + scrollDirection = Degree( 90.0f ); + } + else if ( orientation == ControlOrientation::Down ) + { + scrollDirection = Degree( 180.0f ); + } + else // orientation == ControlOrientation::Right + { + scrollDirection = Degree( 270.0f ); + } + + return scrollDirection; +} + +void GridLayout::ApplyConstraints( Actor& actor, const int itemId, const Vector3& layoutSize, const Actor& itemViewActor ) +{ + // This just implements the default behaviour of constraint application. + // Custom layouts can override this function to apply their custom constraints. + Dali::Toolkit::ItemView itemView = Dali::Toolkit::ItemView::DownCast( itemViewActor ); + if( itemView ) + { + Vector3 itemSize; + GetItemSize( itemId, layoutSize, itemSize ); + const unsigned int columnIndex = itemId % mImpl->mNumberOfColumns; + const ControlOrientation::Type orientation = GetOrientation(); + + // Position constraint + GridPositionConstraint positionConstraint( itemId, + columnIndex, + mImpl->mNumberOfColumns, + mImpl->mRowSpacing, + mImpl->mColumnSpacing, + mImpl->mTopMargin, + mImpl->mSideMargin, + itemSize, + mImpl->mZGap ); + Constraint constraint; + if ( orientation == ControlOrientation::Up ) + { + constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, positionConstraint, &GridPositionConstraint::Orientation0 ); + } + else if ( orientation == ControlOrientation::Left ) + { + constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, positionConstraint, &GridPositionConstraint::Orientation90 ); + } + else if ( orientation == ControlOrientation::Down ) + { + constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, positionConstraint, &GridPositionConstraint::Orientation180 ); + } + else // orientation == ControlOrientation::Right + { + constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, positionConstraint, &GridPositionConstraint::Orientation270 ); + } + constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) ); + constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); + constraint.Apply(); + + // Rotation constraint + if ( orientation == ControlOrientation::Up ) + { + constraint = Constraint::New< Quaternion >( actor, Actor::Property::ORIENTATION, &GridRotationConstraint0 ); + } + else if ( orientation == ControlOrientation::Left ) + { + constraint = Constraint::New< Quaternion >( actor, Actor::Property::ORIENTATION, &GridRotationConstraint90 ); + } + else if ( orientation == ControlOrientation::Down ) + { + constraint = Constraint::New< Quaternion >( actor, Actor::Property::ORIENTATION, &GridRotationConstraint180 ); + } + else // orientation == ControlOrientation::Right + { + constraint = Constraint::New< Quaternion >( actor, Actor::Property::ORIENTATION, &GridRotationConstraint270 ); + } + constraint.Apply(); + + // Color constraint + constraint = Constraint::New< Vector4 >( actor, Actor::Property::COLOR, &GridColorConstraint ); + constraint.SetRemoveAction( Dali::Constraint::Discard ); + constraint.Apply(); + + // Visibility constraint + GridVisibilityConstraint visibilityConstraint( itemId, + columnIndex, + mImpl->mNumberOfColumns, + mImpl->mRowSpacing, + mImpl->mColumnSpacing, + mImpl->mSideMargin, + itemSize ); + if ( IsVertical( orientation ) ) + { + constraint = Constraint::New( actor, Actor::Property::VISIBLE, visibilityConstraint, &GridVisibilityConstraint::Portrait ); + } + else // horizontal + { + constraint = Constraint::New( actor, Actor::Property::VISIBLE, visibilityConstraint, &GridVisibilityConstraint::Landscape ); + } + constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) ); + constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); + constraint.SetRemoveAction( Dali::Constraint::Discard ); + constraint.Apply(); + } +} + +Vector3 GridLayout::GetItemPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) const +{ + Vector3 itemPosition = Vector3::ZERO; + const unsigned int columnIndex = itemID % mImpl->mNumberOfColumns; + const ControlOrientation::Type orientation = GetOrientation(); + Vector3 itemSize; + GetItemSize( itemID, layoutSize, itemSize ); + + GridPositionConstraint positionConstraintStruct( itemID, + columnIndex, + mImpl->mNumberOfColumns, + mImpl->mRowSpacing, + mImpl->mColumnSpacing, + mImpl->mTopMargin, + mImpl->mSideMargin, + itemSize, + mImpl->mZGap ); + + if ( orientation == ControlOrientation::Up ) + { + positionConstraintStruct.Orientation0( itemPosition, currentLayoutPosition + itemID, layoutSize ); + } + else if ( orientation == ControlOrientation::Left ) + { + positionConstraintStruct.Orientation90( itemPosition, currentLayoutPosition + itemID, layoutSize ); + } + else if ( orientation == ControlOrientation::Down ) + { + positionConstraintStruct.Orientation180( itemPosition, currentLayoutPosition + itemID, layoutSize ); + } + else // orientation == ControlOrientation::Right + { + positionConstraintStruct.Orientation270( itemPosition, currentLayoutPosition + itemID, layoutSize ); + } + + return itemPosition; +} + +int GridLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled) +{ + switch( direction ) + { + case Toolkit::Control::Left: + { + itemID--; + if( itemID < 0 ) + { + itemID = loopEnabled ? maxItems - 1 : 0; + } + break; + } + case Toolkit::Control::Up: + { + itemID -= mImpl->mNumberOfColumns; + if( itemID < 0 ) + { + itemID = loopEnabled ? itemID + maxItems : itemID + mImpl->mNumberOfColumns; + } + break; + } + case Toolkit::Control::Right: + { + itemID++; + if( itemID >= maxItems ) + { + itemID = loopEnabled ? 0 : maxItems - 1; + } + break; + } + case Toolkit::Control::Down: + { + itemID += mImpl->mNumberOfColumns; + if( itemID >= maxItems ) + { + itemID = loopEnabled ? 0 : itemID - mImpl->mNumberOfColumns; + } + break; + } + } + return itemID; +} + +GridLayout::GridLayout() +: mImpl(NULL) +{ + mImpl = new Impl(); +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/public-api/controls/scrollable/item-view/grid-layout.h b/dali-toolkit/internal/controls/scrollable/item-view/grid-layout.h similarity index 78% rename from dali-toolkit/public-api/controls/scrollable/item-view/grid-layout.h rename to dali-toolkit/internal/controls/scrollable/item-view/grid-layout.h index aa52d9d..0031559 100644 --- a/dali-toolkit/public-api/controls/scrollable/item-view/grid-layout.h +++ b/dali-toolkit/internal/controls/scrollable/item-view/grid-layout.h @@ -28,6 +28,9 @@ namespace Dali namespace Toolkit { +namespace Internal +{ + class GridLayout; typedef IntrusivePtr GridLayoutPtr; ///< Pointer to a Dali::Toolkit::GridLayout object @@ -35,18 +38,11 @@ typedef IntrusivePtr GridLayoutPtr; ///< Pointer to a Dali::Toolkit: /** * @brief An ItemView layout which arranges items in a grid. */ -class DALI_IMPORT_API GridLayout : public ItemLayout +class GridLayout : public ItemLayout { public: /** - * @brief Function signature for a method to calculate the item size. - * - * @see SetItemSizeFunction() - */ - typedef boost::function ItemSizeFunction; - - /** * @brief Create a new grid layout. */ static GridLayoutPtr New(); @@ -155,20 +151,6 @@ public: float GetZGap() const; /** - * @brief Set the function used to calculate the item-size, for a given layout-size. - * - * @param[in] function The item-size function. - */ - void SetItemSizeFunction(ItemSizeFunction function); - - /** - * @brief Get the function used to calculate the item-size. - * - * @return The item-size function. - */ - ItemSizeFunction GetItemSizeFunction() const; - - /** * @brief Set the factor used to customise the scroll speed while dragging and swiping the layout. * * @param[in] scrollSpeed The scroll speed factor. @@ -247,9 +229,9 @@ private: virtual unsigned int GetReserveItemCount(Vector3 layoutSize) const; /** - * @copydoc ItemLayout::GetItemSize() + * @copydoc ItemLayout::GetDefaultItemSize() */ - virtual bool GetItemSize(unsigned int itemId, Vector3 layoutSize, Vector3& itemSize) const; + virtual void GetDefaultItemSize( unsigned int itemId, const Vector3& layoutSize, Vector3& itemSize ) const; /** * @copydoc ItemLayout::GetResizeAnimation() @@ -257,34 +239,19 @@ private: virtual void GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const; /** - * @copydoc ItemLayout::GetPositionConstraint() - */ - virtual bool GetPositionConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const; - - /** - * @copydoc ItemLayout::GetRotationConstraint() - */ - virtual bool GetRotationConstraint(unsigned int itemId, ItemLayout::QuaternionFunction& constraint) const; - - /** - * @copydoc ItemLayout::GetScaleConstraint() - */ - virtual bool GetScaleConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const; - - /** - * @copydoc ItemLayout::GetColorConstraint() + * @copydoc ItemLayout::GetScrollDirection() */ - virtual bool GetColorConstraint(unsigned int itemId, ItemLayout::Vector4Function& constraint) const; + virtual Degree GetScrollDirection() const; /** - * @copydoc ItemLayout::GetVisibilityConstraint() + * @copydoc ItemLayout::ApplyConstraints() */ - virtual bool GetVisibilityConstraint(unsigned int itemId, ItemLayout::BoolFunction& constraint) const; + virtual void ApplyConstraints( Actor& actor, const int itemId, const Vector3& layoutSize, const Actor& itemViewActor ); /** - * @copydoc ItemLayout::GetScrollDirection() + * @copydoc ItemLayout::GetItemPosition() */ - virtual Degree GetScrollDirection() const; + virtual Vector3 GetItemPosition( int itemID, float currentLayoutPosition, const Vector3& layoutSize ) const; protected: @@ -299,6 +266,8 @@ private: Impl* mImpl; }; +} // namespace Internal + } // namespace Toolkit } // namespace Dali diff --git a/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp b/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp index 68141c3..4e23aa9 100644 --- a/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp +++ b/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp @@ -385,18 +385,15 @@ void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSiz actor.RemoveConstraints(); Vector3 size; - if(mActiveLayout->GetItemSize(itemId, targetSize, size)) - { - // resize immediately - actor.SetSize( size.GetVectorXY() ); - } + mActiveLayout->GetItemSize( itemId, targetSize, size ); + actor.SetSize( size.GetVectorXY() ); - mActiveLayout->ApplyConstraints(actor, itemId, durationSeconds, Self() ); + mActiveLayout->ApplyConstraints(actor, itemId, targetSize, Self() ); } // Refresh the new layout ItemRange range = GetItemRange(*mActiveLayout, targetSize, GetCurrentLayoutPosition(0), false/* don't reserve extra*/); - AddActorsWithinRange( range, durationSeconds ); + AddActorsWithinRange( range, targetSize ); // Scroll to an appropriate layout position @@ -477,7 +474,7 @@ void ItemView::DoRefresh(float currentLayoutPosition, bool cacheExtra) { ItemRange range = GetItemRange(*mActiveLayout, mActiveLayoutTargetSize, currentLayoutPosition, cacheExtra/*reserve extra*/); RemoveActorsOutsideRange( range ); - AddActorsWithinRange( range, 0.0f/*immediate*/ ); + AddActorsWithinRange( range, Self().GetCurrentSize() ); mScrollUpdatedSignal.Emit( Vector2(0.0f, currentLayoutPosition) ); } @@ -591,6 +588,7 @@ unsigned int ItemView::GetItemId( Actor actor ) const void ItemView::InsertItem( Item newItem, float durationSeconds ) { mAddingItems = true; + Vector3 layoutSize = Self().GetCurrentSize(); Actor displacedActor; ItemPoolIter afterDisplacedIter = mItemPool.end(); @@ -598,7 +596,7 @@ void ItemView::InsertItem( Item newItem, float durationSeconds ) ItemPoolIter foundIter = mItemPool.find( newItem.first ); if( mItemPool.end() != foundIter ) { - SetupActor( newItem, durationSeconds ); + SetupActor( newItem, layoutSize ); Self().Add( newItem.second ); displacedActor = foundIter->second; @@ -630,7 +628,7 @@ void ItemView::InsertItem( Item newItem, float durationSeconds ) displacedActor = temp; iter->second.RemoveConstraints(); - mActiveLayout->ApplyConstraints( iter->second, iter->first, durationSeconds, Self() ); + mActiveLayout->ApplyConstraints( iter->second, iter->first, layoutSize, Self() ); } // Create last item @@ -642,11 +640,11 @@ void ItemView::InsertItem( Item newItem, float durationSeconds ) mItemPool.insert( lastItem ); lastItem.second.RemoveConstraints(); - mActiveLayout->ApplyConstraints( lastItem.second, lastItem.first, durationSeconds, Self() ); + mActiveLayout->ApplyConstraints( lastItem.second, lastItem.first, layoutSize, Self() ); } } - CalculateDomainSize(Self().GetCurrentSize()); + CalculateDomainSize( layoutSize ); mAddingItems = false; } @@ -654,6 +652,7 @@ void ItemView::InsertItem( Item newItem, float durationSeconds ) void ItemView::InsertItems( const ItemContainer& newItems, float durationSeconds ) { mAddingItems = true; + Vector3 layoutSize = Self().GetCurrentSize(); // Insert from lowest id to highest std::set sortedItems; @@ -697,16 +696,16 @@ void ItemView::InsertItems( const ItemContainer& newItems, float durationSeconds // If newly inserted if( FindById( newItems, iter->first ) ) { - SetupActor( *iter, durationSeconds ); + SetupActor( *iter, layoutSize ); } else { iter->second.RemoveConstraints(); - mActiveLayout->ApplyConstraints( iter->second, iter->first, durationSeconds, Self() ); + mActiveLayout->ApplyConstraints( iter->second, iter->first, layoutSize, Self() ); } } - CalculateDomainSize(Self().GetCurrentSize()); + CalculateDomainSize( layoutSize ); mAddingItems = false; } @@ -716,7 +715,7 @@ void ItemView::RemoveItem( unsigned int itemId, float durationSeconds ) bool actorsReordered = RemoveActor( itemId ); if( actorsReordered ) { - ReapplyAllConstraints( durationSeconds ); + ReapplyAllConstraints(); OnItemsRemoved(); } @@ -743,7 +742,7 @@ void ItemView::RemoveItems( const ItemIdContainer& itemIds, float durationSecond if( actorsReordered ) { - ReapplyAllConstraints( durationSeconds ); + ReapplyAllConstraints(); OnItemsRemoved(); } @@ -802,8 +801,9 @@ bool ItemView::RemoveActor(unsigned int itemId) void ItemView::ReplaceItem( Item replacementItem, float durationSeconds ) { mAddingItems = true; + Vector3 layoutSize = Self().GetCurrentSize(); - SetupActor( replacementItem, durationSeconds ); + SetupActor( replacementItem, layoutSize ); Self().Add( replacementItem.second ); const ItemPoolIter iter = mItemPool.find( replacementItem.first ); @@ -817,7 +817,7 @@ void ItemView::ReplaceItem( Item replacementItem, float durationSeconds ) mItemPool.insert( replacementItem ); } - CalculateDomainSize(Self().GetCurrentSize()); + CalculateDomainSize( layoutSize ); mAddingItems = false; } @@ -850,7 +850,7 @@ void ItemView::RemoveActorsOutsideRange( ItemRange range ) } } -void ItemView::AddActorsWithinRange( ItemRange range, float durationSeconds ) +void ItemView::AddActorsWithinRange( ItemRange range, const Vector3& layoutSize ) { range.end = std::min(mItemFactory.GetNumberOfItems(), range.end); @@ -859,14 +859,14 @@ void ItemView::AddActorsWithinRange( ItemRange range, float durationSeconds ) { for (unsigned int itemId = range.begin; itemId < range.end; ++itemId) { - AddNewActor( itemId, durationSeconds ); + AddNewActor( itemId, layoutSize ); } } else { for (unsigned int itemId = range.end; itemId > range.begin; --itemId) { - AddNewActor( itemId-1, durationSeconds ); + AddNewActor( itemId-1, layoutSize ); } } @@ -875,7 +875,7 @@ void ItemView::AddActorsWithinRange( ItemRange range, float durationSeconds ) CalculateDomainSize(Self().GetCurrentSize()); } -void ItemView::AddNewActor( unsigned int itemId, float durationSeconds ) +void ItemView::AddNewActor( unsigned int itemId, const Vector3& layoutSize ) { mAddingItems = true; @@ -889,7 +889,7 @@ void ItemView::AddNewActor( unsigned int itemId, float durationSeconds ) mItemPool.insert( newItem ); - SetupActor( newItem, durationSeconds ); + SetupActor( newItem, layoutSize ); Self().Add( actor ); } } @@ -897,7 +897,7 @@ void ItemView::AddNewActor( unsigned int itemId, float durationSeconds ) mAddingItems = false; } -void ItemView::SetupActor( Item item, float durationSeconds ) +void ItemView::SetupActor( Item item, const Vector3& layoutSize ) { item.second.SetParentOrigin( mItemsParentOrigin ); item.second.SetAnchorPoint( mItemsAnchorPoint ); @@ -905,12 +905,10 @@ void ItemView::SetupActor( Item item, float durationSeconds ) if( mActiveLayout ) { Vector3 size; - if( mActiveLayout->GetItemSize( item.first, mActiveLayoutTargetSize, size ) ) - { - item.second.SetSize( size.GetVectorXY() ); - } + mActiveLayout->GetItemSize( item.first, mActiveLayoutTargetSize, size ); + item.second.SetSize( size.GetVectorXY() ); - mActiveLayout->ApplyConstraints( item.second, item.first, durationSeconds, Self() ); + mActiveLayout->ApplyConstraints( item.second, item.first, layoutSize, Self() ); } } @@ -1039,15 +1037,17 @@ bool ItemView::OnMouseWheelEventFinished() return false; } -void ItemView::ReapplyAllConstraints( float durationSeconds ) +void ItemView::ReapplyAllConstraints() { + Vector3 layoutSize = Self().GetCurrentSize(); + for (ConstItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) { unsigned int id = iter->first; Actor actor = iter->second; actor.RemoveConstraints(); - mActiveLayout->ApplyConstraints(actor, id, durationSeconds, Self()); + mActiveLayout->ApplyConstraints(actor, id, layoutSize, Self()); } } diff --git a/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h b/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h index 2835d00..851b640 100644 --- a/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h +++ b/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h @@ -302,23 +302,23 @@ private: /** * Add a range of Actors, if they are not already in the ItemPool. * @param[in] range The range of Item IDs to associate with the new actors. - * @param[in] durationSeconds The time taken to fully constrain the newly added actor. + * @param[in] layoutSize The layout-size. */ - void AddActorsWithinRange( ItemRange range, float durationSeconds ); + void AddActorsWithinRange( ItemRange range, const Vector3& layoutSize ); /** * Add a new Actor, if not already in the ItemPool. * @param[in] item The ID for the new item. - * @param[in] durationSeconds The time taken to fully constrain the new actor. + * @param[in] layoutSize The layout-size. */ - void AddNewActor( ItemId item, float durationSeconds ); + void AddNewActor( ItemId item, const Vector3& layoutSize ); /** * Apply the constraints etc. that are required for ItemView children. * @param[in] item The item to setup. - * @param[in] durationSeconds The time taken to fully constrain the actor. + * @param[in] layoutSize The layout-size. */ - void SetupActor( Item item, float durationSeconds ); + void SetupActor( Item item, const Vector3& layoutSize ); /** * Remove the Actor from the ItemPool and notify the ItemFactory the actor has been released by ItemView. @@ -396,7 +396,7 @@ private: * Helper to re-apply all the constraints after items have been inserted, removed etc. * @param[in] durationSeconds The time taken to fully constrain the actors. */ - void ReapplyAllConstraints( float durationSeconds ); + void ReapplyAllConstraints(); /** * Helper to relayout after item(s) are removed. diff --git a/dali-toolkit/internal/controls/scrollable/item-view/spiral-layout.cpp b/dali-toolkit/internal/controls/scrollable/item-view/spiral-layout.cpp new file mode 100644 index 0000000..731fa90 --- /dev/null +++ b/dali-toolkit/internal/controls/scrollable/item-view/spiral-layout.cpp @@ -0,0 +1,551 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include +#include +#include + +// INTERNAL INCLUDES +#include + +using namespace Dali; +using namespace Dali::Toolkit; + +namespace // unnamed namespace +{ + +const float DEFAULT_ITEMS_PER_SPIRAL_TURN = 9.5f; +const float DEFAULT_ITEM_SPACING_RADIANS = Math::PI*2.0f/DEFAULT_ITEMS_PER_SPIRAL_TURN; + +const float DEFAULT_REVOLUTION_DISTANCE = 190.0f; +const float DEFAULT_ITEM_DESCENT = DEFAULT_REVOLUTION_DISTANCE / DEFAULT_ITEMS_PER_SPIRAL_TURN; + +const float DEFAULT_TOP_ITEM_ALIGNMENT = -0.125f; + +const float DEFAULT_SCROLL_SPEED_FACTOR = 0.01f; +const float DEFAULT_MAXIMUM_SWIPE_SPEED = 30.0f; +const float DEFAULT_ITEM_FLICK_ANIMATION_DURATION = 0.1f; + +float GetDefaultSpiralRadiusFunction(const Vector3& layoutSize) +{ + return layoutSize.width*0.4f; +} + +struct SpiralPositionConstraint +{ + SpiralPositionConstraint( unsigned int itemId, float spiralRadius, float itemSpacingRadians, float itemDescent, float topItemAlignment ) + : mItemId( itemId ), + mSpiralRadius( spiralRadius ), + mItemSpacingRadians( itemSpacingRadians ), + mItemDescent( itemDescent ), + mTopItemAlignment( topItemAlignment ) + { + } + + inline void OrientationUp( Vector3& current, float layoutPosition, const Vector3& layoutSize ) + { + float angle = -Math::PI * 0.5f + mItemSpacingRadians * layoutPosition; + + current.x = -mSpiralRadius * cosf( angle ); + current.y = ( mItemDescent * layoutPosition ) + layoutSize.height * mTopItemAlignment; + current.z = -mSpiralRadius * sinf( angle ); + } + + inline void OrientationLeft( Vector3& current, float layoutPosition, const Vector3& layoutSize ) + { + float angle = Math::PI * 0.5f + mItemSpacingRadians * layoutPosition; + + current.x = ( mItemDescent * layoutPosition ) + layoutSize.width * mTopItemAlignment; + current.y = -mSpiralRadius * cosf( angle ); + current.z = mSpiralRadius * sinf( angle ); + } + + inline void OrientationDown( Vector3& current, float layoutPosition, const Vector3& layoutSize ) + { + float angle = Math::PI * 0.5f + mItemSpacingRadians * layoutPosition; + + current.x = -mSpiralRadius * cosf( angle ); + current.y = ( -mItemDescent * layoutPosition ) - layoutSize.height * mTopItemAlignment; + current.z = mSpiralRadius * sinf(angle); + } + + inline void OrientationRight( Vector3& current, float layoutPosition, const Vector3& layoutSize ) + { + float angle = -Math::PI*0.5f + mItemSpacingRadians * layoutPosition; + + current.x = (-mItemDescent * layoutPosition) - layoutSize.width * mTopItemAlignment; + current.y = -mSpiralRadius * cosf( angle ); + current.z = -mSpiralRadius * sinf( angle ); + } + + void OrientationUp( Vector3& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + OrientationUp( current, layoutPosition, layoutSize ); + } + + void OrientationLeft( Vector3& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + OrientationLeft( current, layoutPosition, layoutSize ); + } + + void OrientationDown( Vector3& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + OrientationDown( current, layoutPosition, layoutSize ); + } + + void OrientationRight( Vector3& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + OrientationRight( current, layoutPosition, layoutSize ); + } + + unsigned int mItemId; + float mSpiralRadius; + float mItemSpacingRadians; + float mItemDescent; + float mTopItemAlignment; +}; + +struct SpiralRotationConstraint +{ + SpiralRotationConstraint( unsigned int itemId, float itemSpacingRadians ) + : mItemId( itemId ), + mItemSpacingRadians( itemSpacingRadians ) + { + } + + void OrientationUp( Quaternion& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + float angle = -mItemSpacingRadians * layoutPosition; + + current = Quaternion( Radian( angle ), Vector3::YAXIS); + } + + void OrientationLeft( Quaternion& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + float angle = -mItemSpacingRadians * layoutPosition; + + current = Quaternion( Radian( -Math::PI * 0.5f ), Vector3::ZAXIS ) * Quaternion( Radian( angle ), Vector3::YAXIS ); + } + + void OrientationDown( Quaternion& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + float angle = -mItemSpacingRadians * layoutPosition; + + current = Quaternion( Radian( -Math::PI ), Vector3::ZAXIS) * Quaternion( Radian( angle ), Vector3::YAXIS ); + } + + void OrientationRight( Quaternion& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + float angle = -mItemSpacingRadians * layoutPosition; + + current = Quaternion( Radian( -Math::PI * 1.5f ), Vector3::ZAXIS) * Quaternion( Radian( angle ), Vector3::YAXIS ); + } + + unsigned int mItemId; + float mItemSpacingRadians; +}; + +struct SpiralColorConstraint +{ + SpiralColorConstraint( unsigned int itemId, float itemSpacingRadians ) + : mItemId( itemId ), + mItemSpacingRadians( itemSpacingRadians ) + { + } + + void operator()( Vector4& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + Radian angle( mItemSpacingRadians * fabsf( layoutPosition ) / Dali::ANGLE_360 ); + + float progress = angle - floorf( angle ); // take fractional bit only to get between 0.0 - 1.0 + progress = (progress > 0.5f) ? 2.0f*(1.0f - progress) : progress*2.0f; + + float darkness(1.0f); + { + const float startMarker = 0.10f; // The progress at which darkening starts + const float endMarker = 0.35f; // The progress at which darkening ends + const float minDarkness = 0.15f; // The darkness at end marker + + if (progress > endMarker) + { + darkness = minDarkness; + } + else if (progress > startMarker) + { + darkness = 1.0f - ( (1.0f - minDarkness) * ((progress-startMarker) / (endMarker-startMarker)) ); + } + } + + current.r = current.g = current.b = darkness; + } + + unsigned int mItemId; + float mItemSpacingRadians; +}; + +struct SpiralVisibilityConstraint +{ + SpiralVisibilityConstraint( unsigned int itemId, float itemSpacingRadians, float itemDescent, float topItemAlignment ) + : mItemId( itemId ), + mItemSpacingRadians( itemSpacingRadians ), + mItemDescent( itemDescent ), + mTopItemAlignment( topItemAlignment ) + { + } + + void Portrait( bool& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + float itemsCachedBeforeTopItem = layoutSize.height*(mTopItemAlignment+0.5f) / mItemDescent; + current = ( layoutPosition >= -itemsCachedBeforeTopItem - 1.0f && layoutPosition <= ( layoutSize.height / mItemDescent ) + 1.0f ); + } + + void Landscape( bool& current, const PropertyInputContainer& inputs ) + { + float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId ); + const Vector3& layoutSize = inputs[1]->GetVector3(); + float itemsCachedBeforeTopItem = layoutSize.width*(mTopItemAlignment+0.5f) / mItemDescent; + current = ( layoutPosition >= -itemsCachedBeforeTopItem - 1.0f && layoutPosition <= ( layoutSize.width / mItemDescent ) + 1.0f ); + } + + unsigned int mItemId; + float mItemSpacingRadians; + float mItemDescent; + float mTopItemAlignment; +}; + +} // unnamed namespace + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +struct SpiralLayout::Impl +{ + Impl() + : mItemSpacingRadians(DEFAULT_ITEM_SPACING_RADIANS), + mRevolutionDistance(DEFAULT_REVOLUTION_DISTANCE), + mItemDescent(DEFAULT_ITEM_DESCENT), + mTopItemAlignment(DEFAULT_TOP_ITEM_ALIGNMENT), + mScrollSpeedFactor(DEFAULT_SCROLL_SPEED_FACTOR), + mMaximumSwipeSpeed(DEFAULT_MAXIMUM_SWIPE_SPEED), + mItemFlickAnimationDuration(DEFAULT_ITEM_FLICK_ANIMATION_DURATION) + { + } + + float mItemSpacingRadians; + float mRevolutionDistance; + float mItemDescent; + float mTopItemAlignment; + float mScrollSpeedFactor; + float mMaximumSwipeSpeed; + float mItemFlickAnimationDuration; +}; + +SpiralLayoutPtr SpiralLayout::New() +{ + return SpiralLayoutPtr(new SpiralLayout()); +} + +SpiralLayout::~SpiralLayout() +{ + delete mImpl; +} + +void SpiralLayout::SetItemSpacing(Radian itemSpacing) +{ + mImpl->mItemSpacingRadians = itemSpacing; + + float itemsPerSpiral = std::max(1.0f, (2.0f*(float)Math::PI) / mImpl->mItemSpacingRadians); + mImpl->mItemDescent = mImpl->mRevolutionDistance / itemsPerSpiral; +} + +Radian SpiralLayout::GetItemSpacing() const +{ + return Radian( mImpl->mItemSpacingRadians ); +} + +void SpiralLayout::SetRevolutionDistance(float distance) +{ + mImpl->mRevolutionDistance = distance; + + float itemsPerSpiral = std::max(1.0f, (2.0f*(float)Math::PI) / mImpl->mItemSpacingRadians); + mImpl->mItemDescent = mImpl->mRevolutionDistance / itemsPerSpiral; +} + +float SpiralLayout::GetRevolutionDistance() const +{ + return mImpl->mRevolutionDistance; +} + +void SpiralLayout::SetTopItemAlignment(float alignment) +{ + mImpl->mTopItemAlignment = alignment; +} + +float SpiralLayout::GetTopItemAlignment() const +{ + return mImpl->mTopItemAlignment; +} + +void SpiralLayout::SetScrollSpeedFactor(float scrollSpeed) +{ + mImpl->mScrollSpeedFactor = scrollSpeed; +} + +void SpiralLayout::SetMaximumSwipeSpeed(float speed) +{ + mImpl->mMaximumSwipeSpeed = speed; +} + +void SpiralLayout::SetItemFlickAnimationDuration(float durationSeconds) +{ + mImpl->mItemFlickAnimationDuration = durationSeconds; +} + +float SpiralLayout::GetScrollSpeedFactor() const +{ + return mImpl->mScrollSpeedFactor; +} + +float SpiralLayout::GetMaximumSwipeSpeed() const +{ + return mImpl->mMaximumSwipeSpeed; +} + +float SpiralLayout::GetItemFlickAnimationDuration() const +{ + return mImpl->mItemFlickAnimationDuration; +} + +float SpiralLayout::GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const +{ + return 1.0f - static_cast(numberOfItems); +} + +float SpiralLayout::GetClosestAnchorPosition(float layoutPosition) const +{ + return round(layoutPosition); +} + +float SpiralLayout::GetItemScrollToPosition(unsigned int itemId) const +{ + return -(static_cast(itemId)); +} + +ItemRange SpiralLayout::GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const +{ + float layoutHeight = IsHorizontal( GetOrientation() ) ? layoutSize.width : layoutSize.height; + float itemsPerSpiral = layoutHeight / mImpl->mItemDescent; + float itemsCachedBeforeTopItem = layoutHeight * (mImpl->mTopItemAlignment + 0.5f) / mImpl->mItemDescent; + float itemsViewable = std::min(itemsPerSpiral, itemsPerSpiral - itemsCachedBeforeTopItem - firstItemPosition + 1.0f); + + unsigned int firstItem = static_cast(std::max(0.0f, -firstItemPosition - itemsCachedBeforeTopItem - 1.0f)); + unsigned int lastItem = static_cast(std::max(0.0f, firstItem + itemsViewable)); + + return ItemRange(firstItem, lastItem+1); +} + +unsigned int SpiralLayout::GetReserveItemCount(Vector3 layoutSize) const +{ + float layoutHeight = IsHorizontal( GetOrientation() ) ? layoutSize.width : layoutSize.height; + return static_cast(layoutHeight / mImpl->mItemDescent); +} + +void SpiralLayout::GetDefaultItemSize( unsigned int itemId, const Vector3& layoutSize, Vector3& itemSize ) const +{ + itemSize.width = layoutSize.width * 0.25f; + + // 4x3 aspect ratio + itemSize.height = itemSize.depth = ( itemSize.width / 4.0f ) * 3.0f; +} + +void SpiralLayout::GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const +{ + if(animation) + { + animation.AnimateTo( Property( actor, Actor::Property::SIZE ), size ); + } +} + +Degree SpiralLayout::GetScrollDirection() const +{ + Degree scrollDirection(0); + const ControlOrientation::Type orientation = GetOrientation(); + + if ( orientation == ControlOrientation::Up ) + { + scrollDirection = Degree( -45.0f ); // Allow swiping horizontally & vertically + } + else if ( orientation == ControlOrientation::Left ) + { + scrollDirection = Degree( 45.0f ); + } + else if ( orientation == ControlOrientation::Down ) + { + scrollDirection = Degree( 180.0f - 45.0f ); + } + else // orientation == ControlOrientation::Right + { + scrollDirection = Degree( 270.0f - 45.0f ); + } + + return scrollDirection; +} + +void SpiralLayout::ApplyConstraints( Actor& actor, const int itemId, const Vector3& layoutSize, const Actor& itemViewActor ) +{ + // This just implements the default behaviour of constraint application. + // Custom layouts can override this function to apply their custom constraints. + Dali::Toolkit::ItemView itemView = Dali::Toolkit::ItemView::DownCast( itemViewActor ); + if( itemView ) + { + const ControlOrientation::Type orientation = GetOrientation(); + + // Position constraint + SpiralPositionConstraint positionConstraint( itemId, GetDefaultSpiralRadiusFunction( layoutSize ), mImpl->mItemSpacingRadians, mImpl->mItemDescent, mImpl->mTopItemAlignment ); + Constraint constraint; + if ( orientation == ControlOrientation::Up ) + { + constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, positionConstraint, &SpiralPositionConstraint::OrientationUp ); + } + else if ( orientation == ControlOrientation::Left ) + { + constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, positionConstraint, &SpiralPositionConstraint::OrientationLeft ); + } + else if ( orientation == ControlOrientation::Down ) + { + constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, positionConstraint, &SpiralPositionConstraint::OrientationDown ); + } + else // orientation == ControlOrientation::Right + { + constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, positionConstraint, &SpiralPositionConstraint::OrientationRight ); + } + constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) ); + constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); + constraint.Apply(); + + // Rotation constraint + SpiralRotationConstraint rotationConstraint( itemId, mImpl->mItemSpacingRadians ); + if ( orientation == ControlOrientation::Up ) + { + constraint = Constraint::New< Quaternion >( actor, Actor::Property::ORIENTATION, rotationConstraint, &SpiralRotationConstraint::OrientationUp ); + } + else if ( orientation == ControlOrientation::Left ) + { + constraint = Constraint::New< Quaternion >( actor, Actor::Property::ORIENTATION, rotationConstraint, &SpiralRotationConstraint::OrientationLeft ); + } + else if ( orientation == ControlOrientation::Down ) + { + constraint = Constraint::New< Quaternion >( actor, Actor::Property::ORIENTATION, rotationConstraint, &SpiralRotationConstraint::OrientationDown ); + } + else // orientation == ControlOrientation::Right + { + constraint = Constraint::New< Quaternion >( actor, Actor::Property::ORIENTATION, rotationConstraint, &SpiralRotationConstraint::OrientationRight ); + } + constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) ); + constraint.Apply(); + + // Color constraint + constraint = Constraint::New< Vector4 >( actor, Actor::Property::COLOR, SpiralColorConstraint( itemId, mImpl->mItemSpacingRadians ) ); + constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) ); + constraint.SetRemoveAction(Dali::Constraint::Discard); + constraint.Apply(); + + // Visibility constraint + SpiralVisibilityConstraint visibilityConstraint( itemId, mImpl->mItemSpacingRadians, mImpl->mItemDescent, mImpl->mTopItemAlignment ); + if (IsVertical( orientation ) ) + { + constraint = Constraint::New< bool >( actor, Actor::Property::VISIBLE, visibilityConstraint, &SpiralVisibilityConstraint::Portrait ); + } + else // horizontal + { + constraint = Constraint::New< bool >( actor, Actor::Property::VISIBLE, visibilityConstraint, &SpiralVisibilityConstraint::Landscape ); + } + constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) ); + constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); + constraint.SetRemoveAction(Dali::Constraint::Discard); + constraint.Apply(); + } +} + +Vector3 SpiralLayout::GetItemPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) const +{ + Vector3 itemPosition = Vector3::ZERO; + const ControlOrientation::Type orientation = GetOrientation(); + + SpiralPositionConstraint positionConstraint( itemID, GetDefaultSpiralRadiusFunction( layoutSize ), mImpl->mItemSpacingRadians, mImpl->mItemDescent, mImpl->mTopItemAlignment ); + + if ( orientation == ControlOrientation::Up ) + { + positionConstraint.OrientationUp( itemPosition, currentLayoutPosition + itemID, layoutSize ); + } + else if ( orientation == ControlOrientation::Left ) + { + positionConstraint.OrientationLeft( itemPosition, currentLayoutPosition + itemID, layoutSize ); + } + else if ( orientation == ControlOrientation::Down ) + { + positionConstraint.OrientationDown( itemPosition, currentLayoutPosition + itemID, layoutSize ); + } + else // orientation == ControlOrientation::Right + { + positionConstraint.OrientationRight( itemPosition, currentLayoutPosition + itemID, layoutSize ); + } + + return itemPosition; +} + +SpiralLayout::SpiralLayout() +: mImpl(NULL) +{ + mImpl = new Impl(); +} + +float SpiralLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) +{ + return GetItemScrollToPosition(itemID); +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/public-api/controls/scrollable/item-view/spiral-layout.h b/dali-toolkit/internal/controls/scrollable/item-view/spiral-layout.h similarity index 72% rename from dali-toolkit/public-api/controls/scrollable/item-view/spiral-layout.h rename to dali-toolkit/internal/controls/scrollable/item-view/spiral-layout.h index af01ee1..326dcc7 100644 --- a/dali-toolkit/public-api/controls/scrollable/item-view/spiral-layout.h +++ b/dali-toolkit/internal/controls/scrollable/item-view/spiral-layout.h @@ -28,6 +28,9 @@ namespace Dali namespace Toolkit { +namespace Internal +{ + class SpiralLayout; typedef IntrusivePtr SpiralLayoutPtr; @@ -35,13 +38,10 @@ typedef IntrusivePtr SpiralLayoutPtr; /** * An ItemView layout which arranges items in a spiral. */ -class DALI_IMPORT_API SpiralLayout : public ItemLayout +class SpiralLayout : public ItemLayout { public: - typedef boost::function ItemSizeFunction; - typedef boost::function SpiralRadiusFunction; - /** * Create a new spiral layout */ @@ -53,18 +53,6 @@ public: virtual ~SpiralLayout(); /** - * Set the function used to calculate the item-size, for a given layout-size. - * @param[in] function The item-size function. - */ - void SetItemSizeFunction(ItemSizeFunction function); - - /** - * Get the function used to calculate the item-size - * @return The item-size function. - */ - ItemSizeFunction GetItemSizeFunction() const; - - /** * Set spacing angle between items. * @param[in] itemSpacing The angle in radians. */ @@ -89,18 +77,6 @@ public: float GetRevolutionDistance() const; /** - * Set the function used to calculate the spiral radius, for a given layout-size. - * @param[in] function The spiral-radius function. - */ - void SetSpiralRadiusFunction(SpiralRadiusFunction function); - - /** - * Get the function used to calculate the spiral radius. - * @return The spiral-radius function. - */ - SpiralRadiusFunction GetSpiralRadiusFunction() const; - - /** * Set the alignment of the top-item, when at the beginning of the spiral (with a first-item layout-position of zero). * A value of 0 indicates that the top-item is centered in the middle of the layout. A value of -0.5 or 0.5 indicates * that the top-item is centred at the top or bottom of the layout respectively. @@ -183,9 +159,9 @@ private: virtual unsigned int GetReserveItemCount(Vector3 layoutSize) const; /** - * @copydoc ItemLayout::GetItemSize() + * @copydoc ItemLayout::GetDefaultItemSize() */ - virtual bool GetItemSize(unsigned int itemId, Vector3 layoutSize, Vector3& itemSize) const; + virtual void GetDefaultItemSize( unsigned int itemId, const Vector3& layoutSize, Vector3& itemSize ) const; /** * @copydoc ItemLayout::GetResizeAnimation() @@ -193,34 +169,19 @@ private: virtual void GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const; /** - * @copydoc ItemLayout::GetPositionConstraint() - */ - virtual bool GetPositionConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const; - - /** - * @copydoc ItemLayout::GetRotationConstraint() - */ - virtual bool GetRotationConstraint(unsigned int itemId, ItemLayout::QuaternionFunction& constraint) const; - - /** - * @copydoc ItemLayout::GetScaleConstraint() - */ - virtual bool GetScaleConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const; - - /** - * @copydoc ItemLayout::GetColorConstraint() + * @copydoc ItemLayout::GetScrollDirection() */ - virtual bool GetColorConstraint(unsigned int itemId, ItemLayout::Vector4Function& constraint) const; + virtual Degree GetScrollDirection() const; /** - * @copydoc ItemLayout::GetVisibilityConstraint() + * @copydoc ItemLayout::ApplyConstraints() */ - virtual bool GetVisibilityConstraint(unsigned int itemId, ItemLayout::BoolFunction& constraint) const; + virtual void ApplyConstraints( Actor& actor, const int itemId, const Vector3& layoutSize, const Actor& itemViewActor ); /** - * @copydoc ItemLayout::GetScrollDirection() + * @copydoc ItemLayout::GetItemPosition() */ - virtual Degree GetScrollDirection() const; + virtual Vector3 GetItemPosition( int itemID, float currentLayoutPosition, const Vector3& layoutSize ) const; protected: @@ -235,6 +196,8 @@ private: Impl* mImpl; }; +} // namespace Internal + } // namespace Toolkit } // namespace Dali diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 2bfb816..1ea219d 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -30,7 +30,10 @@ toolkit_src_files = \ $(toolkit_src_dir)/controls/page-turn-view/page-turn-view-impl.cpp \ $(toolkit_src_dir)/controls/scroll-bar/scroll-bar-impl.cpp \ $(toolkit_src_dir)/controls/scrollable/bouncing-effect-actor.cpp \ + $(toolkit_src_dir)/controls/scrollable/item-view/depth-layout.cpp \ + $(toolkit_src_dir)/controls/scrollable/item-view/grid-layout.cpp \ $(toolkit_src_dir)/controls/scrollable/item-view/item-view-impl.cpp \ + $(toolkit_src_dir)/controls/scrollable/item-view/spiral-layout.cpp \ $(toolkit_src_dir)/controls/scrollable/scrollable-impl.cpp \ $(toolkit_src_dir)/controls/scrollable/scroll-view/scroll-base-impl.cpp \ $(toolkit_src_dir)/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.cpp \ diff --git a/dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.cpp b/dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.cpp new file mode 100644 index 0000000..954e958 --- /dev/null +++ b/dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// HEADER +#include + +// INTERNAL INCLUDES +#include +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace DefaultItemLayout +{ + +ItemLayoutPtr New( Type type ) +{ + ItemLayoutPtr itemLayout; + + switch ( type ) + { + case DEPTH: + { + itemLayout = Internal::DepthLayout::New(); + break; + } + + case GRID: + { + itemLayout = Internal::GridLayout::New(); + break; + } + + case LIST: + { + Internal::GridLayoutPtr layout = Internal::GridLayout::New(); + layout->SetNumberOfColumns( 1 ); + itemLayout = layout; + break; + } + + case SPIRAL: + { + itemLayout = Internal::SpiralLayout::New(); + break; + } + } + + return itemLayout; +} + +} // namespace DefaultItemLayout + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h b/dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h new file mode 100644 index 0000000..6f4eb00 --- /dev/null +++ b/dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h @@ -0,0 +1,56 @@ +#ifndef __DALI_TOOLKIT_DEFAULT_ITEM_LAYOUT_H__ +#define __DALI_TOOLKIT_DEFAULT_ITEM_LAYOUT_H__ + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace DefaultItemLayout +{ + +enum Type +{ + DEPTH, ///< Items arranged in a grid, scrolling along the Z-Axis. + GRID, ///< Items arranged in a grid, scrolling along the Y-Axis. + LIST, ///< One item per line, scrolling along the Y-Axis. + SPIRAL ///< Items arranged in a spiral, centered around the Y-Axis. +}; + +/** + * @brief Creates a built-in default item-layout + * + * @param[in] type The type of layout required. + * + * @return An ItemLayoutPtr to the newly created layout. + */ +DALI_IMPORT_API ItemLayoutPtr New( Type type ); + +} // namespace DefaultItemLayout + +} // namespace Toolkit + +} // namespace Dali + +#endif // __DALI_TOOLKIT_DEFAULT_ITEM_LAYOUT_H__ diff --git a/dali-toolkit/public-api/controls/scrollable/item-view/depth-layout.cpp b/dali-toolkit/public-api/controls/scrollable/item-view/depth-layout.cpp deleted file mode 100644 index abd03b0..0000000 --- a/dali-toolkit/public-api/controls/scrollable/item-view/depth-layout.cpp +++ /dev/null @@ -1,764 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// CLASS HEADER -#include - -// EXTERNAL INCLUDES -#include -#include - -using namespace Dali; -using namespace Dali::Toolkit; - -namespace // unnamed namespace -{ - -const unsigned int DEFAULT_NUMBER_OF_COLUMNS = 3; -const float DEFAULT_NUMBER_OF_ROWS = 20.0f; -const float DEFAULT_ROW_SPACING = 55.0f; -const float DEFAULT_BOTTOM_MARGIN_FACTOR = 0.1f; -const Radian DEFAULT_TILT_ANGLE ( Math::PI*0.12f ); -const Radian DEFAULT_ITEM_TILT_ANGLE ( -Math::PI*0.025f ); -const float DEFAULT_SCROLL_SPEED_FACTOR = 0.02f; -const float DEFAULT_MAXIMUM_SWIPE_SPEED = 50.0f; -const float DEFAULT_ITEM_FLICK_ANIMATION_DURATION = 0.03f; - -static Vector3 GetItemSizeDefaultFunction(unsigned int numberOfColumns, float layoutWidth) -{ - float width = layoutWidth / static_cast(numberOfColumns + 1); - - // 1x1 aspect ratio - return Vector3(width, width, width); -} - -static float GetBottomMarginDefaultFunction(float layoutHeight) -{ - return layoutHeight * DEFAULT_BOTTOM_MARGIN_FACTOR; -} - -struct GetColumnPositionDefaultFunction -{ - float operator()(unsigned int numberOfColumns, - unsigned int columnNumber, - const Vector3& itemSize, - float layoutWidth) - { - // Share the available space between margins & column spacings - float availableSpace = std::max(0.0f, (layoutWidth - itemSize.width*numberOfColumns)); - - float leftMargin = availableSpace/numberOfColumns * 0.5f; - - float columnPosition = leftMargin + itemSize.width*0.5f + columnNumber*(itemSize.width + availableSpace/numberOfColumns); - - return columnPosition - layoutWidth*0.5f; - } -}; - -struct DepthPositionConstraint0 -{ - DepthPositionConstraint0(unsigned int numberOfColumns, - unsigned int columnNumber, - DepthLayout::ItemSizeFunction itemSizeFunction, - DepthLayout::BottomMarginFunction bottomMarginFunction, - DepthLayout::ColumnPositionFunction columnPositionFunction, - float heightScale, - float depthScale) - : mNumberOfColumns(numberOfColumns), - mColumnNumber(columnNumber), - mItemSizeFunction(itemSizeFunction), - mBottomMarginFunction(bottomMarginFunction), - mColumnPositionFunction(columnPositionFunction), - mHeightScale(heightScale), - mDepthScale(depthScale) - { - } - - Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width); - - float rowLayoutPositon = layoutPosition - static_cast(mColumnNumber); - - return Vector3( mColumnPositionFunction(mNumberOfColumns, mColumnNumber, itemSize, layoutSize.width), - rowLayoutPositon*mHeightScale + layoutSize.height*0.5f - mBottomMarginFunction(layoutSize.height) - itemSize.height * 0.5f, - -rowLayoutPositon*mDepthScale ); - } - - unsigned int mNumberOfColumns; - unsigned int mColumnNumber; - - DepthLayout::ItemSizeFunction mItemSizeFunction; - DepthLayout::BottomMarginFunction mBottomMarginFunction; - DepthLayout::ColumnPositionFunction mColumnPositionFunction; - - float mHeightScale; - float mDepthScale; -}; - -struct DepthPositionConstraint90 -{ - DepthPositionConstraint90(unsigned int numberOfColumns, - unsigned int columnNumber, - DepthLayout::ItemSizeFunction itemSizeFunction, - DepthLayout::BottomMarginFunction bottomMarginFunction, - DepthLayout::ColumnPositionFunction columnPositionFunction, - float heightScale, - float depthScale) - : mNumberOfColumns(numberOfColumns), - mColumnNumber(columnNumber), - mItemSizeFunction(itemSizeFunction), - mBottomMarginFunction(bottomMarginFunction), - mColumnPositionFunction(columnPositionFunction), - mHeightScale(heightScale), - mDepthScale(depthScale) - { - } - - Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height); - - float rowLayoutPositon = layoutPosition - static_cast(mColumnNumber) + mNumberOfColumns*0.5f; - - return Vector3( rowLayoutPositon*mHeightScale + layoutSize.width*0.5f - mBottomMarginFunction(layoutSize.width) - itemSize.height * 0.5f, - -mColumnPositionFunction(mNumberOfColumns, mColumnNumber, itemSize, layoutSize.height), - -rowLayoutPositon*mDepthScale ); - } - - unsigned int mNumberOfColumns; - unsigned int mColumnNumber; - - DepthLayout::ItemSizeFunction mItemSizeFunction; - DepthLayout::BottomMarginFunction mBottomMarginFunction; - DepthLayout::ColumnPositionFunction mColumnPositionFunction; - - float mHeightScale; - float mDepthScale; -}; - -struct DepthPositionConstraint180 -{ - DepthPositionConstraint180(unsigned int numberOfColumns, - unsigned int columnNumber, - DepthLayout::ItemSizeFunction itemSizeFunction, - DepthLayout::BottomMarginFunction bottomMarginFunction, - DepthLayout::ColumnPositionFunction columnPositionFunction, - float heightScale, - float depthScale) - : mNumberOfColumns(numberOfColumns), - mColumnNumber(columnNumber), - mItemSizeFunction(itemSizeFunction), - mBottomMarginFunction(bottomMarginFunction), - mColumnPositionFunction(columnPositionFunction), - mHeightScale(heightScale), - mDepthScale(depthScale) - { - } - - Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width); - - float rowLayoutPositon = layoutPosition - static_cast(mColumnNumber); - - return Vector3( -mColumnPositionFunction(mNumberOfColumns, mColumnNumber, itemSize, layoutSize.width), - -(rowLayoutPositon*mHeightScale + layoutSize.height*0.5f - mBottomMarginFunction(layoutSize.height) - itemSize.height * 0.5f), - -rowLayoutPositon*mDepthScale ); - } - - unsigned int mNumberOfColumns; - unsigned int mColumnNumber; - - DepthLayout::ItemSizeFunction mItemSizeFunction; - DepthLayout::BottomMarginFunction mBottomMarginFunction; - DepthLayout::ColumnPositionFunction mColumnPositionFunction; - - float mHeightScale; - float mDepthScale; -}; - -struct DepthPositionConstraint270 -{ - DepthPositionConstraint270(unsigned int numberOfColumns, - unsigned int columnNumber, - DepthLayout::ItemSizeFunction itemSizeFunction, - DepthLayout::BottomMarginFunction bottomMarginFunction, - DepthLayout::ColumnPositionFunction columnPositionFunction, - float heightScale, - float depthScale) - : mNumberOfColumns(numberOfColumns), - mColumnNumber(columnNumber), - mItemSizeFunction(itemSizeFunction), - mBottomMarginFunction(bottomMarginFunction), - mColumnPositionFunction(columnPositionFunction), - mHeightScale(heightScale), - mDepthScale(depthScale) - { - } - - Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height); - - float rowLayoutPositon = layoutPosition - static_cast(mColumnNumber) + mNumberOfColumns*0.5f; - - return Vector3( -(rowLayoutPositon*mHeightScale + layoutSize.width*0.5f - mBottomMarginFunction(layoutSize.width) - itemSize.height * 0.5f), - mColumnPositionFunction(mNumberOfColumns, mColumnNumber, itemSize, layoutSize.height), - -rowLayoutPositon*mDepthScale ); - } - - unsigned int mNumberOfColumns; - unsigned int mColumnNumber; - - DepthLayout::ItemSizeFunction mItemSizeFunction; - DepthLayout::BottomMarginFunction mBottomMarginFunction; - DepthLayout::ColumnPositionFunction mColumnPositionFunction; - - float mHeightScale; - float mDepthScale; -}; - -struct DepthRotationConstraint0 -{ - DepthRotationConstraint0(Radian angleRadians) - : mTiltAngle(angleRadians) - { - } - - Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - return Quaternion( Radian( 0.0f ), Vector3::ZAXIS ) * Quaternion( mTiltAngle, Vector3::XAXIS ); - } - - Radian mTiltAngle; -}; - -struct DepthRotationConstraint90 -{ - DepthRotationConstraint90(Radian angleRadians) - : mTiltAngle(angleRadians) - { - } - - Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - return Quaternion( Radian( 1.5f * Math::PI ), Vector3::ZAXIS) * Quaternion( mTiltAngle, Vector3::XAXIS ); - } - - Radian mTiltAngle; -}; - -struct DepthRotationConstraint180 -{ - DepthRotationConstraint180(Radian angleRadians) - : mTiltAngle(angleRadians) - { - } - - Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - return Quaternion( Radian( -Math::PI ), Vector3::ZAXIS) * Quaternion( mTiltAngle, Vector3::XAXIS ); - } - - Radian mTiltAngle; -}; - -struct DepthRotationConstraint270 -{ - DepthRotationConstraint270(Radian angleRadians) - : mTiltAngle(angleRadians) - { - } - - Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - return Quaternion( Radian( 0.5f * Math::PI ), Vector3::ZAXIS) * Quaternion( mTiltAngle, Vector3::XAXIS ); - } - - Radian mTiltAngle; -}; - -struct DepthColorConstraint -{ - DepthColorConstraint(unsigned int numberOfColumns, float numberOfRows, unsigned int columnNumber) - : mNumberOfColumns(numberOfColumns), - mNumberOfRows(numberOfRows), - mColumnNumber(columnNumber) - { - } - - Vector4 operator()(const Vector4& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - float row = (layoutPosition - static_cast(mColumnNumber)) / mNumberOfColumns; - - float darkness(1.0f); - float alpha(1.0f); - - if (row < 0.0f) - { - darkness = alpha = std::max(0.0f, 1.0f + row); - } - else - { - if (row > mNumberOfRows) - { - darkness = 0.0f; - } - else - { - darkness = 1.0f - ( 1.0f * (row / mNumberOfRows) ); - } - - if (row > (mNumberOfRows-1.0f)) - { - alpha = std::max(0.0f, 1.0f - (row-(mNumberOfRows-1.0f))); - } - } - - return Vector4( darkness, darkness, darkness, current.a * alpha ); - } - - unsigned int mNumberOfColumns; - float mNumberOfRows; - unsigned int mColumnNumber; -}; - -struct DepthVisibilityConstraint -{ - DepthVisibilityConstraint(unsigned int numberOfColumns, float numberOfRows, unsigned int columnNumber) - : mNumberOfColumns(numberOfColumns), - mNumberOfRows(numberOfRows), - mColumnNumber(columnNumber) - { - } - - bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - float row = (layoutPosition - static_cast(mColumnNumber)) / mNumberOfColumns; - return (row > -1.0f) && (row < mNumberOfRows); - } - - unsigned int mNumberOfColumns; - float mNumberOfRows; - unsigned int mColumnNumber; -}; - -} // unnamed namespace - -namespace Dali -{ - -namespace Toolkit -{ - -struct PositionConstraintSet -{ - ItemLayout::Vector3Function mOrientation0; - ItemLayout::Vector3Function mOrientation90; - ItemLayout::Vector3Function mOrientation180; - ItemLayout::Vector3Function mOrientation270; -}; - -struct DepthLayout::Impl -{ - Impl() - : mNumberOfColumns(DEFAULT_NUMBER_OF_COLUMNS), - mNumberOfRows(DEFAULT_NUMBER_OF_ROWS), - mRowSpacing(DEFAULT_ROW_SPACING), - mTiltAngle(DEFAULT_TILT_ANGLE), - mItemTiltAngle(DEFAULT_ITEM_TILT_ANGLE), - mScrollSpeedFactor(DEFAULT_SCROLL_SPEED_FACTOR), - mMaximumSwipeSpeed(DEFAULT_MAXIMUM_SWIPE_SPEED), - mItemFlickAnimationDuration(DEFAULT_ITEM_FLICK_ANIMATION_DURATION), - mItemSizeFunction(GetItemSizeDefaultFunction), - mBottomMarginFunction(GetBottomMarginDefaultFunction), - mColumnPositionFunction(GetColumnPositionDefaultFunction()) - { - } - - unsigned int mNumberOfColumns; - unsigned int mNumberOfRows; - - float mRowSpacing; - - Radian mTiltAngle; - Radian mItemTiltAngle; - - float mScrollSpeedFactor; - float mMaximumSwipeSpeed; - float mItemFlickAnimationDuration; - - ItemSizeFunction mItemSizeFunction; - BottomMarginFunction mBottomMarginFunction; - ColumnPositionFunction mColumnPositionFunction; -}; - -DepthLayoutPtr DepthLayout::New() -{ - return DepthLayoutPtr(new DepthLayout()); -} - -DepthLayout::~DepthLayout() -{ - delete mImpl; -} - -void DepthLayout::SetNumberOfColumns(unsigned int columns) -{ - mImpl->mNumberOfColumns = columns; -} - -unsigned int DepthLayout::GetNumberOfColumns() const -{ - return mImpl->mNumberOfColumns; -} - -void DepthLayout::SetNumberOfRows(unsigned int rows) -{ - mImpl->mNumberOfRows = rows; -} - -unsigned int DepthLayout::GetNumberOfRows() const -{ - return mImpl->mNumberOfRows; -} - -void DepthLayout::SetRowSpacing(float spacing) -{ - mImpl->mRowSpacing = spacing; -} - -float DepthLayout::GetRowSpacing() const -{ - return mImpl->mRowSpacing; -} - -void DepthLayout::SetTiltAngle(Degree angle) -{ - mImpl->mTiltAngle = Degree( Clamp( angle, -45.0f, 45.0f ) ); -} - -Degree DepthLayout::GetTiltAngle() const -{ - return Degree( mImpl->mTiltAngle ); -} - -void DepthLayout::SetItemSizeFunction(ItemSizeFunction function) -{ - mImpl->mItemSizeFunction = function; -} - -DepthLayout::ItemSizeFunction DepthLayout::GetItemSizeFunction() const -{ - return mImpl->mItemSizeFunction; -} - -void DepthLayout::SetBottomMarginFunction(BottomMarginFunction function) -{ - mImpl->mBottomMarginFunction = function; -} - -DepthLayout::BottomMarginFunction DepthLayout::GetBottomMarginFunction() const -{ - return mImpl->mBottomMarginFunction; -} - -void DepthLayout::SetItemTiltAngle(Degree angle) -{ - mImpl->mItemTiltAngle = angle; -} - -Degree DepthLayout::GetItemTiltAngle() const -{ - return Degree( mImpl->mItemTiltAngle ); -} - -void DepthLayout::SetColumnPositionFunction(ColumnPositionFunction function) -{ - mImpl->mColumnPositionFunction = function; -} - -DepthLayout::ColumnPositionFunction DepthLayout::GetColumnPositionFunction() const -{ - return mImpl->mColumnPositionFunction; -} - -void DepthLayout::SetScrollSpeedFactor(float scrollSpeed) -{ - mImpl->mScrollSpeedFactor = scrollSpeed; -} - -void DepthLayout::SetMaximumSwipeSpeed(float speed) -{ - mImpl->mMaximumSwipeSpeed = speed; -} - -void DepthLayout::SetItemFlickAnimationDuration(float durationSeconds) -{ - mImpl->mItemFlickAnimationDuration = durationSeconds; -} - -float DepthLayout::GetScrollSpeedFactor() const -{ - return mImpl->mScrollSpeedFactor; -} - -float DepthLayout::GetMaximumSwipeSpeed() const -{ - return mImpl->mMaximumSwipeSpeed; -} - -float DepthLayout::GetItemFlickAnimationDuration() const -{ - return mImpl->mItemFlickAnimationDuration; -} - -float DepthLayout::GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const -{ - return static_cast(mImpl->mNumberOfColumns) - static_cast(numberOfItems); -} - -float DepthLayout::GetClosestAnchorPosition(float layoutPosition) const -{ - float rowIndex = static_cast(round(layoutPosition / mImpl->mNumberOfColumns)); - return rowIndex * static_cast(mImpl->mNumberOfColumns); -} - -float DepthLayout::GetItemScrollToPosition(unsigned int itemId) const -{ - float rowIndex = static_cast(itemId / mImpl->mNumberOfColumns); - return -rowIndex * static_cast(mImpl->mNumberOfColumns); -} - -ItemRange DepthLayout::GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const -{ - float firstRow = -(firstItemPosition/mImpl->mNumberOfColumns); - float lastRow = firstRow + mImpl->mNumberOfRows * 0.5f; - - unsigned int firstItem = static_cast(std::max(0.0f, firstRow * mImpl->mNumberOfColumns)); - unsigned int lastItem = static_cast(std::max(0.0f, lastRow * mImpl->mNumberOfColumns)); - - return ItemRange(firstItem, lastItem+1); -} - -unsigned int DepthLayout::GetReserveItemCount(Vector3 layoutSize) const -{ - float itemsWithinLayout = (layoutSize.depth * mImpl->mNumberOfColumns) / (cosf(mImpl->mTiltAngle) * mImpl->mRowSpacing); - - return static_cast(itemsWithinLayout); -} - -bool DepthLayout::GetItemSize(unsigned int itemId, Vector3 layoutSize, Vector3& itemSize) const -{ - // Note: itemId is not checked, since every item has the same size - - itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, (IsVertical(mOrientation) ? layoutSize.width : layoutSize.height) ); - return true; -} - -void DepthLayout::GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const -{ - if(animation) - { - animation.AnimateTo( Property( actor, Actor::Property::SIZE ), size ); - } -} - -bool DepthLayout::GetPositionConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const -{ - float heightScale = -sinf(mImpl->mTiltAngle) * mImpl->mRowSpacing; - float depthScale = cosf(mImpl->mTiltAngle) * mImpl->mRowSpacing; - - if (mOrientation == ControlOrientation::Up) - { - constraint = DepthPositionConstraint0( mImpl->mNumberOfColumns, - itemId % mImpl->mNumberOfColumns, - mImpl->mItemSizeFunction, - mImpl->mBottomMarginFunction, - mImpl->mColumnPositionFunction, - heightScale, - depthScale ); - } - else if (mOrientation == ControlOrientation::Left) - { - constraint = DepthPositionConstraint90( mImpl->mNumberOfColumns, - itemId % mImpl->mNumberOfColumns, - mImpl->mItemSizeFunction, - mImpl->mBottomMarginFunction, - mImpl->mColumnPositionFunction, - heightScale, - depthScale ); - } - else if (mOrientation == ControlOrientation::Down) - { - constraint = DepthPositionConstraint180( mImpl->mNumberOfColumns, - itemId % mImpl->mNumberOfColumns, - mImpl->mItemSizeFunction, - mImpl->mBottomMarginFunction, - mImpl->mColumnPositionFunction, - heightScale, - depthScale ); - } - else // mOrientation == ControlOrientation::Right - { - constraint = DepthPositionConstraint270( mImpl->mNumberOfColumns, - itemId % mImpl->mNumberOfColumns, - mImpl->mItemSizeFunction, - mImpl->mBottomMarginFunction, - mImpl->mColumnPositionFunction, - heightScale, - depthScale ); - } - - return true; -} - -bool DepthLayout::GetRotationConstraint(unsigned int itemId, ItemLayout::QuaternionFunction& constraint) const -{ - if (mOrientation == ControlOrientation::Up) - { - constraint = DepthRotationConstraint0(mImpl->mItemTiltAngle); - } - else if (mOrientation == ControlOrientation::Left) - { - constraint = DepthRotationConstraint90(mImpl->mItemTiltAngle); - } - else if (mOrientation == ControlOrientation::Down) - { - constraint = DepthRotationConstraint180(mImpl->mItemTiltAngle); - } - else // mOrientation == ControlOrientation::Right - { - constraint = DepthRotationConstraint270(mImpl->mItemTiltAngle); - } - - return true; -} - -bool DepthLayout::GetScaleConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const -{ - return false; // No scaling -} - -bool DepthLayout::GetColorConstraint(unsigned int itemId, ItemLayout::Vector4Function& constraint) const -{ - constraint = DepthColorConstraint(mImpl->mNumberOfColumns, mImpl->mNumberOfRows*0.5f, itemId % mImpl->mNumberOfColumns); - return true; -} - -bool DepthLayout::GetVisibilityConstraint(unsigned int itemId, ItemLayout::BoolFunction& constraint) const -{ - constraint = DepthVisibilityConstraint(mImpl->mNumberOfColumns, mImpl->mNumberOfRows*0.5f, itemId % mImpl->mNumberOfColumns); - return true; -} - -Degree DepthLayout::GetScrollDirection() const -{ - Degree scrollDirection(0.0f); - - if (mOrientation == ControlOrientation::Up) - { - scrollDirection = Degree( 180.0f ); - } - else if (mOrientation == ControlOrientation::Left) - { - scrollDirection = Degree( 270.0f ); - } - else if (mOrientation == ControlOrientation::Down) - { - scrollDirection = Degree( 0.0f ); - } - else // mOrientation == ControlOrientation::Right - { - scrollDirection = Degree( 90.0f ); - } - - return scrollDirection; -} - -DepthLayout::DepthLayout() -: mImpl(NULL) -{ - mImpl = new Impl(); -} - -float DepthLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) -{ - float scrollTo = currentLayoutPosition; - float row = (currentLayoutPosition + itemID - static_cast(itemID % mImpl->mNumberOfColumns)) / mImpl->mNumberOfColumns; - - // Check whether item is not within viewable area - if(row <= -1.0f) - { - scrollTo = GetItemScrollToPosition(itemID); - } - else if(row > mImpl->mNumberOfRows * 0.5f - 1.0f) - { - scrollTo = GetItemScrollToPosition(itemID) + (mImpl->mNumberOfRows - 1.0f) * 0.5f * mImpl->mNumberOfColumns; - } - - return scrollTo; -} - -int DepthLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled) -{ - switch( direction ) - { - case Control::Left: - { - itemID--; - if( itemID < 0 ) - { - itemID = loopEnabled ? maxItems - 1 : 0; - } - break; - } - case Control::Up: - { - itemID += mImpl->mNumberOfColumns; - if( itemID >= maxItems ) - { - itemID = loopEnabled ? 0 : itemID - mImpl->mNumberOfColumns; - } - break; - } - case Control::Right: - { - itemID++; - if( itemID >= maxItems ) - { - itemID = loopEnabled ? 0 : maxItems - 1; - } - break; - } - case Control::Down: - { - itemID -= mImpl->mNumberOfColumns; - if( itemID < 0 ) - { - itemID = loopEnabled ? itemID + maxItems : itemID + mImpl->mNumberOfColumns; - } - break; - } - } - return itemID; -} - -} // namespace Toolkit - -} // namespace Dali diff --git a/dali-toolkit/public-api/controls/scrollable/item-view/grid-layout.cpp b/dali-toolkit/public-api/controls/scrollable/item-view/grid-layout.cpp deleted file mode 100644 index d855167..0000000 --- a/dali-toolkit/public-api/controls/scrollable/item-view/grid-layout.cpp +++ /dev/null @@ -1,765 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// CLASS HEADER -#include - -// EXTERNAL INCLUDES -#include -#include - -using namespace Dali; -using namespace Dali::Toolkit; - -namespace // unnamed namespace -{ - -const unsigned int DEFAULT_NUMBER_OF_COLUMNS = 4; -const float DEFAULT_TOP_MARGIN = 95.0f; -const float DEFAULT_BOTTOM_MARGIN = 20.0f; -const float DEFAULT_SIDE_MARGIN = 20.0f; -const float DEFAULT_COLUMN_SPACING = 20.0f; -const float DEFAULT_ROW_SPACING = 20.0f; -const float DEFAULT_SCROLL_SPEED_FACTOR = 0.03f; -const float DEFAULT_MAXIMUM_SWIPE_SPEED = 100.0f; -const float DEFAULT_ITEM_FLICK_ANIMATION_DURATION = 0.015f; - -// 4 orientations are supported -static const unsigned int ORIENTATION_COUNT = 4; - -static Vector3 GetItemSizeDefaultFunction(unsigned int numberOfColumns, float layoutWidth, float sideMargin, float columnSpacing) -{ - float width = (layoutWidth - sideMargin * 2.0f - columnSpacing * static_cast(numberOfColumns - 1)) / static_cast(numberOfColumns); - - // 4x3 aspect ratio - return Vector3(width, width * 0.75f, width * 0.75f); -} - -struct GridPositionConstraint0 -{ - GridPositionConstraint0(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float topMargin, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction, const float gap) - : mColumnIndex(columnIndex), - mNumberOfColumns(numberOfColumns), - mRowSpacing(rowSpacing), - mColumnSpacing(columnSpacing), - mTopMargin(topMargin), - mSideMargin(sideMargin), - mItemSizeFunction(itemSizeFunction), - mZGap(gap) - { - } - - Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width, mSideMargin, mColumnSpacing); - - return Vector3(mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.x * 0.5f, - ((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.height * 0.5f + itemSize.y * 0.5f + mTopMargin, - mColumnIndex * mZGap); - } - -public: - - unsigned int mColumnIndex; - unsigned int mNumberOfColumns; - float mRowSpacing; - float mColumnSpacing; - float mTopMargin; - float mSideMargin; - GridLayout::ItemSizeFunction mItemSizeFunction; - float mZGap; -}; - -struct GridPositionConstraint90 -{ - GridPositionConstraint90(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float topMargin, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction, const float gap) - : mColumnIndex(columnIndex), - mNumberOfColumns(numberOfColumns), - mRowSpacing(rowSpacing), - mColumnSpacing(columnSpacing), - mTopMargin(topMargin), - mSideMargin(sideMargin), - mItemSizeFunction(itemSizeFunction), - mZGap(gap) - { - } - - Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height, mSideMargin, mColumnSpacing); - - return Vector3(((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.width * 0.5f + itemSize.y * 0.5f + mTopMargin, - -(mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.y*0.5f), - mColumnIndex * mZGap); - } - -public: - - unsigned int mColumnIndex; - unsigned int mNumberOfColumns; - float mRowSpacing; - float mColumnSpacing; - float mTopMargin; - float mSideMargin; - GridLayout::ItemSizeFunction mItemSizeFunction; - float mZGap; -}; - -struct GridPositionConstraint180 -{ - GridPositionConstraint180(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float topMargin, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction, const float gap) - : mColumnIndex(columnIndex), - mNumberOfColumns(numberOfColumns), - mRowSpacing(rowSpacing), - mColumnSpacing(columnSpacing), - mTopMargin(topMargin), - mSideMargin(sideMargin), - mItemSizeFunction(itemSizeFunction), - mZGap(gap) - { - } - - Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width, mSideMargin, mColumnSpacing); - - return Vector3(-(mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.x * 0.5f), - -(((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.height * 0.5f + itemSize.y * 0.5f + mTopMargin), - mColumnIndex * mZGap); - } - -public: - - unsigned int mColumnIndex; - unsigned int mNumberOfColumns; - float mRowSpacing; - float mColumnSpacing; - float mTopMargin; - float mSideMargin; - GridLayout::ItemSizeFunction mItemSizeFunction; - float mZGap; -}; - -struct GridPositionConstraint270 -{ - GridPositionConstraint270(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float topMargin, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction, const float gap) - : mColumnIndex(columnIndex), - mNumberOfColumns(numberOfColumns), - mRowSpacing(rowSpacing), - mColumnSpacing(columnSpacing), - mTopMargin(topMargin), - mSideMargin(sideMargin), - mItemSizeFunction(itemSizeFunction), - mZGap(gap) - { - } - - Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height, mSideMargin, mColumnSpacing); - - return Vector3(-(((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.width * 0.5f + itemSize.y * 0.5f + mTopMargin), - mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.y * 0.5f, - mColumnIndex * mZGap); - } - -public: - - unsigned int mColumnIndex; - unsigned int mNumberOfColumns; - float mRowSpacing; - float mColumnSpacing; - float mTopMargin; - float mSideMargin; - GridLayout::ItemSizeFunction mItemSizeFunction; - float mZGap; -}; - -struct GridRotationConstraint0 -{ - Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - return Quaternion( Radian( 0.0f ), Vector3::ZAXIS); - } -}; - -struct GridRotationConstraint90 -{ - Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - return Quaternion( Radian( 1.5f * Math::PI ), Vector3::ZAXIS); - } -}; - -struct GridRotationConstraint180 -{ - Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - return Quaternion( Radian( Math::PI ), Vector3::ZAXIS); - } -}; - -struct GridRotationConstraint270 -{ - Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - return Quaternion( Radian( 0.5f * Math::PI ), Vector3::ZAXIS); - } -}; - -struct GridColorConstraint -{ - Vector4 operator()(const Vector4& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - return Vector4( 1.0f, 1.0f, 1.0f, current.a ); - } -}; - -struct GridVisibilityConstraintPortrait -{ - GridVisibilityConstraintPortrait(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction) - : mColumnIndex(columnIndex), - mNumberOfColumns(numberOfColumns), - mRowSpacing(rowSpacing), - mColumnSpacing(columnSpacing), - mSideMargin(sideMargin), - mItemSizeFunction(itemSizeFunction) - { - } - - bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width, mSideMargin, mColumnSpacing); - - float row = (layoutPosition - static_cast(mColumnIndex)) / mNumberOfColumns; - int rowsPerPage = ceil(layoutSize.height / (itemSize.y + mRowSpacing)); - - return (row > -2.0f) && (row < rowsPerPage); - } - -public: - - unsigned int mColumnIndex; - unsigned int mNumberOfColumns; - float mRowSpacing; - float mColumnSpacing; - float mSideMargin; - GridLayout::ItemSizeFunction mItemSizeFunction; -}; - -struct GridVisibilityConstraintLandscape -{ - GridVisibilityConstraintLandscape(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction) - : mColumnIndex(columnIndex), - mNumberOfColumns(numberOfColumns), - mRowSpacing(rowSpacing), - mColumnSpacing(columnSpacing), - mSideMargin(sideMargin), - mItemSizeFunction(itemSizeFunction) - { - } - - bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height, mSideMargin, mColumnSpacing); - - float row = (layoutPosition - static_cast(mColumnIndex)) / mNumberOfColumns; - int rowsPerPage = ceil(layoutSize.width / (itemSize.y + mRowSpacing)); - - return (row > -2.0f) && (row < rowsPerPage); - } - -public: - - unsigned int mColumnIndex; - unsigned int mNumberOfColumns; - float mRowSpacing; - float mColumnSpacing; - float mSideMargin; - GridLayout::ItemSizeFunction mItemSizeFunction; -}; - -} // unnamed namespace - -namespace Dali -{ - -namespace Toolkit -{ - -struct GridLayout::Impl -{ - Impl() - : mNumberOfColumns(DEFAULT_NUMBER_OF_COLUMNS), - mRowSpacing(DEFAULT_ROW_SPACING), - mColumnSpacing(DEFAULT_COLUMN_SPACING), - mTopMargin(DEFAULT_TOP_MARGIN), - mBottomMargin(DEFAULT_BOTTOM_MARGIN), - mSideMargin(DEFAULT_SIDE_MARGIN), - mZGap(0.f), - mScrollSpeedFactor(DEFAULT_SCROLL_SPEED_FACTOR), - mMaximumSwipeSpeed(DEFAULT_MAXIMUM_SWIPE_SPEED), - mItemFlickAnimationDuration(DEFAULT_ITEM_FLICK_ANIMATION_DURATION), - mItemSizeFunction(GetItemSizeDefaultFunction) - { - mColorConstraint = GridColorConstraint(); - - mRotationConstraint[0] = GridRotationConstraint0(); - mRotationConstraint[1] = GridRotationConstraint90(); - mRotationConstraint[2] = GridRotationConstraint180(); - mRotationConstraint[3] = GridRotationConstraint270(); - } - - unsigned int mNumberOfColumns; - float mRowSpacing; - float mColumnSpacing; - float mTopMargin; - float mBottomMargin; - float mSideMargin; - float mZGap; - - float mScrollSpeedFactor; - float mMaximumSwipeSpeed; - float mItemFlickAnimationDuration; - - ItemLayout::QuaternionFunction mRotationConstraint[ORIENTATION_COUNT]; - ItemLayout::Vector4Function mColorConstraint; - - ItemSizeFunction mItemSizeFunction; -}; - -GridLayoutPtr GridLayout::New() -{ - return GridLayoutPtr(new GridLayout()); -} - -GridLayout::~GridLayout() -{ - delete mImpl; -} - -void GridLayout::SetNumberOfColumns(unsigned int columns) -{ - mImpl->mNumberOfColumns = columns; -} - -unsigned int GridLayout::GetNumberOfColumns() const -{ - return mImpl->mNumberOfColumns; -} - -void GridLayout::SetRowSpacing(float spacing) -{ - mImpl->mRowSpacing = spacing; -} - -float GridLayout::GetRowSpacing() const -{ - return mImpl->mRowSpacing; -} - -void GridLayout::SetColumnSpacing(float spacing) -{ - mImpl->mColumnSpacing = spacing; -} - -float GridLayout::GetColumnSpacing() const -{ - return mImpl->mColumnSpacing; -} - -void GridLayout::SetTopMargin(float margin) -{ - mImpl->mTopMargin = margin; -} - -float GridLayout::GetTopMargin() const -{ - return mImpl->mTopMargin; -} - -void GridLayout::SetBottomMargin(float margin) -{ - mImpl->mBottomMargin = margin; -} - -float GridLayout::GetBottomMargin() const -{ - return mImpl->mBottomMargin; -} - -void GridLayout::SetSideMargin(float margin) -{ - mImpl->mSideMargin = margin; -} - -float GridLayout::GetSideMargin() const -{ - return mImpl->mSideMargin; -} - -void GridLayout::SetZGap(float gap) -{ - mImpl->mZGap = gap; -} - -float GridLayout::GetZGap() const -{ - return mImpl->mZGap; -} - -void GridLayout::SetItemSizeFunction(ItemSizeFunction function) -{ - mImpl->mItemSizeFunction = function; -} - -GridLayout::ItemSizeFunction GridLayout::GetItemSizeFunction() const -{ - return mImpl->mItemSizeFunction; -} - -void GridLayout::SetScrollSpeedFactor(float scrollSpeed) -{ - mImpl->mScrollSpeedFactor = scrollSpeed; -} - -void GridLayout::SetMaximumSwipeSpeed(float speed) -{ - mImpl->mMaximumSwipeSpeed = speed; -} - -void GridLayout::SetItemFlickAnimationDuration(float durationSeconds) -{ - mImpl->mItemFlickAnimationDuration = durationSeconds; -} - -float GridLayout::GetScrollSpeedFactor() const -{ - return mImpl->mScrollSpeedFactor; -} - -float GridLayout::GetMaximumSwipeSpeed() const -{ - return mImpl->mMaximumSwipeSpeed; -} - -float GridLayout::GetItemFlickAnimationDuration() const -{ - return mImpl->mItemFlickAnimationDuration; -} - -float GridLayout::GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const -{ - float layoutWidth = IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width; - float layoutHeight = IsHorizontal(mOrientation) ? layoutSize.width : layoutSize.height; - - Vector3 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, layoutWidth, mImpl->mSideMargin, mImpl->mColumnSpacing); - - unsigned int itemsLastRow = numberOfItems % mImpl->mNumberOfColumns; - if (itemsLastRow == 0) - { - itemsLastRow = mImpl->mNumberOfColumns; - } - - float rowsLastPage = (layoutHeight - mImpl->mBottomMargin - mImpl->mTopMargin + mImpl->mRowSpacing) / (itemSize.y + mImpl->mRowSpacing); - float itemsLastPage = (rowsLastPage - 1.0f) * static_cast(mImpl->mNumberOfColumns) + static_cast(itemsLastRow); - - return itemsLastPage - static_cast(numberOfItems); -} - -float GridLayout::GetClosestAnchorPosition(float layoutPosition) const -{ - float rowIndex = static_cast(round(layoutPosition / mImpl->mNumberOfColumns)); - return rowIndex * static_cast(mImpl->mNumberOfColumns); -} - -float GridLayout::GetItemScrollToPosition(unsigned int itemId) const -{ - float rowIndex = static_cast(itemId / mImpl->mNumberOfColumns); - return -rowIndex * static_cast(mImpl->mNumberOfColumns); -} - -ItemRange GridLayout::GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const -{ - float layoutWidth = IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width; - float layoutHeight = IsHorizontal(mOrientation) ? layoutSize.width : layoutSize.height; - - Vector3 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, layoutWidth, mImpl->mSideMargin, mImpl->mColumnSpacing); - - int itemsPerPage = mImpl->mNumberOfColumns * ceil(layoutHeight / (itemSize.y + mImpl->mRowSpacing)); - int firstVisibleItem = -(static_cast(firstItemPosition / mImpl->mNumberOfColumns)) * mImpl->mNumberOfColumns; - - int firstItemIndex = std::max(0, firstVisibleItem - static_cast(mImpl->mNumberOfColumns)); - int lastItemIndex = std::max(0, firstVisibleItem + itemsPerPage); - - return ItemRange(firstItemIndex, lastItemIndex); -} - -float GridLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) -{ - ItemLayout::Vector3Function positionConstraint; - Vector3 itemPosition = Vector3::ZERO; - if (GetPositionConstraint(itemID, positionConstraint)) - { - itemPosition = positionConstraint(Vector3::ZERO, currentLayoutPosition + itemID, 0.0f, layoutSize); - } - Vector3 itemSize; - GetItemSize(itemID, layoutSize, itemSize); - Vector3 onScreenArea = (layoutSize - (IsVertical(mOrientation) ? itemSize : Vector3(itemSize.y, itemSize.x, itemSize.z))) * 0.5f; - if (itemPosition.x < -onScreenArea.x - || itemPosition.x > onScreenArea.x - || itemPosition.y < -onScreenArea.y - || itemPosition.y > onScreenArea.y) - { - // item not within viewable area - float rowHeight = itemSize.y + mImpl->mRowSpacing; - ItemLayout::Vector3Function firstItemPositionConstraint; - Vector3 firstItemPosition = Vector3::ZERO; - float offset = 0.0f; - if (GetPositionConstraint(0, firstItemPositionConstraint)) - { - firstItemPosition = firstItemPositionConstraint(Vector3::ZERO, 0.0f, 0.0f, layoutSize); - } - switch( mOrientation ) - { - case ControlOrientation::Up: - { - if(itemPosition.y > onScreenArea.y) - { - offset = ((layoutSize.y - rowHeight) * 0.5f) - firstItemPosition.y; - } - else - { - offset = ((-layoutSize.y + rowHeight) * 0.5f) - firstItemPosition.y; - } - break; - } - case ControlOrientation::Down: - { - if(itemPosition.y < -onScreenArea.y) - { - offset = ((layoutSize.y - rowHeight) * 0.5f) - firstItemPosition.y; - } - else - { - offset = ((-layoutSize.y + rowHeight) * 0.5f) - firstItemPosition.y; - } - break; - } - case ControlOrientation::Left: - { - if(itemPosition.x > onScreenArea.x) - { - offset = ((layoutSize.x - rowHeight) * 0.5f) - firstItemPosition.x; - } - else - { - offset = ((-layoutSize.x + rowHeight) * 0.5f) - firstItemPosition.x; - } - break; - } - case ControlOrientation::Right: - { - if(itemPosition.x < -onScreenArea.x) - { - offset = ((layoutSize.x - rowHeight) * 0.5f) - firstItemPosition.x; - } - else - { - offset = ((-layoutSize.x + rowHeight) * 0.5f) - firstItemPosition.x; - } - break; - } - } - // work out number of rows from first item position to an item aligned to bottom of screen - float rowDiff = offset / rowHeight; - float layoutPositionOffset = rowDiff * mImpl->mNumberOfColumns; - float scrollTo = GetItemScrollToPosition(itemID) + layoutPositionOffset; - return scrollTo; - } - return currentLayoutPosition; -} - -unsigned int GridLayout::GetReserveItemCount(Vector3 layoutSize) const -{ - float layoutWidth = IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width; - float layoutHeight = IsHorizontal(mOrientation) ? layoutSize.width : layoutSize.height; - - Vector3 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, layoutWidth, mImpl->mSideMargin, mImpl->mColumnSpacing); - int itemsPerPage = mImpl->mNumberOfColumns * ceil(layoutHeight / (itemSize.y + mImpl->mRowSpacing)); - return itemsPerPage; -} - -bool GridLayout::GetItemSize(unsigned int itemId, Vector3 layoutSize, Vector3& itemSize) const -{ - // Note: itemId is not checked, since every item has the same size - - itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, (IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width), mImpl->mSideMargin, mImpl->mColumnSpacing); - return true; -} - -void GridLayout::GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const -{ - if(animation) - { - Vector3 currentSize( actor.GetCurrentSize() ); - Vector3 shrink( currentSize ); - - shrink.width = std::min(size.width, currentSize.width); - shrink.height = std::min(size.height, currentSize.height); - - // Do a nonlinear size animation to shrink the actor first when the actor size changes, - // so that we can avoid the actors overlapping during orientation change. - animation.AnimateTo( Property( actor, Actor::Property::SIZE ), shrink, AlphaFunction::EASE_OUT, TimePeriod( 0.0f, durationSeconds * 0.5f ) ); - animation.AnimateTo( Property( actor, Actor::Property::SIZE ), size, AlphaFunction::EASE_IN, TimePeriod( 0.0f, durationSeconds ) ); - } -} - -bool GridLayout::GetPositionConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const -{ - unsigned int columnIndex = itemId % mImpl->mNumberOfColumns; - - if (mOrientation == ControlOrientation::Up) - { - constraint = GridPositionConstraint0(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap); - } - else if (mOrientation == ControlOrientation::Left) - { - constraint = GridPositionConstraint90(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap); - } - else if (mOrientation == ControlOrientation::Down) - { - constraint = GridPositionConstraint180(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap); - } - else // mOrientation == ControlOrientation::Right - { - constraint = GridPositionConstraint270(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap); - } - - return true; -} - -bool GridLayout::GetRotationConstraint(unsigned int itemId, ItemLayout::QuaternionFunction& constraint) const -{ - constraint = mImpl->mRotationConstraint[mOrientation]; - return true; -} - -bool GridLayout::GetScaleConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const -{ - return false; // No scaling -} - -bool GridLayout::GetColorConstraint(unsigned int itemId, ItemLayout::Vector4Function& constraint) const -{ - constraint = mImpl->mColorConstraint; - return true; -} - -bool GridLayout::GetVisibilityConstraint(unsigned int itemId, ItemLayout::BoolFunction& constraint) const -{ - unsigned int columnIndex = itemId % mImpl->mNumberOfColumns; - - if (IsVertical(mOrientation)) - { - constraint = GridVisibilityConstraintPortrait(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mSideMargin, mImpl->mItemSizeFunction); - } - else // horizontal - { - constraint = GridVisibilityConstraintLandscape(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mSideMargin, mImpl->mItemSizeFunction); - } - - return true; -} - -Degree GridLayout::GetScrollDirection() const -{ - Degree scrollDirection(0.0f); - - if (mOrientation == ControlOrientation::Up) - { - scrollDirection = Degree( 0.0f ); - } - else if (mOrientation == ControlOrientation::Left) - { - scrollDirection = Degree( 90.0f ); - } - else if (mOrientation == ControlOrientation::Down) - { - scrollDirection = Degree( 180.0f ); - } - else // mOrientation == ControlOrientation::Right - { - scrollDirection = Degree( 270.0f ); - } - - return scrollDirection; -} - -int GridLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled) -{ - switch( direction ) - { - case Control::Left: - { - itemID--; - if( itemID < 0 ) - { - itemID = loopEnabled ? maxItems - 1 : 0; - } - break; - } - case Control::Up: - { - itemID -= mImpl->mNumberOfColumns; - if( itemID < 0 ) - { - itemID = loopEnabled ? itemID + maxItems : itemID + mImpl->mNumberOfColumns; - } - break; - } - case Control::Right: - { - itemID++; - if( itemID >= maxItems ) - { - itemID = loopEnabled ? 0 : maxItems - 1; - } - break; - } - case Control::Down: - { - itemID += mImpl->mNumberOfColumns; - if( itemID >= maxItems ) - { - itemID = loopEnabled ? 0 : itemID - mImpl->mNumberOfColumns; - } - break; - } - } - return itemID; -} - -GridLayout::GridLayout() -: mImpl(NULL) -{ - mImpl = new Impl(); -} - -} // namespace Toolkit - -} // namespace Dali diff --git a/dali-toolkit/public-api/controls/scrollable/item-view/item-layout.cpp b/dali-toolkit/public-api/controls/scrollable/item-view/item-layout.cpp index 9e29736..39e09a3 100644 --- a/dali-toolkit/public-api/controls/scrollable/item-view/item-layout.cpp +++ b/dali-toolkit/public-api/controls/scrollable/item-view/item-layout.cpp @@ -26,156 +26,55 @@ // INTERNAL INCLUDES #include -namespace -{ - -// Lerps between initial and target using the progress -template< typename Type > -void Lerp( Type& current, const Type& initial, const Type& target, float progress ) -{ - current = initial + ((target - initial) * progress); -} - -// Functors which wrap constraint functions with stored item IDs -struct WrappedQuaternionConstraint -{ - WrappedQuaternionConstraint( Dali::Toolkit::ItemLayout::QuaternionFunction wrapMe, unsigned int itemId ) - :mWrapMe(wrapMe), - mItemId(itemId), - mInitialised( false ) - { - } - - void operator()( Dali::Quaternion& current, const Dali::PropertyInputContainer& inputs ) - { - float offsetLayoutPosition = inputs[0]->GetFloat() + static_cast(mItemId); - float weight = inputs[3]->GetFloat(); - - if( !mInitialised ) - { - mInitialised = true; - mInitial = current; - } - - current = Dali::Quaternion::Slerp( mInitial, mWrapMe( current, offsetLayoutPosition, inputs[1]->GetFloat(), inputs[2]->GetVector3() ), weight ); - } - - Dali::Toolkit::ItemLayout::QuaternionFunction mWrapMe; - unsigned int mItemId; - Dali::Quaternion mInitial; - bool mInitialised:1; -}; - -struct WrappedVector3Constraint +namespace Dali { - WrappedVector3Constraint( Dali::Toolkit::ItemLayout::Vector3Function wrapMe, unsigned int itemId ) - : mWrapMe(wrapMe), - mItemId(itemId), - mInitial(), - mInitialised( false ) - { - } - - void operator()( Dali::Vector3& current, const Dali::PropertyInputContainer& inputs ) - { - float offsetLayoutPosition = inputs[0]->GetFloat() + static_cast(mItemId); - float weight = inputs[3]->GetFloat(); - - if( !mInitialised ) - { - mInitialised = true; - mInitial = current; - } - - Lerp( current, mInitial, mWrapMe( current, offsetLayoutPosition, inputs[1]->GetFloat(), inputs[2]->GetVector3() ), weight ); - } - Dali::Toolkit::ItemLayout::Vector3Function mWrapMe; - unsigned int mItemId; - Dali::Vector3 mInitial; - bool mInitialised:1; -}; - -struct WrappedVector4Constraint +namespace Toolkit { - WrappedVector4Constraint( Dali::Toolkit::ItemLayout::Vector4Function wrapMe, unsigned int itemId ) - : mWrapMe(wrapMe), - mItemId(itemId), - mInitial(), - mInitialised( false ) - { - } - - void operator()( Dali::Vector4& current, const Dali::PropertyInputContainer& inputs ) - { - float offsetLayoutPosition = inputs[0]->GetFloat() + static_cast(mItemId); - float weight = inputs[3]->GetFloat(); - - if( !mInitialised ) - { - mInitialised = true; - mInitial = current; - } - - Lerp( current, mInitial, mWrapMe( current, offsetLayoutPosition, inputs[1]->GetFloat(), inputs[2]->GetVector3() ), weight ); - } - - Dali::Toolkit::ItemLayout::Vector4Function mWrapMe; - unsigned int mItemId; - Dali::Vector4 mInitial; - bool mInitialised:1; -}; -struct WrappedBoolConstraint +struct ItemLayout::Impl { - WrappedBoolConstraint( Dali::Toolkit::ItemLayout::BoolFunction wrapMe, unsigned int itemId ) - : mWrapMe(wrapMe), - mItemId(itemId) - { - } - - void operator()( bool& current, const Dali::PropertyInputContainer& inputs ) - { - float weight = inputs[3]->GetFloat(); - - if ( weight >= 1.0f ) - { - float offsetLayoutPosition = inputs[0]->GetFloat() + static_cast(mItemId); - current = mWrapMe( current, offsetLayoutPosition, inputs[1]->GetFloat(), inputs[2]->GetVector3() ); - } - } - - Dali::Toolkit::ItemLayout::BoolFunction mWrapMe; - unsigned int mItemId; + Vector3 mItemSize; ///< The size of an item in the layout + ControlOrientation::Type mOrientation; ///< the orientation of the layout. }; -} //Unnamed namespace - -namespace Dali -{ - -namespace Toolkit -{ - ItemLayout::ItemLayout() -: mOrientation( ControlOrientation::Up ), - mAlphaFunction( AlphaFunction::LINEAR ), - mWeightObject() +: mImpl( new Impl ) { + mImpl->mOrientation = ControlOrientation::Up; } ItemLayout::~ItemLayout() { + delete mImpl; } void ItemLayout::SetOrientation(ControlOrientation::Type orientation) { - mOrientation = orientation; + mImpl->mOrientation = orientation; } ControlOrientation::Type ItemLayout::GetOrientation() const { - return mOrientation; + return mImpl->mOrientation; +} + +void ItemLayout::GetItemSize( unsigned int itemId, const Vector3& layoutSize, Vector3& itemSize ) const +{ + // If item-size has not been set then get the default size + if ( mImpl->mItemSize == Vector3::ZERO ) + { + GetDefaultItemSize( itemId, layoutSize, itemSize ); + } + else + { + itemSize = mImpl->mItemSize; + } +} + +void ItemLayout::SetItemSize( const Vector3& itemSize ) +{ + mImpl->mItemSize = itemSize; } float ItemLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) @@ -230,122 +129,6 @@ float ItemLayout::GetFlickSpeedFactor() const return GetScrollSpeedFactor(); } -void ItemLayout::ApplyConstraints( Actor& actor, const int itemId, const float durationSeconds, const Actor& itemViewActor ) -{ - // This just implements the default behaviour of constraint application. - // Custom layouts can override this function to apply their custom constraints. - Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( itemViewActor ); - if(itemView) - { - // We want to animate the layout in so use a weight object to do this - if ( !mWeightObject ) - { - mWeightObject = WeightObject::New(); - } - - ItemLayout::Vector3Function positionConstraint; - if (GetPositionConstraint(itemId, positionConstraint)) - { - WrappedVector3Constraint wrapped(positionConstraint, itemId); - Constraint constraint = Constraint::New( actor, Actor::Property::POSITION, wrapped ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::SCROLL_SPEED ) ); - constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); - constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) ); - constraint.Apply(); - } - - ItemLayout::QuaternionFunction rotationConstraint; - if (GetRotationConstraint(itemId, rotationConstraint)) - { - WrappedQuaternionConstraint wrapped(rotationConstraint, itemId); - - Constraint constraint = Constraint::New( actor, Actor::Property::ORIENTATION, wrapped ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::SCROLL_SPEED ) ); - constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); - constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) ); - constraint.Apply(); - } - - ItemLayout::Vector3Function scaleConstraint; - if (GetScaleConstraint(itemId, scaleConstraint)) - { - WrappedVector3Constraint wrapped(scaleConstraint, itemId); - - Constraint constraint = Constraint::New( actor, Actor::Property::SCALE, wrapped ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::SCROLL_SPEED ) ); - constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); - constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) ); - constraint.Apply(); - } - - ItemLayout::Vector4Function colorConstraint; - if (GetColorConstraint(itemId, colorConstraint)) - { - WrappedVector4Constraint wrapped(colorConstraint, itemId); - - Constraint constraint = Constraint::New( actor, Actor::Property::COLOR, wrapped ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::SCROLL_SPEED ) ); - constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); - constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) ); - constraint.SetRemoveAction(Dali::Constraint::Discard); - constraint.Apply(); - } - - ItemLayout::BoolFunction visibilityConstraint; - if (GetVisibilityConstraint(itemId, visibilityConstraint)) - { - WrappedBoolConstraint wrapped(visibilityConstraint, itemId); - - Constraint constraint = Constraint::New( actor, Actor::Property::VISIBLE, wrapped ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::SCROLL_SPEED ) ); - constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); - constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) ); - - // Release visibility constraints the same time as the color constraint - constraint.SetRemoveAction(Dali::Constraint::Discard); - - constraint.Apply(); - } - - KeyFrames keyFrames = KeyFrames::New(); - keyFrames.Add( 0.0f, 0.0f ); - keyFrames.Add( 1.0f, 1.0f ); - - Animation applyAnimation = Dali::Animation::New( durationSeconds ); - applyAnimation.AnimateBetween( Property( mWeightObject, WeightObject::WEIGHT ), keyFrames, mAlphaFunction, TimePeriod(durationSeconds) ); - applyAnimation.Play(); - } -} - -Vector3 ItemLayout::GetItemPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) const -{ - Vector3 itemPosition = Vector3::ZERO; - - ItemLayout::Vector3Function positionConstraint; - if (GetPositionConstraint(itemID, positionConstraint)) - { - itemPosition = positionConstraint(Vector3::ZERO, currentLayoutPosition + itemID, 0.0f, layoutSize); - } - - return itemPosition; -} - -void ItemLayout::SetAlphaFunction(AlphaFunction func) -{ - mAlphaFunction = func; -} - -AlphaFunction ItemLayout::GetAlphaFunction() const -{ - return mAlphaFunction; -} - - } // namespace Toolkit } // namespace Dali diff --git a/dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h b/dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h index 50cfb95..5eda5d4 100644 --- a/dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h +++ b/dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h @@ -19,7 +19,6 @@ */ // EXTERNAL INCLUDES -#include #include // INTERNAL INCLUDES @@ -127,17 +126,7 @@ class DALI_IMPORT_API ItemLayout : public RefObject { public: - /// @brief Function signature of a boolean constraint - typedef boost::function BoolFunction; - - /// @brief Function signature of a Vector3 constraint - typedef boost::function Vector3Function; - - /// @brief Function signature of a Vector4 constraint - typedef boost::function Vector4Function; - - /// @brief Function signature of a Quaternion constraint - typedef boost::function QuaternionFunction; + class Extension; ///< Forward declare future extension interface /** * @brief Virtual destructor. @@ -159,6 +148,26 @@ public: DALI_IMPORT_API ControlOrientation::Type GetOrientation() const; /** + * @brief Retrieve the target size of an item in the layout. + * + * This will return the default size for the layout unless overridden by calling SetItemSize(). + * + * @note layout-position is not provided as a parameter, since applying size constraints is not recommended. + * Animating to target-sizes is preferable, since this allows controls to perform layouting without constraints. + * @param[in] itemId The ID of an item in the layout. + * @param[in] layoutSize The layout size + * @param[out] itemSize The target size of an item. + */ + DALI_IMPORT_API void GetItemSize( unsigned int itemId, const Vector3& layoutSize, Vector3& itemSize ) const; + + /** + * @brief Overrides the default size for the layout. + * + * @param[in] itemSize The size of each item. + */ + DALI_IMPORT_API void SetItemSize( const Vector3& itemSize ); + + /** * @brief Query the minimum valid layout position; this is a negative value. * * When scrolling, the first item will move within the range 0 to GetMinimumLayoutPosition(). @@ -224,16 +233,15 @@ public: virtual unsigned int GetReserveItemCount(Vector3 layoutSize) const = 0; /** - * @brief Retrieve the target size of an item in the layout. + * @brief Retrieve the default size of an item in the layout. * * @note layout-position is not provided as a parameter, since applying size constraints is not recommended. * Animating to target-sizes is preferable, since this allows controls to perform layouting without constraints. * @param[in] itemId The ID of an item in the layout. * @param[in] layoutSize The layout size - * @param[out] itemSize The target size of an item, or an uninitialized value. - * @return Whether the item size is available or not + * @param[out] itemSize The target size of an item. */ - virtual bool GetItemSize(unsigned int itemId, Vector3 layoutSize, Vector3& itemSize) const = 0; + virtual void GetDefaultItemSize( unsigned int itemId, const Vector3& layoutSize, Vector3& itemSize ) const = 0; /** * @brief Retrieve the resize animation in the layout. @@ -247,56 +255,6 @@ public: virtual void GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const = 0; /** - * @brief Retrieve the position constraint function of an item in the layout. - * - * The constraint will be applied when the item is created or the layout is activated. - * @param[in] itemId The ID of an item in the layout. - * @param[out] constraint The position constraint function of an item, or an uninitialized function pointer. - * @return Whether the position constraint function of an item is available or not - */ - virtual bool GetPositionConstraint(unsigned int itemId, Vector3Function& constraint) const = 0; - - /** - * @brief Retrieve the rotation constraint function of an item in the layout. - * - * The constraint will be applied when the item is created or the layout is activated. - * @param[in] itemId The ID of an item in the layout. - * @param[out] constraint The rotation constraint function of an item, or an uninitialized function pointer. - * @return Whether the rotation constraint function of an item is available or not - */ - virtual bool GetRotationConstraint(unsigned int itemId, QuaternionFunction& constraint) const = 0; - - /** - * @brief Retrieve the scale constraint function of an item in the layout. - * - * The constraint will be applied when the item is created or the layout is activated. - * @param[in] itemId The ID of an item in the layout. - * @param[out] constraint The scale constraint function of an item, or an uninitialized function pointer. - * @return Whether the scale constraint function of an item is available or not - */ - virtual bool GetScaleConstraint(unsigned int itemId, Vector3Function& constraint) const = 0; - - /** - * @brief Retrieve the color constraint function of an item in the layout. - * - * The constraint will be applied when the item is created or the layout is activated. - * @param[in] itemId The ID of an item in the layout. - * @param[out] constraint The color constraint function of an item, or an uninitialized function pointer. - * @return Whether the color constraint function of an item is available or not - */ - virtual bool GetColorConstraint(unsigned int itemId, Vector4Function& constraint) const = 0; - - /** - * @brief Retrieve the visibility constraint function of an item in the layout. - * - * The constraint will be applied when the item is created or the layout is activated. - * @param[in] itemId The ID of an item in the layout. - * @param[out] constraint The visibility constraint function of an item, or an uninitialized function pointer. - * @return Whether the visibility constraint function of an item is available or not - */ - virtual bool GetVisibilityConstraint(unsigned int itemId, BoolFunction& constraint) const = 0; - - /** * @brief Query the scroll direction of the layout. * * When an input gesture follows this direction, the layout-position of items will be increased. @@ -367,10 +325,10 @@ public: * * @param[in] actor The actor to constrain. * @param[in] itemId The ID of the item represented by the actor. - * @param[in] durationSeconds The time taken to fully constrain the actors. + * @param[in] layoutSize the current size of the item view instance. * @param[in] itemViewActor The item view instance which requests the application of constraints. */ - DALI_IMPORT_API virtual void ApplyConstraints( Actor& actor, const int itemId, const float durationSeconds, const Actor& itemViewActor ); + DALI_IMPORT_API virtual void ApplyConstraints( Actor& actor, const int itemId, const Vector3& layoutSize, const Actor& itemViewActor ) = 0; /** * @brief Gets the position of a given item @@ -380,21 +338,17 @@ public: * @param[in] layoutSize the current size of the item view instance * @return The item position (x,y,z) */ - DALI_IMPORT_API virtual Vector3 GetItemPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) const; + DALI_IMPORT_API virtual Vector3 GetItemPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) const = 0; /** - * @brief Set the alpha function used when applying constraints + * Retrieve the extension for this layout. * - * @param[in] func The alpha function to use. + * @return The extension if available, NULL otherwise */ - DALI_IMPORT_API void SetAlphaFunction(AlphaFunction func); - - /** - * @brief Retrieve the alpha function used when applying constraints - * - * @return The alpha function. - */ - DALI_IMPORT_API AlphaFunction GetAlphaFunction() const; + virtual Extension* GetExtension() + { + return NULL; + } protected: @@ -405,9 +359,8 @@ protected: protected: - ControlOrientation::Type mOrientation; ///< the orientation of the layout. - AlphaFunction mAlphaFunction; ///< Alpha function to be applied when removing/adding constraints - Handle mWeightObject; ///< Weight object gets created to apply the constraints over a certain time + struct Impl; + Impl* mImpl; }; } // namespace Toolkit diff --git a/dali-toolkit/public-api/controls/scrollable/item-view/spiral-layout.cpp b/dali-toolkit/public-api/controls/scrollable/item-view/spiral-layout.cpp deleted file mode 100644 index 4d9cede..0000000 --- a/dali-toolkit/public-api/controls/scrollable/item-view/spiral-layout.cpp +++ /dev/null @@ -1,601 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// CLASS HEADER -#include - -// EXTERNAL INCLUDES -#include -#include - -using namespace Dali; -using namespace Dali::Toolkit; - -namespace // unnamed namespace -{ - -const float DEFAULT_ITEMS_PER_SPIRAL_TURN = 9.5f; -const float DEFAULT_ITEM_SPACING_RADIANS = Math::PI*2.0f/DEFAULT_ITEMS_PER_SPIRAL_TURN; - -const float DEFAULT_REVOLUTION_DISTANCE = 190.0f; -const float DEFAULT_ITEM_DESCENT = DEFAULT_REVOLUTION_DISTANCE / DEFAULT_ITEMS_PER_SPIRAL_TURN; - -const float DEFAULT_TOP_ITEM_ALIGNMENT = -0.125f; - -const float DEFAULT_SCROLL_SPEED_FACTOR = 0.01f; -const float DEFAULT_MAXIMUM_SWIPE_SPEED = 30.0f; -const float DEFAULT_ITEM_FLICK_ANIMATION_DURATION = 0.1f; - -struct DefaultItemSizeFunction -{ - Vector3 operator()(const Vector3& layoutSize) - { - float width = layoutSize.width * 0.25f; - - // 4x3 aspect ratio - return Vector3(width, (width/4)*3, (width/4)*3); - } -}; - -struct DefaultSpiralRadiusFunction -{ - float operator()(const Vector3& layoutSize) - { - return layoutSize.width*0.4f; - } -}; - -struct SpiralPositionConstraintUp -{ - SpiralPositionConstraintUp(SpiralLayout::SpiralRadiusFunction spiralRadius, float itemSpacingRadians, float itemDescent, float topItemAlignment) - : mSpiralRadius(spiralRadius), - mItemSpacingRadians(itemSpacingRadians), - mItemDescent(itemDescent), - mTopItemAlignment(topItemAlignment) - { - } - - Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - float spiralRadius = mSpiralRadius(layoutSize); - - float angle = -Math::PI*0.5f + mItemSpacingRadians * layoutPosition; - - return Vector3( -spiralRadius * cosf(angle), - (mItemDescent * layoutPosition) + layoutSize.height*mTopItemAlignment, - -spiralRadius * sinf(angle) ); - } - - SpiralLayout::SpiralRadiusFunction mSpiralRadius; - float mItemSpacingRadians; - float mItemDescent; - float mTopItemAlignment; -}; - -struct SpiralPositionConstraintLeft -{ - SpiralPositionConstraintLeft(SpiralLayout::SpiralRadiusFunction spiralRadius, float itemSpacingRadians, float itemDescent, float topItemAlignment) - : mSpiralRadius(spiralRadius), - mItemSpacingRadians(itemSpacingRadians), - mItemDescent(itemDescent), - mTopItemAlignment(topItemAlignment) - { - } - - Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - float spiralRadius = mSpiralRadius(layoutSize); - - float angle = Math::PI*0.5f + mItemSpacingRadians * layoutPosition; - - return Vector3( (mItemDescent * layoutPosition) + layoutSize.width*mTopItemAlignment, - -spiralRadius * cosf(angle), - spiralRadius * sinf(angle) ); - } - - SpiralLayout::SpiralRadiusFunction mSpiralRadius; - float mItemSpacingRadians; - float mItemDescent; - float mTopItemAlignment; -}; - -struct SpiralPositionConstraintDown -{ - SpiralPositionConstraintDown(SpiralLayout::SpiralRadiusFunction spiralRadius, float itemSpacingRadians, float itemDescent, float topItemAlignment) - : mSpiralRadius(spiralRadius), - mItemSpacingRadians(itemSpacingRadians), - mItemDescent(itemDescent), - mTopItemAlignment(topItemAlignment) - { - } - - Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - float spiralRadius = mSpiralRadius(layoutSize); - - float angle = Math::PI*0.5f + mItemSpacingRadians * layoutPosition; - - return Vector3( -spiralRadius * cosf(angle), - (-mItemDescent * layoutPosition) - layoutSize.height*mTopItemAlignment, - spiralRadius * sinf(angle) ); - } - - SpiralLayout::SpiralRadiusFunction mSpiralRadius; - float mItemSpacingRadians; - float mItemDescent; - float mTopItemAlignment; -}; - -struct SpiralPositionConstraintRight -{ - SpiralPositionConstraintRight(SpiralLayout::SpiralRadiusFunction spiralRadius, float itemSpacingRadians, float itemDescent, float topItemAlignment) - : mSpiralRadius(spiralRadius), - mItemSpacingRadians(itemSpacingRadians), - mItemDescent(itemDescent), - mTopItemAlignment(topItemAlignment) - { - } - - Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - float spiralRadius = mSpiralRadius(layoutSize); - - float angle = -Math::PI*0.5f + mItemSpacingRadians * layoutPosition; - - return Vector3( (-mItemDescent * layoutPosition) - layoutSize.width*mTopItemAlignment, - -spiralRadius * cosf(angle), - -spiralRadius * sinf(angle) ); - } - - SpiralLayout::SpiralRadiusFunction mSpiralRadius; - float mItemSpacingRadians; - float mItemDescent; - float mTopItemAlignment; -}; - -struct SpiralRotationConstraintUp -{ - SpiralRotationConstraintUp(float itemSpacingRadians) - : mItemSpacingRadians(itemSpacingRadians) - { - } - - Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - float angle = -mItemSpacingRadians * layoutPosition; - - return Quaternion( Radian( angle ), Vector3::YAXIS); - } - - float mItemSpacingRadians; -}; - -struct SpiralRotationConstraintLeft -{ - SpiralRotationConstraintLeft(float itemSpacingRadians) - : mItemSpacingRadians(itemSpacingRadians) - { - } - - Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - float angle = -mItemSpacingRadians * layoutPosition; - - return Quaternion( Radian( -Math::PI * 0.5f ), Vector3::ZAXIS ) * Quaternion( Radian( angle ), Vector3::YAXIS ); - } - - float mItemSpacingRadians; -}; - -struct SpiralRotationConstraintDown -{ - SpiralRotationConstraintDown(float itemSpacingRadians) - : mItemSpacingRadians(itemSpacingRadians) - { - } - - Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - float angle = -mItemSpacingRadians * layoutPosition; - - return Quaternion( Radian( -Math::PI ), Vector3::ZAXIS) * Quaternion( Radian( angle ), Vector3::YAXIS ); - } - - float mItemSpacingRadians; -}; - -struct SpiralRotationConstraintRight -{ - SpiralRotationConstraintRight(float itemSpacingRadians) - : mItemSpacingRadians(itemSpacingRadians) - { - } - - Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - float angle = -mItemSpacingRadians * layoutPosition; - - return Quaternion( Radian( -Math::PI * 1.5f ), Vector3::ZAXIS) * Quaternion( Radian( angle ), Vector3::YAXIS ); - } - - float mItemSpacingRadians; -}; - -struct SpiralColorConstraint -{ - SpiralColorConstraint(float itemSpacingRadians) - : mItemSpacingRadians(itemSpacingRadians) - { - } - - Vector4 operator()(const Vector4& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - Radian angle( mItemSpacingRadians * fabsf(layoutPosition) / Dali::ANGLE_360 ); - - float progress = angle - floorf( angle ); // take fractional bit only to get between 0.0 - 1.0 - progress = (progress > 0.5f) ? 2.0f*(1.0f - progress) : progress*2.0f; - - float darkness(1.0f); - { - const float startMarker = 0.10f; // The progress at which darkening starts - const float endMarker = 0.35f; // The progress at which darkening ends - const float minDarkness = 0.15f; // The darkness at end marker - - if (progress > endMarker) - { - darkness = minDarkness; - } - else if (progress > startMarker) - { - darkness = 1.0f - ( (1.0f - minDarkness) * ((progress-startMarker) / (endMarker-startMarker)) ); - } - } - - return Vector4( darkness, darkness, darkness, current.a ); - } - - float mItemSpacingRadians; -}; - -struct SpiralVisibilityConstraintPortrait -{ - SpiralVisibilityConstraintPortrait(float itemSpacingRadians, float itemDescent, float topItemAlignment) - : mItemSpacingRadians(itemSpacingRadians), - mItemDescent(itemDescent), - mTopItemAlignment(topItemAlignment) - { - } - - bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - float itemsCachedBeforeTopItem = layoutSize.height*(mTopItemAlignment+0.5f) / mItemDescent; - return (layoutPosition >= -itemsCachedBeforeTopItem - 1.0f && layoutPosition <= (layoutSize.height / mItemDescent) + 1.0f); - } - - float mItemSpacingRadians; - float mItemDescent; - float mTopItemAlignment; -}; - -struct SpiralVisibilityConstraintLandscape -{ - SpiralVisibilityConstraintLandscape(float itemSpacingRadians, float itemDescent, float topItemAlignment) - : mItemSpacingRadians(itemSpacingRadians), - mItemDescent(itemDescent), - mTopItemAlignment(topItemAlignment) - { - } - - bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize) - { - float itemsCachedBeforeTopItem = layoutSize.width*(mTopItemAlignment+0.5f) / mItemDescent; - return (layoutPosition >= -itemsCachedBeforeTopItem - 1.0f && layoutPosition <= (layoutSize.width / mItemDescent) + 1.0f); - } - - float mItemSpacingRadians; - float mItemDescent; - float mTopItemAlignment; -}; - -} // unnamed namespace - -namespace Dali -{ - -namespace Toolkit -{ - -struct SpiralLayout::Impl -{ - Impl() - : mItemSizeFunction(DefaultItemSizeFunction()), - mSpiralRadiusFunction(DefaultSpiralRadiusFunction()), - mItemSpacingRadians(DEFAULT_ITEM_SPACING_RADIANS), - mRevolutionDistance(DEFAULT_REVOLUTION_DISTANCE), - mItemDescent(DEFAULT_ITEM_DESCENT), - mTopItemAlignment(DEFAULT_TOP_ITEM_ALIGNMENT), - mScrollSpeedFactor(DEFAULT_SCROLL_SPEED_FACTOR), - mMaximumSwipeSpeed(DEFAULT_MAXIMUM_SWIPE_SPEED), - mItemFlickAnimationDuration(DEFAULT_ITEM_FLICK_ANIMATION_DURATION) - { - } - - ItemSizeFunction mItemSizeFunction; - SpiralRadiusFunction mSpiralRadiusFunction; - - float mItemSpacingRadians; - float mRevolutionDistance; - float mItemDescent; - float mTopItemAlignment; - float mScrollSpeedFactor; - float mMaximumSwipeSpeed; - float mItemFlickAnimationDuration; -}; - -SpiralLayoutPtr SpiralLayout::New() -{ - return SpiralLayoutPtr(new SpiralLayout()); -} - -SpiralLayout::~SpiralLayout() -{ - delete mImpl; -} - -void SpiralLayout::SetItemSizeFunction(ItemSizeFunction function) -{ - mImpl->mItemSizeFunction = function; -} - -SpiralLayout::ItemSizeFunction SpiralLayout::GetItemSizeFunction() const -{ - return mImpl->mItemSizeFunction; -} - -void SpiralLayout::SetItemSpacing(Radian itemSpacing) -{ - mImpl->mItemSpacingRadians = itemSpacing; - - float itemsPerSpiral = std::max(1.0f, (2.0f*(float)Math::PI) / mImpl->mItemSpacingRadians); - mImpl->mItemDescent = mImpl->mRevolutionDistance / itemsPerSpiral; -} - -Radian SpiralLayout::GetItemSpacing() const -{ - return Radian( mImpl->mItemSpacingRadians ); -} - -void SpiralLayout::SetRevolutionDistance(float distance) -{ - mImpl->mRevolutionDistance = distance; - - float itemsPerSpiral = std::max(1.0f, (2.0f*(float)Math::PI) / mImpl->mItemSpacingRadians); - mImpl->mItemDescent = mImpl->mRevolutionDistance / itemsPerSpiral; -} - -float SpiralLayout::GetRevolutionDistance() const -{ - return mImpl->mRevolutionDistance; -} - -void SpiralLayout::SetSpiralRadiusFunction(SpiralRadiusFunction function) -{ - mImpl->mSpiralRadiusFunction = function; -} - -SpiralLayout::SpiralRadiusFunction SpiralLayout::GetSpiralRadiusFunction() const -{ - return mImpl->mSpiralRadiusFunction; -} - -void SpiralLayout::SetTopItemAlignment(float alignment) -{ - mImpl->mTopItemAlignment = alignment; -} - -float SpiralLayout::GetTopItemAlignment() const -{ - return mImpl->mTopItemAlignment; -} - -void SpiralLayout::SetScrollSpeedFactor(float scrollSpeed) -{ - mImpl->mScrollSpeedFactor = scrollSpeed; -} - -void SpiralLayout::SetMaximumSwipeSpeed(float speed) -{ - mImpl->mMaximumSwipeSpeed = speed; -} - -void SpiralLayout::SetItemFlickAnimationDuration(float durationSeconds) -{ - mImpl->mItemFlickAnimationDuration = durationSeconds; -} - -float SpiralLayout::GetScrollSpeedFactor() const -{ - return mImpl->mScrollSpeedFactor; -} - -float SpiralLayout::GetMaximumSwipeSpeed() const -{ - return mImpl->mMaximumSwipeSpeed; -} - -float SpiralLayout::GetItemFlickAnimationDuration() const -{ - return mImpl->mItemFlickAnimationDuration; -} - -float SpiralLayout::GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const -{ - return 1.0f - static_cast(numberOfItems); -} - -float SpiralLayout::GetClosestAnchorPosition(float layoutPosition) const -{ - return round(layoutPosition); -} - -float SpiralLayout::GetItemScrollToPosition(unsigned int itemId) const -{ - return -(static_cast(itemId)); -} - -ItemRange SpiralLayout::GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const -{ - float layoutHeight = IsHorizontal(mOrientation) ? layoutSize.width : layoutSize.height; - float itemsPerSpiral = layoutHeight / mImpl->mItemDescent; - float itemsCachedBeforeTopItem = layoutHeight * (mImpl->mTopItemAlignment + 0.5f) / mImpl->mItemDescent; - float itemsViewable = std::min(itemsPerSpiral, itemsPerSpiral - itemsCachedBeforeTopItem - firstItemPosition + 1.0f); - - unsigned int firstItem = static_cast(std::max(0.0f, -firstItemPosition - itemsCachedBeforeTopItem - 1.0f)); - unsigned int lastItem = static_cast(std::max(0.0f, firstItem + itemsViewable)); - - return ItemRange(firstItem, lastItem+1); -} - -unsigned int SpiralLayout::GetReserveItemCount(Vector3 layoutSize) const -{ - float layoutHeight = IsHorizontal(mOrientation) ? layoutSize.width : layoutSize.height; - return static_cast(layoutHeight / mImpl->mItemDescent); -} - -bool SpiralLayout::GetItemSize(unsigned int itemId, Vector3 layoutSize, Vector3& itemSize) const -{ - // Note: itemId is not checked, since every item has the same size - - itemSize = mImpl->mItemSizeFunction(layoutSize); - return true; -} - -void SpiralLayout::GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const -{ - if(animation) - { - animation.AnimateTo( Property( actor, Actor::Property::SIZE ), size ); - } -} - -bool SpiralLayout::GetPositionConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const -{ - if (mOrientation == ControlOrientation::Up) - { - constraint = SpiralPositionConstraintUp(mImpl->mSpiralRadiusFunction, mImpl->mItemSpacingRadians, mImpl->mItemDescent, mImpl->mTopItemAlignment); - } - else if (mOrientation == ControlOrientation::Left) - { - constraint = SpiralPositionConstraintLeft(mImpl->mSpiralRadiusFunction, mImpl->mItemSpacingRadians, mImpl->mItemDescent, mImpl->mTopItemAlignment); - } - else if (mOrientation == ControlOrientation::Down) - { - constraint = SpiralPositionConstraintDown(mImpl->mSpiralRadiusFunction, mImpl->mItemSpacingRadians, mImpl->mItemDescent, mImpl->mTopItemAlignment); - } - else // mOrientation == ControlOrientation::Right - { - constraint = SpiralPositionConstraintRight(mImpl->mSpiralRadiusFunction, mImpl->mItemSpacingRadians, mImpl->mItemDescent, mImpl->mTopItemAlignment); - } - - return true; -} - -bool SpiralLayout::GetRotationConstraint(unsigned int itemId, ItemLayout::QuaternionFunction& constraint) const -{ - if (mOrientation == ControlOrientation::Up) - { - constraint = SpiralRotationConstraintUp(mImpl->mItemSpacingRadians); - } - else if (mOrientation == ControlOrientation::Left) - { - constraint = SpiralRotationConstraintLeft(mImpl->mItemSpacingRadians); - } - else if (mOrientation == ControlOrientation::Down) - { - constraint = SpiralRotationConstraintDown(mImpl->mItemSpacingRadians); - } - else // mOrientation == ControlOrientation::Right - { - constraint = SpiralRotationConstraintRight(mImpl->mItemSpacingRadians); - } - - return true; -} - -bool SpiralLayout::GetScaleConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const -{ - return false; // No scaling -} - -bool SpiralLayout::GetColorConstraint(unsigned int itemId, ItemLayout::Vector4Function& constraint) const -{ - constraint = SpiralColorConstraint(mImpl->mItemSpacingRadians); - return true; -} - -bool SpiralLayout::GetVisibilityConstraint(unsigned int itemId, ItemLayout::BoolFunction& constraint) const -{ - if (IsVertical(mOrientation)) - { - constraint = SpiralVisibilityConstraintPortrait(mImpl->mItemSpacingRadians, mImpl->mItemDescent, mImpl->mTopItemAlignment); - } - else // horizontal - { - constraint = SpiralVisibilityConstraintLandscape(mImpl->mItemSpacingRadians, mImpl->mItemDescent, mImpl->mTopItemAlignment); - } - - return true; -} - -Degree SpiralLayout::GetScrollDirection() const -{ - Degree scrollDirection(0); - - if (mOrientation == ControlOrientation::Up) - { - scrollDirection = Degree( -45.0f ); // Allow swiping horizontally & vertically - } - else if (mOrientation == ControlOrientation::Left) - { - scrollDirection = Degree( 45.0f ); - } - else if (mOrientation == ControlOrientation::Down) - { - scrollDirection = Degree( 180.0f - 45.0f ); - } - else // mOrientation == ControlOrientation::Right - { - scrollDirection = Degree( 270.0f - 45.0f ); - } - - return scrollDirection; -} - -SpiralLayout::SpiralLayout() -: mImpl(NULL) -{ - mImpl = new Impl(); -} - -float SpiralLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) -{ - return GetItemScrollToPosition(itemID); -} - -} // namespace Toolkit - -} // namespace Dali diff --git a/dali-toolkit/public-api/file.list b/dali-toolkit/public-api/file.list index 0b2aa15..981c18a 100755 --- a/dali-toolkit/public-api/file.list +++ b/dali-toolkit/public-api/file.list @@ -22,12 +22,10 @@ public_api_src_files = \ $(public_api_src_dir)/controls/page-turn-view/page-turn-view.cpp \ $(public_api_src_dir)/controls/popup/popup.cpp \ $(public_api_src_dir)/controls/scroll-bar/scroll-bar.cpp \ - $(public_api_src_dir)/controls/scrollable/item-view/depth-layout.cpp \ - $(public_api_src_dir)/controls/scrollable/item-view/grid-layout.cpp \ + $(public_api_src_dir)/controls/scrollable/item-view/default-item-layout.cpp \ $(public_api_src_dir)/controls/scrollable/item-view/item-factory.cpp \ $(public_api_src_dir)/controls/scrollable/item-view/item-layout.cpp \ $(public_api_src_dir)/controls/scrollable/item-view/item-view.cpp \ - $(public_api_src_dir)/controls/scrollable/item-view/spiral-layout.cpp \ $(public_api_src_dir)/controls/scrollable/scroll-view/scroll-view-carousel-effect.cpp \ $(public_api_src_dir)/controls/scrollable/scroll-view/scroll-view-constraints.cpp \ $(public_api_src_dir)/controls/scrollable/scroll-view/scroll-view-cube-effect.cpp \ @@ -136,13 +134,11 @@ public_api_image_view_header_files = \ $(public_api_src_dir)/controls/image-view/masked-image-view.h public_api_item_view_header_files = \ - $(public_api_src_dir)/controls/scrollable/item-view/depth-layout.h \ - $(public_api_src_dir)/controls/scrollable/item-view/grid-layout.h \ + $(public_api_src_dir)/controls/scrollable/item-view/default-item-layout.h \ $(public_api_src_dir)/controls/scrollable/item-view/item-factory.h \ $(public_api_src_dir)/controls/scrollable/item-view/item-layout.h \ $(public_api_src_dir)/controls/scrollable/item-view/item-view-declarations.h \ - $(public_api_src_dir)/controls/scrollable/item-view/item-view.h \ - $(public_api_src_dir)/controls/scrollable/item-view/spiral-layout.h + $(public_api_src_dir)/controls/scrollable/item-view/item-view.h public_api_magnifier_header_files = \ $(public_api_src_dir)/controls/magnifier/magnifier.h -- 2.7.4